solidrun.patch 6.7 MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541475424754347544475454754647547475484754947550475514755247553475544755547556475574755847559475604756147562475634756447565475664756747568475694757047571475724757347574475754757647577475784757947580475814758247583475844758547586475874758847589475904759147592475934759447595475964759747598475994760047601476024760347604476054760647607476084760947610476114761247613476144761547616476174761847619476204762147622476234762447625476264762747628476294763047631476324763347634476354763647637476384763947640476414764247643476444764547646476474764847649476504765147652476534765447655476564765747658476594766047661476624766347664476654766647667476684766947670476714767247673476744767547676476774767847679476804768147682476834768447685476864768747688476894769047691476924769347694476954769647697476984769947700477014770247703477044770547706477074770847709477104771147712477134771447715477164771747718477194772047721477224772347724477254772647727477284772947730477314773247733477344773547736477374773847739477404774147742477434774447745477464774747748477494775047751477524775347754477554775647757477584775947760477614776247763477644776547766477674776847769477704777147772477734777447775477764777747778477794778047781477824778347784477854778647787477884778947790477914779247793477944779547796477974779847799478004780147802478034780447805478064780747808478094781047811478124781347814478154781647817478184781947820478214782247823478244782547826478274782847829478304783147832478334783447835478364783747838478394784047841478424784347844478454784647847478484784947850478514785247853478544785547856478574785847859478604786147862478634786447865478664786747868478694787047871478724787347874478754787647877478784787947880478814788247883478844788547886478874788847889478904789147892478934789447895478964789747898478994790047901479024790347904479054790647907479084790947910479114791247913479144791547916479174791847919479204792147922479234792447925479264792747928479294793047931479324793347934479354793647937479384793947940479414794247943479444794547946479474794847949479504795147952479534795447955479564795747958479594796047961479624796347964479654796647967479684796947970479714797247973479744797547976479774797847979479804798147982479834798447985479864798747988479894799047991479924799347994479954799647997479984799948000480014800248003480044800548006480074800848009480104801148012480134801448015480164801748018480194802048021480224802348024480254802648027480284802948030480314803248033480344803548036480374803848039480404804148042480434804448045480464804748048480494805048051480524805348054480554805648057480584805948060480614806248063480644806548066480674806848069480704807148072480734807448075480764807748078480794808048081480824808348084480854808648087480884808948090480914809248093480944809548096480974809848099481004810148102481034810448105481064810748108481094811048111481124811348114481154811648117481184811948120481214812248123481244812548126481274812848129481304813148132481334813448135481364813748138481394814048141481424814348144481454814648147481484814948150481514815248153481544815548156481574815848159481604816148162481634816448165481664816748168481694817048171481724817348174481754817648177481784817948180481814818248183481844818548186481874818848189481904819148192481934819448195481964819748198481994820048201482024820348204482054820648207482084820948210482114821248213482144821548216482174821848219482204822148222482234822448225482264822748228482294823048231482324823348234482354823648237482384823948240482414824248243482444824548246482474824848249482504825148252482534825448255482564825748258482594826048261482624826348264482654826648267482684826948270482714827248273482744827548276482774827848279482804828148282482834828448285482864828748288482894829048291482924829348294482954829648297482984829948300483014830248303483044830548306483074830848309483104831148312483134831448315483164831748318483194832048321483224832348324483254832648327483284832948330483314833248333483344833548336483374833848339483404834148342483434834448345483464834748348483494835048351483524835348354483554835648357483584835948360483614836248363483644836548366483674836848369483704837148372483734837448375483764837748378483794838048381483824838348384483854838648387483884838948390483914839248393483944839548396483974839848399484004840148402484034840448405484064840748408484094841048411484124841348414484154841648417484184841948420484214842248423484244842548426484274842848429484304843148432484334843448435484364843748438484394844048441484424844348444484454844648447484484844948450484514845248453484544845548456484574845848459484604846148462484634846448465484664846748468484694847048471484724847348474484754847648477484784847948480484814848248483484844848548486484874848848489484904849148492484934849448495484964849748498484994850048501485024850348504485054850648507485084850948510485114851248513485144851548516485174851848519485204852148522485234852448525485264852748528485294853048531485324853348534485354853648537485384853948540485414854248543485444854548546485474854848549485504855148552485534855448555485564855748558485594856048561485624856348564485654856648567485684856948570485714857248573485744857548576485774857848579485804858148582485834858448585485864858748588485894859048591485924859348594485954859648597485984859948600486014860248603486044860548606486074860848609486104861148612486134861448615486164861748618486194862048621486224862348624486254862648627486284862948630486314863248633486344863548636486374863848639486404864148642486434864448645486464864748648486494865048651486524865348654486554865648657486584865948660486614866248663486644866548666486674866848669486704867148672486734867448675486764867748678486794868048681486824868348684486854868648687486884868948690486914869248693486944869548696486974869848699487004870148702487034870448705487064870748708487094871048711487124871348714487154871648717487184871948720487214872248723487244872548726487274872848729487304873148732487334873448735487364873748738487394874048741487424874348744487454874648747487484874948750487514875248753487544875548756487574875848759487604876148762487634876448765487664876748768487694877048771487724877348774487754877648777487784877948780487814878248783487844878548786487874878848789487904879148792487934879448795487964879748798487994880048801488024880348804488054880648807488084880948810488114881248813488144881548816488174881848819488204882148822488234882448825488264882748828488294883048831488324883348834488354883648837488384883948840488414884248843488444884548846488474884848849488504885148852488534885448855488564885748858488594886048861488624886348864488654886648867488684886948870488714887248873488744887548876488774887848879488804888148882488834888448885488864888748888488894889048891488924889348894488954889648897488984889948900489014890248903489044890548906489074890848909489104891148912489134891448915489164891748918489194892048921489224892348924489254892648927489284892948930489314893248933489344893548936489374893848939489404894148942489434894448945489464894748948489494895048951489524895348954489554895648957489584895948960489614896248963489644896548966489674896848969489704897148972489734897448975489764897748978489794898048981489824898348984489854898648987489884898948990489914899248993489944899548996489974899848999490004900149002490034900449005490064900749008490094901049011490124901349014490154901649017490184901949020490214902249023490244902549026490274902849029490304903149032490334903449035490364903749038490394904049041490424904349044490454904649047490484904949050490514905249053490544905549056490574905849059490604906149062490634906449065490664906749068490694907049071490724907349074490754907649077490784907949080490814908249083490844908549086490874908849089490904909149092490934909449095490964909749098490994910049101491024910349104491054910649107491084910949110491114911249113491144911549116491174911849119491204912149122491234912449125491264912749128491294913049131491324913349134491354913649137491384913949140491414914249143491444914549146491474914849149491504915149152491534915449155491564915749158491594916049161491624916349164491654916649167491684916949170491714917249173491744917549176491774917849179491804918149182491834918449185491864918749188491894919049191491924919349194491954919649197491984919949200492014920249203492044920549206492074920849209492104921149212492134921449215492164921749218492194922049221492224922349224492254922649227492284922949230492314923249233492344923549236492374923849239492404924149242492434924449245492464924749248492494925049251492524925349254492554925649257492584925949260492614926249263492644926549266492674926849269492704927149272492734927449275492764927749278492794928049281492824928349284492854928649287492884928949290492914929249293492944929549296492974929849299493004930149302493034930449305493064930749308493094931049311493124931349314493154931649317493184931949320493214932249323493244932549326493274932849329493304933149332493334933449335493364933749338493394934049341493424934349344493454934649347493484934949350493514935249353493544935549356493574935849359493604936149362493634936449365493664936749368493694937049371493724937349374493754937649377493784937949380493814938249383493844938549386493874938849389493904939149392493934939449395493964939749398493994940049401494024940349404494054940649407494084940949410494114941249413494144941549416494174941849419494204942149422494234942449425494264942749428494294943049431494324943349434494354943649437494384943949440494414944249443494444944549446494474944849449494504945149452494534945449455494564945749458494594946049461494624946349464494654946649467494684946949470494714947249473494744947549476494774947849479494804948149482494834948449485494864948749488494894949049491494924949349494494954949649497494984949949500495014950249503495044950549506495074950849509495104951149512495134951449515495164951749518495194952049521495224952349524495254952649527495284952949530495314953249533495344953549536495374953849539495404954149542495434954449545495464954749548495494955049551495524955349554495554955649557495584955949560495614956249563495644956549566495674956849569495704957149572495734957449575495764957749578495794958049581495824958349584495854958649587495884958949590495914959249593495944959549596495974959849599496004960149602496034960449605496064960749608496094961049611496124961349614496154961649617496184961949620496214962249623496244962549626496274962849629496304963149632496334963449635496364963749638496394964049641496424964349644496454964649647496484964949650496514965249653496544965549656496574965849659496604966149662496634966449665496664966749668496694967049671496724967349674496754967649677496784967949680496814968249683496844968549686496874968849689496904969149692496934969449695496964969749698496994970049701497024970349704497054970649707497084970949710497114971249713497144971549716497174971849719497204972149722497234972449725497264972749728497294973049731497324973349734497354973649737497384973949740497414974249743497444974549746497474974849749497504975149752497534975449755497564975749758497594976049761497624976349764497654976649767497684976949770497714977249773497744977549776497774977849779497804978149782497834978449785497864978749788497894979049791497924979349794497954979649797497984979949800498014980249803498044980549806498074980849809498104981149812498134981449815498164981749818498194982049821498224982349824498254982649827498284982949830498314983249833498344983549836498374983849839498404984149842498434984449845498464984749848498494985049851498524985349854498554985649857498584985949860498614986249863498644986549866498674986849869498704987149872498734987449875498764987749878498794988049881498824988349884498854988649887498884988949890498914989249893498944989549896498974989849899499004990149902499034990449905499064990749908499094991049911499124991349914499154991649917499184991949920499214992249923499244992549926499274992849929499304993149932499334993449935499364993749938499394994049941499424994349944499454994649947499484994949950499514995249953499544995549956499574995849959499604996149962499634996449965499664996749968499694997049971499724997349974499754997649977499784997949980499814998249983499844998549986499874998849989499904999149992499934999449995499964999749998499995000050001500025000350004500055000650007500085000950010500115001250013500145001550016500175001850019500205002150022500235002450025500265002750028500295003050031500325003350034500355003650037500385003950040500415004250043500445004550046500475004850049500505005150052500535005450055500565005750058500595006050061500625006350064500655006650067500685006950070500715007250073500745007550076500775007850079500805008150082500835008450085500865008750088500895009050091500925009350094500955009650097500985009950100501015010250103501045010550106501075010850109501105011150112501135011450115501165011750118501195012050121501225012350124501255012650127501285012950130501315013250133501345013550136501375013850139501405014150142501435014450145501465014750148501495015050151501525015350154501555015650157501585015950160501615016250163501645016550166501675016850169501705017150172501735017450175501765017750178501795018050181501825018350184501855018650187501885018950190501915019250193501945019550196501975019850199502005020150202502035020450205502065020750208502095021050211502125021350214502155021650217502185021950220502215022250223502245022550226502275022850229502305023150232502335023450235502365023750238502395024050241502425024350244502455024650247502485024950250502515025250253502545025550256502575025850259502605026150262502635026450265502665026750268502695027050271502725027350274502755027650277502785027950280502815028250283502845028550286502875028850289502905029150292502935029450295502965029750298502995030050301503025030350304503055030650307503085030950310503115031250313503145031550316503175031850319503205032150322503235032450325503265032750328503295033050331503325033350334503355033650337503385033950340503415034250343503445034550346503475034850349503505035150352503535035450355503565035750358503595036050361503625036350364503655036650367503685036950370503715037250373503745037550376503775037850379503805038150382503835038450385503865038750388503895039050391503925039350394503955039650397503985039950400504015040250403504045040550406504075040850409504105041150412504135041450415504165041750418504195042050421504225042350424504255042650427504285042950430504315043250433504345043550436504375043850439504405044150442504435044450445504465044750448504495045050451504525045350454504555045650457504585045950460504615046250463504645046550466504675046850469504705047150472504735047450475504765047750478504795048050481504825048350484504855048650487504885048950490504915049250493504945049550496504975049850499505005050150502505035050450505505065050750508505095051050511505125051350514505155051650517505185051950520505215052250523505245052550526505275052850529505305053150532505335053450535505365053750538505395054050541505425054350544505455054650547505485054950550505515055250553505545055550556505575055850559505605056150562505635056450565505665056750568505695057050571505725057350574505755057650577505785057950580505815058250583505845058550586505875058850589505905059150592505935059450595505965059750598505995060050601506025060350604506055060650607506085060950610506115061250613506145061550616506175061850619506205062150622506235062450625506265062750628506295063050631506325063350634506355063650637506385063950640506415064250643506445064550646506475064850649506505065150652506535065450655506565065750658506595066050661506625066350664506655066650667506685066950670506715067250673506745067550676506775067850679506805068150682506835068450685506865068750688506895069050691506925069350694506955069650697506985069950700507015070250703507045070550706507075070850709507105071150712507135071450715507165071750718507195072050721507225072350724507255072650727507285072950730507315073250733507345073550736507375073850739507405074150742507435074450745507465074750748507495075050751507525075350754507555075650757507585075950760507615076250763507645076550766507675076850769507705077150772507735077450775507765077750778507795078050781507825078350784507855078650787507885078950790507915079250793507945079550796507975079850799508005080150802508035080450805508065080750808508095081050811508125081350814508155081650817508185081950820508215082250823508245082550826508275082850829508305083150832508335083450835508365083750838508395084050841508425084350844508455084650847508485084950850508515085250853508545085550856508575085850859508605086150862508635086450865508665086750868508695087050871508725087350874508755087650877508785087950880508815088250883508845088550886508875088850889508905089150892508935089450895508965089750898508995090050901509025090350904509055090650907509085090950910509115091250913509145091550916509175091850919509205092150922509235092450925509265092750928509295093050931509325093350934509355093650937509385093950940509415094250943509445094550946509475094850949509505095150952509535095450955509565095750958509595096050961509625096350964509655096650967509685096950970509715097250973509745097550976509775097850979509805098150982509835098450985509865098750988509895099050991509925099350994509955099650997509985099951000510015100251003510045100551006510075100851009510105101151012510135101451015510165101751018510195102051021510225102351024510255102651027510285102951030510315103251033510345103551036510375103851039510405104151042510435104451045510465104751048510495105051051510525105351054510555105651057510585105951060510615106251063510645106551066510675106851069510705107151072510735107451075510765107751078510795108051081510825108351084510855108651087510885108951090510915109251093510945109551096510975109851099511005110151102511035110451105511065110751108511095111051111511125111351114511155111651117511185111951120511215112251123511245112551126511275112851129511305113151132511335113451135511365113751138511395114051141511425114351144511455114651147511485114951150511515115251153511545115551156511575115851159511605116151162511635116451165511665116751168511695117051171511725117351174511755117651177511785117951180511815118251183511845118551186511875118851189511905119151192511935119451195511965119751198511995120051201512025120351204512055120651207512085120951210512115121251213512145121551216512175121851219512205122151222512235122451225512265122751228512295123051231512325123351234512355123651237512385123951240512415124251243512445124551246512475124851249512505125151252512535125451255512565125751258512595126051261512625126351264512655126651267512685126951270512715127251273512745127551276512775127851279512805128151282512835128451285512865128751288512895129051291512925129351294512955129651297512985129951300513015130251303513045130551306513075130851309513105131151312513135131451315513165131751318513195132051321513225132351324513255132651327513285132951330513315133251333513345133551336513375133851339513405134151342513435134451345513465134751348513495135051351513525135351354513555135651357513585135951360513615136251363513645136551366513675136851369513705137151372513735137451375513765137751378513795138051381513825138351384513855138651387513885138951390513915139251393513945139551396513975139851399514005140151402514035140451405514065140751408514095141051411514125141351414514155141651417514185141951420514215142251423514245142551426514275142851429514305143151432514335143451435514365143751438514395144051441514425144351444514455144651447514485144951450514515145251453514545145551456514575145851459514605146151462514635146451465514665146751468514695147051471514725147351474514755147651477514785147951480514815148251483514845148551486514875148851489514905149151492514935149451495514965149751498514995150051501515025150351504515055150651507515085150951510515115151251513515145151551516515175151851519515205152151522515235152451525515265152751528515295153051531515325153351534515355153651537515385153951540515415154251543515445154551546515475154851549515505155151552515535155451555515565155751558515595156051561515625156351564515655156651567515685156951570515715157251573515745157551576515775157851579515805158151582515835158451585515865158751588515895159051591515925159351594515955159651597515985159951600516015160251603516045160551606516075160851609516105161151612516135161451615516165161751618516195162051621516225162351624516255162651627516285162951630516315163251633516345163551636516375163851639516405164151642516435164451645516465164751648516495165051651516525165351654516555165651657516585165951660516615166251663516645166551666516675166851669516705167151672516735167451675516765167751678516795168051681516825168351684516855168651687516885168951690516915169251693516945169551696516975169851699517005170151702517035170451705517065170751708517095171051711517125171351714517155171651717517185171951720517215172251723517245172551726517275172851729517305173151732517335173451735517365173751738517395174051741517425174351744517455174651747517485174951750517515175251753517545175551756517575175851759517605176151762517635176451765517665176751768517695177051771517725177351774517755177651777517785177951780517815178251783517845178551786517875178851789517905179151792517935179451795517965179751798517995180051801518025180351804518055180651807518085180951810518115181251813518145181551816518175181851819518205182151822518235182451825518265182751828518295183051831518325183351834518355183651837518385183951840518415184251843518445184551846518475184851849518505185151852518535185451855518565185751858518595186051861518625186351864518655186651867518685186951870518715187251873518745187551876518775187851879518805188151882518835188451885518865188751888518895189051891518925189351894518955189651897518985189951900519015190251903519045190551906519075190851909519105191151912519135191451915519165191751918519195192051921519225192351924519255192651927519285192951930519315193251933519345193551936519375193851939519405194151942519435194451945519465194751948519495195051951519525195351954519555195651957519585195951960519615196251963519645196551966519675196851969519705197151972519735197451975519765197751978519795198051981519825198351984519855198651987519885198951990519915199251993519945199551996519975199851999520005200152002520035200452005520065200752008520095201052011520125201352014520155201652017520185201952020520215202252023520245202552026520275202852029520305203152032520335203452035520365203752038520395204052041520425204352044520455204652047520485204952050520515205252053520545205552056520575205852059520605206152062520635206452065520665206752068520695207052071520725207352074520755207652077520785207952080520815208252083520845208552086520875208852089520905209152092520935209452095520965209752098520995210052101521025210352104521055210652107521085210952110521115211252113521145211552116521175211852119521205212152122521235212452125521265212752128521295213052131521325213352134521355213652137521385213952140521415214252143521445214552146521475214852149521505215152152521535215452155521565215752158521595216052161521625216352164521655216652167521685216952170521715217252173521745217552176521775217852179521805218152182521835218452185521865218752188521895219052191521925219352194521955219652197521985219952200522015220252203522045220552206522075220852209522105221152212522135221452215522165221752218522195222052221522225222352224522255222652227522285222952230522315223252233522345223552236522375223852239522405224152242522435224452245522465224752248522495225052251522525225352254522555225652257522585225952260522615226252263522645226552266522675226852269522705227152272522735227452275522765227752278522795228052281522825228352284522855228652287522885228952290522915229252293522945229552296522975229852299523005230152302523035230452305523065230752308523095231052311523125231352314523155231652317523185231952320523215232252323523245232552326523275232852329523305233152332523335233452335523365233752338523395234052341523425234352344523455234652347523485234952350523515235252353523545235552356523575235852359523605236152362523635236452365523665236752368523695237052371523725237352374523755237652377523785237952380523815238252383523845238552386523875238852389523905239152392523935239452395523965239752398523995240052401524025240352404524055240652407524085240952410524115241252413524145241552416524175241852419524205242152422524235242452425524265242752428524295243052431524325243352434524355243652437524385243952440524415244252443524445244552446524475244852449524505245152452524535245452455524565245752458524595246052461524625246352464524655246652467524685246952470524715247252473524745247552476524775247852479524805248152482524835248452485524865248752488524895249052491524925249352494524955249652497524985249952500525015250252503525045250552506525075250852509525105251152512525135251452515525165251752518525195252052521525225252352524525255252652527525285252952530525315253252533525345253552536525375253852539525405254152542525435254452545525465254752548525495255052551525525255352554525555255652557525585255952560525615256252563525645256552566525675256852569525705257152572525735257452575525765257752578525795258052581525825258352584525855258652587525885258952590525915259252593525945259552596525975259852599526005260152602526035260452605526065260752608526095261052611526125261352614526155261652617526185261952620526215262252623526245262552626526275262852629526305263152632526335263452635526365263752638526395264052641526425264352644526455264652647526485264952650526515265252653526545265552656526575265852659526605266152662526635266452665526665266752668526695267052671526725267352674526755267652677526785267952680526815268252683526845268552686526875268852689526905269152692526935269452695526965269752698526995270052701527025270352704527055270652707527085270952710527115271252713527145271552716527175271852719527205272152722527235272452725527265272752728527295273052731527325273352734527355273652737527385273952740527415274252743527445274552746527475274852749527505275152752527535275452755527565275752758527595276052761527625276352764527655276652767527685276952770527715277252773527745277552776527775277852779527805278152782527835278452785527865278752788527895279052791527925279352794527955279652797527985279952800528015280252803528045280552806528075280852809528105281152812528135281452815528165281752818528195282052821528225282352824528255282652827528285282952830528315283252833528345283552836528375283852839528405284152842528435284452845528465284752848528495285052851528525285352854528555285652857528585285952860528615286252863528645286552866528675286852869528705287152872528735287452875528765287752878528795288052881528825288352884528855288652887528885288952890528915289252893528945289552896528975289852899529005290152902529035290452905529065290752908529095291052911529125291352914529155291652917529185291952920529215292252923529245292552926529275292852929529305293152932529335293452935529365293752938529395294052941529425294352944529455294652947529485294952950529515295252953529545295552956529575295852959529605296152962529635296452965529665296752968529695297052971529725297352974529755297652977529785297952980529815298252983529845298552986529875298852989529905299152992529935299452995529965299752998529995300053001530025300353004530055300653007530085300953010530115301253013530145301553016530175301853019530205302153022530235302453025530265302753028530295303053031530325303353034530355303653037530385303953040530415304253043530445304553046530475304853049530505305153052530535305453055530565305753058530595306053061530625306353064530655306653067530685306953070530715307253073530745307553076530775307853079530805308153082530835308453085530865308753088530895309053091530925309353094530955309653097530985309953100531015310253103531045310553106531075310853109531105311153112531135311453115531165311753118531195312053121531225312353124531255312653127531285312953130531315313253133531345313553136531375313853139531405314153142531435314453145531465314753148531495315053151531525315353154531555315653157531585315953160531615316253163531645316553166531675316853169531705317153172531735317453175531765317753178531795318053181531825318353184531855318653187531885318953190531915319253193531945319553196531975319853199532005320153202532035320453205532065320753208532095321053211532125321353214532155321653217532185321953220532215322253223532245322553226532275322853229532305323153232532335323453235532365323753238532395324053241532425324353244532455324653247532485324953250532515325253253532545325553256532575325853259532605326153262532635326453265532665326753268532695327053271532725327353274532755327653277532785327953280532815328253283532845328553286532875328853289532905329153292532935329453295532965329753298532995330053301533025330353304533055330653307533085330953310533115331253313533145331553316533175331853319533205332153322533235332453325533265332753328533295333053331533325333353334533355333653337533385333953340533415334253343533445334553346533475334853349533505335153352533535335453355533565335753358533595336053361533625336353364533655336653367533685336953370533715337253373533745337553376533775337853379533805338153382533835338453385533865338753388533895339053391533925339353394533955339653397533985339953400534015340253403534045340553406534075340853409534105341153412534135341453415534165341753418534195342053421534225342353424534255342653427534285342953430534315343253433534345343553436534375343853439534405344153442534435344453445534465344753448534495345053451534525345353454534555345653457534585345953460534615346253463534645346553466534675346853469534705347153472534735347453475534765347753478534795348053481534825348353484534855348653487534885348953490534915349253493534945349553496534975349853499535005350153502535035350453505535065350753508535095351053511535125351353514535155351653517535185351953520535215352253523535245352553526535275352853529535305353153532535335353453535535365353753538535395354053541535425354353544535455354653547535485354953550535515355253553535545355553556535575355853559535605356153562535635356453565535665356753568535695357053571535725357353574535755357653577535785357953580535815358253583535845358553586535875358853589535905359153592535935359453595535965359753598535995360053601536025360353604536055360653607536085360953610536115361253613536145361553616536175361853619536205362153622536235362453625536265362753628536295363053631536325363353634536355363653637536385363953640536415364253643536445364553646536475364853649536505365153652536535365453655536565365753658536595366053661536625366353664536655366653667536685366953670536715367253673536745367553676536775367853679536805368153682536835368453685536865368753688536895369053691536925369353694536955369653697536985369953700537015370253703537045370553706537075370853709537105371153712537135371453715537165371753718537195372053721537225372353724537255372653727537285372953730537315373253733537345373553736537375373853739537405374153742537435374453745537465374753748537495375053751537525375353754537555375653757537585375953760537615376253763537645376553766537675376853769537705377153772537735377453775537765377753778537795378053781537825378353784537855378653787537885378953790537915379253793537945379553796537975379853799538005380153802538035380453805538065380753808538095381053811538125381353814538155381653817538185381953820538215382253823538245382553826538275382853829538305383153832538335383453835538365383753838538395384053841538425384353844538455384653847538485384953850538515385253853538545385553856538575385853859538605386153862538635386453865538665386753868538695387053871538725387353874538755387653877538785387953880538815388253883538845388553886538875388853889538905389153892538935389453895538965389753898538995390053901539025390353904539055390653907539085390953910539115391253913539145391553916539175391853919539205392153922539235392453925539265392753928539295393053931539325393353934539355393653937539385393953940539415394253943539445394553946539475394853949539505395153952539535395453955539565395753958539595396053961539625396353964539655396653967539685396953970539715397253973539745397553976539775397853979539805398153982539835398453985539865398753988539895399053991539925399353994539955399653997539985399954000540015400254003540045400554006540075400854009540105401154012540135401454015540165401754018540195402054021540225402354024540255402654027540285402954030540315403254033540345403554036540375403854039540405404154042540435404454045540465404754048540495405054051540525405354054540555405654057540585405954060540615406254063540645406554066540675406854069540705407154072540735407454075540765407754078540795408054081540825408354084540855408654087540885408954090540915409254093540945409554096540975409854099541005410154102541035410454105541065410754108541095411054111541125411354114541155411654117541185411954120541215412254123541245412554126541275412854129541305413154132541335413454135541365413754138541395414054141541425414354144541455414654147541485414954150541515415254153541545415554156541575415854159541605416154162541635416454165541665416754168541695417054171541725417354174541755417654177541785417954180541815418254183541845418554186541875418854189541905419154192541935419454195541965419754198541995420054201542025420354204542055420654207542085420954210542115421254213542145421554216542175421854219542205422154222542235422454225542265422754228542295423054231542325423354234542355423654237542385423954240542415424254243542445424554246542475424854249542505425154252542535425454255542565425754258542595426054261542625426354264542655426654267542685426954270542715427254273542745427554276542775427854279542805428154282542835428454285542865428754288542895429054291542925429354294542955429654297542985429954300543015430254303543045430554306543075430854309543105431154312543135431454315543165431754318543195432054321543225432354324543255432654327543285432954330543315433254333543345433554336543375433854339543405434154342543435434454345543465434754348543495435054351543525435354354543555435654357543585435954360543615436254363543645436554366543675436854369543705437154372543735437454375543765437754378543795438054381543825438354384543855438654387543885438954390543915439254393543945439554396543975439854399544005440154402544035440454405544065440754408544095441054411544125441354414544155441654417544185441954420544215442254423544245442554426544275442854429544305443154432544335443454435544365443754438544395444054441544425444354444544455444654447544485444954450544515445254453544545445554456544575445854459544605446154462544635446454465544665446754468544695447054471544725447354474544755447654477544785447954480544815448254483544845448554486544875448854489544905449154492544935449454495544965449754498544995450054501545025450354504545055450654507545085450954510545115451254513545145451554516545175451854519545205452154522545235452454525545265452754528545295453054531545325453354534545355453654537545385453954540545415454254543545445454554546545475454854549545505455154552545535455454555545565455754558545595456054561545625456354564545655456654567545685456954570545715457254573545745457554576545775457854579545805458154582545835458454585545865458754588545895459054591545925459354594545955459654597545985459954600546015460254603546045460554606546075460854609546105461154612546135461454615546165461754618546195462054621546225462354624546255462654627546285462954630546315463254633546345463554636546375463854639546405464154642546435464454645546465464754648546495465054651546525465354654546555465654657546585465954660546615466254663546645466554666546675466854669546705467154672546735467454675546765467754678546795468054681546825468354684546855468654687546885468954690546915469254693546945469554696546975469854699547005470154702547035470454705547065470754708547095471054711547125471354714547155471654717547185471954720547215472254723547245472554726547275472854729547305473154732547335473454735547365473754738547395474054741547425474354744547455474654747547485474954750547515475254753547545475554756547575475854759547605476154762547635476454765547665476754768547695477054771547725477354774547755477654777547785477954780547815478254783547845478554786547875478854789547905479154792547935479454795547965479754798547995480054801548025480354804548055480654807548085480954810548115481254813548145481554816548175481854819548205482154822548235482454825548265482754828548295483054831548325483354834548355483654837548385483954840548415484254843548445484554846548475484854849548505485154852548535485454855548565485754858548595486054861548625486354864548655486654867548685486954870548715487254873548745487554876548775487854879548805488154882548835488454885548865488754888548895489054891548925489354894548955489654897548985489954900549015490254903549045490554906549075490854909549105491154912549135491454915549165491754918549195492054921549225492354924549255492654927549285492954930549315493254933549345493554936549375493854939549405494154942549435494454945549465494754948549495495054951549525495354954549555495654957549585495954960549615496254963549645496554966549675496854969549705497154972549735497454975549765497754978549795498054981549825498354984549855498654987549885498954990549915499254993549945499554996549975499854999550005500155002550035500455005550065500755008550095501055011550125501355014550155501655017550185501955020550215502255023550245502555026550275502855029550305503155032550335503455035550365503755038550395504055041550425504355044550455504655047550485504955050550515505255053550545505555056550575505855059550605506155062550635506455065550665506755068550695507055071550725507355074550755507655077550785507955080550815508255083550845508555086550875508855089550905509155092550935509455095550965509755098550995510055101551025510355104551055510655107551085510955110551115511255113551145511555116551175511855119551205512155122551235512455125551265512755128551295513055131551325513355134551355513655137551385513955140551415514255143551445514555146551475514855149551505515155152551535515455155551565515755158551595516055161551625516355164551655516655167551685516955170551715517255173551745517555176551775517855179551805518155182551835518455185551865518755188551895519055191551925519355194551955519655197551985519955200552015520255203552045520555206552075520855209552105521155212552135521455215552165521755218552195522055221552225522355224552255522655227552285522955230552315523255233552345523555236552375523855239552405524155242552435524455245552465524755248552495525055251552525525355254552555525655257552585525955260552615526255263552645526555266552675526855269552705527155272552735527455275552765527755278552795528055281552825528355284552855528655287552885528955290552915529255293552945529555296552975529855299553005530155302553035530455305553065530755308553095531055311553125531355314553155531655317553185531955320553215532255323553245532555326553275532855329553305533155332553335533455335553365533755338553395534055341553425534355344553455534655347553485534955350553515535255353553545535555356553575535855359553605536155362553635536455365553665536755368553695537055371553725537355374553755537655377553785537955380553815538255383553845538555386553875538855389553905539155392553935539455395553965539755398553995540055401554025540355404554055540655407554085540955410554115541255413554145541555416554175541855419554205542155422554235542455425554265542755428554295543055431554325543355434554355543655437554385543955440554415544255443554445544555446554475544855449554505545155452554535545455455554565545755458554595546055461554625546355464554655546655467554685546955470554715547255473554745547555476554775547855479554805548155482554835548455485554865548755488554895549055491554925549355494554955549655497554985549955500555015550255503555045550555506555075550855509555105551155512555135551455515555165551755518555195552055521555225552355524555255552655527555285552955530555315553255533555345553555536555375553855539555405554155542555435554455545555465554755548555495555055551555525555355554555555555655557555585555955560555615556255563555645556555566555675556855569555705557155572555735557455575555765557755578555795558055581555825558355584555855558655587555885558955590555915559255593555945559555596555975559855599556005560155602556035560455605556065560755608556095561055611556125561355614556155561655617556185561955620556215562255623556245562555626556275562855629556305563155632556335563455635556365563755638556395564055641556425564355644556455564655647556485564955650556515565255653556545565555656556575565855659556605566155662556635566455665556665566755668556695567055671556725567355674556755567655677556785567955680556815568255683556845568555686556875568855689556905569155692556935569455695556965569755698556995570055701557025570355704557055570655707557085570955710557115571255713557145571555716557175571855719557205572155722557235572455725557265572755728557295573055731557325573355734557355573655737557385573955740557415574255743557445574555746557475574855749557505575155752557535575455755557565575755758557595576055761557625576355764557655576655767557685576955770557715577255773557745577555776557775577855779557805578155782557835578455785557865578755788557895579055791557925579355794557955579655797557985579955800558015580255803558045580555806558075580855809558105581155812558135581455815558165581755818558195582055821558225582355824558255582655827558285582955830558315583255833558345583555836558375583855839558405584155842558435584455845558465584755848558495585055851558525585355854558555585655857558585585955860558615586255863558645586555866558675586855869558705587155872558735587455875558765587755878558795588055881558825588355884558855588655887558885588955890558915589255893558945589555896558975589855899559005590155902559035590455905559065590755908559095591055911559125591355914559155591655917559185591955920559215592255923559245592555926559275592855929559305593155932559335593455935559365593755938559395594055941559425594355944559455594655947559485594955950559515595255953559545595555956559575595855959559605596155962559635596455965559665596755968559695597055971559725597355974559755597655977559785597955980559815598255983559845598555986559875598855989559905599155992559935599455995559965599755998559995600056001560025600356004560055600656007560085600956010560115601256013560145601556016560175601856019560205602156022560235602456025560265602756028560295603056031560325603356034560355603656037560385603956040560415604256043560445604556046560475604856049560505605156052560535605456055560565605756058560595606056061560625606356064560655606656067560685606956070560715607256073560745607556076560775607856079560805608156082560835608456085560865608756088560895609056091560925609356094560955609656097560985609956100561015610256103561045610556106561075610856109561105611156112561135611456115561165611756118561195612056121561225612356124561255612656127561285612956130561315613256133561345613556136561375613856139561405614156142561435614456145561465614756148561495615056151561525615356154561555615656157561585615956160561615616256163561645616556166561675616856169561705617156172561735617456175561765617756178561795618056181561825618356184561855618656187561885618956190561915619256193561945619556196561975619856199562005620156202562035620456205562065620756208562095621056211562125621356214562155621656217562185621956220562215622256223562245622556226562275622856229562305623156232562335623456235562365623756238562395624056241562425624356244562455624656247562485624956250562515625256253562545625556256562575625856259562605626156262562635626456265562665626756268562695627056271562725627356274562755627656277562785627956280562815628256283562845628556286562875628856289562905629156292562935629456295562965629756298562995630056301563025630356304563055630656307563085630956310563115631256313563145631556316563175631856319563205632156322563235632456325563265632756328563295633056331563325633356334563355633656337563385633956340563415634256343563445634556346563475634856349563505635156352563535635456355563565635756358563595636056361563625636356364563655636656367563685636956370563715637256373563745637556376563775637856379563805638156382563835638456385563865638756388563895639056391563925639356394563955639656397563985639956400564015640256403564045640556406564075640856409564105641156412564135641456415564165641756418564195642056421564225642356424564255642656427564285642956430564315643256433564345643556436564375643856439564405644156442564435644456445564465644756448564495645056451564525645356454564555645656457564585645956460564615646256463564645646556466564675646856469564705647156472564735647456475564765647756478564795648056481564825648356484564855648656487564885648956490564915649256493564945649556496564975649856499565005650156502565035650456505565065650756508565095651056511565125651356514565155651656517565185651956520565215652256523565245652556526565275652856529565305653156532565335653456535565365653756538565395654056541565425654356544565455654656547565485654956550565515655256553565545655556556565575655856559565605656156562565635656456565565665656756568565695657056571565725657356574565755657656577565785657956580565815658256583565845658556586565875658856589565905659156592565935659456595565965659756598565995660056601566025660356604566055660656607566085660956610566115661256613566145661556616566175661856619566205662156622566235662456625566265662756628566295663056631566325663356634566355663656637566385663956640566415664256643566445664556646566475664856649566505665156652566535665456655566565665756658566595666056661566625666356664566655666656667566685666956670566715667256673566745667556676566775667856679566805668156682566835668456685566865668756688566895669056691566925669356694566955669656697566985669956700567015670256703567045670556706567075670856709567105671156712567135671456715567165671756718567195672056721567225672356724567255672656727567285672956730567315673256733567345673556736567375673856739567405674156742567435674456745567465674756748567495675056751567525675356754567555675656757567585675956760567615676256763567645676556766567675676856769567705677156772567735677456775567765677756778567795678056781567825678356784567855678656787567885678956790567915679256793567945679556796567975679856799568005680156802568035680456805568065680756808568095681056811568125681356814568155681656817568185681956820568215682256823568245682556826568275682856829568305683156832568335683456835568365683756838568395684056841568425684356844568455684656847568485684956850568515685256853568545685556856568575685856859568605686156862568635686456865568665686756868568695687056871568725687356874568755687656877568785687956880568815688256883568845688556886568875688856889568905689156892568935689456895568965689756898568995690056901569025690356904569055690656907569085690956910569115691256913569145691556916569175691856919569205692156922569235692456925569265692756928569295693056931569325693356934569355693656937569385693956940569415694256943569445694556946569475694856949569505695156952569535695456955569565695756958569595696056961569625696356964569655696656967569685696956970569715697256973569745697556976569775697856979569805698156982569835698456985569865698756988569895699056991569925699356994569955699656997569985699957000570015700257003570045700557006570075700857009570105701157012570135701457015570165701757018570195702057021570225702357024570255702657027570285702957030570315703257033570345703557036570375703857039570405704157042570435704457045570465704757048570495705057051570525705357054570555705657057570585705957060570615706257063570645706557066570675706857069570705707157072570735707457075570765707757078570795708057081570825708357084570855708657087570885708957090570915709257093570945709557096570975709857099571005710157102571035710457105571065710757108571095711057111571125711357114571155711657117571185711957120571215712257123571245712557126571275712857129571305713157132571335713457135571365713757138571395714057141571425714357144571455714657147571485714957150571515715257153571545715557156571575715857159571605716157162571635716457165571665716757168571695717057171571725717357174571755717657177571785717957180571815718257183571845718557186571875718857189571905719157192571935719457195571965719757198571995720057201572025720357204572055720657207572085720957210572115721257213572145721557216572175721857219572205722157222572235722457225572265722757228572295723057231572325723357234572355723657237572385723957240572415724257243572445724557246572475724857249572505725157252572535725457255572565725757258572595726057261572625726357264572655726657267572685726957270572715727257273572745727557276572775727857279572805728157282572835728457285572865728757288572895729057291572925729357294572955729657297572985729957300573015730257303573045730557306573075730857309573105731157312573135731457315573165731757318573195732057321573225732357324573255732657327573285732957330573315733257333573345733557336573375733857339573405734157342573435734457345573465734757348573495735057351573525735357354573555735657357573585735957360573615736257363573645736557366573675736857369573705737157372573735737457375573765737757378573795738057381573825738357384573855738657387573885738957390573915739257393573945739557396573975739857399574005740157402574035740457405574065740757408574095741057411574125741357414574155741657417574185741957420574215742257423574245742557426574275742857429574305743157432574335743457435574365743757438574395744057441574425744357444574455744657447574485744957450574515745257453574545745557456574575745857459574605746157462574635746457465574665746757468574695747057471574725747357474574755747657477574785747957480574815748257483574845748557486574875748857489574905749157492574935749457495574965749757498574995750057501575025750357504575055750657507575085750957510575115751257513575145751557516575175751857519575205752157522575235752457525575265752757528575295753057531575325753357534575355753657537575385753957540575415754257543575445754557546575475754857549575505755157552575535755457555575565755757558575595756057561575625756357564575655756657567575685756957570575715757257573575745757557576575775757857579575805758157582575835758457585575865758757588575895759057591575925759357594575955759657597575985759957600576015760257603576045760557606576075760857609576105761157612576135761457615576165761757618576195762057621576225762357624576255762657627576285762957630576315763257633576345763557636576375763857639576405764157642576435764457645576465764757648576495765057651576525765357654576555765657657576585765957660576615766257663576645766557666576675766857669576705767157672576735767457675576765767757678576795768057681576825768357684576855768657687576885768957690576915769257693576945769557696576975769857699577005770157702577035770457705577065770757708577095771057711577125771357714577155771657717577185771957720577215772257723577245772557726577275772857729577305773157732577335773457735577365773757738577395774057741577425774357744577455774657747577485774957750577515775257753577545775557756577575775857759577605776157762577635776457765577665776757768577695777057771577725777357774577755777657777577785777957780577815778257783577845778557786577875778857789577905779157792577935779457795577965779757798577995780057801578025780357804578055780657807578085780957810578115781257813578145781557816578175781857819578205782157822578235782457825578265782757828578295783057831578325783357834578355783657837578385783957840578415784257843578445784557846578475784857849578505785157852578535785457855578565785757858578595786057861578625786357864578655786657867578685786957870578715787257873578745787557876578775787857879578805788157882578835788457885578865788757888578895789057891578925789357894578955789657897578985789957900579015790257903579045790557906579075790857909579105791157912579135791457915579165791757918579195792057921579225792357924579255792657927579285792957930579315793257933579345793557936579375793857939579405794157942579435794457945579465794757948579495795057951579525795357954579555795657957579585795957960579615796257963579645796557966579675796857969579705797157972579735797457975579765797757978579795798057981579825798357984579855798657987579885798957990579915799257993579945799557996579975799857999580005800158002580035800458005580065800758008580095801058011580125801358014580155801658017580185801958020580215802258023580245802558026580275802858029580305803158032580335803458035580365803758038580395804058041580425804358044580455804658047580485804958050580515805258053580545805558056580575805858059580605806158062580635806458065580665806758068580695807058071580725807358074580755807658077580785807958080580815808258083580845808558086580875808858089580905809158092580935809458095580965809758098580995810058101581025810358104581055810658107581085810958110581115811258113581145811558116581175811858119581205812158122581235812458125581265812758128581295813058131581325813358134581355813658137581385813958140581415814258143581445814558146581475814858149581505815158152581535815458155581565815758158581595816058161581625816358164581655816658167581685816958170581715817258173581745817558176581775817858179581805818158182581835818458185581865818758188581895819058191581925819358194581955819658197581985819958200582015820258203582045820558206582075820858209582105821158212582135821458215582165821758218582195822058221582225822358224582255822658227582285822958230582315823258233582345823558236582375823858239582405824158242582435824458245582465824758248582495825058251582525825358254582555825658257582585825958260582615826258263582645826558266582675826858269582705827158272582735827458275582765827758278582795828058281582825828358284582855828658287582885828958290582915829258293582945829558296582975829858299583005830158302583035830458305583065830758308583095831058311583125831358314583155831658317583185831958320583215832258323583245832558326583275832858329583305833158332583335833458335583365833758338583395834058341583425834358344583455834658347583485834958350583515835258353583545835558356583575835858359583605836158362583635836458365583665836758368583695837058371583725837358374583755837658377583785837958380583815838258383583845838558386583875838858389583905839158392583935839458395583965839758398583995840058401584025840358404584055840658407584085840958410584115841258413584145841558416584175841858419584205842158422584235842458425584265842758428584295843058431584325843358434584355843658437584385843958440584415844258443584445844558446584475844858449584505845158452584535845458455584565845758458584595846058461584625846358464584655846658467584685846958470584715847258473584745847558476584775847858479584805848158482584835848458485584865848758488584895849058491584925849358494584955849658497584985849958500585015850258503585045850558506585075850858509585105851158512585135851458515585165851758518585195852058521585225852358524585255852658527585285852958530585315853258533585345853558536585375853858539585405854158542585435854458545585465854758548585495855058551585525855358554585555855658557585585855958560585615856258563585645856558566585675856858569585705857158572585735857458575585765857758578585795858058581585825858358584585855858658587585885858958590585915859258593585945859558596585975859858599586005860158602586035860458605586065860758608586095861058611586125861358614586155861658617586185861958620586215862258623586245862558626586275862858629586305863158632586335863458635586365863758638586395864058641586425864358644586455864658647586485864958650586515865258653586545865558656586575865858659586605866158662586635866458665586665866758668586695867058671586725867358674586755867658677586785867958680586815868258683586845868558686586875868858689586905869158692586935869458695586965869758698586995870058701587025870358704587055870658707587085870958710587115871258713587145871558716587175871858719587205872158722587235872458725587265872758728587295873058731587325873358734587355873658737587385873958740587415874258743587445874558746587475874858749587505875158752587535875458755587565875758758587595876058761587625876358764587655876658767587685876958770587715877258773587745877558776587775877858779587805878158782587835878458785587865878758788587895879058791587925879358794587955879658797587985879958800588015880258803588045880558806588075880858809588105881158812588135881458815588165881758818588195882058821588225882358824588255882658827588285882958830588315883258833588345883558836588375883858839588405884158842588435884458845588465884758848588495885058851588525885358854588555885658857588585885958860588615886258863588645886558866588675886858869588705887158872588735887458875588765887758878588795888058881588825888358884588855888658887588885888958890588915889258893588945889558896588975889858899589005890158902589035890458905589065890758908589095891058911589125891358914589155891658917589185891958920589215892258923589245892558926589275892858929589305893158932589335893458935589365893758938589395894058941589425894358944589455894658947589485894958950589515895258953589545895558956589575895858959589605896158962589635896458965589665896758968589695897058971589725897358974589755897658977589785897958980589815898258983589845898558986589875898858989589905899158992589935899458995589965899758998589995900059001590025900359004590055900659007590085900959010590115901259013590145901559016590175901859019590205902159022590235902459025590265902759028590295903059031590325903359034590355903659037590385903959040590415904259043590445904559046590475904859049590505905159052590535905459055590565905759058590595906059061590625906359064590655906659067590685906959070590715907259073590745907559076590775907859079590805908159082590835908459085590865908759088590895909059091590925909359094590955909659097590985909959100591015910259103591045910559106591075910859109591105911159112591135911459115591165911759118591195912059121591225912359124591255912659127591285912959130591315913259133591345913559136591375913859139591405914159142591435914459145591465914759148591495915059151591525915359154591555915659157591585915959160591615916259163591645916559166591675916859169591705917159172591735917459175591765917759178591795918059181591825918359184591855918659187591885918959190591915919259193591945919559196591975919859199592005920159202592035920459205592065920759208592095921059211592125921359214592155921659217592185921959220592215922259223592245922559226592275922859229592305923159232592335923459235592365923759238592395924059241592425924359244592455924659247592485924959250592515925259253592545925559256592575925859259592605926159262592635926459265592665926759268592695927059271592725927359274592755927659277592785927959280592815928259283592845928559286592875928859289592905929159292592935929459295592965929759298592995930059301593025930359304593055930659307593085930959310593115931259313593145931559316593175931859319593205932159322593235932459325593265932759328593295933059331593325933359334593355933659337593385933959340593415934259343593445934559346593475934859349593505935159352593535935459355593565935759358593595936059361593625936359364593655936659367593685936959370593715937259373593745937559376593775937859379593805938159382593835938459385593865938759388593895939059391593925939359394593955939659397593985939959400594015940259403594045940559406594075940859409594105941159412594135941459415594165941759418594195942059421594225942359424594255942659427594285942959430594315943259433594345943559436594375943859439594405944159442594435944459445594465944759448594495945059451594525945359454594555945659457594585945959460594615946259463594645946559466594675946859469594705947159472594735947459475594765947759478594795948059481594825948359484594855948659487594885948959490594915949259493594945949559496594975949859499595005950159502595035950459505595065950759508595095951059511595125951359514595155951659517595185951959520595215952259523595245952559526595275952859529595305953159532595335953459535595365953759538595395954059541595425954359544595455954659547595485954959550595515955259553595545955559556595575955859559595605956159562595635956459565595665956759568595695957059571595725957359574595755957659577595785957959580595815958259583595845958559586595875958859589595905959159592595935959459595595965959759598595995960059601596025960359604596055960659607596085960959610596115961259613596145961559616596175961859619596205962159622596235962459625596265962759628596295963059631596325963359634596355963659637596385963959640596415964259643596445964559646596475964859649596505965159652596535965459655596565965759658596595966059661596625966359664596655966659667596685966959670596715967259673596745967559676596775967859679596805968159682596835968459685596865968759688596895969059691596925969359694596955969659697596985969959700597015970259703597045970559706597075970859709597105971159712597135971459715597165971759718597195972059721597225972359724597255972659727597285972959730597315973259733597345973559736597375973859739597405974159742597435974459745597465974759748597495975059751597525975359754597555975659757597585975959760597615976259763597645976559766597675976859769597705977159772597735977459775597765977759778597795978059781597825978359784597855978659787597885978959790597915979259793597945979559796597975979859799598005980159802598035980459805598065980759808598095981059811598125981359814598155981659817598185981959820598215982259823598245982559826598275982859829598305983159832598335983459835598365983759838598395984059841598425984359844598455984659847598485984959850598515985259853598545985559856598575985859859598605986159862598635986459865598665986759868598695987059871598725987359874598755987659877598785987959880598815988259883598845988559886598875988859889598905989159892598935989459895598965989759898598995990059901599025990359904599055990659907599085990959910599115991259913599145991559916599175991859919599205992159922599235992459925599265992759928599295993059931599325993359934599355993659937599385993959940599415994259943599445994559946599475994859949599505995159952599535995459955599565995759958599595996059961599625996359964599655996659967599685996959970599715997259973599745997559976599775997859979599805998159982599835998459985599865998759988599895999059991599925999359994599955999659997599985999960000600016000260003600046000560006600076000860009600106001160012600136001460015600166001760018600196002060021600226002360024600256002660027600286002960030600316003260033600346003560036600376003860039600406004160042600436004460045600466004760048600496005060051600526005360054600556005660057600586005960060600616006260063600646006560066600676006860069600706007160072600736007460075600766007760078600796008060081600826008360084600856008660087600886008960090600916009260093600946009560096600976009860099601006010160102601036010460105601066010760108601096011060111601126011360114601156011660117601186011960120601216012260123601246012560126601276012860129601306013160132601336013460135601366013760138601396014060141601426014360144601456014660147601486014960150601516015260153601546015560156601576015860159601606016160162601636016460165601666016760168601696017060171601726017360174601756017660177601786017960180601816018260183601846018560186601876018860189601906019160192601936019460195601966019760198601996020060201602026020360204602056020660207602086020960210602116021260213602146021560216602176021860219602206022160222602236022460225602266022760228602296023060231602326023360234602356023660237602386023960240602416024260243602446024560246602476024860249602506025160252602536025460255602566025760258602596026060261602626026360264602656026660267602686026960270602716027260273602746027560276602776027860279602806028160282602836028460285602866028760288602896029060291602926029360294602956029660297602986029960300603016030260303603046030560306603076030860309603106031160312603136031460315603166031760318603196032060321603226032360324603256032660327603286032960330603316033260333603346033560336603376033860339603406034160342603436034460345603466034760348603496035060351603526035360354603556035660357603586035960360603616036260363603646036560366603676036860369603706037160372603736037460375603766037760378603796038060381603826038360384603856038660387603886038960390603916039260393603946039560396603976039860399604006040160402604036040460405604066040760408604096041060411604126041360414604156041660417604186041960420604216042260423604246042560426604276042860429604306043160432604336043460435604366043760438604396044060441604426044360444604456044660447604486044960450604516045260453604546045560456604576045860459604606046160462604636046460465604666046760468604696047060471604726047360474604756047660477604786047960480604816048260483604846048560486604876048860489604906049160492604936049460495604966049760498604996050060501605026050360504605056050660507605086050960510605116051260513605146051560516605176051860519605206052160522605236052460525605266052760528605296053060531605326053360534605356053660537605386053960540605416054260543605446054560546605476054860549605506055160552605536055460555605566055760558605596056060561605626056360564605656056660567605686056960570605716057260573605746057560576605776057860579605806058160582605836058460585605866058760588605896059060591605926059360594605956059660597605986059960600606016060260603606046060560606606076060860609606106061160612606136061460615606166061760618606196062060621606226062360624606256062660627606286062960630606316063260633606346063560636606376063860639606406064160642606436064460645606466064760648606496065060651606526065360654606556065660657606586065960660606616066260663606646066560666606676066860669606706067160672606736067460675606766067760678606796068060681606826068360684606856068660687606886068960690606916069260693606946069560696606976069860699607006070160702607036070460705607066070760708607096071060711607126071360714607156071660717607186071960720607216072260723607246072560726607276072860729607306073160732607336073460735607366073760738607396074060741607426074360744607456074660747607486074960750607516075260753607546075560756607576075860759607606076160762607636076460765607666076760768607696077060771607726077360774607756077660777607786077960780607816078260783607846078560786607876078860789607906079160792607936079460795607966079760798607996080060801608026080360804608056080660807608086080960810608116081260813608146081560816608176081860819608206082160822608236082460825608266082760828608296083060831608326083360834608356083660837608386083960840608416084260843608446084560846608476084860849608506085160852608536085460855608566085760858608596086060861608626086360864608656086660867608686086960870608716087260873608746087560876608776087860879608806088160882608836088460885608866088760888608896089060891608926089360894608956089660897608986089960900609016090260903609046090560906609076090860909609106091160912609136091460915609166091760918609196092060921609226092360924609256092660927609286092960930609316093260933609346093560936609376093860939609406094160942609436094460945609466094760948609496095060951609526095360954609556095660957609586095960960609616096260963609646096560966609676096860969609706097160972609736097460975609766097760978609796098060981609826098360984609856098660987609886098960990609916099260993609946099560996609976099860999610006100161002610036100461005610066100761008610096101061011610126101361014610156101661017610186101961020610216102261023610246102561026610276102861029610306103161032610336103461035610366103761038610396104061041610426104361044610456104661047610486104961050610516105261053610546105561056610576105861059610606106161062610636106461065610666106761068610696107061071610726107361074610756107661077610786107961080610816108261083610846108561086610876108861089610906109161092610936109461095610966109761098610996110061101611026110361104611056110661107611086110961110611116111261113611146111561116611176111861119611206112161122611236112461125611266112761128611296113061131611326113361134611356113661137611386113961140611416114261143611446114561146611476114861149611506115161152611536115461155611566115761158611596116061161611626116361164611656116661167611686116961170611716117261173611746117561176611776117861179611806118161182611836118461185611866118761188611896119061191611926119361194611956119661197611986119961200612016120261203612046120561206612076120861209612106121161212612136121461215612166121761218612196122061221612226122361224612256122661227612286122961230612316123261233612346123561236612376123861239612406124161242612436124461245612466124761248612496125061251612526125361254612556125661257612586125961260612616126261263612646126561266612676126861269612706127161272612736127461275612766127761278612796128061281612826128361284612856128661287612886128961290612916129261293612946129561296612976129861299613006130161302613036130461305613066130761308613096131061311613126131361314613156131661317613186131961320613216132261323613246132561326613276132861329613306133161332613336133461335613366133761338613396134061341613426134361344613456134661347613486134961350613516135261353613546135561356613576135861359613606136161362613636136461365613666136761368613696137061371613726137361374613756137661377613786137961380613816138261383613846138561386613876138861389613906139161392613936139461395613966139761398613996140061401614026140361404614056140661407614086140961410614116141261413614146141561416614176141861419614206142161422614236142461425614266142761428614296143061431614326143361434614356143661437614386143961440614416144261443614446144561446614476144861449614506145161452614536145461455614566145761458614596146061461614626146361464614656146661467614686146961470614716147261473614746147561476614776147861479614806148161482614836148461485614866148761488614896149061491614926149361494614956149661497614986149961500615016150261503615046150561506615076150861509615106151161512615136151461515615166151761518615196152061521615226152361524615256152661527615286152961530615316153261533615346153561536615376153861539615406154161542615436154461545615466154761548615496155061551615526155361554615556155661557615586155961560615616156261563615646156561566615676156861569615706157161572615736157461575615766157761578615796158061581615826158361584615856158661587615886158961590615916159261593615946159561596615976159861599616006160161602616036160461605616066160761608616096161061611616126161361614616156161661617616186161961620616216162261623616246162561626616276162861629616306163161632616336163461635616366163761638616396164061641616426164361644616456164661647616486164961650616516165261653616546165561656616576165861659616606166161662616636166461665616666166761668616696167061671616726167361674616756167661677616786167961680616816168261683616846168561686616876168861689616906169161692616936169461695616966169761698616996170061701617026170361704617056170661707617086170961710617116171261713617146171561716617176171861719617206172161722617236172461725617266172761728617296173061731617326173361734617356173661737617386173961740617416174261743617446174561746617476174861749617506175161752617536175461755617566175761758617596176061761617626176361764617656176661767617686176961770617716177261773617746177561776617776177861779617806178161782617836178461785617866178761788617896179061791617926179361794617956179661797617986179961800618016180261803618046180561806618076180861809618106181161812618136181461815618166181761818618196182061821618226182361824618256182661827618286182961830618316183261833618346183561836618376183861839618406184161842618436184461845618466184761848618496185061851618526185361854618556185661857618586185961860618616186261863618646186561866618676186861869618706187161872618736187461875618766187761878618796188061881618826188361884618856188661887618886188961890618916189261893618946189561896618976189861899619006190161902619036190461905619066190761908619096191061911619126191361914619156191661917619186191961920619216192261923619246192561926619276192861929619306193161932619336193461935619366193761938619396194061941619426194361944619456194661947619486194961950619516195261953619546195561956619576195861959619606196161962619636196461965619666196761968619696197061971619726197361974619756197661977619786197961980619816198261983619846198561986619876198861989619906199161992619936199461995619966199761998619996200062001620026200362004620056200662007620086200962010620116201262013620146201562016620176201862019620206202162022620236202462025620266202762028620296203062031620326203362034620356203662037620386203962040620416204262043620446204562046620476204862049620506205162052620536205462055620566205762058620596206062061620626206362064620656206662067620686206962070620716207262073620746207562076620776207862079620806208162082620836208462085620866208762088620896209062091620926209362094620956209662097620986209962100621016210262103621046210562106621076210862109621106211162112621136211462115621166211762118621196212062121621226212362124621256212662127621286212962130621316213262133621346213562136621376213862139621406214162142621436214462145621466214762148621496215062151621526215362154621556215662157621586215962160621616216262163621646216562166621676216862169621706217162172621736217462175621766217762178621796218062181621826218362184621856218662187621886218962190621916219262193621946219562196621976219862199622006220162202622036220462205622066220762208622096221062211622126221362214622156221662217622186221962220622216222262223622246222562226622276222862229622306223162232622336223462235622366223762238622396224062241622426224362244622456224662247622486224962250622516225262253622546225562256622576225862259622606226162262622636226462265622666226762268622696227062271622726227362274622756227662277622786227962280622816228262283622846228562286622876228862289622906229162292622936229462295622966229762298622996230062301623026230362304623056230662307623086230962310623116231262313623146231562316623176231862319623206232162322623236232462325623266232762328623296233062331623326233362334623356233662337623386233962340623416234262343623446234562346623476234862349623506235162352623536235462355623566235762358623596236062361623626236362364623656236662367623686236962370623716237262373623746237562376623776237862379623806238162382623836238462385623866238762388623896239062391623926239362394623956239662397623986239962400624016240262403624046240562406624076240862409624106241162412624136241462415624166241762418624196242062421624226242362424624256242662427624286242962430624316243262433624346243562436624376243862439624406244162442624436244462445624466244762448624496245062451624526245362454624556245662457624586245962460624616246262463624646246562466624676246862469624706247162472624736247462475624766247762478624796248062481624826248362484624856248662487624886248962490624916249262493624946249562496624976249862499625006250162502625036250462505625066250762508625096251062511625126251362514625156251662517625186251962520625216252262523625246252562526625276252862529625306253162532625336253462535625366253762538625396254062541625426254362544625456254662547625486254962550625516255262553625546255562556625576255862559625606256162562625636256462565625666256762568625696257062571625726257362574625756257662577625786257962580625816258262583625846258562586625876258862589625906259162592625936259462595625966259762598625996260062601626026260362604626056260662607626086260962610626116261262613626146261562616626176261862619626206262162622626236262462625626266262762628626296263062631626326263362634626356263662637626386263962640626416264262643626446264562646626476264862649626506265162652626536265462655626566265762658626596266062661626626266362664626656266662667626686266962670626716267262673626746267562676626776267862679626806268162682626836268462685626866268762688626896269062691626926269362694626956269662697626986269962700627016270262703627046270562706627076270862709627106271162712627136271462715627166271762718627196272062721627226272362724627256272662727627286272962730627316273262733627346273562736627376273862739627406274162742627436274462745627466274762748627496275062751627526275362754627556275662757627586275962760627616276262763627646276562766627676276862769627706277162772627736277462775627766277762778627796278062781627826278362784627856278662787627886278962790627916279262793627946279562796627976279862799628006280162802628036280462805628066280762808628096281062811628126281362814628156281662817628186281962820628216282262823628246282562826628276282862829628306283162832628336283462835628366283762838628396284062841628426284362844628456284662847628486284962850628516285262853628546285562856628576285862859628606286162862628636286462865628666286762868628696287062871628726287362874628756287662877628786287962880628816288262883628846288562886628876288862889628906289162892628936289462895628966289762898628996290062901629026290362904629056290662907629086290962910629116291262913629146291562916629176291862919629206292162922629236292462925629266292762928629296293062931629326293362934629356293662937629386293962940629416294262943629446294562946629476294862949629506295162952629536295462955629566295762958629596296062961629626296362964629656296662967629686296962970629716297262973629746297562976629776297862979629806298162982629836298462985629866298762988629896299062991629926299362994629956299662997629986299963000630016300263003630046300563006630076300863009630106301163012630136301463015630166301763018630196302063021630226302363024630256302663027630286302963030630316303263033630346303563036630376303863039630406304163042630436304463045630466304763048630496305063051630526305363054630556305663057630586305963060630616306263063630646306563066630676306863069630706307163072630736307463075630766307763078630796308063081630826308363084630856308663087630886308963090630916309263093630946309563096630976309863099631006310163102631036310463105631066310763108631096311063111631126311363114631156311663117631186311963120631216312263123631246312563126631276312863129631306313163132631336313463135631366313763138631396314063141631426314363144631456314663147631486314963150631516315263153631546315563156631576315863159631606316163162631636316463165631666316763168631696317063171631726317363174631756317663177631786317963180631816318263183631846318563186631876318863189631906319163192631936319463195631966319763198631996320063201632026320363204632056320663207632086320963210632116321263213632146321563216632176321863219632206322163222632236322463225632266322763228632296323063231632326323363234632356323663237632386323963240632416324263243632446324563246632476324863249632506325163252632536325463255632566325763258632596326063261632626326363264632656326663267632686326963270632716327263273632746327563276632776327863279632806328163282632836328463285632866328763288632896329063291632926329363294632956329663297632986329963300633016330263303633046330563306633076330863309633106331163312633136331463315633166331763318633196332063321633226332363324633256332663327633286332963330633316333263333633346333563336633376333863339633406334163342633436334463345633466334763348633496335063351633526335363354633556335663357633586335963360633616336263363633646336563366633676336863369633706337163372633736337463375633766337763378633796338063381633826338363384633856338663387633886338963390633916339263393633946339563396633976339863399634006340163402634036340463405634066340763408634096341063411634126341363414634156341663417634186341963420634216342263423634246342563426634276342863429634306343163432634336343463435634366343763438634396344063441634426344363444634456344663447634486344963450634516345263453634546345563456634576345863459634606346163462634636346463465634666346763468634696347063471634726347363474634756347663477634786347963480634816348263483634846348563486634876348863489634906349163492634936349463495634966349763498634996350063501635026350363504635056350663507635086350963510635116351263513635146351563516635176351863519635206352163522635236352463525635266352763528635296353063531635326353363534635356353663537635386353963540635416354263543635446354563546635476354863549635506355163552635536355463555635566355763558635596356063561635626356363564635656356663567635686356963570635716357263573635746357563576635776357863579635806358163582635836358463585635866358763588635896359063591635926359363594635956359663597635986359963600636016360263603636046360563606636076360863609636106361163612636136361463615636166361763618636196362063621636226362363624636256362663627636286362963630636316363263633636346363563636636376363863639636406364163642636436364463645636466364763648636496365063651636526365363654636556365663657636586365963660636616366263663636646366563666636676366863669636706367163672636736367463675636766367763678636796368063681636826368363684636856368663687636886368963690636916369263693636946369563696636976369863699637006370163702637036370463705637066370763708637096371063711637126371363714637156371663717637186371963720637216372263723637246372563726637276372863729637306373163732637336373463735637366373763738637396374063741637426374363744637456374663747637486374963750637516375263753637546375563756637576375863759637606376163762637636376463765637666376763768637696377063771637726377363774637756377663777637786377963780637816378263783637846378563786637876378863789637906379163792637936379463795637966379763798637996380063801638026380363804638056380663807638086380963810638116381263813638146381563816638176381863819638206382163822638236382463825638266382763828638296383063831638326383363834638356383663837638386383963840638416384263843638446384563846638476384863849638506385163852638536385463855638566385763858638596386063861638626386363864638656386663867638686386963870638716387263873638746387563876638776387863879638806388163882638836388463885638866388763888638896389063891638926389363894638956389663897638986389963900639016390263903639046390563906639076390863909639106391163912639136391463915639166391763918639196392063921639226392363924639256392663927639286392963930639316393263933639346393563936639376393863939639406394163942639436394463945639466394763948639496395063951639526395363954639556395663957639586395963960639616396263963639646396563966639676396863969639706397163972639736397463975639766397763978639796398063981639826398363984639856398663987639886398963990639916399263993639946399563996639976399863999640006400164002640036400464005640066400764008640096401064011640126401364014640156401664017640186401964020640216402264023640246402564026640276402864029640306403164032640336403464035640366403764038640396404064041640426404364044640456404664047640486404964050640516405264053640546405564056640576405864059640606406164062640636406464065640666406764068640696407064071640726407364074640756407664077640786407964080640816408264083640846408564086640876408864089640906409164092640936409464095640966409764098640996410064101641026410364104641056410664107641086410964110641116411264113641146411564116641176411864119641206412164122641236412464125641266412764128641296413064131641326413364134641356413664137641386413964140641416414264143641446414564146641476414864149641506415164152641536415464155641566415764158641596416064161641626416364164641656416664167641686416964170641716417264173641746417564176641776417864179641806418164182641836418464185641866418764188641896419064191641926419364194641956419664197641986419964200642016420264203642046420564206642076420864209642106421164212642136421464215642166421764218642196422064221642226422364224642256422664227642286422964230642316423264233642346423564236642376423864239642406424164242642436424464245642466424764248642496425064251642526425364254642556425664257642586425964260642616426264263642646426564266642676426864269642706427164272642736427464275642766427764278642796428064281642826428364284642856428664287642886428964290642916429264293642946429564296642976429864299643006430164302643036430464305643066430764308643096431064311643126431364314643156431664317643186431964320643216432264323643246432564326643276432864329643306433164332643336433464335643366433764338643396434064341643426434364344643456434664347643486434964350643516435264353643546435564356643576435864359643606436164362643636436464365643666436764368643696437064371643726437364374643756437664377643786437964380643816438264383643846438564386643876438864389643906439164392643936439464395643966439764398643996440064401644026440364404644056440664407644086440964410644116441264413644146441564416644176441864419644206442164422644236442464425644266442764428644296443064431644326443364434644356443664437644386443964440644416444264443644446444564446644476444864449644506445164452644536445464455644566445764458644596446064461644626446364464644656446664467644686446964470644716447264473644746447564476644776447864479644806448164482644836448464485644866448764488644896449064491644926449364494644956449664497644986449964500645016450264503645046450564506645076450864509645106451164512645136451464515645166451764518645196452064521645226452364524645256452664527645286452964530645316453264533645346453564536645376453864539645406454164542645436454464545645466454764548645496455064551645526455364554645556455664557645586455964560645616456264563645646456564566645676456864569645706457164572645736457464575645766457764578645796458064581645826458364584645856458664587645886458964590645916459264593645946459564596645976459864599646006460164602646036460464605646066460764608646096461064611646126461364614646156461664617646186461964620646216462264623646246462564626646276462864629646306463164632646336463464635646366463764638646396464064641646426464364644646456464664647646486464964650646516465264653646546465564656646576465864659646606466164662646636466464665646666466764668646696467064671646726467364674646756467664677646786467964680646816468264683646846468564686646876468864689646906469164692646936469464695646966469764698646996470064701647026470364704647056470664707647086470964710647116471264713647146471564716647176471864719647206472164722647236472464725647266472764728647296473064731647326473364734647356473664737647386473964740647416474264743647446474564746647476474864749647506475164752647536475464755647566475764758647596476064761647626476364764647656476664767647686476964770647716477264773647746477564776647776477864779647806478164782647836478464785647866478764788647896479064791647926479364794647956479664797647986479964800648016480264803648046480564806648076480864809648106481164812648136481464815648166481764818648196482064821648226482364824648256482664827648286482964830648316483264833648346483564836648376483864839648406484164842648436484464845648466484764848648496485064851648526485364854648556485664857648586485964860648616486264863648646486564866648676486864869648706487164872648736487464875648766487764878648796488064881648826488364884648856488664887648886488964890648916489264893648946489564896648976489864899649006490164902649036490464905649066490764908649096491064911649126491364914649156491664917649186491964920649216492264923649246492564926649276492864929649306493164932649336493464935649366493764938649396494064941649426494364944649456494664947649486494964950649516495264953649546495564956649576495864959649606496164962649636496464965649666496764968649696497064971649726497364974649756497664977649786497964980649816498264983649846498564986649876498864989649906499164992649936499464995649966499764998649996500065001650026500365004650056500665007650086500965010650116501265013650146501565016650176501865019650206502165022650236502465025650266502765028650296503065031650326503365034650356503665037650386503965040650416504265043650446504565046650476504865049650506505165052650536505465055650566505765058650596506065061650626506365064650656506665067650686506965070650716507265073650746507565076650776507865079650806508165082650836508465085650866508765088650896509065091650926509365094650956509665097650986509965100651016510265103651046510565106651076510865109651106511165112651136511465115651166511765118651196512065121651226512365124651256512665127651286512965130651316513265133651346513565136651376513865139651406514165142651436514465145651466514765148651496515065151651526515365154651556515665157651586515965160651616516265163651646516565166651676516865169651706517165172651736517465175651766517765178651796518065181651826518365184651856518665187651886518965190651916519265193651946519565196651976519865199652006520165202652036520465205652066520765208652096521065211652126521365214652156521665217652186521965220652216522265223652246522565226652276522865229652306523165232652336523465235652366523765238652396524065241652426524365244652456524665247652486524965250652516525265253652546525565256652576525865259652606526165262652636526465265652666526765268652696527065271652726527365274652756527665277652786527965280652816528265283652846528565286652876528865289652906529165292652936529465295652966529765298652996530065301653026530365304653056530665307653086530965310653116531265313653146531565316653176531865319653206532165322653236532465325653266532765328653296533065331653326533365334653356533665337653386533965340653416534265343653446534565346653476534865349653506535165352653536535465355653566535765358653596536065361653626536365364653656536665367653686536965370653716537265373653746537565376653776537865379653806538165382653836538465385653866538765388653896539065391653926539365394653956539665397653986539965400654016540265403654046540565406654076540865409654106541165412654136541465415654166541765418654196542065421654226542365424654256542665427654286542965430654316543265433654346543565436654376543865439654406544165442654436544465445654466544765448654496545065451654526545365454654556545665457654586545965460654616546265463654646546565466654676546865469654706547165472654736547465475654766547765478654796548065481654826548365484654856548665487654886548965490654916549265493654946549565496654976549865499655006550165502655036550465505655066550765508655096551065511655126551365514655156551665517655186551965520655216552265523655246552565526655276552865529655306553165532655336553465535655366553765538655396554065541655426554365544655456554665547655486554965550655516555265553655546555565556655576555865559655606556165562655636556465565655666556765568655696557065571655726557365574655756557665577655786557965580655816558265583655846558565586655876558865589655906559165592655936559465595655966559765598655996560065601656026560365604656056560665607656086560965610656116561265613656146561565616656176561865619656206562165622656236562465625656266562765628656296563065631656326563365634656356563665637656386563965640656416564265643656446564565646656476564865649656506565165652656536565465655656566565765658656596566065661656626566365664656656566665667656686566965670656716567265673656746567565676656776567865679656806568165682656836568465685656866568765688656896569065691656926569365694656956569665697656986569965700657016570265703657046570565706657076570865709657106571165712657136571465715657166571765718657196572065721657226572365724657256572665727657286572965730657316573265733657346573565736657376573865739657406574165742657436574465745657466574765748657496575065751657526575365754657556575665757657586575965760657616576265763657646576565766657676576865769657706577165772657736577465775657766577765778657796578065781657826578365784657856578665787657886578965790657916579265793657946579565796657976579865799658006580165802658036580465805658066580765808658096581065811658126581365814658156581665817658186581965820658216582265823658246582565826658276582865829658306583165832658336583465835658366583765838658396584065841658426584365844658456584665847658486584965850658516585265853658546585565856658576585865859658606586165862658636586465865658666586765868658696587065871658726587365874658756587665877658786587965880658816588265883658846588565886658876588865889658906589165892658936589465895658966589765898658996590065901659026590365904659056590665907659086590965910659116591265913659146591565916659176591865919659206592165922659236592465925659266592765928659296593065931659326593365934659356593665937659386593965940659416594265943659446594565946659476594865949659506595165952659536595465955659566595765958659596596065961659626596365964659656596665967659686596965970659716597265973659746597565976659776597865979659806598165982659836598465985659866598765988659896599065991659926599365994659956599665997659986599966000660016600266003660046600566006660076600866009660106601166012660136601466015660166601766018660196602066021660226602366024660256602666027660286602966030660316603266033660346603566036660376603866039660406604166042660436604466045660466604766048660496605066051660526605366054660556605666057660586605966060660616606266063660646606566066660676606866069660706607166072660736607466075660766607766078660796608066081660826608366084660856608666087660886608966090660916609266093660946609566096660976609866099661006610166102661036610466105661066610766108661096611066111661126611366114661156611666117661186611966120661216612266123661246612566126661276612866129661306613166132661336613466135661366613766138661396614066141661426614366144661456614666147661486614966150661516615266153661546615566156661576615866159661606616166162661636616466165661666616766168661696617066171661726617366174661756617666177661786617966180661816618266183661846618566186661876618866189661906619166192661936619466195661966619766198661996620066201662026620366204662056620666207662086620966210662116621266213662146621566216662176621866219662206622166222662236622466225662266622766228662296623066231662326623366234662356623666237662386623966240662416624266243662446624566246662476624866249662506625166252662536625466255662566625766258662596626066261662626626366264662656626666267662686626966270662716627266273662746627566276662776627866279662806628166282662836628466285662866628766288662896629066291662926629366294662956629666297662986629966300663016630266303663046630566306663076630866309663106631166312663136631466315663166631766318663196632066321663226632366324663256632666327663286632966330663316633266333663346633566336663376633866339663406634166342663436634466345663466634766348663496635066351663526635366354663556635666357663586635966360663616636266363663646636566366663676636866369663706637166372663736637466375663766637766378663796638066381663826638366384663856638666387663886638966390663916639266393663946639566396663976639866399664006640166402664036640466405664066640766408664096641066411664126641366414664156641666417664186641966420664216642266423664246642566426664276642866429664306643166432664336643466435664366643766438664396644066441664426644366444664456644666447664486644966450664516645266453664546645566456664576645866459664606646166462664636646466465664666646766468664696647066471664726647366474664756647666477664786647966480664816648266483664846648566486664876648866489664906649166492664936649466495664966649766498664996650066501665026650366504665056650666507665086650966510665116651266513665146651566516665176651866519665206652166522665236652466525665266652766528665296653066531665326653366534665356653666537665386653966540665416654266543665446654566546665476654866549665506655166552665536655466555665566655766558665596656066561665626656366564665656656666567665686656966570665716657266573665746657566576665776657866579665806658166582665836658466585665866658766588665896659066591665926659366594665956659666597665986659966600666016660266603666046660566606666076660866609666106661166612666136661466615666166661766618666196662066621666226662366624666256662666627666286662966630666316663266633666346663566636666376663866639666406664166642666436664466645666466664766648666496665066651666526665366654666556665666657666586665966660666616666266663666646666566666666676666866669666706667166672666736667466675666766667766678666796668066681666826668366684666856668666687666886668966690666916669266693666946669566696666976669866699667006670166702667036670466705667066670766708667096671066711667126671366714667156671666717667186671966720667216672266723667246672566726667276672866729667306673166732667336673466735667366673766738667396674066741667426674366744667456674666747667486674966750667516675266753667546675566756667576675866759667606676166762667636676466765667666676766768667696677066771667726677366774667756677666777667786677966780667816678266783667846678566786667876678866789667906679166792667936679466795667966679766798667996680066801668026680366804668056680666807668086680966810668116681266813668146681566816668176681866819668206682166822668236682466825668266682766828668296683066831668326683366834668356683666837668386683966840668416684266843668446684566846668476684866849668506685166852668536685466855668566685766858668596686066861668626686366864668656686666867668686686966870668716687266873668746687566876668776687866879668806688166882668836688466885668866688766888668896689066891668926689366894668956689666897668986689966900669016690266903669046690566906669076690866909669106691166912669136691466915669166691766918669196692066921669226692366924669256692666927669286692966930669316693266933669346693566936669376693866939669406694166942669436694466945669466694766948669496695066951669526695366954669556695666957669586695966960669616696266963669646696566966669676696866969669706697166972669736697466975669766697766978669796698066981669826698366984669856698666987669886698966990669916699266993669946699566996669976699866999670006700167002670036700467005670066700767008670096701067011670126701367014670156701667017670186701967020670216702267023670246702567026670276702867029670306703167032670336703467035670366703767038670396704067041670426704367044670456704667047670486704967050670516705267053670546705567056670576705867059670606706167062670636706467065670666706767068670696707067071670726707367074670756707667077670786707967080670816708267083670846708567086670876708867089670906709167092670936709467095670966709767098670996710067101671026710367104671056710667107671086710967110671116711267113671146711567116671176711867119671206712167122671236712467125671266712767128671296713067131671326713367134671356713667137671386713967140671416714267143671446714567146671476714867149671506715167152671536715467155671566715767158671596716067161671626716367164671656716667167671686716967170671716717267173671746717567176671776717867179671806718167182671836718467185671866718767188671896719067191671926719367194671956719667197671986719967200672016720267203672046720567206672076720867209672106721167212672136721467215672166721767218672196722067221672226722367224672256722667227672286722967230672316723267233672346723567236672376723867239672406724167242672436724467245672466724767248672496725067251672526725367254672556725667257672586725967260672616726267263672646726567266672676726867269672706727167272672736727467275672766727767278672796728067281672826728367284672856728667287672886728967290672916729267293672946729567296672976729867299673006730167302673036730467305673066730767308673096731067311673126731367314673156731667317673186731967320673216732267323673246732567326673276732867329673306733167332673336733467335673366733767338673396734067341673426734367344673456734667347673486734967350673516735267353673546735567356673576735867359673606736167362673636736467365673666736767368673696737067371673726737367374673756737667377673786737967380673816738267383673846738567386673876738867389673906739167392673936739467395673966739767398673996740067401674026740367404674056740667407674086740967410674116741267413674146741567416674176741867419674206742167422674236742467425674266742767428674296743067431674326743367434674356743667437674386743967440674416744267443674446744567446674476744867449674506745167452674536745467455674566745767458674596746067461674626746367464674656746667467674686746967470674716747267473674746747567476674776747867479674806748167482674836748467485674866748767488674896749067491674926749367494674956749667497674986749967500675016750267503675046750567506675076750867509675106751167512675136751467515675166751767518675196752067521675226752367524675256752667527675286752967530675316753267533675346753567536675376753867539675406754167542675436754467545675466754767548675496755067551675526755367554675556755667557675586755967560675616756267563675646756567566675676756867569675706757167572675736757467575675766757767578675796758067581675826758367584675856758667587675886758967590675916759267593675946759567596675976759867599676006760167602676036760467605676066760767608676096761067611676126761367614676156761667617676186761967620676216762267623676246762567626676276762867629676306763167632676336763467635676366763767638676396764067641676426764367644676456764667647676486764967650676516765267653676546765567656676576765867659676606766167662676636766467665676666766767668676696767067671676726767367674676756767667677676786767967680676816768267683676846768567686676876768867689676906769167692676936769467695676966769767698676996770067701677026770367704677056770667707677086770967710677116771267713677146771567716677176771867719677206772167722677236772467725677266772767728677296773067731677326773367734677356773667737677386773967740677416774267743677446774567746677476774867749677506775167752677536775467755677566775767758677596776067761677626776367764677656776667767677686776967770677716777267773677746777567776677776777867779677806778167782677836778467785677866778767788677896779067791677926779367794677956779667797677986779967800678016780267803678046780567806678076780867809678106781167812678136781467815678166781767818678196782067821678226782367824678256782667827678286782967830678316783267833678346783567836678376783867839678406784167842678436784467845678466784767848678496785067851678526785367854678556785667857678586785967860678616786267863678646786567866678676786867869678706787167872678736787467875678766787767878678796788067881678826788367884678856788667887678886788967890678916789267893678946789567896678976789867899679006790167902679036790467905679066790767908679096791067911679126791367914679156791667917679186791967920679216792267923679246792567926679276792867929679306793167932679336793467935679366793767938679396794067941679426794367944679456794667947679486794967950679516795267953679546795567956679576795867959679606796167962679636796467965679666796767968679696797067971679726797367974679756797667977679786797967980679816798267983679846798567986679876798867989679906799167992679936799467995679966799767998679996800068001680026800368004680056800668007680086800968010680116801268013680146801568016680176801868019680206802168022680236802468025680266802768028680296803068031680326803368034680356803668037680386803968040680416804268043680446804568046680476804868049680506805168052680536805468055680566805768058680596806068061680626806368064680656806668067680686806968070680716807268073680746807568076680776807868079680806808168082680836808468085680866808768088680896809068091680926809368094680956809668097680986809968100681016810268103681046810568106681076810868109681106811168112681136811468115681166811768118681196812068121681226812368124681256812668127681286812968130681316813268133681346813568136681376813868139681406814168142681436814468145681466814768148681496815068151681526815368154681556815668157681586815968160681616816268163681646816568166681676816868169681706817168172681736817468175681766817768178681796818068181681826818368184681856818668187681886818968190681916819268193681946819568196681976819868199682006820168202682036820468205682066820768208682096821068211682126821368214682156821668217682186821968220682216822268223682246822568226682276822868229682306823168232682336823468235682366823768238682396824068241682426824368244682456824668247682486824968250682516825268253682546825568256682576825868259682606826168262682636826468265682666826768268682696827068271682726827368274682756827668277682786827968280682816828268283682846828568286682876828868289682906829168292682936829468295682966829768298682996830068301683026830368304683056830668307683086830968310683116831268313683146831568316683176831868319683206832168322683236832468325683266832768328683296833068331683326833368334683356833668337683386833968340683416834268343683446834568346683476834868349683506835168352683536835468355683566835768358683596836068361683626836368364683656836668367683686836968370683716837268373683746837568376683776837868379683806838168382683836838468385683866838768388683896839068391683926839368394683956839668397683986839968400684016840268403684046840568406684076840868409684106841168412684136841468415684166841768418684196842068421684226842368424684256842668427684286842968430684316843268433684346843568436684376843868439684406844168442684436844468445684466844768448684496845068451684526845368454684556845668457684586845968460684616846268463684646846568466684676846868469684706847168472684736847468475684766847768478684796848068481684826848368484684856848668487684886848968490684916849268493684946849568496684976849868499685006850168502685036850468505685066850768508685096851068511685126851368514685156851668517685186851968520685216852268523685246852568526685276852868529685306853168532685336853468535685366853768538685396854068541685426854368544685456854668547685486854968550685516855268553685546855568556685576855868559685606856168562685636856468565685666856768568685696857068571685726857368574685756857668577685786857968580685816858268583685846858568586685876858868589685906859168592685936859468595685966859768598685996860068601686026860368604686056860668607686086860968610686116861268613686146861568616686176861868619686206862168622686236862468625686266862768628686296863068631686326863368634686356863668637686386863968640686416864268643686446864568646686476864868649686506865168652686536865468655686566865768658686596866068661686626866368664686656866668667686686866968670686716867268673686746867568676686776867868679686806868168682686836868468685686866868768688686896869068691686926869368694686956869668697686986869968700687016870268703687046870568706687076870868709687106871168712687136871468715687166871768718687196872068721687226872368724687256872668727687286872968730687316873268733687346873568736687376873868739687406874168742687436874468745687466874768748687496875068751687526875368754687556875668757687586875968760687616876268763687646876568766687676876868769687706877168772687736877468775687766877768778687796878068781687826878368784687856878668787687886878968790687916879268793687946879568796687976879868799688006880168802688036880468805688066880768808688096881068811688126881368814688156881668817688186881968820688216882268823688246882568826688276882868829688306883168832688336883468835688366883768838688396884068841688426884368844688456884668847688486884968850688516885268853688546885568856688576885868859688606886168862688636886468865688666886768868688696887068871688726887368874688756887668877688786887968880688816888268883688846888568886688876888868889688906889168892688936889468895688966889768898688996890068901689026890368904689056890668907689086890968910689116891268913689146891568916689176891868919689206892168922689236892468925689266892768928689296893068931689326893368934689356893668937689386893968940689416894268943689446894568946689476894868949689506895168952689536895468955689566895768958689596896068961689626896368964689656896668967689686896968970689716897268973689746897568976689776897868979689806898168982689836898468985689866898768988689896899068991689926899368994689956899668997689986899969000690016900269003690046900569006690076900869009690106901169012690136901469015690166901769018690196902069021690226902369024690256902669027690286902969030690316903269033690346903569036690376903869039690406904169042690436904469045690466904769048690496905069051690526905369054690556905669057690586905969060690616906269063690646906569066690676906869069690706907169072690736907469075690766907769078690796908069081690826908369084690856908669087690886908969090690916909269093690946909569096690976909869099691006910169102691036910469105691066910769108691096911069111691126911369114691156911669117691186911969120691216912269123691246912569126691276912869129691306913169132691336913469135691366913769138691396914069141691426914369144691456914669147691486914969150691516915269153691546915569156691576915869159691606916169162691636916469165691666916769168691696917069171691726917369174691756917669177691786917969180691816918269183691846918569186691876918869189691906919169192691936919469195691966919769198691996920069201692026920369204692056920669207692086920969210692116921269213692146921569216692176921869219692206922169222692236922469225692266922769228692296923069231692326923369234692356923669237692386923969240692416924269243692446924569246692476924869249692506925169252692536925469255692566925769258692596926069261692626926369264692656926669267692686926969270692716927269273692746927569276692776927869279692806928169282692836928469285692866928769288692896929069291692926929369294692956929669297692986929969300693016930269303693046930569306693076930869309693106931169312693136931469315693166931769318693196932069321693226932369324693256932669327693286932969330693316933269333693346933569336693376933869339693406934169342693436934469345693466934769348693496935069351693526935369354693556935669357693586935969360693616936269363693646936569366693676936869369693706937169372693736937469375693766937769378693796938069381693826938369384693856938669387693886938969390693916939269393693946939569396693976939869399694006940169402694036940469405694066940769408694096941069411694126941369414694156941669417694186941969420694216942269423694246942569426694276942869429694306943169432694336943469435694366943769438694396944069441694426944369444694456944669447694486944969450694516945269453694546945569456694576945869459694606946169462694636946469465694666946769468694696947069471694726947369474694756947669477694786947969480694816948269483694846948569486694876948869489694906949169492694936949469495694966949769498694996950069501695026950369504695056950669507695086950969510695116951269513695146951569516695176951869519695206952169522695236952469525695266952769528695296953069531695326953369534695356953669537695386953969540695416954269543695446954569546695476954869549695506955169552695536955469555695566955769558695596956069561695626956369564695656956669567695686956969570695716957269573695746957569576695776957869579695806958169582695836958469585695866958769588695896959069591695926959369594695956959669597695986959969600696016960269603696046960569606696076960869609696106961169612696136961469615696166961769618696196962069621696226962369624696256962669627696286962969630696316963269633696346963569636696376963869639696406964169642696436964469645696466964769648696496965069651696526965369654696556965669657696586965969660696616966269663696646966569666696676966869669696706967169672696736967469675696766967769678696796968069681696826968369684696856968669687696886968969690696916969269693696946969569696696976969869699697006970169702697036970469705697066970769708697096971069711697126971369714697156971669717697186971969720697216972269723697246972569726697276972869729697306973169732697336973469735697366973769738697396974069741697426974369744697456974669747697486974969750697516975269753697546975569756697576975869759697606976169762697636976469765697666976769768697696977069771697726977369774697756977669777697786977969780697816978269783697846978569786697876978869789697906979169792697936979469795697966979769798697996980069801698026980369804698056980669807698086980969810698116981269813698146981569816698176981869819698206982169822698236982469825698266982769828698296983069831698326983369834698356983669837698386983969840698416984269843698446984569846698476984869849698506985169852698536985469855698566985769858698596986069861698626986369864698656986669867698686986969870698716987269873698746987569876698776987869879698806988169882698836988469885698866988769888698896989069891698926989369894698956989669897698986989969900699016990269903699046990569906699076990869909699106991169912699136991469915699166991769918699196992069921699226992369924699256992669927699286992969930699316993269933699346993569936699376993869939699406994169942699436994469945699466994769948699496995069951699526995369954699556995669957699586995969960699616996269963699646996569966699676996869969699706997169972699736997469975699766997769978699796998069981699826998369984699856998669987699886998969990699916999269993699946999569996699976999869999700007000170002700037000470005700067000770008700097001070011700127001370014700157001670017700187001970020700217002270023700247002570026700277002870029700307003170032700337003470035700367003770038700397004070041700427004370044700457004670047700487004970050700517005270053700547005570056700577005870059700607006170062700637006470065700667006770068700697007070071700727007370074700757007670077700787007970080700817008270083700847008570086700877008870089700907009170092700937009470095700967009770098700997010070101701027010370104701057010670107701087010970110701117011270113701147011570116701177011870119701207012170122701237012470125701267012770128701297013070131701327013370134701357013670137701387013970140701417014270143701447014570146701477014870149701507015170152701537015470155701567015770158701597016070161701627016370164701657016670167701687016970170701717017270173701747017570176701777017870179701807018170182701837018470185701867018770188701897019070191701927019370194701957019670197701987019970200702017020270203702047020570206702077020870209702107021170212702137021470215702167021770218702197022070221702227022370224702257022670227702287022970230702317023270233702347023570236702377023870239702407024170242702437024470245702467024770248702497025070251702527025370254702557025670257702587025970260702617026270263702647026570266702677026870269702707027170272702737027470275702767027770278702797028070281702827028370284702857028670287702887028970290702917029270293702947029570296702977029870299703007030170302703037030470305703067030770308703097031070311703127031370314703157031670317703187031970320703217032270323703247032570326703277032870329703307033170332703337033470335703367033770338703397034070341703427034370344703457034670347703487034970350703517035270353703547035570356703577035870359703607036170362703637036470365703667036770368703697037070371703727037370374703757037670377703787037970380703817038270383703847038570386703877038870389703907039170392703937039470395703967039770398703997040070401704027040370404704057040670407704087040970410704117041270413704147041570416704177041870419704207042170422704237042470425704267042770428704297043070431704327043370434704357043670437704387043970440704417044270443704447044570446704477044870449704507045170452704537045470455704567045770458704597046070461704627046370464704657046670467704687046970470704717047270473704747047570476704777047870479704807048170482704837048470485704867048770488704897049070491704927049370494704957049670497704987049970500705017050270503705047050570506705077050870509705107051170512705137051470515705167051770518705197052070521705227052370524705257052670527705287052970530705317053270533705347053570536705377053870539705407054170542705437054470545705467054770548705497055070551705527055370554705557055670557705587055970560705617056270563705647056570566705677056870569705707057170572705737057470575705767057770578705797058070581705827058370584705857058670587705887058970590705917059270593705947059570596705977059870599706007060170602706037060470605706067060770608706097061070611706127061370614706157061670617706187061970620706217062270623706247062570626706277062870629706307063170632706337063470635706367063770638706397064070641706427064370644706457064670647706487064970650706517065270653706547065570656706577065870659706607066170662706637066470665706667066770668706697067070671706727067370674706757067670677706787067970680706817068270683706847068570686706877068870689706907069170692706937069470695706967069770698706997070070701707027070370704707057070670707707087070970710707117071270713707147071570716707177071870719707207072170722707237072470725707267072770728707297073070731707327073370734707357073670737707387073970740707417074270743707447074570746707477074870749707507075170752707537075470755707567075770758707597076070761707627076370764707657076670767707687076970770707717077270773707747077570776707777077870779707807078170782707837078470785707867078770788707897079070791707927079370794707957079670797707987079970800708017080270803708047080570806708077080870809708107081170812708137081470815708167081770818708197082070821708227082370824708257082670827708287082970830708317083270833708347083570836708377083870839708407084170842708437084470845708467084770848708497085070851708527085370854708557085670857708587085970860708617086270863708647086570866708677086870869708707087170872708737087470875708767087770878708797088070881708827088370884708857088670887708887088970890708917089270893708947089570896708977089870899709007090170902709037090470905709067090770908709097091070911709127091370914709157091670917709187091970920709217092270923709247092570926709277092870929709307093170932709337093470935709367093770938709397094070941709427094370944709457094670947709487094970950709517095270953709547095570956709577095870959709607096170962709637096470965709667096770968709697097070971709727097370974709757097670977709787097970980709817098270983709847098570986709877098870989709907099170992709937099470995709967099770998709997100071001710027100371004710057100671007710087100971010710117101271013710147101571016710177101871019710207102171022710237102471025710267102771028710297103071031710327103371034710357103671037710387103971040710417104271043710447104571046710477104871049710507105171052710537105471055710567105771058710597106071061710627106371064710657106671067710687106971070710717107271073710747107571076710777107871079710807108171082710837108471085710867108771088710897109071091710927109371094710957109671097710987109971100711017110271103711047110571106711077110871109711107111171112711137111471115711167111771118711197112071121711227112371124711257112671127711287112971130711317113271133711347113571136711377113871139711407114171142711437114471145711467114771148711497115071151711527115371154711557115671157711587115971160711617116271163711647116571166711677116871169711707117171172711737117471175711767117771178711797118071181711827118371184711857118671187711887118971190711917119271193711947119571196711977119871199712007120171202712037120471205712067120771208712097121071211712127121371214712157121671217712187121971220712217122271223712247122571226712277122871229712307123171232712337123471235712367123771238712397124071241712427124371244712457124671247712487124971250712517125271253712547125571256712577125871259712607126171262712637126471265712667126771268712697127071271712727127371274712757127671277712787127971280712817128271283712847128571286712877128871289712907129171292712937129471295712967129771298712997130071301713027130371304713057130671307713087130971310713117131271313713147131571316713177131871319713207132171322713237132471325713267132771328713297133071331713327133371334713357133671337713387133971340713417134271343713447134571346713477134871349713507135171352713537135471355713567135771358713597136071361713627136371364713657136671367713687136971370713717137271373713747137571376713777137871379713807138171382713837138471385713867138771388713897139071391713927139371394713957139671397713987139971400714017140271403714047140571406714077140871409714107141171412714137141471415714167141771418714197142071421714227142371424714257142671427714287142971430714317143271433714347143571436714377143871439714407144171442714437144471445714467144771448714497145071451714527145371454714557145671457714587145971460714617146271463714647146571466714677146871469714707147171472714737147471475714767147771478714797148071481714827148371484714857148671487714887148971490714917149271493714947149571496714977149871499715007150171502715037150471505715067150771508715097151071511715127151371514715157151671517715187151971520715217152271523715247152571526715277152871529715307153171532715337153471535715367153771538715397154071541715427154371544715457154671547715487154971550715517155271553715547155571556715577155871559715607156171562715637156471565715667156771568715697157071571715727157371574715757157671577715787157971580715817158271583715847158571586715877158871589715907159171592715937159471595715967159771598715997160071601716027160371604716057160671607716087160971610716117161271613716147161571616716177161871619716207162171622716237162471625716267162771628716297163071631716327163371634716357163671637716387163971640716417164271643716447164571646716477164871649716507165171652716537165471655716567165771658716597166071661716627166371664716657166671667716687166971670716717167271673716747167571676716777167871679716807168171682716837168471685716867168771688716897169071691716927169371694716957169671697716987169971700717017170271703717047170571706717077170871709717107171171712717137171471715717167171771718717197172071721717227172371724717257172671727717287172971730717317173271733717347173571736717377173871739717407174171742717437174471745717467174771748717497175071751717527175371754717557175671757717587175971760717617176271763717647176571766717677176871769717707177171772717737177471775717767177771778717797178071781717827178371784717857178671787717887178971790717917179271793717947179571796717977179871799718007180171802718037180471805718067180771808718097181071811718127181371814718157181671817718187181971820718217182271823718247182571826718277182871829718307183171832718337183471835718367183771838718397184071841718427184371844718457184671847718487184971850718517185271853718547185571856718577185871859718607186171862718637186471865718667186771868718697187071871718727187371874718757187671877718787187971880718817188271883718847188571886718877188871889718907189171892718937189471895718967189771898718997190071901719027190371904719057190671907719087190971910719117191271913719147191571916719177191871919719207192171922719237192471925719267192771928719297193071931719327193371934719357193671937719387193971940719417194271943719447194571946719477194871949719507195171952719537195471955719567195771958719597196071961719627196371964719657196671967719687196971970719717197271973719747197571976719777197871979719807198171982719837198471985719867198771988719897199071991719927199371994719957199671997719987199972000720017200272003720047200572006720077200872009720107201172012720137201472015720167201772018720197202072021720227202372024720257202672027720287202972030720317203272033720347203572036720377203872039720407204172042720437204472045720467204772048720497205072051720527205372054720557205672057720587205972060720617206272063720647206572066720677206872069720707207172072720737207472075720767207772078720797208072081720827208372084720857208672087720887208972090720917209272093720947209572096720977209872099721007210172102721037210472105721067210772108721097211072111721127211372114721157211672117721187211972120721217212272123721247212572126721277212872129721307213172132721337213472135721367213772138721397214072141721427214372144721457214672147721487214972150721517215272153721547215572156721577215872159721607216172162721637216472165721667216772168721697217072171721727217372174721757217672177721787217972180721817218272183721847218572186721877218872189721907219172192721937219472195721967219772198721997220072201722027220372204722057220672207722087220972210722117221272213722147221572216722177221872219722207222172222722237222472225722267222772228722297223072231722327223372234722357223672237722387223972240722417224272243722447224572246722477224872249722507225172252722537225472255722567225772258722597226072261722627226372264722657226672267722687226972270722717227272273722747227572276722777227872279722807228172282722837228472285722867228772288722897229072291722927229372294722957229672297722987229972300723017230272303723047230572306723077230872309723107231172312723137231472315723167231772318723197232072321723227232372324723257232672327723287232972330723317233272333723347233572336723377233872339723407234172342723437234472345723467234772348723497235072351723527235372354723557235672357723587235972360723617236272363723647236572366723677236872369723707237172372723737237472375723767237772378723797238072381723827238372384723857238672387723887238972390723917239272393723947239572396723977239872399724007240172402724037240472405724067240772408724097241072411724127241372414724157241672417724187241972420724217242272423724247242572426724277242872429724307243172432724337243472435724367243772438724397244072441724427244372444724457244672447724487244972450724517245272453724547245572456724577245872459724607246172462724637246472465724667246772468724697247072471724727247372474724757247672477724787247972480724817248272483724847248572486724877248872489724907249172492724937249472495724967249772498724997250072501725027250372504725057250672507725087250972510725117251272513725147251572516725177251872519725207252172522725237252472525725267252772528725297253072531725327253372534725357253672537725387253972540725417254272543725447254572546725477254872549725507255172552725537255472555725567255772558725597256072561725627256372564725657256672567725687256972570725717257272573725747257572576725777257872579725807258172582725837258472585725867258772588725897259072591725927259372594725957259672597725987259972600726017260272603726047260572606726077260872609726107261172612726137261472615726167261772618726197262072621726227262372624726257262672627726287262972630726317263272633726347263572636726377263872639726407264172642726437264472645726467264772648726497265072651726527265372654726557265672657726587265972660726617266272663726647266572666726677266872669726707267172672726737267472675726767267772678726797268072681726827268372684726857268672687726887268972690726917269272693726947269572696726977269872699727007270172702727037270472705727067270772708727097271072711727127271372714727157271672717727187271972720727217272272723727247272572726727277272872729727307273172732727337273472735727367273772738727397274072741727427274372744727457274672747727487274972750727517275272753727547275572756727577275872759727607276172762727637276472765727667276772768727697277072771727727277372774727757277672777727787277972780727817278272783727847278572786727877278872789727907279172792727937279472795727967279772798727997280072801728027280372804728057280672807728087280972810728117281272813728147281572816728177281872819728207282172822728237282472825728267282772828728297283072831728327283372834728357283672837728387283972840728417284272843728447284572846728477284872849728507285172852728537285472855728567285772858728597286072861728627286372864728657286672867728687286972870728717287272873728747287572876728777287872879728807288172882728837288472885728867288772888728897289072891728927289372894728957289672897728987289972900729017290272903729047290572906729077290872909729107291172912729137291472915729167291772918729197292072921729227292372924729257292672927729287292972930729317293272933729347293572936729377293872939729407294172942729437294472945729467294772948729497295072951729527295372954729557295672957729587295972960729617296272963729647296572966729677296872969729707297172972729737297472975729767297772978729797298072981729827298372984729857298672987729887298972990729917299272993729947299572996729977299872999730007300173002730037300473005730067300773008730097301073011730127301373014730157301673017730187301973020730217302273023730247302573026730277302873029730307303173032730337303473035730367303773038730397304073041730427304373044730457304673047730487304973050730517305273053730547305573056730577305873059730607306173062730637306473065730667306773068730697307073071730727307373074730757307673077730787307973080730817308273083730847308573086730877308873089730907309173092730937309473095730967309773098730997310073101731027310373104731057310673107731087310973110731117311273113731147311573116731177311873119731207312173122731237312473125731267312773128731297313073131731327313373134731357313673137731387313973140731417314273143731447314573146731477314873149731507315173152731537315473155731567315773158731597316073161731627316373164731657316673167731687316973170731717317273173731747317573176731777317873179731807318173182731837318473185731867318773188731897319073191731927319373194731957319673197731987319973200732017320273203732047320573206732077320873209732107321173212732137321473215732167321773218732197322073221732227322373224732257322673227732287322973230732317323273233732347323573236732377323873239732407324173242732437324473245732467324773248732497325073251732527325373254732557325673257732587325973260732617326273263732647326573266732677326873269732707327173272732737327473275732767327773278732797328073281732827328373284732857328673287732887328973290732917329273293732947329573296732977329873299733007330173302733037330473305733067330773308733097331073311733127331373314733157331673317733187331973320733217332273323733247332573326733277332873329733307333173332733337333473335733367333773338733397334073341733427334373344733457334673347733487334973350733517335273353733547335573356733577335873359733607336173362733637336473365733667336773368733697337073371733727337373374733757337673377733787337973380733817338273383733847338573386733877338873389733907339173392733937339473395733967339773398733997340073401734027340373404734057340673407734087340973410734117341273413734147341573416734177341873419734207342173422734237342473425734267342773428734297343073431734327343373434734357343673437734387343973440734417344273443734447344573446734477344873449734507345173452734537345473455734567345773458734597346073461734627346373464734657346673467734687346973470734717347273473734747347573476734777347873479734807348173482734837348473485734867348773488734897349073491734927349373494734957349673497734987349973500735017350273503735047350573506735077350873509735107351173512735137351473515735167351773518735197352073521735227352373524735257352673527735287352973530735317353273533735347353573536735377353873539735407354173542735437354473545735467354773548735497355073551735527355373554735557355673557735587355973560735617356273563735647356573566735677356873569735707357173572735737357473575735767357773578735797358073581735827358373584735857358673587735887358973590735917359273593735947359573596735977359873599736007360173602736037360473605736067360773608736097361073611736127361373614736157361673617736187361973620736217362273623736247362573626736277362873629736307363173632736337363473635736367363773638736397364073641736427364373644736457364673647736487364973650736517365273653736547365573656736577365873659736607366173662736637366473665736667366773668736697367073671736727367373674736757367673677736787367973680736817368273683736847368573686736877368873689736907369173692736937369473695736967369773698736997370073701737027370373704737057370673707737087370973710737117371273713737147371573716737177371873719737207372173722737237372473725737267372773728737297373073731737327373373734737357373673737737387373973740737417374273743737447374573746737477374873749737507375173752737537375473755737567375773758737597376073761737627376373764737657376673767737687376973770737717377273773737747377573776737777377873779737807378173782737837378473785737867378773788737897379073791737927379373794737957379673797737987379973800738017380273803738047380573806738077380873809738107381173812738137381473815738167381773818738197382073821738227382373824738257382673827738287382973830738317383273833738347383573836738377383873839738407384173842738437384473845738467384773848738497385073851738527385373854738557385673857738587385973860738617386273863738647386573866738677386873869738707387173872738737387473875738767387773878738797388073881738827388373884738857388673887738887388973890738917389273893738947389573896738977389873899739007390173902739037390473905739067390773908739097391073911739127391373914739157391673917739187391973920739217392273923739247392573926739277392873929739307393173932739337393473935739367393773938739397394073941739427394373944739457394673947739487394973950739517395273953739547395573956739577395873959739607396173962739637396473965739667396773968739697397073971739727397373974739757397673977739787397973980739817398273983739847398573986739877398873989739907399173992739937399473995739967399773998739997400074001740027400374004740057400674007740087400974010740117401274013740147401574016740177401874019740207402174022740237402474025740267402774028740297403074031740327403374034740357403674037740387403974040740417404274043740447404574046740477404874049740507405174052740537405474055740567405774058740597406074061740627406374064740657406674067740687406974070740717407274073740747407574076740777407874079740807408174082740837408474085740867408774088740897409074091740927409374094740957409674097740987409974100741017410274103741047410574106741077410874109741107411174112741137411474115741167411774118741197412074121741227412374124741257412674127741287412974130741317413274133741347413574136741377413874139741407414174142741437414474145741467414774148741497415074151741527415374154741557415674157741587415974160741617416274163741647416574166741677416874169741707417174172741737417474175741767417774178741797418074181741827418374184741857418674187741887418974190741917419274193741947419574196741977419874199742007420174202742037420474205742067420774208742097421074211742127421374214742157421674217742187421974220742217422274223742247422574226742277422874229742307423174232742337423474235742367423774238742397424074241742427424374244742457424674247742487424974250742517425274253742547425574256742577425874259742607426174262742637426474265742667426774268742697427074271742727427374274742757427674277742787427974280742817428274283742847428574286742877428874289742907429174292742937429474295742967429774298742997430074301743027430374304743057430674307743087430974310743117431274313743147431574316743177431874319743207432174322743237432474325743267432774328743297433074331743327433374334743357433674337743387433974340743417434274343743447434574346743477434874349743507435174352743537435474355743567435774358743597436074361743627436374364743657436674367743687436974370743717437274373743747437574376743777437874379743807438174382743837438474385743867438774388743897439074391743927439374394743957439674397743987439974400744017440274403744047440574406744077440874409744107441174412744137441474415744167441774418744197442074421744227442374424744257442674427744287442974430744317443274433744347443574436744377443874439744407444174442744437444474445744467444774448744497445074451744527445374454744557445674457744587445974460744617446274463744647446574466744677446874469744707447174472744737447474475744767447774478744797448074481744827448374484744857448674487744887448974490744917449274493744947449574496744977449874499745007450174502745037450474505745067450774508745097451074511745127451374514745157451674517745187451974520745217452274523745247452574526745277452874529745307453174532745337453474535745367453774538745397454074541745427454374544745457454674547745487454974550745517455274553745547455574556745577455874559745607456174562745637456474565745667456774568745697457074571745727457374574745757457674577745787457974580745817458274583745847458574586745877458874589745907459174592745937459474595745967459774598745997460074601746027460374604746057460674607746087460974610746117461274613746147461574616746177461874619746207462174622746237462474625746267462774628746297463074631746327463374634746357463674637746387463974640746417464274643746447464574646746477464874649746507465174652746537465474655746567465774658746597466074661746627466374664746657466674667746687466974670746717467274673746747467574676746777467874679746807468174682746837468474685746867468774688746897469074691746927469374694746957469674697746987469974700747017470274703747047470574706747077470874709747107471174712747137471474715747167471774718747197472074721747227472374724747257472674727747287472974730747317473274733747347473574736747377473874739747407474174742747437474474745747467474774748747497475074751747527475374754747557475674757747587475974760747617476274763747647476574766747677476874769747707477174772747737477474775747767477774778747797478074781747827478374784747857478674787747887478974790747917479274793747947479574796747977479874799748007480174802748037480474805748067480774808748097481074811748127481374814748157481674817748187481974820748217482274823748247482574826748277482874829748307483174832748337483474835748367483774838748397484074841748427484374844748457484674847748487484974850748517485274853748547485574856748577485874859748607486174862748637486474865748667486774868748697487074871748727487374874748757487674877748787487974880748817488274883748847488574886748877488874889748907489174892748937489474895748967489774898748997490074901749027490374904749057490674907749087490974910749117491274913749147491574916749177491874919749207492174922749237492474925749267492774928749297493074931749327493374934749357493674937749387493974940749417494274943749447494574946749477494874949749507495174952749537495474955749567495774958749597496074961749627496374964749657496674967749687496974970749717497274973749747497574976749777497874979749807498174982749837498474985749867498774988749897499074991749927499374994749957499674997749987499975000750017500275003750047500575006750077500875009750107501175012750137501475015750167501775018750197502075021750227502375024750257502675027750287502975030750317503275033750347503575036750377503875039750407504175042750437504475045750467504775048750497505075051750527505375054750557505675057750587505975060750617506275063750647506575066750677506875069750707507175072750737507475075750767507775078750797508075081750827508375084750857508675087750887508975090750917509275093750947509575096750977509875099751007510175102751037510475105751067510775108751097511075111751127511375114751157511675117751187511975120751217512275123751247512575126751277512875129751307513175132751337513475135751367513775138751397514075141751427514375144751457514675147751487514975150751517515275153751547515575156751577515875159751607516175162751637516475165751667516775168751697517075171751727517375174751757517675177751787517975180751817518275183751847518575186751877518875189751907519175192751937519475195751967519775198751997520075201752027520375204752057520675207752087520975210752117521275213752147521575216752177521875219752207522175222752237522475225752267522775228752297523075231752327523375234752357523675237752387523975240752417524275243752447524575246752477524875249752507525175252752537525475255752567525775258752597526075261752627526375264752657526675267752687526975270752717527275273752747527575276752777527875279752807528175282752837528475285752867528775288752897529075291752927529375294752957529675297752987529975300753017530275303753047530575306753077530875309753107531175312753137531475315753167531775318753197532075321753227532375324753257532675327753287532975330753317533275333753347533575336753377533875339753407534175342753437534475345753467534775348753497535075351753527535375354753557535675357753587535975360753617536275363753647536575366753677536875369753707537175372753737537475375753767537775378753797538075381753827538375384753857538675387753887538975390753917539275393753947539575396753977539875399754007540175402754037540475405754067540775408754097541075411754127541375414754157541675417754187541975420754217542275423754247542575426754277542875429754307543175432754337543475435754367543775438754397544075441754427544375444754457544675447754487544975450754517545275453754547545575456754577545875459754607546175462754637546475465754667546775468754697547075471754727547375474754757547675477754787547975480754817548275483754847548575486754877548875489754907549175492754937549475495754967549775498754997550075501755027550375504755057550675507755087550975510755117551275513755147551575516755177551875519755207552175522755237552475525755267552775528755297553075531755327553375534755357553675537755387553975540755417554275543755447554575546755477554875549755507555175552755537555475555755567555775558755597556075561755627556375564755657556675567755687556975570755717557275573755747557575576755777557875579755807558175582755837558475585755867558775588755897559075591755927559375594755957559675597755987559975600756017560275603756047560575606756077560875609756107561175612756137561475615756167561775618756197562075621756227562375624756257562675627756287562975630756317563275633756347563575636756377563875639756407564175642756437564475645756467564775648756497565075651756527565375654756557565675657756587565975660756617566275663756647566575666756677566875669756707567175672756737567475675756767567775678756797568075681756827568375684756857568675687756887568975690756917569275693756947569575696756977569875699757007570175702757037570475705757067570775708757097571075711757127571375714757157571675717757187571975720757217572275723757247572575726757277572875729757307573175732757337573475735757367573775738757397574075741757427574375744757457574675747757487574975750757517575275753757547575575756757577575875759757607576175762757637576475765757667576775768757697577075771757727577375774757757577675777757787577975780757817578275783757847578575786757877578875789757907579175792757937579475795757967579775798757997580075801758027580375804758057580675807758087580975810758117581275813758147581575816758177581875819758207582175822758237582475825758267582775828758297583075831758327583375834758357583675837758387583975840758417584275843758447584575846758477584875849758507585175852758537585475855758567585775858758597586075861758627586375864758657586675867758687586975870758717587275873758747587575876758777587875879758807588175882758837588475885758867588775888758897589075891758927589375894758957589675897758987589975900759017590275903759047590575906759077590875909759107591175912759137591475915759167591775918759197592075921759227592375924759257592675927759287592975930759317593275933759347593575936759377593875939759407594175942759437594475945759467594775948759497595075951759527595375954759557595675957759587595975960759617596275963759647596575966759677596875969759707597175972759737597475975759767597775978759797598075981759827598375984759857598675987759887598975990759917599275993759947599575996759977599875999760007600176002760037600476005760067600776008760097601076011760127601376014760157601676017760187601976020760217602276023760247602576026760277602876029760307603176032760337603476035760367603776038760397604076041760427604376044760457604676047760487604976050760517605276053760547605576056760577605876059760607606176062760637606476065760667606776068760697607076071760727607376074760757607676077760787607976080760817608276083760847608576086760877608876089760907609176092760937609476095760967609776098760997610076101761027610376104761057610676107761087610976110761117611276113761147611576116761177611876119761207612176122761237612476125761267612776128761297613076131761327613376134761357613676137761387613976140761417614276143761447614576146761477614876149761507615176152761537615476155761567615776158761597616076161761627616376164761657616676167761687616976170761717617276173761747617576176761777617876179761807618176182761837618476185761867618776188761897619076191761927619376194761957619676197761987619976200762017620276203762047620576206762077620876209762107621176212762137621476215762167621776218762197622076221762227622376224762257622676227762287622976230762317623276233762347623576236762377623876239762407624176242762437624476245762467624776248762497625076251762527625376254762557625676257762587625976260762617626276263762647626576266762677626876269762707627176272762737627476275762767627776278762797628076281762827628376284762857628676287762887628976290762917629276293762947629576296762977629876299763007630176302763037630476305763067630776308763097631076311763127631376314763157631676317763187631976320763217632276323763247632576326763277632876329763307633176332763337633476335763367633776338763397634076341763427634376344763457634676347763487634976350763517635276353763547635576356763577635876359763607636176362763637636476365763667636776368763697637076371763727637376374763757637676377763787637976380763817638276383763847638576386763877638876389763907639176392763937639476395763967639776398763997640076401764027640376404764057640676407764087640976410764117641276413764147641576416764177641876419764207642176422764237642476425764267642776428764297643076431764327643376434764357643676437764387643976440764417644276443764447644576446764477644876449764507645176452764537645476455764567645776458764597646076461764627646376464764657646676467764687646976470764717647276473764747647576476764777647876479764807648176482764837648476485764867648776488764897649076491764927649376494764957649676497764987649976500765017650276503765047650576506765077650876509765107651176512765137651476515765167651776518765197652076521765227652376524765257652676527765287652976530765317653276533765347653576536765377653876539765407654176542765437654476545765467654776548765497655076551765527655376554765557655676557765587655976560765617656276563765647656576566765677656876569765707657176572765737657476575765767657776578765797658076581765827658376584765857658676587765887658976590765917659276593765947659576596765977659876599766007660176602766037660476605766067660776608766097661076611766127661376614766157661676617766187661976620766217662276623766247662576626766277662876629766307663176632766337663476635766367663776638766397664076641766427664376644766457664676647766487664976650766517665276653766547665576656766577665876659766607666176662766637666476665766667666776668766697667076671766727667376674766757667676677766787667976680766817668276683766847668576686766877668876689766907669176692766937669476695766967669776698766997670076701767027670376704767057670676707767087670976710767117671276713767147671576716767177671876719767207672176722767237672476725767267672776728767297673076731767327673376734767357673676737767387673976740767417674276743767447674576746767477674876749767507675176752767537675476755767567675776758767597676076761767627676376764767657676676767767687676976770767717677276773767747677576776767777677876779767807678176782767837678476785767867678776788767897679076791767927679376794767957679676797767987679976800768017680276803768047680576806768077680876809768107681176812768137681476815768167681776818768197682076821768227682376824768257682676827768287682976830768317683276833768347683576836768377683876839768407684176842768437684476845768467684776848768497685076851768527685376854768557685676857768587685976860768617686276863768647686576866768677686876869768707687176872768737687476875768767687776878768797688076881768827688376884768857688676887768887688976890768917689276893768947689576896768977689876899769007690176902769037690476905769067690776908769097691076911769127691376914769157691676917769187691976920769217692276923769247692576926769277692876929769307693176932769337693476935769367693776938769397694076941769427694376944769457694676947769487694976950769517695276953769547695576956769577695876959769607696176962769637696476965769667696776968769697697076971769727697376974769757697676977769787697976980769817698276983769847698576986769877698876989769907699176992769937699476995769967699776998769997700077001770027700377004770057700677007770087700977010770117701277013770147701577016770177701877019770207702177022770237702477025770267702777028770297703077031770327703377034770357703677037770387703977040770417704277043770447704577046770477704877049770507705177052770537705477055770567705777058770597706077061770627706377064770657706677067770687706977070770717707277073770747707577076770777707877079770807708177082770837708477085770867708777088770897709077091770927709377094770957709677097770987709977100771017710277103771047710577106771077710877109771107711177112771137711477115771167711777118771197712077121771227712377124771257712677127771287712977130771317713277133771347713577136771377713877139771407714177142771437714477145771467714777148771497715077151771527715377154771557715677157771587715977160771617716277163771647716577166771677716877169771707717177172771737717477175771767717777178771797718077181771827718377184771857718677187771887718977190771917719277193771947719577196771977719877199772007720177202772037720477205772067720777208772097721077211772127721377214772157721677217772187721977220772217722277223772247722577226772277722877229772307723177232772337723477235772367723777238772397724077241772427724377244772457724677247772487724977250772517725277253772547725577256772577725877259772607726177262772637726477265772667726777268772697727077271772727727377274772757727677277772787727977280772817728277283772847728577286772877728877289772907729177292772937729477295772967729777298772997730077301773027730377304773057730677307773087730977310773117731277313773147731577316773177731877319773207732177322773237732477325773267732777328773297733077331773327733377334773357733677337773387733977340773417734277343773447734577346773477734877349773507735177352773537735477355773567735777358773597736077361773627736377364773657736677367773687736977370773717737277373773747737577376773777737877379773807738177382773837738477385773867738777388773897739077391773927739377394773957739677397773987739977400774017740277403774047740577406774077740877409774107741177412774137741477415774167741777418774197742077421774227742377424774257742677427774287742977430774317743277433774347743577436774377743877439774407744177442774437744477445774467744777448774497745077451774527745377454774557745677457774587745977460774617746277463774647746577466774677746877469774707747177472774737747477475774767747777478774797748077481774827748377484774857748677487774887748977490774917749277493774947749577496774977749877499775007750177502775037750477505775067750777508775097751077511775127751377514775157751677517775187751977520775217752277523775247752577526775277752877529775307753177532775337753477535775367753777538775397754077541775427754377544775457754677547775487754977550775517755277553775547755577556775577755877559775607756177562775637756477565775667756777568775697757077571775727757377574775757757677577775787757977580775817758277583775847758577586775877758877589775907759177592775937759477595775967759777598775997760077601776027760377604776057760677607776087760977610776117761277613776147761577616776177761877619776207762177622776237762477625776267762777628776297763077631776327763377634776357763677637776387763977640776417764277643776447764577646776477764877649776507765177652776537765477655776567765777658776597766077661776627766377664776657766677667776687766977670776717767277673776747767577676776777767877679776807768177682776837768477685776867768777688776897769077691776927769377694776957769677697776987769977700777017770277703777047770577706777077770877709777107771177712777137771477715777167771777718777197772077721777227772377724777257772677727777287772977730777317773277733777347773577736777377773877739777407774177742777437774477745777467774777748777497775077751777527775377754777557775677757777587775977760777617776277763777647776577766777677776877769777707777177772777737777477775777767777777778777797778077781777827778377784777857778677787777887778977790777917779277793777947779577796777977779877799778007780177802778037780477805778067780777808778097781077811778127781377814778157781677817778187781977820778217782277823778247782577826778277782877829778307783177832778337783477835778367783777838778397784077841778427784377844778457784677847778487784977850778517785277853778547785577856778577785877859778607786177862778637786477865778667786777868778697787077871778727787377874778757787677877778787787977880778817788277883778847788577886778877788877889778907789177892778937789477895778967789777898778997790077901779027790377904779057790677907779087790977910779117791277913779147791577916779177791877919779207792177922779237792477925779267792777928779297793077931779327793377934779357793677937779387793977940779417794277943779447794577946779477794877949779507795177952779537795477955779567795777958779597796077961779627796377964779657796677967779687796977970779717797277973779747797577976779777797877979779807798177982779837798477985779867798777988779897799077991779927799377994779957799677997779987799978000780017800278003780047800578006780077800878009780107801178012780137801478015780167801778018780197802078021780227802378024780257802678027780287802978030780317803278033780347803578036780377803878039780407804178042780437804478045780467804778048780497805078051780527805378054780557805678057780587805978060780617806278063780647806578066780677806878069780707807178072780737807478075780767807778078780797808078081780827808378084780857808678087780887808978090780917809278093780947809578096780977809878099781007810178102781037810478105781067810778108781097811078111781127811378114781157811678117781187811978120781217812278123781247812578126781277812878129781307813178132781337813478135781367813778138781397814078141781427814378144781457814678147781487814978150781517815278153781547815578156781577815878159781607816178162781637816478165781667816778168781697817078171781727817378174781757817678177781787817978180781817818278183781847818578186781877818878189781907819178192781937819478195781967819778198781997820078201782027820378204782057820678207782087820978210782117821278213782147821578216782177821878219782207822178222782237822478225782267822778228782297823078231782327823378234782357823678237782387823978240782417824278243782447824578246782477824878249782507825178252782537825478255782567825778258782597826078261782627826378264782657826678267782687826978270782717827278273782747827578276782777827878279782807828178282782837828478285782867828778288782897829078291782927829378294782957829678297782987829978300783017830278303783047830578306783077830878309783107831178312783137831478315783167831778318783197832078321783227832378324783257832678327783287832978330783317833278333783347833578336783377833878339783407834178342783437834478345783467834778348783497835078351783527835378354783557835678357783587835978360783617836278363783647836578366783677836878369783707837178372783737837478375783767837778378783797838078381783827838378384783857838678387783887838978390783917839278393783947839578396783977839878399784007840178402784037840478405784067840778408784097841078411784127841378414784157841678417784187841978420784217842278423784247842578426784277842878429784307843178432784337843478435784367843778438784397844078441784427844378444784457844678447784487844978450784517845278453784547845578456784577845878459784607846178462784637846478465784667846778468784697847078471784727847378474784757847678477784787847978480784817848278483784847848578486784877848878489784907849178492784937849478495784967849778498784997850078501785027850378504785057850678507785087850978510785117851278513785147851578516785177851878519785207852178522785237852478525785267852778528785297853078531785327853378534785357853678537785387853978540785417854278543785447854578546785477854878549785507855178552785537855478555785567855778558785597856078561785627856378564785657856678567785687856978570785717857278573785747857578576785777857878579785807858178582785837858478585785867858778588785897859078591785927859378594785957859678597785987859978600786017860278603786047860578606786077860878609786107861178612786137861478615786167861778618786197862078621786227862378624786257862678627786287862978630786317863278633786347863578636786377863878639786407864178642786437864478645786467864778648786497865078651786527865378654786557865678657786587865978660786617866278663786647866578666786677866878669786707867178672786737867478675786767867778678786797868078681786827868378684786857868678687786887868978690786917869278693786947869578696786977869878699787007870178702787037870478705787067870778708787097871078711787127871378714787157871678717787187871978720787217872278723787247872578726787277872878729787307873178732787337873478735787367873778738787397874078741787427874378744787457874678747787487874978750787517875278753787547875578756787577875878759787607876178762787637876478765787667876778768787697877078771787727877378774787757877678777787787877978780787817878278783787847878578786787877878878789787907879178792787937879478795787967879778798787997880078801788027880378804788057880678807788087880978810788117881278813788147881578816788177881878819788207882178822788237882478825788267882778828788297883078831788327883378834788357883678837788387883978840788417884278843788447884578846788477884878849788507885178852788537885478855788567885778858788597886078861788627886378864788657886678867788687886978870788717887278873788747887578876788777887878879788807888178882788837888478885788867888778888788897889078891788927889378894788957889678897788987889978900789017890278903789047890578906789077890878909789107891178912789137891478915789167891778918789197892078921789227892378924789257892678927789287892978930789317893278933789347893578936789377893878939789407894178942789437894478945789467894778948789497895078951789527895378954789557895678957789587895978960789617896278963789647896578966789677896878969789707897178972789737897478975789767897778978789797898078981789827898378984789857898678987789887898978990789917899278993789947899578996789977899878999790007900179002790037900479005790067900779008790097901079011790127901379014790157901679017790187901979020790217902279023790247902579026790277902879029790307903179032790337903479035790367903779038790397904079041790427904379044790457904679047790487904979050790517905279053790547905579056790577905879059790607906179062790637906479065790667906779068790697907079071790727907379074790757907679077790787907979080790817908279083790847908579086790877908879089790907909179092790937909479095790967909779098790997910079101791027910379104791057910679107791087910979110791117911279113791147911579116791177911879119791207912179122791237912479125791267912779128791297913079131791327913379134791357913679137791387913979140791417914279143791447914579146791477914879149791507915179152791537915479155791567915779158791597916079161791627916379164791657916679167791687916979170791717917279173791747917579176791777917879179791807918179182791837918479185791867918779188791897919079191791927919379194791957919679197791987919979200792017920279203792047920579206792077920879209792107921179212792137921479215792167921779218792197922079221792227922379224792257922679227792287922979230792317923279233792347923579236792377923879239792407924179242792437924479245792467924779248792497925079251792527925379254792557925679257792587925979260792617926279263792647926579266792677926879269792707927179272792737927479275792767927779278792797928079281792827928379284792857928679287792887928979290792917929279293792947929579296792977929879299793007930179302793037930479305793067930779308793097931079311793127931379314793157931679317793187931979320793217932279323793247932579326793277932879329793307933179332793337933479335793367933779338793397934079341793427934379344793457934679347793487934979350793517935279353793547935579356793577935879359793607936179362793637936479365793667936779368793697937079371793727937379374793757937679377793787937979380793817938279383793847938579386793877938879389793907939179392793937939479395793967939779398793997940079401794027940379404794057940679407794087940979410794117941279413794147941579416794177941879419794207942179422794237942479425794267942779428794297943079431794327943379434794357943679437794387943979440794417944279443794447944579446794477944879449794507945179452794537945479455794567945779458794597946079461794627946379464794657946679467794687946979470794717947279473794747947579476794777947879479794807948179482794837948479485794867948779488794897949079491794927949379494794957949679497794987949979500795017950279503795047950579506795077950879509795107951179512795137951479515795167951779518795197952079521795227952379524795257952679527795287952979530795317953279533795347953579536795377953879539795407954179542795437954479545795467954779548795497955079551795527955379554795557955679557795587955979560795617956279563795647956579566795677956879569795707957179572795737957479575795767957779578795797958079581795827958379584795857958679587795887958979590795917959279593795947959579596795977959879599796007960179602796037960479605796067960779608796097961079611796127961379614796157961679617796187961979620796217962279623796247962579626796277962879629796307963179632796337963479635796367963779638796397964079641796427964379644796457964679647796487964979650796517965279653796547965579656796577965879659796607966179662796637966479665796667966779668796697967079671796727967379674796757967679677796787967979680796817968279683796847968579686796877968879689796907969179692796937969479695796967969779698796997970079701797027970379704797057970679707797087970979710797117971279713797147971579716797177971879719797207972179722797237972479725797267972779728797297973079731797327973379734797357973679737797387973979740797417974279743797447974579746797477974879749797507975179752797537975479755797567975779758797597976079761797627976379764797657976679767797687976979770797717977279773797747977579776797777977879779797807978179782797837978479785797867978779788797897979079791797927979379794797957979679797797987979979800798017980279803798047980579806798077980879809798107981179812798137981479815798167981779818798197982079821798227982379824798257982679827798287982979830798317983279833798347983579836798377983879839798407984179842798437984479845798467984779848798497985079851798527985379854798557985679857798587985979860798617986279863798647986579866798677986879869798707987179872798737987479875798767987779878798797988079881798827988379884798857988679887798887988979890798917989279893798947989579896798977989879899799007990179902799037990479905799067990779908799097991079911799127991379914799157991679917799187991979920799217992279923799247992579926799277992879929799307993179932799337993479935799367993779938799397994079941799427994379944799457994679947799487994979950799517995279953799547995579956799577995879959799607996179962799637996479965799667996779968799697997079971799727997379974799757997679977799787997979980799817998279983799847998579986799877998879989799907999179992799937999479995799967999779998799998000080001800028000380004800058000680007800088000980010800118001280013800148001580016800178001880019800208002180022800238002480025800268002780028800298003080031800328003380034800358003680037800388003980040800418004280043800448004580046800478004880049800508005180052800538005480055800568005780058800598006080061800628006380064800658006680067800688006980070800718007280073800748007580076800778007880079800808008180082800838008480085800868008780088800898009080091800928009380094800958009680097800988009980100801018010280103801048010580106801078010880109801108011180112801138011480115801168011780118801198012080121801228012380124801258012680127801288012980130801318013280133801348013580136801378013880139801408014180142801438014480145801468014780148801498015080151801528015380154801558015680157801588015980160801618016280163801648016580166801678016880169801708017180172801738017480175801768017780178801798018080181801828018380184801858018680187801888018980190801918019280193801948019580196801978019880199802008020180202802038020480205802068020780208802098021080211802128021380214802158021680217802188021980220802218022280223802248022580226802278022880229802308023180232802338023480235802368023780238802398024080241802428024380244802458024680247802488024980250802518025280253802548025580256802578025880259802608026180262802638026480265802668026780268802698027080271802728027380274802758027680277802788027980280802818028280283802848028580286802878028880289802908029180292802938029480295802968029780298802998030080301803028030380304803058030680307803088030980310803118031280313803148031580316803178031880319803208032180322803238032480325803268032780328803298033080331803328033380334803358033680337803388033980340803418034280343803448034580346803478034880349803508035180352803538035480355803568035780358803598036080361803628036380364803658036680367803688036980370803718037280373803748037580376803778037880379803808038180382803838038480385803868038780388803898039080391803928039380394803958039680397803988039980400804018040280403804048040580406804078040880409804108041180412804138041480415804168041780418804198042080421804228042380424804258042680427804288042980430804318043280433804348043580436804378043880439804408044180442804438044480445804468044780448804498045080451804528045380454804558045680457804588045980460804618046280463804648046580466804678046880469804708047180472804738047480475804768047780478804798048080481804828048380484804858048680487804888048980490804918049280493804948049580496804978049880499805008050180502805038050480505805068050780508805098051080511805128051380514805158051680517805188051980520805218052280523805248052580526805278052880529805308053180532805338053480535805368053780538805398054080541805428054380544805458054680547805488054980550805518055280553805548055580556805578055880559805608056180562805638056480565805668056780568805698057080571805728057380574805758057680577805788057980580805818058280583805848058580586805878058880589805908059180592805938059480595805968059780598805998060080601806028060380604806058060680607806088060980610806118061280613806148061580616806178061880619806208062180622806238062480625806268062780628806298063080631806328063380634806358063680637806388063980640806418064280643806448064580646806478064880649806508065180652806538065480655806568065780658806598066080661806628066380664806658066680667806688066980670806718067280673806748067580676806778067880679806808068180682806838068480685806868068780688806898069080691806928069380694806958069680697806988069980700807018070280703807048070580706807078070880709807108071180712807138071480715807168071780718807198072080721807228072380724807258072680727807288072980730807318073280733807348073580736807378073880739807408074180742807438074480745807468074780748807498075080751807528075380754807558075680757807588075980760807618076280763807648076580766807678076880769807708077180772807738077480775807768077780778807798078080781807828078380784807858078680787807888078980790807918079280793807948079580796807978079880799808008080180802808038080480805808068080780808808098081080811808128081380814808158081680817808188081980820808218082280823808248082580826808278082880829808308083180832808338083480835808368083780838808398084080841808428084380844808458084680847808488084980850808518085280853808548085580856808578085880859808608086180862808638086480865808668086780868808698087080871808728087380874808758087680877808788087980880808818088280883808848088580886808878088880889808908089180892808938089480895808968089780898808998090080901809028090380904809058090680907809088090980910809118091280913809148091580916809178091880919809208092180922809238092480925809268092780928809298093080931809328093380934809358093680937809388093980940809418094280943809448094580946809478094880949809508095180952809538095480955809568095780958809598096080961809628096380964809658096680967809688096980970809718097280973809748097580976809778097880979809808098180982809838098480985809868098780988809898099080991809928099380994809958099680997809988099981000810018100281003810048100581006810078100881009810108101181012810138101481015810168101781018810198102081021810228102381024810258102681027810288102981030810318103281033810348103581036810378103881039810408104181042810438104481045810468104781048810498105081051810528105381054810558105681057810588105981060810618106281063810648106581066810678106881069810708107181072810738107481075810768107781078810798108081081810828108381084810858108681087810888108981090810918109281093810948109581096810978109881099811008110181102811038110481105811068110781108811098111081111811128111381114811158111681117811188111981120811218112281123811248112581126811278112881129811308113181132811338113481135811368113781138811398114081141811428114381144811458114681147811488114981150811518115281153811548115581156811578115881159811608116181162811638116481165811668116781168811698117081171811728117381174811758117681177811788117981180811818118281183811848118581186811878118881189811908119181192811938119481195811968119781198811998120081201812028120381204812058120681207812088120981210812118121281213812148121581216812178121881219812208122181222812238122481225812268122781228812298123081231812328123381234812358123681237812388123981240812418124281243812448124581246812478124881249812508125181252812538125481255812568125781258812598126081261812628126381264812658126681267812688126981270812718127281273812748127581276812778127881279812808128181282812838128481285812868128781288812898129081291812928129381294812958129681297812988129981300813018130281303813048130581306813078130881309813108131181312813138131481315813168131781318813198132081321813228132381324813258132681327813288132981330813318133281333813348133581336813378133881339813408134181342813438134481345813468134781348813498135081351813528135381354813558135681357813588135981360813618136281363813648136581366813678136881369813708137181372813738137481375813768137781378813798138081381813828138381384813858138681387813888138981390813918139281393813948139581396813978139881399814008140181402814038140481405814068140781408814098141081411814128141381414814158141681417814188141981420814218142281423814248142581426814278142881429814308143181432814338143481435814368143781438814398144081441814428144381444814458144681447814488144981450814518145281453814548145581456814578145881459814608146181462814638146481465814668146781468814698147081471814728147381474814758147681477814788147981480814818148281483814848148581486814878148881489814908149181492814938149481495814968149781498814998150081501815028150381504815058150681507815088150981510815118151281513815148151581516815178151881519815208152181522815238152481525815268152781528815298153081531815328153381534815358153681537815388153981540815418154281543815448154581546815478154881549815508155181552815538155481555815568155781558815598156081561815628156381564815658156681567815688156981570815718157281573815748157581576815778157881579815808158181582815838158481585815868158781588815898159081591815928159381594815958159681597815988159981600816018160281603816048160581606816078160881609816108161181612816138161481615816168161781618816198162081621816228162381624816258162681627816288162981630816318163281633816348163581636816378163881639816408164181642816438164481645816468164781648816498165081651816528165381654816558165681657816588165981660816618166281663816648166581666816678166881669816708167181672816738167481675816768167781678816798168081681816828168381684816858168681687816888168981690816918169281693816948169581696816978169881699817008170181702817038170481705817068170781708817098171081711817128171381714817158171681717817188171981720817218172281723817248172581726817278172881729817308173181732817338173481735817368173781738817398174081741817428174381744817458174681747817488174981750817518175281753817548175581756817578175881759817608176181762817638176481765817668176781768817698177081771817728177381774817758177681777817788177981780817818178281783817848178581786817878178881789817908179181792817938179481795817968179781798817998180081801818028180381804818058180681807818088180981810818118181281813818148181581816818178181881819818208182181822818238182481825818268182781828818298183081831818328183381834818358183681837818388183981840818418184281843818448184581846818478184881849818508185181852818538185481855818568185781858818598186081861818628186381864818658186681867818688186981870818718187281873818748187581876818778187881879818808188181882818838188481885818868188781888818898189081891818928189381894818958189681897818988189981900819018190281903819048190581906819078190881909819108191181912819138191481915819168191781918819198192081921819228192381924819258192681927819288192981930819318193281933819348193581936819378193881939819408194181942819438194481945819468194781948819498195081951819528195381954819558195681957819588195981960819618196281963819648196581966819678196881969819708197181972819738197481975819768197781978819798198081981819828198381984819858198681987819888198981990819918199281993819948199581996819978199881999820008200182002820038200482005820068200782008820098201082011820128201382014820158201682017820188201982020820218202282023820248202582026820278202882029820308203182032820338203482035820368203782038820398204082041820428204382044820458204682047820488204982050820518205282053820548205582056820578205882059820608206182062820638206482065820668206782068820698207082071820728207382074820758207682077820788207982080820818208282083820848208582086820878208882089820908209182092820938209482095820968209782098820998210082101821028210382104821058210682107821088210982110821118211282113821148211582116821178211882119821208212182122821238212482125821268212782128821298213082131821328213382134821358213682137821388213982140821418214282143821448214582146821478214882149821508215182152821538215482155821568215782158821598216082161821628216382164821658216682167821688216982170821718217282173821748217582176821778217882179821808218182182821838218482185821868218782188821898219082191821928219382194821958219682197821988219982200822018220282203822048220582206822078220882209822108221182212822138221482215822168221782218822198222082221822228222382224822258222682227822288222982230822318223282233822348223582236822378223882239822408224182242822438224482245822468224782248822498225082251822528225382254822558225682257822588225982260822618226282263822648226582266822678226882269822708227182272822738227482275822768227782278822798228082281822828228382284822858228682287822888228982290822918229282293822948229582296822978229882299823008230182302823038230482305823068230782308823098231082311823128231382314823158231682317823188231982320823218232282323823248232582326823278232882329823308233182332823338233482335823368233782338823398234082341823428234382344823458234682347823488234982350823518235282353823548235582356823578235882359823608236182362823638236482365823668236782368823698237082371823728237382374823758237682377823788237982380823818238282383823848238582386823878238882389823908239182392823938239482395823968239782398823998240082401824028240382404824058240682407824088240982410824118241282413824148241582416824178241882419824208242182422824238242482425824268242782428824298243082431824328243382434824358243682437824388243982440824418244282443824448244582446824478244882449824508245182452824538245482455824568245782458824598246082461824628246382464824658246682467824688246982470824718247282473824748247582476824778247882479824808248182482824838248482485824868248782488824898249082491824928249382494824958249682497824988249982500825018250282503825048250582506825078250882509825108251182512825138251482515825168251782518825198252082521825228252382524825258252682527825288252982530825318253282533825348253582536825378253882539825408254182542825438254482545825468254782548825498255082551825528255382554825558255682557825588255982560825618256282563825648256582566825678256882569825708257182572825738257482575825768257782578825798258082581825828258382584825858258682587825888258982590825918259282593825948259582596825978259882599826008260182602826038260482605826068260782608826098261082611826128261382614826158261682617826188261982620826218262282623826248262582626826278262882629826308263182632826338263482635826368263782638826398264082641826428264382644826458264682647826488264982650826518265282653826548265582656826578265882659826608266182662826638266482665826668266782668826698267082671826728267382674826758267682677826788267982680826818268282683826848268582686826878268882689826908269182692826938269482695826968269782698826998270082701827028270382704827058270682707827088270982710827118271282713827148271582716827178271882719827208272182722827238272482725827268272782728827298273082731827328273382734827358273682737827388273982740827418274282743827448274582746827478274882749827508275182752827538275482755827568275782758827598276082761827628276382764827658276682767827688276982770827718277282773827748277582776827778277882779827808278182782827838278482785827868278782788827898279082791827928279382794827958279682797827988279982800828018280282803828048280582806828078280882809828108281182812828138281482815828168281782818828198282082821828228282382824828258282682827828288282982830828318283282833828348283582836828378283882839828408284182842828438284482845828468284782848828498285082851828528285382854828558285682857828588285982860828618286282863828648286582866828678286882869828708287182872828738287482875828768287782878828798288082881828828288382884828858288682887828888288982890828918289282893828948289582896828978289882899829008290182902829038290482905829068290782908829098291082911829128291382914829158291682917829188291982920829218292282923829248292582926829278292882929829308293182932829338293482935829368293782938829398294082941829428294382944829458294682947829488294982950829518295282953829548295582956829578295882959829608296182962829638296482965829668296782968829698297082971829728297382974829758297682977829788297982980829818298282983829848298582986829878298882989829908299182992829938299482995829968299782998829998300083001830028300383004830058300683007830088300983010830118301283013830148301583016830178301883019830208302183022830238302483025830268302783028830298303083031830328303383034830358303683037830388303983040830418304283043830448304583046830478304883049830508305183052830538305483055830568305783058830598306083061830628306383064830658306683067830688306983070830718307283073830748307583076830778307883079830808308183082830838308483085830868308783088830898309083091830928309383094830958309683097830988309983100831018310283103831048310583106831078310883109831108311183112831138311483115831168311783118831198312083121831228312383124831258312683127831288312983130831318313283133831348313583136831378313883139831408314183142831438314483145831468314783148831498315083151831528315383154831558315683157831588315983160831618316283163831648316583166831678316883169831708317183172831738317483175831768317783178831798318083181831828318383184831858318683187831888318983190831918319283193831948319583196831978319883199832008320183202832038320483205832068320783208832098321083211832128321383214832158321683217832188321983220832218322283223832248322583226832278322883229832308323183232832338323483235832368323783238832398324083241832428324383244832458324683247832488324983250832518325283253832548325583256832578325883259832608326183262832638326483265832668326783268832698327083271832728327383274832758327683277832788327983280832818328283283832848328583286832878328883289832908329183292832938329483295832968329783298832998330083301833028330383304833058330683307833088330983310833118331283313833148331583316833178331883319833208332183322833238332483325833268332783328833298333083331833328333383334833358333683337833388333983340833418334283343833448334583346833478334883349833508335183352833538335483355833568335783358833598336083361833628336383364833658336683367833688336983370833718337283373833748337583376833778337883379833808338183382833838338483385833868338783388833898339083391833928339383394833958339683397833988339983400834018340283403834048340583406834078340883409834108341183412834138341483415834168341783418834198342083421834228342383424834258342683427834288342983430834318343283433834348343583436834378343883439834408344183442834438344483445834468344783448834498345083451834528345383454834558345683457834588345983460834618346283463834648346583466834678346883469834708347183472834738347483475834768347783478834798348083481834828348383484834858348683487834888348983490834918349283493834948349583496834978349883499835008350183502835038350483505835068350783508835098351083511835128351383514835158351683517835188351983520835218352283523835248352583526835278352883529835308353183532835338353483535835368353783538835398354083541835428354383544835458354683547835488354983550835518355283553835548355583556835578355883559835608356183562835638356483565835668356783568835698357083571835728357383574835758357683577835788357983580835818358283583835848358583586835878358883589835908359183592835938359483595835968359783598835998360083601836028360383604836058360683607836088360983610836118361283613836148361583616836178361883619836208362183622836238362483625836268362783628836298363083631836328363383634836358363683637836388363983640836418364283643836448364583646836478364883649836508365183652836538365483655836568365783658836598366083661836628366383664836658366683667836688366983670836718367283673836748367583676836778367883679836808368183682836838368483685836868368783688836898369083691836928369383694836958369683697836988369983700837018370283703837048370583706837078370883709837108371183712837138371483715837168371783718837198372083721837228372383724837258372683727837288372983730837318373283733837348373583736837378373883739837408374183742837438374483745837468374783748837498375083751837528375383754837558375683757837588375983760837618376283763837648376583766837678376883769837708377183772837738377483775837768377783778837798378083781837828378383784837858378683787837888378983790837918379283793837948379583796837978379883799838008380183802838038380483805838068380783808838098381083811838128381383814838158381683817838188381983820838218382283823838248382583826838278382883829838308383183832838338383483835838368383783838838398384083841838428384383844838458384683847838488384983850838518385283853838548385583856838578385883859838608386183862838638386483865838668386783868838698387083871838728387383874838758387683877838788387983880838818388283883838848388583886838878388883889838908389183892838938389483895838968389783898838998390083901839028390383904839058390683907839088390983910839118391283913839148391583916839178391883919839208392183922839238392483925839268392783928839298393083931839328393383934839358393683937839388393983940839418394283943839448394583946839478394883949839508395183952839538395483955839568395783958839598396083961839628396383964839658396683967839688396983970839718397283973839748397583976839778397883979839808398183982839838398483985839868398783988839898399083991839928399383994839958399683997839988399984000840018400284003840048400584006840078400884009840108401184012840138401484015840168401784018840198402084021840228402384024840258402684027840288402984030840318403284033840348403584036840378403884039840408404184042840438404484045840468404784048840498405084051840528405384054840558405684057840588405984060840618406284063840648406584066840678406884069840708407184072840738407484075840768407784078840798408084081840828408384084840858408684087840888408984090840918409284093840948409584096840978409884099841008410184102841038410484105841068410784108841098411084111841128411384114841158411684117841188411984120841218412284123841248412584126841278412884129841308413184132841338413484135841368413784138841398414084141841428414384144841458414684147841488414984150841518415284153841548415584156841578415884159841608416184162841638416484165841668416784168841698417084171841728417384174841758417684177841788417984180841818418284183841848418584186841878418884189841908419184192841938419484195841968419784198841998420084201842028420384204842058420684207842088420984210842118421284213842148421584216842178421884219842208422184222842238422484225842268422784228842298423084231842328423384234842358423684237842388423984240842418424284243842448424584246842478424884249842508425184252842538425484255842568425784258842598426084261842628426384264842658426684267842688426984270842718427284273842748427584276842778427884279842808428184282842838428484285842868428784288842898429084291842928429384294842958429684297842988429984300843018430284303843048430584306843078430884309843108431184312843138431484315843168431784318843198432084321843228432384324843258432684327843288432984330843318433284333843348433584336843378433884339843408434184342843438434484345843468434784348843498435084351843528435384354843558435684357843588435984360843618436284363843648436584366843678436884369843708437184372843738437484375843768437784378843798438084381843828438384384843858438684387843888438984390843918439284393843948439584396843978439884399844008440184402844038440484405844068440784408844098441084411844128441384414844158441684417844188441984420844218442284423844248442584426844278442884429844308443184432844338443484435844368443784438844398444084441844428444384444844458444684447844488444984450844518445284453844548445584456844578445884459844608446184462844638446484465844668446784468844698447084471844728447384474844758447684477844788447984480844818448284483844848448584486844878448884489844908449184492844938449484495844968449784498844998450084501845028450384504845058450684507845088450984510845118451284513845148451584516845178451884519845208452184522845238452484525845268452784528845298453084531845328453384534845358453684537845388453984540845418454284543845448454584546845478454884549845508455184552845538455484555845568455784558845598456084561845628456384564845658456684567845688456984570845718457284573845748457584576845778457884579845808458184582845838458484585845868458784588845898459084591845928459384594845958459684597845988459984600846018460284603846048460584606846078460884609846108461184612846138461484615846168461784618846198462084621846228462384624846258462684627846288462984630846318463284633846348463584636846378463884639846408464184642846438464484645846468464784648846498465084651846528465384654846558465684657846588465984660846618466284663846648466584666846678466884669846708467184672846738467484675846768467784678846798468084681846828468384684846858468684687846888468984690846918469284693846948469584696846978469884699847008470184702847038470484705847068470784708847098471084711847128471384714847158471684717847188471984720847218472284723847248472584726847278472884729847308473184732847338473484735847368473784738847398474084741847428474384744847458474684747847488474984750847518475284753847548475584756847578475884759847608476184762847638476484765847668476784768847698477084771847728477384774847758477684777847788477984780847818478284783847848478584786847878478884789847908479184792847938479484795847968479784798847998480084801848028480384804848058480684807848088480984810848118481284813848148481584816848178481884819848208482184822848238482484825848268482784828848298483084831848328483384834848358483684837848388483984840848418484284843848448484584846848478484884849848508485184852848538485484855848568485784858848598486084861848628486384864848658486684867848688486984870848718487284873848748487584876848778487884879848808488184882848838488484885848868488784888848898489084891848928489384894848958489684897848988489984900849018490284903849048490584906849078490884909849108491184912849138491484915849168491784918849198492084921849228492384924849258492684927849288492984930849318493284933849348493584936849378493884939849408494184942849438494484945849468494784948849498495084951849528495384954849558495684957849588495984960849618496284963849648496584966849678496884969849708497184972849738497484975849768497784978849798498084981849828498384984849858498684987849888498984990849918499284993849948499584996849978499884999850008500185002850038500485005850068500785008850098501085011850128501385014850158501685017850188501985020850218502285023850248502585026850278502885029850308503185032850338503485035850368503785038850398504085041850428504385044850458504685047850488504985050850518505285053850548505585056850578505885059850608506185062850638506485065850668506785068850698507085071850728507385074850758507685077850788507985080850818508285083850848508585086850878508885089850908509185092850938509485095850968509785098850998510085101851028510385104851058510685107851088510985110851118511285113851148511585116851178511885119851208512185122851238512485125851268512785128851298513085131851328513385134851358513685137851388513985140851418514285143851448514585146851478514885149851508515185152851538515485155851568515785158851598516085161851628516385164851658516685167851688516985170851718517285173851748517585176851778517885179851808518185182851838518485185851868518785188851898519085191851928519385194851958519685197851988519985200852018520285203852048520585206852078520885209852108521185212852138521485215852168521785218852198522085221852228522385224852258522685227852288522985230852318523285233852348523585236852378523885239852408524185242852438524485245852468524785248852498525085251852528525385254852558525685257852588525985260852618526285263852648526585266852678526885269852708527185272852738527485275852768527785278852798528085281852828528385284852858528685287852888528985290852918529285293852948529585296852978529885299853008530185302853038530485305853068530785308853098531085311853128531385314853158531685317853188531985320853218532285323853248532585326853278532885329853308533185332853338533485335853368533785338853398534085341853428534385344853458534685347853488534985350853518535285353853548535585356853578535885359853608536185362853638536485365853668536785368853698537085371853728537385374853758537685377853788537985380853818538285383853848538585386853878538885389853908539185392853938539485395853968539785398853998540085401854028540385404854058540685407854088540985410854118541285413854148541585416854178541885419854208542185422854238542485425854268542785428854298543085431854328543385434854358543685437854388543985440854418544285443854448544585446854478544885449854508545185452854538545485455854568545785458854598546085461854628546385464854658546685467854688546985470854718547285473854748547585476854778547885479854808548185482854838548485485854868548785488854898549085491854928549385494854958549685497854988549985500855018550285503855048550585506855078550885509855108551185512855138551485515855168551785518855198552085521855228552385524855258552685527855288552985530855318553285533855348553585536855378553885539855408554185542855438554485545855468554785548855498555085551855528555385554855558555685557855588555985560855618556285563855648556585566855678556885569855708557185572855738557485575855768557785578855798558085581855828558385584855858558685587855888558985590855918559285593855948559585596855978559885599856008560185602856038560485605856068560785608856098561085611856128561385614856158561685617856188561985620856218562285623856248562585626856278562885629856308563185632856338563485635856368563785638856398564085641856428564385644856458564685647856488564985650856518565285653856548565585656856578565885659856608566185662856638566485665856668566785668856698567085671856728567385674856758567685677856788567985680856818568285683856848568585686856878568885689856908569185692856938569485695856968569785698856998570085701857028570385704857058570685707857088570985710857118571285713857148571585716857178571885719857208572185722857238572485725857268572785728857298573085731857328573385734857358573685737857388573985740857418574285743857448574585746857478574885749857508575185752857538575485755857568575785758857598576085761857628576385764857658576685767857688576985770857718577285773857748577585776857778577885779857808578185782857838578485785857868578785788857898579085791857928579385794857958579685797857988579985800858018580285803858048580585806858078580885809858108581185812858138581485815858168581785818858198582085821858228582385824858258582685827858288582985830858318583285833858348583585836858378583885839858408584185842858438584485845858468584785848858498585085851858528585385854858558585685857858588585985860858618586285863858648586585866858678586885869858708587185872858738587485875858768587785878858798588085881858828588385884858858588685887858888588985890858918589285893858948589585896858978589885899859008590185902859038590485905859068590785908859098591085911859128591385914859158591685917859188591985920859218592285923859248592585926859278592885929859308593185932859338593485935859368593785938859398594085941859428594385944859458594685947859488594985950859518595285953859548595585956859578595885959859608596185962859638596485965859668596785968859698597085971859728597385974859758597685977859788597985980859818598285983859848598585986859878598885989859908599185992859938599485995859968599785998859998600086001860028600386004860058600686007860088600986010860118601286013860148601586016860178601886019860208602186022860238602486025860268602786028860298603086031860328603386034860358603686037860388603986040860418604286043860448604586046860478604886049860508605186052860538605486055860568605786058860598606086061860628606386064860658606686067860688606986070860718607286073860748607586076860778607886079860808608186082860838608486085860868608786088860898609086091860928609386094860958609686097860988609986100861018610286103861048610586106861078610886109861108611186112861138611486115861168611786118861198612086121861228612386124861258612686127861288612986130861318613286133861348613586136861378613886139861408614186142861438614486145861468614786148861498615086151861528615386154861558615686157861588615986160861618616286163861648616586166861678616886169861708617186172861738617486175861768617786178861798618086181861828618386184861858618686187861888618986190861918619286193861948619586196861978619886199862008620186202862038620486205862068620786208862098621086211862128621386214862158621686217862188621986220862218622286223862248622586226862278622886229862308623186232862338623486235862368623786238862398624086241862428624386244862458624686247862488624986250862518625286253862548625586256862578625886259862608626186262862638626486265862668626786268862698627086271862728627386274862758627686277862788627986280862818628286283862848628586286862878628886289862908629186292862938629486295862968629786298862998630086301863028630386304863058630686307863088630986310863118631286313863148631586316863178631886319863208632186322863238632486325863268632786328863298633086331863328633386334863358633686337863388633986340863418634286343863448634586346863478634886349863508635186352863538635486355863568635786358863598636086361863628636386364863658636686367863688636986370863718637286373863748637586376863778637886379863808638186382863838638486385863868638786388863898639086391863928639386394863958639686397863988639986400864018640286403864048640586406864078640886409864108641186412864138641486415864168641786418864198642086421864228642386424864258642686427864288642986430864318643286433864348643586436864378643886439864408644186442864438644486445864468644786448864498645086451864528645386454864558645686457864588645986460864618646286463864648646586466864678646886469864708647186472864738647486475864768647786478864798648086481864828648386484864858648686487864888648986490864918649286493864948649586496864978649886499865008650186502865038650486505865068650786508865098651086511865128651386514865158651686517865188651986520865218652286523865248652586526865278652886529865308653186532865338653486535865368653786538865398654086541865428654386544865458654686547865488654986550865518655286553865548655586556865578655886559865608656186562865638656486565865668656786568865698657086571865728657386574865758657686577865788657986580865818658286583865848658586586865878658886589865908659186592865938659486595865968659786598865998660086601866028660386604866058660686607866088660986610866118661286613866148661586616866178661886619866208662186622866238662486625866268662786628866298663086631866328663386634866358663686637866388663986640866418664286643866448664586646866478664886649866508665186652866538665486655866568665786658866598666086661866628666386664866658666686667866688666986670866718667286673866748667586676866778667886679866808668186682866838668486685866868668786688866898669086691866928669386694866958669686697866988669986700867018670286703867048670586706867078670886709867108671186712867138671486715867168671786718867198672086721867228672386724867258672686727867288672986730867318673286733867348673586736867378673886739867408674186742867438674486745867468674786748867498675086751867528675386754867558675686757867588675986760867618676286763867648676586766867678676886769867708677186772867738677486775867768677786778867798678086781867828678386784867858678686787867888678986790867918679286793867948679586796867978679886799868008680186802868038680486805868068680786808868098681086811868128681386814868158681686817868188681986820868218682286823868248682586826868278682886829868308683186832868338683486835868368683786838868398684086841868428684386844868458684686847868488684986850868518685286853868548685586856868578685886859868608686186862868638686486865868668686786868868698687086871868728687386874868758687686877868788687986880868818688286883868848688586886868878688886889868908689186892868938689486895868968689786898868998690086901869028690386904869058690686907869088690986910869118691286913869148691586916869178691886919869208692186922869238692486925869268692786928869298693086931869328693386934869358693686937869388693986940869418694286943869448694586946869478694886949869508695186952869538695486955869568695786958869598696086961869628696386964869658696686967869688696986970869718697286973869748697586976869778697886979869808698186982869838698486985869868698786988869898699086991869928699386994869958699686997869988699987000870018700287003870048700587006870078700887009870108701187012870138701487015870168701787018870198702087021870228702387024870258702687027870288702987030870318703287033870348703587036870378703887039870408704187042870438704487045870468704787048870498705087051870528705387054870558705687057870588705987060870618706287063870648706587066870678706887069870708707187072870738707487075870768707787078870798708087081870828708387084870858708687087870888708987090870918709287093870948709587096870978709887099871008710187102871038710487105871068710787108871098711087111871128711387114871158711687117871188711987120871218712287123871248712587126871278712887129871308713187132871338713487135871368713787138871398714087141871428714387144871458714687147871488714987150871518715287153871548715587156871578715887159871608716187162871638716487165871668716787168871698717087171871728717387174871758717687177871788717987180871818718287183871848718587186871878718887189871908719187192871938719487195871968719787198871998720087201872028720387204872058720687207872088720987210872118721287213872148721587216872178721887219872208722187222872238722487225872268722787228872298723087231872328723387234872358723687237872388723987240872418724287243872448724587246872478724887249872508725187252872538725487255872568725787258872598726087261872628726387264872658726687267872688726987270872718727287273872748727587276872778727887279872808728187282872838728487285872868728787288872898729087291872928729387294872958729687297872988729987300873018730287303873048730587306873078730887309873108731187312873138731487315873168731787318873198732087321873228732387324873258732687327873288732987330873318733287333873348733587336873378733887339873408734187342873438734487345873468734787348873498735087351873528735387354873558735687357873588735987360873618736287363873648736587366873678736887369873708737187372873738737487375873768737787378873798738087381873828738387384873858738687387873888738987390873918739287393873948739587396873978739887399874008740187402874038740487405874068740787408874098741087411874128741387414874158741687417874188741987420874218742287423874248742587426874278742887429874308743187432874338743487435874368743787438874398744087441874428744387444874458744687447874488744987450874518745287453874548745587456874578745887459874608746187462874638746487465874668746787468874698747087471874728747387474874758747687477874788747987480874818748287483874848748587486874878748887489874908749187492874938749487495874968749787498874998750087501875028750387504875058750687507875088750987510875118751287513875148751587516875178751887519875208752187522875238752487525875268752787528875298753087531875328753387534875358753687537875388753987540875418754287543875448754587546875478754887549875508755187552875538755487555875568755787558875598756087561875628756387564875658756687567875688756987570875718757287573875748757587576875778757887579875808758187582875838758487585875868758787588875898759087591875928759387594875958759687597875988759987600876018760287603876048760587606876078760887609876108761187612876138761487615876168761787618876198762087621876228762387624876258762687627876288762987630876318763287633876348763587636876378763887639876408764187642876438764487645876468764787648876498765087651876528765387654876558765687657876588765987660876618766287663876648766587666876678766887669876708767187672876738767487675876768767787678876798768087681876828768387684876858768687687876888768987690876918769287693876948769587696876978769887699877008770187702877038770487705877068770787708877098771087711877128771387714877158771687717877188771987720877218772287723877248772587726877278772887729877308773187732877338773487735877368773787738877398774087741877428774387744877458774687747877488774987750877518775287753877548775587756877578775887759877608776187762877638776487765877668776787768877698777087771877728777387774877758777687777877788777987780877818778287783877848778587786877878778887789877908779187792877938779487795877968779787798877998780087801878028780387804878058780687807878088780987810878118781287813878148781587816878178781887819878208782187822878238782487825878268782787828878298783087831878328783387834878358783687837878388783987840878418784287843878448784587846878478784887849878508785187852878538785487855878568785787858878598786087861878628786387864878658786687867878688786987870878718787287873878748787587876878778787887879878808788187882878838788487885878868788787888878898789087891878928789387894878958789687897878988789987900879018790287903879048790587906879078790887909879108791187912879138791487915879168791787918879198792087921879228792387924879258792687927879288792987930879318793287933879348793587936879378793887939879408794187942879438794487945879468794787948879498795087951879528795387954879558795687957879588795987960879618796287963879648796587966879678796887969879708797187972879738797487975879768797787978879798798087981879828798387984879858798687987879888798987990879918799287993879948799587996879978799887999880008800188002880038800488005880068800788008880098801088011880128801388014880158801688017880188801988020880218802288023880248802588026880278802888029880308803188032880338803488035880368803788038880398804088041880428804388044880458804688047880488804988050880518805288053880548805588056880578805888059880608806188062880638806488065880668806788068880698807088071880728807388074880758807688077880788807988080880818808288083880848808588086880878808888089880908809188092880938809488095880968809788098880998810088101881028810388104881058810688107881088810988110881118811288113881148811588116881178811888119881208812188122881238812488125881268812788128881298813088131881328813388134881358813688137881388813988140881418814288143881448814588146881478814888149881508815188152881538815488155881568815788158881598816088161881628816388164881658816688167881688816988170881718817288173881748817588176881778817888179881808818188182881838818488185881868818788188881898819088191881928819388194881958819688197881988819988200882018820288203882048820588206882078820888209882108821188212882138821488215882168821788218882198822088221882228822388224882258822688227882288822988230882318823288233882348823588236882378823888239882408824188242882438824488245882468824788248882498825088251882528825388254882558825688257882588825988260882618826288263882648826588266882678826888269882708827188272882738827488275882768827788278882798828088281882828828388284882858828688287882888828988290882918829288293882948829588296882978829888299883008830188302883038830488305883068830788308883098831088311883128831388314883158831688317883188831988320883218832288323883248832588326883278832888329883308833188332883338833488335883368833788338883398834088341883428834388344883458834688347883488834988350883518835288353883548835588356883578835888359883608836188362883638836488365883668836788368883698837088371883728837388374883758837688377883788837988380883818838288383883848838588386883878838888389883908839188392883938839488395883968839788398883998840088401884028840388404884058840688407884088840988410884118841288413884148841588416884178841888419884208842188422884238842488425884268842788428884298843088431884328843388434884358843688437884388843988440884418844288443884448844588446884478844888449884508845188452884538845488455884568845788458884598846088461884628846388464884658846688467884688846988470884718847288473884748847588476884778847888479884808848188482884838848488485884868848788488884898849088491884928849388494884958849688497884988849988500885018850288503885048850588506885078850888509885108851188512885138851488515885168851788518885198852088521885228852388524885258852688527885288852988530885318853288533885348853588536885378853888539885408854188542885438854488545885468854788548885498855088551885528855388554885558855688557885588855988560885618856288563885648856588566885678856888569885708857188572885738857488575885768857788578885798858088581885828858388584885858858688587885888858988590885918859288593885948859588596885978859888599886008860188602886038860488605886068860788608886098861088611886128861388614886158861688617886188861988620886218862288623886248862588626886278862888629886308863188632886338863488635886368863788638886398864088641886428864388644886458864688647886488864988650886518865288653886548865588656886578865888659886608866188662886638866488665886668866788668886698867088671886728867388674886758867688677886788867988680886818868288683886848868588686886878868888689886908869188692886938869488695886968869788698886998870088701887028870388704887058870688707887088870988710887118871288713887148871588716887178871888719887208872188722887238872488725887268872788728887298873088731887328873388734887358873688737887388873988740887418874288743887448874588746887478874888749887508875188752887538875488755887568875788758887598876088761887628876388764887658876688767887688876988770887718877288773887748877588776887778877888779887808878188782887838878488785887868878788788887898879088791887928879388794887958879688797887988879988800888018880288803888048880588806888078880888809888108881188812888138881488815888168881788818888198882088821888228882388824888258882688827888288882988830888318883288833888348883588836888378883888839888408884188842888438884488845888468884788848888498885088851888528885388854888558885688857888588885988860888618886288863888648886588866888678886888869888708887188872888738887488875888768887788878888798888088881888828888388884888858888688887888888888988890888918889288893888948889588896888978889888899889008890188902889038890488905889068890788908889098891088911889128891388914889158891688917889188891988920889218892288923889248892588926889278892888929889308893188932889338893488935889368893788938889398894088941889428894388944889458894688947889488894988950889518895288953889548895588956889578895888959889608896188962889638896488965889668896788968889698897088971889728897388974889758897688977889788897988980889818898288983889848898588986889878898888989889908899188992889938899488995889968899788998889998900089001890028900389004890058900689007890088900989010890118901289013890148901589016890178901889019890208902189022890238902489025890268902789028890298903089031890328903389034890358903689037890388903989040890418904289043890448904589046890478904889049890508905189052890538905489055890568905789058890598906089061890628906389064890658906689067890688906989070890718907289073890748907589076890778907889079890808908189082890838908489085890868908789088890898909089091890928909389094890958909689097890988909989100891018910289103891048910589106891078910889109891108911189112891138911489115891168911789118891198912089121891228912389124891258912689127891288912989130891318913289133891348913589136891378913889139891408914189142891438914489145891468914789148891498915089151891528915389154891558915689157891588915989160891618916289163891648916589166891678916889169891708917189172891738917489175891768917789178891798918089181891828918389184891858918689187891888918989190891918919289193891948919589196891978919889199892008920189202892038920489205892068920789208892098921089211892128921389214892158921689217892188921989220892218922289223892248922589226892278922889229892308923189232892338923489235892368923789238892398924089241892428924389244892458924689247892488924989250892518925289253892548925589256892578925889259892608926189262892638926489265892668926789268892698927089271892728927389274892758927689277892788927989280892818928289283892848928589286892878928889289892908929189292892938929489295892968929789298892998930089301893028930389304893058930689307893088930989310893118931289313893148931589316893178931889319893208932189322893238932489325893268932789328893298933089331893328933389334893358933689337893388933989340893418934289343893448934589346893478934889349893508935189352893538935489355893568935789358893598936089361893628936389364893658936689367893688936989370893718937289373893748937589376893778937889379893808938189382893838938489385893868938789388893898939089391893928939389394893958939689397893988939989400894018940289403894048940589406894078940889409894108941189412894138941489415894168941789418894198942089421894228942389424894258942689427894288942989430894318943289433894348943589436894378943889439894408944189442894438944489445894468944789448894498945089451894528945389454894558945689457894588945989460894618946289463894648946589466894678946889469894708947189472894738947489475894768947789478894798948089481894828948389484894858948689487894888948989490894918949289493894948949589496894978949889499895008950189502895038950489505895068950789508895098951089511895128951389514895158951689517895188951989520895218952289523895248952589526895278952889529895308953189532895338953489535895368953789538895398954089541895428954389544895458954689547895488954989550895518955289553895548955589556895578955889559895608956189562895638956489565895668956789568895698957089571895728957389574895758957689577895788957989580895818958289583895848958589586895878958889589895908959189592895938959489595895968959789598895998960089601896028960389604896058960689607896088960989610896118961289613896148961589616896178961889619896208962189622896238962489625896268962789628896298963089631896328963389634896358963689637896388963989640896418964289643896448964589646896478964889649896508965189652896538965489655896568965789658896598966089661896628966389664896658966689667896688966989670896718967289673896748967589676896778967889679896808968189682896838968489685896868968789688896898969089691896928969389694896958969689697896988969989700897018970289703897048970589706897078970889709897108971189712897138971489715897168971789718897198972089721897228972389724897258972689727897288972989730897318973289733897348973589736897378973889739897408974189742897438974489745897468974789748897498975089751897528975389754897558975689757897588975989760897618976289763897648976589766897678976889769897708977189772897738977489775897768977789778897798978089781897828978389784897858978689787897888978989790897918979289793897948979589796897978979889799898008980189802898038980489805898068980789808898098981089811898128981389814898158981689817898188981989820898218982289823898248982589826898278982889829898308983189832898338983489835898368983789838898398984089841898428984389844898458984689847898488984989850898518985289853898548985589856898578985889859898608986189862898638986489865898668986789868898698987089871898728987389874898758987689877898788987989880898818988289883898848988589886898878988889889898908989189892898938989489895898968989789898898998990089901899028990389904899058990689907899088990989910899118991289913899148991589916899178991889919899208992189922899238992489925899268992789928899298993089931899328993389934899358993689937899388993989940899418994289943899448994589946899478994889949899508995189952899538995489955899568995789958899598996089961899628996389964899658996689967899688996989970899718997289973899748997589976899778997889979899808998189982899838998489985899868998789988899898999089991899928999389994899958999689997899988999990000900019000290003900049000590006900079000890009900109001190012900139001490015900169001790018900199002090021900229002390024900259002690027900289002990030900319003290033900349003590036900379003890039900409004190042900439004490045900469004790048900499005090051900529005390054900559005690057900589005990060900619006290063900649006590066900679006890069900709007190072900739007490075900769007790078900799008090081900829008390084900859008690087900889008990090900919009290093900949009590096900979009890099901009010190102901039010490105901069010790108901099011090111901129011390114901159011690117901189011990120901219012290123901249012590126901279012890129901309013190132901339013490135901369013790138901399014090141901429014390144901459014690147901489014990150901519015290153901549015590156901579015890159901609016190162901639016490165901669016790168901699017090171901729017390174901759017690177901789017990180901819018290183901849018590186901879018890189901909019190192901939019490195901969019790198901999020090201902029020390204902059020690207902089020990210902119021290213902149021590216902179021890219902209022190222902239022490225902269022790228902299023090231902329023390234902359023690237902389023990240902419024290243902449024590246902479024890249902509025190252902539025490255902569025790258902599026090261902629026390264902659026690267902689026990270902719027290273902749027590276902779027890279902809028190282902839028490285902869028790288902899029090291902929029390294902959029690297902989029990300903019030290303903049030590306903079030890309903109031190312903139031490315903169031790318903199032090321903229032390324903259032690327903289032990330903319033290333903349033590336903379033890339903409034190342903439034490345903469034790348903499035090351903529035390354903559035690357903589035990360903619036290363903649036590366903679036890369903709037190372903739037490375903769037790378903799038090381903829038390384903859038690387903889038990390903919039290393903949039590396903979039890399904009040190402904039040490405904069040790408904099041090411904129041390414904159041690417904189041990420904219042290423904249042590426904279042890429904309043190432904339043490435904369043790438904399044090441904429044390444904459044690447904489044990450904519045290453904549045590456904579045890459904609046190462904639046490465904669046790468904699047090471904729047390474904759047690477904789047990480904819048290483904849048590486904879048890489904909049190492904939049490495904969049790498904999050090501905029050390504905059050690507905089050990510905119051290513905149051590516905179051890519905209052190522905239052490525905269052790528905299053090531905329053390534905359053690537905389053990540905419054290543905449054590546905479054890549905509055190552905539055490555905569055790558905599056090561905629056390564905659056690567905689056990570905719057290573905749057590576905779057890579905809058190582905839058490585905869058790588905899059090591905929059390594905959059690597905989059990600906019060290603906049060590606906079060890609906109061190612906139061490615906169061790618906199062090621906229062390624906259062690627906289062990630906319063290633906349063590636906379063890639906409064190642906439064490645906469064790648906499065090651906529065390654906559065690657906589065990660906619066290663906649066590666906679066890669906709067190672906739067490675906769067790678906799068090681906829068390684906859068690687906889068990690906919069290693906949069590696906979069890699907009070190702907039070490705907069070790708907099071090711907129071390714907159071690717907189071990720907219072290723907249072590726907279072890729907309073190732907339073490735907369073790738907399074090741907429074390744907459074690747907489074990750907519075290753907549075590756907579075890759907609076190762907639076490765907669076790768907699077090771907729077390774907759077690777907789077990780907819078290783907849078590786907879078890789907909079190792907939079490795907969079790798907999080090801908029080390804908059080690807908089080990810908119081290813908149081590816908179081890819908209082190822908239082490825908269082790828908299083090831908329083390834908359083690837908389083990840908419084290843908449084590846908479084890849908509085190852908539085490855908569085790858908599086090861908629086390864908659086690867908689086990870908719087290873908749087590876908779087890879908809088190882908839088490885908869088790888908899089090891908929089390894908959089690897908989089990900909019090290903909049090590906909079090890909909109091190912909139091490915909169091790918909199092090921909229092390924909259092690927909289092990930909319093290933909349093590936909379093890939909409094190942909439094490945909469094790948909499095090951909529095390954909559095690957909589095990960909619096290963909649096590966909679096890969909709097190972909739097490975909769097790978909799098090981909829098390984909859098690987909889098990990909919099290993909949099590996909979099890999910009100191002910039100491005910069100791008910099101091011910129101391014910159101691017910189101991020910219102291023910249102591026910279102891029910309103191032910339103491035910369103791038910399104091041910429104391044910459104691047910489104991050910519105291053910549105591056910579105891059910609106191062910639106491065910669106791068910699107091071910729107391074910759107691077910789107991080910819108291083910849108591086910879108891089910909109191092910939109491095910969109791098910999110091101911029110391104911059110691107911089110991110911119111291113911149111591116911179111891119911209112191122911239112491125911269112791128911299113091131911329113391134911359113691137911389113991140911419114291143911449114591146911479114891149911509115191152911539115491155911569115791158911599116091161911629116391164911659116691167911689116991170911719117291173911749117591176911779117891179911809118191182911839118491185911869118791188911899119091191911929119391194911959119691197911989119991200912019120291203912049120591206912079120891209912109121191212912139121491215912169121791218912199122091221912229122391224912259122691227912289122991230912319123291233912349123591236912379123891239912409124191242912439124491245912469124791248912499125091251912529125391254912559125691257912589125991260912619126291263912649126591266912679126891269912709127191272912739127491275912769127791278912799128091281912829128391284912859128691287912889128991290912919129291293912949129591296912979129891299913009130191302913039130491305913069130791308913099131091311913129131391314913159131691317913189131991320913219132291323913249132591326913279132891329913309133191332913339133491335913369133791338913399134091341913429134391344913459134691347913489134991350913519135291353913549135591356913579135891359913609136191362913639136491365913669136791368913699137091371913729137391374913759137691377913789137991380913819138291383913849138591386913879138891389913909139191392913939139491395913969139791398913999140091401914029140391404914059140691407914089140991410914119141291413914149141591416914179141891419914209142191422914239142491425914269142791428914299143091431914329143391434914359143691437914389143991440914419144291443914449144591446914479144891449914509145191452914539145491455914569145791458914599146091461914629146391464914659146691467914689146991470914719147291473914749147591476914779147891479914809148191482914839148491485914869148791488914899149091491914929149391494914959149691497914989149991500915019150291503915049150591506915079150891509915109151191512915139151491515915169151791518915199152091521915229152391524915259152691527915289152991530915319153291533915349153591536915379153891539915409154191542915439154491545915469154791548915499155091551915529155391554915559155691557915589155991560915619156291563915649156591566915679156891569915709157191572915739157491575915769157791578915799158091581915829158391584915859158691587915889158991590915919159291593915949159591596915979159891599916009160191602916039160491605916069160791608916099161091611916129161391614916159161691617916189161991620916219162291623916249162591626916279162891629916309163191632916339163491635916369163791638916399164091641916429164391644916459164691647916489164991650916519165291653916549165591656916579165891659916609166191662916639166491665916669166791668916699167091671916729167391674916759167691677916789167991680916819168291683916849168591686916879168891689916909169191692916939169491695916969169791698916999170091701917029170391704917059170691707917089170991710917119171291713917149171591716917179171891719917209172191722917239172491725917269172791728917299173091731917329173391734917359173691737917389173991740917419174291743917449174591746917479174891749917509175191752917539175491755917569175791758917599176091761917629176391764917659176691767917689176991770917719177291773917749177591776917779177891779917809178191782917839178491785917869178791788917899179091791917929179391794917959179691797917989179991800918019180291803918049180591806918079180891809918109181191812918139181491815918169181791818918199182091821918229182391824918259182691827918289182991830918319183291833918349183591836918379183891839918409184191842918439184491845918469184791848918499185091851918529185391854918559185691857918589185991860918619186291863918649186591866918679186891869918709187191872918739187491875918769187791878918799188091881918829188391884918859188691887918889188991890918919189291893918949189591896918979189891899919009190191902919039190491905919069190791908919099191091911919129191391914919159191691917919189191991920919219192291923919249192591926919279192891929919309193191932919339193491935919369193791938919399194091941919429194391944919459194691947919489194991950919519195291953919549195591956919579195891959919609196191962919639196491965919669196791968919699197091971919729197391974919759197691977919789197991980919819198291983919849198591986919879198891989919909199191992919939199491995919969199791998919999200092001920029200392004920059200692007920089200992010920119201292013920149201592016920179201892019920209202192022920239202492025920269202792028920299203092031920329203392034920359203692037920389203992040920419204292043920449204592046920479204892049920509205192052920539205492055920569205792058920599206092061920629206392064920659206692067920689206992070920719207292073920749207592076920779207892079920809208192082920839208492085920869208792088920899209092091920929209392094920959209692097920989209992100921019210292103921049210592106921079210892109921109211192112921139211492115921169211792118921199212092121921229212392124921259212692127921289212992130921319213292133921349213592136921379213892139921409214192142921439214492145921469214792148921499215092151921529215392154921559215692157921589215992160921619216292163921649216592166921679216892169921709217192172921739217492175921769217792178921799218092181921829218392184921859218692187921889218992190921919219292193921949219592196921979219892199922009220192202922039220492205922069220792208922099221092211922129221392214922159221692217922189221992220922219222292223922249222592226922279222892229922309223192232922339223492235922369223792238922399224092241922429224392244922459224692247922489224992250922519225292253922549225592256922579225892259922609226192262922639226492265922669226792268922699227092271922729227392274922759227692277922789227992280922819228292283922849228592286922879228892289922909229192292922939229492295922969229792298922999230092301923029230392304923059230692307923089230992310923119231292313923149231592316923179231892319923209232192322923239232492325923269232792328923299233092331923329233392334923359233692337923389233992340923419234292343923449234592346923479234892349923509235192352923539235492355923569235792358923599236092361923629236392364923659236692367923689236992370923719237292373923749237592376923779237892379923809238192382923839238492385923869238792388923899239092391923929239392394923959239692397923989239992400924019240292403924049240592406924079240892409924109241192412924139241492415924169241792418924199242092421924229242392424924259242692427924289242992430924319243292433924349243592436924379243892439924409244192442924439244492445924469244792448924499245092451924529245392454924559245692457924589245992460924619246292463924649246592466924679246892469924709247192472924739247492475924769247792478924799248092481924829248392484924859248692487924889248992490924919249292493924949249592496924979249892499925009250192502925039250492505925069250792508925099251092511925129251392514925159251692517925189251992520925219252292523925249252592526925279252892529925309253192532925339253492535925369253792538925399254092541925429254392544925459254692547925489254992550925519255292553925549255592556925579255892559925609256192562925639256492565925669256792568925699257092571925729257392574925759257692577925789257992580925819258292583925849258592586925879258892589925909259192592925939259492595925969259792598925999260092601926029260392604926059260692607926089260992610926119261292613926149261592616926179261892619926209262192622926239262492625926269262792628926299263092631926329263392634926359263692637926389263992640926419264292643926449264592646926479264892649926509265192652926539265492655926569265792658926599266092661926629266392664926659266692667926689266992670926719267292673926749267592676926779267892679926809268192682926839268492685926869268792688926899269092691926929269392694926959269692697926989269992700927019270292703927049270592706927079270892709927109271192712927139271492715927169271792718927199272092721927229272392724927259272692727927289272992730927319273292733927349273592736927379273892739927409274192742927439274492745927469274792748927499275092751927529275392754927559275692757927589275992760927619276292763927649276592766927679276892769927709277192772927739277492775927769277792778927799278092781927829278392784927859278692787927889278992790927919279292793927949279592796927979279892799928009280192802928039280492805928069280792808928099281092811928129281392814928159281692817928189281992820928219282292823928249282592826928279282892829928309283192832928339283492835928369283792838928399284092841928429284392844928459284692847928489284992850928519285292853928549285592856928579285892859928609286192862928639286492865928669286792868928699287092871928729287392874928759287692877928789287992880928819288292883928849288592886928879288892889928909289192892928939289492895928969289792898928999290092901929029290392904929059290692907929089290992910929119291292913929149291592916929179291892919929209292192922929239292492925929269292792928929299293092931929329293392934929359293692937929389293992940929419294292943929449294592946929479294892949929509295192952929539295492955929569295792958929599296092961929629296392964929659296692967929689296992970929719297292973929749297592976929779297892979929809298192982929839298492985929869298792988929899299092991929929299392994929959299692997929989299993000930019300293003930049300593006930079300893009930109301193012930139301493015930169301793018930199302093021930229302393024930259302693027930289302993030930319303293033930349303593036930379303893039930409304193042930439304493045930469304793048930499305093051930529305393054930559305693057930589305993060930619306293063930649306593066930679306893069930709307193072930739307493075930769307793078930799308093081930829308393084930859308693087930889308993090930919309293093930949309593096930979309893099931009310193102931039310493105931069310793108931099311093111931129311393114931159311693117931189311993120931219312293123931249312593126931279312893129931309313193132931339313493135931369313793138931399314093141931429314393144931459314693147931489314993150931519315293153931549315593156931579315893159931609316193162931639316493165931669316793168931699317093171931729317393174931759317693177931789317993180931819318293183931849318593186931879318893189931909319193192931939319493195931969319793198931999320093201932029320393204932059320693207932089320993210932119321293213932149321593216932179321893219932209322193222932239322493225932269322793228932299323093231932329323393234932359323693237932389323993240932419324293243932449324593246932479324893249932509325193252932539325493255932569325793258932599326093261932629326393264932659326693267932689326993270932719327293273932749327593276932779327893279932809328193282932839328493285932869328793288932899329093291932929329393294932959329693297932989329993300933019330293303933049330593306933079330893309933109331193312933139331493315933169331793318933199332093321933229332393324933259332693327933289332993330933319333293333933349333593336933379333893339933409334193342933439334493345933469334793348933499335093351933529335393354933559335693357933589335993360933619336293363933649336593366933679336893369933709337193372933739337493375933769337793378933799338093381933829338393384933859338693387933889338993390933919339293393933949339593396933979339893399934009340193402934039340493405934069340793408934099341093411934129341393414934159341693417934189341993420934219342293423934249342593426934279342893429934309343193432934339343493435934369343793438934399344093441934429344393444934459344693447934489344993450934519345293453934549345593456934579345893459934609346193462934639346493465934669346793468934699347093471934729347393474934759347693477934789347993480934819348293483934849348593486934879348893489934909349193492934939349493495934969349793498934999350093501935029350393504935059350693507935089350993510935119351293513935149351593516935179351893519935209352193522935239352493525935269352793528935299353093531935329353393534935359353693537935389353993540935419354293543935449354593546935479354893549935509355193552935539355493555935569355793558935599356093561935629356393564935659356693567935689356993570935719357293573935749357593576935779357893579935809358193582935839358493585935869358793588935899359093591935929359393594935959359693597935989359993600936019360293603936049360593606936079360893609936109361193612936139361493615936169361793618936199362093621936229362393624936259362693627936289362993630936319363293633936349363593636936379363893639936409364193642936439364493645936469364793648936499365093651936529365393654936559365693657936589365993660936619366293663936649366593666936679366893669936709367193672936739367493675936769367793678936799368093681936829368393684936859368693687936889368993690936919369293693936949369593696936979369893699937009370193702937039370493705937069370793708937099371093711937129371393714937159371693717937189371993720937219372293723937249372593726937279372893729937309373193732937339373493735937369373793738937399374093741937429374393744937459374693747937489374993750937519375293753937549375593756937579375893759937609376193762937639376493765937669376793768937699377093771937729377393774937759377693777937789377993780937819378293783937849378593786937879378893789937909379193792937939379493795937969379793798937999380093801938029380393804938059380693807938089380993810938119381293813938149381593816938179381893819938209382193822938239382493825938269382793828938299383093831938329383393834938359383693837938389383993840938419384293843938449384593846938479384893849938509385193852938539385493855938569385793858938599386093861938629386393864938659386693867938689386993870938719387293873938749387593876938779387893879938809388193882938839388493885938869388793888938899389093891938929389393894938959389693897938989389993900939019390293903939049390593906939079390893909939109391193912939139391493915939169391793918939199392093921939229392393924939259392693927939289392993930939319393293933939349393593936939379393893939939409394193942939439394493945939469394793948939499395093951939529395393954939559395693957939589395993960939619396293963939649396593966939679396893969939709397193972939739397493975939769397793978939799398093981939829398393984939859398693987939889398993990939919399293993939949399593996939979399893999940009400194002940039400494005940069400794008940099401094011940129401394014940159401694017940189401994020940219402294023940249402594026940279402894029940309403194032940339403494035940369403794038940399404094041940429404394044940459404694047940489404994050940519405294053940549405594056940579405894059940609406194062940639406494065940669406794068940699407094071940729407394074940759407694077940789407994080940819408294083940849408594086940879408894089940909409194092940939409494095940969409794098940999410094101941029410394104941059410694107941089410994110941119411294113941149411594116941179411894119941209412194122941239412494125941269412794128941299413094131941329413394134941359413694137941389413994140941419414294143941449414594146941479414894149941509415194152941539415494155941569415794158941599416094161941629416394164941659416694167941689416994170941719417294173941749417594176941779417894179941809418194182941839418494185941869418794188941899419094191941929419394194941959419694197941989419994200942019420294203942049420594206942079420894209942109421194212942139421494215942169421794218942199422094221942229422394224942259422694227942289422994230942319423294233942349423594236942379423894239942409424194242942439424494245942469424794248942499425094251942529425394254942559425694257942589425994260942619426294263942649426594266942679426894269942709427194272942739427494275942769427794278942799428094281942829428394284942859428694287942889428994290942919429294293942949429594296942979429894299943009430194302943039430494305943069430794308943099431094311943129431394314943159431694317943189431994320943219432294323943249432594326943279432894329943309433194332943339433494335943369433794338943399434094341943429434394344943459434694347943489434994350943519435294353943549435594356943579435894359943609436194362943639436494365943669436794368943699437094371943729437394374943759437694377943789437994380943819438294383943849438594386943879438894389943909439194392943939439494395943969439794398943999440094401944029440394404944059440694407944089440994410944119441294413944149441594416944179441894419944209442194422944239442494425944269442794428944299443094431944329443394434944359443694437944389443994440944419444294443944449444594446944479444894449944509445194452944539445494455944569445794458944599446094461944629446394464944659446694467944689446994470944719447294473944749447594476944779447894479944809448194482944839448494485944869448794488944899449094491944929449394494944959449694497944989449994500945019450294503945049450594506945079450894509945109451194512945139451494515945169451794518945199452094521945229452394524945259452694527945289452994530945319453294533945349453594536945379453894539945409454194542945439454494545945469454794548945499455094551945529455394554945559455694557945589455994560945619456294563945649456594566945679456894569945709457194572945739457494575945769457794578945799458094581945829458394584945859458694587945889458994590945919459294593945949459594596945979459894599946009460194602946039460494605946069460794608946099461094611946129461394614946159461694617946189461994620946219462294623946249462594626946279462894629946309463194632946339463494635946369463794638946399464094641946429464394644946459464694647946489464994650946519465294653946549465594656946579465894659946609466194662946639466494665946669466794668946699467094671946729467394674946759467694677946789467994680946819468294683946849468594686946879468894689946909469194692946939469494695946969469794698946999470094701947029470394704947059470694707947089470994710947119471294713947149471594716947179471894719947209472194722947239472494725947269472794728947299473094731947329473394734947359473694737947389473994740947419474294743947449474594746947479474894749947509475194752947539475494755947569475794758947599476094761947629476394764947659476694767947689476994770947719477294773947749477594776947779477894779947809478194782947839478494785947869478794788947899479094791947929479394794947959479694797947989479994800948019480294803948049480594806948079480894809948109481194812948139481494815948169481794818948199482094821948229482394824948259482694827948289482994830948319483294833948349483594836948379483894839948409484194842948439484494845948469484794848948499485094851948529485394854948559485694857948589485994860948619486294863948649486594866948679486894869948709487194872948739487494875948769487794878948799488094881948829488394884948859488694887948889488994890948919489294893948949489594896948979489894899949009490194902949039490494905949069490794908949099491094911949129491394914949159491694917949189491994920949219492294923949249492594926949279492894929949309493194932949339493494935949369493794938949399494094941949429494394944949459494694947949489494994950949519495294953949549495594956949579495894959949609496194962949639496494965949669496794968949699497094971949729497394974949759497694977949789497994980949819498294983949849498594986949879498894989949909499194992949939499494995949969499794998949999500095001950029500395004950059500695007950089500995010950119501295013950149501595016950179501895019950209502195022950239502495025950269502795028950299503095031950329503395034950359503695037950389503995040950419504295043950449504595046950479504895049950509505195052950539505495055950569505795058950599506095061950629506395064950659506695067950689506995070950719507295073950749507595076950779507895079950809508195082950839508495085950869508795088950899509095091950929509395094950959509695097950989509995100951019510295103951049510595106951079510895109951109511195112951139511495115951169511795118951199512095121951229512395124951259512695127951289512995130951319513295133951349513595136951379513895139951409514195142951439514495145951469514795148951499515095151951529515395154951559515695157951589515995160951619516295163951649516595166951679516895169951709517195172951739517495175951769517795178951799518095181951829518395184951859518695187951889518995190951919519295193951949519595196951979519895199952009520195202952039520495205952069520795208952099521095211952129521395214952159521695217952189521995220952219522295223952249522595226952279522895229952309523195232952339523495235952369523795238952399524095241952429524395244952459524695247952489524995250952519525295253952549525595256952579525895259952609526195262952639526495265952669526795268952699527095271952729527395274952759527695277952789527995280952819528295283952849528595286952879528895289952909529195292952939529495295952969529795298952999530095301953029530395304953059530695307953089530995310953119531295313953149531595316953179531895319953209532195322953239532495325953269532795328953299533095331953329533395334953359533695337953389533995340953419534295343953449534595346953479534895349953509535195352953539535495355953569535795358953599536095361953629536395364953659536695367953689536995370953719537295373953749537595376953779537895379953809538195382953839538495385953869538795388953899539095391953929539395394953959539695397953989539995400954019540295403954049540595406954079540895409954109541195412954139541495415954169541795418954199542095421954229542395424954259542695427954289542995430954319543295433954349543595436954379543895439954409544195442954439544495445954469544795448954499545095451954529545395454954559545695457954589545995460954619546295463954649546595466954679546895469954709547195472954739547495475954769547795478954799548095481954829548395484954859548695487954889548995490954919549295493954949549595496954979549895499955009550195502955039550495505955069550795508955099551095511955129551395514955159551695517955189551995520955219552295523955249552595526955279552895529955309553195532955339553495535955369553795538955399554095541955429554395544955459554695547955489554995550955519555295553955549555595556955579555895559955609556195562955639556495565955669556795568955699557095571955729557395574955759557695577955789557995580955819558295583955849558595586955879558895589955909559195592955939559495595955969559795598955999560095601956029560395604956059560695607956089560995610956119561295613956149561595616956179561895619956209562195622956239562495625956269562795628956299563095631956329563395634956359563695637956389563995640956419564295643956449564595646956479564895649956509565195652956539565495655956569565795658956599566095661956629566395664956659566695667956689566995670956719567295673956749567595676956779567895679956809568195682956839568495685956869568795688956899569095691956929569395694956959569695697956989569995700957019570295703957049570595706957079570895709957109571195712957139571495715957169571795718957199572095721957229572395724957259572695727957289572995730957319573295733957349573595736957379573895739957409574195742957439574495745957469574795748957499575095751957529575395754957559575695757957589575995760957619576295763957649576595766957679576895769957709577195772957739577495775957769577795778957799578095781957829578395784957859578695787957889578995790957919579295793957949579595796957979579895799958009580195802958039580495805958069580795808958099581095811958129581395814958159581695817958189581995820958219582295823958249582595826958279582895829958309583195832958339583495835958369583795838958399584095841958429584395844958459584695847958489584995850958519585295853958549585595856958579585895859958609586195862958639586495865958669586795868958699587095871958729587395874958759587695877958789587995880958819588295883958849588595886958879588895889958909589195892958939589495895958969589795898958999590095901959029590395904959059590695907959089590995910959119591295913959149591595916959179591895919959209592195922959239592495925959269592795928959299593095931959329593395934959359593695937959389593995940959419594295943959449594595946959479594895949959509595195952959539595495955959569595795958959599596095961959629596395964959659596695967959689596995970959719597295973959749597595976959779597895979959809598195982959839598495985959869598795988959899599095991959929599395994959959599695997959989599996000960019600296003960049600596006960079600896009960109601196012960139601496015960169601796018960199602096021960229602396024960259602696027960289602996030960319603296033960349603596036960379603896039960409604196042960439604496045960469604796048960499605096051960529605396054960559605696057960589605996060960619606296063960649606596066960679606896069960709607196072960739607496075960769607796078960799608096081960829608396084960859608696087960889608996090960919609296093960949609596096960979609896099961009610196102961039610496105961069610796108961099611096111961129611396114961159611696117961189611996120961219612296123961249612596126961279612896129961309613196132961339613496135961369613796138961399614096141961429614396144961459614696147961489614996150961519615296153961549615596156961579615896159961609616196162961639616496165961669616796168961699617096171961729617396174961759617696177961789617996180961819618296183961849618596186961879618896189961909619196192961939619496195961969619796198961999620096201962029620396204962059620696207962089620996210962119621296213962149621596216962179621896219962209622196222962239622496225962269622796228962299623096231962329623396234962359623696237962389623996240962419624296243962449624596246962479624896249962509625196252962539625496255962569625796258962599626096261962629626396264962659626696267962689626996270962719627296273962749627596276962779627896279962809628196282962839628496285962869628796288962899629096291962929629396294962959629696297962989629996300963019630296303963049630596306963079630896309963109631196312963139631496315963169631796318963199632096321963229632396324963259632696327963289632996330963319633296333963349633596336963379633896339963409634196342963439634496345963469634796348963499635096351963529635396354963559635696357963589635996360963619636296363963649636596366963679636896369963709637196372963739637496375963769637796378963799638096381963829638396384963859638696387963889638996390963919639296393963949639596396963979639896399964009640196402964039640496405964069640796408964099641096411964129641396414964159641696417964189641996420964219642296423964249642596426964279642896429964309643196432964339643496435964369643796438964399644096441964429644396444964459644696447964489644996450964519645296453964549645596456964579645896459964609646196462964639646496465964669646796468964699647096471964729647396474964759647696477964789647996480964819648296483964849648596486964879648896489964909649196492964939649496495964969649796498964999650096501965029650396504965059650696507965089650996510965119651296513965149651596516965179651896519965209652196522965239652496525965269652796528965299653096531965329653396534965359653696537965389653996540965419654296543965449654596546965479654896549965509655196552965539655496555965569655796558965599656096561965629656396564965659656696567965689656996570965719657296573965749657596576965779657896579965809658196582965839658496585965869658796588965899659096591965929659396594965959659696597965989659996600966019660296603966049660596606966079660896609966109661196612966139661496615966169661796618966199662096621966229662396624966259662696627966289662996630966319663296633966349663596636966379663896639966409664196642966439664496645966469664796648966499665096651966529665396654966559665696657966589665996660966619666296663966649666596666966679666896669966709667196672966739667496675966769667796678966799668096681966829668396684966859668696687966889668996690966919669296693966949669596696966979669896699967009670196702967039670496705967069670796708967099671096711967129671396714967159671696717967189671996720967219672296723967249672596726967279672896729967309673196732967339673496735967369673796738967399674096741967429674396744967459674696747967489674996750967519675296753967549675596756967579675896759967609676196762967639676496765967669676796768967699677096771967729677396774967759677696777967789677996780967819678296783967849678596786967879678896789967909679196792967939679496795967969679796798967999680096801968029680396804968059680696807968089680996810968119681296813968149681596816968179681896819968209682196822968239682496825968269682796828968299683096831968329683396834968359683696837968389683996840968419684296843968449684596846968479684896849968509685196852968539685496855968569685796858968599686096861968629686396864968659686696867968689686996870968719687296873968749687596876968779687896879968809688196882968839688496885968869688796888968899689096891968929689396894968959689696897968989689996900969019690296903969049690596906969079690896909969109691196912969139691496915969169691796918969199692096921969229692396924969259692696927969289692996930969319693296933969349693596936969379693896939969409694196942969439694496945969469694796948969499695096951969529695396954969559695696957969589695996960969619696296963969649696596966969679696896969969709697196972969739697496975969769697796978969799698096981969829698396984969859698696987969889698996990969919699296993969949699596996969979699896999970009700197002970039700497005970069700797008970099701097011970129701397014970159701697017970189701997020970219702297023970249702597026970279702897029970309703197032970339703497035970369703797038970399704097041970429704397044970459704697047970489704997050970519705297053970549705597056970579705897059970609706197062970639706497065970669706797068970699707097071970729707397074970759707697077970789707997080970819708297083970849708597086970879708897089970909709197092970939709497095970969709797098970999710097101971029710397104971059710697107971089710997110971119711297113971149711597116971179711897119971209712197122971239712497125971269712797128971299713097131971329713397134971359713697137971389713997140971419714297143971449714597146971479714897149971509715197152971539715497155971569715797158971599716097161971629716397164971659716697167971689716997170971719717297173971749717597176971779717897179971809718197182971839718497185971869718797188971899719097191971929719397194971959719697197971989719997200972019720297203972049720597206972079720897209972109721197212972139721497215972169721797218972199722097221972229722397224972259722697227972289722997230972319723297233972349723597236972379723897239972409724197242972439724497245972469724797248972499725097251972529725397254972559725697257972589725997260972619726297263972649726597266972679726897269972709727197272972739727497275972769727797278972799728097281972829728397284972859728697287972889728997290972919729297293972949729597296972979729897299973009730197302973039730497305973069730797308973099731097311973129731397314973159731697317973189731997320973219732297323973249732597326973279732897329973309733197332973339733497335973369733797338973399734097341973429734397344973459734697347973489734997350973519735297353973549735597356973579735897359973609736197362973639736497365973669736797368973699737097371973729737397374973759737697377973789737997380973819738297383973849738597386973879738897389973909739197392973939739497395973969739797398973999740097401974029740397404974059740697407974089740997410974119741297413974149741597416974179741897419974209742197422974239742497425974269742797428974299743097431974329743397434974359743697437974389743997440974419744297443974449744597446974479744897449974509745197452974539745497455974569745797458974599746097461974629746397464974659746697467974689746997470974719747297473974749747597476974779747897479974809748197482974839748497485974869748797488974899749097491974929749397494974959749697497974989749997500975019750297503975049750597506975079750897509975109751197512975139751497515975169751797518975199752097521975229752397524975259752697527975289752997530975319753297533975349753597536975379753897539975409754197542975439754497545975469754797548975499755097551975529755397554975559755697557975589755997560975619756297563975649756597566975679756897569975709757197572975739757497575975769757797578975799758097581975829758397584975859758697587975889758997590975919759297593975949759597596975979759897599976009760197602976039760497605976069760797608976099761097611976129761397614976159761697617976189761997620976219762297623976249762597626976279762897629976309763197632976339763497635976369763797638976399764097641976429764397644976459764697647976489764997650976519765297653976549765597656976579765897659976609766197662976639766497665976669766797668976699767097671976729767397674976759767697677976789767997680976819768297683976849768597686976879768897689976909769197692976939769497695976969769797698976999770097701977029770397704977059770697707977089770997710977119771297713977149771597716977179771897719977209772197722977239772497725977269772797728977299773097731977329773397734977359773697737977389773997740977419774297743977449774597746977479774897749977509775197752977539775497755977569775797758977599776097761977629776397764977659776697767977689776997770977719777297773977749777597776977779777897779977809778197782977839778497785977869778797788977899779097791977929779397794977959779697797977989779997800978019780297803978049780597806978079780897809978109781197812978139781497815978169781797818978199782097821978229782397824978259782697827978289782997830978319783297833978349783597836978379783897839978409784197842978439784497845978469784797848978499785097851978529785397854978559785697857978589785997860978619786297863978649786597866978679786897869978709787197872978739787497875978769787797878978799788097881978829788397884978859788697887978889788997890978919789297893978949789597896978979789897899979009790197902979039790497905979069790797908979099791097911979129791397914979159791697917979189791997920979219792297923979249792597926979279792897929979309793197932979339793497935979369793797938979399794097941979429794397944979459794697947979489794997950979519795297953979549795597956979579795897959979609796197962979639796497965979669796797968979699797097971979729797397974979759797697977979789797997980979819798297983979849798597986979879798897989979909799197992979939799497995979969799797998979999800098001980029800398004980059800698007980089800998010980119801298013980149801598016980179801898019980209802198022980239802498025980269802798028980299803098031980329803398034980359803698037980389803998040980419804298043980449804598046980479804898049980509805198052980539805498055980569805798058980599806098061980629806398064980659806698067980689806998070980719807298073980749807598076980779807898079980809808198082980839808498085980869808798088980899809098091980929809398094980959809698097980989809998100981019810298103981049810598106981079810898109981109811198112981139811498115981169811798118981199812098121981229812398124981259812698127981289812998130981319813298133981349813598136981379813898139981409814198142981439814498145981469814798148981499815098151981529815398154981559815698157981589815998160981619816298163981649816598166981679816898169981709817198172981739817498175981769817798178981799818098181981829818398184981859818698187981889818998190981919819298193981949819598196981979819898199982009820198202982039820498205982069820798208982099821098211982129821398214982159821698217982189821998220982219822298223982249822598226982279822898229982309823198232982339823498235982369823798238982399824098241982429824398244982459824698247982489824998250982519825298253982549825598256982579825898259982609826198262982639826498265982669826798268982699827098271982729827398274982759827698277982789827998280982819828298283982849828598286982879828898289982909829198292982939829498295982969829798298982999830098301983029830398304983059830698307983089830998310983119831298313983149831598316983179831898319983209832198322983239832498325983269832798328983299833098331983329833398334983359833698337983389833998340983419834298343983449834598346983479834898349983509835198352983539835498355983569835798358983599836098361983629836398364983659836698367983689836998370983719837298373983749837598376983779837898379983809838198382983839838498385983869838798388983899839098391983929839398394983959839698397983989839998400984019840298403984049840598406984079840898409984109841198412984139841498415984169841798418984199842098421984229842398424984259842698427984289842998430984319843298433984349843598436984379843898439984409844198442984439844498445984469844798448984499845098451984529845398454984559845698457984589845998460984619846298463984649846598466984679846898469984709847198472984739847498475984769847798478984799848098481984829848398484984859848698487984889848998490984919849298493984949849598496984979849898499985009850198502985039850498505985069850798508985099851098511985129851398514985159851698517985189851998520985219852298523985249852598526985279852898529985309853198532985339853498535985369853798538985399854098541985429854398544985459854698547985489854998550985519855298553985549855598556985579855898559985609856198562985639856498565985669856798568985699857098571985729857398574985759857698577985789857998580985819858298583985849858598586985879858898589985909859198592985939859498595985969859798598985999860098601986029860398604986059860698607986089860998610986119861298613986149861598616986179861898619986209862198622986239862498625986269862798628986299863098631986329863398634986359863698637986389863998640986419864298643986449864598646986479864898649986509865198652986539865498655986569865798658986599866098661986629866398664986659866698667986689866998670986719867298673986749867598676986779867898679986809868198682986839868498685986869868798688986899869098691986929869398694986959869698697986989869998700987019870298703987049870598706987079870898709987109871198712987139871498715987169871798718987199872098721987229872398724987259872698727987289872998730987319873298733987349873598736987379873898739987409874198742987439874498745987469874798748987499875098751987529875398754987559875698757987589875998760987619876298763987649876598766987679876898769987709877198772987739877498775987769877798778987799878098781987829878398784987859878698787987889878998790987919879298793987949879598796987979879898799988009880198802988039880498805988069880798808988099881098811988129881398814988159881698817988189881998820988219882298823988249882598826988279882898829988309883198832988339883498835988369883798838988399884098841988429884398844988459884698847988489884998850988519885298853988549885598856988579885898859988609886198862988639886498865988669886798868988699887098871988729887398874988759887698877988789887998880988819888298883988849888598886988879888898889988909889198892988939889498895988969889798898988999890098901989029890398904989059890698907989089890998910989119891298913989149891598916989179891898919989209892198922989239892498925989269892798928989299893098931989329893398934989359893698937989389893998940989419894298943989449894598946989479894898949989509895198952989539895498955989569895798958989599896098961989629896398964989659896698967989689896998970989719897298973989749897598976989779897898979989809898198982989839898498985989869898798988989899899098991989929899398994989959899698997989989899999000990019900299003990049900599006990079900899009990109901199012990139901499015990169901799018990199902099021990229902399024990259902699027990289902999030990319903299033990349903599036990379903899039990409904199042990439904499045990469904799048990499905099051990529905399054990559905699057990589905999060990619906299063990649906599066990679906899069990709907199072990739907499075990769907799078990799908099081990829908399084990859908699087990889908999090990919909299093990949909599096990979909899099991009910199102991039910499105991069910799108991099911099111991129911399114991159911699117991189911999120991219912299123991249912599126991279912899129991309913199132991339913499135991369913799138991399914099141991429914399144991459914699147991489914999150991519915299153991549915599156991579915899159991609916199162991639916499165991669916799168991699917099171991729917399174991759917699177991789917999180991819918299183991849918599186991879918899189991909919199192991939919499195991969919799198991999920099201992029920399204992059920699207992089920999210992119921299213992149921599216992179921899219992209922199222992239922499225992269922799228992299923099231992329923399234992359923699237992389923999240992419924299243992449924599246992479924899249992509925199252992539925499255992569925799258992599926099261992629926399264992659926699267992689926999270992719927299273992749927599276992779927899279992809928199282992839928499285992869928799288992899929099291992929929399294992959929699297992989929999300993019930299303993049930599306993079930899309993109931199312993139931499315993169931799318993199932099321993229932399324993259932699327993289932999330993319933299333993349933599336993379933899339993409934199342993439934499345993469934799348993499935099351993529935399354993559935699357993589935999360993619936299363993649936599366993679936899369993709937199372993739937499375993769937799378993799938099381993829938399384993859938699387993889938999390993919939299393993949939599396993979939899399994009940199402994039940499405994069940799408994099941099411994129941399414994159941699417994189941999420994219942299423994249942599426994279942899429994309943199432994339943499435994369943799438994399944099441994429944399444994459944699447994489944999450994519945299453994549945599456994579945899459994609946199462994639946499465994669946799468994699947099471994729947399474994759947699477994789947999480994819948299483994849948599486994879948899489994909949199492994939949499495994969949799498994999950099501995029950399504995059950699507995089950999510995119951299513995149951599516995179951899519995209952199522995239952499525995269952799528995299953099531995329953399534995359953699537995389953999540995419954299543995449954599546995479954899549995509955199552995539955499555995569955799558995599956099561995629956399564995659956699567995689956999570995719957299573995749957599576995779957899579995809958199582995839958499585995869958799588995899959099591995929959399594995959959699597995989959999600996019960299603996049960599606996079960899609996109961199612996139961499615996169961799618996199962099621996229962399624996259962699627996289962999630996319963299633996349963599636996379963899639996409964199642996439964499645996469964799648996499965099651996529965399654996559965699657996589965999660996619966299663996649966599666996679966899669996709967199672996739967499675996769967799678996799968099681996829968399684996859968699687996889968999690996919969299693996949969599696996979969899699997009970199702997039970499705997069970799708997099971099711997129971399714997159971699717997189971999720997219972299723997249972599726997279972899729997309973199732997339973499735997369973799738997399974099741997429974399744997459974699747997489974999750997519975299753997549975599756997579975899759997609976199762997639976499765997669976799768997699977099771997729977399774997759977699777997789977999780997819978299783997849978599786997879978899789997909979199792997939979499795997969979799798997999980099801998029980399804998059980699807998089980999810998119981299813998149981599816998179981899819998209982199822998239982499825998269982799828998299983099831998329983399834998359983699837998389983999840998419984299843998449984599846998479984899849998509985199852998539985499855998569985799858998599986099861998629986399864998659986699867998689986999870998719987299873998749987599876998779987899879998809988199882998839988499885998869988799888998899989099891998929989399894998959989699897998989989999900999019990299903999049990599906999079990899909999109991199912999139991499915999169991799918999199992099921999229992399924999259992699927999289992999930999319993299933999349993599936999379993899939999409994199942999439994499945999469994799948999499995099951999529995399954999559995699957999589995999960999619996299963999649996599966999679996899969999709997199972999739997499975999769997799978999799998099981999829998399984999859998699987999889998999990999919999299993999949999599996999979999899999100000100001100002100003100004100005100006100007100008100009100010100011100012100013100014100015100016100017100018100019100020100021100022100023100024100025100026100027100028100029100030100031100032100033100034100035100036100037100038100039100040100041100042100043100044100045100046100047100048100049100050100051100052100053100054100055100056100057100058100059100060100061100062100063100064100065100066100067100068100069100070100071100072100073100074100075100076100077100078100079100080100081100082100083100084100085100086100087100088100089100090100091100092100093100094100095100096100097100098100099100100100101100102100103100104100105100106100107100108100109100110100111100112100113100114100115100116100117100118100119100120100121100122100123100124100125100126100127100128100129100130100131100132100133100134100135100136100137100138100139100140100141100142100143100144100145100146100147100148100149100150100151100152100153100154100155100156100157100158100159100160100161100162100163100164100165100166100167100168100169100170100171100172100173100174100175100176100177100178100179100180100181100182100183100184100185100186100187100188100189100190100191100192100193100194100195100196100197100198100199100200100201100202100203100204100205100206100207100208100209100210100211100212100213100214100215100216100217100218100219100220100221100222100223100224100225100226100227100228100229100230100231100232100233100234100235100236100237100238100239100240100241100242100243100244100245100246100247100248100249100250100251100252100253100254100255100256100257100258100259100260100261100262100263100264100265100266100267100268100269100270100271100272100273100274100275100276100277100278100279100280100281100282100283100284100285100286100287100288100289100290100291100292100293100294100295100296100297100298100299100300100301100302100303100304100305100306100307100308100309100310100311100312100313100314100315100316100317100318100319100320100321100322100323100324100325100326100327100328100329100330100331100332100333100334100335100336100337100338100339100340100341100342100343100344100345100346100347100348100349100350100351100352100353100354100355100356100357100358100359100360100361100362100363100364100365100366100367100368100369100370100371100372100373100374100375100376100377100378100379100380100381100382100383100384100385100386100387100388100389100390100391100392100393100394100395100396100397100398100399100400100401100402100403100404100405100406100407100408100409100410100411100412100413100414100415100416100417100418100419100420100421100422100423100424100425100426100427100428100429100430100431100432100433100434100435100436100437100438100439100440100441100442100443100444100445100446100447100448100449100450100451100452100453100454100455100456100457100458100459100460100461100462100463100464100465100466100467100468100469100470100471100472100473100474100475100476100477100478100479100480100481100482100483100484100485100486100487100488100489100490100491100492100493100494100495100496100497100498100499100500100501100502100503100504100505100506100507100508100509100510100511100512100513100514100515100516100517100518100519100520100521100522100523100524100525100526100527100528100529100530100531100532100533100534100535100536100537100538100539100540100541100542100543100544100545100546100547100548100549100550100551100552100553100554100555100556100557100558100559100560100561100562100563100564100565100566100567100568100569100570100571100572100573100574100575100576100577100578100579100580100581100582100583100584100585100586100587100588100589100590100591100592100593100594100595100596100597100598100599100600100601100602100603100604100605100606100607100608100609100610100611100612100613100614100615100616100617100618100619100620100621100622100623100624100625100626100627100628100629100630100631100632100633100634100635100636100637100638100639100640100641100642100643100644100645100646100647100648100649100650100651100652100653100654100655100656100657100658100659100660100661100662100663100664100665100666100667100668100669100670100671100672100673100674100675100676100677100678100679100680100681100682100683100684100685100686100687100688100689100690100691100692100693100694100695100696100697100698100699100700100701100702100703100704100705100706100707100708100709100710100711100712100713100714100715100716100717100718100719100720100721100722100723100724100725100726100727100728100729100730100731100732100733100734100735100736100737100738100739100740100741100742100743100744100745100746100747100748100749100750100751100752100753100754100755100756100757100758100759100760100761100762100763100764100765100766100767100768100769100770100771100772100773100774100775100776100777100778100779100780100781100782100783100784100785100786100787100788100789100790100791100792100793100794100795100796100797100798100799100800100801100802100803100804100805100806100807100808100809100810100811100812100813100814100815100816100817100818100819100820100821100822100823100824100825100826100827100828100829100830100831100832100833100834100835100836100837100838100839100840100841100842100843100844100845100846100847100848100849100850100851100852100853100854100855100856100857100858100859100860100861100862100863100864100865100866100867100868100869100870100871100872100873100874100875100876100877100878100879100880100881100882100883100884100885100886100887100888100889100890100891100892100893100894100895100896100897100898100899100900100901100902100903100904100905100906100907100908100909100910100911100912100913100914100915100916100917100918100919100920100921100922100923100924100925100926100927100928100929100930100931100932100933100934100935100936100937100938100939100940100941100942100943100944100945100946100947100948100949100950100951100952100953100954100955100956100957100958100959100960100961100962100963100964100965100966100967100968100969100970100971100972100973100974100975100976100977100978100979100980100981100982100983100984100985100986100987100988100989100990100991100992100993100994100995100996100997100998100999101000101001101002101003101004101005101006101007101008101009101010101011101012101013101014101015101016101017101018101019101020101021101022101023101024101025101026101027101028101029101030101031101032101033101034101035101036101037101038101039101040101041101042101043101044101045101046101047101048101049101050101051101052101053101054101055101056101057101058101059101060101061101062101063101064101065101066101067101068101069101070101071101072101073101074101075101076101077101078101079101080101081101082101083101084101085101086101087101088101089101090101091101092101093101094101095101096101097101098101099101100101101101102101103101104101105101106101107101108101109101110101111101112101113101114101115101116101117101118101119101120101121101122101123101124101125101126101127101128101129101130101131101132101133101134101135101136101137101138101139101140101141101142101143101144101145101146101147101148101149101150101151101152101153101154101155101156101157101158101159101160101161101162101163101164101165101166101167101168101169101170101171101172101173101174101175101176101177101178101179101180101181101182101183101184101185101186101187101188101189101190101191101192101193101194101195101196101197101198101199101200101201101202101203101204101205101206101207101208101209101210101211101212101213101214101215101216101217101218101219101220101221101222101223101224101225101226101227101228101229101230101231101232101233101234101235101236101237101238101239101240101241101242101243101244101245101246101247101248101249101250101251101252101253101254101255101256101257101258101259101260101261101262101263101264101265101266101267101268101269101270101271101272101273101274101275101276101277101278101279101280101281101282101283101284101285101286101287101288101289101290101291101292101293101294101295101296101297101298101299101300101301101302101303101304101305101306101307101308101309101310101311101312101313101314101315101316101317101318101319101320101321101322101323101324101325101326101327101328101329101330101331101332101333101334101335101336101337101338101339101340101341101342101343101344101345101346101347101348101349101350101351101352101353101354101355101356101357101358101359101360101361101362101363101364101365101366101367101368101369101370101371101372101373101374101375101376101377101378101379101380101381101382101383101384101385101386101387101388101389101390101391101392101393101394101395101396101397101398101399101400101401101402101403101404101405101406101407101408101409101410101411101412101413101414101415101416101417101418101419101420101421101422101423101424101425101426101427101428101429101430101431101432101433101434101435101436101437101438101439101440101441101442101443101444101445101446101447101448101449101450101451101452101453101454101455101456101457101458101459101460101461101462101463101464101465101466101467101468101469101470101471101472101473101474101475101476101477101478101479101480101481101482101483101484101485101486101487101488101489101490101491101492101493101494101495101496101497101498101499101500101501101502101503101504101505101506101507101508101509101510101511101512101513101514101515101516101517101518101519101520101521101522101523101524101525101526101527101528101529101530101531101532101533101534101535101536101537101538101539101540101541101542101543101544101545101546101547101548101549101550101551101552101553101554101555101556101557101558101559101560101561101562101563101564101565101566101567101568101569101570101571101572101573101574101575101576101577101578101579101580101581101582101583101584101585101586101587101588101589101590101591101592101593101594101595101596101597101598101599101600101601101602101603101604101605101606101607101608101609101610101611101612101613101614101615101616101617101618101619101620101621101622101623101624101625101626101627101628101629101630101631101632101633101634101635101636101637101638101639101640101641101642101643101644101645101646101647101648101649101650101651101652101653101654101655101656101657101658101659101660101661101662101663101664101665101666101667101668101669101670101671101672101673101674101675101676101677101678101679101680101681101682101683101684101685101686101687101688101689101690101691101692101693101694101695101696101697101698101699101700101701101702101703101704101705101706101707101708101709101710101711101712101713101714101715101716101717101718101719101720101721101722101723101724101725101726101727101728101729101730101731101732101733101734101735101736101737101738101739101740101741101742101743101744101745101746101747101748101749101750101751101752101753101754101755101756101757101758101759101760101761101762101763101764101765101766101767101768101769101770101771101772101773101774101775101776101777101778101779101780101781101782101783101784101785101786101787101788101789101790101791101792101793101794101795101796101797101798101799101800101801101802101803101804101805101806101807101808101809101810101811101812101813101814101815101816101817101818101819101820101821101822101823101824101825101826101827101828101829101830101831101832101833101834101835101836101837101838101839101840101841101842101843101844101845101846101847101848101849101850101851101852101853101854101855101856101857101858101859101860101861101862101863101864101865101866101867101868101869101870101871101872101873101874101875101876101877101878101879101880101881101882101883101884101885101886101887101888101889101890101891101892101893101894101895101896101897101898101899101900101901101902101903101904101905101906101907101908101909101910101911101912101913101914101915101916101917101918101919101920101921101922101923101924101925101926101927101928101929101930101931101932101933101934101935101936101937101938101939101940101941101942101943101944101945101946101947101948101949101950101951101952101953101954101955101956101957101958101959101960101961101962101963101964101965101966101967101968101969101970101971101972101973101974101975101976101977101978101979101980101981101982101983101984101985101986101987101988101989101990101991101992101993101994101995101996101997101998101999102000102001102002102003102004102005102006102007102008102009102010102011102012102013102014102015102016102017102018102019102020102021102022102023102024102025102026102027102028102029102030102031102032102033102034102035102036102037102038102039102040102041102042102043102044102045102046102047102048102049102050102051102052102053102054102055102056102057102058102059102060102061102062102063102064102065102066102067102068102069102070102071102072102073102074102075102076102077102078102079102080102081102082102083102084102085102086102087102088102089102090102091102092102093102094102095102096102097102098102099102100102101102102102103102104102105102106102107102108102109102110102111102112102113102114102115102116102117102118102119102120102121102122102123102124102125102126102127102128102129102130102131102132102133102134102135102136102137102138102139102140102141102142102143102144102145102146102147102148102149102150102151102152102153102154102155102156102157102158102159102160102161102162102163102164102165102166102167102168102169102170102171102172102173102174102175102176102177102178102179102180102181102182102183102184102185102186102187102188102189102190102191102192102193102194102195102196102197102198102199102200102201102202102203102204102205102206102207102208102209102210102211102212102213102214102215102216102217102218102219102220102221102222102223102224102225102226102227102228102229102230102231102232102233102234102235102236102237102238102239102240102241102242102243102244102245102246102247102248102249102250102251102252102253102254102255102256102257102258102259102260102261102262102263102264102265102266102267102268102269102270102271102272102273102274102275102276102277102278102279102280102281102282102283102284102285102286102287102288102289102290102291102292102293102294102295102296102297102298102299102300102301102302102303102304102305102306102307102308102309102310102311102312102313102314102315102316102317102318102319102320102321102322102323102324102325102326102327102328102329102330102331102332102333102334102335102336102337102338102339102340102341102342102343102344102345102346102347102348102349102350102351102352102353102354102355102356102357102358102359102360102361102362102363102364102365102366102367102368102369102370102371102372102373102374102375102376102377102378102379102380102381102382102383102384102385102386102387102388102389102390102391102392102393102394102395102396102397102398102399102400102401102402102403102404102405102406102407102408102409102410102411102412102413102414102415102416102417102418102419102420102421102422102423102424102425102426102427102428102429102430102431102432102433102434102435102436102437102438102439102440102441102442102443102444102445102446102447102448102449102450102451102452102453102454102455102456102457102458102459102460102461102462102463102464102465102466102467102468102469102470102471102472102473102474102475102476102477102478102479102480102481102482102483102484102485102486102487102488102489102490102491102492102493102494102495102496102497102498102499102500102501102502102503102504102505102506102507102508102509102510102511102512102513102514102515102516102517102518102519102520102521102522102523102524102525102526102527102528102529102530102531102532102533102534102535102536102537102538102539102540102541102542102543102544102545102546102547102548102549102550102551102552102553102554102555102556102557102558102559102560102561102562102563102564102565102566102567102568102569102570102571102572102573102574102575102576102577102578102579102580102581102582102583102584102585102586102587102588102589102590102591102592102593102594102595102596102597102598102599102600102601102602102603102604102605102606102607102608102609102610102611102612102613102614102615102616102617102618102619102620102621102622102623102624102625102626102627102628102629102630102631102632102633102634102635102636102637102638102639102640102641102642102643102644102645102646102647102648102649102650102651102652102653102654102655102656102657102658102659102660102661102662102663102664102665102666102667102668102669102670102671102672102673102674102675102676102677102678102679102680102681102682102683102684102685102686102687102688102689102690102691102692102693102694102695102696102697102698102699102700102701102702102703102704102705102706102707102708102709102710102711102712102713102714102715102716102717102718102719102720102721102722102723102724102725102726102727102728102729102730102731102732102733102734102735102736102737102738102739102740102741102742102743102744102745102746102747102748102749102750102751102752102753102754102755102756102757102758102759102760102761102762102763102764102765102766102767102768102769102770102771102772102773102774102775102776102777102778102779102780102781102782102783102784102785102786102787102788102789102790102791102792102793102794102795102796102797102798102799102800102801102802102803102804102805102806102807102808102809102810102811102812102813102814102815102816102817102818102819102820102821102822102823102824102825102826102827102828102829102830102831102832102833102834102835102836102837102838102839102840102841102842102843102844102845102846102847102848102849102850102851102852102853102854102855102856102857102858102859102860102861102862102863102864102865102866102867102868102869102870102871102872102873102874102875102876102877102878102879102880102881102882102883102884102885102886102887102888102889102890102891102892102893102894102895102896102897102898102899102900102901102902102903102904102905102906102907102908102909102910102911102912102913102914102915102916102917102918102919102920102921102922102923102924102925102926102927102928102929102930102931102932102933102934102935102936102937102938102939102940102941102942102943102944102945102946102947102948102949102950102951102952102953102954102955102956102957102958102959102960102961102962102963102964102965102966102967102968102969102970102971102972102973102974102975102976102977102978102979102980102981102982102983102984102985102986102987102988102989102990102991102992102993102994102995102996102997102998102999103000103001103002103003103004103005103006103007103008103009103010103011103012103013103014103015103016103017103018103019103020103021103022103023103024103025103026103027103028103029103030103031103032103033103034103035103036103037103038103039103040103041103042103043103044103045103046103047103048103049103050103051103052103053103054103055103056103057103058103059103060103061103062103063103064103065103066103067103068103069103070103071103072103073103074103075103076103077103078103079103080103081103082103083103084103085103086103087103088103089103090103091103092103093103094103095103096103097103098103099103100103101103102103103103104103105103106103107103108103109103110103111103112103113103114103115103116103117103118103119103120103121103122103123103124103125103126103127103128103129103130103131103132103133103134103135103136103137103138103139103140103141103142103143103144103145103146103147103148103149103150103151103152103153103154103155103156103157103158103159103160103161103162103163103164103165103166103167103168103169103170103171103172103173103174103175103176103177103178103179103180103181103182103183103184103185103186103187103188103189103190103191103192103193103194103195103196103197103198103199103200103201103202103203103204103205103206103207103208103209103210103211103212103213103214103215103216103217103218103219103220103221103222103223103224103225103226103227103228103229103230103231103232103233103234103235103236103237103238103239103240103241103242103243103244103245103246103247103248103249103250103251103252103253103254103255103256103257103258103259103260103261103262103263103264103265103266103267103268103269103270103271103272103273103274103275103276103277103278103279103280103281103282103283103284103285103286103287103288103289103290103291103292103293103294103295103296103297103298103299103300103301103302103303103304103305103306103307103308103309103310103311103312103313103314103315103316103317103318103319103320103321103322103323103324103325103326103327103328103329103330103331103332103333103334103335103336103337103338103339103340103341103342103343103344103345103346103347103348103349103350103351103352103353103354103355103356103357103358103359103360103361103362103363103364103365103366103367103368103369103370103371103372103373103374103375103376103377103378103379103380103381103382103383103384103385103386103387103388103389103390103391103392103393103394103395103396103397103398103399103400103401103402103403103404103405103406103407103408103409103410103411103412103413103414103415103416103417103418103419103420103421103422103423103424103425103426103427103428103429103430103431103432103433103434103435103436103437103438103439103440103441103442103443103444103445103446103447103448103449103450103451103452103453103454103455103456103457103458103459103460103461103462103463103464103465103466103467103468103469103470103471103472103473103474103475103476103477103478103479103480103481103482103483103484103485103486103487103488103489103490103491103492103493103494103495103496103497103498103499103500103501103502103503103504103505103506103507103508103509103510103511103512103513103514103515103516103517103518103519103520103521103522103523103524103525103526103527103528103529103530103531103532103533103534103535103536103537103538103539103540103541103542103543103544103545103546103547103548103549103550103551103552103553103554103555103556103557103558103559103560103561103562103563103564103565103566103567103568103569103570103571103572103573103574103575103576103577103578103579103580103581103582103583103584103585103586103587103588103589103590103591103592103593103594103595103596103597103598103599103600103601103602103603103604103605103606103607103608103609103610103611103612103613103614103615103616103617103618103619103620103621103622103623103624103625103626103627103628103629103630103631103632103633103634103635103636103637103638103639103640103641103642103643103644103645103646103647103648103649103650103651103652103653103654103655103656103657103658103659103660103661103662103663103664103665103666103667103668103669103670103671103672103673103674103675103676103677103678103679103680103681103682103683103684103685103686103687103688103689103690103691103692103693103694103695103696103697103698103699103700103701103702103703103704103705103706103707103708103709103710103711103712103713103714103715103716103717103718103719103720103721103722103723103724103725103726103727103728103729103730103731103732103733103734103735103736103737103738103739103740103741103742103743103744103745103746103747103748103749103750103751103752103753103754103755103756103757103758103759103760103761103762103763103764103765103766103767103768103769103770103771103772103773103774103775103776103777103778103779103780103781103782103783103784103785103786103787103788103789103790103791103792103793103794103795103796103797103798103799103800103801103802103803103804103805103806103807103808103809103810103811103812103813103814103815103816103817103818103819103820103821103822103823103824103825103826103827103828103829103830103831103832103833103834103835103836103837103838103839103840103841103842103843103844103845103846103847103848103849103850103851103852103853103854103855103856103857103858103859103860103861103862103863103864103865103866103867103868103869103870103871103872103873103874103875103876103877103878103879103880103881103882103883103884103885103886103887103888103889103890103891103892103893103894103895103896103897103898103899103900103901103902103903103904103905103906103907103908103909103910103911103912103913103914103915103916103917103918103919103920103921103922103923103924103925103926103927103928103929103930103931103932103933103934103935103936103937103938103939103940103941103942103943103944103945103946103947103948103949103950103951103952103953103954103955103956103957103958103959103960103961103962103963103964103965103966103967103968103969103970103971103972103973103974103975103976103977103978103979103980103981103982103983103984103985103986103987103988103989103990103991103992103993103994103995103996103997103998103999104000104001104002104003104004104005104006104007104008104009104010104011104012104013104014104015104016104017104018104019104020104021104022104023104024104025104026104027104028104029104030104031104032104033104034104035104036104037104038104039104040104041104042104043104044104045104046104047104048104049104050104051104052104053104054104055104056104057104058104059104060104061104062104063104064104065104066104067104068104069104070104071104072104073104074104075104076104077104078104079104080104081104082104083104084104085104086104087104088104089104090104091104092104093104094104095104096104097104098104099104100104101104102104103104104104105104106104107104108104109104110104111104112104113104114104115104116104117104118104119104120104121104122104123104124104125104126104127104128104129104130104131104132104133104134104135104136104137104138104139104140104141104142104143104144104145104146104147104148104149104150104151104152104153104154104155104156104157104158104159104160104161104162104163104164104165104166104167104168104169104170104171104172104173104174104175104176104177104178104179104180104181104182104183104184104185104186104187104188104189104190104191104192104193104194104195104196104197104198104199104200104201104202104203104204104205104206104207104208104209104210104211104212104213104214104215104216104217104218104219104220104221104222104223104224104225104226104227104228104229104230104231104232104233104234104235104236104237104238104239104240104241104242104243104244104245104246104247104248104249104250104251104252104253104254104255104256104257104258104259104260104261104262104263104264104265104266104267104268104269104270104271104272104273104274104275104276104277104278104279104280104281104282104283104284104285104286104287104288104289104290104291104292104293104294104295104296104297104298104299104300104301104302104303104304104305104306104307104308104309104310104311104312104313104314104315104316104317104318104319104320104321104322104323104324104325104326104327104328104329104330104331104332104333104334104335104336104337104338104339104340104341104342104343104344104345104346104347104348104349104350104351104352104353104354104355104356104357104358104359104360104361104362104363104364104365104366104367104368104369104370104371104372104373104374104375104376104377104378104379104380104381104382104383104384104385104386104387104388104389104390104391104392104393104394104395104396104397104398104399104400104401104402104403104404104405104406104407104408104409104410104411104412104413104414104415104416104417104418104419104420104421104422104423104424104425104426104427104428104429104430104431104432104433104434104435104436104437104438104439104440104441104442104443104444104445104446104447104448104449104450104451104452104453104454104455104456104457104458104459104460104461104462104463104464104465104466104467104468104469104470104471104472104473104474104475104476104477104478104479104480104481104482104483104484104485104486104487104488104489104490104491104492104493104494104495104496104497104498104499104500104501104502104503104504104505104506104507104508104509104510104511104512104513104514104515104516104517104518104519104520104521104522104523104524104525104526104527104528104529104530104531104532104533104534104535104536104537104538104539104540104541104542104543104544104545104546104547104548104549104550104551104552104553104554104555104556104557104558104559104560104561104562104563104564104565104566104567104568104569104570104571104572104573104574104575104576104577104578104579104580104581104582104583104584104585104586104587104588104589104590104591104592104593104594104595104596104597104598104599104600104601104602104603104604104605104606104607104608104609104610104611104612104613104614104615104616104617104618104619104620104621104622104623104624104625104626104627104628104629104630104631104632104633104634104635104636104637104638104639104640104641104642104643104644104645104646104647104648104649104650104651104652104653104654104655104656104657104658104659104660104661104662104663104664104665104666104667104668104669104670104671104672104673104674104675104676104677104678104679104680104681104682104683104684104685104686104687104688104689104690104691104692104693104694104695104696104697104698104699104700104701104702104703104704104705104706104707104708104709104710104711104712104713104714104715104716104717104718104719104720104721104722104723104724104725104726104727104728104729104730104731104732104733104734104735104736104737104738104739104740104741104742104743104744104745104746104747104748104749104750104751104752104753104754104755104756104757104758104759104760104761104762104763104764104765104766104767104768104769104770104771104772104773104774104775104776104777104778104779104780104781104782104783104784104785104786104787104788104789104790104791104792104793104794104795104796104797104798104799104800104801104802104803104804104805104806104807104808104809104810104811104812104813104814104815104816104817104818104819104820104821104822104823104824104825104826104827104828104829104830104831104832104833104834104835104836104837104838104839104840104841104842104843104844104845104846104847104848104849104850104851104852104853104854104855104856104857104858104859104860104861104862104863104864104865104866104867104868104869104870104871104872104873104874104875104876104877104878104879104880104881104882104883104884104885104886104887104888104889104890104891104892104893104894104895104896104897104898104899104900104901104902104903104904104905104906104907104908104909104910104911104912104913104914104915104916104917104918104919104920104921104922104923104924104925104926104927104928104929104930104931104932104933104934104935104936104937104938104939104940104941104942104943104944104945104946104947104948104949104950104951104952104953104954104955104956104957104958104959104960104961104962104963104964104965104966104967104968104969104970104971104972104973104974104975104976104977104978104979104980104981104982104983104984104985104986104987104988104989104990104991104992104993104994104995104996104997104998104999105000105001105002105003105004105005105006105007105008105009105010105011105012105013105014105015105016105017105018105019105020105021105022105023105024105025105026105027105028105029105030105031105032105033105034105035105036105037105038105039105040105041105042105043105044105045105046105047105048105049105050105051105052105053105054105055105056105057105058105059105060105061105062105063105064105065105066105067105068105069105070105071105072105073105074105075105076105077105078105079105080105081105082105083105084105085105086105087105088105089105090105091105092105093105094105095105096105097105098105099105100105101105102105103105104105105105106105107105108105109105110105111105112105113105114105115105116105117105118105119105120105121105122105123105124105125105126105127105128105129105130105131105132105133105134105135105136105137105138105139105140105141105142105143105144105145105146105147105148105149105150105151105152105153105154105155105156105157105158105159105160105161105162105163105164105165105166105167105168105169105170105171105172105173105174105175105176105177105178105179105180105181105182105183105184105185105186105187105188105189105190105191105192105193105194105195105196105197105198105199105200105201105202105203105204105205105206105207105208105209105210105211105212105213105214105215105216105217105218105219105220105221105222105223105224105225105226105227105228105229105230105231105232105233105234105235105236105237105238105239105240105241105242105243105244105245105246105247105248105249105250105251105252105253105254105255105256105257105258105259105260105261105262105263105264105265105266105267105268105269105270105271105272105273105274105275105276105277105278105279105280105281105282105283105284105285105286105287105288105289105290105291105292105293105294105295105296105297105298105299105300105301105302105303105304105305105306105307105308105309105310105311105312105313105314105315105316105317105318105319105320105321105322105323105324105325105326105327105328105329105330105331105332105333105334105335105336105337105338105339105340105341105342105343105344105345105346105347105348105349105350105351105352105353105354105355105356105357105358105359105360105361105362105363105364105365105366105367105368105369105370105371105372105373105374105375105376105377105378105379105380105381105382105383105384105385105386105387105388105389105390105391105392105393105394105395105396105397105398105399105400105401105402105403105404105405105406105407105408105409105410105411105412105413105414105415105416105417105418105419105420105421105422105423105424105425105426105427105428105429105430105431105432105433105434105435105436105437105438105439105440105441105442105443105444105445105446105447105448105449105450105451105452105453105454105455105456105457105458105459105460105461105462105463105464105465105466105467105468105469105470105471105472105473105474105475105476105477105478105479105480105481105482105483105484105485105486105487105488105489105490105491105492105493105494105495105496105497105498105499105500105501105502105503105504105505105506105507105508105509105510105511105512105513105514105515105516105517105518105519105520105521105522105523105524105525105526105527105528105529105530105531105532105533105534105535105536105537105538105539105540105541105542105543105544105545105546105547105548105549105550105551105552105553105554105555105556105557105558105559105560105561105562105563105564105565105566105567105568105569105570105571105572105573105574105575105576105577105578105579105580105581105582105583105584105585105586105587105588105589105590105591105592105593105594105595105596105597105598105599105600105601105602105603105604105605105606105607105608105609105610105611105612105613105614105615105616105617105618105619105620105621105622105623105624105625105626105627105628105629105630105631105632105633105634105635105636105637105638105639105640105641105642105643105644105645105646105647105648105649105650105651105652105653105654105655105656105657105658105659105660105661105662105663105664105665105666105667105668105669105670105671105672105673105674105675105676105677105678105679105680105681105682105683105684105685105686105687105688105689105690105691105692105693105694105695105696105697105698105699105700105701105702105703105704105705105706105707105708105709105710105711105712105713105714105715105716105717105718105719105720105721105722105723105724105725105726105727105728105729105730105731105732105733105734105735105736105737105738105739105740105741105742105743105744105745105746105747105748105749105750105751105752105753105754105755105756105757105758105759105760105761105762105763105764105765105766105767105768105769105770105771105772105773105774105775105776105777105778105779105780105781105782105783105784105785105786105787105788105789105790105791105792105793105794105795105796105797105798105799105800105801105802105803105804105805105806105807105808105809105810105811105812105813105814105815105816105817105818105819105820105821105822105823105824105825105826105827105828105829105830105831105832105833105834105835105836105837105838105839105840105841105842105843105844105845105846105847105848105849105850105851105852105853105854105855105856105857105858105859105860105861105862105863105864105865105866105867105868105869105870105871105872105873105874105875105876105877105878105879105880105881105882105883105884105885105886105887105888105889105890105891105892105893105894105895105896105897105898105899105900105901105902105903105904105905105906105907105908105909105910105911105912105913105914105915105916105917105918105919105920105921105922105923105924105925105926105927105928105929105930105931105932105933105934105935105936105937105938105939105940105941105942105943105944105945105946105947105948105949105950105951105952105953105954105955105956105957105958105959105960105961105962105963105964105965105966105967105968105969105970105971105972105973105974105975105976105977105978105979105980105981105982105983105984105985105986105987105988105989105990105991105992105993105994105995105996105997105998105999106000106001106002106003106004106005106006106007106008106009106010106011106012106013106014106015106016106017106018106019106020106021106022106023106024106025106026106027106028106029106030106031106032106033106034106035106036106037106038106039106040106041106042106043106044106045106046106047106048106049106050106051106052106053106054106055106056106057106058106059106060106061106062106063106064106065106066106067106068106069106070106071106072106073106074106075106076106077106078106079106080106081106082106083106084106085106086106087106088106089106090106091106092106093106094106095106096106097106098106099106100106101106102106103106104106105106106106107106108106109106110106111106112106113106114106115106116106117106118106119106120106121106122106123106124106125106126106127106128106129106130106131106132106133106134106135106136106137106138106139106140106141106142106143106144106145106146106147106148106149106150106151106152106153106154106155106156106157106158106159106160106161106162106163106164106165106166106167106168106169106170106171106172106173106174106175106176106177106178106179106180106181106182106183106184106185106186106187106188106189106190106191106192106193106194106195106196106197106198106199106200106201106202106203106204106205106206106207106208106209106210106211106212106213106214106215106216106217106218106219106220106221106222106223106224106225106226106227106228106229106230106231106232106233106234106235106236106237106238106239106240106241106242106243106244106245106246106247106248106249106250106251106252106253106254106255106256106257106258106259106260106261106262106263106264106265106266106267106268106269106270106271106272106273106274106275106276106277106278106279106280106281106282106283106284106285106286106287106288106289106290106291106292106293106294106295106296106297106298106299106300106301106302106303106304106305106306106307106308106309106310106311106312106313106314106315106316106317106318106319106320106321106322106323106324106325106326106327106328106329106330106331106332106333106334106335106336106337106338106339106340106341106342106343106344106345106346106347106348106349106350106351106352106353106354106355106356106357106358106359106360106361106362106363106364106365106366106367106368106369106370106371106372106373106374106375106376106377106378106379106380106381106382106383106384106385106386106387106388106389106390106391106392106393106394106395106396106397106398106399106400106401106402106403106404106405106406106407106408106409106410106411106412106413106414106415106416106417106418106419106420106421106422106423106424106425106426106427106428106429106430106431106432106433106434106435106436106437106438106439106440106441106442106443106444106445106446106447106448106449106450106451106452106453106454106455106456106457106458106459106460106461106462106463106464106465106466106467106468106469106470106471106472106473106474106475106476106477106478106479106480106481106482106483106484106485106486106487106488106489106490106491106492106493106494106495106496106497106498106499106500106501106502106503106504106505106506106507106508106509106510106511106512106513106514106515106516106517106518106519106520106521106522106523106524106525106526106527106528106529106530106531106532106533106534106535106536106537106538106539106540106541106542106543106544106545106546106547106548106549106550106551106552106553106554106555106556106557106558106559106560106561106562106563106564106565106566106567106568106569106570106571106572106573106574106575106576106577106578106579106580106581106582106583106584106585106586106587106588106589106590106591106592106593106594106595106596106597106598106599106600106601106602106603106604106605106606106607106608106609106610106611106612106613106614106615106616106617106618106619106620106621106622106623106624106625106626106627106628106629106630106631106632106633106634106635106636106637106638106639106640106641106642106643106644106645106646106647106648106649106650106651106652106653106654106655106656106657106658106659106660106661106662106663106664106665106666106667106668106669106670106671106672106673106674106675106676106677106678106679106680106681106682106683106684106685106686106687106688106689106690106691106692106693106694106695106696106697106698106699106700106701106702106703106704106705106706106707106708106709106710106711106712106713106714106715106716106717106718106719106720106721106722106723106724106725106726106727106728106729106730106731106732106733106734106735106736106737106738106739106740106741106742106743106744106745106746106747106748106749106750106751106752106753106754106755106756106757106758106759106760106761106762106763106764106765106766106767106768106769106770106771106772106773106774106775106776106777106778106779106780106781106782106783106784106785106786106787106788106789106790106791106792106793106794106795106796106797106798106799106800106801106802106803106804106805106806106807106808106809106810106811106812106813106814106815106816106817106818106819106820106821106822106823106824106825106826106827106828106829106830106831106832106833106834106835106836106837106838106839106840106841106842106843106844106845106846106847106848106849106850106851106852106853106854106855106856106857106858106859106860106861106862106863106864106865106866106867106868106869106870106871106872106873106874106875106876106877106878106879106880106881106882106883106884106885106886106887106888106889106890106891106892106893106894106895106896106897106898106899106900106901106902106903106904106905106906106907106908106909106910106911106912106913106914106915106916106917106918106919106920106921106922106923106924106925106926106927106928106929106930106931106932106933106934106935106936106937106938106939106940106941106942106943106944106945106946106947106948106949106950106951106952106953106954106955106956106957106958106959106960106961106962106963106964106965106966106967106968106969106970106971106972106973106974106975106976106977106978106979106980106981106982106983106984106985106986106987106988106989106990106991106992106993106994106995106996106997106998106999107000107001107002107003107004107005107006107007107008107009107010107011107012107013107014107015107016107017107018107019107020107021107022107023107024107025107026107027107028107029107030107031107032107033107034107035107036107037107038107039107040107041107042107043107044107045107046107047107048107049107050107051107052107053107054107055107056107057107058107059107060107061107062107063107064107065107066107067107068107069107070107071107072107073107074107075107076107077107078107079107080107081107082107083107084107085107086107087107088107089107090107091107092107093107094107095107096107097107098107099107100107101107102107103107104107105107106107107107108107109107110107111107112107113107114107115107116107117107118107119107120107121107122107123107124107125107126107127107128107129107130107131107132107133107134107135107136107137107138107139107140107141107142107143107144107145107146107147107148107149107150107151107152107153107154107155107156107157107158107159107160107161107162107163107164107165107166107167107168107169107170107171107172107173107174107175107176107177107178107179107180107181107182107183107184107185107186107187107188107189107190107191107192107193107194107195107196107197107198107199107200107201107202107203107204107205107206107207107208107209107210107211107212107213107214107215107216107217107218107219107220107221107222107223107224107225107226107227107228107229107230107231107232107233107234107235107236107237107238107239107240107241107242107243107244107245107246107247107248107249107250107251107252107253107254107255107256107257107258107259107260107261107262107263107264107265107266107267107268107269107270107271107272107273107274107275107276107277107278107279107280107281107282107283107284107285107286107287107288107289107290107291107292107293107294107295107296107297107298107299107300107301107302107303107304107305107306107307107308107309107310107311107312107313107314107315107316107317107318107319107320107321107322107323107324107325107326107327107328107329107330107331107332107333107334107335107336107337107338107339107340107341107342107343107344107345107346107347107348107349107350107351107352107353107354107355107356107357107358107359107360107361107362107363107364107365107366107367107368107369107370107371107372107373107374107375107376107377107378107379107380107381107382107383107384107385107386107387107388107389107390107391107392107393107394107395107396107397107398107399107400107401107402107403107404107405107406107407107408107409107410107411107412107413107414107415107416107417107418107419107420107421107422107423107424107425107426107427107428107429107430107431107432107433107434107435107436107437107438107439107440107441107442107443107444107445107446107447107448107449107450107451107452107453107454107455107456107457107458107459107460107461107462107463107464107465107466107467107468107469107470107471107472107473107474107475107476107477107478107479107480107481107482107483107484107485107486107487107488107489107490107491107492107493107494107495107496107497107498107499107500107501107502107503107504107505107506107507107508107509107510107511107512107513107514107515107516107517107518107519107520107521107522107523107524107525107526107527107528107529107530107531107532107533107534107535107536107537107538107539107540107541107542107543107544107545107546107547107548107549107550107551107552107553107554107555107556107557107558107559107560107561107562107563107564107565107566107567107568107569107570107571107572107573107574107575107576107577107578107579107580107581107582107583107584107585107586107587107588107589107590107591107592107593107594107595107596107597107598107599107600107601107602107603107604107605107606107607107608107609107610107611107612107613107614107615107616107617107618107619107620107621107622107623107624107625107626107627107628107629107630107631107632107633107634107635107636107637107638107639107640107641107642107643107644107645107646107647107648107649107650107651107652107653107654107655107656107657107658107659107660107661107662107663107664107665107666107667107668107669107670107671107672107673107674107675107676107677107678107679107680107681107682107683107684107685107686107687107688107689107690107691107692107693107694107695107696107697107698107699107700107701107702107703107704107705107706107707107708107709107710107711107712107713107714107715107716107717107718107719107720107721107722107723107724107725107726107727107728107729107730107731107732107733107734107735107736107737107738107739107740107741107742107743107744107745107746107747107748107749107750107751107752107753107754107755107756107757107758107759107760107761107762107763107764107765107766107767107768107769107770107771107772107773107774107775107776107777107778107779107780107781107782107783107784107785107786107787107788107789107790107791107792107793107794107795107796107797107798107799107800107801107802107803107804107805107806107807107808107809107810107811107812107813107814107815107816107817107818107819107820107821107822107823107824107825107826107827107828107829107830107831107832107833107834107835107836107837107838107839107840107841107842107843107844107845107846107847107848107849107850107851107852107853107854107855107856107857107858107859107860107861107862107863107864107865107866107867107868107869107870107871107872107873107874107875107876107877107878107879107880107881107882107883107884107885107886107887107888107889107890107891107892107893107894107895107896107897107898107899107900107901107902107903107904107905107906107907107908107909107910107911107912107913107914107915107916107917107918107919107920107921107922107923107924107925107926107927107928107929107930107931107932107933107934107935107936107937107938107939107940107941107942107943107944107945107946107947107948107949107950107951107952107953107954107955107956107957107958107959107960107961107962107963107964107965107966107967107968107969107970107971107972107973107974107975107976107977107978107979107980107981107982107983107984107985107986107987107988107989107990107991107992107993107994107995107996107997107998107999108000108001108002108003108004108005108006108007108008108009108010108011108012108013108014108015108016108017108018108019108020108021108022108023108024108025108026108027108028108029108030108031108032108033108034108035108036108037108038108039108040108041108042108043108044108045108046108047108048108049108050108051108052108053108054108055108056108057108058108059108060108061108062108063108064108065108066108067108068108069108070108071108072108073108074108075108076108077108078108079108080108081108082108083108084108085108086108087108088108089108090108091108092108093108094108095108096108097108098108099108100108101108102108103108104108105108106108107108108108109108110108111108112108113108114108115108116108117108118108119108120108121108122108123108124108125108126108127108128108129108130108131108132108133108134108135108136108137108138108139108140108141108142108143108144108145108146108147108148108149108150108151108152108153108154108155108156108157108158108159108160108161108162108163108164108165108166108167108168108169108170108171108172108173108174108175108176108177108178108179108180108181108182108183108184108185108186108187108188108189108190108191108192108193108194108195108196108197108198108199108200108201108202108203108204108205108206108207108208108209108210108211108212108213108214108215108216108217108218108219108220108221108222108223108224108225108226108227108228108229108230108231108232108233108234108235108236108237108238108239108240108241108242108243108244108245108246108247108248108249108250108251108252108253108254108255108256108257108258108259108260108261108262108263108264108265108266108267108268108269108270108271108272108273108274108275108276108277108278108279108280108281108282108283108284108285108286108287108288108289108290108291108292108293108294108295108296108297108298108299108300108301108302108303108304108305108306108307108308108309108310108311108312108313108314108315108316108317108318108319108320108321108322108323108324108325108326108327108328108329108330108331108332108333108334108335108336108337108338108339108340108341108342108343108344108345108346108347108348108349108350108351108352108353108354108355108356108357108358108359108360108361108362108363108364108365108366108367108368108369108370108371108372108373108374108375108376108377108378108379108380108381108382108383108384108385108386108387108388108389108390108391108392108393108394108395108396108397108398108399108400108401108402108403108404108405108406108407108408108409108410108411108412108413108414108415108416108417108418108419108420108421108422108423108424108425108426108427108428108429108430108431108432108433108434108435108436108437108438108439108440108441108442108443108444108445108446108447108448108449108450108451108452108453108454108455108456108457108458108459108460108461108462108463108464108465108466108467108468108469108470108471108472108473108474108475108476108477108478108479108480108481108482108483108484108485108486108487108488108489108490108491108492108493108494108495108496108497108498108499108500108501108502108503108504108505108506108507108508108509108510108511108512108513108514108515108516108517108518108519108520108521108522108523108524108525108526108527108528108529108530108531108532108533108534108535108536108537108538108539108540108541108542108543108544108545108546108547108548108549108550108551108552108553108554108555108556108557108558108559108560108561108562108563108564108565108566108567108568108569108570108571108572108573108574108575108576108577108578108579108580108581108582108583108584108585108586108587108588108589108590108591108592108593108594108595108596108597108598108599108600108601108602108603108604108605108606108607108608108609108610108611108612108613108614108615108616108617108618108619108620108621108622108623108624108625108626108627108628108629108630108631108632108633108634108635108636108637108638108639108640108641108642108643108644108645108646108647108648108649108650108651108652108653108654108655108656108657108658108659108660108661108662108663108664108665108666108667108668108669108670108671108672108673108674108675108676108677108678108679108680108681108682108683108684108685108686108687108688108689108690108691108692108693108694108695108696108697108698108699108700108701108702108703108704108705108706108707108708108709108710108711108712108713108714108715108716108717108718108719108720108721108722108723108724108725108726108727108728108729108730108731108732108733108734108735108736108737108738108739108740108741108742108743108744108745108746108747108748108749108750108751108752108753108754108755108756108757108758108759108760108761108762108763108764108765108766108767108768108769108770108771108772108773108774108775108776108777108778108779108780108781108782108783108784108785108786108787108788108789108790108791108792108793108794108795108796108797108798108799108800108801108802108803108804108805108806108807108808108809108810108811108812108813108814108815108816108817108818108819108820108821108822108823108824108825108826108827108828108829108830108831108832108833108834108835108836108837108838108839108840108841108842108843108844108845108846108847108848108849108850108851108852108853108854108855108856108857108858108859108860108861108862108863108864108865108866108867108868108869108870108871108872108873108874108875108876108877108878108879108880108881108882108883108884108885108886108887108888108889108890108891108892108893108894108895108896108897108898108899108900108901108902108903108904108905108906108907108908108909108910108911108912108913108914108915108916108917108918108919108920108921108922108923108924108925108926108927108928108929108930108931108932108933108934108935108936108937108938108939108940108941108942108943108944108945108946108947108948108949108950108951108952108953108954108955108956108957108958108959108960108961108962108963108964108965108966108967108968108969108970108971108972108973108974108975108976108977108978108979108980108981108982108983108984108985108986108987108988108989108990108991108992108993108994108995108996108997108998108999109000109001109002109003109004109005109006109007109008109009109010109011109012109013109014109015109016109017109018109019109020109021109022109023109024109025109026109027109028109029109030109031109032109033109034109035109036109037109038109039109040109041109042109043109044109045109046109047109048109049109050109051109052109053109054109055109056109057109058109059109060109061109062109063109064109065109066109067109068109069109070109071109072109073109074109075109076109077109078109079109080109081109082109083109084109085109086109087109088109089109090109091109092109093109094109095109096109097109098109099109100109101109102109103109104109105109106109107109108109109109110109111109112109113109114109115109116109117109118109119109120109121109122109123109124109125109126109127109128109129109130109131109132109133109134109135109136109137109138109139109140109141109142109143109144109145109146109147109148109149109150109151109152109153109154109155109156109157109158109159109160109161109162109163109164109165109166109167109168109169109170109171109172109173109174109175109176109177109178109179109180109181109182109183109184109185109186109187109188109189109190109191109192109193109194109195109196109197109198109199109200109201109202109203109204109205109206109207109208109209109210109211109212109213109214109215109216109217109218109219109220109221109222109223109224109225109226109227109228109229109230109231109232109233109234109235109236109237109238109239109240109241109242109243109244109245109246109247109248109249109250109251109252109253109254109255109256109257109258109259109260109261109262109263109264109265109266109267109268109269109270109271109272109273109274109275109276109277109278109279109280109281109282109283109284109285109286109287109288109289109290109291109292109293109294109295109296109297109298109299109300109301109302109303109304109305109306109307109308109309109310109311109312109313109314109315109316109317109318109319109320109321109322109323109324109325109326109327109328109329109330109331109332109333109334109335109336109337109338109339109340109341109342109343109344109345109346109347109348109349109350109351109352109353109354109355109356109357109358109359109360109361109362109363109364109365109366109367109368109369109370109371109372109373109374109375109376109377109378109379109380109381109382109383109384109385109386109387109388109389109390109391109392109393109394109395109396109397109398109399109400109401109402109403109404109405109406109407109408109409109410109411109412109413109414109415109416109417109418109419109420109421109422109423109424109425109426109427109428109429109430109431109432109433109434109435109436109437109438109439109440109441109442109443109444109445109446109447109448109449109450109451109452109453109454109455109456109457109458109459109460109461109462109463109464109465109466109467109468109469109470109471109472109473109474109475109476109477109478109479109480109481109482109483109484109485109486109487109488109489109490109491109492109493109494109495109496109497109498109499109500109501109502109503109504109505109506109507109508109509109510109511109512109513109514109515109516109517109518109519109520109521109522109523109524109525109526109527109528109529109530109531109532109533109534109535109536109537109538109539109540109541109542109543109544109545109546109547109548109549109550109551109552109553109554109555109556109557109558109559109560109561109562109563109564109565109566109567109568109569109570109571109572109573109574109575109576109577109578109579109580109581109582109583109584109585109586109587109588109589109590109591109592109593109594109595109596109597109598109599109600109601109602109603109604109605109606109607109608109609109610109611109612109613109614109615109616109617109618109619109620109621109622109623109624109625109626109627109628109629109630109631109632109633109634109635109636109637109638109639109640109641109642109643109644109645109646109647109648109649109650109651109652109653109654109655109656109657109658109659109660109661109662109663109664109665109666109667109668109669109670109671109672109673109674109675109676109677109678109679109680109681109682109683109684109685109686109687109688109689109690109691109692109693109694109695109696109697109698109699109700109701109702109703109704109705109706109707109708109709109710109711109712109713109714109715109716109717109718109719109720109721109722109723109724109725109726109727109728109729109730109731109732109733109734109735109736109737109738109739109740109741109742109743109744109745109746109747109748109749109750109751109752109753109754109755109756109757109758109759109760109761109762109763109764109765109766109767109768109769109770109771109772109773109774109775109776109777109778109779109780109781109782109783109784109785109786109787109788109789109790109791109792109793109794109795109796109797109798109799109800109801109802109803109804109805109806109807109808109809109810109811109812109813109814109815109816109817109818109819109820109821109822109823109824109825109826109827109828109829109830109831109832109833109834109835109836109837109838109839109840109841109842109843109844109845109846109847109848109849109850109851109852109853109854109855109856109857109858109859109860109861109862109863109864109865109866109867109868109869109870109871109872109873109874109875109876109877109878109879109880109881109882109883109884109885109886109887109888109889109890109891109892109893109894109895109896109897109898109899109900109901109902109903109904109905109906109907109908109909109910109911109912109913109914109915109916109917109918109919109920109921109922109923109924109925109926109927109928109929109930109931109932109933109934109935109936109937109938109939109940109941109942109943109944109945109946109947109948109949109950109951109952109953109954109955109956109957109958109959109960109961109962109963109964109965109966109967109968109969109970109971109972109973109974109975109976109977109978109979109980109981109982109983109984109985109986109987109988109989109990109991109992109993109994109995109996109997109998109999110000110001110002110003110004110005110006110007110008110009110010110011110012110013110014110015110016110017110018110019110020110021110022110023110024110025110026110027110028110029110030110031110032110033110034110035110036110037110038110039110040110041110042110043110044110045110046110047110048110049110050110051110052110053110054110055110056110057110058110059110060110061110062110063110064110065110066110067110068110069110070110071110072110073110074110075110076110077110078110079110080110081110082110083110084110085110086110087110088110089110090110091110092110093110094110095110096110097110098110099110100110101110102110103110104110105110106110107110108110109110110110111110112110113110114110115110116110117110118110119110120110121110122110123110124110125110126110127110128110129110130110131110132110133110134110135110136110137110138110139110140110141110142110143110144110145110146110147110148110149110150110151110152110153110154110155110156110157110158110159110160110161110162110163110164110165110166110167110168110169110170110171110172110173110174110175110176110177110178110179110180110181110182110183110184110185110186110187110188110189110190110191110192110193110194110195110196110197110198110199110200110201110202110203110204110205110206110207110208110209110210110211110212110213110214110215110216110217110218110219110220110221110222110223110224110225110226110227110228110229110230110231110232110233110234110235110236110237110238110239110240110241110242110243110244110245110246110247110248110249110250110251110252110253110254110255110256110257110258110259110260110261110262110263110264110265110266110267110268110269110270110271110272110273110274110275110276110277110278110279110280110281110282110283110284110285110286110287110288110289110290110291110292110293110294110295110296110297110298110299110300110301110302110303110304110305110306110307110308110309110310110311110312110313110314110315110316110317110318110319110320110321110322110323110324110325110326110327110328110329110330110331110332110333110334110335110336110337110338110339110340110341110342110343110344110345110346110347110348110349110350110351110352110353110354110355110356110357110358110359110360110361110362110363110364110365110366110367110368110369110370110371110372110373110374110375110376110377110378110379110380110381110382110383110384110385110386110387110388110389110390110391110392110393110394110395110396110397110398110399110400110401110402110403110404110405110406110407110408110409110410110411110412110413110414110415110416110417110418110419110420110421110422110423110424110425110426110427110428110429110430110431110432110433110434110435110436110437110438110439110440110441110442110443110444110445110446110447110448110449110450110451110452110453110454110455110456110457110458110459110460110461110462110463110464110465110466110467110468110469110470110471110472110473110474110475110476110477110478110479110480110481110482110483110484110485110486110487110488110489110490110491110492110493110494110495110496110497110498110499110500110501110502110503110504110505110506110507110508110509110510110511110512110513110514110515110516110517110518110519110520110521110522110523110524110525110526110527110528110529110530110531110532110533110534110535110536110537110538110539110540110541110542110543110544110545110546110547110548110549110550110551110552110553110554110555110556110557110558110559110560110561110562110563110564110565110566110567110568110569110570110571110572110573110574110575110576110577110578110579110580110581110582110583110584110585110586110587110588110589110590110591110592110593110594110595110596110597110598110599110600110601110602110603110604110605110606110607110608110609110610110611110612110613110614110615110616110617110618110619110620110621110622110623110624110625110626110627110628110629110630110631110632110633110634110635110636110637110638110639110640110641110642110643110644110645110646110647110648110649110650110651110652110653110654110655110656110657110658110659110660110661110662110663110664110665110666110667110668110669110670110671110672110673110674110675110676110677110678110679110680110681110682110683110684110685110686110687110688110689110690110691110692110693110694110695110696110697110698110699110700110701110702110703110704110705110706110707110708110709110710110711110712110713110714110715110716110717110718110719110720110721110722110723110724110725110726110727110728110729110730110731110732110733110734110735110736110737110738110739110740110741110742110743110744110745110746110747110748110749110750110751110752110753110754110755110756110757110758110759110760110761110762110763110764110765110766110767110768110769110770110771110772110773110774110775110776110777110778110779110780110781110782110783110784110785110786110787110788110789110790110791110792110793110794110795110796110797110798110799110800110801110802110803110804110805110806110807110808110809110810110811110812110813110814110815110816110817110818110819110820110821110822110823110824110825110826110827110828110829110830110831110832110833110834110835110836110837110838110839110840110841110842110843110844110845110846110847110848110849110850110851110852110853110854110855110856110857110858110859110860110861110862110863110864110865110866110867110868110869110870110871110872110873110874110875110876110877110878110879110880110881110882110883110884110885110886110887110888110889110890110891110892110893110894110895110896110897110898110899110900110901110902110903110904110905110906110907110908110909110910110911110912110913110914110915110916110917110918110919110920110921110922110923110924110925110926110927110928110929110930110931110932110933110934110935110936110937110938110939110940110941110942110943110944110945110946110947110948110949110950110951110952110953110954110955110956110957110958110959110960110961110962110963110964110965110966110967110968110969110970110971110972110973110974110975110976110977110978110979110980110981110982110983110984110985110986110987110988110989110990110991110992110993110994110995110996110997110998110999111000111001111002111003111004111005111006111007111008111009111010111011111012111013111014111015111016111017111018111019111020111021111022111023111024111025111026111027111028111029111030111031111032111033111034111035111036111037111038111039111040111041111042111043111044111045111046111047111048111049111050111051111052111053111054111055111056111057111058111059111060111061111062111063111064111065111066111067111068111069111070111071111072111073111074111075111076111077111078111079111080111081111082111083111084111085111086111087111088111089111090111091111092111093111094111095111096111097111098111099111100111101111102111103111104111105111106111107111108111109111110111111111112111113111114111115111116111117111118111119111120111121111122111123111124111125111126111127111128111129111130111131111132111133111134111135111136111137111138111139111140111141111142111143111144111145111146111147111148111149111150111151111152111153111154111155111156111157111158111159111160111161111162111163111164111165111166111167111168111169111170111171111172111173111174111175111176111177111178111179111180111181111182111183111184111185111186111187111188111189111190111191111192111193111194111195111196111197111198111199111200111201111202111203111204111205111206111207111208111209111210111211111212111213111214111215111216111217111218111219111220111221111222111223111224111225111226111227111228111229111230111231111232111233111234111235111236111237111238111239111240111241111242111243111244111245111246111247111248111249111250111251111252111253111254111255111256111257111258111259111260111261111262111263111264111265111266111267111268111269111270111271111272111273111274111275111276111277111278111279111280111281111282111283111284111285111286111287111288111289111290111291111292111293111294111295111296111297111298111299111300111301111302111303111304111305111306111307111308111309111310111311111312111313111314111315111316111317111318111319111320111321111322111323111324111325111326111327111328111329111330111331111332111333111334111335111336111337111338111339111340111341111342111343111344111345111346111347111348111349111350111351111352111353111354111355111356111357111358111359111360111361111362111363111364111365111366111367111368111369111370111371111372111373111374111375111376111377111378111379111380111381111382111383111384111385111386111387111388111389111390111391111392111393111394111395111396111397111398111399111400111401111402111403111404111405111406111407111408111409111410111411111412111413111414111415111416111417111418111419111420111421111422111423111424111425111426111427111428111429111430111431111432111433111434111435111436111437111438111439111440111441111442111443111444111445111446111447111448111449111450111451111452111453111454111455111456111457111458111459111460111461111462111463111464111465111466111467111468111469111470111471111472111473111474111475111476111477111478111479111480111481111482111483111484111485111486111487111488111489111490111491111492111493111494111495111496111497111498111499111500111501111502111503111504111505111506111507111508111509111510111511111512111513111514111515111516111517111518111519111520111521111522111523111524111525111526111527111528111529111530111531111532111533111534111535111536111537111538111539111540111541111542111543111544111545111546111547111548111549111550111551111552111553111554111555111556111557111558111559111560111561111562111563111564111565111566111567111568111569111570111571111572111573111574111575111576111577111578111579111580111581111582111583111584111585111586111587111588111589111590111591111592111593111594111595111596111597111598111599111600111601111602111603111604111605111606111607111608111609111610111611111612111613111614111615111616111617111618111619111620111621111622111623111624111625111626111627111628111629111630111631111632111633111634111635111636111637111638111639111640111641111642111643111644111645111646111647111648111649111650111651111652111653111654111655111656111657111658111659111660111661111662111663111664111665111666111667111668111669111670111671111672111673111674111675111676111677111678111679111680111681111682111683111684111685111686111687111688111689111690111691111692111693111694111695111696111697111698111699111700111701111702111703111704111705111706111707111708111709111710111711111712111713111714111715111716111717111718111719111720111721111722111723111724111725111726111727111728111729111730111731111732111733111734111735111736111737111738111739111740111741111742111743111744111745111746111747111748111749111750111751111752111753111754111755111756111757111758111759111760111761111762111763111764111765111766111767111768111769111770111771111772111773111774111775111776111777111778111779111780111781111782111783111784111785111786111787111788111789111790111791111792111793111794111795111796111797111798111799111800111801111802111803111804111805111806111807111808111809111810111811111812111813111814111815111816111817111818111819111820111821111822111823111824111825111826111827111828111829111830111831111832111833111834111835111836111837111838111839111840111841111842111843111844111845111846111847111848111849111850111851111852111853111854111855111856111857111858111859111860111861111862111863111864111865111866111867111868111869111870111871111872111873111874111875111876111877111878111879111880111881111882111883111884111885111886111887111888111889111890111891111892111893111894111895111896111897111898111899111900111901111902111903111904111905111906111907111908111909111910111911111912111913111914111915111916111917111918111919111920111921111922111923111924111925111926111927111928111929111930111931111932111933111934111935111936111937111938111939111940111941111942111943111944111945111946111947111948111949111950111951111952111953111954111955111956111957111958111959111960111961111962111963111964111965111966111967111968111969111970111971111972111973111974111975111976111977111978111979111980111981111982111983111984111985111986111987111988111989111990111991111992111993111994111995111996111997111998111999112000112001112002112003112004112005112006112007112008112009112010112011112012112013112014112015112016112017112018112019112020112021112022112023112024112025112026112027112028112029112030112031112032112033112034112035112036112037112038112039112040112041112042112043112044112045112046112047112048112049112050112051112052112053112054112055112056112057112058112059112060112061112062112063112064112065112066112067112068112069112070112071112072112073112074112075112076112077112078112079112080112081112082112083112084112085112086112087112088112089112090112091112092112093112094112095112096112097112098112099112100112101112102112103112104112105112106112107112108112109112110112111112112112113112114112115112116112117112118112119112120112121112122112123112124112125112126112127112128112129112130112131112132112133112134112135112136112137112138112139112140112141112142112143112144112145112146112147112148112149112150112151112152112153112154112155112156112157112158112159112160112161112162112163112164112165112166112167112168112169112170112171112172112173112174112175112176112177112178112179112180112181112182112183112184112185112186112187112188112189112190112191112192112193112194112195112196112197112198112199112200112201112202112203112204112205112206112207112208112209112210112211112212112213112214112215112216112217112218112219112220112221112222112223112224112225112226112227112228112229112230112231112232112233112234112235112236112237112238112239112240112241112242112243112244112245112246112247112248112249112250112251112252112253112254112255112256112257112258112259112260112261112262112263112264112265112266112267112268112269112270112271112272112273112274112275112276112277112278112279112280112281112282112283112284112285112286112287112288112289112290112291112292112293112294112295112296112297112298112299112300112301112302112303112304112305112306112307112308112309112310112311112312112313112314112315112316112317112318112319112320112321112322112323112324112325112326112327112328112329112330112331112332112333112334112335112336112337112338112339112340112341112342112343112344112345112346112347112348112349112350112351112352112353112354112355112356112357112358112359112360112361112362112363112364112365112366112367112368112369112370112371112372112373112374112375112376112377112378112379112380112381112382112383112384112385112386112387112388112389112390112391112392112393112394112395112396112397112398112399112400112401112402112403112404112405112406112407112408112409112410112411112412112413112414112415112416112417112418112419112420112421112422112423112424112425112426112427112428112429112430112431112432112433112434112435112436112437112438112439112440112441112442112443112444112445112446112447112448112449112450112451112452112453112454112455112456112457112458112459112460112461112462112463112464112465112466112467112468112469112470112471112472112473112474112475112476112477112478112479112480112481112482112483112484112485112486112487112488112489112490112491112492112493112494112495112496112497112498112499112500112501112502112503112504112505112506112507112508112509112510112511112512112513112514112515112516112517112518112519112520112521112522112523112524112525112526112527112528112529112530112531112532112533112534112535112536112537112538112539112540112541112542112543112544112545112546112547112548112549112550112551112552112553112554112555112556112557112558112559112560112561112562112563112564112565112566112567112568112569112570112571112572112573112574112575112576112577112578112579112580112581112582112583112584112585112586112587112588112589112590112591112592112593112594112595112596112597112598112599112600112601112602112603112604112605112606112607112608112609112610112611112612112613112614112615112616112617112618112619112620112621112622112623112624112625112626112627112628112629112630112631112632112633112634112635112636112637112638112639112640112641112642112643112644112645112646112647112648112649112650112651112652112653112654112655112656112657112658112659112660112661112662112663112664112665112666112667112668112669112670112671112672112673112674112675112676112677112678112679112680112681112682112683112684112685112686112687112688112689112690112691112692112693112694112695112696112697112698112699112700112701112702112703112704112705112706112707112708112709112710112711112712112713112714112715112716112717112718112719112720112721112722112723112724112725112726112727112728112729112730112731112732112733112734112735112736112737112738112739112740112741112742112743112744112745112746112747112748112749112750112751112752112753112754112755112756112757112758112759112760112761112762112763112764112765112766112767112768112769112770112771112772112773112774112775112776112777112778112779112780112781112782112783112784112785112786112787112788112789112790112791112792112793112794112795112796112797112798112799112800112801112802112803112804112805112806112807112808112809112810112811112812112813112814112815112816112817112818112819112820112821112822112823112824112825112826112827112828112829112830112831112832112833112834112835112836112837112838112839112840112841112842112843112844112845112846112847112848112849112850112851112852112853112854112855112856112857112858112859112860112861112862112863112864112865112866112867112868112869112870112871112872112873112874112875112876112877112878112879112880112881112882112883112884112885112886112887112888112889112890112891112892112893112894112895112896112897112898112899112900112901112902112903112904112905112906112907112908112909112910112911112912112913112914112915112916112917112918112919112920112921112922112923112924112925112926112927112928112929112930112931112932112933112934112935112936112937112938112939112940112941112942112943112944112945112946112947112948112949112950112951112952112953112954112955112956112957112958112959112960112961112962112963112964112965112966112967112968112969112970112971112972112973112974112975112976112977112978112979112980112981112982112983112984112985112986112987112988112989112990112991112992112993112994112995112996112997112998112999113000113001113002113003113004113005113006113007113008113009113010113011113012113013113014113015113016113017113018113019113020113021113022113023113024113025113026113027113028113029113030113031113032113033113034113035113036113037113038113039113040113041113042113043113044113045113046113047113048113049113050113051113052113053113054113055113056113057113058113059113060113061113062113063113064113065113066113067113068113069113070113071113072113073113074113075113076113077113078113079113080113081113082113083113084113085113086113087113088113089113090113091113092113093113094113095113096113097113098113099113100113101113102113103113104113105113106113107113108113109113110113111113112113113113114113115113116113117113118113119113120113121113122113123113124113125113126113127113128113129113130113131113132113133113134113135113136113137113138113139113140113141113142113143113144113145113146113147113148113149113150113151113152113153113154113155113156113157113158113159113160113161113162113163113164113165113166113167113168113169113170113171113172113173113174113175113176113177113178113179113180113181113182113183113184113185113186113187113188113189113190113191113192113193113194113195113196113197113198113199113200113201113202113203113204113205113206113207113208113209113210113211113212113213113214113215113216113217113218113219113220113221113222113223113224113225113226113227113228113229113230113231113232113233113234113235113236113237113238113239113240113241113242113243113244113245113246113247113248113249113250113251113252113253113254113255113256113257113258113259113260113261113262113263113264113265113266113267113268113269113270113271113272113273113274113275113276113277113278113279113280113281113282113283113284113285113286113287113288113289113290113291113292113293113294113295113296113297113298113299113300113301113302113303113304113305113306113307113308113309113310113311113312113313113314113315113316113317113318113319113320113321113322113323113324113325113326113327113328113329113330113331113332113333113334113335113336113337113338113339113340113341113342113343113344113345113346113347113348113349113350113351113352113353113354113355113356113357113358113359113360113361113362113363113364113365113366113367113368113369113370113371113372113373113374113375113376113377113378113379113380113381113382113383113384113385113386113387113388113389113390113391113392113393113394113395113396113397113398113399113400113401113402113403113404113405113406113407113408113409113410113411113412113413113414113415113416113417113418113419113420113421113422113423113424113425113426113427113428113429113430113431113432113433113434113435113436113437113438113439113440113441113442113443113444113445113446113447113448113449113450113451113452113453113454113455113456113457113458113459113460113461113462113463113464113465113466113467113468113469113470113471113472113473113474113475113476113477113478113479113480113481113482113483113484113485113486113487113488113489113490113491113492113493113494113495113496113497113498113499113500113501113502113503113504113505113506113507113508113509113510113511113512113513113514113515113516113517113518113519113520113521113522113523113524113525113526113527113528113529113530113531113532113533113534113535113536113537113538113539113540113541113542113543113544113545113546113547113548113549113550113551113552113553113554113555113556113557113558113559113560113561113562113563113564113565113566113567113568113569113570113571113572113573113574113575113576113577113578113579113580113581113582113583113584113585113586113587113588113589113590113591113592113593113594113595113596113597113598113599113600113601113602113603113604113605113606113607113608113609113610113611113612113613113614113615113616113617113618113619113620113621113622113623113624113625113626113627113628113629113630113631113632113633113634113635113636113637113638113639113640113641113642113643113644113645113646113647113648113649113650113651113652113653113654113655113656113657113658113659113660113661113662113663113664113665113666113667113668113669113670113671113672113673113674113675113676113677113678113679113680113681113682113683113684113685113686113687113688113689113690113691113692113693113694113695113696113697113698113699113700113701113702113703113704113705113706113707113708113709113710113711113712113713113714113715113716113717113718113719113720113721113722113723113724113725113726113727113728113729113730113731113732113733113734113735113736113737113738113739113740113741113742113743113744113745113746113747113748113749113750113751113752113753113754113755113756113757113758113759113760113761113762113763113764113765113766113767113768113769113770113771113772113773113774113775113776113777113778113779113780113781113782113783113784113785113786113787113788113789113790113791113792113793113794113795113796113797113798113799113800113801113802113803113804113805113806113807113808113809113810113811113812113813113814113815113816113817113818113819113820113821113822113823113824113825113826113827113828113829113830113831113832113833113834113835113836113837113838113839113840113841113842113843113844113845113846113847113848113849113850113851113852113853113854113855113856113857113858113859113860113861113862113863113864113865113866113867113868113869113870113871113872113873113874113875113876113877113878113879113880113881113882113883113884113885113886113887113888113889113890113891113892113893113894113895113896113897113898113899113900113901113902113903113904113905113906113907113908113909113910113911113912113913113914113915113916113917113918113919113920113921113922113923113924113925113926113927113928113929113930113931113932113933113934113935113936113937113938113939113940113941113942113943113944113945113946113947113948113949113950113951113952113953113954113955113956113957113958113959113960113961113962113963113964113965113966113967113968113969113970113971113972113973113974113975113976113977113978113979113980113981113982113983113984113985113986113987113988113989113990113991113992113993113994113995113996113997113998113999114000114001114002114003114004114005114006114007114008114009114010114011114012114013114014114015114016114017114018114019114020114021114022114023114024114025114026114027114028114029114030114031114032114033114034114035114036114037114038114039114040114041114042114043114044114045114046114047114048114049114050114051114052114053114054114055114056114057114058114059114060114061114062114063114064114065114066114067114068114069114070114071114072114073114074114075114076114077114078114079114080114081114082114083114084114085114086114087114088114089114090114091114092114093114094114095114096114097114098114099114100114101114102114103114104114105114106114107114108114109114110114111114112114113114114114115114116114117114118114119114120114121114122114123114124114125114126114127114128114129114130114131114132114133114134114135114136114137114138114139114140114141114142114143114144114145114146114147114148114149114150114151114152114153114154114155114156114157114158114159114160114161114162114163114164114165114166114167114168114169114170114171114172114173114174114175114176114177114178114179114180114181114182114183114184114185114186114187114188114189114190114191114192114193114194114195114196114197114198114199114200114201114202114203114204114205114206114207114208114209114210114211114212114213114214114215114216114217114218114219114220114221114222114223114224114225114226114227114228114229114230114231114232114233114234114235114236114237114238114239114240114241114242114243114244114245114246114247114248114249114250114251114252114253114254114255114256114257114258114259114260114261114262114263114264114265114266114267114268114269114270114271114272114273114274114275114276114277114278114279114280114281114282114283114284114285114286114287114288114289114290114291114292114293114294114295114296114297114298114299114300114301114302114303114304114305114306114307114308114309114310114311114312114313114314114315114316114317114318114319114320114321114322114323114324114325114326114327114328114329114330114331114332114333114334114335114336114337114338114339114340114341114342114343114344114345114346114347114348114349114350114351114352114353114354114355114356114357114358114359114360114361114362114363114364114365114366114367114368114369114370114371114372114373114374114375114376114377114378114379114380114381114382114383114384114385114386114387114388114389114390114391114392114393114394114395114396114397114398114399114400114401114402114403114404114405114406114407114408114409114410114411114412114413114414114415114416114417114418114419114420114421114422114423114424114425114426114427114428114429114430114431114432114433114434114435114436114437114438114439114440114441114442114443114444114445114446114447114448114449114450114451114452114453114454114455114456114457114458114459114460114461114462114463114464114465114466114467114468114469114470114471114472114473114474114475114476114477114478114479114480114481114482114483114484114485114486114487114488114489114490114491114492114493114494114495114496114497114498114499114500114501114502114503114504114505114506114507114508114509114510114511114512114513114514114515114516114517114518114519114520114521114522114523114524114525114526114527114528114529114530114531114532114533114534114535114536114537114538114539114540114541114542114543114544114545114546114547114548114549114550114551114552114553114554114555114556114557114558114559114560114561114562114563114564114565114566114567114568114569114570114571114572114573114574114575114576114577114578114579114580114581114582114583114584114585114586114587114588114589114590114591114592114593114594114595114596114597114598114599114600114601114602114603114604114605114606114607114608114609114610114611114612114613114614114615114616114617114618114619114620114621114622114623114624114625114626114627114628114629114630114631114632114633114634114635114636114637114638114639114640114641114642114643114644114645114646114647114648114649114650114651114652114653114654114655114656114657114658114659114660114661114662114663114664114665114666114667114668114669114670114671114672114673114674114675114676114677114678114679114680114681114682114683114684114685114686114687114688114689114690114691114692114693114694114695114696114697114698114699114700114701114702114703114704114705114706114707114708114709114710114711114712114713114714114715114716114717114718114719114720114721114722114723114724114725114726114727114728114729114730114731114732114733114734114735114736114737114738114739114740114741114742114743114744114745114746114747114748114749114750114751114752114753114754114755114756114757114758114759114760114761114762114763114764114765114766114767114768114769114770114771114772114773114774114775114776114777114778114779114780114781114782114783114784114785114786114787114788114789114790114791114792114793114794114795114796114797114798114799114800114801114802114803114804114805114806114807114808114809114810114811114812114813114814114815114816114817114818114819114820114821114822114823114824114825114826114827114828114829114830114831114832114833114834114835114836114837114838114839114840114841114842114843114844114845114846114847114848114849114850114851114852114853114854114855114856114857114858114859114860114861114862114863114864114865114866114867114868114869114870114871114872114873114874114875114876114877114878114879114880114881114882114883114884114885114886114887114888114889114890114891114892114893114894114895114896114897114898114899114900114901114902114903114904114905114906114907114908114909114910114911114912114913114914114915114916114917114918114919114920114921114922114923114924114925114926114927114928114929114930114931114932114933114934114935114936114937114938114939114940114941114942114943114944114945114946114947114948114949114950114951114952114953114954114955114956114957114958114959114960114961114962114963114964114965114966114967114968114969114970114971114972114973114974114975114976114977114978114979114980114981114982114983114984114985114986114987114988114989114990114991114992114993114994114995114996114997114998114999115000115001115002115003115004115005115006115007115008115009115010115011115012115013115014115015115016115017115018115019115020115021115022115023115024115025115026115027115028115029115030115031115032115033115034115035115036115037115038115039115040115041115042115043115044115045115046115047115048115049115050115051115052115053115054115055115056115057115058115059115060115061115062115063115064115065115066115067115068115069115070115071115072115073115074115075115076115077115078115079115080115081115082115083115084115085115086115087115088115089115090115091115092115093115094115095115096115097115098115099115100115101115102115103115104115105115106115107115108115109115110115111115112115113115114115115115116115117115118115119115120115121115122115123115124115125115126115127115128115129115130115131115132115133115134115135115136115137115138115139115140115141115142115143115144115145115146115147115148115149115150115151115152115153115154115155115156115157115158115159115160115161115162115163115164115165115166115167115168115169115170115171115172115173115174115175115176115177115178115179115180115181115182115183115184115185115186115187115188115189115190115191115192115193115194115195115196115197115198115199115200115201115202115203115204115205115206115207115208115209115210115211115212115213115214115215115216115217115218115219115220115221115222115223115224115225115226115227115228115229115230115231115232115233115234115235115236115237115238115239115240115241115242115243115244115245115246115247115248115249115250115251115252115253115254115255115256115257115258115259115260115261115262115263115264115265115266115267115268115269115270115271115272115273115274115275115276115277115278115279115280115281115282115283115284115285115286115287115288115289115290115291115292115293115294115295115296115297115298115299115300115301115302115303115304115305115306115307115308115309115310115311115312115313115314115315115316115317115318115319115320115321115322115323115324115325115326115327115328115329115330115331115332115333115334115335115336115337115338115339115340115341115342115343115344115345115346115347115348115349115350115351115352115353115354115355115356115357115358115359115360115361115362115363115364115365115366115367115368115369115370115371115372115373115374115375115376115377115378115379115380115381115382115383115384115385115386115387115388115389115390115391115392115393115394115395115396115397115398115399115400115401115402115403115404115405115406115407115408115409115410115411115412115413115414115415115416115417115418115419115420115421115422115423115424115425115426115427115428115429115430115431115432115433115434115435115436115437115438115439115440115441115442115443115444115445115446115447115448115449115450115451115452115453115454115455115456115457115458115459115460115461115462115463115464115465115466115467115468115469115470115471115472115473115474115475115476115477115478115479115480115481115482115483115484115485115486115487115488115489115490115491115492115493115494115495115496115497115498115499115500115501115502115503115504115505115506115507115508115509115510115511115512115513115514115515115516115517115518115519115520115521115522115523115524115525115526115527115528115529115530115531115532115533115534115535115536115537115538115539115540115541115542115543115544115545115546115547115548115549115550115551115552115553115554115555115556115557115558115559115560115561115562115563115564115565115566115567115568115569115570115571115572115573115574115575115576115577115578115579115580115581115582115583115584115585115586115587115588115589115590115591115592115593115594115595115596115597115598115599115600115601115602115603115604115605115606115607115608115609115610115611115612115613115614115615115616115617115618115619115620115621115622115623115624115625115626115627115628115629115630115631115632115633115634115635115636115637115638115639115640115641115642115643115644115645115646115647115648115649115650115651115652115653115654115655115656115657115658115659115660115661115662115663115664115665115666115667115668115669115670115671115672115673115674115675115676115677115678115679115680115681115682115683115684115685115686115687115688115689115690115691115692115693115694115695115696115697115698115699115700115701115702115703115704115705115706115707115708115709115710115711115712115713115714115715115716115717115718115719115720115721115722115723115724115725115726115727115728115729115730115731115732115733115734115735115736115737115738115739115740115741115742115743115744115745115746115747115748115749115750115751115752115753115754115755115756115757115758115759115760115761115762115763115764115765115766115767115768115769115770115771115772115773115774115775115776115777115778115779115780115781115782115783115784115785115786115787115788115789115790115791115792115793115794115795115796115797115798115799115800115801115802115803115804115805115806115807115808115809115810115811115812115813115814115815115816115817115818115819115820115821115822115823115824115825115826115827115828115829115830115831115832115833115834115835115836115837115838115839115840115841115842115843115844115845115846115847115848115849115850115851115852115853115854115855115856115857115858115859115860115861115862115863115864115865115866115867115868115869115870115871115872115873115874115875115876115877115878115879115880115881115882115883115884115885115886115887115888115889115890115891115892115893115894115895115896115897115898115899115900115901115902115903115904115905115906115907115908115909115910115911115912115913115914115915115916115917115918115919115920115921115922115923115924115925115926115927115928115929115930115931115932115933115934115935115936115937115938115939115940115941115942115943115944115945115946115947115948115949115950115951115952115953115954115955115956115957115958115959115960115961115962115963115964115965115966115967115968115969115970115971115972115973115974115975115976115977115978115979115980115981115982115983115984115985115986115987115988115989115990115991115992115993115994115995115996115997115998115999116000116001116002116003116004116005116006116007116008116009116010116011116012116013116014116015116016116017116018116019116020116021116022116023116024116025116026116027116028116029116030116031116032116033116034116035116036116037116038116039116040116041116042116043116044116045116046116047116048116049116050116051116052116053116054116055116056116057116058116059116060116061116062116063116064116065116066116067116068116069116070116071116072116073116074116075116076116077116078116079116080116081116082116083116084116085116086116087116088116089116090116091116092116093116094116095116096116097116098116099116100116101116102116103116104116105116106116107116108116109116110116111116112116113116114116115116116116117116118116119116120116121116122116123116124116125116126116127116128116129116130116131116132116133116134116135116136116137116138116139116140116141116142116143116144116145116146116147116148116149116150116151116152116153116154116155116156116157116158116159116160116161116162116163116164116165116166116167116168116169116170116171116172116173116174116175116176116177116178116179116180116181116182116183116184116185116186116187116188116189116190116191116192116193116194116195116196116197116198116199116200116201116202116203116204116205116206116207116208116209116210116211116212116213116214116215116216116217116218116219116220116221116222116223116224116225116226116227116228116229116230116231116232116233116234116235116236116237116238116239116240116241116242116243116244116245116246116247116248116249116250116251116252116253116254116255116256116257116258116259116260116261116262116263116264116265116266116267116268116269116270116271116272116273116274116275116276116277116278116279116280116281116282116283116284116285116286116287116288116289116290116291116292116293116294116295116296116297116298116299116300116301116302116303116304116305116306116307116308116309116310116311116312116313116314116315116316116317116318116319116320116321116322116323116324116325116326116327116328116329116330116331116332116333116334116335116336116337116338116339116340116341116342116343116344116345116346116347116348116349116350116351116352116353116354116355116356116357116358116359116360116361116362116363116364116365116366116367116368116369116370116371116372116373116374116375116376116377116378116379116380116381116382116383116384116385116386116387116388116389116390116391116392116393116394116395116396116397116398116399116400116401116402116403116404116405116406116407116408116409116410116411116412116413116414116415116416116417116418116419116420116421116422116423116424116425116426116427116428116429116430116431116432116433116434116435116436116437116438116439116440116441116442116443116444116445116446116447116448116449116450116451116452116453116454116455116456116457116458116459116460116461116462116463116464116465116466116467116468116469116470116471116472116473116474116475116476116477116478116479116480116481116482116483116484116485116486116487116488116489116490116491116492116493116494116495116496116497116498116499116500116501116502116503116504116505116506116507116508116509116510116511116512116513116514116515116516116517116518116519116520116521116522116523116524116525116526116527116528116529116530116531116532116533116534116535116536116537116538116539116540116541116542116543116544116545116546116547116548116549116550116551116552116553116554116555116556116557116558116559116560116561116562116563116564116565116566116567116568116569116570116571116572116573116574116575116576116577116578116579116580116581116582116583116584116585116586116587116588116589116590116591116592116593116594116595116596116597116598116599116600116601116602116603116604116605116606116607116608116609116610116611116612116613116614116615116616116617116618116619116620116621116622116623116624116625116626116627116628116629116630116631116632116633116634116635116636116637116638116639116640116641116642116643116644116645116646116647116648116649116650116651116652116653116654116655116656116657116658116659116660116661116662116663116664116665116666116667116668116669116670116671116672116673116674116675116676116677116678116679116680116681116682116683116684116685116686116687116688116689116690116691116692116693116694116695116696116697116698116699116700116701116702116703116704116705116706116707116708116709116710116711116712116713116714116715116716116717116718116719116720116721116722116723116724116725116726116727116728116729116730116731116732116733116734116735116736116737116738116739116740116741116742116743116744116745116746116747116748116749116750116751116752116753116754116755116756116757116758116759116760116761116762116763116764116765116766116767116768116769116770116771116772116773116774116775116776116777116778116779116780116781116782116783116784116785116786116787116788116789116790116791116792116793116794116795116796116797116798116799116800116801116802116803116804116805116806116807116808116809116810116811116812116813116814116815116816116817116818116819116820116821116822116823116824116825116826116827116828116829116830116831116832116833116834116835116836116837116838116839116840116841116842116843116844116845116846116847116848116849116850116851116852116853116854116855116856116857116858116859116860116861116862116863116864116865116866116867116868116869116870116871116872116873116874116875116876116877116878116879116880116881116882116883116884116885116886116887116888116889116890116891116892116893116894116895116896116897116898116899116900116901116902116903116904116905116906116907116908116909116910116911116912116913116914116915116916116917116918116919116920116921116922116923116924116925116926116927116928116929116930116931116932116933116934116935116936116937116938116939116940116941116942116943116944116945116946116947116948116949116950116951116952116953116954116955116956116957116958116959116960116961116962116963116964116965116966116967116968116969116970116971116972116973116974116975116976116977116978116979116980116981116982116983116984116985116986116987116988116989116990116991116992116993116994116995116996116997116998116999117000117001117002117003117004117005117006117007117008117009117010117011117012117013117014117015117016117017117018117019117020117021117022117023117024117025117026117027117028117029117030117031117032117033117034117035117036117037117038117039117040117041117042117043117044117045117046117047117048117049117050117051117052117053117054117055117056117057117058117059117060117061117062117063117064117065117066117067117068117069117070117071117072117073117074117075117076117077117078117079117080117081117082117083117084117085117086117087117088117089117090117091117092117093117094117095117096117097117098117099117100117101117102117103117104117105117106117107117108117109117110117111117112117113117114117115117116117117117118117119117120117121117122117123117124117125117126117127117128117129117130117131117132117133117134117135117136117137117138117139117140117141117142117143117144117145117146117147117148117149117150117151117152117153117154117155117156117157117158117159117160117161117162117163117164117165117166117167117168117169117170117171117172117173117174117175117176117177117178117179117180117181117182117183117184117185117186117187117188117189117190117191117192117193117194117195117196117197117198117199117200117201117202117203117204117205117206117207117208117209117210117211117212117213117214117215117216117217117218117219117220117221117222117223117224117225117226117227117228117229117230117231117232117233117234117235117236117237117238117239117240117241117242117243117244117245117246117247117248117249117250117251117252117253117254117255117256117257117258117259117260117261117262117263117264117265117266117267117268117269117270117271117272117273117274117275117276117277117278117279117280117281117282117283117284117285117286117287117288117289117290117291117292117293117294117295117296117297117298117299117300117301117302117303117304117305117306117307117308117309117310117311117312117313117314117315117316117317117318117319117320117321117322117323117324117325117326117327117328117329117330117331117332117333117334117335117336117337117338117339117340117341117342117343117344117345117346117347117348117349117350117351117352117353117354117355117356117357117358117359117360117361117362117363117364117365117366117367117368117369117370117371117372117373117374117375117376117377117378117379117380117381117382117383117384117385117386117387117388117389117390117391117392117393117394117395117396117397117398117399117400117401117402117403117404117405117406117407117408117409117410117411117412117413117414117415117416117417117418117419117420117421117422117423117424117425117426117427117428117429117430117431117432117433117434117435117436117437117438117439117440117441117442117443117444117445117446117447117448117449117450117451117452117453117454117455117456117457117458117459117460117461117462117463117464117465117466117467117468117469117470117471117472117473117474117475117476117477117478117479117480117481117482117483117484117485117486117487117488117489117490117491117492117493117494117495117496117497117498117499117500117501117502117503117504117505117506117507117508117509117510117511117512117513117514117515117516117517117518117519117520117521117522117523117524117525117526117527117528117529117530117531117532117533117534117535117536117537117538117539117540117541117542117543117544117545117546117547117548117549117550117551117552117553117554117555117556117557117558117559117560117561117562117563117564117565117566117567117568117569117570117571117572117573117574117575117576117577117578117579117580117581117582117583117584117585117586117587117588117589117590117591117592117593117594117595117596117597117598117599117600117601117602117603117604117605117606117607117608117609117610117611117612117613117614117615117616117617117618117619117620117621117622117623117624117625117626117627117628117629117630117631117632117633117634117635117636117637117638117639117640117641117642117643117644117645117646117647117648117649117650117651117652117653117654117655117656117657117658117659117660117661117662117663117664117665117666117667117668117669117670117671117672117673117674117675117676117677117678117679117680117681117682117683117684117685117686117687117688117689117690117691117692117693117694117695117696117697117698117699117700117701117702117703117704117705117706117707117708117709117710117711117712117713117714117715117716117717117718117719117720117721117722117723117724117725117726117727117728117729117730117731117732117733117734117735117736117737117738117739117740117741117742117743117744117745117746117747117748117749117750117751117752117753117754117755117756117757117758117759117760117761117762117763117764117765117766117767117768117769117770117771117772117773117774117775117776117777117778117779117780117781117782117783117784117785117786117787117788117789117790117791117792117793117794117795117796117797117798117799117800117801117802117803117804117805117806117807117808117809117810117811117812117813117814117815117816117817117818117819117820117821117822117823117824117825117826117827117828117829117830117831117832117833117834117835117836117837117838117839117840117841117842117843117844117845117846117847117848117849117850117851117852117853117854117855117856117857117858117859117860117861117862117863117864117865117866117867117868117869117870117871117872117873117874117875117876117877117878117879117880117881117882117883117884117885117886117887117888117889117890117891117892117893117894117895117896117897117898117899117900117901117902117903117904117905117906117907117908117909117910117911117912117913117914117915117916117917117918117919117920117921117922117923117924117925117926117927117928117929117930117931117932117933117934117935117936117937117938117939117940117941117942117943117944117945117946117947117948117949117950117951117952117953117954117955117956117957117958117959117960117961117962117963117964117965117966117967117968117969117970117971117972117973117974117975117976117977117978117979117980117981117982117983117984117985117986117987117988117989117990117991117992117993117994117995117996117997117998117999118000118001118002118003118004118005118006118007118008118009118010118011118012118013118014118015118016118017118018118019118020118021118022118023118024118025118026118027118028118029118030118031118032118033118034118035118036118037118038118039118040118041118042118043118044118045118046118047118048118049118050118051118052118053118054118055118056118057118058118059118060118061118062118063118064118065118066118067118068118069118070118071118072118073118074118075118076118077118078118079118080118081118082118083118084118085118086118087118088118089118090118091118092118093118094118095118096118097118098118099118100118101118102118103118104118105118106118107118108118109118110118111118112118113118114118115118116118117118118118119118120118121118122118123118124118125118126118127118128118129118130118131118132118133118134118135118136118137118138118139118140118141118142118143118144118145118146118147118148118149118150118151118152118153118154118155118156118157118158118159118160118161118162118163118164118165118166118167118168118169118170118171118172118173118174118175118176118177118178118179118180118181118182118183118184118185118186118187118188118189118190118191118192118193118194118195118196118197118198118199118200118201118202118203118204118205118206118207118208118209118210118211118212118213118214118215118216118217118218118219118220118221118222118223118224118225118226118227118228118229118230118231118232118233118234118235118236118237118238118239118240118241118242118243118244118245118246118247118248118249118250118251118252118253118254118255118256118257118258118259118260118261118262118263118264118265118266118267118268118269118270118271118272118273118274118275118276118277118278118279118280118281118282118283118284118285118286118287118288118289118290118291118292118293118294118295118296118297118298118299118300118301118302118303118304118305118306118307118308118309118310118311118312118313118314118315118316118317118318118319118320118321118322118323118324118325118326118327118328118329118330118331118332118333118334118335118336118337118338118339118340118341118342118343118344118345118346118347118348118349118350118351118352118353118354118355118356118357118358118359118360118361118362118363118364118365118366118367118368118369118370118371118372118373118374118375118376118377118378118379118380118381118382118383118384118385118386118387118388118389118390118391118392118393118394118395118396118397118398118399118400118401118402118403118404118405118406118407118408118409118410118411118412118413118414118415118416118417118418118419118420118421118422118423118424118425118426118427118428118429118430118431118432118433118434118435118436118437118438118439118440118441118442118443118444118445118446118447118448118449118450118451118452118453118454118455118456118457118458118459118460118461118462118463118464118465118466118467118468118469118470118471118472118473118474118475118476118477118478118479118480118481118482118483118484118485118486118487118488118489118490118491118492118493118494118495118496118497118498118499118500118501118502118503118504118505118506118507118508118509118510118511118512118513118514118515118516118517118518118519118520118521118522118523118524118525118526118527118528118529118530118531118532118533118534118535118536118537118538118539118540118541118542118543118544118545118546118547118548118549118550118551118552118553118554118555118556118557118558118559118560118561118562118563118564118565118566118567118568118569118570118571118572118573118574118575118576118577118578118579118580118581118582118583118584118585118586118587118588118589118590118591118592118593118594118595118596118597118598118599118600118601118602118603118604118605118606118607118608118609118610118611118612118613118614118615118616118617118618118619118620118621118622118623118624118625118626118627118628118629118630118631118632118633118634118635118636118637118638118639118640118641118642118643118644118645118646118647118648118649118650118651118652118653118654118655118656118657118658118659118660118661118662118663118664118665118666118667118668118669118670118671118672118673118674118675118676118677118678118679118680118681118682118683118684118685118686118687118688118689118690118691118692118693118694118695118696118697118698118699118700118701118702118703118704118705118706118707118708118709118710118711118712118713118714118715118716118717118718118719118720118721118722118723118724118725118726118727118728118729118730118731118732118733118734118735118736118737118738118739118740118741118742118743118744118745118746118747118748118749118750118751118752118753118754118755118756118757118758118759118760118761118762118763118764118765118766118767118768118769118770118771118772118773118774118775118776118777118778118779118780118781118782118783118784118785118786118787118788118789118790118791118792118793118794118795118796118797118798118799118800118801118802118803118804118805118806118807118808118809118810118811118812118813118814118815118816118817118818118819118820118821118822118823118824118825118826118827118828118829118830118831118832118833118834118835118836118837118838118839118840118841118842118843118844118845118846118847118848118849118850118851118852118853118854118855118856118857118858118859118860118861118862118863118864118865118866118867118868118869118870118871118872118873118874118875118876118877118878118879118880118881118882118883118884118885118886118887118888118889118890118891118892118893118894118895118896118897118898118899118900118901118902118903118904118905118906118907118908118909118910118911118912118913118914118915118916118917118918118919118920118921118922118923118924118925118926118927118928118929118930118931118932118933118934118935118936118937118938118939118940118941118942118943118944118945118946118947118948118949118950118951118952118953118954118955118956118957118958118959118960118961118962118963118964118965118966118967118968118969118970118971118972118973118974118975118976118977118978118979118980118981118982118983118984118985118986118987118988118989118990118991118992118993118994118995118996118997118998118999119000119001119002119003119004119005119006119007119008119009119010119011119012119013119014119015119016119017119018119019119020119021119022119023119024119025119026119027119028119029119030119031119032119033119034119035119036119037119038119039119040119041119042119043119044119045119046119047119048119049119050119051119052119053119054119055119056119057119058119059119060119061119062119063119064119065119066119067119068119069119070119071119072119073119074119075119076119077119078119079119080119081119082119083119084119085119086119087119088119089119090119091119092119093119094119095119096119097119098119099119100119101119102119103119104119105119106119107119108119109119110119111119112119113119114119115119116119117119118119119119120119121119122119123119124119125119126119127119128119129119130119131119132119133119134119135119136119137119138119139119140119141119142119143119144119145119146119147119148119149119150119151119152119153119154119155119156119157119158119159119160119161119162119163119164119165119166119167119168119169119170119171119172119173119174119175119176119177119178119179119180119181119182119183119184119185119186119187119188119189119190119191119192119193119194119195119196119197119198119199119200119201119202119203119204119205119206119207119208119209119210119211119212119213119214119215119216119217119218119219119220119221119222119223119224119225119226119227119228119229119230119231119232119233119234119235119236119237119238119239119240119241119242119243119244119245119246119247119248119249119250119251119252119253119254119255119256119257119258119259119260119261119262119263119264119265119266119267119268119269119270119271119272119273119274119275119276119277119278119279119280119281119282119283119284119285119286119287119288119289119290119291119292119293119294119295119296119297119298119299119300119301119302119303119304119305119306119307119308119309119310119311119312119313119314119315119316119317119318119319119320119321119322119323119324119325119326119327119328119329119330119331119332119333119334119335119336119337119338119339119340119341119342119343119344119345119346119347119348119349119350119351119352119353119354119355119356119357119358119359119360119361119362119363119364119365119366119367119368119369119370119371119372119373119374119375119376119377119378119379119380119381119382119383119384119385119386119387119388119389119390119391119392119393119394119395119396119397119398119399119400119401119402119403119404119405119406119407119408119409119410119411119412119413119414119415119416119417119418119419119420119421119422119423119424119425119426119427119428119429119430119431119432119433119434119435119436119437119438119439119440119441119442119443119444119445119446119447119448119449119450119451119452119453119454119455119456119457119458119459119460119461119462119463119464119465119466119467119468119469119470119471119472119473119474119475119476119477119478119479119480119481119482119483119484119485119486119487119488119489119490119491119492119493119494119495119496119497119498119499119500119501119502119503119504119505119506119507119508119509119510119511119512119513119514119515119516119517119518119519119520119521119522119523119524119525119526119527119528119529119530119531119532119533119534119535119536119537119538119539119540119541119542119543119544119545119546119547119548119549119550119551119552119553119554119555119556119557119558119559119560119561119562119563119564119565119566119567119568119569119570119571119572119573119574119575119576119577119578119579119580119581119582119583119584119585119586119587119588119589119590119591119592119593119594119595119596119597119598119599119600119601119602119603119604119605119606119607119608119609119610119611119612119613119614119615119616119617119618119619119620119621119622119623119624119625119626119627119628119629119630119631119632119633119634119635119636119637119638119639119640119641119642119643119644119645119646119647119648119649119650119651119652119653119654119655119656119657119658119659119660119661119662119663119664119665119666119667119668119669119670119671119672119673119674119675119676119677119678119679119680119681119682119683119684119685119686119687119688119689119690119691119692119693119694119695119696119697119698119699119700119701119702119703119704119705119706119707119708119709119710119711119712119713119714119715119716119717119718119719119720119721119722119723119724119725119726119727119728119729119730119731119732119733119734119735119736119737119738119739119740119741119742119743119744119745119746119747119748119749119750119751119752119753119754119755119756119757119758119759119760119761119762119763119764119765119766119767119768119769119770119771119772119773119774119775119776119777119778119779119780119781119782119783119784119785119786119787119788119789119790119791119792119793119794119795119796119797119798119799119800119801119802119803119804119805119806119807119808119809119810119811119812119813119814119815119816119817119818119819119820119821119822119823119824119825119826119827119828119829119830119831119832119833119834119835119836119837119838119839119840119841119842119843119844119845119846119847119848119849119850119851119852119853119854119855119856119857119858119859119860119861119862119863119864119865119866119867119868119869119870119871119872119873119874119875119876119877119878119879119880119881119882119883119884119885119886119887119888119889119890119891119892119893119894119895119896119897119898119899119900119901119902119903119904119905119906119907119908119909119910119911119912119913119914119915119916119917119918119919119920119921119922119923119924119925119926119927119928119929119930119931119932119933119934119935119936119937119938119939119940119941119942119943119944119945119946119947119948119949119950119951119952119953119954119955119956119957119958119959119960119961119962119963119964119965119966119967119968119969119970119971119972119973119974119975119976119977119978119979119980119981119982119983119984119985119986119987119988119989119990119991119992119993119994119995119996119997119998119999120000120001120002120003120004120005120006120007120008120009120010120011120012120013120014120015120016120017120018120019120020120021120022120023120024120025120026120027120028120029120030120031120032120033120034120035120036120037120038120039120040120041120042120043120044120045120046120047120048120049120050120051120052120053120054120055120056120057120058120059120060120061120062120063120064120065120066120067120068120069120070120071120072120073120074120075120076120077120078120079120080120081120082120083120084120085120086120087120088120089120090120091120092120093120094120095120096120097120098120099120100120101120102120103120104120105120106120107120108120109120110120111120112120113120114120115120116120117120118120119120120120121120122120123120124120125120126120127120128120129120130120131120132120133120134120135120136120137120138120139120140120141120142120143120144120145120146120147120148120149120150120151120152120153120154120155120156120157120158120159120160120161120162120163120164120165120166120167120168120169120170120171120172120173120174120175120176120177120178120179120180120181120182120183120184120185120186120187120188120189120190120191120192120193120194120195120196120197120198120199120200120201120202120203120204120205120206120207120208120209120210120211120212120213120214120215120216120217120218120219120220120221120222120223120224120225120226120227120228120229120230120231120232120233120234120235120236120237120238120239120240120241120242120243120244120245120246120247120248120249120250120251120252120253120254120255120256120257120258120259120260120261120262120263120264120265120266120267120268120269120270120271120272120273120274120275120276120277120278120279120280120281120282120283120284120285120286120287120288120289120290120291120292120293120294120295120296120297120298120299120300120301120302120303120304120305120306120307120308120309120310120311120312120313120314120315120316120317120318120319120320120321120322120323120324120325120326120327120328120329120330120331120332120333120334120335120336120337120338120339120340120341120342120343120344120345120346120347120348120349120350120351120352120353120354120355120356120357120358120359120360120361120362120363120364120365120366120367120368120369120370120371120372120373120374120375120376120377120378120379120380120381120382120383120384120385120386120387120388120389120390120391120392120393120394120395120396120397120398120399120400120401120402120403120404120405120406120407120408120409120410120411120412120413120414120415120416120417120418120419120420120421120422120423120424120425120426120427120428120429120430120431120432120433120434120435120436120437120438120439120440120441120442120443120444120445120446120447120448120449120450120451120452120453120454120455120456120457120458120459120460120461120462120463120464120465120466120467120468120469120470120471120472120473120474120475120476120477120478120479120480120481120482120483120484120485120486120487120488120489120490120491120492120493120494120495120496120497120498120499120500120501120502120503120504120505120506120507120508120509120510120511120512120513120514120515120516120517120518120519120520120521120522120523120524120525120526120527120528120529120530120531120532120533120534120535120536120537120538120539120540120541120542120543120544120545120546120547120548120549120550120551120552120553120554120555120556120557120558120559120560120561120562120563120564120565120566120567120568120569120570120571120572120573120574120575120576120577120578120579120580120581120582120583120584120585120586120587120588120589120590120591120592120593120594120595120596120597120598120599120600120601120602120603120604120605120606120607120608120609120610120611120612120613120614120615120616120617120618120619120620120621120622120623120624120625120626120627120628120629120630120631120632120633120634120635120636120637120638120639120640120641120642120643120644120645120646120647120648120649120650120651120652120653120654120655120656120657120658120659120660120661120662120663120664120665120666120667120668120669120670120671120672120673120674120675120676120677120678120679120680120681120682120683120684120685120686120687120688120689120690120691120692120693120694120695120696120697120698120699120700120701120702120703120704120705120706120707120708120709120710120711120712120713120714120715120716120717120718120719120720120721120722120723120724120725120726120727120728120729120730120731120732120733120734120735120736120737120738120739120740120741120742120743120744120745120746120747120748120749120750120751120752120753120754120755120756120757120758120759120760120761120762120763120764120765120766120767120768120769120770120771120772120773120774120775120776120777120778120779120780120781120782120783120784120785120786120787120788120789120790120791120792120793120794120795120796120797120798120799120800120801120802120803120804120805120806120807120808120809120810120811120812120813120814120815120816120817120818120819120820120821120822120823120824120825120826120827120828120829120830120831120832120833120834120835120836120837120838120839120840120841120842120843120844120845120846120847120848120849120850120851120852120853120854120855120856120857120858120859120860120861120862120863120864120865120866120867120868120869120870120871120872120873120874120875120876120877120878120879120880120881120882120883120884120885120886120887120888120889120890120891120892120893120894120895120896120897120898120899120900120901120902120903120904120905120906120907120908120909120910120911120912120913120914120915120916120917120918120919120920120921120922120923120924120925120926120927120928120929120930120931120932120933120934120935120936120937120938120939120940120941120942120943120944120945120946120947120948120949120950120951120952120953120954120955120956120957120958120959120960120961120962120963120964120965120966120967120968120969120970120971120972120973120974120975120976120977120978120979120980120981120982120983120984120985120986120987120988120989120990120991120992120993120994120995120996120997120998120999121000121001121002121003121004121005121006121007121008121009121010121011121012121013121014121015121016121017121018121019121020121021121022121023121024121025121026121027121028121029121030121031121032121033121034121035121036121037121038121039121040121041121042121043121044121045121046121047121048121049121050121051121052121053121054121055121056121057121058121059121060121061121062121063121064121065121066121067121068121069121070121071121072121073121074121075121076121077121078121079121080121081121082121083121084121085121086121087121088121089121090121091121092121093121094121095121096121097121098121099121100121101121102121103121104121105121106121107121108121109121110121111121112121113121114121115121116121117121118121119121120121121121122121123121124121125121126121127121128121129121130121131121132121133121134121135121136121137121138121139121140121141121142121143121144121145121146121147121148121149121150121151121152121153121154121155121156121157121158121159121160121161121162121163121164121165121166121167121168121169121170121171121172121173121174121175121176121177121178121179121180121181121182121183121184121185121186121187121188121189121190121191121192121193121194121195121196121197121198121199121200121201121202121203121204121205121206121207121208121209121210121211121212121213121214121215121216121217121218121219121220121221121222121223121224121225121226121227121228121229121230121231121232121233121234121235121236121237121238121239121240121241121242121243121244121245121246121247121248121249121250121251121252121253121254121255121256121257121258121259121260121261121262121263121264121265121266121267121268121269121270121271121272121273121274121275121276121277121278121279121280121281121282121283121284121285121286121287121288121289121290121291121292121293121294121295121296121297121298121299121300121301121302121303121304121305121306121307121308121309121310121311121312121313121314121315121316121317121318121319121320121321121322121323121324121325121326121327121328121329121330121331121332121333121334121335121336121337121338121339121340121341121342121343121344121345121346121347121348121349121350121351121352121353121354121355121356121357121358121359121360121361121362121363121364121365121366121367121368121369121370121371121372121373121374121375121376121377121378121379121380121381121382121383121384121385121386121387121388121389121390121391121392121393121394121395121396121397121398121399121400121401121402121403121404121405121406121407121408121409121410121411121412121413121414121415121416121417121418121419121420121421121422121423121424121425121426121427121428121429121430121431121432121433121434121435121436121437121438121439121440121441121442121443121444121445121446121447121448121449121450121451121452121453121454121455121456121457121458121459121460121461121462121463121464121465121466121467121468121469121470121471121472121473121474121475121476121477121478121479121480121481121482121483121484121485121486121487121488121489121490121491121492121493121494121495121496121497121498121499121500121501121502121503121504121505121506121507121508121509121510121511121512121513121514121515121516121517121518121519121520121521121522121523121524121525121526121527121528121529121530121531121532121533121534121535121536121537121538121539121540121541121542121543121544121545121546121547121548121549121550121551121552121553121554121555121556121557121558121559121560121561121562121563121564121565121566121567121568121569121570121571121572121573121574121575121576121577121578121579121580121581121582121583121584121585121586121587121588121589121590121591121592121593121594121595121596121597121598121599121600121601121602121603121604121605121606121607121608121609121610121611121612121613121614121615121616121617121618121619121620121621121622121623121624121625121626121627121628121629121630121631121632121633121634121635121636121637121638121639121640121641121642121643121644121645121646121647121648121649121650121651121652121653121654121655121656121657121658121659121660121661121662121663121664121665121666121667121668121669121670121671121672121673121674121675121676121677121678121679121680121681121682121683121684121685121686121687121688121689121690121691121692121693121694121695121696121697121698121699121700121701121702121703121704121705121706121707121708121709121710121711121712121713121714121715121716121717121718121719121720121721121722121723121724121725121726121727121728121729121730121731121732121733121734121735121736121737121738121739121740121741121742121743121744121745121746121747121748121749121750121751121752121753121754121755121756121757121758121759121760121761121762121763121764121765121766121767121768121769121770121771121772121773121774121775121776121777121778121779121780121781121782121783121784121785121786121787121788121789121790121791121792121793121794121795121796121797121798121799121800121801121802121803121804121805121806121807121808121809121810121811121812121813121814121815121816121817121818121819121820121821121822121823121824121825121826121827121828121829121830121831121832121833121834121835121836121837121838121839121840121841121842121843121844121845121846121847121848121849121850121851121852121853121854121855121856121857121858121859121860121861121862121863121864121865121866121867121868121869121870121871121872121873121874121875121876121877121878121879121880121881121882121883121884121885121886121887121888121889121890121891121892121893121894121895121896121897121898121899121900121901121902121903121904121905121906121907121908121909121910121911121912121913121914121915121916121917121918121919121920121921121922121923121924121925121926121927121928121929121930121931121932121933121934121935121936121937121938121939121940121941121942121943121944121945121946121947121948121949121950121951121952121953121954121955121956121957121958121959121960121961121962121963121964121965121966121967121968121969121970121971121972121973121974121975121976121977121978121979121980121981121982121983121984121985121986121987121988121989121990121991121992121993121994121995121996121997121998121999122000122001122002122003122004122005122006122007122008122009122010122011122012122013122014122015122016122017122018122019122020122021122022122023122024122025122026122027122028122029122030122031122032122033122034122035122036122037122038122039122040122041122042122043122044122045122046122047122048122049122050122051122052122053122054122055122056122057122058122059122060122061122062122063122064122065122066122067122068122069122070122071122072122073122074122075122076122077122078122079122080122081122082122083122084122085122086122087122088122089122090122091122092122093122094122095122096122097122098122099122100122101122102122103122104122105122106122107122108122109122110122111122112122113122114122115122116122117122118122119122120122121122122122123122124122125122126122127122128122129122130122131122132122133122134122135122136122137122138122139122140122141122142122143122144122145122146122147122148122149122150122151122152122153122154122155122156122157122158122159122160122161122162122163122164122165122166122167122168122169122170122171122172122173122174122175122176122177122178122179122180122181122182122183122184122185122186122187122188122189122190122191122192122193122194122195122196122197122198122199122200122201122202122203122204122205122206122207122208122209122210122211122212122213122214122215122216122217122218122219122220122221122222122223122224122225122226122227122228122229122230122231122232122233122234122235122236122237122238122239122240122241122242122243122244122245122246122247122248122249122250122251122252122253122254122255122256122257122258122259122260122261122262122263122264122265122266122267122268122269122270122271122272122273122274122275122276122277122278122279122280122281122282122283122284122285122286122287122288122289122290122291122292122293122294122295122296122297122298122299122300122301122302122303122304122305122306122307122308122309122310122311122312122313122314122315122316122317122318122319122320122321122322122323122324122325122326122327122328122329122330122331122332122333122334122335122336122337122338122339122340122341122342122343122344122345122346122347122348122349122350122351122352122353122354122355122356122357122358122359122360122361122362122363122364122365122366122367122368122369122370122371122372122373122374122375122376122377122378122379122380122381122382122383122384122385122386122387122388122389122390122391122392122393122394122395122396122397122398122399122400122401122402122403122404122405122406122407122408122409122410122411122412122413122414122415122416122417122418122419122420122421122422122423122424122425122426122427122428122429122430122431122432122433122434122435122436122437122438122439122440122441122442122443122444122445122446122447122448122449122450122451122452122453122454122455122456122457122458122459122460122461122462122463122464122465122466122467122468122469122470122471122472122473122474122475122476122477122478122479122480122481122482122483122484122485122486122487122488122489122490122491122492122493122494122495122496122497122498122499122500122501122502122503122504122505122506122507122508122509122510122511122512122513122514122515122516122517122518122519122520122521122522122523122524122525122526122527122528122529122530122531122532122533122534122535122536122537122538122539122540122541122542122543122544122545122546122547122548122549122550122551122552122553122554122555122556122557122558122559122560122561122562122563122564122565122566122567122568122569122570122571122572122573122574122575122576122577122578122579122580122581122582122583122584122585122586122587122588122589122590122591122592122593122594122595122596122597122598122599122600122601122602122603122604122605122606122607122608122609122610122611122612122613122614122615122616122617122618122619122620122621122622122623122624122625122626122627122628122629122630122631122632122633122634122635122636122637122638122639122640122641122642122643122644122645122646122647122648122649122650122651122652122653122654122655122656122657122658122659122660122661122662122663122664122665122666122667122668122669122670122671122672122673122674122675122676122677122678122679122680122681122682122683122684122685122686122687122688122689122690122691122692122693122694122695122696122697122698122699122700122701122702122703122704122705122706122707122708122709122710122711122712122713122714122715122716122717122718122719122720122721122722122723122724122725122726122727122728122729122730122731122732122733122734122735122736122737122738122739122740122741122742122743122744122745122746122747122748122749122750122751122752122753122754122755122756122757122758122759122760122761122762122763122764122765122766122767122768122769122770122771122772122773122774122775122776122777122778122779122780122781122782122783122784122785122786122787122788122789122790122791122792122793122794122795122796122797122798122799122800122801122802122803122804122805122806122807122808122809122810122811122812122813122814122815122816122817122818122819122820122821122822122823122824122825122826122827122828122829122830122831122832122833122834122835122836122837122838122839122840122841122842122843122844122845122846122847122848122849122850122851122852122853122854122855122856122857122858122859122860122861122862122863122864122865122866122867122868122869122870122871122872122873122874122875122876122877122878122879122880122881122882122883122884122885122886122887122888122889122890122891122892122893122894122895122896122897122898122899122900122901122902122903122904122905122906122907122908122909122910122911122912122913122914122915122916122917122918122919122920122921122922122923122924122925122926122927122928122929122930122931122932122933122934122935122936122937122938122939122940122941122942122943122944122945122946122947122948122949122950122951122952122953122954122955122956122957122958122959122960122961122962122963122964122965122966122967122968122969122970122971122972122973122974122975122976122977122978122979122980122981122982122983122984122985122986122987122988122989122990122991122992122993122994122995122996122997122998122999123000123001123002123003123004123005123006123007123008123009123010123011123012123013123014123015123016123017123018123019123020123021123022123023123024123025123026123027123028123029123030123031123032123033123034123035123036123037123038123039123040123041123042123043123044123045123046123047123048123049123050123051123052123053123054123055123056123057123058123059123060123061123062123063123064123065123066123067123068123069123070123071123072123073123074123075123076123077123078123079123080123081123082123083123084123085123086123087123088123089123090123091123092123093123094123095123096123097123098123099123100123101123102123103123104123105123106123107123108123109123110123111123112123113123114123115123116123117123118123119123120123121123122123123123124123125123126123127123128123129123130123131123132123133123134123135123136123137123138123139123140123141123142123143123144123145123146123147123148123149123150123151123152123153123154123155123156123157123158123159123160123161123162123163123164123165123166123167123168123169123170123171123172123173123174123175123176123177123178123179123180123181123182123183123184123185123186123187123188123189123190123191123192123193123194123195123196123197123198123199123200123201123202123203123204123205123206123207123208123209123210123211123212123213123214123215123216123217123218123219123220123221123222123223123224123225123226123227123228123229123230123231123232123233123234123235123236123237123238123239123240123241123242123243123244123245123246123247123248123249123250123251123252123253123254123255123256123257123258123259123260123261123262123263123264123265123266123267123268123269123270123271123272123273123274123275123276123277123278123279123280123281123282123283123284123285123286123287123288123289123290123291123292123293123294123295123296123297123298123299123300123301123302123303123304123305123306123307123308123309123310123311123312123313123314123315123316123317123318123319123320123321123322123323123324123325123326123327123328123329123330123331123332123333123334123335123336123337123338123339123340123341123342123343123344123345123346123347123348123349123350123351123352123353123354123355123356123357123358123359123360123361123362123363123364123365123366123367123368123369123370123371123372123373123374123375123376123377123378123379123380123381123382123383123384123385123386123387123388123389123390123391123392123393123394123395123396123397123398123399123400123401123402123403123404123405123406123407123408123409123410123411123412123413123414123415123416123417123418123419123420123421123422123423123424123425123426123427123428123429123430123431123432123433123434123435123436123437123438123439123440123441123442123443123444123445123446123447123448123449123450123451123452123453123454123455123456123457123458123459123460123461123462123463123464123465123466123467123468123469123470123471123472123473123474123475123476123477123478123479123480123481123482123483123484123485123486123487123488123489123490123491123492123493123494123495123496123497123498123499123500123501123502123503123504123505123506123507123508123509123510123511123512123513123514123515123516123517123518123519123520123521123522123523123524123525123526123527123528123529123530123531123532123533123534123535123536123537123538123539123540123541123542123543123544123545123546123547123548123549123550123551123552123553123554123555123556123557123558123559123560123561123562123563123564123565123566123567123568123569123570123571123572123573123574123575123576123577123578123579123580123581123582123583123584123585123586123587123588123589123590123591123592123593123594123595123596123597123598123599123600123601123602123603123604123605123606123607123608123609123610123611123612123613123614123615123616123617123618123619123620123621123622123623123624123625123626123627123628123629123630123631123632123633123634123635123636123637123638123639123640123641123642123643123644123645123646123647123648123649123650123651123652123653123654123655123656123657123658123659123660123661123662123663123664123665123666123667123668123669123670123671123672123673123674123675123676123677123678123679123680123681123682123683123684123685123686123687123688123689123690123691123692123693123694123695123696123697123698123699123700123701123702123703123704123705123706123707123708123709123710123711123712123713123714123715123716123717123718123719123720123721123722123723123724123725123726123727123728123729123730123731123732123733123734123735123736123737123738123739123740123741123742123743123744123745123746123747123748123749123750123751123752123753123754123755123756123757123758123759123760123761123762123763123764123765123766123767123768123769123770123771123772123773123774123775123776123777123778123779123780123781123782123783123784123785123786123787123788123789123790123791123792123793123794123795123796123797123798123799123800123801123802123803123804123805123806123807123808123809123810123811123812123813123814123815123816123817123818123819123820123821123822123823123824123825123826123827123828123829123830123831123832123833123834123835123836123837123838123839123840123841123842123843123844123845123846123847123848123849123850123851123852123853123854123855123856123857123858123859123860123861123862123863123864123865123866123867123868123869123870123871123872123873123874123875123876123877123878123879123880123881123882123883123884123885123886123887123888123889123890123891123892123893123894123895123896123897123898123899123900123901123902123903123904123905123906123907123908123909123910123911123912123913123914123915123916123917123918123919123920123921123922123923123924123925123926123927123928123929123930123931123932123933123934123935123936123937123938123939123940123941123942123943123944123945123946123947123948123949123950123951123952123953123954123955123956123957123958123959123960123961123962123963123964123965123966123967123968123969123970123971123972123973123974123975123976123977123978123979123980123981123982123983123984123985123986123987123988123989123990123991123992123993123994123995123996123997123998123999124000124001124002124003124004124005124006124007124008124009124010124011124012124013124014124015124016124017124018124019124020124021124022124023124024124025124026124027124028124029124030124031124032124033124034124035124036124037124038124039124040124041124042124043124044124045124046124047124048124049124050124051124052124053124054124055124056124057124058124059124060124061124062124063124064124065124066124067124068124069124070124071124072124073124074124075124076124077124078124079124080124081124082124083124084124085124086124087124088124089124090124091124092124093124094124095124096124097124098124099124100124101124102124103124104124105124106124107124108124109124110124111124112124113124114124115124116124117124118124119124120124121124122124123124124124125124126124127124128124129124130124131124132124133124134124135124136124137124138124139124140124141124142124143124144124145124146124147124148124149124150124151124152124153124154124155124156124157124158124159124160124161124162124163124164124165124166124167124168124169124170124171124172124173124174124175124176124177124178124179124180124181124182124183124184124185124186124187124188124189124190124191124192124193124194124195124196124197124198124199124200124201124202124203124204124205124206124207124208124209124210124211124212124213124214124215124216124217124218124219124220124221124222124223124224124225124226124227124228124229124230124231124232124233124234124235124236124237124238124239124240124241124242124243124244124245124246124247124248124249124250124251124252124253124254124255124256124257124258124259124260124261124262124263124264124265124266124267124268124269124270124271124272124273124274124275124276124277124278124279124280124281124282124283124284124285124286124287124288124289124290124291124292124293124294124295124296124297124298124299124300124301124302124303124304124305124306124307124308124309124310124311124312124313124314124315124316124317124318124319124320124321124322124323124324124325124326124327124328124329124330124331124332124333124334124335124336124337124338124339124340124341124342124343124344124345124346124347124348124349124350124351124352124353124354124355124356124357124358124359124360124361124362124363124364124365124366124367124368124369124370124371124372124373124374124375124376124377124378124379124380124381124382124383124384124385124386124387124388124389124390124391124392124393124394124395124396124397124398124399124400124401124402124403124404124405124406124407124408124409124410124411124412124413124414124415124416124417124418124419124420124421124422124423124424124425124426124427124428124429124430124431124432124433124434124435124436124437124438124439124440124441124442124443124444124445124446124447124448124449124450124451124452124453124454124455124456124457124458124459124460124461124462124463124464124465124466124467124468124469124470124471124472124473124474124475124476124477124478124479124480124481124482124483124484124485124486124487124488124489124490124491124492124493124494124495124496124497124498124499124500124501124502124503124504124505124506124507124508124509124510124511124512124513124514124515124516124517124518124519124520124521124522124523124524124525124526124527124528124529124530124531124532124533124534124535124536124537124538124539124540124541124542124543124544124545124546124547124548124549124550124551124552124553124554124555124556124557124558124559124560124561124562124563124564124565124566124567124568124569124570124571124572124573124574124575124576124577124578124579124580124581124582124583124584124585124586124587124588124589124590124591124592124593124594124595124596124597124598124599124600124601124602124603124604124605124606124607124608124609124610124611124612124613124614124615124616124617124618124619124620124621124622124623124624124625124626124627124628124629124630124631124632124633124634124635124636124637124638124639124640124641124642124643124644124645124646124647124648124649124650124651124652124653124654124655124656124657124658124659124660124661124662124663124664124665124666124667124668124669124670124671124672124673124674124675124676124677124678124679124680124681124682124683124684124685124686124687124688124689124690124691124692124693124694124695124696124697124698124699124700124701124702124703124704124705124706124707124708124709124710124711124712124713124714124715124716124717124718124719124720124721124722124723124724124725124726124727124728124729124730124731124732124733124734124735124736124737124738124739124740124741124742124743124744124745124746124747124748124749124750124751124752124753124754124755124756124757124758124759124760124761124762124763124764124765124766124767124768124769124770124771124772124773124774124775124776124777124778124779124780124781124782124783124784124785124786124787124788124789124790124791124792124793124794124795124796124797124798124799124800124801124802124803124804124805124806124807124808124809124810124811124812124813124814124815124816124817124818124819124820124821124822124823124824124825124826124827124828124829124830124831124832124833124834124835124836124837124838124839124840124841124842124843124844124845124846124847124848124849124850124851124852124853124854124855124856124857124858124859124860124861124862124863124864124865124866124867124868124869124870124871124872124873124874124875124876124877124878124879124880124881124882124883124884124885124886124887124888124889124890124891124892124893124894124895124896124897124898124899124900124901124902124903124904124905124906124907124908124909124910124911124912124913124914124915124916124917124918124919124920124921124922124923124924124925124926124927124928124929124930124931124932124933124934124935124936124937124938124939124940124941124942124943124944124945124946124947124948124949124950124951124952124953124954124955124956124957124958124959124960124961124962124963124964124965124966124967124968124969124970124971124972124973124974124975124976124977124978124979124980124981124982124983124984124985124986124987124988124989124990124991124992124993124994124995124996124997124998124999125000125001125002125003125004125005125006125007125008125009125010125011125012125013125014125015125016125017125018125019125020125021125022125023125024125025125026125027125028125029125030125031125032125033125034125035125036125037125038125039125040125041125042125043125044125045125046125047125048125049125050125051125052125053125054125055125056125057125058125059125060125061125062125063125064125065125066125067125068125069125070125071125072125073125074125075125076125077125078125079125080125081125082125083125084125085125086125087125088125089125090125091125092125093125094125095125096125097125098125099125100125101125102125103125104125105125106125107125108125109125110125111125112125113125114125115125116125117125118125119125120125121125122125123125124125125125126125127125128125129125130125131125132125133125134125135125136125137125138125139125140125141125142125143125144125145125146125147125148125149125150125151125152125153125154125155125156125157125158125159125160125161125162125163125164125165125166125167125168125169125170125171125172125173125174125175125176125177125178125179125180125181125182125183125184125185125186125187125188125189125190125191125192125193125194125195125196125197125198125199125200125201125202125203125204125205125206125207125208125209125210125211125212125213125214125215125216125217125218125219125220125221125222125223125224125225125226125227125228125229125230125231125232125233125234125235125236125237125238125239125240125241125242125243125244125245125246125247125248125249125250125251125252125253125254125255125256125257125258125259125260125261125262125263125264125265125266125267125268125269125270125271125272125273125274125275125276125277125278125279125280125281125282125283125284125285125286125287125288125289125290125291125292125293125294125295125296125297125298125299125300125301125302125303125304125305125306125307125308125309125310125311125312125313125314125315125316125317125318125319125320125321125322125323125324125325125326125327125328125329125330125331125332125333125334125335125336125337125338125339125340125341125342125343125344125345125346125347125348125349125350125351125352125353125354125355125356125357125358125359125360125361125362125363125364125365125366125367125368125369125370125371125372125373125374125375125376125377125378125379125380125381125382125383125384125385125386125387125388125389125390125391125392125393125394125395125396125397125398125399125400125401125402125403125404125405125406125407125408125409125410125411125412125413125414125415125416125417125418125419125420125421125422125423125424125425125426125427125428125429125430125431125432125433125434125435125436125437125438125439125440125441125442125443125444125445125446125447125448125449125450125451125452125453125454125455125456125457125458125459125460125461125462125463125464125465125466125467125468125469125470125471125472125473125474125475125476125477125478125479125480125481125482125483125484125485125486125487125488125489125490125491125492125493125494125495125496125497125498125499125500125501125502125503125504125505125506125507125508125509125510125511125512125513125514125515125516125517125518125519125520125521125522125523125524125525125526125527125528125529125530125531125532125533125534125535125536125537125538125539125540125541125542125543125544125545125546125547125548125549125550125551125552125553125554125555125556125557125558125559125560125561125562125563125564125565125566125567125568125569125570125571125572125573125574125575125576125577125578125579125580125581125582125583125584125585125586125587125588125589125590125591125592125593125594125595125596125597125598125599125600125601125602125603125604125605125606125607125608125609125610125611125612125613125614125615125616125617125618125619125620125621125622125623125624125625125626125627125628125629125630125631125632125633125634125635125636125637125638125639125640125641125642125643125644125645125646125647125648125649125650125651125652125653125654125655125656125657125658125659125660125661125662125663125664125665125666125667125668125669125670125671125672125673125674125675125676125677125678125679125680125681125682125683125684125685125686125687125688125689125690125691125692125693125694125695125696125697125698125699125700125701125702125703125704125705125706125707125708125709125710125711125712125713125714125715125716125717125718125719125720125721125722125723125724125725125726125727125728125729125730125731125732125733125734125735125736125737125738125739125740125741125742125743125744125745125746125747125748125749125750125751125752125753125754125755125756125757125758125759125760125761125762125763125764125765125766125767125768125769125770125771125772125773125774125775125776125777125778125779125780125781125782125783125784125785125786125787125788125789125790125791125792125793125794125795125796125797125798125799125800125801125802125803125804125805125806125807125808125809125810125811125812125813125814125815125816125817125818125819125820125821125822125823125824125825125826125827125828125829125830125831125832125833125834125835125836125837125838125839125840125841125842125843125844125845125846125847125848125849125850125851125852125853125854125855125856125857125858125859125860125861125862125863125864125865125866125867125868125869125870125871125872125873125874125875125876125877125878125879125880125881125882125883125884125885125886125887125888125889125890125891125892125893125894125895125896125897125898125899125900125901125902125903125904125905125906125907125908125909125910125911125912125913125914125915125916125917125918125919125920125921125922125923125924125925125926125927125928125929125930125931125932125933125934125935125936125937125938125939125940125941125942125943125944125945125946125947125948125949125950125951125952125953125954125955125956125957125958125959125960125961125962125963125964125965125966125967125968125969125970125971125972125973125974125975125976125977125978125979125980125981125982125983125984125985125986125987125988125989125990125991125992125993125994125995125996125997125998125999126000126001126002126003126004126005126006126007126008126009126010126011126012126013126014126015126016126017126018126019126020126021126022126023126024126025126026126027126028126029126030126031126032126033126034126035126036126037126038126039126040126041126042126043126044126045126046126047126048126049126050126051126052126053126054126055126056126057126058126059126060126061126062126063126064126065126066126067126068126069126070126071126072126073126074126075126076126077126078126079126080126081126082126083126084126085126086126087126088126089126090126091126092126093126094126095126096126097126098126099126100126101126102126103126104126105126106126107126108126109126110126111126112126113126114126115126116126117126118126119126120126121126122126123126124126125126126126127126128126129126130126131126132126133126134126135126136126137126138126139126140126141126142126143126144126145126146126147126148126149126150126151126152126153126154126155126156126157126158126159126160126161126162126163126164126165126166126167126168126169126170126171126172126173126174126175126176126177126178126179126180126181126182126183126184126185126186126187126188126189126190126191126192126193126194126195126196126197126198126199126200126201126202126203126204126205126206126207126208126209126210126211126212126213126214126215126216126217126218126219126220126221126222126223126224126225126226126227126228126229126230126231126232126233126234126235126236126237126238126239126240126241126242126243126244126245126246126247126248126249126250126251126252126253126254126255126256126257126258126259126260126261126262126263126264126265126266126267126268126269126270126271126272126273126274126275126276126277126278126279126280126281126282126283126284126285126286126287126288126289126290126291126292126293126294126295126296126297126298126299126300126301126302126303126304126305126306126307126308126309126310126311126312126313126314126315126316126317126318126319126320126321126322126323126324126325126326126327126328126329126330126331126332126333126334126335126336126337126338126339126340126341126342126343126344126345126346126347126348126349126350126351126352126353126354126355126356126357126358126359126360126361126362126363126364126365126366126367126368126369126370126371126372126373126374126375126376126377126378126379126380126381126382126383126384126385126386126387126388126389126390126391126392126393126394126395126396126397126398126399126400126401126402126403126404126405126406126407126408126409126410126411126412126413126414126415126416126417126418126419126420126421126422126423126424126425126426126427126428126429126430126431126432126433126434126435126436126437126438126439126440126441126442126443126444126445126446126447126448126449126450126451126452126453126454126455126456126457126458126459126460126461126462126463126464126465126466126467126468126469126470126471126472126473126474126475126476126477126478126479126480126481126482126483126484126485126486126487126488126489126490126491126492126493126494126495126496126497126498126499126500126501126502126503126504126505126506126507126508126509126510126511126512126513126514126515126516126517126518126519126520126521126522126523126524126525126526126527126528126529126530126531126532126533126534126535126536126537126538126539126540126541126542126543126544126545126546126547126548126549126550126551126552126553126554126555126556126557126558126559126560126561126562126563126564126565126566126567126568126569126570126571126572126573126574126575126576126577126578126579126580126581126582126583126584126585126586126587126588126589126590126591126592126593126594126595126596126597126598126599126600126601126602126603126604126605126606126607126608126609126610126611126612126613126614126615126616126617126618126619126620126621126622126623126624126625126626126627126628126629126630126631126632126633126634126635126636126637126638126639126640126641126642126643126644126645126646126647126648126649126650126651126652126653126654126655126656126657126658126659126660126661126662126663126664126665126666126667126668126669126670126671126672126673126674126675126676126677126678126679126680126681126682126683126684126685126686126687126688126689126690126691126692126693126694126695126696126697126698126699126700126701126702126703126704126705126706126707126708126709126710126711126712126713126714126715126716126717126718126719126720126721126722126723126724126725126726126727126728126729126730126731126732126733126734126735126736126737126738126739126740126741126742126743126744126745126746126747126748126749126750126751126752126753126754126755126756126757126758126759126760126761126762126763126764126765126766126767126768126769126770126771126772126773126774126775126776126777126778126779126780126781126782126783126784126785126786126787126788126789126790126791126792126793126794126795126796126797126798126799126800126801126802126803126804126805126806126807126808126809126810126811126812126813126814126815126816126817126818126819126820126821126822126823126824126825126826126827126828126829126830126831126832126833126834126835126836126837126838126839126840126841126842126843126844126845126846126847126848126849126850126851126852126853126854126855126856126857126858126859126860126861126862126863126864126865126866126867126868126869126870126871126872126873126874126875126876126877126878126879126880126881126882126883126884126885126886126887126888126889126890126891126892126893126894126895126896126897126898126899126900126901126902126903126904126905126906126907126908126909126910126911126912126913126914126915126916126917126918126919126920126921126922126923126924126925126926126927126928126929126930126931126932126933126934126935126936126937126938126939126940126941126942126943126944126945126946126947126948126949126950126951126952126953126954126955126956126957126958126959126960126961126962126963126964126965126966126967126968126969126970126971126972126973126974126975126976126977126978126979126980126981126982126983126984126985126986126987126988126989126990126991126992126993126994126995126996126997126998126999127000127001127002127003127004127005127006127007127008127009127010127011127012127013127014127015127016127017127018127019127020127021127022127023127024127025127026127027127028127029127030127031127032127033127034127035127036127037127038127039127040127041127042127043127044127045127046127047127048127049127050127051127052127053127054127055127056127057127058127059127060127061127062127063127064127065127066127067127068127069127070127071127072127073127074127075127076127077127078127079127080127081127082127083127084127085127086127087127088127089127090127091127092127093127094127095127096127097127098127099127100127101127102127103127104127105127106127107127108127109127110127111127112127113127114127115127116127117127118127119127120127121127122127123127124127125127126127127127128127129127130127131127132127133127134127135127136127137127138127139127140127141127142127143127144127145127146127147127148127149127150127151127152127153127154127155127156127157127158127159127160127161127162127163127164127165127166127167127168127169127170127171127172127173127174127175127176127177127178127179127180127181127182127183127184127185127186127187127188127189127190127191127192127193127194127195127196127197127198127199127200127201127202127203127204127205127206127207127208127209127210127211127212127213127214127215127216127217127218127219127220127221127222127223127224127225127226127227127228127229127230127231127232127233127234127235127236127237127238127239127240127241127242127243127244127245127246127247127248127249127250127251127252127253127254127255127256127257127258127259127260127261127262127263127264127265127266127267127268127269127270127271127272127273127274127275127276127277127278127279127280127281127282127283127284127285127286127287127288127289127290127291127292127293127294127295127296127297127298127299127300127301127302127303127304127305127306127307127308127309127310127311127312127313127314127315127316127317127318127319127320127321127322127323127324127325127326127327127328127329127330127331127332127333127334127335127336127337127338127339127340127341127342127343127344127345127346127347127348127349127350127351127352127353127354127355127356127357127358127359127360127361127362127363127364127365127366127367127368127369127370127371127372127373127374127375127376127377127378127379127380127381127382127383127384127385127386127387127388127389127390127391127392127393127394127395127396127397127398127399127400127401127402127403127404127405127406127407127408127409127410127411127412127413127414127415127416127417127418127419127420127421127422127423127424127425127426127427127428127429127430127431127432127433127434127435127436127437127438127439127440127441127442127443127444127445127446127447127448127449127450127451127452127453127454127455127456127457127458127459127460127461127462127463127464127465127466127467127468127469127470127471127472127473127474127475127476127477127478127479127480127481127482127483127484127485127486127487127488127489127490127491127492127493127494127495127496127497127498127499127500127501127502127503127504127505127506127507127508127509127510127511127512127513127514127515127516127517127518127519127520127521127522127523127524127525127526127527127528127529127530127531127532127533127534127535127536127537127538127539127540127541127542127543127544127545127546127547127548127549127550127551127552127553127554127555127556127557127558127559127560127561127562127563127564127565127566127567127568127569127570127571127572127573127574127575127576127577127578127579127580127581127582127583127584127585127586127587127588127589127590127591127592127593127594127595127596127597127598127599127600127601127602127603127604127605127606127607127608127609127610127611127612127613127614127615127616127617127618127619127620127621127622127623127624127625127626127627127628127629127630127631127632127633127634127635127636127637127638127639127640127641127642127643127644127645127646127647127648127649127650127651127652127653127654127655127656127657127658127659127660127661127662127663127664127665127666127667127668127669127670127671127672127673127674127675127676127677127678127679127680127681127682127683127684127685127686127687127688127689127690127691127692127693127694127695127696127697127698127699127700127701127702127703127704127705127706127707127708127709127710127711127712127713127714127715127716127717127718127719127720127721127722127723127724127725127726127727127728127729127730127731127732127733127734127735127736127737127738127739127740127741127742127743127744127745127746127747127748127749127750127751127752127753127754127755127756127757127758127759127760127761127762127763127764127765127766127767127768127769127770127771127772127773127774127775127776127777127778127779127780127781127782127783127784127785127786127787127788127789127790127791127792127793127794127795127796127797127798127799127800127801127802127803127804127805127806127807127808127809127810127811127812127813127814127815127816127817127818127819127820127821127822127823127824127825127826127827127828127829127830127831127832127833127834127835127836127837127838127839127840127841127842127843127844127845127846127847127848127849127850127851127852127853127854127855127856127857127858127859127860127861127862127863127864127865127866127867127868127869127870127871127872127873127874127875127876127877127878127879127880127881127882127883127884127885127886127887127888127889127890127891127892127893127894127895127896127897127898127899127900127901127902127903127904127905127906127907127908127909127910127911127912127913127914127915127916127917127918127919127920127921127922127923127924127925127926127927127928127929127930127931127932127933127934127935127936127937127938127939127940127941127942127943127944127945127946127947127948127949127950127951127952127953127954127955127956127957127958127959127960127961127962127963127964127965127966127967127968127969127970127971127972127973127974127975127976127977127978127979127980127981127982127983127984127985127986127987127988127989127990127991127992127993127994127995127996127997127998127999128000128001128002128003128004128005128006128007128008128009128010128011128012128013128014128015128016128017128018128019128020128021128022128023128024128025128026128027128028128029128030128031128032128033128034128035128036128037128038128039128040128041128042128043128044128045128046128047128048128049128050128051128052128053128054128055128056128057128058128059128060128061128062128063128064128065128066128067128068128069128070128071128072128073128074128075128076128077128078128079128080128081128082128083128084128085128086128087128088128089128090128091128092128093128094128095128096128097128098128099128100128101128102128103128104128105128106128107128108128109128110128111128112128113128114128115128116128117128118128119128120128121128122128123128124128125128126128127128128128129128130128131128132128133128134128135128136128137128138128139128140128141128142128143128144128145128146128147128148128149128150128151128152128153128154128155128156128157128158128159128160128161128162128163128164128165128166128167128168128169128170128171128172128173128174128175128176128177128178128179128180128181128182128183128184128185128186128187128188128189128190128191128192128193128194128195128196128197128198128199128200128201128202128203128204128205128206128207128208128209128210128211128212128213128214128215128216128217128218128219128220128221128222128223128224128225128226128227128228128229128230128231128232128233128234128235128236128237128238128239128240128241128242128243128244128245128246128247128248128249128250128251128252128253128254128255128256128257128258128259128260128261128262128263128264128265128266128267128268128269128270128271128272128273128274128275128276128277128278128279128280128281128282128283128284128285128286128287128288128289128290128291128292128293128294128295128296128297128298128299128300128301128302128303128304128305128306128307128308128309128310128311128312128313128314128315128316128317128318128319128320128321128322128323128324128325128326128327128328128329128330128331128332128333128334128335128336128337128338128339128340128341128342128343128344128345128346128347128348128349128350128351128352128353128354128355128356128357128358128359128360128361128362128363128364128365128366128367128368128369128370128371128372128373128374128375128376128377128378128379128380128381128382128383128384128385128386128387128388128389128390128391128392128393128394128395128396128397128398128399128400128401128402128403128404128405128406128407128408128409128410128411128412128413128414128415128416128417128418128419128420128421128422128423128424128425128426128427128428128429128430128431128432128433128434128435128436128437128438128439128440128441128442128443128444128445128446128447128448128449128450128451128452128453128454128455128456128457128458128459128460128461128462128463128464128465128466128467128468128469128470128471128472128473128474128475128476128477128478128479128480128481128482128483128484128485128486128487128488128489128490128491128492128493128494128495128496128497128498128499128500128501128502128503128504128505128506128507128508128509128510128511128512128513128514128515128516128517128518128519128520128521128522128523128524128525128526128527128528128529128530128531128532128533128534128535128536128537128538128539128540128541128542128543128544128545128546128547128548128549128550128551128552128553128554128555128556128557128558128559128560128561128562128563128564128565128566128567128568128569128570128571128572128573128574128575128576128577128578128579128580128581128582128583128584128585128586128587128588128589128590128591128592128593128594128595128596128597128598128599128600128601128602128603128604128605128606128607128608128609128610128611128612128613128614128615128616128617128618128619128620128621128622128623128624128625128626128627128628128629128630128631128632128633128634128635128636128637128638128639128640128641128642128643128644128645128646128647128648128649128650128651128652128653128654128655128656128657128658128659128660128661128662128663128664128665128666128667128668128669128670128671128672128673128674128675128676128677128678128679128680128681128682128683128684128685128686128687128688128689128690128691128692128693128694128695128696128697128698128699128700128701128702128703128704128705128706128707128708128709128710128711128712128713128714128715128716128717128718128719128720128721128722128723128724128725128726128727128728128729128730128731128732128733128734128735128736128737128738128739128740128741128742128743128744128745128746128747128748128749128750128751128752128753128754128755128756128757128758128759128760128761128762128763128764128765128766128767128768128769128770128771128772128773128774128775128776128777128778128779128780128781128782128783128784128785128786128787128788128789128790128791128792128793128794128795128796128797128798128799128800128801128802128803128804128805128806128807128808128809128810128811128812128813128814128815128816128817128818128819128820128821128822128823128824128825128826128827128828128829128830128831128832128833128834128835128836128837128838128839128840128841128842128843128844128845128846128847128848128849128850128851128852128853128854128855128856128857128858128859128860128861128862128863128864128865128866128867128868128869128870128871128872128873128874128875128876128877128878128879128880128881128882128883128884128885128886128887128888128889128890128891128892128893128894128895128896128897128898128899128900128901128902128903128904128905128906128907128908128909128910128911128912128913128914128915128916128917128918128919128920128921128922128923128924128925128926128927128928128929128930128931128932128933128934128935128936128937128938128939128940128941128942128943128944128945128946128947128948128949128950128951128952128953128954128955128956128957128958128959128960128961128962128963128964128965128966128967128968128969128970128971128972128973128974128975128976128977128978128979128980128981128982128983128984128985128986128987128988128989128990128991128992128993128994128995128996128997128998128999129000129001129002129003129004129005129006129007129008129009129010129011129012129013129014129015129016129017129018129019129020129021129022129023129024129025129026129027129028129029129030129031129032129033129034129035129036129037129038129039129040129041129042129043129044129045129046129047129048129049129050129051129052129053129054129055129056129057129058129059129060129061129062129063129064129065129066129067129068129069129070129071129072129073129074129075129076129077129078129079129080129081129082129083129084129085129086129087129088129089129090129091129092129093129094129095129096129097129098129099129100129101129102129103129104129105129106129107129108129109129110129111129112129113129114129115129116129117129118129119129120129121129122129123129124129125129126129127129128129129129130129131129132129133129134129135129136129137129138129139129140129141129142129143129144129145129146129147129148129149129150129151129152129153129154129155129156129157129158129159129160129161129162129163129164129165129166129167129168129169129170129171129172129173129174129175129176129177129178129179129180129181129182129183129184129185129186129187129188129189129190129191129192129193129194129195129196129197129198129199129200129201129202129203129204129205129206129207129208129209129210129211129212129213129214129215129216129217129218129219129220129221129222129223129224129225129226129227129228129229129230129231129232129233129234129235129236129237129238129239129240129241129242129243129244129245129246129247129248129249129250129251129252129253129254129255129256129257129258129259129260129261129262129263129264129265129266129267129268129269129270129271129272129273129274129275129276129277129278129279129280129281129282129283129284129285129286129287129288129289129290129291129292129293129294129295129296129297129298129299129300129301129302129303129304129305129306129307129308129309129310129311129312129313129314129315129316129317129318129319129320129321129322129323129324129325129326129327129328129329129330129331129332129333129334129335129336129337129338129339129340129341129342129343129344129345129346129347129348129349129350129351129352129353129354129355129356129357129358129359129360129361129362129363129364129365129366129367129368129369129370129371129372129373129374129375129376129377129378129379129380129381129382129383129384129385129386129387129388129389129390129391129392129393129394129395129396129397129398129399129400129401129402129403129404129405129406129407129408129409129410129411129412129413129414129415129416129417129418129419129420129421129422129423129424129425129426129427129428129429129430129431129432129433129434129435129436129437129438129439129440129441129442129443129444129445129446129447129448129449129450129451129452129453129454129455129456129457129458129459129460129461129462129463129464129465129466129467129468129469129470129471129472129473129474129475129476129477129478129479129480129481129482129483129484129485129486129487129488129489129490129491129492129493129494129495129496129497129498129499129500129501129502129503129504129505129506129507129508129509129510129511129512129513129514129515129516129517129518129519129520129521129522129523129524129525129526129527129528129529129530129531129532129533129534129535129536129537129538129539129540129541129542129543129544129545129546129547129548129549129550129551129552129553129554129555129556129557129558129559129560129561129562129563129564129565129566129567129568129569129570129571129572129573129574129575129576129577129578129579129580129581129582129583129584129585129586129587129588129589129590129591129592129593129594129595129596129597129598129599129600129601129602129603129604129605129606129607129608129609129610129611129612129613129614129615129616129617129618129619129620129621129622129623129624129625129626129627129628129629129630129631129632129633129634129635129636129637129638129639129640129641129642129643129644129645129646129647129648129649129650129651129652129653129654129655129656129657129658129659129660129661129662129663129664129665129666129667129668129669129670129671129672129673129674129675129676129677129678129679129680129681129682129683129684129685129686129687129688129689129690129691129692129693129694129695129696129697129698129699129700129701129702129703129704129705129706129707129708129709129710129711129712129713129714129715129716129717129718129719129720129721129722129723129724129725129726129727129728129729129730129731129732129733129734129735129736129737129738129739129740129741129742129743129744129745129746129747129748129749129750129751129752129753129754129755129756129757129758129759129760129761129762129763129764129765129766129767129768129769129770129771129772129773129774129775129776129777129778129779129780129781129782129783129784129785129786129787129788129789129790129791129792129793129794129795129796129797129798129799129800129801129802129803129804129805129806129807129808129809129810129811129812129813129814129815129816129817129818129819129820129821129822129823129824129825129826129827129828129829129830129831129832129833129834129835129836129837129838129839129840129841129842129843129844129845129846129847129848129849129850129851129852129853129854129855129856129857129858129859129860129861129862129863129864129865129866129867129868129869129870129871129872129873129874129875129876129877129878129879129880129881129882129883129884129885129886129887129888129889129890129891129892129893129894129895129896129897129898129899129900129901129902129903129904129905129906129907129908129909129910129911129912129913129914129915129916129917129918129919129920129921129922129923129924129925129926129927129928129929129930129931129932129933129934129935129936129937129938129939129940129941129942129943129944129945129946129947129948129949129950129951129952129953129954129955129956129957129958129959129960129961129962129963129964129965129966129967129968129969129970129971129972129973129974129975129976129977129978129979129980129981129982129983129984129985129986129987129988129989129990129991129992129993129994129995129996129997129998129999130000130001130002130003130004130005130006130007130008130009130010130011130012130013130014130015130016130017130018130019130020130021130022130023130024130025130026130027130028130029130030130031130032130033130034130035130036130037130038130039130040130041130042130043130044130045130046130047130048130049130050130051130052130053130054130055130056130057130058130059130060130061130062130063130064130065130066130067130068130069130070130071130072130073130074130075130076130077130078130079130080130081130082130083130084130085130086130087130088130089130090130091130092130093130094130095130096130097130098130099130100130101130102130103130104130105130106130107130108130109130110130111130112130113130114130115130116130117130118130119130120130121130122130123130124130125130126130127130128130129130130130131130132130133130134130135130136130137130138130139130140130141130142130143130144130145130146130147130148130149130150130151130152130153130154130155130156130157130158130159130160130161130162130163130164130165130166130167130168130169130170130171130172130173130174130175130176130177130178130179130180130181130182130183130184130185130186130187130188130189130190130191130192130193130194130195130196130197130198130199130200130201130202130203130204130205130206130207130208130209130210130211130212130213130214130215130216130217130218130219130220130221130222130223130224130225130226130227130228130229130230130231130232130233130234130235130236130237130238130239130240130241130242130243130244130245130246130247130248130249130250130251130252130253130254130255130256130257130258130259130260130261130262130263130264130265130266130267130268130269130270130271130272130273130274130275130276130277130278130279130280130281130282130283130284130285130286130287130288130289130290130291130292130293130294130295130296130297130298130299130300130301130302130303130304130305130306130307130308130309130310130311130312130313130314130315130316130317130318130319130320130321130322130323130324130325130326130327130328130329130330130331130332130333130334130335130336130337130338130339130340130341130342130343130344130345130346130347130348130349130350130351130352130353130354130355130356130357130358130359130360130361130362130363130364130365130366130367130368130369130370130371130372130373130374130375130376130377130378130379130380130381130382130383130384130385130386130387130388130389130390130391130392130393130394130395130396130397130398130399130400130401130402130403130404130405130406130407130408130409130410130411130412130413130414130415130416130417130418130419130420130421130422130423130424130425130426130427130428130429130430130431130432130433130434130435130436130437130438130439130440130441130442130443130444130445130446130447130448130449130450130451130452130453130454130455130456130457130458130459130460130461130462130463130464130465130466130467130468130469130470130471130472130473130474130475130476130477130478130479130480130481130482130483130484130485130486130487130488130489130490130491130492130493130494130495130496130497130498130499130500130501130502130503130504130505130506130507130508130509130510130511130512130513130514130515130516130517130518130519130520130521130522130523130524130525130526130527130528130529130530130531130532130533130534130535130536130537130538130539130540130541130542130543130544130545130546130547130548130549130550130551130552130553130554130555130556130557130558130559130560130561130562130563130564130565130566130567130568130569130570130571130572130573130574130575130576130577130578130579130580130581130582130583130584130585130586130587130588130589130590130591130592130593130594130595130596130597130598130599130600130601130602130603130604130605130606130607130608130609130610130611130612130613130614130615130616130617130618130619130620130621130622130623130624130625130626130627130628130629130630130631130632130633130634130635130636130637130638130639130640130641130642130643130644130645130646130647130648130649130650130651130652130653130654130655130656130657130658130659130660130661130662130663130664130665130666130667130668130669130670130671130672130673130674130675130676130677130678130679130680130681130682130683130684130685130686130687130688130689130690130691130692130693130694130695130696130697130698130699130700130701130702130703130704130705130706130707130708130709130710130711130712130713130714130715130716130717130718130719130720130721130722130723130724130725130726130727130728130729130730130731130732130733130734130735130736130737130738130739130740130741130742130743130744130745130746130747130748130749130750130751130752130753130754130755130756130757130758130759130760130761130762130763130764130765130766130767130768130769130770130771130772130773130774130775130776130777130778130779130780130781130782130783130784130785130786130787130788130789130790130791130792130793130794130795130796130797130798130799130800130801130802130803130804130805130806130807130808130809130810130811130812130813130814130815130816130817130818130819130820130821130822130823130824130825130826130827130828130829130830130831130832130833130834130835130836130837130838130839130840130841130842130843130844130845130846130847130848130849130850130851130852130853130854130855130856130857130858130859130860130861130862130863130864130865130866130867130868130869130870130871130872130873130874130875130876130877130878130879130880130881130882130883130884130885130886130887130888130889130890130891130892130893130894130895130896130897130898130899130900130901130902130903130904130905130906130907130908130909130910130911130912130913130914130915130916130917130918130919130920130921130922130923130924130925130926130927130928130929130930130931130932130933130934130935130936130937130938130939130940130941130942130943130944130945130946130947130948130949130950130951130952130953130954130955130956130957130958130959130960130961130962130963130964130965130966130967130968130969130970130971130972130973130974130975130976130977130978130979130980130981130982130983130984130985130986130987130988130989130990130991130992130993130994130995130996130997130998130999131000131001131002131003131004131005131006131007131008131009131010131011131012131013131014131015131016131017131018131019131020131021131022131023131024131025131026131027131028131029131030131031131032131033131034131035131036131037131038131039131040131041131042131043131044131045131046131047131048131049131050131051131052131053131054131055131056131057131058131059131060131061131062131063131064131065131066131067131068131069131070131071131072131073131074131075131076131077131078131079131080131081131082131083131084131085131086131087131088131089131090131091131092131093131094131095131096131097131098131099131100131101131102131103131104131105131106131107131108131109131110131111131112131113131114131115131116131117131118131119131120131121131122131123131124131125131126131127131128131129131130131131131132131133131134131135131136131137131138131139131140131141131142131143131144131145131146131147131148131149131150131151131152131153131154131155131156131157131158131159131160131161131162131163131164131165131166131167131168131169131170131171131172131173131174131175131176131177131178131179131180131181131182131183131184131185131186131187131188131189131190131191131192131193131194131195131196131197131198131199131200131201131202131203131204131205131206131207131208131209131210131211131212131213131214131215131216131217131218131219131220131221131222131223131224131225131226131227131228131229131230131231131232131233131234131235131236131237131238131239131240131241131242131243131244131245131246131247131248131249131250131251131252131253131254131255131256131257131258131259131260131261131262131263131264131265131266131267131268131269131270131271131272131273131274131275131276131277131278131279131280131281131282131283131284131285131286131287131288131289131290131291131292131293131294131295131296131297131298131299131300131301131302131303131304131305131306131307131308131309131310131311131312131313131314131315131316131317131318131319131320131321131322131323131324131325131326131327131328131329131330131331131332131333131334131335131336131337131338131339131340131341131342131343131344131345131346131347131348131349131350131351131352131353131354131355131356131357131358131359131360131361131362131363131364131365131366131367131368131369131370131371131372131373131374131375131376131377131378131379131380131381131382131383131384131385131386131387131388131389131390131391131392131393131394131395131396131397131398131399131400131401131402131403131404131405131406131407131408131409131410131411131412131413131414131415131416131417131418131419131420131421131422131423131424131425131426131427131428131429131430131431131432131433131434131435131436131437131438131439131440131441131442131443131444131445131446131447131448131449131450131451131452131453131454131455131456131457131458131459131460131461131462131463131464131465131466131467131468131469131470131471131472131473131474131475131476131477131478131479131480131481131482131483131484131485131486131487131488131489131490131491131492131493131494131495131496131497131498131499131500131501131502131503131504131505131506131507131508131509131510131511131512131513131514131515131516131517131518131519131520131521131522131523131524131525131526131527131528131529131530131531131532131533131534131535131536131537131538131539131540131541131542131543131544131545131546131547131548131549131550131551131552131553131554131555131556131557131558131559131560131561131562131563131564131565131566131567131568131569131570131571131572131573131574131575131576131577131578131579131580131581131582131583131584131585131586131587131588131589131590131591131592131593131594131595131596131597131598131599131600131601131602131603131604131605131606131607131608131609131610131611131612131613131614131615131616131617131618131619131620131621131622131623131624131625131626131627131628131629131630131631131632131633131634131635131636131637131638131639131640131641131642131643131644131645131646131647131648131649131650131651131652131653131654131655131656131657131658131659131660131661131662131663131664131665131666131667131668131669131670131671131672131673131674131675131676131677131678131679131680131681131682131683131684131685131686131687131688131689131690131691131692131693131694131695131696131697131698131699131700131701131702131703131704131705131706131707131708131709131710131711131712131713131714131715131716131717131718131719131720131721131722131723131724131725131726131727131728131729131730131731131732131733131734131735131736131737131738131739131740131741131742131743131744131745131746131747131748131749131750131751131752131753131754131755131756131757131758131759131760131761131762131763131764131765131766131767131768131769131770131771131772131773131774131775131776131777131778131779131780131781131782131783131784131785131786131787131788131789131790131791131792131793131794131795131796131797131798131799131800131801131802131803131804131805131806131807131808131809131810131811131812131813131814131815131816131817131818131819131820131821131822131823131824131825131826131827131828131829131830131831131832131833131834131835131836131837131838131839131840131841131842131843131844131845131846131847131848131849131850131851131852131853131854131855131856131857131858131859131860131861131862131863131864131865131866131867131868131869131870131871131872131873131874131875131876131877131878131879131880131881131882131883131884131885131886131887131888131889131890131891131892131893131894131895131896131897131898131899131900131901131902131903131904131905131906131907131908131909131910131911131912131913131914131915131916131917131918131919131920131921131922131923131924131925131926131927131928131929131930131931131932131933131934131935131936131937131938131939131940131941131942131943131944131945131946131947131948131949131950131951131952131953131954131955131956131957131958131959131960131961131962131963131964131965131966131967131968131969131970131971131972131973131974131975131976131977131978131979131980131981131982131983131984131985131986131987131988131989131990131991131992131993131994131995131996131997131998131999132000132001132002132003132004132005132006132007132008132009132010132011132012132013132014132015132016132017132018132019132020132021132022132023132024132025132026132027132028132029132030132031132032132033132034132035132036132037132038132039132040132041132042132043132044132045132046132047132048132049132050132051132052132053132054132055132056132057132058132059132060132061132062132063132064132065132066132067132068132069132070132071132072132073132074132075132076132077132078132079132080132081132082132083132084132085132086132087132088132089132090132091132092132093132094132095132096132097132098132099132100132101132102132103132104132105132106132107132108132109132110132111132112132113132114132115132116132117132118132119132120132121132122132123132124132125132126132127132128132129132130132131132132132133132134132135132136132137132138132139132140132141132142132143132144132145132146132147132148132149132150132151132152132153132154132155132156132157132158132159132160132161132162132163132164132165132166132167132168132169132170132171132172132173132174132175132176132177132178132179132180132181132182132183132184132185132186132187132188132189132190132191132192132193132194132195132196132197132198132199132200132201132202132203132204132205132206132207132208132209132210132211132212132213132214132215132216132217132218132219132220132221132222132223132224132225132226132227132228132229132230132231132232132233132234132235132236132237132238132239132240132241132242132243132244132245132246132247132248132249132250132251132252132253132254132255132256132257132258132259132260132261132262132263132264132265132266132267132268132269132270132271132272132273132274132275132276132277132278132279132280132281132282132283132284132285132286132287132288132289132290132291132292132293132294132295132296132297132298132299132300132301132302132303132304132305132306132307132308132309132310132311132312132313132314132315132316132317132318132319132320132321132322132323132324132325132326132327132328132329132330132331132332132333132334132335132336132337132338132339132340132341132342132343132344132345132346132347132348132349132350132351132352132353132354132355132356132357132358132359132360132361132362132363132364132365132366132367132368132369132370132371132372132373132374132375132376132377132378132379132380132381132382132383132384132385132386132387132388132389132390132391132392132393132394132395132396132397132398132399132400132401132402132403132404132405132406132407132408132409132410132411132412132413132414132415132416132417132418132419132420132421132422132423132424132425132426132427132428132429132430132431132432132433132434132435132436132437132438132439132440132441132442132443132444132445132446132447132448132449132450132451132452132453132454132455132456132457132458132459132460132461132462132463132464132465132466132467132468132469132470132471132472132473132474132475132476132477132478132479132480132481132482132483132484132485132486132487132488132489132490132491132492132493132494132495132496132497132498132499132500132501132502132503132504132505132506132507132508132509132510132511132512132513132514132515132516132517132518132519132520132521132522132523132524132525132526132527132528132529132530132531132532132533132534132535132536132537132538132539132540132541132542132543132544132545132546132547132548132549132550132551132552132553132554132555132556132557132558132559132560132561132562132563132564132565132566132567132568132569132570132571132572132573132574132575132576132577132578132579132580132581132582132583132584132585132586132587132588132589132590132591132592132593132594132595132596132597132598132599132600132601132602132603132604132605132606132607132608132609132610132611132612132613132614132615132616132617132618132619132620132621132622132623132624132625132626132627132628132629132630132631132632132633132634132635132636132637132638132639132640132641132642132643132644132645132646132647132648132649132650132651132652132653132654132655132656132657132658132659132660132661132662132663132664132665132666132667132668132669132670132671132672132673132674132675132676132677132678132679132680132681132682132683132684132685132686132687132688132689132690132691132692132693132694132695132696132697132698132699132700132701132702132703132704132705132706132707132708132709132710132711132712132713132714132715132716132717132718132719132720132721132722132723132724132725132726132727132728132729132730132731132732132733132734132735132736132737132738132739132740132741132742132743132744132745132746132747132748132749132750132751132752132753132754132755132756132757132758132759132760132761132762132763132764132765132766132767132768132769132770132771132772132773132774132775132776132777132778132779132780132781132782132783132784132785132786132787132788132789132790132791132792132793132794132795132796132797132798132799132800132801132802132803132804132805132806132807132808132809132810132811132812132813132814132815132816132817132818132819132820132821132822132823132824132825132826132827132828132829132830132831132832132833132834132835132836132837132838132839132840132841132842132843132844132845132846132847132848132849132850132851132852132853132854132855132856132857132858132859132860132861132862132863132864132865132866132867132868132869132870132871132872132873132874132875132876132877132878132879132880132881132882132883132884132885132886132887132888132889132890132891132892132893132894132895132896132897132898132899132900132901132902132903132904132905132906132907132908132909132910132911132912132913132914132915132916132917132918132919132920132921132922132923132924132925132926132927132928132929132930132931132932132933132934132935132936132937132938132939132940132941132942132943132944132945132946132947132948132949132950132951132952132953132954132955132956132957132958132959132960132961132962132963132964132965132966132967132968132969132970132971132972132973132974132975132976132977132978132979132980132981132982132983132984132985132986132987132988132989132990132991132992132993132994132995132996132997132998132999133000133001133002133003133004133005133006133007133008133009133010133011133012133013133014133015133016133017133018133019133020133021133022133023133024133025133026133027133028133029133030133031133032133033133034133035133036133037133038133039133040133041133042133043133044133045133046133047133048133049133050133051133052133053133054133055133056133057133058133059133060133061133062133063133064133065133066133067133068133069133070133071133072133073133074133075133076133077133078133079133080133081133082133083133084133085133086133087133088133089133090133091133092133093133094133095133096133097133098133099133100133101133102133103133104133105133106133107133108133109133110133111133112133113133114133115133116133117133118133119133120133121133122133123133124133125133126133127133128133129133130133131133132133133133134133135133136133137133138133139133140133141133142133143133144133145133146133147133148133149133150133151133152133153133154133155133156133157133158133159133160133161133162133163133164133165133166133167133168133169133170133171133172133173133174133175133176133177133178133179133180133181133182133183133184133185133186133187133188133189133190133191133192133193133194133195133196133197133198133199133200133201133202133203133204133205133206133207133208133209133210133211133212133213133214133215133216133217133218133219133220133221133222133223133224133225133226133227133228133229133230133231133232133233133234133235133236133237133238133239133240133241133242133243133244133245133246133247133248133249133250133251133252133253133254133255133256133257133258133259133260133261133262133263133264133265133266133267133268133269133270133271133272133273133274133275133276133277133278133279133280133281133282133283133284133285133286133287133288133289133290133291133292133293133294133295133296133297133298133299133300133301133302133303133304133305133306133307133308133309133310133311133312133313133314133315133316133317133318133319133320133321133322133323133324133325133326133327133328133329133330133331133332133333133334133335133336133337133338133339133340133341133342133343133344133345133346133347133348133349133350133351133352133353133354133355133356133357133358133359133360133361133362133363133364133365133366133367133368133369133370133371133372133373133374133375133376133377133378133379133380133381133382133383133384133385133386133387133388133389133390133391133392133393133394133395133396133397133398133399133400133401133402133403133404133405133406133407133408133409133410133411133412133413133414133415133416133417133418133419133420133421133422133423133424133425133426133427133428133429133430133431133432133433133434133435133436133437133438133439133440133441133442133443133444133445133446133447133448133449133450133451133452133453133454133455133456133457133458133459133460133461133462133463133464133465133466133467133468133469133470133471133472133473133474133475133476133477133478133479133480133481133482133483133484133485133486133487133488133489133490133491133492133493133494133495133496133497133498133499133500133501133502133503133504133505133506133507133508133509133510133511133512133513133514133515133516133517133518133519133520133521133522133523133524133525133526133527133528133529133530133531133532133533133534133535133536133537133538133539133540133541133542133543133544133545133546133547133548133549133550133551133552133553133554133555133556133557133558133559133560133561133562133563133564133565133566133567133568133569133570133571133572133573133574133575133576133577133578133579133580133581133582133583133584133585133586133587133588133589133590133591133592133593133594133595133596133597133598133599133600133601133602133603133604133605133606133607133608133609133610133611133612133613133614133615133616133617133618133619133620133621133622133623133624133625133626133627133628133629133630133631133632133633133634133635133636133637133638133639133640133641133642133643133644133645133646133647133648133649133650133651133652133653133654133655133656133657133658133659133660133661133662133663133664133665133666133667133668133669133670133671133672133673133674133675133676133677133678133679133680133681133682133683133684133685133686133687133688133689133690133691133692133693133694133695133696133697133698133699133700133701133702133703133704133705133706133707133708133709133710133711133712133713133714133715133716133717133718133719133720133721133722133723133724133725133726133727133728133729133730133731133732133733133734133735133736133737133738133739133740133741133742133743133744133745133746133747133748133749133750133751133752133753133754133755133756133757133758133759133760133761133762133763133764133765133766133767133768133769133770133771133772133773133774133775133776133777133778133779133780133781133782133783133784133785133786133787133788133789133790133791133792133793133794133795133796133797133798133799133800133801133802133803133804133805133806133807133808133809133810133811133812133813133814133815133816133817133818133819133820133821133822133823133824133825133826133827133828133829133830133831133832133833133834133835133836133837133838133839133840133841133842133843133844133845133846133847133848133849133850133851133852133853133854133855133856133857133858133859133860133861133862133863133864133865133866133867133868133869133870133871133872133873133874133875133876133877133878133879133880133881133882133883133884133885133886133887133888133889133890133891133892133893133894133895133896133897133898133899133900133901133902133903133904133905133906133907133908133909133910133911133912133913133914133915133916133917133918133919133920133921133922133923133924133925133926133927133928133929133930133931133932133933133934133935133936133937133938133939133940133941133942133943133944133945133946133947133948133949133950133951133952133953133954133955133956133957133958133959133960133961133962133963133964133965133966133967133968133969133970133971133972133973133974133975133976133977133978133979133980133981133982133983133984133985133986133987133988133989133990133991133992133993133994133995133996133997133998133999134000134001134002134003134004134005134006134007134008134009134010134011134012134013134014134015134016134017134018134019134020134021134022134023134024134025134026134027134028134029134030134031134032134033134034134035134036134037134038134039134040134041134042134043134044134045134046134047134048134049134050134051134052134053134054134055134056134057134058134059134060134061134062134063134064134065134066134067134068134069134070134071134072134073134074134075134076134077134078134079134080134081134082134083134084134085134086134087134088134089134090134091134092134093134094134095134096134097134098134099134100134101134102134103134104134105134106134107134108134109134110134111134112134113134114134115134116134117134118134119134120134121134122134123134124134125134126134127134128134129134130134131134132134133134134134135134136134137134138134139134140134141134142134143134144134145134146134147134148134149134150134151134152134153134154134155134156134157134158134159134160134161134162134163134164134165134166134167134168134169134170134171134172134173134174134175134176134177134178134179134180134181134182134183134184134185134186134187134188134189134190134191134192134193134194134195134196134197134198134199134200134201134202134203134204134205134206134207134208134209134210134211134212134213134214134215134216134217134218134219134220134221134222134223134224134225134226134227134228134229134230134231134232134233134234134235134236134237134238134239134240134241134242134243134244134245134246134247134248134249134250134251134252134253134254134255134256134257134258134259134260134261134262134263134264134265134266134267134268134269134270134271134272134273134274134275134276134277134278134279134280134281134282134283134284134285134286134287134288134289134290134291134292134293134294134295134296134297134298134299134300134301134302134303134304134305134306134307134308134309134310134311134312134313134314134315134316134317134318134319134320134321134322134323134324134325134326134327134328134329134330134331134332134333134334134335134336134337134338134339134340134341134342134343134344134345134346134347134348134349134350134351134352134353134354134355134356134357134358134359134360134361134362134363134364134365134366134367134368134369134370134371134372134373134374134375134376134377134378134379134380134381134382134383134384134385134386134387134388134389134390134391134392134393134394134395134396134397134398134399134400134401134402134403134404134405134406134407134408134409134410134411134412134413134414134415134416134417134418134419134420134421134422134423134424134425134426134427134428134429134430134431134432134433134434134435134436134437134438134439134440134441134442134443134444134445134446134447134448134449134450134451134452134453134454134455134456134457134458134459134460134461134462134463134464134465134466134467134468134469134470134471134472134473134474134475134476134477134478134479134480134481134482134483134484134485134486134487134488134489134490134491134492134493134494134495134496134497134498134499134500134501134502134503134504134505134506134507134508134509134510134511134512134513134514134515134516134517134518134519134520134521134522134523134524134525134526134527134528134529134530134531134532134533134534134535134536134537134538134539134540134541134542134543134544134545134546134547134548134549134550134551134552134553134554134555134556134557134558134559134560134561134562134563134564134565134566134567134568134569134570134571134572134573134574134575134576134577134578134579134580134581134582134583134584134585134586134587134588134589134590134591134592134593134594134595134596134597134598134599134600134601134602134603134604134605134606134607134608134609134610134611134612134613134614134615134616134617134618134619134620134621134622134623134624134625134626134627134628134629134630134631134632134633134634134635134636134637134638134639134640134641134642134643134644134645134646134647134648134649134650134651134652134653134654134655134656134657134658134659134660134661134662134663134664134665134666134667134668134669134670134671134672134673134674134675134676134677134678134679134680134681134682134683134684134685134686134687134688134689134690134691134692134693134694134695134696134697134698134699134700134701134702134703134704134705134706134707134708134709134710134711134712134713134714134715134716134717134718134719134720134721134722134723134724134725134726134727134728134729134730134731134732134733134734134735134736134737134738134739134740134741134742134743134744134745134746134747134748134749134750134751134752134753134754134755134756134757134758134759134760134761134762134763134764134765134766134767134768134769134770134771134772134773134774134775134776134777134778134779134780134781134782134783134784134785134786134787134788134789134790134791134792134793134794134795134796134797134798134799134800134801134802134803134804134805134806134807134808134809134810134811134812134813134814134815134816134817134818134819134820134821134822134823134824134825134826134827134828134829134830134831134832134833134834134835134836134837134838134839134840134841134842134843134844134845134846134847134848134849134850134851134852134853134854134855134856134857134858134859134860134861134862134863134864134865134866134867134868134869134870134871134872134873134874134875134876134877134878134879134880134881134882134883134884134885134886134887134888134889134890134891134892134893134894134895134896134897134898134899134900134901134902134903134904134905134906134907134908134909134910134911134912134913134914134915134916134917134918134919134920134921134922134923134924134925134926134927134928134929134930134931134932134933134934134935134936134937134938134939134940134941134942134943134944134945134946134947134948134949134950134951134952134953134954134955134956134957134958134959134960134961134962134963134964134965134966134967134968134969134970134971134972134973134974134975134976134977134978134979134980134981134982134983134984134985134986134987134988134989134990134991134992134993134994134995134996134997134998134999135000135001135002135003135004135005135006135007135008135009135010135011135012135013135014135015135016135017135018135019135020135021135022135023135024135025135026135027135028135029135030135031135032135033135034135035135036135037135038135039135040135041135042135043135044135045135046135047135048135049135050135051135052135053135054135055135056135057135058135059135060135061135062135063135064135065135066135067135068135069135070135071135072135073135074135075135076135077135078135079135080135081135082135083135084135085135086135087135088135089135090135091135092135093135094135095135096135097135098135099135100135101135102135103135104135105135106135107135108135109135110135111135112135113135114135115135116135117135118135119135120135121135122135123135124135125135126135127135128135129135130135131135132135133135134135135135136135137135138135139135140135141135142135143135144135145135146135147135148135149135150135151135152135153135154135155135156135157135158135159135160135161135162135163135164135165135166135167135168135169135170135171135172135173135174135175135176135177135178135179135180135181135182135183135184135185135186135187135188135189135190135191135192135193135194135195135196135197135198135199135200135201135202135203135204135205135206135207135208135209135210135211135212135213135214135215135216135217135218135219135220135221135222135223135224135225135226135227135228135229135230135231135232135233135234135235135236135237135238135239135240135241135242135243135244135245135246135247135248135249135250135251135252135253135254135255135256135257135258135259135260135261135262135263135264135265135266135267135268135269135270135271135272135273135274135275135276135277135278135279135280135281135282135283135284135285135286135287135288135289135290135291135292135293135294135295135296135297135298135299135300135301135302135303135304135305135306135307135308135309135310135311135312135313135314135315135316135317135318135319135320135321135322135323135324135325135326135327135328135329135330135331135332135333135334135335135336135337135338135339135340135341135342135343135344135345135346135347135348135349135350135351135352135353135354135355135356135357135358135359135360135361135362135363135364135365135366135367135368135369135370135371135372135373135374135375135376135377135378135379135380135381135382135383135384135385135386135387135388135389135390135391135392135393135394135395135396135397135398135399135400135401135402135403135404135405135406135407135408135409135410135411135412135413135414135415135416135417135418135419135420135421135422135423135424135425135426135427135428135429135430135431135432135433135434135435135436135437135438135439135440135441135442135443135444135445135446135447135448135449135450135451135452135453135454135455135456135457135458135459135460135461135462135463135464135465135466135467135468135469135470135471135472135473135474135475135476135477135478135479135480135481135482135483135484135485135486135487135488135489135490135491135492135493135494135495135496135497135498135499135500135501135502135503135504135505135506135507135508135509135510135511135512135513135514135515135516135517135518135519135520135521135522135523135524135525135526135527135528135529135530135531135532135533135534135535135536135537135538135539135540135541135542135543135544135545135546135547135548135549135550135551135552135553135554135555135556135557135558135559135560135561135562135563135564135565135566135567135568135569135570135571135572135573135574135575135576135577135578135579135580135581135582135583135584135585135586135587135588135589135590135591135592135593135594135595135596135597135598135599135600135601135602135603135604135605135606135607135608135609135610135611135612135613135614135615135616135617135618135619135620135621135622135623135624135625135626135627135628135629135630135631135632135633135634135635135636135637135638135639135640135641135642135643135644135645135646135647135648135649135650135651135652135653135654135655135656135657135658135659135660135661135662135663135664135665135666135667135668135669135670135671135672135673135674135675135676135677135678135679135680135681135682135683135684135685135686135687135688135689135690135691135692135693135694135695135696135697135698135699135700135701135702135703135704135705135706135707135708135709135710135711135712135713135714135715135716135717135718135719135720135721135722135723135724135725135726135727135728135729135730135731135732135733135734135735135736135737135738135739135740135741135742135743135744135745135746135747135748135749135750135751135752135753135754135755135756135757135758135759135760135761135762135763135764135765135766135767135768135769135770135771135772135773135774135775135776135777135778135779135780135781135782135783135784135785135786135787135788135789135790135791135792135793135794135795135796135797135798135799135800135801135802135803135804135805135806135807135808135809135810135811135812135813135814135815135816135817135818135819135820135821135822135823135824135825135826135827135828135829135830135831135832135833135834135835135836135837135838135839135840135841135842135843135844135845135846135847135848135849135850135851135852135853135854135855135856135857135858135859135860135861135862135863135864135865135866135867135868135869135870135871135872135873135874135875135876135877135878135879135880135881135882135883135884135885135886135887135888135889135890135891135892135893135894135895135896135897135898135899135900135901135902135903135904135905135906135907135908135909135910135911135912135913135914135915135916135917135918135919135920135921135922135923135924135925135926135927135928135929135930135931135932135933135934135935135936135937135938135939135940135941135942135943135944135945135946135947135948135949135950135951135952135953135954135955135956135957135958135959135960135961135962135963135964135965135966135967135968135969135970135971135972135973135974135975135976135977135978135979135980135981135982135983135984135985135986135987135988135989135990135991135992135993135994135995135996135997135998135999136000136001136002136003136004136005136006136007136008136009136010136011136012136013136014136015136016136017136018136019136020136021136022136023136024136025136026136027136028136029136030136031136032136033136034136035136036136037136038136039136040136041136042136043136044136045136046136047136048136049136050136051136052136053136054136055136056136057136058136059136060136061136062136063136064136065136066136067136068136069136070136071136072136073136074136075136076136077136078136079136080136081136082136083136084136085136086136087136088136089136090136091136092136093136094136095136096136097136098136099136100136101136102136103136104136105136106136107136108136109136110136111136112136113136114136115136116136117136118136119136120136121136122136123136124136125136126136127136128136129136130136131136132136133136134136135136136136137136138136139136140136141136142136143136144136145136146136147136148136149136150136151136152136153136154136155136156136157136158136159136160136161136162136163136164136165136166136167136168136169136170136171136172136173136174136175136176136177136178136179136180136181136182136183136184136185136186136187136188136189136190136191136192136193136194136195136196136197136198136199136200136201136202136203136204136205136206136207136208136209136210136211136212136213136214136215136216136217136218136219136220136221136222136223136224136225136226136227136228136229136230136231136232136233136234136235136236136237136238136239136240136241136242136243136244136245136246136247136248136249136250136251136252136253136254136255136256136257136258136259136260136261136262136263136264136265136266136267136268136269136270136271136272136273136274136275136276136277136278136279136280136281136282136283136284136285136286136287136288136289136290136291136292136293136294136295136296136297136298136299136300136301136302136303136304136305136306136307136308136309136310136311136312136313136314136315136316136317136318136319136320136321136322136323136324136325136326136327136328136329136330136331136332136333136334136335136336136337136338136339136340136341136342136343136344136345136346136347136348136349136350136351136352136353136354136355136356136357136358136359136360136361136362136363136364136365136366136367136368136369136370136371136372136373136374136375136376136377136378136379136380136381136382136383136384136385136386136387136388136389136390136391136392136393136394136395136396136397136398136399136400136401136402136403136404136405136406136407136408136409136410136411136412136413136414136415136416136417136418136419136420136421136422136423136424136425136426136427136428136429136430136431136432136433136434136435136436136437136438136439136440136441136442136443136444136445136446136447136448136449136450136451136452136453136454136455136456136457136458136459136460136461136462136463136464136465136466136467136468136469136470136471136472136473136474136475136476136477136478136479136480136481136482136483136484136485136486136487136488136489136490136491136492136493136494136495136496136497136498136499136500136501136502136503136504136505136506136507136508136509136510136511136512136513136514136515136516136517136518136519136520136521136522136523136524136525136526136527136528136529136530136531136532136533136534136535136536136537136538136539136540136541136542136543136544136545136546136547136548136549136550136551136552136553136554136555136556136557136558136559136560136561136562136563136564136565136566136567136568136569136570136571136572136573136574136575136576136577136578136579136580136581136582136583136584136585136586136587136588136589136590136591136592136593136594136595136596136597136598136599136600136601136602136603136604136605136606136607136608136609136610136611136612136613136614136615136616136617136618136619136620136621136622136623136624136625136626136627136628136629136630136631136632136633136634136635136636136637136638136639136640136641136642136643136644136645136646136647136648136649136650136651136652136653136654136655136656136657136658136659136660136661136662136663136664136665136666136667136668136669136670136671136672136673136674136675136676136677136678136679136680136681136682136683136684136685136686136687136688136689136690136691136692136693136694136695136696136697136698136699136700136701136702136703136704136705136706136707136708136709136710136711136712136713136714136715136716136717136718136719136720136721136722136723136724136725136726136727136728136729136730136731136732136733136734136735136736136737136738136739136740136741136742136743136744136745136746136747136748136749136750136751136752136753136754136755136756136757136758136759136760136761136762136763136764136765136766136767136768136769136770136771136772136773136774136775136776136777136778136779136780136781136782136783136784136785136786136787136788136789136790136791136792136793136794136795136796136797136798136799136800136801136802136803136804136805136806136807136808136809136810136811136812136813136814136815136816136817136818136819136820136821136822136823136824136825136826136827136828136829136830136831136832136833136834136835136836136837136838136839136840136841136842136843136844136845136846136847136848136849136850136851136852136853136854136855136856136857136858136859136860136861136862136863136864136865136866136867136868136869136870136871136872136873136874136875136876136877136878136879136880136881136882136883136884136885136886136887136888136889136890136891136892136893136894136895136896136897136898136899136900136901136902136903136904136905136906136907136908136909136910136911136912136913136914136915136916136917136918136919136920136921136922136923136924136925136926136927136928136929136930136931136932136933136934136935136936136937136938136939136940136941136942136943136944136945136946136947136948136949136950136951136952136953136954136955136956136957136958136959136960136961136962136963136964136965136966136967136968136969136970136971136972136973136974136975136976136977136978136979136980136981136982136983136984136985136986136987136988136989136990136991136992136993136994136995136996136997136998136999137000137001137002137003137004137005137006137007137008137009137010137011137012137013137014137015137016137017137018137019137020137021137022137023137024137025137026137027137028137029137030137031137032137033137034137035137036137037137038137039137040137041137042137043137044137045137046137047137048137049137050137051137052137053137054137055137056137057137058137059137060137061137062137063137064137065137066137067137068137069137070137071137072137073137074137075137076137077137078137079137080137081137082137083137084137085137086137087137088137089137090137091137092137093137094137095137096137097137098137099137100137101137102137103137104137105137106137107137108137109137110137111137112137113137114137115137116137117137118137119137120137121137122137123137124137125137126137127137128137129137130137131137132137133137134137135137136137137137138137139137140137141137142137143137144137145137146137147137148137149137150137151137152137153137154137155137156137157137158137159137160137161137162137163137164137165137166137167137168137169137170137171137172137173137174137175137176137177137178137179137180137181137182137183137184137185137186137187137188137189137190137191137192137193137194137195137196137197137198137199137200137201137202137203137204137205137206137207137208137209137210137211137212137213137214137215137216137217137218137219137220137221137222137223137224137225137226137227137228137229137230137231137232137233137234137235137236137237137238137239137240137241137242137243137244137245137246137247137248137249137250137251137252137253137254137255137256137257137258137259137260137261137262137263137264137265137266137267137268137269137270137271137272137273137274137275137276137277137278137279137280137281137282137283137284137285137286137287137288137289137290137291137292137293137294137295137296137297137298137299137300137301137302137303137304137305137306137307137308137309137310137311137312137313137314137315137316137317137318137319137320137321137322137323137324137325137326137327137328137329137330137331137332137333137334137335137336137337137338137339137340137341137342137343137344137345137346137347137348137349137350137351137352137353137354137355137356137357137358137359137360137361137362137363137364137365137366137367137368137369137370137371137372137373137374137375137376137377137378137379137380137381137382137383137384137385137386137387137388137389137390137391137392137393137394137395137396137397137398137399137400137401137402137403137404137405137406137407137408137409137410137411137412137413137414137415137416137417137418137419137420137421137422137423137424137425137426137427137428137429137430137431137432137433137434137435137436137437137438137439137440137441137442137443137444137445137446137447137448137449137450137451137452137453137454137455137456137457137458137459137460137461137462137463137464137465137466137467137468137469137470137471137472137473137474137475137476137477137478137479137480137481137482137483137484137485137486137487137488137489137490137491137492137493137494137495137496137497137498137499137500137501137502137503137504137505137506137507137508137509137510137511137512137513137514137515137516137517137518137519137520137521137522137523137524137525137526137527137528137529137530137531137532137533137534137535137536137537137538137539137540137541137542137543137544137545137546137547137548137549137550137551137552137553137554137555137556137557137558137559137560137561137562137563137564137565137566137567137568137569137570137571137572137573137574137575137576137577137578137579137580137581137582137583137584137585137586137587137588137589137590137591137592137593137594137595137596137597137598137599137600137601137602137603137604137605137606137607137608137609137610137611137612137613137614137615137616137617137618137619137620137621137622137623137624137625137626137627137628137629137630137631137632137633137634137635137636137637137638137639137640137641137642137643137644137645137646137647137648137649137650137651137652137653137654137655137656137657137658137659137660137661137662137663137664137665137666137667137668137669137670137671137672137673137674137675137676137677137678137679137680137681137682137683137684137685137686137687137688137689137690137691137692137693137694137695137696137697137698137699137700137701137702137703137704137705137706137707137708137709137710137711137712137713137714137715137716137717137718137719137720137721137722137723137724137725137726137727137728137729137730137731137732137733137734137735137736137737137738137739137740137741137742137743137744137745137746137747137748137749137750137751137752137753137754137755137756137757137758137759137760137761137762137763137764137765137766137767137768137769137770137771137772137773137774137775137776137777137778137779137780137781137782137783137784137785137786137787137788137789137790137791137792137793137794137795137796137797137798137799137800137801137802137803137804137805137806137807137808137809137810137811137812137813137814137815137816137817137818137819137820137821137822137823137824137825137826137827137828137829137830137831137832137833137834137835137836137837137838137839137840137841137842137843137844137845137846137847137848137849137850137851137852137853137854137855137856137857137858137859137860137861137862137863137864137865137866137867137868137869137870137871137872137873137874137875137876137877137878137879137880137881137882137883137884137885137886137887137888137889137890137891137892137893137894137895137896137897137898137899137900137901137902137903137904137905137906137907137908137909137910137911137912137913137914137915137916137917137918137919137920137921137922137923137924137925137926137927137928137929137930137931137932137933137934137935137936137937137938137939137940137941137942137943137944137945137946137947137948137949137950137951137952137953137954137955137956137957137958137959137960137961137962137963137964137965137966137967137968137969137970137971137972137973137974137975137976137977137978137979137980137981137982137983137984137985137986137987137988137989137990137991137992137993137994137995137996137997137998137999138000138001138002138003138004138005138006138007138008138009138010138011138012138013138014138015138016138017138018138019138020138021138022138023138024138025138026138027138028138029138030138031138032138033138034138035138036138037138038138039138040138041138042138043138044138045138046138047138048138049138050138051138052138053138054138055138056138057138058138059138060138061138062138063138064138065138066138067138068138069138070138071138072138073138074138075138076138077138078138079138080138081138082138083138084138085138086138087138088138089138090138091138092138093138094138095138096138097138098138099138100138101138102138103138104138105138106138107138108138109138110138111138112138113138114138115138116138117138118138119138120138121138122138123138124138125138126138127138128138129138130138131138132138133138134138135138136138137138138138139138140138141138142138143138144138145138146138147138148138149138150138151138152138153138154138155138156138157138158138159138160138161138162138163138164138165138166138167138168138169138170138171138172138173138174138175138176138177138178138179138180138181138182138183138184138185138186138187138188138189138190138191138192138193138194138195138196138197138198138199138200138201138202138203138204138205138206138207138208138209138210138211138212138213138214138215138216138217138218138219138220138221138222138223138224138225138226138227138228138229138230138231138232138233138234138235138236138237138238138239138240138241138242138243138244138245138246138247138248138249138250138251138252138253138254138255138256138257138258138259138260138261138262138263138264138265138266138267138268138269138270138271138272138273138274138275138276138277138278138279138280138281138282138283138284138285138286138287138288138289138290138291138292138293138294138295138296138297138298138299138300138301138302138303138304138305138306138307138308138309138310138311138312138313138314138315138316138317138318138319138320138321138322138323138324138325138326138327138328138329138330138331138332138333138334138335138336138337138338138339138340138341138342138343138344138345138346138347138348138349138350138351138352138353138354138355138356138357138358138359138360138361138362138363138364138365138366138367138368138369138370138371138372138373138374138375138376138377138378138379138380138381138382138383138384138385138386138387138388138389138390138391138392138393138394138395138396138397138398138399138400138401138402138403138404138405138406138407138408138409138410138411138412138413138414138415138416138417138418138419138420138421138422138423138424138425138426138427138428138429138430138431138432138433138434138435138436138437138438138439138440138441138442138443138444138445138446138447138448138449138450138451138452138453138454138455138456138457138458138459138460138461138462138463138464138465138466138467138468138469138470138471138472138473138474138475138476138477138478138479138480138481138482138483138484138485138486138487138488138489138490138491138492138493138494138495138496138497138498138499138500138501138502138503138504138505138506138507138508138509138510138511138512138513138514138515138516138517138518138519138520138521138522138523138524138525138526138527138528138529138530138531138532138533138534138535138536138537138538138539138540138541138542138543138544138545138546138547138548138549138550138551138552138553138554138555138556138557138558138559138560138561138562138563138564138565138566138567138568138569138570138571138572138573138574138575138576138577138578138579138580138581138582138583138584138585138586138587138588138589138590138591138592138593138594138595138596138597138598138599138600138601138602138603138604138605138606138607138608138609138610138611138612138613138614138615138616138617138618138619138620138621138622138623138624138625138626138627138628138629138630138631138632138633138634138635138636138637138638138639138640138641138642138643138644138645138646138647138648138649138650138651138652138653138654138655138656138657138658138659138660138661138662138663138664138665138666138667138668138669138670138671138672138673138674138675138676138677138678138679138680138681138682138683138684138685138686138687138688138689138690138691138692138693138694138695138696138697138698138699138700138701138702138703138704138705138706138707138708138709138710138711138712138713138714138715138716138717138718138719138720138721138722138723138724138725138726138727138728138729138730138731138732138733138734138735138736138737138738138739138740138741138742138743138744138745138746138747138748138749138750138751138752138753138754138755138756138757138758138759138760138761138762138763138764138765138766138767138768138769138770138771138772138773138774138775138776138777138778138779138780138781138782138783138784138785138786138787138788138789138790138791138792138793138794138795138796138797138798138799138800138801138802138803138804138805138806138807138808138809138810138811138812138813138814138815138816138817138818138819138820138821138822138823138824138825138826138827138828138829138830138831138832138833138834138835138836138837138838138839138840138841138842138843138844138845138846138847138848138849138850138851138852138853138854138855138856138857138858138859138860138861138862138863138864138865138866138867138868138869138870138871138872138873138874138875138876138877138878138879138880138881138882138883138884138885138886138887138888138889138890138891138892138893138894138895138896138897138898138899138900138901138902138903138904138905138906138907138908138909138910138911138912138913138914138915138916138917138918138919138920138921138922138923138924138925138926138927138928138929138930138931138932138933138934138935138936138937138938138939138940138941138942138943138944138945138946138947138948138949138950138951138952138953138954138955138956138957138958138959138960138961138962138963138964138965138966138967138968138969138970138971138972138973138974138975138976138977138978138979138980138981138982138983138984138985138986138987138988138989138990138991138992138993138994138995138996138997138998138999139000139001139002139003139004139005139006139007139008139009139010139011139012139013139014139015139016139017139018139019139020139021139022139023139024139025139026139027139028139029139030139031139032139033139034139035139036139037139038139039139040139041139042139043139044139045139046139047139048139049139050139051139052139053139054139055139056139057139058139059139060139061139062139063139064139065139066139067139068139069139070139071139072139073139074139075139076139077139078139079139080139081139082139083139084139085139086139087139088139089139090139091139092139093139094139095139096139097139098139099139100139101139102139103139104139105139106139107139108139109139110139111139112139113139114139115139116139117139118139119139120139121139122139123139124139125139126139127139128139129139130139131139132139133139134139135139136139137139138139139139140139141139142139143139144139145139146139147139148139149139150139151139152139153139154139155139156139157139158139159139160139161139162139163139164139165139166139167139168139169139170139171139172139173139174139175139176139177139178139179139180139181139182139183139184139185139186139187139188139189139190139191139192139193139194139195139196139197139198139199139200139201139202139203139204139205139206139207139208139209139210139211139212139213139214139215139216139217139218139219139220139221139222139223139224139225139226139227139228139229139230139231139232139233139234139235139236139237139238139239139240139241139242139243139244139245139246139247139248139249139250139251139252139253139254139255139256139257139258139259139260139261139262139263139264139265139266139267139268139269139270139271139272139273139274139275139276139277139278139279139280139281139282139283139284139285139286139287139288139289139290139291139292139293139294139295139296139297139298139299139300139301139302139303139304139305139306139307139308139309139310139311139312139313139314139315139316139317139318139319139320139321139322139323139324139325139326139327139328139329139330139331139332139333139334139335139336139337139338139339139340139341139342139343139344139345139346139347139348139349139350139351139352139353139354139355139356139357139358139359139360139361139362139363139364139365139366139367139368139369139370139371139372139373139374139375139376139377139378139379139380139381139382139383139384139385139386139387139388139389139390139391139392139393139394139395139396139397139398139399139400139401139402139403139404139405139406139407139408139409139410139411139412139413139414139415139416139417139418139419139420139421139422139423139424139425139426139427139428139429139430139431139432139433139434139435139436139437139438139439139440139441139442139443139444139445139446139447139448139449139450139451139452139453139454139455139456139457139458139459139460139461139462139463139464139465139466139467139468139469139470139471139472139473139474139475139476139477139478139479139480139481139482139483139484139485139486139487139488139489139490139491139492139493139494139495139496139497139498139499139500139501139502139503139504139505139506139507139508139509139510139511139512139513139514139515139516139517139518139519139520139521139522139523139524139525139526139527139528139529139530139531139532139533139534139535139536139537139538139539139540139541139542139543139544139545139546139547139548139549139550139551139552139553139554139555139556139557139558139559139560139561139562139563139564139565139566139567139568139569139570139571139572139573139574139575139576139577139578139579139580139581139582139583139584139585139586139587139588139589139590139591139592139593139594139595139596139597139598139599139600139601139602139603139604139605139606139607139608139609139610139611139612139613139614139615139616139617139618139619139620139621139622139623139624139625139626139627139628139629139630139631139632139633139634139635139636139637139638139639139640139641139642139643139644139645139646139647139648139649139650139651139652139653139654139655139656139657139658139659139660139661139662139663139664139665139666139667139668139669139670139671139672139673139674139675139676139677139678139679139680139681139682139683139684139685139686139687139688139689139690139691139692139693139694139695139696139697139698139699139700139701139702139703139704139705139706139707139708139709139710139711139712139713139714139715139716139717139718139719139720139721139722139723139724139725139726139727139728139729139730139731139732139733139734139735139736139737139738139739139740139741139742139743139744139745139746139747139748139749139750139751139752139753139754139755139756139757139758139759139760139761139762139763139764139765139766139767139768139769139770139771139772139773139774139775139776139777139778139779139780139781139782139783139784139785139786139787139788139789139790139791139792139793139794139795139796139797139798139799139800139801139802139803139804139805139806139807139808139809139810139811139812139813139814139815139816139817139818139819139820139821139822139823139824139825139826139827139828139829139830139831139832139833139834139835139836139837139838139839139840139841139842139843139844139845139846139847139848139849139850139851139852139853139854139855139856139857139858139859139860139861139862139863139864139865139866139867139868139869139870139871139872139873139874139875139876139877139878139879139880139881139882139883139884139885139886139887139888139889139890139891139892139893139894139895139896139897139898139899139900139901139902139903139904139905139906139907139908139909139910139911139912139913139914139915139916139917139918139919139920139921139922139923139924139925139926139927139928139929139930139931139932139933139934139935139936139937139938139939139940139941139942139943139944139945139946139947139948139949139950139951139952139953139954139955139956139957139958139959139960139961139962139963139964139965139966139967139968139969139970139971139972139973139974139975139976139977139978139979139980139981139982139983139984139985139986139987139988139989139990139991139992139993139994139995139996139997139998139999140000140001140002140003140004140005140006140007140008140009140010140011140012140013140014140015140016140017140018140019140020140021140022140023140024140025140026140027140028140029140030140031140032140033140034140035140036140037140038140039140040140041140042140043140044140045140046140047140048140049140050140051140052140053140054140055140056140057140058140059140060140061140062140063140064140065140066140067140068140069140070140071140072140073140074140075140076140077140078140079140080140081140082140083140084140085140086140087140088140089140090140091140092140093140094140095140096140097140098140099140100140101140102140103140104140105140106140107140108140109140110140111140112140113140114140115140116140117140118140119140120140121140122140123140124140125140126140127140128140129140130140131140132140133140134140135140136140137140138140139140140140141140142140143140144140145140146140147140148140149140150140151140152140153140154140155140156140157140158140159140160140161140162140163140164140165140166140167140168140169140170140171140172140173140174140175140176140177140178140179140180140181140182140183140184140185140186140187140188140189140190140191140192140193140194140195140196140197140198140199140200140201140202140203140204140205140206140207140208140209140210140211140212140213140214140215140216140217140218140219140220140221140222140223140224140225140226140227140228140229140230140231140232140233140234140235140236140237140238140239140240140241140242140243140244140245140246140247140248140249140250140251140252140253140254140255140256140257140258140259140260140261140262140263140264140265140266140267140268140269140270140271140272140273140274140275140276140277140278140279140280140281140282140283140284140285140286140287140288140289140290140291140292140293140294140295140296140297140298140299140300140301140302140303140304140305140306140307140308140309140310140311140312140313140314140315140316140317140318140319140320140321140322140323140324140325140326140327140328140329140330140331140332140333140334140335140336140337140338140339140340140341140342140343140344140345140346140347140348140349140350140351140352140353140354140355140356140357140358140359140360140361140362140363140364140365140366140367140368140369140370140371140372140373140374140375140376140377140378140379140380140381140382140383140384140385140386140387140388140389140390140391140392140393140394140395140396140397140398140399140400140401140402140403140404140405140406140407140408140409140410140411140412140413140414140415140416140417140418140419140420140421140422140423140424140425140426140427140428140429140430140431140432140433140434140435140436140437140438140439140440140441140442140443140444140445140446140447140448140449140450140451140452140453140454140455140456140457140458140459140460140461140462140463140464140465140466140467140468140469140470140471140472140473140474140475140476140477140478140479140480140481140482140483140484140485140486140487140488140489140490140491140492140493140494140495140496140497140498140499140500140501140502140503140504140505140506140507140508140509140510140511140512140513140514140515140516140517140518140519140520140521140522140523140524140525140526140527140528140529140530140531140532140533140534140535140536140537140538140539140540140541140542140543140544140545140546140547140548140549140550140551140552140553140554140555140556140557140558140559140560140561140562140563140564140565140566140567140568140569140570140571140572140573140574140575140576140577140578140579140580140581140582140583140584140585140586140587140588140589140590140591140592140593140594140595140596140597140598140599140600140601140602140603140604140605140606140607140608140609140610140611140612140613140614140615140616140617140618140619140620140621140622140623140624140625140626140627140628140629140630140631140632140633140634140635140636140637140638140639140640140641140642140643140644140645140646140647140648140649140650140651140652140653140654140655140656140657140658140659140660140661140662140663140664140665140666140667140668140669140670140671140672140673140674140675140676140677140678140679140680140681140682140683140684140685140686140687140688140689140690140691140692140693140694140695140696140697140698140699140700140701140702140703140704140705140706140707140708140709140710140711140712140713140714140715140716140717140718140719140720140721140722140723140724140725140726140727140728140729140730140731140732140733140734140735140736140737140738140739140740140741140742140743140744140745140746140747140748140749140750140751140752140753140754140755140756140757140758140759140760140761140762140763140764140765140766140767140768140769140770140771140772140773140774140775140776140777140778140779140780140781140782140783140784140785140786140787140788140789140790140791140792140793140794140795140796140797140798140799140800140801140802140803140804140805140806140807140808140809140810140811140812140813140814140815140816140817140818140819140820140821140822140823140824140825140826140827140828140829140830140831140832140833140834140835140836140837140838140839140840140841140842140843140844140845140846140847140848140849140850140851140852140853140854140855140856140857140858140859140860140861140862140863140864140865140866140867140868140869140870140871140872140873140874140875140876140877140878140879140880140881140882140883140884140885140886140887140888140889140890140891140892140893140894140895140896140897140898140899140900140901140902140903140904140905140906140907140908140909140910140911140912140913140914140915140916140917140918140919140920140921140922140923140924140925140926140927140928140929140930140931140932140933140934140935140936140937140938140939140940140941140942140943140944140945140946140947140948140949140950140951140952140953140954140955140956140957140958140959140960140961140962140963140964140965140966140967140968140969140970140971140972140973140974140975140976140977140978140979140980140981140982140983140984140985140986140987140988140989140990140991140992140993140994140995140996140997140998140999141000141001141002141003141004141005141006141007141008141009141010141011141012141013141014141015141016141017141018141019141020141021141022141023141024141025141026141027141028141029141030141031141032141033141034141035141036141037141038141039141040141041141042141043141044141045141046141047141048141049141050141051141052141053141054141055141056141057141058141059141060141061141062141063141064141065141066141067141068141069141070141071141072141073141074141075141076141077141078141079141080141081141082141083141084141085141086141087141088141089141090141091141092141093141094141095141096141097141098141099141100141101141102141103141104141105141106141107141108141109141110141111141112141113141114141115141116141117141118141119141120141121141122141123141124141125141126141127141128141129141130141131141132141133141134141135141136141137141138141139141140141141141142141143141144141145141146141147141148141149141150141151141152141153141154141155141156141157141158141159141160141161141162141163141164141165141166141167141168141169141170141171141172141173141174141175141176141177141178141179141180141181141182141183141184141185141186141187141188141189141190141191141192141193141194141195141196141197141198141199141200141201141202141203141204141205141206141207141208141209141210141211141212141213141214141215141216141217141218141219141220141221141222141223141224141225141226141227141228141229141230141231141232141233141234141235141236141237141238141239141240141241141242141243141244141245141246141247141248141249141250141251141252141253141254141255141256141257141258141259141260141261141262141263141264141265141266141267141268141269141270141271141272141273141274141275141276141277141278141279141280141281141282141283141284141285141286141287141288141289141290141291141292141293141294141295141296141297141298141299141300141301141302141303141304141305141306141307141308141309141310141311141312141313141314141315141316141317141318141319141320141321141322141323141324141325141326141327141328141329141330141331141332141333141334141335141336141337141338141339141340141341141342141343141344141345141346141347141348141349141350141351141352141353141354141355141356141357141358141359141360141361141362141363141364141365141366141367141368141369141370141371141372141373141374141375141376141377141378141379141380141381141382141383141384141385141386141387141388141389141390141391141392141393141394141395141396141397141398141399141400141401141402141403141404141405141406141407141408141409141410141411141412141413141414141415141416141417141418141419141420141421141422141423141424141425141426141427141428141429141430141431141432141433141434141435141436141437141438141439141440141441141442141443141444141445141446141447141448141449141450141451141452141453141454141455141456141457141458141459141460141461141462141463141464141465141466141467141468141469141470141471141472141473141474141475141476141477141478141479141480141481141482141483141484141485141486141487141488141489141490141491141492141493141494141495141496141497141498141499141500141501141502141503141504141505141506141507141508141509141510141511141512141513141514141515141516141517141518141519141520141521141522141523141524141525141526141527141528141529141530141531141532141533141534141535141536141537141538141539141540141541141542141543141544141545141546141547141548141549141550141551141552141553141554141555141556141557141558141559141560141561141562141563141564141565141566141567141568141569141570141571141572141573141574141575141576141577141578141579141580141581141582141583141584141585141586141587141588141589141590141591141592141593141594141595141596141597141598141599141600141601141602141603141604141605141606141607141608141609141610141611141612141613141614141615141616141617141618141619141620141621141622141623141624141625141626141627141628141629141630141631141632141633141634141635141636141637141638141639141640141641141642141643141644141645141646141647141648141649141650141651141652141653141654141655141656141657141658141659141660141661141662141663141664141665141666141667141668141669141670141671141672141673141674141675141676141677141678141679141680141681141682141683141684141685141686141687141688141689141690141691141692141693141694141695141696141697141698141699141700141701141702141703141704141705141706141707141708141709141710141711141712141713141714141715141716141717141718141719141720141721141722141723141724141725141726141727141728141729141730141731141732141733141734141735141736141737141738141739141740141741141742141743141744141745141746141747141748141749141750141751141752141753141754141755141756141757141758141759141760141761141762141763141764141765141766141767141768141769141770141771141772141773141774141775141776141777141778141779141780141781141782141783141784141785141786141787141788141789141790141791141792141793141794141795141796141797141798141799141800141801141802141803141804141805141806141807141808141809141810141811141812141813141814141815141816141817141818141819141820141821141822141823141824141825141826141827141828141829141830141831141832141833141834141835141836141837141838141839141840141841141842141843141844141845141846141847141848141849141850141851141852141853141854141855141856141857141858141859141860141861141862141863141864141865141866141867141868141869141870141871141872141873141874141875141876141877141878141879141880141881141882141883141884141885141886141887141888141889141890141891141892141893141894141895141896141897141898141899141900141901141902141903141904141905141906141907141908141909141910141911141912141913141914141915141916141917141918141919141920141921141922141923141924141925141926141927141928141929141930141931141932141933141934141935141936141937141938141939141940141941141942141943141944141945141946141947141948141949141950141951141952141953141954141955141956141957141958141959141960141961141962141963141964141965141966141967141968141969141970141971141972141973141974141975141976141977141978141979141980141981141982141983141984141985141986141987141988141989141990141991141992141993141994141995141996141997141998141999142000142001142002142003142004142005142006142007142008142009142010142011142012142013142014142015142016142017142018142019142020142021142022142023142024142025142026142027142028142029142030142031142032142033142034142035142036142037142038142039142040142041142042142043142044142045142046142047142048142049142050142051142052142053142054142055142056142057142058142059142060142061142062142063142064142065142066142067142068142069142070142071142072142073142074142075142076142077142078142079142080142081142082142083142084142085142086142087142088142089142090142091142092142093142094142095142096142097142098142099142100142101142102142103142104142105142106142107142108142109142110142111142112142113142114142115142116142117142118142119142120142121142122142123142124142125142126142127142128142129142130142131142132142133142134142135142136142137142138142139142140142141142142142143142144142145142146142147142148142149142150142151142152142153142154142155142156142157142158142159142160142161142162142163142164142165142166142167142168142169142170142171142172142173142174142175142176142177142178142179142180142181142182142183142184142185142186142187142188142189142190142191142192142193142194142195142196142197142198142199142200142201142202142203142204142205142206142207142208142209142210142211142212142213142214142215142216142217142218142219142220142221142222142223142224142225142226142227142228142229142230142231142232142233142234142235142236142237142238142239142240142241142242142243142244142245142246142247142248142249142250142251142252142253142254142255142256142257142258142259142260142261142262142263142264142265142266142267142268142269142270142271142272142273142274142275142276142277142278142279142280142281142282142283142284142285142286142287142288142289142290142291142292142293142294142295142296142297142298142299142300142301142302142303142304142305142306142307142308142309142310142311142312142313142314142315142316142317142318142319142320142321142322142323142324142325142326142327142328142329142330142331142332142333142334142335142336142337142338142339142340142341142342142343142344142345142346142347142348142349142350142351142352142353142354142355142356142357142358142359142360142361142362142363142364142365142366142367142368142369142370142371142372142373142374142375142376142377142378142379142380142381142382142383142384142385142386142387142388142389142390142391142392142393142394142395142396142397142398142399142400142401142402142403142404142405142406142407142408142409142410142411142412142413142414142415142416142417142418142419142420142421142422142423142424142425142426142427142428142429142430142431142432142433142434142435142436142437142438142439142440142441142442142443142444142445142446142447142448142449142450142451142452142453142454142455142456142457142458142459142460142461142462142463142464142465142466142467142468142469142470142471142472142473142474142475142476142477142478142479142480142481142482142483142484142485142486142487142488142489142490142491142492142493142494142495142496142497142498142499142500142501142502142503142504142505142506142507142508142509142510142511142512142513142514142515142516142517142518142519142520142521142522142523142524142525142526142527142528142529142530142531142532142533142534142535142536142537142538142539142540142541142542142543142544142545142546142547142548142549142550142551142552142553142554142555142556142557142558142559142560142561142562142563142564142565142566142567142568142569142570142571142572142573142574142575142576142577142578142579142580142581142582142583142584142585142586142587142588142589142590142591142592142593142594142595142596142597142598142599142600142601142602142603142604142605142606142607142608142609142610142611142612142613142614142615142616142617142618142619142620142621142622142623142624142625142626142627142628142629142630142631142632142633142634142635142636142637142638142639142640142641142642142643142644142645142646142647142648142649142650142651142652142653142654142655142656142657142658142659142660142661142662142663142664142665142666142667142668142669142670142671142672142673142674142675142676142677142678142679142680142681142682142683142684142685142686142687142688142689142690142691142692142693142694142695142696142697142698142699142700142701142702142703142704142705142706142707142708142709142710142711142712142713142714142715142716142717142718142719142720142721142722142723142724142725142726142727142728142729142730142731142732142733142734142735142736142737142738142739142740142741142742142743142744142745142746142747142748142749142750142751142752142753142754142755142756142757142758142759142760142761142762142763142764142765142766142767142768142769142770142771142772142773142774142775142776142777142778142779142780142781142782142783142784142785142786142787142788142789142790142791142792142793142794142795142796142797142798142799142800142801142802142803142804142805142806142807142808142809142810142811142812142813142814142815142816142817142818142819142820142821142822142823142824142825142826142827142828142829142830142831142832142833142834142835142836142837142838142839142840142841142842142843142844142845142846142847142848142849142850142851142852142853142854142855142856142857142858142859142860142861142862142863142864142865142866142867142868142869142870142871142872142873142874142875142876142877142878142879142880142881142882142883142884142885142886142887142888142889142890142891142892142893142894142895142896142897142898142899142900142901142902142903142904142905142906142907142908142909142910142911142912142913142914142915142916142917142918142919142920142921142922142923142924142925142926142927142928142929142930142931142932142933142934142935142936142937142938142939142940142941142942142943142944142945142946142947142948142949142950142951142952142953142954142955142956142957142958142959142960142961142962142963142964142965142966142967142968142969142970142971142972142973142974142975142976142977142978142979142980142981142982142983142984142985142986142987142988142989142990142991142992142993142994142995142996142997142998142999143000143001143002143003143004143005143006143007143008143009143010143011143012143013143014143015143016143017143018143019143020143021143022143023143024143025143026143027143028143029143030143031143032143033143034143035143036143037143038143039143040143041143042143043143044143045143046143047143048143049143050143051143052143053143054143055143056143057143058143059143060143061143062143063143064143065143066143067143068143069143070143071143072143073143074143075143076143077143078143079143080143081143082143083143084143085143086143087143088143089143090143091143092143093143094143095143096143097143098143099143100143101143102143103143104143105143106143107143108143109143110143111143112143113143114143115143116143117143118143119143120143121143122143123143124143125143126143127143128143129143130143131143132143133143134143135143136143137143138143139143140143141143142143143143144143145143146143147143148143149143150143151143152143153143154143155143156143157143158143159143160143161143162143163143164143165143166143167143168143169143170143171143172143173143174143175143176143177143178143179143180143181143182143183143184143185143186143187143188143189143190143191143192143193143194143195143196143197143198143199143200143201143202143203143204143205143206143207143208143209143210143211143212143213143214143215143216143217143218143219143220143221143222143223143224143225143226143227143228143229143230143231143232143233143234143235143236143237143238143239143240143241143242143243143244143245143246143247143248143249143250143251143252143253143254143255143256143257143258143259143260143261143262143263143264143265143266143267143268143269143270143271143272143273143274143275143276143277143278143279143280143281143282143283143284143285143286143287143288143289143290143291143292143293143294143295143296143297143298143299143300143301143302143303143304143305143306143307143308143309143310143311143312143313143314143315143316143317143318143319143320143321143322143323143324143325143326143327143328143329143330143331143332143333143334143335143336143337143338143339143340143341143342143343143344143345143346143347143348143349143350143351143352143353143354143355143356143357143358143359143360143361143362143363143364143365143366143367143368143369143370143371143372143373143374143375143376143377143378143379143380143381143382143383143384143385143386143387143388143389143390143391143392143393143394143395143396143397143398143399143400143401143402143403143404143405143406143407143408143409143410143411143412143413143414143415143416143417143418143419143420143421143422143423143424143425143426143427143428143429143430143431143432143433143434143435143436143437143438143439143440143441143442143443143444143445143446143447143448143449143450143451143452143453143454143455143456143457143458143459143460143461143462143463143464143465143466143467143468143469143470143471143472143473143474143475143476143477143478143479143480143481143482143483143484143485143486143487143488143489143490143491143492143493143494143495143496143497143498143499143500143501143502143503143504143505143506143507143508143509143510143511143512143513143514143515143516143517143518143519143520143521143522143523143524143525143526143527143528143529143530143531143532143533143534143535143536143537143538143539143540143541143542143543143544143545143546143547143548143549143550143551143552143553143554143555143556143557143558143559143560143561143562143563143564143565143566143567143568143569143570143571143572143573143574143575143576143577143578143579143580143581143582143583143584143585143586143587143588143589143590143591143592143593143594143595143596143597143598143599143600143601143602143603143604143605143606143607143608143609143610143611143612143613143614143615143616143617143618143619143620143621143622143623143624143625143626143627143628143629143630143631143632143633143634143635143636143637143638143639143640143641143642143643143644143645143646143647143648143649143650143651143652143653143654143655143656143657143658143659143660143661143662143663143664143665143666143667143668143669143670143671143672143673143674143675143676143677143678143679143680143681143682143683143684143685143686143687143688143689143690143691143692143693143694143695143696143697143698143699143700143701143702143703143704143705143706143707143708143709143710143711143712143713143714143715143716143717143718143719143720143721143722143723143724143725143726143727143728143729143730143731143732143733143734143735143736143737143738143739143740143741143742143743143744143745143746143747143748143749143750143751143752143753143754143755143756143757143758143759143760143761143762143763143764143765143766143767143768143769143770143771143772143773143774143775143776143777143778143779143780143781143782143783143784143785143786143787143788143789143790143791143792143793143794143795143796143797143798143799143800143801143802143803143804143805143806143807143808143809143810143811143812143813143814143815143816143817143818143819143820143821143822143823143824143825143826143827143828143829143830143831143832143833143834143835143836143837143838143839143840143841143842143843143844143845143846143847143848143849143850143851143852143853143854143855143856143857143858143859143860143861143862143863143864143865143866143867143868143869143870143871143872143873143874143875143876143877143878143879143880143881143882143883143884143885143886143887143888143889143890143891143892143893143894143895143896143897143898143899143900143901143902143903143904143905143906143907143908143909143910143911143912143913143914143915143916143917143918143919143920143921143922143923143924143925143926143927143928143929143930143931143932143933143934143935143936143937143938143939143940143941143942143943143944143945143946143947143948143949143950143951143952143953143954143955143956143957143958143959143960143961143962143963143964143965143966143967143968143969143970143971143972143973143974143975143976143977143978143979143980143981143982143983143984143985143986143987143988143989143990143991143992143993143994143995143996143997143998143999144000144001144002144003144004144005144006144007144008144009144010144011144012144013144014144015144016144017144018144019144020144021144022144023144024144025144026144027144028144029144030144031144032144033144034144035144036144037144038144039144040144041144042144043144044144045144046144047144048144049144050144051144052144053144054144055144056144057144058144059144060144061144062144063144064144065144066144067144068144069144070144071144072144073144074144075144076144077144078144079144080144081144082144083144084144085144086144087144088144089144090144091144092144093144094144095144096144097144098144099144100144101144102144103144104144105144106144107144108144109144110144111144112144113144114144115144116144117144118144119144120144121144122144123144124144125144126144127144128144129144130144131144132144133144134144135144136144137144138144139144140144141144142144143144144144145144146144147144148144149144150144151144152144153144154144155144156144157144158144159144160144161144162144163144164144165144166144167144168144169144170144171144172144173144174144175144176144177144178144179144180144181144182144183144184144185144186144187144188144189144190144191144192144193144194144195144196144197144198144199144200144201144202144203144204144205144206144207144208144209144210144211144212144213144214144215144216144217144218144219144220144221144222144223144224144225144226144227144228144229144230144231144232144233144234144235144236144237144238144239144240144241144242144243144244144245144246144247144248144249144250144251144252144253144254144255144256144257144258144259144260144261144262144263144264144265144266144267144268144269144270144271144272144273144274144275144276144277144278144279144280144281144282144283144284144285144286144287144288144289144290144291144292144293144294144295144296144297144298144299144300144301144302144303144304144305144306144307144308144309144310144311144312144313144314144315144316144317144318144319144320144321144322144323144324144325144326144327144328144329144330144331144332144333144334144335144336144337144338144339144340144341144342144343144344144345144346144347144348144349144350144351144352144353144354144355144356144357144358144359144360144361144362144363144364144365144366144367144368144369144370144371144372144373144374144375144376144377144378144379144380144381144382144383144384144385144386144387144388144389144390144391144392144393144394144395144396144397144398144399144400144401144402144403144404144405144406144407144408144409144410144411144412144413144414144415144416144417144418144419144420144421144422144423144424144425144426144427144428144429144430144431144432144433144434144435144436144437144438144439144440144441144442144443144444144445144446144447144448144449144450144451144452144453144454144455144456144457144458144459144460144461144462144463144464144465144466144467144468144469144470144471144472144473144474144475144476144477144478144479144480144481144482144483144484144485144486144487144488144489144490144491144492144493144494144495144496144497144498144499144500144501144502144503144504144505144506144507144508144509144510144511144512144513144514144515144516144517144518144519144520144521144522144523144524144525144526144527144528144529144530144531144532144533144534144535144536144537144538144539144540144541144542144543144544144545144546144547144548144549144550144551144552144553144554144555144556144557144558144559144560144561144562144563144564144565144566144567144568144569144570144571144572144573144574144575144576144577144578144579144580144581144582144583144584144585144586144587144588144589144590144591144592144593144594144595144596144597144598144599144600144601144602144603144604144605144606144607144608144609144610144611144612144613144614144615144616144617144618144619144620144621144622144623144624144625144626144627144628144629144630144631144632144633144634144635144636144637144638144639144640144641144642144643144644144645144646144647144648144649144650144651144652144653144654144655144656144657144658144659144660144661144662144663144664144665144666144667144668144669144670144671144672144673144674144675144676144677144678144679144680144681144682144683144684144685144686144687144688144689144690144691144692144693144694144695144696144697144698144699144700144701144702144703144704144705144706144707144708144709144710144711144712144713144714144715144716144717144718144719144720144721144722144723144724144725144726144727144728144729144730144731144732144733144734144735144736144737144738144739144740144741144742144743144744144745144746144747144748144749144750144751144752144753144754144755144756144757144758144759144760144761144762144763144764144765144766144767144768144769144770144771144772144773144774144775144776144777144778144779144780144781144782144783144784144785144786144787144788144789144790144791144792144793144794144795144796144797144798144799144800144801144802144803144804144805144806144807144808144809144810144811144812144813144814144815144816144817144818144819144820144821144822144823144824144825144826144827144828144829144830144831144832144833144834144835144836144837144838144839144840144841144842144843144844144845144846144847144848144849144850144851144852144853144854144855144856144857144858144859144860144861144862144863144864144865144866144867144868144869144870144871144872144873144874144875144876144877144878144879144880144881144882144883144884144885144886144887144888144889144890144891144892144893144894144895144896144897144898144899144900144901144902144903144904144905144906144907144908144909144910144911144912144913144914144915144916144917144918144919144920144921144922144923144924144925144926144927144928144929144930144931144932144933144934144935144936144937144938144939144940144941144942144943144944144945144946144947144948144949144950144951144952144953144954144955144956144957144958144959144960144961144962144963144964144965144966144967144968144969144970144971144972144973144974144975144976144977144978144979144980144981144982144983144984144985144986144987144988144989144990144991144992144993144994144995144996144997144998144999145000145001145002145003145004145005145006145007145008145009145010145011145012145013145014145015145016145017145018145019145020145021145022145023145024145025145026145027145028145029145030145031145032145033145034145035145036145037145038145039145040145041145042145043145044145045145046145047145048145049145050145051145052145053145054145055145056145057145058145059145060145061145062145063145064145065145066145067145068145069145070145071145072145073145074145075145076145077145078145079145080145081145082145083145084145085145086145087145088145089145090145091145092145093145094145095145096145097145098145099145100145101145102145103145104145105145106145107145108145109145110145111145112145113145114145115145116145117145118145119145120145121145122145123145124145125145126145127145128145129145130145131145132145133145134145135145136145137145138145139145140145141145142145143145144145145145146145147145148145149145150145151145152145153145154145155145156145157145158145159145160145161145162145163145164145165145166145167145168145169145170145171145172145173145174145175145176145177145178145179145180145181145182145183145184145185145186145187145188145189145190145191145192145193145194145195145196145197145198145199145200145201145202145203145204145205145206145207145208145209145210145211145212145213145214145215145216145217145218145219145220145221145222145223145224145225145226145227145228145229145230145231145232145233145234145235145236145237145238145239145240145241145242145243145244145245145246145247145248145249145250145251145252145253145254145255145256145257145258145259145260145261145262145263145264145265145266145267145268145269145270145271145272145273145274145275145276145277145278145279145280145281145282145283145284145285145286145287145288145289145290145291145292145293145294145295145296145297145298145299145300145301145302145303145304145305145306145307145308145309145310145311145312145313145314145315145316145317145318145319145320145321145322145323145324145325145326145327145328145329145330145331145332145333145334145335145336145337145338145339145340145341145342145343145344145345145346145347145348145349145350145351145352145353145354145355145356145357145358145359145360145361145362145363145364145365145366145367145368145369145370145371145372145373145374145375145376145377145378145379145380145381145382145383145384145385145386145387145388145389145390145391145392145393145394145395145396145397145398145399145400145401145402145403145404145405145406145407145408145409145410145411145412145413145414145415145416145417145418145419145420145421145422145423145424145425145426145427145428145429145430145431145432145433145434145435145436145437145438145439145440145441145442145443145444145445145446145447145448145449145450145451145452145453145454145455145456145457145458145459145460145461145462145463145464145465145466145467145468145469145470145471145472145473145474145475145476145477145478145479145480145481145482145483145484145485145486145487145488145489145490145491145492145493145494145495145496145497145498145499145500145501145502145503145504145505145506145507145508145509145510145511145512145513145514145515145516145517145518145519145520145521145522145523145524145525145526145527145528145529145530145531145532145533145534145535145536145537145538145539145540145541145542145543145544145545145546145547145548145549145550145551145552145553145554145555145556145557145558145559145560145561145562145563145564145565145566145567145568145569145570145571145572145573145574145575145576145577145578145579145580145581145582145583145584145585145586145587145588145589145590145591145592145593145594145595145596145597145598145599145600145601145602145603145604145605145606145607145608145609145610145611145612145613145614145615145616145617145618145619145620145621145622145623145624145625145626145627145628145629145630145631145632145633145634145635145636145637145638145639145640145641145642145643145644145645145646145647145648145649145650145651145652145653145654145655145656145657145658145659145660145661145662145663145664145665145666145667145668145669145670145671145672145673145674145675145676145677145678145679145680145681145682145683145684145685145686145687145688145689145690145691145692145693145694145695145696145697145698145699145700145701145702145703145704145705145706145707145708145709145710145711145712145713145714145715145716145717145718145719145720145721145722145723145724145725145726145727145728145729145730145731145732145733145734145735145736145737145738145739145740145741145742145743145744145745145746145747145748145749145750145751145752145753145754145755145756145757145758145759145760145761145762145763145764145765145766145767145768145769145770145771145772145773145774145775145776145777145778145779145780145781145782145783145784145785145786145787145788145789145790145791145792145793145794145795145796145797145798145799145800145801145802145803145804145805145806145807145808145809145810145811145812145813145814145815145816145817145818145819145820145821145822145823145824145825145826145827145828145829145830145831145832145833145834145835145836145837145838145839145840145841145842145843145844145845145846145847145848145849145850145851145852145853145854145855145856145857145858145859145860145861145862145863145864145865145866145867145868145869145870145871145872145873145874145875145876145877145878145879145880145881145882145883145884145885145886145887145888145889145890145891145892145893145894145895145896145897145898145899145900145901145902145903145904145905145906145907145908145909145910145911145912145913145914145915145916145917145918145919145920145921145922145923145924145925145926145927145928145929145930145931145932145933145934145935145936145937145938145939145940145941145942145943145944145945145946145947145948145949145950145951145952145953145954145955145956145957145958145959145960145961145962145963145964145965145966145967145968145969145970145971145972145973145974145975145976145977145978145979145980145981145982145983145984145985145986145987145988145989145990145991145992145993145994145995145996145997145998145999146000146001146002146003146004146005146006146007146008146009146010146011146012146013146014146015146016146017146018146019146020146021146022146023146024146025146026146027146028146029146030146031146032146033146034146035146036146037146038146039146040146041146042146043146044146045146046146047146048146049146050146051146052146053146054146055146056146057146058146059146060146061146062146063146064146065146066146067146068146069146070146071146072146073146074146075146076146077146078146079146080146081146082146083146084146085146086146087146088146089146090146091146092146093146094146095146096146097146098146099146100146101146102146103146104146105146106146107146108146109146110146111146112146113146114146115146116146117146118146119146120146121146122146123146124146125146126146127146128146129146130146131146132146133146134146135146136146137146138146139146140146141146142146143146144146145146146146147146148146149146150146151146152146153146154146155146156146157146158146159146160146161146162146163146164146165146166146167146168146169146170146171146172146173146174146175146176146177146178146179146180146181146182146183146184146185146186146187146188146189146190146191146192146193146194146195146196146197146198146199146200146201146202146203146204146205146206146207146208146209146210146211146212146213146214146215146216146217146218146219146220146221146222146223146224146225146226146227146228146229146230146231146232146233146234146235146236146237146238146239146240146241146242146243146244146245146246146247146248146249146250146251146252146253146254146255146256146257146258146259146260146261146262146263146264146265146266146267146268146269146270146271146272146273146274146275146276146277146278146279146280146281146282146283146284146285146286146287146288146289146290146291146292146293146294146295146296146297146298146299146300146301146302146303146304146305146306146307146308146309146310146311146312146313146314146315146316146317146318146319146320146321146322146323146324146325146326146327146328146329146330146331146332146333146334146335146336146337146338146339146340146341146342146343146344146345146346146347146348146349146350146351146352146353146354146355146356146357146358146359146360146361146362146363146364146365146366146367146368146369146370146371146372146373146374146375146376146377146378146379146380146381146382146383146384146385146386146387146388146389146390146391146392146393146394146395146396146397146398146399146400146401146402146403146404146405146406146407146408146409146410146411146412146413146414146415146416146417146418146419146420146421146422146423146424146425146426146427146428146429146430146431146432146433146434146435146436146437146438146439146440146441146442146443146444146445146446146447146448146449146450146451146452146453146454146455146456146457146458146459146460146461146462146463146464146465146466146467146468146469146470146471146472146473146474146475146476146477146478146479146480146481146482146483146484146485146486146487146488146489146490146491146492146493146494146495146496146497146498146499146500146501146502146503146504146505146506146507146508146509146510146511146512146513146514146515146516146517146518146519146520146521146522146523146524146525146526146527146528146529146530146531146532146533146534146535146536146537146538146539146540146541146542146543146544146545146546146547146548146549146550146551146552146553146554146555146556146557146558146559146560146561146562146563146564146565146566146567146568146569146570146571146572146573146574146575146576146577146578146579146580146581146582146583146584146585146586146587146588146589146590146591146592146593146594146595146596146597146598146599146600146601146602146603146604146605146606146607146608146609146610146611146612146613146614146615146616146617146618146619146620146621146622146623146624146625146626146627146628146629146630146631146632146633146634146635146636146637146638146639146640146641146642146643146644146645146646146647146648146649146650146651146652146653146654146655146656146657146658146659146660146661146662146663146664146665146666146667146668146669146670146671146672146673146674146675146676146677146678146679146680146681146682146683146684146685146686146687146688146689146690146691146692146693146694146695146696146697146698146699146700146701146702146703146704146705146706146707146708146709146710146711146712146713146714146715146716146717146718146719146720146721146722146723146724146725146726146727146728146729146730146731146732146733146734146735146736146737146738146739146740146741146742146743146744146745146746146747146748146749146750146751146752146753146754146755146756146757146758146759146760146761146762146763146764146765146766146767146768146769146770146771146772146773146774146775146776146777146778146779146780146781146782146783146784146785146786146787146788146789146790146791146792146793146794146795146796146797146798146799146800146801146802146803146804146805146806146807146808146809146810146811146812146813146814146815146816146817146818146819146820146821146822146823146824146825146826146827146828146829146830146831146832146833146834146835146836146837146838146839146840146841146842146843146844146845146846146847146848146849146850146851146852146853146854146855146856146857146858146859146860146861146862146863146864146865146866146867146868146869146870146871146872146873146874146875146876146877146878146879146880146881146882146883146884146885146886146887146888146889146890146891146892146893146894146895146896146897146898146899146900146901146902146903146904146905146906146907146908146909146910146911146912146913146914146915146916146917146918146919146920146921146922146923146924146925146926146927146928146929146930146931146932146933146934146935146936146937146938146939146940146941146942146943146944146945146946146947146948146949146950146951146952146953146954146955146956146957146958146959146960146961146962146963146964146965146966146967146968146969146970146971146972146973146974146975146976146977146978146979146980146981146982146983146984146985146986146987146988146989146990146991146992146993146994146995146996146997146998146999147000147001147002147003147004147005147006147007147008147009147010147011147012147013147014147015147016147017147018147019147020147021147022147023147024147025147026147027147028147029147030147031147032147033147034147035147036147037147038147039147040147041147042147043147044147045147046147047147048147049147050147051147052147053147054147055147056147057147058147059147060147061147062147063147064147065147066147067147068147069147070147071147072147073147074147075147076147077147078147079147080147081147082147083147084147085147086147087147088147089147090147091147092147093147094147095147096147097147098147099147100147101147102147103147104147105147106147107147108147109147110147111147112147113147114147115147116147117147118147119147120147121147122147123147124147125147126147127147128147129147130147131147132147133147134147135147136147137147138147139147140147141147142147143147144147145147146147147147148147149147150147151147152147153147154147155147156147157147158147159147160147161147162147163147164147165147166147167147168147169147170147171147172147173147174147175147176147177147178147179147180147181147182147183147184147185147186147187147188147189147190147191147192147193147194147195147196147197147198147199147200147201147202147203147204147205147206147207147208147209147210147211147212147213147214147215147216147217147218147219147220147221147222147223147224147225147226147227147228147229147230147231147232147233147234147235147236147237147238147239147240147241147242147243147244147245147246147247147248147249147250147251147252147253147254147255147256147257147258147259147260147261147262147263147264147265147266147267147268147269147270147271147272147273147274147275147276147277147278147279147280147281147282147283147284147285147286147287147288147289147290147291147292147293147294147295147296147297147298147299147300147301147302147303147304147305147306147307147308147309147310147311147312147313147314147315147316147317147318147319147320147321147322147323147324147325147326147327147328147329147330147331147332147333147334147335147336147337147338147339147340147341147342147343147344147345147346147347147348147349147350147351147352147353147354147355147356147357147358147359147360147361147362147363147364147365147366147367147368147369147370147371147372147373147374147375147376147377147378147379147380147381147382147383147384147385147386147387147388147389147390147391147392147393147394147395147396147397147398147399147400147401147402147403147404147405147406147407147408147409147410147411147412147413147414147415147416147417147418147419147420147421147422147423147424147425147426147427147428147429147430147431147432147433147434147435147436147437147438147439147440147441147442147443147444147445147446147447147448147449147450147451147452147453147454147455147456147457147458147459147460147461147462147463147464147465147466147467147468147469147470147471147472147473147474147475147476147477147478147479147480147481147482147483147484147485147486147487147488147489147490147491147492147493147494147495147496147497147498147499147500147501147502147503147504147505147506147507147508147509147510147511147512147513147514147515147516147517147518147519147520147521147522147523147524147525147526147527147528147529147530147531147532147533147534147535147536147537147538147539147540147541147542147543147544147545147546147547147548147549147550147551147552147553147554147555147556147557147558147559147560147561147562147563147564147565147566147567147568147569147570147571147572147573147574147575147576147577147578147579147580147581147582147583147584147585147586147587147588147589147590147591147592147593147594147595147596147597147598147599147600147601147602147603147604147605147606147607147608147609147610147611147612147613147614147615147616147617147618147619147620147621147622147623147624147625147626147627147628147629147630147631147632147633147634147635147636147637147638147639147640147641147642147643147644147645147646147647147648147649147650147651147652147653147654147655147656147657147658147659147660147661147662147663147664147665147666147667147668147669147670147671147672147673147674147675147676147677147678147679147680147681147682147683147684147685147686147687147688147689147690147691147692147693147694147695147696147697147698147699147700147701147702147703147704147705147706147707147708147709147710147711147712147713147714147715147716147717147718147719147720147721147722147723147724147725147726147727147728147729147730147731147732147733147734147735147736147737147738147739147740147741147742147743147744147745147746147747147748147749147750147751147752147753147754147755147756147757147758147759147760147761147762147763147764147765147766147767147768147769147770147771147772147773147774147775147776147777147778147779147780147781147782147783147784147785147786147787147788147789147790147791147792147793147794147795147796147797147798147799147800147801147802147803147804147805147806147807147808147809147810147811147812147813147814147815147816147817147818147819147820147821147822147823147824147825147826147827147828147829147830147831147832147833147834147835147836147837147838147839147840147841147842147843147844147845147846147847147848147849147850147851147852147853147854147855147856147857147858147859147860147861147862147863147864147865147866147867147868147869147870147871147872147873147874147875147876147877147878147879147880147881147882147883147884147885147886147887147888147889147890147891147892147893147894147895147896147897147898147899147900147901147902147903147904147905147906147907147908147909147910147911147912147913147914147915147916147917147918147919147920147921147922147923147924147925147926147927147928147929147930147931147932147933147934147935147936147937147938147939147940147941147942147943147944147945147946147947147948147949147950147951147952147953147954147955147956147957147958147959147960147961147962147963147964147965147966147967147968147969147970147971147972147973147974147975147976147977147978147979147980147981147982147983147984147985147986147987147988147989147990147991147992147993147994147995147996147997147998147999148000148001148002148003148004148005148006148007148008148009148010148011148012148013148014148015148016148017148018148019148020148021148022148023148024148025148026148027148028148029148030148031148032148033148034148035148036148037148038148039148040148041148042148043148044148045148046148047148048148049148050148051148052148053148054148055148056148057148058148059148060148061148062148063148064148065148066148067148068148069148070148071148072148073148074148075148076148077148078148079148080148081148082148083148084148085148086148087148088148089148090148091148092148093148094148095148096148097148098148099148100148101148102148103148104148105148106148107148108148109148110148111148112148113148114148115148116148117148118148119148120148121148122148123148124148125148126148127148128148129148130148131148132148133148134148135148136148137148138148139148140148141148142148143148144148145148146148147148148148149148150148151148152148153148154148155148156148157148158148159148160148161148162148163148164148165148166148167148168148169148170148171148172148173148174148175148176148177148178148179148180148181148182148183148184148185148186148187148188148189148190148191148192148193148194148195148196148197148198148199148200148201148202148203148204148205148206148207148208148209148210148211148212148213148214148215148216148217148218148219148220148221148222148223148224148225148226148227148228148229148230148231148232148233148234148235148236148237148238148239148240148241148242148243148244148245148246148247148248148249148250148251148252148253148254148255148256148257148258148259148260148261148262148263148264148265148266148267148268148269148270148271148272148273148274148275148276148277148278148279148280148281148282148283148284148285148286148287148288148289148290148291148292148293148294148295148296148297148298148299148300148301148302148303148304148305148306148307148308148309148310148311148312148313148314148315148316148317148318148319148320148321148322148323148324148325148326148327148328148329148330148331148332148333148334148335148336148337148338148339148340148341148342148343148344148345148346148347148348148349148350148351148352148353148354148355148356148357148358148359148360148361148362148363148364148365148366148367148368148369148370148371148372148373148374148375148376148377148378148379148380148381148382148383148384148385148386148387148388148389148390148391148392148393148394148395148396148397148398148399148400148401148402148403148404148405148406148407148408148409148410148411148412148413148414148415148416148417148418148419148420148421148422148423148424148425148426148427148428148429148430148431148432148433148434148435148436148437148438148439148440148441148442148443148444148445148446148447148448148449148450148451148452148453148454148455148456148457148458148459148460148461148462148463148464148465148466148467148468148469148470148471148472148473148474148475148476148477148478148479148480148481148482148483148484148485148486148487148488148489148490148491148492148493148494148495148496148497148498148499148500148501148502148503148504148505148506148507148508148509148510148511148512148513148514148515148516148517148518148519148520148521148522148523148524148525148526148527148528148529148530148531148532148533148534148535148536148537148538148539148540148541148542148543148544148545148546148547148548148549148550148551148552148553148554148555148556148557148558148559148560148561148562148563148564148565148566148567148568148569148570148571148572148573148574148575148576148577148578148579148580148581148582148583148584148585148586148587148588148589148590148591148592148593148594148595148596148597148598148599148600148601148602148603148604148605148606148607148608148609148610148611148612148613148614148615148616148617148618148619148620148621148622148623148624148625148626148627148628148629148630148631148632148633148634148635148636148637148638148639148640148641148642148643148644148645148646148647148648148649148650148651148652148653148654148655148656148657148658148659148660148661148662148663148664148665148666148667148668148669148670148671148672148673148674148675148676148677148678148679148680148681148682148683148684148685148686148687148688148689148690148691148692148693148694148695148696148697148698148699148700148701148702148703148704148705148706148707148708148709148710148711148712148713148714148715148716148717148718148719148720148721148722148723148724148725148726148727148728148729148730148731148732148733148734148735148736148737148738148739148740148741148742148743148744148745148746148747148748148749148750148751148752148753148754148755148756148757148758148759148760148761148762148763148764148765148766148767148768148769148770148771148772148773148774148775148776148777148778148779148780148781148782148783148784148785148786148787148788148789148790148791148792148793148794148795148796148797148798148799148800148801148802148803148804148805148806148807148808148809148810148811148812148813148814148815148816148817148818148819148820148821148822148823148824148825148826148827148828148829148830148831148832148833148834148835148836148837148838148839148840148841148842148843148844148845148846148847148848148849148850148851148852148853148854148855148856148857148858148859148860148861148862148863148864148865148866148867148868148869148870148871148872148873148874148875148876148877148878148879148880148881148882148883148884148885148886148887148888148889148890148891148892148893148894148895148896148897148898148899148900148901148902148903148904148905148906148907148908148909148910148911148912148913148914148915148916148917148918148919148920148921148922148923148924148925148926148927148928148929148930148931148932148933148934148935148936148937148938148939148940148941148942148943148944148945148946148947148948148949148950148951148952148953148954148955148956148957148958148959148960148961148962148963148964148965148966148967148968148969148970148971148972148973148974148975148976148977148978148979148980148981148982148983148984148985148986148987148988148989148990148991148992148993148994148995148996148997148998148999149000149001149002149003149004149005149006149007149008149009149010149011149012149013149014149015149016149017149018149019149020149021149022149023149024149025149026149027149028149029149030149031149032149033149034149035149036149037149038149039149040149041149042149043149044149045149046149047149048149049149050149051149052149053149054149055149056149057149058149059149060149061149062149063149064149065149066149067149068149069149070149071149072149073149074149075149076149077149078149079149080149081149082149083149084149085149086149087149088149089149090149091149092149093149094149095149096149097149098149099149100149101149102149103149104149105149106149107149108149109149110149111149112149113149114149115149116149117149118149119149120149121149122149123149124149125149126149127149128149129149130149131149132149133149134149135149136149137149138149139149140149141149142149143149144149145149146149147149148149149149150149151149152149153149154149155149156149157149158149159149160149161149162149163149164149165149166149167149168149169149170149171149172149173149174149175149176149177149178149179149180149181149182149183149184149185149186149187149188149189149190149191149192149193149194149195149196149197149198149199149200149201149202149203149204149205149206149207149208149209149210149211149212149213149214149215149216149217149218149219149220149221149222149223149224149225149226149227149228149229149230149231149232149233149234149235149236149237149238149239149240149241149242149243149244149245149246149247149248149249149250149251149252149253149254149255149256149257149258149259149260149261149262149263149264149265149266149267149268149269149270149271149272149273149274149275149276149277149278149279149280149281149282149283149284149285149286149287149288149289149290149291149292149293149294149295149296149297149298149299149300149301149302149303149304149305149306149307149308149309149310149311149312149313149314149315149316149317149318149319149320149321149322149323149324149325149326149327149328149329149330149331149332149333149334149335149336149337149338149339149340149341149342149343149344149345149346149347149348149349149350149351149352149353149354149355149356149357149358149359149360149361149362149363149364149365149366149367149368149369149370149371149372149373149374149375149376149377149378149379149380149381149382149383149384149385149386149387149388149389149390149391149392149393149394149395149396149397149398149399149400149401149402149403149404149405149406149407149408149409149410149411149412149413149414149415149416149417149418149419149420149421149422149423149424149425149426149427149428149429149430149431149432149433149434149435149436149437149438149439149440149441149442149443149444149445149446149447149448149449149450149451149452149453149454149455149456149457149458149459149460149461149462149463149464149465149466149467149468149469149470149471149472149473149474149475149476149477149478149479149480149481149482149483149484149485149486149487149488149489149490149491149492149493149494149495149496149497149498149499149500149501149502149503149504149505149506149507149508149509149510149511149512149513149514149515149516149517149518149519149520149521149522149523149524149525149526149527149528149529149530149531149532149533149534149535149536149537149538149539149540149541149542149543149544149545149546149547149548149549149550149551149552149553149554149555149556149557149558149559149560149561149562149563149564149565149566149567149568149569149570149571149572149573149574149575149576149577149578149579149580149581149582149583149584149585149586149587149588149589149590149591149592149593149594149595149596149597149598149599149600149601149602149603149604149605149606149607149608149609149610149611149612149613149614149615149616149617149618149619149620149621149622149623149624149625149626149627149628149629149630149631149632149633149634149635149636149637149638149639149640149641149642149643149644149645149646149647149648149649149650149651149652149653149654149655149656149657149658149659149660149661149662149663149664149665149666149667149668149669149670149671149672149673149674149675149676149677149678149679149680149681149682149683149684149685149686149687149688149689149690149691149692149693149694149695149696149697149698149699149700149701149702149703149704149705149706149707149708149709149710149711149712149713149714149715149716149717149718149719149720149721149722149723149724149725149726149727149728149729149730149731149732149733149734149735149736149737149738149739149740149741149742149743149744149745149746149747149748149749149750149751149752149753149754149755149756149757149758149759149760149761149762149763149764149765149766149767149768149769149770149771149772149773149774149775149776149777149778149779149780149781149782149783149784149785149786149787149788149789149790149791149792149793149794149795149796149797149798149799149800149801149802149803149804149805149806149807149808149809149810149811149812149813149814149815149816149817149818149819149820149821149822149823149824149825149826149827149828149829149830149831149832149833149834149835149836149837149838149839149840149841149842149843149844149845149846149847149848149849149850149851149852149853149854149855149856149857149858149859149860149861149862149863149864149865149866149867149868149869149870149871149872149873149874149875149876149877149878149879149880149881149882149883149884149885149886149887149888149889149890149891149892149893149894149895149896149897149898149899149900149901149902149903149904149905149906149907149908149909149910149911149912149913149914149915149916149917149918149919149920149921149922149923149924149925149926149927149928149929149930149931149932149933149934149935149936149937149938149939149940149941149942149943149944149945149946149947149948149949149950149951149952149953149954149955149956149957149958149959149960149961149962149963149964149965149966149967149968149969149970149971149972149973149974149975149976149977149978149979149980149981149982149983149984149985149986149987149988149989149990149991149992149993149994149995149996149997149998149999150000150001150002150003150004150005150006150007150008150009150010150011150012150013150014150015150016150017150018150019150020150021150022150023150024150025150026150027150028150029150030150031150032150033150034150035150036150037150038150039150040150041150042150043150044150045150046150047150048150049150050150051150052150053150054150055150056150057150058150059150060150061150062150063150064150065150066150067150068150069150070150071150072150073150074150075150076150077150078150079150080150081150082150083150084150085150086150087150088150089150090150091150092150093150094150095150096150097150098150099150100150101150102150103150104150105150106150107150108150109150110150111150112150113150114150115150116150117150118150119150120150121150122150123150124150125150126150127150128150129150130150131150132150133150134150135150136150137150138150139150140150141150142150143150144150145150146150147150148150149150150150151150152150153150154150155150156150157150158150159150160150161150162150163150164150165150166150167150168150169150170150171150172150173150174150175150176150177150178150179150180150181150182150183150184150185150186150187150188150189150190150191150192150193150194150195150196150197150198150199150200150201150202150203150204150205150206150207150208150209150210150211150212150213150214150215150216150217150218150219150220150221150222150223150224150225150226150227150228150229150230150231150232150233150234150235150236150237150238150239150240150241150242150243150244150245150246150247150248150249150250150251150252150253150254150255150256150257150258150259150260150261150262150263150264150265150266150267150268150269150270150271150272150273150274150275150276150277150278150279150280150281150282150283150284150285150286150287150288150289150290150291150292150293150294150295150296150297150298150299150300150301150302150303150304150305150306150307150308150309150310150311150312150313150314150315150316150317150318150319150320150321150322150323150324150325150326150327150328150329150330150331150332150333150334150335150336150337150338150339150340150341150342150343150344150345150346150347150348150349150350150351150352150353150354150355150356150357150358150359150360150361150362150363150364150365150366150367150368150369150370150371150372150373150374150375150376150377150378150379150380150381150382150383150384150385150386150387150388150389150390150391150392150393150394150395150396150397150398150399150400150401150402150403150404150405150406150407150408150409150410150411150412150413150414150415150416150417150418150419150420150421150422150423150424150425150426150427150428150429150430150431150432150433150434150435150436150437150438150439150440150441150442150443150444150445150446150447150448150449150450150451150452150453150454150455150456150457150458150459150460150461150462150463150464150465150466150467150468150469150470150471150472150473150474150475150476150477150478150479150480150481150482150483150484150485150486150487150488150489150490150491150492150493150494150495150496150497150498150499150500150501150502150503150504150505150506150507150508150509150510150511150512150513150514150515150516150517150518150519150520150521150522150523150524150525150526150527150528150529150530150531150532150533150534150535150536150537150538150539150540150541150542150543150544150545150546150547150548150549150550150551150552150553150554150555150556150557150558150559150560150561150562150563150564150565150566150567150568150569150570150571150572150573150574150575150576150577150578150579150580150581150582150583150584150585150586150587150588150589150590150591150592150593150594150595150596150597150598150599150600150601150602150603150604150605150606150607150608150609150610150611150612150613150614150615150616150617150618150619150620150621150622150623150624150625150626150627150628150629150630150631150632150633150634150635150636150637150638150639150640150641150642150643150644150645150646150647150648150649150650150651150652150653150654150655150656150657150658150659150660150661150662150663150664150665150666150667150668150669150670150671150672150673150674150675150676150677150678150679150680150681150682150683150684150685150686150687150688150689150690150691150692150693150694150695150696150697150698150699150700150701150702150703150704150705150706150707150708150709150710150711150712150713150714150715150716150717150718150719150720150721150722150723150724150725150726150727150728150729150730150731150732150733150734150735150736150737150738150739150740150741150742150743150744150745150746150747150748150749150750150751150752150753150754150755150756150757150758150759150760150761150762150763150764150765150766150767150768150769150770150771150772150773150774150775150776150777150778150779150780150781150782150783150784150785150786150787150788150789150790150791150792150793150794150795150796150797150798150799150800150801150802150803150804150805150806150807150808150809150810150811150812150813150814150815150816150817150818150819150820150821150822150823150824150825150826150827150828150829150830150831150832150833150834150835150836150837150838150839150840150841150842150843150844150845150846150847150848150849150850150851150852150853150854150855150856150857150858150859150860150861150862150863150864150865150866150867150868150869150870150871150872150873150874150875150876150877150878150879150880150881150882150883150884150885150886150887150888150889150890150891150892150893150894150895150896150897150898150899150900150901150902150903150904150905150906150907150908150909150910150911150912150913150914150915150916150917150918150919150920150921150922150923150924150925150926150927150928150929150930150931150932150933150934150935150936150937150938150939150940150941150942150943150944150945150946150947150948150949150950150951150952150953150954150955150956150957150958150959150960150961150962150963150964150965150966150967150968150969150970150971150972150973150974150975150976150977150978150979150980150981150982150983150984150985150986150987150988150989150990150991150992150993150994150995150996150997150998150999151000151001151002151003151004151005151006151007151008151009151010151011151012151013151014151015151016151017151018151019151020151021151022151023151024151025151026151027151028151029151030151031151032151033151034151035151036151037151038151039151040151041151042151043151044151045151046151047151048151049151050151051151052151053151054151055151056151057151058151059151060151061151062151063151064151065151066151067151068151069151070151071151072151073151074151075151076151077151078151079151080151081151082151083151084151085151086151087151088151089151090151091151092151093151094151095151096151097151098151099151100151101151102151103151104151105151106151107151108151109151110151111151112151113151114151115151116151117151118151119151120151121151122151123151124151125151126151127151128151129151130151131151132151133151134151135151136151137151138151139151140151141151142151143151144151145151146151147151148151149151150151151151152151153151154151155151156151157151158151159151160151161151162151163151164151165151166151167151168151169151170151171151172151173151174151175151176151177151178151179151180151181151182151183151184151185151186151187151188151189151190151191151192151193151194151195151196151197151198151199151200151201151202151203151204151205151206151207151208151209151210151211151212151213151214151215151216151217151218151219151220151221151222151223151224151225151226151227151228151229151230151231151232151233151234151235151236151237151238151239151240151241151242151243151244151245151246151247151248151249151250151251151252151253151254151255151256151257151258151259151260151261151262151263151264151265151266151267151268151269151270151271151272151273151274151275151276151277151278151279151280151281151282151283151284151285151286151287151288151289151290151291151292151293151294151295151296151297151298151299151300151301151302151303151304151305151306151307151308151309151310151311151312151313151314151315151316151317151318151319151320151321151322151323151324151325151326151327151328151329151330151331151332151333151334151335151336151337151338151339151340151341151342151343151344151345151346151347151348151349151350151351151352151353151354151355151356151357151358151359151360151361151362151363151364151365151366151367151368151369151370151371151372151373151374151375151376151377151378151379151380151381151382151383151384151385151386151387151388151389151390151391151392151393151394151395151396151397151398151399151400151401151402151403151404151405151406151407151408151409151410151411151412151413151414151415151416151417151418151419151420151421151422151423151424151425151426151427151428151429151430151431151432151433151434151435151436151437151438151439151440151441151442151443151444151445151446151447151448151449151450151451151452151453151454151455151456151457151458151459151460151461151462151463151464151465151466151467151468151469151470151471151472151473151474151475151476151477151478151479151480151481151482151483151484151485151486151487151488151489151490151491151492151493151494151495151496151497151498151499151500151501151502151503151504151505151506151507151508151509151510151511151512151513151514151515151516151517151518151519151520151521151522151523151524151525151526151527151528151529151530151531151532151533151534151535151536151537151538151539151540151541151542151543151544151545151546151547151548151549151550151551151552151553151554151555151556151557151558151559151560151561151562151563151564151565151566151567151568151569151570151571151572151573151574151575151576151577151578151579151580151581151582151583151584151585151586151587151588151589151590151591151592151593151594151595151596151597151598151599151600151601151602151603151604151605151606151607151608151609151610151611151612151613151614151615151616151617151618151619151620151621151622151623151624151625151626151627151628151629151630151631151632151633151634151635151636151637151638151639151640151641151642151643151644151645151646151647151648151649151650151651151652151653151654151655151656151657151658151659151660151661151662151663151664151665151666151667151668151669151670151671151672151673151674151675151676151677151678151679151680151681151682151683151684151685151686151687151688151689151690151691151692151693151694151695151696151697151698151699151700151701151702151703151704151705151706151707151708151709151710151711151712151713151714151715151716151717151718151719151720151721151722151723151724151725151726151727151728151729151730151731151732151733151734151735151736151737151738151739151740151741151742151743151744151745151746151747151748151749151750151751151752151753151754151755151756151757151758151759151760151761151762151763151764151765151766151767151768151769151770151771151772151773151774151775151776151777151778151779151780151781151782151783151784151785151786151787151788151789151790151791151792151793151794151795151796151797151798151799151800151801151802151803151804151805151806151807151808151809151810151811151812151813151814151815151816151817151818151819151820151821151822151823151824151825151826151827151828151829151830151831151832151833151834151835151836151837151838151839151840151841151842151843151844151845151846151847151848151849151850151851151852151853151854151855151856151857151858151859151860151861151862151863151864151865151866151867151868151869151870151871151872151873151874151875151876151877151878151879151880151881151882151883151884151885151886151887151888151889151890151891151892151893151894151895151896151897151898151899151900151901151902151903151904151905151906151907151908151909151910151911151912151913151914151915151916151917151918151919151920151921151922151923151924151925151926151927151928151929151930151931151932151933151934151935151936151937151938151939151940151941151942151943151944151945151946151947151948151949151950151951151952151953151954151955151956151957151958151959151960151961151962151963151964151965151966151967151968151969151970151971151972151973151974151975151976151977151978151979151980151981151982151983151984151985151986151987151988151989151990151991151992151993151994151995151996151997151998151999152000152001152002152003152004152005152006152007152008152009152010152011152012152013152014152015152016152017152018152019152020152021152022152023152024152025152026152027152028152029152030152031152032152033152034152035152036152037152038152039152040152041152042152043152044152045152046152047152048152049152050152051152052152053152054152055152056152057152058152059152060152061152062152063152064152065152066152067152068152069152070152071152072152073152074152075152076152077152078152079152080152081152082152083152084152085152086152087152088152089152090152091152092152093152094152095152096152097152098152099152100152101152102152103152104152105152106152107152108152109152110152111152112152113152114152115152116152117152118152119152120152121152122152123152124152125152126152127152128152129152130152131152132152133152134152135152136152137152138152139152140152141152142152143152144152145152146152147152148152149152150152151152152152153152154152155152156152157152158152159152160152161152162152163152164152165152166152167152168152169152170152171152172152173152174152175152176152177152178152179152180152181152182152183152184152185152186152187152188152189152190152191152192152193152194152195152196152197152198152199152200152201152202152203152204152205152206152207152208152209152210152211152212152213152214152215152216152217152218152219152220152221152222152223152224152225152226152227152228152229152230152231152232152233152234152235152236152237152238152239152240152241152242152243152244152245152246152247152248152249152250152251152252152253152254152255152256152257152258152259152260152261152262152263152264152265152266152267152268152269152270152271152272152273152274152275152276152277152278152279152280152281152282152283152284152285152286152287152288152289152290152291152292152293152294152295152296152297152298152299152300152301152302152303152304152305152306152307152308152309152310152311152312152313152314152315152316152317152318152319152320152321152322152323152324152325152326152327152328152329152330152331152332152333152334152335152336152337152338152339152340152341152342152343152344152345152346152347152348152349152350152351152352152353152354152355152356152357152358152359152360152361152362152363152364152365152366152367152368152369152370152371152372152373152374152375152376152377152378152379152380152381152382152383152384152385152386152387152388152389152390152391152392152393152394152395152396152397152398152399152400152401152402152403152404152405152406152407152408152409152410152411152412152413152414152415152416152417152418152419152420152421152422152423152424152425152426152427152428152429152430152431152432152433152434152435152436152437152438152439152440152441152442152443152444152445152446152447152448152449152450152451152452152453152454152455152456152457152458152459152460152461152462152463152464152465152466152467152468152469152470152471152472152473152474152475152476152477152478152479152480152481152482152483152484152485152486152487152488152489152490152491152492152493152494152495152496152497152498152499152500152501152502152503152504152505152506152507152508152509152510152511152512152513152514152515152516152517152518152519152520152521152522152523152524152525152526152527152528152529152530152531152532152533152534152535152536152537152538152539152540152541152542152543152544152545152546152547152548152549152550152551152552152553152554152555152556152557152558152559152560152561152562152563152564152565152566152567152568152569152570152571152572152573152574152575152576152577152578152579152580152581152582152583152584152585152586152587152588152589152590152591152592152593152594152595152596152597152598152599152600152601152602152603152604152605152606152607152608152609152610152611152612152613152614152615152616152617152618152619152620152621152622152623152624152625152626152627152628152629152630152631152632152633152634152635152636152637152638152639152640152641152642152643152644152645152646152647152648152649152650152651152652152653152654152655152656152657152658152659152660152661152662152663152664152665152666152667152668152669152670152671152672152673152674152675152676152677152678152679152680152681152682152683152684152685152686152687152688152689152690152691152692152693152694152695152696152697152698152699152700152701152702152703152704152705152706152707152708152709152710152711152712152713152714152715152716152717152718152719152720152721152722152723152724152725152726152727152728152729152730152731152732152733152734152735152736152737152738152739152740152741152742152743152744152745152746152747152748152749152750152751152752152753152754152755152756152757152758152759152760152761152762152763152764152765152766152767152768152769152770152771152772152773152774152775152776152777152778152779152780152781152782152783152784152785152786152787152788152789152790152791152792152793152794152795152796152797152798152799152800152801152802152803152804152805152806152807152808152809152810152811152812152813152814152815152816152817152818152819152820152821152822152823152824152825152826152827152828152829152830152831152832152833152834152835152836152837152838152839152840152841152842152843152844152845152846152847152848152849152850152851152852152853152854152855152856152857152858152859152860152861152862152863152864152865152866152867152868152869152870152871152872152873152874152875152876152877152878152879152880152881152882152883152884152885152886152887152888152889152890152891152892152893152894152895152896152897152898152899152900152901152902152903152904152905152906152907152908152909152910152911152912152913152914152915152916152917152918152919152920152921152922152923152924152925152926152927152928152929152930152931152932152933152934152935152936152937152938152939152940152941152942152943152944152945152946152947152948152949152950152951152952152953152954152955152956152957152958152959152960152961152962152963152964152965152966152967152968152969152970152971152972152973152974152975152976152977152978152979152980152981152982152983152984152985152986152987152988152989152990152991152992152993152994152995152996152997152998152999153000153001153002153003153004153005153006153007153008153009153010153011153012153013153014153015153016153017153018153019153020153021153022153023153024153025153026153027153028153029153030153031153032153033153034153035153036153037153038153039153040153041153042153043153044153045153046153047153048153049153050153051153052153053153054153055153056153057153058153059153060153061153062153063153064153065153066153067153068153069153070153071153072153073153074153075153076153077153078153079153080153081153082153083153084153085153086153087153088153089153090153091153092153093153094153095153096153097153098153099153100153101153102153103153104153105153106153107153108153109153110153111153112153113153114153115153116153117153118153119153120153121153122153123153124153125153126153127153128153129153130153131153132153133153134153135153136153137153138153139153140153141153142153143153144153145153146153147153148153149153150153151153152153153153154153155153156153157153158153159153160153161153162153163153164153165153166153167153168153169153170153171153172153173153174153175153176153177153178153179153180153181153182153183153184153185153186153187153188153189153190153191153192153193153194153195153196153197153198153199153200153201153202153203153204153205153206153207153208153209153210153211153212153213153214153215153216153217153218153219153220153221153222153223153224153225153226153227153228153229153230153231153232153233153234153235153236153237153238153239153240153241153242153243153244153245153246153247153248153249153250153251153252153253153254153255153256153257153258153259153260153261153262153263153264153265153266153267153268153269153270153271153272153273153274153275153276153277153278153279153280153281153282153283153284153285153286153287153288153289153290153291153292153293153294153295153296153297153298153299153300153301153302153303153304153305153306153307153308153309153310153311153312153313153314153315153316153317153318153319153320153321153322153323153324153325153326153327153328153329153330153331153332153333153334153335153336153337153338153339153340153341153342153343153344153345153346153347153348153349153350153351153352153353153354153355153356153357153358153359153360153361153362153363153364153365153366153367153368153369153370153371153372153373153374153375153376153377153378153379153380153381153382153383153384153385153386153387153388153389153390153391153392153393153394153395153396153397153398153399153400153401153402153403153404153405153406153407153408153409153410153411153412153413153414153415153416153417153418153419153420153421153422153423153424153425153426153427153428153429153430153431153432153433153434153435153436153437153438153439153440153441153442153443153444153445153446153447153448153449153450153451153452153453153454153455153456153457153458153459153460153461153462153463153464153465153466153467153468153469153470153471153472153473153474153475153476153477153478153479153480153481153482153483153484153485153486153487153488153489153490153491153492153493153494153495153496153497153498153499153500153501153502153503153504153505153506153507153508153509153510153511153512153513153514153515153516153517153518153519153520153521153522153523153524153525153526153527153528153529153530153531153532153533153534153535153536153537153538153539153540153541153542153543153544153545153546153547153548153549153550153551153552153553153554153555153556153557153558153559153560153561153562153563153564153565153566153567153568153569153570153571153572153573153574153575153576153577153578153579153580153581153582153583153584153585153586153587153588153589153590153591153592153593153594153595153596153597153598153599153600153601153602153603153604153605153606153607153608153609153610153611153612153613153614153615153616153617153618153619153620153621153622153623153624153625153626153627153628153629153630153631153632153633153634153635153636153637153638153639153640153641153642153643153644153645153646153647153648153649153650153651153652153653153654153655153656153657153658153659153660153661153662153663153664153665153666153667153668153669153670153671153672153673153674153675153676153677153678153679153680153681153682153683153684153685153686153687153688153689153690153691153692153693153694153695153696153697153698153699153700153701153702153703153704153705153706153707153708153709153710153711153712153713153714153715153716153717153718153719153720153721153722153723153724153725153726153727153728153729153730153731153732153733153734153735153736153737153738153739153740153741153742153743153744153745153746153747153748153749153750153751153752153753153754153755153756153757153758153759153760153761153762153763153764153765153766153767153768153769153770153771153772153773153774153775153776153777153778153779153780153781153782153783153784153785153786153787153788153789153790153791153792153793153794153795153796153797153798153799153800153801153802153803153804153805153806153807153808153809153810153811153812153813153814153815153816153817153818153819153820153821153822153823153824153825153826153827153828153829153830153831153832153833153834153835153836153837153838153839153840153841153842153843153844153845153846153847153848153849153850153851153852153853153854153855153856153857153858153859153860153861153862153863153864153865153866153867153868153869153870153871153872153873153874153875153876153877153878153879153880153881153882153883153884153885153886153887153888153889153890153891153892153893153894153895153896153897153898153899153900153901153902153903153904153905153906153907153908153909153910153911153912153913153914153915153916153917153918153919153920153921153922153923153924153925153926153927153928153929153930153931153932153933153934153935153936153937153938153939153940153941153942153943153944153945153946153947153948153949153950153951153952153953153954153955153956153957153958153959153960153961153962153963153964153965153966153967153968153969153970153971153972153973153974153975153976153977153978153979153980153981153982153983153984153985153986153987153988153989153990153991153992153993153994153995153996153997153998153999154000154001154002154003154004154005154006154007154008154009154010154011154012154013154014154015154016154017154018154019154020154021154022154023154024154025154026154027154028154029154030154031154032154033154034154035154036154037154038154039154040154041154042154043154044154045154046154047154048154049154050154051154052154053154054154055154056154057154058154059154060154061154062154063154064154065154066154067154068154069154070154071154072154073154074154075154076154077154078154079154080154081154082154083154084154085154086154087154088154089154090154091154092154093154094154095154096154097154098154099154100154101154102154103154104154105154106154107154108154109154110154111154112154113154114154115154116154117154118154119154120154121154122154123154124154125154126154127154128154129154130154131154132154133154134154135154136154137154138154139154140154141154142154143154144154145154146154147154148154149154150154151154152154153154154154155154156154157154158154159154160154161154162154163154164154165154166154167154168154169154170154171154172154173154174154175154176154177154178154179154180154181154182154183154184154185154186154187154188154189154190154191154192154193154194154195154196154197154198154199154200154201154202154203154204154205154206154207154208154209154210154211154212154213154214154215154216154217154218154219154220154221154222154223154224154225154226154227154228154229154230154231154232154233154234154235154236154237154238154239154240154241154242154243154244154245154246154247154248154249154250154251154252154253154254154255154256154257154258154259154260154261154262154263154264154265154266154267154268154269154270154271154272154273154274154275154276154277154278154279154280154281154282154283154284154285154286154287154288154289154290154291154292154293154294154295154296154297154298154299154300154301154302154303154304154305154306154307154308154309154310154311154312154313154314154315154316154317154318154319154320154321154322154323154324154325154326154327154328154329154330154331154332154333154334154335154336154337154338154339154340154341154342154343154344154345154346154347154348154349154350154351154352154353154354154355154356154357154358154359154360154361154362154363154364154365154366154367154368154369154370154371154372154373154374154375154376154377154378154379154380154381154382154383154384154385154386154387154388154389154390154391154392154393154394154395154396154397154398154399154400154401154402154403154404154405154406154407154408154409154410154411154412154413154414154415154416154417154418154419154420154421154422154423154424154425154426154427154428154429154430154431154432154433154434154435154436154437154438154439154440154441154442154443154444154445154446154447154448154449154450154451154452154453154454154455154456154457154458154459154460154461154462154463154464154465154466154467154468154469154470154471154472154473154474154475154476154477154478154479154480154481154482154483154484154485154486154487154488154489154490154491154492154493154494154495154496154497154498154499154500154501154502154503154504154505154506154507154508154509154510154511154512154513154514154515154516154517154518154519154520154521154522154523154524154525154526154527154528154529154530154531154532154533154534154535154536154537154538154539154540154541154542154543154544154545154546154547154548154549154550154551154552154553154554154555154556154557154558154559154560154561154562154563154564154565154566154567154568154569154570154571154572154573154574154575154576154577154578154579154580154581154582154583154584154585154586154587154588154589154590154591154592154593154594154595154596154597154598154599154600154601154602154603154604154605154606154607154608154609154610154611154612154613154614154615154616154617154618154619154620154621154622154623154624154625154626154627154628154629154630154631154632154633154634154635154636154637154638154639154640154641154642154643154644154645154646154647154648154649154650154651154652154653154654154655154656154657154658154659154660154661154662154663154664154665154666154667154668154669154670154671154672154673154674154675154676154677154678154679154680154681154682154683154684154685154686154687154688154689154690154691154692154693154694154695154696154697154698154699154700154701154702154703154704154705154706154707154708154709154710154711154712154713154714154715154716154717154718154719154720154721154722154723154724154725154726154727154728154729154730154731154732154733154734154735154736154737154738154739154740154741154742154743154744154745154746154747154748154749154750154751154752154753154754154755154756154757154758154759154760154761154762154763154764154765154766154767154768154769154770154771154772154773154774154775154776154777154778154779154780154781154782154783154784154785154786154787154788154789154790154791154792154793154794154795154796154797154798154799154800154801154802154803154804154805154806154807154808154809154810154811154812154813154814154815154816154817154818154819154820154821154822154823154824154825154826154827154828154829154830154831154832154833154834154835154836154837154838154839154840154841154842154843154844154845154846154847154848154849154850154851154852154853154854154855154856154857154858154859154860154861154862154863154864154865154866154867154868154869154870154871154872154873154874154875154876154877154878154879154880154881154882154883154884154885154886154887154888154889154890154891154892154893154894154895154896154897154898154899154900154901154902154903154904154905154906154907154908154909154910154911154912154913154914154915154916154917154918154919154920154921154922154923154924154925154926154927154928154929154930154931154932154933154934154935154936154937154938154939154940154941154942154943154944154945154946154947154948154949154950154951154952154953154954154955154956154957154958154959154960154961154962154963154964154965154966154967154968154969154970154971154972154973154974154975154976154977154978154979154980154981154982154983154984154985154986154987154988154989154990154991154992154993154994154995154996154997154998154999155000155001155002155003155004155005155006155007155008155009155010155011155012155013155014155015155016155017155018155019155020155021155022155023155024155025155026155027155028155029155030155031155032155033155034155035155036155037155038155039155040155041155042155043155044155045155046155047155048155049155050155051155052155053155054155055155056155057155058155059155060155061155062155063155064155065155066155067155068155069155070155071155072155073155074155075155076155077155078155079155080155081155082155083155084155085155086155087155088155089155090155091155092155093155094155095155096155097155098155099155100155101155102155103155104155105155106155107155108155109155110155111155112155113155114155115155116155117155118155119155120155121155122155123155124155125155126155127155128155129155130155131155132155133155134155135155136155137155138155139155140155141155142155143155144155145155146155147155148155149155150155151155152155153155154155155155156155157155158155159155160155161155162155163155164155165155166155167155168155169155170155171155172155173155174155175155176155177155178155179155180155181155182155183155184155185155186155187155188155189155190155191155192155193155194155195155196155197155198155199155200155201155202155203155204155205155206155207155208155209155210155211155212155213155214155215155216155217155218155219155220155221155222155223155224155225155226155227155228155229155230155231155232155233155234155235155236155237155238155239155240155241155242155243155244155245155246155247155248155249155250155251155252155253155254155255155256155257155258155259155260155261155262155263155264155265155266155267155268155269155270155271155272155273155274155275155276155277155278155279155280155281155282155283155284155285155286155287155288155289155290155291155292155293155294155295155296155297155298155299155300155301155302155303155304155305155306155307155308155309155310155311155312155313155314155315155316155317155318155319155320155321155322155323155324155325155326155327155328155329155330155331155332155333155334155335155336155337155338155339155340155341155342155343155344155345155346155347155348155349155350155351155352155353155354155355155356155357155358155359155360155361155362155363155364155365155366155367155368155369155370155371155372155373155374155375155376155377155378155379155380155381155382155383155384155385155386155387155388155389155390155391155392155393155394155395155396155397155398155399155400155401155402155403155404155405155406155407155408155409155410155411155412155413155414155415155416155417155418155419155420155421155422155423155424155425155426155427155428155429155430155431155432155433155434155435155436155437155438155439155440155441155442155443155444155445155446155447155448155449155450155451155452155453155454155455155456155457155458155459155460155461155462155463155464155465155466155467155468155469155470155471155472155473155474155475155476155477155478155479155480155481155482155483155484155485155486155487155488155489155490155491155492155493155494155495155496155497155498155499155500155501155502155503155504155505155506155507155508155509155510155511155512155513155514155515155516155517155518155519155520155521155522155523155524155525155526155527155528155529155530155531155532155533155534155535155536155537155538155539155540155541155542155543155544155545155546155547155548155549155550155551155552155553155554155555155556155557155558155559155560155561155562155563155564155565155566155567155568155569155570155571155572155573155574155575155576155577155578155579155580155581155582155583155584155585155586155587155588155589155590155591155592155593155594155595155596155597155598155599155600155601155602155603155604155605155606155607155608155609155610155611155612155613155614155615155616155617155618155619155620155621155622155623155624155625155626155627155628155629155630155631155632155633155634155635155636155637155638155639155640155641155642155643155644155645155646155647155648155649155650155651155652155653155654155655155656155657155658155659155660155661155662155663155664155665155666155667155668155669155670155671155672155673155674155675155676155677155678155679155680155681155682155683155684155685155686155687155688155689155690155691155692155693155694155695155696155697155698155699155700155701155702155703155704155705155706155707155708155709155710155711155712155713155714155715155716155717155718155719155720155721155722155723155724155725155726155727155728155729155730155731155732155733155734155735155736155737155738155739155740155741155742155743155744155745155746155747155748155749155750155751155752155753155754155755155756155757155758155759155760155761155762155763155764155765155766155767155768155769155770155771155772155773155774155775155776155777155778155779155780155781155782155783155784155785155786155787155788155789155790155791155792155793155794155795155796155797155798155799155800155801155802155803155804155805155806155807155808155809155810155811155812155813155814155815155816155817155818155819155820155821155822155823155824155825155826155827155828155829155830155831155832155833155834155835155836155837155838155839155840155841155842155843155844155845155846155847155848155849155850155851155852155853155854155855155856155857155858155859155860155861155862155863155864155865155866155867155868155869155870155871155872155873155874155875155876155877155878155879155880155881155882155883155884155885155886155887155888155889155890155891155892155893155894155895155896155897155898155899155900155901155902155903155904155905155906155907155908155909155910155911155912155913155914155915155916155917155918155919155920155921155922155923155924155925155926155927155928155929155930155931155932155933155934155935155936155937155938155939155940155941155942155943155944155945155946155947155948155949155950155951155952155953155954155955155956155957155958155959155960155961155962155963155964155965155966155967155968155969155970155971155972155973155974155975155976155977155978155979155980155981155982155983155984155985155986155987155988155989155990155991155992155993155994155995155996155997155998155999156000156001156002156003156004156005156006156007156008156009156010156011156012156013156014156015156016156017156018156019156020156021156022156023156024156025156026156027156028156029156030156031156032156033156034156035156036156037156038156039156040156041156042156043156044156045156046156047156048156049156050156051156052156053156054156055156056156057156058156059156060156061156062156063156064156065156066156067156068156069156070156071156072156073156074156075156076156077156078156079156080156081156082156083156084156085156086156087156088156089156090156091156092156093156094156095156096156097156098156099156100156101156102156103156104156105156106156107156108156109156110156111156112156113156114156115156116156117156118156119156120156121156122156123156124156125156126156127156128156129156130156131156132156133156134156135156136156137156138156139156140156141156142156143156144156145156146156147156148156149156150156151156152156153156154156155156156156157156158156159156160156161156162156163156164156165156166156167156168156169156170156171156172156173156174156175156176156177156178156179156180156181156182156183156184156185156186156187156188156189156190156191156192156193156194156195156196156197156198156199156200156201156202156203156204156205156206156207156208156209156210156211156212156213156214156215156216156217156218156219156220156221156222156223156224156225156226156227156228156229156230156231156232156233156234156235156236156237156238156239156240156241156242156243156244156245156246156247156248156249156250156251156252156253156254156255156256156257156258156259156260156261156262156263156264156265156266156267156268156269156270156271156272156273156274156275156276156277156278156279156280156281156282156283156284156285156286156287156288156289156290156291156292156293156294156295156296156297156298156299156300156301156302156303156304156305156306156307156308156309156310156311156312156313156314156315156316156317156318156319156320156321156322156323156324156325156326156327156328156329156330156331156332156333156334156335156336156337156338156339156340156341156342156343156344156345156346156347156348156349156350156351156352156353156354156355156356156357156358156359156360156361156362156363156364156365156366156367156368156369156370156371156372156373156374156375156376156377156378156379156380156381156382156383156384156385156386156387156388156389156390156391156392156393156394156395156396156397156398156399156400156401156402156403156404156405156406156407156408156409156410156411156412156413156414156415156416156417156418156419156420156421156422156423156424156425156426156427156428156429156430156431156432156433156434156435156436156437156438156439156440156441156442156443156444156445156446156447156448156449156450156451156452156453156454156455156456156457156458156459156460156461156462156463156464156465156466156467156468156469156470156471156472156473156474156475156476156477156478156479156480156481156482156483156484156485156486156487156488156489156490156491156492156493156494156495156496156497156498156499156500156501156502156503156504156505156506156507156508156509156510156511156512156513156514156515156516156517156518156519156520156521156522156523156524156525156526156527156528156529156530156531156532156533156534156535156536156537156538156539156540156541156542156543156544156545156546156547156548156549156550156551156552156553156554156555156556156557156558156559156560156561156562156563156564156565156566156567156568156569156570156571156572156573156574156575156576156577156578156579156580156581156582156583156584156585156586156587156588156589156590156591156592156593156594156595156596156597156598156599156600156601156602156603156604156605156606156607156608156609156610156611156612156613156614156615156616156617156618156619156620156621156622156623156624156625156626156627156628156629156630156631156632156633156634156635156636156637156638156639156640156641156642156643156644156645156646156647156648156649156650156651156652156653156654156655156656156657156658156659156660156661156662156663156664156665156666156667156668156669156670156671156672156673156674156675156676156677156678156679156680156681156682156683156684156685156686156687156688156689156690156691156692156693156694156695156696156697156698156699156700156701156702156703156704156705156706156707156708156709156710156711156712156713156714156715156716156717156718156719156720156721156722156723156724156725156726156727156728156729156730156731156732156733156734156735156736156737156738156739156740156741156742156743156744156745156746156747156748156749156750156751156752156753156754156755156756156757156758156759156760156761156762156763156764156765156766156767156768156769156770156771156772156773156774156775156776156777156778156779156780156781156782156783156784156785156786156787156788156789156790156791156792156793156794156795156796156797156798156799156800156801156802156803156804156805156806156807156808156809156810156811156812156813156814156815156816156817156818156819156820156821156822156823156824156825156826156827156828156829156830156831156832156833156834156835156836156837156838156839156840156841156842156843156844156845156846156847156848156849156850156851156852156853156854156855156856156857156858156859156860156861156862156863156864156865156866156867156868156869156870156871156872156873156874156875156876156877156878156879156880156881156882156883156884156885156886156887156888156889156890156891156892156893156894156895156896156897156898156899156900156901156902156903156904156905156906156907156908156909156910156911156912156913156914156915156916156917156918156919156920156921156922156923156924156925156926156927156928156929156930156931156932156933156934156935156936156937156938156939156940156941156942156943156944156945156946156947156948156949156950156951156952156953156954156955156956156957156958156959156960156961156962156963156964156965156966156967156968156969156970156971156972156973156974156975156976156977156978156979156980156981156982156983156984156985156986156987156988156989156990156991156992156993156994156995156996156997156998156999157000157001157002157003157004157005157006157007157008157009157010157011157012157013157014157015157016157017157018157019157020157021157022157023157024157025157026157027157028157029157030157031157032157033157034157035157036157037157038157039157040157041157042157043157044157045157046157047157048157049157050157051157052157053157054157055157056157057157058157059157060157061157062157063157064157065157066157067157068157069157070157071157072157073157074157075157076157077157078157079157080157081157082157083157084157085157086157087157088157089157090157091157092157093157094157095157096157097157098157099157100157101157102157103157104157105157106157107157108157109157110157111157112157113157114157115157116157117157118157119157120157121157122157123157124157125157126157127157128157129157130157131157132157133157134157135157136157137157138157139157140157141157142157143157144157145157146157147157148157149157150157151157152157153157154157155157156157157157158157159157160157161157162157163157164157165157166157167157168157169157170157171157172157173157174157175157176157177157178157179157180157181157182157183157184157185157186157187157188157189157190157191157192157193157194157195157196157197157198157199157200157201157202157203157204157205157206157207157208157209157210157211157212157213157214157215157216157217157218157219157220157221157222157223157224157225157226157227157228157229157230157231157232157233157234157235157236157237157238157239157240157241157242157243157244157245157246157247157248157249157250157251157252157253157254157255157256157257157258157259157260157261157262157263157264157265157266157267157268157269157270157271157272157273157274157275157276157277157278157279157280157281157282157283157284157285157286157287157288157289157290157291157292157293157294157295157296157297157298157299157300157301157302157303157304157305157306157307157308157309157310157311157312157313157314157315157316157317157318157319157320157321157322157323157324157325157326157327157328157329157330157331157332157333157334157335157336157337157338157339157340157341157342157343157344157345157346157347157348157349157350157351157352157353157354157355157356157357157358157359157360157361157362157363157364157365157366157367157368157369157370157371157372157373157374157375157376157377157378157379157380157381157382157383157384157385157386157387157388157389157390157391157392157393157394157395157396157397157398157399157400157401157402157403157404157405157406157407157408157409157410157411157412157413157414157415157416157417157418157419157420157421157422157423157424157425157426157427157428157429157430157431157432157433157434157435157436157437157438157439157440157441157442157443157444157445157446157447157448157449157450157451157452157453157454157455157456157457157458157459157460157461157462157463157464157465157466157467157468157469157470157471157472157473157474157475157476157477157478157479157480157481157482157483157484157485157486157487157488157489157490157491157492157493157494157495157496157497157498157499157500157501157502157503157504157505157506157507157508157509157510157511157512157513157514157515157516157517157518157519157520157521157522157523157524157525157526157527157528157529157530157531157532157533157534157535157536157537157538157539157540157541157542157543157544157545157546157547157548157549157550157551157552157553157554157555157556157557157558157559157560157561157562157563157564157565157566157567157568157569157570157571157572157573157574157575157576157577157578157579157580157581157582157583157584157585157586157587157588157589157590157591157592157593157594157595157596157597157598157599157600157601157602157603157604157605157606157607157608157609157610157611157612157613157614157615157616157617157618157619157620157621157622157623157624157625157626157627157628157629157630157631157632157633157634157635157636157637157638157639157640157641157642157643157644157645157646157647157648157649157650157651157652157653157654157655157656157657157658157659157660157661157662157663157664157665157666157667157668157669157670157671157672157673157674157675157676157677157678157679157680157681157682157683157684157685157686157687157688157689157690157691157692157693157694157695157696157697157698157699157700157701157702157703157704157705157706157707157708157709157710157711157712157713157714157715157716157717157718157719157720157721157722157723157724157725157726157727157728157729157730157731157732157733157734157735157736157737157738157739157740157741157742157743157744157745157746157747157748157749157750157751157752157753157754157755157756157757157758157759157760157761157762157763157764157765157766157767157768157769157770157771157772157773157774157775157776157777157778157779157780157781157782157783157784157785157786157787157788157789157790157791157792157793157794157795157796157797157798157799157800157801157802157803157804157805157806157807157808157809157810157811157812157813157814157815157816157817157818157819157820157821157822157823157824157825157826157827157828157829157830157831157832157833157834157835157836157837157838157839157840157841157842157843157844157845157846157847157848157849157850157851157852157853157854157855157856157857157858157859157860157861157862157863157864157865157866157867157868157869157870157871157872157873157874157875157876157877157878157879157880157881157882157883157884157885157886157887157888157889157890157891157892157893157894157895157896157897157898157899157900157901157902157903157904157905157906157907157908157909157910157911157912157913157914157915157916157917157918157919157920157921157922157923157924157925157926157927157928157929157930157931157932157933157934157935157936157937157938157939157940157941157942157943157944157945157946157947157948157949157950157951157952157953157954157955157956157957157958157959157960157961157962157963157964157965157966157967157968157969157970157971157972157973157974157975157976157977157978157979157980157981157982157983157984157985157986157987157988157989157990157991157992157993157994157995157996157997157998157999158000158001158002158003158004158005158006158007158008158009158010158011158012158013158014158015158016158017158018158019158020158021158022158023158024158025158026158027158028158029158030158031158032158033158034158035158036158037158038158039158040158041158042158043158044158045158046158047158048158049158050158051158052158053158054158055158056158057158058158059158060158061158062158063158064158065158066158067158068158069158070158071158072158073158074158075158076158077158078158079158080158081158082158083158084158085158086158087158088158089158090158091158092158093158094158095158096158097158098158099158100158101158102158103158104158105158106158107158108158109158110158111158112158113158114158115158116158117158118158119158120158121158122158123158124158125158126158127158128158129158130158131158132158133158134158135158136158137158138158139158140158141158142158143158144158145158146158147158148158149158150158151158152158153158154158155158156158157158158158159158160158161158162158163158164158165158166158167158168158169158170158171158172158173158174158175158176158177158178158179158180158181158182158183158184158185158186158187158188158189158190158191158192158193158194158195158196158197158198158199158200158201158202158203158204158205158206158207158208158209158210158211158212158213158214158215158216158217158218158219158220158221158222158223158224158225158226158227158228158229158230158231158232158233158234158235158236158237158238158239158240158241158242158243158244158245158246158247158248158249158250158251158252158253158254158255158256158257158258158259158260158261158262158263158264158265158266158267158268158269158270158271158272158273158274158275158276158277158278158279158280158281158282158283158284158285158286158287158288158289158290158291158292158293158294158295158296158297158298158299158300158301158302158303158304158305158306158307158308158309158310158311158312158313158314158315158316158317158318158319158320158321158322158323158324158325158326158327158328158329158330158331158332158333158334158335158336158337158338158339158340158341158342158343158344158345158346158347158348158349158350158351158352158353158354158355158356158357158358158359158360158361158362158363158364158365158366158367158368158369158370158371158372158373158374158375158376158377158378158379158380158381158382158383158384158385158386158387158388158389158390158391158392158393158394158395158396158397158398158399158400158401158402158403158404158405158406158407158408158409158410158411158412158413158414158415158416158417158418158419158420158421158422158423158424158425158426158427158428158429158430158431158432158433158434158435158436158437158438158439158440158441158442158443158444158445158446158447158448158449158450158451158452158453158454158455158456158457158458158459158460158461158462158463158464158465158466158467158468158469158470158471158472158473158474158475158476158477158478158479158480158481158482158483158484158485158486158487158488158489158490158491158492158493158494158495158496158497158498158499158500158501158502158503158504158505158506158507158508158509158510158511158512158513158514158515158516158517158518158519158520158521158522158523158524158525158526158527158528158529158530158531158532158533158534158535158536158537158538158539158540158541158542158543158544158545158546158547158548158549158550158551158552158553158554158555158556158557158558158559158560158561158562158563158564158565158566158567158568158569158570158571158572158573158574158575158576158577158578158579158580158581158582158583158584158585158586158587158588158589158590158591158592158593158594158595158596158597158598158599158600158601158602158603158604158605158606158607158608158609158610158611158612158613158614158615158616158617158618158619158620158621158622158623158624158625158626158627158628158629158630158631158632158633158634158635158636158637158638158639158640158641158642158643158644158645158646158647158648158649158650158651158652158653158654158655158656158657158658158659158660158661158662158663158664158665158666158667158668158669158670158671158672158673158674158675158676158677158678158679158680158681158682158683158684158685158686158687158688158689158690158691158692158693158694158695158696158697158698158699158700158701158702158703158704158705158706158707158708158709158710158711158712158713158714158715158716158717158718158719158720158721158722158723158724158725158726158727158728158729158730158731158732158733158734158735158736158737158738158739158740158741158742158743158744158745158746158747158748158749158750158751158752158753158754158755158756158757158758158759158760158761158762158763158764158765158766158767158768158769158770158771158772158773158774158775158776158777158778158779158780158781158782158783158784158785158786158787158788158789158790158791158792158793158794158795158796158797158798158799158800158801158802158803158804158805158806158807158808158809158810158811158812158813158814158815158816158817158818158819158820158821158822158823158824158825158826158827158828158829158830158831158832158833158834158835158836158837158838158839158840158841158842158843158844158845158846158847158848158849158850158851158852158853158854158855158856158857158858158859158860158861158862158863158864158865158866158867158868158869158870158871158872158873158874158875158876158877158878158879158880158881158882158883158884158885158886158887158888158889158890158891158892158893158894158895158896158897158898158899158900158901158902158903158904158905158906158907158908158909158910158911158912158913158914158915158916158917158918158919158920158921158922158923158924158925158926158927158928158929158930158931158932158933158934158935158936158937158938158939158940158941158942158943158944158945158946158947158948158949158950158951158952158953158954158955158956158957158958158959158960158961158962158963158964158965158966158967158968158969158970158971158972158973158974158975158976158977158978158979158980158981158982158983158984158985158986158987158988158989158990158991158992158993158994158995158996158997158998158999159000159001159002159003159004159005159006159007159008159009159010159011159012159013159014159015159016159017159018159019159020159021159022159023159024159025159026159027159028159029159030159031159032159033159034159035159036159037159038159039159040159041159042159043159044159045159046159047159048159049159050159051159052159053159054159055159056159057159058159059159060159061159062159063159064159065159066159067159068159069159070159071159072159073159074159075159076159077159078159079159080159081159082159083159084159085159086159087159088159089159090159091159092159093159094159095159096159097159098159099159100159101159102159103159104159105159106159107159108159109159110159111159112159113159114159115159116159117159118159119159120159121159122159123159124159125159126159127159128159129159130159131159132159133159134159135159136159137159138159139159140159141159142159143159144159145159146159147159148159149159150159151159152159153159154159155159156159157159158159159159160159161159162159163159164159165159166159167159168159169159170159171159172159173159174159175159176159177159178159179159180159181159182159183159184159185159186159187159188159189159190159191159192159193159194159195159196159197159198159199159200159201159202159203159204159205159206159207159208159209159210159211159212159213159214159215159216159217159218159219159220159221159222159223159224159225159226159227159228159229159230159231159232159233159234159235159236159237159238159239159240159241159242159243159244159245159246159247159248159249159250159251159252159253159254159255159256159257159258159259159260159261159262159263159264159265159266159267159268159269159270159271159272159273159274159275159276159277159278159279159280159281159282159283159284159285159286159287159288159289159290159291159292159293159294159295159296159297159298159299159300159301159302159303159304159305159306159307159308159309159310159311159312159313159314159315159316159317159318159319159320159321159322159323159324159325159326159327159328159329159330159331159332159333159334159335159336159337159338159339159340159341159342159343159344159345159346159347159348159349159350159351159352159353159354159355159356159357159358159359159360159361159362159363159364159365159366159367159368159369159370159371159372159373159374159375159376159377159378159379159380159381159382159383159384159385159386159387159388159389159390159391159392159393159394159395159396159397159398159399159400159401159402159403159404159405159406159407159408159409159410159411159412159413159414159415159416159417159418159419159420159421159422159423159424159425159426159427159428159429159430159431159432159433159434159435159436159437159438159439159440159441159442159443159444159445159446159447159448159449159450159451159452159453159454159455159456159457159458159459159460159461159462159463159464159465159466159467159468159469159470159471159472159473159474159475159476159477159478159479159480159481159482159483159484159485159486159487159488159489159490159491159492159493159494159495159496159497159498159499159500159501159502159503159504159505159506159507159508159509159510159511159512159513159514159515159516159517159518159519159520159521159522159523159524159525159526159527159528159529159530159531159532159533159534159535159536159537159538159539159540159541159542159543159544159545159546159547159548159549159550159551159552159553159554159555159556159557159558159559159560159561159562159563159564159565159566159567159568159569159570159571159572159573159574159575159576159577159578159579159580159581159582159583159584159585159586159587159588159589159590159591159592159593159594159595159596159597159598159599159600159601159602159603159604159605159606159607159608159609159610159611159612159613159614159615159616159617159618159619159620159621159622159623159624159625159626159627159628159629159630159631159632159633159634159635159636159637159638159639159640159641159642159643159644159645159646159647159648159649159650159651159652159653159654159655159656159657159658159659159660159661159662159663159664159665159666159667159668159669159670159671159672159673159674159675159676159677159678159679159680159681159682159683159684159685159686159687159688159689159690159691159692159693159694159695159696159697159698159699159700159701159702159703159704159705159706159707159708159709159710159711159712159713159714159715159716159717159718159719159720159721159722159723159724159725159726159727159728159729159730159731159732159733159734159735159736159737159738159739159740159741159742159743159744159745159746159747159748159749159750159751159752159753159754159755159756159757159758159759159760159761159762159763159764159765159766159767159768159769159770159771159772159773159774159775159776159777159778159779159780159781159782159783159784159785159786159787159788159789159790159791159792159793159794159795159796159797159798159799159800159801159802159803159804159805159806159807159808159809159810159811159812159813159814159815159816159817159818159819159820159821159822159823159824159825159826159827159828159829159830159831159832159833159834159835159836159837159838159839159840159841159842159843159844159845159846159847159848159849159850159851159852159853159854159855159856159857159858159859159860159861159862159863159864159865159866159867159868159869159870159871159872159873159874159875159876159877159878159879159880159881159882159883159884159885159886159887159888159889159890159891159892159893159894159895159896159897159898159899159900159901159902159903159904159905159906159907159908159909159910159911159912159913159914159915159916159917159918159919159920159921159922159923159924159925159926159927159928159929159930159931159932159933159934159935159936159937159938159939159940159941159942159943159944159945159946159947159948159949159950159951159952159953159954159955159956159957159958159959159960159961159962159963159964159965159966159967159968159969159970159971159972159973159974159975159976159977159978159979159980159981159982159983159984159985159986159987159988159989159990159991159992159993159994159995159996159997159998159999160000160001160002160003160004160005160006160007160008160009160010160011160012160013160014160015160016160017160018160019160020160021160022160023160024160025160026160027160028160029160030160031160032160033160034160035160036160037160038160039160040160041160042160043160044160045160046160047160048160049160050160051160052160053160054160055160056160057160058160059160060160061160062160063160064160065160066160067160068160069160070160071160072160073160074160075160076160077160078160079160080160081160082160083160084160085160086160087160088160089160090160091160092160093160094160095160096160097160098160099160100160101160102160103160104160105160106160107160108160109160110160111160112160113160114160115160116160117160118160119160120160121160122160123160124160125160126160127160128160129160130160131160132160133160134160135160136160137160138160139160140160141160142160143160144160145160146160147160148160149160150160151160152160153160154160155160156160157160158160159160160160161160162160163160164160165160166160167160168160169160170160171160172160173160174160175160176160177160178160179160180160181160182160183160184160185160186160187160188160189160190160191160192160193160194160195160196160197160198160199160200160201160202160203160204160205160206160207160208160209160210160211160212160213160214160215160216160217160218160219160220160221160222160223160224160225160226160227160228160229160230160231160232160233160234160235160236160237160238160239160240160241160242160243160244160245160246160247160248160249160250160251160252160253160254160255160256160257160258160259160260160261160262160263160264160265160266160267160268160269160270160271160272160273160274160275160276160277160278160279160280160281160282160283160284160285160286160287160288160289160290160291160292160293160294160295160296160297160298160299160300160301160302160303160304160305160306160307160308160309160310160311160312160313160314160315160316160317160318160319160320160321160322160323160324160325160326160327160328160329160330160331160332160333160334160335160336160337160338160339160340160341160342160343160344160345160346160347160348160349160350160351160352160353160354160355160356160357160358160359160360160361160362160363160364160365160366160367160368160369160370160371160372160373160374160375160376160377160378160379160380160381160382160383160384160385160386160387160388160389160390160391160392160393160394160395160396160397160398160399160400160401160402160403160404160405160406160407160408160409160410160411160412160413160414160415160416160417160418160419160420160421160422160423160424160425160426160427160428160429160430160431160432160433160434160435160436160437160438160439160440160441160442160443160444160445160446160447160448160449160450160451160452160453160454160455160456160457160458160459160460160461160462160463160464160465160466160467160468160469160470160471160472160473160474160475160476160477160478160479160480160481160482160483160484160485160486160487160488160489160490160491160492160493160494160495160496160497160498160499160500160501160502160503160504160505160506160507160508160509160510160511160512160513160514160515160516160517160518160519160520160521160522160523160524160525160526160527160528160529160530160531160532160533160534160535160536160537160538160539160540160541160542160543160544160545160546160547160548160549160550160551160552160553160554160555160556160557160558160559160560160561160562160563160564160565160566160567160568160569160570160571160572160573160574160575160576160577160578160579160580160581160582160583160584160585160586160587160588160589160590160591160592160593160594160595160596160597160598160599160600160601160602160603160604160605160606160607160608160609160610160611160612160613160614160615160616160617160618160619160620160621160622160623160624160625160626160627160628160629160630160631160632160633160634160635160636160637160638160639160640160641160642160643160644160645160646160647160648160649160650160651160652160653160654160655160656160657160658160659160660160661160662160663160664160665160666160667160668160669160670160671160672160673160674160675160676160677160678160679160680160681160682160683160684160685160686160687160688160689160690160691160692160693160694160695160696160697160698160699160700160701160702160703160704160705160706160707160708160709160710160711160712160713160714160715160716160717160718160719160720160721160722160723160724160725160726160727160728160729160730160731160732160733160734160735160736160737160738160739160740160741160742160743160744160745160746160747160748160749160750160751160752160753160754160755160756160757160758160759160760160761160762160763160764160765160766160767160768160769160770160771160772160773160774160775160776160777160778160779160780160781160782160783160784160785160786160787160788160789160790160791160792160793160794160795160796160797160798160799160800160801160802160803160804160805160806160807160808160809160810160811160812160813160814160815160816160817160818160819160820160821160822160823160824160825160826160827160828160829160830160831160832160833160834160835160836160837160838160839160840160841160842160843160844160845160846160847160848160849160850160851160852160853160854160855160856160857160858160859160860160861160862160863160864160865160866160867160868160869160870160871160872160873160874160875160876160877160878160879160880160881160882160883160884160885160886160887160888160889160890160891160892160893160894160895160896160897160898160899160900160901160902160903160904160905160906160907160908160909160910160911160912160913160914160915160916160917160918160919160920160921160922160923160924160925160926160927160928160929160930160931160932160933160934160935160936160937160938160939160940160941160942160943160944160945160946160947160948160949160950160951160952160953160954160955160956160957160958160959160960160961160962160963160964160965160966160967160968160969160970160971160972160973160974160975160976160977160978160979160980160981160982160983160984160985160986160987160988160989160990160991160992160993160994160995160996160997160998160999161000161001161002161003161004161005161006161007161008161009161010161011161012161013161014161015161016161017161018161019161020161021161022161023161024161025161026161027161028161029161030161031161032161033161034161035161036161037161038161039161040161041161042161043161044161045161046161047161048161049161050161051161052161053161054161055161056161057161058161059161060161061161062161063161064161065161066161067161068161069161070161071161072161073161074161075161076161077161078161079161080161081161082161083161084161085161086161087161088161089161090161091161092161093161094161095161096161097161098161099161100161101161102161103161104161105161106161107161108161109161110161111161112161113161114161115161116161117161118161119161120161121161122161123161124161125161126161127161128161129161130161131161132161133161134161135161136161137161138161139161140161141161142161143161144161145161146161147161148161149161150161151161152161153161154161155161156161157161158161159161160161161161162161163161164161165161166161167161168161169161170161171161172161173161174161175161176161177161178161179161180161181161182161183161184161185161186161187161188161189161190161191161192161193161194161195161196161197161198161199161200161201161202161203161204161205161206161207161208161209161210161211161212161213161214161215161216161217161218161219161220161221161222161223161224161225161226161227161228161229161230161231161232161233161234161235161236161237161238161239161240161241161242161243161244161245161246161247161248161249161250161251161252161253161254161255161256161257161258161259161260161261161262161263161264161265161266161267161268161269161270161271161272161273161274161275161276161277161278161279161280161281161282161283161284161285161286161287161288161289161290161291161292161293161294161295161296161297161298161299161300161301161302161303161304161305161306161307161308161309161310161311161312161313161314161315161316161317161318161319161320161321161322161323161324161325161326161327161328161329161330161331161332161333161334161335161336161337161338161339161340161341161342161343161344161345161346161347161348161349161350161351161352161353161354161355161356161357161358161359161360161361161362161363161364161365161366161367161368161369161370161371161372161373161374161375161376161377161378161379161380161381161382161383161384161385161386161387161388161389161390161391161392161393161394161395161396161397161398161399161400161401161402161403161404161405161406161407161408161409161410161411161412161413161414161415161416161417161418161419161420161421161422161423161424161425161426161427161428161429161430161431161432161433161434161435161436161437161438161439161440161441161442161443161444161445161446161447161448161449161450161451161452161453161454161455161456161457161458161459161460161461161462161463161464161465161466161467161468161469161470161471161472161473161474161475161476161477161478161479161480161481161482161483161484161485161486161487161488161489161490161491161492161493161494161495161496161497161498161499161500161501161502161503161504161505161506161507161508161509161510161511161512161513161514161515161516161517161518161519161520161521161522161523161524161525161526161527161528161529161530161531161532161533161534161535161536161537161538161539161540161541161542161543161544161545161546161547161548161549161550161551161552161553161554161555161556161557161558161559161560161561161562161563161564161565161566161567161568161569161570161571161572161573161574161575161576161577161578161579161580161581161582161583161584161585161586161587161588161589161590161591161592161593161594161595161596161597161598161599161600161601161602161603161604161605161606161607161608161609161610161611161612161613161614161615161616161617161618161619161620161621161622161623161624161625161626161627161628161629161630161631161632161633161634161635161636161637161638161639161640161641161642161643161644161645161646161647161648161649161650161651161652161653161654161655161656161657161658161659161660161661161662161663161664161665161666161667161668161669161670161671161672161673161674161675161676161677161678161679161680161681161682161683161684161685161686161687161688161689161690161691161692161693161694161695161696161697161698161699161700161701161702161703161704161705161706161707161708161709161710161711161712161713161714161715161716161717161718161719161720161721161722161723161724161725161726161727161728161729161730161731161732161733161734161735161736161737161738161739161740161741161742161743161744161745161746161747161748161749161750161751161752161753161754161755161756161757161758161759161760161761161762161763161764161765161766161767161768161769161770161771161772161773161774161775161776161777161778161779161780161781161782161783161784161785161786161787161788161789161790161791161792161793161794161795161796161797161798161799161800161801161802161803161804161805161806161807161808161809161810161811161812161813161814161815161816161817161818161819161820161821161822161823161824161825161826161827161828161829161830161831161832161833161834161835161836161837161838161839161840161841161842161843161844161845161846161847161848161849161850161851161852161853161854161855161856161857161858161859161860161861161862161863161864161865161866161867161868161869161870161871161872161873161874161875161876161877161878161879161880161881161882161883161884161885161886161887161888161889161890161891161892161893161894161895161896161897161898161899161900161901161902161903161904161905161906161907161908161909161910161911161912161913161914161915161916161917161918161919161920161921161922161923161924161925161926161927161928161929161930161931161932161933161934161935161936161937161938161939161940161941161942161943161944161945161946161947161948161949161950161951161952161953161954161955161956161957161958161959161960161961161962161963161964161965161966161967161968161969161970161971161972161973161974161975161976161977161978161979161980161981161982161983161984161985161986161987161988161989161990161991161992161993161994161995161996161997161998161999162000162001162002162003162004162005162006162007162008162009162010162011162012162013162014162015162016162017162018162019162020162021162022162023162024162025162026162027162028162029162030162031162032162033162034162035162036162037162038162039162040162041162042162043162044162045162046162047162048162049162050162051162052162053162054162055162056162057162058162059162060162061162062162063162064162065162066162067162068162069162070162071162072162073162074162075162076162077162078162079162080162081162082162083162084162085162086162087162088162089162090162091162092162093162094162095162096162097162098162099162100162101162102162103162104162105162106162107162108162109162110162111162112162113162114162115162116162117162118162119162120162121162122162123162124162125162126162127162128162129162130162131162132162133162134162135162136162137162138162139162140162141162142162143162144162145162146162147162148162149162150162151162152162153162154162155162156162157162158162159162160162161162162162163162164162165162166162167162168162169162170162171162172162173162174162175162176162177162178162179162180162181162182162183162184162185162186162187162188162189162190162191162192162193162194162195162196162197162198162199162200162201162202162203162204162205162206162207162208162209162210162211162212162213162214162215162216162217162218162219162220162221162222162223162224162225162226162227162228162229162230162231162232162233162234162235162236162237162238162239162240162241162242162243162244162245162246162247162248162249162250162251162252162253162254162255162256162257162258162259162260162261162262162263162264162265162266162267162268162269162270162271162272162273162274162275162276162277162278162279162280162281162282162283162284162285162286162287162288162289162290162291162292162293162294162295162296162297162298162299162300162301162302162303162304162305162306162307162308162309162310162311162312162313162314162315162316162317162318162319162320162321162322162323162324162325162326162327162328162329162330162331162332162333162334162335162336162337162338162339162340162341162342162343162344162345162346162347162348162349162350162351162352162353162354162355162356162357162358162359162360162361162362162363162364162365162366162367162368162369162370162371162372162373162374162375162376162377162378162379162380162381162382162383162384162385162386162387162388162389162390162391162392162393162394162395162396162397162398162399162400162401162402162403162404162405162406162407162408162409162410162411162412162413162414162415162416162417162418162419162420162421162422162423162424162425162426162427162428162429162430162431162432162433162434162435162436162437162438162439162440162441162442162443162444162445162446162447162448162449162450162451162452162453162454162455162456162457162458162459162460162461162462162463162464162465162466162467162468162469162470162471162472162473162474162475162476162477162478162479162480162481162482162483162484162485162486162487162488162489162490162491162492162493162494162495162496162497162498162499162500162501162502162503162504162505162506162507162508162509162510162511162512162513162514162515162516162517162518162519162520162521162522162523162524162525162526162527162528162529162530162531162532162533162534162535162536162537162538162539162540162541162542162543162544162545162546162547162548162549162550162551162552162553162554162555162556162557162558162559162560162561162562162563162564162565162566162567162568162569162570162571162572162573162574162575162576162577162578162579162580162581162582162583162584162585162586162587162588162589162590162591162592162593162594162595162596162597162598162599162600162601162602162603162604162605162606162607162608162609162610162611162612162613162614162615162616162617162618162619162620162621162622162623162624162625162626162627162628162629162630162631162632162633162634162635162636162637162638162639162640162641162642162643162644162645162646162647162648162649162650162651162652162653162654162655162656162657162658162659162660162661162662162663162664162665162666162667162668162669162670162671162672162673162674162675162676162677162678162679162680162681162682162683162684162685162686162687162688162689162690162691162692162693162694162695162696162697162698162699162700162701162702162703162704162705162706162707162708162709162710162711162712162713162714162715162716162717162718162719162720162721162722162723162724162725162726162727162728162729162730162731162732162733162734162735162736162737162738162739162740162741162742162743162744162745162746162747162748162749162750162751162752162753162754162755162756162757162758162759162760162761162762162763162764162765162766162767162768162769162770162771162772162773162774162775162776162777162778162779162780162781162782162783162784162785162786162787162788162789162790162791162792162793162794162795162796162797162798162799162800162801162802162803162804162805162806162807162808162809162810162811162812162813162814162815162816162817162818162819162820162821162822162823162824162825162826162827162828162829162830162831162832162833162834162835162836162837162838162839162840162841162842162843162844162845162846162847162848162849162850162851162852162853162854162855162856162857162858162859162860162861162862162863162864162865162866162867162868162869162870162871162872162873162874162875162876162877162878162879162880162881162882162883162884162885162886162887162888162889162890162891162892162893162894162895162896162897162898162899162900162901162902162903162904162905162906162907162908162909162910162911162912162913162914162915162916162917162918162919162920162921162922162923162924162925162926162927162928162929162930162931162932162933162934162935162936162937162938162939162940162941162942162943162944162945162946162947162948162949162950162951162952162953162954162955162956162957162958162959162960162961162962162963162964162965162966162967162968162969162970162971162972162973162974162975162976162977162978162979162980162981162982162983162984162985162986162987162988162989162990162991162992162993162994162995162996162997162998162999163000163001163002163003163004163005163006163007163008163009163010163011163012163013163014163015163016163017163018163019163020163021163022163023163024163025163026163027163028163029163030163031163032163033163034163035163036163037163038163039163040163041163042163043163044163045163046163047163048163049163050163051163052163053163054163055163056163057163058163059163060163061163062163063163064163065163066163067163068163069163070163071163072163073163074163075163076163077163078163079163080163081163082163083163084163085163086163087163088163089163090163091163092163093163094163095163096163097163098163099163100163101163102163103163104163105163106163107163108163109163110163111163112163113163114163115163116163117163118163119163120163121163122163123163124163125163126163127163128163129163130163131163132163133163134163135163136163137163138163139163140163141163142163143163144163145163146163147163148163149163150163151163152163153163154163155163156163157163158163159163160163161163162163163163164163165163166163167163168163169163170163171163172163173163174163175163176163177163178163179163180163181163182163183163184163185163186163187163188163189163190163191163192163193163194163195163196163197163198163199163200163201163202163203163204163205163206163207163208163209163210163211163212163213163214163215163216163217163218163219163220163221163222163223163224163225163226163227163228163229163230163231163232163233163234163235163236163237163238163239163240163241163242163243163244163245163246163247163248163249163250163251163252163253163254163255163256163257163258163259163260163261163262163263163264163265163266163267163268163269163270163271163272163273163274163275163276163277163278163279163280163281163282163283163284163285163286163287163288163289163290163291163292163293163294163295163296163297163298163299163300163301163302163303163304163305163306163307163308163309163310163311163312163313163314163315163316163317163318163319163320163321163322163323163324163325163326163327163328163329163330163331163332163333163334163335163336163337163338163339163340163341163342163343163344163345163346163347163348163349163350163351163352163353163354163355163356163357163358163359163360163361163362163363163364163365163366163367163368163369163370163371163372163373163374163375163376163377163378163379163380163381163382163383163384163385163386163387163388163389163390163391163392163393163394163395163396163397163398163399163400163401163402163403163404163405163406163407163408163409163410163411163412163413163414163415163416163417163418163419163420163421163422163423163424163425163426163427163428163429163430163431163432163433163434163435163436163437163438163439163440163441163442163443163444163445163446163447163448163449163450163451163452163453163454163455163456163457163458163459163460163461163462163463163464163465163466163467163468163469163470163471163472163473163474163475163476163477163478163479163480163481163482163483163484163485163486163487163488163489163490163491163492163493163494163495163496163497163498163499163500163501163502163503163504163505163506163507163508163509163510163511163512163513163514163515163516163517163518163519163520163521163522163523163524163525163526163527163528163529163530163531163532163533163534163535163536163537163538163539163540163541163542163543163544163545163546163547163548163549163550163551163552163553163554163555163556163557163558163559163560163561163562163563163564163565163566163567163568163569163570163571163572163573163574163575163576163577163578163579163580163581163582163583163584163585163586163587163588163589163590163591163592163593163594163595163596163597163598163599163600163601163602163603163604163605163606163607163608163609163610163611163612163613163614163615163616163617163618163619163620163621163622163623163624163625163626163627163628163629163630163631163632163633163634163635163636163637163638163639163640163641163642163643163644163645163646163647163648163649163650163651163652163653163654163655163656163657163658163659163660163661163662163663163664163665163666163667163668163669163670163671163672163673163674163675163676163677163678163679163680163681163682163683163684163685163686163687163688163689163690163691163692163693163694163695163696163697163698163699163700163701163702163703163704163705163706163707163708163709163710163711163712163713163714163715163716163717163718163719163720163721163722163723163724163725163726163727163728163729163730163731163732163733163734163735163736163737163738163739163740163741163742163743163744163745163746163747163748163749163750163751163752163753163754163755163756163757163758163759163760163761163762163763163764163765163766163767163768163769163770163771163772163773163774163775163776163777163778163779163780163781163782163783163784163785163786163787163788163789163790163791163792163793163794163795163796163797163798163799163800163801163802163803163804163805163806163807163808163809163810163811163812163813163814163815163816163817163818163819163820163821163822163823163824163825163826163827163828163829163830163831163832163833163834163835163836163837163838163839163840163841163842163843163844163845163846163847163848163849163850163851163852163853163854163855163856163857163858163859163860163861163862163863163864163865163866163867163868163869163870163871163872163873163874163875163876163877163878163879163880163881163882163883163884163885163886163887163888163889163890163891163892163893163894163895163896163897163898163899163900163901163902163903163904163905163906163907163908163909163910163911163912163913163914163915163916163917163918163919163920163921163922163923163924163925163926163927163928163929163930163931163932163933163934163935163936163937163938163939163940163941163942163943163944163945163946163947163948163949163950163951163952163953163954163955163956163957163958163959163960163961163962163963163964163965163966163967163968163969163970163971163972163973163974163975163976163977163978163979163980163981163982163983163984163985163986163987163988163989163990163991163992163993163994163995163996163997163998163999164000164001164002164003164004164005164006164007164008164009164010164011164012164013164014164015164016164017164018164019164020164021164022164023164024164025164026164027164028164029164030164031164032164033164034164035164036164037164038164039164040164041164042164043164044164045164046164047164048164049164050164051164052164053164054164055164056164057164058164059164060164061164062164063164064164065164066164067164068164069164070164071164072164073164074164075164076164077164078164079164080164081164082164083164084164085164086164087164088164089164090164091164092164093164094164095164096164097164098164099164100164101164102164103164104164105164106164107164108164109164110164111164112164113164114164115164116164117164118164119164120164121164122164123164124164125164126164127164128164129164130164131164132164133164134164135164136164137164138164139164140164141164142164143164144164145164146164147164148164149164150164151164152164153164154164155164156164157164158164159164160164161164162164163164164164165164166164167164168164169164170164171164172164173164174164175164176164177164178164179164180164181164182164183164184164185164186164187164188164189164190164191164192164193164194164195164196164197164198164199164200164201164202164203164204164205164206164207164208164209164210164211164212164213164214164215164216164217164218164219164220164221164222164223164224164225164226164227164228164229164230164231164232164233164234164235164236164237164238164239164240164241164242164243164244164245164246164247164248164249164250164251164252164253164254164255164256164257164258164259164260164261164262164263164264164265164266164267164268164269164270164271164272164273164274164275164276164277164278164279164280164281164282164283164284164285164286164287164288164289164290164291164292164293164294164295164296164297164298164299164300164301164302164303164304164305164306164307164308164309164310164311164312164313164314164315164316164317164318164319164320164321164322164323164324164325164326164327164328164329164330164331164332164333164334164335164336164337164338164339164340164341164342164343164344164345164346164347164348164349164350164351164352164353164354164355164356164357164358164359164360164361164362164363164364164365164366164367164368164369164370164371164372164373164374164375164376164377164378164379164380164381164382164383164384164385164386164387164388164389164390164391164392164393164394164395164396164397164398164399164400164401164402164403164404164405164406164407164408164409164410164411164412164413164414164415164416164417164418164419164420164421164422164423164424164425164426164427164428164429164430164431164432164433164434164435164436164437164438164439164440164441164442164443164444164445164446164447164448164449164450164451164452164453164454164455164456164457164458164459164460164461164462164463164464164465164466164467164468164469164470164471164472164473164474164475164476164477164478164479164480164481164482164483164484164485164486164487164488164489164490164491164492164493164494164495164496164497164498164499164500164501164502164503164504164505164506164507164508164509164510164511164512164513164514164515164516164517164518164519164520164521164522164523164524164525164526164527164528164529164530164531164532164533164534164535164536164537164538164539164540164541164542164543164544164545164546164547164548164549164550164551164552164553164554164555164556164557164558164559164560164561164562164563164564164565164566164567164568164569164570164571164572164573164574164575164576164577164578164579164580164581164582164583164584164585164586164587164588164589164590164591164592164593164594164595164596164597164598164599164600164601164602164603164604164605164606164607164608164609164610164611164612164613164614164615164616164617164618164619164620164621164622164623164624164625164626164627164628164629164630164631164632164633164634164635164636164637164638164639164640164641164642164643164644164645164646164647164648164649164650164651164652164653164654164655164656164657164658164659164660164661164662164663164664164665164666164667164668164669164670164671164672164673164674164675164676164677164678164679164680164681164682164683164684164685164686164687164688164689164690164691164692164693164694164695164696164697164698164699164700164701164702164703164704164705164706164707164708164709164710164711164712164713164714164715164716164717164718164719164720164721164722164723164724164725164726164727164728164729164730164731164732164733164734164735164736164737164738164739164740164741164742164743164744164745164746164747164748164749164750164751164752164753164754164755164756164757164758164759164760164761164762164763164764164765164766164767164768164769164770164771164772164773164774164775164776164777164778164779164780164781164782164783164784164785164786164787164788164789164790164791164792164793164794164795164796164797164798164799164800164801164802164803164804164805164806164807164808164809164810164811164812164813164814164815164816164817164818164819164820164821164822164823164824164825164826164827164828164829164830164831164832164833164834164835164836164837164838164839164840164841164842164843164844164845164846164847164848164849164850164851164852164853164854164855164856164857164858164859164860164861164862164863164864164865164866164867164868164869164870164871164872164873164874164875164876164877164878164879164880164881164882164883164884164885164886164887164888164889164890164891164892164893164894164895164896164897164898164899164900164901164902164903164904164905164906164907164908164909164910164911164912164913164914164915164916164917164918164919164920164921164922164923164924164925164926164927164928164929164930164931164932164933164934164935164936164937164938164939164940164941164942164943164944164945164946164947164948164949164950164951164952164953164954164955164956164957164958164959164960164961164962164963164964164965164966164967164968164969164970164971164972164973164974164975164976164977164978164979164980164981164982164983164984164985164986164987164988164989164990164991164992164993164994164995164996164997164998164999165000165001165002165003165004165005165006165007165008165009165010165011165012165013165014165015165016165017165018165019165020165021165022165023165024165025165026165027165028165029165030165031165032165033165034165035165036165037165038165039165040165041165042165043165044165045165046165047165048165049165050165051165052165053165054165055165056165057165058165059165060165061165062165063165064165065165066165067165068165069165070165071165072165073165074165075165076165077165078165079165080165081165082165083165084165085165086165087165088165089165090165091165092165093165094165095165096165097165098165099165100165101165102165103165104165105165106165107165108165109165110165111165112165113165114165115165116165117165118165119165120165121165122165123165124165125165126165127165128165129165130165131165132165133165134165135165136165137165138165139165140165141165142165143165144165145165146165147165148165149165150165151165152165153165154165155165156165157165158165159165160165161165162165163165164165165165166165167165168165169165170165171165172165173165174165175165176165177165178165179165180165181165182165183165184165185165186165187165188165189165190165191165192165193165194165195165196165197165198165199165200165201165202165203165204165205165206165207165208165209165210165211165212165213165214165215165216165217165218165219165220165221165222165223165224165225165226165227165228165229165230165231165232165233165234165235165236165237165238165239165240165241165242165243165244165245165246165247165248165249165250165251165252165253165254165255165256165257165258165259165260165261165262165263165264165265165266165267165268165269165270165271165272165273165274165275165276165277165278165279165280165281165282165283165284165285165286165287165288165289165290165291165292165293165294165295165296165297165298165299165300165301165302165303165304165305165306165307165308165309165310165311165312165313165314165315165316165317165318165319165320165321165322165323165324165325165326165327165328165329165330165331165332165333165334165335165336165337165338165339165340165341165342165343165344165345165346165347165348165349165350165351165352165353165354165355165356165357165358165359165360165361165362165363165364165365165366165367165368165369165370165371165372165373165374165375165376165377165378165379165380165381165382165383165384165385165386165387165388165389165390165391165392165393165394165395165396165397165398165399165400165401165402165403165404165405165406165407165408165409165410165411165412165413165414165415165416165417165418165419165420165421165422165423165424165425165426165427165428165429165430165431165432165433165434165435165436165437165438165439165440165441165442165443165444165445165446165447165448165449165450165451165452165453165454165455165456165457165458165459165460165461165462165463165464165465165466165467165468165469165470165471165472165473165474165475165476165477165478165479165480165481165482165483165484165485165486165487165488165489165490165491165492165493165494165495165496165497165498165499165500165501165502165503165504165505165506165507165508165509165510165511165512165513165514165515165516165517165518165519165520165521165522165523165524165525165526165527165528165529165530165531165532165533165534165535165536165537165538165539165540165541165542165543165544165545165546165547165548165549165550165551165552165553165554165555165556165557165558165559165560165561165562165563165564165565165566165567165568165569165570165571165572165573165574165575165576165577165578165579165580165581165582165583165584165585165586165587165588165589165590165591165592165593165594165595165596165597165598165599165600165601165602165603165604165605165606165607165608165609165610165611165612165613165614165615165616165617165618165619165620165621165622165623165624165625165626165627165628165629165630165631165632165633165634165635165636165637165638165639165640165641165642165643165644165645165646165647165648165649165650165651165652165653165654165655165656165657165658165659165660165661165662165663165664165665165666165667165668165669165670165671165672165673165674165675165676165677165678165679165680165681165682165683165684165685165686165687165688165689165690165691165692165693165694165695165696165697165698165699165700165701165702165703165704165705165706165707165708165709165710165711165712165713165714165715165716165717165718165719165720165721165722165723165724165725165726165727165728165729165730165731165732165733165734165735165736165737165738165739165740165741165742165743165744165745165746165747165748165749165750165751165752165753165754165755165756165757165758165759165760165761165762165763165764165765165766165767165768165769165770165771165772165773165774165775165776165777165778165779165780165781165782165783165784165785165786165787165788165789165790165791165792165793165794165795165796165797165798165799165800165801165802165803165804165805165806165807165808165809165810165811165812165813165814165815165816165817165818165819165820165821165822165823165824165825165826165827165828165829165830165831165832165833165834165835165836165837165838165839165840165841165842165843165844165845165846165847165848165849165850165851165852165853165854165855165856165857165858165859165860165861165862165863165864165865165866165867165868165869165870165871165872165873165874165875165876165877165878165879165880165881165882165883165884165885165886165887165888165889165890165891165892165893165894165895165896165897165898165899165900165901165902165903165904165905165906165907165908165909165910165911165912165913165914165915165916165917165918165919165920165921165922165923165924165925165926165927165928165929165930165931165932165933165934165935165936165937165938165939165940165941165942165943165944165945165946165947165948165949165950165951165952165953165954165955165956165957165958165959165960165961165962165963165964165965165966165967165968165969165970165971165972165973165974165975165976165977165978165979165980165981165982165983165984165985165986165987165988165989165990165991165992165993165994165995165996165997165998165999166000166001166002166003166004166005166006166007166008166009166010166011166012166013166014166015166016166017166018166019166020166021166022166023166024166025166026166027166028166029166030166031166032166033166034166035166036166037166038166039166040166041166042166043166044166045166046166047166048166049166050166051166052166053166054166055166056166057166058166059166060166061166062166063166064166065166066166067166068166069166070166071166072166073166074166075166076166077166078166079166080166081166082166083166084166085166086166087166088166089166090166091166092166093166094166095166096166097166098166099166100166101166102166103166104166105166106166107166108166109166110166111166112166113166114166115166116166117166118166119166120166121166122166123166124166125166126166127166128166129166130166131166132166133166134166135166136166137166138166139166140166141166142166143166144166145166146166147166148166149166150166151166152166153166154166155166156166157166158166159166160166161166162166163166164166165166166166167166168166169166170166171166172166173166174166175166176166177166178166179166180166181166182166183166184166185166186166187166188166189166190166191166192166193166194166195166196166197166198166199166200166201166202166203166204166205166206166207166208166209166210166211166212166213166214166215166216166217166218166219166220166221166222166223166224166225166226166227166228166229166230166231166232166233166234166235166236166237166238166239166240166241166242166243166244166245166246166247166248166249166250166251166252166253166254166255166256166257166258166259166260166261166262166263166264166265166266166267166268166269166270166271166272166273166274166275166276166277166278166279166280166281166282166283166284166285166286166287166288166289166290166291166292166293166294166295166296166297166298166299166300166301166302166303166304166305166306166307166308166309166310166311166312166313166314166315166316166317166318166319166320166321166322166323166324166325166326166327166328166329166330166331166332166333166334166335166336166337166338166339166340166341166342166343166344166345166346166347166348166349166350166351166352166353166354166355166356166357166358166359166360166361166362166363166364166365166366166367166368166369166370166371166372166373166374166375166376166377166378166379166380166381166382166383166384166385166386166387166388166389166390166391166392166393166394166395166396166397166398166399166400166401166402166403166404166405166406166407166408166409166410166411166412166413166414166415166416166417166418166419166420166421166422166423166424166425166426166427166428166429166430166431166432166433166434166435166436166437166438166439166440166441166442166443166444166445166446166447166448166449166450166451166452166453166454166455166456166457166458166459166460166461166462166463166464166465166466166467166468166469166470166471166472166473166474166475166476166477166478166479166480166481166482166483166484166485166486166487166488166489166490166491166492166493166494166495166496166497166498166499166500166501166502166503166504166505166506166507166508166509166510166511166512166513166514166515166516166517166518166519166520166521166522166523166524166525166526166527166528166529166530166531166532166533166534166535166536166537166538166539166540166541166542166543166544166545166546166547166548166549166550166551166552166553166554166555166556166557166558166559166560166561166562166563166564166565166566166567166568166569166570166571166572166573166574166575166576166577166578166579166580166581166582166583166584166585166586166587166588166589166590166591166592166593166594166595166596166597166598166599166600166601166602166603166604166605166606166607166608166609166610166611166612166613166614166615166616166617166618166619166620166621166622166623166624166625166626166627166628166629166630166631166632166633166634166635166636166637166638166639166640166641166642166643166644166645166646166647166648166649166650166651166652166653166654166655166656166657166658166659166660166661166662166663166664166665166666166667166668166669166670166671166672166673166674166675166676166677166678166679166680166681166682166683166684166685166686166687166688166689166690166691166692166693166694166695166696166697166698166699166700166701166702166703166704166705166706166707166708166709166710166711166712166713166714166715166716166717166718166719166720166721166722166723166724166725166726166727166728166729166730166731166732166733166734166735166736166737166738166739166740166741166742166743166744166745166746166747166748166749166750166751166752166753166754166755166756166757166758166759166760166761166762166763166764166765166766166767166768166769166770166771166772166773166774166775166776166777166778166779166780166781166782166783166784166785166786166787166788166789166790166791166792166793166794166795166796166797166798166799166800166801166802166803166804166805166806166807166808166809166810166811166812166813166814166815166816166817166818166819166820166821166822166823166824166825166826166827166828166829166830166831166832166833166834166835166836166837166838166839166840166841166842166843166844166845166846166847166848166849166850166851166852166853166854166855166856166857166858166859166860166861166862166863166864166865166866166867166868166869166870166871166872166873166874166875166876166877166878166879166880166881166882166883166884166885166886166887166888166889166890166891166892166893166894166895166896166897166898166899166900166901166902166903166904166905166906166907166908166909166910166911166912166913166914166915166916166917166918166919166920166921166922166923166924166925166926166927166928166929166930166931166932166933166934166935166936166937166938166939166940166941166942166943166944166945166946166947166948166949166950166951166952166953166954166955166956166957166958166959166960166961166962166963166964166965166966166967166968166969166970166971166972166973166974166975166976166977166978166979166980166981166982166983166984166985166986166987166988166989166990166991166992166993166994166995166996166997166998166999167000167001167002167003167004167005167006167007167008167009167010167011167012167013167014167015167016167017167018167019167020167021167022167023167024167025167026167027167028167029167030167031167032167033167034167035167036167037167038167039167040167041167042167043167044167045167046167047167048167049167050167051167052167053167054167055167056167057167058167059167060167061167062167063167064167065167066167067167068167069167070167071167072167073167074167075167076167077167078167079167080167081167082167083167084167085167086167087167088167089167090167091167092167093167094167095167096167097167098167099167100167101167102167103167104167105167106167107167108167109167110167111167112167113167114167115167116167117167118167119167120167121167122167123167124167125167126167127167128167129167130167131167132167133167134167135167136167137167138167139167140167141167142167143167144167145167146167147167148167149167150167151167152167153167154167155167156167157167158167159167160167161167162167163167164167165167166167167167168167169167170167171167172167173167174167175167176167177167178167179167180167181167182167183167184167185167186167187167188167189167190167191167192167193167194167195167196167197167198167199167200167201167202167203167204167205167206167207167208167209167210167211167212167213167214167215167216167217167218167219167220167221167222167223167224167225167226167227167228167229167230167231167232167233167234167235167236167237167238167239167240167241167242167243167244167245167246167247167248167249167250167251167252167253167254167255167256167257167258167259167260167261167262167263167264167265167266167267167268167269167270167271167272167273167274167275167276167277167278167279167280167281167282167283167284167285167286167287167288167289167290167291167292167293167294167295167296167297167298167299167300167301167302167303167304167305167306167307167308167309167310167311167312167313167314167315167316167317167318167319167320167321167322167323167324167325167326167327167328167329167330167331167332167333167334167335167336167337167338167339167340167341167342167343167344167345167346167347167348167349167350167351167352167353167354167355167356167357167358167359167360167361167362167363167364167365167366167367167368167369167370167371167372167373167374167375167376167377167378167379167380167381167382167383167384167385167386167387167388167389167390167391167392167393167394167395167396167397167398167399167400167401167402167403167404167405167406167407167408167409167410167411167412167413167414167415167416167417167418167419167420167421167422167423167424167425167426167427167428167429167430167431167432167433167434167435167436167437167438167439167440167441167442167443167444167445167446167447167448167449167450167451167452167453167454167455167456167457167458167459167460167461167462167463167464167465167466167467167468167469167470167471167472167473167474167475167476167477167478167479167480167481167482167483167484167485167486167487167488167489167490167491167492167493167494167495167496167497167498167499167500167501167502167503167504167505167506167507167508167509167510167511167512167513167514167515167516167517167518167519167520167521167522167523167524167525167526167527167528167529167530167531167532167533167534167535167536167537167538167539167540167541167542167543167544167545167546167547167548167549167550167551167552167553167554167555167556167557167558167559167560167561167562167563167564167565167566167567167568167569167570167571167572167573167574167575167576167577167578167579167580167581167582167583167584167585167586167587167588167589167590167591167592167593167594167595167596167597167598167599167600167601167602167603167604167605167606167607167608167609167610167611167612167613167614167615167616167617167618167619167620167621167622167623167624167625167626167627167628167629167630167631167632167633167634167635167636167637167638167639167640167641167642167643167644167645167646167647167648167649167650167651167652167653167654167655167656167657167658167659167660167661167662167663167664167665167666167667167668167669167670167671167672167673167674167675167676167677167678167679167680167681167682167683167684167685167686167687167688167689167690167691167692167693167694167695167696167697167698167699167700167701167702167703167704167705167706167707167708167709167710167711167712167713167714167715167716167717167718167719167720167721167722167723167724167725167726167727167728167729167730167731167732167733167734167735167736167737167738167739167740167741167742167743167744167745167746167747167748167749167750167751167752167753167754167755167756167757167758167759167760167761167762167763167764167765167766167767167768167769167770167771167772167773167774167775167776167777167778167779167780167781167782167783167784167785167786167787167788167789167790167791167792167793167794167795167796167797167798167799167800167801167802167803167804167805167806167807167808167809167810167811167812167813167814167815167816167817167818167819167820167821167822167823167824167825167826167827167828167829167830167831167832167833167834167835167836167837167838167839167840167841167842167843167844167845167846167847167848167849167850167851167852167853167854167855167856167857167858167859167860167861167862167863167864167865167866167867167868167869167870167871167872167873167874167875167876167877167878167879167880167881167882167883167884167885167886167887167888167889167890167891167892167893167894167895167896167897167898167899167900167901167902167903167904167905167906167907167908167909167910167911167912167913167914167915167916167917167918167919167920167921167922167923167924167925167926167927167928167929167930167931167932167933167934167935167936167937167938167939167940167941167942167943167944167945167946167947167948167949167950167951167952167953167954167955167956167957167958167959167960167961167962167963167964167965167966167967167968167969167970167971167972167973167974167975167976167977167978167979167980167981167982167983167984167985167986167987167988167989167990167991167992167993167994167995167996167997167998167999168000168001168002168003168004168005168006168007168008168009168010168011168012168013168014168015168016168017168018168019168020168021168022168023168024168025168026168027168028168029168030168031168032168033168034168035168036168037168038168039168040168041168042168043168044168045168046168047168048168049168050168051168052168053168054168055168056168057168058168059168060168061168062168063168064168065168066168067168068168069168070168071168072168073168074168075168076168077168078168079168080168081168082168083168084168085168086168087168088168089168090168091168092168093168094168095168096168097168098168099168100168101168102168103168104168105168106168107168108168109168110168111168112168113168114168115168116168117168118168119168120168121168122168123168124168125168126168127168128168129168130168131168132168133168134168135168136168137168138168139168140168141168142168143168144168145168146168147168148168149168150168151168152168153168154168155168156168157168158168159168160168161168162168163168164168165168166168167168168168169168170168171168172168173168174168175168176168177168178168179168180168181168182168183168184168185168186168187168188168189168190168191168192168193168194168195168196168197168198168199168200168201168202168203168204168205168206168207168208168209168210168211168212168213168214168215168216168217168218168219168220168221168222168223168224168225168226168227168228168229168230168231168232168233168234168235168236168237168238168239168240168241168242168243168244168245168246168247168248168249168250168251168252168253168254168255168256168257168258168259168260168261168262168263168264168265168266168267168268168269168270168271168272168273168274168275168276168277168278168279168280168281168282168283168284168285168286168287168288168289168290168291168292168293168294168295168296168297168298168299168300168301168302168303168304168305168306168307168308168309168310168311168312168313168314168315168316168317168318168319168320168321168322168323168324168325168326168327168328168329168330168331168332168333168334168335168336168337168338168339168340168341168342168343168344168345168346168347168348168349168350168351168352168353168354168355168356168357168358168359168360168361168362168363168364168365168366168367168368168369168370168371168372168373168374168375168376168377168378168379168380168381168382168383168384168385168386168387168388168389168390168391168392168393168394168395168396168397168398168399168400168401168402168403168404168405168406168407168408168409168410168411168412168413168414168415168416168417168418168419168420168421168422168423168424168425168426168427168428168429168430168431168432168433168434168435168436168437168438168439168440168441168442168443168444168445168446168447168448168449168450168451168452168453168454168455168456168457168458168459168460168461168462168463168464168465168466168467168468168469168470168471168472168473168474168475168476168477168478168479168480168481168482168483168484168485168486168487168488168489168490168491168492168493168494168495168496168497168498168499168500168501168502168503168504168505168506168507168508168509168510168511168512168513168514168515168516168517168518168519168520168521168522168523168524168525168526168527168528168529168530168531168532168533168534168535168536168537168538168539168540168541168542168543168544168545168546168547168548168549168550168551168552168553168554168555168556168557168558168559168560168561168562168563168564168565168566168567168568168569168570168571168572168573168574168575168576168577168578168579168580168581168582168583168584168585168586168587168588168589168590168591168592168593168594168595168596168597168598168599168600168601168602168603168604168605168606168607168608168609168610168611168612168613168614168615168616168617168618168619168620168621168622168623168624168625168626168627168628168629168630168631168632168633168634168635168636168637168638168639168640168641168642168643168644168645168646168647168648168649168650168651168652168653168654168655168656168657168658168659168660168661168662168663168664168665168666168667168668168669168670168671168672168673168674168675168676168677168678168679168680168681168682168683168684168685168686168687168688168689168690168691168692168693168694168695168696168697168698168699168700168701168702168703168704168705168706168707168708168709168710168711168712168713168714168715168716168717168718168719168720168721168722168723168724168725168726168727168728168729168730168731168732168733168734168735168736168737168738168739168740168741168742168743168744168745168746168747168748168749168750168751168752168753168754168755168756168757168758168759168760168761168762168763168764168765168766168767168768168769168770168771168772168773168774168775168776168777168778168779168780168781168782168783168784168785168786168787168788168789168790168791168792168793168794168795168796168797168798168799168800168801168802168803168804168805168806168807168808168809168810168811168812168813168814168815168816168817168818168819168820168821168822168823168824168825168826168827168828168829168830168831168832168833168834168835168836168837168838168839168840168841168842168843168844168845168846168847168848168849168850168851168852168853168854168855168856168857168858168859168860168861168862168863168864168865168866168867168868168869168870168871168872168873168874168875168876168877168878168879168880168881168882168883168884168885168886168887168888168889168890168891168892168893168894168895168896168897168898168899168900168901168902168903168904168905168906168907168908168909168910168911168912168913168914168915168916168917168918168919168920168921168922168923168924168925168926168927168928168929168930168931168932168933168934168935168936168937168938168939168940168941168942168943168944168945168946168947168948168949168950168951168952168953168954168955168956168957168958168959168960168961168962168963168964168965168966168967168968168969168970168971168972168973168974168975168976168977168978168979168980168981168982168983168984168985168986168987168988168989168990168991168992168993168994168995168996168997168998168999169000169001169002169003169004169005169006169007169008169009169010169011169012169013169014169015169016169017169018169019169020169021169022169023169024169025169026169027169028169029169030169031169032169033169034169035169036169037169038169039169040169041169042169043169044169045169046169047169048169049169050169051169052169053169054169055169056169057169058169059169060169061169062169063169064169065169066169067169068169069169070169071169072169073169074169075169076169077169078169079169080169081169082169083169084169085169086169087169088169089169090169091169092169093169094169095169096169097169098169099169100169101169102169103169104169105169106169107169108169109169110169111169112169113169114169115169116169117169118169119169120169121169122169123169124169125169126169127169128169129169130169131169132169133169134169135169136169137169138169139169140169141169142169143169144169145169146169147169148169149169150169151169152169153169154169155169156169157169158169159169160169161169162169163169164169165169166169167169168169169169170169171169172169173169174169175169176169177169178169179169180169181169182169183169184169185169186169187169188169189169190169191169192169193169194169195169196169197169198169199169200169201169202169203169204169205169206169207169208169209169210169211169212169213169214169215169216169217169218169219169220169221169222169223169224169225169226169227169228169229169230169231169232169233169234169235169236169237169238169239169240169241169242169243169244169245169246169247169248169249169250169251169252169253169254169255169256169257169258169259169260169261169262169263169264169265169266169267169268169269169270169271169272169273169274169275169276169277169278169279169280169281169282169283169284169285169286169287169288169289169290169291169292169293169294169295169296169297169298169299169300169301169302169303169304169305169306169307169308169309169310169311169312169313169314169315169316169317169318169319169320169321169322169323169324169325169326169327169328169329169330169331169332169333169334169335169336169337169338169339169340169341169342169343169344169345169346169347169348169349169350169351169352169353169354169355169356169357169358169359169360169361169362169363169364169365169366169367169368169369169370169371169372169373169374169375169376169377169378169379169380169381169382169383169384169385169386169387169388169389169390169391169392169393169394169395169396169397169398169399169400169401169402169403169404169405169406169407169408169409169410169411169412169413169414169415169416169417169418169419169420169421169422169423169424169425169426169427169428169429169430169431169432169433169434169435169436169437169438169439169440169441169442169443169444169445169446169447169448169449169450169451169452169453169454169455169456169457169458169459169460169461169462169463169464169465169466169467169468169469169470169471169472169473169474169475169476169477169478169479169480169481169482169483169484169485169486169487169488169489169490169491169492169493169494169495169496169497169498169499169500169501169502169503169504169505169506169507169508169509169510169511169512169513169514169515169516169517169518169519169520169521169522169523169524169525169526169527169528169529169530169531169532169533169534169535169536169537169538169539169540169541169542169543169544169545169546169547169548169549169550169551169552169553169554169555169556169557169558169559169560169561169562169563169564169565169566169567169568169569169570169571169572169573169574169575169576169577169578169579169580169581169582169583169584169585169586169587169588169589169590169591169592169593169594169595169596169597169598169599169600169601169602169603169604169605169606169607169608169609169610169611169612169613169614169615169616169617169618169619169620169621169622169623169624169625169626169627169628169629169630169631169632169633169634169635169636169637169638169639169640169641169642169643169644169645169646169647169648169649169650169651169652169653169654169655169656169657169658169659169660169661169662169663169664169665169666169667169668169669169670169671169672169673169674169675169676169677169678169679169680169681169682169683169684169685169686169687169688169689169690169691169692169693169694169695169696169697169698169699169700169701169702169703169704169705169706169707169708169709169710169711169712169713169714169715169716169717169718169719169720169721169722169723169724169725169726169727169728169729169730169731169732169733169734169735169736169737169738169739169740169741169742169743169744169745169746169747169748169749169750169751169752169753169754169755169756169757169758169759169760169761169762169763169764169765169766169767169768169769169770169771169772169773169774169775169776169777169778169779169780169781169782169783169784169785169786169787169788169789169790169791169792169793169794169795169796169797169798169799169800169801169802169803169804169805169806169807169808169809169810169811169812169813169814169815169816169817169818169819169820169821169822169823169824169825169826169827169828169829169830169831169832169833169834169835169836169837169838169839169840169841169842169843169844169845169846169847169848169849169850169851169852169853169854169855169856169857169858169859169860169861169862169863169864169865169866169867169868169869169870169871169872169873169874169875169876169877169878169879169880169881169882169883169884169885169886169887169888169889169890169891169892169893169894169895169896169897169898169899169900169901169902169903169904169905169906169907169908169909169910169911169912169913169914169915169916169917169918169919169920169921169922169923169924169925169926169927169928169929169930169931169932169933169934169935169936169937169938169939169940169941169942169943169944169945169946169947169948169949169950169951169952169953169954169955169956169957169958169959169960169961169962169963169964169965169966169967169968169969169970169971169972169973169974169975169976169977169978169979169980169981169982169983169984169985169986169987169988169989169990169991169992169993169994169995169996169997169998169999170000170001170002170003170004170005170006170007170008170009170010170011170012170013170014170015170016170017170018170019170020170021170022170023170024170025170026170027170028170029170030170031170032170033170034170035170036170037170038170039170040170041170042170043170044170045170046170047170048170049170050170051170052170053170054170055170056170057170058170059170060170061170062170063170064170065170066170067170068170069170070170071170072170073170074170075170076170077170078170079170080170081170082170083170084170085170086170087170088170089170090170091170092170093170094170095170096170097170098170099170100170101170102170103170104170105170106170107170108170109170110170111170112170113170114170115170116170117170118170119170120170121170122170123170124170125170126170127170128170129170130170131170132170133170134170135170136170137170138170139170140170141170142170143170144170145170146170147170148170149170150170151170152170153170154170155170156170157170158170159170160170161170162170163170164170165170166170167170168170169170170170171170172170173170174170175170176170177170178170179170180170181170182170183170184170185170186170187170188170189170190170191170192170193170194170195170196170197170198170199170200170201170202170203170204170205170206170207170208170209170210170211170212170213170214170215170216170217170218170219170220170221170222170223170224170225170226170227170228170229170230170231170232170233170234170235170236170237170238170239170240170241170242170243170244170245170246170247170248170249170250170251170252170253170254170255170256170257170258170259170260170261170262170263170264170265170266170267170268170269170270170271170272170273170274170275170276170277170278170279170280170281170282170283170284170285170286170287170288170289170290170291170292170293170294170295170296170297170298170299170300170301170302170303170304170305170306170307170308170309170310170311170312170313170314170315170316170317170318170319170320170321170322170323170324170325170326170327170328170329170330170331170332170333170334170335170336170337170338170339170340170341170342170343170344170345170346170347170348170349170350170351170352170353170354170355170356170357170358170359170360170361170362170363170364170365170366170367170368170369170370170371170372170373170374170375170376170377170378170379170380170381170382170383170384170385170386170387170388170389170390170391170392170393170394170395170396170397170398170399170400170401170402170403170404170405170406170407170408170409170410170411170412170413170414170415170416170417170418170419170420170421170422170423170424170425170426170427170428170429170430170431170432170433170434170435170436170437170438170439170440170441170442170443170444170445170446170447170448170449170450170451170452170453170454170455170456170457170458170459170460170461170462170463170464170465170466170467170468170469170470170471170472170473170474170475170476170477170478170479170480170481170482170483170484170485170486170487170488170489170490170491170492170493170494170495170496170497170498170499170500170501170502170503170504170505170506170507170508170509170510170511170512170513170514170515170516170517170518170519170520170521170522170523170524170525170526170527170528170529170530170531170532170533170534170535170536170537170538170539170540170541170542170543170544170545170546170547170548170549170550170551170552170553170554170555170556170557170558170559170560170561170562170563170564170565170566170567170568170569170570170571170572170573170574170575170576170577170578170579170580170581170582170583170584170585170586170587170588170589170590170591170592170593170594170595170596170597170598170599170600170601170602170603170604170605170606170607170608170609170610170611170612170613170614170615170616170617170618170619170620170621170622170623170624170625170626170627170628170629170630170631170632170633170634170635170636170637170638170639170640170641170642170643170644170645170646170647170648170649170650170651170652170653170654170655170656170657170658170659170660170661170662170663170664170665170666170667170668170669170670170671170672170673170674170675170676170677170678170679170680170681170682170683170684170685170686170687170688170689170690170691170692170693170694170695170696170697170698170699170700170701170702170703170704170705170706170707170708170709170710170711170712170713170714170715170716170717170718170719170720170721170722170723170724170725170726170727170728170729170730170731170732170733170734170735170736170737170738170739170740170741170742170743170744170745170746170747170748170749170750170751170752170753170754170755170756170757170758170759170760170761170762170763170764170765170766170767170768170769170770170771170772170773170774170775170776170777170778170779170780170781170782170783170784170785170786170787170788170789170790170791170792170793170794170795170796170797170798170799170800170801170802170803170804170805170806170807170808170809170810170811170812170813170814170815170816170817170818170819170820170821170822170823170824170825170826170827170828170829170830170831170832170833170834170835170836170837170838170839170840170841170842170843170844170845170846170847170848170849170850170851170852170853170854170855170856170857170858170859170860170861170862170863170864170865170866170867170868170869170870170871170872170873170874170875170876170877170878170879170880170881170882170883170884170885170886170887170888170889170890170891170892170893170894170895170896170897170898170899170900170901170902170903170904170905170906170907170908170909170910170911170912170913170914170915170916170917170918170919170920170921170922170923170924170925170926170927170928170929170930170931170932170933170934170935170936170937170938170939170940170941170942170943170944170945170946170947170948170949170950170951170952170953170954170955170956170957170958170959170960170961170962170963170964170965170966170967170968170969170970170971170972170973170974170975170976170977170978170979170980170981170982170983170984170985170986170987170988170989170990170991170992170993170994170995170996170997170998170999171000171001171002171003171004171005171006171007171008171009171010171011171012171013171014171015171016171017171018171019171020171021171022171023171024171025171026171027171028171029171030171031171032171033171034171035171036171037171038171039171040171041171042171043171044171045171046171047171048171049171050171051171052171053171054171055171056171057171058171059171060171061171062171063171064171065171066171067171068171069171070171071171072171073171074171075171076171077171078171079171080171081171082171083171084171085171086171087171088171089171090171091171092171093171094171095171096171097171098171099171100171101171102171103171104171105171106171107171108171109171110171111171112171113171114171115171116171117171118171119171120171121171122171123171124171125171126171127171128171129171130171131171132171133171134171135171136171137171138171139171140171141171142171143171144171145171146171147171148171149171150171151171152171153171154171155171156171157171158171159171160171161171162171163171164171165171166171167171168171169171170171171171172171173171174171175171176171177171178171179171180171181171182171183171184171185171186171187171188171189171190171191171192171193171194171195171196171197171198171199171200171201171202171203171204171205171206171207171208171209171210171211171212171213171214171215171216171217171218171219171220171221171222171223171224171225171226171227171228171229171230171231171232171233171234171235171236171237171238171239171240171241171242171243171244171245171246171247171248171249171250171251171252171253171254171255171256171257171258171259171260171261171262171263171264171265171266171267171268171269171270171271171272171273171274171275171276171277171278171279171280171281171282171283171284171285171286171287171288171289171290171291171292171293171294171295171296171297171298171299171300171301171302171303171304171305171306171307171308171309171310171311171312171313171314171315171316171317171318171319171320171321171322171323171324171325171326171327171328171329171330171331171332171333171334171335171336171337171338171339171340171341171342171343171344171345171346171347171348171349171350171351171352171353171354171355171356171357171358171359171360171361171362171363171364171365171366171367171368171369171370171371171372171373171374171375171376171377171378171379171380171381171382171383171384171385171386171387171388171389171390171391171392171393171394171395171396171397171398171399171400171401171402171403171404171405171406171407171408171409171410171411171412171413171414171415171416171417171418171419171420171421171422171423171424171425171426171427171428171429171430171431171432171433171434171435171436171437171438171439171440171441171442171443171444171445171446171447171448171449171450171451171452171453171454171455171456171457171458171459171460171461171462171463171464171465171466171467171468171469171470171471171472171473171474171475171476171477171478171479171480171481171482171483171484171485171486171487171488171489171490171491171492171493171494171495171496171497171498171499171500171501171502171503171504171505171506171507171508171509171510171511171512171513171514171515171516171517171518171519171520171521171522171523171524171525171526171527171528171529171530171531171532171533171534171535171536171537171538171539171540171541171542171543171544171545171546171547171548171549171550171551171552171553171554171555171556171557171558171559171560171561171562171563171564171565171566171567171568171569171570171571171572171573171574171575171576171577171578171579171580171581171582171583171584171585171586171587171588171589171590171591171592171593171594171595171596171597171598171599171600171601171602171603171604171605171606171607171608171609171610171611171612171613171614171615171616171617171618171619171620171621171622171623171624171625171626171627171628171629171630171631171632171633171634171635171636171637171638171639171640171641171642171643171644171645171646171647171648171649171650171651171652171653171654171655171656171657171658171659171660171661171662171663171664171665171666171667171668171669171670171671171672171673171674171675171676171677171678171679171680171681171682171683171684171685171686171687171688171689171690171691171692171693171694171695171696171697171698171699171700171701171702171703171704171705171706171707171708171709171710171711171712171713171714171715171716171717171718171719171720171721171722171723171724171725171726171727171728171729171730171731171732171733171734171735171736171737171738171739171740171741171742171743171744171745171746171747171748171749171750171751171752171753171754171755171756171757171758171759171760171761171762171763171764171765171766171767171768171769171770171771171772171773171774171775171776171777171778171779171780171781171782171783171784171785171786171787171788171789171790171791171792171793171794171795171796171797171798171799171800171801171802171803171804171805171806171807171808171809171810171811171812171813171814171815171816171817171818171819171820171821171822171823171824171825171826171827171828171829171830171831171832171833171834171835171836171837171838171839171840171841171842171843171844171845171846171847171848171849171850171851171852171853171854171855171856171857171858171859171860171861171862171863171864171865171866171867171868171869171870171871171872171873171874171875171876171877171878171879171880171881171882171883171884171885171886171887171888171889171890171891171892171893171894171895171896171897171898171899171900171901171902171903171904171905171906171907171908171909171910171911171912171913171914171915171916171917171918171919171920171921171922171923171924171925171926171927171928171929171930171931171932171933171934171935171936171937171938171939171940171941171942171943171944171945171946171947171948171949171950171951171952171953171954171955171956171957171958171959171960171961171962171963171964171965171966171967171968171969171970171971171972171973171974171975171976171977171978171979171980171981171982171983171984171985171986171987171988171989171990171991171992171993171994171995171996171997171998171999172000172001172002172003172004172005172006172007172008172009172010172011172012172013172014172015172016172017172018172019172020172021172022172023172024172025172026172027172028172029172030172031172032172033172034172035172036172037172038172039172040172041172042172043172044172045172046172047172048172049172050172051172052172053172054172055172056172057172058172059172060172061172062172063172064172065172066172067172068172069172070172071172072172073172074172075172076172077172078172079172080172081172082172083172084172085172086172087172088172089172090172091172092172093172094172095172096172097172098172099172100172101172102172103172104172105172106172107172108172109172110172111172112172113172114172115172116172117172118172119172120172121172122172123172124172125172126172127172128172129172130172131172132172133172134172135172136172137172138172139172140172141172142172143172144172145172146172147172148172149172150172151172152172153172154172155172156172157172158172159172160172161172162172163172164172165172166172167172168172169172170172171172172172173172174172175172176172177172178172179172180172181172182172183172184172185172186172187172188172189172190172191172192172193172194172195172196172197172198172199172200172201172202172203172204172205172206172207172208172209172210172211172212172213172214172215172216172217172218172219172220172221172222172223172224172225172226172227172228172229172230172231172232172233172234172235172236172237172238172239172240172241172242172243172244172245172246172247172248172249172250172251172252172253172254172255172256172257172258172259172260172261172262172263172264172265172266172267172268172269172270172271172272172273172274172275172276172277172278172279172280172281172282172283172284172285172286172287172288172289172290172291172292172293172294172295172296172297172298172299172300172301172302172303172304172305172306172307172308172309172310172311172312172313172314172315172316172317172318172319172320172321172322172323172324172325172326172327172328172329172330172331172332172333172334172335172336172337172338172339172340172341172342172343172344172345172346172347172348172349172350172351172352172353172354172355172356172357172358172359172360172361172362172363172364172365172366172367172368172369172370172371172372172373172374172375172376172377172378172379172380172381172382172383172384172385172386172387172388172389172390172391172392172393172394172395172396172397172398172399172400172401172402172403172404172405172406172407172408172409172410172411172412172413172414172415172416172417172418172419172420172421172422172423172424172425172426172427172428172429172430172431172432172433172434172435172436172437172438172439172440172441172442172443172444172445172446172447172448172449172450172451172452172453172454172455172456172457172458172459172460172461172462172463172464172465172466172467172468172469172470172471172472172473172474172475172476172477172478172479172480172481172482172483172484172485172486172487172488172489172490172491172492172493172494172495172496172497172498172499172500172501172502172503172504172505172506172507172508172509172510172511172512172513172514172515172516172517172518172519172520172521172522172523172524172525172526172527172528172529172530172531172532172533172534172535172536172537172538172539172540172541172542172543172544172545172546172547172548172549172550172551172552172553172554172555172556172557172558172559172560172561172562172563172564172565172566172567172568172569172570172571172572172573172574172575172576172577172578172579172580172581172582172583172584172585172586172587172588172589172590172591172592172593172594172595172596172597172598172599172600172601172602172603172604172605172606172607172608172609172610172611172612172613172614172615172616172617172618172619172620172621172622172623172624172625172626172627172628172629172630172631172632172633172634172635172636172637172638172639172640172641172642172643172644172645172646172647172648172649172650172651172652172653172654172655172656172657172658172659172660172661172662172663172664172665172666172667172668172669172670172671172672172673172674172675172676172677172678172679172680172681172682172683172684172685172686172687172688172689172690172691172692172693172694172695172696172697172698172699172700172701172702172703172704172705172706172707172708172709172710172711172712172713172714172715172716172717172718172719172720172721172722172723172724172725172726172727172728172729172730172731172732172733172734172735172736172737172738172739172740172741172742172743172744172745172746172747172748172749172750172751172752172753172754172755172756172757172758172759172760172761172762172763172764172765172766172767172768172769172770172771172772172773172774172775172776172777172778172779172780172781172782172783172784172785172786172787172788172789172790172791172792172793172794172795172796172797172798172799172800172801172802172803172804172805172806172807172808172809172810172811172812172813172814172815172816172817172818172819172820172821172822172823172824172825172826172827172828172829172830172831172832172833172834172835172836172837172838172839172840172841172842172843172844172845172846172847172848172849172850172851172852172853172854172855172856172857172858172859172860172861172862172863172864172865172866172867172868172869172870172871172872172873172874172875172876172877172878172879172880172881172882172883172884172885172886172887172888172889172890172891172892172893172894172895172896172897172898172899172900172901172902172903172904172905172906172907172908172909172910172911172912172913172914172915172916172917172918172919172920172921172922172923172924172925172926172927172928172929172930172931172932172933172934172935172936172937172938172939172940172941172942172943172944172945172946172947172948172949172950172951172952172953172954172955172956172957172958172959172960172961172962172963172964172965172966172967172968172969172970172971172972172973172974172975172976172977172978172979172980172981172982172983172984172985172986172987172988172989172990172991172992172993172994172995172996172997172998172999173000173001173002173003173004173005173006173007173008173009173010173011173012173013173014173015173016173017173018173019173020173021173022173023173024173025173026173027173028173029173030173031173032173033173034173035173036173037173038173039173040173041173042173043173044173045173046173047173048173049173050173051173052173053173054173055173056173057173058173059173060173061173062173063173064173065173066173067173068173069173070173071173072173073173074173075173076173077173078173079173080173081173082173083173084173085173086173087173088173089173090173091173092173093173094173095173096173097173098173099173100173101173102173103173104173105173106173107173108173109173110173111173112173113173114173115173116173117173118173119173120173121173122173123173124173125173126173127173128173129173130173131173132173133173134173135173136173137173138173139173140173141173142173143173144173145173146173147173148173149173150173151173152173153173154173155173156173157173158173159173160173161173162173163173164173165173166173167173168173169173170173171173172173173173174173175173176173177173178173179173180173181173182173183173184173185173186173187173188173189173190173191173192173193173194173195173196173197173198173199173200173201173202173203173204173205173206173207173208173209173210173211173212173213173214173215173216173217173218173219173220173221173222173223173224173225173226173227173228173229173230173231173232173233173234173235173236173237173238173239173240173241173242173243173244173245173246173247173248173249173250173251173252173253173254173255173256173257173258173259173260173261173262173263173264173265173266173267173268173269173270173271173272173273173274173275173276173277173278173279173280173281173282173283173284173285173286173287173288173289173290173291173292173293173294173295173296173297173298173299173300173301173302173303173304173305173306173307173308173309173310173311173312173313173314173315173316173317173318173319173320173321173322173323173324173325173326173327173328173329173330173331173332173333173334173335173336173337173338173339173340173341173342173343173344173345173346173347173348173349173350173351173352173353173354173355173356173357173358173359173360173361173362173363173364173365173366173367173368173369173370173371173372173373173374173375173376173377173378173379173380173381173382173383173384173385173386173387173388173389173390173391173392173393173394173395173396173397173398173399173400173401173402173403173404173405173406173407173408173409173410173411173412173413173414173415173416173417173418173419173420173421173422173423173424173425173426173427173428173429173430173431173432173433173434173435173436173437173438173439173440173441173442173443173444173445173446173447173448173449173450173451173452173453173454173455173456173457173458173459173460173461173462173463173464173465173466173467173468173469173470173471173472173473173474173475173476173477173478173479173480173481173482173483173484173485173486173487173488173489173490173491173492173493173494173495173496173497173498173499173500173501173502173503173504173505173506173507173508173509173510173511173512173513173514173515173516173517173518173519173520173521173522173523173524173525173526173527173528173529173530173531173532173533173534173535173536173537173538173539173540173541173542173543173544173545173546173547173548173549173550173551173552173553173554173555173556173557173558173559173560173561173562173563173564173565173566173567173568173569173570173571173572173573173574173575173576173577173578173579173580173581173582173583173584173585173586173587173588173589173590173591173592173593173594173595173596173597173598173599173600173601173602173603173604173605173606173607173608173609173610173611173612173613173614173615173616173617173618173619173620173621173622173623173624173625173626173627173628173629173630173631173632173633173634173635173636173637173638173639173640173641173642173643173644173645173646173647173648173649173650173651173652173653173654173655173656173657173658173659173660173661173662173663173664173665173666173667173668173669173670173671173672173673173674173675173676173677173678173679173680173681173682173683173684173685173686173687173688173689173690173691173692173693173694173695173696173697173698173699173700173701173702173703173704173705173706173707173708173709173710173711173712173713173714173715173716173717173718173719173720173721173722173723173724173725173726173727173728173729173730173731173732173733173734173735173736173737173738173739173740173741173742173743173744173745173746173747173748173749173750173751173752173753173754173755173756173757173758173759173760173761173762173763173764173765173766173767173768173769173770173771173772173773173774173775173776173777173778173779173780173781173782173783173784173785173786173787173788173789173790173791173792173793173794173795173796173797173798173799173800173801173802173803173804173805173806173807173808173809173810173811173812173813173814173815173816173817173818173819173820173821173822173823173824173825173826173827173828173829173830173831173832173833173834173835173836173837173838173839173840173841173842173843173844173845173846173847173848173849173850173851173852173853173854173855173856173857173858173859173860173861173862173863173864173865173866173867173868173869173870173871173872173873173874173875173876173877173878173879173880173881173882173883173884173885173886173887173888173889173890173891173892173893173894173895173896173897173898173899173900173901173902173903173904173905173906173907173908173909173910173911173912173913173914173915173916173917173918173919173920173921173922173923173924173925173926173927173928173929173930173931173932173933173934173935173936173937173938173939173940173941173942173943173944173945173946173947173948173949173950173951173952173953173954173955173956173957173958173959173960173961173962173963173964173965173966173967173968173969173970173971173972173973173974173975173976173977173978173979173980173981173982173983173984173985173986173987173988173989173990173991173992173993173994173995173996173997173998173999174000174001174002174003174004174005174006174007174008174009174010174011174012174013174014174015174016174017174018174019174020174021174022174023174024174025174026174027174028174029174030174031174032174033174034174035174036174037174038174039174040174041174042174043174044174045174046174047174048174049174050174051174052174053174054174055174056174057174058174059174060174061174062174063174064174065174066174067174068174069174070174071174072174073174074174075174076174077174078174079174080174081174082174083174084174085174086174087174088174089174090174091174092174093174094174095174096174097174098174099174100174101174102174103174104174105174106174107174108174109174110174111174112174113174114174115174116174117174118174119174120174121174122174123174124174125174126174127174128174129174130174131174132174133174134174135174136174137174138174139174140174141174142174143174144174145174146174147174148174149174150174151174152174153174154174155174156174157174158174159174160174161174162174163174164174165174166174167174168174169174170174171174172174173174174174175174176174177174178174179174180174181174182174183174184174185174186174187174188174189174190174191174192174193174194174195174196174197174198174199174200174201174202174203174204174205174206174207174208174209174210174211174212174213174214174215174216174217174218174219174220174221174222174223174224174225174226174227174228174229174230174231174232174233174234174235174236174237174238174239174240174241174242174243174244174245174246174247174248174249174250174251174252174253174254174255174256174257174258174259174260174261174262174263174264174265174266174267174268174269174270174271174272174273174274174275174276174277174278174279174280174281174282174283174284174285174286174287174288174289174290174291174292174293174294174295174296174297174298174299174300174301174302174303174304174305174306174307174308174309174310174311174312174313174314174315174316174317174318174319174320174321174322174323174324174325174326174327174328174329174330174331174332174333174334174335174336174337174338174339174340174341174342174343174344174345174346174347174348174349174350174351174352174353174354174355174356174357174358174359174360174361174362174363174364174365174366174367174368174369174370174371174372174373174374174375174376174377174378174379174380174381174382174383174384174385174386174387174388174389174390174391174392174393174394174395174396174397174398174399174400174401174402174403174404174405174406174407174408174409174410174411174412174413174414174415174416174417174418174419174420174421174422174423174424174425174426174427174428174429174430174431174432174433174434174435174436174437174438174439174440174441174442174443174444174445174446174447174448174449174450174451174452174453174454174455174456174457174458174459174460174461174462174463174464174465174466174467174468174469174470174471174472174473174474174475174476174477174478174479174480174481174482174483174484174485174486174487174488174489174490174491174492174493174494174495174496174497174498174499174500174501174502174503174504174505174506174507174508174509174510174511174512174513174514174515174516174517174518174519174520174521174522174523174524174525174526174527174528174529174530174531174532174533174534174535174536174537174538174539174540174541174542174543174544174545174546174547174548174549174550174551174552174553174554174555174556174557174558174559174560174561174562174563174564174565174566174567174568174569174570174571174572174573174574174575174576174577174578174579174580174581174582174583174584174585174586174587174588174589174590174591174592174593174594174595174596174597174598174599174600174601174602174603174604174605174606174607174608174609174610174611174612174613174614174615174616174617174618174619174620174621174622174623174624174625174626174627174628174629174630174631174632174633174634174635174636174637174638174639174640174641174642174643174644174645174646174647174648174649174650174651174652174653174654174655174656174657174658174659174660174661174662174663174664174665174666174667174668174669174670174671174672174673174674174675174676174677174678174679174680174681174682174683174684174685174686174687174688174689174690174691174692174693174694174695174696174697174698174699174700174701174702174703174704174705174706174707174708174709174710174711174712174713174714174715174716174717174718174719174720174721174722174723174724174725174726174727174728174729174730174731174732174733174734174735174736174737174738174739174740174741174742174743174744174745174746174747174748174749174750174751174752174753174754174755174756174757174758174759174760174761174762174763174764174765174766174767174768174769174770174771174772174773174774174775174776174777174778174779174780174781174782174783174784174785174786174787174788174789174790174791174792174793174794174795174796174797174798174799174800174801174802174803174804174805174806174807174808174809174810174811174812174813174814174815174816174817174818174819174820174821174822174823174824174825174826174827174828174829174830174831174832174833174834174835174836174837174838174839174840174841174842174843174844174845174846174847174848174849174850174851174852174853174854174855174856174857174858174859174860174861174862174863174864174865174866174867174868174869174870174871174872174873174874174875174876174877174878174879174880174881174882174883174884174885174886174887174888174889174890174891174892174893174894174895174896174897174898174899174900174901174902174903174904174905174906174907174908174909174910174911174912174913174914174915174916174917174918174919174920174921174922174923174924174925174926174927174928174929174930174931174932174933174934174935174936174937174938174939174940174941174942174943174944174945174946174947174948174949174950174951174952174953174954174955174956174957174958174959174960174961174962174963174964174965174966174967174968174969174970174971174972174973174974174975174976174977174978174979174980174981174982174983174984174985174986174987174988174989174990174991174992174993174994174995174996174997174998174999175000175001175002175003175004175005175006175007175008175009175010175011175012175013175014175015175016175017175018175019175020175021175022175023175024175025175026175027175028175029175030175031175032175033175034175035175036175037175038175039175040175041175042175043175044175045175046175047175048175049175050175051175052175053175054175055175056175057175058175059175060175061175062175063175064175065175066175067175068175069175070175071175072175073175074175075175076175077175078175079175080175081175082175083175084175085175086175087175088175089175090175091175092175093175094175095175096175097175098175099175100175101175102175103175104175105175106175107175108175109175110175111175112175113175114175115175116175117175118175119175120175121175122175123175124175125175126175127175128175129175130175131175132175133175134175135175136175137175138175139175140175141175142175143175144175145175146175147175148175149175150175151175152175153175154175155175156175157175158175159175160175161175162175163175164175165175166175167175168175169175170175171175172175173175174175175175176175177175178175179175180175181175182175183175184175185175186175187175188175189175190175191175192175193175194175195175196175197175198175199175200175201175202175203175204175205175206175207175208175209175210175211175212175213175214175215175216175217175218175219175220175221175222175223175224175225175226175227175228175229175230175231175232175233175234175235175236175237175238175239175240175241175242175243175244175245175246175247175248175249175250175251175252175253175254175255175256175257175258175259175260175261175262175263175264175265175266175267175268175269175270175271175272175273175274175275175276175277175278175279175280175281175282175283175284175285175286175287175288175289175290175291175292175293175294175295175296175297175298175299175300175301175302175303175304175305175306175307175308175309175310175311175312175313175314175315175316175317175318175319175320175321175322175323175324175325175326175327175328175329175330175331175332175333175334175335175336175337175338175339175340175341175342175343175344175345175346175347175348175349175350175351175352175353175354175355175356175357175358175359175360175361175362175363175364175365175366175367175368175369175370175371175372175373175374175375175376175377175378175379175380175381175382175383175384175385175386175387175388175389175390175391175392175393175394175395175396175397175398175399175400175401175402175403175404175405175406175407175408175409175410175411175412175413175414175415175416175417175418175419175420175421175422175423175424175425175426175427175428175429175430175431175432175433175434175435175436175437175438175439175440175441175442175443175444175445175446175447175448175449175450175451175452175453175454175455175456175457175458175459175460175461175462175463175464175465175466175467175468175469175470175471175472175473175474175475175476175477175478175479175480175481175482175483175484175485175486175487175488175489175490175491175492175493175494175495175496175497175498175499175500175501175502175503175504175505175506175507175508175509175510175511175512175513175514175515175516175517175518175519175520175521175522175523175524175525175526175527175528175529175530175531175532175533175534175535175536175537175538175539175540175541175542175543175544175545175546175547175548175549175550175551175552175553175554175555175556175557175558175559175560175561175562175563175564175565175566175567175568175569175570175571175572175573175574175575175576175577175578175579175580175581175582175583175584175585175586175587175588175589175590175591175592175593175594175595175596175597175598175599175600175601175602175603175604175605175606175607175608175609175610175611175612175613175614175615175616175617175618175619175620175621175622175623175624175625175626175627175628175629175630175631175632175633175634175635175636175637175638175639175640175641175642175643175644175645175646175647175648175649175650175651175652175653175654175655175656175657175658175659175660175661175662175663175664175665175666175667175668175669175670175671175672175673175674175675175676175677175678175679175680175681175682175683175684175685175686175687175688175689175690175691175692175693175694175695175696175697175698175699175700175701175702175703175704175705175706175707175708175709175710175711175712175713175714175715175716175717175718175719175720175721175722175723175724175725175726175727175728175729175730175731175732175733175734175735175736175737175738175739175740175741175742175743175744175745175746175747175748175749175750175751175752175753175754175755175756175757175758175759175760175761175762175763175764175765175766175767175768175769175770175771175772175773175774175775175776175777175778175779175780175781175782175783175784175785175786175787175788175789175790175791175792175793175794175795175796175797175798175799175800175801175802175803175804175805175806175807175808175809175810175811175812175813175814175815175816175817175818175819175820175821175822175823175824175825175826175827175828175829175830175831175832175833175834175835175836175837175838175839175840175841175842175843175844175845175846175847175848175849175850175851175852175853175854175855175856175857175858175859175860175861175862175863175864175865175866175867175868175869175870175871175872175873175874175875175876175877175878175879175880175881175882175883175884175885175886175887175888175889175890175891175892175893175894175895175896175897175898175899175900175901175902175903175904175905175906175907175908175909175910175911175912175913175914175915175916175917175918175919175920175921175922175923175924175925175926175927175928175929175930175931175932175933175934175935175936175937175938175939175940175941175942175943175944175945175946175947175948175949175950175951175952175953175954175955175956175957175958175959175960175961175962175963175964175965175966175967175968175969175970175971175972175973175974175975175976175977175978175979175980175981175982175983175984175985175986175987175988175989175990175991175992175993175994175995175996175997175998175999176000176001176002176003176004176005176006176007176008176009176010176011176012176013176014176015176016176017176018176019176020176021176022176023176024176025176026176027176028176029176030176031176032176033176034176035176036176037176038176039176040176041176042176043176044176045176046176047176048176049176050176051176052176053176054176055176056176057176058176059176060176061176062176063176064176065176066176067176068176069176070176071176072176073176074176075176076176077176078176079176080176081176082176083176084176085176086176087176088176089176090176091176092176093176094176095176096176097176098176099176100176101176102176103176104176105176106176107176108176109176110176111176112176113176114176115176116176117176118176119176120176121176122176123176124176125176126176127176128176129176130176131176132176133176134176135176136176137176138176139176140176141176142176143176144176145176146176147176148176149176150176151176152176153176154176155176156176157176158176159176160176161176162176163176164176165176166176167176168176169176170176171176172176173176174176175176176176177176178176179176180176181176182176183176184176185176186176187176188176189176190176191176192176193176194176195176196176197176198176199176200176201176202176203176204176205176206176207176208176209176210176211176212176213176214176215176216176217176218176219176220176221176222176223176224176225176226176227176228176229176230176231176232176233176234176235176236176237176238176239176240176241176242176243176244176245176246176247176248176249176250176251176252176253176254176255176256176257176258176259176260176261176262176263176264176265176266176267176268176269176270176271176272176273176274176275176276176277176278176279176280176281176282176283176284176285176286176287176288176289176290176291176292176293176294176295176296176297176298176299176300176301176302176303176304176305176306176307176308176309176310176311176312176313176314176315176316176317176318176319176320176321176322176323176324176325176326176327176328176329176330176331176332176333176334176335176336176337176338176339176340176341176342176343176344176345176346176347176348176349176350176351176352176353176354176355176356176357176358176359176360176361176362176363176364176365176366176367176368176369176370176371176372176373176374176375176376176377176378176379176380176381176382176383176384176385176386176387176388176389176390176391176392176393176394176395176396176397176398176399176400176401176402176403176404176405176406176407176408176409176410176411176412176413176414176415176416176417176418176419176420176421176422176423176424176425176426176427176428176429176430176431176432176433176434176435176436176437176438176439176440176441176442176443176444176445176446176447176448176449176450176451176452176453176454176455176456176457176458176459176460176461176462176463176464176465176466176467176468176469176470176471176472176473176474176475176476176477176478176479176480176481176482176483176484176485176486176487176488176489176490176491176492176493176494176495176496176497176498176499176500176501176502176503176504176505176506176507176508176509176510176511176512176513176514176515176516176517176518176519176520176521176522176523176524176525176526176527176528176529176530176531176532176533176534176535176536176537176538176539176540176541176542176543176544176545176546176547176548176549176550176551176552176553176554176555176556176557176558176559176560176561176562176563176564176565176566176567176568176569176570176571176572176573176574176575176576176577176578176579176580176581176582176583176584176585176586176587176588176589176590176591176592176593176594176595176596176597176598176599176600176601176602176603176604176605176606176607176608176609176610176611176612176613176614176615176616176617176618176619176620176621176622176623176624176625176626176627176628176629176630176631176632176633176634176635176636176637176638176639176640176641176642176643176644176645176646176647176648176649176650176651176652176653176654176655176656176657176658176659176660176661176662176663176664176665176666176667176668176669176670176671176672176673176674176675176676176677176678176679176680176681176682176683176684176685176686176687176688176689176690176691176692176693176694176695176696176697176698176699176700176701176702176703176704176705176706176707176708176709176710176711176712176713176714176715176716176717176718176719176720176721176722176723176724176725176726176727176728176729176730176731176732176733176734176735176736176737176738176739176740176741176742176743176744176745176746176747176748176749176750176751176752176753176754176755176756176757176758176759176760176761176762176763176764176765176766176767176768176769176770176771176772176773176774176775176776176777176778176779176780176781176782176783176784176785176786176787176788176789176790176791176792176793176794176795176796176797176798176799176800176801176802176803176804176805176806176807176808176809176810176811176812176813176814176815176816176817176818176819176820176821176822176823176824176825176826176827176828176829176830176831176832176833176834176835176836176837176838176839176840176841176842176843176844176845176846176847176848176849176850176851176852176853176854176855176856176857176858176859176860176861176862176863176864176865176866176867176868176869176870176871176872176873176874176875176876176877176878176879176880176881176882176883176884176885176886176887176888176889176890176891176892176893176894176895176896176897176898176899176900176901176902176903176904176905176906176907176908176909176910176911176912176913176914176915176916176917176918176919176920176921176922176923176924176925176926176927176928176929176930176931176932176933176934176935176936176937176938176939176940176941176942176943176944176945176946176947176948176949176950176951176952176953176954176955176956176957176958176959176960176961176962176963176964176965176966176967176968176969176970176971176972176973176974176975176976176977176978176979176980176981176982176983176984176985176986176987176988176989176990176991176992176993176994176995176996176997176998176999177000177001177002177003177004177005177006177007177008177009177010177011177012177013177014177015177016177017177018177019177020177021177022177023177024177025177026177027177028177029177030177031177032177033177034177035177036177037177038177039177040177041177042177043177044177045177046177047177048177049177050177051177052177053177054177055177056177057177058177059177060177061177062177063177064177065177066177067177068177069177070177071177072177073177074177075177076177077177078177079177080177081177082177083177084177085177086177087177088177089177090177091177092177093177094177095177096177097177098177099177100177101177102177103177104177105177106177107177108177109177110177111177112177113177114177115177116177117177118177119177120177121177122177123177124177125177126177127177128177129177130177131177132177133177134177135177136177137177138177139177140177141177142177143177144177145177146177147177148177149177150177151177152177153177154177155177156177157177158177159177160177161177162177163177164177165177166177167177168177169177170177171177172177173177174177175177176177177177178177179177180177181177182177183177184177185177186177187177188177189177190177191177192177193177194177195177196177197177198177199177200177201177202177203177204177205177206177207177208177209177210177211177212177213177214177215177216177217177218177219177220177221177222177223177224177225177226177227177228177229177230177231177232177233177234177235177236177237177238177239177240177241177242177243177244177245177246177247177248177249177250177251177252177253177254177255177256177257177258177259177260177261177262177263177264177265177266177267177268177269177270177271177272177273177274177275177276177277177278177279177280177281177282177283177284177285177286177287177288177289177290177291177292177293177294177295177296177297177298177299177300177301177302177303177304177305177306177307177308177309177310177311177312177313177314177315177316177317177318177319177320177321177322177323177324177325177326177327177328177329177330177331177332177333177334177335177336177337177338177339177340177341177342177343177344177345177346177347177348177349177350177351177352177353177354177355177356177357177358177359177360177361177362177363177364177365177366177367177368177369177370177371177372177373177374177375177376177377177378177379177380177381177382177383177384177385177386177387177388177389177390177391177392177393177394177395177396177397177398177399177400177401177402177403177404177405177406177407177408177409177410177411177412177413177414177415177416177417177418177419177420177421177422177423177424177425177426177427177428177429177430177431177432177433177434177435177436177437177438177439177440177441177442177443177444177445177446177447177448177449177450177451177452177453177454177455177456177457177458177459177460177461177462177463177464177465177466177467177468177469177470177471177472177473177474177475177476177477177478177479177480177481177482177483177484177485177486177487177488177489177490177491177492177493177494177495177496177497177498177499177500177501177502177503177504177505177506177507177508177509177510177511177512177513177514177515177516177517177518177519177520177521177522177523177524177525177526177527177528177529177530177531177532177533177534177535177536177537177538177539177540177541177542177543177544177545177546177547177548177549177550177551177552177553177554177555177556177557177558177559177560177561177562177563177564177565177566177567177568177569177570177571177572177573177574177575177576177577177578177579177580177581177582177583177584177585177586177587177588177589177590177591177592177593177594177595177596177597177598177599177600177601177602177603177604177605177606177607177608177609177610177611177612177613177614177615177616177617177618177619177620177621177622177623177624177625177626177627177628177629177630177631177632177633177634177635177636177637177638177639177640177641177642177643177644177645177646177647177648177649177650177651177652177653177654177655177656177657177658177659177660177661177662177663177664177665177666177667177668177669177670177671177672177673177674177675177676177677177678177679177680177681177682177683177684177685177686177687177688177689177690177691177692177693177694177695177696177697177698177699177700177701177702177703177704177705177706177707177708177709177710177711177712177713177714177715177716177717177718177719177720177721177722177723177724177725177726177727177728177729177730177731177732177733177734177735177736177737177738177739177740177741177742177743177744177745177746177747177748177749177750177751177752177753177754177755177756177757177758177759177760177761177762177763177764177765177766177767177768177769177770177771177772177773177774177775177776177777177778177779177780177781177782177783177784177785177786177787177788177789177790177791177792177793177794177795177796177797177798177799177800177801177802177803177804177805177806177807177808177809177810177811177812177813177814177815177816177817177818177819177820177821177822177823177824177825177826177827177828177829177830177831177832177833177834177835177836177837177838177839177840177841177842177843177844177845177846177847177848177849177850177851177852177853177854177855177856177857177858177859177860177861177862177863177864177865177866177867177868177869177870177871177872177873177874177875177876177877177878177879177880177881177882177883177884177885177886177887177888177889177890177891177892177893177894177895177896177897177898177899177900177901177902177903177904177905177906177907177908177909177910177911177912177913177914177915177916177917177918177919177920177921177922177923177924177925177926177927177928177929177930177931177932177933177934177935177936177937177938177939177940177941177942177943177944177945177946177947177948177949177950177951177952177953177954177955177956177957177958177959177960177961177962177963177964177965177966177967177968177969177970177971177972177973177974177975177976177977177978177979177980177981177982177983177984177985177986177987177988177989177990177991177992177993177994177995177996177997177998177999178000178001178002178003178004178005178006178007178008178009178010178011178012178013178014178015178016178017178018178019178020178021178022178023178024178025178026178027178028178029178030178031178032178033178034178035178036178037178038178039178040178041178042178043178044178045178046178047178048178049178050178051178052178053178054178055178056178057178058178059178060178061178062178063178064178065178066178067178068178069178070178071178072178073178074178075178076178077178078178079178080178081178082178083178084178085178086178087178088178089178090178091178092178093178094178095178096178097178098178099178100178101178102178103178104178105178106178107178108178109178110178111178112178113178114178115178116178117178118178119178120178121178122178123178124178125178126178127178128178129178130178131178132178133178134178135178136178137178138178139178140178141178142178143178144178145178146178147178148178149178150178151178152178153178154178155178156178157178158178159178160178161178162178163178164178165178166178167178168178169178170178171178172178173178174178175178176178177178178178179178180178181178182178183178184178185178186178187178188178189178190178191178192178193178194178195178196178197178198178199178200178201178202178203178204178205178206178207178208178209178210178211178212178213178214178215178216178217178218178219178220178221178222178223178224178225178226178227178228178229178230178231178232178233178234178235178236178237178238178239178240178241178242178243178244178245178246178247178248178249178250178251178252178253178254178255178256178257178258178259178260178261178262178263178264178265178266178267178268178269178270178271178272178273178274178275178276178277178278178279178280178281178282178283178284178285178286178287178288178289178290178291178292178293178294178295178296178297178298178299178300178301178302178303178304178305178306178307178308178309178310178311178312178313178314178315178316178317178318178319178320178321178322178323178324178325178326178327178328178329178330178331178332178333178334178335178336178337178338178339178340178341178342178343178344178345178346178347178348178349178350178351178352178353178354178355178356178357178358178359178360178361178362178363178364178365178366178367178368178369178370178371178372178373178374178375178376178377178378178379178380178381178382178383178384178385178386178387178388178389178390178391178392178393178394178395178396178397178398178399178400178401178402178403178404178405178406178407178408178409178410178411178412178413178414178415178416178417178418178419178420178421178422178423178424178425178426178427178428178429178430178431178432178433178434178435178436178437178438178439178440178441178442178443178444178445178446178447178448178449178450178451178452178453178454178455178456178457178458178459178460178461178462178463178464178465178466178467178468178469178470178471178472178473178474178475178476178477178478178479178480178481178482178483178484178485178486178487178488178489178490178491178492178493178494178495178496178497178498178499178500178501178502178503178504178505178506178507178508178509178510178511178512178513178514178515178516178517178518178519178520178521178522178523178524178525178526178527178528178529178530178531178532178533178534178535178536178537178538178539178540178541178542178543178544178545178546178547178548178549178550178551178552178553178554178555178556178557178558178559178560178561178562178563178564178565178566178567178568178569178570178571178572178573178574178575178576178577178578178579178580178581178582178583178584178585178586178587178588178589178590178591178592178593178594178595178596178597178598178599178600178601178602178603178604178605178606178607178608178609178610178611178612178613178614178615178616178617178618178619178620178621178622178623178624178625178626178627178628178629178630178631178632178633178634178635178636178637178638178639178640178641178642178643178644178645178646178647178648178649178650178651178652178653178654178655178656178657178658178659178660178661178662178663178664178665178666178667178668178669178670178671178672178673178674178675178676178677178678178679178680178681178682178683178684178685178686178687178688178689178690178691178692178693178694178695178696178697178698178699178700178701178702178703178704178705178706178707178708178709178710178711178712178713178714178715178716178717178718178719178720178721178722178723178724178725178726178727178728178729178730178731178732178733178734178735178736178737178738178739178740178741178742178743178744178745178746178747178748178749178750178751178752178753178754178755178756178757178758178759178760178761178762178763178764178765178766178767178768178769178770178771178772178773178774178775178776178777178778178779178780178781178782178783178784178785178786178787178788178789178790178791178792178793178794178795178796178797178798178799178800178801178802178803178804178805178806178807178808178809178810178811178812178813178814178815178816178817178818178819178820178821178822178823178824178825178826178827178828178829178830178831178832178833178834178835178836178837178838178839178840178841178842178843178844178845178846178847178848178849178850178851178852178853178854178855178856178857178858178859178860178861178862178863178864178865178866178867178868178869178870178871178872178873178874178875178876178877178878178879178880178881178882178883178884178885178886178887178888178889178890178891178892178893178894178895178896178897178898178899178900178901178902178903178904178905178906178907178908178909178910178911178912178913178914178915178916178917178918178919178920178921178922178923178924178925178926178927178928178929178930178931178932178933178934178935178936178937178938178939178940178941178942178943178944178945178946178947178948178949178950178951178952178953178954178955178956178957178958178959178960178961178962178963178964178965178966178967178968178969178970178971178972178973178974178975178976178977178978178979178980178981178982178983178984178985178986178987178988178989178990178991178992178993178994178995178996178997178998178999179000179001179002179003179004179005179006179007179008179009179010179011179012179013179014179015179016179017179018179019179020179021179022179023179024179025179026179027179028179029179030179031179032179033179034179035179036179037179038179039179040179041179042179043179044179045179046179047179048179049179050179051179052179053179054179055179056179057179058179059179060179061179062179063179064179065179066179067179068179069179070179071179072179073179074179075179076179077179078179079179080179081179082179083179084179085179086179087179088179089179090179091179092179093179094179095179096179097179098179099179100179101179102179103179104179105179106179107179108179109179110179111179112179113179114179115179116179117179118179119179120179121179122179123179124179125179126179127179128179129179130179131179132179133179134179135179136179137179138179139179140179141179142179143179144179145179146179147179148179149179150179151179152179153179154179155179156179157179158179159179160179161179162179163179164179165179166179167179168179169179170179171179172179173179174179175179176179177179178179179179180179181179182179183179184179185179186179187179188179189179190179191179192179193179194179195179196179197179198179199179200179201179202179203179204179205179206179207179208179209179210179211179212179213179214179215179216179217179218179219179220179221179222179223179224179225179226179227179228179229179230179231179232179233179234179235179236179237179238179239179240179241179242179243179244179245179246179247179248179249179250179251179252179253179254179255179256179257179258179259179260179261179262179263179264179265179266179267179268179269179270179271179272179273179274179275179276179277179278179279179280179281179282179283179284179285179286179287179288179289179290179291179292179293179294179295179296179297179298179299179300179301179302179303179304179305179306179307179308179309179310179311179312179313179314179315179316179317179318179319179320179321179322179323179324179325179326179327179328179329179330179331179332179333179334179335179336179337179338179339179340179341179342179343179344179345179346179347179348179349179350179351179352179353179354179355179356179357179358179359179360179361179362179363179364179365179366179367179368179369179370179371179372179373179374179375179376179377179378179379179380179381179382179383179384179385179386179387179388179389179390179391179392179393179394179395179396179397179398179399179400179401179402179403179404179405179406179407179408179409179410179411179412179413179414179415179416179417179418179419179420179421179422179423179424179425179426179427179428179429179430179431179432179433179434179435179436179437179438179439179440179441179442179443179444179445179446179447179448179449179450179451179452179453179454179455179456179457179458179459179460179461179462179463179464179465179466179467179468179469179470179471179472179473179474179475179476179477179478179479179480179481179482179483179484179485179486179487179488179489179490179491179492179493179494179495179496179497179498179499179500179501179502179503179504179505179506179507179508179509179510179511179512179513179514179515179516179517179518179519179520179521179522179523179524179525179526179527179528179529179530179531179532179533179534179535179536179537179538179539179540179541179542179543179544179545179546179547179548179549179550179551179552179553179554179555179556179557179558179559179560179561179562179563179564179565179566179567179568179569179570179571179572179573179574179575179576179577179578179579179580179581179582179583179584179585179586179587179588179589179590179591179592179593179594179595179596179597179598179599179600179601179602179603179604179605179606179607179608179609179610179611179612179613179614179615179616179617179618179619179620179621179622179623179624179625179626179627179628179629179630179631179632179633179634179635179636179637179638179639179640179641179642179643179644179645179646179647179648179649179650179651179652179653179654179655179656179657179658179659179660179661179662179663179664179665179666179667179668179669179670179671179672179673179674179675179676179677179678179679179680179681179682179683179684179685179686179687179688179689179690179691179692179693179694179695179696179697179698179699179700179701179702179703179704179705179706179707179708179709179710179711179712179713179714179715179716179717179718179719179720179721179722179723179724179725179726179727179728179729179730179731179732179733179734179735179736179737179738179739179740179741179742179743179744179745179746179747179748179749179750179751179752179753179754179755179756179757179758179759179760179761179762179763179764179765179766179767179768179769179770179771179772179773179774179775179776179777179778179779179780179781179782179783179784179785179786179787179788179789179790179791179792179793179794179795179796179797179798179799179800179801179802179803179804179805179806179807179808179809179810179811179812179813179814179815179816179817179818179819179820179821179822179823179824179825179826179827179828179829179830179831179832179833179834179835179836179837179838179839179840179841179842179843179844179845179846179847179848179849179850179851179852179853179854179855179856179857179858179859179860179861179862179863179864179865179866179867179868179869179870179871179872179873179874179875179876179877179878179879179880179881179882179883179884179885179886179887179888179889179890179891179892179893179894179895179896179897179898179899179900179901179902179903179904179905179906179907179908179909179910179911179912179913179914179915179916179917179918179919179920179921179922179923179924179925179926179927179928179929179930179931179932179933179934179935179936179937179938179939179940179941179942179943179944179945179946179947179948179949179950179951179952179953179954179955179956179957179958179959179960179961179962179963179964179965179966179967179968179969179970179971179972179973179974179975179976179977179978179979179980179981179982179983179984179985179986179987179988179989179990179991179992179993179994179995179996179997179998179999180000180001180002180003180004180005180006180007180008180009180010180011180012180013180014180015180016180017180018180019180020180021180022180023180024180025180026180027180028180029180030180031180032180033180034180035180036180037180038180039180040180041180042180043180044180045180046180047180048180049180050180051180052180053180054180055180056180057180058180059180060180061180062180063180064180065180066180067180068180069180070180071180072180073180074180075180076180077180078180079180080180081180082180083180084180085180086180087180088180089180090180091180092180093180094180095180096180097180098180099180100180101180102180103180104180105180106180107180108180109180110180111180112180113180114180115180116180117180118180119180120180121180122180123180124180125180126180127180128180129180130180131180132180133180134180135180136180137180138180139180140180141180142180143180144180145180146180147180148180149180150180151180152180153180154180155180156180157180158180159180160180161180162180163180164180165180166180167180168180169180170180171180172180173180174180175180176180177180178180179180180180181180182180183180184180185180186180187180188180189180190180191180192180193180194180195180196180197180198180199180200180201180202180203180204180205180206180207180208180209180210180211180212180213180214180215180216180217180218180219180220180221180222180223180224180225180226180227180228180229180230180231180232180233180234180235180236180237180238180239180240180241180242180243180244180245180246180247180248180249180250180251180252180253180254180255180256180257180258180259180260180261180262180263180264180265180266180267180268180269180270180271180272180273180274180275180276180277180278180279180280180281180282180283180284180285180286180287180288180289180290180291180292180293180294180295180296180297180298180299180300180301180302180303180304180305180306180307180308180309180310180311180312180313180314180315180316180317180318180319180320180321180322180323180324180325180326180327180328180329180330180331180332180333180334180335180336180337180338180339180340180341180342180343180344180345180346180347180348180349180350180351180352180353180354180355180356180357180358180359180360180361180362180363180364180365180366180367180368180369180370180371180372180373180374180375180376180377180378180379180380180381180382180383180384180385180386180387180388180389180390180391180392180393180394180395180396180397180398180399180400180401180402180403180404180405180406180407180408180409180410180411180412180413180414180415180416180417180418180419180420180421180422180423180424180425180426180427180428180429180430180431180432180433180434180435180436180437180438180439180440180441180442180443180444180445180446180447180448180449180450180451180452180453180454180455180456180457180458180459180460180461180462180463180464180465180466180467180468180469180470180471180472180473180474180475180476180477180478180479180480180481180482180483180484180485180486180487180488180489180490180491180492180493180494180495180496180497180498180499180500180501180502180503180504180505180506180507180508180509180510180511180512180513180514180515180516180517180518180519180520180521180522180523180524180525180526180527180528180529180530180531180532180533180534180535180536180537180538180539180540180541180542180543180544180545180546180547180548180549180550180551180552180553180554180555180556180557180558180559180560180561180562180563180564180565180566180567180568180569180570180571180572180573180574180575180576180577180578180579180580180581180582180583180584180585180586180587180588180589180590180591180592180593180594180595180596180597180598180599180600180601180602180603180604180605180606180607180608180609180610180611180612180613180614180615180616180617180618180619180620180621180622180623180624180625180626180627180628180629180630180631180632180633180634180635180636180637180638180639180640180641180642180643180644180645180646180647180648180649180650180651180652180653180654180655180656180657180658180659180660180661180662180663180664180665180666180667180668180669180670180671180672180673180674180675180676180677180678180679180680180681180682180683180684180685180686180687180688180689180690180691180692180693180694180695180696180697180698180699180700180701180702180703180704180705180706180707180708180709180710180711180712180713180714180715180716180717180718180719180720180721180722180723180724180725180726180727180728180729180730180731180732180733180734180735180736180737180738180739180740180741180742180743180744180745180746180747180748180749180750180751180752180753180754180755180756180757180758180759180760180761180762180763180764180765180766180767180768180769180770180771180772180773180774180775180776180777180778180779180780180781180782180783180784180785180786180787180788180789180790180791180792180793180794180795180796180797180798180799180800180801180802180803180804180805180806180807180808180809180810180811180812180813180814180815180816180817180818180819180820180821180822180823180824180825180826180827180828180829180830180831180832180833180834180835180836180837180838180839180840180841180842180843180844180845180846180847180848180849180850180851180852180853180854180855180856180857180858180859180860180861180862180863180864180865180866180867180868180869180870180871180872180873180874180875180876180877180878180879180880180881180882180883180884180885180886180887180888180889180890180891180892180893180894180895180896180897180898180899180900180901180902180903180904180905180906180907180908180909180910180911180912180913180914180915180916180917180918180919180920180921180922180923180924180925180926180927180928180929180930180931180932180933180934180935180936180937180938180939180940180941180942180943180944180945180946180947180948180949180950180951180952180953180954180955180956180957180958180959180960180961180962180963180964180965180966180967180968180969180970180971180972180973180974180975180976180977180978180979180980180981180982180983180984180985180986180987180988180989180990180991180992180993180994180995180996180997180998180999181000181001181002181003181004181005181006181007181008181009181010181011181012181013181014181015181016181017181018181019181020181021181022181023181024181025181026181027181028181029181030181031181032181033181034181035181036181037181038181039181040181041181042181043181044181045181046181047181048181049181050181051181052181053181054181055181056181057181058181059181060181061181062181063181064181065181066181067181068181069181070181071181072181073181074181075181076181077181078181079181080181081181082181083181084181085181086181087181088181089181090181091181092181093181094181095181096181097181098181099181100181101181102181103181104181105181106181107181108181109181110181111181112181113181114181115181116181117181118181119181120181121181122181123181124181125181126181127181128181129181130181131181132181133181134181135181136181137181138181139181140181141181142181143181144181145181146181147181148181149181150181151181152181153181154181155181156181157181158181159181160181161181162181163181164181165181166181167181168181169181170181171181172181173181174181175181176181177181178181179181180181181181182181183181184181185181186181187181188181189181190181191181192181193181194181195181196181197181198181199181200181201181202181203181204181205181206181207181208181209181210181211181212181213181214181215181216181217181218181219181220181221181222181223181224181225181226181227181228181229181230181231181232181233181234181235181236181237181238181239181240181241181242181243181244181245181246181247181248181249181250181251181252181253181254181255181256181257181258181259181260181261181262181263181264181265181266181267181268181269181270181271181272181273181274181275181276181277181278181279181280181281181282181283181284181285181286181287181288181289181290181291181292181293181294181295181296181297181298181299181300181301181302181303181304181305181306181307181308181309181310181311181312181313181314181315181316181317181318181319181320181321181322181323181324181325181326181327181328181329181330181331181332181333181334181335181336181337181338181339181340181341181342181343181344181345181346181347181348181349181350181351181352181353181354181355181356181357181358181359181360181361181362181363181364181365181366181367181368181369181370181371181372181373181374181375181376181377181378181379181380181381181382181383181384181385181386181387181388181389181390181391181392181393181394181395181396181397181398181399181400181401181402181403181404181405181406181407181408181409181410181411181412181413181414181415181416181417181418181419181420181421181422181423181424181425181426181427181428181429181430181431181432181433181434181435181436181437181438181439181440181441181442181443181444181445181446181447181448181449181450181451181452181453181454181455181456181457181458181459181460181461181462181463181464181465181466181467181468181469181470181471181472181473181474181475181476181477181478181479181480181481181482181483181484181485181486181487181488181489181490181491181492181493181494181495181496181497181498181499181500181501181502181503181504181505181506181507181508181509181510181511181512181513181514181515181516181517181518181519181520181521181522181523181524181525181526181527181528181529181530181531181532181533181534181535181536181537181538181539181540181541181542181543181544181545181546181547181548181549181550181551181552181553181554181555181556181557181558181559181560181561181562181563181564181565181566181567181568181569181570181571181572181573181574181575181576181577181578181579181580181581181582181583181584181585181586181587181588181589181590181591181592181593181594181595181596181597181598181599181600181601181602181603181604181605181606181607181608181609181610181611181612181613181614181615181616181617181618181619181620181621181622181623181624181625181626181627181628181629181630181631181632181633181634181635181636181637181638181639181640181641181642181643181644181645181646181647181648181649181650181651181652181653181654181655181656181657181658181659181660181661181662181663181664181665181666181667181668181669181670181671181672181673181674181675181676181677181678181679181680181681181682181683181684181685181686181687181688181689181690181691181692181693181694181695181696181697181698181699181700181701181702181703181704181705181706181707181708181709181710181711181712181713181714181715181716181717181718181719181720181721181722181723181724181725181726181727181728181729181730181731181732181733181734181735181736181737181738181739181740181741181742181743181744181745181746181747181748181749181750181751181752181753181754181755181756181757181758181759181760181761181762181763181764181765181766181767181768181769181770181771181772181773181774181775181776181777181778181779181780181781181782181783181784181785181786181787181788181789181790181791181792181793181794181795181796181797181798181799181800181801181802181803181804181805181806181807181808181809181810181811181812181813181814181815181816181817181818181819181820181821181822181823181824181825181826181827181828181829181830181831181832181833181834181835181836181837181838181839181840181841181842181843181844181845181846181847181848181849181850181851181852181853181854181855181856181857181858181859181860181861181862181863181864181865181866181867181868181869181870181871181872181873181874181875181876181877181878181879181880181881181882181883181884181885181886181887181888181889181890181891181892181893181894181895181896181897181898181899181900181901181902181903181904181905181906181907181908181909181910181911181912181913181914181915181916181917181918181919181920181921181922181923181924181925181926181927181928181929181930181931181932181933181934181935181936181937181938181939181940181941181942181943181944181945181946181947181948181949181950181951181952181953181954181955181956181957181958181959181960181961181962181963181964181965181966181967181968181969181970181971181972181973181974181975181976181977181978181979181980181981181982181983181984181985181986181987181988181989181990181991181992181993181994181995181996181997181998181999182000182001182002182003182004182005182006182007182008182009182010182011182012182013182014182015182016182017182018182019182020182021182022182023182024182025182026182027182028182029182030182031182032182033182034182035182036182037182038182039182040182041182042182043182044182045182046182047182048182049182050182051182052182053182054182055182056182057182058182059182060182061182062182063182064182065182066182067182068182069182070182071182072182073182074182075182076182077182078182079182080182081182082182083182084182085182086182087182088182089182090182091182092182093182094182095182096182097182098182099182100182101182102182103182104182105182106182107182108182109182110182111182112182113182114182115182116182117182118182119182120182121182122182123182124182125182126182127182128182129182130182131182132182133182134182135182136182137182138182139182140182141182142182143182144182145182146182147182148182149182150182151182152182153182154182155182156182157182158182159182160182161182162182163182164182165182166182167182168182169182170182171182172182173182174182175182176182177182178182179182180182181182182182183182184182185182186182187182188182189182190182191182192182193182194182195182196182197182198182199182200182201182202182203182204182205182206182207182208182209182210182211182212182213182214182215182216182217182218182219182220182221182222182223182224182225182226182227182228182229182230182231182232182233182234182235182236182237182238182239182240182241182242182243182244182245182246182247182248182249182250182251182252182253182254182255182256182257182258182259182260182261182262182263182264182265182266182267182268182269182270182271182272182273182274182275182276182277182278182279182280182281182282182283182284182285182286182287182288182289182290182291182292182293182294182295182296182297182298182299182300182301182302182303182304182305182306182307182308182309182310182311182312182313182314182315182316182317182318182319182320182321182322182323182324182325182326182327182328182329182330182331182332182333182334182335182336182337182338182339182340182341182342182343182344182345182346182347182348182349182350182351182352182353182354182355182356182357182358182359182360182361182362182363182364182365182366182367182368182369182370182371182372182373182374182375182376182377182378182379182380182381182382182383182384182385182386182387182388182389182390182391182392182393182394182395182396182397182398182399182400182401182402182403182404182405182406182407182408182409182410182411182412182413182414182415182416182417182418182419182420182421182422182423182424182425182426182427182428182429182430182431182432182433182434182435182436182437182438182439182440182441182442182443182444182445182446182447182448182449182450182451182452182453182454182455182456182457182458182459182460182461182462182463182464182465182466182467182468182469182470182471182472182473182474182475182476182477182478182479182480182481182482182483182484182485182486182487182488182489182490182491182492182493182494182495182496182497182498182499182500182501182502182503182504182505182506182507182508182509182510182511182512182513182514182515182516182517182518182519182520182521182522182523182524182525182526182527182528182529182530182531182532182533182534182535182536182537182538182539182540182541182542182543182544182545182546182547182548182549182550182551182552182553182554182555182556182557182558182559182560182561182562182563182564182565182566182567182568182569182570182571182572182573182574182575182576182577182578182579182580182581182582182583182584182585182586182587182588182589182590182591182592182593182594182595182596182597182598182599182600182601182602182603182604182605182606182607182608182609182610182611182612182613182614182615182616182617182618182619182620182621182622182623182624182625182626182627182628182629182630182631182632182633182634182635182636182637182638182639182640182641182642182643182644182645182646182647182648182649182650182651182652182653182654182655182656182657182658182659182660182661182662182663182664182665182666182667182668182669182670182671182672182673182674182675182676182677182678182679182680182681182682182683182684182685182686182687182688182689182690182691182692182693182694182695182696182697182698182699182700182701182702182703182704182705182706182707182708182709182710182711182712182713182714182715182716182717182718182719182720182721182722182723182724182725182726182727182728182729182730182731182732182733182734182735182736182737182738182739182740182741182742182743182744182745182746182747182748182749182750182751182752182753182754182755182756182757182758182759182760182761182762182763182764182765182766182767182768182769182770182771182772182773182774182775182776182777182778182779182780182781182782182783182784182785182786182787182788182789182790182791182792182793182794182795182796182797182798182799182800182801182802182803182804182805182806182807182808182809182810182811182812182813182814182815182816182817182818182819182820182821182822182823182824182825182826182827182828182829182830182831182832182833182834182835182836182837182838182839182840182841182842182843182844182845182846182847182848182849182850182851182852182853182854182855182856182857182858182859182860182861182862182863182864182865182866182867182868182869182870182871182872182873182874182875182876182877182878182879182880182881182882182883182884182885182886182887182888182889182890182891182892182893182894182895182896182897182898182899182900182901182902182903182904182905182906182907182908182909182910182911182912182913182914182915182916182917182918182919182920182921182922182923182924182925182926182927182928182929182930182931182932182933182934182935182936182937182938182939182940182941182942182943182944182945182946182947182948182949182950182951182952182953182954182955182956182957182958182959182960182961182962182963182964182965182966182967182968182969182970182971182972182973182974182975182976182977182978182979182980182981182982182983182984182985182986182987182988182989182990182991182992182993182994182995182996182997182998182999183000183001183002183003183004183005183006183007183008183009183010183011183012183013183014183015183016183017183018183019183020183021183022183023183024183025183026183027183028183029183030183031183032183033183034183035183036183037183038183039183040183041183042183043183044183045183046183047183048183049183050183051183052183053183054183055183056183057183058183059183060183061183062183063183064183065183066183067183068183069183070183071183072183073183074183075183076183077183078183079183080183081183082183083183084183085183086183087183088183089183090183091183092183093183094183095183096183097183098183099183100183101183102183103183104183105183106183107183108183109183110183111183112183113183114183115183116183117183118183119183120183121183122183123183124183125183126183127183128183129183130183131183132183133183134183135183136183137183138183139183140183141183142183143183144183145183146183147183148183149183150183151183152183153183154183155183156183157183158183159183160183161183162183163183164183165183166183167183168183169183170183171183172183173183174183175183176183177183178183179183180183181183182183183183184183185183186183187183188183189183190183191183192183193183194183195183196183197183198183199183200183201183202183203183204183205183206183207183208183209183210183211183212183213183214183215183216183217183218183219183220183221183222183223183224183225183226183227183228183229183230183231183232183233183234183235183236183237183238183239183240183241183242183243183244183245183246183247183248183249183250183251183252183253183254183255183256183257183258183259183260183261183262183263183264183265183266183267183268183269183270183271183272183273183274183275183276183277183278183279183280183281183282183283183284183285183286183287183288183289183290183291183292183293183294183295183296183297183298183299183300183301183302183303183304183305183306183307183308183309183310183311183312183313183314183315183316183317183318183319183320183321183322183323183324183325183326183327183328183329183330183331183332183333183334183335183336183337183338183339183340183341183342183343183344183345183346183347183348183349183350183351183352183353183354183355183356183357183358183359183360183361183362183363183364183365183366183367183368183369183370183371183372183373183374183375183376183377183378183379183380183381183382183383183384183385183386183387183388183389183390183391183392183393183394183395183396183397183398183399183400183401183402183403183404183405183406183407183408183409183410183411183412183413183414183415183416183417183418183419183420183421183422183423183424183425183426183427183428183429183430183431183432183433183434183435183436183437183438183439183440183441183442183443183444183445183446183447183448183449183450183451183452183453183454183455183456183457183458183459183460183461183462183463183464183465183466183467183468183469183470183471183472183473183474183475183476183477183478183479183480183481183482183483183484183485183486183487183488183489183490183491183492183493183494183495183496183497183498183499183500183501183502183503183504183505183506183507183508183509183510183511183512183513183514183515183516183517183518183519183520183521183522183523183524183525183526183527183528183529183530183531183532183533183534183535183536183537183538183539183540183541183542183543183544183545183546183547183548183549183550183551183552183553183554183555183556183557183558183559183560183561183562183563183564183565183566183567183568183569183570183571183572183573183574183575183576183577183578183579183580183581183582183583183584183585183586183587183588183589183590183591183592183593183594183595183596183597183598183599183600183601183602183603183604183605183606183607183608183609183610183611183612183613183614183615183616183617183618183619183620183621183622183623183624183625183626183627183628183629183630183631183632183633183634183635183636183637183638183639183640183641183642183643183644183645183646183647183648183649183650183651183652183653183654183655183656183657183658183659183660183661183662183663183664183665183666183667183668183669183670183671183672183673183674183675183676183677183678183679183680183681183682183683183684183685183686183687183688183689183690183691183692183693183694183695183696183697183698183699183700183701183702183703183704183705183706183707183708183709183710183711183712183713183714183715183716183717183718183719183720183721183722183723183724183725183726183727183728183729183730183731183732183733183734183735183736183737183738183739183740183741183742183743183744183745183746183747183748183749183750183751183752183753183754183755183756183757183758183759183760183761183762183763183764183765183766183767183768183769183770183771183772183773183774183775183776183777183778183779183780183781183782183783183784183785183786183787183788183789183790183791183792183793183794183795183796183797183798183799183800183801183802183803183804183805183806183807183808183809183810183811183812183813183814183815183816183817183818183819183820183821183822183823183824183825183826183827183828183829183830183831183832183833183834183835183836183837183838183839183840183841183842183843183844183845183846183847183848183849183850183851183852183853183854183855183856183857183858183859183860183861183862183863183864183865183866183867183868183869183870183871183872183873183874183875183876183877183878183879183880183881183882183883183884183885183886183887183888183889183890183891183892183893183894183895183896183897183898183899183900183901183902183903183904183905183906183907183908183909183910183911183912183913183914183915183916183917183918183919183920183921183922183923183924183925183926183927183928183929183930183931183932183933183934183935183936183937183938183939183940183941183942183943183944183945183946183947183948183949183950183951183952183953183954183955183956183957183958183959183960183961183962183963183964183965183966183967183968183969183970183971183972183973183974183975183976183977183978183979183980183981183982183983183984183985183986183987183988183989183990183991183992183993183994183995183996183997183998183999184000184001184002184003184004184005184006184007184008184009184010184011184012184013184014184015184016184017184018184019184020184021184022184023184024184025184026184027184028184029184030184031184032184033184034184035184036184037184038184039184040184041184042184043184044184045184046184047184048184049184050184051184052184053184054184055184056184057184058184059184060184061184062184063184064184065184066184067184068184069184070184071184072184073184074184075184076184077184078184079184080184081184082184083184084184085184086184087184088184089184090184091184092184093184094184095184096184097184098184099184100184101184102184103184104184105184106184107184108184109184110184111184112184113184114184115184116184117184118184119184120184121184122184123184124184125184126184127184128184129184130184131184132184133184134184135184136184137184138184139184140184141184142184143184144184145184146184147184148184149184150184151184152184153184154184155184156184157184158184159184160184161184162184163184164184165184166184167184168184169184170184171184172184173184174184175184176184177184178184179184180184181184182184183184184184185184186184187184188184189184190184191184192184193184194184195184196184197184198184199184200184201184202184203184204184205184206184207184208184209184210184211184212184213184214184215184216184217184218184219184220184221184222184223184224184225184226184227184228184229184230184231184232184233184234184235184236184237184238184239184240184241184242184243184244184245184246184247184248184249184250184251184252184253184254184255184256184257184258184259184260184261184262184263184264184265184266184267184268184269184270184271184272184273184274184275184276184277184278184279184280184281184282184283184284184285184286184287184288184289184290184291184292184293184294184295184296184297184298184299184300184301184302184303184304184305184306184307184308184309184310184311184312184313184314184315184316184317184318184319184320184321184322184323184324184325184326184327184328184329184330184331184332184333184334184335184336184337184338184339184340184341184342184343184344184345184346184347184348184349184350184351184352184353184354184355184356184357184358184359184360184361184362184363184364184365184366184367184368184369184370184371184372184373184374184375184376184377184378184379184380184381184382184383184384184385184386184387184388184389184390184391184392184393184394184395184396184397184398184399184400184401184402184403184404184405184406184407184408184409184410184411184412184413184414184415184416184417184418184419184420184421184422184423184424184425184426184427184428184429184430184431184432184433184434184435184436184437184438184439184440184441184442184443184444184445184446184447184448184449184450184451184452184453184454184455184456184457184458184459184460184461184462184463184464184465184466184467184468184469184470184471184472184473184474184475184476184477184478184479184480184481184482184483184484184485184486184487184488184489184490184491184492184493184494184495184496184497184498184499184500184501184502184503184504184505184506184507184508184509184510184511184512184513184514184515184516184517184518184519184520184521184522184523184524184525184526184527184528184529184530184531184532184533184534184535184536184537184538184539184540184541184542184543184544184545184546184547184548184549184550184551184552184553184554184555184556184557184558184559184560184561184562184563184564184565184566184567184568184569184570184571184572184573184574184575184576184577184578184579184580184581184582184583184584184585184586184587184588184589184590184591184592184593184594184595184596184597184598184599184600184601184602184603184604184605184606184607184608184609184610184611184612184613184614184615184616184617184618184619184620184621184622184623184624184625184626184627184628184629184630184631184632184633184634184635184636184637184638184639184640184641184642184643184644184645184646184647184648184649184650184651184652184653184654184655184656184657184658184659184660184661184662184663184664184665184666184667184668184669184670184671184672184673184674184675184676184677184678184679184680184681184682184683184684184685184686184687184688184689184690184691184692184693184694184695184696184697184698184699184700184701184702184703184704184705184706184707184708184709184710184711184712184713184714184715184716184717184718184719184720184721184722184723184724184725184726184727184728184729184730184731184732184733184734184735184736184737184738184739184740184741184742184743184744184745184746184747184748184749184750184751184752184753184754184755184756184757184758184759184760184761184762184763184764184765184766184767184768184769184770184771184772184773184774184775184776184777184778184779184780184781184782184783184784184785184786184787184788184789184790184791184792184793184794184795184796184797184798184799184800184801184802184803184804184805184806184807184808184809184810184811184812184813184814184815184816184817184818184819184820184821184822184823184824184825184826184827184828184829184830184831184832184833184834184835184836184837184838184839184840184841184842184843184844184845184846184847184848184849184850184851184852184853184854184855184856184857184858184859184860184861184862184863184864184865184866184867184868184869184870184871184872184873184874184875184876184877184878184879184880184881184882184883184884184885184886184887184888184889184890184891184892184893184894184895184896184897184898184899184900184901184902184903184904184905184906184907184908184909184910184911184912184913184914184915184916184917184918184919184920184921184922184923184924184925184926184927184928184929184930184931184932184933184934184935184936184937184938184939184940184941184942184943184944184945184946184947184948184949184950184951184952184953184954184955184956184957184958184959184960184961184962184963184964184965184966184967184968184969184970184971184972184973184974184975184976184977184978184979184980184981184982184983184984184985184986184987184988184989184990184991184992184993184994184995184996184997184998184999185000185001185002185003185004185005185006185007185008185009185010185011185012185013185014185015185016185017185018185019185020185021185022185023185024185025185026185027185028185029185030185031185032185033185034185035185036185037185038185039185040185041185042185043185044185045185046185047185048185049185050185051185052185053185054185055185056185057185058185059185060185061185062185063185064185065185066185067185068185069185070185071185072185073185074185075185076185077185078185079185080185081185082185083185084185085185086185087185088185089185090185091185092185093185094185095185096185097185098185099185100185101185102185103185104185105185106185107185108185109185110185111185112185113185114185115185116185117185118185119185120185121185122185123185124185125185126185127185128185129185130185131185132185133185134185135185136185137185138185139185140185141185142185143185144185145185146185147185148185149185150185151185152185153185154185155185156185157185158185159185160185161185162185163185164185165185166185167185168185169185170185171185172185173185174185175185176185177185178185179185180185181185182185183185184185185185186185187185188185189185190185191185192185193185194185195185196185197185198185199185200185201185202185203185204185205185206185207185208185209185210185211185212185213185214185215185216185217185218185219185220185221185222185223185224185225185226185227185228185229185230185231185232185233185234185235185236185237185238185239185240185241185242185243185244185245185246185247185248185249185250185251185252185253185254185255185256185257185258185259185260185261185262185263185264185265185266185267185268185269185270185271185272185273185274185275185276185277185278185279185280185281185282185283185284185285185286185287185288185289185290185291185292185293185294185295185296185297185298185299185300185301185302185303185304185305185306185307185308185309185310185311185312185313185314185315185316185317185318185319185320185321185322185323185324185325185326185327185328185329185330185331185332185333185334185335185336185337185338185339185340185341185342185343185344185345185346185347185348185349185350185351185352185353185354185355185356185357185358185359185360185361185362185363185364185365185366185367185368185369185370185371185372185373185374185375185376185377185378185379185380185381185382185383185384185385185386185387185388185389185390185391185392185393185394185395185396185397185398185399185400185401185402185403185404185405185406185407185408185409185410185411185412185413185414185415185416185417185418185419185420185421185422185423185424185425185426185427185428185429185430185431185432185433185434185435185436185437185438185439185440185441185442185443185444185445185446185447185448185449185450185451185452185453185454185455185456185457185458185459185460185461185462185463185464185465185466185467185468185469185470185471185472185473185474185475185476185477185478185479185480185481185482185483185484185485185486185487185488185489185490185491185492185493185494185495185496185497185498185499185500185501185502185503185504185505185506185507185508185509185510185511185512185513185514185515185516185517185518185519185520185521185522185523185524185525185526185527185528185529185530185531185532185533185534185535185536185537185538185539185540185541185542185543185544185545185546185547185548185549185550185551185552185553185554185555185556185557185558185559185560185561185562185563185564185565185566185567185568185569185570185571185572185573185574185575185576185577185578185579185580185581185582185583185584185585185586185587185588185589185590185591185592185593185594185595185596185597185598185599185600185601185602185603185604185605185606185607185608185609185610185611185612185613185614185615185616185617185618185619185620185621185622185623185624185625185626185627185628185629185630185631185632185633185634185635185636185637185638185639185640185641185642185643185644185645185646185647185648185649185650185651185652185653185654185655185656185657185658185659185660185661185662185663185664185665185666185667185668185669185670185671185672185673185674185675185676185677185678185679185680185681185682185683185684185685185686185687185688185689185690185691185692185693185694185695185696185697185698185699185700185701185702185703185704185705185706185707185708185709185710185711185712185713185714185715185716185717185718185719185720185721185722185723185724185725185726185727185728185729185730185731185732185733185734185735185736185737185738185739185740185741185742185743185744185745185746185747185748185749185750185751185752185753185754185755185756185757185758185759185760185761185762185763185764185765185766185767185768185769185770185771185772185773185774185775185776185777185778185779185780185781185782185783185784185785185786185787185788185789185790185791185792185793185794185795185796185797185798185799185800185801185802185803185804185805185806185807185808185809185810185811185812185813185814185815185816185817185818185819185820185821185822185823185824185825185826185827185828185829185830185831185832185833185834185835185836185837185838185839185840185841185842185843185844185845185846185847185848185849185850185851185852185853185854185855185856185857185858185859185860185861185862185863185864185865185866185867185868185869185870185871185872185873185874185875185876185877185878185879185880185881185882185883185884185885185886185887185888185889185890185891185892185893185894185895185896185897185898185899185900185901185902185903185904185905185906185907185908185909185910185911185912185913185914185915185916185917185918185919185920185921185922185923185924185925185926185927185928185929185930185931185932185933185934185935185936185937185938185939185940185941185942185943185944185945185946185947185948185949185950185951185952185953185954185955185956185957185958185959185960185961185962185963185964185965185966185967185968185969185970185971185972185973185974185975185976185977185978185979185980185981185982185983185984185985185986185987185988185989185990185991185992185993185994185995185996185997185998185999186000186001186002186003186004186005186006186007186008186009186010186011186012186013186014186015186016186017186018186019186020186021186022186023186024186025186026186027186028186029186030186031186032186033186034186035186036186037186038186039186040186041186042186043186044186045186046186047186048186049186050186051186052186053186054186055186056186057186058186059186060186061186062186063186064186065186066186067186068186069186070186071186072186073186074186075186076186077186078186079186080186081186082186083186084186085186086186087186088186089186090186091186092186093186094186095186096186097186098186099186100186101186102186103186104186105186106186107186108186109186110186111186112186113186114186115186116186117186118186119186120186121186122186123186124186125186126186127186128186129186130186131186132186133186134186135186136186137186138186139186140186141186142186143186144186145186146186147186148186149186150186151186152186153186154186155186156186157186158186159186160186161186162186163186164186165186166186167186168186169186170186171186172186173186174186175186176186177186178186179186180186181186182186183186184186185186186186187186188186189186190186191186192186193186194186195186196186197186198186199186200186201186202186203186204186205186206186207186208186209186210186211186212186213186214186215186216186217186218186219186220186221186222186223186224186225186226186227186228186229186230186231186232186233186234186235186236186237186238186239186240186241186242186243186244186245186246186247186248186249186250186251186252186253186254186255186256186257186258186259186260186261186262186263186264186265186266186267186268186269186270186271186272186273186274186275186276186277186278186279186280186281186282186283186284186285186286186287186288186289186290186291186292186293186294186295186296186297186298186299186300186301186302186303186304186305186306186307186308186309186310186311186312186313186314186315186316186317186318186319186320186321186322186323186324186325186326186327186328186329186330186331186332186333186334186335186336186337186338186339186340186341186342186343186344186345186346186347186348186349186350186351186352186353186354186355186356186357186358186359186360186361186362186363186364186365186366186367186368186369186370186371186372186373186374186375186376186377186378186379186380186381186382186383186384186385186386186387186388186389186390186391186392186393186394186395186396186397186398186399186400186401186402186403186404186405186406186407186408186409186410186411186412186413186414186415186416186417186418186419186420186421186422186423186424186425186426186427186428186429186430186431186432186433186434186435186436186437186438186439186440186441186442186443186444186445186446186447186448186449186450186451186452186453186454186455186456186457186458186459186460186461186462186463186464186465186466186467186468186469186470186471186472186473186474186475186476186477186478186479186480186481186482186483186484186485186486186487186488186489186490186491186492186493186494186495186496186497186498186499186500186501186502186503186504186505186506186507186508186509186510186511186512186513186514186515186516186517186518186519186520186521186522186523186524186525186526186527186528186529186530186531186532186533186534186535186536186537186538186539186540186541186542186543186544186545186546186547186548186549186550186551186552186553186554186555186556186557186558186559186560186561186562186563186564186565186566186567186568186569186570186571186572186573186574186575186576186577186578186579186580186581186582186583186584186585186586186587186588186589186590186591186592186593186594186595186596186597186598186599186600186601186602186603186604186605186606186607186608186609186610186611186612186613186614186615186616186617186618186619186620186621186622186623186624186625186626186627186628186629186630186631186632186633186634186635186636186637186638186639186640186641186642186643186644186645186646186647186648186649186650186651186652186653186654186655186656186657186658186659186660186661186662186663186664186665186666186667186668186669186670186671186672186673186674186675186676186677186678186679186680186681186682186683186684186685186686186687186688186689186690186691186692186693186694186695186696186697186698186699186700186701186702186703186704186705186706186707186708186709186710186711186712186713186714186715186716186717186718186719186720186721186722186723186724186725186726186727186728186729186730186731186732186733186734186735186736186737186738186739186740186741186742186743186744186745186746186747186748186749186750186751186752186753186754186755186756186757186758186759186760186761186762186763186764186765186766186767186768186769186770186771186772186773186774186775186776186777186778186779186780186781186782186783186784186785186786186787186788186789186790186791186792186793186794186795186796186797186798186799186800186801186802186803186804186805186806186807186808186809186810186811186812186813186814186815186816186817186818186819186820186821186822186823186824186825186826186827186828186829186830186831186832186833186834186835186836186837186838186839186840186841186842186843186844186845186846186847186848186849186850186851186852186853186854186855186856186857186858186859186860186861186862186863186864186865186866186867186868186869186870186871186872186873186874186875186876186877186878186879186880186881186882186883186884186885186886186887186888186889186890186891186892186893186894186895186896186897186898186899186900186901186902186903186904186905186906186907186908186909186910186911186912186913186914186915186916186917186918186919186920186921186922186923186924186925186926186927186928186929186930186931186932186933186934186935186936186937186938186939186940186941186942186943186944186945186946186947186948186949186950186951186952186953186954186955186956186957186958186959186960186961186962186963186964186965186966186967186968186969186970186971186972186973186974186975186976186977186978186979186980186981186982186983186984186985186986186987186988186989186990186991186992186993186994186995186996186997186998186999187000187001187002187003187004187005187006187007187008187009187010187011187012187013187014187015187016187017187018187019187020187021187022187023187024187025187026187027187028187029187030187031187032187033187034187035187036187037187038187039187040187041187042187043187044187045187046187047187048187049187050187051187052187053187054187055187056187057187058187059187060187061187062187063187064187065187066187067187068187069187070187071187072187073187074187075187076187077187078187079187080187081187082187083187084187085187086187087187088187089187090187091187092187093187094187095187096187097187098187099187100187101187102187103187104187105187106187107187108187109187110187111187112187113187114187115187116187117187118187119187120187121187122187123187124187125187126187127187128187129187130187131187132187133187134187135187136187137187138187139187140187141187142187143187144187145187146187147187148187149187150187151187152187153187154187155187156187157187158187159187160187161187162187163187164187165187166187167187168187169187170187171187172187173187174187175187176187177187178187179187180187181187182187183187184187185187186187187187188187189187190187191187192187193187194187195187196187197187198187199187200187201187202187203187204187205187206187207187208187209187210187211187212187213187214187215187216187217187218187219187220187221187222187223187224187225187226187227187228187229187230187231187232187233187234187235187236187237187238187239187240187241187242187243187244187245187246187247187248187249187250187251187252187253187254187255187256187257187258187259187260187261187262187263187264187265187266187267187268187269187270187271187272187273187274187275187276187277187278187279187280187281187282187283187284187285187286187287187288187289187290187291187292187293187294187295187296187297187298187299187300187301187302187303187304187305187306187307187308187309187310187311187312187313187314187315187316187317187318187319187320187321187322187323187324187325187326187327187328187329187330187331187332187333187334187335187336187337187338187339187340187341187342187343187344187345187346187347187348187349187350187351187352187353187354187355187356187357187358187359187360187361187362187363187364187365187366187367187368187369187370187371187372187373187374187375187376187377187378187379187380187381187382187383187384187385187386187387187388187389187390187391187392187393187394187395187396187397187398187399187400187401187402187403187404187405187406187407187408187409187410187411187412187413187414187415187416187417187418187419187420187421187422187423187424187425187426187427187428187429187430187431187432187433187434187435187436187437187438187439187440187441187442187443187444187445187446187447187448187449187450187451187452187453187454187455187456187457187458187459187460187461187462187463187464187465187466187467187468187469187470187471187472187473187474187475187476187477187478187479187480187481187482187483187484187485187486187487187488187489187490187491187492187493187494187495187496187497187498187499187500187501187502187503187504187505187506187507187508187509187510187511187512187513187514187515187516187517187518187519187520187521187522187523187524187525187526187527187528187529187530187531187532187533187534187535187536187537187538187539187540187541187542187543187544187545187546187547187548187549187550187551187552187553187554187555187556187557187558187559187560187561187562187563187564187565187566187567187568187569187570187571187572187573187574187575187576187577187578187579187580187581187582187583187584187585187586187587187588187589187590187591187592187593187594187595187596187597187598187599187600187601187602187603187604187605187606187607187608187609187610187611187612187613187614187615187616187617187618187619187620187621187622187623187624187625187626187627187628187629187630187631187632187633187634187635187636187637187638187639187640187641187642187643187644187645187646187647187648187649187650187651187652187653187654187655187656187657187658187659187660187661187662187663187664187665187666187667187668187669187670187671187672187673187674187675187676187677187678187679187680187681187682187683187684187685187686187687187688187689187690187691187692187693187694187695187696187697187698187699187700187701187702187703187704187705187706187707187708187709187710187711187712187713187714187715187716187717187718187719187720187721187722187723187724187725187726187727187728187729187730187731187732187733187734187735187736187737187738187739187740187741187742187743187744187745187746187747187748187749187750187751187752187753187754187755187756187757187758187759187760187761187762187763187764187765187766187767187768187769187770187771187772187773187774187775187776187777187778187779187780187781187782187783187784187785187786187787187788187789187790187791187792187793187794187795187796187797187798187799187800187801187802187803187804187805187806187807187808187809187810187811187812187813187814187815187816187817187818187819187820187821187822187823187824187825187826187827187828187829187830187831187832187833187834187835187836187837187838187839187840187841187842187843187844187845187846187847187848187849187850187851187852187853187854187855187856187857187858187859187860187861187862187863187864187865187866187867187868187869187870187871187872187873187874187875187876187877187878187879187880187881187882187883187884187885187886187887187888187889187890187891187892187893187894187895187896187897187898187899187900187901187902187903187904187905187906187907187908187909187910187911187912187913187914187915187916187917187918187919187920187921187922187923187924187925187926187927187928187929187930187931187932187933187934187935187936187937187938187939187940187941187942187943187944187945187946187947187948187949187950187951187952187953187954187955187956187957187958187959187960187961187962187963187964187965187966187967187968187969187970187971187972187973187974187975187976187977187978187979187980187981187982187983187984187985187986187987187988187989187990187991187992187993187994187995187996187997187998187999188000188001188002188003188004188005188006188007188008188009188010188011188012188013188014188015188016188017188018188019188020188021188022188023188024188025188026188027188028188029188030188031188032188033188034188035188036188037188038188039188040188041188042188043188044188045188046188047188048188049188050188051188052188053188054188055188056188057188058188059188060188061188062188063188064188065188066188067188068188069188070188071188072188073188074188075188076188077188078188079188080188081188082188083188084188085188086188087188088188089188090188091188092188093188094188095188096188097188098188099188100188101188102188103188104188105188106188107188108188109188110188111188112188113188114188115188116188117188118188119188120188121188122188123188124188125188126188127188128188129188130188131188132188133188134188135188136188137188138188139188140188141188142188143188144188145188146188147188148188149188150188151188152188153188154188155188156188157188158188159188160188161188162188163188164188165188166188167188168188169188170188171188172188173188174188175188176188177188178188179188180188181188182188183188184188185188186188187188188188189188190188191188192188193188194188195188196188197188198188199188200188201188202188203188204188205188206188207188208188209188210188211188212188213188214188215188216188217188218188219188220188221188222188223188224188225188226188227188228188229188230188231188232188233188234188235188236188237188238188239188240188241188242188243188244188245188246188247188248188249188250188251188252188253188254188255188256188257188258188259188260188261188262188263188264188265188266188267188268188269188270188271188272188273188274188275188276188277188278188279188280188281188282188283188284188285188286188287188288188289188290188291188292188293188294188295188296188297188298188299188300188301188302188303188304188305188306188307188308188309188310188311188312188313188314188315188316188317188318188319188320188321188322188323188324188325188326188327188328188329188330188331188332188333188334188335188336188337188338188339188340188341188342188343188344188345188346188347188348188349188350188351188352188353188354188355188356188357188358188359188360188361188362188363188364188365188366188367188368188369188370188371188372188373188374188375188376188377188378188379188380188381188382188383188384188385188386188387188388188389188390188391188392188393188394188395188396188397188398188399188400188401188402188403188404188405188406188407188408188409188410188411188412188413188414188415188416188417188418188419188420188421188422188423188424188425188426188427188428188429188430188431188432188433188434188435188436188437188438188439188440188441188442188443188444188445188446188447188448188449188450188451188452188453188454188455188456188457188458188459188460188461188462188463188464188465188466188467188468188469188470188471188472188473188474188475188476188477188478188479188480188481188482188483188484188485188486188487188488188489188490188491188492188493188494188495188496188497188498188499188500188501188502188503188504188505188506188507188508188509188510188511188512188513188514188515188516188517188518188519188520188521188522188523188524188525188526188527188528188529188530188531188532188533188534188535188536188537188538188539188540188541188542188543188544188545188546188547188548188549188550188551188552188553188554188555188556188557188558188559188560188561188562188563188564188565188566188567188568188569188570188571188572188573188574188575188576188577188578188579188580188581188582188583188584188585188586188587188588188589188590188591188592188593188594188595188596188597188598188599188600188601188602188603188604188605188606188607188608188609188610188611188612188613188614188615188616188617188618188619188620188621188622188623188624188625188626188627188628188629188630188631188632188633188634188635188636188637188638188639188640188641188642188643188644188645188646188647188648188649188650188651188652188653188654188655188656188657188658188659188660188661188662188663188664188665188666188667188668188669188670188671188672188673188674188675188676188677188678188679188680188681188682188683188684188685188686188687188688188689188690188691188692188693188694188695188696188697188698188699188700188701188702188703188704188705188706188707188708188709188710188711188712188713188714188715188716188717188718188719188720188721188722188723188724188725188726188727188728188729188730188731188732188733188734188735188736188737188738188739188740188741188742188743188744188745188746188747188748188749188750188751188752188753188754188755188756188757188758188759188760188761188762188763188764188765188766188767188768188769188770188771188772188773188774188775188776188777188778188779188780188781188782188783188784188785188786188787188788188789188790188791188792188793188794188795188796188797188798188799188800188801188802188803188804188805188806188807188808188809188810188811188812188813188814188815188816188817188818188819188820188821188822188823188824188825188826188827188828188829188830188831188832188833188834188835188836188837188838188839188840188841188842188843188844188845188846188847188848188849188850188851188852188853188854188855188856188857188858188859188860188861188862188863188864188865188866188867188868188869188870188871188872188873188874188875188876188877188878188879188880188881188882188883188884188885188886188887188888188889188890188891188892188893188894188895188896188897188898188899188900188901188902188903188904188905188906188907188908188909188910188911188912188913188914188915188916188917188918188919188920188921188922188923188924188925188926188927188928188929188930188931188932188933188934188935188936188937188938188939188940188941188942188943188944188945188946188947188948188949188950188951188952188953188954188955188956188957188958188959188960188961188962188963188964188965188966188967188968188969188970188971188972188973188974188975188976188977188978188979188980188981188982188983188984188985188986188987188988188989188990188991188992188993188994188995188996188997188998188999189000189001189002189003189004189005189006189007189008189009189010189011189012189013189014189015189016189017189018189019189020189021189022189023189024189025189026189027189028189029189030189031189032189033189034189035189036189037189038189039189040189041189042189043189044189045189046189047189048189049189050189051189052189053189054189055189056189057189058189059189060189061189062189063189064189065189066189067189068189069189070189071189072189073189074189075189076189077189078189079189080189081189082189083189084189085189086189087189088189089189090189091189092189093189094189095189096189097189098189099189100189101189102189103189104189105189106189107189108189109189110189111189112189113189114189115189116189117189118189119189120189121189122189123189124189125189126189127189128189129189130189131189132189133189134189135189136189137189138189139189140189141189142189143189144189145189146189147189148189149189150189151189152189153189154189155189156189157189158189159189160189161189162189163189164189165189166189167189168189169189170189171189172189173189174189175189176189177189178189179189180189181189182189183189184189185189186189187189188189189189190189191189192189193189194189195189196189197189198189199189200189201189202189203189204189205189206189207189208189209189210189211189212189213189214189215189216189217189218189219189220189221189222189223189224189225189226189227189228189229189230189231189232189233189234189235189236189237189238189239189240189241189242189243189244189245189246189247189248189249189250189251189252189253189254189255189256189257189258189259189260189261189262189263189264189265189266189267189268189269189270189271189272189273189274189275189276189277189278189279189280189281189282189283189284189285189286189287189288189289189290189291189292189293189294189295189296189297189298189299189300189301189302189303189304189305189306189307189308189309189310189311189312189313189314189315189316189317189318189319189320189321189322189323189324189325189326189327189328189329189330189331189332189333189334189335189336189337189338189339189340189341189342189343189344189345189346189347189348189349189350189351189352189353189354189355189356189357189358189359189360189361189362189363189364189365189366189367189368189369189370189371189372189373189374189375189376189377189378189379189380189381189382189383189384189385189386189387189388189389189390189391189392189393189394189395189396189397189398189399189400189401189402189403189404189405189406189407189408189409189410189411189412189413189414189415189416189417189418189419189420189421189422189423189424189425189426189427189428189429189430189431189432189433189434189435189436189437189438189439189440189441189442189443189444189445189446189447189448189449189450189451189452189453189454189455189456189457189458189459189460189461189462189463189464189465189466189467189468189469189470189471189472189473189474189475189476189477189478189479189480189481189482189483189484189485189486189487189488189489189490189491189492189493189494189495189496189497189498189499189500189501189502189503189504189505189506189507189508189509189510189511189512189513189514189515189516189517189518189519189520189521189522189523189524189525189526189527189528189529189530189531189532189533189534189535189536189537189538189539189540189541189542189543189544189545189546189547189548189549189550189551189552189553189554189555189556189557189558189559189560189561189562189563189564189565189566189567189568189569189570189571189572189573189574189575189576189577189578189579189580189581189582189583189584189585189586189587189588189589189590189591189592189593189594189595189596189597189598189599189600189601189602189603189604189605189606189607189608189609189610189611189612189613189614189615189616189617189618189619189620189621189622189623189624189625189626189627189628189629189630189631189632189633189634189635189636189637189638189639189640189641189642189643189644189645189646189647189648189649189650189651189652189653189654189655189656189657189658189659189660189661189662189663189664189665189666189667189668189669189670189671189672189673189674189675189676189677189678189679189680189681189682189683189684189685189686189687189688189689189690189691189692189693189694189695189696189697189698189699189700189701189702189703189704189705189706189707189708189709189710189711189712189713189714189715189716189717189718189719189720189721189722189723189724189725189726189727189728189729189730189731189732189733189734189735189736189737189738189739189740189741189742189743189744189745189746189747189748189749189750189751189752189753189754189755189756189757189758189759189760189761189762189763189764189765189766189767189768189769189770189771189772189773189774189775189776189777189778189779189780189781189782189783189784189785189786189787189788189789189790189791189792189793189794189795189796189797189798189799189800189801189802189803189804189805189806189807189808189809189810189811189812189813189814189815189816189817189818189819189820189821189822189823189824189825189826189827189828189829189830189831189832189833189834189835189836189837189838189839189840189841189842189843189844189845189846189847189848189849189850189851189852189853189854189855189856189857189858189859189860189861189862189863189864189865189866189867189868189869189870189871189872189873189874189875189876189877189878189879189880189881189882189883189884189885189886189887189888189889189890189891189892189893189894189895189896189897189898189899189900189901189902189903189904189905189906189907189908189909189910189911189912189913189914189915189916189917189918189919189920189921189922189923189924189925189926189927189928189929189930189931189932189933189934189935189936189937189938189939189940189941189942189943189944189945189946189947189948189949189950189951189952189953189954189955189956189957189958189959189960189961189962189963189964189965189966189967189968189969189970189971189972189973189974189975189976189977189978189979189980189981189982189983189984189985189986189987189988189989189990189991189992189993189994189995189996189997189998189999190000190001190002190003190004190005190006190007190008190009190010190011190012190013190014190015190016190017190018190019190020190021190022190023190024190025190026190027190028190029190030190031190032190033190034190035190036190037190038190039190040190041190042190043190044190045190046190047190048190049190050190051190052190053190054190055190056190057190058190059190060190061190062190063190064190065190066190067190068190069190070190071190072190073190074190075190076190077190078190079190080190081190082190083190084190085190086190087190088190089190090190091190092190093190094190095190096190097190098190099190100190101190102190103190104190105190106190107190108190109190110190111190112190113190114190115190116190117190118190119190120190121190122190123190124190125190126190127190128190129190130190131190132190133190134190135190136190137190138190139190140190141190142190143190144190145190146190147190148190149190150190151190152190153190154190155190156190157190158190159190160190161190162190163190164190165190166190167190168190169190170190171190172190173190174190175190176190177190178190179190180190181190182190183190184190185190186190187190188190189190190190191190192190193190194190195190196190197190198190199190200190201190202190203190204190205190206190207190208190209190210190211190212190213190214190215190216190217190218190219190220190221190222190223190224190225190226190227190228190229190230190231190232190233190234190235190236190237190238190239190240190241190242190243190244190245190246190247190248190249190250190251190252190253190254190255190256190257190258190259190260190261190262190263190264190265190266190267190268190269190270190271190272190273190274190275190276190277190278190279190280190281190282190283190284190285190286190287190288190289190290190291190292190293190294190295190296190297190298190299190300190301190302190303190304190305190306190307190308190309190310190311190312190313190314190315190316190317190318190319190320190321190322190323190324190325190326190327190328190329190330190331190332190333190334190335190336190337190338190339190340190341190342190343190344190345190346190347190348190349190350190351190352190353190354190355190356190357190358190359190360190361190362190363190364190365190366190367190368190369190370190371190372190373190374190375190376190377190378190379190380190381190382190383190384190385190386190387190388190389190390190391190392190393190394190395190396190397190398190399190400190401190402190403190404190405190406190407190408190409190410190411190412190413190414190415190416190417190418190419190420190421190422190423190424190425190426190427190428190429190430190431190432190433190434190435190436190437190438190439190440190441190442190443190444190445190446190447190448190449190450190451190452190453190454190455190456190457190458190459190460190461190462190463190464190465190466190467190468190469190470190471190472190473190474190475190476190477190478190479190480190481190482190483190484190485190486190487190488190489190490190491190492190493190494190495190496190497190498190499190500190501190502190503190504190505190506190507190508190509190510190511190512190513190514190515190516190517190518190519190520190521190522190523190524190525190526190527190528190529190530190531190532190533190534190535190536190537190538190539190540190541190542190543190544190545190546190547190548190549190550190551190552190553190554190555190556190557190558190559190560190561190562190563190564190565190566190567190568190569190570190571190572190573190574190575190576190577190578190579190580190581190582190583190584190585190586190587190588190589190590190591190592190593190594190595190596190597190598190599190600190601190602190603190604190605190606190607190608190609190610190611190612190613190614190615190616190617190618190619190620190621190622190623190624190625190626190627190628190629190630190631190632190633190634190635190636190637190638190639190640190641190642190643190644190645190646190647190648190649190650190651190652190653190654190655190656190657190658190659190660190661190662190663190664190665190666190667190668190669190670190671190672190673190674190675190676190677190678190679190680190681190682190683190684190685190686190687190688190689190690190691190692190693190694190695190696190697190698190699190700190701190702190703190704190705190706190707190708190709190710190711190712190713190714190715190716190717190718190719190720190721190722190723190724190725190726190727190728190729190730190731190732190733190734190735190736190737190738190739190740190741190742190743190744190745190746190747190748190749190750190751190752190753190754190755190756190757190758190759190760190761190762190763190764190765190766190767190768190769190770190771190772190773190774190775190776190777190778190779190780190781190782190783190784190785190786190787190788190789190790190791190792190793190794190795190796190797190798190799190800190801190802190803190804190805190806190807190808190809190810190811190812190813190814190815190816190817190818190819190820190821190822190823190824190825190826190827190828190829190830190831190832190833190834190835190836190837190838190839190840190841190842190843190844190845190846190847190848190849190850190851190852190853190854190855190856190857190858190859190860190861190862190863190864190865190866190867190868190869190870190871190872190873190874190875190876190877190878190879190880190881190882190883190884190885190886190887190888190889190890190891190892190893190894190895190896190897190898190899190900190901190902190903190904190905190906190907190908190909190910190911190912190913190914190915190916190917190918190919190920190921190922190923190924190925190926190927190928190929190930190931190932190933190934190935190936190937190938190939190940190941190942190943190944190945190946190947190948190949190950190951190952190953190954190955190956190957190958190959190960190961190962190963190964190965190966190967190968190969190970190971190972190973190974190975190976190977190978190979190980190981190982190983190984190985190986190987190988190989190990190991190992190993190994190995190996190997190998190999191000191001191002191003191004191005191006191007191008191009191010191011191012191013191014191015191016191017191018191019191020191021191022191023191024191025191026191027191028191029191030191031191032191033191034191035191036191037191038191039191040191041191042191043191044191045191046191047191048191049191050191051191052191053191054191055191056191057191058191059191060191061191062191063191064191065191066191067191068191069191070191071191072191073191074191075191076191077191078191079191080191081191082191083191084191085191086191087191088191089191090191091191092191093191094191095191096191097191098191099191100191101191102191103191104191105191106191107191108191109191110191111191112191113191114191115191116191117191118191119191120191121191122191123191124191125191126191127191128191129191130191131191132191133191134191135191136191137191138191139191140191141191142191143191144191145191146191147191148191149191150191151191152191153191154191155191156191157191158191159191160191161191162191163191164191165191166191167191168191169191170191171191172191173191174191175191176191177191178191179191180191181191182191183191184191185191186191187191188191189191190191191191192191193191194191195191196191197191198191199191200191201191202191203191204191205191206191207191208191209191210191211191212191213191214191215191216191217191218191219191220191221191222191223191224191225191226191227191228191229191230191231191232191233191234191235191236191237191238191239191240191241191242191243191244191245191246191247191248191249191250191251191252191253191254191255191256191257191258191259191260191261191262191263191264191265191266191267191268191269191270191271191272191273191274191275191276191277191278191279191280191281191282191283191284191285191286191287191288191289191290191291191292191293191294191295191296191297191298191299191300191301191302191303191304191305191306191307191308191309191310191311191312191313191314191315191316191317191318191319191320191321191322191323191324191325191326191327191328191329191330191331191332191333191334191335191336191337191338191339191340191341191342191343191344191345191346191347191348191349191350191351191352191353191354191355191356191357191358191359191360191361191362191363191364191365191366191367191368191369191370191371191372191373191374191375191376191377191378191379191380191381191382191383191384191385191386191387191388191389191390191391191392191393191394191395191396191397191398191399191400191401191402191403191404191405191406191407191408191409191410191411191412191413191414191415191416191417191418191419191420191421191422191423191424191425191426191427191428191429191430191431191432191433191434191435191436191437191438191439191440191441191442191443191444191445191446191447191448191449191450191451191452191453191454191455191456191457191458191459191460191461191462191463191464191465191466191467191468191469191470191471191472191473191474191475191476191477191478191479191480191481191482191483191484191485191486191487191488191489191490191491191492191493191494191495191496191497191498191499191500191501191502191503191504191505191506191507191508191509191510191511191512191513191514191515191516191517191518191519191520191521191522191523191524191525191526191527191528191529191530191531191532191533191534191535191536191537191538191539191540191541191542191543191544191545191546191547191548191549191550191551191552191553191554191555191556191557191558191559191560191561191562191563191564191565191566191567191568191569191570191571191572191573191574191575191576191577191578191579191580191581191582191583191584191585191586191587191588191589191590191591191592191593191594191595191596191597191598191599191600191601191602191603191604191605191606191607191608191609191610191611191612191613191614191615191616191617191618191619191620191621191622191623191624191625191626191627191628191629191630191631191632191633191634191635191636191637191638191639191640191641191642191643191644191645191646191647191648191649191650191651191652191653191654191655191656191657191658191659191660191661191662191663191664191665191666191667191668191669191670191671191672191673191674191675191676191677191678191679191680191681191682191683191684191685191686191687191688191689191690191691191692191693191694191695191696191697191698191699191700191701191702191703191704191705191706191707191708191709191710191711191712191713191714191715191716191717191718191719191720191721191722191723191724191725191726191727191728191729191730191731191732191733191734191735191736191737191738191739191740191741191742191743191744191745191746191747191748191749191750191751191752191753191754191755191756191757191758191759191760191761191762191763191764191765191766191767191768191769191770191771191772191773191774191775191776191777191778191779191780191781191782191783191784191785191786191787191788191789191790191791191792191793191794191795191796191797191798191799191800191801191802191803191804191805191806191807191808191809191810191811191812191813191814191815191816191817191818191819191820191821191822191823191824191825191826191827191828191829191830191831191832191833191834191835191836191837191838191839191840191841191842191843191844191845191846191847191848191849191850191851191852191853191854191855191856191857191858191859191860191861191862191863191864191865191866191867191868191869191870191871191872191873191874191875191876191877191878191879191880191881191882191883191884191885191886191887191888191889191890191891191892191893191894191895191896191897191898191899191900191901191902191903191904191905191906191907191908191909191910191911191912191913191914191915191916191917191918191919191920191921191922191923191924191925191926191927191928191929191930191931191932191933191934191935191936191937191938191939191940191941191942191943191944191945191946191947191948191949191950191951191952191953191954191955191956191957191958191959191960191961191962191963191964191965191966191967191968191969191970191971191972191973191974191975191976191977191978191979191980191981191982191983191984191985191986191987191988191989191990191991191992191993191994191995191996191997191998191999192000192001192002192003192004192005192006192007192008192009192010192011192012192013192014192015192016192017192018192019192020192021192022192023192024192025192026192027192028192029192030192031192032192033192034192035192036192037192038192039192040192041192042192043192044192045192046192047192048192049192050192051192052192053192054192055192056192057192058192059192060192061192062192063192064192065192066192067192068192069192070192071192072192073192074192075192076192077192078192079192080192081192082192083192084192085192086192087192088192089192090192091192092192093192094192095192096192097192098192099192100192101192102192103192104192105192106192107192108192109192110192111192112192113192114192115192116192117192118192119192120192121192122192123192124192125192126192127192128192129192130192131192132192133192134192135192136192137192138192139192140192141192142192143192144192145192146192147192148192149192150192151192152192153192154192155192156192157192158192159192160192161192162192163192164192165192166192167192168192169192170192171192172192173192174192175192176192177192178192179192180192181192182192183192184192185192186192187192188192189192190192191192192192193192194192195192196192197192198192199192200192201192202192203192204192205192206192207192208192209192210192211192212192213192214192215192216192217192218192219192220192221192222192223192224192225192226192227192228192229192230192231192232192233192234192235192236192237192238192239192240192241192242192243192244192245192246192247192248192249192250192251192252192253192254192255192256192257192258192259192260192261192262192263192264192265192266192267192268192269192270192271192272192273192274192275192276192277192278192279192280192281192282192283192284192285192286192287192288192289192290192291192292192293192294192295192296192297192298192299192300192301192302192303192304192305192306192307192308192309192310192311192312192313192314192315192316192317192318192319192320192321192322192323192324192325192326192327192328192329192330192331192332192333192334192335192336192337192338192339192340192341192342192343192344192345192346192347192348192349192350192351192352192353192354192355192356192357192358192359192360192361192362192363192364192365192366192367192368192369192370192371192372192373192374192375192376192377192378192379192380192381192382192383192384192385192386192387192388192389192390192391192392192393192394192395192396192397192398192399192400192401192402192403192404192405192406192407192408192409192410192411192412192413192414192415192416192417192418192419192420192421192422192423192424192425192426192427192428192429192430192431192432192433192434192435192436192437192438192439192440192441192442192443192444192445192446192447192448192449192450192451192452192453192454192455192456192457192458192459192460192461192462192463192464192465192466192467192468192469192470192471192472192473192474192475192476192477192478192479192480192481192482192483192484192485192486192487192488192489192490192491192492192493192494192495192496192497192498192499192500192501192502192503192504192505192506192507192508192509192510192511192512192513192514192515192516192517192518192519192520192521192522192523192524192525192526192527192528192529192530192531192532192533192534192535192536192537192538192539192540192541192542192543192544192545192546192547192548192549192550192551192552192553192554192555192556192557192558192559192560192561192562192563192564192565192566192567192568192569192570192571192572192573192574192575192576192577192578192579192580192581192582192583192584192585192586192587192588192589192590192591192592192593192594192595192596192597192598192599192600192601192602192603192604192605192606192607192608192609192610192611192612192613192614192615192616192617192618192619192620192621192622192623192624192625192626192627192628192629192630192631192632192633192634192635192636192637192638192639192640192641192642192643192644192645192646192647192648192649192650192651192652192653192654192655192656192657192658192659192660192661192662192663192664192665192666192667192668192669192670192671192672192673192674192675192676192677192678192679192680192681192682192683192684192685192686192687192688192689192690192691192692192693192694192695192696192697192698192699192700192701192702192703192704192705192706192707192708192709192710192711192712192713192714192715192716192717192718192719192720192721192722192723192724192725192726192727192728192729192730192731192732192733192734192735192736192737192738192739192740192741192742192743192744192745192746192747192748192749192750192751192752192753192754192755192756192757192758192759192760192761192762192763192764192765192766192767192768192769192770192771192772192773192774192775192776192777192778192779192780192781192782192783192784192785192786192787192788192789192790192791192792192793192794192795192796192797192798192799192800192801192802192803192804192805192806192807192808192809192810192811192812192813192814192815192816192817192818192819192820192821192822192823192824192825192826192827192828192829192830192831192832192833192834192835192836192837192838192839192840192841192842192843192844192845192846192847192848192849192850192851192852192853192854192855192856192857192858192859192860192861192862192863192864192865192866192867192868192869192870192871192872192873192874192875192876192877192878192879192880192881192882192883192884192885192886192887192888192889192890192891192892192893192894192895192896192897192898192899192900192901192902192903192904192905192906192907192908192909192910192911192912192913192914192915192916192917192918192919192920192921192922192923192924192925192926192927192928192929192930192931192932192933192934192935192936192937192938192939192940192941192942192943192944192945192946192947192948192949192950192951192952192953192954192955192956192957192958192959192960192961192962192963192964192965192966192967192968192969192970192971192972192973192974192975192976192977192978192979192980192981192982192983192984192985192986192987192988192989192990192991192992192993192994192995192996192997192998192999193000193001193002193003193004193005193006193007193008193009193010193011193012193013193014193015193016193017193018193019193020193021193022193023193024193025193026193027193028193029193030193031193032193033193034193035193036193037193038193039193040193041193042193043193044193045193046193047193048193049193050193051193052193053193054193055193056193057193058193059193060193061193062193063193064193065193066193067193068193069193070193071193072193073193074193075193076193077193078193079193080193081193082193083193084193085193086193087193088193089193090193091193092193093193094193095193096193097193098193099193100193101193102193103193104193105193106193107193108193109193110193111193112193113193114193115193116193117193118193119193120193121193122193123193124193125193126193127193128193129193130193131193132193133193134193135193136193137193138193139193140193141193142193143193144193145193146193147193148193149193150193151193152193153193154193155193156193157193158193159193160193161193162193163193164193165193166193167193168193169193170193171193172193173193174193175193176193177193178193179193180193181193182193183193184193185193186193187193188193189193190193191193192193193193194193195193196193197193198193199193200193201193202193203193204193205193206193207193208193209193210193211193212193213193214193215193216193217193218193219193220193221193222193223193224193225193226193227193228193229193230193231193232193233193234193235193236193237193238193239193240193241193242193243193244193245193246193247193248193249193250193251193252193253193254193255193256193257193258193259193260193261193262193263193264193265193266193267193268193269193270193271193272193273193274193275193276193277193278193279193280193281193282193283193284193285193286193287193288193289193290193291193292193293193294193295193296193297193298193299193300193301193302193303193304193305193306193307193308193309193310193311193312193313193314193315193316193317193318193319193320193321193322193323193324193325193326193327193328193329193330193331193332193333193334193335193336193337193338193339193340193341193342193343193344193345193346193347193348193349193350193351193352193353193354193355193356193357193358193359193360193361193362193363193364193365193366193367193368193369193370193371193372193373193374193375193376193377193378193379193380193381193382193383193384193385193386193387193388193389193390193391193392193393193394193395193396193397193398193399193400193401193402193403193404193405193406193407193408193409193410193411193412193413193414193415193416193417193418193419193420193421193422193423193424193425193426193427193428193429193430193431193432193433193434193435193436193437193438193439193440193441193442193443193444193445193446193447193448193449193450193451193452193453193454193455193456193457193458193459193460193461193462193463193464193465193466193467193468193469193470193471193472193473193474193475193476193477193478193479193480193481193482193483193484193485193486193487193488193489193490193491193492193493193494193495193496193497193498193499193500193501193502193503193504193505193506193507193508193509193510193511193512193513193514193515193516193517193518193519193520193521193522193523193524193525193526193527193528193529193530193531193532193533193534193535193536193537193538193539193540193541193542193543193544193545193546193547193548193549193550193551193552193553193554193555193556193557193558193559193560193561193562193563193564193565193566193567193568193569193570193571193572193573193574193575193576193577193578193579193580193581193582193583193584193585193586193587193588193589193590193591193592193593193594193595193596193597193598193599193600193601193602193603193604193605193606193607193608193609193610193611193612193613193614193615193616193617193618193619193620193621193622193623193624193625193626193627193628193629193630193631193632193633193634193635193636193637193638193639193640193641193642193643193644193645193646193647193648193649193650193651193652193653193654193655193656193657193658193659193660193661193662193663193664193665193666193667193668193669193670193671193672193673193674193675193676193677193678193679193680193681193682193683193684193685193686193687193688193689193690193691193692193693193694193695193696193697193698193699193700193701193702193703193704193705193706193707193708193709193710193711193712193713193714193715193716193717193718193719193720193721193722193723193724193725193726193727193728193729193730193731193732193733193734193735193736193737193738193739193740193741193742193743193744193745193746193747193748193749193750193751193752193753193754193755193756193757193758193759193760193761193762193763193764193765193766193767193768193769193770193771193772193773193774193775193776193777193778193779193780193781193782193783193784193785193786193787193788193789193790193791193792193793193794193795193796193797193798193799193800193801193802193803193804193805193806193807193808193809193810193811193812193813193814193815193816193817193818193819193820193821193822193823193824193825193826193827193828193829193830193831193832193833193834193835193836193837193838193839193840193841193842193843193844193845193846193847193848193849193850193851193852193853193854193855193856193857193858193859193860193861193862193863193864193865193866193867193868193869193870193871193872193873193874193875193876193877193878193879193880193881193882193883193884193885193886193887193888193889193890193891193892193893193894193895193896193897193898193899193900193901193902193903193904193905193906193907193908193909193910193911193912193913193914193915193916193917193918193919193920193921193922193923193924193925193926193927193928193929193930193931193932193933193934193935193936193937193938193939193940193941193942193943193944193945193946193947193948193949193950193951193952193953193954193955193956193957193958193959193960193961193962193963193964193965193966193967193968193969193970193971193972193973193974193975193976193977193978193979193980193981193982193983193984193985193986193987193988193989193990193991193992193993193994193995193996193997193998193999194000194001194002194003194004194005194006194007194008194009194010194011194012194013194014194015194016194017194018194019194020194021194022194023194024194025194026194027194028194029194030194031194032194033194034194035194036194037194038194039194040194041194042194043194044194045194046194047194048194049194050194051194052194053194054194055194056194057194058194059194060194061194062194063194064194065194066194067194068194069194070194071194072194073194074194075194076194077194078194079194080194081194082194083194084194085194086194087194088194089194090194091194092194093194094194095194096194097194098194099194100194101194102194103194104194105194106194107194108194109194110194111194112194113194114194115194116194117194118194119194120194121194122194123194124194125194126194127194128194129194130194131194132194133194134194135194136194137194138194139194140194141194142194143194144194145194146194147194148194149194150194151194152194153194154194155194156194157194158194159194160194161194162194163194164194165194166194167194168194169194170194171194172194173194174194175194176194177194178194179194180194181194182194183194184194185194186194187194188194189194190194191194192194193194194194195194196194197194198194199194200194201194202194203194204194205194206194207194208194209194210194211194212194213194214194215194216194217194218194219194220194221194222194223194224194225194226194227194228194229194230194231194232194233194234194235194236194237194238194239194240194241194242194243194244194245194246194247194248194249194250194251194252194253194254194255194256194257194258194259194260194261194262194263194264194265194266194267194268194269194270194271194272194273194274194275194276194277194278194279194280194281194282194283194284194285194286194287194288194289194290194291194292194293194294194295194296194297194298194299194300194301194302194303194304194305194306194307194308194309194310194311194312194313194314194315194316194317194318194319194320194321194322194323194324194325194326194327194328194329194330194331194332194333194334194335194336194337194338194339194340194341194342194343194344194345194346194347194348194349194350194351194352194353194354194355194356194357194358194359194360194361194362194363194364194365194366194367194368194369194370194371194372194373194374194375194376194377194378194379194380194381194382194383194384194385194386194387194388194389194390194391194392194393194394194395194396194397194398194399194400194401194402194403194404194405194406194407194408194409194410194411194412194413194414194415194416194417194418194419194420194421194422194423194424194425194426194427194428194429194430194431194432194433194434194435194436194437194438194439194440194441194442194443194444194445194446194447194448194449194450194451194452194453194454194455194456194457194458194459194460194461194462194463194464194465194466194467194468194469194470194471194472194473194474194475194476194477194478194479194480194481194482194483194484194485194486194487194488194489194490194491194492194493194494194495194496194497194498194499194500194501194502194503194504194505194506194507194508194509194510194511194512194513194514194515194516194517194518194519194520194521194522194523194524194525194526194527194528194529194530194531194532194533194534194535194536194537194538194539194540194541194542194543194544194545194546194547194548194549194550194551194552194553194554194555194556194557194558194559194560194561194562194563194564194565194566194567194568194569194570194571194572194573194574194575194576194577194578194579194580194581194582194583194584194585194586194587194588194589194590194591194592194593194594194595194596194597194598194599194600194601194602194603194604194605194606194607194608194609194610194611194612194613194614194615194616194617194618194619194620194621194622194623194624194625194626194627194628194629194630194631194632194633194634194635194636194637194638194639194640194641194642194643194644194645194646194647194648194649194650194651194652194653194654194655194656194657194658194659194660194661194662194663194664194665194666194667194668194669194670194671194672194673194674194675194676194677194678194679194680194681194682194683194684194685194686194687194688194689194690194691194692194693194694194695194696194697194698194699194700194701194702194703194704194705194706194707194708194709194710194711194712194713194714194715194716194717194718194719194720194721194722194723194724194725194726194727194728194729194730194731194732194733194734194735194736194737194738194739194740194741194742194743194744194745194746194747194748194749194750194751194752194753194754194755194756194757194758194759194760194761194762194763194764194765194766194767194768194769194770194771194772194773194774194775194776194777194778194779194780194781194782194783194784194785194786194787194788194789194790194791194792194793194794194795194796194797194798194799194800194801194802194803194804194805194806194807194808194809194810194811194812194813194814194815194816194817194818194819194820194821194822194823194824194825194826194827194828194829194830194831194832194833194834194835194836194837194838194839194840194841194842194843194844194845194846194847194848194849194850194851194852194853194854194855194856194857194858194859194860194861194862194863194864194865194866194867194868194869194870194871194872194873194874194875194876194877194878194879194880194881194882194883194884194885194886194887194888194889194890194891194892194893194894194895194896194897194898194899194900194901194902194903194904194905194906194907194908194909194910194911194912194913194914194915194916194917194918194919194920194921194922194923194924194925194926194927194928194929194930194931194932194933194934194935194936194937194938194939194940194941194942194943194944194945194946194947194948194949194950194951194952194953194954194955194956194957194958194959194960194961194962194963194964194965194966194967194968194969194970194971194972194973194974194975194976194977194978194979194980194981194982194983194984194985194986194987194988194989194990194991194992194993194994194995194996194997194998194999195000195001195002195003195004195005195006195007195008195009195010195011195012195013195014195015195016195017195018195019195020195021195022195023195024195025195026195027195028195029195030195031195032195033195034195035195036195037195038195039195040195041195042195043195044195045195046195047195048195049195050195051195052195053195054195055195056195057195058195059195060195061195062195063195064195065195066195067195068195069195070195071195072195073195074195075195076195077195078195079195080195081195082195083195084195085195086195087195088195089195090195091195092195093195094195095195096195097195098195099195100195101195102195103195104195105195106195107195108195109195110195111195112195113195114195115195116195117195118195119195120195121195122195123195124195125195126195127195128195129195130195131195132195133195134195135195136195137195138195139195140195141195142195143195144195145195146195147195148195149195150195151195152195153195154195155195156195157195158195159195160195161195162195163195164195165195166195167195168195169195170195171195172195173195174195175195176195177195178195179195180195181195182195183195184195185195186195187195188195189195190195191195192195193195194195195195196195197195198195199195200195201195202195203195204195205195206195207195208195209195210195211195212195213195214195215195216195217195218195219195220195221195222195223195224195225195226195227195228195229195230195231195232195233195234195235195236195237195238195239195240195241195242195243195244195245195246195247195248195249195250195251195252195253195254195255195256195257195258195259195260195261195262195263195264195265195266195267195268195269195270195271195272195273195274195275195276195277195278195279195280195281195282195283195284195285195286195287195288195289195290195291195292195293195294195295195296195297195298195299195300195301195302195303195304195305195306195307195308195309195310195311195312195313195314195315195316195317195318195319195320195321195322195323195324195325195326195327195328195329195330195331195332195333195334195335195336195337195338195339195340195341195342195343195344195345195346195347195348195349195350195351195352195353195354195355195356195357195358195359195360195361195362195363195364195365195366195367195368195369195370195371195372195373195374195375195376195377195378195379195380195381195382195383195384195385195386195387195388195389195390195391195392195393195394195395195396195397195398195399195400195401195402195403195404195405195406195407195408195409195410195411195412195413195414195415195416195417195418195419195420195421195422195423195424195425195426195427195428195429195430195431195432195433195434195435195436195437195438195439195440195441195442195443195444195445195446195447195448195449195450195451195452195453195454195455195456195457195458195459195460195461195462195463195464195465195466195467195468195469195470195471195472195473195474195475195476195477195478195479195480195481195482195483195484195485195486195487195488195489195490195491195492195493195494195495195496195497195498195499195500195501195502195503195504195505195506195507195508195509195510195511195512195513195514195515195516195517195518195519195520195521195522195523195524195525195526195527195528195529195530195531195532195533195534195535195536195537195538195539195540195541195542195543195544195545195546195547195548195549195550195551195552195553195554195555195556195557195558195559195560195561195562195563195564195565195566195567195568195569195570195571195572195573195574195575195576195577195578195579195580195581195582195583195584195585195586195587195588195589195590195591195592195593195594195595195596195597195598195599195600195601195602195603195604195605195606195607195608195609195610195611195612195613195614195615195616195617195618195619195620195621195622195623195624195625195626195627195628195629195630195631195632195633195634195635195636195637195638195639195640195641195642195643195644195645195646195647195648195649195650195651195652195653195654195655195656195657195658195659195660195661195662195663195664195665195666195667195668195669195670195671195672195673195674195675195676195677195678195679195680195681195682195683195684195685195686195687195688195689195690195691195692195693195694195695195696195697195698195699195700195701195702195703195704195705195706195707195708195709195710195711195712195713195714195715195716195717195718195719195720195721195722195723195724195725195726195727195728195729195730195731195732195733195734195735195736195737195738195739195740195741195742195743195744195745195746195747195748195749195750195751195752195753195754195755195756195757195758195759195760195761195762195763195764195765195766195767195768195769195770195771195772195773195774195775195776195777195778195779195780195781195782195783195784195785195786195787195788195789195790195791195792195793195794195795195796195797195798195799195800195801195802195803195804195805195806195807195808195809195810195811195812195813195814195815195816195817195818195819195820195821195822195823195824195825195826195827195828195829195830195831195832195833195834195835195836195837195838195839195840195841195842195843195844195845195846195847195848195849195850195851195852195853195854195855195856195857195858195859195860195861195862195863195864195865195866195867195868195869195870195871195872195873195874195875195876195877195878195879195880195881195882195883195884195885195886195887195888195889195890195891195892195893195894195895195896195897195898195899195900195901195902195903195904195905195906195907195908195909195910195911195912195913195914195915195916195917195918195919195920195921195922195923195924195925195926195927195928195929195930195931195932195933195934195935195936195937195938195939195940195941195942195943195944195945195946195947195948195949195950195951195952195953195954195955195956195957195958195959195960195961195962195963195964195965195966195967195968195969195970195971195972195973195974195975195976195977195978195979195980195981195982195983195984195985195986195987195988195989195990195991195992195993195994195995195996195997195998195999196000196001196002196003196004196005196006196007196008196009196010196011196012196013196014196015196016196017196018196019196020196021196022196023196024196025196026196027196028196029196030196031196032196033196034196035196036196037196038196039196040196041196042196043196044196045196046196047196048196049196050196051196052196053196054196055196056196057196058196059196060196061196062196063196064196065196066196067196068196069196070196071196072196073196074196075196076196077196078196079196080196081196082196083196084196085196086196087196088196089196090196091196092196093196094196095196096196097196098196099196100196101196102196103196104196105196106196107196108196109196110196111196112196113196114196115196116196117196118196119196120196121196122196123196124196125196126196127196128196129196130196131196132196133196134196135196136196137196138196139196140196141196142196143196144196145196146196147196148196149196150196151196152196153196154196155196156196157196158196159196160196161196162196163196164196165196166196167196168196169196170196171196172196173196174196175196176196177196178196179196180196181196182196183196184196185196186196187196188196189196190196191196192196193196194196195196196196197196198196199196200196201196202196203196204196205196206196207196208196209196210196211196212196213196214196215196216196217196218196219196220196221196222196223196224196225196226196227196228196229196230196231196232196233196234196235196236196237196238196239196240196241196242196243196244196245196246196247196248196249196250196251196252196253196254196255196256196257196258196259196260196261196262196263196264196265196266196267196268196269196270196271196272196273196274196275196276196277196278196279196280196281196282196283196284196285196286196287196288196289196290196291196292196293196294196295196296196297196298196299196300196301196302196303196304196305196306196307196308196309196310196311196312196313196314196315196316196317196318196319196320196321196322196323196324196325196326196327196328196329196330196331196332196333196334196335196336196337196338196339196340196341196342196343196344196345196346196347196348196349196350196351196352196353196354196355196356196357196358196359196360196361196362196363196364196365196366196367196368196369196370196371196372196373196374196375196376196377196378196379196380196381196382196383196384196385196386196387196388196389196390196391196392196393196394196395196396196397196398196399196400196401196402196403196404196405196406196407196408196409196410196411196412196413196414196415196416196417196418196419196420196421196422196423196424196425196426196427196428196429196430196431196432196433196434196435196436196437196438196439196440196441196442196443196444196445196446196447196448196449196450196451196452196453196454196455196456196457196458196459196460196461196462196463196464196465196466196467196468196469196470196471196472196473196474196475196476196477196478196479196480196481196482196483196484196485196486196487196488196489196490196491196492196493196494196495196496196497196498196499196500196501196502196503196504196505196506196507196508196509196510196511196512196513196514196515196516196517196518196519196520196521196522196523196524196525196526196527196528196529196530196531196532196533196534196535196536196537196538196539196540196541196542196543196544196545196546196547196548196549196550196551196552196553196554196555196556196557196558196559196560196561196562196563196564196565196566196567196568196569196570196571196572196573196574196575196576196577196578196579196580196581196582196583196584196585196586196587196588196589196590196591196592196593196594196595196596196597196598196599196600196601196602196603196604196605196606196607196608196609196610196611196612196613196614196615196616196617196618196619196620196621196622196623196624196625196626196627196628196629196630196631196632196633196634196635196636196637196638196639196640196641196642196643196644196645196646196647196648196649196650196651196652196653196654196655196656196657196658196659196660196661196662196663196664196665196666196667196668196669196670196671196672196673196674196675196676196677196678196679196680196681196682196683196684196685196686196687196688196689196690196691196692196693196694196695196696196697196698196699196700196701196702196703196704196705196706196707196708196709196710196711196712196713196714196715196716196717196718196719196720196721196722196723196724196725196726196727196728196729196730196731196732196733196734196735196736196737196738196739196740196741196742196743196744196745196746196747196748196749196750196751196752196753196754196755196756196757196758196759196760196761196762196763196764196765196766196767196768196769196770196771196772196773196774196775196776196777196778196779196780196781196782196783196784196785196786196787196788196789196790196791196792196793196794196795196796196797196798196799196800196801196802196803196804196805196806196807196808196809196810196811196812196813196814196815196816196817196818196819196820196821196822196823196824196825196826196827196828196829196830196831196832196833196834196835196836196837196838196839196840196841196842196843196844196845196846196847196848196849196850196851196852196853196854196855196856196857196858196859196860196861196862196863196864196865196866196867196868196869196870196871196872196873196874196875196876196877196878196879196880196881196882196883196884196885196886196887196888196889196890196891196892196893196894196895196896196897196898196899196900196901196902196903196904196905196906196907196908196909196910196911196912196913196914196915196916196917196918196919196920196921196922196923196924196925196926196927196928196929196930196931196932196933196934196935196936196937196938196939196940196941196942196943196944196945196946196947196948196949196950196951196952196953196954196955196956196957196958196959196960196961196962196963196964196965196966196967196968196969196970196971196972196973196974196975196976196977196978196979196980196981196982196983196984196985196986196987196988196989196990196991196992196993196994196995196996196997196998196999197000197001197002197003197004197005197006197007197008197009197010197011197012197013197014197015197016197017197018197019197020197021197022197023197024197025197026197027197028197029197030197031197032197033197034197035197036197037197038197039197040197041197042197043197044197045197046197047197048197049197050197051197052197053197054197055197056197057197058197059197060197061197062197063197064197065197066197067197068197069197070197071197072197073197074197075197076197077197078197079197080197081197082197083197084197085197086197087197088197089197090197091197092197093197094197095197096197097197098197099197100197101197102197103197104197105197106197107197108197109197110197111197112197113197114197115197116197117197118197119197120197121197122197123197124197125197126197127197128197129197130197131197132197133197134197135197136197137197138197139197140197141197142197143197144197145197146197147197148197149197150197151197152197153197154197155197156197157197158197159197160197161197162197163197164197165197166197167197168197169197170197171197172197173197174197175197176197177197178197179197180197181197182197183197184197185197186197187197188197189197190197191197192197193197194197195197196197197197198197199197200197201197202197203197204197205197206197207197208197209197210197211197212197213197214197215197216197217197218197219197220197221197222197223197224197225197226197227197228197229197230197231197232197233197234197235197236197237197238197239197240197241197242197243197244197245197246197247197248197249197250197251197252197253197254197255197256197257197258197259197260197261197262197263197264197265197266197267197268197269197270197271197272197273197274197275197276197277197278197279197280197281197282197283197284197285197286197287197288197289197290197291197292197293197294197295197296197297197298197299197300197301197302197303197304197305197306197307197308197309197310197311197312197313197314197315197316197317197318197319197320197321197322197323197324197325197326197327197328197329197330197331197332197333197334197335197336197337197338197339197340197341197342197343197344197345197346197347197348197349197350197351197352197353197354197355197356197357197358197359197360197361197362197363197364197365197366197367197368197369197370197371197372197373197374197375197376197377197378197379197380197381197382197383197384197385197386197387197388197389197390197391197392197393197394197395197396197397197398197399197400197401197402197403197404197405197406197407197408197409197410197411197412197413197414197415197416197417197418197419197420197421197422197423197424197425197426197427197428197429197430197431197432197433197434197435197436197437197438197439197440197441197442197443197444197445197446197447197448197449197450197451197452197453197454197455197456197457197458197459197460197461197462197463197464197465197466197467197468197469197470197471197472197473197474197475197476197477197478197479197480197481197482197483197484197485197486197487197488197489197490197491197492197493197494197495197496197497197498197499197500197501197502197503197504197505197506197507197508197509197510197511197512197513197514197515197516197517197518197519197520197521197522197523197524197525197526197527197528197529197530197531197532197533197534197535197536197537197538197539197540197541197542197543197544197545197546197547197548197549197550197551197552197553197554197555197556197557197558197559197560197561197562197563197564197565197566197567197568197569197570197571197572197573197574197575197576197577197578197579197580197581197582197583197584197585197586197587197588197589197590197591197592197593197594197595197596197597197598197599197600197601197602197603197604197605197606197607197608197609197610197611197612197613197614197615197616197617197618197619197620197621197622197623197624197625197626197627197628197629197630197631197632197633197634197635197636197637197638197639197640197641197642197643197644197645197646197647197648197649197650197651197652197653197654197655197656197657197658197659197660197661197662197663197664197665197666197667197668197669197670197671197672197673197674197675197676197677197678197679197680197681197682197683197684197685197686197687197688197689197690197691197692197693197694197695197696197697197698197699197700197701197702197703197704197705197706197707197708197709197710197711197712197713197714197715197716197717197718197719197720197721197722197723197724197725197726197727197728197729197730197731197732197733197734197735197736197737197738197739197740197741197742197743197744197745197746197747197748197749197750197751197752197753197754197755197756197757197758197759197760197761197762197763197764197765197766197767197768197769197770197771197772197773197774197775197776197777197778197779197780197781197782197783197784197785197786197787197788197789197790197791197792197793197794197795197796197797197798197799197800197801197802197803197804197805197806197807197808197809197810197811197812197813197814197815197816197817197818197819197820197821197822197823197824197825197826197827197828197829197830197831197832197833197834197835197836197837197838197839197840197841197842197843197844197845197846197847197848197849197850197851197852197853197854197855197856197857197858197859197860197861197862197863197864197865197866197867197868197869197870197871197872197873197874197875197876197877197878197879197880197881197882197883197884197885197886197887197888197889197890197891197892197893197894197895197896197897197898197899197900197901197902197903197904197905197906197907197908197909197910197911197912197913197914197915197916197917197918197919197920197921197922197923197924197925197926197927197928197929197930197931197932197933197934197935197936197937197938197939197940197941197942197943197944197945197946197947197948197949197950197951197952197953197954197955197956197957197958197959197960197961197962197963197964197965197966197967197968197969197970197971197972197973197974197975197976197977197978197979197980197981197982197983197984197985197986197987197988197989197990197991197992197993197994197995197996197997197998197999198000198001198002198003198004198005198006198007198008198009198010198011198012198013198014198015198016198017198018198019198020198021198022198023198024198025198026198027198028198029198030198031198032198033198034198035198036198037198038198039198040198041198042198043198044198045198046198047198048198049198050198051198052198053198054198055198056198057198058198059198060198061198062198063198064198065198066198067198068198069198070198071198072198073198074198075198076198077198078198079198080198081198082198083198084198085198086198087198088198089198090198091198092198093198094198095198096198097198098198099198100198101198102198103198104198105198106198107198108198109198110198111198112198113198114198115198116198117198118198119198120198121198122198123198124198125198126198127198128198129198130198131198132198133198134198135198136198137198138198139198140198141198142198143198144198145198146198147198148198149198150198151198152198153198154198155198156198157198158198159198160198161198162198163198164198165198166198167198168198169198170198171198172198173198174198175198176198177198178198179198180198181198182198183198184198185198186198187198188198189198190198191198192198193198194198195198196198197198198198199198200198201198202198203198204198205198206198207198208198209198210198211198212198213198214198215198216198217198218198219198220198221198222198223198224198225198226198227198228198229198230198231198232198233198234198235198236198237198238198239198240198241198242198243198244198245198246198247198248198249198250198251198252198253198254198255198256198257198258198259198260198261198262198263198264198265198266198267198268198269198270198271198272198273198274198275198276198277198278198279198280198281198282198283198284198285198286198287198288198289198290198291198292198293198294198295198296198297198298198299198300198301198302198303198304198305198306198307198308198309198310198311198312198313198314198315198316198317198318198319198320198321198322198323198324198325198326198327198328198329198330198331198332198333198334198335198336198337198338198339198340198341198342198343198344198345198346198347198348198349198350198351198352198353198354198355198356198357198358198359198360198361198362198363198364198365198366198367198368198369198370198371198372198373198374198375198376198377198378198379198380198381198382198383198384198385198386198387198388198389198390198391198392198393198394198395198396198397198398198399198400198401198402198403198404198405198406198407198408198409198410198411198412198413198414198415198416198417198418198419198420198421198422198423198424198425198426198427198428198429198430198431198432198433198434198435198436198437198438198439198440198441198442198443198444198445198446198447198448198449198450198451198452198453198454198455198456198457198458198459198460198461198462198463198464198465198466198467198468198469198470198471198472198473198474198475198476198477198478198479198480198481198482198483198484198485198486198487198488198489198490198491198492198493198494198495198496198497198498198499198500198501198502198503198504198505198506198507198508198509198510198511198512198513198514198515198516198517198518198519198520198521198522198523198524198525198526198527198528198529198530198531198532198533198534198535198536198537198538198539198540198541198542198543198544198545198546198547198548198549198550198551198552198553198554198555198556198557198558198559198560198561198562198563198564198565198566198567198568198569198570198571198572198573198574198575198576198577198578198579198580198581198582198583198584198585198586198587198588198589198590198591198592198593198594198595198596198597198598198599198600198601198602198603198604198605198606198607198608198609198610198611198612198613198614198615198616198617198618198619198620198621198622198623198624198625198626198627198628198629198630198631198632198633198634198635198636198637198638198639198640198641198642198643198644198645198646198647198648198649198650198651198652198653198654198655198656198657198658198659198660198661198662198663198664198665198666198667198668198669198670198671198672198673198674198675198676198677198678198679198680198681198682198683198684198685198686198687198688198689198690198691198692198693198694198695198696198697198698198699198700198701198702198703198704198705198706198707198708198709198710198711198712198713198714198715198716198717198718198719198720198721198722198723198724198725198726198727198728198729198730198731198732198733198734198735198736198737198738198739198740198741198742198743198744198745198746198747198748198749198750198751198752198753198754198755198756198757198758198759198760198761198762198763198764198765198766198767198768198769198770198771198772198773198774198775198776198777198778198779198780198781198782198783198784198785198786198787198788198789198790198791198792198793198794198795198796198797198798198799198800198801198802198803198804198805198806198807198808198809198810198811198812198813198814198815198816198817198818198819198820198821198822198823198824198825198826198827198828198829198830198831198832198833198834198835198836198837198838198839198840198841198842198843198844198845198846198847198848198849198850198851198852198853198854198855198856198857198858198859198860198861198862198863198864198865198866198867198868198869198870198871198872198873198874198875198876198877198878198879198880198881198882198883198884198885198886198887198888198889198890198891198892198893198894198895198896198897198898198899198900198901198902198903198904198905198906198907198908198909198910198911198912198913198914198915198916198917198918198919198920198921198922198923198924198925198926198927198928198929198930198931198932198933198934198935198936198937198938198939198940198941198942198943198944198945198946198947198948198949198950198951198952198953198954198955198956198957198958198959198960198961198962198963198964198965198966198967198968198969198970198971198972198973198974198975198976198977198978198979198980198981198982198983198984198985198986198987198988198989198990198991198992198993198994198995198996198997198998198999199000199001199002199003199004199005199006199007199008199009199010199011199012199013199014199015199016199017199018199019199020199021199022199023199024199025199026199027199028199029199030199031199032199033199034199035199036199037199038199039199040199041199042199043199044199045199046199047199048199049199050199051199052199053199054199055199056199057199058199059199060199061199062199063199064199065199066199067199068199069199070199071199072199073199074199075199076199077199078199079199080199081199082199083199084199085199086199087199088199089199090199091199092199093199094199095199096199097199098199099199100199101199102199103199104199105199106199107199108199109199110199111199112199113199114199115199116199117199118199119199120199121199122199123199124199125199126199127199128199129199130199131199132199133199134199135199136199137199138199139199140199141199142199143199144199145199146199147199148199149199150199151199152199153199154199155199156199157199158199159199160199161199162199163199164199165199166199167199168199169199170199171199172199173199174199175199176199177199178199179199180199181199182199183199184199185199186199187199188199189199190199191199192199193199194199195199196199197199198199199199200199201199202199203199204199205199206199207199208199209199210199211199212199213199214199215199216199217199218199219199220199221199222199223199224199225199226199227199228199229199230199231199232199233199234199235199236199237199238199239199240199241199242199243199244199245199246199247199248199249199250199251199252199253199254199255199256199257199258199259199260199261199262199263199264199265199266199267199268199269199270199271199272199273199274199275199276199277199278199279199280199281199282199283199284199285199286199287199288199289199290199291199292199293199294199295199296199297199298199299199300199301199302199303199304199305199306199307199308199309199310199311199312199313199314199315199316199317199318199319199320199321199322199323199324199325199326199327199328199329199330199331199332199333199334199335199336199337199338199339199340199341199342199343199344199345199346199347199348199349199350199351199352199353199354199355199356199357199358199359199360199361199362199363199364199365199366199367199368199369199370199371199372199373199374199375199376199377199378199379199380199381199382199383199384199385199386199387199388199389199390199391199392199393199394199395199396199397199398199399199400199401199402199403199404199405199406199407199408199409199410199411199412199413199414199415199416199417199418199419199420199421199422199423199424199425199426199427199428199429199430199431199432199433199434199435199436199437199438199439199440199441199442199443199444199445199446199447199448199449199450199451199452199453199454199455199456199457199458199459199460199461199462199463199464199465199466199467199468199469199470199471199472199473199474199475199476199477199478199479199480199481199482199483199484199485199486199487199488199489199490199491199492199493199494199495199496199497199498199499199500199501199502199503199504199505199506199507199508199509199510199511199512199513199514199515199516199517199518199519199520199521199522199523199524199525199526199527199528199529199530199531199532199533199534199535199536199537199538199539199540199541199542199543199544199545199546199547199548199549199550199551199552199553199554199555199556199557199558199559199560199561199562199563199564199565199566199567199568199569199570199571199572199573199574199575199576199577199578199579199580199581199582199583199584199585199586199587199588199589199590199591199592199593199594199595199596199597199598199599199600199601199602199603199604199605199606199607199608199609199610199611199612199613199614199615199616199617199618199619199620199621199622199623199624199625199626199627199628199629199630199631199632199633199634199635199636199637199638199639199640199641199642199643199644199645199646199647199648199649199650199651199652199653199654199655199656199657199658199659199660199661199662199663199664199665199666199667199668199669199670199671199672199673199674199675199676199677199678199679199680199681199682199683199684199685199686199687199688199689199690199691199692199693199694199695199696199697199698199699199700199701199702199703199704199705199706199707199708199709199710199711199712199713199714199715199716199717199718199719199720199721199722199723199724199725199726199727199728199729199730199731199732199733199734199735199736199737199738199739199740199741199742199743199744199745199746199747199748199749199750199751199752199753199754199755199756199757199758199759199760199761199762199763199764199765199766199767199768199769199770199771199772199773199774199775199776199777199778199779199780199781199782199783199784199785199786199787199788199789199790199791199792199793199794199795199796199797199798199799199800199801199802199803199804199805199806199807199808199809199810199811199812199813199814199815199816199817199818199819199820199821199822199823199824199825199826199827199828199829199830199831199832199833199834199835199836199837199838199839199840199841199842199843199844199845199846199847199848199849199850199851199852199853199854199855199856199857199858199859199860199861199862199863199864199865199866199867199868199869199870199871199872199873199874199875199876199877199878199879199880199881199882199883199884199885199886199887199888199889199890199891199892199893199894199895199896199897199898199899199900199901199902199903199904199905199906199907199908199909199910199911199912199913199914199915199916199917199918199919199920199921199922199923199924199925199926199927199928199929199930199931199932199933199934199935199936199937199938199939199940199941199942199943199944199945199946199947199948199949199950199951199952199953199954199955199956199957199958199959199960199961199962199963199964199965199966199967199968199969199970199971199972199973199974199975199976199977199978199979199980199981199982199983199984199985199986199987199988199989199990199991199992199993199994199995199996199997199998199999200000200001200002200003200004200005200006200007200008200009200010200011200012200013200014200015200016200017200018200019200020200021200022200023200024200025200026200027200028200029200030200031200032200033200034200035200036200037200038200039200040200041200042200043200044200045200046200047200048200049200050200051200052200053200054200055200056200057200058200059200060200061200062200063200064200065200066200067200068200069200070200071200072200073200074200075200076200077200078200079200080200081200082200083200084200085200086200087200088200089200090200091200092200093200094200095200096200097200098200099200100200101200102200103200104200105200106200107200108200109200110200111200112200113200114200115200116200117200118200119200120200121200122200123200124200125200126200127200128200129200130200131200132200133200134200135200136200137200138200139200140200141200142200143200144200145200146200147200148200149200150200151200152200153200154200155200156200157200158200159200160200161200162200163200164200165200166200167200168200169200170200171200172200173200174200175200176200177200178200179200180200181200182200183200184200185200186200187200188200189200190200191200192200193200194200195200196200197200198200199200200200201200202200203200204200205200206200207200208200209200210200211200212200213200214200215200216200217200218200219200220200221200222200223200224200225200226200227200228200229200230200231200232200233200234200235200236200237200238200239200240200241200242200243200244200245200246200247200248200249200250200251200252200253200254200255200256200257200258200259200260200261200262200263200264200265200266200267200268200269200270200271200272200273200274200275200276200277200278200279200280200281200282200283200284200285200286200287200288200289200290200291200292200293200294200295200296200297200298200299200300200301200302200303200304200305200306200307200308200309200310200311200312200313200314200315200316200317200318200319200320200321200322200323200324200325200326200327200328200329200330200331200332200333200334200335200336200337200338200339200340200341200342200343200344200345200346200347200348200349200350200351200352200353200354200355200356200357200358200359200360200361200362200363200364200365200366200367200368200369200370200371200372200373200374200375200376200377200378200379200380200381200382200383200384200385200386200387200388200389200390200391200392200393200394200395200396200397200398200399200400200401200402200403200404200405200406200407200408200409200410200411200412200413200414200415200416200417200418200419200420200421200422200423200424200425200426200427200428200429200430200431200432200433200434200435200436200437200438200439200440200441200442200443200444200445200446200447200448200449200450200451200452200453200454200455200456200457200458200459200460200461200462200463200464200465200466200467200468200469200470200471200472200473200474200475200476200477200478200479200480200481200482200483200484200485200486200487200488200489200490200491200492200493200494200495200496200497200498200499200500200501200502200503200504200505200506200507200508200509200510200511200512200513200514200515200516200517200518200519200520200521200522200523200524200525200526200527200528200529200530200531200532200533200534200535200536200537200538200539200540200541200542200543200544200545200546200547200548200549200550200551200552200553200554200555200556200557200558200559200560200561200562200563200564200565200566200567200568200569200570200571200572200573200574200575200576200577200578200579200580200581200582200583200584200585200586200587200588200589200590200591200592200593200594200595200596200597200598200599200600200601200602200603200604200605200606200607200608200609200610200611200612200613200614200615200616200617200618200619200620200621200622200623200624200625200626200627200628200629200630200631200632200633200634200635200636200637200638200639200640200641200642200643200644200645200646200647200648200649200650200651200652200653200654200655200656200657200658200659200660200661200662200663200664200665200666200667200668200669200670200671200672200673200674200675200676200677200678200679200680200681200682200683200684200685200686200687200688200689200690200691200692200693200694200695200696200697200698200699200700200701200702200703200704200705200706200707200708200709200710200711200712200713200714200715200716200717200718200719200720200721200722200723200724200725200726200727200728200729200730200731200732200733200734200735200736200737200738200739200740200741200742200743200744200745200746200747200748200749200750200751200752200753200754200755200756200757200758200759200760200761200762200763200764200765200766200767200768200769200770200771200772200773200774200775200776200777200778200779200780200781200782200783200784200785200786200787200788200789200790200791200792200793200794200795200796200797200798200799200800200801200802200803200804200805200806200807200808200809200810200811200812200813200814200815200816200817200818200819200820200821200822200823200824200825200826200827200828200829200830200831200832200833200834200835200836200837200838200839200840200841200842200843200844200845200846200847200848200849200850200851200852200853200854200855200856200857200858200859200860200861200862200863200864200865200866200867200868200869200870200871200872200873200874200875200876200877200878200879200880200881200882200883200884200885200886200887200888200889200890200891200892200893200894200895200896200897200898200899200900200901200902200903200904200905200906200907200908200909200910200911200912200913200914200915200916200917200918200919200920200921200922200923200924200925200926200927200928200929200930200931200932200933200934200935200936200937200938200939200940200941200942200943200944200945200946200947200948200949200950200951200952200953200954200955200956200957200958200959200960200961200962200963200964200965200966200967200968200969200970200971200972200973200974200975200976200977200978200979200980200981200982200983200984200985200986200987200988200989200990200991200992200993200994200995200996200997200998200999201000201001201002201003201004201005201006201007201008201009201010201011201012201013201014201015201016201017201018201019201020201021201022201023201024201025201026201027201028201029201030201031201032201033201034201035201036201037201038201039201040201041201042201043201044201045201046201047201048201049201050201051201052201053201054201055201056201057201058201059201060201061201062201063201064201065201066201067201068201069201070201071201072201073201074201075201076201077201078201079201080201081201082201083201084201085201086201087201088201089201090201091201092201093201094201095201096201097201098201099201100201101201102201103201104201105201106201107201108201109201110201111201112201113201114201115201116201117201118201119201120201121201122201123201124201125201126201127201128201129201130201131201132201133201134201135201136201137201138201139201140201141201142201143201144201145201146201147201148201149201150201151201152201153201154201155201156201157201158201159201160201161201162201163201164201165201166201167201168201169201170201171201172201173201174201175201176201177201178201179201180201181201182201183201184201185201186201187201188201189201190201191201192201193201194201195201196201197201198201199201200201201201202201203201204201205201206201207201208201209201210201211201212201213201214201215201216201217201218201219201220201221201222201223201224201225201226201227201228201229201230201231201232201233201234201235201236201237201238201239201240201241201242201243201244201245201246201247201248201249201250201251201252201253201254201255201256201257201258201259201260201261201262201263201264201265201266201267201268201269201270201271201272201273201274201275201276201277201278201279201280201281201282201283201284201285201286201287201288201289201290201291201292201293201294201295201296201297201298201299201300201301201302201303201304201305201306201307201308201309201310201311201312201313201314201315201316201317201318201319201320201321201322201323201324201325201326201327201328201329201330201331201332201333201334201335201336201337201338201339201340201341201342201343201344201345201346201347201348201349201350201351201352201353201354201355201356201357201358201359201360201361201362201363201364201365201366201367201368201369201370201371201372201373201374201375201376201377201378201379201380201381201382201383201384201385201386201387201388201389201390201391201392201393201394201395201396201397201398201399201400201401201402201403201404201405201406201407201408201409201410201411201412201413201414201415201416201417201418201419201420201421201422201423201424201425201426201427201428201429201430201431201432201433201434201435201436201437201438201439201440201441201442201443201444201445201446201447201448201449201450201451201452201453201454201455201456201457201458201459201460201461201462201463201464201465201466201467201468201469201470201471201472201473201474201475201476201477201478201479201480201481201482201483201484201485201486201487201488201489201490201491201492201493201494201495201496201497201498201499201500201501201502201503201504201505201506201507201508201509201510201511201512201513201514201515201516201517201518201519201520201521201522201523201524201525201526201527201528201529201530201531201532201533201534201535201536201537201538201539201540201541201542201543201544201545201546201547201548201549201550201551201552201553201554201555201556201557201558201559201560201561201562201563201564201565201566201567201568201569201570201571201572201573201574201575201576201577201578201579201580201581201582201583201584201585201586201587201588201589201590201591201592201593201594201595201596201597201598201599201600201601201602201603201604201605201606201607201608201609201610201611201612201613201614201615201616201617201618201619201620201621201622201623201624201625201626201627201628201629201630201631201632201633201634201635201636201637201638201639201640201641201642201643201644201645201646201647201648201649201650201651201652201653201654201655201656201657201658201659201660201661201662201663201664201665201666201667201668201669201670201671201672201673201674201675201676201677201678201679201680201681201682201683201684201685201686201687201688201689201690201691201692201693201694201695201696201697201698201699201700201701201702201703201704201705201706201707201708201709201710201711201712201713201714201715201716201717201718201719201720201721201722201723201724201725201726201727201728201729201730201731201732201733201734201735201736201737201738201739201740201741201742201743201744201745201746201747201748201749201750201751201752201753201754201755201756201757201758201759201760201761201762201763201764201765201766201767201768201769201770201771201772201773201774201775201776201777201778201779201780201781201782201783201784201785201786201787201788201789201790201791201792201793201794201795201796201797201798201799201800201801201802201803201804201805201806201807201808201809201810201811201812201813201814201815201816201817201818201819201820201821201822201823201824201825201826201827201828201829201830201831201832201833201834201835201836201837201838201839201840201841201842201843201844201845201846201847201848201849201850201851201852201853201854201855201856201857201858201859201860201861201862201863201864201865201866201867201868201869201870201871201872201873201874201875201876201877201878201879201880201881201882201883201884201885201886201887201888201889201890201891201892201893201894201895201896201897201898201899201900201901201902201903201904201905201906201907201908201909201910201911201912201913201914201915201916201917201918201919201920201921201922201923201924201925201926201927201928201929201930201931201932201933201934201935201936201937201938201939201940201941201942201943201944201945201946201947201948201949201950201951201952201953201954201955201956201957201958201959201960201961201962201963201964201965201966201967201968201969201970201971201972201973201974201975201976201977201978201979201980201981201982201983201984201985201986201987201988201989201990201991201992201993201994201995201996201997201998201999202000202001202002202003202004202005202006202007202008202009202010202011202012202013202014202015202016202017202018202019202020202021202022202023202024202025202026202027202028202029202030202031202032202033202034202035202036202037202038202039202040202041202042202043202044202045202046202047202048202049202050202051202052202053202054202055202056202057202058202059202060202061202062202063202064202065202066202067202068202069202070202071202072202073202074202075202076202077202078202079202080202081202082202083202084202085202086202087202088202089202090202091202092202093202094202095202096202097202098202099202100202101202102202103202104202105202106202107202108202109202110202111202112202113202114202115202116202117202118202119202120202121202122202123202124202125202126202127202128202129202130202131202132202133202134202135202136202137202138202139202140202141202142202143202144202145202146202147202148202149202150202151202152202153202154202155202156202157202158202159202160202161202162202163202164202165202166202167202168202169202170202171202172202173202174202175202176202177202178202179202180202181202182202183202184202185202186202187202188202189202190202191202192202193202194202195202196202197202198202199202200202201202202202203202204202205202206202207202208202209202210202211202212202213202214202215202216202217202218202219202220202221202222202223202224202225202226202227202228202229202230202231202232202233202234202235202236202237202238202239202240202241202242202243202244202245202246202247202248202249202250202251202252202253202254202255202256202257202258202259202260202261202262202263202264202265202266202267202268202269202270202271202272202273202274202275202276202277202278202279202280202281202282202283202284202285202286202287202288202289202290202291202292202293202294202295202296202297202298202299202300202301202302202303202304202305202306202307202308202309202310202311202312202313202314202315202316202317202318202319202320202321202322202323202324202325202326202327202328202329202330202331202332202333202334202335202336202337202338202339202340202341202342202343202344202345202346202347202348202349202350202351202352202353202354202355202356202357202358202359202360202361202362202363202364202365202366202367202368202369202370202371202372202373202374202375202376202377202378202379202380202381202382202383202384202385202386202387202388202389202390202391202392202393202394202395202396202397202398202399202400202401202402202403202404202405202406202407202408202409202410202411202412202413202414202415202416202417202418202419202420202421202422202423202424202425202426202427202428202429202430202431202432202433202434202435202436202437202438202439202440202441202442202443202444202445202446202447202448202449202450202451202452202453202454202455202456202457202458202459202460202461202462202463202464202465202466202467202468202469202470202471202472202473202474202475202476202477202478202479202480202481202482202483202484202485202486202487202488202489202490202491202492202493202494202495202496202497202498202499202500202501202502202503202504202505202506202507202508202509202510202511202512202513202514202515202516202517202518202519202520202521202522202523202524202525202526202527202528202529202530202531202532202533202534202535202536202537202538202539202540202541202542202543202544202545202546202547202548202549202550202551202552202553202554202555202556202557202558202559202560202561202562202563202564202565202566202567202568202569202570202571202572202573202574202575202576202577202578202579202580202581202582202583202584202585202586202587202588202589202590202591202592202593202594202595202596202597202598202599202600202601202602202603202604202605202606202607202608202609202610202611202612202613202614202615202616202617202618202619202620202621202622202623202624202625202626202627202628202629202630202631202632202633202634202635202636202637202638202639202640202641202642202643202644202645202646202647202648202649202650202651202652202653202654202655202656202657202658202659202660202661202662202663202664202665202666202667202668202669202670202671202672202673202674202675202676202677202678202679202680202681202682202683202684202685202686202687202688202689202690202691202692202693202694202695202696202697202698202699202700202701202702202703202704202705202706202707202708202709202710202711202712202713202714202715202716202717202718202719202720202721202722202723202724202725202726202727202728202729202730202731202732202733202734202735202736202737202738202739202740202741202742202743202744202745202746202747202748202749202750202751202752202753202754202755202756202757202758202759202760202761202762202763202764202765202766202767202768202769202770202771202772202773202774202775202776202777202778202779202780202781202782202783202784202785202786202787202788202789202790202791202792202793202794202795202796202797202798202799202800202801202802202803202804202805202806202807202808202809202810202811202812202813202814202815202816202817202818202819202820202821202822202823202824202825202826202827202828202829202830202831202832202833202834202835202836202837202838202839202840202841202842202843202844202845202846202847202848202849202850202851202852202853202854202855202856202857202858202859202860202861202862202863202864202865202866202867202868202869202870202871202872202873202874202875202876202877202878202879202880202881202882202883202884202885202886202887202888202889202890202891202892202893202894202895202896202897202898202899202900202901202902202903202904202905202906202907202908202909202910202911202912202913202914202915202916202917202918202919202920202921202922202923202924202925202926202927202928202929202930202931202932202933202934202935202936202937202938202939202940202941202942202943202944202945202946202947202948202949202950202951202952202953202954202955202956202957202958202959202960202961202962202963202964202965202966202967202968202969202970202971202972202973202974202975202976202977202978202979202980202981202982202983202984202985202986202987202988202989202990202991202992202993202994202995202996202997202998202999203000203001203002203003203004203005203006203007203008203009203010203011203012203013203014203015203016203017203018203019203020203021203022203023203024203025203026203027203028203029203030203031203032203033203034203035203036203037203038203039203040203041203042203043203044203045203046203047203048203049203050203051203052203053203054203055203056203057203058203059203060203061203062203063203064203065203066203067203068203069203070203071203072203073203074203075203076203077203078203079203080203081203082203083203084203085203086203087203088203089203090203091203092203093203094203095203096203097203098203099203100203101203102203103203104203105203106203107203108203109203110203111203112203113203114203115203116203117203118203119203120203121203122203123203124203125203126203127203128203129203130203131203132203133203134203135203136203137203138203139203140203141203142203143203144203145203146203147203148203149203150203151203152203153203154203155203156203157203158203159203160203161203162203163203164203165203166203167203168203169203170203171203172203173203174203175203176203177203178203179203180203181203182203183203184203185203186203187203188203189203190203191203192203193203194203195203196203197203198203199203200203201203202203203203204203205203206203207203208203209203210203211203212203213203214203215203216203217203218203219203220203221203222203223203224203225203226203227203228203229203230203231203232203233203234203235203236203237203238203239203240203241203242203243203244203245203246203247203248203249203250203251203252203253203254203255203256203257203258203259203260203261203262203263203264203265203266203267203268203269203270203271203272203273203274203275203276203277203278203279203280203281203282203283203284203285203286203287203288203289203290203291203292203293203294203295203296203297203298203299203300203301203302203303203304203305203306203307203308203309203310203311203312203313203314203315203316203317203318203319203320203321203322203323203324203325203326203327203328203329203330203331203332203333203334203335203336203337203338203339203340203341203342203343203344203345203346203347203348203349203350203351203352203353203354203355203356203357203358203359203360203361203362203363203364203365203366203367203368203369203370203371203372203373203374203375203376203377203378203379203380203381203382203383203384203385203386203387203388203389203390203391203392203393203394203395203396203397203398203399203400203401203402203403203404203405203406203407203408203409203410203411203412203413203414203415203416203417203418203419203420203421203422203423203424203425203426203427203428203429203430203431203432203433203434203435203436203437203438203439203440203441203442203443203444203445203446203447203448203449203450203451203452203453203454203455203456203457203458203459203460203461203462203463203464203465203466203467203468203469203470203471203472203473203474203475203476203477203478203479203480203481203482203483203484203485203486203487203488203489203490203491203492203493203494203495203496203497203498203499203500203501203502203503203504203505203506203507203508203509203510203511203512203513203514203515203516203517203518203519203520203521203522203523203524203525203526203527203528203529203530203531203532203533203534203535203536203537203538203539203540203541203542203543203544203545203546203547203548203549203550203551203552203553203554203555203556203557203558203559203560203561203562203563203564203565203566203567203568203569203570203571203572203573203574203575203576203577203578203579203580203581203582203583203584203585203586203587203588203589203590203591203592203593203594203595203596203597203598203599203600203601203602203603203604203605203606203607203608203609203610203611203612203613203614203615203616203617203618203619203620203621203622203623203624203625203626203627203628203629203630203631203632203633203634203635203636203637203638203639203640203641203642203643203644203645203646203647203648203649203650203651203652203653203654203655203656203657203658203659203660203661203662203663203664203665203666203667203668203669203670203671203672203673203674203675203676203677203678203679203680203681203682203683203684203685203686203687203688203689203690203691203692203693203694203695203696203697203698203699203700203701203702203703203704203705203706203707203708203709203710203711203712203713203714203715203716203717203718203719203720203721203722203723203724203725203726203727203728203729203730203731203732203733203734203735203736203737203738203739203740203741203742203743203744203745203746203747203748203749203750203751203752203753203754203755203756203757203758203759203760203761203762203763203764203765203766203767203768203769203770203771203772203773203774203775203776203777203778203779203780203781203782203783203784203785203786203787203788203789203790203791203792203793203794203795203796203797203798203799203800203801203802203803203804203805203806203807203808203809203810203811203812203813203814203815203816203817203818203819203820203821203822203823203824203825203826203827203828203829203830203831203832203833203834203835203836203837203838203839203840203841203842203843203844203845203846203847203848203849203850203851203852203853203854203855203856203857203858203859203860203861203862203863203864203865203866203867203868203869203870203871203872203873203874203875203876203877203878203879203880203881203882203883203884203885203886203887203888203889203890203891203892203893203894203895203896203897203898203899203900203901203902203903203904203905203906203907203908203909203910203911203912203913203914203915203916203917203918203919203920203921203922203923203924203925203926203927203928203929203930203931203932203933203934203935203936203937203938203939203940203941203942203943203944203945203946203947203948203949203950203951203952203953203954203955203956203957203958203959203960203961203962203963203964203965203966203967203968203969203970203971203972203973203974203975203976203977203978203979203980203981203982203983203984203985203986203987203988203989203990203991203992203993203994203995203996203997203998203999204000204001204002204003204004204005204006204007204008204009204010204011204012204013204014204015204016204017204018204019204020204021204022204023204024204025204026204027204028204029204030204031204032204033204034204035204036204037204038204039204040204041204042204043204044204045204046204047204048204049204050204051204052204053204054204055204056204057204058204059204060204061204062204063204064204065204066204067204068204069204070204071204072204073204074204075204076204077204078204079204080204081204082204083204084204085204086204087204088204089204090204091204092204093204094204095204096204097204098204099204100204101204102204103204104204105204106204107204108204109204110204111204112204113204114204115204116204117204118204119204120204121204122204123204124204125204126204127204128204129204130204131204132204133204134204135204136204137204138204139204140204141204142204143204144204145204146204147204148204149204150204151204152204153204154204155204156204157204158204159204160204161204162204163204164204165204166204167204168204169204170204171204172204173204174204175204176204177204178204179204180204181204182204183204184204185204186204187204188204189204190204191204192204193204194204195204196204197204198204199204200204201204202204203204204204205204206204207204208204209204210204211204212204213204214204215204216204217204218204219204220204221204222204223204224204225204226204227204228204229204230204231204232204233204234204235204236204237204238204239204240204241204242204243204244204245204246204247204248204249204250204251204252204253204254204255204256204257204258204259204260204261204262204263204264204265204266204267204268204269204270204271204272204273204274204275204276204277204278204279204280204281204282204283204284204285204286204287204288204289204290204291204292204293204294204295204296204297204298204299204300204301204302204303204304204305204306204307204308204309204310204311204312204313204314204315204316204317204318204319204320204321204322204323204324204325204326204327204328204329204330204331204332204333204334204335204336204337204338204339204340204341204342204343204344204345204346204347204348204349204350204351204352204353204354204355204356204357204358204359204360204361204362204363204364204365204366204367204368204369204370204371204372204373204374204375204376204377204378204379204380204381204382204383204384204385204386204387204388204389204390204391204392204393204394204395204396204397204398204399204400204401204402204403204404204405204406204407204408204409204410204411204412204413204414204415204416204417204418204419204420204421204422204423204424204425204426204427204428204429204430204431204432204433204434204435204436204437204438204439204440204441204442204443204444204445204446204447204448204449204450204451204452204453204454204455204456204457204458204459204460204461204462204463204464204465204466204467204468204469204470204471204472204473204474204475204476204477204478204479204480204481204482204483204484204485204486204487204488204489204490204491204492204493204494204495204496204497204498204499204500204501204502204503204504204505204506204507204508204509204510204511204512204513204514204515204516204517204518204519204520204521204522204523204524204525204526204527204528204529204530204531204532204533204534204535204536204537204538204539204540204541204542204543204544204545204546204547204548204549204550204551204552204553204554204555204556204557204558204559204560204561204562204563204564204565204566204567204568204569204570204571204572204573204574204575204576204577204578204579204580204581204582204583204584204585204586204587204588204589204590204591204592204593204594204595204596204597204598204599204600204601204602204603204604204605204606204607204608204609204610204611204612204613204614204615204616204617204618204619204620204621204622204623204624204625204626204627204628204629204630204631204632204633204634204635204636204637204638204639204640204641204642204643204644204645204646204647204648204649204650204651204652204653204654204655204656204657204658204659204660204661204662204663204664204665204666204667204668204669204670204671204672204673204674204675204676204677204678204679204680204681204682204683204684204685204686204687204688204689204690204691204692204693204694204695204696204697204698204699204700204701204702204703204704204705204706204707204708204709204710204711204712204713204714204715204716204717204718204719204720204721204722204723204724204725204726204727204728204729204730204731204732204733204734204735204736204737204738204739204740204741204742204743204744204745204746204747204748204749204750204751204752204753204754204755204756204757204758204759204760204761204762204763204764204765204766204767204768204769204770204771204772204773204774204775204776204777204778204779204780204781204782204783204784204785204786204787204788204789204790204791204792204793204794204795204796204797204798204799204800204801204802204803204804204805204806204807204808204809204810204811204812204813204814204815204816204817204818204819204820204821204822204823204824204825204826204827204828204829204830204831204832204833204834204835204836204837204838204839204840204841204842204843204844204845204846204847204848204849204850204851204852204853204854204855204856204857204858204859204860204861204862204863204864204865204866204867204868204869204870204871204872204873204874204875204876204877204878204879204880204881204882204883204884204885204886204887204888204889204890204891204892204893204894204895204896204897204898204899204900204901204902204903204904204905204906204907204908204909204910204911204912204913204914204915204916204917204918204919204920204921204922204923204924204925204926204927204928204929204930204931204932204933204934204935204936204937204938204939204940204941204942204943204944204945204946204947204948204949204950204951204952204953204954204955204956204957204958204959204960204961204962204963204964204965204966204967204968204969204970204971204972204973204974204975204976204977204978204979204980204981204982204983204984204985204986204987204988204989204990204991204992204993204994204995204996204997204998204999205000205001205002205003205004205005205006205007205008205009205010205011205012205013205014205015205016205017205018205019205020205021205022205023205024205025205026205027205028205029205030205031205032205033205034205035205036205037205038205039205040205041205042205043205044205045205046205047205048205049205050205051205052205053205054205055205056205057205058205059205060205061205062205063205064205065205066205067205068205069205070205071205072205073205074205075205076205077205078205079205080205081205082205083205084205085205086205087205088205089205090205091205092205093205094205095205096205097205098205099205100205101205102205103205104205105205106205107205108205109205110205111205112205113205114205115205116205117205118205119205120205121205122205123205124205125205126205127205128205129205130205131205132205133205134205135205136205137205138205139205140205141205142205143205144205145205146205147205148205149205150205151205152205153205154205155205156205157205158205159205160205161205162205163205164205165205166205167205168205169205170205171205172205173205174205175205176205177205178205179205180205181205182205183205184205185205186205187205188205189205190205191205192205193205194205195205196205197205198205199205200205201205202205203205204205205205206205207205208205209205210205211205212205213205214205215205216205217205218205219205220205221205222205223205224205225205226205227205228205229205230205231205232205233205234205235205236205237205238205239205240205241205242205243205244205245205246205247205248205249205250205251205252205253205254205255205256205257205258205259205260205261205262205263205264205265205266205267205268205269205270205271205272205273205274205275205276205277205278205279205280205281205282205283205284205285205286205287205288205289205290205291205292205293205294205295205296205297205298205299205300205301205302205303205304205305205306205307205308205309205310205311205312205313205314205315205316205317205318205319205320205321205322205323205324205325205326205327205328205329205330205331205332205333205334205335205336205337205338205339205340205341205342205343205344205345205346205347205348205349205350205351205352205353205354205355205356205357205358205359205360205361205362205363205364205365205366205367205368205369205370205371205372205373205374205375205376205377205378205379205380205381205382205383205384205385205386205387205388205389205390205391205392205393205394205395205396205397205398205399205400205401205402205403205404205405205406205407205408205409205410205411205412205413205414205415205416205417205418205419205420205421205422205423205424205425205426205427205428205429205430205431205432205433205434205435205436205437205438205439205440205441205442205443205444205445205446205447205448205449205450205451205452205453205454205455205456205457205458205459205460205461205462205463205464205465205466205467205468205469205470205471205472205473205474205475205476205477205478205479205480205481205482205483205484205485205486205487205488205489205490205491205492205493205494205495205496205497205498205499205500205501205502205503205504205505205506205507205508205509205510205511205512205513205514205515205516205517205518205519205520205521205522205523205524205525205526205527205528205529205530205531205532205533205534205535205536205537205538205539205540205541205542205543205544205545205546205547205548205549205550205551205552205553205554205555205556205557205558205559205560205561205562205563205564205565205566205567205568205569205570205571205572205573205574205575205576205577205578205579205580205581205582205583205584205585205586205587205588205589205590205591205592205593205594205595205596205597205598205599205600205601205602205603205604205605205606205607205608205609205610205611205612205613205614205615205616205617205618205619205620205621205622205623205624205625205626205627205628205629205630205631205632205633205634205635205636205637205638205639205640205641205642205643205644205645205646205647205648205649205650205651205652205653205654205655205656205657205658205659205660205661205662205663205664205665205666205667205668205669205670205671205672205673205674205675205676205677205678205679205680205681205682205683205684205685205686205687205688205689205690205691205692205693205694205695205696205697205698205699205700205701205702205703205704205705205706205707205708205709205710205711205712205713205714205715205716205717205718205719205720205721205722205723205724205725205726205727205728205729205730205731205732205733205734205735205736205737205738205739205740205741205742205743205744205745205746205747205748205749205750205751205752205753205754205755205756205757205758205759205760205761205762205763205764205765205766205767205768205769205770205771205772205773205774205775205776205777205778205779205780205781205782205783205784205785205786205787205788205789205790205791205792205793205794205795205796205797205798205799205800205801205802205803205804205805205806205807205808205809205810205811205812205813205814205815205816205817205818205819205820205821205822205823205824205825205826205827205828205829205830205831205832205833205834205835205836205837205838205839205840205841205842205843205844205845205846205847205848205849205850205851205852205853205854205855205856205857205858205859205860205861205862205863205864205865205866205867205868205869205870205871205872205873205874205875205876205877205878205879205880205881205882205883205884205885205886205887205888205889205890205891205892205893205894205895205896205897205898205899205900205901205902205903205904205905205906205907205908205909205910205911205912205913205914205915205916205917205918205919205920205921205922205923205924205925205926205927205928205929205930205931205932205933205934205935205936205937205938205939205940205941205942205943205944205945205946205947205948205949205950205951205952205953205954205955205956205957205958205959205960205961205962205963205964205965205966205967205968205969205970205971205972205973205974205975205976205977205978205979205980205981205982205983205984205985205986205987205988205989205990205991205992205993205994205995205996205997205998205999206000206001206002206003206004206005206006206007206008206009206010206011206012206013206014206015206016206017206018206019206020206021206022206023206024206025206026206027206028206029206030206031206032206033206034206035206036206037206038206039206040206041206042206043206044206045206046206047206048206049206050206051206052206053206054206055206056206057206058206059206060206061206062206063206064206065206066206067206068206069206070206071206072206073206074206075206076206077206078206079206080206081206082206083206084206085206086206087206088206089206090206091206092206093206094206095206096206097206098206099206100206101206102206103206104206105206106206107206108206109206110206111206112206113206114206115206116206117206118206119206120206121206122206123206124206125206126206127206128206129206130206131206132206133206134206135206136206137206138206139206140206141206142206143206144206145206146206147206148206149206150206151206152206153206154206155206156206157206158206159206160206161206162206163206164206165206166206167206168206169206170206171206172206173206174206175206176206177206178206179206180206181206182206183206184206185206186206187206188206189206190206191206192206193206194206195206196206197206198206199206200206201206202206203206204206205206206206207206208206209206210206211206212206213206214206215206216206217206218206219206220206221206222206223206224206225206226206227206228206229206230206231206232206233206234206235206236206237206238206239206240206241206242206243206244206245206246206247206248206249206250206251206252206253206254206255206256206257206258206259206260206261206262206263206264206265206266206267206268206269206270206271206272206273206274206275206276206277206278206279206280206281206282206283206284206285206286206287206288206289206290206291206292206293206294206295206296206297206298206299206300206301206302206303206304206305206306206307206308206309206310206311206312206313206314206315206316206317206318206319206320206321206322206323206324206325206326206327206328206329206330206331206332206333206334206335206336206337206338206339206340206341206342206343206344206345206346206347206348206349206350206351206352206353206354206355206356206357206358206359206360206361206362206363206364206365206366206367206368206369206370206371206372206373206374206375206376206377206378206379206380206381206382206383206384206385206386206387206388206389206390206391206392206393206394206395206396206397206398206399206400206401206402206403206404206405206406206407206408206409206410206411206412206413206414206415206416206417206418206419206420206421206422206423206424206425206426206427206428206429206430206431206432206433206434206435206436206437206438206439206440206441206442206443206444206445206446206447206448206449206450206451206452206453206454206455206456206457206458206459206460206461206462206463206464206465206466206467206468206469206470206471206472206473206474206475206476206477206478206479206480206481206482206483206484206485206486206487206488206489206490206491206492206493206494206495206496206497206498206499206500206501206502206503206504206505206506206507206508206509206510206511206512206513206514206515206516206517206518206519206520206521206522206523206524206525206526206527206528206529206530206531206532206533206534206535206536206537206538206539206540206541206542206543206544206545206546206547206548206549206550206551206552206553206554206555206556206557206558206559206560206561206562206563206564206565206566206567206568206569206570206571206572206573206574206575206576206577206578206579206580206581206582206583206584206585206586206587206588206589206590206591206592206593206594206595206596206597206598206599206600206601206602206603206604206605206606206607206608206609206610206611206612206613206614206615206616206617206618206619206620206621206622206623206624206625206626206627206628206629206630206631206632206633206634206635206636206637206638206639206640206641206642206643206644206645206646206647206648206649206650206651206652206653206654206655206656206657206658206659206660206661206662206663206664206665206666206667206668206669206670206671206672206673206674206675206676206677206678206679206680206681206682206683206684206685206686206687206688206689206690206691206692206693206694206695206696206697206698206699206700206701206702206703206704206705206706206707206708206709206710206711206712206713206714206715206716206717206718206719206720206721206722206723206724206725206726206727206728206729206730206731206732206733206734206735206736206737206738206739206740206741206742206743206744206745206746206747206748206749206750206751206752206753206754206755206756206757206758206759206760206761206762206763206764206765206766206767206768206769206770206771206772206773206774206775206776206777206778206779206780206781206782206783206784206785206786206787206788206789206790206791206792206793206794206795206796206797206798206799206800206801206802206803206804206805206806206807206808206809206810206811206812206813206814206815206816206817206818206819206820206821206822206823206824206825206826206827206828206829206830206831206832206833206834206835206836206837206838206839206840206841206842206843206844206845206846206847206848206849206850206851206852206853206854206855206856206857206858206859206860206861206862206863206864206865206866206867206868206869206870206871206872206873206874206875206876206877206878206879206880206881206882206883206884206885206886206887206888206889206890206891206892206893206894206895206896206897206898206899206900206901206902206903206904206905206906206907206908206909206910206911206912206913206914206915206916206917206918206919206920206921206922206923206924206925206926206927206928206929206930206931206932206933206934206935206936206937206938206939206940206941206942206943206944206945206946206947206948206949206950206951206952206953206954206955206956206957206958206959206960206961206962206963206964206965206966206967206968206969206970206971206972206973206974206975206976206977206978206979206980206981206982206983206984206985206986206987206988206989206990206991206992206993206994206995206996206997206998206999207000207001207002207003207004207005207006207007207008207009207010207011207012207013207014207015207016207017207018207019207020207021207022207023207024207025207026207027207028207029207030207031207032207033207034207035207036207037207038207039207040207041207042207043207044207045207046207047207048207049207050207051207052207053207054207055207056207057207058207059207060207061207062207063207064207065207066207067207068207069207070207071207072207073207074207075207076207077207078207079207080207081207082207083207084207085207086207087207088207089207090207091207092207093207094207095207096207097207098207099207100207101207102207103207104207105207106207107207108207109207110207111207112207113207114207115207116207117207118207119207120207121207122207123207124207125207126207127207128207129207130207131207132207133207134207135207136207137207138207139207140207141207142207143207144207145207146207147207148207149207150207151207152207153207154207155207156207157207158207159207160207161207162207163207164207165207166207167207168207169207170207171207172207173207174207175207176207177207178207179207180207181207182207183207184207185207186207187207188207189207190207191207192207193207194207195207196207197207198207199207200207201207202207203207204207205207206207207207208207209207210207211207212207213207214207215207216207217207218207219207220207221207222207223207224207225207226207227207228207229207230207231207232207233207234207235207236207237207238207239207240207241207242207243207244207245207246207247207248207249207250207251207252207253207254207255207256207257207258207259207260207261207262207263207264207265207266207267207268207269207270207271207272207273207274207275207276207277207278207279207280207281207282207283207284207285207286207287207288207289207290207291207292207293207294207295207296207297207298207299207300207301207302207303207304207305207306207307207308207309207310207311207312207313207314207315207316207317207318207319207320207321207322207323207324207325207326207327207328207329207330207331207332207333207334207335207336207337207338207339207340207341207342207343207344207345207346207347207348207349207350207351207352207353207354207355207356207357207358207359207360207361207362207363207364207365207366207367207368207369207370207371207372207373207374207375207376207377207378207379207380207381207382207383207384207385207386207387207388207389207390207391207392207393207394207395207396207397207398207399207400207401207402207403207404207405207406207407207408207409207410207411207412207413207414207415207416207417207418207419207420207421207422207423207424207425207426207427207428207429207430207431207432207433207434207435207436207437207438207439207440207441207442207443207444207445207446207447207448207449207450207451207452207453207454207455207456207457207458207459207460207461207462207463207464207465207466207467207468207469207470207471207472207473207474207475207476207477207478207479207480207481207482207483207484207485207486207487207488207489207490207491207492207493207494207495207496207497207498207499207500207501207502207503207504207505207506207507207508207509207510207511207512207513207514207515207516207517207518207519207520207521207522207523207524207525207526207527207528207529207530207531207532207533207534207535207536207537207538207539207540207541207542207543207544207545207546207547207548207549207550207551207552207553207554207555207556207557207558207559207560207561207562207563207564207565207566207567207568207569207570207571207572207573207574207575207576207577207578207579207580207581207582207583207584207585207586207587207588207589207590207591207592207593207594207595207596207597207598207599207600207601207602207603207604207605207606207607207608207609207610207611207612207613207614207615207616207617207618207619207620207621207622207623207624207625207626207627207628207629207630207631207632207633207634207635207636207637207638207639207640207641207642207643207644207645207646207647207648207649207650207651207652207653207654207655207656207657207658207659207660207661207662207663207664207665207666207667207668207669207670207671207672207673207674207675207676207677207678207679207680207681207682207683207684207685207686207687207688207689207690207691207692207693207694207695207696207697207698207699207700207701207702207703207704207705207706207707207708207709207710207711207712207713207714207715207716207717207718207719207720207721207722207723207724207725207726207727207728207729207730207731207732207733207734207735207736207737207738207739207740207741207742207743207744207745207746207747207748207749207750207751207752207753207754207755207756207757207758207759207760207761207762207763207764207765207766207767207768207769207770207771207772207773207774207775207776207777207778207779207780207781207782207783207784207785207786207787207788207789207790207791207792207793207794207795207796207797207798207799207800207801207802207803207804207805207806207807207808207809207810207811207812207813207814207815207816207817207818207819207820207821207822207823207824207825207826207827207828207829207830207831207832207833207834207835207836207837207838207839207840207841207842207843207844207845207846207847207848207849207850207851207852207853207854207855207856207857207858207859207860207861207862207863207864207865207866207867207868207869207870207871207872207873207874207875207876207877207878207879207880207881207882207883207884207885207886207887207888207889207890207891207892207893207894207895207896207897207898207899207900207901207902207903207904207905207906207907207908207909207910207911207912207913207914207915207916207917207918207919207920207921207922207923207924207925207926207927207928207929207930207931207932207933207934207935207936207937207938207939207940207941207942207943207944207945207946207947207948207949207950207951207952207953207954207955207956207957207958207959207960207961207962207963207964207965207966207967207968207969207970207971207972207973207974207975207976207977207978207979207980207981207982207983207984207985207986207987207988207989207990207991207992207993207994207995207996207997207998207999208000208001208002208003208004208005208006208007208008208009208010208011208012208013208014208015208016208017208018208019208020208021208022208023208024208025208026208027208028208029208030208031208032208033208034208035208036208037208038208039208040208041208042208043208044208045208046208047208048208049208050208051208052208053208054208055208056208057208058208059208060208061208062208063208064208065208066208067208068208069208070208071208072208073208074208075208076208077208078208079208080208081208082208083208084208085208086208087208088208089208090208091208092208093208094208095208096208097208098208099208100208101208102208103208104208105208106208107208108208109208110208111208112208113208114208115208116208117208118208119208120208121208122208123208124208125208126208127208128208129208130208131208132208133208134208135208136208137208138208139208140208141208142208143208144208145208146208147208148208149208150208151208152208153208154208155208156208157208158208159208160208161208162208163208164208165208166208167208168208169208170208171208172208173208174208175208176208177208178208179208180208181208182208183208184208185208186208187208188208189208190208191208192208193208194208195208196208197208198208199208200208201208202208203208204208205208206208207208208208209208210208211208212208213208214208215208216208217208218208219208220208221208222208223208224208225208226208227208228208229208230208231208232208233208234208235208236208237208238208239208240208241208242208243208244208245208246208247208248208249208250208251208252208253208254208255208256208257208258208259208260208261208262208263208264208265208266208267208268208269208270208271208272208273208274208275208276208277208278208279208280208281208282208283208284208285208286208287208288208289208290208291208292208293208294208295208296208297208298208299208300208301208302208303208304208305208306208307208308208309208310208311208312208313208314208315208316208317208318208319208320208321208322208323208324208325208326208327208328208329208330208331208332208333208334208335208336208337208338208339208340208341208342208343208344208345208346208347208348208349208350208351208352208353208354208355208356208357208358208359208360208361208362208363208364208365208366208367208368208369208370208371208372208373208374208375208376208377208378208379208380208381208382208383208384208385208386208387208388208389208390208391208392208393208394208395208396208397208398208399208400208401208402208403208404208405208406208407208408208409208410208411208412208413208414208415208416208417208418208419208420208421208422208423208424208425208426208427208428208429208430208431208432208433208434208435208436208437208438208439208440208441208442208443208444208445208446208447208448208449208450208451208452208453208454208455208456208457208458208459208460208461208462208463208464208465208466208467208468208469208470208471208472208473208474208475208476208477208478208479208480208481208482208483208484208485208486208487208488208489208490208491208492208493208494208495208496208497208498208499208500208501208502208503208504208505208506208507208508208509208510208511208512208513208514208515208516208517208518208519208520208521208522208523208524208525208526208527208528208529208530208531208532208533208534208535208536208537208538208539208540208541208542208543208544208545208546208547208548208549208550208551208552208553208554208555208556208557208558208559208560208561208562208563208564208565208566208567208568208569208570208571208572208573208574208575208576208577208578208579208580208581208582208583208584208585208586208587208588208589208590208591208592208593208594208595208596208597208598208599208600208601208602208603208604208605208606208607208608208609208610208611208612208613208614208615208616208617208618208619208620208621208622208623208624208625208626208627208628208629208630208631208632208633208634208635208636208637208638208639208640208641208642208643208644208645208646208647208648208649208650208651208652208653208654208655208656208657208658208659208660208661208662208663208664208665208666208667208668208669208670208671208672208673208674208675208676208677208678208679208680208681208682208683208684208685208686208687208688208689208690208691208692208693208694208695208696208697208698208699208700208701208702208703208704208705208706208707208708208709208710208711208712208713208714208715208716208717208718208719208720208721208722208723208724208725208726208727208728208729208730208731208732208733208734208735208736208737208738208739208740208741208742208743208744208745208746208747208748208749208750208751208752208753208754208755208756208757208758208759208760208761208762208763208764208765208766208767208768208769208770208771208772208773208774208775208776208777208778208779208780208781208782208783208784208785208786208787208788208789208790208791208792208793208794208795208796208797208798208799208800208801208802208803208804208805208806208807208808208809208810208811208812208813208814208815208816208817208818208819208820208821208822208823208824208825208826208827208828208829208830208831208832208833208834208835208836208837208838208839208840208841208842208843208844208845208846208847208848208849208850208851208852208853208854208855208856208857208858208859208860208861208862208863208864208865208866208867208868208869208870208871208872208873208874208875208876208877208878208879208880208881208882208883208884208885208886208887208888208889208890208891208892208893208894208895208896208897208898208899208900208901208902208903208904208905208906208907208908208909208910208911208912208913208914208915208916208917208918208919208920208921208922208923208924208925208926208927208928208929208930208931208932208933208934208935208936208937208938208939208940208941208942208943208944208945208946208947208948208949208950208951208952208953208954208955208956208957208958208959208960208961208962208963208964208965208966208967208968208969208970208971208972208973208974208975208976208977208978208979208980208981208982208983208984208985208986208987208988208989208990208991208992208993208994208995208996208997208998208999209000209001209002209003209004209005209006209007209008209009209010209011209012209013209014209015209016209017209018209019209020209021209022209023209024209025209026209027209028209029209030209031209032209033209034209035209036209037209038209039209040209041209042209043209044209045209046209047209048209049209050209051209052209053209054209055209056209057209058209059209060209061209062209063209064209065209066209067209068209069209070209071209072209073209074209075209076209077209078209079209080209081209082209083209084209085209086209087209088209089209090209091209092209093209094209095209096209097209098209099209100209101209102209103209104209105209106209107209108209109209110209111209112209113209114209115209116209117209118209119209120209121209122209123209124209125209126209127209128209129209130209131209132209133209134209135209136209137209138209139209140209141209142209143209144209145209146209147209148209149209150209151209152209153209154209155209156209157209158209159209160209161209162209163209164209165209166209167209168209169209170209171209172209173209174209175209176209177209178209179209180209181209182209183209184209185209186209187209188209189209190209191209192209193209194209195209196209197209198209199209200209201209202209203209204209205209206209207209208209209209210209211209212209213209214209215209216209217209218209219209220209221209222209223209224209225209226209227209228209229209230209231209232209233209234209235209236209237209238209239209240209241209242209243209244209245209246209247209248209249209250209251209252209253209254209255209256209257209258209259209260209261209262209263209264209265209266209267209268209269209270209271209272209273209274209275209276209277209278209279209280209281209282209283209284209285209286209287209288209289209290209291209292209293209294209295209296209297209298209299209300209301209302209303209304209305209306209307209308209309209310209311209312209313209314209315209316209317209318209319209320209321209322209323209324209325209326209327209328209329209330209331209332209333209334209335209336209337209338209339209340209341209342209343209344209345209346209347209348209349209350209351209352209353209354209355209356209357209358209359209360209361209362209363209364209365209366209367209368209369209370209371209372209373209374209375209376209377209378209379209380209381209382209383209384209385209386209387209388209389209390209391209392209393209394209395209396209397209398209399209400209401209402209403209404209405209406209407209408209409209410209411209412209413209414209415209416209417209418209419209420209421209422209423209424209425209426209427209428209429209430209431209432209433209434209435209436209437209438209439209440209441209442209443209444209445209446209447209448209449209450209451209452209453209454209455209456209457209458209459209460209461209462209463209464209465209466209467209468209469209470209471209472209473209474209475209476209477209478209479209480209481209482209483209484209485209486209487209488209489209490209491209492209493209494209495209496209497209498209499209500209501209502209503209504209505209506209507209508209509209510209511209512209513209514209515209516209517209518209519209520209521209522209523209524209525209526209527209528209529209530209531209532209533209534209535209536209537209538209539209540209541209542209543209544209545209546209547209548209549209550209551209552209553209554209555209556209557209558209559209560209561209562209563209564209565209566209567209568209569209570209571209572209573209574209575209576209577209578209579209580209581209582209583209584209585209586209587209588209589209590209591209592209593209594209595209596209597209598209599209600209601209602209603209604209605209606209607209608209609209610209611209612209613209614209615209616209617209618209619209620209621209622209623209624209625209626209627209628209629209630209631209632209633209634209635209636209637209638209639209640209641209642209643209644209645209646209647209648209649209650209651209652209653209654209655209656209657209658209659209660209661209662209663209664209665209666209667209668209669209670209671209672209673209674209675209676209677209678209679209680209681209682209683209684209685209686209687209688209689209690209691209692209693209694209695209696209697209698209699209700209701209702209703209704209705209706209707209708209709209710209711209712209713209714209715209716209717209718209719209720209721209722209723209724209725209726209727209728209729209730209731209732209733209734209735209736209737209738209739209740209741209742209743209744209745209746209747209748209749209750209751209752209753209754209755209756209757209758209759209760209761209762209763209764209765209766209767209768209769209770209771209772209773209774209775209776209777209778209779209780209781209782209783209784209785209786209787209788209789209790209791209792209793209794209795209796209797209798209799209800209801209802209803209804209805209806209807209808209809209810209811209812209813209814209815209816209817209818209819209820209821209822209823209824209825209826209827209828209829209830209831209832209833209834209835209836209837209838209839209840209841209842209843209844209845209846209847209848209849209850209851209852209853209854209855209856209857209858209859209860209861209862209863209864209865209866209867209868209869209870209871209872209873209874209875209876209877209878209879209880209881209882209883209884209885209886209887209888209889209890209891209892209893209894209895209896209897209898209899209900209901209902209903209904209905209906209907209908209909209910209911209912209913209914209915209916209917209918209919209920209921209922209923209924209925209926209927209928209929209930209931209932209933209934209935209936209937209938209939209940209941209942209943209944209945209946209947209948209949209950209951209952209953209954209955209956209957209958209959209960209961209962209963209964209965209966209967209968209969209970209971209972209973209974209975209976209977209978209979209980209981209982209983209984209985209986209987209988209989209990209991209992209993209994209995209996209997209998209999210000210001210002210003210004210005210006210007210008210009210010210011210012210013210014210015210016210017210018210019210020210021210022210023210024210025210026210027210028210029210030210031210032210033210034210035210036210037210038210039210040210041210042210043210044210045210046210047210048210049210050210051210052210053210054210055210056210057210058210059210060210061210062210063210064210065210066210067210068210069210070210071210072210073210074210075210076210077210078210079210080210081210082210083210084210085210086210087210088210089210090210091210092210093210094210095210096210097210098210099210100210101210102210103210104210105210106210107210108210109210110210111210112210113210114210115210116210117210118210119210120210121210122210123210124210125210126210127210128210129210130210131210132210133210134210135210136210137210138210139210140210141210142210143210144210145210146210147210148210149210150210151210152210153210154210155210156210157210158210159210160210161210162210163210164210165210166210167210168210169210170210171210172210173210174210175210176210177210178210179210180210181210182210183210184210185210186210187210188210189210190210191210192210193210194210195210196210197210198210199210200210201210202210203210204210205210206210207210208210209210210210211210212210213210214210215210216210217210218210219210220210221210222210223210224210225210226210227210228210229210230210231210232210233210234210235210236210237210238210239210240210241210242210243210244210245210246210247210248210249210250210251210252210253210254210255210256210257210258210259210260210261210262210263210264210265210266210267210268210269210270210271210272210273210274210275210276210277210278210279210280210281210282210283210284210285210286210287210288210289210290210291210292210293210294210295210296210297210298210299210300210301210302210303210304210305210306210307210308210309210310210311210312210313210314210315210316210317210318210319210320210321210322210323210324210325210326210327210328210329210330210331210332210333210334210335210336210337210338210339210340210341210342210343210344210345210346210347210348210349210350210351210352210353210354210355210356210357210358210359210360210361210362210363210364210365210366210367210368210369210370210371210372210373210374210375210376210377210378210379210380210381210382210383210384210385210386210387210388210389210390210391210392210393210394210395210396210397210398210399210400210401210402210403210404210405210406210407210408210409210410210411210412210413210414210415210416210417210418210419210420210421210422210423210424210425210426210427210428210429210430210431210432210433210434210435210436210437210438210439210440210441210442210443210444210445210446210447210448210449210450210451210452210453210454210455210456210457210458210459210460210461210462210463210464210465210466210467210468210469210470210471210472210473210474210475210476210477210478210479210480210481210482210483210484210485210486210487210488210489210490210491210492210493210494210495210496210497210498210499210500210501210502210503210504210505210506210507210508210509210510210511210512210513210514210515210516210517210518210519210520210521210522210523210524210525210526210527210528210529210530210531210532210533210534210535210536210537210538210539210540210541210542210543210544210545210546210547210548210549210550210551210552210553210554210555210556210557210558210559210560210561210562210563210564210565210566210567210568210569210570210571210572210573210574210575210576210577210578210579210580210581210582210583210584210585210586210587210588210589210590210591210592210593210594210595210596210597210598210599210600210601210602210603210604210605210606210607210608210609210610210611210612210613210614210615210616210617210618210619210620210621210622210623210624210625210626210627210628210629210630210631210632210633210634210635210636210637210638210639210640210641210642210643210644210645210646210647210648210649210650210651210652210653210654210655210656210657210658210659210660210661210662210663210664210665210666210667210668210669210670210671210672210673210674210675210676210677210678210679210680210681210682210683210684210685210686210687210688210689210690210691210692210693210694210695210696210697210698210699210700210701210702210703210704210705210706210707210708210709210710210711210712210713210714210715210716210717210718210719210720210721210722210723210724210725210726210727210728210729210730210731210732210733210734210735210736210737210738210739210740210741210742210743210744210745210746210747210748210749210750210751210752210753210754210755210756210757210758210759210760210761210762210763210764210765210766210767210768210769210770210771210772210773210774210775210776210777210778210779210780210781210782210783210784210785210786210787210788210789210790210791210792210793210794210795210796210797210798210799210800210801210802210803210804210805210806210807210808210809210810210811210812210813210814210815210816210817210818210819210820210821210822210823210824210825210826210827210828210829210830210831210832210833210834210835210836210837210838210839210840210841210842210843210844210845210846210847210848210849210850210851210852210853210854210855210856210857210858210859210860210861210862210863210864210865210866210867210868210869210870210871210872210873210874210875210876210877210878210879210880210881210882210883210884210885210886210887210888210889210890210891210892210893210894210895210896210897210898210899210900210901210902210903210904210905210906210907210908210909210910210911210912210913210914210915210916210917210918210919210920210921210922210923210924210925210926210927210928210929210930210931210932210933210934210935210936210937210938210939210940210941210942210943210944210945210946210947210948210949210950210951210952210953210954210955210956210957210958210959210960210961210962210963210964210965210966210967210968210969210970210971210972210973210974210975210976210977210978210979210980210981210982210983210984210985210986210987210988210989210990210991210992210993210994210995210996210997210998210999211000211001211002211003211004211005211006211007211008211009211010211011211012211013211014211015211016211017211018211019211020211021211022211023211024211025211026211027211028211029211030211031211032211033211034211035211036211037211038211039211040211041211042211043211044211045211046211047211048211049211050211051211052211053211054211055211056211057211058211059211060211061211062211063211064211065211066211067211068211069211070211071211072211073211074211075211076211077211078211079211080211081211082211083211084211085211086211087211088211089211090211091211092211093211094211095211096211097211098211099211100211101211102211103211104211105211106211107211108211109211110211111211112211113211114211115211116211117211118211119211120211121211122211123211124211125211126211127211128211129211130211131211132211133211134211135211136211137211138211139211140211141211142211143211144211145211146211147211148211149211150211151211152211153211154211155211156211157211158211159211160211161211162211163211164211165211166211167211168211169211170211171211172211173211174211175211176211177211178211179211180211181211182211183211184211185211186211187211188211189211190211191211192211193211194211195211196211197211198211199211200211201211202211203211204211205211206211207211208211209211210211211211212211213211214211215211216211217211218211219211220211221211222211223211224211225211226211227211228211229211230211231211232211233211234211235211236211237211238211239211240211241211242211243211244211245211246211247211248211249211250211251211252211253211254211255211256211257211258211259211260211261211262211263211264211265211266211267211268211269211270211271211272211273211274211275211276211277211278211279211280211281211282211283211284211285211286211287211288211289211290211291211292211293211294211295211296211297211298211299211300211301211302211303211304211305211306211307211308211309211310211311211312211313211314211315211316211317211318211319211320211321211322211323211324211325211326211327211328211329211330211331211332211333211334211335211336211337211338211339211340211341211342211343211344211345211346211347211348211349211350211351211352211353211354211355211356211357211358211359211360211361211362211363211364211365211366211367211368211369211370211371211372211373211374211375211376211377211378211379211380211381211382211383211384211385211386211387211388211389211390211391211392211393211394211395211396211397211398211399211400211401211402211403211404211405211406211407211408211409211410211411211412211413211414211415211416211417211418211419211420211421211422211423211424211425211426211427211428211429211430211431211432211433211434211435211436211437211438211439211440211441211442211443211444211445211446211447211448211449211450211451211452211453211454211455211456211457211458211459211460211461211462211463211464211465211466211467211468211469211470211471211472211473211474211475211476211477211478211479211480211481211482211483211484211485211486211487211488211489211490211491211492211493211494211495211496211497211498211499211500211501211502211503211504211505211506211507211508211509211510211511211512211513211514211515211516211517211518211519211520211521211522211523211524211525211526211527211528211529211530211531211532211533211534211535211536211537211538211539211540211541211542211543211544211545211546211547211548211549211550211551211552211553211554211555211556211557211558211559211560211561211562211563211564211565211566211567211568211569211570211571211572211573211574211575211576211577211578211579211580211581211582211583211584211585211586211587211588211589211590211591211592211593211594211595211596211597211598211599211600211601211602211603211604211605211606211607211608211609211610211611211612211613211614211615211616211617211618211619211620211621211622211623211624211625211626211627211628211629211630211631211632211633211634211635211636211637211638211639211640211641211642211643211644211645211646211647211648211649211650211651211652211653211654211655211656211657211658211659211660211661211662211663211664211665211666211667211668211669211670211671211672211673211674211675211676211677211678211679211680211681211682211683211684211685211686211687211688211689211690211691211692211693211694211695211696211697211698211699211700211701211702211703211704211705211706211707211708211709211710211711211712211713211714211715211716211717211718211719211720211721211722211723211724211725211726211727211728211729211730211731211732211733211734211735211736211737211738211739211740211741211742211743211744211745211746211747211748211749211750211751211752211753211754211755211756211757211758211759211760211761211762211763211764211765211766211767211768211769211770211771211772211773211774211775211776211777211778211779211780211781211782211783211784211785211786211787211788211789211790211791211792211793211794211795211796211797211798211799211800211801211802211803211804211805211806211807211808211809211810211811211812211813211814211815211816211817211818211819211820211821211822211823211824211825211826211827211828211829211830211831211832211833211834211835211836211837211838211839211840211841211842211843211844211845211846211847211848211849211850211851211852211853211854211855211856211857211858211859211860211861211862211863211864211865211866211867211868211869211870211871211872211873211874211875211876211877211878211879211880211881211882211883211884211885211886211887211888211889211890211891211892211893211894211895211896211897211898211899211900211901211902211903211904211905211906211907211908211909211910211911211912211913211914211915211916211917211918211919211920211921211922211923211924211925211926211927211928211929211930211931211932211933211934211935211936211937211938211939211940211941211942211943211944211945211946211947211948211949211950211951211952211953211954211955211956211957211958211959211960211961211962211963211964211965211966211967211968211969211970211971211972211973211974211975211976211977211978211979211980211981211982211983211984211985211986211987211988211989211990211991211992211993211994211995211996211997211998211999212000212001212002212003212004212005212006212007212008212009212010212011212012212013212014212015212016212017212018212019212020212021212022212023212024212025212026212027212028212029212030212031212032212033212034212035212036212037212038212039212040212041212042212043212044212045212046212047212048212049212050212051212052212053212054212055212056212057212058212059212060212061212062212063212064212065212066212067212068212069212070212071212072212073212074212075212076212077212078212079212080212081212082212083212084212085212086212087212088212089212090212091212092212093212094212095212096212097212098212099212100212101212102212103212104212105212106212107212108212109212110212111212112212113212114212115212116212117212118212119212120212121212122212123212124212125212126212127212128212129212130212131212132212133212134212135212136212137212138212139212140212141212142212143212144212145212146212147212148212149212150212151212152212153212154212155212156212157212158212159212160212161212162212163212164212165212166212167212168212169212170212171212172212173212174212175212176212177212178212179212180212181212182212183212184212185212186212187212188212189212190212191212192212193212194212195212196212197212198212199212200212201212202212203212204212205212206212207212208212209212210212211212212212213212214212215212216212217212218212219212220212221212222212223212224212225212226212227212228212229212230212231212232212233212234212235212236212237212238212239212240212241212242212243212244212245212246212247212248212249212250212251212252212253212254212255212256212257212258212259212260212261212262212263212264212265212266212267212268212269212270212271212272212273212274212275212276212277212278212279212280212281212282212283212284212285212286212287212288212289212290212291212292212293212294212295212296212297212298212299212300212301212302212303212304212305212306212307212308212309212310212311212312212313212314212315212316212317212318212319212320212321212322212323212324212325212326212327212328212329212330212331212332212333212334212335212336212337212338212339212340212341212342212343212344212345212346212347212348212349212350212351212352212353212354212355212356212357212358212359212360212361212362212363212364212365212366212367212368212369212370212371212372212373212374212375212376212377212378212379212380212381212382212383212384212385212386212387212388212389212390212391212392212393212394212395212396212397212398212399212400212401212402212403212404212405212406212407212408212409212410212411212412212413212414212415212416212417212418212419212420212421212422212423212424212425212426212427212428212429212430212431212432212433212434212435212436212437212438212439212440212441212442212443212444212445212446212447212448212449212450212451212452212453212454212455212456212457212458212459212460212461212462212463212464212465212466212467212468212469212470212471212472212473212474212475212476212477212478212479212480212481212482212483212484212485212486212487212488212489212490212491212492212493212494212495212496212497212498212499212500212501212502212503212504212505212506212507212508212509212510212511212512212513212514212515212516212517212518212519212520212521212522212523212524212525212526212527212528212529212530212531212532212533212534212535212536212537212538212539212540212541212542212543212544212545212546212547212548212549212550212551212552212553212554212555212556212557212558212559212560212561212562212563212564212565212566212567212568212569212570212571212572212573212574212575212576212577212578212579212580212581212582212583212584212585212586212587212588212589212590212591212592212593212594212595212596212597212598212599212600212601212602212603212604212605212606212607212608212609212610212611212612212613212614212615212616212617212618212619212620212621212622212623212624212625212626212627212628212629212630212631212632212633212634212635212636212637212638212639212640212641212642212643212644212645212646212647212648212649212650212651212652212653212654212655212656212657212658212659212660212661212662212663212664212665212666212667212668212669212670212671212672212673212674212675212676212677212678212679212680212681212682212683212684212685212686212687212688212689212690212691212692212693212694212695212696212697212698212699212700212701212702212703212704212705212706212707212708212709212710212711212712212713212714212715212716212717212718212719212720212721212722212723212724212725212726212727212728212729212730212731212732212733212734212735212736212737212738212739212740212741212742212743212744212745212746212747212748212749212750212751212752212753212754212755212756212757212758212759212760212761212762212763212764212765212766212767212768212769212770212771212772212773212774212775212776212777212778212779212780212781212782212783212784212785212786212787212788212789212790212791212792212793212794212795212796212797212798212799212800212801212802212803212804212805212806212807212808212809212810212811212812212813212814212815212816212817212818212819212820212821212822212823212824212825212826212827212828212829212830212831212832212833212834212835212836212837212838212839212840212841212842212843212844212845212846212847212848212849212850212851212852212853212854212855212856212857212858212859212860212861212862212863212864212865212866212867212868212869212870212871212872212873212874212875212876212877212878212879212880212881212882212883212884212885212886212887212888212889212890212891212892212893212894212895212896212897212898212899212900212901212902212903212904212905212906212907212908212909212910212911212912212913212914212915212916212917212918212919212920212921212922212923212924212925212926212927212928212929212930212931212932212933212934212935212936212937212938212939212940212941212942212943212944212945212946212947212948212949212950212951212952212953212954212955212956212957212958212959212960212961212962212963212964212965212966212967212968212969212970212971212972212973212974212975212976212977212978212979212980212981212982212983212984212985212986212987212988212989212990212991212992212993212994212995212996212997212998212999213000213001213002213003213004213005213006213007213008213009213010213011213012213013213014213015213016213017213018213019213020213021213022213023213024213025213026213027213028213029213030213031213032213033213034213035213036213037213038213039213040213041213042213043213044213045213046213047213048213049213050213051213052213053213054213055213056213057213058213059213060213061213062213063213064213065213066213067213068213069213070213071213072213073213074213075213076213077213078213079213080213081213082213083213084213085213086213087213088213089213090213091213092213093213094213095213096213097213098213099213100213101213102213103213104213105213106213107213108213109213110213111213112213113213114213115213116213117213118213119213120213121213122213123213124213125213126213127213128213129213130213131213132213133213134213135213136213137213138213139213140213141213142213143213144213145213146213147213148213149213150213151213152213153213154213155213156213157213158213159213160213161213162213163213164213165213166213167213168213169213170213171213172213173213174213175213176213177213178213179213180213181213182213183213184213185213186213187213188213189213190213191213192213193213194213195213196213197213198213199213200213201213202213203213204213205213206213207213208213209213210213211213212213213213214213215213216213217213218213219213220213221213222213223213224213225213226213227213228213229213230213231213232213233213234213235213236213237213238213239213240213241213242213243213244213245213246213247213248213249213250213251213252213253213254213255213256213257213258213259213260213261213262213263213264213265213266213267213268213269213270213271213272213273213274213275213276213277213278213279213280213281213282213283213284213285213286213287213288213289213290213291213292213293213294213295213296213297213298213299213300213301213302213303213304213305213306213307213308213309213310213311213312213313213314213315213316213317213318213319213320213321213322213323213324213325213326213327213328213329213330213331213332213333213334213335213336213337213338213339213340213341213342213343213344213345213346213347213348213349213350213351213352213353213354213355213356213357213358213359213360213361213362213363213364213365213366213367213368213369213370213371213372213373213374213375213376213377213378213379213380213381213382213383213384213385213386213387213388213389213390213391213392213393213394213395213396213397213398213399213400213401213402213403213404213405213406213407213408213409213410213411213412213413213414213415213416213417213418213419213420213421213422213423213424213425213426213427213428213429213430213431213432213433213434213435213436213437213438213439213440213441213442213443213444213445213446213447213448213449213450213451213452213453213454213455213456213457213458213459213460213461213462213463213464213465213466213467213468213469213470213471213472213473213474213475213476213477213478213479213480213481213482213483213484213485213486213487213488213489213490213491213492213493213494213495213496213497213498213499213500213501213502213503213504213505213506213507213508213509213510213511213512213513213514213515213516213517213518213519213520213521213522213523213524213525213526213527213528213529213530213531213532213533213534213535213536213537213538213539213540213541213542213543213544213545213546213547213548213549213550213551213552213553213554213555213556213557213558213559213560213561213562213563213564213565213566213567213568213569213570213571213572213573213574213575213576213577213578213579213580213581213582213583213584213585213586213587213588213589213590213591213592213593213594213595213596213597213598213599213600213601213602213603213604213605213606213607213608213609213610213611213612213613213614213615213616213617213618213619213620213621213622213623213624213625213626213627213628213629213630213631213632213633213634213635213636213637213638213639213640213641213642213643213644213645213646213647213648213649213650213651213652213653213654213655213656213657213658213659213660213661213662213663213664213665213666213667213668213669213670213671213672213673213674213675213676213677213678213679213680213681213682213683213684213685213686213687213688213689213690213691213692213693213694213695213696213697213698213699213700213701213702213703213704213705213706213707213708213709213710213711213712213713213714213715213716213717213718213719213720213721213722213723213724213725213726213727213728213729213730213731213732213733213734213735213736213737213738213739213740213741213742213743213744213745213746213747213748213749213750213751213752213753213754213755213756213757213758213759213760213761213762213763213764213765213766213767213768213769213770213771213772213773213774213775213776213777213778213779213780213781213782213783213784213785213786213787213788213789213790213791213792213793213794213795213796213797213798213799213800213801213802213803213804213805213806213807213808213809213810213811213812213813213814213815213816213817213818213819213820213821213822213823213824213825213826213827213828213829213830213831213832213833213834213835213836213837213838213839213840213841213842213843213844213845213846213847213848213849213850213851213852213853213854213855213856213857213858213859213860213861213862213863213864213865213866213867213868213869213870213871213872213873213874213875213876213877213878213879213880213881213882213883213884213885213886213887213888213889213890213891213892213893213894213895213896213897213898213899213900213901213902213903213904213905213906213907213908213909213910213911213912213913213914213915213916213917213918213919213920213921213922213923213924213925213926213927213928213929213930213931213932213933213934213935213936213937213938213939213940213941213942213943213944213945213946213947213948213949213950213951213952213953213954213955213956213957213958213959213960213961213962213963213964213965213966213967213968213969213970213971213972213973213974213975213976213977213978213979213980213981213982213983213984213985213986213987213988213989213990213991213992213993213994213995213996213997213998213999214000214001214002214003214004214005214006214007214008214009214010214011214012214013214014214015214016214017214018214019214020214021214022214023214024214025214026214027214028214029214030214031214032214033214034214035214036214037214038214039214040214041214042214043214044214045214046214047214048214049214050214051214052214053214054214055214056214057214058214059214060214061214062214063214064214065214066214067214068214069214070214071214072214073214074214075214076214077214078214079214080214081214082214083214084214085214086214087214088214089214090214091214092214093214094214095214096214097214098214099214100214101214102214103214104214105214106214107214108214109214110214111214112214113214114214115214116214117214118214119214120214121214122214123214124214125214126214127214128214129214130214131214132214133214134214135214136214137214138214139214140214141214142214143214144214145214146214147214148214149214150214151214152214153214154214155214156214157214158214159214160214161214162214163214164214165214166214167214168214169214170214171214172214173214174214175214176214177214178214179214180214181214182214183214184214185214186214187214188214189214190214191214192214193214194214195214196214197214198214199214200214201214202214203214204214205214206214207214208214209214210214211214212214213214214214215214216214217214218214219214220214221214222214223214224214225214226214227214228214229214230214231214232214233214234214235214236214237214238214239214240214241214242214243214244214245214246214247214248214249214250214251214252214253214254214255214256214257214258214259214260214261214262214263214264214265214266214267214268214269214270214271214272214273214274214275214276214277214278214279214280214281214282214283214284214285214286214287214288214289214290214291214292214293214294214295214296214297214298214299214300214301214302214303214304214305214306214307214308214309214310214311214312214313214314214315214316214317214318214319214320214321214322214323214324214325214326214327214328214329214330214331214332214333214334214335214336214337214338214339214340214341214342214343214344214345214346214347214348214349214350214351214352214353214354214355214356214357214358214359214360214361214362214363214364214365214366214367214368214369214370214371214372214373214374214375214376214377214378214379214380214381214382214383214384214385214386214387214388214389214390214391214392214393214394214395214396214397214398214399214400214401214402214403214404214405214406214407214408214409214410214411214412214413214414214415214416214417214418214419214420214421214422214423214424214425214426214427214428214429214430214431214432214433214434214435214436214437214438214439214440214441214442214443214444214445214446214447214448214449214450214451214452214453214454214455214456214457214458214459214460214461214462214463214464214465214466214467214468214469214470214471214472214473214474214475214476214477214478214479214480214481214482214483214484214485214486214487214488214489214490214491214492214493214494214495214496214497214498214499214500214501214502214503214504214505214506214507214508214509214510214511214512214513214514214515214516214517214518214519214520214521214522214523214524214525214526214527214528214529214530214531214532214533214534214535214536214537214538214539214540214541214542214543214544214545214546214547214548214549214550214551214552214553214554214555214556214557214558214559214560214561214562214563214564214565214566214567214568214569214570214571214572214573214574214575214576214577214578214579214580214581214582214583214584214585214586214587214588214589214590214591214592214593214594214595214596214597214598214599214600214601214602214603214604214605214606214607214608214609214610214611214612214613214614214615214616214617214618214619214620214621214622214623214624214625214626214627214628214629214630214631214632214633214634214635214636214637214638214639214640214641214642214643214644214645214646214647214648214649214650214651214652214653214654214655214656214657214658214659214660214661214662214663214664214665214666214667214668214669214670214671214672214673214674214675214676214677214678214679214680214681214682214683214684214685214686214687214688214689214690214691214692214693214694214695214696214697214698214699214700214701214702214703214704214705214706214707214708214709214710214711214712214713214714214715214716214717214718214719214720214721214722214723214724214725214726214727214728214729214730214731214732214733214734214735214736214737214738214739214740214741214742214743214744214745214746214747214748214749214750214751214752214753214754214755214756214757214758214759214760214761214762214763214764214765214766214767214768214769214770214771214772214773214774214775214776214777214778214779214780214781214782214783214784214785214786214787214788214789214790214791214792214793214794214795214796214797214798214799214800214801214802214803214804214805214806214807214808214809214810214811214812214813214814214815214816214817214818214819214820214821214822214823214824214825214826214827214828214829214830214831214832214833214834214835214836214837214838214839214840214841214842214843214844214845214846214847214848214849214850214851214852214853214854214855214856214857214858214859214860214861214862214863214864214865214866214867214868214869214870214871214872214873214874214875214876214877214878214879214880214881214882214883214884214885214886214887214888214889214890214891214892214893214894214895214896214897214898214899214900214901214902214903214904214905214906214907214908214909214910214911214912214913214914214915214916214917214918214919214920214921214922214923214924214925214926214927214928214929214930214931214932214933214934214935214936214937214938214939214940214941214942214943214944214945214946214947214948214949214950214951214952214953214954214955214956214957214958214959214960214961214962214963214964214965214966214967214968214969214970214971214972214973214974214975214976214977214978214979214980214981214982214983214984214985214986214987214988214989214990214991214992214993214994214995214996214997214998214999215000215001215002215003215004215005215006215007215008215009215010215011215012215013215014215015215016215017215018215019215020215021215022215023215024215025215026215027215028215029215030215031215032215033215034215035215036215037215038215039215040215041215042215043215044215045215046215047215048215049215050215051215052215053215054215055215056215057215058215059215060215061215062215063215064215065215066215067215068215069215070215071215072215073215074215075215076215077215078215079215080215081215082215083215084215085215086215087215088215089215090215091215092215093215094215095215096215097215098215099215100215101215102215103215104215105215106215107215108215109215110215111215112215113215114215115215116215117215118215119215120215121215122215123215124215125215126215127215128215129215130215131215132215133215134215135215136215137215138215139215140215141215142215143215144215145215146215147215148215149215150215151215152215153215154215155215156215157215158215159215160215161215162215163215164215165215166215167215168215169215170215171215172215173215174215175215176215177215178215179215180215181215182215183215184215185215186215187215188215189215190215191215192215193215194215195215196215197215198215199215200215201215202215203215204215205215206215207215208215209215210215211215212215213215214215215215216215217215218215219215220215221215222215223215224215225215226215227215228215229215230215231215232215233215234215235215236215237215238215239215240215241215242215243215244215245215246215247215248215249215250215251215252215253215254215255215256215257215258215259215260215261215262215263215264215265215266215267215268215269215270215271215272215273215274215275215276215277215278215279215280215281215282215283215284215285215286215287215288215289215290215291215292215293215294215295215296215297215298215299215300215301215302215303215304215305215306215307215308215309215310215311215312215313215314215315215316215317215318215319215320215321215322215323215324215325215326215327215328215329215330215331215332215333215334215335215336215337215338215339215340215341215342215343215344215345215346215347215348215349215350215351215352215353215354215355215356215357215358215359215360215361215362215363215364215365215366215367215368215369215370215371215372215373215374215375215376215377215378215379215380215381215382215383215384215385215386215387215388215389215390215391215392215393215394215395215396215397215398215399215400215401215402215403215404215405215406215407215408215409215410215411215412215413215414215415215416215417215418215419215420215421215422215423215424215425215426215427215428215429215430215431215432215433215434215435215436215437215438215439215440215441215442215443215444215445215446215447215448215449215450215451215452215453215454215455215456215457215458215459215460215461215462215463215464215465215466215467215468215469215470215471215472215473215474215475215476215477215478215479215480215481215482215483215484215485215486215487215488215489215490215491215492215493215494215495215496215497215498215499215500215501215502215503215504215505215506215507215508215509215510215511215512215513215514215515215516215517215518215519215520215521215522215523215524215525215526215527215528215529215530215531215532215533215534215535215536215537215538215539215540215541215542215543215544215545215546215547215548215549215550215551215552215553215554215555215556215557215558215559215560215561215562215563215564215565215566215567215568215569215570215571215572215573215574215575215576215577215578215579215580215581215582215583215584215585215586215587215588215589215590215591215592215593215594215595215596215597215598215599215600215601215602215603215604215605215606215607215608215609215610215611215612215613215614215615215616215617215618215619215620215621215622215623215624215625215626215627215628215629215630215631215632215633215634215635215636215637215638215639215640215641215642215643215644215645215646215647215648215649215650215651215652215653215654215655215656215657215658215659215660215661215662215663215664215665215666215667215668215669215670215671215672215673215674215675215676215677215678215679215680215681215682215683215684215685215686215687215688215689215690215691215692215693215694215695215696215697215698215699215700215701215702215703215704215705215706215707215708215709215710215711215712215713215714215715215716215717215718215719215720215721215722215723215724215725215726215727215728215729215730215731215732215733215734215735215736215737215738215739215740215741215742215743215744215745215746215747215748215749215750215751215752215753215754215755215756215757215758215759215760215761215762215763215764215765215766215767215768215769215770215771215772215773215774215775215776215777215778215779215780215781215782215783215784215785215786215787215788215789215790215791215792215793215794215795215796215797215798215799215800215801215802215803215804215805215806215807215808215809215810215811215812215813215814215815215816215817215818215819215820215821215822215823215824215825215826215827215828215829215830215831215832215833215834215835215836215837215838215839215840215841215842215843215844215845215846215847215848215849215850215851215852215853215854215855215856215857215858215859215860215861215862215863215864215865215866215867215868215869215870215871215872215873215874215875215876215877215878215879215880215881215882215883215884215885215886215887215888215889215890215891215892215893215894215895215896215897215898215899215900215901215902215903215904215905215906215907215908215909215910215911215912215913215914215915215916215917215918215919215920215921215922215923215924215925215926215927215928215929215930215931215932215933215934215935215936215937215938215939215940215941215942215943215944215945215946215947215948215949215950215951215952215953215954215955215956215957215958215959215960215961215962215963215964215965215966215967215968215969215970215971215972215973215974215975215976215977215978215979215980215981215982215983215984215985215986215987215988215989215990215991215992215993215994215995215996215997215998215999216000216001216002216003216004216005216006216007216008216009216010216011216012216013216014216015216016216017216018216019216020216021216022216023216024216025216026216027216028216029216030216031216032216033216034216035216036216037216038216039216040216041216042216043216044216045216046216047216048216049216050216051216052216053216054216055216056216057216058216059216060216061216062216063216064216065216066216067216068216069216070216071216072216073216074216075216076216077216078216079216080216081216082216083216084216085216086216087216088216089216090216091216092216093216094216095216096216097216098216099216100216101216102216103216104216105216106216107216108216109216110216111216112216113216114216115216116216117216118216119216120216121216122216123216124216125216126216127216128216129216130216131216132216133216134216135216136216137216138216139216140216141216142216143216144216145216146216147216148216149216150216151216152216153216154216155216156216157216158216159216160216161216162216163216164216165216166216167216168216169216170216171216172216173216174216175216176216177216178216179216180216181216182216183216184216185216186216187216188216189216190216191216192216193216194216195216196216197216198216199216200216201216202216203216204216205216206216207216208216209216210216211216212216213216214216215216216216217216218216219216220216221216222216223216224216225216226216227216228216229216230216231216232216233216234216235216236216237216238216239216240216241216242216243216244216245216246216247216248216249216250216251216252216253216254216255216256216257216258216259216260216261216262216263216264216265216266216267216268216269216270216271216272216273216274216275216276216277216278216279216280216281216282216283216284216285216286216287216288216289216290216291216292216293216294216295216296216297216298216299216300216301216302216303216304216305216306216307216308216309216310216311216312216313216314216315216316216317216318216319216320216321216322216323216324216325216326216327216328216329216330216331216332216333216334216335216336216337216338216339216340216341216342216343216344216345216346216347216348216349216350216351216352216353216354216355216356216357216358216359216360216361216362216363216364216365216366216367216368216369216370216371216372216373216374216375216376216377216378216379216380216381216382216383216384216385216386216387216388216389216390216391216392216393216394216395216396216397216398216399216400216401216402216403216404216405216406216407216408216409216410216411216412216413216414216415216416216417216418216419216420216421216422216423216424216425216426216427216428216429216430216431216432216433216434216435216436216437216438216439216440216441216442216443216444216445216446216447216448216449216450216451216452216453216454216455216456216457216458216459216460216461216462216463216464216465216466216467216468216469216470216471216472216473216474216475216476216477216478216479216480216481216482216483216484216485216486216487216488216489216490216491216492216493216494216495216496216497216498216499216500216501216502216503216504216505216506216507216508216509216510216511216512216513216514216515216516216517216518216519216520216521216522216523216524216525216526216527216528216529216530216531216532216533216534216535216536216537216538216539216540216541216542216543216544216545216546216547216548216549216550216551216552216553216554216555216556216557216558216559216560216561216562216563216564216565216566216567216568216569216570216571216572216573216574216575216576216577216578216579216580216581216582216583216584216585216586216587216588216589216590216591216592216593216594216595216596216597216598216599216600216601216602216603216604216605216606216607216608216609216610216611216612216613216614216615216616216617216618216619216620216621216622216623216624216625216626216627216628216629216630216631216632216633216634216635216636216637216638216639216640216641216642216643216644216645216646216647216648216649216650216651216652216653216654216655216656216657216658216659216660216661216662216663216664216665216666216667216668216669216670216671216672216673216674216675216676216677216678216679216680216681216682216683216684216685216686216687216688216689216690216691216692216693216694216695216696216697216698216699216700216701216702216703216704216705216706216707216708216709216710216711216712216713216714216715216716216717216718216719216720216721216722216723216724216725216726216727216728216729216730216731216732216733216734216735216736216737216738216739216740216741216742216743216744216745216746216747216748216749216750216751216752216753216754216755216756216757216758216759216760216761216762216763216764216765216766216767216768216769216770216771216772216773216774216775216776216777216778216779216780216781216782216783216784216785216786216787216788216789216790216791216792216793216794216795216796216797216798216799216800216801216802216803216804216805216806216807216808216809216810216811216812216813216814216815216816216817216818216819216820216821216822216823216824216825216826216827216828216829216830216831216832216833216834216835216836216837216838216839216840216841216842216843216844216845216846216847216848216849216850216851216852216853216854216855216856216857216858216859216860216861216862216863216864216865216866216867216868216869216870216871216872216873216874216875216876216877216878216879216880216881216882216883216884216885216886216887216888216889216890216891216892216893216894216895216896216897216898216899216900216901216902216903216904216905216906216907216908216909216910216911216912216913216914216915216916216917216918216919216920216921216922216923216924216925216926216927216928216929216930216931216932216933216934216935216936216937216938216939216940216941216942216943216944216945216946216947216948216949216950216951216952216953216954216955216956216957216958216959216960216961216962216963216964216965216966216967216968216969216970216971216972216973216974216975216976216977216978216979216980216981216982216983216984216985216986216987216988216989216990216991216992216993216994216995216996216997216998216999217000217001217002217003217004217005217006217007217008217009217010217011217012217013217014217015217016217017217018217019217020217021217022217023217024217025217026217027217028217029217030217031217032217033217034217035217036217037217038217039217040217041217042217043217044217045217046217047217048217049217050217051217052217053217054217055217056217057217058217059217060217061217062217063217064217065217066217067217068217069217070217071217072217073217074217075217076217077217078217079217080217081217082217083217084217085217086217087217088217089217090217091217092217093217094217095217096217097217098217099217100217101217102217103217104217105217106217107217108217109217110217111217112217113217114217115217116217117217118217119217120217121217122217123217124217125217126217127217128217129217130217131217132217133217134217135217136217137217138217139217140217141217142217143217144217145217146217147217148217149217150217151217152217153217154217155217156217157217158217159217160217161217162217163217164217165217166217167217168217169217170217171217172217173217174217175217176217177217178217179217180217181217182217183217184217185217186217187217188217189217190217191217192217193217194217195217196217197217198217199217200217201217202217203217204217205217206217207217208217209217210217211217212217213217214217215217216217217217218217219217220217221217222217223217224217225217226217227217228217229217230217231217232217233217234217235217236217237217238217239217240217241217242217243217244217245217246217247217248217249217250217251217252217253217254217255217256217257217258217259217260217261217262217263217264217265217266217267217268217269217270217271217272217273217274217275217276217277217278217279217280217281217282217283217284217285217286217287217288217289217290217291217292217293217294217295217296217297217298217299217300217301217302217303217304217305217306217307217308217309217310217311217312217313217314217315217316217317217318217319217320217321217322217323217324217325217326217327217328217329217330217331217332217333217334217335217336217337217338217339217340217341217342217343217344217345217346217347217348217349217350217351217352217353217354217355217356217357217358217359217360217361217362217363217364217365217366217367217368217369217370217371217372217373217374217375217376217377217378217379217380217381217382217383217384217385217386217387217388217389217390217391217392217393217394217395217396217397217398217399217400217401217402217403217404217405217406217407217408217409217410217411217412217413217414217415217416217417217418217419217420217421217422217423217424217425217426217427217428217429217430217431217432217433217434217435217436217437217438217439217440217441217442217443217444217445217446217447217448217449217450217451217452217453217454217455217456217457217458217459217460217461217462217463217464217465217466217467217468217469217470217471217472217473217474217475217476217477217478217479217480217481217482217483217484217485217486217487217488217489217490217491217492217493217494217495217496217497217498217499217500217501217502217503217504217505217506217507217508217509217510217511217512217513217514217515217516217517217518217519217520217521217522217523217524217525217526217527217528217529217530217531217532217533217534217535217536217537217538217539217540217541217542217543217544217545217546217547217548217549217550217551217552217553217554217555217556217557217558217559217560217561217562217563217564217565217566217567217568217569217570217571217572217573217574217575217576217577217578217579217580217581217582217583217584217585217586217587217588217589217590217591217592217593217594217595217596217597217598217599217600217601217602217603217604217605217606217607217608217609217610217611217612217613217614217615217616217617217618217619217620217621217622217623217624217625217626217627217628217629217630217631217632217633217634217635217636217637217638217639217640217641217642217643217644217645217646217647217648217649217650217651217652217653217654217655217656217657217658217659217660217661217662217663217664217665217666217667217668217669217670217671217672217673217674217675217676217677217678217679217680217681217682217683217684217685217686217687217688217689217690217691217692217693217694217695217696217697217698217699217700217701217702217703217704217705217706217707217708217709217710217711217712217713217714217715217716217717217718217719217720217721217722217723217724217725217726217727217728217729217730217731217732217733217734217735217736217737217738217739217740217741217742217743217744217745217746217747217748217749217750217751217752217753217754217755217756217757217758217759217760217761217762217763217764217765217766217767217768217769217770217771217772217773217774217775217776217777217778217779217780217781217782217783217784217785217786217787217788217789217790217791217792217793217794217795217796217797217798217799217800217801217802217803217804217805217806217807217808217809217810217811217812217813217814217815217816217817217818217819217820217821217822217823217824217825217826217827217828217829217830217831217832217833217834217835217836217837217838217839217840217841217842217843217844217845217846217847217848217849217850217851217852217853217854217855217856217857217858217859217860217861217862217863217864217865217866217867217868217869217870217871217872217873217874217875217876217877217878217879217880217881217882217883217884217885217886217887217888217889217890217891217892217893217894217895217896217897217898217899217900217901217902217903217904217905217906217907217908217909217910217911217912217913217914217915217916217917217918217919217920217921217922217923217924217925217926217927217928217929217930217931217932217933217934217935217936217937217938217939217940217941217942217943217944217945217946217947217948217949217950217951217952217953217954217955217956217957217958217959217960217961217962217963217964217965217966217967217968217969217970217971217972217973217974217975217976217977217978217979217980217981217982217983217984217985217986217987217988217989217990217991217992217993217994217995217996217997217998217999218000218001218002218003218004218005218006218007218008218009218010218011218012218013218014218015218016218017218018218019218020218021218022218023218024218025218026218027218028218029218030218031218032218033218034218035218036218037218038218039218040218041218042218043218044218045218046218047218048218049218050218051218052218053218054218055218056218057218058218059218060218061218062218063218064218065218066218067218068218069218070218071218072218073218074218075218076218077218078218079218080218081218082218083218084218085218086218087218088218089218090218091218092218093218094218095218096218097218098218099218100218101218102218103218104218105218106218107218108218109218110218111218112218113218114218115218116218117218118218119218120218121218122218123218124218125218126218127218128218129218130218131218132218133218134218135218136218137218138218139218140218141218142218143218144218145218146218147218148218149218150218151218152218153218154218155218156218157218158218159218160218161218162218163218164218165218166218167218168218169218170218171218172218173218174218175218176218177218178218179218180218181218182218183218184218185218186218187218188218189218190218191218192218193218194218195218196218197218198218199218200218201218202218203218204218205218206218207218208218209218210218211218212218213218214218215218216218217218218218219218220218221218222218223218224218225218226218227218228218229218230218231218232218233218234218235218236218237218238218239218240218241218242218243218244218245218246218247218248218249218250218251218252218253218254218255218256218257218258218259218260218261218262218263218264218265218266218267218268218269218270218271218272218273218274218275218276218277218278218279218280218281218282218283218284218285218286218287218288218289218290218291218292218293218294218295218296218297218298218299218300218301218302218303218304218305218306218307218308218309218310218311218312218313218314218315218316218317218318218319218320218321218322218323218324218325218326218327218328218329218330218331218332218333218334218335218336218337218338218339218340218341218342218343218344218345218346218347218348218349218350218351218352218353218354218355218356218357218358218359218360218361218362218363218364218365218366218367218368218369218370218371218372218373218374218375218376218377218378218379218380218381218382218383218384218385218386218387218388218389218390218391218392218393218394218395218396218397218398218399218400218401218402218403218404218405218406218407218408218409218410218411218412218413218414218415218416218417218418218419218420218421218422218423218424218425218426218427218428218429218430218431218432218433218434218435218436218437218438218439218440218441218442218443218444218445218446218447218448218449218450218451218452218453218454218455218456218457218458218459218460218461218462218463218464218465218466218467218468218469218470218471218472218473218474218475218476218477218478218479218480218481218482218483218484218485218486218487218488218489218490218491218492218493218494218495218496218497218498218499218500218501218502218503218504218505218506218507218508218509218510218511218512218513218514218515218516218517218518218519218520218521218522218523218524218525218526218527218528218529218530218531218532218533218534218535218536218537218538218539218540218541218542218543218544218545218546218547218548218549218550218551218552218553218554218555218556218557218558218559218560218561218562218563218564218565218566218567218568218569218570218571218572218573218574218575218576218577218578218579218580218581218582218583218584218585218586218587218588218589218590218591218592218593218594218595218596218597218598218599218600218601218602218603218604218605218606218607218608218609218610218611218612218613218614218615218616218617218618218619218620218621218622218623218624218625218626218627218628218629218630218631218632218633218634218635218636218637218638218639218640218641218642218643218644218645218646218647218648218649218650218651218652218653218654218655218656218657218658218659218660218661218662218663218664218665218666218667218668218669218670218671218672218673218674218675218676218677218678218679218680218681218682218683218684218685218686218687218688218689218690218691218692218693218694218695218696218697218698218699218700218701218702218703218704218705218706218707218708218709218710218711218712218713218714218715218716218717218718218719218720218721218722218723218724218725218726218727218728218729218730218731218732218733218734218735218736218737218738218739218740218741218742218743218744218745218746218747218748218749218750218751218752218753218754218755218756218757218758218759218760218761218762218763218764218765218766218767218768218769218770218771218772218773218774218775218776218777218778218779218780218781218782218783218784218785218786218787218788218789218790218791218792218793218794218795218796218797218798218799218800218801218802218803218804218805218806218807218808218809218810218811218812218813218814218815218816218817218818218819218820218821218822218823218824218825218826218827218828218829218830218831218832218833218834218835218836218837218838218839218840218841218842218843218844218845218846218847218848218849218850218851218852218853218854218855218856218857218858218859218860218861218862218863218864218865218866218867218868218869218870218871218872218873218874218875218876218877218878218879218880218881218882218883218884218885218886218887218888218889218890218891218892218893218894218895218896218897218898218899218900218901218902218903218904218905218906218907218908218909218910218911218912218913218914218915218916218917218918218919218920218921218922218923218924218925218926218927218928218929218930218931218932218933218934218935218936218937218938218939218940218941218942218943218944218945218946218947218948218949218950218951218952218953218954218955218956218957218958218959218960218961218962218963218964218965218966218967218968218969218970218971218972218973218974218975218976218977218978218979218980218981218982218983218984218985218986218987218988218989218990218991218992218993218994218995218996218997218998218999219000219001219002219003219004219005219006219007219008219009219010219011219012219013219014219015219016219017219018219019219020219021219022219023219024219025219026219027219028219029219030219031219032219033219034219035219036219037219038219039219040219041219042219043219044219045219046219047219048219049219050219051219052219053219054219055219056219057219058219059219060219061219062219063219064219065219066219067219068219069219070219071219072219073219074219075219076219077219078219079219080219081219082219083219084219085219086219087219088219089219090219091219092219093219094219095219096219097219098219099219100219101219102219103219104219105219106219107219108219109219110219111219112219113219114219115219116219117219118219119219120219121219122219123219124219125219126219127219128219129219130219131219132219133219134219135219136219137219138219139219140219141219142219143219144219145219146219147219148219149219150219151219152219153219154219155219156219157219158219159219160219161219162219163219164219165219166219167219168219169219170219171219172219173219174219175219176219177219178219179219180219181219182219183219184219185219186219187219188219189219190219191219192219193219194219195219196219197219198219199219200219201219202219203219204219205219206219207219208219209219210219211219212219213219214219215219216219217219218219219219220219221219222219223219224219225219226219227219228219229219230219231219232219233219234219235219236219237219238219239219240219241219242219243219244219245219246219247219248219249219250219251219252219253219254219255219256219257219258219259219260219261219262219263219264219265219266219267219268219269219270219271219272219273219274219275219276219277219278219279219280219281219282219283219284219285219286219287219288219289219290219291219292219293219294219295219296219297219298219299219300219301219302219303219304219305219306219307219308219309219310219311219312219313219314219315219316219317219318219319219320219321219322219323219324219325219326219327219328219329219330219331219332219333219334219335219336219337219338219339219340219341219342219343219344219345219346219347219348219349219350219351219352219353219354219355219356219357219358219359219360219361219362219363219364219365219366219367219368219369219370219371219372219373219374219375219376219377219378219379219380219381219382219383219384219385219386219387219388219389219390219391219392219393219394219395219396219397219398219399219400219401219402219403219404219405219406219407219408219409219410219411219412219413219414219415219416219417219418219419219420219421219422219423219424219425219426219427219428219429219430219431219432219433219434219435219436219437219438219439219440219441219442219443219444219445219446219447219448219449219450219451219452219453219454219455219456219457219458219459219460219461219462219463219464219465219466219467219468219469219470219471219472219473219474219475219476219477219478219479219480219481219482219483219484219485219486219487219488219489219490219491219492219493219494219495219496219497219498219499219500219501219502219503219504219505219506219507219508219509219510219511219512219513219514219515219516219517219518219519219520219521219522219523219524219525219526219527219528219529219530219531219532219533219534219535219536219537219538219539219540219541219542219543219544219545219546219547219548219549219550219551219552219553219554219555219556219557219558219559219560219561219562219563219564219565219566219567219568219569219570219571219572219573219574219575219576219577219578219579219580219581219582219583219584219585219586219587219588219589219590219591219592219593219594219595219596219597219598219599219600219601219602219603219604219605219606219607219608219609219610219611219612219613219614219615219616219617219618219619219620219621219622219623219624219625219626219627219628219629219630219631219632219633219634219635219636219637219638219639219640219641219642219643219644219645219646219647219648219649219650219651219652219653219654219655219656219657219658219659219660219661219662219663219664219665219666219667219668219669219670219671219672219673219674219675219676219677219678219679219680219681219682219683219684219685219686219687219688219689219690219691219692219693219694219695219696219697219698219699219700219701219702219703219704219705219706219707219708219709219710219711219712219713219714219715219716219717219718219719219720219721219722219723219724219725219726219727219728219729219730219731219732219733219734219735219736219737219738219739219740219741219742219743219744219745219746219747219748219749219750219751219752219753219754219755219756219757219758219759219760219761219762219763219764219765219766219767219768219769219770219771219772219773219774219775219776219777219778219779219780219781219782219783219784219785219786219787219788219789219790219791219792219793219794219795219796219797219798219799219800219801219802219803219804219805219806219807219808219809219810219811219812219813219814219815219816219817219818219819219820219821219822219823219824219825219826219827219828219829219830219831219832219833219834219835219836219837219838219839219840219841219842219843219844219845219846219847219848219849219850219851219852219853219854219855219856219857219858219859219860219861219862219863219864219865219866219867219868219869219870219871219872219873219874219875219876219877219878219879219880219881219882219883219884219885219886219887219888219889219890219891219892219893219894219895219896219897219898219899219900219901219902219903219904219905219906219907219908219909219910219911219912219913219914219915219916219917219918219919219920219921219922219923219924219925219926219927219928219929219930219931219932219933219934219935219936219937219938219939219940219941219942219943219944219945219946219947219948219949219950219951219952219953219954219955219956219957219958219959219960219961219962219963219964219965219966219967219968219969219970219971219972219973219974219975219976219977219978219979219980219981219982219983219984219985219986219987219988219989219990219991219992219993219994219995219996219997219998219999220000220001220002220003220004220005220006220007220008220009220010220011220012220013220014220015220016220017220018220019220020220021220022220023220024220025220026220027220028220029220030220031220032220033220034220035220036220037220038220039220040220041220042220043220044220045220046220047220048220049220050220051220052220053220054220055220056220057220058220059220060220061220062220063220064220065220066220067220068220069220070220071220072220073220074220075220076220077220078220079220080220081220082220083220084220085220086220087220088220089220090220091220092220093220094220095220096220097220098220099220100220101220102220103220104220105220106220107220108220109220110220111220112220113220114220115220116220117220118220119220120220121220122220123220124220125220126220127220128220129220130220131220132220133220134220135220136220137220138220139220140220141220142220143220144220145220146220147220148220149220150220151220152220153220154220155220156220157220158220159220160220161220162220163220164220165220166220167220168220169220170220171220172220173220174220175220176220177220178220179220180220181220182220183220184220185220186220187220188220189220190220191220192220193220194220195220196220197220198220199220200220201220202220203220204220205220206220207220208220209220210220211220212220213220214220215220216220217220218220219220220220221220222220223220224220225220226220227220228220229220230220231220232220233220234220235220236220237220238220239220240220241220242220243220244220245220246220247220248220249220250220251220252220253220254220255220256220257220258220259220260220261220262220263220264220265220266220267220268220269220270220271220272220273220274220275220276220277220278220279220280220281220282220283220284220285220286220287220288220289220290220291220292220293220294220295220296220297220298220299220300220301220302220303220304220305220306220307220308220309220310220311220312220313220314220315220316220317220318220319220320220321220322220323220324220325220326220327220328220329220330220331220332220333220334220335220336220337220338220339220340220341220342220343220344220345220346220347220348220349220350220351220352220353220354220355220356220357220358220359220360220361220362220363220364220365220366220367220368220369220370220371220372220373220374220375220376220377220378220379220380220381220382220383220384220385220386220387220388220389220390220391220392220393220394220395220396220397220398220399220400220401220402220403220404220405220406220407220408220409220410220411220412220413220414220415220416220417220418220419220420220421220422220423220424220425220426220427220428220429220430220431220432220433220434220435220436220437220438220439220440220441220442220443220444220445220446220447220448220449220450220451220452220453220454220455220456220457220458220459220460220461220462220463220464220465220466220467220468220469220470220471220472220473220474220475220476220477220478220479220480220481220482220483220484220485220486220487220488220489220490220491220492220493220494220495220496220497220498220499220500220501220502220503220504220505220506220507220508220509220510220511220512220513220514220515220516220517220518220519220520220521220522220523220524220525220526220527220528220529220530220531220532220533220534220535220536220537220538220539220540220541220542220543220544220545220546220547220548220549220550220551220552220553220554220555220556220557220558220559220560220561220562220563220564220565220566220567220568220569220570220571220572220573220574220575220576220577220578220579220580220581220582220583220584220585220586220587220588220589220590220591220592220593220594220595220596220597220598220599220600220601220602220603220604220605220606220607220608220609220610220611220612220613220614220615220616220617220618220619220620220621220622220623220624220625220626220627220628220629220630220631220632220633220634220635220636220637220638220639220640220641220642220643220644220645220646220647220648220649220650220651220652220653220654220655220656220657220658220659220660220661220662220663220664220665220666220667220668220669220670220671220672220673220674220675220676220677220678220679220680220681220682220683220684220685220686220687220688220689220690220691220692220693220694220695220696220697220698220699220700220701220702220703220704220705220706220707220708220709220710220711220712220713220714220715220716220717220718220719220720220721220722220723220724220725220726220727220728220729220730220731220732220733220734220735220736220737220738220739220740220741220742220743220744220745220746220747220748220749220750220751220752220753220754220755220756220757220758220759220760220761220762220763220764220765220766220767220768220769220770220771220772220773220774220775220776220777220778220779220780220781220782220783220784220785220786220787220788220789220790220791220792220793220794220795220796220797220798220799220800220801220802220803220804220805220806220807220808220809220810220811220812220813220814220815220816220817220818220819220820220821220822220823220824220825220826220827220828220829220830220831220832220833220834220835220836220837220838220839220840220841220842220843220844220845220846220847220848220849220850220851220852220853220854220855220856220857220858220859220860220861220862220863220864220865220866220867220868220869220870220871220872220873220874220875220876220877220878220879220880220881220882220883220884220885220886220887220888220889220890220891220892220893220894220895220896220897220898220899220900220901220902220903220904220905220906220907220908220909220910220911220912220913220914220915220916220917220918220919220920220921220922220923220924220925220926220927220928220929220930220931220932220933220934220935220936220937220938220939220940220941220942220943220944220945220946220947220948220949220950220951220952220953220954220955220956220957220958220959220960220961220962220963220964220965220966220967220968220969220970220971220972220973220974220975220976220977220978220979220980220981220982220983220984220985220986220987220988220989220990220991220992220993220994220995220996220997220998220999221000221001221002221003221004221005221006221007221008221009221010221011221012221013221014221015221016221017221018221019221020221021221022221023221024221025221026221027221028221029221030221031221032221033221034221035221036221037221038221039221040221041221042221043221044221045221046221047221048221049221050221051221052221053221054221055221056221057221058221059221060221061221062221063221064221065221066221067221068221069221070221071221072221073221074221075221076221077221078221079221080221081221082221083221084221085221086221087221088221089221090221091221092221093221094221095221096221097221098221099221100221101221102221103221104221105221106221107221108221109221110221111221112221113221114221115221116221117221118221119221120221121221122221123221124221125221126221127221128221129221130221131221132221133221134221135221136221137221138221139221140221141221142221143221144221145221146221147221148221149221150221151221152221153221154221155221156221157221158221159221160221161221162221163221164221165221166221167221168221169221170221171221172221173221174221175221176221177221178221179221180221181221182221183221184221185221186221187221188221189221190221191221192221193221194221195221196221197221198221199221200221201221202221203221204221205221206221207221208221209221210221211221212221213221214221215221216221217221218221219221220221221221222221223221224221225221226221227221228221229221230221231221232221233221234221235221236221237221238221239221240221241221242221243221244221245221246221247221248221249221250221251221252221253221254221255221256221257221258221259221260221261221262221263221264221265221266221267221268221269221270221271221272221273221274221275221276221277221278221279221280221281221282221283221284221285221286221287221288221289221290221291221292221293221294221295221296221297221298221299221300221301221302221303221304221305221306221307221308221309221310221311221312221313221314221315221316221317221318221319221320221321221322221323221324221325221326221327221328221329221330221331221332221333221334221335221336221337221338221339221340221341221342221343221344221345221346221347221348221349221350221351221352221353221354221355221356221357221358221359221360221361221362221363221364221365221366221367221368221369221370221371221372221373221374221375221376221377221378221379221380221381221382221383221384221385221386221387221388221389221390221391221392221393221394221395221396221397221398221399221400221401221402221403221404221405221406221407221408221409221410221411221412221413221414221415221416221417221418221419221420221421221422221423221424221425221426221427221428221429221430221431221432221433221434221435221436221437221438221439221440221441221442221443221444221445221446221447221448221449221450221451221452221453221454221455221456221457221458221459221460221461221462221463221464221465221466221467221468221469221470221471221472221473221474221475221476221477221478221479221480221481221482221483221484221485221486221487221488221489221490221491221492221493221494221495221496221497221498221499221500221501221502221503221504221505221506221507221508221509221510221511221512221513221514221515221516221517221518221519221520221521221522221523221524221525221526221527221528221529221530221531221532221533221534221535221536221537221538221539221540221541221542221543221544221545221546221547221548221549221550221551221552221553221554221555221556221557221558221559221560221561221562221563221564221565221566221567221568221569221570221571221572221573221574221575221576221577221578221579221580221581221582221583221584221585221586221587221588221589221590221591221592221593221594221595221596221597221598221599221600221601221602221603221604221605221606221607221608221609221610221611221612221613221614221615221616221617221618221619221620221621221622221623221624221625221626221627221628221629221630221631221632221633221634221635221636221637221638221639221640221641221642221643221644221645221646221647221648221649221650221651221652221653221654221655221656221657221658221659221660221661221662221663221664221665221666221667221668221669221670221671221672221673221674221675221676221677221678221679221680221681221682221683221684221685221686221687221688221689221690221691221692221693221694221695221696221697221698221699221700221701221702221703221704221705221706221707221708221709221710221711221712221713221714221715221716221717221718221719221720221721221722221723221724221725221726221727221728221729221730221731221732221733221734221735221736221737221738221739221740221741221742221743221744221745221746221747221748221749221750221751221752221753221754221755221756221757221758221759221760221761221762221763221764221765221766221767221768221769221770221771221772221773221774221775221776221777221778221779221780221781221782221783221784221785221786221787221788221789221790221791221792221793221794221795221796221797221798221799221800221801221802221803221804221805221806221807221808221809221810221811221812221813221814221815221816221817221818221819221820221821221822221823221824221825221826221827221828221829221830221831221832221833221834221835221836221837221838221839221840221841221842221843221844221845221846221847221848221849221850221851221852221853221854221855221856221857221858221859221860221861221862221863221864221865221866221867221868221869221870221871221872221873221874221875221876221877221878221879221880221881221882221883221884221885221886221887221888221889221890221891221892221893221894221895221896221897221898221899221900221901221902221903221904221905221906221907221908221909221910221911221912221913221914221915221916221917221918221919221920221921221922221923221924221925221926221927221928221929221930221931221932221933221934221935221936221937221938221939221940221941221942221943221944221945221946221947221948221949221950221951221952221953221954221955221956221957221958221959221960221961221962221963221964221965221966221967221968221969221970221971221972221973221974221975221976221977221978221979221980221981221982221983221984221985221986221987221988221989221990221991221992221993221994221995221996221997221998221999222000222001222002222003222004222005222006222007222008222009222010222011222012222013222014222015222016222017222018222019222020222021222022222023222024222025222026222027222028222029222030222031222032222033222034222035222036222037222038222039222040222041222042222043222044222045222046222047222048222049222050222051222052222053222054222055222056222057222058222059222060222061222062222063222064222065222066222067222068222069222070222071222072222073222074222075222076222077222078222079222080222081222082222083222084222085222086222087222088222089222090222091222092222093222094222095222096222097222098222099222100222101222102222103222104222105222106222107222108222109222110222111222112222113222114222115222116222117222118222119222120222121222122222123222124222125222126222127222128222129222130222131222132222133222134222135222136222137222138222139222140222141222142222143222144222145222146222147222148222149222150222151222152222153222154222155222156222157222158222159222160222161222162222163222164222165222166222167222168222169222170222171222172222173222174222175222176222177222178222179222180222181222182222183222184222185222186222187222188222189222190222191222192222193222194222195222196222197222198222199222200222201222202222203222204222205222206222207222208222209222210222211222212222213222214222215222216222217222218222219222220222221222222222223222224222225222226222227222228222229222230222231222232222233222234222235222236222237222238222239222240222241222242222243222244222245222246222247222248222249222250222251222252222253222254222255222256222257222258222259222260222261222262222263222264222265222266222267222268222269222270222271222272222273222274222275222276222277222278222279222280222281222282222283222284222285222286222287222288222289222290222291222292222293222294222295222296222297222298222299222300222301222302222303222304222305222306222307222308222309222310222311222312222313222314222315222316222317222318222319222320222321222322222323222324222325222326222327222328222329222330222331222332222333222334222335222336222337222338222339222340222341222342222343222344222345222346222347222348222349222350222351222352222353222354222355222356222357222358222359222360222361222362222363222364222365222366222367222368222369222370222371222372222373222374222375222376222377222378222379222380222381222382222383222384222385222386222387222388222389222390222391222392222393222394222395222396222397222398222399222400222401222402222403222404222405222406222407222408222409222410222411222412222413222414222415222416222417222418222419222420222421222422222423222424222425222426222427222428222429222430222431222432222433222434222435222436222437222438222439222440222441222442222443222444222445222446222447222448222449222450222451222452222453222454222455222456222457222458222459222460222461222462222463222464222465222466222467222468222469222470222471222472222473222474222475222476222477222478222479222480222481222482222483222484222485222486222487222488222489222490222491222492222493222494222495222496222497222498222499222500222501222502222503222504222505222506222507222508222509222510222511222512222513222514222515222516222517222518222519222520222521222522222523222524222525222526222527222528222529222530222531222532222533222534222535222536222537222538222539222540222541222542222543222544222545222546222547222548222549222550222551222552222553222554222555222556222557222558222559222560222561222562222563222564222565222566222567222568222569222570222571222572222573222574222575222576222577222578222579222580222581222582222583222584222585222586222587222588222589222590222591222592222593222594222595222596222597222598222599222600222601222602222603222604222605222606222607222608222609222610222611222612222613222614222615222616222617222618222619222620222621222622222623222624222625222626222627222628222629222630222631222632222633222634222635222636222637222638222639222640222641222642222643222644222645222646222647222648222649222650222651222652222653222654222655222656222657222658222659222660222661222662222663222664222665222666222667222668222669222670222671222672222673222674222675222676222677222678222679222680222681222682222683222684222685222686222687222688222689222690222691222692222693222694222695222696222697222698222699222700222701222702222703222704222705222706222707222708222709222710222711222712222713222714222715222716222717222718222719222720222721222722222723222724222725222726222727222728222729222730222731222732222733222734222735222736222737222738222739222740222741222742222743222744222745222746222747222748222749222750222751222752222753222754222755222756222757222758222759222760222761222762222763222764222765222766222767222768222769222770222771222772222773222774222775222776222777222778222779222780222781222782222783222784222785222786222787222788222789222790222791222792222793222794222795222796222797222798222799222800222801222802222803222804222805222806222807222808222809222810222811222812222813222814222815222816222817222818222819222820222821222822222823222824222825222826222827222828222829222830222831222832222833222834222835222836222837222838222839222840222841222842222843222844222845222846222847222848222849222850222851222852222853222854222855222856222857222858222859222860222861222862222863222864222865222866222867222868222869222870222871222872222873222874222875222876222877222878222879222880222881222882222883222884222885222886222887222888222889222890222891222892222893222894222895222896222897222898222899222900222901222902222903222904222905222906222907222908222909222910222911222912222913222914222915222916222917222918222919222920222921222922222923222924222925222926222927222928222929222930222931222932222933222934222935222936222937222938222939222940222941222942222943222944222945222946222947222948222949222950222951222952222953222954222955222956222957222958222959222960222961222962222963222964222965222966222967222968222969222970222971222972222973222974222975222976222977222978222979222980222981222982222983222984222985222986222987222988222989222990222991222992222993222994222995222996222997222998222999223000223001223002223003223004223005223006223007223008223009223010223011223012223013223014223015223016223017223018223019223020223021223022223023223024223025223026223027223028223029223030223031223032223033223034223035223036223037223038223039223040223041223042223043223044223045223046223047223048223049223050223051223052223053223054223055223056223057223058223059223060223061223062223063223064223065223066223067223068223069223070223071223072223073223074223075223076223077223078223079223080223081223082223083223084223085223086223087223088223089223090223091223092223093223094223095223096223097223098223099223100223101223102223103223104223105223106223107223108223109223110223111223112223113223114223115223116223117223118223119223120223121223122223123223124223125223126223127223128223129223130223131223132223133223134223135223136223137223138223139223140223141223142223143223144223145223146223147223148223149223150223151223152223153223154223155223156223157223158223159223160223161223162223163223164223165223166223167223168223169223170223171223172223173223174223175223176223177223178223179223180223181223182223183223184223185223186223187223188223189223190223191223192223193223194223195223196223197223198223199223200223201223202223203223204223205223206223207223208223209223210223211223212223213223214223215223216223217223218223219223220223221223222223223223224223225223226223227223228223229223230223231223232223233223234223235223236223237223238223239223240223241223242223243223244223245223246223247223248223249223250223251223252223253223254223255223256223257223258223259223260223261223262223263223264223265223266223267223268223269223270223271223272223273223274223275223276223277223278223279223280223281223282223283223284223285223286223287223288223289223290223291223292223293223294223295223296223297223298223299223300223301223302223303223304223305223306223307223308223309223310223311223312223313223314223315223316223317223318223319223320223321223322223323223324223325223326223327223328223329223330223331223332223333223334223335223336223337223338223339223340223341223342223343223344223345223346223347223348223349223350223351223352223353223354223355223356223357223358223359223360223361223362223363223364223365223366223367223368223369223370223371223372223373223374223375223376223377223378223379223380223381223382223383223384223385223386223387223388223389223390223391223392223393223394223395223396223397223398223399223400223401223402223403223404223405223406223407223408223409223410223411223412223413223414223415223416223417223418223419223420223421223422223423223424223425223426223427223428223429223430223431223432223433223434223435223436223437223438223439223440223441223442223443223444223445223446223447223448223449223450223451223452223453223454223455223456223457223458223459223460223461223462223463223464223465223466223467223468223469223470223471223472223473223474223475223476223477223478223479223480223481223482223483223484223485223486223487223488223489223490223491223492223493223494223495223496223497223498223499223500223501223502223503223504223505223506223507223508223509223510223511223512223513223514223515223516223517223518223519223520223521223522223523223524223525223526223527223528223529223530223531223532223533223534223535223536223537223538223539223540223541223542223543223544223545223546223547223548223549223550223551223552223553223554223555223556223557223558223559223560223561223562223563223564223565223566223567223568223569223570223571223572223573223574223575223576223577223578223579223580223581223582223583223584223585223586223587223588223589223590223591223592223593223594223595223596223597223598223599223600223601223602223603223604223605223606223607223608223609223610223611223612223613223614223615223616223617223618223619223620223621223622223623223624223625223626223627223628223629223630223631223632223633223634223635223636223637223638223639223640223641223642223643223644223645223646223647223648223649223650223651223652223653223654223655223656223657223658223659223660223661223662223663223664223665223666223667223668223669223670223671223672223673223674223675223676223677223678223679223680223681223682223683223684223685223686223687223688223689223690223691223692223693223694223695223696223697223698223699223700223701223702223703223704223705223706223707223708223709223710223711223712223713223714223715223716223717223718223719223720223721223722223723223724223725223726223727223728223729223730223731223732223733223734223735223736223737223738223739223740223741223742223743223744223745223746223747223748223749223750223751223752223753223754223755223756223757223758223759223760223761223762223763223764223765223766223767223768223769223770223771223772223773223774223775223776223777223778223779223780223781223782223783223784223785223786223787223788223789223790223791223792223793223794223795223796223797223798223799223800223801223802223803223804223805223806223807223808223809223810223811223812223813223814223815223816223817223818223819223820223821223822223823223824223825223826223827223828223829223830223831223832223833223834223835223836223837223838223839223840223841223842223843223844223845223846223847223848223849223850223851223852223853223854223855223856223857223858223859223860223861223862223863223864223865223866223867223868223869223870223871223872223873223874223875223876223877223878223879223880223881223882223883223884223885223886223887223888223889223890223891223892223893223894223895223896223897223898223899223900223901223902223903223904223905223906223907223908223909223910223911223912223913223914223915223916223917223918223919223920223921223922223923223924223925223926223927223928223929223930223931223932223933223934223935223936223937223938223939223940223941223942223943223944223945223946223947223948223949223950223951223952223953223954223955223956223957223958223959223960223961223962223963223964223965223966223967223968223969223970223971223972223973223974223975223976223977223978223979223980223981223982223983223984223985223986223987223988223989223990223991223992223993223994223995223996223997223998223999224000224001224002224003224004224005224006224007224008224009224010224011224012224013224014224015224016224017224018224019224020224021224022224023224024224025224026224027224028224029224030224031224032224033224034224035224036224037224038224039224040224041224042224043224044224045224046224047224048224049224050224051224052224053224054224055224056224057224058224059224060224061224062224063224064224065224066224067224068224069224070224071224072224073224074224075224076224077224078224079224080224081224082224083224084224085224086224087224088224089224090224091224092224093224094224095224096224097224098224099224100224101224102224103224104224105224106224107224108224109224110224111224112224113224114224115224116224117224118224119224120224121224122224123224124224125224126224127224128224129224130224131224132224133224134224135224136224137224138224139224140224141224142224143224144224145224146224147224148224149224150224151224152224153224154224155224156224157224158224159224160224161224162224163224164224165224166224167224168224169224170224171224172224173224174224175224176224177224178224179224180224181224182224183224184224185224186224187224188224189224190224191224192224193224194224195224196224197224198224199224200224201224202224203224204224205224206224207224208224209224210224211224212224213224214224215224216224217224218224219224220224221224222224223224224224225224226224227224228224229224230224231224232224233224234224235224236224237224238224239224240224241224242224243224244224245224246224247224248224249224250224251224252224253224254224255224256224257224258224259224260224261224262224263224264224265224266224267224268224269224270224271224272224273224274224275224276224277224278224279224280224281224282224283224284224285224286224287224288224289224290224291224292224293224294224295224296224297224298224299224300224301224302224303224304224305224306224307224308224309224310224311224312224313224314224315224316224317224318224319224320224321224322224323224324224325224326224327224328224329224330224331224332224333224334224335224336224337224338224339224340224341224342224343224344224345224346224347224348224349224350224351224352224353224354224355224356224357224358224359224360224361224362224363224364224365224366224367224368224369224370224371224372224373224374224375224376224377224378224379224380224381224382224383224384224385224386224387224388224389224390224391224392224393224394224395224396224397224398224399224400224401224402224403224404224405224406224407224408224409224410224411224412224413224414224415224416224417224418224419224420224421224422224423224424224425224426224427224428224429224430224431224432224433224434224435224436224437224438224439224440224441224442224443224444224445224446224447224448224449224450224451224452224453224454224455224456224457224458224459224460224461224462224463224464224465224466224467224468224469224470224471224472224473224474224475224476224477224478224479224480224481224482224483224484224485224486224487224488224489224490224491224492224493224494224495224496224497224498224499224500224501224502224503224504224505224506224507224508224509224510224511224512224513224514224515224516224517224518224519224520224521224522224523224524224525224526224527224528224529224530224531224532224533224534224535224536224537224538224539224540224541224542224543224544224545224546224547224548224549224550224551224552224553224554224555224556224557224558224559224560224561224562224563224564224565224566224567224568224569224570224571224572224573224574224575224576224577224578224579224580224581224582224583224584224585224586224587224588224589224590224591224592224593224594224595224596224597224598224599224600224601224602224603224604224605224606224607224608224609224610224611224612224613224614224615224616224617224618224619224620224621224622224623224624224625224626224627224628224629224630224631224632224633224634224635224636224637224638224639224640224641224642224643224644224645224646224647224648224649224650224651224652224653224654224655224656224657224658224659224660224661224662224663224664224665224666224667224668224669224670224671224672224673224674224675224676224677224678224679224680224681224682224683224684224685224686224687224688224689224690224691224692224693224694224695224696224697224698224699224700224701224702224703224704224705224706224707224708224709224710224711224712224713224714224715224716224717224718224719224720224721224722224723224724224725224726224727224728224729224730224731224732224733224734224735224736224737224738224739224740224741224742224743224744224745224746224747224748224749224750224751224752224753224754224755224756224757224758224759224760224761224762224763224764224765224766224767224768224769224770224771224772224773224774224775224776224777224778224779224780224781224782224783224784224785224786224787224788224789224790224791224792224793224794224795224796224797224798224799224800224801224802224803224804224805224806224807224808224809224810224811224812224813224814224815224816224817224818224819224820224821224822224823224824224825224826224827224828224829224830224831224832224833224834224835224836224837224838224839224840224841224842224843224844224845224846224847224848224849224850224851224852224853224854224855224856224857224858224859224860224861224862224863224864224865224866224867224868224869224870224871224872224873224874224875224876224877224878224879224880224881224882224883224884224885224886224887224888224889224890224891224892224893224894224895224896224897224898224899224900224901224902224903224904224905224906224907224908224909224910224911224912224913224914224915224916224917224918224919224920224921224922224923224924224925224926224927224928224929224930224931224932224933224934224935224936224937224938224939224940224941224942224943224944224945224946224947224948224949224950224951224952224953224954224955224956224957224958224959224960224961224962224963224964224965224966224967224968224969224970224971224972224973224974224975224976224977224978224979224980224981224982224983224984224985224986224987224988224989224990224991224992224993224994224995224996224997224998224999225000225001225002225003225004225005225006225007225008225009225010225011225012225013225014225015225016225017225018225019225020225021225022225023225024225025225026225027225028225029225030225031225032225033225034225035225036225037225038225039225040225041225042225043225044225045225046225047225048225049225050225051225052225053225054225055225056225057225058225059225060225061225062225063225064225065225066225067225068225069225070225071225072225073225074225075225076225077225078225079225080225081225082225083225084225085225086225087225088225089225090225091225092225093225094225095225096225097225098225099225100225101225102225103225104225105225106225107225108225109225110225111225112225113225114225115225116225117225118225119225120225121225122225123225124225125225126225127225128225129225130225131225132225133225134225135225136225137225138225139225140225141225142225143225144225145225146225147225148225149225150225151225152225153225154225155225156225157225158225159225160225161225162225163225164225165225166225167225168225169225170225171225172225173225174225175225176225177225178225179225180225181225182225183225184225185225186225187225188225189225190225191225192225193225194225195225196225197225198225199225200225201225202225203225204225205225206225207225208225209225210225211225212225213225214225215225216225217225218225219225220225221225222225223225224225225225226225227225228225229225230225231225232225233225234225235225236225237225238225239225240225241225242225243225244225245225246225247225248225249225250225251225252225253225254225255225256225257225258225259225260225261225262225263225264225265225266225267225268225269225270225271225272225273225274225275225276225277225278225279225280225281225282225283225284225285225286225287225288225289225290225291225292225293225294225295225296225297225298225299225300225301225302225303225304225305225306225307225308225309225310225311225312225313225314225315225316225317225318225319225320225321225322225323225324225325225326225327225328225329225330225331225332225333225334225335225336225337225338225339225340225341225342225343225344225345225346225347225348225349225350225351225352225353225354225355225356225357225358225359225360225361225362225363225364225365225366225367225368225369225370225371225372225373225374225375225376225377225378225379225380225381225382225383225384225385225386225387225388225389225390225391225392225393225394225395225396225397225398225399225400225401225402225403225404225405225406225407225408225409225410225411225412225413225414225415225416225417225418225419225420225421225422225423225424225425225426225427225428225429225430225431225432225433225434225435225436225437225438225439225440225441225442225443225444225445225446225447225448225449225450225451225452225453225454225455225456225457225458225459225460225461225462225463225464225465225466225467225468225469225470225471225472225473225474225475225476225477225478225479225480225481225482225483225484225485225486225487225488225489225490225491225492225493225494225495225496225497225498225499225500225501225502225503225504225505225506225507225508225509225510225511225512225513225514225515225516225517225518225519225520225521225522225523225524225525225526225527225528225529225530225531225532225533225534225535225536225537225538225539225540225541225542225543225544225545225546225547225548225549225550225551225552225553225554225555225556225557225558225559225560225561225562225563225564225565225566225567225568225569225570225571225572225573225574225575225576225577225578225579225580225581225582225583225584225585225586225587225588225589225590225591225592225593225594225595225596225597225598225599225600225601225602225603225604225605225606225607225608225609225610225611225612225613225614225615225616225617225618225619225620225621225622225623225624225625225626225627225628225629225630225631225632225633225634225635225636225637225638225639225640225641225642225643225644225645225646225647225648225649225650225651225652225653225654225655225656225657225658225659225660225661225662225663225664225665225666225667225668225669225670225671225672225673225674225675225676225677225678225679225680225681225682225683225684225685225686225687225688225689225690225691225692225693225694225695225696225697225698225699225700225701225702225703225704225705225706225707225708225709225710225711225712225713225714225715225716225717225718225719225720225721225722225723225724225725225726225727225728225729225730225731225732225733225734225735225736225737225738225739225740225741225742225743225744225745225746225747225748225749225750225751225752225753225754225755225756225757225758225759225760225761225762225763225764225765225766225767225768225769225770225771225772225773225774225775225776225777225778225779225780225781225782225783225784225785225786225787225788225789225790225791225792225793225794225795225796225797225798225799225800225801225802225803225804225805225806225807225808225809225810225811225812225813225814225815225816225817225818225819225820225821225822225823225824225825225826225827225828225829225830225831225832225833225834225835225836225837225838225839225840225841225842225843225844225845225846225847225848225849225850225851225852225853225854225855225856225857225858225859225860225861225862225863225864225865225866225867225868225869225870225871225872225873225874225875225876225877225878225879225880225881225882225883225884225885225886225887225888225889225890225891225892225893225894225895225896225897225898225899225900225901225902225903225904225905225906225907225908225909225910225911225912225913225914225915225916225917225918225919225920225921225922225923225924225925225926225927225928225929225930225931225932225933225934225935225936225937225938225939225940225941225942225943225944225945225946225947225948225949225950225951225952225953225954225955225956225957225958225959225960225961225962225963225964225965225966225967225968225969225970225971225972225973225974225975225976225977225978225979225980225981225982225983225984225985225986225987225988225989225990225991225992225993225994225995225996225997225998225999226000226001226002226003226004226005226006226007226008226009226010226011226012226013226014226015226016226017226018226019226020226021226022226023226024226025226026226027226028226029226030226031226032226033226034226035226036226037226038226039226040226041226042226043226044226045226046226047226048226049226050226051226052226053226054226055226056226057226058226059226060226061226062226063226064226065226066226067226068226069226070226071226072226073226074226075226076226077226078226079226080226081226082226083226084226085226086226087226088226089226090226091226092226093226094226095226096226097226098226099226100226101226102226103226104226105226106226107226108226109226110226111226112226113226114226115226116226117226118226119226120226121226122226123226124226125226126226127226128226129226130226131226132226133226134226135226136226137226138226139226140226141226142226143226144226145226146226147226148226149226150226151226152226153226154226155226156226157226158226159226160226161226162226163226164226165226166226167226168226169226170226171226172226173226174226175226176226177226178226179226180226181226182226183226184226185226186226187226188226189226190226191226192226193226194226195226196226197226198226199226200226201226202226203226204226205226206226207226208226209226210226211226212226213226214226215226216226217226218226219226220226221226222226223226224226225226226226227226228226229226230226231226232226233226234226235226236226237226238226239226240226241226242226243226244226245226246226247226248226249226250226251226252226253226254226255226256226257226258226259226260226261226262226263226264226265226266226267226268226269226270226271226272226273226274226275226276226277226278226279226280226281226282226283226284226285226286226287226288226289226290226291226292226293226294226295226296226297226298226299226300226301226302226303226304226305226306226307226308226309226310226311226312226313226314226315226316226317226318226319226320226321226322226323226324226325226326226327226328226329226330226331226332226333226334226335226336226337226338226339226340226341226342226343226344226345226346226347226348226349226350226351226352226353226354226355226356226357226358226359226360226361226362226363226364226365226366226367226368226369226370226371226372226373226374226375226376226377226378226379226380226381226382226383226384226385226386226387226388226389226390226391226392226393226394226395226396226397226398226399226400226401226402226403226404226405226406226407226408226409226410226411226412226413226414226415226416226417226418226419226420226421226422226423226424226425226426226427226428226429226430226431226432226433226434226435226436226437226438226439226440226441226442226443226444226445226446226447226448226449226450226451226452226453226454226455226456226457226458226459226460226461226462226463226464226465226466226467226468226469226470226471226472226473226474226475226476226477226478226479226480226481226482226483226484226485226486226487226488226489226490226491226492226493226494226495226496226497226498226499226500226501226502226503226504226505226506226507226508226509226510226511226512226513226514226515226516226517226518226519226520226521226522226523226524226525226526226527226528226529226530226531226532226533226534226535226536226537226538226539226540226541226542226543226544226545226546226547226548226549226550226551226552226553226554226555226556226557226558226559226560226561226562226563226564226565226566226567226568226569226570226571226572226573226574226575226576226577226578226579226580226581226582226583226584226585226586226587226588226589226590226591226592226593226594226595226596226597226598226599226600226601226602226603226604226605226606226607226608226609226610226611226612226613226614226615226616226617226618226619226620226621226622226623226624226625226626226627226628226629226630226631226632226633226634226635226636226637226638226639226640226641226642226643226644226645226646226647226648226649226650226651226652226653226654226655226656226657226658226659226660226661226662226663226664226665226666226667226668226669226670226671226672226673226674226675226676226677226678226679226680226681226682226683226684226685226686226687226688226689226690226691226692226693226694226695226696226697226698226699226700226701226702226703226704226705226706226707226708226709226710226711226712226713226714226715226716226717226718226719226720226721226722226723226724226725226726226727226728226729226730226731226732226733226734226735226736226737226738226739226740226741226742226743226744226745226746226747226748226749226750226751226752226753226754226755226756226757226758226759226760226761226762226763226764226765226766226767226768226769226770226771226772226773226774226775226776226777226778226779226780226781226782226783226784226785226786226787226788226789226790226791226792226793226794226795226796226797226798226799226800226801226802226803226804226805226806226807226808226809226810226811226812226813226814226815226816226817226818226819226820226821226822226823226824226825226826226827226828226829226830226831226832226833226834226835226836226837226838226839226840226841226842226843226844226845226846226847226848226849226850226851226852226853226854226855226856226857226858226859226860226861226862226863226864226865226866226867226868226869226870226871226872226873226874226875226876226877226878226879226880226881226882226883226884226885226886226887226888226889226890226891226892226893226894226895226896226897226898226899226900226901226902226903226904226905226906226907226908226909226910226911226912226913226914226915226916226917226918226919226920226921226922226923226924226925226926226927226928226929226930226931226932226933226934226935226936226937226938226939226940226941226942226943226944226945226946226947226948226949226950226951226952226953226954226955226956226957226958226959226960226961226962226963226964226965226966226967226968226969226970226971226972226973226974226975226976226977226978226979226980226981226982226983226984226985226986226987226988226989226990226991226992226993226994226995226996226997226998226999227000227001227002227003227004227005227006227007227008227009227010227011227012227013227014227015227016227017227018227019227020227021227022227023227024227025227026227027227028227029227030227031227032227033227034227035227036227037227038227039227040227041227042227043227044227045227046227047227048227049227050227051227052227053227054227055227056227057227058227059227060227061227062227063227064227065227066227067227068227069227070227071227072227073227074227075227076227077227078227079227080227081227082227083227084227085227086227087227088227089227090227091227092227093227094227095227096227097227098227099227100227101227102227103227104227105227106227107227108227109227110227111227112227113227114227115227116227117227118227119227120227121227122227123227124227125227126227127227128227129227130227131227132227133227134227135227136227137227138227139227140227141227142227143227144227145227146227147227148227149227150227151227152227153227154227155227156227157227158227159227160227161227162227163227164227165227166227167227168227169227170227171227172227173227174227175227176227177227178227179227180227181227182227183227184227185227186227187227188227189227190227191227192227193227194227195227196227197227198227199227200227201227202227203227204227205227206227207227208227209227210227211227212227213227214227215227216227217227218227219227220227221227222227223227224227225227226227227227228227229227230227231227232227233227234227235227236227237227238227239227240227241227242227243227244227245227246227247227248227249227250227251227252227253227254227255227256227257227258227259227260227261227262227263227264227265227266227267227268227269227270227271227272227273227274227275227276227277227278227279227280227281227282227283227284227285227286227287227288227289227290227291227292227293227294227295227296227297227298227299227300227301227302227303227304227305227306227307227308227309227310227311227312227313227314227315227316227317227318227319227320227321227322227323227324227325227326227327227328227329227330227331227332227333227334227335227336227337227338227339227340227341227342227343227344227345227346227347227348227349227350227351227352227353227354227355227356227357227358227359227360227361227362227363227364227365227366227367227368227369227370227371227372227373227374227375227376227377227378227379227380227381227382227383227384227385227386227387227388227389227390227391227392227393227394227395227396227397227398227399227400227401227402227403227404227405227406227407227408227409227410227411227412227413227414227415227416227417227418227419227420227421227422227423227424227425227426227427227428227429227430227431227432227433227434227435227436227437227438227439227440227441227442227443227444227445227446227447227448227449227450227451227452227453227454227455227456227457227458227459227460227461227462227463227464227465227466227467227468227469227470227471227472227473227474227475227476227477227478227479227480227481227482227483227484227485227486227487227488227489227490227491227492227493227494227495227496227497227498227499227500227501227502227503227504227505227506227507227508227509227510227511227512227513227514227515227516227517227518227519227520227521227522227523227524227525227526227527227528227529227530227531227532227533227534227535227536227537227538227539227540227541227542227543227544227545227546227547227548227549227550227551227552227553227554227555227556227557227558227559227560227561227562227563227564227565227566227567227568227569227570227571227572227573227574227575227576227577227578227579227580227581227582227583227584227585227586227587227588227589227590227591227592227593227594227595227596227597227598227599227600227601227602227603227604227605227606227607227608227609227610227611227612227613227614227615227616227617227618227619227620227621227622227623227624227625227626227627227628227629227630227631227632227633227634227635227636227637227638227639227640227641227642227643227644227645227646227647227648227649227650227651227652227653227654227655227656227657227658227659227660227661227662227663227664227665227666227667227668227669227670227671227672227673227674227675227676227677227678227679227680227681227682227683227684227685227686227687227688227689227690227691227692227693227694227695227696227697227698227699227700227701227702227703227704227705227706227707227708227709227710227711227712227713227714227715227716227717227718227719227720227721227722227723227724227725227726227727227728227729227730227731227732227733227734227735227736227737227738227739227740227741227742227743227744227745227746227747227748227749227750227751227752227753227754227755227756227757227758227759227760227761227762227763227764227765227766227767227768227769227770227771227772227773227774227775227776227777227778227779227780227781227782227783227784227785227786227787227788227789227790227791227792227793227794227795227796227797227798227799227800227801227802227803227804227805227806227807227808227809227810227811227812227813227814227815227816227817227818227819227820227821227822227823227824227825227826227827227828227829227830227831227832227833227834227835227836227837227838227839227840227841227842227843227844227845227846227847227848227849227850227851227852227853227854227855227856227857227858227859227860227861227862227863227864227865227866227867227868227869227870227871227872227873227874227875227876227877227878227879227880227881227882227883227884227885227886227887227888227889227890227891227892227893227894227895227896227897227898227899227900227901227902227903227904227905227906227907227908227909227910227911227912227913227914227915227916227917227918227919227920227921227922227923227924227925227926227927227928227929227930227931227932227933227934227935227936227937227938227939227940227941227942227943227944227945227946227947227948227949227950227951227952227953227954227955227956227957227958227959227960227961227962227963227964227965227966227967227968227969227970227971227972227973227974227975227976227977227978227979227980227981227982227983227984227985227986227987227988227989227990227991227992227993227994227995227996227997227998227999228000228001228002228003228004228005228006228007228008228009228010228011228012228013228014228015228016228017228018228019228020228021228022228023228024228025228026228027228028228029228030228031228032228033228034228035228036228037228038228039228040228041228042228043228044228045228046228047228048228049228050228051228052228053228054228055228056228057228058228059228060228061228062228063228064228065228066228067228068228069228070228071228072228073228074228075228076228077228078228079228080228081228082228083228084228085228086228087228088228089228090228091228092228093228094228095228096228097228098228099228100228101228102228103228104228105228106228107228108228109228110228111228112228113228114228115228116228117228118228119228120228121228122228123228124228125228126228127228128228129228130228131228132228133228134228135228136228137228138228139228140228141228142228143228144228145228146228147228148228149228150228151228152228153228154228155228156228157228158228159228160228161228162228163228164228165228166228167228168228169228170228171228172228173228174228175228176228177228178228179228180228181228182228183228184228185228186228187228188228189228190228191228192228193228194228195228196228197228198228199228200228201228202228203228204228205228206228207228208228209228210228211228212228213228214228215228216228217228218228219228220228221228222228223228224228225228226228227228228228229228230228231228232228233228234228235228236228237228238228239228240228241228242228243228244228245228246228247228248228249228250228251228252228253228254228255228256228257228258228259228260228261228262228263228264228265228266228267228268228269228270228271228272228273228274228275228276228277228278228279228280228281228282228283228284228285228286228287228288228289228290228291228292228293228294228295228296228297228298228299228300228301228302228303228304228305228306228307228308228309228310228311228312228313228314228315228316228317228318228319228320228321228322228323228324228325228326228327228328228329228330228331228332228333228334228335228336228337228338228339228340228341228342228343228344228345228346228347228348228349228350228351228352228353228354228355228356228357228358228359228360228361228362228363228364228365228366228367228368228369228370228371228372228373228374228375228376228377228378228379228380228381228382228383228384228385228386228387228388228389228390228391228392228393228394228395228396228397228398228399228400228401228402228403228404228405228406228407228408228409228410228411228412228413228414228415228416228417228418228419228420228421228422228423228424228425228426228427228428228429228430228431228432228433228434228435228436228437228438228439228440228441228442228443228444228445228446228447228448228449228450228451228452228453228454228455228456228457228458228459228460228461228462228463228464228465228466228467228468228469228470228471228472228473228474228475228476228477228478228479228480228481228482228483228484228485228486228487228488228489228490228491228492228493228494228495228496228497228498228499228500228501228502228503228504228505228506228507228508228509228510228511228512228513228514228515228516228517228518228519228520228521228522228523228524228525228526228527228528228529228530228531228532228533228534228535228536228537228538228539228540228541228542228543228544228545228546228547228548228549228550228551228552228553228554228555228556228557228558228559228560228561228562228563228564228565228566228567228568228569228570228571228572228573228574228575228576228577228578228579228580228581228582228583228584228585228586228587228588228589228590228591228592228593228594228595228596228597228598228599228600228601228602228603228604228605228606228607228608228609228610228611228612228613228614228615228616228617228618228619228620228621228622228623228624228625228626228627228628228629228630228631228632228633228634228635228636228637228638228639228640228641228642228643228644228645228646228647228648228649228650228651228652228653228654228655228656228657228658228659228660228661228662228663228664228665228666228667228668228669228670228671228672228673228674228675228676228677228678228679228680228681228682228683228684228685228686228687228688228689228690228691228692228693228694228695228696228697228698228699228700228701228702228703228704228705228706228707228708228709228710228711228712228713228714228715228716228717228718228719228720228721228722228723228724228725228726228727228728228729228730228731228732228733228734228735228736228737228738228739228740228741228742228743228744228745228746228747228748228749228750228751228752228753228754228755228756228757228758228759228760228761228762228763228764228765228766228767228768228769228770228771228772228773228774228775228776228777228778228779228780228781228782228783228784228785228786228787228788228789228790228791228792228793228794228795228796228797228798228799228800228801228802228803228804228805228806228807228808228809228810228811228812228813228814228815228816228817228818228819228820228821228822228823228824228825228826228827228828228829228830228831228832228833228834228835228836228837228838228839228840228841228842228843228844228845228846228847228848228849228850228851228852228853228854228855228856228857228858228859228860228861228862228863228864228865228866228867228868228869228870228871228872228873228874228875228876228877228878228879228880228881228882228883228884228885228886228887228888228889228890228891228892228893228894228895228896228897228898228899228900228901228902228903228904228905228906228907228908228909228910228911228912228913228914228915228916228917228918228919228920228921228922228923228924228925228926228927228928228929228930228931228932228933228934228935228936228937228938228939228940228941228942228943228944228945228946228947228948228949228950228951228952228953228954228955228956228957228958228959228960228961228962228963228964228965228966228967228968228969228970228971228972228973228974228975228976228977228978228979228980228981228982228983228984228985228986228987228988228989228990228991228992228993228994228995228996228997228998228999229000229001229002229003229004229005229006229007229008229009229010229011229012229013229014229015229016229017229018229019229020229021229022229023229024229025229026229027229028229029229030229031229032229033229034229035229036229037229038229039229040229041229042229043229044229045229046229047229048229049229050229051229052229053229054229055229056229057229058229059229060229061229062229063229064229065229066229067229068229069229070229071229072229073229074229075229076229077229078229079229080229081229082229083229084229085229086229087229088229089229090229091229092229093229094229095229096229097229098229099229100229101229102229103229104229105229106229107229108229109229110229111229112229113229114229115229116229117229118229119229120229121229122229123229124229125229126229127229128229129229130229131229132229133229134229135229136229137229138229139229140229141229142229143229144229145229146229147229148229149229150229151229152229153229154229155229156229157229158229159229160229161229162229163229164229165229166229167229168229169229170229171229172229173229174229175229176229177229178229179229180229181229182229183229184229185229186229187229188229189229190229191229192229193229194229195229196229197229198229199229200229201229202229203229204229205229206229207229208229209229210229211229212229213229214229215229216229217229218229219229220229221229222229223229224229225229226229227229228229229229230229231229232229233229234229235229236229237229238229239229240229241229242229243229244229245229246229247229248229249229250229251229252229253229254229255229256229257229258229259229260229261229262229263229264229265229266229267229268229269229270229271229272229273229274229275229276229277229278229279229280229281229282229283229284229285229286229287229288229289229290229291229292229293229294229295229296229297229298229299229300229301229302229303229304229305229306229307229308229309229310229311229312229313229314229315229316229317229318229319229320229321229322229323229324229325229326229327229328229329229330229331229332229333229334229335229336229337229338229339229340229341229342229343229344229345229346229347229348229349229350229351229352229353229354229355229356229357229358229359229360229361229362229363229364229365229366229367229368229369229370229371229372229373229374229375229376229377229378229379229380229381229382229383229384229385229386229387229388229389229390229391229392229393229394229395229396229397229398229399229400229401229402229403229404229405229406229407229408229409229410229411229412229413229414229415229416229417229418229419229420229421229422229423229424229425229426229427229428229429229430229431229432229433229434229435229436229437229438229439229440229441229442229443229444229445229446229447229448229449229450229451229452229453229454229455229456229457229458229459229460229461229462229463229464229465229466229467229468229469229470229471229472229473229474229475229476229477229478229479229480229481229482229483229484229485229486229487229488229489229490229491229492229493229494229495229496229497229498229499229500229501229502229503229504229505229506229507229508229509229510229511229512229513229514229515229516229517229518229519229520229521229522229523229524229525229526229527229528229529229530229531229532229533229534229535229536229537229538229539229540229541229542229543229544229545229546229547229548229549229550229551229552229553229554229555229556229557229558229559229560229561229562229563229564229565229566229567229568229569229570229571229572229573229574229575229576229577229578229579229580229581229582229583229584229585229586229587229588229589229590229591229592229593229594229595229596229597229598229599229600229601229602229603229604229605229606229607229608229609229610229611229612229613229614229615229616229617229618229619229620229621229622229623229624229625229626229627229628229629229630229631229632229633229634229635229636229637229638229639229640229641229642229643229644229645229646229647229648229649229650229651229652229653229654229655229656229657229658229659229660229661229662229663229664229665229666229667229668229669229670229671229672229673229674229675229676229677229678229679229680229681229682229683229684229685229686229687229688229689229690229691229692229693229694229695229696229697229698229699229700229701229702229703229704229705229706229707229708229709229710229711229712229713229714229715229716229717229718229719229720229721229722229723229724229725229726229727229728229729229730229731229732229733229734229735229736229737229738229739229740229741229742229743229744229745229746229747229748229749229750229751229752229753229754229755229756229757229758229759229760229761229762229763229764229765229766229767229768229769229770229771229772229773229774229775229776229777229778229779229780229781229782229783229784229785229786229787229788229789229790229791229792229793229794229795229796229797229798229799229800229801229802229803229804229805229806229807229808229809229810229811229812229813229814229815229816229817229818229819229820229821229822229823229824229825229826229827229828229829229830229831229832229833229834229835229836229837229838229839229840229841229842229843229844229845229846229847229848229849229850229851229852229853229854229855229856229857229858229859229860229861229862229863229864229865229866229867229868229869229870229871229872229873229874229875229876229877229878229879229880229881229882229883229884229885229886229887229888229889229890229891229892229893229894229895229896229897229898229899229900229901229902229903229904229905229906229907229908229909229910229911229912229913229914229915229916229917229918229919229920229921229922229923229924229925229926229927229928229929229930229931229932229933229934229935229936229937229938229939229940229941229942229943229944229945229946229947229948229949229950229951229952229953229954229955229956229957229958229959229960229961229962229963229964229965229966229967229968229969229970229971229972229973229974229975229976229977229978229979229980229981229982229983229984229985229986229987229988229989229990229991229992229993229994229995229996229997229998229999230000230001230002230003230004230005230006230007230008230009230010230011230012230013230014230015230016230017230018230019230020230021230022230023230024230025230026230027230028230029230030230031230032230033230034230035230036230037230038230039230040230041230042230043230044230045230046230047230048230049230050230051230052230053230054230055230056230057230058230059230060230061230062230063230064230065230066230067230068230069230070230071230072230073230074230075230076230077230078230079230080230081230082230083230084230085230086230087230088230089230090230091230092230093230094230095230096230097230098230099230100230101230102230103230104230105230106230107230108230109230110230111230112230113230114230115230116230117230118230119230120230121230122230123230124230125230126230127230128230129230130230131230132230133230134230135230136230137230138230139230140230141230142230143230144230145230146230147230148230149230150230151230152230153230154230155230156230157230158230159230160230161230162230163230164230165230166230167230168230169230170230171230172230173230174230175230176230177230178230179230180230181230182230183230184230185230186230187230188230189230190230191230192230193230194230195230196230197230198230199230200230201230202230203230204230205230206230207230208230209230210230211230212230213230214230215230216230217230218230219230220230221230222230223230224230225230226230227230228230229230230230231230232230233230234230235230236230237230238230239230240230241230242230243230244230245230246230247230248230249230250230251230252230253230254230255230256230257230258230259230260230261230262230263230264230265230266230267230268230269230270230271230272230273230274230275230276230277230278230279230280230281230282230283230284230285230286230287230288230289230290230291230292230293230294230295230296230297230298230299230300230301230302230303230304230305230306230307230308230309230310230311230312230313230314230315230316230317230318230319230320230321230322230323230324230325230326230327230328230329230330230331230332230333230334230335230336230337230338230339230340230341230342230343230344230345230346230347230348230349230350230351230352230353230354230355230356230357230358230359230360230361230362230363230364230365230366230367230368230369230370230371230372230373230374230375230376230377230378230379230380230381230382230383230384230385230386230387230388230389230390230391230392230393230394230395230396230397230398230399230400230401230402230403230404230405230406230407230408230409230410230411230412230413230414230415230416230417230418230419230420230421230422230423230424230425230426230427230428230429230430230431230432230433230434230435230436230437230438230439230440230441230442230443230444230445230446230447230448230449230450230451230452230453230454230455230456230457230458230459230460230461230462230463230464230465230466230467230468230469230470230471230472230473230474230475230476230477230478230479230480230481230482230483230484230485230486230487230488230489230490230491230492230493230494230495230496230497230498230499230500230501230502230503230504230505230506230507230508230509230510230511230512230513230514230515230516230517230518230519230520230521230522230523230524230525230526230527230528230529230530230531230532230533230534230535230536230537230538230539230540230541230542230543230544230545230546230547230548230549230550230551230552230553230554230555230556230557230558230559230560230561230562230563230564230565230566230567230568230569230570230571230572230573230574230575230576230577230578230579230580230581230582230583230584230585230586230587230588230589230590230591230592230593230594230595230596230597230598230599230600230601230602230603230604230605230606230607230608230609230610230611230612230613230614230615230616230617230618230619230620230621230622230623230624230625230626230627230628230629230630230631230632230633230634230635230636230637230638230639230640230641230642230643230644230645230646230647230648230649230650230651230652230653230654230655230656230657230658230659230660230661230662230663230664230665230666230667230668230669230670230671230672230673230674230675230676230677230678230679230680230681230682230683230684230685230686230687230688230689230690230691230692230693230694230695230696230697230698230699230700230701230702230703230704230705230706230707230708230709230710230711230712230713230714230715230716230717230718230719230720230721230722230723230724230725230726230727230728230729230730230731230732230733230734230735230736230737230738230739230740230741230742230743230744230745230746230747230748230749230750230751230752230753230754230755230756230757230758230759230760230761230762230763230764230765230766230767230768230769230770230771230772230773230774230775230776230777230778230779230780230781230782230783230784230785230786230787230788230789230790230791230792230793230794230795230796230797230798230799230800230801230802230803230804230805230806230807230808230809230810230811230812230813230814230815230816230817230818230819230820230821230822230823230824230825230826230827230828230829230830230831230832230833230834230835230836230837230838230839230840230841230842230843230844230845230846230847230848230849230850230851230852230853230854230855230856230857230858230859230860230861230862230863230864230865230866230867230868230869230870230871230872230873230874230875230876230877230878230879230880230881230882230883230884230885230886230887230888230889230890230891230892230893230894230895230896230897230898230899230900230901230902230903230904230905230906230907230908230909230910230911230912230913230914230915230916230917230918230919230920230921230922230923230924230925230926230927230928230929230930230931230932230933230934230935230936230937230938230939230940230941230942230943230944230945230946230947230948230949230950230951230952230953230954230955230956230957230958230959230960230961230962230963230964230965230966230967230968230969230970230971230972230973230974230975230976230977230978230979230980230981230982230983230984230985230986230987230988230989230990230991230992230993230994230995230996230997230998230999231000231001231002231003231004231005231006231007231008231009231010231011231012231013231014231015231016231017231018231019231020231021231022231023231024231025231026231027231028231029231030231031231032231033231034231035231036231037231038231039231040231041231042231043231044231045231046231047231048231049231050231051231052231053231054231055231056231057231058231059231060231061231062231063231064231065231066231067231068231069231070231071231072231073231074231075231076231077231078231079231080231081231082231083231084231085231086231087231088231089231090231091231092231093231094231095231096231097231098231099231100231101231102231103231104231105231106231107231108231109231110231111231112231113231114231115231116231117231118231119231120231121231122231123231124231125231126231127231128231129231130231131231132231133231134231135231136231137231138231139231140231141231142231143231144231145231146231147231148231149231150231151231152231153231154231155231156231157231158231159231160231161231162231163231164231165231166231167231168231169231170231171231172231173231174231175231176231177231178231179231180231181231182231183231184231185231186231187231188231189231190231191231192231193231194231195231196231197231198231199231200231201231202231203231204231205231206231207231208231209231210231211231212231213231214231215231216231217231218231219231220231221231222231223231224231225231226231227231228231229231230231231231232231233231234231235231236231237231238231239231240231241231242231243231244231245231246231247231248231249231250231251231252231253231254231255231256231257231258231259231260231261231262231263231264231265231266231267231268231269231270231271231272231273231274231275231276231277231278231279231280231281231282231283231284231285231286231287231288231289231290231291231292231293231294231295231296231297231298231299231300231301231302231303231304231305231306231307231308231309231310231311231312231313231314231315231316231317231318231319231320231321231322231323231324231325231326231327231328231329231330231331231332231333231334231335231336231337231338231339231340231341231342231343231344231345231346231347231348231349231350231351231352231353231354231355231356231357231358231359231360231361231362231363231364231365231366231367231368231369231370231371231372231373231374231375231376231377231378231379231380231381231382231383231384231385231386231387231388231389231390231391231392231393231394231395231396231397231398231399231400231401231402231403231404231405231406231407231408231409231410231411231412231413231414231415231416231417231418231419231420231421231422231423231424231425231426231427231428231429231430231431231432231433231434231435231436231437231438231439231440231441231442231443231444231445231446231447231448231449231450231451231452231453231454231455231456231457231458231459231460231461231462231463231464231465231466231467231468231469231470231471231472231473231474231475231476231477231478231479231480231481231482231483231484231485231486231487231488231489231490231491231492231493231494231495231496231497231498231499231500231501231502231503231504231505231506231507231508231509231510231511231512231513231514231515231516231517231518231519231520231521231522231523231524231525231526231527231528231529231530231531231532231533231534231535231536231537231538231539231540231541231542231543231544231545231546231547231548231549231550231551231552231553231554231555231556231557231558231559231560231561231562231563231564231565231566231567231568231569231570231571231572231573231574231575231576231577231578231579231580231581231582231583231584231585231586231587231588231589231590231591231592231593231594231595231596231597231598231599231600231601231602231603231604231605231606231607231608231609231610231611231612231613231614231615231616231617231618231619231620231621231622231623231624231625231626231627231628231629231630231631231632231633231634231635231636231637231638231639231640231641231642231643231644231645231646231647231648231649231650231651231652231653231654231655231656231657231658231659231660231661231662231663231664231665231666231667231668231669231670231671231672231673231674231675231676231677231678231679231680231681231682231683231684231685231686231687231688231689231690231691231692231693231694231695231696231697231698231699231700231701231702231703231704231705231706231707231708231709231710231711231712231713231714231715231716231717231718231719231720231721231722231723231724231725231726231727231728231729231730231731231732231733231734231735231736231737231738231739231740231741231742231743231744231745231746231747231748231749231750231751231752231753231754231755231756231757231758231759231760231761231762231763231764231765231766231767231768231769231770231771231772231773231774231775231776231777231778231779231780231781231782231783231784231785231786231787231788231789231790231791231792231793231794231795231796231797231798231799231800231801231802231803231804231805231806231807231808231809231810231811231812231813231814231815231816231817231818231819231820231821231822231823231824231825231826231827231828231829231830231831231832231833231834231835231836231837231838231839231840231841231842231843231844231845231846231847231848231849231850231851231852231853231854231855231856231857231858231859231860231861231862231863231864231865231866231867231868231869231870231871231872231873231874231875231876231877231878231879231880231881231882231883231884231885231886231887231888231889231890231891231892231893231894231895231896231897231898231899231900231901231902231903231904231905231906231907231908231909231910231911231912231913231914231915231916231917231918231919231920231921231922231923231924231925231926231927231928231929231930231931231932231933231934231935231936231937231938231939231940231941231942231943231944231945231946231947231948231949231950231951231952231953231954231955231956231957231958231959231960231961231962231963231964231965231966231967231968231969231970231971231972231973231974231975231976231977231978231979231980231981231982231983231984231985231986231987231988231989231990231991231992231993231994231995231996231997231998231999232000232001232002232003232004232005232006232007232008232009232010232011232012232013232014232015232016232017232018232019232020232021232022232023232024232025232026232027232028232029232030232031232032232033232034232035232036232037232038232039232040232041232042232043232044232045232046232047232048232049232050232051232052232053232054232055232056232057232058232059232060232061232062232063232064232065232066232067232068232069232070232071232072232073232074232075232076232077232078232079232080232081232082232083232084232085232086232087232088232089232090232091232092232093232094232095232096232097232098232099232100232101232102232103232104232105232106232107232108232109232110232111232112232113232114232115232116232117232118232119232120232121232122232123232124232125232126232127232128232129232130232131232132232133232134232135232136232137232138232139232140232141232142232143232144232145232146232147232148232149232150232151232152232153232154232155232156232157232158232159232160232161232162232163232164232165232166232167232168232169232170232171232172232173232174232175232176232177232178232179232180232181232182232183232184232185232186232187232188232189232190232191232192232193232194232195232196232197232198232199232200232201232202232203232204232205232206232207232208232209232210232211232212232213232214232215232216232217232218232219232220232221232222232223232224232225232226232227232228232229232230232231232232232233232234232235232236232237232238232239232240232241232242232243232244232245232246232247232248232249232250232251232252232253232254232255232256232257232258232259232260232261232262232263232264232265232266232267232268232269232270232271232272232273232274232275232276232277232278232279232280232281232282232283232284232285232286232287232288232289232290232291232292232293232294232295232296232297232298232299232300232301232302232303232304232305232306232307232308232309232310232311232312232313232314232315232316232317232318232319232320232321232322232323232324232325232326232327232328232329232330232331232332232333232334232335232336232337232338232339232340232341232342232343232344232345232346232347232348232349232350232351232352232353232354232355232356232357232358232359232360232361232362232363232364232365232366232367232368232369232370232371232372232373232374232375232376232377232378232379232380232381232382232383232384232385232386232387232388232389232390232391232392232393232394232395232396232397232398232399232400232401232402232403232404232405232406232407232408232409232410232411232412232413232414232415232416232417232418232419232420232421232422232423232424232425232426232427232428232429232430232431232432232433232434232435232436232437232438232439232440232441232442232443232444232445232446232447232448232449232450232451232452232453232454232455232456232457232458232459232460232461232462232463232464232465232466232467232468232469232470232471232472232473232474232475232476232477232478232479232480232481232482232483232484232485232486232487232488232489232490232491232492232493232494232495232496232497232498232499232500232501232502232503232504232505232506232507232508232509232510232511232512232513232514232515232516232517232518232519232520232521232522232523232524232525232526232527232528232529232530232531232532232533232534232535232536232537232538232539232540232541232542232543232544232545232546232547232548232549232550232551232552232553232554232555232556232557232558232559232560232561232562232563232564232565232566232567232568232569232570232571232572232573232574232575232576232577232578232579232580232581232582232583232584232585232586232587232588232589232590232591232592232593232594232595232596232597232598232599232600232601232602232603232604232605232606232607232608232609232610232611232612232613232614232615232616232617232618232619232620232621232622232623232624232625232626232627232628232629232630232631232632232633232634232635232636232637232638232639232640232641232642232643232644232645232646232647232648232649232650232651232652232653232654232655232656232657232658232659232660232661232662232663232664232665232666232667232668232669232670232671232672232673232674232675232676232677232678232679232680232681232682232683232684232685232686232687232688232689232690232691232692232693232694232695232696232697232698232699232700232701232702232703232704232705232706232707232708232709232710232711232712232713232714232715232716232717232718232719232720232721232722232723232724232725232726232727232728232729232730232731232732232733232734232735232736232737232738232739232740232741232742232743232744232745232746232747232748232749232750232751232752232753232754232755232756232757232758232759232760232761232762232763232764232765232766232767232768232769232770232771232772232773232774232775232776232777232778232779232780232781232782232783232784232785232786232787232788232789232790232791232792232793232794232795232796232797232798232799232800232801232802232803232804232805232806232807232808232809232810232811232812232813232814232815232816232817232818232819232820232821232822232823232824232825232826232827232828232829232830232831232832232833232834232835232836232837232838232839232840232841232842232843232844232845232846232847232848232849232850232851232852232853232854232855232856232857232858232859232860232861232862232863232864232865232866232867232868232869232870232871232872232873232874232875232876232877232878232879232880232881232882232883232884232885232886232887232888232889232890232891232892232893232894232895232896232897232898232899232900232901232902232903232904232905232906232907232908232909232910232911232912232913232914232915232916232917232918232919232920232921232922232923232924232925232926232927232928232929232930232931232932232933232934232935232936232937232938232939232940232941232942232943232944232945232946232947232948232949232950232951232952232953232954232955232956232957232958232959232960232961232962232963232964232965232966232967232968232969232970232971232972232973232974232975232976232977232978232979232980232981232982232983232984232985232986232987232988232989232990232991232992232993232994232995232996232997232998232999233000233001233002233003233004233005233006233007233008233009233010233011233012233013233014233015233016233017233018233019233020233021233022233023233024233025233026233027233028233029233030233031233032233033233034233035233036233037233038233039233040233041233042233043233044233045233046233047233048233049233050233051233052233053233054233055233056233057233058233059233060233061233062233063233064233065233066233067233068233069233070233071233072233073233074233075233076233077233078233079233080233081233082233083233084233085233086233087233088233089233090233091233092233093233094233095233096233097233098233099233100233101233102233103233104233105233106233107233108233109233110233111233112233113233114233115233116233117233118233119233120233121233122233123233124233125233126233127233128233129233130233131233132233133233134233135233136233137233138233139233140233141233142233143233144233145233146233147233148233149233150233151233152233153233154233155233156233157233158233159233160233161233162233163233164233165233166233167233168233169233170233171233172233173233174233175233176233177233178233179233180233181233182233183233184233185233186233187233188233189233190233191233192233193233194233195233196233197233198233199233200233201233202233203233204233205233206233207233208233209233210233211233212233213233214233215233216233217233218233219233220233221233222233223233224233225233226233227233228233229233230233231233232233233233234233235233236233237233238233239233240233241233242233243233244233245233246233247233248233249233250233251233252233253233254233255233256233257233258233259233260233261233262233263233264233265233266233267233268233269233270233271233272233273233274233275233276233277233278233279233280233281233282233283233284233285233286233287233288233289233290233291233292233293233294233295233296233297233298233299233300233301233302233303233304233305233306233307233308233309233310233311233312233313233314233315233316233317233318233319233320233321233322233323233324233325233326233327233328233329233330233331233332233333233334233335233336233337233338233339233340233341233342233343233344233345233346233347233348233349233350233351233352233353233354233355233356233357233358233359233360233361233362233363233364233365233366233367233368233369233370233371233372233373233374233375233376233377233378233379233380233381233382233383233384233385233386233387233388233389233390233391233392233393233394233395233396233397233398233399233400233401233402233403233404233405233406233407233408233409233410233411233412233413233414233415233416233417233418233419233420233421233422233423233424233425233426233427233428233429233430233431233432233433233434233435233436233437233438233439233440233441233442233443233444233445233446233447233448233449233450233451233452233453233454233455233456233457233458233459233460233461233462233463233464233465233466233467233468233469233470233471233472233473233474233475233476233477233478233479233480233481233482233483233484233485233486233487233488233489233490233491233492233493233494233495233496233497233498233499233500233501233502233503233504233505233506233507233508233509233510233511233512233513233514233515233516233517233518233519233520233521233522233523233524233525233526233527233528233529233530233531233532233533233534233535233536233537233538233539233540233541233542233543233544233545233546233547233548233549233550233551233552233553233554233555233556233557233558233559233560233561233562233563233564233565233566233567233568233569233570233571233572233573233574233575233576233577233578233579233580233581233582233583233584233585233586233587233588233589233590233591233592233593233594233595233596233597233598233599233600233601233602233603233604233605233606233607233608233609233610233611233612233613233614233615233616233617233618233619233620233621233622233623233624233625233626233627233628233629233630233631233632233633233634233635233636233637233638233639233640233641233642233643233644233645233646233647233648233649233650233651233652233653233654233655233656233657233658233659233660233661233662233663233664233665233666233667233668233669233670233671233672233673233674233675233676233677233678233679233680233681233682233683233684233685233686233687233688233689233690233691233692233693233694233695233696233697233698233699233700233701233702233703233704233705233706233707233708233709233710233711233712233713233714233715233716233717233718233719233720233721233722233723233724233725233726233727233728233729233730233731233732233733233734233735233736233737233738233739233740233741233742233743233744233745233746233747233748233749233750233751233752233753233754233755233756233757233758233759233760233761233762233763233764233765233766233767233768233769233770233771233772233773233774233775233776233777233778233779233780233781233782233783233784233785233786233787233788233789233790233791233792233793233794233795233796233797233798233799233800233801233802233803233804233805233806233807233808233809233810233811233812233813233814233815233816233817233818233819233820233821233822233823233824233825233826233827233828233829233830233831233832233833233834233835233836233837233838233839233840233841233842233843233844233845233846233847233848233849233850233851233852233853233854233855233856233857233858233859233860233861233862233863233864233865233866233867233868233869233870233871233872233873233874233875233876233877233878233879233880233881233882233883233884233885233886233887233888233889233890233891233892233893233894233895233896233897233898233899233900233901233902233903233904233905233906233907233908233909233910233911233912233913233914233915233916233917233918233919233920233921233922233923233924233925233926233927233928233929233930233931233932233933233934233935233936233937233938233939233940233941233942233943233944233945233946233947233948233949233950233951233952233953233954233955233956233957233958233959233960233961233962233963233964233965233966233967233968233969233970233971233972233973233974233975233976233977233978233979233980233981233982233983233984233985233986233987233988233989233990233991233992233993233994233995233996233997233998233999234000234001234002234003234004234005234006234007234008234009234010234011234012234013234014234015234016234017234018234019234020234021234022234023234024234025234026234027234028234029234030234031234032234033234034234035234036234037234038234039234040234041234042234043234044234045234046234047234048234049234050234051234052234053234054234055234056234057234058234059234060234061234062234063234064234065234066234067234068234069234070234071234072234073234074234075234076234077234078234079234080234081234082234083234084234085234086234087234088234089234090234091234092234093234094234095234096234097234098234099234100234101234102234103234104234105234106234107234108234109234110234111234112234113234114234115234116234117234118234119234120234121234122234123234124234125234126234127234128234129234130234131234132234133234134234135234136234137234138234139234140234141234142234143234144234145234146234147234148234149234150234151234152234153234154234155234156234157234158234159234160234161234162234163234164234165234166234167234168234169234170234171234172234173234174234175234176234177234178234179234180234181234182234183234184234185234186234187234188234189234190234191234192234193234194234195234196234197234198234199234200234201234202234203234204234205234206234207234208234209234210234211234212234213234214234215234216234217234218234219234220234221234222234223234224234225234226234227234228234229234230234231234232234233234234234235234236234237234238234239234240234241234242234243234244234245234246234247234248234249234250234251234252234253234254234255234256234257234258234259234260234261234262234263234264234265234266234267234268234269234270234271234272234273234274234275234276234277234278234279234280234281234282234283234284234285234286234287234288234289234290234291234292234293234294234295234296234297234298234299234300234301234302234303234304234305234306234307234308234309234310234311234312234313234314234315234316234317234318234319234320234321234322234323234324234325234326234327234328234329234330234331234332234333234334234335234336234337234338234339234340234341234342234343234344234345234346234347234348234349234350234351234352234353234354234355234356234357234358234359234360234361234362234363234364234365234366234367234368234369234370234371234372234373234374234375234376234377234378234379234380234381234382234383234384234385234386234387234388234389234390234391234392234393234394234395234396234397234398234399234400234401234402234403234404234405234406234407234408234409234410234411234412234413234414234415234416234417234418234419234420234421234422234423234424234425234426234427234428234429234430234431234432234433234434234435234436234437234438234439234440234441234442234443234444234445234446234447234448234449234450234451234452234453234454234455234456234457234458234459234460234461234462234463234464234465234466234467234468234469234470234471234472234473234474234475234476234477234478234479234480234481234482234483234484234485234486234487234488234489234490234491234492234493234494234495234496234497234498234499234500234501234502234503234504234505234506234507234508234509234510234511234512234513234514234515234516234517234518234519234520234521234522234523234524234525234526234527234528234529234530234531234532234533234534234535234536234537234538234539234540234541234542234543234544234545234546234547234548234549234550234551234552234553234554234555234556234557234558234559234560234561234562234563234564234565234566234567234568234569234570234571234572234573234574234575234576234577234578234579234580234581234582234583234584234585234586234587234588234589234590234591234592234593234594234595234596234597234598234599234600234601234602234603234604234605234606234607234608234609234610234611234612234613234614234615234616234617234618234619234620234621234622234623234624234625234626234627234628234629234630234631234632234633234634234635234636234637234638234639234640234641234642234643234644234645234646234647234648234649234650234651234652234653234654234655234656234657234658234659234660234661234662234663234664234665234666234667234668234669234670234671234672234673234674234675234676234677234678234679234680234681234682234683234684234685234686234687234688234689234690234691234692234693234694234695234696234697234698234699234700234701234702234703234704234705234706234707234708234709234710234711234712234713234714234715234716234717234718234719234720234721234722234723234724234725234726234727234728234729234730234731234732234733234734234735234736234737234738234739234740234741234742234743234744234745234746234747234748234749234750234751234752234753234754234755234756234757234758234759234760234761234762234763234764234765234766234767234768234769234770234771234772234773234774234775234776234777234778234779234780234781234782234783234784234785234786234787234788234789234790234791234792234793234794234795234796234797234798234799234800234801234802234803234804234805234806234807234808234809234810234811234812234813234814234815234816234817234818234819234820234821234822234823234824234825234826234827234828234829234830234831234832234833234834234835234836234837234838234839234840234841234842234843234844234845234846234847234848234849234850234851234852234853234854234855234856234857234858234859234860234861234862234863234864234865234866234867234868234869234870234871234872234873234874234875234876234877234878234879234880234881234882234883234884234885234886234887234888234889234890234891234892234893234894234895234896234897234898234899234900234901234902234903234904234905234906234907234908234909234910234911234912234913234914234915234916234917234918234919234920234921234922234923234924234925234926234927234928234929234930234931234932234933234934234935234936234937234938234939234940234941234942234943234944234945234946234947234948234949234950234951234952234953234954234955234956234957234958234959234960234961234962234963234964234965234966234967234968234969234970234971234972234973234974234975234976234977234978234979234980234981234982234983234984234985234986234987234988234989234990234991234992234993234994234995234996234997234998234999235000235001235002235003235004235005235006235007235008235009235010235011235012235013235014235015235016235017235018235019235020235021235022235023235024235025235026235027235028235029235030235031235032235033235034235035235036235037235038235039235040235041235042235043235044235045235046235047235048235049235050235051235052235053235054235055235056235057235058235059235060235061235062235063235064235065235066235067235068235069235070235071235072235073235074235075235076235077235078235079235080235081235082235083235084235085235086235087235088235089235090235091235092235093235094235095235096235097235098235099235100235101235102235103235104235105235106235107235108235109235110235111235112235113235114235115235116235117235118235119235120235121235122235123235124235125235126235127235128235129235130235131235132235133235134235135235136235137235138235139235140235141235142235143235144235145235146235147235148235149235150235151235152235153235154235155235156235157235158235159235160235161235162235163235164235165235166235167235168235169235170235171235172235173235174235175235176235177235178235179235180235181235182235183235184235185235186235187235188235189235190235191235192235193235194235195235196235197235198235199235200235201235202235203235204235205235206235207235208235209235210235211235212235213235214235215235216235217235218235219235220235221235222235223235224235225235226235227235228235229235230235231235232235233235234235235235236235237235238235239235240235241235242235243235244235245235246235247235248235249235250235251235252235253235254235255235256235257235258235259235260235261235262235263235264235265235266235267235268235269235270235271235272235273235274235275235276235277235278235279235280235281235282235283235284235285235286235287235288235289235290235291235292235293235294235295235296235297235298235299235300235301235302235303235304235305235306235307235308235309235310235311235312235313235314235315235316235317235318235319235320235321235322235323235324235325235326235327235328235329235330235331235332235333235334235335235336235337235338235339235340235341235342235343235344235345235346235347235348235349235350235351235352235353235354235355235356235357235358235359235360235361235362235363235364235365235366235367235368235369235370235371235372235373235374235375235376235377235378235379235380235381235382235383235384235385235386235387235388235389235390235391235392235393235394235395235396235397235398235399235400235401235402235403235404235405235406235407235408235409235410235411235412235413235414235415235416235417235418235419235420235421235422235423235424235425235426235427235428235429235430235431235432235433235434235435235436235437235438235439235440235441235442235443235444235445235446235447235448235449235450235451235452235453235454235455235456235457235458235459235460235461235462235463235464235465235466235467235468235469235470235471235472235473235474235475235476235477235478235479235480235481235482235483235484235485235486235487235488235489235490235491235492235493235494235495235496235497235498235499235500235501235502235503235504235505235506235507235508235509235510235511235512235513235514235515235516235517235518235519235520235521235522235523235524235525235526235527235528235529235530235531235532235533235534235535235536235537235538235539235540235541235542235543235544235545235546235547235548235549235550235551235552235553235554235555235556235557235558235559235560235561235562235563235564235565235566235567235568235569235570235571235572235573235574235575235576235577235578235579235580235581235582235583235584235585235586235587235588235589235590235591235592235593235594235595235596235597235598235599235600235601235602235603235604235605235606235607235608235609235610235611235612235613235614235615235616235617235618235619235620235621235622235623235624235625235626235627235628235629235630235631235632235633235634235635235636235637235638235639235640235641235642235643235644235645235646235647235648235649235650235651235652235653235654235655235656235657235658235659235660235661235662235663235664235665235666235667235668235669235670235671235672235673235674235675235676235677235678235679235680235681235682235683235684235685235686235687235688235689235690235691235692235693235694235695235696235697235698235699235700235701235702235703235704235705235706235707235708235709235710235711235712235713235714235715235716235717235718235719235720235721235722235723235724235725235726235727235728235729235730235731235732235733235734235735235736235737235738235739235740235741235742235743235744235745235746235747235748235749235750235751235752235753235754235755235756235757235758235759235760235761235762235763235764235765235766235767235768235769235770235771235772235773235774235775235776235777235778235779235780235781235782235783235784235785235786235787235788235789235790235791235792235793235794235795235796235797235798235799235800235801235802235803235804235805235806235807235808235809235810235811235812235813235814235815235816235817235818235819235820235821235822235823235824235825235826235827235828235829235830235831235832235833235834235835235836235837235838235839235840235841235842235843235844235845235846235847235848235849235850235851235852235853235854235855235856235857235858235859235860235861235862235863235864235865235866235867235868235869235870235871235872235873235874235875235876235877235878235879235880235881235882235883235884235885235886235887235888235889235890235891235892235893235894235895235896235897235898235899235900235901235902235903235904235905235906235907235908235909235910235911235912235913235914235915235916235917235918235919235920235921235922235923235924235925235926235927235928235929235930235931235932235933235934235935235936235937235938235939235940235941235942235943235944235945235946235947235948235949235950235951235952235953235954235955235956235957235958235959235960235961235962235963235964235965235966235967235968235969235970235971235972235973235974235975235976235977235978235979235980235981235982235983235984235985235986235987235988235989235990235991235992235993235994235995235996235997235998235999236000236001236002236003236004236005236006236007236008236009236010236011236012236013236014236015236016236017236018236019236020236021236022236023236024236025236026236027236028236029236030236031236032236033236034236035236036236037236038236039236040236041236042236043236044236045236046236047236048236049236050236051236052236053236054236055236056236057236058236059236060236061236062236063236064236065236066236067236068236069236070236071236072236073236074236075236076236077236078236079236080236081236082236083236084236085236086236087236088236089236090236091236092236093236094236095236096236097236098236099236100236101236102236103236104236105236106236107236108236109236110236111236112236113236114236115236116236117236118236119236120236121236122236123236124236125236126236127236128236129236130236131236132236133236134236135236136236137236138236139236140236141236142236143236144236145236146236147236148236149236150236151236152236153236154236155236156236157236158236159236160236161236162236163236164236165236166236167236168236169236170236171236172236173236174236175236176236177236178236179236180236181236182236183236184236185236186236187236188236189236190236191236192236193236194236195236196236197236198236199236200236201236202236203236204236205236206236207236208236209236210236211236212236213236214236215236216236217236218236219236220236221236222236223236224236225236226236227236228236229236230236231236232236233236234236235236236236237236238236239236240236241236242236243236244236245236246236247236248236249236250236251236252236253236254236255236256236257236258236259236260236261236262236263236264236265236266236267236268236269236270236271236272236273236274236275236276236277236278236279236280236281236282236283236284236285236286236287236288236289236290236291236292236293236294236295236296236297236298236299236300236301236302236303236304236305236306236307236308236309236310236311236312236313236314236315236316236317236318236319236320236321236322236323236324236325236326236327236328236329236330236331236332236333236334236335236336236337236338236339236340236341236342236343236344236345236346236347236348236349236350236351236352236353236354236355236356236357236358236359236360236361236362236363236364236365236366236367236368236369236370236371236372236373236374236375236376236377236378236379236380236381236382236383236384236385236386236387236388236389236390236391236392236393236394236395236396236397236398236399236400236401236402236403236404236405236406236407236408236409236410236411236412236413236414236415236416236417236418236419236420236421236422236423236424236425236426236427236428236429236430236431236432236433236434236435236436236437236438236439236440236441236442236443236444236445236446236447236448236449236450236451236452236453236454236455236456236457236458236459236460236461236462236463236464236465236466236467236468236469236470236471236472236473236474236475236476236477236478236479236480236481236482236483236484236485236486236487236488236489236490236491236492236493236494236495236496236497236498236499236500236501236502236503236504236505236506236507236508236509236510236511236512236513236514236515236516236517236518236519236520236521236522236523236524236525236526236527236528236529236530236531236532236533236534236535236536236537236538236539236540236541236542236543236544236545236546236547236548236549236550236551236552236553236554236555236556236557236558236559236560236561236562236563236564236565236566236567236568236569236570236571236572236573236574236575236576
  1. diff -Nur linux-3.14.14/arch/arm/boot/dts/clcd-panels.dtsi linux-imx6-3.14/arch/arm/boot/dts/clcd-panels.dtsi
  2. --- linux-3.14.14/arch/arm/boot/dts/clcd-panels.dtsi 1969-12-31 18:00:00.000000000 -0600
  3. +++ linux-imx6-3.14/arch/arm/boot/dts/clcd-panels.dtsi 2014-12-08 00:31:51.112418001 -0600
  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.14/arch/arm/boot/dts/efm32gg-dk3750.dts linux-imx6-3.14/arch/arm/boot/dts/efm32gg-dk3750.dts
  58. --- linux-3.14.14/arch/arm/boot/dts/efm32gg-dk3750.dts 2014-07-28 10:07:25.000000000 -0500
  59. +++ linux-imx6-3.14/arch/arm/boot/dts/efm32gg-dk3750.dts 2014-12-08 00:31:51.116418001 -0600
  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.14/arch/arm/boot/dts/imx23.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx23.dtsi
  68. --- linux-3.14.14/arch/arm/boot/dts/imx23.dtsi 2014-07-28 10:07:25.000000000 -0500
  69. +++ linux-imx6-3.14/arch/arm/boot/dts/imx23.dtsi 2014-12-08 00:31:51.116418001 -0600
  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.14/arch/arm/boot/dts/imx25.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx25.dtsi
  80. --- linux-3.14.14/arch/arm/boot/dts/imx25.dtsi 2014-07-28 10:07:25.000000000 -0500
  81. +++ linux-imx6-3.14/arch/arm/boot/dts/imx25.dtsi 2014-12-08 00:31:51.116418001 -0600
  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.14/arch/arm/boot/dts/imx25-karo-tx25.dts linux-imx6-3.14/arch/arm/boot/dts/imx25-karo-tx25.dts
  97. --- linux-3.14.14/arch/arm/boot/dts/imx25-karo-tx25.dts 2014-07-28 10:07:25.000000000 -0500
  98. +++ linux-imx6-3.14/arch/arm/boot/dts/imx25-karo-tx25.dts 2014-12-08 00:31:51.116418001 -0600
  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.14/arch/arm/boot/dts/imx27-apf27.dts linux-imx6-3.14/arch/arm/boot/dts/imx27-apf27.dts
  110. --- linux-3.14.14/arch/arm/boot/dts/imx27-apf27.dts 2014-07-28 10:07:25.000000000 -0500
  111. +++ linux-imx6-3.14/arch/arm/boot/dts/imx27-apf27.dts 2014-12-08 00:31:51.116418001 -0600
  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.14/arch/arm/boot/dts/imx27.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx27.dtsi
  120. --- linux-3.14.14/arch/arm/boot/dts/imx27.dtsi 2014-07-28 10:07:25.000000000 -0500
  121. +++ linux-imx6-3.14/arch/arm/boot/dts/imx27.dtsi 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts linux-imx6-3.14/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts
  137. --- linux-3.14.14/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts 2014-07-28 10:07:25.000000000 -0500
  138. +++ linux-imx6-3.14/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx28.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx28.dtsi
  150. --- linux-3.14.14/arch/arm/boot/dts/imx28.dtsi 2014-07-28 10:07:25.000000000 -0500
  151. +++ linux-imx6-3.14/arch/arm/boot/dts/imx28.dtsi 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx51-babbage.dts linux-imx6-3.14/arch/arm/boot/dts/imx51-babbage.dts
  163. --- linux-3.14.14/arch/arm/boot/dts/imx51-babbage.dts 2014-07-28 10:07:25.000000000 -0500
  164. +++ linux-imx6-3.14/arch/arm/boot/dts/imx51-babbage.dts 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx51.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx51.dtsi
  176. --- linux-3.14.14/arch/arm/boot/dts/imx51.dtsi 2014-07-28 10:07:25.000000000 -0500
  177. +++ linux-imx6-3.14/arch/arm/boot/dts/imx51.dtsi 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx53.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx53.dtsi
  208. --- linux-3.14.14/arch/arm/boot/dts/imx53.dtsi 2014-07-28 10:07:25.000000000 -0500
  209. +++ linux-imx6-3.14/arch/arm/boot/dts/imx53.dtsi 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx53-mba53.dts linux-imx6-3.14/arch/arm/boot/dts/imx53-mba53.dts
  240. --- linux-3.14.14/arch/arm/boot/dts/imx53-mba53.dts 2014-07-28 10:07:25.000000000 -0500
  241. +++ linux-imx6-3.14/arch/arm/boot/dts/imx53-mba53.dts 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
  253. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts 1969-12-31 18:00:00.000000000 -0600
  254. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx6dl.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6dl.dtsi
  280. --- linux-3.14.14/arch/arm/boot/dts/imx6dl.dtsi 2014-07-28 10:07:25.000000000 -0500
  281. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl.dtsi 2014-12-08 00:31:51.124418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-gw51xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw51xx.dts
  439. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-gw51xx.dts 1969-12-31 18:00:00.000000000 -0600
  440. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw51xx.dts 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-gw52xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw52xx.dts
  462. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-gw52xx.dts 1969-12-31 18:00:00.000000000 -0600
  463. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw52xx.dts 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-gw53xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw53xx.dts
  485. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-gw53xx.dts 1969-12-31 18:00:00.000000000 -0600
  486. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw53xx.dts 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-gw54xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw54xx.dts
  508. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-gw54xx.dts 1969-12-31 18:00:00.000000000 -0600
  509. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw54xx.dts 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-hummingboard.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-hummingboard.dts
  531. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-07-28 10:07:25.000000000 -0500
  532. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-nitrogen6x.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-nitrogen6x.dts
  701. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-nitrogen6x.dts 1969-12-31 18:00:00.000000000 -0600
  702. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-nitrogen6x.dts 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts
  726. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts 1969-12-31 18:00:00.000000000 -0600
  727. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi
  749. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi 1969-12-31 18:00:00.000000000 -0600
  750. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi 2014-12-08 00:31:51.120418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-pinfunc.h linux-imx6-3.14/arch/arm/boot/dts/imx6dl-pinfunc.h
  775. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-pinfunc.h 2014-07-28 10:07:25.000000000 -0500
  776. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-pinfunc.h 2014-12-08 00:31:51.124418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-sabreauto.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabreauto.dts
  794. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-sabreauto.dts 2014-07-28 10:07:25.000000000 -0500
  795. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabreauto.dts 2014-12-08 00:31:51.124418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-sabrelite.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabrelite.dts
  814. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-sabrelite.dts 1969-12-31 18:00:00.000000000 -0600
  815. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabrelite.dts 2014-12-08 00:31:51.124418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-sabresd.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabresd.dts
  838. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-sabresd.dts 2014-07-28 10:07:25.000000000 -0500
  839. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabresd.dts 2014-12-08 00:31:51.124418001 -0600
  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.14/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts
  862. --- linux-3.14.14/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts 1969-12-31 18:00:00.000000000 -0600
  863. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts 2014-12-08 00:31:51.124418001 -0600
  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.14/arch/arm/boot/dts/imx6q-arm2.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-arm2.dts
  885. --- linux-3.14.14/arch/arm/boot/dts/imx6q-arm2.dts 2014-07-28 10:07:25.000000000 -0500
  886. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-arm2.dts 2014-12-08 00:31:51.124418001 -0600
  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.14/arch/arm/boot/dts/imx6q-arm2-hsic.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-arm2-hsic.dts
  1086. --- linux-3.14.14/arch/arm/boot/dts/imx6q-arm2-hsic.dts 1969-12-31 18:00:00.000000000 -0600
  1087. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-arm2-hsic.dts 2014-12-08 00:31:51.124418001 -0600
  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.14/arch/arm/boot/dts/imx6q-cm-fx6.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-cm-fx6.dts
  1122. --- linux-3.14.14/arch/arm/boot/dts/imx6q-cm-fx6.dts 1969-12-31 18:00:00.000000000 -0600
  1123. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-cm-fx6.dts 2014-12-08 00:31:51.124418001 -0600
  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.14/arch/arm/boot/dts/imx6q-cubox-i.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-cubox-i.dts
  1233. --- linux-3.14.14/arch/arm/boot/dts/imx6q-cubox-i.dts 2014-07-28 10:07:25.000000000 -0500
  1234. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-cubox-i.dts 2014-12-08 00:31:51.124418001 -0600
  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.14/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
  1244. --- linux-3.14.14/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts 1969-12-31 18:00:00.000000000 -0600
  1245. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts 2014-12-08 00:31:51.124418001 -0600
  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.14/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
  1271. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-07-28 10:07:25.000000000 -0500
  1272. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-12-08 00:31:51.124418001 -0600
  1273. @@ -5,11 +5,33 @@
  1274. #include "imx6qdl-microsom-ar8035.dtsi"
  1275. / {
  1276. + chosen {
  1277. + bootargs = "quiet console=ttymxc0,115200 root=/dev/mmcblk0p2 rw";
  1278. + };
  1279. +
  1280. + aliases {
  1281. + mxcfb0 = &mxcfb1;
  1282. + };
  1283. +
  1284. ir_recv: ir-receiver {
  1285. compatible = "gpio-ir-receiver";
  1286. gpios = <&gpio3 9 1>;
  1287. pinctrl-names = "default";
  1288. pinctrl-0 = <&pinctrl_cubox_i_ir>;
  1289. + linux,rc-map-name = "rc-rc6-mce";
  1290. + };
  1291. +
  1292. + pwmleds {
  1293. + compatible = "pwm-leds";
  1294. + pinctrl-names = "default";
  1295. + pinctrl-0 = <&pinctrl_cubox_i_pwm1>;
  1296. +
  1297. + front {
  1298. + active-low;
  1299. + label = "imx6:red:front";
  1300. + max-brightness = <248>;
  1301. + pwms = <&pwm1 0 50000>;
  1302. + };
  1303. };
  1304. regulators {
  1305. @@ -49,10 +71,62 @@
  1306. sound-spdif {
  1307. compatible = "fsl,imx-audio-spdif";
  1308. model = "imx-spdif";
  1309. - /* IMX6 doesn't implement this yet */
  1310. spdif-controller = <&spdif>;
  1311. spdif-out;
  1312. };
  1313. +
  1314. + sound-hdmi {
  1315. + compatible = "fsl,imx6q-audio-hdmi",
  1316. + "fsl,imx-audio-hdmi";
  1317. + model = "imx-audio-hdmi";
  1318. + hdmi-controller = <&hdmi_audio>;
  1319. + };
  1320. +
  1321. + mxcfb1: fb@0 {
  1322. + compatible = "fsl,mxc_sdc_fb";
  1323. + disp_dev = "hdmi";
  1324. + interface_pix_fmt = "RGB24";
  1325. + mode_str ="1920x1080M@60";
  1326. + default_bpp = <32>;
  1327. + int_clk = <0>;
  1328. + late_init = <0>;
  1329. + status = "okay";
  1330. + };
  1331. +};
  1332. +
  1333. +&hdmi_core {
  1334. + ipu_id = <0>;
  1335. + disp_id = <0>;
  1336. + status = "okay";
  1337. +};
  1338. +
  1339. +&hdmi_video {
  1340. + fsl,phy_reg_vlev = <0x0294>;
  1341. + fsl,phy_reg_cksymtx = <0x800d>;
  1342. + status = "okay";
  1343. +};
  1344. +
  1345. +&hdmi_audio {
  1346. + status = "okay";
  1347. +};
  1348. +
  1349. +&hdmi_cec {
  1350. + pinctrl-names = "default";
  1351. + pinctrl-0 = <&pinctrl_cubox_i_hdmi>;
  1352. + status = "okay";
  1353. +};
  1354. +
  1355. +&i2c2 {
  1356. + clock-frequency = <100000>;
  1357. + pinctrl-names = "default";
  1358. + pinctrl-0 = <&pinctrl_cubox_i_i2c2>;
  1359. +
  1360. + status = "okay";
  1361. +
  1362. + ddc: imx6_hdmi_i2c@50 {
  1363. + compatible = "fsl,imx6-hdmi-i2c";
  1364. + reg = <0x50>;
  1365. + };
  1366. };
  1367. &i2c3 {
  1368. @@ -69,6 +143,19 @@
  1369. &iomuxc {
  1370. cubox_i {
  1371. + pinctrl_cubox_i_hdmi: cubox-i-hdmi {
  1372. + fsl,pins = <
  1373. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  1374. + >;
  1375. + };
  1376. +
  1377. + pinctrl_cubox_i_i2c2: cubox-i-i2c2 {
  1378. + fsl,pins = <
  1379. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  1380. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  1381. + >;
  1382. + };
  1383. +
  1384. pinctrl_cubox_i_i2c3: cubox-i-i2c3 {
  1385. fsl,pins = <
  1386. MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
  1387. @@ -82,16 +169,35 @@
  1388. >;
  1389. };
  1390. + pinctrl_cubox_i_pwm1: cubox-i-pwm1-front-led {
  1391. + fsl,pins = <MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x1b0b0>;
  1392. + };
  1393. +
  1394. pinctrl_cubox_i_spdif: cubox-i-spdif {
  1395. fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
  1396. };
  1397. + pinctrl_cubox_i_usbh1: cubox-i-usbh1 {
  1398. + fsl,pins = <MX6QDL_PAD_GPIO_3__USB_H1_OC 0x1b0b0>;
  1399. + };
  1400. +
  1401. pinctrl_cubox_i_usbh1_vbus: cubox-i-usbh1-vbus {
  1402. - fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x4001b0b0>;
  1403. + fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0>;
  1404. + };
  1405. +
  1406. + pinctrl_cubox_i_usbotg: cubox-i-usbotg {
  1407. + /*
  1408. + * The Cubox-i pulls ID low, but as it's pointless
  1409. + * leaving it as a pull-up, even if it is just 10uA.
  1410. + */
  1411. + fsl,pins = <
  1412. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059
  1413. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  1414. + >;
  1415. };
  1416. pinctrl_cubox_i_usbotg_vbus: cubox-i-usbotg-vbus {
  1417. - fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x4001b0b0>;
  1418. + fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0>;
  1419. };
  1420. pinctrl_cubox_i_usdhc2_aux: cubox-i-usdhc2-aux {
  1421. @@ -111,29 +217,76 @@
  1422. MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
  1423. >;
  1424. };
  1425. +
  1426. + pinctrl_cubox_i_usdhc2_100mhz: cubox-i-usdhc2-100mhz {
  1427. + fsl,pins = <
  1428. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170b9
  1429. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100b9
  1430. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
  1431. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
  1432. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
  1433. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x130b9
  1434. + >;
  1435. + };
  1436. +
  1437. + pinctrl_cubox_i_usdhc2_200mhz: cubox-i-usdhc2-200mhz {
  1438. + fsl,pins = <
  1439. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170f9
  1440. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100f9
  1441. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
  1442. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
  1443. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
  1444. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x130f9
  1445. + >;
  1446. + };
  1447. };
  1448. };
  1449. &spdif {
  1450. pinctrl-names = "default";
  1451. pinctrl-0 = <&pinctrl_cubox_i_spdif>;
  1452. + clocks = <&clks 197>, <&clks 0>,
  1453. + <&clks 197>, <&clks 0>,
  1454. + <&clks 0>, <&clks 0>,
  1455. + <&clks 0>, <&clks 0>,
  1456. + <&clks 0>;
  1457. + clock-names = "core", "rxtx0",
  1458. + "rxtx1", "rxtx2",
  1459. + "rxtx3", "rxtx4",
  1460. + "rxtx5", "rxtx6",
  1461. + "rxtx7";
  1462. status = "okay";
  1463. };
  1464. &usbh1 {
  1465. + pinctrl-names = "default";
  1466. + pinctrl-0 = <&pinctrl_cubox_i_usbh1>;
  1467. vbus-supply = <&reg_usbh1_vbus>;
  1468. status = "okay";
  1469. };
  1470. &usbotg {
  1471. + pinctrl-names = "default";
  1472. + pinctrl-0 = <&pinctrl_cubox_i_usbotg>;
  1473. vbus-supply = <&reg_usbotg_vbus>;
  1474. status = "okay";
  1475. };
  1476. &usdhc2 {
  1477. - pinctrl-names = "default";
  1478. + pinctrl-names = "default", "state_100mhz", "state_200mhz";
  1479. pinctrl-0 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2>;
  1480. + pinctrl-1 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2_100mhz>;
  1481. + pinctrl-2 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2_200mhz>;
  1482. vmmc-supply = <&reg_3p3v>;
  1483. cd-gpios = <&gpio1 4 0>;
  1484. + no-1-8-v;
  1485. status = "okay";
  1486. };
  1487. +
  1488. +
  1489. +&gpc {
  1490. + fsl,cpu_pupscr_sw2iso = <0xf>;
  1491. + fsl,cpu_pupscr_sw = <0xf>;
  1492. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  1493. + fsl,cpu_pdnscr_iso = <0x1>;
  1494. +};
  1495. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
  1496. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi 1969-12-31 18:00:00.000000000 -0600
  1497. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi 2014-12-08 00:31:51.124418001 -0600
  1498. @@ -0,0 +1,199 @@
  1499. +/ {
  1500. + regulators {
  1501. + compatible = "simple-bus";
  1502. + #address-cells = <1>;
  1503. + #size-cells = <0>;
  1504. +
  1505. + dummy_reg: regulator@0 {
  1506. + compatible = "regulator-fixed";
  1507. + reg = <0>;
  1508. + regulator-name = "dummy-supply";
  1509. + };
  1510. +
  1511. + reg_usb_otg_vbus: regulator@1 {
  1512. + compatible = "regulator-fixed";
  1513. + reg = <1>;
  1514. + regulator-name = "usb_otg_vbus";
  1515. + regulator-min-microvolt = <5000000>;
  1516. + regulator-max-microvolt = <5000000>;
  1517. + gpio = <&gpio3 22 0>;
  1518. + enable-active-high;
  1519. + };
  1520. + };
  1521. +
  1522. + chosen {
  1523. + stdout-path = &uart1;
  1524. + };
  1525. +};
  1526. +
  1527. +&ecspi3 {
  1528. + fsl,spi-num-chipselects = <1>;
  1529. + cs-gpios = <&gpio4 24 0>;
  1530. + pinctrl-names = "default";
  1531. + pinctrl-0 = <&pinctrl_ecspi3>;
  1532. + status = "okay";
  1533. +
  1534. + flash: m25p80@0 {
  1535. + #address-cells = <1>;
  1536. + #size-cells = <1>;
  1537. + compatible = "sst,sst25vf040b", "m25p80";
  1538. + spi-max-frequency = <20000000>;
  1539. + reg = <0>;
  1540. + };
  1541. +};
  1542. +
  1543. +&fec {
  1544. + pinctrl-names = "default";
  1545. + pinctrl-0 = <&pinctrl_enet>;
  1546. + status = "okay";
  1547. + phy-mode = "rgmii";
  1548. +};
  1549. +
  1550. +&iomuxc {
  1551. + pinctrl-names = "default";
  1552. + pinctrl-0 = <&pinctrl_hog>;
  1553. +
  1554. + imx6qdl-dfi-fs700-m60 {
  1555. + pinctrl_hog: hoggrp {
  1556. + fsl,pins = <
  1557. + MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
  1558. + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x80000000 /* PMIC irq */
  1559. + MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x80000000 /* MAX11801 irq */
  1560. + MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x000030b0 /* Backlight enable */
  1561. + >;
  1562. + };
  1563. +
  1564. + pinctrl_enet: enetgrp {
  1565. + fsl,pins = <
  1566. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  1567. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  1568. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  1569. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  1570. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  1571. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  1572. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  1573. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  1574. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  1575. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  1576. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  1577. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  1578. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  1579. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  1580. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  1581. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  1582. + >;
  1583. + };
  1584. +
  1585. + pinctrl_i2c2: i2c2grp {
  1586. + fsl,pins = <
  1587. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  1588. + MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
  1589. + >;
  1590. + };
  1591. +
  1592. + pinctrl_uart1: uart1grp {
  1593. + fsl,pins = <
  1594. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  1595. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  1596. + >;
  1597. + };
  1598. +
  1599. + pinctrl_usbotg: usbotggrp {
  1600. + fsl,pins = <
  1601. + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  1602. + >;
  1603. + };
  1604. +
  1605. + pinctrl_usdhc2: usdhc2grp {
  1606. + fsl,pins = <
  1607. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  1608. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  1609. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  1610. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  1611. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  1612. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  1613. + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000 /* card detect */
  1614. + >;
  1615. + };
  1616. +
  1617. + pinctrl_usdhc3: usdhc3grp {
  1618. + fsl,pins = <
  1619. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  1620. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  1621. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  1622. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  1623. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  1624. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  1625. + >;
  1626. + };
  1627. +
  1628. + pinctrl_usdhc4: usdhc4grp {
  1629. + fsl,pins = <
  1630. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  1631. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  1632. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  1633. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  1634. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  1635. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  1636. + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  1637. + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  1638. + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  1639. + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  1640. + >;
  1641. + };
  1642. +
  1643. + pinctrl_ecspi3: ecspi3grp {
  1644. + fsl,pins = <
  1645. + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
  1646. + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
  1647. + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
  1648. + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
  1649. + >;
  1650. + };
  1651. + };
  1652. +};
  1653. +
  1654. +&i2c2 {
  1655. + pinctrl-names = "default";
  1656. + pinctrl-0 = <&pinctrl_i2c2>;
  1657. + status = "okay";
  1658. +};
  1659. +
  1660. +&uart1 {
  1661. + pinctrl-names = "default";
  1662. + pinctrl-0 = <&pinctrl_uart1>;
  1663. + status = "okay";
  1664. +};
  1665. +
  1666. +&usbh1 {
  1667. + status = "okay";
  1668. +};
  1669. +
  1670. +&usbotg {
  1671. + vbus-supply = <&reg_usb_otg_vbus>;
  1672. + pinctrl-names = "default";
  1673. + pinctrl-0 = <&pinctrl_usbotg>;
  1674. + disable-over-current;
  1675. + dr_mode = "host";
  1676. + status = "okay";
  1677. +};
  1678. +
  1679. +&usdhc2 { /* module slot */
  1680. + pinctrl-names = "default";
  1681. + pinctrl-0 = <&pinctrl_usdhc2>;
  1682. + cd-gpios = <&gpio2 2 0>;
  1683. + status = "okay";
  1684. +};
  1685. +
  1686. +&usdhc3 { /* baseboard slot */
  1687. + pinctrl-names = "default";
  1688. + pinctrl-0 = <&pinctrl_usdhc3>;
  1689. +};
  1690. +
  1691. +&usdhc4 { /* eMMC */
  1692. + pinctrl-names = "default";
  1693. + pinctrl-0 = <&pinctrl_usdhc4>;
  1694. + bus-width = <8>;
  1695. + non-removable;
  1696. + status = "okay";
  1697. +};
  1698. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl.dtsi
  1699. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl.dtsi 2014-07-28 10:07:25.000000000 -0500
  1700. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl.dtsi 2014-12-08 00:31:51.124418001 -0600
  1701. @@ -10,10 +10,16 @@
  1702. * http://www.gnu.org/copyleft/gpl.html
  1703. */
  1704. +#include <dt-bindings/interrupt-controller/arm-gic.h>
  1705. +
  1706. #include "skeleton.dtsi"
  1707. +#include <dt-bindings/gpio/gpio.h>
  1708. / {
  1709. aliases {
  1710. + ethernet0 = &fec;
  1711. + can0 = &can1;
  1712. + can1 = &can2;
  1713. gpio0 = &gpio1;
  1714. gpio1 = &gpio2;
  1715. gpio2 = &gpio3;
  1716. @@ -24,6 +30,11 @@
  1717. i2c0 = &i2c1;
  1718. i2c1 = &i2c2;
  1719. i2c2 = &i2c3;
  1720. + ipu0 = &ipu1;
  1721. + mmc0 = &usdhc1;
  1722. + mmc1 = &usdhc2;
  1723. + mmc2 = &usdhc3;
  1724. + mmc3 = &usdhc4;
  1725. serial0 = &uart1;
  1726. serial1 = &uart2;
  1727. serial2 = &uart3;
  1728. @@ -33,13 +44,13 @@
  1729. spi1 = &ecspi2;
  1730. spi2 = &ecspi3;
  1731. spi3 = &ecspi4;
  1732. + usbphy0 = &usbphy1;
  1733. + usbphy1 = &usbphy2;
  1734. };
  1735. intc: interrupt-controller@00a01000 {
  1736. compatible = "arm,cortex-a9-gic";
  1737. #interrupt-cells = <3>;
  1738. - #address-cells = <1>;
  1739. - #size-cells = <1>;
  1740. interrupt-controller;
  1741. reg = <0x00a01000 0x1000>,
  1742. <0x00a00100 0x100>;
  1743. @@ -51,20 +62,27 @@
  1744. ckil {
  1745. compatible = "fsl,imx-ckil", "fixed-clock";
  1746. + #clock-cells = <0>;
  1747. clock-frequency = <32768>;
  1748. };
  1749. ckih1 {
  1750. compatible = "fsl,imx-ckih1", "fixed-clock";
  1751. + #clock-cells = <0>;
  1752. clock-frequency = <0>;
  1753. };
  1754. osc {
  1755. compatible = "fsl,imx-osc", "fixed-clock";
  1756. + #clock-cells = <0>;
  1757. clock-frequency = <24000000>;
  1758. };
  1759. };
  1760. + pu_dummy: pudummy_reg {
  1761. + compatible = "fsl,imx6-dummy-pureg"; /* only used in ldo-bypass */
  1762. + };
  1763. +
  1764. soc {
  1765. #address-cells = <1>;
  1766. #size-cells = <1>;
  1767. @@ -75,7 +93,10 @@
  1768. dma_apbh: dma-apbh@00110000 {
  1769. compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
  1770. reg = <0x00110000 0x2000>;
  1771. - interrupts = <0 13 0x04>, <0 13 0x04>, <0 13 0x04>, <0 13 0x04>;
  1772. + interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>,
  1773. + <0 13 IRQ_TYPE_LEVEL_HIGH>,
  1774. + <0 13 IRQ_TYPE_LEVEL_HIGH>,
  1775. + <0 13 IRQ_TYPE_LEVEL_HIGH>;
  1776. interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
  1777. #dma-cells = <1>;
  1778. dma-channels = <4>;
  1779. @@ -88,7 +109,7 @@
  1780. #size-cells = <1>;
  1781. reg = <0x00112000 0x2000>, <0x00114000 0x2000>;
  1782. reg-names = "gpmi-nand", "bch";
  1783. - interrupts = <0 15 0x04>;
  1784. + interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
  1785. interrupt-names = "bch";
  1786. clocks = <&clks 152>, <&clks 153>, <&clks 151>,
  1787. <&clks 150>, <&clks 149>;
  1788. @@ -109,11 +130,13 @@
  1789. L2: l2-cache@00a02000 {
  1790. compatible = "arm,pl310-cache";
  1791. reg = <0x00a02000 0x1000>;
  1792. - interrupts = <0 92 0x04>;
  1793. + interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
  1794. cache-unified;
  1795. cache-level = <2>;
  1796. arm,tag-latency = <4 2 3>;
  1797. arm,data-latency = <4 2 3>;
  1798. + arm,dynamic-clk-gating;
  1799. + arm,standby-mode;
  1800. };
  1801. pcie: pcie@0x01000000 {
  1802. @@ -126,15 +149,22 @@
  1803. 0x81000000 0 0 0x01f80000 0 0x00010000 /* downstream I/O */
  1804. 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
  1805. num-lanes = <1>;
  1806. - interrupts = <0 123 0x04>;
  1807. - clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
  1808. - clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
  1809. + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
  1810. + interrupt-names = "pme";
  1811. + #interrupt-cells = <1>;
  1812. + interrupt-map-mask = <0 0 0 0x7>;
  1813. + interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
  1814. + <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
  1815. + <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
  1816. + <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
  1817. + clocks = <&clks 144>, <&clks 221>, <&clks 189>, <&clks 187>;
  1818. + clock-names = "pcie_axi", "lvds_gate", "pcie_ref_125m", "sata_ref_100m";
  1819. status = "disabled";
  1820. };
  1821. pmu {
  1822. compatible = "arm,cortex-a9-pmu";
  1823. - interrupts = <0 94 0x04>;
  1824. + interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
  1825. };
  1826. aips-bus@02000000 { /* AIPS1 */
  1827. @@ -154,7 +184,7 @@
  1828. spdif: spdif@02004000 {
  1829. compatible = "fsl,imx35-spdif";
  1830. reg = <0x02004000 0x4000>;
  1831. - interrupts = <0 52 0x04>;
  1832. + interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
  1833. dmas = <&sdma 14 18 0>,
  1834. <&sdma 15 18 0>;
  1835. dma-names = "rx", "tx";
  1836. @@ -176,9 +206,11 @@
  1837. #size-cells = <0>;
  1838. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1839. reg = <0x02008000 0x4000>;
  1840. - interrupts = <0 31 0x04>;
  1841. + interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
  1842. clocks = <&clks 112>, <&clks 112>;
  1843. clock-names = "ipg", "per";
  1844. + dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
  1845. + dma-names = "rx", "tx";
  1846. status = "disabled";
  1847. };
  1848. @@ -187,9 +219,11 @@
  1849. #size-cells = <0>;
  1850. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1851. reg = <0x0200c000 0x4000>;
  1852. - interrupts = <0 32 0x04>;
  1853. + interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
  1854. clocks = <&clks 113>, <&clks 113>;
  1855. clock-names = "ipg", "per";
  1856. + dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
  1857. + dma-names = "rx", "tx";
  1858. status = "disabled";
  1859. };
  1860. @@ -198,9 +232,11 @@
  1861. #size-cells = <0>;
  1862. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1863. reg = <0x02010000 0x4000>;
  1864. - interrupts = <0 33 0x04>;
  1865. + interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
  1866. clocks = <&clks 114>, <&clks 114>;
  1867. clock-names = "ipg", "per";
  1868. + dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
  1869. + dma-names = "rx", "tx";
  1870. status = "disabled";
  1871. };
  1872. @@ -209,16 +245,18 @@
  1873. #size-cells = <0>;
  1874. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1875. reg = <0x02014000 0x4000>;
  1876. - interrupts = <0 34 0x04>;
  1877. + interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
  1878. clocks = <&clks 115>, <&clks 115>;
  1879. clock-names = "ipg", "per";
  1880. + dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
  1881. + dma-names = "rx", "tx";
  1882. status = "disabled";
  1883. };
  1884. uart1: serial@02020000 {
  1885. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  1886. reg = <0x02020000 0x4000>;
  1887. - interrupts = <0 26 0x04>;
  1888. + interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
  1889. clocks = <&clks 160>, <&clks 161>;
  1890. clock-names = "ipg", "per";
  1891. dmas = <&sdma 25 4 0>, <&sdma 26 4 0>;
  1892. @@ -227,15 +265,23 @@
  1893. };
  1894. esai: esai@02024000 {
  1895. + compatible = "fsl,imx6q-esai";
  1896. reg = <0x02024000 0x4000>;
  1897. - interrupts = <0 51 0x04>;
  1898. + interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
  1899. + clocks = <&clks 118>;
  1900. + fsl,esai-dma-events = <24 23>;
  1901. + fsl,flags = <1>;
  1902. + status = "disabled";
  1903. };
  1904. ssi1: ssi@02028000 {
  1905. - compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
  1906. + compatible = "fsl,imx6q-ssi",
  1907. + "fsl,imx51-ssi",
  1908. + "fsl,imx21-ssi";
  1909. reg = <0x02028000 0x4000>;
  1910. - interrupts = <0 46 0x04>;
  1911. - clocks = <&clks 178>;
  1912. + interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
  1913. + clocks = <&clks 178>, <&clks 157>;
  1914. + clock-names = "ipg", "baud";
  1915. dmas = <&sdma 37 1 0>,
  1916. <&sdma 38 1 0>;
  1917. dma-names = "rx", "tx";
  1918. @@ -245,10 +291,13 @@
  1919. };
  1920. ssi2: ssi@0202c000 {
  1921. - compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
  1922. + compatible = "fsl,imx6q-ssi",
  1923. + "fsl,imx51-ssi",
  1924. + "fsl,imx21-ssi";
  1925. reg = <0x0202c000 0x4000>;
  1926. - interrupts = <0 47 0x04>;
  1927. - clocks = <&clks 179>;
  1928. + interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
  1929. + clocks = <&clks 179>, <&clks 158>;
  1930. + clock-names = "ipg", "baud";
  1931. dmas = <&sdma 41 1 0>,
  1932. <&sdma 42 1 0>;
  1933. dma-names = "rx", "tx";
  1934. @@ -258,10 +307,13 @@
  1935. };
  1936. ssi3: ssi@02030000 {
  1937. - compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
  1938. + compatible = "fsl,imx6q-ssi",
  1939. + "fsl,imx51-ssi",
  1940. + "fsl,imx21-ssi";
  1941. reg = <0x02030000 0x4000>;
  1942. - interrupts = <0 48 0x04>;
  1943. - clocks = <&clks 180>;
  1944. + interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
  1945. + clocks = <&clks 180>, <&clks 159>;
  1946. + clock-names = "ipg", "baud";
  1947. dmas = <&sdma 45 1 0>,
  1948. <&sdma 46 1 0>;
  1949. dma-names = "rx", "tx";
  1950. @@ -271,8 +323,25 @@
  1951. };
  1952. asrc: asrc@02034000 {
  1953. + compatible = "fsl,imx53-asrc";
  1954. reg = <0x02034000 0x4000>;
  1955. - interrupts = <0 50 0x04>;
  1956. + interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
  1957. + clocks = <&clks 107>, <&clks 156>;
  1958. + clock-names = "core", "dma";
  1959. + dmas = <&sdma 17 20 1>, <&sdma 18 20 1>, <&sdma 19 20 1>,
  1960. + <&sdma 20 20 1>, <&sdma 21 20 1>, <&sdma 22 20 1>;
  1961. + dma-names = "rxa", "rxb", "rxc",
  1962. + "txa", "txb", "txc";
  1963. + status = "okay";
  1964. + };
  1965. +
  1966. + asrc_p2p: asrc_p2p {
  1967. + compatible = "fsl,imx6q-asrc-p2p";
  1968. + fsl,output-rate = <48000>;
  1969. + fsl,output-width = <16>;
  1970. + fsl,asrc-dma-rx-events = <17 18 19>;
  1971. + fsl,asrc-dma-tx-events = <20 21 22>;
  1972. + status = "okay";
  1973. };
  1974. spba@0203c000 {
  1975. @@ -281,8 +350,19 @@
  1976. };
  1977. vpu: vpu@02040000 {
  1978. + compatible = "fsl,imx6-vpu";
  1979. reg = <0x02040000 0x3c000>;
  1980. - interrupts = <0 3 0x04 0 12 0x04>;
  1981. + reg-names = "vpu_regs";
  1982. + interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>,
  1983. + <0 12 IRQ_TYPE_LEVEL_HIGH>;
  1984. + interrupt-names = "vpu_jpu_irq", "vpu_ipi_irq";
  1985. + clocks = <&clks 168>, <&clks 140>, <&clks 142>;
  1986. + clock-names = "vpu_clk", "mmdc_ch0_axi", "ocram";
  1987. + iramsize = <0x21000>;
  1988. + iram = <&ocram>;
  1989. + resets = <&src 1>;
  1990. + pu-supply = <&reg_pu>;
  1991. + status = "disabled";
  1992. };
  1993. aipstz@0207c000 { /* AIPSTZ1 */
  1994. @@ -293,7 +373,7 @@
  1995. #pwm-cells = <2>;
  1996. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  1997. reg = <0x02080000 0x4000>;
  1998. - interrupts = <0 83 0x04>;
  1999. + interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
  2000. clocks = <&clks 62>, <&clks 145>;
  2001. clock-names = "ipg", "per";
  2002. };
  2003. @@ -302,7 +382,7 @@
  2004. #pwm-cells = <2>;
  2005. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  2006. reg = <0x02084000 0x4000>;
  2007. - interrupts = <0 84 0x04>;
  2008. + interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
  2009. clocks = <&clks 62>, <&clks 146>;
  2010. clock-names = "ipg", "per";
  2011. };
  2012. @@ -311,7 +391,7 @@
  2013. #pwm-cells = <2>;
  2014. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  2015. reg = <0x02088000 0x4000>;
  2016. - interrupts = <0 85 0x04>;
  2017. + interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
  2018. clocks = <&clks 62>, <&clks 147>;
  2019. clock-names = "ipg", "per";
  2020. };
  2021. @@ -320,7 +400,7 @@
  2022. #pwm-cells = <2>;
  2023. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  2024. reg = <0x0208c000 0x4000>;
  2025. - interrupts = <0 86 0x04>;
  2026. + interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
  2027. clocks = <&clks 62>, <&clks 148>;
  2028. clock-names = "ipg", "per";
  2029. };
  2030. @@ -328,23 +408,25 @@
  2031. can1: flexcan@02090000 {
  2032. compatible = "fsl,imx6q-flexcan";
  2033. reg = <0x02090000 0x4000>;
  2034. - interrupts = <0 110 0x04>;
  2035. + interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
  2036. clocks = <&clks 108>, <&clks 109>;
  2037. clock-names = "ipg", "per";
  2038. + status = "disabled";
  2039. };
  2040. can2: flexcan@02094000 {
  2041. compatible = "fsl,imx6q-flexcan";
  2042. reg = <0x02094000 0x4000>;
  2043. - interrupts = <0 111 0x04>;
  2044. + interrupts = <0 111 IRQ_TYPE_LEVEL_HIGH>;
  2045. clocks = <&clks 110>, <&clks 111>;
  2046. clock-names = "ipg", "per";
  2047. + status = "disabled";
  2048. };
  2049. gpt: gpt@02098000 {
  2050. compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt";
  2051. reg = <0x02098000 0x4000>;
  2052. - interrupts = <0 55 0x04>;
  2053. + interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
  2054. clocks = <&clks 119>, <&clks 120>;
  2055. clock-names = "ipg", "per";
  2056. };
  2057. @@ -352,7 +434,8 @@
  2058. gpio1: gpio@0209c000 {
  2059. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2060. reg = <0x0209c000 0x4000>;
  2061. - interrupts = <0 66 0x04 0 67 0x04>;
  2062. + interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
  2063. + <0 67 IRQ_TYPE_LEVEL_HIGH>;
  2064. gpio-controller;
  2065. #gpio-cells = <2>;
  2066. interrupt-controller;
  2067. @@ -362,7 +445,8 @@
  2068. gpio2: gpio@020a0000 {
  2069. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2070. reg = <0x020a0000 0x4000>;
  2071. - interrupts = <0 68 0x04 0 69 0x04>;
  2072. + interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
  2073. + <0 69 IRQ_TYPE_LEVEL_HIGH>;
  2074. gpio-controller;
  2075. #gpio-cells = <2>;
  2076. interrupt-controller;
  2077. @@ -372,7 +456,8 @@
  2078. gpio3: gpio@020a4000 {
  2079. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2080. reg = <0x020a4000 0x4000>;
  2081. - interrupts = <0 70 0x04 0 71 0x04>;
  2082. + interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
  2083. + <0 71 IRQ_TYPE_LEVEL_HIGH>;
  2084. gpio-controller;
  2085. #gpio-cells = <2>;
  2086. interrupt-controller;
  2087. @@ -382,7 +467,8 @@
  2088. gpio4: gpio@020a8000 {
  2089. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2090. reg = <0x020a8000 0x4000>;
  2091. - interrupts = <0 72 0x04 0 73 0x04>;
  2092. + interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
  2093. + <0 73 IRQ_TYPE_LEVEL_HIGH>;
  2094. gpio-controller;
  2095. #gpio-cells = <2>;
  2096. interrupt-controller;
  2097. @@ -392,7 +478,8 @@
  2098. gpio5: gpio@020ac000 {
  2099. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2100. reg = <0x020ac000 0x4000>;
  2101. - interrupts = <0 74 0x04 0 75 0x04>;
  2102. + interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
  2103. + <0 75 IRQ_TYPE_LEVEL_HIGH>;
  2104. gpio-controller;
  2105. #gpio-cells = <2>;
  2106. interrupt-controller;
  2107. @@ -402,7 +489,8 @@
  2108. gpio6: gpio@020b0000 {
  2109. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2110. reg = <0x020b0000 0x4000>;
  2111. - interrupts = <0 76 0x04 0 77 0x04>;
  2112. + interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>,
  2113. + <0 77 IRQ_TYPE_LEVEL_HIGH>;
  2114. gpio-controller;
  2115. #gpio-cells = <2>;
  2116. interrupt-controller;
  2117. @@ -412,7 +500,8 @@
  2118. gpio7: gpio@020b4000 {
  2119. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2120. reg = <0x020b4000 0x4000>;
  2121. - interrupts = <0 78 0x04 0 79 0x04>;
  2122. + interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>,
  2123. + <0 79 IRQ_TYPE_LEVEL_HIGH>;
  2124. gpio-controller;
  2125. #gpio-cells = <2>;
  2126. interrupt-controller;
  2127. @@ -421,20 +510,20 @@
  2128. kpp: kpp@020b8000 {
  2129. reg = <0x020b8000 0x4000>;
  2130. - interrupts = <0 82 0x04>;
  2131. + interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
  2132. };
  2133. wdog1: wdog@020bc000 {
  2134. compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
  2135. reg = <0x020bc000 0x4000>;
  2136. - interrupts = <0 80 0x04>;
  2137. + interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
  2138. clocks = <&clks 0>;
  2139. };
  2140. wdog2: wdog@020c0000 {
  2141. compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
  2142. reg = <0x020c0000 0x4000>;
  2143. - interrupts = <0 81 0x04>;
  2144. + interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
  2145. clocks = <&clks 0>;
  2146. status = "disabled";
  2147. };
  2148. @@ -442,14 +531,17 @@
  2149. clks: ccm@020c4000 {
  2150. compatible = "fsl,imx6q-ccm";
  2151. reg = <0x020c4000 0x4000>;
  2152. - interrupts = <0 87 0x04 0 88 0x04>;
  2153. + interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
  2154. + <0 88 IRQ_TYPE_LEVEL_HIGH>;
  2155. #clock-cells = <1>;
  2156. };
  2157. anatop: anatop@020c8000 {
  2158. compatible = "fsl,imx6q-anatop", "syscon", "simple-bus";
  2159. reg = <0x020c8000 0x1000>;
  2160. - interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
  2161. + interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
  2162. + <0 54 IRQ_TYPE_LEVEL_HIGH>,
  2163. + <0 127 IRQ_TYPE_LEVEL_HIGH>;
  2164. regulator-1p1@110 {
  2165. compatible = "fsl,anatop-regulator";
  2166. @@ -495,7 +587,7 @@
  2167. reg_arm: regulator-vddcore@140 {
  2168. compatible = "fsl,anatop-regulator";
  2169. - regulator-name = "cpu";
  2170. + regulator-name = "vddarm";
  2171. regulator-min-microvolt = <725000>;
  2172. regulator-max-microvolt = <1450000>;
  2173. regulator-always-on;
  2174. @@ -515,7 +607,6 @@
  2175. regulator-name = "vddpu";
  2176. regulator-min-microvolt = <725000>;
  2177. regulator-max-microvolt = <1450000>;
  2178. - regulator-always-on;
  2179. anatop-reg-offset = <0x140>;
  2180. anatop-vol-bit-shift = <9>;
  2181. anatop-vol-bit-width = <5>;
  2182. @@ -547,23 +638,38 @@
  2183. tempmon: tempmon {
  2184. compatible = "fsl,imx6q-tempmon";
  2185. - interrupts = <0 49 0x04>;
  2186. + interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>;
  2187. fsl,tempmon = <&anatop>;
  2188. fsl,tempmon-data = <&ocotp>;
  2189. + clocks = <&clks 172>;
  2190. };
  2191. usbphy1: usbphy@020c9000 {
  2192. compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
  2193. reg = <0x020c9000 0x1000>;
  2194. - interrupts = <0 44 0x04>;
  2195. + interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
  2196. clocks = <&clks 182>;
  2197. + fsl,anatop = <&anatop>;
  2198. };
  2199. usbphy2: usbphy@020ca000 {
  2200. compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
  2201. reg = <0x020ca000 0x1000>;
  2202. - interrupts = <0 45 0x04>;
  2203. + interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
  2204. clocks = <&clks 183>;
  2205. + fsl,anatop = <&anatop>;
  2206. + };
  2207. +
  2208. + usbphy_nop1: usbphy_nop1 {
  2209. + compatible = "usb-nop-xceiv";
  2210. + clocks = <&clks 182>;
  2211. + clock-names = "main_clk";
  2212. + };
  2213. +
  2214. + usbphy_nop2: usbphy_nop2 {
  2215. + compatible = "usb-nop-xceiv";
  2216. + clocks = <&clks 182>;
  2217. + clock-names = "main_clk";
  2218. };
  2219. snvs@020cc000 {
  2220. @@ -575,31 +681,39 @@
  2221. snvs-rtc-lp@34 {
  2222. compatible = "fsl,sec-v4.0-mon-rtc-lp";
  2223. reg = <0x34 0x58>;
  2224. - interrupts = <0 19 0x04 0 20 0x04>;
  2225. + interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
  2226. + <0 20 IRQ_TYPE_LEVEL_HIGH>;
  2227. };
  2228. };
  2229. epit1: epit@020d0000 { /* EPIT1 */
  2230. reg = <0x020d0000 0x4000>;
  2231. - interrupts = <0 56 0x04>;
  2232. + interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
  2233. };
  2234. epit2: epit@020d4000 { /* EPIT2 */
  2235. reg = <0x020d4000 0x4000>;
  2236. - interrupts = <0 57 0x04>;
  2237. + interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
  2238. };
  2239. src: src@020d8000 {
  2240. compatible = "fsl,imx6q-src", "fsl,imx51-src";
  2241. reg = <0x020d8000 0x4000>;
  2242. - interrupts = <0 91 0x04 0 96 0x04>;
  2243. + interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
  2244. + <0 96 IRQ_TYPE_LEVEL_HIGH>;
  2245. #reset-cells = <1>;
  2246. };
  2247. gpc: gpc@020dc000 {
  2248. compatible = "fsl,imx6q-gpc";
  2249. reg = <0x020dc000 0x4000>;
  2250. - interrupts = <0 89 0x04 0 90 0x04>;
  2251. + interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>,
  2252. + <0 90 IRQ_TYPE_LEVEL_HIGH>;
  2253. + clocks = <&clks 122>, <&clks 74>, <&clks 121>,
  2254. + <&clks 26>, <&clks 143>, <&clks 168>, <&clks 62>;
  2255. + clock-names = "gpu3d_core", "gpu3d_shader", "gpu2d_core",
  2256. + "gpu2d_axi", "openvg_axi", "vpu_axi", "ipg";
  2257. + pu-supply = <&reg_pu>;
  2258. };
  2259. gpr: iomuxc-gpr@020e0000 {
  2260. @@ -610,778 +724,40 @@
  2261. iomuxc: iomuxc@020e0000 {
  2262. compatible = "fsl,imx6dl-iomuxc", "fsl,imx6q-iomuxc";
  2263. reg = <0x020e0000 0x4000>;
  2264. -
  2265. - audmux {
  2266. - pinctrl_audmux_1: audmux-1 {
  2267. - fsl,pins = <
  2268. - MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x80000000
  2269. - MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x80000000
  2270. - MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x80000000
  2271. - MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x80000000
  2272. - >;
  2273. - };
  2274. -
  2275. - pinctrl_audmux_2: audmux-2 {
  2276. - fsl,pins = <
  2277. - MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x80000000
  2278. - MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x80000000
  2279. - MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x80000000
  2280. - MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x80000000
  2281. - >;
  2282. - };
  2283. -
  2284. - pinctrl_audmux_3: audmux-3 {
  2285. - fsl,pins = <
  2286. - MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x80000000
  2287. - MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x80000000
  2288. - MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x80000000
  2289. - >;
  2290. - };
  2291. - };
  2292. -
  2293. - ecspi1 {
  2294. - pinctrl_ecspi1_1: ecspi1grp-1 {
  2295. - fsl,pins = <
  2296. - MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  2297. - MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  2298. - MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  2299. - >;
  2300. - };
  2301. -
  2302. - pinctrl_ecspi1_2: ecspi1grp-2 {
  2303. - fsl,pins = <
  2304. - MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1
  2305. - MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1
  2306. - MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1
  2307. - >;
  2308. - };
  2309. - };
  2310. -
  2311. - ecspi3 {
  2312. - pinctrl_ecspi3_1: ecspi3grp-1 {
  2313. - fsl,pins = <
  2314. - MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
  2315. - MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
  2316. - MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
  2317. - >;
  2318. - };
  2319. - };
  2320. -
  2321. - enet {
  2322. - pinctrl_enet_1: enetgrp-1 {
  2323. - fsl,pins = <
  2324. - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  2325. - MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  2326. - MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  2327. - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  2328. - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  2329. - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  2330. - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  2331. - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  2332. - MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  2333. - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  2334. - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  2335. - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  2336. - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  2337. - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  2338. - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  2339. - MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  2340. - >;
  2341. - };
  2342. -
  2343. - pinctrl_enet_2: enetgrp-2 {
  2344. - fsl,pins = <
  2345. - MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
  2346. - MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0
  2347. - MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  2348. - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  2349. - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  2350. - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  2351. - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  2352. - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  2353. - MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  2354. - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  2355. - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  2356. - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  2357. - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  2358. - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  2359. - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  2360. - >;
  2361. - };
  2362. -
  2363. - pinctrl_enet_3: enetgrp-3 {
  2364. - fsl,pins = <
  2365. - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  2366. - MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  2367. - MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  2368. - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  2369. - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  2370. - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  2371. - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  2372. - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  2373. - MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  2374. - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  2375. - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  2376. - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  2377. - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  2378. - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  2379. - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  2380. - MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
  2381. - >;
  2382. - };
  2383. - };
  2384. -
  2385. - esai {
  2386. - pinctrl_esai_1: esaigrp-1 {
  2387. - fsl,pins = <
  2388. - MX6QDL_PAD_ENET_RXD0__ESAI_TX_HF_CLK 0x1b030
  2389. - MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1b030
  2390. - MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS 0x1b030
  2391. - MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1b030
  2392. - MX6QDL_PAD_ENET_TXD1__ESAI_TX2_RX3 0x1b030
  2393. - MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1 0x1b030
  2394. - MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0 0x1b030
  2395. - MX6QDL_PAD_NANDF_CS2__ESAI_TX0 0x1b030
  2396. - MX6QDL_PAD_NANDF_CS3__ESAI_TX1 0x1b030
  2397. - >;
  2398. - };
  2399. -
  2400. - pinctrl_esai_2: esaigrp-2 {
  2401. - fsl,pins = <
  2402. - MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1b030
  2403. - MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS 0x1b030
  2404. - MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1b030
  2405. - MX6QDL_PAD_GPIO_5__ESAI_TX2_RX3 0x1b030
  2406. - MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1 0x1b030
  2407. - MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0 0x1b030
  2408. - MX6QDL_PAD_GPIO_17__ESAI_TX0 0x1b030
  2409. - MX6QDL_PAD_NANDF_CS3__ESAI_TX1 0x1b030
  2410. - MX6QDL_PAD_ENET_MDIO__ESAI_RX_CLK 0x1b030
  2411. - MX6QDL_PAD_GPIO_9__ESAI_RX_FS 0x1b030
  2412. - >;
  2413. - };
  2414. - };
  2415. -
  2416. - flexcan1 {
  2417. - pinctrl_flexcan1_1: flexcan1grp-1 {
  2418. - fsl,pins = <
  2419. - MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  2420. - MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x80000000
  2421. - >;
  2422. - };
  2423. -
  2424. - pinctrl_flexcan1_2: flexcan1grp-2 {
  2425. - fsl,pins = <
  2426. - MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x80000000
  2427. - MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  2428. - >;
  2429. - };
  2430. - };
  2431. -
  2432. - flexcan2 {
  2433. - pinctrl_flexcan2_1: flexcan2grp-1 {
  2434. - fsl,pins = <
  2435. - MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x80000000
  2436. - MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x80000000
  2437. - >;
  2438. - };
  2439. - };
  2440. -
  2441. - gpmi-nand {
  2442. - pinctrl_gpmi_nand_1: gpmi-nand-1 {
  2443. - fsl,pins = <
  2444. - MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  2445. - MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  2446. - MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  2447. - MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  2448. - MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  2449. - MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  2450. - MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  2451. - MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  2452. - MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  2453. - MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  2454. - MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  2455. - MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  2456. - MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  2457. - MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  2458. - MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  2459. - MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  2460. - MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  2461. - >;
  2462. - };
  2463. - };
  2464. -
  2465. - hdmi_hdcp {
  2466. - pinctrl_hdmi_hdcp_1: hdmihdcpgrp-1 {
  2467. - fsl,pins = <
  2468. - MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
  2469. - MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
  2470. - >;
  2471. - };
  2472. -
  2473. - pinctrl_hdmi_hdcp_2: hdmihdcpgrp-2 {
  2474. - fsl,pins = <
  2475. - MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
  2476. - MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x4001b8b1
  2477. - >;
  2478. - };
  2479. -
  2480. - pinctrl_hdmi_hdcp_3: hdmihdcpgrp-3 {
  2481. - fsl,pins = <
  2482. - MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
  2483. - MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
  2484. - >;
  2485. - };
  2486. - };
  2487. -
  2488. - hdmi_cec {
  2489. - pinctrl_hdmi_cec_1: hdmicecgrp-1 {
  2490. - fsl,pins = <
  2491. - MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE 0x1f8b0
  2492. - >;
  2493. - };
  2494. -
  2495. - pinctrl_hdmi_cec_2: hdmicecgrp-2 {
  2496. - fsl,pins = <
  2497. - MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  2498. - >;
  2499. - };
  2500. - };
  2501. -
  2502. - i2c1 {
  2503. - pinctrl_i2c1_1: i2c1grp-1 {
  2504. - fsl,pins = <
  2505. - MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  2506. - MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  2507. - >;
  2508. - };
  2509. -
  2510. - pinctrl_i2c1_2: i2c1grp-2 {
  2511. - fsl,pins = <
  2512. - MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
  2513. - MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
  2514. - >;
  2515. - };
  2516. - };
  2517. -
  2518. - i2c2 {
  2519. - pinctrl_i2c2_1: i2c2grp-1 {
  2520. - fsl,pins = <
  2521. - MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  2522. - MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
  2523. - >;
  2524. - };
  2525. -
  2526. - pinctrl_i2c2_2: i2c2grp-2 {
  2527. - fsl,pins = <
  2528. - MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  2529. - MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  2530. - >;
  2531. - };
  2532. -
  2533. - pinctrl_i2c2_3: i2c2grp-3 {
  2534. - fsl,pins = <
  2535. - MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  2536. - MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  2537. - >;
  2538. - };
  2539. - };
  2540. -
  2541. - i2c3 {
  2542. - pinctrl_i2c3_1: i2c3grp-1 {
  2543. - fsl,pins = <
  2544. - MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
  2545. - MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
  2546. - >;
  2547. - };
  2548. -
  2549. - pinctrl_i2c3_2: i2c3grp-2 {
  2550. - fsl,pins = <
  2551. - MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  2552. - MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  2553. - >;
  2554. - };
  2555. -
  2556. - pinctrl_i2c3_3: i2c3grp-3 {
  2557. - fsl,pins = <
  2558. - MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
  2559. - MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
  2560. - >;
  2561. - };
  2562. -
  2563. - pinctrl_i2c3_4: i2c3grp-4 {
  2564. - fsl,pins = <
  2565. - MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  2566. - MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
  2567. - >;
  2568. - };
  2569. - };
  2570. -
  2571. - ipu1 {
  2572. - pinctrl_ipu1_1: ipu1grp-1 {
  2573. - fsl,pins = <
  2574. - MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
  2575. - MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
  2576. - MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
  2577. - MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
  2578. - MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x80000000
  2579. - MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10
  2580. - MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
  2581. - MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
  2582. - MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
  2583. - MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
  2584. - MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
  2585. - MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
  2586. - MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
  2587. - MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
  2588. - MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
  2589. - MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
  2590. - MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
  2591. - MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
  2592. - MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
  2593. - MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
  2594. - MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
  2595. - MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
  2596. - MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
  2597. - MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
  2598. - MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
  2599. - MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
  2600. - MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
  2601. - MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
  2602. - MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
  2603. - >;
  2604. - };
  2605. -
  2606. - pinctrl_ipu1_2: ipu1grp-2 { /* parallel camera */
  2607. - fsl,pins = <
  2608. - MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x80000000
  2609. - MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x80000000
  2610. - MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x80000000
  2611. - MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x80000000
  2612. - MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x80000000
  2613. - MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x80000000
  2614. - MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x80000000
  2615. - MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x80000000
  2616. - MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x80000000
  2617. - MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x80000000
  2618. - MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x80000000
  2619. - MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x80000000
  2620. - >;
  2621. - };
  2622. -
  2623. - pinctrl_ipu1_3: ipu1grp-3 { /* parallel port 16-bit */
  2624. - fsl,pins = <
  2625. - MX6QDL_PAD_CSI0_DAT4__IPU1_CSI0_DATA04 0x80000000
  2626. - MX6QDL_PAD_CSI0_DAT5__IPU1_CSI0_DATA05 0x80000000
  2627. - MX6QDL_PAD_CSI0_DAT6__IPU1_CSI0_DATA06 0x80000000
  2628. - MX6QDL_PAD_CSI0_DAT7__IPU1_CSI0_DATA07 0x80000000
  2629. - MX6QDL_PAD_CSI0_DAT8__IPU1_CSI0_DATA08 0x80000000
  2630. - MX6QDL_PAD_CSI0_DAT9__IPU1_CSI0_DATA09 0x80000000
  2631. - MX6QDL_PAD_CSI0_DAT10__IPU1_CSI0_DATA10 0x80000000
  2632. - MX6QDL_PAD_CSI0_DAT11__IPU1_CSI0_DATA11 0x80000000
  2633. - MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x80000000
  2634. - MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x80000000
  2635. - MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x80000000
  2636. - MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x80000000
  2637. - MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x80000000
  2638. - MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x80000000
  2639. - MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x80000000
  2640. - MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x80000000
  2641. - MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x80000000
  2642. - MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x80000000
  2643. - MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x80000000
  2644. - >;
  2645. - };
  2646. - };
  2647. -
  2648. - mlb {
  2649. - pinctrl_mlb_1: mlbgrp-1 {
  2650. - fsl,pins = <
  2651. - MX6QDL_PAD_GPIO_3__MLB_CLK 0x71
  2652. - MX6QDL_PAD_GPIO_6__MLB_SIG 0x71
  2653. - MX6QDL_PAD_GPIO_2__MLB_DATA 0x71
  2654. - >;
  2655. - };
  2656. -
  2657. - pinctrl_mlb_2: mlbgrp-2 {
  2658. - fsl,pins = <
  2659. - MX6QDL_PAD_ENET_TXD1__MLB_CLK 0x71
  2660. - MX6QDL_PAD_GPIO_6__MLB_SIG 0x71
  2661. - MX6QDL_PAD_GPIO_2__MLB_DATA 0x71
  2662. - >;
  2663. - };
  2664. - };
  2665. -
  2666. - pwm0 {
  2667. - pinctrl_pwm0_1: pwm0grp-1 {
  2668. - fsl,pins = <
  2669. - MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  2670. - >;
  2671. - };
  2672. - };
  2673. -
  2674. - pwm3 {
  2675. - pinctrl_pwm3_1: pwm3grp-1 {
  2676. - fsl,pins = <
  2677. - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
  2678. - >;
  2679. - };
  2680. - };
  2681. -
  2682. - spdif {
  2683. - pinctrl_spdif_1: spdifgrp-1 {
  2684. - fsl,pins = <
  2685. - MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x1b0b0
  2686. - >;
  2687. - };
  2688. -
  2689. - pinctrl_spdif_2: spdifgrp-2 {
  2690. - fsl,pins = <
  2691. - MX6QDL_PAD_GPIO_16__SPDIF_IN 0x1b0b0
  2692. - MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0
  2693. - >;
  2694. - };
  2695. -
  2696. - pinctrl_spdif_3: spdifgrp-3 {
  2697. - fsl,pins = <
  2698. - MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1b0b0
  2699. - >;
  2700. - };
  2701. - };
  2702. -
  2703. - uart1 {
  2704. - pinctrl_uart1_1: uart1grp-1 {
  2705. - fsl,pins = <
  2706. - MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  2707. - MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  2708. - >;
  2709. - };
  2710. - };
  2711. -
  2712. - uart2 {
  2713. - pinctrl_uart2_1: uart2grp-1 {
  2714. - fsl,pins = <
  2715. - MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  2716. - MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  2717. - >;
  2718. - };
  2719. -
  2720. - pinctrl_uart2_2: uart2grp-2 { /* DTE mode */
  2721. - fsl,pins = <
  2722. - MX6QDL_PAD_EIM_D26__UART2_RX_DATA 0x1b0b1
  2723. - MX6QDL_PAD_EIM_D27__UART2_TX_DATA 0x1b0b1
  2724. - MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B 0x1b0b1
  2725. - MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B 0x1b0b1
  2726. - >;
  2727. - };
  2728. - };
  2729. -
  2730. - uart3 {
  2731. - pinctrl_uart3_1: uart3grp-1 {
  2732. - fsl,pins = <
  2733. - MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x1b0b1
  2734. - MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x1b0b1
  2735. - MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x1b0b1
  2736. - MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  2737. - >;
  2738. - };
  2739. -
  2740. - pinctrl_uart3_2: uart3grp-2 {
  2741. - fsl,pins = <
  2742. - MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  2743. - MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  2744. - MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1
  2745. - MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  2746. - >;
  2747. - };
  2748. - };
  2749. -
  2750. - uart4 {
  2751. - pinctrl_uart4_1: uart4grp-1 {
  2752. - fsl,pins = <
  2753. - MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  2754. - MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  2755. - >;
  2756. - };
  2757. - };
  2758. -
  2759. - usbotg {
  2760. - pinctrl_usbotg_1: usbotggrp-1 {
  2761. - fsl,pins = <
  2762. - MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  2763. - >;
  2764. - };
  2765. -
  2766. - pinctrl_usbotg_2: usbotggrp-2 {
  2767. - fsl,pins = <
  2768. - MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  2769. - >;
  2770. - };
  2771. - };
  2772. -
  2773. - usbh2 {
  2774. - pinctrl_usbh2_1: usbh2grp-1 {
  2775. - fsl,pins = <
  2776. - MX6QDL_PAD_RGMII_TXC__USB_H2_DATA 0x40013030
  2777. - MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40013030
  2778. - >;
  2779. - };
  2780. -
  2781. - pinctrl_usbh2_2: usbh2grp-2 {
  2782. - fsl,pins = <
  2783. - MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40017030
  2784. - >;
  2785. - };
  2786. - };
  2787. -
  2788. - usbh3 {
  2789. - pinctrl_usbh3_1: usbh3grp-1 {
  2790. - fsl,pins = <
  2791. - MX6QDL_PAD_RGMII_RX_CTL__USB_H3_DATA 0x40013030
  2792. - MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x40013030
  2793. - >;
  2794. - };
  2795. -
  2796. - pinctrl_usbh3_2: usbh3grp-2 {
  2797. - fsl,pins = <
  2798. - MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x40017030
  2799. - >;
  2800. - };
  2801. - };
  2802. -
  2803. - usdhc1 {
  2804. - pinctrl_usdhc1_1: usdhc1grp-1 {
  2805. - fsl,pins = <
  2806. - MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  2807. - MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  2808. - MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  2809. - MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  2810. - MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  2811. - MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  2812. - MX6QDL_PAD_NANDF_D0__SD1_DATA4 0x17059
  2813. - MX6QDL_PAD_NANDF_D1__SD1_DATA5 0x17059
  2814. - MX6QDL_PAD_NANDF_D2__SD1_DATA6 0x17059
  2815. - MX6QDL_PAD_NANDF_D3__SD1_DATA7 0x17059
  2816. - >;
  2817. - };
  2818. -
  2819. - pinctrl_usdhc1_2: usdhc1grp-2 {
  2820. - fsl,pins = <
  2821. - MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  2822. - MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  2823. - MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  2824. - MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  2825. - MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  2826. - MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  2827. - >;
  2828. - };
  2829. - };
  2830. -
  2831. - usdhc2 {
  2832. - pinctrl_usdhc2_1: usdhc2grp-1 {
  2833. - fsl,pins = <
  2834. - MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  2835. - MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  2836. - MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  2837. - MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  2838. - MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  2839. - MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  2840. - MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x17059
  2841. - MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x17059
  2842. - MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x17059
  2843. - MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x17059
  2844. - >;
  2845. - };
  2846. -
  2847. - pinctrl_usdhc2_2: usdhc2grp-2 {
  2848. - fsl,pins = <
  2849. - MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  2850. - MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  2851. - MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  2852. - MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  2853. - MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  2854. - MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  2855. - >;
  2856. - };
  2857. - };
  2858. -
  2859. - usdhc3 {
  2860. - pinctrl_usdhc3_1: usdhc3grp-1 {
  2861. - fsl,pins = <
  2862. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  2863. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  2864. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  2865. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  2866. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  2867. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  2868. - MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
  2869. - MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
  2870. - MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
  2871. - MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
  2872. - >;
  2873. - };
  2874. -
  2875. - pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz { /* 100Mhz */
  2876. - fsl,pins = <
  2877. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9
  2878. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9
  2879. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  2880. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  2881. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  2882. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  2883. - MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9
  2884. - MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9
  2885. - MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9
  2886. - MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9
  2887. - >;
  2888. - };
  2889. -
  2890. - pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz { /* 200Mhz */
  2891. - fsl,pins = <
  2892. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9
  2893. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9
  2894. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  2895. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  2896. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  2897. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  2898. - MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
  2899. - MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
  2900. - MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
  2901. - MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
  2902. - >;
  2903. - };
  2904. -
  2905. - pinctrl_usdhc3_2: usdhc3grp-2 {
  2906. - fsl,pins = <
  2907. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  2908. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  2909. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  2910. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  2911. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  2912. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  2913. - >;
  2914. - };
  2915. - };
  2916. -
  2917. - usdhc4 {
  2918. - pinctrl_usdhc4_1: usdhc4grp-1 {
  2919. - fsl,pins = <
  2920. - MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  2921. - MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  2922. - MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  2923. - MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  2924. - MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  2925. - MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  2926. - MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  2927. - MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  2928. - MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  2929. - MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  2930. - >;
  2931. - };
  2932. -
  2933. - pinctrl_usdhc4_2: usdhc4grp-2 {
  2934. - fsl,pins = <
  2935. - MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  2936. - MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  2937. - MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  2938. - MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  2939. - MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  2940. - MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  2941. - >;
  2942. - };
  2943. - };
  2944. -
  2945. - weim {
  2946. - pinctrl_weim_cs0_1: weim_cs0grp-1 {
  2947. - fsl,pins = <
  2948. - MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0xb0b1
  2949. - >;
  2950. - };
  2951. -
  2952. - pinctrl_weim_nor_1: weim_norgrp-1 {
  2953. - fsl,pins = <
  2954. - MX6QDL_PAD_EIM_OE__EIM_OE_B 0xb0b1
  2955. - MX6QDL_PAD_EIM_RW__EIM_RW 0xb0b1
  2956. - MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060
  2957. - /* data */
  2958. - MX6QDL_PAD_EIM_D16__EIM_DATA16 0x1b0b0
  2959. - MX6QDL_PAD_EIM_D17__EIM_DATA17 0x1b0b0
  2960. - MX6QDL_PAD_EIM_D18__EIM_DATA18 0x1b0b0
  2961. - MX6QDL_PAD_EIM_D19__EIM_DATA19 0x1b0b0
  2962. - MX6QDL_PAD_EIM_D20__EIM_DATA20 0x1b0b0
  2963. - MX6QDL_PAD_EIM_D21__EIM_DATA21 0x1b0b0
  2964. - MX6QDL_PAD_EIM_D22__EIM_DATA22 0x1b0b0
  2965. - MX6QDL_PAD_EIM_D23__EIM_DATA23 0x1b0b0
  2966. - MX6QDL_PAD_EIM_D24__EIM_DATA24 0x1b0b0
  2967. - MX6QDL_PAD_EIM_D25__EIM_DATA25 0x1b0b0
  2968. - MX6QDL_PAD_EIM_D26__EIM_DATA26 0x1b0b0
  2969. - MX6QDL_PAD_EIM_D27__EIM_DATA27 0x1b0b0
  2970. - MX6QDL_PAD_EIM_D28__EIM_DATA28 0x1b0b0
  2971. - MX6QDL_PAD_EIM_D29__EIM_DATA29 0x1b0b0
  2972. - MX6QDL_PAD_EIM_D30__EIM_DATA30 0x1b0b0
  2973. - MX6QDL_PAD_EIM_D31__EIM_DATA31 0x1b0b0
  2974. - /* address */
  2975. - MX6QDL_PAD_EIM_A23__EIM_ADDR23 0xb0b1
  2976. - MX6QDL_PAD_EIM_A22__EIM_ADDR22 0xb0b1
  2977. - MX6QDL_PAD_EIM_A21__EIM_ADDR21 0xb0b1
  2978. - MX6QDL_PAD_EIM_A20__EIM_ADDR20 0xb0b1
  2979. - MX6QDL_PAD_EIM_A19__EIM_ADDR19 0xb0b1
  2980. - MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0b1
  2981. - MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0b1
  2982. - MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0b1
  2983. - MX6QDL_PAD_EIM_DA15__EIM_AD15 0xb0b1
  2984. - MX6QDL_PAD_EIM_DA14__EIM_AD14 0xb0b1
  2985. - MX6QDL_PAD_EIM_DA13__EIM_AD13 0xb0b1
  2986. - MX6QDL_PAD_EIM_DA12__EIM_AD12 0xb0b1
  2987. - MX6QDL_PAD_EIM_DA11__EIM_AD11 0xb0b1
  2988. - MX6QDL_PAD_EIM_DA10__EIM_AD10 0xb0b1
  2989. - MX6QDL_PAD_EIM_DA9__EIM_AD09 0xb0b1
  2990. - MX6QDL_PAD_EIM_DA8__EIM_AD08 0xb0b1
  2991. - MX6QDL_PAD_EIM_DA7__EIM_AD07 0xb0b1
  2992. - MX6QDL_PAD_EIM_DA6__EIM_AD06 0xb0b1
  2993. - MX6QDL_PAD_EIM_DA5__EIM_AD05 0xb0b1
  2994. - MX6QDL_PAD_EIM_DA4__EIM_AD04 0xb0b1
  2995. - MX6QDL_PAD_EIM_DA3__EIM_AD03 0xb0b1
  2996. - MX6QDL_PAD_EIM_DA2__EIM_AD02 0xb0b1
  2997. - MX6QDL_PAD_EIM_DA1__EIM_AD01 0xb0b1
  2998. - MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0b1
  2999. - >;
  3000. - };
  3001. - };
  3002. };
  3003. ldb: ldb@020e0008 {
  3004. - #address-cells = <1>;
  3005. - #size-cells = <0>;
  3006. compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb";
  3007. - gpr = <&gpr>;
  3008. + reg = <0x020e0000 0x4000>;
  3009. + clocks = <&clks 135>, <&clks 136>,
  3010. + <&clks 39>, <&clks 40>,
  3011. + <&clks 41>, <&clks 42>,
  3012. + <&clks 184>, <&clks 185>,
  3013. + <&clks 210>, <&clks 211>,
  3014. + <&clks 212>, <&clks 213>;
  3015. + clock-names = "ldb_di0", "ldb_di1",
  3016. + "ipu1_di0_sel", "ipu1_di1_sel",
  3017. + "ipu2_di0_sel", "ipu2_di1_sel",
  3018. + "di0_div_3_5", "di1_div_3_5",
  3019. + "di0_div_7", "di1_div_7",
  3020. + "di0_div_sel", "di1_div_sel";
  3021. status = "disabled";
  3022. -
  3023. - lvds-channel@0 {
  3024. - reg = <0>;
  3025. - status = "disabled";
  3026. - };
  3027. -
  3028. - lvds-channel@1 {
  3029. - reg = <1>;
  3030. - status = "disabled";
  3031. - };
  3032. };
  3033. dcic1: dcic@020e4000 {
  3034. reg = <0x020e4000 0x4000>;
  3035. - interrupts = <0 124 0x04>;
  3036. + interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>;
  3037. };
  3038. dcic2: dcic@020e8000 {
  3039. reg = <0x020e8000 0x4000>;
  3040. - interrupts = <0 125 0x04>;
  3041. + interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
  3042. };
  3043. sdma: sdma@020ec000 {
  3044. compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
  3045. reg = <0x020ec000 0x4000>;
  3046. - interrupts = <0 2 0x04>;
  3047. + interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
  3048. clocks = <&clks 155>, <&clks 155>;
  3049. clock-names = "ipg", "ahb";
  3050. #dma-cells = <3>;
  3051. @@ -1396,9 +772,29 @@
  3052. reg = <0x02100000 0x100000>;
  3053. ranges;
  3054. - caam@02100000 {
  3055. - reg = <0x02100000 0x40000>;
  3056. - interrupts = <0 105 0x04 0 106 0x04>;
  3057. + crypto: caam@02100000 {
  3058. + compatible = "fsl,sec-v4.0";
  3059. + #address-cells = <1>;
  3060. + #size-cells = <1>;
  3061. + reg = <0x2100000 0x40000>;
  3062. + ranges = <0 0x2100000 0x40000>;
  3063. + interrupt-parent = <&intc>; /* interrupts = <0 92 0x4>; */
  3064. + clocks = <&clks 214>, <&clks 215>, <&clks 216>, <&clks 196>;
  3065. + clock-names = "caam_mem", "caam_aclk", "caam_ipg", "caam_emi_slow";
  3066. +
  3067. + sec_jr0: jr0@1000 {
  3068. + compatible = "fsl,sec-v4.0-job-ring";
  3069. + reg = <0x1000 0x1000>;
  3070. + interrupt-parent = <&intc>;
  3071. + interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
  3072. + };
  3073. +
  3074. + sec_jr1: jr1@2000 {
  3075. + compatible = "fsl,sec-v4.0-job-ring";
  3076. + reg = <0x2000 0x1000>;
  3077. + interrupt-parent = <&intc>;
  3078. + interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
  3079. + };
  3080. };
  3081. aipstz@0217c000 { /* AIPSTZ2 */
  3082. @@ -1408,7 +804,7 @@
  3083. usbotg: usb@02184000 {
  3084. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3085. reg = <0x02184000 0x200>;
  3086. - interrupts = <0 43 0x04>;
  3087. + interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
  3088. clocks = <&clks 162>;
  3089. fsl,usbphy = <&usbphy1>;
  3090. fsl,usbmisc = <&usbmisc 0>;
  3091. @@ -1418,7 +814,7 @@
  3092. usbh1: usb@02184200 {
  3093. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3094. reg = <0x02184200 0x200>;
  3095. - interrupts = <0 40 0x04>;
  3096. + interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
  3097. clocks = <&clks 162>;
  3098. fsl,usbphy = <&usbphy2>;
  3099. fsl,usbmisc = <&usbmisc 1>;
  3100. @@ -1428,18 +824,24 @@
  3101. usbh2: usb@02184400 {
  3102. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3103. reg = <0x02184400 0x200>;
  3104. - interrupts = <0 41 0x04>;
  3105. + interrupts = <0 41 IRQ_TYPE_LEVEL_HIGH>;
  3106. clocks = <&clks 162>;
  3107. fsl,usbmisc = <&usbmisc 2>;
  3108. + phy_type = "hsic";
  3109. + fsl,usbphy = <&usbphy_nop1>;
  3110. + fsl,anatop = <&anatop>;
  3111. status = "disabled";
  3112. };
  3113. usbh3: usb@02184600 {
  3114. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3115. reg = <0x02184600 0x200>;
  3116. - interrupts = <0 42 0x04>;
  3117. + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
  3118. clocks = <&clks 162>;
  3119. fsl,usbmisc = <&usbmisc 3>;
  3120. + phy_type = "hsic";
  3121. + fsl,usbphy = <&usbphy_nop2>;
  3122. + fsl,anatop = <&anatop>;
  3123. status = "disabled";
  3124. };
  3125. @@ -1453,7 +855,9 @@
  3126. fec: ethernet@02188000 {
  3127. compatible = "fsl,imx6q-fec";
  3128. reg = <0x02188000 0x4000>;
  3129. - interrupts = <0 118 0x04 0 119 0x04>;
  3130. + interrupts-extended =
  3131. + <&intc 0 118 IRQ_TYPE_LEVEL_HIGH>,
  3132. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  3133. clocks = <&clks 117>, <&clks 117>, <&clks 190>;
  3134. clock-names = "ipg", "ahb", "ptp";
  3135. status = "disabled";
  3136. @@ -1461,13 +865,15 @@
  3137. mlb@0218c000 {
  3138. reg = <0x0218c000 0x4000>;
  3139. - interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
  3140. + interrupts = <0 53 IRQ_TYPE_LEVEL_HIGH>,
  3141. + <0 117 IRQ_TYPE_LEVEL_HIGH>,
  3142. + <0 126 IRQ_TYPE_LEVEL_HIGH>;
  3143. };
  3144. usdhc1: usdhc@02190000 {
  3145. compatible = "fsl,imx6q-usdhc";
  3146. reg = <0x02190000 0x4000>;
  3147. - interrupts = <0 22 0x04>;
  3148. + interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
  3149. clocks = <&clks 163>, <&clks 163>, <&clks 163>;
  3150. clock-names = "ipg", "ahb", "per";
  3151. bus-width = <4>;
  3152. @@ -1477,7 +883,7 @@
  3153. usdhc2: usdhc@02194000 {
  3154. compatible = "fsl,imx6q-usdhc";
  3155. reg = <0x02194000 0x4000>;
  3156. - interrupts = <0 23 0x04>;
  3157. + interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
  3158. clocks = <&clks 164>, <&clks 164>, <&clks 164>;
  3159. clock-names = "ipg", "ahb", "per";
  3160. bus-width = <4>;
  3161. @@ -1487,7 +893,7 @@
  3162. usdhc3: usdhc@02198000 {
  3163. compatible = "fsl,imx6q-usdhc";
  3164. reg = <0x02198000 0x4000>;
  3165. - interrupts = <0 24 0x04>;
  3166. + interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
  3167. clocks = <&clks 165>, <&clks 165>, <&clks 165>;
  3168. clock-names = "ipg", "ahb", "per";
  3169. bus-width = <4>;
  3170. @@ -1497,7 +903,7 @@
  3171. usdhc4: usdhc@0219c000 {
  3172. compatible = "fsl,imx6q-usdhc";
  3173. reg = <0x0219c000 0x4000>;
  3174. - interrupts = <0 25 0x04>;
  3175. + interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
  3176. clocks = <&clks 166>, <&clks 166>, <&clks 166>;
  3177. clock-names = "ipg", "ahb", "per";
  3178. bus-width = <4>;
  3179. @@ -1509,7 +915,7 @@
  3180. #size-cells = <0>;
  3181. compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
  3182. reg = <0x021a0000 0x4000>;
  3183. - interrupts = <0 36 0x04>;
  3184. + interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
  3185. clocks = <&clks 125>;
  3186. status = "disabled";
  3187. };
  3188. @@ -1519,7 +925,7 @@
  3189. #size-cells = <0>;
  3190. compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
  3191. reg = <0x021a4000 0x4000>;
  3192. - interrupts = <0 37 0x04>;
  3193. + interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
  3194. clocks = <&clks 126>;
  3195. status = "disabled";
  3196. };
  3197. @@ -1529,7 +935,7 @@
  3198. #size-cells = <0>;
  3199. compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
  3200. reg = <0x021a8000 0x4000>;
  3201. - interrupts = <0 38 0x04>;
  3202. + interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
  3203. clocks = <&clks 127>;
  3204. status = "disabled";
  3205. };
  3206. @@ -1538,6 +944,11 @@
  3207. reg = <0x021ac000 0x4000>;
  3208. };
  3209. + mmdc0-1@021b0000 { /* MMDC0-1 */
  3210. + compatible = "fsl,imx6q-mmdc-combine";
  3211. + reg = <0x021b0000 0x8000>;
  3212. + };
  3213. +
  3214. mmdc0: mmdc@021b0000 { /* MMDC0 */
  3215. compatible = "fsl,imx6q-mmdc";
  3216. reg = <0x021b0000 0x4000>;
  3217. @@ -1550,23 +961,29 @@
  3218. weim: weim@021b8000 {
  3219. compatible = "fsl,imx6q-weim";
  3220. reg = <0x021b8000 0x4000>;
  3221. - interrupts = <0 14 0x04>;
  3222. + interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
  3223. clocks = <&clks 196>;
  3224. };
  3225. - ocotp: ocotp@021bc000 {
  3226. - compatible = "fsl,imx6q-ocotp", "syscon";
  3227. + ocotp: ocotp-ctrl@021bc000 {
  3228. + compatible = "syscon";
  3229. reg = <0x021bc000 0x4000>;
  3230. };
  3231. + ocotp-fuse@021bc000 {
  3232. + compatible = "fsl,imx6q-ocotp";
  3233. + reg = <0x021bc000 0x4000>;
  3234. + clocks = <&clks 128>;
  3235. + };
  3236. +
  3237. tzasc@021d0000 { /* TZASC1 */
  3238. reg = <0x021d0000 0x4000>;
  3239. - interrupts = <0 108 0x04>;
  3240. + interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
  3241. };
  3242. tzasc@021d4000 { /* TZASC2 */
  3243. reg = <0x021d4000 0x4000>;
  3244. - interrupts = <0 109 0x04>;
  3245. + interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
  3246. };
  3247. audmux: audmux@021d8000 {
  3248. @@ -1575,23 +992,32 @@
  3249. status = "disabled";
  3250. };
  3251. - mipi@021dc000 { /* MIPI-CSI */
  3252. + mipi_csi: mipi_csi@021dc000 {
  3253. + compatible = "fsl,imx6q-mipi-csi2";
  3254. reg = <0x021dc000 0x4000>;
  3255. - };
  3256. -
  3257. - mipi@021e0000 { /* MIPI-DSI */
  3258. - reg = <0x021e0000 0x4000>;
  3259. + interrupts = <0 100 0x04>, <0 101 0x04>;
  3260. + clocks = <&clks 138>, <&clks 53>, <&clks 204>;
  3261. + /* Note: clks 138 is hsi_tx, however, the dphy_c
  3262. + * hsi_tx and pll_refclk use the same clk gate.
  3263. + * In current clk driver, open/close clk gate do
  3264. + * use hsi_tx for a temporary debug purpose.
  3265. + */
  3266. + clock-names = "dphy_clk", "pixel_clk", "cfg_clk";
  3267. + status = "disabled";
  3268. };
  3269. vdoa@021e4000 {
  3270. + compatible = "fsl,imx6q-vdoa";
  3271. reg = <0x021e4000 0x4000>;
  3272. - interrupts = <0 18 0x04>;
  3273. + interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
  3274. + clocks = <&clks 202>;
  3275. + iram = <&ocram>;
  3276. };
  3277. uart2: serial@021e8000 {
  3278. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3279. reg = <0x021e8000 0x4000>;
  3280. - interrupts = <0 27 0x04>;
  3281. + interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
  3282. clocks = <&clks 160>, <&clks 161>;
  3283. clock-names = "ipg", "per";
  3284. dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
  3285. @@ -1602,7 +1028,7 @@
  3286. uart3: serial@021ec000 {
  3287. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3288. reg = <0x021ec000 0x4000>;
  3289. - interrupts = <0 28 0x04>;
  3290. + interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
  3291. clocks = <&clks 160>, <&clks 161>;
  3292. clock-names = "ipg", "per";
  3293. dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
  3294. @@ -1613,7 +1039,7 @@
  3295. uart4: serial@021f0000 {
  3296. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3297. reg = <0x021f0000 0x4000>;
  3298. - interrupts = <0 29 0x04>;
  3299. + interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
  3300. clocks = <&clks 160>, <&clks 161>;
  3301. clock-names = "ipg", "per";
  3302. dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
  3303. @@ -1624,7 +1050,7 @@
  3304. uart5: serial@021f4000 {
  3305. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3306. reg = <0x021f4000 0x4000>;
  3307. - interrupts = <0 30 0x04>;
  3308. + interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
  3309. clocks = <&clks 160>, <&clks 161>;
  3310. clock-names = "ipg", "per";
  3311. dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
  3312. @@ -1634,13 +1060,18 @@
  3313. };
  3314. ipu1: ipu@02400000 {
  3315. - #crtc-cells = <1>;
  3316. compatible = "fsl,imx6q-ipu";
  3317. reg = <0x02400000 0x400000>;
  3318. - interrupts = <0 6 0x4 0 5 0x4>;
  3319. - clocks = <&clks 130>, <&clks 131>, <&clks 132>;
  3320. - clock-names = "bus", "di0", "di1";
  3321. + interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>,
  3322. + <0 5 IRQ_TYPE_LEVEL_HIGH>;
  3323. + clocks = <&clks 130>, <&clks 131>, <&clks 132>,
  3324. + <&clks 39>, <&clks 40>,
  3325. + <&clks 135>, <&clks 136>;
  3326. + clock-names = "bus", "di0", "di1",
  3327. + "di0_sel", "di1_sel",
  3328. + "ldb_di0", "ldb_di1";
  3329. resets = <&src 2>;
  3330. + bypass_reset = <0>;
  3331. };
  3332. };
  3333. };
  3334. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
  3335. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi 1969-12-31 18:00:00.000000000 -0600
  3336. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi 2014-12-08 00:31:51.124418001 -0600
  3337. @@ -0,0 +1,374 @@
  3338. +/*
  3339. + * Copyright 2013 Gateworks Corporation
  3340. + *
  3341. + * The code contained herein is licensed under the GNU General Public
  3342. + * License. You may obtain a copy of the GNU General Public License
  3343. + * Version 2 or later at the following locations:
  3344. + *
  3345. + * http://www.opensource.org/licenses/gpl-license.html
  3346. + * http://www.gnu.org/copyleft/gpl.html
  3347. + */
  3348. +
  3349. +/ {
  3350. + /* these are used by bootloader for disabling nodes */
  3351. + aliases {
  3352. + can0 = &can1;
  3353. + ethernet0 = &fec;
  3354. + led0 = &led0;
  3355. + led1 = &led1;
  3356. + nand = &gpmi;
  3357. + usb0 = &usbh1;
  3358. + usb1 = &usbotg;
  3359. + };
  3360. +
  3361. + chosen {
  3362. + bootargs = "console=ttymxc1,115200";
  3363. + };
  3364. +
  3365. + leds {
  3366. + compatible = "gpio-leds";
  3367. +
  3368. + led0: user1 {
  3369. + label = "user1";
  3370. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  3371. + default-state = "on";
  3372. + linux,default-trigger = "heartbeat";
  3373. + };
  3374. +
  3375. + led1: user2 {
  3376. + label = "user2";
  3377. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  3378. + default-state = "off";
  3379. + };
  3380. + };
  3381. +
  3382. + memory {
  3383. + reg = <0x10000000 0x20000000>;
  3384. + };
  3385. +
  3386. + pps {
  3387. + compatible = "pps-gpio";
  3388. + gpios = <&gpio1 26 0>;
  3389. + status = "okay";
  3390. + };
  3391. +
  3392. + regulators {
  3393. + compatible = "simple-bus";
  3394. + #address-cells = <1>;
  3395. + #size-cells = <0>;
  3396. +
  3397. + reg_3p3v: regulator@0 {
  3398. + compatible = "regulator-fixed";
  3399. + reg = <0>;
  3400. + regulator-name = "3P3V";
  3401. + regulator-min-microvolt = <3300000>;
  3402. + regulator-max-microvolt = <3300000>;
  3403. + regulator-always-on;
  3404. + };
  3405. +
  3406. + reg_5p0v: regulator@1 {
  3407. + compatible = "regulator-fixed";
  3408. + reg = <1>;
  3409. + regulator-name = "5P0V";
  3410. + regulator-min-microvolt = <5000000>;
  3411. + regulator-max-microvolt = <5000000>;
  3412. + regulator-always-on;
  3413. + };
  3414. +
  3415. + reg_usb_otg_vbus: regulator@2 {
  3416. + compatible = "regulator-fixed";
  3417. + reg = <2>;
  3418. + regulator-name = "usb_otg_vbus";
  3419. + regulator-min-microvolt = <5000000>;
  3420. + regulator-max-microvolt = <5000000>;
  3421. + gpio = <&gpio3 22 0>;
  3422. + enable-active-high;
  3423. + };
  3424. + };
  3425. +};
  3426. +
  3427. +&fec {
  3428. + pinctrl-names = "default";
  3429. + pinctrl-0 = <&pinctrl_enet>;
  3430. + phy-mode = "rgmii";
  3431. + phy-reset-gpios = <&gpio1 30 0>;
  3432. + status = "okay";
  3433. +};
  3434. +
  3435. +&gpmi {
  3436. + pinctrl-names = "default";
  3437. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  3438. + status = "okay";
  3439. +};
  3440. +
  3441. +&i2c1 {
  3442. + clock-frequency = <100000>;
  3443. + pinctrl-names = "default";
  3444. + pinctrl-0 = <&pinctrl_i2c1>;
  3445. + status = "okay";
  3446. +
  3447. + eeprom1: eeprom@50 {
  3448. + compatible = "atmel,24c02";
  3449. + reg = <0x50>;
  3450. + pagesize = <16>;
  3451. + };
  3452. +
  3453. + eeprom2: eeprom@51 {
  3454. + compatible = "atmel,24c02";
  3455. + reg = <0x51>;
  3456. + pagesize = <16>;
  3457. + };
  3458. +
  3459. + eeprom3: eeprom@52 {
  3460. + compatible = "atmel,24c02";
  3461. + reg = <0x52>;
  3462. + pagesize = <16>;
  3463. + };
  3464. +
  3465. + eeprom4: eeprom@53 {
  3466. + compatible = "atmel,24c02";
  3467. + reg = <0x53>;
  3468. + pagesize = <16>;
  3469. + };
  3470. +
  3471. + gpio: pca9555@23 {
  3472. + compatible = "nxp,pca9555";
  3473. + reg = <0x23>;
  3474. + gpio-controller;
  3475. + #gpio-cells = <2>;
  3476. + };
  3477. +
  3478. + hwmon: gsc@29 {
  3479. + compatible = "gw,gsp";
  3480. + reg = <0x29>;
  3481. + };
  3482. +
  3483. + rtc: ds1672@68 {
  3484. + compatible = "dallas,ds1672";
  3485. + reg = <0x68>;
  3486. + };
  3487. +};
  3488. +
  3489. +&i2c2 {
  3490. + clock-frequency = <100000>;
  3491. + pinctrl-names = "default";
  3492. + pinctrl-0 = <&pinctrl_i2c2>;
  3493. + status = "okay";
  3494. +
  3495. + pmic: ltc3676@3c {
  3496. + compatible = "ltc,ltc3676";
  3497. + reg = <0x3c>;
  3498. +
  3499. + regulators {
  3500. + sw1_reg: ltc3676__sw1 {
  3501. + regulator-min-microvolt = <1175000>;
  3502. + regulator-max-microvolt = <1175000>;
  3503. + regulator-boot-on;
  3504. + regulator-always-on;
  3505. + };
  3506. +
  3507. + sw2_reg: ltc3676__sw2 {
  3508. + regulator-min-microvolt = <1800000>;
  3509. + regulator-max-microvolt = <1800000>;
  3510. + regulator-boot-on;
  3511. + regulator-always-on;
  3512. + };
  3513. +
  3514. + sw3_reg: ltc3676__sw3 {
  3515. + regulator-min-microvolt = <1175000>;
  3516. + regulator-max-microvolt = <1175000>;
  3517. + regulator-boot-on;
  3518. + regulator-always-on;
  3519. + };
  3520. +
  3521. + sw4_reg: ltc3676__sw4 {
  3522. + regulator-min-microvolt = <1500000>;
  3523. + regulator-max-microvolt = <1500000>;
  3524. + regulator-boot-on;
  3525. + regulator-always-on;
  3526. + };
  3527. +
  3528. + ldo2_reg: ltc3676__ldo2 {
  3529. + regulator-min-microvolt = <2500000>;
  3530. + regulator-max-microvolt = <2500000>;
  3531. + regulator-boot-on;
  3532. + regulator-always-on;
  3533. + };
  3534. +
  3535. + ldo4_reg: ltc3676__ldo4 {
  3536. + regulator-min-microvolt = <3000000>;
  3537. + regulator-max-microvolt = <3000000>;
  3538. + };
  3539. + };
  3540. + };
  3541. +};
  3542. +
  3543. +&i2c3 {
  3544. + clock-frequency = <100000>;
  3545. + pinctrl-names = "default";
  3546. + pinctrl-0 = <&pinctrl_i2c3>;
  3547. + status = "okay";
  3548. +
  3549. + videoin: adv7180@20 {
  3550. + compatible = "adi,adv7180";
  3551. + reg = <0x20>;
  3552. + };
  3553. +};
  3554. +
  3555. +&iomuxc {
  3556. + pinctrl-names = "default";
  3557. + pinctrl-0 = <&pinctrl_hog>;
  3558. +
  3559. + imx6qdl-gw51xx {
  3560. + pinctrl_hog: hoggrp {
  3561. + fsl,pins = <
  3562. + MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x80000000 /* MEZZ_DIO0 */
  3563. + MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x80000000 /* MEZZ_DIO1 */
  3564. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  3565. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  3566. + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* PHY Reset */
  3567. + MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x80000000 /* PCIE_RST# */
  3568. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  3569. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  3570. + >;
  3571. + };
  3572. +
  3573. + pinctrl_enet: enetgrp {
  3574. + fsl,pins = <
  3575. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  3576. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  3577. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  3578. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  3579. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  3580. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  3581. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  3582. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  3583. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  3584. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  3585. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  3586. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  3587. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  3588. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  3589. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  3590. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  3591. + >;
  3592. + };
  3593. +
  3594. + pinctrl_gpmi_nand: gpminandgrp {
  3595. + fsl,pins = <
  3596. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  3597. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  3598. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  3599. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  3600. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  3601. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  3602. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  3603. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  3604. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  3605. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  3606. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  3607. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  3608. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  3609. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  3610. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  3611. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  3612. + >;
  3613. + };
  3614. +
  3615. + pinctrl_i2c1: i2c1grp {
  3616. + fsl,pins = <
  3617. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  3618. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  3619. + >;
  3620. + };
  3621. +
  3622. + pinctrl_i2c2: i2c2grp {
  3623. + fsl,pins = <
  3624. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  3625. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  3626. + >;
  3627. + };
  3628. +
  3629. + pinctrl_i2c3: i2c3grp {
  3630. + fsl,pins = <
  3631. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  3632. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  3633. + >;
  3634. + };
  3635. +
  3636. + pinctrl_uart1: uart1grp {
  3637. + fsl,pins = <
  3638. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  3639. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  3640. + >;
  3641. + };
  3642. +
  3643. + pinctrl_uart2: uart2grp {
  3644. + fsl,pins = <
  3645. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  3646. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  3647. + >;
  3648. + };
  3649. +
  3650. + pinctrl_uart3: uart3grp {
  3651. + fsl,pins = <
  3652. + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  3653. + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  3654. + >;
  3655. + };
  3656. +
  3657. + pinctrl_uart5: uart5grp {
  3658. + fsl,pins = <
  3659. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  3660. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  3661. + >;
  3662. + };
  3663. +
  3664. + pinctrl_usbotg: usbotggrp {
  3665. + fsl,pins = <
  3666. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  3667. + >;
  3668. + };
  3669. + };
  3670. +};
  3671. +
  3672. +&pcie {
  3673. + reset-gpio = <&gpio1 0 0>;
  3674. + status = "okay";
  3675. +};
  3676. +
  3677. +&uart1 {
  3678. + pinctrl-names = "default";
  3679. + pinctrl-0 = <&pinctrl_uart1>;
  3680. + status = "okay";
  3681. +};
  3682. +
  3683. +&uart2 {
  3684. + pinctrl-names = "default";
  3685. + pinctrl-0 = <&pinctrl_uart2>;
  3686. + status = "okay";
  3687. +};
  3688. +
  3689. +&uart3 {
  3690. + pinctrl-names = "default";
  3691. + pinctrl-0 = <&pinctrl_uart3>;
  3692. + status = "okay";
  3693. +};
  3694. +
  3695. +&uart5 {
  3696. + pinctrl-names = "default";
  3697. + pinctrl-0 = <&pinctrl_uart5>;
  3698. + status = "okay";
  3699. +};
  3700. +
  3701. +&usbotg {
  3702. + vbus-supply = <&reg_usb_otg_vbus>;
  3703. + pinctrl-names = "default";
  3704. + pinctrl-0 = <&pinctrl_usbotg>;
  3705. + disable-over-current;
  3706. + status = "okay";
  3707. +};
  3708. +
  3709. +&usbh1 {
  3710. + status = "okay";
  3711. +};
  3712. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
  3713. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi 1969-12-31 18:00:00.000000000 -0600
  3714. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi 2014-12-08 00:31:51.124418001 -0600
  3715. @@ -0,0 +1,527 @@
  3716. +/*
  3717. + * Copyright 2013 Gateworks Corporation
  3718. + *
  3719. + * The code contained herein is licensed under the GNU General Public
  3720. + * License. You may obtain a copy of the GNU General Public License
  3721. + * Version 2 or later at the following locations:
  3722. + *
  3723. + * http://www.opensource.org/licenses/gpl-license.html
  3724. + * http://www.gnu.org/copyleft/gpl.html
  3725. + */
  3726. +
  3727. +/ {
  3728. + /* these are used by bootloader for disabling nodes */
  3729. + aliases {
  3730. + ethernet0 = &fec;
  3731. + led0 = &led0;
  3732. + led1 = &led1;
  3733. + led2 = &led2;
  3734. + nand = &gpmi;
  3735. + ssi0 = &ssi1;
  3736. + usb0 = &usbh1;
  3737. + usb1 = &usbotg;
  3738. + usdhc2 = &usdhc3;
  3739. + };
  3740. +
  3741. + chosen {
  3742. + bootargs = "console=ttymxc1,115200";
  3743. + };
  3744. +
  3745. + backlight {
  3746. + compatible = "pwm-backlight";
  3747. + pwms = <&pwm4 0 5000000>;
  3748. + brightness-levels = <0 4 8 16 32 64 128 255>;
  3749. + default-brightness-level = <7>;
  3750. + };
  3751. +
  3752. + leds {
  3753. + compatible = "gpio-leds";
  3754. +
  3755. + led0: user1 {
  3756. + label = "user1";
  3757. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  3758. + default-state = "on";
  3759. + linux,default-trigger = "heartbeat";
  3760. + };
  3761. +
  3762. + led1: user2 {
  3763. + label = "user2";
  3764. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  3765. + default-state = "off";
  3766. + };
  3767. +
  3768. + led2: user3 {
  3769. + label = "user3";
  3770. + gpios = <&gpio4 15 1>; /* 111 - MX6_LOCLED# */
  3771. + default-state = "off";
  3772. + };
  3773. + };
  3774. +
  3775. + memory {
  3776. + reg = <0x10000000 0x20000000>;
  3777. + };
  3778. +
  3779. + pps {
  3780. + compatible = "pps-gpio";
  3781. + gpios = <&gpio1 26 0>;
  3782. + status = "okay";
  3783. + };
  3784. +
  3785. + regulators {
  3786. + compatible = "simple-bus";
  3787. + #address-cells = <1>;
  3788. + #size-cells = <0>;
  3789. +
  3790. + reg_1p0v: regulator@0 {
  3791. + compatible = "regulator-fixed";
  3792. + reg = <0>;
  3793. + regulator-name = "1P0V";
  3794. + regulator-min-microvolt = <1000000>;
  3795. + regulator-max-microvolt = <1000000>;
  3796. + regulator-always-on;
  3797. + };
  3798. +
  3799. + /* remove this fixed regulator once ltc3676__sw2 driver available */
  3800. + reg_1p8v: regulator@1 {
  3801. + compatible = "regulator-fixed";
  3802. + reg = <1>;
  3803. + regulator-name = "1P8V";
  3804. + regulator-min-microvolt = <1800000>;
  3805. + regulator-max-microvolt = <1800000>;
  3806. + regulator-always-on;
  3807. + };
  3808. +
  3809. + reg_3p3v: regulator@2 {
  3810. + compatible = "regulator-fixed";
  3811. + reg = <2>;
  3812. + regulator-name = "3P3V";
  3813. + regulator-min-microvolt = <3300000>;
  3814. + regulator-max-microvolt = <3300000>;
  3815. + regulator-always-on;
  3816. + };
  3817. +
  3818. + reg_5p0v: regulator@3 {
  3819. + compatible = "regulator-fixed";
  3820. + reg = <3>;
  3821. + regulator-name = "5P0V";
  3822. + regulator-min-microvolt = <5000000>;
  3823. + regulator-max-microvolt = <5000000>;
  3824. + regulator-always-on;
  3825. + };
  3826. +
  3827. + reg_usb_otg_vbus: regulator@4 {
  3828. + compatible = "regulator-fixed";
  3829. + reg = <4>;
  3830. + regulator-name = "usb_otg_vbus";
  3831. + regulator-min-microvolt = <5000000>;
  3832. + regulator-max-microvolt = <5000000>;
  3833. + gpio = <&gpio3 22 0>;
  3834. + enable-active-high;
  3835. + };
  3836. + };
  3837. +
  3838. + sound {
  3839. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  3840. + "fsl,imx-audio-sgtl5000";
  3841. + model = "imx6q-sabrelite-sgtl5000";
  3842. + ssi-controller = <&ssi1>;
  3843. + audio-codec = <&codec>;
  3844. + audio-routing =
  3845. + "MIC_IN", "Mic Jack",
  3846. + "Mic Jack", "Mic Bias",
  3847. + "Headphone Jack", "HP_OUT";
  3848. + mux-int-port = <1>;
  3849. + mux-ext-port = <4>;
  3850. + };
  3851. +};
  3852. +
  3853. +&audmux {
  3854. + pinctrl-names = "default";
  3855. + pinctrl-0 = <&pinctrl_audmux>;
  3856. + status = "okay";
  3857. +};
  3858. +
  3859. +&fec {
  3860. + pinctrl-names = "default";
  3861. + pinctrl-0 = <&pinctrl_enet>;
  3862. + phy-mode = "rgmii";
  3863. + phy-reset-gpios = <&gpio1 30 0>;
  3864. + status = "okay";
  3865. +};
  3866. +
  3867. +&gpmi {
  3868. + pinctrl-names = "default";
  3869. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  3870. + status = "okay";
  3871. +};
  3872. +
  3873. +&i2c1 {
  3874. + clock-frequency = <100000>;
  3875. + pinctrl-names = "default";
  3876. + pinctrl-0 = <&pinctrl_i2c1>;
  3877. + status = "okay";
  3878. +
  3879. + eeprom1: eeprom@50 {
  3880. + compatible = "atmel,24c02";
  3881. + reg = <0x50>;
  3882. + pagesize = <16>;
  3883. + };
  3884. +
  3885. + eeprom2: eeprom@51 {
  3886. + compatible = "atmel,24c02";
  3887. + reg = <0x51>;
  3888. + pagesize = <16>;
  3889. + };
  3890. +
  3891. + eeprom3: eeprom@52 {
  3892. + compatible = "atmel,24c02";
  3893. + reg = <0x52>;
  3894. + pagesize = <16>;
  3895. + };
  3896. +
  3897. + eeprom4: eeprom@53 {
  3898. + compatible = "atmel,24c02";
  3899. + reg = <0x53>;
  3900. + pagesize = <16>;
  3901. + };
  3902. +
  3903. + gpio: pca9555@23 {
  3904. + compatible = "nxp,pca9555";
  3905. + reg = <0x23>;
  3906. + gpio-controller;
  3907. + #gpio-cells = <2>;
  3908. + };
  3909. +
  3910. + hwmon: gsc@29 {
  3911. + compatible = "gw,gsp";
  3912. + reg = <0x29>;
  3913. + };
  3914. +
  3915. + rtc: ds1672@68 {
  3916. + compatible = "dallas,ds1672";
  3917. + reg = <0x68>;
  3918. + };
  3919. +};
  3920. +
  3921. +&i2c2 {
  3922. + clock-frequency = <100000>;
  3923. + pinctrl-names = "default";
  3924. + pinctrl-0 = <&pinctrl_i2c2>;
  3925. + status = "okay";
  3926. +
  3927. + pciswitch: pex8609@3f {
  3928. + compatible = "plx,pex8609";
  3929. + reg = <0x3f>;
  3930. + };
  3931. +
  3932. + pmic: ltc3676@3c {
  3933. + compatible = "ltc,ltc3676";
  3934. + reg = <0x3c>;
  3935. +
  3936. + regulators {
  3937. + sw1_reg: ltc3676__sw1 {
  3938. + regulator-min-microvolt = <1175000>;
  3939. + regulator-max-microvolt = <1175000>;
  3940. + regulator-boot-on;
  3941. + regulator-always-on;
  3942. + };
  3943. +
  3944. + sw2_reg: ltc3676__sw2 {
  3945. + regulator-min-microvolt = <1800000>;
  3946. + regulator-max-microvolt = <1800000>;
  3947. + regulator-boot-on;
  3948. + regulator-always-on;
  3949. + };
  3950. +
  3951. + sw3_reg: ltc3676__sw3 {
  3952. + regulator-min-microvolt = <1175000>;
  3953. + regulator-max-microvolt = <1175000>;
  3954. + regulator-boot-on;
  3955. + regulator-always-on;
  3956. + };
  3957. +
  3958. + sw4_reg: ltc3676__sw4 {
  3959. + regulator-min-microvolt = <1500000>;
  3960. + regulator-max-microvolt = <1500000>;
  3961. + regulator-boot-on;
  3962. + regulator-always-on;
  3963. + };
  3964. +
  3965. + ldo2_reg: ltc3676__ldo2 {
  3966. + regulator-min-microvolt = <2500000>;
  3967. + regulator-max-microvolt = <2500000>;
  3968. + regulator-boot-on;
  3969. + regulator-always-on;
  3970. + };
  3971. +
  3972. + ldo3_reg: ltc3676__ldo3 {
  3973. + regulator-min-microvolt = <1800000>;
  3974. + regulator-max-microvolt = <1800000>;
  3975. + regulator-boot-on;
  3976. + regulator-always-on;
  3977. + };
  3978. +
  3979. + ldo4_reg: ltc3676__ldo4 {
  3980. + regulator-min-microvolt = <3000000>;
  3981. + regulator-max-microvolt = <3000000>;
  3982. + };
  3983. + };
  3984. + };
  3985. +};
  3986. +
  3987. +&i2c3 {
  3988. + clock-frequency = <100000>;
  3989. + pinctrl-names = "default";
  3990. + pinctrl-0 = <&pinctrl_i2c3>;
  3991. + status = "okay";
  3992. +
  3993. + accelerometer: fxos8700@1e {
  3994. + compatible = "fsl,fxos8700";
  3995. + reg = <0x13>;
  3996. + };
  3997. +
  3998. + codec: sgtl5000@0a {
  3999. + compatible = "fsl,sgtl5000";
  4000. + reg = <0x0a>;
  4001. + clocks = <&clks 169>;
  4002. + VDDA-supply = <&reg_1p8v>;
  4003. + VDDIO-supply = <&reg_3p3v>;
  4004. + };
  4005. +
  4006. + touchscreen: egalax_ts@04 {
  4007. + compatible = "eeti,egalax_ts";
  4008. + reg = <0x04>;
  4009. + interrupt-parent = <&gpio7>;
  4010. + interrupts = <12 2>; /* gpio7_12 active low */
  4011. + wakeup-gpios = <&gpio7 12 0>;
  4012. + };
  4013. +
  4014. + videoin: adv7180@20 {
  4015. + compatible = "adi,adv7180";
  4016. + reg = <0x20>;
  4017. + };
  4018. +};
  4019. +
  4020. +&iomuxc {
  4021. + pinctrl-names = "default";
  4022. + pinctrl-0 = <&pinctrl_hog>;
  4023. +
  4024. + imx6qdl-gw52xx {
  4025. + pinctrl_hog: hoggrp {
  4026. + fsl,pins = <
  4027. + MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x80000000 /* MEZZ_DIO0 */
  4028. + MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x80000000 /* MEZZ_DIO1 */
  4029. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  4030. + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x80000000 /* VIDDEC_PDN# */
  4031. + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* PHY Reset */
  4032. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE_RST# */
  4033. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000 /* GPS_PWDN */
  4034. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  4035. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  4036. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 /* USB_SEL_PCI */
  4037. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* TOUCH_IRQ# */
  4038. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  4039. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  4040. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  4041. + MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x80000000 /* LVDS_TCH# */
  4042. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000 /* SD3_CD# */
  4043. + MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x80000000 /* UART2_EN# */
  4044. + >;
  4045. + };
  4046. +
  4047. + pinctrl_audmux: audmuxgrp {
  4048. + fsl,pins = <
  4049. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  4050. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  4051. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  4052. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  4053. + >;
  4054. + };
  4055. +
  4056. + pinctrl_enet: enetgrp {
  4057. + fsl,pins = <
  4058. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  4059. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  4060. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  4061. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  4062. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  4063. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  4064. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  4065. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  4066. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  4067. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  4068. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  4069. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  4070. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  4071. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  4072. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  4073. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  4074. + >;
  4075. + };
  4076. +
  4077. + pinctrl_gpmi_nand: gpminandgrp {
  4078. + fsl,pins = <
  4079. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  4080. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  4081. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  4082. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  4083. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  4084. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  4085. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  4086. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  4087. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  4088. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  4089. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  4090. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  4091. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  4092. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  4093. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  4094. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  4095. + >;
  4096. + };
  4097. +
  4098. + pinctrl_i2c1: i2c1grp {
  4099. + fsl,pins = <
  4100. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  4101. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  4102. + >;
  4103. + };
  4104. +
  4105. + pinctrl_i2c2: i2c2grp {
  4106. + fsl,pins = <
  4107. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  4108. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  4109. + >;
  4110. + };
  4111. +
  4112. + pinctrl_i2c3: i2c3grp {
  4113. + fsl,pins = <
  4114. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  4115. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  4116. + >;
  4117. + };
  4118. +
  4119. + pinctrl_pwm4: pwm4grp {
  4120. + fsl,pins = <
  4121. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  4122. + >;
  4123. + };
  4124. +
  4125. + pinctrl_uart1: uart1grp {
  4126. + fsl,pins = <
  4127. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  4128. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  4129. + >;
  4130. + };
  4131. +
  4132. + pinctrl_uart2: uart2grp {
  4133. + fsl,pins = <
  4134. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  4135. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  4136. + >;
  4137. + };
  4138. +
  4139. + pinctrl_uart5: uart5grp {
  4140. + fsl,pins = <
  4141. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  4142. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  4143. + >;
  4144. + };
  4145. +
  4146. + pinctrl_usbotg: usbotggrp {
  4147. + fsl,pins = <
  4148. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  4149. + >;
  4150. + };
  4151. +
  4152. + pinctrl_usdhc3: usdhc3grp {
  4153. + fsl,pins = <
  4154. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  4155. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  4156. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  4157. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  4158. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  4159. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  4160. + >;
  4161. + };
  4162. + };
  4163. +};
  4164. +
  4165. +&ldb {
  4166. + status = "okay";
  4167. +
  4168. + lvds-channel@0 {
  4169. + fsl,data-mapping = "spwg";
  4170. + fsl,data-width = <18>;
  4171. + status = "okay";
  4172. +
  4173. + display-timings {
  4174. + native-mode = <&timing0>;
  4175. + timing0: hsd100pxn1 {
  4176. + clock-frequency = <65000000>;
  4177. + hactive = <1024>;
  4178. + vactive = <768>;
  4179. + hback-porch = <220>;
  4180. + hfront-porch = <40>;
  4181. + vback-porch = <21>;
  4182. + vfront-porch = <7>;
  4183. + hsync-len = <60>;
  4184. + vsync-len = <10>;
  4185. + };
  4186. + };
  4187. + };
  4188. +};
  4189. +
  4190. +&pcie {
  4191. + reset-gpio = <&gpio1 29 0>;
  4192. + status = "okay";
  4193. +};
  4194. +
  4195. +&pwm4 {
  4196. + pinctrl-names = "default";
  4197. + pinctrl-0 = <&pinctrl_pwm4>;
  4198. + status = "okay";
  4199. +};
  4200. +
  4201. +&ssi1 {
  4202. + fsl,mode = "i2s-slave";
  4203. + status = "okay";
  4204. +};
  4205. +
  4206. +&uart1 {
  4207. + pinctrl-names = "default";
  4208. + pinctrl-0 = <&pinctrl_uart1>;
  4209. + status = "okay";
  4210. +};
  4211. +
  4212. +&uart2 {
  4213. + pinctrl-names = "default";
  4214. + pinctrl-0 = <&pinctrl_uart2>;
  4215. + status = "okay";
  4216. +};
  4217. +
  4218. +&uart5 {
  4219. + pinctrl-names = "default";
  4220. + pinctrl-0 = <&pinctrl_uart5>;
  4221. + status = "okay";
  4222. +};
  4223. +
  4224. +&usbotg {
  4225. + vbus-supply = <&reg_usb_otg_vbus>;
  4226. + pinctrl-names = "default";
  4227. + pinctrl-0 = <&pinctrl_usbotg>;
  4228. + disable-over-current;
  4229. + status = "okay";
  4230. +};
  4231. +
  4232. +&usbh1 {
  4233. + status = "okay";
  4234. +};
  4235. +
  4236. +&usdhc3 {
  4237. + pinctrl-names = "default";
  4238. + pinctrl-0 = <&pinctrl_usdhc3>;
  4239. + cd-gpios = <&gpio7 0 0>;
  4240. + vmmc-supply = <&reg_3p3v>;
  4241. + status = "okay";
  4242. +};
  4243. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
  4244. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi 1969-12-31 18:00:00.000000000 -0600
  4245. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi 2014-12-08 00:31:51.124418001 -0600
  4246. @@ -0,0 +1,572 @@
  4247. +/*
  4248. + * Copyright 2013 Gateworks Corporation
  4249. + *
  4250. + * The code contained herein is licensed under the GNU General Public
  4251. + * License. You may obtain a copy of the GNU General Public License
  4252. + * Version 2 or later at the following locations:
  4253. + *
  4254. + * http://www.opensource.org/licenses/gpl-license.html
  4255. + * http://www.gnu.org/copyleft/gpl.html
  4256. + */
  4257. +
  4258. +/ {
  4259. + /* these are used by bootloader for disabling nodes */
  4260. + aliases {
  4261. + can0 = &can1;
  4262. + ethernet0 = &fec;
  4263. + ethernet1 = &eth1;
  4264. + led0 = &led0;
  4265. + led1 = &led1;
  4266. + led2 = &led2;
  4267. + nand = &gpmi;
  4268. + sky2 = &eth1;
  4269. + ssi0 = &ssi1;
  4270. + usb0 = &usbh1;
  4271. + usb1 = &usbotg;
  4272. + usdhc2 = &usdhc3;
  4273. + };
  4274. +
  4275. + chosen {
  4276. + bootargs = "console=ttymxc1,115200";
  4277. + };
  4278. +
  4279. + backlight {
  4280. + compatible = "pwm-backlight";
  4281. + pwms = <&pwm4 0 5000000>;
  4282. + brightness-levels = <0 4 8 16 32 64 128 255>;
  4283. + default-brightness-level = <7>;
  4284. + };
  4285. +
  4286. + leds {
  4287. + compatible = "gpio-leds";
  4288. +
  4289. + led0: user1 {
  4290. + label = "user1";
  4291. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  4292. + default-state = "on";
  4293. + linux,default-trigger = "heartbeat";
  4294. + };
  4295. +
  4296. + led1: user2 {
  4297. + label = "user2";
  4298. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  4299. + default-state = "off";
  4300. + };
  4301. +
  4302. + led2: user3 {
  4303. + label = "user3";
  4304. + gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
  4305. + default-state = "off";
  4306. + };
  4307. + };
  4308. +
  4309. + memory {
  4310. + reg = <0x10000000 0x40000000>;
  4311. + };
  4312. +
  4313. + pps {
  4314. + compatible = "pps-gpio";
  4315. + gpios = <&gpio1 26 0>;
  4316. + status = "okay";
  4317. + };
  4318. +
  4319. + regulators {
  4320. + compatible = "simple-bus";
  4321. + #address-cells = <1>;
  4322. + #size-cells = <0>;
  4323. +
  4324. + reg_1p0v: regulator@0 {
  4325. + compatible = "regulator-fixed";
  4326. + reg = <0>;
  4327. + regulator-name = "1P0V";
  4328. + regulator-min-microvolt = <1000000>;
  4329. + regulator-max-microvolt = <1000000>;
  4330. + regulator-always-on;
  4331. + };
  4332. +
  4333. + /* remove when pmic 1p8 regulator available */
  4334. + reg_1p8v: regulator@1 {
  4335. + compatible = "regulator-fixed";
  4336. + reg = <1>;
  4337. + regulator-name = "1P8V";
  4338. + regulator-min-microvolt = <1800000>;
  4339. + regulator-max-microvolt = <1800000>;
  4340. + regulator-always-on;
  4341. + };
  4342. +
  4343. + reg_3p3v: regulator@2 {
  4344. + compatible = "regulator-fixed";
  4345. + reg = <2>;
  4346. + regulator-name = "3P3V";
  4347. + regulator-min-microvolt = <3300000>;
  4348. + regulator-max-microvolt = <3300000>;
  4349. + regulator-always-on;
  4350. + };
  4351. +
  4352. + reg_usb_h1_vbus: regulator@3 {
  4353. + compatible = "regulator-fixed";
  4354. + reg = <3>;
  4355. + regulator-name = "usb_h1_vbus";
  4356. + regulator-min-microvolt = <5000000>;
  4357. + regulator-max-microvolt = <5000000>;
  4358. + regulator-always-on;
  4359. + };
  4360. +
  4361. + reg_usb_otg_vbus: regulator@4 {
  4362. + compatible = "regulator-fixed";
  4363. + reg = <4>;
  4364. + regulator-name = "usb_otg_vbus";
  4365. + regulator-min-microvolt = <5000000>;
  4366. + regulator-max-microvolt = <5000000>;
  4367. + gpio = <&gpio3 22 0>;
  4368. + enable-active-high;
  4369. + };
  4370. + };
  4371. +
  4372. + sound {
  4373. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  4374. + "fsl,imx-audio-sgtl5000";
  4375. + model = "imx6q-sabrelite-sgtl5000";
  4376. + ssi-controller = <&ssi1>;
  4377. + audio-codec = <&codec>;
  4378. + audio-routing =
  4379. + "MIC_IN", "Mic Jack",
  4380. + "Mic Jack", "Mic Bias",
  4381. + "Headphone Jack", "HP_OUT";
  4382. + mux-int-port = <1>;
  4383. + mux-ext-port = <4>;
  4384. + };
  4385. +};
  4386. +
  4387. +&audmux {
  4388. + pinctrl-names = "default";
  4389. + pinctrl-0 = <&pinctrl_audmux>;
  4390. + status = "okay";
  4391. +};
  4392. +
  4393. +&can1 {
  4394. + pinctrl-names = "default";
  4395. + pinctrl-0 = <&pinctrl_flexcan1>;
  4396. + status = "okay";
  4397. +};
  4398. +
  4399. +&fec {
  4400. + pinctrl-names = "default";
  4401. + pinctrl-0 = <&pinctrl_enet>;
  4402. + phy-mode = "rgmii";
  4403. + phy-reset-gpios = <&gpio1 30 0>;
  4404. + status = "okay";
  4405. +};
  4406. +
  4407. +&gpmi {
  4408. + pinctrl-names = "default";
  4409. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  4410. + status = "okay";
  4411. +};
  4412. +
  4413. +&i2c1 {
  4414. + clock-frequency = <100000>;
  4415. + pinctrl-names = "default";
  4416. + pinctrl-0 = <&pinctrl_i2c1>;
  4417. + status = "okay";
  4418. +
  4419. + eeprom1: eeprom@50 {
  4420. + compatible = "atmel,24c02";
  4421. + reg = <0x50>;
  4422. + pagesize = <16>;
  4423. + };
  4424. +
  4425. + eeprom2: eeprom@51 {
  4426. + compatible = "atmel,24c02";
  4427. + reg = <0x51>;
  4428. + pagesize = <16>;
  4429. + };
  4430. +
  4431. + eeprom3: eeprom@52 {
  4432. + compatible = "atmel,24c02";
  4433. + reg = <0x52>;
  4434. + pagesize = <16>;
  4435. + };
  4436. +
  4437. + eeprom4: eeprom@53 {
  4438. + compatible = "atmel,24c02";
  4439. + reg = <0x53>;
  4440. + pagesize = <16>;
  4441. + };
  4442. +
  4443. + gpio: pca9555@23 {
  4444. + compatible = "nxp,pca9555";
  4445. + reg = <0x23>;
  4446. + gpio-controller;
  4447. + #gpio-cells = <2>;
  4448. + };
  4449. +
  4450. + hwmon: gsc@29 {
  4451. + compatible = "gw,gsp";
  4452. + reg = <0x29>;
  4453. + };
  4454. +
  4455. + rtc: ds1672@68 {
  4456. + compatible = "dallas,ds1672";
  4457. + reg = <0x68>;
  4458. + };
  4459. +};
  4460. +
  4461. +&i2c2 {
  4462. + clock-frequency = <100000>;
  4463. + pinctrl-names = "default";
  4464. + pinctrl-0 = <&pinctrl_i2c2>;
  4465. + status = "okay";
  4466. +
  4467. + pciclkgen: si53156@6b {
  4468. + compatible = "sil,si53156";
  4469. + reg = <0x6b>;
  4470. + };
  4471. +
  4472. + pciswitch: pex8606@3f {
  4473. + compatible = "plx,pex8606";
  4474. + reg = <0x3f>;
  4475. + };
  4476. +
  4477. + pmic: ltc3676@3c {
  4478. + compatible = "ltc,ltc3676";
  4479. + reg = <0x3c>;
  4480. +
  4481. + regulators {
  4482. + /* VDD_SOC */
  4483. + sw1_reg: ltc3676__sw1 {
  4484. + regulator-min-microvolt = <1175000>;
  4485. + regulator-max-microvolt = <1175000>;
  4486. + regulator-boot-on;
  4487. + regulator-always-on;
  4488. + };
  4489. +
  4490. + /* VDD_1P8 */
  4491. + sw2_reg: ltc3676__sw2 {
  4492. + regulator-min-microvolt = <1800000>;
  4493. + regulator-max-microvolt = <1800000>;
  4494. + regulator-boot-on;
  4495. + regulator-always-on;
  4496. + };
  4497. +
  4498. + /* VDD_ARM */
  4499. + sw3_reg: ltc3676__sw3 {
  4500. + regulator-min-microvolt = <1175000>;
  4501. + regulator-max-microvolt = <1175000>;
  4502. + regulator-boot-on;
  4503. + regulator-always-on;
  4504. + };
  4505. +
  4506. + /* VDD_DDR */
  4507. + sw4_reg: ltc3676__sw4 {
  4508. + regulator-min-microvolt = <1500000>;
  4509. + regulator-max-microvolt = <1500000>;
  4510. + regulator-boot-on;
  4511. + regulator-always-on;
  4512. + };
  4513. +
  4514. + /* VDD_2P5 */
  4515. + ldo2_reg: ltc3676__ldo2 {
  4516. + regulator-min-microvolt = <2500000>;
  4517. + regulator-max-microvolt = <2500000>;
  4518. + regulator-boot-on;
  4519. + regulator-always-on;
  4520. + };
  4521. +
  4522. + /* VDD_1P8 */
  4523. + ldo3_reg: ltc3676__ldo3 {
  4524. + regulator-min-microvolt = <1800000>;
  4525. + regulator-max-microvolt = <1800000>;
  4526. + regulator-boot-on;
  4527. + regulator-always-on;
  4528. + };
  4529. +
  4530. + /* VDD_HIGH */
  4531. + ldo4_reg: ltc3676__ldo4 {
  4532. + regulator-min-microvolt = <3000000>;
  4533. + regulator-max-microvolt = <3000000>;
  4534. + };
  4535. + };
  4536. + };
  4537. +};
  4538. +
  4539. +&i2c3 {
  4540. + clock-frequency = <100000>;
  4541. + pinctrl-names = "default";
  4542. + pinctrl-0 = <&pinctrl_i2c3>;
  4543. + status = "okay";
  4544. +
  4545. + accelerometer: fxos8700@1e {
  4546. + compatible = "fsl,fxos8700";
  4547. + reg = <0x1e>;
  4548. + };
  4549. +
  4550. + codec: sgtl5000@0a {
  4551. + compatible = "fsl,sgtl5000";
  4552. + reg = <0x0a>;
  4553. + clocks = <&clks 201>;
  4554. + VDDA-supply = <&reg_1p8v>;
  4555. + VDDIO-supply = <&reg_3p3v>;
  4556. + };
  4557. +
  4558. + hdmiin: adv7611@4c {
  4559. + compatible = "adi,adv7611";
  4560. + reg = <0x4c>;
  4561. + };
  4562. +
  4563. + touchscreen: egalax_ts@04 {
  4564. + compatible = "eeti,egalax_ts";
  4565. + reg = <0x04>;
  4566. + interrupt-parent = <&gpio1>;
  4567. + interrupts = <11 2>; /* gpio1_11 active low */
  4568. + wakeup-gpios = <&gpio1 11 0>;
  4569. + };
  4570. +
  4571. + videoout: adv7393@2a {
  4572. + compatible = "adi,adv7393";
  4573. + reg = <0x2a>;
  4574. + };
  4575. +
  4576. + videoin: adv7180@20 {
  4577. + compatible = "adi,adv7180";
  4578. + reg = <0x20>;
  4579. + };
  4580. +};
  4581. +
  4582. +&iomuxc {
  4583. + pinctrl-names = "default";
  4584. + pinctrl-0 = <&pinctrl_hog>;
  4585. +
  4586. + imx6qdl-gw53xx {
  4587. + pinctrl_hog: hoggrp {
  4588. + fsl,pins = <
  4589. + MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x80000000 /* PCIE6EXP_DIO0 */
  4590. + MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x80000000 /* PCIE6EXP_DIO1 */
  4591. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  4592. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000 /* GPS_SHDN */
  4593. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  4594. + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
  4595. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE RST */
  4596. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  4597. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 /* CAN_STBY */
  4598. + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x80000000 /* PMIC_IRQ# */
  4599. + MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x80000000 /* HUB_RST# */
  4600. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* PCIE_WDIS# */
  4601. + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x80000000 /* ACCEL_IRQ# */
  4602. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  4603. + MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x80000000 /* USBOTG_OC# */
  4604. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  4605. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  4606. + MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x80000000 /* TOUCH_IRQ# */
  4607. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000 /* SD3_DET# */
  4608. + >;
  4609. + };
  4610. +
  4611. + pinctrl_audmux: audmuxgrp {
  4612. + fsl,pins = <
  4613. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  4614. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  4615. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  4616. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  4617. + >;
  4618. + };
  4619. +
  4620. + pinctrl_enet: enetgrp {
  4621. + fsl,pins = <
  4622. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  4623. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  4624. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  4625. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  4626. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  4627. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  4628. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  4629. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  4630. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  4631. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  4632. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  4633. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  4634. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  4635. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  4636. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  4637. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  4638. + >;
  4639. + };
  4640. +
  4641. + pinctrl_flexcan1: flexcan1grp {
  4642. + fsl,pins = <
  4643. + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  4644. + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x80000000
  4645. + >;
  4646. + };
  4647. +
  4648. + pinctrl_gpmi_nand: gpminandgrp {
  4649. + fsl,pins = <
  4650. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  4651. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  4652. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  4653. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  4654. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  4655. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  4656. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  4657. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  4658. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  4659. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  4660. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  4661. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  4662. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  4663. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  4664. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  4665. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  4666. + >;
  4667. + };
  4668. +
  4669. + pinctrl_i2c1: i2c1grp {
  4670. + fsl,pins = <
  4671. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  4672. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  4673. + >;
  4674. + };
  4675. +
  4676. + pinctrl_i2c2: i2c2grp {
  4677. + fsl,pins = <
  4678. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  4679. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  4680. + >;
  4681. + };
  4682. +
  4683. + pinctrl_i2c3: i2c3grp {
  4684. + fsl,pins = <
  4685. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  4686. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  4687. + >;
  4688. + };
  4689. +
  4690. + pinctrl_pwm4: pwm4grp {
  4691. + fsl,pins = <
  4692. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  4693. + >;
  4694. + };
  4695. +
  4696. + pinctrl_uart1: uart1grp {
  4697. + fsl,pins = <
  4698. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  4699. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  4700. + >;
  4701. + };
  4702. +
  4703. + pinctrl_uart2: uart2grp {
  4704. + fsl,pins = <
  4705. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  4706. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  4707. + >;
  4708. + };
  4709. +
  4710. + pinctrl_uart5: uart5grp {
  4711. + fsl,pins = <
  4712. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  4713. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  4714. + >;
  4715. + };
  4716. +
  4717. + pinctrl_usbotg: usbotggrp {
  4718. + fsl,pins = <
  4719. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  4720. + >;
  4721. + };
  4722. +
  4723. + pinctrl_usdhc3: usdhc3grp {
  4724. + fsl,pins = <
  4725. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  4726. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  4727. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  4728. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  4729. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  4730. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  4731. + >;
  4732. + };
  4733. + };
  4734. +};
  4735. +
  4736. +&ldb {
  4737. + status = "okay";
  4738. +
  4739. + lvds-channel@1 {
  4740. + fsl,data-mapping = "spwg";
  4741. + fsl,data-width = <18>;
  4742. + status = "okay";
  4743. +
  4744. + display-timings {
  4745. + native-mode = <&timing0>;
  4746. + timing0: hsd100pxn1 {
  4747. + clock-frequency = <65000000>;
  4748. + hactive = <1024>;
  4749. + vactive = <768>;
  4750. + hback-porch = <220>;
  4751. + hfront-porch = <40>;
  4752. + vback-porch = <21>;
  4753. + vfront-porch = <7>;
  4754. + hsync-len = <60>;
  4755. + vsync-len = <10>;
  4756. + };
  4757. + };
  4758. + };
  4759. +};
  4760. +
  4761. +&pcie {
  4762. + reset-gpio = <&gpio1 29 0>;
  4763. + status = "okay";
  4764. +
  4765. + eth1: sky2@8 { /* MAC/PHY on bus 8 */
  4766. + compatible = "marvell,sky2";
  4767. + };
  4768. +};
  4769. +
  4770. +&pwm4 {
  4771. + pinctrl-names = "default";
  4772. + pinctrl-0 = <&pinctrl_pwm4>;
  4773. + status = "okay";
  4774. +};
  4775. +
  4776. +&ssi1 {
  4777. + fsl,mode = "i2s-slave";
  4778. + status = "okay";
  4779. +};
  4780. +
  4781. +&uart1 {
  4782. + pinctrl-names = "default";
  4783. + pinctrl-0 = <&pinctrl_uart1>;
  4784. + status = "okay";
  4785. +};
  4786. +
  4787. +&uart2 {
  4788. + pinctrl-names = "default";
  4789. + pinctrl-0 = <&pinctrl_uart2>;
  4790. + status = "okay";
  4791. +};
  4792. +
  4793. +&uart5 {
  4794. + pinctrl-names = "default";
  4795. + pinctrl-0 = <&pinctrl_uart5>;
  4796. + status = "okay";
  4797. +};
  4798. +
  4799. +&usbotg {
  4800. + vbus-supply = <&reg_usb_otg_vbus>;
  4801. + pinctrl-names = "default";
  4802. + pinctrl-0 = <&pinctrl_usbotg>;
  4803. + disable-over-current;
  4804. + status = "okay";
  4805. +};
  4806. +
  4807. +&usbh1 {
  4808. + vbus-supply = <&reg_usb_h1_vbus>;
  4809. + status = "okay";
  4810. +};
  4811. +
  4812. +&usdhc3 {
  4813. + pinctrl-names = "default";
  4814. + pinctrl-0 = <&pinctrl_usdhc3>;
  4815. + cd-gpios = <&gpio7 0 0>;
  4816. + vmmc-supply = <&reg_3p3v>;
  4817. + status = "okay";
  4818. +};
  4819. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
  4820. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi 1969-12-31 18:00:00.000000000 -0600
  4821. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi 2014-12-08 00:31:51.124418001 -0600
  4822. @@ -0,0 +1,599 @@
  4823. +/*
  4824. + * Copyright 2013 Gateworks Corporation
  4825. + *
  4826. + * The code contained herein is licensed under the GNU General Public
  4827. + * License. You may obtain a copy of the GNU General Public License
  4828. + * Version 2 or later at the following locations:
  4829. + *
  4830. + * http://www.opensource.org/licenses/gpl-license.html
  4831. + * http://www.gnu.org/copyleft/gpl.html
  4832. + */
  4833. +
  4834. +/ {
  4835. + /* these are used by bootloader for disabling nodes */
  4836. + aliases {
  4837. + can0 = &can1;
  4838. + ethernet0 = &fec;
  4839. + ethernet1 = &eth1;
  4840. + led0 = &led0;
  4841. + led1 = &led1;
  4842. + led2 = &led2;
  4843. + nand = &gpmi;
  4844. + sky2 = &eth1;
  4845. + ssi0 = &ssi1;
  4846. + usb0 = &usbh1;
  4847. + usb1 = &usbotg;
  4848. + usdhc2 = &usdhc3;
  4849. + };
  4850. +
  4851. + chosen {
  4852. + bootargs = "console=ttymxc1,115200";
  4853. + };
  4854. +
  4855. + backlight {
  4856. + compatible = "pwm-backlight";
  4857. + pwms = <&pwm4 0 5000000>;
  4858. + brightness-levels = <0 4 8 16 32 64 128 255>;
  4859. + default-brightness-level = <7>;
  4860. + };
  4861. +
  4862. + leds {
  4863. + compatible = "gpio-leds";
  4864. +
  4865. + led0: user1 {
  4866. + label = "user1";
  4867. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  4868. + default-state = "on";
  4869. + linux,default-trigger = "heartbeat";
  4870. + };
  4871. +
  4872. + led1: user2 {
  4873. + label = "user2";
  4874. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  4875. + default-state = "off";
  4876. + };
  4877. +
  4878. + led2: user3 {
  4879. + label = "user3";
  4880. + gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
  4881. + default-state = "off";
  4882. + };
  4883. + };
  4884. +
  4885. + memory {
  4886. + reg = <0x10000000 0x40000000>;
  4887. + };
  4888. +
  4889. + pps {
  4890. + compatible = "pps-gpio";
  4891. + gpios = <&gpio1 26 0>;
  4892. + status = "okay";
  4893. + };
  4894. +
  4895. + regulators {
  4896. + compatible = "simple-bus";
  4897. + #address-cells = <1>;
  4898. + #size-cells = <0>;
  4899. +
  4900. + reg_1p0v: regulator@0 {
  4901. + compatible = "regulator-fixed";
  4902. + reg = <0>;
  4903. + regulator-name = "1P0V";
  4904. + regulator-min-microvolt = <1000000>;
  4905. + regulator-max-microvolt = <1000000>;
  4906. + regulator-always-on;
  4907. + };
  4908. +
  4909. + reg_3p3v: regulator@1 {
  4910. + compatible = "regulator-fixed";
  4911. + reg = <1>;
  4912. + regulator-name = "3P3V";
  4913. + regulator-min-microvolt = <3300000>;
  4914. + regulator-max-microvolt = <3300000>;
  4915. + regulator-always-on;
  4916. + };
  4917. +
  4918. + reg_usb_h1_vbus: regulator@2 {
  4919. + compatible = "regulator-fixed";
  4920. + reg = <2>;
  4921. + regulator-name = "usb_h1_vbus";
  4922. + regulator-min-microvolt = <5000000>;
  4923. + regulator-max-microvolt = <5000000>;
  4924. + regulator-always-on;
  4925. + };
  4926. +
  4927. + reg_usb_otg_vbus: regulator@3 {
  4928. + compatible = "regulator-fixed";
  4929. + reg = <3>;
  4930. + regulator-name = "usb_otg_vbus";
  4931. + regulator-min-microvolt = <5000000>;
  4932. + regulator-max-microvolt = <5000000>;
  4933. + gpio = <&gpio3 22 0>;
  4934. + enable-active-high;
  4935. + };
  4936. + };
  4937. +
  4938. + sound {
  4939. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  4940. + "fsl,imx-audio-sgtl5000";
  4941. + model = "imx6q-sabrelite-sgtl5000";
  4942. + ssi-controller = <&ssi1>;
  4943. + audio-codec = <&codec>;
  4944. + audio-routing =
  4945. + "MIC_IN", "Mic Jack",
  4946. + "Mic Jack", "Mic Bias",
  4947. + "Headphone Jack", "HP_OUT";
  4948. + mux-int-port = <1>;
  4949. + mux-ext-port = <4>;
  4950. + };
  4951. +};
  4952. +
  4953. +&audmux {
  4954. + pinctrl-names = "default";
  4955. + pinctrl-0 = <&pinctrl_audmux>; /* AUD4<->sgtl5000 */
  4956. + status = "okay";
  4957. +};
  4958. +
  4959. +&can1 {
  4960. + pinctrl-names = "default";
  4961. + pinctrl-0 = <&pinctrl_flexcan1>;
  4962. + status = "okay";
  4963. +};
  4964. +
  4965. +&fec {
  4966. + pinctrl-names = "default";
  4967. + pinctrl-0 = <&pinctrl_enet>;
  4968. + phy-mode = "rgmii";
  4969. + phy-reset-gpios = <&gpio1 30 0>;
  4970. + status = "okay";
  4971. +};
  4972. +
  4973. +&gpmi {
  4974. + pinctrl-names = "default";
  4975. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  4976. + status = "okay";
  4977. +};
  4978. +
  4979. +&i2c1 {
  4980. + clock-frequency = <100000>;
  4981. + pinctrl-names = "default";
  4982. + pinctrl-0 = <&pinctrl_i2c1>;
  4983. + status = "okay";
  4984. +
  4985. + eeprom1: eeprom@50 {
  4986. + compatible = "atmel,24c02";
  4987. + reg = <0x50>;
  4988. + pagesize = <16>;
  4989. + };
  4990. +
  4991. + eeprom2: eeprom@51 {
  4992. + compatible = "atmel,24c02";
  4993. + reg = <0x51>;
  4994. + pagesize = <16>;
  4995. + };
  4996. +
  4997. + eeprom3: eeprom@52 {
  4998. + compatible = "atmel,24c02";
  4999. + reg = <0x52>;
  5000. + pagesize = <16>;
  5001. + };
  5002. +
  5003. + eeprom4: eeprom@53 {
  5004. + compatible = "atmel,24c02";
  5005. + reg = <0x53>;
  5006. + pagesize = <16>;
  5007. + };
  5008. +
  5009. + gpio: pca9555@23 {
  5010. + compatible = "nxp,pca9555";
  5011. + reg = <0x23>;
  5012. + gpio-controller;
  5013. + #gpio-cells = <2>;
  5014. + };
  5015. +
  5016. + hwmon: gsc@29 {
  5017. + compatible = "gw,gsp";
  5018. + reg = <0x29>;
  5019. + };
  5020. +
  5021. + rtc: ds1672@68 {
  5022. + compatible = "dallas,ds1672";
  5023. + reg = <0x68>;
  5024. + };
  5025. +};
  5026. +
  5027. +&i2c2 {
  5028. + clock-frequency = <100000>;
  5029. + pinctrl-names = "default";
  5030. + pinctrl-0 = <&pinctrl_i2c2>;
  5031. + status = "okay";
  5032. +
  5033. + pmic: pfuze100@08 {
  5034. + compatible = "fsl,pfuze100";
  5035. + reg = <0x08>;
  5036. +
  5037. + regulators {
  5038. + sw1a_reg: sw1ab {
  5039. + regulator-min-microvolt = <300000>;
  5040. + regulator-max-microvolt = <1875000>;
  5041. + regulator-boot-on;
  5042. + regulator-always-on;
  5043. + regulator-ramp-delay = <6250>;
  5044. + };
  5045. +
  5046. + sw1c_reg: sw1c {
  5047. + regulator-min-microvolt = <300000>;
  5048. + regulator-max-microvolt = <1875000>;
  5049. + regulator-boot-on;
  5050. + regulator-always-on;
  5051. + regulator-ramp-delay = <6250>;
  5052. + };
  5053. +
  5054. + sw2_reg: sw2 {
  5055. + regulator-min-microvolt = <800000>;
  5056. + regulator-max-microvolt = <3950000>;
  5057. + regulator-boot-on;
  5058. + regulator-always-on;
  5059. + };
  5060. +
  5061. + sw3a_reg: sw3a {
  5062. + regulator-min-microvolt = <400000>;
  5063. + regulator-max-microvolt = <1975000>;
  5064. + regulator-boot-on;
  5065. + regulator-always-on;
  5066. + };
  5067. +
  5068. + sw3b_reg: sw3b {
  5069. + regulator-min-microvolt = <400000>;
  5070. + regulator-max-microvolt = <1975000>;
  5071. + regulator-boot-on;
  5072. + regulator-always-on;
  5073. + };
  5074. +
  5075. + sw4_reg: sw4 {
  5076. + regulator-min-microvolt = <800000>;
  5077. + regulator-max-microvolt = <3300000>;
  5078. + };
  5079. +
  5080. + swbst_reg: swbst {
  5081. + regulator-min-microvolt = <5000000>;
  5082. + regulator-max-microvolt = <5150000>;
  5083. + };
  5084. +
  5085. + snvs_reg: vsnvs {
  5086. + regulator-min-microvolt = <1000000>;
  5087. + regulator-max-microvolt = <3000000>;
  5088. + regulator-boot-on;
  5089. + regulator-always-on;
  5090. + };
  5091. +
  5092. + vref_reg: vrefddr {
  5093. + regulator-boot-on;
  5094. + regulator-always-on;
  5095. + };
  5096. +
  5097. + vgen1_reg: vgen1 {
  5098. + regulator-min-microvolt = <800000>;
  5099. + regulator-max-microvolt = <1550000>;
  5100. + };
  5101. +
  5102. + vgen2_reg: vgen2 {
  5103. + regulator-min-microvolt = <800000>;
  5104. + regulator-max-microvolt = <1550000>;
  5105. + };
  5106. +
  5107. + vgen3_reg: vgen3 {
  5108. + regulator-min-microvolt = <1800000>;
  5109. + regulator-max-microvolt = <3300000>;
  5110. + };
  5111. +
  5112. + vgen4_reg: vgen4 {
  5113. + regulator-min-microvolt = <1800000>;
  5114. + regulator-max-microvolt = <3300000>;
  5115. + regulator-always-on;
  5116. + };
  5117. +
  5118. + vgen5_reg: vgen5 {
  5119. + regulator-min-microvolt = <1800000>;
  5120. + regulator-max-microvolt = <3300000>;
  5121. + regulator-always-on;
  5122. + };
  5123. +
  5124. + vgen6_reg: vgen6 {
  5125. + regulator-min-microvolt = <1800000>;
  5126. + regulator-max-microvolt = <3300000>;
  5127. + regulator-always-on;
  5128. + };
  5129. + };
  5130. + };
  5131. +
  5132. + pciswitch: pex8609@3f {
  5133. + compatible = "plx,pex8609";
  5134. + reg = <0x3f>;
  5135. + };
  5136. +
  5137. + pciclkgen: si52147@6b {
  5138. + compatible = "sil,si52147";
  5139. + reg = <0x6b>;
  5140. + };
  5141. +};
  5142. +
  5143. +&i2c3 {
  5144. + clock-frequency = <100000>;
  5145. + pinctrl-names = "default";
  5146. + pinctrl-0 = <&pinctrl_i2c3>;
  5147. + status = "okay";
  5148. +
  5149. + accelerometer: fxos8700@1e {
  5150. + compatible = "fsl,fxos8700";
  5151. + reg = <0x1e>;
  5152. + };
  5153. +
  5154. + codec: sgtl5000@0a {
  5155. + compatible = "fsl,sgtl5000";
  5156. + reg = <0x0a>;
  5157. + clocks = <&clks 201>;
  5158. + VDDA-supply = <&sw4_reg>;
  5159. + VDDIO-supply = <&reg_3p3v>;
  5160. + };
  5161. +
  5162. + hdmiin: adv7611@4c {
  5163. + compatible = "adi,adv7611";
  5164. + reg = <0x4c>;
  5165. + };
  5166. +
  5167. + touchscreen: egalax_ts@04 {
  5168. + compatible = "eeti,egalax_ts";
  5169. + reg = <0x04>;
  5170. + interrupt-parent = <&gpio7>;
  5171. + interrupts = <12 2>; /* gpio7_12 active low */
  5172. + wakeup-gpios = <&gpio7 12 0>;
  5173. + };
  5174. +
  5175. + videoout: adv7393@2a {
  5176. + compatible = "adi,adv7393";
  5177. + reg = <0x2a>;
  5178. + };
  5179. +
  5180. + videoin: adv7180@20 {
  5181. + compatible = "adi,adv7180";
  5182. + reg = <0x20>;
  5183. + };
  5184. +};
  5185. +
  5186. +&iomuxc {
  5187. + pinctrl-names = "default";
  5188. + pinctrl-0 = <&pinctrl_hog>;
  5189. +
  5190. + imx6qdl-gw54xx {
  5191. + pinctrl_hog: hoggrp {
  5192. + fsl,pins = <
  5193. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  5194. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000 /* SPINOR_CS0# */
  5195. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  5196. + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
  5197. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE RST */
  5198. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  5199. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 /* CAN_STBY */
  5200. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* TOUCH_IRQ# */
  5201. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  5202. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  5203. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  5204. + MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x80000000 /* USBHUB_RST# */
  5205. + MX6QDL_PAD_SD1_DAT3__GPIO1_IO21 0x80000000 /* MIPI_DIO */
  5206. + >;
  5207. + };
  5208. +
  5209. + pinctrl_audmux: audmuxgrp {
  5210. + fsl,pins = <
  5211. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  5212. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  5213. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  5214. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  5215. + >;
  5216. + };
  5217. +
  5218. + pinctrl_enet: enetgrp {
  5219. + fsl,pins = <
  5220. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  5221. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  5222. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  5223. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  5224. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  5225. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  5226. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  5227. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  5228. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  5229. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  5230. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  5231. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  5232. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  5233. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  5234. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  5235. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  5236. + >;
  5237. + };
  5238. +
  5239. + pinctrl_flexcan1: flexcan1grp {
  5240. + fsl,pins = <
  5241. + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  5242. + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x80000000
  5243. + >;
  5244. + };
  5245. +
  5246. + pinctrl_gpmi_nand: gpminandgrp {
  5247. + fsl,pins = <
  5248. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  5249. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  5250. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  5251. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  5252. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  5253. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  5254. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  5255. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  5256. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  5257. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  5258. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  5259. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  5260. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  5261. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  5262. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  5263. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  5264. + >;
  5265. + };
  5266. +
  5267. + pinctrl_i2c1: i2c1grp {
  5268. + fsl,pins = <
  5269. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  5270. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  5271. + >;
  5272. + };
  5273. +
  5274. + pinctrl_i2c2: i2c2grp {
  5275. + fsl,pins = <
  5276. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  5277. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  5278. + >;
  5279. + };
  5280. +
  5281. + pinctrl_i2c3: i2c3grp {
  5282. + fsl,pins = <
  5283. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  5284. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  5285. + >;
  5286. + };
  5287. +
  5288. + pinctrl_pwm4: pwm4grp {
  5289. + fsl,pins = <
  5290. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  5291. + >;
  5292. + };
  5293. +
  5294. + pinctrl_uart1: uart1grp {
  5295. + fsl,pins = <
  5296. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  5297. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  5298. + >;
  5299. + };
  5300. +
  5301. + pinctrl_uart2: uart2grp {
  5302. + fsl,pins = <
  5303. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  5304. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  5305. + >;
  5306. + };
  5307. +
  5308. + pinctrl_uart5: uart5grp {
  5309. + fsl,pins = <
  5310. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  5311. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  5312. + >;
  5313. + };
  5314. +
  5315. + pinctrl_usbotg: usbotggrp {
  5316. + fsl,pins = <
  5317. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  5318. + >;
  5319. + };
  5320. +
  5321. + pinctrl_usdhc3: usdhc3grp {
  5322. + fsl,pins = <
  5323. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  5324. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  5325. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  5326. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  5327. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  5328. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  5329. + >;
  5330. + };
  5331. + };
  5332. +};
  5333. +
  5334. +&ldb {
  5335. + status = "okay";
  5336. +
  5337. + lvds-channel@1 {
  5338. + fsl,data-mapping = "spwg";
  5339. + fsl,data-width = <18>;
  5340. + status = "okay";
  5341. +
  5342. + display-timings {
  5343. + native-mode = <&timing0>;
  5344. + timing0: hsd100pxn1 {
  5345. + clock-frequency = <65000000>;
  5346. + hactive = <1024>;
  5347. + vactive = <768>;
  5348. + hback-porch = <220>;
  5349. + hfront-porch = <40>;
  5350. + vback-porch = <21>;
  5351. + vfront-porch = <7>;
  5352. + hsync-len = <60>;
  5353. + vsync-len = <10>;
  5354. + };
  5355. + };
  5356. + };
  5357. +};
  5358. +
  5359. +&pcie {
  5360. + reset-gpio = <&gpio1 29 0>;
  5361. + status = "okay";
  5362. +
  5363. + eth1: sky2@8 { /* MAC/PHY on bus 8 */
  5364. + compatible = "marvell,sky2";
  5365. + };
  5366. +};
  5367. +
  5368. +&pwm4 {
  5369. + pinctrl-names = "default";
  5370. + pinctrl-0 = <&pinctrl_pwm4>;
  5371. + status = "okay";
  5372. +};
  5373. +
  5374. +&ssi1 {
  5375. + fsl,mode = "i2s-slave";
  5376. + status = "okay";
  5377. +};
  5378. +
  5379. +&ssi2 {
  5380. + fsl,mode = "i2s-slave";
  5381. + status = "okay";
  5382. +};
  5383. +
  5384. +&uart1 {
  5385. + pinctrl-names = "default";
  5386. + pinctrl-0 = <&pinctrl_uart1>;
  5387. + status = "okay";
  5388. +};
  5389. +
  5390. +&uart2 {
  5391. + pinctrl-names = "default";
  5392. + pinctrl-0 = <&pinctrl_uart2>;
  5393. + status = "okay";
  5394. +};
  5395. +
  5396. +&uart5 {
  5397. + pinctrl-names = "default";
  5398. + pinctrl-0 = <&pinctrl_uart5>;
  5399. + status = "okay";
  5400. +};
  5401. +
  5402. +&usbotg {
  5403. + vbus-supply = <&reg_usb_otg_vbus>;
  5404. + pinctrl-names = "default";
  5405. + pinctrl-0 = <&pinctrl_usbotg>;
  5406. + disable-over-current;
  5407. + status = "okay";
  5408. +};
  5409. +
  5410. +&usbh1 {
  5411. + vbus-supply = <&reg_usb_h1_vbus>;
  5412. + status = "okay";
  5413. +};
  5414. +
  5415. +&usdhc3 {
  5416. + pinctrl-names = "default";
  5417. + pinctrl-0 = <&pinctrl_usdhc3>;
  5418. + cd-gpios = <&gpio7 0 0>;
  5419. + vmmc-supply = <&reg_3p3v>;
  5420. + status = "okay";
  5421. +};
  5422. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi
  5423. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi 1969-12-31 18:00:00.000000000 -0600
  5424. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi 2014-12-08 00:31:51.124418001 -0600
  5425. @@ -0,0 +1,367 @@
  5426. +/*
  5427. + * Copyright (C) 2013,2014 Russell King
  5428. + */
  5429. +#include "imx6qdl-microsom.dtsi"
  5430. +#include "imx6qdl-microsom-ar8035.dtsi"
  5431. +
  5432. +/ {
  5433. + chosen {
  5434. + bootargs = "quiet console=ttymxc0,115200 root=/dev/mmcblk0p2 rw";
  5435. + };
  5436. +
  5437. + aliases {
  5438. + mxcfb0 = &mxcfb1;
  5439. + };
  5440. +
  5441. + ir_recv: ir-receiver {
  5442. + compatible = "gpio-ir-receiver";
  5443. + gpios = <&gpio3 5 1>;
  5444. + pinctrl-names = "default";
  5445. + pinctrl-0 = <&pinctrl_hummingboard_gpio3_5>;
  5446. + linux,rc-map-name = "rc-rc6-mce";
  5447. + };
  5448. +
  5449. + regulators {
  5450. + compatible = "simple-bus";
  5451. +
  5452. + reg_3p3v: 3p3v {
  5453. + compatible = "regulator-fixed";
  5454. + regulator-name = "3P3V";
  5455. + regulator-min-microvolt = <3300000>;
  5456. + regulator-max-microvolt = <3300000>;
  5457. + regulator-always-on;
  5458. + };
  5459. +
  5460. + reg_usbh1_vbus: usb-h1-vbus {
  5461. + compatible = "regulator-fixed";
  5462. + enable-active-high;
  5463. + gpio = <&gpio1 0 0>;
  5464. + pinctrl-names = "default";
  5465. + pinctrl-0 = <&pinctrl_hummingboard_usbh1_vbus>;
  5466. + regulator-name = "usb_h1_vbus";
  5467. + regulator-min-microvolt = <5000000>;
  5468. + regulator-max-microvolt = <5000000>;
  5469. + };
  5470. +
  5471. + reg_usbotg_vbus: usb-otg-vbus {
  5472. + compatible = "regulator-fixed";
  5473. + enable-active-high;
  5474. + gpio = <&gpio3 22 0>;
  5475. + pinctrl-names = "default";
  5476. + pinctrl-0 = <&pinctrl_hummingboard_usbotg_vbus>;
  5477. + regulator-name = "usb_otg_vbus";
  5478. + regulator-min-microvolt = <5000000>;
  5479. + regulator-max-microvolt = <5000000>;
  5480. + };
  5481. + };
  5482. +
  5483. + sound-sgtl5000 {
  5484. + audio-codec = <&sgtl5000>;
  5485. + audio-routing =
  5486. + "MIC_IN", "Mic Jack",
  5487. + "Mic Jack", "Mic Bias",
  5488. + "Headphone Jack", "HP_OUT";
  5489. + compatible = "fsl,imx-audio-sgtl5000";
  5490. + model = "On-board Codec";
  5491. + mux-ext-port = <5>;
  5492. + mux-int-port = <1>;
  5493. + ssi-controller = <&ssi1>;
  5494. + };
  5495. +
  5496. + sound-spdif {
  5497. + compatible = "fsl,imx-audio-spdif";
  5498. + model = "imx-spdif";
  5499. + spdif-controller = <&spdif>;
  5500. + spdif-out;
  5501. + };
  5502. +
  5503. + sound-hdmi {
  5504. + compatible = "fsl,imx6q-audio-hdmi",
  5505. + "fsl,imx-audio-hdmi";
  5506. + model = "imx-audio-hdmi";
  5507. + hdmi-controller = <&hdmi_audio>;
  5508. + };
  5509. +
  5510. + mxcfb1: fb@0 {
  5511. + compatible = "fsl,mxc_sdc_fb";
  5512. + disp_dev = "hdmi";
  5513. + interface_pix_fmt = "RGB24";
  5514. + mode_str ="1920x1080M@60";
  5515. + default_bpp = <32>;
  5516. + int_clk = <0>;
  5517. + late_init = <0>;
  5518. + status = "okay";
  5519. + };
  5520. +};
  5521. +
  5522. +&hdmi_core {
  5523. + ipu_id = <0>;
  5524. + disp_id = <0>;
  5525. + status = "okay";
  5526. +};
  5527. +
  5528. +&hdmi_video {
  5529. + fsl,phy_reg_vlev = <0x0294>;
  5530. + fsl,phy_reg_cksymtx = <0x800d>;
  5531. + status = "okay";
  5532. +};
  5533. +
  5534. +&hdmi_audio {
  5535. + status = "okay";
  5536. +};
  5537. +
  5538. +&hdmi_cec {
  5539. + pinctrl-names = "default";
  5540. + pinctrl-0 = <&pinctrl_hummingboard_hdmi>;
  5541. + status = "okay";
  5542. +};
  5543. +
  5544. +&i2c2 {
  5545. + clock-frequency = <100000>;
  5546. + pinctrl-names = "default";
  5547. + pinctrl-0 = <&pinctrl_hummingboard_i2c2>;
  5548. + status = "okay";
  5549. +
  5550. + ddc: imx6_hdmi_i2c@50 {
  5551. + compatible = "fsl,imx6-hdmi-i2c";
  5552. + reg = <0x50>;
  5553. + };
  5554. +};
  5555. +
  5556. +&audmux {
  5557. + status = "okay";
  5558. +};
  5559. +
  5560. +&can1 {
  5561. + pinctrl-names = "default";
  5562. + status = "okay";
  5563. +};
  5564. +
  5565. +&i2c1 {
  5566. + clock-frequency = <100000>;
  5567. + pinctrl-names = "default";
  5568. + pinctrl-0 = <&pinctrl_hummingboard_i2c1>;
  5569. + status = "okay";
  5570. +
  5571. + /* Pro model */
  5572. + rtc: pcf8523@68 {
  5573. + compatible = "nxp,pcf8523";
  5574. + reg = <0x68>;
  5575. + };
  5576. +
  5577. + /* Pro model */
  5578. + sgtl5000: sgtl5000@0a {
  5579. + clocks = <&clks 201>;
  5580. + compatible = "fsl,sgtl5000";
  5581. + pinctrl-0 = <&pinctrl_hummingboard_sgtl5000>;
  5582. + pinctrl-names = "default";
  5583. + reg = <0x0a>;
  5584. + VDDA-supply = <&reg_3p3v>;
  5585. + VDDIO-supply = <&reg_3p3v>;
  5586. + };
  5587. +};
  5588. +
  5589. +&iomuxc {
  5590. + pinctrl-names = "default";
  5591. + pinctrl-0 = <&pinctrl_hog>;
  5592. + hummingboard {
  5593. + pinctrl_hog: hoggrp {
  5594. + fsl,pins = <
  5595. + /*
  5596. + * 26 pin header GPIO description. The pins
  5597. + * numbering as following -
  5598. + * GPIO number | GPIO (bank,num) | PIN number
  5599. + * ------------+-----------------+------------
  5600. + * gpio1 | (1,1) | IO7
  5601. + * gpio73 | (3,9) | IO11
  5602. + * gpio72 | (3,8) | IO12
  5603. + * gpio71 | (3,7) | IO13
  5604. + * gpio70 | (3,6) | IO15
  5605. + * gpio194 | (7,2) | IO16
  5606. + * gpio195 | (7,3) | IO18
  5607. + * gpio67 | (3,3) | IO22
  5608. + *
  5609. + * Notice the gpioX and GPIO (Y,Z) mapping forumla :
  5610. + * X = (Y-1) * 32 + Z
  5611. + */
  5612. + MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x400130b1
  5613. + MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x400130b1
  5614. + MX6QDL_PAD_EIM_DA8__GPIO3_IO08 0x400130b1
  5615. + MX6QDL_PAD_EIM_DA7__GPIO3_IO07 0x400130b1
  5616. + MX6QDL_PAD_EIM_DA6__GPIO3_IO06 0x400130b1
  5617. + MX6QDL_PAD_SD3_CMD__GPIO7_IO02 0x400130b1
  5618. + MX6QDL_PAD_SD3_CLK__GPIO7_IO03 0x400130b1
  5619. + MX6QDL_PAD_EIM_DA3__GPIO3_IO03 0x400130b1
  5620. + >;
  5621. + };
  5622. +
  5623. + pinctrl_hummingboard_gpio3_5: hummingboard-gpio3_5 {
  5624. + fsl,pins = <
  5625. + MX6QDL_PAD_EIM_DA5__GPIO3_IO05 0x80000000
  5626. + >;
  5627. + };
  5628. +
  5629. + pinctrl_hummingboard_hdmi: hummingboard-hdmi {
  5630. + fsl,pins = <
  5631. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  5632. + >;
  5633. + };
  5634. +
  5635. + pinctrl_hummingboard_i2c1: hummingboard-i2c1 {
  5636. + fsl,pins = <
  5637. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  5638. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  5639. + >;
  5640. + };
  5641. +
  5642. + pinctrl_hummingboard_i2c2: hummingboard-i2c2 {
  5643. + fsl,pins = <
  5644. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  5645. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  5646. + >;
  5647. + };
  5648. +
  5649. + pinctrl_hummingboard_sgtl5000: hummingboard-sgtl5000 {
  5650. + fsl,pins = <
  5651. + MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0 /*brk*/
  5652. + MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x130b0 /*ok*/
  5653. + MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x110b0 /*brk*/
  5654. + MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x130b0 /*ok*/
  5655. + MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x130b0
  5656. + >;
  5657. + };
  5658. +
  5659. + pinctrl_hummingboard_spdif: hummingboard-spdif {
  5660. + fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
  5661. + };
  5662. +
  5663. + pinctrl_hummingboard_usbh1_vbus: hummingboard-usbh1-vbus {
  5664. + fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0>;
  5665. + };
  5666. +
  5667. + pinctrl_hummingboard_usbotg_id: hummingboard-usbotg-id {
  5668. + /*
  5669. + * Similar to pinctrl_usbotg_2, but we want it
  5670. + * pulled down for a fixed host connection.
  5671. + */
  5672. + fsl,pins = <MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x13059>;
  5673. + };
  5674. +
  5675. + pinctrl_hummingboard_usbotg_vbus: hummingboard-usbotg-vbus {
  5676. + fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0>;
  5677. + };
  5678. +
  5679. + pinctrl_hummingboard_usdhc2_aux: hummingboard-usdhc2-aux {
  5680. + fsl,pins = <
  5681. + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
  5682. + >;
  5683. + };
  5684. +
  5685. + pinctrl_hummingboard_usdhc2: hummingboard-usdhc2 {
  5686. + fsl,pins = <
  5687. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  5688. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  5689. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  5690. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  5691. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  5692. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
  5693. + >;
  5694. + };
  5695. +
  5696. + pinctrl_hummingboard_pcie_reset: hummingboard-pcie-reset {
  5697. + fsl,pins = <
  5698. + MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0x80000000
  5699. + >;
  5700. + };
  5701. +
  5702. + pinctrl_pwm1: pwm1grp {
  5703. + fsl,pins = <
  5704. + MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x1b0b1
  5705. + >;
  5706. + };
  5707. +
  5708. + };
  5709. +};
  5710. +
  5711. +&spdif {
  5712. + pinctrl-names = "default";
  5713. + pinctrl-0 = <&pinctrl_hummingboard_spdif>;
  5714. + clocks = <&clks 197>, <&clks 0>,
  5715. + <&clks 197>, <&clks 0>,
  5716. + <&clks 0>, <&clks 0>,
  5717. + <&clks 0>, <&clks 0>,
  5718. + <&clks 0>;
  5719. + clock-names = "core", "rxtx0",
  5720. + "rxtx1", "rxtx2",
  5721. + "rxtx3", "rxtx4",
  5722. + "rxtx5", "rxtx6",
  5723. + "rxtx7";
  5724. + status = "okay";
  5725. +};
  5726. +
  5727. +&ssi1 {
  5728. + fsl,mode = "i2s-slave";
  5729. + status = "okay";
  5730. +};
  5731. +
  5732. +&usbh1 {
  5733. + disable-over-current;
  5734. + vbus-supply = <&reg_usbh1_vbus>;
  5735. + status = "okay";
  5736. +};
  5737. +
  5738. +&usbotg {
  5739. + disable-over-current;
  5740. + pinctrl-names = "default";
  5741. + pinctrl-0 = <&pinctrl_hummingboard_usbotg_id>;
  5742. + vbus-supply = <&reg_usbotg_vbus>;
  5743. + status = "okay";
  5744. +};
  5745. +
  5746. +&usdhc2 {
  5747. + pinctrl-names = "default";
  5748. + pinctrl-0 = <
  5749. + &pinctrl_hummingboard_usdhc2_aux
  5750. + &pinctrl_hummingboard_usdhc2
  5751. + >;
  5752. + vmmc-supply = <&reg_3p3v>;
  5753. + cd-gpios = <&gpio1 4 0>;
  5754. + status = "okay";
  5755. +};
  5756. +
  5757. +&gpc {
  5758. + fsl,cpu_pupscr_sw2iso = <0xf>;
  5759. + fsl,cpu_pupscr_sw = <0xf>;
  5760. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  5761. + fsl,cpu_pdnscr_iso = <0x1>;
  5762. +};
  5763. +
  5764. +&pcie {
  5765. + pinctrl-names = "default";
  5766. + pinctrl-0 = <
  5767. + &pinctrl_hummingboard_pcie_reset
  5768. + >;
  5769. + reset-gpio = <&gpio3 4 0>;
  5770. + status = "okay";
  5771. + no-msi;
  5772. +};
  5773. +
  5774. +&pwm1 {
  5775. + pinctrl-names = "default";
  5776. + pinctrl-0 = <&pinctrl_pwm1>;
  5777. + status = "okay";
  5778. +};
  5779. +
  5780. +&pwm2 {
  5781. + pinctrl-names = "default";
  5782. + status = "okay";
  5783. +};
  5784. +
  5785. +&pwm3 {
  5786. + status = "disabled";
  5787. +};
  5788. +
  5789. +&pwm4 {
  5790. + status = "disabled";
  5791. +};
  5792. +
  5793. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi
  5794. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi 2014-07-28 10:07:25.000000000 -0500
  5795. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi 2014-12-08 00:31:51.124418001 -0600
  5796. @@ -17,7 +17,7 @@
  5797. enet {
  5798. pinctrl_microsom_enet_ar8035: microsom-enet-ar8035 {
  5799. fsl,pins = <
  5800. - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  5801. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b8b0
  5802. MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  5803. /* AR8035 reset */
  5804. MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x130b0
  5805. @@ -26,25 +26,25 @@
  5806. /* GPIO16 -> AR8035 25MHz */
  5807. MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0xc0000000
  5808. MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x80000000
  5809. - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  5810. - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  5811. - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  5812. - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  5813. - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  5814. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b030
  5815. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b030
  5816. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b030
  5817. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b030
  5818. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b030
  5819. /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */
  5820. MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x0a0b1
  5821. /* AR8035 pin strapping: IO voltage: pull up */
  5822. - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  5823. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030
  5824. /* AR8035 pin strapping: PHYADDR#0: pull down */
  5825. - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x130b0
  5826. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x13030
  5827. /* AR8035 pin strapping: PHYADDR#1: pull down */
  5828. - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x130b0
  5829. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x13030
  5830. /* AR8035 pin strapping: MODE#1: pull up */
  5831. - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  5832. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030
  5833. /* AR8035 pin strapping: MODE#3: pull up */
  5834. - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  5835. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030
  5836. /* AR8035 pin strapping: MODE#0: pull down */
  5837. - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x130b0
  5838. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x13030
  5839. /*
  5840. * As the RMII pins are also connected to RGMII
  5841. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-microsom.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-microsom.dtsi
  5842. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-microsom.dtsi 2014-07-28 10:07:25.000000000 -0500
  5843. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-microsom.dtsi 2014-12-08 00:31:51.124418001 -0600
  5844. @@ -1,9 +1,69 @@
  5845. /*
  5846. * Copyright (C) 2013,2014 Russell King
  5847. */
  5848. +#include <dt-bindings/gpio/gpio.h>
  5849. +/ {
  5850. + regulators {
  5851. + compatible = "simple-bus";
  5852. +
  5853. + reg_brcm_osc: brcm-osc-reg {
  5854. + compatible = "regulator-fixed";
  5855. + enable-active-high;
  5856. + gpio = <&gpio5 5 0>;
  5857. + pinctrl-names = "default";
  5858. + pinctrl-0 = <&pinctrl_microsom_brcm_osc_reg>;
  5859. + regulator-name = "brcm_osc_reg";
  5860. + regulator-min-microvolt = <3300000>;
  5861. + regulator-max-microvolt = <3300000>;
  5862. + regulator-always-on;
  5863. + regulator-boot-on;
  5864. + };
  5865. +
  5866. + reg_brcm: brcm-reg {
  5867. + compatible = "regulator-fixed";
  5868. + enable-active-high;
  5869. + gpio = <&gpio3 19 0>;
  5870. + pinctrl-names = "default";
  5871. + pinctrl-0 = <&pinctrl_microsom_brcm_reg>;
  5872. + regulator-name = "brcm_reg";
  5873. + regulator-min-microvolt = <3300000>;
  5874. + regulator-max-microvolt = <3300000>;
  5875. + startup-delay-us = <200000>;
  5876. + };
  5877. + };
  5878. +};
  5879. &iomuxc {
  5880. microsom {
  5881. + pinctrl_microsom_brcm_bt: microsom-brcm-bt {
  5882. + fsl,pins = <
  5883. + MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00 0x40013070
  5884. + MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01 0x40013070
  5885. + MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04 0x40013070
  5886. + >;
  5887. + };
  5888. +
  5889. + pinctrl_microsom_brcm_osc_reg: microsom-brcm-osc-reg {
  5890. + fsl,pins = <
  5891. + MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05 0x40013070
  5892. + >;
  5893. + };
  5894. +
  5895. + pinctrl_microsom_brcm_reg: microsom-brcm-reg {
  5896. + fsl,pins = <
  5897. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x40013070
  5898. + >;
  5899. + };
  5900. +
  5901. + pinctrl_microsom_brcm_wifi: microsom-brcm-wifi {
  5902. + fsl,pins = <
  5903. + MX6QDL_PAD_GPIO_8__XTALOSC_REF_CLK_32K 0x1b0b0
  5904. + MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x40013070
  5905. + MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x40013070
  5906. + MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x40013070
  5907. + >;
  5908. + };
  5909. +
  5910. pinctrl_microsom_uart1: microsom-uart1 {
  5911. fsl,pins = <
  5912. MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  5913. @@ -11,12 +71,24 @@
  5914. >;
  5915. };
  5916. - pinctrl_microsom_usbotg: microsom-usbotg {
  5917. - /*
  5918. - * Similar to pinctrl_usbotg_2, but we want it
  5919. - * pulled down for a fixed host connection.
  5920. - */
  5921. - fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>;
  5922. + pinctrl_microsom_uart4_1: microsom-uart4 {
  5923. + fsl,pins = <
  5924. + MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1
  5925. + MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1
  5926. + MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x1b0b1
  5927. + MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x1b0b1
  5928. + >;
  5929. + };
  5930. +
  5931. + pinctrl_microsom_usdhc1: microsom-usdhc1 {
  5932. + fsl,pins = <
  5933. + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  5934. + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  5935. + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  5936. + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  5937. + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  5938. + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  5939. + >;
  5940. };
  5941. };
  5942. };
  5943. @@ -27,7 +99,23 @@
  5944. status = "okay";
  5945. };
  5946. -&usbotg {
  5947. +/* UART4 - Connected to optional BRCM Wifi/BT/FM */
  5948. +&uart4 {
  5949. + pinctrl-names = "default";
  5950. + pinctrl-0 = <&pinctrl_microsom_brcm_bt &pinctrl_microsom_uart4_1>;
  5951. + fsl,uart-has-rtscts;
  5952. + status = "okay";
  5953. +};
  5954. +
  5955. +/* USDHC1 - Connected to optional BRCM Wifi/BT/FM */
  5956. +&usdhc1 {
  5957. + card-external-vcc-supply = <&reg_brcm>;
  5958. + card-reset-gpios = <&gpio5 26 GPIO_ACTIVE_LOW>, <&gpio6 0 GPIO_ACTIVE_LOW>;
  5959. + keep-power-in-suspend;
  5960. + non-removable;
  5961. pinctrl-names = "default";
  5962. - pinctrl-0 = <&pinctrl_microsom_usbotg>;
  5963. + pinctrl-0 = <&pinctrl_microsom_brcm_wifi &pinctrl_microsom_usdhc1>;
  5964. + vmmc-supply = <&reg_brcm>;
  5965. + status = "okay";
  5966. };
  5967. +
  5968. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
  5969. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi 1969-12-31 18:00:00.000000000 -0600
  5970. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi 2014-12-08 00:31:51.124418001 -0600
  5971. @@ -0,0 +1,426 @@
  5972. +/*
  5973. + * Copyright 2013 Boundary Devices, Inc.
  5974. + * Copyright 2011 Freescale Semiconductor, Inc.
  5975. + * Copyright 2011 Linaro Ltd.
  5976. + *
  5977. + * The code contained herein is licensed under the GNU General Public
  5978. + * License. You may obtain a copy of the GNU General Public License
  5979. + * Version 2 or later at the following locations:
  5980. + *
  5981. + * http://www.opensource.org/licenses/gpl-license.html
  5982. + * http://www.gnu.org/copyleft/gpl.html
  5983. + */
  5984. +#include <dt-bindings/gpio/gpio.h>
  5985. +#include <dt-bindings/input/input.h>
  5986. +
  5987. +/ {
  5988. + chosen {
  5989. + stdout-path = &uart2;
  5990. + };
  5991. +
  5992. + memory {
  5993. + reg = <0x10000000 0x40000000>;
  5994. + };
  5995. +
  5996. + regulators {
  5997. + compatible = "simple-bus";
  5998. + #address-cells = <1>;
  5999. + #size-cells = <0>;
  6000. +
  6001. + reg_2p5v: regulator@0 {
  6002. + compatible = "regulator-fixed";
  6003. + reg = <0>;
  6004. + regulator-name = "2P5V";
  6005. + regulator-min-microvolt = <2500000>;
  6006. + regulator-max-microvolt = <2500000>;
  6007. + regulator-always-on;
  6008. + };
  6009. +
  6010. + reg_3p3v: regulator@1 {
  6011. + compatible = "regulator-fixed";
  6012. + reg = <1>;
  6013. + regulator-name = "3P3V";
  6014. + regulator-min-microvolt = <3300000>;
  6015. + regulator-max-microvolt = <3300000>;
  6016. + regulator-always-on;
  6017. + };
  6018. +
  6019. + reg_usb_otg_vbus: regulator@2 {
  6020. + compatible = "regulator-fixed";
  6021. + reg = <2>;
  6022. + regulator-name = "usb_otg_vbus";
  6023. + regulator-min-microvolt = <5000000>;
  6024. + regulator-max-microvolt = <5000000>;
  6025. + gpio = <&gpio3 22 0>;
  6026. + enable-active-high;
  6027. + };
  6028. + };
  6029. +
  6030. + gpio-keys {
  6031. + compatible = "gpio-keys";
  6032. + pinctrl-names = "default";
  6033. + pinctrl-0 = <&pinctrl_gpio_keys>;
  6034. +
  6035. + power {
  6036. + label = "Power Button";
  6037. + gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
  6038. + linux,code = <KEY_POWER>;
  6039. + gpio-key,wakeup;
  6040. + };
  6041. +
  6042. + menu {
  6043. + label = "Menu";
  6044. + gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
  6045. + linux,code = <KEY_MENU>;
  6046. + };
  6047. +
  6048. + home {
  6049. + label = "Home";
  6050. + gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
  6051. + linux,code = <KEY_HOME>;
  6052. + };
  6053. +
  6054. + back {
  6055. + label = "Back";
  6056. + gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
  6057. + linux,code = <KEY_BACK>;
  6058. + };
  6059. +
  6060. + volume-up {
  6061. + label = "Volume Up";
  6062. + gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
  6063. + linux,code = <KEY_VOLUMEUP>;
  6064. + };
  6065. +
  6066. + volume-down {
  6067. + label = "Volume Down";
  6068. + gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
  6069. + linux,code = <KEY_VOLUMEDOWN>;
  6070. + };
  6071. + };
  6072. +
  6073. + sound {
  6074. + compatible = "fsl,imx6q-nitrogen6x-sgtl5000",
  6075. + "fsl,imx-audio-sgtl5000";
  6076. + model = "imx6q-nitrogen6x-sgtl5000";
  6077. + ssi-controller = <&ssi1>;
  6078. + audio-codec = <&codec>;
  6079. + audio-routing =
  6080. + "MIC_IN", "Mic Jack",
  6081. + "Mic Jack", "Mic Bias",
  6082. + "Headphone Jack", "HP_OUT";
  6083. + mux-int-port = <1>;
  6084. + mux-ext-port = <3>;
  6085. + };
  6086. +
  6087. + backlight_lcd {
  6088. + compatible = "pwm-backlight";
  6089. + pwms = <&pwm1 0 5000000>;
  6090. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6091. + default-brightness-level = <7>;
  6092. + power-supply = <&reg_3p3v>;
  6093. + status = "okay";
  6094. + };
  6095. +
  6096. + backlight_lvds {
  6097. + compatible = "pwm-backlight";
  6098. + pwms = <&pwm4 0 5000000>;
  6099. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6100. + default-brightness-level = <7>;
  6101. + power-supply = <&reg_3p3v>;
  6102. + status = "okay";
  6103. + };
  6104. +};
  6105. +
  6106. +&audmux {
  6107. + pinctrl-names = "default";
  6108. + pinctrl-0 = <&pinctrl_audmux>;
  6109. + status = "okay";
  6110. +};
  6111. +
  6112. +&ecspi1 {
  6113. + fsl,spi-num-chipselects = <1>;
  6114. + cs-gpios = <&gpio3 19 0>;
  6115. + pinctrl-names = "default";
  6116. + pinctrl-0 = <&pinctrl_ecspi1>;
  6117. + status = "okay";
  6118. +
  6119. + flash: m25p80@0 {
  6120. + compatible = "sst,sst25vf016b";
  6121. + spi-max-frequency = <20000000>;
  6122. + reg = <0>;
  6123. + };
  6124. +};
  6125. +
  6126. +&fec {
  6127. + pinctrl-names = "default";
  6128. + pinctrl-0 = <&pinctrl_enet>;
  6129. + phy-mode = "rgmii";
  6130. + phy-reset-gpios = <&gpio1 27 0>;
  6131. + txen-skew-ps = <0>;
  6132. + txc-skew-ps = <3000>;
  6133. + rxdv-skew-ps = <0>;
  6134. + rxc-skew-ps = <3000>;
  6135. + rxd0-skew-ps = <0>;
  6136. + rxd1-skew-ps = <0>;
  6137. + rxd2-skew-ps = <0>;
  6138. + rxd3-skew-ps = <0>;
  6139. + txd0-skew-ps = <0>;
  6140. + txd1-skew-ps = <0>;
  6141. + txd2-skew-ps = <0>;
  6142. + txd3-skew-ps = <0>;
  6143. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  6144. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  6145. + status = "okay";
  6146. +};
  6147. +
  6148. +&i2c1 {
  6149. + clock-frequency = <100000>;
  6150. + pinctrl-names = "default";
  6151. + pinctrl-0 = <&pinctrl_i2c1>;
  6152. + status = "okay";
  6153. +
  6154. + codec: sgtl5000@0a {
  6155. + compatible = "fsl,sgtl5000";
  6156. + reg = <0x0a>;
  6157. + clocks = <&clks 201>;
  6158. + VDDA-supply = <&reg_2p5v>;
  6159. + VDDIO-supply = <&reg_3p3v>;
  6160. + };
  6161. +};
  6162. +
  6163. +&iomuxc {
  6164. + pinctrl-names = "default";
  6165. + pinctrl-0 = <&pinctrl_hog>;
  6166. +
  6167. + imx6q-nitrogen6x {
  6168. + pinctrl_hog: hoggrp {
  6169. + fsl,pins = <
  6170. + /* SGTL5000 sys_mclk */
  6171. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x030b0
  6172. + >;
  6173. + };
  6174. +
  6175. + pinctrl_audmux: audmuxgrp {
  6176. + fsl,pins = <
  6177. + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
  6178. + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
  6179. + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
  6180. + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
  6181. + >;
  6182. + };
  6183. +
  6184. + pinctrl_ecspi1: ecspi1grp {
  6185. + fsl,pins = <
  6186. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  6187. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  6188. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  6189. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x000b1 /* CS */
  6190. + >;
  6191. + };
  6192. +
  6193. + pinctrl_enet: enetgrp {
  6194. + fsl,pins = <
  6195. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0
  6196. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0
  6197. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0
  6198. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0
  6199. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0
  6200. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0
  6201. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0
  6202. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0
  6203. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0
  6204. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  6205. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  6206. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  6207. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  6208. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  6209. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  6210. + /* Phy reset */
  6211. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x000b0
  6212. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  6213. + >;
  6214. + };
  6215. +
  6216. + pinctrl_gpio_keys: gpio_keysgrp {
  6217. + fsl,pins = <
  6218. + /* Power Button */
  6219. + MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
  6220. + /* Menu Button */
  6221. + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
  6222. + /* Home Button */
  6223. + MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
  6224. + /* Back Button */
  6225. + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
  6226. + /* Volume Up Button */
  6227. + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0
  6228. + /* Volume Down Button */
  6229. + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
  6230. + >;
  6231. + };
  6232. +
  6233. + pinctrl_i2c1: i2c1grp {
  6234. + fsl,pins = <
  6235. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  6236. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  6237. + >;
  6238. + };
  6239. +
  6240. + pinctrl_pwm1: pwm1grp {
  6241. + fsl,pins = <
  6242. + MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  6243. + >;
  6244. + };
  6245. +
  6246. + pinctrl_pwm3: pwm3grp {
  6247. + fsl,pins = <
  6248. + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
  6249. + >;
  6250. + };
  6251. +
  6252. + pinctrl_pwm4: pwm4grp {
  6253. + fsl,pins = <
  6254. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  6255. + >;
  6256. + };
  6257. +
  6258. + pinctrl_uart1: uart1grp {
  6259. + fsl,pins = <
  6260. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  6261. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  6262. + >;
  6263. + };
  6264. +
  6265. + pinctrl_uart2: uart2grp {
  6266. + fsl,pins = <
  6267. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  6268. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  6269. + >;
  6270. + };
  6271. +
  6272. + pinctrl_usbotg: usbotggrp {
  6273. + fsl,pins = <
  6274. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  6275. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  6276. + /* power enable, high active */
  6277. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x000b0
  6278. + >;
  6279. + };
  6280. +
  6281. + pinctrl_usdhc3: usdhc3grp {
  6282. + fsl,pins = <
  6283. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  6284. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  6285. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  6286. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  6287. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  6288. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  6289. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
  6290. + >;
  6291. + };
  6292. +
  6293. + pinctrl_usdhc4: usdhc4grp {
  6294. + fsl,pins = <
  6295. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  6296. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  6297. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  6298. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  6299. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  6300. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  6301. + MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /* CD */
  6302. + >;
  6303. + };
  6304. + };
  6305. +};
  6306. +
  6307. +&ldb {
  6308. + status = "okay";
  6309. +
  6310. + lvds-channel@0 {
  6311. + fsl,data-mapping = "spwg";
  6312. + fsl,data-width = <18>;
  6313. + status = "okay";
  6314. +
  6315. + display-timings {
  6316. + native-mode = <&timing0>;
  6317. + timing0: hsd100pxn1 {
  6318. + clock-frequency = <65000000>;
  6319. + hactive = <1024>;
  6320. + vactive = <768>;
  6321. + hback-porch = <220>;
  6322. + hfront-porch = <40>;
  6323. + vback-porch = <21>;
  6324. + vfront-porch = <7>;
  6325. + hsync-len = <60>;
  6326. + vsync-len = <10>;
  6327. + };
  6328. + };
  6329. + };
  6330. +};
  6331. +
  6332. +&pcie {
  6333. + status = "okay";
  6334. +};
  6335. +
  6336. +&pwm1 {
  6337. + pinctrl-names = "default";
  6338. + pinctrl-0 = <&pinctrl_pwm1>;
  6339. + status = "okay";
  6340. +};
  6341. +
  6342. +&pwm3 {
  6343. + pinctrl-names = "default";
  6344. + pinctrl-0 = <&pinctrl_pwm3>;
  6345. + status = "okay";
  6346. +};
  6347. +
  6348. +&pwm4 {
  6349. + pinctrl-names = "default";
  6350. + pinctrl-0 = <&pinctrl_pwm4>;
  6351. + status = "okay";
  6352. +};
  6353. +
  6354. +&ssi1 {
  6355. + fsl,mode = "i2s-slave";
  6356. + status = "okay";
  6357. +};
  6358. +
  6359. +&uart1 {
  6360. + pinctrl-names = "default";
  6361. + pinctrl-0 = <&pinctrl_uart1>;
  6362. + status = "okay";
  6363. +};
  6364. +
  6365. +&uart2 {
  6366. + pinctrl-names = "default";
  6367. + pinctrl-0 = <&pinctrl_uart2>;
  6368. + status = "okay";
  6369. +};
  6370. +
  6371. +&usbh1 {
  6372. + status = "okay";
  6373. +};
  6374. +
  6375. +&usbotg {
  6376. + vbus-supply = <&reg_usb_otg_vbus>;
  6377. + pinctrl-names = "default";
  6378. + pinctrl-0 = <&pinctrl_usbotg>;
  6379. + disable-over-current;
  6380. + status = "okay";
  6381. +};
  6382. +
  6383. +&usdhc3 {
  6384. + pinctrl-names = "default";
  6385. + pinctrl-0 = <&pinctrl_usdhc3>;
  6386. + cd-gpios = <&gpio7 0 0>;
  6387. + vmmc-supply = <&reg_3p3v>;
  6388. + status = "okay";
  6389. +};
  6390. +
  6391. +&usdhc4 {
  6392. + pinctrl-names = "default";
  6393. + pinctrl-0 = <&pinctrl_usdhc4>;
  6394. + cd-gpios = <&gpio2 6 0>;
  6395. + vmmc-supply = <&reg_3p3v>;
  6396. + status = "okay";
  6397. +};
  6398. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
  6399. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi 1969-12-31 18:00:00.000000000 -0600
  6400. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi 2014-12-08 00:31:51.124418001 -0600
  6401. @@ -0,0 +1,98 @@
  6402. +/*
  6403. + * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
  6404. + *
  6405. + * The code contained herein is licensed under the GNU General Public
  6406. + * License. You may obtain a copy of the GNU General Public License
  6407. + * Version 2 or later at the following locations:
  6408. + *
  6409. + * http://www.opensource.org/licenses/gpl-license.html
  6410. + * http://www.gnu.org/copyleft/gpl.html
  6411. + */
  6412. +
  6413. +/ {
  6414. + chosen {
  6415. + linux,stdout-path = &uart4;
  6416. + };
  6417. +};
  6418. +
  6419. +&fec {
  6420. + status = "okay";
  6421. +};
  6422. +
  6423. +&gpmi {
  6424. + status = "okay";
  6425. +};
  6426. +
  6427. +&i2c2 {
  6428. + pinctrl-names = "default";
  6429. + pinctrl-0 = <&pinctrl_i2c2>;
  6430. + clock-frequency = <100000>;
  6431. + status = "okay";
  6432. +
  6433. + tlv320@18 {
  6434. + compatible = "ti,tlv320aic3x";
  6435. + reg = <0x18>;
  6436. + };
  6437. +
  6438. + stmpe@41 {
  6439. + compatible = "st,stmpe811";
  6440. + reg = <0x41>;
  6441. + };
  6442. +
  6443. + rtc@51 {
  6444. + compatible = "nxp,rtc8564";
  6445. + reg = <0x51>;
  6446. + };
  6447. +
  6448. + adc@64 {
  6449. + compatible = "maxim,max1037";
  6450. + reg = <0x64>;
  6451. + };
  6452. +};
  6453. +
  6454. +&i2c3 {
  6455. + pinctrl-names = "default";
  6456. + pinctrl-0 = <&pinctrl_i2c3>;
  6457. + clock-frequency = <100000>;
  6458. + status = "okay";
  6459. +};
  6460. +
  6461. +&uart3 {
  6462. + status = "okay";
  6463. +};
  6464. +
  6465. +&uart4 {
  6466. + status = "okay";
  6467. +};
  6468. +
  6469. +&usbh1 {
  6470. + status = "okay";
  6471. +};
  6472. +
  6473. +&usbotg {
  6474. + status = "okay";
  6475. +};
  6476. +
  6477. +&usdhc2 {
  6478. + status = "okay";
  6479. +};
  6480. +
  6481. +&usdhc3 {
  6482. + status = "okay";
  6483. +};
  6484. +
  6485. +&iomuxc {
  6486. + pinctrl_i2c2: i2c2grp {
  6487. + fsl,pins = <
  6488. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  6489. + MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
  6490. + >;
  6491. + };
  6492. +
  6493. + pinctrl_i2c3: i2c3grp {
  6494. + fsl,pins = <
  6495. + MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
  6496. + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
  6497. + >;
  6498. + };
  6499. +};
  6500. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
  6501. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi 1969-12-31 18:00:00.000000000 -0600
  6502. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi 2014-12-08 00:31:51.124418001 -0600
  6503. @@ -0,0 +1,356 @@
  6504. +/*
  6505. + * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
  6506. + *
  6507. + * The code contained herein is licensed under the GNU General Public
  6508. + * License. You may obtain a copy of the GNU General Public License
  6509. + * Version 2 or later at the following locations:
  6510. + *
  6511. + * http://www.opensource.org/licenses/gpl-license.html
  6512. + * http://www.gnu.org/copyleft/gpl.html
  6513. + */
  6514. +
  6515. +#include <dt-bindings/gpio/gpio.h>
  6516. +
  6517. +/ {
  6518. + model = "Phytec phyFLEX-i.MX6 Ouad";
  6519. + compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
  6520. +
  6521. + memory {
  6522. + reg = <0x10000000 0x80000000>;
  6523. + };
  6524. +
  6525. + regulators {
  6526. + compatible = "simple-bus";
  6527. + #address-cells = <1>;
  6528. + #size-cells = <0>;
  6529. +
  6530. + reg_usb_otg_vbus: regulator@0 {
  6531. + compatible = "regulator-fixed";
  6532. + reg = <0>;
  6533. + regulator-name = "usb_otg_vbus";
  6534. + regulator-min-microvolt = <5000000>;
  6535. + regulator-max-microvolt = <5000000>;
  6536. + gpio = <&gpio4 15 0>;
  6537. + };
  6538. +
  6539. + reg_usb_h1_vbus: regulator@1 {
  6540. + compatible = "regulator-fixed";
  6541. + reg = <1>;
  6542. + regulator-name = "usb_h1_vbus";
  6543. + regulator-min-microvolt = <5000000>;
  6544. + regulator-max-microvolt = <5000000>;
  6545. + gpio = <&gpio1 0 0>;
  6546. + };
  6547. + };
  6548. +
  6549. + gpio_leds: leds {
  6550. + compatible = "gpio-leds";
  6551. +
  6552. + green {
  6553. + label = "phyflex:green";
  6554. + gpios = <&gpio1 30 0>;
  6555. + };
  6556. +
  6557. + red {
  6558. + label = "phyflex:red";
  6559. + gpios = <&gpio2 31 0>;
  6560. + };
  6561. + };
  6562. +};
  6563. +
  6564. +&ecspi3 {
  6565. + pinctrl-names = "default";
  6566. + pinctrl-0 = <&pinctrl_ecspi3>;
  6567. + status = "okay";
  6568. + fsl,spi-num-chipselects = <1>;
  6569. + cs-gpios = <&gpio4 24 0>;
  6570. +
  6571. + flash@0 {
  6572. + compatible = "m25p80";
  6573. + spi-max-frequency = <20000000>;
  6574. + reg = <0>;
  6575. + };
  6576. +};
  6577. +
  6578. +&i2c1 {
  6579. + pinctrl-names = "default";
  6580. + pinctrl-0 = <&pinctrl_i2c1>;
  6581. + status = "okay";
  6582. +
  6583. + eeprom@50 {
  6584. + compatible = "atmel,24c32";
  6585. + reg = <0x50>;
  6586. + };
  6587. +
  6588. + pmic@58 {
  6589. + compatible = "dialog,da9063";
  6590. + reg = <0x58>;
  6591. + interrupt-parent = <&gpio4>;
  6592. + interrupts = <17 0x8>; /* active-low GPIO4_17 */
  6593. +
  6594. + regulators {
  6595. + vddcore_reg: bcore1 {
  6596. + regulator-min-microvolt = <730000>;
  6597. + regulator-max-microvolt = <1380000>;
  6598. + regulator-always-on;
  6599. + };
  6600. +
  6601. + vddsoc_reg: bcore2 {
  6602. + regulator-min-microvolt = <730000>;
  6603. + regulator-max-microvolt = <1380000>;
  6604. + regulator-always-on;
  6605. + };
  6606. +
  6607. + vdd_ddr3_reg: bpro {
  6608. + regulator-min-microvolt = <1500000>;
  6609. + regulator-max-microvolt = <1500000>;
  6610. + regulator-always-on;
  6611. + };
  6612. +
  6613. + vdd_3v3_reg: bperi {
  6614. + regulator-min-microvolt = <3300000>;
  6615. + regulator-max-microvolt = <3300000>;
  6616. + regulator-always-on;
  6617. + };
  6618. +
  6619. + vdd_buckmem_reg: bmem {
  6620. + regulator-min-microvolt = <3300000>;
  6621. + regulator-max-microvolt = <3300000>;
  6622. + regulator-always-on;
  6623. + };
  6624. +
  6625. + vdd_eth_reg: bio {
  6626. + regulator-min-microvolt = <1200000>;
  6627. + regulator-max-microvolt = <1200000>;
  6628. + regulator-always-on;
  6629. + };
  6630. +
  6631. + vdd_eth_io_reg: ldo4 {
  6632. + regulator-min-microvolt = <2500000>;
  6633. + regulator-max-microvolt = <2500000>;
  6634. + regulator-always-on;
  6635. + };
  6636. +
  6637. + vdd_mx6_snvs_reg: ldo5 {
  6638. + regulator-min-microvolt = <3000000>;
  6639. + regulator-max-microvolt = <3000000>;
  6640. + regulator-always-on;
  6641. + };
  6642. +
  6643. + vdd_3v3_pmic_io_reg: ldo6 {
  6644. + regulator-min-microvolt = <3300000>;
  6645. + regulator-max-microvolt = <3300000>;
  6646. + regulator-always-on;
  6647. + };
  6648. +
  6649. + vdd_sd0_reg: ldo9 {
  6650. + regulator-min-microvolt = <3300000>;
  6651. + regulator-max-microvolt = <3300000>;
  6652. + };
  6653. +
  6654. + vdd_sd1_reg: ldo10 {
  6655. + regulator-min-microvolt = <3300000>;
  6656. + regulator-max-microvolt = <3300000>;
  6657. + };
  6658. +
  6659. + vdd_mx6_high_reg: ldo11 {
  6660. + regulator-min-microvolt = <3000000>;
  6661. + regulator-max-microvolt = <3000000>;
  6662. + regulator-always-on;
  6663. + };
  6664. + };
  6665. + };
  6666. +};
  6667. +
  6668. +&iomuxc {
  6669. + pinctrl-names = "default";
  6670. + pinctrl-0 = <&pinctrl_hog>;
  6671. +
  6672. + imx6q-phytec-pfla02 {
  6673. + pinctrl_hog: hoggrp {
  6674. + fsl,pins = <
  6675. + MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  6676. + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
  6677. + MX6QDL_PAD_DI0_PIN15__GPIO4_IO17 0x80000000 /* PMIC interrupt */
  6678. + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* Green LED */
  6679. + MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x80000000 /* Red LED */
  6680. + >;
  6681. + };
  6682. +
  6683. + pinctrl_ecspi3: ecspi3grp {
  6684. + fsl,pins = <
  6685. + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
  6686. + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
  6687. + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
  6688. + >;
  6689. + };
  6690. +
  6691. + pinctrl_enet: enetgrp {
  6692. + fsl,pins = <
  6693. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  6694. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  6695. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  6696. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  6697. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  6698. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  6699. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  6700. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  6701. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  6702. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  6703. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  6704. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  6705. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  6706. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  6707. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  6708. + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
  6709. + >;
  6710. + };
  6711. +
  6712. + pinctrl_gpmi_nand: gpminandgrp {
  6713. + fsl,pins = <
  6714. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  6715. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  6716. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  6717. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  6718. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  6719. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  6720. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  6721. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  6722. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  6723. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  6724. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  6725. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  6726. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  6727. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  6728. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  6729. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  6730. + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  6731. + >;
  6732. + };
  6733. +
  6734. + pinctrl_i2c1: i2c1grp {
  6735. + fsl,pins = <
  6736. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  6737. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  6738. + >;
  6739. + };
  6740. +
  6741. + pinctrl_uart3: uart3grp {
  6742. + fsl,pins = <
  6743. + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  6744. + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  6745. + MX6QDL_PAD_EIM_D30__UART3_RTS_B 0x1b0b1
  6746. + MX6QDL_PAD_EIM_D31__UART3_CTS_B 0x1b0b1
  6747. + >;
  6748. + };
  6749. +
  6750. + pinctrl_uart4: uart4grp {
  6751. + fsl,pins = <
  6752. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  6753. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  6754. + >;
  6755. + };
  6756. +
  6757. + pinctrl_usbh1: usbh1grp {
  6758. + fsl,pins = <
  6759. + MX6QDL_PAD_GPIO_0__USB_H1_PWR 0x80000000
  6760. + >;
  6761. + };
  6762. +
  6763. + pinctrl_usbotg: usbotggrp {
  6764. + fsl,pins = <
  6765. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  6766. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  6767. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000
  6768. + >;
  6769. + };
  6770. +
  6771. + pinctrl_usdhc2: usdhc2grp {
  6772. + fsl,pins = <
  6773. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  6774. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  6775. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  6776. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  6777. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  6778. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  6779. + >;
  6780. + };
  6781. +
  6782. + pinctrl_usdhc3: usdhc3grp {
  6783. + fsl,pins = <
  6784. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  6785. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  6786. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  6787. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  6788. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  6789. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  6790. + >;
  6791. + };
  6792. +
  6793. + pinctrl_usdhc3_cdwp: usdhc3cdwp {
  6794. + fsl,pins = <
  6795. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
  6796. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
  6797. + >;
  6798. + };
  6799. + };
  6800. +};
  6801. +
  6802. +&fec {
  6803. + pinctrl-names = "default";
  6804. + pinctrl-0 = <&pinctrl_enet>;
  6805. + phy-mode = "rgmii";
  6806. + phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
  6807. + status = "disabled";
  6808. +};
  6809. +
  6810. +&gpmi {
  6811. + pinctrl-names = "default";
  6812. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  6813. + nand-on-flash-bbt;
  6814. + status = "disabled";
  6815. +};
  6816. +
  6817. +&uart3 {
  6818. + pinctrl-names = "default";
  6819. + pinctrl-0 = <&pinctrl_uart3>;
  6820. + status = "disabled";
  6821. +};
  6822. +
  6823. +&uart4 {
  6824. + pinctrl-names = "default";
  6825. + pinctrl-0 = <&pinctrl_uart4>;
  6826. + status = "disabled";
  6827. +};
  6828. +
  6829. +&usbh1 {
  6830. + vbus-supply = <&reg_usb_h1_vbus>;
  6831. + pinctrl-names = "default";
  6832. + pinctrl-0 = <&pinctrl_usbh1>;
  6833. + status = "disabled";
  6834. +};
  6835. +
  6836. +&usbotg {
  6837. + vbus-supply = <&reg_usb_otg_vbus>;
  6838. + pinctrl-names = "default";
  6839. + pinctrl-0 = <&pinctrl_usbotg>;
  6840. + disable-over-current;
  6841. + status = "disabled";
  6842. +};
  6843. +
  6844. +&usdhc2 {
  6845. + pinctrl-names = "default";
  6846. + pinctrl-0 = <&pinctrl_usdhc2>;
  6847. + cd-gpios = <&gpio1 4 0>;
  6848. + wp-gpios = <&gpio1 2 0>;
  6849. + status = "disabled";
  6850. +};
  6851. +
  6852. +&usdhc3 {
  6853. + pinctrl-names = "default";
  6854. + pinctrl-0 = <&pinctrl_usdhc3
  6855. + &pinctrl_usdhc3_cdwp>;
  6856. + cd-gpios = <&gpio1 27 0>;
  6857. + wp-gpios = <&gpio1 29 0>;
  6858. + status = "disabled";
  6859. +};
  6860. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
  6861. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi 2014-07-28 10:07:25.000000000 -0500
  6862. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi 2014-12-08 00:31:51.124418001 -0600
  6863. @@ -10,17 +10,146 @@
  6864. * http://www.gnu.org/copyleft/gpl.html
  6865. */
  6866. +#include <dt-bindings/gpio/gpio.h>
  6867. +
  6868. / {
  6869. + aliases {
  6870. + mxcfb0 = &mxcfb1;
  6871. + mxcfb1 = &mxcfb2;
  6872. + mxcfb2 = &mxcfb3;
  6873. + mxcfb3 = &mxcfb4;
  6874. + };
  6875. +
  6876. memory {
  6877. reg = <0x10000000 0x80000000>;
  6878. };
  6879. +
  6880. + leds {
  6881. + compatible = "gpio-leds";
  6882. + pinctrl-names = "default";
  6883. + pinctrl-0 = <&pinctrl_gpio_leds>;
  6884. +
  6885. + user {
  6886. + label = "debug";
  6887. + gpios = <&gpio5 15 GPIO_ACTIVE_HIGH>;
  6888. + };
  6889. + };
  6890. +
  6891. + sound-spdif {
  6892. + compatible = "fsl,imx-audio-spdif",
  6893. + "fsl,imx-sabreauto-spdif";
  6894. + model = "imx-spdif";
  6895. + spdif-controller = <&spdif>;
  6896. + spdif-in;
  6897. + };
  6898. +
  6899. + backlight {
  6900. + compatible = "pwm-backlight";
  6901. + pwms = <&pwm3 0 5000000>;
  6902. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6903. + default-brightness-level = <7>;
  6904. + status = "okay";
  6905. + };
  6906. +
  6907. + max7310_reset: max7310-reset {
  6908. + compatible = "gpio-reset";
  6909. + reset-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
  6910. + reset-delay-us = <1>;
  6911. + #reset-cells = <0>;
  6912. + };
  6913. +
  6914. + mxcfb1: fb@0 {
  6915. + compatible = "fsl,mxc_sdc_fb";
  6916. + disp_dev = "ldb";
  6917. + interface_pix_fmt = "RGB666";
  6918. + mode_str ="LDB-XGA";
  6919. + default_bpp = <16>;
  6920. + int_clk = <0>;
  6921. + late_init = <0>;
  6922. + status = "disabled";
  6923. + };
  6924. +
  6925. + mxcfb2: fb@1 {
  6926. + compatible = "fsl,mxc_sdc_fb";
  6927. + disp_dev = "hdmi";
  6928. + interface_pix_fmt = "RGB24";
  6929. + mode_str ="1920x1080M@60";
  6930. + default_bpp = <24>;
  6931. + int_clk = <0>;
  6932. + late_init = <0>;
  6933. + status = "disabled";
  6934. + };
  6935. +
  6936. + mxcfb3: fb@2 {
  6937. + compatible = "fsl,mxc_sdc_fb";
  6938. + disp_dev = "lcd";
  6939. + interface_pix_fmt = "RGB565";
  6940. + mode_str ="CLAA-WVGA";
  6941. + default_bpp = <16>;
  6942. + int_clk = <0>;
  6943. + late_init = <0>;
  6944. + status = "disabled";
  6945. + };
  6946. +
  6947. + mxcfb4: fb@3 {
  6948. + compatible = "fsl,mxc_sdc_fb";
  6949. + disp_dev = "ldb";
  6950. + interface_pix_fmt = "RGB666";
  6951. + mode_str ="LDB-XGA";
  6952. + default_bpp = <16>;
  6953. + int_clk = <0>;
  6954. + late_init = <0>;
  6955. + status = "disabled";
  6956. + };
  6957. +
  6958. + backlight {
  6959. + compatible = "pwm-backlight";
  6960. + pwms = <&pwm3 0 5000000>;
  6961. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6962. + default-brightness-level = <7>;
  6963. + };
  6964. +
  6965. + regulators {
  6966. + compatible = "simple-bus";
  6967. + reg_audio: cs42888_supply {
  6968. + compatible = "regulator-fixed";
  6969. + regulator-name = "cs42888_supply";
  6970. + regulator-min-microvolt = <3300000>;
  6971. + regulator-max-microvolt = <3300000>;
  6972. + regulator-always-on;
  6973. + };
  6974. + };
  6975. +
  6976. + sound-cs42888 {
  6977. + compatible = "fsl,imx6-sabreauto-cs42888",
  6978. + "fsl,imx-audio-cs42888";
  6979. + model = "imx-cs42888";
  6980. + esai-controller = <&esai>;
  6981. + asrc-controller = <&asrc_p2p>;
  6982. + audio-codec = <&codec>;
  6983. + };
  6984. +
  6985. + sound-hdmi {
  6986. + compatible = "fsl,imx6q-audio-hdmi",
  6987. + "fsl,imx-audio-hdmi";
  6988. + model = "imx-audio-hdmi";
  6989. + hdmi-controller = <&hdmi_audio>;
  6990. + };
  6991. +
  6992. + clocks {
  6993. + codec_osc: anaclk2 {
  6994. + compatible = "fixed-clock";
  6995. + #clock-cells = <0>;
  6996. + clock-frequency = <24576000>;
  6997. + };
  6998. + };
  6999. };
  7000. &ecspi1 {
  7001. fsl,spi-num-chipselects = <1>;
  7002. cs-gpios = <&gpio3 19 0>;
  7003. pinctrl-names = "default";
  7004. - pinctrl-0 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_sabreauto>;
  7005. + pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
  7006. status = "disabled"; /* pin conflict with WEIM NOR */
  7007. flash: m25p80@0 {
  7008. @@ -34,51 +163,481 @@
  7009. &fec {
  7010. pinctrl-names = "default";
  7011. - pinctrl-0 = <&pinctrl_enet_2>;
  7012. + pinctrl-0 = <&pinctrl_enet>;
  7013. phy-mode = "rgmii";
  7014. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  7015. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  7016. status = "okay";
  7017. };
  7018. &gpmi {
  7019. pinctrl-names = "default";
  7020. - pinctrl-0 = <&pinctrl_gpmi_nand_1>;
  7021. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  7022. + status = "okay";
  7023. +};
  7024. +
  7025. +&i2c2 {
  7026. + clock-frequency = <100000>;
  7027. + pinctrl-names = "default";
  7028. + pinctrl-0 = <&pinctrl_i2c2>;
  7029. + status = "okay";
  7030. +
  7031. + egalax_ts@04 {
  7032. + compatible = "eeti,egalax_ts";
  7033. + reg = <0x04>;
  7034. + interrupt-parent = <&gpio2>;
  7035. + interrupts = <28 2>;
  7036. + wakeup-gpios = <&gpio2 28 0>;
  7037. + };
  7038. +
  7039. + pmic: pfuze100@08 {
  7040. + compatible = "fsl,pfuze100";
  7041. + reg = <0x08>;
  7042. +
  7043. + regulators {
  7044. + sw1a_reg: sw1ab {
  7045. + regulator-min-microvolt = <300000>;
  7046. + regulator-max-microvolt = <1875000>;
  7047. + regulator-boot-on;
  7048. + regulator-always-on;
  7049. + regulator-ramp-delay = <6250>;
  7050. + };
  7051. +
  7052. + sw1c_reg: sw1c {
  7053. + regulator-min-microvolt = <300000>;
  7054. + regulator-max-microvolt = <1875000>;
  7055. + regulator-boot-on;
  7056. + regulator-always-on;
  7057. + regulator-ramp-delay = <6250>;
  7058. + };
  7059. +
  7060. + sw2_reg: sw2 {
  7061. + regulator-min-microvolt = <800000>;
  7062. + regulator-max-microvolt = <3300000>;
  7063. + regulator-boot-on;
  7064. + regulator-always-on;
  7065. + };
  7066. +
  7067. + sw3a_reg: sw3a {
  7068. + regulator-min-microvolt = <400000>;
  7069. + regulator-max-microvolt = <1975000>;
  7070. + regulator-boot-on;
  7071. + regulator-always-on;
  7072. + };
  7073. +
  7074. + sw3b_reg: sw3b {
  7075. + regulator-min-microvolt = <400000>;
  7076. + regulator-max-microvolt = <1975000>;
  7077. + regulator-boot-on;
  7078. + regulator-always-on;
  7079. + };
  7080. +
  7081. + sw4_reg: sw4 {
  7082. + regulator-min-microvolt = <800000>;
  7083. + regulator-max-microvolt = <3300000>;
  7084. + };
  7085. +
  7086. + swbst_reg: swbst {
  7087. + regulator-min-microvolt = <5000000>;
  7088. + regulator-max-microvolt = <5150000>;
  7089. + };
  7090. +
  7091. + snvs_reg: vsnvs {
  7092. + regulator-min-microvolt = <1000000>;
  7093. + regulator-max-microvolt = <3000000>;
  7094. + regulator-boot-on;
  7095. + regulator-always-on;
  7096. + };
  7097. +
  7098. + vref_reg: vrefddr {
  7099. + regulator-boot-on;
  7100. + regulator-always-on;
  7101. + };
  7102. +
  7103. + vgen1_reg: vgen1 {
  7104. + regulator-min-microvolt = <800000>;
  7105. + regulator-max-microvolt = <1550000>;
  7106. + };
  7107. +
  7108. + vgen2_reg: vgen2 {
  7109. + regulator-min-microvolt = <800000>;
  7110. + regulator-max-microvolt = <1550000>;
  7111. + };
  7112. +
  7113. + vgen3_reg: vgen3 {
  7114. + regulator-min-microvolt = <1800000>;
  7115. + regulator-max-microvolt = <3300000>;
  7116. + };
  7117. +
  7118. + vgen4_reg: vgen4 {
  7119. + regulator-min-microvolt = <1800000>;
  7120. + regulator-max-microvolt = <3300000>;
  7121. + regulator-always-on;
  7122. + };
  7123. +
  7124. + vgen5_reg: vgen5 {
  7125. + regulator-min-microvolt = <1800000>;
  7126. + regulator-max-microvolt = <3300000>;
  7127. + regulator-always-on;
  7128. + };
  7129. +
  7130. + vgen6_reg: vgen6 {
  7131. + regulator-min-microvolt = <1800000>;
  7132. + regulator-max-microvolt = <3300000>;
  7133. + regulator-always-on;
  7134. + };
  7135. + };
  7136. + };
  7137. +
  7138. + codec: cs42888@048 {
  7139. + compatible = "cirrus,cs42888";
  7140. + reg = <0x048>;
  7141. + clocks = <&codec_osc 0>;
  7142. + clock-names = "codec_osc";
  7143. + VA-supply = <&reg_audio>;
  7144. + VD-supply = <&reg_audio>;
  7145. + VLS-supply = <&reg_audio>;
  7146. + VLC-supply = <&reg_audio>;
  7147. + };
  7148. +
  7149. + hdmi: edid@50 {
  7150. + compatible = "fsl,imx6-hdmi-i2c";
  7151. + reg = <0x50>;
  7152. + };
  7153. +};
  7154. +
  7155. +&i2c3 {
  7156. + pinctrl-names = "default";
  7157. + pinctrl-0 = <&pinctrl_i2c3>;
  7158. + pinctrl-assert-gpios = <&gpio5 4 GPIO_ACTIVE_HIGH>;
  7159. status = "okay";
  7160. +
  7161. + max7310_a: gpio@30 {
  7162. + compatible = "maxim,max7310";
  7163. + reg = <0x30>;
  7164. + gpio-controller;
  7165. + #gpio-cells = <2>;
  7166. + resets = <&max7310_reset>;
  7167. + };
  7168. +
  7169. + max7310_b: gpio@32 {
  7170. + compatible = "maxim,max7310";
  7171. + reg = <0x32>;
  7172. + gpio-controller;
  7173. + #gpio-cells = <2>;
  7174. + };
  7175. +
  7176. + max7310_c: gpio@34 {
  7177. + compatible = "maxim,max7310";
  7178. + reg = <0x34>;
  7179. + gpio-controller;
  7180. + #gpio-cells = <2>;
  7181. + };
  7182. };
  7183. &iomuxc {
  7184. pinctrl-names = "default";
  7185. pinctrl-0 = <&pinctrl_hog>;
  7186. - hog {
  7187. + imx6qdl-sabreauto {
  7188. pinctrl_hog: hoggrp {
  7189. fsl,pins = <
  7190. MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
  7191. MX6QDL_PAD_SD2_DAT2__GPIO1_IO13 0x80000000
  7192. + MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x80000000
  7193. + MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x80000000
  7194. MX6QDL_PAD_GPIO_18__SD3_VSELECT 0x17059
  7195. >;
  7196. };
  7197. - };
  7198. - ecspi1 {
  7199. - pinctrl_ecspi1_sabreauto: ecspi1-sabreauto {
  7200. + pinctrl_esai1: esai1grp {
  7201. + fsl,pins = <
  7202. + MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1b030
  7203. + MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS 0x1b030
  7204. + MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1b030
  7205. + MX6QDL_PAD_GPIO_5__ESAI_TX2_RX3 0x1b030
  7206. + MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1 0x1b030
  7207. + MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0 0x1b030
  7208. + MX6QDL_PAD_GPIO_17__ESAI_TX0 0x1b030
  7209. + MX6QDL_PAD_NANDF_CS3__ESAI_TX1 0x1b030
  7210. + MX6QDL_PAD_ENET_MDIO__ESAI_RX_CLK 0x1b030
  7211. + MX6QDL_PAD_GPIO_9__ESAI_RX_FS 0x1b030
  7212. + >;
  7213. + };
  7214. +
  7215. + pinctrl_ecspi1: ecspi1grp {
  7216. + fsl,pins = <
  7217. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  7218. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  7219. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  7220. + >;
  7221. + };
  7222. +
  7223. + pinctrl_ecspi1_cs: ecspi1cs {
  7224. fsl,pins = <
  7225. MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000
  7226. >;
  7227. };
  7228. +
  7229. + pinctrl_enet: enetgrp {
  7230. + fsl,pins = <
  7231. + MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
  7232. + MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0
  7233. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  7234. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  7235. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  7236. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  7237. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  7238. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  7239. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  7240. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  7241. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  7242. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  7243. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  7244. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  7245. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  7246. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  7247. + >;
  7248. + };
  7249. +
  7250. + pinctrl_gpio_leds: gpioledsgrp {
  7251. + fsl,pins = <
  7252. + MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x80000000
  7253. + >;
  7254. + };
  7255. +
  7256. + pinctrl_gpmi_nand: gpminandgrp {
  7257. + fsl,pins = <
  7258. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  7259. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  7260. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  7261. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  7262. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  7263. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  7264. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  7265. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  7266. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  7267. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  7268. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  7269. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  7270. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  7271. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  7272. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  7273. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  7274. + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  7275. + >;
  7276. + };
  7277. +
  7278. + pinctrl_hdmi_cec_2: hdmicecgrp-2 {
  7279. + fsl,pins = <
  7280. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  7281. + >;
  7282. + };
  7283. +
  7284. + pinctrl_i2c2: i2c2grp {
  7285. + fsl,pins = <
  7286. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  7287. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  7288. + >;
  7289. + };
  7290. +
  7291. + pinctrl_i2c3: i2c3grp {
  7292. + fsl,pins = <
  7293. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  7294. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  7295. + >;
  7296. + };
  7297. +
  7298. + pinctrl_pwm1: pwm1grp {
  7299. + fsl,pins = <
  7300. + MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
  7301. + >;
  7302. + };
  7303. +
  7304. + pinctrl_spdif: spdifgrp {
  7305. + fsl,pins = <
  7306. + MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x1b0b0
  7307. + >;
  7308. + };
  7309. +
  7310. + pinctrl_uart3: uart3grp {
  7311. + fsl,pins = <
  7312. + MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x1b0b1
  7313. + MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x1b0b1
  7314. + MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x1b0b1
  7315. + MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  7316. + >;
  7317. + };
  7318. +
  7319. + pinctrl_uart4: uart4grp {
  7320. + fsl,pins = <
  7321. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  7322. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  7323. + >;
  7324. + };
  7325. +
  7326. + pinctrl_usdhc3: usdhc3grp {
  7327. + fsl,pins = <
  7328. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  7329. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  7330. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  7331. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  7332. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  7333. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  7334. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
  7335. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
  7336. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
  7337. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
  7338. + >;
  7339. + };
  7340. +
  7341. + pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
  7342. + fsl,pins = <
  7343. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9
  7344. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9
  7345. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  7346. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  7347. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  7348. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  7349. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9
  7350. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9
  7351. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9
  7352. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9
  7353. + >;
  7354. + };
  7355. +
  7356. + pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
  7357. + fsl,pins = <
  7358. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9
  7359. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9
  7360. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  7361. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  7362. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  7363. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  7364. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
  7365. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
  7366. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
  7367. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
  7368. + >;
  7369. + };
  7370. +
  7371. + pinctrl_weim_cs0: weimcs0grp {
  7372. + fsl,pins = <
  7373. + MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0xb0b1
  7374. + >;
  7375. + };
  7376. +
  7377. + pinctrl_weim_nor: weimnorgrp {
  7378. + fsl,pins = <
  7379. + MX6QDL_PAD_EIM_OE__EIM_OE_B 0xb0b1
  7380. + MX6QDL_PAD_EIM_RW__EIM_RW 0xb0b1
  7381. + MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060
  7382. + MX6QDL_PAD_EIM_D16__EIM_DATA16 0x1b0b0
  7383. + MX6QDL_PAD_EIM_D17__EIM_DATA17 0x1b0b0
  7384. + MX6QDL_PAD_EIM_D18__EIM_DATA18 0x1b0b0
  7385. + MX6QDL_PAD_EIM_D19__EIM_DATA19 0x1b0b0
  7386. + MX6QDL_PAD_EIM_D20__EIM_DATA20 0x1b0b0
  7387. + MX6QDL_PAD_EIM_D21__EIM_DATA21 0x1b0b0
  7388. + MX6QDL_PAD_EIM_D22__EIM_DATA22 0x1b0b0
  7389. + MX6QDL_PAD_EIM_D23__EIM_DATA23 0x1b0b0
  7390. + MX6QDL_PAD_EIM_D24__EIM_DATA24 0x1b0b0
  7391. + MX6QDL_PAD_EIM_D25__EIM_DATA25 0x1b0b0
  7392. + MX6QDL_PAD_EIM_D26__EIM_DATA26 0x1b0b0
  7393. + MX6QDL_PAD_EIM_D27__EIM_DATA27 0x1b0b0
  7394. + MX6QDL_PAD_EIM_D28__EIM_DATA28 0x1b0b0
  7395. + MX6QDL_PAD_EIM_D29__EIM_DATA29 0x1b0b0
  7396. + MX6QDL_PAD_EIM_D30__EIM_DATA30 0x1b0b0
  7397. + MX6QDL_PAD_EIM_D31__EIM_DATA31 0x1b0b0
  7398. + MX6QDL_PAD_EIM_A23__EIM_ADDR23 0xb0b1
  7399. + MX6QDL_PAD_EIM_A22__EIM_ADDR22 0xb0b1
  7400. + MX6QDL_PAD_EIM_A21__EIM_ADDR21 0xb0b1
  7401. + MX6QDL_PAD_EIM_A20__EIM_ADDR20 0xb0b1
  7402. + MX6QDL_PAD_EIM_A19__EIM_ADDR19 0xb0b1
  7403. + MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0b1
  7404. + MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0b1
  7405. + MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0b1
  7406. + MX6QDL_PAD_EIM_DA15__EIM_AD15 0xb0b1
  7407. + MX6QDL_PAD_EIM_DA14__EIM_AD14 0xb0b1
  7408. + MX6QDL_PAD_EIM_DA13__EIM_AD13 0xb0b1
  7409. + MX6QDL_PAD_EIM_DA12__EIM_AD12 0xb0b1
  7410. + MX6QDL_PAD_EIM_DA11__EIM_AD11 0xb0b1
  7411. + MX6QDL_PAD_EIM_DA10__EIM_AD10 0xb0b1
  7412. + MX6QDL_PAD_EIM_DA9__EIM_AD09 0xb0b1
  7413. + MX6QDL_PAD_EIM_DA8__EIM_AD08 0xb0b1
  7414. + MX6QDL_PAD_EIM_DA7__EIM_AD07 0xb0b1
  7415. + MX6QDL_PAD_EIM_DA6__EIM_AD06 0xb0b1
  7416. + MX6QDL_PAD_EIM_DA5__EIM_AD05 0xb0b1
  7417. + MX6QDL_PAD_EIM_DA4__EIM_AD04 0xb0b1
  7418. + MX6QDL_PAD_EIM_DA3__EIM_AD03 0xb0b1
  7419. + MX6QDL_PAD_EIM_DA2__EIM_AD02 0xb0b1
  7420. + MX6QDL_PAD_EIM_DA1__EIM_AD01 0xb0b1
  7421. + MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0b1
  7422. + >;
  7423. + };
  7424. + };
  7425. +};
  7426. +
  7427. +&ldb {
  7428. + status = "okay";
  7429. +
  7430. + lvds-channel@0 {
  7431. + fsl,data-mapping = "spwg";
  7432. + fsl,data-width = <18>;
  7433. + status = "okay";
  7434. +
  7435. + display-timings {
  7436. + native-mode = <&timing0>;
  7437. + timing0: hsd100pxn1 {
  7438. + clock-frequency = <65000000>;
  7439. + hactive = <1024>;
  7440. + vactive = <768>;
  7441. + hback-porch = <220>;
  7442. + hfront-porch = <40>;
  7443. + vback-porch = <21>;
  7444. + vfront-porch = <7>;
  7445. + hsync-len = <60>;
  7446. + vsync-len = <10>;
  7447. + };
  7448. + };
  7449. };
  7450. };
  7451. +&pcie {
  7452. + status = "okay";
  7453. +};
  7454. +
  7455. +&pwm3 {
  7456. + pinctrl-names = "default";
  7457. + pinctrl-0 = <&pinctrl_pwm1>;
  7458. + status = "okay";
  7459. +};
  7460. +
  7461. +&spdif {
  7462. + pinctrl-names = "default";
  7463. + pinctrl-0 = <&pinctrl_spdif>;
  7464. + status = "okay";
  7465. +};
  7466. +
  7467. +&uart3 {
  7468. + pinctrl-names = "default";
  7469. + pinctrl-0 = <&pinctrl_uart3>;
  7470. + pinctrl-assert-gpios = <&max7310_b 4 GPIO_ACTIVE_HIGH>, /* CTS */
  7471. + <&max7310_c 3 GPIO_ACTIVE_HIGH>; /* RXD and TXD */
  7472. + fsl,uart-has-rtscts;
  7473. + status = "okay";
  7474. +};
  7475. +
  7476. &uart4 {
  7477. pinctrl-names = "default";
  7478. - pinctrl-0 = <&pinctrl_uart4_1>;
  7479. + pinctrl-0 = <&pinctrl_uart4>;
  7480. status = "okay";
  7481. };
  7482. &usdhc3 {
  7483. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  7484. - pinctrl-0 = <&pinctrl_usdhc3_1>;
  7485. - pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
  7486. - pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
  7487. + pinctrl-0 = <&pinctrl_usdhc3>;
  7488. + pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
  7489. + pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
  7490. cd-gpios = <&gpio6 15 0>;
  7491. wp-gpios = <&gpio1 13 0>;
  7492. status = "okay";
  7493. @@ -86,7 +645,7 @@
  7494. &weim {
  7495. pinctrl-names = "default";
  7496. - pinctrl-0 = <&pinctrl_weim_nor_1 &pinctrl_weim_cs0_1>;
  7497. + pinctrl-0 = <&pinctrl_weim_nor &pinctrl_weim_cs0>;
  7498. #address-cells = <2>;
  7499. #size-cells = <1>;
  7500. ranges = <0 0 0x08000000 0x08000000>;
  7501. @@ -102,3 +661,48 @@
  7502. 0x0000c000 0x1404a38e 0x00000000>;
  7503. };
  7504. };
  7505. +
  7506. +&ldb {
  7507. + ipu_id = <1>;
  7508. + disp_id = <0>;
  7509. + ext_ref = <1>;
  7510. + mode = "sep0";
  7511. + sec_ipu_id = <1>;
  7512. + sec_disp_id = <1>;
  7513. + status = "okay";
  7514. +};
  7515. +
  7516. +&esai {
  7517. + pinctrl-names = "default";
  7518. + pinctrl-0 = <&pinctrl_esai1>;
  7519. + status = "okay";
  7520. +};
  7521. +
  7522. +&hdmi_core {
  7523. + ipu_id = <0>;
  7524. + disp_id = <1>;
  7525. + status = "okay";
  7526. +};
  7527. +
  7528. +&hdmi_video {
  7529. + fsl,phy_reg_vlev = <0x0294>;
  7530. + fsl,phy_reg_cksymtx = <0x800d>;
  7531. + status = "okay";
  7532. +};
  7533. +
  7534. +&hdmi_audio {
  7535. + status = "okay";
  7536. +};
  7537. +
  7538. +&hdmi_cec {
  7539. + pinctrl-names = "default";
  7540. + pinctrl-0 = <&pinctrl_hdmi_cec_2>;
  7541. + status = "okay";
  7542. +};
  7543. +
  7544. +&gpc {
  7545. + fsl,cpu_pupscr_sw2iso = <0xf>;
  7546. + fsl,cpu_pupscr_sw = <0xf>;
  7547. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  7548. + fsl,cpu_pdnscr_iso = <0x1>;
  7549. +};
  7550. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
  7551. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi 1969-12-31 18:00:00.000000000 -0600
  7552. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi 2014-12-08 00:31:51.124418001 -0600
  7553. @@ -0,0 +1,427 @@
  7554. +/*
  7555. + * Copyright 2011 Freescale Semiconductor, Inc.
  7556. + * Copyright 2011 Linaro Ltd.
  7557. + *
  7558. + * The code contained herein is licensed under the GNU General Public
  7559. + * License. You may obtain a copy of the GNU General Public License
  7560. + * Version 2 or later at the following locations:
  7561. + *
  7562. + * http://www.opensource.org/licenses/gpl-license.html
  7563. + * http://www.gnu.org/copyleft/gpl.html
  7564. + */
  7565. +#include <dt-bindings/gpio/gpio.h>
  7566. +#include <dt-bindings/input/input.h>
  7567. +
  7568. +/ {
  7569. + chosen {
  7570. + stdout-path = &uart2;
  7571. + };
  7572. +
  7573. + memory {
  7574. + reg = <0x10000000 0x40000000>;
  7575. + };
  7576. +
  7577. + regulators {
  7578. + compatible = "simple-bus";
  7579. + #address-cells = <1>;
  7580. + #size-cells = <0>;
  7581. +
  7582. + reg_2p5v: regulator@0 {
  7583. + compatible = "regulator-fixed";
  7584. + reg = <0>;
  7585. + regulator-name = "2P5V";
  7586. + regulator-min-microvolt = <2500000>;
  7587. + regulator-max-microvolt = <2500000>;
  7588. + regulator-always-on;
  7589. + };
  7590. +
  7591. + reg_3p3v: regulator@1 {
  7592. + compatible = "regulator-fixed";
  7593. + reg = <1>;
  7594. + regulator-name = "3P3V";
  7595. + regulator-min-microvolt = <3300000>;
  7596. + regulator-max-microvolt = <3300000>;
  7597. + regulator-always-on;
  7598. + };
  7599. +
  7600. + reg_usb_otg_vbus: regulator@2 {
  7601. + compatible = "regulator-fixed";
  7602. + reg = <2>;
  7603. + regulator-name = "usb_otg_vbus";
  7604. + regulator-min-microvolt = <5000000>;
  7605. + regulator-max-microvolt = <5000000>;
  7606. + gpio = <&gpio3 22 0>;
  7607. + enable-active-high;
  7608. + };
  7609. + };
  7610. +
  7611. + gpio-keys {
  7612. + compatible = "gpio-keys";
  7613. + pinctrl-names = "default";
  7614. + pinctrl-0 = <&pinctrl_gpio_keys>;
  7615. +
  7616. + power {
  7617. + label = "Power Button";
  7618. + gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
  7619. + linux,code = <KEY_POWER>;
  7620. + gpio-key,wakeup;
  7621. + };
  7622. +
  7623. + menu {
  7624. + label = "Menu";
  7625. + gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
  7626. + linux,code = <KEY_MENU>;
  7627. + };
  7628. +
  7629. + home {
  7630. + label = "Home";
  7631. + gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
  7632. + linux,code = <KEY_HOME>;
  7633. + };
  7634. +
  7635. + back {
  7636. + label = "Back";
  7637. + gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
  7638. + linux,code = <KEY_BACK>;
  7639. + };
  7640. +
  7641. + volume-up {
  7642. + label = "Volume Up";
  7643. + gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
  7644. + linux,code = <KEY_VOLUMEUP>;
  7645. + };
  7646. +
  7647. + volume-down {
  7648. + label = "Volume Down";
  7649. + gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
  7650. + linux,code = <KEY_VOLUMEDOWN>;
  7651. + };
  7652. + };
  7653. +
  7654. + sound {
  7655. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  7656. + "fsl,imx-audio-sgtl5000";
  7657. + model = "imx6q-sabrelite-sgtl5000";
  7658. + ssi-controller = <&ssi1>;
  7659. + audio-codec = <&codec>;
  7660. + audio-routing =
  7661. + "MIC_IN", "Mic Jack",
  7662. + "Mic Jack", "Mic Bias",
  7663. + "Headphone Jack", "HP_OUT";
  7664. + mux-int-port = <1>;
  7665. + mux-ext-port = <4>;
  7666. + };
  7667. +
  7668. + backlight_lcd {
  7669. + compatible = "pwm-backlight";
  7670. + pwms = <&pwm1 0 5000000>;
  7671. + brightness-levels = <0 4 8 16 32 64 128 255>;
  7672. + default-brightness-level = <7>;
  7673. + power-supply = <&reg_3p3v>;
  7674. + status = "okay";
  7675. + };
  7676. +
  7677. + backlight_lvds {
  7678. + compatible = "pwm-backlight";
  7679. + pwms = <&pwm4 0 5000000>;
  7680. + brightness-levels = <0 4 8 16 32 64 128 255>;
  7681. + default-brightness-level = <7>;
  7682. + power-supply = <&reg_3p3v>;
  7683. + status = "okay";
  7684. + };
  7685. +};
  7686. +
  7687. +&audmux {
  7688. + pinctrl-names = "default";
  7689. + pinctrl-0 = <&pinctrl_audmux>;
  7690. + status = "okay";
  7691. +};
  7692. +
  7693. +&ecspi1 {
  7694. + fsl,spi-num-chipselects = <1>;
  7695. + cs-gpios = <&gpio3 19 0>;
  7696. + pinctrl-names = "default";
  7697. + pinctrl-0 = <&pinctrl_ecspi1>;
  7698. + status = "okay";
  7699. +
  7700. + flash: m25p80@0 {
  7701. + compatible = "sst,sst25vf016b";
  7702. + spi-max-frequency = <20000000>;
  7703. + reg = <0>;
  7704. + };
  7705. +};
  7706. +
  7707. +&fec {
  7708. + pinctrl-names = "default";
  7709. + pinctrl-0 = <&pinctrl_enet>;
  7710. + phy-mode = "rgmii";
  7711. + phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
  7712. + txen-skew-ps = <0>;
  7713. + txc-skew-ps = <3000>;
  7714. + rxdv-skew-ps = <0>;
  7715. + rxc-skew-ps = <3000>;
  7716. + rxd0-skew-ps = <0>;
  7717. + rxd1-skew-ps = <0>;
  7718. + rxd2-skew-ps = <0>;
  7719. + rxd3-skew-ps = <0>;
  7720. + txd0-skew-ps = <0>;
  7721. + txd1-skew-ps = <0>;
  7722. + txd2-skew-ps = <0>;
  7723. + txd3-skew-ps = <0>;
  7724. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  7725. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  7726. + status = "okay";
  7727. +};
  7728. +
  7729. +&i2c1 {
  7730. + clock-frequency = <100000>;
  7731. + pinctrl-names = "default";
  7732. + pinctrl-0 = <&pinctrl_i2c1>;
  7733. + status = "okay";
  7734. +
  7735. + codec: sgtl5000@0a {
  7736. + compatible = "fsl,sgtl5000";
  7737. + reg = <0x0a>;
  7738. + clocks = <&clks 201>;
  7739. + VDDA-supply = <&reg_2p5v>;
  7740. + VDDIO-supply = <&reg_3p3v>;
  7741. + };
  7742. +};
  7743. +
  7744. +&iomuxc {
  7745. + pinctrl-names = "default";
  7746. + pinctrl-0 = <&pinctrl_hog>;
  7747. +
  7748. + imx6q-sabrelite {
  7749. + pinctrl_hog: hoggrp {
  7750. + fsl,pins = <
  7751. + /* SGTL5000 sys_mclk */
  7752. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x030b0
  7753. + >;
  7754. + };
  7755. +
  7756. + pinctrl_audmux: audmuxgrp {
  7757. + fsl,pins = <
  7758. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  7759. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  7760. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  7761. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  7762. + >;
  7763. + };
  7764. +
  7765. + pinctrl_ecspi1: ecspi1grp {
  7766. + fsl,pins = <
  7767. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  7768. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  7769. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  7770. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x000b1 /* CS */
  7771. + >;
  7772. + };
  7773. +
  7774. + pinctrl_enet: enetgrp {
  7775. + fsl,pins = <
  7776. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0
  7777. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0
  7778. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0
  7779. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0
  7780. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0
  7781. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0
  7782. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0
  7783. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0
  7784. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0
  7785. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  7786. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  7787. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  7788. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  7789. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  7790. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  7791. + /* Phy reset */
  7792. + MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x000b0
  7793. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  7794. + >;
  7795. + };
  7796. +
  7797. + pinctrl_gpio_keys: gpio_keysgrp {
  7798. + fsl,pins = <
  7799. + /* Power Button */
  7800. + MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
  7801. + /* Menu Button */
  7802. + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
  7803. + /* Home Button */
  7804. + MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
  7805. + /* Back Button */
  7806. + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
  7807. + /* Volume Up Button */
  7808. + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0
  7809. + /* Volume Down Button */
  7810. + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
  7811. + >;
  7812. + };
  7813. +
  7814. + pinctrl_i2c1: i2c1grp {
  7815. + fsl,pins = <
  7816. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  7817. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  7818. + >;
  7819. + };
  7820. +
  7821. + pinctrl_pwm1: pwm1grp {
  7822. + fsl,pins = <
  7823. + MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  7824. + >;
  7825. + };
  7826. +
  7827. + pinctrl_pwm3: pwm3grp {
  7828. + fsl,pins = <
  7829. + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
  7830. + >;
  7831. + };
  7832. +
  7833. + pinctrl_pwm4: pwm4grp {
  7834. + fsl,pins = <
  7835. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  7836. + >;
  7837. + };
  7838. +
  7839. + pinctrl_uart1: uart1grp {
  7840. + fsl,pins = <
  7841. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  7842. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  7843. + >;
  7844. + };
  7845. +
  7846. + pinctrl_uart2: uart2grp {
  7847. + fsl,pins = <
  7848. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  7849. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  7850. + >;
  7851. + };
  7852. +
  7853. + pinctrl_usbotg: usbotggrp {
  7854. + fsl,pins = <
  7855. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  7856. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  7857. + /* power enable, high active */
  7858. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x000b0
  7859. + >;
  7860. + };
  7861. +
  7862. + pinctrl_usdhc3: usdhc3grp {
  7863. + fsl,pins = <
  7864. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  7865. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  7866. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  7867. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  7868. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  7869. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  7870. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
  7871. + MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0 /* WP */
  7872. + >;
  7873. + };
  7874. +
  7875. + pinctrl_usdhc4: usdhc4grp {
  7876. + fsl,pins = <
  7877. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  7878. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  7879. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  7880. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  7881. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  7882. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  7883. + MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /* CD */
  7884. + >;
  7885. + };
  7886. + };
  7887. +};
  7888. +
  7889. +&ldb {
  7890. + status = "okay";
  7891. +
  7892. + lvds-channel@0 {
  7893. + fsl,data-mapping = "spwg";
  7894. + fsl,data-width = <18>;
  7895. + status = "okay";
  7896. +
  7897. + display-timings {
  7898. + native-mode = <&timing0>;
  7899. + timing0: hsd100pxn1 {
  7900. + clock-frequency = <65000000>;
  7901. + hactive = <1024>;
  7902. + vactive = <768>;
  7903. + hback-porch = <220>;
  7904. + hfront-porch = <40>;
  7905. + vback-porch = <21>;
  7906. + vfront-porch = <7>;
  7907. + hsync-len = <60>;
  7908. + vsync-len = <10>;
  7909. + };
  7910. + };
  7911. + };
  7912. +};
  7913. +
  7914. +&pcie {
  7915. + status = "okay";
  7916. +};
  7917. +
  7918. +&pwm1 {
  7919. + pinctrl-names = "default";
  7920. + pinctrl-0 = <&pinctrl_pwm1>;
  7921. + status = "okay";
  7922. +};
  7923. +
  7924. +&pwm3 {
  7925. + pinctrl-names = "default";
  7926. + pinctrl-0 = <&pinctrl_pwm3>;
  7927. + status = "okay";
  7928. +};
  7929. +
  7930. +&pwm4 {
  7931. + pinctrl-names = "default";
  7932. + pinctrl-0 = <&pinctrl_pwm4>;
  7933. + status = "okay";
  7934. +};
  7935. +
  7936. +&ssi1 {
  7937. + fsl,mode = "i2s-slave";
  7938. + status = "okay";
  7939. +};
  7940. +
  7941. +&uart1 {
  7942. + pinctrl-names = "default";
  7943. + pinctrl-0 = <&pinctrl_uart1>;
  7944. + status = "okay";
  7945. +};
  7946. +
  7947. +&uart2 {
  7948. + pinctrl-names = "default";
  7949. + pinctrl-0 = <&pinctrl_uart2>;
  7950. + status = "okay";
  7951. +};
  7952. +
  7953. +&usbh1 {
  7954. + status = "okay";
  7955. +};
  7956. +
  7957. +&usbotg {
  7958. + vbus-supply = <&reg_usb_otg_vbus>;
  7959. + pinctrl-names = "default";
  7960. + pinctrl-0 = <&pinctrl_usbotg>;
  7961. + disable-over-current;
  7962. + status = "okay";
  7963. +};
  7964. +
  7965. +&usdhc3 {
  7966. + pinctrl-names = "default";
  7967. + pinctrl-0 = <&pinctrl_usdhc3>;
  7968. + cd-gpios = <&gpio7 0 0>;
  7969. + wp-gpios = <&gpio7 1 0>;
  7970. + vmmc-supply = <&reg_3p3v>;
  7971. + status = "okay";
  7972. +};
  7973. +
  7974. +&usdhc4 {
  7975. + pinctrl-names = "default";
  7976. + pinctrl-0 = <&pinctrl_usdhc4>;
  7977. + cd-gpios = <&gpio2 6 0>;
  7978. + vmmc-supply = <&reg_3p3v>;
  7979. + status = "okay";
  7980. +};
  7981. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-sabresd.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
  7982. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-sabresd.dtsi 2014-07-28 10:07:25.000000000 -0500
  7983. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabresd.dtsi 2014-12-08 00:31:51.124418001 -0600
  7984. @@ -10,16 +10,33 @@
  7985. * http://www.gnu.org/copyleft/gpl.html
  7986. */
  7987. +#include <dt-bindings/gpio/gpio.h>
  7988. +#include <dt-bindings/input/input.h>
  7989. +
  7990. / {
  7991. + aliases {
  7992. + mxcfb0 = &mxcfb1;
  7993. + mxcfb1 = &mxcfb2;
  7994. + mxcfb2 = &mxcfb3;
  7995. + mxcfb3 = &mxcfb4;
  7996. + };
  7997. +
  7998. + chosen {
  7999. + stdout-path = &uart1;
  8000. + };
  8001. +
  8002. memory {
  8003. reg = <0x10000000 0x40000000>;
  8004. };
  8005. regulators {
  8006. compatible = "simple-bus";
  8007. + #address-cells = <1>;
  8008. + #size-cells = <0>;
  8009. - reg_usb_otg_vbus: usb_otg_vbus {
  8010. + reg_usb_otg_vbus: regulator@0 {
  8011. compatible = "regulator-fixed";
  8012. + reg = <0>;
  8013. regulator-name = "usb_otg_vbus";
  8014. regulator-min-microvolt = <5000000>;
  8015. regulator-max-microvolt = <5000000>;
  8016. @@ -27,8 +44,9 @@
  8017. enable-active-high;
  8018. };
  8019. - reg_usb_h1_vbus: usb_h1_vbus {
  8020. + reg_usb_h1_vbus: regulator@1 {
  8021. compatible = "regulator-fixed";
  8022. + reg = <1>;
  8023. regulator-name = "usb_h1_vbus";
  8024. regulator-min-microvolt = <5000000>;
  8025. regulator-max-microvolt = <5000000>;
  8026. @@ -36,29 +54,46 @@
  8027. enable-active-high;
  8028. };
  8029. - reg_audio: wm8962_supply {
  8030. + reg_audio: regulator@2 {
  8031. compatible = "regulator-fixed";
  8032. + reg = <2>;
  8033. regulator-name = "wm8962-supply";
  8034. gpio = <&gpio4 10 0>;
  8035. enable-active-high;
  8036. };
  8037. +
  8038. + reg_mipi_dsi_pwr_on: mipi_dsi_pwr_on {
  8039. + compatible = "regulator-fixed";
  8040. + regulator-name = "mipi_dsi_pwr_on";
  8041. + gpio = <&gpio6 14 0>;
  8042. + enable-active-high;
  8043. + };
  8044. };
  8045. gpio-keys {
  8046. compatible = "gpio-keys";
  8047. + pinctrl-names = "default";
  8048. + pinctrl-0 = <&pinctrl_gpio_keys>;
  8049. +
  8050. + power {
  8051. + label = "Power Button";
  8052. + gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
  8053. + gpio-key,wakeup;
  8054. + linux,code = <KEY_POWER>;
  8055. + };
  8056. volume-up {
  8057. label = "Volume Up";
  8058. - gpios = <&gpio1 4 0>;
  8059. + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
  8060. gpio-key,wakeup;
  8061. - linux,code = <115>; /* KEY_VOLUMEUP */
  8062. + linux,code = <KEY_VOLUMEUP>;
  8063. };
  8064. volume-down {
  8065. label = "Volume Down";
  8066. - gpios = <&gpio1 5 0>;
  8067. + gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
  8068. gpio-key,wakeup;
  8069. - linux,code = <114>; /* KEY_VOLUMEDOWN */
  8070. + linux,code = <KEY_VOLUMEDOWN>;
  8071. };
  8072. };
  8073. @@ -88,11 +123,107 @@
  8074. default-brightness-level = <7>;
  8075. status = "okay";
  8076. };
  8077. +
  8078. + leds {
  8079. + compatible = "gpio-leds";
  8080. + pinctrl-names = "default";
  8081. + pinctrl-0 = <&pinctrl_gpio_leds>;
  8082. +
  8083. + red {
  8084. + gpios = <&gpio1 2 0>;
  8085. + default-state = "on";
  8086. + };
  8087. + };
  8088. +
  8089. + sound-hdmi {
  8090. + compatible = "fsl,imx6q-audio-hdmi",
  8091. + "fsl,imx-audio-hdmi";
  8092. + model = "imx-audio-hdmi";
  8093. + hdmi-controller = <&hdmi_audio>;
  8094. + };
  8095. +
  8096. + mxcfb1: fb@0 {
  8097. + compatible = "fsl,mxc_sdc_fb";
  8098. + disp_dev = "ldb";
  8099. + interface_pix_fmt = "RGB666";
  8100. + mode_str ="LDB-XGA";
  8101. + default_bpp = <16>;
  8102. + int_clk = <0>;
  8103. + late_init = <0>;
  8104. + status = "disabled";
  8105. + };
  8106. +
  8107. + mxcfb2: fb@1 {
  8108. + compatible = "fsl,mxc_sdc_fb";
  8109. + disp_dev = "hdmi";
  8110. + interface_pix_fmt = "RGB24";
  8111. + mode_str ="1920x1080M@60";
  8112. + default_bpp = <24>;
  8113. + int_clk = <0>;
  8114. + late_init = <0>;
  8115. + status = "disabled";
  8116. + };
  8117. +
  8118. + mxcfb3: fb@2 {
  8119. + compatible = "fsl,mxc_sdc_fb";
  8120. + disp_dev = "lcd";
  8121. + interface_pix_fmt = "RGB565";
  8122. + mode_str ="CLAA-WVGA";
  8123. + default_bpp = <16>;
  8124. + int_clk = <0>;
  8125. + late_init = <0>;
  8126. + status = "disabled";
  8127. + };
  8128. +
  8129. + mxcfb4: fb@3 {
  8130. + compatible = "fsl,mxc_sdc_fb";
  8131. + disp_dev = "ldb";
  8132. + interface_pix_fmt = "RGB666";
  8133. + mode_str ="LDB-XGA";
  8134. + default_bpp = <16>;
  8135. + int_clk = <0>;
  8136. + late_init = <0>;
  8137. + status = "disabled";
  8138. + };
  8139. +
  8140. + lcd@0 {
  8141. + compatible = "fsl,lcd";
  8142. + ipu_id = <0>;
  8143. + disp_id = <0>;
  8144. + default_ifmt = "RGB565";
  8145. + pinctrl-names = "default";
  8146. + pinctrl-0 = <&pinctrl_ipu1>;
  8147. + status = "okay";
  8148. + };
  8149. +
  8150. + backlight {
  8151. + compatible = "pwm-backlight";
  8152. + pwms = <&pwm1 0 5000000>;
  8153. + brightness-levels = <0 4 8 16 32 64 128 255>;
  8154. + default-brightness-level = <7>;
  8155. + };
  8156. +
  8157. + v4l2_out {
  8158. + compatible = "fsl,mxc_v4l2_output";
  8159. + status = "okay";
  8160. + };
  8161. +
  8162. + lvds_cabc_ctrl {
  8163. + lvds0-gpios = <&gpio6 15 0>;
  8164. + lvds1-gpios = <&gpio6 16 0>;
  8165. + };
  8166. +
  8167. + mipi_dsi_reset: mipi-dsi-reset {
  8168. + compatible = "gpio-reset";
  8169. + reset-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
  8170. + reset-delay-us = <50>;
  8171. + #reset-cells = <0>;
  8172. + };
  8173. };
  8174. &audmux {
  8175. pinctrl-names = "default";
  8176. - pinctrl-0 = <&pinctrl_audmux_2>;
  8177. + pinctrl-0 = <&pinctrl_audmux>;
  8178. status = "okay";
  8179. };
  8180. @@ -100,7 +231,7 @@
  8181. fsl,spi-num-chipselects = <1>;
  8182. cs-gpios = <&gpio4 9 0>;
  8183. pinctrl-names = "default";
  8184. - pinctrl-0 = <&pinctrl_ecspi1_2>;
  8185. + pinctrl-0 = <&pinctrl_ecspi1>;
  8186. status = "okay";
  8187. flash: m25p80@0 {
  8188. @@ -114,7 +245,7 @@
  8189. &fec {
  8190. pinctrl-names = "default";
  8191. - pinctrl-0 = <&pinctrl_enet_1>;
  8192. + pinctrl-0 = <&pinctrl_enet>;
  8193. phy-mode = "rgmii";
  8194. phy-reset-gpios = <&gpio1 25 0>;
  8195. status = "okay";
  8196. @@ -123,7 +254,7 @@
  8197. &i2c1 {
  8198. clock-frequency = <100000>;
  8199. pinctrl-names = "default";
  8200. - pinctrl-0 = <&pinctrl_i2c1_2>;
  8201. + pinctrl-0 = <&pinctrl_i2c1>;
  8202. status = "okay";
  8203. codec: wm8962@1a {
  8204. @@ -149,10 +280,121 @@
  8205. };
  8206. };
  8207. +&i2c2 {
  8208. + clock-frequency = <100000>;
  8209. + pinctrl-names = "default";
  8210. + pinctrl-0 = <&pinctrl_i2c2>;
  8211. + status = "okay";
  8212. +
  8213. + hdmi: edid@50 {
  8214. + compatible = "fsl,imx6-hdmi-i2c";
  8215. + reg = <0x50>;
  8216. + };
  8217. +
  8218. + pmic: pfuze100@08 {
  8219. + compatible = "fsl,pfuze100";
  8220. + reg = <0x08>;
  8221. +
  8222. + regulators {
  8223. + sw1a_reg: sw1ab {
  8224. + regulator-min-microvolt = <300000>;
  8225. + regulator-max-microvolt = <1875000>;
  8226. + regulator-boot-on;
  8227. + regulator-always-on;
  8228. + regulator-ramp-delay = <6250>;
  8229. + };
  8230. +
  8231. + sw1c_reg: sw1c {
  8232. + regulator-min-microvolt = <300000>;
  8233. + regulator-max-microvolt = <1875000>;
  8234. + regulator-boot-on;
  8235. + regulator-always-on;
  8236. + regulator-ramp-delay = <6250>;
  8237. + };
  8238. +
  8239. + sw2_reg: sw2 {
  8240. + regulator-min-microvolt = <800000>;
  8241. + regulator-max-microvolt = <3300000>;
  8242. + regulator-boot-on;
  8243. + regulator-always-on;
  8244. + };
  8245. +
  8246. + sw3a_reg: sw3a {
  8247. + regulator-min-microvolt = <400000>;
  8248. + regulator-max-microvolt = <1975000>;
  8249. + regulator-boot-on;
  8250. + regulator-always-on;
  8251. + };
  8252. +
  8253. + sw3b_reg: sw3b {
  8254. + regulator-min-microvolt = <400000>;
  8255. + regulator-max-microvolt = <1975000>;
  8256. + regulator-boot-on;
  8257. + regulator-always-on;
  8258. + };
  8259. +
  8260. + sw4_reg: sw4 {
  8261. + regulator-min-microvolt = <800000>;
  8262. + regulator-max-microvolt = <3300000>;
  8263. + };
  8264. +
  8265. + swbst_reg: swbst {
  8266. + regulator-min-microvolt = <5000000>;
  8267. + regulator-max-microvolt = <5150000>;
  8268. + };
  8269. +
  8270. + snvs_reg: vsnvs {
  8271. + regulator-min-microvolt = <1000000>;
  8272. + regulator-max-microvolt = <3000000>;
  8273. + regulator-boot-on;
  8274. + regulator-always-on;
  8275. + };
  8276. +
  8277. + vref_reg: vrefddr {
  8278. + regulator-boot-on;
  8279. + regulator-always-on;
  8280. + };
  8281. +
  8282. + vgen1_reg: vgen1 {
  8283. + regulator-min-microvolt = <800000>;
  8284. + regulator-max-microvolt = <1550000>;
  8285. + };
  8286. +
  8287. + vgen2_reg: vgen2 {
  8288. + regulator-min-microvolt = <800000>;
  8289. + regulator-max-microvolt = <1550000>;
  8290. + };
  8291. +
  8292. + vgen3_reg: vgen3 {
  8293. + regulator-min-microvolt = <1800000>;
  8294. + regulator-max-microvolt = <3300000>;
  8295. + };
  8296. +
  8297. + vgen4_reg: vgen4 {
  8298. + regulator-min-microvolt = <1800000>;
  8299. + regulator-max-microvolt = <3300000>;
  8300. + regulator-always-on;
  8301. + };
  8302. +
  8303. + vgen5_reg: vgen5 {
  8304. + regulator-min-microvolt = <1800000>;
  8305. + regulator-max-microvolt = <3300000>;
  8306. + regulator-always-on;
  8307. + };
  8308. +
  8309. + vgen6_reg: vgen6 {
  8310. + regulator-min-microvolt = <1800000>;
  8311. + regulator-max-microvolt = <3300000>;
  8312. + regulator-always-on;
  8313. + };
  8314. + };
  8315. + };
  8316. +};
  8317. +
  8318. &i2c3 {
  8319. clock-frequency = <100000>;
  8320. pinctrl-names = "default";
  8321. - pinctrl-0 = <&pinctrl_i2c3_2>;
  8322. + pinctrl-0 = <&pinctrl_i2c3>;
  8323. status = "okay";
  8324. egalax_ts@04 {
  8325. @@ -168,11 +410,9 @@
  8326. pinctrl-names = "default";
  8327. pinctrl-0 = <&pinctrl_hog>;
  8328. - hog {
  8329. + imx6qdl-sabresd {
  8330. pinctrl_hog: hoggrp {
  8331. fsl,pins = <
  8332. - MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x80000000
  8333. - MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x80000000
  8334. MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x80000000
  8335. MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x80000000
  8336. MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000
  8337. @@ -182,6 +422,202 @@
  8338. MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
  8339. MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000
  8340. MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
  8341. + MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
  8342. + MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x80000000
  8343. + MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
  8344. + MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
  8345. + >;
  8346. + };
  8347. +
  8348. + pinctrl_audmux: audmuxgrp {
  8349. + fsl,pins = <
  8350. + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
  8351. + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
  8352. + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
  8353. + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
  8354. + >;
  8355. + };
  8356. +
  8357. + pinctrl_ecspi1: ecspi1grp {
  8358. + fsl,pins = <
  8359. + MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1
  8360. + MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1
  8361. + MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1
  8362. + >;
  8363. + };
  8364. +
  8365. + pinctrl_enet: enetgrp {
  8366. + fsl,pins = <
  8367. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  8368. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  8369. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  8370. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  8371. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  8372. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  8373. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  8374. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  8375. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  8376. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  8377. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  8378. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  8379. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  8380. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  8381. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  8382. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  8383. + >;
  8384. + };
  8385. +
  8386. + pinctrl_gpio_keys: gpio_keysgrp {
  8387. + fsl,pins = <
  8388. + MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000
  8389. + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x80000000
  8390. + MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x80000000
  8391. + >;
  8392. + };
  8393. +
  8394. + pinctrl_hdmi_cec: hdmi_cecgrp {
  8395. + fsl,pins = <
  8396. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  8397. + >;
  8398. + };
  8399. +
  8400. + pinctrl_hdmi_hdcp: hdmi_hdcpgrp {
  8401. + fsl,pins = <
  8402. + MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
  8403. + MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
  8404. + >;
  8405. + };
  8406. +
  8407. + pinctrl_i2c1: i2c1grp {
  8408. + fsl,pins = <
  8409. + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
  8410. + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
  8411. + >;
  8412. + };
  8413. +
  8414. + pinctrl_i2c2: i2c2grp {
  8415. + fsl,pins = <
  8416. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  8417. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  8418. + >;
  8419. + };
  8420. +
  8421. + pinctrl_i2c3: i2c3grp {
  8422. + fsl,pins = <
  8423. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  8424. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  8425. + >;
  8426. + };
  8427. +
  8428. + pinctrl_ipu1: ipu1grp {
  8429. + fsl,pins = <
  8430. + MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
  8431. + MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
  8432. + MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
  8433. + MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
  8434. + MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x80000000
  8435. + MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10
  8436. + MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
  8437. + MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
  8438. + MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
  8439. + MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
  8440. + MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
  8441. + MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
  8442. + MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
  8443. + MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
  8444. + MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
  8445. + MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
  8446. + MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
  8447. + MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
  8448. + MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
  8449. + MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
  8450. + MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
  8451. + MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
  8452. + MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
  8453. + MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
  8454. + MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
  8455. + MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
  8456. + MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
  8457. + MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
  8458. + MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
  8459. + >;
  8460. + };
  8461. +
  8462. + pinctrl_pcie: pciegrp {
  8463. + fsl,pins = <
  8464. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000
  8465. + >;
  8466. + };
  8467. +
  8468. + pinctrl_pwm1: pwm1grp {
  8469. + fsl,pins = <
  8470. + MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  8471. + >;
  8472. + };
  8473. +
  8474. + pinctrl_uart1: uart1grp {
  8475. + fsl,pins = <
  8476. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  8477. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  8478. + >;
  8479. + };
  8480. +
  8481. + pinctrl_usbotg: usbotggrp {
  8482. + fsl,pins = <
  8483. + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  8484. + >;
  8485. + };
  8486. +
  8487. + pinctrl_usdhc2: usdhc2grp {
  8488. + fsl,pins = <
  8489. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  8490. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  8491. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  8492. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  8493. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  8494. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  8495. + MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x17059
  8496. + MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x17059
  8497. + MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x17059
  8498. + MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x17059
  8499. + >;
  8500. + };
  8501. +
  8502. + pinctrl_usdhc3: usdhc3grp {
  8503. + fsl,pins = <
  8504. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  8505. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  8506. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  8507. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  8508. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  8509. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  8510. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
  8511. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
  8512. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
  8513. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
  8514. + >;
  8515. + };
  8516. +
  8517. + pinctrl_usdhc4: usdhc4grp {
  8518. + fsl,pins = <
  8519. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  8520. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  8521. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  8522. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  8523. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  8524. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  8525. + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  8526. + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  8527. + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  8528. + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  8529. + >;
  8530. + };
  8531. + };
  8532. +
  8533. + gpio_leds {
  8534. + pinctrl_gpio_leds: gpioledsgrp {
  8535. + fsl,pins = <
  8536. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000
  8537. >;
  8538. };
  8539. };
  8540. @@ -212,9 +648,33 @@
  8541. };
  8542. };
  8543. +&pcie {
  8544. + pinctrl-names = "default";
  8545. + pinctrl-0 = <&pinctrl_pcie>;
  8546. + reset-gpio = <&gpio7 12 0>;
  8547. + status = "okay";
  8548. +};
  8549. +
  8550. +&pcie {
  8551. + power-on-gpio = <&gpio3 19 0>;
  8552. + reset-gpio = <&gpio7 12 0>;
  8553. + status = "okay";
  8554. +};
  8555. +
  8556. +
  8557. &pwm1 {
  8558. pinctrl-names = "default";
  8559. - pinctrl-0 = <&pinctrl_pwm0_1>;
  8560. + pinctrl-0 = <&pinctrl_pwm1>;
  8561. + status = "okay";
  8562. +};
  8563. +
  8564. +&ldb {
  8565. + ipu_id = <1>;
  8566. + disp_id = <1>;
  8567. + ext_ref = <1>;
  8568. + mode = "sep1";
  8569. + sec_ipu_id = <1>;
  8570. + sec_disp_id = <0>;
  8571. status = "okay";
  8572. };
  8573. @@ -225,7 +685,16 @@
  8574. &uart1 {
  8575. pinctrl-names = "default";
  8576. - pinctrl-0 = <&pinctrl_uart1_1>;
  8577. + pinctrl-0 = <&pinctrl_uart1>;
  8578. + status = "okay";
  8579. +};
  8580. +
  8581. +&mipi_dsi {
  8582. + dev_id = <0>;
  8583. + disp_id = <0>;
  8584. + lcd_panel = "TRULY-WVGA";
  8585. + disp-power-on-supply = <&reg_mipi_dsi_pwr_on>;
  8586. + resets = <&mipi_dsi_reset>;
  8587. status = "okay";
  8588. };
  8589. @@ -237,14 +706,14 @@
  8590. &usbotg {
  8591. vbus-supply = <&reg_usb_otg_vbus>;
  8592. pinctrl-names = "default";
  8593. - pinctrl-0 = <&pinctrl_usbotg_2>;
  8594. + pinctrl-0 = <&pinctrl_usbotg>;
  8595. disable-over-current;
  8596. status = "okay";
  8597. };
  8598. &usdhc2 {
  8599. pinctrl-names = "default";
  8600. - pinctrl-0 = <&pinctrl_usdhc2_1>;
  8601. + pinctrl-0 = <&pinctrl_usdhc2>;
  8602. bus-width = <8>;
  8603. cd-gpios = <&gpio2 2 0>;
  8604. wp-gpios = <&gpio2 3 0>;
  8605. @@ -253,9 +722,47 @@
  8606. &usdhc3 {
  8607. pinctrl-names = "default";
  8608. - pinctrl-0 = <&pinctrl_usdhc3_1>;
  8609. + pinctrl-0 = <&pinctrl_usdhc3>;
  8610. bus-width = <8>;
  8611. cd-gpios = <&gpio2 0 0>;
  8612. wp-gpios = <&gpio2 1 0>;
  8613. status = "okay";
  8614. };
  8615. +
  8616. +&usdhc4 {
  8617. + pinctrl-names = "default";
  8618. + pinctrl-0 = <&pinctrl_usdhc4>;
  8619. + bus-width = <8>;
  8620. + non-removable;
  8621. + no-1-8-v;
  8622. + status = "okay";
  8623. +};
  8624. +
  8625. +&hdmi_core {
  8626. + ipu_id = <0>;
  8627. + disp_id = <0>;
  8628. + status = "okay";
  8629. +};
  8630. +
  8631. +&hdmi_video {
  8632. + fsl,phy_reg_vlev = <0x0294>;
  8633. + fsl,phy_reg_cksymtx = <0x800d>;
  8634. + status = "okay";
  8635. +};
  8636. +
  8637. +&hdmi_audio {
  8638. + status = "okay";
  8639. +};
  8640. +
  8641. +&hdmi_cec {
  8642. + pinctrl-names = "default";
  8643. + pinctrl-0 = <&pinctrl_hdmi_cec>;
  8644. + status = "okay";
  8645. +};
  8646. +
  8647. +&gpc {
  8648. + fsl,cpu_pupscr_sw2iso = <0xf>;
  8649. + fsl,cpu_pupscr_sw = <0xf>;
  8650. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  8651. + fsl,cpu_pdnscr_iso = <0x1>;
  8652. +};
  8653. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6qdl-wandboard.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
  8654. --- linux-3.14.14/arch/arm/boot/dts/imx6qdl-wandboard.dtsi 2014-07-28 10:07:25.000000000 -0500
  8655. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-wandboard.dtsi 2014-12-08 00:31:51.124418001 -0600
  8656. @@ -12,17 +12,21 @@
  8657. / {
  8658. regulators {
  8659. compatible = "simple-bus";
  8660. + #address-cells = <1>;
  8661. + #size-cells = <0>;
  8662. - reg_2p5v: 2p5v {
  8663. + reg_2p5v: regulator@0 {
  8664. compatible = "regulator-fixed";
  8665. + reg = <0>;
  8666. regulator-name = "2P5V";
  8667. regulator-min-microvolt = <2500000>;
  8668. regulator-max-microvolt = <2500000>;
  8669. regulator-always-on;
  8670. };
  8671. - reg_3p3v: 3p3v {
  8672. + reg_3p3v: regulator@1 {
  8673. compatible = "regulator-fixed";
  8674. + reg = <1>;
  8675. regulator-name = "3P3V";
  8676. regulator-min-microvolt = <3300000>;
  8677. regulator-max-microvolt = <3300000>;
  8678. @@ -54,14 +58,14 @@
  8679. &audmux {
  8680. pinctrl-names = "default";
  8681. - pinctrl-0 = <&pinctrl_audmux_2>;
  8682. + pinctrl-0 = <&pinctrl_audmux>;
  8683. status = "okay";
  8684. };
  8685. &i2c2 {
  8686. clock-frequency = <100000>;
  8687. pinctrl-names = "default";
  8688. - pinctrl-0 = <&pinctrl_i2c2_2>;
  8689. + pinctrl-0 = <&pinctrl_i2c2>;
  8690. status = "okay";
  8691. codec: sgtl5000@0a {
  8692. @@ -77,7 +81,7 @@
  8693. pinctrl-names = "default";
  8694. pinctrl-0 = <&pinctrl_hog>;
  8695. - hog {
  8696. + imx6qdl-wandboard {
  8697. pinctrl_hog: hoggrp {
  8698. fsl,pins = <
  8699. MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0
  8700. @@ -91,20 +95,121 @@
  8701. MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000
  8702. >;
  8703. };
  8704. +
  8705. + pinctrl_audmux: audmuxgrp {
  8706. + fsl,pins = <
  8707. + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
  8708. + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
  8709. + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
  8710. + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
  8711. + >;
  8712. + };
  8713. +
  8714. + pinctrl_enet: enetgrp {
  8715. + fsl,pins = <
  8716. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  8717. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  8718. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  8719. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  8720. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  8721. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  8722. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  8723. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  8724. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  8725. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  8726. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  8727. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  8728. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  8729. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  8730. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  8731. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  8732. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  8733. + >;
  8734. + };
  8735. +
  8736. + pinctrl_i2c2: i2c2grp {
  8737. + fsl,pins = <
  8738. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  8739. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  8740. + >;
  8741. + };
  8742. +
  8743. + pinctrl_spdif: spdifgrp {
  8744. + fsl,pins = <
  8745. + MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1b0b0
  8746. + >;
  8747. + };
  8748. +
  8749. + pinctrl_uart1: uart1grp {
  8750. + fsl,pins = <
  8751. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  8752. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  8753. + >;
  8754. + };
  8755. +
  8756. + pinctrl_uart3: uart3grp {
  8757. + fsl,pins = <
  8758. + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  8759. + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  8760. + MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1
  8761. + MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  8762. + >;
  8763. + };
  8764. +
  8765. + pinctrl_usbotg: usbotggrp {
  8766. + fsl,pins = <
  8767. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  8768. + >;
  8769. + };
  8770. +
  8771. + pinctrl_usdhc1: usdhc1grp {
  8772. + fsl,pins = <
  8773. + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  8774. + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  8775. + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  8776. + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  8777. + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  8778. + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  8779. + >;
  8780. + };
  8781. +
  8782. + pinctrl_usdhc2: usdhc2grp {
  8783. + fsl,pins = <
  8784. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  8785. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  8786. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  8787. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  8788. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  8789. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  8790. + >;
  8791. + };
  8792. +
  8793. + pinctrl_usdhc3: usdhc3grp {
  8794. + fsl,pins = <
  8795. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  8796. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  8797. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  8798. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  8799. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  8800. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  8801. + >;
  8802. + };
  8803. };
  8804. };
  8805. &fec {
  8806. pinctrl-names = "default";
  8807. - pinctrl-0 = <&pinctrl_enet_1>;
  8808. + pinctrl-0 = <&pinctrl_enet>;
  8809. phy-mode = "rgmii";
  8810. phy-reset-gpios = <&gpio3 29 0>;
  8811. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  8812. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  8813. status = "okay";
  8814. };
  8815. &spdif {
  8816. pinctrl-names = "default";
  8817. - pinctrl-0 = <&pinctrl_spdif_3>;
  8818. + pinctrl-0 = <&pinctrl_spdif>;
  8819. status = "okay";
  8820. };
  8821. @@ -115,13 +220,13 @@
  8822. &uart1 {
  8823. pinctrl-names = "default";
  8824. - pinctrl-0 = <&pinctrl_uart1_1>;
  8825. + pinctrl-0 = <&pinctrl_uart1>;
  8826. status = "okay";
  8827. };
  8828. &uart3 {
  8829. pinctrl-names = "default";
  8830. - pinctrl-0 = <&pinctrl_uart3_2>;
  8831. + pinctrl-0 = <&pinctrl_uart3>;
  8832. fsl,uart-has-rtscts;
  8833. status = "okay";
  8834. };
  8835. @@ -132,7 +237,7 @@
  8836. &usbotg {
  8837. pinctrl-names = "default";
  8838. - pinctrl-0 = <&pinctrl_usbotg_1>;
  8839. + pinctrl-0 = <&pinctrl_usbotg>;
  8840. disable-over-current;
  8841. dr_mode = "peripheral";
  8842. status = "okay";
  8843. @@ -140,21 +245,21 @@
  8844. &usdhc1 {
  8845. pinctrl-names = "default";
  8846. - pinctrl-0 = <&pinctrl_usdhc1_2>;
  8847. + pinctrl-0 = <&pinctrl_usdhc1>;
  8848. cd-gpios = <&gpio1 2 0>;
  8849. status = "okay";
  8850. };
  8851. &usdhc2 {
  8852. pinctrl-names = "default";
  8853. - pinctrl-0 = <&pinctrl_usdhc2_2>;
  8854. + pinctrl-0 = <&pinctrl_usdhc2>;
  8855. non-removable;
  8856. status = "okay";
  8857. };
  8858. &usdhc3 {
  8859. pinctrl-names = "default";
  8860. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  8861. + pinctrl-0 = <&pinctrl_usdhc3>;
  8862. cd-gpios = <&gpio3 9 0>;
  8863. status = "okay";
  8864. };
  8865. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
  8866. --- linux-3.14.14/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts 1969-12-31 18:00:00.000000000 -0600
  8867. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts 2014-12-08 00:31:51.124418001 -0600
  8868. @@ -0,0 +1,432 @@
  8869. +/*
  8870. + * Copyright 2013 Data Modul AG
  8871. + *
  8872. + * The code contained herein is licensed under the GNU General Public
  8873. + * License. You may obtain a copy of the GNU General Public License
  8874. + * Version 2 or later at the following locations:
  8875. + *
  8876. + * http://www.opensource.org/licenses/gpl-license.html
  8877. + * http://www.gnu.org/copyleft/gpl.html
  8878. + */
  8879. +
  8880. +/dts-v1/;
  8881. +
  8882. +#include <dt-bindings/gpio/gpio.h>
  8883. +#include "imx6q.dtsi"
  8884. +
  8885. +/ {
  8886. + model = "Data Modul eDM-QMX6 Board";
  8887. + compatible = "dmo,imx6q-edmqmx6", "fsl,imx6q";
  8888. +
  8889. + chosen {
  8890. + stdout-path = &uart2;
  8891. + };
  8892. +
  8893. + aliases {
  8894. + gpio7 = &stmpe_gpio1;
  8895. + gpio8 = &stmpe_gpio2;
  8896. + stmpe-i2c0 = &stmpe1;
  8897. + stmpe-i2c1 = &stmpe2;
  8898. + };
  8899. +
  8900. + memory {
  8901. + reg = <0x10000000 0x80000000>;
  8902. + };
  8903. +
  8904. + regulators {
  8905. + compatible = "simple-bus";
  8906. + #address-cells = <1>;
  8907. + #size-cells = <0>;
  8908. +
  8909. + reg_3p3v: regulator@0 {
  8910. + compatible = "regulator-fixed";
  8911. + reg = <0>;
  8912. + regulator-name = "3P3V";
  8913. + regulator-min-microvolt = <3300000>;
  8914. + regulator-max-microvolt = <3300000>;
  8915. + regulator-always-on;
  8916. + };
  8917. +
  8918. + reg_usb_otg_switch: regulator@1 {
  8919. + compatible = "regulator-fixed";
  8920. + reg = <1>;
  8921. + regulator-name = "usb_otg_switch";
  8922. + regulator-min-microvolt = <5000000>;
  8923. + regulator-max-microvolt = <5000000>;
  8924. + gpio = <&gpio7 12 0>;
  8925. + regulator-boot-on;
  8926. + regulator-always-on;
  8927. + };
  8928. +
  8929. + reg_usb_host1: regulator@2 {
  8930. + compatible = "regulator-fixed";
  8931. + reg = <2>;
  8932. + regulator-name = "usb_host1_en";
  8933. + regulator-min-microvolt = <3300000>;
  8934. + regulator-max-microvolt = <3300000>;
  8935. + gpio = <&gpio3 31 0>;
  8936. + enable-active-high;
  8937. + };
  8938. + };
  8939. +
  8940. + gpio-leds {
  8941. + compatible = "gpio-leds";
  8942. +
  8943. + led-blue {
  8944. + label = "blue";
  8945. + gpios = <&stmpe_gpio1 8 GPIO_ACTIVE_HIGH>;
  8946. + linux,default-trigger = "heartbeat";
  8947. + };
  8948. +
  8949. + led-green {
  8950. + label = "green";
  8951. + gpios = <&stmpe_gpio1 9 GPIO_ACTIVE_HIGH>;
  8952. + };
  8953. +
  8954. + led-pink {
  8955. + label = "pink";
  8956. + gpios = <&stmpe_gpio1 10 GPIO_ACTIVE_HIGH>;
  8957. + };
  8958. +
  8959. + led-red {
  8960. + label = "red";
  8961. + gpios = <&stmpe_gpio1 11 GPIO_ACTIVE_HIGH>;
  8962. + };
  8963. + };
  8964. +};
  8965. +
  8966. +&ecspi5 {
  8967. + pinctrl-names = "default";
  8968. + pinctrl-0 = <&pinctrl_ecspi5>;
  8969. + fsl,spi-num-chipselects = <1>;
  8970. + cs-gpios = <&gpio1 12 0>;
  8971. + status = "okay";
  8972. +
  8973. + flash: m25p80@0 {
  8974. + compatible = "m25p80";
  8975. + spi-max-frequency = <40000000>;
  8976. + reg = <0>;
  8977. + };
  8978. +};
  8979. +
  8980. +&fec {
  8981. + pinctrl-names = "default";
  8982. + pinctrl-0 = <&pinctrl_enet>;
  8983. + phy-mode = "rgmii";
  8984. + phy-reset-gpios = <&gpio3 23 0>;
  8985. + phy-supply = <&vgen2_1v2_eth>;
  8986. + status = "okay";
  8987. +};
  8988. +
  8989. +&i2c2 {
  8990. + clock-frequency = <100000>;
  8991. + pinctrl-names = "default";
  8992. + pinctrl-0 = <&pinctrl_i2c2
  8993. + &pinctrl_stmpe1
  8994. + &pinctrl_stmpe2
  8995. + &pinctrl_pfuze>;
  8996. + status = "okay";
  8997. +
  8998. + pmic: pfuze100@08 {
  8999. + compatible = "fsl,pfuze100";
  9000. + reg = <0x08>;
  9001. + interrupt-parent = <&gpio3>;
  9002. + interrupts = <20 8>;
  9003. +
  9004. + regulators {
  9005. + sw1a_reg: sw1ab {
  9006. + regulator-min-microvolt = <300000>;
  9007. + regulator-max-microvolt = <1875000>;
  9008. + regulator-boot-on;
  9009. + regulator-always-on;
  9010. + };
  9011. +
  9012. + sw1c_reg: sw1c {
  9013. + regulator-min-microvolt = <300000>;
  9014. + regulator-max-microvolt = <1875000>;
  9015. + regulator-boot-on;
  9016. + regulator-always-on;
  9017. + };
  9018. +
  9019. + sw2_reg: sw2 {
  9020. + regulator-min-microvolt = <800000>;
  9021. + regulator-max-microvolt = <3300000>;
  9022. + regulator-boot-on;
  9023. + regulator-always-on;
  9024. + };
  9025. +
  9026. + sw3a_reg: sw3a {
  9027. + regulator-min-microvolt = <400000>;
  9028. + regulator-max-microvolt = <1975000>;
  9029. + regulator-boot-on;
  9030. + regulator-always-on;
  9031. + };
  9032. +
  9033. + sw3b_reg: sw3b {
  9034. + regulator-min-microvolt = <400000>;
  9035. + regulator-max-microvolt = <1975000>;
  9036. + regulator-boot-on;
  9037. + regulator-always-on;
  9038. + };
  9039. +
  9040. + sw4_reg: sw4 {
  9041. + regulator-min-microvolt = <400000>;
  9042. + regulator-max-microvolt = <1975000>;
  9043. + regulator-always-on;
  9044. + };
  9045. +
  9046. + swbst_reg: swbst {
  9047. + regulator-min-microvolt = <5000000>;
  9048. + regulator-max-microvolt = <5150000>;
  9049. + regulator-always-on;
  9050. + };
  9051. +
  9052. + snvs_reg: vsnvs {
  9053. + regulator-min-microvolt = <1000000>;
  9054. + regulator-max-microvolt = <3000000>;
  9055. + regulator-boot-on;
  9056. + regulator-always-on;
  9057. + };
  9058. +
  9059. + vref_reg: vrefddr {
  9060. + regulator-boot-on;
  9061. + regulator-always-on;
  9062. + };
  9063. +
  9064. + vgen1_reg: vgen1 {
  9065. + regulator-min-microvolt = <800000>;
  9066. + regulator-max-microvolt = <1550000>;
  9067. + };
  9068. +
  9069. + vgen2_1v2_eth: vgen2 {
  9070. + regulator-min-microvolt = <800000>;
  9071. + regulator-max-microvolt = <1550000>;
  9072. + };
  9073. +
  9074. + vdd_high_in: vgen3 {
  9075. + regulator-min-microvolt = <1800000>;
  9076. + regulator-max-microvolt = <3300000>;
  9077. + regulator-boot-on;
  9078. + regulator-always-on;
  9079. + };
  9080. +
  9081. + vgen4_reg: vgen4 {
  9082. + regulator-min-microvolt = <1800000>;
  9083. + regulator-max-microvolt = <3300000>;
  9084. + regulator-always-on;
  9085. + };
  9086. +
  9087. + vgen5_reg: vgen5 {
  9088. + regulator-min-microvolt = <1800000>;
  9089. + regulator-max-microvolt = <3300000>;
  9090. + regulator-always-on;
  9091. + };
  9092. +
  9093. + vgen6_reg: vgen6 {
  9094. + regulator-min-microvolt = <1800000>;
  9095. + regulator-max-microvolt = <3300000>;
  9096. + regulator-always-on;
  9097. + };
  9098. + };
  9099. + };
  9100. +
  9101. + stmpe1: stmpe1601@40 {
  9102. + compatible = "st,stmpe1601";
  9103. + reg = <0x40>;
  9104. + interrupts = <30 0>;
  9105. + interrupt-parent = <&gpio3>;
  9106. + vcc-supply = <&sw2_reg>;
  9107. + vio-supply = <&sw2_reg>;
  9108. +
  9109. + stmpe_gpio1: stmpe_gpio {
  9110. + #gpio-cells = <2>;
  9111. + compatible = "st,stmpe-gpio";
  9112. + };
  9113. + };
  9114. +
  9115. + stmpe2: stmpe1601@44 {
  9116. + compatible = "st,stmpe1601";
  9117. + reg = <0x44>;
  9118. + interrupts = <2 0>;
  9119. + interrupt-parent = <&gpio5>;
  9120. + vcc-supply = <&sw2_reg>;
  9121. + vio-supply = <&sw2_reg>;
  9122. +
  9123. + stmpe_gpio2: stmpe_gpio {
  9124. + #gpio-cells = <2>;
  9125. + compatible = "st,stmpe-gpio";
  9126. + };
  9127. + };
  9128. +
  9129. + temp1: ad7414@4c {
  9130. + compatible = "ad,ad7414";
  9131. + reg = <0x4c>;
  9132. + };
  9133. +
  9134. + temp2: ad7414@4d {
  9135. + compatible = "ad,ad7414";
  9136. + reg = <0x4d>;
  9137. + };
  9138. +
  9139. + rtc: m41t62@68 {
  9140. + compatible = "stm,m41t62";
  9141. + reg = <0x68>;
  9142. + };
  9143. +};
  9144. +
  9145. +&iomuxc {
  9146. + pinctrl-names = "default";
  9147. + pinctrl-0 = <&pinctrl_hog>;
  9148. +
  9149. + imx6q-dmo-edmqmx6 {
  9150. + pinctrl_hog: hoggrp {
  9151. + fsl,pins = <
  9152. + MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x80000000
  9153. + MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x80000000
  9154. + >;
  9155. + };
  9156. +
  9157. + pinctrl_ecspi5: ecspi5rp-1 {
  9158. + fsl,pins = <
  9159. + MX6QDL_PAD_SD1_DAT0__ECSPI5_MISO 0x80000000
  9160. + MX6QDL_PAD_SD1_CMD__ECSPI5_MOSI 0x80000000
  9161. + MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK 0x80000000
  9162. + MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x80000000
  9163. + >;
  9164. + };
  9165. +
  9166. + pinctrl_enet: enetgrp {
  9167. + fsl,pins = <
  9168. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  9169. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  9170. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  9171. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  9172. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  9173. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  9174. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  9175. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  9176. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  9177. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  9178. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  9179. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  9180. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  9181. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  9182. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  9183. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  9184. + >;
  9185. + };
  9186. +
  9187. + pinctrl_i2c2: i2c2grp {
  9188. + fsl,pins = <
  9189. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  9190. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  9191. + >;
  9192. + };
  9193. +
  9194. + pinctrl_pfuze: pfuze100grp1 {
  9195. + fsl,pins = <
  9196. + MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x80000000
  9197. + >;
  9198. + };
  9199. +
  9200. + pinctrl_stmpe1: stmpe1grp {
  9201. + fsl,pins = <MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x80000000>;
  9202. + };
  9203. +
  9204. + pinctrl_stmpe2: stmpe2grp {
  9205. + fsl,pins = <MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x80000000>;
  9206. + };
  9207. +
  9208. + pinctrl_uart1: uart1grp {
  9209. + fsl,pins = <
  9210. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  9211. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  9212. + >;
  9213. + };
  9214. +
  9215. + pinctrl_uart2: uart2grp {
  9216. + fsl,pins = <
  9217. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  9218. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  9219. + >;
  9220. + };
  9221. +
  9222. + pinctrl_usbotg: usbotggrp {
  9223. + fsl,pins = <
  9224. + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  9225. + >;
  9226. + };
  9227. +
  9228. + pinctrl_usdhc3: usdhc3grp {
  9229. + fsl,pins = <
  9230. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  9231. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  9232. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  9233. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  9234. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  9235. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  9236. + >;
  9237. + };
  9238. +
  9239. + pinctrl_usdhc4: usdhc4grp {
  9240. + fsl,pins = <
  9241. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  9242. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  9243. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  9244. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  9245. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  9246. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  9247. + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  9248. + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  9249. + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  9250. + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  9251. + >;
  9252. + };
  9253. + };
  9254. +};
  9255. +
  9256. +&sata {
  9257. + status = "okay";
  9258. +};
  9259. +
  9260. +&uart1 {
  9261. + pinctrl-names = "default";
  9262. + pinctrl-0 = <&pinctrl_uart1>;
  9263. + status = "okay";
  9264. +};
  9265. +
  9266. +&uart2 {
  9267. + pinctrl-names = "default";
  9268. + pinctrl-0 = <&pinctrl_uart2>;
  9269. + status = "okay";
  9270. +};
  9271. +
  9272. +&usbh1 {
  9273. + vbus-supply = <&reg_usb_host1>;
  9274. + disable-over-current;
  9275. + dr_mode = "host";
  9276. + status = "okay";
  9277. +};
  9278. +
  9279. +&usbotg {
  9280. + pinctrl-names = "default";
  9281. + pinctrl-0 = <&pinctrl_usbotg>;
  9282. + disable-over-current;
  9283. + status = "okay";
  9284. +};
  9285. +
  9286. +&usdhc3 {
  9287. + pinctrl-names = "default";
  9288. + pinctrl-0 = <&pinctrl_usdhc3>;
  9289. + vmmc-supply = <&reg_3p3v>;
  9290. + status = "okay";
  9291. +};
  9292. +
  9293. +&usdhc4 {
  9294. + pinctrl-names = "default";
  9295. + pinctrl-0 = <&pinctrl_usdhc4>;
  9296. + vmmc-supply = <&reg_3p3v>;
  9297. + non-removable;
  9298. + bus-width = <8>;
  9299. + status = "okay";
  9300. +};
  9301. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6q.dtsi
  9302. --- linux-3.14.14/arch/arm/boot/dts/imx6q.dtsi 2014-07-28 10:07:25.000000000 -0500
  9303. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q.dtsi 2014-12-08 00:31:51.124418001 -0600
  9304. @@ -8,10 +8,16 @@
  9305. *
  9306. */
  9307. +#include <dt-bindings/interrupt-controller/irq.h>
  9308. #include "imx6q-pinfunc.h"
  9309. #include "imx6qdl.dtsi"
  9310. / {
  9311. + aliases {
  9312. + ipu1 = &ipu2;
  9313. + spi4 = &ecspi5;
  9314. + };
  9315. +
  9316. cpus {
  9317. #address-cells = <1>;
  9318. #size-cells = <0>;
  9319. @@ -25,8 +31,17 @@
  9320. /* kHz uV */
  9321. 1200000 1275000
  9322. 996000 1250000
  9323. + 852000 1250000
  9324. 792000 1150000
  9325. - 396000 950000
  9326. + 396000 975000
  9327. + >;
  9328. + fsl,soc-operating-points = <
  9329. + /* ARM kHz SOC-PU uV */
  9330. + 1200000 1275000
  9331. + 996000 1250000
  9332. + 852000 1250000
  9333. + 792000 1175000
  9334. + 396000 1175000
  9335. >;
  9336. clock-latency = <61036>; /* two CLK32 periods */
  9337. clocks = <&clks 104>, <&clks 6>, <&clks 16>,
  9338. @@ -61,12 +76,77 @@
  9339. };
  9340. soc {
  9341. +
  9342. + busfreq { /* BUSFREQ */
  9343. + compatible = "fsl,imx6_busfreq";
  9344. + clocks = <&clks 171>, <&clks 6>, <&clks 11>, <&clks 104>, <&clks 172>, <&clks 58>,
  9345. + <&clks 18>, <&clks 60>, <&clks 20>, <&clks 3>;
  9346. + clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
  9347. + "periph_pre", "periph_clk2", "periph_clk2_sel", "osc";
  9348. + interrupts = <0 107 0x04>, <0 112 0x4>, <0 113 0x4>, <0 114 0x4>;
  9349. + interrupt-names = "irq_busfreq_0", "irq_busfreq_1", "irq_busfreq_2", "irq_busfreq_3";
  9350. + fsl,max_ddr_freq = <528000000>;
  9351. + };
  9352. +
  9353. + gpu@00130000 {
  9354. + compatible = "fsl,imx6q-gpu";
  9355. + reg = <0x00130000 0x4000>, <0x00134000 0x4000>,
  9356. + <0x02204000 0x4000>, <0x0 0x0>;
  9357. + reg-names = "iobase_3d", "iobase_2d",
  9358. + "iobase_vg", "phys_baseaddr";
  9359. + interrupts = <0 9 0x04>, <0 10 0x04>,<0 11 0x04>;
  9360. + interrupt-names = "irq_3d", "irq_2d", "irq_vg";
  9361. + clocks = <&clks 26>, <&clks 143>,
  9362. + <&clks 27>, <&clks 121>,
  9363. + <&clks 122>, <&clks 74>;
  9364. + clock-names = "gpu2d_axi_clk", "openvg_axi_clk",
  9365. + "gpu3d_axi_clk", "gpu2d_clk",
  9366. + "gpu3d_clk", "gpu3d_shader_clk";
  9367. + resets = <&src 0>, <&src 3>, <&src 3>;
  9368. + reset-names = "gpu3d", "gpu2d", "gpuvg";
  9369. + pu-supply = <&reg_pu>;
  9370. + };
  9371. +
  9372. ocram: sram@00900000 {
  9373. compatible = "mmio-sram";
  9374. reg = <0x00900000 0x40000>;
  9375. clocks = <&clks 142>;
  9376. };
  9377. + hdmi_core: hdmi_core@00120000 {
  9378. + compatible = "fsl,imx6q-hdmi-core";
  9379. + reg = <0x00120000 0x9000>;
  9380. + clocks = <&clks 124>, <&clks 123>;
  9381. + clock-names = "hdmi_isfr", "hdmi_iahb";
  9382. + status = "disabled";
  9383. + };
  9384. +
  9385. + hdmi_video: hdmi_video@020e0000 {
  9386. + compatible = "fsl,imx6q-hdmi-video";
  9387. + reg = <0x020e0000 0x1000>;
  9388. + reg-names = "hdmi_gpr";
  9389. + interrupts = <0 115 0x04>;
  9390. + clocks = <&clks 124>, <&clks 123>;
  9391. + clock-names = "hdmi_isfr", "hdmi_iahb";
  9392. + status = "disabled";
  9393. + };
  9394. +
  9395. + hdmi_audio: hdmi_audio@00120000 {
  9396. + compatible = "fsl,imx6q-hdmi-audio";
  9397. + clocks = <&clks 124>, <&clks 123>;
  9398. + clock-names = "hdmi_isfr", "hdmi_iahb";
  9399. + dmas = <&sdma 2 23 0>;
  9400. + dma-names = "tx";
  9401. + status = "disabled";
  9402. + };
  9403. +
  9404. + hdmi_cec: hdmi_cec@00120000 {
  9405. + compatible = "fsl,imx6q-hdmi-cec";
  9406. + interrupts = <0 115 0x04>;
  9407. + status = "disabled";
  9408. + };
  9409. +
  9410. +
  9411. aips-bus@02000000 { /* AIPS1 */
  9412. spba-bus@02000000 {
  9413. ecspi5: ecspi@02018000 {
  9414. @@ -74,13 +154,17 @@
  9415. #size-cells = <0>;
  9416. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  9417. reg = <0x02018000 0x4000>;
  9418. - interrupts = <0 35 0x04>;
  9419. + interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
  9420. clocks = <&clks 116>, <&clks 116>;
  9421. clock-names = "ipg", "per";
  9422. status = "disabled";
  9423. };
  9424. };
  9425. + vpu@02040000 {
  9426. + status = "okay";
  9427. + };
  9428. +
  9429. iomuxc: iomuxc@020e0000 {
  9430. compatible = "fsl,imx6q-iomuxc";
  9431. @@ -122,40 +206,40 @@
  9432. };
  9433. };
  9434. + aips-bus@02100000 { /* AIPS2 */
  9435. + mipi_dsi: mipi@021e0000 {
  9436. + compatible = "fsl,imx6q-mipi-dsi";
  9437. + reg = <0x021e0000 0x4000>;
  9438. + interrupts = <0 102 0x04>;
  9439. + gpr = <&gpr>;
  9440. + clocks = <&clks 138>, <&clks 209>;
  9441. + clock-names = "mipi_pllref_clk", "mipi_cfg_clk";
  9442. + status = "disabled";
  9443. + };
  9444. + };
  9445. +
  9446. sata: sata@02200000 {
  9447. compatible = "fsl,imx6q-ahci";
  9448. reg = <0x02200000 0x4000>;
  9449. - interrupts = <0 39 0x04>;
  9450. + interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
  9451. clocks = <&clks 154>, <&clks 187>, <&clks 105>;
  9452. clock-names = "sata", "sata_ref", "ahb";
  9453. status = "disabled";
  9454. };
  9455. ipu2: ipu@02800000 {
  9456. - #crtc-cells = <1>;
  9457. compatible = "fsl,imx6q-ipu";
  9458. reg = <0x02800000 0x400000>;
  9459. - interrupts = <0 8 0x4 0 7 0x4>;
  9460. - clocks = <&clks 133>, <&clks 134>, <&clks 137>;
  9461. - clock-names = "bus", "di0", "di1";
  9462. + interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>,
  9463. + <0 7 IRQ_TYPE_LEVEL_HIGH>;
  9464. + clocks = <&clks 133>, <&clks 134>, <&clks 137>,
  9465. + <&clks 41>, <&clks 42>,
  9466. + <&clks 135>, <&clks 136>;
  9467. + clock-names = "bus", "di0", "di1",
  9468. + "di0_sel", "di1_sel",
  9469. + "ldb_di0", "ldb_di1";
  9470. resets = <&src 4>;
  9471. + bypass_reset = <0>;
  9472. };
  9473. };
  9474. };
  9475. -
  9476. -&ldb {
  9477. - clocks = <&clks 33>, <&clks 34>,
  9478. - <&clks 39>, <&clks 40>, <&clks 41>, <&clks 42>,
  9479. - <&clks 135>, <&clks 136>;
  9480. - clock-names = "di0_pll", "di1_pll",
  9481. - "di0_sel", "di1_sel", "di2_sel", "di3_sel",
  9482. - "di0", "di1";
  9483. -
  9484. - lvds-channel@0 {
  9485. - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
  9486. - };
  9487. -
  9488. - lvds-channel@1 {
  9489. - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
  9490. - };
  9491. -};
  9492. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-gk802.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gk802.dts
  9493. --- linux-3.14.14/arch/arm/boot/dts/imx6q-gk802.dts 1969-12-31 18:00:00.000000000 -0600
  9494. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gk802.dts 2014-12-08 00:31:51.124418001 -0600
  9495. @@ -0,0 +1,229 @@
  9496. +/*
  9497. + * Copyright (C) 2013 Philipp Zabel
  9498. + *
  9499. + * This file is licensed under the terms of the GNU General Public License
  9500. + * version 2. This program is licensed "as is" without any warranty of any
  9501. + * kind, whether express or implied.
  9502. + */
  9503. +
  9504. +/dts-v1/;
  9505. +#include "imx6q.dtsi"
  9506. +
  9507. +/ {
  9508. + model = "Zealz GK802";
  9509. + compatible = "zealz,imx6q-gk802", "fsl,imx6q";
  9510. +
  9511. + aliases {
  9512. + mxcfb0 = &mxcfb1;
  9513. + };
  9514. +
  9515. + chosen {
  9516. + stdout-path = &uart4;
  9517. + };
  9518. +
  9519. + memory {
  9520. + reg = <0x10000000 0x40000000>;
  9521. + };
  9522. +
  9523. + regulators {
  9524. + compatible = "simple-bus";
  9525. + #address-cells = <1>;
  9526. + #size-cells = <0>;
  9527. +
  9528. + reg_3p3v: regulator@0 {
  9529. + compatible = "regulator-fixed";
  9530. + reg = <0>;
  9531. + regulator-name = "3P3V";
  9532. + regulator-min-microvolt = <3300000>;
  9533. + regulator-max-microvolt = <3300000>;
  9534. + regulator-always-on;
  9535. + };
  9536. +
  9537. + reg_usb_h1_vbus: usb_h1_vbus {
  9538. + compatible = "regulator-fixed";
  9539. + regulator-name = "usb_h1_vbus";
  9540. + regulator-min-microvolt = <5000000>;
  9541. + regulator-max-microvolt = <5000000>;
  9542. + gpio = <&gpio2 0 0>;
  9543. + };
  9544. + };
  9545. +
  9546. + gpio-keys {
  9547. + compatible = "gpio-keys";
  9548. +
  9549. + recovery-button {
  9550. + label = "recovery";
  9551. + gpios = <&gpio3 16 1>;
  9552. + linux,code = <0x198>; /* KEY_RESTART */
  9553. + gpio-key,wakeup;
  9554. + };
  9555. +
  9556. + };
  9557. +
  9558. + sound-hdmi {
  9559. + compatible = "fsl,imx6q-audio-hdmi",
  9560. + "fsl,imx-audio-hdmi";
  9561. + model = "imx-audio-hdmi";
  9562. + hdmi-controller = <&hdmi_audio>;
  9563. + };
  9564. +
  9565. + mxcfb1: fb@0 {
  9566. + compatible = "fsl,mxc_sdc_fb";
  9567. + disp_dev = "hdmi";
  9568. + interface_pix_fmt = "RGB24";
  9569. + mode_str ="1920x1080M@60";
  9570. + default_bpp = <32>;
  9571. + int_clk = <0>;
  9572. + late_init = <0>;
  9573. + status = "okay";
  9574. + };
  9575. +};
  9576. +
  9577. +&hdmi_core {
  9578. + ipu_id = <0>;
  9579. + disp_id = <0>;
  9580. + status = "okay";
  9581. +};
  9582. +
  9583. +&hdmi_video {
  9584. + fsl,phy_reg_vlev = <0x0294>;
  9585. + fsl,phy_reg_cksymtx = <0x800d>;
  9586. + status = "okay";
  9587. +};
  9588. +
  9589. +&hdmi_audio {
  9590. + status = "okay";
  9591. +};
  9592. +
  9593. +
  9594. +/* Internal I2C */
  9595. +&i2c2 {
  9596. + pinctrl-names = "default";
  9597. + pinctrl-0 = <&pinctrl_i2c2>;
  9598. + clock-frequency = <100000>;
  9599. + status = "okay";
  9600. +
  9601. + /* SDMC DM2016 1024 bit EEPROM + 128 bit OTP */
  9602. + eeprom: dm2016@51 {
  9603. + compatible = "sdmc,dm2016";
  9604. + reg = <0x51>;
  9605. + };
  9606. +};
  9607. +
  9608. +/* External I2C via HDMI */
  9609. +&i2c3 {
  9610. + pinctrl-names = "default";
  9611. + pinctrl-0 = <&pinctrl_i2c3>;
  9612. + clock-frequency = <100000>;
  9613. + status = "okay";
  9614. +
  9615. + ddc: imx6_hdmi_i2c@50 {
  9616. + compatible = "fsl,imx6-hdmi-i2c";
  9617. + reg = <0x50>;
  9618. + };
  9619. +};
  9620. +
  9621. +&iomuxc {
  9622. + pinctrl-names = "default";
  9623. + pinctrl-0 = <&pinctrl_hog>;
  9624. +
  9625. + imx6q-gk802 {
  9626. + pinctrl_hog: hoggrp {
  9627. + fsl,pins = <
  9628. + /* Recovery button, active-low */
  9629. + MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x100b1
  9630. + /* RTL8192CU enable GPIO, active-low */
  9631. + MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
  9632. + >;
  9633. + };
  9634. +
  9635. + pinctrl_i2c2: i2c2grp {
  9636. + fsl,pins = <
  9637. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  9638. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  9639. + >;
  9640. + };
  9641. +
  9642. + pinctrl_i2c3: i2c3grp {
  9643. + fsl,pins = <
  9644. + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
  9645. + MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
  9646. + >;
  9647. + };
  9648. +
  9649. + pinctrl_uart4: uart4grp {
  9650. + fsl,pins = <
  9651. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  9652. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  9653. + >;
  9654. + };
  9655. +
  9656. + pinctrl_usdhc3: usdhc3grp {
  9657. + fsl,pins = <
  9658. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  9659. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  9660. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  9661. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  9662. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  9663. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  9664. + >;
  9665. + };
  9666. +
  9667. + pinctrl_usdhc4: usdhc4grp {
  9668. + fsl,pins = <
  9669. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  9670. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  9671. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  9672. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  9673. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  9674. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  9675. + >;
  9676. + };
  9677. + };
  9678. +};
  9679. +
  9680. +&uart2 {
  9681. + status = "okay";
  9682. +};
  9683. +
  9684. +&uart4 {
  9685. + pinctrl-names = "default";
  9686. + pinctrl-0 = <&pinctrl_uart4>;
  9687. + status = "okay";
  9688. +};
  9689. +
  9690. +/* External USB-A port (USBOTG) */
  9691. +&usbotg {
  9692. + phy_type = "utmi";
  9693. + dr_mode = "host";
  9694. + disable-over-current;
  9695. + status = "okay";
  9696. +};
  9697. +
  9698. +/* Internal USB port (USBH1), connected to RTL8192CU */
  9699. +&usbh1 {
  9700. + phy_type = "utmi";
  9701. + dr_mode = "host";
  9702. + vbus-supply = <&reg_usb_h1_vbus>;
  9703. + disable-over-current;
  9704. + status = "okay";
  9705. +};
  9706. +
  9707. +/* External microSD */
  9708. +&usdhc3 {
  9709. + pinctrl-names = "default";
  9710. + pinctrl-0 = <&pinctrl_usdhc3>;
  9711. + bus-width = <4>;
  9712. + cd-gpios = <&gpio6 11 0>;
  9713. + vmmc-supply = <&reg_3p3v>;
  9714. + status = "okay";
  9715. +};
  9716. +
  9717. +/* Internal microSD */
  9718. +&usdhc4 {
  9719. + pinctrl-names = "default";
  9720. + pinctrl-0 = <&pinctrl_usdhc4>;
  9721. + bus-width = <4>;
  9722. + vmmc-supply = <&reg_3p3v>;
  9723. + status = "okay";
  9724. +};
  9725. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-gw51xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw51xx.dts
  9726. --- linux-3.14.14/arch/arm/boot/dts/imx6q-gw51xx.dts 1969-12-31 18:00:00.000000000 -0600
  9727. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw51xx.dts 2014-12-08 00:31:51.124418001 -0600
  9728. @@ -0,0 +1,19 @@
  9729. +/*
  9730. + * Copyright 2013 Gateworks Corporation
  9731. + *
  9732. + * The code contained herein is licensed under the GNU General Public
  9733. + * License. You may obtain a copy of the GNU General Public License
  9734. + * Version 2 or later at the following locations:
  9735. + *
  9736. + * http://www.opensource.org/licenses/gpl-license.html
  9737. + * http://www.gnu.org/copyleft/gpl.html
  9738. + */
  9739. +
  9740. +/dts-v1/;
  9741. +#include "imx6q.dtsi"
  9742. +#include "imx6qdl-gw54xx.dtsi"
  9743. +
  9744. +/ {
  9745. + model = "Gateworks Ventana i.MX6 Quad GW51XX";
  9746. + compatible = "gw,imx6q-gw51xx", "gw,ventana", "fsl,imx6q";
  9747. +};
  9748. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-gw52xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw52xx.dts
  9749. --- linux-3.14.14/arch/arm/boot/dts/imx6q-gw52xx.dts 1969-12-31 18:00:00.000000000 -0600
  9750. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw52xx.dts 2014-12-08 00:31:51.124418001 -0600
  9751. @@ -0,0 +1,23 @@
  9752. +/*
  9753. + * Copyright 2013 Gateworks Corporation
  9754. + *
  9755. + * The code contained herein is licensed under the GNU General Public
  9756. + * License. You may obtain a copy of the GNU General Public License
  9757. + * Version 2 or later at the following locations:
  9758. + *
  9759. + * http://www.opensource.org/licenses/gpl-license.html
  9760. + * http://www.gnu.org/copyleft/gpl.html
  9761. + */
  9762. +
  9763. +/dts-v1/;
  9764. +#include "imx6q.dtsi"
  9765. +#include "imx6qdl-gw52xx.dtsi"
  9766. +
  9767. +/ {
  9768. + model = "Gateworks Ventana i.MX6 Quad GW52XX";
  9769. + compatible = "gw,imx6q-gw52xx", "gw,ventana", "fsl,imx6q";
  9770. +};
  9771. +
  9772. +&sata {
  9773. + status = "okay";
  9774. +};
  9775. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-gw53xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw53xx.dts
  9776. --- linux-3.14.14/arch/arm/boot/dts/imx6q-gw53xx.dts 1969-12-31 18:00:00.000000000 -0600
  9777. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw53xx.dts 2014-12-08 00:31:51.124418001 -0600
  9778. @@ -0,0 +1,23 @@
  9779. +/*
  9780. + * Copyright 2013 Gateworks Corporation
  9781. + *
  9782. + * The code contained herein is licensed under the GNU General Public
  9783. + * License. You may obtain a copy of the GNU General Public License
  9784. + * Version 2 or later at the following locations:
  9785. + *
  9786. + * http://www.opensource.org/licenses/gpl-license.html
  9787. + * http://www.gnu.org/copyleft/gpl.html
  9788. + */
  9789. +
  9790. +/dts-v1/;
  9791. +#include "imx6q.dtsi"
  9792. +#include "imx6qdl-gw53xx.dtsi"
  9793. +
  9794. +/ {
  9795. + model = "Gateworks Ventana i.MX6 Quad GW53XX";
  9796. + compatible = "gw,imx6q-gw53xx", "gw,ventana", "fsl,imx6q";
  9797. +};
  9798. +
  9799. +&sata {
  9800. + status = "okay";
  9801. +};
  9802. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-gw5400-a.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw5400-a.dts
  9803. --- linux-3.14.14/arch/arm/boot/dts/imx6q-gw5400-a.dts 1969-12-31 18:00:00.000000000 -0600
  9804. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw5400-a.dts 2014-12-08 00:31:51.124418001 -0600
  9805. @@ -0,0 +1,543 @@
  9806. +/*
  9807. + * Copyright 2013 Gateworks Corporation
  9808. + *
  9809. + * The code contained herein is licensed under the GNU General Public
  9810. + * License. You may obtain a copy of the GNU General Public License
  9811. + * Version 2 or later at the following locations:
  9812. + *
  9813. + * http://www.opensource.org/licenses/gpl-license.html
  9814. + * http://www.gnu.org/copyleft/gpl.html
  9815. + */
  9816. +
  9817. +/dts-v1/;
  9818. +#include "imx6q.dtsi"
  9819. +
  9820. +/ {
  9821. + model = "Gateworks Ventana GW5400-A";
  9822. + compatible = "gw,imx6q-gw5400-a", "gw,ventana", "fsl,imx6q";
  9823. +
  9824. + /* these are used by bootloader for disabling nodes */
  9825. + aliases {
  9826. + ethernet0 = &fec;
  9827. + ethernet1 = &eth1;
  9828. + i2c0 = &i2c1;
  9829. + i2c1 = &i2c2;
  9830. + i2c2 = &i2c3;
  9831. + led0 = &led0;
  9832. + led1 = &led1;
  9833. + led2 = &led2;
  9834. + sky2 = &eth1;
  9835. + ssi0 = &ssi1;
  9836. + spi0 = &ecspi1;
  9837. + usb0 = &usbh1;
  9838. + usb1 = &usbotg;
  9839. + usdhc2 = &usdhc3;
  9840. + };
  9841. +
  9842. + chosen {
  9843. + bootargs = "console=ttymxc1,115200";
  9844. + };
  9845. +
  9846. + leds {
  9847. + compatible = "gpio-leds";
  9848. +
  9849. + led0: user1 {
  9850. + label = "user1";
  9851. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  9852. + default-state = "on";
  9853. + linux,default-trigger = "heartbeat";
  9854. + };
  9855. +
  9856. + led1: user2 {
  9857. + label = "user2";
  9858. + gpios = <&gpio4 10 0>; /* 106 -> MX6_PANLEDR */
  9859. + default-state = "off";
  9860. + };
  9861. +
  9862. + led2: user3 {
  9863. + label = "user3";
  9864. + gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
  9865. + default-state = "off";
  9866. + };
  9867. + };
  9868. +
  9869. + memory {
  9870. + reg = <0x10000000 0x40000000>;
  9871. + };
  9872. +
  9873. + pps {
  9874. + compatible = "pps-gpio";
  9875. + gpios = <&gpio1 5 0>;
  9876. + status = "okay";
  9877. + };
  9878. +
  9879. + regulators {
  9880. + compatible = "simple-bus";
  9881. + #address-cells = <1>;
  9882. + #size-cells = <0>;
  9883. +
  9884. + reg_1p0v: regulator@0 {
  9885. + compatible = "regulator-fixed";
  9886. + reg = <0>;
  9887. + regulator-name = "1P0V";
  9888. + regulator-min-microvolt = <1000000>;
  9889. + regulator-max-microvolt = <1000000>;
  9890. + regulator-always-on;
  9891. + };
  9892. +
  9893. + reg_3p3v: regulator@1 {
  9894. + compatible = "regulator-fixed";
  9895. + reg = <1>;
  9896. + regulator-name = "3P3V";
  9897. + regulator-min-microvolt = <3300000>;
  9898. + regulator-max-microvolt = <3300000>;
  9899. + regulator-always-on;
  9900. + };
  9901. +
  9902. + reg_usb_h1_vbus: regulator@2 {
  9903. + compatible = "regulator-fixed";
  9904. + reg = <2>;
  9905. + regulator-name = "usb_h1_vbus";
  9906. + regulator-min-microvolt = <5000000>;
  9907. + regulator-max-microvolt = <5000000>;
  9908. + regulator-always-on;
  9909. + };
  9910. +
  9911. + reg_usb_otg_vbus: regulator@3 {
  9912. + compatible = "regulator-fixed";
  9913. + reg = <3>;
  9914. + regulator-name = "usb_otg_vbus";
  9915. + regulator-min-microvolt = <5000000>;
  9916. + regulator-max-microvolt = <5000000>;
  9917. + gpio = <&gpio3 22 0>;
  9918. + enable-active-high;
  9919. + };
  9920. + };
  9921. +
  9922. + sound {
  9923. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  9924. + "fsl,imx-audio-sgtl5000";
  9925. + model = "imx6q-sabrelite-sgtl5000";
  9926. + ssi-controller = <&ssi1>;
  9927. + audio-codec = <&codec>;
  9928. + audio-routing =
  9929. + "MIC_IN", "Mic Jack",
  9930. + "Mic Jack", "Mic Bias",
  9931. + "Headphone Jack", "HP_OUT";
  9932. + mux-int-port = <1>;
  9933. + mux-ext-port = <4>;
  9934. + };
  9935. +};
  9936. +
  9937. +&audmux {
  9938. + pinctrl-names = "default";
  9939. + pinctrl-0 = <&pinctrl_audmux>;
  9940. + status = "okay";
  9941. +};
  9942. +
  9943. +&ecspi1 {
  9944. + fsl,spi-num-chipselects = <1>;
  9945. + cs-gpios = <&gpio3 19 0>;
  9946. + pinctrl-names = "default";
  9947. + pinctrl-0 = <&pinctrl_ecspi1>;
  9948. + status = "okay";
  9949. +
  9950. + flash: m25p80@0 {
  9951. + compatible = "sst,w25q256";
  9952. + spi-max-frequency = <30000000>;
  9953. + reg = <0>;
  9954. + };
  9955. +};
  9956. +
  9957. +&fec {
  9958. + pinctrl-names = "default";
  9959. + pinctrl-0 = <&pinctrl_enet>;
  9960. + phy-mode = "rgmii";
  9961. + phy-reset-gpios = <&gpio1 30 0>;
  9962. + status = "okay";
  9963. +};
  9964. +
  9965. +&i2c1 {
  9966. + clock-frequency = <100000>;
  9967. + pinctrl-names = "default";
  9968. + pinctrl-0 = <&pinctrl_i2c1>;
  9969. + status = "okay";
  9970. +
  9971. + eeprom1: eeprom@50 {
  9972. + compatible = "atmel,24c02";
  9973. + reg = <0x50>;
  9974. + pagesize = <16>;
  9975. + };
  9976. +
  9977. + eeprom2: eeprom@51 {
  9978. + compatible = "atmel,24c02";
  9979. + reg = <0x51>;
  9980. + pagesize = <16>;
  9981. + };
  9982. +
  9983. + eeprom3: eeprom@52 {
  9984. + compatible = "atmel,24c02";
  9985. + reg = <0x52>;
  9986. + pagesize = <16>;
  9987. + };
  9988. +
  9989. + eeprom4: eeprom@53 {
  9990. + compatible = "atmel,24c02";
  9991. + reg = <0x53>;
  9992. + pagesize = <16>;
  9993. + };
  9994. +
  9995. + gpio: pca9555@23 {
  9996. + compatible = "nxp,pca9555";
  9997. + reg = <0x23>;
  9998. + gpio-controller;
  9999. + #gpio-cells = <2>;
  10000. + };
  10001. +
  10002. + hwmon: gsc@29 {
  10003. + compatible = "gw,gsp";
  10004. + reg = <0x29>;
  10005. + };
  10006. +
  10007. + rtc: ds1672@68 {
  10008. + compatible = "dallas,ds1672";
  10009. + reg = <0x68>;
  10010. + };
  10011. +};
  10012. +
  10013. +&i2c2 {
  10014. + clock-frequency = <100000>;
  10015. + pinctrl-names = "default";
  10016. + pinctrl-0 = <&pinctrl_i2c2>;
  10017. + status = "okay";
  10018. +
  10019. + pmic: pfuze100@08 {
  10020. + compatible = "fsl,pfuze100";
  10021. + reg = <0x08>;
  10022. +
  10023. + regulators {
  10024. + sw1a_reg: sw1ab {
  10025. + regulator-min-microvolt = <300000>;
  10026. + regulator-max-microvolt = <1875000>;
  10027. + regulator-boot-on;
  10028. + regulator-always-on;
  10029. + regulator-ramp-delay = <6250>;
  10030. + };
  10031. +
  10032. + sw1c_reg: sw1c {
  10033. + regulator-min-microvolt = <300000>;
  10034. + regulator-max-microvolt = <1875000>;
  10035. + regulator-boot-on;
  10036. + regulator-always-on;
  10037. + regulator-ramp-delay = <6250>;
  10038. + };
  10039. +
  10040. + sw2_reg: sw2 {
  10041. + regulator-min-microvolt = <800000>;
  10042. + regulator-max-microvolt = <3950000>;
  10043. + regulator-boot-on;
  10044. + regulator-always-on;
  10045. + };
  10046. +
  10047. + sw3a_reg: sw3a {
  10048. + regulator-min-microvolt = <400000>;
  10049. + regulator-max-microvolt = <1975000>;
  10050. + regulator-boot-on;
  10051. + regulator-always-on;
  10052. + };
  10053. +
  10054. + sw3b_reg: sw3b {
  10055. + regulator-min-microvolt = <400000>;
  10056. + regulator-max-microvolt = <1975000>;
  10057. + regulator-boot-on;
  10058. + regulator-always-on;
  10059. + };
  10060. +
  10061. + sw4_reg: sw4 {
  10062. + regulator-min-microvolt = <800000>;
  10063. + regulator-max-microvolt = <3300000>;
  10064. + };
  10065. +
  10066. + swbst_reg: swbst {
  10067. + regulator-min-microvolt = <5000000>;
  10068. + regulator-max-microvolt = <5150000>;
  10069. + };
  10070. +
  10071. + snvs_reg: vsnvs {
  10072. + regulator-min-microvolt = <1000000>;
  10073. + regulator-max-microvolt = <3000000>;
  10074. + regulator-boot-on;
  10075. + regulator-always-on;
  10076. + };
  10077. +
  10078. + vref_reg: vrefddr {
  10079. + regulator-boot-on;
  10080. + regulator-always-on;
  10081. + };
  10082. +
  10083. + vgen1_reg: vgen1 {
  10084. + regulator-min-microvolt = <800000>;
  10085. + regulator-max-microvolt = <1550000>;
  10086. + };
  10087. +
  10088. + vgen2_reg: vgen2 {
  10089. + regulator-min-microvolt = <800000>;
  10090. + regulator-max-microvolt = <1550000>;
  10091. + };
  10092. +
  10093. + vgen3_reg: vgen3 {
  10094. + regulator-min-microvolt = <1800000>;
  10095. + regulator-max-microvolt = <3300000>;
  10096. + };
  10097. +
  10098. + vgen4_reg: vgen4 {
  10099. + regulator-min-microvolt = <1800000>;
  10100. + regulator-max-microvolt = <3300000>;
  10101. + regulator-always-on;
  10102. + };
  10103. +
  10104. + vgen5_reg: vgen5 {
  10105. + regulator-min-microvolt = <1800000>;
  10106. + regulator-max-microvolt = <3300000>;
  10107. + regulator-always-on;
  10108. + };
  10109. +
  10110. + vgen6_reg: vgen6 {
  10111. + regulator-min-microvolt = <1800000>;
  10112. + regulator-max-microvolt = <3300000>;
  10113. + regulator-always-on;
  10114. + };
  10115. + };
  10116. + };
  10117. +
  10118. + pciswitch: pex8609@3f {
  10119. + compatible = "plx,pex8609";
  10120. + reg = <0x3f>;
  10121. + };
  10122. +
  10123. + pciclkgen: si52147@6b {
  10124. + compatible = "sil,si52147";
  10125. + reg = <0x6b>;
  10126. + };
  10127. +};
  10128. +
  10129. +&i2c3 {
  10130. + clock-frequency = <100000>;
  10131. + pinctrl-names = "default";
  10132. + pinctrl-0 = <&pinctrl_i2c3>;
  10133. + status = "okay";
  10134. +
  10135. + accelerometer: mma8450@1c {
  10136. + compatible = "fsl,mma8450";
  10137. + reg = <0x1c>;
  10138. + };
  10139. +
  10140. + codec: sgtl5000@0a {
  10141. + compatible = "fsl,sgtl5000";
  10142. + reg = <0x0a>;
  10143. + clocks = <&clks 201>;
  10144. + VDDA-supply = <&sw4_reg>;
  10145. + VDDIO-supply = <&reg_3p3v>;
  10146. + };
  10147. +
  10148. + hdmiin: adv7611@4c {
  10149. + compatible = "adi,adv7611";
  10150. + reg = <0x4c>;
  10151. + };
  10152. +
  10153. + touchscreen: egalax_ts@04 {
  10154. + compatible = "eeti,egalax_ts";
  10155. + reg = <0x04>;
  10156. + interrupt-parent = <&gpio7>;
  10157. + interrupts = <12 2>; /* gpio7_12 active low */
  10158. + wakeup-gpios = <&gpio7 12 0>;
  10159. + };
  10160. +
  10161. + videoout: adv7393@2a {
  10162. + compatible = "adi,adv7393";
  10163. + reg = <0x2a>;
  10164. + };
  10165. +
  10166. + videoin: adv7180@20 {
  10167. + compatible = "adi,adv7180";
  10168. + reg = <0x20>;
  10169. + };
  10170. +};
  10171. +
  10172. +&iomuxc {
  10173. + pinctrl-names = "default";
  10174. + pinctrl-0 = <&pinctrl_hog>;
  10175. +
  10176. + imx6q-gw5400-a {
  10177. + pinctrl_hog: hoggrp {
  10178. + fsl,pins = <
  10179. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  10180. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000 /* SPINOR_CS0# */
  10181. + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
  10182. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE RST */
  10183. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  10184. + MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x80000000 /* GPS_PPS */
  10185. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* TOUCH_IRQ# */
  10186. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  10187. + MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x80000000 /* user2 led */
  10188. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  10189. + MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x80000000 /* USBHUB_RST# */
  10190. + MX6QDL_PAD_SD1_DAT3__GPIO1_IO21 0x80000000 /* MIPI_DIO */
  10191. + >;
  10192. + };
  10193. +
  10194. + pinctrl_audmux: audmuxgrp {
  10195. + fsl,pins = <
  10196. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  10197. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  10198. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  10199. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  10200. + >;
  10201. + };
  10202. +
  10203. + pinctrl_ecspi1: ecspi1grp {
  10204. + fsl,pins = <
  10205. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  10206. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  10207. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  10208. + >;
  10209. + };
  10210. +
  10211. + pinctrl_enet: enetgrp {
  10212. + fsl,pins = <
  10213. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  10214. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  10215. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  10216. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  10217. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  10218. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  10219. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  10220. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  10221. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  10222. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  10223. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  10224. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  10225. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  10226. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  10227. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  10228. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  10229. + >;
  10230. + };
  10231. +
  10232. + pinctrl_i2c1: i2c1grp {
  10233. + fsl,pins = <
  10234. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  10235. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  10236. + >;
  10237. + };
  10238. +
  10239. + pinctrl_i2c2: i2c2grp {
  10240. + fsl,pins = <
  10241. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  10242. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  10243. + >;
  10244. + };
  10245. +
  10246. + pinctrl_i2c3: i2c3grp {
  10247. + fsl,pins = <
  10248. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  10249. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  10250. + >;
  10251. + };
  10252. +
  10253. + pinctrl_uart1: uart1grp {
  10254. + fsl,pins = <
  10255. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  10256. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  10257. + >;
  10258. + };
  10259. +
  10260. + pinctrl_uart2: uart2grp {
  10261. + fsl,pins = <
  10262. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  10263. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  10264. + >;
  10265. + };
  10266. +
  10267. + pinctrl_uart5: uart5grp {
  10268. + fsl,pins = <
  10269. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  10270. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  10271. + >;
  10272. + };
  10273. +
  10274. + pinctrl_usbotg: usbotggrp {
  10275. + fsl,pins = <
  10276. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  10277. + >;
  10278. + };
  10279. +
  10280. + pinctrl_usdhc3: usdhc3grp {
  10281. + fsl,pins = <
  10282. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  10283. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  10284. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  10285. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  10286. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  10287. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  10288. + >;
  10289. + };
  10290. + };
  10291. +};
  10292. +
  10293. +&ldb {
  10294. + status = "okay";
  10295. +};
  10296. +
  10297. +&pcie {
  10298. + reset-gpio = <&gpio1 29 0>;
  10299. + status = "okay";
  10300. +
  10301. + eth1: sky2@8 { /* MAC/PHY on bus 8 */
  10302. + compatible = "marvell,sky2";
  10303. + };
  10304. +};
  10305. +
  10306. +&ssi1 {
  10307. + fsl,mode = "i2s-slave";
  10308. + status = "okay";
  10309. +};
  10310. +
  10311. +&uart1 {
  10312. + pinctrl-names = "default";
  10313. + pinctrl-0 = <&pinctrl_uart1>;
  10314. + status = "okay";
  10315. +};
  10316. +
  10317. +&uart2 {
  10318. + pinctrl-names = "default";
  10319. + pinctrl-0 = <&pinctrl_uart2>;
  10320. + status = "okay";
  10321. +};
  10322. +
  10323. +&uart5 {
  10324. + pinctrl-names = "default";
  10325. + pinctrl-0 = <&pinctrl_uart5>;
  10326. + status = "okay";
  10327. +};
  10328. +
  10329. +&usbotg {
  10330. + vbus-supply = <&reg_usb_otg_vbus>;
  10331. + pinctrl-names = "default";
  10332. + pinctrl-0 = <&pinctrl_usbotg>;
  10333. + disable-over-current;
  10334. + status = "okay";
  10335. +};
  10336. +
  10337. +&usbh1 {
  10338. + vbus-supply = <&reg_usb_h1_vbus>;
  10339. + status = "okay";
  10340. +};
  10341. +
  10342. +&usdhc3 {
  10343. + pinctrl-names = "default";
  10344. + pinctrl-0 = <&pinctrl_usdhc3>;
  10345. + cd-gpios = <&gpio7 0 0>;
  10346. + vmmc-supply = <&reg_3p3v>;
  10347. + status = "okay";
  10348. +};
  10349. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-gw54xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw54xx.dts
  10350. --- linux-3.14.14/arch/arm/boot/dts/imx6q-gw54xx.dts 1969-12-31 18:00:00.000000000 -0600
  10351. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw54xx.dts 2014-12-08 00:31:51.124418001 -0600
  10352. @@ -0,0 +1,23 @@
  10353. +/*
  10354. + * Copyright 2013 Gateworks Corporation
  10355. + *
  10356. + * The code contained herein is licensed under the GNU General Public
  10357. + * License. You may obtain a copy of the GNU General Public License
  10358. + * Version 2 or later at the following locations:
  10359. + *
  10360. + * http://www.opensource.org/licenses/gpl-license.html
  10361. + * http://www.gnu.org/copyleft/gpl.html
  10362. + */
  10363. +
  10364. +/dts-v1/;
  10365. +#include "imx6q.dtsi"
  10366. +#include "imx6qdl-gw54xx.dtsi"
  10367. +
  10368. +/ {
  10369. + model = "Gateworks Ventana i.MX6 Quad GW54XX";
  10370. + compatible = "gw,imx6q-gw54xx", "gw,ventana", "fsl,imx6q";
  10371. +};
  10372. +
  10373. +&sata {
  10374. + status = "okay";
  10375. +};
  10376. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-hummingboard.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-hummingboard.dts
  10377. --- linux-3.14.14/arch/arm/boot/dts/imx6q-hummingboard.dts 1969-12-31 18:00:00.000000000 -0600
  10378. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-hummingboard.dts 2014-12-08 00:31:51.124418001 -0600
  10379. @@ -0,0 +1,21 @@
  10380. +/*
  10381. + * Copyright (C) 2014 Rabeeh Khoury (rabeeh@solid-run.com)
  10382. + * Based on work by Russell King
  10383. + */
  10384. +/dts-v1/;
  10385. +
  10386. +#include "imx6q.dtsi"
  10387. +#include "imx6qdl-hummingboard.dtsi"
  10388. +
  10389. +/ {
  10390. + model = "SolidRun HummingBoard Dual/Quad";
  10391. + compatible = "solidrun,hummingboard/q", "fsl,imx6q";
  10392. +};
  10393. +
  10394. +&sata {
  10395. + status = "okay";
  10396. + fsl,transmit-level-mV = <1104>;
  10397. + fsl,transmit-boost-mdB = <0>;
  10398. + fsl,transmit-atten-16ths = <9>;
  10399. + fsl,no-spread-spectrum;
  10400. +};
  10401. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-nitrogen6x.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-nitrogen6x.dts
  10402. --- linux-3.14.14/arch/arm/boot/dts/imx6q-nitrogen6x.dts 1969-12-31 18:00:00.000000000 -0600
  10403. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-nitrogen6x.dts 2014-12-08 00:31:51.124418001 -0600
  10404. @@ -0,0 +1,25 @@
  10405. +/*
  10406. + * Copyright 2013 Boundary Devices, Inc.
  10407. + * Copyright 2012 Freescale Semiconductor, Inc.
  10408. + * Copyright 2011 Linaro Ltd.
  10409. + *
  10410. + * The code contained herein is licensed under the GNU General Public
  10411. + * License. You may obtain a copy of the GNU General Public License
  10412. + * Version 2 or later at the following locations:
  10413. + *
  10414. + * http://www.opensource.org/licenses/gpl-license.html
  10415. + * http://www.gnu.org/copyleft/gpl.html
  10416. + */
  10417. +
  10418. +/dts-v1/;
  10419. +#include "imx6q.dtsi"
  10420. +#include "imx6qdl-nitrogen6x.dtsi"
  10421. +
  10422. +/ {
  10423. + model = "Freescale i.MX6 Quad Nitrogen6x Board";
  10424. + compatible = "fsl,imx6q-nitrogen6x", "fsl,imx6q";
  10425. +};
  10426. +
  10427. +&sata {
  10428. + status = "okay";
  10429. +};
  10430. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-phytec-pbab01.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-phytec-pbab01.dts
  10431. --- linux-3.14.14/arch/arm/boot/dts/imx6q-phytec-pbab01.dts 2014-07-28 10:07:25.000000000 -0500
  10432. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-phytec-pbab01.dts 2014-12-08 00:31:51.124418001 -0600
  10433. @@ -11,24 +11,17 @@
  10434. /dts-v1/;
  10435. #include "imx6q-phytec-pfla02.dtsi"
  10436. +#include "imx6qdl-phytec-pbab01.dtsi"
  10437. / {
  10438. model = "Phytec phyFLEX-i.MX6 Quad Carrier-Board";
  10439. compatible = "phytec,imx6q-pbab01", "phytec,imx6q-pfla02", "fsl,imx6q";
  10440. -};
  10441. -
  10442. -&fec {
  10443. - status = "okay";
  10444. -};
  10445. -
  10446. -&uart4 {
  10447. - status = "okay";
  10448. -};
  10449. -&usdhc2 {
  10450. - status = "okay";
  10451. + chosen {
  10452. + stdout-path = &uart4;
  10453. + };
  10454. };
  10455. -&usdhc3 {
  10456. - status = "okay";
  10457. +&sata {
  10458. + status = "okay";
  10459. };
  10460. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi
  10461. --- linux-3.14.14/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi 2014-07-28 10:07:25.000000000 -0500
  10462. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi 2014-12-08 00:31:51.124418001 -0600
  10463. @@ -10,171 +10,13 @@
  10464. */
  10465. #include "imx6q.dtsi"
  10466. +#include "imx6qdl-phytec-pfla02.dtsi"
  10467. / {
  10468. - model = "Phytec phyFLEX-i.MX6 Ouad";
  10469. + model = "Phytec phyFLEX-i.MX6 Quad";
  10470. compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
  10471. memory {
  10472. reg = <0x10000000 0x80000000>;
  10473. };
  10474. };
  10475. -
  10476. -&ecspi3 {
  10477. - pinctrl-names = "default";
  10478. - pinctrl-0 = <&pinctrl_ecspi3_1>;
  10479. - status = "okay";
  10480. - fsl,spi-num-chipselects = <1>;
  10481. - cs-gpios = <&gpio4 24 0>;
  10482. -
  10483. - flash@0 {
  10484. - compatible = "m25p80";
  10485. - spi-max-frequency = <20000000>;
  10486. - reg = <0>;
  10487. - };
  10488. -};
  10489. -
  10490. -&i2c1 {
  10491. - pinctrl-names = "default";
  10492. - pinctrl-0 = <&pinctrl_i2c1_1>;
  10493. - status = "okay";
  10494. -
  10495. - eeprom@50 {
  10496. - compatible = "atmel,24c32";
  10497. - reg = <0x50>;
  10498. - };
  10499. -
  10500. - pmic@58 {
  10501. - compatible = "dialog,da9063";
  10502. - reg = <0x58>;
  10503. - interrupt-parent = <&gpio4>;
  10504. - interrupts = <17 0x8>; /* active-low GPIO4_17 */
  10505. -
  10506. - regulators {
  10507. - vddcore_reg: bcore1 {
  10508. - regulator-min-microvolt = <730000>;
  10509. - regulator-max-microvolt = <1380000>;
  10510. - regulator-always-on;
  10511. - };
  10512. -
  10513. - vddsoc_reg: bcore2 {
  10514. - regulator-min-microvolt = <730000>;
  10515. - regulator-max-microvolt = <1380000>;
  10516. - regulator-always-on;
  10517. - };
  10518. -
  10519. - vdd_ddr3_reg: bpro {
  10520. - regulator-min-microvolt = <1500000>;
  10521. - regulator-max-microvolt = <1500000>;
  10522. - regulator-always-on;
  10523. - };
  10524. -
  10525. - vdd_3v3_reg: bperi {
  10526. - regulator-min-microvolt = <3300000>;
  10527. - regulator-max-microvolt = <3300000>;
  10528. - regulator-always-on;
  10529. - };
  10530. -
  10531. - vdd_buckmem_reg: bmem {
  10532. - regulator-min-microvolt = <3300000>;
  10533. - regulator-max-microvolt = <3300000>;
  10534. - regulator-always-on;
  10535. - };
  10536. -
  10537. - vdd_eth_reg: bio {
  10538. - regulator-min-microvolt = <1200000>;
  10539. - regulator-max-microvolt = <1200000>;
  10540. - regulator-always-on;
  10541. - };
  10542. -
  10543. - vdd_eth_io_reg: ldo4 {
  10544. - regulator-min-microvolt = <2500000>;
  10545. - regulator-max-microvolt = <2500000>;
  10546. - regulator-always-on;
  10547. - };
  10548. -
  10549. - vdd_mx6_snvs_reg: ldo5 {
  10550. - regulator-min-microvolt = <3000000>;
  10551. - regulator-max-microvolt = <3000000>;
  10552. - regulator-always-on;
  10553. - };
  10554. -
  10555. - vdd_3v3_pmic_io_reg: ldo6 {
  10556. - regulator-min-microvolt = <3300000>;
  10557. - regulator-max-microvolt = <3300000>;
  10558. - regulator-always-on;
  10559. - };
  10560. -
  10561. - vdd_sd0_reg: ldo9 {
  10562. - regulator-min-microvolt = <3300000>;
  10563. - regulator-max-microvolt = <3300000>;
  10564. - };
  10565. -
  10566. - vdd_sd1_reg: ldo10 {
  10567. - regulator-min-microvolt = <3300000>;
  10568. - regulator-max-microvolt = <3300000>;
  10569. - };
  10570. -
  10571. - vdd_mx6_high_reg: ldo11 {
  10572. - regulator-min-microvolt = <3000000>;
  10573. - regulator-max-microvolt = <3000000>;
  10574. - regulator-always-on;
  10575. - };
  10576. - };
  10577. - };
  10578. -};
  10579. -
  10580. -&iomuxc {
  10581. - pinctrl-names = "default";
  10582. - pinctrl-0 = <&pinctrl_hog>;
  10583. -
  10584. - hog {
  10585. - pinctrl_hog: hoggrp {
  10586. - fsl,pins = <
  10587. - MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  10588. - MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
  10589. - MX6QDL_PAD_DI0_PIN15__GPIO4_IO17 0x80000000 /* PMIC interrupt */
  10590. - >;
  10591. - };
  10592. - };
  10593. -
  10594. - pfla02 {
  10595. - pinctrl_usdhc3_pfla02: usdhc3grp-pfla02 {
  10596. - fsl,pins = <
  10597. - MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
  10598. - MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
  10599. - >;
  10600. - };
  10601. - };
  10602. -};
  10603. -
  10604. -&fec {
  10605. - pinctrl-names = "default";
  10606. - pinctrl-0 = <&pinctrl_enet_3>;
  10607. - phy-mode = "rgmii";
  10608. - phy-reset-gpios = <&gpio3 23 0>;
  10609. - status = "disabled";
  10610. -};
  10611. -
  10612. -&uart4 {
  10613. - pinctrl-names = "default";
  10614. - pinctrl-0 = <&pinctrl_uart4_1>;
  10615. - status = "disabled";
  10616. -};
  10617. -
  10618. -&usdhc2 {
  10619. - pinctrl-names = "default";
  10620. - pinctrl-0 = <&pinctrl_usdhc2_2>;
  10621. - cd-gpios = <&gpio1 4 0>;
  10622. - wp-gpios = <&gpio1 2 0>;
  10623. - status = "disabled";
  10624. -};
  10625. -
  10626. -&usdhc3 {
  10627. - pinctrl-names = "default";
  10628. - pinctrl-0 = <&pinctrl_usdhc3_2
  10629. - &pinctrl_usdhc3_pfla02>;
  10630. - cd-gpios = <&gpio1 27 0>;
  10631. - wp-gpios = <&gpio1 29 0>;
  10632. - status = "disabled";
  10633. -};
  10634. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-pinfunc.h linux-imx6-3.14/arch/arm/boot/dts/imx6q-pinfunc.h
  10635. --- linux-3.14.14/arch/arm/boot/dts/imx6q-pinfunc.h 2014-07-28 10:07:25.000000000 -0500
  10636. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-pinfunc.h 2014-12-08 00:31:51.124418001 -0600
  10637. @@ -673,6 +673,7 @@
  10638. #define MX6QDL_PAD_GPIO_3__USB_H1_OC 0x22c 0x5fc 0x948 0x6 0x1
  10639. #define MX6QDL_PAD_GPIO_3__MLB_CLK 0x22c 0x5fc 0x900 0x7 0x1
  10640. #define MX6QDL_PAD_GPIO_6__ESAI_TX_CLK 0x230 0x600 0x870 0x0 0x1
  10641. +#define MX6QDL_PAD_GPIO_6__ENET_IRQ 0x230 0x600 0x03c 0x11 0xff000609
  10642. #define MX6QDL_PAD_GPIO_6__I2C3_SDA 0x230 0x600 0x8ac 0x2 0x1
  10643. #define MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x230 0x600 0x000 0x5 0x0
  10644. #define MX6QDL_PAD_GPIO_6__SD2_LCTL 0x230 0x600 0x000 0x6 0x0
  10645. @@ -1024,6 +1025,7 @@
  10646. #define MX6QDL_PAD_SD1_DAT2__WDOG1_RESET_B_DEB 0x34c 0x734 0x000 0x6 0x0
  10647. #define MX6QDL_PAD_SD1_CLK__SD1_CLK 0x350 0x738 0x000 0x0 0x0
  10648. #define MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK 0x350 0x738 0x828 0x1 0x0
  10649. +#define MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT 0x350 0x738 0x000 0x2 0x0
  10650. #define MX6QDL_PAD_SD1_CLK__GPT_CLKIN 0x350 0x738 0x000 0x3 0x0
  10651. #define MX6QDL_PAD_SD1_CLK__GPIO1_IO20 0x350 0x738 0x000 0x5 0x0
  10652. #define MX6QDL_PAD_SD2_CLK__SD2_CLK 0x354 0x73c 0x000 0x0 0x0
  10653. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-sabreauto.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabreauto.dts
  10654. --- linux-3.14.14/arch/arm/boot/dts/imx6q-sabreauto.dts 2014-07-28 10:07:25.000000000 -0500
  10655. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabreauto.dts 2014-12-08 00:31:51.124418001 -0600
  10656. @@ -20,6 +20,22 @@
  10657. compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
  10658. };
  10659. +&mxcfb1 {
  10660. + status = "okay";
  10661. +};
  10662. +
  10663. +&mxcfb2 {
  10664. + status = "okay";
  10665. +};
  10666. +
  10667. +&mxcfb3 {
  10668. + status = "okay";
  10669. +};
  10670. +
  10671. +&mxcfb4 {
  10672. + status = "okay";
  10673. +};
  10674. +
  10675. &sata {
  10676. status = "okay";
  10677. };
  10678. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-sabrelite.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabrelite.dts
  10679. --- linux-3.14.14/arch/arm/boot/dts/imx6q-sabrelite.dts 2014-07-28 10:07:25.000000000 -0500
  10680. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabrelite.dts 2014-12-08 00:31:51.124418001 -0600
  10681. @@ -12,189 +12,13 @@
  10682. /dts-v1/;
  10683. #include "imx6q.dtsi"
  10684. +#include "imx6qdl-sabrelite.dtsi"
  10685. / {
  10686. model = "Freescale i.MX6 Quad SABRE Lite Board";
  10687. compatible = "fsl,imx6q-sabrelite", "fsl,imx6q";
  10688. -
  10689. - memory {
  10690. - reg = <0x10000000 0x40000000>;
  10691. - };
  10692. -
  10693. - regulators {
  10694. - compatible = "simple-bus";
  10695. -
  10696. - reg_2p5v: 2p5v {
  10697. - compatible = "regulator-fixed";
  10698. - regulator-name = "2P5V";
  10699. - regulator-min-microvolt = <2500000>;
  10700. - regulator-max-microvolt = <2500000>;
  10701. - regulator-always-on;
  10702. - };
  10703. -
  10704. - reg_3p3v: 3p3v {
  10705. - compatible = "regulator-fixed";
  10706. - regulator-name = "3P3V";
  10707. - regulator-min-microvolt = <3300000>;
  10708. - regulator-max-microvolt = <3300000>;
  10709. - regulator-always-on;
  10710. - };
  10711. -
  10712. - reg_usb_otg_vbus: usb_otg_vbus {
  10713. - compatible = "regulator-fixed";
  10714. - regulator-name = "usb_otg_vbus";
  10715. - regulator-min-microvolt = <5000000>;
  10716. - regulator-max-microvolt = <5000000>;
  10717. - gpio = <&gpio3 22 0>;
  10718. - enable-active-high;
  10719. - };
  10720. - };
  10721. -
  10722. - sound {
  10723. - compatible = "fsl,imx6q-sabrelite-sgtl5000",
  10724. - "fsl,imx-audio-sgtl5000";
  10725. - model = "imx6q-sabrelite-sgtl5000";
  10726. - ssi-controller = <&ssi1>;
  10727. - audio-codec = <&codec>;
  10728. - audio-routing =
  10729. - "MIC_IN", "Mic Jack",
  10730. - "Mic Jack", "Mic Bias",
  10731. - "Headphone Jack", "HP_OUT";
  10732. - mux-int-port = <1>;
  10733. - mux-ext-port = <4>;
  10734. - };
  10735. -};
  10736. -
  10737. -&audmux {
  10738. - status = "okay";
  10739. - pinctrl-names = "default";
  10740. - pinctrl-0 = <&pinctrl_audmux_1>;
  10741. -};
  10742. -
  10743. -&ecspi1 {
  10744. - fsl,spi-num-chipselects = <1>;
  10745. - cs-gpios = <&gpio3 19 0>;
  10746. - pinctrl-names = "default";
  10747. - pinctrl-0 = <&pinctrl_ecspi1_1>;
  10748. - status = "okay";
  10749. -
  10750. - flash: m25p80@0 {
  10751. - compatible = "sst,sst25vf016b";
  10752. - spi-max-frequency = <20000000>;
  10753. - reg = <0>;
  10754. - };
  10755. -};
  10756. -
  10757. -&fec {
  10758. - pinctrl-names = "default";
  10759. - pinctrl-0 = <&pinctrl_enet_1>;
  10760. - phy-mode = "rgmii";
  10761. - phy-reset-gpios = <&gpio3 23 0>;
  10762. - status = "okay";
  10763. -};
  10764. -
  10765. -&i2c1 {
  10766. - status = "okay";
  10767. - clock-frequency = <100000>;
  10768. - pinctrl-names = "default";
  10769. - pinctrl-0 = <&pinctrl_i2c1_1>;
  10770. -
  10771. - codec: sgtl5000@0a {
  10772. - compatible = "fsl,sgtl5000";
  10773. - reg = <0x0a>;
  10774. - clocks = <&clks 201>;
  10775. - VDDA-supply = <&reg_2p5v>;
  10776. - VDDIO-supply = <&reg_3p3v>;
  10777. - };
  10778. -};
  10779. -
  10780. -&iomuxc {
  10781. - pinctrl-names = "default";
  10782. - pinctrl-0 = <&pinctrl_hog>;
  10783. -
  10784. - hog {
  10785. - pinctrl_hog: hoggrp {
  10786. - fsl,pins = <
  10787. - MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x80000000
  10788. - MX6QDL_PAD_NANDF_D7__GPIO2_IO07 0x80000000
  10789. - MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000
  10790. - MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000
  10791. - MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  10792. - MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000
  10793. - MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0
  10794. - MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x80000000
  10795. - MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  10796. - >;
  10797. - };
  10798. - };
  10799. -};
  10800. -
  10801. -&ldb {
  10802. - status = "okay";
  10803. -
  10804. - lvds-channel@0 {
  10805. - fsl,data-mapping = "spwg";
  10806. - fsl,data-width = <18>;
  10807. - status = "okay";
  10808. -
  10809. - display-timings {
  10810. - native-mode = <&timing0>;
  10811. - timing0: hsd100pxn1 {
  10812. - clock-frequency = <65000000>;
  10813. - hactive = <1024>;
  10814. - vactive = <768>;
  10815. - hback-porch = <220>;
  10816. - hfront-porch = <40>;
  10817. - vback-porch = <21>;
  10818. - vfront-porch = <7>;
  10819. - hsync-len = <60>;
  10820. - vsync-len = <10>;
  10821. - };
  10822. - };
  10823. - };
  10824. };
  10825. &sata {
  10826. status = "okay";
  10827. };
  10828. -
  10829. -&ssi1 {
  10830. - fsl,mode = "i2s-slave";
  10831. - status = "okay";
  10832. -};
  10833. -
  10834. -&uart2 {
  10835. - status = "okay";
  10836. - pinctrl-names = "default";
  10837. - pinctrl-0 = <&pinctrl_uart2_1>;
  10838. -};
  10839. -
  10840. -&usbh1 {
  10841. - status = "okay";
  10842. -};
  10843. -
  10844. -&usbotg {
  10845. - vbus-supply = <&reg_usb_otg_vbus>;
  10846. - pinctrl-names = "default";
  10847. - pinctrl-0 = <&pinctrl_usbotg_1>;
  10848. - disable-over-current;
  10849. - status = "okay";
  10850. -};
  10851. -
  10852. -&usdhc3 {
  10853. - pinctrl-names = "default";
  10854. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  10855. - cd-gpios = <&gpio7 0 0>;
  10856. - wp-gpios = <&gpio7 1 0>;
  10857. - vmmc-supply = <&reg_3p3v>;
  10858. - status = "okay";
  10859. -};
  10860. -
  10861. -&usdhc4 {
  10862. - pinctrl-names = "default";
  10863. - pinctrl-0 = <&pinctrl_usdhc4_2>;
  10864. - cd-gpios = <&gpio2 6 0>;
  10865. - wp-gpios = <&gpio2 7 0>;
  10866. - vmmc-supply = <&reg_3p3v>;
  10867. - status = "okay";
  10868. -};
  10869. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-sabresd.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabresd.dts
  10870. --- linux-3.14.14/arch/arm/boot/dts/imx6q-sabresd.dts 2014-07-28 10:07:25.000000000 -0500
  10871. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabresd.dts 2014-12-08 00:31:51.124418001 -0600
  10872. @@ -23,3 +23,19 @@
  10873. &sata {
  10874. status = "okay";
  10875. };
  10876. +
  10877. +&mxcfb1 {
  10878. + status = "okay";
  10879. +};
  10880. +
  10881. +&mxcfb2 {
  10882. + status = "okay";
  10883. +};
  10884. +
  10885. +&mxcfb3 {
  10886. + status = "okay";
  10887. +};
  10888. +
  10889. +&mxcfb4 {
  10890. + status = "okay";
  10891. +};
  10892. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts
  10893. --- linux-3.14.14/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts 1969-12-31 18:00:00.000000000 -0600
  10894. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts 2014-12-08 00:31:51.124418001 -0600
  10895. @@ -0,0 +1,23 @@
  10896. +/*
  10897. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  10898. + * Copyright 2011 Linaro Ltd.
  10899. + *
  10900. + * The code contained herein is licensed under the GNU General Public
  10901. + * License. You may obtain a copy of the GNU General Public License
  10902. + * Version 2 or later at the following locations:
  10903. + *
  10904. + * http://www.opensource.org/licenses/gpl-license.html
  10905. + * http://www.gnu.org/copyleft/gpl.html
  10906. + */
  10907. +
  10908. +#include "imx6q-sabresd.dts"
  10909. +
  10910. +&hdmi_video {
  10911. + pinctrl-names = "default";
  10912. + pinctrl-0 = <&pinctrl_hdmi_hdcp>;
  10913. + fsl,hdcp;
  10914. +};
  10915. +
  10916. +&i2c2 {
  10917. + status = "disable";
  10918. +};
  10919. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-sbc6x.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-sbc6x.dts
  10920. --- linux-3.14.14/arch/arm/boot/dts/imx6q-sbc6x.dts 2014-07-28 10:07:25.000000000 -0500
  10921. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-sbc6x.dts 2014-12-08 00:31:51.124418001 -0600
  10922. @@ -17,28 +17,78 @@
  10923. };
  10924. };
  10925. +
  10926. &fec {
  10927. pinctrl-names = "default";
  10928. - pinctrl-0 = <&pinctrl_enet_1>;
  10929. + pinctrl-0 = <&pinctrl_enet>;
  10930. phy-mode = "rgmii";
  10931. status = "okay";
  10932. };
  10933. +&iomuxc {
  10934. + imx6q-sbc6x {
  10935. + pinctrl_enet: enetgrp {
  10936. + fsl,pins = <
  10937. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  10938. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  10939. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  10940. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  10941. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  10942. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  10943. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  10944. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  10945. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  10946. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  10947. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  10948. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  10949. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  10950. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  10951. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  10952. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  10953. + >;
  10954. + };
  10955. +
  10956. + pinctrl_uart1: uart1grp {
  10957. + fsl,pins = <
  10958. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  10959. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  10960. + >;
  10961. + };
  10962. +
  10963. + pinctrl_usbotg: usbotggrp {
  10964. + fsl,pins = <
  10965. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  10966. + >;
  10967. + };
  10968. +
  10969. + pinctrl_usdhc3: usdhc3grp {
  10970. + fsl,pins = <
  10971. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  10972. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  10973. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  10974. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  10975. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  10976. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  10977. + >;
  10978. + };
  10979. + };
  10980. +};
  10981. +
  10982. &uart1 {
  10983. pinctrl-names = "default";
  10984. - pinctrl-0 = <&pinctrl_uart1_1>;
  10985. + pinctrl-0 = <&pinctrl_uart1>;
  10986. status = "okay";
  10987. };
  10988. &usbotg {
  10989. pinctrl-names = "default";
  10990. - pinctrl-0 = <&pinctrl_usbotg_1>;
  10991. + pinctrl-0 = <&pinctrl_usbotg>;
  10992. disable-over-current;
  10993. status = "okay";
  10994. };
  10995. &usdhc3 {
  10996. pinctrl-names = "default";
  10997. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  10998. + pinctrl-0 = <&pinctrl_usdhc3>;
  10999. status = "okay";
  11000. };
  11001. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6q-udoo.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-udoo.dts
  11002. --- linux-3.14.14/arch/arm/boot/dts/imx6q-udoo.dts 2014-07-28 10:07:25.000000000 -0500
  11003. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-udoo.dts 2014-12-08 00:31:51.124418001 -0600
  11004. @@ -16,24 +16,78 @@
  11005. model = "Udoo i.MX6 Quad Board";
  11006. compatible = "udoo,imx6q-udoo", "fsl,imx6q";
  11007. + chosen {
  11008. + stdout-path = &uart2;
  11009. + };
  11010. +
  11011. memory {
  11012. reg = <0x10000000 0x40000000>;
  11013. };
  11014. };
  11015. +&fec {
  11016. + pinctrl-names = "default";
  11017. + pinctrl-0 = <&pinctrl_enet>;
  11018. + phy-mode = "rgmii";
  11019. + status = "okay";
  11020. +};
  11021. +
  11022. +&iomuxc {
  11023. + imx6q-udoo {
  11024. + pinctrl_enet: enetgrp {
  11025. + fsl,pins = <
  11026. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  11027. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  11028. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  11029. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  11030. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  11031. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  11032. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  11033. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  11034. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  11035. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  11036. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  11037. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  11038. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  11039. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  11040. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  11041. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  11042. + >;
  11043. + };
  11044. +
  11045. + pinctrl_uart2: uart2grp {
  11046. + fsl,pins = <
  11047. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  11048. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  11049. + >;
  11050. + };
  11051. +
  11052. + pinctrl_usdhc3: usdhc3grp {
  11053. + fsl,pins = <
  11054. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  11055. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  11056. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  11057. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  11058. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  11059. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  11060. + >;
  11061. + };
  11062. + };
  11063. +};
  11064. +
  11065. &sata {
  11066. status = "okay";
  11067. };
  11068. &uart2 {
  11069. pinctrl-names = "default";
  11070. - pinctrl-0 = <&pinctrl_uart2_1>;
  11071. + pinctrl-0 = <&pinctrl_uart2>;
  11072. status = "okay";
  11073. };
  11074. &usdhc3 {
  11075. pinctrl-names = "default";
  11076. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  11077. + pinctrl-0 = <&pinctrl_usdhc3>;
  11078. non-removable;
  11079. status = "okay";
  11080. };
  11081. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6sl.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6sl.dtsi
  11082. --- linux-3.14.14/arch/arm/boot/dts/imx6sl.dtsi 2014-07-28 10:07:25.000000000 -0500
  11083. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6sl.dtsi 2014-12-08 00:31:51.124418001 -0600
  11084. @@ -7,12 +7,14 @@
  11085. *
  11086. */
  11087. +#include <dt-bindings/interrupt-controller/irq.h>
  11088. #include "skeleton.dtsi"
  11089. #include "imx6sl-pinfunc.h"
  11090. #include <dt-bindings/clock/imx6sl-clock.h>
  11091. / {
  11092. aliases {
  11093. + ethernet0 = &fec;
  11094. gpio0 = &gpio1;
  11095. gpio1 = &gpio2;
  11096. gpio2 = &gpio3;
  11097. @@ -27,25 +29,46 @@
  11098. spi1 = &ecspi2;
  11099. spi2 = &ecspi3;
  11100. spi3 = &ecspi4;
  11101. + usbphy0 = &usbphy1;
  11102. + usbphy1 = &usbphy2;
  11103. };
  11104. cpus {
  11105. #address-cells = <1>;
  11106. #size-cells = <0>;
  11107. - cpu@0 {
  11108. + cpu0: cpu@0 {
  11109. compatible = "arm,cortex-a9";
  11110. device_type = "cpu";
  11111. reg = <0x0>;
  11112. next-level-cache = <&L2>;
  11113. + operating-points = <
  11114. + /* kHz uV */
  11115. + 996000 1275000
  11116. + 792000 1175000
  11117. + 396000 975000
  11118. + >;
  11119. + fsl,soc-operating-points = <
  11120. + /* ARM kHz SOC-PU uV */
  11121. + 996000 1225000
  11122. + 792000 1175000
  11123. + 396000 1175000
  11124. + >;
  11125. + clock-latency = <61036>; /* two CLK32 periods */
  11126. + clocks = <&clks IMX6SL_CLK_ARM>, <&clks IMX6SL_CLK_PLL2_PFD2>,
  11127. + <&clks IMX6SL_CLK_STEP>, <&clks IMX6SL_CLK_PLL1_SW>,
  11128. + <&clks IMX6SL_CLK_PLL1_SYS>;
  11129. + clock-names = "arm", "pll2_pfd2_396m", "step",
  11130. + "pll1_sw", "pll1_sys";
  11131. + arm-supply = <&reg_arm>;
  11132. + pu-supply = <&reg_pu>;
  11133. + soc-supply = <&reg_soc>;
  11134. };
  11135. };
  11136. intc: interrupt-controller@00a01000 {
  11137. compatible = "arm,cortex-a9-gic";
  11138. #interrupt-cells = <3>;
  11139. - #address-cells = <1>;
  11140. - #size-cells = <1>;
  11141. interrupt-controller;
  11142. reg = <0x00a01000 0x1000>,
  11143. <0x00a00100 0x100>;
  11144. @@ -57,15 +80,21 @@
  11145. ckil {
  11146. compatible = "fixed-clock";
  11147. + #clock-cells = <0>;
  11148. clock-frequency = <32768>;
  11149. };
  11150. osc {
  11151. compatible = "fixed-clock";
  11152. + #clock-cells = <0>;
  11153. clock-frequency = <24000000>;
  11154. };
  11155. };
  11156. + pu_dummy: pudummy_reg {
  11157. + compatible = "fsl,imx6-dummy-pureg"; /* only used in ldo-bypass */
  11158. + };
  11159. +
  11160. soc {
  11161. #address-cells = <1>;
  11162. #size-cells = <1>;
  11163. @@ -73,19 +102,45 @@
  11164. interrupt-parent = <&intc>;
  11165. ranges;
  11166. + ocram: sram@00900000 {
  11167. + compatible = "mmio-sram";
  11168. + reg = <0x00900000 0x20000>;
  11169. + clocks = <&clks IMX6SL_CLK_OCRAM>;
  11170. + };
  11171. +
  11172. + busfreq { /* BUSFREQ */
  11173. + compatible = "fsl,imx6_busfreq";
  11174. + clocks = <&clks IMX6SL_CLK_PLL2_BUS>, <&clks IMX6SL_CLK_PLL2_PFD2>,
  11175. + <&clks IMX6SL_CLK_PLL2_198M>, <&clks IMX6SL_CLK_ARM>,
  11176. + <&clks IMX6SL_CLK_PLL3_USB_OTG>, <&clks IMX6SL_CLK_PERIPH>,
  11177. + <&clks IMX6SL_CLK_PRE_PERIPH_SEL>, <&clks IMX6SL_CLK_PERIPH_CLK2>,
  11178. + <&clks IMX6SL_CLK_PERIPH_CLK2_SEL>, <&clks IMX6SL_CLK_OSC>,
  11179. + <&clks IMX6SL_CLK_PLL1_SYS>, <&clks IMX6SL_CLK_PERIPH2>,
  11180. + <&clks IMX6SL_CLK_AHB>, <&clks IMX6SL_CLK_OCRAM>,
  11181. + <&clks IMX6SL_CLK_PLL1_SW>, <&clks IMX6SL_CLK_PRE_PERIPH2_SEL>,
  11182. + <&clks IMX6SL_CLK_PERIPH2_CLK2_SEL>, <&clks IMX6SL_CLK_PERIPH2_CLK2>,
  11183. + <&clks IMX6SL_CLK_STEP>;
  11184. + clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
  11185. + "periph_pre", "periph_clk2", "periph_clk2_sel", "osc", "pll1_sys", "periph2", "ahb", "ocram", "pll1_sw",
  11186. + "periph2_pre", "periph2_clk2_sel", "periph2_clk2", "step";
  11187. + fsl,max_ddr_freq = <400000000>;
  11188. + };
  11189. +
  11190. L2: l2-cache@00a02000 {
  11191. compatible = "arm,pl310-cache";
  11192. reg = <0x00a02000 0x1000>;
  11193. - interrupts = <0 92 0x04>;
  11194. + interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
  11195. cache-unified;
  11196. cache-level = <2>;
  11197. arm,tag-latency = <4 2 3>;
  11198. arm,data-latency = <4 2 3>;
  11199. + arm,dynamic-clk-gating;
  11200. + arm,standby-mode;
  11201. };
  11202. pmu {
  11203. compatible = "arm,cortex-a9-pmu";
  11204. - interrupts = <0 94 0x04>;
  11205. + interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
  11206. };
  11207. aips1: aips-bus@02000000 {
  11208. @@ -104,7 +159,7 @@
  11209. spdif: spdif@02004000 {
  11210. reg = <0x02004000 0x4000>;
  11211. - interrupts = <0 52 0x04>;
  11212. + interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
  11213. };
  11214. ecspi1: ecspi@02008000 {
  11215. @@ -112,7 +167,7 @@
  11216. #size-cells = <0>;
  11217. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11218. reg = <0x02008000 0x4000>;
  11219. - interrupts = <0 31 0x04>;
  11220. + interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
  11221. clocks = <&clks IMX6SL_CLK_ECSPI1>,
  11222. <&clks IMX6SL_CLK_ECSPI1>;
  11223. clock-names = "ipg", "per";
  11224. @@ -124,7 +179,7 @@
  11225. #size-cells = <0>;
  11226. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11227. reg = <0x0200c000 0x4000>;
  11228. - interrupts = <0 32 0x04>;
  11229. + interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
  11230. clocks = <&clks IMX6SL_CLK_ECSPI2>,
  11231. <&clks IMX6SL_CLK_ECSPI2>;
  11232. clock-names = "ipg", "per";
  11233. @@ -136,7 +191,7 @@
  11234. #size-cells = <0>;
  11235. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11236. reg = <0x02010000 0x4000>;
  11237. - interrupts = <0 33 0x04>;
  11238. + interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
  11239. clocks = <&clks IMX6SL_CLK_ECSPI3>,
  11240. <&clks IMX6SL_CLK_ECSPI3>;
  11241. clock-names = "ipg", "per";
  11242. @@ -148,7 +203,7 @@
  11243. #size-cells = <0>;
  11244. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11245. reg = <0x02014000 0x4000>;
  11246. - interrupts = <0 34 0x04>;
  11247. + interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
  11248. clocks = <&clks IMX6SL_CLK_ECSPI4>,
  11249. <&clks IMX6SL_CLK_ECSPI4>;
  11250. clock-names = "ipg", "per";
  11251. @@ -159,7 +214,7 @@
  11252. compatible = "fsl,imx6sl-uart",
  11253. "fsl,imx6q-uart", "fsl,imx21-uart";
  11254. reg = <0x02018000 0x4000>;
  11255. - interrupts = <0 30 0x04>;
  11256. + interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
  11257. clocks = <&clks IMX6SL_CLK_UART>,
  11258. <&clks IMX6SL_CLK_UART_SERIAL>;
  11259. clock-names = "ipg", "per";
  11260. @@ -172,7 +227,7 @@
  11261. compatible = "fsl,imx6sl-uart",
  11262. "fsl,imx6q-uart", "fsl,imx21-uart";
  11263. reg = <0x02020000 0x4000>;
  11264. - interrupts = <0 26 0x04>;
  11265. + interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
  11266. clocks = <&clks IMX6SL_CLK_UART>,
  11267. <&clks IMX6SL_CLK_UART_SERIAL>;
  11268. clock-names = "ipg", "per";
  11269. @@ -185,7 +240,7 @@
  11270. compatible = "fsl,imx6sl-uart",
  11271. "fsl,imx6q-uart", "fsl,imx21-uart";
  11272. reg = <0x02024000 0x4000>;
  11273. - interrupts = <0 27 0x04>;
  11274. + interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
  11275. clocks = <&clks IMX6SL_CLK_UART>,
  11276. <&clks IMX6SL_CLK_UART_SERIAL>;
  11277. clock-names = "ipg", "per";
  11278. @@ -195,9 +250,11 @@
  11279. };
  11280. ssi1: ssi@02028000 {
  11281. - compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
  11282. + compatible = "fsl,imx6sl-ssi",
  11283. + "fsl,imx51-ssi",
  11284. + "fsl,imx21-ssi";
  11285. reg = <0x02028000 0x4000>;
  11286. - interrupts = <0 46 0x04>;
  11287. + interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
  11288. clocks = <&clks IMX6SL_CLK_SSI1>;
  11289. dmas = <&sdma 37 1 0>,
  11290. <&sdma 38 1 0>;
  11291. @@ -207,9 +264,11 @@
  11292. };
  11293. ssi2: ssi@0202c000 {
  11294. - compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
  11295. + compatible = "fsl,imx6sl-ssi",
  11296. + "fsl,imx51-ssi",
  11297. + "fsl,imx21-ssi";
  11298. reg = <0x0202c000 0x4000>;
  11299. - interrupts = <0 47 0x04>;
  11300. + interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
  11301. clocks = <&clks IMX6SL_CLK_SSI2>;
  11302. dmas = <&sdma 41 1 0>,
  11303. <&sdma 42 1 0>;
  11304. @@ -219,9 +278,11 @@
  11305. };
  11306. ssi3: ssi@02030000 {
  11307. - compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
  11308. + compatible = "fsl,imx6sl-ssi",
  11309. + "fsl,imx51-ssi",
  11310. + "fsl,imx21-ssi";
  11311. reg = <0x02030000 0x4000>;
  11312. - interrupts = <0 48 0x04>;
  11313. + interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
  11314. clocks = <&clks IMX6SL_CLK_SSI3>;
  11315. dmas = <&sdma 45 1 0>,
  11316. <&sdma 46 1 0>;
  11317. @@ -234,7 +295,7 @@
  11318. compatible = "fsl,imx6sl-uart",
  11319. "fsl,imx6q-uart", "fsl,imx21-uart";
  11320. reg = <0x02034000 0x4000>;
  11321. - interrupts = <0 28 0x04>;
  11322. + interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
  11323. clocks = <&clks IMX6SL_CLK_UART>,
  11324. <&clks IMX6SL_CLK_UART_SERIAL>;
  11325. clock-names = "ipg", "per";
  11326. @@ -247,7 +308,7 @@
  11327. compatible = "fsl,imx6sl-uart",
  11328. "fsl,imx6q-uart", "fsl,imx21-uart";
  11329. reg = <0x02038000 0x4000>;
  11330. - interrupts = <0 29 0x04>;
  11331. + interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
  11332. clocks = <&clks IMX6SL_CLK_UART>,
  11333. <&clks IMX6SL_CLK_UART_SERIAL>;
  11334. clock-names = "ipg", "per";
  11335. @@ -261,7 +322,7 @@
  11336. #pwm-cells = <2>;
  11337. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11338. reg = <0x02080000 0x4000>;
  11339. - interrupts = <0 83 0x04>;
  11340. + interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
  11341. clocks = <&clks IMX6SL_CLK_PWM1>,
  11342. <&clks IMX6SL_CLK_PWM1>;
  11343. clock-names = "ipg", "per";
  11344. @@ -271,7 +332,7 @@
  11345. #pwm-cells = <2>;
  11346. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11347. reg = <0x02084000 0x4000>;
  11348. - interrupts = <0 84 0x04>;
  11349. + interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
  11350. clocks = <&clks IMX6SL_CLK_PWM2>,
  11351. <&clks IMX6SL_CLK_PWM2>;
  11352. clock-names = "ipg", "per";
  11353. @@ -281,7 +342,7 @@
  11354. #pwm-cells = <2>;
  11355. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11356. reg = <0x02088000 0x4000>;
  11357. - interrupts = <0 85 0x04>;
  11358. + interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
  11359. clocks = <&clks IMX6SL_CLK_PWM3>,
  11360. <&clks IMX6SL_CLK_PWM3>;
  11361. clock-names = "ipg", "per";
  11362. @@ -291,7 +352,7 @@
  11363. #pwm-cells = <2>;
  11364. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11365. reg = <0x0208c000 0x4000>;
  11366. - interrupts = <0 86 0x04>;
  11367. + interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
  11368. clocks = <&clks IMX6SL_CLK_PWM4>,
  11369. <&clks IMX6SL_CLK_PWM4>;
  11370. clock-names = "ipg", "per";
  11371. @@ -300,7 +361,7 @@
  11372. gpt: gpt@02098000 {
  11373. compatible = "fsl,imx6sl-gpt";
  11374. reg = <0x02098000 0x4000>;
  11375. - interrupts = <0 55 0x04>;
  11376. + interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
  11377. clocks = <&clks IMX6SL_CLK_GPT>,
  11378. <&clks IMX6SL_CLK_GPT_SERIAL>;
  11379. clock-names = "ipg", "per";
  11380. @@ -309,7 +370,8 @@
  11381. gpio1: gpio@0209c000 {
  11382. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11383. reg = <0x0209c000 0x4000>;
  11384. - interrupts = <0 66 0x04 0 67 0x04>;
  11385. + interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
  11386. + <0 67 IRQ_TYPE_LEVEL_HIGH>;
  11387. gpio-controller;
  11388. #gpio-cells = <2>;
  11389. interrupt-controller;
  11390. @@ -319,7 +381,8 @@
  11391. gpio2: gpio@020a0000 {
  11392. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11393. reg = <0x020a0000 0x4000>;
  11394. - interrupts = <0 68 0x04 0 69 0x04>;
  11395. + interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
  11396. + <0 69 IRQ_TYPE_LEVEL_HIGH>;
  11397. gpio-controller;
  11398. #gpio-cells = <2>;
  11399. interrupt-controller;
  11400. @@ -329,7 +392,8 @@
  11401. gpio3: gpio@020a4000 {
  11402. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11403. reg = <0x020a4000 0x4000>;
  11404. - interrupts = <0 70 0x04 0 71 0x04>;
  11405. + interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
  11406. + <0 71 IRQ_TYPE_LEVEL_HIGH>;
  11407. gpio-controller;
  11408. #gpio-cells = <2>;
  11409. interrupt-controller;
  11410. @@ -339,7 +403,8 @@
  11411. gpio4: gpio@020a8000 {
  11412. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11413. reg = <0x020a8000 0x4000>;
  11414. - interrupts = <0 72 0x04 0 73 0x04>;
  11415. + interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
  11416. + <0 73 IRQ_TYPE_LEVEL_HIGH>;
  11417. gpio-controller;
  11418. #gpio-cells = <2>;
  11419. interrupt-controller;
  11420. @@ -349,7 +414,8 @@
  11421. gpio5: gpio@020ac000 {
  11422. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11423. reg = <0x020ac000 0x4000>;
  11424. - interrupts = <0 74 0x04 0 75 0x04>;
  11425. + interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
  11426. + <0 75 IRQ_TYPE_LEVEL_HIGH>;
  11427. gpio-controller;
  11428. #gpio-cells = <2>;
  11429. interrupt-controller;
  11430. @@ -357,21 +423,23 @@
  11431. };
  11432. kpp: kpp@020b8000 {
  11433. + compatible = "fsl,imx6sl-kpp", "fsl,imx21-kpp";
  11434. reg = <0x020b8000 0x4000>;
  11435. - interrupts = <0 82 0x04>;
  11436. + interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
  11437. + clocks = <&clks IMX6SL_CLK_DUMMY>;
  11438. };
  11439. wdog1: wdog@020bc000 {
  11440. compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
  11441. reg = <0x020bc000 0x4000>;
  11442. - interrupts = <0 80 0x04>;
  11443. + interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
  11444. clocks = <&clks IMX6SL_CLK_DUMMY>;
  11445. };
  11446. wdog2: wdog@020c0000 {
  11447. compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
  11448. reg = <0x020c0000 0x4000>;
  11449. - interrupts = <0 81 0x04>;
  11450. + interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
  11451. clocks = <&clks IMX6SL_CLK_DUMMY>;
  11452. status = "disabled";
  11453. };
  11454. @@ -379,7 +447,8 @@
  11455. clks: ccm@020c4000 {
  11456. compatible = "fsl,imx6sl-ccm";
  11457. reg = <0x020c4000 0x4000>;
  11458. - interrupts = <0 87 0x04 0 88 0x04>;
  11459. + interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
  11460. + <0 88 IRQ_TYPE_LEVEL_HIGH>;
  11461. #clock-cells = <1>;
  11462. };
  11463. @@ -388,7 +457,9 @@
  11464. "fsl,imx6q-anatop",
  11465. "syscon", "simple-bus";
  11466. reg = <0x020c8000 0x1000>;
  11467. - interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
  11468. + interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
  11469. + <0 54 IRQ_TYPE_LEVEL_HIGH>,
  11470. + <0 127 IRQ_TYPE_LEVEL_HIGH>;
  11471. regulator-1p1@110 {
  11472. compatible = "fsl,anatop-regulator";
  11473. @@ -434,7 +505,7 @@
  11474. reg_arm: regulator-vddcore@140 {
  11475. compatible = "fsl,anatop-regulator";
  11476. - regulator-name = "cpu";
  11477. + regulator-name = "vddarm";
  11478. regulator-min-microvolt = <725000>;
  11479. regulator-max-microvolt = <1450000>;
  11480. regulator-always-on;
  11481. @@ -454,7 +525,6 @@
  11482. regulator-name = "vddpu";
  11483. regulator-min-microvolt = <725000>;
  11484. regulator-max-microvolt = <1450000>;
  11485. - regulator-always-on;
  11486. anatop-reg-offset = <0x140>;
  11487. anatop-vol-bit-shift = <9>;
  11488. anatop-vol-bit-width = <5>;
  11489. @@ -484,18 +554,34 @@
  11490. };
  11491. };
  11492. + tempmon: tempmon {
  11493. + compatible = "fsl,imx6sl-tempmon", "fsl,imx6q-tempmon";
  11494. + interrupts = <0 49 0x04>;
  11495. + fsl,tempmon = <&anatop>;
  11496. + fsl,tempmon-data = <&ocotp>;
  11497. + clocks = <&clks IMX6SL_CLK_PLL3_USB_OTG>;
  11498. + };
  11499. +
  11500. usbphy1: usbphy@020c9000 {
  11501. compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
  11502. reg = <0x020c9000 0x1000>;
  11503. - interrupts = <0 44 0x04>;
  11504. + interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
  11505. clocks = <&clks IMX6SL_CLK_USBPHY1>;
  11506. + fsl,anatop = <&anatop>;
  11507. };
  11508. usbphy2: usbphy@020ca000 {
  11509. compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
  11510. reg = <0x020ca000 0x1000>;
  11511. - interrupts = <0 45 0x04>;
  11512. + interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
  11513. clocks = <&clks IMX6SL_CLK_USBPHY2>;
  11514. + fsl,anatop = <&anatop>;
  11515. + };
  11516. +
  11517. + usbphy_nop1: usbphy_nop1 {
  11518. + compatible = "usb-nop-xceiv";
  11519. + clocks = <&clks IMX6SL_CLK_USBPHY1>;
  11520. + clock-names = "main_clk";
  11521. };
  11522. snvs@020cc000 {
  11523. @@ -507,271 +593,165 @@
  11524. snvs-rtc-lp@34 {
  11525. compatible = "fsl,sec-v4.0-mon-rtc-lp";
  11526. reg = <0x34 0x58>;
  11527. - interrupts = <0 19 0x04 0 20 0x04>;
  11528. + interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
  11529. + <0 20 IRQ_TYPE_LEVEL_HIGH>;
  11530. };
  11531. - };
  11532. -
  11533. - epit1: epit@020d0000 {
  11534. - reg = <0x020d0000 0x4000>;
  11535. - interrupts = <0 56 0x04>;
  11536. - };
  11537. - epit2: epit@020d4000 {
  11538. - reg = <0x020d4000 0x4000>;
  11539. - interrupts = <0 57 0x04>;
  11540. - };
  11541. -
  11542. - src: src@020d8000 {
  11543. - compatible = "fsl,imx6sl-src", "fsl,imx51-src";
  11544. - reg = <0x020d8000 0x4000>;
  11545. - interrupts = <0 91 0x04 0 96 0x04>;
  11546. - #reset-cells = <1>;
  11547. - };
  11548. -
  11549. - gpc: gpc@020dc000 {
  11550. - compatible = "fsl,imx6sl-gpc", "fsl,imx6q-gpc";
  11551. - reg = <0x020dc000 0x4000>;
  11552. - interrupts = <0 89 0x04>;
  11553. - };
  11554. -
  11555. - gpr: iomuxc-gpr@020e0000 {
  11556. - compatible = "fsl,imx6sl-iomuxc-gpr",
  11557. - "fsl,imx6q-iomuxc-gpr", "syscon";
  11558. - reg = <0x020e0000 0x38>;
  11559. - };
  11560. -
  11561. - iomuxc: iomuxc@020e0000 {
  11562. - compatible = "fsl,imx6sl-iomuxc";
  11563. - reg = <0x020e0000 0x4000>;
  11564. -
  11565. - ecspi1 {
  11566. - pinctrl_ecspi1_1: ecspi1grp-1 {
  11567. + csi {
  11568. + pinctrl_csi_0: csigrp-0 {
  11569. fsl,pins = <
  11570. - MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
  11571. - MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
  11572. - MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
  11573. + MX6SL_PAD_EPDC_GDRL__CSI_MCLK 0x110b0
  11574. + MX6SL_PAD_EPDC_GDCLK__CSI_PIXCLK 0x110b0
  11575. + MX6SL_PAD_EPDC_GDSP__CSI_VSYNC 0x110b0
  11576. + MX6SL_PAD_EPDC_GDOE__CSI_HSYNC 0x110b0
  11577. + MX6SL_PAD_EPDC_SDLE__CSI_DATA09 0x110b0
  11578. + MX6SL_PAD_EPDC_SDCLK__CSI_DATA08 0x110b0
  11579. + MX6SL_PAD_EPDC_D7__CSI_DATA07 0x110b0
  11580. + MX6SL_PAD_EPDC_D6__CSI_DATA06 0x110b0
  11581. + MX6SL_PAD_EPDC_D5__CSI_DATA05 0x110b0
  11582. + MX6SL_PAD_EPDC_D4__CSI_DATA04 0x110b0
  11583. + MX6SL_PAD_EPDC_D3__CSI_DATA03 0x110b0
  11584. + MX6SL_PAD_EPDC_D2__CSI_DATA02 0x110b0
  11585. + MX6SL_PAD_EPDC_D1__CSI_DATA01 0x110b0
  11586. + MX6SL_PAD_EPDC_D0__CSI_DATA00 0x110b0
  11587. + MX6SL_PAD_EPDC_SDSHR__GPIO1_IO26 0x80000000
  11588. + MX6SL_PAD_EPDC_SDOE__GPIO1_IO25 0x80000000
  11589. >;
  11590. };
  11591. };
  11592. - fec {
  11593. - pinctrl_fec_1: fecgrp-1 {
  11594. + i2c1 {
  11595. + pinctrl_i2c1_1: i2c1grp-1 {
  11596. fsl,pins = <
  11597. - MX6SL_PAD_FEC_MDC__FEC_MDC 0x1b0b0
  11598. - MX6SL_PAD_FEC_MDIO__FEC_MDIO 0x1b0b0
  11599. - MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV 0x1b0b0
  11600. - MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0 0x1b0b0
  11601. - MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1 0x1b0b0
  11602. - MX6SL_PAD_FEC_TX_EN__FEC_TX_EN 0x1b0b0
  11603. - MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0 0x1b0b0
  11604. - MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1 0x1b0b0
  11605. - MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x4001b0a8
  11606. + MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1
  11607. + MX6SL_PAD_I2C1_SDA__I2C1_SDA 0x4001b8b1
  11608. >;
  11609. };
  11610. };
  11611. - uart1 {
  11612. - pinctrl_uart1_1: uart1grp-1 {
  11613. + i2c2 {
  11614. + pinctrl_i2c2_1: i2c2grp-1 {
  11615. fsl,pins = <
  11616. - MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x1b0b1
  11617. - MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1
  11618. + MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x4001b8b1
  11619. + MX6SL_PAD_I2C2_SDA__I2C2_SDA 0x4001b8b1
  11620. >;
  11621. };
  11622. };
  11623. - usbotg1 {
  11624. - pinctrl_usbotg1_1: usbotg1grp-1 {
  11625. - fsl,pins = <
  11626. - MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059
  11627. - >;
  11628. - };
  11629. -
  11630. - pinctrl_usbotg1_2: usbotg1grp-2 {
  11631. + i2c3 {
  11632. + pinctrl_i2c3_1: i2c3grp-1 {
  11633. fsl,pins = <
  11634. - MX6SL_PAD_FEC_RXD0__USB_OTG1_ID 0x17059
  11635. - >;
  11636. - };
  11637. -
  11638. - pinctrl_usbotg1_3: usbotg1grp-3 {
  11639. - fsl,pins = <
  11640. - MX6SL_PAD_LCD_DAT1__USB_OTG1_ID 0x17059
  11641. - >;
  11642. - };
  11643. -
  11644. - pinctrl_usbotg1_4: usbotg1grp-4 {
  11645. - fsl,pins = <
  11646. - MX6SL_PAD_REF_CLK_32K__USB_OTG1_ID 0x17059
  11647. - >;
  11648. - };
  11649. -
  11650. - pinctrl_usbotg1_5: usbotg1grp-5 {
  11651. - fsl,pins = <
  11652. - MX6SL_PAD_SD3_DAT0__USB_OTG1_ID 0x17059
  11653. + MX6SL_PAD_EPDC_SDCE2__I2C3_SCL 0x4001b8b1
  11654. + MX6SL_PAD_EPDC_SDCE3__I2C3_SDA 0x4001b8b1
  11655. >;
  11656. };
  11657. };
  11658. - usbotg2 {
  11659. - pinctrl_usbotg2_1: usbotg2grp-1 {
  11660. - fsl,pins = <
  11661. - MX6SL_PAD_ECSPI1_SCLK__USB_OTG2_OC 0x17059
  11662. - >;
  11663. - };
  11664. -
  11665. - pinctrl_usbotg2_2: usbotg2grp-2 {
  11666. + lcdif {
  11667. + pinctrl_lcdif_dat_0: lcdifdatgrp-0 {
  11668. fsl,pins = <
  11669. - MX6SL_PAD_ECSPI2_SCLK__USB_OTG2_OC 0x17059
  11670. + MX6SL_PAD_LCD_DAT0__LCD_DATA00 0x1b0b0
  11671. + MX6SL_PAD_LCD_DAT1__LCD_DATA01 0x1b0b0
  11672. + MX6SL_PAD_LCD_DAT2__LCD_DATA02 0x1b0b0
  11673. + MX6SL_PAD_LCD_DAT3__LCD_DATA03 0x1b0b0
  11674. + MX6SL_PAD_LCD_DAT4__LCD_DATA04 0x1b0b0
  11675. + MX6SL_PAD_LCD_DAT5__LCD_DATA05 0x1b0b0
  11676. + MX6SL_PAD_LCD_DAT6__LCD_DATA06 0x1b0b0
  11677. + MX6SL_PAD_LCD_DAT7__LCD_DATA07 0x1b0b0
  11678. + MX6SL_PAD_LCD_DAT8__LCD_DATA08 0x1b0b0
  11679. + MX6SL_PAD_LCD_DAT9__LCD_DATA09 0x1b0b0
  11680. + MX6SL_PAD_LCD_DAT10__LCD_DATA10 0x1b0b0
  11681. + MX6SL_PAD_LCD_DAT11__LCD_DATA11 0x1b0b0
  11682. + MX6SL_PAD_LCD_DAT12__LCD_DATA12 0x1b0b0
  11683. + MX6SL_PAD_LCD_DAT13__LCD_DATA13 0x1b0b0
  11684. + MX6SL_PAD_LCD_DAT14__LCD_DATA14 0x1b0b0
  11685. + MX6SL_PAD_LCD_DAT15__LCD_DATA15 0x1b0b0
  11686. + MX6SL_PAD_LCD_DAT16__LCD_DATA16 0x1b0b0
  11687. + MX6SL_PAD_LCD_DAT17__LCD_DATA17 0x1b0b0
  11688. + MX6SL_PAD_LCD_DAT18__LCD_DATA18 0x1b0b0
  11689. + MX6SL_PAD_LCD_DAT19__LCD_DATA19 0x1b0b0
  11690. + MX6SL_PAD_LCD_DAT20__LCD_DATA20 0x1b0b0
  11691. + MX6SL_PAD_LCD_DAT21__LCD_DATA21 0x1b0b0
  11692. + MX6SL_PAD_LCD_DAT22__LCD_DATA22 0x1b0b0
  11693. + MX6SL_PAD_LCD_DAT23__LCD_DATA23 0x1b0b0
  11694. >;
  11695. };
  11696. - pinctrl_usbotg2_3: usbotg2grp-3 {
  11697. + pinctrl_lcdif_ctrl_0: lcdifctrlgrp-0 {
  11698. fsl,pins = <
  11699. - MX6SL_PAD_KEY_ROW5__USB_OTG2_OC 0x17059
  11700. - >;
  11701. - };
  11702. -
  11703. - pinctrl_usbotg2_4: usbotg2grp-4 {
  11704. - fsl,pins = <
  11705. - MX6SL_PAD_SD3_DAT2__USB_OTG2_OC 0x17059
  11706. + MX6SL_PAD_LCD_CLK__LCD_CLK 0x1b0b0
  11707. + MX6SL_PAD_LCD_ENABLE__LCD_ENABLE 0x1b0b0
  11708. + MX6SL_PAD_LCD_HSYNC__LCD_HSYNC 0x1b0b0
  11709. + MX6SL_PAD_LCD_VSYNC__LCD_VSYNC 0x1b0b0
  11710. + MX6SL_PAD_LCD_RESET__LCD_RESET 0x1b0b0
  11711. >;
  11712. };
  11713. };
  11714. - usdhc1 {
  11715. - pinctrl_usdhc1_1: usdhc1grp-1 {
  11716. + pwm1 {
  11717. + pinctrl_pwm1_0: pwm1grp-0 {
  11718. fsl,pins = <
  11719. - MX6SL_PAD_SD1_CMD__SD1_CMD 0x17059
  11720. - MX6SL_PAD_SD1_CLK__SD1_CLK 0x10059
  11721. - MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  11722. - MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  11723. - MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  11724. - MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  11725. - MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x17059
  11726. - MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x17059
  11727. - MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x17059
  11728. - MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x17059
  11729. + MX6SL_PAD_PWM1__PWM1_OUT 0x110b0
  11730. >;
  11731. };
  11732. -
  11733. - pinctrl_usdhc1_1_100mhz: usdhc1grp-1-100mhz {
  11734. - fsl,pins = <
  11735. - MX6SL_PAD_SD1_CMD__SD1_CMD 0x170b9
  11736. - MX6SL_PAD_SD1_CLK__SD1_CLK 0x100b9
  11737. - MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170b9
  11738. - MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170b9
  11739. - MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170b9
  11740. - MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170b9
  11741. - MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170b9
  11742. - MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170b9
  11743. - MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170b9
  11744. - MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170b9
  11745. - >;
  11746. - };
  11747. -
  11748. - pinctrl_usdhc1_1_200mhz: usdhc1grp-1-200mhz {
  11749. - fsl,pins = <
  11750. - MX6SL_PAD_SD1_CMD__SD1_CMD 0x170f9
  11751. - MX6SL_PAD_SD1_CLK__SD1_CLK 0x100f9
  11752. - MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
  11753. - MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
  11754. - MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
  11755. - MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
  11756. - MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170f9
  11757. - MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170f9
  11758. - MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170f9
  11759. - MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170f9
  11760. - >;
  11761. - };
  11762. -
  11763. -
  11764. };
  11765. + };
  11766. - usdhc2 {
  11767. - pinctrl_usdhc2_1: usdhc2grp-1 {
  11768. - fsl,pins = <
  11769. - MX6SL_PAD_SD2_CMD__SD2_CMD 0x17059
  11770. - MX6SL_PAD_SD2_CLK__SD2_CLK 0x10059
  11771. - MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  11772. - MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  11773. - MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  11774. - MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  11775. - >;
  11776. - };
  11777. -
  11778. - pinctrl_usdhc2_1_100mhz: usdhc2grp-1-100mhz {
  11779. - fsl,pins = <
  11780. - MX6SL_PAD_SD2_CMD__SD2_CMD 0x170b9
  11781. - MX6SL_PAD_SD2_CLK__SD2_CLK 0x100b9
  11782. - MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
  11783. - MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
  11784. - MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
  11785. - MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170b9
  11786. - >;
  11787. - };
  11788. + epit1: epit@020d0000 {
  11789. + reg = <0x020d0000 0x4000>;
  11790. + interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
  11791. + };
  11792. - pinctrl_usdhc2_1_200mhz: usdhc2grp-1-200mhz {
  11793. - fsl,pins = <
  11794. - MX6SL_PAD_SD2_CMD__SD2_CMD 0x170f9
  11795. - MX6SL_PAD_SD2_CLK__SD2_CLK 0x100f9
  11796. - MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
  11797. - MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
  11798. - MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
  11799. - MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170f9
  11800. - >;
  11801. - };
  11802. + epit2: epit@020d4000 {
  11803. + reg = <0x020d4000 0x4000>;
  11804. + interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
  11805. + };
  11806. - };
  11807. + src: src@020d8000 {
  11808. + compatible = "fsl,imx6sl-src", "fsl,imx51-src";
  11809. + reg = <0x020d8000 0x4000>;
  11810. + interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
  11811. + <0 96 IRQ_TYPE_LEVEL_HIGH>;
  11812. + #reset-cells = <1>;
  11813. + };
  11814. - usdhc3 {
  11815. - pinctrl_usdhc3_1: usdhc3grp-1 {
  11816. - fsl,pins = <
  11817. - MX6SL_PAD_SD3_CMD__SD3_CMD 0x17059
  11818. - MX6SL_PAD_SD3_CLK__SD3_CLK 0x10059
  11819. - MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  11820. - MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  11821. - MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  11822. - MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  11823. - >;
  11824. - };
  11825. + gpc: gpc@020dc000 {
  11826. + compatible = "fsl,imx6sl-gpc", "fsl,imx6q-gpc";
  11827. + reg = <0x020dc000 0x4000>;
  11828. + interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
  11829. + clocks = <&clks IMX6SL_CLK_GPU2D_PODF>, <&clks IMX6SL_CLK_GPU2D_OVG>,
  11830. + <&clks IMX6SL_CLK_IPG>;
  11831. + clock-names = "gpu2d_podf", "gpu2d_ovg", "ipg";
  11832. + pu-supply = <&reg_pu>;
  11833. + };
  11834. - pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz {
  11835. - fsl,pins = <
  11836. - MX6SL_PAD_SD3_CMD__SD3_CMD 0x170b9
  11837. - MX6SL_PAD_SD3_CLK__SD3_CLK 0x100b9
  11838. - MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  11839. - MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  11840. - MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  11841. - MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  11842. - >;
  11843. - };
  11844. + gpr: iomuxc-gpr@020e0000 {
  11845. + compatible = "fsl,imx6sl-iomuxc-gpr",
  11846. + "fsl,imx6q-iomuxc-gpr", "syscon";
  11847. + reg = <0x020e0000 0x38>;
  11848. + };
  11849. - pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz {
  11850. - fsl,pins = <
  11851. - MX6SL_PAD_SD3_CMD__SD3_CMD 0x170f9
  11852. - MX6SL_PAD_SD3_CLK__SD3_CLK 0x100f9
  11853. - MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  11854. - MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  11855. - MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  11856. - MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  11857. - >;
  11858. - };
  11859. - };
  11860. + iomuxc: iomuxc@020e0000 {
  11861. + compatible = "fsl,imx6sl-iomuxc";
  11862. + reg = <0x020e0000 0x4000>;
  11863. };
  11864. csi: csi@020e4000 {
  11865. + compatible = "fsl,imx6sl-csi";
  11866. reg = <0x020e4000 0x4000>;
  11867. - interrupts = <0 7 0x04>;
  11868. + interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
  11869. + status = "disabled";
  11870. };
  11871. spdc: spdc@020e8000 {
  11872. reg = <0x020e8000 0x4000>;
  11873. - interrupts = <0 6 0x04>;
  11874. + interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
  11875. };
  11876. sdma: sdma@020ec000 {
  11877. compatible = "fsl,imx6sl-sdma", "fsl,imx35-sdma";
  11878. reg = <0x020ec000 0x4000>;
  11879. - interrupts = <0 2 0x04>;
  11880. + interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
  11881. clocks = <&clks IMX6SL_CLK_SDMA>,
  11882. <&clks IMX6SL_CLK_SDMA>;
  11883. clock-names = "ipg", "ahb";
  11884. @@ -781,23 +761,32 @@
  11885. };
  11886. pxp: pxp@020f0000 {
  11887. + compatible = "fsl,imx6sl-pxp-dma", "fsl,imx6dl-pxp-dma";
  11888. reg = <0x020f0000 0x4000>;
  11889. - interrupts = <0 98 0x04>;
  11890. + interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
  11891. + clocks = <&clks 111>;
  11892. + clock-names = "pxp-axi";
  11893. + status = "disabled";
  11894. };
  11895. epdc: epdc@020f4000 {
  11896. reg = <0x020f4000 0x4000>;
  11897. - interrupts = <0 97 0x04>;
  11898. + interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
  11899. };
  11900. lcdif: lcdif@020f8000 {
  11901. + compatible = "fsl,imx6sl-lcdif", "fsl,imx28-lcdif";
  11902. reg = <0x020f8000 0x4000>;
  11903. - interrupts = <0 39 0x04>;
  11904. + interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
  11905. + clocks = <&clks IMX6SL_CLK_LCDIF_PIX>,
  11906. + <&clks IMX6SL_CLK_LCDIF_AXI>;
  11907. + clock-names = "pix", "axi";
  11908. + status = "disabled";
  11909. };
  11910. dcp: dcp@020fc000 {
  11911. reg = <0x020fc000 0x4000>;
  11912. - interrupts = <0 99 0x04>;
  11913. + interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>;
  11914. };
  11915. };
  11916. @@ -811,7 +800,7 @@
  11917. usbotg1: usb@02184000 {
  11918. compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
  11919. reg = <0x02184000 0x200>;
  11920. - interrupts = <0 43 0x04>;
  11921. + interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
  11922. clocks = <&clks IMX6SL_CLK_USBOH3>;
  11923. fsl,usbphy = <&usbphy1>;
  11924. fsl,usbmisc = <&usbmisc 0>;
  11925. @@ -821,7 +810,7 @@
  11926. usbotg2: usb@02184200 {
  11927. compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
  11928. reg = <0x02184200 0x200>;
  11929. - interrupts = <0 42 0x04>;
  11930. + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
  11931. clocks = <&clks IMX6SL_CLK_USBOH3>;
  11932. fsl,usbphy = <&usbphy2>;
  11933. fsl,usbmisc = <&usbmisc 1>;
  11934. @@ -831,9 +820,12 @@
  11935. usbh: usb@02184400 {
  11936. compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
  11937. reg = <0x02184400 0x200>;
  11938. - interrupts = <0 40 0x04>;
  11939. + interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
  11940. clocks = <&clks IMX6SL_CLK_USBOH3>;
  11941. fsl,usbmisc = <&usbmisc 2>;
  11942. + phy_type = "hsic";
  11943. + fsl,usbphy = <&usbphy_nop1>;
  11944. + fsl,anatop = <&anatop>;
  11945. status = "disabled";
  11946. };
  11947. @@ -847,7 +839,7 @@
  11948. fec: ethernet@02188000 {
  11949. compatible = "fsl,imx6sl-fec", "fsl,imx25-fec";
  11950. reg = <0x02188000 0x4000>;
  11951. - interrupts = <0 114 0x04>;
  11952. + interrupts = <0 114 IRQ_TYPE_LEVEL_HIGH>;
  11953. clocks = <&clks IMX6SL_CLK_ENET_REF>,
  11954. <&clks IMX6SL_CLK_ENET_REF>;
  11955. clock-names = "ipg", "ahb";
  11956. @@ -857,7 +849,7 @@
  11957. usdhc1: usdhc@02190000 {
  11958. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11959. reg = <0x02190000 0x4000>;
  11960. - interrupts = <0 22 0x04>;
  11961. + interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
  11962. clocks = <&clks IMX6SL_CLK_USDHC1>,
  11963. <&clks IMX6SL_CLK_USDHC1>,
  11964. <&clks IMX6SL_CLK_USDHC1>;
  11965. @@ -869,7 +861,7 @@
  11966. usdhc2: usdhc@02194000 {
  11967. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11968. reg = <0x02194000 0x4000>;
  11969. - interrupts = <0 23 0x04>;
  11970. + interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
  11971. clocks = <&clks IMX6SL_CLK_USDHC2>,
  11972. <&clks IMX6SL_CLK_USDHC2>,
  11973. <&clks IMX6SL_CLK_USDHC2>;
  11974. @@ -881,7 +873,7 @@
  11975. usdhc3: usdhc@02198000 {
  11976. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11977. reg = <0x02198000 0x4000>;
  11978. - interrupts = <0 24 0x04>;
  11979. + interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
  11980. clocks = <&clks IMX6SL_CLK_USDHC3>,
  11981. <&clks IMX6SL_CLK_USDHC3>,
  11982. <&clks IMX6SL_CLK_USDHC3>;
  11983. @@ -893,7 +885,7 @@
  11984. usdhc4: usdhc@0219c000 {
  11985. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11986. reg = <0x0219c000 0x4000>;
  11987. - interrupts = <0 25 0x04>;
  11988. + interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
  11989. clocks = <&clks IMX6SL_CLK_USDHC4>,
  11990. <&clks IMX6SL_CLK_USDHC4>,
  11991. <&clks IMX6SL_CLK_USDHC4>;
  11992. @@ -907,7 +899,7 @@
  11993. #size-cells = <0>;
  11994. compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
  11995. reg = <0x021a0000 0x4000>;
  11996. - interrupts = <0 36 0x04>;
  11997. + interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
  11998. clocks = <&clks IMX6SL_CLK_I2C1>;
  11999. status = "disabled";
  12000. };
  12001. @@ -917,7 +909,7 @@
  12002. #size-cells = <0>;
  12003. compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
  12004. reg = <0x021a4000 0x4000>;
  12005. - interrupts = <0 37 0x04>;
  12006. + interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
  12007. clocks = <&clks IMX6SL_CLK_I2C2>;
  12008. status = "disabled";
  12009. };
  12010. @@ -927,7 +919,7 @@
  12011. #size-cells = <0>;
  12012. compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
  12013. reg = <0x021a8000 0x4000>;
  12014. - interrupts = <0 38 0x04>;
  12015. + interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
  12016. clocks = <&clks IMX6SL_CLK_I2C3>;
  12017. status = "disabled";
  12018. };
  12019. @@ -939,17 +931,23 @@
  12020. rngb: rngb@021b4000 {
  12021. reg = <0x021b4000 0x4000>;
  12022. - interrupts = <0 5 0x04>;
  12023. + interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
  12024. };
  12025. weim: weim@021b8000 {
  12026. reg = <0x021b8000 0x4000>;
  12027. - interrupts = <0 14 0x04>;
  12028. + interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
  12029. + };
  12030. +
  12031. + ocotp: ocotp-ctrl@021bc000 {
  12032. + compatible = "syscon";
  12033. + reg = <0x021bc000 0x4000>;
  12034. };
  12035. - ocotp: ocotp@021bc000 {
  12036. - compatible = "fsl,imx6sl-ocotp";
  12037. + ocotp-fuse@021bc000 {
  12038. + compatible = "fsl,imx6sl-ocotp", "fsl,imx6q-ocotp";
  12039. reg = <0x021bc000 0x4000>;
  12040. + clocks = <&clks IMX6SL_CLK_OCOTP>;
  12041. };
  12042. audmux: audmux@021d8000 {
  12043. @@ -957,6 +955,25 @@
  12044. reg = <0x021d8000 0x4000>;
  12045. status = "disabled";
  12046. };
  12047. +
  12048. + gpu: gpu@02200000 {
  12049. + compatible = "fsl,imx6sl-gpu", "fsl,imx6q-gpu";
  12050. + reg = <0x02200000 0x4000>, <0x02204000 0x4000>,
  12051. + <0x80000000 0x0>;
  12052. + reg-names = "iobase_2d", "iobase_vg",
  12053. + "phys_baseaddr";
  12054. + interrupts = <0 10 0x04>, <0 11 0x04>;
  12055. + interrupt-names = "irq_2d", "irq_vg";
  12056. + clocks = <&clks IMX6SL_CLK_MMDC_ROOT>,
  12057. + <&clks IMX6SL_CLK_MMDC_ROOT>,
  12058. + <&clks IMX6SL_CLK_GPU2D_OVG>;
  12059. + clock-names = "gpu2d_axi_clk", "openvg_axi_clk",
  12060. + "gpu2d_clk";
  12061. + resets = <&src 3>, <&src 3>;
  12062. + reset-names = "gpu2d", "gpuvg";
  12063. + pu-supply = <&reg_pu>;
  12064. + };
  12065. +
  12066. };
  12067. };
  12068. };
  12069. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6sl-evk-csi.dts linux-imx6-3.14/arch/arm/boot/dts/imx6sl-evk-csi.dts
  12070. --- linux-3.14.14/arch/arm/boot/dts/imx6sl-evk-csi.dts 1969-12-31 18:00:00.000000000 -0600
  12071. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6sl-evk-csi.dts 2014-12-08 00:31:51.124418001 -0600
  12072. @@ -0,0 +1,27 @@
  12073. +/*
  12074. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  12075. + *
  12076. + * This program is free software; you can redistribute it and/or modify
  12077. + * it under the terms of the GNU General Public License version 2 as
  12078. + * published by the Free Software Foundation.
  12079. + */
  12080. +
  12081. +#include "imx6sl-evk.dts"
  12082. +
  12083. +/ {
  12084. + csi_v4l2_cap {
  12085. + status = "okay";
  12086. + };
  12087. +};
  12088. +
  12089. +&csi {
  12090. + status = "okay";
  12091. +};
  12092. +
  12093. +&i2c3 {
  12094. + status = "okay";
  12095. +};
  12096. +
  12097. +&epdc {
  12098. + status = "disabled";
  12099. +};
  12100. diff -Nur linux-3.14.14/arch/arm/boot/dts/imx6sl-evk.dts linux-imx6-3.14/arch/arm/boot/dts/imx6sl-evk.dts
  12101. --- linux-3.14.14/arch/arm/boot/dts/imx6sl-evk.dts 2014-07-28 10:07:25.000000000 -0500
  12102. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6sl-evk.dts 2014-12-08 00:31:51.124418001 -0600
  12103. @@ -8,6 +8,8 @@
  12104. /dts-v1/;
  12105. +#include <dt-bindings/gpio/gpio.h>
  12106. +#include <dt-bindings/input/input.h>
  12107. #include "imx6sl.dtsi"
  12108. / {
  12109. @@ -18,11 +20,26 @@
  12110. reg = <0x80000000 0x40000000>;
  12111. };
  12112. + leds {
  12113. + compatible = "gpio-leds";
  12114. + pinctrl-names = "default";
  12115. + pinctrl-0 = <&pinctrl_led>;
  12116. +
  12117. + user {
  12118. + label = "debug";
  12119. + gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
  12120. + linux,default-trigger = "heartbeat";
  12121. + };
  12122. + };
  12123. +
  12124. regulators {
  12125. compatible = "simple-bus";
  12126. + #address-cells = <1>;
  12127. + #size-cells = <0>;
  12128. - reg_usb_otg1_vbus: usb_otg1_vbus {
  12129. + reg_usb_otg1_vbus: regulator@0 {
  12130. compatible = "regulator-fixed";
  12131. + reg = <0>;
  12132. regulator-name = "usb_otg1_vbus";
  12133. regulator-min-microvolt = <5000000>;
  12134. regulator-max-microvolt = <5000000>;
  12135. @@ -30,22 +47,63 @@
  12136. enable-active-high;
  12137. };
  12138. - reg_usb_otg2_vbus: usb_otg2_vbus {
  12139. + reg_usb_otg2_vbus: regulator@1 {
  12140. compatible = "regulator-fixed";
  12141. + reg = <1>;
  12142. regulator-name = "usb_otg2_vbus";
  12143. regulator-min-microvolt = <5000000>;
  12144. regulator-max-microvolt = <5000000>;
  12145. gpio = <&gpio4 2 0>;
  12146. enable-active-high;
  12147. };
  12148. +
  12149. + reg_aud3v: regulator@2 {
  12150. + compatible = "regulator-fixed";
  12151. + reg = <2>;
  12152. + regulator-name = "wm8962-supply-3v15";
  12153. + regulator-min-microvolt = <3150000>;
  12154. + regulator-max-microvolt = <3150000>;
  12155. + regulator-boot-on;
  12156. + };
  12157. +
  12158. + reg_aud4v: regulator@3 {
  12159. + compatible = "regulator-fixed";
  12160. + reg = <3>;
  12161. + regulator-name = "wm8962-supply-4v2";
  12162. + regulator-min-microvolt = <4325000>;
  12163. + regulator-max-microvolt = <4325000>;
  12164. + regulator-boot-on;
  12165. + };
  12166. };
  12167. +
  12168. + sound {
  12169. + compatible = "fsl,imx6sl-evk-wm8962", "fsl,imx-audio-wm8962";
  12170. + model = "wm8962-audio";
  12171. + ssi-controller = <&ssi2>;
  12172. + audio-codec = <&codec>;
  12173. + audio-routing =
  12174. + "Headphone Jack", "HPOUTL",
  12175. + "Headphone Jack", "HPOUTR",
  12176. + "Ext Spk", "SPKOUTL",
  12177. + "Ext Spk", "SPKOUTR",
  12178. + "AMIC", "MICBIAS",
  12179. + "IN3R", "AMIC";
  12180. + mux-int-port = <2>;
  12181. + mux-ext-port = <3>;
  12182. + };
  12183. +};
  12184. +
  12185. +&audmux {
  12186. + pinctrl-names = "default";
  12187. + pinctrl-0 = <&pinctrl_audmux3>;
  12188. + status = "okay";
  12189. };
  12190. &ecspi1 {
  12191. fsl,spi-num-chipselects = <1>;
  12192. cs-gpios = <&gpio4 11 0>;
  12193. pinctrl-names = "default";
  12194. - pinctrl-0 = <&pinctrl_ecspi1_1>;
  12195. + pinctrl-0 = <&pinctrl_ecspi1>;
  12196. status = "okay";
  12197. flash: m25p80@0 {
  12198. @@ -57,18 +115,326 @@
  12199. };
  12200. };
  12201. +&csi {
  12202. + status = "okay";
  12203. +};
  12204. +
  12205. +&cpu0 {
  12206. + arm-supply = <&sw1a_reg>;
  12207. + soc-supply = <&sw1c_reg>;
  12208. + pu-supply = <&pu_dummy>; /* use pu_dummy if VDDSOC share with VDDPU */
  12209. +};
  12210. +
  12211. &fec {
  12212. pinctrl-names = "default";
  12213. - pinctrl-0 = <&pinctrl_fec_1>;
  12214. + pinctrl-0 = <&pinctrl_fec>;
  12215. phy-mode = "rmii";
  12216. status = "okay";
  12217. };
  12218. +&i2c1 {
  12219. + clock-frequency = <100000>;
  12220. + pinctrl-names = "default";
  12221. + pinctrl-0 = <&pinctrl_i2c1>;
  12222. + status = "okay";
  12223. +
  12224. + pmic: pfuze100@08 {
  12225. + compatible = "fsl,pfuze100";
  12226. + reg = <0x08>;
  12227. +
  12228. + regulators {
  12229. + sw1a_reg: sw1ab {
  12230. + regulator-min-microvolt = <300000>;
  12231. + regulator-max-microvolt = <1875000>;
  12232. + regulator-boot-on;
  12233. + regulator-always-on;
  12234. + regulator-ramp-delay = <6250>;
  12235. + };
  12236. +
  12237. + sw1c_reg: sw1c {
  12238. + regulator-min-microvolt = <300000>;
  12239. + regulator-max-microvolt = <1875000>;
  12240. + regulator-boot-on;
  12241. + regulator-always-on;
  12242. + regulator-ramp-delay = <6250>;
  12243. + };
  12244. +
  12245. + sw2_reg: sw2 {
  12246. + regulator-min-microvolt = <800000>;
  12247. + regulator-max-microvolt = <3300000>;
  12248. + regulator-boot-on;
  12249. + regulator-always-on;
  12250. + };
  12251. +
  12252. + sw3a_reg: sw3a {
  12253. + regulator-min-microvolt = <400000>;
  12254. + regulator-max-microvolt = <1975000>;
  12255. + regulator-boot-on;
  12256. + regulator-always-on;
  12257. + };
  12258. +
  12259. + sw3b_reg: sw3b {
  12260. + regulator-min-microvolt = <400000>;
  12261. + regulator-max-microvolt = <1975000>;
  12262. + regulator-boot-on;
  12263. + regulator-always-on;
  12264. + };
  12265. +
  12266. + sw4_reg: sw4 {
  12267. + regulator-min-microvolt = <800000>;
  12268. + regulator-max-microvolt = <3300000>;
  12269. + };
  12270. +
  12271. + swbst_reg: swbst {
  12272. + regulator-min-microvolt = <5000000>;
  12273. + regulator-max-microvolt = <5150000>;
  12274. + };
  12275. +
  12276. + snvs_reg: vsnvs {
  12277. + regulator-min-microvolt = <1000000>;
  12278. + regulator-max-microvolt = <3000000>;
  12279. + regulator-boot-on;
  12280. + regulator-always-on;
  12281. + };
  12282. +
  12283. + vref_reg: vrefddr {
  12284. + regulator-boot-on;
  12285. + regulator-always-on;
  12286. + };
  12287. +
  12288. + vgen1_reg: vgen1 {
  12289. + regulator-min-microvolt = <800000>;
  12290. + regulator-max-microvolt = <1550000>;
  12291. + regulator-always-on;
  12292. + };
  12293. +
  12294. + vgen2_reg: vgen2 {
  12295. + regulator-min-microvolt = <800000>;
  12296. + regulator-max-microvolt = <1550000>;
  12297. + };
  12298. +
  12299. + vgen3_reg: vgen3 {
  12300. + regulator-min-microvolt = <1800000>;
  12301. + regulator-max-microvolt = <3300000>;
  12302. + };
  12303. +
  12304. + vgen4_reg: vgen4 {
  12305. + regulator-min-microvolt = <1800000>;
  12306. + regulator-max-microvolt = <3300000>;
  12307. + regulator-always-on;
  12308. + };
  12309. +
  12310. + vgen5_reg: vgen5 {
  12311. + regulator-min-microvolt = <1800000>;
  12312. + regulator-max-microvolt = <3300000>;
  12313. + regulator-always-on;
  12314. + };
  12315. +
  12316. + vgen6_reg: vgen6 {
  12317. + regulator-min-microvolt = <1800000>;
  12318. + regulator-max-microvolt = <3300000>;
  12319. + regulator-always-on;
  12320. + };
  12321. + };
  12322. + };
  12323. +
  12324. + regulators {
  12325. + compatible = "simple-bus";
  12326. +
  12327. + reg_lcd_3v3: lcd-3v3 {
  12328. + compatible = "regulator-fixed";
  12329. + regulator-name = "lcd-3v3";
  12330. + gpio = <&gpio4 3 0>;
  12331. + enable-active-high;
  12332. + };
  12333. + };
  12334. +
  12335. + backlight {
  12336. + compatible = "pwm-backlight";
  12337. + pwms = <&pwm1 0 5000000>;
  12338. + brightness-levels = <0 4 8 16 32 64 128 255>;
  12339. + default-brightness-level = <6>;
  12340. + };
  12341. +
  12342. + csi_v4l2_cap {
  12343. + compatible = "fsl,imx6sl-csi-v4l2";
  12344. + status = "okay";
  12345. + };
  12346. +
  12347. + pxp_v4l2_out {
  12348. + compatible = "fsl,imx6sl-pxp-v4l2";
  12349. + status = "okay";
  12350. + };
  12351. +};
  12352. +
  12353. +&i2c2 {
  12354. + clock-frequency = <100000>;
  12355. + pinctrl-names = "default";
  12356. + pinctrl-0 = <&pinctrl_i2c2>;
  12357. + status = "okay";
  12358. +
  12359. + codec: wm8962@1a {
  12360. + compatible = "wlf,wm8962";
  12361. + reg = <0x1a>;
  12362. + clocks = <&clks IMX6SL_CLK_EXTERN_AUDIO>;
  12363. + DCVDD-supply = <&vgen3_reg>;
  12364. + DBVDD-supply = <&reg_aud3v>;
  12365. + AVDD-supply = <&vgen3_reg>;
  12366. + CPVDD-supply = <&vgen3_reg>;
  12367. + MICVDD-supply = <&reg_aud3v>;
  12368. + PLLVDD-supply = <&vgen3_reg>;
  12369. + SPKVDD1-supply = <&reg_aud4v>;
  12370. + SPKVDD2-supply = <&reg_aud4v>;
  12371. + };
  12372. +};
  12373. +
  12374. +&i2c1 {
  12375. + clock-frequency = <100000>;
  12376. + pinctrl-names = "default";
  12377. + pinctrl-0 = <&pinctrl_i2c1_1>;
  12378. + status = "okay";
  12379. +
  12380. + pmic: pfuze100@08 {
  12381. + compatible = "fsl,pfuze100";
  12382. + reg = <0x08>;
  12383. +
  12384. + regulators {
  12385. + sw1a_reg: sw1ab {
  12386. + regulator-min-microvolt = <300000>;
  12387. + regulator-max-microvolt = <1875000>;
  12388. + regulator-boot-on;
  12389. + regulator-always-on;
  12390. + regulator-ramp-delay = <6250>;
  12391. + };
  12392. +
  12393. + sw1c_reg: sw1c {
  12394. + regulator-min-microvolt = <300000>;
  12395. + regulator-max-microvolt = <1875000>;
  12396. + regulator-boot-on;
  12397. + regulator-always-on;
  12398. + regulator-ramp-delay = <6250>;
  12399. + };
  12400. +
  12401. + sw2_reg: sw2 {
  12402. + regulator-min-microvolt = <800000>;
  12403. + regulator-max-microvolt = <3300000>;
  12404. + regulator-boot-on;
  12405. + regulator-always-on;
  12406. + };
  12407. +
  12408. + sw3a_reg: sw3a {
  12409. + regulator-min-microvolt = <400000>;
  12410. + regulator-max-microvolt = <1975000>;
  12411. + regulator-boot-on;
  12412. + regulator-always-on;
  12413. + };
  12414. +
  12415. + sw3b_reg: sw3b {
  12416. + regulator-min-microvolt = <400000>;
  12417. + regulator-max-microvolt = <1975000>;
  12418. + regulator-boot-on;
  12419. + regulator-always-on;
  12420. + };
  12421. +
  12422. + sw4_reg: sw4 {
  12423. + regulator-min-microvolt = <800000>;
  12424. + regulator-max-microvolt = <3300000>;
  12425. + };
  12426. +
  12427. + swbst_reg: swbst {
  12428. + regulator-min-microvolt = <5000000>;
  12429. + regulator-max-microvolt = <5150000>;
  12430. + };
  12431. +
  12432. + snvs_reg: vsnvs {
  12433. + regulator-min-microvolt = <1000000>;
  12434. + regulator-max-microvolt = <3000000>;
  12435. + regulator-boot-on;
  12436. + regulator-always-on;
  12437. + };
  12438. +
  12439. + vref_reg: vrefddr {
  12440. + regulator-boot-on;
  12441. + regulator-always-on;
  12442. + };
  12443. +
  12444. + vgen1_reg: vgen1 {
  12445. + regulator-min-microvolt = <800000>;
  12446. + regulator-max-microvolt = <1550000>;
  12447. + };
  12448. +
  12449. + vgen2_reg: vgen2 {
  12450. + regulator-min-microvolt = <800000>;
  12451. + regulator-max-microvolt = <1550000>;
  12452. + };
  12453. +
  12454. + vgen3_reg: vgen3 {
  12455. + regulator-min-microvolt = <1800000>;
  12456. + regulator-max-microvolt = <3300000>;
  12457. + regulator-always-on;
  12458. + };
  12459. +
  12460. + vgen4_reg: vgen4 {
  12461. + regulator-min-microvolt = <1800000>;
  12462. + regulator-max-microvolt = <3300000>;
  12463. + regulator-always-on;
  12464. + };
  12465. +
  12466. + vgen5_reg: vgen5 {
  12467. + regulator-min-microvolt = <1800000>;
  12468. + regulator-max-microvolt = <3300000>;
  12469. + regulator-always-on;
  12470. + };
  12471. +
  12472. + vgen6_reg: vgen6 {
  12473. + regulator-min-microvolt = <1800000>;
  12474. + regulator-max-microvolt = <3300000>;
  12475. + regulator-always-on;
  12476. + };
  12477. + };
  12478. + };
  12479. +
  12480. + mma8450@1c {
  12481. + compatible = "fsl,mma8450";
  12482. + reg = <0x1c>;
  12483. + };
  12484. +};
  12485. +
  12486. +&i2c2 {
  12487. + clock-frequency = <100000>;
  12488. + pinctrl-names = "default";
  12489. + pinctrl-0 = <&pinctrl_i2c2_1>;
  12490. + status = "okay";
  12491. +};
  12492. +
  12493. +&i2c3 {
  12494. + clock-frequency = <100000>;
  12495. + pinctrl-names = "default";
  12496. + pinctrl-0 = <&pinctrl_i2c3_1>;
  12497. + status = "okay";
  12498. +
  12499. + ov564x: ov564x@3c {
  12500. + compatible = "ovti,ov564x";
  12501. + reg = <0x3c>;
  12502. + pinctrl-names = "default";
  12503. + pinctrl-0 = <&pinctrl_csi_0>;
  12504. + clocks = <&clks IMX6SL_CLK_CSI>;
  12505. + clock-names = "csi_mclk";
  12506. + AVDD-supply = <&vgen6_reg>; /* 2.8v */
  12507. + DVDD-supply = <&vgen2_reg>; /* 1.5v*/
  12508. + pwn-gpios = <&gpio1 25 1>;
  12509. + rst-gpios = <&gpio1 26 0>;
  12510. + csi_id = <0>;
  12511. + mclk = <24000000>;
  12512. + mclk_source = <0>;
  12513. + };
  12514. +};
  12515. +
  12516. &iomuxc {
  12517. pinctrl-names = "default";
  12518. pinctrl-0 = <&pinctrl_hog>;
  12519. - hog {
  12520. + imx6sl-evk {
  12521. pinctrl_hog: hoggrp {
  12522. fsl,pins = <
  12523. MX6SL_PAD_KEY_ROW7__GPIO4_IO07 0x17059
  12524. @@ -78,21 +444,270 @@
  12525. MX6SL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059
  12526. MX6SL_PAD_KEY_COL4__GPIO4_IO00 0x80000000
  12527. MX6SL_PAD_KEY_COL5__GPIO4_IO02 0x80000000
  12528. + MX6SL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x4130b0
  12529. + >;
  12530. + };
  12531. +
  12532. + pinctrl_audmux3: audmux3grp {
  12533. + fsl,pins = <
  12534. + MX6SL_PAD_AUD_RXD__AUD3_RXD 0x4130b0
  12535. + MX6SL_PAD_AUD_TXC__AUD3_TXC 0x4130b0
  12536. + MX6SL_PAD_AUD_TXD__AUD3_TXD 0x4110b0
  12537. + MX6SL_PAD_AUD_TXFS__AUD3_TXFS 0x4130b0
  12538. + >;
  12539. + };
  12540. +
  12541. + pinctrl_ecspi1: ecspi1grp {
  12542. + fsl,pins = <
  12543. + MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
  12544. + MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
  12545. + MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
  12546. + MX6SL_PAD_ECSPI1_SS0__GPIO4_IO11 0x80000000
  12547. + >;
  12548. + };
  12549. +
  12550. + pinctrl_fec: fecgrp {
  12551. + fsl,pins = <
  12552. + MX6SL_PAD_FEC_MDC__FEC_MDC 0x1b0b0
  12553. + MX6SL_PAD_FEC_MDIO__FEC_MDIO 0x1b0b0
  12554. + MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV 0x1b0b0
  12555. + MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0 0x1b0b0
  12556. + MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1 0x1b0b0
  12557. + MX6SL_PAD_FEC_TX_EN__FEC_TX_EN 0x1b0b0
  12558. + MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0 0x1b0b0
  12559. + MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1 0x1b0b0
  12560. + MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x4001b0a8
  12561. + >;
  12562. + };
  12563. +
  12564. + pinctrl_i2c1: i2c1grp {
  12565. + fsl,pins = <
  12566. + MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1
  12567. + MX6SL_PAD_I2C1_SDA__I2C1_SDA 0x4001b8b1
  12568. + >;
  12569. + };
  12570. +
  12571. +
  12572. + pinctrl_i2c2: i2c2grp {
  12573. + fsl,pins = <
  12574. + MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x4001b8b1
  12575. + MX6SL_PAD_I2C2_SDA__I2C2_SDA 0x4001b8b1
  12576. + >;
  12577. + };
  12578. +
  12579. + pinctrl_led: ledgrp {
  12580. + fsl,pins = <
  12581. + MX6SL_PAD_HSIC_STROBE__GPIO3_IO20 0x17059
  12582. + >;
  12583. + };
  12584. +
  12585. + pinctrl_kpp: kppgrp {
  12586. + fsl,pins = <
  12587. + MX6SL_PAD_KEY_ROW0__KEY_ROW0 0x1b010
  12588. + MX6SL_PAD_KEY_ROW1__KEY_ROW1 0x1b010
  12589. + MX6SL_PAD_KEY_ROW2__KEY_ROW2 0x1b0b0
  12590. + MX6SL_PAD_KEY_COL0__KEY_COL0 0x110b0
  12591. + MX6SL_PAD_KEY_COL1__KEY_COL1 0x110b0
  12592. + MX6SL_PAD_KEY_COL2__KEY_COL2 0x110b0
  12593. + >;
  12594. + };
  12595. +
  12596. + pinctrl_uart1: uart1grp {
  12597. + fsl,pins = <
  12598. + MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x1b0b1
  12599. + MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1
  12600. + >;
  12601. + };
  12602. +
  12603. + pinctrl_usbotg1: usbotg1grp {
  12604. + fsl,pins = <
  12605. + MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059
  12606. + >;
  12607. + };
  12608. +
  12609. + pinctrl_usdhc1: usdhc1grp {
  12610. + fsl,pins = <
  12611. + MX6SL_PAD_SD1_CMD__SD1_CMD 0x17059
  12612. + MX6SL_PAD_SD1_CLK__SD1_CLK 0x10059
  12613. + MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  12614. + MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  12615. + MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  12616. + MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  12617. + MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x17059
  12618. + MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x17059
  12619. + MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x17059
  12620. + MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x17059
  12621. + >;
  12622. + };
  12623. +
  12624. + pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
  12625. + fsl,pins = <
  12626. + MX6SL_PAD_SD1_CMD__SD1_CMD 0x170b9
  12627. + MX6SL_PAD_SD1_CLK__SD1_CLK 0x100b9
  12628. + MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170b9
  12629. + MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170b9
  12630. + MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170b9
  12631. + MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170b9
  12632. + MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170b9
  12633. + MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170b9
  12634. + MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170b9
  12635. + MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170b9
  12636. + >;
  12637. + };
  12638. +
  12639. + pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
  12640. + fsl,pins = <
  12641. + MX6SL_PAD_SD1_CMD__SD1_CMD 0x170f9
  12642. + MX6SL_PAD_SD1_CLK__SD1_CLK 0x100f9
  12643. + MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
  12644. + MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
  12645. + MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
  12646. + MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
  12647. + MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170f9
  12648. + MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170f9
  12649. + MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170f9
  12650. + MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170f9
  12651. + >;
  12652. + };
  12653. +
  12654. + pinctrl_usdhc2: usdhc2grp {
  12655. + fsl,pins = <
  12656. + MX6SL_PAD_SD2_CMD__SD2_CMD 0x17059
  12657. + MX6SL_PAD_SD2_CLK__SD2_CLK 0x10059
  12658. + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  12659. + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  12660. + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  12661. + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  12662. + >;
  12663. + };
  12664. +
  12665. + pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
  12666. + fsl,pins = <
  12667. + MX6SL_PAD_SD2_CMD__SD2_CMD 0x170b9
  12668. + MX6SL_PAD_SD2_CLK__SD2_CLK 0x100b9
  12669. + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
  12670. + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
  12671. + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
  12672. + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170b9
  12673. + >;
  12674. + };
  12675. +
  12676. + pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
  12677. + fsl,pins = <
  12678. + MX6SL_PAD_SD2_CMD__SD2_CMD 0x170f9
  12679. + MX6SL_PAD_SD2_CLK__SD2_CLK 0x100f9
  12680. + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
  12681. + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
  12682. + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
  12683. + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170f9
  12684. + >;
  12685. + };
  12686. +
  12687. + pinctrl_usdhc3: usdhc3grp {
  12688. + fsl,pins = <
  12689. + MX6SL_PAD_SD3_CMD__SD3_CMD 0x17059
  12690. + MX6SL_PAD_SD3_CLK__SD3_CLK 0x10059
  12691. + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  12692. + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  12693. + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  12694. + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  12695. + >;
  12696. + };
  12697. +
  12698. + pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
  12699. + fsl,pins = <
  12700. + MX6SL_PAD_SD3_CMD__SD3_CMD 0x170b9
  12701. + MX6SL_PAD_SD3_CLK__SD3_CLK 0x100b9
  12702. + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  12703. + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  12704. + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  12705. + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  12706. + >;
  12707. + };
  12708. +
  12709. + pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
  12710. + fsl,pins = <
  12711. + MX6SL_PAD_SD3_CMD__SD3_CMD 0x170f9
  12712. + MX6SL_PAD_SD3_CLK__SD3_CLK 0x100f9
  12713. + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  12714. + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  12715. + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  12716. + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  12717. >;
  12718. };
  12719. };
  12720. };
  12721. +&kpp {
  12722. + pinctrl-names = "default";
  12723. + pinctrl-0 = <&pinctrl_kpp>;
  12724. + linux,keymap = <
  12725. + MATRIX_KEY(0x0, 0x0, KEY_UP) /* ROW0, COL0 */
  12726. + MATRIX_KEY(0x0, 0x1, KEY_DOWN) /* ROW0, COL1 */
  12727. + MATRIX_KEY(0x0, 0x2, KEY_ENTER) /* ROW0, COL2 */
  12728. + MATRIX_KEY(0x1, 0x0, KEY_HOME) /* ROW1, COL0 */
  12729. + MATRIX_KEY(0x1, 0x1, KEY_RIGHT) /* ROW1, COL1 */
  12730. + MATRIX_KEY(0x1, 0x2, KEY_LEFT) /* ROW1, COL2 */
  12731. + MATRIX_KEY(0x2, 0x0, KEY_VOLUMEDOWN) /* ROW2, COL0 */
  12732. + MATRIX_KEY(0x2, 0x1, KEY_VOLUMEUP) /* ROW2, COL1 */
  12733. + >;
  12734. + status = "okay";
  12735. +};
  12736. +
  12737. +&ssi2 {
  12738. + fsl,mode = "i2s-slave";
  12739. + status = "okay";
  12740. +};
  12741. +
  12742. +&lcdif {
  12743. + pinctrl-names = "default";
  12744. + pinctrl-0 = <&pinctrl_lcdif_dat_0
  12745. + &pinctrl_lcdif_ctrl_0>;
  12746. + lcd-supply = <&reg_lcd_3v3>;
  12747. + display = <&display>;
  12748. + status = "okay";
  12749. +
  12750. + display: display {
  12751. + bits-per-pixel = <16>;
  12752. + bus-width = <24>;
  12753. +
  12754. + display-timings {
  12755. + native-mode = <&timing0>;
  12756. + timing0: timing0 {
  12757. + clock-frequency = <33500000>;
  12758. + hactive = <800>;
  12759. + vactive = <480>;
  12760. + hback-porch = <89>;
  12761. + hfront-porch = <164>;
  12762. + vback-porch = <23>;
  12763. + vfront-porch = <10>;
  12764. + hsync-len = <10>;
  12765. + vsync-len = <10>;
  12766. + hsync-active = <0>;
  12767. + vsync-active = <0>;
  12768. + de-active = <1>;
  12769. + pixelclk-active = <0>;
  12770. + };
  12771. + };
  12772. + };
  12773. +};
  12774. +
  12775. +&pwm1 {
  12776. + pinctrl-names = "default";
  12777. + pinctrl-0 = <&pinctrl_pwm1_0>;
  12778. + status = "okay";
  12779. +};
  12780. +
  12781. &uart1 {
  12782. pinctrl-names = "default";
  12783. - pinctrl-0 = <&pinctrl_uart1_1>;
  12784. + pinctrl-0 = <&pinctrl_uart1>;
  12785. status = "okay";
  12786. };
  12787. &usbotg1 {
  12788. vbus-supply = <&reg_usb_otg1_vbus>;
  12789. pinctrl-names = "default";
  12790. - pinctrl-0 = <&pinctrl_usbotg1_1>;
  12791. + pinctrl-0 = <&pinctrl_usbotg1>;
  12792. disable-over-current;
  12793. status = "okay";
  12794. };
  12795. @@ -106,9 +721,9 @@
  12796. &usdhc1 {
  12797. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  12798. - pinctrl-0 = <&pinctrl_usdhc1_1>;
  12799. - pinctrl-1 = <&pinctrl_usdhc1_1_100mhz>;
  12800. - pinctrl-2 = <&pinctrl_usdhc1_1_200mhz>;
  12801. + pinctrl-0 = <&pinctrl_usdhc1>;
  12802. + pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
  12803. + pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
  12804. bus-width = <8>;
  12805. cd-gpios = <&gpio4 7 0>;
  12806. wp-gpios = <&gpio4 6 0>;
  12807. @@ -117,9 +732,9 @@
  12808. &usdhc2 {
  12809. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  12810. - pinctrl-0 = <&pinctrl_usdhc2_1>;
  12811. - pinctrl-1 = <&pinctrl_usdhc2_1_100mhz>;
  12812. - pinctrl-2 = <&pinctrl_usdhc2_1_200mhz>;
  12813. + pinctrl-0 = <&pinctrl_usdhc2>;
  12814. + pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
  12815. + pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
  12816. cd-gpios = <&gpio5 0 0>;
  12817. wp-gpios = <&gpio4 29 0>;
  12818. status = "okay";
  12819. @@ -127,9 +742,26 @@
  12820. &usdhc3 {
  12821. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  12822. - pinctrl-0 = <&pinctrl_usdhc3_1>;
  12823. - pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
  12824. - pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
  12825. + pinctrl-0 = <&pinctrl_usdhc3>;
  12826. + pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
  12827. + pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
  12828. cd-gpios = <&gpio3 22 0>;
  12829. status = "okay";
  12830. };
  12831. +
  12832. +&pxp {
  12833. + status = "okay";
  12834. +};
  12835. +
  12836. +&gpc {
  12837. + fsl,cpu_pupscr_sw2iso = <0xf>;
  12838. + fsl,cpu_pupscr_sw = <0xf>;
  12839. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  12840. + fsl,cpu_pdnscr_iso = <0x1>;
  12841. + fsl,ldo-bypass; /* use ldo-bypass, u-boot will check it and configure */
  12842. + pu-supply = <&pu_dummy>; /* ldo-bypass:use pu_dummy if VDDSOC share with VDDPU */
  12843. +};
  12844. +
  12845. +&gpu {
  12846. + pu-supply = <&pu_dummy>; /* ldo-bypass:use pu_dummy if VDDSOC share with VDDPU */
  12847. +};
  12848. diff -Nur linux-3.14.14/arch/arm/boot/dts/Makefile linux-imx6-3.14/arch/arm/boot/dts/Makefile
  12849. --- linux-3.14.14/arch/arm/boot/dts/Makefile 2014-07-28 10:07:25.000000000 -0500
  12850. +++ linux-imx6-3.14/arch/arm/boot/dts/Makefile 2014-12-08 00:31:51.108418001 -0600
  12851. @@ -154,16 +154,37 @@
  12852. imx53-qsb.dtb \
  12853. imx53-smd.dtb \
  12854. imx6dl-cubox-i.dtb \
  12855. + imx6dl-dfi-fs700-m60.dtb \
  12856. + imx6dl-gw51xx.dtb \
  12857. + imx6dl-gw52xx.dtb \
  12858. + imx6dl-gw53xx.dtb \
  12859. + imx6dl-gw54xx.dtb \
  12860. imx6dl-hummingboard.dtb \
  12861. + imx6dl-nitrogen6x.dtb \
  12862. + imx6dl-phytec-pbab01.dtb \
  12863. imx6dl-sabreauto.dtb \
  12864. + imx6dl-sabrelite.dtb \
  12865. imx6dl-sabresd.dtb \
  12866. + imx6dl-sabresd-hdcp.dtb \
  12867. imx6dl-wandboard.dtb \
  12868. imx6q-arm2.dtb \
  12869. + imx6q-cm-fx6.dtb \
  12870. imx6q-cubox-i.dtb \
  12871. + imx6q-hummingboard.dtb \
  12872. + imx6q-dfi-fs700-m60.dtb \
  12873. + imx6q-dmo-edmqmx6.dtb \
  12874. + imx6q-gk802.dtb \
  12875. + imx6q-gw51xx.dtb \
  12876. + imx6q-gw52xx.dtb \
  12877. + imx6q-gw53xx.dtb \
  12878. + imx6q-gw5400-a.dtb \
  12879. + imx6q-gw54xx.dtb \
  12880. + imx6q-nitrogen6x.dtb \
  12881. imx6q-phytec-pbab01.dtb \
  12882. imx6q-sabreauto.dtb \
  12883. imx6q-sabrelite.dtb \
  12884. imx6q-sabresd.dtb \
  12885. + imx6q-sabresd-hdcp.dtb \
  12886. imx6q-sbc6x.dtb \
  12887. imx6q-udoo.dtb \
  12888. imx6q-wandboard.dtb \
  12889. @@ -312,7 +333,14 @@
  12890. dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
  12891. vexpress-v2p-ca9.dtb \
  12892. vexpress-v2p-ca15-tc1.dtb \
  12893. - vexpress-v2p-ca15_a7.dtb
  12894. + vexpress-v2p-ca15_a7.dtb \
  12895. + rtsm_ve-cortex_a9x2.dtb \
  12896. + rtsm_ve-cortex_a9x4.dtb \
  12897. + rtsm_ve-cortex_a15x1.dtb \
  12898. + rtsm_ve-cortex_a15x2.dtb \
  12899. + rtsm_ve-cortex_a15x4.dtb \
  12900. + rtsm_ve-v2p-ca15x1-ca7x1.dtb \
  12901. + rtsm_ve-v2p-ca15x4-ca7x4.dtb
  12902. dtb-$(CONFIG_ARCH_VIRT) += xenvm-4.2.dtb
  12903. dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
  12904. wm8505-ref.dtb \
  12905. diff -Nur linux-3.14.14/arch/arm/boot/dts/marco.dtsi linux-imx6-3.14/arch/arm/boot/dts/marco.dtsi
  12906. --- linux-3.14.14/arch/arm/boot/dts/marco.dtsi 2014-07-28 10:07:25.000000000 -0500
  12907. +++ linux-imx6-3.14/arch/arm/boot/dts/marco.dtsi 2014-12-08 00:31:51.128418001 -0600
  12908. @@ -36,7 +36,7 @@
  12909. ranges = <0x40000000 0x40000000 0xa0000000>;
  12910. l2-cache-controller@c0030000 {
  12911. - compatible = "sirf,marco-pl310-cache", "arm,pl310-cache";
  12912. + compatible = "arm,pl310-cache";
  12913. reg = <0xc0030000 0x1000>;
  12914. interrupts = <0 59 0>;
  12915. arm,tag-latency = <1 1 1>;
  12916. diff -Nur linux-3.14.14/arch/arm/boot/dts/prima2.dtsi linux-imx6-3.14/arch/arm/boot/dts/prima2.dtsi
  12917. --- linux-3.14.14/arch/arm/boot/dts/prima2.dtsi 2014-07-28 10:07:25.000000000 -0500
  12918. +++ linux-imx6-3.14/arch/arm/boot/dts/prima2.dtsi 2014-12-08 00:31:51.132418001 -0600
  12919. @@ -48,7 +48,7 @@
  12920. ranges = <0x40000000 0x40000000 0x80000000>;
  12921. l2-cache-controller@80040000 {
  12922. - compatible = "arm,pl310-cache", "sirf,prima2-pl310-cache";
  12923. + compatible = "arm,pl310-cache";
  12924. reg = <0x80040000 0x1000>;
  12925. interrupts = <59>;
  12926. arm,tag-latency = <1 1 1>;
  12927. diff -Nur linux-3.14.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts
  12928. --- linux-3.14.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts 1969-12-31 18:00:00.000000000 -0600
  12929. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts 2014-12-08 00:31:51.136418001 -0600
  12930. @@ -0,0 +1,159 @@
  12931. +/*
  12932. + * ARM Ltd. Fast Models
  12933. + *
  12934. + * Versatile Express (VE) system model
  12935. + * ARMCortexA15x1CT
  12936. + *
  12937. + * RTSM_VE_Cortex_A15x1.lisa
  12938. + */
  12939. +
  12940. +/dts-v1/;
  12941. +
  12942. +/ {
  12943. + model = "RTSM_VE_CortexA15x1";
  12944. + arm,vexpress,site = <0xf>;
  12945. + compatible = "arm,rtsm_ve,cortex_a15x1", "arm,vexpress";
  12946. + interrupt-parent = <&gic>;
  12947. + #address-cells = <2>;
  12948. + #size-cells = <2>;
  12949. +
  12950. + chosen { };
  12951. +
  12952. + aliases {
  12953. + serial0 = &v2m_serial0;
  12954. + serial1 = &v2m_serial1;
  12955. + serial2 = &v2m_serial2;
  12956. + serial3 = &v2m_serial3;
  12957. + };
  12958. +
  12959. + cpus {
  12960. + #address-cells = <1>;
  12961. + #size-cells = <0>;
  12962. +
  12963. + cpu@0 {
  12964. + device_type = "cpu";
  12965. + compatible = "arm,cortex-a15";
  12966. + reg = <0>;
  12967. + };
  12968. + };
  12969. +
  12970. + memory@80000000 {
  12971. + device_type = "memory";
  12972. + reg = <0 0x80000000 0 0x80000000>;
  12973. + };
  12974. +
  12975. + gic: interrupt-controller@2c001000 {
  12976. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  12977. + #interrupt-cells = <3>;
  12978. + #address-cells = <0>;
  12979. + interrupt-controller;
  12980. + reg = <0 0x2c001000 0 0x1000>,
  12981. + <0 0x2c002000 0 0x1000>,
  12982. + <0 0x2c004000 0 0x2000>,
  12983. + <0 0x2c006000 0 0x2000>;
  12984. + interrupts = <1 9 0xf04>;
  12985. + };
  12986. +
  12987. + timer {
  12988. + compatible = "arm,armv7-timer";
  12989. + interrupts = <1 13 0xf08>,
  12990. + <1 14 0xf08>,
  12991. + <1 11 0xf08>,
  12992. + <1 10 0xf08>;
  12993. + };
  12994. +
  12995. + dcc {
  12996. + compatible = "arm,vexpress,config-bus";
  12997. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  12998. +
  12999. + osc@0 {
  13000. + /* ACLK clock to the AXI master port on the test chip */
  13001. + compatible = "arm,vexpress-osc";
  13002. + arm,vexpress-sysreg,func = <1 0>;
  13003. + freq-range = <30000000 50000000>;
  13004. + #clock-cells = <0>;
  13005. + clock-output-names = "extsaxiclk";
  13006. + };
  13007. +
  13008. + oscclk1: osc@1 {
  13009. + /* Reference clock for the CLCD */
  13010. + compatible = "arm,vexpress-osc";
  13011. + arm,vexpress-sysreg,func = <1 1>;
  13012. + freq-range = <10000000 80000000>;
  13013. + #clock-cells = <0>;
  13014. + clock-output-names = "clcdclk";
  13015. + };
  13016. +
  13017. + smbclk: oscclk2: osc@2 {
  13018. + /* Reference clock for the test chip internal PLLs */
  13019. + compatible = "arm,vexpress-osc";
  13020. + arm,vexpress-sysreg,func = <1 2>;
  13021. + freq-range = <33000000 100000000>;
  13022. + #clock-cells = <0>;
  13023. + clock-output-names = "tcrefclk";
  13024. + };
  13025. + };
  13026. +
  13027. + smb {
  13028. + compatible = "simple-bus";
  13029. +
  13030. + #address-cells = <2>;
  13031. + #size-cells = <1>;
  13032. + ranges = <0 0 0 0x08000000 0x04000000>,
  13033. + <1 0 0 0x14000000 0x04000000>,
  13034. + <2 0 0 0x18000000 0x04000000>,
  13035. + <3 0 0 0x1c000000 0x04000000>,
  13036. + <4 0 0 0x0c000000 0x04000000>,
  13037. + <5 0 0 0x10000000 0x04000000>;
  13038. +
  13039. + #interrupt-cells = <1>;
  13040. + interrupt-map-mask = <0 0 63>;
  13041. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13042. + <0 0 1 &gic 0 1 4>,
  13043. + <0 0 2 &gic 0 2 4>,
  13044. + <0 0 3 &gic 0 3 4>,
  13045. + <0 0 4 &gic 0 4 4>,
  13046. + <0 0 5 &gic 0 5 4>,
  13047. + <0 0 6 &gic 0 6 4>,
  13048. + <0 0 7 &gic 0 7 4>,
  13049. + <0 0 8 &gic 0 8 4>,
  13050. + <0 0 9 &gic 0 9 4>,
  13051. + <0 0 10 &gic 0 10 4>,
  13052. + <0 0 11 &gic 0 11 4>,
  13053. + <0 0 12 &gic 0 12 4>,
  13054. + <0 0 13 &gic 0 13 4>,
  13055. + <0 0 14 &gic 0 14 4>,
  13056. + <0 0 15 &gic 0 15 4>,
  13057. + <0 0 16 &gic 0 16 4>,
  13058. + <0 0 17 &gic 0 17 4>,
  13059. + <0 0 18 &gic 0 18 4>,
  13060. + <0 0 19 &gic 0 19 4>,
  13061. + <0 0 20 &gic 0 20 4>,
  13062. + <0 0 21 &gic 0 21 4>,
  13063. + <0 0 22 &gic 0 22 4>,
  13064. + <0 0 23 &gic 0 23 4>,
  13065. + <0 0 24 &gic 0 24 4>,
  13066. + <0 0 25 &gic 0 25 4>,
  13067. + <0 0 26 &gic 0 26 4>,
  13068. + <0 0 27 &gic 0 27 4>,
  13069. + <0 0 28 &gic 0 28 4>,
  13070. + <0 0 29 &gic 0 29 4>,
  13071. + <0 0 30 &gic 0 30 4>,
  13072. + <0 0 31 &gic 0 31 4>,
  13073. + <0 0 32 &gic 0 32 4>,
  13074. + <0 0 33 &gic 0 33 4>,
  13075. + <0 0 34 &gic 0 34 4>,
  13076. + <0 0 35 &gic 0 35 4>,
  13077. + <0 0 36 &gic 0 36 4>,
  13078. + <0 0 37 &gic 0 37 4>,
  13079. + <0 0 38 &gic 0 38 4>,
  13080. + <0 0 39 &gic 0 39 4>,
  13081. + <0 0 40 &gic 0 40 4>,
  13082. + <0 0 41 &gic 0 41 4>,
  13083. + <0 0 42 &gic 0 42 4>;
  13084. +
  13085. + /include/ "rtsm_ve-motherboard.dtsi"
  13086. + };
  13087. +};
  13088. +
  13089. +/include/ "clcd-panels.dtsi"
  13090. diff -Nur linux-3.14.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts
  13091. --- linux-3.14.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts 1969-12-31 18:00:00.000000000 -0600
  13092. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts 2014-12-08 00:31:51.136418001 -0600
  13093. @@ -0,0 +1,165 @@
  13094. +/*
  13095. + * ARM Ltd. Fast Models
  13096. + *
  13097. + * Versatile Express (VE) system model
  13098. + * ARMCortexA15x2CT
  13099. + *
  13100. + * RTSM_VE_Cortex_A15x2.lisa
  13101. + */
  13102. +
  13103. +/dts-v1/;
  13104. +
  13105. +/ {
  13106. + model = "RTSM_VE_CortexA15x2";
  13107. + arm,vexpress,site = <0xf>;
  13108. + compatible = "arm,rtsm_ve,cortex_a15x2", "arm,vexpress";
  13109. + interrupt-parent = <&gic>;
  13110. + #address-cells = <2>;
  13111. + #size-cells = <2>;
  13112. +
  13113. + chosen { };
  13114. +
  13115. + aliases {
  13116. + serial0 = &v2m_serial0;
  13117. + serial1 = &v2m_serial1;
  13118. + serial2 = &v2m_serial2;
  13119. + serial3 = &v2m_serial3;
  13120. + };
  13121. +
  13122. + cpus {
  13123. + #address-cells = <1>;
  13124. + #size-cells = <0>;
  13125. +
  13126. + cpu@0 {
  13127. + device_type = "cpu";
  13128. + compatible = "arm,cortex-a15";
  13129. + reg = <0>;
  13130. + };
  13131. +
  13132. + cpu@1 {
  13133. + device_type = "cpu";
  13134. + compatible = "arm,cortex-a15";
  13135. + reg = <1>;
  13136. + };
  13137. + };
  13138. +
  13139. + memory@80000000 {
  13140. + device_type = "memory";
  13141. + reg = <0 0x80000000 0 0x80000000>;
  13142. + };
  13143. +
  13144. + gic: interrupt-controller@2c001000 {
  13145. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  13146. + #interrupt-cells = <3>;
  13147. + #address-cells = <0>;
  13148. + interrupt-controller;
  13149. + reg = <0 0x2c001000 0 0x1000>,
  13150. + <0 0x2c002000 0 0x1000>,
  13151. + <0 0x2c004000 0 0x2000>,
  13152. + <0 0x2c006000 0 0x2000>;
  13153. + interrupts = <1 9 0xf04>;
  13154. + };
  13155. +
  13156. + timer {
  13157. + compatible = "arm,armv7-timer";
  13158. + interrupts = <1 13 0xf08>,
  13159. + <1 14 0xf08>,
  13160. + <1 11 0xf08>,
  13161. + <1 10 0xf08>;
  13162. + };
  13163. +
  13164. + dcc {
  13165. + compatible = "arm,vexpress,config-bus";
  13166. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13167. +
  13168. + osc@0 {
  13169. + /* ACLK clock to the AXI master port on the test chip */
  13170. + compatible = "arm,vexpress-osc";
  13171. + arm,vexpress-sysreg,func = <1 0>;
  13172. + freq-range = <30000000 50000000>;
  13173. + #clock-cells = <0>;
  13174. + clock-output-names = "extsaxiclk";
  13175. + };
  13176. +
  13177. + oscclk1: osc@1 {
  13178. + /* Reference clock for the CLCD */
  13179. + compatible = "arm,vexpress-osc";
  13180. + arm,vexpress-sysreg,func = <1 1>;
  13181. + freq-range = <10000000 80000000>;
  13182. + #clock-cells = <0>;
  13183. + clock-output-names = "clcdclk";
  13184. + };
  13185. +
  13186. + smbclk: oscclk2: osc@2 {
  13187. + /* Reference clock for the test chip internal PLLs */
  13188. + compatible = "arm,vexpress-osc";
  13189. + arm,vexpress-sysreg,func = <1 2>;
  13190. + freq-range = <33000000 100000000>;
  13191. + #clock-cells = <0>;
  13192. + clock-output-names = "tcrefclk";
  13193. + };
  13194. + };
  13195. +
  13196. + smb {
  13197. + compatible = "simple-bus";
  13198. +
  13199. + #address-cells = <2>;
  13200. + #size-cells = <1>;
  13201. + ranges = <0 0 0 0x08000000 0x04000000>,
  13202. + <1 0 0 0x14000000 0x04000000>,
  13203. + <2 0 0 0x18000000 0x04000000>,
  13204. + <3 0 0 0x1c000000 0x04000000>,
  13205. + <4 0 0 0x0c000000 0x04000000>,
  13206. + <5 0 0 0x10000000 0x04000000>;
  13207. +
  13208. + #interrupt-cells = <1>;
  13209. + interrupt-map-mask = <0 0 63>;
  13210. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13211. + <0 0 1 &gic 0 1 4>,
  13212. + <0 0 2 &gic 0 2 4>,
  13213. + <0 0 3 &gic 0 3 4>,
  13214. + <0 0 4 &gic 0 4 4>,
  13215. + <0 0 5 &gic 0 5 4>,
  13216. + <0 0 6 &gic 0 6 4>,
  13217. + <0 0 7 &gic 0 7 4>,
  13218. + <0 0 8 &gic 0 8 4>,
  13219. + <0 0 9 &gic 0 9 4>,
  13220. + <0 0 10 &gic 0 10 4>,
  13221. + <0 0 11 &gic 0 11 4>,
  13222. + <0 0 12 &gic 0 12 4>,
  13223. + <0 0 13 &gic 0 13 4>,
  13224. + <0 0 14 &gic 0 14 4>,
  13225. + <0 0 15 &gic 0 15 4>,
  13226. + <0 0 16 &gic 0 16 4>,
  13227. + <0 0 17 &gic 0 17 4>,
  13228. + <0 0 18 &gic 0 18 4>,
  13229. + <0 0 19 &gic 0 19 4>,
  13230. + <0 0 20 &gic 0 20 4>,
  13231. + <0 0 21 &gic 0 21 4>,
  13232. + <0 0 22 &gic 0 22 4>,
  13233. + <0 0 23 &gic 0 23 4>,
  13234. + <0 0 24 &gic 0 24 4>,
  13235. + <0 0 25 &gic 0 25 4>,
  13236. + <0 0 26 &gic 0 26 4>,
  13237. + <0 0 27 &gic 0 27 4>,
  13238. + <0 0 28 &gic 0 28 4>,
  13239. + <0 0 29 &gic 0 29 4>,
  13240. + <0 0 30 &gic 0 30 4>,
  13241. + <0 0 31 &gic 0 31 4>,
  13242. + <0 0 32 &gic 0 32 4>,
  13243. + <0 0 33 &gic 0 33 4>,
  13244. + <0 0 34 &gic 0 34 4>,
  13245. + <0 0 35 &gic 0 35 4>,
  13246. + <0 0 36 &gic 0 36 4>,
  13247. + <0 0 37 &gic 0 37 4>,
  13248. + <0 0 38 &gic 0 38 4>,
  13249. + <0 0 39 &gic 0 39 4>,
  13250. + <0 0 40 &gic 0 40 4>,
  13251. + <0 0 41 &gic 0 41 4>,
  13252. + <0 0 42 &gic 0 42 4>;
  13253. +
  13254. + /include/ "rtsm_ve-motherboard.dtsi"
  13255. + };
  13256. +};
  13257. +
  13258. +/include/ "clcd-panels.dtsi"
  13259. diff -Nur linux-3.14.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts
  13260. --- linux-3.14.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts 1969-12-31 18:00:00.000000000 -0600
  13261. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts 2014-12-08 00:31:51.136418001 -0600
  13262. @@ -0,0 +1,177 @@
  13263. +/*
  13264. + * ARM Ltd. Fast Models
  13265. + *
  13266. + * Versatile Express (VE) system model
  13267. + * ARMCortexA15x4CT
  13268. + *
  13269. + * RTSM_VE_Cortex_A15x4.lisa
  13270. + */
  13271. +
  13272. +/dts-v1/;
  13273. +
  13274. +/ {
  13275. + model = "RTSM_VE_CortexA15x4";
  13276. + arm,vexpress,site = <0xf>;
  13277. + compatible = "arm,rtsm_ve,cortex_a15x4", "arm,vexpress";
  13278. + interrupt-parent = <&gic>;
  13279. + #address-cells = <2>;
  13280. + #size-cells = <2>;
  13281. +
  13282. + chosen { };
  13283. +
  13284. + aliases {
  13285. + serial0 = &v2m_serial0;
  13286. + serial1 = &v2m_serial1;
  13287. + serial2 = &v2m_serial2;
  13288. + serial3 = &v2m_serial3;
  13289. + };
  13290. +
  13291. + cpus {
  13292. + #address-cells = <1>;
  13293. + #size-cells = <0>;
  13294. +
  13295. + cpu@0 {
  13296. + device_type = "cpu";
  13297. + compatible = "arm,cortex-a15";
  13298. + reg = <0>;
  13299. + };
  13300. +
  13301. + cpu@1 {
  13302. + device_type = "cpu";
  13303. + compatible = "arm,cortex-a15";
  13304. + reg = <1>;
  13305. + };
  13306. +
  13307. + cpu@2 {
  13308. + device_type = "cpu";
  13309. + compatible = "arm,cortex-a15";
  13310. + reg = <2>;
  13311. + };
  13312. +
  13313. + cpu@3 {
  13314. + device_type = "cpu";
  13315. + compatible = "arm,cortex-a15";
  13316. + reg = <3>;
  13317. + };
  13318. + };
  13319. +
  13320. + memory@80000000 {
  13321. + device_type = "memory";
  13322. + reg = <0 0x80000000 0 0x80000000>;
  13323. + };
  13324. +
  13325. + gic: interrupt-controller@2c001000 {
  13326. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  13327. + #interrupt-cells = <3>;
  13328. + #address-cells = <0>;
  13329. + interrupt-controller;
  13330. + reg = <0 0x2c001000 0 0x1000>,
  13331. + <0 0x2c002000 0 0x1000>,
  13332. + <0 0x2c004000 0 0x2000>,
  13333. + <0 0x2c006000 0 0x2000>;
  13334. + interrupts = <1 9 0xf04>;
  13335. + };
  13336. +
  13337. + timer {
  13338. + compatible = "arm,armv7-timer";
  13339. + interrupts = <1 13 0xf08>,
  13340. + <1 14 0xf08>,
  13341. + <1 11 0xf08>,
  13342. + <1 10 0xf08>;
  13343. + };
  13344. +
  13345. + dcc {
  13346. + compatible = "arm,vexpress,config-bus";
  13347. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13348. +
  13349. + osc@0 {
  13350. + /* ACLK clock to the AXI master port on the test chip */
  13351. + compatible = "arm,vexpress-osc";
  13352. + arm,vexpress-sysreg,func = <1 0>;
  13353. + freq-range = <30000000 50000000>;
  13354. + #clock-cells = <0>;
  13355. + clock-output-names = "extsaxiclk";
  13356. + };
  13357. +
  13358. + oscclk1: osc@1 {
  13359. + /* Reference clock for the CLCD */
  13360. + compatible = "arm,vexpress-osc";
  13361. + arm,vexpress-sysreg,func = <1 1>;
  13362. + freq-range = <10000000 80000000>;
  13363. + #clock-cells = <0>;
  13364. + clock-output-names = "clcdclk";
  13365. + };
  13366. +
  13367. + smbclk: oscclk2: osc@2 {
  13368. + /* Reference clock for the test chip internal PLLs */
  13369. + compatible = "arm,vexpress-osc";
  13370. + arm,vexpress-sysreg,func = <1 2>;
  13371. + freq-range = <33000000 100000000>;
  13372. + #clock-cells = <0>;
  13373. + clock-output-names = "tcrefclk";
  13374. + };
  13375. + };
  13376. +
  13377. + smb {
  13378. + compatible = "simple-bus";
  13379. +
  13380. + #address-cells = <2>;
  13381. + #size-cells = <1>;
  13382. + ranges = <0 0 0 0x08000000 0x04000000>,
  13383. + <1 0 0 0x14000000 0x04000000>,
  13384. + <2 0 0 0x18000000 0x04000000>,
  13385. + <3 0 0 0x1c000000 0x04000000>,
  13386. + <4 0 0 0x0c000000 0x04000000>,
  13387. + <5 0 0 0x10000000 0x04000000>;
  13388. +
  13389. + #interrupt-cells = <1>;
  13390. + interrupt-map-mask = <0 0 63>;
  13391. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13392. + <0 0 1 &gic 0 1 4>,
  13393. + <0 0 2 &gic 0 2 4>,
  13394. + <0 0 3 &gic 0 3 4>,
  13395. + <0 0 4 &gic 0 4 4>,
  13396. + <0 0 5 &gic 0 5 4>,
  13397. + <0 0 6 &gic 0 6 4>,
  13398. + <0 0 7 &gic 0 7 4>,
  13399. + <0 0 8 &gic 0 8 4>,
  13400. + <0 0 9 &gic 0 9 4>,
  13401. + <0 0 10 &gic 0 10 4>,
  13402. + <0 0 11 &gic 0 11 4>,
  13403. + <0 0 12 &gic 0 12 4>,
  13404. + <0 0 13 &gic 0 13 4>,
  13405. + <0 0 14 &gic 0 14 4>,
  13406. + <0 0 15 &gic 0 15 4>,
  13407. + <0 0 16 &gic 0 16 4>,
  13408. + <0 0 17 &gic 0 17 4>,
  13409. + <0 0 18 &gic 0 18 4>,
  13410. + <0 0 19 &gic 0 19 4>,
  13411. + <0 0 20 &gic 0 20 4>,
  13412. + <0 0 21 &gic 0 21 4>,
  13413. + <0 0 22 &gic 0 22 4>,
  13414. + <0 0 23 &gic 0 23 4>,
  13415. + <0 0 24 &gic 0 24 4>,
  13416. + <0 0 25 &gic 0 25 4>,
  13417. + <0 0 26 &gic 0 26 4>,
  13418. + <0 0 27 &gic 0 27 4>,
  13419. + <0 0 28 &gic 0 28 4>,
  13420. + <0 0 29 &gic 0 29 4>,
  13421. + <0 0 30 &gic 0 30 4>,
  13422. + <0 0 31 &gic 0 31 4>,
  13423. + <0 0 32 &gic 0 32 4>,
  13424. + <0 0 33 &gic 0 33 4>,
  13425. + <0 0 34 &gic 0 34 4>,
  13426. + <0 0 35 &gic 0 35 4>,
  13427. + <0 0 36 &gic 0 36 4>,
  13428. + <0 0 37 &gic 0 37 4>,
  13429. + <0 0 38 &gic 0 38 4>,
  13430. + <0 0 39 &gic 0 39 4>,
  13431. + <0 0 40 &gic 0 40 4>,
  13432. + <0 0 41 &gic 0 41 4>,
  13433. + <0 0 42 &gic 0 42 4>;
  13434. +
  13435. + /include/ "rtsm_ve-motherboard.dtsi"
  13436. + };
  13437. +};
  13438. +
  13439. +/include/ "clcd-panels.dtsi"
  13440. diff -Nur linux-3.14.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts
  13441. --- linux-3.14.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts 1969-12-31 18:00:00.000000000 -0600
  13442. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts 2014-12-08 00:31:51.136418001 -0600
  13443. @@ -0,0 +1,171 @@
  13444. +/*
  13445. + * ARM Ltd. Fast Models
  13446. + *
  13447. + * Versatile Express (VE) system model
  13448. + * ARMCortexA9MPx2CT
  13449. + *
  13450. + * RTSM_VE_Cortex_A9x2.lisa
  13451. + */
  13452. +
  13453. +/dts-v1/;
  13454. +
  13455. +/ {
  13456. + model = "RTSM_VE_CortexA9x2";
  13457. + arm,vexpress,site = <0xf>;
  13458. + compatible = "arm,rtsm_ve,cortex_a9x2", "arm,vexpress";
  13459. + interrupt-parent = <&gic>;
  13460. + #address-cells = <1>;
  13461. + #size-cells = <1>;
  13462. +
  13463. + chosen { };
  13464. +
  13465. + aliases {
  13466. + serial0 = &v2m_serial0;
  13467. + serial1 = &v2m_serial1;
  13468. + serial2 = &v2m_serial2;
  13469. + serial3 = &v2m_serial3;
  13470. + };
  13471. +
  13472. + cpus {
  13473. + #address-cells = <1>;
  13474. + #size-cells = <0>;
  13475. +
  13476. + cpu@0 {
  13477. + device_type = "cpu";
  13478. + compatible = "arm,cortex-a9";
  13479. + reg = <0>;
  13480. + };
  13481. +
  13482. + cpu@1 {
  13483. + device_type = "cpu";
  13484. + compatible = "arm,cortex-a9";
  13485. + reg = <1>;
  13486. + };
  13487. + };
  13488. +
  13489. + memory@80000000 {
  13490. + device_type = "memory";
  13491. + reg = <0x80000000 0x80000000>;
  13492. + };
  13493. +
  13494. + scu@2c000000 {
  13495. + compatible = "arm,cortex-a9-scu";
  13496. + reg = <0x2c000000 0x58>;
  13497. + };
  13498. +
  13499. + timer@2c000600 {
  13500. + compatible = "arm,cortex-a9-twd-timer";
  13501. + reg = <0x2c000600 0x20>;
  13502. + interrupts = <1 13 0xf04>;
  13503. + };
  13504. +
  13505. + watchdog@2c000620 {
  13506. + compatible = "arm,cortex-a9-twd-wdt";
  13507. + reg = <0x2c000620 0x20>;
  13508. + interrupts = <1 14 0xf04>;
  13509. + };
  13510. +
  13511. + gic: interrupt-controller@2c001000 {
  13512. + compatible = "arm,cortex-a9-gic";
  13513. + #interrupt-cells = <3>;
  13514. + #address-cells = <0>;
  13515. + interrupt-controller;
  13516. + reg = <0x2c001000 0x1000>,
  13517. + <0x2c000100 0x100>;
  13518. + };
  13519. +
  13520. + dcc {
  13521. + compatible = "arm,vexpress,config-bus";
  13522. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13523. +
  13524. + osc@0 {
  13525. + /* ACLK clock to the AXI master port on the test chip */
  13526. + compatible = "arm,vexpress-osc";
  13527. + arm,vexpress-sysreg,func = <1 0>;
  13528. + freq-range = <30000000 50000000>;
  13529. + #clock-cells = <0>;
  13530. + clock-output-names = "extsaxiclk";
  13531. + };
  13532. +
  13533. + oscclk1: osc@1 {
  13534. + /* Reference clock for the CLCD */
  13535. + compatible = "arm,vexpress-osc";
  13536. + arm,vexpress-sysreg,func = <1 1>;
  13537. + freq-range = <10000000 80000000>;
  13538. + #clock-cells = <0>;
  13539. + clock-output-names = "clcdclk";
  13540. + };
  13541. +
  13542. + smbclk: oscclk2: osc@2 {
  13543. + /* Reference clock for the test chip internal PLLs */
  13544. + compatible = "arm,vexpress-osc";
  13545. + arm,vexpress-sysreg,func = <1 2>;
  13546. + freq-range = <33000000 100000000>;
  13547. + #clock-cells = <0>;
  13548. + clock-output-names = "tcrefclk";
  13549. + };
  13550. + };
  13551. +
  13552. + smb {
  13553. + compatible = "simple-bus";
  13554. +
  13555. + #address-cells = <2>;
  13556. + #size-cells = <1>;
  13557. + ranges = <0 0 0x08000000 0x04000000>,
  13558. + <1 0 0x14000000 0x04000000>,
  13559. + <2 0 0x18000000 0x04000000>,
  13560. + <3 0 0x1c000000 0x04000000>,
  13561. + <4 0 0x0c000000 0x04000000>,
  13562. + <5 0 0x10000000 0x04000000>;
  13563. +
  13564. + #interrupt-cells = <1>;
  13565. + interrupt-map-mask = <0 0 63>;
  13566. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13567. + <0 0 1 &gic 0 1 4>,
  13568. + <0 0 2 &gic 0 2 4>,
  13569. + <0 0 3 &gic 0 3 4>,
  13570. + <0 0 4 &gic 0 4 4>,
  13571. + <0 0 5 &gic 0 5 4>,
  13572. + <0 0 6 &gic 0 6 4>,
  13573. + <0 0 7 &gic 0 7 4>,
  13574. + <0 0 8 &gic 0 8 4>,
  13575. + <0 0 9 &gic 0 9 4>,
  13576. + <0 0 10 &gic 0 10 4>,
  13577. + <0 0 11 &gic 0 11 4>,
  13578. + <0 0 12 &gic 0 12 4>,
  13579. + <0 0 13 &gic 0 13 4>,
  13580. + <0 0 14 &gic 0 14 4>,
  13581. + <0 0 15 &gic 0 15 4>,
  13582. + <0 0 16 &gic 0 16 4>,
  13583. + <0 0 17 &gic 0 17 4>,
  13584. + <0 0 18 &gic 0 18 4>,
  13585. + <0 0 19 &gic 0 19 4>,
  13586. + <0 0 20 &gic 0 20 4>,
  13587. + <0 0 21 &gic 0 21 4>,
  13588. + <0 0 22 &gic 0 22 4>,
  13589. + <0 0 23 &gic 0 23 4>,
  13590. + <0 0 24 &gic 0 24 4>,
  13591. + <0 0 25 &gic 0 25 4>,
  13592. + <0 0 26 &gic 0 26 4>,
  13593. + <0 0 27 &gic 0 27 4>,
  13594. + <0 0 28 &gic 0 28 4>,
  13595. + <0 0 29 &gic 0 29 4>,
  13596. + <0 0 30 &gic 0 30 4>,
  13597. + <0 0 31 &gic 0 31 4>,
  13598. + <0 0 32 &gic 0 32 4>,
  13599. + <0 0 33 &gic 0 33 4>,
  13600. + <0 0 34 &gic 0 34 4>,
  13601. + <0 0 35 &gic 0 35 4>,
  13602. + <0 0 36 &gic 0 36 4>,
  13603. + <0 0 37 &gic 0 37 4>,
  13604. + <0 0 38 &gic 0 38 4>,
  13605. + <0 0 39 &gic 0 39 4>,
  13606. + <0 0 40 &gic 0 40 4>,
  13607. + <0 0 41 &gic 0 41 4>,
  13608. + <0 0 42 &gic 0 42 4>;
  13609. +
  13610. + /include/ "rtsm_ve-motherboard.dtsi"
  13611. + };
  13612. +};
  13613. +
  13614. +/include/ "clcd-panels.dtsi"
  13615. diff -Nur linux-3.14.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts
  13616. --- linux-3.14.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts 1969-12-31 18:00:00.000000000 -0600
  13617. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts 2014-12-08 00:31:51.136418001 -0600
  13618. @@ -0,0 +1,183 @@
  13619. +/*
  13620. + * ARM Ltd. Fast Models
  13621. + *
  13622. + * Versatile Express (VE) system model
  13623. + * ARMCortexA9MPx4CT
  13624. + *
  13625. + * RTSM_VE_Cortex_A9x4.lisa
  13626. + */
  13627. +
  13628. +/dts-v1/;
  13629. +
  13630. +/ {
  13631. + model = "RTSM_VE_CortexA9x4";
  13632. + arm,vexpress,site = <0xf>;
  13633. + compatible = "arm,rtsm_ve,cortex_a9x4", "arm,vexpress";
  13634. + interrupt-parent = <&gic>;
  13635. + #address-cells = <1>;
  13636. + #size-cells = <1>;
  13637. +
  13638. + chosen { };
  13639. +
  13640. + aliases {
  13641. + serial0 = &v2m_serial0;
  13642. + serial1 = &v2m_serial1;
  13643. + serial2 = &v2m_serial2;
  13644. + serial3 = &v2m_serial3;
  13645. + };
  13646. +
  13647. + cpus {
  13648. + #address-cells = <1>;
  13649. + #size-cells = <0>;
  13650. +
  13651. + cpu@0 {
  13652. + device_type = "cpu";
  13653. + compatible = "arm,cortex-a9";
  13654. + reg = <0>;
  13655. + };
  13656. +
  13657. + cpu@1 {
  13658. + device_type = "cpu";
  13659. + compatible = "arm,cortex-a9";
  13660. + reg = <1>;
  13661. + };
  13662. +
  13663. + cpu@2 {
  13664. + device_type = "cpu";
  13665. + compatible = "arm,cortex-a9";
  13666. + reg = <2>;
  13667. + };
  13668. +
  13669. + cpu@3 {
  13670. + device_type = "cpu";
  13671. + compatible = "arm,cortex-a9";
  13672. + reg = <3>;
  13673. + };
  13674. + };
  13675. +
  13676. + memory@80000000 {
  13677. + device_type = "memory";
  13678. + reg = <0x80000000 0x80000000>;
  13679. + };
  13680. +
  13681. + scu@2c000000 {
  13682. + compatible = "arm,cortex-a9-scu";
  13683. + reg = <0x2c000000 0x58>;
  13684. + };
  13685. +
  13686. + timer@2c000600 {
  13687. + compatible = "arm,cortex-a9-twd-timer";
  13688. + reg = <0x2c000600 0x20>;
  13689. + interrupts = <1 13 0xf04>;
  13690. + };
  13691. +
  13692. + watchdog@2c000620 {
  13693. + compatible = "arm,cortex-a9-twd-wdt";
  13694. + reg = <0x2c000620 0x20>;
  13695. + interrupts = <1 14 0xf04>;
  13696. + };
  13697. +
  13698. + gic: interrupt-controller@2c001000 {
  13699. + compatible = "arm,cortex-a9-gic";
  13700. + #interrupt-cells = <3>;
  13701. + #address-cells = <0>;
  13702. + interrupt-controller;
  13703. + reg = <0x2c001000 0x1000>,
  13704. + <0x2c000100 0x100>;
  13705. + };
  13706. +
  13707. + dcc {
  13708. + compatible = "arm,vexpress,config-bus";
  13709. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13710. +
  13711. + osc@0 {
  13712. + /* ACLK clock to the AXI master port on the test chip */
  13713. + compatible = "arm,vexpress-osc";
  13714. + arm,vexpress-sysreg,func = <1 0>;
  13715. + freq-range = <30000000 50000000>;
  13716. + #clock-cells = <0>;
  13717. + clock-output-names = "extsaxiclk";
  13718. + };
  13719. +
  13720. + oscclk1: osc@1 {
  13721. + /* Reference clock for the CLCD */
  13722. + compatible = "arm,vexpress-osc";
  13723. + arm,vexpress-sysreg,func = <1 1>;
  13724. + freq-range = <10000000 80000000>;
  13725. + #clock-cells = <0>;
  13726. + clock-output-names = "clcdclk";
  13727. + };
  13728. +
  13729. + smbclk: oscclk2: osc@2 {
  13730. + /* Reference clock for the test chip internal PLLs */
  13731. + compatible = "arm,vexpress-osc";
  13732. + arm,vexpress-sysreg,func = <1 2>;
  13733. + freq-range = <33000000 100000000>;
  13734. + #clock-cells = <0>;
  13735. + clock-output-names = "tcrefclk";
  13736. + };
  13737. + };
  13738. +
  13739. + smb {
  13740. + compatible = "simple-bus";
  13741. +
  13742. + #address-cells = <2>;
  13743. + #size-cells = <1>;
  13744. + ranges = <0 0 0x08000000 0x04000000>,
  13745. + <1 0 0x14000000 0x04000000>,
  13746. + <2 0 0x18000000 0x04000000>,
  13747. + <3 0 0x1c000000 0x04000000>,
  13748. + <4 0 0x0c000000 0x04000000>,
  13749. + <5 0 0x10000000 0x04000000>;
  13750. +
  13751. + #interrupt-cells = <1>;
  13752. + interrupt-map-mask = <0 0 63>;
  13753. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13754. + <0 0 1 &gic 0 1 4>,
  13755. + <0 0 2 &gic 0 2 4>,
  13756. + <0 0 3 &gic 0 3 4>,
  13757. + <0 0 4 &gic 0 4 4>,
  13758. + <0 0 5 &gic 0 5 4>,
  13759. + <0 0 6 &gic 0 6 4>,
  13760. + <0 0 7 &gic 0 7 4>,
  13761. + <0 0 8 &gic 0 8 4>,
  13762. + <0 0 9 &gic 0 9 4>,
  13763. + <0 0 10 &gic 0 10 4>,
  13764. + <0 0 11 &gic 0 11 4>,
  13765. + <0 0 12 &gic 0 12 4>,
  13766. + <0 0 13 &gic 0 13 4>,
  13767. + <0 0 14 &gic 0 14 4>,
  13768. + <0 0 15 &gic 0 15 4>,
  13769. + <0 0 16 &gic 0 16 4>,
  13770. + <0 0 17 &gic 0 17 4>,
  13771. + <0 0 18 &gic 0 18 4>,
  13772. + <0 0 19 &gic 0 19 4>,
  13773. + <0 0 20 &gic 0 20 4>,
  13774. + <0 0 21 &gic 0 21 4>,
  13775. + <0 0 22 &gic 0 22 4>,
  13776. + <0 0 23 &gic 0 23 4>,
  13777. + <0 0 24 &gic 0 24 4>,
  13778. + <0 0 25 &gic 0 25 4>,
  13779. + <0 0 26 &gic 0 26 4>,
  13780. + <0 0 27 &gic 0 27 4>,
  13781. + <0 0 28 &gic 0 28 4>,
  13782. + <0 0 29 &gic 0 29 4>,
  13783. + <0 0 30 &gic 0 30 4>,
  13784. + <0 0 31 &gic 0 31 4>,
  13785. + <0 0 32 &gic 0 32 4>,
  13786. + <0 0 33 &gic 0 33 4>,
  13787. + <0 0 34 &gic 0 34 4>,
  13788. + <0 0 35 &gic 0 35 4>,
  13789. + <0 0 36 &gic 0 36 4>,
  13790. + <0 0 37 &gic 0 37 4>,
  13791. + <0 0 38 &gic 0 38 4>,
  13792. + <0 0 39 &gic 0 39 4>,
  13793. + <0 0 40 &gic 0 40 4>,
  13794. + <0 0 41 &gic 0 41 4>,
  13795. + <0 0 42 &gic 0 42 4>;
  13796. +
  13797. + /include/ "rtsm_ve-motherboard.dtsi"
  13798. + };
  13799. +};
  13800. +
  13801. +/include/ "clcd-panels.dtsi"
  13802. diff -Nur linux-3.14.14/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi
  13803. --- linux-3.14.14/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi 1969-12-31 18:00:00.000000000 -0600
  13804. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi 2014-12-08 00:31:51.136418001 -0600
  13805. @@ -0,0 +1,231 @@
  13806. +/*
  13807. + * ARM Ltd. Fast Models
  13808. + *
  13809. + * Versatile Express (VE) system model
  13810. + * Motherboard component
  13811. + *
  13812. + * VEMotherBoard.lisa
  13813. + */
  13814. +
  13815. + motherboard {
  13816. + compatible = "arm,vexpress,v2m-p1", "simple-bus";
  13817. + arm,hbi = <0x190>;
  13818. + arm,vexpress,site = <0>;
  13819. + arm,v2m-memory-map = "rs1";
  13820. + #address-cells = <2>; /* SMB chipselect number and offset */
  13821. + #size-cells = <1>;
  13822. + #interrupt-cells = <1>;
  13823. + ranges;
  13824. +
  13825. + flash@0,00000000 {
  13826. + compatible = "arm,vexpress-flash", "cfi-flash";
  13827. + reg = <0 0x00000000 0x04000000>,
  13828. + <4 0x00000000 0x04000000>;
  13829. + bank-width = <4>;
  13830. + };
  13831. +
  13832. + vram@2,00000000 {
  13833. + compatible = "arm,vexpress-vram";
  13834. + reg = <2 0x00000000 0x00800000>;
  13835. + };
  13836. +
  13837. + ethernet@2,02000000 {
  13838. + compatible = "smsc,lan91c111";
  13839. + reg = <2 0x02000000 0x10000>;
  13840. + interrupts = <15>;
  13841. + };
  13842. +
  13843. + iofpga@3,00000000 {
  13844. + compatible = "arm,amba-bus", "simple-bus";
  13845. + #address-cells = <1>;
  13846. + #size-cells = <1>;
  13847. + ranges = <0 3 0 0x200000>;
  13848. +
  13849. + v2m_sysreg: sysreg@010000 {
  13850. + compatible = "arm,vexpress-sysreg";
  13851. + reg = <0x010000 0x1000>;
  13852. + gpio-controller;
  13853. + #gpio-cells = <2>;
  13854. + };
  13855. +
  13856. + v2m_sysctl: sysctl@020000 {
  13857. + compatible = "arm,sp810", "arm,primecell";
  13858. + reg = <0x020000 0x1000>;
  13859. + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
  13860. + clock-names = "refclk", "timclk", "apb_pclk";
  13861. + #clock-cells = <1>;
  13862. + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
  13863. + };
  13864. +
  13865. + aaci@040000 {
  13866. + compatible = "arm,pl041", "arm,primecell";
  13867. + reg = <0x040000 0x1000>;
  13868. + interrupts = <11>;
  13869. + clocks = <&smbclk>;
  13870. + clock-names = "apb_pclk";
  13871. + };
  13872. +
  13873. + mmci@050000 {
  13874. + compatible = "arm,pl180", "arm,primecell";
  13875. + reg = <0x050000 0x1000>;
  13876. + interrupts = <9 10>;
  13877. + cd-gpios = <&v2m_sysreg 0 0>;
  13878. + wp-gpios = <&v2m_sysreg 1 0>;
  13879. + max-frequency = <12000000>;
  13880. + vmmc-supply = <&v2m_fixed_3v3>;
  13881. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13882. + clock-names = "mclk", "apb_pclk";
  13883. + };
  13884. +
  13885. + kmi@060000 {
  13886. + compatible = "arm,pl050", "arm,primecell";
  13887. + reg = <0x060000 0x1000>;
  13888. + interrupts = <12>;
  13889. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13890. + clock-names = "KMIREFCLK", "apb_pclk";
  13891. + };
  13892. +
  13893. + kmi@070000 {
  13894. + compatible = "arm,pl050", "arm,primecell";
  13895. + reg = <0x070000 0x1000>;
  13896. + interrupts = <13>;
  13897. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13898. + clock-names = "KMIREFCLK", "apb_pclk";
  13899. + };
  13900. +
  13901. + v2m_serial0: uart@090000 {
  13902. + compatible = "arm,pl011", "arm,primecell";
  13903. + reg = <0x090000 0x1000>;
  13904. + interrupts = <5>;
  13905. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13906. + clock-names = "uartclk", "apb_pclk";
  13907. + };
  13908. +
  13909. + v2m_serial1: uart@0a0000 {
  13910. + compatible = "arm,pl011", "arm,primecell";
  13911. + reg = <0x0a0000 0x1000>;
  13912. + interrupts = <6>;
  13913. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13914. + clock-names = "uartclk", "apb_pclk";
  13915. + };
  13916. +
  13917. + v2m_serial2: uart@0b0000 {
  13918. + compatible = "arm,pl011", "arm,primecell";
  13919. + reg = <0x0b0000 0x1000>;
  13920. + interrupts = <7>;
  13921. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13922. + clock-names = "uartclk", "apb_pclk";
  13923. + };
  13924. +
  13925. + v2m_serial3: uart@0c0000 {
  13926. + compatible = "arm,pl011", "arm,primecell";
  13927. + reg = <0x0c0000 0x1000>;
  13928. + interrupts = <8>;
  13929. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13930. + clock-names = "uartclk", "apb_pclk";
  13931. + };
  13932. +
  13933. + wdt@0f0000 {
  13934. + compatible = "arm,sp805", "arm,primecell";
  13935. + reg = <0x0f0000 0x1000>;
  13936. + interrupts = <0>;
  13937. + clocks = <&v2m_refclk32khz>, <&smbclk>;
  13938. + clock-names = "wdogclk", "apb_pclk";
  13939. + };
  13940. +
  13941. + v2m_timer01: timer@110000 {
  13942. + compatible = "arm,sp804", "arm,primecell";
  13943. + reg = <0x110000 0x1000>;
  13944. + interrupts = <2>;
  13945. + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
  13946. + clock-names = "timclken1", "timclken2", "apb_pclk";
  13947. + };
  13948. +
  13949. + v2m_timer23: timer@120000 {
  13950. + compatible = "arm,sp804", "arm,primecell";
  13951. + reg = <0x120000 0x1000>;
  13952. + interrupts = <3>;
  13953. + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
  13954. + clock-names = "timclken1", "timclken2", "apb_pclk";
  13955. + };
  13956. +
  13957. + rtc@170000 {
  13958. + compatible = "arm,pl031", "arm,primecell";
  13959. + reg = <0x170000 0x1000>;
  13960. + interrupts = <4>;
  13961. + clocks = <&smbclk>;
  13962. + clock-names = "apb_pclk";
  13963. + };
  13964. +
  13965. + clcd@1f0000 {
  13966. + compatible = "arm,pl111", "arm,primecell";
  13967. + reg = <0x1f0000 0x1000>;
  13968. + interrupts = <14>;
  13969. + clocks = <&v2m_oscclk1>, <&smbclk>;
  13970. + clock-names = "v2m:oscclk1", "apb_pclk";
  13971. + mode = "VGA";
  13972. + use_dma = <0>;
  13973. + framebuffer = <0x18000000 0x00180000>;
  13974. + };
  13975. +
  13976. + virtio_block@0130000 {
  13977. + compatible = "virtio,mmio";
  13978. + reg = <0x130000 0x200>;
  13979. + interrupts = <42>;
  13980. + };
  13981. +
  13982. + };
  13983. +
  13984. + v2m_fixed_3v3: fixedregulator@0 {
  13985. + compatible = "regulator-fixed";
  13986. + regulator-name = "3V3";
  13987. + regulator-min-microvolt = <3300000>;
  13988. + regulator-max-microvolt = <3300000>;
  13989. + regulator-always-on;
  13990. + };
  13991. +
  13992. + v2m_clk24mhz: clk24mhz {
  13993. + compatible = "fixed-clock";
  13994. + #clock-cells = <0>;
  13995. + clock-frequency = <24000000>;
  13996. + clock-output-names = "v2m:clk24mhz";
  13997. + };
  13998. +
  13999. + v2m_refclk1mhz: refclk1mhz {
  14000. + compatible = "fixed-clock";
  14001. + #clock-cells = <0>;
  14002. + clock-frequency = <1000000>;
  14003. + clock-output-names = "v2m:refclk1mhz";
  14004. + };
  14005. +
  14006. + v2m_refclk32khz: refclk32khz {
  14007. + compatible = "fixed-clock";
  14008. + #clock-cells = <0>;
  14009. + clock-frequency = <32768>;
  14010. + clock-output-names = "v2m:refclk32khz";
  14011. + };
  14012. +
  14013. + mcc {
  14014. + compatible = "simple-bus";
  14015. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  14016. +
  14017. + v2m_oscclk1: osc@1 {
  14018. + /* CLCD clock */
  14019. + compatible = "arm,vexpress-osc";
  14020. + arm,vexpress-sysreg,func = <1 1>;
  14021. + freq-range = <23750000 63500000>;
  14022. + #clock-cells = <0>;
  14023. + clock-output-names = "v2m:oscclk1";
  14024. + };
  14025. +
  14026. + muxfpga@0 {
  14027. + compatible = "arm,vexpress-muxfpga";
  14028. + arm,vexpress-sysreg,func = <7 0>;
  14029. + };
  14030. +
  14031. + shutdown@0 {
  14032. + compatible = "arm,vexpress-shutdown";
  14033. + arm,vexpress-sysreg,func = <8 0>;
  14034. + };
  14035. + };
  14036. + };
  14037. diff -Nur linux-3.14.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts
  14038. --- linux-3.14.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts 1969-12-31 18:00:00.000000000 -0600
  14039. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts 2014-12-08 00:31:51.136418001 -0600
  14040. @@ -0,0 +1,233 @@
  14041. +/*
  14042. + * ARM Ltd. Fast Models
  14043. + *
  14044. + * Versatile Express (VE) system model
  14045. + * ARMCortexA15x4CT
  14046. + * ARMCortexA7x4CT
  14047. + * RTSM_VE_Cortex_A15x1_A7x1.lisa
  14048. + */
  14049. +
  14050. +/dts-v1/;
  14051. +
  14052. +/memreserve/ 0xff000000 0x01000000;
  14053. +
  14054. +/ {
  14055. + model = "RTSM_VE_CortexA15x1-A7x1";
  14056. + arm,vexpress,site = <0xf>;
  14057. + compatible = "arm,rtsm_ve,cortex_a15x1_a7x1", "arm,vexpress";
  14058. + interrupt-parent = <&gic>;
  14059. + #address-cells = <2>;
  14060. + #size-cells = <2>;
  14061. +
  14062. + chosen { };
  14063. +
  14064. + aliases {
  14065. + serial0 = &v2m_serial0;
  14066. + serial1 = &v2m_serial1;
  14067. + serial2 = &v2m_serial2;
  14068. + serial3 = &v2m_serial3;
  14069. + };
  14070. +
  14071. + clusters {
  14072. + #address-cells = <1>;
  14073. + #size-cells = <0>;
  14074. +
  14075. + cluster0: cluster@0 {
  14076. + reg = <0>;
  14077. +// freqs = <500000000 600000000 700000000 800000000 900000000 1000000000 1100000000 1200000000>;
  14078. + cores {
  14079. + #address-cells = <1>;
  14080. + #size-cells = <0>;
  14081. +
  14082. + core0: core@0 {
  14083. + reg = <0>;
  14084. + };
  14085. +
  14086. + };
  14087. + };
  14088. +
  14089. + cluster1: cluster@1 {
  14090. + reg = <1>;
  14091. +// freqs = <350000000 400000000 500000000 600000000 700000000 800000000 900000000 1000000000>;
  14092. + cores {
  14093. + #address-cells = <1>;
  14094. + #size-cells = <0>;
  14095. +
  14096. + core1: core@0 {
  14097. + reg = <0>;
  14098. + };
  14099. +
  14100. + };
  14101. + };
  14102. + };
  14103. +
  14104. + cpus {
  14105. + #address-cells = <1>;
  14106. + #size-cells = <0>;
  14107. +
  14108. + cpu0: cpu@0 {
  14109. + device_type = "cpu";
  14110. + compatible = "arm,cortex-a15";
  14111. + reg = <0>;
  14112. + cluster = <&cluster0>;
  14113. + core = <&core0>;
  14114. +// clock-frequency = <1000000000>;
  14115. + cci-control-port = <&cci_control1>;
  14116. + };
  14117. +
  14118. + cpu1: cpu@1 {
  14119. + device_type = "cpu";
  14120. + compatible = "arm,cortex-a7";
  14121. + reg = <0x100>;
  14122. + cluster = <&cluster1>;
  14123. + core = <&core1>;
  14124. +// clock-frequency = <800000000>;
  14125. + cci-control-port = <&cci_control2>;
  14126. + };
  14127. + };
  14128. +
  14129. + memory@80000000 {
  14130. + device_type = "memory";
  14131. + reg = <0 0x80000000 0 0x80000000>;
  14132. + };
  14133. +
  14134. + cci@2c090000 {
  14135. + compatible = "arm,cci-400", "arm,cci";
  14136. + #address-cells = <1>;
  14137. + #size-cells = <1>;
  14138. + reg = <0 0x2c090000 0 0x1000>;
  14139. + ranges = <0x0 0x0 0x2c090000 0x10000>;
  14140. +
  14141. + cci_control1: slave-if@4000 {
  14142. + compatible = "arm,cci-400-ctrl-if";
  14143. + interface-type = "ace";
  14144. + reg = <0x4000 0x1000>;
  14145. + };
  14146. +
  14147. + cci_control2: slave-if@5000 {
  14148. + compatible = "arm,cci-400-ctrl-if";
  14149. + interface-type = "ace";
  14150. + reg = <0x5000 0x1000>;
  14151. + };
  14152. + };
  14153. +
  14154. + dcscb@60000000 {
  14155. + compatible = "arm,rtsm,dcscb";
  14156. + reg = <0 0x60000000 0 0x1000>;
  14157. + };
  14158. +
  14159. + gic: interrupt-controller@2c001000 {
  14160. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  14161. + #interrupt-cells = <3>;
  14162. + #address-cells = <0>;
  14163. + interrupt-controller;
  14164. + reg = <0 0x2c001000 0 0x1000>,
  14165. + <0 0x2c002000 0 0x1000>,
  14166. + <0 0x2c004000 0 0x2000>,
  14167. + <0 0x2c006000 0 0x2000>;
  14168. + interrupts = <1 9 0xf04>;
  14169. + };
  14170. +
  14171. + timer {
  14172. + compatible = "arm,armv7-timer";
  14173. + interrupts = <1 13 0xf08>,
  14174. + <1 14 0xf08>,
  14175. + <1 11 0xf08>,
  14176. + <1 10 0xf08>;
  14177. + };
  14178. +
  14179. + dcc {
  14180. + compatible = "arm,vexpress,config-bus";
  14181. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  14182. +
  14183. + osc@0 {
  14184. + /* ACLK clock to the AXI master port on the test chip */
  14185. + compatible = "arm,vexpress-osc";
  14186. + arm,vexpress-sysreg,func = <1 0>;
  14187. + freq-range = <30000000 50000000>;
  14188. + #clock-cells = <0>;
  14189. + clock-output-names = "extsaxiclk";
  14190. + };
  14191. +
  14192. + oscclk1: osc@1 {
  14193. + /* Reference clock for the CLCD */
  14194. + compatible = "arm,vexpress-osc";
  14195. + arm,vexpress-sysreg,func = <1 1>;
  14196. + freq-range = <10000000 80000000>;
  14197. + #clock-cells = <0>;
  14198. + clock-output-names = "clcdclk";
  14199. + };
  14200. +
  14201. + smbclk: oscclk2: osc@2 {
  14202. + /* Reference clock for the test chip internal PLLs */
  14203. + compatible = "arm,vexpress-osc";
  14204. + arm,vexpress-sysreg,func = <1 2>;
  14205. + freq-range = <33000000 100000000>;
  14206. + #clock-cells = <0>;
  14207. + clock-output-names = "tcrefclk";
  14208. + };
  14209. + };
  14210. +
  14211. + smb {
  14212. + compatible = "simple-bus";
  14213. +
  14214. + #address-cells = <2>;
  14215. + #size-cells = <1>;
  14216. + ranges = <0 0 0 0x08000000 0x04000000>,
  14217. + <1 0 0 0x14000000 0x04000000>,
  14218. + <2 0 0 0x18000000 0x04000000>,
  14219. + <3 0 0 0x1c000000 0x04000000>,
  14220. + <4 0 0 0x0c000000 0x04000000>,
  14221. + <5 0 0 0x10000000 0x04000000>;
  14222. +
  14223. + #interrupt-cells = <1>;
  14224. + interrupt-map-mask = <0 0 63>;
  14225. + interrupt-map = <0 0 0 &gic 0 0 4>,
  14226. + <0 0 1 &gic 0 1 4>,
  14227. + <0 0 2 &gic 0 2 4>,
  14228. + <0 0 3 &gic 0 3 4>,
  14229. + <0 0 4 &gic 0 4 4>,
  14230. + <0 0 5 &gic 0 5 4>,
  14231. + <0 0 6 &gic 0 6 4>,
  14232. + <0 0 7 &gic 0 7 4>,
  14233. + <0 0 8 &gic 0 8 4>,
  14234. + <0 0 9 &gic 0 9 4>,
  14235. + <0 0 10 &gic 0 10 4>,
  14236. + <0 0 11 &gic 0 11 4>,
  14237. + <0 0 12 &gic 0 12 4>,
  14238. + <0 0 13 &gic 0 13 4>,
  14239. + <0 0 14 &gic 0 14 4>,
  14240. + <0 0 15 &gic 0 15 4>,
  14241. + <0 0 16 &gic 0 16 4>,
  14242. + <0 0 17 &gic 0 17 4>,
  14243. + <0 0 18 &gic 0 18 4>,
  14244. + <0 0 19 &gic 0 19 4>,
  14245. + <0 0 20 &gic 0 20 4>,
  14246. + <0 0 21 &gic 0 21 4>,
  14247. + <0 0 22 &gic 0 22 4>,
  14248. + <0 0 23 &gic 0 23 4>,
  14249. + <0 0 24 &gic 0 24 4>,
  14250. + <0 0 25 &gic 0 25 4>,
  14251. + <0 0 26 &gic 0 26 4>,
  14252. + <0 0 27 &gic 0 27 4>,
  14253. + <0 0 28 &gic 0 28 4>,
  14254. + <0 0 29 &gic 0 29 4>,
  14255. + <0 0 30 &gic 0 30 4>,
  14256. + <0 0 31 &gic 0 31 4>,
  14257. + <0 0 32 &gic 0 32 4>,
  14258. + <0 0 33 &gic 0 33 4>,
  14259. + <0 0 34 &gic 0 34 4>,
  14260. + <0 0 35 &gic 0 35 4>,
  14261. + <0 0 36 &gic 0 36 4>,
  14262. + <0 0 37 &gic 0 37 4>,
  14263. + <0 0 38 &gic 0 38 4>,
  14264. + <0 0 39 &gic 0 39 4>,
  14265. + <0 0 40 &gic 0 40 4>,
  14266. + <0 0 41 &gic 0 41 4>,
  14267. + <0 0 42 &gic 0 42 4>;
  14268. +
  14269. + /include/ "rtsm_ve-motherboard.dtsi"
  14270. + };
  14271. +};
  14272. +
  14273. +/include/ "clcd-panels.dtsi"
  14274. diff -Nur linux-3.14.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts
  14275. --- linux-3.14.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts 1969-12-31 18:00:00.000000000 -0600
  14276. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts 2014-12-08 00:31:51.136418001 -0600
  14277. @@ -0,0 +1,317 @@
  14278. +/*
  14279. + * ARM Ltd. Fast Models
  14280. + *
  14281. + * Versatile Express (VE) system model
  14282. + * ARMCortexA15x4CT
  14283. + * ARMCortexA7x4CT
  14284. + * RTSM_VE_Cortex_A15x4_A7x4.lisa
  14285. + */
  14286. +
  14287. +/dts-v1/;
  14288. +
  14289. +/memreserve/ 0xff000000 0x01000000;
  14290. +
  14291. +/ {
  14292. + model = "RTSM_VE_CortexA15x4-A7x4";
  14293. + arm,vexpress,site = <0xf>;
  14294. + compatible = "arm,rtsm_ve,cortex_a15x4_a7x4", "arm,vexpress";
  14295. + interrupt-parent = <&gic>;
  14296. + #address-cells = <2>;
  14297. + #size-cells = <2>;
  14298. +
  14299. + chosen { };
  14300. +
  14301. + aliases {
  14302. + serial0 = &v2m_serial0;
  14303. + serial1 = &v2m_serial1;
  14304. + serial2 = &v2m_serial2;
  14305. + serial3 = &v2m_serial3;
  14306. + };
  14307. +
  14308. + clusters {
  14309. + #address-cells = <1>;
  14310. + #size-cells = <0>;
  14311. +
  14312. + cluster0: cluster@0 {
  14313. + reg = <0>;
  14314. +// freqs = <500000000 600000000 700000000 800000000 900000000 1000000000 1100000000 1200000000>;
  14315. + cores {
  14316. + #address-cells = <1>;
  14317. + #size-cells = <0>;
  14318. +
  14319. + core0: core@0 {
  14320. + reg = <0>;
  14321. + };
  14322. +
  14323. + core1: core@1 {
  14324. + reg = <1>;
  14325. + };
  14326. +
  14327. + core2: core@2 {
  14328. + reg = <2>;
  14329. + };
  14330. +
  14331. + core3: core@3 {
  14332. + reg = <3>;
  14333. + };
  14334. +
  14335. + };
  14336. + };
  14337. +
  14338. + cluster1: cluster@1 {
  14339. + reg = <1>;
  14340. +// freqs = <350000000 400000000 500000000 600000000 700000000 800000000 900000000 1000000000>;
  14341. + cores {
  14342. + #address-cells = <1>;
  14343. + #size-cells = <0>;
  14344. +
  14345. + core4: core@0 {
  14346. + reg = <0>;
  14347. + };
  14348. +
  14349. + core5: core@1 {
  14350. + reg = <1>;
  14351. + };
  14352. +
  14353. + core6: core@2 {
  14354. + reg = <2>;
  14355. + };
  14356. +
  14357. + core7: core@3 {
  14358. + reg = <3>;
  14359. + };
  14360. +
  14361. + };
  14362. + };
  14363. + };
  14364. +
  14365. + cpus {
  14366. + #address-cells = <1>;
  14367. + #size-cells = <0>;
  14368. +
  14369. + cpu0: cpu@0 {
  14370. + device_type = "cpu";
  14371. + compatible = "arm,cortex-a15";
  14372. + reg = <0>;
  14373. + cluster = <&cluster0>;
  14374. + core = <&core0>;
  14375. +// clock-frequency = <1000000000>;
  14376. + cci-control-port = <&cci_control1>;
  14377. + };
  14378. +
  14379. + cpu1: cpu@1 {
  14380. + device_type = "cpu";
  14381. + compatible = "arm,cortex-a15";
  14382. + reg = <1>;
  14383. + cluster = <&cluster0>;
  14384. + core = <&core1>;
  14385. +// clock-frequency = <1000000000>;
  14386. + cci-control-port = <&cci_control1>;
  14387. + };
  14388. +
  14389. + cpu2: cpu@2 {
  14390. + device_type = "cpu";
  14391. + compatible = "arm,cortex-a15";
  14392. + reg = <2>;
  14393. + cluster = <&cluster0>;
  14394. + core = <&core2>;
  14395. +// clock-frequency = <1000000000>;
  14396. + cci-control-port = <&cci_control1>;
  14397. + };
  14398. +
  14399. + cpu3: cpu@3 {
  14400. + device_type = "cpu";
  14401. + compatible = "arm,cortex-a15";
  14402. + reg = <3>;
  14403. + cluster = <&cluster0>;
  14404. + core = <&core3>;
  14405. +// clock-frequency = <1000000000>;
  14406. + cci-control-port = <&cci_control1>;
  14407. + };
  14408. +
  14409. + cpu4: cpu@4 {
  14410. + device_type = "cpu";
  14411. + compatible = "arm,cortex-a7";
  14412. + reg = <0x100>;
  14413. + cluster = <&cluster1>;
  14414. + core = <&core4>;
  14415. +// clock-frequency = <800000000>;
  14416. + cci-control-port = <&cci_control2>;
  14417. + };
  14418. +
  14419. + cpu5: cpu@5 {
  14420. + device_type = "cpu";
  14421. + compatible = "arm,cortex-a7";
  14422. + reg = <0x101>;
  14423. + cluster = <&cluster1>;
  14424. + core = <&core5>;
  14425. +// clock-frequency = <800000000>;
  14426. + cci-control-port = <&cci_control2>;
  14427. + };
  14428. +
  14429. + cpu6: cpu@6 {
  14430. + device_type = "cpu";
  14431. + compatible = "arm,cortex-a7";
  14432. + reg = <0x102>;
  14433. + cluster = <&cluster1>;
  14434. + core = <&core6>;
  14435. +// clock-frequency = <800000000>;
  14436. + cci-control-port = <&cci_control2>;
  14437. + };
  14438. +
  14439. + cpu7: cpu@7 {
  14440. + device_type = "cpu";
  14441. + compatible = "arm,cortex-a7";
  14442. + reg = <0x103>;
  14443. + cluster = <&cluster1>;
  14444. + core = <&core7>;
  14445. +// clock-frequency = <800000000>;
  14446. + cci-control-port = <&cci_control2>;
  14447. + };
  14448. + };
  14449. +
  14450. + memory@80000000 {
  14451. + device_type = "memory";
  14452. + reg = <0 0x80000000 0 0x80000000>;
  14453. + };
  14454. +
  14455. + cci@2c090000 {
  14456. + compatible = "arm,cci-400", "arm,cci";
  14457. + #address-cells = <1>;
  14458. + #size-cells = <1>;
  14459. + reg = <0 0x2c090000 0 0x1000>;
  14460. + ranges = <0x0 0x0 0x2c090000 0x10000>;
  14461. +
  14462. + cci_control1: slave-if@4000 {
  14463. + compatible = "arm,cci-400-ctrl-if";
  14464. + interface-type = "ace";
  14465. + reg = <0x4000 0x1000>;
  14466. + };
  14467. +
  14468. + cci_control2: slave-if@5000 {
  14469. + compatible = "arm,cci-400-ctrl-if";
  14470. + interface-type = "ace";
  14471. + reg = <0x5000 0x1000>;
  14472. + };
  14473. + };
  14474. +
  14475. + dcscb@60000000 {
  14476. + compatible = "arm,rtsm,dcscb";
  14477. + reg = <0 0x60000000 0 0x1000>;
  14478. + };
  14479. +
  14480. + gic: interrupt-controller@2c001000 {
  14481. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  14482. + #interrupt-cells = <3>;
  14483. + #address-cells = <0>;
  14484. + interrupt-controller;
  14485. + reg = <0 0x2c001000 0 0x1000>,
  14486. + <0 0x2c002000 0 0x1000>,
  14487. + <0 0x2c004000 0 0x2000>,
  14488. + <0 0x2c006000 0 0x2000>;
  14489. + interrupts = <1 9 0xf04>;
  14490. + };
  14491. +
  14492. + timer {
  14493. + compatible = "arm,armv7-timer";
  14494. + interrupts = <1 13 0xf08>,
  14495. + <1 14 0xf08>,
  14496. + <1 11 0xf08>,
  14497. + <1 10 0xf08>;
  14498. + };
  14499. +
  14500. + dcc {
  14501. + compatible = "arm,vexpress,config-bus";
  14502. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  14503. +
  14504. + osc@0 {
  14505. + /* ACLK clock to the AXI master port on the test chip */
  14506. + compatible = "arm,vexpress-osc";
  14507. + arm,vexpress-sysreg,func = <1 0>;
  14508. + freq-range = <30000000 50000000>;
  14509. + #clock-cells = <0>;
  14510. + clock-output-names = "extsaxiclk";
  14511. + };
  14512. +
  14513. + oscclk1: osc@1 {
  14514. + /* Reference clock for the CLCD */
  14515. + compatible = "arm,vexpress-osc";
  14516. + arm,vexpress-sysreg,func = <1 1>;
  14517. + freq-range = <10000000 80000000>;
  14518. + #clock-cells = <0>;
  14519. + clock-output-names = "clcdclk";
  14520. + };
  14521. +
  14522. + smbclk: oscclk2: osc@2 {
  14523. + /* Reference clock for the test chip internal PLLs */
  14524. + compatible = "arm,vexpress-osc";
  14525. + arm,vexpress-sysreg,func = <1 2>;
  14526. + freq-range = <33000000 100000000>;
  14527. + #clock-cells = <0>;
  14528. + clock-output-names = "tcrefclk";
  14529. + };
  14530. + };
  14531. +
  14532. + smb {
  14533. + compatible = "simple-bus";
  14534. +
  14535. + #address-cells = <2>;
  14536. + #size-cells = <1>;
  14537. + ranges = <0 0 0 0x08000000 0x04000000>,
  14538. + <1 0 0 0x14000000 0x04000000>,
  14539. + <2 0 0 0x18000000 0x04000000>,
  14540. + <3 0 0 0x1c000000 0x04000000>,
  14541. + <4 0 0 0x0c000000 0x04000000>,
  14542. + <5 0 0 0x10000000 0x04000000>;
  14543. +
  14544. + #interrupt-cells = <1>;
  14545. + interrupt-map-mask = <0 0 63>;
  14546. + interrupt-map = <0 0 0 &gic 0 0 4>,
  14547. + <0 0 1 &gic 0 1 4>,
  14548. + <0 0 2 &gic 0 2 4>,
  14549. + <0 0 3 &gic 0 3 4>,
  14550. + <0 0 4 &gic 0 4 4>,
  14551. + <0 0 5 &gic 0 5 4>,
  14552. + <0 0 6 &gic 0 6 4>,
  14553. + <0 0 7 &gic 0 7 4>,
  14554. + <0 0 8 &gic 0 8 4>,
  14555. + <0 0 9 &gic 0 9 4>,
  14556. + <0 0 10 &gic 0 10 4>,
  14557. + <0 0 11 &gic 0 11 4>,
  14558. + <0 0 12 &gic 0 12 4>,
  14559. + <0 0 13 &gic 0 13 4>,
  14560. + <0 0 14 &gic 0 14 4>,
  14561. + <0 0 15 &gic 0 15 4>,
  14562. + <0 0 16 &gic 0 16 4>,
  14563. + <0 0 17 &gic 0 17 4>,
  14564. + <0 0 18 &gic 0 18 4>,
  14565. + <0 0 19 &gic 0 19 4>,
  14566. + <0 0 20 &gic 0 20 4>,
  14567. + <0 0 21 &gic 0 21 4>,
  14568. + <0 0 22 &gic 0 22 4>,
  14569. + <0 0 23 &gic 0 23 4>,
  14570. + <0 0 24 &gic 0 24 4>,
  14571. + <0 0 25 &gic 0 25 4>,
  14572. + <0 0 26 &gic 0 26 4>,
  14573. + <0 0 27 &gic 0 27 4>,
  14574. + <0 0 28 &gic 0 28 4>,
  14575. + <0 0 29 &gic 0 29 4>,
  14576. + <0 0 30 &gic 0 30 4>,
  14577. + <0 0 31 &gic 0 31 4>,
  14578. + <0 0 32 &gic 0 32 4>,
  14579. + <0 0 33 &gic 0 33 4>,
  14580. + <0 0 34 &gic 0 34 4>,
  14581. + <0 0 35 &gic 0 35 4>,
  14582. + <0 0 36 &gic 0 36 4>,
  14583. + <0 0 37 &gic 0 37 4>,
  14584. + <0 0 38 &gic 0 38 4>,
  14585. + <0 0 39 &gic 0 39 4>,
  14586. + <0 0 40 &gic 0 40 4>,
  14587. + <0 0 41 &gic 0 41 4>,
  14588. + <0 0 42 &gic 0 42 4>;
  14589. +
  14590. + /include/ "rtsm_ve-motherboard.dtsi"
  14591. + };
  14592. +};
  14593. +
  14594. +/include/ "clcd-panels.dtsi"
  14595. diff -Nur linux-3.14.14/arch/arm/boot/dts/vexpress-v2m.dtsi linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2m.dtsi
  14596. --- linux-3.14.14/arch/arm/boot/dts/vexpress-v2m.dtsi 2014-07-28 10:07:25.000000000 -0500
  14597. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2m.dtsi 2014-12-08 00:31:51.144418001 -0600
  14598. @@ -227,6 +227,7 @@
  14599. };
  14600. clcd@1f000 {
  14601. + status = "disabled";
  14602. compatible = "arm,pl111", "arm,primecell";
  14603. reg = <0x1f000 0x1000>;
  14604. interrupts = <14>;
  14605. diff -Nur linux-3.14.14/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
  14606. --- linux-3.14.14/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi 2014-07-28 10:07:25.000000000 -0500
  14607. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi 2014-12-08 00:31:51.144418001 -0600
  14608. @@ -228,6 +228,7 @@
  14609. };
  14610. clcd@1f0000 {
  14611. + status = "disabled";
  14612. compatible = "arm,pl111", "arm,primecell";
  14613. reg = <0x1f0000 0x1000>;
  14614. interrupts = <14>;
  14615. diff -Nur linux-3.14.14/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
  14616. --- linux-3.14.14/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts 2014-07-28 10:07:25.000000000 -0500
  14617. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts 2014-12-08 00:31:51.144418001 -0600
  14618. @@ -9,6 +9,8 @@
  14619. /dts-v1/;
  14620. +/memreserve/ 0xff000000 0x01000000;
  14621. +
  14622. / {
  14623. model = "V2P-CA15_CA7";
  14624. arm,hbi = <0x249>;
  14625. @@ -29,29 +31,60 @@
  14626. i2c1 = &v2m_i2c_pcie;
  14627. };
  14628. - cpus {
  14629. + clusters {
  14630. #address-cells = <1>;
  14631. #size-cells = <0>;
  14632. - cpu0: cpu@0 {
  14633. - device_type = "cpu";
  14634. - compatible = "arm,cortex-a15";
  14635. + cluster0: cluster@0 {
  14636. reg = <0>;
  14637. - cci-control-port = <&cci_control1>;
  14638. + cores {
  14639. + #address-cells = <1>;
  14640. + #size-cells = <0>;
  14641. +
  14642. + core0: core@0 {
  14643. + reg = <0>;
  14644. + };
  14645. +
  14646. + core1: core@1 {
  14647. + reg = <1>;
  14648. + };
  14649. +
  14650. + };
  14651. };
  14652. - cpu1: cpu@1 {
  14653. - device_type = "cpu";
  14654. - compatible = "arm,cortex-a15";
  14655. + cluster1: cluster@1 {
  14656. reg = <1>;
  14657. - cci-control-port = <&cci_control1>;
  14658. + cores {
  14659. + #address-cells = <1>;
  14660. + #size-cells = <0>;
  14661. +
  14662. + core2: core@0 {
  14663. + reg = <0>;
  14664. + };
  14665. +
  14666. + core3: core@1 {
  14667. + reg = <1>;
  14668. + };
  14669. +
  14670. + core4: core@2 {
  14671. + reg = <2>;
  14672. + };
  14673. + };
  14674. };
  14675. + };
  14676. +
  14677. + cpus {
  14678. + #address-cells = <1>;
  14679. + #size-cells = <0>;
  14680. cpu2: cpu@2 {
  14681. device_type = "cpu";
  14682. compatible = "arm,cortex-a7";
  14683. reg = <0x100>;
  14684. cci-control-port = <&cci_control2>;
  14685. + cluster = <&cluster1>;
  14686. + core = <&core2>;
  14687. + clock-frequency = <800000000>;
  14688. };
  14689. cpu3: cpu@3 {
  14690. @@ -59,6 +92,9 @@
  14691. compatible = "arm,cortex-a7";
  14692. reg = <0x101>;
  14693. cci-control-port = <&cci_control2>;
  14694. + cluster = <&cluster1>;
  14695. + core = <&core3>;
  14696. + clock-frequency = <800000000>;
  14697. };
  14698. cpu4: cpu@4 {
  14699. @@ -66,12 +102,35 @@
  14700. compatible = "arm,cortex-a7";
  14701. reg = <0x102>;
  14702. cci-control-port = <&cci_control2>;
  14703. + cluster = <&cluster1>;
  14704. + core = <&core4>;
  14705. + clock-frequency = <800000000>;
  14706. + };
  14707. +
  14708. + cpu0: cpu@0 {
  14709. + device_type = "cpu";
  14710. + compatible = "arm,cortex-a15";
  14711. + reg = <0>;
  14712. + cci-control-port = <&cci_control1>;
  14713. + cluster = <&cluster0>;
  14714. + core = <&core0>;
  14715. + clock-frequency = <1000000000>;
  14716. + };
  14717. +
  14718. + cpu1: cpu@1 {
  14719. + device_type = "cpu";
  14720. + compatible = "arm,cortex-a15";
  14721. + reg = <1>;
  14722. + cci-control-port = <&cci_control1>;
  14723. + cluster = <&cluster0>;
  14724. + core = <&core1>;
  14725. + clock-frequency = <1000000000>;
  14726. };
  14727. };
  14728. memory@80000000 {
  14729. device_type = "memory";
  14730. - reg = <0 0x80000000 0 0x40000000>;
  14731. + reg = <0 0x80000000 0 0x80000000>;
  14732. };
  14733. wdt@2a490000 {
  14734. @@ -86,6 +145,8 @@
  14735. compatible = "arm,hdlcd";
  14736. reg = <0 0x2b000000 0 0x1000>;
  14737. interrupts = <0 85 4>;
  14738. + mode = "1024x768-16@60";
  14739. + framebuffer = <0 0xff000000 0 0x01000000>;
  14740. clocks = <&oscclk5>;
  14741. clock-names = "pxlclk";
  14742. };
  14743. @@ -127,6 +188,16 @@
  14744. interface-type = "ace";
  14745. reg = <0x5000 0x1000>;
  14746. };
  14747. +
  14748. + pmu@9000 {
  14749. + compatible = "arm,cci-400-pmu";
  14750. + reg = <0x9000 0x5000>;
  14751. + interrupts = <0 101 4>,
  14752. + <0 102 4>,
  14753. + <0 103 4>,
  14754. + <0 104 4>,
  14755. + <0 105 4>;
  14756. + };
  14757. };
  14758. memory-controller@7ffd0000 {
  14759. @@ -164,12 +235,21 @@
  14760. <1 10 0xf08>;
  14761. };
  14762. - pmu {
  14763. + pmu_a15 {
  14764. compatible = "arm,cortex-a15-pmu";
  14765. + cluster = <&cluster0>;
  14766. interrupts = <0 68 4>,
  14767. <0 69 4>;
  14768. };
  14769. + pmu_a7 {
  14770. + compatible = "arm,cortex-a7-pmu";
  14771. + cluster = <&cluster1>;
  14772. + interrupts = <0 128 4>,
  14773. + <0 129 4>,
  14774. + <0 130 4>;
  14775. + };
  14776. +
  14777. oscclk6a: oscclk6a {
  14778. /* Reference 24MHz clock */
  14779. compatible = "fixed-clock";
  14780. @@ -178,6 +258,19 @@
  14781. clock-output-names = "oscclk6a";
  14782. };
  14783. +/* PSCI requires support from firmware and is not present in the normal TC2
  14784. + * distribution, so this node is commented out by default...
  14785. +
  14786. + psci {
  14787. + compatible = "arm,psci";
  14788. + method = "smc";
  14789. + cpu_suspend = <0x80100001>;
  14790. + cpu_off = <0x80100002>;
  14791. + cpu_on = <0x80100003>;
  14792. + migrate = <0x80100004>;
  14793. + };
  14794. +*/
  14795. +
  14796. dcc {
  14797. compatible = "arm,vexpress,config-bus";
  14798. arm,vexpress,config-bridge = <&v2m_sysreg>;
  14799. diff -Nur linux-3.14.14/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
  14800. --- linux-3.14.14/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts 2014-07-28 10:07:25.000000000 -0500
  14801. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts 2014-12-08 00:31:51.144418001 -0600
  14802. @@ -9,6 +9,8 @@
  14803. /dts-v1/;
  14804. +/memreserve/ 0xbf000000 0x01000000;
  14805. +
  14806. / {
  14807. model = "V2P-CA15";
  14808. arm,hbi = <0x237>;
  14809. @@ -57,6 +59,8 @@
  14810. interrupts = <0 85 4>;
  14811. clocks = <&oscclk5>;
  14812. clock-names = "pxlclk";
  14813. + mode = "1024x768-16@60";
  14814. + framebuffer = <0 0xbf000000 0 0x01000000>;
  14815. };
  14816. memory-controller@2b0a0000 {
  14817. diff -Nur linux-3.14.14/arch/arm/boot/dts/vexpress-v2p-ca5s.dts linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
  14818. --- linux-3.14.14/arch/arm/boot/dts/vexpress-v2p-ca5s.dts 2014-07-28 10:07:25.000000000 -0500
  14819. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca5s.dts 2014-12-08 00:31:51.144418001 -0600
  14820. @@ -9,6 +9,8 @@
  14821. /dts-v1/;
  14822. +/memreserve/ 0xbf000000 0x01000000;
  14823. +
  14824. / {
  14825. model = "V2P-CA5s";
  14826. arm,hbi = <0x225>;
  14827. @@ -59,6 +61,8 @@
  14828. interrupts = <0 85 4>;
  14829. clocks = <&oscclk3>;
  14830. clock-names = "pxlclk";
  14831. + mode = "640x480-16@60";
  14832. + framebuffer = <0xbf000000 0x01000000>;
  14833. };
  14834. memory-controller@2a150000 {
  14835. diff -Nur linux-3.14.14/arch/arm/boot/dts/vexpress-v2p-ca9.dts linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca9.dts
  14836. --- linux-3.14.14/arch/arm/boot/dts/vexpress-v2p-ca9.dts 2014-07-28 10:07:25.000000000 -0500
  14837. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca9.dts 2014-12-08 00:31:51.144418001 -0600
  14838. @@ -9,6 +9,8 @@
  14839. /dts-v1/;
  14840. +/include/ "clcd-panels.dtsi"
  14841. +
  14842. / {
  14843. model = "V2P-CA9";
  14844. arm,hbi = <0x191>;
  14845. @@ -73,6 +75,8 @@
  14846. interrupts = <0 44 4>;
  14847. clocks = <&oscclk1>, <&oscclk2>;
  14848. clock-names = "clcdclk", "apb_pclk";
  14849. + mode = "XVGA";
  14850. + use_dma = <1>;
  14851. };
  14852. memory-controller@100e0000 {
  14853. diff -Nur linux-3.14.14/arch/arm/boot/dts/vf610.dtsi linux-imx6-3.14/arch/arm/boot/dts/vf610.dtsi
  14854. --- linux-3.14.14/arch/arm/boot/dts/vf610.dtsi 2014-07-28 10:07:25.000000000 -0500
  14855. +++ linux-imx6-3.14/arch/arm/boot/dts/vf610.dtsi 2014-12-08 00:31:51.144418001 -0600
  14856. @@ -44,11 +44,13 @@
  14857. sxosc {
  14858. compatible = "fixed-clock";
  14859. + #clock-cells = <0>;
  14860. clock-frequency = <32768>;
  14861. };
  14862. fxosc {
  14863. compatible = "fixed-clock";
  14864. + #clock-cells = <0>;
  14865. clock-frequency = <24000000>;
  14866. };
  14867. };
  14868. diff -Nur linux-3.14.14/arch/arm/boot/dts/vf610-twr.dts linux-imx6-3.14/arch/arm/boot/dts/vf610-twr.dts
  14869. --- linux-3.14.14/arch/arm/boot/dts/vf610-twr.dts 2014-07-28 10:07:25.000000000 -0500
  14870. +++ linux-imx6-3.14/arch/arm/boot/dts/vf610-twr.dts 2014-12-08 00:31:51.144418001 -0600
  14871. @@ -25,11 +25,13 @@
  14872. clocks {
  14873. audio_ext {
  14874. compatible = "fixed-clock";
  14875. + #clock-cells = <0>;
  14876. clock-frequency = <24576000>;
  14877. };
  14878. enet_ext {
  14879. compatible = "fixed-clock";
  14880. + #clock-cells = <0>;
  14881. clock-frequency = <50000000>;
  14882. };
  14883. };
  14884. diff -Nur linux-3.14.14/arch/arm/common/Makefile linux-imx6-3.14/arch/arm/common/Makefile
  14885. --- linux-3.14.14/arch/arm/common/Makefile 2014-07-28 10:07:25.000000000 -0500
  14886. +++ linux-imx6-3.14/arch/arm/common/Makefile 2014-12-08 00:31:51.148418001 -0600
  14887. @@ -13,6 +13,7 @@
  14888. obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
  14889. obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
  14890. obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o
  14891. +CFLAGS_REMOVE_mcpm_entry.o = -pg
  14892. AFLAGS_mcpm_head.o := -march=armv7-a
  14893. AFLAGS_vlock.o := -march=armv7-a
  14894. obj-$(CONFIG_TI_PRIV_EDMA) += edma.o
  14895. diff -Nur linux-3.14.14/arch/arm/configs/imx_v6_v7_defconfig linux-imx6-3.14/arch/arm/configs/imx_v6_v7_defconfig
  14896. --- linux-3.14.14/arch/arm/configs/imx_v6_v7_defconfig 2014-07-28 10:07:25.000000000 -0500
  14897. +++ linux-imx6-3.14/arch/arm/configs/imx_v6_v7_defconfig 2014-12-08 00:31:51.156418001 -0600
  14898. @@ -45,6 +45,9 @@
  14899. CONFIG_AEABI=y
  14900. CONFIG_HIGHMEM=y
  14901. CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  14902. +CONFIG_CPU_FREQ=y
  14903. +CONFIG_ARM_IMX6Q_CPUFREQ=y
  14904. +CONFIG_CPU_IDLE=y
  14905. CONFIG_VFP=y
  14906. CONFIG_NEON=y
  14907. CONFIG_BINFMT_MISC=m
  14908. @@ -70,6 +73,8 @@
  14909. CONFIG_DEVTMPFS=y
  14910. CONFIG_DEVTMPFS_MOUNT=y
  14911. # CONFIG_STANDALONE is not set
  14912. +CONFIG_CMA=y
  14913. +CONFIG_CMA_SIZE_MBYTES=256
  14914. CONFIG_IMX_WEIM=y
  14915. CONFIG_CONNECTOR=y
  14916. CONFIG_MTD=y
  14917. @@ -154,7 +159,12 @@
  14918. CONFIG_SPI_IMX=y
  14919. CONFIG_GPIO_SYSFS=y
  14920. CONFIG_GPIO_MC9S08DZ60=y
  14921. +CONFIG_GPIO_PCA953X=y
  14922. # CONFIG_HWMON is not set
  14923. +CONFIG_THERMAL=y
  14924. +CONFIG_CPU_THERMAL=y
  14925. +CONFIG_IMX_THERMAL=y
  14926. +CONFIG_DEVICE_THERMAL=y
  14927. CONFIG_WATCHDOG=y
  14928. CONFIG_IMX2_WDT=y
  14929. CONFIG_MFD_DA9052_I2C=y
  14930. @@ -170,32 +180,44 @@
  14931. CONFIG_REGULATOR_PFUZE100=y
  14932. CONFIG_MEDIA_SUPPORT=y
  14933. CONFIG_MEDIA_CAMERA_SUPPORT=y
  14934. +CONFIG_MEDIA_USB_SUPPORT=y
  14935. +CONFIG_USB_VIDEO_CLASS=m
  14936. CONFIG_MEDIA_RC_SUPPORT=y
  14937. CONFIG_RC_DEVICES=y
  14938. CONFIG_IR_GPIO_CIR=y
  14939. CONFIG_V4L_PLATFORM_DRIVERS=y
  14940. +CONFIG_VIDEO_MXC_OUTPUT=y
  14941. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  14942. CONFIG_SOC_CAMERA=y
  14943. CONFIG_VIDEO_MX3=y
  14944. CONFIG_V4L_MEM2MEM_DRIVERS=y
  14945. CONFIG_VIDEO_CODA=y
  14946. CONFIG_SOC_CAMERA_OV2640=y
  14947. CONFIG_DRM=y
  14948. +CONFIG_DRM_VIVANTE=y
  14949. CONFIG_BACKLIGHT_LCD_SUPPORT=y
  14950. CONFIG_LCD_CLASS_DEVICE=y
  14951. CONFIG_LCD_L4F00242T03=y
  14952. CONFIG_LCD_PLATFORM=y
  14953. CONFIG_BACKLIGHT_CLASS_DEVICE=y
  14954. CONFIG_BACKLIGHT_PWM=y
  14955. +CONFIG_FB_MXC_SYNC_PANEL=y
  14956. +CONFIG_FB_MXC_LDB=y
  14957. +CONFIG_FB_MXC_HDMI=y
  14958. +CONFIG_FB_MXC_MIPI_DSI=y
  14959. +CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
  14960. CONFIG_FRAMEBUFFER_CONSOLE=y
  14961. CONFIG_LOGO=y
  14962. CONFIG_SOUND=y
  14963. CONFIG_SND=y
  14964. +CONFIG_SND_USB_AUDIO=m
  14965. CONFIG_SND_SOC=y
  14966. CONFIG_SND_IMX_SOC=y
  14967. CONFIG_SND_SOC_PHYCORE_AC97=y
  14968. CONFIG_SND_SOC_EUKREA_TLV320=y
  14969. CONFIG_SND_SOC_IMX_WM8962=y
  14970. CONFIG_SND_SOC_IMX_SGTL5000=y
  14971. +CONFIG_SND_SOC_IMX_CS42888=y
  14972. CONFIG_SND_SOC_IMX_SPDIF=y
  14973. CONFIG_SND_SOC_IMX_MC13783=y
  14974. CONFIG_USB=y
  14975. @@ -208,12 +230,18 @@
  14976. CONFIG_NOP_USB_XCEIV=y
  14977. CONFIG_USB_MXS_PHY=y
  14978. CONFIG_USB_GADGET=y
  14979. +CONFIG_USB_ZERO=m
  14980. CONFIG_USB_ETH=m
  14981. CONFIG_USB_MASS_STORAGE=m
  14982. +CONFIG_USB_G_SERIAL=m
  14983. CONFIG_MMC=y
  14984. +CONFIG_MMC_UNSAFE_RESUME=y
  14985. CONFIG_MMC_SDHCI=y
  14986. CONFIG_MMC_SDHCI_PLTFM=y
  14987. CONFIG_MMC_SDHCI_ESDHC_IMX=y
  14988. +CONFIG_MXC_IPU=y
  14989. +CONFIG_MXC_GPU_VIV=y
  14990. +CONFIG_MXC_ASRC=y
  14991. CONFIG_NEW_LEDS=y
  14992. CONFIG_LEDS_CLASS=y
  14993. CONFIG_LEDS_GPIO=y
  14994. @@ -229,16 +257,10 @@
  14995. CONFIG_RTC_DRV_MXC=y
  14996. CONFIG_RTC_DRV_SNVS=y
  14997. CONFIG_DMADEVICES=y
  14998. +CONFIG_MXC_PXP_V2=y
  14999. CONFIG_IMX_SDMA=y
  15000. CONFIG_MXS_DMA=y
  15001. CONFIG_STAGING=y
  15002. -CONFIG_DRM_IMX=y
  15003. -CONFIG_DRM_IMX_FB_HELPER=y
  15004. -CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
  15005. -CONFIG_DRM_IMX_TVE=y
  15006. -CONFIG_DRM_IMX_LDB=y
  15007. -CONFIG_DRM_IMX_IPUV3_CORE=y
  15008. -CONFIG_DRM_IMX_IPUV3=y
  15009. CONFIG_COMMON_CLK_DEBUG=y
  15010. # CONFIG_IOMMU_SUPPORT is not set
  15011. CONFIG_PWM=y
  15012. diff -Nur linux-3.14.14/arch/arm/configs/imx_v7_cbi_hb_base_defconfig linux-imx6-3.14/arch/arm/configs/imx_v7_cbi_hb_base_defconfig
  15013. --- linux-3.14.14/arch/arm/configs/imx_v7_cbi_hb_base_defconfig 1969-12-31 18:00:00.000000000 -0600
  15014. +++ linux-imx6-3.14/arch/arm/configs/imx_v7_cbi_hb_base_defconfig 2014-12-08 00:31:51.156418001 -0600
  15015. @@ -0,0 +1,367 @@
  15016. +# CONFIG_LOCALVERSION_AUTO is not set
  15017. +CONFIG_KERNEL_LZO=y
  15018. +CONFIG_SYSVIPC=y
  15019. +CONFIG_FHANDLE=y
  15020. +CONFIG_NO_HZ=y
  15021. +CONFIG_HIGH_RES_TIMERS=y
  15022. +CONFIG_LOG_BUF_SHIFT=18
  15023. +CONFIG_CGROUPS=y
  15024. +CONFIG_RELAY=y
  15025. +CONFIG_BLK_DEV_INITRD=y
  15026. +CONFIG_EXPERT=y
  15027. +CONFIG_PERF_EVENTS=y
  15028. +CONFIG_CLEANCACHE=y
  15029. +CONFIG_FRONTSWAP=y
  15030. +CONFIG_ZSWAP=y
  15031. +CONFIG_ZSMALLOC=y
  15032. +# CONFIG_SLUB_DEBUG is not set
  15033. +# CONFIG_COMPAT_BRK is not set
  15034. +CONFIG_MODULES=y
  15035. +CONFIG_MODULE_UNLOAD=y
  15036. +CONFIG_MODVERSIONS=y
  15037. +CONFIG_MODULE_SRCVERSION_ALL=y
  15038. +# CONFIG_BLK_DEV_BSG is not set
  15039. +CONFIG_GPIO_PCA953X=y
  15040. +CONFIG_ARCH_MXC=y
  15041. +CONFIG_MXC_DEBUG_BOARD=y
  15042. +CONFIG_SOC_IMX6Q=y
  15043. +CONFIG_SOC_IMX6SL=y
  15044. +# CONFIG_SWP_EMULATE is not set
  15045. +CONFIG_PCI=y
  15046. +CONFIG_PCIE_DW=y
  15047. +CONFIG_PCI_IMX6=y
  15048. +CONFIG_SMP=y
  15049. +CONFIG_VMSPLIT_2G=y
  15050. +CONFIG_PREEMPT_VOLUNTARY=y
  15051. +CONFIG_AEABI=y
  15052. +# CONFIG_OABI_COMPAT is not set
  15053. +CONFIG_HIGHMEM=y
  15054. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  15055. +CONFIG_CPU_FREQ=y
  15056. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  15057. +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
  15058. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  15059. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  15060. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  15061. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  15062. +CONFIG_ARM_IMX6_CPUFREQ=y
  15063. +CONFIG_CPU_IDLE=y
  15064. +CONFIG_VFP=y
  15065. +CONFIG_VFPv3=y
  15066. +CONFIG_NEON=y
  15067. +CONFIG_KERNEL_MODE_NEON=y
  15068. +CONFIG_BINFMT_MISC=m
  15069. +CONFIG_PM_RUNTIME=y
  15070. +CONFIG_PM_DEBUG=y
  15071. +CONFIG_PM_TEST_SUSPEND=y
  15072. +CONFIG_IOSCHED_BFQ=y
  15073. +CONFIG_CGROUP_BFQIO=y
  15074. +CONFIG_DEFAULT_BFQ=y
  15075. +CONFIG_DEFAULT_IOSCHED="bfq"
  15076. +CONFIG_NET=y
  15077. +CONFIG_PACKET=y
  15078. +CONFIG_UNIX=y
  15079. +CONFIG_INET=y
  15080. +CONFIG_IP_PNP=y
  15081. +CONFIG_IP_PNP_DHCP=y
  15082. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  15083. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  15084. +# CONFIG_INET_XFRM_MODE_BEET is not set
  15085. +# CONFIG_INET_LRO is not set
  15086. +CONFIG_IPV6=y
  15087. +CONFIG_NETFILTER=y
  15088. +CONFIG_VLAN_8021Q=y
  15089. +CONFIG_WIRELESS=y
  15090. +CONFIG_WIRELESS_EXT=y
  15091. +CONFIG_WEXT_CORE=y
  15092. +CONFIG_WEXT_PROC=y
  15093. +CONFIG_WEXT_SPY=y
  15094. +CONFIG_WEXT_PRIV=y
  15095. +CONFIG_CFG80211=y
  15096. +CONFIG_ETHERNET=y
  15097. +# CONFIG_NET_VENDOR_BROADCOM is not set
  15098. +# CONFIG_NET_VENDOR_CIRRUS is not set
  15099. +# CONFIG_NET_VENDOR_FARADAY
  15100. +# CONFIG_NET_VENDOR_INTEL
  15101. +# CONFIG_NET_VENDOR_I825XX
  15102. +# CONFIG_NET_VENDOR_MARVELL
  15103. +# CONFIG_NET_VENDOR_MICROCHIP
  15104. +# CONFIG_NET_VENDOR_MICROCHIP=y
  15105. +# CONFIG_ENC28J60 is not set
  15106. +# CONFIG_NET_VENDOR_NATSEMI=y
  15107. +# CONFIG_NET_VENDOR_8390=y
  15108. +# CONFIG_AX88796 is not set
  15109. +# CONFIG_ETHOC is not set
  15110. +# CONFIG_SH_ETH is not set
  15111. +# CONFIG_NET_VENDOR_SEEQ=y
  15112. +# CONFIG_NET_VENDOR_SMSC=y
  15113. +# CONFIG_SMC91X is not set
  15114. +# CONFIG_SMC911X is not set
  15115. +# CONFIG_SMSC911X is not set
  15116. +# CONFIG_NET_VENDOR_STMICRO=y
  15117. +# CONFIG_STMMAC_ETH is not set
  15118. +# CONFIG_NET_VENDOR_VIA=y
  15119. +# CONFIG_VIA_VELOCITY is not set
  15120. +# CONFIG_NET_VENDOR_WIZNET=y
  15121. +CONFIG_NET_VENDOR_FREESCALE=y
  15122. +CONFIG_FEC=y
  15123. +CONFIG_PHYLIB=y
  15124. +CONFIG_AT803X_PHY=y
  15125. +CONFIG_WLAN=y
  15126. +CONFIG_BRCMUTIL=m
  15127. +CONFIG_BRCMFMAC=m
  15128. +CONFIG_BRCMFMAC_SDIO=y
  15129. +CONFIG_DEVTMPFS=y
  15130. +CONFIG_DEVTMPFS_MOUNT=y
  15131. +# CONFIG_STANDALONE is not set
  15132. +CONFIG_DMA_CMA=y
  15133. +CONFIG_CMA=y
  15134. +CONFIG_CMA_SIZE_MBYTES=256
  15135. +CONFIG_CONNECTOR=y
  15136. +# CONFIG_MTD is not set
  15137. +CONFIG_BLK_DEV_LOOP=y
  15138. +CONFIG_BLK_DEV_RAM=y
  15139. +CONFIG_BLK_DEV_RAM_SIZE=65536
  15140. +# CONFIG_SCSI_PROC_FS is not set
  15141. +CONFIG_BLK_DEV_SD=y
  15142. +CONFIG_SCSI_MULTI_LUN=y
  15143. +CONFIG_SCSI_CONSTANTS=y
  15144. +CONFIG_SCSI_LOGGING=y
  15145. +CONFIG_SCSI_SCAN_ASYNC=y
  15146. +# CONFIG_SCSI_LOWLEVEL is not set
  15147. +CONFIG_ATA=y
  15148. +CONFIG_SATA_AHCI_PLATFORM=y
  15149. +CONFIG_AHCI_IMX=y
  15150. +CONFIG_NETDEVICES=y
  15151. +CONFIG_INPUT_EVDEV=y
  15152. +# CONFIG_INPUT_EVBUG is not set
  15153. +CONFIG_KEYBOARD_GPIO=y
  15154. +CONFIG_KEYBOARD_IMX=y
  15155. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  15156. +# CONFIG_KEYBOARD_ATKBD is not set
  15157. +# CONFIG_MOUSE_PS2 is not set
  15158. +CONFIG_INPUT_MISC=y
  15159. +CONFIG_SERIO_SERPORT=m
  15160. +CONFIG_VT_HW_CONSOLE_BINDING=y
  15161. +# CONFIG_LEGACY_PTYS is not set
  15162. +# CONFIG_DEVKMEM is not set
  15163. +CONFIG_SERIAL_IMX=y
  15164. +CONFIG_SERIAL_IMX_CONSOLE=y
  15165. +CONFIG_SERIAL_FSL_LPUART=y
  15166. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  15167. +CONFIG_FSL_OTP=y
  15168. +CONFIG_GPIO_MXC=y
  15169. +# CONFIG_I2C_COMPAT is not set
  15170. +CONFIG_I2C_CHARDEV=y
  15171. +# CONFIG_I2C_HELPER_AUTO is not set
  15172. +CONFIG_I2C_ALGOPCF=m
  15173. +CONFIG_I2C_ALGOPCA=m
  15174. +CONFIG_I2C_IMX=y
  15175. +CONFIG_SPI=y
  15176. +CONFIG_SPI_IMX=y
  15177. +CONFIG_GPIO_SYSFS=y
  15178. +CONFIG_POWER_SUPPLY=y
  15179. +CONFIG_THERMAL=y
  15180. +CONFIG_CPU_THERMAL=y
  15181. +CONFIG_IMX_THERMAL=y
  15182. +CONFIG_DEVICE_THERMAL=y
  15183. +CONFIG_WATCHDOG=y
  15184. +CONFIG_IMX2_WDT=y
  15185. +CONFIG_MFD_DA9052_I2C=y
  15186. +CONFIG_MFD_MC13XXX_SPI=y
  15187. +CONFIG_MFD_MC13XXX_I2C=y
  15188. +CONFIG_MFD_SI476X_CORE=y
  15189. +CONFIG_REGULATOR=y
  15190. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  15191. +CONFIG_REGULATOR_ANATOP=y
  15192. +CONFIG_REGULATOR_PFUZE100=y
  15193. +CONFIG_MEDIA_SUPPORT=y
  15194. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  15195. +# CONFIG_MEDIA_RADIO_SUPPORT is not set
  15196. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  15197. +# CONFIG_MEDIA_USB_SUPPORT isnot set
  15198. +# CONFIG_USB_VIDEO_CLASS is not set
  15199. +# CONFIG_RADIO_ADAPTERS is not set
  15200. +CONFIG_V4L_PLATFORM_DRIVERS=y
  15201. +CONFIG_VIDEO_MXC_OUTPUT=y
  15202. +CONFIG_VIDEO_MXC_CAPTURE=m
  15203. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  15204. +CONFIG_MXC_CAMERA_OV5640=m
  15205. +CONFIG_MXC_CAMERA_OV5642=m
  15206. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  15207. +CONFIG_MXC_TVIN_ADV7180=m
  15208. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  15209. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  15210. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  15211. +CONFIG_SOC_CAMERA=y
  15212. +CONFIG_SOC_CAMERA_OV2640=y
  15213. +CONFIG_DRM=y
  15214. +CONFIG_DRM_VIVANTE=y
  15215. +CONFIG_FB=y
  15216. +# CONFIG_FB_MX3 is not set
  15217. +CONFIG_FB_MXC_SYNC_PANEL=y
  15218. +CONFIG_FB_MXC_LDB=y
  15219. +CONFIG_FB_MXC_HDMI=y
  15220. +CONFIG_FRAMEBUFFER_CONSOLE=y
  15221. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  15222. +CONFIG_FONTS=y
  15223. +CONFIG_FONT_8x8=y
  15224. +CONFIG_FONT_8x16=y
  15225. +CONFIG_LOGO=y
  15226. +CONFIG_SOUND=y
  15227. +CONFIG_SND=y
  15228. +CONFIG_SND_USB_AUDIO=m
  15229. +CONFIG_SND_SOC=y
  15230. +CONFIG_SND_IMX_SOC=y
  15231. +CONFIG_SND_SOC_IMX_SGTL5000=y
  15232. +CONFIG_SND_SOC_IMX_SPDIF=y
  15233. +CONFIG_SND_SOC_IMX_HDMI=y
  15234. +CONFIG_USB=y
  15235. +CONFIG_USB_EHCI_HCD=y
  15236. +CONFIG_USB_STORAGE=y
  15237. +CONFIG_USB_CHIPIDEA=y
  15238. +CONFIG_USB_CHIPIDEA_UDC=y
  15239. +CONFIG_USB_CHIPIDEA_HOST=y
  15240. +CONFIG_USB_PHY=y
  15241. +CONFIG_NOP_USB_XCEIV=y
  15242. +CONFIG_USB_MXS_PHY=y
  15243. +CONFIG_USB_GADGET=y
  15244. +CONFIG_USB_ZERO=m
  15245. +CONFIG_USB_ETH=m
  15246. +CONFIG_USB_MASS_STORAGE=m
  15247. +CONFIG_USB_G_SERIAL=m
  15248. +CONFIG_MMC=y
  15249. +CONFIG_MMC_UNSAFE_RESUME=y
  15250. +CONFIG_MMC_SDHCI=y
  15251. +CONFIG_MMC_SDHCI_PLTFM=y
  15252. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  15253. +CONFIG_MXC_IPU=y
  15254. +CONFIG_MXC_GPU_VIV=y
  15255. +CONFIG_MXC_ASRC=y
  15256. +CONFIG_MXC_HDMI_CEC=y
  15257. +CONFIG_MXC_MIPI_CSI2=y
  15258. +CONFIG_MXC_MLB150=m
  15259. +CONFIG_NEW_LEDS=y
  15260. +CONFIG_LEDS_CLASS=y
  15261. +CONFIG_LEDS_GPIO=y
  15262. +CONFIG_LEDS_TRIGGERS=y
  15263. +CONFIG_LEDS_TRIGGER_GPIO=y
  15264. +CONFIG_RTC_CLASS=y
  15265. +CONFIG_RTC_DRV_MXC=y
  15266. +CONFIG_RTC_DRV_SNVS=y
  15267. +CONFIG_RTC_DRV_PCF8523=y
  15268. +CONFIG_DMADEVICES=y
  15269. +CONFIG_MXC_PXP_V2=y
  15270. +CONFIG_IMX_SDMA=y
  15271. +CONFIG_MXS_DMA=y
  15272. +CONFIG_SRAM=y
  15273. +CONFIG_STAGING=y
  15274. +CONFIG_COMMON_CLK_DEBUG=y
  15275. +# CONFIG_IOMMU_SUPPORT is not set
  15276. +CONFIG_PWM=y
  15277. +CONFIG_PWM_SYSFS=y
  15278. +CONFIG_PWM_IMX=y
  15279. +CONFIG_IRQCHIP=y
  15280. +CONFIG_ARM_GIC=y
  15281. +# CONFIG_IPACK_BUS is not set
  15282. +CONFIG_ARCH_HAS_RESET_CONTROLLER=y
  15283. +CONFIG_RESET_CONTROLLER=y
  15284. +CONFIG_RESET_GPIO=y
  15285. +CONFIG_EXT4_FS=y
  15286. +CONFIG_EXT4_USE_FOR_EXT23=y
  15287. +CONFIG_EXT4_FS_XATTR=y
  15288. +CONFIG_EXT4_FS_POSIX_ACL=y
  15289. +CONFIG_EXT4_FS_SECURITY=y
  15290. +CONFIG_QUOTA=y
  15291. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  15292. +# CONFIG_PRINT_QUOTA_WARNING is not set
  15293. +CONFIG_AUTOFS4_FS=y
  15294. +CONFIG_FUSE_FS=y
  15295. +CONFIG_ISO9660_FS=m
  15296. +CONFIG_JOLIET=y
  15297. +CONFIG_ZISOFS=y
  15298. +CONFIG_UDF_FS=m
  15299. +CONFIG_MSDOS_FS=m
  15300. +CONFIG_VFAT_FS=y
  15301. +CONFIG_TMPFS=y
  15302. +CONFIG_JFFS2_FS=y
  15303. +CONFIG_UBIFS_FS=y
  15304. +CONFIG_NFS_FS=y
  15305. +CONFIG_NFS_V3_ACL=y
  15306. +CONFIG_NFS_V4=y
  15307. +CONFIG_ROOT_NFS=y
  15308. +CONFIG_NLS_DEFAULT="cp437"
  15309. +CONFIG_NLS_CODEPAGE_437=y
  15310. +CONFIG_NLS_ASCII=y
  15311. +CONFIG_NLS_ISO8859_1=y
  15312. +CONFIG_NLS_ISO8859_15=m
  15313. +CONFIG_NLS_UTF8=y
  15314. +CONFIG_MAGIC_SYSRQ=y
  15315. +# CONFIG_SCHED_DEBUG is not set
  15316. +# CONFIG_DEBUG_BUGVERBOSE is not set
  15317. +# CONFIG_FTRACE is not set
  15318. +CONFIG_SECURITYFS=y
  15319. +CONFIG_CRYPTO_USER=y
  15320. +CONFIG_CRYPTO_TEST=m
  15321. +CONFIG_CRYPTO_CCM=y
  15322. +CONFIG_CRYPTO_GCM=y
  15323. +CONFIG_CRYPTO_CBC=y
  15324. +CONFIG_CRYPTO_CTS=y
  15325. +CONFIG_CRYPTO_ECB=y
  15326. +CONFIG_CRYPTO_LRW=y
  15327. +CONFIG_CRYPTO_XTS=y
  15328. +CONFIG_CRYPTO_MD4=y
  15329. +CONFIG_CRYPTO_MD5=y
  15330. +CONFIG_CRYPTO_MICHAEL_MIC=y
  15331. +CONFIG_CRYPTO_RMD128=y
  15332. +CONFIG_CRYPTO_RMD160=y
  15333. +CONFIG_CRYPTO_RMD256=y
  15334. +CONFIG_CRYPTO_RMD320=y
  15335. +CONFIG_CRYPTO_SHA1=y
  15336. +CONFIG_CRYPTO_SHA256=y
  15337. +CONFIG_CRYPTO_SHA512=y
  15338. +CONFIG_CRYPTO_TGR192=y
  15339. +CONFIG_CRYPTO_WP512=y
  15340. +CONFIG_CRYPTO_BLOWFISH=y
  15341. +CONFIG_CRYPTO_CAMELLIA=y
  15342. +CONFIG_CRYPTO_DES=y
  15343. +CONFIG_CRYPTO_TWOFISH=y
  15344. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  15345. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  15346. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  15347. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  15348. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  15349. +CONFIG_CRYPTO_AES_ARM_BS=y
  15350. +CONFIG_CRC_CCITT=m
  15351. +CONFIG_CRC_T10DIF=y
  15352. +CONFIG_CRC7=m
  15353. +CONFIG_LIBCRC32C=m
  15354. +# CONFIG_MXC_MMA8451 is not set
  15355. +CONFIG_RC_CORE=m
  15356. +CONFIG_RC_DECODERS=y
  15357. +CONFIG_LIRC=m
  15358. +CONFIG_RC_LOOPBACK=m
  15359. +CONFIG_RC_MAP=m
  15360. +CONFIG_RC_DEVICES=y
  15361. +CONFIG_RC_ATI_REMOTE=m
  15362. +CONFIG_IR_NEC_DECODER=m
  15363. +CONFIG_IR_RC5_DECODER=m
  15364. +CONFIG_IR_RC6_DECODER=m
  15365. +CONFIG_IR_JVC_DECODER=m
  15366. +CONFIG_IR_SONY_DECODER=m
  15367. +CONFIG_IR_RC5_SZ_DECODER=m
  15368. +CONFIG_IR_SANYO_DECODER=m
  15369. +CONFIG_IR_MCE_KBD_DECODER=m
  15370. +CONFIG_IR_LIRC_CODEC=m
  15371. +CONFIG_IR_IMON=m
  15372. +CONFIG_IR_MCEUSB=m
  15373. +CONFIG_IR_ITE_CIR=m
  15374. +CONFIG_IR_NUVOTON=m
  15375. +CONFIG_IR_FINTEK=m
  15376. +CONFIG_IR_REDRAT3=m
  15377. +CONFIG_IR_ENE=m
  15378. +CONFIG_IR_STREAMZAP=m
  15379. +CONFIG_IR_WINBOND_CIR=m
  15380. +CONFIG_IR_IGUANA=m
  15381. +CONFIG_IR_TTUSBIR=m
  15382. +CONFIG_IR_GPIO_CIR=m
  15383. diff -Nur linux-3.14.14/arch/arm/configs/imx_v7_cbi_hb_defconfig linux-imx6-3.14/arch/arm/configs/imx_v7_cbi_hb_defconfig
  15384. --- linux-3.14.14/arch/arm/configs/imx_v7_cbi_hb_defconfig 1969-12-31 18:00:00.000000000 -0600
  15385. +++ linux-imx6-3.14/arch/arm/configs/imx_v7_cbi_hb_defconfig 2014-12-08 00:31:51.156418001 -0600
  15386. @@ -0,0 +1,5138 @@
  15387. +#
  15388. +# Automatically generated make config: don't edit
  15389. +#
  15390. +CONFIG_MMU=y
  15391. +CONFIG_HOTPLUG_CPU=y
  15392. +# CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set
  15393. +# CONFIG_DEBUG_HOTPLUG_CPU0 is not set
  15394. +CONFIG_LOCALVERSION=""
  15395. +CONFIG_CROSS_COMPILE=""
  15396. +CONFIG_DEFAULT_HOSTNAME="(none)"
  15397. +
  15398. +#
  15399. +# Code maturity level options
  15400. +#
  15401. +CONFIG_EXPERIMENTAL=y
  15402. +CONFIG_HOTPLUG=y
  15403. +CONFIG_UEVENT_HELPER_PATH=""
  15404. +CONFIG_PREVENT_FIRMWARE_BUILD=y
  15405. +
  15406. +CONFIG_BUILD_DOCSRC=y
  15407. +
  15408. +#
  15409. +# General setup
  15410. +#
  15411. +CONFIG_KERNEL_LZO=y
  15412. +# CONFIG_KERNEL_BZIP2 is not set
  15413. +# CONFIG_KERNEL_LZMA is not set
  15414. +CONFIG_SWAP=y
  15415. +CONFIG_BSD_PROCESS_ACCT=y
  15416. +CONFIG_BSD_PROCESS_ACCT_V3=y
  15417. +# CONFIG_COMPILE_TEST is not set
  15418. +CONFIG_TASKSTATS=y
  15419. +CONFIG_TASK_DELAY_ACCT=y
  15420. +CONFIG_TASK_XACCT=y
  15421. +CONFIG_TASK_IO_ACCOUNTING=y
  15422. +CONFIG_SYSCTL=y
  15423. +# CONFIG_IKCONFIG is not set
  15424. +# CONFIG_EMBEDDED is not set
  15425. +CONFIG_KALLSYMS=y
  15426. +CONFIG_KALLSYMS_ALL=y
  15427. +CONFIG_FUTEX=y
  15428. +CONFIG_EPOLL=y
  15429. +CONFIG_IOSCHED_NOOP=y
  15430. +CONFIG_IOSCHED_DEADLINE=y
  15431. +CONFIG_IOSCHED_CFQ=y
  15432. +CONFIG_CFQ_GROUP_IOSCHED=y
  15433. +CONFIG_IOSCHED_BFQ=y
  15434. +CONFIG_CGROUP_BFQIO=y
  15435. +CONFIG_DEFAULT_BFQ=y
  15436. +CONFIG_DEFAULT_IOSCHED="bfq"
  15437. +# CONFIG_CHECKPOINT_RESTORE is not set
  15438. +CONFIG_NAMESPACES=y
  15439. +CONFIG_PID_NS=y
  15440. +CONFIG_UTS_NS=y
  15441. +CONFIG_IPC_NS=y
  15442. +CONFIG_NET_NS=y
  15443. +CONFIG_USER_NS=y
  15444. +# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
  15445. +CONFIG_SYSVIPC=y
  15446. +CONFIG_FHANDLE=y
  15447. +CONFIG_NO_HZ=y
  15448. +CONFIG_HIGH_RES_TIMERS=y
  15449. +CONFIG_LOG_BUF_SHIFT=18
  15450. +CONFIG_CGROUPS=y
  15451. +CONFIG_RELAY=y
  15452. +CONFIG_BLK_DEV_INITRD=y
  15453. +CONFIG_EXPERT=y
  15454. +CONFIG_PERF_EVENTS=y
  15455. +# CONFIG_SLUB_DEBUG is not set
  15456. +# CONFIG_COMPAT_BRK is not set
  15457. +CONFIG_MODULES=y
  15458. +CONFIG_MODULE_UNLOAD=y
  15459. +CONFIG_MODVERSIONS=y
  15460. +CONFIG_MODULE_SRCVERSION_ALL=y
  15461. +
  15462. +CONFIG_POSIX_MQUEUE=y
  15463. +CONFIG_PREEMPT_VOLUNTARY=y
  15464. +
  15465. +CONFIG_SLUB=y
  15466. +CONFIG_SLUB_CPU_PARTIAL=y
  15467. +# CONFIG_SLUB_STATS is not set
  15468. +# CONFIG_SLUB_DEBUG_ON is not set
  15469. +
  15470. +# CONFIG_AD525X_DPOT is not set
  15471. +# CONFIG_ATMEL_PWM is not set
  15472. +# CONFIG_IWMC3200TOP is not set
  15473. +# CONFIG_BLK_DEV_BSG is not set
  15474. +
  15475. +# MX6 specific kernel configuration
  15476. +CONFIG_GPIO_PCA953X=y
  15477. +CONFIG_ARCH_MXC=y
  15478. +CONFIG_MXC_DEBUG_BOARD=y
  15479. +CONFIG_SOC_IMX6Q=y
  15480. +CONFIG_SOC_IMX6SL=y
  15481. +# CONFIG_SWP_EMULATE is not set
  15482. +CONFIG_PCI=y
  15483. +CONFIG_PCIE_DW=y
  15484. +CONFIG_PCI_IMX6=y
  15485. +CONFIG_SMP=y
  15486. +CONFIG_VMSPLIT_2G=y
  15487. +CONFIG_AEABI=y
  15488. +# CONFIG_OABI_COMPAT is not set
  15489. +CONFIG_HIGHMEM=y
  15490. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  15491. +CONFIG_CPU_FREQ=y
  15492. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  15493. +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
  15494. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  15495. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  15496. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  15497. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  15498. +CONFIG_ARM_IMX6_CPUFREQ=y
  15499. +CONFIG_CPU_IDLE=y
  15500. +CONFIG_VFP=y
  15501. +CONFIG_VFPv3=y
  15502. +CONFIG_NEON=y
  15503. +CONFIG_KERNEL_MODE_NEON=y
  15504. +CONFIG_BINFMT_MISC=m
  15505. +CONFIG_PM_RUNTIME=y
  15506. +CONFIG_PM_DEBUG=y
  15507. +CONFIG_PM_TEST_SUSPEND=y
  15508. +CONFIG_NET=y
  15509. +CONFIG_PACKET=y
  15510. +CONFIG_UNIX=y
  15511. +CONFIG_INET=y
  15512. +CONFIG_IP_PNP=y
  15513. +CONFIG_IP_PNP_DHCP=y
  15514. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  15515. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  15516. +# CONFIG_INET_XFRM_MODE_BEET is not set
  15517. +# CONFIG_INET_LRO is not set
  15518. +CONFIG_IPV6=y
  15519. +CONFIG_NETFILTER=y
  15520. +CONFIG_VLAN_8021Q=y
  15521. +CONFIG_WIRELESS=y
  15522. +CONFIG_WIRELESS_EXT=y
  15523. +CONFIG_WEXT_CORE=y
  15524. +CONFIG_WEXT_PROC=y
  15525. +CONFIG_WEXT_SPY=y
  15526. +CONFIG_WEXT_PRIV=y
  15527. +CONFIG_CFG80211=y
  15528. +CONFIG_ETHERNET=y
  15529. +# CONFIG_NET_VENDOR_BROADCOM is not set
  15530. +# CONFIG_NET_VENDOR_CIRRUS is not set
  15531. +# CONFIG_NET_VENDOR_FARADAY
  15532. +# CONFIG_NET_VENDOR_INTEL
  15533. +# CONFIG_NET_VENDOR_I825XX
  15534. +# CONFIG_NET_VENDOR_MARVELL
  15535. +# CONFIG_NET_VENDOR_MICROCHIP
  15536. +# CONFIG_NET_VENDOR_MICROCHIP=y
  15537. +# CONFIG_ENC28J60 is not set
  15538. +# CONFIG_NET_VENDOR_NATSEMI=y
  15539. +# CONFIG_NET_VENDOR_8390=y
  15540. +# CONFIG_AX88796 is not set
  15541. +# CONFIG_ETHOC is not set
  15542. +# CONFIG_SH_ETH is not set
  15543. +# CONFIG_NET_VENDOR_SEEQ=y
  15544. +# CONFIG_NET_VENDOR_SMSC=y
  15545. +# CONFIG_SMC91X is not set
  15546. +# CONFIG_SMC911X is not set
  15547. +# CONFIG_SMSC911X is not set
  15548. +# CONFIG_NET_VENDOR_STMICRO=y
  15549. +# CONFIG_STMMAC_ETH is not set
  15550. +# CONFIG_NET_VENDOR_VIA=y
  15551. +# CONFIG_VIA_VELOCITY is not set
  15552. +# CONFIG_NET_VENDOR_WIZNET=y
  15553. +CONFIG_NET_VENDOR_FREESCALE=y
  15554. +CONFIG_FEC=y
  15555. +CONFIG_PHYLIB=y
  15556. +CONFIG_AT803X_PHY=y
  15557. +CONFIG_WLAN=y
  15558. +CONFIG_BRCMUTIL=m
  15559. +CONFIG_BRCMFMAC=m
  15560. +CONFIG_BRCMFMAC_SDIO=y
  15561. +CONFIG_DEVTMPFS=y
  15562. +CONFIG_DEVTMPFS_MOUNT=y
  15563. +# CONFIG_STANDALONE is not set
  15564. +CONFIG_DMA_CMA=y
  15565. +CONFIG_CMA=y
  15566. +CONFIG_CMA_SIZE_MBYTES=256
  15567. +CONFIG_CONNECTOR=y
  15568. +# CONFIG_MTD is not set
  15569. +CONFIG_BLK_DEV_LOOP=y
  15570. +CONFIG_BLK_DEV_RAM=y
  15571. +CONFIG_BLK_DEV_RAM_SIZE=65536
  15572. +# CONFIG_SCSI_PROC_FS is not set
  15573. +CONFIG_BLK_DEV_SD=y
  15574. +CONFIG_SCSI_MULTI_LUN=y
  15575. +CONFIG_SCSI_CONSTANTS=y
  15576. +CONFIG_SCSI_LOGGING=y
  15577. +CONFIG_SCSI_SCAN_ASYNC=y
  15578. +# CONFIG_SCSI_LOWLEVEL is not set
  15579. +CONFIG_ATA=y
  15580. +CONFIG_SATA_AHCI_PLATFORM=y
  15581. +CONFIG_AHCI_IMX=y
  15582. +CONFIG_NETDEVICES=y
  15583. +CONFIG_INPUT_EVDEV=y
  15584. +# CONFIG_INPUT_EVBUG is not set
  15585. +CONFIG_KEYBOARD_GPIO=y
  15586. +CONFIG_KEYBOARD_IMX=y
  15587. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  15588. +# CONFIG_KEYBOARD_ATKBD is not set
  15589. +# CONFIG_MOUSE_PS2 is not set
  15590. +CONFIG_INPUT_MISC=y
  15591. +CONFIG_SERIO_SERPORT=m
  15592. +CONFIG_VT_HW_CONSOLE_BINDING=y
  15593. +# CONFIG_LEGACY_PTYS is not set
  15594. +# CONFIG_DEVKMEM is not set
  15595. +CONFIG_SERIAL_IMX=y
  15596. +CONFIG_SERIAL_IMX_CONSOLE=y
  15597. +CONFIG_SERIAL_FSL_LPUART=y
  15598. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  15599. +CONFIG_FSL_OTP=y
  15600. +CONFIG_GPIO_MXC=y
  15601. +# CONFIG_I2C_COMPAT is not set
  15602. +CONFIG_I2C_CHARDEV=y
  15603. +# CONFIG_I2C_HELPER_AUTO is not set
  15604. +CONFIG_I2C_ALGOPCF=m
  15605. +CONFIG_I2C_ALGOPCA=m
  15606. +CONFIG_I2C_IMX=y
  15607. +CONFIG_SPI=y
  15608. +CONFIG_SPI_IMX=y
  15609. +CONFIG_GPIO_SYSFS=y
  15610. +CONFIG_POWER_SUPPLY=y
  15611. +CONFIG_THERMAL=y
  15612. +CONFIG_CPU_THERMAL=y
  15613. +CONFIG_IMX_THERMAL=y
  15614. +CONFIG_DEVICE_THERMAL=y
  15615. +CONFIG_WATCHDOG=y
  15616. +CONFIG_IMX2_WDT=y
  15617. +CONFIG_MFD_DA9052_I2C=y
  15618. +CONFIG_MFD_MC13XXX_SPI=y
  15619. +CONFIG_MFD_MC13XXX_I2C=y
  15620. +CONFIG_MFD_SI476X_CORE=y
  15621. +CONFIG_REGULATOR=y
  15622. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  15623. +CONFIG_REGULATOR_ANATOP=y
  15624. +CONFIG_REGULATOR_PFUZE100=y
  15625. +CONFIG_MEDIA_SUPPORT=y
  15626. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  15627. +# CONFIG_MEDIA_RADIO_SUPPORT is not set
  15628. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  15629. +CONFIG_MEDIA_USB_SUPPORT=y
  15630. +CONFIG_USB_VIDEO_CLASS=m
  15631. +# CONFIG_RADIO_ADAPTERS is not set
  15632. +CONFIG_V4L_PLATFORM_DRIVERS=y
  15633. +CONFIG_VIDEO_MXC_OUTPUT=y
  15634. +CONFIG_VIDEO_MXC_CAPTURE=m
  15635. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  15636. +CONFIG_MXC_CAMERA_OV5640=m
  15637. +CONFIG_MXC_CAMERA_OV5642=m
  15638. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  15639. +CONFIG_MXC_TVIN_ADV7180=m
  15640. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  15641. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  15642. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  15643. +CONFIG_SOC_CAMERA=y
  15644. +CONFIG_SOC_CAMERA_OV2640=y
  15645. +CONFIG_DRM=y
  15646. +CONFIG_DRM_VIVANTE=y
  15647. +CONFIG_FB=y
  15648. +# CONFIG_FB_MX3 is not set
  15649. +CONFIG_FB_MXC_SYNC_PANEL=y
  15650. +CONFIG_FB_MXC_LDB=y
  15651. +CONFIG_FB_MXC_HDMI=y
  15652. +CONFIG_FRAMEBUFFER_CONSOLE=y
  15653. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  15654. +CONFIG_FONTS=y
  15655. +CONFIG_FONT_8x8=y
  15656. +CONFIG_FONT_8x16=y
  15657. +CONFIG_LOGO=y
  15658. +CONFIG_SOUND=y
  15659. +CONFIG_SND=y
  15660. +CONFIG_SND_USB_AUDIO=m
  15661. +CONFIG_SND_SOC=y
  15662. +CONFIG_SND_IMX_SOC=y
  15663. +CONFIG_SND_SOC_IMX_SGTL5000=y
  15664. +CONFIG_SND_SOC_IMX_SPDIF=y
  15665. +CONFIG_SND_SOC_IMX_HDMI=y
  15666. +CONFIG_USB=y
  15667. +CONFIG_USB_EHCI_HCD=y
  15668. +CONFIG_USB_STORAGE=y
  15669. +CONFIG_USB_CHIPIDEA=y
  15670. +CONFIG_USB_CHIPIDEA_UDC=y
  15671. +CONFIG_USB_CHIPIDEA_HOST=y
  15672. +CONFIG_USB_PHY=y
  15673. +CONFIG_NOP_USB_XCEIV=y
  15674. +CONFIG_USB_MXS_PHY=y
  15675. +CONFIG_USB_GADGET=y
  15676. +CONFIG_USB_ZERO=m
  15677. +CONFIG_USB_ETH=m
  15678. +CONFIG_USB_MASS_STORAGE=m
  15679. +CONFIG_USB_G_SERIAL=m
  15680. +CONFIG_MMC=y
  15681. +CONFIG_MMC_UNSAFE_RESUME=y
  15682. +CONFIG_MMC_SDHCI=y
  15683. +CONFIG_MMC_SDHCI_PLTFM=y
  15684. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  15685. +CONFIG_MXC_IPU=y
  15686. +CONFIG_MXC_GPU_VIV=y
  15687. +CONFIG_MXC_ASRC=y
  15688. +CONFIG_MXC_HDMI_CEC=y
  15689. +CONFIG_MXC_MIPI_CSI2=y
  15690. +CONFIG_MXC_MLB150=m
  15691. +CONFIG_NEW_LEDS=y
  15692. +CONFIG_LEDS_CLASS=y
  15693. +CONFIG_LEDS_GPIO=y
  15694. +CONFIG_LEDS_TRIGGERS=y
  15695. +CONFIG_LEDS_TRIGGER_GPIO=y
  15696. +CONFIG_RTC_CLASS=y
  15697. +CONFIG_RTC_DRV_MXC=y
  15698. +CONFIG_RTC_DRV_SNVS=y
  15699. +CONFIG_RTC_DRV_PCF8523=y
  15700. +CONFIG_DMADEVICES=y
  15701. +CONFIG_MXC_PXP_V2=y
  15702. +CONFIG_IMX_SDMA=y
  15703. +CONFIG_MXS_DMA=y
  15704. +CONFIG_SRAM=y
  15705. +CONFIG_STAGING=y
  15706. +CONFIG_COMMON_CLK_DEBUG=y
  15707. +# CONFIG_IOMMU_SUPPORT is not set
  15708. +CONFIG_PWM=y
  15709. +CONFIG_PWM_SYSFS=y
  15710. +CONFIG_PWM_IMX=y
  15711. +CONFIG_IRQCHIP=y
  15712. +CONFIG_ARM_GIC=y
  15713. +CONFIG_ARCH_HAS_RESET_CONTROLLER=y
  15714. +CONFIG_RESET_CONTROLLER=y
  15715. +CONFIG_RESET_GPIO=y
  15716. +CONFIG_EXT4_FS=y
  15717. +CONFIG_EXT4_USE_FOR_EXT23=y
  15718. +CONFIG_EXT4_FS_XATTR=y
  15719. +CONFIG_EXT4_FS_POSIX_ACL=y
  15720. +CONFIG_EXT4_FS_SECURITY=y
  15721. +CONFIG_QUOTA=y
  15722. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  15723. +# CONFIG_PRINT_QUOTA_WARNING is not set
  15724. +CONFIG_AUTOFS4_FS=y
  15725. +CONFIG_FUSE_FS=y
  15726. +CONFIG_ISO9660_FS=m
  15727. +CONFIG_JOLIET=y
  15728. +CONFIG_ZISOFS=y
  15729. +CONFIG_UDF_FS=m
  15730. +CONFIG_MSDOS_FS=m
  15731. +CONFIG_VFAT_FS=y
  15732. +CONFIG_TMPFS=y
  15733. +CONFIG_JFFS2_FS=y
  15734. +CONFIG_UBIFS_FS=y
  15735. +CONFIG_NFS_FS=y
  15736. +CONFIG_NFS_V3_ACL=y
  15737. +CONFIG_NFS_V4=y
  15738. +CONFIG_ROOT_NFS=y
  15739. +CONFIG_NLS_DEFAULT="cp437"
  15740. +CONFIG_NLS_CODEPAGE_437=y
  15741. +CONFIG_NLS_ASCII=y
  15742. +CONFIG_NLS_ISO8859_1=y
  15743. +CONFIG_NLS_ISO8859_15=m
  15744. +CONFIG_NLS_UTF8=y
  15745. +CONFIG_MAGIC_SYSRQ=y
  15746. +# CONFIG_SCHED_DEBUG is not set
  15747. +# CONFIG_DEBUG_BUGVERBOSE is not set
  15748. +# CONFIG_FTRACE is not set
  15749. +CONFIG_SECURITYFS=y
  15750. +CONFIG_CRYPTO_USER=y
  15751. +CONFIG_CRYPTO_TEST=m
  15752. +CONFIG_CRYPTO_CCM=y
  15753. +CONFIG_CRYPTO_GCM=y
  15754. +CONFIG_CRYPTO_CBC=y
  15755. +CONFIG_CRYPTO_CTS=y
  15756. +CONFIG_CRYPTO_ECB=y
  15757. +CONFIG_CRYPTO_LRW=y
  15758. +CONFIG_CRYPTO_XTS=y
  15759. +CONFIG_CRYPTO_MD4=y
  15760. +CONFIG_CRYPTO_MD5=y
  15761. +CONFIG_CRYPTO_MICHAEL_MIC=y
  15762. +CONFIG_CRYPTO_RMD128=y
  15763. +CONFIG_CRYPTO_RMD160=y
  15764. +CONFIG_CRYPTO_RMD256=y
  15765. +CONFIG_CRYPTO_RMD320=y
  15766. +CONFIG_CRYPTO_SHA1=y
  15767. +CONFIG_CRYPTO_SHA256=y
  15768. +CONFIG_CRYPTO_SHA512=y
  15769. +CONFIG_CRYPTO_TGR192=y
  15770. +CONFIG_CRYPTO_WP512=y
  15771. +CONFIG_CRYPTO_BLOWFISH=y
  15772. +CONFIG_CRYPTO_CAMELLIA=y
  15773. +CONFIG_CRYPTO_DES=y
  15774. +CONFIG_CRYPTO_TWOFISH=y
  15775. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  15776. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  15777. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  15778. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  15779. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  15780. +CONFIG_CRYPTO_AES_ARM_BS=y
  15781. +CONFIG_CRC_CCITT=m
  15782. +CONFIG_CRC_T10DIF=y
  15783. +CONFIG_CRC7=m
  15784. +CONFIG_LIBCRC32C=m
  15785. +# CONFIG_MXC_MMA8451 is not set
  15786. +
  15787. +#
  15788. +# Loadable module support
  15789. +#
  15790. +# CONFIG_MODULE_FORCE_LOAD is not set
  15791. +# -- MODULE_FORCE_UNLOAD is controlled by config-debug/nodebug
  15792. +
  15793. +# CONFIG_PCI_DEBUG is not set
  15794. +CONFIG_PCI_STUB=y
  15795. +CONFIG_PCI_IOV=y
  15796. +CONFIG_PCI_PRI=y
  15797. +CONFIG_PCI_PASID=y
  15798. +CONFIG_HT_IRQ=y
  15799. +CONFIG_PCI_MSI=y
  15800. +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
  15801. +CONFIG_PCIEPORTBUS=y
  15802. +CONFIG_PCIEAER=y
  15803. +CONFIG_PCIEASPM=y
  15804. +# CONFIG_PCIEASPM_DEBUG is not set
  15805. +CONFIG_PCIE_ECRC=y
  15806. +CONFIG_PCIEAER_INJECT=m
  15807. +CONFIG_HOTPLUG_PCI_PCIE=y
  15808. +CONFIG_HOTPLUG_PCI_FAKE=m
  15809. +
  15810. +# CONFIG_SGI_IOC4 is not set
  15811. +
  15812. +# CONFIG_ISA is not set
  15813. +# CONFIG_SCx200 is not set
  15814. +
  15815. +#
  15816. +# PCMCIA/CardBus support
  15817. +# FIXME: Deprecate Cardbus ?
  15818. +#
  15819. +CONFIG_PCMCIA=y
  15820. +CONFIG_PCMCIA_LOAD_CIS=y
  15821. +# CONFIG_PCMCIA_DEBUG is not set
  15822. +CONFIG_YENTA=m
  15823. +CONFIG_CARDBUS=y
  15824. +CONFIG_I82092=m
  15825. +CONFIG_PD6729=m
  15826. +
  15827. +CONFIG_PCCARD=y
  15828. +CONFIG_SDIO_UART=m
  15829. +# CONFIG_MMC_TEST is not set
  15830. +# CONFIG_MMC_DEBUG is not set
  15831. +# https://lists.fedoraproject.org/pipermail/kernel/2014-February/004889.html
  15832. +# CONFIG_MMC_CLKGATE is not set
  15833. +CONFIG_MMC_BLOCK=y
  15834. +CONFIG_MMC_BLOCK_MINORS=8
  15835. +CONFIG_MMC_BLOCK_BOUNCE=y
  15836. +CONFIG_MMC_SDHCI_PCI=m
  15837. +CONFIG_MMC_SDHCI_ACPI=m
  15838. +CONFIG_MMC_SDRICOH_CS=m
  15839. +CONFIG_MMC_TIFM_SD=m
  15840. +CONFIG_MMC_WBSD=m
  15841. +CONFIG_MMC_VIA_SDMMC=m
  15842. +CONFIG_MMC_CB710=m
  15843. +CONFIG_MMC_RICOH_MMC=y
  15844. +CONFIG_MMC_USHC=m
  15845. +CONFIG_MMC_REALTEK_PCI=m
  15846. +CONFIG_MMC_VUB300=m
  15847. +# CONFIG_MMC_SDHCI_PXAV2 is not set
  15848. +# CONFIG_MMC_SDHCI_PXAV3 is not set
  15849. +# CONFIG_MMC_SDHCI_OF_ARASAN is not set
  15850. +
  15851. +
  15852. +CONFIG_CB710_CORE=m
  15853. +# CONFIG_CB710_DEBUG is not set
  15854. +
  15855. +CONFIG_INFINIBAND=m
  15856. +CONFIG_INFINIBAND_MTHCA=m
  15857. +# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
  15858. +CONFIG_INFINIBAND_IPOIB=m
  15859. +CONFIG_INFINIBAND_IPOIB_DEBUG=y
  15860. +CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
  15861. +CONFIG_INFINIBAND_IPOIB_CM=y
  15862. +CONFIG_INFINIBAND_SRP=m
  15863. +CONFIG_INFINIBAND_SRPT=m
  15864. +CONFIG_INFINIBAND_USER_MAD=m
  15865. +CONFIG_INFINIBAND_USER_ACCESS=m
  15866. +# CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING is not set #staging
  15867. +CONFIG_INFINIBAND_IPATH=m
  15868. +CONFIG_INFINIBAND_ISER=m
  15869. +CONFIG_INFINIBAND_ISERT=m
  15870. +CONFIG_INFINIBAND_AMSO1100=m
  15871. +# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set
  15872. +CONFIG_INFINIBAND_CXGB3=m
  15873. +CONFIG_INFINIBAND_CXGB4=m
  15874. +CONFIG_SCSI_CXGB3_ISCSI=m
  15875. +CONFIG_SCSI_CXGB4_ISCSI=m
  15876. +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set
  15877. +CONFIG_MLX4_INFINIBAND=m
  15878. +CONFIG_MLX5_INFINIBAND=m
  15879. +CONFIG_INFINIBAND_NES=m
  15880. +# CONFIG_INFINIBAND_NES_DEBUG is not set
  15881. +CONFIG_INFINIBAND_QIB=m
  15882. +CONFIG_INFINIBAND_QIB_DCA=y
  15883. +# CONFIG_INFINIBAND_OCRDMA is not set
  15884. +# CONFIG_INFINIBAND_USNIC is not set
  15885. +
  15886. +#
  15887. +# Executable file formats
  15888. +#
  15889. +CONFIG_BINFMT_ELF=y
  15890. +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
  15891. +# CONFIG_BINFMT_AOUT is not set
  15892. +CONFIG_BINFMT_SCRIPT=y
  15893. +
  15894. +#
  15895. +# Device Drivers
  15896. +#
  15897. +
  15898. +# CONFIG_COMMON_CLK_SI5351 is not set
  15899. +
  15900. +#
  15901. +# Generic Driver Options
  15902. +#
  15903. +CONFIG_FW_LOADER=y
  15904. +# CONFIG_FIRMWARE_IN_KERNEL is not set
  15905. +CONFIG_EXTRA_FIRMWARE=""
  15906. +
  15907. +# Give this a try in rawhide for now
  15908. +# CONFIG_FW_LOADER_USER_HELPER is not set
  15909. +
  15910. +
  15911. +
  15912. +#
  15913. +# Memory Technology Devices (MTD)
  15914. +#
  15915. +# CONFIG_MTD_TESTS is not set
  15916. +# CONFIG_MTD_REDBOOT_PARTS is not set
  15917. +# CONFIG_MTD_AR7_PARTS is not set
  15918. +# CONFIG_MTD_CMDLINE_PARTS is not set
  15919. +
  15920. +#
  15921. +# User Modules And Translation Layers
  15922. +#
  15923. +# CONFIG_MTD_CHAR is not set
  15924. +# CONFIG_MTD_BLKDEVS is not set
  15925. +# CONFIG_MTD_BLOCK is not set
  15926. +# CONFIG_MTD_BLOCK_RO is not set
  15927. +# CONFIG_FTL is not set
  15928. +# CONFIG_NFTL is not set
  15929. +# CONFIG_INFTL is not set
  15930. +# CONFIG_RFD_FTL is not set
  15931. +# CONFIG_SSFDC is not set
  15932. +# CONFIG_SM_FTL is not set
  15933. +# CONFIG_MTD_OOPS is not set
  15934. +# CONFIG_MTD_SWAP is not set
  15935. +
  15936. +#
  15937. +# RAM/ROM/Flash chip drivers
  15938. +#
  15939. +# CONFIG_MTD_CFI is not set
  15940. +# CONFIG_MTD_JEDECPROBE is not set
  15941. +CONFIG_MTD_MAP_BANK_WIDTH_1=y
  15942. +CONFIG_MTD_MAP_BANK_WIDTH_2=y
  15943. +CONFIG_MTD_MAP_BANK_WIDTH_4=y
  15944. +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
  15945. +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
  15946. +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
  15947. +CONFIG_MTD_CFI_I1=y
  15948. +CONFIG_MTD_CFI_I2=y
  15949. +# CONFIG_MTD_CFI_I4 is not set
  15950. +# CONFIG_MTD_CFI_I8 is not set
  15951. +# CONFIG_MTD_RAM is not set
  15952. +# CONFIG_MTD_ROM is not set
  15953. +# CONFIG_MTD_ABSENT is not set
  15954. +
  15955. +#
  15956. +# Mapping drivers for chip access
  15957. +#
  15958. +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
  15959. +# CONFIG_MTD_TS5500 is not set
  15960. +# CONFIG_MTD_INTEL_VR_NOR is not set
  15961. +# CONFIG_MTD_PLATRAM is not set
  15962. +
  15963. +# Self-contained MTD device drivers
  15964. +# CONFIG_MTD_PMC551 is not set
  15965. +# CONFIG_MTD_SLRAM is not set
  15966. +# CONFIG_MTD_PHRAM is not set
  15967. +# CONFIG_MTD_MTDRAM is not set
  15968. +# CONFIG_MTD_BLOCK2MTD is not set
  15969. +
  15970. +#
  15971. +# Disk-On-Chip Device Drivers
  15972. +#
  15973. +# CONFIG_MTD_DOCG3 is not set
  15974. +# CONFIG_MTD_NAND is not set
  15975. +# CONFIG_MTD_ONENAND is not set
  15976. +# CONFIG_MTD_NAND_VERIFY_WRITE is not set
  15977. +# CONFIG_MTD_NAND_ECC_BCH is not set
  15978. +# CONFIG_MTD_NAND_MUSEUM_IDS is not set
  15979. +# CONFIG_MTD_NAND_DISKONCHIP is not set
  15980. +# CONFIG_MTD_LPDDR is not set
  15981. +CONFIG_MTD_UBI=m
  15982. +CONFIG_MTD_UBI_WL_THRESHOLD=4096
  15983. +CONFIG_MTD_UBI_BEB_LIMIT=20
  15984. +# CONFIG_MTD_UBI_FASTMAP is not set
  15985. +# CONFIG_MTD_UBI_GLUEBI is not set
  15986. +
  15987. +#
  15988. +# Parallel port support
  15989. +#
  15990. +CONFIG_PARPORT=m
  15991. +CONFIG_PARPORT_PC=m
  15992. +CONFIG_PARPORT_SERIAL=m
  15993. +# CONFIG_PARPORT_PC_FIFO is not set
  15994. +# CONFIG_PARPORT_PC_SUPERIO is not set
  15995. +CONFIG_PARPORT_PC_PCMCIA=m
  15996. +CONFIG_PARPORT_1284=y
  15997. +# CONFIG_PARPORT_AX88796 is not set
  15998. +
  15999. +CONFIG_ACPI_PCI_SLOT=y
  16000. +CONFIG_HOTPLUG_PCI_ACPI=y
  16001. +CONFIG_HOTPLUG_PCI_ACPI_IBM=m
  16002. +
  16003. +#
  16004. +# Block devices
  16005. +#
  16006. +CONFIG_BLK_DEV=y
  16007. +CONFIG_BLK_DEV_NULL_BLK=m
  16008. +CONFIG_BLK_DEV_FD=m
  16009. +# CONFIG_PARIDE is not set
  16010. +CONFIG_ZRAM=m
  16011. +# CONFIG_ZRAM_DEBUG is not set
  16012. +CONFIG_ENHANCEIO=m
  16013. +
  16014. +CONFIG_BLK_CPQ_DA=m
  16015. +CONFIG_BLK_CPQ_CISS_DA=m
  16016. +CONFIG_CISS_SCSI_TAPE=y
  16017. +CONFIG_BLK_DEV_DAC960=m
  16018. +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
  16019. +CONFIG_BLK_DEV_DRBD=m
  16020. +CONFIG_BLK_DEV_UMEM=m
  16021. +CONFIG_BLK_DEV_LOOP_MIN_COUNT=0
  16022. +# Fedora 18 util-linux is the last release that supports cryptoloop devices
  16023. +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
  16024. +CONFIG_BLK_DEV_NBD=m
  16025. +CONFIG_BLK_DEV_NVME=m
  16026. +CONFIG_BLK_DEV_SKD=m # 64-bit only but easier to put here
  16027. +CONFIG_BLK_DEV_OSD=m
  16028. +CONFIG_BLK_DEV_RAM_COUNT=16
  16029. +CONFIG_BLK_DEV_IO_TRACE=y
  16030. +
  16031. +CONFIG_BLK_DEV_BSGLIB=y
  16032. +CONFIG_BLK_DEV_INTEGRITY=y
  16033. +CONFIG_BLK_DEV_THROTTLING=y
  16034. +# CONFIG_BLK_CMDLINE_PARSER is not set
  16035. +
  16036. +
  16037. +#
  16038. +# ATA/ATAPI/MFM/RLL support
  16039. +#
  16040. +# CONFIG_IDE is not set
  16041. +
  16042. +# CONFIG_BLK_DEV_HD is not set
  16043. +# CONFIG_BLK_DEV_RSXX is not set
  16044. +
  16045. +CONFIG_SCSI_VIRTIO=m
  16046. +CONFIG_VIRTIO_BLK=m
  16047. +CONFIG_VIRTIO_PCI=m
  16048. +CONFIG_VIRTIO_BALLOON=m
  16049. +CONFIG_VIRTIO_MMIO=m
  16050. +# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
  16051. +CONFIG_VIRTIO_NET=m
  16052. +CONFIG_HW_RANDOM_VIRTIO=m
  16053. +CONFIG_VIRTIO_CONSOLE=m
  16054. +CONFIG_VHOST_NET=m
  16055. +CONFIG_TCM_VHOST=m
  16056. +CONFIG_VHOST_SCSI=m
  16057. +
  16058. +#
  16059. +# SCSI device support
  16060. +#
  16061. +CONFIG_SCSI=y
  16062. +
  16063. +CONFIG_SCSI_ENCLOSURE=m
  16064. +CONFIG_SCSI_SRP=m
  16065. +CONFIG_SCSI_SRP_ATTRS=m
  16066. +CONFIG_SCSI_TGT=m
  16067. +CONFIG_SCSI_ISCI=m
  16068. +CONFIG_SCSI_CHELSIO_FCOE=m
  16069. +
  16070. +CONFIG_SCSI_DH=y
  16071. +CONFIG_SCSI_DH_RDAC=m
  16072. +CONFIG_SCSI_DH_HP_SW=m
  16073. +CONFIG_SCSI_DH_EMC=m
  16074. +CONFIG_SCSI_DH_ALUA=m
  16075. +
  16076. +#
  16077. +# SCSI support type (disk, tape, CD-ROM)
  16078. +#
  16079. +CONFIG_CHR_DEV_ST=m
  16080. +CONFIG_CHR_DEV_OSST=m
  16081. +CONFIG_BLK_DEV_SR=y
  16082. +CONFIG_BLK_DEV_SR_VENDOR=y
  16083. +CONFIG_CHR_DEV_SG=y
  16084. +CONFIG_CHR_DEV_SCH=m
  16085. +
  16086. +#
  16087. +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
  16088. +#
  16089. +CONFIG_SCSI_SPI_ATTRS=m
  16090. +CONFIG_SCSI_FC_ATTRS=m
  16091. +CONFIG_SCSI_FC_TGT_ATTRS=y
  16092. +CONFIG_SCSI_ISCSI_ATTRS=m
  16093. +CONFIG_SCSI_SAS_ATTRS=m
  16094. +CONFIG_SCSI_SRP_TGT_ATTRS=y
  16095. +CONFIG_SCSI_SAS_LIBSAS=m
  16096. +CONFIG_SCSI_SAS_ATA=y
  16097. +CONFIG_SCSI_SAS_HOST_SMP=y
  16098. +CONFIG_RAID_ATTRS=m
  16099. +
  16100. +CONFIG_ISCSI_TCP=m
  16101. +CONFIG_ISCSI_BOOT_SYSFS=m
  16102. +
  16103. +#
  16104. +# SCSI low-level drivers
  16105. +#
  16106. +CONFIG_BLK_DEV_3W_XXXX_RAID=m
  16107. +CONFIG_SCSI_3W_9XXX=m
  16108. +CONFIG_SCSI_ACARD=m
  16109. +CONFIG_SCSI_AACRAID=m
  16110. +CONFIG_SCSI_AIC7XXX=m
  16111. +# http://lists.fedoraproject.org/pipermail/kernel/2013-February/004102.html
  16112. +# CONFIG_SCSI_AIC7XXX_OLD is not set
  16113. +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
  16114. +CONFIG_AIC7XXX_RESET_DELAY_MS=15000
  16115. +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
  16116. +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
  16117. +CONFIG_AIC7XXX_DEBUG_MASK=0
  16118. +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
  16119. +CONFIG_SCSI_AIC79XX=m
  16120. +CONFIG_AIC79XX_CMDS_PER_DEVICE=4
  16121. +CONFIG_AIC79XX_RESET_DELAY_MS=15000
  16122. +# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
  16123. +# CONFIG_AIC79XX_DEBUG_ENABLE is not set
  16124. +CONFIG_AIC79XX_DEBUG_MASK=0
  16125. +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
  16126. +CONFIG_SCSI_AIC94XX=m
  16127. +# CONFIG_AIC94XX_DEBUG is not set
  16128. +# CONFIG_SCSI_ADVANSYS is not set
  16129. +CONFIG_SCSI_BFA_FC=m
  16130. +CONFIG_MEGARAID_NEWGEN=y
  16131. +CONFIG_MEGARAID_MM=m
  16132. +CONFIG_MEGARAID_MAILBOX=m
  16133. +CONFIG_MEGARAID_LEGACY=m
  16134. +CONFIG_MEGARAID_SAS=m
  16135. +CONFIG_SCSI_ESAS2R=m
  16136. +CONFIG_SCSI_MVSAS=m
  16137. +# CONFIG_SCSI_MVSAS_DEBUG is not set
  16138. +CONFIG_SCSI_MVSAS_TASKLET=y
  16139. +CONFIG_SCSI_MPT2SAS=m
  16140. +CONFIG_SCSI_MPT2SAS_MAX_SGE=128
  16141. +CONFIG_SCSI_MPT2SAS_LOGGING=y
  16142. +CONFIG_SCSI_MPT3SAS=m
  16143. +CONFIG_SCSI_MPT3SAS_MAX_SGE=128
  16144. +CONFIG_SCSI_MPT3SAS_LOGGING=y
  16145. +
  16146. +CONFIG_SCSI_UFSHCD=m
  16147. +CONFIG_SCSI_UFSHCD_PCI=m
  16148. +# CONFIG_SCSI_UFSHCD_PLATFORM is not set
  16149. +
  16150. +CONFIG_SCSI_MVUMI=m
  16151. +
  16152. +CONFIG_SCSI_OSD_INITIATOR=m
  16153. +CONFIG_SCSI_OSD_ULD=m
  16154. +CONFIG_SCSI_OSD_DPRINT_SENSE=1
  16155. +# CONFIG_SCSI_OSD_DEBUG is not set
  16156. +
  16157. +CONFIG_SCSI_BNX2_ISCSI=m
  16158. +CONFIG_SCSI_BNX2X_FCOE=m
  16159. +CONFIG_BE2ISCSI=m
  16160. +CONFIG_SCSI_PMCRAID=m
  16161. +
  16162. +CONFIG_SCSI_HPSA=m
  16163. +CONFIG_SCSI_3W_SAS=m
  16164. +CONFIG_SCSI_PM8001=m
  16165. +CONFIG_VMWARE_PVSCSI=m
  16166. +CONFIG_VMWARE_BALLOON=m
  16167. +
  16168. +CONFIG_SCSI_ARCMSR=m
  16169. +CONFIG_SCSI_BUSLOGIC=m
  16170. +CONFIG_SCSI_INITIO=m
  16171. +CONFIG_SCSI_FLASHPOINT=y
  16172. +CONFIG_SCSI_DMX3191D=m
  16173. +# CONFIG_SCSI_EATA is not set
  16174. +# CONFIG_SCSI_EATA_PIO is not set
  16175. +# CONFIG_SCSI_FUTURE_DOMAIN is not set
  16176. +CONFIG_SCSI_GDTH=m
  16177. +CONFIG_SCSI_HPTIOP=m
  16178. +CONFIG_SCSI_IPS=m
  16179. +CONFIG_SCSI_INIA100=m
  16180. +# CONFIG_SCSI_PPA is not set
  16181. +# CONFIG_SCSI_IMM is not set
  16182. +# CONFIG_SCSI_IZIP_EPP16 is not set
  16183. +# CONFIG_SCSI_IZIP_SLOW_CTR is not set
  16184. +CONFIG_SCSI_STEX=m
  16185. +CONFIG_SCSI_SYM53C8XX_2=m
  16186. +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
  16187. +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
  16188. +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
  16189. +CONFIG_SCSI_SYM53C8XX_MMIO=y
  16190. +CONFIG_SCSI_QLOGIC_1280=m
  16191. +CONFIG_SCSI_DC395x=m
  16192. +# CONFIG_SCSI_NSP32 is not set
  16193. +CONFIG_SCSI_DEBUG=m
  16194. +CONFIG_SCSI_DC390T=m
  16195. +CONFIG_SCSI_QLA_FC=m
  16196. +CONFIG_TCM_QLA2XXX=m
  16197. +CONFIG_SCSI_QLA_ISCSI=m
  16198. +CONFIG_SCSI_IPR=m
  16199. +CONFIG_SCSI_IPR_TRACE=y
  16200. +CONFIG_SCSI_IPR_DUMP=y
  16201. +# CONFIG_SCSI_DPT_I2O is not set
  16202. +CONFIG_SCSI_LPFC=m
  16203. +# CONFIG_SCSI_LPFC_DEBUG_FS is not set
  16204. +
  16205. +# PCMCIA SCSI adapter support
  16206. +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
  16207. +
  16208. +CONFIG_ATA_BMDMA=y
  16209. +CONFIG_ATA_VERBOSE_ERROR=y
  16210. +CONFIG_ATA_SFF=y
  16211. +CONFIG_ATA_PIIX=y
  16212. +# CONFIG_SATA_HIGHBANK is not set
  16213. +CONFIG_ATA_ACPI=y
  16214. +CONFIG_BLK_DEV_SX8=m
  16215. +CONFIG_PDC_ADMA=m
  16216. +CONFIG_SATA_AHCI=y
  16217. +CONFIG_SATA_INIC162X=m
  16218. +CONFIG_SATA_MV=m
  16219. +CONFIG_SATA_NV=m
  16220. +CONFIG_SATA_PMP=y
  16221. +CONFIG_SATA_PROMISE=m
  16222. +CONFIG_SATA_QSTOR=m
  16223. +CONFIG_SATA_RCAR=m
  16224. +CONFIG_SATA_SIL=m
  16225. +CONFIG_SATA_SIL24=m
  16226. +CONFIG_SATA_SIS=m
  16227. +CONFIG_SATA_SVW=m
  16228. +CONFIG_SATA_SX4=m
  16229. +CONFIG_SATA_ULI=m
  16230. +CONFIG_SATA_VIA=m
  16231. +CONFIG_SATA_VITESSE=m
  16232. +# CONFIG_SATA_ZPODD is not set
  16233. +CONFIG_SATA_ACARD_AHCI=m
  16234. +
  16235. +# CONFIG_PATA_LEGACY is not set
  16236. +CONFIG_PATA_ACPI=m
  16237. +CONFIG_PATA_ALI=m
  16238. +CONFIG_PATA_AMD=m
  16239. +CONFIG_PATA_ARASAN_CF=m
  16240. +CONFIG_PATA_ARTOP=m
  16241. +CONFIG_PATA_ATIIXP=m
  16242. +CONFIG_PATA_CMD640_PCI=m
  16243. +CONFIG_PATA_CMD64X=m
  16244. +CONFIG_PATA_CS5520=m
  16245. +CONFIG_PATA_CS5530=m
  16246. +CONFIG_PATA_CS5535=m
  16247. +CONFIG_PATA_CS5536=m
  16248. +CONFIG_PATA_CYPRESS=m
  16249. +CONFIG_PATA_EFAR=m
  16250. +CONFIG_ATA_GENERIC=m
  16251. +CONFIG_PATA_HPT366=m
  16252. +CONFIG_PATA_HPT37X=m
  16253. +CONFIG_PATA_HPT3X2N=m
  16254. +CONFIG_PATA_HPT3X3=m
  16255. +# CONFIG_PATA_HPT3X3_DMA is not set
  16256. +CONFIG_PATA_IT821X=m
  16257. +CONFIG_PATA_IT8213=m
  16258. +CONFIG_PATA_JMICRON=m
  16259. +CONFIG_PATA_NINJA32=m
  16260. +CONFIG_PATA_MARVELL=m
  16261. +CONFIG_PATA_MPIIX=m
  16262. +CONFIG_PATA_NETCELL=m
  16263. +CONFIG_PATA_NS87410=m
  16264. +CONFIG_PATA_NS87415=m
  16265. +CONFIG_PATA_OLDPIIX=m
  16266. +CONFIG_PATA_OPTI=m
  16267. +CONFIG_PATA_OPTIDMA=m
  16268. +CONFIG_PATA_PCMCIA=m
  16269. +CONFIG_PATA_PDC_OLD=m
  16270. +# CONFIG_PATA_RADISYS is not set
  16271. +CONFIG_PATA_RDC=m
  16272. +# CONFIG_PATA_RZ1000 is not set
  16273. +# CONFIG_PATA_SC1200 is not set
  16274. +CONFIG_PATA_SERVERWORKS=m
  16275. +CONFIG_PATA_PDC2027X=m
  16276. +CONFIG_PATA_SCH=m
  16277. +CONFIG_PATA_SIL680=m
  16278. +CONFIG_PATA_SIS=m
  16279. +CONFIG_PATA_TOSHIBA=m
  16280. +CONFIG_PATA_TRIFLEX=m
  16281. +CONFIG_PATA_VIA=m
  16282. +CONFIG_PATA_WINBOND=m
  16283. +CONFIG_PATA_ATP867X=m
  16284. +
  16285. +
  16286. +#
  16287. +# Multi-device support (RAID and LVM)
  16288. +#
  16289. +CONFIG_MD=y
  16290. +CONFIG_BLK_DEV_MD=y
  16291. +CONFIG_MD_AUTODETECT=y
  16292. +CONFIG_MD_FAULTY=m
  16293. +CONFIG_MD_LINEAR=m
  16294. +CONFIG_MD_MULTIPATH=m
  16295. +CONFIG_MD_RAID0=m
  16296. +CONFIG_MD_RAID1=m
  16297. +CONFIG_MD_RAID10=m
  16298. +CONFIG_MD_RAID456=m
  16299. +
  16300. +CONFIG_BCACHE=m
  16301. +# CONFIG_BCACHE_DEBUG is not set
  16302. +# CONFIG_BCACHE_EDEBUG is not set
  16303. +# CONFIG_BCACHE_CLOSURES_DEBUG is not set
  16304. +
  16305. +# CONFIG_MULTICORE_RAID456 is not set
  16306. +CONFIG_ASYNC_RAID6_TEST=m
  16307. +CONFIG_BLK_DEV_DM=y
  16308. +CONFIG_DM_CRYPT=m
  16309. +CONFIG_DM_DEBUG=y
  16310. +CONFIG_DM_DELAY=m
  16311. +CONFIG_DM_MIRROR=y
  16312. +CONFIG_DM_MULTIPATH=m
  16313. +CONFIG_DM_SNAPSHOT=y
  16314. +CONFIG_DM_THIN_PROVISIONING=m
  16315. +CONFIG_DM_CACHE=m
  16316. +CONFIG_DM_CACHE_MQ=m
  16317. +CONFIG_DM_CACHE_CLEANER=m
  16318. +# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set
  16319. +# CONFIG_DM_DEBUG_SPACE_MAPS is not set
  16320. +CONFIG_DM_UEVENT=y
  16321. +CONFIG_DM_ZERO=y
  16322. +CONFIG_DM_LOG_USERSPACE=m
  16323. +CONFIG_DM_MULTIPATH_QL=m
  16324. +CONFIG_DM_MULTIPATH_ST=m
  16325. +CONFIG_DM_RAID=m
  16326. +CONFIG_DM_FLAKEY=m
  16327. +CONFIG_DM_VERITY=m
  16328. +CONFIG_DM_SWITCH=m
  16329. +
  16330. +#
  16331. +# Fusion MPT device support
  16332. +#
  16333. +CONFIG_FUSION=y
  16334. +CONFIG_FUSION_SPI=m
  16335. +CONFIG_FUSION_FC=m
  16336. +CONFIG_FUSION_MAX_SGE=40
  16337. +CONFIG_FUSION_CTL=m
  16338. +CONFIG_FUSION_LAN=m
  16339. +CONFIG_FUSION_SAS=m
  16340. +CONFIG_FUSION_LOGGING=y
  16341. +
  16342. +#
  16343. +# IEEE 1394 (FireWire) support (JUJU alternative stack)
  16344. +#
  16345. +CONFIG_FIREWIRE=m
  16346. +CONFIG_FIREWIRE_OHCI=m
  16347. +CONFIG_FIREWIRE_SBP2=m
  16348. +CONFIG_FIREWIRE_NET=m
  16349. +CONFIG_FIREWIRE_OHCI_DEBUG=y
  16350. +CONFIG_FIREWIRE_NOSY=m
  16351. +# CONFIG_FIREWIRE_SERIAL is not set
  16352. +# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set
  16353. +
  16354. +#
  16355. +# IEEE 1394 (FireWire) support
  16356. +#
  16357. +
  16358. +#
  16359. +# I2O device support
  16360. +#
  16361. +# CONFIG_I2O is not set
  16362. +# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
  16363. +
  16364. +#
  16365. +# Virtualization support drivers
  16366. +#
  16367. +# CONFIG_VIRT_DRIVERS is not set
  16368. +
  16369. +# Networking support
  16370. +#
  16371. +
  16372. +CONFIG_NET_DMA=y
  16373. +
  16374. +CONFIG_NETLINK_MMAP=y
  16375. +CONFIG_NETLINK_DIAG=m
  16376. +
  16377. +CONFIG_TCP_CONG_ADVANCED=y
  16378. +CONFIG_TCP_CONG_BIC=m
  16379. +CONFIG_TCP_CONG_CUBIC=y
  16380. +CONFIG_TCP_CONG_HTCP=m
  16381. +CONFIG_TCP_CONG_HSTCP=m
  16382. +CONFIG_TCP_CONG_HYBLA=m
  16383. +CONFIG_TCP_CONG_ILLINOIS=m
  16384. +CONFIG_TCP_CONG_LP=m
  16385. +CONFIG_TCP_CONG_SCALABLE=m
  16386. +CONFIG_TCP_CONG_VEGAS=m
  16387. +CONFIG_TCP_CONG_VENO=m
  16388. +CONFIG_TCP_CONG_WESTWOOD=m
  16389. +CONFIG_TCP_CONG_YEAH=m
  16390. +
  16391. +CONFIG_TCP_MD5SIG=y
  16392. +
  16393. +#
  16394. +# Networking options
  16395. +#
  16396. +CONFIG_PACKET_DIAG=m
  16397. +CONFIG_UNIX_DIAG=m
  16398. +CONFIG_NET_KEY=m
  16399. +CONFIG_NET_KEY_MIGRATE=y
  16400. +CONFIG_INET_TUNNEL=m
  16401. +CONFIG_INET_DIAG=m
  16402. +CONFIG_INET_UDP_DIAG=m
  16403. +CONFIG_IP_MULTICAST=y
  16404. +CONFIG_IP_ADVANCED_ROUTER=y
  16405. +CONFIG_IP_FIB_TRIE_STATS=y
  16406. +CONFIG_IP_MULTIPLE_TABLES=y
  16407. +CONFIG_IP_ROUTE_MULTIPATH=y
  16408. +CONFIG_IP_ROUTE_VERBOSE=y
  16409. +CONFIG_IP_NF_SECURITY=m
  16410. +CONFIG_NET_IPIP=m
  16411. +CONFIG_NET_IPGRE_DEMUX=m
  16412. +CONFIG_NET_IPGRE=m
  16413. +CONFIG_NET_IPGRE_BROADCAST=y
  16414. +CONFIG_IP_MROUTE=y
  16415. +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
  16416. +CONFIG_IP_PIMSM_V1=y
  16417. +CONFIG_IP_PIMSM_V2=y
  16418. +CONFIG_ARPD=y
  16419. +CONFIG_SYN_COOKIES=y
  16420. +CONFIG_NET_IPVTI=m
  16421. +CONFIG_INET_AH=m
  16422. +CONFIG_INET_ESP=m
  16423. +CONFIG_INET_IPCOMP=m
  16424. +CONFIG_NETCONSOLE=m
  16425. +CONFIG_NETCONSOLE_DYNAMIC=y
  16426. +CONFIG_NETPOLL_TRAP=y
  16427. +CONFIG_NET_POLL_CONTROLLER=y
  16428. +
  16429. +#
  16430. +# IP: Virtual Server Configuration
  16431. +#
  16432. +CONFIG_IP_VS=m
  16433. +# CONFIG_IP_VS_DEBUG is not set
  16434. +CONFIG_IP_VS_TAB_BITS=12
  16435. +CONFIG_IP_VS_PROTO_TCP=y
  16436. +CONFIG_IP_VS_PROTO_UDP=y
  16437. +CONFIG_IP_VS_PROTO_ESP=y
  16438. +CONFIG_IP_VS_PROTO_AH=y
  16439. +CONFIG_IP_VS_PROTO_SCTP=y
  16440. +CONFIG_IP_VS_IPV6=y
  16441. +CONFIG_IP_VS_RR=m
  16442. +CONFIG_IP_VS_WRR=m
  16443. +CONFIG_IP_VS_LC=m
  16444. +CONFIG_IP_VS_WLC=m
  16445. +CONFIG_IP_VS_LBLC=m
  16446. +CONFIG_IP_VS_LBLCR=m
  16447. +CONFIG_IP_VS_DH=m
  16448. +CONFIG_IP_VS_SH=m
  16449. +CONFIG_IP_VS_SED=m
  16450. +CONFIG_IP_VS_NQ=m
  16451. +
  16452. +#
  16453. +# IPVS SH scheduler
  16454. +#
  16455. +CONFIG_IP_VS_SH_TAB_BITS=8
  16456. +
  16457. +CONFIG_IP_VS_FTP=m
  16458. +CONFIG_IP_VS_PE_SIP=m
  16459. +
  16460. +CONFIG_IPV6_PRIVACY=y
  16461. +CONFIG_IPV6_ROUTER_PREF=y
  16462. +CONFIG_IPV6_ROUTE_INFO=y
  16463. +CONFIG_IPV6_OPTIMISTIC_DAD=y
  16464. +CONFIG_INET6_AH=m
  16465. +CONFIG_INET6_ESP=m
  16466. +CONFIG_INET6_IPCOMP=m
  16467. +CONFIG_IPV6_MIP6=y
  16468. +CONFIG_IPV6_VTI=m
  16469. +CONFIG_IPV6_SIT=m
  16470. +CONFIG_IPV6_SIT_6RD=y
  16471. +CONFIG_IPV6_TUNNEL=m
  16472. +# CONFIG_IPV6_GRE is not set
  16473. +CONFIG_IPV6_SUBTREES=y
  16474. +CONFIG_IPV6_MULTIPLE_TABLES=y
  16475. +CONFIG_IPV6_MROUTE=y
  16476. +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
  16477. +CONFIG_IPV6_PIMSM_V2=y
  16478. +
  16479. +CONFIG_RDS=m
  16480. +# CONFIG_RDS_DEBUG is not set
  16481. +CONFIG_RDS_RDMA=m
  16482. +CONFIG_RDS_TCP=m
  16483. +
  16484. +CONFIG_NET_9P=m
  16485. +CONFIG_NET_9P_VIRTIO=m
  16486. +# CONFIG_NET_9P_DEBUG is not set
  16487. +CONFIG_NET_9P_RDMA=m
  16488. +
  16489. +# CONFIG_DECNET is not set
  16490. +CONFIG_BRIDGE=m
  16491. +CONFIG_BRIDGE_IGMP_SNOOPING=y
  16492. +CONFIG_BRIDGE_VLAN_FILTERING=y
  16493. +
  16494. +# PHY timestamping adds overhead
  16495. +CONFIG_NETWORK_PHY_TIMESTAMPING=y
  16496. +
  16497. +CONFIG_NETFILTER_ADVANCED=y
  16498. +CONFIG_NF_CONNTRACK=m
  16499. +CONFIG_NETFILTER_NETLINK=m
  16500. +CONFIG_NETFILTER_NETLINK_ACCT=m
  16501. +CONFIG_NETFILTER_NETLINK_QUEUE=m
  16502. +CONFIG_NETFILTER_NETLINK_QUEUE_CT=y
  16503. +CONFIG_NETFILTER_NETLINK_LOG=m
  16504. +CONFIG_NETFILTER_TPROXY=m
  16505. +CONFIG_NETFILTER_XTABLES=y
  16506. +CONFIG_NETFILTER_XT_SET=m
  16507. +CONFIG_NETFILTER_XT_MARK=m
  16508. +CONFIG_NETFILTER_XT_CONNMARK=m
  16509. +
  16510. +CONFIG_NETFILTER_XT_TARGET_AUDIT=m
  16511. +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
  16512. +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
  16513. +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
  16514. +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
  16515. +CONFIG_NETFILTER_XT_TARGET_CT=m
  16516. +CONFIG_NETFILTER_XT_TARGET_DSCP=m
  16517. +CONFIG_NETFILTER_XT_TARGET_HMARK=m
  16518. +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
  16519. +CONFIG_NETFILTER_XT_TARGET_LED=m
  16520. +CONFIG_NETFILTER_XT_TARGET_LOG=m
  16521. +CONFIG_NETFILTER_XT_TARGET_MARK=m
  16522. +CONFIG_NETFILTER_XT_TARGET_NFLOG=m
  16523. +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
  16524. +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
  16525. +CONFIG_NETFILTER_XT_TARGET_RATEEST=m
  16526. +CONFIG_NETFILTER_XT_TARGET_SECMARK=m
  16527. +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
  16528. +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
  16529. +CONFIG_NETFILTER_XT_TARGET_TRACE=m
  16530. +CONFIG_NETFILTER_XT_TARGET_TEE=m
  16531. +CONFIG_NETFILTER_XT_TARGET_TPROXY=m
  16532. +
  16533. +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
  16534. +CONFIG_NETFILTER_XT_MATCH_BPF=m
  16535. +CONFIG_NETFILTER_XT_MATCH_CGROUP=m
  16536. +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
  16537. +CONFIG_NETFILTER_XT_MATCH_COMMENT=m
  16538. +CONFIG_NETFILTER_XT_MATCH_CPU=m
  16539. +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
  16540. +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
  16541. +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
  16542. +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
  16543. +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
  16544. +CONFIG_NETFILTER_XT_MATCH_DCCP=m
  16545. +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
  16546. +CONFIG_NETFILTER_XT_MATCH_DSCP=m
  16547. +CONFIG_NETFILTER_XT_MATCH_ECN=m
  16548. +CONFIG_NETFILTER_XT_MATCH_ESP=m
  16549. +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
  16550. +CONFIG_NETFILTER_XT_MATCH_HELPER=m
  16551. +CONFIG_NETFILTER_XT_MATCH_HL=m
  16552. +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m
  16553. +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
  16554. +CONFIG_NETFILTER_XT_MATCH_IPVS=m
  16555. +CONFIG_NETFILTER_XT_MATCH_L2TP=m
  16556. +CONFIG_NETFILTER_XT_MATCH_LENGTH=m
  16557. +CONFIG_NETFILTER_XT_MATCH_LIMIT=m
  16558. +CONFIG_NETFILTER_XT_MATCH_MAC=m
  16559. +CONFIG_NETFILTER_XT_MATCH_MARK=m
  16560. +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
  16561. +CONFIG_NETFILTER_XT_MATCH_NFACCT=m
  16562. +CONFIG_NETFILTER_XT_MATCH_OSF=m
  16563. +CONFIG_NETFILTER_XT_MATCH_OWNER=m
  16564. +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
  16565. +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
  16566. +CONFIG_NETFILTER_XT_MATCH_POLICY=m
  16567. +CONFIG_NETFILTER_XT_MATCH_QUOTA=m
  16568. +CONFIG_NETFILTER_XT_MATCH_RATEEST=m
  16569. +CONFIG_NETFILTER_XT_MATCH_REALM=m
  16570. +CONFIG_NETFILTER_XT_MATCH_RECENT=m
  16571. +CONFIG_NETFILTER_XT_MATCH_SCTP=m
  16572. +CONFIG_NETFILTER_XT_MATCH_SOCKET=m
  16573. +CONFIG_NETFILTER_XT_MATCH_STATE=y
  16574. +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
  16575. +CONFIG_NETFILTER_XT_MATCH_STRING=m
  16576. +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
  16577. +CONFIG_NETFILTER_XT_MATCH_TIME=m
  16578. +CONFIG_NETFILTER_XT_MATCH_U32=m
  16579. +
  16580. +# CONFIG_NETFILTER_DEBUG is not set
  16581. +CONFIG_BRIDGE_NETFILTER=y
  16582. +
  16583. +#
  16584. +# IP: Netfilter Configuration
  16585. +#
  16586. +
  16587. +CONFIG_NF_CONNTRACK_MARK=y
  16588. +CONFIG_NF_CONNTRACK_SECMARK=y
  16589. +CONFIG_NF_CONNTRACK_EVENTS=y
  16590. +CONFIG_NF_CONNTRACK_ZONES=y
  16591. +CONFIG_NF_CONNTRACK_PROCFS=y # check if contrack(8) in f17 supports netlink
  16592. +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
  16593. +CONFIG_NF_CONNTRACK_AMANDA=m
  16594. +CONFIG_NF_CONNTRACK_FTP=m
  16595. +CONFIG_NF_CONNTRACK_H323=m
  16596. +CONFIG_NF_CONNTRACK_IRC=m
  16597. +CONFIG_NF_CONNTRACK_NETBIOS_NS=m
  16598. +CONFIG_NF_CONNTRACK_PPTP=m
  16599. +CONFIG_NF_CONNTRACK_SANE=m
  16600. +CONFIG_NF_CONNTRACK_SIP=m
  16601. +CONFIG_NF_CONNTRACK_TFTP=m
  16602. +CONFIG_NF_CONNTRACK_IPV4=y
  16603. +CONFIG_NF_CONNTRACK_IPV6=y
  16604. +# CONFIG_NF_CONNTRACK_TIMEOUT is not set
  16605. +CONFIG_NF_CONNTRACK_TIMESTAMP=y
  16606. +CONFIG_NF_CONNTRACK_SNMP=m
  16607. +CONFIG_NF_NAT=m
  16608. +CONFIG_NF_NAT_SNMP_BASIC=m
  16609. +CONFIG_NF_CT_PROTO_DCCP=m
  16610. +CONFIG_NF_CT_PROTO_SCTP=m
  16611. +CONFIG_NF_CT_NETLINK=m
  16612. +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
  16613. +CONFIG_NF_CT_NETLINK_HELPER=m
  16614. +CONFIG_NF_CT_PROTO_UDPLITE=m
  16615. +
  16616. +CONFIG_IP_NF_MATCH_AH=m
  16617. +CONFIG_IP_NF_MATCH_ECN=m
  16618. +CONFIG_IP_NF_MATCH_RPFILTER=m
  16619. +CONFIG_IP_NF_MATCH_TTL=m
  16620. +CONFIG_IP_NF_TARGET_CLUSTERIP=m
  16621. +CONFIG_IP_NF_TARGET_REDIRECT=m
  16622. +CONFIG_IP_NF_TARGET_NETMAP=m
  16623. +CONFIG_IP_NF_TARGET_ECN=m
  16624. +CONFIG_IP_NF_TARGET_LOG=m
  16625. +CONFIG_IP_NF_TARGET_ULOG=m
  16626. +CONFIG_IP_NF_TARGET_REJECT=y
  16627. +CONFIG_IP_NF_TARGET_SYNPROXY=m
  16628. +CONFIG_IP_NF_TARGET_TTL=m
  16629. +CONFIG_NF_NAT_IPV4=m
  16630. +CONFIG_IP_NF_TARGET_MASQUERADE=m
  16631. +CONFIG_IP_NF_MANGLE=m
  16632. +CONFIG_IP_NF_ARPTABLES=m
  16633. +CONFIG_IP_NF_ARPFILTER=m
  16634. +CONFIG_IP_NF_ARP_MANGLE=m
  16635. +CONFIG_IP_NF_QUEUE=m
  16636. +CONFIG_IP_NF_RAW=m
  16637. +
  16638. +CONFIG_IP_NF_IPTABLES=y
  16639. +CONFIG_IP_NF_FILTER=y
  16640. +
  16641. +#
  16642. +# IPv6: Netfilter Configuration
  16643. +#
  16644. +CONFIG_IP6_NF_FILTER=m
  16645. +CONFIG_IP6_NF_IPTABLES=m
  16646. +CONFIG_IP6_NF_MANGLE=m
  16647. +CONFIG_IP6_NF_MATCH_AH=m
  16648. +CONFIG_IP6_NF_MATCH_EUI64=m
  16649. +CONFIG_IP6_NF_MATCH_FRAG=m
  16650. +CONFIG_IP6_NF_MATCH_HL=m
  16651. +CONFIG_IP6_NF_MATCH_IPV6HEADER=m
  16652. +CONFIG_IP6_NF_MATCH_MH=m
  16653. +CONFIG_IP6_NF_MATCH_RPFILTER=m
  16654. +CONFIG_IP6_NF_MATCH_OPTS=m
  16655. +CONFIG_IP6_NF_MATCH_RT=m
  16656. +CONFIG_IP6_NF_QUEUE=m
  16657. +CONFIG_IP6_NF_RAW=m
  16658. +CONFIG_IP6_NF_SECURITY=m
  16659. +CONFIG_IP6_NF_TARGET_LOG=m
  16660. +CONFIG_IP6_NF_TARGET_REJECT=m
  16661. +CONFIG_IP6_NF_TARGET_SYNPROXY=m
  16662. +CONFIG_IP6_NF_TARGET_HL=m
  16663. +CONFIG_NF_NAT_IPV6=m
  16664. +CONFIG_IP6_NF_TARGET_MASQUERADE=m
  16665. +# CONFIG_IP6_NF_TARGET_NPT is not set
  16666. +
  16667. +# nf_tables support
  16668. +CONFIG_NF_TABLES=m
  16669. +CONFIG_NF_TABLES_INET=m
  16670. +CONFIG_NFT_EXTHDR=m
  16671. +CONFIG_NFT_META=m
  16672. +CONFIG_NFT_CT=m
  16673. +CONFIG_NFT_RBTREE=m
  16674. +CONFIG_NFT_HASH=m
  16675. +CONFIG_NFT_COUNTER=m
  16676. +CONFIG_NFT_LOG=m
  16677. +CONFIG_NFT_LIMIT=m
  16678. +CONFIG_NFT_NAT=m
  16679. +CONFIG_NFT_QUEUE=m
  16680. +CONFIG_NFT_REJECT=m
  16681. +CONFIG_NFT_COMPAT=m
  16682. +
  16683. +CONFIG_NF_TABLES_IPV4=m
  16684. +CONFIG_NFT_REJECT_IPV4=m
  16685. +CONFIG_NFT_CHAIN_ROUTE_IPV4=m
  16686. +CONFIG_NFT_CHAIN_NAT_IPV4=m
  16687. +CONFIG_NF_TABLES_ARP=m
  16688. +
  16689. +CONFIG_NF_TABLES_IPV6=m
  16690. +CONFIG_NFT_CHAIN_ROUTE_IPV6=m
  16691. +CONFIG_NFT_CHAIN_NAT_IPV6=m
  16692. +
  16693. +CONFIG_NF_TABLES_BRIDGE=m
  16694. +#
  16695. +# Bridge: Netfilter Configuration
  16696. +#
  16697. +CONFIG_BRIDGE_NF_EBTABLES=m
  16698. +CONFIG_BRIDGE_EBT_802_3=m
  16699. +CONFIG_BRIDGE_EBT_AMONG=m
  16700. +CONFIG_BRIDGE_EBT_ARP=m
  16701. +CONFIG_BRIDGE_EBT_ARPREPLY=m
  16702. +CONFIG_BRIDGE_EBT_BROUTE=m
  16703. +CONFIG_BRIDGE_EBT_DNAT=m
  16704. +CONFIG_BRIDGE_EBT_IP=m
  16705. +CONFIG_BRIDGE_EBT_IP6=m
  16706. +CONFIG_BRIDGE_EBT_LIMIT=m
  16707. +CONFIG_BRIDGE_EBT_LOG=m
  16708. +CONFIG_BRIDGE_EBT_MARK=m
  16709. +CONFIG_BRIDGE_EBT_MARK_T=m
  16710. +CONFIG_BRIDGE_EBT_NFLOG=m
  16711. +CONFIG_BRIDGE_EBT_PKTTYPE=m
  16712. +CONFIG_BRIDGE_EBT_REDIRECT=m
  16713. +CONFIG_BRIDGE_EBT_SNAT=m
  16714. +CONFIG_BRIDGE_EBT_STP=m
  16715. +CONFIG_BRIDGE_EBT_T_FILTER=m
  16716. +CONFIG_BRIDGE_EBT_T_NAT=m
  16717. +CONFIG_BRIDGE_EBT_ULOG=m
  16718. +CONFIG_BRIDGE_EBT_VLAN=m
  16719. +CONFIG_XFRM=y
  16720. +CONFIG_XFRM_MIGRATE=y
  16721. +CONFIG_XFRM_SUB_POLICY=y
  16722. +CONFIG_XFRM_STATISTICS=y
  16723. +CONFIG_XFRM_USER=y
  16724. +CONFIG_INET6_XFRM_MODE_TRANSPORT=m
  16725. +CONFIG_INET6_XFRM_MODE_TUNNEL=m
  16726. +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
  16727. +CONFIG_INET6_XFRM_MODE_BEET=m
  16728. +
  16729. +CONFIG_IP_SET=m
  16730. +CONFIG_IP_SET_MAX=256
  16731. +CONFIG_IP_SET_BITMAP_IP=m
  16732. +CONFIG_IP_SET_BITMAP_IPMAC=m
  16733. +CONFIG_IP_SET_BITMAP_PORT=m
  16734. +CONFIG_IP_SET_HASH_IP=m
  16735. +CONFIG_IP_SET_HASH_IPPORT=m
  16736. +CONFIG_IP_SET_HASH_IPPORTIP=m
  16737. +CONFIG_IP_SET_HASH_IPPORTNET=m
  16738. +CONFIG_IP_SET_HASH_NETPORTNET=m
  16739. +CONFIG_IP_SET_HASH_NET=m
  16740. +CONFIG_IP_SET_HASH_NETNET=m
  16741. +CONFIG_IP_SET_HASH_NETPORT=m
  16742. +CONFIG_IP_SET_HASH_NETIFACE=m
  16743. +CONFIG_IP_SET_LIST_SET=m
  16744. +
  16745. +#
  16746. +# SCTP Configuration (EXPERIMENTAL)
  16747. +#
  16748. +CONFIG_IP_SCTP=m
  16749. +CONFIG_NET_SCTPPROBE=m
  16750. +# CONFIG_SCTP_DBG_MSG is not set
  16751. +# CONFIG_SCTP_DBG_OBJCNT is not set
  16752. +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1=y
  16753. +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5 is not set
  16754. +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
  16755. +CONFIG_SCTP_COOKIE_HMAC_MD5=y
  16756. +CONFIG_SCTP_COOKIE_HMAC_SHA1=y
  16757. +CONFIG_ATM=m
  16758. +CONFIG_VLAN_8021Q_GVRP=y
  16759. +CONFIG_VLAN_8021Q_MVRP=y
  16760. +CONFIG_LLC=m
  16761. +# CONFIG_LLC2 is not set
  16762. +CONFIG_IPX=m
  16763. +# CONFIG_IPX_INTERN is not set
  16764. +CONFIG_ATALK=m
  16765. +CONFIG_DEV_APPLETALK=m
  16766. +CONFIG_IPDDP=m
  16767. +CONFIG_IPDDP_ENCAP=y
  16768. +CONFIG_IPDDP_DECAP=y
  16769. +# CONFIG_X25 is not set
  16770. +# CONFIG_LAPB is not set
  16771. +# CONFIG_ECONET is not set
  16772. +CONFIG_WAN_ROUTER=m
  16773. +CONFIG_IP_DCCP=m
  16774. +CONFIG_IP_DCCP_CCID2=m
  16775. +# CONFIG_IP_DCCP_CCID2_DEBUG is not set
  16776. +CONFIG_IP_DCCP_CCID3=y
  16777. +# CONFIG_IP_DCCP_CCID3_DEBUG is not set
  16778. +# CONFIG_IP_DCCP_DEBUG is not set
  16779. +# CONFIG_NET_DCCPPROBE is not set
  16780. +
  16781. +#
  16782. +# TIPC Configuration (EXPERIMENTAL)
  16783. +#
  16784. +CONFIG_TIPC=m
  16785. +CONFIG_TIPC_PORTS=8192
  16786. +# CONFIG_TIPC_MEDIA_IB is not set
  16787. +# CONFIG_TIPC_ADVANCED is not set
  16788. +# CONFIG_TIPC_DEBUG is not set
  16789. +
  16790. +CONFIG_NETLABEL=y
  16791. +
  16792. +#
  16793. +# QoS and/or fair queueing
  16794. +#
  16795. +CONFIG_NET_SCHED=y
  16796. +CONFIG_NET_SCH_CBQ=m
  16797. +CONFIG_NET_SCH_DSMARK=m
  16798. +CONFIG_NET_SCH_DRR=m
  16799. +CONFIG_NET_SCH_GRED=m
  16800. +CONFIG_NET_SCH_HFSC=m
  16801. +CONFIG_NET_SCH_HTB=m
  16802. +CONFIG_NET_SCH_INGRESS=m
  16803. +CONFIG_NET_SCH_NETEM=m
  16804. +CONFIG_NET_SCH_PRIO=m
  16805. +CONFIG_NET_SCH_RED=m
  16806. +CONFIG_NET_SCH_SFQ=m
  16807. +CONFIG_NET_SCH_TBF=m
  16808. +CONFIG_NET_SCH_TEQL=m
  16809. +CONFIG_NET_SCH_SFB=m
  16810. +CONFIG_NET_SCH_MQPRIO=m
  16811. +CONFIG_NET_SCH_MULTIQ=m
  16812. +CONFIG_NET_SCH_CHOKE=m
  16813. +CONFIG_NET_SCH_QFQ=m
  16814. +CONFIG_NET_SCH_CODEL=m
  16815. +CONFIG_NET_SCH_FQ_CODEL=m
  16816. +CONFIG_NET_SCH_FQ=m
  16817. +CONFIG_NET_SCH_HHF=m
  16818. +CONFIG_NET_SCH_PIE=m
  16819. +CONFIG_NET_SCH_PLUG=m
  16820. +CONFIG_NET_CLS=y
  16821. +CONFIG_NET_CLS_ACT=y
  16822. +CONFIG_NET_CLS_BASIC=m
  16823. +CONFIG_NET_CLS_CGROUP=y
  16824. +CONFIG_NET_CLS_BPF=m
  16825. +CONFIG_NET_CLS_FLOW=m
  16826. +CONFIG_NET_CLS_FW=m
  16827. +CONFIG_NET_CLS_IND=y
  16828. +CONFIG_NET_CLS_ROUTE4=m
  16829. +CONFIG_NET_CLS_ROUTE=y
  16830. +CONFIG_NET_CLS_RSVP=m
  16831. +CONFIG_NET_CLS_RSVP6=m
  16832. +CONFIG_NET_CLS_TCINDEX=m
  16833. +CONFIG_NET_CLS_U32=m
  16834. +CONFIG_CLS_U32_MARK=y
  16835. +CONFIG_CLS_U32_PERF=y
  16836. +CONFIG_NET_EMATCH=y
  16837. +CONFIG_NET_EMATCH_CMP=m
  16838. +CONFIG_NET_EMATCH_META=m
  16839. +CONFIG_NET_EMATCH_NBYTE=m
  16840. +CONFIG_NET_EMATCH_STACK=32
  16841. +CONFIG_NET_EMATCH_TEXT=m
  16842. +CONFIG_NET_EMATCH_IPSET=m
  16843. +CONFIG_NET_EMATCH_U32=m
  16844. +
  16845. +CONFIG_NET_ACT_CSUM=m
  16846. +CONFIG_NET_ACT_GACT=m
  16847. +CONFIG_GACT_PROB=y
  16848. +CONFIG_NET_ACT_IPT=m
  16849. +CONFIG_NET_ACT_MIRRED=m
  16850. +CONFIG_NET_ACT_NAT=m
  16851. +CONFIG_NET_ACT_PEDIT=m
  16852. +CONFIG_NET_ACT_POLICE=m
  16853. +CONFIG_NET_ACT_SIMP=m
  16854. +CONFIG_NET_ACT_SKBEDIT=m
  16855. +
  16856. +CONFIG_DCB=y
  16857. +CONFIG_DNS_RESOLVER=m
  16858. +CONFIG_BATMAN_ADV=m
  16859. +CONFIG_BATMAN_ADV_BLA=y
  16860. +CONFIG_BATMAN_ADV_DAT=y
  16861. +CONFIG_BATMAN_ADV_NC=y
  16862. +
  16863. +# CONFIG_BATMAN_ADV_DEBUG is not set
  16864. +CONFIG_OPENVSWITCH=m
  16865. +CONFIG_OPENVSWITCH_GRE=y
  16866. +CONFIG_OPENVSWITCH_VXLAN=y
  16867. +CONFIG_VSOCKETS=m
  16868. +
  16869. +
  16870. +#
  16871. +# Network testing
  16872. +#
  16873. +CONFIG_NET_PKTGEN=m
  16874. +# CONFIG_NET_TCPPROBE is not set
  16875. +CONFIG_NET_DROP_MONITOR=y
  16876. +
  16877. +# disable later --kyle
  16878. +
  16879. +#
  16880. +# ARCnet devices
  16881. +#
  16882. +# CONFIG_ARCNET is not set
  16883. +CONFIG_IFB=m
  16884. +CONFIG_NET_TEAM=m
  16885. +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
  16886. +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
  16887. +CONFIG_NET_TEAM_MODE_LOADBALANCE=m
  16888. +CONFIG_NET_TEAM_MODE_BROADCAST=m
  16889. +CONFIG_NET_TEAM_MODE_RANDOM=m
  16890. +CONFIG_DUMMY=m
  16891. +CONFIG_BONDING=m
  16892. +CONFIG_MACVLAN=m
  16893. +CONFIG_MACVTAP=m
  16894. +CONFIG_VXLAN=m
  16895. +CONFIG_EQUALIZER=m
  16896. +CONFIG_TUN=m
  16897. +CONFIG_VETH=m
  16898. +CONFIG_NLMON=m
  16899. +
  16900. +#
  16901. +# ATM
  16902. +#
  16903. +CONFIG_ATM_DRIVERS=y
  16904. +# CONFIG_ATM_DUMMY is not set
  16905. +CONFIG_ATM_CLIP=m
  16906. +CONFIG_ATM_LANE=m
  16907. +CONFIG_ATM_BR2684=m
  16908. +CONFIG_NET_SCH_ATM=m
  16909. +CONFIG_ATM_TCP=m
  16910. +# CONFIG_ATM_LANAI is not set
  16911. +CONFIG_ATM_ENI=m
  16912. +CONFIG_ATM_FIRESTREAM=m
  16913. +# CONFIG_ATM_ZATM is not set
  16914. +# CONFIG_ATM_IDT77252 is not set
  16915. +# CONFIG_ATM_AMBASSADOR is not set
  16916. +# CONFIG_ATM_HORIZON is not set
  16917. +# CONFIG_ATM_FORE200E is not set
  16918. +# CONFIG_ATM_FORE200E_USE_TASKLET is not set
  16919. +CONFIG_ATM_FORE200E_TX_RETRY=16
  16920. +CONFIG_ATM_FORE200E_DEBUG=0
  16921. +
  16922. +CONFIG_ATM_HE=m
  16923. +CONFIG_PPTP=m
  16924. +CONFIG_PPPOATM=m
  16925. +CONFIG_PPPOL2TP=m
  16926. +CONFIG_ATM_NICSTAR=m
  16927. +# CONFIG_ATM_IA is not set
  16928. +# CONFIG_ATM_CLIP_NO_ICMP is not set
  16929. +# CONFIG_ATM_MPOA is not set
  16930. +# CONFIG_ATM_BR2684_IPFILTER is not set
  16931. +# CONFIG_ATM_ENI_DEBUG is not set
  16932. +# CONFIG_ATM_ENI_TUNE_BURST is not set
  16933. +# CONFIG_ATM_ZATM_DEBUG is not set
  16934. +# CONFIG_ATM_IDT77252_DEBUG is not set
  16935. +# CONFIG_ATM_IDT77252_RCV_ALL is not set
  16936. +# CONFIG_ATM_AMBASSADOR_DEBUG is not set
  16937. +# CONFIG_ATM_HORIZON_DEBUG is not set
  16938. +# CONFIG_ATM_HE_USE_SUNI is not set
  16939. +# CONFIG_ATM_NICSTAR_USE_SUNI is not set
  16940. +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
  16941. +# CONFIG_ATM_IA_DEBUG is not set
  16942. +CONFIG_ATM_SOLOS=m
  16943. +
  16944. +CONFIG_L2TP=m
  16945. +CONFIG_L2TP_V3=y
  16946. +CONFIG_L2TP_IP=m
  16947. +CONFIG_L2TP_ETH=m
  16948. +
  16949. +# CONFIG_CAIF is not set
  16950. +
  16951. +CONFIG_RFKILL=m
  16952. +CONFIG_RFKILL_GPIO=m
  16953. +CONFIG_RFKILL_INPUT=y
  16954. +
  16955. +
  16956. +#
  16957. +# Ethernet (10 or 100Mbit)
  16958. +#
  16959. +
  16960. +CONFIG_NET_VENDOR_ADAPTEC=y
  16961. +CONFIG_ADAPTEC_STARFIRE=m
  16962. +
  16963. +CONFIG_NET_VENDOR_ALTEON=y
  16964. +CONFIG_ACENIC=m
  16965. +# CONFIG_ACENIC_OMIT_TIGON_I is not set
  16966. +
  16967. +CONFIG_NET_VENDOR_AMD=y
  16968. +CONFIG_PCNET32=m
  16969. +CONFIG_AMD8111_ETH=m
  16970. +CONFIG_PCMCIA_NMCLAN=m
  16971. +
  16972. +CONFIG_NET_VENDOR_ARC=y
  16973. +CONFIG_ARC_EMAC=m
  16974. +
  16975. +CONFIG_NET_VENDOR_ATHEROS=y
  16976. +CONFIG_ALX=m
  16977. +CONFIG_ATL2=m
  16978. +CONFIG_ATL1=m
  16979. +CONFIG_ATL1C=m
  16980. +CONFIG_ATL1E=m
  16981. +CONFIG_NET_CADENCE=y
  16982. +CONFIG_ARM_AT91_ETHER=m
  16983. +CONFIG_MACB=m
  16984. +
  16985. +CONFIG_NET_VENDOR_BROCADE=y
  16986. +CONFIG_BNA=m
  16987. +CONFIG_NET_CALXEDA_XGMAC=m
  16988. +
  16989. +CONFIG_NET_VENDOR_CHELSIO=y
  16990. +CONFIG_CHELSIO_T1=m
  16991. +CONFIG_CHELSIO_T1_1G=y
  16992. +CONFIG_CHELSIO_T3=m
  16993. +CONFIG_CHELSIO_T4=m
  16994. +CONFIG_CHELSIO_T4VF=m
  16995. +
  16996. +CONFIG_NET_VENDOR_CISCO=y
  16997. +CONFIG_ENIC=m
  16998. +
  16999. +CONFIG_NET_VENDOR_DEC=y
  17000. +#
  17001. +# Tulip family network device support
  17002. +#
  17003. +CONFIG_NET_TULIP=y
  17004. +CONFIG_DE2104X=m
  17005. +CONFIG_DE2104X_DSL=0
  17006. +CONFIG_TULIP=m
  17007. +# CONFIG_TULIP_NAPI is not set
  17008. +# CONFIG_TULIP_MWI is not set
  17009. +CONFIG_TULIP_MMIO=y
  17010. +# CONFIG_NI5010 is not set
  17011. +CONFIG_DE4X5=m
  17012. +CONFIG_WINBOND_840=m
  17013. +CONFIG_DM9102=m
  17014. +CONFIG_PCMCIA_XIRCOM=m
  17015. +CONFIG_ULI526X=m
  17016. +
  17017. +CONFIG_NET_VENDOR_DLINK=y
  17018. +CONFIG_DE600=m
  17019. +CONFIG_DE620=m
  17020. +CONFIG_DL2K=m
  17021. +CONFIG_SUNDANCE=m
  17022. +# CONFIG_SUNDANCE_MMIO is not set
  17023. +
  17024. +CONFIG_NET_VENDOR_EMULEX=y
  17025. +CONFIG_BE2NET=m
  17026. +
  17027. +CONFIG_NET_VENDOR_EXAR=y
  17028. +CONFIG_S2IO=m
  17029. +CONFIG_VXGE=m
  17030. +# CONFIG_VXGE_DEBUG_TRACE_ALL is not set
  17031. +
  17032. +# CONFIG_NET_VENDOR_FARADAY is not set
  17033. +# CONFIG_NET_VENDOR_FUJITSU is not set
  17034. +# CONFIG_NET_VENDOR_HP is not set
  17035. +CONFIG_NET_VENDOR_INTEL=y
  17036. +CONFIG_E100=m
  17037. +CONFIG_E1000=m
  17038. +CONFIG_E1000E=m
  17039. +CONFIG_IGB=m
  17040. +CONFIG_IGB_HWMON=y
  17041. +CONFIG_IGB_DCA=y
  17042. +CONFIG_IGB_PTP=y
  17043. +CONFIG_IGBVF=m
  17044. +CONFIG_IXGB=m
  17045. +CONFIG_IXGBEVF=m
  17046. +CONFIG_IXGBE=m
  17047. +CONFIG_IXGBE_DCA=y
  17048. +CONFIG_IXGBE_DCB=y
  17049. +CONFIG_IXGBE_HWMON=y
  17050. +CONFIG_IXGBE_PTP=y
  17051. +CONFIG_I40E=m
  17052. +# CONFIG_I40E_VXLAN is not set
  17053. +# CONFIG_I40E_DCB is not set
  17054. +# CONFIG_I40EVF is not set
  17055. +
  17056. +
  17057. +# CONFIG_NET_VENDOR_I825XX is not set
  17058. +CONFIG_NET_VENDOR_MARVELL=y
  17059. +CONFIG_MVMDIO=m
  17060. +CONFIG_SKGE=m
  17061. +# CONFIG_SKGE_DEBUG is not set
  17062. +CONFIG_SKGE_GENESIS=y
  17063. +CONFIG_SKY2=m
  17064. +# CONFIG_SKY2_DEBUG is not set
  17065. +
  17066. +CONFIG_NET_VENDOR_MICREL=y
  17067. +CONFIG_KSZ884X_PCI=m
  17068. +# CONFIG_KS8842 is not set
  17069. +# CONFIG_KS8851_MLL is not set
  17070. +
  17071. +CONFIG_NET_VENDOR_MYRI=y
  17072. +CONFIG_MYRI10GE=m
  17073. +CONFIG_MYRI10GE_DCA=y
  17074. +
  17075. +CONFIG_NATSEMI=m
  17076. +CONFIG_NS83820=m
  17077. +
  17078. +CONFIG_PCMCIA_AXNET=m
  17079. +CONFIG_NE2K_PCI=m
  17080. +CONFIG_NE3210=m
  17081. +CONFIG_PCMCIA_PCNET=m
  17082. +
  17083. +CONFIG_NET_VENDOR_NVIDIA=y
  17084. +CONFIG_FORCEDETH=m
  17085. +
  17086. +CONFIG_NET_VENDOR_OKI=y
  17087. +# CONFIG_PCH_GBE is not set
  17088. +# CONFIG_PCH_PTP is not set
  17089. +
  17090. +CONFIG_NET_PACKET_ENGINE=y
  17091. +CONFIG_HAMACHI=m
  17092. +CONFIG_YELLOWFIN=m
  17093. +
  17094. +CONFIG_NET_VENDOR_QLOGIC=y
  17095. +CONFIG_QLA3XXX=m
  17096. +CONFIG_QLCNIC=m
  17097. +CONFIG_QLCNIC_SRIOV=y
  17098. +CONFIG_QLCNIC_DCB=y
  17099. +CONFIG_QLGE=m
  17100. +CONFIG_NETXEN_NIC=m
  17101. +
  17102. +CONFIG_NET_VENDOR_REALTEK=y
  17103. +CONFIG_ATP=m
  17104. +CONFIG_8139CP=m
  17105. +CONFIG_8139TOO=m
  17106. +# CONFIG_8139TOO_PIO is not set
  17107. +# CONFIG_8139TOO_TUNE_TWISTER is not set
  17108. +CONFIG_8139TOO_8129=y
  17109. +# CONFIG_8139_OLD_RX_RESET is not set
  17110. +CONFIG_R8169=m
  17111. +
  17112. +
  17113. +CONFIG_NET_VENDOR_RDC=y
  17114. +CONFIG_R6040=m
  17115. +
  17116. +
  17117. +CONFIG_NET_VENDOR_SILAN=y
  17118. +CONFIG_SC92031=m
  17119. +
  17120. +CONFIG_NET_VENDOR_SIS=y
  17121. +CONFIG_SIS900=m
  17122. +CONFIG_SIS190=m
  17123. +
  17124. +CONFIG_PCMCIA_SMC91C92=m
  17125. +CONFIG_EPIC100=m
  17126. +CONFIG_SMSC9420=m
  17127. +
  17128. +# CONFIG_STMMAC_PLATFORM is not set
  17129. +# CONFIG_STMMAC_PCI is not set
  17130. +# CONFIG_STMMAC_DA is not set
  17131. +# CONFIG_STMMAC_DUAL_MAC is not set
  17132. +# CONFIG_STMMAC_TIMER is not set
  17133. +# CONFIG_STMMAC_DEBUG_FS is not set
  17134. +
  17135. +CONFIG_NET_VENDOR_SUN=y
  17136. +CONFIG_HAPPYMEAL=m
  17137. +CONFIG_SUNGEM=m
  17138. +CONFIG_CASSINI=m
  17139. +CONFIG_NIU=m
  17140. +
  17141. +CONFIG_NET_VENDOR_TEHUTI=y
  17142. +CONFIG_TEHUTI=m
  17143. +
  17144. +CONFIG_NET_VENDOR_TI=y
  17145. +CONFIG_TLAN=m
  17146. +
  17147. +CONFIG_VIA_RHINE=m
  17148. +CONFIG_VIA_RHINE_MMIO=y
  17149. +
  17150. +CONFIG_WIZNET_W5100=m
  17151. +CONFIG_WIZNET_W5300=m
  17152. +CONFIG_NET_VENDOR_XIRCOM=y
  17153. +CONFIG_PCMCIA_XIRC2PS=m
  17154. +
  17155. +CONFIG_AMD_PHY=m
  17156. +CONFIG_BROADCOM_PHY=m
  17157. +CONFIG_BCM87XX_PHY=m
  17158. +CONFIG_CICADA_PHY=m
  17159. +CONFIG_DAVICOM_PHY=m
  17160. +CONFIG_DP83640_PHY=m
  17161. +CONFIG_FIXED_PHY=y
  17162. +CONFIG_MDIO_BITBANG=m
  17163. +CONFIG_NATIONAL_PHY=m
  17164. +CONFIG_ICPLUS_PHY=m
  17165. +CONFIG_BCM63XX_PHY=m
  17166. +CONFIG_LSI_ET1011C_PHY=m
  17167. +CONFIG_LXT_PHY=m
  17168. +CONFIG_MARVELL_PHY=m
  17169. +CONFIG_QSEMI_PHY=m
  17170. +CONFIG_REALTEK_PHY=m
  17171. +CONFIG_SMSC_PHY=m
  17172. +CONFIG_STE10XP=m
  17173. +CONFIG_VITESSE_PHY=m
  17174. +CONFIG_MICREL_PHY=m
  17175. +
  17176. +CONFIG_MII=m
  17177. +CONFIG_NET_CORE=y
  17178. +CONFIG_NET_VENDOR_3COM=y
  17179. +CONFIG_VORTEX=m
  17180. +CONFIG_TYPHOON=m
  17181. +CONFIG_DNET=m
  17182. +
  17183. +
  17184. +CONFIG_LNE390=m
  17185. +CONFIG_ES3210=m
  17186. +CONFIG_NET_PCI=y
  17187. +CONFIG_B44=m
  17188. +CONFIG_B44_PCI=y
  17189. +CONFIG_BNX2=m
  17190. +CONFIG_BNX2X=m
  17191. +CONFIG_BNX2X_SRIOV=y
  17192. +CONFIG_CNIC=m
  17193. +CONFIG_FEALNX=m
  17194. +CONFIG_NET_POCKET=y
  17195. +
  17196. +#
  17197. +# Ethernet (1000 Mbit)
  17198. +#
  17199. +CONFIG_TIGON3=m
  17200. +CONFIG_JME=m
  17201. +
  17202. +#
  17203. +# Ethernet (10000 Mbit)
  17204. +#
  17205. +# CONFIG_IP1000 is not set
  17206. +# CONFIG_MLX4_EN is not set
  17207. +# CONFIG_SFC is not set
  17208. +
  17209. +# CONFIG_FDDI is not set
  17210. +# CONFIG_DEFXX is not set
  17211. +# CONFIG_SKFP is not set
  17212. +# CONFIG_HIPPI is not set
  17213. +# CONFIG_PLIP is not set
  17214. +CONFIG_PPP=m
  17215. +CONFIG_PPP_MULTILINK=y
  17216. +CONFIG_PPP_FILTER=y
  17217. +CONFIG_PPP_ASYNC=m
  17218. +CONFIG_PPP_SYNC_TTY=m
  17219. +CONFIG_PPP_DEFLATE=m
  17220. +CONFIG_IPPP_FILTER=y
  17221. +CONFIG_PPP_BSDCOMP=y
  17222. +CONFIG_PPPOE=m
  17223. +CONFIG_PPP_MPPE=m
  17224. +CONFIG_SLIP=m
  17225. +CONFIG_SLIP_COMPRESSED=y
  17226. +CONFIG_SLIP_SMART=y
  17227. +# CONFIG_SLIP_MODE_SLIP6 is not set
  17228. +
  17229. +#
  17230. +# Wireless LAN
  17231. +#
  17232. +#
  17233. +# CONFIG_STRIP is not set
  17234. +# CONFIG_PCMCIA_RAYCS is not set
  17235. +
  17236. +CONFIG_CFG80211_WEXT=y
  17237. +# CONFIG_CFG80211_REG_DEBUG is not set
  17238. +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
  17239. +CONFIG_CFG80211_DEFAULT_PS=y
  17240. +CONFIG_NL80211=y
  17241. +# CONFIG_NL80211_TESTMODE is not set
  17242. +# CONFIG_WIRELESS_EXT_SYSFS is not set
  17243. +CONFIG_LIB80211=m
  17244. +CONFIG_LIB80211_CRYPT_WEP=m
  17245. +CONFIG_LIB80211_CRYPT_CCMP=m
  17246. +CONFIG_LIB80211_CRYPT_TKIP=m
  17247. +# CONFIG_LIB80211_DEBUG is not set
  17248. +
  17249. +CONFIG_MAC80211=m
  17250. +CONFIG_MAC80211_RC_MINSTREL=y
  17251. +# CONFIG_MAC80211_RC_DEFAULT_PID is not set
  17252. +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
  17253. +CONFIG_MAC80211_RC_DEFAULT="minstrel"
  17254. +CONFIG_MAC80211_MESH=y
  17255. +CONFIG_MAC80211_LEDS=y
  17256. +# CONFIG_MAC80211_DEBUG_MENU is not set
  17257. +
  17258. +# CONFIG_WIMAX is not set
  17259. +
  17260. +# CONFIG_ADM8211 is not set
  17261. +CONFIG_ATH_COMMON=m
  17262. +CONFIG_ATH_CARDS=m
  17263. +CONFIG_ATH5K=m
  17264. +CONFIG_ATH5K_DEBUG=y
  17265. +# CONFIG_ATH5K_TRACER is not set
  17266. +CONFIG_ATH6KL=m
  17267. +CONFIG_ATH6KL_DEBUG=y
  17268. +CONFIG_ATH6KL_SDIO=m
  17269. +CONFIG_ATH6KL_USB=m
  17270. +# CONFIG_ATH6KL_TRACING is not set
  17271. +CONFIG_AR5523=m
  17272. +CONFIG_ATH9K=m
  17273. +CONFIG_ATH9K_PCI=y
  17274. +CONFIG_ATH9K_AHB=y
  17275. +# CONFIG_ATH9K_DEBUG is not set
  17276. +# CONFIG_ATH9K_MAC_DEBUG is not set
  17277. +CONFIG_ATH9K_HTC=m
  17278. +CONFIG_ATH9K_BTCOEX_SUPPORT=y
  17279. +# CONFIG_ATH9K_LEGACY_RATE_CONTROL is not set
  17280. +# CONFIG_ATH9K_WOW is not set
  17281. +#
  17282. +CONFIG_ATH10K=m
  17283. +CONFIG_ATH10K_PCI=m
  17284. +# CONFIG_ATH10K_DEBUG is not set
  17285. +# CONFIG_ATH10K_TRACING is not set
  17286. +CONFIG_ATH10K_DEBUGFS=y
  17287. +CONFIG_WCN36XX=m
  17288. +# CONFIG_WCN36XX_DEBUGFS is not set
  17289. +CONFIG_WIL6210=m
  17290. +CONFIG_WIL6210_ISR_COR=y
  17291. +# CONFIG_WIL6210_TRACING is not set
  17292. +CONFIG_CARL9170=m
  17293. +CONFIG_CARL9170_LEDS=y
  17294. +# CONFIG_CARL9170_HWRNG is not set
  17295. +CONFIG_AT76C50X_USB=m
  17296. +# CONFIG_AIRO is not set
  17297. +# CONFIG_AIRO_CS is not set
  17298. +# CONFIG_ATMEL is not set
  17299. +CONFIG_B43=m
  17300. +CONFIG_B43_PCMCIA=y
  17301. +CONFIG_B43_SDIO=y
  17302. +CONFIG_B43_BCMA=y
  17303. +# CONFIG_B43_BCMA_EXTRA is not set
  17304. +CONFIG_B43_BCMA_PIO=y
  17305. +# CONFIG_B43_DEBUG is not set
  17306. +CONFIG_B43_PHY_LP=y
  17307. +CONFIG_B43_PHY_N=y
  17308. +CONFIG_B43_PHY_HT=y
  17309. +# CONFIG_B43_FORCE_PIO is not set
  17310. +CONFIG_B43LEGACY=m
  17311. +# CONFIG_B43LEGACY_DEBUG is not set
  17312. +CONFIG_B43LEGACY_DMA=y
  17313. +CONFIG_B43LEGACY_PIO=y
  17314. +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
  17315. +# CONFIG_B43LEGACY_DMA_MODE is not set
  17316. +# CONFIG_B43LEGACY_PIO_MODE is not set
  17317. +CONFIG_BRCMSMAC=m
  17318. +# CONFIG_BRCMFMAC_SDIO_OOB is not set
  17319. +CONFIG_BRCMFMAC_USB=y
  17320. +# CONFIG_BRCM_TRACING is not set
  17321. +# CONFIG_BRCMISCAN is not set
  17322. +# CONFIG_BRCMDBG is not set
  17323. +CONFIG_HERMES=m
  17324. +CONFIG_HERMES_CACHE_FW_ON_INIT=y
  17325. +# CONFIG_HERMES_PRISM is not set
  17326. +CONFIG_NORTEL_HERMES=m
  17327. +CONFIG_PCI_HERMES=m
  17328. +CONFIG_PLX_HERMES=m
  17329. +CONFIG_PCMCIA_HERMES=m
  17330. +CONFIG_ORINOCO_USB=m
  17331. +# CONFIG_TMD_HERMES is not set
  17332. +# CONFIG_PCMCIA_SPECTRUM is not set
  17333. +CONFIG_CW1200=m
  17334. +CONFIG_CW1200_WLAN_SDIO=m
  17335. +CONFIG_CW1200_WLAN_SPI=m
  17336. +# CONFIG_HOSTAP is not set
  17337. +# CONFIG_IPW2100 is not set
  17338. +# CONFIG_IPW2200 is not set
  17339. +# CONFIG_IPW2100_DEBUG is not set
  17340. +# CONFIG_IPW2200_DEBUG is not set
  17341. +# CONFIG_LIBIPW_DEBUG is not set
  17342. +CONFIG_LIBERTAS=m
  17343. +CONFIG_LIBERTAS_USB=m
  17344. +CONFIG_LIBERTAS_CS=m
  17345. +CONFIG_LIBERTAS_SDIO=m
  17346. +# CONFIG_LIBERTAS_DEBUG is not set
  17347. +# CONFIG_LIBERTAS_THINFIRM is not set
  17348. +CONFIG_LIBERTAS_MESH=y
  17349. +CONFIG_IWLWIFI=m
  17350. +CONFIG_IWLDVM=m
  17351. +CONFIG_IWLMVM=m
  17352. +CONFIG_IWLWIFI_DEBUG=y
  17353. +CONFIG_IWLWIFI_DEVICE_SVTOOL=y
  17354. +# CONFIG_IWLWIFI_EXPERIMENTAL_MFP is not set
  17355. +CONFIG_IWLWIFI_UCODE16=y
  17356. +# CONFIG_IWLWIFI_P2P is not set
  17357. +CONFIG_IWLEGACY=m
  17358. +CONFIG_IWLEGACY_DEBUG=y
  17359. +# CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING is not set
  17360. +CONFIG_IWL4965=y
  17361. +CONFIG_IWL3945=m
  17362. +# CONFIG_IWM is not set
  17363. +# CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE is not set
  17364. +CONFIG_MAC80211_HWSIM=m
  17365. +CONFIG_P54_COMMON=m
  17366. +CONFIG_P54_USB=m
  17367. +CONFIG_P54_PCI=m
  17368. +CONFIG_MWL8K=m
  17369. +# CONFIG_PRISM54 is not set
  17370. +# CONFIG_PCMCIA_WL3501 is not set
  17371. +CONFIG_RT2X00=m
  17372. +# CONFIG_RT2X00_DEBUG is not set
  17373. +CONFIG_RT2400PCI=m
  17374. +CONFIG_RT2500PCI=m
  17375. +CONFIG_RT61PCI=m
  17376. +CONFIG_RT2500USB=m
  17377. +CONFIG_RT2800USB=m
  17378. +CONFIG_RT2800USB_RT33XX=y
  17379. +CONFIG_RT2800USB_RT35XX=y
  17380. +CONFIG_RT2800USB_RT3573=y
  17381. +CONFIG_RT2800USB_RT53XX=y
  17382. +CONFIG_RT2800USB_RT55XX=y
  17383. +CONFIG_RT2800USB_UNKNOWN=y
  17384. +CONFIG_RT2800PCI=m
  17385. +CONFIG_RT2800PCI_RT3290=y
  17386. +CONFIG_RT2800PCI_RT33XX=y
  17387. +CONFIG_RT2800PCI_RT35XX=y
  17388. +CONFIG_RT2800PCI_RT53XX=y
  17389. +CONFIG_RT73USB=m
  17390. +CONFIG_RTL8180=m
  17391. +CONFIG_RTL8187=m
  17392. +# CONFIG_USB_ZD1201 is not set
  17393. +# CONFIG_USB_NET_SR9800 is not set
  17394. +CONFIG_USB_NET_RNDIS_WLAN=m
  17395. +CONFIG_USB_NET_KALMIA=m
  17396. +CONFIG_USB_NET_QMI_WWAN=m
  17397. +CONFIG_USB_NET_SMSC75XX=m
  17398. +# CONFIG_WL_TI is not set
  17399. +CONFIG_ZD1211RW=m
  17400. +# CONFIG_ZD1211RW_DEBUG is not set
  17401. +
  17402. +CONFIG_WL12XX=m
  17403. +CONFIG_WL12XX_SPI=m
  17404. +CONFIG_WL12XX_SDIO=m
  17405. +
  17406. +CONFIG_WL1251=m
  17407. +CONFIG_WL1251_SPI=m
  17408. +CONFIG_WL1251_SDIO=m
  17409. +
  17410. +CONFIG_RTL_CARDS=m
  17411. +CONFIG_RTLWIFI=m
  17412. +CONFIG_RTL8192CE=m
  17413. +CONFIG_RTL8192SE=m
  17414. +CONFIG_RTL8192CU=m
  17415. +CONFIG_RTL8192DE=m
  17416. +CONFIG_RTL8723AE=m
  17417. +CONFIG_RTL8188EE=m
  17418. +
  17419. +CONFIG_MWIFIEX=m
  17420. +CONFIG_MWIFIEX_SDIO=m
  17421. +CONFIG_MWIFIEX_PCIE=m
  17422. +CONFIG_MWIFIEX_USB=m
  17423. +
  17424. +#
  17425. +# Token Ring devices
  17426. +#
  17427. +# CONFIG_TR is not set
  17428. +
  17429. +CONFIG_NET_FC=y
  17430. +
  17431. +#
  17432. +# Wan interfaces
  17433. +#
  17434. +# CONFIG_WAN is not set
  17435. +
  17436. +#
  17437. +# PCMCIA network device support
  17438. +#
  17439. +CONFIG_NET_PCMCIA=y
  17440. +CONFIG_PCMCIA_3C589=m
  17441. +CONFIG_PCMCIA_3C574=m
  17442. +CONFIG_PCMCIA_FMVJ18X=m
  17443. +
  17444. +#
  17445. +# Amateur Radio support
  17446. +#
  17447. +CONFIG_HAMRADIO=y
  17448. +CONFIG_AX25=m
  17449. +CONFIG_AX25_DAMA_SLAVE=y
  17450. +
  17451. +# CONFIG_CAN is not set
  17452. +
  17453. +CONFIG_NETROM=m
  17454. +CONFIG_ROSE=m
  17455. +CONFIG_MKISS=m
  17456. +CONFIG_6PACK=m
  17457. +CONFIG_BPQETHER=m
  17458. +CONFIG_BAYCOM_SER_FDX=m
  17459. +CONFIG_BAYCOM_SER_HDX=m
  17460. +CONFIG_BAYCOM_PAR=m
  17461. +CONFIG_BAYCOM_EPP=m
  17462. +CONFIG_YAM=m
  17463. +
  17464. +CONFIG_NFC=m
  17465. +CONFIG_NFC_DIGITAL=m
  17466. +CONFIG_NFC_NCI=m
  17467. +CONFIG_NFC_HCI=m
  17468. +CONFIG_NFC_SHDLC=y
  17469. +CONFIG_NFC_LLCP=y
  17470. +CONFIG_NFC_SIM=m
  17471. +CONFIG_NFC_MRVL=m
  17472. +CONFIG_NFC_MRVL_USB=m
  17473. +
  17474. +#
  17475. +# Near Field Communication (NFC) devices
  17476. +#
  17477. +CONFIG_NFC_PORT100=m
  17478. +CONFIG_NFC_PN544=m
  17479. +CONFIG_NFC_PN544_I2C=m
  17480. +CONFIG_NFC_PN533=m
  17481. +CONFIG_NFC_MICROREAD=m
  17482. +CONFIG_NFC_MICROREAD_I2C=m
  17483. +
  17484. +#
  17485. +# IrDA (infrared) support
  17486. +#
  17487. +CONFIG_IRDA=m
  17488. +# CONFIG_IRDA_DEBUG is not set
  17489. +CONFIG_IRLAN=m
  17490. +CONFIG_IRNET=m
  17491. +CONFIG_IRCOMM=m
  17492. +# CONFIG_IRDA_ULTRA is not set
  17493. +CONFIG_IRDA_CACHE_LAST_LSAP=y
  17494. +CONFIG_IRDA_FAST_RR=y
  17495. +CONFIG_IRTTY_SIR=m
  17496. +CONFIG_DONGLE=y
  17497. +CONFIG_ACTISYS_DONGLE=m
  17498. +CONFIG_ACT200L_DONGLE=m
  17499. +CONFIG_ESI_DONGLE=m
  17500. +CONFIG_GIRBIL_DONGLE=m
  17501. +CONFIG_KINGSUN_DONGLE=m
  17502. +CONFIG_KSDAZZLE_DONGLE=m
  17503. +CONFIG_KS959_DONGLE=m
  17504. +CONFIG_LITELINK_DONGLE=m
  17505. +CONFIG_MA600_DONGLE=m
  17506. +CONFIG_MCP2120_DONGLE=m
  17507. +CONFIG_OLD_BELKIN_DONGLE=m
  17508. +CONFIG_TEKRAM_DONGLE=m
  17509. +CONFIG_TOIM3232_DONGLE=m
  17510. +
  17511. +CONFIG_ALI_FIR=m
  17512. +CONFIG_MCS_FIR=m
  17513. +CONFIG_NSC_FIR=m
  17514. +CONFIG_SIGMATEL_FIR=m
  17515. +CONFIG_SMC_IRCC_FIR=m
  17516. +# CONFIG_TOSHIBA_FIR is not set
  17517. +CONFIG_USB_IRDA=m
  17518. +CONFIG_VLSI_FIR=m
  17519. +CONFIG_VIA_FIR=m
  17520. +CONFIG_WINBOND_FIR=m
  17521. +
  17522. +#
  17523. +# Bluetooth support
  17524. +#
  17525. +CONFIG_BT=m
  17526. +CONFIG_BT_L2CAP=y
  17527. +CONFIG_BT_SCO=y
  17528. +CONFIG_BT_CMTP=m
  17529. +CONFIG_BT_RFCOMM=m
  17530. +CONFIG_BT_RFCOMM_TTY=y
  17531. +CONFIG_BT_BNEP=m
  17532. +CONFIG_BT_BNEP_MC_FILTER=y
  17533. +CONFIG_BT_BNEP_PROTO_FILTER=y
  17534. +CONFIG_BT_HIDP=m
  17535. +
  17536. +#
  17537. +# Bluetooth device drivers
  17538. +#
  17539. +CONFIG_BT_HCIBTUSB=m
  17540. +# Disable the BT_HCIUSB driver.
  17541. +# It sucks more power than BT_HCIBTUSB which has the same functionality.
  17542. +CONFIG_BT_HCIUART=m
  17543. +CONFIG_BT_HCIUART_H4=y
  17544. +CONFIG_BT_HCIUART_BCSP=y
  17545. +CONFIG_BT_HCIUART_ATH3K=y
  17546. +CONFIG_BT_HCIUART_3WIRE=y
  17547. +CONFIG_BT_HCIDTL1=m
  17548. +CONFIG_BT_HCIBT3C=m
  17549. +CONFIG_BT_HCIBLUECARD=m
  17550. +CONFIG_BT_HCIBTUART=m
  17551. +CONFIG_BT_HCIVHCI=m
  17552. +CONFIG_BT_HCIBCM203X=m
  17553. +CONFIG_BT_HCIBFUSB=m
  17554. +CONFIG_BT_HCIBPA10X=m
  17555. +CONFIG_BT_HCIBTSDIO=m
  17556. +CONFIG_BT_HCIUART_LL=y
  17557. +CONFIG_BT_MRVL=m
  17558. +CONFIG_BT_MRVL_SDIO=m
  17559. +CONFIG_BT_ATH3K=m
  17560. +CONFIG_BT_WILINK=m
  17561. +
  17562. +#
  17563. +# ISDN subsystem
  17564. +#
  17565. +CONFIG_ISDN=y
  17566. +CONFIG_MISDN=m
  17567. +CONFIG_MISDN_DSP=m
  17568. +CONFIG_MISDN_L1OIP=m
  17569. +CONFIG_MISDN_AVMFRITZ=m
  17570. +CONFIG_MISDN_SPEEDFAX=m
  17571. +CONFIG_MISDN_INFINEON=m
  17572. +CONFIG_MISDN_W6692=m
  17573. +CONFIG_MISDN_NETJET=m
  17574. +
  17575. +#
  17576. +# mISDN hardware drivers
  17577. +#
  17578. +CONFIG_MISDN_HFCPCI=m
  17579. +CONFIG_MISDN_HFCMULTI=m
  17580. +CONFIG_ISDN_I4L=m
  17581. +CONFIG_ISDN_DRV_AVMB1_B1PCI=m
  17582. +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
  17583. +CONFIG_ISDN_DRV_AVMB1_T1PCI=m
  17584. +CONFIG_ISDN_DRV_AVMB1_C4=m
  17585. +
  17586. +CONFIG_MISDN_HFCUSB=m
  17587. +
  17588. +CONFIG_ISDN_PPP=y
  17589. +CONFIG_ISDN_PPP_VJ=y
  17590. +CONFIG_ISDN_MPP=y
  17591. +# CONFIG_ISDN_PPP_BSDCOMP is not set
  17592. +CONFIG_ISDN_TTY_FAX=y
  17593. +CONFIG_DE_AOC=y
  17594. +
  17595. +CONFIG_ISDN_AUDIO=y
  17596. +
  17597. +CONFIG_ISDN_DRV_HISAX=m
  17598. +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
  17599. +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
  17600. +
  17601. +CONFIG_ISDN_CAPI_CAPIDRV=m
  17602. +CONFIG_ISDN_DIVERSION=m
  17603. +
  17604. +CONFIG_HISAX_EURO=y
  17605. +CONFIG_HISAX_1TR6=y
  17606. +CONFIG_HISAX_NI1=y
  17607. +CONFIG_HISAX_MAX_CARDS=8
  17608. +CONFIG_HISAX_16_3=y
  17609. +CONFIG_HISAX_TELESPCI=y
  17610. +CONFIG_HISAX_S0BOX=y
  17611. +CONFIG_HISAX_FRITZPCI=y
  17612. +CONFIG_HISAX_AVM_A1_PCMCIA=y
  17613. +CONFIG_HISAX_ELSA=y
  17614. +CONFIG_HISAX_DIEHLDIVA=y
  17615. +CONFIG_HISAX_SEDLBAUER=y
  17616. +CONFIG_HISAX_NETJET=y
  17617. +CONFIG_HISAX_NETJET_U=y
  17618. +CONFIG_HISAX_NICCY=y
  17619. +CONFIG_HISAX_BKM_A4T=y
  17620. +CONFIG_HISAX_SCT_QUADRO=y
  17621. +CONFIG_HISAX_GAZEL=y
  17622. +CONFIG_HISAX_HFC_PCI=y
  17623. +CONFIG_HISAX_W6692=y
  17624. +CONFIG_HISAX_HFC_SX=y
  17625. +CONFIG_HISAX_ENTERNOW_PCI=y
  17626. +# CONFIG_HISAX_DEBUG is not set
  17627. +CONFIG_HISAX_AVM_A1_CS=m
  17628. +CONFIG_HISAX_ST5481=m
  17629. +# CONFIG_HISAX_HFCUSB is not set
  17630. +CONFIG_HISAX_FRITZ_PCIPNP=m
  17631. +CONFIG_HISAX_NO_SENDCOMPLETE=y
  17632. +CONFIG_HISAX_NO_LLC=y
  17633. +CONFIG_HISAX_NO_KEYPAD=y
  17634. +CONFIG_HISAX_SEDLBAUER_CS=m
  17635. +CONFIG_HISAX_ELSA_CS=m
  17636. +CONFIG_HISAX_TELES_CS=m
  17637. +CONFIG_HISAX_HFC4S8S=m
  17638. +
  17639. +CONFIG_ISDN_DRV_LOOP=m
  17640. +CONFIG_HYSDN=m
  17641. +CONFIG_HYSDN_CAPI=y
  17642. +
  17643. +
  17644. +#
  17645. +# CAPI subsystem
  17646. +#
  17647. +CONFIG_ISDN_CAPI=m
  17648. +# CONFIG_CAPI_TRACE is not set
  17649. +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
  17650. +CONFIG_ISDN_CAPI_MIDDLEWARE=y
  17651. +CONFIG_ISDN_CAPI_CAPI20=m
  17652. +
  17653. +#
  17654. +# CAPI hardware drivers
  17655. +#
  17656. +
  17657. +#
  17658. +# Active AVM cards
  17659. +#
  17660. +CONFIG_CAPI_AVM=y
  17661. +
  17662. +#
  17663. +# Active Eicon DIVA Server cards
  17664. +#
  17665. +# CONFIG_CAPI_EICON is not set
  17666. +CONFIG_ISDN_DIVAS=m
  17667. +CONFIG_ISDN_DIVAS_BRIPCI=y
  17668. +CONFIG_ISDN_DIVAS_PRIPCI=y
  17669. +CONFIG_ISDN_DIVAS_DIVACAPI=m
  17670. +CONFIG_ISDN_DIVAS_USERIDI=m
  17671. +CONFIG_ISDN_DIVAS_MAINT=m
  17672. +
  17673. +CONFIG_ISDN_DRV_GIGASET=m
  17674. +CONFIG_GIGASET_CAPI=y
  17675. +CONFIG_GIGASET_BASE=m
  17676. +CONFIG_GIGASET_M101=m
  17677. +CONFIG_GIGASET_M105=m
  17678. +# CONFIG_GIGASET_DEBUG is not set
  17679. +
  17680. +#
  17681. +# Telephony Support
  17682. +#
  17683. +# CONFIG_PHONE is not set
  17684. +
  17685. +#
  17686. +# Input device support
  17687. +#
  17688. +CONFIG_INPUT=y
  17689. +CONFIG_INPUT_FF_MEMLESS=m
  17690. +
  17691. +#
  17692. +# Userland interfaces
  17693. +#
  17694. +CONFIG_INPUT_MOUSEDEV=y
  17695. +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
  17696. +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
  17697. +CONFIG_INPUT_JOYDEV=m
  17698. +# CONFIG_INPUT_MATRIXKMAP is not set
  17699. +
  17700. +CONFIG_INPUT_TABLET=y
  17701. +CONFIG_TABLET_USB_ACECAD=m
  17702. +CONFIG_TABLET_USB_AIPTEK=m
  17703. +CONFIG_TABLET_USB_GTCO=m
  17704. +CONFIG_TABLET_USB_HANWANG=m
  17705. +CONFIG_TABLET_USB_KBTAB=m
  17706. +CONFIG_TABLET_USB_WACOM=m
  17707. +
  17708. +CONFIG_INPUT_POWERMATE=m
  17709. +CONFIG_INPUT_YEALINK=m
  17710. +CONFIG_INPUT_CM109=m
  17711. +CONFIG_INPUT_POLLDEV=m
  17712. +CONFIG_INPUT_SPARSEKMAP=m
  17713. +# CONFIG_INPUT_ADXL34X is not set
  17714. +# CONFIG_INPUT_BMA150 is not set
  17715. +# CONFIG_INPUT_IMS_PCU is not set
  17716. +CONFIG_INPUT_CMA3000=m
  17717. +CONFIG_INPUT_CMA3000_I2C=m
  17718. +CONFIG_INPUT_IDEAPAD_SLIDEBAR=m
  17719. +
  17720. +#
  17721. +# Input I/O drivers
  17722. +#
  17723. +CONFIG_GAMEPORT=m
  17724. +CONFIG_GAMEPORT_NS558=m
  17725. +CONFIG_GAMEPORT_L4=m
  17726. +CONFIG_GAMEPORT_EMU10K1=m
  17727. +CONFIG_GAMEPORT_FM801=m
  17728. +CONFIG_SERIO=y
  17729. +CONFIG_SERIO_I8042=y
  17730. +CONFIG_SERIO_RAW=m
  17731. +CONFIG_SERIO_ALTERA_PS2=m
  17732. +# CONFIG_SERIO_PS2MULT is not set
  17733. +CONFIG_SERIO_ARC_PS2=m
  17734. +# CONFIG_SERIO_APBPS2 is not set
  17735. +
  17736. +# CONFIG_SERIO_CT82C710 is not set
  17737. +# CONFIG_SERIO_OLPC_APSP is not set
  17738. +# CONFIG_SERIO_PARKBD is not set
  17739. +# CONFIG_SERIO_PCIPS2 is not set
  17740. +# CONFIG_SERIO_LIBPS2 is not set
  17741. +
  17742. +#
  17743. +# Input Device Drivers
  17744. +#
  17745. +CONFIG_INPUT_KEYBOARD=y
  17746. +# CONFIG_KEYBOARD_SUNKBD is not set
  17747. +# CONFIG_KEYBOARD_SH_KEYSC is not set
  17748. +# CONFIG_KEYBOARD_XTKBD is not set
  17749. +# CONFIG_KEYBOARD_MATRIX is not set
  17750. +# CONFIG_KEYBOARD_NEWTON is not set
  17751. +# CONFIG_KEYBOARD_STOWAWAY is not set
  17752. +# CONFIG_KEYBOARD_LKKBD is not set
  17753. +# CONFIG_KEYBOARD_LM8323 is not set
  17754. +# CONFIG_KEYBOARD_LM8333 is not set
  17755. +# CONFIG_KEYBOARD_MAX7359 is not set
  17756. +# CONFIG_KEYBOARD_ADP5589 is not set
  17757. +# CONFIG_KEYBOARD_MPR121 is not set
  17758. +# CONFIG_KEYBOARD_QT1070 is not set
  17759. +# CONFIG_KEYBOARD_MCS is not set
  17760. +# CONFIG_KEYBOARD_OPENCORES is not set
  17761. +# CONFIG_KEYBOARD_SAMSUNG is not set
  17762. +# CONFIG_KEYBOARD_QT2160 is not set
  17763. +# CONFIG_KEYBOARD_TCA6416 is not set
  17764. +# CONFIG_KEYBOARD_TCA8418 is not set
  17765. +# CONFIG_KEYBOARD_OMAP4 is not set
  17766. +CONFIG_INPUT_MOUSE=y
  17767. +# CONFIG_MOUSE_PS2_TOUCHKIT is not set
  17768. +CONFIG_MOUSE_PS2_ELANTECH=y
  17769. +CONFIG_MOUSE_PS2_SENTELIC=y
  17770. +CONFIG_MOUSE_SERIAL=m
  17771. +CONFIG_MOUSE_VSXXXAA=m
  17772. +CONFIG_MOUSE_APPLETOUCH=m
  17773. +CONFIG_MOUSE_BCM5974=m
  17774. +CONFIG_MOUSE_SYNAPTICS_I2C=m
  17775. +CONFIG_MOUSE_SYNAPTICS_USB=m
  17776. +CONFIG_MOUSE_CYAPA=m
  17777. +CONFIG_INPUT_JOYSTICK=y
  17778. +CONFIG_JOYSTICK_ANALOG=m
  17779. +CONFIG_JOYSTICK_A3D=m
  17780. +CONFIG_JOYSTICK_ADI=m
  17781. +CONFIG_JOYSTICK_COBRA=m
  17782. +CONFIG_JOYSTICK_GF2K=m
  17783. +CONFIG_JOYSTICK_GRIP=m
  17784. +CONFIG_JOYSTICK_GRIP_MP=m
  17785. +CONFIG_JOYSTICK_GUILLEMOT=m
  17786. +CONFIG_JOYSTICK_INTERACT=m
  17787. +CONFIG_JOYSTICK_SIDEWINDER=m
  17788. +CONFIG_JOYSTICK_TMDC=m
  17789. +CONFIG_JOYSTICK_IFORCE=m
  17790. +CONFIG_JOYSTICK_IFORCE_USB=y
  17791. +CONFIG_JOYSTICK_IFORCE_232=y
  17792. +CONFIG_JOYSTICK_WARRIOR=m
  17793. +CONFIG_JOYSTICK_MAGELLAN=m
  17794. +CONFIG_JOYSTICK_SPACEORB=m
  17795. +CONFIG_JOYSTICK_SPACEBALL=m
  17796. +CONFIG_JOYSTICK_STINGER=m
  17797. +CONFIG_JOYSTICK_DB9=m
  17798. +CONFIG_JOYSTICK_GAMECON=m
  17799. +CONFIG_JOYSTICK_TURBOGRAFX=m
  17800. +CONFIG_JOYSTICK_JOYDUMP=m
  17801. +CONFIG_JOYSTICK_TWIDJOY=m
  17802. +CONFIG_JOYSTICK_WALKERA0701=m
  17803. +CONFIG_JOYSTICK_XPAD=m
  17804. +CONFIG_JOYSTICK_XPAD_FF=y
  17805. +CONFIG_JOYSTICK_XPAD_LEDS=y
  17806. +CONFIG_JOYSTICK_ZHENHUA=m
  17807. +# CONFIG_JOYSTICK_AS5011 is not set
  17808. +
  17809. +CONFIG_INPUT_TOUCHSCREEN=y
  17810. +# CONFIG_TOUCHSCREEN_AD7879 is not set
  17811. +CONFIG_TOUCHSCREEN_AD7879_I2C=m
  17812. +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
  17813. +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
  17814. +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set
  17815. +CONFIG_TOUCHSCREEN_DYNAPRO=m
  17816. +CONFIG_TOUCHSCREEN_EDT_FT5X06=m
  17817. +CONFIG_TOUCHSCREEN_EETI=m
  17818. +CONFIG_TOUCHSCREEN_EGALAX=m
  17819. +CONFIG_TOUCHSCREEN_ELO=m
  17820. +CONFIG_TOUCHSCREEN_FUJITSU=m
  17821. +CONFIG_TOUCHSCREEN_GUNZE=m
  17822. +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
  17823. +CONFIG_TOUCHSCREEN_INEXIO=m
  17824. +CONFIG_TOUCHSCREEN_ILI210X=m
  17825. +CONFIG_TOUCHSCREEN_MMS114=m
  17826. +CONFIG_TOUCHSCREEN_MTOUCH=m
  17827. +CONFIG_TOUCHSCREEN_MCS5000=m
  17828. +CONFIG_TOUCHSCREEN_MK712=m
  17829. +CONFIG_TOUCHSCREEN_PENMOUNT=m
  17830. +# CONFIG_TOUCHSCREEN_SUR40 is not set
  17831. +# CONFIG_TOUCHSCREEN_TPS6507X is not set
  17832. +CONFIG_TOUCHSCREEN_TSC_SERIO=m
  17833. +CONFIG_TOUCHSCREEN_TSC2007=m
  17834. +CONFIG_TOUCHSCREEN_TOUCHIT213=m
  17835. +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
  17836. +CONFIG_TOUCHSCREEN_TOUCHWIN=m
  17837. +CONFIG_TOUCHSCREEN_PIXCIR=m
  17838. +CONFIG_TOUCHSCREEN_UCB1400=m
  17839. +CONFIG_TOUCHSCREEN_WACOM_W8001=m
  17840. +CONFIG_TOUCHSCREEN_WACOM_I2C=m
  17841. +CONFIG_TOUCHSCREEN_USB_E2I=y
  17842. +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
  17843. +# CONFIG_TOUCHSCREEN_WM97XX is not set
  17844. +CONFIG_TOUCHSCREEN_W90X900=m
  17845. +# CONFIG_TOUCHSCREEN_BU21013 is not set
  17846. +CONFIG_TOUCHSCREEN_ST1232=m
  17847. +CONFIG_TOUCHSCREEN_ATMEL_MXT=m
  17848. +# CONFIG_TOUCHSCREEN_MAX11801 is not set
  17849. +CONFIG_TOUCHSCREEN_AUO_PIXCIR=m
  17850. +CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m
  17851. +CONFIG_TOUCHSCREEN_ZFORCE=m
  17852. +
  17853. +CONFIG_INPUT_PCSPKR=m
  17854. +CONFIG_INPUT_RETU_PWRBUTTON=m
  17855. +CONFIG_INPUT_UINPUT=m
  17856. +CONFIG_INPUT_WISTRON_BTNS=m
  17857. +CONFIG_INPUT_ATLAS_BTNS=m
  17858. +
  17859. +CONFIG_INPUT_ATI_REMOTE2=m
  17860. +CONFIG_INPUT_KEYSPAN_REMOTE=m
  17861. +
  17862. +CONFIG_MAC_EMUMOUSEBTN=y
  17863. +
  17864. +CONFIG_INPUT_WM831X_ON=m
  17865. +
  17866. +
  17867. +# CONFIG_INPUT_AD714X is not set
  17868. +# CONFIG_INPUT_PCF8574 is not set
  17869. +CONFIG_INPUT_MMA8450=m
  17870. +CONFIG_INPUT_MPU3050=m
  17871. +CONFIG_INPUT_KXTJ9=m
  17872. +# CONFIG_INPUT_KXTJ9_POLLED_MODE is not set
  17873. +
  17874. +#
  17875. +# Character devices
  17876. +#
  17877. +CONFIG_VT=y
  17878. +CONFIG_VT_CONSOLE=y
  17879. +CONFIG_HW_CONSOLE=y
  17880. +CONFIG_SERIAL_NONSTANDARD=y
  17881. +CONFIG_ROCKETPORT=m
  17882. +CONFIG_SYNCLINK=m
  17883. +CONFIG_SYNCLINKMP=m
  17884. +CONFIG_SYNCLINK_GT=m
  17885. +CONFIG_N_HDLC=m
  17886. +CONFIG_N_GSM=m
  17887. +# CONFIG_TRACE_SINK is not set
  17888. +# CONFIG_STALDRV is not set
  17889. +# CONFIG_DUMMY_IRQ is not set
  17890. +# CONFIG_IBM_ASM is not set
  17891. +CONFIG_TIFM_CORE=m
  17892. +CONFIG_TIFM_7XX1=m
  17893. +CONFIG_TCG_TPM=m
  17894. +CONFIG_TCG_TIS=m
  17895. +# CONFIG_TCG_TIS_I2C_INFINEON is not set
  17896. +# CONFIG_TCG_TIS_I2C_ATMEL is not set
  17897. +# CONFIG_TCG_TIS_I2C_NUVOTON is not set
  17898. +CONFIG_TCG_NSC=m
  17899. +CONFIG_TCG_ATMEL=m
  17900. +# CONFIG_TCG_INFINEON is not set
  17901. +# CONFIG_TCG_ST33_I2C is not set
  17902. +# CONFIG_TCG_XEN is not set
  17903. +CONFIG_TELCLOCK=m
  17904. +
  17905. +#
  17906. +# Serial drivers
  17907. +#
  17908. +CONFIG_SERIAL_8250=y
  17909. +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
  17910. +CONFIG_SERIAL_8250_CONSOLE=y
  17911. +CONFIG_SERIAL_8250_CS=m
  17912. +CONFIG_SERIAL_8250_NR_UARTS=32
  17913. +CONFIG_SERIAL_8250_RUNTIME_UARTS=4
  17914. +CONFIG_SERIAL_8250_EXTENDED=y
  17915. +CONFIG_SERIAL_8250_MANY_PORTS=y
  17916. +CONFIG_SERIAL_8250_SHARE_IRQ=y
  17917. +# CONFIG_SERIAL_8250_DETECT_IRQ is not set
  17918. +CONFIG_SERIAL_8250_RSA=y
  17919. +# CONFIG_SERIAL_8250_DW is not set
  17920. +CONFIG_CYCLADES=m
  17921. +# CONFIG_CYZ_INTR is not set
  17922. +# CONFIG_MOXA_INTELLIO is not set
  17923. +# CONFIG_MOXA_SMARTIO is not set
  17924. +# CONFIG_ISI is not set
  17925. +# CONFIG_RIO is not set
  17926. +CONFIG_SERIAL_JSM=m
  17927. +# CONFIG_SERIAL_SCCNXP is not set
  17928. +# CONFIG_SERIAL_MFD_HSU is not set
  17929. +
  17930. +# CONFIG_SERIAL_ALTERA_JTAGUART is not set
  17931. +# CONFIG_SERIAL_ALTERA_UART is not set
  17932. +
  17933. +#
  17934. +# Non-8250 serial port support
  17935. +#
  17936. +CONFIG_SERIAL_CORE=y
  17937. +CONFIG_SERIAL_CORE_CONSOLE=y
  17938. +# CONFIG_SERIAL_XILINX_PS_UART is not set
  17939. +# CONFIG_SERIAL_TIMBERDALE is not set
  17940. +CONFIG_SERIAL_ARC=m
  17941. +CONFIG_SERIAL_ARC_NR_PORTS=1
  17942. +# CONFIG_SERIAL_RP2 is not set
  17943. +# CONFIG_SERIAL_ST_ASC is not set
  17944. +# CONFIG_SERIAL_PCH_UART is not set
  17945. +
  17946. +CONFIG_UNIX98_PTYS=y
  17947. +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
  17948. +CONFIG_PRINTER=m
  17949. +CONFIG_LP_CONSOLE=y
  17950. +CONFIG_PPDEV=m
  17951. +
  17952. +#
  17953. +# I2C support
  17954. +#
  17955. +CONFIG_I2C=y
  17956. +# CONFIG_I2C_MUX is not set
  17957. +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
  17958. +# CONFIG_I2C_MUX_PCA954x is not set
  17959. +# CONFIG_I2C_MUX_GPIO is not set
  17960. +# CONFIG_I2C_MUX_PCA9541 is not set
  17961. +# CONFIG_I2C_MUX_PINCTRL is not set
  17962. +#
  17963. +
  17964. +#
  17965. +# I2C Algorithms
  17966. +#
  17967. +# CONFIG_I2C_DEBUG_ALGO is not set
  17968. +CONFIG_I2C_ALGOBIT=m
  17969. +
  17970. +#
  17971. +# I2C Hardware Bus support
  17972. +#
  17973. +
  17974. +# CONFIG_I2C_ALI1535 is not set
  17975. +# CONFIG_I2C_ALI1563 is not set
  17976. +# CONFIG_I2C_ALI15X3 is not set
  17977. +# CONFIG_I2C_AMD756 is not set
  17978. +# CONFIG_I2C_AMD756_S4882 is not set
  17979. +# CONFIG_I2C_AMD8111 is not set
  17980. +# CONFIG_I2C_DEBUG_CORE is not set
  17981. +# CONFIG_I2C_DEBUG_BUS is not set
  17982. +# CONFIG_I2C_I801 is not set
  17983. +# CONFIG_I2C_ISCH is not set
  17984. +# CONFIG_I2C_NFORCE2_S4985 is not set
  17985. +# CONFIG_I2C_INTEL_MID is not set
  17986. +# CONFIG_I2C_EG20T is not set
  17987. +# CONFIG_I2C_CBUS_GPIO is not set
  17988. +CONFIG_I2C_VIPERBOARD=m
  17989. +
  17990. +CONFIG_EEPROM_AT24=m
  17991. +CONFIG_EEPROM_LEGACY=m
  17992. +CONFIG_EEPROM_93CX6=m
  17993. +CONFIG_EEPROM_MAX6875=m
  17994. +
  17995. +CONFIG_I2C_NFORCE2=m
  17996. +# CONFIG_I2C_OCORES is not set
  17997. +CONFIG_I2C_PARPORT=m
  17998. +CONFIG_I2C_PARPORT_LIGHT=m
  17999. +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
  18000. +CONFIG_I2C_PASEMI=m
  18001. +CONFIG_I2C_PCA_PLATFORM=m
  18002. +# CONFIG_I2C_PIIX4 is not set
  18003. +# CONFIG_SCx200_ACB is not set
  18004. +# CONFIG_I2C_SIS5595 is not set
  18005. +# CONFIG_I2C_SIS630 is not set
  18006. +# CONFIG_I2C_SIS96X is not set
  18007. +CONFIG_I2C_SIMTEC=m
  18008. +CONFIG_I2C_STUB=m
  18009. +CONFIG_I2C_TINY_USB=m
  18010. +# CONFIG_I2C_TAOS_EVM is not set
  18011. +# CONFIG_I2C_VIA is not set
  18012. +# CONFIG_I2C_VIAPRO is not set
  18013. +# CONFIG_I2C_DESIGNWARE is not set
  18014. +# CONFIG_I2C_XILINX is not set
  18015. +
  18016. +CONFIG_I2C_DIOLAN_U2C=m
  18017. +
  18018. +#
  18019. +# I2C Hardware Sensors Chip support
  18020. +#
  18021. +CONFIG_SENSORS_ATK0110=m
  18022. +CONFIG_SENSORS_ABITUGURU=m
  18023. +CONFIG_SENSORS_ABITUGURU3=m
  18024. +CONFIG_SENSORS_AD7414=m
  18025. +CONFIG_SENSORS_AD7418=m
  18026. +CONFIG_SENSORS_ADM1021=m
  18027. +CONFIG_SENSORS_ADM1025=m
  18028. +CONFIG_SENSORS_ADM1026=m
  18029. +CONFIG_SENSORS_ADM1029=m
  18030. +CONFIG_SENSORS_ADM1031=m
  18031. +CONFIG_SENSORS_ADM9240=m
  18032. +CONFIG_SENSORS_ADT7310=m
  18033. +CONFIG_SENSORS_ADT7410=m
  18034. +CONFIG_SENSORS_ADS7828=m
  18035. +CONFIG_SENSORS_ADT7462=m
  18036. +CONFIG_SENSORS_ADT7470=m
  18037. +CONFIG_SENSORS_ADT7475=m
  18038. +CONFIG_SENSORS_APPLESMC=m
  18039. +CONFIG_SENSORS_ASB100=m
  18040. +CONFIG_SENSORS_ATXP1=m
  18041. +CONFIG_SENSORS_CORETEMP=m
  18042. +CONFIG_SENSORS_DME1737=m
  18043. +CONFIG_SENSORS_DS1621=m
  18044. +# CONFIG_DS1682 is not set
  18045. +CONFIG_SENSORS_F71805F=m
  18046. +CONFIG_SENSORS_F71882FG=m
  18047. +CONFIG_SENSORS_F75375S=m
  18048. +CONFIG_SENSORS_FSCHMD=m
  18049. +CONFIG_SENSORS_G760A=m
  18050. +CONFIG_SENSORS_G762=m
  18051. +CONFIG_SENSORS_GL518SM=m
  18052. +CONFIG_SENSORS_GL520SM=m
  18053. +CONFIG_SENSORS_HDAPS=m
  18054. +# CONFIG_SENSORS_HIH6130 is not set
  18055. +# CONFIG_SENSORS_HTU21 is not set
  18056. +# CONFIG_SENSORS_I5K_AMB is not set
  18057. +# FIXME: IBMAEM x86 only?
  18058. +CONFIG_SENSORS_IBMAEM=m
  18059. +CONFIG_SENSORS_IBMPEX=m
  18060. +# CONFIG_SENSORS_IIO_HWMON is not set
  18061. +CONFIG_SENSORS_IT87=m
  18062. +CONFIG_SENSORS_K8TEMP=m
  18063. +CONFIG_SENSORS_K10TEMP=m
  18064. +CONFIG_SENSORS_LIS3LV02D=m
  18065. +CONFIG_SENSORS_LIS3_SPI=m
  18066. +CONFIG_SENSORS_LIS3_I2C=m
  18067. +CONFIG_SENSORS_LM63=m
  18068. +CONFIG_SENSORS_LM75=m
  18069. +CONFIG_SENSORS_LM77=m
  18070. +CONFIG_SENSORS_LM78=m
  18071. +CONFIG_SENSORS_LM80=m
  18072. +CONFIG_SENSORS_LM83=m
  18073. +CONFIG_SENSORS_LM85=m
  18074. +CONFIG_SENSORS_LM87=m
  18075. +CONFIG_SENSORS_LM90=m
  18076. +CONFIG_SENSORS_LM92=m
  18077. +CONFIG_SENSORS_LM93=m
  18078. +CONFIG_SENSORS_LM95234=m
  18079. +CONFIG_SENSORS_LTC4245=m
  18080. +CONFIG_SENSORS_MAX1619=m
  18081. +CONFIG_SENSORS_MAX6650=m
  18082. +CONFIG_SENSORS_MAX6697=m
  18083. +CONFIG_SENSORS_MCP3021=m
  18084. +CONFIG_SENSORS_NCT6775=m
  18085. +CONFIG_SENSORS_NTC_THERMISTOR=m
  18086. +CONFIG_SENSORS_PC87360=m
  18087. +CONFIG_SENSORS_PC87427=m
  18088. +CONFIG_SENSORS_PCF8591=m
  18089. +CONFIG_SENSORS_SHT15=m
  18090. +CONFIG_SENSORS_SIS5595=m
  18091. +CONFIG_CHARGER_SMB347=m
  18092. +CONFIG_SENSORS_SMSC47M1=m
  18093. +CONFIG_SENSORS_SMSC47M192=m
  18094. +CONFIG_SENSORS_SMSC47B397=m
  18095. +CONFIG_SENSORS_THMC50=m
  18096. +CONFIG_SENSORS_TMP401=m
  18097. +CONFIG_APDS9802ALS=m
  18098. +CONFIG_ISL29020=m
  18099. +CONFIG_ISL29003=m
  18100. +CONFIG_SENSORS_BH1770=m
  18101. +CONFIG_SENSORS_APDS990X=m
  18102. +CONFIG_SENSORS_TSL2550=m
  18103. +CONFIG_SENSORS_VIA686A=m
  18104. +CONFIG_SENSORS_VIA_CPUTEMP=m
  18105. +CONFIG_SENSORS_VT1211=m
  18106. +CONFIG_SENSORS_VT8231=m
  18107. +CONFIG_SENSORS_W83627HF=m
  18108. +CONFIG_SENSORS_W83781D=m
  18109. +CONFIG_SENSORS_W83L785TS=m
  18110. +CONFIG_SENSORS_W83L786NG=m
  18111. +CONFIG_SENSORS_W83627EHF=m
  18112. +CONFIG_SENSORS_W83791D=m
  18113. +CONFIG_SENSORS_W83792D=m
  18114. +CONFIG_SENSORS_W83793=m
  18115. +CONFIG_SENSORS_LTC4215=m
  18116. +CONFIG_SENSORS_LM95241=m
  18117. +CONFIG_SENSORS_LM95245=m
  18118. +CONFIG_SENSORS_TMP421=m
  18119. +CONFIG_SENSORS_WM8350=m
  18120. +CONFIG_SENSORS_WM831X=m
  18121. +CONFIG_SENSORS_LM73=m
  18122. +CONFIG_SENSORS_AMC6821=m
  18123. +CONFIG_SENSORS_INA2XX=m
  18124. +CONFIG_SENSORS_INA209=m
  18125. +CONFIG_SENSORS_ADT7411=m
  18126. +CONFIG_SENSORS_ASC7621=m
  18127. +CONFIG_SENSORS_EMC1403=m
  18128. +CONFIG_SENSORS_TMP102=m
  18129. +CONFIG_SENSORS_LTC4261=m
  18130. +# CONFIG_SENSORS_BH1780 is not set
  18131. +# CONFIG_SENSORS_JC42 is not set
  18132. +# CONFIG_SENSORS_SMM665 is not set
  18133. +# CONFIG_SENSORS_EMC2103 is not set
  18134. +# CONFIG_SENSORS_GPIO_FAN is not set
  18135. +CONFIG_SENSORS_W83795=m
  18136. +# CONFIG_SENSORS_W83795_FANCTRL is not set
  18137. +CONFIG_SENSORS_DS620=m
  18138. +CONFIG_SENSORS_SHT21=m
  18139. +CONFIG_SENSORS_LINEAGE=m
  18140. +CONFIG_SENSORS_LTC4151=m
  18141. +CONFIG_SENSORS_MAX6639=m
  18142. +CONFIG_SENSORS_SCH5627=m
  18143. +CONFIG_SENSORS_SCH5636=m
  18144. +CONFIG_SENSORS_ADS1015=m
  18145. +CONFIG_SENSORS_MAX16065=m
  18146. +CONFIG_SENSORS_MAX6642=m
  18147. +CONFIG_SENSORS_ADM1275=m
  18148. +CONFIG_SENSORS_UCD9000=m
  18149. +CONFIG_SENSORS_UCD9200=m
  18150. +CONFIG_SENSORS_ZL6100=m
  18151. +CONFIG_SENSORS_EMC6W201=m
  18152. +
  18153. +CONFIG_PMBUS=m
  18154. +CONFIG_SENSORS_PMBUS=m
  18155. +CONFIG_SENSORS_MAX16064=m
  18156. +CONFIG_SENSORS_LM25066=m
  18157. +CONFIG_SENSORS_LTC2978=m
  18158. +CONFIG_SENSORS_MAX34440=m
  18159. +CONFIG_SENSORS_MAX8688=m
  18160. +CONFIG_SENSORS_MAX1668=m
  18161. +CONFIG_SENSORS_MAX197=m
  18162. +
  18163. +# Industrial I/O subsystem configuration
  18164. +CONFIG_IIO=m
  18165. +CONFIG_IIO_BUFFER=y
  18166. +CONFIG_IIO_BUFFER_CB=y
  18167. +# CONFIG_IIO_KFIFO_BUF is not set
  18168. +CONFIG_IIO_TRIGGERED_BUFFER=m
  18169. +CONFIG_IIO_TRIGGER=y
  18170. +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
  18171. +CONFIG_IIO_INTERRUPT_TRIGGER=m
  18172. +CONFIG_HID_SENSOR_IIO_COMMON=m
  18173. +CONFIG_HID_SENSOR_IIO_TRIGGER=m
  18174. +CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS=y
  18175. +# CONFIG_IIO_SYSFS_TRIGGER is not set
  18176. +# CONFIG_AD5446 is not set
  18177. +# CONFIG_AD5380 is not set
  18178. +# CONFIG_AD5064 is not set
  18179. +# CONFIG_BMA180 is not set
  18180. +# CONFIG_MAX1363 is not set
  18181. +# CONFIG_MAX517 is not set
  18182. +# CONFIG_MCP4725 is not set
  18183. +# CONFIG_ITG3200 is not set
  18184. +# CONFIG_APDS9300 is not set
  18185. +# CONFIG_CM32181 is not set
  18186. +# CONFIG_CM36651 is not set
  18187. +# CONFIG_GP2AP020A00F is not set
  18188. +# CONFIG_TSL2583 is not set
  18189. +# CONFIG_TSL2x7x is not set
  18190. +# CONFIG_TCS3472 is not set
  18191. +# CONFIG_TSL4531 is not set
  18192. +# CONFIG_NAU7802 is not set
  18193. +# CONFIG_TI_ADC081C is not set
  18194. +# CONFIG_EXYNOS_ADC is not set
  18195. +# CONFIG_VIPERBOARD_ADC is not set
  18196. +# CONFIG_INV_MPU6050_IIO is not set
  18197. +CONFIG_IIO_ST_GYRO_3AXIS=m
  18198. +CONFIG_IIO_ST_MAGN_3AXIS=m
  18199. +CONFIG_IIO_ST_ACCEL_3AXIS=m
  18200. +CONFIG_HID_SENSOR_INCLINOMETER_3D=m
  18201. +# CONFIG_ADJD_S311 is not set
  18202. +# CONFIG_SENSORS_TSL2563 is not set
  18203. +# CONFIG_VCNL4000 is not set
  18204. +# CONFIG_AK8975 is not set
  18205. +# CONFIG_MAG3110 is not set
  18206. +# CONFIG_TMP006 is not set
  18207. +# CONFIG_IIO_ST_PRESS is not set
  18208. +# CONFIG_KXSD9 is not set
  18209. +# CONFIG_AD7266 is not set
  18210. +# CONFIG_AD7298 is not set
  18211. +# CONFIG_AD7476 is not set
  18212. +# CONFIG_AD7791 is not set
  18213. +# CONFIG_AD7793 is not set
  18214. +# CONFIG_AD7887 is not set
  18215. +# CONFIG_AD7923 is not set
  18216. +# CONFIG_MCP320X is not set
  18217. +# CONFIG_MCP3422 is not set
  18218. +# CONFIG_AD8366 is not set
  18219. +# CONFIG_AD5360 is not set
  18220. +# CONFIG_AD5421 is not set
  18221. +# CONFIG_AD5449 is not set
  18222. +# CONFIG_AD5504 is not set
  18223. +# CONFIG_AD5624R_SPI is not set
  18224. +# CONFIG_AD5686 is not set
  18225. +# CONFIG_AD5755 is not set
  18226. +# CONFIG_AD5764 is not set
  18227. +# CONFIG_AD5791 is not set
  18228. +# CONFIG_AD7303 is not set
  18229. +# CONFIG_AD9523 is not set
  18230. +# CONFIG_ADF4350 is not set
  18231. +# CONFIG_ADIS16080 is not set
  18232. +# CONFIG_ADIS16130 is not set
  18233. +# CONFIG_ADIS16136 is not set
  18234. +# CONFIG_ADIS16260 is not set
  18235. +# CONFIG_ADXRS450 is not set
  18236. +# CONFIG_ADIS16400 is not set
  18237. +# CONFIG_ADIS16480 is not set
  18238. +# CONFIG_DHT11 is not set
  18239. +# CONFIG_MPL3115 is not set
  18240. +
  18241. +# staging IIO drivers
  18242. +# CONFIG_AD7291 is not set
  18243. +# CONFIG_AD7606 is not set
  18244. +# CONFIG_AD799X is not set
  18245. +# CONFIG_ADT7316 is not set
  18246. +# CONFIG_AD7150 is not set
  18247. +# CONFIG_AD7152 is not set
  18248. +# CONFIG_AD7746 is not set
  18249. +# CONFIG_AD5933 is not set
  18250. +# CONFIG_ADE7854 is not set
  18251. +# CONFIG_SENSORS_ISL29018 is not set
  18252. +# CONFIG_SENSORS_ISL29028 is not set
  18253. +# CONFIG_SENSORS_HMC5843 is not set
  18254. +# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set
  18255. +# CONFIG_IIO_SIMPLE_DUMMY is not set
  18256. +# CONFIG_ADIS16201 is not set
  18257. +# CONFIG_ADIS16203 is not set
  18258. +# CONFIG_ADIS16204 is not set
  18259. +# CONFIG_ADIS16209 is not set
  18260. +# CONFIG_ADIS16220 is not set
  18261. +# CONFIG_ADIS16240 is not set
  18262. +# CONFIG_LIS3L02DQ is not set
  18263. +# CONFIG_SCA3000 is not set
  18264. +# CONFIG_AD7780 is not set
  18265. +# CONFIG_AD7816 is not set
  18266. +# CONFIG_AD7192 is not set
  18267. +# CONFIG_AD7280 is not set
  18268. +# CONFIG_AD5930 is not set
  18269. +# CONFIG_AD9832 is not set
  18270. +# CONFIG_AD9834 is not set
  18271. +# CONFIG_AD9850 is not set
  18272. +# CONFIG_AD9852 is not set
  18273. +# CONFIG_AD9910 is not set
  18274. +# CONFIG_AD9951 is not set
  18275. +# CONFIG_ADIS16060 is not set
  18276. +# CONFIG_ADE7753 is not set
  18277. +# CONFIG_ADE7754 is not set
  18278. +# CONFIG_ADE7758 is not set
  18279. +# CONFIG_ADE7759 is not set
  18280. +# CONFIG_AD2S90 is not set
  18281. +# CONFIG_AD2S1200 is not set
  18282. +# CONFIG_AD2S1210 is not set
  18283. +
  18284. +
  18285. +
  18286. +# CONFIG_HMC6352 is not set
  18287. +# CONFIG_BMP085 is not set
  18288. +# CONFIG_BMP085_I2C is not set
  18289. +# CONFIG_PCH_PHUB is not set
  18290. +# CONFIG_USB_SWITCH_FSA9480 is not set
  18291. +
  18292. +CONFIG_W1=m
  18293. +CONFIG_W1_CON=y
  18294. +# CONFIG_W1_MASTER_MATROX is not set
  18295. +CONFIG_W1_MASTER_DS2490=m
  18296. +CONFIG_W1_MASTER_DS2482=m
  18297. +CONFIG_W1_MASTER_DS1WM=m
  18298. +CONFIG_W1_MASTER_GPIO=m
  18299. +# CONFIG_HDQ_MASTER_OMAP is not set
  18300. +CONFIG_W1_SLAVE_THERM=m
  18301. +CONFIG_W1_SLAVE_SMEM=m
  18302. +CONFIG_W1_SLAVE_DS2408=m
  18303. +# CONFIG_W1_SLAVE_DS2408_READBACK is not set
  18304. +CONFIG_W1_SLAVE_DS2413=m
  18305. +CONFIG_W1_SLAVE_DS2423=m
  18306. +CONFIG_W1_SLAVE_DS2431=m
  18307. +CONFIG_W1_SLAVE_DS2433=m
  18308. +CONFIG_W1_SLAVE_DS2433_CRC=y
  18309. +CONFIG_W1_SLAVE_DS2760=m
  18310. +CONFIG_W1_SLAVE_DS2780=m
  18311. +CONFIG_W1_SLAVE_DS2781=m
  18312. +CONFIG_W1_SLAVE_DS28E04=m
  18313. +CONFIG_W1_SLAVE_BQ27000=m
  18314. +
  18315. +#
  18316. +# Mice
  18317. +#
  18318. +
  18319. +#
  18320. +# IPMI
  18321. +#
  18322. +CONFIG_IPMI_HANDLER=m
  18323. +# CONFIG_IPMI_PANIC_EVENT is not set
  18324. +CONFIG_IPMI_DEVICE_INTERFACE=m
  18325. +CONFIG_IPMI_WATCHDOG=m
  18326. +CONFIG_IPMI_SI=m
  18327. +CONFIG_IPMI_POWEROFF=m
  18328. +
  18329. +#
  18330. +# Watchdog Cards
  18331. +#
  18332. +CONFIG_WATCHDOG_CORE=y
  18333. +# CONFIG_WATCHDOG_NOWAYOUT is not set
  18334. +CONFIG_SOFT_WATCHDOG=m
  18335. +CONFIG_WDTPCI=m
  18336. +# CONFIG_ACQUIRE_WDT is not set
  18337. +# CONFIG_ADVANTECH_WDT is not set
  18338. +# CONFIG_EUROTECH_WDT is not set
  18339. +CONFIG_IB700_WDT=m
  18340. +# CONFIG_SCx200_WDT is not set
  18341. +# CONFIG_60XX_WDT is not set
  18342. +CONFIG_W83877F_WDT=m
  18343. +CONFIG_W83627HF_WDT=m
  18344. +CONFIG_MACHZ_WDT=m
  18345. +# CONFIG_SC520_WDT is not set
  18346. +CONFIG_ALIM7101_WDT=m
  18347. +CONFIG_ALIM1535_WDT=m
  18348. +CONFIG_IT87_WDT=m
  18349. +CONFIG_ITCO_WDT=m
  18350. +CONFIG_ITCO_VENDOR_SUPPORT=y
  18351. +# CONFIG_SC1200_WDT is not set
  18352. +# CONFIG_PC87413_WDT is not set
  18353. +# CONFIG_WAFER_WDT is not set
  18354. +# CONFIG_CPU5_WDT is not set
  18355. +CONFIG_I6300ESB_WDT=m
  18356. +CONFIG_IT8712F_WDT=m
  18357. +# CONFIG_SBC8360_WDT is not set
  18358. +# CONFIG_SBC7240_WDT is not set
  18359. +CONFIG_SMSC_SCH311X_WDT=m
  18360. +CONFIG_W83977F_WDT=m
  18361. +CONFIG_PCIPCWATCHDOG=m
  18362. +CONFIG_USBPCWATCHDOG=m
  18363. +# CONFIG_SBC_EPX_C3_WATCHDOG is not set
  18364. +CONFIG_WM8350_WATCHDOG=m
  18365. +CONFIG_WM831X_WATCHDOG=m
  18366. +# CONFIG_MAX63XX_WATCHDOG is not set
  18367. +# CONFIG_DW_WATCHDOG is not set
  18368. +CONFIG_W83697UG_WDT=m
  18369. +# CONFIG_MEN_A21_WDT is not set
  18370. +# CONFIG_GPIO_WATCHDOG is not set
  18371. +
  18372. +CONFIG_HW_RANDOM=y
  18373. +CONFIG_HW_RANDOM_TIMERIOMEM=m
  18374. +CONFIG_HW_RANDOM_TPM=m
  18375. +# CONFIG_HW_RANDOM_ATMEL is not set
  18376. +# CONFIG_HW_RANDOM_EXYNOS is not set
  18377. +# CONFIG_NVRAM is not set
  18378. +# CONFIG_RTC is not set
  18379. +# CONFIG_RTC_DEBUG is not set
  18380. +# CONFIG_GEN_RTC is not set
  18381. +CONFIG_RTC_HCTOSYS=y
  18382. +# CONFIG_RTC_SYSTOHC is not set
  18383. +CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
  18384. +CONFIG_RTC_INTF_SYSFS=y
  18385. +CONFIG_RTC_INTF_PROC=y
  18386. +CONFIG_RTC_INTF_DEV=y
  18387. +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
  18388. +CONFIG_RTC_DRV_CMOS=y
  18389. +CONFIG_RTC_DRV_DS1307=m
  18390. +CONFIG_RTC_DRV_DS1511=m
  18391. +CONFIG_RTC_DRV_DS1553=m
  18392. +CONFIG_RTC_DRV_DS1672=m
  18393. +CONFIG_RTC_DRV_DS1742=m
  18394. +CONFIG_RTC_DRV_DS1374=m
  18395. +# CONFIG_RTC_DRV_EP93XX is not set
  18396. +CONFIG_RTC_DRV_FM3130=m
  18397. +CONFIG_RTC_DRV_ISL1208=m
  18398. +CONFIG_RTC_DRV_M41T80=m
  18399. +CONFIG_RTC_DRV_M41T80_WDT=y
  18400. +CONFIG_RTC_DRV_M48T59=m
  18401. +CONFIG_RTC_DRV_MAX6900=m
  18402. +# CONFIG_RTC_DRV_M48T86 is not set
  18403. +CONFIG_RTC_DRV_PCF2127=m
  18404. +CONFIG_RTC_DRV_PCF8563=m
  18405. +CONFIG_RTC_DRV_PCF8583=m
  18406. +CONFIG_RTC_DRV_RS5C372=m
  18407. +# CONFIG_RTC_DRV_SA1100 is not set
  18408. +# CONFIG_RTC_DRV_TEST is not set
  18409. +CONFIG_RTC_DRV_X1205=m
  18410. +CONFIG_RTC_DRV_V3020=m
  18411. +CONFIG_RTC_DRV_DS2404=m
  18412. +CONFIG_RTC_DRV_STK17TA8=m
  18413. +# CONFIG_RTC_DRV_S35390A is not set
  18414. +CONFIG_RTC_DRV_RX8581=m
  18415. +CONFIG_RTC_DRV_RX8025=m
  18416. +CONFIG_RTC_DRV_DS1286=m
  18417. +CONFIG_RTC_DRV_M48T35=m
  18418. +CONFIG_RTC_DRV_BQ4802=m
  18419. +CONFIG_RTC_DRV_WM8350=m
  18420. +# CONFIG_RTC_DRV_AB3100 is not set
  18421. +CONFIG_RTC_DRV_WM831X=m
  18422. +CONFIG_RTC_DRV_BQ32K=m
  18423. +CONFIG_RTC_DRV_MSM6242=m
  18424. +CONFIG_RTC_DRV_RP5C01=m
  18425. +CONFIG_RTC_DRV_EM3027=m
  18426. +CONFIG_RTC_DRV_RV3029C2=m
  18427. +CONFIG_RTC_DRV_PCF50633=m
  18428. +CONFIG_RTC_DRV_DS3232=m
  18429. +CONFIG_RTC_DRV_ISL12022=m
  18430. +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
  18431. +# CONFIG_RTC_DRV_MOXART is not set
  18432. +# CONFIG_RTC_DRV_ISL12057 is not set
  18433. +
  18434. +CONFIG_R3964=m
  18435. +# CONFIG_APPLICOM is not set
  18436. +# CONFIG_SONYPI is not set
  18437. +
  18438. +#
  18439. +# Ftape, the floppy tape device driver
  18440. +#
  18441. +CONFIG_AGP=y
  18442. +CONFIG_AGP_ALI=y
  18443. +CONFIG_AGP_ATI=y
  18444. +CONFIG_AGP_AMD=y
  18445. +CONFIG_AGP_AMD64=y
  18446. +CONFIG_AGP_INTEL=y
  18447. +CONFIG_AGP_NVIDIA=y
  18448. +CONFIG_AGP_SIS=y
  18449. +CONFIG_AGP_SWORKS=y
  18450. +CONFIG_AGP_VIA=y
  18451. +CONFIG_AGP_EFFICEON=y
  18452. +
  18453. +CONFIG_VGA_ARB=y
  18454. +CONFIG_VGA_ARB_MAX_GPUS=16
  18455. +
  18456. +# CONFIG_STUB_POULSBO is not set
  18457. +
  18458. +#
  18459. +# PCMCIA character devices
  18460. +#
  18461. +# CONFIG_SYNCLINK_CS is not set
  18462. +
  18463. +CONFIG_CARDMAN_4000=m
  18464. +CONFIG_CARDMAN_4040=m
  18465. +
  18466. +CONFIG_MWAVE=m
  18467. +CONFIG_RAW_DRIVER=y
  18468. +CONFIG_MAX_RAW_DEVS=8192
  18469. +CONFIG_HANGCHECK_TIMER=m
  18470. +
  18471. +CONFIG_MEDIA_PCI_SUPPORT=y
  18472. +#
  18473. +# Multimedia devices
  18474. +#
  18475. +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
  18476. +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
  18477. +CONFIG_MEDIA_RC_SUPPORT=y
  18478. +CONFIG_MEDIA_CONTROLLER=y
  18479. +CONFIG_VIDEO_DEV=m
  18480. +# CONFIG_VIDEO_ADV_DEBUG is not set
  18481. +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
  18482. +CONFIG_VIDEO_V4L2=y
  18483. +CONFIG_VIDEO_V4L2_SUBDEV_API=y
  18484. +# CONFIG_VIDEO_VIVI is not set
  18485. +# CONFIG_USB_SI4713 is not set
  18486. +# CONFIG_PLATFORM_SI4713 is not set
  18487. +# CONFIG_I2C_SI4713 is not set
  18488. +# CONFIG_USB_RAREMONO is not set
  18489. +
  18490. +#
  18491. +# Video For Linux
  18492. +#
  18493. +
  18494. +#
  18495. +# Video Adapters
  18496. +#
  18497. +CONFIG_V4L_USB_DRIVERS=y
  18498. +CONFIG_VIDEO_CAPTURE_DRIVERS=y
  18499. +CONFIG_V4L_PCI_DRIVERS=y
  18500. +CONFIG_VIDEO_AU0828=m
  18501. +CONFIG_VIDEO_AU0828_V4L2=y
  18502. +CONFIG_VIDEO_BT848=m
  18503. +CONFIG_VIDEO_BT848_DVB=y
  18504. +CONFIG_VIDEO_BWQCAM=m
  18505. +CONFIG_VIDEO_SR030PC30=m
  18506. +CONFIG_VIDEO_NOON010PC30=m
  18507. +CONFIG_VIDEO_CAFE_CCIC=m
  18508. +# CONFIG_VIDEO_CPIA is not set
  18509. +CONFIG_VIDEO_CPIA2=m
  18510. +CONFIG_VIDEO_CQCAM=m
  18511. +CONFIG_VIDEO_CX23885=m
  18512. +CONFIG_MEDIA_ALTERA_CI=m
  18513. +CONFIG_VIDEO_CX18=m
  18514. +CONFIG_VIDEO_CX18_ALSA=m
  18515. +CONFIG_VIDEO_CX88=m
  18516. +CONFIG_VIDEO_CX88_DVB=m
  18517. +CONFIG_VIDEO_CX88_ALSA=m
  18518. +CONFIG_VIDEO_CX88_BLACKBIRD=m
  18519. +CONFIG_VIDEO_CX88_ENABLE_VP3054=y
  18520. +CONFIG_VIDEO_CX88_VP3054=m
  18521. +CONFIG_VIDEO_EM28XX=m
  18522. +CONFIG_VIDEO_EM28XX_V4L2=m
  18523. +CONFIG_VIDEO_EM28XX_ALSA=m
  18524. +CONFIG_VIDEO_EM28XX_DVB=m
  18525. +CONFIG_VIDEO_EM28XX_RC=y
  18526. +CONFIG_VIDEO_CX231XX=m
  18527. +CONFIG_VIDEO_CX231XX_ALSA=m
  18528. +CONFIG_VIDEO_CX231XX_DVB=m
  18529. +CONFIG_VIDEO_CX231XX_RC=y
  18530. +CONFIG_VIDEO_HEXIUM_ORION=m
  18531. +CONFIG_VIDEO_HEXIUM_GEMINI=m
  18532. +CONFIG_VIDEO_IVTV=m
  18533. +# CONFIG_VIDEO_IVTV_ALSA is not set
  18534. +CONFIG_VIDEO_MEYE=m
  18535. +CONFIG_VIDEO_MXB=m
  18536. +CONFIG_VIDEO_PVRUSB2_DVB=y
  18537. +# CONFIG_VIDEO_PMS is not set
  18538. +CONFIG_VIDEO_HDPVR=m
  18539. +CONFIG_VIDEO_SAA6588=m
  18540. +CONFIG_VIDEO_SAA7134=m
  18541. +CONFIG_VIDEO_SAA7134_ALSA=m
  18542. +CONFIG_VIDEO_SAA7134_DVB=m
  18543. +CONFIG_VIDEO_SAA7134_RC=y
  18544. +CONFIG_VIDEO_USBVISION=m
  18545. +CONFIG_VIDEO_STK1160_COMMON=m
  18546. +CONFIG_VIDEO_STK1160=m
  18547. +CONFIG_VIDEO_STK1160_AC97=y
  18548. +CONFIG_VIDEO_W9966=m
  18549. +CONFIG_VIDEO_ZORAN=m
  18550. +CONFIG_VIDEO_ZORAN_AVS6EYES=m
  18551. +CONFIG_VIDEO_ZORAN_BUZ=m
  18552. +CONFIG_VIDEO_ZORAN_DC10=m
  18553. +CONFIG_VIDEO_ZORAN_DC30=m
  18554. +CONFIG_VIDEO_ZORAN_LML33=m
  18555. +CONFIG_VIDEO_ZORAN_LML33R10=m
  18556. +CONFIG_VIDEO_ZORAN_ZR36060=m
  18557. +# CONFIG_V4L_ISA_PARPORT_DRIVERS is not set
  18558. +CONFIG_VIDEO_FB_IVTV=m
  18559. +CONFIG_VIDEO_SAA7164=m
  18560. +CONFIG_VIDEO_TM6000=m
  18561. +CONFIG_VIDEO_TM6000_ALSA=m
  18562. +CONFIG_VIDEO_TM6000_DVB=m
  18563. +CONFIG_VIDEO_TLG2300=m
  18564. +CONFIG_VIDEO_USBTV=m
  18565. +
  18566. +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
  18567. +
  18568. +#
  18569. +# Radio Adapters
  18570. +#
  18571. +CONFIG_RADIO_MAXIRADIO=m
  18572. +CONFIG_RADIO_SHARK=m
  18573. +CONFIG_RADIO_SHARK2=m
  18574. +CONFIG_RADIO_WL1273=m
  18575. +
  18576. +CONFIG_MEDIA_ATTACH=y
  18577. +
  18578. +#
  18579. +# V4L/DVB tuners
  18580. +# Selected automatically by not setting CONFIG_MEDIA_TUNER_CUSTOMISE
  18581. +#
  18582. +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
  18583. +
  18584. +#
  18585. +# Digital Video Broadcasting Devices
  18586. +#
  18587. +CONFIG_DVB_CAPTURE_DRIVERS=y
  18588. +CONFIG_DVB_CORE=m
  18589. +CONFIG_DVB_NET=y
  18590. +CONFIG_DVB_MAX_ADAPTERS=8
  18591. +CONFIG_DVB_DYNAMIC_MINORS=y
  18592. +
  18593. +#
  18594. +# DVB frontends
  18595. +# Selected automatically by not setting CONFIG_DVB_FE_CUSTOMISE
  18596. +#
  18597. +# CONFIG_DVB_FE_CUSTOMISE is not set
  18598. +
  18599. +#
  18600. +# Supported DVB bridge Modules
  18601. +#
  18602. +CONFIG_DVB_BT8XX=m
  18603. +CONFIG_DVB_BUDGET_CORE=m
  18604. +CONFIG_DVB_PLUTO2=m
  18605. +CONFIG_SMS_SIANO_MDTV=m
  18606. +CONFIG_SMS_SIANO_RC=y
  18607. +# CONFIG_SMS_SIANO_DEBUGFS is not set
  18608. +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
  18609. +CONFIG_SMS_USB_DRV=m
  18610. +CONFIG_SMS_SDIO_DRV=m
  18611. +CONFIG_DVB_TTUSB_DEC=m
  18612. +CONFIG_DVB_USB_DTV5100=m
  18613. +CONFIG_DVB_USB_AF9015=m
  18614. +CONFIG_DVB_USB_ANYSEE=m
  18615. +CONFIG_DVB_USB_DW2102=m
  18616. +CONFIG_DVB_USB_FRIIO=m
  18617. +CONFIG_DVB_USB_EC168=m
  18618. +CONFIG_DVB_USB_PCTV452E=m
  18619. +CONFIG_DVB_USB_IT913X=m
  18620. +CONFIG_DVB_USB_MXL111SF=m
  18621. +CONFIG_DVB_DM1105=m
  18622. +CONFIG_DVB_FIREDTV=m
  18623. +CONFIG_DVB_NGENE=m
  18624. +CONFIG_DVB_DDBRIDGE=m
  18625. +CONFIG_DVB_USB_TECHNISAT_USB2=m
  18626. +CONFIG_DVB_USB_V2=m
  18627. +
  18628. +CONFIG_DVB_AV7110=m
  18629. +CONFIG_DVB_AV7110_OSD=y
  18630. +CONFIG_DVB_BUDGET=m
  18631. +CONFIG_DVB_BUDGET_CI=m
  18632. +CONFIG_DVB_BUDGET_AV=m
  18633. +CONFIG_DVB_BUDGET_PATCH=m
  18634. +
  18635. +CONFIG_DVB_TTUSB_BUDGET=m
  18636. +
  18637. +CONFIG_DVB_USB_CINERGY_T2=m
  18638. +CONFIG_DVB_B2C2_FLEXCOP=m
  18639. +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set
  18640. +
  18641. +CONFIG_DVB_B2C2_FLEXCOP_PCI=m
  18642. +# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set
  18643. +CONFIG_DVB_B2C2_FLEXCOP_USB=m
  18644. +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
  18645. +CONFIG_DVB_USB=m
  18646. +# CONFIG_DVB_USB_DEBUG is not set
  18647. +CONFIG_DVB_USB_A800=m
  18648. +CONFIG_DVB_USB_AF9005=m
  18649. +CONFIG_DVB_USB_AF9005_REMOTE=m
  18650. +CONFIG_DVB_USB_AU6610=m
  18651. +CONFIG_DVB_USB_CXUSB=m
  18652. +CONFIG_DVB_USB_DIBUSB_MB=m
  18653. +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
  18654. +CONFIG_DVB_USB_DIBUSB_MC=m
  18655. +CONFIG_DVB_USB_DIB0700=m
  18656. +CONFIG_DVB_USB_DIGITV=m
  18657. +CONFIG_DVB_USB_DTT200U=m
  18658. +CONFIG_DVB_USB_GL861=m
  18659. +CONFIG_DVB_USB_GP8PSK=m
  18660. +CONFIG_DVB_USB_M920X=m
  18661. +CONFIG_DVB_USB_NOVA_T_USB2=m
  18662. +CONFIG_DVB_USB_CE6230=m
  18663. +CONFIG_DVB_USB_OPERA1=m
  18664. +CONFIG_DVB_USB_TTUSB2=m
  18665. +CONFIG_DVB_USB_UMT_010=m
  18666. +CONFIG_DVB_USB_VP702X=m
  18667. +CONFIG_DVB_USB_VP7045=m
  18668. +CONFIG_DVB_USB_AZ6027=m
  18669. +CONFIG_DVB_USB_AZ6007=m
  18670. +CONFIG_DVB_USB_LME2510=m
  18671. +CONFIG_DVB_USB_RTL28XXU=m
  18672. +CONFIG_DVB_USB_AF9035=m
  18673. +
  18674. +CONFIG_DVB_PT1=m
  18675. +
  18676. +CONFIG_MANTIS_CORE=m
  18677. +CONFIG_DVB_MANTIS=m
  18678. +CONFIG_DVB_HOPPER=m
  18679. +
  18680. +CONFIG_VIDEO_SAA7146=m
  18681. +CONFIG_VIDEO_SAA7146_VV=m
  18682. +CONFIG_VIDEO_TVP5150=m
  18683. +CONFIG_VIDEO_TUNER=m
  18684. +CONFIG_VIDEO_BTCX=m
  18685. +CONFIG_VIDEO_PVRUSB2=m
  18686. +CONFIG_VIDEO_PVRUSB2_SYSFS=y
  18687. +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
  18688. +
  18689. +CONFIG_RC_CORE=m
  18690. +CONFIG_RC_DECODERS=y
  18691. +CONFIG_LIRC=m
  18692. +CONFIG_RC_LOOPBACK=m
  18693. +CONFIG_RC_MAP=m
  18694. +CONFIG_RC_DEVICES=y
  18695. +CONFIG_RC_ATI_REMOTE=m
  18696. +CONFIG_IR_NEC_DECODER=m
  18697. +CONFIG_IR_RC5_DECODER=m
  18698. +CONFIG_IR_RC6_DECODER=m
  18699. +CONFIG_IR_JVC_DECODER=m
  18700. +CONFIG_IR_SONY_DECODER=m
  18701. +CONFIG_IR_RC5_SZ_DECODER=m
  18702. +CONFIG_IR_SANYO_DECODER=m
  18703. +CONFIG_IR_MCE_KBD_DECODER=m
  18704. +CONFIG_IR_LIRC_CODEC=m
  18705. +CONFIG_IR_IMON=m
  18706. +CONFIG_IR_MCEUSB=m
  18707. +CONFIG_IR_ITE_CIR=m
  18708. +CONFIG_IR_NUVOTON=m
  18709. +CONFIG_IR_FINTEK=m
  18710. +CONFIG_IR_REDRAT3=m
  18711. +CONFIG_IR_ENE=m
  18712. +CONFIG_IR_STREAMZAP=m
  18713. +CONFIG_IR_WINBOND_CIR=m
  18714. +CONFIG_IR_IGUANA=m
  18715. +CONFIG_IR_TTUSBIR=m
  18716. +CONFIG_IR_GPIO_CIR=m
  18717. +
  18718. +CONFIG_V4L_MEM2MEM_DRIVERS=y
  18719. +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
  18720. +# CONFIG_VIDEO_SH_VEU is not set
  18721. +# CONFIG_VIDEO_RENESAS_VSP1 is not set
  18722. +# CONFIG_V4L_TEST_DRIVERS is not set
  18723. +
  18724. +# CONFIG_VIDEO_MEM2MEM_TESTDEV is not set
  18725. +
  18726. +#
  18727. +# Broadcom Crystal HD video decoder driver
  18728. +#
  18729. +CONFIG_CRYSTALHD=m
  18730. +
  18731. +#
  18732. +# Graphics support
  18733. +#
  18734. +
  18735. +CONFIG_DISPLAY_SUPPORT=m
  18736. +CONFIG_VIDEO_OUTPUT_CONTROL=m
  18737. +
  18738. +#
  18739. +# Console display driver support
  18740. +#
  18741. +CONFIG_VGA_CONSOLE=y
  18742. +CONFIG_VGACON_SOFT_SCROLLBACK=y
  18743. +CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
  18744. +CONFIG_DUMMY_CONSOLE=y
  18745. +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
  18746. +
  18747. +#
  18748. +# Logo configuration
  18749. +#
  18750. +# CONFIG_LOGO_LINUX_MONO is not set
  18751. +# CONFIG_LOGO_LINUX_VGA16 is not set
  18752. +CONFIG_LOGO_LINUX_CLUT224=y
  18753. +
  18754. +#
  18755. +# Sound
  18756. +#
  18757. +
  18758. +#
  18759. +# Advanced Linux Sound Architecture
  18760. +#
  18761. +CONFIG_SOUND_OSS_CORE_PRECLAIM=y
  18762. +# CONFIG_SND_DEBUG_VERBOSE is not set
  18763. +CONFIG_SND_VERBOSE_PROCFS=y
  18764. +CONFIG_SND_SEQUENCER=y
  18765. +CONFIG_SND_HRTIMER=y
  18766. +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
  18767. +CONFIG_SND_SEQ_DUMMY=m
  18768. +CONFIG_SND_SEQUENCER_OSS=y
  18769. +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
  18770. +CONFIG_SND_OSSEMUL=y
  18771. +CONFIG_SND_MIXER_OSS=y
  18772. +CONFIG_SND_PCM_OSS=y
  18773. +CONFIG_SND_PCM_OSS_PLUGINS=y
  18774. +CONFIG_SND_RTCTIMER=y
  18775. +CONFIG_SND_DYNAMIC_MINORS=y
  18776. +CONFIG_SND_MAX_CARDS=32
  18777. +# CONFIG_SND_SUPPORT_OLD_API is not set
  18778. +
  18779. +#
  18780. +# Generic devices
  18781. +#
  18782. +CONFIG_SND_DUMMY=m
  18783. +CONFIG_SND_ALOOP=m
  18784. +CONFIG_SND_VIRMIDI=m
  18785. +CONFIG_SND_MTPAV=m
  18786. +CONFIG_SND_MTS64=m
  18787. +CONFIG_SND_SERIAL_U16550=m
  18788. +CONFIG_SND_MPU401=m
  18789. +CONFIG_SND_PORTMAN2X4=m
  18790. +CONFIG_SND_AC97_POWER_SAVE=y
  18791. +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0
  18792. +
  18793. +CONFIG_SND_DRIVERS=y
  18794. +
  18795. +#
  18796. +# ISA devices
  18797. +#
  18798. +CONFIG_SND_AD1889=m
  18799. +
  18800. +#
  18801. +# PCI devices
  18802. +#
  18803. +CONFIG_SND_PCI=y
  18804. +CONFIG_SND_ALI5451=m
  18805. +CONFIG_SND_ALS300=m
  18806. +CONFIG_SND_ALS4000=m
  18807. +CONFIG_SND_ATIIXP=m
  18808. +CONFIG_SND_ATIIXP_MODEM=m
  18809. +CONFIG_SND_AU8810=m
  18810. +CONFIG_SND_AU8820=m
  18811. +CONFIG_SND_AU8830=m
  18812. +# CONFIG_SND_AW2 is not set
  18813. +CONFIG_SND_AZT3328=m
  18814. +CONFIG_SND_BT87X=m
  18815. +# CONFIG_SND_BT87X_OVERCLOCK is not set
  18816. +CONFIG_SND_CA0106=m
  18817. +CONFIG_SND_CMIPCI=m
  18818. +CONFIG_SND_CS46XX=m
  18819. +CONFIG_SND_CS46XX_NEW_DSP=y
  18820. +CONFIG_SND_CS4281=m
  18821. +CONFIG_SND_CS5530=m
  18822. +CONFIG_SND_CS5535AUDIO=m
  18823. +CONFIG_SND_EMU10K1=m
  18824. +CONFIG_SND_EMU10K1X=m
  18825. +CONFIG_SND_ENS1370=m
  18826. +CONFIG_SND_ENS1371=m
  18827. +CONFIG_SND_ES1938=m
  18828. +CONFIG_SND_ES1968=m
  18829. +CONFIG_SND_ES1968_INPUT=y
  18830. +CONFIG_SND_ES1968_RADIO=y
  18831. +CONFIG_SND_FM801=m
  18832. +CONFIG_SND_FM801_TEA575X_BOOL=y
  18833. +CONFIG_SND_CTXFI=m
  18834. +CONFIG_SND_LX6464ES=m
  18835. +CONFIG_SND_HDA_INTEL=y
  18836. +CONFIG_SND_HDA_INPUT_BEEP=y
  18837. +CONFIG_SND_HDA_INPUT_BEEP_MODE=0
  18838. +CONFIG_SND_HDA_INPUT_JACK=y
  18839. +CONFIG_SND_HDA_PATCH_LOADER=y
  18840. +CONFIG_SND_HDA_HWDEP=y
  18841. +CONFIG_SND_HDA_CODEC_REALTEK=y
  18842. +CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS=y
  18843. +CONFIG_SND_HDA_CODEC_CA0110=y
  18844. +CONFIG_SND_HDA_CODEC_ANALOG=y
  18845. +CONFIG_SND_HDA_CODEC_SIGMATEL=y
  18846. +CONFIG_SND_HDA_CODEC_VIA=y
  18847. +CONFIG_SND_HDA_CODEC_CIRRUS=y
  18848. +CONFIG_SND_HDA_CODEC_CONEXANT=y
  18849. +CONFIG_SND_HDA_CODEC_CMEDIA=y
  18850. +CONFIG_SND_HDA_CODEC_SI3054=y
  18851. +CONFIG_SND_HDA_CODEC_HDMI=y
  18852. +CONFIG_SND_HDA_I915=y
  18853. +CONFIG_SND_HDA_CODEC_CA0132=y
  18854. +CONFIG_SND_HDA_CODEC_CA0132_DSP=y
  18855. +CONFIG_SND_HDA_GENERIC=y
  18856. +CONFIG_SND_HDA_POWER_SAVE=y
  18857. +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
  18858. +CONFIG_SND_HDA_RECONFIG=y
  18859. +CONFIG_SND_HDA_PREALLOC_SIZE=4096
  18860. +CONFIG_SND_HDSPM=m
  18861. +CONFIG_SND_ICE1712=m
  18862. +CONFIG_SND_ICE1724=m
  18863. +CONFIG_SND_INTEL8X0=y
  18864. +CONFIG_SND_INTEL8X0M=m
  18865. +CONFIG_SND_KORG1212=m
  18866. +CONFIG_SND_MAESTRO3=m
  18867. +CONFIG_SND_MAESTRO3_INPUT=y
  18868. +CONFIG_SND_MIXART=m
  18869. +CONFIG_SND_NM256=m
  18870. +CONFIG_SND_OXYGEN=m
  18871. +CONFIG_SND_RME32=m
  18872. +CONFIG_SND_PCSP=m
  18873. +CONFIG_SND_PCXHR=m
  18874. +CONFIG_SND_RIPTIDE=m
  18875. +CONFIG_SND_RME96=m
  18876. +CONFIG_SND_RME9652=m
  18877. +CONFIG_SND_SIS7019=m
  18878. +CONFIG_SND_SONICVIBES=m
  18879. +CONFIG_SND_HDSP=m
  18880. +CONFIG_SND_TRIDENT=m
  18881. +CONFIG_SND_VIA82XX=m
  18882. +CONFIG_SND_VIA82XX_MODEM=m
  18883. +CONFIG_SND_VIRTUOSO=m
  18884. +CONFIG_SND_VX222=m
  18885. +CONFIG_SND_YMFPCI=m
  18886. +CONFIG_SND_ASIHPI=m
  18887. +CONFIG_SND_LOLA=m
  18888. +
  18889. +#
  18890. +# ALSA USB devices
  18891. +#
  18892. +CONFIG_SND_USB=y
  18893. +CONFIG_SND_USB_CAIAQ=m
  18894. +CONFIG_SND_USB_CAIAQ_INPUT=y
  18895. +CONFIG_SND_USB_USX2Y=m
  18896. +CONFIG_SND_USB_US122L=m
  18897. +CONFIG_SND_USB_UA101=m
  18898. +CONFIG_SND_USB_6FIRE=m
  18899. +CONFIG_SND_USB_HIFACE=m
  18900. +
  18901. +#
  18902. +# PCMCIA devices
  18903. +#
  18904. +# CONFIG_SND_PCMCIA is not set
  18905. +
  18906. +CONFIG_SND_FIREWIRE=y
  18907. +CONFIG_SND_FIREWIRE_SPEAKERS=m
  18908. +CONFIG_SND_ISIGHT=m
  18909. +CONFIG_SND_SCS1X=m
  18910. +CONFIG_SND_DICE=m
  18911. +
  18912. +#
  18913. +# Open Sound System
  18914. +#
  18915. +# CONFIG_SOUND_PRIME is not set
  18916. +
  18917. +#
  18918. +# USB support
  18919. +#
  18920. +CONFIG_USB_SUPPORT=y
  18921. +# CONFIG_USB_DEBUG is not set
  18922. +
  18923. +# DEPRECATED: See bug 362221. Fix udev.
  18924. +# CONFIG_USB_DEVICE_CLASS is not set
  18925. +
  18926. +
  18927. +#
  18928. +# Miscellaneous USB options
  18929. +#
  18930. +
  18931. +# Deprecated.
  18932. +# CONFIG_USB_DEVICEFS is not set
  18933. +
  18934. +CONFIG_USB_DEFAULT_PERSIST=y
  18935. +# CONFIG_USB_DYNAMIC_MINORS is not set
  18936. +CONFIG_USB_SUSPEND=y
  18937. +
  18938. +#
  18939. +# USB Host Controller Drivers
  18940. +#
  18941. +CONFIG_USB_EHCI_ROOT_HUB_TT=y
  18942. +CONFIG_USB_EHCI_TT_NEWSCHED=y
  18943. +# CONFIG_USB_EHCI_MV is not set
  18944. +# CONFIG_USB_EHCI_HCD_PLATFORM is not set
  18945. +# CONFIG_USB_ISP116X_HCD is not set
  18946. +# CONFIG_USB_ISP1760_HCD is not set
  18947. +CONFIG_USB_ISP1362_HCD=m
  18948. +CONFIG_USB_FUSBH200_HCD=m
  18949. +# CONFIG_USB_FOTG210_HCD is not set
  18950. +# CONFIG_USB_GR_UDC is not set
  18951. +CONFIG_USB_OHCI_HCD=y
  18952. +CONFIG_USB_OHCI_HCD_PCI=y
  18953. +# CONFIG_USB_OHCI_HCD_SSB is not set
  18954. +# CONFIG_USB_HCD_TEST_MODE is not set
  18955. +# CONFIG_USB_OHCI_HCD_PLATFORM is not set
  18956. +CONFIG_USB_UHCI_HCD=y
  18957. +CONFIG_USB_SL811_HCD=m
  18958. +CONFIG_USB_SL811_HCD_ISO=y
  18959. +# CONFIG_USB_SL811_CS is not set
  18960. +# CONFIG_USB_R8A66597_HCD is not set
  18961. +CONFIG_USB_XHCI_HCD=y
  18962. +# CONFIG_USB_XHCI_HCD_DEBUGGING is not set
  18963. +
  18964. +#
  18965. +# USB Device Class drivers
  18966. +#
  18967. +
  18968. +#
  18969. +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
  18970. +#
  18971. +CONFIG_USB_ACM=m
  18972. +CONFIG_USB_PRINTER=m
  18973. +CONFIG_USB_WDM=m
  18974. +CONFIG_USB_TMC=m
  18975. +# CONFIG_BLK_DEV_UB is not set
  18976. +# CONFIG_USB_STORAGE_DEBUG is not set
  18977. +CONFIG_USB_STORAGE_CYPRESS_ATACB=m
  18978. +CONFIG_USB_STORAGE_DATAFAB=m
  18979. +CONFIG_USB_STORAGE_FREECOM=m
  18980. +CONFIG_USB_STORAGE_ISD200=m
  18981. +CONFIG_USB_STORAGE_SDDR09=m
  18982. +CONFIG_USB_STORAGE_SDDR55=m
  18983. +CONFIG_USB_STORAGE_JUMPSHOT=m
  18984. +CONFIG_USB_STORAGE_USBAT=y
  18985. +CONFIG_USB_STORAGE_ONETOUCH=m
  18986. +CONFIG_USB_STORAGE_ALAUDA=m
  18987. +CONFIG_USB_STORAGE_KARMA=m
  18988. +CONFIG_USB_STORAGE_REALTEK=m
  18989. +CONFIG_REALTEK_AUTOPM=y
  18990. +CONFIG_USB_STORAGE_ENE_UB6250=m
  18991. +# CONFIG_USB_LIBUSUAL is not set
  18992. +# CONFIG_USB_UAS is not set
  18993. +
  18994. +
  18995. +#
  18996. +# USB Human Interface Devices (HID)
  18997. +#
  18998. +CONFIG_USB_HID=y
  18999. +
  19000. +CONFIG_HID_SUPPORT=y
  19001. +
  19002. +CONFIG_HID=y
  19003. +CONFIG_I2C_HID=m
  19004. +CONFIG_HID_BATTERY_STRENGTH=y
  19005. +# debugging default is y upstream now
  19006. +CONFIG_HIDRAW=y
  19007. +CONFIG_UHID=m
  19008. +CONFIG_HID_PID=y
  19009. +CONFIG_LOGITECH_FF=y
  19010. +CONFIG_HID_LOGITECH_DJ=m
  19011. +CONFIG_LOGIWII_FF=y
  19012. +CONFIG_LOGIRUMBLEPAD2_FF=y
  19013. +CONFIG_PANTHERLORD_FF=y
  19014. +CONFIG_THRUSTMASTER_FF=y
  19015. +CONFIG_HID_WACOM=m
  19016. +CONFIG_HID_WACOM_POWER_SUPPLY=y
  19017. +CONFIG_ZEROPLUS_FF=y
  19018. +CONFIG_USB_HIDDEV=y
  19019. +CONFIG_USB_IDMOUSE=m
  19020. +CONFIG_DRAGONRISE_FF=y
  19021. +CONFIG_GREENASIA_FF=y
  19022. +CONFIG_SMARTJOYPLUS_FF=y
  19023. +CONFIG_LOGIG940_FF=y
  19024. +CONFIG_LOGIWHEELS_FF=y
  19025. +CONFIG_HID_MAGICMOUSE=y
  19026. +CONFIG_HID_MULTITOUCH=m
  19027. +CONFIG_HID_NTRIG=y
  19028. +CONFIG_HID_QUANTA=y
  19029. +CONFIG_HID_PRIMAX=m
  19030. +CONFIG_HID_PS3REMOTE=m
  19031. +CONFIG_HID_PRODIKEYS=m
  19032. +CONFIG_HID_DRAGONRISE=m
  19033. +CONFIG_HID_GYRATION=m
  19034. +CONFIG_HID_ICADE=m
  19035. +CONFIG_HID_TWINHAN=m
  19036. +CONFIG_HID_ORTEK=m
  19037. +CONFIG_HID_PANTHERLORD=m
  19038. +CONFIG_HID_PETALYNX=m
  19039. +CONFIG_HID_PICOLCD=m
  19040. +CONFIG_HID_RMI=m
  19041. +CONFIG_HID_ROCCAT=m
  19042. +CONFIG_HID_ROCCAT_KONE=m
  19043. +CONFIG_HID_SAMSUNG=m
  19044. +CONFIG_HID_SONY=m
  19045. +CONFIG_SONY_FF=y
  19046. +CONFIG_HID_SUNPLUS=m
  19047. +CONFIG_HID_STEELSERIES=m
  19048. +CONFIG_HID_GREENASIA=m
  19049. +CONFIG_HID_SMARTJOYPLUS=m
  19050. +CONFIG_HID_TOPSEED=m
  19051. +CONFIG_HID_THINGM=m
  19052. +CONFIG_HID_THRUSTMASTER=m
  19053. +CONFIG_HID_XINMO=m
  19054. +CONFIG_HID_ZEROPLUS=m
  19055. +CONFIG_HID_ZYDACRON=m
  19056. +CONFIG_HID_SENSOR_HUB=m
  19057. +CONFIG_HID_SENSOR_GYRO_3D=m
  19058. +CONFIG_HID_SENSOR_MAGNETOMETER_3D=m
  19059. +CONFIG_HID_SENSOR_ALS=m
  19060. +CONFIG_HID_SENSOR_ACCEL_3D=m
  19061. +CONFIG_HID_EMS_FF=m
  19062. +CONFIG_HID_ELECOM=m
  19063. +CONFIG_HID_ELO=m
  19064. +CONFIG_HID_UCLOGIC=m
  19065. +CONFIG_HID_WALTOP=m
  19066. +CONFIG_HID_ROCCAT_PYRA=m
  19067. +CONFIG_HID_ROCCAT_KONEPLUS=m
  19068. +CONFIG_HID_ACRUX=m
  19069. +CONFIG_HID_ACRUX_FF=y
  19070. +CONFIG_HID_KEYTOUCH=m
  19071. +CONFIG_HID_LCPOWER=m
  19072. +CONFIG_HID_LENOVO_TPKBD=m
  19073. +CONFIG_HID_ROCCAT_ARVO=m
  19074. +CONFIG_HID_ROCCAT_ISKU=m
  19075. +CONFIG_HID_ROCCAT_KOVAPLUS=m
  19076. +CONFIG_HID_HOLTEK=m
  19077. +CONFIG_HOLTEK_FF=y
  19078. +CONFIG_HID_HUION=m
  19079. +CONFIG_HID_SPEEDLINK=m
  19080. +CONFIG_HID_WIIMOTE=m
  19081. +CONFIG_HID_WIIMOTE_EXT=y
  19082. +CONFIG_HID_KYE=m
  19083. +CONFIG_HID_SAITEK=m
  19084. +CONFIG_HID_TIVO=m
  19085. +CONFIG_HID_GENERIC=y
  19086. +CONFIG_HID_AUREAL=m
  19087. +CONFIG_HID_APPLEIR=m
  19088. +
  19089. +
  19090. +#
  19091. +# USB Imaging devices
  19092. +#
  19093. +CONFIG_USB_MDC800=m
  19094. +CONFIG_USB_MICROTEK=m
  19095. +
  19096. +#
  19097. +# USB Multimedia devices
  19098. +#
  19099. +
  19100. +CONFIG_USB_DSBR=m
  19101. +# CONFIG_USB_ET61X251 is not set
  19102. +CONFIG_USB_M5602=m
  19103. +CONFIG_USB_STV06XX=m
  19104. +CONFIG_USB_GSPCA=m
  19105. +CONFIG_USB_GSPCA_MR97310A=m
  19106. +CONFIG_USB_GSPCA_BENQ=m
  19107. +CONFIG_USB_GSPCA_CONEX=m
  19108. +CONFIG_USB_GSPCA_CPIA1=m
  19109. +CONFIG_USB_GSPCA_ETOMS=m
  19110. +CONFIG_USB_GSPCA_FINEPIX=m
  19111. +CONFIG_USB_GSPCA_MARS=m
  19112. +CONFIG_USB_GSPCA_OV519=m
  19113. +CONFIG_USB_GSPCA_OV534=m
  19114. +CONFIG_USB_GSPCA_OV534_9=m
  19115. +CONFIG_USB_GSPCA_PAC207=m
  19116. +CONFIG_USB_GSPCA_PAC7311=m
  19117. +CONFIG_USB_GSPCA_SN9C2028=m
  19118. +CONFIG_USB_GSPCA_SN9C20X=m
  19119. +CONFIG_USB_GSPCA_SONIXB=m
  19120. +CONFIG_USB_GSPCA_SONIXJ=m
  19121. +CONFIG_USB_GSPCA_SPCA500=m
  19122. +CONFIG_USB_GSPCA_SPCA501=m
  19123. +CONFIG_USB_GSPCA_SPCA505=m
  19124. +CONFIG_USB_GSPCA_SPCA506=m
  19125. +CONFIG_USB_GSPCA_SPCA508=m
  19126. +CONFIG_USB_GSPCA_SPCA561=m
  19127. +CONFIG_USB_GSPCA_STK014=m
  19128. +CONFIG_USB_GSPCA_STK1135=m
  19129. +CONFIG_USB_GSPCA_SUNPLUS=m
  19130. +CONFIG_USB_GSPCA_T613=m
  19131. +CONFIG_USB_GSPCA_TOPRO=m
  19132. +CONFIG_USB_GSPCA_TV8532=m
  19133. +CONFIG_USB_GSPCA_VC032X=m
  19134. +CONFIG_USB_GSPCA_ZC3XX=m
  19135. +CONFIG_USB_GSPCA_SQ905=m
  19136. +CONFIG_USB_GSPCA_SQ905C=m
  19137. +CONFIG_USB_GSPCA_PAC7302=m
  19138. +CONFIG_USB_GSPCA_STV0680=m
  19139. +CONFIG_USB_GL860=m
  19140. +CONFIG_USB_GSPCA_JEILINJ=m
  19141. +CONFIG_USB_GSPCA_JL2005BCD=m
  19142. +CONFIG_USB_GSPCA_KONICA=m
  19143. +CONFIG_USB_GSPCA_XIRLINK_CIT=m
  19144. +CONFIG_USB_GSPCA_SPCA1528=m
  19145. +CONFIG_USB_GSPCA_SQ930X=m
  19146. +CONFIG_USB_GSPCA_NW80X=m
  19147. +CONFIG_USB_GSPCA_VICAM=m
  19148. +CONFIG_USB_GSPCA_KINECT=m
  19149. +CONFIG_USB_GSPCA_SE401=m
  19150. +
  19151. +CONFIG_USB_S2255=m
  19152. +# CONFIG_VIDEO_SH_MOBILE_CEU is not set
  19153. +# CONFIG_VIDEO_SH_MOBILE_CSI2 is not set
  19154. +# CONFIG_USB_SN9C102 is not set
  19155. +CONFIG_USB_ZR364XX=m
  19156. +
  19157. +#
  19158. +# USB Network adaptors
  19159. +#
  19160. +CONFIG_USB_CATC=m
  19161. +CONFIG_USB_HSO=m
  19162. +CONFIG_USB_KAWETH=m
  19163. +CONFIG_USB_PEGASUS=m
  19164. +CONFIG_USB_RTL8150=m
  19165. +CONFIG_USB_RTL8152=m
  19166. +CONFIG_USB_USBNET=m
  19167. +CONFIG_USB_SPEEDTOUCH=m
  19168. +CONFIG_USB_NET_AX8817X=m
  19169. +CONFIG_USB_NET_AX88179_178A=m
  19170. +CONFIG_USB_NET_DM9601=m
  19171. +CONFIG_USB_NET_SR9700=m
  19172. +CONFIG_USB_NET_SMSC95XX=m
  19173. +CONFIG_USB_NET_GL620A=m
  19174. +CONFIG_USB_NET_NET1080=m
  19175. +CONFIG_USB_NET_PLUSB=m
  19176. +CONFIG_USB_NET_MCS7830=m
  19177. +CONFIG_USB_NET_RNDIS_HOST=m
  19178. +CONFIG_USB_NET_CDC_SUBSET=m
  19179. +CONFIG_USB_NET_CDC_EEM=m
  19180. +CONFIG_USB_NET_CDC_NCM=m
  19181. +CONFIG_USB_NET_HUAWEI_CDC_NCM=m
  19182. +CONFIG_USB_NET_CDC_MBIM=m
  19183. +CONFIG_USB_NET_ZAURUS=m
  19184. +CONFIG_USB_NET_CX82310_ETH=m
  19185. +CONFIG_USB_NET_INT51X1=m
  19186. +CONFIG_USB_CDC_PHONET=m
  19187. +CONFIG_USB_IPHETH=m
  19188. +CONFIG_USB_SIERRA_NET=m
  19189. +CONFIG_USB_VL600=m
  19190. +
  19191. +#
  19192. +# USB Host-to-Host Cables
  19193. +#
  19194. +CONFIG_USB_AN2720=y
  19195. +CONFIG_USB_BELKIN=y
  19196. +
  19197. +#
  19198. +# Intelligent USB Devices/Gadgets
  19199. +#
  19200. +CONFIG_USB_ARMLINUX=y
  19201. +CONFIG_USB_EPSON2888=y
  19202. +CONFIG_USB_KC2190=y
  19203. +
  19204. +# CONFIG_USB_MUSB_HDRC is not set
  19205. +
  19206. +#
  19207. +# USB port drivers
  19208. +#
  19209. +CONFIG_USB_USS720=m
  19210. +
  19211. +#
  19212. +# USB Serial Converter support
  19213. +#
  19214. +CONFIG_USB_SERIAL=y
  19215. +CONFIG_USB_SERIAL_GENERIC=y
  19216. +CONFIG_USB_SERIAL_SIMPLE=m
  19217. +CONFIG_USB_SERIAL_AIRCABLE=m
  19218. +CONFIG_USB_SERIAL_ARK3116=m
  19219. +CONFIG_USB_SERIAL_BELKIN=m
  19220. +CONFIG_USB_SERIAL_CH341=m
  19221. +CONFIG_USB_SERIAL_CYPRESS_M8=m
  19222. +CONFIG_USB_SERIAL_CYBERJACK=m
  19223. +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
  19224. +CONFIG_USB_SERIAL_CP210X=m
  19225. +CONFIG_USB_SERIAL_QUALCOMM=m
  19226. +CONFIG_USB_SERIAL_SYMBOL=m
  19227. +CONFIG_USB_SERIAL_EDGEPORT=m
  19228. +CONFIG_USB_SERIAL_EDGEPORT_TI=m
  19229. +CONFIG_USB_SERIAL_EMPEG=m
  19230. +# CONFIG_USB_SERIAL_F81232 is not set
  19231. +CONFIG_USB_SERIAL_FTDI_SIO=m
  19232. +CONFIG_USB_SERIAL_FUNSOFT=m
  19233. +CONFIG_USB_SERIAL_GARMIN=m
  19234. +CONFIG_USB_SERIAL_HP4X=m
  19235. +CONFIG_USB_SERIAL_IPAQ=m
  19236. +CONFIG_USB_SERIAL_IPW=m
  19237. +CONFIG_USB_SERIAL_IR=m
  19238. +CONFIG_USB_SERIAL_IUU=m
  19239. +CONFIG_USB_SERIAL_KEYSPAN_PDA=m
  19240. +CONFIG_USB_SERIAL_KEYSPAN=m
  19241. +CONFIG_USB_SERIAL_KEYSPAN_MPR=y
  19242. +CONFIG_USB_SERIAL_KEYSPAN_USA28=y
  19243. +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
  19244. +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
  19245. +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
  19246. +CONFIG_USB_SERIAL_KEYSPAN_USA19=y
  19247. +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
  19248. +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
  19249. +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
  19250. +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
  19251. +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
  19252. +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
  19253. +CONFIG_USB_SERIAL_KLSI=m
  19254. +CONFIG_USB_SERIAL_KOBIL_SCT=m
  19255. +CONFIG_USB_SERIAL_MCT_U232=m
  19256. +# CONFIG_USB_SERIAL_METRO is not set
  19257. +CONFIG_USB_SERIAL_MOS7720=m
  19258. +CONFIG_USB_SERIAL_MOS7715_PARPORT=y
  19259. +# CONFIG_USB_SERIAL_ZIO is not set
  19260. +# CONFIG_USB_SERIAL_WISHBONE is not set
  19261. +# CONFIG_USB_SERIAL_ZTE is not set
  19262. +CONFIG_USB_SERIAL_MOS7840=m
  19263. +CONFIG_USB_SERIAL_MOTOROLA=m
  19264. +# CONFIG_USB_SERIAL_MXUPORT is not set
  19265. +CONFIG_USB_SERIAL_NAVMAN=m
  19266. +CONFIG_USB_SERIAL_OPTION=m
  19267. +CONFIG_USB_SERIAL_OTI6858=m
  19268. +CONFIG_USB_SERIAL_OPTICON=m
  19269. +CONFIG_USB_SERIAL_OMNINET=m
  19270. +CONFIG_USB_SERIAL_PL2303=m
  19271. +# CONFIG_USB_SERIAL_QUATECH2 is not set
  19272. +CONFIG_USB_SERIAL_SAFE=m
  19273. +CONFIG_USB_SERIAL_SAFE_PADDED=y
  19274. +CONFIG_USB_SERIAL_SIERRAWIRELESS=m
  19275. +CONFIG_USB_SERIAL_SIEMENS_MPI=m
  19276. +CONFIG_USB_SERIAL_SPCP8X5=m
  19277. +CONFIG_USB_SERIAL_TI=m
  19278. +CONFIG_USB_SERIAL_VISOR=m
  19279. +CONFIG_USB_SERIAL_WHITEHEAT=m
  19280. +CONFIG_USB_SERIAL_XIRCOM=m
  19281. +CONFIG_USB_SERIAL_QCAUX=m
  19282. +CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m
  19283. +CONFIG_USB_SERIAL_XSENS_MT=m
  19284. +CONFIG_USB_SERIAL_DEBUG=m
  19285. +CONFIG_USB_SERIAL_SSU100=m
  19286. +CONFIG_USB_SERIAL_QT2=m
  19287. +CONFIG_USB_SERIAL_FLASHLOADER=m
  19288. +CONFIG_USB_SERIAL_SUUNTO=m
  19289. +CONFIG_USB_SERIAL_CONSOLE=y
  19290. +
  19291. +CONFIG_USB_EZUSB=y
  19292. +CONFIG_USB_EMI62=m
  19293. +CONFIG_USB_LED=m
  19294. +# CONFIG_USB_CYPRESS_CY7C63 is not set
  19295. +
  19296. +#
  19297. +# USB Miscellaneous drivers
  19298. +#
  19299. +
  19300. +CONFIG_USB_ADUTUX=m
  19301. +CONFIG_USB_SEVSEG=m
  19302. +CONFIG_USB_ALI_M5632=y
  19303. +CONFIG_USB_APPLEDISPLAY=m
  19304. +
  19305. +# Physical Layer USB driver
  19306. +# CONFIG_USB_OTG_FSM is not set
  19307. +
  19308. +# CONFIG_GENERIC_PHY is not set
  19309. +# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set
  19310. +# CONFIG_PHY_EXYNOS_DP_VIDEO is not set
  19311. +# CONFIG_OMAP_USB2 is not set
  19312. +# CONFIG_OMAP_USB3 is not set
  19313. +# CONFIG_OMAP_CONTROL_USB is not set
  19314. +# CONFIG_AM335X_PHY_USB is not set
  19315. +# CONFIG_SAMSUNG_USBPHY is not set
  19316. +# CONFIG_SAMSUNG_USB2PHY is not set
  19317. +# CONFIG_SAMSUNG_USB3PHY is not set
  19318. +# CONFIG_BCM_KONA_USB2_PHY is not set
  19319. +CONFIG_USB_RCAR_PHY=m
  19320. +CONFIG_USB_ATM=m
  19321. +CONFIG_USB_CXACRU=m
  19322. +# CONFIG_USB_C67X00_HCD is not set
  19323. +# CONFIG_USB_CYTHERM is not set
  19324. +CONFIG_USB_EMI26=m
  19325. +CONFIG_USB_FTDI_ELAN=m
  19326. +CONFIG_USB_FILE_STORAGE=m
  19327. +# CONFIG_USB_FILE_STORAGE_TEST is not set
  19328. +# CONFIG_USB_DWC3 is not set
  19329. +# CONFIG_USB_GADGETFS is not set
  19330. +# CONFIG_USB_OXU210HP_HCD is not set
  19331. +CONFIG_USB_IOWARRIOR=m
  19332. +CONFIG_USB_ISIGHTFW=m
  19333. +CONFIG_USB_YUREX=m
  19334. +CONFIG_USB_EZUSB_FX2=m
  19335. +CONFIG_USB_HSIC_USB3503=m
  19336. +CONFIG_USB_LCD=m
  19337. +CONFIG_USB_LD=m
  19338. +CONFIG_USB_LEGOTOWER=m
  19339. +CONFIG_USB_MON=y
  19340. +CONFIG_USB_PWC=m
  19341. +CONFIG_USB_PWC_INPUT_EVDEV=y
  19342. +# CONFIG_USB_PWC_DEBUG is not set
  19343. +# CONFIG_USB_RIO500 is not set
  19344. +CONFIG_USB_SISUSBVGA=m
  19345. +CONFIG_USB_SISUSBVGA_CON=y
  19346. +CONFIG_RADIO_SI470X=y
  19347. +CONFIG_USB_KEENE=m
  19348. +CONFIG_USB_MA901=m
  19349. +CONFIG_USB_SI470X=m
  19350. +CONFIG_I2C_SI470X=m
  19351. +CONFIG_RADIO_SI4713=m
  19352. +# CONFIG_RADIO_TEF6862 is not set
  19353. +CONFIG_USB_MR800=m
  19354. +CONFIG_USB_STKWEBCAM=m
  19355. +# CONFIG_USB_TEST is not set
  19356. +# CONFIG_USB_EHSET_TEST_FIXTURE is not set
  19357. +CONFIG_USB_TRANCEVIBRATOR=m
  19358. +CONFIG_USB_U132_HCD=m
  19359. +CONFIG_USB_UEAGLEATM=m
  19360. +CONFIG_USB_XUSBATM=m
  19361. +
  19362. +# CONFIG_USB_DWC2 is not set
  19363. +
  19364. +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
  19365. +
  19366. +# CONFIG_USB_ISP1301 is not set
  19367. +
  19368. +# CONFIG_USB_OTG is not set
  19369. +
  19370. +#
  19371. +# Sonics Silicon Backplane
  19372. +#
  19373. +CONFIG_SSB=m
  19374. +CONFIG_SSB_PCIHOST=y
  19375. +CONFIG_SSB_SDIOHOST=y
  19376. +CONFIG_SSB_PCMCIAHOST=y
  19377. +# CONFIG_SSB_SILENT is not set
  19378. +# CONFIG_SSB_DEBUG is not set
  19379. +CONFIG_SSB_DRIVER_PCICORE=y
  19380. +CONFIG_SSB_DRIVER_GPIO=y
  19381. +
  19382. +# Multifunction USB devices
  19383. +# CONFIG_MFD_PCF50633 is not set
  19384. +CONFIG_PCF50633_ADC=m
  19385. +CONFIG_PCF50633_GPIO=m
  19386. +# CONFIG_AB3100_CORE is not set
  19387. +CONFIG_INPUT_PCF50633_PMU=m
  19388. +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
  19389. +
  19390. +CONFIG_MFD_SUPPORT=y
  19391. +CONFIG_MFD_VX855=m
  19392. +CONFIG_MFD_SM501=m
  19393. +CONFIG_MFD_SM501_GPIO=y
  19394. +CONFIG_MFD_RTSX_PCI=m
  19395. +# CONFIG_MFD_TI_AM335X_TSCADC is not set
  19396. +CONFIG_MFD_VIPERBOARD=m
  19397. +# CONFIG_MFD_RETU is not set
  19398. +# CONFIG_MFD_TC6393XB is not set
  19399. +# CONFIG_MFD_WM8400 is not set
  19400. +# CONFIG_MFD_WM8350_I2C is not set
  19401. +# CONFIG_MFD_WM8350 is not set
  19402. +# CONFIG_MFD_WM831X is not set
  19403. +# CONFIG_AB3100_OTP is not set
  19404. +# CONFIG_MFD_TIMBERDALE is not set
  19405. +# CONFIG_MFD_WM8994 is not set
  19406. +# CONFIG_MFD_88PM860X is not set
  19407. +# CONFIG_LPC_SCH is not set
  19408. +# CONFIG_LPC_ICH is not set
  19409. +# CONFIG_HTC_I2CPLD is not set
  19410. +# CONFIG_MFD_MAX8925 is not set
  19411. +# CONFIG_MFD_ASIC3 is not set
  19412. +# CONFIG_MFD_AS3722 is not set
  19413. +# CONFIG_HTC_EGPIO is not set
  19414. +# CONFIG_TPS6507X is not set
  19415. +# CONFIG_ABX500_CORE is not set
  19416. +# CONFIG_MFD_RDC321X is not set
  19417. +# CONFIG_MFD_JANZ_CMODIO is not set
  19418. +# CONFIG_MFD_KEMPLD is not set
  19419. +# CONFIG_MFD_WM831X_I2C is not set
  19420. +# CONFIG_MFD_CS5535 is not set
  19421. +# CONFIG_MFD_STMPE is not set
  19422. +# CONFIG_MFD_MAX8998 is not set
  19423. +# CONFIG_MFD_TPS6586X is not set
  19424. +# CONFIG_MFD_TC3589X is not set
  19425. +# CONFIG_MFD_WL1273_CORE is not set
  19426. +# CONFIG_MFD_TPS65217 is not set
  19427. +# CONFIG_MFD_LM3533 is not set
  19428. +# CONFIG_MFD_ARIZONA is not set
  19429. +# CONFIG_MFD_ARIZONA_I2C is not set
  19430. +# CONFIG_MFD_CROS_EC is not set
  19431. +# CONFIG_MFD_TPS65912 is not set
  19432. +# CONFIG_MFD_SYSCON is not set
  19433. +# CONFIG_MFD_DA9063 is not set
  19434. +# CONFIG_MFD_LP3943 is not set
  19435. +
  19436. +#
  19437. +# File systems
  19438. +#
  19439. +CONFIG_MISC_FILESYSTEMS=y
  19440. +
  19441. +# ext4 is used for ext2 and ext3 filesystems
  19442. +CONFIG_JBD2=y
  19443. +CONFIG_FS_MBCACHE=y
  19444. +CONFIG_REISERFS_FS=m
  19445. +# CONFIG_REISERFS_CHECK is not set
  19446. +CONFIG_REISERFS_PROC_INFO=y
  19447. +CONFIG_REISERFS_FS_XATTR=y
  19448. +CONFIG_REISERFS_FS_POSIX_ACL=y
  19449. +CONFIG_REISERFS_FS_SECURITY=y
  19450. +CONFIG_JFS_FS=m
  19451. +# CONFIG_JFS_DEBUG is not set
  19452. +# CONFIG_JFS_STATISTICS is not set
  19453. +CONFIG_JFS_POSIX_ACL=y
  19454. +CONFIG_JFS_SECURITY=y
  19455. +CONFIG_XFS_FS=m
  19456. +# CONFIG_XFS_DEBUG is not set
  19457. +# CONFIG_XFS_RT is not set
  19458. +CONFIG_XFS_QUOTA=y
  19459. +CONFIG_XFS_POSIX_ACL=y
  19460. +CONFIG_MINIX_FS=m
  19461. +CONFIG_ROMFS_FS=m
  19462. +# CONFIG_QFMT_V1 is not set
  19463. +CONFIG_QFMT_V2=y
  19464. +CONFIG_QUOTACTL=y
  19465. +CONFIG_DNOTIFY=y
  19466. +# Autofsv3 is obsolete.
  19467. +# systemd is dependant upon AUTOFS, so build it in.
  19468. +# CONFIG_EXOFS_FS is not set
  19469. +# CONFIG_EXOFS_DEBUG is not set
  19470. +CONFIG_NILFS2_FS=m
  19471. +# CONFIG_LOGFS is not set
  19472. +CONFIG_CEPH_FS=m
  19473. +CONFIG_CEPH_FSCACHE=y
  19474. +CONFIG_BLK_DEV_RBD=m
  19475. +CONFIG_CEPH_LIB=m
  19476. +CONFIG_CEPH_FS_POSIX_ACL=y
  19477. +# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set
  19478. +
  19479. +CONFIG_FSCACHE=m
  19480. +CONFIG_FSCACHE_STATS=y
  19481. +# CONFIG_FSCACHE_HISTOGRAM is not set
  19482. +# CONFIG_FSCACHE_DEBUG is not set
  19483. +CONFIG_FSCACHE_OBJECT_LIST=y
  19484. +
  19485. +CONFIG_CACHEFILES=m
  19486. +# CONFIG_CACHEFILES_DEBUG is not set
  19487. +# CONFIG_CACHEFILES_HISTOGRAM is not set
  19488. +
  19489. +#
  19490. +# CD-ROM/DVD Filesystems
  19491. +#
  19492. +
  19493. +#
  19494. +# DOS/FAT/NT Filesystems
  19495. +#
  19496. +CONFIG_FAT_FS=m
  19497. +CONFIG_FAT_DEFAULT_CODEPAGE=437
  19498. +CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
  19499. +# CONFIG_NTFS_FS is not set
  19500. +
  19501. +#
  19502. +# Pseudo filesystems
  19503. +#
  19504. +CONFIG_PROC_FS=y
  19505. +CONFIG_PROC_KCORE=y
  19506. +CONFIG_PROC_VMCORE=y
  19507. +CONFIG_TMPFS_POSIX_ACL=y
  19508. +CONFIG_TMPFS_XATTR=y
  19509. +CONFIG_HUGETLBFS=y
  19510. +CONFIG_HUGETLB_PAGE=y
  19511. +# CONFIG_DEBUG_FS is not set
  19512. +
  19513. +#
  19514. +# Miscellaneous filesystems
  19515. +#
  19516. +# CONFIG_ADFS_FS is not set
  19517. +CONFIG_AFFS_FS=m
  19518. +CONFIG_ECRYPT_FS=m
  19519. +# CONFIG_ECRYPT_FS_MESSAGING is not set
  19520. +CONFIG_HFS_FS=m
  19521. +CONFIG_HFSPLUS_FS=m
  19522. +# CONFIG_HFSPLUS_FS_POSIX_ACL is not set
  19523. +CONFIG_BEFS_FS=m
  19524. +# CONFIG_BEFS_DEBUG is not set
  19525. +# CONFIG_BFS_FS is not set
  19526. +# CONFIG_EFS_FS is not set
  19527. +
  19528. +CONFIG_CRAMFS=m
  19529. +CONFIG_SQUASHFS=m
  19530. +CONFIG_SQUASHFS_XATTR=y
  19531. +CONFIG_SQUASHFS_LZO=y
  19532. +CONFIG_SQUASHFS_XZ=y
  19533. +CONFIG_SQUASHFS_ZLIB=y
  19534. +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
  19535. +# CONFIG_SQUASHFS_EMBEDDED is not set
  19536. +# CONFIG_VXFS_FS is not set
  19537. +# CONFIG_HPFS_FS is not set
  19538. +# CONFIG_QNX4FS_FS is not set
  19539. +# CONFIG_QNX6FS_FS is not set
  19540. +CONFIG_SYSV_FS=m
  19541. +CONFIG_UFS_FS=m
  19542. +# CONFIG_UFS_FS_WRITE is not set
  19543. +# CONFIG_UFS_DEBUG is not set
  19544. +CONFIG_9P_FS=m
  19545. +CONFIG_9P_FSCACHE=y
  19546. +CONFIG_9P_FS_POSIX_ACL=y
  19547. +CONFIG_9P_FS_SECURITY=y
  19548. +# CONFIG_OMFS_FS is not set
  19549. +CONFIG_CUSE=m
  19550. +# CONFIG_F2FS_FS is not set
  19551. +
  19552. +#
  19553. +# Network File Systems
  19554. +#
  19555. +CONFIG_NETWORK_FILESYSTEMS=y
  19556. +# CONFIG_NFS_V2 is not set
  19557. +CONFIG_NFS_V3=y
  19558. +CONFIG_NFS_SWAP=y
  19559. +CONFIG_NFS_V4_1=y
  19560. +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
  19561. +# CONFIG_NFS_V4_1_MIGRATION is not set
  19562. +CONFIG_NFS_V4_2=y
  19563. +CONFIG_NFSD=m
  19564. +CONFIG_NFSD_V3=y
  19565. +CONFIG_NFSD_V3_ACL=y
  19566. +CONFIG_NFSD_V4=y
  19567. +CONFIG_NFSD_V4_SECURITY_LABEL=y
  19568. +CONFIG_NFS_FSCACHE=y
  19569. +# CONFIG_NFS_USE_LEGACY_DNS is not set
  19570. +CONFIG_PNFS_OBJLAYOUT=m
  19571. +CONFIG_PNFS_BLOCK=m
  19572. +CONFIG_LOCKD=m
  19573. +CONFIG_LOCKD_V4=y
  19574. +CONFIG_EXPORTFS=y
  19575. +CONFIG_SUNRPC=m
  19576. +CONFIG_SUNRPC_GSS=m
  19577. +CONFIG_SUNRPC_XPRT_RDMA=m
  19578. +CONFIG_SUNRPC_DEBUG=y
  19579. +CONFIG_RPCSEC_GSS_KRB5=m
  19580. +CONFIG_CIFS=m
  19581. +CONFIG_CIFS_STATS=y
  19582. +# CONFIG_CIFS_STATS2 is not set
  19583. +CONFIG_CIFS_SMB2=y
  19584. +CONFIG_CIFS_UPCALL=y
  19585. +CONFIG_CIFS_XATTR=y
  19586. +CONFIG_CIFS_POSIX=y
  19587. +CONFIG_CIFS_FSCACHE=y
  19588. +CONFIG_CIFS_ACL=y
  19589. +CONFIG_CIFS_WEAK_PW_HASH=y
  19590. +CONFIG_CIFS_DEBUG=y
  19591. +# CONFIG_CIFS_DEBUG2 is not set
  19592. +CONFIG_CIFS_DFS_UPCALL=y
  19593. +CONFIG_CIFS_NFSD_EXPORT=y
  19594. +CONFIG_NCP_FS=m
  19595. +CONFIG_NCPFS_PACKET_SIGNING=y
  19596. +CONFIG_NCPFS_IOCTL_LOCKING=y
  19597. +CONFIG_NCPFS_STRONG=y
  19598. +CONFIG_NCPFS_NFS_NS=y
  19599. +CONFIG_NCPFS_OS2_NS=y
  19600. +CONFIG_NCPFS_SMALLDOS=y
  19601. +CONFIG_NCPFS_NLS=y
  19602. +CONFIG_NCPFS_EXTRAS=y
  19603. +CONFIG_CODA_FS=m
  19604. +# CONFIG_AFS_FS is not set
  19605. +# CONFIG_AF_RXRPC is not set
  19606. +
  19607. +CONFIG_OCFS2_FS=m
  19608. +# CONFIG_OCFS2_DEBUG_FS is not set
  19609. +# CONFIG_OCFS2_DEBUG_MASKLOG is not set
  19610. +CONFIG_OCFS2_FS_O2CB=m
  19611. +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
  19612. +# CONFIG_OCFS2_FS_STATS is not set
  19613. +
  19614. +CONFIG_BTRFS_FS=m
  19615. +CONFIG_BTRFS_FS_POSIX_ACL=y
  19616. +# Maybe see if we want this on for debug kernels?
  19617. +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
  19618. +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
  19619. +# CONFIG_BTRFS_DEBUG is not set
  19620. +# CONFIG_BTRFS_ASSERT is not set
  19621. +
  19622. +CONFIG_CONFIGFS_FS=y
  19623. +
  19624. +CONFIG_DLM=m
  19625. +CONFIG_DLM_DEBUG=y
  19626. +CONFIG_GFS2_FS=m
  19627. +CONFIG_GFS2_FS_LOCKING_DLM=y
  19628. +
  19629. +
  19630. +CONFIG_UBIFS_FS_XATTR=y
  19631. +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
  19632. +# CONFIG_UBIFS_FS_DEBUG is not set
  19633. +
  19634. +#
  19635. +# Partition Types
  19636. +#
  19637. +CONFIG_PARTITION_ADVANCED=y
  19638. +# CONFIG_ACORN_PARTITION is not set
  19639. +CONFIG_AIX_PARTITION=y
  19640. +CONFIG_AMIGA_PARTITION=y
  19641. +# CONFIG_ATARI_PARTITION is not set
  19642. +CONFIG_BSD_DISKLABEL=y
  19643. +CONFIG_EFI_PARTITION=y
  19644. +CONFIG_KARMA_PARTITION=y
  19645. +CONFIG_LDM_PARTITION=y
  19646. +# CONFIG_LDM_DEBUG is not set
  19647. +CONFIG_MAC_PARTITION=y
  19648. +CONFIG_MSDOS_PARTITION=y
  19649. +CONFIG_MINIX_SUBPARTITION=y
  19650. +CONFIG_OSF_PARTITION=y
  19651. +CONFIG_SGI_PARTITION=y
  19652. +CONFIG_SOLARIS_X86_PARTITION=y
  19653. +CONFIG_SUN_PARTITION=y
  19654. +# CONFIG_SYSV68_PARTITION is not set
  19655. +CONFIG_UNIXWARE_DISKLABEL=y
  19656. +# CONFIG_ULTRIX_PARTITION is not set
  19657. +# CONFIG_CMDLINE_PARTITION is not set
  19658. +
  19659. +CONFIG_NLS=y
  19660. +
  19661. +#
  19662. +# Native Language Support
  19663. +#
  19664. +CONFIG_NLS_CODEPAGE_737=m
  19665. +CONFIG_NLS_CODEPAGE_775=m
  19666. +CONFIG_NLS_CODEPAGE_850=m
  19667. +CONFIG_NLS_CODEPAGE_852=m
  19668. +CONFIG_NLS_CODEPAGE_855=m
  19669. +CONFIG_NLS_CODEPAGE_857=m
  19670. +CONFIG_NLS_CODEPAGE_860=m
  19671. +CONFIG_NLS_CODEPAGE_861=m
  19672. +CONFIG_NLS_CODEPAGE_862=m
  19673. +CONFIG_NLS_CODEPAGE_863=m
  19674. +CONFIG_NLS_CODEPAGE_864=m
  19675. +CONFIG_NLS_CODEPAGE_865=m
  19676. +CONFIG_NLS_CODEPAGE_866=m
  19677. +CONFIG_NLS_CODEPAGE_869=m
  19678. +CONFIG_NLS_CODEPAGE_936=m
  19679. +CONFIG_NLS_CODEPAGE_950=m
  19680. +CONFIG_NLS_CODEPAGE_932=m
  19681. +CONFIG_NLS_CODEPAGE_949=m
  19682. +CONFIG_NLS_CODEPAGE_874=m
  19683. +CONFIG_NLS_ISO8859_8=m
  19684. +CONFIG_NLS_CODEPAGE_1250=m
  19685. +CONFIG_NLS_CODEPAGE_1251=m
  19686. +CONFIG_NLS_ISO8859_2=m
  19687. +CONFIG_NLS_ISO8859_3=m
  19688. +CONFIG_NLS_ISO8859_4=m
  19689. +CONFIG_NLS_ISO8859_5=m
  19690. +CONFIG_NLS_ISO8859_6=m
  19691. +CONFIG_NLS_ISO8859_7=m
  19692. +CONFIG_NLS_ISO8859_9=m
  19693. +CONFIG_NLS_ISO8859_13=m
  19694. +CONFIG_NLS_ISO8859_14=m
  19695. +CONFIG_NLS_KOI8_R=m
  19696. +CONFIG_NLS_KOI8_U=m
  19697. +CONFIG_NLS_MAC_ROMAN=m
  19698. +CONFIG_NLS_MAC_CELTIC=m
  19699. +CONFIG_NLS_MAC_CENTEURO=m
  19700. +CONFIG_NLS_MAC_CROATIAN=m
  19701. +CONFIG_NLS_MAC_CYRILLIC=m
  19702. +CONFIG_NLS_MAC_GAELIC=m
  19703. +CONFIG_NLS_MAC_GREEK=m
  19704. +CONFIG_NLS_MAC_ICELAND=m
  19705. +CONFIG_NLS_MAC_INUIT=m
  19706. +CONFIG_NLS_MAC_ROMANIAN=m
  19707. +CONFIG_NLS_MAC_TURKISH=m
  19708. +
  19709. +#
  19710. +# Profiling support
  19711. +#
  19712. +CONFIG_PROFILING=y
  19713. +CONFIG_OPROFILE=m
  19714. +CONFIG_OPROFILE_EVENT_MULTIPLEX=y
  19715. +
  19716. +#
  19717. +# Kernel hacking
  19718. +#
  19719. +CONFIG_DEBUG_KERNEL=y
  19720. +CONFIG_FRAME_WARN=1024
  19721. +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x0
  19722. +# CONFIG_DEBUG_INFO is not set
  19723. +CONFIG_FRAME_POINTER=y
  19724. +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
  19725. +# CONFIG_DEBUG_DRIVER is not set
  19726. +CONFIG_HEADERS_CHECK=y
  19727. +# CONFIG_LKDTM is not set
  19728. +# CONFIG_NOTIFIER_ERROR_INJECTION is not set
  19729. +# CONFIG_READABLE_ASM is not set
  19730. +
  19731. +# CONFIG_RT_MUTEX_TESTER is not set
  19732. +# CONFIG_DEBUG_LOCKDEP is not set
  19733. +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
  19734. +
  19735. +# DEBUG options that don't get enabled/disabled with 'make debug/release'
  19736. +
  19737. +# This generates a huge amount of dmesg spew
  19738. +# CONFIG_DEBUG_KOBJECT is not set
  19739. +#
  19740. +# This breaks booting until the module patches are in-tree
  19741. +# CONFIG_DEBUG_KOBJECT_RELEASE is not set
  19742. +#
  19743. +#
  19744. +# These debug options are deliberatly left on (even in 'make release' kernels).
  19745. +# They aren't that much of a performance impact, and the value
  19746. +# from getting useful bug-reports makes it worth leaving them on.
  19747. +# CONFIG_DEBUG_HIGHMEM is not set
  19748. +# CONFIG_DEBUG_SHIRQ is not set
  19749. +CONFIG_BOOT_PRINTK_DELAY=y
  19750. +CONFIG_DEBUG_DEVRES=y
  19751. +CONFIG_DEBUG_RODATA_TEST=y
  19752. +CONFIG_DEBUG_NX_TEST=m
  19753. +CONFIG_DEBUG_SET_MODULE_RONX=y
  19754. +CONFIG_DEBUG_BOOT_PARAMS=y
  19755. +# CONFIG_DEBUG_VM is not set
  19756. +# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
  19757. +CONFIG_LOCKUP_DETECTOR=y
  19758. +# CONFIG_DEBUG_INFO_REDUCED is not set
  19759. +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
  19760. +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
  19761. +# CONFIG_PANIC_ON_OOPS is not set
  19762. +CONFIG_PANIC_TIMEOUT=0
  19763. +CONFIG_ATOMIC64_SELFTEST=y
  19764. +CONFIG_MEMORY_FAILURE=y
  19765. +CONFIG_HWPOISON_INJECT=m
  19766. +CONFIG_CROSS_MEMORY_ATTACH=y
  19767. +# CONFIG_DEBUG_SECTION_MISMATCH is not set
  19768. +# CONFIG_BACKTRACE_SELF_TEST is not set
  19769. +CONFIG_RESOURCE_COUNTERS=y
  19770. +# CONFIG_DEBUG_VIRTUAL is not set
  19771. +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
  19772. +CONFIG_EARLY_PRINTK_DBGP=y
  19773. +# CONFIG_PAGE_POISONING is not set
  19774. +# CONFIG_CRASH_DUMP is not set
  19775. +# CONFIG_CRASH is not set
  19776. +# CONFIG_GCOV_KERNEL is not set
  19777. +# CONFIG_RAMOOPS is not set
  19778. +
  19779. +
  19780. +#
  19781. +# Security options
  19782. +#
  19783. +CONFIG_SECURITY=y
  19784. +# CONFIG_SECURITY_DMESG_RESTRICT is not set
  19785. +CONFIG_SECURITY_NETWORK=y
  19786. +CONFIG_SECURITY_NETWORK_XFRM=y
  19787. +# CONFIG_SECURITY_PATH is not set
  19788. +CONFIG_SECURITY_SELINUX=y
  19789. +CONFIG_SECURITY_SELINUX_BOOTPARAM=y
  19790. +CONFIG_SECURITY_SELINUX_DISABLE=y
  19791. +CONFIG_SECURITY_SELINUX_DEVELOP=y
  19792. +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
  19793. +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
  19794. +CONFIG_SECURITY_SELINUX_AVC_STATS=y
  19795. +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
  19796. +# CONFIG_SECURITY_SMACK is not set
  19797. +# CONFIG_SECURITY_TOMOYO is not set
  19798. +# CONFIG_SECURITY_APPARMOR is not set
  19799. +# CONFIG_SECURITY_YAMA is not set
  19800. +CONFIG_AUDIT=y
  19801. +CONFIG_AUDITSYSCALL=y
  19802. +# http://lists.fedoraproject.org/pipermail/kernel/2013-February/004125.html
  19803. +CONFIG_AUDIT_LOGINUID_IMMUTABLE=y
  19804. +
  19805. +CONFIG_SECCOMP=y
  19806. +
  19807. +# CONFIG_SSBI is not set
  19808. +
  19809. +#
  19810. +# Cryptographic options
  19811. +#
  19812. +CONFIG_CRYPTO=y
  19813. +CONFIG_CRYPTO_FIPS=y
  19814. +CONFIG_CRYPTO_USER_API_HASH=y
  19815. +CONFIG_CRYPTO_USER_API_SKCIPHER=y
  19816. +CONFIG_CRYPTO_MANAGER=y
  19817. +# Note, CONFIG_CRYPTO_MANAGER_DISABLE_TESTS needs to be unset, or FIPS will be disabled.
  19818. +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
  19819. +CONFIG_CRYPTO_HW=y
  19820. +CONFIG_CRYPTO_BLKCIPHER=y
  19821. +# CONFIG_CRYPTO_CRYPTD is not set
  19822. +CONFIG_CRYPTO_AES=y
  19823. +CONFIG_CRYPTO_ARC4=m
  19824. +CONFIG_CRYPTO_ANUBIS=m
  19825. +CONFIG_CRYPTO_AUTHENC=m
  19826. +CONFIG_CRYPTO_CAST5=m
  19827. +CONFIG_CRYPTO_CAST6=m
  19828. +CONFIG_CRYPTO_CRC32C=y
  19829. +CONFIG_CRYPTO_CRC32=m
  19830. +CONFIG_CRYPTO_CTR=y
  19831. +CONFIG_CRYPTO_DEFLATE=m
  19832. +CONFIG_CRYPTO_FCRYPT=m
  19833. +CONFIG_CRYPTO_GF128MUL=m
  19834. +CONFIG_CRYPTO_CMAC=m
  19835. +CONFIG_CRYPTO_HMAC=y
  19836. +CONFIG_CRYPTO_KHAZAD=m
  19837. +CONFIG_CRYPTO_LZO=m
  19838. +CONFIG_CRYPTO_LZ4=m
  19839. +CONFIG_CRYPTO_LZ4HC=m
  19840. +CONFIG_CRYPTO_NULL=m
  19841. +CONFIG_CRYPTO_PCBC=m
  19842. +CONFIG_CRYPTO_SALSA20=m
  19843. +CONFIG_CRYPTO_SALSA20_586=m
  19844. +CONFIG_CRYPTO_SEED=m
  19845. +CONFIG_CRYPTO_SEQIV=m
  19846. +CONFIG_CRYPTO_SERPENT=m
  19847. +CONFIG_CRYPTO_TEA=m
  19848. +CONFIG_CRYPTO_XCBC=m
  19849. +CONFIG_CRYPTO_VMAC=m
  19850. +CONFIG_CRYPTO_CRC32C_INTEL=m
  19851. +CONFIG_CRYPTO_GHASH=m
  19852. +CONFIG_CRYPTO_DEV_HIFN_795X=m
  19853. +CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y
  19854. +CONFIG_CRYPTO_PCRYPT=m
  19855. +
  19856. +
  19857. +
  19858. +# Random number generation
  19859. +
  19860. +#
  19861. +# Library routines
  19862. +#
  19863. +CONFIG_CRC16=y
  19864. +CONFIG_CRC32=m
  19865. +# CONFIG_CRC32_SELFTEST is not set
  19866. +CONFIG_CRC_ITU_T=m
  19867. +CONFIG_CRC8=m
  19868. +# CONFIG_RANDOM32_SELFTEST is not set
  19869. +CONFIG_CORDIC=m
  19870. +# CONFIG_DDR is not set
  19871. +
  19872. +CONFIG_CRYPTO_ZLIB=m
  19873. +CONFIG_ZLIB_INFLATE=y
  19874. +CONFIG_ZLIB_DEFLATE=m
  19875. +
  19876. +CONFIG_INITRAMFS_SOURCE=""
  19877. +CONFIG_KEYS=y
  19878. +CONFIG_PERSISTENT_KEYRINGS=y
  19879. +CONFIG_BIG_KEYS=y
  19880. +CONFIG_TRUSTED_KEYS=m
  19881. +CONFIG_ENCRYPTED_KEYS=m
  19882. +CONFIG_KEYS_DEBUG_PROC_KEYS=y
  19883. +CONFIG_CDROM_PKTCDVD=m
  19884. +CONFIG_CDROM_PKTCDVD_BUFFERS=8
  19885. +# CONFIG_CDROM_PKTCDVD_WCACHE is not set
  19886. +
  19887. +CONFIG_ATA_OVER_ETH=m
  19888. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  19889. +CONFIG_BACKLIGHT_CLASS_DEVICE=m
  19890. +# CONFIG_BACKLIGHT_GENERIC is not set
  19891. +CONFIG_BACKLIGHT_PROGEAR=m
  19892. +
  19893. +CONFIG_LCD_CLASS_DEVICE=m
  19894. +CONFIG_LCD_PLATFORM=m
  19895. +
  19896. +CONFIG_FAIR_GROUP_SCHED=y
  19897. +CONFIG_CFS_BANDWIDTH=y
  19898. +CONFIG_SCHED_OMIT_FRAME_POINTER=y
  19899. +CONFIG_RT_GROUP_SCHED=y
  19900. +CONFIG_SCHED_AUTOGROUP=y
  19901. +
  19902. +CONFIG_CPUSETS=y
  19903. +CONFIG_PROC_PID_CPUSET=y
  19904. +
  19905. +# CONFIG_CGROUP_DEBUG is not set
  19906. +CONFIG_CGROUP_CPUACCT=y
  19907. +CONFIG_CGROUP_DEVICE=y
  19908. +CONFIG_CGROUP_FREEZER=y
  19909. +CONFIG_CGROUP_SCHED=y
  19910. +CONFIG_MEMCG=y
  19911. +CONFIG_MEMCG_SWAP=y
  19912. +CONFIG_MEMCG_SWAP_ENABLED=y
  19913. +CONFIG_MEMCG_KMEM=y
  19914. +# CONFIG_CGROUP_HUGETLB is not set
  19915. +CONFIG_CGROUP_PERF=y
  19916. +CONFIG_CGROUP_NET_PRIO=m
  19917. +# CONFIG_CGROUP_NET_CLASSID is not set
  19918. +CONFIG_BLK_CGROUP=y
  19919. +
  19920. +# CONFIG_SYSFS_DEPRECATED is not set
  19921. +# CONFIG_SYSFS_DEPRECATED_V2 is not set
  19922. +
  19923. +CONFIG_PRINTK_TIME=y
  19924. +
  19925. +CONFIG_ENABLE_MUST_CHECK=y
  19926. +# CONFIG_ENABLE_WARN_DEPRECATED is not set
  19927. +
  19928. +CONFIG_KEXEC=y
  19929. +
  19930. +CONFIG_HWMON=y
  19931. +# CONFIG_HWMON_DEBUG_CHIP is not set
  19932. +CONFIG_THERMAL_HWMON=y
  19933. +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
  19934. +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
  19935. +CONFIG_THERMAL_GOV_FAIR_SHARE=y
  19936. +# CONFIG_THERMAL_GOV_USER_SPACE is not set
  19937. +CONFIG_THERMAL_GOV_STEP_WISE=y
  19938. +# CONFIG_THERMAL_EMULATION is not set
  19939. +
  19940. +CONFIG_INOTIFY=y
  19941. +CONFIG_INOTIFY_USER=y
  19942. +
  19943. +#
  19944. +# Bus devices
  19945. +#
  19946. +# CONFIG_OMAP_OCP2SCP is not set
  19947. +CONFIG_PROC_EVENTS=y
  19948. +
  19949. +CONFIG_IBMASR=m
  19950. +
  19951. +CONFIG_PM=y
  19952. +CONFIG_PM_STD_PARTITION=""
  19953. +# CONFIG_DPM_WATCHDOG is not set # revisit this in debug
  19954. +CONFIG_PM_TRACE=y
  19955. +CONFIG_PM_TRACE_RTC=y
  19956. +# CONFIG_PM_OPP is not set
  19957. +# CONFIG_PM_AUTOSLEEP is not set
  19958. +# CONFIG_PM_WAKELOCKS is not set
  19959. +CONFIG_HIBERNATION=y
  19960. +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
  19961. +CONFIG_SUSPEND=y
  19962. +
  19963. +CONFIG_CPU_FREQ_TABLE=y
  19964. +CONFIG_CPU_FREQ_STAT=m
  19965. +CONFIG_CPU_FREQ_STAT_DETAILS=y
  19966. +
  19967. +
  19968. +CONFIG_NET_VENDOR_SMC=y
  19969. +# CONFIG_IBMTR is not set
  19970. +# CONFIG_SKISA is not set
  19971. +# CONFIG_PROTEON is not set
  19972. +# CONFIG_SMCTR is not set
  19973. +
  19974. +# CONFIG_MOUSE_ATIXL is not set
  19975. +
  19976. +# CONFIG_MEDIA_PARPORT_SUPPORT is not set
  19977. +
  19978. +CONFIG_RADIO_TEA5764=m
  19979. +CONFIG_RADIO_SAA7706H=m
  19980. +CONFIG_RADIO_CADET=m
  19981. +CONFIG_RADIO_RTRACK=m
  19982. +CONFIG_RADIO_RTRACK2=m
  19983. +CONFIG_RADIO_AZTECH=m
  19984. +CONFIG_RADIO_GEMTEK=m
  19985. +CONFIG_RADIO_SF16FMI=m
  19986. +CONFIG_RADIO_SF16FMR2=m
  19987. +CONFIG_RADIO_TERRATEC=m
  19988. +CONFIG_RADIO_TRUST=m
  19989. +CONFIG_RADIO_TYPHOON=m
  19990. +CONFIG_RADIO_ZOLTRIX=m
  19991. +
  19992. +CONFIG_SND_DARLA20=m
  19993. +CONFIG_SND_GINA20=m
  19994. +CONFIG_SND_LAYLA20=m
  19995. +CONFIG_SND_DARLA24=m
  19996. +CONFIG_SND_GINA24=m
  19997. +CONFIG_SND_LAYLA24=m
  19998. +CONFIG_SND_MONA=m
  19999. +CONFIG_SND_MIA=m
  20000. +CONFIG_SND_ECHO3G=m
  20001. +CONFIG_SND_INDIGO=m
  20002. +CONFIG_SND_INDIGOIO=m
  20003. +CONFIG_SND_INDIGODJ=m
  20004. +CONFIG_SND_INDIGOIOX=m
  20005. +CONFIG_SND_INDIGODJX=m
  20006. +
  20007. +CONFIG_BALLOON_COMPACTION=y
  20008. +CONFIG_COMPACTION=y
  20009. +CONFIG_MIGRATION=y
  20010. +CONFIG_BOUNCE=y
  20011. +# CONFIG_LEDS_AMS_DELTA is not set
  20012. +# CONFIG_LEDS_LOCOMO is not set
  20013. +# CONFIG_LEDS_NET48XX is not set
  20014. +# CONFIG_LEDS_NET5501 is not set
  20015. +# CONFIG_LEDS_PCA9532 is not set
  20016. +# CONFIG_LEDS_PCA955X is not set
  20017. +# CONFIG_LEDS_BD2802 is not set
  20018. +# CONFIG_LEDS_S3C24XX is not set
  20019. +# CONFIG_LEDS_PCA9633 is not set
  20020. +CONFIG_LEDS_DELL_NETBOOKS=m
  20021. +# CONFIG_LEDS_TCA6507 is not set
  20022. +# CONFIG_LEDS_LM355x is not set
  20023. +# CONFIG_LEDS_OT200 is not set
  20024. +# CONFIG_LEDS_PWM is not set
  20025. +# CONFIG_LEDS_LP8501 is not set
  20026. +# CONFIG_LEDS_PCA963X is not set
  20027. +# CONFIG_LEDS_PCA9685 is not set
  20028. +CONFIG_LEDS_TRIGGER_TIMER=m
  20029. +CONFIG_LEDS_TRIGGER_ONESHOT=m
  20030. +CONFIG_LEDS_TRIGGER_IDE_DISK=y
  20031. +CONFIG_LEDS_TRIGGER_HEARTBEAT=m
  20032. +CONFIG_LEDS_TRIGGER_BACKLIGHT=m
  20033. +# CONFIG_LEDS_TRIGGER_CPU is not set
  20034. +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
  20035. +CONFIG_LEDS_TRIGGER_TRANSIENT=m
  20036. +CONFIG_LEDS_TRIGGER_CAMERA=m
  20037. +CONFIG_LEDS_ALIX2=m
  20038. +CONFIG_LEDS_CLEVO_MAIL=m
  20039. +CONFIG_LEDS_INTEL_SS4200=m
  20040. +CONFIG_LEDS_LM3530=m
  20041. +# CONFIG_LEDS_LM3642 is not set
  20042. +CONFIG_LEDS_LM3556=m
  20043. +CONFIG_LEDS_BLINKM=m
  20044. +CONFIG_LEDS_LP3944=m
  20045. +CONFIG_LEDS_LP5521=m
  20046. +CONFIG_LEDS_LP5523=m
  20047. +CONFIG_LEDS_LP5562=m
  20048. +CONFIG_LEDS_LT3593=m
  20049. +CONFIG_LEDS_REGULATOR=m
  20050. +CONFIG_LEDS_WM8350=m
  20051. +CONFIG_LEDS_WM831X_STATUS=m
  20052. +
  20053. +CONFIG_DMA_ENGINE=y
  20054. +CONFIG_DW_DMAC_CORE=m
  20055. +CONFIG_DW_DMAC=m
  20056. +CONFIG_DW_DMAC_PCI=m
  20057. +# CONFIG_DW_DMAC_BIG_ENDIAN_IO is not set
  20058. +# CONFIG_TIMB_DMA is not set
  20059. +# CONFIG_DMATEST is not set
  20060. +CONFIG_ASYNC_TX_DMA=y
  20061. +
  20062. +CONFIG_UNUSED_SYMBOLS=y
  20063. +
  20064. +CONFIG_UPROBE_EVENT=y
  20065. +
  20066. +CONFIG_DYNAMIC_FTRACE=y
  20067. +# CONFIG_IRQSOFF_TRACER is not set
  20068. +CONFIG_SCHED_TRACER=y
  20069. +CONFIG_CONTEXT_SWITCH_TRACER=y
  20070. +CONFIG_TRACER_SNAPSHOT=y
  20071. +# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set
  20072. +CONFIG_FTRACE_SYSCALLS=y
  20073. +CONFIG_FTRACE_MCOUNT_RECORD=y
  20074. +# CONFIG_FTRACE_STARTUP_TEST is not set
  20075. +# CONFIG_TRACE_BRANCH_PROFILING is not set
  20076. +CONFIG_FUNCTION_PROFILER=y
  20077. +CONFIG_RING_BUFFER_BENCHMARK=m
  20078. +# CONFIG_RING_BUFFER_STARTUP_TEST is not set
  20079. +# CONFIG_RBTREE_TEST is not set
  20080. +# CONFIG_INTERVAL_TREE_TEST is not set
  20081. +CONFIG_FUNCTION_TRACER=y
  20082. +CONFIG_STACK_TRACER=y
  20083. +# CONFIG_FUNCTION_GRAPH_TRACER is not set
  20084. +
  20085. +CONFIG_KPROBES=y
  20086. +CONFIG_KPROBE_EVENT=y
  20087. +# CONFIG_KPROBES_SANITY_TEST is not set
  20088. +# CONFIG_JUMP_LABEL is not set
  20089. +CONFIG_OPTPROBES=y
  20090. +
  20091. +CONFIG_HZ_1000=y
  20092. +
  20093. +CONFIG_TIMER_STATS=y
  20094. +CONFIG_PERF_COUNTERS=y
  20095. +
  20096. +# Auxillary displays
  20097. +CONFIG_KS0108=m
  20098. +CONFIG_KS0108_PORT=0x378
  20099. +CONFIG_KS0108_DELAY=2
  20100. +CONFIG_CFAG12864B=y
  20101. +CONFIG_CFAG12864B_RATE=20
  20102. +
  20103. +# CONFIG_PHANTOM is not set
  20104. +
  20105. +# CONFIG_POWER_SUPPLY_DEBUG is not set
  20106. +
  20107. +# CONFIG_TEST_POWER is not set
  20108. +CONFIG_APM_POWER=m
  20109. +# CONFIG_GENERIC_ADC_BATTERY is not set
  20110. +# CONFIG_WM831X_POWER is not set
  20111. +
  20112. +# CONFIG_BATTERY_DS2760 is not set
  20113. +# CONFIG_BATTERY_DS2781 is not set
  20114. +# CONFIG_BATTERY_DS2782 is not set
  20115. +# CONFIG_BATTERY_SBS is not set
  20116. +# CONFIG_BATTERY_BQ20Z75 is not set
  20117. +# CONFIG_BATTERY_DS2780 is not set
  20118. +# CONFIG_BATTERY_BQ27x00 is not set
  20119. +# CONFIG_BATTERY_MAX17040 is not set
  20120. +# CONFIG_BATTERY_MAX17042 is not set
  20121. +# CONFIG_BATTERY_GOLDFISH is not set
  20122. +
  20123. +# CONFIG_CHARGER_ISP1704 is not set
  20124. +# CONFIG_CHARGER_MAX8903 is not set
  20125. +# CONFIG_CHARGER_LP8727 is not set
  20126. +# CONFIG_CHARGER_GPIO is not set
  20127. +# CONFIG_CHARGER_PCF50633 is not set
  20128. +# CONFIG_CHARGER_BQ2415X is not set
  20129. +# CONFIG_CHARGER_BQ24190 is not set
  20130. +# CONFIG_CHARGER_BQ24735 is not set
  20131. +CONFIG_POWER_RESET=y
  20132. +
  20133. +# CONFIG_PDA_POWER is not set
  20134. +
  20135. +CONFIG_AUXDISPLAY=y
  20136. +
  20137. +CONFIG_UIO=m
  20138. +CONFIG_UIO_CIF=m
  20139. +# CONFIG_UIO_PDRV is not set
  20140. +# CONFIG_UIO_PDRV_GENIRQ is not set
  20141. +# CONFIG_UIO_DMEM_GENIRQ is not set
  20142. +CONFIG_UIO_AEC=m
  20143. +CONFIG_UIO_SERCOS3=m
  20144. +CONFIG_UIO_PCI_GENERIC=m
  20145. +# CONFIG_UIO_NETX is not set
  20146. +# CONFIG_UIO_MF624 is not set
  20147. +
  20148. +CONFIG_VFIO=m
  20149. +CONFIG_VFIO_IOMMU_TYPE1=m
  20150. +CONFIG_VFIO_PCI=m
  20151. +
  20152. +
  20153. +# LIRC
  20154. +CONFIG_LIRC_STAGING=y
  20155. +CONFIG_LIRC_BT829=m
  20156. +CONFIG_LIRC_IGORPLUGUSB=m
  20157. +CONFIG_LIRC_IMON=m
  20158. +CONFIG_LIRC_ZILOG=m
  20159. +CONFIG_LIRC_PARALLEL=m
  20160. +CONFIG_LIRC_SERIAL=m
  20161. +CONFIG_LIRC_SERIAL_TRANSMITTER=y
  20162. +CONFIG_LIRC_SASEM=m
  20163. +CONFIG_LIRC_SIR=m
  20164. +CONFIG_LIRC_TTUSBIR=m
  20165. +
  20166. +# CONFIG_SAMPLES is not set
  20167. +
  20168. +
  20169. +CONFIG_NOZOMI=m
  20170. +# CONFIG_TPS65010 is not set
  20171. +
  20172. +CONFIG_INPUT_APANEL=m
  20173. +CONFIG_INPUT_GP2A=m
  20174. +# CONFIG_INPUT_GPIO_TILT_POLLED is not set
  20175. +# CONFIG_INPUT_GPIO_BEEPER is not set
  20176. +
  20177. +# CONFIG_INTEL_MENLOW is not set
  20178. +CONFIG_ENCLOSURE_SERVICES=m
  20179. +CONFIG_IPWIRELESS=m
  20180. +
  20181. +# CONFIG_BLK_DEV_XIP is not set
  20182. +CONFIG_MEMSTICK=m
  20183. +# CONFIG_MEMSTICK_DEBUG is not set
  20184. +# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
  20185. +CONFIG_MSPRO_BLOCK=m
  20186. +# CONFIG_MS_BLOCK is not set
  20187. +CONFIG_MEMSTICK_TIFM_MS=m
  20188. +CONFIG_MEMSTICK_JMICRON_38X=m
  20189. +CONFIG_MEMSTICK_R592=m
  20190. +CONFIG_MEMSTICK_REALTEK_PCI=m
  20191. +
  20192. +CONFIG_ACCESSIBILITY=y
  20193. +CONFIG_A11Y_BRAILLE_CONSOLE=y
  20194. +
  20195. +# CONFIG_HTC_PASIC3 is not set
  20196. +
  20197. +# MT9V022_PCA9536_SWITCH is not set
  20198. +
  20199. +CONFIG_OPTIMIZE_INLINING=y
  20200. +
  20201. +# FIXME: This should be x86/ia64 only
  20202. +# CONFIG_HP_ILO is not set
  20203. +
  20204. +CONFIG_GPIOLIB=y
  20205. +# CONFIG_PINCTRL is not set
  20206. +# CONFIG_DEBUG_PINCTRL is not set
  20207. +# CONFIG_PINMUX is not set
  20208. +# CONFIG_PINCONF is not set
  20209. +
  20210. +CONFIG_NET_DSA=m
  20211. +CONFIG_NET_DSA_MV88E6060=m
  20212. +CONFIG_NET_DSA_MV88E6131=m
  20213. +CONFIG_NET_DSA_MV88E6123_61_65=m
  20214. +
  20215. +# Used by Maemo, we don't care.
  20216. +# CONFIG_PHONET is not set
  20217. +
  20218. +# CONFIG_ICS932S401 is not set
  20219. +# CONFIG_ATMEL_SSC is not set
  20220. +
  20221. +# CONFIG_C2PORT is not set
  20222. +
  20223. +# CONFIG_REGULATOR_DEBUG is not set
  20224. +
  20225. +CONFIG_WM8350_POWER=m
  20226. +
  20227. +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
  20228. +
  20229. +CONFIG_USB_WUSB=m
  20230. +CONFIG_USB_WUSB_CBAF=m
  20231. +# CONFIG_USB_WUSB_CBAF_DEBUG is not set
  20232. +CONFIG_USB_WHCI_HCD=m
  20233. +CONFIG_USB_HWA_HCD=m
  20234. +# CONFIG_USB_HCD_BCMA is not set
  20235. +# CONFIG_USB_HCD_SSB is not set
  20236. +
  20237. +CONFIG_UWB=m
  20238. +CONFIG_UWB_HWA=m
  20239. +CONFIG_UWB_WHCI=m
  20240. +CONFIG_UWB_I1480U=m
  20241. +
  20242. +# CONFIG_ANDROID is not set
  20243. +CONFIG_STAGING_MEDIA=y
  20244. +# CONFIG_DVB_AS102 is not set
  20245. +# CONFIG_ET131X is not set
  20246. +# CONFIG_SLICOSS is not set
  20247. +# CONFIG_WLAGS49_H2 is not set
  20248. +# CONFIG_WLAGS49_H25 is not set
  20249. +# CONFIG_VIDEO_DT3155 is not set
  20250. +# CONFIG_TI_ST is not set
  20251. +# CONFIG_FB_XGI is not set
  20252. +# CONFIG_VIDEO_GO7007 is not set
  20253. +# CONFIG_I2C_BCM2048 is not set
  20254. +# CONFIG_VIDEO_TCM825X is not set
  20255. +# CONFIG_VIDEO_OMAP4 is not set
  20256. +# CONFIG_USB_MSI3101 is not set
  20257. +# CONFIG_DT3155 is not set
  20258. +# CONFIG_W35UND is not set
  20259. +# CONFIG_PRISM2_USB is not set
  20260. +# CONFIG_ECHO is not set
  20261. +CONFIG_USB_ATMEL=m
  20262. +# CONFIG_COMEDI is not set
  20263. +# CONFIG_ASUS_OLED is not set
  20264. +# CONFIG_PANEL is not set
  20265. +# CONFIG_TRANZPORT is not set
  20266. +# CONFIG_POHMELFS is not set
  20267. +# CONFIG_IDE_PHISON is not set
  20268. +# CONFIG_LINE6_USB is not set
  20269. +# CONFIG_VME_BUS is not set
  20270. +# CONFIG_RAR_REGISTER is not set
  20271. +# CONFIG_VT6656 is not set
  20272. +# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
  20273. +# Larry Finger maintains these (rhbz 913753)
  20274. +CONFIG_RTLLIB=m
  20275. +CONFIG_RTLLIB_CRYPTO_CCMP=m
  20276. +CONFIG_RTLLIB_CRYPTO_TKIP=m
  20277. +CONFIG_RTLLIB_CRYPTO_WEP=m
  20278. +CONFIG_RTL8192E=m
  20279. +# CONFIG_INPUT_GPIO is not set
  20280. +# CONFIG_VIDEO_CX25821 is not set
  20281. +# CONFIG_R8187SE is not set
  20282. +# CONFIG_R8188EU is not set
  20283. +# CONFIG_R8821AE is not set
  20284. +# CONFIG_RTL8192U is not set
  20285. +# CONFIG_FB_SM7XX is not set
  20286. +# CONFIG_SPECTRA is not set
  20287. +# CONFIG_EASYCAP is not set
  20288. +# CONFIG_SOLO6X10 is not set
  20289. +# CONFIG_ACPI_QUICKSTART is not set
  20290. +# CONFIG_LTE_GDM724X is not set
  20291. +CONFIG_R8712U=m # Larry Finger maintains this (rhbz 699618)
  20292. +# CONFIG_R8712_AP is not set
  20293. +# CONFIG_ATH6K_LEGACY is not set
  20294. +# CONFIG_USB_ENESTORAGE is not set
  20295. +# CONFIG_BCM_WIMAX is not set
  20296. +# CONFIG_USB_BTMTK is not set
  20297. +# CONFIG_FT1000 is not set
  20298. +# CONFIG_SPEAKUP is not set
  20299. +# CONFIG_DX_SEP is not set
  20300. +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
  20301. +# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
  20302. +# CONFIG_RTS_PSTOR is not set
  20303. +CONFIG_ALTERA_STAPL=m
  20304. +# CONFIG_DVB_CXD2099 is not set
  20305. +# CONFIG_USBIP_CORE is not set
  20306. +# CONFIG_INTEL_MEI is not set
  20307. +# CONFIG_ZCACHE is not set
  20308. +# CONFIG_RTS5139 is not set
  20309. +# CONFIG_NVEC_LEDS is not set
  20310. +# CONFIG_VT6655 is not set
  20311. +# CONFIG_RAMSTER is not set
  20312. +# CONFIG_USB_WPAN_HCD is not set
  20313. +# CONFIG_WIMAX_GDM72XX is not set
  20314. +# CONFIG_IPACK_BUS is not set
  20315. +# CONFIG_CSR_WIFI is not set
  20316. +# CONFIG_ZCACHE2 is not set
  20317. +# CONFIG_NET_VENDOR_SILICOM is not set
  20318. +# CONFIG_SBYPASS is not set
  20319. +# CONFIG_BPCTL is not set
  20320. +# CONFIG_CED1401 is not set
  20321. +# CONFIG_DGRP is not set
  20322. +# CONFIG_SB105X is not set
  20323. +# CONFIG_LUSTRE_FS is not set
  20324. +# CONFIG_XILLYBUS is not set
  20325. +# CONFIG_DGAP is not set
  20326. +# CONFIG_DGNC is not set
  20327. +# CONFIG_RTS5208 is not set
  20328. +# END OF STAGING
  20329. +
  20330. +#
  20331. +# Remoteproc drivers (EXPERIMENTAL)
  20332. +#
  20333. +# CONFIG_STE_MODEM_RPROC is not set
  20334. +
  20335. +CONFIG_LIBFC=m
  20336. +CONFIG_LIBFCOE=m
  20337. +CONFIG_FCOE=m
  20338. +CONFIG_FCOE_FNIC=m
  20339. +
  20340. +
  20341. +# CONFIG_IMA is not set
  20342. +CONFIG_IMA_MEASURE_PCR_IDX=10
  20343. +CONFIG_IMA_AUDIT=y
  20344. +CONFIG_IMA_LSM_RULES=y
  20345. +
  20346. +# CONFIG_EVM is not set
  20347. +# CONFIG_PWM_PCA9685 is not set
  20348. +
  20349. +CONFIG_LSM_MMAP_MIN_ADDR=65536
  20350. +
  20351. +CONFIG_STRIP_ASM_SYMS=y
  20352. +
  20353. +# CONFIG_RCU_FANOUT_EXACT is not set
  20354. +# FIXME: Revisit FAST_NO_HZ after it's fixed
  20355. +# CONFIG_RCU_FAST_NO_HZ is not set
  20356. +# CONFIG_RCU_NOCB_CPU is not set
  20357. +CONFIG_RCU_CPU_STALL_TIMEOUT=60
  20358. +# CONFIG_RCU_TORTURE_TEST is not set
  20359. +# CONFIG_RCU_TRACE is not set
  20360. +# CONFIG_RCU_CPU_STALL_INFO is not set
  20361. +# CONFIG_RCU_USER_QS is not set
  20362. +
  20363. +CONFIG_KSM=y
  20364. +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
  20365. +
  20366. +CONFIG_FSNOTIFY=y
  20367. +CONFIG_FANOTIFY=y
  20368. +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
  20369. +
  20370. +CONFIG_IEEE802154=m
  20371. +CONFIG_IEEE802154_6LOWPAN=m
  20372. +CONFIG_IEEE802154_DRIVERS=m
  20373. +CONFIG_IEEE802154_FAKEHARD=m
  20374. +CONFIG_IEEE802154_FAKELB=m
  20375. +
  20376. +CONFIG_MAC802154=m
  20377. +CONFIG_NET_MPLS_GSO=m
  20378. +
  20379. +# CONFIG_HSR is not set
  20380. +
  20381. +# CONFIG_EXTCON is not set
  20382. +# CONFIG_EXTCON_ADC_JACK is not set
  20383. +# CONFIG_MEMORY is not set
  20384. +
  20385. +CONFIG_PPS=m
  20386. +# CONFIG_PPS_CLIENT_KTIMER is not set
  20387. +CONFIG_PPS_CLIENT_LDISC=m
  20388. +# CONFIG_PPS_DEBUG is not set
  20389. +CONFIG_PPS_CLIENT_PARPORT=m
  20390. +CONFIG_PPS_GENERATOR_PARPORT=m
  20391. +CONFIG_PPS_CLIENT_GPIO=m
  20392. +CONFIG_NTP_PPS=y
  20393. +
  20394. +CONFIG_PTP_1588_CLOCK=m
  20395. +CONFIG_PTP_1588_CLOCK_PCH=m
  20396. +
  20397. +CONFIG_CLEANCACHE=y
  20398. +CONFIG_FRONTSWAP=y
  20399. +CONFIG_ZSWAP=y
  20400. +CONFIG_ZSMALLOC=y
  20401. +# CONFIG_PGTABLE_MAPPING is not set
  20402. +
  20403. +# CONFIG_MDIO_GPIO is not set
  20404. +# CONFIG_KEYBOARD_GPIO_POLLED is not set
  20405. +# CONFIG_MOUSE_GPIO is not set
  20406. +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
  20407. +# CONFIG_I2C_DESIGNWARE_PCI is not set
  20408. +# CONFIG_I2C_GPIO is not set
  20409. +# CONFIG_DEBUG_GPIO is not set
  20410. +# CONFIG_GPIO_GENERIC_PLATFORM is not set
  20411. +# CONFIG_GPIO_CS5535 is not set
  20412. +# CONFIG_GPIO_IT8761E is not set
  20413. +# CONFIG SB105x is not set
  20414. +# CONFIG_GPIO_TS5500 is not set
  20415. +CONFIG_GPIO_VIPERBOARD=m
  20416. +# CONFIG_UCB1400_CORE is not set
  20417. +# CONFIG_TPS6105X is not set
  20418. +# CONFIG_RADIO_MIROPCM20 is not set
  20419. +# CONFIG_USB_GPIO_VBUS is not set
  20420. +# CONFIG_GPIO_SCH is not set
  20421. +# CONFIG_GPIO_LANGWELL is not set
  20422. +# CONFIG_GPIO_RDC321X is not set
  20423. +# CONFIG_GPIO_VX855 is not set
  20424. +# CONFIG_GPIO_PCH is not set
  20425. +# CONFIG_GPIO_ML_IOH is not set
  20426. +# CONFIG_GPIO_AMD8111 is not set
  20427. +# CONFIG_GPIO_BT8XX is not set
  20428. +# CONFIG_GPIO_GRGPIO is not set
  20429. +# CONFIG_GPIO_PL061 is not set
  20430. +# CONFIG_GPIO_BCM_KONA is not set
  20431. +# CONFIG_GPIO_SCH311X is not set
  20432. +CONFIG_GPIO_MAX730X=m
  20433. +CONFIG_GPIO_MAX7300=m
  20434. +CONFIG_GPIO_MAX732X=m
  20435. +CONFIG_GPIO_PCF857X=m
  20436. +CONFIG_GPIO_SX150X=y
  20437. +CONFIG_GPIO_ADP5588=m
  20438. +CONFIG_GPIO_ADNP=m
  20439. +CONFIG_GPIO_MAX7301=m
  20440. +CONFIG_GPIO_MCP23S08=m
  20441. +CONFIG_GPIO_MC33880=m
  20442. +CONFIG_GPIO_74X164=m
  20443. +
  20444. +# FIXME: Why?
  20445. +CONFIG_EVENT_POWER_TRACING_DEPRECATED=y
  20446. +
  20447. +CONFIG_TEST_KSTRTOX=y
  20448. +CONFIG_XZ_DEC=y
  20449. +CONFIG_XZ_DEC_X86=y
  20450. +CONFIG_XZ_DEC_POWERPC=y
  20451. +# CONFIG_XZ_DEC_IA64 is not set
  20452. +CONFIG_XZ_DEC_ARM=y
  20453. +# CONFIG_XZ_DEC_ARMTHUMB is not set
  20454. +# CONFIG_XZ_DEC_SPARC is not set
  20455. +# CONFIG_XZ_DEC_TEST is not set
  20456. +
  20457. +# CONFIG_POWER_AVS is not set
  20458. +
  20459. +CONFIG_TARGET_CORE=m
  20460. +CONFIG_ISCSI_TARGET=m
  20461. +CONFIG_LOOPBACK_TARGET=m
  20462. +CONFIG_SBP_TARGET=m
  20463. +CONFIG_TCM_IBLOCK=m
  20464. +CONFIG_TCM_FILEIO=m
  20465. +CONFIG_TCM_PSCSI=m
  20466. +CONFIG_TCM_FC=m
  20467. +
  20468. +CONFIG_HWSPINLOCK=m
  20469. +
  20470. +CONFIG_PSTORE=y
  20471. +CONFIG_PSTORE_RAM=m
  20472. +# CONFIG_PSTORE_CONSOLE is not set
  20473. +# CONFIG_PSTORE_FTRACE is not set
  20474. +
  20475. +# CONFIG_TEST_MODULE is not set
  20476. +# CONFIG_TEST_USER_COPY is not set
  20477. +
  20478. +# CONFIG_AVERAGE is not set
  20479. +# CONFIG_VMXNET3 is not set
  20480. +
  20481. +# CONFIG_SIGMA is not set
  20482. +
  20483. +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
  20484. +
  20485. +CONFIG_BCMA=m
  20486. +CONFIG_BCMA_BLOCKIO=y
  20487. +CONFIG_BCMA_HOST_PCI_POSSIBLE=y
  20488. +CONFIG_BCMA_HOST_PCI=y
  20489. +# CONFIG_BCMA_HOST_SOC is not set
  20490. +CONFIG_BCMA_DRIVER_GMAC_CMN=y
  20491. +CONFIG_BCMA_DRIVER_GPIO=y
  20492. +# CONFIG_BCMA_DEBUG is not set
  20493. +
  20494. +# CONFIG_GOOGLE_FIRMWARE is not set
  20495. +# CONFIG_INTEL_MID_PTI is not set
  20496. +
  20497. +# CONFIG_MAILBOX is not set
  20498. +
  20499. +CONFIG_FMC=m
  20500. +CONFIG_FMC_FAKEDEV=m
  20501. +CONFIG_FMC_TRIVIAL=m
  20502. +CONFIG_FMC_WRITE_EEPROM=m
  20503. +CONFIG_FMC_CHARDEV=m
  20504. +
  20505. +# CONFIG_GENWQE is not set
  20506. +
  20507. +# CONFIG_POWERCAP is not set
  20508. +
  20509. +# CONFIG_HSI is not set
  20510. +
  20511. +
  20512. +# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set
  20513. +
  20514. +# CONFIG_PM_DEVFREQ is not set
  20515. +# CONFIG_MODULE_SIG is not set
  20516. +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set
  20517. +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
  20518. +# CONFIG_MODULE_VERIFY_ELF is not set
  20519. +# CONFIG_CRYPTO_KEY_TYPE is not set
  20520. +# CONFIG_PGP_LIBRARY is not set
  20521. +# CONFIG_PGP_PRELOAD is not set
  20522. +# CONFIG_LOCALVERSION_AUTO is not set
  20523. +CONFIG_PROC_DEVICETREE=y
  20524. +
  20525. diff -Nur linux-3.14.14/arch/arm/configs/imx_v7_defconfig linux-imx6-3.14/arch/arm/configs/imx_v7_defconfig
  20526. --- linux-3.14.14/arch/arm/configs/imx_v7_defconfig 1969-12-31 18:00:00.000000000 -0600
  20527. +++ linux-imx6-3.14/arch/arm/configs/imx_v7_defconfig 2014-12-08 00:31:51.156418001 -0600
  20528. @@ -0,0 +1,343 @@
  20529. +# CONFIG_LOCALVERSION_AUTO is not set
  20530. +CONFIG_KERNEL_LZO=y
  20531. +CONFIG_SYSVIPC=y
  20532. +CONFIG_NO_HZ=y
  20533. +CONFIG_HIGH_RES_TIMERS=y
  20534. +CONFIG_LOG_BUF_SHIFT=18
  20535. +CONFIG_CGROUPS=y
  20536. +CONFIG_RELAY=y
  20537. +CONFIG_BLK_DEV_INITRD=y
  20538. +CONFIG_EXPERT=y
  20539. +CONFIG_PERF_EVENTS=y
  20540. +# CONFIG_SLUB_DEBUG is not set
  20541. +# CONFIG_COMPAT_BRK is not set
  20542. +CONFIG_MODULES=y
  20543. +CONFIG_MODULE_UNLOAD=y
  20544. +CONFIG_MODVERSIONS=y
  20545. +CONFIG_MODULE_SRCVERSION_ALL=y
  20546. +# CONFIG_BLK_DEV_BSG is not set
  20547. +CONFIG_GPIO_PCA953X=y
  20548. +CONFIG_ARCH_MXC=y
  20549. +CONFIG_MXC_DEBUG_BOARD=y
  20550. +CONFIG_MACH_IMX51_DT=y
  20551. +CONFIG_MACH_EUKREA_CPUIMX51SD=y
  20552. +CONFIG_SOC_IMX53=y
  20553. +CONFIG_SOC_IMX6Q=y
  20554. +CONFIG_SOC_IMX6SL=y
  20555. +CONFIG_SOC_VF610=y
  20556. +# CONFIG_SWP_EMULATE is not set
  20557. +CONFIG_SMP=y
  20558. +CONFIG_VMSPLIT_2G=y
  20559. +CONFIG_PREEMPT=y
  20560. +CONFIG_AEABI=y
  20561. +# CONFIG_OABI_COMPAT is not set
  20562. +CONFIG_HIGHMEM=y
  20563. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  20564. +CONFIG_CPU_FREQ=y
  20565. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  20566. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  20567. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  20568. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  20569. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  20570. +CONFIG_ARM_IMX6_CPUFREQ=y
  20571. +CONFIG_CPU_IDLE=y
  20572. +CONFIG_VFP=y
  20573. +CONFIG_NEON=y
  20574. +CONFIG_BINFMT_MISC=m
  20575. +CONFIG_PM_RUNTIME=y
  20576. +CONFIG_PM_DEBUG=y
  20577. +CONFIG_PM_TEST_SUSPEND=y
  20578. +CONFIG_NET=y
  20579. +CONFIG_PACKET=y
  20580. +CONFIG_UNIX=y
  20581. +CONFIG_INET=y
  20582. +CONFIG_IP_PNP=y
  20583. +CONFIG_IP_PNP_DHCP=y
  20584. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  20585. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  20586. +# CONFIG_INET_XFRM_MODE_BEET is not set
  20587. +# CONFIG_INET_LRO is not set
  20588. +CONFIG_IPV6=y
  20589. +CONFIG_NETFILTER=y
  20590. +CONFIG_VLAN_8021Q=y
  20591. +# CONFIG_WIRELESS is not set
  20592. +CONFIG_DEVTMPFS=y
  20593. +CONFIG_DEVTMPFS_MOUNT=y
  20594. +# CONFIG_STANDALONE is not set
  20595. +CONFIG_CMA=y
  20596. +CONFIG_CMA_SIZE_MBYTES=320
  20597. +CONFIG_IMX_WEIM=y
  20598. +CONFIG_CONNECTOR=y
  20599. +CONFIG_MTD=y
  20600. +CONFIG_MTD_CMDLINE_PARTS=y
  20601. +CONFIG_MTD_BLOCK=y
  20602. +CONFIG_MTD_CFI=y
  20603. +CONFIG_MTD_JEDECPROBE=y
  20604. +CONFIG_MTD_CFI_INTELEXT=y
  20605. +CONFIG_MTD_CFI_AMDSTD=y
  20606. +CONFIG_MTD_CFI_STAA=y
  20607. +CONFIG_MTD_PHYSMAP_OF=y
  20608. +CONFIG_MTD_DATAFLASH=y
  20609. +CONFIG_MTD_M25P80=y
  20610. +CONFIG_MTD_SST25L=y
  20611. +CONFIG_MTD_NAND=y
  20612. +CONFIG_MTD_NAND_GPMI_NAND=y
  20613. +CONFIG_MTD_NAND_MXC=y
  20614. +CONFIG_MTD_UBI=y
  20615. +CONFIG_BLK_DEV_LOOP=y
  20616. +CONFIG_BLK_DEV_RAM=y
  20617. +CONFIG_BLK_DEV_RAM_SIZE=65536
  20618. +CONFIG_EEPROM_AT24=y
  20619. +CONFIG_EEPROM_AT25=y
  20620. +# CONFIG_SCSI_PROC_FS is not set
  20621. +CONFIG_BLK_DEV_SD=y
  20622. +CONFIG_SCSI_MULTI_LUN=y
  20623. +CONFIG_SCSI_CONSTANTS=y
  20624. +CONFIG_SCSI_LOGGING=y
  20625. +CONFIG_SCSI_SCAN_ASYNC=y
  20626. +# CONFIG_SCSI_LOWLEVEL is not set
  20627. +CONFIG_ATA=y
  20628. +CONFIG_SATA_AHCI_PLATFORM=y
  20629. +CONFIG_AHCI_IMX=y
  20630. +CONFIG_PATA_IMX=y
  20631. +CONFIG_NETDEVICES=y
  20632. +# CONFIG_NET_VENDOR_BROADCOM is not set
  20633. +CONFIG_CS89x0=y
  20634. +CONFIG_CS89x0_PLATFORM=y
  20635. +# CONFIG_NET_VENDOR_FARADAY is not set
  20636. +# CONFIG_NET_VENDOR_INTEL is not set
  20637. +# CONFIG_NET_VENDOR_MARVELL is not set
  20638. +# CONFIG_NET_VENDOR_MICREL is not set
  20639. +# CONFIG_NET_VENDOR_MICROCHIP is not set
  20640. +# CONFIG_NET_VENDOR_NATSEMI is not set
  20641. +# CONFIG_NET_VENDOR_SEEQ is not set
  20642. +CONFIG_SMC91X=y
  20643. +CONFIG_SMC911X=y
  20644. +CONFIG_SMSC911X=y
  20645. +# CONFIG_NET_VENDOR_STMICRO is not set
  20646. +# CONFIG_WLAN is not set
  20647. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  20648. +CONFIG_INPUT_EVDEV=y
  20649. +CONFIG_INPUT_EVBUG=m
  20650. +CONFIG_KEYBOARD_GPIO=y
  20651. +CONFIG_KEYBOARD_IMX=y
  20652. +CONFIG_MOUSE_PS2=m
  20653. +CONFIG_MOUSE_PS2_ELANTECH=y
  20654. +CONFIG_INPUT_TOUCHSCREEN=y
  20655. +CONFIG_TOUCHSCREEN_EGALAX=y
  20656. +CONFIG_TOUCHSCREEN_EGALAX_SINGLE_TOUCH=y
  20657. +CONFIG_TOUCHSCREEN_MAX11801=y
  20658. +CONFIG_TOUCHSCREEN_MC13783=y
  20659. +CONFIG_INPUT_MISC=y
  20660. +CONFIG_INPUT_MMA8450=y
  20661. +CONFIG_INPUT_ISL29023=y
  20662. +CONFIG_SERIO_SERPORT=m
  20663. +CONFIG_VT_HW_CONSOLE_BINDING=y
  20664. +# CONFIG_LEGACY_PTYS is not set
  20665. +# CONFIG_DEVKMEM is not set
  20666. +CONFIG_SERIAL_IMX=y
  20667. +CONFIG_SERIAL_IMX_CONSOLE=y
  20668. +CONFIG_SERIAL_FSL_LPUART=y
  20669. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  20670. +CONFIG_FSL_OTP=y
  20671. +# CONFIG_I2C_COMPAT is not set
  20672. +CONFIG_I2C_CHARDEV=y
  20673. +# CONFIG_I2C_HELPER_AUTO is not set
  20674. +CONFIG_I2C_ALGOPCF=m
  20675. +CONFIG_I2C_ALGOPCA=m
  20676. +CONFIG_I2C_IMX=y
  20677. +CONFIG_SPI=y
  20678. +CONFIG_SPI_IMX=y
  20679. +CONFIG_GPIO_SYSFS=y
  20680. +CONFIG_POWER_SUPPLY=y
  20681. +CONFIG_SABRESD_MAX8903=y
  20682. +CONFIG_IMX6_USB_CHARGER=y
  20683. +CONFIG_SENSORS_MAG3110=y
  20684. +CONFIG_THERMAL=y
  20685. +CONFIG_CPU_THERMAL=y
  20686. +CONFIG_IMX_THERMAL=y
  20687. +CONFIG_DEVICE_THERMAL=y
  20688. +CONFIG_WATCHDOG=y
  20689. +CONFIG_IMX2_WDT=y
  20690. +CONFIG_MFD_DA9052_I2C=y
  20691. +CONFIG_MFD_MC13XXX_SPI=y
  20692. +CONFIG_MFD_MC13XXX_I2C=y
  20693. +CONFIG_MFD_SI476X_CORE=y
  20694. +CONFIG_REGULATOR=y
  20695. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  20696. +CONFIG_REGULATOR_DA9052=y
  20697. +CONFIG_REGULATOR_ANATOP=y
  20698. +CONFIG_REGULATOR_MC13783=y
  20699. +CONFIG_REGULATOR_MC13892=y
  20700. +CONFIG_REGULATOR_PFUZE100=y
  20701. +CONFIG_MEDIA_SUPPORT=y
  20702. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  20703. +CONFIG_MEDIA_RADIO_SUPPORT=y
  20704. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  20705. +CONFIG_MEDIA_USB_SUPPORT=y
  20706. +CONFIG_USB_VIDEO_CLASS=m
  20707. +CONFIG_V4L_PLATFORM_DRIVERS=y
  20708. +CONFIG_VIDEO_MXC_OUTPUT=y
  20709. +CONFIG_VIDEO_MXC_CAPTURE=m
  20710. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  20711. +CONFIG_MXC_CAMERA_OV5640=m
  20712. +CONFIG_MXC_CAMERA_OV5642=m
  20713. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  20714. +CONFIG_MXC_TVIN_ADV7180=m
  20715. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  20716. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  20717. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  20718. +CONFIG_SOC_CAMERA=y
  20719. +CONFIG_VIDEO_MX3=y
  20720. +CONFIG_RADIO_SI476X=y
  20721. +CONFIG_SOC_CAMERA_OV2640=y
  20722. +CONFIG_DRM=y
  20723. +CONFIG_DRM_VIVANTE=y
  20724. +CONFIG_FB=y
  20725. +CONFIG_FB_MXS=y
  20726. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  20727. +CONFIG_LCD_CLASS_DEVICE=y
  20728. +CONFIG_LCD_L4F00242T03=y
  20729. +CONFIG_LCD_PLATFORM=y
  20730. +CONFIG_BACKLIGHT_CLASS_DEVICE=y
  20731. +CONFIG_BACKLIGHT_PWM=y
  20732. +CONFIG_FB_MXC_SYNC_PANEL=y
  20733. +CONFIG_FB_MXC_LDB=y
  20734. +CONFIG_FB_MXC_MIPI_DSI=y
  20735. +CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
  20736. +CONFIG_FB_MXC_HDMI=y
  20737. +CONFIG_FRAMEBUFFER_CONSOLE=y
  20738. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  20739. +CONFIG_FONTS=y
  20740. +CONFIG_FONT_8x8=y
  20741. +CONFIG_FONT_8x16=y
  20742. +CONFIG_LOGO=y
  20743. +CONFIG_SOUND=y
  20744. +CONFIG_SND=y
  20745. +CONFIG_SND_USB_AUDIO=m
  20746. +CONFIG_SND_SOC=y
  20747. +CONFIG_SND_IMX_SOC=y
  20748. +CONFIG_SND_SOC_EUKREA_TLV320=y
  20749. +CONFIG_SND_SOC_IMX_CS42888=y
  20750. +CONFIG_SND_SOC_IMX_WM8962=y
  20751. +CONFIG_SND_SOC_IMX_SGTL5000=y
  20752. +CONFIG_SND_SOC_IMX_SPDIF=y
  20753. +CONFIG_SND_SOC_IMX_MC13783=y
  20754. +CONFIG_SND_SOC_IMX_HDMI=y
  20755. +CONFIG_SND_SOC_IMX_SI476X=y
  20756. +CONFIG_USB=y
  20757. +CONFIG_USB_EHCI_HCD=y
  20758. +CONFIG_USB_STORAGE=y
  20759. +CONFIG_USB_CHIPIDEA=y
  20760. +CONFIG_USB_CHIPIDEA_UDC=y
  20761. +CONFIG_USB_CHIPIDEA_HOST=y
  20762. +CONFIG_USB_PHY=y
  20763. +CONFIG_NOP_USB_XCEIV=y
  20764. +CONFIG_USB_MXS_PHY=y
  20765. +CONFIG_USB_GADGET=y
  20766. +CONFIG_USB_ZERO=m
  20767. +CONFIG_USB_ETH=m
  20768. +CONFIG_USB_MASS_STORAGE=m
  20769. +CONFIG_USB_G_SERIAL=m
  20770. +CONFIG_MMC=y
  20771. +CONFIG_MMC_UNSAFE_RESUME=y
  20772. +CONFIG_MMC_SDHCI=y
  20773. +CONFIG_MMC_SDHCI_PLTFM=y
  20774. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  20775. +CONFIG_MXC_IPU=y
  20776. +CONFIG_MXC_GPU_VIV=y
  20777. +CONFIG_MXC_ASRC=y
  20778. +CONFIG_MXC_MIPI_CSI2=y
  20779. +CONFIG_MXC_MLB150=m
  20780. +CONFIG_NEW_LEDS=y
  20781. +CONFIG_LEDS_CLASS=y
  20782. +CONFIG_LEDS_GPIO=y
  20783. +CONFIG_LEDS_TRIGGERS=y
  20784. +CONFIG_LEDS_TRIGGER_GPIO=y
  20785. +CONFIG_RTC_CLASS=y
  20786. +CONFIG_RTC_INTF_DEV_UIE_EMUL=y
  20787. +CONFIG_RTC_DRV_MC13XXX=y
  20788. +CONFIG_RTC_DRV_MXC=y
  20789. +CONFIG_RTC_DRV_SNVS=y
  20790. +CONFIG_DMADEVICES=y
  20791. +CONFIG_MXC_PXP_V2=y
  20792. +CONFIG_IMX_SDMA=y
  20793. +CONFIG_MXS_DMA=y
  20794. +CONFIG_STAGING=y
  20795. +CONFIG_COMMON_CLK_DEBUG=y
  20796. +# CONFIG_IOMMU_SUPPORT is not set
  20797. +CONFIG_PWM=y
  20798. +CONFIG_PWM_IMX=y
  20799. +CONFIG_EXT2_FS=y
  20800. +CONFIG_EXT2_FS_XATTR=y
  20801. +CONFIG_EXT2_FS_POSIX_ACL=y
  20802. +CONFIG_EXT2_FS_SECURITY=y
  20803. +CONFIG_EXT3_FS=y
  20804. +CONFIG_EXT3_FS_POSIX_ACL=y
  20805. +CONFIG_EXT3_FS_SECURITY=y
  20806. +CONFIG_EXT4_FS=y
  20807. +CONFIG_EXT4_FS_POSIX_ACL=y
  20808. +CONFIG_EXT4_FS_SECURITY=y
  20809. +CONFIG_QUOTA=y
  20810. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  20811. +# CONFIG_PRINT_QUOTA_WARNING is not set
  20812. +CONFIG_AUTOFS4_FS=y
  20813. +CONFIG_FUSE_FS=y
  20814. +CONFIG_ISO9660_FS=m
  20815. +CONFIG_JOLIET=y
  20816. +CONFIG_ZISOFS=y
  20817. +CONFIG_UDF_FS=m
  20818. +CONFIG_MSDOS_FS=m
  20819. +CONFIG_VFAT_FS=y
  20820. +CONFIG_TMPFS=y
  20821. +CONFIG_JFFS2_FS=y
  20822. +CONFIG_UBIFS_FS=y
  20823. +CONFIG_NFS_FS=y
  20824. +CONFIG_NFS_V3_ACL=y
  20825. +CONFIG_NFS_V4=y
  20826. +CONFIG_ROOT_NFS=y
  20827. +CONFIG_NLS_DEFAULT="cp437"
  20828. +CONFIG_NLS_CODEPAGE_437=y
  20829. +CONFIG_NLS_ASCII=y
  20830. +CONFIG_NLS_ISO8859_1=y
  20831. +CONFIG_NLS_ISO8859_15=m
  20832. +CONFIG_NLS_UTF8=y
  20833. +CONFIG_MAGIC_SYSRQ=y
  20834. +# CONFIG_SCHED_DEBUG is not set
  20835. +# CONFIG_DEBUG_BUGVERBOSE is not set
  20836. +# CONFIG_FTRACE is not set
  20837. +CONFIG_SECURITYFS=y
  20838. +CONFIG_CRYPTO_USER=y
  20839. +CONFIG_CRYPTO_TEST=m
  20840. +CONFIG_CRYPTO_CCM=y
  20841. +CONFIG_CRYPTO_GCM=y
  20842. +CONFIG_CRYPTO_CBC=y
  20843. +CONFIG_CRYPTO_CTS=y
  20844. +CONFIG_CRYPTO_ECB=y
  20845. +CONFIG_CRYPTO_LRW=y
  20846. +CONFIG_CRYPTO_XTS=y
  20847. +CONFIG_CRYPTO_MD4=y
  20848. +CONFIG_CRYPTO_MD5=y
  20849. +CONFIG_CRYPTO_MICHAEL_MIC=y
  20850. +CONFIG_CRYPTO_RMD128=y
  20851. +CONFIG_CRYPTO_RMD160=y
  20852. +CONFIG_CRYPTO_RMD256=y
  20853. +CONFIG_CRYPTO_RMD320=y
  20854. +CONFIG_CRYPTO_SHA1=y
  20855. +CONFIG_CRYPTO_SHA256=y
  20856. +CONFIG_CRYPTO_SHA512=y
  20857. +CONFIG_CRYPTO_TGR192=y
  20858. +CONFIG_CRYPTO_WP512=y
  20859. +CONFIG_CRYPTO_BLOWFISH=y
  20860. +CONFIG_CRYPTO_CAMELLIA=y
  20861. +CONFIG_CRYPTO_DES=y
  20862. +CONFIG_CRYPTO_TWOFISH=y
  20863. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  20864. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  20865. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  20866. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  20867. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  20868. +CONFIG_CRC_CCITT=m
  20869. +CONFIG_CRC_T10DIF=y
  20870. +CONFIG_CRC7=m
  20871. +CONFIG_LIBCRC32C=m
  20872. diff -Nur linux-3.14.14/arch/arm/configs/imx_v7_mfg_defconfig linux-imx6-3.14/arch/arm/configs/imx_v7_mfg_defconfig
  20873. --- linux-3.14.14/arch/arm/configs/imx_v7_mfg_defconfig 1969-12-31 18:00:00.000000000 -0600
  20874. +++ linux-imx6-3.14/arch/arm/configs/imx_v7_mfg_defconfig 2014-12-08 00:31:51.156418001 -0600
  20875. @@ -0,0 +1,341 @@
  20876. +CONFIG_KERNEL_LZO=y
  20877. +CONFIG_SYSVIPC=y
  20878. +CONFIG_NO_HZ=y
  20879. +CONFIG_HIGH_RES_TIMERS=y
  20880. +CONFIG_IKCONFIG=y
  20881. +CONFIG_IKCONFIG_PROC=y
  20882. +CONFIG_LOG_BUF_SHIFT=18
  20883. +CONFIG_CGROUPS=y
  20884. +CONFIG_RELAY=y
  20885. +CONFIG_BLK_DEV_INITRD=y
  20886. +CONFIG_EXPERT=y
  20887. +CONFIG_PERF_EVENTS=y
  20888. +# CONFIG_SLUB_DEBUG is not set
  20889. +# CONFIG_COMPAT_BRK is not set
  20890. +CONFIG_MODULES=y
  20891. +CONFIG_MODULE_UNLOAD=y
  20892. +CONFIG_MODVERSIONS=y
  20893. +CONFIG_MODULE_SRCVERSION_ALL=y
  20894. +# CONFIG_BLK_DEV_BSG is not set
  20895. +CONFIG_GPIO_PCA953X=y
  20896. +CONFIG_ARCH_MXC=y
  20897. +CONFIG_MXC_DEBUG_BOARD=y
  20898. +CONFIG_MACH_IMX51_DT=y
  20899. +CONFIG_MACH_EUKREA_CPUIMX51SD=y
  20900. +CONFIG_SOC_IMX53=y
  20901. +CONFIG_SOC_IMX6Q=y
  20902. +CONFIG_SOC_IMX6SL=y
  20903. +CONFIG_SOC_VF610=y
  20904. +# CONFIG_SWP_EMULATE is not set
  20905. +CONFIG_SMP=y
  20906. +CONFIG_VMSPLIT_2G=y
  20907. +CONFIG_PREEMPT_VOLUNTARY=y
  20908. +CONFIG_AEABI=y
  20909. +# CONFIG_OABI_COMPAT is not set
  20910. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  20911. +CONFIG_CPU_FREQ=y
  20912. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  20913. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  20914. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  20915. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  20916. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  20917. +CONFIG_ARM_IMX6_CPUFREQ=y
  20918. +CONFIG_CPU_IDLE=y
  20919. +CONFIG_VFP=y
  20920. +CONFIG_NEON=y
  20921. +CONFIG_BINFMT_MISC=m
  20922. +CONFIG_PM_RUNTIME=y
  20923. +CONFIG_PM_DEBUG=y
  20924. +CONFIG_PM_TEST_SUSPEND=y
  20925. +CONFIG_NET=y
  20926. +CONFIG_PACKET=y
  20927. +CONFIG_UNIX=y
  20928. +CONFIG_INET=y
  20929. +CONFIG_IP_PNP=y
  20930. +CONFIG_IP_PNP_DHCP=y
  20931. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  20932. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  20933. +# CONFIG_INET_XFRM_MODE_BEET is not set
  20934. +# CONFIG_INET_LRO is not set
  20935. +CONFIG_IPV6=y
  20936. +CONFIG_NETFILTER=y
  20937. +CONFIG_VLAN_8021Q=y
  20938. +CONFIG_CFG80211=y
  20939. +CONFIG_CFG80211_WEXT=y
  20940. +CONFIG_MAC80211=y
  20941. +CONFIG_DEVTMPFS=y
  20942. +CONFIG_DEVTMPFS_MOUNT=y
  20943. +# CONFIG_STANDALONE is not set
  20944. +CONFIG_CMA=y
  20945. +CONFIG_CMA_SIZE_MBYTES=320
  20946. +CONFIG_IMX_WEIM=y
  20947. +CONFIG_CONNECTOR=y
  20948. +CONFIG_MTD=y
  20949. +CONFIG_MTD_CMDLINE_PARTS=y
  20950. +CONFIG_MTD_BLOCK=y
  20951. +CONFIG_MTD_CFI=y
  20952. +CONFIG_MTD_JEDECPROBE=y
  20953. +CONFIG_MTD_CFI_INTELEXT=y
  20954. +CONFIG_MTD_CFI_AMDSTD=y
  20955. +CONFIG_MTD_CFI_STAA=y
  20956. +CONFIG_MTD_PHYSMAP_OF=y
  20957. +CONFIG_MTD_DATAFLASH=y
  20958. +CONFIG_MTD_M25P80=y
  20959. +CONFIG_MTD_SST25L=y
  20960. +CONFIG_MTD_NAND=y
  20961. +CONFIG_MTD_NAND_GPMI_NAND=y
  20962. +CONFIG_MTD_NAND_MXC=y
  20963. +CONFIG_MTD_UBI=y
  20964. +CONFIG_BLK_DEV_LOOP=y
  20965. +CONFIG_BLK_DEV_RAM=y
  20966. +CONFIG_BLK_DEV_RAM_SIZE=65536
  20967. +CONFIG_EEPROM_AT24=y
  20968. +CONFIG_EEPROM_AT25=y
  20969. +# CONFIG_SCSI_PROC_FS is not set
  20970. +CONFIG_BLK_DEV_SD=y
  20971. +CONFIG_SCSI_MULTI_LUN=y
  20972. +CONFIG_SCSI_CONSTANTS=y
  20973. +CONFIG_SCSI_LOGGING=y
  20974. +CONFIG_SCSI_SCAN_ASYNC=y
  20975. +# CONFIG_SCSI_LOWLEVEL is not set
  20976. +CONFIG_ATA=y
  20977. +CONFIG_SATA_AHCI_PLATFORM=y
  20978. +CONFIG_AHCI_IMX=y
  20979. +CONFIG_PATA_IMX=y
  20980. +CONFIG_NETDEVICES=y
  20981. +# CONFIG_NET_VENDOR_BROADCOM is not set
  20982. +CONFIG_CS89x0=y
  20983. +CONFIG_CS89x0_PLATFORM=y
  20984. +# CONFIG_NET_VENDOR_FARADAY is not set
  20985. +# CONFIG_NET_VENDOR_INTEL is not set
  20986. +# CONFIG_NET_VENDOR_MARVELL is not set
  20987. +# CONFIG_NET_VENDOR_MICREL is not set
  20988. +# CONFIG_NET_VENDOR_MICROCHIP is not set
  20989. +# CONFIG_NET_VENDOR_NATSEMI is not set
  20990. +# CONFIG_NET_VENDOR_SEEQ is not set
  20991. +CONFIG_SMC91X=y
  20992. +CONFIG_SMC911X=y
  20993. +CONFIG_SMSC911X=y
  20994. +# CONFIG_NET_VENDOR_STMICRO is not set
  20995. +CONFIG_ATH_CARDS=y
  20996. +CONFIG_ATH6KL=m
  20997. +CONFIG_ATH6KL_SDIO=m
  20998. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  20999. +CONFIG_INPUT_EVDEV=y
  21000. +CONFIG_INPUT_EVBUG=m
  21001. +CONFIG_KEYBOARD_GPIO=y
  21002. +CONFIG_KEYBOARD_IMX=y
  21003. +CONFIG_MOUSE_PS2=m
  21004. +CONFIG_MOUSE_PS2_ELANTECH=y
  21005. +CONFIG_INPUT_TOUCHSCREEN=y
  21006. +CONFIG_TOUCHSCREEN_EGALAX=y
  21007. +CONFIG_TOUCHSCREEN_ELAN=y
  21008. +CONFIG_TOUCHSCREEN_MAX11801=y
  21009. +CONFIG_TOUCHSCREEN_MC13783=y
  21010. +CONFIG_INPUT_MISC=y
  21011. +CONFIG_INPUT_MMA8450=y
  21012. +CONFIG_INPUT_ISL29023=y
  21013. +CONFIG_SERIO_SERPORT=m
  21014. +CONFIG_VT_HW_CONSOLE_BINDING=y
  21015. +# CONFIG_LEGACY_PTYS is not set
  21016. +# CONFIG_DEVKMEM is not set
  21017. +CONFIG_SERIAL_IMX=y
  21018. +CONFIG_SERIAL_IMX_CONSOLE=y
  21019. +CONFIG_SERIAL_FSL_LPUART=y
  21020. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  21021. +CONFIG_FSL_OTP=y
  21022. +# CONFIG_I2C_COMPAT is not set
  21023. +CONFIG_I2C_CHARDEV=y
  21024. +# CONFIG_I2C_HELPER_AUTO is not set
  21025. +CONFIG_I2C_ALGOPCF=m
  21026. +CONFIG_I2C_ALGOPCA=m
  21027. +CONFIG_I2C_IMX=y
  21028. +CONFIG_SPI=y
  21029. +CONFIG_SPI_IMX=y
  21030. +CONFIG_GPIO_SYSFS=y
  21031. +CONFIG_POWER_SUPPLY=y
  21032. +CONFIG_SABRESD_MAX8903=y
  21033. +CONFIG_SENSORS_MAX17135=y
  21034. +CONFIG_SENSORS_MAG3110=y
  21035. +CONFIG_THERMAL=y
  21036. +CONFIG_CPU_THERMAL=y
  21037. +CONFIG_IMX_THERMAL=y
  21038. +CONFIG_DEVICE_THERMAL=y
  21039. +CONFIG_WATCHDOG=y
  21040. +CONFIG_IMX2_WDT=y
  21041. +CONFIG_MFD_DA9052_I2C=y
  21042. +CONFIG_MFD_MC13XXX_SPI=y
  21043. +CONFIG_MFD_MC13XXX_I2C=y
  21044. +CONFIG_MFD_MAX17135=y
  21045. +CONFIG_MFD_SI476X_CORE=y
  21046. +CONFIG_REGULATOR=y
  21047. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  21048. +CONFIG_REGULATOR_DA9052=y
  21049. +CONFIG_REGULATOR_ANATOP=y
  21050. +CONFIG_REGULATOR_MC13783=y
  21051. +CONFIG_REGULATOR_MC13892=y
  21052. +CONFIG_REGULATOR_MAX17135=y
  21053. +CONFIG_REGULATOR_PFUZE100=y
  21054. +CONFIG_MEDIA_SUPPORT=y
  21055. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  21056. +CONFIG_MEDIA_RADIO_SUPPORT=y
  21057. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  21058. +CONFIG_MEDIA_USB_SUPPORT=y
  21059. +CONFIG_USB_VIDEO_CLASS=m
  21060. +CONFIG_V4L_PLATFORM_DRIVERS=y
  21061. +CONFIG_VIDEO_MXC_OUTPUT=y
  21062. +CONFIG_VIDEO_MXC_CAPTURE=m
  21063. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  21064. +CONFIG_MXC_CAMERA_OV5640=m
  21065. +CONFIG_MXC_CAMERA_OV5642=m
  21066. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  21067. +CONFIG_MXC_TVIN_ADV7180=m
  21068. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  21069. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  21070. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  21071. +CONFIG_SOC_CAMERA=y
  21072. +CONFIG_VIDEO_MX3=y
  21073. +CONFIG_RADIO_SI476X=y
  21074. +CONFIG_SOC_CAMERA_OV2640=y
  21075. +CONFIG_DRM=y
  21076. +CONFIG_DRM_VIVANTE=y
  21077. +CONFIG_FB=y
  21078. +CONFIG_FB_MXS=y
  21079. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  21080. +CONFIG_LCD_CLASS_DEVICE=y
  21081. +CONFIG_LCD_L4F00242T03=y
  21082. +CONFIG_LCD_PLATFORM=y
  21083. +CONFIG_BACKLIGHT_CLASS_DEVICE=y
  21084. +CONFIG_BACKLIGHT_PWM=y
  21085. +CONFIG_FB_MXC_SYNC_PANEL=y
  21086. +CONFIG_FB_MXC_LDB=y
  21087. +CONFIG_FB_MXC_MIPI_DSI=y
  21088. +CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
  21089. +CONFIG_FB_MXC_HDMI=y
  21090. +CONFIG_FB_MXC_EINK_PANEL=y
  21091. +CONFIG_FB_MXS_SII902X=y
  21092. +CONFIG_FRAMEBUFFER_CONSOLE=y
  21093. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  21094. +CONFIG_FONTS=y
  21095. +CONFIG_FONT_8x8=y
  21096. +CONFIG_FONT_8x16=y
  21097. +CONFIG_LOGO=y
  21098. +CONFIG_SOUND=y
  21099. +CONFIG_SND=y
  21100. +CONFIG_SND_USB_AUDIO=m
  21101. +CONFIG_SND_SOC=y
  21102. +CONFIG_SND_IMX_SOC=y
  21103. +CONFIG_SND_SOC_EUKREA_TLV320=y
  21104. +CONFIG_SND_SOC_IMX_CS42888=y
  21105. +CONFIG_SND_SOC_IMX_WM8962=y
  21106. +CONFIG_SND_SOC_IMX_SGTL5000=y
  21107. +CONFIG_SND_SOC_IMX_SPDIF=y
  21108. +CONFIG_SND_SOC_IMX_MC13783=y
  21109. +CONFIG_SND_SOC_IMX_HDMI=y
  21110. +CONFIG_SND_SOC_IMX_SI476X=y
  21111. +CONFIG_USB=y
  21112. +CONFIG_USB_EHCI_HCD=y
  21113. +CONFIG_USB_STORAGE=y
  21114. +CONFIG_USB_CHIPIDEA=y
  21115. +CONFIG_USB_CHIPIDEA_UDC=y
  21116. +CONFIG_USB_CHIPIDEA_HOST=y
  21117. +CONFIG_USB_PHY=y
  21118. +CONFIG_USB_MXS_PHY=y
  21119. +CONFIG_USB_GADGET=y
  21120. +# CONFIG_USB_ZERO is not set
  21121. +# CONFIG_USB_AUDIO is not set
  21122. +# CONFIG_USB_ETH is not set
  21123. +# CONFIG_USB_G_NCM is not set
  21124. +# CONFIG_USB_GADGETFS is not set
  21125. +# CONFIG_USB_FUNCTIONFS is not set
  21126. +CONFIG_USB_MASS_STORAGE=y
  21127. +CONFIG_FSL_UTP=y
  21128. +# CONFIG_USB_G_SERIAL is not set
  21129. +# CONFIG_USB_MIDI_GADGET is not set
  21130. +# CONFIG_USB_G_PRINTER is not set
  21131. +# CONFIG_USB_CDC_COMPOSITE is not set
  21132. +# CONFIG_USB_G_ACM_MS is not set
  21133. +# CONFIG_USB_G_MULTI is not set
  21134. +# CONFIG_USB_G_HID is not set
  21135. +# CONFIG_USB_G_DBGP is not set
  21136. +# CONFIG_USB_G_WEBCAM is not set
  21137. +CONFIG_MMC=y
  21138. +CONFIG_MMC_UNSAFE_RESUME=y
  21139. +CONFIG_MMC_SDHCI=y
  21140. +CONFIG_MMC_SDHCI_PLTFM=y
  21141. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  21142. +CONFIG_MXC_IPU=y
  21143. +CONFIG_MXC_GPU_VIV=y
  21144. +CONFIG_MXC_ASRC=y
  21145. +CONFIG_MXC_MIPI_CSI2=y
  21146. +CONFIG_NEW_LEDS=y
  21147. +CONFIG_LEDS_CLASS=y
  21148. +CONFIG_RTC_CLASS=y
  21149. +CONFIG_RTC_INTF_DEV_UIE_EMUL=y
  21150. +CONFIG_RTC_DRV_MC13XXX=y
  21151. +CONFIG_RTC_DRV_MXC=y
  21152. +CONFIG_RTC_DRV_SNVS=y
  21153. +CONFIG_DMADEVICES=y
  21154. +CONFIG_MXC_PXP_V2=y
  21155. +CONFIG_IMX_SDMA=y
  21156. +CONFIG_MXS_DMA=y
  21157. +CONFIG_STAGING=y
  21158. +CONFIG_COMMON_CLK_DEBUG=y
  21159. +# CONFIG_IOMMU_SUPPORT is not set
  21160. +CONFIG_PWM=y
  21161. +CONFIG_PWM_IMX=y
  21162. +CONFIG_EXT2_FS=y
  21163. +CONFIG_EXT2_FS_XATTR=y
  21164. +CONFIG_EXT2_FS_POSIX_ACL=y
  21165. +CONFIG_EXT2_FS_SECURITY=y
  21166. +CONFIG_EXT3_FS=y
  21167. +CONFIG_EXT3_FS_POSIX_ACL=y
  21168. +CONFIG_EXT3_FS_SECURITY=y
  21169. +CONFIG_EXT4_FS=y
  21170. +CONFIG_EXT4_FS_POSIX_ACL=y
  21171. +CONFIG_EXT4_FS_SECURITY=y
  21172. +CONFIG_QUOTA=y
  21173. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  21174. +# CONFIG_PRINT_QUOTA_WARNING is not set
  21175. +CONFIG_AUTOFS4_FS=y
  21176. +CONFIG_FUSE_FS=y
  21177. +CONFIG_ISO9660_FS=m
  21178. +CONFIG_JOLIET=y
  21179. +CONFIG_ZISOFS=y
  21180. +CONFIG_UDF_FS=m
  21181. +CONFIG_MSDOS_FS=m
  21182. +CONFIG_VFAT_FS=y
  21183. +CONFIG_TMPFS=y
  21184. +CONFIG_JFFS2_FS=y
  21185. +CONFIG_UBIFS_FS=y
  21186. +CONFIG_NFS_FS=y
  21187. +CONFIG_NFS_V3_ACL=y
  21188. +CONFIG_NFS_V4=y
  21189. +CONFIG_ROOT_NFS=y
  21190. +CONFIG_NLS_DEFAULT="cp437"
  21191. +CONFIG_NLS_CODEPAGE_437=y
  21192. +CONFIG_NLS_ASCII=y
  21193. +CONFIG_NLS_ISO8859_1=y
  21194. +CONFIG_NLS_ISO8859_15=m
  21195. +CONFIG_NLS_UTF8=y
  21196. +CONFIG_MAGIC_SYSRQ=y
  21197. +# CONFIG_SCHED_DEBUG is not set
  21198. +# CONFIG_DEBUG_BUGVERBOSE is not set
  21199. +# CONFIG_FTRACE is not set
  21200. +CONFIG_SECURITYFS=y
  21201. +CONFIG_CRYPTO_USER=y
  21202. +CONFIG_CRYPTO_CCM=y
  21203. +CONFIG_CRYPTO_GCM=y
  21204. +CONFIG_CRYPTO_CBC=y
  21205. +CONFIG_CRYPTO_CTS=y
  21206. +CONFIG_CRYPTO_ECB=y
  21207. +CONFIG_CRYPTO_LRW=y
  21208. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  21209. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  21210. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  21211. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  21212. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  21213. +CONFIG_CRC_CCITT=m
  21214. +CONFIG_CRC_T10DIF=y
  21215. +CONFIG_CRC7=m
  21216. +CONFIG_LIBCRC32C=m
  21217. diff -Nur linux-3.14.14/arch/arm/include/asm/arch_timer.h linux-imx6-3.14/arch/arm/include/asm/arch_timer.h
  21218. --- linux-3.14.14/arch/arm/include/asm/arch_timer.h 2014-07-28 10:07:25.000000000 -0500
  21219. +++ linux-imx6-3.14/arch/arm/include/asm/arch_timer.h 2014-12-08 00:31:51.168418001 -0600
  21220. @@ -107,7 +107,6 @@
  21221. /* Also disable virtual event stream */
  21222. cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
  21223. | ARCH_TIMER_USR_VT_ACCESS_EN
  21224. - | ARCH_TIMER_VIRT_EVT_EN
  21225. | ARCH_TIMER_USR_VCT_ACCESS_EN
  21226. | ARCH_TIMER_USR_PCT_ACCESS_EN);
  21227. arch_timer_set_cntkctl(cntkctl);
  21228. diff -Nur linux-3.14.14/arch/arm/include/asm/atomic.h linux-imx6-3.14/arch/arm/include/asm/atomic.h
  21229. --- linux-3.14.14/arch/arm/include/asm/atomic.h 2014-07-28 10:07:25.000000000 -0500
  21230. +++ linux-imx6-3.14/arch/arm/include/asm/atomic.h 2014-12-08 00:31:51.168418001 -0600
  21231. @@ -60,6 +60,7 @@
  21232. int result;
  21233. smp_mb();
  21234. + prefetchw(&v->counter);
  21235. __asm__ __volatile__("@ atomic_add_return\n"
  21236. "1: ldrex %0, [%3]\n"
  21237. @@ -99,6 +100,7 @@
  21238. int result;
  21239. smp_mb();
  21240. + prefetchw(&v->counter);
  21241. __asm__ __volatile__("@ atomic_sub_return\n"
  21242. "1: ldrex %0, [%3]\n"
  21243. @@ -121,6 +123,7 @@
  21244. unsigned long res;
  21245. smp_mb();
  21246. + prefetchw(&ptr->counter);
  21247. do {
  21248. __asm__ __volatile__("@ atomic_cmpxchg\n"
  21249. @@ -138,6 +141,33 @@
  21250. return oldval;
  21251. }
  21252. +static inline int __atomic_add_unless(atomic_t *v, int a, int u)
  21253. +{
  21254. + int oldval, newval;
  21255. + unsigned long tmp;
  21256. +
  21257. + smp_mb();
  21258. + prefetchw(&v->counter);
  21259. +
  21260. + __asm__ __volatile__ ("@ atomic_add_unless\n"
  21261. +"1: ldrex %0, [%4]\n"
  21262. +" teq %0, %5\n"
  21263. +" beq 2f\n"
  21264. +" add %1, %0, %6\n"
  21265. +" strex %2, %1, [%4]\n"
  21266. +" teq %2, #0\n"
  21267. +" bne 1b\n"
  21268. +"2:"
  21269. + : "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter)
  21270. + : "r" (&v->counter), "r" (u), "r" (a)
  21271. + : "cc");
  21272. +
  21273. + if (oldval != u)
  21274. + smp_mb();
  21275. +
  21276. + return oldval;
  21277. +}
  21278. +
  21279. #else /* ARM_ARCH_6 */
  21280. #ifdef CONFIG_SMP
  21281. @@ -186,10 +216,6 @@
  21282. return ret;
  21283. }
  21284. -#endif /* __LINUX_ARM_ARCH__ */
  21285. -
  21286. -#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
  21287. -
  21288. static inline int __atomic_add_unless(atomic_t *v, int a, int u)
  21289. {
  21290. int c, old;
  21291. @@ -200,6 +226,10 @@
  21292. return c;
  21293. }
  21294. +#endif /* __LINUX_ARM_ARCH__ */
  21295. +
  21296. +#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
  21297. +
  21298. #define atomic_inc(v) atomic_add(1, v)
  21299. #define atomic_dec(v) atomic_sub(1, v)
  21300. @@ -299,6 +329,7 @@
  21301. unsigned long tmp;
  21302. smp_mb();
  21303. + prefetchw(&v->counter);
  21304. __asm__ __volatile__("@ atomic64_add_return\n"
  21305. "1: ldrexd %0, %H0, [%3]\n"
  21306. @@ -340,6 +371,7 @@
  21307. unsigned long tmp;
  21308. smp_mb();
  21309. + prefetchw(&v->counter);
  21310. __asm__ __volatile__("@ atomic64_sub_return\n"
  21311. "1: ldrexd %0, %H0, [%3]\n"
  21312. @@ -364,6 +396,7 @@
  21313. unsigned long res;
  21314. smp_mb();
  21315. + prefetchw(&ptr->counter);
  21316. do {
  21317. __asm__ __volatile__("@ atomic64_cmpxchg\n"
  21318. @@ -388,6 +421,7 @@
  21319. unsigned long tmp;
  21320. smp_mb();
  21321. + prefetchw(&ptr->counter);
  21322. __asm__ __volatile__("@ atomic64_xchg\n"
  21323. "1: ldrexd %0, %H0, [%3]\n"
  21324. @@ -409,6 +443,7 @@
  21325. unsigned long tmp;
  21326. smp_mb();
  21327. + prefetchw(&v->counter);
  21328. __asm__ __volatile__("@ atomic64_dec_if_positive\n"
  21329. "1: ldrexd %0, %H0, [%3]\n"
  21330. @@ -436,6 +471,7 @@
  21331. int ret = 1;
  21332. smp_mb();
  21333. + prefetchw(&v->counter);
  21334. __asm__ __volatile__("@ atomic64_add_unless\n"
  21335. "1: ldrexd %0, %H0, [%4]\n"
  21336. diff -Nur linux-3.14.14/arch/arm/include/asm/cmpxchg.h linux-imx6-3.14/arch/arm/include/asm/cmpxchg.h
  21337. --- linux-3.14.14/arch/arm/include/asm/cmpxchg.h 2014-07-28 10:07:25.000000000 -0500
  21338. +++ linux-imx6-3.14/arch/arm/include/asm/cmpxchg.h 2014-12-08 00:31:51.168418001 -0600
  21339. @@ -2,6 +2,7 @@
  21340. #define __ASM_ARM_CMPXCHG_H
  21341. #include <linux/irqflags.h>
  21342. +#include <linux/prefetch.h>
  21343. #include <asm/barrier.h>
  21344. #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
  21345. @@ -35,6 +36,7 @@
  21346. #endif
  21347. smp_mb();
  21348. + prefetchw((const void *)ptr);
  21349. switch (size) {
  21350. #if __LINUX_ARM_ARCH__ >= 6
  21351. @@ -138,6 +140,8 @@
  21352. {
  21353. unsigned long oldval, res;
  21354. + prefetchw((const void *)ptr);
  21355. +
  21356. switch (size) {
  21357. #ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
  21358. case 1:
  21359. @@ -230,6 +234,8 @@
  21360. unsigned long long oldval;
  21361. unsigned long res;
  21362. + prefetchw(ptr);
  21363. +
  21364. __asm__ __volatile__(
  21365. "1: ldrexd %1, %H1, [%3]\n"
  21366. " teq %1, %4\n"
  21367. diff -Nur linux-3.14.14/arch/arm/include/asm/ftrace.h linux-imx6-3.14/arch/arm/include/asm/ftrace.h
  21368. --- linux-3.14.14/arch/arm/include/asm/ftrace.h 2014-07-28 10:07:25.000000000 -0500
  21369. +++ linux-imx6-3.14/arch/arm/include/asm/ftrace.h 2014-12-08 00:31:51.172418001 -0600
  21370. @@ -52,15 +52,7 @@
  21371. #endif
  21372. -#define HAVE_ARCH_CALLER_ADDR
  21373. -
  21374. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  21375. -#define CALLER_ADDR1 ((unsigned long)return_address(1))
  21376. -#define CALLER_ADDR2 ((unsigned long)return_address(2))
  21377. -#define CALLER_ADDR3 ((unsigned long)return_address(3))
  21378. -#define CALLER_ADDR4 ((unsigned long)return_address(4))
  21379. -#define CALLER_ADDR5 ((unsigned long)return_address(5))
  21380. -#define CALLER_ADDR6 ((unsigned long)return_address(6))
  21381. +#define ftrace_return_address(n) return_address(n)
  21382. #endif /* ifndef __ASSEMBLY__ */
  21383. diff -Nur linux-3.14.14/arch/arm/include/asm/futex.h linux-imx6-3.14/arch/arm/include/asm/futex.h
  21384. --- linux-3.14.14/arch/arm/include/asm/futex.h 2014-07-28 10:07:25.000000000 -0500
  21385. +++ linux-imx6-3.14/arch/arm/include/asm/futex.h 2014-12-08 00:31:51.172418001 -0600
  21386. @@ -23,6 +23,7 @@
  21387. #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
  21388. smp_mb(); \
  21389. + prefetchw(uaddr); \
  21390. __asm__ __volatile__( \
  21391. "1: ldrex %1, [%3]\n" \
  21392. " " insn "\n" \
  21393. @@ -46,6 +47,8 @@
  21394. return -EFAULT;
  21395. smp_mb();
  21396. + /* Prefetching cannot fault */
  21397. + prefetchw(uaddr);
  21398. __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
  21399. "1: ldrex %1, [%4]\n"
  21400. " teq %1, %2\n"
  21401. diff -Nur linux-3.14.14/arch/arm/include/asm/glue-cache.h linux-imx6-3.14/arch/arm/include/asm/glue-cache.h
  21402. --- linux-3.14.14/arch/arm/include/asm/glue-cache.h 2014-07-28 10:07:25.000000000 -0500
  21403. +++ linux-imx6-3.14/arch/arm/include/asm/glue-cache.h 2014-12-08 00:31:51.172418001 -0600
  21404. @@ -102,19 +102,19 @@
  21405. #endif
  21406. #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
  21407. -# ifdef _CACHE
  21408. +//# ifdef _CACHE
  21409. # define MULTI_CACHE 1
  21410. -# else
  21411. -# define _CACHE v6
  21412. -# endif
  21413. +//# else
  21414. +//# define _CACHE v6
  21415. +//# endif
  21416. #endif
  21417. #if defined(CONFIG_CPU_V7)
  21418. -# ifdef _CACHE
  21419. +//# ifdef _CACHE
  21420. # define MULTI_CACHE 1
  21421. -# else
  21422. -# define _CACHE v7
  21423. -# endif
  21424. +//# else
  21425. +//# define _CACHE v7
  21426. +//# endif
  21427. #endif
  21428. #if defined(CONFIG_CPU_V7M)
  21429. diff -Nur linux-3.14.14/arch/arm/include/asm/hardware/cache-l2x0.h linux-imx6-3.14/arch/arm/include/asm/hardware/cache-l2x0.h
  21430. --- linux-3.14.14/arch/arm/include/asm/hardware/cache-l2x0.h 2014-07-28 10:07:25.000000000 -0500
  21431. +++ linux-imx6-3.14/arch/arm/include/asm/hardware/cache-l2x0.h 2014-12-08 00:31:51.172418001 -0600
  21432. @@ -26,8 +26,8 @@
  21433. #define L2X0_CACHE_TYPE 0x004
  21434. #define L2X0_CTRL 0x100
  21435. #define L2X0_AUX_CTRL 0x104
  21436. -#define L2X0_TAG_LATENCY_CTRL 0x108
  21437. -#define L2X0_DATA_LATENCY_CTRL 0x10C
  21438. +#define L310_TAG_LATENCY_CTRL 0x108
  21439. +#define L310_DATA_LATENCY_CTRL 0x10C
  21440. #define L2X0_EVENT_CNT_CTRL 0x200
  21441. #define L2X0_EVENT_CNT1_CFG 0x204
  21442. #define L2X0_EVENT_CNT0_CFG 0x208
  21443. @@ -54,53 +54,93 @@
  21444. #define L2X0_LOCKDOWN_WAY_D_BASE 0x900
  21445. #define L2X0_LOCKDOWN_WAY_I_BASE 0x904
  21446. #define L2X0_LOCKDOWN_STRIDE 0x08
  21447. -#define L2X0_ADDR_FILTER_START 0xC00
  21448. -#define L2X0_ADDR_FILTER_END 0xC04
  21449. +#define L310_ADDR_FILTER_START 0xC00
  21450. +#define L310_ADDR_FILTER_END 0xC04
  21451. #define L2X0_TEST_OPERATION 0xF00
  21452. #define L2X0_LINE_DATA 0xF10
  21453. #define L2X0_LINE_TAG 0xF30
  21454. #define L2X0_DEBUG_CTRL 0xF40
  21455. -#define L2X0_PREFETCH_CTRL 0xF60
  21456. -#define L2X0_POWER_CTRL 0xF80
  21457. -#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1)
  21458. -#define L2X0_STNDBY_MODE_EN (1 << 0)
  21459. +#define L310_PREFETCH_CTRL 0xF60
  21460. +#define L310_POWER_CTRL 0xF80
  21461. +#define L310_DYNAMIC_CLK_GATING_EN (1 << 1)
  21462. +#define L310_STNDBY_MODE_EN (1 << 0)
  21463. /* Registers shifts and masks */
  21464. #define L2X0_CACHE_ID_PART_MASK (0xf << 6)
  21465. #define L2X0_CACHE_ID_PART_L210 (1 << 6)
  21466. +#define L2X0_CACHE_ID_PART_L220 (2 << 6)
  21467. #define L2X0_CACHE_ID_PART_L310 (3 << 6)
  21468. #define L2X0_CACHE_ID_RTL_MASK 0x3f
  21469. -#define L2X0_CACHE_ID_RTL_R0P0 0x0
  21470. -#define L2X0_CACHE_ID_RTL_R1P0 0x2
  21471. -#define L2X0_CACHE_ID_RTL_R2P0 0x4
  21472. -#define L2X0_CACHE_ID_RTL_R3P0 0x5
  21473. -#define L2X0_CACHE_ID_RTL_R3P1 0x6
  21474. -#define L2X0_CACHE_ID_RTL_R3P2 0x8
  21475. -
  21476. -#define L2X0_AUX_CTRL_MASK 0xc0000fff
  21477. +#define L210_CACHE_ID_RTL_R0P2_02 0x00
  21478. +#define L210_CACHE_ID_RTL_R0P1 0x01
  21479. +#define L210_CACHE_ID_RTL_R0P2_01 0x02
  21480. +#define L210_CACHE_ID_RTL_R0P3 0x03
  21481. +#define L210_CACHE_ID_RTL_R0P4 0x0b
  21482. +#define L210_CACHE_ID_RTL_R0P5 0x0f
  21483. +#define L220_CACHE_ID_RTL_R1P7_01REL0 0x06
  21484. +#define L310_CACHE_ID_RTL_R0P0 0x00
  21485. +#define L310_CACHE_ID_RTL_R1P0 0x02
  21486. +#define L310_CACHE_ID_RTL_R2P0 0x04
  21487. +#define L310_CACHE_ID_RTL_R3P0 0x05
  21488. +#define L310_CACHE_ID_RTL_R3P1 0x06
  21489. +#define L310_CACHE_ID_RTL_R3P1_50REL0 0x07
  21490. +#define L310_CACHE_ID_RTL_R3P2 0x08
  21491. +#define L310_CACHE_ID_RTL_R3P3 0x09
  21492. +
  21493. +/* L2C auxiliary control register - bits common to L2C-210/220/310 */
  21494. +#define L2C_AUX_CTRL_WAY_SIZE_SHIFT 17
  21495. +#define L2C_AUX_CTRL_WAY_SIZE_MASK (7 << 17)
  21496. +#define L2C_AUX_CTRL_WAY_SIZE(n) ((n) << 17)
  21497. +#define L2C_AUX_CTRL_EVTMON_ENABLE BIT(20)
  21498. +#define L2C_AUX_CTRL_PARITY_ENABLE BIT(21)
  21499. +#define L2C_AUX_CTRL_SHARED_OVERRIDE BIT(22)
  21500. +/* L2C-210/220 common bits */
  21501. #define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT 0
  21502. -#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK 0x7
  21503. +#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK (7 << 0)
  21504. #define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT 3
  21505. -#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK (0x7 << 3)
  21506. +#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK (7 << 3)
  21507. #define L2X0_AUX_CTRL_TAG_LATENCY_SHIFT 6
  21508. -#define L2X0_AUX_CTRL_TAG_LATENCY_MASK (0x7 << 6)
  21509. +#define L2X0_AUX_CTRL_TAG_LATENCY_MASK (7 << 6)
  21510. #define L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT 9
  21511. -#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK (0x7 << 9)
  21512. -#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16
  21513. -#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17
  21514. -#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17)
  21515. -#define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22
  21516. -#define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26
  21517. -#define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27
  21518. -#define L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT 28
  21519. -#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29
  21520. -#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30
  21521. -
  21522. -#define L2X0_LATENCY_CTRL_SETUP_SHIFT 0
  21523. -#define L2X0_LATENCY_CTRL_RD_SHIFT 4
  21524. -#define L2X0_LATENCY_CTRL_WR_SHIFT 8
  21525. -
  21526. -#define L2X0_ADDR_FILTER_EN 1
  21527. +#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK (7 << 9)
  21528. +#define L2X0_AUX_CTRL_ASSOC_SHIFT 13
  21529. +#define L2X0_AUX_CTRL_ASSOC_MASK (15 << 13)
  21530. +/* L2C-210 specific bits */
  21531. +#define L210_AUX_CTRL_WRAP_DISABLE BIT(12)
  21532. +#define L210_AUX_CTRL_WA_OVERRIDE BIT(23)
  21533. +#define L210_AUX_CTRL_EXCLUSIVE_ABORT BIT(24)
  21534. +/* L2C-220 specific bits */
  21535. +#define L220_AUX_CTRL_EXCLUSIVE_CACHE BIT(12)
  21536. +#define L220_AUX_CTRL_FWA_SHIFT 23
  21537. +#define L220_AUX_CTRL_FWA_MASK (3 << 23)
  21538. +#define L220_AUX_CTRL_NS_LOCKDOWN BIT(26)
  21539. +#define L220_AUX_CTRL_NS_INT_CTRL BIT(27)
  21540. +/* L2C-310 specific bits */
  21541. +#define L310_AUX_CTRL_FULL_LINE_ZERO BIT(0) /* R2P0+ */
  21542. +#define L310_AUX_CTRL_HIGHPRIO_SO_DEV BIT(10) /* R2P0+ */
  21543. +#define L310_AUX_CTRL_STORE_LIMITATION BIT(11) /* R2P0+ */
  21544. +#define L310_AUX_CTRL_EXCLUSIVE_CACHE BIT(12)
  21545. +#define L310_AUX_CTRL_ASSOCIATIVITY_16 BIT(16)
  21546. +#define L310_AUX_CTRL_CACHE_REPLACE_RR BIT(25) /* R2P0+ */
  21547. +#define L310_AUX_CTRL_NS_LOCKDOWN BIT(26)
  21548. +#define L310_AUX_CTRL_NS_INT_CTRL BIT(27)
  21549. +#define L310_AUX_CTRL_DATA_PREFETCH BIT(28)
  21550. +#define L310_AUX_CTRL_INSTR_PREFETCH BIT(29)
  21551. +#define L310_AUX_CTRL_EARLY_BRESP BIT(30) /* R2P0+ */
  21552. +
  21553. +#define L310_LATENCY_CTRL_SETUP(n) ((n) << 0)
  21554. +#define L310_LATENCY_CTRL_RD(n) ((n) << 4)
  21555. +#define L310_LATENCY_CTRL_WR(n) ((n) << 8)
  21556. +
  21557. +#define L310_ADDR_FILTER_EN 1
  21558. +
  21559. +#define L310_PREFETCH_CTRL_OFFSET_MASK 0x1f
  21560. +#define L310_PREFETCH_CTRL_DBL_LINEFILL_INCR BIT(23)
  21561. +#define L310_PREFETCH_CTRL_PREFETCH_DROP BIT(24)
  21562. +#define L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP BIT(27)
  21563. +#define L310_PREFETCH_CTRL_DATA_PREFETCH BIT(28)
  21564. +#define L310_PREFETCH_CTRL_INSTR_PREFETCH BIT(29)
  21565. +#define L310_PREFETCH_CTRL_DBL_LINEFILL BIT(30)
  21566. #define L2X0_CTRL_EN 1
  21567. diff -Nur linux-3.14.14/arch/arm/include/asm/outercache.h linux-imx6-3.14/arch/arm/include/asm/outercache.h
  21568. --- linux-3.14.14/arch/arm/include/asm/outercache.h 2014-07-28 10:07:25.000000000 -0500
  21569. +++ linux-imx6-3.14/arch/arm/include/asm/outercache.h 2014-12-08 00:31:51.176418001 -0600
  21570. @@ -21,6 +21,7 @@
  21571. #ifndef __ASM_OUTERCACHE_H
  21572. #define __ASM_OUTERCACHE_H
  21573. +#include <linux/bug.h>
  21574. #include <linux/types.h>
  21575. struct outer_cache_fns {
  21576. @@ -28,53 +29,84 @@
  21577. void (*clean_range)(unsigned long, unsigned long);
  21578. void (*flush_range)(unsigned long, unsigned long);
  21579. void (*flush_all)(void);
  21580. - void (*inv_all)(void);
  21581. void (*disable)(void);
  21582. #ifdef CONFIG_OUTER_CACHE_SYNC
  21583. void (*sync)(void);
  21584. #endif
  21585. - void (*set_debug)(unsigned long);
  21586. void (*resume)(void);
  21587. +
  21588. + /* This is an ARM L2C thing */
  21589. + void (*write_sec)(unsigned long, unsigned);
  21590. };
  21591. extern struct outer_cache_fns outer_cache;
  21592. #ifdef CONFIG_OUTER_CACHE
  21593. -
  21594. +/**
  21595. + * outer_inv_range - invalidate range of outer cache lines
  21596. + * @start: starting physical address, inclusive
  21597. + * @end: end physical address, exclusive
  21598. + */
  21599. static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
  21600. {
  21601. if (outer_cache.inv_range)
  21602. outer_cache.inv_range(start, end);
  21603. }
  21604. +
  21605. +/**
  21606. + * outer_clean_range - clean dirty outer cache lines
  21607. + * @start: starting physical address, inclusive
  21608. + * @end: end physical address, exclusive
  21609. + */
  21610. static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
  21611. {
  21612. if (outer_cache.clean_range)
  21613. outer_cache.clean_range(start, end);
  21614. }
  21615. +
  21616. +/**
  21617. + * outer_flush_range - clean and invalidate outer cache lines
  21618. + * @start: starting physical address, inclusive
  21619. + * @end: end physical address, exclusive
  21620. + */
  21621. static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
  21622. {
  21623. if (outer_cache.flush_range)
  21624. outer_cache.flush_range(start, end);
  21625. }
  21626. +/**
  21627. + * outer_flush_all - clean and invalidate all cache lines in the outer cache
  21628. + *
  21629. + * Note: depending on implementation, this may not be atomic - it must
  21630. + * only be called with interrupts disabled and no other active outer
  21631. + * cache masters.
  21632. + *
  21633. + * It is intended that this function is only used by implementations
  21634. + * needing to override the outer_cache.disable() method due to security.
  21635. + * (Some implementations perform this as a clean followed by an invalidate.)
  21636. + */
  21637. static inline void outer_flush_all(void)
  21638. {
  21639. if (outer_cache.flush_all)
  21640. outer_cache.flush_all();
  21641. }
  21642. -static inline void outer_inv_all(void)
  21643. -{
  21644. - if (outer_cache.inv_all)
  21645. - outer_cache.inv_all();
  21646. -}
  21647. -
  21648. -static inline void outer_disable(void)
  21649. -{
  21650. - if (outer_cache.disable)
  21651. - outer_cache.disable();
  21652. -}
  21653. -
  21654. +/**
  21655. + * outer_disable - clean, invalidate and disable the outer cache
  21656. + *
  21657. + * Disable the outer cache, ensuring that any data contained in the outer
  21658. + * cache is pushed out to lower levels of system memory. The note and
  21659. + * conditions above concerning outer_flush_all() applies here.
  21660. + */
  21661. +extern void outer_disable(void);
  21662. +
  21663. +/**
  21664. + * outer_resume - restore the cache configuration and re-enable outer cache
  21665. + *
  21666. + * Restore any configuration that the cache had when previously enabled,
  21667. + * and re-enable the outer cache.
  21668. + */
  21669. static inline void outer_resume(void)
  21670. {
  21671. if (outer_cache.resume)
  21672. @@ -90,13 +122,18 @@
  21673. static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
  21674. { }
  21675. static inline void outer_flush_all(void) { }
  21676. -static inline void outer_inv_all(void) { }
  21677. static inline void outer_disable(void) { }
  21678. static inline void outer_resume(void) { }
  21679. #endif
  21680. #ifdef CONFIG_OUTER_CACHE_SYNC
  21681. +/**
  21682. + * outer_sync - perform a sync point for outer cache
  21683. + *
  21684. + * Ensure that all outer cache operations are complete and any store
  21685. + * buffers are drained.
  21686. + */
  21687. static inline void outer_sync(void)
  21688. {
  21689. if (outer_cache.sync)
  21690. diff -Nur linux-3.14.14/arch/arm/include/asm/pmu.h linux-imx6-3.14/arch/arm/include/asm/pmu.h
  21691. --- linux-3.14.14/arch/arm/include/asm/pmu.h 2014-07-28 10:07:25.000000000 -0500
  21692. +++ linux-imx6-3.14/arch/arm/include/asm/pmu.h 2014-12-08 00:31:51.176418001 -0600
  21693. @@ -62,9 +62,19 @@
  21694. raw_spinlock_t pmu_lock;
  21695. };
  21696. +struct cpupmu_regs {
  21697. + u32 pmc;
  21698. + u32 pmcntenset;
  21699. + u32 pmuseren;
  21700. + u32 pmintenset;
  21701. + u32 pmxevttype[8];
  21702. + u32 pmxevtcnt[8];
  21703. +};
  21704. +
  21705. struct arm_pmu {
  21706. struct pmu pmu;
  21707. cpumask_t active_irqs;
  21708. + cpumask_t valid_cpus;
  21709. char *name;
  21710. irqreturn_t (*handle_irq)(int irq_num, void *dev);
  21711. void (*enable)(struct perf_event *event);
  21712. @@ -81,6 +91,8 @@
  21713. int (*request_irq)(struct arm_pmu *, irq_handler_t handler);
  21714. void (*free_irq)(struct arm_pmu *);
  21715. int (*map_event)(struct perf_event *event);
  21716. + void (*save_regs)(struct arm_pmu *, struct cpupmu_regs *);
  21717. + void (*restore_regs)(struct arm_pmu *, struct cpupmu_regs *);
  21718. int num_events;
  21719. atomic_t active_events;
  21720. struct mutex reserve_mutex;
  21721. diff -Nur linux-3.14.14/arch/arm/include/asm/psci.h linux-imx6-3.14/arch/arm/include/asm/psci.h
  21722. --- linux-3.14.14/arch/arm/include/asm/psci.h 2014-07-28 10:07:25.000000000 -0500
  21723. +++ linux-imx6-3.14/arch/arm/include/asm/psci.h 2014-12-08 00:31:51.176418001 -0600
  21724. @@ -16,6 +16,10 @@
  21725. #define PSCI_POWER_STATE_TYPE_STANDBY 0
  21726. #define PSCI_POWER_STATE_TYPE_POWER_DOWN 1
  21727. +#define PSCI_POWER_STATE_AFFINITY_LEVEL0 0
  21728. +#define PSCI_POWER_STATE_AFFINITY_LEVEL1 1
  21729. +#define PSCI_POWER_STATE_AFFINITY_LEVEL2 2
  21730. +#define PSCI_POWER_STATE_AFFINITY_LEVEL3 3
  21731. struct psci_power_state {
  21732. u16 id;
  21733. @@ -42,4 +46,12 @@
  21734. static inline bool psci_smp_available(void) { return false; }
  21735. #endif
  21736. +#ifdef CONFIG_ARM_PSCI
  21737. +extern int psci_probe(void);
  21738. +#else
  21739. +static inline int psci_probe(void)
  21740. +{
  21741. + return -ENODEV;
  21742. +}
  21743. +#endif
  21744. #endif /* __ASM_ARM_PSCI_H */
  21745. diff -Nur linux-3.14.14/arch/arm/include/asm/topology.h linux-imx6-3.14/arch/arm/include/asm/topology.h
  21746. --- linux-3.14.14/arch/arm/include/asm/topology.h 2014-07-28 10:07:25.000000000 -0500
  21747. +++ linux-imx6-3.14/arch/arm/include/asm/topology.h 2014-12-08 00:31:51.176418001 -0600
  21748. @@ -26,11 +26,14 @@
  21749. void init_cpu_topology(void);
  21750. void store_cpu_topology(unsigned int cpuid);
  21751. const struct cpumask *cpu_coregroup_mask(int cpu);
  21752. +int cluster_to_logical_mask(unsigned int socket_id, cpumask_t *cluster_mask);
  21753. #else
  21754. static inline void init_cpu_topology(void) { }
  21755. static inline void store_cpu_topology(unsigned int cpuid) { }
  21756. +static inline int cluster_to_logical_mask(unsigned int socket_id,
  21757. + cpumask_t *cluster_mask) { return -EINVAL; }
  21758. #endif
  21759. diff -Nur linux-3.14.14/arch/arm/Kconfig linux-imx6-3.14/arch/arm/Kconfig
  21760. --- linux-3.14.14/arch/arm/Kconfig 2014-07-28 10:07:25.000000000 -0500
  21761. +++ linux-imx6-3.14/arch/arm/Kconfig 2014-12-08 00:31:51.108418001 -0600
  21762. @@ -1216,19 +1216,6 @@
  21763. register of the Cortex-A9 which reduces the linefill issuing
  21764. capabilities of the processor.
  21765. -config PL310_ERRATA_588369
  21766. - bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
  21767. - depends on CACHE_L2X0
  21768. - help
  21769. - The PL310 L2 cache controller implements three types of Clean &
  21770. - Invalidate maintenance operations: by Physical Address
  21771. - (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
  21772. - They are architecturally defined to behave as the execution of a
  21773. - clean operation followed immediately by an invalidate operation,
  21774. - both performing to the same memory location. This functionality
  21775. - is not correctly implemented in PL310 as clean lines are not
  21776. - invalidated as a result of these operations.
  21777. -
  21778. config ARM_ERRATA_643719
  21779. bool "ARM errata: LoUIS bit field in CLIDR register is incorrect"
  21780. depends on CPU_V7 && SMP
  21781. @@ -1251,17 +1238,6 @@
  21782. tables. The workaround changes the TLB flushing routines to invalidate
  21783. entries regardless of the ASID.
  21784. -config PL310_ERRATA_727915
  21785. - bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
  21786. - depends on CACHE_L2X0
  21787. - help
  21788. - PL310 implements the Clean & Invalidate by Way L2 cache maintenance
  21789. - operation (offset 0x7FC). This operation runs in background so that
  21790. - PL310 can handle normal accesses while it is in progress. Under very
  21791. - rare circumstances, due to this erratum, write data can be lost when
  21792. - PL310 treats a cacheable write transaction during a Clean &
  21793. - Invalidate by Way operation.
  21794. -
  21795. config ARM_ERRATA_743622
  21796. bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption"
  21797. depends on CPU_V7
  21798. @@ -1287,21 +1263,6 @@
  21799. operation is received by a CPU before the ICIALLUIS has completed,
  21800. potentially leading to corrupted entries in the cache or TLB.
  21801. -config PL310_ERRATA_753970
  21802. - bool "PL310 errata: cache sync operation may be faulty"
  21803. - depends on CACHE_PL310
  21804. - help
  21805. - This option enables the workaround for the 753970 PL310 (r3p0) erratum.
  21806. -
  21807. - Under some condition the effect of cache sync operation on
  21808. - the store buffer still remains when the operation completes.
  21809. - This means that the store buffer is always asked to drain and
  21810. - this prevents it from merging any further writes. The workaround
  21811. - is to replace the normal offset of cache sync operation (0x730)
  21812. - by another offset targeting an unmapped PL310 register 0x740.
  21813. - This has the same effect as the cache sync operation: store buffer
  21814. - drain and waiting for all buffers empty.
  21815. -
  21816. config ARM_ERRATA_754322
  21817. bool "ARM errata: possible faulty MMU translations following an ASID switch"
  21818. depends on CPU_V7
  21819. @@ -1350,18 +1311,6 @@
  21820. relevant cache maintenance functions and sets a specific bit
  21821. in the diagnostic control register of the SCU.
  21822. -config PL310_ERRATA_769419
  21823. - bool "PL310 errata: no automatic Store Buffer drain"
  21824. - depends on CACHE_L2X0
  21825. - help
  21826. - On revisions of the PL310 prior to r3p2, the Store Buffer does
  21827. - not automatically drain. This can cause normal, non-cacheable
  21828. - writes to be retained when the memory system is idle, leading
  21829. - to suboptimal I/O performance for drivers using coherent DMA.
  21830. - This option adds a write barrier to the cpu_idle loop so that,
  21831. - on systems with an outer cache, the store buffer is drained
  21832. - explicitly.
  21833. -
  21834. config ARM_ERRATA_775420
  21835. bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock"
  21836. depends on CPU_V7
  21837. @@ -1391,6 +1340,29 @@
  21838. loop buffer may deliver incorrect instructions. This
  21839. workaround disables the loop buffer to avoid the erratum.
  21840. +config ARM_ERRATA_794072
  21841. + bool "ARM errata: A short loop including a DMB instruction might cause a denial of service"
  21842. + depends on CPU_V7 && SMP
  21843. + help
  21844. + This option enables the workaround for the 794072 Cortex-A9
  21845. + (all revisions). A processor which continuously executes a short
  21846. + loop containing a DMB instruction might prevent a CP15 operation
  21847. + broadcast by another processor making further progress, causing
  21848. + a denial of service. This erratum can be worked around by setting
  21849. + bit[4] of the undocumented Diagnostic Control Register to 1.
  21850. +
  21851. +config ARM_ERRATA_761320
  21852. + bool "Full cache line writes to the same memory region from at least two processors might deadlock processor"
  21853. + depends on CPU_V7 && SMP
  21854. + help
  21855. + This option enables the workaround for the 761320 Cortex-A9 (r0..r3).
  21856. + Under very rare circumstances, full cache line writes
  21857. + from (at least) 2 processors on cache lines in hazard with
  21858. + other requests may cause arbitration issues in the SCU,
  21859. + leading to processor deadlock. This erratum can be
  21860. + worked around by setting bit[21] of the undocumented
  21861. + Diagnostic Control Register to 1.
  21862. +
  21863. endmenu
  21864. source "arch/arm/common/Kconfig"
  21865. @@ -1835,6 +1807,7 @@
  21866. range 11 64 if ARCH_SHMOBILE_LEGACY
  21867. default "12" if SOC_AM33XX
  21868. default "9" if SA1111 || ARCH_EFM32
  21869. + default "14" if ARCH_MXC
  21870. default "11"
  21871. help
  21872. The kernel memory allocator divides physically contiguous memory
  21873. diff -Nur linux-3.14.14/arch/arm/kernel/perf_event.c linux-imx6-3.14/arch/arm/kernel/perf_event.c
  21874. --- linux-3.14.14/arch/arm/kernel/perf_event.c 2014-07-28 10:07:25.000000000 -0500
  21875. +++ linux-imx6-3.14/arch/arm/kernel/perf_event.c 2014-12-08 00:31:51.184418001 -0600
  21876. @@ -12,6 +12,7 @@
  21877. */
  21878. #define pr_fmt(fmt) "hw perfevents: " fmt
  21879. +#include <linux/cpumask.h>
  21880. #include <linux/kernel.h>
  21881. #include <linux/platform_device.h>
  21882. #include <linux/pm_runtime.h>
  21883. @@ -86,6 +87,9 @@
  21884. return armpmu_map_cache_event(cache_map, config);
  21885. case PERF_TYPE_RAW:
  21886. return armpmu_map_raw_event(raw_event_mask, config);
  21887. + default:
  21888. + if (event->attr.type >= PERF_TYPE_MAX)
  21889. + return armpmu_map_raw_event(raw_event_mask, config);
  21890. }
  21891. return -ENOENT;
  21892. @@ -159,6 +163,8 @@
  21893. struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
  21894. struct hw_perf_event *hwc = &event->hw;
  21895. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21896. + return;
  21897. /*
  21898. * ARM pmu always has to update the counter, so ignore
  21899. * PERF_EF_UPDATE, see comments in armpmu_start().
  21900. @@ -175,6 +181,8 @@
  21901. struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
  21902. struct hw_perf_event *hwc = &event->hw;
  21903. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21904. + return;
  21905. /*
  21906. * ARM pmu always has to reprogram the period, so ignore
  21907. * PERF_EF_RELOAD, see the comment below.
  21908. @@ -202,6 +210,9 @@
  21909. struct hw_perf_event *hwc = &event->hw;
  21910. int idx = hwc->idx;
  21911. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21912. + return;
  21913. +
  21914. armpmu_stop(event, PERF_EF_UPDATE);
  21915. hw_events->events[idx] = NULL;
  21916. clear_bit(idx, hw_events->used_mask);
  21917. @@ -218,6 +229,10 @@
  21918. int idx;
  21919. int err = 0;
  21920. + /* An event following a process won't be stopped earlier */
  21921. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21922. + return 0;
  21923. +
  21924. perf_pmu_disable(event->pmu);
  21925. /* If we don't have a space for the counter then finish early. */
  21926. @@ -419,6 +434,10 @@
  21927. int err = 0;
  21928. atomic_t *active_events = &armpmu->active_events;
  21929. + if (event->cpu != -1 &&
  21930. + !cpumask_test_cpu(event->cpu, &armpmu->valid_cpus))
  21931. + return -ENOENT;
  21932. +
  21933. /* does not support taken branch sampling */
  21934. if (has_branch_stack(event))
  21935. return -EOPNOTSUPP;
  21936. diff -Nur linux-3.14.14/arch/arm/kernel/perf_event_cpu.c linux-imx6-3.14/arch/arm/kernel/perf_event_cpu.c
  21937. --- linux-3.14.14/arch/arm/kernel/perf_event_cpu.c 2014-07-28 10:07:25.000000000 -0500
  21938. +++ linux-imx6-3.14/arch/arm/kernel/perf_event_cpu.c 2014-12-08 00:31:51.188418001 -0600
  21939. @@ -19,6 +19,7 @@
  21940. #define pr_fmt(fmt) "CPU PMU: " fmt
  21941. #include <linux/bitmap.h>
  21942. +#include <linux/cpu_pm.h>
  21943. #include <linux/export.h>
  21944. #include <linux/kernel.h>
  21945. #include <linux/of.h>
  21946. @@ -31,33 +32,36 @@
  21947. #include <asm/pmu.h>
  21948. /* Set at runtime when we know what CPU type we are. */
  21949. -static struct arm_pmu *cpu_pmu;
  21950. +static DEFINE_PER_CPU(struct arm_pmu *, cpu_pmu);
  21951. static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
  21952. static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
  21953. static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
  21954. +static DEFINE_PER_CPU(struct cpupmu_regs, cpu_pmu_regs);
  21955. +
  21956. /*
  21957. * Despite the names, these two functions are CPU-specific and are used
  21958. * by the OProfile/perf code.
  21959. */
  21960. const char *perf_pmu_name(void)
  21961. {
  21962. - if (!cpu_pmu)
  21963. + struct arm_pmu *pmu = per_cpu(cpu_pmu, 0);
  21964. + if (!pmu)
  21965. return NULL;
  21966. - return cpu_pmu->name;
  21967. + return pmu->name;
  21968. }
  21969. EXPORT_SYMBOL_GPL(perf_pmu_name);
  21970. int perf_num_counters(void)
  21971. {
  21972. - int max_events = 0;
  21973. + struct arm_pmu *pmu = per_cpu(cpu_pmu, 0);
  21974. - if (cpu_pmu != NULL)
  21975. - max_events = cpu_pmu->num_events;
  21976. + if (!pmu)
  21977. + return 0;
  21978. - return max_events;
  21979. + return pmu->num_events;
  21980. }
  21981. EXPORT_SYMBOL_GPL(perf_num_counters);
  21982. @@ -75,11 +79,13 @@
  21983. {
  21984. int i, irq, irqs;
  21985. struct platform_device *pmu_device = cpu_pmu->plat_device;
  21986. + int cpu = -1;
  21987. irqs = min(pmu_device->num_resources, num_possible_cpus());
  21988. for (i = 0; i < irqs; ++i) {
  21989. - if (!cpumask_test_and_clear_cpu(i, &cpu_pmu->active_irqs))
  21990. + cpu = cpumask_next(cpu, &cpu_pmu->valid_cpus);
  21991. + if (!cpumask_test_and_clear_cpu(cpu, &cpu_pmu->active_irqs))
  21992. continue;
  21993. irq = platform_get_irq(pmu_device, i);
  21994. if (irq >= 0)
  21995. @@ -91,6 +97,7 @@
  21996. {
  21997. int i, err, irq, irqs;
  21998. struct platform_device *pmu_device = cpu_pmu->plat_device;
  21999. + int cpu = -1;
  22000. if (!pmu_device)
  22001. return -ENODEV;
  22002. @@ -103,6 +110,7 @@
  22003. for (i = 0; i < irqs; ++i) {
  22004. err = 0;
  22005. + cpu = cpumask_next(cpu, &cpu_pmu->valid_cpus);
  22006. irq = platform_get_irq(pmu_device, i);
  22007. if (irq < 0)
  22008. continue;
  22009. @@ -112,7 +120,7 @@
  22010. * assume that we're running on a uniprocessor machine and
  22011. * continue. Otherwise, continue without this interrupt.
  22012. */
  22013. - if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
  22014. + if (irq_set_affinity(irq, cpumask_of(cpu)) && irqs > 1) {
  22015. pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
  22016. irq, i);
  22017. continue;
  22018. @@ -127,7 +135,7 @@
  22019. return err;
  22020. }
  22021. - cpumask_set_cpu(i, &cpu_pmu->active_irqs);
  22022. + cpumask_set_cpu(cpu, &cpu_pmu->active_irqs);
  22023. }
  22024. return 0;
  22025. @@ -136,7 +144,7 @@
  22026. static void cpu_pmu_init(struct arm_pmu *cpu_pmu)
  22027. {
  22028. int cpu;
  22029. - for_each_possible_cpu(cpu) {
  22030. + for_each_cpu_mask(cpu, cpu_pmu->valid_cpus) {
  22031. struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu);
  22032. events->events = per_cpu(hw_events, cpu);
  22033. events->used_mask = per_cpu(used_mask, cpu);
  22034. @@ -149,7 +157,7 @@
  22035. /* Ensure the PMU has sane values out of reset. */
  22036. if (cpu_pmu->reset)
  22037. - on_each_cpu(cpu_pmu->reset, cpu_pmu, 1);
  22038. + on_each_cpu_mask(&cpu_pmu->valid_cpus, cpu_pmu->reset, cpu_pmu, 1);
  22039. }
  22040. /*
  22041. @@ -161,21 +169,46 @@
  22042. static int cpu_pmu_notify(struct notifier_block *b, unsigned long action,
  22043. void *hcpu)
  22044. {
  22045. + struct arm_pmu *pmu = per_cpu(cpu_pmu, (long)hcpu);
  22046. +
  22047. if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
  22048. return NOTIFY_DONE;
  22049. - if (cpu_pmu && cpu_pmu->reset)
  22050. - cpu_pmu->reset(cpu_pmu);
  22051. + if (pmu && pmu->reset)
  22052. + pmu->reset(pmu);
  22053. else
  22054. return NOTIFY_DONE;
  22055. return NOTIFY_OK;
  22056. }
  22057. +static int cpu_pmu_pm_notify(struct notifier_block *b,
  22058. + unsigned long action, void *hcpu)
  22059. +{
  22060. + int cpu = smp_processor_id();
  22061. + struct arm_pmu *pmu = per_cpu(cpu_pmu, cpu);
  22062. + struct cpupmu_regs *pmuregs = &per_cpu(cpu_pmu_regs, cpu);
  22063. +
  22064. + if (!pmu)
  22065. + return NOTIFY_DONE;
  22066. +
  22067. + if (action == CPU_PM_ENTER && pmu->save_regs) {
  22068. + pmu->save_regs(pmu, pmuregs);
  22069. + } else if (action == CPU_PM_EXIT && pmu->restore_regs) {
  22070. + pmu->restore_regs(pmu, pmuregs);
  22071. + }
  22072. +
  22073. + return NOTIFY_OK;
  22074. +}
  22075. +
  22076. static struct notifier_block cpu_pmu_hotplug_notifier = {
  22077. .notifier_call = cpu_pmu_notify,
  22078. };
  22079. +static struct notifier_block cpu_pmu_pm_notifier = {
  22080. + .notifier_call = cpu_pmu_pm_notify,
  22081. +};
  22082. +
  22083. /*
  22084. * PMU platform driver and devicetree bindings.
  22085. */
  22086. @@ -247,6 +280,9 @@
  22087. }
  22088. }
  22089. + /* assume PMU support all the CPUs in this case */
  22090. + cpumask_setall(&pmu->valid_cpus);
  22091. +
  22092. put_cpu();
  22093. return ret;
  22094. }
  22095. @@ -254,15 +290,10 @@
  22096. static int cpu_pmu_device_probe(struct platform_device *pdev)
  22097. {
  22098. const struct of_device_id *of_id;
  22099. - const int (*init_fn)(struct arm_pmu *);
  22100. struct device_node *node = pdev->dev.of_node;
  22101. struct arm_pmu *pmu;
  22102. - int ret = -ENODEV;
  22103. -
  22104. - if (cpu_pmu) {
  22105. - pr_info("attempt to register multiple PMU devices!");
  22106. - return -ENOSPC;
  22107. - }
  22108. + int ret = 0;
  22109. + int cpu;
  22110. pmu = kzalloc(sizeof(struct arm_pmu), GFP_KERNEL);
  22111. if (!pmu) {
  22112. @@ -271,8 +302,28 @@
  22113. }
  22114. if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) {
  22115. - init_fn = of_id->data;
  22116. - ret = init_fn(pmu);
  22117. + smp_call_func_t init_fn = (smp_call_func_t)of_id->data;
  22118. + struct device_node *ncluster;
  22119. + int cluster = -1;
  22120. + cpumask_t sibling_mask;
  22121. +
  22122. + ncluster = of_parse_phandle(node, "cluster", 0);
  22123. + if (ncluster) {
  22124. + int len;
  22125. + const u32 *hwid;
  22126. + hwid = of_get_property(ncluster, "reg", &len);
  22127. + if (hwid && len == 4)
  22128. + cluster = be32_to_cpup(hwid);
  22129. + }
  22130. + /* set sibling mask to all cpu mask if socket is not specified */
  22131. + if (cluster == -1 ||
  22132. + cluster_to_logical_mask(cluster, &sibling_mask))
  22133. + cpumask_setall(&sibling_mask);
  22134. +
  22135. + smp_call_function_any(&sibling_mask, init_fn, pmu, 1);
  22136. +
  22137. + /* now set the valid_cpus after init */
  22138. + cpumask_copy(&pmu->valid_cpus, &sibling_mask);
  22139. } else {
  22140. ret = probe_current_pmu(pmu);
  22141. }
  22142. @@ -282,10 +333,12 @@
  22143. goto out_free;
  22144. }
  22145. - cpu_pmu = pmu;
  22146. - cpu_pmu->plat_device = pdev;
  22147. - cpu_pmu_init(cpu_pmu);
  22148. - ret = armpmu_register(cpu_pmu, PERF_TYPE_RAW);
  22149. + for_each_cpu_mask(cpu, pmu->valid_cpus)
  22150. + per_cpu(cpu_pmu, cpu) = pmu;
  22151. +
  22152. + pmu->plat_device = pdev;
  22153. + cpu_pmu_init(pmu);
  22154. + ret = armpmu_register(pmu, -1);
  22155. if (!ret)
  22156. return 0;
  22157. @@ -314,9 +367,17 @@
  22158. if (err)
  22159. return err;
  22160. + err = cpu_pm_register_notifier(&cpu_pmu_pm_notifier);
  22161. + if (err) {
  22162. + unregister_cpu_notifier(&cpu_pmu_hotplug_notifier);
  22163. + return err;
  22164. + }
  22165. +
  22166. err = platform_driver_register(&cpu_pmu_driver);
  22167. - if (err)
  22168. + if (err) {
  22169. + cpu_pm_unregister_notifier(&cpu_pmu_pm_notifier);
  22170. unregister_cpu_notifier(&cpu_pmu_hotplug_notifier);
  22171. + }
  22172. return err;
  22173. }
  22174. diff -Nur linux-3.14.14/arch/arm/kernel/perf_event_v7.c linux-imx6-3.14/arch/arm/kernel/perf_event_v7.c
  22175. --- linux-3.14.14/arch/arm/kernel/perf_event_v7.c 2014-07-28 10:07:25.000000000 -0500
  22176. +++ linux-imx6-3.14/arch/arm/kernel/perf_event_v7.c 2014-12-08 00:31:51.188418001 -0600
  22177. @@ -950,6 +950,51 @@
  22178. }
  22179. #endif
  22180. +static void armv7pmu_save_regs(struct arm_pmu *cpu_pmu,
  22181. + struct cpupmu_regs *regs)
  22182. +{
  22183. + unsigned int cnt;
  22184. + asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (regs->pmc));
  22185. + if (!(regs->pmc & ARMV7_PMNC_E))
  22186. + return;
  22187. +
  22188. + asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (regs->pmcntenset));
  22189. + asm volatile("mrc p15, 0, %0, c9, c14, 0" : "=r" (regs->pmuseren));
  22190. + asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (regs->pmintenset));
  22191. + asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (regs->pmxevtcnt[0]));
  22192. + for (cnt = ARMV7_IDX_COUNTER0;
  22193. + cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
  22194. + armv7_pmnc_select_counter(cnt);
  22195. + asm volatile("mrc p15, 0, %0, c9, c13, 1"
  22196. + : "=r"(regs->pmxevttype[cnt]));
  22197. + asm volatile("mrc p15, 0, %0, c9, c13, 2"
  22198. + : "=r"(regs->pmxevtcnt[cnt]));
  22199. + }
  22200. + return;
  22201. +}
  22202. +
  22203. +static void armv7pmu_restore_regs(struct arm_pmu *cpu_pmu,
  22204. + struct cpupmu_regs *regs)
  22205. +{
  22206. + unsigned int cnt;
  22207. + if (!(regs->pmc & ARMV7_PMNC_E))
  22208. + return;
  22209. +
  22210. + asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (regs->pmcntenset));
  22211. + asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r" (regs->pmuseren));
  22212. + asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (regs->pmintenset));
  22213. + asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (regs->pmxevtcnt[0]));
  22214. + for (cnt = ARMV7_IDX_COUNTER0;
  22215. + cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
  22216. + armv7_pmnc_select_counter(cnt);
  22217. + asm volatile("mcr p15, 0, %0, c9, c13, 1"
  22218. + : : "r"(regs->pmxevttype[cnt]));
  22219. + asm volatile("mcr p15, 0, %0, c9, c13, 2"
  22220. + : : "r"(regs->pmxevtcnt[cnt]));
  22221. + }
  22222. + asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (regs->pmc));
  22223. +}
  22224. +
  22225. static void armv7pmu_enable_event(struct perf_event *event)
  22226. {
  22227. unsigned long flags;
  22228. @@ -1223,6 +1268,8 @@
  22229. cpu_pmu->start = armv7pmu_start;
  22230. cpu_pmu->stop = armv7pmu_stop;
  22231. cpu_pmu->reset = armv7pmu_reset;
  22232. + cpu_pmu->save_regs = armv7pmu_save_regs;
  22233. + cpu_pmu->restore_regs = armv7pmu_restore_regs;
  22234. cpu_pmu->max_period = (1LLU << 32) - 1;
  22235. };
  22236. @@ -1240,7 +1287,7 @@
  22237. static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
  22238. {
  22239. armv7pmu_init(cpu_pmu);
  22240. - cpu_pmu->name = "ARMv7 Cortex-A8";
  22241. + cpu_pmu->name = "ARMv7_Cortex_A8";
  22242. cpu_pmu->map_event = armv7_a8_map_event;
  22243. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22244. return 0;
  22245. @@ -1249,7 +1296,7 @@
  22246. static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
  22247. {
  22248. armv7pmu_init(cpu_pmu);
  22249. - cpu_pmu->name = "ARMv7 Cortex-A9";
  22250. + cpu_pmu->name = "ARMv7_Cortex_A9";
  22251. cpu_pmu->map_event = armv7_a9_map_event;
  22252. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22253. return 0;
  22254. @@ -1258,7 +1305,7 @@
  22255. static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
  22256. {
  22257. armv7pmu_init(cpu_pmu);
  22258. - cpu_pmu->name = "ARMv7 Cortex-A5";
  22259. + cpu_pmu->name = "ARMv7_Cortex_A5";
  22260. cpu_pmu->map_event = armv7_a5_map_event;
  22261. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22262. return 0;
  22263. @@ -1267,7 +1314,7 @@
  22264. static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
  22265. {
  22266. armv7pmu_init(cpu_pmu);
  22267. - cpu_pmu->name = "ARMv7 Cortex-A15";
  22268. + cpu_pmu->name = "ARMv7_Cortex_A15";
  22269. cpu_pmu->map_event = armv7_a15_map_event;
  22270. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22271. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  22272. @@ -1277,7 +1324,7 @@
  22273. static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
  22274. {
  22275. armv7pmu_init(cpu_pmu);
  22276. - cpu_pmu->name = "ARMv7 Cortex-A7";
  22277. + cpu_pmu->name = "ARMv7_Cortex_A7";
  22278. cpu_pmu->map_event = armv7_a7_map_event;
  22279. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22280. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  22281. diff -Nur linux-3.14.14/arch/arm/kernel/process.c linux-imx6-3.14/arch/arm/kernel/process.c
  22282. --- linux-3.14.14/arch/arm/kernel/process.c 2014-07-28 10:07:25.000000000 -0500
  22283. +++ linux-imx6-3.14/arch/arm/kernel/process.c 2014-12-08 00:31:51.188418001 -0600
  22284. @@ -172,8 +172,10 @@
  22285. */
  22286. void arch_cpu_idle(void)
  22287. {
  22288. + idle_notifier_call_chain(IDLE_START);
  22289. if (cpuidle_idle_call())
  22290. default_idle();
  22291. + idle_notifier_call_chain(IDLE_END);
  22292. }
  22293. /*
  22294. diff -Nur linux-3.14.14/arch/arm/kernel/psci.c linux-imx6-3.14/arch/arm/kernel/psci.c
  22295. --- linux-3.14.14/arch/arm/kernel/psci.c 2014-07-28 10:07:25.000000000 -0500
  22296. +++ linux-imx6-3.14/arch/arm/kernel/psci.c 2014-12-08 00:31:51.188418001 -0600
  22297. @@ -42,6 +42,7 @@
  22298. #define PSCI_RET_EOPNOTSUPP -1
  22299. #define PSCI_RET_EINVAL -2
  22300. #define PSCI_RET_EPERM -3
  22301. +#define PSCI_RET_EALREADYON -4
  22302. static int psci_to_linux_errno(int errno)
  22303. {
  22304. @@ -54,6 +55,8 @@
  22305. return -EINVAL;
  22306. case PSCI_RET_EPERM:
  22307. return -EPERM;
  22308. + case PSCI_RET_EALREADYON:
  22309. + return -EAGAIN;
  22310. };
  22311. return -EINVAL;
  22312. @@ -153,7 +156,7 @@
  22313. return psci_to_linux_errno(err);
  22314. }
  22315. -static const struct of_device_id psci_of_match[] __initconst = {
  22316. +static const struct of_device_id psci_of_match[] = {
  22317. { .compatible = "arm,psci", },
  22318. {},
  22319. };
  22320. @@ -208,3 +211,16 @@
  22321. of_node_put(np);
  22322. return;
  22323. }
  22324. +
  22325. +int psci_probe(void)
  22326. +{
  22327. + struct device_node *np;
  22328. + int ret = -ENODEV;
  22329. +
  22330. + np = of_find_matching_node(NULL, psci_of_match);
  22331. + if (np)
  22332. + ret = 0;
  22333. +
  22334. + of_node_put(np);
  22335. + return ret;
  22336. +}
  22337. diff -Nur linux-3.14.14/arch/arm/kernel/setup.c linux-imx6-3.14/arch/arm/kernel/setup.c
  22338. --- linux-3.14.14/arch/arm/kernel/setup.c 2014-07-28 10:07:25.000000000 -0500
  22339. +++ linux-imx6-3.14/arch/arm/kernel/setup.c 2014-12-08 00:31:51.188418001 -0600
  22340. @@ -273,6 +273,19 @@
  22341. int aliasing_icache;
  22342. unsigned int id_reg, num_sets, line_size;
  22343. +#ifdef CONFIG_BIG_LITTLE
  22344. + /*
  22345. + * We expect a combination of Cortex-A15 and Cortex-A7 cores.
  22346. + * A7 = VIPT aliasing I-cache
  22347. + * A15 = PIPT (non-aliasing) I-cache
  22348. + * To cater for this discrepancy, let's assume aliasing I-cache
  22349. + * all the time. This means unneeded extra work on the A15 but
  22350. + * only ptrace is affected which is not performance critical.
  22351. + */
  22352. + if ((read_cpuid_id() & 0xff0ffff0) == 0x410fc0f0)
  22353. + return 1;
  22354. +#endif
  22355. +
  22356. /* PIPT caches never alias. */
  22357. if (icache_is_pipt())
  22358. return 0;
  22359. diff -Nur linux-3.14.14/arch/arm/kernel/topology.c linux-imx6-3.14/arch/arm/kernel/topology.c
  22360. --- linux-3.14.14/arch/arm/kernel/topology.c 2014-07-28 10:07:25.000000000 -0500
  22361. +++ linux-imx6-3.14/arch/arm/kernel/topology.c 2014-12-08 00:31:51.188418001 -0600
  22362. @@ -267,6 +267,33 @@
  22363. }
  22364. /*
  22365. + * cluster_to_logical_mask - return cpu logical mask of CPUs in a cluster
  22366. + * @socket_id: cluster HW identifier
  22367. + * @cluster_mask: the cpumask location to be initialized, modified by the
  22368. + * function only if return value == 0
  22369. + *
  22370. + * Return:
  22371. + *
  22372. + * 0 on success
  22373. + * -EINVAL if cluster_mask is NULL or there is no record matching socket_id
  22374. + */
  22375. +int cluster_to_logical_mask(unsigned int socket_id, cpumask_t *cluster_mask)
  22376. +{
  22377. + int cpu;
  22378. +
  22379. + if (!cluster_mask)
  22380. + return -EINVAL;
  22381. +
  22382. + for_each_online_cpu(cpu)
  22383. + if (socket_id == topology_physical_package_id(cpu)) {
  22384. + cpumask_copy(cluster_mask, topology_core_cpumask(cpu));
  22385. + return 0;
  22386. + }
  22387. +
  22388. + return -EINVAL;
  22389. +}
  22390. +
  22391. +/*
  22392. * init_cpu_topology is called at boot when only one cpu is running
  22393. * which prevent simultaneous write access to cpu_topology array
  22394. */
  22395. diff -Nur linux-3.14.14/arch/arm/lib/bitops.h linux-imx6-3.14/arch/arm/lib/bitops.h
  22396. --- linux-3.14.14/arch/arm/lib/bitops.h 2014-07-28 10:07:25.000000000 -0500
  22397. +++ linux-imx6-3.14/arch/arm/lib/bitops.h 2014-12-08 00:31:51.192418001 -0600
  22398. @@ -37,6 +37,11 @@
  22399. add r1, r1, r0, lsl #2 @ Get word offset
  22400. mov r3, r2, lsl r3 @ create mask
  22401. smp_dmb
  22402. +#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
  22403. + .arch_extension mp
  22404. + ALT_SMP(W(pldw) [r1])
  22405. + ALT_UP(W(nop))
  22406. +#endif
  22407. 1: ldrex r2, [r1]
  22408. ands r0, r2, r3 @ save old value of bit
  22409. \instr r2, r2, r3 @ toggle bit
  22410. diff -Nur linux-3.14.14/arch/arm/mach-berlin/berlin.c linux-imx6-3.14/arch/arm/mach-berlin/berlin.c
  22411. --- linux-3.14.14/arch/arm/mach-berlin/berlin.c 2014-07-28 10:07:25.000000000 -0500
  22412. +++ linux-imx6-3.14/arch/arm/mach-berlin/berlin.c 2014-12-08 00:31:51.204418001 -0600
  22413. @@ -24,7 +24,7 @@
  22414. * with DT probing for L2CCs, berlin_init_machine can be removed.
  22415. * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
  22416. */
  22417. - l2x0_of_init(0x70c00000, 0xfeffffff);
  22418. + l2x0_of_init(0x30c00000, 0xfeffffff);
  22419. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  22420. }
  22421. diff -Nur linux-3.14.14/arch/arm/mach-cns3xxx/core.c linux-imx6-3.14/arch/arm/mach-cns3xxx/core.c
  22422. --- linux-3.14.14/arch/arm/mach-cns3xxx/core.c 2014-07-28 10:07:25.000000000 -0500
  22423. +++ linux-imx6-3.14/arch/arm/mach-cns3xxx/core.c 2014-12-08 00:31:51.204418001 -0600
  22424. @@ -240,9 +240,9 @@
  22425. *
  22426. * 1 cycle of latency for setup, read and write accesses
  22427. */
  22428. - val = readl(base + L2X0_TAG_LATENCY_CTRL);
  22429. + val = readl(base + L310_TAG_LATENCY_CTRL);
  22430. val &= 0xfffff888;
  22431. - writel(val, base + L2X0_TAG_LATENCY_CTRL);
  22432. + writel(val, base + L310_TAG_LATENCY_CTRL);
  22433. /*
  22434. * Data RAM Control register
  22435. @@ -253,12 +253,12 @@
  22436. *
  22437. * 1 cycle of latency for setup, read and write accesses
  22438. */
  22439. - val = readl(base + L2X0_DATA_LATENCY_CTRL);
  22440. + val = readl(base + L310_DATA_LATENCY_CTRL);
  22441. val &= 0xfffff888;
  22442. - writel(val, base + L2X0_DATA_LATENCY_CTRL);
  22443. + writel(val, base + L310_DATA_LATENCY_CTRL);
  22444. /* 32 KiB, 8-way, parity disable */
  22445. - l2x0_init(base, 0x00540000, 0xfe000fff);
  22446. + l2x0_init(base, 0x00500000, 0xfe0f0fff);
  22447. }
  22448. #endif /* CONFIG_CACHE_L2X0 */
  22449. diff -Nur linux-3.14.14/arch/arm/mach-exynos/common.c linux-imx6-3.14/arch/arm/mach-exynos/common.c
  22450. --- linux-3.14.14/arch/arm/mach-exynos/common.c 2014-07-28 10:07:25.000000000 -0500
  22451. +++ linux-imx6-3.14/arch/arm/mach-exynos/common.c 2014-12-08 00:31:51.212418001 -0600
  22452. @@ -45,9 +45,6 @@
  22453. #include "common.h"
  22454. #include "regs-pmu.h"
  22455. -#define L2_AUX_VAL 0x7C470001
  22456. -#define L2_AUX_MASK 0xC200ffff
  22457. -
  22458. static const char name_exynos4210[] = "EXYNOS4210";
  22459. static const char name_exynos4212[] = "EXYNOS4212";
  22460. static const char name_exynos4412[] = "EXYNOS4412";
  22461. @@ -400,7 +397,7 @@
  22462. {
  22463. int ret;
  22464. - ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
  22465. + ret = l2x0_of_init(0x3c400001, 0xc20fffff);
  22466. if (ret)
  22467. return ret;
  22468. diff -Nur linux-3.14.14/arch/arm/mach-highbank/highbank.c linux-imx6-3.14/arch/arm/mach-highbank/highbank.c
  22469. --- linux-3.14.14/arch/arm/mach-highbank/highbank.c 2014-07-28 10:07:25.000000000 -0500
  22470. +++ linux-imx6-3.14/arch/arm/mach-highbank/highbank.c 2014-12-08 00:31:51.216418001 -0600
  22471. @@ -20,7 +20,7 @@
  22472. #include <linux/input.h>
  22473. #include <linux/io.h>
  22474. #include <linux/irqchip.h>
  22475. -#include <linux/mailbox.h>
  22476. +#include <linux/pl320-ipc.h>
  22477. #include <linux/of.h>
  22478. #include <linux/of_irq.h>
  22479. #include <linux/of_platform.h>
  22480. @@ -51,11 +51,13 @@
  22481. }
  22482. -static void highbank_l2x0_disable(void)
  22483. +static void highbank_l2c310_write_sec(unsigned long val, unsigned reg)
  22484. {
  22485. - outer_flush_all();
  22486. - /* Disable PL310 L2 Cache controller */
  22487. - highbank_smc1(0x102, 0x0);
  22488. + if (reg == L2X0_CTRL)
  22489. + highbank_smc1(0x102, val);
  22490. + else
  22491. + WARN_ONCE(1, "Highbank L2C310: ignoring write to reg 0x%x\n",
  22492. + reg);
  22493. }
  22494. static void __init highbank_init_irq(void)
  22495. @@ -66,11 +68,9 @@
  22496. highbank_scu_map_io();
  22497. /* Enable PL310 L2 Cache controller */
  22498. - if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
  22499. - of_find_compatible_node(NULL, NULL, "arm,pl310-cache")) {
  22500. - highbank_smc1(0x102, 0x1);
  22501. - l2x0_of_init(0, ~0UL);
  22502. - outer_cache.disable = highbank_l2x0_disable;
  22503. + if (IS_ENABLED(CONFIG_CACHE_L2X0)) {
  22504. + outer_cache.write_sec = highbank_l2c310_write_sec;
  22505. + l2x0_of_init(0, ~0);
  22506. }
  22507. }
  22508. diff -Nur linux-3.14.14/arch/arm/mach-imx/anatop.c linux-imx6-3.14/arch/arm/mach-imx/anatop.c
  22509. --- linux-3.14.14/arch/arm/mach-imx/anatop.c 2014-07-28 10:07:25.000000000 -0500
  22510. +++ linux-imx6-3.14/arch/arm/mach-imx/anatop.c 2014-12-08 00:31:51.220418001 -0600
  22511. @@ -9,6 +9,7 @@
  22512. * http://www.gnu.org/copyleft/gpl.html
  22513. */
  22514. +#include <linux/delay.h>
  22515. #include <linux/err.h>
  22516. #include <linux/io.h>
  22517. #include <linux/of.h>
  22518. @@ -35,6 +36,10 @@
  22519. #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000
  22520. #define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000
  22521. +#define ANADIG_REG_TARG_MASK 0x1f
  22522. +#define ANADIG_REG1_TARG_SHIFT 9 /* VDDPU */
  22523. +#define ANADIG_REG2_TARG_SHIFT 18 /* VDDSOC */
  22524. +
  22525. static struct regmap *anatop;
  22526. static void imx_anatop_enable_weak2p5(bool enable)
  22527. @@ -78,6 +83,28 @@
  22528. BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
  22529. }
  22530. +void imx_anatop_pu_enable(bool enable)
  22531. +{
  22532. + u32 val;
  22533. +
  22534. + regmap_read(anatop, ANADIG_REG_CORE, &val);
  22535. + val &= ANADIG_REG_TARG_MASK << ANADIG_REG2_TARG_SHIFT;
  22536. + /*
  22537. + * set pu regulator only in LDO_BYPASS mode(know by VDDSOC reg 0x1f),
  22538. + * else handled by anatop regulator driver.
  22539. + */
  22540. + if (((val >> (ANADIG_REG2_TARG_SHIFT)) & ANADIG_REG_TARG_MASK)
  22541. + == ANADIG_REG_TARG_MASK) {
  22542. + if (enable) {
  22543. + regmap_write(anatop, ANADIG_REG_CORE + REG_SET,
  22544. + ANADIG_REG_TARG_MASK << ANADIG_REG1_TARG_SHIFT);
  22545. + udelay(70); /* bypass need 70us to be stable */
  22546. + } else {
  22547. + regmap_write(anatop, ANADIG_REG_CORE + REG_CLR,
  22548. + ANADIG_REG_TARG_MASK << ANADIG_REG1_TARG_SHIFT);
  22549. + }
  22550. + }
  22551. +}
  22552. void __init imx_init_revision_from_anatop(void)
  22553. {
  22554. struct device_node *np;
  22555. @@ -104,6 +131,15 @@
  22556. case 2:
  22557. revision = IMX_CHIP_REVISION_1_2;
  22558. break;
  22559. + case 3:
  22560. + revision = IMX_CHIP_REVISION_1_3;
  22561. + break;
  22562. + case 4:
  22563. + revision = IMX_CHIP_REVISION_1_4;
  22564. + break;
  22565. + case 5:
  22566. + revision = IMX_CHIP_REVISION_1_5;
  22567. + break;
  22568. default:
  22569. revision = IMX_CHIP_REVISION_UNKNOWN;
  22570. }
  22571. diff -Nur linux-3.14.14/arch/arm/mach-imx/busfreq_ddr3.c linux-imx6-3.14/arch/arm/mach-imx/busfreq_ddr3.c
  22572. --- linux-3.14.14/arch/arm/mach-imx/busfreq_ddr3.c 1969-12-31 18:00:00.000000000 -0600
  22573. +++ linux-imx6-3.14/arch/arm/mach-imx/busfreq_ddr3.c 2014-12-08 00:31:51.220418001 -0600
  22574. @@ -0,0 +1,471 @@
  22575. +/*
  22576. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  22577. + */
  22578. +
  22579. +/*
  22580. + * The code contained herein is licensed under the GNU General Public
  22581. + * License. You may obtain a copy of the GNU General Public License
  22582. + * Version 2 or later at the following locations:
  22583. + *
  22584. + * http://www.opensource.org/licenses/gpl-license.html
  22585. + * http://www.gnu.org/copyleft/gpl.html
  22586. + */
  22587. +
  22588. +/*!
  22589. + * @file busfreq_ddr3.c
  22590. + *
  22591. + * @brief iMX6 DDR3 frequency change specific file.
  22592. + *
  22593. + * @ingroup PM
  22594. + */
  22595. +#include <asm/cacheflush.h>
  22596. +#include <asm/fncpy.h>
  22597. +#include <asm/io.h>
  22598. +#include <asm/mach/map.h>
  22599. +#include <asm/mach-types.h>
  22600. +#include <asm/tlb.h>
  22601. +#include <linux/clk.h>
  22602. +#include <linux/cpumask.h>
  22603. +#include <linux/delay.h>
  22604. +#include <linux/genalloc.h>
  22605. +#include <linux/interrupt.h>
  22606. +#include <linux/irqchip/arm-gic.h>
  22607. +#include <linux/kernel.h>
  22608. +#include <linux/mutex.h>
  22609. +#include <linux/of.h>
  22610. +#include <linux/of_address.h>
  22611. +#include <linux/of_device.h>
  22612. +#include <linux/platform_device.h>
  22613. +#include <linux/proc_fs.h>
  22614. +#include <linux/sched.h>
  22615. +#include <linux/smp.h>
  22616. +
  22617. +#include "hardware.h"
  22618. +
  22619. +/* DDR settings */
  22620. +static unsigned long (*iram_ddr_settings)[2];
  22621. +static unsigned long (*normal_mmdc_settings)[2];
  22622. +static unsigned long (*iram_iomux_settings)[2];
  22623. +static void __iomem *mmdc_base;
  22624. +static void __iomem *iomux_base;
  22625. +static void __iomem *ccm_base;
  22626. +static void __iomem *l2_base;
  22627. +static void __iomem *gic_dist_base;
  22628. +static u32 *irqs_used;
  22629. +
  22630. +static void *ddr_freq_change_iram_base;
  22631. +static int ddr_settings_size;
  22632. +static int iomux_settings_size;
  22633. +static volatile unsigned int cpus_in_wfe;
  22634. +static volatile bool wait_for_ddr_freq_update;
  22635. +static int curr_ddr_rate;
  22636. +
  22637. +void (*mx6_change_ddr_freq)(u32 freq, void *ddr_settings,
  22638. + bool dll_mode, void *iomux_offsets) = NULL;
  22639. +
  22640. +extern unsigned int ddr_med_rate;
  22641. +extern unsigned int ddr_normal_rate;
  22642. +extern int low_bus_freq_mode;
  22643. +extern int audio_bus_freq_mode;
  22644. +extern void mx6_ddr3_freq_change(u32 freq, void *ddr_settings,
  22645. + bool dll_mode, void *iomux_offsets);
  22646. +
  22647. +#define MIN_DLL_ON_FREQ 333000000
  22648. +#define MAX_DLL_OFF_FREQ 125000000
  22649. +#define DDR_FREQ_CHANGE_SIZE 0x2000
  22650. +
  22651. +unsigned long ddr3_dll_mx6q[][2] = {
  22652. + {0x0c, 0x0},
  22653. + {0x10, 0x0},
  22654. + {0x1C, 0x04088032},
  22655. + {0x1C, 0x0408803a},
  22656. + {0x1C, 0x08408030},
  22657. + {0x1C, 0x08408038},
  22658. + {0x818, 0x0},
  22659. +};
  22660. +
  22661. +unsigned long ddr3_calibration[][2] = {
  22662. + {0x83c, 0x0},
  22663. + {0x840, 0x0},
  22664. + {0x483c, 0x0},
  22665. + {0x4840, 0x0},
  22666. + {0x848, 0x0},
  22667. + {0x4848, 0x0},
  22668. + {0x850, 0x0},
  22669. + {0x4850, 0x0},
  22670. +};
  22671. +
  22672. +unsigned long ddr3_dll_mx6dl[][2] = {
  22673. + {0x0c, 0x0},
  22674. + {0x10, 0x0},
  22675. + {0x1C, 0x04008032},
  22676. + {0x1C, 0x0400803a},
  22677. + {0x1C, 0x07208030},
  22678. + {0x1C, 0x07208038},
  22679. + {0x818, 0x0},
  22680. +};
  22681. +
  22682. +unsigned long iomux_offsets_mx6q[][2] = {
  22683. + {0x5A8, 0x0},
  22684. + {0x5B0, 0x0},
  22685. + {0x524, 0x0},
  22686. + {0x51C, 0x0},
  22687. + {0x518, 0x0},
  22688. + {0x50C, 0x0},
  22689. + {0x5B8, 0x0},
  22690. + {0x5C0, 0x0},
  22691. +};
  22692. +
  22693. +unsigned long iomux_offsets_mx6dl[][2] = {
  22694. + {0x4BC, 0x0},
  22695. + {0x4C0, 0x0},
  22696. + {0x4C4, 0x0},
  22697. + {0x4C8, 0x0},
  22698. + {0x4CC, 0x0},
  22699. + {0x4D0, 0x0},
  22700. + {0x4D4, 0x0},
  22701. + {0x4D8, 0x0},
  22702. +};
  22703. +
  22704. +unsigned long ddr3_400[][2] = {
  22705. + {0x83c, 0x42490249},
  22706. + {0x840, 0x02470247},
  22707. + {0x483c, 0x42570257},
  22708. + {0x4840, 0x02400240},
  22709. + {0x848, 0x4039363C},
  22710. + {0x4848, 0x3A39333F},
  22711. + {0x850, 0x38414441},
  22712. + {0x4850, 0x472D4833}
  22713. +};
  22714. +
  22715. +int can_change_ddr_freq(void)
  22716. +{
  22717. + return 1;
  22718. +}
  22719. +
  22720. +/*
  22721. + * each active core apart from the one changing
  22722. + * the DDR frequency will execute this function.
  22723. + * the rest of the cores have to remain in WFE
  22724. + * state until the frequency is changed.
  22725. + */
  22726. +irqreturn_t wait_in_wfe_irq(int irq, void *dev_id)
  22727. +{
  22728. + u32 me = smp_processor_id();
  22729. +
  22730. + *((char *)(&cpus_in_wfe) + (u8)me) = 0xff;
  22731. +
  22732. + while (wait_for_ddr_freq_update)
  22733. + wfe();
  22734. +
  22735. + *((char *)(&cpus_in_wfe) + (u8)me) = 0;
  22736. +
  22737. + return IRQ_HANDLED;
  22738. +}
  22739. +
  22740. +/* change the DDR frequency. */
  22741. +int update_ddr_freq(int ddr_rate)
  22742. +{
  22743. + int i, j;
  22744. + unsigned int reg;
  22745. + bool dll_off = false;
  22746. + unsigned int online_cpus = 0;
  22747. + int cpu = 0;
  22748. + int me;
  22749. +
  22750. + if (!can_change_ddr_freq())
  22751. + return -1;
  22752. +
  22753. + if (ddr_rate == curr_ddr_rate)
  22754. + return 0;
  22755. +
  22756. + pr_debug("Bus freq set to %d start...\n", ddr_rate);
  22757. +
  22758. + if (low_bus_freq_mode || audio_bus_freq_mode)
  22759. + dll_off = true;
  22760. +
  22761. + iram_ddr_settings[0][0] = ddr_settings_size;
  22762. + iram_iomux_settings[0][0] = iomux_settings_size;
  22763. + if (ddr_rate == ddr_med_rate && cpu_is_imx6q()) {
  22764. + for (i = 0; i < ARRAY_SIZE(ddr3_dll_mx6q); i++) {
  22765. + iram_ddr_settings[i + 1][0] =
  22766. + normal_mmdc_settings[i][0];
  22767. + iram_ddr_settings[i + 1][1] =
  22768. + normal_mmdc_settings[i][1];
  22769. + }
  22770. + for (j = 0, i = ARRAY_SIZE(ddr3_dll_mx6q);
  22771. + i < iram_ddr_settings[0][0]; j++, i++) {
  22772. + iram_ddr_settings[i + 1][0] =
  22773. + ddr3_400[j][0];
  22774. + iram_ddr_settings[i + 1][1] =
  22775. + ddr3_400[j][1];
  22776. + }
  22777. + } else if (ddr_rate == ddr_normal_rate) {
  22778. + for (i = 0; i < iram_ddr_settings[0][0]; i++) {
  22779. + iram_ddr_settings[i + 1][0] =
  22780. + normal_mmdc_settings[i][0];
  22781. + iram_ddr_settings[i + 1][1] =
  22782. + normal_mmdc_settings[i][1];
  22783. + }
  22784. + }
  22785. +
  22786. + /* ensure that all Cores are in WFE. */
  22787. + local_irq_disable();
  22788. +
  22789. + me = smp_processor_id();
  22790. +
  22791. + *((char *)(&cpus_in_wfe) + (u8)me) = 0xff;
  22792. + wait_for_ddr_freq_update = true;
  22793. + for_each_online_cpu(cpu) {
  22794. + *((char *)(&online_cpus) + (u8)cpu) = 0xff;
  22795. + if (cpu != me) {
  22796. + /* set the interrupt to be pending in the GIC. */
  22797. + reg = 1 << (irqs_used[cpu] % 32);
  22798. + writel_relaxed(reg, gic_dist_base + GIC_DIST_PENDING_SET
  22799. + + (irqs_used[cpu] / 32) * 4);
  22800. + }
  22801. + }
  22802. + while (cpus_in_wfe != online_cpus)
  22803. + udelay(5);
  22804. +
  22805. + /*
  22806. + * Flush the TLB, to ensure no TLB maintenance occurs
  22807. + * when DDR is in self-refresh.
  22808. + */
  22809. + local_flush_tlb_all();
  22810. + /* Now we can change the DDR frequency. */
  22811. + mx6_change_ddr_freq(ddr_rate, iram_ddr_settings,
  22812. + dll_off, iram_iomux_settings);
  22813. +
  22814. + curr_ddr_rate = ddr_rate;
  22815. +
  22816. + /* DDR frequency change is done . */
  22817. + wait_for_ddr_freq_update = false;
  22818. +
  22819. + /* wake up all the cores. */
  22820. + sev();
  22821. +
  22822. + *((char *)(&cpus_in_wfe) + (u8)me) = 0;
  22823. +
  22824. + local_irq_enable();
  22825. +
  22826. + pr_debug("Bus freq set to %d done!\n", ddr_rate);
  22827. +
  22828. + return 0;
  22829. +}
  22830. +
  22831. +int init_mmdc_ddr3_settings(struct platform_device *busfreq_pdev)
  22832. +{
  22833. + struct device *dev = &busfreq_pdev->dev;
  22834. + struct platform_device *ocram_dev;
  22835. + unsigned int iram_paddr;
  22836. + int i, err;
  22837. + u32 cpu;
  22838. + struct device_node *node;
  22839. + struct gen_pool *iram_pool;
  22840. +
  22841. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-mmdc-combine");
  22842. + if (!node) {
  22843. + pr_err("failed to find imx6q-mmdc device tree data!\n");
  22844. + return -EINVAL;
  22845. + }
  22846. + mmdc_base = of_iomap(node, 0);
  22847. + WARN(!mmdc_base, "unable to map mmdc registers\n");
  22848. +
  22849. + node = NULL;
  22850. + if (cpu_is_imx6q())
  22851. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-iomuxc");
  22852. + if (cpu_is_imx6dl())
  22853. + node = of_find_compatible_node(NULL, NULL,
  22854. + "fsl,imx6dl-iomuxc");
  22855. + if (!node) {
  22856. + pr_err("failed to find imx6q-iomux device tree data!\n");
  22857. + return -EINVAL;
  22858. + }
  22859. + iomux_base = of_iomap(node, 0);
  22860. + WARN(!iomux_base, "unable to map iomux registers\n");
  22861. +
  22862. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
  22863. + if (!node) {
  22864. + pr_err("failed to find imx6q-ccm device tree data!\n");
  22865. + return -EINVAL;
  22866. + }
  22867. + ccm_base = of_iomap(node, 0);
  22868. + WARN(!ccm_base, "unable to map mmdc registers\n");
  22869. +
  22870. + node = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
  22871. + if (!node) {
  22872. + pr_err("failed to find imx6q-pl310-cache device tree data!\n");
  22873. + return -EINVAL;
  22874. + }
  22875. + l2_base = of_iomap(node, 0);
  22876. + WARN(!ccm_base, "unable to map mmdc registers\n");
  22877. +
  22878. + node = NULL;
  22879. + node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic");
  22880. + if (!node) {
  22881. + pr_err("failed to find imx6q-a9-gic device tree data!\n");
  22882. + return -EINVAL;
  22883. + }
  22884. + gic_dist_base = of_iomap(node, 0);
  22885. + WARN(!gic_dist_base, "unable to map gic dist registers\n");
  22886. +
  22887. + if (cpu_is_imx6q())
  22888. + ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6q) +
  22889. + ARRAY_SIZE(ddr3_calibration);
  22890. + if (cpu_is_imx6dl())
  22891. + ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6dl) +
  22892. + ARRAY_SIZE(ddr3_calibration);
  22893. +
  22894. + normal_mmdc_settings = kmalloc((ddr_settings_size * 8), GFP_KERNEL);
  22895. + if (cpu_is_imx6q()) {
  22896. + memcpy(normal_mmdc_settings, ddr3_dll_mx6q,
  22897. + sizeof(ddr3_dll_mx6q));
  22898. + memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6q)),
  22899. + ddr3_calibration, sizeof(ddr3_calibration));
  22900. + }
  22901. + if (cpu_is_imx6dl()) {
  22902. + memcpy(normal_mmdc_settings, ddr3_dll_mx6dl,
  22903. + sizeof(ddr3_dll_mx6dl));
  22904. + memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6dl)),
  22905. + ddr3_calibration, sizeof(ddr3_calibration));
  22906. + }
  22907. + /* store the original DDR settings at boot. */
  22908. + for (i = 0; i < ddr_settings_size; i++) {
  22909. + /*
  22910. + * writes via command mode register cannot be read back.
  22911. + * hence hardcode them in the initial static array.
  22912. + * this may require modification on a per customer basis.
  22913. + */
  22914. + if (normal_mmdc_settings[i][0] != 0x1C)
  22915. + normal_mmdc_settings[i][1] =
  22916. + readl_relaxed(mmdc_base
  22917. + + normal_mmdc_settings[i][0]);
  22918. + }
  22919. +
  22920. + irqs_used = devm_kzalloc(dev, sizeof(u32) * num_present_cpus(),
  22921. + GFP_KERNEL);
  22922. +
  22923. + for_each_online_cpu(cpu) {
  22924. + int irq;
  22925. +
  22926. + /*
  22927. + * set up a reserved interrupt to get all
  22928. + * the active cores into a WFE state
  22929. + * before changing the DDR frequency.
  22930. + */
  22931. + irq = platform_get_irq(busfreq_pdev, cpu);
  22932. + err = request_irq(irq, wait_in_wfe_irq,
  22933. + IRQF_PERCPU, "mmdc_1", NULL);
  22934. + if (err) {
  22935. + dev_err(dev,
  22936. + "Busfreq:request_irq failed %d, err = %d\n",
  22937. + irq, err);
  22938. + return err;
  22939. + }
  22940. + err = irq_set_affinity(irq, cpumask_of(cpu));
  22941. + if (err) {
  22942. + dev_err(dev,
  22943. + "Busfreq: Cannot set irq affinity irq=%d,\n",
  22944. + irq);
  22945. + return err;
  22946. + }
  22947. + irqs_used[cpu] = irq;
  22948. + }
  22949. +
  22950. + node = NULL;
  22951. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  22952. + if (!node) {
  22953. + dev_err(dev, "%s: failed to find ocram node\n",
  22954. + __func__);
  22955. + return -EINVAL;
  22956. + }
  22957. +
  22958. + ocram_dev = of_find_device_by_node(node);
  22959. + if (!ocram_dev) {
  22960. + dev_err(dev, "failed to find ocram device!\n");
  22961. + return -EINVAL;
  22962. + }
  22963. +
  22964. + iram_pool = dev_get_gen_pool(&ocram_dev->dev);
  22965. + if (!iram_pool) {
  22966. + dev_err(dev, "iram pool unavailable!\n");
  22967. + return -EINVAL;
  22968. + }
  22969. +
  22970. + iomux_settings_size = ARRAY_SIZE(iomux_offsets_mx6q);
  22971. + iram_iomux_settings = gen_pool_alloc(iram_pool,
  22972. + (iomux_settings_size * 8) + 8);
  22973. + if (!iram_iomux_settings) {
  22974. + dev_err(dev, "unable to alloc iram for IOMUX settings!\n");
  22975. + return -ENOMEM;
  22976. + }
  22977. +
  22978. + /*
  22979. + * Allocate extra space to store the number of entries in the
  22980. + * ddr_settings plus 4 extra regsiter information that needs
  22981. + * to be passed to the frequency change code.
  22982. + * sizeof(iram_ddr_settings) = sizeof(ddr_settings) +
  22983. + * entries in ddr_settings + 16.
  22984. + * The last 4 enties store the addresses of the registers:
  22985. + * CCM_BASE_ADDR
  22986. + * MMDC_BASE_ADDR
  22987. + * IOMUX_BASE_ADDR
  22988. + * L2X0_BASE_ADDR
  22989. + */
  22990. + iram_ddr_settings = gen_pool_alloc(iram_pool,
  22991. + (ddr_settings_size * 8) + 8 + 32);
  22992. + if (!iram_ddr_settings) {
  22993. + dev_err(dev, "unable to alloc iram for ddr settings!\n");
  22994. + return -ENOMEM;
  22995. + }
  22996. + i = ddr_settings_size + 1;
  22997. + iram_ddr_settings[i][0] = (unsigned long)mmdc_base;
  22998. + iram_ddr_settings[i+1][0] = (unsigned long)ccm_base;
  22999. + iram_ddr_settings[i+2][0] = (unsigned long)iomux_base;
  23000. + iram_ddr_settings[i+3][0] = (unsigned long)l2_base;
  23001. +
  23002. + if (cpu_is_imx6q()) {
  23003. + /* store the IOMUX settings at boot. */
  23004. + for (i = 0; i < iomux_settings_size; i++) {
  23005. + iomux_offsets_mx6q[i][1] =
  23006. + readl_relaxed(iomux_base +
  23007. + iomux_offsets_mx6q[i][0]);
  23008. + iram_iomux_settings[i+1][0] = iomux_offsets_mx6q[i][0];
  23009. + iram_iomux_settings[i+1][1] = iomux_offsets_mx6q[i][1];
  23010. + }
  23011. + }
  23012. +
  23013. + if (cpu_is_imx6dl()) {
  23014. + for (i = 0; i < iomux_settings_size; i++) {
  23015. + iomux_offsets_mx6dl[i][1] =
  23016. + readl_relaxed(iomux_base +
  23017. + iomux_offsets_mx6dl[i][0]);
  23018. + iram_iomux_settings[i+1][0] = iomux_offsets_mx6dl[i][0];
  23019. + iram_iomux_settings[i+1][1] = iomux_offsets_mx6dl[i][1];
  23020. + }
  23021. + }
  23022. +
  23023. + ddr_freq_change_iram_base = gen_pool_alloc(iram_pool,
  23024. + DDR_FREQ_CHANGE_SIZE);
  23025. + if (!ddr_freq_change_iram_base) {
  23026. + dev_err(dev, "Cannot alloc iram for ddr freq change code!\n");
  23027. + return -ENOMEM;
  23028. + }
  23029. +
  23030. + iram_paddr = gen_pool_virt_to_phys(iram_pool,
  23031. + (unsigned long)ddr_freq_change_iram_base);
  23032. + /*
  23033. + * Need to remap the area here since we want
  23034. + * the memory region to be executable.
  23035. + */
  23036. + ddr_freq_change_iram_base = __arm_ioremap(iram_paddr,
  23037. + DDR_FREQ_CHANGE_SIZE,
  23038. + MT_MEMORY_RWX_NONCACHED);
  23039. + mx6_change_ddr_freq = (void *)fncpy(ddr_freq_change_iram_base,
  23040. + &mx6_ddr3_freq_change, DDR_FREQ_CHANGE_SIZE);
  23041. +
  23042. + curr_ddr_rate = ddr_normal_rate;
  23043. +
  23044. + return 0;
  23045. +}
  23046. diff -Nur linux-3.14.14/arch/arm/mach-imx/busfreq-imx6.c linux-imx6-3.14/arch/arm/mach-imx/busfreq-imx6.c
  23047. --- linux-3.14.14/arch/arm/mach-imx/busfreq-imx6.c 1969-12-31 18:00:00.000000000 -0600
  23048. +++ linux-imx6-3.14/arch/arm/mach-imx/busfreq-imx6.c 2014-12-08 00:31:51.220418001 -0600
  23049. @@ -0,0 +1,952 @@
  23050. +/*
  23051. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  23052. + *
  23053. + * This program is free software; you can redistribute it and/or modify
  23054. + * it under the terms of the GNU General Public License as published by
  23055. + * the Free Software Foundation; either version 2 of the License, or
  23056. + * (at your option) any later version.
  23057. +
  23058. + * This program is distributed in the hope that it will be useful,
  23059. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23060. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23061. + * GNU General Public License for more details.
  23062. +
  23063. + * You should have received a copy of the GNU General Public License along
  23064. + * with this program; if not, write to the Free Software Foundation, Inc.,
  23065. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  23066. + */
  23067. +
  23068. +/*!
  23069. + * @file busfreq-imx6.c
  23070. + *
  23071. + * @brief A common API for the Freescale Semiconductor iMX6 Busfreq API
  23072. + *
  23073. + * The APIs are for setting bus frequency to different values based on the
  23074. + * highest freqeuncy requested.
  23075. + *
  23076. + * @ingroup PM
  23077. + */
  23078. +
  23079. +#include <asm/cacheflush.h>
  23080. +#include <asm/io.h>
  23081. +#include <asm/mach/map.h>
  23082. +#include <asm/mach-types.h>
  23083. +#include <asm/tlb.h>
  23084. +#include <linux/busfreq-imx6.h>
  23085. +#include <linux/clk.h>
  23086. +#include <linux/clk-provider.h>
  23087. +#include <linux/delay.h>
  23088. +#include <linux/module.h>
  23089. +#include <linux/mutex.h>
  23090. +#include <linux/of.h>
  23091. +#include <linux/platform_device.h>
  23092. +#include <linux/proc_fs.h>
  23093. +#include <linux/reboot.h>
  23094. +#include <linux/regulator/consumer.h>
  23095. +#include <linux/sched.h>
  23096. +#include <linux/suspend.h>
  23097. +#include "hardware.h"
  23098. +
  23099. +#define LPAPM_CLK 24000000
  23100. +#define DDR3_AUDIO_CLK 50000000
  23101. +#define LPDDR2_AUDIO_CLK 100000000
  23102. +
  23103. +int high_bus_freq_mode;
  23104. +int med_bus_freq_mode;
  23105. +int audio_bus_freq_mode;
  23106. +int low_bus_freq_mode;
  23107. +int ultra_low_bus_freq_mode;
  23108. +unsigned int ddr_med_rate;
  23109. +unsigned int ddr_normal_rate;
  23110. +
  23111. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23112. +static int bus_freq_scaling_initialized;
  23113. +static struct device *busfreq_dev;
  23114. +static int busfreq_suspended;
  23115. +static u32 org_arm_rate;
  23116. +static int bus_freq_scaling_is_active;
  23117. +static int high_bus_count, med_bus_count, audio_bus_count, low_bus_count;
  23118. +static unsigned int ddr_low_rate;
  23119. +
  23120. +extern int init_mmdc_lpddr2_settings(struct platform_device *dev);
  23121. +extern int init_mmdc_ddr3_settings(struct platform_device *dev);
  23122. +extern int update_ddr_freq(int ddr_rate);
  23123. +extern int update_lpddr2_freq(int ddr_rate);
  23124. +
  23125. +DEFINE_MUTEX(bus_freq_mutex);
  23126. +static DEFINE_SPINLOCK(freq_lock);
  23127. +
  23128. +static struct clk *pll2_400;
  23129. +static struct clk *periph_clk;
  23130. +static struct clk *periph_pre_clk;
  23131. +static struct clk *periph_clk2_sel;
  23132. +static struct clk *periph_clk2;
  23133. +static struct clk *osc_clk;
  23134. +static struct clk *cpu_clk;
  23135. +static struct clk *pll3;
  23136. +static struct clk *pll2;
  23137. +static struct clk *pll2_200;
  23138. +static struct clk *pll1_sys;
  23139. +static struct clk *periph2_clk;
  23140. +static struct clk *ocram_clk;
  23141. +static struct clk *ahb_clk;
  23142. +static struct clk *pll1_sw_clk;
  23143. +static struct clk *periph2_pre_clk;
  23144. +static struct clk *periph2_clk2_sel;
  23145. +static struct clk *periph2_clk2;
  23146. +static struct clk *step_clk;
  23147. +static struct clk *axi_sel_clk;
  23148. +static struct clk *pll3_pfd1_540m;
  23149. +
  23150. +static u32 pll2_org_rate;
  23151. +static struct delayed_work low_bus_freq_handler;
  23152. +static struct delayed_work bus_freq_daemon;
  23153. +
  23154. +static void enter_lpm_imx6sl(void)
  23155. +{
  23156. + unsigned long flags;
  23157. +
  23158. + if (high_bus_freq_mode) {
  23159. + pll2_org_rate = clk_get_rate(pll2);
  23160. + /* Set periph_clk to be sourced from OSC_CLK */
  23161. + clk_set_parent(periph_clk2_sel, osc_clk);
  23162. + clk_set_parent(periph_clk, periph_clk2);
  23163. + /* Ensure AHB/AXI clks are at 24MHz. */
  23164. + clk_set_rate(ahb_clk, LPAPM_CLK);
  23165. + clk_set_rate(ocram_clk, LPAPM_CLK);
  23166. + }
  23167. + if (audio_bus_count) {
  23168. + /* Set AHB to 8MHz to lower pwer.*/
  23169. + clk_set_rate(ahb_clk, LPAPM_CLK / 3);
  23170. +
  23171. + /* Set up DDR to 100MHz. */
  23172. + spin_lock_irqsave(&freq_lock, flags);
  23173. + update_lpddr2_freq(LPDDR2_AUDIO_CLK);
  23174. + spin_unlock_irqrestore(&freq_lock, flags);
  23175. +
  23176. + /* Fix the clock tree in kernel */
  23177. + clk_set_rate(pll2, pll2_org_rate);
  23178. + clk_set_parent(periph2_pre_clk, pll2_200);
  23179. + clk_set_parent(periph2_clk, periph2_pre_clk);
  23180. +
  23181. + if (low_bus_freq_mode || ultra_low_bus_freq_mode) {
  23182. + /*
  23183. + * Swtich ARM to run off PLL2_PFD2_400MHz
  23184. + * since DDR is anyway at 100MHz.
  23185. + */
  23186. + clk_set_parent(step_clk, pll2_400);
  23187. + clk_set_parent(pll1_sw_clk, step_clk);
  23188. + /*
  23189. + * Ensure that the clock will be
  23190. + * at original speed.
  23191. + */
  23192. + clk_set_rate(cpu_clk, org_arm_rate);
  23193. + }
  23194. + low_bus_freq_mode = 0;
  23195. + ultra_low_bus_freq_mode = 0;
  23196. + audio_bus_freq_mode = 1;
  23197. + } else {
  23198. + u32 arm_div, pll1_rate;
  23199. + org_arm_rate = clk_get_rate(cpu_clk);
  23200. + if (low_bus_freq_mode && low_bus_count == 0) {
  23201. + /*
  23202. + * We are already in DDR @ 24MHz state, but
  23203. + * no one but ARM needs the DDR. In this case,
  23204. + * we can lower the DDR freq to 1MHz when ARM
  23205. + * enters WFI in this state. Keep track of this state.
  23206. + */
  23207. + ultra_low_bus_freq_mode = 1;
  23208. + low_bus_freq_mode = 0;
  23209. + audio_bus_freq_mode = 0;
  23210. + } else {
  23211. + if (!ultra_low_bus_freq_mode && !low_bus_freq_mode) {
  23212. + /*
  23213. + * Set DDR to 24MHz.
  23214. + * Since we are going to bypass PLL2,
  23215. + * we need to move ARM clk off PLL2_PFD2
  23216. + * to PLL1. Make sure the PLL1 is running
  23217. + * at the lowest possible freq.
  23218. + */
  23219. + clk_set_rate(pll1_sys,
  23220. + clk_round_rate(pll1_sys, org_arm_rate));
  23221. + pll1_rate = clk_get_rate(pll1_sys);
  23222. + arm_div = pll1_rate / org_arm_rate + 1;
  23223. + /*
  23224. + * Ensure ARM CLK is lower before
  23225. + * changing the parent.
  23226. + */
  23227. + clk_set_rate(cpu_clk, org_arm_rate / arm_div);
  23228. + /* Now set the ARM clk parent to PLL1_SYS. */
  23229. + clk_set_parent(pll1_sw_clk, pll1_sys);
  23230. +
  23231. + /*
  23232. + * Set STEP_CLK back to OSC to save power and
  23233. + * also to maintain the parent.The WFI iram code
  23234. + * will switch step_clk to osc, but the clock API
  23235. + * is not aware of the change and when a new request
  23236. + * to change the step_clk parent to pll2_pfd2_400M
  23237. + * is requested sometime later, the change is ignored.
  23238. + */
  23239. + clk_set_parent(step_clk, osc_clk);
  23240. + /* Now set DDR to 24MHz. */
  23241. + spin_lock_irqsave(&freq_lock, flags);
  23242. + update_lpddr2_freq(LPAPM_CLK);
  23243. + spin_unlock_irqrestore(&freq_lock, flags);
  23244. +
  23245. + /*
  23246. + * Fix the clock tree in kernel.
  23247. + * Make sure PLL2 rate is updated as it gets
  23248. + * bypassed in the DDR freq change code.
  23249. + */
  23250. + clk_set_rate(pll2, LPAPM_CLK);
  23251. + clk_set_parent(periph2_clk2_sel, pll2);
  23252. + clk_set_parent(periph2_clk, periph2_clk2_sel);
  23253. +
  23254. + }
  23255. + if (low_bus_count == 0) {
  23256. + ultra_low_bus_freq_mode = 1;
  23257. + low_bus_freq_mode = 0;
  23258. + } else {
  23259. + ultra_low_bus_freq_mode = 0;
  23260. + low_bus_freq_mode = 1;
  23261. + }
  23262. + audio_bus_freq_mode = 0;
  23263. + }
  23264. + }
  23265. +}
  23266. +
  23267. +static void exit_lpm_imx6sl(void)
  23268. +{
  23269. + unsigned long flags;
  23270. +
  23271. + spin_lock_irqsave(&freq_lock, flags);
  23272. + /* Change DDR freq in IRAM. */
  23273. + update_lpddr2_freq(ddr_normal_rate);
  23274. + spin_unlock_irqrestore(&freq_lock, flags);
  23275. +
  23276. + /*
  23277. + * Fix the clock tree in kernel.
  23278. + * Make sure PLL2 rate is updated as it gets
  23279. + * un-bypassed in the DDR freq change code.
  23280. + */
  23281. + clk_set_rate(pll2, pll2_org_rate);
  23282. + clk_set_parent(periph2_pre_clk, pll2_400);
  23283. + clk_set_parent(periph2_clk, periph2_pre_clk);
  23284. +
  23285. + /* Ensure that periph_clk is sourced from PLL2_400. */
  23286. + clk_set_parent(periph_pre_clk, pll2_400);
  23287. + /*
  23288. + * Before switching the perhiph_clk, ensure that the
  23289. + * AHB/AXI will not be too fast.
  23290. + */
  23291. + clk_set_rate(ahb_clk, LPAPM_CLK / 3);
  23292. + clk_set_rate(ocram_clk, LPAPM_CLK / 2);
  23293. + clk_set_parent(periph_clk, periph_pre_clk);
  23294. +
  23295. + if (low_bus_freq_mode || ultra_low_bus_freq_mode) {
  23296. + /* Move ARM from PLL1_SW_CLK to PLL2_400. */
  23297. + clk_set_parent(step_clk, pll2_400);
  23298. + clk_set_parent(pll1_sw_clk, step_clk);
  23299. + clk_set_rate(cpu_clk, org_arm_rate);
  23300. + ultra_low_bus_freq_mode = 0;
  23301. + }
  23302. +}
  23303. +
  23304. +int reduce_bus_freq(void)
  23305. +{
  23306. + int ret = 0;
  23307. + clk_prepare_enable(pll3);
  23308. + if (cpu_is_imx6sl())
  23309. + enter_lpm_imx6sl();
  23310. + else {
  23311. + if (cpu_is_imx6dl() && (clk_get_parent(axi_sel_clk)
  23312. + != periph_clk))
  23313. + /* Set axi to periph_clk */
  23314. + clk_set_parent(axi_sel_clk, periph_clk);
  23315. +
  23316. + if (audio_bus_count) {
  23317. + /* Need to ensure that PLL2_PFD_400M is kept ON. */
  23318. + clk_prepare_enable(pll2_400);
  23319. + update_ddr_freq(DDR3_AUDIO_CLK);
  23320. + /* Make sure periph clk's parent also got updated */
  23321. + ret = clk_set_parent(periph_clk2_sel, pll3);
  23322. + if (ret)
  23323. + dev_WARN(busfreq_dev,
  23324. + "%s: %d: clk set parent fail!\n",
  23325. + __func__, __LINE__);
  23326. + ret = clk_set_parent(periph_pre_clk, pll2_200);
  23327. + if (ret)
  23328. + dev_WARN(busfreq_dev,
  23329. + "%s: %d: clk set parent fail!\n",
  23330. + __func__, __LINE__);
  23331. + ret = clk_set_parent(periph_clk, periph_pre_clk);
  23332. + if (ret)
  23333. + dev_WARN(busfreq_dev,
  23334. + "%s: %d: clk set parent fail!\n",
  23335. + __func__, __LINE__);
  23336. + audio_bus_freq_mode = 1;
  23337. + low_bus_freq_mode = 0;
  23338. + } else {
  23339. + update_ddr_freq(LPAPM_CLK);
  23340. + /* Make sure periph clk's parent also got updated */
  23341. + ret = clk_set_parent(periph_clk2_sel, osc_clk);
  23342. + if (ret)
  23343. + dev_WARN(busfreq_dev,
  23344. + "%s: %d: clk set parent fail!\n",
  23345. + __func__, __LINE__);
  23346. + /* Set periph_clk parent to OSC via periph_clk2_sel */
  23347. + ret = clk_set_parent(periph_clk, periph_clk2);
  23348. + if (ret)
  23349. + dev_WARN(busfreq_dev,
  23350. + "%s: %d: clk set parent fail!\n",
  23351. + __func__, __LINE__);
  23352. + if (audio_bus_freq_mode)
  23353. + clk_disable_unprepare(pll2_400);
  23354. + low_bus_freq_mode = 1;
  23355. + audio_bus_freq_mode = 0;
  23356. + }
  23357. + }
  23358. + clk_disable_unprepare(pll3);
  23359. +
  23360. + med_bus_freq_mode = 0;
  23361. + high_bus_freq_mode = 0;
  23362. +
  23363. + if (audio_bus_freq_mode)
  23364. + dev_dbg(busfreq_dev, "Bus freq set to audio mode. Count:\
  23365. + high %d, med %d, audio %d\n",
  23366. + high_bus_count, med_bus_count, audio_bus_count);
  23367. + if (low_bus_freq_mode)
  23368. + dev_dbg(busfreq_dev, "Bus freq set to low mode. Count:\
  23369. + high %d, med %d, audio %d\n",
  23370. + high_bus_count, med_bus_count, audio_bus_count);
  23371. +
  23372. + return ret;
  23373. +}
  23374. +
  23375. +static void reduce_bus_freq_handler(struct work_struct *work)
  23376. +{
  23377. + mutex_lock(&bus_freq_mutex);
  23378. +
  23379. + reduce_bus_freq();
  23380. +
  23381. + mutex_unlock(&bus_freq_mutex);
  23382. +}
  23383. +
  23384. +/*
  23385. + * Set the DDR, AHB to 24MHz.
  23386. + * This mode will be activated only when none of the modules that
  23387. + * need a higher DDR or AHB frequency are active.
  23388. + */
  23389. +int set_low_bus_freq(void)
  23390. +{
  23391. + if (busfreq_suspended)
  23392. + return 0;
  23393. +
  23394. + if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
  23395. + return 0;
  23396. +
  23397. + /*
  23398. + * Check to see if we need to got from
  23399. + * low bus freq mode to audio bus freq mode.
  23400. + * If so, the change needs to be done immediately.
  23401. + */
  23402. + if (audio_bus_count && (low_bus_freq_mode || ultra_low_bus_freq_mode))
  23403. + reduce_bus_freq();
  23404. + else
  23405. + /*
  23406. + * Don't lower the frequency immediately. Instead
  23407. + * scheduled a delayed work and drop the freq if
  23408. + * the conditions still remain the same.
  23409. + */
  23410. + schedule_delayed_work(&low_bus_freq_handler,
  23411. + usecs_to_jiffies(3000000));
  23412. + return 0;
  23413. +}
  23414. +
  23415. +/*
  23416. + * Set the DDR to either 528MHz or 400MHz for iMX6qd
  23417. + * or 400MHz for iMX6dl.
  23418. + */
  23419. +int set_high_bus_freq(int high_bus_freq)
  23420. +{
  23421. + int ret = 0;
  23422. + struct clk *periph_clk_parent;
  23423. +
  23424. + if (bus_freq_scaling_initialized && bus_freq_scaling_is_active)
  23425. + cancel_delayed_work_sync(&low_bus_freq_handler);
  23426. +
  23427. + if (busfreq_suspended)
  23428. + return 0;
  23429. +
  23430. + if (cpu_is_imx6q())
  23431. + periph_clk_parent = pll2;
  23432. + else
  23433. + periph_clk_parent = pll2_400;
  23434. +
  23435. + if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
  23436. + return 0;
  23437. +
  23438. + if (high_bus_freq_mode)
  23439. + return 0;
  23440. +
  23441. + /* medium bus freq is only supported for MX6DQ */
  23442. + if (med_bus_freq_mode && !high_bus_freq)
  23443. + return 0;
  23444. +
  23445. + clk_prepare_enable(pll3);
  23446. + if (cpu_is_imx6sl())
  23447. + exit_lpm_imx6sl();
  23448. + else {
  23449. + if (high_bus_freq) {
  23450. + update_ddr_freq(ddr_normal_rate);
  23451. + /* Make sure periph clk's parent also got updated */
  23452. + ret = clk_set_parent(periph_clk2_sel, pll3);
  23453. + if (ret)
  23454. + dev_WARN(busfreq_dev,
  23455. + "%s: %d: clk set parent fail!\n",
  23456. + __func__, __LINE__);
  23457. + ret = clk_set_parent(periph_pre_clk, periph_clk_parent);
  23458. + if (ret)
  23459. + dev_WARN(busfreq_dev,
  23460. + "%s: %d: clk set parent fail!\n",
  23461. + __func__, __LINE__);
  23462. + ret = clk_set_parent(periph_clk, periph_pre_clk);
  23463. + if (ret)
  23464. + dev_WARN(busfreq_dev,
  23465. + "%s: %d: clk set parent fail!\n",
  23466. + __func__, __LINE__);
  23467. + if (cpu_is_imx6dl() && (clk_get_parent(axi_sel_clk)
  23468. + != pll3_pfd1_540m))
  23469. + /* Set axi to pll3_pfd1_540m */
  23470. + clk_set_parent(axi_sel_clk, pll3_pfd1_540m);
  23471. + } else {
  23472. + update_ddr_freq(ddr_med_rate);
  23473. + /* Make sure periph clk's parent also got updated */
  23474. + ret = clk_set_parent(periph_clk2_sel, pll3);
  23475. + if (ret)
  23476. + dev_WARN(busfreq_dev,
  23477. + "%s: %d: clk set parent fail!\n",
  23478. + __func__, __LINE__);
  23479. + ret = clk_set_parent(periph_pre_clk, pll2_400);
  23480. + if (ret)
  23481. + dev_WARN(busfreq_dev,
  23482. + "%s: %d: clk set parent fail!\n",
  23483. + __func__, __LINE__);
  23484. + ret = clk_set_parent(periph_clk, periph_pre_clk);
  23485. + if (ret)
  23486. + dev_WARN(busfreq_dev,
  23487. + "%s: %d: clk set parent fail!\n",
  23488. + __func__, __LINE__);
  23489. + }
  23490. + if (audio_bus_freq_mode)
  23491. + clk_disable_unprepare(pll2_400);
  23492. + }
  23493. +
  23494. + high_bus_freq_mode = 1;
  23495. + med_bus_freq_mode = 0;
  23496. + low_bus_freq_mode = 0;
  23497. + audio_bus_freq_mode = 0;
  23498. +
  23499. + clk_disable_unprepare(pll3);
  23500. +
  23501. + if (high_bus_freq_mode)
  23502. + dev_dbg(busfreq_dev, "Bus freq set to high mode. Count:\
  23503. + high %d, med %d, audio %d\n",
  23504. + high_bus_count, med_bus_count, audio_bus_count);
  23505. + if (med_bus_freq_mode)
  23506. + dev_dbg(busfreq_dev, "Bus freq set to med mode. Count:\
  23507. + high %d, med %d, audio %d\n",
  23508. + high_bus_count, med_bus_count, audio_bus_count);
  23509. +
  23510. + return 0;
  23511. +}
  23512. +#endif
  23513. +
  23514. +void request_bus_freq(enum bus_freq_mode mode)
  23515. +{
  23516. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23517. + mutex_lock(&bus_freq_mutex);
  23518. +
  23519. + if (mode == BUS_FREQ_HIGH)
  23520. + high_bus_count++;
  23521. + else if (mode == BUS_FREQ_MED)
  23522. + med_bus_count++;
  23523. + else if (mode == BUS_FREQ_AUDIO)
  23524. + audio_bus_count++;
  23525. + else if (mode == BUS_FREQ_LOW)
  23526. + low_bus_count++;
  23527. +
  23528. + if (busfreq_suspended || !bus_freq_scaling_initialized ||
  23529. + !bus_freq_scaling_is_active) {
  23530. + mutex_unlock(&bus_freq_mutex);
  23531. + return;
  23532. + }
  23533. + cancel_delayed_work_sync(&low_bus_freq_handler);
  23534. +
  23535. + if (cpu_is_imx6dl()) {
  23536. + /* No support for medium setpoint on MX6DL. */
  23537. + if (mode == BUS_FREQ_MED) {
  23538. + high_bus_count++;
  23539. + mode = BUS_FREQ_HIGH;
  23540. + }
  23541. + }
  23542. +
  23543. + if ((mode == BUS_FREQ_HIGH) && (!high_bus_freq_mode)) {
  23544. + set_high_bus_freq(1);
  23545. + mutex_unlock(&bus_freq_mutex);
  23546. + return;
  23547. + }
  23548. +
  23549. + if ((mode == BUS_FREQ_MED) && (!high_bus_freq_mode) &&
  23550. + (!med_bus_freq_mode)) {
  23551. + set_high_bus_freq(0);
  23552. + mutex_unlock(&bus_freq_mutex);
  23553. + return;
  23554. + }
  23555. + if ((mode == BUS_FREQ_AUDIO) && (!high_bus_freq_mode) &&
  23556. + (!med_bus_freq_mode) && (!audio_bus_freq_mode)) {
  23557. + set_low_bus_freq();
  23558. + mutex_unlock(&bus_freq_mutex);
  23559. + return;
  23560. + }
  23561. + mutex_unlock(&bus_freq_mutex);
  23562. +#endif
  23563. + return;
  23564. +}
  23565. +EXPORT_SYMBOL(request_bus_freq);
  23566. +
  23567. +void release_bus_freq(enum bus_freq_mode mode)
  23568. +{
  23569. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23570. + mutex_lock(&bus_freq_mutex);
  23571. +
  23572. + if (mode == BUS_FREQ_HIGH) {
  23573. + if (high_bus_count == 0) {
  23574. + dev_err(busfreq_dev, "high bus count mismatch!\n");
  23575. + dump_stack();
  23576. + mutex_unlock(&bus_freq_mutex);
  23577. + return;
  23578. + }
  23579. + high_bus_count--;
  23580. + } else if (mode == BUS_FREQ_MED) {
  23581. + if (med_bus_count == 0) {
  23582. + dev_err(busfreq_dev, "med bus count mismatch!\n");
  23583. + dump_stack();
  23584. + mutex_unlock(&bus_freq_mutex);
  23585. + return;
  23586. + }
  23587. + med_bus_count--;
  23588. + } else if (mode == BUS_FREQ_AUDIO) {
  23589. + if (audio_bus_count == 0) {
  23590. + dev_err(busfreq_dev, "audio bus count mismatch!\n");
  23591. + dump_stack();
  23592. + mutex_unlock(&bus_freq_mutex);
  23593. + return;
  23594. + }
  23595. + audio_bus_count--;
  23596. + } else if (mode == BUS_FREQ_LOW) {
  23597. + if (low_bus_count == 0) {
  23598. + dev_err(busfreq_dev, "low bus count mismatch!\n");
  23599. + dump_stack();
  23600. + mutex_unlock(&bus_freq_mutex);
  23601. + return;
  23602. + }
  23603. + low_bus_count--;
  23604. + }
  23605. +
  23606. + if (busfreq_suspended || !bus_freq_scaling_initialized ||
  23607. + !bus_freq_scaling_is_active) {
  23608. + mutex_unlock(&bus_freq_mutex);
  23609. + return;
  23610. + }
  23611. +
  23612. + if (cpu_is_imx6dl()) {
  23613. + /* No support for medium setpoint on MX6DL. */
  23614. + if (mode == BUS_FREQ_MED) {
  23615. + high_bus_count--;
  23616. + mode = BUS_FREQ_HIGH;
  23617. + }
  23618. + }
  23619. +
  23620. + if ((!audio_bus_freq_mode) && (high_bus_count == 0) &&
  23621. + (med_bus_count == 0) && (audio_bus_count != 0)) {
  23622. + set_low_bus_freq();
  23623. + mutex_unlock(&bus_freq_mutex);
  23624. + return;
  23625. + }
  23626. + if ((!low_bus_freq_mode) && (high_bus_count == 0) &&
  23627. + (med_bus_count == 0) && (audio_bus_count == 0) &&
  23628. + (low_bus_count != 0)) {
  23629. + set_low_bus_freq();
  23630. + mutex_unlock(&bus_freq_mutex);
  23631. + return;
  23632. + }
  23633. + if ((!ultra_low_bus_freq_mode) && (high_bus_count == 0) &&
  23634. + (med_bus_count == 0) && (audio_bus_count == 0) &&
  23635. + (low_bus_count == 0)) {
  23636. + set_low_bus_freq();
  23637. + mutex_unlock(&bus_freq_mutex);
  23638. + return;
  23639. + }
  23640. +
  23641. + mutex_unlock(&bus_freq_mutex);
  23642. +#endif
  23643. + return;
  23644. +}
  23645. +EXPORT_SYMBOL(release_bus_freq);
  23646. +
  23647. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23648. +static void bus_freq_daemon_handler(struct work_struct *work)
  23649. +{
  23650. + mutex_lock(&bus_freq_mutex);
  23651. + if ((!low_bus_freq_mode) && (high_bus_count == 0) &&
  23652. + (med_bus_count == 0) && (audio_bus_count == 0))
  23653. + set_low_bus_freq();
  23654. + mutex_unlock(&bus_freq_mutex);
  23655. +}
  23656. +
  23657. +static ssize_t bus_freq_scaling_enable_show(struct device *dev,
  23658. + struct device_attribute *attr, char *buf)
  23659. +{
  23660. + if (bus_freq_scaling_is_active)
  23661. + return sprintf(buf, "Bus frequency scaling is enabled\n");
  23662. + else
  23663. + return sprintf(buf, "Bus frequency scaling is disabled\n");
  23664. +}
  23665. +
  23666. +static ssize_t bus_freq_scaling_enable_store(struct device *dev,
  23667. + struct device_attribute *attr,
  23668. + const char *buf, size_t size)
  23669. +{
  23670. + if (strncmp(buf, "1", 1) == 0) {
  23671. + bus_freq_scaling_is_active = 1;
  23672. + set_high_bus_freq(1);
  23673. + /*
  23674. + * We set bus freq to highest at the beginning,
  23675. + * so we use this daemon thread to make sure system
  23676. + * can enter low bus mode if
  23677. + * there is no high bus request pending
  23678. + */
  23679. + schedule_delayed_work(&bus_freq_daemon,
  23680. + usecs_to_jiffies(5000000));
  23681. + } else if (strncmp(buf, "0", 1) == 0) {
  23682. + if (bus_freq_scaling_is_active)
  23683. + set_high_bus_freq(1);
  23684. + bus_freq_scaling_is_active = 0;
  23685. + }
  23686. + return size;
  23687. +}
  23688. +
  23689. +static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event,
  23690. + void *dummy)
  23691. +{
  23692. + mutex_lock(&bus_freq_mutex);
  23693. +
  23694. + if (event == PM_SUSPEND_PREPARE) {
  23695. + high_bus_count++;
  23696. + set_high_bus_freq(1);
  23697. + busfreq_suspended = 1;
  23698. + } else if (event == PM_POST_SUSPEND) {
  23699. + busfreq_suspended = 0;
  23700. + high_bus_count--;
  23701. + schedule_delayed_work(&bus_freq_daemon,
  23702. + usecs_to_jiffies(5000000));
  23703. + }
  23704. +
  23705. + mutex_unlock(&bus_freq_mutex);
  23706. +
  23707. + return NOTIFY_OK;
  23708. +}
  23709. +
  23710. +static int busfreq_reboot_notifier_event(struct notifier_block *this,
  23711. + unsigned long event, void *ptr)
  23712. +{
  23713. + /* System is rebooting. Set the system into high_bus_freq_mode. */
  23714. + request_bus_freq(BUS_FREQ_HIGH);
  23715. +
  23716. + return 0;
  23717. +}
  23718. +
  23719. +static struct notifier_block imx_bus_freq_pm_notifier = {
  23720. + .notifier_call = bus_freq_pm_notify,
  23721. +};
  23722. +
  23723. +static struct notifier_block imx_busfreq_reboot_notifier = {
  23724. + .notifier_call = busfreq_reboot_notifier_event,
  23725. +};
  23726. +
  23727. +
  23728. +static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show,
  23729. + bus_freq_scaling_enable_store);
  23730. +#endif
  23731. +
  23732. +/*!
  23733. + * This is the probe routine for the bus frequency driver.
  23734. + *
  23735. + * @param pdev The platform device structure
  23736. + *
  23737. + * @return The function returns 0 on success
  23738. + *
  23739. + */
  23740. +
  23741. +static int busfreq_probe(struct platform_device *pdev)
  23742. +{
  23743. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23744. + u32 err;
  23745. +
  23746. + busfreq_dev = &pdev->dev;
  23747. +
  23748. + pll2_400 = devm_clk_get(&pdev->dev, "pll2_pfd2_396m");
  23749. + if (IS_ERR(pll2_400)) {
  23750. + dev_err(busfreq_dev, "%s: failed to get pll2_pfd2_396m\n",
  23751. + __func__);
  23752. + return PTR_ERR(pll2_400);
  23753. + }
  23754. +
  23755. + pll2_200 = devm_clk_get(&pdev->dev, "pll2_198m");
  23756. + if (IS_ERR(pll2_200)) {
  23757. + dev_err(busfreq_dev, "%s: failed to get pll2_198m\n",
  23758. + __func__);
  23759. + return PTR_ERR(pll2_200);
  23760. + }
  23761. +
  23762. + pll2 = devm_clk_get(&pdev->dev, "pll2_bus");
  23763. + if (IS_ERR(pll2)) {
  23764. + dev_err(busfreq_dev, "%s: failed to get pll2_bus\n",
  23765. + __func__);
  23766. + return PTR_ERR(pll2);
  23767. + }
  23768. +
  23769. + cpu_clk = devm_clk_get(&pdev->dev, "arm");
  23770. + if (IS_ERR(cpu_clk)) {
  23771. + dev_err(busfreq_dev, "%s: failed to get cpu_clk\n",
  23772. + __func__);
  23773. + return PTR_ERR(cpu_clk);
  23774. + }
  23775. +
  23776. + pll3 = devm_clk_get(&pdev->dev, "pll3_usb_otg");
  23777. + if (IS_ERR(pll3)) {
  23778. + dev_err(busfreq_dev, "%s: failed to get pll3_usb_otg\n",
  23779. + __func__);
  23780. + return PTR_ERR(pll3);
  23781. + }
  23782. +
  23783. + periph_clk = devm_clk_get(&pdev->dev, "periph");
  23784. + if (IS_ERR(periph_clk)) {
  23785. + dev_err(busfreq_dev, "%s: failed to get periph\n",
  23786. + __func__);
  23787. + return PTR_ERR(periph_clk);
  23788. + }
  23789. +
  23790. + periph_pre_clk = devm_clk_get(&pdev->dev, "periph_pre");
  23791. + if (IS_ERR(periph_pre_clk)) {
  23792. + dev_err(busfreq_dev, "%s: failed to get periph_pre\n",
  23793. + __func__);
  23794. + return PTR_ERR(periph_pre_clk);
  23795. + }
  23796. +
  23797. + periph_clk2 = devm_clk_get(&pdev->dev, "periph_clk2");
  23798. + if (IS_ERR(periph_clk2)) {
  23799. + dev_err(busfreq_dev, "%s: failed to get periph_clk2\n",
  23800. + __func__);
  23801. + return PTR_ERR(periph_clk2);
  23802. + }
  23803. +
  23804. + periph_clk2_sel = devm_clk_get(&pdev->dev, "periph_clk2_sel");
  23805. + if (IS_ERR(periph_clk2_sel)) {
  23806. + dev_err(busfreq_dev, "%s: failed to get periph_clk2_sel\n",
  23807. + __func__);
  23808. + return PTR_ERR(periph_clk2_sel);
  23809. + }
  23810. +
  23811. + osc_clk = devm_clk_get(&pdev->dev, "osc");
  23812. + if (IS_ERR(osc_clk)) {
  23813. + dev_err(busfreq_dev, "%s: failed to get osc_clk\n",
  23814. + __func__);
  23815. + return PTR_ERR(osc_clk);
  23816. + }
  23817. +
  23818. + if (cpu_is_imx6dl()) {
  23819. + axi_sel_clk = devm_clk_get(&pdev->dev, "axi_sel");
  23820. + if (IS_ERR(axi_sel_clk)) {
  23821. + dev_err(busfreq_dev, "%s: failed to get axi_sel_clk\n",
  23822. + __func__);
  23823. + return PTR_ERR(axi_sel_clk);
  23824. + }
  23825. +
  23826. + pll3_pfd1_540m = devm_clk_get(&pdev->dev, "pll3_pfd1_540m");
  23827. + if (IS_ERR(pll3_pfd1_540m)) {
  23828. + dev_err(busfreq_dev,
  23829. + "%s: failed to get pll3_pfd1_540m\n", __func__);
  23830. + return PTR_ERR(pll3_pfd1_540m);
  23831. + }
  23832. + }
  23833. +
  23834. + if (cpu_is_imx6sl()) {
  23835. + pll1_sys = devm_clk_get(&pdev->dev, "pll1_sys");
  23836. + if (IS_ERR(pll1_sys)) {
  23837. + dev_err(busfreq_dev, "%s: failed to get pll1_sys\n",
  23838. + __func__);
  23839. + return PTR_ERR(pll1_sys);
  23840. + }
  23841. +
  23842. + ahb_clk = devm_clk_get(&pdev->dev, "ahb");
  23843. + if (IS_ERR(ahb_clk)) {
  23844. + dev_err(busfreq_dev, "%s: failed to get ahb_clk\n",
  23845. + __func__);
  23846. + return PTR_ERR(ahb_clk);
  23847. + }
  23848. +
  23849. + ocram_clk = devm_clk_get(&pdev->dev, "ocram");
  23850. + if (IS_ERR(ocram_clk)) {
  23851. + dev_err(busfreq_dev, "%s: failed to get ocram_clk\n",
  23852. + __func__);
  23853. + return PTR_ERR(ocram_clk);
  23854. + }
  23855. +
  23856. + pll1_sw_clk = devm_clk_get(&pdev->dev, "pll1_sw");
  23857. + if (IS_ERR(pll1_sw_clk)) {
  23858. + dev_err(busfreq_dev, "%s: failed to get pll1_sw_clk\n",
  23859. + __func__);
  23860. + return PTR_ERR(pll1_sw_clk);
  23861. + }
  23862. +
  23863. + periph2_clk = devm_clk_get(&pdev->dev, "periph2");
  23864. + if (IS_ERR(periph2_clk)) {
  23865. + dev_err(busfreq_dev, "%s: failed to get periph2\n",
  23866. + __func__);
  23867. + return PTR_ERR(periph2_clk);
  23868. + }
  23869. +
  23870. + periph2_pre_clk = devm_clk_get(&pdev->dev, "periph2_pre");
  23871. + if (IS_ERR(periph2_pre_clk)) {
  23872. + dev_err(busfreq_dev,
  23873. + "%s: failed to get periph2_pre_clk\n",
  23874. + __func__);
  23875. + return PTR_ERR(periph2_pre_clk);
  23876. + }
  23877. +
  23878. + periph2_clk2 = devm_clk_get(&pdev->dev, "periph2_clk2");
  23879. + if (IS_ERR(periph2_clk2)) {
  23880. + dev_err(busfreq_dev,
  23881. + "%s: failed to get periph2_clk2\n",
  23882. + __func__);
  23883. + return PTR_ERR(periph2_clk2);
  23884. + }
  23885. +
  23886. + periph2_clk2_sel = devm_clk_get(&pdev->dev, "periph2_clk2_sel");
  23887. + if (IS_ERR(periph2_clk2_sel)) {
  23888. + dev_err(busfreq_dev,
  23889. + "%s: failed to get periph2_clk2_sel\n",
  23890. + __func__);
  23891. + return PTR_ERR(periph2_clk2_sel);
  23892. + }
  23893. +
  23894. + step_clk = devm_clk_get(&pdev->dev, "step");
  23895. + if (IS_ERR(step_clk)) {
  23896. + dev_err(busfreq_dev,
  23897. + "%s: failed to get step_clk\n",
  23898. + __func__);
  23899. + return PTR_ERR(periph2_clk2_sel);
  23900. + }
  23901. +
  23902. + }
  23903. +
  23904. + err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
  23905. + if (err) {
  23906. + dev_err(busfreq_dev,
  23907. + "Unable to register sysdev entry for BUSFREQ");
  23908. + return err;
  23909. + }
  23910. +
  23911. + if (of_property_read_u32(pdev->dev.of_node, "fsl,max_ddr_freq",
  23912. + &ddr_normal_rate)) {
  23913. + dev_err(busfreq_dev, "max_ddr_freq entry missing\n");
  23914. + return -EINVAL;
  23915. + }
  23916. +#endif
  23917. +
  23918. + high_bus_freq_mode = 1;
  23919. + med_bus_freq_mode = 0;
  23920. + low_bus_freq_mode = 0;
  23921. + audio_bus_freq_mode = 0;
  23922. + ultra_low_bus_freq_mode = 0;
  23923. +
  23924. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23925. + bus_freq_scaling_is_active = 1;
  23926. + bus_freq_scaling_initialized = 1;
  23927. +
  23928. + ddr_low_rate = LPAPM_CLK;
  23929. + if (cpu_is_imx6q()) {
  23930. + if (of_property_read_u32(pdev->dev.of_node, "fsl,med_ddr_freq",
  23931. + &ddr_med_rate)) {
  23932. + dev_info(busfreq_dev,
  23933. + "DDR medium rate not supported.\n");
  23934. + ddr_med_rate = ddr_normal_rate;
  23935. + }
  23936. + }
  23937. +
  23938. + INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler);
  23939. + INIT_DELAYED_WORK(&bus_freq_daemon, bus_freq_daemon_handler);
  23940. + register_pm_notifier(&imx_bus_freq_pm_notifier);
  23941. + register_reboot_notifier(&imx_busfreq_reboot_notifier);
  23942. +
  23943. + if (cpu_is_imx6sl())
  23944. + err = init_mmdc_lpddr2_settings(pdev);
  23945. + else
  23946. + err = init_mmdc_ddr3_settings(pdev);
  23947. + if (err) {
  23948. + dev_err(busfreq_dev, "Busfreq init of MMDC failed\n");
  23949. + return err;
  23950. + }
  23951. +#endif
  23952. + return 0;
  23953. +}
  23954. +
  23955. +static const struct of_device_id imx6_busfreq_ids[] = {
  23956. + { .compatible = "fsl,imx6_busfreq", },
  23957. + { /* sentinel */ }
  23958. +};
  23959. +
  23960. +static struct platform_driver busfreq_driver = {
  23961. + .driver = {
  23962. + .name = "imx6_busfreq",
  23963. + .owner = THIS_MODULE,
  23964. + .of_match_table = imx6_busfreq_ids,
  23965. + },
  23966. + .probe = busfreq_probe,
  23967. +};
  23968. +
  23969. +/*!
  23970. + * Initialise the busfreq_driver.
  23971. + *
  23972. + * @return The function always returns 0.
  23973. + */
  23974. +
  23975. +static int __init busfreq_init(void)
  23976. +{
  23977. + if (platform_driver_register(&busfreq_driver) != 0)
  23978. + return -ENODEV;
  23979. +
  23980. + printk(KERN_INFO "Bus freq driver module loaded\n");
  23981. +
  23982. + return 0;
  23983. +}
  23984. +
  23985. +static void __exit busfreq_cleanup(void)
  23986. +{
  23987. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23988. + sysfs_remove_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
  23989. +
  23990. + bus_freq_scaling_initialized = 0;
  23991. +#endif
  23992. + /* Unregister the device structure */
  23993. + platform_driver_unregister(&busfreq_driver);
  23994. +}
  23995. +
  23996. +module_init(busfreq_init);
  23997. +module_exit(busfreq_cleanup);
  23998. +
  23999. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  24000. +MODULE_DESCRIPTION("BusFreq driver");
  24001. +MODULE_LICENSE("GPL");
  24002. diff -Nur linux-3.14.14/arch/arm/mach-imx/busfreq_lpddr2.c linux-imx6-3.14/arch/arm/mach-imx/busfreq_lpddr2.c
  24003. --- linux-3.14.14/arch/arm/mach-imx/busfreq_lpddr2.c 1969-12-31 18:00:00.000000000 -0600
  24004. +++ linux-imx6-3.14/arch/arm/mach-imx/busfreq_lpddr2.c 2014-12-08 00:31:51.220418001 -0600
  24005. @@ -0,0 +1,183 @@
  24006. +/*
  24007. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  24008. + */
  24009. +
  24010. +/*
  24011. + * The code contained herein is licensed under the GNU General Public
  24012. + * License. You may obtain a copy of the GNU General Public License
  24013. + * Version 2 or later at the following locations:
  24014. + *
  24015. + * http://www.opensource.org/licenses/gpl-license.html
  24016. + * http://www.gnu.org/copyleft/gpl.html
  24017. + */
  24018. +
  24019. +/*!
  24020. + * @file busfreq_lpddr2.c
  24021. + *
  24022. + * @brief iMX6 LPDDR2 frequency change specific file.
  24023. + *
  24024. + * @ingroup PM
  24025. + */
  24026. +#include <asm/cacheflush.h>
  24027. +#include <asm/fncpy.h>
  24028. +#include <asm/io.h>
  24029. +#include <asm/mach/map.h>
  24030. +#include <asm/mach-types.h>
  24031. +#include <asm/tlb.h>
  24032. +#include <linux/clk.h>
  24033. +#include <linux/cpumask.h>
  24034. +#include <linux/delay.h>
  24035. +#include <linux/genalloc.h>
  24036. +#include <linux/interrupt.h>
  24037. +#include <linux/irqchip/arm-gic.h>
  24038. +#include <linux/kernel.h>
  24039. +#include <linux/mutex.h>
  24040. +#include <linux/of.h>
  24041. +#include <linux/of_address.h>
  24042. +#include <linux/of_device.h>
  24043. +#include <linux/platform_device.h>
  24044. +#include <linux/proc_fs.h>
  24045. +#include <linux/sched.h>
  24046. +#include <linux/smp.h>
  24047. +
  24048. +#include "hardware.h"
  24049. +
  24050. +/* DDR settings */
  24051. +static void __iomem *mmdc_base;
  24052. +static void __iomem *anatop_base;
  24053. +static void __iomem *ccm_base;
  24054. +static void __iomem *l2_base;
  24055. +static struct device *busfreq_dev;
  24056. +static void *ddr_freq_change_iram_base;
  24057. +static int curr_ddr_rate;
  24058. +
  24059. +unsigned long reg_addrs[4];
  24060. +
  24061. +void (*mx6_change_lpddr2_freq)(u32 ddr_freq, int bus_freq_mode,
  24062. + void *iram_addr) = NULL;
  24063. +
  24064. +extern unsigned int ddr_normal_rate;
  24065. +extern int low_bus_freq_mode;
  24066. +extern int ultra_low_bus_freq_mode;
  24067. +extern void mx6_lpddr2_freq_change(u32 freq, int bus_freq_mode,
  24068. + void *iram_addr);
  24069. +
  24070. +
  24071. +#define LPDDR2_FREQ_CHANGE_SIZE 0x1000
  24072. +
  24073. +
  24074. +/* change the DDR frequency. */
  24075. +int update_lpddr2_freq(int ddr_rate)
  24076. +{
  24077. + if (ddr_rate == curr_ddr_rate)
  24078. + return 0;
  24079. +
  24080. + dev_dbg(busfreq_dev, "\nBus freq set to %d start...\n", ddr_rate);
  24081. +
  24082. + /*
  24083. + * Flush the TLB, to ensure no TLB maintenance occurs
  24084. + * when DDR is in self-refresh.
  24085. + */
  24086. + local_flush_tlb_all();
  24087. + /* Now change DDR frequency. */
  24088. + mx6_change_lpddr2_freq(ddr_rate,
  24089. + (low_bus_freq_mode | ultra_low_bus_freq_mode),
  24090. + reg_addrs);
  24091. +
  24092. + curr_ddr_rate = ddr_rate;
  24093. +
  24094. + dev_dbg(busfreq_dev, "\nBus freq set to %d done...\n", ddr_rate);
  24095. +
  24096. + return 0;
  24097. +}
  24098. +
  24099. +int init_mmdc_lpddr2_settings(struct platform_device *busfreq_pdev)
  24100. +{
  24101. + struct platform_device *ocram_dev;
  24102. + unsigned int iram_paddr;
  24103. + struct device_node *node;
  24104. + struct gen_pool *iram_pool;
  24105. +
  24106. + busfreq_dev = &busfreq_pdev->dev;
  24107. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-mmdc");
  24108. + if (!node) {
  24109. + printk(KERN_ERR "failed to find imx6sl-mmdc device tree data!\n");
  24110. + return -EINVAL;
  24111. + }
  24112. + mmdc_base = of_iomap(node, 0);
  24113. + WARN(!mmdc_base, "unable to map mmdc registers\n");
  24114. +
  24115. + node = NULL;
  24116. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-ccm");
  24117. + if (!node) {
  24118. + printk(KERN_ERR "failed to find imx6sl-ccm device tree data!\n");
  24119. + return -EINVAL;
  24120. + }
  24121. + ccm_base = of_iomap(node, 0);
  24122. + WARN(!ccm_base, "unable to map ccm registers\n");
  24123. +
  24124. + node = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
  24125. + if (!node) {
  24126. + printk(KERN_ERR "failed to find imx6sl-pl310-cache device tree data!\n");
  24127. + return -EINVAL;
  24128. + }
  24129. + l2_base = of_iomap(node, 0);
  24130. + WARN(!l2_base, "unable to map PL310 registers\n");
  24131. +
  24132. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
  24133. + if (!node) {
  24134. + printk(KERN_ERR "failed to find imx6sl-pl310-cache device tree data!\n");
  24135. + return -EINVAL;
  24136. + }
  24137. + anatop_base = of_iomap(node, 0);
  24138. + WARN(!anatop_base, "unable to map anatop registers\n");
  24139. +
  24140. + node = NULL;
  24141. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  24142. + if (!node) {
  24143. + dev_err(busfreq_dev, "%s: failed to find ocram node\n",
  24144. + __func__);
  24145. + return -EINVAL;
  24146. + }
  24147. +
  24148. + ocram_dev = of_find_device_by_node(node);
  24149. + if (!ocram_dev) {
  24150. + dev_err(busfreq_dev, "failed to find ocram device!\n");
  24151. + return -EINVAL;
  24152. + }
  24153. +
  24154. + iram_pool = dev_get_gen_pool(&ocram_dev->dev);
  24155. + if (!iram_pool) {
  24156. + dev_err(busfreq_dev, "iram pool unavailable!\n");
  24157. + return -EINVAL;
  24158. + }
  24159. +
  24160. + reg_addrs[0] = (unsigned long)anatop_base;
  24161. + reg_addrs[1] = (unsigned long)ccm_base;
  24162. + reg_addrs[2] = (unsigned long)mmdc_base;
  24163. + reg_addrs[3] = (unsigned long)l2_base;
  24164. +
  24165. + ddr_freq_change_iram_base = (void *)gen_pool_alloc(iram_pool,
  24166. + LPDDR2_FREQ_CHANGE_SIZE);
  24167. + if (!ddr_freq_change_iram_base) {
  24168. + dev_err(busfreq_dev,
  24169. + "Cannot alloc iram for ddr freq change code!\n");
  24170. + return -ENOMEM;
  24171. + }
  24172. +
  24173. + iram_paddr = gen_pool_virt_to_phys(iram_pool,
  24174. + (unsigned long)ddr_freq_change_iram_base);
  24175. + /*
  24176. + * Need to remap the area here since we want
  24177. + * the memory region to be executable.
  24178. + */
  24179. + ddr_freq_change_iram_base = __arm_ioremap(iram_paddr,
  24180. + LPDDR2_FREQ_CHANGE_SIZE,
  24181. + MT_MEMORY_RWX_NONCACHED);
  24182. + mx6_change_lpddr2_freq = (void *)fncpy(ddr_freq_change_iram_base,
  24183. + &mx6_lpddr2_freq_change, LPDDR2_FREQ_CHANGE_SIZE);
  24184. +
  24185. + curr_ddr_rate = ddr_normal_rate;
  24186. +
  24187. + return 0;
  24188. +}
  24189. diff -Nur linux-3.14.14/arch/arm/mach-imx/clk.h linux-imx6-3.14/arch/arm/mach-imx/clk.h
  24190. --- linux-3.14.14/arch/arm/mach-imx/clk.h 2014-07-28 10:07:25.000000000 -0500
  24191. +++ linux-imx6-3.14/arch/arm/mach-imx/clk.h 2014-12-08 00:31:51.220418001 -0600
  24192. @@ -23,7 +23,8 @@
  24193. };
  24194. struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
  24195. - const char *parent_name, void __iomem *base, u32 div_mask);
  24196. + const char *parent_name, void __iomem *base,
  24197. + u32 div_mask, bool always_on);
  24198. struct clk *clk_register_gate2(struct device *dev, const char *name,
  24199. const char *parent_name, unsigned long flags,
  24200. diff -Nur linux-3.14.14/arch/arm/mach-imx/clk-imx6q.c linux-imx6-3.14/arch/arm/mach-imx/clk-imx6q.c
  24201. --- linux-3.14.14/arch/arm/mach-imx/clk-imx6q.c 2014-07-28 10:07:25.000000000 -0500
  24202. +++ linux-imx6-3.14/arch/arm/mach-imx/clk-imx6q.c 2014-12-08 00:31:51.220418001 -0600
  24203. @@ -1,5 +1,5 @@
  24204. /*
  24205. - * Copyright 2011-2013 Freescale Semiconductor, Inc.
  24206. + * Copyright 2011-2014 Freescale Semiconductor, Inc.
  24207. * Copyright 2011 Linaro Ltd.
  24208. *
  24209. * The code contained herein is licensed under the GNU General Public
  24210. @@ -24,6 +24,8 @@
  24211. #include "common.h"
  24212. #include "hardware.h"
  24213. +#define CCM_CCGR_OFFSET(index) (index * 2)
  24214. +
  24215. static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
  24216. static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
  24217. static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
  24218. @@ -39,6 +41,8 @@
  24219. static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", };
  24220. static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
  24221. static const char *ldb_di_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
  24222. +static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
  24223. +static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
  24224. 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", };
  24225. static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
  24226. static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
  24227. @@ -72,6 +76,10 @@
  24228. "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
  24229. "pcie_ref", "sata_ref",
  24230. };
  24231. +static const char *pll_av_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
  24232. +static void __iomem *anatop_base;
  24233. +static void __iomem *ccm_base;
  24234. +
  24235. enum mx6q_clks {
  24236. dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
  24237. @@ -88,11 +96,11 @@
  24238. periph_clk2, periph2_clk2, ipg, ipg_per, esai_pred, esai_podf,
  24239. asrc_pred, asrc_podf, spdif_pred, spdif_podf, can_root, ecspi_root,
  24240. gpu2d_core_podf, gpu3d_core_podf, gpu3d_shader, ipu1_podf, ipu2_podf,
  24241. - ldb_di0_podf, ldb_di1_podf, ipu1_di0_pre, ipu1_di1_pre, ipu2_di0_pre,
  24242. - ipu2_di1_pre, hsi_tx_podf, ssi1_pred, ssi1_podf, ssi2_pred, ssi2_podf,
  24243. - ssi3_pred, ssi3_podf, uart_serial_podf, usdhc1_podf, usdhc2_podf,
  24244. - usdhc3_podf, usdhc4_podf, enfc_pred, enfc_podf, emi_podf,
  24245. - emi_slow_podf, vpu_axi_podf, cko1_podf, axi, mmdc_ch0_axi_podf,
  24246. + ldb_di0_podf_unused, ldb_di1_podf_unused, ipu1_di0_pre, ipu1_di1_pre,
  24247. + ipu2_di0_pre, ipu2_di1_pre, hsi_tx_podf, ssi1_pred, ssi1_podf,
  24248. + ssi2_pred, ssi2_podf, ssi3_pred, ssi3_podf, uart_serial_podf,
  24249. + usdhc1_podf, usdhc2_podf, usdhc3_podf, usdhc4_podf, enfc_pred, enfc_podf,
  24250. + emi_podf, emi_slow_podf, vpu_axi_podf, cko1_podf, axi, mmdc_ch0_axi_podf,
  24251. mmdc_ch1_axi_podf, arm, ahb, apbh_dma, asrc, can1_ipg, can1_serial,
  24252. can2_ipg, can2_serial, ecspi1, ecspi2, ecspi3, ecspi4, ecspi5, enet,
  24253. esai, gpt_ipg, gpt_ipg_per, gpu2d_core, gpu3d_core, hdmi_iahb,
  24254. @@ -107,7 +115,10 @@
  24255. sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
  24256. usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow,
  24257. spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, pll4_audio_div,
  24258. - lvds1_sel, lvds2_sel, lvds1_gate, lvds2_gate, clk_max
  24259. + lvds1_sel, lvds2_sel, lvds1_gate, lvds2_gate, gpt_3m, video_27m,
  24260. + ldb_di0_div_7, ldb_di1_div_7, ldb_di0_div_sel, ldb_di1_div_sel,
  24261. + caam_mem, caam_aclk, caam_ipg, epit1, epit2, tzasc2, lvds1_in, lvds1_out,
  24262. + pll4_sel, lvds2_in, lvds2_out, anaclk1, anaclk2, clk_max
  24263. };
  24264. static struct clk *clk[clk_max];
  24265. @@ -140,20 +151,131 @@
  24266. { /* sentinel */ }
  24267. };
  24268. +static void init_ldb_clks(enum mx6q_clks new_parent)
  24269. +{
  24270. + u32 reg;
  24271. +
  24272. + /*
  24273. + * Need to follow a strict procedure when changing the LDB
  24274. + * clock, else we can introduce a glitch. Things to keep in
  24275. + * mind:
  24276. + * 1. The current and new parent clocks must be disabled.
  24277. + * 2. The default clock for ldb_dio_clk is mmdc_ch1 which has
  24278. + * no CG bit.
  24279. + * 3. In the RTL implementation of the LDB_DI_CLK_SEL mux
  24280. + * the top four options are in one mux and the PLL3 option along
  24281. + * with another option is in the second mux. There is third mux
  24282. + * used to decide between the first and second mux.
  24283. + * The code below switches the parent to the bottom mux first
  24284. + * and then manipulates the top mux. This ensures that no glitch
  24285. + * will enter the divider.
  24286. + *
  24287. + * Need to disable MMDC_CH1 clock manually as there is no CG bit
  24288. + * for this clock. The only way to disable this clock is to move
  24289. + * it topll3_sw_clk and then to disable pll3_sw_clk
  24290. + * Make sure periph2_clk2_sel is set to pll3_sw_clk
  24291. + */
  24292. + reg = readl_relaxed(ccm_base + 0x18);
  24293. + reg &= ~(1 << 20);
  24294. + writel_relaxed(reg, ccm_base + 0x18);
  24295. +
  24296. + /*
  24297. + * Set MMDC_CH1 mask bit.
  24298. + */
  24299. + reg = readl_relaxed(ccm_base + 0x4);
  24300. + reg |= 1 << 16;
  24301. + writel_relaxed(reg, ccm_base + 0x4);
  24302. +
  24303. + /*
  24304. + * Set the periph2_clk_sel to the top mux so that
  24305. + * mmdc_ch1 is from pll3_sw_clk.
  24306. + */
  24307. + reg = readl_relaxed(ccm_base + 0x14);
  24308. + reg |= 1 << 26;
  24309. + writel_relaxed(reg, ccm_base + 0x14);
  24310. +
  24311. + /*
  24312. + * Wait for the clock switch.
  24313. + */
  24314. + while (readl_relaxed(ccm_base + 0x48))
  24315. + ;
  24316. +
  24317. + /*
  24318. + * Disable pll3_sw_clk by selecting the bypass clock source.
  24319. + */
  24320. + reg = readl_relaxed(ccm_base + 0xc);
  24321. + reg |= 1 << 0;
  24322. + writel_relaxed(reg, ccm_base + 0xc);
  24323. +
  24324. + /*
  24325. + * Set the ldb_di0_clk and ldb_di1_clk to 111b.
  24326. + */
  24327. + reg = readl_relaxed(ccm_base + 0x2c);
  24328. + reg |= ((7 << 9) | (7 << 12));
  24329. + writel_relaxed(reg, ccm_base + 0x2c);
  24330. +
  24331. + /*
  24332. + * Set the ldb_di0_clk and ldb_di1_clk to 100b.
  24333. + */
  24334. + reg = readl_relaxed(ccm_base + 0x2c);
  24335. + reg &= ~((7 << 9) | (7 << 12));
  24336. + reg |= ((4 << 9) | (4 << 12));
  24337. + writel_relaxed(reg, ccm_base + 0x2c);
  24338. +
  24339. + /*
  24340. + * Perform the LDB parent clock switch.
  24341. + */
  24342. + clk_set_parent(clk[ldb_di0_sel], clk[new_parent]);
  24343. + clk_set_parent(clk[ldb_di1_sel], clk[new_parent]);
  24344. +
  24345. + /*
  24346. + * Unbypass pll3_sw_clk.
  24347. + */
  24348. + reg = readl_relaxed(ccm_base + 0xc);
  24349. + reg &= ~(1 << 0);
  24350. + writel_relaxed(reg, ccm_base + 0xc);
  24351. +
  24352. + /*
  24353. + * Set the periph2_clk_sel back to the bottom mux so that
  24354. + * mmdc_ch1 is from its original parent.
  24355. + */
  24356. + reg = readl_relaxed(ccm_base + 0x14);
  24357. + reg &= ~(1 << 26);
  24358. + writel_relaxed(reg, ccm_base + 0x14);
  24359. +
  24360. + /*
  24361. + * Wait for the clock switch.
  24362. + */
  24363. + while (readl_relaxed(ccm_base + 0x48))
  24364. + ;
  24365. +
  24366. + /*
  24367. + * Clear MMDC_CH1 mask bit.
  24368. + */
  24369. + reg = readl_relaxed(ccm_base + 0x4);
  24370. + reg &= ~(1 << 16);
  24371. + writel_relaxed(reg, ccm_base + 0x4);
  24372. +
  24373. +}
  24374. +
  24375. static void __init imx6q_clocks_init(struct device_node *ccm_node)
  24376. {
  24377. struct device_node *np;
  24378. void __iomem *base;
  24379. int i, irq;
  24380. int ret;
  24381. + u32 reg;
  24382. clk[dummy] = imx_clk_fixed("dummy", 0);
  24383. clk[ckil] = imx_obtain_fixed_clock("ckil", 0);
  24384. clk[ckih] = imx_obtain_fixed_clock("ckih1", 0);
  24385. clk[osc] = imx_obtain_fixed_clock("osc", 0);
  24386. + /* Clock source from external clock via ANACLK1/2 PADs */
  24387. + clk[anaclk1] = imx_obtain_fixed_clock("anaclk1", 0);
  24388. + clk[anaclk2] = imx_obtain_fixed_clock("anaclk2", 0);
  24389. np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
  24390. - base = of_iomap(np, 0);
  24391. + anatop_base = base = of_iomap(np, 0);
  24392. WARN_ON(!base);
  24393. /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
  24394. @@ -165,13 +287,18 @@
  24395. };
  24396. /* type name parent_name base div_mask */
  24397. - clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
  24398. - clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
  24399. - clk[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3);
  24400. - clk[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f);
  24401. - clk[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
  24402. - clk[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
  24403. - clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3);
  24404. + clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f, false);
  24405. + clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1, false);
  24406. + clk[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3, false);
  24407. + clk[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "pll4_sel", base + 0x70, 0x7f, false);
  24408. + clk[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f, false);
  24409. + clk[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3, false);
  24410. + clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3, false);
  24411. +
  24412. + /* name reg shift width parent_names num_parents */
  24413. + clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24414. + clk[lvds2_sel] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24415. + clk[pll4_sel] = imx_clk_mux("pll4_sel", base + 0x70, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
  24416. /*
  24417. * Bit 20 is the reserved and read-only bit, we do this only for:
  24418. @@ -191,6 +318,11 @@
  24419. clk[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
  24420. clk[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
  24421. + /* NOTICE: The gate of the lvds1/2 in/out is used to select the clk direction */
  24422. + clk[lvds1_in] = imx_clk_gate("lvds1_in", "anaclk1", base + 0x160, 12);
  24423. + clk[lvds2_in] = imx_clk_gate("lvds2_in", "anaclk2", base + 0x160, 13);
  24424. + clk[lvds1_out] = imx_clk_gate("lvds1_out", "lvds1_sel", base + 0x160, 10);
  24425. + clk[lvds2_out] = imx_clk_gate("lvds2_out", "lvds2_sel", base + 0x160, 11);
  24426. clk[sata_ref_100m] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
  24427. clk[pcie_ref_125m] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
  24428. @@ -199,18 +331,6 @@
  24429. base + 0xe0, 0, 2, 0, clk_enet_ref_table,
  24430. &imx_ccm_lock);
  24431. - clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24432. - clk[lvds2_sel] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24433. -
  24434. - /*
  24435. - * lvds1_gate and lvds2_gate are pseudo-gates. Both can be
  24436. - * independently configured as clock inputs or outputs. We treat
  24437. - * the "output_enable" bit as a gate, even though it's really just
  24438. - * enabling clock output.
  24439. - */
  24440. - clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "dummy", base + 0x160, 10);
  24441. - clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "dummy", base + 0x160, 11);
  24442. -
  24443. /* name parent_name reg idx */
  24444. clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
  24445. clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
  24446. @@ -226,6 +346,8 @@
  24447. clk[pll3_80m] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
  24448. clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
  24449. clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2);
  24450. + clk[gpt_3m] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
  24451. + clk[video_27m] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20);
  24452. 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);
  24453. 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);
  24454. @@ -233,7 +355,7 @@
  24455. 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);
  24456. np = ccm_node;
  24457. - base = of_iomap(np, 0);
  24458. + ccm_base = base = of_iomap(np, 0);
  24459. WARN_ON(!base);
  24460. imx6q_pm_set_ccm_base(base);
  24461. @@ -258,14 +380,16 @@
  24462. clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
  24463. 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);
  24464. 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);
  24465. - 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));
  24466. - 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));
  24467. - 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));
  24468. - 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));
  24469. - clk[ipu1_di0_sel] = imx_clk_mux("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels));
  24470. - clk[ipu1_di1_sel] = imx_clk_mux("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels));
  24471. - clk[ipu2_di0_sel] = imx_clk_mux("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels));
  24472. - clk[ipu2_di1_sel] = imx_clk_mux("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels));
  24473. + 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);
  24474. + 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);
  24475. + 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);
  24476. + 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);
  24477. + 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);
  24478. + 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);
  24479. + 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);
  24480. + 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);
  24481. + 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);
  24482. + 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);
  24483. clk[hsi_tx_sel] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels));
  24484. clk[pcie_axi_sel] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
  24485. clk[ssi1_sel] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
  24486. @@ -307,9 +431,9 @@
  24487. clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
  24488. clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
  24489. clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
  24490. - clk[ldb_di0_podf] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
  24491. + clk[ldb_di0_div_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7);
  24492. clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
  24493. - clk[ldb_di1_podf] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0);
  24494. + clk[ldb_di1_div_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7);
  24495. clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3);
  24496. clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3);
  24497. clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3);
  24498. @@ -344,6 +468,9 @@
  24499. /* name parent_name reg shift */
  24500. clk[apbh_dma] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4);
  24501. clk[asrc] = imx_clk_gate2("asrc", "asrc_podf", base + 0x68, 6);
  24502. + clk[caam_mem] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8);
  24503. + clk[caam_aclk] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
  24504. + clk[caam_ipg] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
  24505. clk[can1_ipg] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
  24506. clk[can1_serial] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16);
  24507. clk[can2_ipg] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
  24508. @@ -354,6 +481,8 @@
  24509. clk[ecspi4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
  24510. clk[ecspi5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8);
  24511. clk[enet] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
  24512. + clk[epit1] = imx_clk_gate2("epit1", "ipg", base + 0x6c, 12);
  24513. + clk[epit2] = imx_clk_gate2("epit2", "ipg", base + 0x6c, 14);
  24514. clk[esai] = imx_clk_gate2("esai", "esai_podf", base + 0x6c, 16);
  24515. clk[gpt_ipg] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
  24516. clk[gpt_ipg_per] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
  24517. @@ -373,15 +502,16 @@
  24518. clk[i2c3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10);
  24519. clk[iim] = imx_clk_gate2("iim", "ipg", base + 0x70, 12);
  24520. clk[enfc] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14);
  24521. + clk[tzasc2] = imx_clk_gate2("tzasc2", "mmdc_ch0_axi_podf", base + 0x70, 24);
  24522. clk[vdoa] = imx_clk_gate2("vdoa", "vdo_axi", base + 0x70, 26);
  24523. clk[ipu1] = imx_clk_gate2("ipu1", "ipu1_podf", base + 0x74, 0);
  24524. clk[ipu1_di0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", base + 0x74, 2);
  24525. clk[ipu1_di1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4);
  24526. clk[ipu2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6);
  24527. clk[ipu2_di0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8);
  24528. - clk[ldb_di0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12);
  24529. - clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14);
  24530. clk[ipu2_di1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10);
  24531. + clk[ldb_di0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12);
  24532. + clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_div_sel", base + 0x74, 14);
  24533. clk[hsi_tx] = imx_clk_gate2("hsi_tx", "hsi_tx_podf", base + 0x74, 16);
  24534. if (cpu_is_imx6dl())
  24535. /*
  24536. @@ -413,6 +543,9 @@
  24537. clk[ssi1_ipg] = imx_clk_gate2("ssi1_ipg", "ipg", base + 0x7c, 18);
  24538. clk[ssi2_ipg] = imx_clk_gate2("ssi2_ipg", "ipg", base + 0x7c, 20);
  24539. clk[ssi3_ipg] = imx_clk_gate2("ssi3_ipg", "ipg", base + 0x7c, 22);
  24540. + clk[ssi1] = imx_clk_gate2("ssi1", "ssi1_podf", base + 0x7c, 18);
  24541. + clk[ssi2] = imx_clk_gate2("ssi2", "ssi2_podf", base + 0x7c, 20);
  24542. + clk[ssi3] = imx_clk_gate2("ssi3", "ssi3_podf", base + 0x7c, 22);
  24543. clk[uart_ipg] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
  24544. clk[uart_serial] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26);
  24545. clk[usboh3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
  24546. @@ -431,25 +564,79 @@
  24547. pr_err("i.MX6q clk %d: register failed with %ld\n",
  24548. i, PTR_ERR(clk[i]));
  24549. + /* Initialize clock gate status */
  24550. + writel_relaxed(1 << CCM_CCGR_OFFSET(11) |
  24551. + 3 << CCM_CCGR_OFFSET(1) |
  24552. + 3 << CCM_CCGR_OFFSET(0), base + 0x68);
  24553. + if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0)
  24554. + writel_relaxed(3 << CCM_CCGR_OFFSET(11) |
  24555. + 3 << CCM_CCGR_OFFSET(10), base + 0x6c);
  24556. + else
  24557. + writel_relaxed(3 << CCM_CCGR_OFFSET(10), base + 0x6c);
  24558. + writel_relaxed(1 << CCM_CCGR_OFFSET(12) |
  24559. + 3 << CCM_CCGR_OFFSET(11) |
  24560. + 3 << CCM_CCGR_OFFSET(10) |
  24561. + 3 << CCM_CCGR_OFFSET(9) |
  24562. + 3 << CCM_CCGR_OFFSET(8), base + 0x70);
  24563. + writel_relaxed(3 << CCM_CCGR_OFFSET(14) |
  24564. + 1 << CCM_CCGR_OFFSET(13) |
  24565. + 3 << CCM_CCGR_OFFSET(12) |
  24566. + 1 << CCM_CCGR_OFFSET(11) |
  24567. + 3 << CCM_CCGR_OFFSET(10), base + 0x74);
  24568. + writel_relaxed(3 << CCM_CCGR_OFFSET(7) |
  24569. + 3 << CCM_CCGR_OFFSET(6) |
  24570. + 3 << CCM_CCGR_OFFSET(4), base + 0x78);
  24571. + writel_relaxed(1 << CCM_CCGR_OFFSET(0), base + 0x7c);
  24572. + writel_relaxed(0, base + 0x80);
  24573. +
  24574. + /* Make sure PFDs are disabled at boot. */
  24575. + reg = readl_relaxed(anatop_base + 0x100);
  24576. + /* Cannot disable pll2_pfd2_396M, as it is the MMDC clock in iMX6DL */
  24577. + if (cpu_is_imx6dl())
  24578. + reg |= 0x80008080;
  24579. + else
  24580. + reg |= 0x80808080;
  24581. + writel_relaxed(reg, anatop_base + 0x100);
  24582. +
  24583. + /* Disable PLL3 PFDs. */
  24584. + reg = readl_relaxed(anatop_base + 0xF0);
  24585. + reg |= 0x80808080;
  24586. + writel_relaxed(reg, anatop_base + 0xF0);
  24587. +
  24588. + /* Make sure PLLs is disabled */
  24589. + reg = readl_relaxed(anatop_base + 0xA0);
  24590. + reg &= ~(1 << 13);
  24591. + writel_relaxed(reg, anatop_base + 0xA0);
  24592. +
  24593. clk_data.clks = clk;
  24594. clk_data.clk_num = ARRAY_SIZE(clk);
  24595. of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
  24596. clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0");
  24597. clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
  24598. + clk_register_clkdev(clk[gpt_3m], "gpt_3m", "imx-gpt.0");
  24599. clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL);
  24600. clk_register_clkdev(clk[ahb], "ahb", NULL);
  24601. clk_register_clkdev(clk[cko1], "cko1", NULL);
  24602. clk_register_clkdev(clk[arm], NULL, "cpu0");
  24603. - clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL);
  24604. - clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL);
  24605. + clk_register_clkdev(clk[pll4_audio_div], "pll4_audio_div", NULL);
  24606. + clk_register_clkdev(clk[pll4_sel], "pll4_sel", NULL);
  24607. + clk_register_clkdev(clk[lvds2_in], "lvds2_in", NULL);
  24608. + clk_register_clkdev(clk[esai], "esai", NULL);
  24609. - if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
  24610. - cpu_is_imx6dl()) {
  24611. - clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
  24612. - clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
  24613. + if (cpu_is_imx6dl()) {
  24614. + clk_set_parent(clk[ipu1_sel], clk[pll3_pfd1_540m]);
  24615. }
  24616. + clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]);
  24617. + clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]);
  24618. + clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]);
  24619. + clk_set_parent(clk[ipu2_di1_pre_sel], clk[pll5_video_div]);
  24620. + clk_set_parent(clk[ipu1_di0_sel], clk[ipu1_di0_pre]);
  24621. + clk_set_parent(clk[ipu1_di1_sel], clk[ipu1_di1_pre]);
  24622. + clk_set_parent(clk[ipu2_di0_sel], clk[ipu2_di0_pre]);
  24623. + clk_set_parent(clk[ipu2_di1_sel], clk[ipu2_di1_pre]);
  24624. +
  24625. /*
  24626. * The gpmi needs 100MHz frequency in the EDO/Sync mode,
  24627. * We can not get the 100MHz from the pll2_pfd0_352m.
  24628. @@ -457,6 +644,19 @@
  24629. */
  24630. clk_set_parent(clk[enfc_sel], clk[pll2_pfd2_396m]);
  24631. + /* Set the parent clks of PCIe lvds1 and pcie_axi to be sata ref, axi */
  24632. + if (clk_set_parent(clk[lvds1_sel], clk[sata_ref]))
  24633. + pr_err("Failed to set PCIe bus parent clk.\n");
  24634. + if (clk_set_parent(clk[pcie_axi_sel], clk[axi]))
  24635. + pr_err("Failed to set PCIe parent clk.\n");
  24636. +
  24637. + /* gpu clock initilazation */
  24638. + clk_set_parent(clk[gpu3d_shader_sel], clk[pll2_pfd1_594m]);
  24639. + clk_set_rate(clk[gpu3d_shader], 594000000);
  24640. + clk_set_parent(clk[gpu3d_core_sel], clk[mmdc_ch0_axi]);
  24641. + clk_set_rate(clk[gpu3d_core], 528000000);
  24642. + clk_set_parent(clk[gpu2d_core_sel], clk[pll3_usb_otg]);
  24643. +
  24644. for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
  24645. clk_prepare_enable(clk[clks_init_on[i]]);
  24646. @@ -465,6 +665,25 @@
  24647. clk_prepare_enable(clk[usbphy2_gate]);
  24648. }
  24649. + /* ipu clock initialization */
  24650. + init_ldb_clks(pll2_pfd0_352m);
  24651. + clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]);
  24652. + clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]);
  24653. + clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]);
  24654. + clk_set_parent(clk[ipu2_di1_pre_sel], clk[pll5_video_div]);
  24655. + clk_set_parent(clk[ipu1_di0_sel], clk[ipu1_di0_pre]);
  24656. + clk_set_parent(clk[ipu1_di1_sel], clk[ipu1_di1_pre]);
  24657. + clk_set_parent(clk[ipu2_di0_sel], clk[ipu2_di0_pre]);
  24658. + clk_set_parent(clk[ipu2_di1_sel], clk[ipu2_di1_pre]);
  24659. + if (cpu_is_imx6dl()) {
  24660. + clk_set_rate(clk[pll3_pfd1_540m], 540000000);
  24661. + clk_set_parent(clk[ipu1_sel], clk[pll3_pfd1_540m]);
  24662. + clk_set_parent(clk[axi_sel], clk[pll3_pfd1_540m]);
  24663. + } else if (cpu_is_imx6q()) {
  24664. + clk_set_parent(clk[ipu1_sel], clk[mmdc_ch0_axi]);
  24665. + clk_set_parent(clk[ipu2_sel], clk[mmdc_ch0_axi]);
  24666. + }
  24667. +
  24668. /*
  24669. * Let's initially set up CLKO with OSC24M, since this configuration
  24670. * is widely used by imx6q board designs to clock audio codec.
  24671. @@ -482,6 +701,18 @@
  24672. if (IS_ENABLED(CONFIG_PCI_IMX6))
  24673. clk_set_parent(clk[lvds1_sel], clk[sata_ref]);
  24674. + /* Audio clocks */
  24675. + clk_set_parent(clk[ssi1_sel], clk[pll4_audio_div]);
  24676. + clk_set_parent(clk[ssi2_sel], clk[pll4_audio_div]);
  24677. + clk_set_parent(clk[ssi3_sel], clk[pll4_audio_div]);
  24678. + clk_set_parent(clk[esai_sel], clk[pll4_audio_div]);
  24679. + clk_set_parent(clk[spdif_sel], clk[pll3_pfd3_454m]);
  24680. + clk_set_parent(clk[asrc_sel], clk[pll3_usb_otg]);
  24681. + clk_set_rate(clk[asrc_sel], 7500000);
  24682. +
  24683. + /* Set pll4_audio to a value that can derive 5K-88.2KHz and 8K-96KHz */
  24684. + clk_set_rate(clk[pll4_audio_div], 541900800);
  24685. +
  24686. /* Set initial power mode */
  24687. imx6q_set_lpm(WAIT_CLOCKED);
  24688. diff -Nur linux-3.14.14/arch/arm/mach-imx/clk-imx6sl.c linux-imx6-3.14/arch/arm/mach-imx/clk-imx6sl.c
  24689. --- linux-3.14.14/arch/arm/mach-imx/clk-imx6sl.c 2014-07-28 10:07:25.000000000 -0500
  24690. +++ linux-imx6-3.14/arch/arm/mach-imx/clk-imx6sl.c 2014-12-08 00:31:51.220418001 -0600
  24691. @@ -7,9 +7,29 @@
  24692. *
  24693. */
  24694. +#define CCM_CCDR_OFFSET 0x4
  24695. +#define ANATOP_PLL_USB1 0x10
  24696. +#define ANATOP_PLL_USB2 0x20
  24697. +#define ANATOP_PLL_ENET 0xE0
  24698. +#define ANATOP_PLL_BYPASS_OFFSET (1 << 16)
  24699. +#define ANATOP_PLL_ENABLE_OFFSET (1 << 13)
  24700. +#define ANATOP_PLL_POWER_OFFSET (1 << 12)
  24701. +#define ANATOP_PFD_480n_OFFSET 0xf0
  24702. +#define ANATOP_PFD_528n_OFFSET 0x100
  24703. +#define PFD0_CLKGATE (1 << 7)
  24704. +#define PFD1_CLK_GATE (1 << 15)
  24705. +#define PFD2_CLK_GATE (1 << 23)
  24706. +#define PFD3_CLK_GATE (1 << 31)
  24707. +#define CCDR_CH0_HS_BYP 17
  24708. +#define OSC_RATE 24000000
  24709. +
  24710. +#define CCM_CCGR_OFFSET(index) (index * 2)
  24711. +
  24712. #include <linux/clk.h>
  24713. #include <linux/clkdev.h>
  24714. #include <linux/err.h>
  24715. +#include <linux/init.h>
  24716. +#include <linux/io.h>
  24717. #include <linux/of.h>
  24718. #include <linux/of_address.h>
  24719. #include <linux/of_irq.h>
  24720. @@ -18,6 +38,7 @@
  24721. #include "clk.h"
  24722. #include "common.h"
  24723. +static bool uart_from_osc;
  24724. static const char const *step_sels[] = { "osc", "pll2_pfd2", };
  24725. static const char const *pll1_sw_sels[] = { "pll1_sys", "step", };
  24726. static const char const *ocram_alt_sels[] = { "pll2_pfd2", "pll3_pfd1", };
  24727. @@ -25,8 +46,8 @@
  24728. static const char const *pre_periph_sels[] = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", };
  24729. static const char const *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", };
  24730. static const char const *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
  24731. -static const char const *periph_sels[] = { "pre_periph_sel", "periph_clk2_podf", };
  24732. -static const char const *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2_podf", };
  24733. +static const char const *periph_sels[] = { "pre_periph_sel", "periph_clk2", };
  24734. +static const char const *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2", };
  24735. static const char const *csi_lcdif_sels[] = { "mmdc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
  24736. static const char const *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", };
  24737. static const char const *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", };
  24738. @@ -38,7 +59,7 @@
  24739. static const char const *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", };
  24740. static const char const *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", };
  24741. static const char const *ecspi_sels[] = { "pll3_60m", "osc", };
  24742. -static const char const *uart_sels[] = { "pll3_80m", "osc", };
  24743. +static const char const *uart_sels[] = { "pll3_80m", "uart_osc_4M", };
  24744. static struct clk_div_table clk_enet_ref_table[] = {
  24745. { .val = 0, .div = 20, },
  24746. @@ -65,6 +86,80 @@
  24747. static struct clk *clks[IMX6SL_CLK_END];
  24748. static struct clk_onecell_data clk_data;
  24749. +static u32 cur_arm_podf;
  24750. +static u32 pll1_org_rate;
  24751. +
  24752. +extern int low_bus_freq_mode;
  24753. +extern int audio_bus_freq_mode;
  24754. +
  24755. +/*
  24756. + * On MX6SL, need to ensure that the ARM:IPG clock ratio is maintained
  24757. + * within 12:5 when the clocks to ARM are gated when the SOC enters
  24758. + * WAIT mode. This is necessary to avoid WAIT mode issue (an early
  24759. + * interrupt waking up the ARM).
  24760. + * This function will set the ARM clk to max value within the 12:5 limit.
  24761. + */
  24762. +void imx6sl_set_wait_clk(bool enter)
  24763. +{
  24764. + u32 parent_rate;
  24765. +
  24766. + if (enter) {
  24767. + u32 wait_podf;
  24768. + u32 new_parent_rate = OSC_RATE;
  24769. + u32 ipg_rate = clk_get_rate(clks[IMX6SL_CLK_IPG]);
  24770. + u32 max_arm_wait_clk = (12 * ipg_rate) / 5;
  24771. + parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
  24772. + cur_arm_podf = parent_rate / clk_get_rate(clks[IMX6SL_CLK_ARM]);
  24773. + if (low_bus_freq_mode) {
  24774. + /*
  24775. + * IPG clk is at 12MHz at this point, we can only run
  24776. + * ARM at a max of 28.8MHz. So we need to set ARM
  24777. + * to run from the 24MHz OSC, as there is no way to
  24778. + * get 28.8MHz when ARM is sourced from PLL1.
  24779. + */
  24780. + clk_set_parent(clks[IMX6SL_CLK_STEP],
  24781. + clks[IMX6SL_CLK_OSC]);
  24782. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW],
  24783. + clks[IMX6SL_CLK_STEP]);
  24784. + } else if (audio_bus_freq_mode) {
  24785. + /*
  24786. + * In this mode ARM is from PLL2_PFD2 (396MHz),
  24787. + * but IPG is at 12MHz. Need to switch ARM to run
  24788. + * from the bypassed PLL1 clocks so that we can run
  24789. + * ARM at 24MHz.
  24790. + */
  24791. + pll1_org_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SYS]);
  24792. + /* Ensure PLL1 is at 24MHz. */
  24793. + clk_set_rate(clks[IMX6SL_CLK_PLL1_SYS], OSC_RATE);
  24794. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW], clks[IMX6SL_CLK_PLL1_SYS]);
  24795. + } else
  24796. + new_parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
  24797. + wait_podf = (new_parent_rate + max_arm_wait_clk - 1) /
  24798. + max_arm_wait_clk;
  24799. +
  24800. + clk_set_rate(clks[IMX6SL_CLK_ARM], new_parent_rate / wait_podf);
  24801. + } else {
  24802. + if (low_bus_freq_mode)
  24803. + /* Move ARM back to PLL1. */
  24804. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW],
  24805. + clks[IMX6SL_CLK_PLL1_SYS]);
  24806. + else if (audio_bus_freq_mode) {
  24807. + /* Move ARM back to PLL2_PFD2 via STEP_CLK. */
  24808. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW], clks[IMX6SL_CLK_STEP]);
  24809. + clk_set_rate(clks[IMX6SL_CLK_PLL1_SYS], pll1_org_rate);
  24810. + }
  24811. + parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
  24812. + clk_set_rate(clks[IMX6SL_CLK_ARM], parent_rate / cur_arm_podf);
  24813. + }
  24814. +}
  24815. +
  24816. +static int __init setup_uart_clk(char *uart_rate)
  24817. +{
  24818. + uart_from_osc = true;
  24819. + return 1;
  24820. +}
  24821. +
  24822. +__setup("uart_at_4M", setup_uart_clk);
  24823. static void __init imx6sl_clocks_init(struct device_node *ccm_node)
  24824. {
  24825. @@ -72,6 +167,8 @@
  24826. void __iomem *base;
  24827. int irq;
  24828. int i;
  24829. + int ret;
  24830. + u32 reg;
  24831. clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
  24832. clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
  24833. @@ -82,13 +179,18 @@
  24834. WARN_ON(!base);
  24835. /* type name parent base div_mask */
  24836. - clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
  24837. - clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
  24838. - clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3);
  24839. - clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f);
  24840. - clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
  24841. - clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
  24842. - clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3);
  24843. + clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f, true);
  24844. + clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1, true);
  24845. + clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3, false);
  24846. + clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f, false);
  24847. + clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f, false);
  24848. + clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3, false);
  24849. + clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3, false);
  24850. +
  24851. + /* Ensure the AHB clk is at 132MHz. */
  24852. + ret = clk_set_rate(clks[IMX6SL_CLK_AHB], 132000000);
  24853. + if (ret)
  24854. + pr_warn("%s: failed to set AHB clock rate %d\n", __func__, ret);
  24855. /*
  24856. * usbphy1 and usbphy2 are implemented as dummy gates using reserve
  24857. @@ -118,11 +220,36 @@
  24858. clks[IMX6SL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", base + 0xf0, 2);
  24859. clks[IMX6SL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", base + 0xf0, 3);
  24860. - /* name parent_name mult div */
  24861. - clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2);
  24862. - clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
  24863. - clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
  24864. - clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
  24865. + /* name parent_name mult div */
  24866. + clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2);
  24867. + clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
  24868. + clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
  24869. + clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
  24870. + clks[IMX6SL_CLK_UART_OSC_4M] = imx_clk_fixed_factor("uart_osc_4M", "osc", 1, 6);
  24871. +
  24872. + /* Ensure all PFDs but PLL2_PFD2 are disabled. */
  24873. + reg = readl_relaxed(base + ANATOP_PFD_480n_OFFSET);
  24874. + reg |= (PFD0_CLKGATE | PFD1_CLK_GATE | PFD2_CLK_GATE | PFD3_CLK_GATE);
  24875. + writel_relaxed(reg, base + ANATOP_PFD_480n_OFFSET);
  24876. + reg = readl_relaxed(base + ANATOP_PFD_528n_OFFSET);
  24877. + reg |= (PFD0_CLKGATE | PFD1_CLK_GATE);
  24878. + writel_relaxed(reg, base + ANATOP_PFD_528n_OFFSET);
  24879. +
  24880. + /* Ensure Unused PLLs are disabled. */
  24881. + reg = readl_relaxed(base + ANATOP_PLL_USB1);
  24882. + reg |= ANATOP_PLL_BYPASS_OFFSET;
  24883. + reg &= ~(ANATOP_PLL_ENABLE_OFFSET | ANATOP_PLL_POWER_OFFSET);
  24884. + writel_relaxed(reg, base + ANATOP_PLL_USB1);
  24885. +
  24886. + reg = readl_relaxed(base + ANATOP_PLL_USB2);
  24887. + reg |= ANATOP_PLL_BYPASS_OFFSET;
  24888. + reg &= ~(ANATOP_PLL_ENABLE_OFFSET | ANATOP_PLL_POWER_OFFSET);
  24889. + writel_relaxed(reg, base + ANATOP_PLL_USB2);
  24890. +
  24891. + reg = readl_relaxed(base + ANATOP_PLL_ENET);
  24892. + reg |= (ANATOP_PLL_BYPASS_OFFSET | ANATOP_PLL_POWER_OFFSET);
  24893. + reg &= ~ANATOP_PLL_ENABLE_OFFSET;
  24894. + writel_relaxed(reg, base + ANATOP_PLL_ENET);
  24895. np = ccm_node;
  24896. base = of_iomap(np, 0);
  24897. @@ -158,7 +285,7 @@
  24898. clks[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_mux("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels));
  24899. clks[IMX6SL_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
  24900. clks[IMX6SL_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
  24901. - clks[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
  24902. + 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);
  24903. clks[IMX6SL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
  24904. clks[IMX6SL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
  24905. @@ -168,8 +295,8 @@
  24906. /* name parent_name reg shift width */
  24907. clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3);
  24908. - clks[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3);
  24909. - clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3);
  24910. + clks[IMX6SL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
  24911. + clks[IMX6SL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
  24912. clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
  24913. clks[IMX6SL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
  24914. clks[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3);
  24915. @@ -251,6 +378,25 @@
  24916. pr_err("i.MX6SL clk %d: register failed with %ld\n",
  24917. i, PTR_ERR(clks[i]));
  24918. + /* Initialize clock gate status */
  24919. + writel_relaxed(1 << CCM_CCGR_OFFSET(11) |
  24920. + 3 << CCM_CCGR_OFFSET(1) |
  24921. + 3 << CCM_CCGR_OFFSET(0), base + 0x68);
  24922. + writel_relaxed(3 << CCM_CCGR_OFFSET(10), base + 0x6c);
  24923. + writel_relaxed(1 << CCM_CCGR_OFFSET(11) |
  24924. + 3 << CCM_CCGR_OFFSET(10) |
  24925. + 3 << CCM_CCGR_OFFSET(9) |
  24926. + 3 << CCM_CCGR_OFFSET(8), base + 0x70);
  24927. + writel_relaxed(3 << CCM_CCGR_OFFSET(14) |
  24928. + 3 << CCM_CCGR_OFFSET(13) |
  24929. + 3 << CCM_CCGR_OFFSET(12) |
  24930. + 3 << CCM_CCGR_OFFSET(11) |
  24931. + 3 << CCM_CCGR_OFFSET(10), base + 0x74);
  24932. + writel_relaxed(3 << CCM_CCGR_OFFSET(7) |
  24933. + 3 << CCM_CCGR_OFFSET(4), base + 0x78);
  24934. + writel_relaxed(1 << CCM_CCGR_OFFSET(0), base + 0x7c);
  24935. + writel_relaxed(0, base + 0x80);
  24936. +
  24937. clk_data.clks = clks;
  24938. clk_data.clk_num = ARRAY_SIZE(clks);
  24939. of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
  24940. @@ -258,17 +404,58 @@
  24941. clk_register_clkdev(clks[IMX6SL_CLK_GPT], "ipg", "imx-gpt.0");
  24942. clk_register_clkdev(clks[IMX6SL_CLK_GPT_SERIAL], "per", "imx-gpt.0");
  24943. + /*
  24944. + * Make sure the ARM clk is enabled to maintain the correct usecount
  24945. + * and enabling/disabling of parent PLLs.
  24946. + */
  24947. + ret = clk_prepare_enable(clks[IMX6SL_CLK_ARM]);
  24948. + if (ret)
  24949. + pr_warn("%s: failed to enable ARM core clock %d\n",
  24950. + __func__, ret);
  24951. +
  24952. + /*
  24953. + * Make sure the MMDC clk is enabled to maintain the correct usecount
  24954. + * and enabling/disabling of parent PLLs.
  24955. + */
  24956. + ret = clk_prepare_enable(clks[IMX6SL_CLK_MMDC_ROOT]);
  24957. + if (ret)
  24958. + pr_warn("%s: failed to enable MMDC clock %d\n",
  24959. + __func__, ret);
  24960. +
  24961. if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
  24962. clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]);
  24963. clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]);
  24964. }
  24965. + clk_set_parent(clks[IMX6SL_CLK_GPU2D_OVG_SEL],
  24966. + clks[IMX6SL_CLK_PLL2_BUS]);
  24967. + clk_set_parent(clks[IMX6SL_CLK_GPU2D_SEL], clks[IMX6SL_CLK_PLL2_BUS]);
  24968. +
  24969. /* Audio-related clocks configuration */
  24970. clk_set_parent(clks[IMX6SL_CLK_SPDIF0_SEL], clks[IMX6SL_CLK_PLL3_PFD3]);
  24971. + /* set extern_audio to be sourced from PLL4/audio PLL */
  24972. + clk_set_parent(clks[IMX6SL_CLK_EXTERN_AUDIO_SEL], clks[IMX6SL_CLK_PLL4_AUDIO_DIV]);
  24973. + /* set extern_audio to 24MHz */
  24974. + clk_set_rate(clks[IMX6SL_CLK_PLL4_AUDIO], 24000000);
  24975. + clk_set_rate(clks[IMX6SL_CLK_EXTERN_AUDIO], 24000000);
  24976. +
  24977. + /* set SSI2 parent to PLL4 */
  24978. + clk_set_parent(clks[IMX6SL_CLK_SSI2_SEL], clks[IMX6SL_CLK_PLL4_AUDIO_DIV]);
  24979. + clk_set_rate(clks[IMX6SL_CLK_SSI2], 24000000);
  24980. +
  24981. /* Set initial power mode */
  24982. imx6q_set_lpm(WAIT_CLOCKED);
  24983. + /* Ensure that CH0 handshake is bypassed. */
  24984. + reg = readl_relaxed(base + CCM_CCDR_OFFSET);
  24985. + reg |= 1 << CCDR_CH0_HS_BYP;
  24986. + writel_relaxed(reg, base + CCM_CCDR_OFFSET);
  24987. +
  24988. + /* Set the UART parent if needed. */
  24989. + if (uart_from_osc)
  24990. + ret = clk_set_parent(clks[IMX6SL_CLK_UART_SEL], clks[IMX6SL_CLK_UART_OSC_4M]);
  24991. +
  24992. np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpt");
  24993. base = of_iomap(np, 0);
  24994. WARN_ON(!base);
  24995. diff -Nur linux-3.14.14/arch/arm/mach-imx/clk-pfd.c linux-imx6-3.14/arch/arm/mach-imx/clk-pfd.c
  24996. --- linux-3.14.14/arch/arm/mach-imx/clk-pfd.c 2014-07-28 10:07:25.000000000 -0500
  24997. +++ linux-imx6-3.14/arch/arm/mach-imx/clk-pfd.c 2014-12-08 00:31:51.220418001 -0600
  24998. @@ -1,5 +1,5 @@
  24999. /*
  25000. - * Copyright 2012 Freescale Semiconductor, Inc.
  25001. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  25002. * Copyright 2012 Linaro Ltd.
  25003. *
  25004. * The code contained herein is licensed under the GNU General Public
  25005. @@ -17,6 +17,8 @@
  25006. #include <linux/err.h>
  25007. #include "clk.h"
  25008. +#define BYPASS_RATE 24000000
  25009. +
  25010. /**
  25011. * struct clk_pfd - IMX PFD clock
  25012. * @clk_hw: clock source
  25013. @@ -62,9 +64,14 @@
  25014. u64 tmp = parent_rate;
  25015. u8 frac = (readl_relaxed(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
  25016. - tmp *= 18;
  25017. - do_div(tmp, frac);
  25018. -
  25019. + /*
  25020. + * If the parent PLL is in bypass state, the PFDs
  25021. + * are also in bypass state.
  25022. + */
  25023. + if (tmp != BYPASS_RATE) {
  25024. + tmp *= 18;
  25025. + do_div(tmp, frac);
  25026. + }
  25027. return tmp;
  25028. }
  25029. @@ -74,17 +81,22 @@
  25030. u64 tmp = *prate;
  25031. u8 frac;
  25032. - tmp = tmp * 18 + rate / 2;
  25033. - do_div(tmp, rate);
  25034. - frac = tmp;
  25035. - if (frac < 12)
  25036. - frac = 12;
  25037. - else if (frac > 35)
  25038. - frac = 35;
  25039. - tmp = *prate;
  25040. - tmp *= 18;
  25041. - do_div(tmp, frac);
  25042. -
  25043. + /*
  25044. + * If the parent PLL is in bypass state, the PFDs
  25045. + * are also in bypass state.
  25046. + */
  25047. + if (tmp != BYPASS_RATE) {
  25048. + tmp = tmp * 18 + rate / 2;
  25049. + do_div(tmp, rate);
  25050. + frac = tmp;
  25051. + if (frac < 12)
  25052. + frac = 12;
  25053. + else if (frac > 35)
  25054. + frac = 35;
  25055. + tmp = *prate;
  25056. + tmp *= 18;
  25057. + do_div(tmp, frac);
  25058. + }
  25059. return tmp;
  25060. }
  25061. @@ -95,6 +107,9 @@
  25062. u64 tmp = parent_rate;
  25063. u8 frac;
  25064. + if (tmp == BYPASS_RATE)
  25065. + return 0;
  25066. +
  25067. tmp = tmp * 18 + rate / 2;
  25068. do_div(tmp, rate);
  25069. frac = tmp;
  25070. diff -Nur linux-3.14.14/arch/arm/mach-imx/clk-pllv3.c linux-imx6-3.14/arch/arm/mach-imx/clk-pllv3.c
  25071. --- linux-3.14.14/arch/arm/mach-imx/clk-pllv3.c 2014-07-28 10:07:25.000000000 -0500
  25072. +++ linux-imx6-3.14/arch/arm/mach-imx/clk-pllv3.c 2014-12-08 00:31:51.220418001 -0600
  25073. @@ -26,12 +26,15 @@
  25074. #define BM_PLL_ENABLE (0x1 << 13)
  25075. #define BM_PLL_BYPASS (0x1 << 16)
  25076. #define BM_PLL_LOCK (0x1 << 31)
  25077. +#define BYPASS_RATE 24000000
  25078. +#define BYPASS_MASK 0x10000
  25079. /**
  25080. * struct clk_pllv3 - IMX PLL clock version 3
  25081. * @clk_hw: clock source
  25082. * @base: base address of PLL registers
  25083. * @powerup_set: set POWER bit to power up the PLL
  25084. + * @always_on : Leave the PLL powered up all the time.
  25085. * @div_mask: mask of divider bits
  25086. *
  25087. * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3
  25088. @@ -41,7 +44,9 @@
  25089. struct clk_hw hw;
  25090. void __iomem *base;
  25091. bool powerup_set;
  25092. + bool always_on;
  25093. u32 div_mask;
  25094. + u32 rate_req;
  25095. };
  25096. #define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
  25097. @@ -61,54 +66,53 @@
  25098. break;
  25099. if (time_after(jiffies, timeout))
  25100. break;
  25101. - usleep_range(50, 500);
  25102. + udelay(100);
  25103. } while (1);
  25104. return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
  25105. }
  25106. -static int clk_pllv3_prepare(struct clk_hw *hw)
  25107. +static int clk_pllv3_power_up_down(struct clk_hw *hw, bool enable)
  25108. {
  25109. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25110. - u32 val;
  25111. - int ret;
  25112. -
  25113. - val = readl_relaxed(pll->base);
  25114. - if (pll->powerup_set)
  25115. - val |= BM_PLL_POWER;
  25116. - else
  25117. - val &= ~BM_PLL_POWER;
  25118. - writel_relaxed(val, pll->base);
  25119. -
  25120. - ret = clk_pllv3_wait_lock(pll);
  25121. - if (ret)
  25122. - return ret;
  25123. + u32 val, ret = 0;
  25124. - val = readl_relaxed(pll->base);
  25125. - val &= ~BM_PLL_BYPASS;
  25126. - writel_relaxed(val, pll->base);
  25127. -
  25128. - return 0;
  25129. -}
  25130. + if (enable) {
  25131. + val = readl_relaxed(pll->base);
  25132. + val &= ~BM_PLL_BYPASS;
  25133. + if (pll->powerup_set)
  25134. + val |= BM_PLL_POWER;
  25135. + else
  25136. + val &= ~BM_PLL_POWER;
  25137. + writel_relaxed(val, pll->base);
  25138. +
  25139. + ret = clk_pllv3_wait_lock(pll);
  25140. + } else {
  25141. + val = readl_relaxed(pll->base);
  25142. + val |= BM_PLL_BYPASS;
  25143. + if (pll->powerup_set)
  25144. + val &= ~BM_PLL_POWER;
  25145. + else
  25146. + val |= BM_PLL_POWER;
  25147. + writel_relaxed(val, pll->base);
  25148. + }
  25149. -static void clk_pllv3_unprepare(struct clk_hw *hw)
  25150. -{
  25151. - struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25152. - u32 val;
  25153. + if (!ret) {
  25154. + val = readl_relaxed(pll->base);
  25155. + val &= ~BM_PLL_BYPASS;
  25156. + writel_relaxed(val, pll->base);
  25157. + }
  25158. - val = readl_relaxed(pll->base);
  25159. - val |= BM_PLL_BYPASS;
  25160. - if (pll->powerup_set)
  25161. - val &= ~BM_PLL_POWER;
  25162. - else
  25163. - val |= BM_PLL_POWER;
  25164. - writel_relaxed(val, pll->base);
  25165. + return ret;
  25166. }
  25167. static int clk_pllv3_enable(struct clk_hw *hw)
  25168. {
  25169. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25170. u32 val;
  25171. +
  25172. + if (pll->rate_req != BYPASS_RATE)
  25173. + clk_pllv3_power_up_down(hw, true);
  25174. val = readl_relaxed(pll->base);
  25175. val |= BM_PLL_ENABLE;
  25176. @@ -123,8 +127,12 @@
  25177. u32 val;
  25178. val = readl_relaxed(pll->base);
  25179. - val &= ~BM_PLL_ENABLE;
  25180. + if (!pll->always_on)
  25181. + val &= ~BM_PLL_ENABLE;
  25182. writel_relaxed(val, pll->base);
  25183. +
  25184. + if (pll->rate_req != BYPASS_RATE)
  25185. + clk_pllv3_power_up_down(hw, false);
  25186. }
  25187. static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
  25188. @@ -132,8 +140,15 @@
  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. + u32 rate;
  25194. +
  25195. + if (pll->rate_req == BYPASS_RATE && bypass)
  25196. + rate = BYPASS_RATE;
  25197. + else
  25198. + rate = (div == 1) ? parent_rate * 22 : parent_rate * 20;
  25199. - return (div == 1) ? parent_rate * 22 : parent_rate * 20;
  25200. + return rate;
  25201. }
  25202. static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
  25203. @@ -141,6 +156,10 @@
  25204. {
  25205. unsigned long parent_rate = *prate;
  25206. + /* If the PLL is bypassed, its rate is 24MHz. */
  25207. + if (rate == BYPASS_RATE)
  25208. + return BYPASS_RATE;
  25209. +
  25210. return (rate >= parent_rate * 22) ? parent_rate * 22 :
  25211. parent_rate * 20;
  25212. }
  25213. @@ -151,6 +170,22 @@
  25214. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25215. u32 val, div;
  25216. + pll->rate_req = rate;
  25217. + val = readl_relaxed(pll->base);
  25218. +
  25219. + /* If the PLL is bypassed, its rate is 24MHz. */
  25220. + if (rate == BYPASS_RATE) {
  25221. + /* Set the bypass bit. */
  25222. + val |= BM_PLL_BYPASS;
  25223. + /* Power down the PLL. */
  25224. + if (pll->powerup_set)
  25225. + val &= ~BM_PLL_POWER;
  25226. + else
  25227. + val |= BM_PLL_POWER;
  25228. + writel_relaxed(val, pll->base);
  25229. +
  25230. + return 0;
  25231. + }
  25232. if (rate == parent_rate * 22)
  25233. div = 1;
  25234. else if (rate == parent_rate * 20)
  25235. @@ -167,8 +202,6 @@
  25236. }
  25237. static const struct clk_ops clk_pllv3_ops = {
  25238. - .prepare = clk_pllv3_prepare,
  25239. - .unprepare = clk_pllv3_unprepare,
  25240. .enable = clk_pllv3_enable,
  25241. .disable = clk_pllv3_disable,
  25242. .recalc_rate = clk_pllv3_recalc_rate,
  25243. @@ -181,6 +214,10 @@
  25244. {
  25245. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25246. u32 div = readl_relaxed(pll->base) & pll->div_mask;
  25247. + u32 bypass = readl_relaxed(pll->base) & BYPASS_MASK;
  25248. +
  25249. + if (pll->rate_req == BYPASS_RATE && bypass)
  25250. + return BYPASS_RATE;
  25251. return parent_rate * div / 2;
  25252. }
  25253. @@ -193,6 +230,9 @@
  25254. unsigned long max_rate = parent_rate * 108 / 2;
  25255. u32 div;
  25256. + if (rate == BYPASS_RATE)
  25257. + return BYPASS_RATE;
  25258. +
  25259. if (rate > max_rate)
  25260. rate = max_rate;
  25261. else if (rate < min_rate)
  25262. @@ -210,9 +250,26 @@
  25263. unsigned long max_rate = parent_rate * 108 / 2;
  25264. u32 val, div;
  25265. - if (rate < min_rate || rate > max_rate)
  25266. + if (rate != BYPASS_RATE && (rate < min_rate || rate > max_rate))
  25267. return -EINVAL;
  25268. + pll->rate_req = rate;
  25269. + val = readl_relaxed(pll->base);
  25270. +
  25271. + if (rate == BYPASS_RATE) {
  25272. + /*
  25273. + * Set the PLL in bypass mode if rate requested is
  25274. + * BYPASS_RATE.
  25275. + */
  25276. + val |= BM_PLL_BYPASS;
  25277. + /* Power down the PLL. */
  25278. + if (pll->powerup_set)
  25279. + val &= ~BM_PLL_POWER;
  25280. + else
  25281. + val |= BM_PLL_POWER;
  25282. + writel_relaxed(val, pll->base);
  25283. + return 0;
  25284. + }
  25285. div = rate * 2 / parent_rate;
  25286. val = readl_relaxed(pll->base);
  25287. val &= ~pll->div_mask;
  25288. @@ -223,8 +280,6 @@
  25289. }
  25290. static const struct clk_ops clk_pllv3_sys_ops = {
  25291. - .prepare = clk_pllv3_prepare,
  25292. - .unprepare = clk_pllv3_unprepare,
  25293. .enable = clk_pllv3_enable,
  25294. .disable = clk_pllv3_disable,
  25295. .recalc_rate = clk_pllv3_sys_recalc_rate,
  25296. @@ -239,6 +294,10 @@
  25297. u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
  25298. u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
  25299. u32 div = readl_relaxed(pll->base) & pll->div_mask;
  25300. + u32 bypass = readl_relaxed(pll->base) & BYPASS_MASK;
  25301. +
  25302. + if (pll->rate_req == BYPASS_RATE && bypass)
  25303. + return BYPASS_RATE;
  25304. return (parent_rate * div) + ((parent_rate / mfd) * mfn);
  25305. }
  25306. @@ -253,6 +312,9 @@
  25307. u32 mfn, mfd = 1000000;
  25308. s64 temp64;
  25309. + if (rate == BYPASS_RATE)
  25310. + return BYPASS_RATE;
  25311. +
  25312. if (rate > max_rate)
  25313. rate = max_rate;
  25314. else if (rate < min_rate)
  25315. @@ -273,13 +335,36 @@
  25316. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25317. unsigned long min_rate = parent_rate * 27;
  25318. unsigned long max_rate = parent_rate * 54;
  25319. - u32 val, div;
  25320. + u32 val, newval, div;
  25321. u32 mfn, mfd = 1000000;
  25322. s64 temp64;
  25323. + int ret;
  25324. - if (rate < min_rate || rate > max_rate)
  25325. + if (rate != BYPASS_RATE && (rate < min_rate || rate > max_rate))
  25326. return -EINVAL;
  25327. + pll->rate_req = rate;
  25328. + val = readl_relaxed(pll->base);
  25329. +
  25330. + if (rate == BYPASS_RATE) {
  25331. + /*
  25332. + * Set the PLL in bypass mode if rate requested is
  25333. + * BYPASS_RATE.
  25334. + */
  25335. + /* Bypass the PLL */
  25336. + val |= BM_PLL_BYPASS;
  25337. + /* Power down the PLL. */
  25338. + if (pll->powerup_set)
  25339. + val &= ~BM_PLL_POWER;
  25340. + else
  25341. + val |= BM_PLL_POWER;
  25342. + writel_relaxed(val, pll->base);
  25343. + return 0;
  25344. + }
  25345. + /* Else clear the bypass bit. */
  25346. + val &= ~BM_PLL_BYPASS;
  25347. + writel_relaxed(val, pll->base);
  25348. +
  25349. div = rate / parent_rate;
  25350. temp64 = (u64) (rate - div * parent_rate);
  25351. temp64 *= mfd;
  25352. @@ -287,18 +372,30 @@
  25353. mfn = temp64;
  25354. val = readl_relaxed(pll->base);
  25355. - val &= ~pll->div_mask;
  25356. - val |= div;
  25357. - writel_relaxed(val, pll->base);
  25358. +
  25359. + /* set the PLL into bypass mode */
  25360. + newval = val | BM_PLL_BYPASS;
  25361. + writel_relaxed(newval, pll->base);
  25362. +
  25363. + /* configure the new frequency */
  25364. + newval &= ~pll->div_mask;
  25365. + newval |= div;
  25366. + writel_relaxed(newval, pll->base);
  25367. writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
  25368. - writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
  25369. + writel(mfd, pll->base + PLL_DENOM_OFFSET);
  25370. - return clk_pllv3_wait_lock(pll);
  25371. + ret = clk_pllv3_wait_lock(pll);
  25372. + if (ret == 0 && val & BM_PLL_POWER) {
  25373. + /* only if it locked can we switch back to the PLL */
  25374. + newval &= ~BM_PLL_BYPASS;
  25375. + newval |= val & BM_PLL_BYPASS;
  25376. + writel(newval, pll->base);
  25377. + }
  25378. +
  25379. + return ret;
  25380. }
  25381. static const struct clk_ops clk_pllv3_av_ops = {
  25382. - .prepare = clk_pllv3_prepare,
  25383. - .unprepare = clk_pllv3_unprepare,
  25384. .enable = clk_pllv3_enable,
  25385. .disable = clk_pllv3_disable,
  25386. .recalc_rate = clk_pllv3_av_recalc_rate,
  25387. @@ -313,8 +410,6 @@
  25388. }
  25389. static const struct clk_ops clk_pllv3_enet_ops = {
  25390. - .prepare = clk_pllv3_prepare,
  25391. - .unprepare = clk_pllv3_unprepare,
  25392. .enable = clk_pllv3_enable,
  25393. .disable = clk_pllv3_disable,
  25394. .recalc_rate = clk_pllv3_enet_recalc_rate,
  25395. @@ -322,7 +417,7 @@
  25396. struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
  25397. const char *parent_name, void __iomem *base,
  25398. - u32 div_mask)
  25399. + u32 div_mask, bool always_on)
  25400. {
  25401. struct clk_pllv3 *pll;
  25402. const struct clk_ops *ops;
  25403. @@ -352,6 +447,7 @@
  25404. }
  25405. pll->base = base;
  25406. pll->div_mask = div_mask;
  25407. + pll->always_on = always_on;
  25408. init.name = name;
  25409. init.ops = ops;
  25410. diff -Nur linux-3.14.14/arch/arm/mach-imx/common.h linux-imx6-3.14/arch/arm/mach-imx/common.h
  25411. --- linux-3.14.14/arch/arm/mach-imx/common.h 2014-07-28 10:07:25.000000000 -0500
  25412. +++ linux-imx6-3.14/arch/arm/mach-imx/common.h 2014-12-08 00:31:51.220418001 -0600
  25413. @@ -1,5 +1,5 @@
  25414. /*
  25415. - * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  25416. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  25417. */
  25418. /*
  25419. @@ -116,7 +116,6 @@
  25420. void imx_set_cpu_jump(int cpu, void *jump_addr);
  25421. u32 imx_get_cpu_arg(int cpu);
  25422. void imx_set_cpu_arg(int cpu, u32 arg);
  25423. -void v7_cpu_resume(void);
  25424. #ifdef CONFIG_SMP
  25425. void v7_secondary_startup(void);
  25426. void imx_scu_map_io(void);
  25427. @@ -129,7 +128,7 @@
  25428. #endif
  25429. void imx_src_init(void);
  25430. void imx_gpc_init(void);
  25431. -void imx_gpc_pre_suspend(void);
  25432. +void imx_gpc_pre_suspend(bool arm_power_off);
  25433. void imx_gpc_post_resume(void);
  25434. void imx_gpc_mask_all(void);
  25435. void imx_gpc_restore_all(void);
  25436. @@ -138,14 +137,28 @@
  25437. void imx_anatop_init(void);
  25438. void imx_anatop_pre_suspend(void);
  25439. void imx_anatop_post_resume(void);
  25440. +void imx_anatop_pu_enable(bool enable);
  25441. int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
  25442. -void imx6q_set_chicken_bit(void);
  25443. +void imx6q_set_cache_lpm_in_wait(bool enable);
  25444. +void imx6sl_set_wait_clk(bool enter);
  25445. +void imx6_enet_mac_init(const char *compatible);
  25446. void imx_cpu_die(unsigned int cpu);
  25447. int imx_cpu_kill(unsigned int cpu);
  25448. +#ifdef CONFIG_SUSPEND
  25449. +void v7_cpu_resume(void);
  25450. +void imx6_suspend(void __iomem *ocram_vbase);
  25451. +#else
  25452. +static inline void v7_cpu_resume(void) {}
  25453. +static inline void imx6_suspend(void __iomem *ocram_vbase) {}
  25454. +#endif
  25455. +
  25456. void imx6q_pm_init(void);
  25457. +void imx6dl_pm_init(void);
  25458. +void imx6sl_pm_init(void);
  25459. void imx6q_pm_set_ccm_base(void __iomem *base);
  25460. +
  25461. #ifdef CONFIG_PM
  25462. void imx5_pm_init(void);
  25463. #else
  25464. diff -Nur linux-3.14.14/arch/arm/mach-imx/cpuidle.h linux-imx6-3.14/arch/arm/mach-imx/cpuidle.h
  25465. --- linux-3.14.14/arch/arm/mach-imx/cpuidle.h 2014-07-28 10:07:25.000000000 -0500
  25466. +++ linux-imx6-3.14/arch/arm/mach-imx/cpuidle.h 2014-12-08 00:31:51.220418001 -0600
  25467. @@ -1,5 +1,5 @@
  25468. /*
  25469. - * Copyright 2012 Freescale Semiconductor, Inc.
  25470. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  25471. * Copyright 2012 Linaro Ltd.
  25472. *
  25473. * The code contained herein is licensed under the GNU General Public
  25474. @@ -13,6 +13,7 @@
  25475. #ifdef CONFIG_CPU_IDLE
  25476. extern int imx5_cpuidle_init(void);
  25477. extern int imx6q_cpuidle_init(void);
  25478. +extern int imx6sl_cpuidle_init(void);
  25479. #else
  25480. static inline int imx5_cpuidle_init(void)
  25481. {
  25482. @@ -22,4 +23,8 @@
  25483. {
  25484. return 0;
  25485. }
  25486. +static inline int imx6sl_cpuidle_init(void)
  25487. +{
  25488. + return 0;
  25489. +}
  25490. #endif
  25491. diff -Nur linux-3.14.14/arch/arm/mach-imx/cpuidle-imx6q.c linux-imx6-3.14/arch/arm/mach-imx/cpuidle-imx6q.c
  25492. --- linux-3.14.14/arch/arm/mach-imx/cpuidle-imx6q.c 2014-07-28 10:07:25.000000000 -0500
  25493. +++ linux-imx6-3.14/arch/arm/mach-imx/cpuidle-imx6q.c 2014-12-08 00:31:51.220418001 -0600
  25494. @@ -1,5 +1,5 @@
  25495. /*
  25496. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  25497. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  25498. *
  25499. * This program is free software; you can redistribute it and/or modify
  25500. * it under the terms of the GNU General Public License version 2 as
  25501. @@ -68,8 +68,8 @@
  25502. /* Need to enable SCU standby for entering WAIT modes */
  25503. imx_scu_standby_enable();
  25504. - /* Set chicken bit to get a reliable WAIT mode support */
  25505. - imx6q_set_chicken_bit();
  25506. + /* Set cache lpm bit for reliable WAIT mode support */
  25507. + imx6q_set_cache_lpm_in_wait(true);
  25508. return cpuidle_register(&imx6q_cpuidle_driver, NULL);
  25509. }
  25510. diff -Nur linux-3.14.14/arch/arm/mach-imx/cpuidle-imx6sl.c linux-imx6-3.14/arch/arm/mach-imx/cpuidle-imx6sl.c
  25511. --- linux-3.14.14/arch/arm/mach-imx/cpuidle-imx6sl.c 1969-12-31 18:00:00.000000000 -0600
  25512. +++ linux-imx6-3.14/arch/arm/mach-imx/cpuidle-imx6sl.c 2014-12-08 00:31:51.220418001 -0600
  25513. @@ -0,0 +1,149 @@
  25514. +/*
  25515. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  25516. + *
  25517. + * This program is free software; you can redistribute it and/or modify
  25518. + * it under the terms of the GNU General Public License version 2 as
  25519. + * published by the Free Software Foundation.
  25520. + */
  25521. +
  25522. +#include <linux/cpuidle.h>
  25523. +#include <linux/genalloc.h>
  25524. +#include <linux/module.h>
  25525. +#include <linux/of.h>
  25526. +#include <linux/of_address.h>
  25527. +#include <linux/of_device.h>
  25528. +#include <asm/cpuidle.h>
  25529. +#include <asm/fncpy.h>
  25530. +#include <asm/mach/map.h>
  25531. +#include <asm/proc-fns.h>
  25532. +#include <asm/tlb.h>
  25533. +
  25534. +#include "common.h"
  25535. +#include "cpuidle.h"
  25536. +
  25537. +extern u32 audio_bus_freq_mode;
  25538. +extern u32 ultra_low_bus_freq_mode;
  25539. +extern unsigned long reg_addrs[];
  25540. +extern void imx6sl_low_power_wfi(void);
  25541. +
  25542. +static void __iomem *iomux_base;
  25543. +static void *wfi_iram_base;
  25544. +
  25545. +void (*imx6sl_wfi_in_iram_fn)(void *wfi_iram_base,
  25546. + void *iomux_addr, void *regs_addr, u32 audio_mode) = NULL;
  25547. +
  25548. +#define WFI_IN_IRAM_SIZE 0x1000
  25549. +
  25550. +static int imx6sl_enter_wait(struct cpuidle_device *dev,
  25551. + struct cpuidle_driver *drv, int index)
  25552. +{
  25553. + imx6q_set_lpm(WAIT_UNCLOCKED);
  25554. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  25555. + if (ultra_low_bus_freq_mode || audio_bus_freq_mode) {
  25556. + /*
  25557. + * Flush the TLB, to ensure no TLB maintenance occurs
  25558. + * when DDR is in self-refresh.
  25559. + */
  25560. + local_flush_tlb_all();
  25561. + /*
  25562. + * Run WFI code from IRAM.
  25563. + * Drop the DDR freq to 1MHz and AHB to 3MHz
  25564. + * Also float DDR IO pads.
  25565. + */
  25566. + imx6sl_wfi_in_iram_fn(wfi_iram_base, iomux_base, reg_addrs, audio_bus_freq_mode);
  25567. + }
  25568. + else
  25569. +#endif
  25570. + {
  25571. + imx6sl_set_wait_clk(true);
  25572. + cpu_do_idle();
  25573. + imx6sl_set_wait_clk(false);
  25574. + }
  25575. + imx6q_set_lpm(WAIT_CLOCKED);
  25576. +
  25577. + return index;
  25578. +}
  25579. +
  25580. +static struct cpuidle_driver imx6sl_cpuidle_driver = {
  25581. + .name = "imx6sl_cpuidle",
  25582. + .owner = THIS_MODULE,
  25583. + .states = {
  25584. + /* WFI */
  25585. + ARM_CPUIDLE_WFI_STATE,
  25586. + /* WAIT */
  25587. + {
  25588. + .exit_latency = 50,
  25589. + .target_residency = 75,
  25590. + .flags = CPUIDLE_FLAG_TIME_VALID |
  25591. + CPUIDLE_FLAG_TIMER_STOP,
  25592. + .enter = imx6sl_enter_wait,
  25593. + .name = "WAIT",
  25594. + .desc = "Clock off",
  25595. + },
  25596. + },
  25597. + .state_count = 2,
  25598. + .safe_state_index = 0,
  25599. +};
  25600. +
  25601. +int __init imx6sl_cpuidle_init(void)
  25602. +{
  25603. + struct platform_device *ocram_dev;
  25604. + unsigned int iram_paddr;
  25605. + struct device_node *node;
  25606. + struct gen_pool *iram_pool;
  25607. +
  25608. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-iomuxc");
  25609. + if (!node) {
  25610. + pr_err("failed to find imx6sl-iomuxc device tree data!\n");
  25611. + return -EINVAL;
  25612. + }
  25613. + iomux_base = of_iomap(node, 0);
  25614. + WARN(!iomux_base, "unable to map iomux registers\n");
  25615. +
  25616. + node = NULL;
  25617. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  25618. + if (!node) {
  25619. + pr_err("%s: failed to find ocram node\n",
  25620. + __func__);
  25621. + return -EINVAL;
  25622. + }
  25623. +
  25624. + ocram_dev = of_find_device_by_node(node);
  25625. + if (!ocram_dev) {
  25626. + pr_err("failed to find ocram device!\n");
  25627. + return -EINVAL;
  25628. + }
  25629. +
  25630. + iram_pool = dev_get_gen_pool(&ocram_dev->dev);
  25631. + if (!iram_pool) {
  25632. + pr_err("iram pool unavailable!\n");
  25633. + return -EINVAL;
  25634. + }
  25635. + /*
  25636. + * Allocate IRAM memory when ARM executes WFI in
  25637. + * ultra_low_power_mode.
  25638. + */
  25639. + wfi_iram_base = (void *)gen_pool_alloc(iram_pool,
  25640. + WFI_IN_IRAM_SIZE);
  25641. + if (!wfi_iram_base) {
  25642. + pr_err("Cannot alloc iram for wfi code!\n");
  25643. + return -ENOMEM;
  25644. + }
  25645. +
  25646. + iram_paddr = gen_pool_virt_to_phys(iram_pool,
  25647. + (unsigned long)wfi_iram_base);
  25648. + /*
  25649. + * Need to remap the area here since we want
  25650. + * the memory region to be executable.
  25651. + */
  25652. + wfi_iram_base = __arm_ioremap(iram_paddr,
  25653. + WFI_IN_IRAM_SIZE,
  25654. + MT_MEMORY_RWX_NONCACHED);
  25655. + if (!wfi_iram_base)
  25656. + pr_err("wfi_ram_base NOT remapped\n");
  25657. +
  25658. + imx6sl_wfi_in_iram_fn = (void *)fncpy(wfi_iram_base,
  25659. + &imx6sl_low_power_wfi, WFI_IN_IRAM_SIZE);
  25660. +
  25661. + return cpuidle_register(&imx6sl_cpuidle_driver, NULL);
  25662. +}
  25663. diff -Nur linux-3.14.14/arch/arm/mach-imx/ddr3_freq_imx6.S linux-imx6-3.14/arch/arm/mach-imx/ddr3_freq_imx6.S
  25664. --- linux-3.14.14/arch/arm/mach-imx/ddr3_freq_imx6.S 1969-12-31 18:00:00.000000000 -0600
  25665. +++ linux-imx6-3.14/arch/arm/mach-imx/ddr3_freq_imx6.S 2014-12-08 00:31:51.220418001 -0600
  25666. @@ -0,0 +1,893 @@
  25667. +/*
  25668. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  25669. + *
  25670. + * This program is free software; you can redistribute it and/or modify
  25671. + * it under the terms of the GNU General Public License as published by
  25672. + * the Free Software Foundation; either version 2 of the License, or
  25673. + * (at your option) any later version.
  25674. +
  25675. + * This program is distributed in the hope that it will be useful,
  25676. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25677. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25678. + * GNU General Public License for more details.
  25679. +
  25680. + * You should have received a copy of the GNU General Public License along
  25681. + * with this program; if not, write to the Free Software Foundation, Inc.,
  25682. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  25683. + */
  25684. +
  25685. +#include <linux/linkage.h>
  25686. +
  25687. +#define MMDC0_MDPDC 0x4
  25688. +#define MMDC0_MDCF0 0x0c
  25689. +#define MMDC0_MDCF1 0x10
  25690. +#define MMDC0_MDMISC 0x18
  25691. +#define MMDC0_MDSCR 0x1c
  25692. +#define MMDC0_MAPSR 0x404
  25693. +#define MMDC0_MADPCR0 0x410
  25694. +#define MMDC0_MPZQHWCTRL 0x800
  25695. +#define MMDC1_MPZQHWCTRL 0x4800
  25696. +#define MMDC0_MPODTCTRL 0x818
  25697. +#define MMDC1_MPODTCTRL 0x4818
  25698. +#define MMDC0_MPDGCTRL0 0x83c
  25699. +#define MMDC1_MPDGCTRL0 0x483c
  25700. +#define MMDC0_MPMUR0 0x8b8
  25701. +#define MMDC1_MPMUR0 0x48b8
  25702. +
  25703. +#define CCM_CBCDR 0x14
  25704. +#define CCM_CBCMR 0x18
  25705. +#define CCM_CSCMR1 0x1c
  25706. +#define CCM_CDHIPR 0x48
  25707. +
  25708. +#define L2_CACHE_SYNC 0x730
  25709. +
  25710. + .align 3
  25711. +
  25712. + .macro switch_to_528MHz
  25713. +
  25714. + /* check if periph_clk_sel is already set */
  25715. + ldr r0, [r6, #CCM_CBCDR]
  25716. + and r0, r0, #(1 << 25)
  25717. + cmp r0, #(1 << 25)
  25718. + beq set_ahb_podf_before_switch
  25719. +
  25720. + /* change periph_clk to be sourced from pll3_clk. */
  25721. + ldr r0, [r6, #CCM_CBCMR]
  25722. + bic r0, r0, #(3 << 12)
  25723. + str r0, [r6, #CCM_CBCMR]
  25724. +
  25725. + ldr r0, [r6, #CCM_CBCDR]
  25726. + bic r0, r0, #(0x38 << 20)
  25727. + str r0, [r6, #CCM_CBCDR]
  25728. +
  25729. + /*
  25730. + * set the AHB dividers before the switch,
  25731. + * don't change AXI clock divider,
  25732. + * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
  25733. + */
  25734. + ldr r0, [r6, #CCM_CBCDR]
  25735. + ldr r2, =0x3f1f00
  25736. + bic r0, r0, r2
  25737. + orr r0, r0, #0xd00
  25738. + orr r0, r0, #(1 << 16)
  25739. + str r0, [r6, #CCM_CBCDR]
  25740. +
  25741. +wait_div_update528:
  25742. + ldr r0, [r6, #CCM_CDHIPR]
  25743. + cmp r0, #0
  25744. + bne wait_div_update528
  25745. +
  25746. + /* now switch periph_clk to pll3_main_clk. */
  25747. + ldr r0, [r6, #CCM_CBCDR]
  25748. + orr r0, r0, #(1 << 25)
  25749. + str r0, [r6, #CCM_CBCDR]
  25750. +
  25751. +periph_clk_switch3:
  25752. + ldr r0, [r6, #CCM_CDHIPR]
  25753. + cmp r0, #0
  25754. + bne periph_clk_switch3
  25755. +
  25756. + b switch_pre_periph_clk_528
  25757. +
  25758. +set_ahb_podf_before_switch:
  25759. + /*
  25760. + * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
  25761. + */
  25762. + ldr r0, [r6, #CCM_CBCDR]
  25763. + ldr r2, =0x3f1f00
  25764. + bic r0, r0, r2
  25765. + orr r0, r0, #0xd00
  25766. + orr r0, r0, #(1 << 16)
  25767. + str r0, [r6, #CCM_CBCDR]
  25768. +
  25769. +wait_div_update528_1:
  25770. + ldr r0, [r6, #CCM_CDHIPR]
  25771. + cmp r0, #0
  25772. + bne wait_div_update528_1
  25773. +
  25774. +switch_pre_periph_clk_528:
  25775. +
  25776. + /* now switch pre_periph_clk to PLL2_528MHz. */
  25777. + ldr r0, [r6, #CCM_CBCMR]
  25778. + bic r0, r0, #(0xc << 16)
  25779. + str r0, [r6, #CCM_CBCMR]
  25780. +
  25781. + /* now switch periph_clk back. */
  25782. + ldr r0, [r6, #CCM_CBCDR]
  25783. + bic r0, r0, #(1 << 25)
  25784. + str r0, [r6, #CCM_CBCDR]
  25785. +
  25786. +periph_clk_switch4:
  25787. + ldr r0, [r6, #CCM_CDHIPR]
  25788. + cmp r0, #0
  25789. + bne periph_clk_switch4
  25790. +
  25791. + .endm
  25792. +
  25793. + .macro switch_to_400MHz
  25794. +
  25795. + /* check if periph_clk_sel is already set. */
  25796. + ldr r0, [r6, #CCM_CBCDR]
  25797. + and r0, r0, #(1 << 25)
  25798. + cmp r0, #(1 << 25)
  25799. + beq set_ahb_podf_before_switch1
  25800. +
  25801. + /* change periph_clk to be sourced from pll3_clk. */
  25802. + ldr r0, [r6, #CCM_CBCMR]
  25803. + bic r0, r0, #(3 << 12)
  25804. + str r0, [r6, #CCM_CBCMR]
  25805. +
  25806. + ldr r0, [r6, #CCM_CBCDR]
  25807. + bic r0, r0, #(0x38 << 24)
  25808. + str r0, [r6, #CCM_CBCDR]
  25809. +
  25810. + /* now switch periph_clk to pll3_main_clk. */
  25811. + ldr r0, [r6, #CCM_CBCDR]
  25812. + orr r0, r0, #(1 << 25)
  25813. + str r0, [r6, #CCM_CBCDR]
  25814. +
  25815. +periph_clk_switch5:
  25816. + ldr r0, [r6, #CCM_CDHIPR]
  25817. + cmp r0, #0
  25818. + bne periph_clk_switch5
  25819. +
  25820. + b switch_pre_periph_clk_400
  25821. +
  25822. +set_ahb_podf_before_switch1:
  25823. + /*
  25824. + * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
  25825. + */
  25826. + ldr r0, [r6, #CCM_CBCDR]
  25827. + ldr r2, =0x3f1f00
  25828. + bic r0, r0, r2
  25829. + orr r0, r0, #(0x9 << 8)
  25830. + orr r0, r0, #(1 << 16)
  25831. + str r0, [r6, #CCM_CBCDR]
  25832. +
  25833. +wait_div_update400_1:
  25834. + ldr r0, [r6, #CCM_CDHIPR]
  25835. + cmp r0, #0
  25836. + bne wait_div_update400_1
  25837. +
  25838. +switch_pre_periph_clk_400:
  25839. +
  25840. + /* now switch pre_periph_clk to PFD_400MHz. */
  25841. + ldr r0, [r6, #CCM_CBCMR]
  25842. + bic r0, r0, #(0xc << 16)
  25843. + orr r0, r0, #(0x4 << 16)
  25844. + str r0, [r6, #CCM_CBCMR]
  25845. +
  25846. + /* now switch periph_clk back. */
  25847. + ldr r0, [r6, #CCM_CBCDR]
  25848. + bic r0, r0, #(1 << 25)
  25849. + str r0, [r6, #CCM_CBCDR]
  25850. +
  25851. +periph_clk_switch6:
  25852. + ldr r0, [r6, #CCM_CDHIPR]
  25853. + cmp r0, #0
  25854. + bne periph_clk_switch6
  25855. +
  25856. + /*
  25857. + * change AHB divider so that we are at 400/3=133MHz.
  25858. + * don't change AXI clock divider.
  25859. + * set the MMDC_DIV=1, AXI_DIV=2, AHB_DIV=3,
  25860. + */
  25861. + ldr r0, [r6, #CCM_CBCDR]
  25862. + ldr r2, =0x3f1f00
  25863. + bic r0, r0, r2
  25864. + orr r0, r0, #(0x9 << 8)
  25865. + orr r0, r0, #(1 << 16)
  25866. + str r0, [r6, #CCM_CBCDR]
  25867. +
  25868. +wait_div_update400_2:
  25869. + ldr r0, [r6, #CCM_CDHIPR]
  25870. + cmp r0, #0
  25871. + bne wait_div_update400_2
  25872. +
  25873. + .endm
  25874. +
  25875. + .macro switch_to_50MHz
  25876. +
  25877. + /* check if periph_clk_sel is already set. */
  25878. + ldr r0, [r6, #CCM_CBCDR]
  25879. + and r0, r0, #(1 << 25)
  25880. + cmp r0, #(1 << 25)
  25881. + beq switch_pre_periph_clk_50
  25882. +
  25883. + /*
  25884. + * set the periph_clk to be sourced from PLL2_PFD_200M
  25885. + * change periph_clk to be sourced from pll3_clk.
  25886. + * ensure PLL3 is the source and set the divider to 1.
  25887. + */
  25888. + ldr r0, [r6, #CCM_CBCMR]
  25889. + bic r0, r0, #(0x3 << 12)
  25890. + str r0, [r6, #CCM_CBCMR]
  25891. +
  25892. + ldr r0, [r6, #CCM_CBCDR]
  25893. + bic r0, r0, #(0x38 << 24)
  25894. + str r0, [r6, #CCM_CBCDR]
  25895. +
  25896. + /* now switch periph_clk to pll3_main_clk. */
  25897. + ldr r0, [r6, #CCM_CBCDR]
  25898. + orr r0, r0, #(1 << 25)
  25899. + str r0, [r6, #CCM_CBCDR]
  25900. +
  25901. +periph_clk_switch_50:
  25902. + ldr r0, [r6, #CCM_CDHIPR]
  25903. + cmp r0, #0
  25904. + bne periph_clk_switch_50
  25905. +
  25906. +switch_pre_periph_clk_50:
  25907. +
  25908. + /* now switch pre_periph_clk to PFD_200MHz. */
  25909. + ldr r0, [r6, #CCM_CBCMR]
  25910. + orr r0, r0, #(0xc << 16)
  25911. + str r0, [r6, #CCM_CBCMR]
  25912. +
  25913. + /*
  25914. + * set the MMDC_DIV=4, AXI_DIV = 4, AHB_DIV=8,
  25915. + */
  25916. + ldr r0, [r6, #CCM_CBCDR]
  25917. + ldr r2, =0x3f1f00
  25918. + bic r0, r0, r2
  25919. + orr r0, r0, #(0x18 << 16)
  25920. + orr r0, r0, #(0x3 << 16)
  25921. +
  25922. + /*
  25923. + * if changing AHB divider remember to change
  25924. + * the IPGPER divider too below.
  25925. + */
  25926. + orr r0, r0, #0x1d00
  25927. + str r0, [r6, #CCM_CBCDR]
  25928. +
  25929. +wait_div_update_50:
  25930. + ldr r0, [r6, #CCM_CDHIPR]
  25931. + cmp r0, #0
  25932. + bne wait_div_update_50
  25933. +
  25934. + /* now switch periph_clk back. */
  25935. + ldr r0, [r6, #CCM_CBCDR]
  25936. + bic r0, r0, #(1 << 25)
  25937. + str r0, [r6, #CCM_CBCDR]
  25938. +
  25939. +periph_clk_switch2:
  25940. + ldr r0, [r6, #CCM_CDHIPR]
  25941. + cmp r0, #0
  25942. + bne periph_clk_switch2
  25943. +
  25944. + .endm
  25945. +
  25946. + .macro switch_to_24MHz
  25947. + /*
  25948. + * change the freq now try setting DDR to 24MHz.
  25949. + * source it from the periph_clk2 ensure the
  25950. + * periph_clk2 is sourced from 24MHz and the
  25951. + * divider is 1.
  25952. + */
  25953. +
  25954. + ldr r0, [r6, #CCM_CBCMR]
  25955. + bic r0, r0, #(0x3 << 12)
  25956. + orr r0, r0, #(1 << 12)
  25957. + str r0, [r6, #CCM_CBCMR]
  25958. +
  25959. + ldr r0, [r6, #CCM_CBCDR]
  25960. + bic r0, r0, #(0x38 << 24)
  25961. + str r0, [r6, #CCM_CBCDR]
  25962. +
  25963. + /* now switch periph_clk to 24MHz. */
  25964. + ldr r0, [r6, #CCM_CBCDR]
  25965. + orr r0, r0, #(1 << 25)
  25966. + str r0, [r6, #CCM_CBCDR]
  25967. +
  25968. +periph_clk_switch1:
  25969. + ldr r0, [r6, #CCM_CDHIPR]
  25970. + cmp r0, #0
  25971. + bne periph_clk_switch1
  25972. +
  25973. + /* change all the dividers to 1. */
  25974. + ldr r0, [r6, #CCM_CBCDR]
  25975. + ldr r2, =0x3f1f00
  25976. + bic r0, r0, r2
  25977. + orr r0, r0, #(1 << 8)
  25978. + str r0, [r6, #CCM_CBCDR]
  25979. +
  25980. + /* Wait for the divider to change. */
  25981. +wait_div_update:
  25982. + ldr r0, [r6, #CCM_CDHIPR]
  25983. + cmp r0, #0
  25984. + bne wait_div_update
  25985. +
  25986. + .endm
  25987. +
  25988. +/*
  25989. + * mx6_ddr3_freq_change
  25990. + *
  25991. + * idle the processor (eg, wait for interrupt).
  25992. + * make sure DDR is in self-refresh.
  25993. + * IRQs are already disabled.
  25994. + */
  25995. +ENTRY(mx6_ddr3_freq_change)
  25996. +
  25997. + stmfd sp!, {r4-r12}
  25998. +
  25999. + /*
  26000. + * r5 -> mmdc_base
  26001. + * r6 -> ccm_base
  26002. + * r7 -> iomux_base
  26003. + * r12 -> l2_base
  26004. + */
  26005. + mov r4, r0
  26006. + mov r8, r1
  26007. + mov r9, r2
  26008. + mov r11, r3
  26009. +
  26010. + /*
  26011. + * Get the addresses of the registers.
  26012. + * They are last few entries in the
  26013. + * ddr_settings parameter.
  26014. + * The first entry contains the count,
  26015. + * and each entry is 2 words.
  26016. + */
  26017. + ldr r0, [r1]
  26018. + add r0, r0, #1
  26019. + lsl r0, r0, #3
  26020. + add r1, r0, r1
  26021. + /* mmdc_base. */
  26022. + ldr r5, [r1]
  26023. + add r1, #8
  26024. + /* ccm_base */
  26025. + ldr r6, [r1]
  26026. + add r1, #8
  26027. + /*iomux_base */
  26028. + ldr r7, [r1]
  26029. + add r1, #8
  26030. + /*l2_base */
  26031. + ldr r12, [r1]
  26032. +
  26033. +ddr_freq_change:
  26034. + /*
  26035. + * make sure no TLB miss will occur when
  26036. + * the DDR is in self refresh. invalidate
  26037. + * TLB single entry to ensure that the
  26038. + * address is not already in the TLB.
  26039. + */
  26040. +
  26041. + adr r10, ddr_freq_change
  26042. +
  26043. + ldr r2, [r6]
  26044. + ldr r2, [r5]
  26045. + ldr r2, [r7]
  26046. + ldr r2, [r8]
  26047. + ldr r2, [r10]
  26048. + ldr r2, [r11]
  26049. + ldr r2, [r12]
  26050. +
  26051. +#ifdef CONFIG_CACHE_L2X0
  26052. + /*
  26053. + * Make sure the L2 buffers are drained.
  26054. + * Sync operation on L2 drains the buffers.
  26055. + */
  26056. + mov r1, #0x0
  26057. + str r1, [r12, #L2_CACHE_SYNC]
  26058. +#endif
  26059. +
  26060. + /* disable automatic power saving. */
  26061. + ldr r0, [r5, #MMDC0_MAPSR]
  26062. + orr r0, r0, #0x01
  26063. + str r0, [r5, #MMDC0_MAPSR]
  26064. +
  26065. + /* disable MMDC power down timer. */
  26066. + ldr r0, [r5, #MMDC0_MDPDC]
  26067. + bic r0, r0, #(0xff << 8)
  26068. + str r0, [r5, #MMDC0_MDPDC]
  26069. +
  26070. + /* delay for a while */
  26071. + ldr r1, =4
  26072. +delay1:
  26073. + ldr r2, =0
  26074. +cont1:
  26075. + ldr r0, [r5, r2]
  26076. + add r2, r2, #4
  26077. + cmp r2, #16
  26078. + bne cont1
  26079. + sub r1, r1, #1
  26080. + cmp r1, #0
  26081. + bgt delay1
  26082. +
  26083. + /* set CON_REG */
  26084. + ldr r0, =0x8000
  26085. + str r0, [r5, #MMDC0_MDSCR]
  26086. +poll_conreq_set_1:
  26087. + ldr r0, [r5, #MMDC0_MDSCR]
  26088. + and r0, r0, #(0x4 << 12)
  26089. + cmp r0, #(0x4 << 12)
  26090. + bne poll_conreq_set_1
  26091. +
  26092. + ldr r0, =0x00008010
  26093. + str r0, [r5, #MMDC0_MDSCR]
  26094. + ldr r0, =0x00008018
  26095. + str r0, [r5, #MMDC0_MDSCR]
  26096. +
  26097. + /*
  26098. + * if requested frequency is greater than
  26099. + * 300MHz go to DLL on mode.
  26100. + */
  26101. + ldr r1, =300000000
  26102. + cmp r4, r1
  26103. + bge dll_on_mode
  26104. +
  26105. +dll_off_mode:
  26106. +
  26107. + /* if DLL is currently on, turn it off. */
  26108. + cmp r9, #1
  26109. + beq continue_dll_off_1
  26110. +
  26111. + ldr r0, =0x00018031
  26112. + str r0, [r5, #MMDC0_MDSCR]
  26113. +
  26114. + ldr r0, =0x00018039
  26115. + str r0, [r5, #MMDC0_MDSCR]
  26116. +
  26117. + ldr r1, =10
  26118. +delay1a:
  26119. + ldr r2, =0
  26120. +cont1a:
  26121. + ldr r0, [r5, r2]
  26122. + add r2, r2, #4
  26123. + cmp r2, #16
  26124. + bne cont1a
  26125. + sub r1, r1, #1
  26126. + cmp r1, #0
  26127. + bgt delay1a
  26128. +
  26129. +continue_dll_off_1:
  26130. + /* set DVFS - enter self refresh mode */
  26131. + ldr r0, [r5, #MMDC0_MAPSR]
  26132. + orr r0, r0, #(1 << 21)
  26133. + str r0, [r5, #MMDC0_MAPSR]
  26134. +
  26135. + /* de-assert con_req */
  26136. + mov r0, #0x0
  26137. + str r0, [r5, #MMDC0_MDSCR]
  26138. +
  26139. +poll_dvfs_set_1:
  26140. + ldr r0, [r5, #MMDC0_MAPSR]
  26141. + and r0, r0, #(1 << 25)
  26142. + cmp r0, #(1 << 25)
  26143. + bne poll_dvfs_set_1
  26144. +
  26145. + ldr r1, =24000000
  26146. + cmp r4, r1
  26147. + beq switch_freq_24
  26148. +
  26149. + switch_to_50MHz
  26150. + b continue_dll_off_2
  26151. +
  26152. +switch_freq_24:
  26153. + switch_to_24MHz
  26154. +
  26155. +continue_dll_off_2:
  26156. +
  26157. + /* set SBS - block ddr accesses */
  26158. + ldr r0, [r5, #MMDC0_MADPCR0]
  26159. + orr r0, r0, #(1 << 8)
  26160. + str r0, [r5, #MMDC0_MADPCR0]
  26161. +
  26162. + /* clear DVFS - exit from self refresh mode */
  26163. + ldr r0, [r5, #MMDC0_MAPSR]
  26164. + bic r0, r0, #(1 << 21)
  26165. + str r0, [r5, #MMDC0_MAPSR]
  26166. +
  26167. +poll_dvfs_clear_1:
  26168. + ldr r0, [r5, #MMDC0_MAPSR]
  26169. + and r0, r0, #(1 << 25)
  26170. + cmp r0, #(1 << 25)
  26171. + beq poll_dvfs_clear_1
  26172. +
  26173. + /* if DLL was previously on, continue DLL off routine. */
  26174. + cmp r9, #1
  26175. + beq continue_dll_off_3
  26176. +
  26177. + ldr r0, =0x00018031
  26178. + str r0, [r5, #MMDC0_MDSCR]
  26179. +
  26180. + ldr r0, =0x00018039
  26181. + str r0, [r5, #MMDC0_MDSCR]
  26182. +
  26183. + ldr r0, =0x08208030
  26184. + str r0, [r5, #MMDC0_MDSCR]
  26185. +
  26186. + ldr r0, =0x08208038
  26187. + str r0, [r5, #MMDC0_MDSCR]
  26188. +
  26189. + ldr r0, =0x00088032
  26190. + str r0, [r5, #MMDC0_MDSCR]
  26191. +
  26192. + ldr r0, =0x0008803A
  26193. + str r0, [r5, #MMDC0_MDSCR]
  26194. +
  26195. + /* delay for a while. */
  26196. + ldr r1, =4
  26197. +delay_1:
  26198. + ldr r2, =0
  26199. +cont_1:
  26200. + ldr r0, [r5, r2]
  26201. + add r2, r2, #4
  26202. + cmp r2, #16
  26203. + bne cont_1
  26204. + sub r1, r1, #1
  26205. + cmp r1, #0
  26206. + bgt delay_1
  26207. +
  26208. + ldr r0, [r5, #MMDC0_MDCF0]
  26209. + bic r0, r0, #0xf
  26210. + orr r0, r0, #0x3
  26211. + str r0, [r5, #MMDC0_MDCF0]
  26212. +
  26213. + ldr r0, [r5, #MMDC0_MDCF1]
  26214. + bic r0, r0, #0x7
  26215. + orr r0, r0, #0x4
  26216. + str r0, [r5, #MMDC0_MDCF1]
  26217. +
  26218. + ldr r0, =0x00091680
  26219. + str r0, [r5, #MMDC0_MDMISC]
  26220. +
  26221. + /* enable dqs pull down in the IOMUX. */
  26222. + ldr r1, [r11]
  26223. + add r11, r11, #8
  26224. + ldr r2, =0x3028
  26225. +update_iomux:
  26226. + ldr r0, [r11, #0x0]
  26227. + ldr r3, [r7, r0]
  26228. + bic r3, r3, r2
  26229. + orr r3, r3, #(0x3 << 12)
  26230. + orr r3, r3, #0x28
  26231. + str r3, [r7, r0]
  26232. + add r11, r11, #8
  26233. + sub r1, r1, #1
  26234. + cmp r1, #0
  26235. + bgt update_iomux
  26236. +
  26237. + /* ODT disabled. */
  26238. + ldr r0, =0x0
  26239. + ldr r2, =MMDC0_MPODTCTRL
  26240. + str r0, [r5, r2]
  26241. + ldr r2, =MMDC1_MPODTCTRL
  26242. + str r0, [r5, r2]
  26243. +
  26244. + /* DQS gating disabled. */
  26245. + ldr r2, =MMDC0_MPDGCTRL0
  26246. + ldr r0, [r5, r2]
  26247. + orr r0, r0, #(1 << 29)
  26248. + str r0, [r5, r2]
  26249. +
  26250. + ldr r2, =MMDC1_MPDGCTRL0
  26251. + ldr r0, [r5, r2]
  26252. + orr r0, r0, #(0x1 << 29)
  26253. + str r0, [r5, r2]
  26254. +
  26255. + /* MMDC0_MAPSR adopt power down enable. */
  26256. + ldr r0, [r5, #MMDC0_MAPSR]
  26257. + bic r0, r0, #0x01
  26258. + str r0, [r5, #MMDC0_MAPSR]
  26259. +
  26260. + /* frc_msr + mu bypass */
  26261. + ldr r0, =0x00000060
  26262. + str r0, [r5, #MMDC0_MPMUR0]
  26263. + ldr r2, =MMDC1_MPMUR0
  26264. + str r0, [r5, r2]
  26265. + ldr r0, =0x00000460
  26266. + str r0, [r5, #MMDC0_MPMUR0]
  26267. + ldr r2, =MMDC1_MPMUR0
  26268. + str r0, [r5, r2]
  26269. + ldr r0, =0x00000c60
  26270. + str r0, [r5, #MMDC0_MPMUR0]
  26271. + ldr r2, =MMDC1_MPMUR0
  26272. + str r0, [r5, r2]
  26273. +
  26274. +continue_dll_off_3:
  26275. + /* clear SBS - unblock accesses to DDR. */
  26276. + ldr r0, [r5, #MMDC0_MADPCR0]
  26277. + bic r0, r0, #(0x1 << 8)
  26278. + str r0, [r5, #MMDC0_MADPCR0]
  26279. +
  26280. + mov r0, #0x0
  26281. + str r0, [r5, #MMDC0_MDSCR]
  26282. +poll_conreq_clear_1:
  26283. + ldr r0, [r5, #MMDC0_MDSCR]
  26284. + and r0, r0, #(0x4 << 12)
  26285. + cmp r0, #(0x4 << 12)
  26286. + beq poll_conreq_clear_1
  26287. +
  26288. + b done
  26289. +
  26290. +dll_on_mode:
  26291. + /* assert DVFS - enter self refresh mode. */
  26292. + ldr r0, [r5, #MMDC0_MAPSR]
  26293. + orr r0, r0, #(1 << 21)
  26294. + str r0, [r5, #MMDC0_MAPSR]
  26295. +
  26296. + /* de-assert CON_REQ. */
  26297. + mov r0, #0x0
  26298. + str r0, [r5, #MMDC0_MDSCR]
  26299. +
  26300. + /* poll DVFS ack. */
  26301. +poll_dvfs_set_2:
  26302. + ldr r0, [r5, #MMDC0_MAPSR]
  26303. + and r0, r0, #(1 << 25)
  26304. + cmp r0, #(1 << 25)
  26305. + bne poll_dvfs_set_2
  26306. +
  26307. + ldr r1, =528000000
  26308. + cmp r4, r1
  26309. + beq switch_freq_528
  26310. +
  26311. + switch_to_400MHz
  26312. +
  26313. + b continue_dll_on
  26314. +
  26315. +switch_freq_528:
  26316. + switch_to_528MHz
  26317. +
  26318. +continue_dll_on:
  26319. +
  26320. + /* set SBS step-by-step mode. */
  26321. + ldr r0, [r5, #MMDC0_MADPCR0]
  26322. + orr r0, r0, #( 1 << 8)
  26323. + str r0, [r5, #MMDC0_MADPCR0]
  26324. +
  26325. + /* clear DVFS - exit self refresh mode. */
  26326. + ldr r0, [r5, #MMDC0_MAPSR]
  26327. + bic r0, r0, #(1 << 21)
  26328. + str r0, [r5, #MMDC0_MAPSR]
  26329. +
  26330. +poll_dvfs_clear_2:
  26331. + ldr r0, [r5, #MMDC0_MAPSR]
  26332. + and r0, r0, #(1 << 25)
  26333. + cmp r0, #(1 << 25)
  26334. + beq poll_dvfs_clear_2
  26335. +
  26336. + /* if DLL is currently off, turn it back on. */
  26337. + cmp r9, #0
  26338. + beq update_calibration_only
  26339. +
  26340. + ldr r0, =0xa5390003
  26341. + str r0, [r5, #MMDC0_MPZQHWCTRL]
  26342. + ldr r2, =MMDC1_MPZQHWCTRL
  26343. + str r0, [r5, r2]
  26344. +
  26345. + /* enable DQS gating. */
  26346. + ldr r2, =MMDC0_MPDGCTRL0
  26347. + ldr r0, [r5, r2]
  26348. + bic r0, r0, #(1 << 29)
  26349. + str r0, [r5, r2]
  26350. +
  26351. + ldr r2, =MMDC1_MPDGCTRL0
  26352. + ldr r0, [r5, r2]
  26353. + bic r0, r0, #(1 << 29)
  26354. + str r0, [r5, r2]
  26355. +
  26356. + /* force measure. */
  26357. + ldr r0, =0x00000800
  26358. + str r0, [r5, #MMDC0_MPMUR0]
  26359. + ldr r2, =MMDC1_MPMUR0
  26360. + str r0, [r5, r2]
  26361. +
  26362. + /* delay for while. */
  26363. + ldr r1, =4
  26364. +delay5:
  26365. + ldr r2, =0
  26366. +cont5:
  26367. + ldr r0, [r5, r2]
  26368. + add r2, r2, #4
  26369. + cmp r2, #16
  26370. + bne cont5
  26371. + sub r1, r1, #1
  26372. + cmp r1, #0
  26373. + bgt delay5
  26374. +
  26375. + /* disable dqs pull down in the IOMUX. */
  26376. + ldr r1, [r11]
  26377. + add r11, r11, #8
  26378. +update_iomux1:
  26379. + ldr r0, [r11, #0x0]
  26380. + ldr r3, [r11, #0x4]
  26381. + str r3, [r7, r0]
  26382. + add r11, r11, #8
  26383. + sub r1, r1, #1
  26384. + cmp r1, #0
  26385. + bgt update_iomux1
  26386. +
  26387. + /* config MMDC timings to 528MHz. */
  26388. + ldr r9, [r8]
  26389. + add r8, r8, #8
  26390. + ldr r0, [r8, #0x0]
  26391. + ldr r3, [r8, #0x4]
  26392. + str r3, [r5, r0]
  26393. + add r8, r8, #8
  26394. +
  26395. + ldr r0, [r8, #0x0]
  26396. + ldr r3, [r8, #0x4]
  26397. + str r3, [r5, r0]
  26398. + add r8, r8, #8
  26399. +
  26400. + /* update MISC register: WALAT, RALAT */
  26401. + ldr r0, =0x00081740
  26402. + str r0, [r5, #MMDC0_MDMISC]
  26403. +
  26404. + /* configure ddr devices to dll on, odt. */
  26405. + ldr r0, =0x00028031
  26406. + str r0, [r5, #MMDC0_MDSCR]
  26407. +
  26408. + ldr r0, =0x00028039
  26409. + str r0, [r5, #MMDC0_MDSCR]
  26410. +
  26411. + /* delay for while. */
  26412. + ldr r1, =4
  26413. +delay7:
  26414. + ldr r2, =0
  26415. +cont7:
  26416. + ldr r0, [r5, r2]
  26417. + add r2, r2, #4
  26418. + cmp r2, #16
  26419. + bne cont7
  26420. + sub r1, r1, #1
  26421. + cmp r1, #0
  26422. + bgt delay7
  26423. +
  26424. + /* reset dll. */
  26425. + ldr r0, =0x09208030
  26426. + str r0, [r5, #MMDC0_MDSCR]
  26427. +
  26428. + ldr r0, =0x09208038
  26429. + str r0, [r5, #MMDC0_MDSCR]
  26430. +
  26431. + /* delay for while. */
  26432. + ldr r1, =100
  26433. +delay8:
  26434. + ldr r2, =0
  26435. +cont8:
  26436. + ldr r0, [r5, r2]
  26437. + add r2, r2, #4
  26438. + cmp r2, #16
  26439. + bne cont8
  26440. + sub r1, r1, #1
  26441. + cmp r1, #0
  26442. + bgt delay8
  26443. +
  26444. + ldr r0, [r8, #0x0]
  26445. + ldr r3, [r8, #0x4]
  26446. + str r3, [r5, r0]
  26447. + add r8, r8, #8
  26448. +
  26449. + ldr r0, [r8, #0x0]
  26450. + ldr r3, [r8, #0x4]
  26451. + str r3, [r5, r0]
  26452. + add r8, r8, #8
  26453. +
  26454. + ldr r0, =0x00428031
  26455. + str r0, [r5, #MMDC0_MDSCR]
  26456. +
  26457. + ldr r0, =0x00428039
  26458. + str r0, [r5, #MMDC0_MDSCR]
  26459. +
  26460. + ldr r0, [r8, #0x0]
  26461. + ldr r3, [r8, #0x4]
  26462. + str r3, [r5, r0]
  26463. + add r8, r8, #8
  26464. +
  26465. + ldr r0, [r8, #0x0]
  26466. + ldr r3, [r8, #0x4]
  26467. + str r3, [r5, r0]
  26468. + add r8, r8, #8
  26469. +
  26470. + /* issue a zq command. */
  26471. + ldr r0, =0x04008040
  26472. + str r0, [r5, #MMDC0_MDSCR]
  26473. +
  26474. + ldr r0, =0x04008048
  26475. + str r0, [r5, #MMDC0_MDSCR]
  26476. +
  26477. + /* MMDC ODT enable. */
  26478. + ldr r0, [r8, #0x0]
  26479. + ldr r3, [r8, #0x4]
  26480. + str r3, [r5, r0]
  26481. + add r8, r8, #8
  26482. +
  26483. + ldr r2, =0x4818
  26484. + str r0, [r5, r2]
  26485. +
  26486. + /* delay for while. */
  26487. + ldr r1, =40
  26488. +delay15:
  26489. + ldr r2, =0
  26490. +cont15:
  26491. + ldr r0, [r5, r2]
  26492. + add r2, r2, #4
  26493. + cmp r2, #16
  26494. + bne cont15
  26495. + sub r1, r1, #1
  26496. + cmp r1, #0
  26497. + bgt delay15
  26498. +
  26499. + /* MMDC0_MAPSR adopt power down enable. */
  26500. + ldr r0, [r5, #MMDC0_MAPSR]
  26501. + bic r0, r0, #0x01
  26502. + str r0, [r5, #MMDC0_MAPSR]
  26503. +
  26504. + /* enable MMDC power down timer. */
  26505. + ldr r0, [r5, #MMDC0_MDPDC]
  26506. + orr r0, r0, #(0x55 << 8)
  26507. + str r0, [r5, #MMDC0_MDPDC]
  26508. +
  26509. + b update_calibration
  26510. +
  26511. +update_calibration_only:
  26512. + ldr r1, [r8]
  26513. + sub r1, r1, #7
  26514. + add r8, r8, #64
  26515. + b update_calib
  26516. +
  26517. +update_calibration:
  26518. + /* write the new calibration values. */
  26519. + mov r1, r9
  26520. + sub r1, r1, #7
  26521. +
  26522. +update_calib:
  26523. + ldr r0, [r8, #0x0]
  26524. + ldr r3, [r8, #0x4]
  26525. + str r3, [r5, r0]
  26526. + add r8, r8, #8
  26527. + sub r1, r1, #1
  26528. + cmp r1, #0
  26529. + bgt update_calib
  26530. +
  26531. + /* perform a force measurement. */
  26532. + ldr r0, =0x800
  26533. + str r0, [r5, #MMDC0_MPMUR0]
  26534. + ldr r2, =MMDC1_MPMUR0
  26535. + str r0, [r5, r2]
  26536. +
  26537. + /* clear SBS - unblock DDR accesses. */
  26538. + ldr r0, [r5, #MMDC0_MADPCR0]
  26539. + bic r0, r0, #(1 << 8)
  26540. + str r0, [r5, #MMDC0_MADPCR0]
  26541. +
  26542. + mov r0, #0x0
  26543. + str r0, [r5, #MMDC0_MDSCR]
  26544. +poll_conreq_clear_2:
  26545. + ldr r0, [r5, #MMDC0_MDSCR]
  26546. + and r0, r0, #(0x4 << 12)
  26547. + cmp r0, #(0x4 << 12)
  26548. + beq poll_conreq_clear_2
  26549. +
  26550. +done:
  26551. + /* restore registers */
  26552. +
  26553. + ldmfd sp!, {r4-r12}
  26554. + mov pc, lr
  26555. +
  26556. + .type mx6_do_ddr3_freq_change, #object
  26557. +ENTRY(mx6_do_ddr_freq_change)
  26558. + .word mx6_ddr3_freq_change
  26559. + .size mx6_ddr3_freq_change, . - mx6_ddr3_freq_change
  26560. diff -Nur linux-3.14.14/arch/arm/mach-imx/gpc.c linux-imx6-3.14/arch/arm/mach-imx/gpc.c
  26561. --- linux-3.14.14/arch/arm/mach-imx/gpc.c 2014-07-28 10:07:25.000000000 -0500
  26562. +++ linux-imx6-3.14/arch/arm/mach-imx/gpc.c 2014-12-08 00:31:51.224418001 -0600
  26563. @@ -10,30 +10,69 @@
  26564. * http://www.gnu.org/copyleft/gpl.html
  26565. */
  26566. +#include <linux/clk.h>
  26567. +#include <linux/delay.h>
  26568. #include <linux/io.h>
  26569. #include <linux/irq.h>
  26570. +#include <linux/module.h>
  26571. #include <linux/of.h>
  26572. #include <linux/of_address.h>
  26573. #include <linux/of_irq.h>
  26574. +#include <linux/platform_device.h>
  26575. #include <linux/irqchip/arm-gic.h>
  26576. +#include <linux/regulator/consumer.h>
  26577. +#include <linux/regulator/driver.h>
  26578. +#include <linux/regulator/machine.h>
  26579. #include "common.h"
  26580. +#include "hardware.h"
  26581. #define GPC_IMR1 0x008
  26582. #define GPC_PGC_CPU_PDN 0x2a0
  26583. +#define GPC_PGC_GPU_PDN 0x260
  26584. +#define GPC_PGC_GPU_PUPSCR 0x264
  26585. +#define GPC_PGC_GPU_PDNSCR 0x268
  26586. +#define GPC_PGC_GPU_SW_SHIFT 0
  26587. +#define GPC_PGC_GPU_SW_MASK 0x3f
  26588. +#define GPC_PGC_GPU_SW2ISO_SHIFT 8
  26589. +#define GPC_PGC_GPU_SW2ISO_MASK 0x3f
  26590. +#define GPC_PGC_CPU_PUPSCR 0x2a4
  26591. +#define GPC_PGC_CPU_PDNSCR 0x2a8
  26592. +#define GPC_PGC_CPU_SW_SHIFT 0
  26593. +#define GPC_PGC_CPU_SW_MASK 0x3f
  26594. +#define GPC_PGC_CPU_SW2ISO_SHIFT 8
  26595. +#define GPC_PGC_CPU_SW2ISO_MASK 0x3f
  26596. +#define GPC_CNTR 0x0
  26597. +#define GPC_CNTR_PU_UP_REQ_SHIFT 0x1
  26598. +#define GPC_CNTR_PU_DOWN_REQ_SHIFT 0x0
  26599. #define IMR_NUM 4
  26600. static void __iomem *gpc_base;
  26601. static u32 gpc_wake_irqs[IMR_NUM];
  26602. static u32 gpc_saved_imrs[IMR_NUM];
  26603. +static struct clk *gpu3d_clk, *gpu3d_shader_clk, *gpu2d_clk, *gpu2d_axi_clk;
  26604. +static struct clk *openvg_axi_clk, *vpu_clk, *ipg_clk;
  26605. +static struct device *gpc_dev;
  26606. +struct regulator *pu_reg;
  26607. +struct notifier_block nb;
  26608. +static struct regulator_dev *pu_dummy_regulator_rdev;
  26609. +static struct regulator_init_data pu_dummy_initdata = {
  26610. + .constraints = {
  26611. + .max_uV = 1450000, /* allign with real max of anatop */
  26612. + .valid_ops_mask = REGULATOR_CHANGE_STATUS |
  26613. + REGULATOR_CHANGE_VOLTAGE,
  26614. + },
  26615. +};
  26616. +static int pu_dummy_enable;
  26617. -void imx_gpc_pre_suspend(void)
  26618. +void imx_gpc_pre_suspend(bool arm_power_off)
  26619. {
  26620. void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
  26621. int i;
  26622. - /* Tell GPC to power off ARM core when suspend */
  26623. - writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
  26624. + if (arm_power_off)
  26625. + /* Tell GPC to power off ARM core when suspend */
  26626. + writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
  26627. for (i = 0; i < IMR_NUM; i++) {
  26628. gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
  26629. @@ -120,10 +159,119 @@
  26630. writel_relaxed(val, reg);
  26631. }
  26632. +static void imx_pu_clk(bool enable)
  26633. +{
  26634. + if (enable) {
  26635. + if (cpu_is_imx6sl()) {
  26636. + clk_prepare_enable(gpu2d_clk);
  26637. + clk_prepare_enable(openvg_axi_clk);
  26638. + } else {
  26639. + clk_prepare_enable(vpu_clk);
  26640. + clk_prepare_enable(gpu3d_clk);
  26641. + clk_prepare_enable(gpu3d_shader_clk);
  26642. + clk_prepare_enable(gpu2d_clk);
  26643. + clk_prepare_enable(gpu2d_axi_clk);
  26644. + clk_prepare_enable(openvg_axi_clk);
  26645. + }
  26646. + } else {
  26647. + if (cpu_is_imx6sl()) {
  26648. + clk_disable_unprepare(gpu2d_clk);
  26649. + clk_disable_unprepare(openvg_axi_clk);
  26650. + } else {
  26651. + clk_disable_unprepare(openvg_axi_clk);
  26652. + clk_disable_unprepare(gpu2d_axi_clk);
  26653. + clk_disable_unprepare(gpu2d_clk);
  26654. + clk_disable_unprepare(gpu3d_shader_clk);
  26655. + clk_disable_unprepare(gpu3d_clk);
  26656. + clk_disable_unprepare(vpu_clk);
  26657. + }
  26658. + }
  26659. +}
  26660. +
  26661. +static void imx_gpc_pu_enable(bool enable)
  26662. +{
  26663. + u32 rate, delay_us;
  26664. + u32 gpu_pupscr_sw2iso, gpu_pdnscr_iso2sw;
  26665. + u32 gpu_pupscr_sw, gpu_pdnscr_iso;
  26666. +
  26667. + /* get ipg clk rate for PGC delay */
  26668. + rate = clk_get_rate(ipg_clk);
  26669. +
  26670. + if (enable) {
  26671. + imx_anatop_pu_enable(true);
  26672. + /*
  26673. + * need to add necessary delay between powering up PU LDO and
  26674. + * disabling PU isolation in PGC, the counter of PU isolation
  26675. + * is based on ipg clk.
  26676. + */
  26677. + gpu_pupscr_sw2iso = (readl_relaxed(gpc_base +
  26678. + GPC_PGC_GPU_PUPSCR) >> GPC_PGC_GPU_SW2ISO_SHIFT)
  26679. + & GPC_PGC_GPU_SW2ISO_MASK;
  26680. + gpu_pupscr_sw = (readl_relaxed(gpc_base +
  26681. + GPC_PGC_GPU_PUPSCR) >> GPC_PGC_GPU_SW_SHIFT)
  26682. + & GPC_PGC_GPU_SW_MASK;
  26683. + delay_us = (gpu_pupscr_sw2iso + gpu_pupscr_sw) * 1000000
  26684. + / rate + 1;
  26685. + udelay(delay_us);
  26686. +
  26687. + imx_pu_clk(true);
  26688. + writel_relaxed(1, gpc_base + GPC_PGC_GPU_PDN);
  26689. + writel_relaxed(1 << GPC_CNTR_PU_UP_REQ_SHIFT,
  26690. + gpc_base + GPC_CNTR);
  26691. + while (readl_relaxed(gpc_base + GPC_CNTR) &
  26692. + (1 << GPC_CNTR_PU_UP_REQ_SHIFT))
  26693. + ;
  26694. + imx_pu_clk(false);
  26695. + } else {
  26696. + writel_relaxed(1, gpc_base + GPC_PGC_GPU_PDN);
  26697. + writel_relaxed(1 << GPC_CNTR_PU_DOWN_REQ_SHIFT,
  26698. + gpc_base + GPC_CNTR);
  26699. + while (readl_relaxed(gpc_base + GPC_CNTR) &
  26700. + (1 << GPC_CNTR_PU_DOWN_REQ_SHIFT))
  26701. + ;
  26702. + /*
  26703. + * need to add necessary delay between enabling PU isolation
  26704. + * in PGC and powering down PU LDO , the counter of PU isolation
  26705. + * is based on ipg clk.
  26706. + */
  26707. + gpu_pdnscr_iso2sw = (readl_relaxed(gpc_base +
  26708. + GPC_PGC_GPU_PDNSCR) >> GPC_PGC_GPU_SW2ISO_SHIFT)
  26709. + & GPC_PGC_GPU_SW2ISO_MASK;
  26710. + gpu_pdnscr_iso = (readl_relaxed(gpc_base +
  26711. + GPC_PGC_GPU_PDNSCR) >> GPC_PGC_GPU_SW_SHIFT)
  26712. + & GPC_PGC_GPU_SW_MASK;
  26713. + delay_us = (gpu_pdnscr_iso2sw + gpu_pdnscr_iso) * 1000000
  26714. + / rate + 1;
  26715. + udelay(delay_us);
  26716. + imx_anatop_pu_enable(false);
  26717. + }
  26718. +}
  26719. +
  26720. +static int imx_gpc_regulator_notify(struct notifier_block *nb,
  26721. + unsigned long event,
  26722. + void *ignored)
  26723. +{
  26724. + switch (event) {
  26725. + case REGULATOR_EVENT_PRE_DISABLE:
  26726. + imx_gpc_pu_enable(false);
  26727. + break;
  26728. + case REGULATOR_EVENT_ENABLE:
  26729. + imx_gpc_pu_enable(true);
  26730. + break;
  26731. + default:
  26732. + break;
  26733. + }
  26734. +
  26735. + return NOTIFY_OK;
  26736. +}
  26737. +
  26738. void __init imx_gpc_init(void)
  26739. {
  26740. struct device_node *np;
  26741. int i;
  26742. + u32 val;
  26743. + u32 cpu_pupscr_sw2iso, cpu_pupscr_sw;
  26744. + u32 cpu_pdnscr_iso2sw, cpu_pdnscr_iso;
  26745. np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
  26746. gpc_base = of_iomap(np, 0);
  26747. @@ -137,4 +285,190 @@
  26748. gic_arch_extn.irq_mask = imx_gpc_irq_mask;
  26749. gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
  26750. gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
  26751. +
  26752. + /*
  26753. + * If there are CPU isolation timing settings in dts,
  26754. + * update them according to dts, otherwise, keep them
  26755. + * with default value in registers.
  26756. + */
  26757. + cpu_pupscr_sw2iso = cpu_pupscr_sw =
  26758. + cpu_pdnscr_iso2sw = cpu_pdnscr_iso = 0;
  26759. +
  26760. + /* Read CPU isolation setting for GPC */
  26761. + of_property_read_u32(np, "fsl,cpu_pupscr_sw2iso", &cpu_pupscr_sw2iso);
  26762. + of_property_read_u32(np, "fsl,cpu_pupscr_sw", &cpu_pupscr_sw);
  26763. + of_property_read_u32(np, "fsl,cpu_pdnscr_iso2sw", &cpu_pdnscr_iso2sw);
  26764. + of_property_read_u32(np, "fsl,cpu_pdnscr_iso", &cpu_pdnscr_iso);
  26765. +
  26766. + /* Update CPU PUPSCR timing if it is defined in dts */
  26767. + val = readl_relaxed(gpc_base + GPC_PGC_CPU_PUPSCR);
  26768. + if (cpu_pupscr_sw2iso)
  26769. + val &= ~(GPC_PGC_CPU_SW2ISO_MASK << GPC_PGC_CPU_SW2ISO_SHIFT);
  26770. + if (cpu_pupscr_sw)
  26771. + val &= ~(GPC_PGC_CPU_SW_MASK << GPC_PGC_CPU_SW_SHIFT);
  26772. + val |= cpu_pupscr_sw2iso << GPC_PGC_CPU_SW2ISO_SHIFT;
  26773. + val |= cpu_pupscr_sw << GPC_PGC_CPU_SW_SHIFT;
  26774. + writel_relaxed(val, gpc_base + GPC_PGC_CPU_PUPSCR);
  26775. +
  26776. + /* Update CPU PDNSCR timing if it is defined in dts */
  26777. + val = readl_relaxed(gpc_base + GPC_PGC_CPU_PDNSCR);
  26778. + if (cpu_pdnscr_iso2sw)
  26779. + val &= ~(GPC_PGC_CPU_SW2ISO_MASK << GPC_PGC_CPU_SW2ISO_SHIFT);
  26780. + if (cpu_pdnscr_iso)
  26781. + val &= ~(GPC_PGC_CPU_SW_MASK << GPC_PGC_CPU_SW_SHIFT);
  26782. + val |= cpu_pdnscr_iso2sw << GPC_PGC_CPU_SW2ISO_SHIFT;
  26783. + val |= cpu_pdnscr_iso << GPC_PGC_CPU_SW_SHIFT;
  26784. + writel_relaxed(val, gpc_base + GPC_PGC_CPU_PDNSCR);
  26785. +}
  26786. +
  26787. +static int imx_pureg_set_voltage(struct regulator_dev *reg, int min_uV,
  26788. + int max_uV, unsigned *selector)
  26789. +{
  26790. + return 0;
  26791. +}
  26792. +
  26793. +static int imx_pureg_enable(struct regulator_dev *rdev)
  26794. +{
  26795. + pu_dummy_enable = 1;
  26796. +
  26797. + return 0;
  26798. +}
  26799. +
  26800. +static int imx_pureg_disable(struct regulator_dev *rdev)
  26801. +{
  26802. + pu_dummy_enable = 0;
  26803. +
  26804. + return 0;
  26805. }
  26806. +
  26807. +static int imx_pureg_is_enable(struct regulator_dev *rdev)
  26808. +{
  26809. + return pu_dummy_enable;
  26810. +}
  26811. +
  26812. +static int imx_pureg_list_voltage(struct regulator_dev *rdev,
  26813. + unsigned int selector)
  26814. +{
  26815. + return 0;
  26816. +}
  26817. +
  26818. +static struct regulator_ops pu_dummy_ops = {
  26819. + .set_voltage = imx_pureg_set_voltage,
  26820. + .enable = imx_pureg_enable,
  26821. + .disable = imx_pureg_disable,
  26822. + .is_enabled = imx_pureg_is_enable,
  26823. + .list_voltage = imx_pureg_list_voltage,
  26824. +};
  26825. +
  26826. +static struct regulator_desc pu_dummy_desc = {
  26827. + .name = "pureg-dummy",
  26828. + .id = -1,
  26829. + .type = REGULATOR_VOLTAGE,
  26830. + .owner = THIS_MODULE,
  26831. + .ops = &pu_dummy_ops,
  26832. +};
  26833. +
  26834. +static int pu_dummy_probe(struct platform_device *pdev)
  26835. +{
  26836. + struct regulator_config config = { };
  26837. + int ret;
  26838. +
  26839. + config.dev = &pdev->dev;
  26840. + config.init_data = &pu_dummy_initdata;
  26841. + config.of_node = pdev->dev.of_node;
  26842. +
  26843. + pu_dummy_regulator_rdev = regulator_register(&pu_dummy_desc, &config);
  26844. + if (IS_ERR(pu_dummy_regulator_rdev)) {
  26845. + ret = PTR_ERR(pu_dummy_regulator_rdev);
  26846. + dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
  26847. + return ret;
  26848. + }
  26849. +
  26850. + return 0;
  26851. +}
  26852. +
  26853. +static const struct of_device_id imx_pudummy_ids[] = {
  26854. + { .compatible = "fsl,imx6-dummy-pureg" },
  26855. +};
  26856. +MODULE_DEVICE_TABLE(of, imx_pudummy_ids);
  26857. +
  26858. +static struct platform_driver pu_dummy_driver = {
  26859. + .probe = pu_dummy_probe,
  26860. + .driver = {
  26861. + .name = "pu-dummy",
  26862. + .owner = THIS_MODULE,
  26863. + .of_match_table = imx_pudummy_ids,
  26864. + },
  26865. +};
  26866. +
  26867. +static int imx_gpc_probe(struct platform_device *pdev)
  26868. +{
  26869. + int ret;
  26870. +
  26871. + gpc_dev = &pdev->dev;
  26872. +
  26873. + pu_reg = devm_regulator_get(gpc_dev, "pu");
  26874. + if (IS_ERR(pu_reg)) {
  26875. + ret = PTR_ERR(pu_reg);
  26876. + dev_info(gpc_dev, "pu regulator not ready.\n");
  26877. + return ret;
  26878. + }
  26879. + nb.notifier_call = &imx_gpc_regulator_notify;
  26880. +
  26881. + /* Get gpu&vpu clk for power up PU by GPC */
  26882. + if (cpu_is_imx6sl()) {
  26883. + gpu2d_clk = devm_clk_get(gpc_dev, "gpu2d_podf");
  26884. + openvg_axi_clk = devm_clk_get(gpc_dev, "gpu2d_ovg");
  26885. + ipg_clk = devm_clk_get(gpc_dev, "ipg");
  26886. + if (IS_ERR(gpu2d_clk) || IS_ERR(openvg_axi_clk)
  26887. + || IS_ERR(ipg_clk)) {
  26888. + dev_err(gpc_dev, "failed to get clk!\n");
  26889. + return -ENOENT;
  26890. + }
  26891. + } else {
  26892. + gpu3d_clk = devm_clk_get(gpc_dev, "gpu3d_core");
  26893. + gpu3d_shader_clk = devm_clk_get(gpc_dev, "gpu3d_shader");
  26894. + gpu2d_clk = devm_clk_get(gpc_dev, "gpu2d_core");
  26895. + gpu2d_axi_clk = devm_clk_get(gpc_dev, "gpu2d_axi");
  26896. + openvg_axi_clk = devm_clk_get(gpc_dev, "openvg_axi");
  26897. + vpu_clk = devm_clk_get(gpc_dev, "vpu_axi");
  26898. + ipg_clk = devm_clk_get(gpc_dev, "ipg");
  26899. + if (IS_ERR(gpu3d_clk) || IS_ERR(gpu3d_shader_clk)
  26900. + || IS_ERR(gpu2d_clk) || IS_ERR(gpu2d_axi_clk)
  26901. + || IS_ERR(openvg_axi_clk) || IS_ERR(vpu_clk)
  26902. + || IS_ERR(ipg_clk)) {
  26903. + dev_err(gpc_dev, "failed to get clk!\n");
  26904. + return -ENOENT;
  26905. + }
  26906. + }
  26907. +
  26908. + ret = regulator_register_notifier(pu_reg, &nb);
  26909. + if (ret) {
  26910. + dev_err(gpc_dev,
  26911. + "regulator notifier request failed\n");
  26912. + return ret;
  26913. + }
  26914. +
  26915. + return 0;
  26916. +}
  26917. +
  26918. +static const struct of_device_id imx_gpc_ids[] = {
  26919. + { .compatible = "fsl,imx6q-gpc" },
  26920. +};
  26921. +MODULE_DEVICE_TABLE(of, imx_gpc_ids);
  26922. +
  26923. +static struct platform_driver imx_gpc_platdrv = {
  26924. + .driver = {
  26925. + .name = "imx-gpc",
  26926. + .owner = THIS_MODULE,
  26927. + .of_match_table = imx_gpc_ids,
  26928. + },
  26929. + .probe = imx_gpc_probe,
  26930. +};
  26931. +module_platform_driver(imx_gpc_platdrv);
  26932. +
  26933. +module_platform_driver(pu_dummy_driver);
  26934. +
  26935. +MODULE_AUTHOR("Anson Huang <b20788@freescale.com>");
  26936. +MODULE_DESCRIPTION("Freescale i.MX GPC driver");
  26937. +MODULE_LICENSE("GPL");
  26938. diff -Nur linux-3.14.14/arch/arm/mach-imx/hardware.h linux-imx6-3.14/arch/arm/mach-imx/hardware.h
  26939. --- linux-3.14.14/arch/arm/mach-imx/hardware.h 2014-07-28 10:07:25.000000000 -0500
  26940. +++ linux-imx6-3.14/arch/arm/mach-imx/hardware.h 2014-12-08 00:31:51.224418001 -0600
  26941. @@ -1,5 +1,5 @@
  26942. /*
  26943. - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
  26944. + * Copyright 2004-2007, 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  26945. * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
  26946. *
  26947. * This program is free software; you can redistribute it and/or
  26948. @@ -20,7 +20,9 @@
  26949. #ifndef __ASM_ARCH_MXC_HARDWARE_H__
  26950. #define __ASM_ARCH_MXC_HARDWARE_H__
  26951. +#ifndef __ASSEMBLY__
  26952. #include <asm/io.h>
  26953. +#endif
  26954. #include <asm/sizes.h>
  26955. #define addr_in_module(addr, mod) \
  26956. diff -Nur linux-3.14.14/arch/arm/mach-imx/headsmp.S linux-imx6-3.14/arch/arm/mach-imx/headsmp.S
  26957. --- linux-3.14.14/arch/arm/mach-imx/headsmp.S 2014-07-28 10:07:25.000000000 -0500
  26958. +++ linux-imx6-3.14/arch/arm/mach-imx/headsmp.S 2014-12-08 00:31:51.224418001 -0600
  26959. @@ -12,8 +12,6 @@
  26960. #include <linux/linkage.h>
  26961. #include <linux/init.h>
  26962. -#include <asm/asm-offsets.h>
  26963. -#include <asm/hardware/cache-l2x0.h>
  26964. .section ".text.head", "ax"
  26965. @@ -35,37 +33,3 @@
  26966. b secondary_startup
  26967. ENDPROC(v7_secondary_startup)
  26968. #endif
  26969. -
  26970. -#ifdef CONFIG_ARM_CPU_SUSPEND
  26971. -/*
  26972. - * The following code must assume it is running from physical address
  26973. - * where absolute virtual addresses to the data section have to be
  26974. - * turned into relative ones.
  26975. - */
  26976. -
  26977. -#ifdef CONFIG_CACHE_L2X0
  26978. - .macro pl310_resume
  26979. - adr r0, l2x0_saved_regs_offset
  26980. - ldr r2, [r0]
  26981. - add r2, r2, r0
  26982. - ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0
  26983. - ldr r1, [r2, #L2X0_R_AUX_CTRL] @ get aux_ctrl value
  26984. - str r1, [r0, #L2X0_AUX_CTRL] @ restore aux_ctrl
  26985. - mov r1, #0x1
  26986. - str r1, [r0, #L2X0_CTRL] @ re-enable L2
  26987. - .endm
  26988. -
  26989. -l2x0_saved_regs_offset:
  26990. - .word l2x0_saved_regs - .
  26991. -
  26992. -#else
  26993. - .macro pl310_resume
  26994. - .endm
  26995. -#endif
  26996. -
  26997. -ENTRY(v7_cpu_resume)
  26998. - bl v7_invalidate_l1
  26999. - pl310_resume
  27000. - b cpu_resume
  27001. -ENDPROC(v7_cpu_resume)
  27002. -#endif
  27003. diff -Nur linux-3.14.14/arch/arm/mach-imx/imx6sl_wfi.S linux-imx6-3.14/arch/arm/mach-imx/imx6sl_wfi.S
  27004. --- linux-3.14.14/arch/arm/mach-imx/imx6sl_wfi.S 1969-12-31 18:00:00.000000000 -0600
  27005. +++ linux-imx6-3.14/arch/arm/mach-imx/imx6sl_wfi.S 2014-12-08 00:31:51.224418001 -0600
  27006. @@ -0,0 +1,639 @@
  27007. +/*
  27008. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  27009. + *
  27010. + * This program is free software; you can redistribute it and/or modify
  27011. + * it under the terms of the GNU General Public License as published by
  27012. + * the Free Software Foundation; either version 2 of the License, or
  27013. + * (at your option) any later version.
  27014. +
  27015. + * This program is distributed in the hope that it will be useful,
  27016. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27017. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27018. + * GNU General Public License for more details.
  27019. +
  27020. + * You should have received a copy of the GNU General Public License along
  27021. + * with this program; if not, write to the Free Software Foundation, Inc.,
  27022. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  27023. + */
  27024. +
  27025. +#include <linux/linkage.h>
  27026. +#define IRAM_WAIT_SIZE (1 << 11)
  27027. +
  27028. + .macro sl_ddr_io_save
  27029. +
  27030. + ldr r4, [r1, #0x30c] /* DRAM_DQM0 */
  27031. + ldr r5, [r1, #0x310] /* DRAM_DQM1 */
  27032. + ldr r6, [r1, #0x314] /* DRAM_DQM2 */
  27033. + ldr r7, [r1, #0x318] /* DRAM_DQM3 */
  27034. + stmfd r9!, {r4-r7}
  27035. +
  27036. + ldr r4, [r1, #0x5c4] /* GPR_B0DS */
  27037. + ldr r5, [r1, #0x5cc] /* GPR_B1DS */
  27038. + ldr r6, [r1, #0x5d4] /* GPR_B2DS */
  27039. + ldr r7, [r1, #0x5d8] /* GPR_B3DS */
  27040. + stmfd r9!, {r4-r7}
  27041. +
  27042. + ldr r4, [r1, #0x300] /* DRAM_CAS */
  27043. + ldr r5, [r1, #0x31c] /* DRAM_RAS */
  27044. + ldr r6, [r1, #0x338] /* DRAM_SDCLK_0 */
  27045. + ldr r7, [r1, #0x5ac] /* GPR_ADDS*/
  27046. + stmfd r9!, {r4-r7}
  27047. +
  27048. + ldr r4, [r1, #0x5b0] /* DDRMODE_CTL */
  27049. + ldr r5, [r1, #0x5c0] /* DDRMODE */
  27050. + ldr r6, [r1, #0x33c] /* DRAM_SODT0*/
  27051. + ldr r7, [r1, #0x340] /* DRAM_SODT1*/
  27052. + stmfd r9!, {r4-r7}
  27053. +
  27054. + ldr r4, [r1, #0x330] /* DRAM_SDCKE0 */
  27055. + ldr r5, [r1, #0x334] /* DRAM_SDCKE1 */
  27056. + ldr r6, [r1, #0x320] /* DRAM_RESET */
  27057. + stmfd r9!, {r4-r6}
  27058. +
  27059. + .endm
  27060. +
  27061. + .macro sl_ddr_io_restore
  27062. +
  27063. + /*
  27064. + * r9 points to IRAM stack.
  27065. + * r1 points to IOMUX base address.
  27066. + * r8 points to MMDC base address.
  27067. + */
  27068. + ldmea r9!, {r4-r7}
  27069. + str r4, [r1, #0x30c] /* DRAM_DQM0 */
  27070. + str r5, [r1, #0x310] /* DRAM_DQM1 */
  27071. + str r6, [r1, #0x314] /* DRAM_DQM2 */
  27072. + str r7, [r1, #0x318] /* DRAM_DQM3 */
  27073. +
  27074. + ldmea r9!, {r4-r7}
  27075. + str r4, [r1, #0x5c4] /* GPR_B0DS */
  27076. + str r5, [r1, #0x5cc] /* GPR_B1DS */
  27077. + str r6, [r1, #0x5d4] /* GPR_B2DS */
  27078. + str r7, [r1, #0x5d8] /* GPR_B3DS */
  27079. +
  27080. + ldmea r9!, {r4-r7}
  27081. + str r4, [r1, #0x300] /* DRAM_CAS */
  27082. + str r5, [r1, #0x31c] /* DRAM_RAS */
  27083. + str r6, [r1, #0x338] /* DRAM_SDCLK_0 */
  27084. + str r7, [r1, #0x5ac] /* GPR_ADDS*/
  27085. +
  27086. + ldmea r9!, {r4-r7}
  27087. + str r4, [r1, #0x5b0] /* DDRMODE_CTL */
  27088. + str r5, [r1, #0x5c0] /* DDRMODE */
  27089. + str r6, [r1, #0x33c] /* DRAM_SODT0*/
  27090. + str r7, [r1, #0x340] /* DRAM_SODT1*/
  27091. +
  27092. + ldmea r9!, {r4-r6}
  27093. + str r4, [r1, #0x330] /* DRAM_SDCKE0 */
  27094. + str r5, [r1, #0x334] /* DRAM_SDCKE1 */
  27095. + str r6, [r1, #0x320] /* DRAM_RESET */
  27096. +
  27097. + /*
  27098. + * Need to reset the FIFO to avoid MMDC lockup
  27099. + * caused because of floating/changing the
  27100. + * configuration of many DDR IO pads.
  27101. + */
  27102. + ldr r7, =0x83c
  27103. + ldr r6, [r8, r7]
  27104. + orr r6, r6, #0x80000000
  27105. + str r6, [r8, r7]
  27106. +fifo_reset1_wait:
  27107. + ldr r6, [r8, r7]
  27108. + and r6, r6, #0x80000000
  27109. + cmp r6, #0
  27110. + bne fifo_reset1_wait
  27111. +
  27112. + /* reset FIFO a second time */
  27113. + ldr r6, [r8, r7]
  27114. + orr r6, r6, #0x80000000
  27115. + str r6, [r8, r7]
  27116. +fifo_reset2_wait:
  27117. + ldr r6, [r8, r7]
  27118. + and r6, r6, #0x80000000
  27119. + cmp r6, #0
  27120. + bne fifo_reset2_wait
  27121. +
  27122. + .endm
  27123. +
  27124. + .macro sl_ddr_io_set_lpm
  27125. +
  27126. + mov r4, #0
  27127. + str r4, [r1, #0x30c] /* DRAM_DQM0 */
  27128. + str r4, [r1, #0x310] /* DRAM_DQM1 */
  27129. + str r4, [r1, #0x314] /* DRAM_DQM2 */
  27130. + str r4, [r1, #0x318] /* DRAM_DQM3 */
  27131. +
  27132. + str r4, [r1, #0x5c4] /* GPR_B0DS */
  27133. + str r4, [r1, #0x5cc] /* GPR_B1DS */
  27134. + str r4, [r1, #0x5d4] /* GPR_B2DS */
  27135. + str r4, [r1, #0x5d8] /* GPR_B3DS */
  27136. +
  27137. + str r4, [r1, #0x300] /* DRAM_CAS */
  27138. + str r4, [r1, #0x31c] /* DRAM_RAS */
  27139. + str r4, [r1, #0x338] /* DRAM_SDCLK_0 */
  27140. + str r4, [r1, #0x5ac] /* GPR_ADDS*/
  27141. +
  27142. + str r4, [r1, #0x5b0] /* DDRMODE_CTL */
  27143. + str r4, [r1, #0x5c0] /* DDRMODE */
  27144. + str r4, [r1, #0x33c] /* DRAM_SODT0*/
  27145. + str r4, [r1, #0x340] /* DRAM_SODT1*/
  27146. +
  27147. + mov r4, #0x80000
  27148. + str r4, [r1, #0x320] /* DRAM_RESET */
  27149. + mov r4, #0x1000
  27150. + str r4, [r1, #0x330] /* DRAM_SDCKE0 */
  27151. + str r4, [r1, #0x334] /* DRAM_SDCKE1 */
  27152. +
  27153. + .endm
  27154. +
  27155. +/*
  27156. + * imx6sl_low_power_wfi
  27157. + *
  27158. + * Idle the processor (eg, wait for interrupt).
  27159. + * Make sure DDR is in self-refresh.
  27160. + * IRQs are already disabled.
  27161. + * r0: WFI IRAMcode base address.
  27162. + * r1: IOMUX base address
  27163. + * r2: Base address of CCM, ANATOP and MMDC
  27164. + * r3: 1 if in audio_bus_freq_mode
  27165. + */
  27166. + .align 3
  27167. +ENTRY(imx6sl_low_power_wfi)
  27168. +
  27169. + push {r4-r11}
  27170. +
  27171. +mx6sl_lpm_wfi:
  27172. + /* Store audio_bus_freq_mode */
  27173. + mov r11, r3
  27174. +
  27175. + mov r4,r2
  27176. + /* Get the IRAM data storage address. */
  27177. + mov r10, r0
  27178. + mov r9, r0 /* get suspend_iram_base */
  27179. + add r9, r9, #IRAM_WAIT_SIZE
  27180. +
  27181. + /* Anatop Base address in r3. */
  27182. + ldr r3, [r4]
  27183. + /* CCM Base Address in r2 */
  27184. + ldr r2, [r4, #0x4]
  27185. + /* MMDC Base Address in r8 */
  27186. + ldr r8, [r4, #0x8]
  27187. + /* L2 Base Address in r7 */
  27188. + ldr r7, [r4, #0xC]
  27189. +
  27190. + ldr r6, [r8]
  27191. + ldr r6, [r3]
  27192. + ldr r6, [r2]
  27193. + ldr r6, [r1]
  27194. +
  27195. + /* Store the original ARM PODF. */
  27196. + ldr r0, [r2, #0x10]
  27197. +
  27198. + /* Drain all the L1 buffers. */
  27199. + dsb
  27200. +
  27201. +#ifdef CONFIG_CACHE_L2X0
  27202. + /*
  27203. + * Need to make sure the buffers in L2 are drained.
  27204. + * Performing a sync operation does this.
  27205. + */
  27206. + mov r6, #0x0
  27207. + str r6, [r7, #0x730]
  27208. +#endif
  27209. +
  27210. + /*
  27211. + * The second dsb might be needed to keep cache sync (device write)
  27212. + * ordering with the memory accesses before it.
  27213. + */
  27214. + dsb
  27215. + isb
  27216. +
  27217. + /* Save the DDR IO state. */
  27218. + sl_ddr_io_save
  27219. +
  27220. + /* Disable Automatic power savings. */
  27221. + ldr r6, [r8, #0x404]
  27222. + orr r6, r6, #0x01
  27223. + str r6, [r8, #0x404]
  27224. +
  27225. + /* Make the DDR explicitly enter self-refresh. */
  27226. + ldr r6, [r8, #0x404]
  27227. + orr r6, r6, #0x200000
  27228. + str r6, [r8, #0x404]
  27229. +
  27230. +poll_dvfs_set_1:
  27231. + ldr r6, [r8, #0x404]
  27232. + and r6, r6, #0x2000000
  27233. + cmp r6, #0x2000000
  27234. + bne poll_dvfs_set_1
  27235. +
  27236. + /* set SBS step-by-step mode */
  27237. + ldr r6, [r8, #0x410]
  27238. + orr r6, r6, #0x100
  27239. + str r6, [r8, #0x410]
  27240. +
  27241. + cmp r11, #1
  27242. + beq audio_mode
  27243. + /*
  27244. + * Now set DDR rate to 1MHz.
  27245. + * DDR is from bypassed PLL2 on periph2_clk2 path.
  27246. + * Set the periph2_clk2_podf to divide by 8.
  27247. + */
  27248. + ldr r6, [r2, #0x14]
  27249. + orr r6, r6, #0x07
  27250. + str r6, [r2, #0x14]
  27251. +
  27252. + /* Now set MMDC PODF to divide by 3. */
  27253. + ldr r6, [r2, #0x14]
  27254. + bic r6, r6, #0x38
  27255. + orr r6, r6, #0x10
  27256. + str r6, [r2, #0x14]
  27257. + b mmdc_podf
  27258. +
  27259. +audio_mode:
  27260. + /* MMDC is from PLL2_200M.
  27261. + * Set the mmdc_podf to div by 8.
  27262. + */
  27263. + ldr r6, [r2, #0x14]
  27264. + orr r6, r6, #0x38
  27265. + str r6, [r2, #0x14]
  27266. +
  27267. + /* Loop till podf is accepted. */
  27268. +mmdc_podf:
  27269. + ldr r6, [r2, #0x48]
  27270. + cmp r6, #0x0
  27271. + bne mmdc_podf
  27272. +
  27273. + /* Set the DDR IO in LPM state. */
  27274. + sl_ddr_io_set_lpm
  27275. +
  27276. + cmp r11, #1
  27277. + beq do_audio_arm_clk
  27278. +
  27279. + /*
  27280. + * Check if none of the PLLs are
  27281. + * locked, except PLL1 which will get
  27282. + * bypassed below.
  27283. + * We should not be here if PLL2 is not
  27284. + * bypassed.
  27285. + */
  27286. + ldr r7, =1
  27287. + /* USB1 PLL3 */
  27288. + ldr r6, [r3, #0x10]
  27289. + and r6, r6, #0x80000000
  27290. + cmp r6, #0x80000000
  27291. + beq no_analog_saving
  27292. +
  27293. + /* USB2 PLL7 */
  27294. + ldr r6, [r3, #0x20]
  27295. + and r6, r6, #0x80000000
  27296. + cmp r6, #0x80000000
  27297. + beq no_analog_saving
  27298. +
  27299. + /* Audio PLL4 */
  27300. + ldr r6, [r3, #0x70]
  27301. + and r6, r6, #0x80000000
  27302. + cmp r6, #0x80000000
  27303. + beq no_analog_saving
  27304. +
  27305. + /* Video PLL5 */
  27306. + ldr r6, [r3, #0xA0]
  27307. + and r6, r6, #0x80000000
  27308. + cmp r6, #0x80000000
  27309. + beq no_analog_saving
  27310. +
  27311. + /* ENET PLL8 */
  27312. + ldr r6, [r3, #0xE0]
  27313. + and r6, r6, #0x80000000
  27314. + cmp r6, #0x80000000
  27315. + beq no_analog_saving
  27316. +
  27317. + b cont
  27318. +
  27319. +no_analog_saving:
  27320. + ldr r7, =0
  27321. +
  27322. +cont:
  27323. + /* Set the AHB to 3MHz. AXI to 3MHz. */
  27324. + ldr r9, [r2, #0x14]
  27325. + mov r6, r9
  27326. + orr r6, r6, #0x1c00
  27327. + orr r6, r6, #0x70000
  27328. + str r6, [r2, #0x14]
  27329. +
  27330. + /* Loop till podf is accepted. */
  27331. +ahb_podf:
  27332. + ldr r6, [r2, #0x48]
  27333. + cmp r6, #0x0
  27334. + bne podf_loop
  27335. +
  27336. + /*
  27337. + * Now set ARM to 24MHz.
  27338. + * Move ARM to be sourced from STEP_CLK
  27339. + * after setting STEP_CLK to 24MHz.
  27340. + */
  27341. + ldr r6, [r2, #0xc]
  27342. + bic r6, r6, #0x100
  27343. + str r6, [r2, #0x0c]
  27344. + /* Now PLL1_SW_CLK to step_clk. */
  27345. + ldr r6, [r2, #0x0c]
  27346. + orr r6, r6, #0x4
  27347. + str r6, [r2, #0x0c]
  27348. +
  27349. + /* Bypass PLL1 and power it down. */
  27350. + ldr r6, =(1 << 16)
  27351. + orr r6, r6, #0x1000
  27352. + str r6, [r3, #0x04]
  27353. +
  27354. + /*
  27355. + * Set the ARM PODF to divide by 8.
  27356. + * IPG is at 1.5MHz here, we need ARM to
  27357. + * run at the 12:5 ratio (WAIT mode issue).
  27358. + */
  27359. + ldr r6, =0x7
  27360. + str r6, [r2, #0x10]
  27361. +
  27362. + /* Loop till podf is accepted. */
  27363. +podf_loop:
  27364. + ldr r6, [r2, #0x48]
  27365. + cmp r6, #0x0
  27366. + bne podf_loop
  27367. +
  27368. + /*
  27369. + * Check if we can save some
  27370. + * power in the Analog section.
  27371. + */
  27372. + cmp r7, #0x1
  27373. + bne do_wfi
  27374. +
  27375. + /* Disable 1p1 brown out. */
  27376. + ldr r6, [r3, #0x110]
  27377. + bic r6, r6, #0x2
  27378. + str r6, [r3, #0x110]
  27379. +
  27380. + /* Enable the weak 2P5 */
  27381. + ldr r6, [r3, #0x130]
  27382. + orr r6, r6, #0x40000
  27383. + str r6, [r3, #0x130]
  27384. +
  27385. + /* Disable main 2p5. */
  27386. + ldr r6, [r3, #0x130]
  27387. + bic r6, r6, #0x1
  27388. + str r6, [r3, #0x130]
  27389. +
  27390. + /*
  27391. + * Set the OSC bias current to -37.5%
  27392. + * to drop the power on VDDHIGH.
  27393. + */
  27394. + ldr r6, [r3, #0x150]
  27395. + orr r6, r6, #0xC000
  27396. + str r6, [r3, #0x150]
  27397. +
  27398. + /* Enable low power bandgap */
  27399. + ldr r6, [r3, #0x260]
  27400. + orr r6, r6, #0x20
  27401. + str r6, [r3, #0x260]
  27402. +
  27403. + /*
  27404. + * Turn off the bias current
  27405. + * from the regular bandgap.
  27406. + */
  27407. + ldr r6, [r3, #0x260]
  27408. + orr r6, r6, #0x80
  27409. + str r6, [r3, #0x260]
  27410. +
  27411. + /*
  27412. + * Clear the REFTOP_SELFBIASOFF,
  27413. + * self-bias circuit of the band gap.
  27414. + * Per RM, should be cleared when
  27415. + * band gap is powered down.
  27416. + */
  27417. + ldr r6, [r3, #0x150]
  27418. + bic r6, r6, #0x8
  27419. + str r6, [r3, #0x150]
  27420. +
  27421. + /* Power down the regular bandgap. */
  27422. + ldr r6, [r3, #0x150]
  27423. + orr r6, r6, #0x1
  27424. + str r6, [r3, #0x150]
  27425. +
  27426. + b do_wfi
  27427. +
  27428. +do_audio_arm_clk:
  27429. + /*
  27430. + * ARM is from PLL2_PFD2_400M here.
  27431. + * Switch ARM to bypassed PLL1.
  27432. + */
  27433. + ldr r6, [r2, #0xC]
  27434. + bic r6, r6, #0x4
  27435. + str r6, [r2, #0xC]
  27436. +
  27437. + /*
  27438. + * Set the ARM_PODF to divide by 2
  27439. + * as IPG is at 4MHz, we cannot run
  27440. + * ARM_CLK above 9.6MHz when
  27441. + * system enters WAIT mode.
  27442. + */
  27443. + ldr r6, =0x2
  27444. + str r6, [r2, #0x10]
  27445. +
  27446. + /* Loop till podf is accepted. */
  27447. +podf_loop_audio:
  27448. + ldr r6, [r2, #0x48]
  27449. + cmp r6, #0x0
  27450. + bne podf_loop_audio
  27451. +
  27452. +do_wfi:
  27453. + /* Now do WFI. */
  27454. + wfi
  27455. +
  27456. + /* Set original ARM PODF back. */
  27457. + str r0, [r2, #0x10]
  27458. +
  27459. + /* Loop till podf is accepted. */
  27460. +podf_loop1:
  27461. + ldr r6, [r2, #0x48]
  27462. + cmp r6, #0x0
  27463. + bne podf_loop1
  27464. +
  27465. + cmp r11, #1
  27466. + beq audio_arm_clk_restore
  27467. +
  27468. + /*
  27469. + * Check if powered down
  27470. + * analog components.
  27471. + */
  27472. + cmp r7, #0x1
  27473. + bne skip_analog_restore
  27474. +
  27475. + /* Power up the regular bandgap. */
  27476. + ldr r6, [r3, #0x150]
  27477. + bic r6, r6, #0x1
  27478. + str r6, [r3, #0x150]
  27479. +
  27480. + /*
  27481. + * Turn on the bias current
  27482. + * from the regular bandgap.
  27483. + */
  27484. + ldr r6, [r3, #0x260]
  27485. + bic r6, r6, #0x80
  27486. + str r6, [r3, #0x260]
  27487. +
  27488. + /* Disable the low power bandgap */
  27489. + ldr r6, [r3, #0x260]
  27490. + bic r6, r6, #0x20
  27491. + str r6, [r3, #0x260]
  27492. +
  27493. + /*
  27494. + * Set the OSC bias current to max
  27495. + * value for normal operation.
  27496. + */
  27497. + ldr r6, [r3, #0x150]
  27498. + bic r6, r6, #0xC000
  27499. + str r6, [r3, #0x150]
  27500. +
  27501. + /* Enable main 2p5. */
  27502. + ldr r6, [r3, #0x130]
  27503. + orr r6, r6, #0x1
  27504. + str r6, [r3, #0x130]
  27505. +
  27506. + /* Ensure the 2P5 is up. */
  27507. +loop_2p5:
  27508. + ldr r6, [r3, #0x130]
  27509. + and r6, r6, #0x20000
  27510. + cmp r6, #0x20000
  27511. + bne loop_2p5
  27512. +
  27513. + /* Disable the weak 2P5 */
  27514. + ldr r6, [r3, #0x130]
  27515. + bic r6, r6, #0x40000
  27516. + str r6, [r3, #0x130]
  27517. +
  27518. + /* Enable 1p1 brown out. */
  27519. + ldr r6, [r3, #0x110]
  27520. + orr r6, r6, #0x2
  27521. + str r6, [r3, #0x110]
  27522. +
  27523. +skip_analog_restore:
  27524. +
  27525. + /* Power up PLL1 and un-bypass it. */
  27526. + ldr r6, =(1 << 12)
  27527. + str r6, [r3, #0x08]
  27528. +
  27529. + /* Wait for PLL1 to relock. */
  27530. +wait_for_pll_lock:
  27531. + ldr r6, [r3, #0x0]
  27532. + and r6, r6, #0x80000000
  27533. + cmp r6, #0x80000000
  27534. + bne wait_for_pll_lock
  27535. +
  27536. + ldr r6, =(1 << 16)
  27537. + str r6, [r3, #0x08]
  27538. +
  27539. + /* Set PLL1_sw_clk back to PLL1. */
  27540. + ldr r6, [r2, #0x0c]
  27541. + bic r6, r6, #0x4
  27542. + str r6, [r2, #0xc]
  27543. +
  27544. + /* Restore AHB/AXI back. */
  27545. + str r9, [r2, #0x14]
  27546. +
  27547. + /* Loop till podf is accepted. */
  27548. +ahb_podf1:
  27549. + ldr r6, [r2, #0x48]
  27550. + cmp r6, #0x0
  27551. + bne podf_loop1
  27552. +
  27553. + b wfi_restore
  27554. +
  27555. + audio_arm_clk_restore:
  27556. + /* Move ARM back to PLL2_PFD2_400M */
  27557. + ldr r6, [r2, #0xC]
  27558. + orr r6, r6, #0x4
  27559. + str r6, [r2, #0xC]
  27560. +
  27561. +wfi_restore:
  27562. + /* get suspend_iram_base */
  27563. + mov r9, r10
  27564. + add r9, r9, #IRAM_WAIT_SIZE
  27565. +
  27566. + /* Restore the DDR IO before exiting self-refresh. */
  27567. + sl_ddr_io_restore
  27568. +
  27569. + /*
  27570. + * Set MMDC back to 24MHz.
  27571. + * Set periph2_clk2_podf to divide by 1
  27572. + * Now set MMDC PODF to divide by 1.
  27573. + */
  27574. + ldr r6, [r2, #0x14]
  27575. + bic r6, r6, #0x3f
  27576. + str r6, [r2, #0x14]
  27577. +
  27578. +mmdc_podf1:
  27579. + ldr r6, [r2, #0x48]
  27580. + cmp r6, #0x0
  27581. + bne mmdc_podf1
  27582. +
  27583. + /* clear DVFS - exit from self refresh mode */
  27584. + ldr r6, [r8, #0x404]
  27585. + bic r6, r6, #0x200000
  27586. + str r6, [r8, #0x404]
  27587. +
  27588. +poll_dvfs_clear_1:
  27589. + ldr r6, [r8, #0x404]
  27590. + and r6, r6, #0x2000000
  27591. + cmp r6, #0x2000000
  27592. + beq poll_dvfs_clear_1
  27593. +
  27594. + /*
  27595. + * Add these nops so that the
  27596. + * prefetcher will not try to get
  27597. + * any instructions from DDR.
  27598. + * The prefetch depth is about 23
  27599. + * on A9, so adding 25 nops.
  27600. + */
  27601. + nop
  27602. + nop
  27603. + nop
  27604. + nop
  27605. + nop
  27606. +
  27607. + nop
  27608. + nop
  27609. + nop
  27610. + nop
  27611. + nop
  27612. +
  27613. + nop
  27614. + nop
  27615. + nop
  27616. + nop
  27617. + nop
  27618. +
  27619. + nop
  27620. + nop
  27621. + nop
  27622. + nop
  27623. + nop
  27624. +
  27625. + nop
  27626. + nop
  27627. + nop
  27628. + nop
  27629. + nop
  27630. +
  27631. + /* Enable Automatic power savings. */
  27632. + ldr r6, [r8, #0x404]
  27633. + bic r6, r6, #0x01
  27634. + str r6, [r8, #0x404]
  27635. +
  27636. + /* clear SBS - unblock DDR accesses */
  27637. + ldr r6, [r8, #0x410]
  27638. + bic r6, r6, #0x100
  27639. + str r6, [r8, #0x410]
  27640. +
  27641. +
  27642. + pop {r4-r11}
  27643. +
  27644. + /* Restore registers */
  27645. + mov pc, lr
  27646. diff -Nur linux-3.14.14/arch/arm/mach-imx/Kconfig linux-imx6-3.14/arch/arm/mach-imx/Kconfig
  27647. --- linux-3.14.14/arch/arm/mach-imx/Kconfig 2014-07-28 10:07:25.000000000 -0500
  27648. +++ linux-imx6-3.14/arch/arm/mach-imx/Kconfig 2014-12-08 00:31:51.220418001 -0600
  27649. @@ -1,5 +1,6 @@
  27650. config ARCH_MXC
  27651. bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
  27652. + select ARCH_HAS_RESET_CONTROLLER
  27653. select ARCH_REQUIRE_GPIOLIB
  27654. select ARM_CPU_SUSPEND if PM
  27655. select ARM_PATCH_PHYS_VIRT
  27656. @@ -13,6 +14,7 @@
  27657. select PINCTRL
  27658. select SOC_BUS
  27659. select SPARSE_IRQ
  27660. + select SRAM
  27661. select USE_OF
  27662. help
  27663. Support for Freescale MXC/iMX-based family of processors
  27664. @@ -63,7 +65,6 @@
  27665. config HAVE_IMX_SRC
  27666. def_bool y if SMP
  27667. - select ARCH_HAS_RESET_CONTROLLER
  27668. config IMX_HAVE_IOMUX_V1
  27669. bool
  27670. @@ -791,6 +792,8 @@
  27671. select ARM_ERRATA_754322
  27672. select ARM_ERRATA_764369 if SMP
  27673. select ARM_ERRATA_775420
  27674. + select ARM_ERRATA_794072 if SMP
  27675. + select ARM_ERRATA_761320 if SMP
  27676. select ARM_GIC
  27677. select CPU_V7
  27678. select HAVE_ARM_SCU if SMP
  27679. @@ -803,11 +806,13 @@
  27680. select MFD_SYSCON
  27681. select MIGHT_HAVE_PCI
  27682. select PCI_DOMAINS if PCI
  27683. + select ARCH_SUPPORTS_MSI
  27684. select PINCTRL_IMX6Q
  27685. select PL310_ERRATA_588369 if CACHE_PL310
  27686. select PL310_ERRATA_727915 if CACHE_PL310
  27687. select PL310_ERRATA_769419 if CACHE_PL310
  27688. select PM_OPP if PM
  27689. + select ZONE_DMA
  27690. help
  27691. This enables support for Freescale i.MX6 Quad processor.
  27692. diff -Nur linux-3.14.14/arch/arm/mach-imx/lpddr2_freq_imx6.S linux-imx6-3.14/arch/arm/mach-imx/lpddr2_freq_imx6.S
  27693. --- linux-3.14.14/arch/arm/mach-imx/lpddr2_freq_imx6.S 1969-12-31 18:00:00.000000000 -0600
  27694. +++ linux-imx6-3.14/arch/arm/mach-imx/lpddr2_freq_imx6.S 2014-12-08 00:31:51.228418001 -0600
  27695. @@ -0,0 +1,484 @@
  27696. +/*
  27697. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  27698. + *
  27699. + * This program is free software; you can redistribute it and/or modify
  27700. + * it under the terms of the GNU General Public License as published by
  27701. + * the Free Software Foundation; either version 2 of the License, or
  27702. + * (at your option) any later version.
  27703. +
  27704. + * This program is distributed in the hope that it will be useful,
  27705. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27706. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27707. + * GNU General Public License for more details.
  27708. +
  27709. + * You should have received a copy of the GNU General Public License along
  27710. + * with this program; if not, write to the Free Software Foundation, Inc.,
  27711. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  27712. + */
  27713. +
  27714. +#include <linux/linkage.h>
  27715. +
  27716. + .macro mx6sl_switch_to_24MHz
  27717. +
  27718. + /*
  27719. + * Set MMDC clock to be sourced from PLL3.
  27720. + * Ensure first periph2_clk2 is sourced from PLL3.
  27721. + * Set the PERIPH2_CLK2_PODF to divide by 2.
  27722. + */
  27723. + ldr r6, [r2, #0x14]
  27724. + bic r6, r6, #0x7
  27725. + orr r6, r6, #0x1
  27726. + str r6, [r2, #0x14]
  27727. +
  27728. + /* Select PLL3 to source MMDC. */
  27729. + ldr r6, [r2, #0x18]
  27730. + bic r6, r6, #0x100000
  27731. + str r6, [r2, #0x18]
  27732. +
  27733. + /* Swtich periph2_clk_sel to run from PLL3. */
  27734. + ldr r6, [r2, #0x14]
  27735. + orr r6, r6, #0x4000000
  27736. + str r6, [r2, #0x14]
  27737. +
  27738. +periph2_clk_switch1:
  27739. + ldr r6, [r2, #0x48]
  27740. + cmp r6, #0
  27741. + bne periph2_clk_switch1
  27742. +
  27743. + /*
  27744. + * Need to clock gate the 528 PFDs before
  27745. + * powering down PLL2.
  27746. + * Only the PLL2_PFD2_400M should be ON
  27747. + * at this time, so only clock gate that one.
  27748. + */
  27749. + ldr r6, [r3, #0x100]
  27750. + orr r6, r6, #0x800000
  27751. + str r6, [r3, #0x100]
  27752. +
  27753. + /*
  27754. + * Set PLL2 to bypass state. We should be here
  27755. + * only if MMDC is not sourced from PLL2.
  27756. + */
  27757. + ldr r6, [r3, #0x30]
  27758. + orr r6, r6, #0x10000
  27759. + str r6, [r3, #0x30]
  27760. +
  27761. + ldr r6, [r3, #0x30]
  27762. + orr r6, r6, #0x1000
  27763. + str r6, [r3, #0x30]
  27764. +
  27765. + /* Ensure pre_periph2_clk_mux is set to pll2 */
  27766. + ldr r6, [r2, #0x18]
  27767. + bic r6, r6, #0x600000
  27768. + str r6, [r2, #0x18]
  27769. +
  27770. + /* Set MMDC clock to be sourced from the bypassed PLL2. */
  27771. + ldr r6, [r2, #0x14]
  27772. + bic r6, r6, #0x4000000
  27773. + str r6, [r2, #0x14]
  27774. +
  27775. +periph2_clk_switch2:
  27776. + ldr r6, [r2, #0x48]
  27777. + cmp r6, #0
  27778. + bne periph2_clk_switch2
  27779. +
  27780. + /*
  27781. + * Now move MMDC back to periph2_clk2 source.
  27782. + * after selecting PLL2 as the option.
  27783. + * Select PLL2 as the source.
  27784. + */
  27785. + ldr r6, [r2, #0x18]
  27786. + orr r6, r6, #0x100000
  27787. + str r6, [r2, #0x18]
  27788. +
  27789. + /* set periph2_clk2_podf to divide by 1. */
  27790. + ldr r6, [r2, #0x14]
  27791. + bic r6, r6, #0x7
  27792. + str r6, [r2, #0x14]
  27793. +
  27794. + /* Now move periph2_clk to periph2_clk2 source */
  27795. + ldr r6, [r2, #0x14]
  27796. + orr r6, r6, #0x4000000
  27797. + str r6, [r2, #0x14]
  27798. +
  27799. +periph2_clk_switch3:
  27800. + ldr r6, [r2, #0x48]
  27801. + cmp r6, #0
  27802. + bne periph2_clk_switch3
  27803. +
  27804. + /* Now set the MMDC PODF back to 1.*/
  27805. + ldr r6, [r2, #0x14]
  27806. + bic r6, r6, #0x38
  27807. + str r6, [r2, #0x14]
  27808. +
  27809. +mmdc_podf0:
  27810. + ldr r6, [r2, #0x48]
  27811. + cmp r6, #0
  27812. + bne mmdc_podf0
  27813. +
  27814. + .endm
  27815. +
  27816. + .macro ddr_switch_400MHz
  27817. +
  27818. + /* Set MMDC divider first, in case PLL3 is at 480MHz. */
  27819. + ldr r6, [r3, #0x10]
  27820. + and r6, r6, #0x10000
  27821. + cmp r6, #0x10000
  27822. + beq pll3_in_bypass
  27823. +
  27824. + /* Set MMDC divder to divide by 2. */
  27825. + ldr r6, [r2, #0x14]
  27826. + bic r6, r6, #0x38
  27827. + orr r6, r6, #0x8
  27828. + str r6, [r2, #0x14]
  27829. +
  27830. +mmdc_podf:
  27831. + ldr r6, [r2, #0x48]
  27832. + cmp r6, #0
  27833. + bne mmdc_podf
  27834. +
  27835. +pll3_in_bypass:
  27836. + /*
  27837. + * Check if we are switching between
  27838. + * 400Mhz <-> 100MHz.If so, we should
  27839. + * try to source MMDC from PLL2_200M.
  27840. + */
  27841. + cmp r1, #0
  27842. + beq not_low_bus_freq
  27843. +
  27844. + /* Ensure that MMDC is sourced from PLL2 mux first. */
  27845. + ldr r6, [r2, #0x14]
  27846. + bic r6, r6, #0x4000000
  27847. + str r6, [r2, #0x14]
  27848. +
  27849. +periph2_clk_switch4:
  27850. + ldr r6, [r2, #0x48]
  27851. + cmp r6, #0
  27852. + bne periph2_clk_switch4
  27853. +
  27854. +not_low_bus_freq:
  27855. + /* Now ensure periph2_clk2_sel mux is set to PLL3 */
  27856. + ldr r6, [r2, #0x18]
  27857. + bic r6, r6, #0x100000
  27858. + str r6, [r2, #0x18]
  27859. +
  27860. + /* Now switch MMDC to PLL3. */
  27861. + ldr r6, [r2, #0x14]
  27862. + orr r6, r6, #0x4000000
  27863. + str r6, [r2, #0x14]
  27864. +
  27865. +periph2_clk_switch5:
  27866. + ldr r6, [r2, #0x48]
  27867. + cmp r6, #0
  27868. + bne periph2_clk_switch5
  27869. +
  27870. + /*
  27871. + * Check if PLL2 is already unlocked.
  27872. + * If so do nothing with PLL2.
  27873. + */
  27874. + cmp r1, #0
  27875. + beq pll2_already_on
  27876. +
  27877. + /* Now power up PLL2 and unbypass it. */
  27878. + ldr r6, [r3, #0x30]
  27879. + bic r6, r6, #0x1000
  27880. + str r6, [r3, #0x30]
  27881. +
  27882. + /* Make sure PLL2 has locked.*/
  27883. +wait_for_pll_lock:
  27884. + ldr r6, [r3, #0x30]
  27885. + and r6, r6, #0x80000000
  27886. + cmp r6, #0x80000000
  27887. + bne wait_for_pll_lock
  27888. +
  27889. + ldr r6, [r3, #0x30]
  27890. + bic r6, r6, #0x10000
  27891. + str r6, [r3, #0x30]
  27892. +
  27893. + /*
  27894. + * Need to enable the 528 PFDs after
  27895. + * powering up PLL2.
  27896. + * Only the PLL2_PFD2_400M should be ON
  27897. + * as it feeds the MMDC. Rest should have
  27898. + * been managed by clock code.
  27899. + */
  27900. + ldr r6, [r3, #0x100]
  27901. + bic r6, r6, #0x800000
  27902. + str r6, [r3, #0x100]
  27903. +
  27904. +pll2_already_on:
  27905. + /*
  27906. + * Now switch MMDC clk back to pll2_mux option.
  27907. + * Ensure pre_periph2_clk2 is set to pll2_pfd_400M.
  27908. + * If switching to audio DDR freq, set the
  27909. + * pre_periph2_clk2 to PLL2_PFD_200M
  27910. + */
  27911. + ldr r6, =400000000
  27912. + cmp r6, r0
  27913. + bne use_pll2_pfd_200M
  27914. +
  27915. + ldr r6, [r2, #0x18]
  27916. + bic r6, r6, #0x600000
  27917. + orr r6, r6, #0x200000
  27918. + str r6, [r2, #0x18]
  27919. + ldr r6, =400000000
  27920. + b cont2
  27921. +
  27922. +use_pll2_pfd_200M:
  27923. + ldr r6, [r2, #0x18]
  27924. + orr r6, r6, #0x600000
  27925. + str r6, [r2, #0x18]
  27926. + ldr r6, =200000000
  27927. +
  27928. +cont2:
  27929. + ldr r4, [r2, #0x14]
  27930. + bic r4, r4, #0x4000000
  27931. + str r4, [r2, #0x14]
  27932. +
  27933. +periph2_clk_switch6:
  27934. + ldr r4, [r2, #0x48]
  27935. + cmp r4, #0
  27936. + bne periph2_clk_switch6
  27937. +
  27938. +change_divider_only:
  27939. + /*
  27940. + * Calculate the MMDC divider
  27941. + * based on the requested freq.
  27942. + */
  27943. + ldr r4, =0
  27944. +Loop2:
  27945. + sub r6, r6, r0
  27946. + cmp r6, r0
  27947. + blt Div_Found
  27948. + add r4, r4, #1
  27949. + bgt Loop2
  27950. +
  27951. + /* Shift divider into correct offset. */
  27952. + lsl r4, r4, #3
  27953. +Div_Found:
  27954. + /* Set the MMDC PODF. */
  27955. + ldr r6, [r2, #0x14]
  27956. + bic r6, r6, #0x38
  27957. + orr r6, r6, r4
  27958. + str r6, [r2, #0x14]
  27959. +
  27960. +mmdc_podf1:
  27961. + ldr r6, [r2, #0x48]
  27962. + cmp r6, #0
  27963. + bne mmdc_podf1
  27964. +
  27965. + .endm
  27966. +
  27967. + .macro mmdc_clk_lower_100MHz
  27968. +
  27969. + /*
  27970. + * Prior to reducing the DDR frequency (at 528/400 MHz),
  27971. + * read the Measure unit count bits (MU_UNIT_DEL_NUM)
  27972. + */
  27973. + ldr r5, =0x8B8
  27974. + ldr r6, [r8, r5]
  27975. + /* Original MU unit count */
  27976. + mov r6, r6, LSR #16
  27977. + ldr r4, =0x3FF
  27978. + and r6, r6, r4
  27979. + /* Original MU unit count * 2 */
  27980. + mov r7, r6, LSL #1
  27981. + /*
  27982. + * Bypass the automatic measure unit when below 100 MHz
  27983. + * by setting the Measure unit bypass enable bit (MU_BYP_EN)
  27984. + */
  27985. + ldr r6, [r8, r5]
  27986. + orr r6, r6, #0x400
  27987. + str r6, [r8, r5]
  27988. + /*
  27989. + * Double the measure count value read in step 1 and program it in the
  27990. + * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit
  27991. + * Register for the reduced frequency operation below 100 MHz
  27992. + */
  27993. + ldr r6, [r8, r5]
  27994. + ldr r4, =0x3FF
  27995. + bic r6, r6, r4
  27996. + orr r6, r6, r7
  27997. + str r6, [r8, r5]
  27998. + /* Now perform a Force Measurement. */
  27999. + ldr r6, [r8, r5]
  28000. + orr r6, r6, #0x800
  28001. + str r6, [r8, r5]
  28002. + /* Wait for FRC_MSR to clear. */
  28003. +force_measure:
  28004. + ldr r6, [r8, r5]
  28005. + and r6, r6, #0x800
  28006. + cmp r6, #0x0
  28007. + bne force_measure
  28008. +
  28009. + .endm
  28010. +
  28011. + .macro mmdc_clk_above_100MHz
  28012. +
  28013. + /* Make sure that the PHY measurement unit is NOT in bypass mode */
  28014. + ldr r5, =0x8B8
  28015. + ldr r6, [r8, r5]
  28016. + bic r6, r6, #0x400
  28017. + str r6, [r8, r5]
  28018. + /* Now perform a Force Measurement. */
  28019. + ldr r6, [r8, r5]
  28020. + orr r6, r6, #0x800
  28021. + str r6, [r8, r5]
  28022. + /* Wait for FRC_MSR to clear. */
  28023. +force_measure1:
  28024. + ldr r6, [r8, r5]
  28025. + and r6, r6, #0x800
  28026. + cmp r6, #0x0
  28027. + bne force_measure1
  28028. + .endm
  28029. +
  28030. +/*
  28031. + * mx6_lpddr2_freq_change
  28032. + *
  28033. + * Make sure DDR is in self-refresh.
  28034. + * IRQs are already disabled.
  28035. + * r0 : DDR freq.
  28036. + * r1: low_bus_freq_mode flag
  28037. + * r2: Pointer to array containing addresses of registers.
  28038. + */
  28039. + .align 3
  28040. +ENTRY(mx6_lpddr2_freq_change)
  28041. +
  28042. + push {r4-r10}
  28043. +
  28044. + mov r4, r2
  28045. + ldr r3, [r4] @ANATOP_BASE_ADDR
  28046. + ldr r2, [r4, #0x4] @CCM_BASE_ADDR
  28047. + ldr r8, [r4, #0x8] @MMDC_P0_BASE_ADDR
  28048. + ldr r7, [r4, #0xC] @L2_BASE_ADDR
  28049. +
  28050. +lpddr2_freq_change:
  28051. + adr r9, lpddr2_freq_change
  28052. +
  28053. + /* Prime all TLB entries. */
  28054. + ldr r6, [r9]
  28055. + ldr r6, [r8]
  28056. + ldr r6, [r3]
  28057. + ldr r6, [r2]
  28058. +
  28059. + /* Drain all the L1 buffers. */
  28060. + dsb
  28061. +
  28062. +#ifdef CONFIG_CACHE_L2X0
  28063. + /*
  28064. + * Need to make sure the buffers in L2 are drained.
  28065. + * Performing a sync operation does this.
  28066. + */
  28067. + mov r6, #0x0
  28068. + str r6, [r7, #0x730]
  28069. +#endif
  28070. +
  28071. + /*
  28072. + * The second dsb might be needed to keep cache sync (device write)
  28073. + * ordering with the memory accesses before it.
  28074. + */
  28075. + dsb
  28076. + isb
  28077. +
  28078. + /* Disable Automatic power savings. */
  28079. + ldr r6, [r8, #0x404]
  28080. + orr r6, r6, #0x01
  28081. + str r6, [r8, #0x404]
  28082. +
  28083. + /* MMDC0_MDPDC disable power down timer */
  28084. + ldr r6, [r8, #0x4]
  28085. + bic r6, r6, #0xff00
  28086. + str r6, [r8, #0x4]
  28087. +
  28088. + /* Delay for a while */
  28089. + ldr r10, =10
  28090. +delay1:
  28091. + ldr r7, =0
  28092. +cont1:
  28093. + ldr r6, [r8, r7]
  28094. + add r7, r7, #4
  28095. + cmp r7, #16
  28096. + bne cont1
  28097. + sub r10, r10, #1
  28098. + cmp r10, #0
  28099. + bgt delay1
  28100. +
  28101. + /* Make the DDR explicitly enter self-refresh. */
  28102. + ldr r6, [r8, #0x404]
  28103. + orr r6, r6, #0x200000
  28104. + str r6, [r8, #0x404]
  28105. +
  28106. +poll_dvfs_set_1:
  28107. + ldr r6, [r8, #0x404]
  28108. + and r6, r6, #0x2000000
  28109. + cmp r6, #0x2000000
  28110. + bne poll_dvfs_set_1
  28111. +
  28112. + /* set SBS step-by-step mode */
  28113. + ldr r6, [r8, #0x410]
  28114. + orr r6, r6, #0x100
  28115. + str r6, [r8, #0x410]
  28116. +
  28117. + ldr r10, =100000000
  28118. + cmp r0, r10
  28119. + bgt set_ddr_mu_above_100
  28120. + mmdc_clk_lower_100MHz
  28121. +
  28122. +set_ddr_mu_above_100:
  28123. + ldr r10, =24000000
  28124. + cmp r0, r10
  28125. + beq set_to_24MHz
  28126. +
  28127. + ddr_switch_400MHz
  28128. +
  28129. + ldr r10,=100000000
  28130. + cmp r0, r10
  28131. + blt done
  28132. + mmdc_clk_above_100MHz
  28133. +
  28134. + b done
  28135. +
  28136. +set_to_24MHz:
  28137. + mx6sl_switch_to_24MHz
  28138. +
  28139. +done:
  28140. + /* clear DVFS - exit from self refresh mode */
  28141. + ldr r6, [r8, #0x404]
  28142. + bic r6, r6, #0x200000
  28143. + str r6, [r8, #0x404]
  28144. +
  28145. +poll_dvfs_clear_1:
  28146. + ldr r6, [r8, #0x404]
  28147. + and r6, r6, #0x2000000
  28148. + cmp r6, #0x2000000
  28149. + beq poll_dvfs_clear_1
  28150. +
  28151. + /* Enable Automatic power savings. */
  28152. + ldr r6, [r8, #0x404]
  28153. + bic r6, r6, #0x01
  28154. + str r6, [r8, #0x404]
  28155. +
  28156. + ldr r10, =24000000
  28157. + cmp r0, r10
  28158. + beq skip_power_down
  28159. +
  28160. + /* Enable MMDC power down timer. */
  28161. + ldr r6, [r8, #0x4]
  28162. + orr r6, r6, #0x5500
  28163. + str r6, [r8, #0x4]
  28164. +
  28165. +skip_power_down:
  28166. + /* clear SBS - unblock DDR accesses */
  28167. + ldr r6, [r8, #0x410]
  28168. + bic r6, r6, #0x100
  28169. + str r6, [r8, #0x410]
  28170. +
  28171. + pop {r4-r10}
  28172. +
  28173. + /* Restore registers */
  28174. + mov pc, lr
  28175. +
  28176. + .type mx6_lpddr2_do_iram, #object
  28177. +ENTRY(mx6_lpddr2_do_iram)
  28178. + .word mx6_lpddr2_freq_change
  28179. + .size mx6_lpddr2_freq_change, . - mx6_lpddr2_freq_change
  28180. diff -Nur linux-3.14.14/arch/arm/mach-imx/mach-imx6q.c linux-imx6-3.14/arch/arm/mach-imx/mach-imx6q.c
  28181. --- linux-3.14.14/arch/arm/mach-imx/mach-imx6q.c 2014-07-28 10:07:25.000000000 -0500
  28182. +++ linux-imx6-3.14/arch/arm/mach-imx/mach-imx6q.c 2014-12-08 00:31:51.228418001 -0600
  28183. @@ -1,5 +1,5 @@
  28184. /*
  28185. - * Copyright 2011-2013 Freescale Semiconductor, Inc.
  28186. + * Copyright 2011-2014 Freescale Semiconductor, Inc.
  28187. * Copyright 2011 Linaro Ltd.
  28188. *
  28189. * The code contained herein is licensed under the GNU General Public
  28190. @@ -15,6 +15,7 @@
  28191. #include <linux/cpu.h>
  28192. #include <linux/delay.h>
  28193. #include <linux/export.h>
  28194. +#include <linux/gpio.h>
  28195. #include <linux/init.h>
  28196. #include <linux/io.h>
  28197. #include <linux/irq.h>
  28198. @@ -22,15 +23,18 @@
  28199. #include <linux/of.h>
  28200. #include <linux/of_address.h>
  28201. #include <linux/of_irq.h>
  28202. +#include <linux/of_gpio.h>
  28203. #include <linux/of_platform.h>
  28204. #include <linux/pm_opp.h>
  28205. #include <linux/pci.h>
  28206. #include <linux/phy.h>
  28207. +#include <linux/pm_opp.h>
  28208. #include <linux/reboot.h>
  28209. #include <linux/regmap.h>
  28210. #include <linux/micrel_phy.h>
  28211. #include <linux/mfd/syscon.h>
  28212. #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  28213. +#include <linux/of_net.h>
  28214. #include <asm/mach/arch.h>
  28215. #include <asm/mach/map.h>
  28216. #include <asm/system_misc.h>
  28217. @@ -194,6 +198,101 @@
  28218. }
  28219. +static void __init imx6q_csi_mux_init(void)
  28220. +{
  28221. + /*
  28222. + * MX6Q SabreSD board:
  28223. + * IPU1 CSI0 connects to parallel interface.
  28224. + * Set GPR1 bit 19 to 0x1.
  28225. + *
  28226. + * MX6DL SabreSD board:
  28227. + * IPU1 CSI0 connects to parallel interface.
  28228. + * Set GPR13 bit 0-2 to 0x4.
  28229. + * IPU1 CSI1 connects to MIPI CSI2 virtual channel 1.
  28230. + * Set GPR13 bit 3-5 to 0x1.
  28231. + */
  28232. + struct regmap *gpr;
  28233. +
  28234. + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  28235. + if (!IS_ERR(gpr)) {
  28236. + if (of_machine_is_compatible("fsl,imx6q-sabresd") ||
  28237. + of_machine_is_compatible("fsl,imx6q-sabreauto"))
  28238. + regmap_update_bits(gpr, IOMUXC_GPR1, 1 << 19, 1 << 19);
  28239. + else if (of_machine_is_compatible("fsl,imx6dl-sabresd") ||
  28240. + of_machine_is_compatible("fsl,imx6dl-sabreauto"))
  28241. + regmap_update_bits(gpr, IOMUXC_GPR13, 0x3F, 0x0C);
  28242. + } else {
  28243. + pr_err("%s(): failed to find fsl,imx6q-iomux-gpr regmap\n",
  28244. + __func__);
  28245. + }
  28246. +}
  28247. +
  28248. +#define OCOTP_MACn(n) (0x00000620 + (n) * 0x10)
  28249. +void __init imx6_enet_mac_init(const char *compatible)
  28250. +{
  28251. + struct device_node *ocotp_np, *enet_np;
  28252. + void __iomem *base;
  28253. + struct property *newmac;
  28254. + u32 macaddr_low, macaddr_high;
  28255. + u8 *macaddr;
  28256. +
  28257. + enet_np = of_find_compatible_node(NULL, NULL, compatible);
  28258. + if (!enet_np)
  28259. + return;
  28260. +
  28261. + if (of_get_mac_address(enet_np))
  28262. + goto put_enet_node;
  28263. +
  28264. + ocotp_np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
  28265. + if (!ocotp_np) {
  28266. + pr_warn("failed to find ocotp node\n");
  28267. + goto put_enet_node;
  28268. + }
  28269. +
  28270. + base = of_iomap(ocotp_np, 0);
  28271. + if (!base) {
  28272. + pr_warn("failed to map ocotp\n");
  28273. + goto put_ocotp_node;
  28274. + }
  28275. +
  28276. + macaddr_high = readl_relaxed(base + OCOTP_MACn(0));
  28277. + macaddr_low = readl_relaxed(base + OCOTP_MACn(1));
  28278. +
  28279. + newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL);
  28280. + if (!newmac)
  28281. + goto put_ocotp_node;
  28282. +
  28283. + newmac->value = newmac + 1;
  28284. + newmac->length = 6;
  28285. + newmac->name = kstrdup("local-mac-address", GFP_KERNEL);
  28286. + if (!newmac->name) {
  28287. + kfree(newmac);
  28288. + goto put_ocotp_node;
  28289. + }
  28290. +
  28291. + macaddr = newmac->value;
  28292. + macaddr[5] = macaddr_high & 0xff;
  28293. + macaddr[4] = (macaddr_high >> 8) & 0xff;
  28294. + macaddr[3] = (macaddr_high >> 16) & 0xff;
  28295. + macaddr[2] = (macaddr_high >> 24) & 0xff;
  28296. + macaddr[1] = macaddr_low & 0xff;
  28297. + macaddr[0] = (macaddr_low >> 8) & 0xff;
  28298. +
  28299. + of_update_property(enet_np, newmac);
  28300. +
  28301. +put_ocotp_node:
  28302. + of_node_put(ocotp_np);
  28303. +put_enet_node:
  28304. + of_node_put(enet_np);
  28305. +}
  28306. +
  28307. +static inline void imx6q_enet_init(void)
  28308. +{
  28309. + imx6_enet_mac_init("fsl,imx6q-fec");
  28310. + imx6q_enet_phy_init();
  28311. + imx6q_1588_init();
  28312. +}
  28313. +
  28314. static void __init imx6q_init_machine(void)
  28315. {
  28316. struct device *parent;
  28317. @@ -207,20 +306,22 @@
  28318. if (parent == NULL)
  28319. pr_warn("failed to initialize soc device\n");
  28320. - imx6q_enet_phy_init();
  28321. -
  28322. of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
  28323. + imx6q_enet_init();
  28324. imx_anatop_init();
  28325. - imx6q_pm_init();
  28326. - imx6q_1588_init();
  28327. + cpu_is_imx6q() ? imx6q_pm_init() : imx6dl_pm_init();
  28328. + imx6q_csi_mux_init();
  28329. }
  28330. #define OCOTP_CFG3 0x440
  28331. #define OCOTP_CFG3_SPEED_SHIFT 16
  28332. #define OCOTP_CFG3_SPEED_1P2GHZ 0x3
  28333. +#define OCOTP_CFG3_SPEED_1GHZ 0x2
  28334. +#define OCOTP_CFG3_SPEED_850MHZ 0x1
  28335. +#define OCOTP_CFG3_SPEED_800MHZ 0x0
  28336. -static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev)
  28337. +static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
  28338. {
  28339. struct device_node *np;
  28340. void __iomem *base;
  28341. @@ -238,11 +339,31 @@
  28342. goto put_node;
  28343. }
  28344. + /*
  28345. + * SPEED_GRADING[1:0] defines the max speed of ARM:
  28346. + * 2b'11: 1200000000Hz; -- i.MX6Q only.
  28347. + * 2b'10: 1000000000Hz;
  28348. + * 2b'01: 850000000Hz; -- i.MX6Q Only, exclusive with 1GHz.
  28349. + * 2b'00: 800000000Hz;
  28350. + * We need to set the max speed of ARM according to fuse map.
  28351. + */
  28352. +
  28353. val = readl_relaxed(base + OCOTP_CFG3);
  28354. val >>= OCOTP_CFG3_SPEED_SHIFT;
  28355. - if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ)
  28356. - if (dev_pm_opp_disable(cpu_dev, 1200000000))
  28357. - pr_warn("failed to disable 1.2 GHz OPP\n");
  28358. + if (cpu_is_imx6q()) {
  28359. + if ((val & 0x3) < OCOTP_CFG3_SPEED_1P2GHZ)
  28360. + if (dev_pm_opp_disable(cpu_dev, 1200000000))
  28361. + pr_warn("failed to disable 1.2 GHz OPP\n");
  28362. + }
  28363. + if ((val & 0x3) < OCOTP_CFG3_SPEED_1GHZ)
  28364. + if (dev_pm_opp_disable(cpu_dev, 996000000))
  28365. + pr_warn("failed to disable 1 GHz OPP\n");
  28366. + if (cpu_is_imx6q()) {
  28367. + if ((val & 0x3) < OCOTP_CFG3_SPEED_850MHZ ||
  28368. + (val & 0x3) == OCOTP_CFG3_SPEED_1GHZ)
  28369. + if (dev_pm_opp_disable(cpu_dev, 852000000))
  28370. + pr_warn("failed to disable 850 MHz OPP\n");
  28371. + }
  28372. put_node:
  28373. of_node_put(np);
  28374. @@ -268,29 +389,70 @@
  28375. goto put_node;
  28376. }
  28377. - imx6q_opp_check_1p2ghz(cpu_dev);
  28378. + imx6q_opp_check_speed_grading(cpu_dev);
  28379. put_node:
  28380. of_node_put(np);
  28381. }
  28382. +#define ESAI_AUDIO_MCLK 24576000
  28383. +
  28384. +static void __init imx6q_audio_lvds2_init(void)
  28385. +{
  28386. + struct clk *pll4_sel, *lvds2_in, *pll4_audio_div, *esai;
  28387. +
  28388. + pll4_audio_div = clk_get_sys(NULL, "pll4_audio_div");
  28389. + pll4_sel = clk_get_sys(NULL, "pll4_sel");
  28390. + lvds2_in = clk_get_sys(NULL, "lvds2_in");
  28391. + esai = clk_get_sys(NULL, "esai");
  28392. + if (IS_ERR(pll4_audio_div) || IS_ERR(pll4_sel) ||
  28393. + IS_ERR(lvds2_in) || IS_ERR(esai))
  28394. + return;
  28395. +
  28396. + if (clk_get_rate(lvds2_in) != ESAI_AUDIO_MCLK)
  28397. + return;
  28398. +
  28399. + clk_set_parent(pll4_sel, lvds2_in);
  28400. + clk_set_rate(pll4_audio_div, 786432000);
  28401. + clk_set_rate(esai, ESAI_AUDIO_MCLK);
  28402. +}
  28403. +
  28404. static struct platform_device imx6q_cpufreq_pdev = {
  28405. - .name = "imx6q-cpufreq",
  28406. + .name = "imx6-cpufreq",
  28407. };
  28408. static void __init imx6q_init_late(void)
  28409. {
  28410. + struct regmap *gpr;
  28411. +
  28412. + /*
  28413. + * Need to force IOMUXC irq pending to meet CCM low power mode
  28414. + * restriction, this is recommended by hardware team.
  28415. + */
  28416. + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  28417. + if (!IS_ERR(gpr))
  28418. + regmap_update_bits(gpr, IOMUXC_GPR1,
  28419. + IMX6Q_GPR1_GINT_MASK,
  28420. + IMX6Q_GPR1_GINT_ASSERT);
  28421. +
  28422. /*
  28423. * WAIT mode is broken on TO 1.0 and 1.1, so there is no point
  28424. * to run cpuidle on them.
  28425. */
  28426. - if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
  28427. + if ((cpu_is_imx6q() && imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
  28428. + || (cpu_is_imx6dl() && imx_get_soc_revision() >
  28429. + IMX_CHIP_REVISION_1_0))
  28430. imx6q_cpuidle_init();
  28431. - if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
  28432. + if (IS_ENABLED(CONFIG_ARM_IMX6_CPUFREQ)) {
  28433. imx6q_opp_init();
  28434. platform_device_register(&imx6q_cpufreq_pdev);
  28435. }
  28436. +
  28437. + if (of_machine_is_compatible("fsl,imx6q-sabreauto")
  28438. + || of_machine_is_compatible("fsl,imx6dl-sabreauto")) {
  28439. + imx6q_audio_lvds2_init();
  28440. + }
  28441. }
  28442. static void __init imx6q_map_io(void)
  28443. @@ -315,6 +477,12 @@
  28444. };
  28445. DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
  28446. + /*
  28447. + * i.MX6Q/DL maps system memory at 0x10000000 (offset 256MiB), and
  28448. + * GPU has a limit on physical address that it accesses, which must
  28449. + * be below 2GiB.
  28450. + */
  28451. + .dma_zone_size = (SZ_2G - SZ_256M),
  28452. .smp = smp_ops(imx_smp_ops),
  28453. .map_io = imx6q_map_io,
  28454. .init_irq = imx6q_init_irq,
  28455. diff -Nur linux-3.14.14/arch/arm/mach-imx/mach-imx6sl.c linux-imx6-3.14/arch/arm/mach-imx/mach-imx6sl.c
  28456. --- linux-3.14.14/arch/arm/mach-imx/mach-imx6sl.c 2014-07-28 10:07:25.000000000 -0500
  28457. +++ linux-imx6-3.14/arch/arm/mach-imx/mach-imx6sl.c 2014-12-08 00:31:51.228418001 -0600
  28458. @@ -17,8 +17,9 @@
  28459. #include <asm/mach/map.h>
  28460. #include "common.h"
  28461. +#include "cpuidle.h"
  28462. -static void __init imx6sl_fec_init(void)
  28463. +static void __init imx6sl_fec_clk_init(void)
  28464. {
  28465. struct regmap *gpr;
  28466. @@ -34,8 +35,17 @@
  28467. }
  28468. }
  28469. +static inline void imx6sl_fec_init(void)
  28470. +{
  28471. + imx6sl_fec_clk_init();
  28472. + imx6_enet_mac_init("fsl,imx6sl-fec");
  28473. +}
  28474. +
  28475. static void __init imx6sl_init_late(void)
  28476. {
  28477. + /* Init CPUIDLE */
  28478. + imx6sl_cpuidle_init();
  28479. +
  28480. /* imx6sl reuses imx6q cpufreq driver */
  28481. if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
  28482. platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
  28483. @@ -55,8 +65,7 @@
  28484. imx6sl_fec_init();
  28485. imx_anatop_init();
  28486. - /* Reuse imx6q pm code */
  28487. - imx6q_pm_init();
  28488. + imx6sl_pm_init();
  28489. }
  28490. static void __init imx6sl_init_irq(void)
  28491. diff -Nur linux-3.14.14/arch/arm/mach-imx/mach-vf610.c linux-imx6-3.14/arch/arm/mach-imx/mach-vf610.c
  28492. --- linux-3.14.14/arch/arm/mach-imx/mach-vf610.c 2014-07-28 10:07:25.000000000 -0500
  28493. +++ linux-imx6-3.14/arch/arm/mach-imx/mach-vf610.c 2014-12-08 00:31:51.228418001 -0600
  28494. @@ -22,7 +22,7 @@
  28495. static void __init vf610_init_irq(void)
  28496. {
  28497. - l2x0_of_init(0, ~0UL);
  28498. + l2x0_of_init(0, ~0);
  28499. irqchip_init();
  28500. }
  28501. diff -Nur linux-3.14.14/arch/arm/mach-imx/Makefile linux-imx6-3.14/arch/arm/mach-imx/Makefile
  28502. --- linux-3.14.14/arch/arm/mach-imx/Makefile 2014-07-28 10:07:25.000000000 -0500
  28503. +++ linux-imx6-3.14/arch/arm/mach-imx/Makefile 2014-12-08 00:31:51.220418001 -0600
  28504. @@ -30,6 +30,7 @@
  28505. ifeq ($(CONFIG_CPU_IDLE),y)
  28506. obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
  28507. obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
  28508. +obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
  28509. endif
  28510. ifdef CONFIG_SND_IMX_SOC
  28511. @@ -101,9 +102,18 @@
  28512. obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
  28513. obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
  28514. -obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
  28515. -# i.MX6SL reuses i.MX6Q code
  28516. -obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o
  28517. +AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
  28518. +obj-$(CONFIG_PM) += suspend-imx6.o pm-imx6.o headsmp.o
  28519. +
  28520. +obj-y += busfreq-imx6.o
  28521. +ifeq ($(CONFIG_ARM_IMX6_CPUFREQ),y)
  28522. +obj-$(CONFIG_SOC_IMX6Q) += ddr3_freq_imx6.o busfreq_ddr3.o
  28523. +obj-$(CONFIG_SOC_IMX6SL) += lpddr2_freq_imx6.o busfreq_lpddr2.o
  28524. +endif
  28525. +ifeq ($(CONFIG_CPU_IDLE), y)
  28526. +obj-$(CONFIG_SOC_IMX6SL) += imx6sl_wfi.o
  28527. +endif
  28528. +
  28529. # i.MX5 based machines
  28530. obj-$(CONFIG_MACH_MX51_BABBAGE) += mach-mx51_babbage.o
  28531. diff -Nur linux-3.14.14/arch/arm/mach-imx/mx6.h linux-imx6-3.14/arch/arm/mach-imx/mx6.h
  28532. --- linux-3.14.14/arch/arm/mach-imx/mx6.h 1969-12-31 18:00:00.000000000 -0600
  28533. +++ linux-imx6-3.14/arch/arm/mach-imx/mx6.h 2014-12-08 00:31:51.232418001 -0600
  28534. @@ -0,0 +1,35 @@
  28535. +/*
  28536. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  28537. + */
  28538. +
  28539. +/*
  28540. + * This program is free software; you can redistribute it and/or modify
  28541. + * it under the terms of the GNU General Public License version 2 as
  28542. + * published by the Free Software Foundation.
  28543. + */
  28544. +
  28545. +#ifndef __ASM_ARCH_MXC_IOMAP_H__
  28546. +#define __ASM_ARCH_MXC_IOMAP_H__
  28547. +
  28548. +#define MX6Q_IO_P2V(x) IMX_IO_P2V(x)
  28549. +#define MX6Q_IO_ADDRESS(x) IOMEM(MX6Q_IO_P2V(x))
  28550. +
  28551. +#define MX6Q_L2_BASE_ADDR 0x00a02000
  28552. +#define MX6Q_L2_SIZE 0x1000
  28553. +#define MX6Q_IOMUXC_BASE_ADDR 0x020e0000
  28554. +#define MX6Q_IOMUXC_SIZE 0x4000
  28555. +#define MX6Q_SRC_BASE_ADDR 0x020d8000
  28556. +#define MX6Q_SRC_SIZE 0x4000
  28557. +#define MX6Q_CCM_BASE_ADDR 0x020c4000
  28558. +#define MX6Q_CCM_SIZE 0x4000
  28559. +#define MX6Q_ANATOP_BASE_ADDR 0x020c8000
  28560. +#define MX6Q_ANATOP_SIZE 0x1000
  28561. +#define MX6Q_GPC_BASE_ADDR 0x020dc000
  28562. +#define MX6Q_GPC_SIZE 0x4000
  28563. +#define MX6Q_MMDC_P0_BASE_ADDR 0x021b0000
  28564. +#define MX6Q_MMDC_P0_SIZE 0x4000
  28565. +#define MX6Q_MMDC_P1_BASE_ADDR 0x021b4000
  28566. +#define MX6Q_MMDC_P1_SIZE 0x4000
  28567. +
  28568. +#define MX6_SUSPEND_IRAM_SIZE 0x1000
  28569. +#endif
  28570. diff -Nur linux-3.14.14/arch/arm/mach-imx/mxc.h linux-imx6-3.14/arch/arm/mach-imx/mxc.h
  28571. --- linux-3.14.14/arch/arm/mach-imx/mxc.h 2014-07-28 10:07:25.000000000 -0500
  28572. +++ linux-imx6-3.14/arch/arm/mach-imx/mxc.h 2014-12-08 00:31:51.232418001 -0600
  28573. @@ -42,6 +42,8 @@
  28574. #define IMX_CHIP_REVISION_1_1 0x11
  28575. #define IMX_CHIP_REVISION_1_2 0x12
  28576. #define IMX_CHIP_REVISION_1_3 0x13
  28577. +#define IMX_CHIP_REVISION_1_4 0x14
  28578. +#define IMX_CHIP_REVISION_1_5 0x15
  28579. #define IMX_CHIP_REVISION_2_0 0x20
  28580. #define IMX_CHIP_REVISION_2_1 0x21
  28581. #define IMX_CHIP_REVISION_2_2 0x22
  28582. @@ -177,6 +179,7 @@
  28583. extern struct cpu_op *(*get_cpu_op)(int *op);
  28584. #endif
  28585. +#define cpu_is_imx6() (cpu_is_imx6q() || cpu_is_imx6dl() || cpu_is_imx6sl())
  28586. #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35())
  28587. #define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27())
  28588. diff -Nur linux-3.14.14/arch/arm/mach-imx/pm-imx6.c linux-imx6-3.14/arch/arm/mach-imx/pm-imx6.c
  28589. --- linux-3.14.14/arch/arm/mach-imx/pm-imx6.c 1969-12-31 18:00:00.000000000 -0600
  28590. +++ linux-imx6-3.14/arch/arm/mach-imx/pm-imx6.c 2014-12-08 00:31:51.232418001 -0600
  28591. @@ -0,0 +1,580 @@
  28592. +/*
  28593. + * Copyright 2011-2014 Freescale Semiconductor, Inc.
  28594. + * Copyright 2011 Linaro Ltd.
  28595. + *
  28596. + * The code contained herein is licensed under the GNU General Public
  28597. + * License. You may obtain a copy of the GNU General Public License
  28598. + * Version 2 or later at the following locations:
  28599. + *
  28600. + * http://www.opensource.org/licenses/gpl-license.html
  28601. + * http://www.gnu.org/copyleft/gpl.html
  28602. + */
  28603. +
  28604. +#include <linux/delay.h>
  28605. +#include <linux/init.h>
  28606. +#include <linux/io.h>
  28607. +#include <linux/irq.h>
  28608. +#include <linux/genalloc.h>
  28609. +#include <linux/mfd/syscon.h>
  28610. +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  28611. +#include <linux/of.h>
  28612. +#include <linux/of_address.h>
  28613. +#include <linux/of_platform.h>
  28614. +#include <linux/regmap.h>
  28615. +#include <linux/suspend.h>
  28616. +#include <linux/regmap.h>
  28617. +#include <linux/mfd/syscon.h>
  28618. +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  28619. +#include <asm/cacheflush.h>
  28620. +#include <asm/fncpy.h>
  28621. +#include <asm/proc-fns.h>
  28622. +#include <asm/suspend.h>
  28623. +#include <asm/tlb.h>
  28624. +
  28625. +#include "common.h"
  28626. +#include "hardware.h"
  28627. +
  28628. +#define CCR 0x0
  28629. +#define BM_CCR_WB_COUNT (0x7 << 16)
  28630. +#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
  28631. +#define BM_CCR_RBC_EN (0x1 << 27)
  28632. +
  28633. +#define CLPCR 0x54
  28634. +#define BP_CLPCR_LPM 0
  28635. +#define BM_CLPCR_LPM (0x3 << 0)
  28636. +#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
  28637. +#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
  28638. +#define BM_CLPCR_SBYOS (0x1 << 6)
  28639. +#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
  28640. +#define BM_CLPCR_VSTBY (0x1 << 8)
  28641. +#define BP_CLPCR_STBY_COUNT 9
  28642. +#define BM_CLPCR_STBY_COUNT (0x3 << 9)
  28643. +#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
  28644. +#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
  28645. +#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
  28646. +#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
  28647. +#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
  28648. +#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
  28649. +#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
  28650. +#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
  28651. +#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
  28652. +#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
  28653. +#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
  28654. +
  28655. +#define CGPR 0x64
  28656. +#define BM_CGPR_INT_MEM_CLK_LPM (0x1 << 17)
  28657. +
  28658. +#define MX6Q_SUSPEND_OCRAM_SIZE 0x1000
  28659. +#define MX6_MAX_MMDC_IO_NUM 33
  28660. +
  28661. +static void __iomem *ccm_base;
  28662. +static void __iomem *suspend_ocram_base;
  28663. +static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
  28664. +
  28665. +/*
  28666. + * suspend ocram space layout:
  28667. + * ======================== high address ======================
  28668. + * .
  28669. + * .
  28670. + * .
  28671. + * ^
  28672. + * ^
  28673. + * ^
  28674. + * imx6_suspend code
  28675. + * PM_INFO structure(imx6_cpu_pm_info)
  28676. + * ======================== low address =======================
  28677. + */
  28678. +
  28679. +struct imx6_pm_base {
  28680. + phys_addr_t pbase;
  28681. + void __iomem *vbase;
  28682. +};
  28683. +
  28684. +struct imx6_pm_socdata {
  28685. + u32 cpu_type;
  28686. + const char *mmdc_compat;
  28687. + const char *src_compat;
  28688. + const char *iomuxc_compat;
  28689. + const char *gpc_compat;
  28690. + const u32 mmdc_io_num;
  28691. + const u32 *mmdc_io_offset;
  28692. +};
  28693. +
  28694. +static const u32 imx6q_mmdc_io_offset[] __initconst = {
  28695. + 0x5ac, 0x5b4, 0x528, 0x520, /* DQM0 ~ DQM3 */
  28696. + 0x514, 0x510, 0x5bc, 0x5c4, /* DQM4 ~ DQM7 */
  28697. + 0x56c, 0x578, 0x588, 0x594, /* CAS, RAS, SDCLK_0, SDCLK_1 */
  28698. + 0x5a8, 0x5b0, 0x524, 0x51c, /* SDQS0 ~ SDQS3 */
  28699. + 0x518, 0x50c, 0x5b8, 0x5c0, /* SDQS4 ~ SDQS7 */
  28700. + 0x784, 0x788, 0x794, 0x79c, /* GPR_B0DS ~ GPR_B3DS */
  28701. + 0x7a0, 0x7a4, 0x7a8, 0x748, /* GPR_B4DS ~ GPR_B7DS */
  28702. + 0x59c, 0x5a0, 0x750, 0x774, /* SODT0, SODT1, MODE_CTL, MODE */
  28703. + 0x74c, /* GPR_ADDS */
  28704. +};
  28705. +
  28706. +static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
  28707. + .cpu_type = MXC_CPU_IMX6Q,
  28708. + .mmdc_compat = "fsl,imx6q-mmdc",
  28709. + .src_compat = "fsl,imx6q-src",
  28710. + .iomuxc_compat = "fsl,imx6q-iomuxc",
  28711. + .gpc_compat = "fsl,imx6q-gpc",
  28712. + .mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset),
  28713. + .mmdc_io_offset = imx6q_mmdc_io_offset,
  28714. +};
  28715. +
  28716. +/*
  28717. + * This structure is for passing necessary data for low level ocram
  28718. + * suspend code(arch/arm/mach-imx/suspend-imx6.S), if this struct
  28719. + * definition is changed, the offset definition in
  28720. + * arch/arm/mach-imx/suspend-imx6.S must be also changed accordingly,
  28721. + * otherwise, the suspend to ocram function will be broken!
  28722. + */
  28723. +struct imx6_cpu_pm_info {
  28724. + phys_addr_t pbase; /* The physical address of pm_info. */
  28725. + phys_addr_t resume_addr; /* The physical resume address for asm code */
  28726. + u32 cpu_type;
  28727. + u32 pm_info_size; /* Size of pm_info. */
  28728. + struct imx6_pm_base mmdc_base;
  28729. + struct imx6_pm_base src_base;
  28730. + struct imx6_pm_base iomuxc_base;
  28731. + struct imx6_pm_base ccm_base;
  28732. + struct imx6_pm_base gpc_base;
  28733. + struct imx6_pm_base l2_base;
  28734. + u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
  28735. + u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2]; /* To save offset and value */
  28736. +} __aligned(8);
  28737. +
  28738. +void imx6q_set_cache_lpm_in_wait(bool enable)
  28739. +{
  28740. + if ((cpu_is_imx6q() && imx_get_soc_revision() >
  28741. + IMX_CHIP_REVISION_1_1) ||
  28742. + (cpu_is_imx6dl() && imx_get_soc_revision() >
  28743. + IMX_CHIP_REVISION_1_0)) {
  28744. + u32 val;
  28745. +
  28746. + val = readl_relaxed(ccm_base + CGPR);
  28747. + if (enable)
  28748. + val |= BM_CGPR_INT_MEM_CLK_LPM;
  28749. + else
  28750. + val &= ~BM_CGPR_INT_MEM_CLK_LPM;
  28751. + writel_relaxed(val, ccm_base + CGPR);
  28752. + }
  28753. +}
  28754. +
  28755. +static void imx6q_enable_rbc(bool enable)
  28756. +{
  28757. + u32 val;
  28758. +
  28759. + /*
  28760. + * need to mask all interrupts in GPC before
  28761. + * operating RBC configurations
  28762. + */
  28763. + imx_gpc_mask_all();
  28764. +
  28765. + /* configure RBC enable bit */
  28766. + val = readl_relaxed(ccm_base + CCR);
  28767. + val &= ~BM_CCR_RBC_EN;
  28768. + val |= enable ? BM_CCR_RBC_EN : 0;
  28769. + writel_relaxed(val, ccm_base + CCR);
  28770. +
  28771. + /* configure RBC count */
  28772. + val = readl_relaxed(ccm_base + CCR);
  28773. + val &= ~BM_CCR_RBC_BYPASS_COUNT;
  28774. + val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
  28775. + writel(val, ccm_base + CCR);
  28776. +
  28777. + /*
  28778. + * need to delay at least 2 cycles of CKIL(32K)
  28779. + * due to hardware design requirement, which is
  28780. + * ~61us, here we use 65us for safe
  28781. + */
  28782. + udelay(65);
  28783. +
  28784. + /* restore GPC interrupt mask settings */
  28785. + imx_gpc_restore_all();
  28786. +}
  28787. +
  28788. +static void imx6q_enable_wb(bool enable)
  28789. +{
  28790. + u32 val;
  28791. +
  28792. + /* configure well bias enable bit */
  28793. + val = readl_relaxed(ccm_base + CLPCR);
  28794. + val &= ~BM_CLPCR_WB_PER_AT_LPM;
  28795. + val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
  28796. + writel_relaxed(val, ccm_base + CLPCR);
  28797. +
  28798. + /* configure well bias count */
  28799. + val = readl_relaxed(ccm_base + CCR);
  28800. + val &= ~BM_CCR_WB_COUNT;
  28801. + val |= enable ? BM_CCR_WB_COUNT : 0;
  28802. + writel_relaxed(val, ccm_base + CCR);
  28803. +}
  28804. +
  28805. +int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
  28806. +{
  28807. + struct irq_desc *iomuxc_irq_desc;
  28808. + u32 val = readl_relaxed(ccm_base + CLPCR);
  28809. +
  28810. + val &= ~BM_CLPCR_LPM;
  28811. + switch (mode) {
  28812. + case WAIT_CLOCKED:
  28813. + break;
  28814. + case WAIT_UNCLOCKED:
  28815. + val |= 0x1 << BP_CLPCR_LPM;
  28816. + val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
  28817. + val &= ~BM_CLPCR_VSTBY;
  28818. + val &= ~BM_CLPCR_SBYOS;
  28819. + if (cpu_is_imx6sl())
  28820. + val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
  28821. + else
  28822. + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  28823. + break;
  28824. + case STOP_POWER_ON:
  28825. + val |= 0x2 << BP_CLPCR_LPM;
  28826. + val &= ~BM_CLPCR_VSTBY;
  28827. + val &= ~BM_CLPCR_SBYOS;
  28828. + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  28829. + break;
  28830. + case WAIT_UNCLOCKED_POWER_OFF:
  28831. + val |= 0x1 << BP_CLPCR_LPM;
  28832. + val &= ~BM_CLPCR_VSTBY;
  28833. + val &= ~BM_CLPCR_SBYOS;
  28834. + break;
  28835. + case STOP_POWER_OFF:
  28836. + val |= 0x2 << BP_CLPCR_LPM;
  28837. + val |= 0x3 << BP_CLPCR_STBY_COUNT;
  28838. + val |= BM_CLPCR_VSTBY;
  28839. + val |= BM_CLPCR_SBYOS;
  28840. + if (cpu_is_imx6sl()) {
  28841. + val |= BM_CLPCR_BYPASS_PMIC_READY;
  28842. + val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
  28843. + } else {
  28844. + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  28845. + }
  28846. + break;
  28847. + default:
  28848. + return -EINVAL;
  28849. + }
  28850. +
  28851. + /*
  28852. + * ERR007265: CCM: When improper low-power sequence is used,
  28853. + * the SoC enters low power mode before the ARM core executes WFI.
  28854. + *
  28855. + * Software workaround:
  28856. + * 1) Software should trigger IRQ #32 (IOMUX) to be always pending
  28857. + * by setting IOMUX_GPR1_GINT.
  28858. + * 2) Software should then unmask IRQ #32 in GPC before setting CCM
  28859. + * Low-Power mode.
  28860. + * 3) Software should mask IRQ #32 right after CCM Low-Power mode
  28861. + * is set (set bits 0-1 of CCM_CLPCR).
  28862. + */
  28863. + iomuxc_irq_desc = irq_to_desc(32);
  28864. + imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data);
  28865. + writel_relaxed(val, ccm_base + CLPCR);
  28866. + imx_gpc_irq_mask(&iomuxc_irq_desc->irq_data);
  28867. +
  28868. + return 0;
  28869. +}
  28870. +
  28871. +static int imx6q_suspend_finish(unsigned long val)
  28872. +{
  28873. + if (!imx6_suspend_in_ocram_fn) {
  28874. + cpu_do_idle();
  28875. + } else {
  28876. + /*
  28877. + * call low level suspend function in ocram,
  28878. + * as we need to float DDR IO.
  28879. + */
  28880. + local_flush_tlb_all();
  28881. + imx6_suspend_in_ocram_fn(suspend_ocram_base);
  28882. + }
  28883. +
  28884. + return 0;
  28885. +}
  28886. +
  28887. +static int imx6q_pm_enter(suspend_state_t state)
  28888. +{
  28889. + struct regmap *g;
  28890. +
  28891. + /*
  28892. + * L2 can exit by 'reset' or Inband beacon (from remote EP)
  28893. + * toggling phy_powerdown has same effect as 'inband beacon'
  28894. + * So, toggle bit18 of GPR1, used as a workaround of errata
  28895. + * "PCIe PCIe does not support L2 Power Down"
  28896. + */
  28897. + if (IS_ENABLED(CONFIG_PCI_IMX6)) {
  28898. + g = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  28899. + if (IS_ERR(g)) {
  28900. + pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n");
  28901. + return PTR_ERR(g);
  28902. + }
  28903. + regmap_update_bits(g, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD,
  28904. + IMX6Q_GPR1_PCIE_TEST_PD);
  28905. + }
  28906. +
  28907. + switch (state) {
  28908. + case PM_SUSPEND_STANDBY:
  28909. + imx6q_set_lpm(STOP_POWER_ON);
  28910. + imx6q_set_cache_lpm_in_wait(true);
  28911. + imx_gpc_pre_suspend(false);
  28912. + if (cpu_is_imx6sl())
  28913. + imx6sl_set_wait_clk(true);
  28914. + /* Zzz ... */
  28915. + cpu_do_idle();
  28916. + if (cpu_is_imx6sl())
  28917. + imx6sl_set_wait_clk(false);
  28918. + imx_gpc_post_resume();
  28919. + imx6q_set_lpm(WAIT_CLOCKED);
  28920. + break;
  28921. + case PM_SUSPEND_MEM:
  28922. + imx6q_set_cache_lpm_in_wait(false);
  28923. + imx6q_set_lpm(STOP_POWER_OFF);
  28924. + imx6q_enable_wb(true);
  28925. + /*
  28926. + * For suspend into ocram, asm code already take care of
  28927. + * RBC setting, so we do NOT need to do that here.
  28928. + */
  28929. + if (!imx6_suspend_in_ocram_fn)
  28930. + imx6q_enable_rbc(true);
  28931. + imx_gpc_pre_suspend(true);
  28932. + imx_anatop_pre_suspend();
  28933. + imx_set_cpu_jump(0, v7_cpu_resume);
  28934. + /* Zzz ... */
  28935. + cpu_suspend(0, imx6q_suspend_finish);
  28936. + if (cpu_is_imx6q() || cpu_is_imx6dl())
  28937. + imx_smp_prepare();
  28938. + imx_anatop_post_resume();
  28939. + imx_gpc_post_resume();
  28940. + imx6q_enable_wb(false);
  28941. + imx6q_set_lpm(WAIT_CLOCKED);
  28942. + break;
  28943. + default:
  28944. + return -EINVAL;
  28945. + }
  28946. +
  28947. + /*
  28948. + * L2 can exit by 'reset' or Inband beacon (from remote EP)
  28949. + * toggling phy_powerdown has same effect as 'inband beacon'
  28950. + * So, toggle bit18 of GPR1, used as a workaround of errata
  28951. + * "PCIe PCIe does not support L2 Power Down"
  28952. + */
  28953. + if (IS_ENABLED(CONFIG_PCI_IMX6)) {
  28954. + regmap_update_bits(g, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD,
  28955. + !IMX6Q_GPR1_PCIE_TEST_PD);
  28956. + }
  28957. +
  28958. + return 0;
  28959. +}
  28960. +
  28961. +static int imx6q_pm_valid(suspend_state_t state)
  28962. +{
  28963. + return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM);
  28964. +}
  28965. +
  28966. +static const struct platform_suspend_ops imx6q_pm_ops = {
  28967. + .enter = imx6q_pm_enter,
  28968. + .valid = imx6q_pm_valid,
  28969. +};
  28970. +
  28971. +void __init imx6q_pm_set_ccm_base(void __iomem *base)
  28972. +{
  28973. + ccm_base = base;
  28974. +}
  28975. +
  28976. +static int __init imx6_pm_get_base(struct imx6_pm_base *base,
  28977. + const char *compat)
  28978. +{
  28979. + struct device_node *node;
  28980. + struct resource res;
  28981. + int ret = 0;
  28982. +
  28983. + node = of_find_compatible_node(NULL, NULL, compat);
  28984. + if (!node) {
  28985. + ret = -ENODEV;
  28986. + goto out;
  28987. + }
  28988. +
  28989. + ret = of_address_to_resource(node, 0, &res);
  28990. + if (ret)
  28991. + goto put_node;
  28992. +
  28993. + base->pbase = res.start;
  28994. + base->vbase = ioremap(res.start, resource_size(&res));
  28995. + if (!base->vbase)
  28996. + ret = -ENOMEM;
  28997. +
  28998. +put_node:
  28999. + of_node_put(node);
  29000. +out:
  29001. + return ret;
  29002. +}
  29003. +
  29004. +static int __init imx6q_ocram_suspend_init(const struct imx6_pm_socdata
  29005. + *socdata)
  29006. +{
  29007. + phys_addr_t ocram_pbase;
  29008. + struct device_node *node;
  29009. + struct platform_device *pdev;
  29010. + struct imx6_cpu_pm_info *pm_info;
  29011. + struct gen_pool *ocram_pool;
  29012. + unsigned long ocram_base;
  29013. + int i, ret = 0;
  29014. + const u32 *mmdc_offset_array;
  29015. +
  29016. + if (!socdata) {
  29017. + pr_warn("%s: invalid argument!\n", __func__);
  29018. + return -EINVAL;
  29019. + }
  29020. +
  29021. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  29022. + if (!node) {
  29023. + pr_warn("%s: failed to find ocram node!\n", __func__);
  29024. + return -ENODEV;
  29025. + }
  29026. +
  29027. + pdev = of_find_device_by_node(node);
  29028. + if (!pdev) {
  29029. + pr_warn("%s: failed to find ocram device!\n", __func__);
  29030. + ret = -ENODEV;
  29031. + goto put_node;
  29032. + }
  29033. +
  29034. + ocram_pool = dev_get_gen_pool(&pdev->dev);
  29035. + if (!ocram_pool) {
  29036. + pr_warn("%s: ocram pool unavailable!\n", __func__);
  29037. + ret = -ENODEV;
  29038. + goto put_node;
  29039. + }
  29040. +
  29041. + ocram_base = gen_pool_alloc(ocram_pool, MX6Q_SUSPEND_OCRAM_SIZE);
  29042. + if (!ocram_base) {
  29043. + pr_warn("%s: unable to alloc ocram!\n", __func__);
  29044. + ret = -ENOMEM;
  29045. + goto put_node;
  29046. + }
  29047. +
  29048. + ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);
  29049. +
  29050. + suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
  29051. + MX6Q_SUSPEND_OCRAM_SIZE, false);
  29052. +
  29053. + pm_info = suspend_ocram_base;
  29054. + pm_info->pbase = ocram_pbase;
  29055. + pm_info->resume_addr = virt_to_phys(v7_cpu_resume);
  29056. + pm_info->pm_info_size = sizeof(*pm_info);
  29057. +
  29058. + /*
  29059. + * ccm physical address is not used by asm code currently,
  29060. + * so get ccm virtual address directly, as we already have
  29061. + * it from ccm driver.
  29062. + */
  29063. + pm_info->ccm_base.vbase = ccm_base;
  29064. +
  29065. + ret = imx6_pm_get_base(&pm_info->mmdc_base, socdata->mmdc_compat);
  29066. + if (ret) {
  29067. + pr_warn("%s: failed to get mmdc base %d!\n", __func__, ret);
  29068. + goto put_node;
  29069. + }
  29070. +
  29071. + ret = imx6_pm_get_base(&pm_info->src_base, socdata->src_compat);
  29072. + if (ret) {
  29073. + pr_warn("%s: failed to get src base %d!\n", __func__, ret);
  29074. + goto src_map_failed;
  29075. + }
  29076. +
  29077. + ret = imx6_pm_get_base(&pm_info->iomuxc_base, socdata->iomuxc_compat);
  29078. + if (ret) {
  29079. + pr_warn("%s: failed to get iomuxc base %d!\n", __func__, ret);
  29080. + goto iomuxc_map_failed;
  29081. + }
  29082. +
  29083. + ret = imx6_pm_get_base(&pm_info->gpc_base, socdata->gpc_compat);
  29084. + if (ret) {
  29085. + pr_warn("%s: failed to get gpc base %d!\n", __func__, ret);
  29086. + goto gpc_map_failed;
  29087. + }
  29088. +
  29089. + ret = imx6_pm_get_base(&pm_info->l2_base, "arm,pl310-cache");
  29090. + if (ret) {
  29091. + pr_warn("%s: failed to get pl310-cache base %d!\n",
  29092. + __func__, ret);
  29093. + goto pl310_cache_map_failed;
  29094. + }
  29095. +
  29096. + pm_info->cpu_type = socdata->cpu_type;
  29097. + pm_info->mmdc_io_num = socdata->mmdc_io_num;
  29098. + mmdc_offset_array = socdata->mmdc_io_offset;
  29099. +
  29100. + for (i = 0; i < pm_info->mmdc_io_num; i++) {
  29101. + pm_info->mmdc_io_val[i][0] =
  29102. + mmdc_offset_array[i];
  29103. + pm_info->mmdc_io_val[i][1] =
  29104. + readl_relaxed(pm_info->iomuxc_base.vbase +
  29105. + mmdc_offset_array[i]);
  29106. + }
  29107. +
  29108. + imx6_suspend_in_ocram_fn = fncpy(
  29109. + suspend_ocram_base + sizeof(*pm_info),
  29110. + &imx6_suspend,
  29111. + MX6Q_SUSPEND_OCRAM_SIZE - sizeof(*pm_info));
  29112. +
  29113. + goto put_node;
  29114. +
  29115. +pl310_cache_map_failed:
  29116. + iounmap(&pm_info->gpc_base.vbase);
  29117. +gpc_map_failed:
  29118. + iounmap(&pm_info->iomuxc_base.vbase);
  29119. +iomuxc_map_failed:
  29120. + iounmap(&pm_info->src_base.vbase);
  29121. +src_map_failed:
  29122. + iounmap(&pm_info->mmdc_base.vbase);
  29123. +put_node:
  29124. + of_node_put(node);
  29125. +
  29126. + return ret;
  29127. +}
  29128. +
  29129. +static void __init imx6_pm_common_init(const struct imx6_pm_socdata
  29130. + *socdata)
  29131. +{
  29132. + struct regmap *gpr;
  29133. + int ret;
  29134. +
  29135. + WARN_ON(!ccm_base);
  29136. +
  29137. + ret = imx6q_ocram_suspend_init(socdata);
  29138. + if (ret)
  29139. + pr_warn("%s: failed to initialize ocram suspend %d!\n",
  29140. + __func__, ret);
  29141. +
  29142. + /*
  29143. + * This is for SW workaround step #1 of ERR007265, see comments
  29144. + * in imx6q_set_lpm for details of this errata.
  29145. + * Force IOMUXC irq pending, so that the interrupt to GPC can be
  29146. + * used to deassert dsm_request signal when the signal gets
  29147. + * asserted unexpectedly.
  29148. + */
  29149. + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  29150. + if (!IS_ERR(gpr))
  29151. + regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT_MASK,
  29152. + IMX6Q_GPR1_GINT_MASK);
  29153. +
  29154. +
  29155. + suspend_set_ops(&imx6q_pm_ops);
  29156. +}
  29157. +
  29158. +void __init imx6q_pm_init(void)
  29159. +{
  29160. + imx6_pm_common_init(&imx6q_pm_data);
  29161. +}
  29162. +
  29163. +void __init imx6dl_pm_init(void)
  29164. +{
  29165. + imx6_pm_common_init(NULL);
  29166. +}
  29167. +
  29168. +void __init imx6sl_pm_init(void)
  29169. +{
  29170. + imx6_pm_common_init(NULL);
  29171. +}
  29172. diff -Nur linux-3.14.14/arch/arm/mach-imx/pm-imx6q.c linux-imx6-3.14/arch/arm/mach-imx/pm-imx6q.c
  29173. --- linux-3.14.14/arch/arm/mach-imx/pm-imx6q.c 2014-07-28 10:07:25.000000000 -0500
  29174. +++ linux-imx6-3.14/arch/arm/mach-imx/pm-imx6q.c 1969-12-31 18:00:00.000000000 -0600
  29175. @@ -1,241 +0,0 @@
  29176. -/*
  29177. - * Copyright 2011-2013 Freescale Semiconductor, Inc.
  29178. - * Copyright 2011 Linaro Ltd.
  29179. - *
  29180. - * The code contained herein is licensed under the GNU General Public
  29181. - * License. You may obtain a copy of the GNU General Public License
  29182. - * Version 2 or later at the following locations:
  29183. - *
  29184. - * http://www.opensource.org/licenses/gpl-license.html
  29185. - * http://www.gnu.org/copyleft/gpl.html
  29186. - */
  29187. -
  29188. -#include <linux/delay.h>
  29189. -#include <linux/init.h>
  29190. -#include <linux/io.h>
  29191. -#include <linux/irq.h>
  29192. -#include <linux/mfd/syscon.h>
  29193. -#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  29194. -#include <linux/of.h>
  29195. -#include <linux/of_address.h>
  29196. -#include <linux/regmap.h>
  29197. -#include <linux/suspend.h>
  29198. -#include <asm/cacheflush.h>
  29199. -#include <asm/proc-fns.h>
  29200. -#include <asm/suspend.h>
  29201. -#include <asm/hardware/cache-l2x0.h>
  29202. -
  29203. -#include "common.h"
  29204. -#include "hardware.h"
  29205. -
  29206. -#define CCR 0x0
  29207. -#define BM_CCR_WB_COUNT (0x7 << 16)
  29208. -#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
  29209. -#define BM_CCR_RBC_EN (0x1 << 27)
  29210. -
  29211. -#define CLPCR 0x54
  29212. -#define BP_CLPCR_LPM 0
  29213. -#define BM_CLPCR_LPM (0x3 << 0)
  29214. -#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
  29215. -#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
  29216. -#define BM_CLPCR_SBYOS (0x1 << 6)
  29217. -#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
  29218. -#define BM_CLPCR_VSTBY (0x1 << 8)
  29219. -#define BP_CLPCR_STBY_COUNT 9
  29220. -#define BM_CLPCR_STBY_COUNT (0x3 << 9)
  29221. -#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
  29222. -#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
  29223. -#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
  29224. -#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
  29225. -#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
  29226. -#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
  29227. -#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
  29228. -#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
  29229. -#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
  29230. -#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
  29231. -#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
  29232. -
  29233. -#define CGPR 0x64
  29234. -#define BM_CGPR_CHICKEN_BIT (0x1 << 17)
  29235. -
  29236. -static void __iomem *ccm_base;
  29237. -
  29238. -void imx6q_set_chicken_bit(void)
  29239. -{
  29240. - u32 val = readl_relaxed(ccm_base + CGPR);
  29241. -
  29242. - val |= BM_CGPR_CHICKEN_BIT;
  29243. - writel_relaxed(val, ccm_base + CGPR);
  29244. -}
  29245. -
  29246. -static void imx6q_enable_rbc(bool enable)
  29247. -{
  29248. - u32 val;
  29249. -
  29250. - /*
  29251. - * need to mask all interrupts in GPC before
  29252. - * operating RBC configurations
  29253. - */
  29254. - imx_gpc_mask_all();
  29255. -
  29256. - /* configure RBC enable bit */
  29257. - val = readl_relaxed(ccm_base + CCR);
  29258. - val &= ~BM_CCR_RBC_EN;
  29259. - val |= enable ? BM_CCR_RBC_EN : 0;
  29260. - writel_relaxed(val, ccm_base + CCR);
  29261. -
  29262. - /* configure RBC count */
  29263. - val = readl_relaxed(ccm_base + CCR);
  29264. - val &= ~BM_CCR_RBC_BYPASS_COUNT;
  29265. - val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
  29266. - writel(val, ccm_base + CCR);
  29267. -
  29268. - /*
  29269. - * need to delay at least 2 cycles of CKIL(32K)
  29270. - * due to hardware design requirement, which is
  29271. - * ~61us, here we use 65us for safe
  29272. - */
  29273. - udelay(65);
  29274. -
  29275. - /* restore GPC interrupt mask settings */
  29276. - imx_gpc_restore_all();
  29277. -}
  29278. -
  29279. -static void imx6q_enable_wb(bool enable)
  29280. -{
  29281. - u32 val;
  29282. -
  29283. - /* configure well bias enable bit */
  29284. - val = readl_relaxed(ccm_base + CLPCR);
  29285. - val &= ~BM_CLPCR_WB_PER_AT_LPM;
  29286. - val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
  29287. - writel_relaxed(val, ccm_base + CLPCR);
  29288. -
  29289. - /* configure well bias count */
  29290. - val = readl_relaxed(ccm_base + CCR);
  29291. - val &= ~BM_CCR_WB_COUNT;
  29292. - val |= enable ? BM_CCR_WB_COUNT : 0;
  29293. - writel_relaxed(val, ccm_base + CCR);
  29294. -}
  29295. -
  29296. -int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
  29297. -{
  29298. - struct irq_desc *iomuxc_irq_desc;
  29299. - u32 val = readl_relaxed(ccm_base + CLPCR);
  29300. -
  29301. - val &= ~BM_CLPCR_LPM;
  29302. - switch (mode) {
  29303. - case WAIT_CLOCKED:
  29304. - break;
  29305. - case WAIT_UNCLOCKED:
  29306. - val |= 0x1 << BP_CLPCR_LPM;
  29307. - val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
  29308. - break;
  29309. - case STOP_POWER_ON:
  29310. - val |= 0x2 << BP_CLPCR_LPM;
  29311. - break;
  29312. - case WAIT_UNCLOCKED_POWER_OFF:
  29313. - val |= 0x1 << BP_CLPCR_LPM;
  29314. - val &= ~BM_CLPCR_VSTBY;
  29315. - val &= ~BM_CLPCR_SBYOS;
  29316. - break;
  29317. - case STOP_POWER_OFF:
  29318. - val |= 0x2 << BP_CLPCR_LPM;
  29319. - val |= 0x3 << BP_CLPCR_STBY_COUNT;
  29320. - val |= BM_CLPCR_VSTBY;
  29321. - val |= BM_CLPCR_SBYOS;
  29322. - if (cpu_is_imx6sl()) {
  29323. - val |= BM_CLPCR_BYPASS_PMIC_READY;
  29324. - val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
  29325. - } else {
  29326. - val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  29327. - }
  29328. - break;
  29329. - default:
  29330. - return -EINVAL;
  29331. - }
  29332. -
  29333. - /*
  29334. - * ERR007265: CCM: When improper low-power sequence is used,
  29335. - * the SoC enters low power mode before the ARM core executes WFI.
  29336. - *
  29337. - * Software workaround:
  29338. - * 1) Software should trigger IRQ #32 (IOMUX) to be always pending
  29339. - * by setting IOMUX_GPR1_GINT.
  29340. - * 2) Software should then unmask IRQ #32 in GPC before setting CCM
  29341. - * Low-Power mode.
  29342. - * 3) Software should mask IRQ #32 right after CCM Low-Power mode
  29343. - * is set (set bits 0-1 of CCM_CLPCR).
  29344. - */
  29345. - iomuxc_irq_desc = irq_to_desc(32);
  29346. - imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data);
  29347. - writel_relaxed(val, ccm_base + CLPCR);
  29348. - imx_gpc_irq_mask(&iomuxc_irq_desc->irq_data);
  29349. -
  29350. - return 0;
  29351. -}
  29352. -
  29353. -static int imx6q_suspend_finish(unsigned long val)
  29354. -{
  29355. - cpu_do_idle();
  29356. - return 0;
  29357. -}
  29358. -
  29359. -static int imx6q_pm_enter(suspend_state_t state)
  29360. -{
  29361. - switch (state) {
  29362. - case PM_SUSPEND_MEM:
  29363. - imx6q_set_lpm(STOP_POWER_OFF);
  29364. - imx6q_enable_wb(true);
  29365. - imx6q_enable_rbc(true);
  29366. - imx_gpc_pre_suspend();
  29367. - imx_anatop_pre_suspend();
  29368. - imx_set_cpu_jump(0, v7_cpu_resume);
  29369. - /* Zzz ... */
  29370. - cpu_suspend(0, imx6q_suspend_finish);
  29371. - if (cpu_is_imx6q() || cpu_is_imx6dl())
  29372. - imx_smp_prepare();
  29373. - imx_anatop_post_resume();
  29374. - imx_gpc_post_resume();
  29375. - imx6q_enable_rbc(false);
  29376. - imx6q_enable_wb(false);
  29377. - imx6q_set_lpm(WAIT_CLOCKED);
  29378. - break;
  29379. - default:
  29380. - return -EINVAL;
  29381. - }
  29382. -
  29383. - return 0;
  29384. -}
  29385. -
  29386. -static const struct platform_suspend_ops imx6q_pm_ops = {
  29387. - .enter = imx6q_pm_enter,
  29388. - .valid = suspend_valid_only_mem,
  29389. -};
  29390. -
  29391. -void __init imx6q_pm_set_ccm_base(void __iomem *base)
  29392. -{
  29393. - ccm_base = base;
  29394. -}
  29395. -
  29396. -void __init imx6q_pm_init(void)
  29397. -{
  29398. - struct regmap *gpr;
  29399. -
  29400. - WARN_ON(!ccm_base);
  29401. -
  29402. - /*
  29403. - * This is for SW workaround step #1 of ERR007265, see comments
  29404. - * in imx6q_set_lpm for details of this errata.
  29405. - * Force IOMUXC irq pending, so that the interrupt to GPC can be
  29406. - * used to deassert dsm_request signal when the signal gets
  29407. - * asserted unexpectedly.
  29408. - */
  29409. - gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  29410. - if (!IS_ERR(gpr))
  29411. - regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
  29412. - IMX6Q_GPR1_GINT);
  29413. -
  29414. -
  29415. - suspend_set_ops(&imx6q_pm_ops);
  29416. -}
  29417. diff -Nur linux-3.14.14/arch/arm/mach-imx/suspend-imx6.S linux-imx6-3.14/arch/arm/mach-imx/suspend-imx6.S
  29418. --- linux-3.14.14/arch/arm/mach-imx/suspend-imx6.S 1969-12-31 18:00:00.000000000 -0600
  29419. +++ linux-imx6-3.14/arch/arm/mach-imx/suspend-imx6.S 2014-12-08 00:31:51.232418001 -0600
  29420. @@ -0,0 +1,306 @@
  29421. +/*
  29422. + * Copyright 2014 Freescale Semiconductor, Inc.
  29423. + *
  29424. + * The code contained herein is licensed under the GNU General Public
  29425. + * License. You may obtain a copy of the GNU General Public License
  29426. + * Version 2 or later at the following locations:
  29427. + *
  29428. + * http://www.opensource.org/licenses/gpl-license.html
  29429. + * http://www.gnu.org/copyleft/gpl.html
  29430. + */
  29431. +
  29432. +#include <linux/linkage.h>
  29433. +#include <asm/asm-offsets.h>
  29434. +#include <asm/hardware/cache-l2x0.h>
  29435. +#include "hardware.h"
  29436. +
  29437. +/*
  29438. + * ==================== low level suspend ====================
  29439. + *
  29440. + * Better to follow below rules to use ARM registers:
  29441. + * r0: pm_info structure address;
  29442. + * r1 ~ r4: for saving pm_info members;
  29443. + * r5 ~ r10: free registers;
  29444. + * r11: io base address.
  29445. + *
  29446. + * suspend ocram space layout:
  29447. + * ======================== high address ======================
  29448. + * .
  29449. + * .
  29450. + * .
  29451. + * ^
  29452. + * ^
  29453. + * ^
  29454. + * imx6_suspend code
  29455. + * PM_INFO structure(imx6_cpu_pm_info)
  29456. + * ======================== low address =======================
  29457. + */
  29458. +
  29459. +/*
  29460. + * Below offsets are based on struct imx6_cpu_pm_info
  29461. + * which defined in arch/arm/mach-imx/pm-imx6q.c, this
  29462. + * structure contains necessary pm info for low level
  29463. + * suspend related code.
  29464. + */
  29465. +#define PM_INFO_PBASE_OFFSET 0x0
  29466. +#define PM_INFO_RESUME_ADDR_OFFSET 0x4
  29467. +#define PM_INFO_CPU_TYPE_OFFSET 0x8
  29468. +#define PM_INFO_PM_INFO_SIZE_OFFSET 0xC
  29469. +#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
  29470. +#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
  29471. +#define PM_INFO_MX6Q_SRC_P_OFFSET 0x18
  29472. +#define PM_INFO_MX6Q_SRC_V_OFFSET 0x1C
  29473. +#define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x20
  29474. +#define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x24
  29475. +#define PM_INFO_MX6Q_CCM_P_OFFSET 0x28
  29476. +#define PM_INFO_MX6Q_CCM_V_OFFSET 0x2C
  29477. +#define PM_INFO_MX6Q_GPC_P_OFFSET 0x30
  29478. +#define PM_INFO_MX6Q_GPC_V_OFFSET 0x34
  29479. +#define PM_INFO_MX6Q_L2_P_OFFSET 0x38
  29480. +#define PM_INFO_MX6Q_L2_V_OFFSET 0x3C
  29481. +#define PM_INFO_MMDC_IO_NUM_OFFSET 0x40
  29482. +#define PM_INFO_MMDC_IO_VAL_OFFSET 0x44
  29483. +
  29484. +#define MX6Q_SRC_GPR1 0x20
  29485. +#define MX6Q_SRC_GPR2 0x24
  29486. +#define MX6Q_MMDC_MAPSR 0x404
  29487. +#define MX6Q_GPC_IMR1 0x08
  29488. +#define MX6Q_GPC_IMR2 0x0c
  29489. +#define MX6Q_GPC_IMR3 0x10
  29490. +#define MX6Q_GPC_IMR4 0x14
  29491. +#define MX6Q_CCM_CCR 0x0
  29492. +
  29493. + .align 3
  29494. +
  29495. + .macro sync_l2_cache
  29496. +
  29497. + /* sync L2 cache to drain L2's buffers to DRAM. */
  29498. +#ifdef CONFIG_CACHE_L2X0
  29499. + ldr r11, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
  29500. + mov r6, #0x0
  29501. + str r6, [r11, #L2X0_CACHE_SYNC]
  29502. +1:
  29503. + ldr r6, [r11, #L2X0_CACHE_SYNC]
  29504. + ands r6, r6, #0x1
  29505. + bne 1b
  29506. +#endif
  29507. +
  29508. + .endm
  29509. +
  29510. + .macro resume_mmdc
  29511. +
  29512. + /* restore MMDC IO */
  29513. + cmp r5, #0x0
  29514. + ldreq r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
  29515. + ldrne r11, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
  29516. +
  29517. + ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
  29518. + ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
  29519. + add r7, r7, r0
  29520. +1:
  29521. + ldr r8, [r7], #0x4
  29522. + ldr r9, [r7], #0x4
  29523. + str r9, [r11, r8]
  29524. + subs r6, r6, #0x1
  29525. + bne 1b
  29526. +
  29527. + cmp r5, #0x0
  29528. + ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
  29529. + ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
  29530. +
  29531. + /* let DDR out of self-refresh */
  29532. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29533. + bic r7, r7, #(1 << 21)
  29534. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29535. +2:
  29536. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29537. + ands r7, r7, #(1 << 25)
  29538. + bne 2b
  29539. +
  29540. + /* enable DDR auto power saving */
  29541. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29542. + bic r7, r7, #0x1
  29543. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29544. +
  29545. + .endm
  29546. +
  29547. +ENTRY(imx6_suspend)
  29548. + ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
  29549. + ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
  29550. + ldr r3, [r0, #PM_INFO_CPU_TYPE_OFFSET]
  29551. + ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
  29552. +
  29553. + /*
  29554. + * counting the resume address in iram
  29555. + * to set it in SRC register.
  29556. + */
  29557. + ldr r6, =imx6_suspend
  29558. + ldr r7, =resume
  29559. + sub r7, r7, r6
  29560. + add r8, r1, r4
  29561. + add r9, r8, r7
  29562. +
  29563. + /*
  29564. + * make sure TLB contain the addr we want,
  29565. + * as we will access them after MMDC IO floated.
  29566. + */
  29567. +
  29568. + ldr r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
  29569. + ldr r6, [r11, #0x0]
  29570. + ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
  29571. + ldr r6, [r11, #0x0]
  29572. + ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
  29573. + ldr r6, [r11, #0x0]
  29574. +
  29575. + /* use r11 to store the IO address */
  29576. + ldr r11, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
  29577. + /* store physical resume addr and pm_info address. */
  29578. + str r9, [r11, #MX6Q_SRC_GPR1]
  29579. + str r1, [r11, #MX6Q_SRC_GPR2]
  29580. +
  29581. + /* need to sync L2 cache before DSM. */
  29582. + sync_l2_cache
  29583. +
  29584. + ldr r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
  29585. + /*
  29586. + * put DDR explicitly into self-refresh and
  29587. + * disable automatic power savings.
  29588. + */
  29589. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29590. + orr r7, r7, #0x1
  29591. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29592. +
  29593. + /* make the DDR explicitly enter self-refresh. */
  29594. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29595. + orr r7, r7, #(1 << 21)
  29596. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29597. +
  29598. +poll_dvfs_set:
  29599. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29600. + ands r7, r7, #(1 << 25)
  29601. + beq poll_dvfs_set
  29602. +
  29603. + ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
  29604. + ldr r6, =0x0
  29605. + ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
  29606. + ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
  29607. + add r8, r8, r0
  29608. +set_mmdc_io_lpm:
  29609. + ldr r9, [r8], #0x8
  29610. + str r6, [r11, r9]
  29611. + subs r7, r7, #0x1
  29612. + bne set_mmdc_io_lpm
  29613. +
  29614. + /*
  29615. + * mask all GPC interrupts before
  29616. + * enabling the RBC counters to
  29617. + * avoid the counter starting too
  29618. + * early if an interupt is already
  29619. + * pending.
  29620. + */
  29621. + ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
  29622. + ldr r6, [r11, #MX6Q_GPC_IMR1]
  29623. + ldr r7, [r11, #MX6Q_GPC_IMR2]
  29624. + ldr r8, [r11, #MX6Q_GPC_IMR3]
  29625. + ldr r9, [r11, #MX6Q_GPC_IMR4]
  29626. +
  29627. + ldr r10, =0xffffffff
  29628. + str r10, [r11, #MX6Q_GPC_IMR1]
  29629. + str r10, [r11, #MX6Q_GPC_IMR2]
  29630. + str r10, [r11, #MX6Q_GPC_IMR3]
  29631. + str r10, [r11, #MX6Q_GPC_IMR4]
  29632. +
  29633. + /*
  29634. + * enable the RBC bypass counter here
  29635. + * to hold off the interrupts. RBC counter
  29636. + * = 32 (1ms), Minimum RBC delay should be
  29637. + * 400us for the analog LDOs to power down.
  29638. + */
  29639. + ldr r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
  29640. + ldr r10, [r11, #MX6Q_CCM_CCR]
  29641. + bic r10, r10, #(0x3f << 21)
  29642. + orr r10, r10, #(0x20 << 21)
  29643. + str r10, [r11, #MX6Q_CCM_CCR]
  29644. +
  29645. + /* enable the counter. */
  29646. + ldr r10, [r11, #MX6Q_CCM_CCR]
  29647. + orr r10, r10, #(0x1 << 27)
  29648. + str r10, [r11, #MX6Q_CCM_CCR]
  29649. +
  29650. + /* unmask all the GPC interrupts. */
  29651. + ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
  29652. + str r6, [r11, #MX6Q_GPC_IMR1]
  29653. + str r7, [r11, #MX6Q_GPC_IMR2]
  29654. + str r8, [r11, #MX6Q_GPC_IMR3]
  29655. + str r9, [r11, #MX6Q_GPC_IMR4]
  29656. +
  29657. + /*
  29658. + * now delay for a short while (3usec)
  29659. + * ARM is at 1GHz at this point
  29660. + * so a short loop should be enough.
  29661. + * this delay is required to ensure that
  29662. + * the RBC counter can start counting in
  29663. + * case an interrupt is already pending
  29664. + * or in case an interrupt arrives just
  29665. + * as ARM is about to assert DSM_request.
  29666. + */
  29667. + ldr r6, =2000
  29668. +rbc_loop:
  29669. + subs r6, r6, #0x1
  29670. + bne rbc_loop
  29671. +
  29672. + /* Zzz, enter stop mode */
  29673. + wfi
  29674. + nop
  29675. + nop
  29676. + nop
  29677. + nop
  29678. +
  29679. + /*
  29680. + * run to here means there is pending
  29681. + * wakeup source, system should auto
  29682. + * resume, we need to restore MMDC IO first
  29683. + */
  29684. + mov r5, #0x0
  29685. + resume_mmdc
  29686. +
  29687. + /* return to suspend finish */
  29688. + mov pc, lr
  29689. +
  29690. +resume:
  29691. + /* invalidate L1 I-cache first */
  29692. + mov r6, #0x0
  29693. + mcr p15, 0, r6, c7, c5, 0
  29694. + mcr p15, 0, r6, c7, c5, 6
  29695. + /* enable the Icache and branch prediction */
  29696. + mov r6, #0x1800
  29697. + mcr p15, 0, r6, c1, c0, 0
  29698. + isb
  29699. +
  29700. + /* get physical resume address from pm_info. */
  29701. + ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
  29702. + /* clear core0's entry and parameter */
  29703. + ldr r11, [r0, #PM_INFO_MX6Q_SRC_P_OFFSET]
  29704. + mov r7, #0x0
  29705. + str r7, [r11, #MX6Q_SRC_GPR1]
  29706. + str r7, [r11, #MX6Q_SRC_GPR2]
  29707. +
  29708. + mov r5, #0x1
  29709. + resume_mmdc
  29710. +
  29711. + mov pc, lr
  29712. +ENDPROC(imx6_suspend)
  29713. +
  29714. +/*
  29715. + * The following code must assume it is running from physical address
  29716. + * where absolute virtual addresses to the data section have to be
  29717. + * turned into relative ones.
  29718. + */
  29719. +
  29720. +ENTRY(v7_cpu_resume)
  29721. + bl v7_invalidate_l1
  29722. +#ifdef CONFIG_CACHE_L2X0
  29723. + bl l2c310_early_resume
  29724. +#endif
  29725. + b cpu_resume
  29726. +ENDPROC(v7_cpu_resume)
  29727. diff -Nur linux-3.14.14/arch/arm/mach-imx/system.c linux-imx6-3.14/arch/arm/mach-imx/system.c
  29728. --- linux-3.14.14/arch/arm/mach-imx/system.c 2014-07-28 10:07:25.000000000 -0500
  29729. +++ linux-imx6-3.14/arch/arm/mach-imx/system.c 2014-12-08 00:31:51.232418001 -0600
  29730. @@ -34,6 +34,7 @@
  29731. static void __iomem *wdog_base;
  29732. static struct clk *wdog_clk;
  29733. +static u32 wdog_source = 1; /* use WDOG1 default */
  29734. /*
  29735. * Reset the system. It is called by machine_restart().
  29736. @@ -47,6 +48,15 @@
  29737. if (cpu_is_mx1())
  29738. wcr_enable = (1 << 0);
  29739. + /*
  29740. + * Some i.MX6 boards use WDOG2 to reset external pmic in bypass mode,
  29741. + * so do WDOG2 reset here. Do not set SRS, since we will
  29742. + * trigger external POR later. Use WDOG1 to reset in ldo-enable
  29743. + * mode. You can set it by "fsl,wdog-reset" in dts.
  29744. + */
  29745. + else if (wdog_source == 2 && (cpu_is_imx6q() || cpu_is_imx6dl() ||
  29746. + cpu_is_imx6sl()))
  29747. + wcr_enable = 0x14;
  29748. else
  29749. wcr_enable = (1 << 2);
  29750. @@ -90,12 +100,29 @@
  29751. void __init mxc_arch_reset_init_dt(void)
  29752. {
  29753. - struct device_node *np;
  29754. + struct device_node *np = NULL;
  29755. +
  29756. + if (cpu_is_imx6q() || cpu_is_imx6dl())
  29757. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
  29758. + else if (cpu_is_imx6sl())
  29759. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpc");
  29760. +
  29761. + if (np)
  29762. + of_property_read_u32(np, "fsl,wdog-reset", &wdog_source);
  29763. + pr_info("Use WDOG%d as reset source\n", wdog_source);
  29764. np = of_find_compatible_node(NULL, NULL, "fsl,imx21-wdt");
  29765. wdog_base = of_iomap(np, 0);
  29766. WARN_ON(!wdog_base);
  29767. + /* Some i.MX6 boards use WDOG2 to reset board in ldo-bypass mode */
  29768. + if (wdog_source == 2 && (cpu_is_imx6q() || cpu_is_imx6dl() ||
  29769. + cpu_is_imx6sl())) {
  29770. + np = of_find_compatible_node(np, NULL, "fsl,imx21-wdt");
  29771. + wdog_base = of_iomap(np, 0);
  29772. + WARN_ON(!wdog_base);
  29773. + }
  29774. +
  29775. wdog_clk = of_clk_get(np, 0);
  29776. if (IS_ERR(wdog_clk)) {
  29777. pr_warn("%s: failed to get wdog clock\n", __func__);
  29778. @@ -124,7 +151,7 @@
  29779. }
  29780. /* Configure the L2 PREFETCH and POWER registers */
  29781. - val = readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
  29782. + val = readl_relaxed(l2x0_base + L310_PREFETCH_CTRL);
  29783. val |= 0x70800000;
  29784. /*
  29785. * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
  29786. @@ -137,14 +164,12 @@
  29787. */
  29788. if (cpu_is_imx6q())
  29789. val &= ~(1 << 30 | 1 << 23);
  29790. - writel_relaxed(val, l2x0_base + L2X0_PREFETCH_CTRL);
  29791. - val = L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN;
  29792. - writel_relaxed(val, l2x0_base + L2X0_POWER_CTRL);
  29793. + writel_relaxed(val, l2x0_base + L310_PREFETCH_CTRL);
  29794. iounmap(l2x0_base);
  29795. of_node_put(np);
  29796. out:
  29797. - l2x0_of_init(0, ~0UL);
  29798. + l2x0_of_init(0, ~0);
  29799. }
  29800. #endif
  29801. diff -Nur linux-3.14.14/arch/arm/mach-imx/time.c linux-imx6-3.14/arch/arm/mach-imx/time.c
  29802. --- linux-3.14.14/arch/arm/mach-imx/time.c 2014-07-28 10:07:25.000000000 -0500
  29803. +++ linux-imx6-3.14/arch/arm/mach-imx/time.c 2014-12-08 00:31:51.232418001 -0600
  29804. @@ -60,7 +60,11 @@
  29805. #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */
  29806. #define V2_TCTL_CLK_IPG (1 << 6)
  29807. #define V2_TCTL_CLK_PER (2 << 6)
  29808. +#define V2_TCTL_CLK_OSC_DIV8 (5 << 6)
  29809. +#define V2_TCTL_CLK_OSC (7 << 6)
  29810. +#define V2_TCTL_24MEN (1 << 10)
  29811. #define V2_TCTL_FRR (1 << 9)
  29812. +#define V2_TPRER_PRE24M 12
  29813. #define V2_IR 0x0c
  29814. #define V2_TSTAT 0x08
  29815. #define V2_TSTAT_OF1 (1 << 0)
  29816. @@ -277,11 +281,20 @@
  29817. void __init mxc_timer_init(void __iomem *base, int irq)
  29818. {
  29819. - uint32_t tctl_val;
  29820. + uint32_t tctl_val, tprer_val;
  29821. struct clk *timer_clk;
  29822. struct clk *timer_ipg_clk;
  29823. - timer_clk = clk_get_sys("imx-gpt.0", "per");
  29824. + /*
  29825. + * gpt clk source from 24M OSC on imx6q > TO1.0 and
  29826. + * imx6dl, others from per clk.
  29827. + */
  29828. + if ((cpu_is_imx6q() && imx_get_soc_revision() > IMX_CHIP_REVISION_1_0)
  29829. + || cpu_is_imx6dl())
  29830. + timer_clk = clk_get_sys("imx-gpt.0", "gpt_3m");
  29831. + else
  29832. + timer_clk = clk_get_sys("imx-gpt.0", "per");
  29833. +
  29834. if (IS_ERR(timer_clk)) {
  29835. pr_err("i.MX timer: unable to get clk\n");
  29836. return;
  29837. @@ -302,10 +315,24 @@
  29838. __raw_writel(0, timer_base + MXC_TCTL);
  29839. __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
  29840. - if (timer_is_v2())
  29841. - tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
  29842. - else
  29843. + if (timer_is_v2()) {
  29844. + if ((cpu_is_imx6q() && imx_get_soc_revision() >
  29845. + IMX_CHIP_REVISION_1_0) || cpu_is_imx6dl()) {
  29846. + tctl_val = V2_TCTL_CLK_OSC_DIV8 | V2_TCTL_FRR |
  29847. + V2_TCTL_WAITEN | MXC_TCTL_TEN;
  29848. + if (cpu_is_imx6dl()) {
  29849. + /* 24 / 8 = 3 MHz */
  29850. + tprer_val = 7 << V2_TPRER_PRE24M;
  29851. + __raw_writel(tprer_val, timer_base + MXC_TPRER);
  29852. + tctl_val |= V2_TCTL_24MEN;
  29853. + }
  29854. + } else {
  29855. + tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR |
  29856. + V2_TCTL_WAITEN | MXC_TCTL_TEN;
  29857. + }
  29858. + } else {
  29859. tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
  29860. + }
  29861. __raw_writel(tctl_val, timer_base + MXC_TCTL);
  29862. diff -Nur linux-3.14.14/arch/arm/mach-nomadik/cpu-8815.c linux-imx6-3.14/arch/arm/mach-nomadik/cpu-8815.c
  29863. --- linux-3.14.14/arch/arm/mach-nomadik/cpu-8815.c 2014-07-28 10:07:25.000000000 -0500
  29864. +++ linux-imx6-3.14/arch/arm/mach-nomadik/cpu-8815.c 2014-12-08 00:31:51.256418001 -0600
  29865. @@ -147,7 +147,7 @@
  29866. {
  29867. #ifdef CONFIG_CACHE_L2X0
  29868. /* At full speed latency must be >=2, so 0x249 in low bits */
  29869. - l2x0_of_init(0x00730249, 0xfe000fff);
  29870. + l2x0_of_init(0x00700249, 0xfe0fefff);
  29871. #endif
  29872. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  29873. }
  29874. diff -Nur linux-3.14.14/arch/arm/mach-omap2/common.h linux-imx6-3.14/arch/arm/mach-omap2/common.h
  29875. --- linux-3.14.14/arch/arm/mach-omap2/common.h 2014-07-28 10:07:25.000000000 -0500
  29876. +++ linux-imx6-3.14/arch/arm/mach-omap2/common.h 2014-12-08 00:31:51.272418001 -0600
  29877. @@ -91,6 +91,7 @@
  29878. extern void omap3_secure_sync32k_timer_init(void);
  29879. extern void omap3_gptimer_timer_init(void);
  29880. extern void omap4_local_timer_init(void);
  29881. +int omap_l2_cache_init(void);
  29882. extern void omap5_realtime_timer_init(void);
  29883. void omap2420_init_early(void);
  29884. diff -Nur linux-3.14.14/arch/arm/mach-omap2/io.c linux-imx6-3.14/arch/arm/mach-omap2/io.c
  29885. --- linux-3.14.14/arch/arm/mach-omap2/io.c 2014-07-28 10:07:25.000000000 -0500
  29886. +++ linux-imx6-3.14/arch/arm/mach-omap2/io.c 2014-12-08 00:31:51.276418001 -0600
  29887. @@ -608,6 +608,7 @@
  29888. am43xx_clockdomains_init();
  29889. am43xx_hwmod_init();
  29890. omap_hwmod_init_postsetup();
  29891. + omap_l2_cache_init();
  29892. omap_clk_soc_init = am43xx_dt_clk_init;
  29893. }
  29894. @@ -639,6 +640,7 @@
  29895. omap44xx_clockdomains_init();
  29896. omap44xx_hwmod_init();
  29897. omap_hwmod_init_postsetup();
  29898. + omap_l2_cache_init();
  29899. omap_clk_soc_init = omap4xxx_dt_clk_init;
  29900. }
  29901. diff -Nur linux-3.14.14/arch/arm/mach-omap2/Kconfig linux-imx6-3.14/arch/arm/mach-omap2/Kconfig
  29902. --- linux-3.14.14/arch/arm/mach-omap2/Kconfig 2014-07-28 10:07:25.000000000 -0500
  29903. +++ linux-imx6-3.14/arch/arm/mach-omap2/Kconfig 2014-12-08 00:31:51.264418001 -0600
  29904. @@ -78,6 +78,7 @@
  29905. select MULTI_IRQ_HANDLER
  29906. select ARM_GIC
  29907. select MACH_OMAP_GENERIC
  29908. + select MIGHT_HAVE_CACHE_L2X0
  29909. config SOC_DRA7XX
  29910. bool "TI DRA7XX"
  29911. diff -Nur linux-3.14.14/arch/arm/mach-omap2/omap4-common.c linux-imx6-3.14/arch/arm/mach-omap2/omap4-common.c
  29912. --- linux-3.14.14/arch/arm/mach-omap2/omap4-common.c 2014-07-28 10:07:25.000000000 -0500
  29913. +++ linux-imx6-3.14/arch/arm/mach-omap2/omap4-common.c 2014-12-08 00:31:51.280418001 -0600
  29914. @@ -166,75 +166,57 @@
  29915. return l2cache_base;
  29916. }
  29917. -static void omap4_l2x0_disable(void)
  29918. +static void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
  29919. {
  29920. - outer_flush_all();
  29921. - /* Disable PL310 L2 Cache controller */
  29922. - omap_smc1(0x102, 0x0);
  29923. -}
  29924. + unsigned smc_op;
  29925. -static void omap4_l2x0_set_debug(unsigned long val)
  29926. -{
  29927. - /* Program PL310 L2 Cache controller debug register */
  29928. - omap_smc1(0x100, val);
  29929. + switch (reg) {
  29930. + case L2X0_CTRL:
  29931. + smc_op = OMAP4_MON_L2X0_CTRL_INDEX;
  29932. + break;
  29933. +
  29934. + case L2X0_AUX_CTRL:
  29935. + smc_op = OMAP4_MON_L2X0_AUXCTRL_INDEX;
  29936. + break;
  29937. +
  29938. + case L2X0_DEBUG_CTRL:
  29939. + smc_op = OMAP4_MON_L2X0_DBG_CTRL_INDEX;
  29940. + break;
  29941. +
  29942. + case L310_PREFETCH_CTRL:
  29943. + smc_op = OMAP4_MON_L2X0_PREFETCH_INDEX;
  29944. + break;
  29945. +
  29946. + default:
  29947. + WARN_ONCE(1, "OMAP L2C310: ignoring write to reg 0x%x\n", reg);
  29948. + return;
  29949. + }
  29950. +
  29951. + omap_smc1(smc_op, val);
  29952. }
  29953. -static int __init omap_l2_cache_init(void)
  29954. +int __init omap_l2_cache_init(void)
  29955. {
  29956. - u32 aux_ctrl = 0;
  29957. -
  29958. - /*
  29959. - * To avoid code running on other OMAPs in
  29960. - * multi-omap builds
  29961. - */
  29962. - if (!cpu_is_omap44xx())
  29963. - return -ENODEV;
  29964. + u32 aux_ctrl;
  29965. /* Static mapping, never released */
  29966. l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
  29967. if (WARN_ON(!l2cache_base))
  29968. return -ENOMEM;
  29969. - /*
  29970. - * 16-way associativity, parity disabled
  29971. - * Way size - 32KB (es1.0)
  29972. - * Way size - 64KB (es2.0 +)
  29973. - */
  29974. - aux_ctrl = ((1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT) |
  29975. - (0x1 << 25) |
  29976. - (0x1 << L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT) |
  29977. - (0x1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT));
  29978. -
  29979. - if (omap_rev() == OMAP4430_REV_ES1_0) {
  29980. - aux_ctrl |= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT;
  29981. - } else {
  29982. - aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
  29983. - (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
  29984. - (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
  29985. - (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
  29986. - (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT));
  29987. - }
  29988. - if (omap_rev() != OMAP4430_REV_ES1_0)
  29989. - omap_smc1(0x109, aux_ctrl);
  29990. -
  29991. - /* Enable PL310 L2 Cache controller */
  29992. - omap_smc1(0x102, 0x1);
  29993. + /* 16-way associativity, parity disabled, way size - 64KB (es2.0 +) */
  29994. + aux_ctrl = L2C_AUX_CTRL_SHARED_OVERRIDE |
  29995. + L310_AUX_CTRL_DATA_PREFETCH |
  29996. + L310_AUX_CTRL_INSTR_PREFETCH;
  29997. + outer_cache.write_sec = omap4_l2c310_write_sec;
  29998. if (of_have_populated_dt())
  29999. - l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
  30000. + l2x0_of_init(aux_ctrl, 0xcf9fffff);
  30001. else
  30002. - l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK);
  30003. -
  30004. - /*
  30005. - * Override default outer_cache.disable with a OMAP4
  30006. - * specific one
  30007. - */
  30008. - outer_cache.disable = omap4_l2x0_disable;
  30009. - outer_cache.set_debug = omap4_l2x0_set_debug;
  30010. + l2x0_init(l2cache_base, aux_ctrl, 0xcf9fffff);
  30011. return 0;
  30012. }
  30013. -omap_early_initcall(omap_l2_cache_init);
  30014. #endif
  30015. void __iomem *omap4_get_sar_ram_base(void)
  30016. diff -Nur linux-3.14.14/arch/arm/mach-omap2/omap-mpuss-lowpower.c linux-imx6-3.14/arch/arm/mach-omap2/omap-mpuss-lowpower.c
  30017. --- linux-3.14.14/arch/arm/mach-omap2/omap-mpuss-lowpower.c 2014-07-28 10:07:25.000000000 -0500
  30018. +++ linux-imx6-3.14/arch/arm/mach-omap2/omap-mpuss-lowpower.c 2014-12-08 00:31:51.280418001 -0600
  30019. @@ -187,19 +187,15 @@
  30020. * in every restore MPUSS OFF path.
  30021. */
  30022. #ifdef CONFIG_CACHE_L2X0
  30023. -static void save_l2x0_context(void)
  30024. +static void __init save_l2x0_context(void)
  30025. {
  30026. - u32 val;
  30027. - void __iomem *l2x0_base = omap4_get_l2cache_base();
  30028. - if (l2x0_base) {
  30029. - val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
  30030. - __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
  30031. - val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL);
  30032. - __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
  30033. - }
  30034. + __raw_writel(l2x0_saved_regs.aux_ctrl,
  30035. + sar_base + L2X0_AUXCTRL_OFFSET);
  30036. + __raw_writel(l2x0_saved_regs.prefetch_ctrl,
  30037. + sar_base + L2X0_PREFETCH_CTRL_OFFSET);
  30038. }
  30039. #else
  30040. -static void save_l2x0_context(void)
  30041. +static void __init save_l2x0_context(void)
  30042. {}
  30043. #endif
  30044. diff -Nur linux-3.14.14/arch/arm/mach-prima2/l2x0.c linux-imx6-3.14/arch/arm/mach-prima2/l2x0.c
  30045. --- linux-3.14.14/arch/arm/mach-prima2/l2x0.c 2014-07-28 10:07:25.000000000 -0500
  30046. +++ linux-imx6-3.14/arch/arm/mach-prima2/l2x0.c 2014-12-08 00:31:51.296418001 -0600
  30047. @@ -8,43 +8,10 @@
  30048. #include <linux/init.h>
  30049. #include <linux/kernel.h>
  30050. -#include <linux/of.h>
  30051. #include <asm/hardware/cache-l2x0.h>
  30052. -struct l2x0_aux
  30053. -{
  30054. - u32 val;
  30055. - u32 mask;
  30056. -};
  30057. -
  30058. -static struct l2x0_aux prima2_l2x0_aux __initconst = {
  30059. - .val = 2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT,
  30060. - .mask = 0,
  30061. -};
  30062. -
  30063. -static struct l2x0_aux marco_l2x0_aux __initconst = {
  30064. - .val = (2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
  30065. - (1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT),
  30066. - .mask = L2X0_AUX_CTRL_MASK,
  30067. -};
  30068. -
  30069. -static struct of_device_id sirf_l2x0_ids[] __initconst = {
  30070. - { .compatible = "sirf,prima2-pl310-cache", .data = &prima2_l2x0_aux, },
  30071. - { .compatible = "sirf,marco-pl310-cache", .data = &marco_l2x0_aux, },
  30072. - {},
  30073. -};
  30074. -
  30075. static int __init sirfsoc_l2x0_init(void)
  30076. {
  30077. - struct device_node *np;
  30078. - const struct l2x0_aux *aux;
  30079. -
  30080. - np = of_find_matching_node(NULL, sirf_l2x0_ids);
  30081. - if (np) {
  30082. - aux = of_match_node(sirf_l2x0_ids, np)->data;
  30083. - return l2x0_of_init(aux->val, aux->mask);
  30084. - }
  30085. -
  30086. - return 0;
  30087. + return l2x0_of_init(0, ~0);
  30088. }
  30089. early_initcall(sirfsoc_l2x0_init);
  30090. diff -Nur linux-3.14.14/arch/arm/mach-prima2/pm.c linux-imx6-3.14/arch/arm/mach-prima2/pm.c
  30091. --- linux-3.14.14/arch/arm/mach-prima2/pm.c 2014-07-28 10:07:25.000000000 -0500
  30092. +++ linux-imx6-3.14/arch/arm/mach-prima2/pm.c 2014-12-08 00:31:51.296418001 -0600
  30093. @@ -71,7 +71,6 @@
  30094. case PM_SUSPEND_MEM:
  30095. sirfsoc_pre_suspend_power_off();
  30096. - outer_flush_all();
  30097. outer_disable();
  30098. /* go zzz */
  30099. cpu_suspend(0, sirfsoc_finish_suspend);
  30100. diff -Nur linux-3.14.14/arch/arm/mach-realview/realview_eb.c linux-imx6-3.14/arch/arm/mach-realview/realview_eb.c
  30101. --- linux-3.14.14/arch/arm/mach-realview/realview_eb.c 2014-07-28 10:07:25.000000000 -0500
  30102. +++ linux-imx6-3.14/arch/arm/mach-realview/realview_eb.c 2014-12-08 00:31:51.348418001 -0600
  30103. @@ -442,8 +442,13 @@
  30104. realview_eb11mp_fixup();
  30105. #ifdef CONFIG_CACHE_L2X0
  30106. - /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
  30107. - * Bits: .... ...0 0111 1001 0000 .... .... .... */
  30108. + /*
  30109. + * The PL220 needs to be manually configured as the hardware
  30110. + * doesn't report the correct sizes.
  30111. + * 1MB (128KB/way), 8-way associativity, event monitor and
  30112. + * parity enabled, ignore share bit, no force write allocate
  30113. + * Bits: .... ...0 0111 1001 0000 .... .... ....
  30114. + */
  30115. l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
  30116. #endif
  30117. platform_device_register(&pmu_device);
  30118. diff -Nur linux-3.14.14/arch/arm/mach-realview/realview_pb1176.c linux-imx6-3.14/arch/arm/mach-realview/realview_pb1176.c
  30119. --- linux-3.14.14/arch/arm/mach-realview/realview_pb1176.c 2014-07-28 10:07:25.000000000 -0500
  30120. +++ linux-imx6-3.14/arch/arm/mach-realview/realview_pb1176.c 2014-12-08 00:31:51.348418001 -0600
  30121. @@ -355,7 +355,13 @@
  30122. int i;
  30123. #ifdef CONFIG_CACHE_L2X0
  30124. - /* 128Kb (16Kb/way) 8-way associativity. evmon/parity/share enabled. */
  30125. + /*
  30126. + * The PL220 needs to be manually configured as the hardware
  30127. + * doesn't report the correct sizes.
  30128. + * 128kB (16kB/way), 8-way associativity, event monitor and
  30129. + * parity enabled, ignore share bit, no force write allocate
  30130. + * Bits: .... ...0 0111 0011 0000 .... .... ....
  30131. + */
  30132. l2x0_init(__io_address(REALVIEW_PB1176_L220_BASE), 0x00730000, 0xfe000fff);
  30133. #endif
  30134. diff -Nur linux-3.14.14/arch/arm/mach-realview/realview_pb11mp.c linux-imx6-3.14/arch/arm/mach-realview/realview_pb11mp.c
  30135. --- linux-3.14.14/arch/arm/mach-realview/realview_pb11mp.c 2014-07-28 10:07:25.000000000 -0500
  30136. +++ linux-imx6-3.14/arch/arm/mach-realview/realview_pb11mp.c 2014-12-08 00:31:51.348418001 -0600
  30137. @@ -337,8 +337,13 @@
  30138. int i;
  30139. #ifdef CONFIG_CACHE_L2X0
  30140. - /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
  30141. - * Bits: .... ...0 0111 1001 0000 .... .... .... */
  30142. + /*
  30143. + * The PL220 needs to be manually configured as the hardware
  30144. + * doesn't report the correct sizes.
  30145. + * 1MB (128KB/way), 8-way associativity, event monitor and
  30146. + * parity enabled, ignore share bit, no force write allocate
  30147. + * Bits: .... ...0 0111 1001 0000 .... .... ....
  30148. + */
  30149. l2x0_init(__io_address(REALVIEW_TC11MP_L220_BASE), 0x00790000, 0xfe000fff);
  30150. #endif
  30151. diff -Nur linux-3.14.14/arch/arm/mach-realview/realview_pbx.c linux-imx6-3.14/arch/arm/mach-realview/realview_pbx.c
  30152. --- linux-3.14.14/arch/arm/mach-realview/realview_pbx.c 2014-07-28 10:07:25.000000000 -0500
  30153. +++ linux-imx6-3.14/arch/arm/mach-realview/realview_pbx.c 2014-12-08 00:31:51.348418001 -0600
  30154. @@ -370,8 +370,8 @@
  30155. __io_address(REALVIEW_PBX_TILE_L220_BASE);
  30156. /* set RAM latencies to 1 cycle for eASIC */
  30157. - writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
  30158. - writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
  30159. + writel(0, l2x0_base + L310_TAG_LATENCY_CTRL);
  30160. + writel(0, l2x0_base + L310_DATA_LATENCY_CTRL);
  30161. /* 16KB way size, 8-way associativity, parity disabled
  30162. * Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... */
  30163. diff -Nur linux-3.14.14/arch/arm/mach-rockchip/rockchip.c linux-imx6-3.14/arch/arm/mach-rockchip/rockchip.c
  30164. --- linux-3.14.14/arch/arm/mach-rockchip/rockchip.c 2014-07-28 10:07:25.000000000 -0500
  30165. +++ linux-imx6-3.14/arch/arm/mach-rockchip/rockchip.c 2014-12-08 00:31:51.348418001 -0600
  30166. @@ -25,7 +25,7 @@
  30167. static void __init rockchip_dt_init(void)
  30168. {
  30169. - l2x0_of_init(0, ~0UL);
  30170. + l2x0_of_init(0, ~0);
  30171. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  30172. }
  30173. diff -Nur linux-3.14.14/arch/arm/mach-shmobile/board-armadillo800eva.c linux-imx6-3.14/arch/arm/mach-shmobile/board-armadillo800eva.c
  30174. --- linux-3.14.14/arch/arm/mach-shmobile/board-armadillo800eva.c 2014-07-28 10:07:25.000000000 -0500
  30175. +++ linux-imx6-3.14/arch/arm/mach-shmobile/board-armadillo800eva.c 2014-12-08 00:31:51.372418001 -0600
  30176. @@ -1270,8 +1270,8 @@
  30177. #ifdef CONFIG_CACHE_L2X0
  30178. - /* Early BRESP enable, Shared attribute override enable, 32K*8way */
  30179. - l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
  30180. + /* Shared attribute override enable, 32K*8way */
  30181. + l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
  30182. #endif
  30183. i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
  30184. diff -Nur linux-3.14.14/arch/arm/mach-shmobile/board-armadillo800eva-reference.c linux-imx6-3.14/arch/arm/mach-shmobile/board-armadillo800eva-reference.c
  30185. --- linux-3.14.14/arch/arm/mach-shmobile/board-armadillo800eva-reference.c 2014-07-28 10:07:25.000000000 -0500
  30186. +++ linux-imx6-3.14/arch/arm/mach-shmobile/board-armadillo800eva-reference.c 2014-12-08 00:31:51.372418001 -0600
  30187. @@ -164,8 +164,8 @@
  30188. r8a7740_meram_workaround();
  30189. #ifdef CONFIG_CACHE_L2X0
  30190. - /* Early BRESP enable, Shared attribute override enable, 32K*8way */
  30191. - l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
  30192. + /* Shared attribute override enable, 32K*8way */
  30193. + l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
  30194. #endif
  30195. r8a7740_add_standard_devices_dt();
  30196. diff -Nur linux-3.14.14/arch/arm/mach-shmobile/board-kzm9g.c linux-imx6-3.14/arch/arm/mach-shmobile/board-kzm9g.c
  30197. --- linux-3.14.14/arch/arm/mach-shmobile/board-kzm9g.c 2014-07-28 10:07:25.000000000 -0500
  30198. +++ linux-imx6-3.14/arch/arm/mach-shmobile/board-kzm9g.c 2014-12-08 00:31:51.372418001 -0600
  30199. @@ -878,8 +878,8 @@
  30200. gpio_request_one(223, GPIOF_IN, NULL); /* IRQ8 */
  30201. #ifdef CONFIG_CACHE_L2X0
  30202. - /* Early BRESP enable, Shared attribute override enable, 64K*8way */
  30203. - l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);
  30204. + /* Shared attribute override enable, 64K*8way */
  30205. + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
  30206. #endif
  30207. i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
  30208. diff -Nur linux-3.14.14/arch/arm/mach-shmobile/board-kzm9g-reference.c linux-imx6-3.14/arch/arm/mach-shmobile/board-kzm9g-reference.c
  30209. --- linux-3.14.14/arch/arm/mach-shmobile/board-kzm9g-reference.c 2014-07-28 10:07:25.000000000 -0500
  30210. +++ linux-imx6-3.14/arch/arm/mach-shmobile/board-kzm9g-reference.c 2014-12-08 00:31:51.372418001 -0600
  30211. @@ -36,8 +36,8 @@
  30212. sh73a0_add_standard_devices_dt();
  30213. #ifdef CONFIG_CACHE_L2X0
  30214. - /* Early BRESP enable, Shared attribute override enable, 64K*8way */
  30215. - l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);
  30216. + /* Shared attribute override enable, 64K*8way */
  30217. + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
  30218. #endif
  30219. }
  30220. diff -Nur linux-3.14.14/arch/arm/mach-shmobile/setup-r8a7778.c linux-imx6-3.14/arch/arm/mach-shmobile/setup-r8a7778.c
  30221. --- linux-3.14.14/arch/arm/mach-shmobile/setup-r8a7778.c 2014-07-28 10:07:25.000000000 -0500
  30222. +++ linux-imx6-3.14/arch/arm/mach-shmobile/setup-r8a7778.c 2014-12-08 00:31:51.376418001 -0600
  30223. @@ -298,10 +298,10 @@
  30224. void __iomem *base = ioremap_nocache(0xf0100000, 0x1000);
  30225. if (base) {
  30226. /*
  30227. - * Early BRESP enable, Shared attribute override enable, 64K*16way
  30228. + * Shared attribute override enable, 64K*16way
  30229. * don't call iounmap(base)
  30230. */
  30231. - l2x0_init(base, 0x40470000, 0x82000fff);
  30232. + l2x0_init(base, 0x00400000, 0xc20f0fff);
  30233. }
  30234. #endif
  30235. diff -Nur linux-3.14.14/arch/arm/mach-shmobile/setup-r8a7779.c linux-imx6-3.14/arch/arm/mach-shmobile/setup-r8a7779.c
  30236. --- linux-3.14.14/arch/arm/mach-shmobile/setup-r8a7779.c 2014-07-28 10:07:25.000000000 -0500
  30237. +++ linux-imx6-3.14/arch/arm/mach-shmobile/setup-r8a7779.c 2014-12-08 00:31:51.376418001 -0600
  30238. @@ -700,8 +700,8 @@
  30239. void __init r8a7779_add_standard_devices(void)
  30240. {
  30241. #ifdef CONFIG_CACHE_L2X0
  30242. - /* Early BRESP enable, Shared attribute override enable, 64K*16way */
  30243. - l2x0_init(IOMEM(0xf0100000), 0x40470000, 0x82000fff);
  30244. + /* Shared attribute override enable, 64K*16way */
  30245. + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
  30246. #endif
  30247. r8a7779_pm_init();
  30248. diff -Nur linux-3.14.14/arch/arm/mach-socfpga/socfpga.c linux-imx6-3.14/arch/arm/mach-socfpga/socfpga.c
  30249. --- linux-3.14.14/arch/arm/mach-socfpga/socfpga.c 2014-07-28 10:07:25.000000000 -0500
  30250. +++ linux-imx6-3.14/arch/arm/mach-socfpga/socfpga.c 2014-12-08 00:31:51.376418001 -0600
  30251. @@ -104,7 +104,7 @@
  30252. static void __init socfpga_cyclone5_init(void)
  30253. {
  30254. - l2x0_of_init(0, ~0UL);
  30255. + l2x0_of_init(0, ~0);
  30256. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  30257. socfpga_init_clocks();
  30258. }
  30259. diff -Nur linux-3.14.14/arch/arm/mach-spear/platsmp.c linux-imx6-3.14/arch/arm/mach-spear/platsmp.c
  30260. --- linux-3.14.14/arch/arm/mach-spear/platsmp.c 2014-07-28 10:07:25.000000000 -0500
  30261. +++ linux-imx6-3.14/arch/arm/mach-spear/platsmp.c 2014-12-08 00:31:51.376418001 -0600
  30262. @@ -20,6 +20,18 @@
  30263. #include <mach/spear.h>
  30264. #include "generic.h"
  30265. +/*
  30266. + * Write pen_release in a way that is guaranteed to be visible to all
  30267. + * observers, irrespective of whether they're taking part in coherency
  30268. + * or not. This is necessary for the hotplug code to work reliably.
  30269. + */
  30270. +static void write_pen_release(int val)
  30271. +{
  30272. + pen_release = val;
  30273. + smp_wmb();
  30274. + sync_cache_w(&pen_release);
  30275. +}
  30276. +
  30277. static DEFINE_SPINLOCK(boot_lock);
  30278. static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
  30279. @@ -30,8 +42,7 @@
  30280. * let the primary processor know we're out of the
  30281. * pen, then head off into the C entry point
  30282. */
  30283. - pen_release = -1;
  30284. - smp_wmb();
  30285. + write_pen_release(-1);
  30286. /*
  30287. * Synchronise with the boot thread.
  30288. @@ -58,9 +69,7 @@
  30289. * Note that "pen_release" is the hardware CPU ID, whereas
  30290. * "cpu" is Linux's internal ID.
  30291. */
  30292. - pen_release = cpu;
  30293. - flush_cache_all();
  30294. - outer_flush_all();
  30295. + write_pen_release(cpu);
  30296. timeout = jiffies + (1 * HZ);
  30297. while (time_before(jiffies, timeout)) {
  30298. diff -Nur linux-3.14.14/arch/arm/mach-spear/spear13xx.c linux-imx6-3.14/arch/arm/mach-spear/spear13xx.c
  30299. --- linux-3.14.14/arch/arm/mach-spear/spear13xx.c 2014-07-28 10:07:25.000000000 -0500
  30300. +++ linux-imx6-3.14/arch/arm/mach-spear/spear13xx.c 2014-12-08 00:31:51.380418001 -0600
  30301. @@ -38,15 +38,15 @@
  30302. if (!IS_ENABLED(CONFIG_CACHE_L2X0))
  30303. return;
  30304. - writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL);
  30305. + writel_relaxed(0x06, VA_L2CC_BASE + L310_PREFETCH_CTRL);
  30306. /*
  30307. * Program following latencies in order to make
  30308. * SPEAr1340 work at 600 MHz
  30309. */
  30310. - writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL);
  30311. - writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL);
  30312. - l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff);
  30313. + writel_relaxed(0x221, VA_L2CC_BASE + L310_TAG_LATENCY_CTRL);
  30314. + writel_relaxed(0x441, VA_L2CC_BASE + L310_DATA_LATENCY_CTRL);
  30315. + l2x0_init(VA_L2CC_BASE, 0x30a00001, 0xfe0fffff);
  30316. }
  30317. /*
  30318. diff -Nur linux-3.14.14/arch/arm/mach-sti/board-dt.c linux-imx6-3.14/arch/arm/mach-sti/board-dt.c
  30319. --- linux-3.14.14/arch/arm/mach-sti/board-dt.c 2014-07-28 10:07:25.000000000 -0500
  30320. +++ linux-imx6-3.14/arch/arm/mach-sti/board-dt.c 2014-12-08 00:31:51.380418001 -0600
  30321. @@ -16,15 +16,9 @@
  30322. void __init stih41x_l2x0_init(void)
  30323. {
  30324. - u32 way_size = 0x4;
  30325. - u32 aux_ctrl;
  30326. - /* may be this can be encoded in macros like BIT*() */
  30327. - aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
  30328. - (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
  30329. - (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
  30330. - (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
  30331. -
  30332. - l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
  30333. + l2x0_of_init(L2C_AUX_CTRL_SHARED_OVERRIDE |
  30334. + L310_AUX_CTRL_DATA_PREFETCH |
  30335. + L310_AUX_CTRL_INSTR_PREFETCH, 0xc00f0fff);
  30336. }
  30337. static void __init stih41x_machine_init(void)
  30338. diff -Nur linux-3.14.14/arch/arm/mach-tegra/pm.h linux-imx6-3.14/arch/arm/mach-tegra/pm.h
  30339. --- linux-3.14.14/arch/arm/mach-tegra/pm.h 2014-07-28 10:07:25.000000000 -0500
  30340. +++ linux-imx6-3.14/arch/arm/mach-tegra/pm.h 2014-12-08 00:31:51.380418001 -0600
  30341. @@ -35,8 +35,6 @@
  30342. void tegra30_lp1_iram_hook(void);
  30343. void tegra30_sleep_core_init(void);
  30344. -extern unsigned long l2x0_saved_regs_addr;
  30345. -
  30346. void tegra_clear_cpu_in_lp2(void);
  30347. bool tegra_set_cpu_in_lp2(void);
  30348. diff -Nur linux-3.14.14/arch/arm/mach-tegra/reset-handler.S linux-imx6-3.14/arch/arm/mach-tegra/reset-handler.S
  30349. --- linux-3.14.14/arch/arm/mach-tegra/reset-handler.S 2014-07-28 10:07:25.000000000 -0500
  30350. +++ linux-imx6-3.14/arch/arm/mach-tegra/reset-handler.S 2014-12-08 00:31:51.380418001 -0600
  30351. @@ -19,7 +19,6 @@
  30352. #include <asm/cache.h>
  30353. #include <asm/asm-offsets.h>
  30354. -#include <asm/hardware/cache-l2x0.h>
  30355. #include "flowctrl.h"
  30356. #include "fuse.h"
  30357. @@ -78,8 +77,10 @@
  30358. str r1, [r0]
  30359. #endif
  30360. +#ifdef CONFIG_CACHE_L2X0
  30361. /* L2 cache resume & re-enable */
  30362. - l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr
  30363. + bl l2c310_early_resume
  30364. +#endif
  30365. end_ca9_scu_l2_resume:
  30366. mov32 r9, 0xc0f
  30367. cmp r8, r9
  30368. @@ -89,12 +90,6 @@
  30369. ENDPROC(tegra_resume)
  30370. #endif
  30371. -#ifdef CONFIG_CACHE_L2X0
  30372. - .globl l2x0_saved_regs_addr
  30373. -l2x0_saved_regs_addr:
  30374. - .long 0
  30375. -#endif
  30376. -
  30377. .align L1_CACHE_SHIFT
  30378. ENTRY(__tegra_cpu_reset_handler_start)
  30379. diff -Nur linux-3.14.14/arch/arm/mach-tegra/sleep.h linux-imx6-3.14/arch/arm/mach-tegra/sleep.h
  30380. --- linux-3.14.14/arch/arm/mach-tegra/sleep.h 2014-07-28 10:07:25.000000000 -0500
  30381. +++ linux-imx6-3.14/arch/arm/mach-tegra/sleep.h 2014-12-08 00:31:51.380418001 -0600
  30382. @@ -120,37 +120,6 @@
  30383. mov \tmp1, \tmp1, lsr #8
  30384. .endm
  30385. -/* Macro to resume & re-enable L2 cache */
  30386. -#ifndef L2X0_CTRL_EN
  30387. -#define L2X0_CTRL_EN 1
  30388. -#endif
  30389. -
  30390. -#ifdef CONFIG_CACHE_L2X0
  30391. -.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
  30392. - W(adr) \tmp1, \phys_l2x0_saved_regs
  30393. - ldr \tmp1, [\tmp1]
  30394. - ldr \tmp2, [\tmp1, #L2X0_R_PHY_BASE]
  30395. - ldr \tmp3, [\tmp2, #L2X0_CTRL]
  30396. - tst \tmp3, #L2X0_CTRL_EN
  30397. - bne exit_l2_resume
  30398. - ldr \tmp3, [\tmp1, #L2X0_R_TAG_LATENCY]
  30399. - str \tmp3, [\tmp2, #L2X0_TAG_LATENCY_CTRL]
  30400. - ldr \tmp3, [\tmp1, #L2X0_R_DATA_LATENCY]
  30401. - str \tmp3, [\tmp2, #L2X0_DATA_LATENCY_CTRL]
  30402. - ldr \tmp3, [\tmp1, #L2X0_R_PREFETCH_CTRL]
  30403. - str \tmp3, [\tmp2, #L2X0_PREFETCH_CTRL]
  30404. - ldr \tmp3, [\tmp1, #L2X0_R_PWR_CTRL]
  30405. - str \tmp3, [\tmp2, #L2X0_POWER_CTRL]
  30406. - ldr \tmp3, [\tmp1, #L2X0_R_AUX_CTRL]
  30407. - str \tmp3, [\tmp2, #L2X0_AUX_CTRL]
  30408. - mov \tmp3, #L2X0_CTRL_EN
  30409. - str \tmp3, [\tmp2, #L2X0_CTRL]
  30410. -exit_l2_resume:
  30411. -.endm
  30412. -#else /* CONFIG_CACHE_L2X0 */
  30413. -.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
  30414. -.endm
  30415. -#endif /* CONFIG_CACHE_L2X0 */
  30416. #else
  30417. void tegra_pen_lock(void);
  30418. void tegra_pen_unlock(void);
  30419. diff -Nur linux-3.14.14/arch/arm/mach-tegra/tegra.c linux-imx6-3.14/arch/arm/mach-tegra/tegra.c
  30420. --- linux-3.14.14/arch/arm/mach-tegra/tegra.c 2014-07-28 10:07:25.000000000 -0500
  30421. +++ linux-imx6-3.14/arch/arm/mach-tegra/tegra.c 2014-12-08 00:31:51.380418001 -0600
  30422. @@ -73,27 +73,7 @@
  30423. static void __init tegra_init_cache(void)
  30424. {
  30425. #ifdef CONFIG_CACHE_L2X0
  30426. - static const struct of_device_id pl310_ids[] __initconst = {
  30427. - { .compatible = "arm,pl310-cache", },
  30428. - {}
  30429. - };
  30430. -
  30431. - struct device_node *np;
  30432. - int ret;
  30433. - void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
  30434. - u32 aux_ctrl, cache_type;
  30435. -
  30436. - np = of_find_matching_node(NULL, pl310_ids);
  30437. - if (!np)
  30438. - return;
  30439. -
  30440. - cache_type = readl(p + L2X0_CACHE_TYPE);
  30441. - aux_ctrl = (cache_type & 0x700) << (17-8);
  30442. - aux_ctrl |= 0x7C400001;
  30443. -
  30444. - ret = l2x0_of_init(aux_ctrl, 0x8200c3fe);
  30445. - if (!ret)
  30446. - l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs);
  30447. + l2x0_of_init(0x3c400001, 0xc20fc3fe);
  30448. #endif
  30449. }
  30450. diff -Nur linux-3.14.14/arch/arm/mach-ux500/board-mop500-audio.c linux-imx6-3.14/arch/arm/mach-ux500/board-mop500-audio.c
  30451. --- linux-3.14.14/arch/arm/mach-ux500/board-mop500-audio.c 2014-07-28 10:07:25.000000000 -0500
  30452. +++ linux-imx6-3.14/arch/arm/mach-ux500/board-mop500-audio.c 2014-12-08 00:31:51.384418001 -0600
  30453. @@ -9,7 +9,6 @@
  30454. #include <linux/gpio.h>
  30455. #include <linux/platform_data/dma-ste-dma40.h>
  30456. -#include "irqs.h"
  30457. #include <linux/platform_data/asoc-ux500-msp.h>
  30458. #include "ste-dma40-db8500.h"
  30459. diff -Nur linux-3.14.14/arch/arm/mach-ux500/cache-l2x0.c linux-imx6-3.14/arch/arm/mach-ux500/cache-l2x0.c
  30460. --- linux-3.14.14/arch/arm/mach-ux500/cache-l2x0.c 2014-07-28 10:07:25.000000000 -0500
  30461. +++ linux-imx6-3.14/arch/arm/mach-ux500/cache-l2x0.c 2014-12-08 00:31:51.384418001 -0600
  30462. @@ -35,10 +35,16 @@
  30463. return 0;
  30464. }
  30465. -static int __init ux500_l2x0_init(void)
  30466. +static void ux500_l2c310_write_sec(unsigned long val, unsigned reg)
  30467. {
  30468. - u32 aux_val = 0x3e000000;
  30469. + /*
  30470. + * We can't write to secure registers as we are in non-secure
  30471. + * mode, until we have some SMI service available.
  30472. + */
  30473. +}
  30474. +static int __init ux500_l2x0_init(void)
  30475. +{
  30476. if (cpu_is_u8500_family() || cpu_is_ux540_family())
  30477. l2x0_base = __io_address(U8500_L2CC_BASE);
  30478. else
  30479. @@ -48,28 +54,12 @@
  30480. /* Unlock before init */
  30481. ux500_l2x0_unlock();
  30482. - /* DBx540's L2 has 128KB way size */
  30483. - if (cpu_is_ux540_family())
  30484. - /* 128KB way size */
  30485. - aux_val |= (0x4 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
  30486. - else
  30487. - /* 64KB way size */
  30488. - aux_val |= (0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
  30489. + outer_cache.write_sec = ux500_l2c310_write_sec;
  30490. - /* 64KB way size, 8 way associativity, force WA */
  30491. if (of_have_populated_dt())
  30492. - l2x0_of_init(aux_val, 0xc0000fff);
  30493. + l2x0_of_init(0, ~0);
  30494. else
  30495. - l2x0_init(l2x0_base, aux_val, 0xc0000fff);
  30496. -
  30497. - /*
  30498. - * We can't disable l2 as we are in non secure mode, currently
  30499. - * this seems be called only during kexec path. So let's
  30500. - * override outer.disable with nasty assignment until we have
  30501. - * some SMI service available.
  30502. - */
  30503. - outer_cache.disable = NULL;
  30504. - outer_cache.set_debug = NULL;
  30505. + l2x0_init(l2x0_base, 0, ~0);
  30506. return 0;
  30507. }
  30508. diff -Nur linux-3.14.14/arch/arm/mach-ux500/cpu-db8500.c linux-imx6-3.14/arch/arm/mach-ux500/cpu-db8500.c
  30509. --- linux-3.14.14/arch/arm/mach-ux500/cpu-db8500.c 2014-07-28 10:07:25.000000000 -0500
  30510. +++ linux-imx6-3.14/arch/arm/mach-ux500/cpu-db8500.c 2014-12-08 00:31:51.384418001 -0600
  30511. @@ -27,7 +27,6 @@
  30512. #include <asm/mach/map.h>
  30513. #include "setup.h"
  30514. -#include "irqs.h"
  30515. #include "board-mop500-regulators.h"
  30516. #include "board-mop500.h"
  30517. @@ -35,14 +34,11 @@
  30518. #include "id.h"
  30519. struct ab8500_platform_data ab8500_platdata = {
  30520. - .irq_base = MOP500_AB8500_IRQ_BASE,
  30521. .regulator = &ab8500_regulator_plat_data,
  30522. };
  30523. struct prcmu_pdata db8500_prcmu_pdata = {
  30524. .ab_platdata = &ab8500_platdata,
  30525. - .ab_irq = IRQ_DB8500_AB8500,
  30526. - .irq_base = IRQ_PRCMU_BASE,
  30527. .version_offset = DB8500_PRCMU_FW_VERSION_OFFSET,
  30528. .legacy_offset = DB8500_PRCMU_LEGACY_OFFSET,
  30529. };
  30530. diff -Nur linux-3.14.14/arch/arm/mach-ux500/irqs-board-mop500.h linux-imx6-3.14/arch/arm/mach-ux500/irqs-board-mop500.h
  30531. --- linux-3.14.14/arch/arm/mach-ux500/irqs-board-mop500.h 2014-07-28 10:07:25.000000000 -0500
  30532. +++ linux-imx6-3.14/arch/arm/mach-ux500/irqs-board-mop500.h 1969-12-31 18:00:00.000000000 -0600
  30533. @@ -1,55 +0,0 @@
  30534. -/*
  30535. - * Copyright (C) ST-Ericsson SA 2010
  30536. - *
  30537. - * Author: Rabin Vincent <rabin.vincent@stericsson.com>
  30538. - * License terms: GNU General Public License (GPL) version 2
  30539. - */
  30540. -
  30541. -#ifndef __MACH_IRQS_BOARD_MOP500_H
  30542. -#define __MACH_IRQS_BOARD_MOP500_H
  30543. -
  30544. -/* Number of AB8500 irqs is taken from header file */
  30545. -#include <linux/mfd/abx500/ab8500.h>
  30546. -
  30547. -#define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START
  30548. -#define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \
  30549. - + AB8500_MAX_NR_IRQS)
  30550. -
  30551. -/* TC35892 */
  30552. -#define TC35892_NR_INTERNAL_IRQS 8
  30553. -#define TC35892_INT_GPIO(x) (TC35892_NR_INTERNAL_IRQS + (x))
  30554. -#define TC35892_NR_GPIOS 24
  30555. -#define TC35892_NR_IRQS TC35892_INT_GPIO(TC35892_NR_GPIOS)
  30556. -
  30557. -#define MOP500_EGPIO_NR_IRQS TC35892_NR_IRQS
  30558. -
  30559. -#define MOP500_EGPIO_IRQ_BASE MOP500_AB8500_IRQ_END
  30560. -#define MOP500_EGPIO_IRQ_END (MOP500_EGPIO_IRQ_BASE \
  30561. - + MOP500_EGPIO_NR_IRQS)
  30562. -/* STMPE1601 irqs */
  30563. -#define STMPE_NR_INTERNAL_IRQS 9
  30564. -#define STMPE_INT_GPIO(x) (STMPE_NR_INTERNAL_IRQS + (x))
  30565. -#define STMPE_NR_GPIOS 24
  30566. -#define STMPE_NR_IRQS STMPE_INT_GPIO(STMPE_NR_GPIOS)
  30567. -
  30568. -#define MOP500_STMPE1601_IRQBASE MOP500_EGPIO_IRQ_END
  30569. -#define MOP500_STMPE1601_IRQ(x) (MOP500_STMPE1601_IRQBASE + (x))
  30570. -
  30571. -#define MOP500_STMPE1601_IRQ_END \
  30572. - MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS)
  30573. -
  30574. -#define MOP500_NR_IRQS MOP500_STMPE1601_IRQ_END
  30575. -
  30576. -#define MOP500_IRQ_END MOP500_NR_IRQS
  30577. -
  30578. -/*
  30579. - * We may have several boards, but only one will run at a
  30580. - * time, so the one with most IRQs will bump this ahead,
  30581. - * but the IRQ_BOARD_START remains the same for either board.
  30582. - */
  30583. -#if MOP500_IRQ_END > IRQ_BOARD_END
  30584. -#undef IRQ_BOARD_END
  30585. -#define IRQ_BOARD_END MOP500_IRQ_END
  30586. -#endif
  30587. -
  30588. -#endif
  30589. diff -Nur linux-3.14.14/arch/arm/mach-ux500/irqs-db8500.h linux-imx6-3.14/arch/arm/mach-ux500/irqs-db8500.h
  30590. --- linux-3.14.14/arch/arm/mach-ux500/irqs-db8500.h 2014-07-28 10:07:25.000000000 -0500
  30591. +++ linux-imx6-3.14/arch/arm/mach-ux500/irqs-db8500.h 1969-12-31 18:00:00.000000000 -0600
  30592. @@ -1,125 +0,0 @@
  30593. -/*
  30594. - * Copyright (C) ST-Ericsson SA 2010
  30595. - *
  30596. - * Author: Rabin Vincent <rabin.vincent@stericsson.com>
  30597. - * License terms: GNU General Public License (GPL) version 2
  30598. - */
  30599. -
  30600. -#ifndef __MACH_IRQS_DB8500_H
  30601. -#define __MACH_IRQS_DB8500_H
  30602. -
  30603. -#define IRQ_DB8500_MTU0 (IRQ_SHPI_START + 4)
  30604. -#define IRQ_DB8500_SPI2 (IRQ_SHPI_START + 6)
  30605. -#define IRQ_DB8500_PMU (IRQ_SHPI_START + 7)
  30606. -#define IRQ_DB8500_SPI0 (IRQ_SHPI_START + 8)
  30607. -#define IRQ_DB8500_RTT (IRQ_SHPI_START + 9)
  30608. -#define IRQ_DB8500_PKA (IRQ_SHPI_START + 10)
  30609. -#define IRQ_DB8500_UART0 (IRQ_SHPI_START + 11)
  30610. -#define IRQ_DB8500_I2C3 (IRQ_SHPI_START + 12)
  30611. -#define IRQ_DB8500_L2CC (IRQ_SHPI_START + 13)
  30612. -#define IRQ_DB8500_SSP0 (IRQ_SHPI_START + 14)
  30613. -#define IRQ_DB8500_CRYP1 (IRQ_SHPI_START + 15)
  30614. -#define IRQ_DB8500_MSP1_RX (IRQ_SHPI_START + 16)
  30615. -#define IRQ_DB8500_MTU1 (IRQ_SHPI_START + 17)
  30616. -#define IRQ_DB8500_RTC (IRQ_SHPI_START + 18)
  30617. -#define IRQ_DB8500_UART1 (IRQ_SHPI_START + 19)
  30618. -#define IRQ_DB8500_USB_WAKEUP (IRQ_SHPI_START + 20)
  30619. -#define IRQ_DB8500_I2C0 (IRQ_SHPI_START + 21)
  30620. -#define IRQ_DB8500_I2C1 (IRQ_SHPI_START + 22)
  30621. -#define IRQ_DB8500_USBOTG (IRQ_SHPI_START + 23)
  30622. -#define IRQ_DB8500_DMA_SECURE (IRQ_SHPI_START + 24)
  30623. -#define IRQ_DB8500_DMA (IRQ_SHPI_START + 25)
  30624. -#define IRQ_DB8500_UART2 (IRQ_SHPI_START + 26)
  30625. -#define IRQ_DB8500_ICN_PMU1 (IRQ_SHPI_START + 27)
  30626. -#define IRQ_DB8500_ICN_PMU2 (IRQ_SHPI_START + 28)
  30627. -#define IRQ_DB8500_HSIR_EXCEP (IRQ_SHPI_START + 29)
  30628. -#define IRQ_DB8500_MSP0 (IRQ_SHPI_START + 31)
  30629. -#define IRQ_DB8500_HSIR_CH0_OVRRUN (IRQ_SHPI_START + 32)
  30630. -#define IRQ_DB8500_HSIR_CH1_OVRRUN (IRQ_SHPI_START + 33)
  30631. -#define IRQ_DB8500_HSIR_CH2_OVRRUN (IRQ_SHPI_START + 34)
  30632. -#define IRQ_DB8500_HSIR_CH3_OVRRUN (IRQ_SHPI_START + 35)
  30633. -#define IRQ_DB8500_HSIR_CH4_OVRRUN (IRQ_SHPI_START + 36)
  30634. -#define IRQ_DB8500_HSIR_CH5_OVRRUN (IRQ_SHPI_START + 37)
  30635. -#define IRQ_DB8500_HSIR_CH6_OVRRUN (IRQ_SHPI_START + 38)
  30636. -#define IRQ_DB8500_HSIR_CH7_OVRRUN (IRQ_SHPI_START + 39)
  30637. -#define IRQ_DB8500_AB8500 (IRQ_SHPI_START + 40)
  30638. -#define IRQ_DB8500_SDMMC2 (IRQ_SHPI_START + 41)
  30639. -#define IRQ_DB8500_SIA (IRQ_SHPI_START + 42)
  30640. -#define IRQ_DB8500_SIA2 (IRQ_SHPI_START + 43)
  30641. -#define IRQ_DB8500_SVA (IRQ_SHPI_START + 44)
  30642. -#define IRQ_DB8500_SVA2 (IRQ_SHPI_START + 45)
  30643. -#define IRQ_DB8500_PRCMU0 (IRQ_SHPI_START + 46)
  30644. -#define IRQ_DB8500_PRCMU1 (IRQ_SHPI_START + 47)
  30645. -#define IRQ_DB8500_DISP (IRQ_SHPI_START + 48)
  30646. -#define IRQ_DB8500_SPI3 (IRQ_SHPI_START + 49)
  30647. -#define IRQ_DB8500_SDMMC1 (IRQ_SHPI_START + 50)
  30648. -#define IRQ_DB8500_I2C4 (IRQ_SHPI_START + 51)
  30649. -#define IRQ_DB8500_SSP1 (IRQ_SHPI_START + 52)
  30650. -#define IRQ_DB8500_SKE (IRQ_SHPI_START + 53)
  30651. -#define IRQ_DB8500_KB (IRQ_SHPI_START + 54)
  30652. -#define IRQ_DB8500_I2C2 (IRQ_SHPI_START + 55)
  30653. -#define IRQ_DB8500_B2R2 (IRQ_SHPI_START + 56)
  30654. -#define IRQ_DB8500_CRYP0 (IRQ_SHPI_START + 57)
  30655. -#define IRQ_DB8500_SDMMC3 (IRQ_SHPI_START + 59)
  30656. -#define IRQ_DB8500_SDMMC0 (IRQ_SHPI_START + 60)
  30657. -#define IRQ_DB8500_HSEM (IRQ_SHPI_START + 61)
  30658. -#define IRQ_DB8500_MSP1 (IRQ_SHPI_START + 62)
  30659. -#define IRQ_DB8500_SBAG (IRQ_SHPI_START + 63)
  30660. -#define IRQ_DB8500_SPI1 (IRQ_SHPI_START + 96)
  30661. -#define IRQ_DB8500_SRPTIMER (IRQ_SHPI_START + 97)
  30662. -#define IRQ_DB8500_MSP2 (IRQ_SHPI_START + 98)
  30663. -#define IRQ_DB8500_SDMMC4 (IRQ_SHPI_START + 99)
  30664. -#define IRQ_DB8500_SDMMC5 (IRQ_SHPI_START + 100)
  30665. -#define IRQ_DB8500_HSIRD0 (IRQ_SHPI_START + 104)
  30666. -#define IRQ_DB8500_HSIRD1 (IRQ_SHPI_START + 105)
  30667. -#define IRQ_DB8500_HSITD0 (IRQ_SHPI_START + 106)
  30668. -#define IRQ_DB8500_HSITD1 (IRQ_SHPI_START + 107)
  30669. -#define IRQ_DB8500_CTI0 (IRQ_SHPI_START + 108)
  30670. -#define IRQ_DB8500_CTI1 (IRQ_SHPI_START + 109)
  30671. -#define IRQ_DB8500_ICN_ERR (IRQ_SHPI_START + 110)
  30672. -#define IRQ_DB8500_MALI_PPMMU (IRQ_SHPI_START + 112)
  30673. -#define IRQ_DB8500_MALI_PP (IRQ_SHPI_START + 113)
  30674. -#define IRQ_DB8500_MALI_GPMMU (IRQ_SHPI_START + 114)
  30675. -#define IRQ_DB8500_MALI_GP (IRQ_SHPI_START + 115)
  30676. -#define IRQ_DB8500_MALI (IRQ_SHPI_START + 116)
  30677. -#define IRQ_DB8500_PRCMU_SEM (IRQ_SHPI_START + 118)
  30678. -#define IRQ_DB8500_GPIO0 (IRQ_SHPI_START + 119)
  30679. -#define IRQ_DB8500_GPIO1 (IRQ_SHPI_START + 120)
  30680. -#define IRQ_DB8500_GPIO2 (IRQ_SHPI_START + 121)
  30681. -#define IRQ_DB8500_GPIO3 (IRQ_SHPI_START + 122)
  30682. -#define IRQ_DB8500_GPIO4 (IRQ_SHPI_START + 123)
  30683. -#define IRQ_DB8500_GPIO5 (IRQ_SHPI_START + 124)
  30684. -#define IRQ_DB8500_GPIO6 (IRQ_SHPI_START + 125)
  30685. -#define IRQ_DB8500_GPIO7 (IRQ_SHPI_START + 126)
  30686. -#define IRQ_DB8500_GPIO8 (IRQ_SHPI_START + 127)
  30687. -
  30688. -#define IRQ_CA_WAKE_REQ_ED (IRQ_SHPI_START + 71)
  30689. -#define IRQ_AC_READ_NOTIFICATION_0_ED (IRQ_SHPI_START + 66)
  30690. -#define IRQ_AC_READ_NOTIFICATION_1_ED (IRQ_SHPI_START + 64)
  30691. -#define IRQ_CA_MSG_PEND_NOTIFICATION_0_ED (IRQ_SHPI_START + 67)
  30692. -#define IRQ_CA_MSG_PEND_NOTIFICATION_1_ED (IRQ_SHPI_START + 65)
  30693. -
  30694. -#define IRQ_CA_WAKE_REQ_V1 (IRQ_SHPI_START + 83)
  30695. -#define IRQ_AC_READ_NOTIFICATION_0_V1 (IRQ_SHPI_START + 78)
  30696. -#define IRQ_AC_READ_NOTIFICATION_1_V1 (IRQ_SHPI_START + 76)
  30697. -#define IRQ_CA_MSG_PEND_NOTIFICATION_0_V1 (IRQ_SHPI_START + 79)
  30698. -#define IRQ_CA_MSG_PEND_NOTIFICATION_1_V1 (IRQ_SHPI_START + 77)
  30699. -
  30700. -#ifdef CONFIG_UX500_SOC_DB8500
  30701. -
  30702. -/* Virtual interrupts corresponding to the PRCMU wakeups. */
  30703. -#define IRQ_PRCMU_BASE IRQ_SOC_START
  30704. -#define IRQ_PRCMU_END (IRQ_PRCMU_BASE + 23)
  30705. -
  30706. -/*
  30707. - * We may have several SoCs, but only one will run at a
  30708. - * time, so the one with most IRQs will bump this ahead,
  30709. - * but the IRQ_SOC_START remains the same for either SoC.
  30710. - */
  30711. -#if IRQ_SOC_END < IRQ_PRCMU_END
  30712. -#undef IRQ_SOC_END
  30713. -#define IRQ_SOC_END IRQ_PRCMU_END
  30714. -#endif
  30715. -
  30716. -#endif /* CONFIG_UX500_SOC_DB8500 */
  30717. -#endif
  30718. diff -Nur linux-3.14.14/arch/arm/mach-ux500/irqs.h linux-imx6-3.14/arch/arm/mach-ux500/irqs.h
  30719. --- linux-3.14.14/arch/arm/mach-ux500/irqs.h 2014-07-28 10:07:25.000000000 -0500
  30720. +++ linux-imx6-3.14/arch/arm/mach-ux500/irqs.h 1969-12-31 18:00:00.000000000 -0600
  30721. @@ -1,49 +0,0 @@
  30722. -/*
  30723. - * Copyright (C) 2008 STMicroelectronics
  30724. - * Copyright (C) 2009 ST-Ericsson.
  30725. - *
  30726. - * This program is free software; you can redistribute it and/or modify
  30727. - * it under the terms of the GNU General Public License as published by
  30728. - * the Free Software Foundation; either version 2 of the License, or
  30729. - * (at your option) any later version.
  30730. - */
  30731. -#ifndef ASM_ARCH_IRQS_H
  30732. -#define ASM_ARCH_IRQS_H
  30733. -
  30734. -#define IRQ_LOCALTIMER 29
  30735. -#define IRQ_LOCALWDOG 30
  30736. -
  30737. -/* Shared Peripheral Interrupt (SHPI) */
  30738. -#define IRQ_SHPI_START 32
  30739. -
  30740. -/*
  30741. - * MTU0 preserved for now until plat-nomadik is taught not to use it. Don't
  30742. - * add any other IRQs here, use the irqs-dbx500.h files.
  30743. - */
  30744. -#define IRQ_MTU0 (IRQ_SHPI_START + 4)
  30745. -
  30746. -#define DBX500_NR_INTERNAL_IRQS 166
  30747. -
  30748. -/* After chip-specific IRQ numbers we have the GPIO ones */
  30749. -#define NOMADIK_NR_GPIO 288
  30750. -#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + DBX500_NR_INTERNAL_IRQS)
  30751. -#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - DBX500_NR_INTERNAL_IRQS)
  30752. -#define IRQ_GPIO_END NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
  30753. -
  30754. -#define IRQ_SOC_START IRQ_GPIO_END
  30755. -/* This will be overridden by SoC-specific irq headers */
  30756. -#define IRQ_SOC_END IRQ_SOC_START
  30757. -
  30758. -#include "irqs-db8500.h"
  30759. -
  30760. -#define IRQ_BOARD_START IRQ_SOC_END
  30761. -/* This will be overridden by board-specific irq headers */
  30762. -#define IRQ_BOARD_END IRQ_BOARD_START
  30763. -
  30764. -#ifdef CONFIG_MACH_MOP500
  30765. -#include "irqs-board-mop500.h"
  30766. -#endif
  30767. -
  30768. -#define UX500_NR_IRQS IRQ_BOARD_END
  30769. -
  30770. -#endif /* ASM_ARCH_IRQS_H */
  30771. diff -Nur linux-3.14.14/arch/arm/mach-vexpress/ct-ca9x4.c linux-imx6-3.14/arch/arm/mach-vexpress/ct-ca9x4.c
  30772. --- linux-3.14.14/arch/arm/mach-vexpress/ct-ca9x4.c 2014-07-28 10:07:25.000000000 -0500
  30773. +++ linux-imx6-3.14/arch/arm/mach-vexpress/ct-ca9x4.c 2014-12-08 00:31:51.384418001 -0600
  30774. @@ -45,6 +45,23 @@
  30775. iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
  30776. }
  30777. +static void __init ca9x4_l2_init(void)
  30778. +{
  30779. +#ifdef CONFIG_CACHE_L2X0
  30780. + void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
  30781. +
  30782. + if (l2x0_base) {
  30783. + /* set RAM latencies to 1 cycle for this core tile. */
  30784. + writel(0, l2x0_base + L310_TAG_LATENCY_CTRL);
  30785. + writel(0, l2x0_base + L310_DATA_LATENCY_CTRL);
  30786. +
  30787. + l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
  30788. + } else {
  30789. + pr_err("L2C: unable to map L2 cache controller\n");
  30790. + }
  30791. +#endif
  30792. +}
  30793. +
  30794. #ifdef CONFIG_HAVE_ARM_TWD
  30795. static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, A9_MPCORE_TWD, IRQ_LOCALTIMER);
  30796. @@ -63,6 +80,7 @@
  30797. gic_init(0, 29, ioremap(A9_MPCORE_GIC_DIST, SZ_4K),
  30798. ioremap(A9_MPCORE_GIC_CPU, SZ_256));
  30799. ca9x4_twd_init();
  30800. + ca9x4_l2_init();
  30801. }
  30802. static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
  30803. @@ -141,16 +159,6 @@
  30804. {
  30805. int i;
  30806. -#ifdef CONFIG_CACHE_L2X0
  30807. - void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
  30808. -
  30809. - /* set RAM latencies to 1 cycle for this core tile. */
  30810. - writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
  30811. - writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
  30812. -
  30813. - l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
  30814. -#endif
  30815. -
  30816. for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
  30817. amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
  30818. diff -Nur linux-3.14.14/arch/arm/mach-vexpress/dcscb.c linux-imx6-3.14/arch/arm/mach-vexpress/dcscb.c
  30819. --- linux-3.14.14/arch/arm/mach-vexpress/dcscb.c 2014-07-28 10:07:25.000000000 -0500
  30820. +++ linux-imx6-3.14/arch/arm/mach-vexpress/dcscb.c 2014-12-08 00:31:51.384418001 -0600
  30821. @@ -23,6 +23,7 @@
  30822. #include <asm/cacheflush.h>
  30823. #include <asm/cputype.h>
  30824. #include <asm/cp15.h>
  30825. +#include <asm/psci.h>
  30826. #define RST_HOLD0 0x0
  30827. @@ -193,6 +194,12 @@
  30828. unsigned int cfg;
  30829. int ret;
  30830. + ret = psci_probe();
  30831. + if (!ret) {
  30832. + pr_debug("psci found. Aborting native init\n");
  30833. + return -ENODEV;
  30834. + }
  30835. +
  30836. if (!cci_probed())
  30837. return -ENODEV;
  30838. diff -Nur linux-3.14.14/arch/arm/mach-vexpress/Kconfig linux-imx6-3.14/arch/arm/mach-vexpress/Kconfig
  30839. --- linux-3.14.14/arch/arm/mach-vexpress/Kconfig 2014-07-28 10:07:25.000000000 -0500
  30840. +++ linux-imx6-3.14/arch/arm/mach-vexpress/Kconfig 2014-12-08 00:31:51.384418001 -0600
  30841. @@ -55,6 +55,7 @@
  30842. config ARCH_VEXPRESS_CA9X4
  30843. bool "Versatile Express Cortex-A9x4 tile"
  30844. + select ARM_ERRATA_643719
  30845. config ARCH_VEXPRESS_DCSCB
  30846. bool "Dual Cluster System Control Block (DCSCB) support"
  30847. diff -Nur linux-3.14.14/arch/arm/mach-vexpress/Makefile linux-imx6-3.14/arch/arm/mach-vexpress/Makefile
  30848. --- linux-3.14.14/arch/arm/mach-vexpress/Makefile 2014-07-28 10:07:25.000000000 -0500
  30849. +++ linux-imx6-3.14/arch/arm/mach-vexpress/Makefile 2014-12-08 00:31:51.384418001 -0600
  30850. @@ -8,8 +8,15 @@
  30851. obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
  30852. obj-$(CONFIG_ARCH_VEXPRESS_DCSCB) += dcscb.o dcscb_setup.o
  30853. CFLAGS_dcscb.o += -march=armv7-a
  30854. +CFLAGS_REMOVE_dcscb.o = -pg
  30855. obj-$(CONFIG_ARCH_VEXPRESS_SPC) += spc.o
  30856. +CFLAGS_REMOVE_spc.o = -pg
  30857. obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o
  30858. CFLAGS_tc2_pm.o += -march=armv7-a
  30859. +CFLAGS_REMOVE_tc2_pm.o = -pg
  30860. +ifeq ($(CONFIG_ARCH_VEXPRESS_TC2_PM),y)
  30861. +obj-$(CONFIG_ARM_PSCI) += tc2_pm_psci.o
  30862. +CFLAGS_REMOVE_tc2_pm_psci.o = -pg
  30863. +endif
  30864. obj-$(CONFIG_SMP) += platsmp.o
  30865. obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
  30866. diff -Nur linux-3.14.14/arch/arm/mach-vexpress/spc.c linux-imx6-3.14/arch/arm/mach-vexpress/spc.c
  30867. --- linux-3.14.14/arch/arm/mach-vexpress/spc.c 2014-07-28 10:07:25.000000000 -0500
  30868. +++ linux-imx6-3.14/arch/arm/mach-vexpress/spc.c 2014-12-08 00:31:51.388418001 -0600
  30869. @@ -392,7 +392,7 @@
  30870. * +--------------------------+
  30871. * | 31 20 | 19 0 |
  30872. * +--------------------------+
  30873. - * | u_volt | freq(kHz) |
  30874. + * | m_volt | freq(kHz) |
  30875. * +--------------------------+
  30876. */
  30877. #define MULT_FACTOR 20
  30878. @@ -414,7 +414,7 @@
  30879. ret = ve_spc_read_sys_cfg(SYSCFG_SCC, off, &data);
  30880. if (!ret) {
  30881. opps->freq = (data & FREQ_MASK) * MULT_FACTOR;
  30882. - opps->u_volt = data >> VOLT_SHIFT;
  30883. + opps->u_volt = (data >> VOLT_SHIFT) * 1000;
  30884. } else {
  30885. break;
  30886. }
  30887. diff -Nur linux-3.14.14/arch/arm/mach-vexpress/tc2_pm.c linux-imx6-3.14/arch/arm/mach-vexpress/tc2_pm.c
  30888. --- linux-3.14.14/arch/arm/mach-vexpress/tc2_pm.c 2014-07-28 10:07:25.000000000 -0500
  30889. +++ linux-imx6-3.14/arch/arm/mach-vexpress/tc2_pm.c 2014-12-08 00:31:51.388418001 -0600
  30890. @@ -27,6 +27,7 @@
  30891. #include <asm/cacheflush.h>
  30892. #include <asm/cputype.h>
  30893. #include <asm/cp15.h>
  30894. +#include <asm/psci.h>
  30895. #include <linux/arm-cci.h>
  30896. @@ -329,6 +330,12 @@
  30897. u32 a15_cluster_id, a7_cluster_id, sys_info;
  30898. struct device_node *np;
  30899. + ret = psci_probe();
  30900. + if (!ret) {
  30901. + pr_debug("psci found. Aborting native init\n");
  30902. + return -ENODEV;
  30903. + }
  30904. +
  30905. /*
  30906. * The power management-related features are hidden behind
  30907. * SCC registers. We need to extract runtime information like
  30908. diff -Nur linux-3.14.14/arch/arm/mach-vexpress/tc2_pm_psci.c linux-imx6-3.14/arch/arm/mach-vexpress/tc2_pm_psci.c
  30909. --- linux-3.14.14/arch/arm/mach-vexpress/tc2_pm_psci.c 1969-12-31 18:00:00.000000000 -0600
  30910. +++ linux-imx6-3.14/arch/arm/mach-vexpress/tc2_pm_psci.c 2014-12-08 00:31:51.388418001 -0600
  30911. @@ -0,0 +1,173 @@
  30912. +/*
  30913. + * arch/arm/mach-vexpress/tc2_pm_psci.c - TC2 PSCI support
  30914. + *
  30915. + * Created by: Achin Gupta, December 2012
  30916. + * Copyright: (C) 2012 ARM Limited
  30917. + *
  30918. + * Some portions of this file were originally written by Nicolas Pitre
  30919. + * Copyright: (C) 2012 Linaro Limited
  30920. + *
  30921. + * This program is free software; you can redistribute it and/or modify
  30922. + * it under the terms of the GNU General Public License version 2 as
  30923. + * published by the Free Software Foundation.
  30924. + */
  30925. +
  30926. +#include <linux/init.h>
  30927. +#include <linux/kernel.h>
  30928. +#include <linux/of.h>
  30929. +#include <linux/spinlock.h>
  30930. +#include <linux/errno.h>
  30931. +
  30932. +#include <asm/mcpm.h>
  30933. +#include <asm/proc-fns.h>
  30934. +#include <asm/cacheflush.h>
  30935. +#include <asm/psci.h>
  30936. +#include <asm/atomic.h>
  30937. +#include <asm/cputype.h>
  30938. +#include <asm/cp15.h>
  30939. +
  30940. +#include <mach/motherboard.h>
  30941. +
  30942. +#include <linux/vexpress.h>
  30943. +
  30944. +/*
  30945. + * Platform specific state id understood by the firmware and used to
  30946. + * program the power controller
  30947. + */
  30948. +#define PSCI_POWER_STATE_ID 0
  30949. +
  30950. +#define TC2_CLUSTERS 2
  30951. +#define TC2_MAX_CPUS_PER_CLUSTER 3
  30952. +
  30953. +static atomic_t tc2_pm_use_count[TC2_MAX_CPUS_PER_CLUSTER][TC2_CLUSTERS];
  30954. +
  30955. +static int tc2_pm_psci_power_up(unsigned int cpu, unsigned int cluster)
  30956. +{
  30957. + unsigned int mpidr = (cluster << 8) | cpu;
  30958. + int ret = 0;
  30959. +
  30960. + BUG_ON(!psci_ops.cpu_on);
  30961. +
  30962. + switch (atomic_inc_return(&tc2_pm_use_count[cpu][cluster])) {
  30963. + case 1:
  30964. + /*
  30965. + * This is a request to power up a cpu that linux thinks has
  30966. + * been powered down. Retries are needed if the firmware has
  30967. + * seen the power down request as yet.
  30968. + */
  30969. + do
  30970. + ret = psci_ops.cpu_on(mpidr,
  30971. + virt_to_phys(mcpm_entry_point));
  30972. + while (ret == -EAGAIN);
  30973. +
  30974. + return ret;
  30975. + case 2:
  30976. + /* This power up request has overtaken a power down request */
  30977. + return ret;
  30978. + default:
  30979. + /* Any other value is a bug */
  30980. + BUG();
  30981. + }
  30982. +}
  30983. +
  30984. +static void tc2_pm_psci_power_down(void)
  30985. +{
  30986. + struct psci_power_state power_state;
  30987. + unsigned int mpidr, cpu, cluster;
  30988. +
  30989. + mpidr = read_cpuid_mpidr();
  30990. + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
  30991. + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
  30992. +
  30993. + BUG_ON(!psci_ops.cpu_off);
  30994. +
  30995. + switch (atomic_dec_return(&tc2_pm_use_count[cpu][cluster])) {
  30996. + case 1:
  30997. + /*
  30998. + * Overtaken by a power up. Flush caches, exit coherency,
  30999. + * return & fake a reset
  31000. + */
  31001. + set_cr(get_cr() & ~CR_C);
  31002. +
  31003. + flush_cache_louis();
  31004. +
  31005. + asm volatile ("clrex");
  31006. + set_auxcr(get_auxcr() & ~(1 << 6));
  31007. +
  31008. + return;
  31009. + case 0:
  31010. + /* A normal request to possibly power down the cluster */
  31011. + power_state.id = PSCI_POWER_STATE_ID;
  31012. + power_state.type = PSCI_POWER_STATE_TYPE_POWER_DOWN;
  31013. + power_state.affinity_level = PSCI_POWER_STATE_AFFINITY_LEVEL1;
  31014. +
  31015. + psci_ops.cpu_off(power_state);
  31016. +
  31017. + /* On success this function never returns */
  31018. + default:
  31019. + /* Any other value is a bug */
  31020. + BUG();
  31021. + }
  31022. +}
  31023. +
  31024. +static void tc2_pm_psci_suspend(u64 unused)
  31025. +{
  31026. + struct psci_power_state power_state;
  31027. +
  31028. + BUG_ON(!psci_ops.cpu_suspend);
  31029. +
  31030. + /* On TC2 always attempt to power down the cluster */
  31031. + power_state.id = PSCI_POWER_STATE_ID;
  31032. + power_state.type = PSCI_POWER_STATE_TYPE_POWER_DOWN;
  31033. + power_state.affinity_level = PSCI_POWER_STATE_AFFINITY_LEVEL1;
  31034. +
  31035. + psci_ops.cpu_suspend(power_state, virt_to_phys(mcpm_entry_point));
  31036. +
  31037. + /* On success this function never returns */
  31038. + BUG();
  31039. +}
  31040. +
  31041. +static const struct mcpm_platform_ops tc2_pm_power_ops = {
  31042. + .power_up = tc2_pm_psci_power_up,
  31043. + .power_down = tc2_pm_psci_power_down,
  31044. + .suspend = tc2_pm_psci_suspend,
  31045. +};
  31046. +
  31047. +static void __init tc2_pm_usage_count_init(void)
  31048. +{
  31049. + unsigned int mpidr, cpu, cluster;
  31050. +
  31051. + mpidr = read_cpuid_mpidr();
  31052. + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
  31053. + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
  31054. +
  31055. + pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
  31056. + BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
  31057. +
  31058. + atomic_set(&tc2_pm_use_count[cpu][cluster], 1);
  31059. +}
  31060. +
  31061. +static int __init tc2_pm_psci_init(void)
  31062. +{
  31063. + int ret;
  31064. +
  31065. + ret = psci_probe();
  31066. + if (ret) {
  31067. + pr_debug("psci not found. Aborting psci init\n");
  31068. + return -ENODEV;
  31069. + }
  31070. +
  31071. + if (!of_machine_is_compatible("arm,vexpress,v2p-ca15_a7"))
  31072. + return -ENODEV;
  31073. +
  31074. + tc2_pm_usage_count_init();
  31075. +
  31076. + ret = mcpm_platform_register(&tc2_pm_power_ops);
  31077. + if (!ret)
  31078. + ret = mcpm_sync_init(NULL);
  31079. + if (!ret)
  31080. + pr_info("TC2 power management using PSCI initialized\n");
  31081. + return ret;
  31082. +}
  31083. +
  31084. +early_initcall(tc2_pm_psci_init);
  31085. diff -Nur linux-3.14.14/arch/arm/mach-vexpress/v2m.c linux-imx6-3.14/arch/arm/mach-vexpress/v2m.c
  31086. --- linux-3.14.14/arch/arm/mach-vexpress/v2m.c 2014-07-28 10:07:25.000000000 -0500
  31087. +++ linux-imx6-3.14/arch/arm/mach-vexpress/v2m.c 2014-12-08 00:31:51.388418001 -0600
  31088. @@ -7,6 +7,7 @@
  31089. #include <linux/io.h>
  31090. #include <linux/smp.h>
  31091. #include <linux/init.h>
  31092. +#include <linux/memblock.h>
  31093. #include <linux/of_address.h>
  31094. #include <linux/of_fdt.h>
  31095. #include <linux/of_irq.h>
  31096. @@ -369,6 +370,31 @@
  31097. .init_machine = v2m_init,
  31098. MACHINE_END
  31099. +static void __init v2m_dt_hdlcd_init(void)
  31100. +{
  31101. + struct device_node *node;
  31102. + int len, na, ns;
  31103. + const __be32 *prop;
  31104. + phys_addr_t fb_base, fb_size;
  31105. +
  31106. + node = of_find_compatible_node(NULL, NULL, "arm,hdlcd");
  31107. + if (!node)
  31108. + return;
  31109. +
  31110. + na = of_n_addr_cells(node);
  31111. + ns = of_n_size_cells(node);
  31112. +
  31113. + prop = of_get_property(node, "framebuffer", &len);
  31114. + if (WARN_ON(!prop || len < (na + ns) * sizeof(*prop)))
  31115. + return;
  31116. +
  31117. + fb_base = of_read_number(prop, na);
  31118. + fb_size = of_read_number(prop + na, ns);
  31119. +
  31120. + if (WARN_ON(memblock_remove(fb_base, fb_size)))
  31121. + return;
  31122. +};
  31123. +
  31124. static struct map_desc v2m_rs1_io_desc __initdata = {
  31125. .virtual = V2M_PERIPH,
  31126. .pfn = __phys_to_pfn(0x1c000000),
  31127. @@ -421,6 +447,8 @@
  31128. }
  31129. versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000);
  31130. +
  31131. + v2m_dt_hdlcd_init();
  31132. }
  31133. static const struct of_device_id v2m_dt_bus_match[] __initconst = {
  31134. diff -Nur linux-3.14.14/arch/arm/mach-zynq/common.c linux-imx6-3.14/arch/arm/mach-zynq/common.c
  31135. --- linux-3.14.14/arch/arm/mach-zynq/common.c 2014-07-28 10:07:25.000000000 -0500
  31136. +++ linux-imx6-3.14/arch/arm/mach-zynq/common.c 2014-12-08 00:31:51.388418001 -0600
  31137. @@ -67,7 +67,7 @@
  31138. /*
  31139. * 64KB way size, 8-way associativity, parity disabled
  31140. */
  31141. - l2x0_of_init(0x02060000, 0xF0F0FFFF);
  31142. + l2x0_of_init(0x02000000, 0xf0ffffff);
  31143. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  31144. diff -Nur linux-3.14.14/arch/arm/mm/cache-feroceon-l2.c linux-imx6-3.14/arch/arm/mm/cache-feroceon-l2.c
  31145. --- linux-3.14.14/arch/arm/mm/cache-feroceon-l2.c 2014-07-28 10:07:25.000000000 -0500
  31146. +++ linux-imx6-3.14/arch/arm/mm/cache-feroceon-l2.c 2014-12-08 00:31:51.388418001 -0600
  31147. @@ -343,7 +343,6 @@
  31148. outer_cache.inv_range = feroceon_l2_inv_range;
  31149. outer_cache.clean_range = feroceon_l2_clean_range;
  31150. outer_cache.flush_range = feroceon_l2_flush_range;
  31151. - outer_cache.inv_all = l2_inv_all;
  31152. enable_l2();
  31153. diff -Nur linux-3.14.14/arch/arm/mm/cache-l2x0.c linux-imx6-3.14/arch/arm/mm/cache-l2x0.c
  31154. --- linux-3.14.14/arch/arm/mm/cache-l2x0.c 2014-07-28 10:07:25.000000000 -0500
  31155. +++ linux-imx6-3.14/arch/arm/mm/cache-l2x0.c 2014-12-08 00:31:51.392418001 -0600
  31156. @@ -16,18 +16,33 @@
  31157. * along with this program; if not, write to the Free Software
  31158. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  31159. */
  31160. +#include <linux/cpu.h>
  31161. #include <linux/err.h>
  31162. #include <linux/init.h>
  31163. +#include <linux/smp.h>
  31164. #include <linux/spinlock.h>
  31165. #include <linux/io.h>
  31166. #include <linux/of.h>
  31167. #include <linux/of_address.h>
  31168. #include <asm/cacheflush.h>
  31169. +#include <asm/cp15.h>
  31170. +#include <asm/cputype.h>
  31171. #include <asm/hardware/cache-l2x0.h>
  31172. #include "cache-tauros3.h"
  31173. #include "cache-aurora-l2.h"
  31174. +struct l2c_init_data {
  31175. + const char *type;
  31176. + unsigned way_size_0;
  31177. + unsigned num_lock;
  31178. + void (*of_parse)(const struct device_node *, u32 *, u32 *);
  31179. + void (*enable)(void __iomem *, u32, unsigned);
  31180. + void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
  31181. + void (*save)(void __iomem *);
  31182. + struct outer_cache_fns outer_cache;
  31183. +};
  31184. +
  31185. #define CACHE_LINE_SIZE 32
  31186. static void __iomem *l2x0_base;
  31187. @@ -36,96 +51,116 @@
  31188. static u32 l2x0_size;
  31189. static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
  31190. -/* Aurora don't have the cache ID register available, so we have to
  31191. - * pass it though the device tree */
  31192. -static u32 cache_id_part_number_from_dt;
  31193. -
  31194. struct l2x0_regs l2x0_saved_regs;
  31195. -struct l2x0_of_data {
  31196. - void (*setup)(const struct device_node *, u32 *, u32 *);
  31197. - void (*save)(void);
  31198. - struct outer_cache_fns outer_cache;
  31199. -};
  31200. -
  31201. -static bool of_init = false;
  31202. -
  31203. -static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
  31204. +/*
  31205. + * Common code for all cache controllers.
  31206. + */
  31207. +static inline void l2c_wait_mask(void __iomem *reg, unsigned long mask)
  31208. {
  31209. /* wait for cache operation by line or way to complete */
  31210. while (readl_relaxed(reg) & mask)
  31211. cpu_relax();
  31212. }
  31213. -#ifdef CONFIG_CACHE_PL310
  31214. -static inline void cache_wait(void __iomem *reg, unsigned long mask)
  31215. +/*
  31216. + * By default, we write directly to secure registers. Platforms must
  31217. + * override this if they are running non-secure.
  31218. + */
  31219. +static void l2c_write_sec(unsigned long val, void __iomem *base, unsigned reg)
  31220. {
  31221. - /* cache operations by line are atomic on PL310 */
  31222. + if (val == readl_relaxed(base + reg))
  31223. + return;
  31224. + if (outer_cache.write_sec)
  31225. + outer_cache.write_sec(val, reg);
  31226. + else
  31227. + writel_relaxed(val, base + reg);
  31228. }
  31229. -#else
  31230. -#define cache_wait cache_wait_way
  31231. -#endif
  31232. -static inline void cache_sync(void)
  31233. +/*
  31234. + * This should only be called when we have a requirement that the
  31235. + * register be written due to a work-around, as platforms running
  31236. + * in non-secure mode may not be able to access this register.
  31237. + */
  31238. +static inline void l2c_set_debug(void __iomem *base, unsigned long val)
  31239. {
  31240. - void __iomem *base = l2x0_base;
  31241. -
  31242. - writel_relaxed(0, base + sync_reg_offset);
  31243. - cache_wait(base + L2X0_CACHE_SYNC, 1);
  31244. + l2c_write_sec(val, base, L2X0_DEBUG_CTRL);
  31245. }
  31246. -static inline void l2x0_clean_line(unsigned long addr)
  31247. +static void __l2c_op_way(void __iomem *reg)
  31248. {
  31249. - void __iomem *base = l2x0_base;
  31250. - cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
  31251. - writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
  31252. + writel_relaxed(l2x0_way_mask, reg);
  31253. + l2c_wait_mask(reg, l2x0_way_mask);
  31254. }
  31255. -static inline void l2x0_inv_line(unsigned long addr)
  31256. +static inline void l2c_unlock(void __iomem *base, unsigned num)
  31257. {
  31258. - void __iomem *base = l2x0_base;
  31259. - cache_wait(base + L2X0_INV_LINE_PA, 1);
  31260. - writel_relaxed(addr, base + L2X0_INV_LINE_PA);
  31261. + unsigned i;
  31262. +
  31263. + for (i = 0; i < num; i++) {
  31264. + writel_relaxed(0, base + L2X0_LOCKDOWN_WAY_D_BASE +
  31265. + i * L2X0_LOCKDOWN_STRIDE);
  31266. + writel_relaxed(0, base + L2X0_LOCKDOWN_WAY_I_BASE +
  31267. + i * L2X0_LOCKDOWN_STRIDE);
  31268. + }
  31269. }
  31270. -#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
  31271. -static inline void debug_writel(unsigned long val)
  31272. +/*
  31273. + * Enable the L2 cache controller. This function must only be
  31274. + * called when the cache controller is known to be disabled.
  31275. + */
  31276. +static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
  31277. {
  31278. - if (outer_cache.set_debug)
  31279. - outer_cache.set_debug(val);
  31280. + unsigned long flags;
  31281. +
  31282. + l2c_write_sec(aux, base, L2X0_AUX_CTRL);
  31283. +
  31284. + l2c_unlock(base, num_lock);
  31285. +
  31286. + local_irq_save(flags);
  31287. + __l2c_op_way(base + L2X0_INV_WAY);
  31288. + writel_relaxed(0, base + sync_reg_offset);
  31289. + l2c_wait_mask(base + sync_reg_offset, 1);
  31290. + local_irq_restore(flags);
  31291. +
  31292. + l2c_write_sec(L2X0_CTRL_EN, base, L2X0_CTRL);
  31293. }
  31294. -static void pl310_set_debug(unsigned long val)
  31295. +static void l2c_disable(void)
  31296. {
  31297. - writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
  31298. + void __iomem *base = l2x0_base;
  31299. +
  31300. + outer_cache.flush_all();
  31301. + l2c_write_sec(0, base, L2X0_CTRL);
  31302. + dsb(st);
  31303. }
  31304. -#else
  31305. -/* Optimised out for non-errata case */
  31306. -static inline void debug_writel(unsigned long val)
  31307. +
  31308. +#ifdef CONFIG_CACHE_PL310
  31309. +static inline void cache_wait(void __iomem *reg, unsigned long mask)
  31310. {
  31311. + /* cache operations by line are atomic on PL310 */
  31312. }
  31313. -
  31314. -#define pl310_set_debug NULL
  31315. +#else
  31316. +#define cache_wait l2c_wait_mask
  31317. #endif
  31318. -#ifdef CONFIG_PL310_ERRATA_588369
  31319. -static inline void l2x0_flush_line(unsigned long addr)
  31320. +static inline void cache_sync(void)
  31321. {
  31322. void __iomem *base = l2x0_base;
  31323. - /* Clean by PA followed by Invalidate by PA */
  31324. - cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
  31325. - writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
  31326. - cache_wait(base + L2X0_INV_LINE_PA, 1);
  31327. - writel_relaxed(addr, base + L2X0_INV_LINE_PA);
  31328. + writel_relaxed(0, base + sync_reg_offset);
  31329. + cache_wait(base + L2X0_CACHE_SYNC, 1);
  31330. }
  31331. -#else
  31332. -static inline void l2x0_flush_line(unsigned long addr)
  31333. +#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
  31334. +static inline void debug_writel(unsigned long val)
  31335. +{
  31336. + l2c_set_debug(l2x0_base, val);
  31337. +}
  31338. +#else
  31339. +/* Optimised out for non-errata case */
  31340. +static inline void debug_writel(unsigned long val)
  31341. {
  31342. - void __iomem *base = l2x0_base;
  31343. - cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31344. - writel_relaxed(addr, base + L2X0_CLEAN_INV_LINE_PA);
  31345. }
  31346. #endif
  31347. @@ -141,8 +176,7 @@
  31348. static void __l2x0_flush_all(void)
  31349. {
  31350. debug_writel(0x03);
  31351. - writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
  31352. - cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
  31353. + __l2c_op_way(l2x0_base + L2X0_CLEAN_INV_WAY);
  31354. cache_sync();
  31355. debug_writel(0x00);
  31356. }
  31357. @@ -157,274 +191,882 @@
  31358. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31359. }
  31360. -static void l2x0_clean_all(void)
  31361. +static void l2x0_disable(void)
  31362. {
  31363. unsigned long flags;
  31364. - /* clean all ways */
  31365. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31366. - writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
  31367. - cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
  31368. - cache_sync();
  31369. + __l2x0_flush_all();
  31370. + l2c_write_sec(0, l2x0_base, L2X0_CTRL);
  31371. + dsb(st);
  31372. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31373. }
  31374. -static void l2x0_inv_all(void)
  31375. +static void l2c_save(void __iomem *base)
  31376. {
  31377. - unsigned long flags;
  31378. + l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  31379. +}
  31380. - /* invalidate all ways */
  31381. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31382. - /* Invalidating when L2 is enabled is a nono */
  31383. - BUG_ON(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN);
  31384. - writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
  31385. - cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
  31386. - cache_sync();
  31387. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31388. +/*
  31389. + * L2C-210 specific code.
  31390. + *
  31391. + * The L2C-2x0 PA, set/way and sync operations are atomic, but we must
  31392. + * ensure that no background operation is running. The way operations
  31393. + * are all background tasks.
  31394. + *
  31395. + * While a background operation is in progress, any new operation is
  31396. + * ignored (unspecified whether this causes an error.) Thankfully, not
  31397. + * used on SMP.
  31398. + *
  31399. + * Never has a different sync register other than L2X0_CACHE_SYNC, but
  31400. + * we use sync_reg_offset here so we can share some of this with L2C-310.
  31401. + */
  31402. +static void __l2c210_cache_sync(void __iomem *base)
  31403. +{
  31404. + writel_relaxed(0, base + sync_reg_offset);
  31405. }
  31406. -static void l2x0_inv_range(unsigned long start, unsigned long end)
  31407. +static void __l2c210_op_pa_range(void __iomem *reg, unsigned long start,
  31408. + unsigned long end)
  31409. +{
  31410. + while (start < end) {
  31411. + writel_relaxed(start, reg);
  31412. + start += CACHE_LINE_SIZE;
  31413. + }
  31414. +}
  31415. +
  31416. +static void l2c210_inv_range(unsigned long start, unsigned long end)
  31417. {
  31418. void __iomem *base = l2x0_base;
  31419. - unsigned long flags;
  31420. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31421. if (start & (CACHE_LINE_SIZE - 1)) {
  31422. start &= ~(CACHE_LINE_SIZE - 1);
  31423. - debug_writel(0x03);
  31424. - l2x0_flush_line(start);
  31425. - debug_writel(0x00);
  31426. + writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
  31427. start += CACHE_LINE_SIZE;
  31428. }
  31429. if (end & (CACHE_LINE_SIZE - 1)) {
  31430. end &= ~(CACHE_LINE_SIZE - 1);
  31431. - debug_writel(0x03);
  31432. - l2x0_flush_line(end);
  31433. - debug_writel(0x00);
  31434. + writel_relaxed(end, base + L2X0_CLEAN_INV_LINE_PA);
  31435. }
  31436. + __l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
  31437. + __l2c210_cache_sync(base);
  31438. +}
  31439. +
  31440. +static void l2c210_clean_range(unsigned long start, unsigned long end)
  31441. +{
  31442. + void __iomem *base = l2x0_base;
  31443. +
  31444. + start &= ~(CACHE_LINE_SIZE - 1);
  31445. + __l2c210_op_pa_range(base + L2X0_CLEAN_LINE_PA, start, end);
  31446. + __l2c210_cache_sync(base);
  31447. +}
  31448. +
  31449. +static void l2c210_flush_range(unsigned long start, unsigned long end)
  31450. +{
  31451. + void __iomem *base = l2x0_base;
  31452. +
  31453. + start &= ~(CACHE_LINE_SIZE - 1);
  31454. + __l2c210_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA, start, end);
  31455. + __l2c210_cache_sync(base);
  31456. +}
  31457. +
  31458. +static void l2c210_flush_all(void)
  31459. +{
  31460. + void __iomem *base = l2x0_base;
  31461. +
  31462. + BUG_ON(!irqs_disabled());
  31463. +
  31464. + __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
  31465. + __l2c210_cache_sync(base);
  31466. +}
  31467. +
  31468. +static void l2c210_sync(void)
  31469. +{
  31470. + __l2c210_cache_sync(l2x0_base);
  31471. +}
  31472. +
  31473. +static void l2c210_resume(void)
  31474. +{
  31475. + void __iomem *base = l2x0_base;
  31476. +
  31477. + if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
  31478. + l2c_enable(base, l2x0_saved_regs.aux_ctrl, 1);
  31479. +}
  31480. +
  31481. +static const struct l2c_init_data l2c210_data __initconst = {
  31482. + .type = "L2C-210",
  31483. + .way_size_0 = SZ_8K,
  31484. + .num_lock = 1,
  31485. + .enable = l2c_enable,
  31486. + .save = l2c_save,
  31487. + .outer_cache = {
  31488. + .inv_range = l2c210_inv_range,
  31489. + .clean_range = l2c210_clean_range,
  31490. + .flush_range = l2c210_flush_range,
  31491. + .flush_all = l2c210_flush_all,
  31492. + .disable = l2c_disable,
  31493. + .sync = l2c210_sync,
  31494. + .resume = l2c210_resume,
  31495. + },
  31496. +};
  31497. +
  31498. +/*
  31499. + * L2C-220 specific code.
  31500. + *
  31501. + * All operations are background operations: they have to be waited for.
  31502. + * Conflicting requests generate a slave error (which will cause an
  31503. + * imprecise abort.) Never uses sync_reg_offset, so we hard-code the
  31504. + * sync register here.
  31505. + *
  31506. + * However, we can re-use the l2c210_resume call.
  31507. + */
  31508. +static inline void __l2c220_cache_sync(void __iomem *base)
  31509. +{
  31510. + writel_relaxed(0, base + L2X0_CACHE_SYNC);
  31511. + l2c_wait_mask(base + L2X0_CACHE_SYNC, 1);
  31512. +}
  31513. +
  31514. +static void l2c220_op_way(void __iomem *base, unsigned reg)
  31515. +{
  31516. + unsigned long flags;
  31517. +
  31518. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31519. + __l2c_op_way(base + reg);
  31520. + __l2c220_cache_sync(base);
  31521. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31522. +}
  31523. +
  31524. +static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long start,
  31525. + unsigned long end, unsigned long flags)
  31526. +{
  31527. + raw_spinlock_t *lock = &l2x0_lock;
  31528. +
  31529. while (start < end) {
  31530. unsigned long blk_end = start + min(end - start, 4096UL);
  31531. while (start < blk_end) {
  31532. - l2x0_inv_line(start);
  31533. + l2c_wait_mask(reg, 1);
  31534. + writel_relaxed(start, reg);
  31535. start += CACHE_LINE_SIZE;
  31536. }
  31537. if (blk_end < end) {
  31538. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31539. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31540. + raw_spin_unlock_irqrestore(lock, flags);
  31541. + raw_spin_lock_irqsave(lock, flags);
  31542. }
  31543. }
  31544. - cache_wait(base + L2X0_INV_LINE_PA, 1);
  31545. - cache_sync();
  31546. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31547. +
  31548. + return flags;
  31549. }
  31550. -static void l2x0_clean_range(unsigned long start, unsigned long end)
  31551. +static void l2c220_inv_range(unsigned long start, unsigned long end)
  31552. {
  31553. void __iomem *base = l2x0_base;
  31554. unsigned long flags;
  31555. - if ((end - start) >= l2x0_size) {
  31556. - l2x0_clean_all();
  31557. - return;
  31558. - }
  31559. -
  31560. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31561. - start &= ~(CACHE_LINE_SIZE - 1);
  31562. - while (start < end) {
  31563. - unsigned long blk_end = start + min(end - start, 4096UL);
  31564. -
  31565. - while (start < blk_end) {
  31566. - l2x0_clean_line(start);
  31567. + if ((start | end) & (CACHE_LINE_SIZE - 1)) {
  31568. + if (start & (CACHE_LINE_SIZE - 1)) {
  31569. + start &= ~(CACHE_LINE_SIZE - 1);
  31570. + writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
  31571. start += CACHE_LINE_SIZE;
  31572. }
  31573. - if (blk_end < end) {
  31574. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31575. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31576. + if (end & (CACHE_LINE_SIZE - 1)) {
  31577. + end &= ~(CACHE_LINE_SIZE - 1);
  31578. + l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31579. + writel_relaxed(end, base + L2X0_CLEAN_INV_LINE_PA);
  31580. }
  31581. }
  31582. - cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
  31583. - cache_sync();
  31584. +
  31585. + flags = l2c220_op_pa_range(base + L2X0_INV_LINE_PA,
  31586. + start, end, flags);
  31587. + l2c_wait_mask(base + L2X0_INV_LINE_PA, 1);
  31588. + __l2c220_cache_sync(base);
  31589. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31590. }
  31591. -static void l2x0_flush_range(unsigned long start, unsigned long end)
  31592. +static void l2c220_clean_range(unsigned long start, unsigned long end)
  31593. {
  31594. void __iomem *base = l2x0_base;
  31595. unsigned long flags;
  31596. + start &= ~(CACHE_LINE_SIZE - 1);
  31597. if ((end - start) >= l2x0_size) {
  31598. - l2x0_flush_all();
  31599. + l2c220_op_way(base, L2X0_CLEAN_WAY);
  31600. return;
  31601. }
  31602. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31603. + flags = l2c220_op_pa_range(base + L2X0_CLEAN_LINE_PA,
  31604. + start, end, flags);
  31605. + l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31606. + __l2c220_cache_sync(base);
  31607. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31608. +}
  31609. +
  31610. +static void l2c220_flush_range(unsigned long start, unsigned long end)
  31611. +{
  31612. + void __iomem *base = l2x0_base;
  31613. + unsigned long flags;
  31614. +
  31615. start &= ~(CACHE_LINE_SIZE - 1);
  31616. + if ((end - start) >= l2x0_size) {
  31617. + l2c220_op_way(base, L2X0_CLEAN_INV_WAY);
  31618. + return;
  31619. + }
  31620. +
  31621. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31622. + flags = l2c220_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA,
  31623. + start, end, flags);
  31624. + l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31625. + __l2c220_cache_sync(base);
  31626. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31627. +}
  31628. +
  31629. +static void l2c220_flush_all(void)
  31630. +{
  31631. + l2c220_op_way(l2x0_base, L2X0_CLEAN_INV_WAY);
  31632. +}
  31633. +
  31634. +static void l2c220_sync(void)
  31635. +{
  31636. + unsigned long flags;
  31637. +
  31638. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31639. + __l2c220_cache_sync(l2x0_base);
  31640. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31641. +}
  31642. +
  31643. +static void l2c220_enable(void __iomem *base, u32 aux, unsigned num_lock)
  31644. +{
  31645. + /*
  31646. + * Always enable non-secure access to the lockdown registers -
  31647. + * we write to them as part of the L2C enable sequence so they
  31648. + * need to be accessible.
  31649. + */
  31650. + aux |= L220_AUX_CTRL_NS_LOCKDOWN;
  31651. +
  31652. + l2c_enable(base, aux, num_lock);
  31653. +}
  31654. +
  31655. +static const struct l2c_init_data l2c220_data = {
  31656. + .type = "L2C-220",
  31657. + .way_size_0 = SZ_8K,
  31658. + .num_lock = 1,
  31659. + .enable = l2c220_enable,
  31660. + .save = l2c_save,
  31661. + .outer_cache = {
  31662. + .inv_range = l2c220_inv_range,
  31663. + .clean_range = l2c220_clean_range,
  31664. + .flush_range = l2c220_flush_range,
  31665. + .flush_all = l2c220_flush_all,
  31666. + .disable = l2c_disable,
  31667. + .sync = l2c220_sync,
  31668. + .resume = l2c210_resume,
  31669. + },
  31670. +};
  31671. +
  31672. +/*
  31673. + * L2C-310 specific code.
  31674. + *
  31675. + * Very similar to L2C-210, the PA, set/way and sync operations are atomic,
  31676. + * and the way operations are all background tasks. However, issuing an
  31677. + * operation while a background operation is in progress results in a
  31678. + * SLVERR response. We can reuse:
  31679. + *
  31680. + * __l2c210_cache_sync (using sync_reg_offset)
  31681. + * l2c210_sync
  31682. + * l2c210_inv_range (if 588369 is not applicable)
  31683. + * l2c210_clean_range
  31684. + * l2c210_flush_range (if 588369 is not applicable)
  31685. + * l2c210_flush_all (if 727915 is not applicable)
  31686. + *
  31687. + * Errata:
  31688. + * 588369: PL310 R0P0->R1P0, fixed R2P0.
  31689. + * Affects: all clean+invalidate operations
  31690. + * clean and invalidate skips the invalidate step, so we need to issue
  31691. + * separate operations. We also require the above debug workaround
  31692. + * enclosing this code fragment on affected parts. On unaffected parts,
  31693. + * we must not use this workaround without the debug register writes
  31694. + * to avoid exposing a problem similar to 727915.
  31695. + *
  31696. + * 727915: PL310 R2P0->R3P0, fixed R3P1.
  31697. + * Affects: clean+invalidate by way
  31698. + * clean and invalidate by way runs in the background, and a store can
  31699. + * hit the line between the clean operation and invalidate operation,
  31700. + * resulting in the store being lost.
  31701. + *
  31702. + * 752271: PL310 R3P0->R3P1-50REL0, fixed R3P2.
  31703. + * Affects: 8x64-bit (double fill) line fetches
  31704. + * double fill line fetches can fail to cause dirty data to be evicted
  31705. + * from the cache before the new data overwrites the second line.
  31706. + *
  31707. + * 753970: PL310 R3P0, fixed R3P1.
  31708. + * Affects: sync
  31709. + * prevents merging writes after the sync operation, until another L2C
  31710. + * operation is performed (or a number of other conditions.)
  31711. + *
  31712. + * 769419: PL310 R0P0->R3P1, fixed R3P2.
  31713. + * Affects: store buffer
  31714. + * store buffer is not automatically drained.
  31715. + */
  31716. +static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
  31717. +{
  31718. + void __iomem *base = l2x0_base;
  31719. +
  31720. + if ((start | end) & (CACHE_LINE_SIZE - 1)) {
  31721. + unsigned long flags;
  31722. +
  31723. + /* Erratum 588369 for both clean+invalidate operations */
  31724. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31725. + l2c_set_debug(base, 0x03);
  31726. +
  31727. + if (start & (CACHE_LINE_SIZE - 1)) {
  31728. + start &= ~(CACHE_LINE_SIZE - 1);
  31729. + writel_relaxed(start, base + L2X0_CLEAN_LINE_PA);
  31730. + writel_relaxed(start, base + L2X0_INV_LINE_PA);
  31731. + start += CACHE_LINE_SIZE;
  31732. + }
  31733. +
  31734. + if (end & (CACHE_LINE_SIZE - 1)) {
  31735. + end &= ~(CACHE_LINE_SIZE - 1);
  31736. + writel_relaxed(end, base + L2X0_CLEAN_LINE_PA);
  31737. + writel_relaxed(end, base + L2X0_INV_LINE_PA);
  31738. + }
  31739. +
  31740. + l2c_set_debug(base, 0x00);
  31741. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31742. + }
  31743. +
  31744. + __l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
  31745. + __l2c210_cache_sync(base);
  31746. +}
  31747. +
  31748. +static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
  31749. +{
  31750. + raw_spinlock_t *lock = &l2x0_lock;
  31751. + unsigned long flags;
  31752. + void __iomem *base = l2x0_base;
  31753. +
  31754. + raw_spin_lock_irqsave(lock, flags);
  31755. while (start < end) {
  31756. unsigned long blk_end = start + min(end - start, 4096UL);
  31757. - debug_writel(0x03);
  31758. + l2c_set_debug(base, 0x03);
  31759. while (start < blk_end) {
  31760. - l2x0_flush_line(start);
  31761. + writel_relaxed(start, base + L2X0_CLEAN_LINE_PA);
  31762. + writel_relaxed(start, base + L2X0_INV_LINE_PA);
  31763. start += CACHE_LINE_SIZE;
  31764. }
  31765. - debug_writel(0x00);
  31766. + l2c_set_debug(base, 0x00);
  31767. if (blk_end < end) {
  31768. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31769. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31770. + raw_spin_unlock_irqrestore(lock, flags);
  31771. + raw_spin_lock_irqsave(lock, flags);
  31772. }
  31773. }
  31774. - cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31775. - cache_sync();
  31776. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31777. + raw_spin_unlock_irqrestore(lock, flags);
  31778. + __l2c210_cache_sync(base);
  31779. }
  31780. -static void l2x0_disable(void)
  31781. +static void l2c310_flush_all_erratum(void)
  31782. {
  31783. + void __iomem *base = l2x0_base;
  31784. unsigned long flags;
  31785. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31786. - __l2x0_flush_all();
  31787. - writel_relaxed(0, l2x0_base + L2X0_CTRL);
  31788. - dsb(st);
  31789. + l2c_set_debug(base, 0x03);
  31790. + __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
  31791. + l2c_set_debug(base, 0x00);
  31792. + __l2c210_cache_sync(base);
  31793. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31794. }
  31795. -static void l2x0_unlock(u32 cache_id)
  31796. +static void __init l2c310_save(void __iomem *base)
  31797. {
  31798. - int lockregs;
  31799. - int i;
  31800. + unsigned revision;
  31801. - switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
  31802. - case L2X0_CACHE_ID_PART_L310:
  31803. - lockregs = 8;
  31804. - break;
  31805. - case AURORA_CACHE_ID:
  31806. - lockregs = 4;
  31807. + l2c_save(base);
  31808. +
  31809. + l2x0_saved_regs.tag_latency = readl_relaxed(base +
  31810. + L310_TAG_LATENCY_CTRL);
  31811. + l2x0_saved_regs.data_latency = readl_relaxed(base +
  31812. + L310_DATA_LATENCY_CTRL);
  31813. + l2x0_saved_regs.filter_end = readl_relaxed(base +
  31814. + L310_ADDR_FILTER_END);
  31815. + l2x0_saved_regs.filter_start = readl_relaxed(base +
  31816. + L310_ADDR_FILTER_START);
  31817. +
  31818. + revision = readl_relaxed(base + L2X0_CACHE_ID) &
  31819. + L2X0_CACHE_ID_RTL_MASK;
  31820. +
  31821. + /* From r2p0, there is Prefetch offset/control register */
  31822. + if (revision >= L310_CACHE_ID_RTL_R2P0)
  31823. + l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base +
  31824. + L310_PREFETCH_CTRL);
  31825. +
  31826. + /* From r3p0, there is Power control register */
  31827. + if (revision >= L310_CACHE_ID_RTL_R3P0)
  31828. + l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
  31829. + L310_POWER_CTRL);
  31830. +}
  31831. +
  31832. +static void l2c310_resume(void)
  31833. +{
  31834. + void __iomem *base = l2x0_base;
  31835. +
  31836. + if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  31837. + unsigned revision;
  31838. +
  31839. + /* restore pl310 setup */
  31840. + writel_relaxed(l2x0_saved_regs.tag_latency,
  31841. + base + L310_TAG_LATENCY_CTRL);
  31842. + writel_relaxed(l2x0_saved_regs.data_latency,
  31843. + base + L310_DATA_LATENCY_CTRL);
  31844. + writel_relaxed(l2x0_saved_regs.filter_end,
  31845. + base + L310_ADDR_FILTER_END);
  31846. + writel_relaxed(l2x0_saved_regs.filter_start,
  31847. + base + L310_ADDR_FILTER_START);
  31848. +
  31849. + revision = readl_relaxed(base + L2X0_CACHE_ID) &
  31850. + L2X0_CACHE_ID_RTL_MASK;
  31851. +
  31852. + if (revision >= L310_CACHE_ID_RTL_R2P0)
  31853. + l2c_write_sec(l2x0_saved_regs.prefetch_ctrl, base,
  31854. + L310_PREFETCH_CTRL);
  31855. + if (revision >= L310_CACHE_ID_RTL_R3P0)
  31856. + l2c_write_sec(l2x0_saved_regs.pwr_ctrl, base,
  31857. + L310_POWER_CTRL);
  31858. +
  31859. + l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
  31860. +
  31861. + /* Re-enable full-line-of-zeros for Cortex-A9 */
  31862. + if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
  31863. + set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
  31864. + }
  31865. +}
  31866. +
  31867. +static int l2c310_cpu_enable_flz(struct notifier_block *nb, unsigned long act, void *data)
  31868. +{
  31869. + switch (act & ~CPU_TASKS_FROZEN) {
  31870. + case CPU_STARTING:
  31871. + set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
  31872. break;
  31873. - default:
  31874. - /* L210 and unknown types */
  31875. - lockregs = 1;
  31876. + case CPU_DYING:
  31877. + set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
  31878. break;
  31879. }
  31880. + return NOTIFY_OK;
  31881. +}
  31882. - for (i = 0; i < lockregs; i++) {
  31883. - writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
  31884. - i * L2X0_LOCKDOWN_STRIDE);
  31885. - writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE +
  31886. - i * L2X0_LOCKDOWN_STRIDE);
  31887. +static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
  31888. +{
  31889. + unsigned rev = readl_relaxed(base + L2X0_CACHE_ID) & L2X0_CACHE_ID_PART_MASK;
  31890. + bool cortex_a9 = read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9;
  31891. +
  31892. + if (rev >= L310_CACHE_ID_RTL_R2P0) {
  31893. + if (cortex_a9) {
  31894. + aux |= L310_AUX_CTRL_EARLY_BRESP;
  31895. + pr_info("L2C-310 enabling early BRESP for Cortex-A9\n");
  31896. + } else if (aux & L310_AUX_CTRL_EARLY_BRESP) {
  31897. + pr_warn("L2C-310 early BRESP only supported with Cortex-A9\n");
  31898. + aux &= ~L310_AUX_CTRL_EARLY_BRESP;
  31899. + }
  31900. + }
  31901. +
  31902. + if (cortex_a9) {
  31903. + u32 aux_cur = readl_relaxed(base + L2X0_AUX_CTRL);
  31904. + u32 acr = get_auxcr();
  31905. +
  31906. + pr_debug("Cortex-A9 ACR=0x%08x\n", acr);
  31907. +
  31908. + if (acr & BIT(3) && !(aux_cur & L310_AUX_CTRL_FULL_LINE_ZERO))
  31909. + pr_err("L2C-310: full line of zeros enabled in Cortex-A9 but not L2C-310 - invalid\n");
  31910. +
  31911. + if (aux & L310_AUX_CTRL_FULL_LINE_ZERO && !(acr & BIT(3)))
  31912. + pr_err("L2C-310: enabling full line of zeros but not enabled in Cortex-A9\n");
  31913. +
  31914. + if (!(aux & L310_AUX_CTRL_FULL_LINE_ZERO) && !outer_cache.write_sec) {
  31915. + aux |= L310_AUX_CTRL_FULL_LINE_ZERO;
  31916. + pr_info("L2C-310 full line of zeros enabled for Cortex-A9\n");
  31917. + }
  31918. + } else if (aux & (L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP)) {
  31919. + pr_err("L2C-310: disabling Cortex-A9 specific feature bits\n");
  31920. + aux &= ~(L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP);
  31921. + }
  31922. +
  31923. + if (aux & (L310_AUX_CTRL_DATA_PREFETCH | L310_AUX_CTRL_INSTR_PREFETCH)) {
  31924. + u32 prefetch = readl_relaxed(base + L310_PREFETCH_CTRL);
  31925. +
  31926. + pr_info("L2C-310 %s%s prefetch enabled, offset %u lines\n",
  31927. + aux & L310_AUX_CTRL_INSTR_PREFETCH ? "I" : "",
  31928. + aux & L310_AUX_CTRL_DATA_PREFETCH ? "D" : "",
  31929. + 1 + (prefetch & L310_PREFETCH_CTRL_OFFSET_MASK));
  31930. + }
  31931. +
  31932. + /* r3p0 or later has power control register */
  31933. + if (rev >= L310_CACHE_ID_RTL_R3P0) {
  31934. + u32 power_ctrl;
  31935. +
  31936. + l2c_write_sec(L310_DYNAMIC_CLK_GATING_EN | L310_STNDBY_MODE_EN,
  31937. + base, L310_POWER_CTRL);
  31938. + power_ctrl = readl_relaxed(base + L310_POWER_CTRL);
  31939. + pr_info("L2C-310 dynamic clock gating %sabled, standby mode %sabled\n",
  31940. + power_ctrl & L310_DYNAMIC_CLK_GATING_EN ? "en" : "dis",
  31941. + power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis");
  31942. + }
  31943. +
  31944. + /*
  31945. + * Always enable non-secure access to the lockdown registers -
  31946. + * we write to them as part of the L2C enable sequence so they
  31947. + * need to be accessible.
  31948. + */
  31949. + aux |= L310_AUX_CTRL_NS_LOCKDOWN;
  31950. +
  31951. + l2c_enable(base, aux, num_lock);
  31952. +
  31953. + if (aux & L310_AUX_CTRL_FULL_LINE_ZERO) {
  31954. + set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
  31955. + cpu_notifier(l2c310_cpu_enable_flz, 0);
  31956. }
  31957. }
  31958. -void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
  31959. +static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
  31960. + struct outer_cache_fns *fns)
  31961. {
  31962. - u32 aux;
  31963. - u32 cache_id;
  31964. - u32 way_size = 0;
  31965. - int ways;
  31966. - int way_size_shift = L2X0_WAY_SIZE_SHIFT;
  31967. - const char *type;
  31968. + unsigned revision = cache_id & L2X0_CACHE_ID_RTL_MASK;
  31969. + const char *errata[8];
  31970. + unsigned n = 0;
  31971. - l2x0_base = base;
  31972. - if (cache_id_part_number_from_dt)
  31973. - cache_id = cache_id_part_number_from_dt;
  31974. - else
  31975. - cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
  31976. - aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  31977. + if (IS_ENABLED(CONFIG_PL310_ERRATA_588369) &&
  31978. + revision < L310_CACHE_ID_RTL_R2P0 &&
  31979. + /* For bcm compatibility */
  31980. + fns->inv_range == l2c210_inv_range) {
  31981. + fns->inv_range = l2c310_inv_range_erratum;
  31982. + fns->flush_range = l2c310_flush_range_erratum;
  31983. + errata[n++] = "588369";
  31984. + }
  31985. +
  31986. + if (IS_ENABLED(CONFIG_PL310_ERRATA_727915) &&
  31987. + revision >= L310_CACHE_ID_RTL_R2P0 &&
  31988. + revision < L310_CACHE_ID_RTL_R3P1) {
  31989. + fns->flush_all = l2c310_flush_all_erratum;
  31990. + errata[n++] = "727915";
  31991. + }
  31992. +
  31993. + if (revision >= L310_CACHE_ID_RTL_R3P0 &&
  31994. + revision < L310_CACHE_ID_RTL_R3P2) {
  31995. + u32 val = readl_relaxed(base + L310_PREFETCH_CTRL);
  31996. + /* I don't think bit23 is required here... but iMX6 does so */
  31997. + if (val & (BIT(30) | BIT(23))) {
  31998. + val &= ~(BIT(30) | BIT(23));
  31999. + l2c_write_sec(val, base, L310_PREFETCH_CTRL);
  32000. + errata[n++] = "752271";
  32001. + }
  32002. + }
  32003. +
  32004. + if (IS_ENABLED(CONFIG_PL310_ERRATA_753970) &&
  32005. + revision == L310_CACHE_ID_RTL_R3P0) {
  32006. + sync_reg_offset = L2X0_DUMMY_REG;
  32007. + errata[n++] = "753970";
  32008. + }
  32009. +
  32010. + if (IS_ENABLED(CONFIG_PL310_ERRATA_769419))
  32011. + errata[n++] = "769419";
  32012. +
  32013. + if (n) {
  32014. + unsigned i;
  32015. +
  32016. + pr_info("L2C-310 errat%s", n > 1 ? "a" : "um");
  32017. + for (i = 0; i < n; i++)
  32018. + pr_cont(" %s", errata[i]);
  32019. + pr_cont(" enabled\n");
  32020. + }
  32021. +}
  32022. +
  32023. +static void l2c310_disable(void)
  32024. +{
  32025. + /*
  32026. + * If full-line-of-zeros is enabled, we must first disable it in the
  32027. + * Cortex-A9 auxiliary control register before disabling the L2 cache.
  32028. + */
  32029. + if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
  32030. + set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
  32031. + l2c_disable();
  32032. +}
  32033. +
  32034. +static const struct l2c_init_data l2c310_init_fns __initconst = {
  32035. + .type = "L2C-310",
  32036. + .way_size_0 = SZ_8K,
  32037. + .num_lock = 8,
  32038. + .enable = l2c310_enable,
  32039. + .fixup = l2c310_fixup,
  32040. + .save = l2c310_save,
  32041. + .outer_cache = {
  32042. + .inv_range = l2c210_inv_range,
  32043. + .clean_range = l2c210_clean_range,
  32044. + .flush_range = l2c210_flush_range,
  32045. + .flush_all = l2c210_flush_all,
  32046. + .disable = l2c310_disable,
  32047. + .sync = l2c210_sync,
  32048. + .resume = l2c310_resume,
  32049. + },
  32050. +};
  32051. +
  32052. +static void __init __l2c_init(const struct l2c_init_data *data,
  32053. + u32 aux_val, u32 aux_mask, u32 cache_id)
  32054. +{
  32055. + struct outer_cache_fns fns;
  32056. + unsigned way_size_bits, ways;
  32057. + u32 aux, old_aux;
  32058. +
  32059. + /*
  32060. + * Sanity check the aux values. aux_mask is the bits we preserve
  32061. + * from reading the hardware register, and aux_val is the bits we
  32062. + * set.
  32063. + */
  32064. + if (aux_val & aux_mask)
  32065. + pr_alert("L2C: platform provided aux values permit register corruption.\n");
  32066. +
  32067. + old_aux = aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32068. aux &= aux_mask;
  32069. aux |= aux_val;
  32070. + if (old_aux != aux)
  32071. + pr_warn("L2C: DT/platform modifies aux control register: 0x%08x -> 0x%08x\n",
  32072. + old_aux, aux);
  32073. +
  32074. /* Determine the number of ways */
  32075. switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
  32076. case L2X0_CACHE_ID_PART_L310:
  32077. + if ((aux_val | ~aux_mask) & (L2C_AUX_CTRL_WAY_SIZE_MASK | L310_AUX_CTRL_ASSOCIATIVITY_16))
  32078. + pr_warn("L2C: DT/platform tries to modify or specify cache size\n");
  32079. if (aux & (1 << 16))
  32080. ways = 16;
  32081. else
  32082. ways = 8;
  32083. - type = "L310";
  32084. -#ifdef CONFIG_PL310_ERRATA_753970
  32085. - /* Unmapped register. */
  32086. - sync_reg_offset = L2X0_DUMMY_REG;
  32087. -#endif
  32088. - if ((cache_id & L2X0_CACHE_ID_RTL_MASK) <= L2X0_CACHE_ID_RTL_R3P0)
  32089. - outer_cache.set_debug = pl310_set_debug;
  32090. break;
  32091. +
  32092. case L2X0_CACHE_ID_PART_L210:
  32093. + case L2X0_CACHE_ID_PART_L220:
  32094. ways = (aux >> 13) & 0xf;
  32095. - type = "L210";
  32096. break;
  32097. case AURORA_CACHE_ID:
  32098. - sync_reg_offset = AURORA_SYNC_REG;
  32099. ways = (aux >> 13) & 0xf;
  32100. ways = 2 << ((ways + 1) >> 2);
  32101. - way_size_shift = AURORA_WAY_SIZE_SHIFT;
  32102. - type = "Aurora";
  32103. break;
  32104. +
  32105. default:
  32106. /* Assume unknown chips have 8 ways */
  32107. ways = 8;
  32108. - type = "L2x0 series";
  32109. break;
  32110. }
  32111. l2x0_way_mask = (1 << ways) - 1;
  32112. /*
  32113. - * L2 cache Size = Way size * Number of ways
  32114. + * way_size_0 is the size that a way_size value of zero would be
  32115. + * given the calculation: way_size = way_size_0 << way_size_bits.
  32116. + * So, if way_size_bits=0 is reserved, but way_size_bits=1 is 16k,
  32117. + * then way_size_0 would be 8k.
  32118. + *
  32119. + * L2 cache size = number of ways * way size.
  32120. + */
  32121. + way_size_bits = (aux & L2C_AUX_CTRL_WAY_SIZE_MASK) >>
  32122. + L2C_AUX_CTRL_WAY_SIZE_SHIFT;
  32123. + l2x0_size = ways * (data->way_size_0 << way_size_bits);
  32124. +
  32125. + fns = data->outer_cache;
  32126. + fns.write_sec = outer_cache.write_sec;
  32127. + if (data->fixup)
  32128. + data->fixup(l2x0_base, cache_id, &fns);
  32129. +
  32130. + /*
  32131. + * Check if l2x0 controller is already enabled. If we are booting
  32132. + * in non-secure mode accessing the below registers will fault.
  32133. */
  32134. - way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
  32135. - way_size = 1 << (way_size + way_size_shift);
  32136. + if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
  32137. + data->enable(l2x0_base, aux, data->num_lock);
  32138. - l2x0_size = ways * way_size * SZ_1K;
  32139. + outer_cache = fns;
  32140. /*
  32141. - * Check if l2x0 controller is already enabled.
  32142. - * If you are booting from non-secure mode
  32143. - * accessing the below registers will fault.
  32144. + * It is strange to save the register state before initialisation,
  32145. + * but hey, this is what the DT implementations decided to do.
  32146. */
  32147. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32148. - /* Make sure that I&D is not locked down when starting */
  32149. - l2x0_unlock(cache_id);
  32150. + if (data->save)
  32151. + data->save(l2x0_base);
  32152. +
  32153. + /* Re-read it in case some bits are reserved. */
  32154. + aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32155. +
  32156. + pr_info("%s cache controller enabled, %d ways, %d kB\n",
  32157. + data->type, ways, l2x0_size >> 10);
  32158. + pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
  32159. + data->type, cache_id, aux);
  32160. +}
  32161. - /* l2x0 controller is disabled */
  32162. - writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
  32163. +void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
  32164. +{
  32165. + const struct l2c_init_data *data;
  32166. + u32 cache_id;
  32167. - l2x0_inv_all();
  32168. + l2x0_base = base;
  32169. - /* enable L2X0 */
  32170. - writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
  32171. + cache_id = readl_relaxed(base + L2X0_CACHE_ID);
  32172. +
  32173. + switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
  32174. + default:
  32175. + case L2X0_CACHE_ID_PART_L210:
  32176. + data = &l2c210_data;
  32177. + break;
  32178. +
  32179. + case L2X0_CACHE_ID_PART_L220:
  32180. + data = &l2c220_data;
  32181. + break;
  32182. +
  32183. + case L2X0_CACHE_ID_PART_L310:
  32184. + data = &l2c310_init_fns;
  32185. + break;
  32186. }
  32187. - /* Re-read it in case some bits are reserved. */
  32188. - aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32189. + __l2c_init(data, aux_val, aux_mask, cache_id);
  32190. +}
  32191. +
  32192. +#ifdef CONFIG_OF
  32193. +static int l2_wt_override;
  32194. +
  32195. +/* Aurora don't have the cache ID register available, so we have to
  32196. + * pass it though the device tree */
  32197. +static u32 cache_id_part_number_from_dt;
  32198. +
  32199. +static void __init l2x0_of_parse(const struct device_node *np,
  32200. + u32 *aux_val, u32 *aux_mask)
  32201. +{
  32202. + u32 data[2] = { 0, 0 };
  32203. + u32 tag = 0;
  32204. + u32 dirty = 0;
  32205. + u32 val = 0, mask = 0;
  32206. +
  32207. + of_property_read_u32(np, "arm,tag-latency", &tag);
  32208. + if (tag) {
  32209. + mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
  32210. + val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
  32211. + }
  32212. +
  32213. + of_property_read_u32_array(np, "arm,data-latency",
  32214. + data, ARRAY_SIZE(data));
  32215. + if (data[0] && data[1]) {
  32216. + mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
  32217. + L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
  32218. + val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
  32219. + ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
  32220. + }
  32221. +
  32222. + of_property_read_u32(np, "arm,dirty-latency", &dirty);
  32223. + if (dirty) {
  32224. + mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
  32225. + val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
  32226. + }
  32227. - /* Save the value for resuming. */
  32228. - l2x0_saved_regs.aux_ctrl = aux;
  32229. + *aux_val &= ~mask;
  32230. + *aux_val |= val;
  32231. + *aux_mask &= ~mask;
  32232. +}
  32233. +
  32234. +static const struct l2c_init_data of_l2c210_data __initconst = {
  32235. + .type = "L2C-210",
  32236. + .way_size_0 = SZ_8K,
  32237. + .num_lock = 1,
  32238. + .of_parse = l2x0_of_parse,
  32239. + .enable = l2c_enable,
  32240. + .save = l2c_save,
  32241. + .outer_cache = {
  32242. + .inv_range = l2c210_inv_range,
  32243. + .clean_range = l2c210_clean_range,
  32244. + .flush_range = l2c210_flush_range,
  32245. + .flush_all = l2c210_flush_all,
  32246. + .disable = l2c_disable,
  32247. + .sync = l2c210_sync,
  32248. + .resume = l2c210_resume,
  32249. + },
  32250. +};
  32251. +
  32252. +static const struct l2c_init_data of_l2c220_data __initconst = {
  32253. + .type = "L2C-220",
  32254. + .way_size_0 = SZ_8K,
  32255. + .num_lock = 1,
  32256. + .of_parse = l2x0_of_parse,
  32257. + .enable = l2c220_enable,
  32258. + .save = l2c_save,
  32259. + .outer_cache = {
  32260. + .inv_range = l2c220_inv_range,
  32261. + .clean_range = l2c220_clean_range,
  32262. + .flush_range = l2c220_flush_range,
  32263. + .flush_all = l2c220_flush_all,
  32264. + .disable = l2c_disable,
  32265. + .sync = l2c220_sync,
  32266. + .resume = l2c210_resume,
  32267. + },
  32268. +};
  32269. +
  32270. +static void __init l2c310_of_parse(const struct device_node *np,
  32271. + u32 *aux_val, u32 *aux_mask)
  32272. +{
  32273. + u32 data[3] = { 0, 0, 0 };
  32274. + u32 tag[3] = { 0, 0, 0 };
  32275. + u32 filter[2] = { 0, 0 };
  32276. +
  32277. + of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
  32278. + if (tag[0] && tag[1] && tag[2])
  32279. + writel_relaxed(
  32280. + L310_LATENCY_CTRL_RD(tag[0] - 1) |
  32281. + L310_LATENCY_CTRL_WR(tag[1] - 1) |
  32282. + L310_LATENCY_CTRL_SETUP(tag[2] - 1),
  32283. + l2x0_base + L310_TAG_LATENCY_CTRL);
  32284. +
  32285. + of_property_read_u32_array(np, "arm,data-latency",
  32286. + data, ARRAY_SIZE(data));
  32287. + if (data[0] && data[1] && data[2])
  32288. + writel_relaxed(
  32289. + L310_LATENCY_CTRL_RD(data[0] - 1) |
  32290. + L310_LATENCY_CTRL_WR(data[1] - 1) |
  32291. + L310_LATENCY_CTRL_SETUP(data[2] - 1),
  32292. + l2x0_base + L310_DATA_LATENCY_CTRL);
  32293. - if (!of_init) {
  32294. - outer_cache.inv_range = l2x0_inv_range;
  32295. - outer_cache.clean_range = l2x0_clean_range;
  32296. - outer_cache.flush_range = l2x0_flush_range;
  32297. - outer_cache.sync = l2x0_cache_sync;
  32298. - outer_cache.flush_all = l2x0_flush_all;
  32299. - outer_cache.inv_all = l2x0_inv_all;
  32300. - outer_cache.disable = l2x0_disable;
  32301. - }
  32302. -
  32303. - pr_info("%s cache controller enabled\n", type);
  32304. - pr_info("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d kB\n",
  32305. - ways, cache_id, aux, l2x0_size >> 10);
  32306. + of_property_read_u32_array(np, "arm,filter-ranges",
  32307. + filter, ARRAY_SIZE(filter));
  32308. + if (filter[1]) {
  32309. + writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
  32310. + l2x0_base + L310_ADDR_FILTER_END);
  32311. + writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L310_ADDR_FILTER_EN,
  32312. + l2x0_base + L310_ADDR_FILTER_START);
  32313. + }
  32314. }
  32315. -#ifdef CONFIG_OF
  32316. -static int l2_wt_override;
  32317. +static const struct l2c_init_data of_l2c310_data __initconst = {
  32318. + .type = "L2C-310",
  32319. + .way_size_0 = SZ_8K,
  32320. + .num_lock = 8,
  32321. + .of_parse = l2c310_of_parse,
  32322. + .enable = l2c310_enable,
  32323. + .fixup = l2c310_fixup,
  32324. + .save = l2c310_save,
  32325. + .outer_cache = {
  32326. + .inv_range = l2c210_inv_range,
  32327. + .clean_range = l2c210_clean_range,
  32328. + .flush_range = l2c210_flush_range,
  32329. + .flush_all = l2c210_flush_all,
  32330. + .disable = l2c310_disable,
  32331. + .sync = l2c210_sync,
  32332. + .resume = l2c310_resume,
  32333. + },
  32334. +};
  32335. /*
  32336. * Note that the end addresses passed to Linux primitives are
  32337. @@ -524,6 +1166,100 @@
  32338. }
  32339. }
  32340. +static void aurora_save(void __iomem *base)
  32341. +{
  32342. + l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL);
  32343. + l2x0_saved_regs.aux_ctrl = readl_relaxed(base + L2X0_AUX_CTRL);
  32344. +}
  32345. +
  32346. +static void aurora_resume(void)
  32347. +{
  32348. + void __iomem *base = l2x0_base;
  32349. +
  32350. + if (!(readl(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32351. + writel_relaxed(l2x0_saved_regs.aux_ctrl, base + L2X0_AUX_CTRL);
  32352. + writel_relaxed(l2x0_saved_regs.ctrl, base + L2X0_CTRL);
  32353. + }
  32354. +}
  32355. +
  32356. +/*
  32357. + * For Aurora cache in no outer mode, enable via the CP15 coprocessor
  32358. + * broadcasting of cache commands to L2.
  32359. + */
  32360. +static void __init aurora_enable_no_outer(void __iomem *base, u32 aux,
  32361. + unsigned num_lock)
  32362. +{
  32363. + u32 u;
  32364. +
  32365. + asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u));
  32366. + u |= AURORA_CTRL_FW; /* Set the FW bit */
  32367. + asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u));
  32368. +
  32369. + isb();
  32370. +
  32371. + l2c_enable(base, aux, num_lock);
  32372. +}
  32373. +
  32374. +static void __init aurora_fixup(void __iomem *base, u32 cache_id,
  32375. + struct outer_cache_fns *fns)
  32376. +{
  32377. + sync_reg_offset = AURORA_SYNC_REG;
  32378. +}
  32379. +
  32380. +static void __init aurora_of_parse(const struct device_node *np,
  32381. + u32 *aux_val, u32 *aux_mask)
  32382. +{
  32383. + u32 val = AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU;
  32384. + u32 mask = AURORA_ACR_REPLACEMENT_MASK;
  32385. +
  32386. + of_property_read_u32(np, "cache-id-part",
  32387. + &cache_id_part_number_from_dt);
  32388. +
  32389. + /* Determine and save the write policy */
  32390. + l2_wt_override = of_property_read_bool(np, "wt-override");
  32391. +
  32392. + if (l2_wt_override) {
  32393. + val |= AURORA_ACR_FORCE_WRITE_THRO_POLICY;
  32394. + mask |= AURORA_ACR_FORCE_WRITE_POLICY_MASK;
  32395. + }
  32396. +
  32397. + *aux_val &= ~mask;
  32398. + *aux_val |= val;
  32399. + *aux_mask &= ~mask;
  32400. +}
  32401. +
  32402. +static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
  32403. + .type = "Aurora",
  32404. + .way_size_0 = SZ_4K,
  32405. + .num_lock = 4,
  32406. + .of_parse = aurora_of_parse,
  32407. + .enable = l2c_enable,
  32408. + .fixup = aurora_fixup,
  32409. + .save = aurora_save,
  32410. + .outer_cache = {
  32411. + .inv_range = aurora_inv_range,
  32412. + .clean_range = aurora_clean_range,
  32413. + .flush_range = aurora_flush_range,
  32414. + .flush_all = l2x0_flush_all,
  32415. + .disable = l2x0_disable,
  32416. + .sync = l2x0_cache_sync,
  32417. + .resume = aurora_resume,
  32418. + },
  32419. +};
  32420. +
  32421. +static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
  32422. + .type = "Aurora",
  32423. + .way_size_0 = SZ_4K,
  32424. + .num_lock = 4,
  32425. + .of_parse = aurora_of_parse,
  32426. + .enable = aurora_enable_no_outer,
  32427. + .fixup = aurora_fixup,
  32428. + .save = aurora_save,
  32429. + .outer_cache = {
  32430. + .resume = aurora_resume,
  32431. + },
  32432. +};
  32433. +
  32434. /*
  32435. * For certain Broadcom SoCs, depending on the address range, different offsets
  32436. * need to be added to the address before passing it to L2 for
  32437. @@ -588,16 +1324,16 @@
  32438. /* normal case, no cross section between start and end */
  32439. if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
  32440. - l2x0_inv_range(new_start, new_end);
  32441. + l2c210_inv_range(new_start, new_end);
  32442. return;
  32443. }
  32444. /* They cross sections, so it can only be a cross from section
  32445. * 2 to section 3
  32446. */
  32447. - l2x0_inv_range(new_start,
  32448. + l2c210_inv_range(new_start,
  32449. bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
  32450. - l2x0_inv_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32451. + l2c210_inv_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32452. new_end);
  32453. }
  32454. @@ -610,26 +1346,21 @@
  32455. if (unlikely(end <= start))
  32456. return;
  32457. - if ((end - start) >= l2x0_size) {
  32458. - l2x0_clean_all();
  32459. - return;
  32460. - }
  32461. -
  32462. new_start = bcm_l2_phys_addr(start);
  32463. new_end = bcm_l2_phys_addr(end);
  32464. /* normal case, no cross section between start and end */
  32465. if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
  32466. - l2x0_clean_range(new_start, new_end);
  32467. + l2c210_clean_range(new_start, new_end);
  32468. return;
  32469. }
  32470. /* They cross sections, so it can only be a cross from section
  32471. * 2 to section 3
  32472. */
  32473. - l2x0_clean_range(new_start,
  32474. + l2c210_clean_range(new_start,
  32475. bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
  32476. - l2x0_clean_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32477. + l2c210_clean_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32478. new_end);
  32479. }
  32480. @@ -643,7 +1374,7 @@
  32481. return;
  32482. if ((end - start) >= l2x0_size) {
  32483. - l2x0_flush_all();
  32484. + outer_cache.flush_all();
  32485. return;
  32486. }
  32487. @@ -652,283 +1383,67 @@
  32488. /* normal case, no cross section between start and end */
  32489. if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
  32490. - l2x0_flush_range(new_start, new_end);
  32491. + l2c210_flush_range(new_start, new_end);
  32492. return;
  32493. }
  32494. /* They cross sections, so it can only be a cross from section
  32495. * 2 to section 3
  32496. */
  32497. - l2x0_flush_range(new_start,
  32498. + l2c210_flush_range(new_start,
  32499. bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
  32500. - l2x0_flush_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32501. + l2c210_flush_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32502. new_end);
  32503. }
  32504. -static void __init l2x0_of_setup(const struct device_node *np,
  32505. - u32 *aux_val, u32 *aux_mask)
  32506. -{
  32507. - u32 data[2] = { 0, 0 };
  32508. - u32 tag = 0;
  32509. - u32 dirty = 0;
  32510. - u32 val = 0, mask = 0;
  32511. -
  32512. - of_property_read_u32(np, "arm,tag-latency", &tag);
  32513. - if (tag) {
  32514. - mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
  32515. - val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
  32516. - }
  32517. -
  32518. - of_property_read_u32_array(np, "arm,data-latency",
  32519. - data, ARRAY_SIZE(data));
  32520. - if (data[0] && data[1]) {
  32521. - mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
  32522. - L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
  32523. - val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
  32524. - ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
  32525. - }
  32526. -
  32527. - of_property_read_u32(np, "arm,dirty-latency", &dirty);
  32528. - if (dirty) {
  32529. - mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
  32530. - val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
  32531. - }
  32532. -
  32533. - *aux_val &= ~mask;
  32534. - *aux_val |= val;
  32535. - *aux_mask &= ~mask;
  32536. -}
  32537. -
  32538. -static void __init pl310_of_setup(const struct device_node *np,
  32539. - u32 *aux_val, u32 *aux_mask)
  32540. -{
  32541. - u32 data[3] = { 0, 0, 0 };
  32542. - u32 tag[3] = { 0, 0, 0 };
  32543. - u32 filter[2] = { 0, 0 };
  32544. -
  32545. - of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
  32546. - if (tag[0] && tag[1] && tag[2])
  32547. - writel_relaxed(
  32548. - ((tag[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
  32549. - ((tag[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
  32550. - ((tag[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
  32551. - l2x0_base + L2X0_TAG_LATENCY_CTRL);
  32552. -
  32553. - of_property_read_u32_array(np, "arm,data-latency",
  32554. - data, ARRAY_SIZE(data));
  32555. - if (data[0] && data[1] && data[2])
  32556. - writel_relaxed(
  32557. - ((data[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
  32558. - ((data[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
  32559. - ((data[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
  32560. - l2x0_base + L2X0_DATA_LATENCY_CTRL);
  32561. -
  32562. - of_property_read_u32_array(np, "arm,filter-ranges",
  32563. - filter, ARRAY_SIZE(filter));
  32564. - if (filter[1]) {
  32565. - writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
  32566. - l2x0_base + L2X0_ADDR_FILTER_END);
  32567. - writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L2X0_ADDR_FILTER_EN,
  32568. - l2x0_base + L2X0_ADDR_FILTER_START);
  32569. - }
  32570. -}
  32571. -
  32572. -static void __init pl310_save(void)
  32573. -{
  32574. - u32 l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
  32575. - L2X0_CACHE_ID_RTL_MASK;
  32576. -
  32577. - l2x0_saved_regs.tag_latency = readl_relaxed(l2x0_base +
  32578. - L2X0_TAG_LATENCY_CTRL);
  32579. - l2x0_saved_regs.data_latency = readl_relaxed(l2x0_base +
  32580. - L2X0_DATA_LATENCY_CTRL);
  32581. - l2x0_saved_regs.filter_end = readl_relaxed(l2x0_base +
  32582. - L2X0_ADDR_FILTER_END);
  32583. - l2x0_saved_regs.filter_start = readl_relaxed(l2x0_base +
  32584. - L2X0_ADDR_FILTER_START);
  32585. -
  32586. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) {
  32587. - /*
  32588. - * From r2p0, there is Prefetch offset/control register
  32589. - */
  32590. - l2x0_saved_regs.prefetch_ctrl = readl_relaxed(l2x0_base +
  32591. - L2X0_PREFETCH_CTRL);
  32592. - /*
  32593. - * From r3p0, there is Power control register
  32594. - */
  32595. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0)
  32596. - l2x0_saved_regs.pwr_ctrl = readl_relaxed(l2x0_base +
  32597. - L2X0_POWER_CTRL);
  32598. - }
  32599. -}
  32600. +/* Broadcom L2C-310 start from ARMs R3P2 or later, and require no fixups */
  32601. +static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
  32602. + .type = "BCM-L2C-310",
  32603. + .way_size_0 = SZ_8K,
  32604. + .num_lock = 8,
  32605. + .of_parse = l2c310_of_parse,
  32606. + .enable = l2c310_enable,
  32607. + .save = l2c310_save,
  32608. + .outer_cache = {
  32609. + .inv_range = bcm_inv_range,
  32610. + .clean_range = bcm_clean_range,
  32611. + .flush_range = bcm_flush_range,
  32612. + .flush_all = l2c210_flush_all,
  32613. + .disable = l2c310_disable,
  32614. + .sync = l2c210_sync,
  32615. + .resume = l2c310_resume,
  32616. + },
  32617. +};
  32618. -static void aurora_save(void)
  32619. +static void __init tauros3_save(void __iomem *base)
  32620. {
  32621. - l2x0_saved_regs.ctrl = readl_relaxed(l2x0_base + L2X0_CTRL);
  32622. - l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32623. -}
  32624. + l2c_save(base);
  32625. -static void __init tauros3_save(void)
  32626. -{
  32627. l2x0_saved_regs.aux2_ctrl =
  32628. - readl_relaxed(l2x0_base + TAUROS3_AUX2_CTRL);
  32629. + readl_relaxed(base + TAUROS3_AUX2_CTRL);
  32630. l2x0_saved_regs.prefetch_ctrl =
  32631. - readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
  32632. -}
  32633. -
  32634. -static void l2x0_resume(void)
  32635. -{
  32636. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32637. - /* restore aux ctrl and enable l2 */
  32638. - l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID));
  32639. -
  32640. - writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base +
  32641. - L2X0_AUX_CTRL);
  32642. -
  32643. - l2x0_inv_all();
  32644. -
  32645. - writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
  32646. - }
  32647. -}
  32648. -
  32649. -static void pl310_resume(void)
  32650. -{
  32651. - u32 l2x0_revision;
  32652. -
  32653. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32654. - /* restore pl310 setup */
  32655. - writel_relaxed(l2x0_saved_regs.tag_latency,
  32656. - l2x0_base + L2X0_TAG_LATENCY_CTRL);
  32657. - writel_relaxed(l2x0_saved_regs.data_latency,
  32658. - l2x0_base + L2X0_DATA_LATENCY_CTRL);
  32659. - writel_relaxed(l2x0_saved_regs.filter_end,
  32660. - l2x0_base + L2X0_ADDR_FILTER_END);
  32661. - writel_relaxed(l2x0_saved_regs.filter_start,
  32662. - l2x0_base + L2X0_ADDR_FILTER_START);
  32663. -
  32664. - l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
  32665. - L2X0_CACHE_ID_RTL_MASK;
  32666. -
  32667. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) {
  32668. - writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
  32669. - l2x0_base + L2X0_PREFETCH_CTRL);
  32670. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0)
  32671. - writel_relaxed(l2x0_saved_regs.pwr_ctrl,
  32672. - l2x0_base + L2X0_POWER_CTRL);
  32673. - }
  32674. - }
  32675. -
  32676. - l2x0_resume();
  32677. -}
  32678. -
  32679. -static void aurora_resume(void)
  32680. -{
  32681. - if (!(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32682. - writel_relaxed(l2x0_saved_regs.aux_ctrl,
  32683. - l2x0_base + L2X0_AUX_CTRL);
  32684. - writel_relaxed(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL);
  32685. - }
  32686. + readl_relaxed(base + L310_PREFETCH_CTRL);
  32687. }
  32688. static void tauros3_resume(void)
  32689. {
  32690. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32691. + void __iomem *base = l2x0_base;
  32692. +
  32693. + if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32694. writel_relaxed(l2x0_saved_regs.aux2_ctrl,
  32695. - l2x0_base + TAUROS3_AUX2_CTRL);
  32696. + base + TAUROS3_AUX2_CTRL);
  32697. writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
  32698. - l2x0_base + L2X0_PREFETCH_CTRL);
  32699. - }
  32700. -
  32701. - l2x0_resume();
  32702. -}
  32703. -
  32704. -static void __init aurora_broadcast_l2_commands(void)
  32705. -{
  32706. - __u32 u;
  32707. - /* Enable Broadcasting of cache commands to L2*/
  32708. - __asm__ __volatile__("mrc p15, 1, %0, c15, c2, 0" : "=r"(u));
  32709. - u |= AURORA_CTRL_FW; /* Set the FW bit */
  32710. - __asm__ __volatile__("mcr p15, 1, %0, c15, c2, 0\n" : : "r"(u));
  32711. - isb();
  32712. -}
  32713. -
  32714. -static void __init aurora_of_setup(const struct device_node *np,
  32715. - u32 *aux_val, u32 *aux_mask)
  32716. -{
  32717. - u32 val = AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU;
  32718. - u32 mask = AURORA_ACR_REPLACEMENT_MASK;
  32719. + base + L310_PREFETCH_CTRL);
  32720. - of_property_read_u32(np, "cache-id-part",
  32721. - &cache_id_part_number_from_dt);
  32722. -
  32723. - /* Determine and save the write policy */
  32724. - l2_wt_override = of_property_read_bool(np, "wt-override");
  32725. -
  32726. - if (l2_wt_override) {
  32727. - val |= AURORA_ACR_FORCE_WRITE_THRO_POLICY;
  32728. - mask |= AURORA_ACR_FORCE_WRITE_POLICY_MASK;
  32729. + l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
  32730. }
  32731. -
  32732. - *aux_val &= ~mask;
  32733. - *aux_val |= val;
  32734. - *aux_mask &= ~mask;
  32735. }
  32736. -static const struct l2x0_of_data pl310_data = {
  32737. - .setup = pl310_of_setup,
  32738. - .save = pl310_save,
  32739. - .outer_cache = {
  32740. - .resume = pl310_resume,
  32741. - .inv_range = l2x0_inv_range,
  32742. - .clean_range = l2x0_clean_range,
  32743. - .flush_range = l2x0_flush_range,
  32744. - .sync = l2x0_cache_sync,
  32745. - .flush_all = l2x0_flush_all,
  32746. - .inv_all = l2x0_inv_all,
  32747. - .disable = l2x0_disable,
  32748. - },
  32749. -};
  32750. -
  32751. -static const struct l2x0_of_data l2x0_data = {
  32752. - .setup = l2x0_of_setup,
  32753. - .save = NULL,
  32754. - .outer_cache = {
  32755. - .resume = l2x0_resume,
  32756. - .inv_range = l2x0_inv_range,
  32757. - .clean_range = l2x0_clean_range,
  32758. - .flush_range = l2x0_flush_range,
  32759. - .sync = l2x0_cache_sync,
  32760. - .flush_all = l2x0_flush_all,
  32761. - .inv_all = l2x0_inv_all,
  32762. - .disable = l2x0_disable,
  32763. - },
  32764. -};
  32765. -
  32766. -static const struct l2x0_of_data aurora_with_outer_data = {
  32767. - .setup = aurora_of_setup,
  32768. - .save = aurora_save,
  32769. - .outer_cache = {
  32770. - .resume = aurora_resume,
  32771. - .inv_range = aurora_inv_range,
  32772. - .clean_range = aurora_clean_range,
  32773. - .flush_range = aurora_flush_range,
  32774. - .sync = l2x0_cache_sync,
  32775. - .flush_all = l2x0_flush_all,
  32776. - .inv_all = l2x0_inv_all,
  32777. - .disable = l2x0_disable,
  32778. - },
  32779. -};
  32780. -
  32781. -static const struct l2x0_of_data aurora_no_outer_data = {
  32782. - .setup = aurora_of_setup,
  32783. - .save = aurora_save,
  32784. - .outer_cache = {
  32785. - .resume = aurora_resume,
  32786. - },
  32787. -};
  32788. -
  32789. -static const struct l2x0_of_data tauros3_data = {
  32790. - .setup = NULL,
  32791. +static const struct l2c_init_data of_tauros3_data __initconst = {
  32792. + .type = "Tauros3",
  32793. + .way_size_0 = SZ_8K,
  32794. + .num_lock = 8,
  32795. + .enable = l2c_enable,
  32796. .save = tauros3_save,
  32797. /* Tauros3 broadcasts L1 cache operations to L2 */
  32798. .outer_cache = {
  32799. @@ -936,43 +1451,26 @@
  32800. },
  32801. };
  32802. -static const struct l2x0_of_data bcm_l2x0_data = {
  32803. - .setup = pl310_of_setup,
  32804. - .save = pl310_save,
  32805. - .outer_cache = {
  32806. - .resume = pl310_resume,
  32807. - .inv_range = bcm_inv_range,
  32808. - .clean_range = bcm_clean_range,
  32809. - .flush_range = bcm_flush_range,
  32810. - .sync = l2x0_cache_sync,
  32811. - .flush_all = l2x0_flush_all,
  32812. - .inv_all = l2x0_inv_all,
  32813. - .disable = l2x0_disable,
  32814. - },
  32815. -};
  32816. -
  32817. +#define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns }
  32818. static const struct of_device_id l2x0_ids[] __initconst = {
  32819. - { .compatible = "arm,l210-cache", .data = (void *)&l2x0_data },
  32820. - { .compatible = "arm,l220-cache", .data = (void *)&l2x0_data },
  32821. - { .compatible = "arm,pl310-cache", .data = (void *)&pl310_data },
  32822. - { .compatible = "bcm,bcm11351-a2-pl310-cache", /* deprecated name */
  32823. - .data = (void *)&bcm_l2x0_data},
  32824. - { .compatible = "brcm,bcm11351-a2-pl310-cache",
  32825. - .data = (void *)&bcm_l2x0_data},
  32826. - { .compatible = "marvell,aurora-outer-cache",
  32827. - .data = (void *)&aurora_with_outer_data},
  32828. - { .compatible = "marvell,aurora-system-cache",
  32829. - .data = (void *)&aurora_no_outer_data},
  32830. - { .compatible = "marvell,tauros3-cache",
  32831. - .data = (void *)&tauros3_data },
  32832. + L2C_ID("arm,l210-cache", of_l2c210_data),
  32833. + L2C_ID("arm,l220-cache", of_l2c220_data),
  32834. + L2C_ID("arm,pl310-cache", of_l2c310_data),
  32835. + L2C_ID("brcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
  32836. + L2C_ID("marvell,aurora-outer-cache", of_aurora_with_outer_data),
  32837. + L2C_ID("marvell,aurora-system-cache", of_aurora_no_outer_data),
  32838. + L2C_ID("marvell,tauros3-cache", of_tauros3_data),
  32839. + /* Deprecated IDs */
  32840. + L2C_ID("bcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
  32841. {}
  32842. };
  32843. int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
  32844. {
  32845. + const struct l2c_init_data *data;
  32846. struct device_node *np;
  32847. - const struct l2x0_of_data *data;
  32848. struct resource res;
  32849. + u32 cache_id, old_aux;
  32850. np = of_find_matching_node(NULL, l2x0_ids);
  32851. if (!np)
  32852. @@ -989,23 +1487,29 @@
  32853. data = of_match_node(l2x0_ids, np)->data;
  32854. - /* L2 configuration can only be changed if the cache is disabled */
  32855. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32856. - if (data->setup)
  32857. - data->setup(np, &aux_val, &aux_mask);
  32858. -
  32859. - /* For aurora cache in no outer mode select the
  32860. - * correct mode using the coprocessor*/
  32861. - if (data == &aurora_no_outer_data)
  32862. - aurora_broadcast_l2_commands();
  32863. + old_aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32864. + if (old_aux != ((old_aux & aux_mask) | aux_val)) {
  32865. + pr_warn("L2C: platform modifies aux control register: 0x%08x -> 0x%08x\n",
  32866. + old_aux, (old_aux & aux_mask) | aux_val);
  32867. + } else if (aux_mask != ~0U && aux_val != 0) {
  32868. + pr_alert("L2C: platform provided aux values match the hardware, so have no effect. Please remove them.\n");
  32869. }
  32870. - if (data->save)
  32871. - data->save();
  32872. + /* All L2 caches are unified, so this property should be specified */
  32873. + if (!of_property_read_bool(np, "cache-unified"))
  32874. + pr_err("L2C: device tree omits to specify unified cache\n");
  32875. +
  32876. + /* L2 configuration can only be changed if the cache is disabled */
  32877. + if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
  32878. + if (data->of_parse)
  32879. + data->of_parse(np, &aux_val, &aux_mask);
  32880. +
  32881. + if (cache_id_part_number_from_dt)
  32882. + cache_id = cache_id_part_number_from_dt;
  32883. + else
  32884. + cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
  32885. - of_init = true;
  32886. - memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache));
  32887. - l2x0_init(l2x0_base, aux_val, aux_mask);
  32888. + __l2c_init(data, aux_val, aux_mask, cache_id);
  32889. return 0;
  32890. }
  32891. diff -Nur linux-3.14.14/arch/arm/mm/dma-mapping.c linux-imx6-3.14/arch/arm/mm/dma-mapping.c
  32892. --- linux-3.14.14/arch/arm/mm/dma-mapping.c 2014-07-28 10:07:25.000000000 -0500
  32893. +++ linux-imx6-3.14/arch/arm/mm/dma-mapping.c 2014-12-08 00:31:51.392418001 -0600
  32894. @@ -26,6 +26,7 @@
  32895. #include <linux/io.h>
  32896. #include <linux/vmalloc.h>
  32897. #include <linux/sizes.h>
  32898. +#include <linux/cma.h>
  32899. #include <asm/memory.h>
  32900. #include <asm/highmem.h>
  32901. diff -Nur linux-3.14.14/arch/arm/mm/fault.c linux-imx6-3.14/arch/arm/mm/fault.c
  32902. --- linux-3.14.14/arch/arm/mm/fault.c 2014-07-28 10:07:25.000000000 -0500
  32903. +++ linux-imx6-3.14/arch/arm/mm/fault.c 2014-12-08 00:31:51.392418001 -0600
  32904. @@ -449,8 +449,16 @@
  32905. if (pud_none(*pud_k))
  32906. goto bad_area;
  32907. - if (!pud_present(*pud))
  32908. + if (!pud_present(*pud)) {
  32909. set_pud(pud, *pud_k);
  32910. + /*
  32911. + * There is a small window during free_pgtables() where the
  32912. + * user *pud entry is 0 but the TLB has not been invalidated
  32913. + * and we get a level 2 (pmd) translation fault caused by the
  32914. + * intermediate TLB caching of the old level 1 (pud) entry.
  32915. + */
  32916. + flush_tlb_kernel_page(addr);
  32917. + }
  32918. pmd = pmd_offset(pud, addr);
  32919. pmd_k = pmd_offset(pud_k, addr);
  32920. @@ -473,8 +481,9 @@
  32921. #endif
  32922. if (pmd_none(pmd_k[index]))
  32923. goto bad_area;
  32924. + if (!pmd_present(pmd[index]))
  32925. + copy_pmd(pmd, pmd_k);
  32926. - copy_pmd(pmd, pmd_k);
  32927. return 0;
  32928. bad_area:
  32929. diff -Nur linux-3.14.14/arch/arm/mm/init.c linux-imx6-3.14/arch/arm/mm/init.c
  32930. --- linux-3.14.14/arch/arm/mm/init.c 2014-07-28 10:07:25.000000000 -0500
  32931. +++ linux-imx6-3.14/arch/arm/mm/init.c 2014-12-08 00:31:51.392418001 -0600
  32932. @@ -327,7 +327,7 @@
  32933. * reserve memory for DMA contigouos allocations,
  32934. * must come from DMA area inside low memory
  32935. */
  32936. - dma_contiguous_reserve(min(arm_dma_limit, arm_lowmem_limit));
  32937. + dma_contiguous_reserve(arm_dma_limit);
  32938. arm_memblock_steal_permitted = false;
  32939. memblock_dump_all();
  32940. diff -Nur linux-3.14.14/arch/arm/mm/Kconfig linux-imx6-3.14/arch/arm/mm/Kconfig
  32941. --- linux-3.14.14/arch/arm/mm/Kconfig 2014-07-28 10:07:25.000000000 -0500
  32942. +++ linux-imx6-3.14/arch/arm/mm/Kconfig 2014-12-08 00:31:51.388418001 -0600
  32943. @@ -897,6 +897,57 @@
  32944. This option enables optimisations for the PL310 cache
  32945. controller.
  32946. +config PL310_ERRATA_588369
  32947. + bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
  32948. + depends on CACHE_L2X0
  32949. + help
  32950. + The PL310 L2 cache controller implements three types of Clean &
  32951. + Invalidate maintenance operations: by Physical Address
  32952. + (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
  32953. + They are architecturally defined to behave as the execution of a
  32954. + clean operation followed immediately by an invalidate operation,
  32955. + both performing to the same memory location. This functionality
  32956. + is not correctly implemented in PL310 as clean lines are not
  32957. + invalidated as a result of these operations.
  32958. +
  32959. +config PL310_ERRATA_727915
  32960. + bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
  32961. + depends on CACHE_L2X0
  32962. + help
  32963. + PL310 implements the Clean & Invalidate by Way L2 cache maintenance
  32964. + operation (offset 0x7FC). This operation runs in background so that
  32965. + PL310 can handle normal accesses while it is in progress. Under very
  32966. + rare circumstances, due to this erratum, write data can be lost when
  32967. + PL310 treats a cacheable write transaction during a Clean &
  32968. + Invalidate by Way operation.
  32969. +
  32970. +config PL310_ERRATA_753970
  32971. + bool "PL310 errata: cache sync operation may be faulty"
  32972. + depends on CACHE_PL310
  32973. + help
  32974. + This option enables the workaround for the 753970 PL310 (r3p0) erratum.
  32975. +
  32976. + Under some condition the effect of cache sync operation on
  32977. + the store buffer still remains when the operation completes.
  32978. + This means that the store buffer is always asked to drain and
  32979. + this prevents it from merging any further writes. The workaround
  32980. + is to replace the normal offset of cache sync operation (0x730)
  32981. + by another offset targeting an unmapped PL310 register 0x740.
  32982. + This has the same effect as the cache sync operation: store buffer
  32983. + drain and waiting for all buffers empty.
  32984. +
  32985. +config PL310_ERRATA_769419
  32986. + bool "PL310 errata: no automatic Store Buffer drain"
  32987. + depends on CACHE_L2X0
  32988. + help
  32989. + On revisions of the PL310 prior to r3p2, the Store Buffer does
  32990. + not automatically drain. This can cause normal, non-cacheable
  32991. + writes to be retained when the memory system is idle, leading
  32992. + to suboptimal I/O performance for drivers using coherent DMA.
  32993. + This option adds a write barrier to the cpu_idle loop so that,
  32994. + on systems with an outer cache, the store buffer is drained
  32995. + explicitly.
  32996. +
  32997. config CACHE_TAUROS2
  32998. bool "Enable the Tauros2 L2 cache controller"
  32999. depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
  33000. diff -Nur linux-3.14.14/arch/arm/mm/l2c-common.c linux-imx6-3.14/arch/arm/mm/l2c-common.c
  33001. --- linux-3.14.14/arch/arm/mm/l2c-common.c 1969-12-31 18:00:00.000000000 -0600
  33002. +++ linux-imx6-3.14/arch/arm/mm/l2c-common.c 2014-12-08 00:31:51.392418001 -0600
  33003. @@ -0,0 +1,20 @@
  33004. +/*
  33005. + * Copyright (C) 2010 ARM Ltd.
  33006. + * Written by Catalin Marinas <catalin.marinas@arm.com>
  33007. + *
  33008. + * This program is free software; you can redistribute it and/or modify
  33009. + * it under the terms of the GNU General Public License version 2 as
  33010. + * published by the Free Software Foundation.
  33011. + */
  33012. +#include <linux/bug.h>
  33013. +#include <linux/smp.h>
  33014. +#include <asm/outercache.h>
  33015. +
  33016. +void outer_disable(void)
  33017. +{
  33018. + WARN_ON(!irqs_disabled());
  33019. + WARN_ON(num_online_cpus() > 1);
  33020. +
  33021. + if (outer_cache.disable)
  33022. + outer_cache.disable();
  33023. +}
  33024. diff -Nur linux-3.14.14/arch/arm/mm/l2c-l2x0-resume.S linux-imx6-3.14/arch/arm/mm/l2c-l2x0-resume.S
  33025. --- linux-3.14.14/arch/arm/mm/l2c-l2x0-resume.S 1969-12-31 18:00:00.000000000 -0600
  33026. +++ linux-imx6-3.14/arch/arm/mm/l2c-l2x0-resume.S 2014-12-08 00:31:51.392418001 -0600
  33027. @@ -0,0 +1,58 @@
  33028. +/*
  33029. + * L2C-310 early resume code. This can be used by platforms to restore
  33030. + * the settings of their L2 cache controller before restoring the
  33031. + * processor state.
  33032. + *
  33033. + * This code can only be used to if you are running in the secure world.
  33034. + */
  33035. +#include <linux/linkage.h>
  33036. +#include <asm/hardware/cache-l2x0.h>
  33037. +
  33038. + .text
  33039. +
  33040. +ENTRY(l2c310_early_resume)
  33041. + adr r0, 1f
  33042. + ldr r2, [r0]
  33043. + add r0, r2, r0
  33044. +
  33045. + ldmia r0, {r1, r2, r3, r4, r5, r6, r7, r8}
  33046. + @ r1 = phys address of L2C-310 controller
  33047. + @ r2 = aux_ctrl
  33048. + @ r3 = tag_latency
  33049. + @ r4 = data_latency
  33050. + @ r5 = filter_start
  33051. + @ r6 = filter_end
  33052. + @ r7 = prefetch_ctrl
  33053. + @ r8 = pwr_ctrl
  33054. +
  33055. + @ Check that the address has been initialised
  33056. + teq r1, #0
  33057. + moveq pc, lr
  33058. +
  33059. + @ The prefetch and power control registers are revision dependent
  33060. + @ and can be written whether or not the L2 cache is enabled
  33061. + ldr r0, [r1, #L2X0_CACHE_ID]
  33062. + and r0, r0, #L2X0_CACHE_ID_RTL_MASK
  33063. + cmp r0, #L310_CACHE_ID_RTL_R2P0
  33064. + strcs r7, [r1, #L310_PREFETCH_CTRL]
  33065. + cmp r0, #L310_CACHE_ID_RTL_R3P0
  33066. + strcs r8, [r1, #L310_POWER_CTRL]
  33067. +
  33068. + @ Don't setup the L2 cache if it is already enabled
  33069. + ldr r0, [r1, #L2X0_CTRL]
  33070. + tst r0, #L2X0_CTRL_EN
  33071. + movne pc, lr
  33072. +
  33073. + str r3, [r1, #L310_TAG_LATENCY_CTRL]
  33074. + str r4, [r1, #L310_DATA_LATENCY_CTRL]
  33075. + str r6, [r1, #L310_ADDR_FILTER_END]
  33076. + str r5, [r1, #L310_ADDR_FILTER_START]
  33077. +
  33078. + str r2, [r1, #L2X0_AUX_CTRL]
  33079. + mov r9, #L2X0_CTRL_EN
  33080. + str r9, [r1, #L2X0_CTRL]
  33081. + mov pc, lr
  33082. +ENDPROC(l2c310_early_resume)
  33083. +
  33084. + .align
  33085. +1: .long l2x0_saved_regs - .
  33086. diff -Nur linux-3.14.14/arch/arm/mm/Makefile linux-imx6-3.14/arch/arm/mm/Makefile
  33087. --- linux-3.14.14/arch/arm/mm/Makefile 2014-07-28 10:07:25.000000000 -0500
  33088. +++ linux-imx6-3.14/arch/arm/mm/Makefile 2014-12-08 00:31:51.388418001 -0600
  33089. @@ -95,7 +95,8 @@
  33090. AFLAGS_proc-v6.o :=-Wa,-march=armv6
  33091. AFLAGS_proc-v7.o :=-Wa,-march=armv7-a
  33092. +obj-$(CONFIG_OUTER_CACHE) += l2c-common.o
  33093. obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o
  33094. -obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
  33095. +obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o l2c-l2x0-resume.o
  33096. obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o
  33097. obj-$(CONFIG_CACHE_TAUROS2) += cache-tauros2.o
  33098. diff -Nur linux-3.14.14/arch/arm/mm/proc-v7.S linux-imx6-3.14/arch/arm/mm/proc-v7.S
  33099. --- linux-3.14.14/arch/arm/mm/proc-v7.S 2014-07-28 10:07:25.000000000 -0500
  33100. +++ linux-imx6-3.14/arch/arm/mm/proc-v7.S 2014-12-08 00:31:51.396418001 -0600
  33101. @@ -336,6 +336,17 @@
  33102. mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
  33103. 1:
  33104. #endif
  33105. +#ifdef CONFIG_ARM_ERRATA_794072
  33106. + mrc p15, 0, r10, c15, c0, 1 @ read diagnostic register
  33107. + orr r10, r10, #1 << 4 @ set bit #4
  33108. + mcr p15, 0, r10, c15, c0, 1 @ write diagnostic register
  33109. +#endif
  33110. +#ifdef CONFIG_ARM_ERRATA_761320
  33111. + cmp r6, #0x40 @ present prior to r4p0
  33112. + mrclt p15, 0, r10, c15, c0, 1 @ read diagnostic register
  33113. + orrlt r10, r10, #1 << 21 @ set bit #21
  33114. + mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
  33115. +#endif
  33116. /* Cortex-A15 Errata */
  33117. 3: ldr r10, =0x00000c0f @ Cortex-A15 primary part number
  33118. diff -Nur linux-3.14.14/arch/arm64/boot/dts/apm-mustang.dts linux-imx6-3.14/arch/arm64/boot/dts/apm-mustang.dts
  33119. --- linux-3.14.14/arch/arm64/boot/dts/apm-mustang.dts 2014-07-28 10:07:25.000000000 -0500
  33120. +++ linux-imx6-3.14/arch/arm64/boot/dts/apm-mustang.dts 2014-12-08 00:31:51.408418001 -0600
  33121. @@ -24,3 +24,7 @@
  33122. reg = < 0x1 0x00000000 0x0 0x80000000 >; /* Updated by bootloader */
  33123. };
  33124. };
  33125. +
  33126. +&serial0 {
  33127. + status = "ok";
  33128. +};
  33129. diff -Nur linux-3.14.14/arch/arm64/boot/dts/apm-storm.dtsi linux-imx6-3.14/arch/arm64/boot/dts/apm-storm.dtsi
  33130. --- linux-3.14.14/arch/arm64/boot/dts/apm-storm.dtsi 2014-07-28 10:07:25.000000000 -0500
  33131. +++ linux-imx6-3.14/arch/arm64/boot/dts/apm-storm.dtsi 2014-12-08 00:31:51.408418001 -0600
  33132. @@ -176,16 +176,226 @@
  33133. reg-names = "csr-reg";
  33134. clock-output-names = "eth8clk";
  33135. };
  33136. +
  33137. + sataphy1clk: sataphy1clk@1f21c000 {
  33138. + compatible = "apm,xgene-device-clock";
  33139. + #clock-cells = <1>;
  33140. + clocks = <&socplldiv2 0>;
  33141. + reg = <0x0 0x1f21c000 0x0 0x1000>;
  33142. + reg-names = "csr-reg";
  33143. + clock-output-names = "sataphy1clk";
  33144. + status = "disabled";
  33145. + csr-offset = <0x4>;
  33146. + csr-mask = <0x00>;
  33147. + enable-offset = <0x0>;
  33148. + enable-mask = <0x06>;
  33149. + };
  33150. +
  33151. + sataphy2clk: sataphy1clk@1f22c000 {
  33152. + compatible = "apm,xgene-device-clock";
  33153. + #clock-cells = <1>;
  33154. + clocks = <&socplldiv2 0>;
  33155. + reg = <0x0 0x1f22c000 0x0 0x1000>;
  33156. + reg-names = "csr-reg";
  33157. + clock-output-names = "sataphy2clk";
  33158. + status = "ok";
  33159. + csr-offset = <0x4>;
  33160. + csr-mask = <0x3a>;
  33161. + enable-offset = <0x0>;
  33162. + enable-mask = <0x06>;
  33163. + };
  33164. +
  33165. + sataphy3clk: sataphy1clk@1f23c000 {
  33166. + compatible = "apm,xgene-device-clock";
  33167. + #clock-cells = <1>;
  33168. + clocks = <&socplldiv2 0>;
  33169. + reg = <0x0 0x1f23c000 0x0 0x1000>;
  33170. + reg-names = "csr-reg";
  33171. + clock-output-names = "sataphy3clk";
  33172. + status = "ok";
  33173. + csr-offset = <0x4>;
  33174. + csr-mask = <0x3a>;
  33175. + enable-offset = <0x0>;
  33176. + enable-mask = <0x06>;
  33177. + };
  33178. +
  33179. + sata01clk: sata01clk@1f21c000 {
  33180. + compatible = "apm,xgene-device-clock";
  33181. + #clock-cells = <1>;
  33182. + clocks = <&socplldiv2 0>;
  33183. + reg = <0x0 0x1f21c000 0x0 0x1000>;
  33184. + reg-names = "csr-reg";
  33185. + clock-output-names = "sata01clk";
  33186. + csr-offset = <0x4>;
  33187. + csr-mask = <0x05>;
  33188. + enable-offset = <0x0>;
  33189. + enable-mask = <0x39>;
  33190. + };
  33191. +
  33192. + sata23clk: sata23clk@1f22c000 {
  33193. + compatible = "apm,xgene-device-clock";
  33194. + #clock-cells = <1>;
  33195. + clocks = <&socplldiv2 0>;
  33196. + reg = <0x0 0x1f22c000 0x0 0x1000>;
  33197. + reg-names = "csr-reg";
  33198. + clock-output-names = "sata23clk";
  33199. + csr-offset = <0x4>;
  33200. + csr-mask = <0x05>;
  33201. + enable-offset = <0x0>;
  33202. + enable-mask = <0x39>;
  33203. + };
  33204. +
  33205. + sata45clk: sata45clk@1f23c000 {
  33206. + compatible = "apm,xgene-device-clock";
  33207. + #clock-cells = <1>;
  33208. + clocks = <&socplldiv2 0>;
  33209. + reg = <0x0 0x1f23c000 0x0 0x1000>;
  33210. + reg-names = "csr-reg";
  33211. + clock-output-names = "sata45clk";
  33212. + csr-offset = <0x4>;
  33213. + csr-mask = <0x05>;
  33214. + enable-offset = <0x0>;
  33215. + enable-mask = <0x39>;
  33216. + };
  33217. +
  33218. + rtcclk: rtcclk@17000000 {
  33219. + compatible = "apm,xgene-device-clock";
  33220. + #clock-cells = <1>;
  33221. + clocks = <&socplldiv2 0>;
  33222. + reg = <0x0 0x17000000 0x0 0x2000>;
  33223. + reg-names = "csr-reg";
  33224. + csr-offset = <0xc>;
  33225. + csr-mask = <0x2>;
  33226. + enable-offset = <0x10>;
  33227. + enable-mask = <0x2>;
  33228. + clock-output-names = "rtcclk";
  33229. + };
  33230. };
  33231. serial0: serial@1c020000 {
  33232. + status = "disabled";
  33233. device_type = "serial";
  33234. - compatible = "ns16550";
  33235. + compatible = "ns16550a";
  33236. reg = <0 0x1c020000 0x0 0x1000>;
  33237. reg-shift = <2>;
  33238. clock-frequency = <10000000>; /* Updated by bootloader */
  33239. interrupt-parent = <&gic>;
  33240. interrupts = <0x0 0x4c 0x4>;
  33241. };
  33242. +
  33243. + serial1: serial@1c021000 {
  33244. + status = "disabled";
  33245. + device_type = "serial";
  33246. + compatible = "ns16550a";
  33247. + reg = <0 0x1c021000 0x0 0x1000>;
  33248. + reg-shift = <2>;
  33249. + clock-frequency = <10000000>; /* Updated by bootloader */
  33250. + interrupt-parent = <&gic>;
  33251. + interrupts = <0x0 0x4d 0x4>;
  33252. + };
  33253. +
  33254. + serial2: serial@1c022000 {
  33255. + status = "disabled";
  33256. + device_type = "serial";
  33257. + compatible = "ns16550a";
  33258. + reg = <0 0x1c022000 0x0 0x1000>;
  33259. + reg-shift = <2>;
  33260. + clock-frequency = <10000000>; /* Updated by bootloader */
  33261. + interrupt-parent = <&gic>;
  33262. + interrupts = <0x0 0x4e 0x4>;
  33263. + };
  33264. +
  33265. + serial3: serial@1c023000 {
  33266. + status = "disabled";
  33267. + device_type = "serial";
  33268. + compatible = "ns16550a";
  33269. + reg = <0 0x1c023000 0x0 0x1000>;
  33270. + reg-shift = <2>;
  33271. + clock-frequency = <10000000>; /* Updated by bootloader */
  33272. + interrupt-parent = <&gic>;
  33273. + interrupts = <0x0 0x4f 0x4>;
  33274. + };
  33275. +
  33276. + phy1: phy@1f21a000 {
  33277. + compatible = "apm,xgene-phy";
  33278. + reg = <0x0 0x1f21a000 0x0 0x100>;
  33279. + #phy-cells = <1>;
  33280. + clocks = <&sataphy1clk 0>;
  33281. + status = "disabled";
  33282. + apm,tx-boost-gain = <30 30 30 30 30 30>;
  33283. + apm,tx-eye-tuning = <2 10 10 2 10 10>;
  33284. + };
  33285. +
  33286. + phy2: phy@1f22a000 {
  33287. + compatible = "apm,xgene-phy";
  33288. + reg = <0x0 0x1f22a000 0x0 0x100>;
  33289. + #phy-cells = <1>;
  33290. + clocks = <&sataphy2clk 0>;
  33291. + status = "ok";
  33292. + apm,tx-boost-gain = <30 30 30 30 30 30>;
  33293. + apm,tx-eye-tuning = <1 10 10 2 10 10>;
  33294. + };
  33295. +
  33296. + phy3: phy@1f23a000 {
  33297. + compatible = "apm,xgene-phy";
  33298. + reg = <0x0 0x1f23a000 0x0 0x100>;
  33299. + #phy-cells = <1>;
  33300. + clocks = <&sataphy3clk 0>;
  33301. + status = "ok";
  33302. + apm,tx-boost-gain = <31 31 31 31 31 31>;
  33303. + apm,tx-eye-tuning = <2 10 10 2 10 10>;
  33304. + };
  33305. +
  33306. + sata1: sata@1a000000 {
  33307. + compatible = "apm,xgene-ahci";
  33308. + reg = <0x0 0x1a000000 0x0 0x1000>,
  33309. + <0x0 0x1f210000 0x0 0x1000>,
  33310. + <0x0 0x1f21d000 0x0 0x1000>,
  33311. + <0x0 0x1f21e000 0x0 0x1000>,
  33312. + <0x0 0x1f217000 0x0 0x1000>;
  33313. + interrupts = <0x0 0x86 0x4>;
  33314. + dma-coherent;
  33315. + status = "disabled";
  33316. + clocks = <&sata01clk 0>;
  33317. + phys = <&phy1 0>;
  33318. + phy-names = "sata-phy";
  33319. + };
  33320. +
  33321. + sata2: sata@1a400000 {
  33322. + compatible = "apm,xgene-ahci";
  33323. + reg = <0x0 0x1a400000 0x0 0x1000>,
  33324. + <0x0 0x1f220000 0x0 0x1000>,
  33325. + <0x0 0x1f22d000 0x0 0x1000>,
  33326. + <0x0 0x1f22e000 0x0 0x1000>,
  33327. + <0x0 0x1f227000 0x0 0x1000>;
  33328. + interrupts = <0x0 0x87 0x4>;
  33329. + dma-coherent;
  33330. + status = "ok";
  33331. + clocks = <&sata23clk 0>;
  33332. + phys = <&phy2 0>;
  33333. + phy-names = "sata-phy";
  33334. + };
  33335. +
  33336. + sata3: sata@1a800000 {
  33337. + compatible = "apm,xgene-ahci";
  33338. + reg = <0x0 0x1a800000 0x0 0x1000>,
  33339. + <0x0 0x1f230000 0x0 0x1000>,
  33340. + <0x0 0x1f23d000 0x0 0x1000>,
  33341. + <0x0 0x1f23e000 0x0 0x1000>;
  33342. + interrupts = <0x0 0x88 0x4>;
  33343. + dma-coherent;
  33344. + status = "ok";
  33345. + clocks = <&sata45clk 0>;
  33346. + phys = <&phy3 0>;
  33347. + phy-names = "sata-phy";
  33348. + };
  33349. +
  33350. + rtc: rtc@10510000 {
  33351. + compatible = "apm,xgene-rtc";
  33352. + reg = <0x0 0x10510000 0x0 0x400>;
  33353. + interrupts = <0x0 0x46 0x4>;
  33354. + #clock-cells = <1>;
  33355. + clocks = <&rtcclk 0>;
  33356. + };
  33357. };
  33358. };
  33359. diff -Nur linux-3.14.14/arch/arm64/boot/dts/clcd-panels.dtsi linux-imx6-3.14/arch/arm64/boot/dts/clcd-panels.dtsi
  33360. --- linux-3.14.14/arch/arm64/boot/dts/clcd-panels.dtsi 1969-12-31 18:00:00.000000000 -0600
  33361. +++ linux-imx6-3.14/arch/arm64/boot/dts/clcd-panels.dtsi 2014-12-08 00:31:51.408418001 -0600
  33362. @@ -0,0 +1,52 @@
  33363. +/*
  33364. + * ARM Ltd. Versatile Express
  33365. + *
  33366. + */
  33367. +
  33368. +/ {
  33369. + panels {
  33370. + panel@0 {
  33371. + compatible = "panel";
  33372. + mode = "VGA";
  33373. + refresh = <60>;
  33374. + xres = <640>;
  33375. + yres = <480>;
  33376. + pixclock = <39721>;
  33377. + left_margin = <40>;
  33378. + right_margin = <24>;
  33379. + upper_margin = <32>;
  33380. + lower_margin = <11>;
  33381. + hsync_len = <96>;
  33382. + vsync_len = <2>;
  33383. + sync = <0>;
  33384. + vmode = "FB_VMODE_NONINTERLACED";
  33385. +
  33386. + tim2 = "TIM2_BCD", "TIM2_IPC";
  33387. + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
  33388. + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
  33389. + bpp = <16>;
  33390. + };
  33391. +
  33392. + panel@1 {
  33393. + compatible = "panel";
  33394. + mode = "XVGA";
  33395. + refresh = <60>;
  33396. + xres = <1024>;
  33397. + yres = <768>;
  33398. + pixclock = <15748>;
  33399. + left_margin = <152>;
  33400. + right_margin = <48>;
  33401. + upper_margin = <23>;
  33402. + lower_margin = <3>;
  33403. + hsync_len = <104>;
  33404. + vsync_len = <4>;
  33405. + sync = <0>;
  33406. + vmode = "FB_VMODE_NONINTERLACED";
  33407. +
  33408. + tim2 = "TIM2_BCD", "TIM2_IPC";
  33409. + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
  33410. + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
  33411. + bpp = <16>;
  33412. + };
  33413. + };
  33414. +};
  33415. diff -Nur linux-3.14.14/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts linux-imx6-3.14/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts
  33416. --- linux-3.14.14/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts 1969-12-31 18:00:00.000000000 -0600
  33417. +++ linux-imx6-3.14/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts 2014-12-08 00:31:51.408418001 -0600
  33418. @@ -0,0 +1,266 @@
  33419. +/*
  33420. + * Copyright (c) 2013, ARM Limited. All rights reserved.
  33421. + *
  33422. + * Redistribution and use in source and binary forms, with or without
  33423. + * modification, are permitted provided that the following conditions are met:
  33424. + *
  33425. + * Redistributions of source code must retain the above copyright notice, this
  33426. + * list of conditions and the following disclaimer.
  33427. + *
  33428. + * Redistributions in binary form must reproduce the above copyright notice,
  33429. + * this list of conditions and the following disclaimer in the documentation
  33430. + * and/or other materials provided with the distribution.
  33431. + *
  33432. + * Neither the name of ARM nor the names of its contributors may be used
  33433. + * to endorse or promote products derived from this software without specific
  33434. + * prior written permission.
  33435. + *
  33436. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  33437. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33438. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33439. + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  33440. + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33441. + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33442. + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33443. + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33444. + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33445. + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33446. + * POSSIBILITY OF SUCH DAMAGE.
  33447. + */
  33448. +
  33449. +/dts-v1/;
  33450. +
  33451. +/memreserve/ 0x80000000 0x00010000;
  33452. +
  33453. +/ {
  33454. +};
  33455. +
  33456. +/ {
  33457. + model = "FVP Base";
  33458. + compatible = "arm,vfp-base", "arm,vexpress";
  33459. + interrupt-parent = <&gic>;
  33460. + #address-cells = <2>;
  33461. + #size-cells = <2>;
  33462. +
  33463. + chosen { };
  33464. +
  33465. + aliases {
  33466. + serial0 = &v2m_serial0;
  33467. + serial1 = &v2m_serial1;
  33468. + serial2 = &v2m_serial2;
  33469. + serial3 = &v2m_serial3;
  33470. + };
  33471. +
  33472. + psci {
  33473. + compatible = "arm,psci";
  33474. + method = "smc";
  33475. + cpu_suspend = <0xc4000001>;
  33476. + cpu_off = <0x84000002>;
  33477. + cpu_on = <0xc4000003>;
  33478. + };
  33479. +
  33480. + cpus {
  33481. + #address-cells = <2>;
  33482. + #size-cells = <0>;
  33483. +
  33484. + big0: cpu@0 {
  33485. + device_type = "cpu";
  33486. + compatible = "arm,cortex-a57", "arm,armv8";
  33487. + reg = <0x0 0x0>;
  33488. + enable-method = "psci";
  33489. + clock-frequency = <1000000>;
  33490. + };
  33491. + big1: cpu@1 {
  33492. + device_type = "cpu";
  33493. + compatible = "arm,cortex-a57", "arm,armv8";
  33494. + reg = <0x0 0x1>;
  33495. + enable-method = "psci";
  33496. + clock-frequency = <1000000>;
  33497. + };
  33498. + big2: cpu@2 {
  33499. + device_type = "cpu";
  33500. + compatible = "arm,cortex-a57", "arm,armv8";
  33501. + reg = <0x0 0x2>;
  33502. + enable-method = "psci";
  33503. + clock-frequency = <1000000>;
  33504. + };
  33505. + big3: cpu@3 {
  33506. + device_type = "cpu";
  33507. + compatible = "arm,cortex-a57", "arm,armv8";
  33508. + reg = <0x0 0x3>;
  33509. + enable-method = "psci";
  33510. + clock-frequency = <1000000>;
  33511. + };
  33512. + little0: cpu@100 {
  33513. + device_type = "cpu";
  33514. + compatible = "arm,cortex-a53", "arm,armv8";
  33515. + reg = <0x0 0x100>;
  33516. + enable-method = "psci";
  33517. + clock-frequency = <1000000>;
  33518. + };
  33519. + little1: cpu@101 {
  33520. + device_type = "cpu";
  33521. + compatible = "arm,cortex-a53", "arm,armv8";
  33522. + reg = <0x0 0x101>;
  33523. + enable-method = "psci";
  33524. + clock-frequency = <1000000>;
  33525. + };
  33526. + little2: cpu@102 {
  33527. + device_type = "cpu";
  33528. + compatible = "arm,cortex-a53", "arm,armv8";
  33529. + reg = <0x0 0x102>;
  33530. + enable-method = "psci";
  33531. + clock-frequency = <1000000>;
  33532. + };
  33533. + little3: cpu@103 {
  33534. + device_type = "cpu";
  33535. + compatible = "arm,cortex-a53", "arm,armv8";
  33536. + reg = <0x0 0x103>;
  33537. + enable-method = "psci";
  33538. + clock-frequency = <1000000>;
  33539. + };
  33540. +
  33541. + cpu-map {
  33542. + cluster0 {
  33543. + core0 {
  33544. + cpu = <&big0>;
  33545. + };
  33546. + core1 {
  33547. + cpu = <&big1>;
  33548. + };
  33549. + core2 {
  33550. + cpu = <&big2>;
  33551. + };
  33552. + core3 {
  33553. + cpu = <&big3>;
  33554. + };
  33555. + };
  33556. + cluster1 {
  33557. + core0 {
  33558. + cpu = <&little0>;
  33559. + };
  33560. + core1 {
  33561. + cpu = <&little1>;
  33562. + };
  33563. + core2 {
  33564. + cpu = <&little2>;
  33565. + };
  33566. + core3 {
  33567. + cpu = <&little3>;
  33568. + };
  33569. + };
  33570. + };
  33571. + };
  33572. +
  33573. + memory@80000000 {
  33574. + device_type = "memory";
  33575. + reg = <0x00000000 0x80000000 0 0x80000000>,
  33576. + <0x00000008 0x80000000 0 0x80000000>;
  33577. + };
  33578. +
  33579. + gic: interrupt-controller@2f000000 {
  33580. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  33581. + #interrupt-cells = <3>;
  33582. + #address-cells = <0>;
  33583. + interrupt-controller;
  33584. + reg = <0x0 0x2f000000 0 0x10000>,
  33585. + <0x0 0x2c000000 0 0x2000>,
  33586. + <0x0 0x2c010000 0 0x2000>,
  33587. + <0x0 0x2c02F000 0 0x2000>;
  33588. + interrupts = <1 9 0xf04>;
  33589. + };
  33590. +
  33591. + timer {
  33592. + compatible = "arm,armv8-timer";
  33593. + interrupts = <1 13 0xff01>,
  33594. + <1 14 0xff01>,
  33595. + <1 11 0xff01>,
  33596. + <1 10 0xff01>;
  33597. + clock-frequency = <100000000>;
  33598. + };
  33599. +
  33600. + timer@2a810000 {
  33601. + compatible = "arm,armv7-timer-mem";
  33602. + reg = <0x0 0x2a810000 0x0 0x10000>;
  33603. + clock-frequency = <100000000>;
  33604. + #address-cells = <2>;
  33605. + #size-cells = <2>;
  33606. + ranges;
  33607. + frame@2a820000 {
  33608. + frame-number = <0>;
  33609. + interrupts = <0 25 4>;
  33610. + reg = <0x0 0x2a820000 0x0 0x10000>;
  33611. + };
  33612. + };
  33613. +
  33614. + pmu {
  33615. + compatible = "arm,armv8-pmuv3";
  33616. + interrupts = <0 60 4>,
  33617. + <0 61 4>,
  33618. + <0 62 4>,
  33619. + <0 63 4>;
  33620. + };
  33621. +
  33622. + smb {
  33623. + compatible = "simple-bus";
  33624. +
  33625. + #address-cells = <2>;
  33626. + #size-cells = <1>;
  33627. + ranges = <0 0 0 0x08000000 0x04000000>,
  33628. + <1 0 0 0x14000000 0x04000000>,
  33629. + <2 0 0 0x18000000 0x04000000>,
  33630. + <3 0 0 0x1c000000 0x04000000>,
  33631. + <4 0 0 0x0c000000 0x04000000>,
  33632. + <5 0 0 0x10000000 0x04000000>;
  33633. +
  33634. + #interrupt-cells = <1>;
  33635. + interrupt-map-mask = <0 0 63>;
  33636. + interrupt-map = <0 0 0 &gic 0 0 4>,
  33637. + <0 0 1 &gic 0 1 4>,
  33638. + <0 0 2 &gic 0 2 4>,
  33639. + <0 0 3 &gic 0 3 4>,
  33640. + <0 0 4 &gic 0 4 4>,
  33641. + <0 0 5 &gic 0 5 4>,
  33642. + <0 0 6 &gic 0 6 4>,
  33643. + <0 0 7 &gic 0 7 4>,
  33644. + <0 0 8 &gic 0 8 4>,
  33645. + <0 0 9 &gic 0 9 4>,
  33646. + <0 0 10 &gic 0 10 4>,
  33647. + <0 0 11 &gic 0 11 4>,
  33648. + <0 0 12 &gic 0 12 4>,
  33649. + <0 0 13 &gic 0 13 4>,
  33650. + <0 0 14 &gic 0 14 4>,
  33651. + <0 0 15 &gic 0 15 4>,
  33652. + <0 0 16 &gic 0 16 4>,
  33653. + <0 0 17 &gic 0 17 4>,
  33654. + <0 0 18 &gic 0 18 4>,
  33655. + <0 0 19 &gic 0 19 4>,
  33656. + <0 0 20 &gic 0 20 4>,
  33657. + <0 0 21 &gic 0 21 4>,
  33658. + <0 0 22 &gic 0 22 4>,
  33659. + <0 0 23 &gic 0 23 4>,
  33660. + <0 0 24 &gic 0 24 4>,
  33661. + <0 0 25 &gic 0 25 4>,
  33662. + <0 0 26 &gic 0 26 4>,
  33663. + <0 0 27 &gic 0 27 4>,
  33664. + <0 0 28 &gic 0 28 4>,
  33665. + <0 0 29 &gic 0 29 4>,
  33666. + <0 0 30 &gic 0 30 4>,
  33667. + <0 0 31 &gic 0 31 4>,
  33668. + <0 0 32 &gic 0 32 4>,
  33669. + <0 0 33 &gic 0 33 4>,
  33670. + <0 0 34 &gic 0 34 4>,
  33671. + <0 0 35 &gic 0 35 4>,
  33672. + <0 0 36 &gic 0 36 4>,
  33673. + <0 0 37 &gic 0 37 4>,
  33674. + <0 0 38 &gic 0 38 4>,
  33675. + <0 0 39 &gic 0 39 4>,
  33676. + <0 0 40 &gic 0 40 4>,
  33677. + <0 0 41 &gic 0 41 4>,
  33678. + <0 0 42 &gic 0 42 4>;
  33679. +
  33680. + /include/ "rtsm_ve-motherboard.dtsi"
  33681. + };
  33682. +};
  33683. +
  33684. +/include/ "clcd-panels.dtsi"
  33685. diff -Nur linux-3.14.14/arch/arm64/boot/dts/juno.dts linux-imx6-3.14/arch/arm64/boot/dts/juno.dts
  33686. --- linux-3.14.14/arch/arm64/boot/dts/juno.dts 1969-12-31 18:00:00.000000000 -0600
  33687. +++ linux-imx6-3.14/arch/arm64/boot/dts/juno.dts 2014-12-08 00:31:51.408418001 -0600
  33688. @@ -0,0 +1,498 @@
  33689. +/*
  33690. + * ARM Ltd. Juno Plaform
  33691. + *
  33692. + * Fast Models FVP v2 support
  33693. + */
  33694. +
  33695. +/dts-v1/;
  33696. +
  33697. +#include <dt-bindings/interrupt-controller/arm-gic.h>
  33698. +
  33699. +/ {
  33700. + model = "Juno";
  33701. + compatible = "arm,juno", "arm,vexpress";
  33702. + interrupt-parent = <&gic>;
  33703. + #address-cells = <2>;
  33704. + #size-cells = <2>;
  33705. +
  33706. + aliases {
  33707. + serial0 = &soc_uart0;
  33708. + };
  33709. +
  33710. + cpus {
  33711. + #address-cells = <2>;
  33712. + #size-cells = <0>;
  33713. +
  33714. + cpu@100 {
  33715. + device_type = "cpu";
  33716. + compatible = "arm,cortex-a53","arm,armv8";
  33717. + reg = <0x0 0x100>;
  33718. + enable-method = "psci";
  33719. + };
  33720. +
  33721. + cpu@101 {
  33722. + device_type = "cpu";
  33723. + compatible = "arm,cortex-a53","arm,armv8";
  33724. + reg = <0x0 0x101>;
  33725. + enable-method = "psci";
  33726. + };
  33727. +
  33728. + cpu@102 {
  33729. + device_type = "cpu";
  33730. + compatible = "arm,cortex-a53","arm,armv8";
  33731. + reg = <0x0 0x102>;
  33732. + enable-method = "psci";
  33733. + };
  33734. +
  33735. + cpu@103 {
  33736. + device_type = "cpu";
  33737. + compatible = "arm,cortex-a53","arm,armv8";
  33738. + reg = <0x0 0x103>;
  33739. + enable-method = "psci";
  33740. + };
  33741. +
  33742. + cpu@0 {
  33743. + device_type = "cpu";
  33744. + compatible = "arm,cortex-a57","arm,armv8";
  33745. + reg = <0x0 0x0>;
  33746. + enable-method = "psci";
  33747. + };
  33748. +
  33749. + cpu@1 {
  33750. + device_type = "cpu";
  33751. + compatible = "arm,cortex-a57","arm,armv8";
  33752. + reg = <0x0 0x1>;
  33753. + enable-method = "psci";
  33754. + };
  33755. + };
  33756. +
  33757. + memory@80000000 {
  33758. + device_type = "memory";
  33759. + reg = <0x00000000 0x80000000 0x0 0x80000000>,
  33760. + <0x00000008 0x80000000 0x1 0x80000000>;
  33761. + };
  33762. +
  33763. + /* memory@14000000 {
  33764. + device_type = "memory";
  33765. + reg = <0x00000000 0x14000000 0x0 0x02000000>;
  33766. + }; */
  33767. +
  33768. + gic: interrupt-controller@2c001000 {
  33769. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  33770. + #interrupt-cells = <3>;
  33771. + #address-cells = <0>;
  33772. + interrupt-controller;
  33773. + reg = <0x0 0x2c010000 0 0x1000>,
  33774. + <0x0 0x2c02f000 0 0x1000>,
  33775. + <0x0 0x2c04f000 0 0x2000>,
  33776. + <0x0 0x2c06f000 0 0x2000>;
  33777. + interrupts = <GIC_PPI 9 0xf04>;
  33778. + };
  33779. +
  33780. + msi0: msi@2c1c0000 {
  33781. + compatible = "arm,gic-msi";
  33782. + reg = <0x0 0x2c1c0000 0 0x10000
  33783. + 0x0 0x2c1d0000 0 0x10000
  33784. + 0x0 0x2c1e0000 0 0x10000
  33785. + 0x0 0x2c1f0000 0 0x10000>;
  33786. + };
  33787. +
  33788. + timer {
  33789. + compatible = "arm,armv8-timer";
  33790. + interrupts = <GIC_PPI 13 0xff01>,
  33791. + <GIC_PPI 14 0xff01>,
  33792. + <GIC_PPI 11 0xff01>,
  33793. + <GIC_PPI 10 0xff01>;
  33794. + };
  33795. +
  33796. + pmu {
  33797. + compatible = "arm,armv8-pmuv3";
  33798. + interrupts = <GIC_SPI 60 4>,
  33799. + <GIC_SPI 61 4>,
  33800. + <GIC_SPI 62 4>,
  33801. + <GIC_SPI 63 4>;
  33802. + };
  33803. +
  33804. + psci {
  33805. + compatible = "arm,psci";
  33806. + method = "smc";
  33807. + cpu_suspend = <0xC4000001>;
  33808. + cpu_off = <0x84000002>;
  33809. + cpu_on = <0xC4000003>;
  33810. + migrate = <0xC4000005>;
  33811. + };
  33812. +
  33813. + pci0: pci@30000000 {
  33814. + compatible = "arm,pcie-xr3";
  33815. + device_type = "pci";
  33816. + reg = <0 0x7ff30000 0 0x1000
  33817. + 0 0x7ff20000 0 0x10000
  33818. + 0 0x40000000 0 0x10000000>;
  33819. + bus-range = <0 255>;
  33820. + #address-cells = <3>;
  33821. + #size-cells = <2>;
  33822. + ranges = <0x01000000 0x0 0x00000000 0x00 0x5ff00000 0x0 0x00100000
  33823. + 0x02000000 0x0 0x00000000 0x40 0x00000000 0x0 0x80000000
  33824. + 0x42000000 0x0 0x80000000 0x40 0x80000000 0x0 0x80000000>;
  33825. + #interrupt-cells = <1>;
  33826. + interrupt-map-mask = <0 0 0 7>;
  33827. + interrupt-map = <0 0 0 1 &gic 0 136 4
  33828. + 0 0 0 2 &gic 0 137 4
  33829. + 0 0 0 3 &gic 0 138 4
  33830. + 0 0 0 4 &gic 0 139 4>;
  33831. + };
  33832. +
  33833. + scpi: scpi@2b1f0000 {
  33834. + compatible = "arm,scpi-mhu";
  33835. + reg = <0x0 0x2b1f0000 0x0 0x10000>, /* MHU registers */
  33836. + <0x0 0x2e000000 0x0 0x10000>; /* Payload area */
  33837. + interrupts = <0 36 4>, /* low priority interrupt */
  33838. + <0 35 4>, /* high priority interrupt */
  33839. + <0 37 4>; /* secure channel interrupt */
  33840. + #clock-cells = <1>;
  33841. + clock-output-names = "a57", "a53", "gpu", "hdlcd0", "hdlcd1";
  33842. + };
  33843. +
  33844. + hdlcd0_osc: scpi_osc@3 {
  33845. + compatible = "arm,scpi-osc";
  33846. + #clock-cells = <0>;
  33847. + clocks = <&scpi 3>;
  33848. + frequency-range = <23000000 210000000>;
  33849. + clock-output-names = "pxlclk0";
  33850. + };
  33851. +
  33852. + hdlcd1_osc: scpi_osc@4 {
  33853. + compatible = "arm,scpi-osc";
  33854. + #clock-cells = <0>;
  33855. + clocks = <&scpi 4>;
  33856. + frequency-range = <23000000 210000000>;
  33857. + clock-output-names = "pxlclk1";
  33858. + };
  33859. +
  33860. + soc_uartclk: refclk72738khz {
  33861. + compatible = "fixed-clock";
  33862. + #clock-cells = <0>;
  33863. + clock-frequency = <7273800>;
  33864. + clock-output-names = "juno:uartclk";
  33865. + };
  33866. +
  33867. + soc_refclk24mhz: clk24mhz {
  33868. + compatible = "fixed-clock";
  33869. + #clock-cells = <0>;
  33870. + clock-frequency = <24000000>;
  33871. + clock-output-names = "juno:clk24mhz";
  33872. + };
  33873. +
  33874. + mb_eth25mhz: clk25mhz {
  33875. + compatible = "fixed-clock";
  33876. + #clock-cells = <0>;
  33877. + clock-frequency = <25000000>;
  33878. + clock-output-names = "ethclk25mhz";
  33879. + };
  33880. +
  33881. + soc_usb48mhz: clk48mhz {
  33882. + compatible = "fixed-clock";
  33883. + #clock-cells = <0>;
  33884. + clock-frequency = <48000000>;
  33885. + clock-output-names = "clk48mhz";
  33886. + };
  33887. +
  33888. + soc_smc50mhz: clk50mhz {
  33889. + compatible = "fixed-clock";
  33890. + #clock-cells = <0>;
  33891. + clock-frequency = <50000000>;
  33892. + clock-output-names = "smc_clk";
  33893. + };
  33894. +
  33895. + soc_refclk100mhz: refclk100mhz {
  33896. + compatible = "fixed-clock";
  33897. + #clock-cells = <0>;
  33898. + clock-frequency = <100000000>;
  33899. + clock-output-names = "apb_pclk";
  33900. + };
  33901. +
  33902. + soc_faxiclk: refclk533mhz {
  33903. + compatible = "fixed-clock";
  33904. + #clock-cells = <0>;
  33905. + clock-frequency = <533000000>;
  33906. + clock-output-names = "faxi_clk";
  33907. + };
  33908. +
  33909. + soc_fixed_3v3: fixedregulator@0 {
  33910. + compatible = "regulator-fixed";
  33911. + regulator-name = "3V3";
  33912. + regulator-min-microvolt = <3300000>;
  33913. + regulator-max-microvolt = <3300000>;
  33914. + regulator-always-on;
  33915. + };
  33916. +
  33917. + memory-controller@7ffd0000 {
  33918. + compatible = "arm,pl354", "arm,primecell";
  33919. + reg = <0 0x7ffd0000 0 0x1000>;
  33920. + interrupts = <0 86 4>,
  33921. + <0 87 4>;
  33922. + clocks = <&soc_smc50mhz>;
  33923. + clock-names = "apb_pclk";
  33924. + chip5-memwidth = <16>;
  33925. + };
  33926. +
  33927. + dma0: dma@0x7ff00000 {
  33928. + compatible = "arm,pl330", "arm,primecell";
  33929. + reg = <0x0 0x7ff00000 0 0x1000>;
  33930. + interrupts = <0 95 4>,
  33931. + <0 88 4>,
  33932. + <0 89 4>,
  33933. + <0 90 4>,
  33934. + <0 91 4>,
  33935. + <0 108 4>,
  33936. + <0 109 4>,
  33937. + <0 110 4>,
  33938. + <0 111 4>;
  33939. + #dma-cells = <1>;
  33940. + #dma-channels = <8>;
  33941. + #dma-requests = <32>;
  33942. + clocks = <&soc_faxiclk>;
  33943. + clock-names = "apb_pclk";
  33944. + };
  33945. +
  33946. + soc_uart0: uart@7ff80000 {
  33947. + compatible = "arm,pl011", "arm,primecell";
  33948. + reg = <0x0 0x7ff80000 0x0 0x1000>;
  33949. + interrupts = <0 83 4>;
  33950. + clocks = <&soc_uartclk>, <&soc_refclk100mhz>;
  33951. + clock-names = "uartclk", "apb_pclk";
  33952. + dmas = <&dma0 1
  33953. + &dma0 2>;
  33954. + dma-names = "rx", "tx";
  33955. + };
  33956. +
  33957. + /* this UART is reserved for secure software.
  33958. + soc_uart1: uart@7ff70000 {
  33959. + compatible = "arm,pl011", "arm,primecell";
  33960. + reg = <0x0 0x7ff70000 0x0 0x1000>;
  33961. + interrupts = <0 84 4>;
  33962. + clocks = <&soc_uartclk>, <&soc_refclk100mhz>;
  33963. + clock-names = "uartclk", "apb_pclk";
  33964. + }; */
  33965. +
  33966. + ulpi_phy: phy@0 {
  33967. + compatible = "phy-ulpi-generic";
  33968. + reg = <0x0 0x94 0x0 0x4>;
  33969. + phy-id = <0>;
  33970. + };
  33971. +
  33972. + ehci@7ffc0000 {
  33973. + compatible = "snps,ehci-h20ahb";
  33974. + /* compatible = "arm,h20ahb-ehci"; */
  33975. + reg = <0x0 0x7ffc0000 0x0 0x10000>;
  33976. + interrupts = <0 117 4>;
  33977. + clocks = <&soc_usb48mhz>;
  33978. + clock-names = "otg";
  33979. + phys = <&ulpi_phy>;
  33980. + };
  33981. +
  33982. + ohci@0x7ffb0000 {
  33983. + compatible = "generic-ohci";
  33984. + reg = <0x0 0x7ffb0000 0x0 0x10000>;
  33985. + interrupts = <0 116 4>;
  33986. + clocks = <&soc_usb48mhz>;
  33987. + clock-names = "otg";
  33988. + };
  33989. +
  33990. + i2c@0x7ffa0000 {
  33991. + #address-cells = <1>;
  33992. + #size-cells = <0>;
  33993. + compatible = "snps,designware-i2c";
  33994. + reg = <0x0 0x7ffa0000 0x0 0x1000>;
  33995. + interrupts = <0 104 4>;
  33996. + clock-frequency = <400000>;
  33997. + i2c-sda-hold-time-ns = <500>;
  33998. + clocks = <&soc_smc50mhz>;
  33999. +
  34000. + dvi0: dvi-transmitter@70 {
  34001. + compatible = "nxp,tda998x";
  34002. + reg = <0x70>;
  34003. + };
  34004. +
  34005. + dvi1: dvi-transmitter@71 {
  34006. + compatible = "nxp,tda998x";
  34007. + reg = <0x71>;
  34008. + };
  34009. + };
  34010. +
  34011. + /* mmci@1c050000 {
  34012. + compatible = "arm,pl180", "arm,primecell";
  34013. + reg = <0x0 0x1c050000 0x0 0x1000>;
  34014. + interrupts = <0 73 4>,
  34015. + <0 74 4>;
  34016. + max-frequency = <12000000>;
  34017. + vmmc-supply = <&soc_fixed_3v3>;
  34018. + clocks = <&soc_refclk24mhz>, <&soc_refclk100mhz>;
  34019. + clock-names = "mclk", "apb_pclk";
  34020. + }; */
  34021. +
  34022. + hdlcd@7ff60000 {
  34023. + compatible = "arm,hdlcd";
  34024. + reg = <0 0x7ff60000 0 0x1000>;
  34025. + interrupts = <0 85 4>;
  34026. + clocks = <&hdlcd0_osc>;
  34027. + clock-names = "pxlclk";
  34028. + i2c-slave = <&dvi0>;
  34029. +
  34030. + /* display-timings {
  34031. + native-mode = <&timing0>;
  34032. + timing0: timing@0 {
  34033. + /* 1024 x 768 framebufer, standard VGA timings * /
  34034. + clock-frequency = <65000>;
  34035. + hactive = <1024>;
  34036. + vactive = <768>;
  34037. + hfront-porch = <24>;
  34038. + hback-porch = <160>;
  34039. + hsync-len = <136>;
  34040. + vfront-porch = <3>;
  34041. + vback-porch = <29>;
  34042. + vsync-len = <6>;
  34043. + };
  34044. + }; */
  34045. + };
  34046. +
  34047. + hdlcd@7ff50000 {
  34048. + compatible = "arm,hdlcd";
  34049. + reg = <0 0x7ff50000 0 0x1000>;
  34050. + interrupts = <0 93 4>;
  34051. + clocks = <&hdlcd1_osc>;
  34052. + clock-names = "pxlclk";
  34053. + i2c-slave = <&dvi1>;
  34054. +
  34055. + display-timings {
  34056. + native-mode = <&timing1>;
  34057. + timing1: timing@1 {
  34058. + /* 1024 x 768 framebufer, standard VGA timings */
  34059. + clock-frequency = <65000>;
  34060. + hactive = <1024>;
  34061. + vactive = <768>;
  34062. + hfront-porch = <24>;
  34063. + hback-porch = <160>;
  34064. + hsync-len = <136>;
  34065. + vfront-porch = <3>;
  34066. + vback-porch = <29>;
  34067. + vsync-len = <6>;
  34068. + };
  34069. + };
  34070. + };
  34071. +
  34072. + smb {
  34073. + compatible = "simple-bus";
  34074. + #address-cells = <2>;
  34075. + #size-cells = <1>;
  34076. + ranges = <0 0 0 0x08000000 0x04000000>,
  34077. + <1 0 0 0x14000000 0x04000000>,
  34078. + <2 0 0 0x18000000 0x04000000>,
  34079. + <3 0 0 0x1c000000 0x04000000>,
  34080. + <4 0 0 0x0c000000 0x04000000>,
  34081. + <5 0 0 0x10000000 0x04000000>;
  34082. +
  34083. + #interrupt-cells = <1>;
  34084. + interrupt-map-mask = <0 0 15>;
  34085. + interrupt-map = <0 0 0 &gic 0 68 4>,
  34086. + <0 0 1 &gic 0 69 4>,
  34087. + <0 0 2 &gic 0 70 4>,
  34088. + <0 0 3 &gic 0 160 4>,
  34089. + <0 0 4 &gic 0 161 4>,
  34090. + <0 0 5 &gic 0 162 4>,
  34091. + <0 0 6 &gic 0 163 4>,
  34092. + <0 0 7 &gic 0 164 4>,
  34093. + <0 0 8 &gic 0 165 4>,
  34094. + <0 0 9 &gic 0 166 4>,
  34095. + <0 0 10 &gic 0 167 4>,
  34096. + <0 0 11 &gic 0 168 4>,
  34097. + <0 0 12 &gic 0 169 4>;
  34098. +
  34099. + motherboard {
  34100. + model = "V2M-Juno";
  34101. + arm,hbi = <0x252>;
  34102. + arm,vexpress,site = <0>;
  34103. + arm,v2m-memory-map = "rs1";
  34104. + compatible = "arm,vexpress,v2p-p1", "simple-bus";
  34105. + #address-cells = <2>; /* SMB chipselect number and offset */
  34106. + #size-cells = <1>;
  34107. + #interrupt-cells = <1>;
  34108. + ranges;
  34109. +
  34110. + usb@5,00000000 {
  34111. + compatible = "nxp,usb-isp1763";
  34112. + reg = <5 0x00000000 0x20000>;
  34113. + bus-width = <16>;
  34114. + interrupts = <4>;
  34115. + };
  34116. +
  34117. + ethernet@2,00000000 {
  34118. + compatible = "smsc,lan9118", "smsc,lan9115";
  34119. + reg = <2 0x00000000 0x10000>;
  34120. + interrupts = <3>;
  34121. + phy-mode = "mii";
  34122. + reg-io-width = <4>;
  34123. + smsc,irq-active-high;
  34124. + smsc,irq-push-pull;
  34125. + clocks = <&mb_eth25mhz>;
  34126. + vdd33a-supply = <&soc_fixed_3v3>; /* change this */
  34127. + vddvario-supply = <&soc_fixed_3v3>; /* and this */
  34128. + };
  34129. +
  34130. + iofpga@3,00000000 {
  34131. + compatible = "arm,amba-bus", "simple-bus";
  34132. + #address-cells = <1>;
  34133. + #size-cells = <1>;
  34134. + ranges = <0 3 0 0x200000>;
  34135. +
  34136. + kmi@060000 {
  34137. + compatible = "arm,pl050", "arm,primecell";
  34138. + reg = <0x060000 0x1000>;
  34139. + interrupts = <8>;
  34140. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34141. + clock-names = "KMIREFCLK", "apb_pclk";
  34142. + };
  34143. +
  34144. + kmi@070000 {
  34145. + compatible = "arm,pl050", "arm,primecell";
  34146. + reg = <0x070000 0x1000>;
  34147. + interrupts = <8>;
  34148. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34149. + clock-names = "KMIREFCLK", "apb_pclk";
  34150. + };
  34151. +
  34152. + wdt@0f0000 {
  34153. + compatible = "arm,sp805", "arm,primecell";
  34154. + reg = <0x0f0000 0x10000>;
  34155. + interrupts = <7>;
  34156. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34157. + clock-names = "wdogclk", "apb_pclk";
  34158. + };
  34159. +
  34160. + v2m_timer01: timer@110000 {
  34161. + compatible = "arm,sp804", "arm,primecell";
  34162. + reg = <0x110000 0x10000>;
  34163. + interrupts = <9>;
  34164. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34165. + clock-names = "timclken1", "apb_pclk";
  34166. + };
  34167. +
  34168. + v2m_timer23: timer@120000 {
  34169. + compatible = "arm,sp804", "arm,primecell";
  34170. + reg = <0x120000 0x10000>;
  34171. + interrupts = <9>;
  34172. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34173. + clock-names = "timclken1", "apb_pclk";
  34174. + };
  34175. +
  34176. + rtc@170000 {
  34177. + compatible = "arm,pl031", "arm,primecell";
  34178. + reg = <0x170000 0x10000>;
  34179. + interrupts = <0>;
  34180. + clocks = <&soc_smc50mhz>;
  34181. + clock-names = "apb_pclk";
  34182. + };
  34183. + };
  34184. + };
  34185. + };
  34186. +};
  34187. diff -Nur linux-3.14.14/arch/arm64/boot/dts/Makefile linux-imx6-3.14/arch/arm64/boot/dts/Makefile
  34188. --- linux-3.14.14/arch/arm64/boot/dts/Makefile 2014-07-28 10:07:25.000000000 -0500
  34189. +++ linux-imx6-3.14/arch/arm64/boot/dts/Makefile 2014-12-08 00:31:51.408418001 -0600
  34190. @@ -1,5 +1,7 @@
  34191. -dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb
  34192. +dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb \
  34193. + fvp-base-gicv2-psci.dtb
  34194. dtb-$(CONFIG_ARCH_XGENE) += apm-mustang.dtb
  34195. +dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb
  34196. targets += dtbs
  34197. targets += $(dtb-y)
  34198. diff -Nur linux-3.14.14/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts linux-imx6-3.14/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts
  34199. --- linux-3.14.14/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts 2014-07-28 10:07:25.000000000 -0500
  34200. +++ linux-imx6-3.14/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts 2014-12-08 00:31:51.408418001 -0600
  34201. @@ -157,3 +157,5 @@
  34202. /include/ "rtsm_ve-motherboard.dtsi"
  34203. };
  34204. };
  34205. +
  34206. +/include/ "clcd-panels.dtsi"
  34207. diff -Nur linux-3.14.14/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi linux-imx6-3.14/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi
  34208. --- linux-3.14.14/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi 2014-07-28 10:07:25.000000000 -0500
  34209. +++ linux-imx6-3.14/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi 2014-12-08 00:31:51.408418001 -0600
  34210. @@ -182,6 +182,9 @@
  34211. interrupts = <14>;
  34212. clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
  34213. clock-names = "clcdclk", "apb_pclk";
  34214. + mode = "XVGA";
  34215. + use_dma = <0>;
  34216. + framebuffer = <0x18000000 0x00180000>;
  34217. };
  34218. virtio_block@0130000 {
  34219. diff -Nur linux-3.14.14/arch/arm64/crypto/aes-ce-ccm-core.S linux-imx6-3.14/arch/arm64/crypto/aes-ce-ccm-core.S
  34220. --- linux-3.14.14/arch/arm64/crypto/aes-ce-ccm-core.S 1969-12-31 18:00:00.000000000 -0600
  34221. +++ linux-imx6-3.14/arch/arm64/crypto/aes-ce-ccm-core.S 2014-12-08 00:31:51.412418001 -0600
  34222. @@ -0,0 +1,222 @@
  34223. +/*
  34224. + * aesce-ccm-core.S - AES-CCM transform for ARMv8 with Crypto Extensions
  34225. + *
  34226. + * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  34227. + *
  34228. + * This program is free software; you can redistribute it and/or modify
  34229. + * it under the terms of the GNU General Public License version 2 as
  34230. + * published by the Free Software Foundation.
  34231. + */
  34232. +
  34233. +#include <linux/linkage.h>
  34234. +
  34235. + .text
  34236. + .arch armv8-a+crypto
  34237. +
  34238. + /*
  34239. + * void ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
  34240. + * u32 *macp, u8 const rk[], u32 rounds);
  34241. + */
  34242. +ENTRY(ce_aes_ccm_auth_data)
  34243. + ldr w8, [x3] /* leftover from prev round? */
  34244. + ld1 {v0.2d}, [x0] /* load mac */
  34245. + cbz w8, 1f
  34246. + sub w8, w8, #16
  34247. + eor v1.16b, v1.16b, v1.16b
  34248. +0: ldrb w7, [x1], #1 /* get 1 byte of input */
  34249. + subs w2, w2, #1
  34250. + add w8, w8, #1
  34251. + ins v1.b[0], w7
  34252. + ext v1.16b, v1.16b, v1.16b, #1 /* rotate in the input bytes */
  34253. + beq 8f /* out of input? */
  34254. + cbnz w8, 0b
  34255. + eor v0.16b, v0.16b, v1.16b
  34256. +1: ld1 {v3.2d}, [x4] /* load first round key */
  34257. + prfm pldl1strm, [x1]
  34258. + cmp w5, #12 /* which key size? */
  34259. + add x6, x4, #16
  34260. + sub w7, w5, #2 /* modified # of rounds */
  34261. + bmi 2f
  34262. + bne 5f
  34263. + mov v5.16b, v3.16b
  34264. + b 4f
  34265. +2: mov v4.16b, v3.16b
  34266. + ld1 {v5.2d}, [x6], #16 /* load 2nd round key */
  34267. +3: aese v0.16b, v4.16b
  34268. + aesmc v0.16b, v0.16b
  34269. +4: ld1 {v3.2d}, [x6], #16 /* load next round key */
  34270. + aese v0.16b, v5.16b
  34271. + aesmc v0.16b, v0.16b
  34272. +5: ld1 {v4.2d}, [x6], #16 /* load next round key */
  34273. + subs w7, w7, #3
  34274. + aese v0.16b, v3.16b
  34275. + aesmc v0.16b, v0.16b
  34276. + ld1 {v5.2d}, [x6], #16 /* load next round key */
  34277. + bpl 3b
  34278. + aese v0.16b, v4.16b
  34279. + subs w2, w2, #16 /* last data? */
  34280. + eor v0.16b, v0.16b, v5.16b /* final round */
  34281. + bmi 6f
  34282. + ld1 {v1.16b}, [x1], #16 /* load next input block */
  34283. + eor v0.16b, v0.16b, v1.16b /* xor with mac */
  34284. + bne 1b
  34285. +6: st1 {v0.2d}, [x0] /* store mac */
  34286. + beq 10f
  34287. + adds w2, w2, #16
  34288. + beq 10f
  34289. + mov w8, w2
  34290. +7: ldrb w7, [x1], #1
  34291. + umov w6, v0.b[0]
  34292. + eor w6, w6, w7
  34293. + strb w6, [x0], #1
  34294. + subs w2, w2, #1
  34295. + beq 10f
  34296. + ext v0.16b, v0.16b, v0.16b, #1 /* rotate out the mac bytes */
  34297. + b 7b
  34298. +8: mov w7, w8
  34299. + add w8, w8, #16
  34300. +9: ext v1.16b, v1.16b, v1.16b, #1
  34301. + adds w7, w7, #1
  34302. + bne 9b
  34303. + eor v0.16b, v0.16b, v1.16b
  34304. + st1 {v0.2d}, [x0]
  34305. +10: str w8, [x3]
  34306. + ret
  34307. +ENDPROC(ce_aes_ccm_auth_data)
  34308. +
  34309. + /*
  34310. + * void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u8 const rk[],
  34311. + * u32 rounds);
  34312. + */
  34313. +ENTRY(ce_aes_ccm_final)
  34314. + ld1 {v3.2d}, [x2], #16 /* load first round key */
  34315. + ld1 {v0.2d}, [x0] /* load mac */
  34316. + cmp w3, #12 /* which key size? */
  34317. + sub w3, w3, #2 /* modified # of rounds */
  34318. + ld1 {v1.2d}, [x1] /* load 1st ctriv */
  34319. + bmi 0f
  34320. + bne 3f
  34321. + mov v5.16b, v3.16b
  34322. + b 2f
  34323. +0: mov v4.16b, v3.16b
  34324. +1: ld1 {v5.2d}, [x2], #16 /* load next round key */
  34325. + aese v0.16b, v4.16b
  34326. + aese v1.16b, v4.16b
  34327. + aesmc v0.16b, v0.16b
  34328. + aesmc v1.16b, v1.16b
  34329. +2: ld1 {v3.2d}, [x2], #16 /* load next round key */
  34330. + aese v0.16b, v5.16b
  34331. + aese v1.16b, v5.16b
  34332. + aesmc v0.16b, v0.16b
  34333. + aesmc v1.16b, v1.16b
  34334. +3: ld1 {v4.2d}, [x2], #16 /* load next round key */
  34335. + subs w3, w3, #3
  34336. + aese v0.16b, v3.16b
  34337. + aese v1.16b, v3.16b
  34338. + aesmc v0.16b, v0.16b
  34339. + aesmc v1.16b, v1.16b
  34340. + bpl 1b
  34341. + aese v0.16b, v4.16b
  34342. + aese v1.16b, v4.16b
  34343. + /* final round key cancels out */
  34344. + eor v0.16b, v0.16b, v1.16b /* en-/decrypt the mac */
  34345. + st1 {v0.2d}, [x0] /* store result */
  34346. + ret
  34347. +ENDPROC(ce_aes_ccm_final)
  34348. +
  34349. + .macro aes_ccm_do_crypt,enc
  34350. + ldr x8, [x6, #8] /* load lower ctr */
  34351. + ld1 {v0.2d}, [x5] /* load mac */
  34352. + rev x8, x8 /* keep swabbed ctr in reg */
  34353. +0: /* outer loop */
  34354. + ld1 {v1.1d}, [x6] /* load upper ctr */
  34355. + prfm pldl1strm, [x1]
  34356. + add x8, x8, #1
  34357. + rev x9, x8
  34358. + cmp w4, #12 /* which key size? */
  34359. + sub w7, w4, #2 /* get modified # of rounds */
  34360. + ins v1.d[1], x9 /* no carry in lower ctr */
  34361. + ld1 {v3.2d}, [x3] /* load first round key */
  34362. + add x10, x3, #16
  34363. + bmi 1f
  34364. + bne 4f
  34365. + mov v5.16b, v3.16b
  34366. + b 3f
  34367. +1: mov v4.16b, v3.16b
  34368. + ld1 {v5.2d}, [x10], #16 /* load 2nd round key */
  34369. +2: /* inner loop: 3 rounds, 2x interleaved */
  34370. + aese v0.16b, v4.16b
  34371. + aese v1.16b, v4.16b
  34372. + aesmc v0.16b, v0.16b
  34373. + aesmc v1.16b, v1.16b
  34374. +3: ld1 {v3.2d}, [x10], #16 /* load next round key */
  34375. + aese v0.16b, v5.16b
  34376. + aese v1.16b, v5.16b
  34377. + aesmc v0.16b, v0.16b
  34378. + aesmc v1.16b, v1.16b
  34379. +4: ld1 {v4.2d}, [x10], #16 /* load next round key */
  34380. + subs w7, w7, #3
  34381. + aese v0.16b, v3.16b
  34382. + aese v1.16b, v3.16b
  34383. + aesmc v0.16b, v0.16b
  34384. + aesmc v1.16b, v1.16b
  34385. + ld1 {v5.2d}, [x10], #16 /* load next round key */
  34386. + bpl 2b
  34387. + aese v0.16b, v4.16b
  34388. + aese v1.16b, v4.16b
  34389. + subs w2, w2, #16
  34390. + bmi 6f /* partial block? */
  34391. + ld1 {v2.16b}, [x1], #16 /* load next input block */
  34392. + .if \enc == 1
  34393. + eor v2.16b, v2.16b, v5.16b /* final round enc+mac */
  34394. + eor v1.16b, v1.16b, v2.16b /* xor with crypted ctr */
  34395. + .else
  34396. + eor v2.16b, v2.16b, v1.16b /* xor with crypted ctr */
  34397. + eor v1.16b, v2.16b, v5.16b /* final round enc */
  34398. + .endif
  34399. + eor v0.16b, v0.16b, v2.16b /* xor mac with pt ^ rk[last] */
  34400. + st1 {v1.16b}, [x0], #16 /* write output block */
  34401. + bne 0b
  34402. + rev x8, x8
  34403. + st1 {v0.2d}, [x5] /* store mac */
  34404. + str x8, [x6, #8] /* store lsb end of ctr (BE) */
  34405. +5: ret
  34406. +
  34407. +6: eor v0.16b, v0.16b, v5.16b /* final round mac */
  34408. + eor v1.16b, v1.16b, v5.16b /* final round enc */
  34409. + st1 {v0.2d}, [x5] /* store mac */
  34410. + add w2, w2, #16 /* process partial tail block */
  34411. +7: ldrb w9, [x1], #1 /* get 1 byte of input */
  34412. + umov w6, v1.b[0] /* get top crypted ctr byte */
  34413. + umov w7, v0.b[0] /* get top mac byte */
  34414. + .if \enc == 1
  34415. + eor w7, w7, w9
  34416. + eor w9, w9, w6
  34417. + .else
  34418. + eor w9, w9, w6
  34419. + eor w7, w7, w9
  34420. + .endif
  34421. + strb w9, [x0], #1 /* store out byte */
  34422. + strb w7, [x5], #1 /* store mac byte */
  34423. + subs w2, w2, #1
  34424. + beq 5b
  34425. + ext v0.16b, v0.16b, v0.16b, #1 /* shift out mac byte */
  34426. + ext v1.16b, v1.16b, v1.16b, #1 /* shift out ctr byte */
  34427. + b 7b
  34428. + .endm
  34429. +
  34430. + /*
  34431. + * void ce_aes_ccm_encrypt(u8 out[], u8 const in[], u32 cbytes,
  34432. + * u8 const rk[], u32 rounds, u8 mac[],
  34433. + * u8 ctr[]);
  34434. + * void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes,
  34435. + * u8 const rk[], u32 rounds, u8 mac[],
  34436. + * u8 ctr[]);
  34437. + */
  34438. +ENTRY(ce_aes_ccm_encrypt)
  34439. + aes_ccm_do_crypt 1
  34440. +ENDPROC(ce_aes_ccm_encrypt)
  34441. +
  34442. +ENTRY(ce_aes_ccm_decrypt)
  34443. + aes_ccm_do_crypt 0
  34444. +ENDPROC(ce_aes_ccm_decrypt)
  34445. diff -Nur linux-3.14.14/arch/arm64/crypto/aes-ce-ccm-glue.c linux-imx6-3.14/arch/arm64/crypto/aes-ce-ccm-glue.c
  34446. --- linux-3.14.14/arch/arm64/crypto/aes-ce-ccm-glue.c 1969-12-31 18:00:00.000000000 -0600
  34447. +++ linux-imx6-3.14/arch/arm64/crypto/aes-ce-ccm-glue.c 2014-12-08 00:31:51.412418001 -0600
  34448. @@ -0,0 +1,297 @@
  34449. +/*
  34450. + * aes-ccm-glue.c - AES-CCM transform for ARMv8 with Crypto Extensions
  34451. + *
  34452. + * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  34453. + *
  34454. + * This program is free software; you can redistribute it and/or modify
  34455. + * it under the terms of the GNU General Public License version 2 as
  34456. + * published by the Free Software Foundation.
  34457. + */
  34458. +
  34459. +#include <asm/neon.h>
  34460. +#include <asm/unaligned.h>
  34461. +#include <crypto/aes.h>
  34462. +#include <crypto/algapi.h>
  34463. +#include <crypto/scatterwalk.h>
  34464. +#include <linux/crypto.h>
  34465. +#include <linux/module.h>
  34466. +
  34467. +static int num_rounds(struct crypto_aes_ctx *ctx)
  34468. +{
  34469. + /*
  34470. + * # of rounds specified by AES:
  34471. + * 128 bit key 10 rounds
  34472. + * 192 bit key 12 rounds
  34473. + * 256 bit key 14 rounds
  34474. + * => n byte key => 6 + (n/4) rounds
  34475. + */
  34476. + return 6 + ctx->key_length / 4;
  34477. +}
  34478. +
  34479. +asmlinkage void ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
  34480. + u32 *macp, u32 const rk[], u32 rounds);
  34481. +
  34482. +asmlinkage void ce_aes_ccm_encrypt(u8 out[], u8 const in[], u32 cbytes,
  34483. + u32 const rk[], u32 rounds, u8 mac[],
  34484. + u8 ctr[]);
  34485. +
  34486. +asmlinkage void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes,
  34487. + u32 const rk[], u32 rounds, u8 mac[],
  34488. + u8 ctr[]);
  34489. +
  34490. +asmlinkage void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u32 const rk[],
  34491. + u32 rounds);
  34492. +
  34493. +static int ccm_setkey(struct crypto_aead *tfm, const u8 *in_key,
  34494. + unsigned int key_len)
  34495. +{
  34496. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(tfm);
  34497. + int ret;
  34498. +
  34499. + ret = crypto_aes_expand_key(ctx, in_key, key_len);
  34500. + if (!ret)
  34501. + return 0;
  34502. +
  34503. + tfm->base.crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  34504. + return -EINVAL;
  34505. +}
  34506. +
  34507. +static int ccm_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
  34508. +{
  34509. + if ((authsize & 1) || authsize < 4)
  34510. + return -EINVAL;
  34511. + return 0;
  34512. +}
  34513. +
  34514. +static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen)
  34515. +{
  34516. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34517. + __be32 *n = (__be32 *)&maciv[AES_BLOCK_SIZE - 8];
  34518. + u32 l = req->iv[0] + 1;
  34519. +
  34520. + /* verify that CCM dimension 'L' is set correctly in the IV */
  34521. + if (l < 2 || l > 8)
  34522. + return -EINVAL;
  34523. +
  34524. + /* verify that msglen can in fact be represented in L bytes */
  34525. + if (l < 4 && msglen >> (8 * l))
  34526. + return -EOVERFLOW;
  34527. +
  34528. + /*
  34529. + * Even if the CCM spec allows L values of up to 8, the Linux cryptoapi
  34530. + * uses a u32 type to represent msglen so the top 4 bytes are always 0.
  34531. + */
  34532. + n[0] = 0;
  34533. + n[1] = cpu_to_be32(msglen);
  34534. +
  34535. + memcpy(maciv, req->iv, AES_BLOCK_SIZE - l);
  34536. +
  34537. + /*
  34538. + * Meaning of byte 0 according to CCM spec (RFC 3610/NIST 800-38C)
  34539. + * - bits 0..2 : max # of bytes required to represent msglen, minus 1
  34540. + * (already set by caller)
  34541. + * - bits 3..5 : size of auth tag (1 => 4 bytes, 2 => 6 bytes, etc)
  34542. + * - bit 6 : indicates presence of authenticate-only data
  34543. + */
  34544. + maciv[0] |= (crypto_aead_authsize(aead) - 2) << 2;
  34545. + if (req->assoclen)
  34546. + maciv[0] |= 0x40;
  34547. +
  34548. + memset(&req->iv[AES_BLOCK_SIZE - l], 0, l);
  34549. + return 0;
  34550. +}
  34551. +
  34552. +static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
  34553. +{
  34554. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34555. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead);
  34556. + struct __packed { __be16 l; __be32 h; u16 len; } ltag;
  34557. + struct scatter_walk walk;
  34558. + u32 len = req->assoclen;
  34559. + u32 macp = 0;
  34560. +
  34561. + /* prepend the AAD with a length tag */
  34562. + if (len < 0xff00) {
  34563. + ltag.l = cpu_to_be16(len);
  34564. + ltag.len = 2;
  34565. + } else {
  34566. + ltag.l = cpu_to_be16(0xfffe);
  34567. + put_unaligned_be32(len, &ltag.h);
  34568. + ltag.len = 6;
  34569. + }
  34570. +
  34571. + ce_aes_ccm_auth_data(mac, (u8 *)&ltag, ltag.len, &macp, ctx->key_enc,
  34572. + num_rounds(ctx));
  34573. + scatterwalk_start(&walk, req->assoc);
  34574. +
  34575. + do {
  34576. + u32 n = scatterwalk_clamp(&walk, len);
  34577. + u8 *p;
  34578. +
  34579. + if (!n) {
  34580. + scatterwalk_start(&walk, sg_next(walk.sg));
  34581. + n = scatterwalk_clamp(&walk, len);
  34582. + }
  34583. + p = scatterwalk_map(&walk);
  34584. + ce_aes_ccm_auth_data(mac, p, n, &macp, ctx->key_enc,
  34585. + num_rounds(ctx));
  34586. + len -= n;
  34587. +
  34588. + scatterwalk_unmap(p);
  34589. + scatterwalk_advance(&walk, n);
  34590. + scatterwalk_done(&walk, 0, len);
  34591. + } while (len);
  34592. +}
  34593. +
  34594. +static int ccm_encrypt(struct aead_request *req)
  34595. +{
  34596. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34597. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead);
  34598. + struct blkcipher_desc desc = { .info = req->iv };
  34599. + struct blkcipher_walk walk;
  34600. + u8 __aligned(8) mac[AES_BLOCK_SIZE];
  34601. + u8 buf[AES_BLOCK_SIZE];
  34602. + u32 len = req->cryptlen;
  34603. + int err;
  34604. +
  34605. + err = ccm_init_mac(req, mac, len);
  34606. + if (err)
  34607. + return err;
  34608. +
  34609. + kernel_neon_begin_partial(6);
  34610. +
  34611. + if (req->assoclen)
  34612. + ccm_calculate_auth_mac(req, mac);
  34613. +
  34614. + /* preserve the original iv for the final round */
  34615. + memcpy(buf, req->iv, AES_BLOCK_SIZE);
  34616. +
  34617. + blkcipher_walk_init(&walk, req->dst, req->src, len);
  34618. + err = blkcipher_aead_walk_virt_block(&desc, &walk, aead,
  34619. + AES_BLOCK_SIZE);
  34620. +
  34621. + while (walk.nbytes) {
  34622. + u32 tail = walk.nbytes % AES_BLOCK_SIZE;
  34623. +
  34624. + if (walk.nbytes == len)
  34625. + tail = 0;
  34626. +
  34627. + ce_aes_ccm_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  34628. + walk.nbytes - tail, ctx->key_enc,
  34629. + num_rounds(ctx), mac, walk.iv);
  34630. +
  34631. + len -= walk.nbytes - tail;
  34632. + err = blkcipher_walk_done(&desc, &walk, tail);
  34633. + }
  34634. + if (!err)
  34635. + ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
  34636. +
  34637. + kernel_neon_end();
  34638. +
  34639. + if (err)
  34640. + return err;
  34641. +
  34642. + /* copy authtag to end of dst */
  34643. + scatterwalk_map_and_copy(mac, req->dst, req->cryptlen,
  34644. + crypto_aead_authsize(aead), 1);
  34645. +
  34646. + return 0;
  34647. +}
  34648. +
  34649. +static int ccm_decrypt(struct aead_request *req)
  34650. +{
  34651. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34652. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead);
  34653. + unsigned int authsize = crypto_aead_authsize(aead);
  34654. + struct blkcipher_desc desc = { .info = req->iv };
  34655. + struct blkcipher_walk walk;
  34656. + u8 __aligned(8) mac[AES_BLOCK_SIZE];
  34657. + u8 buf[AES_BLOCK_SIZE];
  34658. + u32 len = req->cryptlen - authsize;
  34659. + int err;
  34660. +
  34661. + err = ccm_init_mac(req, mac, len);
  34662. + if (err)
  34663. + return err;
  34664. +
  34665. + kernel_neon_begin_partial(6);
  34666. +
  34667. + if (req->assoclen)
  34668. + ccm_calculate_auth_mac(req, mac);
  34669. +
  34670. + /* preserve the original iv for the final round */
  34671. + memcpy(buf, req->iv, AES_BLOCK_SIZE);
  34672. +
  34673. + blkcipher_walk_init(&walk, req->dst, req->src, len);
  34674. + err = blkcipher_aead_walk_virt_block(&desc, &walk, aead,
  34675. + AES_BLOCK_SIZE);
  34676. +
  34677. + while (walk.nbytes) {
  34678. + u32 tail = walk.nbytes % AES_BLOCK_SIZE;
  34679. +
  34680. + if (walk.nbytes == len)
  34681. + tail = 0;
  34682. +
  34683. + ce_aes_ccm_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  34684. + walk.nbytes - tail, ctx->key_enc,
  34685. + num_rounds(ctx), mac, walk.iv);
  34686. +
  34687. + len -= walk.nbytes - tail;
  34688. + err = blkcipher_walk_done(&desc, &walk, tail);
  34689. + }
  34690. + if (!err)
  34691. + ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
  34692. +
  34693. + kernel_neon_end();
  34694. +
  34695. + if (err)
  34696. + return err;
  34697. +
  34698. + /* compare calculated auth tag with the stored one */
  34699. + scatterwalk_map_and_copy(buf, req->src, req->cryptlen - authsize,
  34700. + authsize, 0);
  34701. +
  34702. + if (memcmp(mac, buf, authsize))
  34703. + return -EBADMSG;
  34704. + return 0;
  34705. +}
  34706. +
  34707. +static struct crypto_alg ccm_aes_alg = {
  34708. + .cra_name = "ccm(aes)",
  34709. + .cra_driver_name = "ccm-aes-ce",
  34710. + .cra_priority = 300,
  34711. + .cra_flags = CRYPTO_ALG_TYPE_AEAD,
  34712. + .cra_blocksize = 1,
  34713. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  34714. + .cra_alignmask = 7,
  34715. + .cra_type = &crypto_aead_type,
  34716. + .cra_module = THIS_MODULE,
  34717. + .cra_aead = {
  34718. + .ivsize = AES_BLOCK_SIZE,
  34719. + .maxauthsize = AES_BLOCK_SIZE,
  34720. + .setkey = ccm_setkey,
  34721. + .setauthsize = ccm_setauthsize,
  34722. + .encrypt = ccm_encrypt,
  34723. + .decrypt = ccm_decrypt,
  34724. + }
  34725. +};
  34726. +
  34727. +static int __init aes_mod_init(void)
  34728. +{
  34729. + if (!(elf_hwcap & HWCAP_AES))
  34730. + return -ENODEV;
  34731. + return crypto_register_alg(&ccm_aes_alg);
  34732. +}
  34733. +
  34734. +static void __exit aes_mod_exit(void)
  34735. +{
  34736. + crypto_unregister_alg(&ccm_aes_alg);
  34737. +}
  34738. +
  34739. +module_init(aes_mod_init);
  34740. +module_exit(aes_mod_exit);
  34741. +
  34742. +MODULE_DESCRIPTION("Synchronous AES in CCM mode using ARMv8 Crypto Extensions");
  34743. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  34744. +MODULE_LICENSE("GPL v2");
  34745. +MODULE_ALIAS("ccm(aes)");
  34746. diff -Nur linux-3.14.14/arch/arm64/crypto/aes-ce-cipher.c linux-imx6-3.14/arch/arm64/crypto/aes-ce-cipher.c
  34747. --- linux-3.14.14/arch/arm64/crypto/aes-ce-cipher.c 1969-12-31 18:00:00.000000000 -0600
  34748. +++ linux-imx6-3.14/arch/arm64/crypto/aes-ce-cipher.c 2014-12-08 00:31:51.412418001 -0600
  34749. @@ -0,0 +1,155 @@
  34750. +/*
  34751. + * aes-ce-cipher.c - core AES cipher using ARMv8 Crypto Extensions
  34752. + *
  34753. + * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  34754. + *
  34755. + * This program is free software; you can redistribute it and/or modify
  34756. + * it under the terms of the GNU General Public License version 2 as
  34757. + * published by the Free Software Foundation.
  34758. + */
  34759. +
  34760. +#include <asm/neon.h>
  34761. +#include <crypto/aes.h>
  34762. +#include <linux/cpufeature.h>
  34763. +#include <linux/crypto.h>
  34764. +#include <linux/module.h>
  34765. +
  34766. +MODULE_DESCRIPTION("Synchronous AES cipher using ARMv8 Crypto Extensions");
  34767. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  34768. +MODULE_LICENSE("GPL v2");
  34769. +
  34770. +struct aes_block {
  34771. + u8 b[AES_BLOCK_SIZE];
  34772. +};
  34773. +
  34774. +static int num_rounds(struct crypto_aes_ctx *ctx)
  34775. +{
  34776. + /*
  34777. + * # of rounds specified by AES:
  34778. + * 128 bit key 10 rounds
  34779. + * 192 bit key 12 rounds
  34780. + * 256 bit key 14 rounds
  34781. + * => n byte key => 6 + (n/4) rounds
  34782. + */
  34783. + return 6 + ctx->key_length / 4;
  34784. +}
  34785. +
  34786. +static void aes_cipher_encrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[])
  34787. +{
  34788. + struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
  34789. + struct aes_block *out = (struct aes_block *)dst;
  34790. + struct aes_block const *in = (struct aes_block *)src;
  34791. + void *dummy0;
  34792. + int dummy1;
  34793. +
  34794. + kernel_neon_begin_partial(4);
  34795. +
  34796. + __asm__(" ld1 {v0.16b}, %[in] ;"
  34797. + " ld1 {v1.2d}, [%[key]], #16 ;"
  34798. + " cmp %w[rounds], #10 ;"
  34799. + " bmi 0f ;"
  34800. + " bne 3f ;"
  34801. + " mov v3.16b, v1.16b ;"
  34802. + " b 2f ;"
  34803. + "0: mov v2.16b, v1.16b ;"
  34804. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34805. + "1: aese v0.16b, v2.16b ;"
  34806. + " aesmc v0.16b, v0.16b ;"
  34807. + "2: ld1 {v1.2d}, [%[key]], #16 ;"
  34808. + " aese v0.16b, v3.16b ;"
  34809. + " aesmc v0.16b, v0.16b ;"
  34810. + "3: ld1 {v2.2d}, [%[key]], #16 ;"
  34811. + " subs %w[rounds], %w[rounds], #3 ;"
  34812. + " aese v0.16b, v1.16b ;"
  34813. + " aesmc v0.16b, v0.16b ;"
  34814. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34815. + " bpl 1b ;"
  34816. + " aese v0.16b, v2.16b ;"
  34817. + " eor v0.16b, v0.16b, v3.16b ;"
  34818. + " st1 {v0.16b}, %[out] ;"
  34819. +
  34820. + : [out] "=Q"(*out),
  34821. + [key] "=r"(dummy0),
  34822. + [rounds] "=r"(dummy1)
  34823. + : [in] "Q"(*in),
  34824. + "1"(ctx->key_enc),
  34825. + "2"(num_rounds(ctx) - 2)
  34826. + : "cc");
  34827. +
  34828. + kernel_neon_end();
  34829. +}
  34830. +
  34831. +static void aes_cipher_decrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[])
  34832. +{
  34833. + struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
  34834. + struct aes_block *out = (struct aes_block *)dst;
  34835. + struct aes_block const *in = (struct aes_block *)src;
  34836. + void *dummy0;
  34837. + int dummy1;
  34838. +
  34839. + kernel_neon_begin_partial(4);
  34840. +
  34841. + __asm__(" ld1 {v0.16b}, %[in] ;"
  34842. + " ld1 {v1.2d}, [%[key]], #16 ;"
  34843. + " cmp %w[rounds], #10 ;"
  34844. + " bmi 0f ;"
  34845. + " bne 3f ;"
  34846. + " mov v3.16b, v1.16b ;"
  34847. + " b 2f ;"
  34848. + "0: mov v2.16b, v1.16b ;"
  34849. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34850. + "1: aesd v0.16b, v2.16b ;"
  34851. + " aesimc v0.16b, v0.16b ;"
  34852. + "2: ld1 {v1.2d}, [%[key]], #16 ;"
  34853. + " aesd v0.16b, v3.16b ;"
  34854. + " aesimc v0.16b, v0.16b ;"
  34855. + "3: ld1 {v2.2d}, [%[key]], #16 ;"
  34856. + " subs %w[rounds], %w[rounds], #3 ;"
  34857. + " aesd v0.16b, v1.16b ;"
  34858. + " aesimc v0.16b, v0.16b ;"
  34859. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34860. + " bpl 1b ;"
  34861. + " aesd v0.16b, v2.16b ;"
  34862. + " eor v0.16b, v0.16b, v3.16b ;"
  34863. + " st1 {v0.16b}, %[out] ;"
  34864. +
  34865. + : [out] "=Q"(*out),
  34866. + [key] "=r"(dummy0),
  34867. + [rounds] "=r"(dummy1)
  34868. + : [in] "Q"(*in),
  34869. + "1"(ctx->key_dec),
  34870. + "2"(num_rounds(ctx) - 2)
  34871. + : "cc");
  34872. +
  34873. + kernel_neon_end();
  34874. +}
  34875. +
  34876. +static struct crypto_alg aes_alg = {
  34877. + .cra_name = "aes",
  34878. + .cra_driver_name = "aes-ce",
  34879. + .cra_priority = 300,
  34880. + .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
  34881. + .cra_blocksize = AES_BLOCK_SIZE,
  34882. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  34883. + .cra_module = THIS_MODULE,
  34884. + .cra_cipher = {
  34885. + .cia_min_keysize = AES_MIN_KEY_SIZE,
  34886. + .cia_max_keysize = AES_MAX_KEY_SIZE,
  34887. + .cia_setkey = crypto_aes_set_key,
  34888. + .cia_encrypt = aes_cipher_encrypt,
  34889. + .cia_decrypt = aes_cipher_decrypt
  34890. + }
  34891. +};
  34892. +
  34893. +static int __init aes_mod_init(void)
  34894. +{
  34895. + return crypto_register_alg(&aes_alg);
  34896. +}
  34897. +
  34898. +static void __exit aes_mod_exit(void)
  34899. +{
  34900. + crypto_unregister_alg(&aes_alg);
  34901. +}
  34902. +
  34903. +module_cpu_feature_match(AES, aes_mod_init);
  34904. +module_exit(aes_mod_exit);
  34905. diff -Nur linux-3.14.14/arch/arm64/crypto/aes-ce.S linux-imx6-3.14/arch/arm64/crypto/aes-ce.S
  34906. --- linux-3.14.14/arch/arm64/crypto/aes-ce.S 1969-12-31 18:00:00.000000000 -0600
  34907. +++ linux-imx6-3.14/arch/arm64/crypto/aes-ce.S 2014-12-08 00:31:51.412418001 -0600
  34908. @@ -0,0 +1,133 @@
  34909. +/*
  34910. + * linux/arch/arm64/crypto/aes-ce.S - AES cipher for ARMv8 with
  34911. + * Crypto Extensions
  34912. + *
  34913. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  34914. + *
  34915. + * This program is free software; you can redistribute it and/or modify
  34916. + * it under the terms of the GNU General Public License version 2 as
  34917. + * published by the Free Software Foundation.
  34918. + */
  34919. +
  34920. +#include <linux/linkage.h>
  34921. +
  34922. +#define AES_ENTRY(func) ENTRY(ce_ ## func)
  34923. +#define AES_ENDPROC(func) ENDPROC(ce_ ## func)
  34924. +
  34925. + .arch armv8-a+crypto
  34926. +
  34927. + /* preload all round keys */
  34928. + .macro load_round_keys, rounds, rk
  34929. + cmp \rounds, #12
  34930. + blo 2222f /* 128 bits */
  34931. + beq 1111f /* 192 bits */
  34932. + ld1 {v17.16b-v18.16b}, [\rk], #32
  34933. +1111: ld1 {v19.16b-v20.16b}, [\rk], #32
  34934. +2222: ld1 {v21.16b-v24.16b}, [\rk], #64
  34935. + ld1 {v25.16b-v28.16b}, [\rk], #64
  34936. + ld1 {v29.16b-v31.16b}, [\rk]
  34937. + .endm
  34938. +
  34939. + /* prepare for encryption with key in rk[] */
  34940. + .macro enc_prepare, rounds, rk, ignore
  34941. + load_round_keys \rounds, \rk
  34942. + .endm
  34943. +
  34944. + /* prepare for encryption (again) but with new key in rk[] */
  34945. + .macro enc_switch_key, rounds, rk, ignore
  34946. + load_round_keys \rounds, \rk
  34947. + .endm
  34948. +
  34949. + /* prepare for decryption with key in rk[] */
  34950. + .macro dec_prepare, rounds, rk, ignore
  34951. + load_round_keys \rounds, \rk
  34952. + .endm
  34953. +
  34954. + .macro do_enc_Nx, de, mc, k, i0, i1, i2, i3
  34955. + aes\de \i0\().16b, \k\().16b
  34956. + .ifnb \i1
  34957. + aes\de \i1\().16b, \k\().16b
  34958. + .ifnb \i3
  34959. + aes\de \i2\().16b, \k\().16b
  34960. + aes\de \i3\().16b, \k\().16b
  34961. + .endif
  34962. + .endif
  34963. + aes\mc \i0\().16b, \i0\().16b
  34964. + .ifnb \i1
  34965. + aes\mc \i1\().16b, \i1\().16b
  34966. + .ifnb \i3
  34967. + aes\mc \i2\().16b, \i2\().16b
  34968. + aes\mc \i3\().16b, \i3\().16b
  34969. + .endif
  34970. + .endif
  34971. + .endm
  34972. +
  34973. + /* up to 4 interleaved encryption rounds with the same round key */
  34974. + .macro round_Nx, enc, k, i0, i1, i2, i3
  34975. + .ifc \enc, e
  34976. + do_enc_Nx e, mc, \k, \i0, \i1, \i2, \i3
  34977. + .else
  34978. + do_enc_Nx d, imc, \k, \i0, \i1, \i2, \i3
  34979. + .endif
  34980. + .endm
  34981. +
  34982. + /* up to 4 interleaved final rounds */
  34983. + .macro fin_round_Nx, de, k, k2, i0, i1, i2, i3
  34984. + aes\de \i0\().16b, \k\().16b
  34985. + .ifnb \i1
  34986. + aes\de \i1\().16b, \k\().16b
  34987. + .ifnb \i3
  34988. + aes\de \i2\().16b, \k\().16b
  34989. + aes\de \i3\().16b, \k\().16b
  34990. + .endif
  34991. + .endif
  34992. + eor \i0\().16b, \i0\().16b, \k2\().16b
  34993. + .ifnb \i1
  34994. + eor \i1\().16b, \i1\().16b, \k2\().16b
  34995. + .ifnb \i3
  34996. + eor \i2\().16b, \i2\().16b, \k2\().16b
  34997. + eor \i3\().16b, \i3\().16b, \k2\().16b
  34998. + .endif
  34999. + .endif
  35000. + .endm
  35001. +
  35002. + /* up to 4 interleaved blocks */
  35003. + .macro do_block_Nx, enc, rounds, i0, i1, i2, i3
  35004. + cmp \rounds, #12
  35005. + blo 2222f /* 128 bits */
  35006. + beq 1111f /* 192 bits */
  35007. + round_Nx \enc, v17, \i0, \i1, \i2, \i3
  35008. + round_Nx \enc, v18, \i0, \i1, \i2, \i3
  35009. +1111: round_Nx \enc, v19, \i0, \i1, \i2, \i3
  35010. + round_Nx \enc, v20, \i0, \i1, \i2, \i3
  35011. +2222: .irp key, v21, v22, v23, v24, v25, v26, v27, v28, v29
  35012. + round_Nx \enc, \key, \i0, \i1, \i2, \i3
  35013. + .endr
  35014. + fin_round_Nx \enc, v30, v31, \i0, \i1, \i2, \i3
  35015. + .endm
  35016. +
  35017. + .macro encrypt_block, in, rounds, t0, t1, t2
  35018. + do_block_Nx e, \rounds, \in
  35019. + .endm
  35020. +
  35021. + .macro encrypt_block2x, i0, i1, rounds, t0, t1, t2
  35022. + do_block_Nx e, \rounds, \i0, \i1
  35023. + .endm
  35024. +
  35025. + .macro encrypt_block4x, i0, i1, i2, i3, rounds, t0, t1, t2
  35026. + do_block_Nx e, \rounds, \i0, \i1, \i2, \i3
  35027. + .endm
  35028. +
  35029. + .macro decrypt_block, in, rounds, t0, t1, t2
  35030. + do_block_Nx d, \rounds, \in
  35031. + .endm
  35032. +
  35033. + .macro decrypt_block2x, i0, i1, rounds, t0, t1, t2
  35034. + do_block_Nx d, \rounds, \i0, \i1
  35035. + .endm
  35036. +
  35037. + .macro decrypt_block4x, i0, i1, i2, i3, rounds, t0, t1, t2
  35038. + do_block_Nx d, \rounds, \i0, \i1, \i2, \i3
  35039. + .endm
  35040. +
  35041. +#include "aes-modes.S"
  35042. diff -Nur linux-3.14.14/arch/arm64/crypto/aes-glue.c linux-imx6-3.14/arch/arm64/crypto/aes-glue.c
  35043. --- linux-3.14.14/arch/arm64/crypto/aes-glue.c 1969-12-31 18:00:00.000000000 -0600
  35044. +++ linux-imx6-3.14/arch/arm64/crypto/aes-glue.c 2014-12-08 00:31:51.412418001 -0600
  35045. @@ -0,0 +1,446 @@
  35046. +/*
  35047. + * linux/arch/arm64/crypto/aes-glue.c - wrapper code for ARMv8 AES
  35048. + *
  35049. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  35050. + *
  35051. + * This program is free software; you can redistribute it and/or modify
  35052. + * it under the terms of the GNU General Public License version 2 as
  35053. + * published by the Free Software Foundation.
  35054. + */
  35055. +
  35056. +#include <asm/neon.h>
  35057. +#include <asm/hwcap.h>
  35058. +#include <crypto/aes.h>
  35059. +#include <crypto/ablk_helper.h>
  35060. +#include <crypto/algapi.h>
  35061. +#include <linux/module.h>
  35062. +#include <linux/cpufeature.h>
  35063. +
  35064. +#ifdef USE_V8_CRYPTO_EXTENSIONS
  35065. +#define MODE "ce"
  35066. +#define PRIO 300
  35067. +#define aes_ecb_encrypt ce_aes_ecb_encrypt
  35068. +#define aes_ecb_decrypt ce_aes_ecb_decrypt
  35069. +#define aes_cbc_encrypt ce_aes_cbc_encrypt
  35070. +#define aes_cbc_decrypt ce_aes_cbc_decrypt
  35071. +#define aes_ctr_encrypt ce_aes_ctr_encrypt
  35072. +#define aes_xts_encrypt ce_aes_xts_encrypt
  35073. +#define aes_xts_decrypt ce_aes_xts_decrypt
  35074. +MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
  35075. +#else
  35076. +#define MODE "neon"
  35077. +#define PRIO 200
  35078. +#define aes_ecb_encrypt neon_aes_ecb_encrypt
  35079. +#define aes_ecb_decrypt neon_aes_ecb_decrypt
  35080. +#define aes_cbc_encrypt neon_aes_cbc_encrypt
  35081. +#define aes_cbc_decrypt neon_aes_cbc_decrypt
  35082. +#define aes_ctr_encrypt neon_aes_ctr_encrypt
  35083. +#define aes_xts_encrypt neon_aes_xts_encrypt
  35084. +#define aes_xts_decrypt neon_aes_xts_decrypt
  35085. +MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 NEON");
  35086. +MODULE_ALIAS("ecb(aes)");
  35087. +MODULE_ALIAS("cbc(aes)");
  35088. +MODULE_ALIAS("ctr(aes)");
  35089. +MODULE_ALIAS("xts(aes)");
  35090. +#endif
  35091. +
  35092. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  35093. +MODULE_LICENSE("GPL v2");
  35094. +
  35095. +/* defined in aes-modes.S */
  35096. +asmlinkage void aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[],
  35097. + int rounds, int blocks, int first);
  35098. +asmlinkage void aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[],
  35099. + int rounds, int blocks, int first);
  35100. +
  35101. +asmlinkage void aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[],
  35102. + int rounds, int blocks, u8 iv[], int first);
  35103. +asmlinkage void aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
  35104. + int rounds, int blocks, u8 iv[], int first);
  35105. +
  35106. +asmlinkage void aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
  35107. + int rounds, int blocks, u8 ctr[], int first);
  35108. +
  35109. +asmlinkage void aes_xts_encrypt(u8 out[], u8 const in[], u8 const rk1[],
  35110. + int rounds, int blocks, u8 const rk2[], u8 iv[],
  35111. + int first);
  35112. +asmlinkage void aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[],
  35113. + int rounds, int blocks, u8 const rk2[], u8 iv[],
  35114. + int first);
  35115. +
  35116. +struct crypto_aes_xts_ctx {
  35117. + struct crypto_aes_ctx key1;
  35118. + struct crypto_aes_ctx __aligned(8) key2;
  35119. +};
  35120. +
  35121. +static int xts_set_key(struct crypto_tfm *tfm, const u8 *in_key,
  35122. + unsigned int key_len)
  35123. +{
  35124. + struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
  35125. + int ret;
  35126. +
  35127. + ret = crypto_aes_expand_key(&ctx->key1, in_key, key_len / 2);
  35128. + if (!ret)
  35129. + ret = crypto_aes_expand_key(&ctx->key2, &in_key[key_len / 2],
  35130. + key_len / 2);
  35131. + if (!ret)
  35132. + return 0;
  35133. +
  35134. + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  35135. + return -EINVAL;
  35136. +}
  35137. +
  35138. +static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35139. + struct scatterlist *src, unsigned int nbytes)
  35140. +{
  35141. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35142. + int err, first, rounds = 6 + ctx->key_length / 4;
  35143. + struct blkcipher_walk walk;
  35144. + unsigned int blocks;
  35145. +
  35146. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35147. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35148. + err = blkcipher_walk_virt(desc, &walk);
  35149. +
  35150. + kernel_neon_begin();
  35151. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35152. + aes_ecb_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35153. + (u8 *)ctx->key_enc, rounds, blocks, first);
  35154. + err = blkcipher_walk_done(desc, &walk, 0);
  35155. + }
  35156. + kernel_neon_end();
  35157. + return err;
  35158. +}
  35159. +
  35160. +static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35161. + struct scatterlist *src, unsigned int nbytes)
  35162. +{
  35163. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35164. + int err, first, rounds = 6 + ctx->key_length / 4;
  35165. + struct blkcipher_walk walk;
  35166. + unsigned int blocks;
  35167. +
  35168. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35169. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35170. + err = blkcipher_walk_virt(desc, &walk);
  35171. +
  35172. + kernel_neon_begin();
  35173. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35174. + aes_ecb_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35175. + (u8 *)ctx->key_dec, rounds, blocks, first);
  35176. + err = blkcipher_walk_done(desc, &walk, 0);
  35177. + }
  35178. + kernel_neon_end();
  35179. + return err;
  35180. +}
  35181. +
  35182. +static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35183. + struct scatterlist *src, unsigned int nbytes)
  35184. +{
  35185. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35186. + int err, first, rounds = 6 + ctx->key_length / 4;
  35187. + struct blkcipher_walk walk;
  35188. + unsigned int blocks;
  35189. +
  35190. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35191. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35192. + err = blkcipher_walk_virt(desc, &walk);
  35193. +
  35194. + kernel_neon_begin();
  35195. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35196. + aes_cbc_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35197. + (u8 *)ctx->key_enc, rounds, blocks, walk.iv,
  35198. + first);
  35199. + err = blkcipher_walk_done(desc, &walk, 0);
  35200. + }
  35201. + kernel_neon_end();
  35202. + return err;
  35203. +}
  35204. +
  35205. +static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35206. + struct scatterlist *src, unsigned int nbytes)
  35207. +{
  35208. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35209. + int err, first, rounds = 6 + ctx->key_length / 4;
  35210. + struct blkcipher_walk walk;
  35211. + unsigned int blocks;
  35212. +
  35213. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35214. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35215. + err = blkcipher_walk_virt(desc, &walk);
  35216. +
  35217. + kernel_neon_begin();
  35218. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35219. + aes_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35220. + (u8 *)ctx->key_dec, rounds, blocks, walk.iv,
  35221. + first);
  35222. + err = blkcipher_walk_done(desc, &walk, 0);
  35223. + }
  35224. + kernel_neon_end();
  35225. + return err;
  35226. +}
  35227. +
  35228. +static int ctr_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35229. + struct scatterlist *src, unsigned int nbytes)
  35230. +{
  35231. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35232. + int err, first, rounds = 6 + ctx->key_length / 4;
  35233. + struct blkcipher_walk walk;
  35234. + int blocks;
  35235. +
  35236. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35237. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35238. + err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE);
  35239. +
  35240. + first = 1;
  35241. + kernel_neon_begin();
  35242. + while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
  35243. + aes_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35244. + (u8 *)ctx->key_enc, rounds, blocks, walk.iv,
  35245. + first);
  35246. + first = 0;
  35247. + nbytes -= blocks * AES_BLOCK_SIZE;
  35248. + if (nbytes && nbytes == walk.nbytes % AES_BLOCK_SIZE)
  35249. + break;
  35250. + err = blkcipher_walk_done(desc, &walk,
  35251. + walk.nbytes % AES_BLOCK_SIZE);
  35252. + }
  35253. + if (nbytes) {
  35254. + u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
  35255. + u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
  35256. + u8 __aligned(8) tail[AES_BLOCK_SIZE];
  35257. +
  35258. + /*
  35259. + * Minimum alignment is 8 bytes, so if nbytes is <= 8, we need
  35260. + * to tell aes_ctr_encrypt() to only read half a block.
  35261. + */
  35262. + blocks = (nbytes <= 8) ? -1 : 1;
  35263. +
  35264. + aes_ctr_encrypt(tail, tsrc, (u8 *)ctx->key_enc, rounds,
  35265. + blocks, walk.iv, first);
  35266. + memcpy(tdst, tail, nbytes);
  35267. + err = blkcipher_walk_done(desc, &walk, 0);
  35268. + }
  35269. + kernel_neon_end();
  35270. +
  35271. + return err;
  35272. +}
  35273. +
  35274. +static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35275. + struct scatterlist *src, unsigned int nbytes)
  35276. +{
  35277. + struct crypto_aes_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35278. + int err, first, rounds = 6 + ctx->key1.key_length / 4;
  35279. + struct blkcipher_walk walk;
  35280. + unsigned int blocks;
  35281. +
  35282. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35283. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35284. + err = blkcipher_walk_virt(desc, &walk);
  35285. +
  35286. + kernel_neon_begin();
  35287. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35288. + aes_xts_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35289. + (u8 *)ctx->key1.key_enc, rounds, blocks,
  35290. + (u8 *)ctx->key2.key_enc, walk.iv, first);
  35291. + err = blkcipher_walk_done(desc, &walk, 0);
  35292. + }
  35293. + kernel_neon_end();
  35294. +
  35295. + return err;
  35296. +}
  35297. +
  35298. +static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35299. + struct scatterlist *src, unsigned int nbytes)
  35300. +{
  35301. + struct crypto_aes_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35302. + int err, first, rounds = 6 + ctx->key1.key_length / 4;
  35303. + struct blkcipher_walk walk;
  35304. + unsigned int blocks;
  35305. +
  35306. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35307. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35308. + err = blkcipher_walk_virt(desc, &walk);
  35309. +
  35310. + kernel_neon_begin();
  35311. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35312. + aes_xts_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35313. + (u8 *)ctx->key1.key_dec, rounds, blocks,
  35314. + (u8 *)ctx->key2.key_enc, walk.iv, first);
  35315. + err = blkcipher_walk_done(desc, &walk, 0);
  35316. + }
  35317. + kernel_neon_end();
  35318. +
  35319. + return err;
  35320. +}
  35321. +
  35322. +static struct crypto_alg aes_algs[] = { {
  35323. + .cra_name = "__ecb-aes-" MODE,
  35324. + .cra_driver_name = "__driver-ecb-aes-" MODE,
  35325. + .cra_priority = 0,
  35326. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35327. + .cra_blocksize = AES_BLOCK_SIZE,
  35328. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  35329. + .cra_alignmask = 7,
  35330. + .cra_type = &crypto_blkcipher_type,
  35331. + .cra_module = THIS_MODULE,
  35332. + .cra_blkcipher = {
  35333. + .min_keysize = AES_MIN_KEY_SIZE,
  35334. + .max_keysize = AES_MAX_KEY_SIZE,
  35335. + .ivsize = AES_BLOCK_SIZE,
  35336. + .setkey = crypto_aes_set_key,
  35337. + .encrypt = ecb_encrypt,
  35338. + .decrypt = ecb_decrypt,
  35339. + },
  35340. +}, {
  35341. + .cra_name = "__cbc-aes-" MODE,
  35342. + .cra_driver_name = "__driver-cbc-aes-" MODE,
  35343. + .cra_priority = 0,
  35344. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35345. + .cra_blocksize = AES_BLOCK_SIZE,
  35346. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  35347. + .cra_alignmask = 7,
  35348. + .cra_type = &crypto_blkcipher_type,
  35349. + .cra_module = THIS_MODULE,
  35350. + .cra_blkcipher = {
  35351. + .min_keysize = AES_MIN_KEY_SIZE,
  35352. + .max_keysize = AES_MAX_KEY_SIZE,
  35353. + .ivsize = AES_BLOCK_SIZE,
  35354. + .setkey = crypto_aes_set_key,
  35355. + .encrypt = cbc_encrypt,
  35356. + .decrypt = cbc_decrypt,
  35357. + },
  35358. +}, {
  35359. + .cra_name = "__ctr-aes-" MODE,
  35360. + .cra_driver_name = "__driver-ctr-aes-" MODE,
  35361. + .cra_priority = 0,
  35362. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35363. + .cra_blocksize = 1,
  35364. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  35365. + .cra_alignmask = 7,
  35366. + .cra_type = &crypto_blkcipher_type,
  35367. + .cra_module = THIS_MODULE,
  35368. + .cra_blkcipher = {
  35369. + .min_keysize = AES_MIN_KEY_SIZE,
  35370. + .max_keysize = AES_MAX_KEY_SIZE,
  35371. + .ivsize = AES_BLOCK_SIZE,
  35372. + .setkey = crypto_aes_set_key,
  35373. + .encrypt = ctr_encrypt,
  35374. + .decrypt = ctr_encrypt,
  35375. + },
  35376. +}, {
  35377. + .cra_name = "__xts-aes-" MODE,
  35378. + .cra_driver_name = "__driver-xts-aes-" MODE,
  35379. + .cra_priority = 0,
  35380. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35381. + .cra_blocksize = AES_BLOCK_SIZE,
  35382. + .cra_ctxsize = sizeof(struct crypto_aes_xts_ctx),
  35383. + .cra_alignmask = 7,
  35384. + .cra_type = &crypto_blkcipher_type,
  35385. + .cra_module = THIS_MODULE,
  35386. + .cra_blkcipher = {
  35387. + .min_keysize = 2 * AES_MIN_KEY_SIZE,
  35388. + .max_keysize = 2 * AES_MAX_KEY_SIZE,
  35389. + .ivsize = AES_BLOCK_SIZE,
  35390. + .setkey = xts_set_key,
  35391. + .encrypt = xts_encrypt,
  35392. + .decrypt = xts_decrypt,
  35393. + },
  35394. +}, {
  35395. + .cra_name = "ecb(aes)",
  35396. + .cra_driver_name = "ecb-aes-" MODE,
  35397. + .cra_priority = PRIO,
  35398. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35399. + .cra_blocksize = AES_BLOCK_SIZE,
  35400. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35401. + .cra_alignmask = 7,
  35402. + .cra_type = &crypto_ablkcipher_type,
  35403. + .cra_module = THIS_MODULE,
  35404. + .cra_init = ablk_init,
  35405. + .cra_exit = ablk_exit,
  35406. + .cra_ablkcipher = {
  35407. + .min_keysize = AES_MIN_KEY_SIZE,
  35408. + .max_keysize = AES_MAX_KEY_SIZE,
  35409. + .ivsize = AES_BLOCK_SIZE,
  35410. + .setkey = ablk_set_key,
  35411. + .encrypt = ablk_encrypt,
  35412. + .decrypt = ablk_decrypt,
  35413. + }
  35414. +}, {
  35415. + .cra_name = "cbc(aes)",
  35416. + .cra_driver_name = "cbc-aes-" MODE,
  35417. + .cra_priority = PRIO,
  35418. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35419. + .cra_blocksize = AES_BLOCK_SIZE,
  35420. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35421. + .cra_alignmask = 7,
  35422. + .cra_type = &crypto_ablkcipher_type,
  35423. + .cra_module = THIS_MODULE,
  35424. + .cra_init = ablk_init,
  35425. + .cra_exit = ablk_exit,
  35426. + .cra_ablkcipher = {
  35427. + .min_keysize = AES_MIN_KEY_SIZE,
  35428. + .max_keysize = AES_MAX_KEY_SIZE,
  35429. + .ivsize = AES_BLOCK_SIZE,
  35430. + .setkey = ablk_set_key,
  35431. + .encrypt = ablk_encrypt,
  35432. + .decrypt = ablk_decrypt,
  35433. + }
  35434. +}, {
  35435. + .cra_name = "ctr(aes)",
  35436. + .cra_driver_name = "ctr-aes-" MODE,
  35437. + .cra_priority = PRIO,
  35438. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35439. + .cra_blocksize = 1,
  35440. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35441. + .cra_alignmask = 7,
  35442. + .cra_type = &crypto_ablkcipher_type,
  35443. + .cra_module = THIS_MODULE,
  35444. + .cra_init = ablk_init,
  35445. + .cra_exit = ablk_exit,
  35446. + .cra_ablkcipher = {
  35447. + .min_keysize = AES_MIN_KEY_SIZE,
  35448. + .max_keysize = AES_MAX_KEY_SIZE,
  35449. + .ivsize = AES_BLOCK_SIZE,
  35450. + .setkey = ablk_set_key,
  35451. + .encrypt = ablk_encrypt,
  35452. + .decrypt = ablk_decrypt,
  35453. + }
  35454. +}, {
  35455. + .cra_name = "xts(aes)",
  35456. + .cra_driver_name = "xts-aes-" MODE,
  35457. + .cra_priority = PRIO,
  35458. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35459. + .cra_blocksize = AES_BLOCK_SIZE,
  35460. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35461. + .cra_alignmask = 7,
  35462. + .cra_type = &crypto_ablkcipher_type,
  35463. + .cra_module = THIS_MODULE,
  35464. + .cra_init = ablk_init,
  35465. + .cra_exit = ablk_exit,
  35466. + .cra_ablkcipher = {
  35467. + .min_keysize = 2 * AES_MIN_KEY_SIZE,
  35468. + .max_keysize = 2 * AES_MAX_KEY_SIZE,
  35469. + .ivsize = AES_BLOCK_SIZE,
  35470. + .setkey = ablk_set_key,
  35471. + .encrypt = ablk_encrypt,
  35472. + .decrypt = ablk_decrypt,
  35473. + }
  35474. +} };
  35475. +
  35476. +static int __init aes_init(void)
  35477. +{
  35478. + return crypto_register_algs(aes_algs, ARRAY_SIZE(aes_algs));
  35479. +}
  35480. +
  35481. +static void __exit aes_exit(void)
  35482. +{
  35483. + crypto_unregister_algs(aes_algs, ARRAY_SIZE(aes_algs));
  35484. +}
  35485. +
  35486. +#ifdef USE_V8_CRYPTO_EXTENSIONS
  35487. +module_cpu_feature_match(AES, aes_init);
  35488. +#else
  35489. +module_init(aes_init);
  35490. +#endif
  35491. +module_exit(aes_exit);
  35492. diff -Nur linux-3.14.14/arch/arm64/crypto/aes-modes.S linux-imx6-3.14/arch/arm64/crypto/aes-modes.S
  35493. --- linux-3.14.14/arch/arm64/crypto/aes-modes.S 1969-12-31 18:00:00.000000000 -0600
  35494. +++ linux-imx6-3.14/arch/arm64/crypto/aes-modes.S 2014-12-08 00:31:51.412418001 -0600
  35495. @@ -0,0 +1,532 @@
  35496. +/*
  35497. + * linux/arch/arm64/crypto/aes-modes.S - chaining mode wrappers for AES
  35498. + *
  35499. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  35500. + *
  35501. + * This program is free software; you can redistribute it and/or modify
  35502. + * it under the terms of the GNU General Public License version 2 as
  35503. + * published by the Free Software Foundation.
  35504. + */
  35505. +
  35506. +/* included by aes-ce.S and aes-neon.S */
  35507. +
  35508. + .text
  35509. + .align 4
  35510. +
  35511. +/*
  35512. + * There are several ways to instantiate this code:
  35513. + * - no interleave, all inline
  35514. + * - 2-way interleave, 2x calls out of line (-DINTERLEAVE=2)
  35515. + * - 2-way interleave, all inline (-DINTERLEAVE=2 -DINTERLEAVE_INLINE)
  35516. + * - 4-way interleave, 4x calls out of line (-DINTERLEAVE=4)
  35517. + * - 4-way interleave, all inline (-DINTERLEAVE=4 -DINTERLEAVE_INLINE)
  35518. + *
  35519. + * Macros imported by this code:
  35520. + * - enc_prepare - setup NEON registers for encryption
  35521. + * - dec_prepare - setup NEON registers for decryption
  35522. + * - enc_switch_key - change to new key after having prepared for encryption
  35523. + * - encrypt_block - encrypt a single block
  35524. + * - decrypt block - decrypt a single block
  35525. + * - encrypt_block2x - encrypt 2 blocks in parallel (if INTERLEAVE == 2)
  35526. + * - decrypt_block2x - decrypt 2 blocks in parallel (if INTERLEAVE == 2)
  35527. + * - encrypt_block4x - encrypt 4 blocks in parallel (if INTERLEAVE == 4)
  35528. + * - decrypt_block4x - decrypt 4 blocks in parallel (if INTERLEAVE == 4)
  35529. + */
  35530. +
  35531. +#if defined(INTERLEAVE) && !defined(INTERLEAVE_INLINE)
  35532. +#define FRAME_PUSH stp x29, x30, [sp,#-16]! ; mov x29, sp
  35533. +#define FRAME_POP ldp x29, x30, [sp],#16
  35534. +
  35535. +#if INTERLEAVE == 2
  35536. +
  35537. +aes_encrypt_block2x:
  35538. + encrypt_block2x v0, v1, w3, x2, x6, w7
  35539. + ret
  35540. +ENDPROC(aes_encrypt_block2x)
  35541. +
  35542. +aes_decrypt_block2x:
  35543. + decrypt_block2x v0, v1, w3, x2, x6, w7
  35544. + ret
  35545. +ENDPROC(aes_decrypt_block2x)
  35546. +
  35547. +#elif INTERLEAVE == 4
  35548. +
  35549. +aes_encrypt_block4x:
  35550. + encrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35551. + ret
  35552. +ENDPROC(aes_encrypt_block4x)
  35553. +
  35554. +aes_decrypt_block4x:
  35555. + decrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35556. + ret
  35557. +ENDPROC(aes_decrypt_block4x)
  35558. +
  35559. +#else
  35560. +#error INTERLEAVE should equal 2 or 4
  35561. +#endif
  35562. +
  35563. + .macro do_encrypt_block2x
  35564. + bl aes_encrypt_block2x
  35565. + .endm
  35566. +
  35567. + .macro do_decrypt_block2x
  35568. + bl aes_decrypt_block2x
  35569. + .endm
  35570. +
  35571. + .macro do_encrypt_block4x
  35572. + bl aes_encrypt_block4x
  35573. + .endm
  35574. +
  35575. + .macro do_decrypt_block4x
  35576. + bl aes_decrypt_block4x
  35577. + .endm
  35578. +
  35579. +#else
  35580. +#define FRAME_PUSH
  35581. +#define FRAME_POP
  35582. +
  35583. + .macro do_encrypt_block2x
  35584. + encrypt_block2x v0, v1, w3, x2, x6, w7
  35585. + .endm
  35586. +
  35587. + .macro do_decrypt_block2x
  35588. + decrypt_block2x v0, v1, w3, x2, x6, w7
  35589. + .endm
  35590. +
  35591. + .macro do_encrypt_block4x
  35592. + encrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35593. + .endm
  35594. +
  35595. + .macro do_decrypt_block4x
  35596. + decrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35597. + .endm
  35598. +
  35599. +#endif
  35600. +
  35601. + /*
  35602. + * aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35603. + * int blocks, int first)
  35604. + * aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35605. + * int blocks, int first)
  35606. + */
  35607. +
  35608. +AES_ENTRY(aes_ecb_encrypt)
  35609. + FRAME_PUSH
  35610. + cbz w5, .LecbencloopNx
  35611. +
  35612. + enc_prepare w3, x2, x5
  35613. +
  35614. +.LecbencloopNx:
  35615. +#if INTERLEAVE >= 2
  35616. + subs w4, w4, #INTERLEAVE
  35617. + bmi .Lecbenc1x
  35618. +#if INTERLEAVE == 2
  35619. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 pt blocks */
  35620. + do_encrypt_block2x
  35621. + st1 {v0.16b-v1.16b}, [x0], #32
  35622. +#else
  35623. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 pt blocks */
  35624. + do_encrypt_block4x
  35625. + st1 {v0.16b-v3.16b}, [x0], #64
  35626. +#endif
  35627. + b .LecbencloopNx
  35628. +.Lecbenc1x:
  35629. + adds w4, w4, #INTERLEAVE
  35630. + beq .Lecbencout
  35631. +#endif
  35632. +.Lecbencloop:
  35633. + ld1 {v0.16b}, [x1], #16 /* get next pt block */
  35634. + encrypt_block v0, w3, x2, x5, w6
  35635. + st1 {v0.16b}, [x0], #16
  35636. + subs w4, w4, #1
  35637. + bne .Lecbencloop
  35638. +.Lecbencout:
  35639. + FRAME_POP
  35640. + ret
  35641. +AES_ENDPROC(aes_ecb_encrypt)
  35642. +
  35643. +
  35644. +AES_ENTRY(aes_ecb_decrypt)
  35645. + FRAME_PUSH
  35646. + cbz w5, .LecbdecloopNx
  35647. +
  35648. + dec_prepare w3, x2, x5
  35649. +
  35650. +.LecbdecloopNx:
  35651. +#if INTERLEAVE >= 2
  35652. + subs w4, w4, #INTERLEAVE
  35653. + bmi .Lecbdec1x
  35654. +#if INTERLEAVE == 2
  35655. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 ct blocks */
  35656. + do_decrypt_block2x
  35657. + st1 {v0.16b-v1.16b}, [x0], #32
  35658. +#else
  35659. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  35660. + do_decrypt_block4x
  35661. + st1 {v0.16b-v3.16b}, [x0], #64
  35662. +#endif
  35663. + b .LecbdecloopNx
  35664. +.Lecbdec1x:
  35665. + adds w4, w4, #INTERLEAVE
  35666. + beq .Lecbdecout
  35667. +#endif
  35668. +.Lecbdecloop:
  35669. + ld1 {v0.16b}, [x1], #16 /* get next ct block */
  35670. + decrypt_block v0, w3, x2, x5, w6
  35671. + st1 {v0.16b}, [x0], #16
  35672. + subs w4, w4, #1
  35673. + bne .Lecbdecloop
  35674. +.Lecbdecout:
  35675. + FRAME_POP
  35676. + ret
  35677. +AES_ENDPROC(aes_ecb_decrypt)
  35678. +
  35679. +
  35680. + /*
  35681. + * aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35682. + * int blocks, u8 iv[], int first)
  35683. + * aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35684. + * int blocks, u8 iv[], int first)
  35685. + */
  35686. +
  35687. +AES_ENTRY(aes_cbc_encrypt)
  35688. + cbz w6, .Lcbcencloop
  35689. +
  35690. + ld1 {v0.16b}, [x5] /* get iv */
  35691. + enc_prepare w3, x2, x5
  35692. +
  35693. +.Lcbcencloop:
  35694. + ld1 {v1.16b}, [x1], #16 /* get next pt block */
  35695. + eor v0.16b, v0.16b, v1.16b /* ..and xor with iv */
  35696. + encrypt_block v0, w3, x2, x5, w6
  35697. + st1 {v0.16b}, [x0], #16
  35698. + subs w4, w4, #1
  35699. + bne .Lcbcencloop
  35700. + ret
  35701. +AES_ENDPROC(aes_cbc_encrypt)
  35702. +
  35703. +
  35704. +AES_ENTRY(aes_cbc_decrypt)
  35705. + FRAME_PUSH
  35706. + cbz w6, .LcbcdecloopNx
  35707. +
  35708. + ld1 {v7.16b}, [x5] /* get iv */
  35709. + dec_prepare w3, x2, x5
  35710. +
  35711. +.LcbcdecloopNx:
  35712. +#if INTERLEAVE >= 2
  35713. + subs w4, w4, #INTERLEAVE
  35714. + bmi .Lcbcdec1x
  35715. +#if INTERLEAVE == 2
  35716. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 ct blocks */
  35717. + mov v2.16b, v0.16b
  35718. + mov v3.16b, v1.16b
  35719. + do_decrypt_block2x
  35720. + eor v0.16b, v0.16b, v7.16b
  35721. + eor v1.16b, v1.16b, v2.16b
  35722. + mov v7.16b, v3.16b
  35723. + st1 {v0.16b-v1.16b}, [x0], #32
  35724. +#else
  35725. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  35726. + mov v4.16b, v0.16b
  35727. + mov v5.16b, v1.16b
  35728. + mov v6.16b, v2.16b
  35729. + do_decrypt_block4x
  35730. + sub x1, x1, #16
  35731. + eor v0.16b, v0.16b, v7.16b
  35732. + eor v1.16b, v1.16b, v4.16b
  35733. + ld1 {v7.16b}, [x1], #16 /* reload 1 ct block */
  35734. + eor v2.16b, v2.16b, v5.16b
  35735. + eor v3.16b, v3.16b, v6.16b
  35736. + st1 {v0.16b-v3.16b}, [x0], #64
  35737. +#endif
  35738. + b .LcbcdecloopNx
  35739. +.Lcbcdec1x:
  35740. + adds w4, w4, #INTERLEAVE
  35741. + beq .Lcbcdecout
  35742. +#endif
  35743. +.Lcbcdecloop:
  35744. + ld1 {v1.16b}, [x1], #16 /* get next ct block */
  35745. + mov v0.16b, v1.16b /* ...and copy to v0 */
  35746. + decrypt_block v0, w3, x2, x5, w6
  35747. + eor v0.16b, v0.16b, v7.16b /* xor with iv => pt */
  35748. + mov v7.16b, v1.16b /* ct is next iv */
  35749. + st1 {v0.16b}, [x0], #16
  35750. + subs w4, w4, #1
  35751. + bne .Lcbcdecloop
  35752. +.Lcbcdecout:
  35753. + FRAME_POP
  35754. + ret
  35755. +AES_ENDPROC(aes_cbc_decrypt)
  35756. +
  35757. +
  35758. + /*
  35759. + * aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35760. + * int blocks, u8 ctr[], int first)
  35761. + */
  35762. +
  35763. +AES_ENTRY(aes_ctr_encrypt)
  35764. + FRAME_PUSH
  35765. + cbnz w6, .Lctrfirst /* 1st time around? */
  35766. + umov x5, v4.d[1] /* keep swabbed ctr in reg */
  35767. + rev x5, x5
  35768. +#if INTERLEAVE >= 2
  35769. + cmn w5, w4 /* 32 bit overflow? */
  35770. + bcs .Lctrinc
  35771. + add x5, x5, #1 /* increment BE ctr */
  35772. + b .LctrincNx
  35773. +#else
  35774. + b .Lctrinc
  35775. +#endif
  35776. +.Lctrfirst:
  35777. + enc_prepare w3, x2, x6
  35778. + ld1 {v4.16b}, [x5]
  35779. + umov x5, v4.d[1] /* keep swabbed ctr in reg */
  35780. + rev x5, x5
  35781. +#if INTERLEAVE >= 2
  35782. + cmn w5, w4 /* 32 bit overflow? */
  35783. + bcs .Lctrloop
  35784. +.LctrloopNx:
  35785. + subs w4, w4, #INTERLEAVE
  35786. + bmi .Lctr1x
  35787. +#if INTERLEAVE == 2
  35788. + mov v0.8b, v4.8b
  35789. + mov v1.8b, v4.8b
  35790. + rev x7, x5
  35791. + add x5, x5, #1
  35792. + ins v0.d[1], x7
  35793. + rev x7, x5
  35794. + add x5, x5, #1
  35795. + ins v1.d[1], x7
  35796. + ld1 {v2.16b-v3.16b}, [x1], #32 /* get 2 input blocks */
  35797. + do_encrypt_block2x
  35798. + eor v0.16b, v0.16b, v2.16b
  35799. + eor v1.16b, v1.16b, v3.16b
  35800. + st1 {v0.16b-v1.16b}, [x0], #32
  35801. +#else
  35802. + ldr q8, =0x30000000200000001 /* addends 1,2,3[,0] */
  35803. + dup v7.4s, w5
  35804. + mov v0.16b, v4.16b
  35805. + add v7.4s, v7.4s, v8.4s
  35806. + mov v1.16b, v4.16b
  35807. + rev32 v8.16b, v7.16b
  35808. + mov v2.16b, v4.16b
  35809. + mov v3.16b, v4.16b
  35810. + mov v1.s[3], v8.s[0]
  35811. + mov v2.s[3], v8.s[1]
  35812. + mov v3.s[3], v8.s[2]
  35813. + ld1 {v5.16b-v7.16b}, [x1], #48 /* get 3 input blocks */
  35814. + do_encrypt_block4x
  35815. + eor v0.16b, v5.16b, v0.16b
  35816. + ld1 {v5.16b}, [x1], #16 /* get 1 input block */
  35817. + eor v1.16b, v6.16b, v1.16b
  35818. + eor v2.16b, v7.16b, v2.16b
  35819. + eor v3.16b, v5.16b, v3.16b
  35820. + st1 {v0.16b-v3.16b}, [x0], #64
  35821. + add x5, x5, #INTERLEAVE
  35822. +#endif
  35823. + cbz w4, .LctroutNx
  35824. +.LctrincNx:
  35825. + rev x7, x5
  35826. + ins v4.d[1], x7
  35827. + b .LctrloopNx
  35828. +.LctroutNx:
  35829. + sub x5, x5, #1
  35830. + rev x7, x5
  35831. + ins v4.d[1], x7
  35832. + b .Lctrout
  35833. +.Lctr1x:
  35834. + adds w4, w4, #INTERLEAVE
  35835. + beq .Lctrout
  35836. +#endif
  35837. +.Lctrloop:
  35838. + mov v0.16b, v4.16b
  35839. + encrypt_block v0, w3, x2, x6, w7
  35840. + subs w4, w4, #1
  35841. + bmi .Lctrhalfblock /* blocks < 0 means 1/2 block */
  35842. + ld1 {v3.16b}, [x1], #16
  35843. + eor v3.16b, v0.16b, v3.16b
  35844. + st1 {v3.16b}, [x0], #16
  35845. + beq .Lctrout
  35846. +.Lctrinc:
  35847. + adds x5, x5, #1 /* increment BE ctr */
  35848. + rev x7, x5
  35849. + ins v4.d[1], x7
  35850. + bcc .Lctrloop /* no overflow? */
  35851. + umov x7, v4.d[0] /* load upper word of ctr */
  35852. + rev x7, x7 /* ... to handle the carry */
  35853. + add x7, x7, #1
  35854. + rev x7, x7
  35855. + ins v4.d[0], x7
  35856. + b .Lctrloop
  35857. +.Lctrhalfblock:
  35858. + ld1 {v3.8b}, [x1]
  35859. + eor v3.8b, v0.8b, v3.8b
  35860. + st1 {v3.8b}, [x0]
  35861. +.Lctrout:
  35862. + FRAME_POP
  35863. + ret
  35864. +AES_ENDPROC(aes_ctr_encrypt)
  35865. + .ltorg
  35866. +
  35867. +
  35868. + /*
  35869. + * aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
  35870. + * int blocks, u8 const rk2[], u8 iv[], int first)
  35871. + * aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
  35872. + * int blocks, u8 const rk2[], u8 iv[], int first)
  35873. + */
  35874. +
  35875. + .macro next_tweak, out, in, const, tmp
  35876. + sshr \tmp\().2d, \in\().2d, #63
  35877. + and \tmp\().16b, \tmp\().16b, \const\().16b
  35878. + add \out\().2d, \in\().2d, \in\().2d
  35879. + ext \tmp\().16b, \tmp\().16b, \tmp\().16b, #8
  35880. + eor \out\().16b, \out\().16b, \tmp\().16b
  35881. + .endm
  35882. +
  35883. +.Lxts_mul_x:
  35884. + .word 1, 0, 0x87, 0
  35885. +
  35886. +AES_ENTRY(aes_xts_encrypt)
  35887. + FRAME_PUSH
  35888. + cbz w7, .LxtsencloopNx
  35889. +
  35890. + ld1 {v4.16b}, [x6]
  35891. + enc_prepare w3, x5, x6
  35892. + encrypt_block v4, w3, x5, x6, w7 /* first tweak */
  35893. + enc_switch_key w3, x2, x6
  35894. + ldr q7, .Lxts_mul_x
  35895. + b .LxtsencNx
  35896. +
  35897. +.LxtsencloopNx:
  35898. + ldr q7, .Lxts_mul_x
  35899. + next_tweak v4, v4, v7, v8
  35900. +.LxtsencNx:
  35901. +#if INTERLEAVE >= 2
  35902. + subs w4, w4, #INTERLEAVE
  35903. + bmi .Lxtsenc1x
  35904. +#if INTERLEAVE == 2
  35905. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 pt blocks */
  35906. + next_tweak v5, v4, v7, v8
  35907. + eor v0.16b, v0.16b, v4.16b
  35908. + eor v1.16b, v1.16b, v5.16b
  35909. + do_encrypt_block2x
  35910. + eor v0.16b, v0.16b, v4.16b
  35911. + eor v1.16b, v1.16b, v5.16b
  35912. + st1 {v0.16b-v1.16b}, [x0], #32
  35913. + cbz w4, .LxtsencoutNx
  35914. + next_tweak v4, v5, v7, v8
  35915. + b .LxtsencNx
  35916. +.LxtsencoutNx:
  35917. + mov v4.16b, v5.16b
  35918. + b .Lxtsencout
  35919. +#else
  35920. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 pt blocks */
  35921. + next_tweak v5, v4, v7, v8
  35922. + eor v0.16b, v0.16b, v4.16b
  35923. + next_tweak v6, v5, v7, v8
  35924. + eor v1.16b, v1.16b, v5.16b
  35925. + eor v2.16b, v2.16b, v6.16b
  35926. + next_tweak v7, v6, v7, v8
  35927. + eor v3.16b, v3.16b, v7.16b
  35928. + do_encrypt_block4x
  35929. + eor v3.16b, v3.16b, v7.16b
  35930. + eor v0.16b, v0.16b, v4.16b
  35931. + eor v1.16b, v1.16b, v5.16b
  35932. + eor v2.16b, v2.16b, v6.16b
  35933. + st1 {v0.16b-v3.16b}, [x0], #64
  35934. + mov v4.16b, v7.16b
  35935. + cbz w4, .Lxtsencout
  35936. + b .LxtsencloopNx
  35937. +#endif
  35938. +.Lxtsenc1x:
  35939. + adds w4, w4, #INTERLEAVE
  35940. + beq .Lxtsencout
  35941. +#endif
  35942. +.Lxtsencloop:
  35943. + ld1 {v1.16b}, [x1], #16
  35944. + eor v0.16b, v1.16b, v4.16b
  35945. + encrypt_block v0, w3, x2, x6, w7
  35946. + eor v0.16b, v0.16b, v4.16b
  35947. + st1 {v0.16b}, [x0], #16
  35948. + subs w4, w4, #1
  35949. + beq .Lxtsencout
  35950. + next_tweak v4, v4, v7, v8
  35951. + b .Lxtsencloop
  35952. +.Lxtsencout:
  35953. + FRAME_POP
  35954. + ret
  35955. +AES_ENDPROC(aes_xts_encrypt)
  35956. +
  35957. +
  35958. +AES_ENTRY(aes_xts_decrypt)
  35959. + FRAME_PUSH
  35960. + cbz w7, .LxtsdecloopNx
  35961. +
  35962. + ld1 {v4.16b}, [x6]
  35963. + enc_prepare w3, x5, x6
  35964. + encrypt_block v4, w3, x5, x6, w7 /* first tweak */
  35965. + dec_prepare w3, x2, x6
  35966. + ldr q7, .Lxts_mul_x
  35967. + b .LxtsdecNx
  35968. +
  35969. +.LxtsdecloopNx:
  35970. + ldr q7, .Lxts_mul_x
  35971. + next_tweak v4, v4, v7, v8
  35972. +.LxtsdecNx:
  35973. +#if INTERLEAVE >= 2
  35974. + subs w4, w4, #INTERLEAVE
  35975. + bmi .Lxtsdec1x
  35976. +#if INTERLEAVE == 2
  35977. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 ct blocks */
  35978. + next_tweak v5, v4, v7, v8
  35979. + eor v0.16b, v0.16b, v4.16b
  35980. + eor v1.16b, v1.16b, v5.16b
  35981. + do_decrypt_block2x
  35982. + eor v0.16b, v0.16b, v4.16b
  35983. + eor v1.16b, v1.16b, v5.16b
  35984. + st1 {v0.16b-v1.16b}, [x0], #32
  35985. + cbz w4, .LxtsdecoutNx
  35986. + next_tweak v4, v5, v7, v8
  35987. + b .LxtsdecNx
  35988. +.LxtsdecoutNx:
  35989. + mov v4.16b, v5.16b
  35990. + b .Lxtsdecout
  35991. +#else
  35992. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  35993. + next_tweak v5, v4, v7, v8
  35994. + eor v0.16b, v0.16b, v4.16b
  35995. + next_tweak v6, v5, v7, v8
  35996. + eor v1.16b, v1.16b, v5.16b
  35997. + eor v2.16b, v2.16b, v6.16b
  35998. + next_tweak v7, v6, v7, v8
  35999. + eor v3.16b, v3.16b, v7.16b
  36000. + do_decrypt_block4x
  36001. + eor v3.16b, v3.16b, v7.16b
  36002. + eor v0.16b, v0.16b, v4.16b
  36003. + eor v1.16b, v1.16b, v5.16b
  36004. + eor v2.16b, v2.16b, v6.16b
  36005. + st1 {v0.16b-v3.16b}, [x0], #64
  36006. + mov v4.16b, v7.16b
  36007. + cbz w4, .Lxtsdecout
  36008. + b .LxtsdecloopNx
  36009. +#endif
  36010. +.Lxtsdec1x:
  36011. + adds w4, w4, #INTERLEAVE
  36012. + beq .Lxtsdecout
  36013. +#endif
  36014. +.Lxtsdecloop:
  36015. + ld1 {v1.16b}, [x1], #16
  36016. + eor v0.16b, v1.16b, v4.16b
  36017. + decrypt_block v0, w3, x2, x6, w7
  36018. + eor v0.16b, v0.16b, v4.16b
  36019. + st1 {v0.16b}, [x0], #16
  36020. + subs w4, w4, #1
  36021. + beq .Lxtsdecout
  36022. + next_tweak v4, v4, v7, v8
  36023. + b .Lxtsdecloop
  36024. +.Lxtsdecout:
  36025. + FRAME_POP
  36026. + ret
  36027. +AES_ENDPROC(aes_xts_decrypt)
  36028. diff -Nur linux-3.14.14/arch/arm64/crypto/aes-neon.S linux-imx6-3.14/arch/arm64/crypto/aes-neon.S
  36029. --- linux-3.14.14/arch/arm64/crypto/aes-neon.S 1969-12-31 18:00:00.000000000 -0600
  36030. +++ linux-imx6-3.14/arch/arm64/crypto/aes-neon.S 2014-12-08 00:31:51.412418001 -0600
  36031. @@ -0,0 +1,382 @@
  36032. +/*
  36033. + * linux/arch/arm64/crypto/aes-neon.S - AES cipher for ARMv8 NEON
  36034. + *
  36035. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  36036. + *
  36037. + * This program is free software; you can redistribute it and/or modify
  36038. + * it under the terms of the GNU General Public License version 2 as
  36039. + * published by the Free Software Foundation.
  36040. + */
  36041. +
  36042. +#include <linux/linkage.h>
  36043. +
  36044. +#define AES_ENTRY(func) ENTRY(neon_ ## func)
  36045. +#define AES_ENDPROC(func) ENDPROC(neon_ ## func)
  36046. +
  36047. + /* multiply by polynomial 'x' in GF(2^8) */
  36048. + .macro mul_by_x, out, in, temp, const
  36049. + sshr \temp, \in, #7
  36050. + add \out, \in, \in
  36051. + and \temp, \temp, \const
  36052. + eor \out, \out, \temp
  36053. + .endm
  36054. +
  36055. + /* preload the entire Sbox */
  36056. + .macro prepare, sbox, shiftrows, temp
  36057. + adr \temp, \sbox
  36058. + movi v12.16b, #0x40
  36059. + ldr q13, \shiftrows
  36060. + movi v14.16b, #0x1b
  36061. + ld1 {v16.16b-v19.16b}, [\temp], #64
  36062. + ld1 {v20.16b-v23.16b}, [\temp], #64
  36063. + ld1 {v24.16b-v27.16b}, [\temp], #64
  36064. + ld1 {v28.16b-v31.16b}, [\temp]
  36065. + .endm
  36066. +
  36067. + /* do preload for encryption */
  36068. + .macro enc_prepare, ignore0, ignore1, temp
  36069. + prepare .LForward_Sbox, .LForward_ShiftRows, \temp
  36070. + .endm
  36071. +
  36072. + .macro enc_switch_key, ignore0, ignore1, temp
  36073. + /* do nothing */
  36074. + .endm
  36075. +
  36076. + /* do preload for decryption */
  36077. + .macro dec_prepare, ignore0, ignore1, temp
  36078. + prepare .LReverse_Sbox, .LReverse_ShiftRows, \temp
  36079. + .endm
  36080. +
  36081. + /* apply SubBytes transformation using the the preloaded Sbox */
  36082. + .macro sub_bytes, in
  36083. + sub v9.16b, \in\().16b, v12.16b
  36084. + tbl \in\().16b, {v16.16b-v19.16b}, \in\().16b
  36085. + sub v10.16b, v9.16b, v12.16b
  36086. + tbx \in\().16b, {v20.16b-v23.16b}, v9.16b
  36087. + sub v11.16b, v10.16b, v12.16b
  36088. + tbx \in\().16b, {v24.16b-v27.16b}, v10.16b
  36089. + tbx \in\().16b, {v28.16b-v31.16b}, v11.16b
  36090. + .endm
  36091. +
  36092. + /* apply MixColumns transformation */
  36093. + .macro mix_columns, in
  36094. + mul_by_x v10.16b, \in\().16b, v9.16b, v14.16b
  36095. + rev32 v8.8h, \in\().8h
  36096. + eor \in\().16b, v10.16b, \in\().16b
  36097. + shl v9.4s, v8.4s, #24
  36098. + shl v11.4s, \in\().4s, #24
  36099. + sri v9.4s, v8.4s, #8
  36100. + sri v11.4s, \in\().4s, #8
  36101. + eor v9.16b, v9.16b, v8.16b
  36102. + eor v10.16b, v10.16b, v9.16b
  36103. + eor \in\().16b, v10.16b, v11.16b
  36104. + .endm
  36105. +
  36106. + /* Inverse MixColumns: pre-multiply by { 5, 0, 4, 0 } */
  36107. + .macro inv_mix_columns, in
  36108. + mul_by_x v11.16b, \in\().16b, v10.16b, v14.16b
  36109. + mul_by_x v11.16b, v11.16b, v10.16b, v14.16b
  36110. + eor \in\().16b, \in\().16b, v11.16b
  36111. + rev32 v11.8h, v11.8h
  36112. + eor \in\().16b, \in\().16b, v11.16b
  36113. + mix_columns \in
  36114. + .endm
  36115. +
  36116. + .macro do_block, enc, in, rounds, rk, rkp, i
  36117. + ld1 {v15.16b}, [\rk]
  36118. + add \rkp, \rk, #16
  36119. + mov \i, \rounds
  36120. +1111: eor \in\().16b, \in\().16b, v15.16b /* ^round key */
  36121. + tbl \in\().16b, {\in\().16b}, v13.16b /* ShiftRows */
  36122. + sub_bytes \in
  36123. + ld1 {v15.16b}, [\rkp], #16
  36124. + subs \i, \i, #1
  36125. + beq 2222f
  36126. + .if \enc == 1
  36127. + mix_columns \in
  36128. + .else
  36129. + inv_mix_columns \in
  36130. + .endif
  36131. + b 1111b
  36132. +2222: eor \in\().16b, \in\().16b, v15.16b /* ^round key */
  36133. + .endm
  36134. +
  36135. + .macro encrypt_block, in, rounds, rk, rkp, i
  36136. + do_block 1, \in, \rounds, \rk, \rkp, \i
  36137. + .endm
  36138. +
  36139. + .macro decrypt_block, in, rounds, rk, rkp, i
  36140. + do_block 0, \in, \rounds, \rk, \rkp, \i
  36141. + .endm
  36142. +
  36143. + /*
  36144. + * Interleaved versions: functionally equivalent to the
  36145. + * ones above, but applied to 2 or 4 AES states in parallel.
  36146. + */
  36147. +
  36148. + .macro sub_bytes_2x, in0, in1
  36149. + sub v8.16b, \in0\().16b, v12.16b
  36150. + sub v9.16b, \in1\().16b, v12.16b
  36151. + tbl \in0\().16b, {v16.16b-v19.16b}, \in0\().16b
  36152. + tbl \in1\().16b, {v16.16b-v19.16b}, \in1\().16b
  36153. + sub v10.16b, v8.16b, v12.16b
  36154. + sub v11.16b, v9.16b, v12.16b
  36155. + tbx \in0\().16b, {v20.16b-v23.16b}, v8.16b
  36156. + tbx \in1\().16b, {v20.16b-v23.16b}, v9.16b
  36157. + sub v8.16b, v10.16b, v12.16b
  36158. + sub v9.16b, v11.16b, v12.16b
  36159. + tbx \in0\().16b, {v24.16b-v27.16b}, v10.16b
  36160. + tbx \in1\().16b, {v24.16b-v27.16b}, v11.16b
  36161. + tbx \in0\().16b, {v28.16b-v31.16b}, v8.16b
  36162. + tbx \in1\().16b, {v28.16b-v31.16b}, v9.16b
  36163. + .endm
  36164. +
  36165. + .macro sub_bytes_4x, in0, in1, in2, in3
  36166. + sub v8.16b, \in0\().16b, v12.16b
  36167. + tbl \in0\().16b, {v16.16b-v19.16b}, \in0\().16b
  36168. + sub v9.16b, \in1\().16b, v12.16b
  36169. + tbl \in1\().16b, {v16.16b-v19.16b}, \in1\().16b
  36170. + sub v10.16b, \in2\().16b, v12.16b
  36171. + tbl \in2\().16b, {v16.16b-v19.16b}, \in2\().16b
  36172. + sub v11.16b, \in3\().16b, v12.16b
  36173. + tbl \in3\().16b, {v16.16b-v19.16b}, \in3\().16b
  36174. + tbx \in0\().16b, {v20.16b-v23.16b}, v8.16b
  36175. + tbx \in1\().16b, {v20.16b-v23.16b}, v9.16b
  36176. + sub v8.16b, v8.16b, v12.16b
  36177. + tbx \in2\().16b, {v20.16b-v23.16b}, v10.16b
  36178. + sub v9.16b, v9.16b, v12.16b
  36179. + tbx \in3\().16b, {v20.16b-v23.16b}, v11.16b
  36180. + sub v10.16b, v10.16b, v12.16b
  36181. + tbx \in0\().16b, {v24.16b-v27.16b}, v8.16b
  36182. + sub v11.16b, v11.16b, v12.16b
  36183. + tbx \in1\().16b, {v24.16b-v27.16b}, v9.16b
  36184. + sub v8.16b, v8.16b, v12.16b
  36185. + tbx \in2\().16b, {v24.16b-v27.16b}, v10.16b
  36186. + sub v9.16b, v9.16b, v12.16b
  36187. + tbx \in3\().16b, {v24.16b-v27.16b}, v11.16b
  36188. + sub v10.16b, v10.16b, v12.16b
  36189. + tbx \in0\().16b, {v28.16b-v31.16b}, v8.16b
  36190. + sub v11.16b, v11.16b, v12.16b
  36191. + tbx \in1\().16b, {v28.16b-v31.16b}, v9.16b
  36192. + tbx \in2\().16b, {v28.16b-v31.16b}, v10.16b
  36193. + tbx \in3\().16b, {v28.16b-v31.16b}, v11.16b
  36194. + .endm
  36195. +
  36196. + .macro mul_by_x_2x, out0, out1, in0, in1, tmp0, tmp1, const
  36197. + sshr \tmp0\().16b, \in0\().16b, #7
  36198. + add \out0\().16b, \in0\().16b, \in0\().16b
  36199. + sshr \tmp1\().16b, \in1\().16b, #7
  36200. + and \tmp0\().16b, \tmp0\().16b, \const\().16b
  36201. + add \out1\().16b, \in1\().16b, \in1\().16b
  36202. + and \tmp1\().16b, \tmp1\().16b, \const\().16b
  36203. + eor \out0\().16b, \out0\().16b, \tmp0\().16b
  36204. + eor \out1\().16b, \out1\().16b, \tmp1\().16b
  36205. + .endm
  36206. +
  36207. + .macro mix_columns_2x, in0, in1
  36208. + mul_by_x_2x v8, v9, \in0, \in1, v10, v11, v14
  36209. + rev32 v10.8h, \in0\().8h
  36210. + rev32 v11.8h, \in1\().8h
  36211. + eor \in0\().16b, v8.16b, \in0\().16b
  36212. + eor \in1\().16b, v9.16b, \in1\().16b
  36213. + shl v12.4s, v10.4s, #24
  36214. + shl v13.4s, v11.4s, #24
  36215. + eor v8.16b, v8.16b, v10.16b
  36216. + sri v12.4s, v10.4s, #8
  36217. + shl v10.4s, \in0\().4s, #24
  36218. + eor v9.16b, v9.16b, v11.16b
  36219. + sri v13.4s, v11.4s, #8
  36220. + shl v11.4s, \in1\().4s, #24
  36221. + sri v10.4s, \in0\().4s, #8
  36222. + eor \in0\().16b, v8.16b, v12.16b
  36223. + sri v11.4s, \in1\().4s, #8
  36224. + eor \in1\().16b, v9.16b, v13.16b
  36225. + eor \in0\().16b, v10.16b, \in0\().16b
  36226. + eor \in1\().16b, v11.16b, \in1\().16b
  36227. + .endm
  36228. +
  36229. + .macro inv_mix_cols_2x, in0, in1
  36230. + mul_by_x_2x v8, v9, \in0, \in1, v10, v11, v14
  36231. + mul_by_x_2x v8, v9, v8, v9, v10, v11, v14
  36232. + eor \in0\().16b, \in0\().16b, v8.16b
  36233. + eor \in1\().16b, \in1\().16b, v9.16b
  36234. + rev32 v8.8h, v8.8h
  36235. + rev32 v9.8h, v9.8h
  36236. + eor \in0\().16b, \in0\().16b, v8.16b
  36237. + eor \in1\().16b, \in1\().16b, v9.16b
  36238. + mix_columns_2x \in0, \in1
  36239. + .endm
  36240. +
  36241. + .macro inv_mix_cols_4x, in0, in1, in2, in3
  36242. + mul_by_x_2x v8, v9, \in0, \in1, v10, v11, v14
  36243. + mul_by_x_2x v10, v11, \in2, \in3, v12, v13, v14
  36244. + mul_by_x_2x v8, v9, v8, v9, v12, v13, v14
  36245. + mul_by_x_2x v10, v11, v10, v11, v12, v13, v14
  36246. + eor \in0\().16b, \in0\().16b, v8.16b
  36247. + eor \in1\().16b, \in1\().16b, v9.16b
  36248. + eor \in2\().16b, \in2\().16b, v10.16b
  36249. + eor \in3\().16b, \in3\().16b, v11.16b
  36250. + rev32 v8.8h, v8.8h
  36251. + rev32 v9.8h, v9.8h
  36252. + rev32 v10.8h, v10.8h
  36253. + rev32 v11.8h, v11.8h
  36254. + eor \in0\().16b, \in0\().16b, v8.16b
  36255. + eor \in1\().16b, \in1\().16b, v9.16b
  36256. + eor \in2\().16b, \in2\().16b, v10.16b
  36257. + eor \in3\().16b, \in3\().16b, v11.16b
  36258. + mix_columns_2x \in0, \in1
  36259. + mix_columns_2x \in2, \in3
  36260. + .endm
  36261. +
  36262. + .macro do_block_2x, enc, in0, in1 rounds, rk, rkp, i
  36263. + ld1 {v15.16b}, [\rk]
  36264. + add \rkp, \rk, #16
  36265. + mov \i, \rounds
  36266. +1111: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36267. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36268. + sub_bytes_2x \in0, \in1
  36269. + tbl \in0\().16b, {\in0\().16b}, v13.16b /* ShiftRows */
  36270. + tbl \in1\().16b, {\in1\().16b}, v13.16b /* ShiftRows */
  36271. + ld1 {v15.16b}, [\rkp], #16
  36272. + subs \i, \i, #1
  36273. + beq 2222f
  36274. + .if \enc == 1
  36275. + mix_columns_2x \in0, \in1
  36276. + ldr q13, .LForward_ShiftRows
  36277. + .else
  36278. + inv_mix_cols_2x \in0, \in1
  36279. + ldr q13, .LReverse_ShiftRows
  36280. + .endif
  36281. + movi v12.16b, #0x40
  36282. + b 1111b
  36283. +2222: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36284. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36285. + .endm
  36286. +
  36287. + .macro do_block_4x, enc, in0, in1, in2, in3, rounds, rk, rkp, i
  36288. + ld1 {v15.16b}, [\rk]
  36289. + add \rkp, \rk, #16
  36290. + mov \i, \rounds
  36291. +1111: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36292. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36293. + eor \in2\().16b, \in2\().16b, v15.16b /* ^round key */
  36294. + eor \in3\().16b, \in3\().16b, v15.16b /* ^round key */
  36295. + sub_bytes_4x \in0, \in1, \in2, \in3
  36296. + tbl \in0\().16b, {\in0\().16b}, v13.16b /* ShiftRows */
  36297. + tbl \in1\().16b, {\in1\().16b}, v13.16b /* ShiftRows */
  36298. + tbl \in2\().16b, {\in2\().16b}, v13.16b /* ShiftRows */
  36299. + tbl \in3\().16b, {\in3\().16b}, v13.16b /* ShiftRows */
  36300. + ld1 {v15.16b}, [\rkp], #16
  36301. + subs \i, \i, #1
  36302. + beq 2222f
  36303. + .if \enc == 1
  36304. + mix_columns_2x \in0, \in1
  36305. + mix_columns_2x \in2, \in3
  36306. + ldr q13, .LForward_ShiftRows
  36307. + .else
  36308. + inv_mix_cols_4x \in0, \in1, \in2, \in3
  36309. + ldr q13, .LReverse_ShiftRows
  36310. + .endif
  36311. + movi v12.16b, #0x40
  36312. + b 1111b
  36313. +2222: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36314. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36315. + eor \in2\().16b, \in2\().16b, v15.16b /* ^round key */
  36316. + eor \in3\().16b, \in3\().16b, v15.16b /* ^round key */
  36317. + .endm
  36318. +
  36319. + .macro encrypt_block2x, in0, in1, rounds, rk, rkp, i
  36320. + do_block_2x 1, \in0, \in1, \rounds, \rk, \rkp, \i
  36321. + .endm
  36322. +
  36323. + .macro decrypt_block2x, in0, in1, rounds, rk, rkp, i
  36324. + do_block_2x 0, \in0, \in1, \rounds, \rk, \rkp, \i
  36325. + .endm
  36326. +
  36327. + .macro encrypt_block4x, in0, in1, in2, in3, rounds, rk, rkp, i
  36328. + do_block_4x 1, \in0, \in1, \in2, \in3, \rounds, \rk, \rkp, \i
  36329. + .endm
  36330. +
  36331. + .macro decrypt_block4x, in0, in1, in2, in3, rounds, rk, rkp, i
  36332. + do_block_4x 0, \in0, \in1, \in2, \in3, \rounds, \rk, \rkp, \i
  36333. + .endm
  36334. +
  36335. +#include "aes-modes.S"
  36336. +
  36337. + .text
  36338. + .align 4
  36339. +.LForward_ShiftRows:
  36340. + .byte 0x0, 0x5, 0xa, 0xf, 0x4, 0x9, 0xe, 0x3
  36341. + .byte 0x8, 0xd, 0x2, 0x7, 0xc, 0x1, 0x6, 0xb
  36342. +
  36343. +.LReverse_ShiftRows:
  36344. + .byte 0x0, 0xd, 0xa, 0x7, 0x4, 0x1, 0xe, 0xb
  36345. + .byte 0x8, 0x5, 0x2, 0xf, 0xc, 0x9, 0x6, 0x3
  36346. +
  36347. +.LForward_Sbox:
  36348. + .byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
  36349. + .byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
  36350. + .byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
  36351. + .byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
  36352. + .byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
  36353. + .byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
  36354. + .byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
  36355. + .byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
  36356. + .byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
  36357. + .byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
  36358. + .byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
  36359. + .byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
  36360. + .byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
  36361. + .byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
  36362. + .byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
  36363. + .byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
  36364. + .byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
  36365. + .byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
  36366. + .byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
  36367. + .byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
  36368. + .byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
  36369. + .byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
  36370. + .byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
  36371. + .byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
  36372. + .byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
  36373. + .byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
  36374. + .byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
  36375. + .byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
  36376. + .byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
  36377. + .byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
  36378. + .byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
  36379. + .byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
  36380. +
  36381. +.LReverse_Sbox:
  36382. + .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
  36383. + .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
  36384. + .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
  36385. + .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
  36386. + .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
  36387. + .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
  36388. + .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
  36389. + .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
  36390. + .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
  36391. + .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
  36392. + .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
  36393. + .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
  36394. + .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
  36395. + .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
  36396. + .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
  36397. + .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
  36398. + .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
  36399. + .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
  36400. + .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
  36401. + .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
  36402. + .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
  36403. + .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
  36404. + .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
  36405. + .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
  36406. + .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
  36407. + .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
  36408. + .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
  36409. + .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
  36410. + .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
  36411. + .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
  36412. + .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
  36413. + .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
  36414. diff -Nur linux-3.14.14/arch/arm64/crypto/ghash-ce-core.S linux-imx6-3.14/arch/arm64/crypto/ghash-ce-core.S
  36415. --- linux-3.14.14/arch/arm64/crypto/ghash-ce-core.S 1969-12-31 18:00:00.000000000 -0600
  36416. +++ linux-imx6-3.14/arch/arm64/crypto/ghash-ce-core.S 2014-12-08 00:31:51.412418001 -0600
  36417. @@ -0,0 +1,79 @@
  36418. +/*
  36419. + * Accelerated GHASH implementation with ARMv8 PMULL instructions.
  36420. + *
  36421. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  36422. + *
  36423. + * This program is free software; you can redistribute it and/or modify it
  36424. + * under the terms of the GNU General Public License version 2 as published
  36425. + * by the Free Software Foundation.
  36426. + */
  36427. +
  36428. +#include <linux/linkage.h>
  36429. +#include <asm/assembler.h>
  36430. +
  36431. + SHASH .req v0
  36432. + SHASH2 .req v1
  36433. + T1 .req v2
  36434. + T2 .req v3
  36435. + MASK .req v4
  36436. + XL .req v5
  36437. + XM .req v6
  36438. + XH .req v7
  36439. + IN1 .req v7
  36440. +
  36441. + .text
  36442. + .arch armv8-a+crypto
  36443. +
  36444. + /*
  36445. + * void pmull_ghash_update(int blocks, u64 dg[], const char *src,
  36446. + * struct ghash_key const *k, const char *head)
  36447. + */
  36448. +ENTRY(pmull_ghash_update)
  36449. + ld1 {SHASH.16b}, [x3]
  36450. + ld1 {XL.16b}, [x1]
  36451. + movi MASK.16b, #0xe1
  36452. + ext SHASH2.16b, SHASH.16b, SHASH.16b, #8
  36453. + shl MASK.2d, MASK.2d, #57
  36454. + eor SHASH2.16b, SHASH2.16b, SHASH.16b
  36455. +
  36456. + /* do the head block first, if supplied */
  36457. + cbz x4, 0f
  36458. + ld1 {T1.2d}, [x4]
  36459. + b 1f
  36460. +
  36461. +0: ld1 {T1.2d}, [x2], #16
  36462. + sub w0, w0, #1
  36463. +
  36464. +1: /* multiply XL by SHASH in GF(2^128) */
  36465. +CPU_LE( rev64 T1.16b, T1.16b )
  36466. +
  36467. + ext T2.16b, XL.16b, XL.16b, #8
  36468. + ext IN1.16b, T1.16b, T1.16b, #8
  36469. + eor T1.16b, T1.16b, T2.16b
  36470. + eor XL.16b, XL.16b, IN1.16b
  36471. +
  36472. + pmull2 XH.1q, SHASH.2d, XL.2d // a1 * b1
  36473. + eor T1.16b, T1.16b, XL.16b
  36474. + pmull XL.1q, SHASH.1d, XL.1d // a0 * b0
  36475. + pmull XM.1q, SHASH2.1d, T1.1d // (a1 + a0)(b1 + b0)
  36476. +
  36477. + ext T1.16b, XL.16b, XH.16b, #8
  36478. + eor T2.16b, XL.16b, XH.16b
  36479. + eor XM.16b, XM.16b, T1.16b
  36480. + eor XM.16b, XM.16b, T2.16b
  36481. + pmull T2.1q, XL.1d, MASK.1d
  36482. +
  36483. + mov XH.d[0], XM.d[1]
  36484. + mov XM.d[1], XL.d[0]
  36485. +
  36486. + eor XL.16b, XM.16b, T2.16b
  36487. + ext T2.16b, XL.16b, XL.16b, #8
  36488. + pmull XL.1q, XL.1d, MASK.1d
  36489. + eor T2.16b, T2.16b, XH.16b
  36490. + eor XL.16b, XL.16b, T2.16b
  36491. +
  36492. + cbnz w0, 0b
  36493. +
  36494. + st1 {XL.16b}, [x1]
  36495. + ret
  36496. +ENDPROC(pmull_ghash_update)
  36497. diff -Nur linux-3.14.14/arch/arm64/crypto/ghash-ce-glue.c linux-imx6-3.14/arch/arm64/crypto/ghash-ce-glue.c
  36498. --- linux-3.14.14/arch/arm64/crypto/ghash-ce-glue.c 1969-12-31 18:00:00.000000000 -0600
  36499. +++ linux-imx6-3.14/arch/arm64/crypto/ghash-ce-glue.c 2014-12-08 00:31:51.412418001 -0600
  36500. @@ -0,0 +1,156 @@
  36501. +/*
  36502. + * Accelerated GHASH implementation with ARMv8 PMULL instructions.
  36503. + *
  36504. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  36505. + *
  36506. + * This program is free software; you can redistribute it and/or modify it
  36507. + * under the terms of the GNU General Public License version 2 as published
  36508. + * by the Free Software Foundation.
  36509. + */
  36510. +
  36511. +#include <asm/neon.h>
  36512. +#include <asm/unaligned.h>
  36513. +#include <crypto/internal/hash.h>
  36514. +#include <linux/cpufeature.h>
  36515. +#include <linux/crypto.h>
  36516. +#include <linux/module.h>
  36517. +
  36518. +MODULE_DESCRIPTION("GHASH secure hash using ARMv8 Crypto Extensions");
  36519. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  36520. +MODULE_LICENSE("GPL v2");
  36521. +
  36522. +#define GHASH_BLOCK_SIZE 16
  36523. +#define GHASH_DIGEST_SIZE 16
  36524. +
  36525. +struct ghash_key {
  36526. + u64 a;
  36527. + u64 b;
  36528. +};
  36529. +
  36530. +struct ghash_desc_ctx {
  36531. + u64 digest[GHASH_DIGEST_SIZE/sizeof(u64)];
  36532. + u8 buf[GHASH_BLOCK_SIZE];
  36533. + u32 count;
  36534. +};
  36535. +
  36536. +asmlinkage void pmull_ghash_update(int blocks, u64 dg[], const char *src,
  36537. + struct ghash_key const *k, const char *head);
  36538. +
  36539. +static int ghash_init(struct shash_desc *desc)
  36540. +{
  36541. + struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
  36542. +
  36543. + *ctx = (struct ghash_desc_ctx){};
  36544. + return 0;
  36545. +}
  36546. +
  36547. +static int ghash_update(struct shash_desc *desc, const u8 *src,
  36548. + unsigned int len)
  36549. +{
  36550. + struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
  36551. + unsigned int partial = ctx->count % GHASH_BLOCK_SIZE;
  36552. +
  36553. + ctx->count += len;
  36554. +
  36555. + if ((partial + len) >= GHASH_BLOCK_SIZE) {
  36556. + struct ghash_key *key = crypto_shash_ctx(desc->tfm);
  36557. + int blocks;
  36558. +
  36559. + if (partial) {
  36560. + int p = GHASH_BLOCK_SIZE - partial;
  36561. +
  36562. + memcpy(ctx->buf + partial, src, p);
  36563. + src += p;
  36564. + len -= p;
  36565. + }
  36566. +
  36567. + blocks = len / GHASH_BLOCK_SIZE;
  36568. + len %= GHASH_BLOCK_SIZE;
  36569. +
  36570. + kernel_neon_begin_partial(8);
  36571. + pmull_ghash_update(blocks, ctx->digest, src, key,
  36572. + partial ? ctx->buf : NULL);
  36573. + kernel_neon_end();
  36574. + src += blocks * GHASH_BLOCK_SIZE;
  36575. + partial = 0;
  36576. + }
  36577. + if (len)
  36578. + memcpy(ctx->buf + partial, src, len);
  36579. + return 0;
  36580. +}
  36581. +
  36582. +static int ghash_final(struct shash_desc *desc, u8 *dst)
  36583. +{
  36584. + struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
  36585. + unsigned int partial = ctx->count % GHASH_BLOCK_SIZE;
  36586. +
  36587. + if (partial) {
  36588. + struct ghash_key *key = crypto_shash_ctx(desc->tfm);
  36589. +
  36590. + memset(ctx->buf + partial, 0, GHASH_BLOCK_SIZE - partial);
  36591. +
  36592. + kernel_neon_begin_partial(8);
  36593. + pmull_ghash_update(1, ctx->digest, ctx->buf, key, NULL);
  36594. + kernel_neon_end();
  36595. + }
  36596. + put_unaligned_be64(ctx->digest[1], dst);
  36597. + put_unaligned_be64(ctx->digest[0], dst + 8);
  36598. +
  36599. + *ctx = (struct ghash_desc_ctx){};
  36600. + return 0;
  36601. +}
  36602. +
  36603. +static int ghash_setkey(struct crypto_shash *tfm,
  36604. + const u8 *inkey, unsigned int keylen)
  36605. +{
  36606. + struct ghash_key *key = crypto_shash_ctx(tfm);
  36607. + u64 a, b;
  36608. +
  36609. + if (keylen != GHASH_BLOCK_SIZE) {
  36610. + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
  36611. + return -EINVAL;
  36612. + }
  36613. +
  36614. + /* perform multiplication by 'x' in GF(2^128) */
  36615. + b = get_unaligned_be64(inkey);
  36616. + a = get_unaligned_be64(inkey + 8);
  36617. +
  36618. + key->a = (a << 1) | (b >> 63);
  36619. + key->b = (b << 1) | (a >> 63);
  36620. +
  36621. + if (b >> 63)
  36622. + key->b ^= 0xc200000000000000UL;
  36623. +
  36624. + return 0;
  36625. +}
  36626. +
  36627. +static struct shash_alg ghash_alg = {
  36628. + .digestsize = GHASH_DIGEST_SIZE,
  36629. + .init = ghash_init,
  36630. + .update = ghash_update,
  36631. + .final = ghash_final,
  36632. + .setkey = ghash_setkey,
  36633. + .descsize = sizeof(struct ghash_desc_ctx),
  36634. + .base = {
  36635. + .cra_name = "ghash",
  36636. + .cra_driver_name = "ghash-ce",
  36637. + .cra_priority = 200,
  36638. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  36639. + .cra_blocksize = GHASH_BLOCK_SIZE,
  36640. + .cra_ctxsize = sizeof(struct ghash_key),
  36641. + .cra_module = THIS_MODULE,
  36642. + },
  36643. +};
  36644. +
  36645. +static int __init ghash_ce_mod_init(void)
  36646. +{
  36647. + return crypto_register_shash(&ghash_alg);
  36648. +}
  36649. +
  36650. +static void __exit ghash_ce_mod_exit(void)
  36651. +{
  36652. + crypto_unregister_shash(&ghash_alg);
  36653. +}
  36654. +
  36655. +module_cpu_feature_match(PMULL, ghash_ce_mod_init);
  36656. +module_exit(ghash_ce_mod_exit);
  36657. diff -Nur linux-3.14.14/arch/arm64/crypto/Kconfig linux-imx6-3.14/arch/arm64/crypto/Kconfig
  36658. --- linux-3.14.14/arch/arm64/crypto/Kconfig 1969-12-31 18:00:00.000000000 -0600
  36659. +++ linux-imx6-3.14/arch/arm64/crypto/Kconfig 2014-12-08 00:31:51.408418001 -0600
  36660. @@ -0,0 +1,53 @@
  36661. +
  36662. +menuconfig ARM64_CRYPTO
  36663. + bool "ARM64 Accelerated Cryptographic Algorithms"
  36664. + depends on ARM64
  36665. + help
  36666. + Say Y here to choose from a selection of cryptographic algorithms
  36667. + implemented using ARM64 specific CPU features or instructions.
  36668. +
  36669. +if ARM64_CRYPTO
  36670. +
  36671. +config CRYPTO_SHA1_ARM64_CE
  36672. + tristate "SHA-1 digest algorithm (ARMv8 Crypto Extensions)"
  36673. + depends on ARM64 && KERNEL_MODE_NEON
  36674. + select CRYPTO_HASH
  36675. +
  36676. +config CRYPTO_SHA2_ARM64_CE
  36677. + tristate "SHA-224/SHA-256 digest algorithm (ARMv8 Crypto Extensions)"
  36678. + depends on ARM64 && KERNEL_MODE_NEON
  36679. + select CRYPTO_HASH
  36680. +
  36681. +config CRYPTO_GHASH_ARM64_CE
  36682. + tristate "GHASH (for GCM chaining mode) using ARMv8 Crypto Extensions"
  36683. + depends on ARM64 && KERNEL_MODE_NEON
  36684. + select CRYPTO_HASH
  36685. +
  36686. +config CRYPTO_AES_ARM64_CE
  36687. + tristate "AES core cipher using ARMv8 Crypto Extensions"
  36688. + depends on ARM64 && KERNEL_MODE_NEON
  36689. + select CRYPTO_ALGAPI
  36690. + select CRYPTO_AES
  36691. +
  36692. +config CRYPTO_AES_ARM64_CE_CCM
  36693. + tristate "AES in CCM mode using ARMv8 Crypto Extensions"
  36694. + depends on ARM64 && KERNEL_MODE_NEON
  36695. + select CRYPTO_ALGAPI
  36696. + select CRYPTO_AES
  36697. + select CRYPTO_AEAD
  36698. +
  36699. +config CRYPTO_AES_ARM64_CE_BLK
  36700. + tristate "AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions"
  36701. + depends on ARM64 && KERNEL_MODE_NEON
  36702. + select CRYPTO_BLKCIPHER
  36703. + select CRYPTO_AES
  36704. + select CRYPTO_ABLK_HELPER
  36705. +
  36706. +config CRYPTO_AES_ARM64_NEON_BLK
  36707. + tristate "AES in ECB/CBC/CTR/XTS modes using NEON instructions"
  36708. + depends on ARM64 && KERNEL_MODE_NEON
  36709. + select CRYPTO_BLKCIPHER
  36710. + select CRYPTO_AES
  36711. + select CRYPTO_ABLK_HELPER
  36712. +
  36713. +endif
  36714. diff -Nur linux-3.14.14/arch/arm64/crypto/Makefile linux-imx6-3.14/arch/arm64/crypto/Makefile
  36715. --- linux-3.14.14/arch/arm64/crypto/Makefile 1969-12-31 18:00:00.000000000 -0600
  36716. +++ linux-imx6-3.14/arch/arm64/crypto/Makefile 2014-12-08 00:31:51.408418001 -0600
  36717. @@ -0,0 +1,38 @@
  36718. +#
  36719. +# linux/arch/arm64/crypto/Makefile
  36720. +#
  36721. +# Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  36722. +#
  36723. +# This program is free software; you can redistribute it and/or modify
  36724. +# it under the terms of the GNU General Public License version 2 as
  36725. +# published by the Free Software Foundation.
  36726. +#
  36727. +
  36728. +obj-$(CONFIG_CRYPTO_SHA1_ARM64_CE) += sha1-ce.o
  36729. +sha1-ce-y := sha1-ce-glue.o sha1-ce-core.o
  36730. +
  36731. +obj-$(CONFIG_CRYPTO_SHA2_ARM64_CE) += sha2-ce.o
  36732. +sha2-ce-y := sha2-ce-glue.o sha2-ce-core.o
  36733. +
  36734. +obj-$(CONFIG_CRYPTO_GHASH_ARM64_CE) += ghash-ce.o
  36735. +ghash-ce-y := ghash-ce-glue.o ghash-ce-core.o
  36736. +
  36737. +obj-$(CONFIG_CRYPTO_AES_ARM64_CE) += aes-ce-cipher.o
  36738. +CFLAGS_aes-ce-cipher.o += -march=armv8-a+crypto
  36739. +
  36740. +obj-$(CONFIG_CRYPTO_AES_ARM64_CE_CCM) += aes-ce-ccm.o
  36741. +aes-ce-ccm-y := aes-ce-ccm-glue.o aes-ce-ccm-core.o
  36742. +
  36743. +obj-$(CONFIG_CRYPTO_AES_ARM64_CE_BLK) += aes-ce-blk.o
  36744. +aes-ce-blk-y := aes-glue-ce.o aes-ce.o
  36745. +
  36746. +obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o
  36747. +aes-neon-blk-y := aes-glue-neon.o aes-neon.o
  36748. +
  36749. +AFLAGS_aes-ce.o := -DINTERLEAVE=2 -DINTERLEAVE_INLINE
  36750. +AFLAGS_aes-neon.o := -DINTERLEAVE=4
  36751. +
  36752. +CFLAGS_aes-glue-ce.o := -DUSE_V8_CRYPTO_EXTENSIONS
  36753. +
  36754. +$(obj)/aes-glue-%.o: $(src)/aes-glue.c FORCE
  36755. + $(call if_changed_dep,cc_o_c)
  36756. diff -Nur linux-3.14.14/arch/arm64/crypto/sha1-ce-core.S linux-imx6-3.14/arch/arm64/crypto/sha1-ce-core.S
  36757. --- linux-3.14.14/arch/arm64/crypto/sha1-ce-core.S 1969-12-31 18:00:00.000000000 -0600
  36758. +++ linux-imx6-3.14/arch/arm64/crypto/sha1-ce-core.S 2014-12-08 00:31:51.412418001 -0600
  36759. @@ -0,0 +1,153 @@
  36760. +/*
  36761. + * sha1-ce-core.S - SHA-1 secure hash using ARMv8 Crypto Extensions
  36762. + *
  36763. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  36764. + *
  36765. + * This program is free software; you can redistribute it and/or modify
  36766. + * it under the terms of the GNU General Public License version 2 as
  36767. + * published by the Free Software Foundation.
  36768. + */
  36769. +
  36770. +#include <linux/linkage.h>
  36771. +#include <asm/assembler.h>
  36772. +
  36773. + .text
  36774. + .arch armv8-a+crypto
  36775. +
  36776. + k0 .req v0
  36777. + k1 .req v1
  36778. + k2 .req v2
  36779. + k3 .req v3
  36780. +
  36781. + t0 .req v4
  36782. + t1 .req v5
  36783. +
  36784. + dga .req q6
  36785. + dgav .req v6
  36786. + dgb .req s7
  36787. + dgbv .req v7
  36788. +
  36789. + dg0q .req q12
  36790. + dg0s .req s12
  36791. + dg0v .req v12
  36792. + dg1s .req s13
  36793. + dg1v .req v13
  36794. + dg2s .req s14
  36795. +
  36796. + .macro add_only, op, ev, rc, s0, dg1
  36797. + .ifc \ev, ev
  36798. + add t1.4s, v\s0\().4s, \rc\().4s
  36799. + sha1h dg2s, dg0s
  36800. + .ifnb \dg1
  36801. + sha1\op dg0q, \dg1, t0.4s
  36802. + .else
  36803. + sha1\op dg0q, dg1s, t0.4s
  36804. + .endif
  36805. + .else
  36806. + .ifnb \s0
  36807. + add t0.4s, v\s0\().4s, \rc\().4s
  36808. + .endif
  36809. + sha1h dg1s, dg0s
  36810. + sha1\op dg0q, dg2s, t1.4s
  36811. + .endif
  36812. + .endm
  36813. +
  36814. + .macro add_update, op, ev, rc, s0, s1, s2, s3, dg1
  36815. + sha1su0 v\s0\().4s, v\s1\().4s, v\s2\().4s
  36816. + add_only \op, \ev, \rc, \s1, \dg1
  36817. + sha1su1 v\s0\().4s, v\s3\().4s
  36818. + .endm
  36819. +
  36820. + /*
  36821. + * The SHA1 round constants
  36822. + */
  36823. + .align 4
  36824. +.Lsha1_rcon:
  36825. + .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
  36826. +
  36827. + /*
  36828. + * void sha1_ce_transform(int blocks, u8 const *src, u32 *state,
  36829. + * u8 *head, long bytes)
  36830. + */
  36831. +ENTRY(sha1_ce_transform)
  36832. + /* load round constants */
  36833. + adr x6, .Lsha1_rcon
  36834. + ld1r {k0.4s}, [x6], #4
  36835. + ld1r {k1.4s}, [x6], #4
  36836. + ld1r {k2.4s}, [x6], #4
  36837. + ld1r {k3.4s}, [x6]
  36838. +
  36839. + /* load state */
  36840. + ldr dga, [x2]
  36841. + ldr dgb, [x2, #16]
  36842. +
  36843. + /* load partial state (if supplied) */
  36844. + cbz x3, 0f
  36845. + ld1 {v8.4s-v11.4s}, [x3]
  36846. + b 1f
  36847. +
  36848. + /* load input */
  36849. +0: ld1 {v8.4s-v11.4s}, [x1], #64
  36850. + sub w0, w0, #1
  36851. +
  36852. +1:
  36853. +CPU_LE( rev32 v8.16b, v8.16b )
  36854. +CPU_LE( rev32 v9.16b, v9.16b )
  36855. +CPU_LE( rev32 v10.16b, v10.16b )
  36856. +CPU_LE( rev32 v11.16b, v11.16b )
  36857. +
  36858. +2: add t0.4s, v8.4s, k0.4s
  36859. + mov dg0v.16b, dgav.16b
  36860. +
  36861. + add_update c, ev, k0, 8, 9, 10, 11, dgb
  36862. + add_update c, od, k0, 9, 10, 11, 8
  36863. + add_update c, ev, k0, 10, 11, 8, 9
  36864. + add_update c, od, k0, 11, 8, 9, 10
  36865. + add_update c, ev, k1, 8, 9, 10, 11
  36866. +
  36867. + add_update p, od, k1, 9, 10, 11, 8
  36868. + add_update p, ev, k1, 10, 11, 8, 9
  36869. + add_update p, od, k1, 11, 8, 9, 10
  36870. + add_update p, ev, k1, 8, 9, 10, 11
  36871. + add_update p, od, k2, 9, 10, 11, 8
  36872. +
  36873. + add_update m, ev, k2, 10, 11, 8, 9
  36874. + add_update m, od, k2, 11, 8, 9, 10
  36875. + add_update m, ev, k2, 8, 9, 10, 11
  36876. + add_update m, od, k2, 9, 10, 11, 8
  36877. + add_update m, ev, k3, 10, 11, 8, 9
  36878. +
  36879. + add_update p, od, k3, 11, 8, 9, 10
  36880. + add_only p, ev, k3, 9
  36881. + add_only p, od, k3, 10
  36882. + add_only p, ev, k3, 11
  36883. + add_only p, od
  36884. +
  36885. + /* update state */
  36886. + add dgbv.2s, dgbv.2s, dg1v.2s
  36887. + add dgav.4s, dgav.4s, dg0v.4s
  36888. +
  36889. + cbnz w0, 0b
  36890. +
  36891. + /*
  36892. + * Final block: add padding and total bit count.
  36893. + * Skip if we have no total byte count in x4. In that case, the input
  36894. + * size was not a round multiple of the block size, and the padding is
  36895. + * handled by the C code.
  36896. + */
  36897. + cbz x4, 3f
  36898. + movi v9.2d, #0
  36899. + mov x8, #0x80000000
  36900. + movi v10.2d, #0
  36901. + ror x7, x4, #29 // ror(lsl(x4, 3), 32)
  36902. + fmov d8, x8
  36903. + mov x4, #0
  36904. + mov v11.d[0], xzr
  36905. + mov v11.d[1], x7
  36906. + b 2b
  36907. +
  36908. + /* store new state */
  36909. +3: str dga, [x2]
  36910. + str dgb, [x2, #16]
  36911. + ret
  36912. +ENDPROC(sha1_ce_transform)
  36913. diff -Nur linux-3.14.14/arch/arm64/crypto/sha1-ce-glue.c linux-imx6-3.14/arch/arm64/crypto/sha1-ce-glue.c
  36914. --- linux-3.14.14/arch/arm64/crypto/sha1-ce-glue.c 1969-12-31 18:00:00.000000000 -0600
  36915. +++ linux-imx6-3.14/arch/arm64/crypto/sha1-ce-glue.c 2014-12-08 00:31:51.412418001 -0600
  36916. @@ -0,0 +1,174 @@
  36917. +/*
  36918. + * sha1-ce-glue.c - SHA-1 secure hash using ARMv8 Crypto Extensions
  36919. + *
  36920. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  36921. + *
  36922. + * This program is free software; you can redistribute it and/or modify
  36923. + * it under the terms of the GNU General Public License version 2 as
  36924. + * published by the Free Software Foundation.
  36925. + */
  36926. +
  36927. +#include <asm/neon.h>
  36928. +#include <asm/unaligned.h>
  36929. +#include <crypto/internal/hash.h>
  36930. +#include <crypto/sha.h>
  36931. +#include <linux/cpufeature.h>
  36932. +#include <linux/crypto.h>
  36933. +#include <linux/module.h>
  36934. +
  36935. +MODULE_DESCRIPTION("SHA1 secure hash using ARMv8 Crypto Extensions");
  36936. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  36937. +MODULE_LICENSE("GPL v2");
  36938. +
  36939. +asmlinkage void sha1_ce_transform(int blocks, u8 const *src, u32 *state,
  36940. + u8 *head, long bytes);
  36941. +
  36942. +static int sha1_init(struct shash_desc *desc)
  36943. +{
  36944. + struct sha1_state *sctx = shash_desc_ctx(desc);
  36945. +
  36946. + *sctx = (struct sha1_state){
  36947. + .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
  36948. + };
  36949. + return 0;
  36950. +}
  36951. +
  36952. +static int sha1_update(struct shash_desc *desc, const u8 *data,
  36953. + unsigned int len)
  36954. +{
  36955. + struct sha1_state *sctx = shash_desc_ctx(desc);
  36956. + unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
  36957. +
  36958. + sctx->count += len;
  36959. +
  36960. + if ((partial + len) >= SHA1_BLOCK_SIZE) {
  36961. + int blocks;
  36962. +
  36963. + if (partial) {
  36964. + int p = SHA1_BLOCK_SIZE - partial;
  36965. +
  36966. + memcpy(sctx->buffer + partial, data, p);
  36967. + data += p;
  36968. + len -= p;
  36969. + }
  36970. +
  36971. + blocks = len / SHA1_BLOCK_SIZE;
  36972. + len %= SHA1_BLOCK_SIZE;
  36973. +
  36974. + kernel_neon_begin_partial(16);
  36975. + sha1_ce_transform(blocks, data, sctx->state,
  36976. + partial ? sctx->buffer : NULL, 0);
  36977. + kernel_neon_end();
  36978. +
  36979. + data += blocks * SHA1_BLOCK_SIZE;
  36980. + partial = 0;
  36981. + }
  36982. + if (len)
  36983. + memcpy(sctx->buffer + partial, data, len);
  36984. + return 0;
  36985. +}
  36986. +
  36987. +static int sha1_final(struct shash_desc *desc, u8 *out)
  36988. +{
  36989. + static const u8 padding[SHA1_BLOCK_SIZE] = { 0x80, };
  36990. +
  36991. + struct sha1_state *sctx = shash_desc_ctx(desc);
  36992. + __be64 bits = cpu_to_be64(sctx->count << 3);
  36993. + __be32 *dst = (__be32 *)out;
  36994. + int i;
  36995. +
  36996. + u32 padlen = SHA1_BLOCK_SIZE
  36997. + - ((sctx->count + sizeof(bits)) % SHA1_BLOCK_SIZE);
  36998. +
  36999. + sha1_update(desc, padding, padlen);
  37000. + sha1_update(desc, (const u8 *)&bits, sizeof(bits));
  37001. +
  37002. + for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++)
  37003. + put_unaligned_be32(sctx->state[i], dst++);
  37004. +
  37005. + *sctx = (struct sha1_state){};
  37006. + return 0;
  37007. +}
  37008. +
  37009. +static int sha1_finup(struct shash_desc *desc, const u8 *data,
  37010. + unsigned int len, u8 *out)
  37011. +{
  37012. + struct sha1_state *sctx = shash_desc_ctx(desc);
  37013. + __be32 *dst = (__be32 *)out;
  37014. + int blocks;
  37015. + int i;
  37016. +
  37017. + if (sctx->count || !len || (len % SHA1_BLOCK_SIZE)) {
  37018. + sha1_update(desc, data, len);
  37019. + return sha1_final(desc, out);
  37020. + }
  37021. +
  37022. + /*
  37023. + * Use a fast path if the input is a multiple of 64 bytes. In
  37024. + * this case, there is no need to copy data around, and we can
  37025. + * perform the entire digest calculation in a single invocation
  37026. + * of sha1_ce_transform()
  37027. + */
  37028. + blocks = len / SHA1_BLOCK_SIZE;
  37029. +
  37030. + kernel_neon_begin_partial(16);
  37031. + sha1_ce_transform(blocks, data, sctx->state, NULL, len);
  37032. + kernel_neon_end();
  37033. +
  37034. + for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++)
  37035. + put_unaligned_be32(sctx->state[i], dst++);
  37036. +
  37037. + *sctx = (struct sha1_state){};
  37038. + return 0;
  37039. +}
  37040. +
  37041. +static int sha1_export(struct shash_desc *desc, void *out)
  37042. +{
  37043. + struct sha1_state *sctx = shash_desc_ctx(desc);
  37044. + struct sha1_state *dst = out;
  37045. +
  37046. + *dst = *sctx;
  37047. + return 0;
  37048. +}
  37049. +
  37050. +static int sha1_import(struct shash_desc *desc, const void *in)
  37051. +{
  37052. + struct sha1_state *sctx = shash_desc_ctx(desc);
  37053. + struct sha1_state const *src = in;
  37054. +
  37055. + *sctx = *src;
  37056. + return 0;
  37057. +}
  37058. +
  37059. +static struct shash_alg alg = {
  37060. + .init = sha1_init,
  37061. + .update = sha1_update,
  37062. + .final = sha1_final,
  37063. + .finup = sha1_finup,
  37064. + .export = sha1_export,
  37065. + .import = sha1_import,
  37066. + .descsize = sizeof(struct sha1_state),
  37067. + .digestsize = SHA1_DIGEST_SIZE,
  37068. + .statesize = sizeof(struct sha1_state),
  37069. + .base = {
  37070. + .cra_name = "sha1",
  37071. + .cra_driver_name = "sha1-ce",
  37072. + .cra_priority = 200,
  37073. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  37074. + .cra_blocksize = SHA1_BLOCK_SIZE,
  37075. + .cra_module = THIS_MODULE,
  37076. + }
  37077. +};
  37078. +
  37079. +static int __init sha1_ce_mod_init(void)
  37080. +{
  37081. + return crypto_register_shash(&alg);
  37082. +}
  37083. +
  37084. +static void __exit sha1_ce_mod_fini(void)
  37085. +{
  37086. + crypto_unregister_shash(&alg);
  37087. +}
  37088. +
  37089. +module_cpu_feature_match(SHA1, sha1_ce_mod_init);
  37090. +module_exit(sha1_ce_mod_fini);
  37091. diff -Nur linux-3.14.14/arch/arm64/crypto/sha2-ce-core.S linux-imx6-3.14/arch/arm64/crypto/sha2-ce-core.S
  37092. --- linux-3.14.14/arch/arm64/crypto/sha2-ce-core.S 1969-12-31 18:00:00.000000000 -0600
  37093. +++ linux-imx6-3.14/arch/arm64/crypto/sha2-ce-core.S 2014-12-08 00:31:51.412418001 -0600
  37094. @@ -0,0 +1,156 @@
  37095. +/*
  37096. + * sha2-ce-core.S - core SHA-224/SHA-256 transform using v8 Crypto Extensions
  37097. + *
  37098. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  37099. + *
  37100. + * This program is free software; you can redistribute it and/or modify
  37101. + * it under the terms of the GNU General Public License version 2 as
  37102. + * published by the Free Software Foundation.
  37103. + */
  37104. +
  37105. +#include <linux/linkage.h>
  37106. +#include <asm/assembler.h>
  37107. +
  37108. + .text
  37109. + .arch armv8-a+crypto
  37110. +
  37111. + dga .req q20
  37112. + dgav .req v20
  37113. + dgb .req q21
  37114. + dgbv .req v21
  37115. +
  37116. + t0 .req v22
  37117. + t1 .req v23
  37118. +
  37119. + dg0q .req q24
  37120. + dg0v .req v24
  37121. + dg1q .req q25
  37122. + dg1v .req v25
  37123. + dg2q .req q26
  37124. + dg2v .req v26
  37125. +
  37126. + .macro add_only, ev, rc, s0
  37127. + mov dg2v.16b, dg0v.16b
  37128. + .ifeq \ev
  37129. + add t1.4s, v\s0\().4s, \rc\().4s
  37130. + sha256h dg0q, dg1q, t0.4s
  37131. + sha256h2 dg1q, dg2q, t0.4s
  37132. + .else
  37133. + .ifnb \s0
  37134. + add t0.4s, v\s0\().4s, \rc\().4s
  37135. + .endif
  37136. + sha256h dg0q, dg1q, t1.4s
  37137. + sha256h2 dg1q, dg2q, t1.4s
  37138. + .endif
  37139. + .endm
  37140. +
  37141. + .macro add_update, ev, rc, s0, s1, s2, s3
  37142. + sha256su0 v\s0\().4s, v\s1\().4s
  37143. + add_only \ev, \rc, \s1
  37144. + sha256su1 v\s0\().4s, v\s2\().4s, v\s3\().4s
  37145. + .endm
  37146. +
  37147. + /*
  37148. + * The SHA-256 round constants
  37149. + */
  37150. + .align 4
  37151. +.Lsha2_rcon:
  37152. + .word 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
  37153. + .word 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
  37154. + .word 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
  37155. + .word 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
  37156. + .word 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
  37157. + .word 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
  37158. + .word 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
  37159. + .word 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
  37160. + .word 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
  37161. + .word 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
  37162. + .word 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
  37163. + .word 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
  37164. + .word 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
  37165. + .word 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
  37166. + .word 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
  37167. + .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
  37168. +
  37169. + /*
  37170. + * void sha2_ce_transform(int blocks, u8 const *src, u32 *state,
  37171. + * u8 *head, long bytes)
  37172. + */
  37173. +ENTRY(sha2_ce_transform)
  37174. + /* load round constants */
  37175. + adr x8, .Lsha2_rcon
  37176. + ld1 { v0.4s- v3.4s}, [x8], #64
  37177. + ld1 { v4.4s- v7.4s}, [x8], #64
  37178. + ld1 { v8.4s-v11.4s}, [x8], #64
  37179. + ld1 {v12.4s-v15.4s}, [x8]
  37180. +
  37181. + /* load state */
  37182. + ldp dga, dgb, [x2]
  37183. +
  37184. + /* load partial input (if supplied) */
  37185. + cbz x3, 0f
  37186. + ld1 {v16.4s-v19.4s}, [x3]
  37187. + b 1f
  37188. +
  37189. + /* load input */
  37190. +0: ld1 {v16.4s-v19.4s}, [x1], #64
  37191. + sub w0, w0, #1
  37192. +
  37193. +1:
  37194. +CPU_LE( rev32 v16.16b, v16.16b )
  37195. +CPU_LE( rev32 v17.16b, v17.16b )
  37196. +CPU_LE( rev32 v18.16b, v18.16b )
  37197. +CPU_LE( rev32 v19.16b, v19.16b )
  37198. +
  37199. +2: add t0.4s, v16.4s, v0.4s
  37200. + mov dg0v.16b, dgav.16b
  37201. + mov dg1v.16b, dgbv.16b
  37202. +
  37203. + add_update 0, v1, 16, 17, 18, 19
  37204. + add_update 1, v2, 17, 18, 19, 16
  37205. + add_update 0, v3, 18, 19, 16, 17
  37206. + add_update 1, v4, 19, 16, 17, 18
  37207. +
  37208. + add_update 0, v5, 16, 17, 18, 19
  37209. + add_update 1, v6, 17, 18, 19, 16
  37210. + add_update 0, v7, 18, 19, 16, 17
  37211. + add_update 1, v8, 19, 16, 17, 18
  37212. +
  37213. + add_update 0, v9, 16, 17, 18, 19
  37214. + add_update 1, v10, 17, 18, 19, 16
  37215. + add_update 0, v11, 18, 19, 16, 17
  37216. + add_update 1, v12, 19, 16, 17, 18
  37217. +
  37218. + add_only 0, v13, 17
  37219. + add_only 1, v14, 18
  37220. + add_only 0, v15, 19
  37221. + add_only 1
  37222. +
  37223. + /* update state */
  37224. + add dgav.4s, dgav.4s, dg0v.4s
  37225. + add dgbv.4s, dgbv.4s, dg1v.4s
  37226. +
  37227. + /* handled all input blocks? */
  37228. + cbnz w0, 0b
  37229. +
  37230. + /*
  37231. + * Final block: add padding and total bit count.
  37232. + * Skip if we have no total byte count in x4. In that case, the input
  37233. + * size was not a round multiple of the block size, and the padding is
  37234. + * handled by the C code.
  37235. + */
  37236. + cbz x4, 3f
  37237. + movi v17.2d, #0
  37238. + mov x8, #0x80000000
  37239. + movi v18.2d, #0
  37240. + ror x7, x4, #29 // ror(lsl(x4, 3), 32)
  37241. + fmov d16, x8
  37242. + mov x4, #0
  37243. + mov v19.d[0], xzr
  37244. + mov v19.d[1], x7
  37245. + b 2b
  37246. +
  37247. + /* store new state */
  37248. +3: stp dga, dgb, [x2]
  37249. + ret
  37250. +ENDPROC(sha2_ce_transform)
  37251. diff -Nur linux-3.14.14/arch/arm64/crypto/sha2-ce-glue.c linux-imx6-3.14/arch/arm64/crypto/sha2-ce-glue.c
  37252. --- linux-3.14.14/arch/arm64/crypto/sha2-ce-glue.c 1969-12-31 18:00:00.000000000 -0600
  37253. +++ linux-imx6-3.14/arch/arm64/crypto/sha2-ce-glue.c 2014-12-08 00:31:51.412418001 -0600
  37254. @@ -0,0 +1,255 @@
  37255. +/*
  37256. + * sha2-ce-glue.c - SHA-224/SHA-256 using ARMv8 Crypto Extensions
  37257. + *
  37258. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  37259. + *
  37260. + * This program is free software; you can redistribute it and/or modify
  37261. + * it under the terms of the GNU General Public License version 2 as
  37262. + * published by the Free Software Foundation.
  37263. + */
  37264. +
  37265. +#include <asm/neon.h>
  37266. +#include <asm/unaligned.h>
  37267. +#include <crypto/internal/hash.h>
  37268. +#include <crypto/sha.h>
  37269. +#include <linux/cpufeature.h>
  37270. +#include <linux/crypto.h>
  37271. +#include <linux/module.h>
  37272. +
  37273. +MODULE_DESCRIPTION("SHA-224/SHA-256 secure hash using ARMv8 Crypto Extensions");
  37274. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  37275. +MODULE_LICENSE("GPL v2");
  37276. +
  37277. +asmlinkage int sha2_ce_transform(int blocks, u8 const *src, u32 *state,
  37278. + u8 *head, long bytes);
  37279. +
  37280. +static int sha224_init(struct shash_desc *desc)
  37281. +{
  37282. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37283. +
  37284. + *sctx = (struct sha256_state){
  37285. + .state = {
  37286. + SHA224_H0, SHA224_H1, SHA224_H2, SHA224_H3,
  37287. + SHA224_H4, SHA224_H5, SHA224_H6, SHA224_H7,
  37288. + }
  37289. + };
  37290. + return 0;
  37291. +}
  37292. +
  37293. +static int sha256_init(struct shash_desc *desc)
  37294. +{
  37295. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37296. +
  37297. + *sctx = (struct sha256_state){
  37298. + .state = {
  37299. + SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3,
  37300. + SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7,
  37301. + }
  37302. + };
  37303. + return 0;
  37304. +}
  37305. +
  37306. +static int sha2_update(struct shash_desc *desc, const u8 *data,
  37307. + unsigned int len)
  37308. +{
  37309. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37310. + unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
  37311. +
  37312. + sctx->count += len;
  37313. +
  37314. + if ((partial + len) >= SHA256_BLOCK_SIZE) {
  37315. + int blocks;
  37316. +
  37317. + if (partial) {
  37318. + int p = SHA256_BLOCK_SIZE - partial;
  37319. +
  37320. + memcpy(sctx->buf + partial, data, p);
  37321. + data += p;
  37322. + len -= p;
  37323. + }
  37324. +
  37325. + blocks = len / SHA256_BLOCK_SIZE;
  37326. + len %= SHA256_BLOCK_SIZE;
  37327. +
  37328. + kernel_neon_begin_partial(28);
  37329. + sha2_ce_transform(blocks, data, sctx->state,
  37330. + partial ? sctx->buf : NULL, 0);
  37331. + kernel_neon_end();
  37332. +
  37333. + data += blocks * SHA256_BLOCK_SIZE;
  37334. + partial = 0;
  37335. + }
  37336. + if (len)
  37337. + memcpy(sctx->buf + partial, data, len);
  37338. + return 0;
  37339. +}
  37340. +
  37341. +static void sha2_final(struct shash_desc *desc)
  37342. +{
  37343. + static const u8 padding[SHA256_BLOCK_SIZE] = { 0x80, };
  37344. +
  37345. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37346. + __be64 bits = cpu_to_be64(sctx->count << 3);
  37347. + u32 padlen = SHA256_BLOCK_SIZE
  37348. + - ((sctx->count + sizeof(bits)) % SHA256_BLOCK_SIZE);
  37349. +
  37350. + sha2_update(desc, padding, padlen);
  37351. + sha2_update(desc, (const u8 *)&bits, sizeof(bits));
  37352. +}
  37353. +
  37354. +static int sha224_final(struct shash_desc *desc, u8 *out)
  37355. +{
  37356. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37357. + __be32 *dst = (__be32 *)out;
  37358. + int i;
  37359. +
  37360. + sha2_final(desc);
  37361. +
  37362. + for (i = 0; i < SHA224_DIGEST_SIZE / sizeof(__be32); i++)
  37363. + put_unaligned_be32(sctx->state[i], dst++);
  37364. +
  37365. + *sctx = (struct sha256_state){};
  37366. + return 0;
  37367. +}
  37368. +
  37369. +static int sha256_final(struct shash_desc *desc, u8 *out)
  37370. +{
  37371. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37372. + __be32 *dst = (__be32 *)out;
  37373. + int i;
  37374. +
  37375. + sha2_final(desc);
  37376. +
  37377. + for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(__be32); i++)
  37378. + put_unaligned_be32(sctx->state[i], dst++);
  37379. +
  37380. + *sctx = (struct sha256_state){};
  37381. + return 0;
  37382. +}
  37383. +
  37384. +static void sha2_finup(struct shash_desc *desc, const u8 *data,
  37385. + unsigned int len)
  37386. +{
  37387. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37388. + int blocks;
  37389. +
  37390. + if (sctx->count || !len || (len % SHA256_BLOCK_SIZE)) {
  37391. + sha2_update(desc, data, len);
  37392. + sha2_final(desc);
  37393. + return;
  37394. + }
  37395. +
  37396. + /*
  37397. + * Use a fast path if the input is a multiple of 64 bytes. In
  37398. + * this case, there is no need to copy data around, and we can
  37399. + * perform the entire digest calculation in a single invocation
  37400. + * of sha2_ce_transform()
  37401. + */
  37402. + blocks = len / SHA256_BLOCK_SIZE;
  37403. +
  37404. + kernel_neon_begin_partial(28);
  37405. + sha2_ce_transform(blocks, data, sctx->state, NULL, len);
  37406. + kernel_neon_end();
  37407. + data += blocks * SHA256_BLOCK_SIZE;
  37408. +}
  37409. +
  37410. +static int sha224_finup(struct shash_desc *desc, const u8 *data,
  37411. + unsigned int len, u8 *out)
  37412. +{
  37413. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37414. + __be32 *dst = (__be32 *)out;
  37415. + int i;
  37416. +
  37417. + sha2_finup(desc, data, len);
  37418. +
  37419. + for (i = 0; i < SHA224_DIGEST_SIZE / sizeof(__be32); i++)
  37420. + put_unaligned_be32(sctx->state[i], dst++);
  37421. +
  37422. + *sctx = (struct sha256_state){};
  37423. + return 0;
  37424. +}
  37425. +
  37426. +static int sha256_finup(struct shash_desc *desc, const u8 *data,
  37427. + unsigned int len, u8 *out)
  37428. +{
  37429. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37430. + __be32 *dst = (__be32 *)out;
  37431. + int i;
  37432. +
  37433. + sha2_finup(desc, data, len);
  37434. +
  37435. + for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(__be32); i++)
  37436. + put_unaligned_be32(sctx->state[i], dst++);
  37437. +
  37438. + *sctx = (struct sha256_state){};
  37439. + return 0;
  37440. +}
  37441. +
  37442. +static int sha2_export(struct shash_desc *desc, void *out)
  37443. +{
  37444. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37445. + struct sha256_state *dst = out;
  37446. +
  37447. + *dst = *sctx;
  37448. + return 0;
  37449. +}
  37450. +
  37451. +static int sha2_import(struct shash_desc *desc, const void *in)
  37452. +{
  37453. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37454. + struct sha256_state const *src = in;
  37455. +
  37456. + *sctx = *src;
  37457. + return 0;
  37458. +}
  37459. +
  37460. +static struct shash_alg algs[] = { {
  37461. + .init = sha224_init,
  37462. + .update = sha2_update,
  37463. + .final = sha224_final,
  37464. + .finup = sha224_finup,
  37465. + .export = sha2_export,
  37466. + .import = sha2_import,
  37467. + .descsize = sizeof(struct sha256_state),
  37468. + .digestsize = SHA224_DIGEST_SIZE,
  37469. + .statesize = sizeof(struct sha256_state),
  37470. + .base = {
  37471. + .cra_name = "sha224",
  37472. + .cra_driver_name = "sha224-ce",
  37473. + .cra_priority = 200,
  37474. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  37475. + .cra_blocksize = SHA256_BLOCK_SIZE,
  37476. + .cra_module = THIS_MODULE,
  37477. + }
  37478. +}, {
  37479. + .init = sha256_init,
  37480. + .update = sha2_update,
  37481. + .final = sha256_final,
  37482. + .finup = sha256_finup,
  37483. + .export = sha2_export,
  37484. + .import = sha2_import,
  37485. + .descsize = sizeof(struct sha256_state),
  37486. + .digestsize = SHA256_DIGEST_SIZE,
  37487. + .statesize = sizeof(struct sha256_state),
  37488. + .base = {
  37489. + .cra_name = "sha256",
  37490. + .cra_driver_name = "sha256-ce",
  37491. + .cra_priority = 200,
  37492. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  37493. + .cra_blocksize = SHA256_BLOCK_SIZE,
  37494. + .cra_module = THIS_MODULE,
  37495. + }
  37496. +} };
  37497. +
  37498. +static int __init sha2_ce_mod_init(void)
  37499. +{
  37500. + return crypto_register_shashes(algs, ARRAY_SIZE(algs));
  37501. +}
  37502. +
  37503. +static void __exit sha2_ce_mod_fini(void)
  37504. +{
  37505. + crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
  37506. +}
  37507. +
  37508. +module_cpu_feature_match(SHA2, sha2_ce_mod_init);
  37509. +module_exit(sha2_ce_mod_fini);
  37510. diff -Nur linux-3.14.14/arch/arm64/include/asm/bL_switcher.h linux-imx6-3.14/arch/arm64/include/asm/bL_switcher.h
  37511. --- linux-3.14.14/arch/arm64/include/asm/bL_switcher.h 1969-12-31 18:00:00.000000000 -0600
  37512. +++ linux-imx6-3.14/arch/arm64/include/asm/bL_switcher.h 2014-12-08 00:31:51.412418001 -0600
  37513. @@ -0,0 +1,54 @@
  37514. +/*
  37515. + * Based on the stubs for the ARM implementation which is:
  37516. + *
  37517. + * Created by: Nicolas Pitre, April 2012
  37518. + * Copyright: (C) 2012-2013 Linaro Limited
  37519. + *
  37520. + * This program is free software; you can redistribute it and/or modify
  37521. + * it under the terms of the GNU General Public License version 2 as
  37522. + * published by the Free Software Foundation.
  37523. + */
  37524. +
  37525. +#ifndef ASM_BL_SWITCHER_H
  37526. +#define ASM_BL_SWITCHER_H
  37527. +
  37528. +#include <linux/notifier.h>
  37529. +#include <linux/types.h>
  37530. +
  37531. +typedef void (*bL_switch_completion_handler)(void *cookie);
  37532. +
  37533. +static inline int bL_switch_request(unsigned int cpu,
  37534. + unsigned int new_cluster_id)
  37535. +{
  37536. + return -ENOTSUPP;
  37537. +}
  37538. +
  37539. +/*
  37540. + * Register here to be notified about runtime enabling/disabling of
  37541. + * the switcher.
  37542. + *
  37543. + * The notifier chain is called with the switcher activation lock held:
  37544. + * the switcher will not be enabled or disabled during callbacks.
  37545. + * Callbacks must not call bL_switcher_{get,put}_enabled().
  37546. + */
  37547. +#define BL_NOTIFY_PRE_ENABLE 0
  37548. +#define BL_NOTIFY_POST_ENABLE 1
  37549. +#define BL_NOTIFY_PRE_DISABLE 2
  37550. +#define BL_NOTIFY_POST_DISABLE 3
  37551. +
  37552. +static inline int bL_switcher_register_notifier(struct notifier_block *nb)
  37553. +{
  37554. + return 0;
  37555. +}
  37556. +
  37557. +static inline int bL_switcher_unregister_notifier(struct notifier_block *nb)
  37558. +{
  37559. + return 0;
  37560. +}
  37561. +
  37562. +static inline bool bL_switcher_get_enabled(void) { return false; }
  37563. +static inline void bL_switcher_put_enabled(void) { }
  37564. +static inline int bL_switcher_trace_trigger(void) { return 0; }
  37565. +static inline int bL_switcher_get_logical_index(u32 mpidr) { return -EUNATCH; }
  37566. +
  37567. +#endif
  37568. diff -Nur linux-3.14.14/arch/arm64/include/asm/cacheflush.h linux-imx6-3.14/arch/arm64/include/asm/cacheflush.h
  37569. --- linux-3.14.14/arch/arm64/include/asm/cacheflush.h 2014-07-28 10:07:25.000000000 -0500
  37570. +++ linux-imx6-3.14/arch/arm64/include/asm/cacheflush.h 2014-12-08 00:31:51.412418001 -0600
  37571. @@ -85,6 +85,13 @@
  37572. }
  37573. /*
  37574. + * Cache maintenance functions used by the DMA API. No to be used directly.
  37575. + */
  37576. +extern void __dma_map_area(const void *, size_t, int);
  37577. +extern void __dma_unmap_area(const void *, size_t, int);
  37578. +extern void __dma_flush_range(const void *, const void *);
  37579. +
  37580. +/*
  37581. * Copy user data from/to a page which is mapped into a different
  37582. * processes address space. Really, we want to allow our "user
  37583. * space" model to handle this.
  37584. diff -Nur linux-3.14.14/arch/arm64/include/asm/compat.h linux-imx6-3.14/arch/arm64/include/asm/compat.h
  37585. --- linux-3.14.14/arch/arm64/include/asm/compat.h 2014-07-28 10:07:25.000000000 -0500
  37586. +++ linux-imx6-3.14/arch/arm64/include/asm/compat.h 2014-12-08 00:31:51.412418001 -0600
  37587. @@ -228,7 +228,7 @@
  37588. return (u32)(unsigned long)uptr;
  37589. }
  37590. -#define compat_user_stack_pointer() (current_pt_regs()->compat_sp)
  37591. +#define compat_user_stack_pointer() (user_stack_pointer(current_pt_regs()))
  37592. static inline void __user *arch_compat_alloc_user_space(long len)
  37593. {
  37594. @@ -305,11 +305,6 @@
  37595. #else /* !CONFIG_COMPAT */
  37596. -static inline int is_compat_task(void)
  37597. -{
  37598. - return 0;
  37599. -}
  37600. -
  37601. static inline int is_compat_thread(struct thread_info *thread)
  37602. {
  37603. return 0;
  37604. diff -Nur linux-3.14.14/arch/arm64/include/asm/cpufeature.h linux-imx6-3.14/arch/arm64/include/asm/cpufeature.h
  37605. --- linux-3.14.14/arch/arm64/include/asm/cpufeature.h 1969-12-31 18:00:00.000000000 -0600
  37606. +++ linux-imx6-3.14/arch/arm64/include/asm/cpufeature.h 2014-12-08 00:31:51.412418001 -0600
  37607. @@ -0,0 +1,29 @@
  37608. +/*
  37609. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  37610. + *
  37611. + * This program is free software; you can redistribute it and/or modify
  37612. + * it under the terms of the GNU General Public License version 2 as
  37613. + * published by the Free Software Foundation.
  37614. + */
  37615. +
  37616. +#ifndef __ASM_CPUFEATURE_H
  37617. +#define __ASM_CPUFEATURE_H
  37618. +
  37619. +#include <asm/hwcap.h>
  37620. +
  37621. +/*
  37622. + * In the arm64 world (as in the ARM world), elf_hwcap is used both internally
  37623. + * in the kernel and for user space to keep track of which optional features
  37624. + * are supported by the current system. So let's map feature 'x' to HWCAP_x.
  37625. + * Note that HWCAP_x constants are bit fields so we need to take the log.
  37626. + */
  37627. +
  37628. +#define MAX_CPU_FEATURES (8 * sizeof(elf_hwcap))
  37629. +#define cpu_feature(x) ilog2(HWCAP_ ## x)
  37630. +
  37631. +static inline bool cpu_have_feature(unsigned int num)
  37632. +{
  37633. + return elf_hwcap & (1UL << num);
  37634. +}
  37635. +
  37636. +#endif
  37637. diff -Nur linux-3.14.14/arch/arm64/include/asm/debug-monitors.h linux-imx6-3.14/arch/arm64/include/asm/debug-monitors.h
  37638. --- linux-3.14.14/arch/arm64/include/asm/debug-monitors.h 2014-07-28 10:07:25.000000000 -0500
  37639. +++ linux-imx6-3.14/arch/arm64/include/asm/debug-monitors.h 2014-12-08 00:31:51.412418001 -0600
  37640. @@ -26,6 +26,53 @@
  37641. #define DBG_ESR_EVT_HWWP 0x2
  37642. #define DBG_ESR_EVT_BRK 0x6
  37643. +/*
  37644. + * Break point instruction encoding
  37645. + */
  37646. +#define BREAK_INSTR_SIZE 4
  37647. +
  37648. +/*
  37649. + * ESR values expected for dynamic and compile time BRK instruction
  37650. + */
  37651. +#define DBG_ESR_VAL_BRK(x) (0xf2000000 | ((x) & 0xfffff))
  37652. +
  37653. +/*
  37654. + * #imm16 values used for BRK instruction generation
  37655. + * Allowed values for kgbd are 0x400 - 0x7ff
  37656. + * 0x400: for dynamic BRK instruction
  37657. + * 0x401: for compile time BRK instruction
  37658. + */
  37659. +#define KGDB_DYN_DGB_BRK_IMM 0x400
  37660. +#define KDBG_COMPILED_DBG_BRK_IMM 0x401
  37661. +
  37662. +/*
  37663. + * BRK instruction encoding
  37664. + * The #imm16 value should be placed at bits[20:5] within BRK ins
  37665. + */
  37666. +#define AARCH64_BREAK_MON 0xd4200000
  37667. +
  37668. +/*
  37669. + * Extract byte from BRK instruction
  37670. + */
  37671. +#define KGDB_DYN_DGB_BRK_INS_BYTE(x) \
  37672. + ((((AARCH64_BREAK_MON) & 0xffe0001f) >> (x * 8)) & 0xff)
  37673. +
  37674. +/*
  37675. + * Extract byte from BRK #imm16
  37676. + */
  37677. +#define KGBD_DYN_DGB_BRK_IMM_BYTE(x) \
  37678. + (((((KGDB_DYN_DGB_BRK_IMM) & 0xffff) << 5) >> (x * 8)) & 0xff)
  37679. +
  37680. +#define KGDB_DYN_DGB_BRK_BYTE(x) \
  37681. + (KGDB_DYN_DGB_BRK_INS_BYTE(x) | KGBD_DYN_DGB_BRK_IMM_BYTE(x))
  37682. +
  37683. +#define KGDB_DYN_BRK_INS_BYTE0 KGDB_DYN_DGB_BRK_BYTE(0)
  37684. +#define KGDB_DYN_BRK_INS_BYTE1 KGDB_DYN_DGB_BRK_BYTE(1)
  37685. +#define KGDB_DYN_BRK_INS_BYTE2 KGDB_DYN_DGB_BRK_BYTE(2)
  37686. +#define KGDB_DYN_BRK_INS_BYTE3 KGDB_DYN_DGB_BRK_BYTE(3)
  37687. +
  37688. +#define CACHE_FLUSH_IS_SAFE 1
  37689. +
  37690. enum debug_el {
  37691. DBG_ACTIVE_EL0 = 0,
  37692. DBG_ACTIVE_EL1,
  37693. @@ -43,23 +90,6 @@
  37694. #ifndef __ASSEMBLY__
  37695. struct task_struct;
  37696. -#define local_dbg_save(flags) \
  37697. - do { \
  37698. - typecheck(unsigned long, flags); \
  37699. - asm volatile( \
  37700. - "mrs %0, daif // local_dbg_save\n" \
  37701. - "msr daifset, #8" \
  37702. - : "=r" (flags) : : "memory"); \
  37703. - } while (0)
  37704. -
  37705. -#define local_dbg_restore(flags) \
  37706. - do { \
  37707. - typecheck(unsigned long, flags); \
  37708. - asm volatile( \
  37709. - "msr daif, %0 // local_dbg_restore\n" \
  37710. - : : "r" (flags) : "memory"); \
  37711. - } while (0)
  37712. -
  37713. #define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
  37714. #define DBG_HOOK_HANDLED 0
  37715. diff -Nur linux-3.14.14/arch/arm64/include/asm/dma-mapping.h linux-imx6-3.14/arch/arm64/include/asm/dma-mapping.h
  37716. --- linux-3.14.14/arch/arm64/include/asm/dma-mapping.h 2014-07-28 10:07:25.000000000 -0500
  37717. +++ linux-imx6-3.14/arch/arm64/include/asm/dma-mapping.h 2014-12-08 00:31:51.412418001 -0600
  37718. @@ -28,6 +28,8 @@
  37719. #define DMA_ERROR_CODE (~(dma_addr_t)0)
  37720. extern struct dma_map_ops *dma_ops;
  37721. +extern struct dma_map_ops coherent_swiotlb_dma_ops;
  37722. +extern struct dma_map_ops noncoherent_swiotlb_dma_ops;
  37723. static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
  37724. {
  37725. @@ -45,6 +47,11 @@
  37726. return __generic_dma_ops(dev);
  37727. }
  37728. +static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
  37729. +{
  37730. + dev->archdata.dma_ops = ops;
  37731. +}
  37732. +
  37733. #include <asm-generic/dma-mapping-common.h>
  37734. static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
  37735. diff -Nur linux-3.14.14/arch/arm64/include/asm/ftrace.h linux-imx6-3.14/arch/arm64/include/asm/ftrace.h
  37736. --- linux-3.14.14/arch/arm64/include/asm/ftrace.h 1969-12-31 18:00:00.000000000 -0600
  37737. +++ linux-imx6-3.14/arch/arm64/include/asm/ftrace.h 2014-12-08 00:31:51.412418001 -0600
  37738. @@ -0,0 +1,59 @@
  37739. +/*
  37740. + * arch/arm64/include/asm/ftrace.h
  37741. + *
  37742. + * Copyright (C) 2013 Linaro Limited
  37743. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  37744. + *
  37745. + * This program is free software; you can redistribute it and/or modify
  37746. + * it under the terms of the GNU General Public License version 2 as
  37747. + * published by the Free Software Foundation.
  37748. + */
  37749. +#ifndef __ASM_FTRACE_H
  37750. +#define __ASM_FTRACE_H
  37751. +
  37752. +#include <asm/insn.h>
  37753. +
  37754. +#define MCOUNT_ADDR ((unsigned long)_mcount)
  37755. +#define MCOUNT_INSN_SIZE AARCH64_INSN_SIZE
  37756. +
  37757. +#ifndef __ASSEMBLY__
  37758. +#include <linux/compat.h>
  37759. +
  37760. +extern void _mcount(unsigned long);
  37761. +extern void *return_address(unsigned int);
  37762. +
  37763. +struct dyn_arch_ftrace {
  37764. + /* No extra data needed for arm64 */
  37765. +};
  37766. +
  37767. +extern unsigned long ftrace_graph_call;
  37768. +
  37769. +static inline unsigned long ftrace_call_adjust(unsigned long addr)
  37770. +{
  37771. + /*
  37772. + * addr is the address of the mcount call instruction.
  37773. + * recordmcount does the necessary offset calculation.
  37774. + */
  37775. + return addr;
  37776. +}
  37777. +
  37778. +#define ftrace_return_address(n) return_address(n)
  37779. +
  37780. +/*
  37781. + * Because AArch32 mode does not share the same syscall table with AArch64,
  37782. + * tracing compat syscalls may result in reporting bogus syscalls or even
  37783. + * hang-up, so just do not trace them.
  37784. + * See kernel/trace/trace_syscalls.c
  37785. + *
  37786. + * x86 code says:
  37787. + * If the user realy wants these, then they should use the
  37788. + * raw syscall tracepoints with filtering.
  37789. + */
  37790. +#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
  37791. +static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
  37792. +{
  37793. + return is_compat_task();
  37794. +}
  37795. +#endif /* ifndef __ASSEMBLY__ */
  37796. +
  37797. +#endif /* __ASM_FTRACE_H */
  37798. diff -Nur linux-3.14.14/arch/arm64/include/asm/hwcap.h linux-imx6-3.14/arch/arm64/include/asm/hwcap.h
  37799. --- linux-3.14.14/arch/arm64/include/asm/hwcap.h 2014-07-28 10:07:25.000000000 -0500
  37800. +++ linux-imx6-3.14/arch/arm64/include/asm/hwcap.h 2014-12-08 00:31:51.412418001 -0600
  37801. @@ -32,6 +32,12 @@
  37802. #define COMPAT_HWCAP_IDIV (COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT)
  37803. #define COMPAT_HWCAP_EVTSTRM (1 << 21)
  37804. +#define COMPAT_HWCAP2_AES (1 << 0)
  37805. +#define COMPAT_HWCAP2_PMULL (1 << 1)
  37806. +#define COMPAT_HWCAP2_SHA1 (1 << 2)
  37807. +#define COMPAT_HWCAP2_SHA2 (1 << 3)
  37808. +#define COMPAT_HWCAP2_CRC32 (1 << 4)
  37809. +
  37810. #ifndef __ASSEMBLY__
  37811. /*
  37812. * This yields a mask that user programs can use to figure out what
  37813. @@ -41,7 +47,8 @@
  37814. #ifdef CONFIG_COMPAT
  37815. #define COMPAT_ELF_HWCAP (compat_elf_hwcap)
  37816. -extern unsigned int compat_elf_hwcap;
  37817. +#define COMPAT_ELF_HWCAP2 (compat_elf_hwcap2)
  37818. +extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
  37819. #endif
  37820. extern unsigned long elf_hwcap;
  37821. diff -Nur linux-3.14.14/arch/arm64/include/asm/insn.h linux-imx6-3.14/arch/arm64/include/asm/insn.h
  37822. --- linux-3.14.14/arch/arm64/include/asm/insn.h 2014-07-28 10:07:25.000000000 -0500
  37823. +++ linux-imx6-3.14/arch/arm64/include/asm/insn.h 2014-12-08 00:31:51.412418001 -0600
  37824. @@ -16,11 +16,14 @@
  37825. */
  37826. #ifndef __ASM_INSN_H
  37827. #define __ASM_INSN_H
  37828. +
  37829. #include <linux/types.h>
  37830. /* A64 instructions are always 32 bits. */
  37831. #define AARCH64_INSN_SIZE 4
  37832. +#ifndef __ASSEMBLY__
  37833. +
  37834. /*
  37835. * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
  37836. * Section C3.1 "A64 instruction index by encoding":
  37837. @@ -105,4 +108,6 @@
  37838. int aarch64_insn_patch_text_sync(void *addrs[], u32 insns[], int cnt);
  37839. int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
  37840. +#endif /* __ASSEMBLY__ */
  37841. +
  37842. #endif /* __ASM_INSN_H */
  37843. diff -Nur linux-3.14.14/arch/arm64/include/asm/irqflags.h linux-imx6-3.14/arch/arm64/include/asm/irqflags.h
  37844. --- linux-3.14.14/arch/arm64/include/asm/irqflags.h 2014-07-28 10:07:25.000000000 -0500
  37845. +++ linux-imx6-3.14/arch/arm64/include/asm/irqflags.h 2014-12-08 00:31:51.412418001 -0600
  37846. @@ -90,5 +90,28 @@
  37847. return flags & PSR_I_BIT;
  37848. }
  37849. +/*
  37850. + * save and restore debug state
  37851. + */
  37852. +#define local_dbg_save(flags) \
  37853. + do { \
  37854. + typecheck(unsigned long, flags); \
  37855. + asm volatile( \
  37856. + "mrs %0, daif // local_dbg_save\n" \
  37857. + "msr daifset, #8" \
  37858. + : "=r" (flags) : : "memory"); \
  37859. + } while (0)
  37860. +
  37861. +#define local_dbg_restore(flags) \
  37862. + do { \
  37863. + typecheck(unsigned long, flags); \
  37864. + asm volatile( \
  37865. + "msr daif, %0 // local_dbg_restore\n" \
  37866. + : : "r" (flags) : "memory"); \
  37867. + } while (0)
  37868. +
  37869. +#define local_dbg_enable() asm("msr daifclr, #8" : : : "memory")
  37870. +#define local_dbg_disable() asm("msr daifset, #8" : : : "memory")
  37871. +
  37872. #endif
  37873. #endif
  37874. diff -Nur linux-3.14.14/arch/arm64/include/asm/Kbuild linux-imx6-3.14/arch/arm64/include/asm/Kbuild
  37875. --- linux-3.14.14/arch/arm64/include/asm/Kbuild 2014-07-28 10:07:25.000000000 -0500
  37876. +++ linux-imx6-3.14/arch/arm64/include/asm/Kbuild 2014-12-08 00:31:51.412418001 -0600
  37877. @@ -35,6 +35,7 @@
  37878. generic-y += sembuf.h
  37879. generic-y += serial.h
  37880. generic-y += shmbuf.h
  37881. +generic-y += simd.h
  37882. generic-y += sizes.h
  37883. generic-y += socket.h
  37884. generic-y += sockios.h
  37885. diff -Nur linux-3.14.14/arch/arm64/include/asm/kgdb.h linux-imx6-3.14/arch/arm64/include/asm/kgdb.h
  37886. --- linux-3.14.14/arch/arm64/include/asm/kgdb.h 1969-12-31 18:00:00.000000000 -0600
  37887. +++ linux-imx6-3.14/arch/arm64/include/asm/kgdb.h 2014-12-08 00:31:51.412418001 -0600
  37888. @@ -0,0 +1,84 @@
  37889. +/*
  37890. + * AArch64 KGDB support
  37891. + *
  37892. + * Based on arch/arm/include/kgdb.h
  37893. + *
  37894. + * Copyright (C) 2013 Cavium Inc.
  37895. + * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>
  37896. + *
  37897. + * This program is free software; you can redistribute it and/or modify
  37898. + * it under the terms of the GNU General Public License version 2 as
  37899. + * published by the Free Software Foundation.
  37900. + *
  37901. + * This program is distributed in the hope that it will be useful,
  37902. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  37903. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  37904. + * GNU General Public License for more details.
  37905. + *
  37906. + * You should have received a copy of the GNU General Public License
  37907. + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  37908. + */
  37909. +
  37910. +#ifndef __ARM_KGDB_H
  37911. +#define __ARM_KGDB_H
  37912. +
  37913. +#include <linux/ptrace.h>
  37914. +#include <asm/debug-monitors.h>
  37915. +
  37916. +#ifndef __ASSEMBLY__
  37917. +
  37918. +static inline void arch_kgdb_breakpoint(void)
  37919. +{
  37920. + asm ("brk %0" : : "I" (KDBG_COMPILED_DBG_BRK_IMM));
  37921. +}
  37922. +
  37923. +extern void kgdb_handle_bus_error(void);
  37924. +extern int kgdb_fault_expected;
  37925. +
  37926. +#endif /* !__ASSEMBLY__ */
  37927. +
  37928. +/*
  37929. + * gdb is expecting the following registers layout.
  37930. + *
  37931. + * General purpose regs:
  37932. + * r0-r30: 64 bit
  37933. + * sp,pc : 64 bit
  37934. + * pstate : 64 bit
  37935. + * Total: 34
  37936. + * FPU regs:
  37937. + * f0-f31: 128 bit
  37938. + * Total: 32
  37939. + * Extra regs
  37940. + * fpsr & fpcr: 32 bit
  37941. + * Total: 2
  37942. + *
  37943. + */
  37944. +
  37945. +#define _GP_REGS 34
  37946. +#define _FP_REGS 32
  37947. +#define _EXTRA_REGS 2
  37948. +/*
  37949. + * general purpose registers size in bytes.
  37950. + * pstate is only 4 bytes. subtract 4 bytes
  37951. + */
  37952. +#define GP_REG_BYTES (_GP_REGS * 8)
  37953. +#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS)
  37954. +
  37955. +/*
  37956. + * Size of I/O buffer for gdb packet.
  37957. + * considering to hold all register contents, size is set
  37958. + */
  37959. +
  37960. +#define BUFMAX 2048
  37961. +
  37962. +/*
  37963. + * Number of bytes required for gdb_regs buffer.
  37964. + * _GP_REGS: 8 bytes, _FP_REGS: 16 bytes and _EXTRA_REGS: 4 bytes each
  37965. + * GDB fails to connect for size beyond this with error
  37966. + * "'g' packet reply is too long"
  37967. + */
  37968. +
  37969. +#define NUMREGBYTES ((_GP_REGS * 8) + (_FP_REGS * 16) + \
  37970. + (_EXTRA_REGS * 4))
  37971. +
  37972. +#endif /* __ASM_KGDB_H */
  37973. diff -Nur linux-3.14.14/arch/arm64/include/asm/page.h linux-imx6-3.14/arch/arm64/include/asm/page.h
  37974. --- linux-3.14.14/arch/arm64/include/asm/page.h 2014-07-28 10:07:25.000000000 -0500
  37975. +++ linux-imx6-3.14/arch/arm64/include/asm/page.h 2014-12-08 00:31:51.412418001 -0600
  37976. @@ -31,6 +31,15 @@
  37977. /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
  37978. #define __HAVE_ARCH_GATE_AREA 1
  37979. +/*
  37980. + * The idmap and swapper page tables need some space reserved in the kernel
  37981. + * image. The idmap only requires a pgd and a next level table to (section) map
  37982. + * the kernel, while the swapper also maps the FDT and requires an additional
  37983. + * table to map an early UART. See __create_page_tables for more information.
  37984. + */
  37985. +#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
  37986. +#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
  37987. +
  37988. #ifndef __ASSEMBLY__
  37989. #ifdef CONFIG_ARM64_64K_PAGES
  37990. diff -Nur linux-3.14.14/arch/arm64/include/asm/pgtable.h linux-imx6-3.14/arch/arm64/include/asm/pgtable.h
  37991. --- linux-3.14.14/arch/arm64/include/asm/pgtable.h 2014-07-28 10:07:25.000000000 -0500
  37992. +++ linux-imx6-3.14/arch/arm64/include/asm/pgtable.h 2014-12-08 00:31:51.416418001 -0600
  37993. @@ -227,36 +227,36 @@
  37994. #define __HAVE_ARCH_PTE_SPECIAL
  37995. -/*
  37996. - * Software PMD bits for THP
  37997. - */
  37998. +static inline pte_t pmd_pte(pmd_t pmd)
  37999. +{
  38000. + return __pte(pmd_val(pmd));
  38001. +}
  38002. -#define PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55)
  38003. -#define PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 57)
  38004. +static inline pmd_t pte_pmd(pte_t pte)
  38005. +{
  38006. + return __pmd(pte_val(pte));
  38007. +}
  38008. /*
  38009. * THP definitions.
  38010. */
  38011. -#define pmd_young(pmd) (pmd_val(pmd) & PMD_SECT_AF)
  38012. -
  38013. -#define __HAVE_ARCH_PMD_WRITE
  38014. -#define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY))
  38015. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  38016. #define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
  38017. -#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
  38018. +#define pmd_trans_splitting(pmd) pte_special(pmd_pte(pmd))
  38019. #endif
  38020. -#define PMD_BIT_FUNC(fn,op) \
  38021. -static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
  38022. +#define pmd_young(pmd) pte_young(pmd_pte(pmd))
  38023. +#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
  38024. +#define pmd_mksplitting(pmd) pte_pmd(pte_mkspecial(pmd_pte(pmd)))
  38025. +#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
  38026. +#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
  38027. +#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
  38028. +#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
  38029. +#define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) &= ~PMD_TYPE_MASK))
  38030. -PMD_BIT_FUNC(wrprotect, |= PMD_SECT_RDONLY);
  38031. -PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF);
  38032. -PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING);
  38033. -PMD_BIT_FUNC(mkwrite, &= ~PMD_SECT_RDONLY);
  38034. -PMD_BIT_FUNC(mkdirty, |= PMD_SECT_DIRTY);
  38035. -PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
  38036. -PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
  38037. +#define __HAVE_ARCH_PMD_WRITE
  38038. +#define pmd_write(pmd) pte_write(pmd_pte(pmd))
  38039. #define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
  38040. @@ -266,16 +266,7 @@
  38041. #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
  38042. -static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
  38043. -{
  38044. - const pmdval_t mask = PMD_SECT_USER | PMD_SECT_PXN | PMD_SECT_UXN |
  38045. - PMD_SECT_RDONLY | PMD_SECT_PROT_NONE |
  38046. - PMD_SECT_VALID;
  38047. - pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
  38048. - return pmd;
  38049. -}
  38050. -
  38051. -#define set_pmd_at(mm, addr, pmdp, pmd) set_pmd(pmdp, pmd)
  38052. +#define set_pmd_at(mm, addr, pmdp, pmd) set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd))
  38053. static inline int has_transparent_hugepage(void)
  38054. {
  38055. @@ -383,12 +374,14 @@
  38056. return pte;
  38057. }
  38058. +static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
  38059. +{
  38060. + return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
  38061. +}
  38062. +
  38063. extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
  38064. extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
  38065. -#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
  38066. -#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
  38067. -
  38068. /*
  38069. * Encode and decode a swap entry:
  38070. * bits 0-1: present (must be zero)
  38071. diff -Nur linux-3.14.14/arch/arm64/include/asm/ptrace.h linux-imx6-3.14/arch/arm64/include/asm/ptrace.h
  38072. --- linux-3.14.14/arch/arm64/include/asm/ptrace.h 2014-07-28 10:07:25.000000000 -0500
  38073. +++ linux-imx6-3.14/arch/arm64/include/asm/ptrace.h 2014-12-08 00:31:51.416418001 -0600
  38074. @@ -68,6 +68,7 @@
  38075. /* Architecturally defined mapping between AArch32 and AArch64 registers */
  38076. #define compat_usr(x) regs[(x)]
  38077. +#define compat_fp regs[11]
  38078. #define compat_sp regs[13]
  38079. #define compat_lr regs[14]
  38080. #define compat_sp_hyp regs[15]
  38081. @@ -132,7 +133,12 @@
  38082. (!((regs)->pstate & PSR_F_BIT))
  38083. #define user_stack_pointer(regs) \
  38084. - ((regs)->sp)
  38085. + (!compat_user_mode(regs)) ? ((regs)->sp) : ((regs)->compat_sp)
  38086. +
  38087. +static inline unsigned long regs_return_value(struct pt_regs *regs)
  38088. +{
  38089. + return regs->regs[0];
  38090. +}
  38091. /*
  38092. * Are the current registers suitable for user mode? (used to maintain
  38093. @@ -164,7 +170,7 @@
  38094. return 0;
  38095. }
  38096. -#define instruction_pointer(regs) (regs)->pc
  38097. +#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
  38098. #ifdef CONFIG_SMP
  38099. extern unsigned long profile_pc(struct pt_regs *regs);
  38100. diff -Nur linux-3.14.14/arch/arm64/include/asm/syscall.h linux-imx6-3.14/arch/arm64/include/asm/syscall.h
  38101. --- linux-3.14.14/arch/arm64/include/asm/syscall.h 2014-07-28 10:07:25.000000000 -0500
  38102. +++ linux-imx6-3.14/arch/arm64/include/asm/syscall.h 2014-12-08 00:31:51.416418001 -0600
  38103. @@ -18,6 +18,7 @@
  38104. #include <linux/err.h>
  38105. +extern const void *sys_call_table[];
  38106. static inline int syscall_get_nr(struct task_struct *task,
  38107. struct pt_regs *regs)
  38108. diff -Nur linux-3.14.14/arch/arm64/include/asm/thread_info.h linux-imx6-3.14/arch/arm64/include/asm/thread_info.h
  38109. --- linux-3.14.14/arch/arm64/include/asm/thread_info.h 2014-07-28 10:07:25.000000000 -0500
  38110. +++ linux-imx6-3.14/arch/arm64/include/asm/thread_info.h 2014-12-08 00:31:51.416418001 -0600
  38111. @@ -91,6 +91,9 @@
  38112. /*
  38113. * thread information flags:
  38114. * TIF_SYSCALL_TRACE - syscall trace active
  38115. + * TIF_SYSCALL_TRACEPOINT - syscall tracepoint for ftrace
  38116. + * TIF_SYSCALL_AUDIT - syscall auditing
  38117. + * TIF_SECOMP - syscall secure computing
  38118. * TIF_SIGPENDING - signal pending
  38119. * TIF_NEED_RESCHED - rescheduling necessary
  38120. * TIF_NOTIFY_RESUME - callback before returning to user
  38121. @@ -101,6 +104,9 @@
  38122. #define TIF_NEED_RESCHED 1
  38123. #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
  38124. #define TIF_SYSCALL_TRACE 8
  38125. +#define TIF_SYSCALL_AUDIT 9
  38126. +#define TIF_SYSCALL_TRACEPOINT 10
  38127. +#define TIF_SECCOMP 11
  38128. #define TIF_POLLING_NRFLAG 16
  38129. #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
  38130. #define TIF_FREEZE 19
  38131. @@ -112,10 +118,17 @@
  38132. #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
  38133. #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
  38134. #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
  38135. +#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
  38136. +#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
  38137. +#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
  38138. +#define _TIF_SECCOMP (1 << TIF_SECCOMP)
  38139. #define _TIF_32BIT (1 << TIF_32BIT)
  38140. #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
  38141. _TIF_NOTIFY_RESUME)
  38142. +#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
  38143. + _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
  38144. +
  38145. #endif /* __KERNEL__ */
  38146. #endif /* __ASM_THREAD_INFO_H */
  38147. diff -Nur linux-3.14.14/arch/arm64/include/asm/topology.h linux-imx6-3.14/arch/arm64/include/asm/topology.h
  38148. --- linux-3.14.14/arch/arm64/include/asm/topology.h 1969-12-31 18:00:00.000000000 -0600
  38149. +++ linux-imx6-3.14/arch/arm64/include/asm/topology.h 2014-12-08 00:31:51.416418001 -0600
  38150. @@ -0,0 +1,70 @@
  38151. +#ifndef __ASM_TOPOLOGY_H
  38152. +#define __ASM_TOPOLOGY_H
  38153. +
  38154. +#ifdef CONFIG_SMP
  38155. +
  38156. +#include <linux/cpumask.h>
  38157. +
  38158. +struct cpu_topology {
  38159. + int thread_id;
  38160. + int core_id;
  38161. + int cluster_id;
  38162. + cpumask_t thread_sibling;
  38163. + cpumask_t core_sibling;
  38164. +};
  38165. +
  38166. +extern struct cpu_topology cpu_topology[NR_CPUS];
  38167. +
  38168. +#define topology_physical_package_id(cpu) (cpu_topology[cpu].cluster_id)
  38169. +#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
  38170. +#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
  38171. +#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)
  38172. +
  38173. +#define mc_capable() (cpu_topology[0].cluster_id != -1)
  38174. +#define smt_capable() (cpu_topology[0].thread_id != -1)
  38175. +
  38176. +void init_cpu_topology(void);
  38177. +void store_cpu_topology(unsigned int cpuid);
  38178. +const struct cpumask *cpu_coregroup_mask(int cpu);
  38179. +
  38180. +#ifdef CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE
  38181. +/* Common values for CPUs */
  38182. +#ifndef SD_CPU_INIT
  38183. +#define SD_CPU_INIT (struct sched_domain) { \
  38184. + .min_interval = 1, \
  38185. + .max_interval = 4, \
  38186. + .busy_factor = 64, \
  38187. + .imbalance_pct = 125, \
  38188. + .cache_nice_tries = 1, \
  38189. + .busy_idx = 2, \
  38190. + .idle_idx = 1, \
  38191. + .newidle_idx = 0, \
  38192. + .wake_idx = 0, \
  38193. + .forkexec_idx = 0, \
  38194. + \
  38195. + .flags = 0*SD_LOAD_BALANCE \
  38196. + | 1*SD_BALANCE_NEWIDLE \
  38197. + | 1*SD_BALANCE_EXEC \
  38198. + | 1*SD_BALANCE_FORK \
  38199. + | 0*SD_BALANCE_WAKE \
  38200. + | 1*SD_WAKE_AFFINE \
  38201. + | 0*SD_SHARE_CPUPOWER \
  38202. + | 0*SD_SHARE_PKG_RESOURCES \
  38203. + | 0*SD_SERIALIZE \
  38204. + , \
  38205. + .last_balance = jiffies, \
  38206. + .balance_interval = 1, \
  38207. +}
  38208. +#endif
  38209. +#endif /* CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE */
  38210. +
  38211. +#else
  38212. +
  38213. +static inline void init_cpu_topology(void) { }
  38214. +static inline void store_cpu_topology(unsigned int cpuid) { }
  38215. +
  38216. +#endif
  38217. +
  38218. +#include <asm-generic/topology.h>
  38219. +
  38220. +#endif /* _ASM_ARM_TOPOLOGY_H */
  38221. diff -Nur linux-3.14.14/arch/arm64/include/asm/unistd.h linux-imx6-3.14/arch/arm64/include/asm/unistd.h
  38222. --- linux-3.14.14/arch/arm64/include/asm/unistd.h 2014-07-28 10:07:25.000000000 -0500
  38223. +++ linux-imx6-3.14/arch/arm64/include/asm/unistd.h 2014-12-08 00:31:51.416418001 -0600
  38224. @@ -28,3 +28,5 @@
  38225. #endif
  38226. #define __ARCH_WANT_SYS_CLONE
  38227. #include <uapi/asm/unistd.h>
  38228. +
  38229. +#define NR_syscalls (__NR_syscalls)
  38230. diff -Nur linux-3.14.14/arch/arm64/include/uapi/asm/Kbuild linux-imx6-3.14/arch/arm64/include/uapi/asm/Kbuild
  38231. --- linux-3.14.14/arch/arm64/include/uapi/asm/Kbuild 2014-07-28 10:07:25.000000000 -0500
  38232. +++ linux-imx6-3.14/arch/arm64/include/uapi/asm/Kbuild 2014-12-08 00:31:51.416418001 -0600
  38233. @@ -9,6 +9,7 @@
  38234. header-y += fcntl.h
  38235. header-y += hwcap.h
  38236. header-y += kvm_para.h
  38237. +header-y += perf_regs.h
  38238. header-y += param.h
  38239. header-y += ptrace.h
  38240. header-y += setup.h
  38241. diff -Nur linux-3.14.14/arch/arm64/include/uapi/asm/perf_regs.h linux-imx6-3.14/arch/arm64/include/uapi/asm/perf_regs.h
  38242. --- linux-3.14.14/arch/arm64/include/uapi/asm/perf_regs.h 1969-12-31 18:00:00.000000000 -0600
  38243. +++ linux-imx6-3.14/arch/arm64/include/uapi/asm/perf_regs.h 2014-12-08 00:31:51.416418001 -0600
  38244. @@ -0,0 +1,40 @@
  38245. +#ifndef _ASM_ARM64_PERF_REGS_H
  38246. +#define _ASM_ARM64_PERF_REGS_H
  38247. +
  38248. +enum perf_event_arm_regs {
  38249. + PERF_REG_ARM64_X0,
  38250. + PERF_REG_ARM64_X1,
  38251. + PERF_REG_ARM64_X2,
  38252. + PERF_REG_ARM64_X3,
  38253. + PERF_REG_ARM64_X4,
  38254. + PERF_REG_ARM64_X5,
  38255. + PERF_REG_ARM64_X6,
  38256. + PERF_REG_ARM64_X7,
  38257. + PERF_REG_ARM64_X8,
  38258. + PERF_REG_ARM64_X9,
  38259. + PERF_REG_ARM64_X10,
  38260. + PERF_REG_ARM64_X11,
  38261. + PERF_REG_ARM64_X12,
  38262. + PERF_REG_ARM64_X13,
  38263. + PERF_REG_ARM64_X14,
  38264. + PERF_REG_ARM64_X15,
  38265. + PERF_REG_ARM64_X16,
  38266. + PERF_REG_ARM64_X17,
  38267. + PERF_REG_ARM64_X18,
  38268. + PERF_REG_ARM64_X19,
  38269. + PERF_REG_ARM64_X20,
  38270. + PERF_REG_ARM64_X21,
  38271. + PERF_REG_ARM64_X22,
  38272. + PERF_REG_ARM64_X23,
  38273. + PERF_REG_ARM64_X24,
  38274. + PERF_REG_ARM64_X25,
  38275. + PERF_REG_ARM64_X26,
  38276. + PERF_REG_ARM64_X27,
  38277. + PERF_REG_ARM64_X28,
  38278. + PERF_REG_ARM64_X29,
  38279. + PERF_REG_ARM64_LR,
  38280. + PERF_REG_ARM64_SP,
  38281. + PERF_REG_ARM64_PC,
  38282. + PERF_REG_ARM64_MAX,
  38283. +};
  38284. +#endif /* _ASM_ARM64_PERF_REGS_H */
  38285. diff -Nur linux-3.14.14/arch/arm64/Kconfig linux-imx6-3.14/arch/arm64/Kconfig
  38286. --- linux-3.14.14/arch/arm64/Kconfig 2014-07-28 10:07:25.000000000 -0500
  38287. +++ linux-imx6-3.14/arch/arm64/Kconfig 2014-12-08 00:31:51.408418001 -0600
  38288. @@ -4,6 +4,7 @@
  38289. select ARCH_USE_CMPXCHG_LOCKREF
  38290. select ARCH_SUPPORTS_ATOMIC_RMW
  38291. select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
  38292. + select ARCH_HAS_OPP
  38293. select ARCH_WANT_OPTIONAL_GPIOLIB
  38294. select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
  38295. select ARCH_WANT_FRAME_POINTERS
  38296. @@ -17,6 +18,7 @@
  38297. select DCACHE_WORD_ACCESS
  38298. select GENERIC_CLOCKEVENTS
  38299. select GENERIC_CLOCKEVENTS_BROADCAST if SMP
  38300. + select GENERIC_CPU_AUTOPROBE
  38301. select GENERIC_IOMAP
  38302. select GENERIC_IRQ_PROBE
  38303. select GENERIC_IRQ_SHOW
  38304. @@ -27,18 +29,27 @@
  38305. select GENERIC_TIME_VSYSCALL
  38306. select HARDIRQS_SW_RESEND
  38307. select HAVE_ARCH_JUMP_LABEL
  38308. + select HAVE_ARCH_KGDB
  38309. select HAVE_ARCH_TRACEHOOK
  38310. + select HAVE_C_RECORDMCOUNT
  38311. select HAVE_DEBUG_BUGVERBOSE
  38312. select HAVE_DEBUG_KMEMLEAK
  38313. select HAVE_DMA_API_DEBUG
  38314. select HAVE_DMA_ATTRS
  38315. select HAVE_DMA_CONTIGUOUS
  38316. select HAVE_EFFICIENT_UNALIGNED_ACCESS
  38317. + select HAVE_DYNAMIC_FTRACE
  38318. + select HAVE_FTRACE_MCOUNT_RECORD
  38319. + select HAVE_FUNCTION_TRACER
  38320. + select HAVE_FUNCTION_GRAPH_TRACER
  38321. select HAVE_GENERIC_DMA_COHERENT
  38322. select HAVE_HW_BREAKPOINT if PERF_EVENTS
  38323. select HAVE_MEMBLOCK
  38324. select HAVE_PATA_PLATFORM
  38325. select HAVE_PERF_EVENTS
  38326. + select HAVE_PERF_REGS
  38327. + select HAVE_PERF_USER_STACK_DUMP
  38328. + select HAVE_SYSCALL_TRACEPOINTS
  38329. select IRQ_DOMAIN
  38330. select MODULES_USE_ELF_RELA
  38331. select NO_BOOTMEM
  38332. @@ -86,7 +97,7 @@
  38333. config GENERIC_CALIBRATE_DELAY
  38334. def_bool y
  38335. -config ZONE_DMA32
  38336. +config ZONE_DMA
  38337. def_bool y
  38338. config ARCH_DMA_ADDR_T_64BIT
  38339. @@ -165,6 +176,134 @@
  38340. If you don't know what to do here, say N.
  38341. +config SCHED_MC
  38342. + bool "Multi-core scheduler support"
  38343. + depends on SMP
  38344. + help
  38345. + Multi-core scheduler support improves the CPU scheduler's decision
  38346. + making when dealing with multi-core CPU chips at a cost of slightly
  38347. + increased overhead in some places. If unsure say N here.
  38348. +
  38349. +config SCHED_SMT
  38350. + bool "SMT scheduler support"
  38351. + depends on SMP
  38352. + help
  38353. + Improves the CPU scheduler's decision making when dealing with
  38354. + MultiThreading at a cost of slightly increased overhead in some
  38355. + places. If unsure say N here.
  38356. +
  38357. +config SCHED_MC
  38358. + bool "Multi-core scheduler support"
  38359. + depends on ARM_CPU_TOPOLOGY
  38360. + help
  38361. + Multi-core scheduler support improves the CPU scheduler's decision
  38362. + making when dealing with multi-core CPU chips at a cost of slightly
  38363. + increased overhead in some places. If unsure say N here.
  38364. +
  38365. +config SCHED_SMT
  38366. + bool "SMT scheduler support"
  38367. + depends on ARM_CPU_TOPOLOGY
  38368. + help
  38369. + Improves the CPU scheduler's decision making when dealing with
  38370. + MultiThreading at a cost of slightly increased overhead in some
  38371. + places. If unsure say N here.
  38372. +
  38373. +config DISABLE_CPU_SCHED_DOMAIN_BALANCE
  38374. + bool "(EXPERIMENTAL) Disable CPU level scheduler load-balancing"
  38375. + help
  38376. + Disables scheduler load-balancing at CPU sched domain level.
  38377. +
  38378. +config SCHED_HMP
  38379. + bool "(EXPERIMENTAL) Heterogenous multiprocessor scheduling"
  38380. + depends on DISABLE_CPU_SCHED_DOMAIN_BALANCE && SCHED_MC && FAIR_GROUP_SCHED && !SCHED_AUTOGROUP
  38381. + help
  38382. + Experimental scheduler optimizations for heterogeneous platforms.
  38383. + Attempts to introspectively select task affinity to optimize power
  38384. + and performance. Basic support for multiple (>2) cpu types is in place,
  38385. + but it has only been tested with two types of cpus.
  38386. + There is currently no support for migration of task groups, hence
  38387. + !SCHED_AUTOGROUP. Furthermore, normal load-balancing must be disabled
  38388. + between cpus of different type (DISABLE_CPU_SCHED_DOMAIN_BALANCE).
  38389. +
  38390. +config SCHED_HMP_PRIO_FILTER
  38391. + bool "(EXPERIMENTAL) Filter HMP migrations by task priority"
  38392. + depends on SCHED_HMP
  38393. + help
  38394. + Enables task priority based HMP migration filter. Any task with
  38395. + a NICE value above the threshold will always be on low-power cpus
  38396. + with less compute capacity.
  38397. +
  38398. +config SCHED_HMP_PRIO_FILTER_VAL
  38399. + int "NICE priority threshold"
  38400. + default 5
  38401. + depends on SCHED_HMP_PRIO_FILTER
  38402. +
  38403. +config HMP_FAST_CPU_MASK
  38404. + string "HMP scheduler fast CPU mask"
  38405. + depends on SCHED_HMP
  38406. + help
  38407. + Leave empty to use device tree information.
  38408. + Specify the cpuids of the fast CPUs in the system as a list string,
  38409. + e.g. cpuid 0+1 should be specified as 0-1.
  38410. +
  38411. +config HMP_SLOW_CPU_MASK
  38412. + string "HMP scheduler slow CPU mask"
  38413. + depends on SCHED_HMP
  38414. + help
  38415. + Leave empty to use device tree information.
  38416. + Specify the cpuids of the slow CPUs in the system as a list string,
  38417. + e.g. cpuid 0+1 should be specified as 0-1.
  38418. +
  38419. +config HMP_VARIABLE_SCALE
  38420. + bool "Allows changing the load tracking scale through sysfs"
  38421. + depends on SCHED_HMP
  38422. + help
  38423. + When turned on, this option exports the thresholds and load average
  38424. + period value for the load tracking patches through sysfs.
  38425. + The values can be modified to change the rate of load accumulation
  38426. + and the thresholds used for HMP migration.
  38427. + The load_avg_period_ms is the time in ms to reach a load average of
  38428. + 0.5 for an idle task of 0 load average ratio that start a busy loop.
  38429. + The up_threshold and down_threshold is the value to go to a faster
  38430. + CPU or to go back to a slower cpu.
  38431. + The {up,down}_threshold are devided by 1024 before being compared
  38432. + to the load average.
  38433. + For examples, with load_avg_period_ms = 128 and up_threshold = 512,
  38434. + a running task with a load of 0 will be migrated to a bigger CPU after
  38435. + 128ms, because after 128ms its load_avg_ratio is 0.5 and the real
  38436. + up_threshold is 0.5.
  38437. + This patch has the same behavior as changing the Y of the load
  38438. + average computation to
  38439. + (1002/1024)^(LOAD_AVG_PERIOD/load_avg_period_ms)
  38440. + but it remove intermadiate overflows in computation.
  38441. +
  38442. +config HMP_FREQUENCY_INVARIANT_SCALE
  38443. + bool "(EXPERIMENTAL) Frequency-Invariant Tracked Load for HMP"
  38444. + depends on HMP_VARIABLE_SCALE && CPU_FREQ
  38445. + help
  38446. + Scales the current load contribution in line with the frequency
  38447. + of the CPU that the task was executed on.
  38448. + In this version, we use a simple linear scale derived from the
  38449. + maximum frequency reported by CPUFreq.
  38450. + Restricting tracked load to be scaled by the CPU's frequency
  38451. + represents the consumption of possible compute capacity
  38452. + (rather than consumption of actual instantaneous capacity as
  38453. + normal) and allows the HMP migration's simple threshold
  38454. + migration strategy to interact more predictably with CPUFreq's
  38455. + asynchronous compute capacity changes.
  38456. +
  38457. +config SCHED_HMP_LITTLE_PACKING
  38458. + bool "Small task packing for HMP"
  38459. + depends on SCHED_HMP
  38460. + default n
  38461. + help
  38462. + Allows the HMP Scheduler to pack small tasks into CPUs in the
  38463. + smallest HMP domain.
  38464. + Controlled by two sysfs files in sys/kernel/hmp.
  38465. + packing_enable: 1 to enable, 0 to disable packing. Default 1.
  38466. + packing_limit: runqueue load ratio where a RQ is considered
  38467. + to be full. Default is NICE_0_LOAD * 9/8.
  38468. +
  38469. config NR_CPUS
  38470. int "Maximum number of CPUs (2-32)"
  38471. range 2 32
  38472. @@ -317,5 +456,8 @@
  38473. source "security/Kconfig"
  38474. source "crypto/Kconfig"
  38475. +if CRYPTO
  38476. +source "arch/arm64/crypto/Kconfig"
  38477. +endif
  38478. source "lib/Kconfig"
  38479. diff -Nur linux-3.14.14/arch/arm64/kernel/arm64ksyms.c linux-imx6-3.14/arch/arm64/kernel/arm64ksyms.c
  38480. --- linux-3.14.14/arch/arm64/kernel/arm64ksyms.c 2014-07-28 10:07:25.000000000 -0500
  38481. +++ linux-imx6-3.14/arch/arm64/kernel/arm64ksyms.c 2014-12-08 00:31:51.416418001 -0600
  38482. @@ -56,3 +56,7 @@
  38483. EXPORT_SYMBOL(test_and_clear_bit);
  38484. EXPORT_SYMBOL(change_bit);
  38485. EXPORT_SYMBOL(test_and_change_bit);
  38486. +
  38487. +#ifdef CONFIG_FUNCTION_TRACER
  38488. +EXPORT_SYMBOL(_mcount);
  38489. +#endif
  38490. diff -Nur linux-3.14.14/arch/arm64/kernel/debug-monitors.c linux-imx6-3.14/arch/arm64/kernel/debug-monitors.c
  38491. --- linux-3.14.14/arch/arm64/kernel/debug-monitors.c 2014-07-28 10:07:25.000000000 -0500
  38492. +++ linux-imx6-3.14/arch/arm64/kernel/debug-monitors.c 2014-12-08 00:31:51.416418001 -0600
  38493. @@ -138,6 +138,7 @@
  38494. {
  38495. asm volatile("msr oslar_el1, %0" : : "r" (0));
  38496. isb();
  38497. + local_dbg_enable();
  38498. }
  38499. static int os_lock_notify(struct notifier_block *self,
  38500. @@ -314,9 +315,6 @@
  38501. if (call_break_hook(regs, esr) == DBG_HOOK_HANDLED)
  38502. return 0;
  38503. - pr_warn("unexpected brk exception at %lx, esr=0x%x\n",
  38504. - (long)instruction_pointer(regs), esr);
  38505. -
  38506. if (!user_mode(regs))
  38507. return -EFAULT;
  38508. diff -Nur linux-3.14.14/arch/arm64/kernel/entry-ftrace.S linux-imx6-3.14/arch/arm64/kernel/entry-ftrace.S
  38509. --- linux-3.14.14/arch/arm64/kernel/entry-ftrace.S 1969-12-31 18:00:00.000000000 -0600
  38510. +++ linux-imx6-3.14/arch/arm64/kernel/entry-ftrace.S 2014-12-08 00:31:51.416418001 -0600
  38511. @@ -0,0 +1,218 @@
  38512. +/*
  38513. + * arch/arm64/kernel/entry-ftrace.S
  38514. + *
  38515. + * Copyright (C) 2013 Linaro Limited
  38516. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  38517. + *
  38518. + * This program is free software; you can redistribute it and/or modify
  38519. + * it under the terms of the GNU General Public License version 2 as
  38520. + * published by the Free Software Foundation.
  38521. + */
  38522. +
  38523. +#include <linux/linkage.h>
  38524. +#include <asm/ftrace.h>
  38525. +#include <asm/insn.h>
  38526. +
  38527. +/*
  38528. + * Gcc with -pg will put the following code in the beginning of each function:
  38529. + * mov x0, x30
  38530. + * bl _mcount
  38531. + * [function's body ...]
  38532. + * "bl _mcount" may be replaced to "bl ftrace_caller" or NOP if dynamic
  38533. + * ftrace is enabled.
  38534. + *
  38535. + * Please note that x0 as an argument will not be used here because we can
  38536. + * get lr(x30) of instrumented function at any time by winding up call stack
  38537. + * as long as the kernel is compiled without -fomit-frame-pointer.
  38538. + * (or CONFIG_FRAME_POINTER, this is forced on arm64)
  38539. + *
  38540. + * stack layout after mcount_enter in _mcount():
  38541. + *
  38542. + * current sp/fp => 0:+-----+
  38543. + * in _mcount() | x29 | -> instrumented function's fp
  38544. + * +-----+
  38545. + * | x30 | -> _mcount()'s lr (= instrumented function's pc)
  38546. + * old sp => +16:+-----+
  38547. + * when instrumented | |
  38548. + * function calls | ... |
  38549. + * _mcount() | |
  38550. + * | |
  38551. + * instrumented => +xx:+-----+
  38552. + * function's fp | x29 | -> parent's fp
  38553. + * +-----+
  38554. + * | x30 | -> instrumented function's lr (= parent's pc)
  38555. + * +-----+
  38556. + * | ... |
  38557. + */
  38558. +
  38559. + .macro mcount_enter
  38560. + stp x29, x30, [sp, #-16]!
  38561. + mov x29, sp
  38562. + .endm
  38563. +
  38564. + .macro mcount_exit
  38565. + ldp x29, x30, [sp], #16
  38566. + ret
  38567. + .endm
  38568. +
  38569. + .macro mcount_adjust_addr rd, rn
  38570. + sub \rd, \rn, #AARCH64_INSN_SIZE
  38571. + .endm
  38572. +
  38573. + /* for instrumented function's parent */
  38574. + .macro mcount_get_parent_fp reg
  38575. + ldr \reg, [x29]
  38576. + ldr \reg, [\reg]
  38577. + .endm
  38578. +
  38579. + /* for instrumented function */
  38580. + .macro mcount_get_pc0 reg
  38581. + mcount_adjust_addr \reg, x30
  38582. + .endm
  38583. +
  38584. + .macro mcount_get_pc reg
  38585. + ldr \reg, [x29, #8]
  38586. + mcount_adjust_addr \reg, \reg
  38587. + .endm
  38588. +
  38589. + .macro mcount_get_lr reg
  38590. + ldr \reg, [x29]
  38591. + ldr \reg, [\reg, #8]
  38592. + mcount_adjust_addr \reg, \reg
  38593. + .endm
  38594. +
  38595. + .macro mcount_get_lr_addr reg
  38596. + ldr \reg, [x29]
  38597. + add \reg, \reg, #8
  38598. + .endm
  38599. +
  38600. +#ifndef CONFIG_DYNAMIC_FTRACE
  38601. +/*
  38602. + * void _mcount(unsigned long return_address)
  38603. + * @return_address: return address to instrumented function
  38604. + *
  38605. + * This function makes calls, if enabled, to:
  38606. + * - tracer function to probe instrumented function's entry,
  38607. + * - ftrace_graph_caller to set up an exit hook
  38608. + */
  38609. +ENTRY(_mcount)
  38610. +#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
  38611. + ldr x0, =ftrace_trace_stop
  38612. + ldr x0, [x0] // if ftrace_trace_stop
  38613. + ret // return;
  38614. +#endif
  38615. + mcount_enter
  38616. +
  38617. + ldr x0, =ftrace_trace_function
  38618. + ldr x2, [x0]
  38619. + adr x0, ftrace_stub
  38620. + cmp x0, x2 // if (ftrace_trace_function
  38621. + b.eq skip_ftrace_call // != ftrace_stub) {
  38622. +
  38623. + mcount_get_pc x0 // function's pc
  38624. + mcount_get_lr x1 // function's lr (= parent's pc)
  38625. + blr x2 // (*ftrace_trace_function)(pc, lr);
  38626. +
  38627. +#ifndef CONFIG_FUNCTION_GRAPH_TRACER
  38628. +skip_ftrace_call: // return;
  38629. + mcount_exit // }
  38630. +#else
  38631. + mcount_exit // return;
  38632. + // }
  38633. +skip_ftrace_call:
  38634. + ldr x1, =ftrace_graph_return
  38635. + ldr x2, [x1] // if ((ftrace_graph_return
  38636. + cmp x0, x2 // != ftrace_stub)
  38637. + b.ne ftrace_graph_caller
  38638. +
  38639. + ldr x1, =ftrace_graph_entry // || (ftrace_graph_entry
  38640. + ldr x2, [x1] // != ftrace_graph_entry_stub))
  38641. + ldr x0, =ftrace_graph_entry_stub
  38642. + cmp x0, x2
  38643. + b.ne ftrace_graph_caller // ftrace_graph_caller();
  38644. +
  38645. + mcount_exit
  38646. +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  38647. +ENDPROC(_mcount)
  38648. +
  38649. +#else /* CONFIG_DYNAMIC_FTRACE */
  38650. +/*
  38651. + * _mcount() is used to build the kernel with -pg option, but all the branch
  38652. + * instructions to _mcount() are replaced to NOP initially at kernel start up,
  38653. + * and later on, NOP to branch to ftrace_caller() when enabled or branch to
  38654. + * NOP when disabled per-function base.
  38655. + */
  38656. +ENTRY(_mcount)
  38657. + ret
  38658. +ENDPROC(_mcount)
  38659. +
  38660. +/*
  38661. + * void ftrace_caller(unsigned long return_address)
  38662. + * @return_address: return address to instrumented function
  38663. + *
  38664. + * This function is a counterpart of _mcount() in 'static' ftrace, and
  38665. + * makes calls to:
  38666. + * - tracer function to probe instrumented function's entry,
  38667. + * - ftrace_graph_caller to set up an exit hook
  38668. + */
  38669. +ENTRY(ftrace_caller)
  38670. + mcount_enter
  38671. +
  38672. + mcount_get_pc0 x0 // function's pc
  38673. + mcount_get_lr x1 // function's lr
  38674. +
  38675. + .global ftrace_call
  38676. +ftrace_call: // tracer(pc, lr);
  38677. + nop // This will be replaced with "bl xxx"
  38678. + // where xxx can be any kind of tracer.
  38679. +
  38680. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  38681. + .global ftrace_graph_call
  38682. +ftrace_graph_call: // ftrace_graph_caller();
  38683. + nop // If enabled, this will be replaced
  38684. + // "b ftrace_graph_caller"
  38685. +#endif
  38686. +
  38687. + mcount_exit
  38688. +ENDPROC(ftrace_caller)
  38689. +#endif /* CONFIG_DYNAMIC_FTRACE */
  38690. +
  38691. +ENTRY(ftrace_stub)
  38692. + ret
  38693. +ENDPROC(ftrace_stub)
  38694. +
  38695. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  38696. +/*
  38697. + * void ftrace_graph_caller(void)
  38698. + *
  38699. + * Called from _mcount() or ftrace_caller() when function_graph tracer is
  38700. + * selected.
  38701. + * This function w/ prepare_ftrace_return() fakes link register's value on
  38702. + * the call stack in order to intercept instrumented function's return path
  38703. + * and run return_to_handler() later on its exit.
  38704. + */
  38705. +ENTRY(ftrace_graph_caller)
  38706. + mcount_get_lr_addr x0 // pointer to function's saved lr
  38707. + mcount_get_pc x1 // function's pc
  38708. + mcount_get_parent_fp x2 // parent's fp
  38709. + bl prepare_ftrace_return // prepare_ftrace_return(&lr, pc, fp)
  38710. +
  38711. + mcount_exit
  38712. +ENDPROC(ftrace_graph_caller)
  38713. +
  38714. +/*
  38715. + * void return_to_handler(void)
  38716. + *
  38717. + * Run ftrace_return_to_handler() before going back to parent.
  38718. + * @fp is checked against the value passed by ftrace_graph_caller()
  38719. + * only when CONFIG_FUNCTION_GRAPH_FP_TEST is enabled.
  38720. + */
  38721. +ENTRY(return_to_handler)
  38722. + str x0, [sp, #-16]!
  38723. + mov x0, x29 // parent's fp
  38724. + bl ftrace_return_to_handler// addr = ftrace_return_to_hander(fp);
  38725. + mov x30, x0 // restore the original return address
  38726. + ldr x0, [sp], #16
  38727. + ret
  38728. +END(return_to_handler)
  38729. +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  38730. diff -Nur linux-3.14.14/arch/arm64/kernel/entry.S linux-imx6-3.14/arch/arm64/kernel/entry.S
  38731. --- linux-3.14.14/arch/arm64/kernel/entry.S 2014-07-28 10:07:25.000000000 -0500
  38732. +++ linux-imx6-3.14/arch/arm64/kernel/entry.S 2014-12-08 00:31:51.416418001 -0600
  38733. @@ -630,8 +630,9 @@
  38734. enable_irq
  38735. get_thread_info tsk
  38736. - ldr x16, [tsk, #TI_FLAGS] // check for syscall tracing
  38737. - tbnz x16, #TIF_SYSCALL_TRACE, __sys_trace // are we tracing syscalls?
  38738. + ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks
  38739. + tst x16, #_TIF_SYSCALL_WORK
  38740. + b.ne __sys_trace
  38741. adr lr, ret_fast_syscall // return address
  38742. cmp scno, sc_nr // check upper syscall limit
  38743. b.hs ni_sys
  38744. @@ -647,9 +648,8 @@
  38745. * switches, and waiting for our parent to respond.
  38746. */
  38747. __sys_trace:
  38748. - mov x1, sp
  38749. - mov w0, #0 // trace entry
  38750. - bl syscall_trace
  38751. + mov x0, sp
  38752. + bl syscall_trace_enter
  38753. adr lr, __sys_trace_return // return address
  38754. uxtw scno, w0 // syscall number (possibly new)
  38755. mov x1, sp // pointer to regs
  38756. @@ -664,9 +664,8 @@
  38757. __sys_trace_return:
  38758. str x0, [sp] // save returned x0
  38759. - mov x1, sp
  38760. - mov w0, #1 // trace exit
  38761. - bl syscall_trace
  38762. + mov x0, sp
  38763. + bl syscall_trace_exit
  38764. b ret_to_user
  38765. /*
  38766. diff -Nur linux-3.14.14/arch/arm64/kernel/ftrace.c linux-imx6-3.14/arch/arm64/kernel/ftrace.c
  38767. --- linux-3.14.14/arch/arm64/kernel/ftrace.c 1969-12-31 18:00:00.000000000 -0600
  38768. +++ linux-imx6-3.14/arch/arm64/kernel/ftrace.c 2014-12-08 00:31:51.420418001 -0600
  38769. @@ -0,0 +1,177 @@
  38770. +/*
  38771. + * arch/arm64/kernel/ftrace.c
  38772. + *
  38773. + * Copyright (C) 2013 Linaro Limited
  38774. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  38775. + *
  38776. + * This program is free software; you can redistribute it and/or modify
  38777. + * it under the terms of the GNU General Public License version 2 as
  38778. + * published by the Free Software Foundation.
  38779. + */
  38780. +
  38781. +#include <linux/ftrace.h>
  38782. +#include <linux/swab.h>
  38783. +#include <linux/uaccess.h>
  38784. +
  38785. +#include <asm/cacheflush.h>
  38786. +#include <asm/ftrace.h>
  38787. +#include <asm/insn.h>
  38788. +
  38789. +#ifdef CONFIG_DYNAMIC_FTRACE
  38790. +/*
  38791. + * Replace a single instruction, which may be a branch or NOP.
  38792. + * If @validate == true, a replaced instruction is checked against 'old'.
  38793. + */
  38794. +static int ftrace_modify_code(unsigned long pc, u32 old, u32 new,
  38795. + bool validate)
  38796. +{
  38797. + u32 replaced;
  38798. +
  38799. + /*
  38800. + * Note:
  38801. + * Due to modules and __init, code can disappear and change,
  38802. + * we need to protect against faulting as well as code changing.
  38803. + * We do this by aarch64_insn_*() which use the probe_kernel_*().
  38804. + *
  38805. + * No lock is held here because all the modifications are run
  38806. + * through stop_machine().
  38807. + */
  38808. + if (validate) {
  38809. + if (aarch64_insn_read((void *)pc, &replaced))
  38810. + return -EFAULT;
  38811. +
  38812. + if (replaced != old)
  38813. + return -EINVAL;
  38814. + }
  38815. + if (aarch64_insn_patch_text_nosync((void *)pc, new))
  38816. + return -EPERM;
  38817. +
  38818. + return 0;
  38819. +}
  38820. +
  38821. +/*
  38822. + * Replace tracer function in ftrace_caller()
  38823. + */
  38824. +int ftrace_update_ftrace_func(ftrace_func_t func)
  38825. +{
  38826. + unsigned long pc;
  38827. + u32 new;
  38828. +
  38829. + pc = (unsigned long)&ftrace_call;
  38830. + new = aarch64_insn_gen_branch_imm(pc, (unsigned long)func, true);
  38831. +
  38832. + return ftrace_modify_code(pc, 0, new, false);
  38833. +}
  38834. +
  38835. +/*
  38836. + * Turn on the call to ftrace_caller() in instrumented function
  38837. + */
  38838. +int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
  38839. +{
  38840. + unsigned long pc = rec->ip;
  38841. + u32 old, new;
  38842. +
  38843. + old = aarch64_insn_gen_nop();
  38844. + new = aarch64_insn_gen_branch_imm(pc, addr, true);
  38845. +
  38846. + return ftrace_modify_code(pc, old, new, true);
  38847. +}
  38848. +
  38849. +/*
  38850. + * Turn off the call to ftrace_caller() in instrumented function
  38851. + */
  38852. +int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
  38853. + unsigned long addr)
  38854. +{
  38855. + unsigned long pc = rec->ip;
  38856. + u32 old, new;
  38857. +
  38858. + old = aarch64_insn_gen_branch_imm(pc, addr, true);
  38859. + new = aarch64_insn_gen_nop();
  38860. +
  38861. + return ftrace_modify_code(pc, old, new, true);
  38862. +}
  38863. +
  38864. +int __init ftrace_dyn_arch_init(void *data)
  38865. +{
  38866. + *(unsigned long *)data = 0;
  38867. + return 0;
  38868. +}
  38869. +#endif /* CONFIG_DYNAMIC_FTRACE */
  38870. +
  38871. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  38872. +/*
  38873. + * function_graph tracer expects ftrace_return_to_handler() to be called
  38874. + * on the way back to parent. For this purpose, this function is called
  38875. + * in _mcount() or ftrace_caller() to replace return address (*parent) on
  38876. + * the call stack to return_to_handler.
  38877. + *
  38878. + * Note that @frame_pointer is used only for sanity check later.
  38879. + */
  38880. +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
  38881. + unsigned long frame_pointer)
  38882. +{
  38883. + unsigned long return_hooker = (unsigned long)&return_to_handler;
  38884. + unsigned long old;
  38885. + struct ftrace_graph_ent trace;
  38886. + int err;
  38887. +
  38888. + if (unlikely(atomic_read(&current->tracing_graph_pause)))
  38889. + return;
  38890. +
  38891. + /*
  38892. + * Note:
  38893. + * No protection against faulting at *parent, which may be seen
  38894. + * on other archs. It's unlikely on AArch64.
  38895. + */
  38896. + old = *parent;
  38897. + *parent = return_hooker;
  38898. +
  38899. + trace.func = self_addr;
  38900. + trace.depth = current->curr_ret_stack + 1;
  38901. +
  38902. + /* Only trace if the calling function expects to */
  38903. + if (!ftrace_graph_entry(&trace)) {
  38904. + *parent = old;
  38905. + return;
  38906. + }
  38907. +
  38908. + err = ftrace_push_return_trace(old, self_addr, &trace.depth,
  38909. + frame_pointer);
  38910. + if (err == -EBUSY) {
  38911. + *parent = old;
  38912. + return;
  38913. + }
  38914. +}
  38915. +
  38916. +#ifdef CONFIG_DYNAMIC_FTRACE
  38917. +/*
  38918. + * Turn on/off the call to ftrace_graph_caller() in ftrace_caller()
  38919. + * depending on @enable.
  38920. + */
  38921. +static int ftrace_modify_graph_caller(bool enable)
  38922. +{
  38923. + unsigned long pc = (unsigned long)&ftrace_graph_call;
  38924. + u32 branch, nop;
  38925. +
  38926. + branch = aarch64_insn_gen_branch_imm(pc,
  38927. + (unsigned long)ftrace_graph_caller, false);
  38928. + nop = aarch64_insn_gen_nop();
  38929. +
  38930. + if (enable)
  38931. + return ftrace_modify_code(pc, nop, branch, true);
  38932. + else
  38933. + return ftrace_modify_code(pc, branch, nop, true);
  38934. +}
  38935. +
  38936. +int ftrace_enable_ftrace_graph_caller(void)
  38937. +{
  38938. + return ftrace_modify_graph_caller(true);
  38939. +}
  38940. +
  38941. +int ftrace_disable_ftrace_graph_caller(void)
  38942. +{
  38943. + return ftrace_modify_graph_caller(false);
  38944. +}
  38945. +#endif /* CONFIG_DYNAMIC_FTRACE */
  38946. +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  38947. diff -Nur linux-3.14.14/arch/arm64/kernel/head.S linux-imx6-3.14/arch/arm64/kernel/head.S
  38948. --- linux-3.14.14/arch/arm64/kernel/head.S 2014-07-28 10:07:25.000000000 -0500
  38949. +++ linux-imx6-3.14/arch/arm64/kernel/head.S 2014-12-08 00:31:51.420418001 -0600
  38950. @@ -26,6 +26,7 @@
  38951. #include <asm/assembler.h>
  38952. #include <asm/ptrace.h>
  38953. #include <asm/asm-offsets.h>
  38954. +#include <asm/cache.h>
  38955. #include <asm/cputype.h>
  38956. #include <asm/memory.h>
  38957. #include <asm/thread_info.h>
  38958. @@ -34,29 +35,17 @@
  38959. #include <asm/page.h>
  38960. #include <asm/virt.h>
  38961. -/*
  38962. - * swapper_pg_dir is the virtual address of the initial page table. We place
  38963. - * the page tables 3 * PAGE_SIZE below KERNEL_RAM_VADDR. The idmap_pg_dir has
  38964. - * 2 pages and is placed below swapper_pg_dir.
  38965. - */
  38966. #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
  38967. #if (KERNEL_RAM_VADDR & 0xfffff) != 0x80000
  38968. #error KERNEL_RAM_VADDR must start at 0xXXX80000
  38969. #endif
  38970. -#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
  38971. -#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
  38972. -
  38973. - .globl swapper_pg_dir
  38974. - .equ swapper_pg_dir, KERNEL_RAM_VADDR - SWAPPER_DIR_SIZE
  38975. -
  38976. - .globl idmap_pg_dir
  38977. - .equ idmap_pg_dir, swapper_pg_dir - IDMAP_DIR_SIZE
  38978. -
  38979. - .macro pgtbl, ttb0, ttb1, phys
  38980. - add \ttb1, \phys, #TEXT_OFFSET - SWAPPER_DIR_SIZE
  38981. - sub \ttb0, \ttb1, #IDMAP_DIR_SIZE
  38982. + .macro pgtbl, ttb0, ttb1, virt_to_phys
  38983. + ldr \ttb1, =swapper_pg_dir
  38984. + ldr \ttb0, =idmap_pg_dir
  38985. + add \ttb1, \ttb1, \virt_to_phys
  38986. + add \ttb0, \ttb0, \virt_to_phys
  38987. .endm
  38988. #ifdef CONFIG_ARM64_64K_PAGES
  38989. @@ -229,7 +218,11 @@
  38990. cmp w20, #BOOT_CPU_MODE_EL2
  38991. b.ne 1f
  38992. add x1, x1, #4
  38993. -1: str w20, [x1] // This CPU has booted in EL1
  38994. +1: dc cvac, x1 // Clean potentially dirty cache line
  38995. + dsb sy
  38996. + str w20, [x1] // This CPU has booted in EL1
  38997. + dc civac, x1 // Clean&invalidate potentially stale cache line
  38998. + dsb sy
  38999. ret
  39000. ENDPROC(set_cpu_boot_mode_flag)
  39001. @@ -240,8 +233,9 @@
  39002. * This is not in .bss, because we set it sufficiently early that the boot-time
  39003. * zeroing of .bss would clobber it.
  39004. */
  39005. - .pushsection .data
  39006. + .pushsection .data..cacheline_aligned
  39007. ENTRY(__boot_cpu_mode)
  39008. + .align L1_CACHE_SHIFT
  39009. .long BOOT_CPU_MODE_EL2
  39010. .long 0
  39011. .popsection
  39012. @@ -298,7 +292,7 @@
  39013. mov x23, x0 // x23=current cpu_table
  39014. cbz x23, __error_p // invalid processor (x23=0)?
  39015. - pgtbl x25, x26, x24 // x25=TTBR0, x26=TTBR1
  39016. + pgtbl x25, x26, x28 // x25=TTBR0, x26=TTBR1
  39017. ldr x12, [x23, #CPU_INFO_SETUP]
  39018. add x12, x12, x28 // __virt_to_phys
  39019. blr x12 // initialise processor
  39020. @@ -340,8 +334,13 @@
  39021. * x27 = *virtual* address to jump to upon completion
  39022. *
  39023. * other registers depend on the function called upon completion
  39024. + *
  39025. + * We align the entire function to the smallest power of two larger than it to
  39026. + * ensure it fits within a single block map entry. Otherwise were PHYS_OFFSET
  39027. + * close to the end of a 512MB or 1GB block we might require an additional
  39028. + * table to map the entire function.
  39029. */
  39030. - .align 6
  39031. + .align 4
  39032. __turn_mmu_on:
  39033. msr sctlr_el1, x0
  39034. isb
  39035. @@ -384,26 +383,18 @@
  39036. * Preserves: tbl, flags
  39037. * Corrupts: phys, start, end, pstate
  39038. */
  39039. - .macro create_block_map, tbl, flags, phys, start, end, idmap=0
  39040. + .macro create_block_map, tbl, flags, phys, start, end
  39041. lsr \phys, \phys, #BLOCK_SHIFT
  39042. - .if \idmap
  39043. - and \start, \phys, #PTRS_PER_PTE - 1 // table index
  39044. - .else
  39045. lsr \start, \start, #BLOCK_SHIFT
  39046. and \start, \start, #PTRS_PER_PTE - 1 // table index
  39047. - .endif
  39048. orr \phys, \flags, \phys, lsl #BLOCK_SHIFT // table entry
  39049. - .ifnc \start,\end
  39050. lsr \end, \end, #BLOCK_SHIFT
  39051. and \end, \end, #PTRS_PER_PTE - 1 // table end index
  39052. - .endif
  39053. 9999: str \phys, [\tbl, \start, lsl #3] // store the entry
  39054. - .ifnc \start,\end
  39055. add \start, \start, #1 // next entry
  39056. add \phys, \phys, #BLOCK_SIZE // next block
  39057. cmp \start, \end
  39058. b.ls 9999b
  39059. - .endif
  39060. .endm
  39061. /*
  39062. @@ -415,7 +406,16 @@
  39063. * - UART mapping if CONFIG_EARLY_PRINTK is enabled (TTBR1)
  39064. */
  39065. __create_page_tables:
  39066. - pgtbl x25, x26, x24 // idmap_pg_dir and swapper_pg_dir addresses
  39067. + pgtbl x25, x26, x28 // idmap_pg_dir and swapper_pg_dir addresses
  39068. + mov x27, lr
  39069. +
  39070. + /*
  39071. + * Invalidate the idmap and swapper page tables to avoid potential
  39072. + * dirty cache lines being evicted.
  39073. + */
  39074. + mov x0, x25
  39075. + add x1, x26, #SWAPPER_DIR_SIZE
  39076. + bl __inval_cache_range
  39077. /*
  39078. * Clear the idmap and swapper page tables.
  39079. @@ -435,9 +435,13 @@
  39080. * Create the identity mapping.
  39081. */
  39082. add x0, x25, #PAGE_SIZE // section table address
  39083. - adr x3, __turn_mmu_on // virtual/physical address
  39084. + ldr x3, =KERNEL_START
  39085. + add x3, x3, x28 // __pa(KERNEL_START)
  39086. create_pgd_entry x25, x0, x3, x5, x6
  39087. - create_block_map x0, x7, x3, x5, x5, idmap=1
  39088. + ldr x6, =KERNEL_END
  39089. + mov x5, x3 // __pa(KERNEL_START)
  39090. + add x6, x6, x28 // __pa(KERNEL_END)
  39091. + create_block_map x0, x7, x3, x5, x6
  39092. /*
  39093. * Map the kernel image (starting with PHYS_OFFSET).
  39094. @@ -445,7 +449,7 @@
  39095. add x0, x26, #PAGE_SIZE // section table address
  39096. mov x5, #PAGE_OFFSET
  39097. create_pgd_entry x26, x0, x5, x3, x6
  39098. - ldr x6, =KERNEL_END - 1
  39099. + ldr x6, =KERNEL_END
  39100. mov x3, x24 // phys offset
  39101. create_block_map x0, x7, x3, x5, x6
  39102. @@ -474,6 +478,17 @@
  39103. add x0, x26, #2 * PAGE_SIZE // section table address
  39104. create_pgd_entry x26, x0, x5, x6, x7
  39105. #endif
  39106. +
  39107. + /*
  39108. + * Since the page tables have been populated with non-cacheable
  39109. + * accesses (MMU disabled), invalidate the idmap and swapper page
  39110. + * tables again to remove any speculatively loaded cache lines.
  39111. + */
  39112. + mov x0, x25
  39113. + add x1, x26, #SWAPPER_DIR_SIZE
  39114. + bl __inval_cache_range
  39115. +
  39116. + mov lr, x27
  39117. ret
  39118. ENDPROC(__create_page_tables)
  39119. .ltorg
  39120. @@ -483,7 +498,7 @@
  39121. __switch_data:
  39122. .quad __mmap_switched
  39123. .quad __bss_start // x6
  39124. - .quad _end // x7
  39125. + .quad __bss_stop // x7
  39126. .quad processor_id // x4
  39127. .quad __fdt_pointer // x5
  39128. .quad memstart_addr // x6
  39129. diff -Nur linux-3.14.14/arch/arm64/kernel/hw_breakpoint.c linux-imx6-3.14/arch/arm64/kernel/hw_breakpoint.c
  39130. --- linux-3.14.14/arch/arm64/kernel/hw_breakpoint.c 2014-07-28 10:07:25.000000000 -0500
  39131. +++ linux-imx6-3.14/arch/arm64/kernel/hw_breakpoint.c 2014-12-08 00:31:51.420418001 -0600
  39132. @@ -20,6 +20,7 @@
  39133. #define pr_fmt(fmt) "hw-breakpoint: " fmt
  39134. +#include <linux/compat.h>
  39135. #include <linux/cpu_pm.h>
  39136. #include <linux/errno.h>
  39137. #include <linux/hw_breakpoint.h>
  39138. @@ -27,7 +28,6 @@
  39139. #include <linux/ptrace.h>
  39140. #include <linux/smp.h>
  39141. -#include <asm/compat.h>
  39142. #include <asm/current.h>
  39143. #include <asm/debug-monitors.h>
  39144. #include <asm/hw_breakpoint.h>
  39145. diff -Nur linux-3.14.14/arch/arm64/kernel/kgdb.c linux-imx6-3.14/arch/arm64/kernel/kgdb.c
  39146. --- linux-3.14.14/arch/arm64/kernel/kgdb.c 1969-12-31 18:00:00.000000000 -0600
  39147. +++ linux-imx6-3.14/arch/arm64/kernel/kgdb.c 2014-12-08 00:31:51.420418001 -0600
  39148. @@ -0,0 +1,336 @@
  39149. +/*
  39150. + * AArch64 KGDB support
  39151. + *
  39152. + * Based on arch/arm/kernel/kgdb.c
  39153. + *
  39154. + * Copyright (C) 2013 Cavium Inc.
  39155. + * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>
  39156. + *
  39157. + * This program is free software; you can redistribute it and/or modify
  39158. + * it under the terms of the GNU General Public License version 2 as
  39159. + * published by the Free Software Foundation.
  39160. + *
  39161. + * This program is distributed in the hope that it will be useful,
  39162. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  39163. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  39164. + * GNU General Public License for more details.
  39165. + *
  39166. + * You should have received a copy of the GNU General Public License
  39167. + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  39168. + */
  39169. +
  39170. +#include <linux/irq.h>
  39171. +#include <linux/kdebug.h>
  39172. +#include <linux/kgdb.h>
  39173. +#include <asm/traps.h>
  39174. +
  39175. +struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
  39176. + { "x0", 8, offsetof(struct pt_regs, regs[0])},
  39177. + { "x1", 8, offsetof(struct pt_regs, regs[1])},
  39178. + { "x2", 8, offsetof(struct pt_regs, regs[2])},
  39179. + { "x3", 8, offsetof(struct pt_regs, regs[3])},
  39180. + { "x4", 8, offsetof(struct pt_regs, regs[4])},
  39181. + { "x5", 8, offsetof(struct pt_regs, regs[5])},
  39182. + { "x6", 8, offsetof(struct pt_regs, regs[6])},
  39183. + { "x7", 8, offsetof(struct pt_regs, regs[7])},
  39184. + { "x8", 8, offsetof(struct pt_regs, regs[8])},
  39185. + { "x9", 8, offsetof(struct pt_regs, regs[9])},
  39186. + { "x10", 8, offsetof(struct pt_regs, regs[10])},
  39187. + { "x11", 8, offsetof(struct pt_regs, regs[11])},
  39188. + { "x12", 8, offsetof(struct pt_regs, regs[12])},
  39189. + { "x13", 8, offsetof(struct pt_regs, regs[13])},
  39190. + { "x14", 8, offsetof(struct pt_regs, regs[14])},
  39191. + { "x15", 8, offsetof(struct pt_regs, regs[15])},
  39192. + { "x16", 8, offsetof(struct pt_regs, regs[16])},
  39193. + { "x17", 8, offsetof(struct pt_regs, regs[17])},
  39194. + { "x18", 8, offsetof(struct pt_regs, regs[18])},
  39195. + { "x19", 8, offsetof(struct pt_regs, regs[19])},
  39196. + { "x20", 8, offsetof(struct pt_regs, regs[20])},
  39197. + { "x21", 8, offsetof(struct pt_regs, regs[21])},
  39198. + { "x22", 8, offsetof(struct pt_regs, regs[22])},
  39199. + { "x23", 8, offsetof(struct pt_regs, regs[23])},
  39200. + { "x24", 8, offsetof(struct pt_regs, regs[24])},
  39201. + { "x25", 8, offsetof(struct pt_regs, regs[25])},
  39202. + { "x26", 8, offsetof(struct pt_regs, regs[26])},
  39203. + { "x27", 8, offsetof(struct pt_regs, regs[27])},
  39204. + { "x28", 8, offsetof(struct pt_regs, regs[28])},
  39205. + { "x29", 8, offsetof(struct pt_regs, regs[29])},
  39206. + { "x30", 8, offsetof(struct pt_regs, regs[30])},
  39207. + { "sp", 8, offsetof(struct pt_regs, sp)},
  39208. + { "pc", 8, offsetof(struct pt_regs, pc)},
  39209. + { "pstate", 8, offsetof(struct pt_regs, pstate)},
  39210. + { "v0", 16, -1 },
  39211. + { "v1", 16, -1 },
  39212. + { "v2", 16, -1 },
  39213. + { "v3", 16, -1 },
  39214. + { "v4", 16, -1 },
  39215. + { "v5", 16, -1 },
  39216. + { "v6", 16, -1 },
  39217. + { "v7", 16, -1 },
  39218. + { "v8", 16, -1 },
  39219. + { "v9", 16, -1 },
  39220. + { "v10", 16, -1 },
  39221. + { "v11", 16, -1 },
  39222. + { "v12", 16, -1 },
  39223. + { "v13", 16, -1 },
  39224. + { "v14", 16, -1 },
  39225. + { "v15", 16, -1 },
  39226. + { "v16", 16, -1 },
  39227. + { "v17", 16, -1 },
  39228. + { "v18", 16, -1 },
  39229. + { "v19", 16, -1 },
  39230. + { "v20", 16, -1 },
  39231. + { "v21", 16, -1 },
  39232. + { "v22", 16, -1 },
  39233. + { "v23", 16, -1 },
  39234. + { "v24", 16, -1 },
  39235. + { "v25", 16, -1 },
  39236. + { "v26", 16, -1 },
  39237. + { "v27", 16, -1 },
  39238. + { "v28", 16, -1 },
  39239. + { "v29", 16, -1 },
  39240. + { "v30", 16, -1 },
  39241. + { "v31", 16, -1 },
  39242. + { "fpsr", 4, -1 },
  39243. + { "fpcr", 4, -1 },
  39244. +};
  39245. +
  39246. +char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
  39247. +{
  39248. + if (regno >= DBG_MAX_REG_NUM || regno < 0)
  39249. + return NULL;
  39250. +
  39251. + if (dbg_reg_def[regno].offset != -1)
  39252. + memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
  39253. + dbg_reg_def[regno].size);
  39254. + else
  39255. + memset(mem, 0, dbg_reg_def[regno].size);
  39256. + return dbg_reg_def[regno].name;
  39257. +}
  39258. +
  39259. +int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
  39260. +{
  39261. + if (regno >= DBG_MAX_REG_NUM || regno < 0)
  39262. + return -EINVAL;
  39263. +
  39264. + if (dbg_reg_def[regno].offset != -1)
  39265. + memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
  39266. + dbg_reg_def[regno].size);
  39267. + return 0;
  39268. +}
  39269. +
  39270. +void
  39271. +sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
  39272. +{
  39273. + struct pt_regs *thread_regs;
  39274. +
  39275. + /* Initialize to zero */
  39276. + memset((char *)gdb_regs, 0, NUMREGBYTES);
  39277. + thread_regs = task_pt_regs(task);
  39278. + memcpy((void *)gdb_regs, (void *)thread_regs->regs, GP_REG_BYTES);
  39279. +}
  39280. +
  39281. +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
  39282. +{
  39283. + regs->pc = pc;
  39284. +}
  39285. +
  39286. +static int compiled_break;
  39287. +
  39288. +static void kgdb_arch_update_addr(struct pt_regs *regs,
  39289. + char *remcom_in_buffer)
  39290. +{
  39291. + unsigned long addr;
  39292. + char *ptr;
  39293. +
  39294. + ptr = &remcom_in_buffer[1];
  39295. + if (kgdb_hex2long(&ptr, &addr))
  39296. + kgdb_arch_set_pc(regs, addr);
  39297. + else if (compiled_break == 1)
  39298. + kgdb_arch_set_pc(regs, regs->pc + 4);
  39299. +
  39300. + compiled_break = 0;
  39301. +}
  39302. +
  39303. +int kgdb_arch_handle_exception(int exception_vector, int signo,
  39304. + int err_code, char *remcom_in_buffer,
  39305. + char *remcom_out_buffer,
  39306. + struct pt_regs *linux_regs)
  39307. +{
  39308. + int err;
  39309. +
  39310. + switch (remcom_in_buffer[0]) {
  39311. + case 'D':
  39312. + case 'k':
  39313. + /*
  39314. + * Packet D (Detach), k (kill). No special handling
  39315. + * is required here. Handle same as c packet.
  39316. + */
  39317. + case 'c':
  39318. + /*
  39319. + * Packet c (Continue) to continue executing.
  39320. + * Set pc to required address.
  39321. + * Try to read optional parameter and set pc.
  39322. + * If this was a compiled breakpoint, we need to move
  39323. + * to the next instruction else we will just breakpoint
  39324. + * over and over again.
  39325. + */
  39326. + kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
  39327. + atomic_set(&kgdb_cpu_doing_single_step, -1);
  39328. + kgdb_single_step = 0;
  39329. +
  39330. + /*
  39331. + * Received continue command, disable single step
  39332. + */
  39333. + if (kernel_active_single_step())
  39334. + kernel_disable_single_step();
  39335. +
  39336. + err = 0;
  39337. + break;
  39338. + case 's':
  39339. + /*
  39340. + * Update step address value with address passed
  39341. + * with step packet.
  39342. + * On debug exception return PC is copied to ELR
  39343. + * So just update PC.
  39344. + * If no step address is passed, resume from the address
  39345. + * pointed by PC. Do not update PC
  39346. + */
  39347. + kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
  39348. + atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id());
  39349. + kgdb_single_step = 1;
  39350. +
  39351. + /*
  39352. + * Enable single step handling
  39353. + */
  39354. + if (!kernel_active_single_step())
  39355. + kernel_enable_single_step(linux_regs);
  39356. + err = 0;
  39357. + break;
  39358. + default:
  39359. + err = -1;
  39360. + }
  39361. + return err;
  39362. +}
  39363. +
  39364. +static int kgdb_brk_fn(struct pt_regs *regs, unsigned int esr)
  39365. +{
  39366. + kgdb_handle_exception(1, SIGTRAP, 0, regs);
  39367. + return 0;
  39368. +}
  39369. +
  39370. +static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
  39371. +{
  39372. + compiled_break = 1;
  39373. + kgdb_handle_exception(1, SIGTRAP, 0, regs);
  39374. +
  39375. + return 0;
  39376. +}
  39377. +
  39378. +static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
  39379. +{
  39380. + kgdb_handle_exception(1, SIGTRAP, 0, regs);
  39381. + return 0;
  39382. +}
  39383. +
  39384. +static struct break_hook kgdb_brkpt_hook = {
  39385. + .esr_mask = 0xffffffff,
  39386. + .esr_val = DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM),
  39387. + .fn = kgdb_brk_fn
  39388. +};
  39389. +
  39390. +static struct break_hook kgdb_compiled_brkpt_hook = {
  39391. + .esr_mask = 0xffffffff,
  39392. + .esr_val = DBG_ESR_VAL_BRK(KDBG_COMPILED_DBG_BRK_IMM),
  39393. + .fn = kgdb_compiled_brk_fn
  39394. +};
  39395. +
  39396. +static struct step_hook kgdb_step_hook = {
  39397. + .fn = kgdb_step_brk_fn
  39398. +};
  39399. +
  39400. +static void kgdb_call_nmi_hook(void *ignored)
  39401. +{
  39402. + kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
  39403. +}
  39404. +
  39405. +void kgdb_roundup_cpus(unsigned long flags)
  39406. +{
  39407. + local_irq_enable();
  39408. + smp_call_function(kgdb_call_nmi_hook, NULL, 0);
  39409. + local_irq_disable();
  39410. +}
  39411. +
  39412. +static int __kgdb_notify(struct die_args *args, unsigned long cmd)
  39413. +{
  39414. + struct pt_regs *regs = args->regs;
  39415. +
  39416. + if (kgdb_handle_exception(1, args->signr, cmd, regs))
  39417. + return NOTIFY_DONE;
  39418. + return NOTIFY_STOP;
  39419. +}
  39420. +
  39421. +static int
  39422. +kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
  39423. +{
  39424. + unsigned long flags;
  39425. + int ret;
  39426. +
  39427. + local_irq_save(flags);
  39428. + ret = __kgdb_notify(ptr, cmd);
  39429. + local_irq_restore(flags);
  39430. +
  39431. + return ret;
  39432. +}
  39433. +
  39434. +static struct notifier_block kgdb_notifier = {
  39435. + .notifier_call = kgdb_notify,
  39436. + /*
  39437. + * Want to be lowest priority
  39438. + */
  39439. + .priority = -INT_MAX,
  39440. +};
  39441. +
  39442. +/*
  39443. + * kgdb_arch_init - Perform any architecture specific initalization.
  39444. + * This function will handle the initalization of any architecture
  39445. + * specific callbacks.
  39446. + */
  39447. +int kgdb_arch_init(void)
  39448. +{
  39449. + int ret = register_die_notifier(&kgdb_notifier);
  39450. +
  39451. + if (ret != 0)
  39452. + return ret;
  39453. +
  39454. + register_break_hook(&kgdb_brkpt_hook);
  39455. + register_break_hook(&kgdb_compiled_brkpt_hook);
  39456. + register_step_hook(&kgdb_step_hook);
  39457. + return 0;
  39458. +}
  39459. +
  39460. +/*
  39461. + * kgdb_arch_exit - Perform any architecture specific uninitalization.
  39462. + * This function will handle the uninitalization of any architecture
  39463. + * specific callbacks, for dynamic registration and unregistration.
  39464. + */
  39465. +void kgdb_arch_exit(void)
  39466. +{
  39467. + unregister_break_hook(&kgdb_brkpt_hook);
  39468. + unregister_break_hook(&kgdb_compiled_brkpt_hook);
  39469. + unregister_step_hook(&kgdb_step_hook);
  39470. + unregister_die_notifier(&kgdb_notifier);
  39471. +}
  39472. +
  39473. +/*
  39474. + * ARM instructions are always in LE.
  39475. + * Break instruction is encoded in LE format
  39476. + */
  39477. +struct kgdb_arch arch_kgdb_ops = {
  39478. + .gdb_bpt_instr = {
  39479. + KGDB_DYN_BRK_INS_BYTE0,
  39480. + KGDB_DYN_BRK_INS_BYTE1,
  39481. + KGDB_DYN_BRK_INS_BYTE2,
  39482. + KGDB_DYN_BRK_INS_BYTE3,
  39483. + }
  39484. +};
  39485. diff -Nur linux-3.14.14/arch/arm64/kernel/Makefile linux-imx6-3.14/arch/arm64/kernel/Makefile
  39486. --- linux-3.14.14/arch/arm64/kernel/Makefile 2014-07-28 10:07:25.000000000 -0500
  39487. +++ linux-imx6-3.14/arch/arm64/kernel/Makefile 2014-12-08 00:31:51.416418001 -0600
  39488. @@ -5,21 +5,29 @@
  39489. CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
  39490. AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
  39491. +CFLAGS_REMOVE_ftrace.o = -pg
  39492. +CFLAGS_REMOVE_insn.o = -pg
  39493. +CFLAGS_REMOVE_return_address.o = -pg
  39494. +
  39495. # Object file lists.
  39496. arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \
  39497. entry-fpsimd.o process.o ptrace.o setup.o signal.o \
  39498. sys.o stacktrace.o time.o traps.o io.o vdso.o \
  39499. - hyp-stub.o psci.o cpu_ops.o insn.o
  39500. + hyp-stub.o psci.o cpu_ops.o insn.o return_address.o
  39501. arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
  39502. sys_compat.o
  39503. +arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
  39504. arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
  39505. +arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o topology.o
  39506. arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o
  39507. +arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
  39508. arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
  39509. -arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
  39510. +arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
  39511. arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  39512. arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o
  39513. arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
  39514. +arm64-obj-$(CONFIG_KGDB) += kgdb.o
  39515. obj-y += $(arm64-obj-y) vdso/
  39516. obj-m += $(arm64-obj-m)
  39517. diff -Nur linux-3.14.14/arch/arm64/kernel/perf_event.c linux-imx6-3.14/arch/arm64/kernel/perf_event.c
  39518. --- linux-3.14.14/arch/arm64/kernel/perf_event.c 2014-07-28 10:07:25.000000000 -0500
  39519. +++ linux-imx6-3.14/arch/arm64/kernel/perf_event.c 2014-12-08 00:31:51.420418001 -0600
  39520. @@ -1348,8 +1348,8 @@
  39521. * Callchain handling code.
  39522. */
  39523. struct frame_tail {
  39524. - struct frame_tail __user *fp;
  39525. - unsigned long lr;
  39526. + struct frame_tail __user *fp;
  39527. + unsigned long lr;
  39528. } __attribute__((packed));
  39529. /*
  39530. @@ -1386,22 +1386,84 @@
  39531. return buftail.fp;
  39532. }
  39533. +#ifdef CONFIG_COMPAT
  39534. +/*
  39535. + * The registers we're interested in are at the end of the variable
  39536. + * length saved register structure. The fp points at the end of this
  39537. + * structure so the address of this struct is:
  39538. + * (struct compat_frame_tail *)(xxx->fp)-1
  39539. + *
  39540. + * This code has been adapted from the ARM OProfile support.
  39541. + */
  39542. +struct compat_frame_tail {
  39543. + compat_uptr_t fp; /* a (struct compat_frame_tail *) in compat mode */
  39544. + u32 sp;
  39545. + u32 lr;
  39546. +} __attribute__((packed));
  39547. +
  39548. +static struct compat_frame_tail __user *
  39549. +compat_user_backtrace(struct compat_frame_tail __user *tail,
  39550. + struct perf_callchain_entry *entry)
  39551. +{
  39552. + struct compat_frame_tail buftail;
  39553. + unsigned long err;
  39554. +
  39555. + /* Also check accessibility of one struct frame_tail beyond */
  39556. + if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
  39557. + return NULL;
  39558. +
  39559. + pagefault_disable();
  39560. + err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail));
  39561. + pagefault_enable();
  39562. +
  39563. + if (err)
  39564. + return NULL;
  39565. +
  39566. + perf_callchain_store(entry, buftail.lr);
  39567. +
  39568. + /*
  39569. + * Frame pointers should strictly progress back up the stack
  39570. + * (towards higher addresses).
  39571. + */
  39572. + if (tail + 1 >= (struct compat_frame_tail __user *)
  39573. + compat_ptr(buftail.fp))
  39574. + return NULL;
  39575. +
  39576. + return (struct compat_frame_tail __user *)compat_ptr(buftail.fp) - 1;
  39577. +}
  39578. +#endif /* CONFIG_COMPAT */
  39579. +
  39580. void perf_callchain_user(struct perf_callchain_entry *entry,
  39581. struct pt_regs *regs)
  39582. {
  39583. - struct frame_tail __user *tail;
  39584. -
  39585. if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
  39586. /* We don't support guest os callchain now */
  39587. return;
  39588. }
  39589. perf_callchain_store(entry, regs->pc);
  39590. - tail = (struct frame_tail __user *)regs->regs[29];
  39591. - while (entry->nr < PERF_MAX_STACK_DEPTH &&
  39592. - tail && !((unsigned long)tail & 0xf))
  39593. - tail = user_backtrace(tail, entry);
  39594. + if (!compat_user_mode(regs)) {
  39595. + /* AARCH64 mode */
  39596. + struct frame_tail __user *tail;
  39597. +
  39598. + tail = (struct frame_tail __user *)regs->regs[29];
  39599. +
  39600. + while (entry->nr < PERF_MAX_STACK_DEPTH &&
  39601. + tail && !((unsigned long)tail & 0xf))
  39602. + tail = user_backtrace(tail, entry);
  39603. + } else {
  39604. +#ifdef CONFIG_COMPAT
  39605. + /* AARCH32 compat mode */
  39606. + struct compat_frame_tail __user *tail;
  39607. +
  39608. + tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
  39609. +
  39610. + while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
  39611. + tail && !((unsigned long)tail & 0x3))
  39612. + tail = compat_user_backtrace(tail, entry);
  39613. +#endif
  39614. + }
  39615. }
  39616. /*
  39617. @@ -1429,6 +1491,7 @@
  39618. frame.fp = regs->regs[29];
  39619. frame.sp = regs->sp;
  39620. frame.pc = regs->pc;
  39621. +
  39622. walk_stackframe(&frame, callchain_trace, entry);
  39623. }
  39624. diff -Nur linux-3.14.14/arch/arm64/kernel/perf_regs.c linux-imx6-3.14/arch/arm64/kernel/perf_regs.c
  39625. --- linux-3.14.14/arch/arm64/kernel/perf_regs.c 1969-12-31 18:00:00.000000000 -0600
  39626. +++ linux-imx6-3.14/arch/arm64/kernel/perf_regs.c 2014-12-08 00:31:51.420418001 -0600
  39627. @@ -0,0 +1,46 @@
  39628. +#include <linux/errno.h>
  39629. +#include <linux/kernel.h>
  39630. +#include <linux/perf_event.h>
  39631. +#include <linux/bug.h>
  39632. +
  39633. +#include <asm/compat.h>
  39634. +#include <asm/perf_regs.h>
  39635. +#include <asm/ptrace.h>
  39636. +
  39637. +u64 perf_reg_value(struct pt_regs *regs, int idx)
  39638. +{
  39639. + if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
  39640. + return 0;
  39641. +
  39642. + /*
  39643. + * Compat (i.e. 32 bit) mode:
  39644. + * - PC has been set in the pt_regs struct in kernel_entry,
  39645. + * - Handle SP and LR here.
  39646. + */
  39647. + if (compat_user_mode(regs)) {
  39648. + if ((u32)idx == PERF_REG_ARM64_SP)
  39649. + return regs->compat_sp;
  39650. + if ((u32)idx == PERF_REG_ARM64_LR)
  39651. + return regs->compat_lr;
  39652. + }
  39653. +
  39654. + return regs->regs[idx];
  39655. +}
  39656. +
  39657. +#define REG_RESERVED (~((1ULL << PERF_REG_ARM64_MAX) - 1))
  39658. +
  39659. +int perf_reg_validate(u64 mask)
  39660. +{
  39661. + if (!mask || mask & REG_RESERVED)
  39662. + return -EINVAL;
  39663. +
  39664. + return 0;
  39665. +}
  39666. +
  39667. +u64 perf_reg_abi(struct task_struct *task)
  39668. +{
  39669. + if (is_compat_thread(task_thread_info(task)))
  39670. + return PERF_SAMPLE_REGS_ABI_32;
  39671. + else
  39672. + return PERF_SAMPLE_REGS_ABI_64;
  39673. +}
  39674. diff -Nur linux-3.14.14/arch/arm64/kernel/process.c linux-imx6-3.14/arch/arm64/kernel/process.c
  39675. --- linux-3.14.14/arch/arm64/kernel/process.c 2014-07-28 10:07:25.000000000 -0500
  39676. +++ linux-imx6-3.14/arch/arm64/kernel/process.c 2014-12-08 00:31:51.420418001 -0600
  39677. @@ -20,6 +20,7 @@
  39678. #include <stdarg.h>
  39679. +#include <linux/compat.h>
  39680. #include <linux/export.h>
  39681. #include <linux/sched.h>
  39682. #include <linux/kernel.h>
  39683. diff -Nur linux-3.14.14/arch/arm64/kernel/ptrace.c linux-imx6-3.14/arch/arm64/kernel/ptrace.c
  39684. --- linux-3.14.14/arch/arm64/kernel/ptrace.c 2014-07-28 10:07:25.000000000 -0500
  39685. +++ linux-imx6-3.14/arch/arm64/kernel/ptrace.c 2014-12-08 00:31:51.420418001 -0600
  39686. @@ -19,6 +19,7 @@
  39687. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  39688. */
  39689. +#include <linux/compat.h>
  39690. #include <linux/kernel.h>
  39691. #include <linux/sched.h>
  39692. #include <linux/mm.h>
  39693. @@ -41,6 +42,9 @@
  39694. #include <asm/traps.h>
  39695. #include <asm/system_misc.h>
  39696. +#define CREATE_TRACE_POINTS
  39697. +#include <trace/events/syscalls.h>
  39698. +
  39699. /*
  39700. * TODO: does not yet catch signals sent when the child dies.
  39701. * in exit.c or in signal.c.
  39702. @@ -1072,35 +1076,49 @@
  39703. return ptrace_request(child, request, addr, data);
  39704. }
  39705. -asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
  39706. +enum ptrace_syscall_dir {
  39707. + PTRACE_SYSCALL_ENTER = 0,
  39708. + PTRACE_SYSCALL_EXIT,
  39709. +};
  39710. +
  39711. +static void tracehook_report_syscall(struct pt_regs *regs,
  39712. + enum ptrace_syscall_dir dir)
  39713. {
  39714. + int regno;
  39715. unsigned long saved_reg;
  39716. - if (!test_thread_flag(TIF_SYSCALL_TRACE))
  39717. - return regs->syscallno;
  39718. -
  39719. - if (is_compat_task()) {
  39720. - /* AArch32 uses ip (r12) for scratch */
  39721. - saved_reg = regs->regs[12];
  39722. - regs->regs[12] = dir;
  39723. - } else {
  39724. - /*
  39725. - * Save X7. X7 is used to denote syscall entry/exit:
  39726. - * X7 = 0 -> entry, = 1 -> exit
  39727. - */
  39728. - saved_reg = regs->regs[7];
  39729. - regs->regs[7] = dir;
  39730. - }
  39731. + /*
  39732. + * A scratch register (ip(r12) on AArch32, x7 on AArch64) is
  39733. + * used to denote syscall entry/exit:
  39734. + */
  39735. + regno = (is_compat_task() ? 12 : 7);
  39736. + saved_reg = regs->regs[regno];
  39737. + regs->regs[regno] = dir;
  39738. - if (dir)
  39739. + if (dir == PTRACE_SYSCALL_EXIT)
  39740. tracehook_report_syscall_exit(regs, 0);
  39741. else if (tracehook_report_syscall_entry(regs))
  39742. regs->syscallno = ~0UL;
  39743. - if (is_compat_task())
  39744. - regs->regs[12] = saved_reg;
  39745. - else
  39746. - regs->regs[7] = saved_reg;
  39747. + regs->regs[regno] = saved_reg;
  39748. +}
  39749. +
  39750. +asmlinkage int syscall_trace_enter(struct pt_regs *regs)
  39751. +{
  39752. + if (test_thread_flag(TIF_SYSCALL_TRACE))
  39753. + tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
  39754. +
  39755. + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
  39756. + trace_sys_enter(regs, regs->syscallno);
  39757. return regs->syscallno;
  39758. }
  39759. +
  39760. +asmlinkage void syscall_trace_exit(struct pt_regs *regs)
  39761. +{
  39762. + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
  39763. + trace_sys_exit(regs, regs_return_value(regs));
  39764. +
  39765. + if (test_thread_flag(TIF_SYSCALL_TRACE))
  39766. + tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
  39767. +}
  39768. diff -Nur linux-3.14.14/arch/arm64/kernel/return_address.c linux-imx6-3.14/arch/arm64/kernel/return_address.c
  39769. --- linux-3.14.14/arch/arm64/kernel/return_address.c 1969-12-31 18:00:00.000000000 -0600
  39770. +++ linux-imx6-3.14/arch/arm64/kernel/return_address.c 2014-12-08 00:31:51.420418001 -0600
  39771. @@ -0,0 +1,55 @@
  39772. +/*
  39773. + * arch/arm64/kernel/return_address.c
  39774. + *
  39775. + * Copyright (C) 2013 Linaro Limited
  39776. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  39777. + *
  39778. + * This program is free software; you can redistribute it and/or modify
  39779. + * it under the terms of the GNU General Public License version 2 as
  39780. + * published by the Free Software Foundation.
  39781. + */
  39782. +
  39783. +#include <linux/export.h>
  39784. +#include <linux/ftrace.h>
  39785. +
  39786. +#include <asm/stacktrace.h>
  39787. +
  39788. +struct return_address_data {
  39789. + unsigned int level;
  39790. + void *addr;
  39791. +};
  39792. +
  39793. +static int save_return_addr(struct stackframe *frame, void *d)
  39794. +{
  39795. + struct return_address_data *data = d;
  39796. +
  39797. + if (!data->level) {
  39798. + data->addr = (void *)frame->pc;
  39799. + return 1;
  39800. + } else {
  39801. + --data->level;
  39802. + return 0;
  39803. + }
  39804. +}
  39805. +
  39806. +void *return_address(unsigned int level)
  39807. +{
  39808. + struct return_address_data data;
  39809. + struct stackframe frame;
  39810. + register unsigned long current_sp asm ("sp");
  39811. +
  39812. + data.level = level + 2;
  39813. + data.addr = NULL;
  39814. +
  39815. + frame.fp = (unsigned long)__builtin_frame_address(0);
  39816. + frame.sp = current_sp;
  39817. + frame.pc = (unsigned long)return_address; /* dummy */
  39818. +
  39819. + walk_stackframe(&frame, save_return_addr, &data);
  39820. +
  39821. + if (!data.level)
  39822. + return data.addr;
  39823. + else
  39824. + return NULL;
  39825. +}
  39826. +EXPORT_SYMBOL_GPL(return_address);
  39827. diff -Nur linux-3.14.14/arch/arm64/kernel/setup.c linux-imx6-3.14/arch/arm64/kernel/setup.c
  39828. --- linux-3.14.14/arch/arm64/kernel/setup.c 2014-07-28 10:07:25.000000000 -0500
  39829. +++ linux-imx6-3.14/arch/arm64/kernel/setup.c 2014-12-08 00:31:51.420418001 -0600
  39830. @@ -69,6 +69,7 @@
  39831. COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\
  39832. COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV)
  39833. unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT;
  39834. +unsigned int compat_elf_hwcap2 __read_mostly;
  39835. #endif
  39836. static const char *cpu_name;
  39837. @@ -242,6 +243,38 @@
  39838. block = (features >> 16) & 0xf;
  39839. if (block && !(block & 0x8))
  39840. elf_hwcap |= HWCAP_CRC32;
  39841. +
  39842. +#ifdef CONFIG_COMPAT
  39843. + /*
  39844. + * ID_ISAR5_EL1 carries similar information as above, but pertaining to
  39845. + * the Aarch32 32-bit execution state.
  39846. + */
  39847. + features = read_cpuid(ID_ISAR5_EL1);
  39848. + block = (features >> 4) & 0xf;
  39849. + if (!(block & 0x8)) {
  39850. + switch (block) {
  39851. + default:
  39852. + case 2:
  39853. + compat_elf_hwcap2 |= COMPAT_HWCAP2_PMULL;
  39854. + case 1:
  39855. + compat_elf_hwcap2 |= COMPAT_HWCAP2_AES;
  39856. + case 0:
  39857. + break;
  39858. + }
  39859. + }
  39860. +
  39861. + block = (features >> 8) & 0xf;
  39862. + if (block && !(block & 0x8))
  39863. + compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA1;
  39864. +
  39865. + block = (features >> 12) & 0xf;
  39866. + if (block && !(block & 0x8))
  39867. + compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA2;
  39868. +
  39869. + block = (features >> 16) & 0xf;
  39870. + if (block && !(block & 0x8))
  39871. + compat_elf_hwcap2 |= COMPAT_HWCAP2_CRC32;
  39872. +#endif
  39873. }
  39874. static void __init setup_machine_fdt(phys_addr_t dt_phys)
  39875. @@ -360,7 +393,7 @@
  39876. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  39877. return 0;
  39878. }
  39879. -arch_initcall(arm64_device_init);
  39880. +arch_initcall_sync(arm64_device_init);
  39881. static DEFINE_PER_CPU(struct cpu, cpu_data);
  39882. diff -Nur linux-3.14.14/arch/arm64/kernel/signal.c linux-imx6-3.14/arch/arm64/kernel/signal.c
  39883. --- linux-3.14.14/arch/arm64/kernel/signal.c 2014-07-28 10:07:25.000000000 -0500
  39884. +++ linux-imx6-3.14/arch/arm64/kernel/signal.c 2014-12-08 00:31:51.420418001 -0600
  39885. @@ -17,6 +17,7 @@
  39886. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  39887. */
  39888. +#include <linux/compat.h>
  39889. #include <linux/errno.h>
  39890. #include <linux/signal.h>
  39891. #include <linux/personality.h>
  39892. @@ -25,7 +26,6 @@
  39893. #include <linux/tracehook.h>
  39894. #include <linux/ratelimit.h>
  39895. -#include <asm/compat.h>
  39896. #include <asm/debug-monitors.h>
  39897. #include <asm/elf.h>
  39898. #include <asm/cacheflush.h>
  39899. diff -Nur linux-3.14.14/arch/arm64/kernel/smp.c linux-imx6-3.14/arch/arm64/kernel/smp.c
  39900. --- linux-3.14.14/arch/arm64/kernel/smp.c 2014-07-28 10:07:25.000000000 -0500
  39901. +++ linux-imx6-3.14/arch/arm64/kernel/smp.c 2014-12-08 00:31:51.420418001 -0600
  39902. @@ -114,6 +114,11 @@
  39903. return ret;
  39904. }
  39905. +static void smp_store_cpu_info(unsigned int cpuid)
  39906. +{
  39907. + store_cpu_topology(cpuid);
  39908. +}
  39909. +
  39910. /*
  39911. * This is the secondary CPU boot entry. We're using this CPUs
  39912. * idle thread stack, but a set of temporary page tables.
  39913. @@ -152,6 +157,8 @@
  39914. */
  39915. notify_cpu_starting(cpu);
  39916. + smp_store_cpu_info(cpu);
  39917. +
  39918. /*
  39919. * OK, now it's safe to let the boot CPU continue. Wait for
  39920. * the CPU migration code to notice that the CPU is online
  39921. @@ -390,6 +397,10 @@
  39922. int err;
  39923. unsigned int cpu, ncores = num_possible_cpus();
  39924. + init_cpu_topology();
  39925. +
  39926. + smp_store_cpu_info(smp_processor_id());
  39927. +
  39928. /*
  39929. * are we trying to boot more cores than exist?
  39930. */
  39931. diff -Nur linux-3.14.14/arch/arm64/kernel/stacktrace.c linux-imx6-3.14/arch/arm64/kernel/stacktrace.c
  39932. --- linux-3.14.14/arch/arm64/kernel/stacktrace.c 2014-07-28 10:07:25.000000000 -0500
  39933. +++ linux-imx6-3.14/arch/arm64/kernel/stacktrace.c 2014-12-08 00:31:51.420418001 -0600
  39934. @@ -35,7 +35,7 @@
  39935. * ldp x29, x30, [sp]
  39936. * add sp, sp, #0x10
  39937. */
  39938. -int unwind_frame(struct stackframe *frame)
  39939. +int notrace unwind_frame(struct stackframe *frame)
  39940. {
  39941. unsigned long high, low;
  39942. unsigned long fp = frame->fp;
  39943. diff -Nur linux-3.14.14/arch/arm64/kernel/topology.c linux-imx6-3.14/arch/arm64/kernel/topology.c
  39944. --- linux-3.14.14/arch/arm64/kernel/topology.c 1969-12-31 18:00:00.000000000 -0600
  39945. +++ linux-imx6-3.14/arch/arm64/kernel/topology.c 2014-12-08 00:31:51.420418001 -0600
  39946. @@ -0,0 +1,558 @@
  39947. +/*
  39948. + * arch/arm64/kernel/topology.c
  39949. + *
  39950. + * Copyright (C) 2011,2013,2014 Linaro Limited.
  39951. + *
  39952. + * Based on the arm32 version written by Vincent Guittot in turn based on
  39953. + * arch/sh/kernel/topology.c
  39954. + *
  39955. + * This file is subject to the terms and conditions of the GNU General Public
  39956. + * License. See the file "COPYING" in the main directory of this archive
  39957. + * for more details.
  39958. + */
  39959. +
  39960. +#include <linux/cpu.h>
  39961. +#include <linux/cpumask.h>
  39962. +#include <linux/init.h>
  39963. +#include <linux/percpu.h>
  39964. +#include <linux/node.h>
  39965. +#include <linux/nodemask.h>
  39966. +#include <linux/of.h>
  39967. +#include <linux/sched.h>
  39968. +#include <linux/slab.h>
  39969. +
  39970. +#include <asm/topology.h>
  39971. +
  39972. +/*
  39973. + * cpu power table
  39974. + * This per cpu data structure describes the relative capacity of each core.
  39975. + * On a heteregenous system, cores don't have the same computation capacity
  39976. + * and we reflect that difference in the cpu_power field so the scheduler can
  39977. + * take this difference into account during load balance. A per cpu structure
  39978. + * is preferred because each CPU updates its own cpu_power field during the
  39979. + * load balance except for idle cores. One idle core is selected to run the
  39980. + * rebalance_domains for all idle cores and the cpu_power can be updated
  39981. + * during this sequence.
  39982. + */
  39983. +static DEFINE_PER_CPU(unsigned long, cpu_scale);
  39984. +
  39985. +unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu)
  39986. +{
  39987. + return per_cpu(cpu_scale, cpu);
  39988. +}
  39989. +
  39990. +static void set_power_scale(unsigned int cpu, unsigned long power)
  39991. +{
  39992. + per_cpu(cpu_scale, cpu) = power;
  39993. +}
  39994. +
  39995. +static int __init get_cpu_for_node(struct device_node *node)
  39996. +{
  39997. + struct device_node *cpu_node;
  39998. + int cpu;
  39999. +
  40000. + cpu_node = of_parse_phandle(node, "cpu", 0);
  40001. + if (!cpu_node)
  40002. + return -1;
  40003. +
  40004. + for_each_possible_cpu(cpu) {
  40005. + if (of_get_cpu_node(cpu, NULL) == cpu_node) {
  40006. + of_node_put(cpu_node);
  40007. + return cpu;
  40008. + }
  40009. + }
  40010. +
  40011. + pr_crit("Unable to find CPU node for %s\n", cpu_node->full_name);
  40012. +
  40013. + of_node_put(cpu_node);
  40014. + return -1;
  40015. +}
  40016. +
  40017. +static int __init parse_core(struct device_node *core, int cluster_id,
  40018. + int core_id)
  40019. +{
  40020. + char name[10];
  40021. + bool leaf = true;
  40022. + int i = 0;
  40023. + int cpu;
  40024. + struct device_node *t;
  40025. +
  40026. + do {
  40027. + snprintf(name, sizeof(name), "thread%d", i);
  40028. + t = of_get_child_by_name(core, name);
  40029. + if (t) {
  40030. + leaf = false;
  40031. + cpu = get_cpu_for_node(t);
  40032. + if (cpu >= 0) {
  40033. + cpu_topology[cpu].cluster_id = cluster_id;
  40034. + cpu_topology[cpu].core_id = core_id;
  40035. + cpu_topology[cpu].thread_id = i;
  40036. + } else {
  40037. + pr_err("%s: Can't get CPU for thread\n",
  40038. + t->full_name);
  40039. + of_node_put(t);
  40040. + return -EINVAL;
  40041. + }
  40042. + of_node_put(t);
  40043. + }
  40044. + i++;
  40045. + } while (t);
  40046. +
  40047. + cpu = get_cpu_for_node(core);
  40048. + if (cpu >= 0) {
  40049. + if (!leaf) {
  40050. + pr_err("%s: Core has both threads and CPU\n",
  40051. + core->full_name);
  40052. + return -EINVAL;
  40053. + }
  40054. +
  40055. + cpu_topology[cpu].cluster_id = cluster_id;
  40056. + cpu_topology[cpu].core_id = core_id;
  40057. + } else if (leaf) {
  40058. + pr_err("%s: Can't get CPU for leaf core\n", core->full_name);
  40059. + return -EINVAL;
  40060. + }
  40061. +
  40062. + return 0;
  40063. +}
  40064. +
  40065. +static int __init parse_cluster(struct device_node *cluster, int depth)
  40066. +{
  40067. + char name[10];
  40068. + bool leaf = true;
  40069. + bool has_cores = false;
  40070. + struct device_node *c;
  40071. + static int cluster_id __initdata;
  40072. + int core_id = 0;
  40073. + int i, ret;
  40074. +
  40075. + /*
  40076. + * First check for child clusters; we currently ignore any
  40077. + * information about the nesting of clusters and present the
  40078. + * scheduler with a flat list of them.
  40079. + */
  40080. + i = 0;
  40081. + do {
  40082. + snprintf(name, sizeof(name), "cluster%d", i);
  40083. + c = of_get_child_by_name(cluster, name);
  40084. + if (c) {
  40085. + leaf = false;
  40086. + ret = parse_cluster(c, depth + 1);
  40087. + of_node_put(c);
  40088. + if (ret != 0)
  40089. + return ret;
  40090. + }
  40091. + i++;
  40092. + } while (c);
  40093. +
  40094. + /* Now check for cores */
  40095. + i = 0;
  40096. + do {
  40097. + snprintf(name, sizeof(name), "core%d", i);
  40098. + c = of_get_child_by_name(cluster, name);
  40099. + if (c) {
  40100. + has_cores = true;
  40101. +
  40102. + if (depth == 0) {
  40103. + pr_err("%s: cpu-map children should be clusters\n",
  40104. + c->full_name);
  40105. + of_node_put(c);
  40106. + return -EINVAL;
  40107. + }
  40108. +
  40109. + if (leaf) {
  40110. + ret = parse_core(c, cluster_id, core_id++);
  40111. + } else {
  40112. + pr_err("%s: Non-leaf cluster with core %s\n",
  40113. + cluster->full_name, name);
  40114. + ret = -EINVAL;
  40115. + }
  40116. +
  40117. + of_node_put(c);
  40118. + if (ret != 0)
  40119. + return ret;
  40120. + }
  40121. + i++;
  40122. + } while (c);
  40123. +
  40124. + if (leaf && !has_cores)
  40125. + pr_warn("%s: empty cluster\n", cluster->full_name);
  40126. +
  40127. + if (leaf)
  40128. + cluster_id++;
  40129. +
  40130. + return 0;
  40131. +}
  40132. +
  40133. +struct cpu_efficiency {
  40134. + const char *compatible;
  40135. + unsigned long efficiency;
  40136. +};
  40137. +
  40138. +/*
  40139. + * Table of relative efficiency of each processors
  40140. + * The efficiency value must fit in 20bit and the final
  40141. + * cpu_scale value must be in the range
  40142. + * 0 < cpu_scale < 3*SCHED_POWER_SCALE/2
  40143. + * in order to return at most 1 when DIV_ROUND_CLOSEST
  40144. + * is used to compute the capacity of a CPU.
  40145. + * Processors that are not defined in the table,
  40146. + * use the default SCHED_POWER_SCALE value for cpu_scale.
  40147. + */
  40148. +static const struct cpu_efficiency table_efficiency[] = {
  40149. + { "arm,cortex-a57", 3891 },
  40150. + { "arm,cortex-a53", 2048 },
  40151. + { NULL, },
  40152. +};
  40153. +
  40154. +static unsigned long *__cpu_capacity;
  40155. +#define cpu_capacity(cpu) __cpu_capacity[cpu]
  40156. +
  40157. +static unsigned long middle_capacity = 1;
  40158. +
  40159. +/*
  40160. + * Iterate all CPUs' descriptor in DT and compute the efficiency
  40161. + * (as per table_efficiency). Also calculate a middle efficiency
  40162. + * as close as possible to (max{eff_i} - min{eff_i}) / 2
  40163. + * This is later used to scale the cpu_power field such that an
  40164. + * 'average' CPU is of middle power. Also see the comments near
  40165. + * table_efficiency[] and update_cpu_power().
  40166. + */
  40167. +static int __init parse_dt_topology(void)
  40168. +{
  40169. + struct device_node *cn, *map;
  40170. + int ret = 0;
  40171. + int cpu;
  40172. +
  40173. + cn = of_find_node_by_path("/cpus");
  40174. + if (!cn) {
  40175. + pr_err("No CPU information found in DT\n");
  40176. + return 0;
  40177. + }
  40178. +
  40179. + /*
  40180. + * When topology is provided cpu-map is essentially a root
  40181. + * cluster with restricted subnodes.
  40182. + */
  40183. + map = of_get_child_by_name(cn, "cpu-map");
  40184. + if (!map)
  40185. + goto out;
  40186. +
  40187. + ret = parse_cluster(map, 0);
  40188. + if (ret != 0)
  40189. + goto out_map;
  40190. +
  40191. + /*
  40192. + * Check that all cores are in the topology; the SMP code will
  40193. + * only mark cores described in the DT as possible.
  40194. + */
  40195. + for_each_possible_cpu(cpu) {
  40196. + if (cpu_topology[cpu].cluster_id == -1) {
  40197. + pr_err("CPU%d: No topology information specified\n",
  40198. + cpu);
  40199. + ret = -EINVAL;
  40200. + }
  40201. + }
  40202. +
  40203. +out_map:
  40204. + of_node_put(map);
  40205. +out:
  40206. + of_node_put(cn);
  40207. + return ret;
  40208. +}
  40209. +
  40210. +static void __init parse_dt_cpu_power(void)
  40211. +{
  40212. + const struct cpu_efficiency *cpu_eff;
  40213. + struct device_node *cn;
  40214. + unsigned long min_capacity = ULONG_MAX;
  40215. + unsigned long max_capacity = 0;
  40216. + unsigned long capacity = 0;
  40217. + int cpu;
  40218. +
  40219. + __cpu_capacity = kcalloc(nr_cpu_ids, sizeof(*__cpu_capacity),
  40220. + GFP_NOWAIT);
  40221. +
  40222. + for_each_possible_cpu(cpu) {
  40223. + const u32 *rate;
  40224. + int len;
  40225. +
  40226. + /* Too early to use cpu->of_node */
  40227. + cn = of_get_cpu_node(cpu, NULL);
  40228. + if (!cn) {
  40229. + pr_err("Missing device node for CPU %d\n", cpu);
  40230. + continue;
  40231. + }
  40232. +
  40233. + for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
  40234. + if (of_device_is_compatible(cn, cpu_eff->compatible))
  40235. + break;
  40236. +
  40237. + if (cpu_eff->compatible == NULL) {
  40238. + pr_warn("%s: Unknown CPU type\n", cn->full_name);
  40239. + continue;
  40240. + }
  40241. +
  40242. + rate = of_get_property(cn, "clock-frequency", &len);
  40243. + if (!rate || len != 4) {
  40244. + pr_err("%s: Missing clock-frequency property\n",
  40245. + cn->full_name);
  40246. + continue;
  40247. + }
  40248. +
  40249. + capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
  40250. +
  40251. + /* Save min capacity of the system */
  40252. + if (capacity < min_capacity)
  40253. + min_capacity = capacity;
  40254. +
  40255. + /* Save max capacity of the system */
  40256. + if (capacity > max_capacity)
  40257. + max_capacity = capacity;
  40258. +
  40259. + cpu_capacity(cpu) = capacity;
  40260. + }
  40261. +
  40262. + /* If min and max capacities are equal we bypass the update of the
  40263. + * cpu_scale because all CPUs have the same capacity. Otherwise, we
  40264. + * compute a middle_capacity factor that will ensure that the capacity
  40265. + * of an 'average' CPU of the system will be as close as possible to
  40266. + * SCHED_POWER_SCALE, which is the default value, but with the
  40267. + * constraint explained near table_efficiency[].
  40268. + */
  40269. + if (min_capacity == max_capacity)
  40270. + return;
  40271. + else if (4 * max_capacity < (3 * (max_capacity + min_capacity)))
  40272. + middle_capacity = (min_capacity + max_capacity)
  40273. + >> (SCHED_POWER_SHIFT+1);
  40274. + else
  40275. + middle_capacity = ((max_capacity / 3)
  40276. + >> (SCHED_POWER_SHIFT-1)) + 1;
  40277. +}
  40278. +
  40279. +/*
  40280. + * Look for a customed capacity of a CPU in the cpu_topo_data table during the
  40281. + * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
  40282. + * function returns directly for SMP system.
  40283. + */
  40284. +static void update_cpu_power(unsigned int cpu)
  40285. +{
  40286. + if (!cpu_capacity(cpu))
  40287. + return;
  40288. +
  40289. + set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity);
  40290. +
  40291. + pr_info("CPU%u: update cpu_power %lu\n",
  40292. + cpu, arch_scale_freq_power(NULL, cpu));
  40293. +}
  40294. +
  40295. +/*
  40296. + * cpu topology table
  40297. + */
  40298. +struct cpu_topology cpu_topology[NR_CPUS];
  40299. +EXPORT_SYMBOL_GPL(cpu_topology);
  40300. +
  40301. +const struct cpumask *cpu_coregroup_mask(int cpu)
  40302. +{
  40303. + return &cpu_topology[cpu].core_sibling;
  40304. +}
  40305. +
  40306. +static void update_siblings_masks(unsigned int cpuid)
  40307. +{
  40308. + struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
  40309. + int cpu;
  40310. +
  40311. + if (cpuid_topo->cluster_id == -1) {
  40312. + /*
  40313. + * DT does not contain topology information for this cpu.
  40314. + */
  40315. + pr_debug("CPU%u: No topology information configured\n", cpuid);
  40316. + return;
  40317. + }
  40318. +
  40319. + /* update core and thread sibling masks */
  40320. + for_each_possible_cpu(cpu) {
  40321. + cpu_topo = &cpu_topology[cpu];
  40322. +
  40323. + if (cpuid_topo->cluster_id != cpu_topo->cluster_id)
  40324. + continue;
  40325. +
  40326. + cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
  40327. + if (cpu != cpuid)
  40328. + cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
  40329. +
  40330. + if (cpuid_topo->core_id != cpu_topo->core_id)
  40331. + continue;
  40332. +
  40333. + cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
  40334. + if (cpu != cpuid)
  40335. + cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
  40336. + }
  40337. +}
  40338. +
  40339. +void store_cpu_topology(unsigned int cpuid)
  40340. +{
  40341. + update_siblings_masks(cpuid);
  40342. + update_cpu_power(cpuid);
  40343. +}
  40344. +
  40345. +#ifdef CONFIG_SCHED_HMP
  40346. +
  40347. +/*
  40348. + * Retrieve logical cpu index corresponding to a given MPIDR[23:0]
  40349. + * - mpidr: MPIDR[23:0] to be used for the look-up
  40350. + *
  40351. + * Returns the cpu logical index or -EINVAL on look-up error
  40352. + */
  40353. +static inline int get_logical_index(u32 mpidr)
  40354. +{
  40355. + int cpu;
  40356. + for (cpu = 0; cpu < nr_cpu_ids; cpu++)
  40357. + if (cpu_logical_map(cpu) == mpidr)
  40358. + return cpu;
  40359. + return -EINVAL;
  40360. +}
  40361. +
  40362. +static const char * const little_cores[] = {
  40363. + "arm,cortex-a53",
  40364. + NULL,
  40365. +};
  40366. +
  40367. +static bool is_little_cpu(struct device_node *cn)
  40368. +{
  40369. + const char * const *lc;
  40370. + for (lc = little_cores; *lc; lc++)
  40371. + if (of_device_is_compatible(cn, *lc))
  40372. + return true;
  40373. + return false;
  40374. +}
  40375. +
  40376. +void __init arch_get_fast_and_slow_cpus(struct cpumask *fast,
  40377. + struct cpumask *slow)
  40378. +{
  40379. + struct device_node *cn = NULL;
  40380. + int cpu;
  40381. +
  40382. + cpumask_clear(fast);
  40383. + cpumask_clear(slow);
  40384. +
  40385. + /*
  40386. + * Use the config options if they are given. This helps testing
  40387. + * HMP scheduling on systems without a big.LITTLE architecture.
  40388. + */
  40389. + if (strlen(CONFIG_HMP_FAST_CPU_MASK) && strlen(CONFIG_HMP_SLOW_CPU_MASK)) {
  40390. + if (cpulist_parse(CONFIG_HMP_FAST_CPU_MASK, fast))
  40391. + WARN(1, "Failed to parse HMP fast cpu mask!\n");
  40392. + if (cpulist_parse(CONFIG_HMP_SLOW_CPU_MASK, slow))
  40393. + WARN(1, "Failed to parse HMP slow cpu mask!\n");
  40394. + return;
  40395. + }
  40396. +
  40397. + /*
  40398. + * Else, parse device tree for little cores.
  40399. + */
  40400. + while ((cn = of_find_node_by_type(cn, "cpu"))) {
  40401. +
  40402. + const u32 *mpidr;
  40403. + int len;
  40404. +
  40405. + mpidr = of_get_property(cn, "reg", &len);
  40406. + if (!mpidr || len != 8) {
  40407. + pr_err("%s missing reg property\n", cn->full_name);
  40408. + continue;
  40409. + }
  40410. +
  40411. + cpu = get_logical_index(be32_to_cpup(mpidr+1));
  40412. + if (cpu == -EINVAL) {
  40413. + pr_err("couldn't get logical index for mpidr %x\n",
  40414. + be32_to_cpup(mpidr+1));
  40415. + break;
  40416. + }
  40417. +
  40418. + if (is_little_cpu(cn))
  40419. + cpumask_set_cpu(cpu, slow);
  40420. + else
  40421. + cpumask_set_cpu(cpu, fast);
  40422. + }
  40423. +
  40424. + if (!cpumask_empty(fast) && !cpumask_empty(slow))
  40425. + return;
  40426. +
  40427. + /*
  40428. + * We didn't find both big and little cores so let's call all cores
  40429. + * fast as this will keep the system running, with all cores being
  40430. + * treated equal.
  40431. + */
  40432. + cpumask_setall(fast);
  40433. + cpumask_clear(slow);
  40434. +}
  40435. +
  40436. +struct cpumask hmp_slow_cpu_mask;
  40437. +
  40438. +void __init arch_get_hmp_domains(struct list_head *hmp_domains_list)
  40439. +{
  40440. + struct cpumask hmp_fast_cpu_mask;
  40441. + struct hmp_domain *domain;
  40442. +
  40443. + arch_get_fast_and_slow_cpus(&hmp_fast_cpu_mask, &hmp_slow_cpu_mask);
  40444. +
  40445. + /*
  40446. + * Initialize hmp_domains
  40447. + * Must be ordered with respect to compute capacity.
  40448. + * Fastest domain at head of list.
  40449. + */
  40450. + if(!cpumask_empty(&hmp_slow_cpu_mask)) {
  40451. + domain = (struct hmp_domain *)
  40452. + kmalloc(sizeof(struct hmp_domain), GFP_KERNEL);
  40453. + cpumask_copy(&domain->possible_cpus, &hmp_slow_cpu_mask);
  40454. + cpumask_and(&domain->cpus, cpu_online_mask, &domain->possible_cpus);
  40455. + list_add(&domain->hmp_domains, hmp_domains_list);
  40456. + }
  40457. + domain = (struct hmp_domain *)
  40458. + kmalloc(sizeof(struct hmp_domain), GFP_KERNEL);
  40459. + cpumask_copy(&domain->possible_cpus, &hmp_fast_cpu_mask);
  40460. + cpumask_and(&domain->cpus, cpu_online_mask, &domain->possible_cpus);
  40461. + list_add(&domain->hmp_domains, hmp_domains_list);
  40462. +}
  40463. +#endif /* CONFIG_SCHED_HMP */
  40464. +
  40465. +static void __init reset_cpu_topology(void)
  40466. +{
  40467. + unsigned int cpu;
  40468. +
  40469. + for_each_possible_cpu(cpu) {
  40470. + struct cpu_topology *cpu_topo = &cpu_topology[cpu];
  40471. +
  40472. + cpu_topo->thread_id = -1;
  40473. + cpu_topo->core_id = 0;
  40474. + cpu_topo->cluster_id = -1;
  40475. +
  40476. + cpumask_clear(&cpu_topo->core_sibling);
  40477. + cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
  40478. + cpumask_clear(&cpu_topo->thread_sibling);
  40479. + cpumask_set_cpu(cpu, &cpu_topo->thread_sibling);
  40480. + }
  40481. +}
  40482. +
  40483. +static void __init reset_cpu_power(void)
  40484. +{
  40485. + unsigned int cpu;
  40486. +
  40487. + for_each_possible_cpu(cpu)
  40488. + set_power_scale(cpu, SCHED_POWER_SCALE);
  40489. +}
  40490. +
  40491. +void __init init_cpu_topology(void)
  40492. +{
  40493. + reset_cpu_topology();
  40494. +
  40495. + /*
  40496. + * Discard anything that was parsed if we hit an error so we
  40497. + * don't use partial information.
  40498. + */
  40499. + if (parse_dt_topology())
  40500. + reset_cpu_topology();
  40501. +
  40502. + reset_cpu_power();
  40503. + parse_dt_cpu_power();
  40504. +}
  40505. diff -Nur linux-3.14.14/arch/arm64/kernel/vdso/Makefile linux-imx6-3.14/arch/arm64/kernel/vdso/Makefile
  40506. --- linux-3.14.14/arch/arm64/kernel/vdso/Makefile 2014-07-28 10:07:25.000000000 -0500
  40507. +++ linux-imx6-3.14/arch/arm64/kernel/vdso/Makefile 2014-12-08 00:31:51.420418001 -0600
  40508. @@ -47,9 +47,9 @@
  40509. $(call if_changed_dep,vdsoas)
  40510. # Actual build commands
  40511. -quiet_cmd_vdsold = VDSOL $@
  40512. +quiet_cmd_vdsold = VDSOL $@
  40513. cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@
  40514. -quiet_cmd_vdsoas = VDSOA $@
  40515. +quiet_cmd_vdsoas = VDSOA $@
  40516. cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
  40517. # Install commands for the unstripped file
  40518. diff -Nur linux-3.14.14/arch/arm64/kernel/vdso.c linux-imx6-3.14/arch/arm64/kernel/vdso.c
  40519. --- linux-3.14.14/arch/arm64/kernel/vdso.c 2014-07-28 10:07:25.000000000 -0500
  40520. +++ linux-imx6-3.14/arch/arm64/kernel/vdso.c 2014-12-08 00:31:51.420418001 -0600
  40521. @@ -156,11 +156,12 @@
  40522. int uses_interp)
  40523. {
  40524. struct mm_struct *mm = current->mm;
  40525. - unsigned long vdso_base, vdso_mapping_len;
  40526. + unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
  40527. int ret;
  40528. + vdso_text_len = vdso_pages << PAGE_SHIFT;
  40529. /* Be sure to map the data page */
  40530. - vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
  40531. + vdso_mapping_len = vdso_text_len + PAGE_SIZE;
  40532. down_write(&mm->mmap_sem);
  40533. vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
  40534. @@ -170,35 +171,52 @@
  40535. }
  40536. mm->context.vdso = (void *)vdso_base;
  40537. - ret = install_special_mapping(mm, vdso_base, vdso_mapping_len,
  40538. + ret = install_special_mapping(mm, vdso_base, vdso_text_len,
  40539. VM_READ|VM_EXEC|
  40540. VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
  40541. vdso_pagelist);
  40542. - if (ret) {
  40543. - mm->context.vdso = NULL;
  40544. + if (ret)
  40545. + goto up_fail;
  40546. +
  40547. + vdso_base += vdso_text_len;
  40548. + ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
  40549. + VM_READ|VM_MAYREAD,
  40550. + vdso_pagelist + vdso_pages);
  40551. + if (ret)
  40552. goto up_fail;
  40553. - }
  40554. -up_fail:
  40555. up_write(&mm->mmap_sem);
  40556. + return 0;
  40557. +up_fail:
  40558. + mm->context.vdso = NULL;
  40559. + up_write(&mm->mmap_sem);
  40560. return ret;
  40561. }
  40562. const char *arch_vma_name(struct vm_area_struct *vma)
  40563. {
  40564. + unsigned long vdso_text;
  40565. +
  40566. + if (!vma->vm_mm)
  40567. + return NULL;
  40568. +
  40569. + vdso_text = (unsigned long)vma->vm_mm->context.vdso;
  40570. +
  40571. /*
  40572. * We can re-use the vdso pointer in mm_context_t for identifying
  40573. * the vectors page for compat applications. The vDSO will always
  40574. * sit above TASK_UNMAPPED_BASE and so we don't need to worry about
  40575. * it conflicting with the vectors base.
  40576. */
  40577. - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) {
  40578. + if (vma->vm_start == vdso_text) {
  40579. #ifdef CONFIG_COMPAT
  40580. if (vma->vm_start == AARCH32_VECTORS_BASE)
  40581. return "[vectors]";
  40582. #endif
  40583. return "[vdso]";
  40584. + } else if (vma->vm_start == (vdso_text + (vdso_pages << PAGE_SHIFT))) {
  40585. + return "[vvar]";
  40586. }
  40587. return NULL;
  40588. diff -Nur linux-3.14.14/arch/arm64/kernel/vmlinux.lds.S linux-imx6-3.14/arch/arm64/kernel/vmlinux.lds.S
  40589. --- linux-3.14.14/arch/arm64/kernel/vmlinux.lds.S 2014-07-28 10:07:25.000000000 -0500
  40590. +++ linux-imx6-3.14/arch/arm64/kernel/vmlinux.lds.S 2014-12-08 00:31:51.420418001 -0600
  40591. @@ -104,6 +104,13 @@
  40592. _edata = .;
  40593. BSS_SECTION(0, 0, 0)
  40594. +
  40595. + . = ALIGN(PAGE_SIZE);
  40596. + idmap_pg_dir = .;
  40597. + . += IDMAP_DIR_SIZE;
  40598. + swapper_pg_dir = .;
  40599. + . += SWAPPER_DIR_SIZE;
  40600. +
  40601. _end = .;
  40602. STABS_DEBUG
  40603. diff -Nur linux-3.14.14/arch/arm64/Makefile linux-imx6-3.14/arch/arm64/Makefile
  40604. --- linux-3.14.14/arch/arm64/Makefile 2014-07-28 10:07:25.000000000 -0500
  40605. +++ linux-imx6-3.14/arch/arm64/Makefile 2014-12-08 00:31:51.408418001 -0600
  40606. @@ -45,6 +45,7 @@
  40607. core-y += arch/arm64/kernel/ arch/arm64/mm/
  40608. core-$(CONFIG_KVM) += arch/arm64/kvm/
  40609. core-$(CONFIG_XEN) += arch/arm64/xen/
  40610. +core-$(CONFIG_CRYPTO) += arch/arm64/crypto/
  40611. libs-y := arch/arm64/lib/ $(libs-y)
  40612. libs-y += $(LIBGCC)
  40613. diff -Nur linux-3.14.14/arch/arm64/mm/cache.S linux-imx6-3.14/arch/arm64/mm/cache.S
  40614. --- linux-3.14.14/arch/arm64/mm/cache.S 2014-07-28 10:07:25.000000000 -0500
  40615. +++ linux-imx6-3.14/arch/arm64/mm/cache.S 2014-12-08 00:31:51.424418001 -0600
  40616. @@ -30,7 +30,7 @@
  40617. *
  40618. * Corrupted registers: x0-x7, x9-x11
  40619. */
  40620. -ENTRY(__flush_dcache_all)
  40621. +__flush_dcache_all:
  40622. dsb sy // ensure ordering with previous memory accesses
  40623. mrs x0, clidr_el1 // read clidr
  40624. and x3, x0, #0x7000000 // extract loc from clidr
  40625. @@ -166,3 +166,97 @@
  40626. dsb sy
  40627. ret
  40628. ENDPROC(__flush_dcache_area)
  40629. +
  40630. +/*
  40631. + * __inval_cache_range(start, end)
  40632. + * - start - start address of region
  40633. + * - end - end address of region
  40634. + */
  40635. +ENTRY(__inval_cache_range)
  40636. + /* FALLTHROUGH */
  40637. +
  40638. +/*
  40639. + * __dma_inv_range(start, end)
  40640. + * - start - virtual start address of region
  40641. + * - end - virtual end address of region
  40642. + */
  40643. +__dma_inv_range:
  40644. + dcache_line_size x2, x3
  40645. + sub x3, x2, #1
  40646. + tst x1, x3 // end cache line aligned?
  40647. + bic x1, x1, x3
  40648. + b.eq 1f
  40649. + dc civac, x1 // clean & invalidate D / U line
  40650. +1: tst x0, x3 // start cache line aligned?
  40651. + bic x0, x0, x3
  40652. + b.eq 2f
  40653. + dc civac, x0 // clean & invalidate D / U line
  40654. + b 3f
  40655. +2: dc ivac, x0 // invalidate D / U line
  40656. +3: add x0, x0, x2
  40657. + cmp x0, x1
  40658. + b.lo 2b
  40659. + dsb sy
  40660. + ret
  40661. +ENDPROC(__inval_cache_range)
  40662. +ENDPROC(__dma_inv_range)
  40663. +
  40664. +/*
  40665. + * __dma_clean_range(start, end)
  40666. + * - start - virtual start address of region
  40667. + * - end - virtual end address of region
  40668. + */
  40669. +__dma_clean_range:
  40670. + dcache_line_size x2, x3
  40671. + sub x3, x2, #1
  40672. + bic x0, x0, x3
  40673. +1: dc cvac, x0 // clean D / U line
  40674. + add x0, x0, x2
  40675. + cmp x0, x1
  40676. + b.lo 1b
  40677. + dsb sy
  40678. + ret
  40679. +ENDPROC(__dma_clean_range)
  40680. +
  40681. +/*
  40682. + * __dma_flush_range(start, end)
  40683. + * - start - virtual start address of region
  40684. + * - end - virtual end address of region
  40685. + */
  40686. +ENTRY(__dma_flush_range)
  40687. + dcache_line_size x2, x3
  40688. + sub x3, x2, #1
  40689. + bic x0, x0, x3
  40690. +1: dc civac, x0 // clean & invalidate D / U line
  40691. + add x0, x0, x2
  40692. + cmp x0, x1
  40693. + b.lo 1b
  40694. + dsb sy
  40695. + ret
  40696. +ENDPROC(__dma_flush_range)
  40697. +
  40698. +/*
  40699. + * __dma_map_area(start, size, dir)
  40700. + * - start - kernel virtual start address
  40701. + * - size - size of region
  40702. + * - dir - DMA direction
  40703. + */
  40704. +ENTRY(__dma_map_area)
  40705. + add x1, x1, x0
  40706. + cmp w2, #DMA_FROM_DEVICE
  40707. + b.eq __dma_inv_range
  40708. + b __dma_clean_range
  40709. +ENDPROC(__dma_map_area)
  40710. +
  40711. +/*
  40712. + * __dma_unmap_area(start, size, dir)
  40713. + * - start - kernel virtual start address
  40714. + * - size - size of region
  40715. + * - dir - DMA direction
  40716. + */
  40717. +ENTRY(__dma_unmap_area)
  40718. + add x1, x1, x0
  40719. + cmp w2, #DMA_TO_DEVICE
  40720. + b.ne __dma_inv_range
  40721. + ret
  40722. +ENDPROC(__dma_unmap_area)
  40723. diff -Nur linux-3.14.14/arch/arm64/mm/copypage.c linux-imx6-3.14/arch/arm64/mm/copypage.c
  40724. --- linux-3.14.14/arch/arm64/mm/copypage.c 2014-07-28 10:07:25.000000000 -0500
  40725. +++ linux-imx6-3.14/arch/arm64/mm/copypage.c 2014-12-08 00:31:51.424418001 -0600
  40726. @@ -27,8 +27,10 @@
  40727. copy_page(kto, kfrom);
  40728. __flush_dcache_area(kto, PAGE_SIZE);
  40729. }
  40730. +EXPORT_SYMBOL_GPL(__cpu_copy_user_page);
  40731. void __cpu_clear_user_page(void *kaddr, unsigned long vaddr)
  40732. {
  40733. clear_page(kaddr);
  40734. }
  40735. +EXPORT_SYMBOL_GPL(__cpu_clear_user_page);
  40736. diff -Nur linux-3.14.14/arch/arm64/mm/dma-mapping.c linux-imx6-3.14/arch/arm64/mm/dma-mapping.c
  40737. --- linux-3.14.14/arch/arm64/mm/dma-mapping.c 2014-07-28 10:07:25.000000000 -0500
  40738. +++ linux-imx6-3.14/arch/arm64/mm/dma-mapping.c 2014-12-08 00:31:51.424418001 -0600
  40739. @@ -22,26 +22,39 @@
  40740. #include <linux/slab.h>
  40741. #include <linux/dma-mapping.h>
  40742. #include <linux/dma-contiguous.h>
  40743. +#include <linux/of.h>
  40744. +#include <linux/platform_device.h>
  40745. #include <linux/vmalloc.h>
  40746. #include <linux/swiotlb.h>
  40747. +#include <linux/amba/bus.h>
  40748. #include <asm/cacheflush.h>
  40749. struct dma_map_ops *dma_ops;
  40750. EXPORT_SYMBOL(dma_ops);
  40751. -static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size,
  40752. - dma_addr_t *dma_handle, gfp_t flags,
  40753. - struct dma_attrs *attrs)
  40754. +static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
  40755. + bool coherent)
  40756. +{
  40757. + if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
  40758. + return pgprot_writecombine(prot);
  40759. + else if (!coherent)
  40760. + return pgprot_dmacoherent(prot);
  40761. + return prot;
  40762. +}
  40763. +
  40764. +static void *__dma_alloc_coherent(struct device *dev, size_t size,
  40765. + dma_addr_t *dma_handle, gfp_t flags,
  40766. + struct dma_attrs *attrs)
  40767. {
  40768. if (dev == NULL) {
  40769. WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
  40770. return NULL;
  40771. }
  40772. - if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
  40773. + if (IS_ENABLED(CONFIG_ZONE_DMA) &&
  40774. dev->coherent_dma_mask <= DMA_BIT_MASK(32))
  40775. - flags |= GFP_DMA32;
  40776. + flags |= GFP_DMA;
  40777. if (IS_ENABLED(CONFIG_DMA_CMA)) {
  40778. struct page *page;
  40779. @@ -58,9 +71,9 @@
  40780. }
  40781. }
  40782. -static void arm64_swiotlb_free_coherent(struct device *dev, size_t size,
  40783. - void *vaddr, dma_addr_t dma_handle,
  40784. - struct dma_attrs *attrs)
  40785. +static void __dma_free_coherent(struct device *dev, size_t size,
  40786. + void *vaddr, dma_addr_t dma_handle,
  40787. + struct dma_attrs *attrs)
  40788. {
  40789. if (dev == NULL) {
  40790. WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
  40791. @@ -78,9 +91,212 @@
  40792. }
  40793. }
  40794. -static struct dma_map_ops arm64_swiotlb_dma_ops = {
  40795. - .alloc = arm64_swiotlb_alloc_coherent,
  40796. - .free = arm64_swiotlb_free_coherent,
  40797. +static void *__dma_alloc_noncoherent(struct device *dev, size_t size,
  40798. + dma_addr_t *dma_handle, gfp_t flags,
  40799. + struct dma_attrs *attrs)
  40800. +{
  40801. + struct page *page, **map;
  40802. + void *ptr, *coherent_ptr;
  40803. + int order, i;
  40804. +
  40805. + size = PAGE_ALIGN(size);
  40806. + order = get_order(size);
  40807. +
  40808. + ptr = __dma_alloc_coherent(dev, size, dma_handle, flags, attrs);
  40809. + if (!ptr)
  40810. + goto no_mem;
  40811. + map = kmalloc(sizeof(struct page *) << order, flags & ~GFP_DMA);
  40812. + if (!map)
  40813. + goto no_map;
  40814. +
  40815. + /* remove any dirty cache lines on the kernel alias */
  40816. + __dma_flush_range(ptr, ptr + size);
  40817. +
  40818. + /* create a coherent mapping */
  40819. + page = virt_to_page(ptr);
  40820. + for (i = 0; i < (size >> PAGE_SHIFT); i++)
  40821. + map[i] = page + i;
  40822. + coherent_ptr = vmap(map, size >> PAGE_SHIFT, VM_MAP,
  40823. + __get_dma_pgprot(attrs, pgprot_default, false));
  40824. + kfree(map);
  40825. + if (!coherent_ptr)
  40826. + goto no_map;
  40827. +
  40828. + return coherent_ptr;
  40829. +
  40830. +no_map:
  40831. + __dma_free_coherent(dev, size, ptr, *dma_handle, attrs);
  40832. +no_mem:
  40833. + *dma_handle = ~0;
  40834. + return NULL;
  40835. +}
  40836. +
  40837. +static void __dma_free_noncoherent(struct device *dev, size_t size,
  40838. + void *vaddr, dma_addr_t dma_handle,
  40839. + struct dma_attrs *attrs)
  40840. +{
  40841. + void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
  40842. +
  40843. + vunmap(vaddr);
  40844. + __dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
  40845. +}
  40846. +
  40847. +static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
  40848. + unsigned long offset, size_t size,
  40849. + enum dma_data_direction dir,
  40850. + struct dma_attrs *attrs)
  40851. +{
  40852. + dma_addr_t dev_addr;
  40853. +
  40854. + dev_addr = swiotlb_map_page(dev, page, offset, size, dir, attrs);
  40855. + __dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40856. +
  40857. + return dev_addr;
  40858. +}
  40859. +
  40860. +
  40861. +static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
  40862. + size_t size, enum dma_data_direction dir,
  40863. + struct dma_attrs *attrs)
  40864. +{
  40865. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40866. + swiotlb_unmap_page(dev, dev_addr, size, dir, attrs);
  40867. +}
  40868. +
  40869. +static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
  40870. + int nelems, enum dma_data_direction dir,
  40871. + struct dma_attrs *attrs)
  40872. +{
  40873. + struct scatterlist *sg;
  40874. + int i, ret;
  40875. +
  40876. + ret = swiotlb_map_sg_attrs(dev, sgl, nelems, dir, attrs);
  40877. + for_each_sg(sgl, sg, ret, i)
  40878. + __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  40879. + sg->length, dir);
  40880. +
  40881. + return ret;
  40882. +}
  40883. +
  40884. +static void __swiotlb_unmap_sg_attrs(struct device *dev,
  40885. + struct scatterlist *sgl, int nelems,
  40886. + enum dma_data_direction dir,
  40887. + struct dma_attrs *attrs)
  40888. +{
  40889. + struct scatterlist *sg;
  40890. + int i;
  40891. +
  40892. + for_each_sg(sgl, sg, nelems, i)
  40893. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  40894. + sg->length, dir);
  40895. + swiotlb_unmap_sg_attrs(dev, sgl, nelems, dir, attrs);
  40896. +}
  40897. +
  40898. +static void __swiotlb_sync_single_for_cpu(struct device *dev,
  40899. + dma_addr_t dev_addr, size_t size,
  40900. + enum dma_data_direction dir)
  40901. +{
  40902. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40903. + swiotlb_sync_single_for_cpu(dev, dev_addr, size, dir);
  40904. +}
  40905. +
  40906. +static void __swiotlb_sync_single_for_device(struct device *dev,
  40907. + dma_addr_t dev_addr, size_t size,
  40908. + enum dma_data_direction dir)
  40909. +{
  40910. + swiotlb_sync_single_for_device(dev, dev_addr, size, dir);
  40911. + __dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40912. +}
  40913. +
  40914. +static void __swiotlb_sync_sg_for_cpu(struct device *dev,
  40915. + struct scatterlist *sgl, int nelems,
  40916. + enum dma_data_direction dir)
  40917. +{
  40918. + struct scatterlist *sg;
  40919. + int i;
  40920. +
  40921. + for_each_sg(sgl, sg, nelems, i)
  40922. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  40923. + sg->length, dir);
  40924. + swiotlb_sync_sg_for_cpu(dev, sgl, nelems, dir);
  40925. +}
  40926. +
  40927. +static void __swiotlb_sync_sg_for_device(struct device *dev,
  40928. + struct scatterlist *sgl, int nelems,
  40929. + enum dma_data_direction dir)
  40930. +{
  40931. + struct scatterlist *sg;
  40932. + int i;
  40933. +
  40934. + swiotlb_sync_sg_for_device(dev, sgl, nelems, dir);
  40935. + for_each_sg(sgl, sg, nelems, i)
  40936. + __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  40937. + sg->length, dir);
  40938. +}
  40939. +
  40940. +/* vma->vm_page_prot must be set appropriately before calling this function */
  40941. +static int __dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
  40942. + void *cpu_addr, dma_addr_t dma_addr, size_t size)
  40943. +{
  40944. + int ret = -ENXIO;
  40945. + unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >>
  40946. + PAGE_SHIFT;
  40947. + unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
  40948. + unsigned long pfn = dma_to_phys(dev, dma_addr) >> PAGE_SHIFT;
  40949. + unsigned long off = vma->vm_pgoff;
  40950. +
  40951. + if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
  40952. + return ret;
  40953. +
  40954. + if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) {
  40955. + ret = remap_pfn_range(vma, vma->vm_start,
  40956. + pfn + off,
  40957. + vma->vm_end - vma->vm_start,
  40958. + vma->vm_page_prot);
  40959. + }
  40960. +
  40961. + return ret;
  40962. +}
  40963. +
  40964. +static int __swiotlb_mmap_noncoherent(struct device *dev,
  40965. + struct vm_area_struct *vma,
  40966. + void *cpu_addr, dma_addr_t dma_addr, size_t size,
  40967. + struct dma_attrs *attrs)
  40968. +{
  40969. + vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, false);
  40970. + return __dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
  40971. +}
  40972. +
  40973. +static int __swiotlb_mmap_coherent(struct device *dev,
  40974. + struct vm_area_struct *vma,
  40975. + void *cpu_addr, dma_addr_t dma_addr, size_t size,
  40976. + struct dma_attrs *attrs)
  40977. +{
  40978. + /* Just use whatever page_prot attributes were specified */
  40979. + return __dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
  40980. +}
  40981. +
  40982. +struct dma_map_ops noncoherent_swiotlb_dma_ops = {
  40983. + .alloc = __dma_alloc_noncoherent,
  40984. + .free = __dma_free_noncoherent,
  40985. + .mmap = __swiotlb_mmap_noncoherent,
  40986. + .map_page = __swiotlb_map_page,
  40987. + .unmap_page = __swiotlb_unmap_page,
  40988. + .map_sg = __swiotlb_map_sg_attrs,
  40989. + .unmap_sg = __swiotlb_unmap_sg_attrs,
  40990. + .sync_single_for_cpu = __swiotlb_sync_single_for_cpu,
  40991. + .sync_single_for_device = __swiotlb_sync_single_for_device,
  40992. + .sync_sg_for_cpu = __swiotlb_sync_sg_for_cpu,
  40993. + .sync_sg_for_device = __swiotlb_sync_sg_for_device,
  40994. + .dma_supported = swiotlb_dma_supported,
  40995. + .mapping_error = swiotlb_dma_mapping_error,
  40996. +};
  40997. +EXPORT_SYMBOL(noncoherent_swiotlb_dma_ops);
  40998. +
  40999. +struct dma_map_ops coherent_swiotlb_dma_ops = {
  41000. + .alloc = __dma_alloc_coherent,
  41001. + .free = __dma_free_coherent,
  41002. + .mmap = __swiotlb_mmap_coherent,
  41003. .map_page = swiotlb_map_page,
  41004. .unmap_page = swiotlb_unmap_page,
  41005. .map_sg = swiotlb_map_sg_attrs,
  41006. @@ -92,12 +308,47 @@
  41007. .dma_supported = swiotlb_dma_supported,
  41008. .mapping_error = swiotlb_dma_mapping_error,
  41009. };
  41010. +EXPORT_SYMBOL(coherent_swiotlb_dma_ops);
  41011. -void __init arm64_swiotlb_init(void)
  41012. +static int dma_bus_notifier(struct notifier_block *nb,
  41013. + unsigned long event, void *_dev)
  41014. {
  41015. - dma_ops = &arm64_swiotlb_dma_ops;
  41016. - swiotlb_init(1);
  41017. + struct device *dev = _dev;
  41018. +
  41019. + if (event != BUS_NOTIFY_ADD_DEVICE)
  41020. + return NOTIFY_DONE;
  41021. +
  41022. + if (of_property_read_bool(dev->of_node, "dma-coherent"))
  41023. + set_dma_ops(dev, &coherent_swiotlb_dma_ops);
  41024. +
  41025. + return NOTIFY_OK;
  41026. +}
  41027. +
  41028. +static struct notifier_block platform_bus_nb = {
  41029. + .notifier_call = dma_bus_notifier,
  41030. +};
  41031. +
  41032. +static struct notifier_block amba_bus_nb = {
  41033. + .notifier_call = dma_bus_notifier,
  41034. +};
  41035. +
  41036. +extern int swiotlb_late_init_with_default_size(size_t default_size);
  41037. +
  41038. +static int __init swiotlb_late_init(void)
  41039. +{
  41040. + size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT);
  41041. +
  41042. + /*
  41043. + * These must be registered before of_platform_populate().
  41044. + */
  41045. + bus_register_notifier(&platform_bus_type, &platform_bus_nb);
  41046. + bus_register_notifier(&amba_bustype, &amba_bus_nb);
  41047. +
  41048. + dma_ops = &noncoherent_swiotlb_dma_ops;
  41049. +
  41050. + return swiotlb_late_init_with_default_size(swiotlb_size);
  41051. }
  41052. +arch_initcall(swiotlb_late_init);
  41053. #define PREALLOC_DMA_DEBUG_ENTRIES 4096
  41054. diff -Nur linux-3.14.14/arch/arm64/mm/init.c linux-imx6-3.14/arch/arm64/mm/init.c
  41055. --- linux-3.14.14/arch/arm64/mm/init.c 2014-07-28 10:07:25.000000000 -0500
  41056. +++ linux-imx6-3.14/arch/arm64/mm/init.c 2014-12-08 00:31:51.424418001 -0600
  41057. @@ -30,6 +30,7 @@
  41058. #include <linux/memblock.h>
  41059. #include <linux/sort.h>
  41060. #include <linux/of_fdt.h>
  41061. +#include <linux/dma-mapping.h>
  41062. #include <linux/dma-contiguous.h>
  41063. #include <asm/sections.h>
  41064. @@ -59,22 +60,22 @@
  41065. early_param("initrd", early_initrd);
  41066. #endif
  41067. -#define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT)
  41068. -
  41069. static void __init zone_sizes_init(unsigned long min, unsigned long max)
  41070. {
  41071. struct memblock_region *reg;
  41072. unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
  41073. - unsigned long max_dma32 = min;
  41074. + unsigned long max_dma = min;
  41075. memset(zone_size, 0, sizeof(zone_size));
  41076. -#ifdef CONFIG_ZONE_DMA32
  41077. /* 4GB maximum for 32-bit only capable devices */
  41078. - max_dma32 = max(min, min(max, MAX_DMA32_PFN));
  41079. - zone_size[ZONE_DMA32] = max_dma32 - min;
  41080. -#endif
  41081. - zone_size[ZONE_NORMAL] = max - max_dma32;
  41082. + if (IS_ENABLED(CONFIG_ZONE_DMA)) {
  41083. + unsigned long max_dma_phys =
  41084. + (unsigned long)dma_to_phys(NULL, DMA_BIT_MASK(32) + 1);
  41085. + max_dma = max(min, min(max, max_dma_phys >> PAGE_SHIFT));
  41086. + zone_size[ZONE_DMA] = max_dma - min;
  41087. + }
  41088. + zone_size[ZONE_NORMAL] = max - max_dma;
  41089. memcpy(zhole_size, zone_size, sizeof(zhole_size));
  41090. @@ -84,15 +85,15 @@
  41091. if (start >= max)
  41092. continue;
  41093. -#ifdef CONFIG_ZONE_DMA32
  41094. - if (start < max_dma32) {
  41095. - unsigned long dma_end = min(end, max_dma32);
  41096. - zhole_size[ZONE_DMA32] -= dma_end - start;
  41097. +
  41098. + if (IS_ENABLED(CONFIG_ZONE_DMA) && start < max_dma) {
  41099. + unsigned long dma_end = min(end, max_dma);
  41100. + zhole_size[ZONE_DMA] -= dma_end - start;
  41101. }
  41102. -#endif
  41103. - if (end > max_dma32) {
  41104. +
  41105. + if (end > max_dma) {
  41106. unsigned long normal_end = min(end, max);
  41107. - unsigned long normal_start = max(start, max_dma32);
  41108. + unsigned long normal_start = max(start, max_dma);
  41109. zhole_size[ZONE_NORMAL] -= normal_end - normal_start;
  41110. }
  41111. }
  41112. @@ -127,20 +128,16 @@
  41113. {
  41114. u64 *reserve_map, base, size;
  41115. - /* Register the kernel text, kernel data and initrd with memblock */
  41116. + /*
  41117. + * Register the kernel text, kernel data, initrd, and initial
  41118. + * pagetables with memblock.
  41119. + */
  41120. memblock_reserve(__pa(_text), _end - _text);
  41121. #ifdef CONFIG_BLK_DEV_INITRD
  41122. if (initrd_start)
  41123. memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
  41124. #endif
  41125. - /*
  41126. - * Reserve the page tables. These are already in use,
  41127. - * and can only be in node 0.
  41128. - */
  41129. - memblock_reserve(__pa(swapper_pg_dir), SWAPPER_DIR_SIZE);
  41130. - memblock_reserve(__pa(idmap_pg_dir), IDMAP_DIR_SIZE);
  41131. -
  41132. /* Reserve the dtb region */
  41133. memblock_reserve(virt_to_phys(initial_boot_params),
  41134. be32_to_cpu(initial_boot_params->totalsize));
  41135. @@ -261,8 +258,6 @@
  41136. */
  41137. void __init mem_init(void)
  41138. {
  41139. - arm64_swiotlb_init();
  41140. -
  41141. max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
  41142. #ifndef CONFIG_SPARSEMEM_VMEMMAP
  41143. diff -Nur linux-3.14.14/arch/arm64/mm/proc.S linux-imx6-3.14/arch/arm64/mm/proc.S
  41144. --- linux-3.14.14/arch/arm64/mm/proc.S 2014-07-28 10:07:25.000000000 -0500
  41145. +++ linux-imx6-3.14/arch/arm64/mm/proc.S 2014-12-08 00:31:51.424418001 -0600
  41146. @@ -173,12 +173,6 @@
  41147. * value of the SCTLR_EL1 register.
  41148. */
  41149. ENTRY(__cpu_setup)
  41150. - /*
  41151. - * Preserve the link register across the function call.
  41152. - */
  41153. - mov x28, lr
  41154. - bl __flush_dcache_all
  41155. - mov lr, x28
  41156. ic iallu // I+BTB cache invalidate
  41157. tlbi vmalle1is // invalidate I + D TLBs
  41158. dsb sy
  41159. diff -Nur linux-3.14.14/arch/avr32/kernel/cpu.c linux-imx6-3.14/arch/avr32/kernel/cpu.c
  41160. --- linux-3.14.14/arch/avr32/kernel/cpu.c 2014-07-28 10:07:25.000000000 -0500
  41161. +++ linux-imx6-3.14/arch/avr32/kernel/cpu.c 2014-12-08 00:31:51.432418001 -0600
  41162. @@ -39,10 +39,12 @@
  41163. size_t count)
  41164. {
  41165. unsigned long val;
  41166. - char *endp;
  41167. + int ret;
  41168. - val = simple_strtoul(buf, &endp, 0);
  41169. - if (endp == buf || val > 0x3f)
  41170. + ret = kstrtoul(buf, 0, &val);
  41171. + if (ret)
  41172. + return ret;
  41173. + if (val > 0x3f)
  41174. return -EINVAL;
  41175. val = (val << 12) | (sysreg_read(PCCR) & 0xfffc0fff);
  41176. sysreg_write(PCCR, val);
  41177. @@ -61,11 +63,11 @@
  41178. const char *buf, size_t count)
  41179. {
  41180. unsigned long val;
  41181. - char *endp;
  41182. + int ret;
  41183. - val = simple_strtoul(buf, &endp, 0);
  41184. - if (endp == buf)
  41185. - return -EINVAL;
  41186. + ret = kstrtoul(buf, 0, &val);
  41187. + if (ret)
  41188. + return ret;
  41189. sysreg_write(PCNT0, val);
  41190. return count;
  41191. @@ -84,10 +86,12 @@
  41192. size_t count)
  41193. {
  41194. unsigned long val;
  41195. - char *endp;
  41196. + int ret;
  41197. - val = simple_strtoul(buf, &endp, 0);
  41198. - if (endp == buf || val > 0x3f)
  41199. + ret = kstrtoul(buf, 0, &val);
  41200. + if (ret)
  41201. + return ret;
  41202. + if (val > 0x3f)
  41203. return -EINVAL;
  41204. val = (val << 18) | (sysreg_read(PCCR) & 0xff03ffff);
  41205. sysreg_write(PCCR, val);
  41206. @@ -106,11 +110,11 @@
  41207. size_t count)
  41208. {
  41209. unsigned long val;
  41210. - char *endp;
  41211. + int ret;
  41212. - val = simple_strtoul(buf, &endp, 0);
  41213. - if (endp == buf)
  41214. - return -EINVAL;
  41215. + ret = kstrtoul(buf, 0, &val);
  41216. + if (ret)
  41217. + return ret;
  41218. sysreg_write(PCNT1, val);
  41219. return count;
  41220. @@ -129,11 +133,11 @@
  41221. size_t count)
  41222. {
  41223. unsigned long val;
  41224. - char *endp;
  41225. + int ret;
  41226. - val = simple_strtoul(buf, &endp, 0);
  41227. - if (endp == buf)
  41228. - return -EINVAL;
  41229. + ret = kstrtoul(buf, 0, &val);
  41230. + if (ret)
  41231. + return ret;
  41232. sysreg_write(PCCNT, val);
  41233. return count;
  41234. @@ -152,11 +156,11 @@
  41235. size_t count)
  41236. {
  41237. unsigned long pccr, val;
  41238. - char *endp;
  41239. + int ret;
  41240. - val = simple_strtoul(buf, &endp, 0);
  41241. - if (endp == buf)
  41242. - return -EINVAL;
  41243. + ret = kstrtoul(buf, 0, &val);
  41244. + if (ret)
  41245. + return ret;
  41246. if (val)
  41247. val = 1;
  41248. diff -Nur linux-3.14.14/arch/blackfin/include/asm/ftrace.h linux-imx6-3.14/arch/blackfin/include/asm/ftrace.h
  41249. --- linux-3.14.14/arch/blackfin/include/asm/ftrace.h 2014-07-28 10:07:25.000000000 -0500
  41250. +++ linux-imx6-3.14/arch/blackfin/include/asm/ftrace.h 2014-12-08 00:31:51.440418001 -0600
  41251. @@ -66,16 +66,7 @@
  41252. #endif /* CONFIG_FRAME_POINTER */
  41253. -#define HAVE_ARCH_CALLER_ADDR
  41254. -
  41255. -/* inline function or macro may lead to unexpected result */
  41256. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  41257. -#define CALLER_ADDR1 ((unsigned long)return_address(1))
  41258. -#define CALLER_ADDR2 ((unsigned long)return_address(2))
  41259. -#define CALLER_ADDR3 ((unsigned long)return_address(3))
  41260. -#define CALLER_ADDR4 ((unsigned long)return_address(4))
  41261. -#define CALLER_ADDR5 ((unsigned long)return_address(5))
  41262. -#define CALLER_ADDR6 ((unsigned long)return_address(6))
  41263. +#define ftrace_return_address(n) return_address(n)
  41264. #endif /* __ASSEMBLY__ */
  41265. diff -Nur linux-3.14.14/arch/hexagon/include/asm/elf.h linux-imx6-3.14/arch/hexagon/include/asm/elf.h
  41266. --- linux-3.14.14/arch/hexagon/include/asm/elf.h 2014-07-28 10:07:25.000000000 -0500
  41267. +++ linux-imx6-3.14/arch/hexagon/include/asm/elf.h 2014-12-08 00:31:51.536418001 -0600
  41268. @@ -1,7 +1,7 @@
  41269. /*
  41270. * ELF definitions for the Hexagon architecture
  41271. *
  41272. - * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  41273. + * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  41274. *
  41275. * This program is free software; you can redistribute it and/or modify
  41276. * it under the terms of the GNU General Public License version 2 and
  41277. diff -Nur linux-3.14.14/arch/parisc/include/asm/ftrace.h linux-imx6-3.14/arch/parisc/include/asm/ftrace.h
  41278. --- linux-3.14.14/arch/parisc/include/asm/ftrace.h 2014-07-28 10:07:25.000000000 -0500
  41279. +++ linux-imx6-3.14/arch/parisc/include/asm/ftrace.h 2014-12-08 00:31:51.852418001 -0600
  41280. @@ -24,15 +24,7 @@
  41281. extern unsigned long return_address(unsigned int);
  41282. -#define HAVE_ARCH_CALLER_ADDR
  41283. -
  41284. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  41285. -#define CALLER_ADDR1 return_address(1)
  41286. -#define CALLER_ADDR2 return_address(2)
  41287. -#define CALLER_ADDR3 return_address(3)
  41288. -#define CALLER_ADDR4 return_address(4)
  41289. -#define CALLER_ADDR5 return_address(5)
  41290. -#define CALLER_ADDR6 return_address(6)
  41291. +#define ftrace_return_address(n) return_address(n)
  41292. #endif /* __ASSEMBLY__ */
  41293. diff -Nur linux-3.14.14/arch/s390/include/asm/cio.h linux-imx6-3.14/arch/s390/include/asm/cio.h
  41294. --- linux-3.14.14/arch/s390/include/asm/cio.h 2014-07-28 10:07:25.000000000 -0500
  41295. +++ linux-imx6-3.14/arch/s390/include/asm/cio.h 2014-12-08 00:31:52.040418001 -0600
  41296. @@ -199,7 +199,7 @@
  41297. /**
  41298. * struct irb - interruption response block
  41299. * @scsw: subchannel status word
  41300. - * @esw: extened status word
  41301. + * @esw: extended status word
  41302. * @ecw: extended control word
  41303. *
  41304. * The irb that is handed to the device driver when an interrupt occurs. For
  41305. diff -Nur linux-3.14.14/arch/sh/include/asm/ftrace.h linux-imx6-3.14/arch/sh/include/asm/ftrace.h
  41306. --- linux-3.14.14/arch/sh/include/asm/ftrace.h 2014-07-28 10:07:25.000000000 -0500
  41307. +++ linux-imx6-3.14/arch/sh/include/asm/ftrace.h 2014-12-08 00:31:52.108418001 -0600
  41308. @@ -40,15 +40,7 @@
  41309. /* arch/sh/kernel/return_address.c */
  41310. extern void *return_address(unsigned int);
  41311. -#define HAVE_ARCH_CALLER_ADDR
  41312. -
  41313. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  41314. -#define CALLER_ADDR1 ((unsigned long)return_address(1))
  41315. -#define CALLER_ADDR2 ((unsigned long)return_address(2))
  41316. -#define CALLER_ADDR3 ((unsigned long)return_address(3))
  41317. -#define CALLER_ADDR4 ((unsigned long)return_address(4))
  41318. -#define CALLER_ADDR5 ((unsigned long)return_address(5))
  41319. -#define CALLER_ADDR6 ((unsigned long)return_address(6))
  41320. +#define ftrace_return_address(n) return_address(n)
  41321. #endif /* __ASSEMBLY__ */
  41322. diff -Nur linux-3.14.14/arch/x86/kernel/setup.c linux-imx6-3.14/arch/x86/kernel/setup.c
  41323. --- linux-3.14.14/arch/x86/kernel/setup.c 2014-07-28 10:07:25.000000000 -0500
  41324. +++ linux-imx6-3.14/arch/x86/kernel/setup.c 2014-12-08 00:31:52.308418001 -0600
  41325. @@ -1120,7 +1120,7 @@
  41326. setup_real_mode();
  41327. memblock_set_current_limit(get_max_mapped());
  41328. - dma_contiguous_reserve(0);
  41329. + dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT);
  41330. /*
  41331. * NOTE: On x86-32, only from this point on, fixmaps are ready for use.
  41332. diff -Nur linux-3.14.14/block/bfq-cgroup.c linux-imx6-3.14/block/bfq-cgroup.c
  41333. --- linux-3.14.14/block/bfq-cgroup.c 1969-12-31 18:00:00.000000000 -0600
  41334. +++ linux-imx6-3.14/block/bfq-cgroup.c 2014-12-08 00:31:52.364418001 -0600
  41335. @@ -0,0 +1,932 @@
  41336. +/*
  41337. + * BFQ: CGROUPS support.
  41338. + *
  41339. + * Based on ideas and code from CFQ:
  41340. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  41341. + *
  41342. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  41343. + * Paolo Valente <paolo.valente@unimore.it>
  41344. + *
  41345. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  41346. + *
  41347. + * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
  41348. + * file.
  41349. + */
  41350. +
  41351. +#ifdef CONFIG_CGROUP_BFQIO
  41352. +
  41353. +static DEFINE_MUTEX(bfqio_mutex);
  41354. +
  41355. +static bool bfqio_is_removed(struct bfqio_cgroup *bgrp)
  41356. +{
  41357. + return bgrp ? !bgrp->online : false;
  41358. +}
  41359. +
  41360. +static struct bfqio_cgroup bfqio_root_cgroup = {
  41361. + .weight = BFQ_DEFAULT_GRP_WEIGHT,
  41362. + .ioprio = BFQ_DEFAULT_GRP_IOPRIO,
  41363. + .ioprio_class = BFQ_DEFAULT_GRP_CLASS,
  41364. +};
  41365. +
  41366. +static inline void bfq_init_entity(struct bfq_entity *entity,
  41367. + struct bfq_group *bfqg)
  41368. +{
  41369. + entity->weight = entity->new_weight;
  41370. + entity->orig_weight = entity->new_weight;
  41371. + entity->ioprio = entity->new_ioprio;
  41372. + entity->ioprio_class = entity->new_ioprio_class;
  41373. + entity->parent = bfqg->my_entity;
  41374. + entity->sched_data = &bfqg->sched_data;
  41375. +}
  41376. +
  41377. +static struct bfqio_cgroup *css_to_bfqio(struct cgroup_subsys_state *css)
  41378. +{
  41379. + return css ? container_of(css, struct bfqio_cgroup, css) : NULL;
  41380. +}
  41381. +
  41382. +/*
  41383. + * Search the bfq_group for bfqd into the hash table (by now only a list)
  41384. + * of bgrp. Must be called under rcu_read_lock().
  41385. + */
  41386. +static struct bfq_group *bfqio_lookup_group(struct bfqio_cgroup *bgrp,
  41387. + struct bfq_data *bfqd)
  41388. +{
  41389. + struct bfq_group *bfqg;
  41390. + void *key;
  41391. +
  41392. + hlist_for_each_entry_rcu(bfqg, &bgrp->group_data, group_node) {
  41393. + key = rcu_dereference(bfqg->bfqd);
  41394. + if (key == bfqd)
  41395. + return bfqg;
  41396. + }
  41397. +
  41398. + return NULL;
  41399. +}
  41400. +
  41401. +static inline void bfq_group_init_entity(struct bfqio_cgroup *bgrp,
  41402. + struct bfq_group *bfqg)
  41403. +{
  41404. + struct bfq_entity *entity = &bfqg->entity;
  41405. +
  41406. + /*
  41407. + * If the weight of the entity has never been set via the sysfs
  41408. + * interface, then bgrp->weight == 0. In this case we initialize
  41409. + * the weight from the current ioprio value. Otherwise, the group
  41410. + * weight, if set, has priority over the ioprio value.
  41411. + */
  41412. + if (bgrp->weight == 0) {
  41413. + entity->new_weight = bfq_ioprio_to_weight(bgrp->ioprio);
  41414. + entity->new_ioprio = bgrp->ioprio;
  41415. + } else {
  41416. + entity->new_weight = bgrp->weight;
  41417. + entity->new_ioprio = bfq_weight_to_ioprio(bgrp->weight);
  41418. + }
  41419. + entity->orig_weight = entity->weight = entity->new_weight;
  41420. + entity->ioprio = entity->new_ioprio;
  41421. + entity->ioprio_class = entity->new_ioprio_class = bgrp->ioprio_class;
  41422. + entity->my_sched_data = &bfqg->sched_data;
  41423. + bfqg->active_entities = 0;
  41424. +}
  41425. +
  41426. +static inline void bfq_group_set_parent(struct bfq_group *bfqg,
  41427. + struct bfq_group *parent)
  41428. +{
  41429. + struct bfq_entity *entity;
  41430. +
  41431. + BUG_ON(parent == NULL);
  41432. + BUG_ON(bfqg == NULL);
  41433. +
  41434. + entity = &bfqg->entity;
  41435. + entity->parent = parent->my_entity;
  41436. + entity->sched_data = &parent->sched_data;
  41437. +}
  41438. +
  41439. +/**
  41440. + * bfq_group_chain_alloc - allocate a chain of groups.
  41441. + * @bfqd: queue descriptor.
  41442. + * @css: the leaf cgroup_subsys_state this chain starts from.
  41443. + *
  41444. + * Allocate a chain of groups starting from the one belonging to
  41445. + * @cgroup up to the root cgroup. Stop if a cgroup on the chain
  41446. + * to the root has already an allocated group on @bfqd.
  41447. + */
  41448. +static struct bfq_group *bfq_group_chain_alloc(struct bfq_data *bfqd,
  41449. + struct cgroup_subsys_state *css)
  41450. +{
  41451. + struct bfqio_cgroup *bgrp;
  41452. + struct bfq_group *bfqg, *prev = NULL, *leaf = NULL;
  41453. +
  41454. + for (; css != NULL; css = css->parent) {
  41455. + bgrp = css_to_bfqio(css);
  41456. +
  41457. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  41458. + if (bfqg != NULL) {
  41459. + /*
  41460. + * All the cgroups in the path from there to the
  41461. + * root must have a bfq_group for bfqd, so we don't
  41462. + * need any more allocations.
  41463. + */
  41464. + break;
  41465. + }
  41466. +
  41467. + bfqg = kzalloc(sizeof(*bfqg), GFP_ATOMIC);
  41468. + if (bfqg == NULL)
  41469. + goto cleanup;
  41470. +
  41471. + bfq_group_init_entity(bgrp, bfqg);
  41472. + bfqg->my_entity = &bfqg->entity;
  41473. +
  41474. + if (leaf == NULL) {
  41475. + leaf = bfqg;
  41476. + prev = leaf;
  41477. + } else {
  41478. + bfq_group_set_parent(prev, bfqg);
  41479. + /*
  41480. + * Build a list of allocated nodes using the bfqd
  41481. + * filed, that is still unused and will be
  41482. + * initialized only after the node will be
  41483. + * connected.
  41484. + */
  41485. + prev->bfqd = bfqg;
  41486. + prev = bfqg;
  41487. + }
  41488. + }
  41489. +
  41490. + return leaf;
  41491. +
  41492. +cleanup:
  41493. + while (leaf != NULL) {
  41494. + prev = leaf;
  41495. + leaf = leaf->bfqd;
  41496. + kfree(prev);
  41497. + }
  41498. +
  41499. + return NULL;
  41500. +}
  41501. +
  41502. +/**
  41503. + * bfq_group_chain_link - link an allocated group chain to a cgroup
  41504. + * hierarchy.
  41505. + * @bfqd: the queue descriptor.
  41506. + * @css: the leaf cgroup_subsys_state to start from.
  41507. + * @leaf: the leaf group (to be associated to @cgroup).
  41508. + *
  41509. + * Try to link a chain of groups to a cgroup hierarchy, connecting the
  41510. + * nodes bottom-up, so we can be sure that when we find a cgroup in the
  41511. + * hierarchy that already as a group associated to @bfqd all the nodes
  41512. + * in the path to the root cgroup have one too.
  41513. + *
  41514. + * On locking: the queue lock protects the hierarchy (there is a hierarchy
  41515. + * per device) while the bfqio_cgroup lock protects the list of groups
  41516. + * belonging to the same cgroup.
  41517. + */
  41518. +static void bfq_group_chain_link(struct bfq_data *bfqd,
  41519. + struct cgroup_subsys_state *css,
  41520. + struct bfq_group *leaf)
  41521. +{
  41522. + struct bfqio_cgroup *bgrp;
  41523. + struct bfq_group *bfqg, *next, *prev = NULL;
  41524. + unsigned long flags;
  41525. +
  41526. + assert_spin_locked(bfqd->queue->queue_lock);
  41527. +
  41528. + for (; css != NULL && leaf != NULL; css = css->parent) {
  41529. + bgrp = css_to_bfqio(css);
  41530. + next = leaf->bfqd;
  41531. +
  41532. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  41533. + BUG_ON(bfqg != NULL);
  41534. +
  41535. + spin_lock_irqsave(&bgrp->lock, flags);
  41536. +
  41537. + rcu_assign_pointer(leaf->bfqd, bfqd);
  41538. + hlist_add_head_rcu(&leaf->group_node, &bgrp->group_data);
  41539. + hlist_add_head(&leaf->bfqd_node, &bfqd->group_list);
  41540. +
  41541. + spin_unlock_irqrestore(&bgrp->lock, flags);
  41542. +
  41543. + prev = leaf;
  41544. + leaf = next;
  41545. + }
  41546. +
  41547. + BUG_ON(css == NULL && leaf != NULL);
  41548. + if (css != NULL && prev != NULL) {
  41549. + bgrp = css_to_bfqio(css);
  41550. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  41551. + bfq_group_set_parent(prev, bfqg);
  41552. + }
  41553. +}
  41554. +
  41555. +/**
  41556. + * bfq_find_alloc_group - return the group associated to @bfqd in @cgroup.
  41557. + * @bfqd: queue descriptor.
  41558. + * @cgroup: cgroup being searched for.
  41559. + *
  41560. + * Return a group associated to @bfqd in @cgroup, allocating one if
  41561. + * necessary. When a group is returned all the cgroups in the path
  41562. + * to the root have a group associated to @bfqd.
  41563. + *
  41564. + * If the allocation fails, return the root group: this breaks guarantees
  41565. + * but is a safe fallback. If this loss becomes a problem it can be
  41566. + * mitigated using the equivalent weight (given by the product of the
  41567. + * weights of the groups in the path from @group to the root) in the
  41568. + * root scheduler.
  41569. + *
  41570. + * We allocate all the missing nodes in the path from the leaf cgroup
  41571. + * to the root and we connect the nodes only after all the allocations
  41572. + * have been successful.
  41573. + */
  41574. +static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd,
  41575. + struct cgroup_subsys_state *css)
  41576. +{
  41577. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  41578. + struct bfq_group *bfqg;
  41579. +
  41580. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  41581. + if (bfqg != NULL)
  41582. + return bfqg;
  41583. +
  41584. + bfqg = bfq_group_chain_alloc(bfqd, css);
  41585. + if (bfqg != NULL)
  41586. + bfq_group_chain_link(bfqd, css, bfqg);
  41587. + else
  41588. + bfqg = bfqd->root_group;
  41589. +
  41590. + return bfqg;
  41591. +}
  41592. +
  41593. +/**
  41594. + * bfq_bfqq_move - migrate @bfqq to @bfqg.
  41595. + * @bfqd: queue descriptor.
  41596. + * @bfqq: the queue to move.
  41597. + * @entity: @bfqq's entity.
  41598. + * @bfqg: the group to move to.
  41599. + *
  41600. + * Move @bfqq to @bfqg, deactivating it from its old group and reactivating
  41601. + * it on the new one. Avoid putting the entity on the old group idle tree.
  41602. + *
  41603. + * Must be called under the queue lock; the cgroup owning @bfqg must
  41604. + * not disappear (by now this just means that we are called under
  41605. + * rcu_read_lock()).
  41606. + */
  41607. +static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  41608. + struct bfq_entity *entity, struct bfq_group *bfqg)
  41609. +{
  41610. + int busy, resume;
  41611. +
  41612. + busy = bfq_bfqq_busy(bfqq);
  41613. + resume = !RB_EMPTY_ROOT(&bfqq->sort_list);
  41614. +
  41615. + BUG_ON(resume && !entity->on_st);
  41616. + BUG_ON(busy && !resume && entity->on_st &&
  41617. + bfqq != bfqd->in_service_queue);
  41618. +
  41619. + if (busy) {
  41620. + BUG_ON(atomic_read(&bfqq->ref) < 2);
  41621. +
  41622. + if (!resume)
  41623. + bfq_del_bfqq_busy(bfqd, bfqq, 0);
  41624. + else
  41625. + bfq_deactivate_bfqq(bfqd, bfqq, 0);
  41626. + } else if (entity->on_st)
  41627. + bfq_put_idle_entity(bfq_entity_service_tree(entity), entity);
  41628. +
  41629. + /*
  41630. + * Here we use a reference to bfqg. We don't need a refcounter
  41631. + * as the cgroup reference will not be dropped, so that its
  41632. + * destroy() callback will not be invoked.
  41633. + */
  41634. + entity->parent = bfqg->my_entity;
  41635. + entity->sched_data = &bfqg->sched_data;
  41636. +
  41637. + if (busy && resume)
  41638. + bfq_activate_bfqq(bfqd, bfqq);
  41639. +
  41640. + if (bfqd->in_service_queue == NULL && !bfqd->rq_in_driver)
  41641. + bfq_schedule_dispatch(bfqd);
  41642. +}
  41643. +
  41644. +/**
  41645. + * __bfq_bic_change_cgroup - move @bic to @cgroup.
  41646. + * @bfqd: the queue descriptor.
  41647. + * @bic: the bic to move.
  41648. + * @cgroup: the cgroup to move to.
  41649. + *
  41650. + * Move bic to cgroup, assuming that bfqd->queue is locked; the caller
  41651. + * has to make sure that the reference to cgroup is valid across the call.
  41652. + *
  41653. + * NOTE: an alternative approach might have been to store the current
  41654. + * cgroup in bfqq and getting a reference to it, reducing the lookup
  41655. + * time here, at the price of slightly more complex code.
  41656. + */
  41657. +static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
  41658. + struct bfq_io_cq *bic,
  41659. + struct cgroup_subsys_state *css)
  41660. +{
  41661. + struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0);
  41662. + struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1);
  41663. + struct bfq_entity *entity;
  41664. + struct bfq_group *bfqg;
  41665. + struct bfqio_cgroup *bgrp;
  41666. +
  41667. + bgrp = css_to_bfqio(css);
  41668. +
  41669. + bfqg = bfq_find_alloc_group(bfqd, css);
  41670. + if (async_bfqq != NULL) {
  41671. + entity = &async_bfqq->entity;
  41672. +
  41673. + if (entity->sched_data != &bfqg->sched_data) {
  41674. + bic_set_bfqq(bic, NULL, 0);
  41675. + bfq_log_bfqq(bfqd, async_bfqq,
  41676. + "bic_change_group: %p %d",
  41677. + async_bfqq, atomic_read(&async_bfqq->ref));
  41678. + bfq_put_queue(async_bfqq);
  41679. + }
  41680. + }
  41681. +
  41682. + if (sync_bfqq != NULL) {
  41683. + entity = &sync_bfqq->entity;
  41684. + if (entity->sched_data != &bfqg->sched_data)
  41685. + bfq_bfqq_move(bfqd, sync_bfqq, entity, bfqg);
  41686. + }
  41687. +
  41688. + return bfqg;
  41689. +}
  41690. +
  41691. +/**
  41692. + * bfq_bic_change_cgroup - move @bic to @cgroup.
  41693. + * @bic: the bic being migrated.
  41694. + * @cgroup: the destination cgroup.
  41695. + *
  41696. + * When the task owning @bic is moved to @cgroup, @bic is immediately
  41697. + * moved into its new parent group.
  41698. + */
  41699. +static void bfq_bic_change_cgroup(struct bfq_io_cq *bic,
  41700. + struct cgroup_subsys_state *css)
  41701. +{
  41702. + struct bfq_data *bfqd;
  41703. + unsigned long uninitialized_var(flags);
  41704. +
  41705. + bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data),
  41706. + &flags);
  41707. + if (bfqd != NULL) {
  41708. + __bfq_bic_change_cgroup(bfqd, bic, css);
  41709. + bfq_put_bfqd_unlock(bfqd, &flags);
  41710. + }
  41711. +}
  41712. +
  41713. +/**
  41714. + * bfq_bic_update_cgroup - update the cgroup of @bic.
  41715. + * @bic: the @bic to update.
  41716. + *
  41717. + * Make sure that @bic is enqueued in the cgroup of the current task.
  41718. + * We need this in addition to moving bics during the cgroup attach
  41719. + * phase because the task owning @bic could be at its first disk
  41720. + * access or we may end up in the root cgroup as the result of a
  41721. + * memory allocation failure and here we try to move to the right
  41722. + * group.
  41723. + *
  41724. + * Must be called under the queue lock. It is safe to use the returned
  41725. + * value even after the rcu_read_unlock() as the migration/destruction
  41726. + * paths act under the queue lock too. IOW it is impossible to race with
  41727. + * group migration/destruction and end up with an invalid group as:
  41728. + * a) here cgroup has not yet been destroyed, nor its destroy callback
  41729. + * has started execution, as current holds a reference to it,
  41730. + * b) if it is destroyed after rcu_read_unlock() [after current is
  41731. + * migrated to a different cgroup] its attach() callback will have
  41732. + * taken care of remove all the references to the old cgroup data.
  41733. + */
  41734. +static struct bfq_group *bfq_bic_update_cgroup(struct bfq_io_cq *bic)
  41735. +{
  41736. + struct bfq_data *bfqd = bic_to_bfqd(bic);
  41737. + struct bfq_group *bfqg;
  41738. + struct cgroup_subsys_state *css;
  41739. +
  41740. + BUG_ON(bfqd == NULL);
  41741. +
  41742. + rcu_read_lock();
  41743. + css = task_css(current, bfqio_subsys_id);
  41744. + bfqg = __bfq_bic_change_cgroup(bfqd, bic, css);
  41745. + rcu_read_unlock();
  41746. +
  41747. + return bfqg;
  41748. +}
  41749. +
  41750. +/**
  41751. + * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st.
  41752. + * @st: the service tree being flushed.
  41753. + */
  41754. +static inline void bfq_flush_idle_tree(struct bfq_service_tree *st)
  41755. +{
  41756. + struct bfq_entity *entity = st->first_idle;
  41757. +
  41758. + for (; entity != NULL; entity = st->first_idle)
  41759. + __bfq_deactivate_entity(entity, 0);
  41760. +}
  41761. +
  41762. +/**
  41763. + * bfq_reparent_leaf_entity - move leaf entity to the root_group.
  41764. + * @bfqd: the device data structure with the root group.
  41765. + * @entity: the entity to move.
  41766. + */
  41767. +static inline void bfq_reparent_leaf_entity(struct bfq_data *bfqd,
  41768. + struct bfq_entity *entity)
  41769. +{
  41770. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  41771. +
  41772. + BUG_ON(bfqq == NULL);
  41773. + bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group);
  41774. + return;
  41775. +}
  41776. +
  41777. +/**
  41778. + * bfq_reparent_active_entities - move to the root group all active
  41779. + * entities.
  41780. + * @bfqd: the device data structure with the root group.
  41781. + * @bfqg: the group to move from.
  41782. + * @st: the service tree with the entities.
  41783. + *
  41784. + * Needs queue_lock to be taken and reference to be valid over the call.
  41785. + */
  41786. +static inline void bfq_reparent_active_entities(struct bfq_data *bfqd,
  41787. + struct bfq_group *bfqg,
  41788. + struct bfq_service_tree *st)
  41789. +{
  41790. + struct rb_root *active = &st->active;
  41791. + struct bfq_entity *entity = NULL;
  41792. +
  41793. + if (!RB_EMPTY_ROOT(&st->active))
  41794. + entity = bfq_entity_of(rb_first(active));
  41795. +
  41796. + for (; entity != NULL; entity = bfq_entity_of(rb_first(active)))
  41797. + bfq_reparent_leaf_entity(bfqd, entity);
  41798. +
  41799. + if (bfqg->sched_data.in_service_entity != NULL)
  41800. + bfq_reparent_leaf_entity(bfqd,
  41801. + bfqg->sched_data.in_service_entity);
  41802. +
  41803. + return;
  41804. +}
  41805. +
  41806. +/**
  41807. + * bfq_destroy_group - destroy @bfqg.
  41808. + * @bgrp: the bfqio_cgroup containing @bfqg.
  41809. + * @bfqg: the group being destroyed.
  41810. + *
  41811. + * Destroy @bfqg, making sure that it is not referenced from its parent.
  41812. + */
  41813. +static void bfq_destroy_group(struct bfqio_cgroup *bgrp, struct bfq_group *bfqg)
  41814. +{
  41815. + struct bfq_data *bfqd;
  41816. + struct bfq_service_tree *st;
  41817. + struct bfq_entity *entity = bfqg->my_entity;
  41818. + unsigned long uninitialized_var(flags);
  41819. + int i;
  41820. +
  41821. + hlist_del(&bfqg->group_node);
  41822. +
  41823. + /*
  41824. + * Empty all service_trees belonging to this group before
  41825. + * deactivating the group itself.
  41826. + */
  41827. + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) {
  41828. + st = bfqg->sched_data.service_tree + i;
  41829. +
  41830. + /*
  41831. + * The idle tree may still contain bfq_queues belonging
  41832. + * to exited task because they never migrated to a different
  41833. + * cgroup from the one being destroyed now. No one else
  41834. + * can access them so it's safe to act without any lock.
  41835. + */
  41836. + bfq_flush_idle_tree(st);
  41837. +
  41838. + /*
  41839. + * It may happen that some queues are still active
  41840. + * (busy) upon group destruction (if the corresponding
  41841. + * processes have been forced to terminate). We move
  41842. + * all the leaf entities corresponding to these queues
  41843. + * to the root_group.
  41844. + * Also, it may happen that the group has an entity
  41845. + * in service, which is disconnected from the active
  41846. + * tree: it must be moved, too.
  41847. + * There is no need to put the sync queues, as the
  41848. + * scheduler has taken no reference.
  41849. + */
  41850. + bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags);
  41851. + if (bfqd != NULL) {
  41852. + bfq_reparent_active_entities(bfqd, bfqg, st);
  41853. + bfq_put_bfqd_unlock(bfqd, &flags);
  41854. + }
  41855. + BUG_ON(!RB_EMPTY_ROOT(&st->active));
  41856. + BUG_ON(!RB_EMPTY_ROOT(&st->idle));
  41857. + }
  41858. + BUG_ON(bfqg->sched_data.next_in_service != NULL);
  41859. + BUG_ON(bfqg->sched_data.in_service_entity != NULL);
  41860. +
  41861. + /*
  41862. + * We may race with device destruction, take extra care when
  41863. + * dereferencing bfqg->bfqd.
  41864. + */
  41865. + bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags);
  41866. + if (bfqd != NULL) {
  41867. + hlist_del(&bfqg->bfqd_node);
  41868. + __bfq_deactivate_entity(entity, 0);
  41869. + bfq_put_async_queues(bfqd, bfqg);
  41870. + bfq_put_bfqd_unlock(bfqd, &flags);
  41871. + }
  41872. + BUG_ON(entity->tree != NULL);
  41873. +
  41874. + /*
  41875. + * No need to defer the kfree() to the end of the RCU grace
  41876. + * period: we are called from the destroy() callback of our
  41877. + * cgroup, so we can be sure that no one is a) still using
  41878. + * this cgroup or b) doing lookups in it.
  41879. + */
  41880. + kfree(bfqg);
  41881. +}
  41882. +
  41883. +static void bfq_end_wr_async(struct bfq_data *bfqd)
  41884. +{
  41885. + struct hlist_node *tmp;
  41886. + struct bfq_group *bfqg;
  41887. +
  41888. + hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node)
  41889. + bfq_end_wr_async_queues(bfqd, bfqg);
  41890. + bfq_end_wr_async_queues(bfqd, bfqd->root_group);
  41891. +}
  41892. +
  41893. +/**
  41894. + * bfq_disconnect_groups - disconnect @bfqd from all its groups.
  41895. + * @bfqd: the device descriptor being exited.
  41896. + *
  41897. + * When the device exits we just make sure that no lookup can return
  41898. + * the now unused group structures. They will be deallocated on cgroup
  41899. + * destruction.
  41900. + */
  41901. +static void bfq_disconnect_groups(struct bfq_data *bfqd)
  41902. +{
  41903. + struct hlist_node *tmp;
  41904. + struct bfq_group *bfqg;
  41905. +
  41906. + bfq_log(bfqd, "disconnect_groups beginning");
  41907. + hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) {
  41908. + hlist_del(&bfqg->bfqd_node);
  41909. +
  41910. + __bfq_deactivate_entity(bfqg->my_entity, 0);
  41911. +
  41912. + /*
  41913. + * Don't remove from the group hash, just set an
  41914. + * invalid key. No lookups can race with the
  41915. + * assignment as bfqd is being destroyed; this
  41916. + * implies also that new elements cannot be added
  41917. + * to the list.
  41918. + */
  41919. + rcu_assign_pointer(bfqg->bfqd, NULL);
  41920. +
  41921. + bfq_log(bfqd, "disconnect_groups: put async for group %p",
  41922. + bfqg);
  41923. + bfq_put_async_queues(bfqd, bfqg);
  41924. + }
  41925. +}
  41926. +
  41927. +static inline void bfq_free_root_group(struct bfq_data *bfqd)
  41928. +{
  41929. + struct bfqio_cgroup *bgrp = &bfqio_root_cgroup;
  41930. + struct bfq_group *bfqg = bfqd->root_group;
  41931. +
  41932. + bfq_put_async_queues(bfqd, bfqg);
  41933. +
  41934. + spin_lock_irq(&bgrp->lock);
  41935. + hlist_del_rcu(&bfqg->group_node);
  41936. + spin_unlock_irq(&bgrp->lock);
  41937. +
  41938. + /*
  41939. + * No need to synchronize_rcu() here: since the device is gone
  41940. + * there cannot be any read-side access to its root_group.
  41941. + */
  41942. + kfree(bfqg);
  41943. +}
  41944. +
  41945. +static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node)
  41946. +{
  41947. + struct bfq_group *bfqg;
  41948. + struct bfqio_cgroup *bgrp;
  41949. + int i;
  41950. +
  41951. + bfqg = kzalloc_node(sizeof(*bfqg), GFP_KERNEL, node);
  41952. + if (bfqg == NULL)
  41953. + return NULL;
  41954. +
  41955. + bfqg->entity.parent = NULL;
  41956. + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++)
  41957. + bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT;
  41958. +
  41959. + bgrp = &bfqio_root_cgroup;
  41960. + spin_lock_irq(&bgrp->lock);
  41961. + rcu_assign_pointer(bfqg->bfqd, bfqd);
  41962. + hlist_add_head_rcu(&bfqg->group_node, &bgrp->group_data);
  41963. + spin_unlock_irq(&bgrp->lock);
  41964. +
  41965. + return bfqg;
  41966. +}
  41967. +
  41968. +#define SHOW_FUNCTION(__VAR) \
  41969. +static u64 bfqio_cgroup_##__VAR##_read(struct cgroup_subsys_state *css, \
  41970. + struct cftype *cftype) \
  41971. +{ \
  41972. + struct bfqio_cgroup *bgrp = css_to_bfqio(css); \
  41973. + u64 ret = -ENODEV; \
  41974. + \
  41975. + mutex_lock(&bfqio_mutex); \
  41976. + if (bfqio_is_removed(bgrp)) \
  41977. + goto out_unlock; \
  41978. + \
  41979. + spin_lock_irq(&bgrp->lock); \
  41980. + ret = bgrp->__VAR; \
  41981. + spin_unlock_irq(&bgrp->lock); \
  41982. + \
  41983. +out_unlock: \
  41984. + mutex_unlock(&bfqio_mutex); \
  41985. + return ret; \
  41986. +}
  41987. +
  41988. +SHOW_FUNCTION(weight);
  41989. +SHOW_FUNCTION(ioprio);
  41990. +SHOW_FUNCTION(ioprio_class);
  41991. +#undef SHOW_FUNCTION
  41992. +
  41993. +#define STORE_FUNCTION(__VAR, __MIN, __MAX) \
  41994. +static int bfqio_cgroup_##__VAR##_write(struct cgroup_subsys_state *css,\
  41995. + struct cftype *cftype, \
  41996. + u64 val) \
  41997. +{ \
  41998. + struct bfqio_cgroup *bgrp = css_to_bfqio(css); \
  41999. + struct bfq_group *bfqg; \
  42000. + int ret = -EINVAL; \
  42001. + \
  42002. + if (val < (__MIN) || val > (__MAX)) \
  42003. + return ret; \
  42004. + \
  42005. + ret = -ENODEV; \
  42006. + mutex_lock(&bfqio_mutex); \
  42007. + if (bfqio_is_removed(bgrp)) \
  42008. + goto out_unlock; \
  42009. + ret = 0; \
  42010. + \
  42011. + spin_lock_irq(&bgrp->lock); \
  42012. + bgrp->__VAR = (unsigned short)val; \
  42013. + hlist_for_each_entry(bfqg, &bgrp->group_data, group_node) { \
  42014. + /* \
  42015. + * Setting the ioprio_changed flag of the entity \
  42016. + * to 1 with new_##__VAR == ##__VAR would re-set \
  42017. + * the value of the weight to its ioprio mapping. \
  42018. + * Set the flag only if necessary. \
  42019. + */ \
  42020. + if ((unsigned short)val != bfqg->entity.new_##__VAR) { \
  42021. + bfqg->entity.new_##__VAR = (unsigned short)val; \
  42022. + /* \
  42023. + * Make sure that the above new value has been \
  42024. + * stored in bfqg->entity.new_##__VAR before \
  42025. + * setting the ioprio_changed flag. In fact, \
  42026. + * this flag may be read asynchronously (in \
  42027. + * critical sections protected by a different \
  42028. + * lock than that held here), and finding this \
  42029. + * flag set may cause the execution of the code \
  42030. + * for updating parameters whose value may \
  42031. + * depend also on bfqg->entity.new_##__VAR (in \
  42032. + * __bfq_entity_update_weight_prio). \
  42033. + * This barrier makes sure that the new value \
  42034. + * of bfqg->entity.new_##__VAR is correctly \
  42035. + * seen in that code. \
  42036. + */ \
  42037. + smp_wmb(); \
  42038. + bfqg->entity.ioprio_changed = 1; \
  42039. + } \
  42040. + } \
  42041. + spin_unlock_irq(&bgrp->lock); \
  42042. + \
  42043. +out_unlock: \
  42044. + mutex_unlock(&bfqio_mutex); \
  42045. + return ret; \
  42046. +}
  42047. +
  42048. +STORE_FUNCTION(weight, BFQ_MIN_WEIGHT, BFQ_MAX_WEIGHT);
  42049. +STORE_FUNCTION(ioprio, 0, IOPRIO_BE_NR - 1);
  42050. +STORE_FUNCTION(ioprio_class, IOPRIO_CLASS_RT, IOPRIO_CLASS_IDLE);
  42051. +#undef STORE_FUNCTION
  42052. +
  42053. +static struct cftype bfqio_files[] = {
  42054. + {
  42055. + .name = "weight",
  42056. + .read_u64 = bfqio_cgroup_weight_read,
  42057. + .write_u64 = bfqio_cgroup_weight_write,
  42058. + },
  42059. + {
  42060. + .name = "ioprio",
  42061. + .read_u64 = bfqio_cgroup_ioprio_read,
  42062. + .write_u64 = bfqio_cgroup_ioprio_write,
  42063. + },
  42064. + {
  42065. + .name = "ioprio_class",
  42066. + .read_u64 = bfqio_cgroup_ioprio_class_read,
  42067. + .write_u64 = bfqio_cgroup_ioprio_class_write,
  42068. + },
  42069. + { }, /* terminate */
  42070. +};
  42071. +
  42072. +static struct cgroup_subsys_state *bfqio_create(struct cgroup_subsys_state
  42073. + *parent_css)
  42074. +{
  42075. + struct bfqio_cgroup *bgrp;
  42076. +
  42077. + if (parent_css != NULL) {
  42078. + bgrp = kzalloc(sizeof(*bgrp), GFP_KERNEL);
  42079. + if (bgrp == NULL)
  42080. + return ERR_PTR(-ENOMEM);
  42081. + } else
  42082. + bgrp = &bfqio_root_cgroup;
  42083. +
  42084. + spin_lock_init(&bgrp->lock);
  42085. + INIT_HLIST_HEAD(&bgrp->group_data);
  42086. + bgrp->ioprio = BFQ_DEFAULT_GRP_IOPRIO;
  42087. + bgrp->ioprio_class = BFQ_DEFAULT_GRP_CLASS;
  42088. +
  42089. + return &bgrp->css;
  42090. +}
  42091. +
  42092. +/*
  42093. + * We cannot support shared io contexts, as we have no means to support
  42094. + * two tasks with the same ioc in two different groups without major rework
  42095. + * of the main bic/bfqq data structures. By now we allow a task to change
  42096. + * its cgroup only if it's the only owner of its ioc; the drawback of this
  42097. + * behavior is that a group containing a task that forked using CLONE_IO
  42098. + * will not be destroyed until the tasks sharing the ioc die.
  42099. + */
  42100. +static int bfqio_can_attach(struct cgroup_subsys_state *css,
  42101. + struct cgroup_taskset *tset)
  42102. +{
  42103. + struct task_struct *task;
  42104. + struct io_context *ioc;
  42105. + int ret = 0;
  42106. +
  42107. + cgroup_taskset_for_each(task, css, tset) {
  42108. + /*
  42109. + * task_lock() is needed to avoid races with
  42110. + * exit_io_context()
  42111. + */
  42112. + task_lock(task);
  42113. + ioc = task->io_context;
  42114. + if (ioc != NULL && atomic_read(&ioc->nr_tasks) > 1)
  42115. + /*
  42116. + * ioc == NULL means that the task is either too
  42117. + * young or exiting: if it has still no ioc the
  42118. + * ioc can't be shared, if the task is exiting the
  42119. + * attach will fail anyway, no matter what we
  42120. + * return here.
  42121. + */
  42122. + ret = -EINVAL;
  42123. + task_unlock(task);
  42124. + if (ret)
  42125. + break;
  42126. + }
  42127. +
  42128. + return ret;
  42129. +}
  42130. +
  42131. +static void bfqio_attach(struct cgroup_subsys_state *css,
  42132. + struct cgroup_taskset *tset)
  42133. +{
  42134. + struct task_struct *task;
  42135. + struct io_context *ioc;
  42136. + struct io_cq *icq;
  42137. +
  42138. + /*
  42139. + * IMPORTANT NOTE: The move of more than one process at a time to a
  42140. + * new group has not yet been tested.
  42141. + */
  42142. + cgroup_taskset_for_each(task, css, tset) {
  42143. + ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE);
  42144. + if (ioc) {
  42145. + /*
  42146. + * Handle cgroup change here.
  42147. + */
  42148. + rcu_read_lock();
  42149. + hlist_for_each_entry_rcu(icq, &ioc->icq_list, ioc_node)
  42150. + if (!strncmp(
  42151. + icq->q->elevator->type->elevator_name,
  42152. + "bfq", ELV_NAME_MAX))
  42153. + bfq_bic_change_cgroup(icq_to_bic(icq),
  42154. + css);
  42155. + rcu_read_unlock();
  42156. + put_io_context(ioc);
  42157. + }
  42158. + }
  42159. +}
  42160. +
  42161. +static void bfqio_destroy(struct cgroup_subsys_state *css)
  42162. +{
  42163. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  42164. + struct hlist_node *tmp;
  42165. + struct bfq_group *bfqg;
  42166. +
  42167. + /*
  42168. + * Since we are destroying the cgroup, there are no more tasks
  42169. + * referencing it, and all the RCU grace periods that may have
  42170. + * referenced it are ended (as the destruction of the parent
  42171. + * cgroup is RCU-safe); bgrp->group_data will not be accessed by
  42172. + * anything else and we don't need any synchronization.
  42173. + */
  42174. + hlist_for_each_entry_safe(bfqg, tmp, &bgrp->group_data, group_node)
  42175. + bfq_destroy_group(bgrp, bfqg);
  42176. +
  42177. + BUG_ON(!hlist_empty(&bgrp->group_data));
  42178. +
  42179. + kfree(bgrp);
  42180. +}
  42181. +
  42182. +static int bfqio_css_online(struct cgroup_subsys_state *css)
  42183. +{
  42184. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  42185. +
  42186. + mutex_lock(&bfqio_mutex);
  42187. + bgrp->online = true;
  42188. + mutex_unlock(&bfqio_mutex);
  42189. +
  42190. + return 0;
  42191. +}
  42192. +
  42193. +static void bfqio_css_offline(struct cgroup_subsys_state *css)
  42194. +{
  42195. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  42196. +
  42197. + mutex_lock(&bfqio_mutex);
  42198. + bgrp->online = false;
  42199. + mutex_unlock(&bfqio_mutex);
  42200. +}
  42201. +
  42202. +struct cgroup_subsys bfqio_subsys = {
  42203. + .name = "bfqio",
  42204. + .css_alloc = bfqio_create,
  42205. + .css_online = bfqio_css_online,
  42206. + .css_offline = bfqio_css_offline,
  42207. + .can_attach = bfqio_can_attach,
  42208. + .attach = bfqio_attach,
  42209. + .css_free = bfqio_destroy,
  42210. + .subsys_id = bfqio_subsys_id,
  42211. + .base_cftypes = bfqio_files,
  42212. +};
  42213. +#else
  42214. +static inline void bfq_init_entity(struct bfq_entity *entity,
  42215. + struct bfq_group *bfqg)
  42216. +{
  42217. + entity->weight = entity->new_weight;
  42218. + entity->orig_weight = entity->new_weight;
  42219. + entity->ioprio = entity->new_ioprio;
  42220. + entity->ioprio_class = entity->new_ioprio_class;
  42221. + entity->sched_data = &bfqg->sched_data;
  42222. +}
  42223. +
  42224. +static inline struct bfq_group *
  42225. +bfq_bic_update_cgroup(struct bfq_io_cq *bic)
  42226. +{
  42227. + struct bfq_data *bfqd = bic_to_bfqd(bic);
  42228. + return bfqd->root_group;
  42229. +}
  42230. +
  42231. +static inline void bfq_bfqq_move(struct bfq_data *bfqd,
  42232. + struct bfq_queue *bfqq,
  42233. + struct bfq_entity *entity,
  42234. + struct bfq_group *bfqg)
  42235. +{
  42236. +}
  42237. +
  42238. +static void bfq_end_wr_async(struct bfq_data *bfqd)
  42239. +{
  42240. + bfq_end_wr_async_queues(bfqd, bfqd->root_group);
  42241. +}
  42242. +
  42243. +static inline void bfq_disconnect_groups(struct bfq_data *bfqd)
  42244. +{
  42245. + bfq_put_async_queues(bfqd, bfqd->root_group);
  42246. +}
  42247. +
  42248. +static inline void bfq_free_root_group(struct bfq_data *bfqd)
  42249. +{
  42250. + kfree(bfqd->root_group);
  42251. +}
  42252. +
  42253. +static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node)
  42254. +{
  42255. + struct bfq_group *bfqg;
  42256. + int i;
  42257. +
  42258. + bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node);
  42259. + if (bfqg == NULL)
  42260. + return NULL;
  42261. +
  42262. + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++)
  42263. + bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT;
  42264. +
  42265. + return bfqg;
  42266. +}
  42267. +#endif
  42268. diff -Nur linux-3.14.14/block/bfq.h linux-imx6-3.14/block/bfq.h
  42269. --- linux-3.14.14/block/bfq.h 1969-12-31 18:00:00.000000000 -0600
  42270. +++ linux-imx6-3.14/block/bfq.h 2014-12-08 00:31:52.364418001 -0600
  42271. @@ -0,0 +1,770 @@
  42272. +/*
  42273. + * BFQ-v7r5 for 3.14.0: data structures and common functions prototypes.
  42274. + *
  42275. + * Based on ideas and code from CFQ:
  42276. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  42277. + *
  42278. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  42279. + * Paolo Valente <paolo.valente@unimore.it>
  42280. + *
  42281. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  42282. + */
  42283. +
  42284. +#ifndef _BFQ_H
  42285. +#define _BFQ_H
  42286. +
  42287. +#include <linux/blktrace_api.h>
  42288. +#include <linux/hrtimer.h>
  42289. +#include <linux/ioprio.h>
  42290. +#include <linux/rbtree.h>
  42291. +
  42292. +#define BFQ_IOPRIO_CLASSES 3
  42293. +#define BFQ_CL_IDLE_TIMEOUT (HZ/5)
  42294. +
  42295. +#define BFQ_MIN_WEIGHT 1
  42296. +#define BFQ_MAX_WEIGHT 1000
  42297. +
  42298. +#define BFQ_DEFAULT_GRP_WEIGHT 10
  42299. +#define BFQ_DEFAULT_GRP_IOPRIO 0
  42300. +#define BFQ_DEFAULT_GRP_CLASS IOPRIO_CLASS_BE
  42301. +
  42302. +struct bfq_entity;
  42303. +
  42304. +/**
  42305. + * struct bfq_service_tree - per ioprio_class service tree.
  42306. + * @active: tree for active entities (i.e., those backlogged).
  42307. + * @idle: tree for idle entities (i.e., those not backlogged, with V <= F_i).
  42308. + * @first_idle: idle entity with minimum F_i.
  42309. + * @last_idle: idle entity with maximum F_i.
  42310. + * @vtime: scheduler virtual time.
  42311. + * @wsum: scheduler weight sum; active and idle entities contribute to it.
  42312. + *
  42313. + * Each service tree represents a B-WF2Q+ scheduler on its own. Each
  42314. + * ioprio_class has its own independent scheduler, and so its own
  42315. + * bfq_service_tree. All the fields are protected by the queue lock
  42316. + * of the containing bfqd.
  42317. + */
  42318. +struct bfq_service_tree {
  42319. + struct rb_root active;
  42320. + struct rb_root idle;
  42321. +
  42322. + struct bfq_entity *first_idle;
  42323. + struct bfq_entity *last_idle;
  42324. +
  42325. + u64 vtime;
  42326. + unsigned long wsum;
  42327. +};
  42328. +
  42329. +/**
  42330. + * struct bfq_sched_data - multi-class scheduler.
  42331. + * @in_service_entity: entity in service.
  42332. + * @next_in_service: head-of-the-line entity in the scheduler.
  42333. + * @service_tree: array of service trees, one per ioprio_class.
  42334. + *
  42335. + * bfq_sched_data is the basic scheduler queue. It supports three
  42336. + * ioprio_classes, and can be used either as a toplevel queue or as
  42337. + * an intermediate queue on a hierarchical setup.
  42338. + * @next_in_service points to the active entity of the sched_data
  42339. + * service trees that will be scheduled next.
  42340. + *
  42341. + * The supported ioprio_classes are the same as in CFQ, in descending
  42342. + * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE.
  42343. + * Requests from higher priority queues are served before all the
  42344. + * requests from lower priority queues; among requests of the same
  42345. + * queue requests are served according to B-WF2Q+.
  42346. + * All the fields are protected by the queue lock of the containing bfqd.
  42347. + */
  42348. +struct bfq_sched_data {
  42349. + struct bfq_entity *in_service_entity;
  42350. + struct bfq_entity *next_in_service;
  42351. + struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES];
  42352. +};
  42353. +
  42354. +/**
  42355. + * struct bfq_weight_counter - counter of the number of all active entities
  42356. + * with a given weight.
  42357. + * @weight: weight of the entities that this counter refers to.
  42358. + * @num_active: number of active entities with this weight.
  42359. + * @weights_node: weights tree member (see bfq_data's @queue_weights_tree
  42360. + * and @group_weights_tree).
  42361. + */
  42362. +struct bfq_weight_counter {
  42363. + short int weight;
  42364. + unsigned int num_active;
  42365. + struct rb_node weights_node;
  42366. +};
  42367. +
  42368. +/**
  42369. + * struct bfq_entity - schedulable entity.
  42370. + * @rb_node: service_tree member.
  42371. + * @weight_counter: pointer to the weight counter associated with this entity.
  42372. + * @on_st: flag, true if the entity is on a tree (either the active or
  42373. + * the idle one of its service_tree).
  42374. + * @finish: B-WF2Q+ finish timestamp (aka F_i).
  42375. + * @start: B-WF2Q+ start timestamp (aka S_i).
  42376. + * @tree: tree the entity is enqueued into; %NULL if not on a tree.
  42377. + * @min_start: minimum start time of the (active) subtree rooted at
  42378. + * this entity; used for O(log N) lookups into active trees.
  42379. + * @service: service received during the last round of service.
  42380. + * @budget: budget used to calculate F_i; F_i = S_i + @budget / @weight.
  42381. + * @weight: weight of the queue
  42382. + * @parent: parent entity, for hierarchical scheduling.
  42383. + * @my_sched_data: for non-leaf nodes in the cgroup hierarchy, the
  42384. + * associated scheduler queue, %NULL on leaf nodes.
  42385. + * @sched_data: the scheduler queue this entity belongs to.
  42386. + * @ioprio: the ioprio in use.
  42387. + * @new_weight: when a weight change is requested, the new weight value.
  42388. + * @orig_weight: original weight, used to implement weight boosting
  42389. + * @new_ioprio: when an ioprio change is requested, the new ioprio value.
  42390. + * @ioprio_class: the ioprio_class in use.
  42391. + * @new_ioprio_class: when an ioprio_class change is requested, the new
  42392. + * ioprio_class value.
  42393. + * @ioprio_changed: flag, true when the user requested a weight, ioprio or
  42394. + * ioprio_class change.
  42395. + *
  42396. + * A bfq_entity is used to represent either a bfq_queue (leaf node in the
  42397. + * cgroup hierarchy) or a bfq_group into the upper level scheduler. Each
  42398. + * entity belongs to the sched_data of the parent group in the cgroup
  42399. + * hierarchy. Non-leaf entities have also their own sched_data, stored
  42400. + * in @my_sched_data.
  42401. + *
  42402. + * Each entity stores independently its priority values; this would
  42403. + * allow different weights on different devices, but this
  42404. + * functionality is not exported to userspace by now. Priorities and
  42405. + * weights are updated lazily, first storing the new values into the
  42406. + * new_* fields, then setting the @ioprio_changed flag. As soon as
  42407. + * there is a transition in the entity state that allows the priority
  42408. + * update to take place the effective and the requested priority
  42409. + * values are synchronized.
  42410. + *
  42411. + * Unless cgroups are used, the weight value is calculated from the
  42412. + * ioprio to export the same interface as CFQ. When dealing with
  42413. + * ``well-behaved'' queues (i.e., queues that do not spend too much
  42414. + * time to consume their budget and have true sequential behavior, and
  42415. + * when there are no external factors breaking anticipation) the
  42416. + * relative weights at each level of the cgroups hierarchy should be
  42417. + * guaranteed. All the fields are protected by the queue lock of the
  42418. + * containing bfqd.
  42419. + */
  42420. +struct bfq_entity {
  42421. + struct rb_node rb_node;
  42422. + struct bfq_weight_counter *weight_counter;
  42423. +
  42424. + int on_st;
  42425. +
  42426. + u64 finish;
  42427. + u64 start;
  42428. +
  42429. + struct rb_root *tree;
  42430. +
  42431. + u64 min_start;
  42432. +
  42433. + unsigned long service, budget;
  42434. + unsigned short weight, new_weight;
  42435. + unsigned short orig_weight;
  42436. +
  42437. + struct bfq_entity *parent;
  42438. +
  42439. + struct bfq_sched_data *my_sched_data;
  42440. + struct bfq_sched_data *sched_data;
  42441. +
  42442. + unsigned short ioprio, new_ioprio;
  42443. + unsigned short ioprio_class, new_ioprio_class;
  42444. +
  42445. + int ioprio_changed;
  42446. +};
  42447. +
  42448. +struct bfq_group;
  42449. +
  42450. +/**
  42451. + * struct bfq_queue - leaf schedulable entity.
  42452. + * @ref: reference counter.
  42453. + * @bfqd: parent bfq_data.
  42454. + * @new_bfqq: shared bfq_queue if queue is cooperating with
  42455. + * one or more other queues.
  42456. + * @pos_node: request-position tree member (see bfq_data's @rq_pos_tree).
  42457. + * @pos_root: request-position tree root (see bfq_data's @rq_pos_tree).
  42458. + * @sort_list: sorted list of pending requests.
  42459. + * @next_rq: if fifo isn't expired, next request to serve.
  42460. + * @queued: nr of requests queued in @sort_list.
  42461. + * @allocated: currently allocated requests.
  42462. + * @meta_pending: pending metadata requests.
  42463. + * @fifo: fifo list of requests in sort_list.
  42464. + * @entity: entity representing this queue in the scheduler.
  42465. + * @max_budget: maximum budget allowed from the feedback mechanism.
  42466. + * @budget_timeout: budget expiration (in jiffies).
  42467. + * @dispatched: number of requests on the dispatch list or inside driver.
  42468. + * @flags: status flags.
  42469. + * @bfqq_list: node for active/idle bfqq list inside our bfqd.
  42470. + * @seek_samples: number of seeks sampled
  42471. + * @seek_total: sum of the distances of the seeks sampled
  42472. + * @seek_mean: mean seek distance
  42473. + * @last_request_pos: position of the last request enqueued
  42474. + * @requests_within_timer: number of consecutive pairs of request completion
  42475. + * and arrival, such that the queue becomes idle
  42476. + * after the completion, but the next request arrives
  42477. + * within an idle time slice; used only if the queue's
  42478. + * IO_bound has been cleared.
  42479. + * @pid: pid of the process owning the queue, used for logging purposes.
  42480. + * @last_wr_start_finish: start time of the current weight-raising period if
  42481. + * the @bfq-queue is being weight-raised, otherwise
  42482. + * finish time of the last weight-raising period
  42483. + * @wr_cur_max_time: current max raising time for this queue
  42484. + * @soft_rt_next_start: minimum time instant such that, only if a new
  42485. + * request is enqueued after this time instant in an
  42486. + * idle @bfq_queue with no outstanding requests, then
  42487. + * the task associated with the queue it is deemed as
  42488. + * soft real-time (see the comments to the function
  42489. + * bfq_bfqq_softrt_next_start())
  42490. + * @last_idle_bklogged: time of the last transition of the @bfq_queue from
  42491. + * idle to backlogged
  42492. + * @service_from_backlogged: cumulative service received from the @bfq_queue
  42493. + * since the last transition from idle to
  42494. + * backlogged
  42495. + * @bic: pointer to the bfq_io_cq owning the bfq_queue, set to %NULL if the
  42496. + * queue is shared
  42497. + *
  42498. + * A bfq_queue is a leaf request queue; it can be associated with an
  42499. + * io_context or more, if it is async or shared between cooperating
  42500. + * processes. @cgroup holds a reference to the cgroup, to be sure that it
  42501. + * does not disappear while a bfqq still references it (mostly to avoid
  42502. + * races between request issuing and task migration followed by cgroup
  42503. + * destruction).
  42504. + * All the fields are protected by the queue lock of the containing bfqd.
  42505. + */
  42506. +struct bfq_queue {
  42507. + atomic_t ref;
  42508. + struct bfq_data *bfqd;
  42509. +
  42510. + /* fields for cooperating queues handling */
  42511. + struct bfq_queue *new_bfqq;
  42512. + struct rb_node pos_node;
  42513. + struct rb_root *pos_root;
  42514. +
  42515. + struct rb_root sort_list;
  42516. + struct request *next_rq;
  42517. + int queued[2];
  42518. + int allocated[2];
  42519. + int meta_pending;
  42520. + struct list_head fifo;
  42521. +
  42522. + struct bfq_entity entity;
  42523. +
  42524. + unsigned long max_budget;
  42525. + unsigned long budget_timeout;
  42526. +
  42527. + int dispatched;
  42528. +
  42529. + unsigned int flags;
  42530. +
  42531. + struct list_head bfqq_list;
  42532. +
  42533. + unsigned int seek_samples;
  42534. + u64 seek_total;
  42535. + sector_t seek_mean;
  42536. + sector_t last_request_pos;
  42537. +
  42538. + unsigned int requests_within_timer;
  42539. +
  42540. + pid_t pid;
  42541. + struct bfq_io_cq *bic;
  42542. +
  42543. + /* weight-raising fields */
  42544. + unsigned long wr_cur_max_time;
  42545. + unsigned long soft_rt_next_start;
  42546. + unsigned long last_wr_start_finish;
  42547. + unsigned int wr_coeff;
  42548. + unsigned long last_idle_bklogged;
  42549. + unsigned long service_from_backlogged;
  42550. +};
  42551. +
  42552. +/**
  42553. + * struct bfq_ttime - per process thinktime stats.
  42554. + * @ttime_total: total process thinktime
  42555. + * @ttime_samples: number of thinktime samples
  42556. + * @ttime_mean: average process thinktime
  42557. + */
  42558. +struct bfq_ttime {
  42559. + unsigned long last_end_request;
  42560. +
  42561. + unsigned long ttime_total;
  42562. + unsigned long ttime_samples;
  42563. + unsigned long ttime_mean;
  42564. +};
  42565. +
  42566. +/**
  42567. + * struct bfq_io_cq - per (request_queue, io_context) structure.
  42568. + * @icq: associated io_cq structure
  42569. + * @bfqq: array of two process queues, the sync and the async
  42570. + * @ttime: associated @bfq_ttime struct
  42571. + * @wr_time_left: snapshot of the time left before weight raising ends
  42572. + * for the sync queue associated to this process; this
  42573. + * snapshot is taken to remember this value while the weight
  42574. + * raising is suspended because the queue is merged with a
  42575. + * shared queue, and is used to set @raising_cur_max_time
  42576. + * when the queue is split from the shared queue and its
  42577. + * weight is raised again
  42578. + * @saved_idle_window: same purpose as the previous field for the idle
  42579. + * window
  42580. + * @saved_IO_bound: same purpose as the previous two fields for the I/O
  42581. + * bound classification of a queue
  42582. + * @cooperations: counter of consecutive successful queue merges underwent
  42583. + * by any of the process' @bfq_queues
  42584. + * @failed_cooperations: counter of consecutive failed queue merges of any
  42585. + * of the process' @bfq_queues
  42586. + */
  42587. +struct bfq_io_cq {
  42588. + struct io_cq icq; /* must be the first member */
  42589. + struct bfq_queue *bfqq[2];
  42590. + struct bfq_ttime ttime;
  42591. + int ioprio;
  42592. +
  42593. + unsigned int wr_time_left;
  42594. + unsigned int saved_idle_window;
  42595. + unsigned int saved_IO_bound;
  42596. +
  42597. + unsigned int cooperations;
  42598. + unsigned int failed_cooperations;
  42599. +};
  42600. +
  42601. +enum bfq_device_speed {
  42602. + BFQ_BFQD_FAST,
  42603. + BFQ_BFQD_SLOW,
  42604. +};
  42605. +
  42606. +/**
  42607. + * struct bfq_data - per device data structure.
  42608. + * @queue: request queue for the managed device.
  42609. + * @root_group: root bfq_group for the device.
  42610. + * @rq_pos_tree: rbtree sorted by next_request position, used when
  42611. + * determining if two or more queues have interleaving
  42612. + * requests (see bfq_close_cooperator()).
  42613. + * @active_numerous_groups: number of bfq_groups containing more than one
  42614. + * active @bfq_entity.
  42615. + * @queue_weights_tree: rbtree of weight counters of @bfq_queues, sorted by
  42616. + * weight. Used to keep track of whether all @bfq_queues
  42617. + * have the same weight. The tree contains one counter
  42618. + * for each distinct weight associated to some active
  42619. + * and not weight-raised @bfq_queue (see the comments to
  42620. + * the functions bfq_weights_tree_[add|remove] for
  42621. + * further details).
  42622. + * @group_weights_tree: rbtree of non-queue @bfq_entity weight counters, sorted
  42623. + * by weight. Used to keep track of whether all
  42624. + * @bfq_groups have the same weight. The tree contains
  42625. + * one counter for each distinct weight associated to
  42626. + * some active @bfq_group (see the comments to the
  42627. + * functions bfq_weights_tree_[add|remove] for further
  42628. + * details).
  42629. + * @busy_queues: number of bfq_queues containing requests (including the
  42630. + * queue in service, even if it is idling).
  42631. + * @busy_in_flight_queues: number of @bfq_queues containing pending or
  42632. + * in-flight requests, plus the @bfq_queue in
  42633. + * service, even if idle but waiting for the
  42634. + * possible arrival of its next sync request. This
  42635. + * field is updated only if the device is rotational,
  42636. + * but used only if the device is also NCQ-capable.
  42637. + * The reason why the field is updated also for non-
  42638. + * NCQ-capable rotational devices is related to the
  42639. + * fact that the value of @hw_tag may be set also
  42640. + * later than when busy_in_flight_queues may need to
  42641. + * be incremented for the first time(s). Taking also
  42642. + * this possibility into account, to avoid unbalanced
  42643. + * increments/decrements, would imply more overhead
  42644. + * than just updating busy_in_flight_queues
  42645. + * regardless of the value of @hw_tag.
  42646. + * @const_seeky_busy_in_flight_queues: number of constantly-seeky @bfq_queues
  42647. + * (that is, seeky queues that expired
  42648. + * for budget timeout at least once)
  42649. + * containing pending or in-flight
  42650. + * requests, including the in-service
  42651. + * @bfq_queue if constantly seeky. This
  42652. + * field is updated only if the device
  42653. + * is rotational, but used only if the
  42654. + * device is also NCQ-capable (see the
  42655. + * comments to @busy_in_flight_queues).
  42656. + * @wr_busy_queues: number of weight-raised busy @bfq_queues.
  42657. + * @queued: number of queued requests.
  42658. + * @rq_in_driver: number of requests dispatched and waiting for completion.
  42659. + * @sync_flight: number of sync requests in the driver.
  42660. + * @max_rq_in_driver: max number of reqs in driver in the last
  42661. + * @hw_tag_samples completed requests.
  42662. + * @hw_tag_samples: nr of samples used to calculate hw_tag.
  42663. + * @hw_tag: flag set to one if the driver is showing a queueing behavior.
  42664. + * @budgets_assigned: number of budgets assigned.
  42665. + * @idle_slice_timer: timer set when idling for the next sequential request
  42666. + * from the queue in service.
  42667. + * @unplug_work: delayed work to restart dispatching on the request queue.
  42668. + * @in_service_queue: bfq_queue in service.
  42669. + * @in_service_bic: bfq_io_cq (bic) associated with the @in_service_queue.
  42670. + * @last_position: on-disk position of the last served request.
  42671. + * @last_budget_start: beginning of the last budget.
  42672. + * @last_idling_start: beginning of the last idle slice.
  42673. + * @peak_rate: peak transfer rate observed for a budget.
  42674. + * @peak_rate_samples: number of samples used to calculate @peak_rate.
  42675. + * @bfq_max_budget: maximum budget allotted to a bfq_queue before
  42676. + * rescheduling.
  42677. + * @group_list: list of all the bfq_groups active on the device.
  42678. + * @active_list: list of all the bfq_queues active on the device.
  42679. + * @idle_list: list of all the bfq_queues idle on the device.
  42680. + * @bfq_quantum: max number of requests dispatched per dispatch round.
  42681. + * @bfq_fifo_expire: timeout for async/sync requests; when it expires
  42682. + * requests are served in fifo order.
  42683. + * @bfq_back_penalty: weight of backward seeks wrt forward ones.
  42684. + * @bfq_back_max: maximum allowed backward seek.
  42685. + * @bfq_slice_idle: maximum idling time.
  42686. + * @bfq_user_max_budget: user-configured max budget value
  42687. + * (0 for auto-tuning).
  42688. + * @bfq_max_budget_async_rq: maximum budget (in nr of requests) allotted to
  42689. + * async queues.
  42690. + * @bfq_timeout: timeout for bfq_queues to consume their budget; used to
  42691. + * to prevent seeky queues to impose long latencies to well
  42692. + * behaved ones (this also implies that seeky queues cannot
  42693. + * receive guarantees in the service domain; after a timeout
  42694. + * they are charged for the whole allocated budget, to try
  42695. + * to preserve a behavior reasonably fair among them, but
  42696. + * without service-domain guarantees).
  42697. + * @bfq_coop_thresh: number of queue merges after which a @bfq_queue is
  42698. + * no more granted any weight-raising.
  42699. + * @bfq_failed_cooperations: number of consecutive failed cooperation
  42700. + * chances after which weight-raising is restored
  42701. + * to a queue subject to more than bfq_coop_thresh
  42702. + * queue merges.
  42703. + * @bfq_requests_within_timer: number of consecutive requests that must be
  42704. + * issued within the idle time slice to set
  42705. + * again idling to a queue which was marked as
  42706. + * non-I/O-bound (see the definition of the
  42707. + * IO_bound flag for further details).
  42708. + * @bfq_wr_coeff: Maximum factor by which the weight of a weight-raised
  42709. + * queue is multiplied
  42710. + * @bfq_wr_max_time: maximum duration of a weight-raising period (jiffies)
  42711. + * @bfq_wr_rt_max_time: maximum duration for soft real-time processes
  42712. + * @bfq_wr_min_idle_time: minimum idle period after which weight-raising
  42713. + * may be reactivated for a queue (in jiffies)
  42714. + * @bfq_wr_min_inter_arr_async: minimum period between request arrivals
  42715. + * after which weight-raising may be
  42716. + * reactivated for an already busy queue
  42717. + * (in jiffies)
  42718. + * @bfq_wr_max_softrt_rate: max service-rate for a soft real-time queue,
  42719. + * sectors per seconds
  42720. + * @RT_prod: cached value of the product R*T used for computing the maximum
  42721. + * duration of the weight raising automatically
  42722. + * @device_speed: device-speed class for the low-latency heuristic
  42723. + * @oom_bfqq: fallback dummy bfqq for extreme OOM conditions
  42724. + *
  42725. + * All the fields are protected by the @queue lock.
  42726. + */
  42727. +struct bfq_data {
  42728. + struct request_queue *queue;
  42729. +
  42730. + struct bfq_group *root_group;
  42731. + struct rb_root rq_pos_tree;
  42732. +
  42733. +#ifdef CONFIG_CGROUP_BFQIO
  42734. + int active_numerous_groups;
  42735. +#endif
  42736. +
  42737. + struct rb_root queue_weights_tree;
  42738. + struct rb_root group_weights_tree;
  42739. +
  42740. + int busy_queues;
  42741. + int busy_in_flight_queues;
  42742. + int const_seeky_busy_in_flight_queues;
  42743. + int wr_busy_queues;
  42744. + int queued;
  42745. + int rq_in_driver;
  42746. + int sync_flight;
  42747. +
  42748. + int max_rq_in_driver;
  42749. + int hw_tag_samples;
  42750. + int hw_tag;
  42751. +
  42752. + int budgets_assigned;
  42753. +
  42754. + struct timer_list idle_slice_timer;
  42755. + struct work_struct unplug_work;
  42756. +
  42757. + struct bfq_queue *in_service_queue;
  42758. + struct bfq_io_cq *in_service_bic;
  42759. +
  42760. + sector_t last_position;
  42761. +
  42762. + ktime_t last_budget_start;
  42763. + ktime_t last_idling_start;
  42764. + int peak_rate_samples;
  42765. + u64 peak_rate;
  42766. + unsigned long bfq_max_budget;
  42767. +
  42768. + struct hlist_head group_list;
  42769. + struct list_head active_list;
  42770. + struct list_head idle_list;
  42771. +
  42772. + unsigned int bfq_quantum;
  42773. + unsigned int bfq_fifo_expire[2];
  42774. + unsigned int bfq_back_penalty;
  42775. + unsigned int bfq_back_max;
  42776. + unsigned int bfq_slice_idle;
  42777. + u64 bfq_class_idle_last_service;
  42778. +
  42779. + unsigned int bfq_user_max_budget;
  42780. + unsigned int bfq_max_budget_async_rq;
  42781. + unsigned int bfq_timeout[2];
  42782. +
  42783. + unsigned int bfq_coop_thresh;
  42784. + unsigned int bfq_failed_cooperations;
  42785. + unsigned int bfq_requests_within_timer;
  42786. +
  42787. + bool low_latency;
  42788. +
  42789. + /* parameters of the low_latency heuristics */
  42790. + unsigned int bfq_wr_coeff;
  42791. + unsigned int bfq_wr_max_time;
  42792. + unsigned int bfq_wr_rt_max_time;
  42793. + unsigned int bfq_wr_min_idle_time;
  42794. + unsigned long bfq_wr_min_inter_arr_async;
  42795. + unsigned int bfq_wr_max_softrt_rate;
  42796. + u64 RT_prod;
  42797. + enum bfq_device_speed device_speed;
  42798. +
  42799. + struct bfq_queue oom_bfqq;
  42800. +};
  42801. +
  42802. +enum bfqq_state_flags {
  42803. + BFQ_BFQQ_FLAG_busy = 0, /* has requests or is in service */
  42804. + BFQ_BFQQ_FLAG_wait_request, /* waiting for a request */
  42805. + BFQ_BFQQ_FLAG_must_alloc, /* must be allowed rq alloc */
  42806. + BFQ_BFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */
  42807. + BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */
  42808. + BFQ_BFQQ_FLAG_prio_changed, /* task priority has changed */
  42809. + BFQ_BFQQ_FLAG_sync, /* synchronous queue */
  42810. + BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */
  42811. + BFQ_BFQQ_FLAG_IO_bound, /*
  42812. + * bfqq has timed-out at least once
  42813. + * having consumed at most 2/10 of
  42814. + * its budget
  42815. + */
  42816. + BFQ_BFQQ_FLAG_constantly_seeky, /*
  42817. + * bfqq has proved to be slow and
  42818. + * seeky until budget timeout
  42819. + */
  42820. + BFQ_BFQQ_FLAG_softrt_update, /*
  42821. + * may need softrt-next-start
  42822. + * update
  42823. + */
  42824. + BFQ_BFQQ_FLAG_coop, /* bfqq is shared */
  42825. + BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be split */
  42826. + BFQ_BFQQ_FLAG_just_split, /* queue has just been split */
  42827. +};
  42828. +
  42829. +#define BFQ_BFQQ_FNS(name) \
  42830. +static inline void bfq_mark_bfqq_##name(struct bfq_queue *bfqq) \
  42831. +{ \
  42832. + (bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name); \
  42833. +} \
  42834. +static inline void bfq_clear_bfqq_##name(struct bfq_queue *bfqq) \
  42835. +{ \
  42836. + (bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name); \
  42837. +} \
  42838. +static inline int bfq_bfqq_##name(const struct bfq_queue *bfqq) \
  42839. +{ \
  42840. + return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \
  42841. +}
  42842. +
  42843. +BFQ_BFQQ_FNS(busy);
  42844. +BFQ_BFQQ_FNS(wait_request);
  42845. +BFQ_BFQQ_FNS(must_alloc);
  42846. +BFQ_BFQQ_FNS(fifo_expire);
  42847. +BFQ_BFQQ_FNS(idle_window);
  42848. +BFQ_BFQQ_FNS(prio_changed);
  42849. +BFQ_BFQQ_FNS(sync);
  42850. +BFQ_BFQQ_FNS(budget_new);
  42851. +BFQ_BFQQ_FNS(IO_bound);
  42852. +BFQ_BFQQ_FNS(constantly_seeky);
  42853. +BFQ_BFQQ_FNS(coop);
  42854. +BFQ_BFQQ_FNS(split_coop);
  42855. +BFQ_BFQQ_FNS(just_split);
  42856. +BFQ_BFQQ_FNS(softrt_update);
  42857. +#undef BFQ_BFQQ_FNS
  42858. +
  42859. +/* Logging facilities. */
  42860. +#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \
  42861. + blk_add_trace_msg((bfqd)->queue, "bfq%d " fmt, (bfqq)->pid, ##args)
  42862. +
  42863. +#define bfq_log(bfqd, fmt, args...) \
  42864. + blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args)
  42865. +
  42866. +/* Expiration reasons. */
  42867. +enum bfqq_expiration {
  42868. + BFQ_BFQQ_TOO_IDLE = 0, /*
  42869. + * queue has been idling for
  42870. + * too long
  42871. + */
  42872. + BFQ_BFQQ_BUDGET_TIMEOUT, /* budget took too long to be used */
  42873. + BFQ_BFQQ_BUDGET_EXHAUSTED, /* budget consumed */
  42874. + BFQ_BFQQ_NO_MORE_REQUESTS, /* the queue has no more requests */
  42875. +};
  42876. +
  42877. +#ifdef CONFIG_CGROUP_BFQIO
  42878. +/**
  42879. + * struct bfq_group - per (device, cgroup) data structure.
  42880. + * @entity: schedulable entity to insert into the parent group sched_data.
  42881. + * @sched_data: own sched_data, to contain child entities (they may be
  42882. + * both bfq_queues and bfq_groups).
  42883. + * @group_node: node to be inserted into the bfqio_cgroup->group_data
  42884. + * list of the containing cgroup's bfqio_cgroup.
  42885. + * @bfqd_node: node to be inserted into the @bfqd->group_list list
  42886. + * of the groups active on the same device; used for cleanup.
  42887. + * @bfqd: the bfq_data for the device this group acts upon.
  42888. + * @async_bfqq: array of async queues for all the tasks belonging to
  42889. + * the group, one queue per ioprio value per ioprio_class,
  42890. + * except for the idle class that has only one queue.
  42891. + * @async_idle_bfqq: async queue for the idle class (ioprio is ignored).
  42892. + * @my_entity: pointer to @entity, %NULL for the toplevel group; used
  42893. + * to avoid too many special cases during group creation/
  42894. + * migration.
  42895. + * @active_entities: number of active entities belonging to the group;
  42896. + * unused for the root group. Used to know whether there
  42897. + * are groups with more than one active @bfq_entity
  42898. + * (see the comments to the function
  42899. + * bfq_bfqq_must_not_expire()).
  42900. + *
  42901. + * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup
  42902. + * there is a set of bfq_groups, each one collecting the lower-level
  42903. + * entities belonging to the group that are acting on the same device.
  42904. + *
  42905. + * Locking works as follows:
  42906. + * o @group_node is protected by the bfqio_cgroup lock, and is accessed
  42907. + * via RCU from its readers.
  42908. + * o @bfqd is protected by the queue lock, RCU is used to access it
  42909. + * from the readers.
  42910. + * o All the other fields are protected by the @bfqd queue lock.
  42911. + */
  42912. +struct bfq_group {
  42913. + struct bfq_entity entity;
  42914. + struct bfq_sched_data sched_data;
  42915. +
  42916. + struct hlist_node group_node;
  42917. + struct hlist_node bfqd_node;
  42918. +
  42919. + void *bfqd;
  42920. +
  42921. + struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR];
  42922. + struct bfq_queue *async_idle_bfqq;
  42923. +
  42924. + struct bfq_entity *my_entity;
  42925. +
  42926. + int active_entities;
  42927. +};
  42928. +
  42929. +/**
  42930. + * struct bfqio_cgroup - bfq cgroup data structure.
  42931. + * @css: subsystem state for bfq in the containing cgroup.
  42932. + * @online: flag marked when the subsystem is inserted.
  42933. + * @weight: cgroup weight.
  42934. + * @ioprio: cgroup ioprio.
  42935. + * @ioprio_class: cgroup ioprio_class.
  42936. + * @lock: spinlock that protects @ioprio, @ioprio_class and @group_data.
  42937. + * @group_data: list containing the bfq_group belonging to this cgroup.
  42938. + *
  42939. + * @group_data is accessed using RCU, with @lock protecting the updates,
  42940. + * @ioprio and @ioprio_class are protected by @lock.
  42941. + */
  42942. +struct bfqio_cgroup {
  42943. + struct cgroup_subsys_state css;
  42944. + bool online;
  42945. +
  42946. + unsigned short weight, ioprio, ioprio_class;
  42947. +
  42948. + spinlock_t lock;
  42949. + struct hlist_head group_data;
  42950. +};
  42951. +#else
  42952. +struct bfq_group {
  42953. + struct bfq_sched_data sched_data;
  42954. +
  42955. + struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR];
  42956. + struct bfq_queue *async_idle_bfqq;
  42957. +};
  42958. +#endif
  42959. +
  42960. +static inline struct bfq_service_tree *
  42961. +bfq_entity_service_tree(struct bfq_entity *entity)
  42962. +{
  42963. + struct bfq_sched_data *sched_data = entity->sched_data;
  42964. + unsigned int idx = entity->ioprio_class - 1;
  42965. +
  42966. + BUG_ON(idx >= BFQ_IOPRIO_CLASSES);
  42967. + BUG_ON(sched_data == NULL);
  42968. +
  42969. + return sched_data->service_tree + idx;
  42970. +}
  42971. +
  42972. +static inline struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic,
  42973. + int is_sync)
  42974. +{
  42975. + return bic->bfqq[!!is_sync];
  42976. +}
  42977. +
  42978. +static inline void bic_set_bfqq(struct bfq_io_cq *bic,
  42979. + struct bfq_queue *bfqq, int is_sync)
  42980. +{
  42981. + bic->bfqq[!!is_sync] = bfqq;
  42982. +}
  42983. +
  42984. +static inline struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic)
  42985. +{
  42986. + return bic->icq.q->elevator->elevator_data;
  42987. +}
  42988. +
  42989. +/**
  42990. + * bfq_get_bfqd_locked - get a lock to a bfqd using a RCU protected pointer.
  42991. + * @ptr: a pointer to a bfqd.
  42992. + * @flags: storage for the flags to be saved.
  42993. + *
  42994. + * This function allows bfqg->bfqd to be protected by the
  42995. + * queue lock of the bfqd they reference; the pointer is dereferenced
  42996. + * under RCU, so the storage for bfqd is assured to be safe as long
  42997. + * as the RCU read side critical section does not end. After the
  42998. + * bfqd->queue->queue_lock is taken the pointer is rechecked, to be
  42999. + * sure that no other writer accessed it. If we raced with a writer,
  43000. + * the function returns NULL, with the queue unlocked, otherwise it
  43001. + * returns the dereferenced pointer, with the queue locked.
  43002. + */
  43003. +static inline struct bfq_data *bfq_get_bfqd_locked(void **ptr,
  43004. + unsigned long *flags)
  43005. +{
  43006. + struct bfq_data *bfqd;
  43007. +
  43008. + rcu_read_lock();
  43009. + bfqd = rcu_dereference(*(struct bfq_data **)ptr);
  43010. +
  43011. + if (bfqd != NULL) {
  43012. + spin_lock_irqsave(bfqd->queue->queue_lock, *flags);
  43013. + if (*ptr == bfqd)
  43014. + goto out;
  43015. + spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags);
  43016. + }
  43017. +
  43018. + bfqd = NULL;
  43019. +out:
  43020. + rcu_read_unlock();
  43021. + return bfqd;
  43022. +}
  43023. +
  43024. +static inline void bfq_put_bfqd_unlock(struct bfq_data *bfqd,
  43025. + unsigned long *flags)
  43026. +{
  43027. + spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags);
  43028. +}
  43029. +
  43030. +static void bfq_changed_ioprio(struct bfq_io_cq *bic);
  43031. +static void bfq_put_queue(struct bfq_queue *bfqq);
  43032. +static void bfq_dispatch_insert(struct request_queue *q, struct request *rq);
  43033. +static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
  43034. + struct bfq_group *bfqg, int is_sync,
  43035. + struct bfq_io_cq *bic, gfp_t gfp_mask);
  43036. +static void bfq_end_wr_async_queues(struct bfq_data *bfqd,
  43037. + struct bfq_group *bfqg);
  43038. +static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg);
  43039. +static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq);
  43040. +
  43041. +#endif /* _BFQ_H */
  43042. diff -Nur linux-3.14.14/block/bfq-ioc.c linux-imx6-3.14/block/bfq-ioc.c
  43043. --- linux-3.14.14/block/bfq-ioc.c 1969-12-31 18:00:00.000000000 -0600
  43044. +++ linux-imx6-3.14/block/bfq-ioc.c 2014-12-08 00:31:52.364418001 -0600
  43045. @@ -0,0 +1,36 @@
  43046. +/*
  43047. + * BFQ: I/O context handling.
  43048. + *
  43049. + * Based on ideas and code from CFQ:
  43050. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  43051. + *
  43052. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  43053. + * Paolo Valente <paolo.valente@unimore.it>
  43054. + *
  43055. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  43056. + */
  43057. +
  43058. +/**
  43059. + * icq_to_bic - convert iocontext queue structure to bfq_io_cq.
  43060. + * @icq: the iocontext queue.
  43061. + */
  43062. +static inline struct bfq_io_cq *icq_to_bic(struct io_cq *icq)
  43063. +{
  43064. + /* bic->icq is the first member, %NULL will convert to %NULL */
  43065. + return container_of(icq, struct bfq_io_cq, icq);
  43066. +}
  43067. +
  43068. +/**
  43069. + * bfq_bic_lookup - search into @ioc a bic associated to @bfqd.
  43070. + * @bfqd: the lookup key.
  43071. + * @ioc: the io_context of the process doing I/O.
  43072. + *
  43073. + * Queue lock must be held.
  43074. + */
  43075. +static inline struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd,
  43076. + struct io_context *ioc)
  43077. +{
  43078. + if (ioc)
  43079. + return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue));
  43080. + return NULL;
  43081. +}
  43082. diff -Nur linux-3.14.14/block/bfq-iosched.c linux-imx6-3.14/block/bfq-iosched.c
  43083. --- linux-3.14.14/block/bfq-iosched.c 1969-12-31 18:00:00.000000000 -0600
  43084. +++ linux-imx6-3.14/block/bfq-iosched.c 2014-12-08 00:31:52.364418001 -0600
  43085. @@ -0,0 +1,3919 @@
  43086. +/*
  43087. + * Budget Fair Queueing (BFQ) disk scheduler.
  43088. + *
  43089. + * Based on ideas and code from CFQ:
  43090. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  43091. + *
  43092. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  43093. + * Paolo Valente <paolo.valente@unimore.it>
  43094. + *
  43095. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  43096. + *
  43097. + * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
  43098. + * file.
  43099. + *
  43100. + * BFQ is a proportional-share storage-I/O scheduling algorithm based on
  43101. + * the slice-by-slice service scheme of CFQ. But BFQ assigns budgets,
  43102. + * measured in number of sectors, to processes instead of time slices. The
  43103. + * device is not granted to the in-service process for a given time slice,
  43104. + * but until it has exhausted its assigned budget. This change from the time
  43105. + * to the service domain allows BFQ to distribute the device throughput
  43106. + * among processes as desired, without any distortion due to ZBR, workload
  43107. + * fluctuations or other factors. BFQ uses an ad hoc internal scheduler,
  43108. + * called B-WF2Q+, to schedule processes according to their budgets. More
  43109. + * precisely, BFQ schedules queues associated to processes. Thanks to the
  43110. + * accurate policy of B-WF2Q+, BFQ can afford to assign high budgets to
  43111. + * I/O-bound processes issuing sequential requests (to boost the
  43112. + * throughput), and yet guarantee a low latency to interactive and soft
  43113. + * real-time applications.
  43114. + *
  43115. + * BFQ is described in [1], where also a reference to the initial, more
  43116. + * theoretical paper on BFQ can be found. The interested reader can find
  43117. + * in the latter paper full details on the main algorithm, as well as
  43118. + * formulas of the guarantees and formal proofs of all the properties.
  43119. + * With respect to the version of BFQ presented in these papers, this
  43120. + * implementation adds a few more heuristics, such as the one that
  43121. + * guarantees a low latency to soft real-time applications, and a
  43122. + * hierarchical extension based on H-WF2Q+.
  43123. + *
  43124. + * B-WF2Q+ is based on WF2Q+, that is described in [2], together with
  43125. + * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N)
  43126. + * complexity derives from the one introduced with EEVDF in [3].
  43127. + *
  43128. + * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness
  43129. + * with the BFQ Disk I/O Scheduler'',
  43130. + * Proceedings of the 5th Annual International Systems and Storage
  43131. + * Conference (SYSTOR '12), June 2012.
  43132. + *
  43133. + * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf
  43134. + *
  43135. + * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing
  43136. + * Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689,
  43137. + * Oct 1997.
  43138. + *
  43139. + * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz
  43140. + *
  43141. + * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline
  43142. + * First: A Flexible and Accurate Mechanism for Proportional Share
  43143. + * Resource Allocation,'' technical report.
  43144. + *
  43145. + * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf
  43146. + */
  43147. +#include <linux/module.h>
  43148. +#include <linux/slab.h>
  43149. +#include <linux/blkdev.h>
  43150. +#include <linux/cgroup.h>
  43151. +#include <linux/elevator.h>
  43152. +#include <linux/jiffies.h>
  43153. +#include <linux/rbtree.h>
  43154. +#include <linux/ioprio.h>
  43155. +#include "bfq.h"
  43156. +#include "blk.h"
  43157. +
  43158. +/* Max number of dispatches in one round of service. */
  43159. +static const int bfq_quantum = 4;
  43160. +
  43161. +/* Expiration time of sync (0) and async (1) requests, in jiffies. */
  43162. +static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
  43163. +
  43164. +/* Maximum backwards seek, in KiB. */
  43165. +static const int bfq_back_max = 16 * 1024;
  43166. +
  43167. +/* Penalty of a backwards seek, in number of sectors. */
  43168. +static const int bfq_back_penalty = 2;
  43169. +
  43170. +/* Idling period duration, in jiffies. */
  43171. +static int bfq_slice_idle = HZ / 125;
  43172. +
  43173. +/* Default maximum budget values, in sectors and number of requests. */
  43174. +static const int bfq_default_max_budget = 16 * 1024;
  43175. +static const int bfq_max_budget_async_rq = 4;
  43176. +
  43177. +/*
  43178. + * Async to sync throughput distribution is controlled as follows:
  43179. + * when an async request is served, the entity is charged the number
  43180. + * of sectors of the request, multiplied by the factor below
  43181. + */
  43182. +static const int bfq_async_charge_factor = 10;
  43183. +
  43184. +/* Default timeout values, in jiffies, approximating CFQ defaults. */
  43185. +static const int bfq_timeout_sync = HZ / 8;
  43186. +static int bfq_timeout_async = HZ / 25;
  43187. +
  43188. +struct kmem_cache *bfq_pool;
  43189. +
  43190. +/* Below this threshold (in ms), we consider thinktime immediate. */
  43191. +#define BFQ_MIN_TT 2
  43192. +
  43193. +/* hw_tag detection: parallel requests threshold and min samples needed. */
  43194. +#define BFQ_HW_QUEUE_THRESHOLD 4
  43195. +#define BFQ_HW_QUEUE_SAMPLES 32
  43196. +
  43197. +#define BFQQ_SEEK_THR (sector_t)(8 * 1024)
  43198. +#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR)
  43199. +
  43200. +/* Min samples used for peak rate estimation (for autotuning). */
  43201. +#define BFQ_PEAK_RATE_SAMPLES 32
  43202. +
  43203. +/* Shift used for peak rate fixed precision calculations. */
  43204. +#define BFQ_RATE_SHIFT 16
  43205. +
  43206. +/*
  43207. + * By default, BFQ computes the duration of the weight raising for
  43208. + * interactive applications automatically, using the following formula:
  43209. + * duration = (R / r) * T, where r is the peak rate of the device, and
  43210. + * R and T are two reference parameters.
  43211. + * In particular, R is the peak rate of the reference device (see below),
  43212. + * and T is a reference time: given the systems that are likely to be
  43213. + * installed on the reference device according to its speed class, T is
  43214. + * about the maximum time needed, under BFQ and while reading two files in
  43215. + * parallel, to load typical large applications on these systems.
  43216. + * In practice, the slower/faster the device at hand is, the more/less it
  43217. + * takes to load applications with respect to the reference device.
  43218. + * Accordingly, the longer/shorter BFQ grants weight raising to interactive
  43219. + * applications.
  43220. + *
  43221. + * BFQ uses four different reference pairs (R, T), depending on:
  43222. + * . whether the device is rotational or non-rotational;
  43223. + * . whether the device is slow, such as old or portable HDDs, as well as
  43224. + * SD cards, or fast, such as newer HDDs and SSDs.
  43225. + *
  43226. + * The device's speed class is dynamically (re)detected in
  43227. + * bfq_update_peak_rate() every time the estimated peak rate is updated.
  43228. + *
  43229. + * In the following definitions, R_slow[0]/R_fast[0] and T_slow[0]/T_fast[0]
  43230. + * are the reference values for a slow/fast rotational device, whereas
  43231. + * R_slow[1]/R_fast[1] and T_slow[1]/T_fast[1] are the reference values for
  43232. + * a slow/fast non-rotational device. Finally, device_speed_thresh are the
  43233. + * thresholds used to switch between speed classes.
  43234. + * Both the reference peak rates and the thresholds are measured in
  43235. + * sectors/usec, left-shifted by BFQ_RATE_SHIFT.
  43236. + */
  43237. +static int R_slow[2] = {1536, 10752};
  43238. +static int R_fast[2] = {17415, 34791};
  43239. +/*
  43240. + * To improve readability, a conversion function is used to initialize the
  43241. + * following arrays, which entails that they can be initialized only in a
  43242. + * function.
  43243. + */
  43244. +static int T_slow[2];
  43245. +static int T_fast[2];
  43246. +static int device_speed_thresh[2];
  43247. +
  43248. +#define BFQ_SERVICE_TREE_INIT ((struct bfq_service_tree) \
  43249. + { RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 })
  43250. +
  43251. +#define RQ_BIC(rq) ((struct bfq_io_cq *) (rq)->elv.priv[0])
  43252. +#define RQ_BFQQ(rq) ((rq)->elv.priv[1])
  43253. +
  43254. +static inline void bfq_schedule_dispatch(struct bfq_data *bfqd);
  43255. +
  43256. +#include "bfq-ioc.c"
  43257. +#include "bfq-sched.c"
  43258. +#include "bfq-cgroup.c"
  43259. +
  43260. +#define bfq_class_idle(bfqq) ((bfqq)->entity.ioprio_class ==\
  43261. + IOPRIO_CLASS_IDLE)
  43262. +#define bfq_class_rt(bfqq) ((bfqq)->entity.ioprio_class ==\
  43263. + IOPRIO_CLASS_RT)
  43264. +
  43265. +#define bfq_sample_valid(samples) ((samples) > 80)
  43266. +
  43267. +/*
  43268. + * We regard a request as SYNC, if either it's a read or has the SYNC bit
  43269. + * set (in which case it could also be a direct WRITE).
  43270. + */
  43271. +static inline int bfq_bio_sync(struct bio *bio)
  43272. +{
  43273. + if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC))
  43274. + return 1;
  43275. +
  43276. + return 0;
  43277. +}
  43278. +
  43279. +/*
  43280. + * Scheduler run of queue, if there are requests pending and no one in the
  43281. + * driver that will restart queueing.
  43282. + */
  43283. +static inline void bfq_schedule_dispatch(struct bfq_data *bfqd)
  43284. +{
  43285. + if (bfqd->queued != 0) {
  43286. + bfq_log(bfqd, "schedule dispatch");
  43287. + kblockd_schedule_work(bfqd->queue, &bfqd->unplug_work);
  43288. + }
  43289. +}
  43290. +
  43291. +/*
  43292. + * Lifted from AS - choose which of rq1 and rq2 that is best served now.
  43293. + * We choose the request that is closesr to the head right now. Distance
  43294. + * behind the head is penalized and only allowed to a certain extent.
  43295. + */
  43296. +static struct request *bfq_choose_req(struct bfq_data *bfqd,
  43297. + struct request *rq1,
  43298. + struct request *rq2,
  43299. + sector_t last)
  43300. +{
  43301. + sector_t s1, s2, d1 = 0, d2 = 0;
  43302. + unsigned long back_max;
  43303. +#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */
  43304. +#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */
  43305. + unsigned wrap = 0; /* bit mask: requests behind the disk head? */
  43306. +
  43307. + if (rq1 == NULL || rq1 == rq2)
  43308. + return rq2;
  43309. + if (rq2 == NULL)
  43310. + return rq1;
  43311. +
  43312. + if (rq_is_sync(rq1) && !rq_is_sync(rq2))
  43313. + return rq1;
  43314. + else if (rq_is_sync(rq2) && !rq_is_sync(rq1))
  43315. + return rq2;
  43316. + if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META))
  43317. + return rq1;
  43318. + else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META))
  43319. + return rq2;
  43320. +
  43321. + s1 = blk_rq_pos(rq1);
  43322. + s2 = blk_rq_pos(rq2);
  43323. +
  43324. + /*
  43325. + * By definition, 1KiB is 2 sectors.
  43326. + */
  43327. + back_max = bfqd->bfq_back_max * 2;
  43328. +
  43329. + /*
  43330. + * Strict one way elevator _except_ in the case where we allow
  43331. + * short backward seeks which are biased as twice the cost of a
  43332. + * similar forward seek.
  43333. + */
  43334. + if (s1 >= last)
  43335. + d1 = s1 - last;
  43336. + else if (s1 + back_max >= last)
  43337. + d1 = (last - s1) * bfqd->bfq_back_penalty;
  43338. + else
  43339. + wrap |= BFQ_RQ1_WRAP;
  43340. +
  43341. + if (s2 >= last)
  43342. + d2 = s2 - last;
  43343. + else if (s2 + back_max >= last)
  43344. + d2 = (last - s2) * bfqd->bfq_back_penalty;
  43345. + else
  43346. + wrap |= BFQ_RQ2_WRAP;
  43347. +
  43348. + /* Found required data */
  43349. +
  43350. + /*
  43351. + * By doing switch() on the bit mask "wrap" we avoid having to
  43352. + * check two variables for all permutations: --> faster!
  43353. + */
  43354. + switch (wrap) {
  43355. + case 0: /* common case for CFQ: rq1 and rq2 not wrapped */
  43356. + if (d1 < d2)
  43357. + return rq1;
  43358. + else if (d2 < d1)
  43359. + return rq2;
  43360. + else {
  43361. + if (s1 >= s2)
  43362. + return rq1;
  43363. + else
  43364. + return rq2;
  43365. + }
  43366. +
  43367. + case BFQ_RQ2_WRAP:
  43368. + return rq1;
  43369. + case BFQ_RQ1_WRAP:
  43370. + return rq2;
  43371. + case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */
  43372. + default:
  43373. + /*
  43374. + * Since both rqs are wrapped,
  43375. + * start with the one that's further behind head
  43376. + * (--> only *one* back seek required),
  43377. + * since back seek takes more time than forward.
  43378. + */
  43379. + if (s1 <= s2)
  43380. + return rq1;
  43381. + else
  43382. + return rq2;
  43383. + }
  43384. +}
  43385. +
  43386. +static struct bfq_queue *
  43387. +bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root,
  43388. + sector_t sector, struct rb_node **ret_parent,
  43389. + struct rb_node ***rb_link)
  43390. +{
  43391. + struct rb_node **p, *parent;
  43392. + struct bfq_queue *bfqq = NULL;
  43393. +
  43394. + parent = NULL;
  43395. + p = &root->rb_node;
  43396. + while (*p) {
  43397. + struct rb_node **n;
  43398. +
  43399. + parent = *p;
  43400. + bfqq = rb_entry(parent, struct bfq_queue, pos_node);
  43401. +
  43402. + /*
  43403. + * Sort strictly based on sector. Smallest to the left,
  43404. + * largest to the right.
  43405. + */
  43406. + if (sector > blk_rq_pos(bfqq->next_rq))
  43407. + n = &(*p)->rb_right;
  43408. + else if (sector < blk_rq_pos(bfqq->next_rq))
  43409. + n = &(*p)->rb_left;
  43410. + else
  43411. + break;
  43412. + p = n;
  43413. + bfqq = NULL;
  43414. + }
  43415. +
  43416. + *ret_parent = parent;
  43417. + if (rb_link)
  43418. + *rb_link = p;
  43419. +
  43420. + bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d",
  43421. + (long long unsigned)sector,
  43422. + bfqq != NULL ? bfqq->pid : 0);
  43423. +
  43424. + return bfqq;
  43425. +}
  43426. +
  43427. +static void bfq_rq_pos_tree_add(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  43428. +{
  43429. + struct rb_node **p, *parent;
  43430. + struct bfq_queue *__bfqq;
  43431. +
  43432. + if (bfqq->pos_root != NULL) {
  43433. + rb_erase(&bfqq->pos_node, bfqq->pos_root);
  43434. + bfqq->pos_root = NULL;
  43435. + }
  43436. +
  43437. + if (bfq_class_idle(bfqq))
  43438. + return;
  43439. + if (!bfqq->next_rq)
  43440. + return;
  43441. +
  43442. + bfqq->pos_root = &bfqd->rq_pos_tree;
  43443. + __bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root,
  43444. + blk_rq_pos(bfqq->next_rq), &parent, &p);
  43445. + if (__bfqq == NULL) {
  43446. + rb_link_node(&bfqq->pos_node, parent, p);
  43447. + rb_insert_color(&bfqq->pos_node, bfqq->pos_root);
  43448. + } else
  43449. + bfqq->pos_root = NULL;
  43450. +}
  43451. +
  43452. +/*
  43453. + * Tell whether there are active queues or groups with differentiated weights.
  43454. + */
  43455. +static inline bool bfq_differentiated_weights(struct bfq_data *bfqd)
  43456. +{
  43457. + BUG_ON(!bfqd->hw_tag);
  43458. + /*
  43459. + * For weights to differ, at least one of the trees must contain
  43460. + * at least two nodes.
  43461. + */
  43462. + return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) &&
  43463. + (bfqd->queue_weights_tree.rb_node->rb_left ||
  43464. + bfqd->queue_weights_tree.rb_node->rb_right)
  43465. +#ifdef CONFIG_CGROUP_BFQIO
  43466. + ) ||
  43467. + (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) &&
  43468. + (bfqd->group_weights_tree.rb_node->rb_left ||
  43469. + bfqd->group_weights_tree.rb_node->rb_right)
  43470. +#endif
  43471. + );
  43472. +}
  43473. +
  43474. +/*
  43475. + * If the weight-counter tree passed as input contains no counter for
  43476. + * the weight of the input entity, then add that counter; otherwise just
  43477. + * increment the existing counter.
  43478. + *
  43479. + * Note that weight-counter trees contain few nodes in mostly symmetric
  43480. + * scenarios. For example, if all queues have the same weight, then the
  43481. + * weight-counter tree for the queues may contain at most one node.
  43482. + * This holds even if low_latency is on, because weight-raised queues
  43483. + * are not inserted in the tree.
  43484. + * In most scenarios, the rate at which nodes are created/destroyed
  43485. + * should be low too.
  43486. + */
  43487. +static void bfq_weights_tree_add(struct bfq_data *bfqd,
  43488. + struct bfq_entity *entity,
  43489. + struct rb_root *root)
  43490. +{
  43491. + struct rb_node **new = &(root->rb_node), *parent = NULL;
  43492. +
  43493. + /*
  43494. + * Do not insert if:
  43495. + * - the device does not support queueing;
  43496. + * - the entity is already associated with a counter, which happens if:
  43497. + * 1) the entity is associated with a queue, 2) a request arrival
  43498. + * has caused the queue to become both non-weight-raised, and hence
  43499. + * change its weight, and backlogged; in this respect, each
  43500. + * of the two events causes an invocation of this function,
  43501. + * 3) this is the invocation of this function caused by the second
  43502. + * event. This second invocation is actually useless, and we handle
  43503. + * this fact by exiting immediately. More efficient or clearer
  43504. + * solutions might possibly be adopted.
  43505. + */
  43506. + if (!bfqd->hw_tag || entity->weight_counter)
  43507. + return;
  43508. +
  43509. + while (*new) {
  43510. + struct bfq_weight_counter *__counter = container_of(*new,
  43511. + struct bfq_weight_counter,
  43512. + weights_node);
  43513. + parent = *new;
  43514. +
  43515. + if (entity->weight == __counter->weight) {
  43516. + entity->weight_counter = __counter;
  43517. + goto inc_counter;
  43518. + }
  43519. + if (entity->weight < __counter->weight)
  43520. + new = &((*new)->rb_left);
  43521. + else
  43522. + new = &((*new)->rb_right);
  43523. + }
  43524. +
  43525. + entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter),
  43526. + GFP_ATOMIC);
  43527. + entity->weight_counter->weight = entity->weight;
  43528. + rb_link_node(&entity->weight_counter->weights_node, parent, new);
  43529. + rb_insert_color(&entity->weight_counter->weights_node, root);
  43530. +
  43531. +inc_counter:
  43532. + entity->weight_counter->num_active++;
  43533. +}
  43534. +
  43535. +/*
  43536. + * Decrement the weight counter associated with the entity, and, if the
  43537. + * counter reaches 0, remove the counter from the tree.
  43538. + * See the comments to the function bfq_weights_tree_add() for considerations
  43539. + * about overhead.
  43540. + */
  43541. +static void bfq_weights_tree_remove(struct bfq_data *bfqd,
  43542. + struct bfq_entity *entity,
  43543. + struct rb_root *root)
  43544. +{
  43545. + /*
  43546. + * Check whether the entity is actually associated with a counter.
  43547. + * In fact, the device may not be considered NCQ-capable for a while,
  43548. + * which implies that no insertion in the weight trees is performed,
  43549. + * after which the device may start to be deemed NCQ-capable, and hence
  43550. + * this function may start to be invoked. This may cause the function
  43551. + * to be invoked for entities that are not associated with any counter.
  43552. + */
  43553. + if (!entity->weight_counter)
  43554. + return;
  43555. +
  43556. + BUG_ON(RB_EMPTY_ROOT(root));
  43557. + BUG_ON(entity->weight_counter->weight != entity->weight);
  43558. +
  43559. + BUG_ON(!entity->weight_counter->num_active);
  43560. + entity->weight_counter->num_active--;
  43561. + if (entity->weight_counter->num_active > 0)
  43562. + goto reset_entity_pointer;
  43563. +
  43564. + rb_erase(&entity->weight_counter->weights_node, root);
  43565. + kfree(entity->weight_counter);
  43566. +
  43567. +reset_entity_pointer:
  43568. + entity->weight_counter = NULL;
  43569. +}
  43570. +
  43571. +static struct request *bfq_find_next_rq(struct bfq_data *bfqd,
  43572. + struct bfq_queue *bfqq,
  43573. + struct request *last)
  43574. +{
  43575. + struct rb_node *rbnext = rb_next(&last->rb_node);
  43576. + struct rb_node *rbprev = rb_prev(&last->rb_node);
  43577. + struct request *next = NULL, *prev = NULL;
  43578. +
  43579. + BUG_ON(RB_EMPTY_NODE(&last->rb_node));
  43580. +
  43581. + if (rbprev != NULL)
  43582. + prev = rb_entry_rq(rbprev);
  43583. +
  43584. + if (rbnext != NULL)
  43585. + next = rb_entry_rq(rbnext);
  43586. + else {
  43587. + rbnext = rb_first(&bfqq->sort_list);
  43588. + if (rbnext && rbnext != &last->rb_node)
  43589. + next = rb_entry_rq(rbnext);
  43590. + }
  43591. +
  43592. + return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last));
  43593. +}
  43594. +
  43595. +/* see the definition of bfq_async_charge_factor for details */
  43596. +static inline unsigned long bfq_serv_to_charge(struct request *rq,
  43597. + struct bfq_queue *bfqq)
  43598. +{
  43599. + return blk_rq_sectors(rq) *
  43600. + (1 + ((!bfq_bfqq_sync(bfqq)) * (bfqq->wr_coeff == 1) *
  43601. + bfq_async_charge_factor));
  43602. +}
  43603. +
  43604. +/**
  43605. + * bfq_updated_next_req - update the queue after a new next_rq selection.
  43606. + * @bfqd: the device data the queue belongs to.
  43607. + * @bfqq: the queue to update.
  43608. + *
  43609. + * If the first request of a queue changes we make sure that the queue
  43610. + * has enough budget to serve at least its first request (if the
  43611. + * request has grown). We do this because if the queue has not enough
  43612. + * budget for its first request, it has to go through two dispatch
  43613. + * rounds to actually get it dispatched.
  43614. + */
  43615. +static void bfq_updated_next_req(struct bfq_data *bfqd,
  43616. + struct bfq_queue *bfqq)
  43617. +{
  43618. + struct bfq_entity *entity = &bfqq->entity;
  43619. + struct bfq_service_tree *st = bfq_entity_service_tree(entity);
  43620. + struct request *next_rq = bfqq->next_rq;
  43621. + unsigned long new_budget;
  43622. +
  43623. + if (next_rq == NULL)
  43624. + return;
  43625. +
  43626. + if (bfqq == bfqd->in_service_queue)
  43627. + /*
  43628. + * In order not to break guarantees, budgets cannot be
  43629. + * changed after an entity has been selected.
  43630. + */
  43631. + return;
  43632. +
  43633. + BUG_ON(entity->tree != &st->active);
  43634. + BUG_ON(entity == entity->sched_data->in_service_entity);
  43635. +
  43636. + new_budget = max_t(unsigned long, bfqq->max_budget,
  43637. + bfq_serv_to_charge(next_rq, bfqq));
  43638. + if (entity->budget != new_budget) {
  43639. + entity->budget = new_budget;
  43640. + bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu",
  43641. + new_budget);
  43642. + bfq_activate_bfqq(bfqd, bfqq);
  43643. + }
  43644. +}
  43645. +
  43646. +static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd)
  43647. +{
  43648. + u64 dur;
  43649. +
  43650. + if (bfqd->bfq_wr_max_time > 0)
  43651. + return bfqd->bfq_wr_max_time;
  43652. +
  43653. + dur = bfqd->RT_prod;
  43654. + do_div(dur, bfqd->peak_rate);
  43655. +
  43656. + return dur;
  43657. +}
  43658. +
  43659. +static inline unsigned
  43660. +bfq_bfqq_cooperations(struct bfq_queue *bfqq)
  43661. +{
  43662. + return bfqq->bic ? bfqq->bic->cooperations : 0;
  43663. +}
  43664. +
  43665. +static inline void
  43666. +bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
  43667. +{
  43668. + if (bic->saved_idle_window)
  43669. + bfq_mark_bfqq_idle_window(bfqq);
  43670. + else
  43671. + bfq_clear_bfqq_idle_window(bfqq);
  43672. + if (bic->saved_IO_bound)
  43673. + bfq_mark_bfqq_IO_bound(bfqq);
  43674. + else
  43675. + bfq_clear_bfqq_IO_bound(bfqq);
  43676. + if (bic->wr_time_left && bfqq->bfqd->low_latency &&
  43677. + bic->cooperations < bfqq->bfqd->bfq_coop_thresh) {
  43678. + /*
  43679. + * Start a weight raising period with the duration given by
  43680. + * the raising_time_left snapshot.
  43681. + */
  43682. + if (bfq_bfqq_busy(bfqq))
  43683. + bfqq->bfqd->wr_busy_queues++;
  43684. + bfqq->wr_coeff = bfqq->bfqd->bfq_wr_coeff;
  43685. + bfqq->wr_cur_max_time = bic->wr_time_left;
  43686. + bfqq->last_wr_start_finish = jiffies;
  43687. + bfqq->entity.ioprio_changed = 1;
  43688. + }
  43689. + /*
  43690. + * Clear wr_time_left to prevent bfq_bfqq_save_state() from
  43691. + * getting confused about the queue's need of a weight-raising
  43692. + * period.
  43693. + */
  43694. + bic->wr_time_left = 0;
  43695. +}
  43696. +
  43697. +/*
  43698. + * Must be called with the queue_lock held.
  43699. + */
  43700. +static int bfqq_process_refs(struct bfq_queue *bfqq)
  43701. +{
  43702. + int process_refs, io_refs;
  43703. +
  43704. + io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE];
  43705. + process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st;
  43706. + BUG_ON(process_refs < 0);
  43707. + return process_refs;
  43708. +}
  43709. +
  43710. +static void bfq_add_request(struct request *rq)
  43711. +{
  43712. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  43713. + struct bfq_entity *entity = &bfqq->entity;
  43714. + struct bfq_data *bfqd = bfqq->bfqd;
  43715. + struct request *next_rq, *prev;
  43716. + unsigned long old_wr_coeff = bfqq->wr_coeff;
  43717. + int idle_for_long_time = 0;
  43718. +
  43719. + bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq));
  43720. + bfqq->queued[rq_is_sync(rq)]++;
  43721. + bfqd->queued++;
  43722. +
  43723. + elv_rb_add(&bfqq->sort_list, rq);
  43724. +
  43725. + /*
  43726. + * Check if this request is a better next-serve candidate.
  43727. + */
  43728. + prev = bfqq->next_rq;
  43729. + next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position);
  43730. + BUG_ON(next_rq == NULL);
  43731. + bfqq->next_rq = next_rq;
  43732. +
  43733. + /*
  43734. + * Adjust priority tree position, if next_rq changes.
  43735. + */
  43736. + if (prev != bfqq->next_rq)
  43737. + bfq_rq_pos_tree_add(bfqd, bfqq);
  43738. +
  43739. + if (!bfq_bfqq_busy(bfqq)) {
  43740. + int soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 &&
  43741. + bfq_bfqq_cooperations(bfqq) < bfqd->bfq_coop_thresh &&
  43742. + time_is_before_jiffies(bfqq->soft_rt_next_start);
  43743. + idle_for_long_time = bfq_bfqq_cooperations(bfqq) <
  43744. + bfqd->bfq_coop_thresh &&
  43745. + time_is_before_jiffies(
  43746. + bfqq->budget_timeout +
  43747. + bfqd->bfq_wr_min_idle_time);
  43748. + entity->budget = max_t(unsigned long, bfqq->max_budget,
  43749. + bfq_serv_to_charge(next_rq, bfqq));
  43750. +
  43751. + if (!bfq_bfqq_IO_bound(bfqq)) {
  43752. + if (time_before(jiffies,
  43753. + RQ_BIC(rq)->ttime.last_end_request +
  43754. + bfqd->bfq_slice_idle)) {
  43755. + bfqq->requests_within_timer++;
  43756. + if (bfqq->requests_within_timer >=
  43757. + bfqd->bfq_requests_within_timer)
  43758. + bfq_mark_bfqq_IO_bound(bfqq);
  43759. + } else
  43760. + bfqq->requests_within_timer = 0;
  43761. + }
  43762. +
  43763. + if (!bfqd->low_latency)
  43764. + goto add_bfqq_busy;
  43765. +
  43766. + if (bfq_bfqq_just_split(bfqq))
  43767. + goto set_ioprio_changed;
  43768. +
  43769. + /*
  43770. + * If the queue:
  43771. + * - is not being boosted,
  43772. + * - has been idle for enough time,
  43773. + * - is not a sync queue or is linked to a bfq_io_cq (it is
  43774. + * shared "for its nature" or it is not shared and its
  43775. + * requests have not been redirected to a shared queue)
  43776. + * start a weight-raising period.
  43777. + */
  43778. + if (old_wr_coeff == 1 && (idle_for_long_time || soft_rt) &&
  43779. + (!bfq_bfqq_sync(bfqq) || bfqq->bic != NULL)) {
  43780. + bfqq->wr_coeff = bfqd->bfq_wr_coeff;
  43781. + if (idle_for_long_time)
  43782. + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
  43783. + else
  43784. + bfqq->wr_cur_max_time =
  43785. + bfqd->bfq_wr_rt_max_time;
  43786. + bfq_log_bfqq(bfqd, bfqq,
  43787. + "wrais starting at %lu, rais_max_time %u",
  43788. + jiffies,
  43789. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  43790. + } else if (old_wr_coeff > 1) {
  43791. + if (idle_for_long_time)
  43792. + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
  43793. + else if (bfq_bfqq_cooperations(bfqq) >=
  43794. + bfqd->bfq_coop_thresh ||
  43795. + (bfqq->wr_cur_max_time ==
  43796. + bfqd->bfq_wr_rt_max_time &&
  43797. + !soft_rt)) {
  43798. + bfqq->wr_coeff = 1;
  43799. + bfq_log_bfqq(bfqd, bfqq,
  43800. + "wrais ending at %lu, rais_max_time %u",
  43801. + jiffies,
  43802. + jiffies_to_msecs(bfqq->
  43803. + wr_cur_max_time));
  43804. + } else if (time_before(
  43805. + bfqq->last_wr_start_finish +
  43806. + bfqq->wr_cur_max_time,
  43807. + jiffies +
  43808. + bfqd->bfq_wr_rt_max_time) &&
  43809. + soft_rt) {
  43810. + /*
  43811. + *
  43812. + * The remaining weight-raising time is lower
  43813. + * than bfqd->bfq_wr_rt_max_time, which means
  43814. + * that the application is enjoying weight
  43815. + * raising either because deemed soft-rt in
  43816. + * the near past, or because deemed interactive
  43817. + * a long ago.
  43818. + * In both cases, resetting now the current
  43819. + * remaining weight-raising time for the
  43820. + * application to the weight-raising duration
  43821. + * for soft rt applications would not cause any
  43822. + * latency increase for the application (as the
  43823. + * new duration would be higher than the
  43824. + * remaining time).
  43825. + *
  43826. + * In addition, the application is now meeting
  43827. + * the requirements for being deemed soft rt.
  43828. + * In the end we can correctly and safely
  43829. + * (re)charge the weight-raising duration for
  43830. + * the application with the weight-raising
  43831. + * duration for soft rt applications.
  43832. + *
  43833. + * In particular, doing this recharge now, i.e.,
  43834. + * before the weight-raising period for the
  43835. + * application finishes, reduces the probability
  43836. + * of the following negative scenario:
  43837. + * 1) the weight of a soft rt application is
  43838. + * raised at startup (as for any newly
  43839. + * created application),
  43840. + * 2) since the application is not interactive,
  43841. + * at a certain time weight-raising is
  43842. + * stopped for the application,
  43843. + * 3) at that time the application happens to
  43844. + * still have pending requests, and hence
  43845. + * is destined to not have a chance to be
  43846. + * deemed soft rt before these requests are
  43847. + * completed (see the comments to the
  43848. + * function bfq_bfqq_softrt_next_start()
  43849. + * for details on soft rt detection),
  43850. + * 4) these pending requests experience a high
  43851. + * latency because the application is not
  43852. + * weight-raised while they are pending.
  43853. + */
  43854. + bfqq->last_wr_start_finish = jiffies;
  43855. + bfqq->wr_cur_max_time =
  43856. + bfqd->bfq_wr_rt_max_time;
  43857. + }
  43858. + }
  43859. +set_ioprio_changed:
  43860. + if (old_wr_coeff != bfqq->wr_coeff)
  43861. + entity->ioprio_changed = 1;
  43862. +add_bfqq_busy:
  43863. + bfqq->last_idle_bklogged = jiffies;
  43864. + bfqq->service_from_backlogged = 0;
  43865. + bfq_clear_bfqq_softrt_update(bfqq);
  43866. + bfq_add_bfqq_busy(bfqd, bfqq);
  43867. + } else {
  43868. + if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) &&
  43869. + time_is_before_jiffies(
  43870. + bfqq->last_wr_start_finish +
  43871. + bfqd->bfq_wr_min_inter_arr_async)) {
  43872. + bfqq->wr_coeff = bfqd->bfq_wr_coeff;
  43873. + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
  43874. +
  43875. + bfqd->wr_busy_queues++;
  43876. + entity->ioprio_changed = 1;
  43877. + bfq_log_bfqq(bfqd, bfqq,
  43878. + "non-idle wrais starting at %lu, rais_max_time %u",
  43879. + jiffies,
  43880. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  43881. + }
  43882. + if (prev != bfqq->next_rq)
  43883. + bfq_updated_next_req(bfqd, bfqq);
  43884. + }
  43885. +
  43886. + if (bfqd->low_latency &&
  43887. + (old_wr_coeff == 1 || bfqq->wr_coeff == 1 ||
  43888. + idle_for_long_time))
  43889. + bfqq->last_wr_start_finish = jiffies;
  43890. +}
  43891. +
  43892. +static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd,
  43893. + struct bio *bio)
  43894. +{
  43895. + struct task_struct *tsk = current;
  43896. + struct bfq_io_cq *bic;
  43897. + struct bfq_queue *bfqq;
  43898. +
  43899. + bic = bfq_bic_lookup(bfqd, tsk->io_context);
  43900. + if (bic == NULL)
  43901. + return NULL;
  43902. +
  43903. + bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio));
  43904. + if (bfqq != NULL)
  43905. + return elv_rb_find(&bfqq->sort_list, bio_end_sector(bio));
  43906. +
  43907. + return NULL;
  43908. +}
  43909. +
  43910. +static void bfq_activate_request(struct request_queue *q, struct request *rq)
  43911. +{
  43912. + struct bfq_data *bfqd = q->elevator->elevator_data;
  43913. +
  43914. + bfqd->rq_in_driver++;
  43915. + bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
  43916. + bfq_log(bfqd, "activate_request: new bfqd->last_position %llu",
  43917. + (long long unsigned)bfqd->last_position);
  43918. +}
  43919. +
  43920. +static inline void bfq_deactivate_request(struct request_queue *q,
  43921. + struct request *rq)
  43922. +{
  43923. + struct bfq_data *bfqd = q->elevator->elevator_data;
  43924. +
  43925. + BUG_ON(bfqd->rq_in_driver == 0);
  43926. + bfqd->rq_in_driver--;
  43927. +}
  43928. +
  43929. +static void bfq_remove_request(struct request *rq)
  43930. +{
  43931. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  43932. + struct bfq_data *bfqd = bfqq->bfqd;
  43933. + const int sync = rq_is_sync(rq);
  43934. +
  43935. + if (bfqq->next_rq == rq) {
  43936. + bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq);
  43937. + bfq_updated_next_req(bfqd, bfqq);
  43938. + }
  43939. +
  43940. + list_del_init(&rq->queuelist);
  43941. + BUG_ON(bfqq->queued[sync] == 0);
  43942. + bfqq->queued[sync]--;
  43943. + bfqd->queued--;
  43944. + elv_rb_del(&bfqq->sort_list, rq);
  43945. +
  43946. + if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
  43947. + if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue)
  43948. + bfq_del_bfqq_busy(bfqd, bfqq, 1);
  43949. + /*
  43950. + * Remove queue from request-position tree as it is empty.
  43951. + */
  43952. + if (bfqq->pos_root != NULL) {
  43953. + rb_erase(&bfqq->pos_node, bfqq->pos_root);
  43954. + bfqq->pos_root = NULL;
  43955. + }
  43956. + }
  43957. +
  43958. + if (rq->cmd_flags & REQ_META) {
  43959. + BUG_ON(bfqq->meta_pending == 0);
  43960. + bfqq->meta_pending--;
  43961. + }
  43962. +}
  43963. +
  43964. +static int bfq_merge(struct request_queue *q, struct request **req,
  43965. + struct bio *bio)
  43966. +{
  43967. + struct bfq_data *bfqd = q->elevator->elevator_data;
  43968. + struct request *__rq;
  43969. +
  43970. + __rq = bfq_find_rq_fmerge(bfqd, bio);
  43971. + if (__rq != NULL && elv_rq_merge_ok(__rq, bio)) {
  43972. + *req = __rq;
  43973. + return ELEVATOR_FRONT_MERGE;
  43974. + }
  43975. +
  43976. + return ELEVATOR_NO_MERGE;
  43977. +}
  43978. +
  43979. +static void bfq_merged_request(struct request_queue *q, struct request *req,
  43980. + int type)
  43981. +{
  43982. + if (type == ELEVATOR_FRONT_MERGE &&
  43983. + rb_prev(&req->rb_node) &&
  43984. + blk_rq_pos(req) <
  43985. + blk_rq_pos(container_of(rb_prev(&req->rb_node),
  43986. + struct request, rb_node))) {
  43987. + struct bfq_queue *bfqq = RQ_BFQQ(req);
  43988. + struct bfq_data *bfqd = bfqq->bfqd;
  43989. + struct request *prev, *next_rq;
  43990. +
  43991. + /* Reposition request in its sort_list */
  43992. + elv_rb_del(&bfqq->sort_list, req);
  43993. + elv_rb_add(&bfqq->sort_list, req);
  43994. + /* Choose next request to be served for bfqq */
  43995. + prev = bfqq->next_rq;
  43996. + next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req,
  43997. + bfqd->last_position);
  43998. + BUG_ON(next_rq == NULL);
  43999. + bfqq->next_rq = next_rq;
  44000. + /*
  44001. + * If next_rq changes, update both the queue's budget to
  44002. + * fit the new request and the queue's position in its
  44003. + * rq_pos_tree.
  44004. + */
  44005. + if (prev != bfqq->next_rq) {
  44006. + bfq_updated_next_req(bfqd, bfqq);
  44007. + bfq_rq_pos_tree_add(bfqd, bfqq);
  44008. + }
  44009. + }
  44010. +}
  44011. +
  44012. +static void bfq_merged_requests(struct request_queue *q, struct request *rq,
  44013. + struct request *next)
  44014. +{
  44015. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  44016. +
  44017. + /*
  44018. + * Reposition in fifo if next is older than rq.
  44019. + */
  44020. + if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) &&
  44021. + time_before(rq_fifo_time(next), rq_fifo_time(rq))) {
  44022. + list_move(&rq->queuelist, &next->queuelist);
  44023. + rq_set_fifo_time(rq, rq_fifo_time(next));
  44024. + }
  44025. +
  44026. + if (bfqq->next_rq == next)
  44027. + bfqq->next_rq = rq;
  44028. +
  44029. + bfq_remove_request(next);
  44030. +}
  44031. +
  44032. +/* Must be called with bfqq != NULL */
  44033. +static inline void bfq_bfqq_end_wr(struct bfq_queue *bfqq)
  44034. +{
  44035. + BUG_ON(bfqq == NULL);
  44036. + if (bfq_bfqq_busy(bfqq))
  44037. + bfqq->bfqd->wr_busy_queues--;
  44038. + bfqq->wr_coeff = 1;
  44039. + bfqq->wr_cur_max_time = 0;
  44040. + /* Trigger a weight change on the next activation of the queue */
  44041. + bfqq->entity.ioprio_changed = 1;
  44042. +}
  44043. +
  44044. +static void bfq_end_wr_async_queues(struct bfq_data *bfqd,
  44045. + struct bfq_group *bfqg)
  44046. +{
  44047. + int i, j;
  44048. +
  44049. + for (i = 0; i < 2; i++)
  44050. + for (j = 0; j < IOPRIO_BE_NR; j++)
  44051. + if (bfqg->async_bfqq[i][j] != NULL)
  44052. + bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]);
  44053. + if (bfqg->async_idle_bfqq != NULL)
  44054. + bfq_bfqq_end_wr(bfqg->async_idle_bfqq);
  44055. +}
  44056. +
  44057. +static void bfq_end_wr(struct bfq_data *bfqd)
  44058. +{
  44059. + struct bfq_queue *bfqq;
  44060. +
  44061. + spin_lock_irq(bfqd->queue->queue_lock);
  44062. +
  44063. + list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list)
  44064. + bfq_bfqq_end_wr(bfqq);
  44065. + list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list)
  44066. + bfq_bfqq_end_wr(bfqq);
  44067. + bfq_end_wr_async(bfqd);
  44068. +
  44069. + spin_unlock_irq(bfqd->queue->queue_lock);
  44070. +}
  44071. +
  44072. +static inline sector_t bfq_io_struct_pos(void *io_struct, bool request)
  44073. +{
  44074. + if (request)
  44075. + return blk_rq_pos(io_struct);
  44076. + else
  44077. + return ((struct bio *)io_struct)->bi_iter.bi_sector;
  44078. +}
  44079. +
  44080. +static inline sector_t bfq_dist_from(sector_t pos1,
  44081. + sector_t pos2)
  44082. +{
  44083. + if (pos1 >= pos2)
  44084. + return pos1 - pos2;
  44085. + else
  44086. + return pos2 - pos1;
  44087. +}
  44088. +
  44089. +static inline int bfq_rq_close_to_sector(void *io_struct, bool request,
  44090. + sector_t sector)
  44091. +{
  44092. + return bfq_dist_from(bfq_io_struct_pos(io_struct, request), sector) <=
  44093. + BFQQ_SEEK_THR;
  44094. +}
  44095. +
  44096. +static struct bfq_queue *bfqq_close(struct bfq_data *bfqd, sector_t sector)
  44097. +{
  44098. + struct rb_root *root = &bfqd->rq_pos_tree;
  44099. + struct rb_node *parent, *node;
  44100. + struct bfq_queue *__bfqq;
  44101. +
  44102. + if (RB_EMPTY_ROOT(root))
  44103. + return NULL;
  44104. +
  44105. + /*
  44106. + * First, if we find a request starting at the end of the last
  44107. + * request, choose it.
  44108. + */
  44109. + __bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL);
  44110. + if (__bfqq != NULL)
  44111. + return __bfqq;
  44112. +
  44113. + /*
  44114. + * If the exact sector wasn't found, the parent of the NULL leaf
  44115. + * will contain the closest sector (rq_pos_tree sorted by
  44116. + * next_request position).
  44117. + */
  44118. + __bfqq = rb_entry(parent, struct bfq_queue, pos_node);
  44119. + if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector))
  44120. + return __bfqq;
  44121. +
  44122. + if (blk_rq_pos(__bfqq->next_rq) < sector)
  44123. + node = rb_next(&__bfqq->pos_node);
  44124. + else
  44125. + node = rb_prev(&__bfqq->pos_node);
  44126. + if (node == NULL)
  44127. + return NULL;
  44128. +
  44129. + __bfqq = rb_entry(node, struct bfq_queue, pos_node);
  44130. + if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector))
  44131. + return __bfqq;
  44132. +
  44133. + return NULL;
  44134. +}
  44135. +
  44136. +/*
  44137. + * bfqd - obvious
  44138. + * cur_bfqq - passed in so that we don't decide that the current queue
  44139. + * is closely cooperating with itself
  44140. + * sector - used as a reference point to search for a close queue
  44141. + */
  44142. +static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd,
  44143. + struct bfq_queue *cur_bfqq,
  44144. + sector_t sector)
  44145. +{
  44146. + struct bfq_queue *bfqq;
  44147. +
  44148. + if (bfq_class_idle(cur_bfqq))
  44149. + return NULL;
  44150. + if (!bfq_bfqq_sync(cur_bfqq))
  44151. + return NULL;
  44152. + if (BFQQ_SEEKY(cur_bfqq))
  44153. + return NULL;
  44154. +
  44155. + /* If device has only one backlogged bfq_queue, don't search. */
  44156. + if (bfqd->busy_queues == 1)
  44157. + return NULL;
  44158. +
  44159. + /*
  44160. + * We should notice if some of the queues are cooperating, e.g.
  44161. + * working closely on the same area of the disk. In that case,
  44162. + * we can group them together and don't waste time idling.
  44163. + */
  44164. + bfqq = bfqq_close(bfqd, sector);
  44165. + if (bfqq == NULL || bfqq == cur_bfqq)
  44166. + return NULL;
  44167. +
  44168. + /*
  44169. + * Do not merge queues from different bfq_groups.
  44170. + */
  44171. + if (bfqq->entity.parent != cur_bfqq->entity.parent)
  44172. + return NULL;
  44173. +
  44174. + /*
  44175. + * It only makes sense to merge sync queues.
  44176. + */
  44177. + if (!bfq_bfqq_sync(bfqq))
  44178. + return NULL;
  44179. + if (BFQQ_SEEKY(bfqq))
  44180. + return NULL;
  44181. +
  44182. + /*
  44183. + * Do not merge queues of different priority classes.
  44184. + */
  44185. + if (bfq_class_rt(bfqq) != bfq_class_rt(cur_bfqq))
  44186. + return NULL;
  44187. +
  44188. + return bfqq;
  44189. +}
  44190. +
  44191. +static struct bfq_queue *
  44192. +bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
  44193. +{
  44194. + int process_refs, new_process_refs;
  44195. + struct bfq_queue *__bfqq;
  44196. +
  44197. + /*
  44198. + * If there are no process references on the new_bfqq, then it is
  44199. + * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain
  44200. + * may have dropped their last reference (not just their last process
  44201. + * reference).
  44202. + */
  44203. + if (!bfqq_process_refs(new_bfqq))
  44204. + return NULL;
  44205. +
  44206. + /* Avoid a circular list and skip interim queue merges. */
  44207. + while ((__bfqq = new_bfqq->new_bfqq)) {
  44208. + if (__bfqq == bfqq)
  44209. + return NULL;
  44210. + new_bfqq = __bfqq;
  44211. + }
  44212. +
  44213. + process_refs = bfqq_process_refs(bfqq);
  44214. + new_process_refs = bfqq_process_refs(new_bfqq);
  44215. + /*
  44216. + * If the process for the bfqq has gone away, there is no
  44217. + * sense in merging the queues.
  44218. + */
  44219. + if (process_refs == 0 || new_process_refs == 0)
  44220. + return NULL;
  44221. +
  44222. + bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d",
  44223. + new_bfqq->pid);
  44224. +
  44225. + /*
  44226. + * Merging is just a redirection: the requests of the process
  44227. + * owning one of the two queues are redirected to the other queue.
  44228. + * The latter queue, in its turn, is set as shared if this is the
  44229. + * first time that the requests of some process are redirected to
  44230. + * it.
  44231. + *
  44232. + * We redirect bfqq to new_bfqq and not the opposite, because we
  44233. + * are in the context of the process owning bfqq, hence we have
  44234. + * the io_cq of this process. So we can immediately configure this
  44235. + * io_cq to redirect the requests of the process to new_bfqq.
  44236. + *
  44237. + * NOTE, even if new_bfqq coincides with the in-service queue, the
  44238. + * io_cq of new_bfqq is not available, because, if the in-service
  44239. + * queue is shared, bfqd->in_service_bic may not point to the
  44240. + * io_cq of the in-service queue.
  44241. + * Redirecting the requests of the process owning bfqq to the
  44242. + * currently in-service queue is in any case the best option, as
  44243. + * we feed the in-service queue with new requests close to the
  44244. + * last request served and, by doing so, hopefully increase the
  44245. + * throughput.
  44246. + */
  44247. + bfqq->new_bfqq = new_bfqq;
  44248. + atomic_add(process_refs, &new_bfqq->ref);
  44249. + return new_bfqq;
  44250. +}
  44251. +
  44252. +/*
  44253. + * Attempt to schedule a merge of bfqq with the currently in-service queue
  44254. + * or with a close queue among the scheduled queues.
  44255. + * Return NULL if no merge was scheduled, a pointer to the shared bfq_queue
  44256. + * structure otherwise.
  44257. + */
  44258. +static struct bfq_queue *
  44259. +bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  44260. + void *io_struct, bool request)
  44261. +{
  44262. + struct bfq_queue *in_service_bfqq, *new_bfqq;
  44263. +
  44264. + if (bfqq->new_bfqq)
  44265. + return bfqq->new_bfqq;
  44266. +
  44267. + if (!io_struct)
  44268. + return NULL;
  44269. +
  44270. + in_service_bfqq = bfqd->in_service_queue;
  44271. +
  44272. + if (in_service_bfqq == NULL || in_service_bfqq == bfqq ||
  44273. + !bfqd->in_service_bic)
  44274. + goto check_scheduled;
  44275. +
  44276. + if (bfq_class_idle(in_service_bfqq) || bfq_class_idle(bfqq))
  44277. + goto check_scheduled;
  44278. +
  44279. + if (bfq_class_rt(in_service_bfqq) != bfq_class_rt(bfqq))
  44280. + goto check_scheduled;
  44281. +
  44282. + if (in_service_bfqq->entity.parent != bfqq->entity.parent)
  44283. + goto check_scheduled;
  44284. +
  44285. + if (bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) &&
  44286. + bfq_bfqq_sync(in_service_bfqq) && bfq_bfqq_sync(bfqq)) {
  44287. + new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq);
  44288. + if (new_bfqq != NULL)
  44289. + return new_bfqq; /* Merge with in-service queue */
  44290. + }
  44291. +
  44292. + /*
  44293. + * Check whether there is a cooperator among currently scheduled
  44294. + * queues. The only thing we need is that the bio/request is not
  44295. + * NULL, as we need it to establish whether a cooperator exists.
  44296. + */
  44297. +check_scheduled:
  44298. + new_bfqq = bfq_close_cooperator(bfqd, bfqq,
  44299. + bfq_io_struct_pos(io_struct, request));
  44300. + if (new_bfqq)
  44301. + return bfq_setup_merge(bfqq, new_bfqq);
  44302. +
  44303. + return NULL;
  44304. +}
  44305. +
  44306. +static inline void
  44307. +bfq_bfqq_save_state(struct bfq_queue *bfqq)
  44308. +{
  44309. + /*
  44310. + * If bfqq->bic == NULL, the queue is already shared or its requests
  44311. + * have already been redirected to a shared queue; both idle window
  44312. + * and weight raising state have already been saved. Do nothing.
  44313. + */
  44314. + if (bfqq->bic == NULL)
  44315. + return;
  44316. + if (bfqq->bic->wr_time_left)
  44317. + /*
  44318. + * This is the queue of a just-started process, and would
  44319. + * deserve weight raising: we set wr_time_left to the full
  44320. + * weight-raising duration to trigger weight-raising when
  44321. + * and if the queue is split and the first request of the
  44322. + * queue is enqueued.
  44323. + */
  44324. + bfqq->bic->wr_time_left = bfq_wr_duration(bfqq->bfqd);
  44325. + else if (bfqq->wr_coeff > 1) {
  44326. + unsigned long wr_duration =
  44327. + jiffies - bfqq->last_wr_start_finish;
  44328. + /*
  44329. + * It may happen that a queue's weight raising period lasts
  44330. + * longer than its wr_cur_max_time, as weight raising is
  44331. + * handled only when a request is enqueued or dispatched (it
  44332. + * does not use any timer). If the weight raising period is
  44333. + * about to end, don't save it.
  44334. + */
  44335. + if (bfqq->wr_cur_max_time <= wr_duration)
  44336. + bfqq->bic->wr_time_left = 0;
  44337. + else
  44338. + bfqq->bic->wr_time_left =
  44339. + bfqq->wr_cur_max_time - wr_duration;
  44340. + /*
  44341. + * The bfq_queue is becoming shared or the requests of the
  44342. + * process owning the queue are being redirected to a shared
  44343. + * queue. Stop the weight raising period of the queue, as in
  44344. + * both cases it should not be owned by an interactive or
  44345. + * soft real-time application.
  44346. + */
  44347. + bfq_bfqq_end_wr(bfqq);
  44348. + } else
  44349. + bfqq->bic->wr_time_left = 0;
  44350. + bfqq->bic->saved_idle_window = bfq_bfqq_idle_window(bfqq);
  44351. + bfqq->bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq);
  44352. + bfqq->bic->cooperations++;
  44353. + bfqq->bic->failed_cooperations = 0;
  44354. +}
  44355. +
  44356. +static inline void
  44357. +bfq_get_bic_reference(struct bfq_queue *bfqq)
  44358. +{
  44359. + /*
  44360. + * If bfqq->bic has a non-NULL value, the bic to which it belongs
  44361. + * is about to begin using a shared bfq_queue.
  44362. + */
  44363. + if (bfqq->bic)
  44364. + atomic_long_inc(&bfqq->bic->icq.ioc->refcount);
  44365. +}
  44366. +
  44367. +static void
  44368. +bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
  44369. + struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
  44370. +{
  44371. + bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu",
  44372. + (long unsigned)new_bfqq->pid);
  44373. + /* Save weight raising and idle window of the merged queues */
  44374. + bfq_bfqq_save_state(bfqq);
  44375. + bfq_bfqq_save_state(new_bfqq);
  44376. + if (bfq_bfqq_IO_bound(bfqq))
  44377. + bfq_mark_bfqq_IO_bound(new_bfqq);
  44378. + bfq_clear_bfqq_IO_bound(bfqq);
  44379. + /*
  44380. + * Grab a reference to the bic, to prevent it from being destroyed
  44381. + * before being possibly touched by a bfq_split_bfqq().
  44382. + */
  44383. + bfq_get_bic_reference(bfqq);
  44384. + bfq_get_bic_reference(new_bfqq);
  44385. + /*
  44386. + * Merge queues (that is, let bic redirect its requests to new_bfqq)
  44387. + */
  44388. + bic_set_bfqq(bic, new_bfqq, 1);
  44389. + bfq_mark_bfqq_coop(new_bfqq);
  44390. + /*
  44391. + * new_bfqq now belongs to at least two bics (it is a shared queue):
  44392. + * set new_bfqq->bic to NULL. bfqq either:
  44393. + * - does not belong to any bic any more, and hence bfqq->bic must
  44394. + * be set to NULL, or
  44395. + * - is a queue whose owning bics have already been redirected to a
  44396. + * different queue, hence the queue is destined to not belong to
  44397. + * any bic soon and bfqq->bic is already NULL (therefore the next
  44398. + * assignment causes no harm).
  44399. + */
  44400. + new_bfqq->bic = NULL;
  44401. + bfqq->bic = NULL;
  44402. + bfq_put_queue(bfqq);
  44403. +}
  44404. +
  44405. +static inline void bfq_bfqq_increase_failed_cooperations(struct bfq_queue *bfqq)
  44406. +{
  44407. + struct bfq_io_cq *bic = bfqq->bic;
  44408. + struct bfq_data *bfqd = bfqq->bfqd;
  44409. +
  44410. + if (bic && bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh) {
  44411. + bic->failed_cooperations++;
  44412. + if (bic->failed_cooperations >= bfqd->bfq_failed_cooperations)
  44413. + bic->cooperations = 0;
  44414. + }
  44415. +}
  44416. +
  44417. +static int bfq_allow_merge(struct request_queue *q, struct request *rq,
  44418. + struct bio *bio)
  44419. +{
  44420. + struct bfq_data *bfqd = q->elevator->elevator_data;
  44421. + struct bfq_io_cq *bic;
  44422. + struct bfq_queue *bfqq, *new_bfqq;
  44423. +
  44424. + /*
  44425. + * Disallow merge of a sync bio into an async request.
  44426. + */
  44427. + if (bfq_bio_sync(bio) && !rq_is_sync(rq))
  44428. + return 0;
  44429. +
  44430. + /*
  44431. + * Lookup the bfqq that this bio will be queued with. Allow
  44432. + * merge only if rq is queued there.
  44433. + * Queue lock is held here.
  44434. + */
  44435. + bic = bfq_bic_lookup(bfqd, current->io_context);
  44436. + if (bic == NULL)
  44437. + return 0;
  44438. +
  44439. + bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio));
  44440. + /*
  44441. + * We take advantage of this function to perform an early merge
  44442. + * of the queues of possible cooperating processes.
  44443. + */
  44444. + if (bfqq != NULL) {
  44445. + new_bfqq = bfq_setup_cooperator(bfqd, bfqq, bio, false);
  44446. + if (new_bfqq != NULL) {
  44447. + bfq_merge_bfqqs(bfqd, bic, bfqq, new_bfqq);
  44448. + /*
  44449. + * If we get here, the bio will be queued in the
  44450. + * shared queue, i.e., new_bfqq, so use new_bfqq
  44451. + * to decide whether bio and rq can be merged.
  44452. + */
  44453. + bfqq = new_bfqq;
  44454. + } else
  44455. + bfq_bfqq_increase_failed_cooperations(bfqq);
  44456. + }
  44457. +
  44458. + return bfqq == RQ_BFQQ(rq);
  44459. +}
  44460. +
  44461. +static void __bfq_set_in_service_queue(struct bfq_data *bfqd,
  44462. + struct bfq_queue *bfqq)
  44463. +{
  44464. + if (bfqq != NULL) {
  44465. + bfq_mark_bfqq_must_alloc(bfqq);
  44466. + bfq_mark_bfqq_budget_new(bfqq);
  44467. + bfq_clear_bfqq_fifo_expire(bfqq);
  44468. +
  44469. + bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8;
  44470. +
  44471. + bfq_log_bfqq(bfqd, bfqq,
  44472. + "set_in_service_queue, cur-budget = %lu",
  44473. + bfqq->entity.budget);
  44474. + }
  44475. +
  44476. + bfqd->in_service_queue = bfqq;
  44477. +}
  44478. +
  44479. +/*
  44480. + * Get and set a new queue for service.
  44481. + */
  44482. +static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd)
  44483. +{
  44484. + struct bfq_queue *bfqq = bfq_get_next_queue(bfqd);
  44485. +
  44486. + __bfq_set_in_service_queue(bfqd, bfqq);
  44487. + return bfqq;
  44488. +}
  44489. +
  44490. +/*
  44491. + * If enough samples have been computed, return the current max budget
  44492. + * stored in bfqd, which is dynamically updated according to the
  44493. + * estimated disk peak rate; otherwise return the default max budget
  44494. + */
  44495. +static inline unsigned long bfq_max_budget(struct bfq_data *bfqd)
  44496. +{
  44497. + if (bfqd->budgets_assigned < 194)
  44498. + return bfq_default_max_budget;
  44499. + else
  44500. + return bfqd->bfq_max_budget;
  44501. +}
  44502. +
  44503. +/*
  44504. + * Return min budget, which is a fraction of the current or default
  44505. + * max budget (trying with 1/32)
  44506. + */
  44507. +static inline unsigned long bfq_min_budget(struct bfq_data *bfqd)
  44508. +{
  44509. + if (bfqd->budgets_assigned < 194)
  44510. + return bfq_default_max_budget / 32;
  44511. + else
  44512. + return bfqd->bfq_max_budget / 32;
  44513. +}
  44514. +
  44515. +static void bfq_arm_slice_timer(struct bfq_data *bfqd)
  44516. +{
  44517. + struct bfq_queue *bfqq = bfqd->in_service_queue;
  44518. + struct bfq_io_cq *bic;
  44519. + unsigned long sl;
  44520. +
  44521. + BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
  44522. +
  44523. + /* Processes have exited, don't wait. */
  44524. + bic = bfqd->in_service_bic;
  44525. + if (bic == NULL || atomic_read(&bic->icq.ioc->active_ref) == 0)
  44526. + return;
  44527. +
  44528. + bfq_mark_bfqq_wait_request(bfqq);
  44529. +
  44530. + /*
  44531. + * We don't want to idle for seeks, but we do want to allow
  44532. + * fair distribution of slice time for a process doing back-to-back
  44533. + * seeks. So allow a little bit of time for him to submit a new rq.
  44534. + *
  44535. + * To prevent processes with (partly) seeky workloads from
  44536. + * being too ill-treated, grant them a small fraction of the
  44537. + * assigned budget before reducing the waiting time to
  44538. + * BFQ_MIN_TT. This happened to help reduce latency.
  44539. + */
  44540. + sl = bfqd->bfq_slice_idle;
  44541. + /*
  44542. + * Unless the queue is being weight-raised, grant only minimum idle
  44543. + * time if the queue either has been seeky for long enough or has
  44544. + * already proved to be constantly seeky.
  44545. + */
  44546. + if (bfq_sample_valid(bfqq->seek_samples) &&
  44547. + ((BFQQ_SEEKY(bfqq) && bfqq->entity.service >
  44548. + bfq_max_budget(bfqq->bfqd) / 8) ||
  44549. + bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1)
  44550. + sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT));
  44551. + else if (bfqq->wr_coeff > 1)
  44552. + sl = sl * 3;
  44553. + bfqd->last_idling_start = ktime_get();
  44554. + mod_timer(&bfqd->idle_slice_timer, jiffies + sl);
  44555. + bfq_log(bfqd, "arm idle: %u/%u ms",
  44556. + jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle));
  44557. +}
  44558. +
  44559. +/*
  44560. + * Set the maximum time for the in-service queue to consume its
  44561. + * budget. This prevents seeky processes from lowering the disk
  44562. + * throughput (always guaranteed with a time slice scheme as in CFQ).
  44563. + */
  44564. +static void bfq_set_budget_timeout(struct bfq_data *bfqd)
  44565. +{
  44566. + struct bfq_queue *bfqq = bfqd->in_service_queue;
  44567. + unsigned int timeout_coeff;
  44568. + if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time)
  44569. + timeout_coeff = 1;
  44570. + else
  44571. + timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight;
  44572. +
  44573. + bfqd->last_budget_start = ktime_get();
  44574. +
  44575. + bfq_clear_bfqq_budget_new(bfqq);
  44576. + bfqq->budget_timeout = jiffies +
  44577. + bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff;
  44578. +
  44579. + bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u",
  44580. + jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] *
  44581. + timeout_coeff));
  44582. +}
  44583. +
  44584. +/*
  44585. + * Move request from internal lists to the request queue dispatch list.
  44586. + */
  44587. +static void bfq_dispatch_insert(struct request_queue *q, struct request *rq)
  44588. +{
  44589. + struct bfq_data *bfqd = q->elevator->elevator_data;
  44590. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  44591. +
  44592. + /*
  44593. + * For consistency, the next instruction should have been executed
  44594. + * after removing the request from the queue and dispatching it.
  44595. + * We execute instead this instruction before bfq_remove_request()
  44596. + * (and hence introduce a temporary inconsistency), for efficiency.
  44597. + * In fact, in a forced_dispatch, this prevents two counters related
  44598. + * to bfqq->dispatched to risk to be uselessly decremented if bfqq
  44599. + * is not in service, and then to be incremented again after
  44600. + * incrementing bfqq->dispatched.
  44601. + */
  44602. + bfqq->dispatched++;
  44603. + bfq_remove_request(rq);
  44604. + elv_dispatch_sort(q, rq);
  44605. +
  44606. + if (bfq_bfqq_sync(bfqq))
  44607. + bfqd->sync_flight++;
  44608. +}
  44609. +
  44610. +/*
  44611. + * Return expired entry, or NULL to just start from scratch in rbtree.
  44612. + */
  44613. +static struct request *bfq_check_fifo(struct bfq_queue *bfqq)
  44614. +{
  44615. + struct request *rq = NULL;
  44616. +
  44617. + if (bfq_bfqq_fifo_expire(bfqq))
  44618. + return NULL;
  44619. +
  44620. + bfq_mark_bfqq_fifo_expire(bfqq);
  44621. +
  44622. + if (list_empty(&bfqq->fifo))
  44623. + return NULL;
  44624. +
  44625. + rq = rq_entry_fifo(bfqq->fifo.next);
  44626. +
  44627. + if (time_before(jiffies, rq_fifo_time(rq)))
  44628. + return NULL;
  44629. +
  44630. + return rq;
  44631. +}
  44632. +
  44633. +static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq)
  44634. +{
  44635. + struct bfq_entity *entity = &bfqq->entity;
  44636. + return entity->budget - entity->service;
  44637. +}
  44638. +
  44639. +static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  44640. +{
  44641. + BUG_ON(bfqq != bfqd->in_service_queue);
  44642. +
  44643. + __bfq_bfqd_reset_in_service(bfqd);
  44644. +
  44645. + /*
  44646. + * If this bfqq is shared between multiple processes, check
  44647. + * to make sure that those processes are still issuing I/Os
  44648. + * within the mean seek distance. If not, it may be time to
  44649. + * break the queues apart again.
  44650. + */
  44651. + if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq))
  44652. + bfq_mark_bfqq_split_coop(bfqq);
  44653. +
  44654. + if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
  44655. + /*
  44656. + * Overloading budget_timeout field to store the time
  44657. + * at which the queue remains with no backlog; used by
  44658. + * the weight-raising mechanism.
  44659. + */
  44660. + bfqq->budget_timeout = jiffies;
  44661. + bfq_del_bfqq_busy(bfqd, bfqq, 1);
  44662. + } else {
  44663. + bfq_activate_bfqq(bfqd, bfqq);
  44664. + /*
  44665. + * Resort priority tree of potential close cooperators.
  44666. + */
  44667. + bfq_rq_pos_tree_add(bfqd, bfqq);
  44668. + }
  44669. +}
  44670. +
  44671. +/**
  44672. + * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior.
  44673. + * @bfqd: device data.
  44674. + * @bfqq: queue to update.
  44675. + * @reason: reason for expiration.
  44676. + *
  44677. + * Handle the feedback on @bfqq budget. See the body for detailed
  44678. + * comments.
  44679. + */
  44680. +static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd,
  44681. + struct bfq_queue *bfqq,
  44682. + enum bfqq_expiration reason)
  44683. +{
  44684. + struct request *next_rq;
  44685. + unsigned long budget, min_budget;
  44686. +
  44687. + budget = bfqq->max_budget;
  44688. + min_budget = bfq_min_budget(bfqd);
  44689. +
  44690. + BUG_ON(bfqq != bfqd->in_service_queue);
  44691. +
  44692. + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %lu, budg left %lu",
  44693. + bfqq->entity.budget, bfq_bfqq_budget_left(bfqq));
  44694. + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %lu, min budg %lu",
  44695. + budget, bfq_min_budget(bfqd));
  44696. + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d",
  44697. + bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue));
  44698. +
  44699. + if (bfq_bfqq_sync(bfqq)) {
  44700. + switch (reason) {
  44701. + /*
  44702. + * Caveat: in all the following cases we trade latency
  44703. + * for throughput.
  44704. + */
  44705. + case BFQ_BFQQ_TOO_IDLE:
  44706. + /*
  44707. + * This is the only case where we may reduce
  44708. + * the budget: if there is no request of the
  44709. + * process still waiting for completion, then
  44710. + * we assume (tentatively) that the timer has
  44711. + * expired because the batch of requests of
  44712. + * the process could have been served with a
  44713. + * smaller budget. Hence, betting that
  44714. + * process will behave in the same way when it
  44715. + * becomes backlogged again, we reduce its
  44716. + * next budget. As long as we guess right,
  44717. + * this budget cut reduces the latency
  44718. + * experienced by the process.
  44719. + *
  44720. + * However, if there are still outstanding
  44721. + * requests, then the process may have not yet
  44722. + * issued its next request just because it is
  44723. + * still waiting for the completion of some of
  44724. + * the still outstanding ones. So in this
  44725. + * subcase we do not reduce its budget, on the
  44726. + * contrary we increase it to possibly boost
  44727. + * the throughput, as discussed in the
  44728. + * comments to the BUDGET_TIMEOUT case.
  44729. + */
  44730. + if (bfqq->dispatched > 0) /* still outstanding reqs */
  44731. + budget = min(budget * 2, bfqd->bfq_max_budget);
  44732. + else {
  44733. + if (budget > 5 * min_budget)
  44734. + budget -= 4 * min_budget;
  44735. + else
  44736. + budget = min_budget;
  44737. + }
  44738. + break;
  44739. + case BFQ_BFQQ_BUDGET_TIMEOUT:
  44740. + /*
  44741. + * We double the budget here because: 1) it
  44742. + * gives the chance to boost the throughput if
  44743. + * this is not a seeky process (which may have
  44744. + * bumped into this timeout because of, e.g.,
  44745. + * ZBR), 2) together with charge_full_budget
  44746. + * it helps give seeky processes higher
  44747. + * timestamps, and hence be served less
  44748. + * frequently.
  44749. + */
  44750. + budget = min(budget * 2, bfqd->bfq_max_budget);
  44751. + break;
  44752. + case BFQ_BFQQ_BUDGET_EXHAUSTED:
  44753. + /*
  44754. + * The process still has backlog, and did not
  44755. + * let either the budget timeout or the disk
  44756. + * idling timeout expire. Hence it is not
  44757. + * seeky, has a short thinktime and may be
  44758. + * happy with a higher budget too. So
  44759. + * definitely increase the budget of this good
  44760. + * candidate to boost the disk throughput.
  44761. + */
  44762. + budget = min(budget * 4, bfqd->bfq_max_budget);
  44763. + break;
  44764. + case BFQ_BFQQ_NO_MORE_REQUESTS:
  44765. + /*
  44766. + * Leave the budget unchanged.
  44767. + */
  44768. + default:
  44769. + return;
  44770. + }
  44771. + } else /* async queue */
  44772. + /* async queues get always the maximum possible budget
  44773. + * (their ability to dispatch is limited by
  44774. + * @bfqd->bfq_max_budget_async_rq).
  44775. + */
  44776. + budget = bfqd->bfq_max_budget;
  44777. +
  44778. + bfqq->max_budget = budget;
  44779. +
  44780. + if (bfqd->budgets_assigned >= 194 && bfqd->bfq_user_max_budget == 0 &&
  44781. + bfqq->max_budget > bfqd->bfq_max_budget)
  44782. + bfqq->max_budget = bfqd->bfq_max_budget;
  44783. +
  44784. + /*
  44785. + * Make sure that we have enough budget for the next request.
  44786. + * Since the finish time of the bfqq must be kept in sync with
  44787. + * the budget, be sure to call __bfq_bfqq_expire() after the
  44788. + * update.
  44789. + */
  44790. + next_rq = bfqq->next_rq;
  44791. + if (next_rq != NULL)
  44792. + bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget,
  44793. + bfq_serv_to_charge(next_rq, bfqq));
  44794. + else
  44795. + bfqq->entity.budget = bfqq->max_budget;
  44796. +
  44797. + bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %lu",
  44798. + next_rq != NULL ? blk_rq_sectors(next_rq) : 0,
  44799. + bfqq->entity.budget);
  44800. +}
  44801. +
  44802. +static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout)
  44803. +{
  44804. + unsigned long max_budget;
  44805. +
  44806. + /*
  44807. + * The max_budget calculated when autotuning is equal to the
  44808. + * amount of sectors transfered in timeout_sync at the
  44809. + * estimated peak rate.
  44810. + */
  44811. + max_budget = (unsigned long)(peak_rate * 1000 *
  44812. + timeout >> BFQ_RATE_SHIFT);
  44813. +
  44814. + return max_budget;
  44815. +}
  44816. +
  44817. +/*
  44818. + * In addition to updating the peak rate, checks whether the process
  44819. + * is "slow", and returns 1 if so. This slow flag is used, in addition
  44820. + * to the budget timeout, to reduce the amount of service provided to
  44821. + * seeky processes, and hence reduce their chances to lower the
  44822. + * throughput. See the code for more details.
  44823. + */
  44824. +static int bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  44825. + int compensate, enum bfqq_expiration reason)
  44826. +{
  44827. + u64 bw, usecs, expected, timeout;
  44828. + ktime_t delta;
  44829. + int update = 0;
  44830. +
  44831. + if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq))
  44832. + return 0;
  44833. +
  44834. + if (compensate)
  44835. + delta = bfqd->last_idling_start;
  44836. + else
  44837. + delta = ktime_get();
  44838. + delta = ktime_sub(delta, bfqd->last_budget_start);
  44839. + usecs = ktime_to_us(delta);
  44840. +
  44841. + /* Don't trust short/unrealistic values. */
  44842. + if (usecs < 100 || usecs >= LONG_MAX)
  44843. + return 0;
  44844. +
  44845. + /*
  44846. + * Calculate the bandwidth for the last slice. We use a 64 bit
  44847. + * value to store the peak rate, in sectors per usec in fixed
  44848. + * point math. We do so to have enough precision in the estimate
  44849. + * and to avoid overflows.
  44850. + */
  44851. + bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT;
  44852. + do_div(bw, (unsigned long)usecs);
  44853. +
  44854. + timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]);
  44855. +
  44856. + /*
  44857. + * Use only long (> 20ms) intervals to filter out spikes for
  44858. + * the peak rate estimation.
  44859. + */
  44860. + if (usecs > 20000) {
  44861. + if (bw > bfqd->peak_rate ||
  44862. + (!BFQQ_SEEKY(bfqq) &&
  44863. + reason == BFQ_BFQQ_BUDGET_TIMEOUT)) {
  44864. + bfq_log(bfqd, "measured bw =%llu", bw);
  44865. + /*
  44866. + * To smooth oscillations use a low-pass filter with
  44867. + * alpha=7/8, i.e.,
  44868. + * new_rate = (7/8) * old_rate + (1/8) * bw
  44869. + */
  44870. + do_div(bw, 8);
  44871. + if (bw == 0)
  44872. + return 0;
  44873. + bfqd->peak_rate *= 7;
  44874. + do_div(bfqd->peak_rate, 8);
  44875. + bfqd->peak_rate += bw;
  44876. + update = 1;
  44877. + bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate);
  44878. + }
  44879. +
  44880. + update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1;
  44881. +
  44882. + if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES)
  44883. + bfqd->peak_rate_samples++;
  44884. +
  44885. + if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES &&
  44886. + update) {
  44887. + int dev_type = blk_queue_nonrot(bfqd->queue);
  44888. + if (bfqd->bfq_user_max_budget == 0) {
  44889. + bfqd->bfq_max_budget =
  44890. + bfq_calc_max_budget(bfqd->peak_rate,
  44891. + timeout);
  44892. + bfq_log(bfqd, "new max_budget=%lu",
  44893. + bfqd->bfq_max_budget);
  44894. + }
  44895. + if (bfqd->device_speed == BFQ_BFQD_FAST &&
  44896. + bfqd->peak_rate < device_speed_thresh[dev_type]) {
  44897. + bfqd->device_speed = BFQ_BFQD_SLOW;
  44898. + bfqd->RT_prod = R_slow[dev_type] *
  44899. + T_slow[dev_type];
  44900. + } else if (bfqd->device_speed == BFQ_BFQD_SLOW &&
  44901. + bfqd->peak_rate > device_speed_thresh[dev_type]) {
  44902. + bfqd->device_speed = BFQ_BFQD_FAST;
  44903. + bfqd->RT_prod = R_fast[dev_type] *
  44904. + T_fast[dev_type];
  44905. + }
  44906. + }
  44907. + }
  44908. +
  44909. + /*
  44910. + * If the process has been served for a too short time
  44911. + * interval to let its possible sequential accesses prevail on
  44912. + * the initial seek time needed to move the disk head on the
  44913. + * first sector it requested, then give the process a chance
  44914. + * and for the moment return false.
  44915. + */
  44916. + if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8)
  44917. + return 0;
  44918. +
  44919. + /*
  44920. + * A process is considered ``slow'' (i.e., seeky, so that we
  44921. + * cannot treat it fairly in the service domain, as it would
  44922. + * slow down too much the other processes) if, when a slice
  44923. + * ends for whatever reason, it has received service at a
  44924. + * rate that would not be high enough to complete the budget
  44925. + * before the budget timeout expiration.
  44926. + */
  44927. + expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT;
  44928. +
  44929. + /*
  44930. + * Caveat: processes doing IO in the slower disk zones will
  44931. + * tend to be slow(er) even if not seeky. And the estimated
  44932. + * peak rate will actually be an average over the disk
  44933. + * surface. Hence, to not be too harsh with unlucky processes,
  44934. + * we keep a budget/3 margin of safety before declaring a
  44935. + * process slow.
  44936. + */
  44937. + return expected > (4 * bfqq->entity.budget) / 3;
  44938. +}
  44939. +
  44940. +/*
  44941. + * To be deemed as soft real-time, an application must meet two
  44942. + * requirements. First, the application must not require an average
  44943. + * bandwidth higher than the approximate bandwidth required to playback or
  44944. + * record a compressed high-definition video.
  44945. + * The next function is invoked on the completion of the last request of a
  44946. + * batch, to compute the next-start time instant, soft_rt_next_start, such
  44947. + * that, if the next request of the application does not arrive before
  44948. + * soft_rt_next_start, then the above requirement on the bandwidth is met.
  44949. + *
  44950. + * The second requirement is that the request pattern of the application is
  44951. + * isochronous, i.e., that, after issuing a request or a batch of requests,
  44952. + * the application stops issuing new requests until all its pending requests
  44953. + * have been completed. After that, the application may issue a new batch,
  44954. + * and so on.
  44955. + * For this reason the next function is invoked to compute
  44956. + * soft_rt_next_start only for applications that meet this requirement,
  44957. + * whereas soft_rt_next_start is set to infinity for applications that do
  44958. + * not.
  44959. + *
  44960. + * Unfortunately, even a greedy application may happen to behave in an
  44961. + * isochronous way if the CPU load is high. In fact, the application may
  44962. + * stop issuing requests while the CPUs are busy serving other processes,
  44963. + * then restart, then stop again for a while, and so on. In addition, if
  44964. + * the disk achieves a low enough throughput with the request pattern
  44965. + * issued by the application (e.g., because the request pattern is random
  44966. + * and/or the device is slow), then the application may meet the above
  44967. + * bandwidth requirement too. To prevent such a greedy application to be
  44968. + * deemed as soft real-time, a further rule is used in the computation of
  44969. + * soft_rt_next_start: soft_rt_next_start must be higher than the current
  44970. + * time plus the maximum time for which the arrival of a request is waited
  44971. + * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle.
  44972. + * This filters out greedy applications, as the latter issue instead their
  44973. + * next request as soon as possible after the last one has been completed
  44974. + * (in contrast, when a batch of requests is completed, a soft real-time
  44975. + * application spends some time processing data).
  44976. + *
  44977. + * Unfortunately, the last filter may easily generate false positives if
  44978. + * only bfqd->bfq_slice_idle is used as a reference time interval and one
  44979. + * or both the following cases occur:
  44980. + * 1) HZ is so low that the duration of a jiffy is comparable to or higher
  44981. + * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with
  44982. + * HZ=100.
  44983. + * 2) jiffies, instead of increasing at a constant rate, may stop increasing
  44984. + * for a while, then suddenly 'jump' by several units to recover the lost
  44985. + * increments. This seems to happen, e.g., inside virtual machines.
  44986. + * To address this issue, we do not use as a reference time interval just
  44987. + * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In
  44988. + * particular we add the minimum number of jiffies for which the filter
  44989. + * seems to be quite precise also in embedded systems and KVM/QEMU virtual
  44990. + * machines.
  44991. + */
  44992. +static inline unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd,
  44993. + struct bfq_queue *bfqq)
  44994. +{
  44995. + return max(bfqq->last_idle_bklogged +
  44996. + HZ * bfqq->service_from_backlogged /
  44997. + bfqd->bfq_wr_max_softrt_rate,
  44998. + jiffies + bfqq->bfqd->bfq_slice_idle + 4);
  44999. +}
  45000. +
  45001. +/*
  45002. + * Return the largest-possible time instant such that, for as long as possible,
  45003. + * the current time will be lower than this time instant according to the macro
  45004. + * time_is_before_jiffies().
  45005. + */
  45006. +static inline unsigned long bfq_infinity_from_now(unsigned long now)
  45007. +{
  45008. + return now + ULONG_MAX / 2;
  45009. +}
  45010. +
  45011. +/**
  45012. + * bfq_bfqq_expire - expire a queue.
  45013. + * @bfqd: device owning the queue.
  45014. + * @bfqq: the queue to expire.
  45015. + * @compensate: if true, compensate for the time spent idling.
  45016. + * @reason: the reason causing the expiration.
  45017. + *
  45018. + *
  45019. + * If the process associated to the queue is slow (i.e., seeky), or in
  45020. + * case of budget timeout, or, finally, if it is async, we
  45021. + * artificially charge it an entire budget (independently of the
  45022. + * actual service it received). As a consequence, the queue will get
  45023. + * higher timestamps than the correct ones upon reactivation, and
  45024. + * hence it will be rescheduled as if it had received more service
  45025. + * than what it actually received. In the end, this class of processes
  45026. + * will receive less service in proportion to how slowly they consume
  45027. + * their budgets (and hence how seriously they tend to lower the
  45028. + * throughput).
  45029. + *
  45030. + * In contrast, when a queue expires because it has been idling for
  45031. + * too much or because it exhausted its budget, we do not touch the
  45032. + * amount of service it has received. Hence when the queue will be
  45033. + * reactivated and its timestamps updated, the latter will be in sync
  45034. + * with the actual service received by the queue until expiration.
  45035. + *
  45036. + * Charging a full budget to the first type of queues and the exact
  45037. + * service to the others has the effect of using the WF2Q+ policy to
  45038. + * schedule the former on a timeslice basis, without violating the
  45039. + * service domain guarantees of the latter.
  45040. + */
  45041. +static void bfq_bfqq_expire(struct bfq_data *bfqd,
  45042. + struct bfq_queue *bfqq,
  45043. + int compensate,
  45044. + enum bfqq_expiration reason)
  45045. +{
  45046. + int slow;
  45047. + BUG_ON(bfqq != bfqd->in_service_queue);
  45048. +
  45049. + /* Update disk peak rate for autotuning and check whether the
  45050. + * process is slow (see bfq_update_peak_rate).
  45051. + */
  45052. + slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason);
  45053. +
  45054. + /*
  45055. + * As above explained, 'punish' slow (i.e., seeky), timed-out
  45056. + * and async queues, to favor sequential sync workloads.
  45057. + *
  45058. + * Processes doing I/O in the slower disk zones will tend to be
  45059. + * slow(er) even if not seeky. Hence, since the estimated peak
  45060. + * rate is actually an average over the disk surface, these
  45061. + * processes may timeout just for bad luck. To avoid punishing
  45062. + * them we do not charge a full budget to a process that
  45063. + * succeeded in consuming at least 2/3 of its budget.
  45064. + */
  45065. + if (slow || (reason == BFQ_BFQQ_BUDGET_TIMEOUT &&
  45066. + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3))
  45067. + bfq_bfqq_charge_full_budget(bfqq);
  45068. +
  45069. + bfqq->service_from_backlogged += bfqq->entity.service;
  45070. +
  45071. + if (BFQQ_SEEKY(bfqq) && reason == BFQ_BFQQ_BUDGET_TIMEOUT &&
  45072. + !bfq_bfqq_constantly_seeky(bfqq)) {
  45073. + bfq_mark_bfqq_constantly_seeky(bfqq);
  45074. + if (!blk_queue_nonrot(bfqd->queue))
  45075. + bfqd->const_seeky_busy_in_flight_queues++;
  45076. + }
  45077. +
  45078. + if (reason == BFQ_BFQQ_TOO_IDLE &&
  45079. + bfqq->entity.service <= 2 * bfqq->entity.budget / 10 )
  45080. + bfq_clear_bfqq_IO_bound(bfqq);
  45081. +
  45082. + if (bfqd->low_latency && bfqq->wr_coeff == 1)
  45083. + bfqq->last_wr_start_finish = jiffies;
  45084. +
  45085. + if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 &&
  45086. + RB_EMPTY_ROOT(&bfqq->sort_list)) {
  45087. + /*
  45088. + * If we get here, and there are no outstanding requests,
  45089. + * then the request pattern is isochronous (see the comments
  45090. + * to the function bfq_bfqq_softrt_next_start()). Hence we
  45091. + * can compute soft_rt_next_start. If, instead, the queue
  45092. + * still has outstanding requests, then we have to wait
  45093. + * for the completion of all the outstanding requests to
  45094. + * discover whether the request pattern is actually
  45095. + * isochronous.
  45096. + */
  45097. + if (bfqq->dispatched == 0)
  45098. + bfqq->soft_rt_next_start =
  45099. + bfq_bfqq_softrt_next_start(bfqd, bfqq);
  45100. + else {
  45101. + /*
  45102. + * The application is still waiting for the
  45103. + * completion of one or more requests:
  45104. + * prevent it from possibly being incorrectly
  45105. + * deemed as soft real-time by setting its
  45106. + * soft_rt_next_start to infinity. In fact,
  45107. + * without this assignment, the application
  45108. + * would be incorrectly deemed as soft
  45109. + * real-time if:
  45110. + * 1) it issued a new request before the
  45111. + * completion of all its in-flight
  45112. + * requests, and
  45113. + * 2) at that time, its soft_rt_next_start
  45114. + * happened to be in the past.
  45115. + */
  45116. + bfqq->soft_rt_next_start =
  45117. + bfq_infinity_from_now(jiffies);
  45118. + /*
  45119. + * Schedule an update of soft_rt_next_start to when
  45120. + * the task may be discovered to be isochronous.
  45121. + */
  45122. + bfq_mark_bfqq_softrt_update(bfqq);
  45123. + }
  45124. + }
  45125. +
  45126. + bfq_log_bfqq(bfqd, bfqq,
  45127. + "expire (%d, slow %d, num_disp %d, idle_win %d)", reason,
  45128. + slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq));
  45129. +
  45130. + /*
  45131. + * Increase, decrease or leave budget unchanged according to
  45132. + * reason.
  45133. + */
  45134. + __bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
  45135. + __bfq_bfqq_expire(bfqd, bfqq);
  45136. +}
  45137. +
  45138. +/*
  45139. + * Budget timeout is not implemented through a dedicated timer, but
  45140. + * just checked on request arrivals and completions, as well as on
  45141. + * idle timer expirations.
  45142. + */
  45143. +static int bfq_bfqq_budget_timeout(struct bfq_queue *bfqq)
  45144. +{
  45145. + if (bfq_bfqq_budget_new(bfqq) ||
  45146. + time_before(jiffies, bfqq->budget_timeout))
  45147. + return 0;
  45148. + return 1;
  45149. +}
  45150. +
  45151. +/*
  45152. + * If we expire a queue that is waiting for the arrival of a new
  45153. + * request, we may prevent the fictitious timestamp back-shifting that
  45154. + * allows the guarantees of the queue to be preserved (see [1] for
  45155. + * this tricky aspect). Hence we return true only if this condition
  45156. + * does not hold, or if the queue is slow enough to deserve only to be
  45157. + * kicked off for preserving a high throughput.
  45158. +*/
  45159. +static inline int bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq)
  45160. +{
  45161. + bfq_log_bfqq(bfqq->bfqd, bfqq,
  45162. + "may_budget_timeout: wait_request %d left %d timeout %d",
  45163. + bfq_bfqq_wait_request(bfqq),
  45164. + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3,
  45165. + bfq_bfqq_budget_timeout(bfqq));
  45166. +
  45167. + return (!bfq_bfqq_wait_request(bfqq) ||
  45168. + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3)
  45169. + &&
  45170. + bfq_bfqq_budget_timeout(bfqq);
  45171. +}
  45172. +
  45173. +/*
  45174. + * Device idling is allowed only for the queues for which this function
  45175. + * returns true. For this reason, the return value of this function plays a
  45176. + * critical role for both throughput boosting and service guarantees. The
  45177. + * return value is computed through a logical expression. In this rather
  45178. + * long comment, we try to briefly describe all the details and motivations
  45179. + * behind the components of this logical expression.
  45180. + *
  45181. + * First, the expression may be true only for sync queues. Besides, if
  45182. + * bfqq is also being weight-raised, then the expression always evaluates
  45183. + * to true, as device idling is instrumental for preserving low-latency
  45184. + * guarantees (see [1]). Otherwise, the expression evaluates to true only
  45185. + * if bfqq has a non-null idle window and at least one of the following
  45186. + * two conditions holds. The first condition is that the device is not
  45187. + * performing NCQ, because idling the device most certainly boosts the
  45188. + * throughput if this condition holds and bfqq has been granted a non-null
  45189. + * idle window. The second compound condition is made of the logical AND of
  45190. + * two components.
  45191. + *
  45192. + * The first component is true only if there is no weight-raised busy
  45193. + * queue. This guarantees that the device is not idled for a sync non-
  45194. + * weight-raised queue when there are busy weight-raised queues. The former
  45195. + * is then expired immediately if empty. Combined with the timestamping
  45196. + * rules of BFQ (see [1] for details), this causes sync non-weight-raised
  45197. + * queues to get a lower number of requests served, and hence to ask for a
  45198. + * lower number of requests from the request pool, before the busy weight-
  45199. + * raised queues get served again.
  45200. + *
  45201. + * This is beneficial for the processes associated with weight-raised
  45202. + * queues, when the request pool is saturated (e.g., in the presence of
  45203. + * write hogs). In fact, if the processes associated with the other queues
  45204. + * ask for requests at a lower rate, then weight-raised processes have a
  45205. + * higher probability to get a request from the pool immediately (or at
  45206. + * least soon) when they need one. Hence they have a higher probability to
  45207. + * actually get a fraction of the disk throughput proportional to their
  45208. + * high weight. This is especially true with NCQ-capable drives, which
  45209. + * enqueue several requests in advance and further reorder internally-
  45210. + * queued requests.
  45211. + *
  45212. + * In the end, mistreating non-weight-raised queues when there are busy
  45213. + * weight-raised queues seems to mitigate starvation problems in the
  45214. + * presence of heavy write workloads and NCQ, and hence to guarantee a
  45215. + * higher application and system responsiveness in these hostile scenarios.
  45216. + *
  45217. + * If the first component of the compound condition is instead true, i.e.,
  45218. + * there is no weight-raised busy queue, then the second component of the
  45219. + * compound condition takes into account service-guarantee and throughput
  45220. + * issues related to NCQ (recall that the compound condition is evaluated
  45221. + * only if the device is detected as supporting NCQ).
  45222. + *
  45223. + * As for service guarantees, allowing the drive to enqueue more than one
  45224. + * request at a time, and hence delegating de facto final scheduling
  45225. + * decisions to the drive's internal scheduler, causes loss of control on
  45226. + * the actual request service order. In this respect, when the drive is
  45227. + * allowed to enqueue more than one request at a time, the service
  45228. + * distribution enforced by the drive's internal scheduler is likely to
  45229. + * coincide with the desired device-throughput distribution only in the
  45230. + * following, perfectly symmetric, scenario:
  45231. + * 1) all active queues have the same weight,
  45232. + * 2) all active groups at the same level in the groups tree have the same
  45233. + * weight,
  45234. + * 3) all active groups at the same level in the groups tree have the same
  45235. + * number of children.
  45236. + *
  45237. + * Even in such a scenario, sequential I/O may still receive a preferential
  45238. + * treatment, but this is not likely to be a big issue with flash-based
  45239. + * devices, because of their non-dramatic loss of throughput with random
  45240. + * I/O. Things do differ with HDDs, for which additional care is taken, as
  45241. + * explained after completing the discussion for flash-based devices.
  45242. + *
  45243. + * Unfortunately, keeping the necessary state for evaluating exactly the
  45244. + * above symmetry conditions would be quite complex and time-consuming.
  45245. + * Therefore BFQ evaluates instead the following stronger sub-conditions,
  45246. + * for which it is much easier to maintain the needed state:
  45247. + * 1) all active queues have the same weight,
  45248. + * 2) all active groups have the same weight,
  45249. + * 3) all active groups have at most one active child each.
  45250. + * In particular, the last two conditions are always true if hierarchical
  45251. + * support and the cgroups interface are not enabled, hence no state needs
  45252. + * to be maintained in this case.
  45253. + *
  45254. + * According to the above considerations, the second component of the
  45255. + * compound condition evaluates to true if any of the above symmetry
  45256. + * sub-condition does not hold, or the device is not flash-based. Therefore,
  45257. + * if also the first component is true, then idling is allowed for a sync
  45258. + * queue. These are the only sub-conditions considered if the device is
  45259. + * flash-based, as, for such a device, it is sensible to force idling only
  45260. + * for service-guarantee issues. In fact, as for throughput, idling
  45261. + * NCQ-capable flash-based devices would not boost the throughput even
  45262. + * with sequential I/O; rather it would lower the throughput in proportion
  45263. + * to how fast the device is. In the end, (only) if all the three
  45264. + * sub-conditions hold and the device is flash-based, the compound
  45265. + * condition evaluates to false and therefore no idling is performed.
  45266. + *
  45267. + * As already said, things change with a rotational device, where idling
  45268. + * boosts the throughput with sequential I/O (even with NCQ). Hence, for
  45269. + * such a device the second component of the compound condition evaluates
  45270. + * to true also if the following additional sub-condition does not hold:
  45271. + * the queue is constantly seeky. Unfortunately, this different behavior
  45272. + * with respect to flash-based devices causes an additional asymmetry: if
  45273. + * some sync queues enjoy idling and some other sync queues do not, then
  45274. + * the latter get a low share of the device throughput, simply because the
  45275. + * former get many requests served after being set as in service, whereas
  45276. + * the latter do not. As a consequence, to guarantee the desired throughput
  45277. + * distribution, on HDDs the compound expression evaluates to true (and
  45278. + * hence device idling is performed) also if the following last symmetry
  45279. + * condition does not hold: no other queue is benefiting from idling. Also
  45280. + * this last condition is actually replaced with a simpler-to-maintain and
  45281. + * stronger condition: there is no busy queue which is not constantly seeky
  45282. + * (and hence may also benefit from idling).
  45283. + *
  45284. + * To sum up, when all the required symmetry and throughput-boosting
  45285. + * sub-conditions hold, the second component of the compound condition
  45286. + * evaluates to false, and hence no idling is performed. This helps to
  45287. + * keep the drives' internal queues full on NCQ-capable devices, and hence
  45288. + * to boost the throughput, without causing 'almost' any loss of service
  45289. + * guarantees. The 'almost' follows from the fact that, if the internal
  45290. + * queue of one such device is filled while all the sub-conditions hold,
  45291. + * but at some point in time some sub-condition stops to hold, then it may
  45292. + * become impossible to let requests be served in the new desired order
  45293. + * until all the requests already queued in the device have been served.
  45294. + */
  45295. +static inline bool bfq_bfqq_must_not_expire(struct bfq_queue *bfqq)
  45296. +{
  45297. + struct bfq_data *bfqd = bfqq->bfqd;
  45298. +#ifdef CONFIG_CGROUP_BFQIO
  45299. +#define symmetric_scenario (!bfqd->active_numerous_groups && \
  45300. + !bfq_differentiated_weights(bfqd))
  45301. +#else
  45302. +#define symmetric_scenario (!bfq_differentiated_weights(bfqd))
  45303. +#endif
  45304. +#define cond_for_seeky_on_ncq_hdd (bfq_bfqq_constantly_seeky(bfqq) && \
  45305. + bfqd->busy_in_flight_queues == \
  45306. + bfqd->const_seeky_busy_in_flight_queues)
  45307. +/*
  45308. + * Condition for expiring a non-weight-raised queue (and hence not idling
  45309. + * the device).
  45310. + */
  45311. +#define cond_for_expiring_non_wr (bfqd->hw_tag && \
  45312. + (bfqd->wr_busy_queues > 0 || \
  45313. + (symmetric_scenario && \
  45314. + (blk_queue_nonrot(bfqd->queue) || \
  45315. + cond_for_seeky_on_ncq_hdd))))
  45316. +
  45317. + return bfq_bfqq_sync(bfqq) &&
  45318. + (bfq_bfqq_IO_bound(bfqq) || bfqq->wr_coeff > 1) &&
  45319. + (bfqq->wr_coeff > 1 ||
  45320. + (bfq_bfqq_idle_window(bfqq) &&
  45321. + !cond_for_expiring_non_wr)
  45322. + );
  45323. +}
  45324. +
  45325. +/*
  45326. + * If the in-service queue is empty but sync, and the function
  45327. + * bfq_bfqq_must_not_expire returns true, then:
  45328. + * 1) the queue must remain in service and cannot be expired, and
  45329. + * 2) the disk must be idled to wait for the possible arrival of a new
  45330. + * request for the queue.
  45331. + * See the comments to the function bfq_bfqq_must_not_expire for the reasons
  45332. + * why performing device idling is the best choice to boost the throughput
  45333. + * and preserve service guarantees when bfq_bfqq_must_not_expire itself
  45334. + * returns true.
  45335. + */
  45336. +static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq)
  45337. +{
  45338. + struct bfq_data *bfqd = bfqq->bfqd;
  45339. +
  45340. + return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 &&
  45341. + bfq_bfqq_must_not_expire(bfqq);
  45342. +}
  45343. +
  45344. +/*
  45345. + * Select a queue for service. If we have a current queue in service,
  45346. + * check whether to continue servicing it, or retrieve and set a new one.
  45347. + */
  45348. +static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
  45349. +{
  45350. + struct bfq_queue *bfqq;
  45351. + struct request *next_rq;
  45352. + enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT;
  45353. +
  45354. + bfqq = bfqd->in_service_queue;
  45355. + if (bfqq == NULL)
  45356. + goto new_queue;
  45357. +
  45358. + bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue");
  45359. +
  45360. + if (bfq_may_expire_for_budg_timeout(bfqq) &&
  45361. + !timer_pending(&bfqd->idle_slice_timer) &&
  45362. + !bfq_bfqq_must_idle(bfqq))
  45363. + goto expire;
  45364. +
  45365. + next_rq = bfqq->next_rq;
  45366. + /*
  45367. + * If bfqq has requests queued and it has enough budget left to
  45368. + * serve them, keep the queue, otherwise expire it.
  45369. + */
  45370. + if (next_rq != NULL) {
  45371. + if (bfq_serv_to_charge(next_rq, bfqq) >
  45372. + bfq_bfqq_budget_left(bfqq)) {
  45373. + reason = BFQ_BFQQ_BUDGET_EXHAUSTED;
  45374. + goto expire;
  45375. + } else {
  45376. + /*
  45377. + * The idle timer may be pending because we may
  45378. + * not disable disk idling even when a new request
  45379. + * arrives.
  45380. + */
  45381. + if (timer_pending(&bfqd->idle_slice_timer)) {
  45382. + /*
  45383. + * If we get here: 1) at least a new request
  45384. + * has arrived but we have not disabled the
  45385. + * timer because the request was too small,
  45386. + * 2) then the block layer has unplugged
  45387. + * the device, causing the dispatch to be
  45388. + * invoked.
  45389. + *
  45390. + * Since the device is unplugged, now the
  45391. + * requests are probably large enough to
  45392. + * provide a reasonable throughput.
  45393. + * So we disable idling.
  45394. + */
  45395. + bfq_clear_bfqq_wait_request(bfqq);
  45396. + del_timer(&bfqd->idle_slice_timer);
  45397. + }
  45398. + goto keep_queue;
  45399. + }
  45400. + }
  45401. +
  45402. + /*
  45403. + * No requests pending. If the in-service queue still has requests
  45404. + * in flight (possibly waiting for a completion) or is idling for a
  45405. + * new request, then keep it.
  45406. + */
  45407. + if (timer_pending(&bfqd->idle_slice_timer) ||
  45408. + (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq))) {
  45409. + bfqq = NULL;
  45410. + goto keep_queue;
  45411. + }
  45412. +
  45413. + reason = BFQ_BFQQ_NO_MORE_REQUESTS;
  45414. +expire:
  45415. + bfq_bfqq_expire(bfqd, bfqq, 0, reason);
  45416. +new_queue:
  45417. + bfqq = bfq_set_in_service_queue(bfqd);
  45418. + bfq_log(bfqd, "select_queue: new queue %d returned",
  45419. + bfqq != NULL ? bfqq->pid : 0);
  45420. +keep_queue:
  45421. + return bfqq;
  45422. +}
  45423. +
  45424. +static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  45425. +{
  45426. + struct bfq_entity *entity = &bfqq->entity;
  45427. + if (bfqq->wr_coeff > 1) { /* queue is being weight-raised */
  45428. + bfq_log_bfqq(bfqd, bfqq,
  45429. + "raising period dur %u/%u msec, old coeff %u, w %d(%d)",
  45430. + jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish),
  45431. + jiffies_to_msecs(bfqq->wr_cur_max_time),
  45432. + bfqq->wr_coeff,
  45433. + bfqq->entity.weight, bfqq->entity.orig_weight);
  45434. +
  45435. + BUG_ON(bfqq != bfqd->in_service_queue && entity->weight !=
  45436. + entity->orig_weight * bfqq->wr_coeff);
  45437. + if (entity->ioprio_changed)
  45438. + bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change");
  45439. +
  45440. + /*
  45441. + * If too much time has elapsed from the beginning
  45442. + * of this weight-raising period, or the queue has
  45443. + * exceeded the acceptable number of cooperations,
  45444. + * stop it.
  45445. + */
  45446. + if (bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh ||
  45447. + time_is_before_jiffies(bfqq->last_wr_start_finish +
  45448. + bfqq->wr_cur_max_time)) {
  45449. + bfqq->last_wr_start_finish = jiffies;
  45450. + bfq_log_bfqq(bfqd, bfqq,
  45451. + "wrais ending at %lu, rais_max_time %u",
  45452. + bfqq->last_wr_start_finish,
  45453. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  45454. + bfq_bfqq_end_wr(bfqq);
  45455. + }
  45456. + }
  45457. + /* Update weight both if it must be raised and if it must be lowered */
  45458. + if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1))
  45459. + __bfq_entity_update_weight_prio(
  45460. + bfq_entity_service_tree(entity),
  45461. + entity);
  45462. +}
  45463. +
  45464. +/*
  45465. + * Dispatch one request from bfqq, moving it to the request queue
  45466. + * dispatch list.
  45467. + */
  45468. +static int bfq_dispatch_request(struct bfq_data *bfqd,
  45469. + struct bfq_queue *bfqq)
  45470. +{
  45471. + int dispatched = 0;
  45472. + struct request *rq;
  45473. + unsigned long service_to_charge;
  45474. +
  45475. + BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
  45476. +
  45477. + /* Follow expired path, else get first next available. */
  45478. + rq = bfq_check_fifo(bfqq);
  45479. + if (rq == NULL)
  45480. + rq = bfqq->next_rq;
  45481. + service_to_charge = bfq_serv_to_charge(rq, bfqq);
  45482. +
  45483. + if (service_to_charge > bfq_bfqq_budget_left(bfqq)) {
  45484. + /*
  45485. + * This may happen if the next rq is chosen in fifo order
  45486. + * instead of sector order. The budget is properly
  45487. + * dimensioned to be always sufficient to serve the next
  45488. + * request only if it is chosen in sector order. The reason
  45489. + * is that it would be quite inefficient and little useful
  45490. + * to always make sure that the budget is large enough to
  45491. + * serve even the possible next rq in fifo order.
  45492. + * In fact, requests are seldom served in fifo order.
  45493. + *
  45494. + * Expire the queue for budget exhaustion, and make sure
  45495. + * that the next act_budget is enough to serve the next
  45496. + * request, even if it comes from the fifo expired path.
  45497. + */
  45498. + bfqq->next_rq = rq;
  45499. + /*
  45500. + * Since this dispatch is failed, make sure that
  45501. + * a new one will be performed
  45502. + */
  45503. + if (!bfqd->rq_in_driver)
  45504. + bfq_schedule_dispatch(bfqd);
  45505. + goto expire;
  45506. + }
  45507. +
  45508. + /* Finally, insert request into driver dispatch list. */
  45509. + bfq_bfqq_served(bfqq, service_to_charge);
  45510. + bfq_dispatch_insert(bfqd->queue, rq);
  45511. +
  45512. + bfq_update_wr_data(bfqd, bfqq);
  45513. +
  45514. + bfq_log_bfqq(bfqd, bfqq,
  45515. + "dispatched %u sec req (%llu), budg left %lu",
  45516. + blk_rq_sectors(rq),
  45517. + (long long unsigned)blk_rq_pos(rq),
  45518. + bfq_bfqq_budget_left(bfqq));
  45519. +
  45520. + dispatched++;
  45521. +
  45522. + if (bfqd->in_service_bic == NULL) {
  45523. + atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount);
  45524. + bfqd->in_service_bic = RQ_BIC(rq);
  45525. + }
  45526. +
  45527. + if (bfqd->busy_queues > 1 && ((!bfq_bfqq_sync(bfqq) &&
  45528. + dispatched >= bfqd->bfq_max_budget_async_rq) ||
  45529. + bfq_class_idle(bfqq)))
  45530. + goto expire;
  45531. +
  45532. + return dispatched;
  45533. +
  45534. +expire:
  45535. + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_EXHAUSTED);
  45536. + return dispatched;
  45537. +}
  45538. +
  45539. +static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq)
  45540. +{
  45541. + int dispatched = 0;
  45542. +
  45543. + while (bfqq->next_rq != NULL) {
  45544. + bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq);
  45545. + dispatched++;
  45546. + }
  45547. +
  45548. + BUG_ON(!list_empty(&bfqq->fifo));
  45549. + return dispatched;
  45550. +}
  45551. +
  45552. +/*
  45553. + * Drain our current requests.
  45554. + * Used for barriers and when switching io schedulers on-the-fly.
  45555. + */
  45556. +static int bfq_forced_dispatch(struct bfq_data *bfqd)
  45557. +{
  45558. + struct bfq_queue *bfqq, *n;
  45559. + struct bfq_service_tree *st;
  45560. + int dispatched = 0;
  45561. +
  45562. + bfqq = bfqd->in_service_queue;
  45563. + if (bfqq != NULL)
  45564. + __bfq_bfqq_expire(bfqd, bfqq);
  45565. +
  45566. + /*
  45567. + * Loop through classes, and be careful to leave the scheduler
  45568. + * in a consistent state, as feedback mechanisms and vtime
  45569. + * updates cannot be disabled during the process.
  45570. + */
  45571. + list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) {
  45572. + st = bfq_entity_service_tree(&bfqq->entity);
  45573. +
  45574. + dispatched += __bfq_forced_dispatch_bfqq(bfqq);
  45575. + bfqq->max_budget = bfq_max_budget(bfqd);
  45576. +
  45577. + bfq_forget_idle(st);
  45578. + }
  45579. +
  45580. + BUG_ON(bfqd->busy_queues != 0);
  45581. +
  45582. + return dispatched;
  45583. +}
  45584. +
  45585. +static int bfq_dispatch_requests(struct request_queue *q, int force)
  45586. +{
  45587. + struct bfq_data *bfqd = q->elevator->elevator_data;
  45588. + struct bfq_queue *bfqq;
  45589. + int max_dispatch;
  45590. +
  45591. + bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues);
  45592. + if (bfqd->busy_queues == 0)
  45593. + return 0;
  45594. +
  45595. + if (unlikely(force))
  45596. + return bfq_forced_dispatch(bfqd);
  45597. +
  45598. + bfqq = bfq_select_queue(bfqd);
  45599. + if (bfqq == NULL)
  45600. + return 0;
  45601. +
  45602. + max_dispatch = bfqd->bfq_quantum;
  45603. + if (bfq_class_idle(bfqq))
  45604. + max_dispatch = 1;
  45605. +
  45606. + if (!bfq_bfqq_sync(bfqq))
  45607. + max_dispatch = bfqd->bfq_max_budget_async_rq;
  45608. +
  45609. + if (bfqq->dispatched >= max_dispatch) {
  45610. + if (bfqd->busy_queues > 1)
  45611. + return 0;
  45612. + if (bfqq->dispatched >= 4 * max_dispatch)
  45613. + return 0;
  45614. + }
  45615. +
  45616. + if (bfqd->sync_flight != 0 && !bfq_bfqq_sync(bfqq))
  45617. + return 0;
  45618. +
  45619. + bfq_clear_bfqq_wait_request(bfqq);
  45620. + BUG_ON(timer_pending(&bfqd->idle_slice_timer));
  45621. +
  45622. + if (!bfq_dispatch_request(bfqd, bfqq))
  45623. + return 0;
  45624. +
  45625. + bfq_log_bfqq(bfqd, bfqq, "dispatched one request of %d (max_disp %d)",
  45626. + bfqq->pid, max_dispatch);
  45627. +
  45628. + return 1;
  45629. +}
  45630. +
  45631. +/*
  45632. + * Task holds one reference to the queue, dropped when task exits. Each rq
  45633. + * in-flight on this queue also holds a reference, dropped when rq is freed.
  45634. + *
  45635. + * Queue lock must be held here.
  45636. + */
  45637. +static void bfq_put_queue(struct bfq_queue *bfqq)
  45638. +{
  45639. + struct bfq_data *bfqd = bfqq->bfqd;
  45640. +
  45641. + BUG_ON(atomic_read(&bfqq->ref) <= 0);
  45642. +
  45643. + bfq_log_bfqq(bfqd, bfqq, "put_queue: %p %d", bfqq,
  45644. + atomic_read(&bfqq->ref));
  45645. + if (!atomic_dec_and_test(&bfqq->ref))
  45646. + return;
  45647. +
  45648. + BUG_ON(rb_first(&bfqq->sort_list) != NULL);
  45649. + BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0);
  45650. + BUG_ON(bfqq->entity.tree != NULL);
  45651. + BUG_ON(bfq_bfqq_busy(bfqq));
  45652. + BUG_ON(bfqd->in_service_queue == bfqq);
  45653. +
  45654. + bfq_log_bfqq(bfqd, bfqq, "put_queue: %p freed", bfqq);
  45655. +
  45656. + kmem_cache_free(bfq_pool, bfqq);
  45657. +}
  45658. +
  45659. +static void bfq_put_cooperator(struct bfq_queue *bfqq)
  45660. +{
  45661. + struct bfq_queue *__bfqq, *next;
  45662. +
  45663. + /*
  45664. + * If this queue was scheduled to merge with another queue, be
  45665. + * sure to drop the reference taken on that queue (and others in
  45666. + * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs.
  45667. + */
  45668. + __bfqq = bfqq->new_bfqq;
  45669. + while (__bfqq) {
  45670. + if (__bfqq == bfqq)
  45671. + break;
  45672. + next = __bfqq->new_bfqq;
  45673. + bfq_put_queue(__bfqq);
  45674. + __bfqq = next;
  45675. + }
  45676. +}
  45677. +
  45678. +static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  45679. +{
  45680. + if (bfqq == bfqd->in_service_queue) {
  45681. + __bfq_bfqq_expire(bfqd, bfqq);
  45682. + bfq_schedule_dispatch(bfqd);
  45683. + }
  45684. +
  45685. + bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq,
  45686. + atomic_read(&bfqq->ref));
  45687. +
  45688. + bfq_put_cooperator(bfqq);
  45689. +
  45690. + bfq_put_queue(bfqq);
  45691. +}
  45692. +
  45693. +static inline void bfq_init_icq(struct io_cq *icq)
  45694. +{
  45695. + struct bfq_io_cq *bic = icq_to_bic(icq);
  45696. +
  45697. + bic->ttime.last_end_request = jiffies;
  45698. + /*
  45699. + * A newly created bic indicates that the process has just
  45700. + * started doing I/O, and is probably mapping into memory its
  45701. + * executable and libraries: it definitely needs weight raising.
  45702. + * There is however the possibility that the process performs,
  45703. + * for a while, I/O close to some other process. EQM intercepts
  45704. + * this behavior and may merge the queue corresponding to the
  45705. + * process with some other queue, BEFORE the weight of the queue
  45706. + * is raised. Merged queues are not weight-raised (they are assumed
  45707. + * to belong to processes that benefit only from high throughput).
  45708. + * If the merge is basically the consequence of an accident, then
  45709. + * the queue will be split soon and will get back its old weight.
  45710. + * It is then important to write down somewhere that this queue
  45711. + * does need weight raising, even if it did not make it to get its
  45712. + * weight raised before being merged. To this purpose, we overload
  45713. + * the field raising_time_left and assign 1 to it, to mark the queue
  45714. + * as needing weight raising.
  45715. + */
  45716. + bic->wr_time_left = 1;
  45717. +}
  45718. +
  45719. +static void bfq_exit_icq(struct io_cq *icq)
  45720. +{
  45721. + struct bfq_io_cq *bic = icq_to_bic(icq);
  45722. + struct bfq_data *bfqd = bic_to_bfqd(bic);
  45723. +
  45724. + if (bic->bfqq[BLK_RW_ASYNC]) {
  45725. + bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_ASYNC]);
  45726. + bic->bfqq[BLK_RW_ASYNC] = NULL;
  45727. + }
  45728. +
  45729. + if (bic->bfqq[BLK_RW_SYNC]) {
  45730. + /*
  45731. + * If the bic is using a shared queue, put the reference
  45732. + * taken on the io_context when the bic started using a
  45733. + * shared bfq_queue.
  45734. + */
  45735. + if (bfq_bfqq_coop(bic->bfqq[BLK_RW_SYNC]))
  45736. + put_io_context(icq->ioc);
  45737. + bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]);
  45738. + bic->bfqq[BLK_RW_SYNC] = NULL;
  45739. + }
  45740. +}
  45741. +
  45742. +/*
  45743. + * Update the entity prio values; note that the new values will not
  45744. + * be used until the next (re)activation.
  45745. + */
  45746. +static void bfq_init_prio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
  45747. +{
  45748. + struct task_struct *tsk = current;
  45749. + int ioprio_class;
  45750. +
  45751. + if (!bfq_bfqq_prio_changed(bfqq))
  45752. + return;
  45753. +
  45754. + ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio);
  45755. + switch (ioprio_class) {
  45756. + default:
  45757. + dev_err(bfqq->bfqd->queue->backing_dev_info.dev,
  45758. + "bfq: bad prio %x\n", ioprio_class);
  45759. + case IOPRIO_CLASS_NONE:
  45760. + /*
  45761. + * No prio set, inherit CPU scheduling settings.
  45762. + */
  45763. + bfqq->entity.new_ioprio = task_nice_ioprio(tsk);
  45764. + bfqq->entity.new_ioprio_class = task_nice_ioclass(tsk);
  45765. + break;
  45766. + case IOPRIO_CLASS_RT:
  45767. + bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
  45768. + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_RT;
  45769. + break;
  45770. + case IOPRIO_CLASS_BE:
  45771. + bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
  45772. + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_BE;
  45773. + break;
  45774. + case IOPRIO_CLASS_IDLE:
  45775. + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_IDLE;
  45776. + bfqq->entity.new_ioprio = 7;
  45777. + bfq_clear_bfqq_idle_window(bfqq);
  45778. + break;
  45779. + }
  45780. +
  45781. + bfqq->entity.ioprio_changed = 1;
  45782. +
  45783. + bfq_clear_bfqq_prio_changed(bfqq);
  45784. +}
  45785. +
  45786. +static void bfq_changed_ioprio(struct bfq_io_cq *bic)
  45787. +{
  45788. + struct bfq_data *bfqd;
  45789. + struct bfq_queue *bfqq, *new_bfqq;
  45790. + struct bfq_group *bfqg;
  45791. + unsigned long uninitialized_var(flags);
  45792. + int ioprio = bic->icq.ioc->ioprio;
  45793. +
  45794. + bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data),
  45795. + &flags);
  45796. + /*
  45797. + * This condition may trigger on a newly created bic, be sure to
  45798. + * drop the lock before returning.
  45799. + */
  45800. + if (unlikely(bfqd == NULL) || likely(bic->ioprio == ioprio))
  45801. + goto out;
  45802. +
  45803. + bfqq = bic->bfqq[BLK_RW_ASYNC];
  45804. + if (bfqq != NULL) {
  45805. + bfqg = container_of(bfqq->entity.sched_data, struct bfq_group,
  45806. + sched_data);
  45807. + new_bfqq = bfq_get_queue(bfqd, bfqg, BLK_RW_ASYNC, bic,
  45808. + GFP_ATOMIC);
  45809. + if (new_bfqq != NULL) {
  45810. + bic->bfqq[BLK_RW_ASYNC] = new_bfqq;
  45811. + bfq_log_bfqq(bfqd, bfqq,
  45812. + "changed_ioprio: bfqq %p %d",
  45813. + bfqq, atomic_read(&bfqq->ref));
  45814. + bfq_put_queue(bfqq);
  45815. + }
  45816. + }
  45817. +
  45818. + bfqq = bic->bfqq[BLK_RW_SYNC];
  45819. + if (bfqq != NULL)
  45820. + bfq_mark_bfqq_prio_changed(bfqq);
  45821. +
  45822. + bic->ioprio = ioprio;
  45823. +
  45824. +out:
  45825. + bfq_put_bfqd_unlock(bfqd, &flags);
  45826. +}
  45827. +
  45828. +static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  45829. + pid_t pid, int is_sync)
  45830. +{
  45831. + RB_CLEAR_NODE(&bfqq->entity.rb_node);
  45832. + INIT_LIST_HEAD(&bfqq->fifo);
  45833. +
  45834. + atomic_set(&bfqq->ref, 0);
  45835. + bfqq->bfqd = bfqd;
  45836. +
  45837. + bfq_mark_bfqq_prio_changed(bfqq);
  45838. +
  45839. + if (is_sync) {
  45840. + if (!bfq_class_idle(bfqq))
  45841. + bfq_mark_bfqq_idle_window(bfqq);
  45842. + bfq_mark_bfqq_sync(bfqq);
  45843. + }
  45844. + bfq_mark_bfqq_IO_bound(bfqq);
  45845. +
  45846. + /* Tentative initial value to trade off between thr and lat */
  45847. + bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3;
  45848. + bfqq->pid = pid;
  45849. +
  45850. + bfqq->wr_coeff = 1;
  45851. + bfqq->last_wr_start_finish = 0;
  45852. + /*
  45853. + * Set to the value for which bfqq will not be deemed as
  45854. + * soft rt when it becomes backlogged.
  45855. + */
  45856. + bfqq->soft_rt_next_start = bfq_infinity_from_now(jiffies);
  45857. +}
  45858. +
  45859. +static struct bfq_queue *bfq_find_alloc_queue(struct bfq_data *bfqd,
  45860. + struct bfq_group *bfqg,
  45861. + int is_sync,
  45862. + struct bfq_io_cq *bic,
  45863. + gfp_t gfp_mask)
  45864. +{
  45865. + struct bfq_queue *bfqq, *new_bfqq = NULL;
  45866. +
  45867. +retry:
  45868. + /* bic always exists here */
  45869. + bfqq = bic_to_bfqq(bic, is_sync);
  45870. +
  45871. + /*
  45872. + * Always try a new alloc if we fall back to the OOM bfqq
  45873. + * originally, since it should just be a temporary situation.
  45874. + */
  45875. + if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) {
  45876. + bfqq = NULL;
  45877. + if (new_bfqq != NULL) {
  45878. + bfqq = new_bfqq;
  45879. + new_bfqq = NULL;
  45880. + } else if (gfp_mask & __GFP_WAIT) {
  45881. + spin_unlock_irq(bfqd->queue->queue_lock);
  45882. + new_bfqq = kmem_cache_alloc_node(bfq_pool,
  45883. + gfp_mask | __GFP_ZERO,
  45884. + bfqd->queue->node);
  45885. + spin_lock_irq(bfqd->queue->queue_lock);
  45886. + if (new_bfqq != NULL)
  45887. + goto retry;
  45888. + } else {
  45889. + bfqq = kmem_cache_alloc_node(bfq_pool,
  45890. + gfp_mask | __GFP_ZERO,
  45891. + bfqd->queue->node);
  45892. + }
  45893. +
  45894. + if (bfqq != NULL) {
  45895. + bfq_init_bfqq(bfqd, bfqq, current->pid, is_sync);
  45896. + bfq_log_bfqq(bfqd, bfqq, "allocated");
  45897. + } else {
  45898. + bfqq = &bfqd->oom_bfqq;
  45899. + bfq_log_bfqq(bfqd, bfqq, "using oom bfqq");
  45900. + }
  45901. +
  45902. + bfq_init_prio_data(bfqq, bic);
  45903. + bfq_init_entity(&bfqq->entity, bfqg);
  45904. + }
  45905. +
  45906. + if (new_bfqq != NULL)
  45907. + kmem_cache_free(bfq_pool, new_bfqq);
  45908. +
  45909. + return bfqq;
  45910. +}
  45911. +
  45912. +static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd,
  45913. + struct bfq_group *bfqg,
  45914. + int ioprio_class, int ioprio)
  45915. +{
  45916. + switch (ioprio_class) {
  45917. + case IOPRIO_CLASS_RT:
  45918. + return &bfqg->async_bfqq[0][ioprio];
  45919. + case IOPRIO_CLASS_NONE:
  45920. + ioprio = IOPRIO_NORM;
  45921. + /* fall through */
  45922. + case IOPRIO_CLASS_BE:
  45923. + return &bfqg->async_bfqq[1][ioprio];
  45924. + case IOPRIO_CLASS_IDLE:
  45925. + return &bfqg->async_idle_bfqq;
  45926. + default:
  45927. + BUG();
  45928. + }
  45929. +}
  45930. +
  45931. +static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
  45932. + struct bfq_group *bfqg, int is_sync,
  45933. + struct bfq_io_cq *bic, gfp_t gfp_mask)
  45934. +{
  45935. + const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
  45936. + const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio);
  45937. + struct bfq_queue **async_bfqq = NULL;
  45938. + struct bfq_queue *bfqq = NULL;
  45939. +
  45940. + if (!is_sync) {
  45941. + async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class,
  45942. + ioprio);
  45943. + bfqq = *async_bfqq;
  45944. + }
  45945. +
  45946. + if (bfqq == NULL)
  45947. + bfqq = bfq_find_alloc_queue(bfqd, bfqg, is_sync, bic, gfp_mask);
  45948. +
  45949. + /*
  45950. + * Pin the queue now that it's allocated, scheduler exit will
  45951. + * prune it.
  45952. + */
  45953. + if (!is_sync && *async_bfqq == NULL) {
  45954. + atomic_inc(&bfqq->ref);
  45955. + bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d",
  45956. + bfqq, atomic_read(&bfqq->ref));
  45957. + *async_bfqq = bfqq;
  45958. + }
  45959. +
  45960. + atomic_inc(&bfqq->ref);
  45961. + bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq,
  45962. + atomic_read(&bfqq->ref));
  45963. + return bfqq;
  45964. +}
  45965. +
  45966. +static void bfq_update_io_thinktime(struct bfq_data *bfqd,
  45967. + struct bfq_io_cq *bic)
  45968. +{
  45969. + unsigned long elapsed = jiffies - bic->ttime.last_end_request;
  45970. + unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle);
  45971. +
  45972. + bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8;
  45973. + bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8;
  45974. + bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) /
  45975. + bic->ttime.ttime_samples;
  45976. +}
  45977. +
  45978. +static void bfq_update_io_seektime(struct bfq_data *bfqd,
  45979. + struct bfq_queue *bfqq,
  45980. + struct request *rq)
  45981. +{
  45982. + sector_t sdist;
  45983. + u64 total;
  45984. +
  45985. + if (bfqq->last_request_pos < blk_rq_pos(rq))
  45986. + sdist = blk_rq_pos(rq) - bfqq->last_request_pos;
  45987. + else
  45988. + sdist = bfqq->last_request_pos - blk_rq_pos(rq);
  45989. +
  45990. + /*
  45991. + * Don't allow the seek distance to get too large from the
  45992. + * odd fragment, pagein, etc.
  45993. + */
  45994. + if (bfqq->seek_samples == 0) /* first request, not really a seek */
  45995. + sdist = 0;
  45996. + else if (bfqq->seek_samples <= 60) /* second & third seek */
  45997. + sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024);
  45998. + else
  45999. + sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64);
  46000. +
  46001. + bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8;
  46002. + bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8;
  46003. + total = bfqq->seek_total + (bfqq->seek_samples/2);
  46004. + do_div(total, bfqq->seek_samples);
  46005. + bfqq->seek_mean = (sector_t)total;
  46006. +
  46007. + bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist,
  46008. + (u64)bfqq->seek_mean);
  46009. +}
  46010. +
  46011. +/*
  46012. + * Disable idle window if the process thinks too long or seeks so much that
  46013. + * it doesn't matter.
  46014. + */
  46015. +static void bfq_update_idle_window(struct bfq_data *bfqd,
  46016. + struct bfq_queue *bfqq,
  46017. + struct bfq_io_cq *bic)
  46018. +{
  46019. + int enable_idle;
  46020. +
  46021. + /* Don't idle for async or idle io prio class. */
  46022. + if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq))
  46023. + return;
  46024. +
  46025. + /* Idle window just restored, statistics are meaningless. */
  46026. + if (bfq_bfqq_just_split(bfqq))
  46027. + return;
  46028. +
  46029. + enable_idle = bfq_bfqq_idle_window(bfqq);
  46030. +
  46031. + if (atomic_read(&bic->icq.ioc->active_ref) == 0 ||
  46032. + bfqd->bfq_slice_idle == 0 ||
  46033. + (bfqd->hw_tag && BFQQ_SEEKY(bfqq) &&
  46034. + bfqq->wr_coeff == 1))
  46035. + enable_idle = 0;
  46036. + else if (bfq_sample_valid(bic->ttime.ttime_samples)) {
  46037. + if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle &&
  46038. + bfqq->wr_coeff == 1)
  46039. + enable_idle = 0;
  46040. + else
  46041. + enable_idle = 1;
  46042. + }
  46043. + bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d",
  46044. + enable_idle);
  46045. +
  46046. + if (enable_idle)
  46047. + bfq_mark_bfqq_idle_window(bfqq);
  46048. + else
  46049. + bfq_clear_bfqq_idle_window(bfqq);
  46050. +}
  46051. +
  46052. +/*
  46053. + * Called when a new fs request (rq) is added to bfqq. Check if there's
  46054. + * something we should do about it.
  46055. + */
  46056. +static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  46057. + struct request *rq)
  46058. +{
  46059. + struct bfq_io_cq *bic = RQ_BIC(rq);
  46060. +
  46061. + if (rq->cmd_flags & REQ_META)
  46062. + bfqq->meta_pending++;
  46063. +
  46064. + bfq_update_io_thinktime(bfqd, bic);
  46065. + bfq_update_io_seektime(bfqd, bfqq, rq);
  46066. + if (!BFQQ_SEEKY(bfqq) && bfq_bfqq_constantly_seeky(bfqq)) {
  46067. + bfq_clear_bfqq_constantly_seeky(bfqq);
  46068. + if (!blk_queue_nonrot(bfqd->queue)) {
  46069. + BUG_ON(!bfqd->const_seeky_busy_in_flight_queues);
  46070. + bfqd->const_seeky_busy_in_flight_queues--;
  46071. + }
  46072. + }
  46073. + if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 ||
  46074. + !BFQQ_SEEKY(bfqq))
  46075. + bfq_update_idle_window(bfqd, bfqq, bic);
  46076. + bfq_clear_bfqq_just_split(bfqq);
  46077. +
  46078. + bfq_log_bfqq(bfqd, bfqq,
  46079. + "rq_enqueued: idle_window=%d (seeky %d, mean %llu)",
  46080. + bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq),
  46081. + (long long unsigned)bfqq->seek_mean);
  46082. +
  46083. + bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
  46084. +
  46085. + if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) {
  46086. + int small_req = bfqq->queued[rq_is_sync(rq)] == 1 &&
  46087. + blk_rq_sectors(rq) < 32;
  46088. + int budget_timeout = bfq_bfqq_budget_timeout(bfqq);
  46089. +
  46090. + /*
  46091. + * There is just this request queued: if the request
  46092. + * is small and the queue is not to be expired, then
  46093. + * just exit.
  46094. + *
  46095. + * In this way, if the disk is being idled to wait for
  46096. + * a new request from the in-service queue, we avoid
  46097. + * unplugging the device and committing the disk to serve
  46098. + * just a small request. On the contrary, we wait for
  46099. + * the block layer to decide when to unplug the device:
  46100. + * hopefully, new requests will be merged to this one
  46101. + * quickly, then the device will be unplugged and
  46102. + * larger requests will be dispatched.
  46103. + */
  46104. + if (small_req && !budget_timeout)
  46105. + return;
  46106. +
  46107. + /*
  46108. + * A large enough request arrived, or the queue is to
  46109. + * be expired: in both cases disk idling is to be
  46110. + * stopped, so clear wait_request flag and reset
  46111. + * timer.
  46112. + */
  46113. + bfq_clear_bfqq_wait_request(bfqq);
  46114. + del_timer(&bfqd->idle_slice_timer);
  46115. +
  46116. + /*
  46117. + * The queue is not empty, because a new request just
  46118. + * arrived. Hence we can safely expire the queue, in
  46119. + * case of budget timeout, without risking that the
  46120. + * timestamps of the queue are not updated correctly.
  46121. + * See [1] for more details.
  46122. + */
  46123. + if (budget_timeout)
  46124. + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT);
  46125. +
  46126. + /*
  46127. + * Let the request rip immediately, or let a new queue be
  46128. + * selected if bfqq has just been expired.
  46129. + */
  46130. + __blk_run_queue(bfqd->queue);
  46131. + }
  46132. +}
  46133. +
  46134. +static void bfq_insert_request(struct request_queue *q, struct request *rq)
  46135. +{
  46136. + struct bfq_data *bfqd = q->elevator->elevator_data;
  46137. + struct bfq_queue *bfqq = RQ_BFQQ(rq), *new_bfqq;
  46138. +
  46139. + assert_spin_locked(bfqd->queue->queue_lock);
  46140. +
  46141. + /*
  46142. + * An unplug may trigger a requeue of a request from the device
  46143. + * driver: make sure we are in process context while trying to
  46144. + * merge two bfq_queues.
  46145. + */
  46146. + if (!in_interrupt()) {
  46147. + new_bfqq = bfq_setup_cooperator(bfqd, bfqq, rq, true);
  46148. + if (new_bfqq != NULL) {
  46149. + if (bic_to_bfqq(RQ_BIC(rq), 1) != bfqq)
  46150. + new_bfqq = bic_to_bfqq(RQ_BIC(rq), 1);
  46151. + /*
  46152. + * Release the request's reference to the old bfqq
  46153. + * and make sure one is taken to the shared queue.
  46154. + */
  46155. + new_bfqq->allocated[rq_data_dir(rq)]++;
  46156. + bfqq->allocated[rq_data_dir(rq)]--;
  46157. + atomic_inc(&new_bfqq->ref);
  46158. + bfq_put_queue(bfqq);
  46159. + if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq)
  46160. + bfq_merge_bfqqs(bfqd, RQ_BIC(rq),
  46161. + bfqq, new_bfqq);
  46162. + rq->elv.priv[1] = new_bfqq;
  46163. + bfqq = new_bfqq;
  46164. + } else
  46165. + bfq_bfqq_increase_failed_cooperations(bfqq);
  46166. + }
  46167. +
  46168. + bfq_init_prio_data(bfqq, RQ_BIC(rq));
  46169. +
  46170. + bfq_add_request(rq);
  46171. +
  46172. + /*
  46173. + * Here a newly-created bfq_queue has already started a weight-raising
  46174. + * period: clear raising_time_left to prevent bfq_bfqq_save_state()
  46175. + * from assigning it a full weight-raising period. See the detailed
  46176. + * comments about this field in bfq_init_icq().
  46177. + */
  46178. + if (bfqq->bic != NULL)
  46179. + bfqq->bic->wr_time_left = 0;
  46180. + rq_set_fifo_time(rq, jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]);
  46181. + list_add_tail(&rq->queuelist, &bfqq->fifo);
  46182. +
  46183. + bfq_rq_enqueued(bfqd, bfqq, rq);
  46184. +}
  46185. +
  46186. +static void bfq_update_hw_tag(struct bfq_data *bfqd)
  46187. +{
  46188. + bfqd->max_rq_in_driver = max(bfqd->max_rq_in_driver,
  46189. + bfqd->rq_in_driver);
  46190. +
  46191. + if (bfqd->hw_tag == 1)
  46192. + return;
  46193. +
  46194. + /*
  46195. + * This sample is valid if the number of outstanding requests
  46196. + * is large enough to allow a queueing behavior. Note that the
  46197. + * sum is not exact, as it's not taking into account deactivated
  46198. + * requests.
  46199. + */
  46200. + if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD)
  46201. + return;
  46202. +
  46203. + if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES)
  46204. + return;
  46205. +
  46206. + bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD;
  46207. + bfqd->max_rq_in_driver = 0;
  46208. + bfqd->hw_tag_samples = 0;
  46209. +}
  46210. +
  46211. +static void bfq_completed_request(struct request_queue *q, struct request *rq)
  46212. +{
  46213. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  46214. + struct bfq_data *bfqd = bfqq->bfqd;
  46215. + bool sync = bfq_bfqq_sync(bfqq);
  46216. +
  46217. + bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)",
  46218. + blk_rq_sectors(rq), sync);
  46219. +
  46220. + bfq_update_hw_tag(bfqd);
  46221. +
  46222. + BUG_ON(!bfqd->rq_in_driver);
  46223. + BUG_ON(!bfqq->dispatched);
  46224. + bfqd->rq_in_driver--;
  46225. + bfqq->dispatched--;
  46226. +
  46227. + if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) {
  46228. + bfq_weights_tree_remove(bfqd, &bfqq->entity,
  46229. + &bfqd->queue_weights_tree);
  46230. + if (!blk_queue_nonrot(bfqd->queue)) {
  46231. + BUG_ON(!bfqd->busy_in_flight_queues);
  46232. + bfqd->busy_in_flight_queues--;
  46233. + if (bfq_bfqq_constantly_seeky(bfqq)) {
  46234. + BUG_ON(!bfqd->
  46235. + const_seeky_busy_in_flight_queues);
  46236. + bfqd->const_seeky_busy_in_flight_queues--;
  46237. + }
  46238. + }
  46239. + }
  46240. +
  46241. + if (sync) {
  46242. + bfqd->sync_flight--;
  46243. + RQ_BIC(rq)->ttime.last_end_request = jiffies;
  46244. + }
  46245. +
  46246. + /*
  46247. + * If we are waiting to discover whether the request pattern of the
  46248. + * task associated with the queue is actually isochronous, and
  46249. + * both requisites for this condition to hold are satisfied, then
  46250. + * compute soft_rt_next_start (see the comments to the function
  46251. + * bfq_bfqq_softrt_next_start()).
  46252. + */
  46253. + if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 &&
  46254. + RB_EMPTY_ROOT(&bfqq->sort_list))
  46255. + bfqq->soft_rt_next_start =
  46256. + bfq_bfqq_softrt_next_start(bfqd, bfqq);
  46257. +
  46258. + /*
  46259. + * If this is the in-service queue, check if it needs to be expired,
  46260. + * or if we want to idle in case it has no pending requests.
  46261. + */
  46262. + if (bfqd->in_service_queue == bfqq) {
  46263. + if (bfq_bfqq_budget_new(bfqq))
  46264. + bfq_set_budget_timeout(bfqd);
  46265. +
  46266. + if (bfq_bfqq_must_idle(bfqq)) {
  46267. + bfq_arm_slice_timer(bfqd);
  46268. + goto out;
  46269. + } else if (bfq_may_expire_for_budg_timeout(bfqq))
  46270. + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT);
  46271. + else if (RB_EMPTY_ROOT(&bfqq->sort_list) &&
  46272. + (bfqq->dispatched == 0 ||
  46273. + !bfq_bfqq_must_not_expire(bfqq)))
  46274. + bfq_bfqq_expire(bfqd, bfqq, 0,
  46275. + BFQ_BFQQ_NO_MORE_REQUESTS);
  46276. + }
  46277. +
  46278. + if (!bfqd->rq_in_driver)
  46279. + bfq_schedule_dispatch(bfqd);
  46280. +
  46281. +out:
  46282. + return;
  46283. +}
  46284. +
  46285. +static inline int __bfq_may_queue(struct bfq_queue *bfqq)
  46286. +{
  46287. + if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) {
  46288. + bfq_clear_bfqq_must_alloc(bfqq);
  46289. + return ELV_MQUEUE_MUST;
  46290. + }
  46291. +
  46292. + return ELV_MQUEUE_MAY;
  46293. +}
  46294. +
  46295. +static int bfq_may_queue(struct request_queue *q, int rw)
  46296. +{
  46297. + struct bfq_data *bfqd = q->elevator->elevator_data;
  46298. + struct task_struct *tsk = current;
  46299. + struct bfq_io_cq *bic;
  46300. + struct bfq_queue *bfqq;
  46301. +
  46302. + /*
  46303. + * Don't force setup of a queue from here, as a call to may_queue
  46304. + * does not necessarily imply that a request actually will be
  46305. + * queued. So just lookup a possibly existing queue, or return
  46306. + * 'may queue' if that fails.
  46307. + */
  46308. + bic = bfq_bic_lookup(bfqd, tsk->io_context);
  46309. + if (bic == NULL)
  46310. + return ELV_MQUEUE_MAY;
  46311. +
  46312. + bfqq = bic_to_bfqq(bic, rw_is_sync(rw));
  46313. + if (bfqq != NULL) {
  46314. + bfq_init_prio_data(bfqq, bic);
  46315. +
  46316. + return __bfq_may_queue(bfqq);
  46317. + }
  46318. +
  46319. + return ELV_MQUEUE_MAY;
  46320. +}
  46321. +
  46322. +/*
  46323. + * Queue lock held here.
  46324. + */
  46325. +static void bfq_put_request(struct request *rq)
  46326. +{
  46327. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  46328. +
  46329. + if (bfqq != NULL) {
  46330. + const int rw = rq_data_dir(rq);
  46331. +
  46332. + BUG_ON(!bfqq->allocated[rw]);
  46333. + bfqq->allocated[rw]--;
  46334. +
  46335. + rq->elv.priv[0] = NULL;
  46336. + rq->elv.priv[1] = NULL;
  46337. +
  46338. + bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d",
  46339. + bfqq, atomic_read(&bfqq->ref));
  46340. + bfq_put_queue(bfqq);
  46341. + }
  46342. +}
  46343. +
  46344. +/*
  46345. + * Returns NULL if a new bfqq should be allocated, or the old bfqq if this
  46346. + * was the last process referring to said bfqq.
  46347. + */
  46348. +static struct bfq_queue *
  46349. +bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
  46350. +{
  46351. + bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
  46352. +
  46353. + put_io_context(bic->icq.ioc);
  46354. +
  46355. + if (bfqq_process_refs(bfqq) == 1) {
  46356. + bfqq->pid = current->pid;
  46357. + bfq_clear_bfqq_coop(bfqq);
  46358. + bfq_clear_bfqq_split_coop(bfqq);
  46359. + return bfqq;
  46360. + }
  46361. +
  46362. + bic_set_bfqq(bic, NULL, 1);
  46363. +
  46364. + bfq_put_cooperator(bfqq);
  46365. +
  46366. + bfq_put_queue(bfqq);
  46367. + return NULL;
  46368. +}
  46369. +
  46370. +/*
  46371. + * Allocate bfq data structures associated with this request.
  46372. + */
  46373. +static int bfq_set_request(struct request_queue *q, struct request *rq,
  46374. + struct bio *bio, gfp_t gfp_mask)
  46375. +{
  46376. + struct bfq_data *bfqd = q->elevator->elevator_data;
  46377. + struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq);
  46378. + const int rw = rq_data_dir(rq);
  46379. + const int is_sync = rq_is_sync(rq);
  46380. + struct bfq_queue *bfqq;
  46381. + struct bfq_group *bfqg;
  46382. + unsigned long flags;
  46383. + bool split = false;
  46384. +
  46385. + might_sleep_if(gfp_mask & __GFP_WAIT);
  46386. +
  46387. + bfq_changed_ioprio(bic);
  46388. +
  46389. + spin_lock_irqsave(q->queue_lock, flags);
  46390. +
  46391. + if (bic == NULL)
  46392. + goto queue_fail;
  46393. +
  46394. + bfqg = bfq_bic_update_cgroup(bic);
  46395. +
  46396. +new_queue:
  46397. + bfqq = bic_to_bfqq(bic, is_sync);
  46398. + if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) {
  46399. + bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic, gfp_mask);
  46400. + bic_set_bfqq(bic, bfqq, is_sync);
  46401. + } else {
  46402. + /* If the queue was seeky for too long, break it apart. */
  46403. + if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) {
  46404. + bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq");
  46405. + bfqq = bfq_split_bfqq(bic, bfqq);
  46406. + split = true;
  46407. + if (!bfqq)
  46408. + goto new_queue;
  46409. + }
  46410. + }
  46411. +
  46412. + bfqq->allocated[rw]++;
  46413. + atomic_inc(&bfqq->ref);
  46414. + bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq,
  46415. + atomic_read(&bfqq->ref));
  46416. +
  46417. + rq->elv.priv[0] = bic;
  46418. + rq->elv.priv[1] = bfqq;
  46419. +
  46420. + /*
  46421. + * If a bfq_queue has only one process reference, it is owned
  46422. + * by only one bfq_io_cq: we can set the bic field of the
  46423. + * bfq_queue to the address of that structure. Also, if the
  46424. + * queue has just been split, mark a flag so that the
  46425. + * information is available to the other scheduler hooks.
  46426. + */
  46427. + if (bfqq_process_refs(bfqq) == 1) {
  46428. + bfqq->bic = bic;
  46429. + if (split) {
  46430. + bfq_mark_bfqq_just_split(bfqq);
  46431. + /*
  46432. + * If the queue has just been split from a shared
  46433. + * queue, restore the idle window and the possible
  46434. + * weight raising period.
  46435. + */
  46436. + bfq_bfqq_resume_state(bfqq, bic);
  46437. + }
  46438. + }
  46439. +
  46440. + spin_unlock_irqrestore(q->queue_lock, flags);
  46441. +
  46442. + return 0;
  46443. +
  46444. +queue_fail:
  46445. + bfq_schedule_dispatch(bfqd);
  46446. + spin_unlock_irqrestore(q->queue_lock, flags);
  46447. +
  46448. + return 1;
  46449. +}
  46450. +
  46451. +static void bfq_kick_queue(struct work_struct *work)
  46452. +{
  46453. + struct bfq_data *bfqd =
  46454. + container_of(work, struct bfq_data, unplug_work);
  46455. + struct request_queue *q = bfqd->queue;
  46456. +
  46457. + spin_lock_irq(q->queue_lock);
  46458. + __blk_run_queue(q);
  46459. + spin_unlock_irq(q->queue_lock);
  46460. +}
  46461. +
  46462. +/*
  46463. + * Handler of the expiration of the timer running if the in-service queue
  46464. + * is idling inside its time slice.
  46465. + */
  46466. +static void bfq_idle_slice_timer(unsigned long data)
  46467. +{
  46468. + struct bfq_data *bfqd = (struct bfq_data *)data;
  46469. + struct bfq_queue *bfqq;
  46470. + unsigned long flags;
  46471. + enum bfqq_expiration reason;
  46472. +
  46473. + spin_lock_irqsave(bfqd->queue->queue_lock, flags);
  46474. +
  46475. + bfqq = bfqd->in_service_queue;
  46476. + /*
  46477. + * Theoretical race here: the in-service queue can be NULL or
  46478. + * different from the queue that was idling if the timer handler
  46479. + * spins on the queue_lock and a new request arrives for the
  46480. + * current queue and there is a full dispatch cycle that changes
  46481. + * the in-service queue. This can hardly happen, but in the worst
  46482. + * case we just expire a queue too early.
  46483. + */
  46484. + if (bfqq != NULL) {
  46485. + bfq_log_bfqq(bfqd, bfqq, "slice_timer expired");
  46486. + if (bfq_bfqq_budget_timeout(bfqq))
  46487. + /*
  46488. + * Also here the queue can be safely expired
  46489. + * for budget timeout without wasting
  46490. + * guarantees
  46491. + */
  46492. + reason = BFQ_BFQQ_BUDGET_TIMEOUT;
  46493. + else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0)
  46494. + /*
  46495. + * The queue may not be empty upon timer expiration,
  46496. + * because we may not disable the timer when the
  46497. + * first request of the in-service queue arrives
  46498. + * during disk idling.
  46499. + */
  46500. + reason = BFQ_BFQQ_TOO_IDLE;
  46501. + else
  46502. + goto schedule_dispatch;
  46503. +
  46504. + bfq_bfqq_expire(bfqd, bfqq, 1, reason);
  46505. + }
  46506. +
  46507. +schedule_dispatch:
  46508. + bfq_schedule_dispatch(bfqd);
  46509. +
  46510. + spin_unlock_irqrestore(bfqd->queue->queue_lock, flags);
  46511. +}
  46512. +
  46513. +static void bfq_shutdown_timer_wq(struct bfq_data *bfqd)
  46514. +{
  46515. + del_timer_sync(&bfqd->idle_slice_timer);
  46516. + cancel_work_sync(&bfqd->unplug_work);
  46517. +}
  46518. +
  46519. +static inline void __bfq_put_async_bfqq(struct bfq_data *bfqd,
  46520. + struct bfq_queue **bfqq_ptr)
  46521. +{
  46522. + struct bfq_group *root_group = bfqd->root_group;
  46523. + struct bfq_queue *bfqq = *bfqq_ptr;
  46524. +
  46525. + bfq_log(bfqd, "put_async_bfqq: %p", bfqq);
  46526. + if (bfqq != NULL) {
  46527. + bfq_bfqq_move(bfqd, bfqq, &bfqq->entity, root_group);
  46528. + bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d",
  46529. + bfqq, atomic_read(&bfqq->ref));
  46530. + bfq_put_queue(bfqq);
  46531. + *bfqq_ptr = NULL;
  46532. + }
  46533. +}
  46534. +
  46535. +/*
  46536. + * Release all the bfqg references to its async queues. If we are
  46537. + * deallocating the group these queues may still contain requests, so
  46538. + * we reparent them to the root cgroup (i.e., the only one that will
  46539. + * exist for sure until all the requests on a device are gone).
  46540. + */
  46541. +static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg)
  46542. +{
  46543. + int i, j;
  46544. +
  46545. + for (i = 0; i < 2; i++)
  46546. + for (j = 0; j < IOPRIO_BE_NR; j++)
  46547. + __bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]);
  46548. +
  46549. + __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq);
  46550. +}
  46551. +
  46552. +static void bfq_exit_queue(struct elevator_queue *e)
  46553. +{
  46554. + struct bfq_data *bfqd = e->elevator_data;
  46555. + struct request_queue *q = bfqd->queue;
  46556. + struct bfq_queue *bfqq, *n;
  46557. +
  46558. + bfq_shutdown_timer_wq(bfqd);
  46559. +
  46560. + spin_lock_irq(q->queue_lock);
  46561. +
  46562. + BUG_ON(bfqd->in_service_queue != NULL);
  46563. + list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list)
  46564. + bfq_deactivate_bfqq(bfqd, bfqq, 0);
  46565. +
  46566. + bfq_disconnect_groups(bfqd);
  46567. + spin_unlock_irq(q->queue_lock);
  46568. +
  46569. + bfq_shutdown_timer_wq(bfqd);
  46570. +
  46571. + synchronize_rcu();
  46572. +
  46573. + BUG_ON(timer_pending(&bfqd->idle_slice_timer));
  46574. +
  46575. + bfq_free_root_group(bfqd);
  46576. + kfree(bfqd);
  46577. +}
  46578. +
  46579. +static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
  46580. +{
  46581. + struct bfq_group *bfqg;
  46582. + struct bfq_data *bfqd;
  46583. + struct elevator_queue *eq;
  46584. +
  46585. + eq = elevator_alloc(q, e);
  46586. + if (eq == NULL)
  46587. + return -ENOMEM;
  46588. +
  46589. + bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node);
  46590. + if (bfqd == NULL) {
  46591. + kobject_put(&eq->kobj);
  46592. + return -ENOMEM;
  46593. + }
  46594. + eq->elevator_data = bfqd;
  46595. +
  46596. + /*
  46597. + * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues.
  46598. + * Grab a permanent reference to it, so that the normal code flow
  46599. + * will not attempt to free it.
  46600. + */
  46601. + bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, 1, 0);
  46602. + atomic_inc(&bfqd->oom_bfqq.ref);
  46603. +
  46604. + bfqd->queue = q;
  46605. +
  46606. + spin_lock_irq(q->queue_lock);
  46607. + q->elevator = eq;
  46608. + spin_unlock_irq(q->queue_lock);
  46609. +
  46610. + bfqg = bfq_alloc_root_group(bfqd, q->node);
  46611. + if (bfqg == NULL) {
  46612. + kfree(bfqd);
  46613. + kobject_put(&eq->kobj);
  46614. + return -ENOMEM;
  46615. + }
  46616. +
  46617. + bfqd->root_group = bfqg;
  46618. +#ifdef CONFIG_CGROUP_BFQIO
  46619. + bfqd->active_numerous_groups = 0;
  46620. +#endif
  46621. +
  46622. + init_timer(&bfqd->idle_slice_timer);
  46623. + bfqd->idle_slice_timer.function = bfq_idle_slice_timer;
  46624. + bfqd->idle_slice_timer.data = (unsigned long)bfqd;
  46625. +
  46626. + bfqd->rq_pos_tree = RB_ROOT;
  46627. + bfqd->queue_weights_tree = RB_ROOT;
  46628. + bfqd->group_weights_tree = RB_ROOT;
  46629. +
  46630. + INIT_WORK(&bfqd->unplug_work, bfq_kick_queue);
  46631. +
  46632. + INIT_LIST_HEAD(&bfqd->active_list);
  46633. + INIT_LIST_HEAD(&bfqd->idle_list);
  46634. +
  46635. + bfqd->hw_tag = -1;
  46636. +
  46637. + bfqd->bfq_max_budget = bfq_default_max_budget;
  46638. +
  46639. + bfqd->bfq_quantum = bfq_quantum;
  46640. + bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0];
  46641. + bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1];
  46642. + bfqd->bfq_back_max = bfq_back_max;
  46643. + bfqd->bfq_back_penalty = bfq_back_penalty;
  46644. + bfqd->bfq_slice_idle = bfq_slice_idle;
  46645. + bfqd->bfq_class_idle_last_service = 0;
  46646. + bfqd->bfq_max_budget_async_rq = bfq_max_budget_async_rq;
  46647. + bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async;
  46648. + bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync;
  46649. +
  46650. + bfqd->bfq_coop_thresh = 2;
  46651. + bfqd->bfq_failed_cooperations = 7000;
  46652. + bfqd->bfq_requests_within_timer = 120;
  46653. +
  46654. + bfqd->low_latency = true;
  46655. +
  46656. + bfqd->bfq_wr_coeff = 20;
  46657. + bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300);
  46658. + bfqd->bfq_wr_max_time = 0;
  46659. + bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000);
  46660. + bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500);
  46661. + bfqd->bfq_wr_max_softrt_rate = 7000; /*
  46662. + * Approximate rate required
  46663. + * to playback or record a
  46664. + * high-definition compressed
  46665. + * video.
  46666. + */
  46667. + bfqd->wr_busy_queues = 0;
  46668. + bfqd->busy_in_flight_queues = 0;
  46669. + bfqd->const_seeky_busy_in_flight_queues = 0;
  46670. +
  46671. + /*
  46672. + * Begin by assuming, optimistically, that the device peak rate is
  46673. + * equal to the highest reference rate.
  46674. + */
  46675. + bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] *
  46676. + T_fast[blk_queue_nonrot(bfqd->queue)];
  46677. + bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)];
  46678. + bfqd->device_speed = BFQ_BFQD_FAST;
  46679. +
  46680. + return 0;
  46681. +}
  46682. +
  46683. +static void bfq_slab_kill(void)
  46684. +{
  46685. + if (bfq_pool != NULL)
  46686. + kmem_cache_destroy(bfq_pool);
  46687. +}
  46688. +
  46689. +static int __init bfq_slab_setup(void)
  46690. +{
  46691. + bfq_pool = KMEM_CACHE(bfq_queue, 0);
  46692. + if (bfq_pool == NULL)
  46693. + return -ENOMEM;
  46694. + return 0;
  46695. +}
  46696. +
  46697. +static ssize_t bfq_var_show(unsigned int var, char *page)
  46698. +{
  46699. + return sprintf(page, "%d\n", var);
  46700. +}
  46701. +
  46702. +static ssize_t bfq_var_store(unsigned long *var, const char *page,
  46703. + size_t count)
  46704. +{
  46705. + unsigned long new_val;
  46706. + int ret = kstrtoul(page, 10, &new_val);
  46707. +
  46708. + if (ret == 0)
  46709. + *var = new_val;
  46710. +
  46711. + return count;
  46712. +}
  46713. +
  46714. +static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page)
  46715. +{
  46716. + struct bfq_data *bfqd = e->elevator_data;
  46717. + return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ?
  46718. + jiffies_to_msecs(bfqd->bfq_wr_max_time) :
  46719. + jiffies_to_msecs(bfq_wr_duration(bfqd)));
  46720. +}
  46721. +
  46722. +static ssize_t bfq_weights_show(struct elevator_queue *e, char *page)
  46723. +{
  46724. + struct bfq_queue *bfqq;
  46725. + struct bfq_data *bfqd = e->elevator_data;
  46726. + ssize_t num_char = 0;
  46727. +
  46728. + num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n",
  46729. + bfqd->queued);
  46730. +
  46731. + spin_lock_irq(bfqd->queue->queue_lock);
  46732. +
  46733. + num_char += sprintf(page + num_char, "Active:\n");
  46734. + list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) {
  46735. + num_char += sprintf(page + num_char,
  46736. + "pid%d: weight %hu, nr_queued %d %d, dur %d/%u\n",
  46737. + bfqq->pid,
  46738. + bfqq->entity.weight,
  46739. + bfqq->queued[0],
  46740. + bfqq->queued[1],
  46741. + jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish),
  46742. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  46743. + }
  46744. +
  46745. + num_char += sprintf(page + num_char, "Idle:\n");
  46746. + list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) {
  46747. + num_char += sprintf(page + num_char,
  46748. + "pid%d: weight %hu, dur %d/%u\n",
  46749. + bfqq->pid,
  46750. + bfqq->entity.weight,
  46751. + jiffies_to_msecs(jiffies -
  46752. + bfqq->last_wr_start_finish),
  46753. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  46754. + }
  46755. +
  46756. + spin_unlock_irq(bfqd->queue->queue_lock);
  46757. +
  46758. + return num_char;
  46759. +}
  46760. +
  46761. +#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
  46762. +static ssize_t __FUNC(struct elevator_queue *e, char *page) \
  46763. +{ \
  46764. + struct bfq_data *bfqd = e->elevator_data; \
  46765. + unsigned int __data = __VAR; \
  46766. + if (__CONV) \
  46767. + __data = jiffies_to_msecs(__data); \
  46768. + return bfq_var_show(__data, (page)); \
  46769. +}
  46770. +SHOW_FUNCTION(bfq_quantum_show, bfqd->bfq_quantum, 0);
  46771. +SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 1);
  46772. +SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1);
  46773. +SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0);
  46774. +SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0);
  46775. +SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1);
  46776. +SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0);
  46777. +SHOW_FUNCTION(bfq_max_budget_async_rq_show,
  46778. + bfqd->bfq_max_budget_async_rq, 0);
  46779. +SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout[BLK_RW_SYNC], 1);
  46780. +SHOW_FUNCTION(bfq_timeout_async_show, bfqd->bfq_timeout[BLK_RW_ASYNC], 1);
  46781. +SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0);
  46782. +SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0);
  46783. +SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1);
  46784. +SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1);
  46785. +SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async,
  46786. + 1);
  46787. +SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0);
  46788. +#undef SHOW_FUNCTION
  46789. +
  46790. +#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \
  46791. +static ssize_t \
  46792. +__FUNC(struct elevator_queue *e, const char *page, size_t count) \
  46793. +{ \
  46794. + struct bfq_data *bfqd = e->elevator_data; \
  46795. + unsigned long uninitialized_var(__data); \
  46796. + int ret = bfq_var_store(&__data, (page), count); \
  46797. + if (__data < (MIN)) \
  46798. + __data = (MIN); \
  46799. + else if (__data > (MAX)) \
  46800. + __data = (MAX); \
  46801. + if (__CONV) \
  46802. + *(__PTR) = msecs_to_jiffies(__data); \
  46803. + else \
  46804. + *(__PTR) = __data; \
  46805. + return ret; \
  46806. +}
  46807. +STORE_FUNCTION(bfq_quantum_store, &bfqd->bfq_quantum, 1, INT_MAX, 0);
  46808. +STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1,
  46809. + INT_MAX, 1);
  46810. +STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1,
  46811. + INT_MAX, 1);
  46812. +STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0);
  46813. +STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1,
  46814. + INT_MAX, 0);
  46815. +STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1);
  46816. +STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq,
  46817. + 1, INT_MAX, 0);
  46818. +STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0,
  46819. + INT_MAX, 1);
  46820. +STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0);
  46821. +STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1);
  46822. +STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX,
  46823. + 1);
  46824. +STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0,
  46825. + INT_MAX, 1);
  46826. +STORE_FUNCTION(bfq_wr_min_inter_arr_async_store,
  46827. + &bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1);
  46828. +STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0,
  46829. + INT_MAX, 0);
  46830. +#undef STORE_FUNCTION
  46831. +
  46832. +/* do nothing for the moment */
  46833. +static ssize_t bfq_weights_store(struct elevator_queue *e,
  46834. + const char *page, size_t count)
  46835. +{
  46836. + return count;
  46837. +}
  46838. +
  46839. +static inline unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd)
  46840. +{
  46841. + u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]);
  46842. +
  46843. + if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES)
  46844. + return bfq_calc_max_budget(bfqd->peak_rate, timeout);
  46845. + else
  46846. + return bfq_default_max_budget;
  46847. +}
  46848. +
  46849. +static ssize_t bfq_max_budget_store(struct elevator_queue *e,
  46850. + const char *page, size_t count)
  46851. +{
  46852. + struct bfq_data *bfqd = e->elevator_data;
  46853. + unsigned long uninitialized_var(__data);
  46854. + int ret = bfq_var_store(&__data, (page), count);
  46855. +
  46856. + if (__data == 0)
  46857. + bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd);
  46858. + else {
  46859. + if (__data > INT_MAX)
  46860. + __data = INT_MAX;
  46861. + bfqd->bfq_max_budget = __data;
  46862. + }
  46863. +
  46864. + bfqd->bfq_user_max_budget = __data;
  46865. +
  46866. + return ret;
  46867. +}
  46868. +
  46869. +static ssize_t bfq_timeout_sync_store(struct elevator_queue *e,
  46870. + const char *page, size_t count)
  46871. +{
  46872. + struct bfq_data *bfqd = e->elevator_data;
  46873. + unsigned long uninitialized_var(__data);
  46874. + int ret = bfq_var_store(&__data, (page), count);
  46875. +
  46876. + if (__data < 1)
  46877. + __data = 1;
  46878. + else if (__data > INT_MAX)
  46879. + __data = INT_MAX;
  46880. +
  46881. + bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data);
  46882. + if (bfqd->bfq_user_max_budget == 0)
  46883. + bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd);
  46884. +
  46885. + return ret;
  46886. +}
  46887. +
  46888. +static ssize_t bfq_low_latency_store(struct elevator_queue *e,
  46889. + const char *page, size_t count)
  46890. +{
  46891. + struct bfq_data *bfqd = e->elevator_data;
  46892. + unsigned long uninitialized_var(__data);
  46893. + int ret = bfq_var_store(&__data, (page), count);
  46894. +
  46895. + if (__data > 1)
  46896. + __data = 1;
  46897. + if (__data == 0 && bfqd->low_latency != 0)
  46898. + bfq_end_wr(bfqd);
  46899. + bfqd->low_latency = __data;
  46900. +
  46901. + return ret;
  46902. +}
  46903. +
  46904. +#define BFQ_ATTR(name) \
  46905. + __ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store)
  46906. +
  46907. +static struct elv_fs_entry bfq_attrs[] = {
  46908. + BFQ_ATTR(quantum),
  46909. + BFQ_ATTR(fifo_expire_sync),
  46910. + BFQ_ATTR(fifo_expire_async),
  46911. + BFQ_ATTR(back_seek_max),
  46912. + BFQ_ATTR(back_seek_penalty),
  46913. + BFQ_ATTR(slice_idle),
  46914. + BFQ_ATTR(max_budget),
  46915. + BFQ_ATTR(max_budget_async_rq),
  46916. + BFQ_ATTR(timeout_sync),
  46917. + BFQ_ATTR(timeout_async),
  46918. + BFQ_ATTR(low_latency),
  46919. + BFQ_ATTR(wr_coeff),
  46920. + BFQ_ATTR(wr_max_time),
  46921. + BFQ_ATTR(wr_rt_max_time),
  46922. + BFQ_ATTR(wr_min_idle_time),
  46923. + BFQ_ATTR(wr_min_inter_arr_async),
  46924. + BFQ_ATTR(wr_max_softrt_rate),
  46925. + BFQ_ATTR(weights),
  46926. + __ATTR_NULL
  46927. +};
  46928. +
  46929. +static struct elevator_type iosched_bfq = {
  46930. + .ops = {
  46931. + .elevator_merge_fn = bfq_merge,
  46932. + .elevator_merged_fn = bfq_merged_request,
  46933. + .elevator_merge_req_fn = bfq_merged_requests,
  46934. + .elevator_allow_merge_fn = bfq_allow_merge,
  46935. + .elevator_dispatch_fn = bfq_dispatch_requests,
  46936. + .elevator_add_req_fn = bfq_insert_request,
  46937. + .elevator_activate_req_fn = bfq_activate_request,
  46938. + .elevator_deactivate_req_fn = bfq_deactivate_request,
  46939. + .elevator_completed_req_fn = bfq_completed_request,
  46940. + .elevator_former_req_fn = elv_rb_former_request,
  46941. + .elevator_latter_req_fn = elv_rb_latter_request,
  46942. + .elevator_init_icq_fn = bfq_init_icq,
  46943. + .elevator_exit_icq_fn = bfq_exit_icq,
  46944. + .elevator_set_req_fn = bfq_set_request,
  46945. + .elevator_put_req_fn = bfq_put_request,
  46946. + .elevator_may_queue_fn = bfq_may_queue,
  46947. + .elevator_init_fn = bfq_init_queue,
  46948. + .elevator_exit_fn = bfq_exit_queue,
  46949. + },
  46950. + .icq_size = sizeof(struct bfq_io_cq),
  46951. + .icq_align = __alignof__(struct bfq_io_cq),
  46952. + .elevator_attrs = bfq_attrs,
  46953. + .elevator_name = "bfq",
  46954. + .elevator_owner = THIS_MODULE,
  46955. +};
  46956. +
  46957. +static int __init bfq_init(void)
  46958. +{
  46959. + /*
  46960. + * Can be 0 on HZ < 1000 setups.
  46961. + */
  46962. + if (bfq_slice_idle == 0)
  46963. + bfq_slice_idle = 1;
  46964. +
  46965. + if (bfq_timeout_async == 0)
  46966. + bfq_timeout_async = 1;
  46967. +
  46968. + if (bfq_slab_setup())
  46969. + return -ENOMEM;
  46970. +
  46971. + /*
  46972. + * Times to load large popular applications for the typical systems
  46973. + * installed on the reference devices (see the comments before the
  46974. + * definitions of the two arrays).
  46975. + */
  46976. + T_slow[0] = msecs_to_jiffies(2600);
  46977. + T_slow[1] = msecs_to_jiffies(1000);
  46978. + T_fast[0] = msecs_to_jiffies(5500);
  46979. + T_fast[1] = msecs_to_jiffies(2000);
  46980. +
  46981. + /*
  46982. + * Thresholds that determine the switch between speed classes (see
  46983. + * the comments before the definition of the array).
  46984. + */
  46985. + device_speed_thresh[0] = (R_fast[0] + R_slow[0]) / 2;
  46986. + device_speed_thresh[1] = (R_fast[1] + R_slow[1]) / 2;
  46987. +
  46988. + elv_register(&iosched_bfq);
  46989. + pr_info("BFQ I/O-scheduler version: v7r5");
  46990. +
  46991. + return 0;
  46992. +}
  46993. +
  46994. +static void __exit bfq_exit(void)
  46995. +{
  46996. + elv_unregister(&iosched_bfq);
  46997. + bfq_slab_kill();
  46998. +}
  46999. +
  47000. +module_init(bfq_init);
  47001. +module_exit(bfq_exit);
  47002. +
  47003. +MODULE_AUTHOR("Fabio Checconi, Paolo Valente");
  47004. +MODULE_LICENSE("GPL");
  47005. diff -Nur linux-3.14.14/block/bfq-sched.c linux-imx6-3.14/block/bfq-sched.c
  47006. --- linux-3.14.14/block/bfq-sched.c 1969-12-31 18:00:00.000000000 -0600
  47007. +++ linux-imx6-3.14/block/bfq-sched.c 2014-12-08 00:31:52.364418001 -0600
  47008. @@ -0,0 +1,1179 @@
  47009. +/*
  47010. + * BFQ: Hierarchical B-WF2Q+ scheduler.
  47011. + *
  47012. + * Based on ideas and code from CFQ:
  47013. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  47014. + *
  47015. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  47016. + * Paolo Valente <paolo.valente@unimore.it>
  47017. + *
  47018. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  47019. + */
  47020. +
  47021. +#ifdef CONFIG_CGROUP_BFQIO
  47022. +#define for_each_entity(entity) \
  47023. + for (; entity != NULL; entity = entity->parent)
  47024. +
  47025. +#define for_each_entity_safe(entity, parent) \
  47026. + for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
  47027. +
  47028. +static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
  47029. + int extract,
  47030. + struct bfq_data *bfqd);
  47031. +
  47032. +static inline void bfq_update_budget(struct bfq_entity *next_in_service)
  47033. +{
  47034. + struct bfq_entity *bfqg_entity;
  47035. + struct bfq_group *bfqg;
  47036. + struct bfq_sched_data *group_sd;
  47037. +
  47038. + BUG_ON(next_in_service == NULL);
  47039. +
  47040. + group_sd = next_in_service->sched_data;
  47041. +
  47042. + bfqg = container_of(group_sd, struct bfq_group, sched_data);
  47043. + /*
  47044. + * bfq_group's my_entity field is not NULL only if the group
  47045. + * is not the root group. We must not touch the root entity
  47046. + * as it must never become an in-service entity.
  47047. + */
  47048. + bfqg_entity = bfqg->my_entity;
  47049. + if (bfqg_entity != NULL)
  47050. + bfqg_entity->budget = next_in_service->budget;
  47051. +}
  47052. +
  47053. +static int bfq_update_next_in_service(struct bfq_sched_data *sd)
  47054. +{
  47055. + struct bfq_entity *next_in_service;
  47056. +
  47057. + if (sd->in_service_entity != NULL)
  47058. + /* will update/requeue at the end of service */
  47059. + return 0;
  47060. +
  47061. + /*
  47062. + * NOTE: this can be improved in many ways, such as returning
  47063. + * 1 (and thus propagating upwards the update) only when the
  47064. + * budget changes, or caching the bfqq that will be scheduled
  47065. + * next from this subtree. By now we worry more about
  47066. + * correctness than about performance...
  47067. + */
  47068. + next_in_service = bfq_lookup_next_entity(sd, 0, NULL);
  47069. + sd->next_in_service = next_in_service;
  47070. +
  47071. + if (next_in_service != NULL)
  47072. + bfq_update_budget(next_in_service);
  47073. +
  47074. + return 1;
  47075. +}
  47076. +
  47077. +static inline void bfq_check_next_in_service(struct bfq_sched_data *sd,
  47078. + struct bfq_entity *entity)
  47079. +{
  47080. + BUG_ON(sd->next_in_service != entity);
  47081. +}
  47082. +#else
  47083. +#define for_each_entity(entity) \
  47084. + for (; entity != NULL; entity = NULL)
  47085. +
  47086. +#define for_each_entity_safe(entity, parent) \
  47087. + for (parent = NULL; entity != NULL; entity = parent)
  47088. +
  47089. +static inline int bfq_update_next_in_service(struct bfq_sched_data *sd)
  47090. +{
  47091. + return 0;
  47092. +}
  47093. +
  47094. +static inline void bfq_check_next_in_service(struct bfq_sched_data *sd,
  47095. + struct bfq_entity *entity)
  47096. +{
  47097. +}
  47098. +
  47099. +static inline void bfq_update_budget(struct bfq_entity *next_in_service)
  47100. +{
  47101. +}
  47102. +#endif
  47103. +
  47104. +/*
  47105. + * Shift for timestamp calculations. This actually limits the maximum
  47106. + * service allowed in one timestamp delta (small shift values increase it),
  47107. + * the maximum total weight that can be used for the queues in the system
  47108. + * (big shift values increase it), and the period of virtual time
  47109. + * wraparounds.
  47110. + */
  47111. +#define WFQ_SERVICE_SHIFT 22
  47112. +
  47113. +/**
  47114. + * bfq_gt - compare two timestamps.
  47115. + * @a: first ts.
  47116. + * @b: second ts.
  47117. + *
  47118. + * Return @a > @b, dealing with wrapping correctly.
  47119. + */
  47120. +static inline int bfq_gt(u64 a, u64 b)
  47121. +{
  47122. + return (s64)(a - b) > 0;
  47123. +}
  47124. +
  47125. +static inline struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity)
  47126. +{
  47127. + struct bfq_queue *bfqq = NULL;
  47128. +
  47129. + BUG_ON(entity == NULL);
  47130. +
  47131. + if (entity->my_sched_data == NULL)
  47132. + bfqq = container_of(entity, struct bfq_queue, entity);
  47133. +
  47134. + return bfqq;
  47135. +}
  47136. +
  47137. +
  47138. +/**
  47139. + * bfq_delta - map service into the virtual time domain.
  47140. + * @service: amount of service.
  47141. + * @weight: scale factor (weight of an entity or weight sum).
  47142. + */
  47143. +static inline u64 bfq_delta(unsigned long service,
  47144. + unsigned long weight)
  47145. +{
  47146. + u64 d = (u64)service << WFQ_SERVICE_SHIFT;
  47147. +
  47148. + do_div(d, weight);
  47149. + return d;
  47150. +}
  47151. +
  47152. +/**
  47153. + * bfq_calc_finish - assign the finish time to an entity.
  47154. + * @entity: the entity to act upon.
  47155. + * @service: the service to be charged to the entity.
  47156. + */
  47157. +static inline void bfq_calc_finish(struct bfq_entity *entity,
  47158. + unsigned long service)
  47159. +{
  47160. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47161. +
  47162. + BUG_ON(entity->weight == 0);
  47163. +
  47164. + entity->finish = entity->start +
  47165. + bfq_delta(service, entity->weight);
  47166. +
  47167. + if (bfqq != NULL) {
  47168. + bfq_log_bfqq(bfqq->bfqd, bfqq,
  47169. + "calc_finish: serv %lu, w %d",
  47170. + service, entity->weight);
  47171. + bfq_log_bfqq(bfqq->bfqd, bfqq,
  47172. + "calc_finish: start %llu, finish %llu, delta %llu",
  47173. + entity->start, entity->finish,
  47174. + bfq_delta(service, entity->weight));
  47175. + }
  47176. +}
  47177. +
  47178. +/**
  47179. + * bfq_entity_of - get an entity from a node.
  47180. + * @node: the node field of the entity.
  47181. + *
  47182. + * Convert a node pointer to the relative entity. This is used only
  47183. + * to simplify the logic of some functions and not as the generic
  47184. + * conversion mechanism because, e.g., in the tree walking functions,
  47185. + * the check for a %NULL value would be redundant.
  47186. + */
  47187. +static inline struct bfq_entity *bfq_entity_of(struct rb_node *node)
  47188. +{
  47189. + struct bfq_entity *entity = NULL;
  47190. +
  47191. + if (node != NULL)
  47192. + entity = rb_entry(node, struct bfq_entity, rb_node);
  47193. +
  47194. + return entity;
  47195. +}
  47196. +
  47197. +/**
  47198. + * bfq_extract - remove an entity from a tree.
  47199. + * @root: the tree root.
  47200. + * @entity: the entity to remove.
  47201. + */
  47202. +static inline void bfq_extract(struct rb_root *root,
  47203. + struct bfq_entity *entity)
  47204. +{
  47205. + BUG_ON(entity->tree != root);
  47206. +
  47207. + entity->tree = NULL;
  47208. + rb_erase(&entity->rb_node, root);
  47209. +}
  47210. +
  47211. +/**
  47212. + * bfq_idle_extract - extract an entity from the idle tree.
  47213. + * @st: the service tree of the owning @entity.
  47214. + * @entity: the entity being removed.
  47215. + */
  47216. +static void bfq_idle_extract(struct bfq_service_tree *st,
  47217. + struct bfq_entity *entity)
  47218. +{
  47219. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47220. + struct rb_node *next;
  47221. +
  47222. + BUG_ON(entity->tree != &st->idle);
  47223. +
  47224. + if (entity == st->first_idle) {
  47225. + next = rb_next(&entity->rb_node);
  47226. + st->first_idle = bfq_entity_of(next);
  47227. + }
  47228. +
  47229. + if (entity == st->last_idle) {
  47230. + next = rb_prev(&entity->rb_node);
  47231. + st->last_idle = bfq_entity_of(next);
  47232. + }
  47233. +
  47234. + bfq_extract(&st->idle, entity);
  47235. +
  47236. + if (bfqq != NULL)
  47237. + list_del(&bfqq->bfqq_list);
  47238. +}
  47239. +
  47240. +/**
  47241. + * bfq_insert - generic tree insertion.
  47242. + * @root: tree root.
  47243. + * @entity: entity to insert.
  47244. + *
  47245. + * This is used for the idle and the active tree, since they are both
  47246. + * ordered by finish time.
  47247. + */
  47248. +static void bfq_insert(struct rb_root *root, struct bfq_entity *entity)
  47249. +{
  47250. + struct bfq_entity *entry;
  47251. + struct rb_node **node = &root->rb_node;
  47252. + struct rb_node *parent = NULL;
  47253. +
  47254. + BUG_ON(entity->tree != NULL);
  47255. +
  47256. + while (*node != NULL) {
  47257. + parent = *node;
  47258. + entry = rb_entry(parent, struct bfq_entity, rb_node);
  47259. +
  47260. + if (bfq_gt(entry->finish, entity->finish))
  47261. + node = &parent->rb_left;
  47262. + else
  47263. + node = &parent->rb_right;
  47264. + }
  47265. +
  47266. + rb_link_node(&entity->rb_node, parent, node);
  47267. + rb_insert_color(&entity->rb_node, root);
  47268. +
  47269. + entity->tree = root;
  47270. +}
  47271. +
  47272. +/**
  47273. + * bfq_update_min - update the min_start field of a entity.
  47274. + * @entity: the entity to update.
  47275. + * @node: one of its children.
  47276. + *
  47277. + * This function is called when @entity may store an invalid value for
  47278. + * min_start due to updates to the active tree. The function assumes
  47279. + * that the subtree rooted at @node (which may be its left or its right
  47280. + * child) has a valid min_start value.
  47281. + */
  47282. +static inline void bfq_update_min(struct bfq_entity *entity,
  47283. + struct rb_node *node)
  47284. +{
  47285. + struct bfq_entity *child;
  47286. +
  47287. + if (node != NULL) {
  47288. + child = rb_entry(node, struct bfq_entity, rb_node);
  47289. + if (bfq_gt(entity->min_start, child->min_start))
  47290. + entity->min_start = child->min_start;
  47291. + }
  47292. +}
  47293. +
  47294. +/**
  47295. + * bfq_update_active_node - recalculate min_start.
  47296. + * @node: the node to update.
  47297. + *
  47298. + * @node may have changed position or one of its children may have moved,
  47299. + * this function updates its min_start value. The left and right subtrees
  47300. + * are assumed to hold a correct min_start value.
  47301. + */
  47302. +static inline void bfq_update_active_node(struct rb_node *node)
  47303. +{
  47304. + struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node);
  47305. +
  47306. + entity->min_start = entity->start;
  47307. + bfq_update_min(entity, node->rb_right);
  47308. + bfq_update_min(entity, node->rb_left);
  47309. +}
  47310. +
  47311. +/**
  47312. + * bfq_update_active_tree - update min_start for the whole active tree.
  47313. + * @node: the starting node.
  47314. + *
  47315. + * @node must be the deepest modified node after an update. This function
  47316. + * updates its min_start using the values held by its children, assuming
  47317. + * that they did not change, and then updates all the nodes that may have
  47318. + * changed in the path to the root. The only nodes that may have changed
  47319. + * are the ones in the path or their siblings.
  47320. + */
  47321. +static void bfq_update_active_tree(struct rb_node *node)
  47322. +{
  47323. + struct rb_node *parent;
  47324. +
  47325. +up:
  47326. + bfq_update_active_node(node);
  47327. +
  47328. + parent = rb_parent(node);
  47329. + if (parent == NULL)
  47330. + return;
  47331. +
  47332. + if (node == parent->rb_left && parent->rb_right != NULL)
  47333. + bfq_update_active_node(parent->rb_right);
  47334. + else if (parent->rb_left != NULL)
  47335. + bfq_update_active_node(parent->rb_left);
  47336. +
  47337. + node = parent;
  47338. + goto up;
  47339. +}
  47340. +
  47341. +static void bfq_weights_tree_add(struct bfq_data *bfqd,
  47342. + struct bfq_entity *entity,
  47343. + struct rb_root *root);
  47344. +
  47345. +static void bfq_weights_tree_remove(struct bfq_data *bfqd,
  47346. + struct bfq_entity *entity,
  47347. + struct rb_root *root);
  47348. +
  47349. +
  47350. +/**
  47351. + * bfq_active_insert - insert an entity in the active tree of its
  47352. + * group/device.
  47353. + * @st: the service tree of the entity.
  47354. + * @entity: the entity being inserted.
  47355. + *
  47356. + * The active tree is ordered by finish time, but an extra key is kept
  47357. + * per each node, containing the minimum value for the start times of
  47358. + * its children (and the node itself), so it's possible to search for
  47359. + * the eligible node with the lowest finish time in logarithmic time.
  47360. + */
  47361. +static void bfq_active_insert(struct bfq_service_tree *st,
  47362. + struct bfq_entity *entity)
  47363. +{
  47364. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47365. + struct rb_node *node = &entity->rb_node;
  47366. +#ifdef CONFIG_CGROUP_BFQIO
  47367. + struct bfq_sched_data *sd = NULL;
  47368. + struct bfq_group *bfqg = NULL;
  47369. + struct bfq_data *bfqd = NULL;
  47370. +#endif
  47371. +
  47372. + bfq_insert(&st->active, entity);
  47373. +
  47374. + if (node->rb_left != NULL)
  47375. + node = node->rb_left;
  47376. + else if (node->rb_right != NULL)
  47377. + node = node->rb_right;
  47378. +
  47379. + bfq_update_active_tree(node);
  47380. +
  47381. +#ifdef CONFIG_CGROUP_BFQIO
  47382. + sd = entity->sched_data;
  47383. + bfqg = container_of(sd, struct bfq_group, sched_data);
  47384. + BUG_ON(!bfqg);
  47385. + bfqd = (struct bfq_data *)bfqg->bfqd;
  47386. +#endif
  47387. + if (bfqq != NULL)
  47388. + list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list);
  47389. +#ifdef CONFIG_CGROUP_BFQIO
  47390. + else { /* bfq_group */
  47391. + BUG_ON(!bfqd);
  47392. + bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree);
  47393. + }
  47394. + if (bfqg != bfqd->root_group) {
  47395. + BUG_ON(!bfqg);
  47396. + BUG_ON(!bfqd);
  47397. + bfqg->active_entities++;
  47398. + if (bfqg->active_entities == 2)
  47399. + bfqd->active_numerous_groups++;
  47400. + }
  47401. +#endif
  47402. +}
  47403. +
  47404. +/**
  47405. + * bfq_ioprio_to_weight - calc a weight from an ioprio.
  47406. + * @ioprio: the ioprio value to convert.
  47407. + */
  47408. +static inline unsigned short bfq_ioprio_to_weight(int ioprio)
  47409. +{
  47410. + BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR);
  47411. + return IOPRIO_BE_NR - ioprio;
  47412. +}
  47413. +
  47414. +/**
  47415. + * bfq_weight_to_ioprio - calc an ioprio from a weight.
  47416. + * @weight: the weight value to convert.
  47417. + *
  47418. + * To preserve as mush as possible the old only-ioprio user interface,
  47419. + * 0 is used as an escape ioprio value for weights (numerically) equal or
  47420. + * larger than IOPRIO_BE_NR
  47421. + */
  47422. +static inline unsigned short bfq_weight_to_ioprio(int weight)
  47423. +{
  47424. + BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT);
  47425. + return IOPRIO_BE_NR - weight < 0 ? 0 : IOPRIO_BE_NR - weight;
  47426. +}
  47427. +
  47428. +static inline void bfq_get_entity(struct bfq_entity *entity)
  47429. +{
  47430. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47431. +
  47432. + if (bfqq != NULL) {
  47433. + atomic_inc(&bfqq->ref);
  47434. + bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d",
  47435. + bfqq, atomic_read(&bfqq->ref));
  47436. + }
  47437. +}
  47438. +
  47439. +/**
  47440. + * bfq_find_deepest - find the deepest node that an extraction can modify.
  47441. + * @node: the node being removed.
  47442. + *
  47443. + * Do the first step of an extraction in an rb tree, looking for the
  47444. + * node that will replace @node, and returning the deepest node that
  47445. + * the following modifications to the tree can touch. If @node is the
  47446. + * last node in the tree return %NULL.
  47447. + */
  47448. +static struct rb_node *bfq_find_deepest(struct rb_node *node)
  47449. +{
  47450. + struct rb_node *deepest;
  47451. +
  47452. + if (node->rb_right == NULL && node->rb_left == NULL)
  47453. + deepest = rb_parent(node);
  47454. + else if (node->rb_right == NULL)
  47455. + deepest = node->rb_left;
  47456. + else if (node->rb_left == NULL)
  47457. + deepest = node->rb_right;
  47458. + else {
  47459. + deepest = rb_next(node);
  47460. + if (deepest->rb_right != NULL)
  47461. + deepest = deepest->rb_right;
  47462. + else if (rb_parent(deepest) != node)
  47463. + deepest = rb_parent(deepest);
  47464. + }
  47465. +
  47466. + return deepest;
  47467. +}
  47468. +
  47469. +/**
  47470. + * bfq_active_extract - remove an entity from the active tree.
  47471. + * @st: the service_tree containing the tree.
  47472. + * @entity: the entity being removed.
  47473. + */
  47474. +static void bfq_active_extract(struct bfq_service_tree *st,
  47475. + struct bfq_entity *entity)
  47476. +{
  47477. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47478. + struct rb_node *node;
  47479. +#ifdef CONFIG_CGROUP_BFQIO
  47480. + struct bfq_sched_data *sd = NULL;
  47481. + struct bfq_group *bfqg = NULL;
  47482. + struct bfq_data *bfqd = NULL;
  47483. +#endif
  47484. +
  47485. + node = bfq_find_deepest(&entity->rb_node);
  47486. + bfq_extract(&st->active, entity);
  47487. +
  47488. + if (node != NULL)
  47489. + bfq_update_active_tree(node);
  47490. +
  47491. +#ifdef CONFIG_CGROUP_BFQIO
  47492. + sd = entity->sched_data;
  47493. + bfqg = container_of(sd, struct bfq_group, sched_data);
  47494. + BUG_ON(!bfqg);
  47495. + bfqd = (struct bfq_data *)bfqg->bfqd;
  47496. +#endif
  47497. + if (bfqq != NULL)
  47498. + list_del(&bfqq->bfqq_list);
  47499. +#ifdef CONFIG_CGROUP_BFQIO
  47500. + else { /* bfq_group */
  47501. + BUG_ON(!bfqd);
  47502. + bfq_weights_tree_remove(bfqd, entity,
  47503. + &bfqd->group_weights_tree);
  47504. + }
  47505. + if (bfqg != bfqd->root_group) {
  47506. + BUG_ON(!bfqg);
  47507. + BUG_ON(!bfqd);
  47508. + BUG_ON(!bfqg->active_entities);
  47509. + bfqg->active_entities--;
  47510. + if (bfqg->active_entities == 1) {
  47511. + BUG_ON(!bfqd->active_numerous_groups);
  47512. + bfqd->active_numerous_groups--;
  47513. + }
  47514. + }
  47515. +#endif
  47516. +}
  47517. +
  47518. +/**
  47519. + * bfq_idle_insert - insert an entity into the idle tree.
  47520. + * @st: the service tree containing the tree.
  47521. + * @entity: the entity to insert.
  47522. + */
  47523. +static void bfq_idle_insert(struct bfq_service_tree *st,
  47524. + struct bfq_entity *entity)
  47525. +{
  47526. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47527. + struct bfq_entity *first_idle = st->first_idle;
  47528. + struct bfq_entity *last_idle = st->last_idle;
  47529. +
  47530. + if (first_idle == NULL || bfq_gt(first_idle->finish, entity->finish))
  47531. + st->first_idle = entity;
  47532. + if (last_idle == NULL || bfq_gt(entity->finish, last_idle->finish))
  47533. + st->last_idle = entity;
  47534. +
  47535. + bfq_insert(&st->idle, entity);
  47536. +
  47537. + if (bfqq != NULL)
  47538. + list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list);
  47539. +}
  47540. +
  47541. +/**
  47542. + * bfq_forget_entity - remove an entity from the wfq trees.
  47543. + * @st: the service tree.
  47544. + * @entity: the entity being removed.
  47545. + *
  47546. + * Update the device status and forget everything about @entity, putting
  47547. + * the device reference to it, if it is a queue. Entities belonging to
  47548. + * groups are not refcounted.
  47549. + */
  47550. +static void bfq_forget_entity(struct bfq_service_tree *st,
  47551. + struct bfq_entity *entity)
  47552. +{
  47553. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47554. + struct bfq_sched_data *sd;
  47555. +
  47556. + BUG_ON(!entity->on_st);
  47557. +
  47558. + entity->on_st = 0;
  47559. + st->wsum -= entity->weight;
  47560. + if (bfqq != NULL) {
  47561. + sd = entity->sched_data;
  47562. + bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d",
  47563. + bfqq, atomic_read(&bfqq->ref));
  47564. + bfq_put_queue(bfqq);
  47565. + }
  47566. +}
  47567. +
  47568. +/**
  47569. + * bfq_put_idle_entity - release the idle tree ref of an entity.
  47570. + * @st: service tree for the entity.
  47571. + * @entity: the entity being released.
  47572. + */
  47573. +static void bfq_put_idle_entity(struct bfq_service_tree *st,
  47574. + struct bfq_entity *entity)
  47575. +{
  47576. + bfq_idle_extract(st, entity);
  47577. + bfq_forget_entity(st, entity);
  47578. +}
  47579. +
  47580. +/**
  47581. + * bfq_forget_idle - update the idle tree if necessary.
  47582. + * @st: the service tree to act upon.
  47583. + *
  47584. + * To preserve the global O(log N) complexity we only remove one entry here;
  47585. + * as the idle tree will not grow indefinitely this can be done safely.
  47586. + */
  47587. +static void bfq_forget_idle(struct bfq_service_tree *st)
  47588. +{
  47589. + struct bfq_entity *first_idle = st->first_idle;
  47590. + struct bfq_entity *last_idle = st->last_idle;
  47591. +
  47592. + if (RB_EMPTY_ROOT(&st->active) && last_idle != NULL &&
  47593. + !bfq_gt(last_idle->finish, st->vtime)) {
  47594. + /*
  47595. + * Forget the whole idle tree, increasing the vtime past
  47596. + * the last finish time of idle entities.
  47597. + */
  47598. + st->vtime = last_idle->finish;
  47599. + }
  47600. +
  47601. + if (first_idle != NULL && !bfq_gt(first_idle->finish, st->vtime))
  47602. + bfq_put_idle_entity(st, first_idle);
  47603. +}
  47604. +
  47605. +static struct bfq_service_tree *
  47606. +__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
  47607. + struct bfq_entity *entity)
  47608. +{
  47609. + struct bfq_service_tree *new_st = old_st;
  47610. +
  47611. + if (entity->ioprio_changed) {
  47612. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  47613. + unsigned short prev_weight, new_weight;
  47614. + struct bfq_data *bfqd = NULL;
  47615. + struct rb_root *root;
  47616. +#ifdef CONFIG_CGROUP_BFQIO
  47617. + struct bfq_sched_data *sd;
  47618. + struct bfq_group *bfqg;
  47619. +#endif
  47620. +
  47621. + if (bfqq != NULL)
  47622. + bfqd = bfqq->bfqd;
  47623. +#ifdef CONFIG_CGROUP_BFQIO
  47624. + else {
  47625. + sd = entity->my_sched_data;
  47626. + bfqg = container_of(sd, struct bfq_group, sched_data);
  47627. + BUG_ON(!bfqg);
  47628. + bfqd = (struct bfq_data *)bfqg->bfqd;
  47629. + BUG_ON(!bfqd);
  47630. + }
  47631. +#endif
  47632. +
  47633. + BUG_ON(old_st->wsum < entity->weight);
  47634. + old_st->wsum -= entity->weight;
  47635. +
  47636. + if (entity->new_weight != entity->orig_weight) {
  47637. + entity->orig_weight = entity->new_weight;
  47638. + entity->ioprio =
  47639. + bfq_weight_to_ioprio(entity->orig_weight);
  47640. + } else if (entity->new_ioprio != entity->ioprio) {
  47641. + entity->ioprio = entity->new_ioprio;
  47642. + entity->orig_weight =
  47643. + bfq_ioprio_to_weight(entity->ioprio);
  47644. + } else
  47645. + entity->new_weight = entity->orig_weight =
  47646. + bfq_ioprio_to_weight(entity->ioprio);
  47647. +
  47648. + entity->ioprio_class = entity->new_ioprio_class;
  47649. + entity->ioprio_changed = 0;
  47650. +
  47651. + /*
  47652. + * NOTE: here we may be changing the weight too early,
  47653. + * this will cause unfairness. The correct approach
  47654. + * would have required additional complexity to defer
  47655. + * weight changes to the proper time instants (i.e.,
  47656. + * when entity->finish <= old_st->vtime).
  47657. + */
  47658. + new_st = bfq_entity_service_tree(entity);
  47659. +
  47660. + prev_weight = entity->weight;
  47661. + new_weight = entity->orig_weight *
  47662. + (bfqq != NULL ? bfqq->wr_coeff : 1);
  47663. + /*
  47664. + * If the weight of the entity changes, remove the entity
  47665. + * from its old weight counter (if there is a counter
  47666. + * associated with the entity), and add it to the counter
  47667. + * associated with its new weight.
  47668. + */
  47669. + if (prev_weight != new_weight) {
  47670. + root = bfqq ? &bfqd->queue_weights_tree :
  47671. + &bfqd->group_weights_tree;
  47672. + bfq_weights_tree_remove(bfqd, entity, root);
  47673. + }
  47674. + entity->weight = new_weight;
  47675. + /*
  47676. + * Add the entity to its weights tree only if it is
  47677. + * not associated with a weight-raised queue.
  47678. + */
  47679. + if (prev_weight != new_weight &&
  47680. + (bfqq ? bfqq->wr_coeff == 1 : 1))
  47681. + /* If we get here, root has been initialized. */
  47682. + bfq_weights_tree_add(bfqd, entity, root);
  47683. +
  47684. + new_st->wsum += entity->weight;
  47685. +
  47686. + if (new_st != old_st)
  47687. + entity->start = new_st->vtime;
  47688. + }
  47689. +
  47690. + return new_st;
  47691. +}
  47692. +
  47693. +/**
  47694. + * bfq_bfqq_served - update the scheduler status after selection for
  47695. + * service.
  47696. + * @bfqq: the queue being served.
  47697. + * @served: bytes to transfer.
  47698. + *
  47699. + * NOTE: this can be optimized, as the timestamps of upper level entities
  47700. + * are synchronized every time a new bfqq is selected for service. By now,
  47701. + * we keep it to better check consistency.
  47702. + */
  47703. +static void bfq_bfqq_served(struct bfq_queue *bfqq, unsigned long served)
  47704. +{
  47705. + struct bfq_entity *entity = &bfqq->entity;
  47706. + struct bfq_service_tree *st;
  47707. +
  47708. + for_each_entity(entity) {
  47709. + st = bfq_entity_service_tree(entity);
  47710. +
  47711. + entity->service += served;
  47712. + BUG_ON(entity->service > entity->budget);
  47713. + BUG_ON(st->wsum == 0);
  47714. +
  47715. + st->vtime += bfq_delta(served, st->wsum);
  47716. + bfq_forget_idle(st);
  47717. + }
  47718. + bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %lu secs", served);
  47719. +}
  47720. +
  47721. +/**
  47722. + * bfq_bfqq_charge_full_budget - set the service to the entity budget.
  47723. + * @bfqq: the queue that needs a service update.
  47724. + *
  47725. + * When it's not possible to be fair in the service domain, because
  47726. + * a queue is not consuming its budget fast enough (the meaning of
  47727. + * fast depends on the timeout parameter), we charge it a full
  47728. + * budget. In this way we should obtain a sort of time-domain
  47729. + * fairness among all the seeky/slow queues.
  47730. + */
  47731. +static inline void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq)
  47732. +{
  47733. + struct bfq_entity *entity = &bfqq->entity;
  47734. +
  47735. + bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget");
  47736. +
  47737. + bfq_bfqq_served(bfqq, entity->budget - entity->service);
  47738. +}
  47739. +
  47740. +/**
  47741. + * __bfq_activate_entity - activate an entity.
  47742. + * @entity: the entity being activated.
  47743. + *
  47744. + * Called whenever an entity is activated, i.e., it is not active and one
  47745. + * of its children receives a new request, or has to be reactivated due to
  47746. + * budget exhaustion. It uses the current budget of the entity (and the
  47747. + * service received if @entity is active) of the queue to calculate its
  47748. + * timestamps.
  47749. + */
  47750. +static void __bfq_activate_entity(struct bfq_entity *entity)
  47751. +{
  47752. + struct bfq_sched_data *sd = entity->sched_data;
  47753. + struct bfq_service_tree *st = bfq_entity_service_tree(entity);
  47754. +
  47755. + if (entity == sd->in_service_entity) {
  47756. + BUG_ON(entity->tree != NULL);
  47757. + /*
  47758. + * If we are requeueing the current entity we have
  47759. + * to take care of not charging to it service it has
  47760. + * not received.
  47761. + */
  47762. + bfq_calc_finish(entity, entity->service);
  47763. + entity->start = entity->finish;
  47764. + sd->in_service_entity = NULL;
  47765. + } else if (entity->tree == &st->active) {
  47766. + /*
  47767. + * Requeueing an entity due to a change of some
  47768. + * next_in_service entity below it. We reuse the
  47769. + * old start time.
  47770. + */
  47771. + bfq_active_extract(st, entity);
  47772. + } else if (entity->tree == &st->idle) {
  47773. + /*
  47774. + * Must be on the idle tree, bfq_idle_extract() will
  47775. + * check for that.
  47776. + */
  47777. + bfq_idle_extract(st, entity);
  47778. + entity->start = bfq_gt(st->vtime, entity->finish) ?
  47779. + st->vtime : entity->finish;
  47780. + } else {
  47781. + /*
  47782. + * The finish time of the entity may be invalid, and
  47783. + * it is in the past for sure, otherwise the queue
  47784. + * would have been on the idle tree.
  47785. + */
  47786. + entity->start = st->vtime;
  47787. + st->wsum += entity->weight;
  47788. + bfq_get_entity(entity);
  47789. +
  47790. + BUG_ON(entity->on_st);
  47791. + entity->on_st = 1;
  47792. + }
  47793. +
  47794. + st = __bfq_entity_update_weight_prio(st, entity);
  47795. + bfq_calc_finish(entity, entity->budget);
  47796. + bfq_active_insert(st, entity);
  47797. +}
  47798. +
  47799. +/**
  47800. + * bfq_activate_entity - activate an entity and its ancestors if necessary.
  47801. + * @entity: the entity to activate.
  47802. + *
  47803. + * Activate @entity and all the entities on the path from it to the root.
  47804. + */
  47805. +static void bfq_activate_entity(struct bfq_entity *entity)
  47806. +{
  47807. + struct bfq_sched_data *sd;
  47808. +
  47809. + for_each_entity(entity) {
  47810. + __bfq_activate_entity(entity);
  47811. +
  47812. + sd = entity->sched_data;
  47813. + if (!bfq_update_next_in_service(sd))
  47814. + /*
  47815. + * No need to propagate the activation to the
  47816. + * upper entities, as they will be updated when
  47817. + * the in-service entity is rescheduled.
  47818. + */
  47819. + break;
  47820. + }
  47821. +}
  47822. +
  47823. +/**
  47824. + * __bfq_deactivate_entity - deactivate an entity from its service tree.
  47825. + * @entity: the entity to deactivate.
  47826. + * @requeue: if false, the entity will not be put into the idle tree.
  47827. + *
  47828. + * Deactivate an entity, independently from its previous state. If the
  47829. + * entity was not on a service tree just return, otherwise if it is on
  47830. + * any scheduler tree, extract it from that tree, and if necessary
  47831. + * and if the caller did not specify @requeue, put it on the idle tree.
  47832. + *
  47833. + * Return %1 if the caller should update the entity hierarchy, i.e.,
  47834. + * if the entity was in service or if it was the next_in_service for
  47835. + * its sched_data; return %0 otherwise.
  47836. + */
  47837. +static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
  47838. +{
  47839. + struct bfq_sched_data *sd = entity->sched_data;
  47840. + struct bfq_service_tree *st = bfq_entity_service_tree(entity);
  47841. + int was_in_service = entity == sd->in_service_entity;
  47842. + int ret = 0;
  47843. +
  47844. + if (!entity->on_st)
  47845. + return 0;
  47846. +
  47847. + BUG_ON(was_in_service && entity->tree != NULL);
  47848. +
  47849. + if (was_in_service) {
  47850. + bfq_calc_finish(entity, entity->service);
  47851. + sd->in_service_entity = NULL;
  47852. + } else if (entity->tree == &st->active)
  47853. + bfq_active_extract(st, entity);
  47854. + else if (entity->tree == &st->idle)
  47855. + bfq_idle_extract(st, entity);
  47856. + else if (entity->tree != NULL)
  47857. + BUG();
  47858. +
  47859. + if (was_in_service || sd->next_in_service == entity)
  47860. + ret = bfq_update_next_in_service(sd);
  47861. +
  47862. + if (!requeue || !bfq_gt(entity->finish, st->vtime))
  47863. + bfq_forget_entity(st, entity);
  47864. + else
  47865. + bfq_idle_insert(st, entity);
  47866. +
  47867. + BUG_ON(sd->in_service_entity == entity);
  47868. + BUG_ON(sd->next_in_service == entity);
  47869. +
  47870. + return ret;
  47871. +}
  47872. +
  47873. +/**
  47874. + * bfq_deactivate_entity - deactivate an entity.
  47875. + * @entity: the entity to deactivate.
  47876. + * @requeue: true if the entity can be put on the idle tree
  47877. + */
  47878. +static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
  47879. +{
  47880. + struct bfq_sched_data *sd;
  47881. + struct bfq_entity *parent;
  47882. +
  47883. + for_each_entity_safe(entity, parent) {
  47884. + sd = entity->sched_data;
  47885. +
  47886. + if (!__bfq_deactivate_entity(entity, requeue))
  47887. + /*
  47888. + * The parent entity is still backlogged, and
  47889. + * we don't need to update it as it is still
  47890. + * in service.
  47891. + */
  47892. + break;
  47893. +
  47894. + if (sd->next_in_service != NULL)
  47895. + /*
  47896. + * The parent entity is still backlogged and
  47897. + * the budgets on the path towards the root
  47898. + * need to be updated.
  47899. + */
  47900. + goto update;
  47901. +
  47902. + /*
  47903. + * If we reach there the parent is no more backlogged and
  47904. + * we want to propagate the dequeue upwards.
  47905. + */
  47906. + requeue = 1;
  47907. + }
  47908. +
  47909. + return;
  47910. +
  47911. +update:
  47912. + entity = parent;
  47913. + for_each_entity(entity) {
  47914. + __bfq_activate_entity(entity);
  47915. +
  47916. + sd = entity->sched_data;
  47917. + if (!bfq_update_next_in_service(sd))
  47918. + break;
  47919. + }
  47920. +}
  47921. +
  47922. +/**
  47923. + * bfq_update_vtime - update vtime if necessary.
  47924. + * @st: the service tree to act upon.
  47925. + *
  47926. + * If necessary update the service tree vtime to have at least one
  47927. + * eligible entity, skipping to its start time. Assumes that the
  47928. + * active tree of the device is not empty.
  47929. + *
  47930. + * NOTE: this hierarchical implementation updates vtimes quite often,
  47931. + * we may end up with reactivated processes getting timestamps after a
  47932. + * vtime skip done because we needed a ->first_active entity on some
  47933. + * intermediate node.
  47934. + */
  47935. +static void bfq_update_vtime(struct bfq_service_tree *st)
  47936. +{
  47937. + struct bfq_entity *entry;
  47938. + struct rb_node *node = st->active.rb_node;
  47939. +
  47940. + entry = rb_entry(node, struct bfq_entity, rb_node);
  47941. + if (bfq_gt(entry->min_start, st->vtime)) {
  47942. + st->vtime = entry->min_start;
  47943. + bfq_forget_idle(st);
  47944. + }
  47945. +}
  47946. +
  47947. +/**
  47948. + * bfq_first_active_entity - find the eligible entity with
  47949. + * the smallest finish time
  47950. + * @st: the service tree to select from.
  47951. + *
  47952. + * This function searches the first schedulable entity, starting from the
  47953. + * root of the tree and going on the left every time on this side there is
  47954. + * a subtree with at least one eligible (start >= vtime) entity. The path on
  47955. + * the right is followed only if a) the left subtree contains no eligible
  47956. + * entities and b) no eligible entity has been found yet.
  47957. + */
  47958. +static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
  47959. +{
  47960. + struct bfq_entity *entry, *first = NULL;
  47961. + struct rb_node *node = st->active.rb_node;
  47962. +
  47963. + while (node != NULL) {
  47964. + entry = rb_entry(node, struct bfq_entity, rb_node);
  47965. +left:
  47966. + if (!bfq_gt(entry->start, st->vtime))
  47967. + first = entry;
  47968. +
  47969. + BUG_ON(bfq_gt(entry->min_start, st->vtime));
  47970. +
  47971. + if (node->rb_left != NULL) {
  47972. + entry = rb_entry(node->rb_left,
  47973. + struct bfq_entity, rb_node);
  47974. + if (!bfq_gt(entry->min_start, st->vtime)) {
  47975. + node = node->rb_left;
  47976. + goto left;
  47977. + }
  47978. + }
  47979. + if (first != NULL)
  47980. + break;
  47981. + node = node->rb_right;
  47982. + }
  47983. +
  47984. + BUG_ON(first == NULL && !RB_EMPTY_ROOT(&st->active));
  47985. + return first;
  47986. +}
  47987. +
  47988. +/**
  47989. + * __bfq_lookup_next_entity - return the first eligible entity in @st.
  47990. + * @st: the service tree.
  47991. + *
  47992. + * Update the virtual time in @st and return the first eligible entity
  47993. + * it contains.
  47994. + */
  47995. +static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
  47996. + bool force)
  47997. +{
  47998. + struct bfq_entity *entity, *new_next_in_service = NULL;
  47999. +
  48000. + if (RB_EMPTY_ROOT(&st->active))
  48001. + return NULL;
  48002. +
  48003. + bfq_update_vtime(st);
  48004. + entity = bfq_first_active_entity(st);
  48005. + BUG_ON(bfq_gt(entity->start, st->vtime));
  48006. +
  48007. + /*
  48008. + * If the chosen entity does not match with the sched_data's
  48009. + * next_in_service and we are forcedly serving the IDLE priority
  48010. + * class tree, bubble up budget update.
  48011. + */
  48012. + if (unlikely(force && entity != entity->sched_data->next_in_service)) {
  48013. + new_next_in_service = entity;
  48014. + for_each_entity(new_next_in_service)
  48015. + bfq_update_budget(new_next_in_service);
  48016. + }
  48017. +
  48018. + return entity;
  48019. +}
  48020. +
  48021. +/**
  48022. + * bfq_lookup_next_entity - return the first eligible entity in @sd.
  48023. + * @sd: the sched_data.
  48024. + * @extract: if true the returned entity will be also extracted from @sd.
  48025. + *
  48026. + * NOTE: since we cache the next_in_service entity at each level of the
  48027. + * hierarchy, the complexity of the lookup can be decreased with
  48028. + * absolutely no effort just returning the cached next_in_service value;
  48029. + * we prefer to do full lookups to test the consistency of * the data
  48030. + * structures.
  48031. + */
  48032. +static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
  48033. + int extract,
  48034. + struct bfq_data *bfqd)
  48035. +{
  48036. + struct bfq_service_tree *st = sd->service_tree;
  48037. + struct bfq_entity *entity;
  48038. + int i = 0;
  48039. +
  48040. + BUG_ON(sd->in_service_entity != NULL);
  48041. +
  48042. + if (bfqd != NULL &&
  48043. + jiffies - bfqd->bfq_class_idle_last_service > BFQ_CL_IDLE_TIMEOUT) {
  48044. + entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1,
  48045. + true);
  48046. + if (entity != NULL) {
  48047. + i = BFQ_IOPRIO_CLASSES - 1;
  48048. + bfqd->bfq_class_idle_last_service = jiffies;
  48049. + sd->next_in_service = entity;
  48050. + }
  48051. + }
  48052. + for (; i < BFQ_IOPRIO_CLASSES; i++) {
  48053. + entity = __bfq_lookup_next_entity(st + i, false);
  48054. + if (entity != NULL) {
  48055. + if (extract) {
  48056. + bfq_check_next_in_service(sd, entity);
  48057. + bfq_active_extract(st + i, entity);
  48058. + sd->in_service_entity = entity;
  48059. + sd->next_in_service = NULL;
  48060. + }
  48061. + break;
  48062. + }
  48063. + }
  48064. +
  48065. + return entity;
  48066. +}
  48067. +
  48068. +/*
  48069. + * Get next queue for service.
  48070. + */
  48071. +static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
  48072. +{
  48073. + struct bfq_entity *entity = NULL;
  48074. + struct bfq_sched_data *sd;
  48075. + struct bfq_queue *bfqq;
  48076. +
  48077. + BUG_ON(bfqd->in_service_queue != NULL);
  48078. +
  48079. + if (bfqd->busy_queues == 0)
  48080. + return NULL;
  48081. +
  48082. + sd = &bfqd->root_group->sched_data;
  48083. + for (; sd != NULL; sd = entity->my_sched_data) {
  48084. + entity = bfq_lookup_next_entity(sd, 1, bfqd);
  48085. + BUG_ON(entity == NULL);
  48086. + entity->service = 0;
  48087. + }
  48088. +
  48089. + bfqq = bfq_entity_to_bfqq(entity);
  48090. + BUG_ON(bfqq == NULL);
  48091. +
  48092. + return bfqq;
  48093. +}
  48094. +
  48095. +static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
  48096. +{
  48097. + if (bfqd->in_service_bic != NULL) {
  48098. + put_io_context(bfqd->in_service_bic->icq.ioc);
  48099. + bfqd->in_service_bic = NULL;
  48100. + }
  48101. +
  48102. + bfqd->in_service_queue = NULL;
  48103. + del_timer(&bfqd->idle_slice_timer);
  48104. +}
  48105. +
  48106. +static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  48107. + int requeue)
  48108. +{
  48109. + struct bfq_entity *entity = &bfqq->entity;
  48110. +
  48111. + if (bfqq == bfqd->in_service_queue)
  48112. + __bfq_bfqd_reset_in_service(bfqd);
  48113. +
  48114. + bfq_deactivate_entity(entity, requeue);
  48115. +}
  48116. +
  48117. +static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  48118. +{
  48119. + struct bfq_entity *entity = &bfqq->entity;
  48120. +
  48121. + bfq_activate_entity(entity);
  48122. +}
  48123. +
  48124. +/*
  48125. + * Called when the bfqq no longer has requests pending, remove it from
  48126. + * the service tree.
  48127. + */
  48128. +static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  48129. + int requeue)
  48130. +{
  48131. + BUG_ON(!bfq_bfqq_busy(bfqq));
  48132. + BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
  48133. +
  48134. + bfq_log_bfqq(bfqd, bfqq, "del from busy");
  48135. +
  48136. + bfq_clear_bfqq_busy(bfqq);
  48137. +
  48138. + BUG_ON(bfqd->busy_queues == 0);
  48139. + bfqd->busy_queues--;
  48140. +
  48141. + if (!bfqq->dispatched) {
  48142. + bfq_weights_tree_remove(bfqd, &bfqq->entity,
  48143. + &bfqd->queue_weights_tree);
  48144. + if (!blk_queue_nonrot(bfqd->queue)) {
  48145. + BUG_ON(!bfqd->busy_in_flight_queues);
  48146. + bfqd->busy_in_flight_queues--;
  48147. + if (bfq_bfqq_constantly_seeky(bfqq)) {
  48148. + BUG_ON(!bfqd->
  48149. + const_seeky_busy_in_flight_queues);
  48150. + bfqd->const_seeky_busy_in_flight_queues--;
  48151. + }
  48152. + }
  48153. + }
  48154. + if (bfqq->wr_coeff > 1)
  48155. + bfqd->wr_busy_queues--;
  48156. +
  48157. + bfq_deactivate_bfqq(bfqd, bfqq, requeue);
  48158. +}
  48159. +
  48160. +/*
  48161. + * Called when an inactive queue receives a new request.
  48162. + */
  48163. +static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  48164. +{
  48165. + BUG_ON(bfq_bfqq_busy(bfqq));
  48166. + BUG_ON(bfqq == bfqd->in_service_queue);
  48167. +
  48168. + bfq_log_bfqq(bfqd, bfqq, "add to busy");
  48169. +
  48170. + bfq_activate_bfqq(bfqd, bfqq);
  48171. +
  48172. + bfq_mark_bfqq_busy(bfqq);
  48173. + bfqd->busy_queues++;
  48174. +
  48175. + if (!bfqq->dispatched) {
  48176. + if (bfqq->wr_coeff == 1)
  48177. + bfq_weights_tree_add(bfqd, &bfqq->entity,
  48178. + &bfqd->queue_weights_tree);
  48179. + if (!blk_queue_nonrot(bfqd->queue)) {
  48180. + bfqd->busy_in_flight_queues++;
  48181. + if (bfq_bfqq_constantly_seeky(bfqq))
  48182. + bfqd->const_seeky_busy_in_flight_queues++;
  48183. + }
  48184. + }
  48185. + if (bfqq->wr_coeff > 1)
  48186. + bfqd->wr_busy_queues++;
  48187. +}
  48188. diff -Nur linux-3.14.14/block/blk-core.c linux-imx6-3.14/block/blk-core.c
  48189. --- linux-3.14.14/block/blk-core.c 2014-07-28 10:07:25.000000000 -0500
  48190. +++ linux-imx6-3.14/block/blk-core.c 2014-12-08 00:31:52.368418001 -0600
  48191. @@ -1928,7 +1928,7 @@
  48192. * in some cases below, so export this function.
  48193. * Request stacking drivers like request-based dm may change the queue
  48194. * limits while requests are in the queue (e.g. dm's table swapping).
  48195. - * Such request stacking drivers should check those requests agaist
  48196. + * Such request stacking drivers should check those requests against
  48197. * the new queue limits again when they dispatch those requests,
  48198. * although such checkings are also done against the old queue limits
  48199. * when submitting requests.
  48200. diff -Nur linux-3.14.14/block/blk-map.c linux-imx6-3.14/block/blk-map.c
  48201. --- linux-3.14.14/block/blk-map.c 2014-07-28 10:07:25.000000000 -0500
  48202. +++ linux-imx6-3.14/block/blk-map.c 2014-12-08 00:31:52.368418001 -0600
  48203. @@ -285,7 +285,7 @@
  48204. *
  48205. * Description:
  48206. * Data will be mapped directly if possible. Otherwise a bounce
  48207. - * buffer is used. Can be called multple times to append multple
  48208. + * buffer is used. Can be called multiple times to append multiple
  48209. * buffers.
  48210. */
  48211. int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
  48212. diff -Nur linux-3.14.14/block/Kconfig.iosched linux-imx6-3.14/block/Kconfig.iosched
  48213. --- linux-3.14.14/block/Kconfig.iosched 2014-07-28 10:07:25.000000000 -0500
  48214. +++ linux-imx6-3.14/block/Kconfig.iosched 2014-12-08 00:31:52.364418001 -0600
  48215. @@ -39,6 +39,27 @@
  48216. ---help---
  48217. Enable group IO scheduling in CFQ.
  48218. +config IOSCHED_BFQ
  48219. + tristate "BFQ I/O scheduler"
  48220. + default n
  48221. + ---help---
  48222. + The BFQ I/O scheduler tries to distribute bandwidth among
  48223. + all processes according to their weights.
  48224. + It aims at distributing the bandwidth as desired, independently of
  48225. + the disk parameters and with any workload. It also tries to
  48226. + guarantee low latency to interactive and soft real-time
  48227. + applications. If compiled built-in (saying Y here), BFQ can
  48228. + be configured to support hierarchical scheduling.
  48229. +
  48230. +config CGROUP_BFQIO
  48231. + bool "BFQ hierarchical scheduling support"
  48232. + depends on CGROUPS && IOSCHED_BFQ=y
  48233. + default n
  48234. + ---help---
  48235. + Enable hierarchical scheduling in BFQ, using the cgroups
  48236. + filesystem interface. The name of the subsystem will be
  48237. + bfqio.
  48238. +
  48239. choice
  48240. prompt "Default I/O scheduler"
  48241. default DEFAULT_CFQ
  48242. @@ -52,6 +73,16 @@
  48243. config DEFAULT_CFQ
  48244. bool "CFQ" if IOSCHED_CFQ=y
  48245. + config DEFAULT_BFQ
  48246. + bool "BFQ" if IOSCHED_BFQ=y
  48247. + help
  48248. + Selects BFQ as the default I/O scheduler which will be
  48249. + used by default for all block devices.
  48250. + The BFQ I/O scheduler aims at distributing the bandwidth
  48251. + as desired, independently of the disk parameters and with
  48252. + any workload. It also tries to guarantee low latency to
  48253. + interactive and soft real-time applications.
  48254. +
  48255. config DEFAULT_NOOP
  48256. bool "No-op"
  48257. @@ -61,6 +92,7 @@
  48258. string
  48259. default "deadline" if DEFAULT_DEADLINE
  48260. default "cfq" if DEFAULT_CFQ
  48261. + default "bfq" if DEFAULT_BFQ
  48262. default "noop" if DEFAULT_NOOP
  48263. endmenu
  48264. diff -Nur linux-3.14.14/block/Makefile linux-imx6-3.14/block/Makefile
  48265. --- linux-3.14.14/block/Makefile 2014-07-28 10:07:25.000000000 -0500
  48266. +++ linux-imx6-3.14/block/Makefile 2014-12-08 00:31:52.364418001 -0600
  48267. @@ -16,6 +16,7 @@
  48268. obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
  48269. obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
  48270. obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
  48271. +obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o
  48272. obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
  48273. obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o
  48274. diff -Nur linux-3.14.14/crypto/blkcipher.c linux-imx6-3.14/crypto/blkcipher.c
  48275. --- linux-3.14.14/crypto/blkcipher.c 2014-07-28 10:07:25.000000000 -0500
  48276. +++ linux-imx6-3.14/crypto/blkcipher.c 2014-12-08 00:31:52.376418001 -0600
  48277. @@ -70,14 +70,12 @@
  48278. return max(start, end_page);
  48279. }
  48280. -static inline unsigned int blkcipher_done_slow(struct crypto_blkcipher *tfm,
  48281. - struct blkcipher_walk *walk,
  48282. +static inline unsigned int blkcipher_done_slow(struct blkcipher_walk *walk,
  48283. unsigned int bsize)
  48284. {
  48285. u8 *addr;
  48286. - unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
  48287. - addr = (u8 *)ALIGN((unsigned long)walk->buffer, alignmask + 1);
  48288. + addr = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
  48289. addr = blkcipher_get_spot(addr, bsize);
  48290. scatterwalk_copychunks(addr, &walk->out, bsize, 1);
  48291. return bsize;
  48292. @@ -105,7 +103,6 @@
  48293. int blkcipher_walk_done(struct blkcipher_desc *desc,
  48294. struct blkcipher_walk *walk, int err)
  48295. {
  48296. - struct crypto_blkcipher *tfm = desc->tfm;
  48297. unsigned int nbytes = 0;
  48298. if (likely(err >= 0)) {
  48299. @@ -117,7 +114,7 @@
  48300. err = -EINVAL;
  48301. goto err;
  48302. } else
  48303. - n = blkcipher_done_slow(tfm, walk, n);
  48304. + n = blkcipher_done_slow(walk, n);
  48305. nbytes = walk->total - n;
  48306. err = 0;
  48307. @@ -136,7 +133,7 @@
  48308. }
  48309. if (walk->iv != desc->info)
  48310. - memcpy(desc->info, walk->iv, crypto_blkcipher_ivsize(tfm));
  48311. + memcpy(desc->info, walk->iv, walk->ivsize);
  48312. if (walk->buffer != walk->page)
  48313. kfree(walk->buffer);
  48314. if (walk->page)
  48315. @@ -226,22 +223,20 @@
  48316. static int blkcipher_walk_next(struct blkcipher_desc *desc,
  48317. struct blkcipher_walk *walk)
  48318. {
  48319. - struct crypto_blkcipher *tfm = desc->tfm;
  48320. - unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
  48321. unsigned int bsize;
  48322. unsigned int n;
  48323. int err;
  48324. n = walk->total;
  48325. - if (unlikely(n < crypto_blkcipher_blocksize(tfm))) {
  48326. + if (unlikely(n < walk->cipher_blocksize)) {
  48327. desc->flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
  48328. return blkcipher_walk_done(desc, walk, -EINVAL);
  48329. }
  48330. walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY |
  48331. BLKCIPHER_WALK_DIFF);
  48332. - if (!scatterwalk_aligned(&walk->in, alignmask) ||
  48333. - !scatterwalk_aligned(&walk->out, alignmask)) {
  48334. + if (!scatterwalk_aligned(&walk->in, walk->alignmask) ||
  48335. + !scatterwalk_aligned(&walk->out, walk->alignmask)) {
  48336. walk->flags |= BLKCIPHER_WALK_COPY;
  48337. if (!walk->page) {
  48338. walk->page = (void *)__get_free_page(GFP_ATOMIC);
  48339. @@ -250,12 +245,12 @@
  48340. }
  48341. }
  48342. - bsize = min(walk->blocksize, n);
  48343. + bsize = min(walk->walk_blocksize, n);
  48344. n = scatterwalk_clamp(&walk->in, n);
  48345. n = scatterwalk_clamp(&walk->out, n);
  48346. if (unlikely(n < bsize)) {
  48347. - err = blkcipher_next_slow(desc, walk, bsize, alignmask);
  48348. + err = blkcipher_next_slow(desc, walk, bsize, walk->alignmask);
  48349. goto set_phys_lowmem;
  48350. }
  48351. @@ -277,28 +272,26 @@
  48352. return err;
  48353. }
  48354. -static inline int blkcipher_copy_iv(struct blkcipher_walk *walk,
  48355. - struct crypto_blkcipher *tfm,
  48356. - unsigned int alignmask)
  48357. -{
  48358. - unsigned bs = walk->blocksize;
  48359. - unsigned int ivsize = crypto_blkcipher_ivsize(tfm);
  48360. - unsigned aligned_bs = ALIGN(bs, alignmask + 1);
  48361. - unsigned int size = aligned_bs * 2 + ivsize + max(aligned_bs, ivsize) -
  48362. - (alignmask + 1);
  48363. +static inline int blkcipher_copy_iv(struct blkcipher_walk *walk)
  48364. +{
  48365. + unsigned bs = walk->walk_blocksize;
  48366. + unsigned aligned_bs = ALIGN(bs, walk->alignmask + 1);
  48367. + unsigned int size = aligned_bs * 2 +
  48368. + walk->ivsize + max(aligned_bs, walk->ivsize) -
  48369. + (walk->alignmask + 1);
  48370. u8 *iv;
  48371. - size += alignmask & ~(crypto_tfm_ctx_alignment() - 1);
  48372. + size += walk->alignmask & ~(crypto_tfm_ctx_alignment() - 1);
  48373. walk->buffer = kmalloc(size, GFP_ATOMIC);
  48374. if (!walk->buffer)
  48375. return -ENOMEM;
  48376. - iv = (u8 *)ALIGN((unsigned long)walk->buffer, alignmask + 1);
  48377. + iv = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
  48378. iv = blkcipher_get_spot(iv, bs) + aligned_bs;
  48379. iv = blkcipher_get_spot(iv, bs) + aligned_bs;
  48380. - iv = blkcipher_get_spot(iv, ivsize);
  48381. + iv = blkcipher_get_spot(iv, walk->ivsize);
  48382. - walk->iv = memcpy(iv, walk->iv, ivsize);
  48383. + walk->iv = memcpy(iv, walk->iv, walk->ivsize);
  48384. return 0;
  48385. }
  48386. @@ -306,7 +299,10 @@
  48387. struct blkcipher_walk *walk)
  48388. {
  48389. walk->flags &= ~BLKCIPHER_WALK_PHYS;
  48390. - walk->blocksize = crypto_blkcipher_blocksize(desc->tfm);
  48391. + walk->walk_blocksize = crypto_blkcipher_blocksize(desc->tfm);
  48392. + walk->cipher_blocksize = walk->walk_blocksize;
  48393. + walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
  48394. + walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
  48395. return blkcipher_walk_first(desc, walk);
  48396. }
  48397. EXPORT_SYMBOL_GPL(blkcipher_walk_virt);
  48398. @@ -315,7 +311,10 @@
  48399. struct blkcipher_walk *walk)
  48400. {
  48401. walk->flags |= BLKCIPHER_WALK_PHYS;
  48402. - walk->blocksize = crypto_blkcipher_blocksize(desc->tfm);
  48403. + walk->walk_blocksize = crypto_blkcipher_blocksize(desc->tfm);
  48404. + walk->cipher_blocksize = walk->walk_blocksize;
  48405. + walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
  48406. + walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
  48407. return blkcipher_walk_first(desc, walk);
  48408. }
  48409. EXPORT_SYMBOL_GPL(blkcipher_walk_phys);
  48410. @@ -323,9 +322,6 @@
  48411. static int blkcipher_walk_first(struct blkcipher_desc *desc,
  48412. struct blkcipher_walk *walk)
  48413. {
  48414. - struct crypto_blkcipher *tfm = desc->tfm;
  48415. - unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
  48416. -
  48417. if (WARN_ON_ONCE(in_irq()))
  48418. return -EDEADLK;
  48419. @@ -335,8 +331,8 @@
  48420. walk->buffer = NULL;
  48421. walk->iv = desc->info;
  48422. - if (unlikely(((unsigned long)walk->iv & alignmask))) {
  48423. - int err = blkcipher_copy_iv(walk, tfm, alignmask);
  48424. + if (unlikely(((unsigned long)walk->iv & walk->alignmask))) {
  48425. + int err = blkcipher_copy_iv(walk);
  48426. if (err)
  48427. return err;
  48428. }
  48429. @@ -353,11 +349,28 @@
  48430. unsigned int blocksize)
  48431. {
  48432. walk->flags &= ~BLKCIPHER_WALK_PHYS;
  48433. - walk->blocksize = blocksize;
  48434. + walk->walk_blocksize = blocksize;
  48435. + walk->cipher_blocksize = crypto_blkcipher_blocksize(desc->tfm);
  48436. + walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
  48437. + walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
  48438. return blkcipher_walk_first(desc, walk);
  48439. }
  48440. EXPORT_SYMBOL_GPL(blkcipher_walk_virt_block);
  48441. +int blkcipher_aead_walk_virt_block(struct blkcipher_desc *desc,
  48442. + struct blkcipher_walk *walk,
  48443. + struct crypto_aead *tfm,
  48444. + unsigned int blocksize)
  48445. +{
  48446. + walk->flags &= ~BLKCIPHER_WALK_PHYS;
  48447. + walk->walk_blocksize = blocksize;
  48448. + walk->cipher_blocksize = crypto_aead_blocksize(tfm);
  48449. + walk->ivsize = crypto_aead_ivsize(tfm);
  48450. + walk->alignmask = crypto_aead_alignmask(tfm);
  48451. + return blkcipher_walk_first(desc, walk);
  48452. +}
  48453. +EXPORT_SYMBOL_GPL(blkcipher_aead_walk_virt_block);
  48454. +
  48455. static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key,
  48456. unsigned int keylen)
  48457. {
  48458. diff -Nur linux-3.14.14/crypto/tcrypt.c linux-imx6-3.14/crypto/tcrypt.c
  48459. --- linux-3.14.14/crypto/tcrypt.c 2014-07-28 10:07:25.000000000 -0500
  48460. +++ linux-imx6-3.14/crypto/tcrypt.c 2014-12-08 00:31:52.384418001 -0600
  48461. @@ -33,6 +33,7 @@
  48462. #include <linux/jiffies.h>
  48463. #include <linux/timex.h>
  48464. #include <linux/interrupt.h>
  48465. +#include <linux/sched.h>
  48466. #include "tcrypt.h"
  48467. #include "internal.h"
  48468. @@ -447,6 +448,7 @@
  48469. goto out;
  48470. }
  48471. + schedule();
  48472. printk("test %u (%d bit key, %d byte blocks): ", i,
  48473. *keysize * 8, *b_size);
  48474. @@ -713,6 +715,7 @@
  48475. if (speed[i].klen)
  48476. crypto_hash_setkey(tfm, tvmem[0], speed[i].klen);
  48477. + schedule();
  48478. printk(KERN_INFO "test%3u "
  48479. "(%5u byte blocks,%5u bytes per update,%4u updates): ",
  48480. i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
  48481. @@ -953,6 +956,7 @@
  48482. break;
  48483. }
  48484. + schedule();
  48485. pr_info("test%3u "
  48486. "(%5u byte blocks,%5u bytes per update,%4u updates): ",
  48487. i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
  48488. @@ -1118,6 +1122,7 @@
  48489. goto out_free_req;
  48490. }
  48491. + schedule();
  48492. pr_info("test %u (%d bit key, %d byte blocks): ", i,
  48493. *keysize * 8, *b_size);
  48494. @@ -1199,6 +1204,7 @@
  48495. printk("alg %s ", *name);
  48496. printk(crypto_has_alg(*name, 0, 0) ?
  48497. "found\n" : "not found\n");
  48498. + schedule();
  48499. name++;
  48500. }
  48501. }
  48502. diff -Nur linux-3.14.14/Documentation/ABI/testing/sysfs-class-net-statistics linux-imx6-3.14/Documentation/ABI/testing/sysfs-class-net-statistics
  48503. --- linux-3.14.14/Documentation/ABI/testing/sysfs-class-net-statistics 1969-12-31 18:00:00.000000000 -0600
  48504. +++ linux-imx6-3.14/Documentation/ABI/testing/sysfs-class-net-statistics 2014-12-08 00:31:50.752418001 -0600
  48505. @@ -0,0 +1,201 @@
  48506. +What: /sys/class/<iface>/statistics/collisions
  48507. +Date: April 2005
  48508. +KernelVersion: 2.6.12
  48509. +Contact: netdev@vger.kernel.org
  48510. +Description:
  48511. + Indicates the number of collisions seen by this network device.
  48512. + This value might not be relevant with all MAC layers.
  48513. +
  48514. +What: /sys/class/<iface>/statistics/multicast
  48515. +Date: April 2005
  48516. +KernelVersion: 2.6.12
  48517. +Contact: netdev@vger.kernel.org
  48518. +Description:
  48519. + Indicates the number of multicast packets received by this
  48520. + network device.
  48521. +
  48522. +What: /sys/class/<iface>/statistics/rx_bytes
  48523. +Date: April 2005
  48524. +KernelVersion: 2.6.12
  48525. +Contact: netdev@vger.kernel.org
  48526. +Description:
  48527. + Indicates the number of bytes received by this network device.
  48528. + See the network driver for the exact meaning of when this
  48529. + value is incremented.
  48530. +
  48531. +What: /sys/class/<iface>/statistics/rx_compressed
  48532. +Date: April 2005
  48533. +KernelVersion: 2.6.12
  48534. +Contact: netdev@vger.kernel.org
  48535. +Description:
  48536. + Indicates the number of compressed packets received by this
  48537. + network device. This value might only be relevant for interfaces
  48538. + that support packet compression (e.g: PPP).
  48539. +
  48540. +What: /sys/class/<iface>/statistics/rx_crc_errors
  48541. +Date: April 2005
  48542. +KernelVersion: 2.6.12
  48543. +Contact: netdev@vger.kernel.org
  48544. +Description:
  48545. + Indicates the number of packets received with a CRC (FCS) error
  48546. + by this network device. Note that the specific meaning might
  48547. + depend on the MAC layer used by the interface.
  48548. +
  48549. +What: /sys/class/<iface>/statistics/rx_dropped
  48550. +Date: April 2005
  48551. +KernelVersion: 2.6.12
  48552. +Contact: netdev@vger.kernel.org
  48553. +Description:
  48554. + Indicates the number of packets received by the network device
  48555. + but dropped, that are not forwarded to the upper layers for
  48556. + packet processing. See the network driver for the exact
  48557. + meaning of this value.
  48558. +
  48559. +What: /sys/class/<iface>/statistics/rx_fifo_errors
  48560. +Date: April 2005
  48561. +KernelVersion: 2.6.12
  48562. +Contact: netdev@vger.kernel.org
  48563. +Description:
  48564. + Indicates the number of receive FIFO errors seen by this
  48565. + network device. See the network driver for the exact
  48566. + meaning of this value.
  48567. +
  48568. +What: /sys/class/<iface>/statistics/rx_frame_errors
  48569. +Date: April 2005
  48570. +KernelVersion: 2.6.12
  48571. +Contact: netdev@vger.kernel.org
  48572. +Description:
  48573. + Indicates the number of received frames with error, such as
  48574. + alignment errors. Note that the specific meaning depends on
  48575. + on the MAC layer protocol used. See the network driver for
  48576. + the exact meaning of this value.
  48577. +
  48578. +What: /sys/class/<iface>/statistics/rx_length_errors
  48579. +Date: April 2005
  48580. +KernelVersion: 2.6.12
  48581. +Contact: netdev@vger.kernel.org
  48582. +Description:
  48583. + Indicates the number of received error packet with a length
  48584. + error, oversized or undersized. See the network driver for the
  48585. + exact meaning of this value.
  48586. +
  48587. +What: /sys/class/<iface>/statistics/rx_missed_errors
  48588. +Date: April 2005
  48589. +KernelVersion: 2.6.12
  48590. +Contact: netdev@vger.kernel.org
  48591. +Description:
  48592. + Indicates the number of received packets that have been missed
  48593. + due to lack of capacity in the receive side. See the network
  48594. + driver for the exact meaning of this value.
  48595. +
  48596. +What: /sys/class/<iface>/statistics/rx_over_errors
  48597. +Date: April 2005
  48598. +KernelVersion: 2.6.12
  48599. +Contact: netdev@vger.kernel.org
  48600. +Description:
  48601. + Indicates the number of received packets that are oversized
  48602. + compared to what the network device is configured to accept
  48603. + (e.g: larger than MTU). See the network driver for the exact
  48604. + meaning of this value.
  48605. +
  48606. +What: /sys/class/<iface>/statistics/rx_packets
  48607. +Date: April 2005
  48608. +KernelVersion: 2.6.12
  48609. +Contact: netdev@vger.kernel.org
  48610. +Description:
  48611. + Indicates the total number of good packets received by this
  48612. + network device.
  48613. +
  48614. +What: /sys/class/<iface>/statistics/tx_aborted_errors
  48615. +Date: April 2005
  48616. +KernelVersion: 2.6.12
  48617. +Contact: netdev@vger.kernel.org
  48618. +Description:
  48619. + Indicates the number of packets that have been aborted
  48620. + during transmission by a network device (e.g: because of
  48621. + a medium collision). See the network driver for the exact
  48622. + meaning of this value.
  48623. +
  48624. +What: /sys/class/<iface>/statistics/tx_bytes
  48625. +Date: April 2005
  48626. +KernelVersion: 2.6.12
  48627. +Contact: netdev@vger.kernel.org
  48628. +Description:
  48629. + Indicates the number of bytes transmitted by a network
  48630. + device. See the network driver for the exact meaning of this
  48631. + value, in particular whether this accounts for all successfully
  48632. + transmitted packets or all packets that have been queued for
  48633. + transmission.
  48634. +
  48635. +What: /sys/class/<iface>/statistics/tx_carrier_errors
  48636. +Date: April 2005
  48637. +KernelVersion: 2.6.12
  48638. +Contact: netdev@vger.kernel.org
  48639. +Description:
  48640. + Indicates the number of packets that could not be transmitted
  48641. + because of carrier errors (e.g: physical link down). See the
  48642. + network driver for the exact meaning of this value.
  48643. +
  48644. +What: /sys/class/<iface>/statistics/tx_compressed
  48645. +Date: April 2005
  48646. +KernelVersion: 2.6.12
  48647. +Contact: netdev@vger.kernel.org
  48648. +Description:
  48649. + Indicates the number of transmitted compressed packets. Note
  48650. + this might only be relevant for devices that support
  48651. + compression (e.g: PPP).
  48652. +
  48653. +What: /sys/class/<iface>/statistics/tx_dropped
  48654. +Date: April 2005
  48655. +KernelVersion: 2.6.12
  48656. +Contact: netdev@vger.kernel.org
  48657. +Description:
  48658. + Indicates the number of packets dropped during transmission.
  48659. + See the driver for the exact reasons as to why the packets were
  48660. + dropped.
  48661. +
  48662. +What: /sys/class/<iface>/statistics/tx_errors
  48663. +Date: April 2005
  48664. +KernelVersion: 2.6.12
  48665. +Contact: netdev@vger.kernel.org
  48666. +Description:
  48667. + Indicates the number of packets in error during transmission by
  48668. + a network device. See the driver for the exact reasons as to
  48669. + why the packets were dropped.
  48670. +
  48671. +What: /sys/class/<iface>/statistics/tx_fifo_errors
  48672. +Date: April 2005
  48673. +KernelVersion: 2.6.12
  48674. +Contact: netdev@vger.kernel.org
  48675. +Description:
  48676. + Indicates the number of packets having caused a transmit
  48677. + FIFO error. See the driver for the exact reasons as to why the
  48678. + packets were dropped.
  48679. +
  48680. +What: /sys/class/<iface>/statistics/tx_heartbeat_errors
  48681. +Date: April 2005
  48682. +KernelVersion: 2.6.12
  48683. +Contact: netdev@vger.kernel.org
  48684. +Description:
  48685. + Indicates the number of packets transmitted that have been
  48686. + reported as heartbeat errors. See the driver for the exact
  48687. + reasons as to why the packets were dropped.
  48688. +
  48689. +What: /sys/class/<iface>/statistics/tx_packets
  48690. +Date: April 2005
  48691. +KernelVersion: 2.6.12
  48692. +Contact: netdev@vger.kernel.org
  48693. +Description:
  48694. + Indicates the number of packets transmitted by a network
  48695. + device. See the driver for whether this reports the number of all
  48696. + attempted or successful transmissions.
  48697. +
  48698. +What: /sys/class/<iface>/statistics/tx_window_errors
  48699. +Date: April 2005
  48700. +KernelVersion: 2.6.12
  48701. +Contact: netdev@vger.kernel.org
  48702. +Description:
  48703. + Indicates the number of packets not successfully transmitted
  48704. + due to a window collision. The specific meaning depends on the
  48705. + MAC layer used. On Ethernet this is usually used to report
  48706. + late collisions errors.
  48707. diff -Nur linux-3.14.14/Documentation/arm64/booting.txt linux-imx6-3.14/Documentation/arm64/booting.txt
  48708. --- linux-3.14.14/Documentation/arm64/booting.txt 2014-07-28 10:07:25.000000000 -0500
  48709. +++ linux-imx6-3.14/Documentation/arm64/booting.txt 2014-12-08 00:31:50.844418001 -0600
  48710. @@ -111,8 +111,14 @@
  48711. - Caches, MMUs
  48712. The MMU must be off.
  48713. Instruction cache may be on or off.
  48714. - Data cache must be off and invalidated.
  48715. - External caches (if present) must be configured and disabled.
  48716. + The address range corresponding to the loaded kernel image must be
  48717. + cleaned to the PoC. In the presence of a system cache or other
  48718. + coherent masters with caches enabled, this will typically require
  48719. + cache maintenance by VA rather than set/way operations.
  48720. + System caches which respect the architected cache maintenance by VA
  48721. + operations must be configured and may be enabled.
  48722. + System caches which do not respect architected cache maintenance by VA
  48723. + operations (not recommended) must be configured and disabled.
  48724. - Architected timers
  48725. CNTFRQ must be programmed with the timer frequency and CNTVOFF must
  48726. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt linux-imx6-3.14/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt
  48727. --- linux-3.14.14/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt 1969-12-31 18:00:00.000000000 -0600
  48728. +++ linux-imx6-3.14/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt 2014-12-08 00:31:50.860418001 -0600
  48729. @@ -0,0 +1,64 @@
  48730. +Freescale Busfreq driver
  48731. +
  48732. +It is a generic driver that manages the frequency of the DDR, AHB and AXI buses in the iMX6x architecture.
  48733. +It works for both SMP and UP systems and for both DDR3 and LPDDR2 memory types.
  48734. +
  48735. +Required properties are listed below:
  48736. +- compatible: should be "fsl,imx6_busfreq"
  48737. +- clocks: Lists the various clocks used by the busfreq driver
  48738. +- interrupts - Lists the interrupts used by the busfreq driver. This is needed only for SMP architecutre.
  48739. +- fsl,max_ddr_freq - The max ddr freq for this chip
  48740. +
  48741. +Examples:
  48742. +For SOC imx6q.dtsi:
  48743. + busfreq { /* BUSFREQ */
  48744. + compatible = "fsl,imx6_busfreq";
  48745. + clocks = <&clks 171>, <&clks 6>, <&clks 11>, <&clks 104>, <&clks 172>, <&clks 58>,
  48746. + <&clks 18>, <&clks 60>, <&clks 20>, <&clks 3>;
  48747. + clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
  48748. + "periph_pre", "periph_clk2", "periph_clk2_sel", "osc";
  48749. + interrupts = <0 107 0x04>, <0 112 0x4>, <0 113 0x4>, <0 114 0x4>;
  48750. + interrupt-names = "irq_busfreq_0", "irq_busfreq_1", "irq_busfreq_2", "irq_busfreq_3";
  48751. + fsl,max_ddr_freq = <528000000>;
  48752. + };
  48753. +
  48754. +The Freescale Busfreq driver supports the following setpoints for the DDR freq:
  48755. +enum bus_freq_mode {
  48756. + BUS_FREQ_HIGH, -> The max freq the SOC supports
  48757. + BUS_FREQ_MED, -> Medium setpoint (ex 400MHz for DDR3 when the max is 528MHz)
  48758. + BUS_FREQ_AUDIO, -> Audio playback freq (50MHz)
  48759. + BUS_FREQ_LOW, -> Low power IDLE freq (24MHz)
  48760. +};
  48761. +
  48762. +Currently the Freescale Busfreq driver implementation requires drivers to call the following APIs:
  48763. +1. request_bus_freq(enum bus_freq_mode):
  48764. + The driver is requesting the system and ddr freq to be set to the requested value. The driver should call this
  48765. + API before it even enables its clocks.
  48766. +
  48767. +2. release_bus_freq(enum bus_freq_mode):
  48768. + The driver no longer needs the system and ddr freq at the required value. The driver should call this API after
  48769. + its work is done and it has disabled its clocks.
  48770. +
  48771. +Examples:
  48772. +In the IPU driver, the requesting and releasing of the required bus frequency is tied into the runtime PM implementation:
  48773. +
  48774. +int ipu_runtime_suspend(struct device *dev)
  48775. +{
  48776. + release_bus_freq(BUS_FREQ_HIGH);
  48777. + dev_dbg(dev, "ipu busfreq high release.\n");
  48778. +
  48779. + return 0;
  48780. +}
  48781. +
  48782. +int ipu_runtime_resume(struct device *dev)
  48783. +{
  48784. + request_bus_freq(BUS_FREQ_HIGH);
  48785. + dev_dbg(dev, "ipu busfreq high requst.\n");
  48786. +
  48787. + return 0;
  48788. +}
  48789. +
  48790. +static const struct dev_pm_ops ipu_pm_ops = {
  48791. + SET_RUNTIME_PM_OPS(ipu_runtime_suspend, ipu_runtime_resume, NULL)
  48792. + SET_SYSTEM_SLEEP_PM_OPS(ipu_suspend, ipu_resume)
  48793. +};
  48794. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/arm/imx/gpc.txt linux-imx6-3.14/Documentation/devicetree/bindings/arm/imx/gpc.txt
  48795. --- linux-3.14.14/Documentation/devicetree/bindings/arm/imx/gpc.txt 1969-12-31 18:00:00.000000000 -0600
  48796. +++ linux-imx6-3.14/Documentation/devicetree/bindings/arm/imx/gpc.txt 2014-12-08 00:31:50.860418001 -0600
  48797. @@ -0,0 +1,20 @@
  48798. +Freescale imx GPC bindings
  48799. +
  48800. +Optional properties:
  48801. +- fsl,cpu_pupscr_sw2iso: for powering up CPU, number of 32K clock cycle PGC will wait before negating isolation signal.
  48802. +- fsl,cpu_pupscr_sw: for powering up CPU, number of 32K clock cycle PGC will wait before asserting isolation signal.
  48803. +- fsl,cpu_pdnscr_iso2sw: for powering down CPU, number of ipg clock cycle PGC will wait before negating isolation signal.
  48804. +- fsl,cpu_pdnscr_iso: for powering down CPU, number of ipg clock cycle PGC will wait before asserting isolation signal.
  48805. +
  48806. +These properties are for adjusting the GPC PGC CPU power up/down setting, if there is no such property in dts, then default
  48807. +value in GPC PGC registers will be used.
  48808. +
  48809. +
  48810. +Example:
  48811. +
  48812. + &gpc {
  48813. + fsl,cpu_pupscr_sw2iso = <0xf>;
  48814. + fsl,cpu_pupscr_sw = <0xf>;
  48815. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  48816. + fsl,cpu_pdnscr_iso = <0x1>;
  48817. + };
  48818. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/arm/pmu.txt linux-imx6-3.14/Documentation/devicetree/bindings/arm/pmu.txt
  48819. --- linux-3.14.14/Documentation/devicetree/bindings/arm/pmu.txt 2014-07-28 10:07:25.000000000 -0500
  48820. +++ linux-imx6-3.14/Documentation/devicetree/bindings/arm/pmu.txt 2014-12-08 00:31:50.864418001 -0600
  48821. @@ -17,6 +17,9 @@
  48822. "arm,arm1176-pmu"
  48823. "arm,arm1136-pmu"
  48824. - interrupts : 1 combined interrupt or 1 per core.
  48825. +- cluster : a phandle to the cluster to which it belongs
  48826. + If there are more than one cluster with same CPU type
  48827. + then there should be separate PMU nodes per cluster.
  48828. Example:
  48829. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/ata/ahci-platform.txt linux-imx6-3.14/Documentation/devicetree/bindings/ata/ahci-platform.txt
  48830. --- linux-3.14.14/Documentation/devicetree/bindings/ata/ahci-platform.txt 2014-07-28 10:07:25.000000000 -0500
  48831. +++ linux-imx6-3.14/Documentation/devicetree/bindings/ata/ahci-platform.txt 2014-12-08 00:31:50.880418001 -0600
  48832. @@ -4,12 +4,19 @@
  48833. Each SATA controller should have its own node.
  48834. Required properties:
  48835. -- compatible : compatible list, contains "snps,spear-ahci"
  48836. +- compatible : compatible list, contains "snps,spear-ahci",
  48837. + "fsl,imx53-ahci" or "fsl,imx6q-ahci"
  48838. - interrupts : <interrupt mapping for SATA IRQ>
  48839. - reg : <registers mapping>
  48840. Optional properties:
  48841. - dma-coherent : Present if dma operations are coherent
  48842. +- clocks : a list of phandle + clock specifier pairs
  48843. +- target-supply : regulator for SATA target power
  48844. +
  48845. +"fsl,imx53-ahci", "fsl,imx6q-ahci" required properties:
  48846. +- clocks : must contain the sata, sata_ref and ahb clocks
  48847. +- clock-names : must contain "ahb" for the ahb clock
  48848. Example:
  48849. sata@ffe08000 {
  48850. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/clock/imx6q-clock.txt linux-imx6-3.14/Documentation/devicetree/bindings/clock/imx6q-clock.txt
  48851. --- linux-3.14.14/Documentation/devicetree/bindings/clock/imx6q-clock.txt 2014-07-28 10:07:25.000000000 -0500
  48852. +++ linux-imx6-3.14/Documentation/devicetree/bindings/clock/imx6q-clock.txt 2014-12-08 00:31:50.884418001 -0600
  48853. @@ -89,8 +89,6 @@
  48854. gpu3d_shader 74
  48855. ipu1_podf 75
  48856. ipu2_podf 76
  48857. - ldb_di0_podf 77
  48858. - ldb_di1_podf 78
  48859. ipu1_di0_pre 79
  48860. ipu1_di1_pre 80
  48861. ipu2_di0_pre 81
  48862. @@ -220,6 +218,20 @@
  48863. lvds2_sel 205
  48864. lvds1_gate 206
  48865. lvds2_gate 207
  48866. + gpt_3m 208
  48867. + video_27m 209
  48868. + ldb_di0_div_7 210
  48869. + ldb_di1_div_7 211
  48870. + ldb_di0_div_sel 212
  48871. + ldb_di1_div_sel 213
  48872. + caam_mem 214
  48873. + caam_aclk 215
  48874. + caam_ipg 216
  48875. + epit1 217
  48876. + epit2 218
  48877. + tzasc2 219
  48878. + lvds1_in 220
  48879. + lvds1_out 221
  48880. Examples:
  48881. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt linux-imx6-3.14/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
  48882. --- linux-3.14.14/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt 2014-07-28 10:07:25.000000000 -0500
  48883. +++ linux-imx6-3.14/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt 2014-12-08 00:31:50.892418001 -0600
  48884. @@ -47,6 +47,7 @@
  48885. 20 ASRC
  48886. 21 ESAI
  48887. 22 SSI Dual FIFO (needs firmware ver >= 2)
  48888. + 23 HDMI Audio
  48889. The third cell specifies the transfer priority as below.
  48890. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt linux-imx6-3.14/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt
  48891. --- linux-3.14.14/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt 1969-12-31 18:00:00.000000000 -0600
  48892. +++ linux-imx6-3.14/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt 2014-12-08 00:31:50.892418001 -0600
  48893. @@ -0,0 +1,146 @@
  48894. +* FSL IPUv3 Display/FB
  48895. +
  48896. +The FSL IPUv3 is Image Processing Unit version 3, a part of video and graphics
  48897. +subsystem in an application processor. The goal of the IPU is to provide
  48898. +comprehensive support for the flow of data from an image sensor or/and to a
  48899. +display device.
  48900. +
  48901. +Two IPU units are on the imx6q SOC while only one IPU unit on the imx6dl SOC.
  48902. +Each IPU unit has two display interfaces.
  48903. +
  48904. +For LDB/LVDS panel, there are two LVDS channels(LVDS0 and LVDS1) which can
  48905. +transfer video data, these two channels can be used as
  48906. +split/dual/single/separate mode.
  48907. +-split mode means display data from DI0 or DI1 will send to both channels
  48908. + LVDS0+LVDS1.
  48909. +-dual mode means display data from DI0 or DI1 will be duplicated on LVDS0
  48910. + and LVDS1, it said, LVDS0 and LVDS1 has the same content.
  48911. +-single mode means only work for DI0/DI1->LVDS0 or DI0/DI1->LVDS1.
  48912. +-separate mode means you can make DI0/DI1->LVDS0 and DI0/DI1->LVDS1 work
  48913. + at the same time.
  48914. + "ldb=spl0/1" -- split mode on DI0/1
  48915. + "ldb=dul0/1" -- dual mode on DI0/1
  48916. + "ldb=sin0/1" -- single mode on LVDS0/1
  48917. + "ldb=sep0/1" -- separate mode begin from LVDS0/1
  48918. +
  48919. +Required properties for IPU:
  48920. +- bypass_reset :Bypass reset to avoid display channel being.
  48921. + stopped by probe since it may start to work in bootloader: 0 or 1.
  48922. +- compatible : should be "fsl,imx6q-ipu".
  48923. +- reg : the register address range.
  48924. +- interrupts : the error and sync interrupts request.
  48925. +- clocks : the clock sources that it depends on.
  48926. +- clock-names: the related clock names.
  48927. +- resets : IPU reset specifier. See reset.txt and fsl,imx-src.txt in
  48928. + Documentation/devicetree/bindings/reset/ for details.
  48929. +
  48930. +Required properties for fb:
  48931. +- compatible : should be "fsl,mxc_sdc_fb".
  48932. +- disp_dev : display device: "ldb", "lcd", "hdmi", "mipi_dsi".
  48933. +- mode_str : video mode string: "LDB-XGA" or "LDB-1080P60" for ldb,
  48934. + "CLAA-WVGA" for lcd, "TRULY-WVGA" for TRULY mipi_dsi lcd panel,
  48935. + "1920x1080M@60" for hdmi.
  48936. +- default_bpp : default bits per pixel: 8/16/24/32
  48937. +- int_clk : use internal clock as pixel clock: 0 or 1
  48938. +- late_init : to avoid display channel being re-initialized
  48939. + as we've probably setup the channel in bootloader: 0 or 1
  48940. +- interface_pix_fmt : display interface pixel format as below:
  48941. + RGB666 IPU_PIX_FMT_RGB666
  48942. + RGB565 IPU_PIX_FMT_RGB565
  48943. + RGB24 IPU_PIX_FMT_RGB24
  48944. + BGR24 IPU_PIX_FMT_BGR24
  48945. + GBR24 IPU_PIX_FMT_GBR24
  48946. + YUV444 IPU_PIX_FMT_YUV444
  48947. + LVDS666 IPU_PIX_FMT_LVDS666
  48948. + YUYV IPU_PIX_FMT_YUYV
  48949. + UYVY IPU_PIX_FMT_UYVY
  48950. + YVYV IPU_PIX_FMT_YVYU
  48951. + VYUY IPU_PIX_FMT_VYUY
  48952. +
  48953. +Required properties for display:
  48954. +- compatible : should be "fsl,lcd" for lcd panel, "fsl,imx6q-ldb" for ldb
  48955. +- reg : the register address range if necessary to have.
  48956. +- interrupts : the error and sync interrupts if necessary to have.
  48957. +- clocks : the clock sources that it depends on if necessary to have.
  48958. +- clock-names: the related clock names if necessary to have.
  48959. +- ipu_id : ipu id for the first display device: 0 or 1
  48960. +- disp_id : display interface id for the first display interface: 0 or 1
  48961. +- default_ifmt : save as above display interface pixel format for lcd
  48962. +- pinctrl-names : should be "default"
  48963. +- pinctrl-0 : should be pinctrl_ipu1_1 or pinctrl_ipu2_1, which depends on the
  48964. + IPU connected.
  48965. +- sec_ipu_id : secondary ipu id for the second display device(ldb only): 0 or 1
  48966. +- sec_disp_id : secondary display interface id for the second display
  48967. + device(ldb only): 0 or 1
  48968. +- ext_ref : reference resistor select for ldb only: 0 or 1
  48969. +- mode : ldb mode as below:
  48970. + spl0 LDB_SPL_DI0
  48971. + spl1 LDB_SPL_DI1
  48972. + dul0 LDB_DUL_DI0
  48973. + dul1 LDB_DUL_DI1
  48974. + sin0 LDB_SIN0
  48975. + sin1 LDB_SIN1
  48976. + sep0 LDB_SEP0
  48977. + sep1 LDB_SEP1
  48978. +- gpr : the mux controller for the display engine's display interfaces and the display encoder
  48979. + (only valid for mipi dsi now).
  48980. +- disp-power-on-supply : the regulator to control display panel's power.
  48981. + (only valid for mipi dsi now).
  48982. +- resets : the gpio pin to reset the display device(only valid for mipi display panel now).
  48983. +- lcd_panel : the video mode name for the display device(only valid for mipi display panel now).
  48984. +- dev_id : the display engine's identity within the system, which intends to replace ipu_id
  48985. + (only valid for mipi dsi now).
  48986. +
  48987. +Example for IPU:
  48988. + ipu1: ipu@02400000 {
  48989. + compatible = "fsl,imx6q-ipu";
  48990. + reg = <0x02400000 0x400000>;
  48991. + interrupts = <0 6 0x4 0 5 0x4>;
  48992. + clocks = <&clks 130>, <&clks 131>, <&clks 132>,
  48993. + <&clks 39>, <&clks 40>,
  48994. + <&clks 135>, <&clks 136>;
  48995. + clock-names = "bus", "di0", "di1",
  48996. + "di0_sel", "di1_sel",
  48997. + "ldb_di0", "ldb_di1";
  48998. + resets = <&src 2>;
  48999. + bypass_reset = <0>;
  49000. + };
  49001. +
  49002. +Example for fb:
  49003. + fb0 {
  49004. + compatible = "fsl,mxc_sdc_fb";
  49005. + disp_dev = "ldb";
  49006. + interface_pix_fmt = "RGB666";
  49007. + mode_str ="LDB-XGA";
  49008. + default_bpp = <16>;
  49009. + int_clk = <0>;
  49010. + late_init = <0>;
  49011. + status = "okay";
  49012. + };
  49013. +
  49014. +Example for ldb display:
  49015. + ldb@020e0000 {
  49016. + ipu_id = <1>;
  49017. + disp_id = <0>;
  49018. + ext_ref = <1>;
  49019. + mode = "sep0";
  49020. + sec_ipu_id = <1>;
  49021. + sec_disp_id = <1>;
  49022. + status = "okay";
  49023. + };
  49024. +
  49025. +Example for mipi dsi display:
  49026. + mipi_dsi: mipi@021e0000 {
  49027. + compatible = "fsl,imx6q-mipi-dsi";
  49028. + reg = <0x021e0000 0x4000>;
  49029. + interrupts = <0 102 0x04>;
  49030. + gpr = <&gpr>;
  49031. + clocks = <&clks 138>, <&clks 204>;
  49032. + clock-names = "mipi_pllref_clk", "mipi_cfg_clk";
  49033. + dev_id = <0>;
  49034. + disp_id = <0>;
  49035. + lcd_panel = "TRULY-WVGA";
  49036. + disp-power-on-supply = <&reg_mipi_dsi_pwr_on>
  49037. + resets = <&mipi_dsi_reset>;
  49038. + status = "okay";
  49039. + };
  49040. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/leds/leds-pwm.txt linux-imx6-3.14/Documentation/devicetree/bindings/leds/leds-pwm.txt
  49041. --- linux-3.14.14/Documentation/devicetree/bindings/leds/leds-pwm.txt 2014-07-28 10:07:25.000000000 -0500
  49042. +++ linux-imx6-3.14/Documentation/devicetree/bindings/leds/leds-pwm.txt 2014-12-08 00:31:50.928418001 -0600
  49043. @@ -13,6 +13,8 @@
  49044. For the pwms and pwm-names property please refer to:
  49045. Documentation/devicetree/bindings/pwm/pwm.txt
  49046. - max-brightness : Maximum brightness possible for the LED
  49047. +- active-low : (optional) For PWMs where the LED is wired to supply
  49048. + rather than ground.
  49049. - label : (optional)
  49050. see Documentation/devicetree/bindings/leds/common.txt
  49051. - linux,default-trigger : (optional)
  49052. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/mailbox/mailbox.txt linux-imx6-3.14/Documentation/devicetree/bindings/mailbox/mailbox.txt
  49053. --- linux-3.14.14/Documentation/devicetree/bindings/mailbox/mailbox.txt 1969-12-31 18:00:00.000000000 -0600
  49054. +++ linux-imx6-3.14/Documentation/devicetree/bindings/mailbox/mailbox.txt 2014-12-08 00:31:50.928418001 -0600
  49055. @@ -0,0 +1,33 @@
  49056. +* Generic Mailbox Controller and client driver bindings
  49057. +
  49058. +Generic binding to provide a way for Mailbox controller drivers to
  49059. +assign appropriate mailbox channel to client drivers.
  49060. +
  49061. +* Mailbox Controller
  49062. +
  49063. +Required property:
  49064. +- #mbox-cells: Must be at least 1. Number of cells in a mailbox
  49065. + specifier.
  49066. +
  49067. +Example:
  49068. + mailbox: mailbox {
  49069. + ...
  49070. + #mbox-cells = <1>;
  49071. + };
  49072. +
  49073. +
  49074. +* Mailbox Client
  49075. +
  49076. +Required property:
  49077. +- mbox: List of phandle and mailbox channel specifier.
  49078. +
  49079. +- mbox-names: List of identifier strings for each mailbox channel
  49080. + required by the client.
  49081. +
  49082. +Example:
  49083. + pwr_cntrl: power {
  49084. + ...
  49085. + mbox-names = "pwr-ctrl", "rpc";
  49086. + mbox = <&mailbox 0
  49087. + &mailbox 1>;
  49088. + };
  49089. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/mlb/mlb150.txt linux-imx6-3.14/Documentation/devicetree/bindings/mlb/mlb150.txt
  49090. --- linux-3.14.14/Documentation/devicetree/bindings/mlb/mlb150.txt 1969-12-31 18:00:00.000000000 -0600
  49091. +++ linux-imx6-3.14/Documentation/devicetree/bindings/mlb/mlb150.txt 2014-12-08 00:31:50.932418001 -0600
  49092. @@ -0,0 +1,22 @@
  49093. +* Freescale Media Local Bus Host Controller (MLB) for i.MX6Q/DL
  49094. +
  49095. +The Media Local Bus Host Controller on Freescale i.MX family
  49096. +provides an interface for MOST network.
  49097. +
  49098. +Required properties:
  49099. +- compatible : Should be "fsl,<chip>-mlb150"
  49100. +- reg : Should contain mlb registers location and length
  49101. +- interrupts : Should contain mlb interrupt
  49102. +- clocks: Should contain the mlb clock sources
  49103. +- clock-names: Should be the names of mlb clock sources
  49104. +- iram : phandle pointing to the SRAM device node
  49105. +
  49106. +Examples:
  49107. +mlb@0218c000 {
  49108. + compatible = "fsl,imx6q-mlb150";
  49109. + reg = <0x0218c000 0x4000>;
  49110. + interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
  49111. + clocks = <&clks 139>, <&clks 175>;
  49112. + clock-names = "mlb", "pll8_mlb";
  49113. + iram = <&ocram>;
  49114. +};
  49115. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/mmc/mmc.txt linux-imx6-3.14/Documentation/devicetree/bindings/mmc/mmc.txt
  49116. --- linux-3.14.14/Documentation/devicetree/bindings/mmc/mmc.txt 2014-07-28 10:07:25.000000000 -0500
  49117. +++ linux-imx6-3.14/Documentation/devicetree/bindings/mmc/mmc.txt 2014-12-08 00:31:50.932418001 -0600
  49118. @@ -5,6 +5,8 @@
  49119. Interpreted by the OF core:
  49120. - reg: Registers location and length.
  49121. - interrupts: Interrupts used by the MMC controller.
  49122. +- clocks: Clocks needed for the host controller, if any.
  49123. +- clock-names: Goes with clocks above.
  49124. Card detection:
  49125. If no property below is supplied, host native card detect is used.
  49126. @@ -30,6 +32,15 @@
  49127. - cap-sdio-irq: enable SDIO IRQ signalling on this interface
  49128. - full-pwr-cycle: full power cycle of the card is supported
  49129. +Card power and reset control:
  49130. +The following properties can be specified for cases where the MMC
  49131. +peripheral needs additional reset, regulator and clock lines. It is for
  49132. +example common for WiFi/BT adapters to have these separate from the main
  49133. +MMC bus:
  49134. + - card-reset-gpios: Specify GPIOs for card reset (reset active low)
  49135. + - card-external-vcc-supply: Regulator to drive (independent) card VCC
  49136. + - clock with name "card_ext_clock": External clock provided to the card
  49137. +
  49138. *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
  49139. polarity properties, we have to fix the meaning of the "normal" and "inverted"
  49140. line levels. We choose to follow the SDHCI standard, which specifies both those
  49141. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt linux-imx6-3.14/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
  49142. --- linux-3.14.14/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt 2014-07-28 10:07:25.000000000 -0500
  49143. +++ linux-imx6-3.14/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt 2014-12-08 00:31:50.940418001 -0600
  49144. @@ -71,6 +71,13 @@
  49145. name for integer state ID 0, list entry 1 for state ID 1, and
  49146. so on.
  49147. +pinctrl-assert-gpios:
  49148. + List of phandles, each pointing at a GPIO which is used by some
  49149. + board design to steer pins between two peripherals on the board.
  49150. + It plays like a board level pin multiplexer to choose different
  49151. + functions for given pins by pulling up/down the GPIOs. See
  49152. + bindings/gpio/gpio.txt for details of how to specify GPIO.
  49153. +
  49154. For example:
  49155. /* For a client device requiring named states */
  49156. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/reset/gpio-reset.txt linux-imx6-3.14/Documentation/devicetree/bindings/reset/gpio-reset.txt
  49157. --- linux-3.14.14/Documentation/devicetree/bindings/reset/gpio-reset.txt 1969-12-31 18:00:00.000000000 -0600
  49158. +++ linux-imx6-3.14/Documentation/devicetree/bindings/reset/gpio-reset.txt 2014-12-08 00:31:50.944418001 -0600
  49159. @@ -0,0 +1,35 @@
  49160. +GPIO reset controller
  49161. +=====================
  49162. +
  49163. +A GPIO reset controller controls a single GPIO that is connected to the reset
  49164. +pin of a peripheral IC. Please also refer to reset.txt in this directory for
  49165. +common reset controller binding usage.
  49166. +
  49167. +Required properties:
  49168. +- compatible: Should be "gpio-reset"
  49169. +- reset-gpios: A gpio used as reset line. The gpio specifier for this property
  49170. + depends on the gpio controller that provides the gpio.
  49171. +- #reset-cells: 0, see below
  49172. +
  49173. +Optional properties:
  49174. +- reset-delay-us: delay in microseconds. The gpio reset line will be asserted for
  49175. + this duration to reset.
  49176. +- initially-in-reset: boolean. If not set, the initial state should be a
  49177. + deasserted reset line. If this property exists, the
  49178. + reset line should be kept in reset.
  49179. +
  49180. +example:
  49181. +
  49182. +sii902x_reset: gpio-reset {
  49183. + compatible = "gpio-reset";
  49184. + reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
  49185. + reset-delay-us = <10000>;
  49186. + initially-in-reset;
  49187. + #reset-cells = <0>;
  49188. +};
  49189. +
  49190. +/* Device with nRESET pin connected to GPIO5_0 */
  49191. +sii902x@39 {
  49192. + /* ... */
  49193. + resets = <&sii902x_reset>; /* active-low GPIO5_0, 10 ms delay */
  49194. +};
  49195. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/sound/cs42888.txt linux-imx6-3.14/Documentation/devicetree/bindings/sound/cs42888.txt
  49196. --- linux-3.14.14/Documentation/devicetree/bindings/sound/cs42888.txt 1969-12-31 18:00:00.000000000 -0600
  49197. +++ linux-imx6-3.14/Documentation/devicetree/bindings/sound/cs42888.txt 2014-12-08 00:31:50.948418001 -0600
  49198. @@ -0,0 +1,29 @@
  49199. +CS42888 audio CODEC
  49200. +
  49201. +This device supports I2C only.
  49202. +
  49203. +Required properties:
  49204. +
  49205. + - compatible: "cirrus,cs42888"
  49206. + - reg: the I2C address of the device.
  49207. + - clocks: Phandle to the clock node.
  49208. + - clock-names: Contains name for each entry in clocks.
  49209. + "codec_osc" : the external oscillator.
  49210. + "esai" : the hckt clock from esai.
  49211. + - <name>-supply: Phandle to the regulator <name>.
  49212. +
  49213. +Note: cs42888 needs a regulators node and a clocks node.
  49214. +
  49215. +Example:
  49216. +In this case, the clock is external oscillator.
  49217. +
  49218. +codec: cs42888@48 {
  49219. + compatible = "cirrus,cs42888";
  49220. + reg = <0x048>;
  49221. + clocks = <&codec_osc 0>;
  49222. + clock-names = "codec_osc";
  49223. + VA-supply = <&reg_audio>;
  49224. + VD-supply = <&reg_audio>;
  49225. + VLS-supply = <&reg_audio>;
  49226. + VLC-supply = <&reg_audio>;
  49227. +};
  49228. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt linux-imx6-3.14/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt
  49229. --- linux-3.14.14/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt 1969-12-31 18:00:00.000000000 -0600
  49230. +++ linux-imx6-3.14/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt 2014-12-08 00:31:50.948418001 -0600
  49231. @@ -0,0 +1,23 @@
  49232. +* Freescale Asynchronous Sample Rate Converter (ASRC)
  49233. +
  49234. +This document is for asrc p2p node. p2p is one of asrc mode. asrc p2p depend on
  49235. +MXC_ASRC.
  49236. +
  49237. +Required properties:
  49238. + - compatible: Should be "fsl,<chip>-asrc-p2p".
  49239. + - fsl,output-rate: the output rate of asrc p2p. which can be <32000> to <192000>,
  49240. + - fsl,output-width: the output width of asrc p2p. which can be <16>, <24>.
  49241. + - fsl,asrc-dma-rx-events: The rx dma event of the asrc, <a b c> corresponding
  49242. + to 3 pair of asrc.
  49243. + - fsl,asrc-dma-tx-events: The tx dma event of the esai, <a b c> corresponding
  49244. + to 3 pair of asrc.
  49245. +
  49246. +Example:
  49247. +asrc_p2p: asrc_p2p {
  49248. + compatible = "fsl,imx6q-asrc-p2p";
  49249. + fsl,output-rate = <48000>;
  49250. + fsl,output-width = <16>;
  49251. + fsl,asrc-dma-rx-events = <17 18 19>;
  49252. + fsl,asrc-dma-tx-events = <20 21 22>;
  49253. + status = "okay";
  49254. +};
  49255. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt linux-imx6-3.14/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt
  49256. --- linux-3.14.14/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt 1969-12-31 18:00:00.000000000 -0600
  49257. +++ linux-imx6-3.14/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt 2014-12-08 00:31:50.948418001 -0600
  49258. @@ -0,0 +1,25 @@
  49259. +Freescale i.MX audio complex with CS42888 codec
  49260. +
  49261. +Required properties:
  49262. +- compatible : "fsl,imx-audio-cs42888"
  49263. +- model : The user-visible name of this sound complex
  49264. +- esai-controller : The phandle of the i.MX SSI controller
  49265. +- audio-codec : The phandle of the CS42888 audio codec
  49266. +
  49267. +Optional properties:
  49268. +- asrc-controller : The phandle of the i.MX ASRC controller
  49269. +- audio-routing : A list of the connections between audio components.
  49270. + Each entry is a pair of strings, the first being the connection's sink,
  49271. + the second being the connection's source. Valid names could be power
  49272. + supplies, CS42888 pins, and the jacks on the board:
  49273. +
  49274. +Example:
  49275. +
  49276. +sound {
  49277. + compatible = "fsl,imx6q-sabresd-wm8962",
  49278. + "fsl,imx-audio-wm8962";
  49279. + model = "cs42888-audio";
  49280. + esai-controller = <&esai>;
  49281. + asrc-controller = <&asrc_p2p>;
  49282. + audio-codec = <&codec>;
  49283. +};
  49284. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt linux-imx6-3.14/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
  49285. --- linux-3.14.14/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt 2014-07-28 10:07:25.000000000 -0500
  49286. +++ linux-imx6-3.14/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt 2014-12-08 00:31:50.948418001 -0600
  49287. @@ -24,6 +24,12 @@
  49288. Note: The AUDMUX port numbering should start at 1, which is consistent with
  49289. hardware manual.
  49290. +Optional properties:
  49291. +- hp-det-gpios : The gpio pin to detect plug in/out event that happens to
  49292. + Headphone jack.
  49293. +- mic-det-gpios: The gpio pin to detect plug in/out event that happens to
  49294. + Microphone jack.
  49295. +
  49296. Example:
  49297. sound {
  49298. @@ -43,4 +49,6 @@
  49299. "DMICDAT", "DMIC";
  49300. mux-int-port = <2>;
  49301. mux-ext-port = <3>;
  49302. + hp-det-gpios = <&gpio7 8 1>;
  49303. + mic-det-gpios = <&gpio1 9 1>;
  49304. };
  49305. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/sound/wm8962.txt linux-imx6-3.14/Documentation/devicetree/bindings/sound/wm8962.txt
  49306. --- linux-3.14.14/Documentation/devicetree/bindings/sound/wm8962.txt 2014-07-28 10:07:25.000000000 -0500
  49307. +++ linux-imx6-3.14/Documentation/devicetree/bindings/sound/wm8962.txt 2014-12-08 00:31:50.948418001 -0600
  49308. @@ -13,6 +13,14 @@
  49309. of R51 (Class D Control 2) gets set, indicating that the speaker is
  49310. in mono mode.
  49311. + - amic-mono: This is a boolean property. If present, indicating that the
  49312. + analog micphone is hardware mono input, the driver would enable monomix
  49313. + for it.
  49314. +
  49315. + - dmic-mono: This is a boolean property. If present, indicating that the
  49316. + digital micphone is hardware mono input, the driver would enable monomix
  49317. + for it.
  49318. +
  49319. - mic-cfg : Default register value for R48 (Additional Control 4).
  49320. If absent, the default should be the register default.
  49321. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/usb/mxs-phy.txt linux-imx6-3.14/Documentation/devicetree/bindings/usb/mxs-phy.txt
  49322. --- linux-3.14.14/Documentation/devicetree/bindings/usb/mxs-phy.txt 2014-07-28 10:07:25.000000000 -0500
  49323. +++ linux-imx6-3.14/Documentation/devicetree/bindings/usb/mxs-phy.txt 2014-12-08 00:31:50.952418001 -0600
  49324. @@ -1,13 +1,16 @@
  49325. * Freescale MXS USB Phy Device
  49326. Required properties:
  49327. -- compatible: Should be "fsl,imx23-usbphy"
  49328. +- compatible: "fsl,imx23-usbphy" for imx23 and imx28, "fsl,imx6q-usbphy"
  49329. +for imx6dq and imx6dl, "fsl,imx6sl-usbphy" for imx6sl
  49330. - reg: Should contain registers location and length
  49331. - interrupts: Should contain phy interrupt
  49332. +- fsl,anatop: phandle for anatop register, it is only for imx6 SoC series
  49333. Example:
  49334. usbphy1: usbphy@020c9000 {
  49335. compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
  49336. reg = <0x020c9000 0x1000>;
  49337. interrupts = <0 44 0x04>;
  49338. + fsl,anatop = <&anatop>;
  49339. };
  49340. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt
  49341. --- linux-3.14.14/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt 1969-12-31 18:00:00.000000000 -0600
  49342. +++ linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt 2014-12-08 00:31:50.952418001 -0600
  49343. @@ -0,0 +1,61 @@
  49344. +* Freescale CMOS Sensor Interface (CSI) V4L2 Capture
  49345. +
  49346. +Required properties for CSI
  49347. +- compatible: "fsl,<soc>-csi". Supported chip includes imx6sl
  49348. +- reg: Address and length of the register set for CSI
  49349. +- interrupts: Should contain CSI interrupts
  49350. +
  49351. +Required properties for v4l2_capture
  49352. +- compatible: should be "fsl,<soc>-csi-v4l2", supported socs include imx6sl
  49353. +
  49354. +Required properties for sensor
  49355. +- compatible: "<vendor>,<sensor>"
  49356. + please check the supported sensor in the Supported Sensor fields.
  49357. +- reg: sensor I2C slave address
  49358. +- pinctrl-names: should be "default" for parallel sensor
  49359. +- pinctrl-0: should depend on the connection between sensor and i.MX
  49360. + connection between sensor and i.MX could be only legacy parallel on i.MX6SL
  49361. +- clocks: should be the clock source provided to sensor.
  49362. +- clock-names: should be "csi_mclk"
  49363. +- AVDD-supply: set according to the board.
  49364. +- DVDD-supply: set according to the board.
  49365. +- pwn-gpios: set according to the board.
  49366. +- rst-gpios: set according to the board.
  49367. +- csi_id: csi id for v4l2 capture device
  49368. + should be 0 for i.MX6SL
  49369. +- mclk: should the value of mclk clock send out the sensor. unit is Hz.
  49370. +- mclk_source: should be 0 for i.MX6SL
  49371. +
  49372. +Supported Sensor
  49373. +- ovti, ov5640
  49374. +
  49375. +Example for CSI:
  49376. + csi: csi@020e4000 {
  49377. + compatible = "fsl,imx6sl-csi";
  49378. + reg = <0x020e4000 0x4000>;
  49379. + interrupts = <0 7 0x04>;
  49380. + status = "disabled";
  49381. + };
  49382. +
  49383. +Examples for v4l2_capture:
  49384. + csi_v4l2_cap {
  49385. + compatible = "fsl,imx6q-v4l2-capture";
  49386. + status = "okay";
  49387. + };
  49388. +
  49389. +Examples for sensors:
  49390. + ov564x: ov564x@3c {
  49391. + compatible = "ovti,ov564x";
  49392. + reg = <0x3c>;
  49393. + pinctrl-names = "default";
  49394. + pinctrl-0 = <&pinctrl_csi_0>;
  49395. + clocks = <&clks IMX6SL_CLK_CSI>;
  49396. + clock-names = "csi_mclk";
  49397. + AVDD-supply = <&vgen6_reg>; /* 2.8v */
  49398. + DVDD-supply = <&vgen2_reg>; /* 1.5v*/
  49399. + pwn-gpios = <&gpio1 25 1>;
  49400. + rst-gpios = <&gpio1 26 0>;
  49401. + csi_id = <0>;
  49402. + mclk = <24000000>;
  49403. + mclk_source = <0>;
  49404. + };
  49405. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt
  49406. --- linux-3.14.14/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt 1969-12-31 18:00:00.000000000 -0600
  49407. +++ linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt 2014-12-08 00:31:50.952418001 -0600
  49408. @@ -0,0 +1,42 @@
  49409. +* Freescale MIPI CSI2 Controller for i.MX6DQ/i.MX6SDL
  49410. +
  49411. +Required properties for mipi csi2 controller:
  49412. +- compatible: should be "fsl,imx6q-mipi-csi2"
  49413. +- reg: <base addr, range> contains mipi csi2 register base address and range
  49414. +- interrupts: <type num flag> where type is a interrupt type, num is the
  49415. + interrupt number and flag is a field that level/trigger information for
  49416. + the interrupt.
  49417. +- clocks: the clock sources that mipi csi2 depends on.
  49418. +- clock-names: the name is related to the clock source one by one.
  49419. +- status: should be set to "disable".
  49420. +
  49421. +Required properties for mipi csi2 on specified board:
  49422. +- ipu_id: ipu id which mipi csi2 connected to.
  49423. + should be 0 or 1 for i.MX6DQ; should be 0 for i.MX6SDL
  49424. +- csi_id: csi id which mipi csi2 connected to.
  49425. + should be 0 or 1 for i.MX6DQ/i.MX6SDL
  49426. +- v_channel: virtual channel which send to MIPI CSI2 controller
  49427. + should keep consistent with the input MIPI signal.
  49428. +- lanes: data lanes of input MIPI signal. The maximum data lanes is 4.
  49429. + should keep consistent with the input MIPI signal.
  49430. +- status: should be set to "okay".
  49431. +
  49432. +Examples:
  49433. +for SOC imx6qdl.dtsi:
  49434. + mipi_csi@021dc000 {
  49435. + compatible = "fsl,imx6q-mipi-csi2";
  49436. + reg = <0x021dc000 0x4000>;
  49437. + interrupts = <0 100 0x04>, <0 101 0x04>;
  49438. + clocks = <&clks 138>, <&clks 53>, <&clks 204>;
  49439. + clock-names = "dphy_clk", "pixel_clk", "cfg_clk";
  49440. + status = "disabled";
  49441. + };
  49442. +
  49443. +for board imx6qdl-sabresd.dtsi:
  49444. + mipi_csi@021dc000 {
  49445. + status = "okay";
  49446. + ipu_id = <0>;
  49447. + csi_id = <1>;
  49448. + v_channel = <0>;
  49449. + lanes = <2>;
  49450. + };
  49451. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/video/fsl,pxp.txt linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,pxp.txt
  49452. --- linux-3.14.14/Documentation/devicetree/bindings/video/fsl,pxp.txt 1969-12-31 18:00:00.000000000 -0600
  49453. +++ linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,pxp.txt 2014-12-08 00:31:50.952418001 -0600
  49454. @@ -0,0 +1,30 @@
  49455. +* Freescale PxP Controller for i.MX6DL, i.MX6SL
  49456. +
  49457. +Required properties for PxP controller:
  49458. +- compatible: should be "fsl,<soc>-pxp-dma"
  49459. +- reg: <base addr, range> contains pxp register base address and range
  49460. +- interrupts: <type num flag> where type is an interrupt type, num is the
  49461. + interrupt number and flag is a field that level/trigger information for
  49462. + the interrupt.
  49463. +- clocks: the clock sources that pxp depends on.
  49464. +- clock-names: the name is related to the clock source
  49465. +
  49466. +Required properties for pxp on specified board:
  49467. +- status: should be set to "okay" if want to use PxP
  49468. +
  49469. +Examples:
  49470. +for SOC imx6dl.dtsi:
  49471. + pxp@020f0000 {
  49472. + compatible = "fsl,imx6dl-pxp-dma";
  49473. + reg = <0x020f0000 0x4000>;
  49474. + interrupts = <0 98 0x04>;
  49475. + clocks = <&clks 133>;
  49476. + clock-names = "pxp-axi";
  49477. + status = "disabled";
  49478. + };
  49479. +
  49480. +
  49481. +for board imx6dl-sabresd.dts:
  49482. + &pxp {
  49483. + status = "okay";
  49484. + };
  49485. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt
  49486. --- linux-3.14.14/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt 1969-12-31 18:00:00.000000000 -0600
  49487. +++ linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt 2014-12-08 00:31:50.952418001 -0600
  49488. @@ -0,0 +1,102 @@
  49489. +* Freescale V4L2 Capture for i.MX6DQ/i.MX6SDL
  49490. +
  49491. +Required board properties for IPUv3 capture:
  49492. +- clocks: should include the clock provided by i.MX6 to sensor
  49493. +- clock-names: sensor clock's name should be "ipux_csiy"
  49494. + x should be 1 or 2 for i.MX6DQ; should be 1 for i.MX6SDL
  49495. + y is 0 or 1 for i.MX6DQ/i.MX6SDL
  49496. +Note: other detailed information for IPUv3, please refer to
  49497. +Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt
  49498. +
  49499. +Required properties for v4l2_capture
  49500. +- compatible: should be "fsl,imx6q-v4l2-capture"
  49501. +- ipu_id: ipu id for v4l2 capture device
  49502. + should be 0 or 1 for i.MX6DQ; should be 0 for i.MX6SDL
  49503. +- csi_id: csi id for v4l2 capture device
  49504. + should be 0 or 1 for i.MX6DQ/i.MX6SDL
  49505. +- mclk_source: should be 0 or 1. two mclk sources at most now
  49506. +- status: should be set to "okay" to enable this device
  49507. +
  49508. +Required properties for sensor
  49509. +- compatible: "<vendor>,<sensor>"
  49510. + please check the supported sensor in the Supported Sensor fields.
  49511. +- reg: sensor I2C slave address
  49512. +- pinctrl-names: should be "default" for parallel sensor
  49513. +- pinctrl-0: should depend on the connection between sensor and i.MX
  49514. + connection between sensor and i.MX could be MIPI-CSI2 or legacy parallel
  49515. +- clocks: should be the clock source provided to sensor.
  49516. +- clock-names: should be "csi_mclk"
  49517. +- DOVDD-supply: set according to the board.
  49518. +- AVDD-supply: set according to the board.
  49519. +- DVDD-supply: set according to the board.
  49520. +- pwn-gpios: set according to the board.
  49521. +- rst-gpios: set according to the board.
  49522. +- csi_id: csi id for v4l2 capture device
  49523. + should be 0 or 1 for i.MX6DQ/i.MX6SDL.
  49524. +- mclk: should the value of mclk clock send out the sensor. unit is Hz.
  49525. +- mclk_source: should be 0 or 1 and should be the same as the setting in
  49526. + v4l2_capture.
  49527. +- cvbs: 1 for CVBS input, 0 YPbPr input. This property is only needed for
  49528. + adv7180 tv decoder.
  49529. +
  49530. +Supported Sensor
  49531. +- ov5640
  49532. +- ov5642
  49533. +- ov5640_mipi
  49534. +- adv7180
  49535. +
  49536. +
  49537. +Example for IPUv3 including capture settings on imx6q-sabresd.dts:
  49538. + ipu1: ipu@02400000 { /* IPU1 */
  49539. + compatible = "fsl,imx6q-ipuv3";
  49540. + reg = <0x02400000 0x400000>;
  49541. + interrupts = <0 5 0x04>, < 0 6 0x04>;
  49542. + clocks = <&clks 130>, <&clks 131>, <&clks 132>, <&clks 39>, <&clks 40>, <&clks 169>;
  49543. + clock-names = "ipu1", "ipu1_di0", "ipu1_di1", "ipu1_di0_sel", "ipu1_di1_sel", "ipu1_csi0";
  49544. + status = "disabled";
  49545. + };
  49546. +
  49547. +Examples for v4l2_capture:
  49548. + v4l2_cap {
  49549. + compatible = "fsl,imx6q-v4l2-capture";
  49550. + ipu_id = <0>;
  49551. + csi_id = <0>;
  49552. + mclk_source = <0>;
  49553. + status = "okay";
  49554. + };
  49555. +
  49556. +Examples for sensors:
  49557. + ov5642: ov5642@3c {
  49558. + compatible = "ovti,ov5642";
  49559. + reg = <0x3c>;
  49560. + pinctrl-names = "default";
  49561. + pinctrl-0 = <&pinctrl_ipu1_2>;
  49562. + clocks = <&clks 201>;
  49563. + clock-names = "csi_mclk";
  49564. + DOVDD-supply = <&vgen4_reg>; /* 1.8v */
  49565. + AVDD-supply = <&vgen3_reg>; /* 2.8v, on rev C board is VGEN3 */
  49566. + DVDD-supply = <&vgen2_reg>; /* 1.5v*/
  49567. + pwn-gpios = <&gpio1 16 1>; /* active low: SD1_DAT0 */
  49568. + rst-gpios = <&gpio1 17 0>; /* active high: SD1_DAT1 */
  49569. + csi_id = <0>;
  49570. + mclk = <24000000>;
  49571. + mclk_source = <0>;
  49572. + };
  49573. +
  49574. + adv7180: adv7180@21 {
  49575. + compatible = "adv,adv7180";
  49576. + reg = <0x21>;
  49577. + pinctrl-names = "default";
  49578. + pinctrl-0 = <&pinctrl_ipu1_3>;
  49579. + clocks = <&clks 201>;
  49580. + clock-names = "csi_mclk";
  49581. + DOVDD-supply = <&reg_3p3v>; /* 3.3v, enabled via 2.8 VGEN6 */
  49582. + AVDD-supply = <&reg_3p3v>; /* 1.8v */
  49583. + DVDD-supply = <&reg_3p3v>; /* 1.8v */
  49584. + PVDD-supply = <&reg_3p3v>; /* 1.8v */
  49585. + pwn-gpios = <&max7310_b 2 0>;
  49586. + csi_id = <0>;
  49587. + mclk = <24000000>;
  49588. + mclk_source = <0>;
  49589. + cvbs = <1>;
  49590. + };
  49591. diff -Nur linux-3.14.14/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt linux-imx6-3.14/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt
  49592. --- linux-3.14.14/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt 1969-12-31 18:00:00.000000000 -0600
  49593. +++ linux-imx6-3.14/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt 2014-12-08 00:31:50.952418001 -0600
  49594. @@ -0,0 +1,20 @@
  49595. +Device-Tree bindings for hdmi video driver
  49596. +
  49597. +Required properties:
  49598. +- compatible: value should be "fsl,imx6q-hdmi-video".
  49599. +- fsl,hdcp: define the property in dts, hdmi driver will initalize for hdcp,
  49600. + otherwise hdcp function will not supported.
  49601. +- fsl,phy_reg_vlev: hdmi phy register,Voltage Level Control Register offset 0x0e,
  49602. + adjust hdmi phy signal voltage level.
  49603. +- fsl,phy_reg_cksymtx: hdmi phy register, clock symbol and transmitter control
  49604. + register offset 0x09, adjust hdmi signal pre-emphasis.
  49605. +
  49606. +Example:
  49607. +
  49608. + hdmi_video {
  49609. + compatible = "fsl,imx6q-hdmi-video";
  49610. + fsl,hdcp;
  49611. + fsl,phy_reg_vlev = <0x0294>;
  49612. + fsl,phy_reg_cksymtx = <0x800d>;
  49613. + };
  49614. +
  49615. diff -Nur linux-3.14.14/Documentation/filesystems/hfsplus.txt linux-imx6-3.14/Documentation/filesystems/hfsplus.txt
  49616. --- linux-3.14.14/Documentation/filesystems/hfsplus.txt 2014-07-28 10:07:25.000000000 -0500
  49617. +++ linux-imx6-3.14/Documentation/filesystems/hfsplus.txt 2014-12-08 00:31:50.968418001 -0600
  49618. @@ -56,4 +56,4 @@
  49619. kernel source: <file:fs/hfsplus>
  49620. -Apple Technote 1150 http://developer.apple.com/technotes/tn/tn1150.html
  49621. +Apple Technote 1150 https://developer.apple.com/legacy/library/technotes/tn/tn1150.html
  49622. diff -Nur linux-3.14.14/Documentation/kernel-parameters.txt linux-imx6-3.14/Documentation/kernel-parameters.txt
  49623. --- linux-3.14.14/Documentation/kernel-parameters.txt 2014-07-28 10:07:25.000000000 -0500
  49624. +++ linux-imx6-3.14/Documentation/kernel-parameters.txt 2014-12-08 00:31:50.996418001 -0600
  49625. @@ -603,8 +603,11 @@
  49626. Also note the kernel might malfunction if you disable
  49627. some critical bits.
  49628. - cma=nn[MG] [ARM,KNL]
  49629. - Sets the size of kernel global memory area for contiguous
  49630. + cma=nn[MG]@[start[MG][-end[MG]]]
  49631. + [ARM,X86,KNL]
  49632. + Sets the size of kernel global memory area for
  49633. + contiguous memory allocations and optionally the
  49634. + placement constraint by the physical address range of
  49635. memory allocations. For more information, see
  49636. include/linux/dma-contiguous.h
  49637. diff -Nur linux-3.14.14/Documentation/networking/gianfar.txt linux-imx6-3.14/Documentation/networking/gianfar.txt
  49638. --- linux-3.14.14/Documentation/networking/gianfar.txt 2014-07-28 10:07:25.000000000 -0500
  49639. +++ linux-imx6-3.14/Documentation/networking/gianfar.txt 2014-12-08 00:31:51.008418001 -0600
  49640. @@ -1,38 +1,8 @@
  49641. The Gianfar Ethernet Driver
  49642. -Sysfs File description
  49643. Author: Andy Fleming <afleming@freescale.com>
  49644. Updated: 2005-07-28
  49645. -SYSFS
  49646. -
  49647. -Several of the features of the gianfar driver are controlled
  49648. -through sysfs files. These are:
  49649. -
  49650. -bd_stash:
  49651. -To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
  49652. -bd_stash, echo 'off' or '0' to disable
  49653. -
  49654. -rx_stash_len:
  49655. -To stash the first n bytes of the packet in L2, echo the number
  49656. -of bytes to buf_stash_len. echo 0 to disable.
  49657. -
  49658. -WARNING: You could really screw these up if you set them too low or high!
  49659. -fifo_threshold:
  49660. -To change the number of bytes the controller needs in the
  49661. -fifo before it starts transmission, echo the number of bytes to
  49662. -fifo_thresh. Range should be 0-511.
  49663. -
  49664. -fifo_starve:
  49665. -When the FIFO has less than this many bytes during a transmit, it
  49666. -enters starve mode, and increases the priority of TX memory
  49667. -transactions. To change, echo the number of bytes to
  49668. -fifo_starve. Range should be 0-511.
  49669. -
  49670. -fifo_starve_off:
  49671. -Once in starve mode, the FIFO remains there until it has this
  49672. -many bytes. To change, echo the number of bytes to
  49673. -fifo_starve_off. Range should be 0-511.
  49674. CHECKSUM OFFLOADING
  49675. diff -Nur linux-3.14.14/drivers/ata/acard-ahci.c linux-imx6-3.14/drivers/ata/acard-ahci.c
  49676. --- linux-3.14.14/drivers/ata/acard-ahci.c 2014-07-28 10:07:25.000000000 -0500
  49677. +++ linux-imx6-3.14/drivers/ata/acard-ahci.c 2014-12-08 00:31:52.424418001 -0600
  49678. @@ -36,7 +36,6 @@
  49679. #include <linux/kernel.h>
  49680. #include <linux/module.h>
  49681. #include <linux/pci.h>
  49682. -#include <linux/init.h>
  49683. #include <linux/blkdev.h>
  49684. #include <linux/delay.h>
  49685. #include <linux/interrupt.h>
  49686. diff -Nur linux-3.14.14/drivers/ata/ahci.c linux-imx6-3.14/drivers/ata/ahci.c
  49687. --- linux-3.14.14/drivers/ata/ahci.c 2014-07-28 10:07:25.000000000 -0500
  49688. +++ linux-imx6-3.14/drivers/ata/ahci.c 2014-12-08 00:31:52.424418001 -0600
  49689. @@ -35,7 +35,6 @@
  49690. #include <linux/kernel.h>
  49691. #include <linux/module.h>
  49692. #include <linux/pci.h>
  49693. -#include <linux/init.h>
  49694. #include <linux/blkdev.h>
  49695. #include <linux/delay.h>
  49696. #include <linux/interrupt.h>
  49697. @@ -582,6 +581,7 @@
  49698. unsigned long deadline)
  49699. {
  49700. struct ata_port *ap = link->ap;
  49701. + struct ahci_host_priv *hpriv = ap->host->private_data;
  49702. bool online;
  49703. int rc;
  49704. @@ -592,7 +592,7 @@
  49705. rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
  49706. deadline, &online, NULL);
  49707. - ahci_start_engine(ap);
  49708. + hpriv->start_engine(ap);
  49709. DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
  49710. @@ -607,6 +607,7 @@
  49711. {
  49712. struct ata_port *ap = link->ap;
  49713. struct ahci_port_priv *pp = ap->private_data;
  49714. + struct ahci_host_priv *hpriv = ap->host->private_data;
  49715. u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
  49716. struct ata_taskfile tf;
  49717. bool online;
  49718. @@ -622,7 +623,7 @@
  49719. rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
  49720. deadline, &online, NULL);
  49721. - ahci_start_engine(ap);
  49722. + hpriv->start_engine(ap);
  49723. /* The pseudo configuration device on SIMG4726 attached to
  49724. * ASUS P5W-DH Deluxe doesn't send signature FIS after
  49725. @@ -1118,6 +1119,17 @@
  49726. return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
  49727. }
  49728. +static bool ahci_broken_devslp(struct pci_dev *pdev)
  49729. +{
  49730. + /* device with broken DEVSLP but still showing SDS capability */
  49731. + static const struct pci_device_id ids[] = {
  49732. + { PCI_VDEVICE(INTEL, 0x0f23)}, /* Valleyview SoC */
  49733. + {}
  49734. + };
  49735. +
  49736. + return pci_match_id(ids, pdev);
  49737. +}
  49738. +
  49739. #ifdef CONFIG_ATA_ACPI
  49740. static void ahci_gtf_filter_workaround(struct ata_host *host)
  49741. {
  49742. @@ -1369,6 +1381,10 @@
  49743. hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar];
  49744. + /* must set flag prior to save config in order to take effect */
  49745. + if (ahci_broken_devslp(pdev))
  49746. + hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
  49747. +
  49748. /* save initial config */
  49749. ahci_pci_save_initial_config(pdev, hpriv);
  49750. diff -Nur linux-3.14.14/drivers/ata/ahci.h linux-imx6-3.14/drivers/ata/ahci.h
  49751. --- linux-3.14.14/drivers/ata/ahci.h 2014-07-28 10:07:25.000000000 -0500
  49752. +++ linux-imx6-3.14/drivers/ata/ahci.h 2014-12-08 00:31:52.424418001 -0600
  49753. @@ -37,6 +37,8 @@
  49754. #include <linux/clk.h>
  49755. #include <linux/libata.h>
  49756. +#include <linux/phy/phy.h>
  49757. +#include <linux/regulator/consumer.h>
  49758. /* Enclosure Management Control */
  49759. #define EM_CTRL_MSG_TYPE 0x000f0000
  49760. @@ -51,6 +53,7 @@
  49761. enum {
  49762. AHCI_MAX_PORTS = 32,
  49763. + AHCI_MAX_CLKS = 3,
  49764. AHCI_MAX_SG = 168, /* hardware max is 64K */
  49765. AHCI_DMA_BOUNDARY = 0xffffffff,
  49766. AHCI_MAX_CMDS = 32,
  49767. @@ -233,6 +236,8 @@
  49768. port start (wait until
  49769. error-handling stage) */
  49770. AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */
  49771. + AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */
  49772. + AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */
  49773. /* ap->flags bits */
  49774. @@ -322,8 +327,17 @@
  49775. u32 em_loc; /* enclosure management location */
  49776. u32 em_buf_sz; /* EM buffer size in byte */
  49777. u32 em_msg_type; /* EM message type */
  49778. - struct clk *clk; /* Only for platforms supporting clk */
  49779. + bool got_runtime_pm; /* Did we do pm_runtime_get? */
  49780. + struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
  49781. + struct regulator *target_pwr; /* Optional */
  49782. + struct phy *phy; /* If platform uses phy */
  49783. void *plat_data; /* Other platform data */
  49784. + /*
  49785. + * Optional ahci_start_engine override, if not set this gets set to the
  49786. + * default ahci_start_engine during ahci_save_initial_config, this can
  49787. + * be overridden anytime before the host is activated.
  49788. + */
  49789. + void (*start_engine)(struct ata_port *ap);
  49790. };
  49791. extern int ahci_ignore_sss;
  49792. diff -Nur linux-3.14.14/drivers/ata/ahci_imx.c linux-imx6-3.14/drivers/ata/ahci_imx.c
  49793. --- linux-3.14.14/drivers/ata/ahci_imx.c 2014-07-28 10:07:25.000000000 -0500
  49794. +++ linux-imx6-3.14/drivers/ata/ahci_imx.c 2014-12-08 00:31:52.428418001 -0600
  49795. @@ -26,12 +26,29 @@
  49796. #include <linux/mfd/syscon.h>
  49797. #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  49798. #include <linux/libata.h>
  49799. +#include <linux/busfreq-imx6.h>
  49800. #include "ahci.h"
  49801. enum {
  49802. - PORT_PHY_CTL = 0x178, /* Port0 PHY Control */
  49803. - PORT_PHY_CTL_PDDQ_LOC = 0x100000, /* PORT_PHY_CTL bits */
  49804. - HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
  49805. + /* Timer 1-ms Register */
  49806. + IMX_TIMER1MS = 0x00e0,
  49807. + /* Port0 PHY Control Register */
  49808. + IMX_P0PHYCR = 0x0178,
  49809. + IMX_P0PHYCR_TEST_PDDQ = 1 << 20,
  49810. + IMX_P0PHYCR_CR_READ = 1 << 19,
  49811. + IMX_P0PHYCR_CR_WRITE = 1 << 18,
  49812. + IMX_P0PHYCR_CR_CAP_DATA = 1 << 17,
  49813. + IMX_P0PHYCR_CR_CAP_ADDR = 1 << 16,
  49814. + /* Port0 PHY Status Register */
  49815. + IMX_P0PHYSR = 0x017c,
  49816. + IMX_P0PHYSR_CR_ACK = 1 << 18,
  49817. + IMX_P0PHYSR_CR_DATA_OUT = 0xffff << 0,
  49818. + /* Lane0 Output Status Register */
  49819. + IMX_LANE0_OUT_STAT = 0x2003,
  49820. + IMX_LANE0_OUT_STAT_RX_PLL_STATE = 1 << 1,
  49821. + /* Clock Reset Register */
  49822. + IMX_CLOCK_RESET = 0x7f3f,
  49823. + IMX_CLOCK_RESET_RESET = 1 << 0,
  49824. };
  49825. enum ahci_imx_type {
  49826. @@ -42,62 +59,230 @@
  49827. struct imx_ahci_priv {
  49828. struct platform_device *ahci_pdev;
  49829. enum ahci_imx_type type;
  49830. -
  49831. - /* i.MX53 clock */
  49832. - struct clk *sata_gate_clk;
  49833. - /* Common clock */
  49834. - struct clk *sata_ref_clk;
  49835. struct clk *ahb_clk;
  49836. -
  49837. struct regmap *gpr;
  49838. bool no_device;
  49839. bool first_time;
  49840. + u32 phy_params;
  49841. };
  49842. static int ahci_imx_hotplug;
  49843. module_param_named(hotplug, ahci_imx_hotplug, int, 0644);
  49844. MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)");
  49845. -static int imx_sata_clock_enable(struct device *dev)
  49846. +static void ahci_imx_host_stop(struct ata_host *host);
  49847. +
  49848. +static int imx_phy_crbit_assert(void __iomem *mmio, u32 bit, bool assert)
  49849. +{
  49850. + int timeout = 10;
  49851. + u32 crval;
  49852. + u32 srval;
  49853. +
  49854. + /* Assert or deassert the bit */
  49855. + crval = readl(mmio + IMX_P0PHYCR);
  49856. + if (assert)
  49857. + crval |= bit;
  49858. + else
  49859. + crval &= ~bit;
  49860. + writel(crval, mmio + IMX_P0PHYCR);
  49861. +
  49862. + /* Wait for the cr_ack signal */
  49863. + do {
  49864. + srval = readl(mmio + IMX_P0PHYSR);
  49865. + if ((assert ? srval : ~srval) & IMX_P0PHYSR_CR_ACK)
  49866. + break;
  49867. + usleep_range(100, 200);
  49868. + } while (--timeout);
  49869. +
  49870. + return timeout ? 0 : -ETIMEDOUT;
  49871. +}
  49872. +
  49873. +static int imx_phy_reg_addressing(u16 addr, void __iomem *mmio)
  49874. {
  49875. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  49876. + u32 crval = addr;
  49877. int ret;
  49878. - if (imxpriv->type == AHCI_IMX53) {
  49879. - ret = clk_prepare_enable(imxpriv->sata_gate_clk);
  49880. - if (ret < 0) {
  49881. - dev_err(dev, "prepare-enable sata_gate clock err:%d\n",
  49882. - ret);
  49883. - return ret;
  49884. - }
  49885. + /* Supply the address on cr_data_in */
  49886. + writel(crval, mmio + IMX_P0PHYCR);
  49887. +
  49888. + /* Assert the cr_cap_addr signal */
  49889. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, true);
  49890. + if (ret)
  49891. + return ret;
  49892. +
  49893. + /* Deassert cr_cap_addr */
  49894. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, false);
  49895. + if (ret)
  49896. + return ret;
  49897. +
  49898. + return 0;
  49899. +}
  49900. +
  49901. +static int imx_phy_reg_write(u16 val, void __iomem *mmio)
  49902. +{
  49903. + u32 crval = val;
  49904. + int ret;
  49905. +
  49906. + /* Supply the data on cr_data_in */
  49907. + writel(crval, mmio + IMX_P0PHYCR);
  49908. +
  49909. + /* Assert the cr_cap_data signal */
  49910. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, true);
  49911. + if (ret)
  49912. + return ret;
  49913. +
  49914. + /* Deassert cr_cap_data */
  49915. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, false);
  49916. + if (ret)
  49917. + return ret;
  49918. +
  49919. + if (val & IMX_CLOCK_RESET_RESET) {
  49920. + /*
  49921. + * In case we're resetting the phy, it's unable to acknowledge,
  49922. + * so we return immediately here.
  49923. + */
  49924. + crval |= IMX_P0PHYCR_CR_WRITE;
  49925. + writel(crval, mmio + IMX_P0PHYCR);
  49926. + goto out;
  49927. }
  49928. - ret = clk_prepare_enable(imxpriv->sata_ref_clk);
  49929. - if (ret < 0) {
  49930. - dev_err(dev, "prepare-enable sata_ref clock err:%d\n",
  49931. - ret);
  49932. - goto clk_err;
  49933. + /* Assert the cr_write signal */
  49934. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, true);
  49935. + if (ret)
  49936. + return ret;
  49937. +
  49938. + /* Deassert cr_write */
  49939. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, false);
  49940. + if (ret)
  49941. + return ret;
  49942. +
  49943. +out:
  49944. + return 0;
  49945. +}
  49946. +
  49947. +static int imx_phy_reg_read(u16 *val, void __iomem *mmio)
  49948. +{
  49949. + int ret;
  49950. +
  49951. + /* Assert the cr_read signal */
  49952. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, true);
  49953. + if (ret)
  49954. + return ret;
  49955. +
  49956. + /* Capture the data from cr_data_out[] */
  49957. + *val = readl(mmio + IMX_P0PHYSR) & IMX_P0PHYSR_CR_DATA_OUT;
  49958. +
  49959. + /* Deassert cr_read */
  49960. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, false);
  49961. + if (ret)
  49962. + return ret;
  49963. +
  49964. + return 0;
  49965. +}
  49966. +
  49967. +static int imx_sata_phy_reset(struct ahci_host_priv *hpriv)
  49968. +{
  49969. + void __iomem *mmio = hpriv->mmio;
  49970. + int timeout = 10;
  49971. + u16 val;
  49972. + int ret;
  49973. +
  49974. + /* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */
  49975. + ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio);
  49976. + if (ret)
  49977. + return ret;
  49978. + ret = imx_phy_reg_write(IMX_CLOCK_RESET_RESET, mmio);
  49979. + if (ret)
  49980. + return ret;
  49981. +
  49982. + /* Wait for PHY RX_PLL to be stable */
  49983. + do {
  49984. + usleep_range(100, 200);
  49985. + ret = imx_phy_reg_addressing(IMX_LANE0_OUT_STAT, mmio);
  49986. + if (ret)
  49987. + return ret;
  49988. + ret = imx_phy_reg_read(&val, mmio);
  49989. + if (ret)
  49990. + return ret;
  49991. + if (val & IMX_LANE0_OUT_STAT_RX_PLL_STATE)
  49992. + break;
  49993. + } while (--timeout);
  49994. +
  49995. + return timeout ? 0 : -ETIMEDOUT;
  49996. +}
  49997. +
  49998. +static int imx_sata_enable(struct ahci_host_priv *hpriv)
  49999. +{
  50000. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  50001. + struct device *dev = &imxpriv->ahci_pdev->dev;
  50002. + int ret;
  50003. +
  50004. + if (imxpriv->no_device)
  50005. + return 0;
  50006. +
  50007. + if (hpriv->target_pwr) {
  50008. + ret = regulator_enable(hpriv->target_pwr);
  50009. + if (ret)
  50010. + return ret;
  50011. }
  50012. + request_bus_freq(BUS_FREQ_HIGH);
  50013. +
  50014. + ret = ahci_platform_enable_clks(hpriv);
  50015. + if (ret < 0)
  50016. + goto disable_regulator;
  50017. +
  50018. if (imxpriv->type == AHCI_IMX6Q) {
  50019. + /*
  50020. + * set PHY Paremeters, two steps to configure the GPR13,
  50021. + * one write for rest of parameters, mask of first write
  50022. + * is 0x07ffffff, and the other one write for setting
  50023. + * the mpll_clk_en.
  50024. + */
  50025. + regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  50026. + IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK |
  50027. + IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK |
  50028. + IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK |
  50029. + IMX6Q_GPR13_SATA_SPD_MODE_MASK |
  50030. + IMX6Q_GPR13_SATA_MPLL_SS_EN |
  50031. + IMX6Q_GPR13_SATA_TX_ATTEN_MASK |
  50032. + IMX6Q_GPR13_SATA_TX_BOOST_MASK |
  50033. + IMX6Q_GPR13_SATA_TX_LVL_MASK |
  50034. + IMX6Q_GPR13_SATA_MPLL_CLK_EN |
  50035. + IMX6Q_GPR13_SATA_TX_EDGE_RATE,
  50036. + imxpriv->phy_params);
  50037. regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  50038. IMX6Q_GPR13_SATA_MPLL_CLK_EN,
  50039. IMX6Q_GPR13_SATA_MPLL_CLK_EN);
  50040. +
  50041. + usleep_range(100, 200);
  50042. +
  50043. + ret = imx_sata_phy_reset(hpriv);
  50044. + if (ret) {
  50045. + dev_err(dev, "failed to reset phy: %d\n", ret);
  50046. + goto disable_regulator;
  50047. + }
  50048. }
  50049. usleep_range(1000, 2000);
  50050. return 0;
  50051. -clk_err:
  50052. - if (imxpriv->type == AHCI_IMX53)
  50053. - clk_disable_unprepare(imxpriv->sata_gate_clk);
  50054. +disable_regulator:
  50055. + release_bus_freq(BUS_FREQ_HIGH);
  50056. +
  50057. + if (hpriv->target_pwr)
  50058. + regulator_disable(hpriv->target_pwr);
  50059. +
  50060. return ret;
  50061. }
  50062. -static void imx_sata_clock_disable(struct device *dev)
  50063. +static void imx_sata_disable(struct ahci_host_priv *hpriv)
  50064. {
  50065. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  50066. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  50067. +
  50068. + if (imxpriv->no_device)
  50069. + return;
  50070. if (imxpriv->type == AHCI_IMX6Q) {
  50071. regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  50072. @@ -105,10 +290,12 @@
  50073. !IMX6Q_GPR13_SATA_MPLL_CLK_EN);
  50074. }
  50075. - clk_disable_unprepare(imxpriv->sata_ref_clk);
  50076. + ahci_platform_disable_clks(hpriv);
  50077. - if (imxpriv->type == AHCI_IMX53)
  50078. - clk_disable_unprepare(imxpriv->sata_gate_clk);
  50079. + release_bus_freq(BUS_FREQ_HIGH);
  50080. +
  50081. + if (hpriv->target_pwr)
  50082. + regulator_disable(hpriv->target_pwr);
  50083. }
  50084. static void ahci_imx_error_handler(struct ata_port *ap)
  50085. @@ -118,7 +305,7 @@
  50086. struct ata_host *host = dev_get_drvdata(ap->dev);
  50087. struct ahci_host_priv *hpriv = host->private_data;
  50088. void __iomem *mmio = hpriv->mmio;
  50089. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent);
  50090. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  50091. ahci_error_handler(ap);
  50092. @@ -134,17 +321,23 @@
  50093. * without full reset once the pddq mode is enabled making it
  50094. * impossible to use as part of libata LPM.
  50095. */
  50096. - reg_val = readl(mmio + PORT_PHY_CTL);
  50097. - writel(reg_val | PORT_PHY_CTL_PDDQ_LOC, mmio + PORT_PHY_CTL);
  50098. - imx_sata_clock_disable(ap->dev);
  50099. + reg_val = readl(mmio + IMX_P0PHYCR);
  50100. + writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR);
  50101. + imx_sata_disable(hpriv);
  50102. imxpriv->no_device = true;
  50103. +
  50104. + dev_info(ap->dev, "no device found, disabling link.\n");
  50105. + dev_info(ap->dev, "pass " MODULE_PARAM_PREFIX
  50106. + ".hotplug=1 to enable hotplug\n");
  50107. }
  50108. static int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
  50109. unsigned long deadline)
  50110. {
  50111. struct ata_port *ap = link->ap;
  50112. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent);
  50113. + struct ata_host *host = dev_get_drvdata(ap->dev);
  50114. + struct ahci_host_priv *hpriv = host->private_data;
  50115. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  50116. int ret = -EIO;
  50117. if (imxpriv->type == AHCI_IMX53)
  50118. @@ -156,7 +349,8 @@
  50119. }
  50120. static struct ata_port_operations ahci_imx_ops = {
  50121. - .inherits = &ahci_platform_ops,
  50122. + .inherits = &ahci_ops,
  50123. + .host_stop = ahci_imx_host_stop,
  50124. .error_handler = ahci_imx_error_handler,
  50125. .softreset = ahci_imx_softreset,
  50126. };
  50127. @@ -168,234 +362,306 @@
  50128. .port_ops = &ahci_imx_ops,
  50129. };
  50130. -static int imx_sata_init(struct device *dev, void __iomem *mmio)
  50131. -{
  50132. - int ret = 0;
  50133. - unsigned int reg_val;
  50134. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  50135. -
  50136. - ret = imx_sata_clock_enable(dev);
  50137. - if (ret < 0)
  50138. - return ret;
  50139. +static const struct of_device_id imx_ahci_of_match[] = {
  50140. + { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
  50141. + { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
  50142. + {},
  50143. +};
  50144. +MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
  50145. - /*
  50146. - * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
  50147. - * and IP vendor specific register HOST_TIMER1MS.
  50148. - * Configure CAP_SSS (support stagered spin up).
  50149. - * Implement the port0.
  50150. - * Get the ahb clock rate, and configure the TIMER1MS register.
  50151. - */
  50152. - reg_val = readl(mmio + HOST_CAP);
  50153. - if (!(reg_val & HOST_CAP_SSS)) {
  50154. - reg_val |= HOST_CAP_SSS;
  50155. - writel(reg_val, mmio + HOST_CAP);
  50156. - }
  50157. - reg_val = readl(mmio + HOST_PORTS_IMPL);
  50158. - if (!(reg_val & 0x1)) {
  50159. - reg_val |= 0x1;
  50160. - writel(reg_val, mmio + HOST_PORTS_IMPL);
  50161. - }
  50162. +struct reg_value {
  50163. + u32 of_value;
  50164. + u32 reg_value;
  50165. +};
  50166. - reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
  50167. - writel(reg_val, mmio + HOST_TIMER1MS);
  50168. +struct reg_property {
  50169. + const char *name;
  50170. + const struct reg_value *values;
  50171. + size_t num_values;
  50172. + u32 def_value;
  50173. + u32 set_value;
  50174. +};
  50175. - return 0;
  50176. -}
  50177. +static const struct reg_value gpr13_tx_level[] = {
  50178. + { 937, IMX6Q_GPR13_SATA_TX_LVL_0_937_V },
  50179. + { 947, IMX6Q_GPR13_SATA_TX_LVL_0_947_V },
  50180. + { 957, IMX6Q_GPR13_SATA_TX_LVL_0_957_V },
  50181. + { 966, IMX6Q_GPR13_SATA_TX_LVL_0_966_V },
  50182. + { 976, IMX6Q_GPR13_SATA_TX_LVL_0_976_V },
  50183. + { 986, IMX6Q_GPR13_SATA_TX_LVL_0_986_V },
  50184. + { 996, IMX6Q_GPR13_SATA_TX_LVL_0_996_V },
  50185. + { 1005, IMX6Q_GPR13_SATA_TX_LVL_1_005_V },
  50186. + { 1015, IMX6Q_GPR13_SATA_TX_LVL_1_015_V },
  50187. + { 1025, IMX6Q_GPR13_SATA_TX_LVL_1_025_V },
  50188. + { 1035, IMX6Q_GPR13_SATA_TX_LVL_1_035_V },
  50189. + { 1045, IMX6Q_GPR13_SATA_TX_LVL_1_045_V },
  50190. + { 1054, IMX6Q_GPR13_SATA_TX_LVL_1_054_V },
  50191. + { 1064, IMX6Q_GPR13_SATA_TX_LVL_1_064_V },
  50192. + { 1074, IMX6Q_GPR13_SATA_TX_LVL_1_074_V },
  50193. + { 1084, IMX6Q_GPR13_SATA_TX_LVL_1_084_V },
  50194. + { 1094, IMX6Q_GPR13_SATA_TX_LVL_1_094_V },
  50195. + { 1104, IMX6Q_GPR13_SATA_TX_LVL_1_104_V },
  50196. + { 1113, IMX6Q_GPR13_SATA_TX_LVL_1_113_V },
  50197. + { 1123, IMX6Q_GPR13_SATA_TX_LVL_1_123_V },
  50198. + { 1133, IMX6Q_GPR13_SATA_TX_LVL_1_133_V },
  50199. + { 1143, IMX6Q_GPR13_SATA_TX_LVL_1_143_V },
  50200. + { 1152, IMX6Q_GPR13_SATA_TX_LVL_1_152_V },
  50201. + { 1162, IMX6Q_GPR13_SATA_TX_LVL_1_162_V },
  50202. + { 1172, IMX6Q_GPR13_SATA_TX_LVL_1_172_V },
  50203. + { 1182, IMX6Q_GPR13_SATA_TX_LVL_1_182_V },
  50204. + { 1191, IMX6Q_GPR13_SATA_TX_LVL_1_191_V },
  50205. + { 1201, IMX6Q_GPR13_SATA_TX_LVL_1_201_V },
  50206. + { 1211, IMX6Q_GPR13_SATA_TX_LVL_1_211_V },
  50207. + { 1221, IMX6Q_GPR13_SATA_TX_LVL_1_221_V },
  50208. + { 1230, IMX6Q_GPR13_SATA_TX_LVL_1_230_V },
  50209. + { 1240, IMX6Q_GPR13_SATA_TX_LVL_1_240_V }
  50210. +};
  50211. -static void imx_sata_exit(struct device *dev)
  50212. -{
  50213. - imx_sata_clock_disable(dev);
  50214. -}
  50215. +static const struct reg_value gpr13_tx_boost[] = {
  50216. + { 0, IMX6Q_GPR13_SATA_TX_BOOST_0_00_DB },
  50217. + { 370, IMX6Q_GPR13_SATA_TX_BOOST_0_37_DB },
  50218. + { 740, IMX6Q_GPR13_SATA_TX_BOOST_0_74_DB },
  50219. + { 1110, IMX6Q_GPR13_SATA_TX_BOOST_1_11_DB },
  50220. + { 1480, IMX6Q_GPR13_SATA_TX_BOOST_1_48_DB },
  50221. + { 1850, IMX6Q_GPR13_SATA_TX_BOOST_1_85_DB },
  50222. + { 2220, IMX6Q_GPR13_SATA_TX_BOOST_2_22_DB },
  50223. + { 2590, IMX6Q_GPR13_SATA_TX_BOOST_2_59_DB },
  50224. + { 2960, IMX6Q_GPR13_SATA_TX_BOOST_2_96_DB },
  50225. + { 3330, IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB },
  50226. + { 3700, IMX6Q_GPR13_SATA_TX_BOOST_3_70_DB },
  50227. + { 4070, IMX6Q_GPR13_SATA_TX_BOOST_4_07_DB },
  50228. + { 4440, IMX6Q_GPR13_SATA_TX_BOOST_4_44_DB },
  50229. + { 4810, IMX6Q_GPR13_SATA_TX_BOOST_4_81_DB },
  50230. + { 5280, IMX6Q_GPR13_SATA_TX_BOOST_5_28_DB },
  50231. + { 5750, IMX6Q_GPR13_SATA_TX_BOOST_5_75_DB }
  50232. +};
  50233. -static int imx_ahci_suspend(struct device *dev)
  50234. -{
  50235. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  50236. +static const struct reg_value gpr13_tx_atten[] = {
  50237. + { 8, IMX6Q_GPR13_SATA_TX_ATTEN_8_16 },
  50238. + { 9, IMX6Q_GPR13_SATA_TX_ATTEN_9_16 },
  50239. + { 10, IMX6Q_GPR13_SATA_TX_ATTEN_10_16 },
  50240. + { 12, IMX6Q_GPR13_SATA_TX_ATTEN_12_16 },
  50241. + { 14, IMX6Q_GPR13_SATA_TX_ATTEN_14_16 },
  50242. + { 16, IMX6Q_GPR13_SATA_TX_ATTEN_16_16 },
  50243. +};
  50244. - /*
  50245. - * If no_device is set, The CLKs had been gated off in the
  50246. - * initialization so don't do it again here.
  50247. - */
  50248. - if (!imxpriv->no_device)
  50249. - imx_sata_clock_disable(dev);
  50250. +static const struct reg_value gpr13_rx_eq[] = {
  50251. + { 500, IMX6Q_GPR13_SATA_RX_EQ_VAL_0_5_DB },
  50252. + { 1000, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_0_DB },
  50253. + { 1500, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_5_DB },
  50254. + { 2000, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_0_DB },
  50255. + { 2500, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_5_DB },
  50256. + { 3000, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB },
  50257. + { 3500, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_5_DB },
  50258. + { 4000, IMX6Q_GPR13_SATA_RX_EQ_VAL_4_0_DB },
  50259. +};
  50260. - return 0;
  50261. -}
  50262. +static const struct reg_property gpr13_props[] = {
  50263. + {
  50264. + .name = "fsl,transmit-level-mV",
  50265. + .values = gpr13_tx_level,
  50266. + .num_values = ARRAY_SIZE(gpr13_tx_level),
  50267. + .def_value = IMX6Q_GPR13_SATA_TX_LVL_1_025_V,
  50268. + }, {
  50269. + .name = "fsl,transmit-boost-mdB",
  50270. + .values = gpr13_tx_boost,
  50271. + .num_values = ARRAY_SIZE(gpr13_tx_boost),
  50272. + .def_value = IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB,
  50273. + }, {
  50274. + .name = "fsl,transmit-atten-16ths",
  50275. + .values = gpr13_tx_atten,
  50276. + .num_values = ARRAY_SIZE(gpr13_tx_atten),
  50277. + .def_value = IMX6Q_GPR13_SATA_TX_ATTEN_9_16,
  50278. + }, {
  50279. + .name = "fsl,receive-eq-mdB",
  50280. + .values = gpr13_rx_eq,
  50281. + .num_values = ARRAY_SIZE(gpr13_rx_eq),
  50282. + .def_value = IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB,
  50283. + }, {
  50284. + .name = "fsl,no-spread-spectrum",
  50285. + .def_value = IMX6Q_GPR13_SATA_MPLL_SS_EN,
  50286. + .set_value = 0,
  50287. + },
  50288. +};
  50289. -static int imx_ahci_resume(struct device *dev)
  50290. +static u32 imx_ahci_parse_props(struct device *dev,
  50291. + const struct reg_property *prop, size_t num)
  50292. {
  50293. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  50294. - int ret = 0;
  50295. -
  50296. - if (!imxpriv->no_device)
  50297. - ret = imx_sata_clock_enable(dev);
  50298. + struct device_node *np = dev->of_node;
  50299. + u32 reg_value = 0;
  50300. + int i, j;
  50301. +
  50302. + for (i = 0; i < num; i++, prop++) {
  50303. + u32 of_val;
  50304. +
  50305. + if (prop->num_values == 0) {
  50306. + if (of_property_read_bool(np, prop->name))
  50307. + reg_value |= prop->set_value;
  50308. + else
  50309. + reg_value |= prop->def_value;
  50310. + continue;
  50311. + }
  50312. - return ret;
  50313. -}
  50314. + if (of_property_read_u32(np, prop->name, &of_val)) {
  50315. + dev_info(dev, "%s not specified, using %08x\n",
  50316. + prop->name, prop->def_value);
  50317. + reg_value |= prop->def_value;
  50318. + continue;
  50319. + }
  50320. -static struct ahci_platform_data imx_sata_pdata = {
  50321. - .init = imx_sata_init,
  50322. - .exit = imx_sata_exit,
  50323. - .ata_port_info = &ahci_imx_port_info,
  50324. - .suspend = imx_ahci_suspend,
  50325. - .resume = imx_ahci_resume,
  50326. + for (j = 0; j < prop->num_values; j++) {
  50327. + if (prop->values[j].of_value == of_val) {
  50328. + dev_info(dev, "%s value %u, using %08x\n",
  50329. + prop->name, of_val, prop->values[j].reg_value);
  50330. + reg_value |= prop->values[j].reg_value;
  50331. + break;
  50332. + }
  50333. + }
  50334. -};
  50335. + if (j == prop->num_values) {
  50336. + dev_err(dev, "DT property %s is not a valid value\n",
  50337. + prop->name);
  50338. + reg_value |= prop->def_value;
  50339. + }
  50340. + }
  50341. -static const struct of_device_id imx_ahci_of_match[] = {
  50342. - { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
  50343. - { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
  50344. - {},
  50345. -};
  50346. -MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
  50347. + return reg_value;
  50348. +}
  50349. static int imx_ahci_probe(struct platform_device *pdev)
  50350. {
  50351. struct device *dev = &pdev->dev;
  50352. - struct resource *mem, *irq, res[2];
  50353. const struct of_device_id *of_id;
  50354. - enum ahci_imx_type type;
  50355. - const struct ahci_platform_data *pdata = NULL;
  50356. + struct ahci_host_priv *hpriv;
  50357. struct imx_ahci_priv *imxpriv;
  50358. - struct device *ahci_dev;
  50359. - struct platform_device *ahci_pdev;
  50360. + unsigned int reg_val;
  50361. int ret;
  50362. of_id = of_match_device(imx_ahci_of_match, dev);
  50363. if (!of_id)
  50364. return -EINVAL;
  50365. - type = (enum ahci_imx_type)of_id->data;
  50366. - pdata = &imx_sata_pdata;
  50367. -
  50368. imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
  50369. - if (!imxpriv) {
  50370. - dev_err(dev, "can't alloc ahci_host_priv\n");
  50371. + if (!imxpriv)
  50372. return -ENOMEM;
  50373. - }
  50374. -
  50375. - ahci_pdev = platform_device_alloc("ahci", -1);
  50376. - if (!ahci_pdev)
  50377. - return -ENODEV;
  50378. -
  50379. - ahci_dev = &ahci_pdev->dev;
  50380. - ahci_dev->parent = dev;
  50381. + imxpriv->ahci_pdev = pdev;
  50382. imxpriv->no_device = false;
  50383. imxpriv->first_time = true;
  50384. - imxpriv->type = type;
  50385. -
  50386. + imxpriv->type = (enum ahci_imx_type)of_id->data;
  50387. imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
  50388. if (IS_ERR(imxpriv->ahb_clk)) {
  50389. dev_err(dev, "can't get ahb clock.\n");
  50390. - ret = PTR_ERR(imxpriv->ahb_clk);
  50391. - goto err_out;
  50392. - }
  50393. -
  50394. - if (type == AHCI_IMX53) {
  50395. - imxpriv->sata_gate_clk = devm_clk_get(dev, "sata_gate");
  50396. - if (IS_ERR(imxpriv->sata_gate_clk)) {
  50397. - dev_err(dev, "can't get sata_gate clock.\n");
  50398. - ret = PTR_ERR(imxpriv->sata_gate_clk);
  50399. - goto err_out;
  50400. - }
  50401. - }
  50402. -
  50403. - imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
  50404. - if (IS_ERR(imxpriv->sata_ref_clk)) {
  50405. - dev_err(dev, "can't get sata_ref clock.\n");
  50406. - ret = PTR_ERR(imxpriv->sata_ref_clk);
  50407. - goto err_out;
  50408. + return PTR_ERR(imxpriv->ahb_clk);
  50409. }
  50410. - imxpriv->ahci_pdev = ahci_pdev;
  50411. - platform_set_drvdata(pdev, imxpriv);
  50412. -
  50413. - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  50414. - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  50415. - if (!mem || !irq) {
  50416. - dev_err(dev, "no mmio/irq resource\n");
  50417. - ret = -ENOMEM;
  50418. - goto err_out;
  50419. - }
  50420. -
  50421. - res[0] = *mem;
  50422. - res[1] = *irq;
  50423. -
  50424. - ahci_dev->coherent_dma_mask = DMA_BIT_MASK(32);
  50425. - ahci_dev->dma_mask = &ahci_dev->coherent_dma_mask;
  50426. - ahci_dev->of_node = dev->of_node;
  50427. + if (imxpriv->type == AHCI_IMX6Q) {
  50428. + u32 reg_value;
  50429. - if (type == AHCI_IMX6Q) {
  50430. imxpriv->gpr = syscon_regmap_lookup_by_compatible(
  50431. "fsl,imx6q-iomuxc-gpr");
  50432. if (IS_ERR(imxpriv->gpr)) {
  50433. dev_err(dev,
  50434. "failed to find fsl,imx6q-iomux-gpr regmap\n");
  50435. - ret = PTR_ERR(imxpriv->gpr);
  50436. - goto err_out;
  50437. + return PTR_ERR(imxpriv->gpr);
  50438. }
  50439. - /*
  50440. - * Set PHY Paremeters, two steps to configure the GPR13,
  50441. - * one write for rest of parameters, mask of first write
  50442. - * is 0x07fffffe, and the other one write for setting
  50443. - * the mpll_clk_en happens in imx_sata_clock_enable().
  50444. - */
  50445. - regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  50446. - IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK |
  50447. - IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK |
  50448. - IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK |
  50449. - IMX6Q_GPR13_SATA_SPD_MODE_MASK |
  50450. - IMX6Q_GPR13_SATA_MPLL_SS_EN |
  50451. - IMX6Q_GPR13_SATA_TX_ATTEN_MASK |
  50452. - IMX6Q_GPR13_SATA_TX_BOOST_MASK |
  50453. - IMX6Q_GPR13_SATA_TX_LVL_MASK |
  50454. - IMX6Q_GPR13_SATA_MPLL_CLK_EN |
  50455. - IMX6Q_GPR13_SATA_TX_EDGE_RATE,
  50456. - IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB |
  50457. + reg_value = imx_ahci_parse_props(dev, gpr13_props,
  50458. + ARRAY_SIZE(gpr13_props));
  50459. +
  50460. + imxpriv->phy_params =
  50461. IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
  50462. IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
  50463. IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
  50464. - IMX6Q_GPR13_SATA_MPLL_SS_EN |
  50465. - IMX6Q_GPR13_SATA_TX_ATTEN_9_16 |
  50466. - IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB |
  50467. - IMX6Q_GPR13_SATA_TX_LVL_1_025_V);
  50468. + reg_value;
  50469. }
  50470. - ret = platform_device_add_resources(ahci_pdev, res, 2);
  50471. + hpriv = ahci_platform_get_resources(pdev);
  50472. + if (IS_ERR(hpriv))
  50473. + return PTR_ERR(hpriv);
  50474. +
  50475. + hpriv->plat_data = imxpriv;
  50476. +
  50477. + ret = imx_sata_enable(hpriv);
  50478. if (ret)
  50479. - goto err_out;
  50480. + return ret;
  50481. - ret = platform_device_add_data(ahci_pdev, pdata, sizeof(*pdata));
  50482. + /*
  50483. + * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
  50484. + * and IP vendor specific register IMX_TIMER1MS.
  50485. + * Configure CAP_SSS (support stagered spin up).
  50486. + * Implement the port0.
  50487. + * Get the ahb clock rate, and configure the TIMER1MS register.
  50488. + */
  50489. + reg_val = readl(hpriv->mmio + HOST_CAP);
  50490. + if (!(reg_val & HOST_CAP_SSS)) {
  50491. + reg_val |= HOST_CAP_SSS;
  50492. + writel(reg_val, hpriv->mmio + HOST_CAP);
  50493. + }
  50494. + reg_val = readl(hpriv->mmio + HOST_PORTS_IMPL);
  50495. + if (!(reg_val & 0x1)) {
  50496. + reg_val |= 0x1;
  50497. + writel(reg_val, hpriv->mmio + HOST_PORTS_IMPL);
  50498. + }
  50499. +
  50500. + reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
  50501. + writel(reg_val, hpriv->mmio + IMX_TIMER1MS);
  50502. +
  50503. + ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
  50504. + 0, 0, 0);
  50505. if (ret)
  50506. - goto err_out;
  50507. + imx_sata_disable(hpriv);
  50508. +
  50509. + return ret;
  50510. +}
  50511. - ret = platform_device_add(ahci_pdev);
  50512. - if (ret) {
  50513. -err_out:
  50514. - platform_device_put(ahci_pdev);
  50515. +static void ahci_imx_host_stop(struct ata_host *host)
  50516. +{
  50517. + struct ahci_host_priv *hpriv = host->private_data;
  50518. +
  50519. + imx_sata_disable(hpriv);
  50520. +}
  50521. +
  50522. +#ifdef CONFIG_PM_SLEEP
  50523. +static int imx_ahci_suspend(struct device *dev)
  50524. +{
  50525. + struct ata_host *host = dev_get_drvdata(dev);
  50526. + struct ahci_host_priv *hpriv = host->private_data;
  50527. + int ret;
  50528. +
  50529. + ret = ahci_platform_suspend_host(dev);
  50530. + if (ret)
  50531. return ret;
  50532. - }
  50533. +
  50534. + imx_sata_disable(hpriv);
  50535. return 0;
  50536. }
  50537. -static int imx_ahci_remove(struct platform_device *pdev)
  50538. +static int imx_ahci_resume(struct device *dev)
  50539. {
  50540. - struct imx_ahci_priv *imxpriv = platform_get_drvdata(pdev);
  50541. - struct platform_device *ahci_pdev = imxpriv->ahci_pdev;
  50542. + struct ata_host *host = dev_get_drvdata(dev);
  50543. + struct ahci_host_priv *hpriv = host->private_data;
  50544. + int ret;
  50545. - platform_device_unregister(ahci_pdev);
  50546. - return 0;
  50547. + ret = imx_sata_enable(hpriv);
  50548. + if (ret)
  50549. + return ret;
  50550. +
  50551. + return ahci_platform_resume_host(dev);
  50552. }
  50553. +#endif
  50554. +
  50555. +static SIMPLE_DEV_PM_OPS(ahci_imx_pm_ops, imx_ahci_suspend, imx_ahci_resume);
  50556. static struct platform_driver imx_ahci_driver = {
  50557. .probe = imx_ahci_probe,
  50558. - .remove = imx_ahci_remove,
  50559. + .remove = ata_platform_remove_one,
  50560. .driver = {
  50561. .name = "ahci-imx",
  50562. .owner = THIS_MODULE,
  50563. .of_match_table = imx_ahci_of_match,
  50564. + .pm = &ahci_imx_pm_ops,
  50565. },
  50566. };
  50567. module_platform_driver(imx_ahci_driver);
  50568. diff -Nur linux-3.14.14/drivers/ata/ahci_platform.c linux-imx6-3.14/drivers/ata/ahci_platform.c
  50569. --- linux-3.14.14/drivers/ata/ahci_platform.c 2014-07-28 10:07:25.000000000 -0500
  50570. +++ linux-imx6-3.14/drivers/ata/ahci_platform.c 2014-12-08 00:31:52.428418001 -0600
  50571. @@ -12,135 +12,36 @@
  50572. * any later version.
  50573. */
  50574. -#include <linux/clk.h>
  50575. #include <linux/kernel.h>
  50576. -#include <linux/gfp.h>
  50577. #include <linux/module.h>
  50578. #include <linux/pm.h>
  50579. -#include <linux/init.h>
  50580. -#include <linux/interrupt.h>
  50581. #include <linux/device.h>
  50582. #include <linux/platform_device.h>
  50583. #include <linux/libata.h>
  50584. #include <linux/ahci_platform.h>
  50585. #include "ahci.h"
  50586. -static void ahci_host_stop(struct ata_host *host);
  50587. -
  50588. -enum ahci_type {
  50589. - AHCI, /* standard platform ahci */
  50590. - IMX53_AHCI, /* ahci on i.mx53 */
  50591. - STRICT_AHCI, /* delayed DMA engine start */
  50592. -};
  50593. -
  50594. -static struct platform_device_id ahci_devtype[] = {
  50595. - {
  50596. - .name = "ahci",
  50597. - .driver_data = AHCI,
  50598. - }, {
  50599. - .name = "imx53-ahci",
  50600. - .driver_data = IMX53_AHCI,
  50601. - }, {
  50602. - .name = "strict-ahci",
  50603. - .driver_data = STRICT_AHCI,
  50604. - }, {
  50605. - /* sentinel */
  50606. - }
  50607. -};
  50608. -MODULE_DEVICE_TABLE(platform, ahci_devtype);
  50609. -
  50610. -struct ata_port_operations ahci_platform_ops = {
  50611. - .inherits = &ahci_ops,
  50612. - .host_stop = ahci_host_stop,
  50613. -};
  50614. -EXPORT_SYMBOL_GPL(ahci_platform_ops);
  50615. -
  50616. -static struct ata_port_operations ahci_platform_retry_srst_ops = {
  50617. - .inherits = &ahci_pmp_retry_srst_ops,
  50618. - .host_stop = ahci_host_stop,
  50619. -};
  50620. -
  50621. -static const struct ata_port_info ahci_port_info[] = {
  50622. - /* by features */
  50623. - [AHCI] = {
  50624. - .flags = AHCI_FLAG_COMMON,
  50625. - .pio_mask = ATA_PIO4,
  50626. - .udma_mask = ATA_UDMA6,
  50627. - .port_ops = &ahci_platform_ops,
  50628. - },
  50629. - [IMX53_AHCI] = {
  50630. - .flags = AHCI_FLAG_COMMON,
  50631. - .pio_mask = ATA_PIO4,
  50632. - .udma_mask = ATA_UDMA6,
  50633. - .port_ops = &ahci_platform_retry_srst_ops,
  50634. - },
  50635. - [STRICT_AHCI] = {
  50636. - AHCI_HFLAGS (AHCI_HFLAG_DELAY_ENGINE),
  50637. - .flags = AHCI_FLAG_COMMON,
  50638. - .pio_mask = ATA_PIO4,
  50639. - .udma_mask = ATA_UDMA6,
  50640. - .port_ops = &ahci_platform_ops,
  50641. - },
  50642. -};
  50643. -
  50644. -static struct scsi_host_template ahci_platform_sht = {
  50645. - AHCI_SHT("ahci_platform"),
  50646. +static const struct ata_port_info ahci_port_info = {
  50647. + .flags = AHCI_FLAG_COMMON,
  50648. + .pio_mask = ATA_PIO4,
  50649. + .udma_mask = ATA_UDMA6,
  50650. + .port_ops = &ahci_platform_ops,
  50651. };
  50652. static int ahci_probe(struct platform_device *pdev)
  50653. {
  50654. struct device *dev = &pdev->dev;
  50655. struct ahci_platform_data *pdata = dev_get_platdata(dev);
  50656. - const struct platform_device_id *id = platform_get_device_id(pdev);
  50657. - struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0];
  50658. - const struct ata_port_info *ppi[] = { &pi, NULL };
  50659. struct ahci_host_priv *hpriv;
  50660. - struct ata_host *host;
  50661. - struct resource *mem;
  50662. - int irq;
  50663. - int n_ports;
  50664. - int i;
  50665. int rc;
  50666. - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  50667. - if (!mem) {
  50668. - dev_err(dev, "no mmio space\n");
  50669. - return -EINVAL;
  50670. - }
  50671. -
  50672. - irq = platform_get_irq(pdev, 0);
  50673. - if (irq <= 0) {
  50674. - dev_err(dev, "no irq\n");
  50675. - return -EINVAL;
  50676. - }
  50677. -
  50678. - if (pdata && pdata->ata_port_info)
  50679. - pi = *pdata->ata_port_info;
  50680. -
  50681. - hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
  50682. - if (!hpriv) {
  50683. - dev_err(dev, "can't alloc ahci_host_priv\n");
  50684. - return -ENOMEM;
  50685. - }
  50686. -
  50687. - hpriv->flags |= (unsigned long)pi.private_data;
  50688. + hpriv = ahci_platform_get_resources(pdev);
  50689. + if (IS_ERR(hpriv))
  50690. + return PTR_ERR(hpriv);
  50691. - hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
  50692. - if (!hpriv->mmio) {
  50693. - dev_err(dev, "can't map %pR\n", mem);
  50694. - return -ENOMEM;
  50695. - }
  50696. -
  50697. - hpriv->clk = clk_get(dev, NULL);
  50698. - if (IS_ERR(hpriv->clk)) {
  50699. - dev_err(dev, "can't get clock\n");
  50700. - } else {
  50701. - rc = clk_prepare_enable(hpriv->clk);
  50702. - if (rc) {
  50703. - dev_err(dev, "clock prepare enable failed");
  50704. - goto free_clk;
  50705. - }
  50706. - }
  50707. + rc = ahci_platform_enable_resources(hpriv);
  50708. + if (rc)
  50709. + return rc;
  50710. /*
  50711. * Some platforms might need to prepare for mmio region access,
  50712. @@ -151,69 +52,10 @@
  50713. if (pdata && pdata->init) {
  50714. rc = pdata->init(dev, hpriv->mmio);
  50715. if (rc)
  50716. - goto disable_unprepare_clk;
  50717. - }
  50718. -
  50719. - ahci_save_initial_config(dev, hpriv,
  50720. - pdata ? pdata->force_port_map : 0,
  50721. - pdata ? pdata->mask_port_map : 0);
  50722. -
  50723. - /* prepare host */
  50724. - if (hpriv->cap & HOST_CAP_NCQ)
  50725. - pi.flags |= ATA_FLAG_NCQ;
  50726. -
  50727. - if (hpriv->cap & HOST_CAP_PMP)
  50728. - pi.flags |= ATA_FLAG_PMP;
  50729. -
  50730. - ahci_set_em_messages(hpriv, &pi);
  50731. -
  50732. - /* CAP.NP sometimes indicate the index of the last enabled
  50733. - * port, at other times, that of the last possible port, so
  50734. - * determining the maximum port number requires looking at
  50735. - * both CAP.NP and port_map.
  50736. - */
  50737. - n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
  50738. -
  50739. - host = ata_host_alloc_pinfo(dev, ppi, n_ports);
  50740. - if (!host) {
  50741. - rc = -ENOMEM;
  50742. - goto pdata_exit;
  50743. + goto disable_resources;
  50744. }
  50745. - host->private_data = hpriv;
  50746. -
  50747. - if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
  50748. - host->flags |= ATA_HOST_PARALLEL_SCAN;
  50749. - else
  50750. - dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
  50751. -
  50752. - if (pi.flags & ATA_FLAG_EM)
  50753. - ahci_reset_em(host);
  50754. -
  50755. - for (i = 0; i < host->n_ports; i++) {
  50756. - struct ata_port *ap = host->ports[i];
  50757. -
  50758. - ata_port_desc(ap, "mmio %pR", mem);
  50759. - ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
  50760. -
  50761. - /* set enclosure management message type */
  50762. - if (ap->flags & ATA_FLAG_EM)
  50763. - ap->em_message_type = hpriv->em_msg_type;
  50764. -
  50765. - /* disabled/not-implemented port */
  50766. - if (!(hpriv->port_map & (1 << i)))
  50767. - ap->ops = &ata_dummy_port_ops;
  50768. - }
  50769. -
  50770. - rc = ahci_reset_controller(host);
  50771. - if (rc)
  50772. - goto pdata_exit;
  50773. -
  50774. - ahci_init_controller(host);
  50775. - ahci_print_info(host, "platform");
  50776. -
  50777. - rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
  50778. - &ahci_platform_sht);
  50779. + rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, 0, 0, 0);
  50780. if (rc)
  50781. goto pdata_exit;
  50782. @@ -221,115 +63,19 @@
  50783. pdata_exit:
  50784. if (pdata && pdata->exit)
  50785. pdata->exit(dev);
  50786. -disable_unprepare_clk:
  50787. - if (!IS_ERR(hpriv->clk))
  50788. - clk_disable_unprepare(hpriv->clk);
  50789. -free_clk:
  50790. - if (!IS_ERR(hpriv->clk))
  50791. - clk_put(hpriv->clk);
  50792. - return rc;
  50793. -}
  50794. -
  50795. -static void ahci_host_stop(struct ata_host *host)
  50796. -{
  50797. - struct device *dev = host->dev;
  50798. - struct ahci_platform_data *pdata = dev_get_platdata(dev);
  50799. - struct ahci_host_priv *hpriv = host->private_data;
  50800. -
  50801. - if (pdata && pdata->exit)
  50802. - pdata->exit(dev);
  50803. -
  50804. - if (!IS_ERR(hpriv->clk)) {
  50805. - clk_disable_unprepare(hpriv->clk);
  50806. - clk_put(hpriv->clk);
  50807. - }
  50808. -}
  50809. -
  50810. -#ifdef CONFIG_PM_SLEEP
  50811. -static int ahci_suspend(struct device *dev)
  50812. -{
  50813. - struct ahci_platform_data *pdata = dev_get_platdata(dev);
  50814. - struct ata_host *host = dev_get_drvdata(dev);
  50815. - struct ahci_host_priv *hpriv = host->private_data;
  50816. - void __iomem *mmio = hpriv->mmio;
  50817. - u32 ctl;
  50818. - int rc;
  50819. -
  50820. - if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
  50821. - dev_err(dev, "firmware update required for suspend/resume\n");
  50822. - return -EIO;
  50823. - }
  50824. -
  50825. - /*
  50826. - * AHCI spec rev1.1 section 8.3.3:
  50827. - * Software must disable interrupts prior to requesting a
  50828. - * transition of the HBA to D3 state.
  50829. - */
  50830. - ctl = readl(mmio + HOST_CTL);
  50831. - ctl &= ~HOST_IRQ_EN;
  50832. - writel(ctl, mmio + HOST_CTL);
  50833. - readl(mmio + HOST_CTL); /* flush */
  50834. -
  50835. - rc = ata_host_suspend(host, PMSG_SUSPEND);
  50836. - if (rc)
  50837. - return rc;
  50838. -
  50839. - if (pdata && pdata->suspend)
  50840. - return pdata->suspend(dev);
  50841. -
  50842. - if (!IS_ERR(hpriv->clk))
  50843. - clk_disable_unprepare(hpriv->clk);
  50844. -
  50845. - return 0;
  50846. -}
  50847. -
  50848. -static int ahci_resume(struct device *dev)
  50849. -{
  50850. - struct ahci_platform_data *pdata = dev_get_platdata(dev);
  50851. - struct ata_host *host = dev_get_drvdata(dev);
  50852. - struct ahci_host_priv *hpriv = host->private_data;
  50853. - int rc;
  50854. -
  50855. - if (!IS_ERR(hpriv->clk)) {
  50856. - rc = clk_prepare_enable(hpriv->clk);
  50857. - if (rc) {
  50858. - dev_err(dev, "clock prepare enable failed");
  50859. - return rc;
  50860. - }
  50861. - }
  50862. -
  50863. - if (pdata && pdata->resume) {
  50864. - rc = pdata->resume(dev);
  50865. - if (rc)
  50866. - goto disable_unprepare_clk;
  50867. - }
  50868. -
  50869. - if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
  50870. - rc = ahci_reset_controller(host);
  50871. - if (rc)
  50872. - goto disable_unprepare_clk;
  50873. -
  50874. - ahci_init_controller(host);
  50875. - }
  50876. -
  50877. - ata_host_resume(host);
  50878. -
  50879. - return 0;
  50880. -
  50881. -disable_unprepare_clk:
  50882. - if (!IS_ERR(hpriv->clk))
  50883. - clk_disable_unprepare(hpriv->clk);
  50884. -
  50885. +disable_resources:
  50886. + ahci_platform_disable_resources(hpriv);
  50887. return rc;
  50888. }
  50889. -#endif
  50890. -static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
  50891. +static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
  50892. + ahci_platform_resume);
  50893. static const struct of_device_id ahci_of_match[] = {
  50894. { .compatible = "snps,spear-ahci", },
  50895. { .compatible = "snps,exynos5440-ahci", },
  50896. { .compatible = "ibm,476gtr-ahci", },
  50897. + { .compatible = "snps,dwc-ahci", },
  50898. {},
  50899. };
  50900. MODULE_DEVICE_TABLE(of, ahci_of_match);
  50901. @@ -343,7 +89,6 @@
  50902. .of_match_table = ahci_of_match,
  50903. .pm = &ahci_pm_ops,
  50904. },
  50905. - .id_table = ahci_devtype,
  50906. };
  50907. module_platform_driver(ahci_driver);
  50908. diff -Nur linux-3.14.14/drivers/ata/ata_generic.c linux-imx6-3.14/drivers/ata/ata_generic.c
  50909. --- linux-3.14.14/drivers/ata/ata_generic.c 2014-07-28 10:07:25.000000000 -0500
  50910. +++ linux-imx6-3.14/drivers/ata/ata_generic.c 2014-12-08 00:31:52.428418001 -0600
  50911. @@ -19,7 +19,6 @@
  50912. #include <linux/kernel.h>
  50913. #include <linux/module.h>
  50914. #include <linux/pci.h>
  50915. -#include <linux/init.h>
  50916. #include <linux/blkdev.h>
  50917. #include <linux/delay.h>
  50918. #include <scsi/scsi_host.h>
  50919. diff -Nur linux-3.14.14/drivers/ata/Kconfig linux-imx6-3.14/drivers/ata/Kconfig
  50920. --- linux-3.14.14/drivers/ata/Kconfig 2014-07-28 10:07:25.000000000 -0500
  50921. +++ linux-imx6-3.14/drivers/ata/Kconfig 2014-12-08 00:31:52.424418001 -0600
  50922. @@ -99,7 +99,7 @@
  50923. config AHCI_IMX
  50924. tristate "Freescale i.MX AHCI SATA support"
  50925. - depends on SATA_AHCI_PLATFORM && MFD_SYSCON
  50926. + depends on MFD_SYSCON
  50927. help
  50928. This option enables support for the Freescale i.MX SoC's
  50929. onboard AHCI SATA.
  50930. diff -Nur linux-3.14.14/drivers/ata/libahci.c linux-imx6-3.14/drivers/ata/libahci.c
  50931. --- linux-3.14.14/drivers/ata/libahci.c 2014-07-28 10:07:25.000000000 -0500
  50932. +++ linux-imx6-3.14/drivers/ata/libahci.c 2014-12-08 00:31:52.428418001 -0600
  50933. @@ -35,7 +35,6 @@
  50934. #include <linux/kernel.h>
  50935. #include <linux/gfp.h>
  50936. #include <linux/module.h>
  50937. -#include <linux/init.h>
  50938. #include <linux/blkdev.h>
  50939. #include <linux/delay.h>
  50940. #include <linux/interrupt.h>
  50941. @@ -394,6 +393,9 @@
  50942. *
  50943. * If inconsistent, config values are fixed up by this function.
  50944. *
  50945. + * If it is not set already this function sets hpriv->start_engine to
  50946. + * ahci_start_engine.
  50947. + *
  50948. * LOCKING:
  50949. * None.
  50950. */
  50951. @@ -450,11 +452,23 @@
  50952. cap &= ~HOST_CAP_SNTF;
  50953. }
  50954. + if ((cap2 & HOST_CAP2_SDS) && (hpriv->flags & AHCI_HFLAG_NO_DEVSLP)) {
  50955. + dev_info(dev,
  50956. + "controller can't do DEVSLP, turning off\n");
  50957. + cap2 &= ~HOST_CAP2_SDS;
  50958. + cap2 &= ~HOST_CAP2_SADM;
  50959. + }
  50960. +
  50961. if (!(cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_YES_FBS)) {
  50962. dev_info(dev, "controller can do FBS, turning on CAP_FBS\n");
  50963. cap |= HOST_CAP_FBS;
  50964. }
  50965. + if ((cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_NO_FBS)) {
  50966. + dev_info(dev, "controller can't do FBS, turning off CAP_FBS\n");
  50967. + cap &= ~HOST_CAP_FBS;
  50968. + }
  50969. +
  50970. if (force_port_map && port_map != force_port_map) {
  50971. dev_info(dev, "forcing port_map 0x%x -> 0x%x\n",
  50972. port_map, force_port_map);
  50973. @@ -500,6 +514,9 @@
  50974. hpriv->cap = cap;
  50975. hpriv->cap2 = cap2;
  50976. hpriv->port_map = port_map;
  50977. +
  50978. + if (!hpriv->start_engine)
  50979. + hpriv->start_engine = ahci_start_engine;
  50980. }
  50981. EXPORT_SYMBOL_GPL(ahci_save_initial_config);
  50982. @@ -766,7 +783,7 @@
  50983. /* enable DMA */
  50984. if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE))
  50985. - ahci_start_engine(ap);
  50986. + hpriv->start_engine(ap);
  50987. /* turn on LEDs */
  50988. if (ap->flags & ATA_FLAG_EM) {
  50989. @@ -1234,7 +1251,7 @@
  50990. /* restart engine */
  50991. out_restart:
  50992. - ahci_start_engine(ap);
  50993. + hpriv->start_engine(ap);
  50994. return rc;
  50995. }
  50996. EXPORT_SYMBOL_GPL(ahci_kick_engine);
  50997. @@ -1426,6 +1443,7 @@
  50998. const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
  50999. struct ata_port *ap = link->ap;
  51000. struct ahci_port_priv *pp = ap->private_data;
  51001. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51002. u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
  51003. struct ata_taskfile tf;
  51004. bool online;
  51005. @@ -1443,7 +1461,7 @@
  51006. rc = sata_link_hardreset(link, timing, deadline, &online,
  51007. ahci_check_ready);
  51008. - ahci_start_engine(ap);
  51009. + hpriv->start_engine(ap);
  51010. if (online)
  51011. *class = ahci_dev_classify(ap);
  51012. @@ -2007,10 +2025,12 @@
  51013. void ahci_error_handler(struct ata_port *ap)
  51014. {
  51015. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51016. +
  51017. if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
  51018. /* restart engine */
  51019. ahci_stop_engine(ap);
  51020. - ahci_start_engine(ap);
  51021. + hpriv->start_engine(ap);
  51022. }
  51023. sata_pmp_error_handler(ap);
  51024. @@ -2031,6 +2051,7 @@
  51025. static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
  51026. {
  51027. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51028. void __iomem *port_mmio = ahci_port_base(ap);
  51029. struct ata_device *dev = ap->link.device;
  51030. u32 devslp, dm, dito, mdat, deto;
  51031. @@ -2094,7 +2115,7 @@
  51032. PORT_DEVSLP_ADSE);
  51033. writel(devslp, port_mmio + PORT_DEVSLP);
  51034. - ahci_start_engine(ap);
  51035. + hpriv->start_engine(ap);
  51036. /* enable device sleep feature for the drive */
  51037. err_mask = ata_dev_set_feature(dev,
  51038. @@ -2106,6 +2127,7 @@
  51039. static void ahci_enable_fbs(struct ata_port *ap)
  51040. {
  51041. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51042. struct ahci_port_priv *pp = ap->private_data;
  51043. void __iomem *port_mmio = ahci_port_base(ap);
  51044. u32 fbs;
  51045. @@ -2134,11 +2156,12 @@
  51046. } else
  51047. dev_err(ap->host->dev, "Failed to enable FBS\n");
  51048. - ahci_start_engine(ap);
  51049. + hpriv->start_engine(ap);
  51050. }
  51051. static void ahci_disable_fbs(struct ata_port *ap)
  51052. {
  51053. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51054. struct ahci_port_priv *pp = ap->private_data;
  51055. void __iomem *port_mmio = ahci_port_base(ap);
  51056. u32 fbs;
  51057. @@ -2166,7 +2189,7 @@
  51058. pp->fbs_enabled = false;
  51059. }
  51060. - ahci_start_engine(ap);
  51061. + hpriv->start_engine(ap);
  51062. }
  51063. static void ahci_pmp_attach(struct ata_port *ap)
  51064. diff -Nur linux-3.14.14/drivers/ata/libahci_platform.c linux-imx6-3.14/drivers/ata/libahci_platform.c
  51065. --- linux-3.14.14/drivers/ata/libahci_platform.c 1969-12-31 18:00:00.000000000 -0600
  51066. +++ linux-imx6-3.14/drivers/ata/libahci_platform.c 2014-12-08 00:31:52.428418001 -0600
  51067. @@ -0,0 +1,544 @@
  51068. +/*
  51069. + * AHCI SATA platform library
  51070. + *
  51071. + * Copyright 2004-2005 Red Hat, Inc.
  51072. + * Jeff Garzik <jgarzik@pobox.com>
  51073. + * Copyright 2010 MontaVista Software, LLC.
  51074. + * Anton Vorontsov <avorontsov@ru.mvista.com>
  51075. + *
  51076. + * This program is free software; you can redistribute it and/or modify
  51077. + * it under the terms of the GNU General Public License as published by
  51078. + * the Free Software Foundation; either version 2, or (at your option)
  51079. + * any later version.
  51080. + */
  51081. +
  51082. +#include <linux/clk.h>
  51083. +#include <linux/kernel.h>
  51084. +#include <linux/gfp.h>
  51085. +#include <linux/module.h>
  51086. +#include <linux/pm.h>
  51087. +#include <linux/interrupt.h>
  51088. +#include <linux/device.h>
  51089. +#include <linux/platform_device.h>
  51090. +#include <linux/libata.h>
  51091. +#include <linux/ahci_platform.h>
  51092. +#include <linux/phy/phy.h>
  51093. +#include <linux/pm_runtime.h>
  51094. +#include "ahci.h"
  51095. +
  51096. +static void ahci_host_stop(struct ata_host *host);
  51097. +
  51098. +struct ata_port_operations ahci_platform_ops = {
  51099. + .inherits = &ahci_ops,
  51100. + .host_stop = ahci_host_stop,
  51101. +};
  51102. +EXPORT_SYMBOL_GPL(ahci_platform_ops);
  51103. +
  51104. +static struct scsi_host_template ahci_platform_sht = {
  51105. + AHCI_SHT("ahci_platform"),
  51106. +};
  51107. +
  51108. +/**
  51109. + * ahci_platform_enable_clks - Enable platform clocks
  51110. + * @hpriv: host private area to store config values
  51111. + *
  51112. + * This function enables all the clks found in hpriv->clks, starting at
  51113. + * index 0. If any clk fails to enable it disables all the clks already
  51114. + * enabled in reverse order, and then returns an error.
  51115. + *
  51116. + * RETURNS:
  51117. + * 0 on success otherwise a negative error code
  51118. + */
  51119. +int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
  51120. +{
  51121. + int c, rc;
  51122. +
  51123. + for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) {
  51124. + rc = clk_prepare_enable(hpriv->clks[c]);
  51125. + if (rc)
  51126. + goto disable_unprepare_clk;
  51127. + }
  51128. + return 0;
  51129. +
  51130. +disable_unprepare_clk:
  51131. + while (--c >= 0)
  51132. + clk_disable_unprepare(hpriv->clks[c]);
  51133. + return rc;
  51134. +}
  51135. +EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
  51136. +
  51137. +/**
  51138. + * ahci_platform_disable_clks - Disable platform clocks
  51139. + * @hpriv: host private area to store config values
  51140. + *
  51141. + * This function disables all the clks found in hpriv->clks, in reverse
  51142. + * order of ahci_platform_enable_clks (starting at the end of the array).
  51143. + */
  51144. +void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
  51145. +{
  51146. + int c;
  51147. +
  51148. + for (c = AHCI_MAX_CLKS - 1; c >= 0; c--)
  51149. + if (hpriv->clks[c])
  51150. + clk_disable_unprepare(hpriv->clks[c]);
  51151. +}
  51152. +EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
  51153. +
  51154. +/**
  51155. + * ahci_platform_enable_resources - Enable platform resources
  51156. + * @hpriv: host private area to store config values
  51157. + *
  51158. + * This function enables all ahci_platform managed resources in the
  51159. + * following order:
  51160. + * 1) Regulator
  51161. + * 2) Clocks (through ahci_platform_enable_clks)
  51162. + * 3) Phy
  51163. + *
  51164. + * If resource enabling fails at any point the previous enabled resources
  51165. + * are disabled in reverse order.
  51166. + *
  51167. + * RETURNS:
  51168. + * 0 on success otherwise a negative error code
  51169. + */
  51170. +int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
  51171. +{
  51172. + int rc;
  51173. +
  51174. + if (hpriv->target_pwr) {
  51175. + rc = regulator_enable(hpriv->target_pwr);
  51176. + if (rc)
  51177. + return rc;
  51178. + }
  51179. +
  51180. + rc = ahci_platform_enable_clks(hpriv);
  51181. + if (rc)
  51182. + goto disable_regulator;
  51183. +
  51184. + if (hpriv->phy) {
  51185. + rc = phy_init(hpriv->phy);
  51186. + if (rc)
  51187. + goto disable_clks;
  51188. +
  51189. + rc = phy_power_on(hpriv->phy);
  51190. + if (rc) {
  51191. + phy_exit(hpriv->phy);
  51192. + goto disable_clks;
  51193. + }
  51194. + }
  51195. +
  51196. + return 0;
  51197. +
  51198. +disable_clks:
  51199. + ahci_platform_disable_clks(hpriv);
  51200. +
  51201. +disable_regulator:
  51202. + if (hpriv->target_pwr)
  51203. + regulator_disable(hpriv->target_pwr);
  51204. + return rc;
  51205. +}
  51206. +EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
  51207. +
  51208. +/**
  51209. + * ahci_platform_disable_resources - Disable platform resources
  51210. + * @hpriv: host private area to store config values
  51211. + *
  51212. + * This function disables all ahci_platform managed resources in the
  51213. + * following order:
  51214. + * 1) Phy
  51215. + * 2) Clocks (through ahci_platform_disable_clks)
  51216. + * 3) Regulator
  51217. + */
  51218. +void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
  51219. +{
  51220. + if (hpriv->phy) {
  51221. + phy_power_off(hpriv->phy);
  51222. + phy_exit(hpriv->phy);
  51223. + }
  51224. +
  51225. + ahci_platform_disable_clks(hpriv);
  51226. +
  51227. + if (hpriv->target_pwr)
  51228. + regulator_disable(hpriv->target_pwr);
  51229. +}
  51230. +EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
  51231. +
  51232. +static void ahci_platform_put_resources(struct device *dev, void *res)
  51233. +{
  51234. + struct ahci_host_priv *hpriv = res;
  51235. + int c;
  51236. +
  51237. + if (hpriv->got_runtime_pm) {
  51238. + pm_runtime_put_sync(dev);
  51239. + pm_runtime_disable(dev);
  51240. + }
  51241. +
  51242. + for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
  51243. + clk_put(hpriv->clks[c]);
  51244. +}
  51245. +
  51246. +/**
  51247. + * ahci_platform_get_resources - Get platform resources
  51248. + * @pdev: platform device to get resources for
  51249. + *
  51250. + * This function allocates an ahci_host_priv struct, and gets the following
  51251. + * resources, storing a reference to them inside the returned struct:
  51252. + *
  51253. + * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
  51254. + * 2) regulator for controlling the targets power (optional)
  51255. + * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
  51256. + * or for non devicetree enabled platforms a single clock
  51257. + * 4) phy (optional)
  51258. + *
  51259. + * RETURNS:
  51260. + * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
  51261. + */
  51262. +struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
  51263. +{
  51264. + struct device *dev = &pdev->dev;
  51265. + struct ahci_host_priv *hpriv;
  51266. + struct clk *clk;
  51267. + int i, rc = -ENOMEM;
  51268. +
  51269. + if (!devres_open_group(dev, NULL, GFP_KERNEL))
  51270. + return ERR_PTR(-ENOMEM);
  51271. +
  51272. + hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
  51273. + GFP_KERNEL);
  51274. + if (!hpriv)
  51275. + goto err_out;
  51276. +
  51277. + devres_add(dev, hpriv);
  51278. +
  51279. + hpriv->mmio = devm_ioremap_resource(dev,
  51280. + platform_get_resource(pdev, IORESOURCE_MEM, 0));
  51281. + if (IS_ERR(hpriv->mmio)) {
  51282. + dev_err(dev, "no mmio space\n");
  51283. + rc = PTR_ERR(hpriv->mmio);
  51284. + goto err_out;
  51285. + }
  51286. +
  51287. + hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
  51288. + if (IS_ERR(hpriv->target_pwr)) {
  51289. + rc = PTR_ERR(hpriv->target_pwr);
  51290. + if (rc == -EPROBE_DEFER)
  51291. + goto err_out;
  51292. + hpriv->target_pwr = NULL;
  51293. + }
  51294. +
  51295. + for (i = 0; i < AHCI_MAX_CLKS; i++) {
  51296. + /*
  51297. + * For now we must use clk_get(dev, NULL) for the first clock,
  51298. + * because some platforms (da850, spear13xx) are not yet
  51299. + * converted to use devicetree for clocks. For new platforms
  51300. + * this is equivalent to of_clk_get(dev->of_node, 0).
  51301. + */
  51302. + if (i == 0)
  51303. + clk = clk_get(dev, NULL);
  51304. + else
  51305. + clk = of_clk_get(dev->of_node, i);
  51306. +
  51307. + if (IS_ERR(clk)) {
  51308. + rc = PTR_ERR(clk);
  51309. + if (rc == -EPROBE_DEFER)
  51310. + goto err_out;
  51311. + break;
  51312. + }
  51313. + hpriv->clks[i] = clk;
  51314. + }
  51315. +
  51316. + hpriv->phy = devm_phy_get(dev, "sata-phy");
  51317. + if (IS_ERR(hpriv->phy)) {
  51318. + rc = PTR_ERR(hpriv->phy);
  51319. + switch (rc) {
  51320. + case -ENODEV:
  51321. + case -ENOSYS:
  51322. + /* continue normally */
  51323. + hpriv->phy = NULL;
  51324. + break;
  51325. +
  51326. + case -EPROBE_DEFER:
  51327. + goto err_out;
  51328. +
  51329. + default:
  51330. + dev_err(dev, "couldn't get sata-phy\n");
  51331. + goto err_out;
  51332. + }
  51333. + }
  51334. +
  51335. + pm_runtime_enable(dev);
  51336. + pm_runtime_get_sync(dev);
  51337. + hpriv->got_runtime_pm = true;
  51338. +
  51339. + devres_remove_group(dev, NULL);
  51340. + return hpriv;
  51341. +
  51342. +err_out:
  51343. + devres_release_group(dev, NULL);
  51344. + return ERR_PTR(rc);
  51345. +}
  51346. +EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
  51347. +
  51348. +/**
  51349. + * ahci_platform_init_host - Bring up an ahci-platform host
  51350. + * @pdev: platform device pointer for the host
  51351. + * @hpriv: ahci-host private data for the host
  51352. + * @pi_template: template for the ata_port_info to use
  51353. + * @host_flags: ahci host flags used in ahci_host_priv
  51354. + * @force_port_map: param passed to ahci_save_initial_config
  51355. + * @mask_port_map: param passed to ahci_save_initial_config
  51356. + *
  51357. + * This function does all the usual steps needed to bring up an
  51358. + * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
  51359. + * must be initialized / enabled before calling this.
  51360. + *
  51361. + * RETURNS:
  51362. + * 0 on success otherwise a negative error code
  51363. + */
  51364. +int ahci_platform_init_host(struct platform_device *pdev,
  51365. + struct ahci_host_priv *hpriv,
  51366. + const struct ata_port_info *pi_template,
  51367. + unsigned long host_flags,
  51368. + unsigned int force_port_map,
  51369. + unsigned int mask_port_map)
  51370. +{
  51371. + struct device *dev = &pdev->dev;
  51372. + struct ata_port_info pi = *pi_template;
  51373. + const struct ata_port_info *ppi[] = { &pi, NULL };
  51374. + struct ata_host *host;
  51375. + int i, irq, n_ports, rc;
  51376. +
  51377. + irq = platform_get_irq(pdev, 0);
  51378. + if (irq <= 0) {
  51379. + dev_err(dev, "no irq\n");
  51380. + return -EINVAL;
  51381. + }
  51382. +
  51383. + /* prepare host */
  51384. + pi.private_data = (void *)host_flags;
  51385. + hpriv->flags |= host_flags;
  51386. +
  51387. + ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
  51388. +
  51389. + if (hpriv->cap & HOST_CAP_NCQ)
  51390. + pi.flags |= ATA_FLAG_NCQ;
  51391. +
  51392. + if (hpriv->cap & HOST_CAP_PMP)
  51393. + pi.flags |= ATA_FLAG_PMP;
  51394. +
  51395. + ahci_set_em_messages(hpriv, &pi);
  51396. +
  51397. + /* CAP.NP sometimes indicate the index of the last enabled
  51398. + * port, at other times, that of the last possible port, so
  51399. + * determining the maximum port number requires looking at
  51400. + * both CAP.NP and port_map.
  51401. + */
  51402. + n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
  51403. +
  51404. + host = ata_host_alloc_pinfo(dev, ppi, n_ports);
  51405. + if (!host)
  51406. + return -ENOMEM;
  51407. +
  51408. + host->private_data = hpriv;
  51409. +
  51410. + if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
  51411. + host->flags |= ATA_HOST_PARALLEL_SCAN;
  51412. + else
  51413. + dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
  51414. +
  51415. + if (pi.flags & ATA_FLAG_EM)
  51416. + ahci_reset_em(host);
  51417. +
  51418. + for (i = 0; i < host->n_ports; i++) {
  51419. + struct ata_port *ap = host->ports[i];
  51420. +
  51421. + ata_port_desc(ap, "mmio %pR",
  51422. + platform_get_resource(pdev, IORESOURCE_MEM, 0));
  51423. + ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
  51424. +
  51425. + /* set enclosure management message type */
  51426. + if (ap->flags & ATA_FLAG_EM)
  51427. + ap->em_message_type = hpriv->em_msg_type;
  51428. +
  51429. + /* disabled/not-implemented port */
  51430. + if (!(hpriv->port_map & (1 << i)))
  51431. + ap->ops = &ata_dummy_port_ops;
  51432. + }
  51433. +
  51434. + rc = ahci_reset_controller(host);
  51435. + if (rc)
  51436. + return rc;
  51437. +
  51438. + ahci_init_controller(host);
  51439. + ahci_print_info(host, "platform");
  51440. +
  51441. + return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
  51442. + &ahci_platform_sht);
  51443. +}
  51444. +EXPORT_SYMBOL_GPL(ahci_platform_init_host);
  51445. +
  51446. +static void ahci_host_stop(struct ata_host *host)
  51447. +{
  51448. + struct device *dev = host->dev;
  51449. + struct ahci_platform_data *pdata = dev_get_platdata(dev);
  51450. + struct ahci_host_priv *hpriv = host->private_data;
  51451. +
  51452. + if (pdata && pdata->exit)
  51453. + pdata->exit(dev);
  51454. +
  51455. + ahci_platform_disable_resources(hpriv);
  51456. +}
  51457. +
  51458. +#ifdef CONFIG_PM_SLEEP
  51459. +/**
  51460. + * ahci_platform_suspend_host - Suspend an ahci-platform host
  51461. + * @dev: device pointer for the host
  51462. + *
  51463. + * This function does all the usual steps needed to suspend an
  51464. + * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
  51465. + * must be disabled after calling this.
  51466. + *
  51467. + * RETURNS:
  51468. + * 0 on success otherwise a negative error code
  51469. + */
  51470. +int ahci_platform_suspend_host(struct device *dev)
  51471. +{
  51472. + struct ata_host *host = dev_get_drvdata(dev);
  51473. + struct ahci_host_priv *hpriv = host->private_data;
  51474. + void __iomem *mmio = hpriv->mmio;
  51475. + u32 ctl;
  51476. +
  51477. + if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
  51478. + dev_err(dev, "firmware update required for suspend/resume\n");
  51479. + return -EIO;
  51480. + }
  51481. +
  51482. + /*
  51483. + * AHCI spec rev1.1 section 8.3.3:
  51484. + * Software must disable interrupts prior to requesting a
  51485. + * transition of the HBA to D3 state.
  51486. + */
  51487. + ctl = readl(mmio + HOST_CTL);
  51488. + ctl &= ~HOST_IRQ_EN;
  51489. + writel(ctl, mmio + HOST_CTL);
  51490. + readl(mmio + HOST_CTL); /* flush */
  51491. +
  51492. + return ata_host_suspend(host, PMSG_SUSPEND);
  51493. +}
  51494. +EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
  51495. +
  51496. +/**
  51497. + * ahci_platform_resume_host - Resume an ahci-platform host
  51498. + * @dev: device pointer for the host
  51499. + *
  51500. + * This function does all the usual steps needed to resume an ahci-platform
  51501. + * host, note any necessary resources (ie clks, phy, etc.) must be
  51502. + * initialized / enabled before calling this.
  51503. + *
  51504. + * RETURNS:
  51505. + * 0 on success otherwise a negative error code
  51506. + */
  51507. +int ahci_platform_resume_host(struct device *dev)
  51508. +{
  51509. + struct ata_host *host = dev_get_drvdata(dev);
  51510. + int rc;
  51511. +
  51512. + if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
  51513. + rc = ahci_reset_controller(host);
  51514. + if (rc)
  51515. + return rc;
  51516. +
  51517. + ahci_init_controller(host);
  51518. + }
  51519. +
  51520. + ata_host_resume(host);
  51521. +
  51522. + return 0;
  51523. +}
  51524. +EXPORT_SYMBOL_GPL(ahci_platform_resume_host);
  51525. +
  51526. +/**
  51527. + * ahci_platform_suspend - Suspend an ahci-platform device
  51528. + * @dev: the platform device to suspend
  51529. + *
  51530. + * This function suspends the host associated with the device, followed by
  51531. + * disabling all the resources of the device.
  51532. + *
  51533. + * RETURNS:
  51534. + * 0 on success otherwise a negative error code
  51535. + */
  51536. +int ahci_platform_suspend(struct device *dev)
  51537. +{
  51538. + struct ahci_platform_data *pdata = dev_get_platdata(dev);
  51539. + struct ata_host *host = dev_get_drvdata(dev);
  51540. + struct ahci_host_priv *hpriv = host->private_data;
  51541. + int rc;
  51542. +
  51543. + rc = ahci_platform_suspend_host(dev);
  51544. + if (rc)
  51545. + return rc;
  51546. +
  51547. + if (pdata && pdata->suspend) {
  51548. + rc = pdata->suspend(dev);
  51549. + if (rc)
  51550. + goto resume_host;
  51551. + }
  51552. +
  51553. + ahci_platform_disable_resources(hpriv);
  51554. +
  51555. + return 0;
  51556. +
  51557. +resume_host:
  51558. + ahci_platform_resume_host(dev);
  51559. + return rc;
  51560. +}
  51561. +EXPORT_SYMBOL_GPL(ahci_platform_suspend);
  51562. +
  51563. +/**
  51564. + * ahci_platform_resume - Resume an ahci-platform device
  51565. + * @dev: the platform device to resume
  51566. + *
  51567. + * This function enables all the resources of the device followed by
  51568. + * resuming the host associated with the device.
  51569. + *
  51570. + * RETURNS:
  51571. + * 0 on success otherwise a negative error code
  51572. + */
  51573. +int ahci_platform_resume(struct device *dev)
  51574. +{
  51575. + struct ahci_platform_data *pdata = dev_get_platdata(dev);
  51576. + struct ata_host *host = dev_get_drvdata(dev);
  51577. + struct ahci_host_priv *hpriv = host->private_data;
  51578. + int rc;
  51579. +
  51580. + rc = ahci_platform_enable_resources(hpriv);
  51581. + if (rc)
  51582. + return rc;
  51583. +
  51584. + if (pdata && pdata->resume) {
  51585. + rc = pdata->resume(dev);
  51586. + if (rc)
  51587. + goto disable_resources;
  51588. + }
  51589. +
  51590. + rc = ahci_platform_resume_host(dev);
  51591. + if (rc)
  51592. + goto disable_resources;
  51593. +
  51594. + /* We resumed so update PM runtime state */
  51595. + pm_runtime_disable(dev);
  51596. + pm_runtime_set_active(dev);
  51597. + pm_runtime_enable(dev);
  51598. +
  51599. + return 0;
  51600. +
  51601. +disable_resources:
  51602. + ahci_platform_disable_resources(hpriv);
  51603. +
  51604. + return rc;
  51605. +}
  51606. +EXPORT_SYMBOL_GPL(ahci_platform_resume);
  51607. +#endif
  51608. +
  51609. +MODULE_DESCRIPTION("AHCI SATA platform library");
  51610. +MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
  51611. +MODULE_LICENSE("GPL");
  51612. diff -Nur linux-3.14.14/drivers/ata/libata-core.c linux-imx6-3.14/drivers/ata/libata-core.c
  51613. --- linux-3.14.14/drivers/ata/libata-core.c 2014-07-28 10:07:25.000000000 -0500
  51614. +++ linux-imx6-3.14/drivers/ata/libata-core.c 2014-12-08 00:31:52.428418001 -0600
  51615. @@ -1524,7 +1524,7 @@
  51616. * @dev: Device to which the command is sent
  51617. * @tf: Taskfile registers for the command and the result
  51618. * @cdb: CDB for packet command
  51619. - * @dma_dir: Data tranfer direction of the command
  51620. + * @dma_dir: Data transfer direction of the command
  51621. * @sgl: sg list for the data buffer of the command
  51622. * @n_elem: Number of sg entries
  51623. * @timeout: Timeout in msecs (0 for default)
  51624. @@ -1712,7 +1712,7 @@
  51625. * @dev: Device to which the command is sent
  51626. * @tf: Taskfile registers for the command and the result
  51627. * @cdb: CDB for packet command
  51628. - * @dma_dir: Data tranfer direction of the command
  51629. + * @dma_dir: Data transfer direction of the command
  51630. * @buf: Data buffer of the command
  51631. * @buflen: Length of data buffer
  51632. * @timeout: Timeout in msecs (0 for default)
  51633. diff -Nur linux-3.14.14/drivers/ata/Makefile linux-imx6-3.14/drivers/ata/Makefile
  51634. --- linux-3.14.14/drivers/ata/Makefile 2014-07-28 10:07:25.000000000 -0500
  51635. +++ linux-imx6-3.14/drivers/ata/Makefile 2014-12-08 00:31:52.424418001 -0600
  51636. @@ -4,13 +4,13 @@
  51637. # non-SFF interface
  51638. obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o
  51639. obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o
  51640. -obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
  51641. +obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o
  51642. obj-$(CONFIG_SATA_FSL) += sata_fsl.o
  51643. obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
  51644. obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
  51645. obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
  51646. obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
  51647. -obj-$(CONFIG_AHCI_IMX) += ahci_imx.o
  51648. +obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o
  51649. # SFF w/ custom DMA
  51650. obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
  51651. diff -Nur linux-3.14.14/drivers/ata/pata_acpi.c linux-imx6-3.14/drivers/ata/pata_acpi.c
  51652. --- linux-3.14.14/drivers/ata/pata_acpi.c 2014-07-28 10:07:25.000000000 -0500
  51653. +++ linux-imx6-3.14/drivers/ata/pata_acpi.c 2014-12-08 00:31:52.432418001 -0600
  51654. @@ -7,7 +7,6 @@
  51655. #include <linux/kernel.h>
  51656. #include <linux/module.h>
  51657. #include <linux/pci.h>
  51658. -#include <linux/init.h>
  51659. #include <linux/blkdev.h>
  51660. #include <linux/delay.h>
  51661. #include <linux/device.h>
  51662. diff -Nur linux-3.14.14/drivers/ata/pata_amd.c linux-imx6-3.14/drivers/ata/pata_amd.c
  51663. --- linux-3.14.14/drivers/ata/pata_amd.c 2014-07-28 10:07:25.000000000 -0500
  51664. +++ linux-imx6-3.14/drivers/ata/pata_amd.c 2014-12-08 00:31:52.432418001 -0600
  51665. @@ -17,7 +17,6 @@
  51666. #include <linux/kernel.h>
  51667. #include <linux/module.h>
  51668. #include <linux/pci.h>
  51669. -#include <linux/init.h>
  51670. #include <linux/blkdev.h>
  51671. #include <linux/delay.h>
  51672. #include <scsi/scsi_host.h>
  51673. diff -Nur linux-3.14.14/drivers/ata/pata_artop.c linux-imx6-3.14/drivers/ata/pata_artop.c
  51674. --- linux-3.14.14/drivers/ata/pata_artop.c 2014-07-28 10:07:25.000000000 -0500
  51675. +++ linux-imx6-3.14/drivers/ata/pata_artop.c 2014-12-08 00:31:52.432418001 -0600
  51676. @@ -19,7 +19,6 @@
  51677. #include <linux/kernel.h>
  51678. #include <linux/module.h>
  51679. #include <linux/pci.h>
  51680. -#include <linux/init.h>
  51681. #include <linux/blkdev.h>
  51682. #include <linux/delay.h>
  51683. #include <linux/device.h>
  51684. diff -Nur linux-3.14.14/drivers/ata/pata_at91.c linux-imx6-3.14/drivers/ata/pata_at91.c
  51685. --- linux-3.14.14/drivers/ata/pata_at91.c 2014-07-28 10:07:25.000000000 -0500
  51686. +++ linux-imx6-3.14/drivers/ata/pata_at91.c 2014-12-08 00:31:52.432418001 -0600
  51687. @@ -18,7 +18,6 @@
  51688. #include <linux/kernel.h>
  51689. #include <linux/module.h>
  51690. -#include <linux/init.h>
  51691. #include <linux/blkdev.h>
  51692. #include <linux/gfp.h>
  51693. #include <scsi/scsi_host.h>
  51694. diff -Nur linux-3.14.14/drivers/ata/pata_atiixp.c linux-imx6-3.14/drivers/ata/pata_atiixp.c
  51695. --- linux-3.14.14/drivers/ata/pata_atiixp.c 2014-07-28 10:07:25.000000000 -0500
  51696. +++ linux-imx6-3.14/drivers/ata/pata_atiixp.c 2014-12-08 00:31:52.432418001 -0600
  51697. @@ -15,7 +15,6 @@
  51698. #include <linux/kernel.h>
  51699. #include <linux/module.h>
  51700. #include <linux/pci.h>
  51701. -#include <linux/init.h>
  51702. #include <linux/blkdev.h>
  51703. #include <linux/delay.h>
  51704. #include <scsi/scsi_host.h>
  51705. diff -Nur linux-3.14.14/drivers/ata/pata_atp867x.c linux-imx6-3.14/drivers/ata/pata_atp867x.c
  51706. --- linux-3.14.14/drivers/ata/pata_atp867x.c 2014-07-28 10:07:25.000000000 -0500
  51707. +++ linux-imx6-3.14/drivers/ata/pata_atp867x.c 2014-12-08 00:31:52.432418001 -0600
  51708. @@ -29,7 +29,6 @@
  51709. #include <linux/kernel.h>
  51710. #include <linux/module.h>
  51711. #include <linux/pci.h>
  51712. -#include <linux/init.h>
  51713. #include <linux/blkdev.h>
  51714. #include <linux/delay.h>
  51715. #include <linux/device.h>
  51716. diff -Nur linux-3.14.14/drivers/ata/pata_cmd640.c linux-imx6-3.14/drivers/ata/pata_cmd640.c
  51717. --- linux-3.14.14/drivers/ata/pata_cmd640.c 2014-07-28 10:07:25.000000000 -0500
  51718. +++ linux-imx6-3.14/drivers/ata/pata_cmd640.c 2014-12-08 00:31:52.432418001 -0600
  51719. @@ -15,7 +15,6 @@
  51720. #include <linux/kernel.h>
  51721. #include <linux/module.h>
  51722. #include <linux/pci.h>
  51723. -#include <linux/init.h>
  51724. #include <linux/blkdev.h>
  51725. #include <linux/delay.h>
  51726. #include <linux/gfp.h>
  51727. diff -Nur linux-3.14.14/drivers/ata/pata_cmd64x.c linux-imx6-3.14/drivers/ata/pata_cmd64x.c
  51728. --- linux-3.14.14/drivers/ata/pata_cmd64x.c 2014-07-28 10:07:25.000000000 -0500
  51729. +++ linux-imx6-3.14/drivers/ata/pata_cmd64x.c 2014-12-08 00:31:52.432418001 -0600
  51730. @@ -26,7 +26,6 @@
  51731. #include <linux/kernel.h>
  51732. #include <linux/module.h>
  51733. #include <linux/pci.h>
  51734. -#include <linux/init.h>
  51735. #include <linux/blkdev.h>
  51736. #include <linux/delay.h>
  51737. #include <scsi/scsi_host.h>
  51738. diff -Nur linux-3.14.14/drivers/ata/pata_cs5520.c linux-imx6-3.14/drivers/ata/pata_cs5520.c
  51739. --- linux-3.14.14/drivers/ata/pata_cs5520.c 2014-07-28 10:07:25.000000000 -0500
  51740. +++ linux-imx6-3.14/drivers/ata/pata_cs5520.c 2014-12-08 00:31:52.432418001 -0600
  51741. @@ -34,7 +34,6 @@
  51742. #include <linux/kernel.h>
  51743. #include <linux/module.h>
  51744. #include <linux/pci.h>
  51745. -#include <linux/init.h>
  51746. #include <linux/blkdev.h>
  51747. #include <linux/delay.h>
  51748. #include <scsi/scsi_host.h>
  51749. diff -Nur linux-3.14.14/drivers/ata/pata_cs5530.c linux-imx6-3.14/drivers/ata/pata_cs5530.c
  51750. --- linux-3.14.14/drivers/ata/pata_cs5530.c 2014-07-28 10:07:25.000000000 -0500
  51751. +++ linux-imx6-3.14/drivers/ata/pata_cs5530.c 2014-12-08 00:31:52.432418001 -0600
  51752. @@ -26,7 +26,6 @@
  51753. #include <linux/kernel.h>
  51754. #include <linux/module.h>
  51755. #include <linux/pci.h>
  51756. -#include <linux/init.h>
  51757. #include <linux/blkdev.h>
  51758. #include <linux/delay.h>
  51759. #include <scsi/scsi_host.h>
  51760. diff -Nur linux-3.14.14/drivers/ata/pata_cs5535.c linux-imx6-3.14/drivers/ata/pata_cs5535.c
  51761. --- linux-3.14.14/drivers/ata/pata_cs5535.c 2014-07-28 10:07:25.000000000 -0500
  51762. +++ linux-imx6-3.14/drivers/ata/pata_cs5535.c 2014-12-08 00:31:52.432418001 -0600
  51763. @@ -31,7 +31,6 @@
  51764. #include <linux/kernel.h>
  51765. #include <linux/module.h>
  51766. #include <linux/pci.h>
  51767. -#include <linux/init.h>
  51768. #include <linux/blkdev.h>
  51769. #include <linux/delay.h>
  51770. #include <scsi/scsi_host.h>
  51771. diff -Nur linux-3.14.14/drivers/ata/pata_cs5536.c linux-imx6-3.14/drivers/ata/pata_cs5536.c
  51772. --- linux-3.14.14/drivers/ata/pata_cs5536.c 2014-07-28 10:07:25.000000000 -0500
  51773. +++ linux-imx6-3.14/drivers/ata/pata_cs5536.c 2014-12-08 00:31:52.432418001 -0600
  51774. @@ -33,7 +33,6 @@
  51775. #include <linux/kernel.h>
  51776. #include <linux/module.h>
  51777. #include <linux/pci.h>
  51778. -#include <linux/init.h>
  51779. #include <linux/blkdev.h>
  51780. #include <linux/delay.h>
  51781. #include <linux/libata.h>
  51782. diff -Nur linux-3.14.14/drivers/ata/pata_cypress.c linux-imx6-3.14/drivers/ata/pata_cypress.c
  51783. --- linux-3.14.14/drivers/ata/pata_cypress.c 2014-07-28 10:07:25.000000000 -0500
  51784. +++ linux-imx6-3.14/drivers/ata/pata_cypress.c 2014-12-08 00:31:52.436418001 -0600
  51785. @@ -11,7 +11,6 @@
  51786. #include <linux/kernel.h>
  51787. #include <linux/module.h>
  51788. #include <linux/pci.h>
  51789. -#include <linux/init.h>
  51790. #include <linux/blkdev.h>
  51791. #include <linux/delay.h>
  51792. #include <scsi/scsi_host.h>
  51793. diff -Nur linux-3.14.14/drivers/ata/pata_efar.c linux-imx6-3.14/drivers/ata/pata_efar.c
  51794. --- linux-3.14.14/drivers/ata/pata_efar.c 2014-07-28 10:07:25.000000000 -0500
  51795. +++ linux-imx6-3.14/drivers/ata/pata_efar.c 2014-12-08 00:31:52.436418001 -0600
  51796. @@ -14,7 +14,6 @@
  51797. #include <linux/kernel.h>
  51798. #include <linux/module.h>
  51799. #include <linux/pci.h>
  51800. -#include <linux/init.h>
  51801. #include <linux/blkdev.h>
  51802. #include <linux/delay.h>
  51803. #include <linux/device.h>
  51804. diff -Nur linux-3.14.14/drivers/ata/pata_ep93xx.c linux-imx6-3.14/drivers/ata/pata_ep93xx.c
  51805. --- linux-3.14.14/drivers/ata/pata_ep93xx.c 2014-07-28 10:07:25.000000000 -0500
  51806. +++ linux-imx6-3.14/drivers/ata/pata_ep93xx.c 2014-12-08 00:31:52.436418001 -0600
  51807. @@ -34,7 +34,6 @@
  51808. #include <linux/err.h>
  51809. #include <linux/kernel.h>
  51810. #include <linux/module.h>
  51811. -#include <linux/init.h>
  51812. #include <linux/blkdev.h>
  51813. #include <scsi/scsi_host.h>
  51814. #include <linux/ata.h>
  51815. diff -Nur linux-3.14.14/drivers/ata/pata_hpt366.c linux-imx6-3.14/drivers/ata/pata_hpt366.c
  51816. --- linux-3.14.14/drivers/ata/pata_hpt366.c 2014-07-28 10:07:25.000000000 -0500
  51817. +++ linux-imx6-3.14/drivers/ata/pata_hpt366.c 2014-12-08 00:31:52.436418001 -0600
  51818. @@ -19,7 +19,6 @@
  51819. #include <linux/kernel.h>
  51820. #include <linux/module.h>
  51821. #include <linux/pci.h>
  51822. -#include <linux/init.h>
  51823. #include <linux/blkdev.h>
  51824. #include <linux/delay.h>
  51825. #include <scsi/scsi_host.h>
  51826. diff -Nur linux-3.14.14/drivers/ata/pata_hpt37x.c linux-imx6-3.14/drivers/ata/pata_hpt37x.c
  51827. --- linux-3.14.14/drivers/ata/pata_hpt37x.c 2014-07-28 10:07:25.000000000 -0500
  51828. +++ linux-imx6-3.14/drivers/ata/pata_hpt37x.c 2014-12-08 00:31:52.436418001 -0600
  51829. @@ -19,7 +19,6 @@
  51830. #include <linux/kernel.h>
  51831. #include <linux/module.h>
  51832. #include <linux/pci.h>
  51833. -#include <linux/init.h>
  51834. #include <linux/blkdev.h>
  51835. #include <linux/delay.h>
  51836. #include <scsi/scsi_host.h>
  51837. diff -Nur linux-3.14.14/drivers/ata/pata_hpt3x2n.c linux-imx6-3.14/drivers/ata/pata_hpt3x2n.c
  51838. --- linux-3.14.14/drivers/ata/pata_hpt3x2n.c 2014-07-28 10:07:25.000000000 -0500
  51839. +++ linux-imx6-3.14/drivers/ata/pata_hpt3x2n.c 2014-12-08 00:31:52.436418001 -0600
  51840. @@ -20,7 +20,6 @@
  51841. #include <linux/kernel.h>
  51842. #include <linux/module.h>
  51843. #include <linux/pci.h>
  51844. -#include <linux/init.h>
  51845. #include <linux/blkdev.h>
  51846. #include <linux/delay.h>
  51847. #include <scsi/scsi_host.h>
  51848. diff -Nur linux-3.14.14/drivers/ata/pata_hpt3x3.c linux-imx6-3.14/drivers/ata/pata_hpt3x3.c
  51849. --- linux-3.14.14/drivers/ata/pata_hpt3x3.c 2014-07-28 10:07:25.000000000 -0500
  51850. +++ linux-imx6-3.14/drivers/ata/pata_hpt3x3.c 2014-12-08 00:31:52.436418001 -0600
  51851. @@ -16,7 +16,6 @@
  51852. #include <linux/kernel.h>
  51853. #include <linux/module.h>
  51854. #include <linux/pci.h>
  51855. -#include <linux/init.h>
  51856. #include <linux/blkdev.h>
  51857. #include <linux/delay.h>
  51858. #include <scsi/scsi_host.h>
  51859. diff -Nur linux-3.14.14/drivers/ata/pata_imx.c linux-imx6-3.14/drivers/ata/pata_imx.c
  51860. --- linux-3.14.14/drivers/ata/pata_imx.c 2014-07-28 10:07:25.000000000 -0500
  51861. +++ linux-imx6-3.14/drivers/ata/pata_imx.c 2014-12-08 00:31:52.436418001 -0600
  51862. @@ -15,7 +15,6 @@
  51863. */
  51864. #include <linux/kernel.h>
  51865. #include <linux/module.h>
  51866. -#include <linux/init.h>
  51867. #include <linux/blkdev.h>
  51868. #include <scsi/scsi_host.h>
  51869. #include <linux/ata.h>
  51870. diff -Nur linux-3.14.14/drivers/ata/pata_it8213.c linux-imx6-3.14/drivers/ata/pata_it8213.c
  51871. --- linux-3.14.14/drivers/ata/pata_it8213.c 2014-07-28 10:07:25.000000000 -0500
  51872. +++ linux-imx6-3.14/drivers/ata/pata_it8213.c 2014-12-08 00:31:52.436418001 -0600
  51873. @@ -10,7 +10,6 @@
  51874. #include <linux/kernel.h>
  51875. #include <linux/module.h>
  51876. #include <linux/pci.h>
  51877. -#include <linux/init.h>
  51878. #include <linux/blkdev.h>
  51879. #include <linux/delay.h>
  51880. #include <linux/device.h>
  51881. diff -Nur linux-3.14.14/drivers/ata/pata_it821x.c linux-imx6-3.14/drivers/ata/pata_it821x.c
  51882. --- linux-3.14.14/drivers/ata/pata_it821x.c 2014-07-28 10:07:25.000000000 -0500
  51883. +++ linux-imx6-3.14/drivers/ata/pata_it821x.c 2014-12-08 00:31:52.436418001 -0600
  51884. @@ -72,7 +72,6 @@
  51885. #include <linux/kernel.h>
  51886. #include <linux/module.h>
  51887. #include <linux/pci.h>
  51888. -#include <linux/init.h>
  51889. #include <linux/blkdev.h>
  51890. #include <linux/delay.h>
  51891. #include <linux/slab.h>
  51892. diff -Nur linux-3.14.14/drivers/ata/pata_jmicron.c linux-imx6-3.14/drivers/ata/pata_jmicron.c
  51893. --- linux-3.14.14/drivers/ata/pata_jmicron.c 2014-07-28 10:07:25.000000000 -0500
  51894. +++ linux-imx6-3.14/drivers/ata/pata_jmicron.c 2014-12-08 00:31:52.436418001 -0600
  51895. @@ -10,7 +10,6 @@
  51896. #include <linux/kernel.h>
  51897. #include <linux/module.h>
  51898. #include <linux/pci.h>
  51899. -#include <linux/init.h>
  51900. #include <linux/blkdev.h>
  51901. #include <linux/delay.h>
  51902. #include <linux/device.h>
  51903. diff -Nur linux-3.14.14/drivers/ata/pata_marvell.c linux-imx6-3.14/drivers/ata/pata_marvell.c
  51904. --- linux-3.14.14/drivers/ata/pata_marvell.c 2014-07-28 10:07:25.000000000 -0500
  51905. +++ linux-imx6-3.14/drivers/ata/pata_marvell.c 2014-12-08 00:31:52.436418001 -0600
  51906. @@ -11,7 +11,6 @@
  51907. #include <linux/kernel.h>
  51908. #include <linux/module.h>
  51909. #include <linux/pci.h>
  51910. -#include <linux/init.h>
  51911. #include <linux/blkdev.h>
  51912. #include <linux/delay.h>
  51913. #include <linux/device.h>
  51914. diff -Nur linux-3.14.14/drivers/ata/pata_mpiix.c linux-imx6-3.14/drivers/ata/pata_mpiix.c
  51915. --- linux-3.14.14/drivers/ata/pata_mpiix.c 2014-07-28 10:07:25.000000000 -0500
  51916. +++ linux-imx6-3.14/drivers/ata/pata_mpiix.c 2014-12-08 00:31:52.436418001 -0600
  51917. @@ -28,7 +28,6 @@
  51918. #include <linux/kernel.h>
  51919. #include <linux/module.h>
  51920. #include <linux/pci.h>
  51921. -#include <linux/init.h>
  51922. #include <linux/blkdev.h>
  51923. #include <linux/delay.h>
  51924. #include <scsi/scsi_host.h>
  51925. diff -Nur linux-3.14.14/drivers/ata/pata_netcell.c linux-imx6-3.14/drivers/ata/pata_netcell.c
  51926. --- linux-3.14.14/drivers/ata/pata_netcell.c 2014-07-28 10:07:25.000000000 -0500
  51927. +++ linux-imx6-3.14/drivers/ata/pata_netcell.c 2014-12-08 00:31:52.436418001 -0600
  51928. @@ -7,7 +7,6 @@
  51929. #include <linux/kernel.h>
  51930. #include <linux/module.h>
  51931. #include <linux/pci.h>
  51932. -#include <linux/init.h>
  51933. #include <linux/blkdev.h>
  51934. #include <linux/delay.h>
  51935. #include <linux/device.h>
  51936. diff -Nur linux-3.14.14/drivers/ata/pata_ninja32.c linux-imx6-3.14/drivers/ata/pata_ninja32.c
  51937. --- linux-3.14.14/drivers/ata/pata_ninja32.c 2014-07-28 10:07:25.000000000 -0500
  51938. +++ linux-imx6-3.14/drivers/ata/pata_ninja32.c 2014-12-08 00:31:52.436418001 -0600
  51939. @@ -37,7 +37,6 @@
  51940. #include <linux/kernel.h>
  51941. #include <linux/module.h>
  51942. #include <linux/pci.h>
  51943. -#include <linux/init.h>
  51944. #include <linux/blkdev.h>
  51945. #include <linux/delay.h>
  51946. #include <scsi/scsi_host.h>
  51947. diff -Nur linux-3.14.14/drivers/ata/pata_ns87410.c linux-imx6-3.14/drivers/ata/pata_ns87410.c
  51948. --- linux-3.14.14/drivers/ata/pata_ns87410.c 2014-07-28 10:07:25.000000000 -0500
  51949. +++ linux-imx6-3.14/drivers/ata/pata_ns87410.c 2014-12-08 00:31:52.436418001 -0600
  51950. @@ -20,7 +20,6 @@
  51951. #include <linux/kernel.h>
  51952. #include <linux/module.h>
  51953. #include <linux/pci.h>
  51954. -#include <linux/init.h>
  51955. #include <linux/blkdev.h>
  51956. #include <linux/delay.h>
  51957. #include <scsi/scsi_host.h>
  51958. diff -Nur linux-3.14.14/drivers/ata/pata_ns87415.c linux-imx6-3.14/drivers/ata/pata_ns87415.c
  51959. --- linux-3.14.14/drivers/ata/pata_ns87415.c 2014-07-28 10:07:25.000000000 -0500
  51960. +++ linux-imx6-3.14/drivers/ata/pata_ns87415.c 2014-12-08 00:31:52.436418001 -0600
  51961. @@ -25,7 +25,6 @@
  51962. #include <linux/kernel.h>
  51963. #include <linux/module.h>
  51964. #include <linux/pci.h>
  51965. -#include <linux/init.h>
  51966. #include <linux/blkdev.h>
  51967. #include <linux/delay.h>
  51968. #include <linux/device.h>
  51969. diff -Nur linux-3.14.14/drivers/ata/pata_oldpiix.c linux-imx6-3.14/drivers/ata/pata_oldpiix.c
  51970. --- linux-3.14.14/drivers/ata/pata_oldpiix.c 2014-07-28 10:07:25.000000000 -0500
  51971. +++ linux-imx6-3.14/drivers/ata/pata_oldpiix.c 2014-12-08 00:31:52.436418001 -0600
  51972. @@ -16,7 +16,6 @@
  51973. #include <linux/kernel.h>
  51974. #include <linux/module.h>
  51975. #include <linux/pci.h>
  51976. -#include <linux/init.h>
  51977. #include <linux/blkdev.h>
  51978. #include <linux/delay.h>
  51979. #include <linux/device.h>
  51980. diff -Nur linux-3.14.14/drivers/ata/pata_opti.c linux-imx6-3.14/drivers/ata/pata_opti.c
  51981. --- linux-3.14.14/drivers/ata/pata_opti.c 2014-07-28 10:07:25.000000000 -0500
  51982. +++ linux-imx6-3.14/drivers/ata/pata_opti.c 2014-12-08 00:31:52.436418001 -0600
  51983. @@ -26,7 +26,6 @@
  51984. #include <linux/kernel.h>
  51985. #include <linux/module.h>
  51986. #include <linux/pci.h>
  51987. -#include <linux/init.h>
  51988. #include <linux/blkdev.h>
  51989. #include <linux/delay.h>
  51990. #include <scsi/scsi_host.h>
  51991. diff -Nur linux-3.14.14/drivers/ata/pata_optidma.c linux-imx6-3.14/drivers/ata/pata_optidma.c
  51992. --- linux-3.14.14/drivers/ata/pata_optidma.c 2014-07-28 10:07:25.000000000 -0500
  51993. +++ linux-imx6-3.14/drivers/ata/pata_optidma.c 2014-12-08 00:31:52.436418001 -0600
  51994. @@ -25,7 +25,6 @@
  51995. #include <linux/kernel.h>
  51996. #include <linux/module.h>
  51997. #include <linux/pci.h>
  51998. -#include <linux/init.h>
  51999. #include <linux/blkdev.h>
  52000. #include <linux/delay.h>
  52001. #include <scsi/scsi_host.h>
  52002. diff -Nur linux-3.14.14/drivers/ata/pata_pcmcia.c linux-imx6-3.14/drivers/ata/pata_pcmcia.c
  52003. --- linux-3.14.14/drivers/ata/pata_pcmcia.c 2014-07-28 10:07:25.000000000 -0500
  52004. +++ linux-imx6-3.14/drivers/ata/pata_pcmcia.c 2014-12-08 00:31:52.436418001 -0600
  52005. @@ -26,7 +26,6 @@
  52006. #include <linux/kernel.h>
  52007. #include <linux/module.h>
  52008. -#include <linux/init.h>
  52009. #include <linux/blkdev.h>
  52010. #include <linux/delay.h>
  52011. #include <linux/slab.h>
  52012. diff -Nur linux-3.14.14/drivers/ata/pata_pdc2027x.c linux-imx6-3.14/drivers/ata/pata_pdc2027x.c
  52013. --- linux-3.14.14/drivers/ata/pata_pdc2027x.c 2014-07-28 10:07:25.000000000 -0500
  52014. +++ linux-imx6-3.14/drivers/ata/pata_pdc2027x.c 2014-12-08 00:31:52.440418001 -0600
  52015. @@ -25,7 +25,6 @@
  52016. #include <linux/kernel.h>
  52017. #include <linux/module.h>
  52018. #include <linux/pci.h>
  52019. -#include <linux/init.h>
  52020. #include <linux/blkdev.h>
  52021. #include <linux/delay.h>
  52022. #include <linux/device.h>
  52023. diff -Nur linux-3.14.14/drivers/ata/pata_pdc202xx_old.c linux-imx6-3.14/drivers/ata/pata_pdc202xx_old.c
  52024. --- linux-3.14.14/drivers/ata/pata_pdc202xx_old.c 2014-07-28 10:07:25.000000000 -0500
  52025. +++ linux-imx6-3.14/drivers/ata/pata_pdc202xx_old.c 2014-12-08 00:31:52.440418001 -0600
  52026. @@ -15,7 +15,6 @@
  52027. #include <linux/kernel.h>
  52028. #include <linux/module.h>
  52029. #include <linux/pci.h>
  52030. -#include <linux/init.h>
  52031. #include <linux/blkdev.h>
  52032. #include <linux/delay.h>
  52033. #include <scsi/scsi_host.h>
  52034. diff -Nur linux-3.14.14/drivers/ata/pata_piccolo.c linux-imx6-3.14/drivers/ata/pata_piccolo.c
  52035. --- linux-3.14.14/drivers/ata/pata_piccolo.c 2014-07-28 10:07:25.000000000 -0500
  52036. +++ linux-imx6-3.14/drivers/ata/pata_piccolo.c 2014-12-08 00:31:52.440418001 -0600
  52037. @@ -18,7 +18,6 @@
  52038. #include <linux/kernel.h>
  52039. #include <linux/module.h>
  52040. #include <linux/pci.h>
  52041. -#include <linux/init.h>
  52042. #include <linux/blkdev.h>
  52043. #include <linux/delay.h>
  52044. #include <scsi/scsi_host.h>
  52045. diff -Nur linux-3.14.14/drivers/ata/pata_platform.c linux-imx6-3.14/drivers/ata/pata_platform.c
  52046. --- linux-3.14.14/drivers/ata/pata_platform.c 2014-07-28 10:07:25.000000000 -0500
  52047. +++ linux-imx6-3.14/drivers/ata/pata_platform.c 2014-12-08 00:31:52.440418001 -0600
  52048. @@ -13,7 +13,6 @@
  52049. */
  52050. #include <linux/kernel.h>
  52051. #include <linux/module.h>
  52052. -#include <linux/init.h>
  52053. #include <linux/blkdev.h>
  52054. #include <scsi/scsi_host.h>
  52055. #include <linux/ata.h>
  52056. diff -Nur linux-3.14.14/drivers/ata/pata_pxa.c linux-imx6-3.14/drivers/ata/pata_pxa.c
  52057. --- linux-3.14.14/drivers/ata/pata_pxa.c 2014-07-28 10:07:25.000000000 -0500
  52058. +++ linux-imx6-3.14/drivers/ata/pata_pxa.c 2014-12-08 00:31:52.440418001 -0600
  52059. @@ -20,7 +20,6 @@
  52060. #include <linux/kernel.h>
  52061. #include <linux/module.h>
  52062. -#include <linux/init.h>
  52063. #include <linux/blkdev.h>
  52064. #include <linux/ata.h>
  52065. #include <linux/libata.h>
  52066. diff -Nur linux-3.14.14/drivers/ata/pata_radisys.c linux-imx6-3.14/drivers/ata/pata_radisys.c
  52067. --- linux-3.14.14/drivers/ata/pata_radisys.c 2014-07-28 10:07:25.000000000 -0500
  52068. +++ linux-imx6-3.14/drivers/ata/pata_radisys.c 2014-12-08 00:31:52.440418001 -0600
  52069. @@ -15,7 +15,6 @@
  52070. #include <linux/kernel.h>
  52071. #include <linux/module.h>
  52072. #include <linux/pci.h>
  52073. -#include <linux/init.h>
  52074. #include <linux/blkdev.h>
  52075. #include <linux/delay.h>
  52076. #include <linux/device.h>
  52077. diff -Nur linux-3.14.14/drivers/ata/pata_rdc.c linux-imx6-3.14/drivers/ata/pata_rdc.c
  52078. --- linux-3.14.14/drivers/ata/pata_rdc.c 2014-07-28 10:07:25.000000000 -0500
  52079. +++ linux-imx6-3.14/drivers/ata/pata_rdc.c 2014-12-08 00:31:52.440418001 -0600
  52080. @@ -24,7 +24,6 @@
  52081. #include <linux/kernel.h>
  52082. #include <linux/module.h>
  52083. #include <linux/pci.h>
  52084. -#include <linux/init.h>
  52085. #include <linux/blkdev.h>
  52086. #include <linux/delay.h>
  52087. #include <linux/device.h>
  52088. diff -Nur linux-3.14.14/drivers/ata/pata_rz1000.c linux-imx6-3.14/drivers/ata/pata_rz1000.c
  52089. --- linux-3.14.14/drivers/ata/pata_rz1000.c 2014-07-28 10:07:25.000000000 -0500
  52090. +++ linux-imx6-3.14/drivers/ata/pata_rz1000.c 2014-12-08 00:31:52.440418001 -0600
  52091. @@ -14,7 +14,6 @@
  52092. #include <linux/kernel.h>
  52093. #include <linux/module.h>
  52094. #include <linux/pci.h>
  52095. -#include <linux/init.h>
  52096. #include <linux/blkdev.h>
  52097. #include <linux/delay.h>
  52098. #include <scsi/scsi_host.h>
  52099. diff -Nur linux-3.14.14/drivers/ata/pata_sc1200.c linux-imx6-3.14/drivers/ata/pata_sc1200.c
  52100. --- linux-3.14.14/drivers/ata/pata_sc1200.c 2014-07-28 10:07:25.000000000 -0500
  52101. +++ linux-imx6-3.14/drivers/ata/pata_sc1200.c 2014-12-08 00:31:52.440418001 -0600
  52102. @@ -32,7 +32,6 @@
  52103. #include <linux/kernel.h>
  52104. #include <linux/module.h>
  52105. #include <linux/pci.h>
  52106. -#include <linux/init.h>
  52107. #include <linux/blkdev.h>
  52108. #include <linux/delay.h>
  52109. #include <scsi/scsi_host.h>
  52110. diff -Nur linux-3.14.14/drivers/ata/pata_scc.c linux-imx6-3.14/drivers/ata/pata_scc.c
  52111. --- linux-3.14.14/drivers/ata/pata_scc.c 2014-07-28 10:07:25.000000000 -0500
  52112. +++ linux-imx6-3.14/drivers/ata/pata_scc.c 2014-12-08 00:31:52.440418001 -0600
  52113. @@ -35,7 +35,6 @@
  52114. #include <linux/kernel.h>
  52115. #include <linux/module.h>
  52116. #include <linux/pci.h>
  52117. -#include <linux/init.h>
  52118. #include <linux/blkdev.h>
  52119. #include <linux/delay.h>
  52120. #include <linux/device.h>
  52121. diff -Nur linux-3.14.14/drivers/ata/pata_sch.c linux-imx6-3.14/drivers/ata/pata_sch.c
  52122. --- linux-3.14.14/drivers/ata/pata_sch.c 2014-07-28 10:07:25.000000000 -0500
  52123. +++ linux-imx6-3.14/drivers/ata/pata_sch.c 2014-12-08 00:31:52.440418001 -0600
  52124. @@ -27,7 +27,6 @@
  52125. #include <linux/kernel.h>
  52126. #include <linux/module.h>
  52127. #include <linux/pci.h>
  52128. -#include <linux/init.h>
  52129. #include <linux/blkdev.h>
  52130. #include <linux/delay.h>
  52131. #include <linux/device.h>
  52132. diff -Nur linux-3.14.14/drivers/ata/pata_serverworks.c linux-imx6-3.14/drivers/ata/pata_serverworks.c
  52133. --- linux-3.14.14/drivers/ata/pata_serverworks.c 2014-07-28 10:07:25.000000000 -0500
  52134. +++ linux-imx6-3.14/drivers/ata/pata_serverworks.c 2014-12-08 00:31:52.440418001 -0600
  52135. @@ -34,7 +34,6 @@
  52136. #include <linux/kernel.h>
  52137. #include <linux/module.h>
  52138. #include <linux/pci.h>
  52139. -#include <linux/init.h>
  52140. #include <linux/blkdev.h>
  52141. #include <linux/delay.h>
  52142. #include <scsi/scsi_host.h>
  52143. diff -Nur linux-3.14.14/drivers/ata/pata_sil680.c linux-imx6-3.14/drivers/ata/pata_sil680.c
  52144. --- linux-3.14.14/drivers/ata/pata_sil680.c 2014-07-28 10:07:25.000000000 -0500
  52145. +++ linux-imx6-3.14/drivers/ata/pata_sil680.c 2014-12-08 00:31:52.440418001 -0600
  52146. @@ -25,7 +25,6 @@
  52147. #include <linux/kernel.h>
  52148. #include <linux/module.h>
  52149. #include <linux/pci.h>
  52150. -#include <linux/init.h>
  52151. #include <linux/blkdev.h>
  52152. #include <linux/delay.h>
  52153. #include <scsi/scsi_host.h>
  52154. diff -Nur linux-3.14.14/drivers/ata/pata_sis.c linux-imx6-3.14/drivers/ata/pata_sis.c
  52155. --- linux-3.14.14/drivers/ata/pata_sis.c 2014-07-28 10:07:25.000000000 -0500
  52156. +++ linux-imx6-3.14/drivers/ata/pata_sis.c 2014-12-08 00:31:52.440418001 -0600
  52157. @@ -26,7 +26,6 @@
  52158. #include <linux/kernel.h>
  52159. #include <linux/module.h>
  52160. #include <linux/pci.h>
  52161. -#include <linux/init.h>
  52162. #include <linux/blkdev.h>
  52163. #include <linux/delay.h>
  52164. #include <linux/device.h>
  52165. diff -Nur linux-3.14.14/drivers/ata/pata_sl82c105.c linux-imx6-3.14/drivers/ata/pata_sl82c105.c
  52166. --- linux-3.14.14/drivers/ata/pata_sl82c105.c 2014-07-28 10:07:25.000000000 -0500
  52167. +++ linux-imx6-3.14/drivers/ata/pata_sl82c105.c 2014-12-08 00:31:52.440418001 -0600
  52168. @@ -19,7 +19,6 @@
  52169. #include <linux/kernel.h>
  52170. #include <linux/module.h>
  52171. #include <linux/pci.h>
  52172. -#include <linux/init.h>
  52173. #include <linux/blkdev.h>
  52174. #include <linux/delay.h>
  52175. #include <scsi/scsi_host.h>
  52176. diff -Nur linux-3.14.14/drivers/ata/pata_triflex.c linux-imx6-3.14/drivers/ata/pata_triflex.c
  52177. --- linux-3.14.14/drivers/ata/pata_triflex.c 2014-07-28 10:07:25.000000000 -0500
  52178. +++ linux-imx6-3.14/drivers/ata/pata_triflex.c 2014-12-08 00:31:52.440418001 -0600
  52179. @@ -36,7 +36,6 @@
  52180. #include <linux/kernel.h>
  52181. #include <linux/module.h>
  52182. #include <linux/pci.h>
  52183. -#include <linux/init.h>
  52184. #include <linux/blkdev.h>
  52185. #include <linux/delay.h>
  52186. #include <scsi/scsi_host.h>
  52187. diff -Nur linux-3.14.14/drivers/ata/pata_via.c linux-imx6-3.14/drivers/ata/pata_via.c
  52188. --- linux-3.14.14/drivers/ata/pata_via.c 2014-07-28 10:07:25.000000000 -0500
  52189. +++ linux-imx6-3.14/drivers/ata/pata_via.c 2014-12-08 00:31:52.440418001 -0600
  52190. @@ -55,7 +55,6 @@
  52191. #include <linux/kernel.h>
  52192. #include <linux/module.h>
  52193. #include <linux/pci.h>
  52194. -#include <linux/init.h>
  52195. #include <linux/blkdev.h>
  52196. #include <linux/delay.h>
  52197. #include <linux/gfp.h>
  52198. diff -Nur linux-3.14.14/drivers/ata/pdc_adma.c linux-imx6-3.14/drivers/ata/pdc_adma.c
  52199. --- linux-3.14.14/drivers/ata/pdc_adma.c 2014-07-28 10:07:25.000000000 -0500
  52200. +++ linux-imx6-3.14/drivers/ata/pdc_adma.c 2014-12-08 00:31:52.440418001 -0600
  52201. @@ -36,7 +36,6 @@
  52202. #include <linux/module.h>
  52203. #include <linux/gfp.h>
  52204. #include <linux/pci.h>
  52205. -#include <linux/init.h>
  52206. #include <linux/blkdev.h>
  52207. #include <linux/delay.h>
  52208. #include <linux/interrupt.h>
  52209. diff -Nur linux-3.14.14/drivers/ata/sata_dwc_460ex.c linux-imx6-3.14/drivers/ata/sata_dwc_460ex.c
  52210. --- linux-3.14.14/drivers/ata/sata_dwc_460ex.c 2014-07-28 10:07:25.000000000 -0500
  52211. +++ linux-imx6-3.14/drivers/ata/sata_dwc_460ex.c 2014-12-08 00:31:52.440418001 -0600
  52212. @@ -29,7 +29,6 @@
  52213. #include <linux/kernel.h>
  52214. #include <linux/module.h>
  52215. -#include <linux/init.h>
  52216. #include <linux/device.h>
  52217. #include <linux/of_address.h>
  52218. #include <linux/of_irq.h>
  52219. diff -Nur linux-3.14.14/drivers/ata/sata_highbank.c linux-imx6-3.14/drivers/ata/sata_highbank.c
  52220. --- linux-3.14.14/drivers/ata/sata_highbank.c 2014-07-28 10:07:25.000000000 -0500
  52221. +++ linux-imx6-3.14/drivers/ata/sata_highbank.c 2014-12-08 00:31:52.440418001 -0600
  52222. @@ -19,7 +19,6 @@
  52223. #include <linux/kernel.h>
  52224. #include <linux/gfp.h>
  52225. #include <linux/module.h>
  52226. -#include <linux/init.h>
  52227. #include <linux/types.h>
  52228. #include <linux/err.h>
  52229. #include <linux/io.h>
  52230. @@ -403,6 +402,7 @@
  52231. static const unsigned long timing[] = { 5, 100, 500};
  52232. struct ata_port *ap = link->ap;
  52233. struct ahci_port_priv *pp = ap->private_data;
  52234. + struct ahci_host_priv *hpriv = ap->host->private_data;
  52235. u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
  52236. struct ata_taskfile tf;
  52237. bool online;
  52238. @@ -431,7 +431,7 @@
  52239. break;
  52240. } while (!online && retry--);
  52241. - ahci_start_engine(ap);
  52242. + hpriv->start_engine(ap);
  52243. if (online)
  52244. *class = ahci_dev_classify(ap);
  52245. diff -Nur linux-3.14.14/drivers/ata/sata_nv.c linux-imx6-3.14/drivers/ata/sata_nv.c
  52246. --- linux-3.14.14/drivers/ata/sata_nv.c 2014-07-28 10:07:25.000000000 -0500
  52247. +++ linux-imx6-3.14/drivers/ata/sata_nv.c 2014-12-08 00:31:52.444418001 -0600
  52248. @@ -40,7 +40,6 @@
  52249. #include <linux/module.h>
  52250. #include <linux/gfp.h>
  52251. #include <linux/pci.h>
  52252. -#include <linux/init.h>
  52253. #include <linux/blkdev.h>
  52254. #include <linux/delay.h>
  52255. #include <linux/interrupt.h>
  52256. diff -Nur linux-3.14.14/drivers/ata/sata_promise.c linux-imx6-3.14/drivers/ata/sata_promise.c
  52257. --- linux-3.14.14/drivers/ata/sata_promise.c 2014-07-28 10:07:25.000000000 -0500
  52258. +++ linux-imx6-3.14/drivers/ata/sata_promise.c 2014-12-08 00:31:52.444418001 -0600
  52259. @@ -35,7 +35,6 @@
  52260. #include <linux/module.h>
  52261. #include <linux/gfp.h>
  52262. #include <linux/pci.h>
  52263. -#include <linux/init.h>
  52264. #include <linux/blkdev.h>
  52265. #include <linux/delay.h>
  52266. #include <linux/interrupt.h>
  52267. diff -Nur linux-3.14.14/drivers/ata/sata_qstor.c linux-imx6-3.14/drivers/ata/sata_qstor.c
  52268. --- linux-3.14.14/drivers/ata/sata_qstor.c 2014-07-28 10:07:25.000000000 -0500
  52269. +++ linux-imx6-3.14/drivers/ata/sata_qstor.c 2014-12-08 00:31:52.444418001 -0600
  52270. @@ -31,7 +31,6 @@
  52271. #include <linux/module.h>
  52272. #include <linux/gfp.h>
  52273. #include <linux/pci.h>
  52274. -#include <linux/init.h>
  52275. #include <linux/blkdev.h>
  52276. #include <linux/delay.h>
  52277. #include <linux/interrupt.h>
  52278. diff -Nur linux-3.14.14/drivers/ata/sata_sil.c linux-imx6-3.14/drivers/ata/sata_sil.c
  52279. --- linux-3.14.14/drivers/ata/sata_sil.c 2014-07-28 10:07:25.000000000 -0500
  52280. +++ linux-imx6-3.14/drivers/ata/sata_sil.c 2014-12-08 00:31:52.444418001 -0600
  52281. @@ -37,7 +37,6 @@
  52282. #include <linux/kernel.h>
  52283. #include <linux/module.h>
  52284. #include <linux/pci.h>
  52285. -#include <linux/init.h>
  52286. #include <linux/blkdev.h>
  52287. #include <linux/delay.h>
  52288. #include <linux/interrupt.h>
  52289. diff -Nur linux-3.14.14/drivers/ata/sata_sis.c linux-imx6-3.14/drivers/ata/sata_sis.c
  52290. --- linux-3.14.14/drivers/ata/sata_sis.c 2014-07-28 10:07:25.000000000 -0500
  52291. +++ linux-imx6-3.14/drivers/ata/sata_sis.c 2014-12-08 00:31:52.444418001 -0600
  52292. @@ -33,7 +33,6 @@
  52293. #include <linux/kernel.h>
  52294. #include <linux/module.h>
  52295. #include <linux/pci.h>
  52296. -#include <linux/init.h>
  52297. #include <linux/blkdev.h>
  52298. #include <linux/delay.h>
  52299. #include <linux/interrupt.h>
  52300. diff -Nur linux-3.14.14/drivers/ata/sata_svw.c linux-imx6-3.14/drivers/ata/sata_svw.c
  52301. --- linux-3.14.14/drivers/ata/sata_svw.c 2014-07-28 10:07:25.000000000 -0500
  52302. +++ linux-imx6-3.14/drivers/ata/sata_svw.c 2014-12-08 00:31:52.444418001 -0600
  52303. @@ -39,7 +39,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/interrupt.h>
  52311. diff -Nur linux-3.14.14/drivers/ata/sata_sx4.c linux-imx6-3.14/drivers/ata/sata_sx4.c
  52312. --- linux-3.14.14/drivers/ata/sata_sx4.c 2014-07-28 10:07:25.000000000 -0500
  52313. +++ linux-imx6-3.14/drivers/ata/sata_sx4.c 2014-12-08 00:31:52.444418001 -0600
  52314. @@ -82,7 +82,6 @@
  52315. #include <linux/module.h>
  52316. #include <linux/pci.h>
  52317. #include <linux/slab.h>
  52318. -#include <linux/init.h>
  52319. #include <linux/blkdev.h>
  52320. #include <linux/delay.h>
  52321. #include <linux/interrupt.h>
  52322. diff -Nur linux-3.14.14/drivers/ata/sata_uli.c linux-imx6-3.14/drivers/ata/sata_uli.c
  52323. --- linux-3.14.14/drivers/ata/sata_uli.c 2014-07-28 10:07:25.000000000 -0500
  52324. +++ linux-imx6-3.14/drivers/ata/sata_uli.c 2014-12-08 00:31:52.444418001 -0600
  52325. @@ -28,7 +28,6 @@
  52326. #include <linux/module.h>
  52327. #include <linux/gfp.h>
  52328. #include <linux/pci.h>
  52329. -#include <linux/init.h>
  52330. #include <linux/blkdev.h>
  52331. #include <linux/delay.h>
  52332. #include <linux/interrupt.h>
  52333. diff -Nur linux-3.14.14/drivers/ata/sata_via.c linux-imx6-3.14/drivers/ata/sata_via.c
  52334. --- linux-3.14.14/drivers/ata/sata_via.c 2014-07-28 10:07:25.000000000 -0500
  52335. +++ linux-imx6-3.14/drivers/ata/sata_via.c 2014-12-08 00:31:52.444418001 -0600
  52336. @@ -36,7 +36,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 <linux/device.h>
  52344. diff -Nur linux-3.14.14/drivers/ata/sata_vsc.c linux-imx6-3.14/drivers/ata/sata_vsc.c
  52345. --- linux-3.14.14/drivers/ata/sata_vsc.c 2014-07-28 10:07:25.000000000 -0500
  52346. +++ linux-imx6-3.14/drivers/ata/sata_vsc.c 2014-12-08 00:31:52.444418001 -0600
  52347. @@ -37,7 +37,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/interrupt.h>
  52355. diff -Nur linux-3.14.14/drivers/base/bus.c linux-imx6-3.14/drivers/base/bus.c
  52356. --- linux-3.14.14/drivers/base/bus.c 2014-07-28 10:07:25.000000000 -0500
  52357. +++ linux-imx6-3.14/drivers/base/bus.c 2014-12-08 00:31:52.456418001 -0600
  52358. @@ -1218,7 +1218,7 @@
  52359. * with the name of the subsystem. The root device can carry subsystem-
  52360. * wide attributes. All registered devices are below this single root
  52361. * device and are named after the subsystem with a simple enumeration
  52362. - * number appended. The registered devices are not explicitely named;
  52363. + * number appended. The registered devices are not explicitly named;
  52364. * only 'id' in the device needs to be set.
  52365. *
  52366. * Do not use this interface for anything new, it exists for compatibility
  52367. diff -Nur linux-3.14.14/drivers/base/cpu.c linux-imx6-3.14/drivers/base/cpu.c
  52368. --- linux-3.14.14/drivers/base/cpu.c 2014-07-28 10:07:25.000000000 -0500
  52369. +++ linux-imx6-3.14/drivers/base/cpu.c 2014-12-08 00:31:52.456418001 -0600
  52370. @@ -15,6 +15,7 @@
  52371. #include <linux/percpu.h>
  52372. #include <linux/acpi.h>
  52373. #include <linux/of.h>
  52374. +#include <linux/cpufeature.h>
  52375. #include "base.h"
  52376. @@ -286,6 +287,45 @@
  52377. */
  52378. }
  52379. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  52380. +#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
  52381. +static ssize_t print_cpu_modalias(struct device *dev,
  52382. + struct device_attribute *attr,
  52383. + char *buf)
  52384. +{
  52385. + ssize_t n;
  52386. + u32 i;
  52387. +
  52388. + n = sprintf(buf, "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:",
  52389. + CPU_FEATURE_TYPEVAL);
  52390. +
  52391. + for (i = 0; i < MAX_CPU_FEATURES; i++)
  52392. + if (cpu_have_feature(i)) {
  52393. + if (PAGE_SIZE < n + sizeof(",XXXX\n")) {
  52394. + WARN(1, "CPU features overflow page\n");
  52395. + break;
  52396. + }
  52397. + n += sprintf(&buf[n], ",%04X", i);
  52398. + }
  52399. + buf[n++] = '\n';
  52400. + return n;
  52401. +}
  52402. +#else
  52403. +#define print_cpu_modalias arch_print_cpu_modalias
  52404. +#endif
  52405. +
  52406. +static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
  52407. +{
  52408. + char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
  52409. + if (buf) {
  52410. + print_cpu_modalias(NULL, NULL, buf);
  52411. + add_uevent_var(env, "MODALIAS=%s", buf);
  52412. + kfree(buf);
  52413. + }
  52414. + return 0;
  52415. +}
  52416. +#endif
  52417. +
  52418. /*
  52419. * register_cpu - Setup a sysfs device for a CPU.
  52420. * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
  52421. @@ -306,8 +346,8 @@
  52422. cpu->dev.offline_disabled = !cpu->hotpluggable;
  52423. cpu->dev.offline = !cpu_online(num);
  52424. cpu->dev.of_node = of_get_cpu_node(num, NULL);
  52425. -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
  52426. - cpu->dev.bus->uevent = arch_cpu_uevent;
  52427. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  52428. + cpu->dev.bus->uevent = cpu_uevent;
  52429. #endif
  52430. cpu->dev.groups = common_cpu_attr_groups;
  52431. if (cpu->hotpluggable)
  52432. @@ -330,8 +370,8 @@
  52433. }
  52434. EXPORT_SYMBOL_GPL(get_cpu_device);
  52435. -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
  52436. -static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL);
  52437. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  52438. +static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
  52439. #endif
  52440. static struct attribute *cpu_root_attrs[] = {
  52441. @@ -344,7 +384,7 @@
  52442. &cpu_attrs[2].attr.attr,
  52443. &dev_attr_kernel_max.attr,
  52444. &dev_attr_offline.attr,
  52445. -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
  52446. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  52447. &dev_attr_modalias.attr,
  52448. #endif
  52449. NULL
  52450. diff -Nur linux-3.14.14/drivers/base/dma-buf.c linux-imx6-3.14/drivers/base/dma-buf.c
  52451. --- linux-3.14.14/drivers/base/dma-buf.c 2014-07-28 10:07:25.000000000 -0500
  52452. +++ linux-imx6-3.14/drivers/base/dma-buf.c 2014-12-08 00:31:52.456418001 -0600
  52453. @@ -251,9 +251,8 @@
  52454. * @dmabuf: [in] buffer to attach device to.
  52455. * @dev: [in] device to be attached.
  52456. *
  52457. - * Returns struct dma_buf_attachment * for this attachment; may return negative
  52458. - * error codes.
  52459. - *
  52460. + * Returns struct dma_buf_attachment * for this attachment; returns ERR_PTR on
  52461. + * error.
  52462. */
  52463. struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
  52464. struct device *dev)
  52465. @@ -319,9 +318,8 @@
  52466. * @attach: [in] attachment whose scatterlist is to be returned
  52467. * @direction: [in] direction of DMA transfer
  52468. *
  52469. - * Returns sg_table containing the scatterlist to be returned; may return NULL
  52470. - * or ERR_PTR.
  52471. - *
  52472. + * Returns sg_table containing the scatterlist to be returned; returns ERR_PTR
  52473. + * on error.
  52474. */
  52475. struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
  52476. enum dma_data_direction direction)
  52477. @@ -334,6 +332,8 @@
  52478. return ERR_PTR(-EINVAL);
  52479. sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction);
  52480. + if (!sg_table)
  52481. + sg_table = ERR_PTR(-ENOMEM);
  52482. return sg_table;
  52483. }
  52484. @@ -544,6 +544,8 @@
  52485. * These calls are optional in drivers. The intended use for them
  52486. * is for mapping objects linear in kernel space for high use objects.
  52487. * Please attempt to use kmap/kunmap before thinking about these interfaces.
  52488. + *
  52489. + * Returns NULL on error.
  52490. */
  52491. void *dma_buf_vmap(struct dma_buf *dmabuf)
  52492. {
  52493. @@ -566,7 +568,9 @@
  52494. BUG_ON(dmabuf->vmap_ptr);
  52495. ptr = dmabuf->ops->vmap(dmabuf);
  52496. - if (IS_ERR_OR_NULL(ptr))
  52497. + if (WARN_ON_ONCE(IS_ERR(ptr)))
  52498. + ptr = NULL;
  52499. + if (!ptr)
  52500. goto out_unlock;
  52501. dmabuf->vmap_ptr = ptr;
  52502. diff -Nur linux-3.14.14/drivers/base/dma-contiguous.c linux-imx6-3.14/drivers/base/dma-contiguous.c
  52503. --- linux-3.14.14/drivers/base/dma-contiguous.c 2014-07-28 10:07:25.000000000 -0500
  52504. +++ linux-imx6-3.14/drivers/base/dma-contiguous.c 2014-12-08 00:31:52.456418001 -0600
  52505. @@ -24,22 +24,9 @@
  52506. #include <linux/memblock.h>
  52507. #include <linux/err.h>
  52508. -#include <linux/mm.h>
  52509. -#include <linux/mutex.h>
  52510. -#include <linux/page-isolation.h>
  52511. #include <linux/sizes.h>
  52512. -#include <linux/slab.h>
  52513. -#include <linux/swap.h>
  52514. -#include <linux/mm_types.h>
  52515. #include <linux/dma-contiguous.h>
  52516. -
  52517. -struct cma {
  52518. - unsigned long base_pfn;
  52519. - unsigned long count;
  52520. - unsigned long *bitmap;
  52521. -};
  52522. -
  52523. -struct cma *dma_contiguous_default_area;
  52524. +#include <linux/cma.h>
  52525. #ifdef CONFIG_CMA_SIZE_MBYTES
  52526. #define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
  52527. @@ -47,6 +34,8 @@
  52528. #define CMA_SIZE_MBYTES 0
  52529. #endif
  52530. +struct cma *dma_contiguous_default_area;
  52531. +
  52532. /*
  52533. * Default global CMA area size can be defined in kernel's .config.
  52534. * This is useful mainly for distro maintainers to create a kernel
  52535. @@ -59,11 +48,22 @@
  52536. */
  52537. static const phys_addr_t size_bytes = CMA_SIZE_MBYTES * SZ_1M;
  52538. static phys_addr_t size_cmdline = -1;
  52539. +static phys_addr_t base_cmdline;
  52540. +static phys_addr_t limit_cmdline;
  52541. static int __init early_cma(char *p)
  52542. {
  52543. pr_debug("%s(%s)\n", __func__, p);
  52544. size_cmdline = memparse(p, &p);
  52545. + if (*p != '@')
  52546. + return 0;
  52547. + base_cmdline = memparse(p + 1, &p);
  52548. + if (*p != '-') {
  52549. + limit_cmdline = base_cmdline + size_cmdline;
  52550. + return 0;
  52551. + }
  52552. + limit_cmdline = memparse(p + 1, &p);
  52553. +
  52554. return 0;
  52555. }
  52556. early_param("cma", early_cma);
  52557. @@ -107,11 +107,18 @@
  52558. void __init dma_contiguous_reserve(phys_addr_t limit)
  52559. {
  52560. phys_addr_t selected_size = 0;
  52561. + phys_addr_t selected_base = 0;
  52562. + phys_addr_t selected_limit = limit;
  52563. + bool fixed = false;
  52564. pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit);
  52565. if (size_cmdline != -1) {
  52566. selected_size = size_cmdline;
  52567. + selected_base = base_cmdline;
  52568. + selected_limit = min_not_zero(limit_cmdline, limit);
  52569. + if (base_cmdline + size_cmdline == limit_cmdline)
  52570. + fixed = true;
  52571. } else {
  52572. #ifdef CONFIG_CMA_SIZE_SEL_MBYTES
  52573. selected_size = size_bytes;
  52574. @@ -128,68 +135,12 @@
  52575. pr_debug("%s: reserving %ld MiB for global area\n", __func__,
  52576. (unsigned long)selected_size / SZ_1M);
  52577. - dma_contiguous_reserve_area(selected_size, 0, limit,
  52578. - &dma_contiguous_default_area);
  52579. - }
  52580. -};
  52581. -
  52582. -static DEFINE_MUTEX(cma_mutex);
  52583. -
  52584. -static int __init cma_activate_area(struct cma *cma)
  52585. -{
  52586. - int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long);
  52587. - unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;
  52588. - unsigned i = cma->count >> pageblock_order;
  52589. - struct zone *zone;
  52590. -
  52591. - cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
  52592. -
  52593. - if (!cma->bitmap)
  52594. - return -ENOMEM;
  52595. -
  52596. - WARN_ON_ONCE(!pfn_valid(pfn));
  52597. - zone = page_zone(pfn_to_page(pfn));
  52598. -
  52599. - do {
  52600. - unsigned j;
  52601. - base_pfn = pfn;
  52602. - for (j = pageblock_nr_pages; j; --j, pfn++) {
  52603. - WARN_ON_ONCE(!pfn_valid(pfn));
  52604. - /*
  52605. - * alloc_contig_range requires the pfn range
  52606. - * specified to be in the same zone. Make this
  52607. - * simple by forcing the entire CMA resv range
  52608. - * to be in the same zone.
  52609. - */
  52610. - if (page_zone(pfn_to_page(pfn)) != zone)
  52611. - goto err;
  52612. - }
  52613. - init_cma_reserved_pageblock(pfn_to_page(base_pfn));
  52614. - } while (--i);
  52615. -
  52616. - return 0;
  52617. -
  52618. -err:
  52619. - kfree(cma->bitmap);
  52620. - return -EINVAL;
  52621. -}
  52622. -
  52623. -static struct cma cma_areas[MAX_CMA_AREAS];
  52624. -static unsigned cma_area_count;
  52625. -
  52626. -static int __init cma_init_reserved_areas(void)
  52627. -{
  52628. - int i;
  52629. -
  52630. - for (i = 0; i < cma_area_count; i++) {
  52631. - int ret = cma_activate_area(&cma_areas[i]);
  52632. - if (ret)
  52633. - return ret;
  52634. + dma_contiguous_reserve_area(selected_size, selected_base,
  52635. + selected_limit,
  52636. + &dma_contiguous_default_area,
  52637. + fixed);
  52638. }
  52639. -
  52640. - return 0;
  52641. }
  52642. -core_initcall(cma_init_reserved_areas);
  52643. /**
  52644. * dma_contiguous_reserve_area() - reserve custom contiguous area
  52645. @@ -197,78 +148,32 @@
  52646. * @base: Base address of the reserved area optional, use 0 for any
  52647. * @limit: End address of the reserved memory (optional, 0 for any).
  52648. * @res_cma: Pointer to store the created cma region.
  52649. + * @fixed: hint about where to place the reserved area
  52650. *
  52651. * This function reserves memory from early allocator. It should be
  52652. * called by arch specific code once the early allocator (memblock or bootmem)
  52653. * has been activated and all other subsystems have already allocated/reserved
  52654. * memory. This function allows to create custom reserved areas for specific
  52655. * devices.
  52656. + *
  52657. + * If @fixed is true, reserve contiguous area at exactly @base. If false,
  52658. + * reserve in range from @base to @limit.
  52659. */
  52660. int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
  52661. - phys_addr_t limit, struct cma **res_cma)
  52662. + phys_addr_t limit, struct cma **res_cma,
  52663. + bool fixed)
  52664. {
  52665. - struct cma *cma = &cma_areas[cma_area_count];
  52666. - phys_addr_t alignment;
  52667. - int ret = 0;
  52668. -
  52669. - pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
  52670. - (unsigned long)size, (unsigned long)base,
  52671. - (unsigned long)limit);
  52672. -
  52673. - /* Sanity checks */
  52674. - if (cma_area_count == ARRAY_SIZE(cma_areas)) {
  52675. - pr_err("Not enough slots for CMA reserved regions!\n");
  52676. - return -ENOSPC;
  52677. - }
  52678. -
  52679. - if (!size)
  52680. - return -EINVAL;
  52681. -
  52682. - /* Sanitise input arguments */
  52683. - alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
  52684. - base = ALIGN(base, alignment);
  52685. - size = ALIGN(size, alignment);
  52686. - limit &= ~(alignment - 1);
  52687. -
  52688. - /* Reserve memory */
  52689. - if (base) {
  52690. - if (memblock_is_region_reserved(base, size) ||
  52691. - memblock_reserve(base, size) < 0) {
  52692. - ret = -EBUSY;
  52693. - goto err;
  52694. - }
  52695. - } else {
  52696. - /*
  52697. - * Use __memblock_alloc_base() since
  52698. - * memblock_alloc_base() panic()s.
  52699. - */
  52700. - phys_addr_t addr = __memblock_alloc_base(size, alignment, limit);
  52701. - if (!addr) {
  52702. - ret = -ENOMEM;
  52703. - goto err;
  52704. - } else {
  52705. - base = addr;
  52706. - }
  52707. - }
  52708. -
  52709. - /*
  52710. - * Each reserved area must be initialised later, when more kernel
  52711. - * subsystems (like slab allocator) are available.
  52712. - */
  52713. - cma->base_pfn = PFN_DOWN(base);
  52714. - cma->count = size >> PAGE_SHIFT;
  52715. - *res_cma = cma;
  52716. - cma_area_count++;
  52717. + int ret;
  52718. - pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
  52719. - (unsigned long)base);
  52720. + ret = cma_declare_contiguous(base, size, limit, 0, 0, fixed, res_cma);
  52721. + if (ret)
  52722. + return ret;
  52723. /* Architecture specific contiguous memory fixup. */
  52724. - dma_contiguous_early_fixup(base, size);
  52725. + dma_contiguous_early_fixup(cma_get_base(*res_cma),
  52726. + cma_get_size(*res_cma));
  52727. +
  52728. return 0;
  52729. -err:
  52730. - pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
  52731. - return ret;
  52732. }
  52733. /**
  52734. @@ -279,57 +184,16 @@
  52735. *
  52736. * This function allocates memory buffer for specified device. It uses
  52737. * device specific contiguous memory area if available or the default
  52738. - * global one. Requires architecture specific get_dev_cma_area() helper
  52739. + * global one. Requires architecture specific dev_get_cma_area() helper
  52740. * function.
  52741. */
  52742. struct page *dma_alloc_from_contiguous(struct device *dev, int count,
  52743. unsigned int align)
  52744. {
  52745. - unsigned long mask, pfn, pageno, start = 0;
  52746. - struct cma *cma = dev_get_cma_area(dev);
  52747. - struct page *page = NULL;
  52748. - int ret;
  52749. -
  52750. - if (!cma || !cma->count)
  52751. - return NULL;
  52752. -
  52753. if (align > CONFIG_CMA_ALIGNMENT)
  52754. align = CONFIG_CMA_ALIGNMENT;
  52755. - pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma,
  52756. - count, align);
  52757. -
  52758. - if (!count)
  52759. - return NULL;
  52760. -
  52761. - mask = (1 << align) - 1;
  52762. -
  52763. - mutex_lock(&cma_mutex);
  52764. -
  52765. - for (;;) {
  52766. - pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count,
  52767. - start, count, mask);
  52768. - if (pageno >= cma->count)
  52769. - break;
  52770. -
  52771. - pfn = cma->base_pfn + pageno;
  52772. - ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
  52773. - if (ret == 0) {
  52774. - bitmap_set(cma->bitmap, pageno, count);
  52775. - page = pfn_to_page(pfn);
  52776. - break;
  52777. - } else if (ret != -EBUSY) {
  52778. - break;
  52779. - }
  52780. - pr_debug("%s(): memory range at %p is busy, retrying\n",
  52781. - __func__, pfn_to_page(pfn));
  52782. - /* try again with a bit different memory target */
  52783. - start = pageno + mask + 1;
  52784. - }
  52785. -
  52786. - mutex_unlock(&cma_mutex);
  52787. - pr_debug("%s(): returned %p\n", __func__, page);
  52788. - return page;
  52789. + return cma_alloc(dev_get_cma_area(dev), count, align);
  52790. }
  52791. /**
  52792. @@ -345,25 +209,5 @@
  52793. bool dma_release_from_contiguous(struct device *dev, struct page *pages,
  52794. int count)
  52795. {
  52796. - struct cma *cma = dev_get_cma_area(dev);
  52797. - unsigned long pfn;
  52798. -
  52799. - if (!cma || !pages)
  52800. - return false;
  52801. -
  52802. - pr_debug("%s(page %p)\n", __func__, (void *)pages);
  52803. -
  52804. - pfn = page_to_pfn(pages);
  52805. -
  52806. - if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
  52807. - return false;
  52808. -
  52809. - VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
  52810. -
  52811. - mutex_lock(&cma_mutex);
  52812. - bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count);
  52813. - free_contig_range(pfn, count);
  52814. - mutex_unlock(&cma_mutex);
  52815. -
  52816. - return true;
  52817. + return cma_release(dev_get_cma_area(dev), pages, count);
  52818. }
  52819. diff -Nur linux-3.14.14/drivers/base/Kconfig linux-imx6-3.14/drivers/base/Kconfig
  52820. --- linux-3.14.14/drivers/base/Kconfig 2014-07-28 10:07:25.000000000 -0500
  52821. +++ linux-imx6-3.14/drivers/base/Kconfig 2014-12-08 00:31:52.456418001 -0600
  52822. @@ -185,6 +185,14 @@
  52823. bool
  52824. default n
  52825. +config HAVE_CPU_AUTOPROBE
  52826. + def_bool ARCH_HAS_CPU_AUTOPROBE
  52827. +
  52828. +config GENERIC_CPU_AUTOPROBE
  52829. + bool
  52830. + depends on !ARCH_HAS_CPU_AUTOPROBE
  52831. + select HAVE_CPU_AUTOPROBE
  52832. +
  52833. config SOC_BUS
  52834. bool
  52835. @@ -266,16 +274,6 @@
  52836. If unsure, leave the default value "8".
  52837. -config CMA_AREAS
  52838. - int "Maximum count of the CMA device-private areas"
  52839. - default 7
  52840. - help
  52841. - CMA allows to create CMA areas for particular devices. This parameter
  52842. - sets the maximum number of such device private CMA areas in the
  52843. - system.
  52844. -
  52845. - If unsure, leave the default value "7".
  52846. -
  52847. endif
  52848. endmenu
  52849. diff -Nur linux-3.14.14/drivers/bus/arm-cci.c linux-imx6-3.14/drivers/bus/arm-cci.c
  52850. --- linux-3.14.14/drivers/bus/arm-cci.c 2014-07-28 10:07:25.000000000 -0500
  52851. +++ linux-imx6-3.14/drivers/bus/arm-cci.c 2014-12-08 00:31:52.496418001 -0600
  52852. @@ -26,6 +26,7 @@
  52853. #include <asm/cacheflush.h>
  52854. #include <asm/irq_regs.h>
  52855. +#include <asm/psci.h>
  52856. #include <asm/pmu.h>
  52857. #include <asm/smp_plat.h>
  52858. @@ -544,6 +545,7 @@
  52859. cci_pmu->plat_device = pdev;
  52860. cci_pmu->num_events = pmu_get_max_counters();
  52861. + cpumask_setall(&cci_pmu->valid_cpus);
  52862. return armpmu_register(cci_pmu, -1);
  52863. }
  52864. @@ -969,6 +971,11 @@
  52865. const char *match_str;
  52866. bool is_ace;
  52867. + if (psci_probe() == 0) {
  52868. + pr_debug("psci found. Aborting cci probe\n");
  52869. + return -ENODEV;
  52870. + }
  52871. +
  52872. np = of_find_matching_node(NULL, arm_cci_matches);
  52873. if (!np)
  52874. return -ENODEV;
  52875. diff -Nur linux-3.14.14/drivers/char/fsl_otp.c linux-imx6-3.14/drivers/char/fsl_otp.c
  52876. --- linux-3.14.14/drivers/char/fsl_otp.c 1969-12-31 18:00:00.000000000 -0600
  52877. +++ linux-imx6-3.14/drivers/char/fsl_otp.c 2014-12-08 00:31:52.500418001 -0600
  52878. @@ -0,0 +1,299 @@
  52879. +/*
  52880. + * Freescale On-Chip OTP driver
  52881. + *
  52882. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  52883. + *
  52884. + * This program is free software; you can redistribute it and/or modify
  52885. + * it under the terms of the GNU General Public License as published by
  52886. + * the Free Software Foundation; either version 2 of the License, or
  52887. + * (at your option) any later version.
  52888. + *
  52889. + * This program is distributed in the hope that it will be useful,
  52890. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  52891. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  52892. + * GNU General Public License for more details.
  52893. + *
  52894. + * You should have received a copy of the GNU General Public License
  52895. + * along with this program; if not, write to the Free Software
  52896. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  52897. + */
  52898. +
  52899. +#include <linux/clk.h>
  52900. +#include <linux/delay.h>
  52901. +#include <linux/err.h>
  52902. +#include <linux/init.h>
  52903. +#include <linux/io.h>
  52904. +#include <linux/kobject.h>
  52905. +#include <linux/module.h>
  52906. +#include <linux/mutex.h>
  52907. +#include <linux/of.h>
  52908. +#include <linux/platform_device.h>
  52909. +#include <linux/slab.h>
  52910. +#include <linux/sysfs.h>
  52911. +
  52912. +#define HW_OCOTP_CTRL 0x00000000
  52913. +#define HW_OCOTP_CTRL_SET 0x00000004
  52914. +#define BP_OCOTP_CTRL_WR_UNLOCK 16
  52915. +#define BM_OCOTP_CTRL_WR_UNLOCK 0xFFFF0000
  52916. +#define BM_OCOTP_CTRL_RELOAD_SHADOWS 0x00000400
  52917. +#define BM_OCOTP_CTRL_ERROR 0x00000200
  52918. +#define BM_OCOTP_CTRL_BUSY 0x00000100
  52919. +#define BP_OCOTP_CTRL_ADDR 0
  52920. +#define BM_OCOTP_CTRL_ADDR 0x0000007F
  52921. +
  52922. +#define HW_OCOTP_TIMING 0x00000010
  52923. +#define BP_OCOTP_TIMING_STROBE_READ 16
  52924. +#define BM_OCOTP_TIMING_STROBE_READ 0x003F0000
  52925. +#define BP_OCOTP_TIMING_RELAX 12
  52926. +#define BM_OCOTP_TIMING_RELAX 0x0000F000
  52927. +#define BP_OCOTP_TIMING_STROBE_PROG 0
  52928. +#define BM_OCOTP_TIMING_STROBE_PROG 0x00000FFF
  52929. +
  52930. +#define HW_OCOTP_DATA 0x00000020
  52931. +
  52932. +#define HW_OCOTP_CUST_N(n) (0x00000400 + (n) * 0x10)
  52933. +#define BF(value, field) (((value) << BP_##field) & BM_##field)
  52934. +
  52935. +#define DEF_RELAX 20 /* > 16.5ns */
  52936. +
  52937. +#define BANK(a, b, c, d, e, f, g, h) { \
  52938. + "HW_OCOTP_"#a, "HW_OCOTP_"#b, "HW_OCOTP_"#c, "HW_OCOTP_"#d, \
  52939. + "HW_OCOTP_"#e, "HW_OCOTP_"#f, "HW_OCOTP_"#g, "HW_OCOTP_"#h, \
  52940. +}
  52941. +
  52942. +static const char *imx6q_otp_desc[16][8] = {
  52943. + BANK(LOCK, CFG0, CFG1, CFG2, CFG3, CFG4, CFG5, CFG6),
  52944. + BANK(MEM0, MEM1, MEM2, MEM3, MEM4, ANA0, ANA1, ANA2),
  52945. + BANK(OTPMK0, OTPMK1, OTPMK2, OTPMK3, OTPMK4, OTPMK5, OTPMK6, OTPMK7),
  52946. + BANK(SRK0, SRK1, SRK2, SRK3, SRK4, SRK5, SRK6, SRK7),
  52947. + BANK(RESP0, HSJC_RESP1, MAC0, MAC1, HDCP_KSV0, HDCP_KSV1, GP1, GP2),
  52948. + BANK(DTCP_KEY0, DTCP_KEY1, DTCP_KEY2, DTCP_KEY3, DTCP_KEY4, MISC_CONF, FIELD_RETURN, SRK_REVOKE),
  52949. + BANK(HDCP_KEY0, HDCP_KEY1, HDCP_KEY2, HDCP_KEY3, HDCP_KEY4, HDCP_KEY5, HDCP_KEY6, HDCP_KEY7),
  52950. + BANK(HDCP_KEY8, HDCP_KEY9, HDCP_KEY10, HDCP_KEY11, HDCP_KEY12, HDCP_KEY13, HDCP_KEY14, HDCP_KEY15),
  52951. + BANK(HDCP_KEY16, HDCP_KEY17, HDCP_KEY18, HDCP_KEY19, HDCP_KEY20, HDCP_KEY21, HDCP_KEY22, HDCP_KEY23),
  52952. + BANK(HDCP_KEY24, HDCP_KEY25, HDCP_KEY26, HDCP_KEY27, HDCP_KEY28, HDCP_KEY29, HDCP_KEY30, HDCP_KEY31),
  52953. + BANK(HDCP_KEY32, HDCP_KEY33, HDCP_KEY34, HDCP_KEY35, HDCP_KEY36, HDCP_KEY37, HDCP_KEY38, HDCP_KEY39),
  52954. + BANK(HDCP_KEY40, HDCP_KEY41, HDCP_KEY42, HDCP_KEY43, HDCP_KEY44, HDCP_KEY45, HDCP_KEY46, HDCP_KEY47),
  52955. + BANK(HDCP_KEY48, HDCP_KEY49, HDCP_KEY50, HDCP_KEY51, HDCP_KEY52, HDCP_KEY53, HDCP_KEY54, HDCP_KEY55),
  52956. + BANK(HDCP_KEY56, HDCP_KEY57, HDCP_KEY58, HDCP_KEY59, HDCP_KEY60, HDCP_KEY61, HDCP_KEY62, HDCP_KEY63),
  52957. + BANK(HDCP_KEY64, HDCP_KEY65, HDCP_KEY66, HDCP_KEY67, HDCP_KEY68, HDCP_KEY69, HDCP_KEY70, HDCP_KEY71),
  52958. + BANK(CRC0, CRC1, CRC2, CRC3, CRC4, CRC5, CRC6, CRC7),
  52959. +};
  52960. +
  52961. +static DEFINE_MUTEX(otp_mutex);
  52962. +static void __iomem *otp_base;
  52963. +static struct clk *otp_clk;
  52964. +struct kobject *otp_kobj;
  52965. +struct kobj_attribute *otp_kattr;
  52966. +struct attribute_group *otp_attr_group;
  52967. +
  52968. +static void set_otp_timing(void)
  52969. +{
  52970. + unsigned long clk_rate = 0;
  52971. + unsigned long strobe_read, relex, strobe_prog;
  52972. + u32 timing = 0;
  52973. +
  52974. + clk_rate = clk_get_rate(otp_clk);
  52975. +
  52976. + /* do optimization for too many zeros */
  52977. + relex = clk_rate / (1000000000 / DEF_RELAX) - 1;
  52978. + strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
  52979. + strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
  52980. +
  52981. + timing = BF(relex, OCOTP_TIMING_RELAX);
  52982. + timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
  52983. + timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
  52984. +
  52985. + __raw_writel(timing, otp_base + HW_OCOTP_TIMING);
  52986. +}
  52987. +
  52988. +static int otp_wait_busy(u32 flags)
  52989. +{
  52990. + int count;
  52991. + u32 c;
  52992. +
  52993. + for (count = 10000; count >= 0; count--) {
  52994. + c = __raw_readl(otp_base + HW_OCOTP_CTRL);
  52995. + if (!(c & (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR | flags)))
  52996. + break;
  52997. + cpu_relax();
  52998. + }
  52999. +
  53000. + if (count < 0)
  53001. + return -ETIMEDOUT;
  53002. +
  53003. + return 0;
  53004. +}
  53005. +
  53006. +static ssize_t fsl_otp_show(struct kobject *kobj, struct kobj_attribute *attr,
  53007. + char *buf)
  53008. +{
  53009. + unsigned int index = attr - otp_kattr;
  53010. + u32 value = 0;
  53011. + int ret;
  53012. +
  53013. + ret = clk_prepare_enable(otp_clk);
  53014. + if (ret)
  53015. + return 0;
  53016. +
  53017. + mutex_lock(&otp_mutex);
  53018. +
  53019. + set_otp_timing();
  53020. + ret = otp_wait_busy(0);
  53021. + if (ret)
  53022. + goto out;
  53023. +
  53024. + value = __raw_readl(otp_base + HW_OCOTP_CUST_N(index));
  53025. +
  53026. +out:
  53027. + mutex_unlock(&otp_mutex);
  53028. + clk_disable_unprepare(otp_clk);
  53029. + return ret ? 0 : sprintf(buf, "0x%x\n", value);
  53030. +}
  53031. +
  53032. +static int otp_write_bits(int addr, u32 data, u32 magic)
  53033. +{
  53034. + u32 c; /* for control register */
  53035. +
  53036. + /* init the control register */
  53037. + c = __raw_readl(otp_base + HW_OCOTP_CTRL);
  53038. + c &= ~BM_OCOTP_CTRL_ADDR;
  53039. + c |= BF(addr, OCOTP_CTRL_ADDR);
  53040. + c |= BF(magic, OCOTP_CTRL_WR_UNLOCK);
  53041. + __raw_writel(c, otp_base + HW_OCOTP_CTRL);
  53042. +
  53043. + /* init the data register */
  53044. + __raw_writel(data, otp_base + HW_OCOTP_DATA);
  53045. + otp_wait_busy(0);
  53046. +
  53047. + mdelay(2); /* Write Postamble */
  53048. +
  53049. + return 0;
  53050. +}
  53051. +
  53052. +static ssize_t fsl_otp_store(struct kobject *kobj, struct kobj_attribute *attr,
  53053. + const char *buf, size_t count)
  53054. +{
  53055. + unsigned int index = attr - otp_kattr;
  53056. + u32 value;
  53057. + int ret;
  53058. +
  53059. + sscanf(buf, "0x%x", &value);
  53060. +
  53061. + ret = clk_prepare_enable(otp_clk);
  53062. + if (ret)
  53063. + return 0;
  53064. +
  53065. + mutex_lock(&otp_mutex);
  53066. +
  53067. + set_otp_timing();
  53068. + ret = otp_wait_busy(0);
  53069. + if (ret)
  53070. + goto out;
  53071. +
  53072. + otp_write_bits(index, value, 0x3e77);
  53073. +
  53074. + /* Reload all the shadow registers */
  53075. + __raw_writel(BM_OCOTP_CTRL_RELOAD_SHADOWS,
  53076. + otp_base + HW_OCOTP_CTRL_SET);
  53077. + udelay(1);
  53078. + otp_wait_busy(BM_OCOTP_CTRL_RELOAD_SHADOWS);
  53079. +
  53080. +out:
  53081. + mutex_unlock(&otp_mutex);
  53082. + clk_disable_unprepare(otp_clk);
  53083. + return ret ? 0 : count;
  53084. +}
  53085. +
  53086. +static int fsl_otp_probe(struct platform_device *pdev)
  53087. +{
  53088. + struct resource *res;
  53089. + struct attribute **attrs;
  53090. + const char **desc;
  53091. + int i, num;
  53092. + int ret;
  53093. +
  53094. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  53095. + otp_base = devm_ioremap_resource(&pdev->dev, res);
  53096. + if (IS_ERR(otp_base)) {
  53097. + ret = PTR_ERR(otp_base);
  53098. + dev_err(&pdev->dev, "failed to ioremap resource: %d\n", ret);
  53099. + return ret;
  53100. + }
  53101. +
  53102. + otp_clk = devm_clk_get(&pdev->dev, NULL);
  53103. + if (IS_ERR(otp_clk)) {
  53104. + ret = PTR_ERR(otp_clk);
  53105. + dev_err(&pdev->dev, "failed to get clock: %d\n", ret);
  53106. + return ret;
  53107. + }
  53108. +
  53109. + desc = (const char **) imx6q_otp_desc;
  53110. + num = sizeof(imx6q_otp_desc) / sizeof(void *);
  53111. +
  53112. + /* The last one is NULL, which is used to detect the end */
  53113. + attrs = devm_kzalloc(&pdev->dev, (num + 1) * sizeof(*attrs),
  53114. + GFP_KERNEL);
  53115. + otp_kattr = devm_kzalloc(&pdev->dev, num * sizeof(*otp_kattr),
  53116. + GFP_KERNEL);
  53117. + otp_attr_group = devm_kzalloc(&pdev->dev, sizeof(*otp_attr_group),
  53118. + GFP_KERNEL);
  53119. + if (!attrs || !otp_kattr || !otp_attr_group)
  53120. + return -ENOMEM;
  53121. +
  53122. + for (i = 0; i < num; i++) {
  53123. + sysfs_attr_init(&otp_kattr[i].attr);
  53124. + otp_kattr[i].attr.name = desc[i];
  53125. + otp_kattr[i].attr.mode = 0600;
  53126. + otp_kattr[i].show = fsl_otp_show;
  53127. + otp_kattr[i].store = fsl_otp_store;
  53128. + attrs[i] = &otp_kattr[i].attr;
  53129. + }
  53130. + otp_attr_group->attrs = attrs;
  53131. +
  53132. + otp_kobj = kobject_create_and_add("fsl_otp", NULL);
  53133. + if (!otp_kobj) {
  53134. + dev_err(&pdev->dev, "failed to add kobject\n");
  53135. + return -ENOMEM;
  53136. + }
  53137. +
  53138. + ret = sysfs_create_group(otp_kobj, otp_attr_group);
  53139. + if (ret) {
  53140. + dev_err(&pdev->dev, "failed to create sysfs group: %d\n", ret);
  53141. + kobject_put(otp_kobj);
  53142. + return ret;
  53143. + }
  53144. +
  53145. + mutex_init(&otp_mutex);
  53146. +
  53147. + return 0;
  53148. +}
  53149. +
  53150. +static int fsl_otp_remove(struct platform_device *pdev)
  53151. +{
  53152. + sysfs_remove_group(otp_kobj, otp_attr_group);
  53153. + kobject_put(otp_kobj);
  53154. +
  53155. + return 0;
  53156. +}
  53157. +
  53158. +static const struct of_device_id fsl_otp_dt_ids[] = {
  53159. + { .compatible = "fsl,imx6q-ocotp", },
  53160. + { /* sentinel */ }
  53161. +};
  53162. +MODULE_DEVICE_TABLE(of, fsl_otp_dt_ids);
  53163. +
  53164. +static struct platform_driver fsl_otp_driver = {
  53165. + .driver = {
  53166. + .name = "imx-ocotp",
  53167. + .owner = THIS_MODULE,
  53168. + .of_match_table = fsl_otp_dt_ids,
  53169. + },
  53170. + .probe = fsl_otp_probe,
  53171. + .remove = fsl_otp_remove,
  53172. +};
  53173. +module_platform_driver(fsl_otp_driver);
  53174. +
  53175. +MODULE_LICENSE("GPL");
  53176. +MODULE_AUTHOR("Huang Shijie <b32955@freescale.com>");
  53177. +MODULE_DESCRIPTION("Freescale i.MX OCOTP driver");
  53178. diff -Nur linux-3.14.14/drivers/char/Kconfig linux-imx6-3.14/drivers/char/Kconfig
  53179. --- linux-3.14.14/drivers/char/Kconfig 2014-07-28 10:07:25.000000000 -0500
  53180. +++ linux-imx6-3.14/drivers/char/Kconfig 2014-12-08 00:31:52.496418001 -0600
  53181. @@ -82,6 +82,21 @@
  53182. If unsure, say N.
  53183. +config FSL_OTP
  53184. + tristate "Freescale On-Chip OTP Memory Support"
  53185. + depends on HAS_IOMEM && OF
  53186. + help
  53187. + If you say Y here, you will get support for a character device
  53188. + interface into the One Time Programmable memory pages that are
  53189. + stored on the some Freescale i.MX processors. This will not get
  53190. + you access to the secure memory pages however. You will need to
  53191. + write your own secure code and reader for that.
  53192. +
  53193. + To compile this driver as a module, choose M here: the module
  53194. + will be called fsl_otp.
  53195. +
  53196. + If unsure, it is safe to say Y.
  53197. +
  53198. config PRINTER
  53199. tristate "Parallel printer support"
  53200. depends on PARPORT
  53201. diff -Nur linux-3.14.14/drivers/char/Makefile linux-imx6-3.14/drivers/char/Makefile
  53202. --- linux-3.14.14/drivers/char/Makefile 2014-07-28 10:07:25.000000000 -0500
  53203. +++ linux-imx6-3.14/drivers/char/Makefile 2014-12-08 00:31:52.496418001 -0600
  53204. @@ -16,6 +16,7 @@
  53205. obj-$(CONFIG_IBM_BSR) += bsr.o
  53206. obj-$(CONFIG_SGI_MBCS) += mbcs.o
  53207. obj-$(CONFIG_BFIN_OTP) += bfin-otp.o
  53208. +obj-$(CONFIG_FSL_OTP) += fsl_otp.o
  53209. obj-$(CONFIG_PRINTER) += lp.o
  53210. diff -Nur linux-3.14.14/drivers/clk/clk.c linux-imx6-3.14/drivers/clk/clk.c
  53211. --- linux-3.14.14/drivers/clk/clk.c 2014-07-28 10:07:25.000000000 -0500
  53212. +++ linux-imx6-3.14/drivers/clk/clk.c 2014-12-08 00:31:52.520418001 -0600
  53213. @@ -1702,6 +1702,7 @@
  53214. */
  53215. int clk_set_parent(struct clk *clk, struct clk *parent)
  53216. {
  53217. + struct clk *child;
  53218. int ret = 0;
  53219. int p_index = 0;
  53220. unsigned long p_rate = 0;
  53221. @@ -1728,6 +1729,18 @@
  53222. goto out;
  53223. }
  53224. + /* check two consecutive basic mux clocks */
  53225. + if (clk->flags & CLK_IS_BASIC_MUX) {
  53226. + hlist_for_each_entry(child, &clk->children, child_node) {
  53227. + if (child->flags & CLK_IS_BASIC_MUX) {
  53228. + pr_err("%s: failed to switch parent of %s due to child mux %s\n",
  53229. + __func__, clk->name, child->name);
  53230. + ret = -EBUSY;
  53231. + goto out;
  53232. + }
  53233. + }
  53234. + }
  53235. +
  53236. /* try finding the new parent index */
  53237. if (parent) {
  53238. p_index = clk_fetch_parent_index(clk, parent);
  53239. diff -Nur linux-3.14.14/drivers/clk/clk-mux.c linux-imx6-3.14/drivers/clk/clk-mux.c
  53240. --- linux-3.14.14/drivers/clk/clk-mux.c 2014-07-28 10:07:25.000000000 -0500
  53241. +++ linux-imx6-3.14/drivers/clk/clk-mux.c 2014-12-08 00:31:52.516418001 -0600
  53242. @@ -143,7 +143,7 @@
  53243. init.ops = &clk_mux_ro_ops;
  53244. else
  53245. init.ops = &clk_mux_ops;
  53246. - init.flags = flags | CLK_IS_BASIC;
  53247. + init.flags = flags | CLK_IS_BASIC | CLK_IS_BASIC_MUX;
  53248. init.parent_names = parent_names;
  53249. init.num_parents = num_parents;
  53250. diff -Nur linux-3.14.14/drivers/cpufreq/cpufreq_interactive.c linux-imx6-3.14/drivers/cpufreq/cpufreq_interactive.c
  53251. --- linux-3.14.14/drivers/cpufreq/cpufreq_interactive.c 1969-12-31 18:00:00.000000000 -0600
  53252. +++ linux-imx6-3.14/drivers/cpufreq/cpufreq_interactive.c 2014-12-08 00:31:52.540418001 -0600
  53253. @@ -0,0 +1,1349 @@
  53254. +/*
  53255. + * drivers/cpufreq/cpufreq_interactive.c
  53256. + *
  53257. + * Copyright (C) 2010 Google, Inc.
  53258. + *
  53259. + * This software is licensed under the terms of the GNU General Public
  53260. + * License version 2, as published by the Free Software Foundation, and
  53261. + * may be copied, distributed, and modified under those terms.
  53262. + *
  53263. + * This program is distributed in the hope that it will be useful,
  53264. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  53265. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  53266. + * GNU General Public License for more details.
  53267. + *
  53268. + * Author: Mike Chan (mike@android.com)
  53269. + *
  53270. + */
  53271. +
  53272. +#include <linux/cpu.h>
  53273. +#include <linux/cpumask.h>
  53274. +#include <linux/cpufreq.h>
  53275. +#include <linux/module.h>
  53276. +#include <linux/moduleparam.h>
  53277. +#include <linux/rwsem.h>
  53278. +#include <linux/sched.h>
  53279. +#include <linux/sched/rt.h>
  53280. +#include <linux/tick.h>
  53281. +#include <linux/time.h>
  53282. +#include <linux/timer.h>
  53283. +#include <linux/workqueue.h>
  53284. +#include <linux/kthread.h>
  53285. +#include <linux/slab.h>
  53286. +
  53287. +#define CREATE_TRACE_POINTS
  53288. +#include <trace/events/cpufreq_interactive.h>
  53289. +
  53290. +struct cpufreq_interactive_cpuinfo {
  53291. + struct timer_list cpu_timer;
  53292. + struct timer_list cpu_slack_timer;
  53293. + spinlock_t load_lock; /* protects the next 4 fields */
  53294. + u64 time_in_idle;
  53295. + u64 time_in_idle_timestamp;
  53296. + u64 cputime_speedadj;
  53297. + u64 cputime_speedadj_timestamp;
  53298. + struct cpufreq_policy *policy;
  53299. + struct cpufreq_frequency_table *freq_table;
  53300. + unsigned int target_freq;
  53301. + unsigned int floor_freq;
  53302. + u64 floor_validate_time;
  53303. + u64 hispeed_validate_time;
  53304. + struct rw_semaphore enable_sem;
  53305. + int governor_enabled;
  53306. +};
  53307. +
  53308. +static DEFINE_PER_CPU(struct cpufreq_interactive_cpuinfo, cpuinfo);
  53309. +
  53310. +/* realtime thread handles frequency scaling */
  53311. +static struct task_struct *speedchange_task;
  53312. +static cpumask_t speedchange_cpumask;
  53313. +static spinlock_t speedchange_cpumask_lock;
  53314. +static struct mutex gov_lock;
  53315. +
  53316. +/* Target load. Lower values result in higher CPU speeds. */
  53317. +#define DEFAULT_TARGET_LOAD 90
  53318. +static unsigned int default_target_loads[] = {DEFAULT_TARGET_LOAD};
  53319. +
  53320. +#define DEFAULT_TIMER_RATE (20 * USEC_PER_MSEC)
  53321. +#define DEFAULT_ABOVE_HISPEED_DELAY DEFAULT_TIMER_RATE
  53322. +static unsigned int default_above_hispeed_delay[] = {
  53323. + DEFAULT_ABOVE_HISPEED_DELAY };
  53324. +
  53325. +struct cpufreq_interactive_tunables {
  53326. + int usage_count;
  53327. + /* Hi speed to bump to from lo speed when load burst (default max) */
  53328. + unsigned int hispeed_freq;
  53329. + /* Go to hi speed when CPU load at or above this value. */
  53330. +#define DEFAULT_GO_HISPEED_LOAD 99
  53331. + unsigned long go_hispeed_load;
  53332. + /* Target load. Lower values result in higher CPU speeds. */
  53333. + spinlock_t target_loads_lock;
  53334. + unsigned int *target_loads;
  53335. + int ntarget_loads;
  53336. + /*
  53337. + * The minimum amount of time to spend at a frequency before we can ramp
  53338. + * down.
  53339. + */
  53340. +#define DEFAULT_MIN_SAMPLE_TIME (80 * USEC_PER_MSEC)
  53341. + unsigned long min_sample_time;
  53342. + /*
  53343. + * The sample rate of the timer used to increase frequency
  53344. + */
  53345. + unsigned long timer_rate;
  53346. + /*
  53347. + * Wait this long before raising speed above hispeed, by default a
  53348. + * single timer interval.
  53349. + */
  53350. + spinlock_t above_hispeed_delay_lock;
  53351. + unsigned int *above_hispeed_delay;
  53352. + int nabove_hispeed_delay;
  53353. + /* Non-zero means indefinite speed boost active */
  53354. + int boost_val;
  53355. + /* Duration of a boot pulse in usecs */
  53356. + int boostpulse_duration_val;
  53357. + /* End time of boost pulse in ktime converted to usecs */
  53358. + u64 boostpulse_endtime;
  53359. + /*
  53360. + * Max additional time to wait in idle, beyond timer_rate, at speeds
  53361. + * above minimum before wakeup to reduce speed, or -1 if unnecessary.
  53362. + */
  53363. +#define DEFAULT_TIMER_SLACK (4 * DEFAULT_TIMER_RATE)
  53364. + int timer_slack_val;
  53365. + bool io_is_busy;
  53366. +};
  53367. +
  53368. +/* For cases where we have single governor instance for system */
  53369. +struct cpufreq_interactive_tunables *common_tunables;
  53370. +
  53371. +static struct attribute_group *get_sysfs_attr(void);
  53372. +
  53373. +static void cpufreq_interactive_timer_resched(
  53374. + struct cpufreq_interactive_cpuinfo *pcpu)
  53375. +{
  53376. + struct cpufreq_interactive_tunables *tunables =
  53377. + pcpu->policy->governor_data;
  53378. + unsigned long expires;
  53379. + unsigned long flags;
  53380. +
  53381. + spin_lock_irqsave(&pcpu->load_lock, flags);
  53382. + pcpu->time_in_idle =
  53383. + get_cpu_idle_time(smp_processor_id(),
  53384. + &pcpu->time_in_idle_timestamp,
  53385. + tunables->io_is_busy);
  53386. + pcpu->cputime_speedadj = 0;
  53387. + pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp;
  53388. + expires = jiffies + usecs_to_jiffies(tunables->timer_rate);
  53389. + mod_timer_pinned(&pcpu->cpu_timer, expires);
  53390. +
  53391. + if (tunables->timer_slack_val >= 0 &&
  53392. + pcpu->target_freq > pcpu->policy->min) {
  53393. + expires += usecs_to_jiffies(tunables->timer_slack_val);
  53394. + mod_timer_pinned(&pcpu->cpu_slack_timer, expires);
  53395. + }
  53396. +
  53397. + spin_unlock_irqrestore(&pcpu->load_lock, flags);
  53398. +}
  53399. +
  53400. +/* The caller shall take enable_sem write semaphore to avoid any timer race.
  53401. + * The cpu_timer and cpu_slack_timer must be deactivated when calling this
  53402. + * function.
  53403. + */
  53404. +static void cpufreq_interactive_timer_start(
  53405. + struct cpufreq_interactive_tunables *tunables, int cpu)
  53406. +{
  53407. + struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu);
  53408. + unsigned long expires = jiffies +
  53409. + usecs_to_jiffies(tunables->timer_rate);
  53410. + unsigned long flags;
  53411. +
  53412. + pcpu->cpu_timer.expires = expires;
  53413. + add_timer_on(&pcpu->cpu_timer, cpu);
  53414. + if (tunables->timer_slack_val >= 0 &&
  53415. + pcpu->target_freq > pcpu->policy->min) {
  53416. + expires += usecs_to_jiffies(tunables->timer_slack_val);
  53417. + pcpu->cpu_slack_timer.expires = expires;
  53418. + add_timer_on(&pcpu->cpu_slack_timer, cpu);
  53419. + }
  53420. +
  53421. + spin_lock_irqsave(&pcpu->load_lock, flags);
  53422. + pcpu->time_in_idle =
  53423. + get_cpu_idle_time(cpu, &pcpu->time_in_idle_timestamp,
  53424. + tunables->io_is_busy);
  53425. + pcpu->cputime_speedadj = 0;
  53426. + pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp;
  53427. + spin_unlock_irqrestore(&pcpu->load_lock, flags);
  53428. +}
  53429. +
  53430. +static unsigned int freq_to_above_hispeed_delay(
  53431. + struct cpufreq_interactive_tunables *tunables,
  53432. + unsigned int freq)
  53433. +{
  53434. + int i;
  53435. + unsigned int ret;
  53436. + unsigned long flags;
  53437. +
  53438. + spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
  53439. +
  53440. + for (i = 0; i < tunables->nabove_hispeed_delay - 1 &&
  53441. + freq >= tunables->above_hispeed_delay[i+1]; i += 2)
  53442. + ;
  53443. +
  53444. + ret = tunables->above_hispeed_delay[i];
  53445. + spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
  53446. + return ret;
  53447. +}
  53448. +
  53449. +static unsigned int freq_to_targetload(
  53450. + struct cpufreq_interactive_tunables *tunables, unsigned int freq)
  53451. +{
  53452. + int i;
  53453. + unsigned int ret;
  53454. + unsigned long flags;
  53455. +
  53456. + spin_lock_irqsave(&tunables->target_loads_lock, flags);
  53457. +
  53458. + for (i = 0; i < tunables->ntarget_loads - 1 &&
  53459. + freq >= tunables->target_loads[i+1]; i += 2)
  53460. + ;
  53461. +
  53462. + ret = tunables->target_loads[i];
  53463. + spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
  53464. + return ret;
  53465. +}
  53466. +
  53467. +/*
  53468. + * If increasing frequencies never map to a lower target load then
  53469. + * choose_freq() will find the minimum frequency that does not exceed its
  53470. + * target load given the current load.
  53471. + */
  53472. +static unsigned int choose_freq(struct cpufreq_interactive_cpuinfo *pcpu,
  53473. + unsigned int loadadjfreq)
  53474. +{
  53475. + unsigned int freq = pcpu->policy->cur;
  53476. + unsigned int prevfreq, freqmin, freqmax;
  53477. + unsigned int tl;
  53478. + int index;
  53479. +
  53480. + freqmin = 0;
  53481. + freqmax = UINT_MAX;
  53482. +
  53483. + do {
  53484. + prevfreq = freq;
  53485. + tl = freq_to_targetload(pcpu->policy->governor_data, freq);
  53486. +
  53487. + /*
  53488. + * Find the lowest frequency where the computed load is less
  53489. + * than or equal to the target load.
  53490. + */
  53491. +
  53492. + if (cpufreq_frequency_table_target(
  53493. + pcpu->policy, pcpu->freq_table, loadadjfreq / tl,
  53494. + CPUFREQ_RELATION_L, &index))
  53495. + break;
  53496. + freq = pcpu->freq_table[index].frequency;
  53497. +
  53498. + if (freq > prevfreq) {
  53499. + /* The previous frequency is too low. */
  53500. + freqmin = prevfreq;
  53501. +
  53502. + if (freq >= freqmax) {
  53503. + /*
  53504. + * Find the highest frequency that is less
  53505. + * than freqmax.
  53506. + */
  53507. + if (cpufreq_frequency_table_target(
  53508. + pcpu->policy, pcpu->freq_table,
  53509. + freqmax - 1, CPUFREQ_RELATION_H,
  53510. + &index))
  53511. + break;
  53512. + freq = pcpu->freq_table[index].frequency;
  53513. +
  53514. + if (freq == freqmin) {
  53515. + /*
  53516. + * The first frequency below freqmax
  53517. + * has already been found to be too
  53518. + * low. freqmax is the lowest speed
  53519. + * we found that is fast enough.
  53520. + */
  53521. + freq = freqmax;
  53522. + break;
  53523. + }
  53524. + }
  53525. + } else if (freq < prevfreq) {
  53526. + /* The previous frequency is high enough. */
  53527. + freqmax = prevfreq;
  53528. +
  53529. + if (freq <= freqmin) {
  53530. + /*
  53531. + * Find the lowest frequency that is higher
  53532. + * than freqmin.
  53533. + */
  53534. + if (cpufreq_frequency_table_target(
  53535. + pcpu->policy, pcpu->freq_table,
  53536. + freqmin + 1, CPUFREQ_RELATION_L,
  53537. + &index))
  53538. + break;
  53539. + freq = pcpu->freq_table[index].frequency;
  53540. +
  53541. + /*
  53542. + * If freqmax is the first frequency above
  53543. + * freqmin then we have already found that
  53544. + * this speed is fast enough.
  53545. + */
  53546. + if (freq == freqmax)
  53547. + break;
  53548. + }
  53549. + }
  53550. +
  53551. + /* If same frequency chosen as previous then done. */
  53552. + } while (freq != prevfreq);
  53553. +
  53554. + return freq;
  53555. +}
  53556. +
  53557. +static u64 update_load(int cpu)
  53558. +{
  53559. + struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu);
  53560. + struct cpufreq_interactive_tunables *tunables =
  53561. + pcpu->policy->governor_data;
  53562. + u64 now;
  53563. + u64 now_idle;
  53564. + unsigned int delta_idle;
  53565. + unsigned int delta_time;
  53566. + u64 active_time;
  53567. +
  53568. + now_idle = get_cpu_idle_time(cpu, &now, tunables->io_is_busy);
  53569. + delta_idle = (unsigned int)(now_idle - pcpu->time_in_idle);
  53570. + delta_time = (unsigned int)(now - pcpu->time_in_idle_timestamp);
  53571. +
  53572. + if (delta_time <= delta_idle)
  53573. + active_time = 0;
  53574. + else
  53575. + active_time = delta_time - delta_idle;
  53576. +
  53577. + pcpu->cputime_speedadj += active_time * pcpu->policy->cur;
  53578. +
  53579. + pcpu->time_in_idle = now_idle;
  53580. + pcpu->time_in_idle_timestamp = now;
  53581. + return now;
  53582. +}
  53583. +
  53584. +static void cpufreq_interactive_timer(unsigned long data)
  53585. +{
  53586. + u64 now;
  53587. + unsigned int delta_time;
  53588. + u64 cputime_speedadj;
  53589. + int cpu_load;
  53590. + struct cpufreq_interactive_cpuinfo *pcpu =
  53591. + &per_cpu(cpuinfo, data);
  53592. + struct cpufreq_interactive_tunables *tunables =
  53593. + pcpu->policy->governor_data;
  53594. + unsigned int new_freq;
  53595. + unsigned int loadadjfreq;
  53596. + unsigned int index;
  53597. + unsigned long flags;
  53598. + bool boosted;
  53599. +
  53600. + if (!down_read_trylock(&pcpu->enable_sem))
  53601. + return;
  53602. + if (!pcpu->governor_enabled)
  53603. + goto exit;
  53604. +
  53605. + spin_lock_irqsave(&pcpu->load_lock, flags);
  53606. + now = update_load(data);
  53607. + delta_time = (unsigned int)(now - pcpu->cputime_speedadj_timestamp);
  53608. + cputime_speedadj = pcpu->cputime_speedadj;
  53609. + spin_unlock_irqrestore(&pcpu->load_lock, flags);
  53610. +
  53611. + if (WARN_ON_ONCE(!delta_time))
  53612. + goto rearm;
  53613. +
  53614. + do_div(cputime_speedadj, delta_time);
  53615. + loadadjfreq = (unsigned int)cputime_speedadj * 100;
  53616. + cpu_load = loadadjfreq / pcpu->target_freq;
  53617. + boosted = tunables->boost_val || now < tunables->boostpulse_endtime;
  53618. +
  53619. + if (cpu_load >= tunables->go_hispeed_load || boosted) {
  53620. + if (pcpu->target_freq < tunables->hispeed_freq) {
  53621. + new_freq = tunables->hispeed_freq;
  53622. + } else {
  53623. + new_freq = choose_freq(pcpu, loadadjfreq);
  53624. +
  53625. + if (new_freq < tunables->hispeed_freq)
  53626. + new_freq = tunables->hispeed_freq;
  53627. + }
  53628. + } else {
  53629. + new_freq = choose_freq(pcpu, loadadjfreq);
  53630. + }
  53631. +
  53632. + if (pcpu->target_freq >= tunables->hispeed_freq &&
  53633. + new_freq > pcpu->target_freq &&
  53634. + now - pcpu->hispeed_validate_time <
  53635. + freq_to_above_hispeed_delay(tunables, pcpu->target_freq)) {
  53636. + trace_cpufreq_interactive_notyet(
  53637. + data, cpu_load, pcpu->target_freq,
  53638. + pcpu->policy->cur, new_freq);
  53639. + goto rearm;
  53640. + }
  53641. +
  53642. + pcpu->hispeed_validate_time = now;
  53643. +
  53644. + if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table,
  53645. + new_freq, CPUFREQ_RELATION_L,
  53646. + &index))
  53647. + goto rearm;
  53648. +
  53649. + new_freq = pcpu->freq_table[index].frequency;
  53650. +
  53651. + /*
  53652. + * Do not scale below floor_freq unless we have been at or above the
  53653. + * floor frequency for the minimum sample time since last validated.
  53654. + */
  53655. + if (new_freq < pcpu->floor_freq) {
  53656. + if (now - pcpu->floor_validate_time <
  53657. + tunables->min_sample_time) {
  53658. + trace_cpufreq_interactive_notyet(
  53659. + data, cpu_load, pcpu->target_freq,
  53660. + pcpu->policy->cur, new_freq);
  53661. + goto rearm;
  53662. + }
  53663. + }
  53664. +
  53665. + /*
  53666. + * Update the timestamp for checking whether speed has been held at
  53667. + * or above the selected frequency for a minimum of min_sample_time,
  53668. + * if not boosted to hispeed_freq. If boosted to hispeed_freq then we
  53669. + * allow the speed to drop as soon as the boostpulse duration expires
  53670. + * (or the indefinite boost is turned off).
  53671. + */
  53672. +
  53673. + if (!boosted || new_freq > tunables->hispeed_freq) {
  53674. + pcpu->floor_freq = new_freq;
  53675. + pcpu->floor_validate_time = now;
  53676. + }
  53677. +
  53678. + if (pcpu->target_freq == new_freq) {
  53679. + trace_cpufreq_interactive_already(
  53680. + data, cpu_load, pcpu->target_freq,
  53681. + pcpu->policy->cur, new_freq);
  53682. + goto rearm_if_notmax;
  53683. + }
  53684. +
  53685. + trace_cpufreq_interactive_target(data, cpu_load, pcpu->target_freq,
  53686. + pcpu->policy->cur, new_freq);
  53687. +
  53688. + pcpu->target_freq = new_freq;
  53689. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  53690. + cpumask_set_cpu(data, &speedchange_cpumask);
  53691. + spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
  53692. + wake_up_process(speedchange_task);
  53693. +
  53694. +rearm_if_notmax:
  53695. + /*
  53696. + * Already set max speed and don't see a need to change that,
  53697. + * wait until next idle to re-evaluate, don't need timer.
  53698. + */
  53699. + if (pcpu->target_freq == pcpu->policy->max)
  53700. + goto exit;
  53701. +
  53702. +rearm:
  53703. + if (!timer_pending(&pcpu->cpu_timer))
  53704. + cpufreq_interactive_timer_resched(pcpu);
  53705. +
  53706. +exit:
  53707. + up_read(&pcpu->enable_sem);
  53708. + return;
  53709. +}
  53710. +
  53711. +static void cpufreq_interactive_idle_start(void)
  53712. +{
  53713. + struct cpufreq_interactive_cpuinfo *pcpu =
  53714. + &per_cpu(cpuinfo, smp_processor_id());
  53715. + int pending;
  53716. +
  53717. + if (!down_read_trylock(&pcpu->enable_sem))
  53718. + return;
  53719. + if (!pcpu->governor_enabled) {
  53720. + up_read(&pcpu->enable_sem);
  53721. + return;
  53722. + }
  53723. +
  53724. + pending = timer_pending(&pcpu->cpu_timer);
  53725. +
  53726. + if (pcpu->target_freq != pcpu->policy->min) {
  53727. + /*
  53728. + * Entering idle while not at lowest speed. On some
  53729. + * platforms this can hold the other CPU(s) at that speed
  53730. + * even though the CPU is idle. Set a timer to re-evaluate
  53731. + * speed so this idle CPU doesn't hold the other CPUs above
  53732. + * min indefinitely. This should probably be a quirk of
  53733. + * the CPUFreq driver.
  53734. + */
  53735. + if (!pending)
  53736. + cpufreq_interactive_timer_resched(pcpu);
  53737. + }
  53738. +
  53739. + up_read(&pcpu->enable_sem);
  53740. +}
  53741. +
  53742. +static void cpufreq_interactive_idle_end(void)
  53743. +{
  53744. + struct cpufreq_interactive_cpuinfo *pcpu =
  53745. + &per_cpu(cpuinfo, smp_processor_id());
  53746. +
  53747. + if (!down_read_trylock(&pcpu->enable_sem))
  53748. + return;
  53749. + if (!pcpu->governor_enabled) {
  53750. + up_read(&pcpu->enable_sem);
  53751. + return;
  53752. + }
  53753. +
  53754. + /* Arm the timer for 1-2 ticks later if not already. */
  53755. + if (!timer_pending(&pcpu->cpu_timer)) {
  53756. + cpufreq_interactive_timer_resched(pcpu);
  53757. + } else if (time_after_eq(jiffies, pcpu->cpu_timer.expires)) {
  53758. + del_timer(&pcpu->cpu_timer);
  53759. + del_timer(&pcpu->cpu_slack_timer);
  53760. + cpufreq_interactive_timer(smp_processor_id());
  53761. + }
  53762. +
  53763. + up_read(&pcpu->enable_sem);
  53764. +}
  53765. +
  53766. +static int cpufreq_interactive_speedchange_task(void *data)
  53767. +{
  53768. + unsigned int cpu;
  53769. + cpumask_t tmp_mask;
  53770. + unsigned long flags;
  53771. + struct cpufreq_interactive_cpuinfo *pcpu;
  53772. +
  53773. + while (1) {
  53774. + set_current_state(TASK_INTERRUPTIBLE);
  53775. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  53776. +
  53777. + if (cpumask_empty(&speedchange_cpumask)) {
  53778. + spin_unlock_irqrestore(&speedchange_cpumask_lock,
  53779. + flags);
  53780. + schedule();
  53781. +
  53782. + if (kthread_should_stop())
  53783. + break;
  53784. +
  53785. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  53786. + }
  53787. +
  53788. + set_current_state(TASK_RUNNING);
  53789. + tmp_mask = speedchange_cpumask;
  53790. + cpumask_clear(&speedchange_cpumask);
  53791. + spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
  53792. +
  53793. + for_each_cpu(cpu, &tmp_mask) {
  53794. + unsigned int j;
  53795. + unsigned int max_freq = 0;
  53796. +
  53797. + pcpu = &per_cpu(cpuinfo, cpu);
  53798. + if (!down_read_trylock(&pcpu->enable_sem))
  53799. + continue;
  53800. + if (!pcpu->governor_enabled) {
  53801. + up_read(&pcpu->enable_sem);
  53802. + continue;
  53803. + }
  53804. +
  53805. + for_each_cpu(j, pcpu->policy->cpus) {
  53806. + struct cpufreq_interactive_cpuinfo *pjcpu =
  53807. + &per_cpu(cpuinfo, j);
  53808. +
  53809. + if (pjcpu->target_freq > max_freq)
  53810. + max_freq = pjcpu->target_freq;
  53811. + }
  53812. +
  53813. + if (max_freq != pcpu->policy->cur)
  53814. + __cpufreq_driver_target(pcpu->policy,
  53815. + max_freq,
  53816. + CPUFREQ_RELATION_H);
  53817. + trace_cpufreq_interactive_setspeed(cpu,
  53818. + pcpu->target_freq,
  53819. + pcpu->policy->cur);
  53820. +
  53821. + up_read(&pcpu->enable_sem);
  53822. + }
  53823. + }
  53824. +
  53825. + return 0;
  53826. +}
  53827. +
  53828. +static void cpufreq_interactive_boost(void)
  53829. +{
  53830. + int i;
  53831. + int anyboost = 0;
  53832. + unsigned long flags;
  53833. + struct cpufreq_interactive_cpuinfo *pcpu;
  53834. + struct cpufreq_interactive_tunables *tunables;
  53835. +
  53836. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  53837. +
  53838. + for_each_online_cpu(i) {
  53839. + pcpu = &per_cpu(cpuinfo, i);
  53840. + tunables = pcpu->policy->governor_data;
  53841. +
  53842. + if (pcpu->target_freq < tunables->hispeed_freq) {
  53843. + pcpu->target_freq = tunables->hispeed_freq;
  53844. + cpumask_set_cpu(i, &speedchange_cpumask);
  53845. + pcpu->hispeed_validate_time =
  53846. + ktime_to_us(ktime_get());
  53847. + anyboost = 1;
  53848. + }
  53849. +
  53850. + /*
  53851. + * Set floor freq and (re)start timer for when last
  53852. + * validated.
  53853. + */
  53854. +
  53855. + pcpu->floor_freq = tunables->hispeed_freq;
  53856. + pcpu->floor_validate_time = ktime_to_us(ktime_get());
  53857. + }
  53858. +
  53859. + spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
  53860. +
  53861. + if (anyboost)
  53862. + wake_up_process(speedchange_task);
  53863. +}
  53864. +
  53865. +static int cpufreq_interactive_notifier(
  53866. + struct notifier_block *nb, unsigned long val, void *data)
  53867. +{
  53868. + struct cpufreq_freqs *freq = data;
  53869. + struct cpufreq_interactive_cpuinfo *pcpu;
  53870. + int cpu;
  53871. + unsigned long flags;
  53872. +
  53873. + if (val == CPUFREQ_POSTCHANGE) {
  53874. + pcpu = &per_cpu(cpuinfo, freq->cpu);
  53875. + if (!down_read_trylock(&pcpu->enable_sem))
  53876. + return 0;
  53877. + if (!pcpu->governor_enabled) {
  53878. + up_read(&pcpu->enable_sem);
  53879. + return 0;
  53880. + }
  53881. +
  53882. + for_each_cpu(cpu, pcpu->policy->cpus) {
  53883. + struct cpufreq_interactive_cpuinfo *pjcpu =
  53884. + &per_cpu(cpuinfo, cpu);
  53885. + if (cpu != freq->cpu) {
  53886. + if (!down_read_trylock(&pjcpu->enable_sem))
  53887. + continue;
  53888. + if (!pjcpu->governor_enabled) {
  53889. + up_read(&pjcpu->enable_sem);
  53890. + continue;
  53891. + }
  53892. + }
  53893. + spin_lock_irqsave(&pjcpu->load_lock, flags);
  53894. + update_load(cpu);
  53895. + spin_unlock_irqrestore(&pjcpu->load_lock, flags);
  53896. + if (cpu != freq->cpu)
  53897. + up_read(&pjcpu->enable_sem);
  53898. + }
  53899. +
  53900. + up_read(&pcpu->enable_sem);
  53901. + }
  53902. + return 0;
  53903. +}
  53904. +
  53905. +static struct notifier_block cpufreq_notifier_block = {
  53906. + .notifier_call = cpufreq_interactive_notifier,
  53907. +};
  53908. +
  53909. +static unsigned int *get_tokenized_data(const char *buf, int *num_tokens)
  53910. +{
  53911. + const char *cp;
  53912. + int i;
  53913. + int ntokens = 1;
  53914. + unsigned int *tokenized_data;
  53915. + int err = -EINVAL;
  53916. +
  53917. + cp = buf;
  53918. + while ((cp = strpbrk(cp + 1, " :")))
  53919. + ntokens++;
  53920. +
  53921. + if (!(ntokens & 0x1))
  53922. + goto err;
  53923. +
  53924. + tokenized_data = kmalloc(ntokens * sizeof(unsigned int), GFP_KERNEL);
  53925. + if (!tokenized_data) {
  53926. + err = -ENOMEM;
  53927. + goto err;
  53928. + }
  53929. +
  53930. + cp = buf;
  53931. + i = 0;
  53932. + while (i < ntokens) {
  53933. + if (sscanf(cp, "%u", &tokenized_data[i++]) != 1)
  53934. + goto err_kfree;
  53935. +
  53936. + cp = strpbrk(cp, " :");
  53937. + if (!cp)
  53938. + break;
  53939. + cp++;
  53940. + }
  53941. +
  53942. + if (i != ntokens)
  53943. + goto err_kfree;
  53944. +
  53945. + *num_tokens = ntokens;
  53946. + return tokenized_data;
  53947. +
  53948. +err_kfree:
  53949. + kfree(tokenized_data);
  53950. +err:
  53951. + return ERR_PTR(err);
  53952. +}
  53953. +
  53954. +static ssize_t show_target_loads(
  53955. + struct cpufreq_interactive_tunables *tunables,
  53956. + char *buf)
  53957. +{
  53958. + int i;
  53959. + ssize_t ret = 0;
  53960. + unsigned long flags;
  53961. +
  53962. + spin_lock_irqsave(&tunables->target_loads_lock, flags);
  53963. +
  53964. + for (i = 0; i < tunables->ntarget_loads; i++)
  53965. + ret += sprintf(buf + ret, "%u%s", tunables->target_loads[i],
  53966. + i & 0x1 ? ":" : " ");
  53967. +
  53968. + sprintf(buf + ret - 1, "\n");
  53969. + spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
  53970. + return ret;
  53971. +}
  53972. +
  53973. +static ssize_t store_target_loads(
  53974. + struct cpufreq_interactive_tunables *tunables,
  53975. + const char *buf, size_t count)
  53976. +{
  53977. + int ntokens;
  53978. + unsigned int *new_target_loads = NULL;
  53979. + unsigned long flags;
  53980. +
  53981. + new_target_loads = get_tokenized_data(buf, &ntokens);
  53982. + if (IS_ERR(new_target_loads))
  53983. + return PTR_RET(new_target_loads);
  53984. +
  53985. + spin_lock_irqsave(&tunables->target_loads_lock, flags);
  53986. + if (tunables->target_loads != default_target_loads)
  53987. + kfree(tunables->target_loads);
  53988. + tunables->target_loads = new_target_loads;
  53989. + tunables->ntarget_loads = ntokens;
  53990. + spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
  53991. + return count;
  53992. +}
  53993. +
  53994. +static ssize_t show_above_hispeed_delay(
  53995. + struct cpufreq_interactive_tunables *tunables, char *buf)
  53996. +{
  53997. + int i;
  53998. + ssize_t ret = 0;
  53999. + unsigned long flags;
  54000. +
  54001. + spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
  54002. +
  54003. + for (i = 0; i < tunables->nabove_hispeed_delay; i++)
  54004. + ret += sprintf(buf + ret, "%u%s",
  54005. + tunables->above_hispeed_delay[i],
  54006. + i & 0x1 ? ":" : " ");
  54007. +
  54008. + sprintf(buf + ret - 1, "\n");
  54009. + spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
  54010. + return ret;
  54011. +}
  54012. +
  54013. +static ssize_t store_above_hispeed_delay(
  54014. + struct cpufreq_interactive_tunables *tunables,
  54015. + const char *buf, size_t count)
  54016. +{
  54017. + int ntokens;
  54018. + unsigned int *new_above_hispeed_delay = NULL;
  54019. + unsigned long flags;
  54020. +
  54021. + new_above_hispeed_delay = get_tokenized_data(buf, &ntokens);
  54022. + if (IS_ERR(new_above_hispeed_delay))
  54023. + return PTR_RET(new_above_hispeed_delay);
  54024. +
  54025. + spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
  54026. + if (tunables->above_hispeed_delay != default_above_hispeed_delay)
  54027. + kfree(tunables->above_hispeed_delay);
  54028. + tunables->above_hispeed_delay = new_above_hispeed_delay;
  54029. + tunables->nabove_hispeed_delay = ntokens;
  54030. + spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
  54031. + return count;
  54032. +
  54033. +}
  54034. +
  54035. +static ssize_t show_hispeed_freq(struct cpufreq_interactive_tunables *tunables,
  54036. + char *buf)
  54037. +{
  54038. + return sprintf(buf, "%u\n", tunables->hispeed_freq);
  54039. +}
  54040. +
  54041. +static ssize_t store_hispeed_freq(struct cpufreq_interactive_tunables *tunables,
  54042. + const char *buf, size_t count)
  54043. +{
  54044. + int ret;
  54045. + long unsigned int val;
  54046. +
  54047. + ret = strict_strtoul(buf, 0, &val);
  54048. + if (ret < 0)
  54049. + return ret;
  54050. + tunables->hispeed_freq = val;
  54051. + return count;
  54052. +}
  54053. +
  54054. +static ssize_t show_go_hispeed_load(struct cpufreq_interactive_tunables
  54055. + *tunables, char *buf)
  54056. +{
  54057. + return sprintf(buf, "%lu\n", tunables->go_hispeed_load);
  54058. +}
  54059. +
  54060. +static ssize_t store_go_hispeed_load(struct cpufreq_interactive_tunables
  54061. + *tunables, const char *buf, size_t count)
  54062. +{
  54063. + int ret;
  54064. + unsigned long val;
  54065. +
  54066. + ret = strict_strtoul(buf, 0, &val);
  54067. + if (ret < 0)
  54068. + return ret;
  54069. + tunables->go_hispeed_load = val;
  54070. + return count;
  54071. +}
  54072. +
  54073. +static ssize_t show_min_sample_time(struct cpufreq_interactive_tunables
  54074. + *tunables, char *buf)
  54075. +{
  54076. + return sprintf(buf, "%lu\n", tunables->min_sample_time);
  54077. +}
  54078. +
  54079. +static ssize_t store_min_sample_time(struct cpufreq_interactive_tunables
  54080. + *tunables, const char *buf, size_t count)
  54081. +{
  54082. + int ret;
  54083. + unsigned long val;
  54084. +
  54085. + ret = strict_strtoul(buf, 0, &val);
  54086. + if (ret < 0)
  54087. + return ret;
  54088. + tunables->min_sample_time = val;
  54089. + return count;
  54090. +}
  54091. +
  54092. +static ssize_t show_timer_rate(struct cpufreq_interactive_tunables *tunables,
  54093. + char *buf)
  54094. +{
  54095. + return sprintf(buf, "%lu\n", tunables->timer_rate);
  54096. +}
  54097. +
  54098. +static ssize_t store_timer_rate(struct cpufreq_interactive_tunables *tunables,
  54099. + const char *buf, size_t count)
  54100. +{
  54101. + int ret;
  54102. + unsigned long val;
  54103. +
  54104. + ret = strict_strtoul(buf, 0, &val);
  54105. + if (ret < 0)
  54106. + return ret;
  54107. + tunables->timer_rate = val;
  54108. + return count;
  54109. +}
  54110. +
  54111. +static ssize_t show_timer_slack(struct cpufreq_interactive_tunables *tunables,
  54112. + char *buf)
  54113. +{
  54114. + return sprintf(buf, "%d\n", tunables->timer_slack_val);
  54115. +}
  54116. +
  54117. +static ssize_t store_timer_slack(struct cpufreq_interactive_tunables *tunables,
  54118. + const char *buf, size_t count)
  54119. +{
  54120. + int ret;
  54121. + unsigned long val;
  54122. +
  54123. + ret = kstrtol(buf, 10, &val);
  54124. + if (ret < 0)
  54125. + return ret;
  54126. +
  54127. + tunables->timer_slack_val = val;
  54128. + return count;
  54129. +}
  54130. +
  54131. +static ssize_t show_boost(struct cpufreq_interactive_tunables *tunables,
  54132. + char *buf)
  54133. +{
  54134. + return sprintf(buf, "%d\n", tunables->boost_val);
  54135. +}
  54136. +
  54137. +static ssize_t store_boost(struct cpufreq_interactive_tunables *tunables,
  54138. + const char *buf, size_t count)
  54139. +{
  54140. + int ret;
  54141. + unsigned long val;
  54142. +
  54143. + ret = kstrtoul(buf, 0, &val);
  54144. + if (ret < 0)
  54145. + return ret;
  54146. +
  54147. + tunables->boost_val = val;
  54148. +
  54149. + if (tunables->boost_val) {
  54150. + trace_cpufreq_interactive_boost("on");
  54151. + cpufreq_interactive_boost();
  54152. + } else {
  54153. + trace_cpufreq_interactive_unboost("off");
  54154. + }
  54155. +
  54156. + return count;
  54157. +}
  54158. +
  54159. +static ssize_t store_boostpulse(struct cpufreq_interactive_tunables *tunables,
  54160. + const char *buf, size_t count)
  54161. +{
  54162. + int ret;
  54163. + unsigned long val;
  54164. +
  54165. + ret = kstrtoul(buf, 0, &val);
  54166. + if (ret < 0)
  54167. + return ret;
  54168. +
  54169. + tunables->boostpulse_endtime = ktime_to_us(ktime_get()) +
  54170. + tunables->boostpulse_duration_val;
  54171. + trace_cpufreq_interactive_boost("pulse");
  54172. + cpufreq_interactive_boost();
  54173. + return count;
  54174. +}
  54175. +
  54176. +static ssize_t show_boostpulse_duration(struct cpufreq_interactive_tunables
  54177. + *tunables, char *buf)
  54178. +{
  54179. + return sprintf(buf, "%d\n", tunables->boostpulse_duration_val);
  54180. +}
  54181. +
  54182. +static ssize_t store_boostpulse_duration(struct cpufreq_interactive_tunables
  54183. + *tunables, const char *buf, size_t count)
  54184. +{
  54185. + int ret;
  54186. + unsigned long val;
  54187. +
  54188. + ret = kstrtoul(buf, 0, &val);
  54189. + if (ret < 0)
  54190. + return ret;
  54191. +
  54192. + tunables->boostpulse_duration_val = val;
  54193. + return count;
  54194. +}
  54195. +
  54196. +static ssize_t show_io_is_busy(struct cpufreq_interactive_tunables *tunables,
  54197. + char *buf)
  54198. +{
  54199. + return sprintf(buf, "%u\n", tunables->io_is_busy);
  54200. +}
  54201. +
  54202. +static ssize_t store_io_is_busy(struct cpufreq_interactive_tunables *tunables,
  54203. + const char *buf, size_t count)
  54204. +{
  54205. + int ret;
  54206. + unsigned long val;
  54207. +
  54208. + ret = kstrtoul(buf, 0, &val);
  54209. + if (ret < 0)
  54210. + return ret;
  54211. + tunables->io_is_busy = val;
  54212. + return count;
  54213. +}
  54214. +
  54215. +/*
  54216. + * Create show/store routines
  54217. + * - sys: One governor instance for complete SYSTEM
  54218. + * - pol: One governor instance per struct cpufreq_policy
  54219. + */
  54220. +#define show_gov_pol_sys(file_name) \
  54221. +static ssize_t show_##file_name##_gov_sys \
  54222. +(struct kobject *kobj, struct attribute *attr, char *buf) \
  54223. +{ \
  54224. + return show_##file_name(common_tunables, buf); \
  54225. +} \
  54226. + \
  54227. +static ssize_t show_##file_name##_gov_pol \
  54228. +(struct cpufreq_policy *policy, char *buf) \
  54229. +{ \
  54230. + return show_##file_name(policy->governor_data, buf); \
  54231. +}
  54232. +
  54233. +#define store_gov_pol_sys(file_name) \
  54234. +static ssize_t store_##file_name##_gov_sys \
  54235. +(struct kobject *kobj, struct attribute *attr, const char *buf, \
  54236. + size_t count) \
  54237. +{ \
  54238. + return store_##file_name(common_tunables, buf, count); \
  54239. +} \
  54240. + \
  54241. +static ssize_t store_##file_name##_gov_pol \
  54242. +(struct cpufreq_policy *policy, const char *buf, size_t count) \
  54243. +{ \
  54244. + return store_##file_name(policy->governor_data, buf, count); \
  54245. +}
  54246. +
  54247. +#define show_store_gov_pol_sys(file_name) \
  54248. +show_gov_pol_sys(file_name); \
  54249. +store_gov_pol_sys(file_name)
  54250. +
  54251. +show_store_gov_pol_sys(target_loads);
  54252. +show_store_gov_pol_sys(above_hispeed_delay);
  54253. +show_store_gov_pol_sys(hispeed_freq);
  54254. +show_store_gov_pol_sys(go_hispeed_load);
  54255. +show_store_gov_pol_sys(min_sample_time);
  54256. +show_store_gov_pol_sys(timer_rate);
  54257. +show_store_gov_pol_sys(timer_slack);
  54258. +show_store_gov_pol_sys(boost);
  54259. +store_gov_pol_sys(boostpulse);
  54260. +show_store_gov_pol_sys(boostpulse_duration);
  54261. +show_store_gov_pol_sys(io_is_busy);
  54262. +
  54263. +#define gov_sys_attr_rw(_name) \
  54264. +static struct global_attr _name##_gov_sys = \
  54265. +__ATTR(_name, 0644, show_##_name##_gov_sys, store_##_name##_gov_sys)
  54266. +
  54267. +#define gov_pol_attr_rw(_name) \
  54268. +static struct freq_attr _name##_gov_pol = \
  54269. +__ATTR(_name, 0644, show_##_name##_gov_pol, store_##_name##_gov_pol)
  54270. +
  54271. +#define gov_sys_pol_attr_rw(_name) \
  54272. + gov_sys_attr_rw(_name); \
  54273. + gov_pol_attr_rw(_name)
  54274. +
  54275. +gov_sys_pol_attr_rw(target_loads);
  54276. +gov_sys_pol_attr_rw(above_hispeed_delay);
  54277. +gov_sys_pol_attr_rw(hispeed_freq);
  54278. +gov_sys_pol_attr_rw(go_hispeed_load);
  54279. +gov_sys_pol_attr_rw(min_sample_time);
  54280. +gov_sys_pol_attr_rw(timer_rate);
  54281. +gov_sys_pol_attr_rw(timer_slack);
  54282. +gov_sys_pol_attr_rw(boost);
  54283. +gov_sys_pol_attr_rw(boostpulse_duration);
  54284. +gov_sys_pol_attr_rw(io_is_busy);
  54285. +
  54286. +static struct global_attr boostpulse_gov_sys =
  54287. + __ATTR(boostpulse, 0200, NULL, store_boostpulse_gov_sys);
  54288. +
  54289. +static struct freq_attr boostpulse_gov_pol =
  54290. + __ATTR(boostpulse, 0200, NULL, store_boostpulse_gov_pol);
  54291. +
  54292. +/* One Governor instance for entire system */
  54293. +static struct attribute *interactive_attributes_gov_sys[] = {
  54294. + &target_loads_gov_sys.attr,
  54295. + &above_hispeed_delay_gov_sys.attr,
  54296. + &hispeed_freq_gov_sys.attr,
  54297. + &go_hispeed_load_gov_sys.attr,
  54298. + &min_sample_time_gov_sys.attr,
  54299. + &timer_rate_gov_sys.attr,
  54300. + &timer_slack_gov_sys.attr,
  54301. + &boost_gov_sys.attr,
  54302. + &boostpulse_gov_sys.attr,
  54303. + &boostpulse_duration_gov_sys.attr,
  54304. + &io_is_busy_gov_sys.attr,
  54305. + NULL,
  54306. +};
  54307. +
  54308. +static struct attribute_group interactive_attr_group_gov_sys = {
  54309. + .attrs = interactive_attributes_gov_sys,
  54310. + .name = "interactive",
  54311. +};
  54312. +
  54313. +/* Per policy governor instance */
  54314. +static struct attribute *interactive_attributes_gov_pol[] = {
  54315. + &target_loads_gov_pol.attr,
  54316. + &above_hispeed_delay_gov_pol.attr,
  54317. + &hispeed_freq_gov_pol.attr,
  54318. + &go_hispeed_load_gov_pol.attr,
  54319. + &min_sample_time_gov_pol.attr,
  54320. + &timer_rate_gov_pol.attr,
  54321. + &timer_slack_gov_pol.attr,
  54322. + &boost_gov_pol.attr,
  54323. + &boostpulse_gov_pol.attr,
  54324. + &boostpulse_duration_gov_pol.attr,
  54325. + &io_is_busy_gov_pol.attr,
  54326. + NULL,
  54327. +};
  54328. +
  54329. +static struct attribute_group interactive_attr_group_gov_pol = {
  54330. + .attrs = interactive_attributes_gov_pol,
  54331. + .name = "interactive",
  54332. +};
  54333. +
  54334. +static struct attribute_group *get_sysfs_attr(void)
  54335. +{
  54336. + if (have_governor_per_policy())
  54337. + return &interactive_attr_group_gov_pol;
  54338. + else
  54339. + return &interactive_attr_group_gov_sys;
  54340. +}
  54341. +
  54342. +static int cpufreq_interactive_idle_notifier(struct notifier_block *nb,
  54343. + unsigned long val,
  54344. + void *data)
  54345. +{
  54346. + switch (val) {
  54347. + case IDLE_START:
  54348. + cpufreq_interactive_idle_start();
  54349. + break;
  54350. + case IDLE_END:
  54351. + cpufreq_interactive_idle_end();
  54352. + break;
  54353. + }
  54354. +
  54355. + return 0;
  54356. +}
  54357. +
  54358. +static struct notifier_block cpufreq_interactive_idle_nb = {
  54359. + .notifier_call = cpufreq_interactive_idle_notifier,
  54360. +};
  54361. +
  54362. +static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
  54363. + unsigned int event)
  54364. +{
  54365. + int rc;
  54366. + unsigned int j;
  54367. + struct cpufreq_interactive_cpuinfo *pcpu;
  54368. + struct cpufreq_frequency_table *freq_table;
  54369. + struct cpufreq_interactive_tunables *tunables;
  54370. +
  54371. + if (have_governor_per_policy())
  54372. + tunables = policy->governor_data;
  54373. + else
  54374. + tunables = common_tunables;
  54375. +
  54376. + WARN_ON(!tunables && (event != CPUFREQ_GOV_POLICY_INIT));
  54377. +
  54378. + switch (event) {
  54379. + case CPUFREQ_GOV_POLICY_INIT:
  54380. + if (have_governor_per_policy()) {
  54381. + WARN_ON(tunables);
  54382. + } else if (tunables) {
  54383. + tunables->usage_count++;
  54384. + policy->governor_data = tunables;
  54385. + return 0;
  54386. + }
  54387. +
  54388. + tunables = kzalloc(sizeof(*tunables), GFP_KERNEL);
  54389. + if (!tunables) {
  54390. + pr_err("%s: POLICY_INIT: kzalloc failed\n", __func__);
  54391. + return -ENOMEM;
  54392. + }
  54393. +
  54394. + tunables->usage_count = 1;
  54395. + tunables->above_hispeed_delay = default_above_hispeed_delay;
  54396. + tunables->nabove_hispeed_delay =
  54397. + ARRAY_SIZE(default_above_hispeed_delay);
  54398. + tunables->go_hispeed_load = DEFAULT_GO_HISPEED_LOAD;
  54399. + tunables->target_loads = default_target_loads;
  54400. + tunables->ntarget_loads = ARRAY_SIZE(default_target_loads);
  54401. + tunables->min_sample_time = DEFAULT_MIN_SAMPLE_TIME;
  54402. + tunables->timer_rate = DEFAULT_TIMER_RATE;
  54403. + tunables->boostpulse_duration_val = DEFAULT_MIN_SAMPLE_TIME;
  54404. + tunables->timer_slack_val = DEFAULT_TIMER_SLACK;
  54405. +
  54406. + spin_lock_init(&tunables->target_loads_lock);
  54407. + spin_lock_init(&tunables->above_hispeed_delay_lock);
  54408. +
  54409. + policy->governor_data = tunables;
  54410. + if (!have_governor_per_policy()) {
  54411. + common_tunables = tunables;
  54412. + WARN_ON(cpufreq_get_global_kobject());
  54413. + }
  54414. +
  54415. + rc = sysfs_create_group(get_governor_parent_kobj(policy),
  54416. + get_sysfs_attr());
  54417. + if (rc) {
  54418. + kfree(tunables);
  54419. + policy->governor_data = NULL;
  54420. + if (!have_governor_per_policy())
  54421. + common_tunables = NULL;
  54422. + return rc;
  54423. + }
  54424. +
  54425. + if (!policy->governor->initialized) {
  54426. + idle_notifier_register(&cpufreq_interactive_idle_nb);
  54427. + cpufreq_register_notifier(&cpufreq_notifier_block,
  54428. + CPUFREQ_TRANSITION_NOTIFIER);
  54429. + }
  54430. +
  54431. + break;
  54432. +
  54433. + case CPUFREQ_GOV_POLICY_EXIT:
  54434. + if (!--tunables->usage_count) {
  54435. + sysfs_remove_group(get_governor_parent_kobj(policy),
  54436. + get_sysfs_attr());
  54437. +
  54438. + if (!have_governor_per_policy())
  54439. + cpufreq_put_global_kobject();
  54440. +
  54441. + if (policy->governor->initialized == 1) {
  54442. + cpufreq_unregister_notifier(&cpufreq_notifier_block,
  54443. + CPUFREQ_TRANSITION_NOTIFIER);
  54444. + idle_notifier_unregister(&cpufreq_interactive_idle_nb);
  54445. + }
  54446. +
  54447. + kfree(tunables);
  54448. + common_tunables = NULL;
  54449. + }
  54450. +
  54451. + policy->governor_data = NULL;
  54452. + break;
  54453. +
  54454. + case CPUFREQ_GOV_START:
  54455. + mutex_lock(&gov_lock);
  54456. +
  54457. + freq_table = cpufreq_frequency_get_table(policy->cpu);
  54458. + if (!tunables->hispeed_freq)
  54459. + tunables->hispeed_freq = policy->max;
  54460. +
  54461. + for_each_cpu(j, policy->cpus) {
  54462. + pcpu = &per_cpu(cpuinfo, j);
  54463. + pcpu->policy = policy;
  54464. + pcpu->target_freq = policy->cur;
  54465. + pcpu->freq_table = freq_table;
  54466. + pcpu->floor_freq = pcpu->target_freq;
  54467. + pcpu->floor_validate_time =
  54468. + ktime_to_us(ktime_get());
  54469. + pcpu->hispeed_validate_time =
  54470. + pcpu->floor_validate_time;
  54471. + down_write(&pcpu->enable_sem);
  54472. + del_timer_sync(&pcpu->cpu_timer);
  54473. + del_timer_sync(&pcpu->cpu_slack_timer);
  54474. + cpufreq_interactive_timer_start(tunables, j);
  54475. + pcpu->governor_enabled = 1;
  54476. + up_write(&pcpu->enable_sem);
  54477. + }
  54478. +
  54479. + mutex_unlock(&gov_lock);
  54480. + break;
  54481. +
  54482. + case CPUFREQ_GOV_STOP:
  54483. + mutex_lock(&gov_lock);
  54484. + for_each_cpu(j, policy->cpus) {
  54485. + pcpu = &per_cpu(cpuinfo, j);
  54486. + down_write(&pcpu->enable_sem);
  54487. + pcpu->governor_enabled = 0;
  54488. + del_timer_sync(&pcpu->cpu_timer);
  54489. + del_timer_sync(&pcpu->cpu_slack_timer);
  54490. + up_write(&pcpu->enable_sem);
  54491. + }
  54492. +
  54493. + mutex_unlock(&gov_lock);
  54494. + break;
  54495. +
  54496. + case CPUFREQ_GOV_LIMITS:
  54497. + if (policy->max < policy->cur)
  54498. + __cpufreq_driver_target(policy,
  54499. + policy->max, CPUFREQ_RELATION_H);
  54500. + else if (policy->min > policy->cur)
  54501. + __cpufreq_driver_target(policy,
  54502. + policy->min, CPUFREQ_RELATION_L);
  54503. + for_each_cpu(j, policy->cpus) {
  54504. + pcpu = &per_cpu(cpuinfo, j);
  54505. +
  54506. + /* hold write semaphore to avoid race */
  54507. + down_write(&pcpu->enable_sem);
  54508. + if (pcpu->governor_enabled == 0) {
  54509. + up_write(&pcpu->enable_sem);
  54510. + continue;
  54511. + }
  54512. +
  54513. + /* update target_freq firstly */
  54514. + if (policy->max < pcpu->target_freq)
  54515. + pcpu->target_freq = policy->max;
  54516. + else if (policy->min > pcpu->target_freq)
  54517. + pcpu->target_freq = policy->min;
  54518. +
  54519. + /* Reschedule timer.
  54520. + * Delete the timers, else the timer callback may
  54521. + * return without re-arm the timer when failed
  54522. + * acquire the semaphore. This race may cause timer
  54523. + * stopped unexpectedly.
  54524. + */
  54525. + del_timer_sync(&pcpu->cpu_timer);
  54526. + del_timer_sync(&pcpu->cpu_slack_timer);
  54527. + cpufreq_interactive_timer_start(tunables, j);
  54528. + up_write(&pcpu->enable_sem);
  54529. + }
  54530. + break;
  54531. + }
  54532. + return 0;
  54533. +}
  54534. +
  54535. +#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE
  54536. +static
  54537. +#endif
  54538. +struct cpufreq_governor cpufreq_gov_interactive = {
  54539. + .name = "interactive",
  54540. + .governor = cpufreq_governor_interactive,
  54541. + .max_transition_latency = 10000000,
  54542. + .owner = THIS_MODULE,
  54543. +};
  54544. +
  54545. +static void cpufreq_interactive_nop_timer(unsigned long data)
  54546. +{
  54547. +}
  54548. +
  54549. +static int __init cpufreq_interactive_init(void)
  54550. +{
  54551. + unsigned int i;
  54552. + struct cpufreq_interactive_cpuinfo *pcpu;
  54553. + struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
  54554. +
  54555. + /* Initalize per-cpu timers */
  54556. + for_each_possible_cpu(i) {
  54557. + pcpu = &per_cpu(cpuinfo, i);
  54558. + init_timer_deferrable(&pcpu->cpu_timer);
  54559. + pcpu->cpu_timer.function = cpufreq_interactive_timer;
  54560. + pcpu->cpu_timer.data = i;
  54561. + init_timer(&pcpu->cpu_slack_timer);
  54562. + pcpu->cpu_slack_timer.function = cpufreq_interactive_nop_timer;
  54563. + spin_lock_init(&pcpu->load_lock);
  54564. + init_rwsem(&pcpu->enable_sem);
  54565. + }
  54566. +
  54567. + spin_lock_init(&speedchange_cpumask_lock);
  54568. + mutex_init(&gov_lock);
  54569. + speedchange_task =
  54570. + kthread_create(cpufreq_interactive_speedchange_task, NULL,
  54571. + "cfinteractive");
  54572. + if (IS_ERR(speedchange_task))
  54573. + return PTR_ERR(speedchange_task);
  54574. +
  54575. + sched_setscheduler_nocheck(speedchange_task, SCHED_FIFO, &param);
  54576. + get_task_struct(speedchange_task);
  54577. +
  54578. + /* NB: wake up so the thread does not look hung to the freezer */
  54579. + wake_up_process(speedchange_task);
  54580. +
  54581. + return cpufreq_register_governor(&cpufreq_gov_interactive);
  54582. +}
  54583. +
  54584. +#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE
  54585. +fs_initcall(cpufreq_interactive_init);
  54586. +#else
  54587. +module_init(cpufreq_interactive_init);
  54588. +#endif
  54589. +
  54590. +static void __exit cpufreq_interactive_exit(void)
  54591. +{
  54592. + cpufreq_unregister_governor(&cpufreq_gov_interactive);
  54593. + kthread_stop(speedchange_task);
  54594. + put_task_struct(speedchange_task);
  54595. +}
  54596. +
  54597. +module_exit(cpufreq_interactive_exit);
  54598. +
  54599. +MODULE_AUTHOR("Mike Chan <mike@android.com>");
  54600. +MODULE_DESCRIPTION("'cpufreq_interactive' - A cpufreq governor for "
  54601. + "Latency sensitive workloads");
  54602. +MODULE_LICENSE("GPL");
  54603. diff -Nur linux-3.14.14/drivers/cpufreq/highbank-cpufreq.c linux-imx6-3.14/drivers/cpufreq/highbank-cpufreq.c
  54604. --- linux-3.14.14/drivers/cpufreq/highbank-cpufreq.c 2014-07-28 10:07:25.000000000 -0500
  54605. +++ linux-imx6-3.14/drivers/cpufreq/highbank-cpufreq.c 2014-12-08 00:31:52.540418001 -0600
  54606. @@ -19,7 +19,7 @@
  54607. #include <linux/cpu.h>
  54608. #include <linux/err.h>
  54609. #include <linux/of.h>
  54610. -#include <linux/mailbox.h>
  54611. +#include <linux/pl320-ipc.h>
  54612. #include <linux/platform_device.h>
  54613. #define HB_CPUFREQ_CHANGE_NOTE 0x80000001
  54614. diff -Nur linux-3.14.14/drivers/cpufreq/imx6-cpufreq.c linux-imx6-3.14/drivers/cpufreq/imx6-cpufreq.c
  54615. --- linux-3.14.14/drivers/cpufreq/imx6-cpufreq.c 1969-12-31 18:00:00.000000000 -0600
  54616. +++ linux-imx6-3.14/drivers/cpufreq/imx6-cpufreq.c 2014-12-08 00:31:52.540418001 -0600
  54617. @@ -0,0 +1,393 @@
  54618. +/*
  54619. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  54620. + *
  54621. + * This program is free software; you can redistribute it and/or modify
  54622. + * it under the terms of the GNU General Public License version 2 as
  54623. + * published by the Free Software Foundation.
  54624. + */
  54625. +
  54626. +#include <linux/busfreq-imx6.h>
  54627. +#include <linux/clk.h>
  54628. +#include <linux/cpu.h>
  54629. +#include <linux/cpufreq.h>
  54630. +#include <linux/delay.h>
  54631. +#include <linux/err.h>
  54632. +#include <linux/module.h>
  54633. +#include <linux/of.h>
  54634. +#include <linux/pm_opp.h>
  54635. +#include <linux/platform_device.h>
  54636. +#include <linux/regulator/consumer.h>
  54637. +#include <linux/suspend.h>
  54638. +
  54639. +#define PU_SOC_VOLTAGE_NORMAL 1250000
  54640. +#define PU_SOC_VOLTAGE_HIGH 1275000
  54641. +#define FREQ_1P2_GHZ 1200000000
  54642. +
  54643. +static struct regulator *arm_reg;
  54644. +static struct regulator *pu_reg;
  54645. +static struct regulator *soc_reg;
  54646. +
  54647. +static struct clk *arm_clk;
  54648. +static struct clk *pll1_sys_clk;
  54649. +static struct clk *pll1_sw_clk;
  54650. +static struct clk *step_clk;
  54651. +static struct clk *pll2_pfd2_396m_clk;
  54652. +
  54653. +static struct device *cpu_dev;
  54654. +static struct cpufreq_frequency_table *freq_table;
  54655. +static unsigned int transition_latency;
  54656. +static struct mutex set_cpufreq_lock;
  54657. +
  54658. +static u32 *imx6_soc_volt;
  54659. +static u32 soc_opp_count;
  54660. +
  54661. +static int imx6_set_target(struct cpufreq_policy *policy, unsigned int index)
  54662. +{
  54663. + struct dev_pm_opp *opp;
  54664. + unsigned long freq_hz, volt, volt_old;
  54665. + unsigned int old_freq, new_freq;
  54666. + int ret;
  54667. +
  54668. + mutex_lock(&set_cpufreq_lock);
  54669. +
  54670. + new_freq = freq_table[index].frequency;
  54671. + freq_hz = new_freq * 1000;
  54672. + old_freq = clk_get_rate(arm_clk) / 1000;
  54673. +
  54674. + rcu_read_lock();
  54675. + opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
  54676. + if (IS_ERR(opp)) {
  54677. + rcu_read_unlock();
  54678. + dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
  54679. + ret = PTR_ERR(opp);
  54680. + goto unlock;
  54681. + }
  54682. +
  54683. + volt = dev_pm_opp_get_voltage(opp);
  54684. + rcu_read_unlock();
  54685. + volt_old = regulator_get_voltage(arm_reg);
  54686. +
  54687. + dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
  54688. + old_freq / 1000, volt_old / 1000,
  54689. + new_freq / 1000, volt / 1000);
  54690. +
  54691. + /*
  54692. + * CPU freq is increasing, so need to ensure
  54693. + * that bus frequency is increased too.
  54694. + */
  54695. + if (old_freq == freq_table[0].frequency)
  54696. + request_bus_freq(BUS_FREQ_HIGH);
  54697. +
  54698. + /* scaling up? scale voltage before frequency */
  54699. + if (new_freq > old_freq) {
  54700. + if (regulator_is_enabled(pu_reg)) {
  54701. + ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  54702. + if (ret) {
  54703. + dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
  54704. + goto unlock;
  54705. + }
  54706. + }
  54707. + ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  54708. + if (ret) {
  54709. + dev_err(cpu_dev, "failed to scale vddsoc up: %d\n", ret);
  54710. + goto unlock;
  54711. + }
  54712. + ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  54713. + if (ret) {
  54714. + dev_err(cpu_dev,
  54715. + "failed to scale vddarm up: %d\n", ret);
  54716. + goto unlock;
  54717. + }
  54718. + }
  54719. +
  54720. + /*
  54721. + * The setpoints are selected per PLL/PDF frequencies, so we need to
  54722. + * reprogram PLL for frequency scaling. The procedure of reprogramming
  54723. + * PLL1 is as below.
  54724. + *
  54725. + * - Enable pll2_pfd2_396m_clk and reparent pll1_sw_clk to it
  54726. + * - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it
  54727. + * - Disable pll2_pfd2_396m_clk
  54728. + */
  54729. + clk_set_parent(step_clk, pll2_pfd2_396m_clk);
  54730. + clk_set_parent(pll1_sw_clk, step_clk);
  54731. + if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) {
  54732. + clk_set_rate(pll1_sys_clk, new_freq * 1000);
  54733. + clk_set_parent(pll1_sw_clk, pll1_sys_clk);
  54734. + }
  54735. +
  54736. + /* Ensure the arm clock divider is what we expect */
  54737. + ret = clk_set_rate(arm_clk, new_freq * 1000);
  54738. + if (ret) {
  54739. + dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
  54740. + regulator_set_voltage_tol(arm_reg, volt_old, 0);
  54741. + goto unlock;
  54742. + }
  54743. +
  54744. + /* scaling down? scale voltage after frequency */
  54745. + if (new_freq < old_freq) {
  54746. + ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  54747. + if (ret) {
  54748. + dev_warn(cpu_dev,
  54749. + "failed to scale vddarm down: %d\n", ret);
  54750. + ret = 0;
  54751. + }
  54752. + ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  54753. + if (ret) {
  54754. + dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);
  54755. + ret = 0;
  54756. + }
  54757. + if (regulator_is_enabled(pu_reg)) {
  54758. + ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  54759. + if (ret) {
  54760. + dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
  54761. + ret = 0;
  54762. + }
  54763. + }
  54764. + }
  54765. +
  54766. + if (policy->cur == freq_table[0].frequency)
  54767. + release_bus_freq(BUS_FREQ_HIGH);
  54768. +
  54769. +unlock:
  54770. + mutex_unlock(&set_cpufreq_lock);
  54771. + return ret;
  54772. +}
  54773. +
  54774. +static int imx6_cpufreq_init(struct cpufreq_policy *policy)
  54775. +{
  54776. + policy->clk = arm_clk;
  54777. +
  54778. + if (policy->cur > freq_table[0].frequency)
  54779. + request_bus_freq(BUS_FREQ_HIGH);
  54780. +
  54781. + return cpufreq_generic_init(policy, freq_table, transition_latency);
  54782. +}
  54783. +
  54784. +static struct cpufreq_driver imx6_cpufreq_driver = {
  54785. + .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
  54786. + .verify = cpufreq_generic_frequency_table_verify,
  54787. + .target_index = imx6_set_target,
  54788. + .get = cpufreq_generic_get,
  54789. + .init = imx6_cpufreq_init,
  54790. + .exit = cpufreq_generic_exit,
  54791. + .name = "imx6-cpufreq",
  54792. + .attr = cpufreq_generic_attr,
  54793. +};
  54794. +
  54795. +static int imx6_cpufreq_pm_notify(struct notifier_block *nb,
  54796. + unsigned long event, void *dummy)
  54797. +{
  54798. + struct cpufreq_policy *data = cpufreq_cpu_get(0);
  54799. + static u32 cpufreq_policy_min_pre_suspend;
  54800. +
  54801. + /*
  54802. + * During suspend/resume, When cpufreq driver try to increase
  54803. + * voltage/freq, it needs to control I2C/SPI to communicate
  54804. + * with external PMIC to adjust voltage, but these I2C/SPI
  54805. + * devices may be already suspended, to avoid such scenario,
  54806. + * we just increase cpufreq to highest setpoint before suspend.
  54807. + */
  54808. + switch (event) {
  54809. + case PM_SUSPEND_PREPARE:
  54810. + cpufreq_policy_min_pre_suspend = data->user_policy.min;
  54811. + data->user_policy.min = data->user_policy.max;
  54812. + break;
  54813. + case PM_POST_SUSPEND:
  54814. + data->user_policy.min = cpufreq_policy_min_pre_suspend;
  54815. + break;
  54816. + default:
  54817. + break;
  54818. + }
  54819. +
  54820. + cpufreq_update_policy(0);
  54821. +
  54822. + return NOTIFY_OK;
  54823. +}
  54824. +
  54825. +static struct notifier_block imx6_cpufreq_pm_notifier = {
  54826. + .notifier_call = imx6_cpufreq_pm_notify,
  54827. +};
  54828. +
  54829. +static int imx6_cpufreq_probe(struct platform_device *pdev)
  54830. +{
  54831. + struct device_node *np;
  54832. + struct dev_pm_opp *opp;
  54833. + unsigned long min_volt, max_volt;
  54834. + int num, ret;
  54835. + const struct property *prop;
  54836. + const __be32 *val;
  54837. + u32 nr, i, j;
  54838. +
  54839. + cpu_dev = get_cpu_device(0);
  54840. + if (!cpu_dev) {
  54841. + pr_err("failed to get cpu0 device\n");
  54842. + return -ENODEV;
  54843. + }
  54844. +
  54845. + np = of_node_get(cpu_dev->of_node);
  54846. + if (!np) {
  54847. + dev_err(cpu_dev, "failed to find cpu0 node\n");
  54848. + return -ENOENT;
  54849. + }
  54850. +
  54851. + arm_clk = devm_clk_get(cpu_dev, "arm");
  54852. + pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
  54853. + pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
  54854. + step_clk = devm_clk_get(cpu_dev, "step");
  54855. + pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m");
  54856. + if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
  54857. + IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
  54858. + dev_err(cpu_dev, "failed to get clocks\n");
  54859. + ret = -ENOENT;
  54860. + goto put_node;
  54861. + }
  54862. +
  54863. + arm_reg = devm_regulator_get(cpu_dev, "arm");
  54864. + pu_reg = devm_regulator_get(cpu_dev, "pu");
  54865. + soc_reg = devm_regulator_get(cpu_dev, "soc");
  54866. + if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
  54867. + dev_err(cpu_dev, "failed to get regulators\n");
  54868. + ret = -ENOENT;
  54869. + goto put_node;
  54870. + }
  54871. +
  54872. + /*
  54873. + * We expect an OPP table supplied by platform.
  54874. + * Just, incase the platform did not supply the OPP
  54875. + * table, it will try to get it.
  54876. + */
  54877. + num = dev_pm_opp_get_opp_count(cpu_dev);
  54878. + if (num < 0) {
  54879. + ret = of_init_opp_table(cpu_dev);
  54880. + if (ret < 0) {
  54881. + dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
  54882. + goto put_node;
  54883. + }
  54884. +
  54885. + num = dev_pm_opp_get_opp_count(cpu_dev);
  54886. + if (num < 0) {
  54887. + ret = num;
  54888. + dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
  54889. + goto put_node;
  54890. + }
  54891. + }
  54892. +
  54893. + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
  54894. + if (ret) {
  54895. + dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
  54896. + goto put_node;
  54897. + }
  54898. +
  54899. + /* Make imx6_soc_volt array's size same as arm opp number */
  54900. + imx6_soc_volt = devm_kzalloc(cpu_dev, sizeof(*imx6_soc_volt) * num, GFP_KERNEL);
  54901. + if (imx6_soc_volt == NULL) {
  54902. + ret = -ENOMEM;
  54903. + goto free_freq_table;
  54904. + }
  54905. +
  54906. + prop = of_find_property(np, "fsl,soc-operating-points", NULL);
  54907. + if (!prop || !prop->value)
  54908. + goto soc_opp_out;
  54909. +
  54910. + /*
  54911. + * Each OPP is a set of tuples consisting of frequency and
  54912. + * voltage like <freq-kHz vol-uV>.
  54913. + */
  54914. + nr = prop->length / sizeof(u32);
  54915. + if (nr % 2 || (nr / 2) < num)
  54916. + goto soc_opp_out;
  54917. +
  54918. + for (j = 0; j < num; j++) {
  54919. + val = prop->value;
  54920. + for (i = 0; i < nr / 2; i++) {
  54921. + unsigned long freq = be32_to_cpup(val++);
  54922. + unsigned long volt = be32_to_cpup(val++);
  54923. + if (freq_table[j].frequency == freq) {
  54924. + imx6_soc_volt[soc_opp_count++] = volt;
  54925. + break;
  54926. + }
  54927. + }
  54928. + }
  54929. +
  54930. +soc_opp_out:
  54931. + /* use fixed soc opp volt if no valid soc opp info found in dtb */
  54932. + if (soc_opp_count != num) {
  54933. + dev_warn(cpu_dev, "can NOT find valid fsl,soc-operating-points property in dtb, use default value!\n");
  54934. + for (j = 0; j < num; j++)
  54935. + imx6_soc_volt[j] = PU_SOC_VOLTAGE_NORMAL;
  54936. + if (freq_table[num - 1].frequency * 1000 == FREQ_1P2_GHZ)
  54937. + imx6_soc_volt[num - 1] = PU_SOC_VOLTAGE_HIGH;
  54938. + }
  54939. +
  54940. + if (of_property_read_u32(np, "clock-latency", &transition_latency))
  54941. + transition_latency = CPUFREQ_ETERNAL;
  54942. +
  54943. + /*
  54944. + * Calculate the ramp time for max voltage change in the
  54945. + * VDDSOC and VDDPU regulators.
  54946. + */
  54947. + ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  54948. + if (ret > 0)
  54949. + transition_latency += ret * 1000;
  54950. + ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  54951. + if (ret > 0)
  54952. + transition_latency += ret * 1000;
  54953. +
  54954. + /*
  54955. + * OPP is maintained in order of increasing frequency, and
  54956. + * freq_table initialised from OPP is therefore sorted in the
  54957. + * same order.
  54958. + */
  54959. + rcu_read_lock();
  54960. + opp = dev_pm_opp_find_freq_exact(cpu_dev,
  54961. + freq_table[0].frequency * 1000, true);
  54962. + min_volt = dev_pm_opp_get_voltage(opp);
  54963. + opp = dev_pm_opp_find_freq_exact(cpu_dev,
  54964. + freq_table[--num].frequency * 1000, true);
  54965. + max_volt = dev_pm_opp_get_voltage(opp);
  54966. + rcu_read_unlock();
  54967. + ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt);
  54968. + if (ret > 0)
  54969. + transition_latency += ret * 1000;
  54970. +
  54971. + mutex_init(&set_cpufreq_lock);
  54972. + register_pm_notifier(&imx6_cpufreq_pm_notifier);
  54973. +
  54974. + ret = cpufreq_register_driver(&imx6_cpufreq_driver);
  54975. + if (ret) {
  54976. + dev_err(cpu_dev, "failed register driver: %d\n", ret);
  54977. + goto free_freq_table;
  54978. + }
  54979. +
  54980. + of_node_put(np);
  54981. + return 0;
  54982. +
  54983. +free_freq_table:
  54984. + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  54985. +put_node:
  54986. + of_node_put(np);
  54987. + return ret;
  54988. +}
  54989. +
  54990. +static int imx6_cpufreq_remove(struct platform_device *pdev)
  54991. +{
  54992. + cpufreq_unregister_driver(&imx6_cpufreq_driver);
  54993. + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  54994. +
  54995. + return 0;
  54996. +}
  54997. +
  54998. +static struct platform_driver imx6_cpufreq_platdrv = {
  54999. + .driver = {
  55000. + .name = "imx6-cpufreq",
  55001. + .owner = THIS_MODULE,
  55002. + },
  55003. + .probe = imx6_cpufreq_probe,
  55004. + .remove = imx6_cpufreq_remove,
  55005. +};
  55006. +module_platform_driver(imx6_cpufreq_platdrv);
  55007. +
  55008. +MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
  55009. +MODULE_DESCRIPTION("Freescale i.MX6Q cpufreq driver");
  55010. +MODULE_LICENSE("GPL");
  55011. diff -Nur linux-3.14.14/drivers/cpufreq/imx6q-cpufreq.c linux-imx6-3.14/drivers/cpufreq/imx6q-cpufreq.c
  55012. --- linux-3.14.14/drivers/cpufreq/imx6q-cpufreq.c 2014-07-28 10:07:25.000000000 -0500
  55013. +++ linux-imx6-3.14/drivers/cpufreq/imx6q-cpufreq.c 1969-12-31 18:00:00.000000000 -0600
  55014. @@ -1,330 +0,0 @@
  55015. -/*
  55016. - * Copyright (C) 2013 Freescale Semiconductor, Inc.
  55017. - *
  55018. - * This program is free software; you can redistribute it and/or modify
  55019. - * it under the terms of the GNU General Public License version 2 as
  55020. - * published by the Free Software Foundation.
  55021. - */
  55022. -
  55023. -#include <linux/clk.h>
  55024. -#include <linux/cpu.h>
  55025. -#include <linux/cpufreq.h>
  55026. -#include <linux/delay.h>
  55027. -#include <linux/err.h>
  55028. -#include <linux/module.h>
  55029. -#include <linux/of.h>
  55030. -#include <linux/pm_opp.h>
  55031. -#include <linux/platform_device.h>
  55032. -#include <linux/regulator/consumer.h>
  55033. -
  55034. -#define PU_SOC_VOLTAGE_NORMAL 1250000
  55035. -#define PU_SOC_VOLTAGE_HIGH 1275000
  55036. -#define FREQ_1P2_GHZ 1200000000
  55037. -
  55038. -static struct regulator *arm_reg;
  55039. -static struct regulator *pu_reg;
  55040. -static struct regulator *soc_reg;
  55041. -
  55042. -static struct clk *arm_clk;
  55043. -static struct clk *pll1_sys_clk;
  55044. -static struct clk *pll1_sw_clk;
  55045. -static struct clk *step_clk;
  55046. -static struct clk *pll2_pfd2_396m_clk;
  55047. -
  55048. -static struct device *cpu_dev;
  55049. -static struct cpufreq_frequency_table *freq_table;
  55050. -static unsigned int transition_latency;
  55051. -
  55052. -static u32 *imx6_soc_volt;
  55053. -static u32 soc_opp_count;
  55054. -
  55055. -static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
  55056. -{
  55057. - struct dev_pm_opp *opp;
  55058. - unsigned long freq_hz, volt, volt_old;
  55059. - unsigned int old_freq, new_freq;
  55060. - int ret;
  55061. -
  55062. - new_freq = freq_table[index].frequency;
  55063. - freq_hz = new_freq * 1000;
  55064. - old_freq = clk_get_rate(arm_clk) / 1000;
  55065. -
  55066. - rcu_read_lock();
  55067. - opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
  55068. - if (IS_ERR(opp)) {
  55069. - rcu_read_unlock();
  55070. - dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
  55071. - return PTR_ERR(opp);
  55072. - }
  55073. -
  55074. - volt = dev_pm_opp_get_voltage(opp);
  55075. - rcu_read_unlock();
  55076. - volt_old = regulator_get_voltage(arm_reg);
  55077. -
  55078. - dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
  55079. - old_freq / 1000, volt_old / 1000,
  55080. - new_freq / 1000, volt / 1000);
  55081. -
  55082. - /* scaling up? scale voltage before frequency */
  55083. - if (new_freq > old_freq) {
  55084. - ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  55085. - if (ret) {
  55086. - dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
  55087. - return ret;
  55088. - }
  55089. - ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  55090. - if (ret) {
  55091. - dev_err(cpu_dev, "failed to scale vddsoc up: %d\n", ret);
  55092. - return ret;
  55093. - }
  55094. - ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  55095. - if (ret) {
  55096. - dev_err(cpu_dev,
  55097. - "failed to scale vddarm up: %d\n", ret);
  55098. - return ret;
  55099. - }
  55100. - }
  55101. -
  55102. - /*
  55103. - * The setpoints are selected per PLL/PDF frequencies, so we need to
  55104. - * reprogram PLL for frequency scaling. The procedure of reprogramming
  55105. - * PLL1 is as below.
  55106. - *
  55107. - * - Enable pll2_pfd2_396m_clk and reparent pll1_sw_clk to it
  55108. - * - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it
  55109. - * - Disable pll2_pfd2_396m_clk
  55110. - */
  55111. - clk_set_parent(step_clk, pll2_pfd2_396m_clk);
  55112. - clk_set_parent(pll1_sw_clk, step_clk);
  55113. - if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) {
  55114. - clk_set_rate(pll1_sys_clk, new_freq * 1000);
  55115. - clk_set_parent(pll1_sw_clk, pll1_sys_clk);
  55116. - }
  55117. -
  55118. - /* Ensure the arm clock divider is what we expect */
  55119. - ret = clk_set_rate(arm_clk, new_freq * 1000);
  55120. - if (ret) {
  55121. - dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
  55122. - regulator_set_voltage_tol(arm_reg, volt_old, 0);
  55123. - return ret;
  55124. - }
  55125. -
  55126. - /* scaling down? scale voltage after frequency */
  55127. - if (new_freq < old_freq) {
  55128. - ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  55129. - if (ret) {
  55130. - dev_warn(cpu_dev,
  55131. - "failed to scale vddarm down: %d\n", ret);
  55132. - ret = 0;
  55133. - }
  55134. - ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  55135. - if (ret) {
  55136. - dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);
  55137. - ret = 0;
  55138. - }
  55139. - ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  55140. - if (ret) {
  55141. - dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
  55142. - ret = 0;
  55143. - }
  55144. - }
  55145. -
  55146. - return 0;
  55147. -}
  55148. -
  55149. -static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
  55150. -{
  55151. - policy->clk = arm_clk;
  55152. - return cpufreq_generic_init(policy, freq_table, transition_latency);
  55153. -}
  55154. -
  55155. -static struct cpufreq_driver imx6q_cpufreq_driver = {
  55156. - .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
  55157. - .verify = cpufreq_generic_frequency_table_verify,
  55158. - .target_index = imx6q_set_target,
  55159. - .get = cpufreq_generic_get,
  55160. - .init = imx6q_cpufreq_init,
  55161. - .exit = cpufreq_generic_exit,
  55162. - .name = "imx6q-cpufreq",
  55163. - .attr = cpufreq_generic_attr,
  55164. -};
  55165. -
  55166. -static int imx6q_cpufreq_probe(struct platform_device *pdev)
  55167. -{
  55168. - struct device_node *np;
  55169. - struct dev_pm_opp *opp;
  55170. - unsigned long min_volt, max_volt;
  55171. - int num, ret;
  55172. - const struct property *prop;
  55173. - const __be32 *val;
  55174. - u32 nr, i, j;
  55175. -
  55176. - cpu_dev = get_cpu_device(0);
  55177. - if (!cpu_dev) {
  55178. - pr_err("failed to get cpu0 device\n");
  55179. - return -ENODEV;
  55180. - }
  55181. -
  55182. - np = of_node_get(cpu_dev->of_node);
  55183. - if (!np) {
  55184. - dev_err(cpu_dev, "failed to find cpu0 node\n");
  55185. - return -ENOENT;
  55186. - }
  55187. -
  55188. - arm_clk = devm_clk_get(cpu_dev, "arm");
  55189. - pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
  55190. - pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
  55191. - step_clk = devm_clk_get(cpu_dev, "step");
  55192. - pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m");
  55193. - if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
  55194. - IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
  55195. - dev_err(cpu_dev, "failed to get clocks\n");
  55196. - ret = -ENOENT;
  55197. - goto put_node;
  55198. - }
  55199. -
  55200. - arm_reg = devm_regulator_get(cpu_dev, "arm");
  55201. - pu_reg = devm_regulator_get(cpu_dev, "pu");
  55202. - soc_reg = devm_regulator_get(cpu_dev, "soc");
  55203. - if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
  55204. - dev_err(cpu_dev, "failed to get regulators\n");
  55205. - ret = -ENOENT;
  55206. - goto put_node;
  55207. - }
  55208. -
  55209. - /*
  55210. - * We expect an OPP table supplied by platform.
  55211. - * Just, incase the platform did not supply the OPP
  55212. - * table, it will try to get it.
  55213. - */
  55214. - num = dev_pm_opp_get_opp_count(cpu_dev);
  55215. - if (num < 0) {
  55216. - ret = of_init_opp_table(cpu_dev);
  55217. - if (ret < 0) {
  55218. - dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
  55219. - goto put_node;
  55220. - }
  55221. -
  55222. - num = dev_pm_opp_get_opp_count(cpu_dev);
  55223. - if (num < 0) {
  55224. - ret = num;
  55225. - dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
  55226. - goto put_node;
  55227. - }
  55228. - }
  55229. -
  55230. - ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
  55231. - if (ret) {
  55232. - dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
  55233. - goto put_node;
  55234. - }
  55235. -
  55236. - /* Make imx6_soc_volt array's size same as arm opp number */
  55237. - imx6_soc_volt = devm_kzalloc(cpu_dev, sizeof(*imx6_soc_volt) * num, GFP_KERNEL);
  55238. - if (imx6_soc_volt == NULL) {
  55239. - ret = -ENOMEM;
  55240. - goto free_freq_table;
  55241. - }
  55242. -
  55243. - prop = of_find_property(np, "fsl,soc-operating-points", NULL);
  55244. - if (!prop || !prop->value)
  55245. - goto soc_opp_out;
  55246. -
  55247. - /*
  55248. - * Each OPP is a set of tuples consisting of frequency and
  55249. - * voltage like <freq-kHz vol-uV>.
  55250. - */
  55251. - nr = prop->length / sizeof(u32);
  55252. - if (nr % 2 || (nr / 2) < num)
  55253. - goto soc_opp_out;
  55254. -
  55255. - for (j = 0; j < num; j++) {
  55256. - val = prop->value;
  55257. - for (i = 0; i < nr / 2; i++) {
  55258. - unsigned long freq = be32_to_cpup(val++);
  55259. - unsigned long volt = be32_to_cpup(val++);
  55260. - if (freq_table[j].frequency == freq) {
  55261. - imx6_soc_volt[soc_opp_count++] = volt;
  55262. - break;
  55263. - }
  55264. - }
  55265. - }
  55266. -
  55267. -soc_opp_out:
  55268. - /* use fixed soc opp volt if no valid soc opp info found in dtb */
  55269. - if (soc_opp_count != num) {
  55270. - dev_warn(cpu_dev, "can NOT find valid fsl,soc-operating-points property in dtb, use default value!\n");
  55271. - for (j = 0; j < num; j++)
  55272. - imx6_soc_volt[j] = PU_SOC_VOLTAGE_NORMAL;
  55273. - if (freq_table[num - 1].frequency * 1000 == FREQ_1P2_GHZ)
  55274. - imx6_soc_volt[num - 1] = PU_SOC_VOLTAGE_HIGH;
  55275. - }
  55276. -
  55277. - if (of_property_read_u32(np, "clock-latency", &transition_latency))
  55278. - transition_latency = CPUFREQ_ETERNAL;
  55279. -
  55280. - /*
  55281. - * Calculate the ramp time for max voltage change in the
  55282. - * VDDSOC and VDDPU regulators.
  55283. - */
  55284. - ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  55285. - if (ret > 0)
  55286. - transition_latency += ret * 1000;
  55287. - ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  55288. - if (ret > 0)
  55289. - transition_latency += ret * 1000;
  55290. -
  55291. - /*
  55292. - * OPP is maintained in order of increasing frequency, and
  55293. - * freq_table initialised from OPP is therefore sorted in the
  55294. - * same order.
  55295. - */
  55296. - rcu_read_lock();
  55297. - opp = dev_pm_opp_find_freq_exact(cpu_dev,
  55298. - freq_table[0].frequency * 1000, true);
  55299. - min_volt = dev_pm_opp_get_voltage(opp);
  55300. - opp = dev_pm_opp_find_freq_exact(cpu_dev,
  55301. - freq_table[--num].frequency * 1000, true);
  55302. - max_volt = dev_pm_opp_get_voltage(opp);
  55303. - rcu_read_unlock();
  55304. - ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt);
  55305. - if (ret > 0)
  55306. - transition_latency += ret * 1000;
  55307. -
  55308. - ret = cpufreq_register_driver(&imx6q_cpufreq_driver);
  55309. - if (ret) {
  55310. - dev_err(cpu_dev, "failed register driver: %d\n", ret);
  55311. - goto free_freq_table;
  55312. - }
  55313. -
  55314. - of_node_put(np);
  55315. - return 0;
  55316. -
  55317. -free_freq_table:
  55318. - dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  55319. -put_node:
  55320. - of_node_put(np);
  55321. - return ret;
  55322. -}
  55323. -
  55324. -static int imx6q_cpufreq_remove(struct platform_device *pdev)
  55325. -{
  55326. - cpufreq_unregister_driver(&imx6q_cpufreq_driver);
  55327. - dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  55328. -
  55329. - return 0;
  55330. -}
  55331. -
  55332. -static struct platform_driver imx6q_cpufreq_platdrv = {
  55333. - .driver = {
  55334. - .name = "imx6q-cpufreq",
  55335. - .owner = THIS_MODULE,
  55336. - },
  55337. - .probe = imx6q_cpufreq_probe,
  55338. - .remove = imx6q_cpufreq_remove,
  55339. -};
  55340. -module_platform_driver(imx6q_cpufreq_platdrv);
  55341. -
  55342. -MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
  55343. -MODULE_DESCRIPTION("Freescale i.MX6Q cpufreq driver");
  55344. -MODULE_LICENSE("GPL");
  55345. diff -Nur linux-3.14.14/drivers/cpufreq/Kconfig linux-imx6-3.14/drivers/cpufreq/Kconfig
  55346. --- linux-3.14.14/drivers/cpufreq/Kconfig 2014-07-28 10:07:25.000000000 -0500
  55347. +++ linux-imx6-3.14/drivers/cpufreq/Kconfig 2014-12-08 00:31:52.536418001 -0600
  55348. @@ -91,6 +91,15 @@
  55349. governor. If unsure have a look at the help section of the
  55350. driver. Fallback governor will be the performance governor.
  55351. +config CPU_FREQ_DEFAULT_GOV_INTERACTIVE
  55352. + bool "interactive"
  55353. + select CPU_FREQ_GOV_INTERACTIVE
  55354. + help
  55355. + Use the CPUFreq governor 'interactive' as default. This allows
  55356. + you to get a full dynamic cpu frequency capable system by simply
  55357. + loading your cpufreq low-level hardware driver, using the
  55358. + 'interactive' governor for latency-sensitive workloads.
  55359. +
  55360. config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
  55361. bool "conservative"
  55362. select CPU_FREQ_GOV_CONSERVATIVE
  55363. @@ -157,6 +166,24 @@
  55364. For details, take a look at linux/Documentation/cpu-freq.
  55365. + If in doubt, say N.
  55366. +
  55367. +config CPU_FREQ_GOV_INTERACTIVE
  55368. + tristate "'interactive' cpufreq policy governor"
  55369. + default n
  55370. + help
  55371. + 'interactive' - This driver adds a dynamic cpufreq policy governor
  55372. + designed for latency-sensitive workloads.
  55373. +
  55374. + This governor attempts to reduce the latency of clock
  55375. + increases so that the system is more responsive to
  55376. + interactive workloads.
  55377. +
  55378. + To compile this driver as a module, choose M here: the
  55379. + module will be called cpufreq_interactive.
  55380. +
  55381. + For details, take a look at linux/Documentation/cpu-freq.
  55382. +
  55383. If in doubt, say N.
  55384. config CPU_FREQ_GOV_CONSERVATIVE
  55385. diff -Nur linux-3.14.14/drivers/cpufreq/Kconfig.arm linux-imx6-3.14/drivers/cpufreq/Kconfig.arm
  55386. --- linux-3.14.14/drivers/cpufreq/Kconfig.arm 2014-07-28 10:07:25.000000000 -0500
  55387. +++ linux-imx6-3.14/drivers/cpufreq/Kconfig.arm 2014-12-08 00:31:52.536418001 -0600
  55388. @@ -4,7 +4,8 @@
  55389. config ARM_BIG_LITTLE_CPUFREQ
  55390. tristate "Generic ARM big LITTLE CPUfreq driver"
  55391. - depends on ARM && BIG_LITTLE && ARM_CPU_TOPOLOGY && HAVE_CLK
  55392. + depends on (BIG_LITTLE && ARM_CPU_TOPOLOGY) || (ARM64 && SMP)
  55393. + depends on HAVE_CLK
  55394. select PM_OPP
  55395. help
  55396. This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
  55397. @@ -95,7 +96,7 @@
  55398. If in doubt, say N.
  55399. -config ARM_IMX6Q_CPUFREQ
  55400. +config ARM_IMX6_CPUFREQ
  55401. tristate "Freescale i.MX6 cpufreq support"
  55402. depends on ARCH_MXC
  55403. depends on REGULATOR_ANATOP
  55404. diff -Nur linux-3.14.14/drivers/cpufreq/Makefile linux-imx6-3.14/drivers/cpufreq/Makefile
  55405. --- linux-3.14.14/drivers/cpufreq/Makefile 2014-07-28 10:07:25.000000000 -0500
  55406. +++ linux-imx6-3.14/drivers/cpufreq/Makefile 2014-12-08 00:31:52.536418001 -0600
  55407. @@ -8,6 +8,7 @@
  55408. obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
  55409. obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
  55410. obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o
  55411. +obj-$(CONFIG_CPU_FREQ_GOV_INTERACTIVE) += cpufreq_interactive.o
  55412. obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o
  55413. obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o
  55414. @@ -55,7 +56,7 @@
  55415. obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o
  55416. obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o
  55417. obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o
  55418. -obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
  55419. +obj-$(CONFIG_ARM_IMX6_CPUFREQ) += imx6-cpufreq.o
  55420. obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o
  55421. obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
  55422. obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
  55423. diff -Nur linux-3.14.14/drivers/crypto/caam/secvio.c linux-imx6-3.14/drivers/crypto/caam/secvio.c
  55424. --- linux-3.14.14/drivers/crypto/caam/secvio.c 1969-12-31 18:00:00.000000000 -0600
  55425. +++ linux-imx6-3.14/drivers/crypto/caam/secvio.c 2014-12-08 00:31:52.552418001 -0600
  55426. @@ -0,0 +1,335 @@
  55427. +
  55428. +/*
  55429. + * CAAM/SEC 4.x Security Violation Handler
  55430. + * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
  55431. + */
  55432. +
  55433. +#include "compat.h"
  55434. +#include "intern.h"
  55435. +#include "secvio.h"
  55436. +#include "regs.h"
  55437. +
  55438. +/*
  55439. + * These names are associated with each violation handler.
  55440. + * The source names were taken from MX6, and are based on recommendations
  55441. + * for most common SoCs.
  55442. + */
  55443. +static const u8 *violation_src_name[] = {
  55444. + "CAAM Security Violation",
  55445. + "JTAG Alarm",
  55446. + "Watchdog",
  55447. + "(reserved)",
  55448. + "External Boot",
  55449. + "Tamper Detect",
  55450. +};
  55451. +
  55452. +/* Top-level security violation interrupt */
  55453. +static irqreturn_t caam_secvio_interrupt(int irq, void *snvsdev)
  55454. +{
  55455. + struct device *dev = snvsdev;
  55456. + struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
  55457. + u32 irqstate;
  55458. +
  55459. + /* Check the HP secvio status register */
  55460. + irqstate = rd_reg32(&svpriv->svregs->hp.secvio_status) |
  55461. + HP_SECVIOST_SECVIOMASK;
  55462. +
  55463. + if (!irqstate)
  55464. + return IRQ_NONE;
  55465. +
  55466. + /* Mask out one or more causes for deferred service */
  55467. + clrbits32(&svpriv->svregs->hp.secvio_int_ctl, irqstate);
  55468. +
  55469. + /* Now ACK causes */
  55470. + setbits32(&svpriv->svregs->hp.secvio_status, irqstate);
  55471. +
  55472. + /* And run deferred service */
  55473. + preempt_disable();
  55474. + tasklet_schedule(&svpriv->irqtask[smp_processor_id()]);
  55475. + preempt_enable();
  55476. +
  55477. + return IRQ_HANDLED;
  55478. +}
  55479. +
  55480. +/* Deferred service handler. Tasklet arg is simply the SNVS dev */
  55481. +static void caam_secvio_dispatch(unsigned long indev)
  55482. +{
  55483. + struct device *dev = (struct device *)indev;
  55484. + struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
  55485. + unsigned long flags, cause;
  55486. + int i;
  55487. +
  55488. +
  55489. + /*
  55490. + * Capture the interrupt cause, using masked interrupts as
  55491. + * identification. This only works if all are enabled; if
  55492. + * this changes in the future, a "cause queue" will have to
  55493. + * be built
  55494. + */
  55495. + cause = rd_reg32(&svpriv->svregs->hp.secvio_int_ctl) &
  55496. + (HP_SECVIO_INTEN_SRC5 | HP_SECVIO_INTEN_SRC4 |
  55497. + HP_SECVIO_INTEN_SRC3 | HP_SECVIO_INTEN_SRC2 |
  55498. + HP_SECVIO_INTEN_SRC1 | HP_SECVIO_INTEN_SRC0);
  55499. +
  55500. + /* Look through causes, call each handler if exists */
  55501. + for (i = 0; i < MAX_SECVIO_SOURCES; i++)
  55502. + if (cause & (1 << i)) {
  55503. + spin_lock_irqsave(&svpriv->svlock, flags);
  55504. + svpriv->intsrc[i].handler(dev, i,
  55505. + svpriv->intsrc[i].ext);
  55506. + spin_unlock_irqrestore(&svpriv->svlock, flags);
  55507. + };
  55508. +
  55509. + /* Re-enable now-serviced interrupts */
  55510. + setbits32(&svpriv->svregs->hp.secvio_int_ctl, cause);
  55511. +}
  55512. +
  55513. +/*
  55514. + * Default cause handler, used in lieu of an application-defined handler.
  55515. + * All it does at this time is print a console message. It could force a halt.
  55516. + */
  55517. +static void caam_secvio_default(struct device *dev, u32 cause, void *ext)
  55518. +{
  55519. + struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
  55520. +
  55521. + dev_err(dev, "Unhandled Security Violation Interrupt %d = %s\n",
  55522. + cause, svpriv->intsrc[cause].intname);
  55523. +}
  55524. +
  55525. +/*
  55526. + * Install an application-defined handler for a specified cause
  55527. + * Arguments:
  55528. + * - dev points to SNVS-owning device
  55529. + * - cause interrupt source cause
  55530. + * - handler application-defined handler, gets called with dev
  55531. + * source cause, and locally-defined handler argument
  55532. + * - cause_description points to a string to override the default cause
  55533. + * name, this can be used as an alternate for error
  55534. + * messages and such. If left NULL, the default
  55535. + * description string is used.
  55536. + * - ext pointer to any extra data needed by the handler.
  55537. + */
  55538. +int caam_secvio_install_handler(struct device *dev, enum secvio_cause cause,
  55539. + void (*handler)(struct device *dev, u32 cause,
  55540. + void *ext),
  55541. + u8 *cause_description, void *ext)
  55542. +{
  55543. + unsigned long flags;
  55544. + struct caam_drv_private_secvio *svpriv;
  55545. +
  55546. + svpriv = dev_get_drvdata(dev);
  55547. +
  55548. + if ((handler == NULL) || (cause > SECVIO_CAUSE_SOURCE_5))
  55549. + return -EINVAL;
  55550. +
  55551. + spin_lock_irqsave(&svpriv->svlock, flags);
  55552. + svpriv->intsrc[cause].handler = handler;
  55553. + if (cause_description != NULL)
  55554. + svpriv->intsrc[cause].intname = cause_description;
  55555. + if (ext != NULL)
  55556. + svpriv->intsrc[cause].ext = ext;
  55557. + spin_unlock_irqrestore(&svpriv->svlock, flags);
  55558. +
  55559. + return 0;
  55560. +}
  55561. +EXPORT_SYMBOL(caam_secvio_install_handler);
  55562. +
  55563. +/*
  55564. + * Remove an application-defined handler for a specified cause (and, by
  55565. + * implication, restore the "default".
  55566. + * Arguments:
  55567. + * - dev points to SNVS-owning device
  55568. + * - cause interrupt source cause
  55569. + */
  55570. +int caam_secvio_remove_handler(struct device *dev, enum secvio_cause cause)
  55571. +{
  55572. + unsigned long flags;
  55573. + struct caam_drv_private_secvio *svpriv;
  55574. +
  55575. + svpriv = dev_get_drvdata(dev);
  55576. +
  55577. + if (cause > SECVIO_CAUSE_SOURCE_5)
  55578. + return -EINVAL;
  55579. +
  55580. + spin_lock_irqsave(&svpriv->svlock, flags);
  55581. + svpriv->intsrc[cause].intname = violation_src_name[cause];
  55582. + svpriv->intsrc[cause].handler = caam_secvio_default;
  55583. + svpriv->intsrc[cause].ext = NULL;
  55584. + spin_unlock_irqrestore(&svpriv->svlock, flags);
  55585. + return 0;
  55586. +}
  55587. +EXPORT_SYMBOL(caam_secvio_remove_handler);
  55588. +
  55589. +int caam_secvio_startup(struct platform_device *pdev)
  55590. +{
  55591. + struct device *ctrldev, *svdev;
  55592. + struct caam_drv_private *ctrlpriv;
  55593. + struct caam_drv_private_secvio *svpriv;
  55594. + struct platform_device *svpdev;
  55595. + struct device_node *np;
  55596. + const void *prop;
  55597. + int i, error, secvio_inten_src;
  55598. +
  55599. + ctrldev = &pdev->dev;
  55600. + ctrlpriv = dev_get_drvdata(ctrldev);
  55601. + /*
  55602. + * Set up the private block for secure memory
  55603. + * Only one instance is possible
  55604. + */
  55605. + svpriv = kzalloc(sizeof(struct caam_drv_private_secvio), GFP_KERNEL);
  55606. + if (svpriv == NULL) {
  55607. + dev_err(ctrldev, "can't alloc private mem for secvio\n");
  55608. + return -ENOMEM;
  55609. + }
  55610. + svpriv->parentdev = ctrldev;
  55611. +
  55612. + /* Create the security violation dev */
  55613. +#ifdef CONFIG_OF
  55614. +
  55615. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-secvio");
  55616. + if (!np)
  55617. + return -ENODEV;
  55618. +
  55619. + ctrlpriv->secvio_irq = of_irq_to_resource(np, 0, NULL);
  55620. +
  55621. + prop = of_get_property(np, "secvio_src", NULL);
  55622. + if (prop)
  55623. + secvio_inten_src = of_read_ulong(prop, 1);
  55624. + else
  55625. + secvio_inten_src = HP_SECVIO_INTEN_ALL;
  55626. +
  55627. + printk(KERN_ERR "secvio_inten_src = %x\n", secvio_inten_src);
  55628. +
  55629. + svpdev = of_platform_device_create(np, NULL, ctrldev);
  55630. + if (!svpdev)
  55631. + return -ENODEV;
  55632. +
  55633. +#else
  55634. + svpdev = platform_device_register_data(ctrldev, "caam_secvio", 0,
  55635. + svpriv,
  55636. + sizeof(struct caam_drv_private_secvio));
  55637. +
  55638. + secvio_inten_src = HP_SECVIO_INTEN_ALL;
  55639. +#endif
  55640. + if (svpdev == NULL) {
  55641. + kfree(svpriv);
  55642. + return -EINVAL;
  55643. + }
  55644. + svdev = &svpdev->dev;
  55645. + dev_set_drvdata(svdev, svpriv);
  55646. + ctrlpriv->secviodev = svdev;
  55647. + svpriv->svregs = ctrlpriv->snvs;
  55648. +
  55649. + /*
  55650. + * Now we have all the dev data set up. Init interrupt
  55651. + * source descriptions
  55652. + */
  55653. + for (i = 0; i < MAX_SECVIO_SOURCES; i++) {
  55654. + svpriv->intsrc[i].intname = violation_src_name[i];
  55655. + svpriv->intsrc[i].handler = caam_secvio_default;
  55656. + }
  55657. +
  55658. + /* Connect main handler */
  55659. + for_each_possible_cpu(i)
  55660. + tasklet_init(&svpriv->irqtask[i], caam_secvio_dispatch,
  55661. + (unsigned long)svdev);
  55662. +
  55663. + error = request_irq(ctrlpriv->secvio_irq, caam_secvio_interrupt,
  55664. + IRQF_SHARED, "caam_secvio", svdev);
  55665. + if (error) {
  55666. + dev_err(svdev, "can't connect secvio interrupt\n");
  55667. + irq_dispose_mapping(ctrlpriv->secvio_irq);
  55668. + ctrlpriv->secvio_irq = 0;
  55669. + return -EINVAL;
  55670. + }
  55671. +
  55672. + /* Enable all sources */
  55673. + wr_reg32(&svpriv->svregs->hp.secvio_int_ctl, secvio_inten_src);
  55674. +
  55675. + dev_info(svdev, "security violation service handlers armed\n");
  55676. +
  55677. + return 0;
  55678. +}
  55679. +
  55680. +void caam_secvio_shutdown(struct platform_device *pdev)
  55681. +{
  55682. + struct device *ctrldev, *svdev;
  55683. + struct caam_drv_private *priv;
  55684. + struct caam_drv_private_secvio *svpriv;
  55685. + int i;
  55686. +
  55687. + ctrldev = &pdev->dev;
  55688. + priv = dev_get_drvdata(ctrldev);
  55689. + svdev = priv->secviodev;
  55690. + svpriv = dev_get_drvdata(svdev);
  55691. +
  55692. + /* Shut off all sources */
  55693. +
  55694. + wr_reg32(&svpriv->svregs->hp.secvio_int_ctl, 0);
  55695. +
  55696. + /* Remove tasklets and release interrupt */
  55697. + for_each_possible_cpu(i)
  55698. + tasklet_kill(&svpriv->irqtask[i]);
  55699. +
  55700. + free_irq(priv->secvio_irq, svdev);
  55701. +
  55702. + kfree(svpriv);
  55703. +}
  55704. +
  55705. +
  55706. +#ifdef CONFIG_OF
  55707. +static void __exit caam_secvio_exit(void)
  55708. +{
  55709. + struct device_node *dev_node;
  55710. + struct platform_device *pdev;
  55711. +
  55712. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  55713. + if (!dev_node) {
  55714. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  55715. + if (!dev_node)
  55716. + return;
  55717. + }
  55718. +
  55719. + pdev = of_find_device_by_node(dev_node);
  55720. + if (!pdev)
  55721. + return;
  55722. +
  55723. + of_node_get(dev_node);
  55724. +
  55725. + caam_secvio_shutdown(pdev);
  55726. +
  55727. +}
  55728. +
  55729. +static int __init caam_secvio_init(void)
  55730. +{
  55731. + struct device_node *dev_node;
  55732. + struct platform_device *pdev;
  55733. +
  55734. + /*
  55735. + * Do of_find_compatible_node() then of_find_device_by_node()
  55736. + * once a functional device tree is available
  55737. + */
  55738. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  55739. + if (!dev_node) {
  55740. + dev_node = of_find_compatible_node(NULL, NULL,
  55741. + "arm,imx6-caam-secvio");
  55742. + if (!dev_node)
  55743. + return -ENODEV;
  55744. + }
  55745. +
  55746. + pdev = of_find_device_by_node(dev_node);
  55747. + if (!pdev)
  55748. + return -ENODEV;
  55749. +
  55750. + of_node_put(dev_node);
  55751. +
  55752. + return caam_secvio_startup(pdev);
  55753. +}
  55754. +
  55755. +module_init(caam_secvio_init);
  55756. +module_exit(caam_secvio_exit);
  55757. +
  55758. +MODULE_LICENSE("Dual BSD/GPL");
  55759. +MODULE_DESCRIPTION("FSL CAAM/SNVS Security Violation Handler");
  55760. +MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
  55761. +#endif
  55762. diff -Nur linux-3.14.14/drivers/crypto/caam/secvio.h linux-imx6-3.14/drivers/crypto/caam/secvio.h
  55763. --- linux-3.14.14/drivers/crypto/caam/secvio.h 1969-12-31 18:00:00.000000000 -0600
  55764. +++ linux-imx6-3.14/drivers/crypto/caam/secvio.h 2014-12-08 00:31:52.552418001 -0600
  55765. @@ -0,0 +1,64 @@
  55766. +
  55767. +/*
  55768. + * CAAM Security Violation Handler
  55769. + * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
  55770. + */
  55771. +
  55772. +#ifndef SECVIO_H
  55773. +#define SECVIO_H
  55774. +
  55775. +#include "snvsregs.h"
  55776. +
  55777. +
  55778. +/*
  55779. + * Defines the published interfaces to install/remove application-specified
  55780. + * handlers for catching violations
  55781. + */
  55782. +
  55783. +#define MAX_SECVIO_SOURCES 6
  55784. +
  55785. +/* these are the untranslated causes */
  55786. +enum secvio_cause {
  55787. + SECVIO_CAUSE_SOURCE_0,
  55788. + SECVIO_CAUSE_SOURCE_1,
  55789. + SECVIO_CAUSE_SOURCE_2,
  55790. + SECVIO_CAUSE_SOURCE_3,
  55791. + SECVIO_CAUSE_SOURCE_4,
  55792. + SECVIO_CAUSE_SOURCE_5
  55793. +};
  55794. +
  55795. +/* These are common "recommended" cause definitions for most devices */
  55796. +#define SECVIO_CAUSE_CAAM_VIOLATION SECVIO_CAUSE_SOURCE_0
  55797. +#define SECVIO_CAUSE JTAG_ALARM SECVIO_CAUSE_SOURCE_1
  55798. +#define SECVIO_CAUSE_WATCHDOG SECVIO_CAUSE_SOURCE_2
  55799. +#define SECVIO_CAUSE_EXTERNAL_BOOT SECVIO_CAUSE_SOURCE_4
  55800. +#define SECVIO_CAUSE_TAMPER_DETECT SECVIO_CAUSE_SOURCE_5
  55801. +
  55802. +int caam_secvio_install_handler(struct device *dev, enum secvio_cause cause,
  55803. + void (*handler)(struct device *dev, u32 cause,
  55804. + void *ext),
  55805. + u8 *cause_description, void *ext);
  55806. +int caam_secvio_remove_handler(struct device *dev, enum secvio_cause cause);
  55807. +
  55808. +/*
  55809. + * Private data definitions for the secvio "driver"
  55810. + */
  55811. +
  55812. +struct secvio_int_src {
  55813. + const u8 *intname; /* Points to a descriptive name for source */
  55814. + void *ext; /* Extended data to pass to the handler */
  55815. + void (*handler)(struct device *dev, u32 cause, void *ext);
  55816. +};
  55817. +
  55818. +struct caam_drv_private_secvio {
  55819. + struct device *parentdev; /* points back to the controller */
  55820. + spinlock_t svlock ____cacheline_aligned;
  55821. + struct tasklet_struct irqtask[NR_CPUS];
  55822. + struct snvs_full __iomem *svregs; /* both HP and LP domains */
  55823. +
  55824. + /* Registered handlers for each violation */
  55825. + struct secvio_int_src intsrc[MAX_SECVIO_SOURCES];
  55826. +
  55827. +};
  55828. +
  55829. +#endif /* SECVIO_H */
  55830. diff -Nur linux-3.14.14/drivers/crypto/caam/sm.h linux-imx6-3.14/drivers/crypto/caam/sm.h
  55831. --- linux-3.14.14/drivers/crypto/caam/sm.h 1969-12-31 18:00:00.000000000 -0600
  55832. +++ linux-imx6-3.14/drivers/crypto/caam/sm.h 2014-12-08 00:31:52.552418001 -0600
  55833. @@ -0,0 +1,88 @@
  55834. +
  55835. +/*
  55836. + * CAAM Secure Memory/Keywrap API Definitions
  55837. + * Copyright (C) 2008-2013 Freescale Semiconductor, Inc.
  55838. + */
  55839. +
  55840. +#ifndef SM_H
  55841. +#define SM_H
  55842. +
  55843. +
  55844. +/* Storage access permissions */
  55845. +#define SM_PERM_READ 0x01
  55846. +#define SM_PERM_WRITE 0x02
  55847. +#define SM_PERM_BLOB 0x03
  55848. +
  55849. +
  55850. +/* Keystore maintenance functions */
  55851. +void sm_init_keystore(struct device *dev);
  55852. +u32 sm_detect_keystore_units(struct device *dev);
  55853. +int sm_establish_keystore(struct device *dev, u32 unit);
  55854. +void sm_release_keystore(struct device *dev, u32 unit);
  55855. +void caam_sm_shutdown(struct platform_device *pdev);
  55856. +int caam_sm_example_init(struct platform_device *pdev);
  55857. +
  55858. +/* Keystore accessor functions */
  55859. +extern int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size,
  55860. + u32 *slot);
  55861. +extern int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot);
  55862. +extern int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
  55863. + const u8 *key_data, u32 key_length);
  55864. +extern int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
  55865. + u32 key_length, u8 *key_data);
  55866. +extern int sm_keystore_slot_encapsulate(struct device *dev, u32 unit,
  55867. + u32 inslot, u32 outslot, u16 secretlen,
  55868. + u8 *keymod, u16 keymodlen);
  55869. +extern int sm_keystore_slot_decapsulate(struct device *dev, u32 unit,
  55870. + u32 inslot, u32 outslot, u16 secretlen,
  55871. + u8 *keymod, u16 keymodlen);
  55872. +
  55873. +/* Data structure to hold per-slot information */
  55874. +struct keystore_data_slot_info {
  55875. + u8 allocated; /* Track slot assignments */
  55876. + u32 key_length; /* Size of the key */
  55877. +};
  55878. +
  55879. +/* Data structure to hold keystore information */
  55880. +struct keystore_data {
  55881. + void *base_address; /* Base of the Secure Partition */
  55882. + u32 slot_count; /* Number of slots in the keystore */
  55883. + struct keystore_data_slot_info *slot; /* Per-slot information */
  55884. +};
  55885. +
  55886. +/* store the detected attributes of a secure memory page */
  55887. +struct sm_page_descriptor {
  55888. + u16 phys_pagenum; /* may be discontiguous */
  55889. + u16 own_part; /* Owning partition */
  55890. + void *pg_base; /* Calculated virtual address */
  55891. + struct keystore_data *ksdata;
  55892. +};
  55893. +
  55894. +struct caam_drv_private_sm {
  55895. + struct device *parentdev; /* this ends up as the controller */
  55896. + struct device *smringdev; /* ring that owns this instance */
  55897. + spinlock_t kslock ____cacheline_aligned;
  55898. +
  55899. + /* Default parameters for geometry */
  55900. + u32 max_pages; /* maximum pages this instance can support */
  55901. + u32 top_partition; /* highest partition number in this instance */
  55902. + u32 top_page; /* highest page number in this instance */
  55903. + u32 page_size; /* page size */
  55904. + u32 slot_size; /* selected size of each storage block */
  55905. +
  55906. + /* Partition/Page Allocation Map */
  55907. + u32 localpages; /* Number of pages we can access */
  55908. + struct sm_page_descriptor *pagedesc; /* Allocated per-page */
  55909. +
  55910. + /* Installed handlers for keystore access */
  55911. + int (*data_init)(struct device *dev, u32 unit);
  55912. + void (*data_cleanup)(struct device *dev, u32 unit);
  55913. + int (*slot_alloc)(struct device *dev, u32 unit, u32 size, u32 *slot);
  55914. + int (*slot_dealloc)(struct device *dev, u32 unit, u32 slot);
  55915. + void *(*slot_get_address)(struct device *dev, u32 unit, u32 handle);
  55916. + u32 (*slot_get_base)(struct device *dev, u32 unit, u32 handle);
  55917. + u32 (*slot_get_offset)(struct device *dev, u32 unit, u32 handle);
  55918. + u32 (*slot_get_slot_size)(struct device *dev, u32 unit, u32 handle);
  55919. +};
  55920. +
  55921. +#endif /* SM_H */
  55922. diff -Nur linux-3.14.14/drivers/crypto/caam/sm_store.c linux-imx6-3.14/drivers/crypto/caam/sm_store.c
  55923. --- linux-3.14.14/drivers/crypto/caam/sm_store.c 1969-12-31 18:00:00.000000000 -0600
  55924. +++ linux-imx6-3.14/drivers/crypto/caam/sm_store.c 2014-12-08 00:31:52.552418001 -0600
  55925. @@ -0,0 +1,896 @@
  55926. +
  55927. +/*
  55928. + * CAAM Secure Memory Storage Interface
  55929. + * Copyright (C) 2008-2013 Freescale Semiconductor, Inc.
  55930. + *
  55931. + * Loosely based on the SHW Keystore API for SCC/SCC2
  55932. + * Experimental implementation and NOT intended for upstream use. Expect
  55933. + * this interface to be amended significantly in the future once it becomes
  55934. + * integrated into live applications.
  55935. + *
  55936. + * Known issues:
  55937. + *
  55938. + * - Executes one instance of an secure memory "driver". This is tied to the
  55939. + * fact that job rings can't run as standalone instances in the present
  55940. + * configuration.
  55941. + *
  55942. + * - It does not expose a userspace interface. The value of a userspace
  55943. + * interface for access to secrets is a point for further architectural
  55944. + * discussion.
  55945. + *
  55946. + * - Partition/permission management is not part of this interface. It
  55947. + * depends on some level of "knowledge" agreed upon between bootloader,
  55948. + * provisioning applications, and OS-hosted software (which uses this
  55949. + * driver).
  55950. + *
  55951. + * - No means of identifying the location or purpose of secrets managed by
  55952. + * this interface exists; "slot location" and format of a given secret
  55953. + * needs to be agreed upon between bootloader, provisioner, and OS-hosted
  55954. + * application.
  55955. + */
  55956. +
  55957. +#include "compat.h"
  55958. +#include "regs.h"
  55959. +#include "jr.h"
  55960. +#include "desc.h"
  55961. +#include "intern.h"
  55962. +#include "error.h"
  55963. +#include "sm.h"
  55964. +
  55965. +#ifdef SM_DEBUG_CONT
  55966. +void sm_show_page(struct device *dev, struct sm_page_descriptor *pgdesc)
  55967. +{
  55968. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  55969. + u32 i, *smdata;
  55970. +
  55971. + dev_info(dev, "physical page %d content at 0x%08x\n",
  55972. + pgdesc->phys_pagenum, pgdesc->pg_base);
  55973. + smdata = pgdesc->pg_base;
  55974. + for (i = 0; i < (smpriv->page_size / sizeof(u32)); i += 4)
  55975. + dev_info(dev, "[0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n",
  55976. + (u32)&smdata[i], smdata[i], smdata[i+1], smdata[i+2],
  55977. + smdata[i+3]);
  55978. +}
  55979. +#endif
  55980. +
  55981. +/*
  55982. + * Construct a secure memory blob encapsulation job descriptor
  55983. + *
  55984. + * - desc pointer to hold new (to be allocated) pointer to the generated
  55985. + * descriptor for later use. Calling thread can kfree the
  55986. + * descriptor after execution.
  55987. + * - keymod Physical pointer to key modifier (contiguous piece).
  55988. + * - keymodsz Size of key modifier in bytes (should normally be 8).
  55989. + * - secretbuf Physical pointer (within an accessible secure memory page)
  55990. + * of the secret to be encapsulated.
  55991. + * - outbuf Physical pointer (within an accessible secure memory page)
  55992. + * of the encapsulated output. This will be larger than the
  55993. + * input secret because of the added encapsulation data.
  55994. + * - secretsz Size of input secret, in bytes.
  55995. + * - auth If nonzero, use AES-CCM for encapsulation, else use ECB
  55996. + *
  55997. + * Note: this uses 32-bit pointers at present
  55998. + */
  55999. +#define INITIAL_DESCSZ 16 /* size of tmp buffer for descriptor const. */
  56000. +static int blob_encap_desc(u32 **desc, dma_addr_t keymod, u16 keymodsz,
  56001. + dma_addr_t secretbuf, dma_addr_t outbuf,
  56002. + u16 secretsz, bool auth)
  56003. +{
  56004. + u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
  56005. + u16 dsize, idx;
  56006. +
  56007. + memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
  56008. + idx = 1;
  56009. +
  56010. + /* Load key modifier */
  56011. + tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY |
  56012. + ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK) |
  56013. + (keymodsz & LDST_LEN_MASK);
  56014. +
  56015. + tmpdesc[idx++] = (u32)keymod;
  56016. +
  56017. + /* Encapsulate to secure memory */
  56018. + tmpdesc[idx++] = CMD_SEQ_IN_PTR | secretsz;
  56019. + tmpdesc[idx++] = (u32)secretbuf;
  56020. +
  56021. + /* Add space for BKEK and MAC tag */
  56022. + tmpdesc[idx++] = CMD_SEQ_IN_PTR | (secretsz + (32 + 16));
  56023. +
  56024. + tmpdesc[idx++] = (u32)outbuf;
  56025. + tmpdesc[idx] = CMD_OPERATION | OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB |
  56026. + OP_PCL_BLOB_PTXT_SECMEM;
  56027. + if (auth)
  56028. + tmpdesc[idx] |= OP_PCL_BLOB_EKT;
  56029. +
  56030. + idx++;
  56031. + tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
  56032. + dsize = idx * sizeof(u32);
  56033. +
  56034. + tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
  56035. + if (tdesc == NULL)
  56036. + return 0;
  56037. +
  56038. + memcpy(tdesc, tmpdesc, dsize);
  56039. + *desc = tdesc;
  56040. + return dsize;
  56041. +}
  56042. +
  56043. +/*
  56044. + * Construct a secure memory blob decapsulation job descriptor
  56045. + *
  56046. + * - desc pointer to hold new (to be allocated) pointer to the generated
  56047. + * descriptor for later use. Calling thread can kfree the
  56048. + * descriptor after execution.
  56049. + * - keymod Physical pointer to key modifier (contiguous piece).
  56050. + * - keymodsz Size of key modifier in bytes (should normally be 16).
  56051. + * - blobbuf Physical pointer (within an accessible secure memory page)
  56052. + * of the blob to be decapsulated.
  56053. + * - outbuf Physical pointer (within an accessible secure memory page)
  56054. + * of the decapsulated output.
  56055. + * - secretsz Size of input blob, in bytes.
  56056. + * - auth If nonzero, assume AES-CCM for decapsulation, else use ECB
  56057. + *
  56058. + * Note: this uses 32-bit pointers at present
  56059. + */
  56060. +static int blob_decap_desc(u32 **desc, dma_addr_t keymod, u16 keymodsz,
  56061. + dma_addr_t blobbuf, dma_addr_t outbuf,
  56062. + u16 blobsz, bool auth)
  56063. +{
  56064. + u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
  56065. + u16 dsize, idx;
  56066. +
  56067. + memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
  56068. + idx = 1;
  56069. +
  56070. + /* Load key modifier */
  56071. + tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY |
  56072. + ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK) |
  56073. + (keymodsz & LDST_LEN_MASK);
  56074. +
  56075. + tmpdesc[idx++] = (u32)keymod;
  56076. +
  56077. + /* Compensate BKEK + MAC tag */
  56078. + tmpdesc[idx++] = CMD_SEQ_IN_PTR | (blobsz + 32 + 16);
  56079. +
  56080. + tmpdesc[idx++] = (u32)blobbuf;
  56081. + tmpdesc[idx++] = CMD_SEQ_OUT_PTR | blobsz;
  56082. + tmpdesc[idx++] = (u32)outbuf;
  56083. +
  56084. + /* Decapsulate from secure memory partition to black blob */
  56085. + tmpdesc[idx] = CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB |
  56086. + OP_PCL_BLOB_PTXT_SECMEM | OP_PCL_BLOB_BLACK;
  56087. + if (auth)
  56088. + tmpdesc[idx] |= OP_PCL_BLOB_EKT;
  56089. +
  56090. + idx++;
  56091. + tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
  56092. + dsize = idx * sizeof(u32);
  56093. +
  56094. + tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
  56095. + if (tdesc == NULL)
  56096. + return 0;
  56097. +
  56098. + memcpy(tdesc, tmpdesc, dsize);
  56099. + *desc = tdesc;
  56100. + return dsize;
  56101. +}
  56102. +
  56103. +/*
  56104. + * Pseudo-synchronous ring access functions for carrying out key
  56105. + * encapsulation and decapsulation
  56106. + */
  56107. +
  56108. +struct sm_key_job_result {
  56109. + int error;
  56110. + struct completion completion;
  56111. +};
  56112. +
  56113. +void sm_key_job_done(struct device *dev, u32 *desc, u32 err, void *context)
  56114. +{
  56115. + struct sm_key_job_result *res = context;
  56116. +
  56117. + res->error = err; /* save off the error for postprocessing */
  56118. + complete(&res->completion); /* mark us complete */
  56119. +}
  56120. +
  56121. +static int sm_key_job(struct device *ksdev, u32 *jobdesc)
  56122. +{
  56123. + struct sm_key_job_result testres;
  56124. + struct caam_drv_private_sm *kspriv;
  56125. + int rtn = 0;
  56126. +
  56127. + kspriv = dev_get_drvdata(ksdev);
  56128. +
  56129. + init_completion(&testres.completion);
  56130. +
  56131. + rtn = caam_jr_enqueue(kspriv->smringdev, jobdesc, sm_key_job_done,
  56132. + &testres);
  56133. + if (!rtn) {
  56134. + wait_for_completion_interruptible(&testres.completion);
  56135. + rtn = testres.error;
  56136. + }
  56137. + return rtn;
  56138. +}
  56139. +
  56140. +/*
  56141. + * Following section establishes the default methods for keystore access
  56142. + * They are NOT intended for use external to this module
  56143. + *
  56144. + * In the present version, these are the only means for the higher-level
  56145. + * interface to deal with the mechanics of accessing the phyiscal keystore
  56146. + */
  56147. +
  56148. +
  56149. +int slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot)
  56150. +{
  56151. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56152. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  56153. + u32 i;
  56154. +#ifdef SM_DEBUG
  56155. + dev_info(dev, "slot_alloc(): requesting slot for %d bytes\n", size);
  56156. +#endif
  56157. +
  56158. + if (size > smpriv->slot_size)
  56159. + return -EKEYREJECTED;
  56160. +
  56161. + for (i = 0; i < ksdata->slot_count; i++) {
  56162. + if (ksdata->slot[i].allocated == 0) {
  56163. + ksdata->slot[i].allocated = 1;
  56164. + (*slot) = i;
  56165. +#ifdef SM_DEBUG
  56166. + dev_info(dev, "slot_alloc(): new slot %d allocated\n",
  56167. + *slot);
  56168. +#endif
  56169. + return 0;
  56170. + }
  56171. + }
  56172. +
  56173. + return -ENOSPC;
  56174. +}
  56175. +EXPORT_SYMBOL(slot_alloc);
  56176. +
  56177. +int slot_dealloc(struct device *dev, u32 unit, u32 slot)
  56178. +{
  56179. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56180. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  56181. + u8 __iomem *slotdata;
  56182. +
  56183. +#ifdef SM_DEBUG
  56184. + dev_info(dev, "slot_dealloc(): releasing slot %d\n", slot);
  56185. +#endif
  56186. + if (slot >= ksdata->slot_count)
  56187. + return -EINVAL;
  56188. + slotdata = ksdata->base_address + slot * smpriv->slot_size;
  56189. +
  56190. + if (ksdata->slot[slot].allocated == 1) {
  56191. + /* Forcibly overwrite the data from the keystore */
  56192. + memset(ksdata->base_address + slot * smpriv->slot_size, 0,
  56193. + smpriv->slot_size);
  56194. +
  56195. + ksdata->slot[slot].allocated = 0;
  56196. +#ifdef SM_DEBUG
  56197. + dev_info(dev, "slot_dealloc(): slot %d released\n", slot);
  56198. +#endif
  56199. + return 0;
  56200. + }
  56201. +
  56202. + return -EINVAL;
  56203. +}
  56204. +EXPORT_SYMBOL(slot_dealloc);
  56205. +
  56206. +void *slot_get_address(struct device *dev, u32 unit, u32 slot)
  56207. +{
  56208. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56209. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  56210. +
  56211. + if (slot >= ksdata->slot_count)
  56212. + return NULL;
  56213. +
  56214. +#ifdef SM_DEBUG
  56215. + dev_info(dev, "slot_get_address(): slot %d is 0x%08x\n", slot,
  56216. + (u32)ksdata->base_address + slot * smpriv->slot_size);
  56217. +#endif
  56218. +
  56219. + return ksdata->base_address + slot * smpriv->slot_size;
  56220. +}
  56221. +
  56222. +u32 slot_get_base(struct device *dev, u32 unit, u32 slot)
  56223. +{
  56224. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56225. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  56226. +
  56227. + /*
  56228. + * There could potentially be more than one secure partition object
  56229. + * associated with this keystore. For now, there is just one.
  56230. + */
  56231. +
  56232. + (void)slot;
  56233. +
  56234. +#ifdef SM_DEBUG
  56235. + dev_info(dev, "slot_get_base(): slot %d = 0x%08x\n",
  56236. + slot, (u32)ksdata->base_address);
  56237. +#endif
  56238. +
  56239. + return (u32)(ksdata->base_address);
  56240. +}
  56241. +
  56242. +u32 slot_get_offset(struct device *dev, u32 unit, u32 slot)
  56243. +{
  56244. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56245. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  56246. +
  56247. + if (slot >= ksdata->slot_count)
  56248. + return -EINVAL;
  56249. +
  56250. +#ifdef SM_DEBUG
  56251. + dev_info(dev, "slot_get_offset(): slot %d = %d\n", slot,
  56252. + slot * smpriv->slot_size);
  56253. +#endif
  56254. +
  56255. + return slot * smpriv->slot_size;
  56256. +}
  56257. +
  56258. +u32 slot_get_slot_size(struct device *dev, u32 unit, u32 slot)
  56259. +{
  56260. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56261. +
  56262. +
  56263. +#ifdef SM_DEBUG
  56264. + dev_info(dev, "slot_get_slot_size(): slot %d = %d\n", slot,
  56265. + smpriv->slot_size);
  56266. +#endif
  56267. + /* All slots are the same size in the default implementation */
  56268. + return smpriv->slot_size;
  56269. +}
  56270. +
  56271. +
  56272. +
  56273. +int kso_init_data(struct device *dev, u32 unit)
  56274. +{
  56275. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56276. + int retval = -EINVAL;
  56277. + struct keystore_data *keystore_data = NULL;
  56278. + u32 slot_count;
  56279. + u32 keystore_data_size;
  56280. +
  56281. + /*
  56282. + * Calculate the required size of the keystore data structure, based
  56283. + * on the number of keys that can fit in the partition.
  56284. + */
  56285. + slot_count = smpriv->page_size / smpriv->slot_size;
  56286. +#ifdef SM_DEBUG
  56287. + dev_info(dev, "kso_init_data: %d slots initializing\n", slot_count);
  56288. +#endif
  56289. +
  56290. + keystore_data_size = sizeof(struct keystore_data) +
  56291. + slot_count *
  56292. + sizeof(struct keystore_data_slot_info);
  56293. +
  56294. + keystore_data = kzalloc(keystore_data_size, GFP_KERNEL);
  56295. +
  56296. + if (keystore_data == NULL) {
  56297. + retval = -ENOSPC;
  56298. + goto out;
  56299. + }
  56300. +
  56301. +#ifdef SM_DEBUG
  56302. + dev_info(dev, "kso_init_data: keystore data size = %d\n",
  56303. + keystore_data_size);
  56304. +#endif
  56305. +
  56306. + /*
  56307. + * Place the slot information structure directly after the keystore data
  56308. + * structure.
  56309. + */
  56310. + keystore_data->slot = (struct keystore_data_slot_info *)
  56311. + (keystore_data + 1);
  56312. + keystore_data->slot_count = slot_count;
  56313. +
  56314. + smpriv->pagedesc[unit].ksdata = keystore_data;
  56315. + smpriv->pagedesc[unit].ksdata->base_address =
  56316. + smpriv->pagedesc[unit].pg_base;
  56317. +
  56318. + retval = 0;
  56319. +
  56320. +out:
  56321. + if (retval != 0)
  56322. + if (keystore_data != NULL)
  56323. + kfree(keystore_data);
  56324. +
  56325. +
  56326. + return retval;
  56327. +}
  56328. +
  56329. +void kso_cleanup_data(struct device *dev, u32 unit)
  56330. +{
  56331. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56332. + struct keystore_data *keystore_data = NULL;
  56333. +
  56334. + if (smpriv->pagedesc[unit].ksdata != NULL)
  56335. + keystore_data = smpriv->pagedesc[unit].ksdata;
  56336. +
  56337. + /* Release the allocated keystore management data */
  56338. + kfree(smpriv->pagedesc[unit].ksdata);
  56339. +
  56340. + return;
  56341. +}
  56342. +
  56343. +
  56344. +
  56345. +/*
  56346. + * Keystore management section
  56347. + */
  56348. +
  56349. +void sm_init_keystore(struct device *dev)
  56350. +{
  56351. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56352. +
  56353. + smpriv->data_init = kso_init_data;
  56354. + smpriv->data_cleanup = kso_cleanup_data;
  56355. + smpriv->slot_alloc = slot_alloc;
  56356. + smpriv->slot_dealloc = slot_dealloc;
  56357. + smpriv->slot_get_address = slot_get_address;
  56358. + smpriv->slot_get_base = slot_get_base;
  56359. + smpriv->slot_get_offset = slot_get_offset;
  56360. + smpriv->slot_get_slot_size = slot_get_slot_size;
  56361. +#ifdef SM_DEBUG
  56362. + dev_info(dev, "sm_init_keystore(): handlers installed\n");
  56363. +#endif
  56364. +}
  56365. +EXPORT_SYMBOL(sm_init_keystore);
  56366. +
  56367. +/* Return available pages/units */
  56368. +u32 sm_detect_keystore_units(struct device *dev)
  56369. +{
  56370. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56371. +
  56372. + return smpriv->localpages;
  56373. +}
  56374. +EXPORT_SYMBOL(sm_detect_keystore_units);
  56375. +
  56376. +/*
  56377. + * Do any keystore specific initializations
  56378. + */
  56379. +int sm_establish_keystore(struct device *dev, u32 unit)
  56380. +{
  56381. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56382. +
  56383. +#ifdef SM_DEBUG
  56384. + dev_info(dev, "sm_establish_keystore(): unit %d initializing\n", unit);
  56385. +#endif
  56386. +
  56387. + if (smpriv->data_init == NULL)
  56388. + return -EINVAL;
  56389. +
  56390. + /* Call the data_init function for any user setup */
  56391. + return smpriv->data_init(dev, unit);
  56392. +}
  56393. +EXPORT_SYMBOL(sm_establish_keystore);
  56394. +
  56395. +void sm_release_keystore(struct device *dev, u32 unit)
  56396. +{
  56397. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56398. +
  56399. +#ifdef SM_DEBUG
  56400. + dev_info(dev, "sm_establish_keystore(): unit %d releasing\n", unit);
  56401. +#endif
  56402. + if ((smpriv != NULL) && (smpriv->data_cleanup != NULL))
  56403. + smpriv->data_cleanup(dev, unit);
  56404. +
  56405. + return;
  56406. +}
  56407. +EXPORT_SYMBOL(sm_release_keystore);
  56408. +
  56409. +/*
  56410. + * Subsequent interfacce (sm_keystore_*) forms the accessor interfacce to
  56411. + * the keystore
  56412. + */
  56413. +int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot)
  56414. +{
  56415. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56416. + int retval = -EINVAL;
  56417. +
  56418. + spin_lock(&smpriv->kslock);
  56419. +
  56420. + if ((smpriv->slot_alloc == NULL) ||
  56421. + (smpriv->pagedesc[unit].ksdata == NULL))
  56422. + goto out;
  56423. +
  56424. + retval = smpriv->slot_alloc(dev, unit, size, slot);
  56425. +
  56426. +out:
  56427. + spin_unlock(&smpriv->kslock);
  56428. + return retval;
  56429. +}
  56430. +EXPORT_SYMBOL(sm_keystore_slot_alloc);
  56431. +
  56432. +int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot)
  56433. +{
  56434. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56435. + int retval = -EINVAL;
  56436. +
  56437. + spin_lock(&smpriv->kslock);
  56438. +
  56439. + if ((smpriv->slot_alloc == NULL) ||
  56440. + (smpriv->pagedesc[unit].ksdata == NULL))
  56441. + goto out;
  56442. +
  56443. + retval = smpriv->slot_dealloc(dev, unit, slot);
  56444. +out:
  56445. + spin_unlock(&smpriv->kslock);
  56446. + return retval;
  56447. +}
  56448. +EXPORT_SYMBOL(sm_keystore_slot_dealloc);
  56449. +
  56450. +int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
  56451. + const u8 *key_data, u32 key_length)
  56452. +{
  56453. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56454. + int retval = -EINVAL;
  56455. + u32 slot_size;
  56456. + u32 i;
  56457. + u8 __iomem *slot_location;
  56458. +
  56459. + spin_lock(&smpriv->kslock);
  56460. +
  56461. + slot_size = smpriv->slot_get_slot_size(dev, unit, slot);
  56462. +
  56463. + if (key_length > slot_size) {
  56464. + retval = -EFBIG;
  56465. + goto out;
  56466. + }
  56467. +
  56468. + slot_location = smpriv->slot_get_address(dev, unit, slot);
  56469. +
  56470. + for (i = 0; i < key_length; i++)
  56471. + slot_location[i] = key_data[i];
  56472. +
  56473. + retval = 0;
  56474. +
  56475. +out:
  56476. + spin_unlock(&smpriv->kslock);
  56477. + return retval;
  56478. +}
  56479. +EXPORT_SYMBOL(sm_keystore_slot_load);
  56480. +
  56481. +int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
  56482. + u32 key_length, u8 *key_data)
  56483. +{
  56484. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56485. + int retval = -EINVAL;
  56486. + u8 __iomem *slot_addr;
  56487. + u32 slot_size;
  56488. +
  56489. + spin_lock(&smpriv->kslock);
  56490. +
  56491. + slot_addr = smpriv->slot_get_address(dev, unit, slot);
  56492. + slot_size = smpriv->slot_get_slot_size(dev, unit, slot);
  56493. +
  56494. + if (key_length > slot_size) {
  56495. + retval = -EKEYREJECTED;
  56496. + goto out;
  56497. + }
  56498. +
  56499. + memcpy(key_data, slot_addr, key_length);
  56500. + retval = 0;
  56501. +
  56502. +out:
  56503. + spin_unlock(&smpriv->kslock);
  56504. + return retval;
  56505. +}
  56506. +EXPORT_SYMBOL(sm_keystore_slot_read);
  56507. +
  56508. +int sm_keystore_slot_encapsulate(struct device *dev, u32 unit, u32 inslot,
  56509. + u32 outslot, u16 secretlen, u8 *keymod,
  56510. + u16 keymodlen)
  56511. +{
  56512. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56513. + int retval = 0;
  56514. + u32 slot_length, dsize, jstat;
  56515. + u32 __iomem *encapdesc = NULL;
  56516. + u8 __iomem *lkeymod, *inpslotaddr, *outslotaddr;
  56517. + dma_addr_t keymod_dma;
  56518. +
  56519. + /* Ensure that the full blob will fit in the key slot */
  56520. + slot_length = smpriv->slot_get_slot_size(dev, unit, outslot);
  56521. + if ((secretlen + 48) > slot_length)
  56522. + goto out;
  56523. +
  56524. + /* Get the base addresses of both keystore slots */
  56525. + inpslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, inslot);
  56526. + outslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, outslot);
  56527. +
  56528. + /* Build the key modifier */
  56529. + lkeymod = kmalloc(keymodlen, GFP_KERNEL | GFP_DMA);
  56530. + memcpy(lkeymod, keymod, keymodlen);
  56531. + keymod_dma = dma_map_single(dev, lkeymod, keymodlen, DMA_TO_DEVICE);
  56532. + dma_sync_single_for_device(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  56533. +
  56534. + /* Build the encapsulation job descriptor */
  56535. + dsize = blob_encap_desc(&encapdesc, keymod_dma, keymodlen,
  56536. + __pa(inpslotaddr), __pa(outslotaddr),
  56537. + secretlen, 0);
  56538. + if (!dsize) {
  56539. + dev_err(dev, "can't alloc an encap descriptor\n");
  56540. + retval = -ENOMEM;
  56541. + goto out;
  56542. + }
  56543. + jstat = sm_key_job(dev, encapdesc);
  56544. +
  56545. + dma_unmap_single(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  56546. + kfree(encapdesc);
  56547. +
  56548. +out:
  56549. + return retval;
  56550. +
  56551. +}
  56552. +EXPORT_SYMBOL(sm_keystore_slot_encapsulate);
  56553. +
  56554. +int sm_keystore_slot_decapsulate(struct device *dev, u32 unit, u32 inslot,
  56555. + u32 outslot, u16 secretlen, u8 *keymod,
  56556. + u16 keymodlen)
  56557. +{
  56558. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  56559. + int retval = 0;
  56560. + u32 slot_length, dsize, jstat;
  56561. + u32 __iomem *decapdesc = NULL;
  56562. + u8 __iomem *lkeymod, *inpslotaddr, *outslotaddr;
  56563. + dma_addr_t keymod_dma;
  56564. +
  56565. + /* Ensure that the decap data will fit in the key slot */
  56566. + slot_length = smpriv->slot_get_slot_size(dev, unit, outslot);
  56567. + if (secretlen > slot_length)
  56568. + goto out;
  56569. +
  56570. + /* Get the base addresses of both keystore slots */
  56571. + inpslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, inslot);
  56572. + outslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, outslot);
  56573. +
  56574. + /* Build the key modifier */
  56575. + lkeymod = kmalloc(keymodlen, GFP_KERNEL | GFP_DMA);
  56576. + memcpy(lkeymod, keymod, keymodlen);
  56577. + keymod_dma = dma_map_single(dev, lkeymod, keymodlen, DMA_TO_DEVICE);
  56578. + dma_sync_single_for_device(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  56579. +
  56580. + /* Build the decapsulation job descriptor */
  56581. + dsize = blob_decap_desc(&decapdesc, keymod_dma, keymodlen,
  56582. + __pa(inpslotaddr), __pa(outslotaddr),
  56583. + secretlen, 0);
  56584. + if (!dsize) {
  56585. + dev_err(dev, "can't alloc a decap descriptor\n");
  56586. + retval = -ENOMEM;
  56587. + goto out;
  56588. + }
  56589. + jstat = sm_key_job(dev, decapdesc);
  56590. +
  56591. + dma_unmap_single(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  56592. + kfree(decapdesc);
  56593. +
  56594. +out:
  56595. + return retval;
  56596. +
  56597. +}
  56598. +EXPORT_SYMBOL(sm_keystore_slot_decapsulate);
  56599. +
  56600. +
  56601. +/*
  56602. + * Initialization/shutdown subsystem
  56603. + * Assumes statically-invoked startup/shutdown from the controller driver
  56604. + * for the present time, to be reworked when a device tree becomes
  56605. + * available. This code will not modularize in present form.
  56606. + *
  56607. + * Also, simply uses ring 0 for execution at the present
  56608. + */
  56609. +
  56610. +int caam_sm_startup(struct platform_device *pdev)
  56611. +{
  56612. + struct device *ctrldev, *smdev;
  56613. + struct caam_drv_private *ctrlpriv;
  56614. + struct caam_drv_private_sm *smpriv;
  56615. + struct caam_drv_private_jr *jrpriv; /* need this for reg page */
  56616. + struct platform_device *sm_pdev;
  56617. + struct sm_page_descriptor *lpagedesc;
  56618. + u32 page, pgstat, lpagect, detectedpage;
  56619. +
  56620. + struct device_node *np;
  56621. + ctrldev = &pdev->dev;
  56622. + ctrlpriv = dev_get_drvdata(ctrldev);
  56623. +
  56624. + /*
  56625. + * Set up the private block for secure memory
  56626. + * Only one instance is possible
  56627. + */
  56628. + smpriv = kzalloc(sizeof(struct caam_drv_private_sm), GFP_KERNEL);
  56629. + if (smpriv == NULL) {
  56630. + dev_err(ctrldev, "can't alloc private mem for secure memory\n");
  56631. + return -ENOMEM;
  56632. + }
  56633. + smpriv->parentdev = ctrldev; /* copy of parent dev is handy */
  56634. +
  56635. + /* Create the dev */
  56636. +#ifdef CONFIG_OF
  56637. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm");
  56638. + sm_pdev = of_platform_device_create(np, "caam_sm", ctrldev);
  56639. +#else
  56640. + sm_pdev = platform_device_register_data(ctrldev, "caam_sm", 0,
  56641. + smpriv,
  56642. + sizeof(struct caam_drv_private_sm));
  56643. +#endif
  56644. + if (sm_pdev == NULL) {
  56645. + kfree(smpriv);
  56646. + return -EINVAL;
  56647. + }
  56648. + smdev = &sm_pdev->dev;
  56649. + dev_set_drvdata(smdev, smpriv);
  56650. + ctrlpriv->smdev = smdev;
  56651. +
  56652. + /*
  56653. + * Collect configuration limit data for reference
  56654. + * This batch comes from the partition data/vid registers in perfmon
  56655. + */
  56656. + smpriv->max_pages = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
  56657. + & SMPART_MAX_NUMPG_MASK) >>
  56658. + SMPART_MAX_NUMPG_SHIFT) + 1;
  56659. + smpriv->top_partition = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
  56660. + & SMPART_MAX_PNUM_MASK) >>
  56661. + SMPART_MAX_PNUM_SHIFT) + 1;
  56662. + smpriv->top_page = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
  56663. + & SMPART_MAX_PG_MASK) >> SMPART_MAX_PG_SHIFT) + 1;
  56664. + smpriv->page_size = 1024 << ((rd_reg32(&ctrlpriv->ctrl->perfmon.smvid)
  56665. + & SMVID_PG_SIZE_MASK) >> SMVID_PG_SIZE_SHIFT);
  56666. + smpriv->slot_size = 1 << CONFIG_CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE;
  56667. +
  56668. +#ifdef SM_DEBUG
  56669. + dev_info(smdev, "max pages = %d, top partition = %d\n",
  56670. + smpriv->max_pages, smpriv->top_partition);
  56671. + dev_info(smdev, "top page = %d, page size = %d (total = %d)\n",
  56672. + smpriv->top_page, smpriv->page_size,
  56673. + smpriv->top_page * smpriv->page_size);
  56674. + dev_info(smdev, "selected slot size = %d\n", smpriv->slot_size);
  56675. +#endif
  56676. +
  56677. + /*
  56678. + * Now probe for partitions/pages to which we have access. Note that
  56679. + * these have likely been set up by a bootloader or platform
  56680. + * provisioning application, so we have to assume that we "inherit"
  56681. + * a configuration and work within the constraints of what it might be.
  56682. + *
  56683. + * Assume use of the zeroth ring in the present iteration (until
  56684. + * we can divorce the controller and ring drivers, and then assign
  56685. + * an SM instance to any ring instance).
  56686. + */
  56687. + smpriv->smringdev = ctrlpriv->jrdev[0];
  56688. + jrpriv = dev_get_drvdata(smpriv->smringdev);
  56689. + lpagect = 0;
  56690. + lpagedesc = kzalloc(sizeof(struct sm_page_descriptor)
  56691. + * smpriv->max_pages, GFP_KERNEL);
  56692. + if (lpagedesc == NULL) {
  56693. + kfree(smpriv);
  56694. + return -ENOMEM;
  56695. + }
  56696. +
  56697. + for (page = 0; page < smpriv->max_pages; page++) {
  56698. + wr_reg32(&jrpriv->rregs->sm_cmd,
  56699. + ((page << SMC_PAGE_SHIFT) & SMC_PAGE_MASK) |
  56700. + (SMC_CMD_PAGE_INQUIRY & SMC_CMD_MASK));
  56701. + pgstat = rd_reg32(&jrpriv->rregs->sm_status);
  56702. + if (((pgstat & SMCS_PGWON_MASK) >> SMCS_PGOWN_SHIFT)
  56703. + == SMCS_PGOWN_OWNED) { /* our page? */
  56704. + lpagedesc[page].phys_pagenum =
  56705. + (pgstat & SMCS_PAGE_MASK) >> SMCS_PAGE_SHIFT;
  56706. + lpagedesc[page].own_part =
  56707. + (pgstat & SMCS_PART_SHIFT) >> SMCS_PART_MASK;
  56708. + lpagedesc[page].pg_base = ctrlpriv->sm_base +
  56709. + ((smpriv->page_size * page) / sizeof(u32));
  56710. + lpagect++;
  56711. +#ifdef SM_DEBUG
  56712. + dev_info(smdev,
  56713. + "physical page %d, owning partition = %d\n",
  56714. + lpagedesc[page].phys_pagenum,
  56715. + lpagedesc[page].own_part);
  56716. +#endif
  56717. + }
  56718. + }
  56719. +
  56720. + smpriv->pagedesc = kzalloc(sizeof(struct sm_page_descriptor) * lpagect,
  56721. + GFP_KERNEL);
  56722. + if (smpriv->pagedesc == NULL) {
  56723. + kfree(lpagedesc);
  56724. + kfree(smpriv);
  56725. + return -ENOMEM;
  56726. + }
  56727. + smpriv->localpages = lpagect;
  56728. +
  56729. + detectedpage = 0;
  56730. + for (page = 0; page < smpriv->max_pages; page++) {
  56731. + if (lpagedesc[page].pg_base != NULL) { /* e.g. live entry */
  56732. + memcpy(&smpriv->pagedesc[detectedpage],
  56733. + &lpagedesc[page],
  56734. + sizeof(struct sm_page_descriptor));
  56735. +#ifdef SM_DEBUG_CONT
  56736. + sm_show_page(smdev, &smpriv->pagedesc[detectedpage]);
  56737. +#endif
  56738. + detectedpage++;
  56739. + }
  56740. + }
  56741. +
  56742. + kfree(lpagedesc);
  56743. +
  56744. + sm_init_keystore(smdev);
  56745. +
  56746. + return 0;
  56747. +}
  56748. +
  56749. +void caam_sm_shutdown(struct platform_device *pdev)
  56750. +{
  56751. + struct device *ctrldev, *smdev;
  56752. + struct caam_drv_private *priv;
  56753. + struct caam_drv_private_sm *smpriv;
  56754. +
  56755. + ctrldev = &pdev->dev;
  56756. + priv = dev_get_drvdata(ctrldev);
  56757. + smdev = priv->smdev;
  56758. + smpriv = dev_get_drvdata(smdev);
  56759. +
  56760. + kfree(smpriv->pagedesc);
  56761. + kfree(smpriv);
  56762. +}
  56763. +EXPORT_SYMBOL(caam_sm_shutdown);
  56764. +#ifdef CONFIG_OF
  56765. +static void __exit caam_sm_exit(void)
  56766. +{
  56767. + struct device_node *dev_node;
  56768. + struct platform_device *pdev;
  56769. +
  56770. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  56771. + if (!dev_node) {
  56772. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  56773. + if (!dev_node)
  56774. + return;
  56775. + }
  56776. +
  56777. + pdev = of_find_device_by_node(dev_node);
  56778. + if (!pdev)
  56779. + return;
  56780. +
  56781. + of_node_put(dev_node);
  56782. +
  56783. + caam_sm_shutdown(pdev);
  56784. +
  56785. + return;
  56786. +}
  56787. +
  56788. +static int __init caam_sm_init(void)
  56789. +{
  56790. + struct device_node *dev_node;
  56791. + struct platform_device *pdev;
  56792. +
  56793. + /*
  56794. + * Do of_find_compatible_node() then of_find_device_by_node()
  56795. + * once a functional device tree is available
  56796. + */
  56797. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  56798. + if (!dev_node) {
  56799. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  56800. + if (!dev_node)
  56801. + return -ENODEV;
  56802. + }
  56803. +
  56804. + pdev = of_find_device_by_node(dev_node);
  56805. + if (!pdev)
  56806. + return -ENODEV;
  56807. +
  56808. + of_node_get(dev_node);
  56809. +
  56810. + caam_sm_startup(pdev);
  56811. +
  56812. + return 0;
  56813. +}
  56814. +
  56815. +module_init(caam_sm_init);
  56816. +module_exit(caam_sm_exit);
  56817. +
  56818. +MODULE_LICENSE("Dual BSD/GPL");
  56819. +MODULE_DESCRIPTION("FSL CAAM Secure Memory / Keystore");
  56820. +MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
  56821. +#endif
  56822. diff -Nur linux-3.14.14/drivers/crypto/caam/sm_test.c linux-imx6-3.14/drivers/crypto/caam/sm_test.c
  56823. --- linux-3.14.14/drivers/crypto/caam/sm_test.c 1969-12-31 18:00:00.000000000 -0600
  56824. +++ linux-imx6-3.14/drivers/crypto/caam/sm_test.c 2014-12-08 00:31:52.552418001 -0600
  56825. @@ -0,0 +1,844 @@
  56826. +/*
  56827. + * Secure Memory / Keystore Exemplification Module
  56828. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  56829. + *
  56830. + * Serves as a functional example, and as a self-contained unit test for
  56831. + * the functionality contained in sm_store.c.
  56832. + *
  56833. + * The example function, caam_sm_example_init(), runs a thread that:
  56834. + *
  56835. + * - initializes a set of fixed keys
  56836. + * - stores one copy in clear buffers
  56837. + * - stores them again in secure memory
  56838. + * - extracts stored keys back out for use
  56839. + * - intializes 3 data buffers for a test:
  56840. + * (1) containing cleartext
  56841. + * (2) to hold ciphertext encrypted with an extracted black key
  56842. + * (3) to hold extracted cleartext decrypted with an equivalent clear key
  56843. + *
  56844. + * The function then builds simple job descriptors that reference the key
  56845. + * material and buffers as initialized, and executes an encryption job
  56846. + * with a black key, and a decryption job using a the same key held in the
  56847. + * clear. The output of the decryption job is compared to the original
  56848. + * cleartext; if they don't compare correctly, one can assume a key problem
  56849. + * exists, where the function will exit with an error.
  56850. + *
  56851. + * This module can use a substantial amount of refactoring, which may occur
  56852. + * after the API gets some mileage. Furthermore, expect this module to
  56853. + * eventually disappear once the API is integrated into "real" software.
  56854. + */
  56855. +
  56856. +#include "compat.h"
  56857. +#include "intern.h"
  56858. +#include "desc.h"
  56859. +#include "error.h"
  56860. +#include "jr.h"
  56861. +#include "sm.h"
  56862. +
  56863. +static u8 skeymod[] = {
  56864. + 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
  56865. + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
  56866. +};
  56867. +static u8 symkey[] = {
  56868. + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  56869. + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  56870. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  56871. + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
  56872. +};
  56873. +
  56874. +static u8 symdata[] = {
  56875. + 0x00, 0x01, 0x02, 0x03, 0x04, 0x0f, 0x06, 0x07,
  56876. + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  56877. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  56878. + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  56879. + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  56880. + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  56881. + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  56882. + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  56883. + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  56884. + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  56885. + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
  56886. + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
  56887. + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  56888. + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
  56889. + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
  56890. + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
  56891. + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  56892. + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
  56893. + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  56894. + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
  56895. + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
  56896. + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  56897. + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
  56898. + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
  56899. + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
  56900. + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  56901. + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
  56902. + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
  56903. + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
  56904. + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
  56905. + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  56906. + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
  56907. +};
  56908. +
  56909. +static int mk_job_desc(u32 *desc, dma_addr_t key, u16 keysz, dma_addr_t indata,
  56910. + dma_addr_t outdata, u16 sz, u32 cipherdir, u32 keymode)
  56911. +{
  56912. + desc[1] = CMD_KEY | CLASS_1 | (keysz & KEY_LENGTH_MASK) | keymode;
  56913. + desc[2] = (u32)key;
  56914. + desc[3] = CMD_OPERATION | OP_TYPE_CLASS1_ALG | OP_ALG_AAI_ECB |
  56915. + cipherdir;
  56916. + desc[4] = CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 |
  56917. + FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1 | sz;
  56918. + desc[5] = (u32)indata;
  56919. + desc[6] = CMD_FIFO_STORE | FIFOST_TYPE_MESSAGE_DATA | sz;
  56920. + desc[7] = (u32)outdata;
  56921. +
  56922. + desc[0] = CMD_DESC_HDR | HDR_ONE | (8 & HDR_DESCLEN_MASK);
  56923. + return 8 * sizeof(u32);
  56924. +}
  56925. +
  56926. +struct exec_test_result {
  56927. + int error;
  56928. + struct completion completion;
  56929. +};
  56930. +
  56931. +void exec_test_done(struct device *dev, u32 *desc, u32 err, void *context)
  56932. +{
  56933. + struct exec_test_result *res = context;
  56934. +
  56935. + if (err) {
  56936. + char tmp[CAAM_ERROR_STR_MAX];
  56937. + dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err));
  56938. + }
  56939. +
  56940. + res->error = err;
  56941. + complete(&res->completion);
  56942. +}
  56943. +
  56944. +static int exec_test_job(struct device *ksdev, u32 *jobdesc)
  56945. +{
  56946. + struct exec_test_result testres;
  56947. + struct caam_drv_private_sm *kspriv;
  56948. + int rtn = 0;
  56949. +
  56950. + kspriv = dev_get_drvdata(ksdev);
  56951. +
  56952. + init_completion(&testres.completion);
  56953. +
  56954. + rtn = caam_jr_enqueue(kspriv->smringdev, jobdesc, exec_test_done,
  56955. + &testres);
  56956. + if (!rtn) {
  56957. + wait_for_completion_interruptible(&testres.completion);
  56958. + rtn = testres.error;
  56959. + }
  56960. + return rtn;
  56961. +}
  56962. +
  56963. +
  56964. +int caam_sm_example_init(struct platform_device *pdev)
  56965. +{
  56966. + struct device *ctrldev, *ksdev;
  56967. + struct caam_drv_private *ctrlpriv;
  56968. + struct caam_drv_private_sm *kspriv;
  56969. + u32 unit, units, jdescsz;
  56970. + int stat, jstat, rtnval = 0;
  56971. + u8 __iomem *syminp, *symint, *symout = NULL;
  56972. + dma_addr_t syminp_dma, symint_dma, symout_dma;
  56973. + u8 __iomem *black_key_des, *black_key_aes128;
  56974. + u8 __iomem *black_key_aes256;
  56975. + dma_addr_t black_key_des_dma, black_key_aes128_dma;
  56976. + dma_addr_t black_key_aes256_dma;
  56977. + u8 __iomem *clear_key_des, *clear_key_aes128, *clear_key_aes256;
  56978. + dma_addr_t clear_key_des_dma, clear_key_aes128_dma;
  56979. + dma_addr_t clear_key_aes256_dma;
  56980. + u32 __iomem *jdesc;
  56981. + u32 keyslot_des, keyslot_aes128, keyslot_aes256 = 0;
  56982. +
  56983. + jdesc = NULL;
  56984. + black_key_des = black_key_aes128 = black_key_aes256 = NULL;
  56985. + clear_key_des = clear_key_aes128 = clear_key_aes256 = NULL;
  56986. +
  56987. + /* We can lose this cruft once we can get a pdev by name */
  56988. + ctrldev = &pdev->dev;
  56989. + ctrlpriv = dev_get_drvdata(ctrldev);
  56990. + ksdev = ctrlpriv->smdev;
  56991. + kspriv = dev_get_drvdata(ksdev);
  56992. + if (kspriv == NULL)
  56993. + return -ENODEV;
  56994. +
  56995. + /* Now that we have the dev for the single SM instance, connect */
  56996. +#ifdef SM_TEST_DETAIL
  56997. + dev_info(ksdev, "caam_sm_test_init() running\n");
  56998. +#endif
  56999. + /* Probe to see what keystores are available to us */
  57000. + units = sm_detect_keystore_units(ksdev);
  57001. + if (!units)
  57002. + dev_err(ksdev, "caam_sm_test: no keystore units available\n");
  57003. +
  57004. + /*
  57005. + * MX6 bootloader stores some stuff in unit 0, so let's
  57006. + * use 1 or above
  57007. + */
  57008. + if (units < 2) {
  57009. + dev_err(ksdev, "caam_sm_test: insufficient keystore units\n");
  57010. + return -ENODEV;
  57011. + }
  57012. + unit = 1;
  57013. +
  57014. +#ifdef SM_TEST_DETAIL
  57015. + dev_info(ksdev, "caam_sm_test: %d keystore units available\n", units);
  57016. +#endif
  57017. +
  57018. + /* Initialize/Establish Keystore */
  57019. + sm_establish_keystore(ksdev, unit); /* Initalize store in #1 */
  57020. +
  57021. + /*
  57022. + * Top of main test thread
  57023. + */
  57024. +
  57025. + /* Allocate test data blocks (input, intermediate, output) */
  57026. + syminp = kmalloc(256, GFP_KERNEL | GFP_DMA);
  57027. + symint = kmalloc(256, GFP_KERNEL | GFP_DMA);
  57028. + symout = kmalloc(256, GFP_KERNEL | GFP_DMA);
  57029. + if ((syminp == NULL) || (symint == NULL) || (symout == NULL)) {
  57030. + rtnval = -ENOMEM;
  57031. + dev_err(ksdev, "caam_sm_test: can't get test data buffers\n");
  57032. + goto freemem;
  57033. + }
  57034. +
  57035. + /* Allocate storage for 3 black keys: encapsulated 8, 16, 32 */
  57036. + black_key_des = kmalloc(16, GFP_KERNEL | GFP_DMA); /* padded to 16... */
  57037. + black_key_aes128 = kmalloc(16, GFP_KERNEL | GFP_DMA);
  57038. + black_key_aes256 = kmalloc(16, GFP_KERNEL | GFP_DMA);
  57039. + if ((black_key_des == NULL) || (black_key_aes128 == NULL) ||
  57040. + (black_key_aes256 == NULL)) {
  57041. + rtnval = -ENOMEM;
  57042. + dev_err(ksdev, "caam_sm_test: can't black key buffers\n");
  57043. + goto freemem;
  57044. + }
  57045. +
  57046. + clear_key_des = kmalloc(8, GFP_KERNEL | GFP_DMA);
  57047. + clear_key_aes128 = kmalloc(16, GFP_KERNEL | GFP_DMA);
  57048. + clear_key_aes256 = kmalloc(32, GFP_KERNEL | GFP_DMA);
  57049. + if ((clear_key_des == NULL) || (clear_key_aes128 == NULL) ||
  57050. + (clear_key_aes256 == NULL)) {
  57051. + rtnval = -ENOMEM;
  57052. + dev_err(ksdev, "caam_sm_test: can't get clear key buffers\n");
  57053. + goto freemem;
  57054. + }
  57055. +
  57056. + /* Allocate storage for job descriptor */
  57057. + jdesc = kmalloc(8 * sizeof(u32), GFP_KERNEL | GFP_DMA);
  57058. + if (jdesc == NULL) {
  57059. + rtnval = -ENOMEM;
  57060. + dev_err(ksdev, "caam_sm_test: can't get descriptor buffers\n");
  57061. + goto freemem;
  57062. + }
  57063. +
  57064. +#ifdef SM_TEST_DETAIL
  57065. + dev_info(ksdev, "caam_sm_test: all buffers allocated\n");
  57066. +#endif
  57067. +
  57068. + /* Load up input data block, clear outputs */
  57069. + memcpy(syminp, symdata, 256);
  57070. + memset(symint, 0, 256);
  57071. + memset(symout, 0, 256);
  57072. +#ifdef SM_TEST_DETAIL
  57073. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57074. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57075. + syminp[0], syminp[1], syminp[2], syminp[3],
  57076. + syminp[4], syminp[5], syminp[6], syminp[7]);
  57077. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57078. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57079. + symint[0], symint[1], symint[2], symint[3],
  57080. + symint[4], symint[5], symint[6], symint[7]);
  57081. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57082. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57083. + symout[0], symout[1], symout[2], symout[3],
  57084. + symout[4], symout[5], symout[6], symout[7]);
  57085. +
  57086. + dev_info(ksdev, "caam_sm_test: data buffers initialized\n");
  57087. +#endif
  57088. +
  57089. + /* Load up clear keys */
  57090. + memcpy(clear_key_des, symkey, 8);
  57091. + memcpy(clear_key_aes128, symkey, 16);
  57092. + memcpy(clear_key_aes256, symkey, 32);
  57093. +
  57094. +#ifdef SM_TEST_DETAIL
  57095. + dev_info(ksdev, "caam_sm_test: all clear keys loaded\n");
  57096. +#endif
  57097. +
  57098. + /*
  57099. + * Place clear keys in keystore.
  57100. + * All the interesting stuff happens here.
  57101. + */
  57102. + /* 8 bit DES key */
  57103. + stat = sm_keystore_slot_alloc(ksdev, unit, 8, &keyslot_des);
  57104. + if (stat)
  57105. + goto freemem;
  57106. +#ifdef SM_TEST_DETAIL
  57107. + dev_info(ksdev, "caam_sm_test: 8 byte key slot in %d\n", keyslot_des);
  57108. +#endif
  57109. + stat = sm_keystore_slot_load(ksdev, unit, keyslot_des, clear_key_des,
  57110. + 8);
  57111. + if (stat) {
  57112. +#ifdef SM_TEST_DETAIL
  57113. + dev_info(ksdev, "caam_sm_test: can't load 8 byte key in %d\n",
  57114. + keyslot_des);
  57115. +#endif
  57116. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  57117. + goto freemem;
  57118. + }
  57119. +
  57120. + /* 16 bit AES key */
  57121. + stat = sm_keystore_slot_alloc(ksdev, unit, 16, &keyslot_aes128);
  57122. + if (stat) {
  57123. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  57124. + goto freemem;
  57125. + }
  57126. +#ifdef SM_TEST_DETAIL
  57127. + dev_info(ksdev, "caam_sm_test: 16 byte key slot in %d\n",
  57128. + keyslot_aes128);
  57129. +#endif
  57130. + stat = sm_keystore_slot_load(ksdev, unit, keyslot_aes128,
  57131. + clear_key_aes128, 16);
  57132. + if (stat) {
  57133. +#ifdef SM_TEST_DETAIL
  57134. + dev_info(ksdev, "caam_sm_test: can't load 16 byte key in %d\n",
  57135. + keyslot_aes128);
  57136. +#endif
  57137. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  57138. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  57139. + goto freemem;
  57140. + }
  57141. +
  57142. + /* 32 bit AES key */
  57143. + stat = sm_keystore_slot_alloc(ksdev, unit, 32, &keyslot_aes256);
  57144. + if (stat) {
  57145. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  57146. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  57147. + goto freemem;
  57148. + }
  57149. +#ifdef SM_TEST_DETAIL
  57150. + dev_info(ksdev, "caam_sm_test: 32 byte key slot in %d\n",
  57151. + keyslot_aes256);
  57152. +#endif
  57153. + stat = sm_keystore_slot_load(ksdev, unit, keyslot_aes256,
  57154. + clear_key_aes256, 32);
  57155. + if (stat) {
  57156. +#ifdef SM_TEST_DETAIL
  57157. + dev_info(ksdev, "caam_sm_test: can't load 32 byte key in %d\n",
  57158. + keyslot_aes128);
  57159. +#endif
  57160. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes256);
  57161. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  57162. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  57163. + goto freemem;
  57164. + }
  57165. +
  57166. + /* Encapsulate all keys as SM blobs */
  57167. + stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_des,
  57168. + keyslot_des, 8, skeymod, 8);
  57169. + if (stat) {
  57170. + dev_info(ksdev, "caam_sm_test: can't encapsulate DES key\n");
  57171. + goto freekeys;
  57172. + }
  57173. +
  57174. + stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_aes128,
  57175. + keyslot_aes128, 16, skeymod, 8);
  57176. + if (stat) {
  57177. + dev_info(ksdev, "caam_sm_test: can't encapsulate AES128 key\n");
  57178. + goto freekeys;
  57179. + }
  57180. +
  57181. + stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_aes256,
  57182. + keyslot_aes256, 32, skeymod, 8);
  57183. + if (stat) {
  57184. + dev_info(ksdev, "caam_sm_test: can't encapsulate AES256 key\n");
  57185. + goto freekeys;
  57186. + }
  57187. +
  57188. + /* Now decapsulate as black key blobs */
  57189. + stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_des,
  57190. + keyslot_des, 8, skeymod, 8);
  57191. + if (stat) {
  57192. + dev_info(ksdev, "caam_sm_test: can't decapsulate DES key\n");
  57193. + goto freekeys;
  57194. + }
  57195. +
  57196. + stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_aes128,
  57197. + keyslot_aes128, 16, skeymod, 8);
  57198. + if (stat) {
  57199. + dev_info(ksdev, "caam_sm_test: can't decapsulate AES128 key\n");
  57200. + goto freekeys;
  57201. + }
  57202. +
  57203. + stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_aes256,
  57204. + keyslot_aes256, 32, skeymod, 8);
  57205. + if (stat) {
  57206. + dev_info(ksdev, "caam_sm_test: can't decapsulate AES128 key\n");
  57207. + goto freekeys;
  57208. + }
  57209. +
  57210. + /* Extract 8/16/32 byte black keys */
  57211. + sm_keystore_slot_read(ksdev, unit, keyslot_des, 8, black_key_des);
  57212. + sm_keystore_slot_read(ksdev, unit, keyslot_aes128, 16,
  57213. + black_key_aes128);
  57214. + sm_keystore_slot_read(ksdev, unit, keyslot_aes256, 32,
  57215. + black_key_aes256);
  57216. +
  57217. +#ifdef SM_TEST_DETAIL
  57218. + dev_info(ksdev, "caam_sm_test: all black keys extracted\n");
  57219. +#endif
  57220. +
  57221. + /* DES encrypt using 8 byte black key */
  57222. + black_key_des_dma = dma_map_single(ksdev, black_key_des, 8,
  57223. + DMA_TO_DEVICE);
  57224. + dma_sync_single_for_device(ksdev, black_key_des_dma, 8, DMA_TO_DEVICE);
  57225. + syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
  57226. + dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57227. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
  57228. +
  57229. + jdescsz = mk_job_desc(jdesc, black_key_des_dma, 8, syminp_dma,
  57230. + symint_dma, 256,
  57231. + OP_ALG_ENCRYPT | OP_ALG_ALGSEL_DES, 0);
  57232. +
  57233. +#ifdef SM_TEST_DETAIL
  57234. + dev_info(ksdev, "jobdesc:\n");
  57235. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57236. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57237. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57238. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57239. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57240. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57241. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57242. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57243. +#endif
  57244. +
  57245. + jstat = exec_test_job(ksdev, jdesc);
  57246. +
  57247. + dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57248. + dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57249. + dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57250. + dma_unmap_single(ksdev, black_key_des_dma, 8, DMA_TO_DEVICE);
  57251. +
  57252. +#ifdef SM_TEST_DETAIL
  57253. + dev_info(ksdev, "input block:\n");
  57254. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57255. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57256. + syminp[0], syminp[1], syminp[2], syminp[3],
  57257. + syminp[4], syminp[5], syminp[6], syminp[7]);
  57258. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57259. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57260. + syminp[8], syminp[9], syminp[10], syminp[11],
  57261. + syminp[12], syminp[13], syminp[14], syminp[15]);
  57262. + dev_info(ksdev, "intermediate block:\n");
  57263. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57264. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57265. + symint[0], symint[1], symint[2], symint[3],
  57266. + symint[4], symint[5], symint[6], symint[7]);
  57267. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57268. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57269. + symint[8], symint[9], symint[10], symint[11],
  57270. + symint[12], symint[13], symint[14], symint[15]);
  57271. + dev_info(ksdev, "caam_sm_test: encrypt cycle with 8 byte key\n");
  57272. +#endif
  57273. +
  57274. + /* DES decrypt using 8 byte clear key */
  57275. + clear_key_des_dma = dma_map_single(ksdev, clear_key_des, 8,
  57276. + DMA_TO_DEVICE);
  57277. + dma_sync_single_for_device(ksdev, clear_key_des_dma, 8, DMA_TO_DEVICE);
  57278. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
  57279. + dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57280. + symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
  57281. +
  57282. + jdescsz = mk_job_desc(jdesc, clear_key_des_dma, 8, symint_dma,
  57283. + symout_dma, 256,
  57284. + OP_ALG_DECRYPT | OP_ALG_ALGSEL_DES, 0);
  57285. +
  57286. +#ifdef SM_TEST_DETAIL
  57287. + dev_info(ksdev, "jobdesc:\n");
  57288. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57289. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57290. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57291. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57292. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57293. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57294. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57295. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57296. +#endif
  57297. +
  57298. + jstat = exec_test_job(ksdev, jdesc);
  57299. +
  57300. + dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57301. + dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57302. + dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57303. + dma_unmap_single(ksdev, clear_key_des_dma, 8, DMA_TO_DEVICE);
  57304. +
  57305. +#ifdef SM_TEST_DETAIL
  57306. + dev_info(ksdev, "intermediate block:\n");
  57307. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57308. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57309. + symint[0], symint[1], symint[2], symint[3],
  57310. + symint[4], symint[5], symint[6], symint[7]);
  57311. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57312. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57313. + symint[8], symint[9], symint[10], symint[11],
  57314. + symint[12], symint[13], symint[14], symint[15]);
  57315. + dev_info(ksdev, "decrypted block:\n");
  57316. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57317. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57318. + symout[0], symout[1], symout[2], symout[3],
  57319. + symout[4], symout[5], symout[6], symout[7]);
  57320. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57321. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57322. + symout[8], symout[9], symout[10], symout[11],
  57323. + symout[12], symout[13], symout[14], symout[15]);
  57324. + dev_info(ksdev, "caam_sm_test: decrypt cycle with 8 byte key\n");
  57325. +#endif
  57326. +
  57327. + /* Check result */
  57328. + if (memcmp(symout, syminp, 256)) {
  57329. + dev_info(ksdev, "caam_sm_test: 8-byte key test mismatch\n");
  57330. + rtnval = -1;
  57331. + goto freekeys;
  57332. + } else
  57333. + dev_info(ksdev, "caam_sm_test: 8-byte key test match OK\n");
  57334. +
  57335. + /* AES-128 encrypt using 16 byte black key */
  57336. + black_key_aes128_dma = dma_map_single(ksdev, black_key_aes128, 16,
  57337. + DMA_TO_DEVICE);
  57338. + dma_sync_single_for_device(ksdev, black_key_aes128_dma, 16,
  57339. + DMA_TO_DEVICE);
  57340. + syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
  57341. + dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57342. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
  57343. +
  57344. + jdescsz = mk_job_desc(jdesc, black_key_aes128_dma, 16, syminp_dma,
  57345. + symint_dma, 256,
  57346. + OP_ALG_ENCRYPT | OP_ALG_ALGSEL_AES, 0);
  57347. +
  57348. +#ifdef SM_TEST_DETAIL
  57349. + dev_info(ksdev, "jobdesc:\n");
  57350. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57351. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57352. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57353. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57354. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57355. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57356. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57357. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57358. +#endif
  57359. +
  57360. + jstat = exec_test_job(ksdev, jdesc);
  57361. +
  57362. + dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57363. + dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57364. + dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57365. + dma_unmap_single(ksdev, black_key_aes128_dma, 16, DMA_TO_DEVICE);
  57366. +
  57367. +#ifdef SM_TEST_DETAIL
  57368. + dev_info(ksdev, "input block:\n");
  57369. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57370. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57371. + syminp[0], syminp[1], syminp[2], syminp[3],
  57372. + syminp[4], syminp[5], syminp[6], syminp[7]);
  57373. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57374. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57375. + syminp[8], syminp[9], syminp[10], syminp[11],
  57376. + syminp[12], syminp[13], syminp[14], syminp[15]);
  57377. + dev_info(ksdev, "intermediate block:\n");
  57378. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57379. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57380. + symint[0], symint[1], symint[2], symint[3],
  57381. + symint[4], symint[5], symint[6], symint[7]);
  57382. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57383. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57384. + symint[8], symint[9], symint[10], symint[11],
  57385. + symint[12], symint[13], symint[14], symint[15]);
  57386. + dev_info(ksdev, "caam_sm_test: encrypt cycle with 16 byte key\n");
  57387. +#endif
  57388. +
  57389. + /* AES-128 decrypt using 16 byte clear key */
  57390. + clear_key_aes128_dma = dma_map_single(ksdev, clear_key_aes128, 16,
  57391. + DMA_TO_DEVICE);
  57392. + dma_sync_single_for_device(ksdev, clear_key_aes128_dma, 16,
  57393. + DMA_TO_DEVICE);
  57394. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
  57395. + dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57396. + symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
  57397. +
  57398. + jdescsz = mk_job_desc(jdesc, clear_key_aes128_dma, 16, symint_dma,
  57399. + symout_dma, 256,
  57400. + OP_ALG_DECRYPT | OP_ALG_ALGSEL_AES, 0);
  57401. +
  57402. +#ifdef SM_TEST_DETAIL
  57403. + dev_info(ksdev, "jobdesc:\n");
  57404. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57405. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57406. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57407. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57408. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57409. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57410. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57411. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57412. +#endif
  57413. + jstat = exec_test_job(ksdev, jdesc);
  57414. +
  57415. + dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57416. + dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57417. + dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57418. + dma_unmap_single(ksdev, clear_key_aes128_dma, 16, DMA_TO_DEVICE);
  57419. +
  57420. +#ifdef SM_TEST_DETAIL
  57421. + dev_info(ksdev, "intermediate block:\n");
  57422. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57423. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57424. + symint[0], symint[1], symint[2], symint[3],
  57425. + symint[4], symint[5], symint[6], symint[7]);
  57426. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57427. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57428. + symint[8], symint[9], symint[10], symint[11],
  57429. + symint[12], symint[13], symint[14], symint[15]);
  57430. + dev_info(ksdev, "decrypted block:\n");
  57431. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57432. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57433. + symout[0], symout[1], symout[2], symout[3],
  57434. + symout[4], symout[5], symout[6], symout[7]);
  57435. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57436. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57437. + symout[8], symout[9], symout[10], symout[11],
  57438. + symout[12], symout[13], symout[14], symout[15]);
  57439. + dev_info(ksdev, "caam_sm_test: decrypt cycle with 16 byte key\n");
  57440. +#endif
  57441. +
  57442. + /* Check result */
  57443. + if (memcmp(symout, syminp, 256)) {
  57444. + dev_info(ksdev, "caam_sm_test: 16-byte key test mismatch\n");
  57445. + rtnval = -1;
  57446. + goto freekeys;
  57447. + } else
  57448. + dev_info(ksdev, "caam_sm_test: 16-byte key test match OK\n");
  57449. +
  57450. + /* AES-256 encrypt using 32 byte black key */
  57451. + black_key_aes256_dma = dma_map_single(ksdev, black_key_aes256, 32,
  57452. + DMA_TO_DEVICE);
  57453. + dma_sync_single_for_device(ksdev, black_key_aes256_dma, 32,
  57454. + DMA_TO_DEVICE);
  57455. + syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
  57456. + dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57457. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
  57458. +
  57459. + jdescsz = mk_job_desc(jdesc, black_key_aes256_dma, 32, syminp_dma,
  57460. + symint_dma, 256,
  57461. + OP_ALG_ENCRYPT | OP_ALG_ALGSEL_AES, 0);
  57462. +
  57463. +#ifdef SM_TEST_DETAIL
  57464. + dev_info(ksdev, "jobdesc:\n");
  57465. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57466. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57467. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57468. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57469. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57470. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57471. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57472. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57473. +#endif
  57474. +
  57475. + jstat = exec_test_job(ksdev, jdesc);
  57476. +
  57477. + dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57478. + dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  57479. + dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  57480. + dma_unmap_single(ksdev, black_key_aes256_dma, 32, DMA_TO_DEVICE);
  57481. +
  57482. +#ifdef SM_TEST_DETAIL
  57483. + dev_info(ksdev, "input block:\n");
  57484. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57485. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57486. + syminp[0], syminp[1], syminp[2], syminp[3],
  57487. + syminp[4], syminp[5], syminp[6], syminp[7]);
  57488. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57489. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57490. + syminp[8], syminp[9], syminp[10], syminp[11],
  57491. + syminp[12], syminp[13], syminp[14], syminp[15]);
  57492. + dev_info(ksdev, "intermediate block:\n");
  57493. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57494. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57495. + symint[0], symint[1], symint[2], symint[3],
  57496. + symint[4], symint[5], symint[6], symint[7]);
  57497. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57498. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57499. + symint[8], symint[9], symint[10], symint[11],
  57500. + symint[12], symint[13], symint[14], symint[15]);
  57501. + dev_info(ksdev, "caam_sm_test: encrypt cycle with 32 byte key\n");
  57502. +#endif
  57503. +
  57504. + /* AES-256 decrypt using 32-byte black key */
  57505. + clear_key_aes256_dma = dma_map_single(ksdev, clear_key_aes256, 32,
  57506. + DMA_TO_DEVICE);
  57507. + dma_sync_single_for_device(ksdev, clear_key_aes256_dma, 32,
  57508. + DMA_TO_DEVICE);
  57509. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
  57510. + dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57511. + symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
  57512. +
  57513. + jdescsz = mk_job_desc(jdesc, clear_key_aes256_dma, 32, symint_dma,
  57514. + symout_dma, 256,
  57515. + OP_ALG_DECRYPT | OP_ALG_ALGSEL_AES, 0);
  57516. +
  57517. +#ifdef SM_TEST_DETAIL
  57518. + dev_info(ksdev, "jobdesc:\n");
  57519. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  57520. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  57521. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  57522. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  57523. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  57524. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  57525. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  57526. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  57527. +#endif
  57528. +
  57529. + jstat = exec_test_job(ksdev, jdesc);
  57530. +
  57531. + dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57532. + dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  57533. + dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  57534. + dma_unmap_single(ksdev, clear_key_aes256_dma, 32, DMA_TO_DEVICE);
  57535. +
  57536. +#ifdef SM_TEST_DETAIL
  57537. + dev_info(ksdev, "intermediate block:\n");
  57538. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57539. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57540. + symint[0], symint[1], symint[2], symint[3],
  57541. + symint[4], symint[5], symint[6], symint[7]);
  57542. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57543. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57544. + symint[8], symint[9], symint[10], symint[11],
  57545. + symint[12], symint[13], symint[14], symint[15]);
  57546. + dev_info(ksdev, "decrypted block:\n");
  57547. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57548. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57549. + symout[0], symout[1], symout[2], symout[3],
  57550. + symout[4], symout[5], symout[6], symout[7]);
  57551. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  57552. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  57553. + symout[8], symout[9], symout[10], symout[11],
  57554. + symout[12], symout[13], symout[14], symout[15]);
  57555. + dev_info(ksdev, "caam_sm_test: decrypt cycle with 32 byte key\n");
  57556. +#endif
  57557. +
  57558. + /* Check result */
  57559. + if (memcmp(symout, syminp, 256)) {
  57560. + dev_info(ksdev, "caam_sm_test: 32-byte key test mismatch\n");
  57561. + rtnval = -1;
  57562. + goto freekeys;
  57563. + } else
  57564. + dev_info(ksdev, "caam_sm_test: 32-byte key test match OK\n");
  57565. +
  57566. +
  57567. + /* Remove 8/16/32 byte keys from keystore */
  57568. +freekeys:
  57569. + stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  57570. + if (stat)
  57571. + dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
  57572. + keyslot_des);
  57573. +
  57574. + stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  57575. + if (stat)
  57576. + dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
  57577. + keyslot_aes128);
  57578. +
  57579. + stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes256);
  57580. + if (stat)
  57581. + dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
  57582. + keyslot_aes256);
  57583. +
  57584. +
  57585. + /* Free resources */
  57586. +freemem:
  57587. +#ifdef SM_TEST_DETAIL
  57588. + dev_info(ksdev, "caam_sm_test: cleaning up\n");
  57589. +#endif
  57590. + kfree(syminp);
  57591. + kfree(symint);
  57592. + kfree(symout);
  57593. + kfree(clear_key_des);
  57594. + kfree(clear_key_aes128);
  57595. + kfree(clear_key_aes256);
  57596. + kfree(black_key_des);
  57597. + kfree(black_key_aes128);
  57598. + kfree(black_key_aes256);
  57599. + kfree(jdesc);
  57600. +
  57601. + /* Disconnect from keystore and leave */
  57602. + sm_release_keystore(ksdev, unit);
  57603. +
  57604. + return rtnval;
  57605. +}
  57606. +EXPORT_SYMBOL(caam_sm_example_init);
  57607. +
  57608. +void caam_sm_example_shutdown(void)
  57609. +{
  57610. + /* unused in present version */
  57611. + struct device_node *dev_node;
  57612. + struct platform_device *pdev;
  57613. +
  57614. + /*
  57615. + * Do of_find_compatible_node() then of_find_device_by_node()
  57616. + * once a functional device tree is available
  57617. + */
  57618. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  57619. + if (!dev_node) {
  57620. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  57621. + if (!dev_node)
  57622. + return;
  57623. + }
  57624. +
  57625. + pdev = of_find_device_by_node(dev_node);
  57626. + if (!pdev)
  57627. + return;
  57628. +
  57629. + of_node_get(dev_node);
  57630. +
  57631. +}
  57632. +
  57633. +static int __init caam_sm_test_init(void)
  57634. +{
  57635. + struct device_node *dev_node;
  57636. + struct platform_device *pdev;
  57637. +
  57638. + /*
  57639. + * Do of_find_compatible_node() then of_find_device_by_node()
  57640. + * once a functional device tree is available
  57641. + */
  57642. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  57643. + if (!dev_node) {
  57644. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  57645. + if (!dev_node)
  57646. + return -ENODEV;
  57647. + }
  57648. +
  57649. + pdev = of_find_device_by_node(dev_node);
  57650. + if (!pdev)
  57651. + return -ENODEV;
  57652. +
  57653. + of_node_put(dev_node);
  57654. +
  57655. + caam_sm_example_init(pdev);
  57656. +
  57657. + return 0;
  57658. +}
  57659. +
  57660. +
  57661. +/* Module-based initialization needs to wait for dev tree */
  57662. +#ifdef CONFIG_OF
  57663. +module_init(caam_sm_test_init);
  57664. +module_exit(caam_sm_example_shutdown);
  57665. +
  57666. +MODULE_LICENSE("Dual BSD/GPL");
  57667. +MODULE_DESCRIPTION("FSL CAAM Keystore Usage Example");
  57668. +MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
  57669. +#endif
  57670. diff -Nur linux-3.14.14/drivers/crypto/caam/snvsregs.h linux-imx6-3.14/drivers/crypto/caam/snvsregs.h
  57671. --- linux-3.14.14/drivers/crypto/caam/snvsregs.h 1969-12-31 18:00:00.000000000 -0600
  57672. +++ linux-imx6-3.14/drivers/crypto/caam/snvsregs.h 2014-12-08 00:31:52.552418001 -0600
  57673. @@ -0,0 +1,237 @@
  57674. +/*
  57675. + * SNVS hardware register-level view
  57676. + *
  57677. + * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
  57678. + */
  57679. +
  57680. +#ifndef SNVSREGS_H
  57681. +#define SNVSREGS_H
  57682. +
  57683. +#include <linux/types.h>
  57684. +#include <linux/io.h>
  57685. +
  57686. +/*
  57687. + * SNVS High Power Domain
  57688. + * Includes security violations, HA counter, RTC, alarm
  57689. + */
  57690. +struct snvs_hp {
  57691. + u32 lock;
  57692. + u32 cmd;
  57693. + u32 ctl;
  57694. + u32 secvio_int_en; /* Security Violation Interrupt Enable */
  57695. + u32 secvio_int_ctl; /* Security Violation Interrupt Control */
  57696. + u32 status;
  57697. + u32 secvio_status; /* Security Violation Status */
  57698. + u32 ha_counteriv; /* High Assurance Counter IV */
  57699. + u32 ha_counter; /* High Assurance Counter */
  57700. + u32 rtc_msb; /* Real Time Clock/Counter MSB */
  57701. + u32 rtc_lsb; /* Real Time Counter LSB */
  57702. + u32 time_alarm_msb; /* Time Alarm MSB */
  57703. + u32 time_alarm_lsb; /* Time Alarm LSB */
  57704. +};
  57705. +
  57706. +#define HP_LOCK_HAC_LCK 0x00040000
  57707. +#define HP_LOCK_HPSICR_LCK 0x00020000
  57708. +#define HP_LOCK_HPSVCR_LCK 0x00010000
  57709. +#define HP_LOCK_MKEYSEL_LCK 0x00000200
  57710. +#define HP_LOCK_TAMPCFG_LCK 0x00000100
  57711. +#define HP_LOCK_TAMPFLT_LCK 0x00000080
  57712. +#define HP_LOCK_SECVIO_LCK 0x00000040
  57713. +#define HP_LOCK_GENP_LCK 0x00000020
  57714. +#define HP_LOCK_MONOCTR_LCK 0x00000010
  57715. +#define HP_LOCK_CALIB_LCK 0x00000008
  57716. +#define HP_LOCK_SRTC_LCK 0x00000004
  57717. +#define HP_LOCK_ZMK_RD_LCK 0x00000002
  57718. +#define HP_LOCK_ZMK_WT_LCK 0x00000001
  57719. +
  57720. +#define HP_CMD_NONPRIV_AXS 0x80000000
  57721. +#define HP_CMD_HAC_STOP 0x00080000
  57722. +#define HP_CMD_HAC_CLEAR 0x00040000
  57723. +#define HP_CMD_HAC_LOAD 0x00020000
  57724. +#define HP_CMD_HAC_CFG_EN 0x00010000
  57725. +#define HP_CMD_SNVS_MSTR_KEY 0x00002000
  57726. +#define HP_CMD_PROG_ZMK 0x00001000
  57727. +#define HP_CMD_SW_LPSV 0x00000400
  57728. +#define HP_CMD_SW_FSV 0x00000200
  57729. +#define HP_CMD_SW_SV 0x00000100
  57730. +#define HP_CMD_LP_SWR_DIS 0x00000020
  57731. +#define HP_CMD_LP_SWR 0x00000010
  57732. +#define HP_CMD_SSM_SFNS_DIS 0x00000004
  57733. +#define HP_CMD_SSM_ST_DIS 0x00000002
  57734. +#define HP_CMD_SMM_ST 0x00000001
  57735. +
  57736. +#define HP_CTL_TIME_SYNC 0x00010000
  57737. +#define HP_CTL_CAL_VAL_SHIFT 10
  57738. +#define HP_CTL_CAL_VAL_MASK (0x1f << HP_CTL_CALIB_SHIFT)
  57739. +#define HP_CTL_CALIB_EN 0x00000100
  57740. +#define HP_CTL_PI_FREQ_SHIFT 4
  57741. +#define HP_CTL_PI_FREQ_MASK (0xf << HP_CTL_PI_FREQ_SHIFT)
  57742. +#define HP_CTL_PI_EN 0x00000008
  57743. +#define HP_CTL_TIMEALARM_EN 0x00000002
  57744. +#define HP_CTL_RTC_EN 0x00000001
  57745. +
  57746. +#define HP_SECVIO_INTEN_EN 0x10000000
  57747. +#define HP_SECVIO_INTEN_SRC5 0x00000020
  57748. +#define HP_SECVIO_INTEN_SRC4 0x00000010
  57749. +#define HP_SECVIO_INTEN_SRC3 0x00000008
  57750. +#define HP_SECVIO_INTEN_SRC2 0x00000004
  57751. +#define HP_SECVIO_INTEN_SRC1 0x00000002
  57752. +#define HP_SECVIO_INTEN_SRC0 0x00000001
  57753. +#define HP_SECVIO_INTEN_ALL 0x8000003f
  57754. +
  57755. +#define HP_SECVIO_ICTL_CFG_SHIFT 30
  57756. +#define HP_SECVIO_ICTL_CFG_MASK (0x3 << HP_SECVIO_ICTL_CFG_SHIFT)
  57757. +#define HP_SECVIO_ICTL_CFG5_SHIFT 5
  57758. +#define HP_SECVIO_ICTL_CFG5_MASK (0x3 << HP_SECVIO_ICTL_CFG5_SHIFT)
  57759. +#define HP_SECVIO_ICTL_CFG_DISABLE 0
  57760. +#define HP_SECVIO_ICTL_CFG_NONFATAL 1
  57761. +#define HP_SECVIO_ICTL_CFG_FATAL 2
  57762. +#define HP_SECVIO_ICTL_CFG4_FATAL 0x00000010
  57763. +#define HP_SECVIO_ICTL_CFG3_FATAL 0x00000008
  57764. +#define HP_SECVIO_ICTL_CFG2_FATAL 0x00000004
  57765. +#define HP_SECVIO_ICTL_CFG1_FATAL 0x00000002
  57766. +#define HP_SECVIO_ICTL_CFG0_FATAL 0x00000001
  57767. +
  57768. +#define HP_STATUS_ZMK_ZERO 0x80000000
  57769. +#define HP_STATUS_OTPMK_ZERO 0x08000000
  57770. +#define HP_STATUS_OTPMK_SYN_SHIFT 16
  57771. +#define HP_STATUS_OTPMK_SYN_MASK (0x1ff << HP_STATUS_OTPMK_SYN_SHIFT)
  57772. +#define HP_STATUS_SSM_ST_SHIFT 8
  57773. +#define HP_STATUS_SSM_ST_MASK (0xf << HP_STATUS_SSM_ST_SHIFT)
  57774. +#define HP_STATUS_SSM_ST_INIT 0
  57775. +#define HP_STATUS_SSM_ST_HARDFAIL 1
  57776. +#define HP_STATUS_SSM_ST_SOFTFAIL 3
  57777. +#define HP_STATUS_SSM_ST_INITINT 8
  57778. +#define HP_STATUS_SSM_ST_CHECK 9
  57779. +#define HP_STATUS_SSM_ST_NONSECURE 11
  57780. +#define HP_STATUS_SSM_ST_TRUSTED 13
  57781. +#define HP_STATUS_SSM_ST_SECURE 15
  57782. +
  57783. +#define HP_SECVIOST_ZMK_ECC_FAIL 0x08000000 /* write to clear */
  57784. +#define HP_SECVIOST_ZMK_SYN_SHIFT 16
  57785. +#define HP_SECVIOST_ZMK_SYN_MASK (0x1ff << HP_SECVIOST_ZMK_SYN_SHIFT)
  57786. +#define HP_SECVIOST_SECVIO5 0x00000020
  57787. +#define HP_SECVIOST_SECVIO4 0x00000010
  57788. +#define HP_SECVIOST_SECVIO3 0x00000008
  57789. +#define HP_SECVIOST_SECVIO2 0x00000004
  57790. +#define HP_SECVIOST_SECVIO1 0x00000002
  57791. +#define HP_SECVIOST_SECVIO0 0x00000001
  57792. +#define HP_SECVIOST_SECVIOMASK 0x0000003f
  57793. +
  57794. +/*
  57795. + * SNVS Low Power Domain
  57796. + * Includes glitch detector, SRTC, alarm, monotonic counter, ZMK
  57797. + */
  57798. +struct snvs_lp {
  57799. + u32 lock;
  57800. + u32 ctl;
  57801. + u32 mstr_key_ctl; /* Master Key Control */
  57802. + u32 secvio_ctl; /* Security Violation Control */
  57803. + u32 tamper_filt_cfg; /* Tamper Glitch Filters Configuration */
  57804. + u32 tamper_det_cfg; /* Tamper Detectors Configuration */
  57805. + u32 status;
  57806. + u32 srtc_msb; /* Secure Real Time Clock/Counter MSB */
  57807. + u32 srtc_lsb; /* Secure Real Time Clock/Counter LSB */
  57808. + u32 time_alarm; /* Time Alarm */
  57809. + u32 smc_msb; /* Secure Monotonic Counter MSB */
  57810. + u32 smc_lsb; /* Secure Monotonic Counter LSB */
  57811. + u32 pwr_glitch_det; /* Power Glitch Detector */
  57812. + u32 gen_purpose;
  57813. + u32 zmk[8]; /* Zeroizable Master Key */
  57814. +};
  57815. +
  57816. +#define LP_LOCK_MKEYSEL_LCK 0x00000200
  57817. +#define LP_LOCK_TAMPDET_LCK 0x00000100
  57818. +#define LP_LOCK_TAMPFLT_LCK 0x00000080
  57819. +#define LP_LOCK_SECVIO_LCK 0x00000040
  57820. +#define LP_LOCK_GENP_LCK 0x00000020
  57821. +#define LP_LOCK_MONOCTR_LCK 0x00000010
  57822. +#define LP_LOCK_CALIB_LCK 0x00000008
  57823. +#define LP_LOCK_SRTC_LCK 0x00000004
  57824. +#define LP_LOCK_ZMK_RD_LCK 0x00000002
  57825. +#define LP_LOCK_ZMK_WT_LCK 0x00000001
  57826. +
  57827. +#define LP_CTL_CAL_VAL_SHIFT 10
  57828. +#define LP_CTL_CAL_VAL_MASK (0x1f << LP_CTL_CAL_VAL_SHIFT)
  57829. +#define LP_CTL_CALIB_EN 0x00000100
  57830. +#define LP_CTL_SRTC_INVAL_EN 0x00000010
  57831. +#define LP_CTL_WAKE_INT_EN 0x00000008
  57832. +#define LP_CTL_MONOCTR_EN 0x00000004
  57833. +#define LP_CTL_TIMEALARM_EN 0x00000002
  57834. +#define LP_CTL_SRTC_EN 0x00000001
  57835. +
  57836. +#define LP_MKEYCTL_ZMKECC_SHIFT 8
  57837. +#define LP_MKEYCTL_ZMKECC_MASK (0xff << LP_MKEYCTL_ZMKECC_SHIFT)
  57838. +#define LP_MKEYCTL_ZMKECC_EN 0x00000010
  57839. +#define LP_MKEYCTL_ZMKECC_VAL 0x00000008
  57840. +#define LP_MKEYCTL_ZMKECC_PROG 0x00000004
  57841. +#define LP_MKEYCTL_MKSEL_SHIFT 0
  57842. +#define LP_MKEYCTL_MKSEL_MASK (3 << LP_MKEYCTL_MKSEL_SHIFT)
  57843. +#define LP_MKEYCTL_MK_OTP 0
  57844. +#define LP_MKEYCTL_MK_ZMK 2
  57845. +#define LP_MKEYCTL_MK_COMB 3
  57846. +
  57847. +#define LP_SECVIO_CTL_SRC5 0x20
  57848. +#define LP_SECVIO_CTL_SRC4 0x10
  57849. +#define LP_SECVIO_CTL_SRC3 0x08
  57850. +#define LP_SECVIO_CTL_SRC2 0x04
  57851. +#define LP_SECVIO_CTL_SRC1 0x02
  57852. +#define LP_SECVIO_CTL_SRC0 0x01
  57853. +
  57854. +#define LP_TAMPFILT_EXT2_EN 0x80000000
  57855. +#define LP_TAMPFILT_EXT2_SHIFT 24
  57856. +#define LP_TAMPFILT_EXT2_MASK (0x1f << LP_TAMPFILT_EXT2_SHIFT)
  57857. +#define LP_TAMPFILT_EXT1_EN 0x00800000
  57858. +#define LP_TAMPFILT_EXT1_SHIFT 16
  57859. +#define LP_TAMPFILT_EXT1_MASK (0x1f << LP_TAMPFILT_EXT1_SHIFT)
  57860. +#define LP_TAMPFILT_WM_EN 0x00000080
  57861. +#define LP_TAMPFILT_WM_SHIFT 0
  57862. +#define LP_TAMPFILT_WM_MASK (0x1f << LP_TAMPFILT_WM_SHIFT)
  57863. +
  57864. +#define LP_TAMPDET_OSC_BPS 0x10000000
  57865. +#define LP_TAMPDET_VRC_SHIFT 24
  57866. +#define LP_TAMPDET_VRC_MASK (3 << LP_TAMPFILT_VRC_SHIFT)
  57867. +#define LP_TAMPDET_HTDC_SHIFT 20
  57868. +#define LP_TAMPDET_HTDC_MASK (3 << LP_TAMPFILT_HTDC_SHIFT)
  57869. +#define LP_TAMPDET_LTDC_SHIFT 16
  57870. +#define LP_TAMPDET_LTDC_MASK (3 << LP_TAMPFILT_LTDC_SHIFT)
  57871. +#define LP_TAMPDET_POR_OBS 0x00008000
  57872. +#define LP_TAMPDET_PFD_OBS 0x00004000
  57873. +#define LP_TAMPDET_ET2_EN 0x00000400
  57874. +#define LP_TAMPDET_ET1_EN 0x00000200
  57875. +#define LP_TAMPDET_WMT2_EN 0x00000100
  57876. +#define LP_TAMPDET_WMT1_EN 0x00000080
  57877. +#define LP_TAMPDET_VT_EN 0x00000040
  57878. +#define LP_TAMPDET_TT_EN 0x00000020
  57879. +#define LP_TAMPDET_CT_EN 0x00000010
  57880. +#define LP_TAMPDET_MCR_EN 0x00000004
  57881. +#define LP_TAMPDET_SRTCR_EN 0x00000002
  57882. +
  57883. +#define LP_STATUS_SECURE
  57884. +#define LP_STATUS_NONSECURE
  57885. +#define LP_STATUS_SCANEXIT 0x00100000 /* all write 1 clear here on */
  57886. +#define LP_STATUS_EXT_SECVIO 0x00010000
  57887. +#define LP_STATUS_ET2 0x00000400
  57888. +#define LP_STATUS_ET1 0x00000200
  57889. +#define LP_STATUS_WMT2 0x00000100
  57890. +#define LP_STATUS_WMT1 0x00000080
  57891. +#define LP_STATUS_VTD 0x00000040
  57892. +#define LP_STATUS_TTD 0x00000020
  57893. +#define LP_STATUS_CTD 0x00000010
  57894. +#define LP_STATUS_PGD 0x00000008
  57895. +#define LP_STATUS_MCR 0x00000004
  57896. +#define LP_STATUS_SRTCR 0x00000002
  57897. +#define LP_STATUS_LPTA 0x00000001
  57898. +
  57899. +/* Full SNVS register page, including version/options */
  57900. +struct snvs_full {
  57901. + struct snvs_hp hp;
  57902. + struct snvs_lp lp;
  57903. + u32 rsvd[731]; /* deadspace 0x08c-0xbf7 */
  57904. +
  57905. + /* Version / Revision / Option ID space - end of register page */
  57906. + u32 vid; /* 0xbf8 HP Version ID (VID 1) */
  57907. + u32 opt_rev; /* 0xbfc HP Options / Revision (VID 2) */
  57908. +};
  57909. +
  57910. +#endif /* SNVSREGS_H */
  57911. diff -Nur linux-3.14.14/drivers/dma/imx-sdma.c linux-imx6-3.14/drivers/dma/imx-sdma.c
  57912. --- linux-3.14.14/drivers/dma/imx-sdma.c 2014-07-28 10:07:25.000000000 -0500
  57913. +++ linux-imx6-3.14/drivers/dma/imx-sdma.c 2014-12-08 00:31:52.568418001 -0600
  57914. @@ -29,6 +29,7 @@
  57915. #include <linux/semaphore.h>
  57916. #include <linux/spinlock.h>
  57917. #include <linux/device.h>
  57918. +#include <linux/genalloc.h>
  57919. #include <linux/dma-mapping.h>
  57920. #include <linux/firmware.h>
  57921. #include <linux/slab.h>
  57922. @@ -232,6 +233,14 @@
  57923. struct sdma_engine;
  57924. +enum sdma_mode {
  57925. + SDMA_MODE_INVALID = 0,
  57926. + SDMA_MODE_LOOP,
  57927. + SDMA_MODE_NORMAL,
  57928. + SDMA_MODE_P2P,
  57929. + SDMA_MODE_NO_BD,
  57930. +};
  57931. +
  57932. /**
  57933. * struct sdma_channel - housekeeping for a SDMA channel
  57934. *
  57935. @@ -244,6 +253,7 @@
  57936. * @word_size peripheral access size
  57937. * @buf_tail ID of the buffer that was processed
  57938. * @num_bd max NUM_BD. number of descriptors currently handling
  57939. + * @bd_iram flag indicating the memory location of buffer descriptor
  57940. */
  57941. struct sdma_channel {
  57942. struct sdma_engine *sdma;
  57943. @@ -255,14 +265,19 @@
  57944. enum dma_slave_buswidth word_size;
  57945. unsigned int buf_tail;
  57946. unsigned int num_bd;
  57947. + unsigned int period_len;
  57948. struct sdma_buffer_descriptor *bd;
  57949. dma_addr_t bd_phys;
  57950. + bool bd_iram;
  57951. unsigned int pc_from_device, pc_to_device;
  57952. - unsigned long flags;
  57953. - dma_addr_t per_address;
  57954. + unsigned int device_to_device;
  57955. + unsigned int other_script;
  57956. + enum sdma_mode mode;
  57957. + dma_addr_t per_address, per_address2;
  57958. unsigned long event_mask[2];
  57959. unsigned long watermark_level;
  57960. u32 shp_addr, per_addr;
  57961. + u32 data_addr1, data_addr2;
  57962. struct dma_chan chan;
  57963. spinlock_t lock;
  57964. struct dma_async_tx_descriptor desc;
  57965. @@ -272,8 +287,6 @@
  57966. struct tasklet_struct tasklet;
  57967. };
  57968. -#define IMX_DMA_SG_LOOP BIT(0)
  57969. -
  57970. #define MAX_DMA_CHANNELS 32
  57971. #define MXC_SDMA_DEFAULT_PRIORITY 1
  57972. #define MXC_SDMA_MIN_PRIORITY 1
  57973. @@ -325,6 +338,7 @@
  57974. spinlock_t channel_0_lock;
  57975. u32 script_number;
  57976. struct sdma_script_start_addrs *script_addrs;
  57977. + struct gen_pool *iram_pool;
  57978. const struct sdma_driver_data *drvdata;
  57979. };
  57980. @@ -540,12 +554,14 @@
  57981. dma_addr_t buf_phys;
  57982. int ret;
  57983. unsigned long flags;
  57984. + bool use_iram = true;
  57985. - buf_virt = dma_alloc_coherent(NULL,
  57986. - size,
  57987. - &buf_phys, GFP_KERNEL);
  57988. + buf_virt = gen_pool_dma_alloc(sdma->iram_pool, size, &buf_phys);
  57989. if (!buf_virt) {
  57990. - return -ENOMEM;
  57991. + use_iram = false;
  57992. + buf_virt = dma_alloc_coherent(NULL, size, &buf_phys, GFP_KERNEL);
  57993. + if (!buf_virt)
  57994. + return -ENOMEM;
  57995. }
  57996. spin_lock_irqsave(&sdma->channel_0_lock, flags);
  57997. @@ -562,7 +578,10 @@
  57998. spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
  57999. - dma_free_coherent(NULL, size, buf_virt, buf_phys);
  58000. + if (use_iram)
  58001. + gen_pool_free(sdma->iram_pool, (unsigned long)buf_virt, size);
  58002. + else
  58003. + dma_free_coherent(NULL, size, buf_virt, buf_phys);
  58004. return ret;
  58005. }
  58006. @@ -593,6 +612,12 @@
  58007. static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
  58008. {
  58009. + if (sdmac->desc.callback)
  58010. + sdmac->desc.callback(sdmac->desc.callback_param);
  58011. +}
  58012. +
  58013. +static void sdma_update_channel_loop(struct sdma_channel *sdmac)
  58014. +{
  58015. struct sdma_buffer_descriptor *bd;
  58016. /*
  58017. @@ -607,15 +632,10 @@
  58018. if (bd->mode.status & BD_RROR)
  58019. sdmac->status = DMA_ERROR;
  58020. - else
  58021. - sdmac->status = DMA_IN_PROGRESS;
  58022. bd->mode.status |= BD_DONE;
  58023. sdmac->buf_tail++;
  58024. sdmac->buf_tail %= sdmac->num_bd;
  58025. -
  58026. - if (sdmac->desc.callback)
  58027. - sdmac->desc.callback(sdmac->desc.callback_param);
  58028. }
  58029. }
  58030. @@ -647,14 +667,31 @@
  58031. sdmac->desc.callback(sdmac->desc.callback_param);
  58032. }
  58033. +static void sdma_handle_other_intr(struct sdma_channel *sdmac)
  58034. +{
  58035. + if (sdmac->desc.callback)
  58036. + sdmac->desc.callback(sdmac->desc.callback_param);
  58037. +}
  58038. +
  58039. static void sdma_tasklet(unsigned long data)
  58040. {
  58041. struct sdma_channel *sdmac = (struct sdma_channel *) data;
  58042. + struct sdma_engine *sdma = sdmac->sdma;
  58043. - if (sdmac->flags & IMX_DMA_SG_LOOP)
  58044. + switch (sdmac->mode) {
  58045. + case SDMA_MODE_LOOP:
  58046. sdma_handle_channel_loop(sdmac);
  58047. - else
  58048. + break;
  58049. + case SDMA_MODE_NORMAL:
  58050. mxc_sdma_handle_channel_normal(sdmac);
  58051. + break;
  58052. + case SDMA_MODE_NO_BD:
  58053. + sdma_handle_other_intr(sdmac);
  58054. + break;
  58055. + default:
  58056. + dev_err(sdma->dev, "invalid SDMA MODE!\n");
  58057. + break;
  58058. + }
  58059. }
  58060. static irqreturn_t sdma_int_handler(int irq, void *dev_id)
  58061. @@ -671,6 +708,9 @@
  58062. int channel = fls(stat) - 1;
  58063. struct sdma_channel *sdmac = &sdma->channel[channel];
  58064. + if (sdmac->mode & SDMA_MODE_LOOP)
  58065. + sdma_update_channel_loop(sdmac);
  58066. +
  58067. tasklet_schedule(&sdmac->tasklet);
  58068. __clear_bit(channel, &stat);
  58069. @@ -692,9 +732,12 @@
  58070. * two peripherals or memory-to-memory transfers
  58071. */
  58072. int per_2_per = 0, emi_2_emi = 0;
  58073. + int other = 0;
  58074. sdmac->pc_from_device = 0;
  58075. sdmac->pc_to_device = 0;
  58076. + sdmac->device_to_device = 0;
  58077. + sdmac->other_script = 0;
  58078. switch (peripheral_type) {
  58079. case IMX_DMATYPE_MEMORY:
  58080. @@ -740,8 +783,8 @@
  58081. emi_2_per = sdma->script_addrs->mcu_2_shp_addr;
  58082. break;
  58083. case IMX_DMATYPE_ASRC:
  58084. - per_2_emi = sdma->script_addrs->asrc_2_mcu_addr;
  58085. - emi_2_per = sdma->script_addrs->asrc_2_mcu_addr;
  58086. + per_2_emi = sdma->script_addrs->shp_2_mcu_addr;
  58087. + emi_2_per = sdma->script_addrs->mcu_2_shp_addr;
  58088. per_2_per = sdma->script_addrs->per_2_per_addr;
  58089. break;
  58090. case IMX_DMATYPE_MSHC:
  58091. @@ -758,12 +801,17 @@
  58092. case IMX_DMATYPE_IPU_MEMORY:
  58093. emi_2_per = sdma->script_addrs->ext_mem_2_ipu_addr;
  58094. break;
  58095. + case IMX_DMATYPE_HDMI:
  58096. + other = sdma->script_addrs->hdmi_dma_addr;
  58097. + break;
  58098. default:
  58099. break;
  58100. }
  58101. sdmac->pc_from_device = per_2_emi;
  58102. sdmac->pc_to_device = emi_2_per;
  58103. + sdmac->device_to_device = per_2_per;
  58104. + sdmac->other_script = other;
  58105. }
  58106. static int sdma_load_context(struct sdma_channel *sdmac)
  58107. @@ -776,11 +824,14 @@
  58108. int ret;
  58109. unsigned long flags;
  58110. - if (sdmac->direction == DMA_DEV_TO_MEM) {
  58111. + if (sdmac->direction == DMA_DEV_TO_MEM)
  58112. load_address = sdmac->pc_from_device;
  58113. - } else {
  58114. + else if (sdmac->direction == DMA_DEV_TO_DEV)
  58115. + load_address = sdmac->device_to_device;
  58116. + else if (sdmac->direction == DMA_MEM_TO_DEV)
  58117. load_address = sdmac->pc_to_device;
  58118. - }
  58119. + else
  58120. + load_address = sdmac->other_script;
  58121. if (load_address < 0)
  58122. return load_address;
  58123. @@ -800,11 +851,16 @@
  58124. /* Send by context the event mask,base address for peripheral
  58125. * and watermark level
  58126. */
  58127. - context->gReg[0] = sdmac->event_mask[1];
  58128. - context->gReg[1] = sdmac->event_mask[0];
  58129. - context->gReg[2] = sdmac->per_addr;
  58130. - context->gReg[6] = sdmac->shp_addr;
  58131. - context->gReg[7] = sdmac->watermark_level;
  58132. + if (sdmac->peripheral_type == IMX_DMATYPE_HDMI) {
  58133. + context->gReg[4] = sdmac->data_addr1;
  58134. + context->gReg[6] = sdmac->data_addr2;
  58135. + } else {
  58136. + context->gReg[0] = sdmac->event_mask[1];
  58137. + context->gReg[1] = sdmac->event_mask[0];
  58138. + context->gReg[2] = sdmac->per_addr;
  58139. + context->gReg[6] = sdmac->shp_addr;
  58140. + context->gReg[7] = sdmac->watermark_level;
  58141. + }
  58142. bd0->mode.command = C0_SETDM;
  58143. bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
  58144. @@ -829,6 +885,7 @@
  58145. static int sdma_config_channel(struct sdma_channel *sdmac)
  58146. {
  58147. + struct imx_dma_data *data = sdmac->chan.private;
  58148. int ret;
  58149. sdma_disable_channel(sdmac);
  58150. @@ -837,12 +894,19 @@
  58151. sdmac->event_mask[1] = 0;
  58152. sdmac->shp_addr = 0;
  58153. sdmac->per_addr = 0;
  58154. + sdmac->data_addr1 = 0;
  58155. + sdmac->data_addr2 = 0;
  58156. if (sdmac->event_id0) {
  58157. if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
  58158. return -EINVAL;
  58159. sdma_event_enable(sdmac, sdmac->event_id0);
  58160. }
  58161. + if (sdmac->event_id1) {
  58162. + if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events)
  58163. + return -EINVAL;
  58164. + sdma_event_enable(sdmac, sdmac->event_id1);
  58165. + }
  58166. switch (sdmac->peripheral_type) {
  58167. case IMX_DMATYPE_DSP:
  58168. @@ -862,19 +926,75 @@
  58169. (sdmac->peripheral_type != IMX_DMATYPE_DSP)) {
  58170. /* Handle multiple event channels differently */
  58171. if (sdmac->event_id1) {
  58172. - sdmac->event_mask[1] = BIT(sdmac->event_id1 % 32);
  58173. - if (sdmac->event_id1 > 31)
  58174. - __set_bit(31, &sdmac->watermark_level);
  58175. - sdmac->event_mask[0] = BIT(sdmac->event_id0 % 32);
  58176. - if (sdmac->event_id0 > 31)
  58177. - __set_bit(30, &sdmac->watermark_level);
  58178. + if (sdmac->event_id0 > 31) {
  58179. + sdmac->event_mask[0] |= 0;
  58180. + __set_bit(28, &sdmac->watermark_level);
  58181. + sdmac->event_mask[1] |=
  58182. + BIT(sdmac->event_id0 % 32);
  58183. + } else {
  58184. + sdmac->event_mask[1] |= 0;
  58185. + sdmac->event_mask[0] |=
  58186. + BIT(sdmac->event_id0 % 32);
  58187. + }
  58188. + if (sdmac->event_id1 > 31) {
  58189. + sdmac->event_mask[0] |= 0;
  58190. + __set_bit(29, &sdmac->watermark_level);
  58191. + sdmac->event_mask[1] |=
  58192. + BIT(sdmac->event_id1 % 32);
  58193. + } else {
  58194. + sdmac->event_mask[1] |= 0;
  58195. + sdmac->event_mask[0] |=
  58196. + BIT(sdmac->event_id1 % 32);
  58197. + }
  58198. + /* BIT 11:
  58199. + * 1 : Source on SPBA
  58200. + * 0 : Source on AIPS
  58201. + */
  58202. + __set_bit(11, &sdmac->watermark_level);
  58203. + /* BIT 12:
  58204. + * 1 : Destination on SPBA
  58205. + * 0 : Destination on AIPS
  58206. + */
  58207. + __set_bit(12, &sdmac->watermark_level);
  58208. + __set_bit(31, &sdmac->watermark_level);
  58209. + /* BIT 31:
  58210. + * 1 : Amount of samples to be transferred is
  58211. + * unknown and script will keep on transferring
  58212. + * samples as long as both events are detected
  58213. + * and script must be manually stopped by the
  58214. + * application.
  58215. + * 0 : The amount of samples to be is equal to
  58216. + * the count field of mode word
  58217. + * */
  58218. + __set_bit(25, &sdmac->watermark_level);
  58219. + __clear_bit(24, &sdmac->watermark_level);
  58220. } else {
  58221. - __set_bit(sdmac->event_id0, sdmac->event_mask);
  58222. + if (sdmac->event_id0 > 31) {
  58223. + sdmac->event_mask[0] = 0;
  58224. + sdmac->event_mask[1] |=
  58225. + BIT(sdmac->event_id0 % 32);
  58226. + } else {
  58227. + sdmac->event_mask[0] |=
  58228. + BIT(sdmac->event_id0 % 32);
  58229. + sdmac->event_mask[1] = 0;
  58230. + }
  58231. }
  58232. /* Watermark Level */
  58233. sdmac->watermark_level |= sdmac->watermark_level;
  58234. /* Address */
  58235. - sdmac->shp_addr = sdmac->per_address;
  58236. + if (sdmac->direction == DMA_DEV_TO_DEV) {
  58237. + sdmac->shp_addr = sdmac->per_address2;
  58238. + sdmac->per_addr = sdmac->per_address;
  58239. + } else if (sdmac->direction == DMA_TRANS_NONE) {
  58240. + if (sdmac->peripheral_type != IMX_DMATYPE_HDMI ||
  58241. + !data->data_addr1 || !data->data_addr2)
  58242. + return -EINVAL;
  58243. + sdmac->data_addr1 = *(u32 *)data->data_addr1;
  58244. + sdmac->data_addr2 = *(u32 *)data->data_addr2;
  58245. + sdmac->watermark_level = 0;
  58246. + } else {
  58247. + sdmac->shp_addr = sdmac->per_address;
  58248. + }
  58249. } else {
  58250. sdmac->watermark_level = 0; /* FIXME: M3_BASE_ADDRESS */
  58251. }
  58252. @@ -906,10 +1026,15 @@
  58253. int channel = sdmac->channel;
  58254. int ret = -EBUSY;
  58255. - sdmac->bd = dma_alloc_coherent(NULL, PAGE_SIZE, &sdmac->bd_phys, GFP_KERNEL);
  58256. + sdmac->bd_iram = true;
  58257. + sdmac->bd = gen_pool_dma_alloc(sdma->iram_pool, PAGE_SIZE, &sdmac->bd_phys);
  58258. if (!sdmac->bd) {
  58259. - ret = -ENOMEM;
  58260. - goto out;
  58261. + sdmac->bd_iram = false;
  58262. + sdmac->bd = dma_alloc_coherent(NULL, PAGE_SIZE, &sdmac->bd_phys, GFP_KERNEL);
  58263. + if (!sdmac->bd) {
  58264. + ret = -ENOMEM;
  58265. + goto out;
  58266. + }
  58267. }
  58268. memset(sdmac->bd, 0, PAGE_SIZE);
  58269. @@ -967,7 +1092,8 @@
  58270. }
  58271. sdmac->peripheral_type = data->peripheral_type;
  58272. - sdmac->event_id0 = data->dma_request;
  58273. + sdmac->event_id0 = data->dma_request0;
  58274. + sdmac->event_id1 = data->dma_request1;
  58275. clk_enable(sdmac->sdma->clk_ipg);
  58276. clk_enable(sdmac->sdma->clk_ahb);
  58277. @@ -985,6 +1111,9 @@
  58278. /* txd.flags will be overwritten in prep funcs */
  58279. sdmac->desc.flags = DMA_CTRL_ACK;
  58280. + /* Set SDMA channel mode to unvalid to avoid misconfig */
  58281. + sdmac->mode = SDMA_MODE_INVALID;
  58282. +
  58283. return 0;
  58284. }
  58285. @@ -1005,7 +1134,10 @@
  58286. sdma_set_channel_priority(sdmac, 0);
  58287. - dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys);
  58288. + if (sdmac->bd_iram)
  58289. + gen_pool_free(sdma->iram_pool, (unsigned long)sdmac->bd, PAGE_SIZE);
  58290. + else
  58291. + dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys);
  58292. clk_disable(sdma->clk_ipg);
  58293. clk_disable(sdma->clk_ahb);
  58294. @@ -1026,7 +1158,7 @@
  58295. return NULL;
  58296. sdmac->status = DMA_IN_PROGRESS;
  58297. - sdmac->flags = 0;
  58298. + sdmac->mode = SDMA_MODE_NORMAL;
  58299. sdmac->buf_tail = 0;
  58300. @@ -1119,9 +1251,9 @@
  58301. {
  58302. struct sdma_channel *sdmac = to_sdma_chan(chan);
  58303. struct sdma_engine *sdma = sdmac->sdma;
  58304. - int num_periods = buf_len / period_len;
  58305. int channel = sdmac->channel;
  58306. int ret, i = 0, buf = 0;
  58307. + int num_periods;
  58308. dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
  58309. @@ -1131,13 +1263,35 @@
  58310. sdmac->status = DMA_IN_PROGRESS;
  58311. sdmac->buf_tail = 0;
  58312. + sdmac->period_len = period_len;
  58313. - sdmac->flags |= IMX_DMA_SG_LOOP;
  58314. sdmac->direction = direction;
  58315. +
  58316. + switch (sdmac->direction) {
  58317. + case DMA_DEV_TO_DEV:
  58318. + sdmac->mode = SDMA_MODE_P2P;
  58319. + break;
  58320. + case DMA_TRANS_NONE:
  58321. + sdmac->mode = SDMA_MODE_NO_BD;
  58322. + break;
  58323. + case DMA_MEM_TO_DEV:
  58324. + case DMA_DEV_TO_MEM:
  58325. + sdmac->mode = SDMA_MODE_LOOP;
  58326. + break;
  58327. + default:
  58328. + dev_err(sdma->dev, "invalid SDMA direction %d\n", direction);
  58329. + return NULL;
  58330. + }
  58331. +
  58332. ret = sdma_load_context(sdmac);
  58333. if (ret)
  58334. goto err_out;
  58335. + if (period_len)
  58336. + num_periods = buf_len / period_len;
  58337. + else
  58338. + return &sdmac->desc;
  58339. +
  58340. if (num_periods > NUM_BD) {
  58341. dev_err(sdma->dev, "SDMA channel %d: maximum number of sg exceeded: %d > %d\n",
  58342. channel, num_periods, NUM_BD);
  58343. @@ -1202,18 +1356,31 @@
  58344. sdma_disable_channel(sdmac);
  58345. return 0;
  58346. case DMA_SLAVE_CONFIG:
  58347. - if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
  58348. + if (dmaengine_cfg->direction == DMA_DEV_TO_DEV) {
  58349. + sdmac->per_address = dmaengine_cfg->src_addr;
  58350. + sdmac->per_address2 = dmaengine_cfg->dst_addr;
  58351. + sdmac->watermark_level = 0;
  58352. + sdmac->watermark_level |=
  58353. + dmaengine_cfg->src_maxburst;
  58354. + sdmac->watermark_level |=
  58355. + dmaengine_cfg->dst_maxburst << 16;
  58356. + sdmac->word_size = dmaengine_cfg->dst_addr_width;
  58357. + } else if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
  58358. sdmac->per_address = dmaengine_cfg->src_addr;
  58359. sdmac->watermark_level = dmaengine_cfg->src_maxburst *
  58360. dmaengine_cfg->src_addr_width;
  58361. sdmac->word_size = dmaengine_cfg->src_addr_width;
  58362. - } else {
  58363. + } else if (dmaengine_cfg->direction == DMA_MEM_TO_DEV) {
  58364. sdmac->per_address = dmaengine_cfg->dst_addr;
  58365. sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
  58366. dmaengine_cfg->dst_addr_width;
  58367. sdmac->word_size = dmaengine_cfg->dst_addr_width;
  58368. }
  58369. sdmac->direction = dmaengine_cfg->direction;
  58370. + if (dmaengine_cfg->dma_request0)
  58371. + sdmac->event_id0 = dmaengine_cfg->dma_request0;
  58372. + if (dmaengine_cfg->dma_request1)
  58373. + sdmac->event_id1 = dmaengine_cfg->dma_request1;
  58374. return sdma_config_channel(sdmac);
  58375. default:
  58376. return -ENOSYS;
  58377. @@ -1227,9 +1394,15 @@
  58378. struct dma_tx_state *txstate)
  58379. {
  58380. struct sdma_channel *sdmac = to_sdma_chan(chan);
  58381. + u32 residue;
  58382. +
  58383. + if (sdmac->mode & SDMA_MODE_LOOP)
  58384. + residue = (sdmac->num_bd - sdmac->buf_tail) * sdmac->period_len;
  58385. + else
  58386. + residue = sdmac->chn_count - sdmac->chn_real_count;
  58387. dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie,
  58388. - sdmac->chn_count - sdmac->chn_real_count);
  58389. + residue);
  58390. return sdmac->status;
  58391. }
  58392. @@ -1285,7 +1458,10 @@
  58393. goto err_firmware;
  58394. switch (header->version_major) {
  58395. case 1:
  58396. - sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
  58397. + if (header->version_minor > 0)
  58398. + sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
  58399. + else
  58400. + sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
  58401. break;
  58402. case 2:
  58403. sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
  58404. @@ -1331,7 +1507,7 @@
  58405. static int __init sdma_init(struct sdma_engine *sdma)
  58406. {
  58407. - int i, ret;
  58408. + int i, ret, ccbsize;
  58409. dma_addr_t ccb_phys;
  58410. clk_enable(sdma->clk_ipg);
  58411. @@ -1340,14 +1516,17 @@
  58412. /* Be sure SDMA has not started yet */
  58413. writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
  58414. - sdma->channel_control = dma_alloc_coherent(NULL,
  58415. - MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control) +
  58416. - sizeof(struct sdma_context_data),
  58417. - &ccb_phys, GFP_KERNEL);
  58418. + ccbsize = MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control)
  58419. + + sizeof(struct sdma_context_data);
  58420. + sdma->channel_control = gen_pool_dma_alloc(sdma->iram_pool, ccbsize, &ccb_phys);
  58421. if (!sdma->channel_control) {
  58422. - ret = -ENOMEM;
  58423. - goto err_dma_alloc;
  58424. + sdma->channel_control = dma_alloc_coherent(NULL, ccbsize,
  58425. + &ccb_phys, GFP_KERNEL);
  58426. + if (!sdma->channel_control) {
  58427. + ret = -ENOMEM;
  58428. + goto err_dma_alloc;
  58429. + }
  58430. }
  58431. sdma->context = (void *)sdma->channel_control +
  58432. @@ -1422,9 +1601,10 @@
  58433. if (dma_spec->args_count != 3)
  58434. return NULL;
  58435. - data.dma_request = dma_spec->args[0];
  58436. + data.dma_request0 = dma_spec->args[0];
  58437. data.peripheral_type = dma_spec->args[1];
  58438. data.priority = dma_spec->args[2];
  58439. + data.dma_request1 = 0;
  58440. return dma_request_channel(mask, sdma_filter_fn, &data);
  58441. }
  58442. @@ -1542,6 +1722,11 @@
  58443. &sdma->dma_device.channels);
  58444. }
  58445. + if (np)
  58446. + sdma->iram_pool = of_get_named_gen_pool(np, "iram", 0);
  58447. + if (!sdma->iram_pool)
  58448. + dev_warn(&pdev->dev, "no iram assigned, using external mem\n");
  58449. +
  58450. ret = sdma_init(sdma);
  58451. if (ret)
  58452. goto err_init;
  58453. diff -Nur linux-3.14.14/drivers/dma/Kconfig linux-imx6-3.14/drivers/dma/Kconfig
  58454. --- linux-3.14.14/drivers/dma/Kconfig 2014-07-28 10:07:25.000000000 -0500
  58455. +++ linux-imx6-3.14/drivers/dma/Kconfig 2014-12-08 00:31:52.564418001 -0600
  58456. @@ -137,6 +137,19 @@
  58457. To avoid bloating the irq_desc[] array we allocate a sufficient
  58458. number of IRQ slots and map them dynamically to specific sources.
  58459. +config MXC_PXP_V2
  58460. + bool "MXC PxP V2 support"
  58461. + depends on ARM
  58462. + select DMA_ENGINE
  58463. + help
  58464. + Support the PxP (Pixel Pipeline) on i.MX6 DualLite and i.MX6 SoloLite.
  58465. + If unsure, select N.
  58466. +
  58467. +config MXC_PXP_CLIENT_DEVICE
  58468. + bool "MXC PxP Client Device"
  58469. + default y
  58470. + depends on MXC_PXP_V2
  58471. +
  58472. config TXX9_DMAC
  58473. tristate "Toshiba TXx9 SoC DMA support"
  58474. depends on MACH_TX49XX || MACH_TX39XX
  58475. diff -Nur linux-3.14.14/drivers/dma/Makefile linux-imx6-3.14/drivers/dma/Makefile
  58476. --- linux-3.14.14/drivers/dma/Makefile 2014-07-28 10:07:25.000000000 -0500
  58477. +++ linux-imx6-3.14/drivers/dma/Makefile 2014-12-08 00:31:52.564418001 -0600
  58478. @@ -18,6 +18,7 @@
  58479. obj-$(CONFIG_DW_DMAC_CORE) += dw/
  58480. obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
  58481. obj-$(CONFIG_MX3_IPU) += ipu/
  58482. +obj-$(CONFIG_MXC_PXP_V2) += pxp/
  58483. obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
  58484. obj-$(CONFIG_SH_DMAE_BASE) += sh/
  58485. obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
  58486. diff -Nur linux-3.14.14/drivers/dma/pxp/Makefile linux-imx6-3.14/drivers/dma/pxp/Makefile
  58487. --- linux-3.14.14/drivers/dma/pxp/Makefile 1969-12-31 18:00:00.000000000 -0600
  58488. +++ linux-imx6-3.14/drivers/dma/pxp/Makefile 2014-12-08 00:31:52.572418001 -0600
  58489. @@ -0,0 +1,2 @@
  58490. +obj-$(CONFIG_MXC_PXP_V2) += pxp_dma_v2.o
  58491. +obj-$(CONFIG_MXC_PXP_CLIENT_DEVICE) += pxp_device.o
  58492. diff -Nur linux-3.14.14/drivers/dma/pxp/pxp_device.c linux-imx6-3.14/drivers/dma/pxp/pxp_device.c
  58493. --- linux-3.14.14/drivers/dma/pxp/pxp_device.c 1969-12-31 18:00:00.000000000 -0600
  58494. +++ linux-imx6-3.14/drivers/dma/pxp/pxp_device.c 2014-12-08 00:31:52.572418001 -0600
  58495. @@ -0,0 +1,765 @@
  58496. +/*
  58497. + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  58498. + *
  58499. + * This program is free software; you can redistribute it and/or modify
  58500. + * it under the terms of the GNU General Public License as published by
  58501. + * the Free Software Foundation; either version 2 of the License, or
  58502. + * (at your option) any later version.
  58503. + *
  58504. + * This program is distributed in the hope that it will be useful,
  58505. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  58506. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  58507. + * GNU General Public License for more details.
  58508. + *
  58509. + * You should have received a copy of the GNU General Public License
  58510. + * along with this program; if not, write to the Free Software
  58511. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  58512. + *
  58513. + */
  58514. +#include <linux/interrupt.h>
  58515. +#include <linux/miscdevice.h>
  58516. +#include <linux/platform_device.h>
  58517. +#include <linux/fs.h>
  58518. +#include <linux/slab.h>
  58519. +#include <linux/uaccess.h>
  58520. +#include <linux/delay.h>
  58521. +#include <linux/dmaengine.h>
  58522. +#include <linux/dma-mapping.h>
  58523. +#include <linux/sched.h>
  58524. +#include <linux/module.h>
  58525. +#include <linux/pxp_device.h>
  58526. +#include <linux/atomic.h>
  58527. +#include <linux/platform_data/dma-imx.h>
  58528. +
  58529. +#define BUFFER_HASH_ORDER 4
  58530. +
  58531. +static struct pxp_buffer_hash bufhash;
  58532. +static struct pxp_irq_info irq_info[NR_PXP_VIRT_CHANNEL];
  58533. +
  58534. +static int pxp_ht_create(struct pxp_buffer_hash *hash, int order)
  58535. +{
  58536. + unsigned long i;
  58537. + unsigned long table_size;
  58538. +
  58539. + table_size = 1U << order;
  58540. +
  58541. + hash->order = order;
  58542. + hash->hash_table = kmalloc(sizeof(*hash->hash_table) * table_size, GFP_KERNEL);
  58543. +
  58544. + if (!hash->hash_table) {
  58545. + pr_err("%s: Out of memory for hash table\n", __func__);
  58546. + return -ENOMEM;
  58547. + }
  58548. +
  58549. + for (i = 0; i < table_size; i++)
  58550. + INIT_HLIST_HEAD(&hash->hash_table[i]);
  58551. +
  58552. + return 0;
  58553. +}
  58554. +
  58555. +static int pxp_ht_insert_item(struct pxp_buffer_hash *hash,
  58556. + struct pxp_buf_obj *new)
  58557. +{
  58558. + unsigned long hashkey;
  58559. + struct hlist_head *h_list;
  58560. +
  58561. + hashkey = hash_long(new->offset >> PAGE_SHIFT, hash->order);
  58562. + h_list = &hash->hash_table[hashkey];
  58563. +
  58564. + spin_lock(&hash->hash_lock);
  58565. + hlist_add_head_rcu(&new->item, h_list);
  58566. + spin_unlock(&hash->hash_lock);
  58567. +
  58568. + return 0;
  58569. +}
  58570. +
  58571. +static int pxp_ht_remove_item(struct pxp_buffer_hash *hash,
  58572. + struct pxp_buf_obj *obj)
  58573. +{
  58574. + spin_lock(&hash->hash_lock);
  58575. + hlist_del_init_rcu(&obj->item);
  58576. + spin_unlock(&hash->hash_lock);
  58577. + return 0;
  58578. +}
  58579. +
  58580. +static struct hlist_node *pxp_ht_find_key(struct pxp_buffer_hash *hash,
  58581. + unsigned long key)
  58582. +{
  58583. + struct pxp_buf_obj *entry;
  58584. + struct hlist_head *h_list;
  58585. + unsigned long hashkey;
  58586. +
  58587. + hashkey = hash_long(key, hash->order);
  58588. + h_list = &hash->hash_table[hashkey];
  58589. +
  58590. + hlist_for_each_entry_rcu(entry, h_list, item) {
  58591. + if (entry->offset >> PAGE_SHIFT == key)
  58592. + return &entry->item;
  58593. + }
  58594. +
  58595. + return NULL;
  58596. +}
  58597. +
  58598. +static void pxp_ht_destroy(struct pxp_buffer_hash *hash)
  58599. +{
  58600. + kfree(hash->hash_table);
  58601. + hash->hash_table = NULL;
  58602. +}
  58603. +
  58604. +static int pxp_buffer_handle_create(struct pxp_file *file_priv,
  58605. + struct pxp_buf_obj *obj,
  58606. + uint32_t *handlep)
  58607. +{
  58608. + int ret;
  58609. +
  58610. + idr_preload(GFP_KERNEL);
  58611. + spin_lock(&file_priv->buffer_lock);
  58612. +
  58613. + ret = idr_alloc(&file_priv->buffer_idr, obj, 1, 0, GFP_NOWAIT);
  58614. +
  58615. + spin_unlock(&file_priv->buffer_lock);
  58616. + idr_preload_end();
  58617. +
  58618. + if (ret < 0)
  58619. + return ret;
  58620. +
  58621. + *handlep = ret;
  58622. +
  58623. + return 0;
  58624. +}
  58625. +
  58626. +static struct pxp_buf_obj *
  58627. +pxp_buffer_object_lookup(struct pxp_file *file_priv,
  58628. + uint32_t handle)
  58629. +{
  58630. + struct pxp_buf_obj *obj;
  58631. +
  58632. + spin_lock(&file_priv->buffer_lock);
  58633. +
  58634. + obj = idr_find(&file_priv->buffer_idr, handle);
  58635. + if (!obj) {
  58636. + spin_unlock(&file_priv->buffer_lock);
  58637. + return NULL;
  58638. + }
  58639. +
  58640. + spin_unlock(&file_priv->buffer_lock);
  58641. +
  58642. + return obj;
  58643. +}
  58644. +
  58645. +static int pxp_buffer_handle_delete(struct pxp_file *file_priv,
  58646. + uint32_t handle)
  58647. +{
  58648. + struct pxp_buf_obj *obj;
  58649. +
  58650. + spin_lock(&file_priv->buffer_lock);
  58651. +
  58652. + obj = idr_find(&file_priv->buffer_idr, handle);
  58653. + if (!obj) {
  58654. + spin_unlock(&file_priv->buffer_lock);
  58655. + return -EINVAL;
  58656. + }
  58657. +
  58658. + idr_remove(&file_priv->buffer_idr, handle);
  58659. + spin_unlock(&file_priv->buffer_lock);
  58660. +
  58661. + return 0;
  58662. +}
  58663. +
  58664. +static int pxp_channel_handle_create(struct pxp_file *file_priv,
  58665. + struct pxp_chan_obj *obj,
  58666. + uint32_t *handlep)
  58667. +{
  58668. + int ret;
  58669. +
  58670. + idr_preload(GFP_KERNEL);
  58671. + spin_lock(&file_priv->channel_lock);
  58672. +
  58673. + ret = idr_alloc(&file_priv->channel_idr, obj, 0, 0, GFP_NOWAIT);
  58674. +
  58675. + spin_unlock(&file_priv->channel_lock);
  58676. + idr_preload_end();
  58677. +
  58678. + if (ret < 0)
  58679. + return ret;
  58680. +
  58681. + *handlep = ret;
  58682. +
  58683. + return 0;
  58684. +}
  58685. +
  58686. +static struct pxp_chan_obj *
  58687. +pxp_channel_object_lookup(struct pxp_file *file_priv,
  58688. + uint32_t handle)
  58689. +{
  58690. + struct pxp_chan_obj *obj;
  58691. +
  58692. + spin_lock(&file_priv->channel_lock);
  58693. +
  58694. + obj = idr_find(&file_priv->channel_idr, handle);
  58695. + if (!obj) {
  58696. + spin_unlock(&file_priv->channel_lock);
  58697. + return NULL;
  58698. + }
  58699. +
  58700. + spin_unlock(&file_priv->channel_lock);
  58701. +
  58702. + return obj;
  58703. +}
  58704. +
  58705. +static int pxp_channel_handle_delete(struct pxp_file *file_priv,
  58706. + uint32_t handle)
  58707. +{
  58708. + struct pxp_chan_obj *obj;
  58709. +
  58710. + spin_lock(&file_priv->channel_lock);
  58711. +
  58712. + obj = idr_find(&file_priv->channel_idr, handle);
  58713. + if (!obj) {
  58714. + spin_unlock(&file_priv->channel_lock);
  58715. + return -EINVAL;
  58716. + }
  58717. +
  58718. + idr_remove(&file_priv->channel_idr, handle);
  58719. + spin_unlock(&file_priv->channel_lock);
  58720. +
  58721. + return 0;
  58722. +}
  58723. +
  58724. +static int pxp_alloc_dma_buffer(struct pxp_buf_obj *obj)
  58725. +{
  58726. + obj->virtual = dma_alloc_coherent(NULL, PAGE_ALIGN(obj->size),
  58727. + (dma_addr_t *) (&obj->offset),
  58728. + GFP_DMA | GFP_KERNEL);
  58729. + pr_debug("[ALLOC] mem alloc phys_addr = 0x%lx\n", obj->offset);
  58730. +
  58731. + if (obj->virtual == NULL) {
  58732. + printk(KERN_ERR "Physical memory allocation error!\n");
  58733. + return -1;
  58734. + }
  58735. +
  58736. + return 0;
  58737. +}
  58738. +
  58739. +static void pxp_free_dma_buffer(struct pxp_buf_obj *obj)
  58740. +{
  58741. + if (obj->virtual != NULL) {
  58742. + dma_free_coherent(0, PAGE_ALIGN(obj->size),
  58743. + obj->virtual, (dma_addr_t)obj->offset);
  58744. + }
  58745. +}
  58746. +
  58747. +static int
  58748. +pxp_buffer_object_free(int id, void *ptr, void *data)
  58749. +{
  58750. + struct pxp_file *file_priv = data;
  58751. + struct pxp_buf_obj *obj = ptr;
  58752. + int ret;
  58753. +
  58754. + ret = pxp_buffer_handle_delete(file_priv, obj->handle);
  58755. + if (ret < 0)
  58756. + return ret;
  58757. +
  58758. + pxp_ht_remove_item(&bufhash, obj);
  58759. + pxp_free_dma_buffer(obj);
  58760. + kfree(obj);
  58761. +
  58762. + return 0;
  58763. +}
  58764. +
  58765. +static int
  58766. +pxp_channel_object_free(int id, void *ptr, void *data)
  58767. +{
  58768. + struct pxp_file *file_priv = data;
  58769. + struct pxp_chan_obj *obj = ptr;
  58770. + int chan_id;
  58771. +
  58772. + chan_id = obj->chan->chan_id;
  58773. + wait_event(irq_info[chan_id].waitq,
  58774. + atomic_read(&irq_info[chan_id].irq_pending) == 0);
  58775. +
  58776. + pxp_channel_handle_delete(file_priv, obj->handle);
  58777. + dma_release_channel(obj->chan);
  58778. + kfree(obj);
  58779. +
  58780. + return 0;
  58781. +}
  58782. +
  58783. +static void pxp_free_buffers(struct pxp_file *file_priv)
  58784. +{
  58785. + idr_for_each(&file_priv->buffer_idr,
  58786. + &pxp_buffer_object_free, file_priv);
  58787. + idr_destroy(&file_priv->buffer_idr);
  58788. +}
  58789. +
  58790. +static void pxp_free_channels(struct pxp_file *file_priv)
  58791. +{
  58792. + idr_for_each(&file_priv->channel_idr,
  58793. + &pxp_channel_object_free, file_priv);
  58794. + idr_destroy(&file_priv->channel_idr);
  58795. +}
  58796. +
  58797. +/* Callback function triggered after PxP receives an EOF interrupt */
  58798. +static void pxp_dma_done(void *arg)
  58799. +{
  58800. + struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
  58801. + struct dma_chan *chan = tx_desc->txd.chan;
  58802. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  58803. + int chan_id = pxp_chan->dma_chan.chan_id;
  58804. +
  58805. + pr_debug("DMA Done ISR, chan_id %d\n", chan_id);
  58806. +
  58807. + atomic_dec(&irq_info[chan_id].irq_pending);
  58808. + irq_info[chan_id].hist_status = tx_desc->hist_status;
  58809. +
  58810. + wake_up(&(irq_info[chan_id].waitq));
  58811. +}
  58812. +
  58813. +static int pxp_ioc_config_chan(struct pxp_file *priv, unsigned long arg)
  58814. +{
  58815. + struct scatterlist sg[3];
  58816. + struct pxp_tx_desc *desc;
  58817. + struct dma_async_tx_descriptor *txd;
  58818. + struct pxp_config_data pxp_conf;
  58819. + dma_cookie_t cookie;
  58820. + int handle, chan_id;
  58821. + int i, length, ret;
  58822. + struct dma_chan *chan;
  58823. + struct pxp_chan_obj *obj;
  58824. +
  58825. + ret = copy_from_user(&pxp_conf,
  58826. + (struct pxp_config_data *)arg,
  58827. + sizeof(struct pxp_config_data));
  58828. + if (ret)
  58829. + return -EFAULT;
  58830. +
  58831. + handle = pxp_conf.handle;
  58832. + obj = pxp_channel_object_lookup(priv, handle);
  58833. + if (!obj)
  58834. + return -EINVAL;
  58835. + chan = obj->chan;
  58836. + chan_id = chan->chan_id;
  58837. +
  58838. + sg_init_table(sg, 3);
  58839. +
  58840. + txd = chan->device->device_prep_slave_sg(chan,
  58841. + sg, 3,
  58842. + DMA_TO_DEVICE,
  58843. + DMA_PREP_INTERRUPT,
  58844. + NULL);
  58845. + if (!txd) {
  58846. + pr_err("Error preparing a DMA transaction descriptor.\n");
  58847. + return -EIO;
  58848. + }
  58849. +
  58850. + txd->callback_param = txd;
  58851. + txd->callback = pxp_dma_done;
  58852. +
  58853. + desc = to_tx_desc(txd);
  58854. +
  58855. + length = desc->len;
  58856. + for (i = 0; i < length; i++) {
  58857. + if (i == 0) { /* S0 */
  58858. + memcpy(&desc->proc_data,
  58859. + &pxp_conf.proc_data,
  58860. + sizeof(struct pxp_proc_data));
  58861. + memcpy(&desc->layer_param.s0_param,
  58862. + &pxp_conf.s0_param,
  58863. + sizeof(struct pxp_layer_param));
  58864. + } else if (i == 1) { /* Output */
  58865. + memcpy(&desc->layer_param.out_param,
  58866. + &pxp_conf.out_param,
  58867. + sizeof(struct pxp_layer_param));
  58868. + } else {
  58869. + /* OverLay */
  58870. + memcpy(&desc->layer_param.ol_param,
  58871. + &pxp_conf.ol_param,
  58872. + sizeof(struct pxp_layer_param));
  58873. + }
  58874. +
  58875. + desc = desc->next;
  58876. + }
  58877. +
  58878. + cookie = txd->tx_submit(txd);
  58879. + if (cookie < 0) {
  58880. + pr_err("Error tx_submit\n");
  58881. + return -EIO;
  58882. + }
  58883. +
  58884. + atomic_inc(&irq_info[chan_id].irq_pending);
  58885. +
  58886. + return 0;
  58887. +}
  58888. +
  58889. +static int pxp_device_open(struct inode *inode, struct file *filp)
  58890. +{
  58891. + struct pxp_file *priv;
  58892. +
  58893. + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  58894. +
  58895. + if (!priv)
  58896. + return -ENOMEM;
  58897. +
  58898. + filp->private_data = priv;
  58899. + priv->filp = filp;
  58900. +
  58901. + idr_init(&priv->buffer_idr);
  58902. + spin_lock_init(&priv->buffer_lock);
  58903. +
  58904. + idr_init(&priv->channel_idr);
  58905. + spin_lock_init(&priv->channel_lock);
  58906. +
  58907. + return 0;
  58908. +}
  58909. +
  58910. +static int pxp_device_release(struct inode *inode, struct file *filp)
  58911. +{
  58912. + struct pxp_file *priv = filp->private_data;
  58913. +
  58914. + if (priv) {
  58915. + pxp_free_channels(priv);
  58916. + pxp_free_buffers(priv);
  58917. + kfree(priv);
  58918. + filp->private_data = NULL;
  58919. + }
  58920. +
  58921. + return 0;
  58922. +}
  58923. +
  58924. +static int pxp_device_mmap(struct file *file, struct vm_area_struct *vma)
  58925. +{
  58926. + int request_size;
  58927. + struct hlist_node *node;
  58928. + struct pxp_buf_obj *obj;
  58929. +
  58930. + request_size = vma->vm_end - vma->vm_start;
  58931. +
  58932. + pr_debug("start=0x%x, pgoff=0x%x, size=0x%x\n",
  58933. + (unsigned int)(vma->vm_start), (unsigned int)(vma->vm_pgoff),
  58934. + request_size);
  58935. +
  58936. + node = pxp_ht_find_key(&bufhash, vma->vm_pgoff);
  58937. + if (!node)
  58938. + return -EINVAL;
  58939. +
  58940. + obj = list_entry(node, struct pxp_buf_obj, item);
  58941. + if (obj->offset + (obj->size >> PAGE_SHIFT) <
  58942. + (vma->vm_pgoff + vma_pages(vma)))
  58943. + return -ENOMEM;
  58944. +
  58945. + switch (obj->mem_type) {
  58946. + case MEMORY_TYPE_UNCACHED:
  58947. + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  58948. + break;
  58949. + case MEMORY_TYPE_WC:
  58950. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  58951. + break;
  58952. + case MEMORY_TYPE_CACHED:
  58953. + break;
  58954. + default:
  58955. + pr_err("%s: invalid memory type!\n", __func__);
  58956. + return -EINVAL;
  58957. + }
  58958. +
  58959. + return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  58960. + request_size, vma->vm_page_prot) ? -EAGAIN : 0;
  58961. +}
  58962. +
  58963. +static bool chan_filter(struct dma_chan *chan, void *arg)
  58964. +{
  58965. + if (imx_dma_is_pxp(chan))
  58966. + return true;
  58967. + else
  58968. + return false;
  58969. +}
  58970. +
  58971. +static long pxp_device_ioctl(struct file *filp,
  58972. + unsigned int cmd, unsigned long arg)
  58973. +{
  58974. + int ret = 0;
  58975. + struct pxp_file *file_priv = filp->private_data;
  58976. +
  58977. + switch (cmd) {
  58978. + case PXP_IOC_GET_CHAN:
  58979. + {
  58980. + int ret;
  58981. + struct dma_chan *chan = NULL;
  58982. + dma_cap_mask_t mask;
  58983. + struct pxp_chan_obj *obj = NULL;
  58984. +
  58985. + pr_debug("drv: PXP_IOC_GET_CHAN Line %d\n", __LINE__);
  58986. +
  58987. + dma_cap_zero(mask);
  58988. + dma_cap_set(DMA_SLAVE, mask);
  58989. + dma_cap_set(DMA_PRIVATE, mask);
  58990. +
  58991. + chan = dma_request_channel(mask, chan_filter, NULL);
  58992. + if (!chan) {
  58993. + pr_err("Unsccessfully received channel!\n");
  58994. + return -EBUSY;
  58995. + }
  58996. +
  58997. + pr_debug("Successfully received channel."
  58998. + "chan_id %d\n", chan->chan_id);
  58999. +
  59000. + obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  59001. + if (!obj) {
  59002. + dma_release_channel(chan);
  59003. + return -ENOMEM;
  59004. + }
  59005. + obj->chan = chan;
  59006. +
  59007. + ret = pxp_channel_handle_create(file_priv, obj,
  59008. + &obj->handle);
  59009. + if (ret) {
  59010. + dma_release_channel(chan);
  59011. + kfree(obj);
  59012. + return ret;
  59013. + }
  59014. +
  59015. + init_waitqueue_head(&(irq_info[chan->chan_id].waitq));
  59016. + if (put_user(obj->handle, (u32 __user *) arg)) {
  59017. + pxp_channel_handle_delete(file_priv, obj->handle);
  59018. + dma_release_channel(chan);
  59019. + kfree(obj);
  59020. + return -EFAULT;
  59021. + }
  59022. +
  59023. + break;
  59024. + }
  59025. + case PXP_IOC_PUT_CHAN:
  59026. + {
  59027. + int handle;
  59028. + struct pxp_chan_obj *obj;
  59029. +
  59030. + if (get_user(handle, (u32 __user *) arg))
  59031. + return -EFAULT;
  59032. +
  59033. + pr_debug("%d release handle %d\n", __LINE__, handle);
  59034. +
  59035. + obj = pxp_channel_object_lookup(file_priv, handle);
  59036. + if (!obj)
  59037. + return -EINVAL;
  59038. +
  59039. + pxp_channel_handle_delete(file_priv, obj->handle);
  59040. + dma_release_channel(obj->chan);
  59041. + kfree(obj);
  59042. +
  59043. + break;
  59044. + }
  59045. + case PXP_IOC_CONFIG_CHAN:
  59046. + {
  59047. + int ret;
  59048. +
  59049. + ret = pxp_ioc_config_chan(file_priv, arg);
  59050. + if (ret)
  59051. + return ret;
  59052. +
  59053. + break;
  59054. + }
  59055. + case PXP_IOC_START_CHAN:
  59056. + {
  59057. + int handle;
  59058. + struct pxp_chan_obj *obj = NULL;
  59059. +
  59060. + if (get_user(handle, (u32 __user *) arg))
  59061. + return -EFAULT;
  59062. +
  59063. + obj = pxp_channel_object_lookup(file_priv, handle);
  59064. + if (!obj)
  59065. + return -EINVAL;
  59066. +
  59067. + dma_async_issue_pending(obj->chan);
  59068. +
  59069. + break;
  59070. + }
  59071. + case PXP_IOC_GET_PHYMEM:
  59072. + {
  59073. + struct pxp_mem_desc buffer;
  59074. + struct pxp_buf_obj *obj;
  59075. +
  59076. + ret = copy_from_user(&buffer,
  59077. + (struct pxp_mem_desc *)arg,
  59078. + sizeof(struct pxp_mem_desc));
  59079. + if (ret)
  59080. + return -EFAULT;
  59081. +
  59082. + pr_debug("[ALLOC] mem alloc size = 0x%x\n",
  59083. + buffer.size);
  59084. +
  59085. + obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  59086. + if (!obj)
  59087. + return -ENOMEM;
  59088. + obj->size = buffer.size;
  59089. + obj->mem_type = buffer.mtype;
  59090. +
  59091. + ret = pxp_alloc_dma_buffer(obj);
  59092. + if (ret == -1) {
  59093. + printk(KERN_ERR
  59094. + "Physical memory allocation error!\n");
  59095. + kfree(obj);
  59096. + return ret;
  59097. + }
  59098. +
  59099. + ret = pxp_buffer_handle_create(file_priv, obj, &obj->handle);
  59100. + if (ret) {
  59101. + pxp_free_dma_buffer(obj);
  59102. + kfree(obj);
  59103. + return ret;
  59104. + }
  59105. + buffer.handle = obj->handle;
  59106. + buffer.phys_addr = obj->offset;
  59107. +
  59108. + ret = copy_to_user((void __user *)arg, &buffer,
  59109. + sizeof(struct pxp_mem_desc));
  59110. + if (ret) {
  59111. + pxp_buffer_handle_delete(file_priv, buffer.handle);
  59112. + pxp_free_dma_buffer(obj);
  59113. + kfree(obj);
  59114. + return -EFAULT;
  59115. + }
  59116. +
  59117. + pxp_ht_insert_item(&bufhash, obj);
  59118. +
  59119. + break;
  59120. + }
  59121. + case PXP_IOC_PUT_PHYMEM:
  59122. + {
  59123. + struct pxp_mem_desc pxp_mem;
  59124. + struct pxp_buf_obj *obj;
  59125. +
  59126. + ret = copy_from_user(&pxp_mem,
  59127. + (struct pxp_mem_desc *)arg,
  59128. + sizeof(struct pxp_mem_desc));
  59129. + if (ret)
  59130. + return -EACCES;
  59131. +
  59132. + obj = pxp_buffer_object_lookup(file_priv, pxp_mem.handle);
  59133. + if (!obj)
  59134. + return -EINVAL;
  59135. +
  59136. + ret = pxp_buffer_handle_delete(file_priv, obj->handle);
  59137. + if (ret)
  59138. + return ret;
  59139. +
  59140. + pxp_ht_remove_item(&bufhash, obj);
  59141. + pxp_free_dma_buffer(obj);
  59142. + kfree(obj);
  59143. +
  59144. + break;
  59145. + }
  59146. + case PXP_IOC_FLUSH_PHYMEM:
  59147. + {
  59148. + int ret;
  59149. + struct pxp_mem_flush flush;
  59150. + struct pxp_buf_obj *obj;
  59151. +
  59152. + ret = copy_from_user(&flush,
  59153. + (struct pxp_mem_flush *)arg,
  59154. + sizeof(struct pxp_mem_flush));
  59155. + if (ret)
  59156. + return -EACCES;
  59157. +
  59158. + obj = pxp_buffer_object_lookup(file_priv, flush.handle);
  59159. + if (!obj)
  59160. + return -EINVAL;
  59161. +
  59162. + switch (flush.type) {
  59163. + case CACHE_CLEAN:
  59164. + dma_sync_single_for_device(NULL, obj->offset,
  59165. + obj->size, DMA_TO_DEVICE);
  59166. + break;
  59167. + case CACHE_INVALIDATE:
  59168. + dma_sync_single_for_device(NULL, obj->offset,
  59169. + obj->size, DMA_FROM_DEVICE);
  59170. + break;
  59171. + case CACHE_FLUSH:
  59172. + dma_sync_single_for_device(NULL, obj->offset,
  59173. + obj->size, DMA_TO_DEVICE);
  59174. + dma_sync_single_for_device(NULL, obj->offset,
  59175. + obj->size, DMA_FROM_DEVICE);
  59176. + break;
  59177. + default:
  59178. + pr_err("%s: invalid cache flush type\n", __func__);
  59179. + return -EINVAL;
  59180. + }
  59181. +
  59182. + break;
  59183. + }
  59184. + case PXP_IOC_WAIT4CMPLT:
  59185. + {
  59186. + struct pxp_chan_handle chan_handle;
  59187. + int ret, chan_id, handle;
  59188. + struct pxp_chan_obj *obj = NULL;
  59189. +
  59190. + ret = copy_from_user(&chan_handle,
  59191. + (struct pxp_chan_handle *)arg,
  59192. + sizeof(struct pxp_chan_handle));
  59193. + if (ret)
  59194. + return -EFAULT;
  59195. +
  59196. + handle = chan_handle.handle;
  59197. + obj = pxp_channel_object_lookup(file_priv, handle);
  59198. + if (!obj)
  59199. + return -EINVAL;
  59200. + chan_id = obj->chan->chan_id;
  59201. +
  59202. + ret = wait_event_interruptible
  59203. + (irq_info[chan_id].waitq,
  59204. + (atomic_read(&irq_info[chan_id].irq_pending) == 0));
  59205. + if (ret < 0) {
  59206. + printk(KERN_WARNING
  59207. + "WAIT4CMPLT: signal received.\n");
  59208. + return -ERESTARTSYS;
  59209. + }
  59210. +
  59211. + chan_handle.hist_status = irq_info[chan_id].hist_status;
  59212. + ret = copy_to_user((struct pxp_chan_handle *)arg,
  59213. + &chan_handle,
  59214. + sizeof(struct pxp_chan_handle));
  59215. + if (ret)
  59216. + return -EFAULT;
  59217. + break;
  59218. + }
  59219. + default:
  59220. + break;
  59221. + }
  59222. +
  59223. + return 0;
  59224. +}
  59225. +
  59226. +static const struct file_operations pxp_device_fops = {
  59227. + .open = pxp_device_open,
  59228. + .release = pxp_device_release,
  59229. + .unlocked_ioctl = pxp_device_ioctl,
  59230. + .mmap = pxp_device_mmap,
  59231. +};
  59232. +
  59233. +static struct miscdevice pxp_device_miscdev = {
  59234. + .minor = MISC_DYNAMIC_MINOR,
  59235. + .name = "pxp_device",
  59236. + .fops = &pxp_device_fops,
  59237. +};
  59238. +
  59239. +int register_pxp_device(void)
  59240. +{
  59241. + int ret;
  59242. +
  59243. + ret = misc_register(&pxp_device_miscdev);
  59244. + if (ret)
  59245. + return ret;
  59246. +
  59247. + ret = pxp_ht_create(&bufhash, BUFFER_HASH_ORDER);
  59248. + if (ret)
  59249. + return ret;
  59250. + spin_lock_init(&(bufhash.hash_lock));
  59251. +
  59252. + pr_debug("PxP_Device registered Successfully\n");
  59253. + return 0;
  59254. +}
  59255. +
  59256. +void unregister_pxp_device(void)
  59257. +{
  59258. + pxp_ht_destroy(&bufhash);
  59259. + misc_deregister(&pxp_device_miscdev);
  59260. +}
  59261. diff -Nur linux-3.14.14/drivers/dma/pxp/pxp_dma_v2.c linux-imx6-3.14/drivers/dma/pxp/pxp_dma_v2.c
  59262. --- linux-3.14.14/drivers/dma/pxp/pxp_dma_v2.c 1969-12-31 18:00:00.000000000 -0600
  59263. +++ linux-imx6-3.14/drivers/dma/pxp/pxp_dma_v2.c 2014-12-08 00:31:52.576418001 -0600
  59264. @@ -0,0 +1,1854 @@
  59265. +/*
  59266. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
  59267. + *
  59268. + * This program is free software; you can redistribute it and/or modify
  59269. + * it under the terms of the GNU General Public License as published by
  59270. + * the Free Software Foundation; either version 2 of the License, or
  59271. + * (at your option) any later version.
  59272. + *
  59273. + * This program is distributed in the hope that it will be useful,
  59274. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  59275. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  59276. + * GNU General Public License for more details.
  59277. + *
  59278. + * You should have received a copy of the GNU General Public License
  59279. + * along with this program; if not, write to the Free Software
  59280. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  59281. + *
  59282. + */
  59283. +/*
  59284. + * Based on STMP378X PxP driver
  59285. + * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
  59286. + */
  59287. +
  59288. +#include <linux/dma-mapping.h>
  59289. +#include <linux/init.h>
  59290. +#include <linux/interrupt.h>
  59291. +#include <linux/io.h>
  59292. +#include <linux/kernel.h>
  59293. +#include <linux/module.h>
  59294. +#include <linux/mutex.h>
  59295. +#include <linux/platform_device.h>
  59296. +#include <linux/slab.h>
  59297. +#include <linux/vmalloc.h>
  59298. +#include <linux/dmaengine.h>
  59299. +#include <linux/pxp_dma.h>
  59300. +#include <linux/timer.h>
  59301. +#include <linux/clk.h>
  59302. +#include <linux/workqueue.h>
  59303. +#include <linux/sched.h>
  59304. +#include <linux/of.h>
  59305. +#include <linux/kthread.h>
  59306. +
  59307. +#include "regs-pxp_v2.h"
  59308. +
  59309. +#define PXP_DOWNSCALE_THRESHOLD 0x4000
  59310. +
  59311. +static LIST_HEAD(head);
  59312. +static int timeout_in_ms = 600;
  59313. +static unsigned int block_size;
  59314. +static struct kmem_cache *tx_desc_cache;
  59315. +
  59316. +struct pxp_dma {
  59317. + struct dma_device dma;
  59318. +};
  59319. +
  59320. +struct pxps {
  59321. + struct platform_device *pdev;
  59322. + struct clk *clk;
  59323. + void __iomem *base;
  59324. + int irq; /* PXP IRQ to the CPU */
  59325. +
  59326. + spinlock_t lock;
  59327. + struct mutex clk_mutex;
  59328. + int clk_stat;
  59329. +#define CLK_STAT_OFF 0
  59330. +#define CLK_STAT_ON 1
  59331. + int pxp_ongoing;
  59332. + int lut_state;
  59333. +
  59334. + struct device *dev;
  59335. + struct pxp_dma pxp_dma;
  59336. + struct pxp_channel channel[NR_PXP_VIRT_CHANNEL];
  59337. + struct work_struct work;
  59338. +
  59339. + /* describes most recent processing configuration */
  59340. + struct pxp_config_data pxp_conf_state;
  59341. +
  59342. + /* to turn clock off when pxp is inactive */
  59343. + struct timer_list clk_timer;
  59344. +
  59345. + /* for pxp config dispatch asynchronously*/
  59346. + struct task_struct *dispatch;
  59347. + wait_queue_head_t thread_waitq;
  59348. + struct completion complete;
  59349. +};
  59350. +
  59351. +#define to_pxp_dma(d) container_of(d, struct pxp_dma, dma)
  59352. +#define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
  59353. +#define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
  59354. +#define to_pxp(id) container_of(id, struct pxps, pxp_dma)
  59355. +
  59356. +#define PXP_DEF_BUFS 2
  59357. +#define PXP_MIN_PIX 8
  59358. +
  59359. +static uint32_t pxp_s0_formats[] = {
  59360. + PXP_PIX_FMT_RGB32,
  59361. + PXP_PIX_FMT_RGB565,
  59362. + PXP_PIX_FMT_RGB555,
  59363. + PXP_PIX_FMT_YUV420P,
  59364. + PXP_PIX_FMT_YUV422P,
  59365. +};
  59366. +
  59367. +/*
  59368. + * PXP common functions
  59369. + */
  59370. +static void dump_pxp_reg(struct pxps *pxp)
  59371. +{
  59372. + dev_dbg(pxp->dev, "PXP_CTRL 0x%x",
  59373. + __raw_readl(pxp->base + HW_PXP_CTRL));
  59374. + dev_dbg(pxp->dev, "PXP_STAT 0x%x",
  59375. + __raw_readl(pxp->base + HW_PXP_STAT));
  59376. + dev_dbg(pxp->dev, "PXP_OUT_CTRL 0x%x",
  59377. + __raw_readl(pxp->base + HW_PXP_OUT_CTRL));
  59378. + dev_dbg(pxp->dev, "PXP_OUT_BUF 0x%x",
  59379. + __raw_readl(pxp->base + HW_PXP_OUT_BUF));
  59380. + dev_dbg(pxp->dev, "PXP_OUT_BUF2 0x%x",
  59381. + __raw_readl(pxp->base + HW_PXP_OUT_BUF2));
  59382. + dev_dbg(pxp->dev, "PXP_OUT_PITCH 0x%x",
  59383. + __raw_readl(pxp->base + HW_PXP_OUT_PITCH));
  59384. + dev_dbg(pxp->dev, "PXP_OUT_LRC 0x%x",
  59385. + __raw_readl(pxp->base + HW_PXP_OUT_LRC));
  59386. + dev_dbg(pxp->dev, "PXP_OUT_PS_ULC 0x%x",
  59387. + __raw_readl(pxp->base + HW_PXP_OUT_PS_ULC));
  59388. + dev_dbg(pxp->dev, "PXP_OUT_PS_LRC 0x%x",
  59389. + __raw_readl(pxp->base + HW_PXP_OUT_PS_LRC));
  59390. + dev_dbg(pxp->dev, "PXP_OUT_AS_ULC 0x%x",
  59391. + __raw_readl(pxp->base + HW_PXP_OUT_AS_ULC));
  59392. + dev_dbg(pxp->dev, "PXP_OUT_AS_LRC 0x%x",
  59393. + __raw_readl(pxp->base + HW_PXP_OUT_AS_LRC));
  59394. + dev_dbg(pxp->dev, "PXP_PS_CTRL 0x%x",
  59395. + __raw_readl(pxp->base + HW_PXP_PS_CTRL));
  59396. + dev_dbg(pxp->dev, "PXP_PS_BUF 0x%x",
  59397. + __raw_readl(pxp->base + HW_PXP_PS_BUF));
  59398. + dev_dbg(pxp->dev, "PXP_PS_UBUF 0x%x",
  59399. + __raw_readl(pxp->base + HW_PXP_PS_UBUF));
  59400. + dev_dbg(pxp->dev, "PXP_PS_VBUF 0x%x",
  59401. + __raw_readl(pxp->base + HW_PXP_PS_VBUF));
  59402. + dev_dbg(pxp->dev, "PXP_PS_PITCH 0x%x",
  59403. + __raw_readl(pxp->base + HW_PXP_PS_PITCH));
  59404. + dev_dbg(pxp->dev, "PXP_PS_BACKGROUND 0x%x",
  59405. + __raw_readl(pxp->base + HW_PXP_PS_BACKGROUND));
  59406. + dev_dbg(pxp->dev, "PXP_PS_SCALE 0x%x",
  59407. + __raw_readl(pxp->base + HW_PXP_PS_SCALE));
  59408. + dev_dbg(pxp->dev, "PXP_PS_OFFSET 0x%x",
  59409. + __raw_readl(pxp->base + HW_PXP_PS_OFFSET));
  59410. + dev_dbg(pxp->dev, "PXP_PS_CLRKEYLOW 0x%x",
  59411. + __raw_readl(pxp->base + HW_PXP_PS_CLRKEYLOW));
  59412. + dev_dbg(pxp->dev, "PXP_PS_CLRKEYHIGH 0x%x",
  59413. + __raw_readl(pxp->base + HW_PXP_PS_CLRKEYHIGH));
  59414. + dev_dbg(pxp->dev, "PXP_AS_CTRL 0x%x",
  59415. + __raw_readl(pxp->base + HW_PXP_AS_CTRL));
  59416. + dev_dbg(pxp->dev, "PXP_AS_BUF 0x%x",
  59417. + __raw_readl(pxp->base + HW_PXP_AS_BUF));
  59418. + dev_dbg(pxp->dev, "PXP_AS_PITCH 0x%x",
  59419. + __raw_readl(pxp->base + HW_PXP_AS_PITCH));
  59420. + dev_dbg(pxp->dev, "PXP_AS_CLRKEYLOW 0x%x",
  59421. + __raw_readl(pxp->base + HW_PXP_AS_CLRKEYLOW));
  59422. + dev_dbg(pxp->dev, "PXP_AS_CLRKEYHIGH 0x%x",
  59423. + __raw_readl(pxp->base + HW_PXP_AS_CLRKEYHIGH));
  59424. + dev_dbg(pxp->dev, "PXP_CSC1_COEF0 0x%x",
  59425. + __raw_readl(pxp->base + HW_PXP_CSC1_COEF0));
  59426. + dev_dbg(pxp->dev, "PXP_CSC1_COEF1 0x%x",
  59427. + __raw_readl(pxp->base + HW_PXP_CSC1_COEF1));
  59428. + dev_dbg(pxp->dev, "PXP_CSC1_COEF2 0x%x",
  59429. + __raw_readl(pxp->base + HW_PXP_CSC1_COEF2));
  59430. + dev_dbg(pxp->dev, "PXP_CSC2_CTRL 0x%x",
  59431. + __raw_readl(pxp->base + HW_PXP_CSC2_CTRL));
  59432. + dev_dbg(pxp->dev, "PXP_CSC2_COEF0 0x%x",
  59433. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF0));
  59434. + dev_dbg(pxp->dev, "PXP_CSC2_COEF1 0x%x",
  59435. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF1));
  59436. + dev_dbg(pxp->dev, "PXP_CSC2_COEF2 0x%x",
  59437. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF2));
  59438. + dev_dbg(pxp->dev, "PXP_CSC2_COEF3 0x%x",
  59439. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF3));
  59440. + dev_dbg(pxp->dev, "PXP_CSC2_COEF4 0x%x",
  59441. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF4));
  59442. + dev_dbg(pxp->dev, "PXP_CSC2_COEF5 0x%x",
  59443. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF5));
  59444. + dev_dbg(pxp->dev, "PXP_LUT_CTRL 0x%x",
  59445. + __raw_readl(pxp->base + HW_PXP_LUT_CTRL));
  59446. + dev_dbg(pxp->dev, "PXP_LUT_ADDR 0x%x",
  59447. + __raw_readl(pxp->base + HW_PXP_LUT_ADDR));
  59448. + dev_dbg(pxp->dev, "PXP_LUT_DATA 0x%x",
  59449. + __raw_readl(pxp->base + HW_PXP_LUT_DATA));
  59450. + dev_dbg(pxp->dev, "PXP_LUT_EXTMEM 0x%x",
  59451. + __raw_readl(pxp->base + HW_PXP_LUT_EXTMEM));
  59452. + dev_dbg(pxp->dev, "PXP_CFA 0x%x",
  59453. + __raw_readl(pxp->base + HW_PXP_CFA));
  59454. + dev_dbg(pxp->dev, "PXP_HIST_CTRL 0x%x",
  59455. + __raw_readl(pxp->base + HW_PXP_HIST_CTRL));
  59456. + dev_dbg(pxp->dev, "PXP_HIST2_PARAM 0x%x",
  59457. + __raw_readl(pxp->base + HW_PXP_HIST2_PARAM));
  59458. + dev_dbg(pxp->dev, "PXP_HIST4_PARAM 0x%x",
  59459. + __raw_readl(pxp->base + HW_PXP_HIST4_PARAM));
  59460. + dev_dbg(pxp->dev, "PXP_HIST8_PARAM0 0x%x",
  59461. + __raw_readl(pxp->base + HW_PXP_HIST8_PARAM0));
  59462. + dev_dbg(pxp->dev, "PXP_HIST8_PARAM1 0x%x",
  59463. + __raw_readl(pxp->base + HW_PXP_HIST8_PARAM1));
  59464. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM0 0x%x",
  59465. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM0));
  59466. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM1 0x%x",
  59467. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM1));
  59468. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM2 0x%x",
  59469. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM2));
  59470. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM3 0x%x",
  59471. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM3));
  59472. + dev_dbg(pxp->dev, "PXP_POWER 0x%x",
  59473. + __raw_readl(pxp->base + HW_PXP_POWER));
  59474. + dev_dbg(pxp->dev, "PXP_NEXT 0x%x",
  59475. + __raw_readl(pxp->base + HW_PXP_NEXT));
  59476. + dev_dbg(pxp->dev, "PXP_DEBUGCTRL 0x%x",
  59477. + __raw_readl(pxp->base + HW_PXP_DEBUGCTRL));
  59478. + dev_dbg(pxp->dev, "PXP_DEBUG 0x%x",
  59479. + __raw_readl(pxp->base + HW_PXP_DEBUG));
  59480. + dev_dbg(pxp->dev, "PXP_VERSION 0x%x",
  59481. + __raw_readl(pxp->base + HW_PXP_VERSION));
  59482. +}
  59483. +
  59484. +static bool is_yuv(u32 pix_fmt)
  59485. +{
  59486. + if ((pix_fmt == PXP_PIX_FMT_YUYV) |
  59487. + (pix_fmt == PXP_PIX_FMT_UYVY) |
  59488. + (pix_fmt == PXP_PIX_FMT_YVYU) |
  59489. + (pix_fmt == PXP_PIX_FMT_VYUY) |
  59490. + (pix_fmt == PXP_PIX_FMT_Y41P) |
  59491. + (pix_fmt == PXP_PIX_FMT_YUV444) |
  59492. + (pix_fmt == PXP_PIX_FMT_NV12) |
  59493. + (pix_fmt == PXP_PIX_FMT_NV16) |
  59494. + (pix_fmt == PXP_PIX_FMT_NV61) |
  59495. + (pix_fmt == PXP_PIX_FMT_GREY) |
  59496. + (pix_fmt == PXP_PIX_FMT_GY04) |
  59497. + (pix_fmt == PXP_PIX_FMT_YVU410P) |
  59498. + (pix_fmt == PXP_PIX_FMT_YUV410P) |
  59499. + (pix_fmt == PXP_PIX_FMT_YVU420P) |
  59500. + (pix_fmt == PXP_PIX_FMT_YUV420P) |
  59501. + (pix_fmt == PXP_PIX_FMT_YUV420P2) |
  59502. + (pix_fmt == PXP_PIX_FMT_YVU422P) |
  59503. + (pix_fmt == PXP_PIX_FMT_YUV422P)) {
  59504. + return true;
  59505. + } else {
  59506. + return false;
  59507. + }
  59508. +}
  59509. +
  59510. +static void pxp_set_ctrl(struct pxps *pxp)
  59511. +{
  59512. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59513. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  59514. + u32 ctrl;
  59515. + u32 fmt_ctrl;
  59516. + int need_swap = 0; /* to support YUYV and YVYU formats */
  59517. +
  59518. + /* Configure S0 input format */
  59519. + switch (pxp_conf->s0_param.pixel_fmt) {
  59520. + case PXP_PIX_FMT_RGB32:
  59521. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB888;
  59522. + break;
  59523. + case PXP_PIX_FMT_RGB565:
  59524. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB565;
  59525. + break;
  59526. + case PXP_PIX_FMT_RGB555:
  59527. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB555;
  59528. + break;
  59529. + case PXP_PIX_FMT_YUV420P:
  59530. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
  59531. + break;
  59532. + case PXP_PIX_FMT_YVU420P:
  59533. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
  59534. + break;
  59535. + case PXP_PIX_FMT_GREY:
  59536. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y8;
  59537. + break;
  59538. + case PXP_PIX_FMT_GY04:
  59539. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y4;
  59540. + break;
  59541. + case PXP_PIX_FMT_YUV422P:
  59542. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV422;
  59543. + break;
  59544. + case PXP_PIX_FMT_UYVY:
  59545. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
  59546. + break;
  59547. + case PXP_PIX_FMT_YUYV:
  59548. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
  59549. + need_swap = 1;
  59550. + break;
  59551. + case PXP_PIX_FMT_VYUY:
  59552. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
  59553. + break;
  59554. + case PXP_PIX_FMT_YVYU:
  59555. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
  59556. + need_swap = 1;
  59557. + break;
  59558. + case PXP_PIX_FMT_NV12:
  59559. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P420;
  59560. + break;
  59561. + case PXP_PIX_FMT_NV21:
  59562. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P420;
  59563. + break;
  59564. + case PXP_PIX_FMT_NV16:
  59565. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P422;
  59566. + break;
  59567. + case PXP_PIX_FMT_NV61:
  59568. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P422;
  59569. + break;
  59570. + default:
  59571. + fmt_ctrl = 0;
  59572. + }
  59573. +
  59574. + ctrl = BF_PXP_PS_CTRL_FORMAT(fmt_ctrl) | BF_PXP_PS_CTRL_SWAP(need_swap);
  59575. + __raw_writel(ctrl, pxp->base + HW_PXP_PS_CTRL_SET);
  59576. +
  59577. + /* Configure output format based on out_channel format */
  59578. + switch (pxp_conf->out_param.pixel_fmt) {
  59579. + case PXP_PIX_FMT_RGB32:
  59580. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888;
  59581. + break;
  59582. + case PXP_PIX_FMT_BGRA32:
  59583. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__ARGB8888;
  59584. + break;
  59585. + case PXP_PIX_FMT_RGB24:
  59586. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888P;
  59587. + break;
  59588. + case PXP_PIX_FMT_RGB565:
  59589. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB565;
  59590. + break;
  59591. + case PXP_PIX_FMT_RGB555:
  59592. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB555;
  59593. + break;
  59594. + case PXP_PIX_FMT_GREY:
  59595. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y8;
  59596. + break;
  59597. + case PXP_PIX_FMT_GY04:
  59598. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y4;
  59599. + break;
  59600. + case PXP_PIX_FMT_UYVY:
  59601. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__UYVY1P422;
  59602. + break;
  59603. + case PXP_PIX_FMT_VYUY:
  59604. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__VYUY1P422;
  59605. + break;
  59606. + case PXP_PIX_FMT_NV12:
  59607. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P420;
  59608. + break;
  59609. + case PXP_PIX_FMT_NV21:
  59610. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P420;
  59611. + break;
  59612. + case PXP_PIX_FMT_NV16:
  59613. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P422;
  59614. + break;
  59615. + case PXP_PIX_FMT_NV61:
  59616. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P422;
  59617. + break;
  59618. + default:
  59619. + fmt_ctrl = 0;
  59620. + }
  59621. +
  59622. + ctrl = BF_PXP_OUT_CTRL_FORMAT(fmt_ctrl);
  59623. + __raw_writel(ctrl, pxp->base + HW_PXP_OUT_CTRL);
  59624. +
  59625. + ctrl = 0;
  59626. + if (proc_data->scaling)
  59627. + ;
  59628. + if (proc_data->vflip)
  59629. + ctrl |= BM_PXP_CTRL_VFLIP;
  59630. + if (proc_data->hflip)
  59631. + ctrl |= BM_PXP_CTRL_HFLIP;
  59632. + if (proc_data->rotate) {
  59633. + ctrl |= BF_PXP_CTRL_ROTATE(proc_data->rotate / 90);
  59634. + if (proc_data->rot_pos)
  59635. + ctrl |= BM_PXP_CTRL_ROT_POS;
  59636. + }
  59637. +
  59638. + /* In default, the block size is set to 8x8
  59639. + * But block size can be set to 16x16 due to
  59640. + * blocksize variable modification
  59641. + */
  59642. + ctrl |= block_size << 23;
  59643. +
  59644. + __raw_writel(ctrl, pxp->base + HW_PXP_CTRL);
  59645. +}
  59646. +
  59647. +static int pxp_start(struct pxps *pxp)
  59648. +{
  59649. + __raw_writel(BM_PXP_CTRL_IRQ_ENABLE, pxp->base + HW_PXP_CTRL_SET);
  59650. + __raw_writel(BM_PXP_CTRL_ENABLE, pxp->base + HW_PXP_CTRL_SET);
  59651. + dump_pxp_reg(pxp);
  59652. +
  59653. + return 0;
  59654. +}
  59655. +
  59656. +static void pxp_set_outbuf(struct pxps *pxp)
  59657. +{
  59658. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59659. + struct pxp_layer_param *out_params = &pxp_conf->out_param;
  59660. +
  59661. + __raw_writel(out_params->paddr, pxp->base + HW_PXP_OUT_BUF);
  59662. +
  59663. + __raw_writel(BF_PXP_OUT_LRC_X(out_params->width - 1) |
  59664. + BF_PXP_OUT_LRC_Y(out_params->height - 1),
  59665. + pxp->base + HW_PXP_OUT_LRC);
  59666. +
  59667. + if (out_params->pixel_fmt == PXP_PIX_FMT_RGB24) {
  59668. + __raw_writel(out_params->stride * 3,
  59669. + pxp->base + HW_PXP_OUT_PITCH);
  59670. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_BGRA32 ||
  59671. + out_params->pixel_fmt == PXP_PIX_FMT_RGB32) {
  59672. + __raw_writel(out_params->stride << 2,
  59673. + pxp->base + HW_PXP_OUT_PITCH);
  59674. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_RGB565) {
  59675. + __raw_writel(out_params->stride << 1,
  59676. + pxp->base + HW_PXP_OUT_PITCH);
  59677. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
  59678. + (out_params->pixel_fmt == PXP_PIX_FMT_VYUY)) {
  59679. + __raw_writel(out_params->stride << 1,
  59680. + pxp->base + HW_PXP_OUT_PITCH);
  59681. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_GREY ||
  59682. + out_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
  59683. + out_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
  59684. + out_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
  59685. + out_params->pixel_fmt == PXP_PIX_FMT_NV61) {
  59686. + __raw_writel(out_params->stride,
  59687. + pxp->base + HW_PXP_OUT_PITCH);
  59688. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_GY04) {
  59689. + __raw_writel(out_params->stride >> 1,
  59690. + pxp->base + HW_PXP_OUT_PITCH);
  59691. + } else {
  59692. + __raw_writel(0, pxp->base + HW_PXP_OUT_PITCH);
  59693. + }
  59694. +
  59695. + /* set global alpha if necessary */
  59696. + if (out_params->global_alpha_enable) {
  59697. + __raw_writel(out_params->global_alpha << 24,
  59698. + pxp->base + HW_PXP_OUT_CTRL_SET);
  59699. + __raw_writel(BM_PXP_OUT_CTRL_ALPHA_OUTPUT,
  59700. + pxp->base + HW_PXP_OUT_CTRL_SET);
  59701. + }
  59702. +}
  59703. +
  59704. +static void pxp_set_s0colorkey(struct pxps *pxp)
  59705. +{
  59706. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59707. + struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  59708. +
  59709. + /* Low and high are set equal. V4L does not allow a chromakey range */
  59710. + if (s0_params->color_key_enable == 0 || s0_params->color_key == -1) {
  59711. + /* disable color key */
  59712. + __raw_writel(0xFFFFFF, pxp->base + HW_PXP_PS_CLRKEYLOW);
  59713. + __raw_writel(0, pxp->base + HW_PXP_PS_CLRKEYHIGH);
  59714. + } else {
  59715. + __raw_writel(s0_params->color_key,
  59716. + pxp->base + HW_PXP_PS_CLRKEYLOW);
  59717. + __raw_writel(s0_params->color_key,
  59718. + pxp->base + HW_PXP_PS_CLRKEYHIGH);
  59719. + }
  59720. +}
  59721. +
  59722. +static void pxp_set_olcolorkey(int layer_no, struct pxps *pxp)
  59723. +{
  59724. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59725. + struct pxp_layer_param *ol_params = &pxp_conf->ol_param[layer_no];
  59726. +
  59727. + /* Low and high are set equal. V4L does not allow a chromakey range */
  59728. + if (ol_params->color_key_enable != 0 && ol_params->color_key != -1) {
  59729. + __raw_writel(ol_params->color_key,
  59730. + pxp->base + HW_PXP_AS_CLRKEYLOW);
  59731. + __raw_writel(ol_params->color_key,
  59732. + pxp->base + HW_PXP_AS_CLRKEYHIGH);
  59733. + } else {
  59734. + /* disable color key */
  59735. + __raw_writel(0xFFFFFF, pxp->base + HW_PXP_AS_CLRKEYLOW);
  59736. + __raw_writel(0, pxp->base + HW_PXP_AS_CLRKEYHIGH);
  59737. + }
  59738. +}
  59739. +
  59740. +static void pxp_set_oln(int layer_no, struct pxps *pxp)
  59741. +{
  59742. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59743. + struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
  59744. + dma_addr_t phys_addr = olparams_data->paddr;
  59745. + u32 pitch = olparams_data->stride ? olparams_data->stride :
  59746. + olparams_data->width;
  59747. +
  59748. + __raw_writel(phys_addr, pxp->base + HW_PXP_AS_BUF);
  59749. +
  59750. + /* Fixme */
  59751. + if (olparams_data->width == 0 && olparams_data->height == 0) {
  59752. + __raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_AS_ULC);
  59753. + __raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_LRC);
  59754. + } else {
  59755. + __raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_ULC);
  59756. + if (pxp_conf->proc_data.rotate == 90 ||
  59757. + pxp_conf->proc_data.rotate == 270) {
  59758. + if (pxp_conf->proc_data.rot_pos == 1) {
  59759. + __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->height - 1) |
  59760. + BF_PXP_OUT_AS_LRC_Y(olparams_data->width - 1),
  59761. + pxp->base + HW_PXP_OUT_AS_LRC);
  59762. + } else {
  59763. + __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width - 1) |
  59764. + BF_PXP_OUT_AS_LRC_Y(olparams_data->height - 1),
  59765. + pxp->base + HW_PXP_OUT_AS_LRC);
  59766. + }
  59767. + } else {
  59768. + __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width - 1) |
  59769. + BF_PXP_OUT_AS_LRC_Y(olparams_data->height - 1),
  59770. + pxp->base + HW_PXP_OUT_AS_LRC);
  59771. + }
  59772. + }
  59773. +
  59774. + if ((olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) |
  59775. + (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB32)) {
  59776. + __raw_writel(pitch << 2,
  59777. + pxp->base + HW_PXP_AS_PITCH);
  59778. + } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) {
  59779. + __raw_writel(pitch << 1,
  59780. + pxp->base + HW_PXP_AS_PITCH);
  59781. + } else {
  59782. + __raw_writel(0, pxp->base + HW_PXP_AS_PITCH);
  59783. + }
  59784. +}
  59785. +
  59786. +static void pxp_set_olparam(int layer_no, struct pxps *pxp)
  59787. +{
  59788. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59789. + struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
  59790. + u32 olparam;
  59791. +
  59792. + olparam = BF_PXP_AS_CTRL_ALPHA(olparams_data->global_alpha);
  59793. + if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB32) {
  59794. + olparam |=
  59795. + BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB888);
  59796. + } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) {
  59797. + olparam |=
  59798. + BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__ARGB8888);
  59799. + if (!olparams_data->combine_enable) {
  59800. + olparam |=
  59801. + BF_PXP_AS_CTRL_ALPHA_CTRL
  59802. + (BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs);
  59803. + olparam |= 0x3 << 16;
  59804. + }
  59805. + } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) {
  59806. + olparam |=
  59807. + BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB565);
  59808. + }
  59809. + if (olparams_data->global_alpha_enable) {
  59810. + if (olparams_data->global_override) {
  59811. + olparam |=
  59812. + BF_PXP_AS_CTRL_ALPHA_CTRL
  59813. + (BV_PXP_AS_CTRL_ALPHA_CTRL__Override);
  59814. + } else {
  59815. + olparam |=
  59816. + BF_PXP_AS_CTRL_ALPHA_CTRL
  59817. + (BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply);
  59818. + }
  59819. + if (olparams_data->alpha_invert)
  59820. + olparam |= BM_PXP_AS_CTRL_ALPHA_INVERT;
  59821. + }
  59822. + if (olparams_data->color_key_enable)
  59823. + olparam |= BM_PXP_AS_CTRL_ENABLE_COLORKEY;
  59824. +
  59825. + __raw_writel(olparam, pxp->base + HW_PXP_AS_CTRL);
  59826. +}
  59827. +
  59828. +static void pxp_set_s0param(struct pxps *pxp)
  59829. +{
  59830. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59831. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  59832. + u32 s0param;
  59833. +
  59834. + /* contains the coordinate for the PS in the OUTPUT buffer. */
  59835. + if ((pxp_conf->s0_param).width == 0 &&
  59836. + (pxp_conf->s0_param).height == 0) {
  59837. + __raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_PS_ULC);
  59838. + __raw_writel(0x0, pxp->base + HW_PXP_OUT_PS_LRC);
  59839. + } else {
  59840. + s0param = BF_PXP_OUT_PS_ULC_X(proc_data->drect.left);
  59841. + s0param |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.top);
  59842. + __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_ULC);
  59843. + s0param = BF_PXP_OUT_PS_LRC_X(proc_data->drect.left +
  59844. + proc_data->drect.width - 1);
  59845. + s0param |= BF_PXP_OUT_PS_LRC_Y(proc_data->drect.top +
  59846. + proc_data->drect.height - 1);
  59847. + __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_LRC);
  59848. + }
  59849. +}
  59850. +
  59851. +/* crop behavior is re-designed in h/w. */
  59852. +static void pxp_set_s0crop(struct pxps *pxp)
  59853. +{
  59854. + /*
  59855. + * place-holder, it's implemented in other functions in this driver.
  59856. + * Refer to "Clipping source images" section in RM for detail.
  59857. + */
  59858. +}
  59859. +
  59860. +static int pxp_set_scaling(struct pxps *pxp)
  59861. +{
  59862. + int ret = 0;
  59863. + u32 xscale, yscale, s0scale;
  59864. + u32 decx, decy, xdec = 0, ydec = 0;
  59865. + struct pxp_proc_data *proc_data = &pxp->pxp_conf_state.proc_data;
  59866. +
  59867. + if (((proc_data->srect.width == proc_data->drect.width) &&
  59868. + (proc_data->srect.height == proc_data->drect.height)) ||
  59869. + ((proc_data->srect.width == 0) && (proc_data->srect.height == 0))) {
  59870. + proc_data->scaling = 0;
  59871. + __raw_writel(0x10001000, pxp->base + HW_PXP_PS_SCALE);
  59872. + __raw_writel(0, pxp->base + HW_PXP_PS_CTRL);
  59873. + goto out;
  59874. + }
  59875. +
  59876. + proc_data->scaling = 1;
  59877. + decx = proc_data->srect.width / proc_data->drect.width;
  59878. + decy = proc_data->srect.height / proc_data->drect.height;
  59879. + if (decx > 0) {
  59880. + if (decx >= 2 && decx < 4) {
  59881. + decx = 2;
  59882. + xdec = 1;
  59883. + } else if (decx >= 4 && decx < 8) {
  59884. + decx = 4;
  59885. + xdec = 2;
  59886. + } else if (decx >= 8) {
  59887. + decx = 8;
  59888. + xdec = 3;
  59889. + }
  59890. + xscale = proc_data->srect.width * 0x1000 /
  59891. + (proc_data->drect.width * decx);
  59892. + } else
  59893. + xscale = proc_data->srect.width * 0x1000 /
  59894. + proc_data->drect.width;
  59895. + if (decy > 0) {
  59896. + if (decy >= 2 && decy < 4) {
  59897. + decy = 2;
  59898. + ydec = 1;
  59899. + } else if (decy >= 4 && decy < 8) {
  59900. + decy = 4;
  59901. + ydec = 2;
  59902. + } else if (decy >= 8) {
  59903. + decy = 8;
  59904. + ydec = 3;
  59905. + }
  59906. + yscale = proc_data->srect.height * 0x1000 /
  59907. + (proc_data->drect.height * decy);
  59908. + } else
  59909. + yscale = proc_data->srect.height * 0x1000 /
  59910. + proc_data->drect.height;
  59911. +
  59912. + __raw_writel((xdec << 10) | (ydec << 8), pxp->base + HW_PXP_PS_CTRL);
  59913. +
  59914. + if (xscale > PXP_DOWNSCALE_THRESHOLD)
  59915. + xscale = PXP_DOWNSCALE_THRESHOLD;
  59916. + if (yscale > PXP_DOWNSCALE_THRESHOLD)
  59917. + yscale = PXP_DOWNSCALE_THRESHOLD;
  59918. + s0scale = BF_PXP_PS_SCALE_YSCALE(yscale) |
  59919. + BF_PXP_PS_SCALE_XSCALE(xscale);
  59920. + __raw_writel(s0scale, pxp->base + HW_PXP_PS_SCALE);
  59921. +
  59922. +out:
  59923. + pxp_set_ctrl(pxp);
  59924. +
  59925. + return ret;
  59926. +}
  59927. +
  59928. +static void pxp_set_bg(struct pxps *pxp)
  59929. +{
  59930. + __raw_writel(pxp->pxp_conf_state.proc_data.bgcolor,
  59931. + pxp->base + HW_PXP_PS_BACKGROUND);
  59932. +}
  59933. +
  59934. +static void pxp_set_lut(struct pxps *pxp)
  59935. +{
  59936. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  59937. + int lut_op = pxp_conf->proc_data.lut_transform;
  59938. + u32 reg_val;
  59939. + int i;
  59940. + bool use_cmap = (lut_op & PXP_LUT_USE_CMAP) ? true : false;
  59941. + u8 *cmap = pxp_conf->proc_data.lut_map;
  59942. + u32 entry_src;
  59943. + u32 pix_val;
  59944. + u8 entry[4];
  59945. +
  59946. + /*
  59947. + * If LUT already configured as needed, return...
  59948. + * Unless CMAP is needed and it has been updated.
  59949. + */
  59950. + if ((pxp->lut_state == lut_op) &&
  59951. + !(use_cmap && pxp_conf->proc_data.lut_map_updated))
  59952. + return;
  59953. +
  59954. + if (lut_op == PXP_LUT_NONE) {
  59955. + __raw_writel(BM_PXP_LUT_CTRL_BYPASS,
  59956. + pxp->base + HW_PXP_LUT_CTRL);
  59957. + } else if (((lut_op & PXP_LUT_INVERT) != 0)
  59958. + && ((lut_op & PXP_LUT_BLACK_WHITE) != 0)) {
  59959. + /* Fill out LUT table with inverted monochromized values */
  59960. +
  59961. + /* clear bypass bit, set lookup mode & out mode */
  59962. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  59963. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  59964. + BF_PXP_LUT_CTRL_OUT_MODE
  59965. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  59966. + pxp->base + HW_PXP_LUT_CTRL);
  59967. +
  59968. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  59969. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  59970. +
  59971. + /* LUT address pointer auto-increments after each data write */
  59972. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  59973. + for (i = 0; i < 4; i++) {
  59974. + entry_src = use_cmap ?
  59975. + cmap[pix_val + i] : pix_val + i;
  59976. + entry[i] = (entry_src < 0x80) ? 0xFF : 0x00;
  59977. + }
  59978. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  59979. + (entry[1] << 8) | entry[0];
  59980. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  59981. + }
  59982. + } else if ((lut_op & PXP_LUT_INVERT) != 0) {
  59983. + /* Fill out LUT table with 8-bit inverted values */
  59984. +
  59985. + /* clear bypass bit, set lookup mode & out mode */
  59986. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  59987. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  59988. + BF_PXP_LUT_CTRL_OUT_MODE
  59989. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  59990. + pxp->base + HW_PXP_LUT_CTRL);
  59991. +
  59992. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  59993. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  59994. +
  59995. + /* LUT address pointer auto-increments after each data write */
  59996. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  59997. + for (i = 0; i < 4; i++) {
  59998. + entry_src = use_cmap ?
  59999. + cmap[pix_val + i] : pix_val + i;
  60000. + entry[i] = ~entry_src & 0xFF;
  60001. + }
  60002. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  60003. + (entry[1] << 8) | entry[0];
  60004. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  60005. + }
  60006. + } else if ((lut_op & PXP_LUT_BLACK_WHITE) != 0) {
  60007. + /* Fill out LUT table with 8-bit monochromized values */
  60008. +
  60009. + /* clear bypass bit, set lookup mode & out mode */
  60010. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  60011. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  60012. + BF_PXP_LUT_CTRL_OUT_MODE
  60013. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  60014. + pxp->base + HW_PXP_LUT_CTRL);
  60015. +
  60016. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  60017. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  60018. +
  60019. + /* LUT address pointer auto-increments after each data write */
  60020. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  60021. + for (i = 0; i < 4; i++) {
  60022. + entry_src = use_cmap ?
  60023. + cmap[pix_val + i] : pix_val + i;
  60024. + entry[i] = (entry_src < 0x80) ? 0x00 : 0xFF;
  60025. + }
  60026. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  60027. + (entry[1] << 8) | entry[0];
  60028. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  60029. + }
  60030. + } else if (use_cmap) {
  60031. + /* Fill out LUT table using colormap values */
  60032. +
  60033. + /* clear bypass bit, set lookup mode & out mode */
  60034. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  60035. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  60036. + BF_PXP_LUT_CTRL_OUT_MODE
  60037. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  60038. + pxp->base + HW_PXP_LUT_CTRL);
  60039. +
  60040. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  60041. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  60042. +
  60043. + /* LUT address pointer auto-increments after each data write */
  60044. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  60045. + for (i = 0; i < 4; i++)
  60046. + entry[i] = cmap[pix_val + i];
  60047. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  60048. + (entry[1] << 8) | entry[0];
  60049. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  60050. + }
  60051. + }
  60052. +
  60053. + pxp->lut_state = lut_op;
  60054. +}
  60055. +
  60056. +static void pxp_set_csc(struct pxps *pxp)
  60057. +{
  60058. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  60059. + struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  60060. + struct pxp_layer_param *ol_params = &pxp_conf->ol_param[0];
  60061. + struct pxp_layer_param *out_params = &pxp_conf->out_param;
  60062. +
  60063. + bool input_is_YUV = is_yuv(s0_params->pixel_fmt);
  60064. + bool output_is_YUV = is_yuv(out_params->pixel_fmt);
  60065. +
  60066. + if (input_is_YUV && output_is_YUV) {
  60067. + /*
  60068. + * Input = YUV, Output = YUV
  60069. + * No CSC unless we need to do combining
  60070. + */
  60071. + if (ol_params->combine_enable) {
  60072. + /* Must convert to RGB for combining with RGB overlay */
  60073. +
  60074. + /* CSC1 - YUV->RGB */
  60075. + __raw_writel(0x04030000, pxp->base + HW_PXP_CSC1_COEF0);
  60076. + __raw_writel(0x01230208, pxp->base + HW_PXP_CSC1_COEF1);
  60077. + __raw_writel(0x076b079c, pxp->base + HW_PXP_CSC1_COEF2);
  60078. +
  60079. + /* CSC2 - RGB->YUV */
  60080. + __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
  60081. + __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
  60082. + __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
  60083. + __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
  60084. + __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
  60085. + __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
  60086. + __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
  60087. + } else {
  60088. + /* Input & Output both YUV, so bypass both CSCs */
  60089. +
  60090. + /* CSC1 - Bypass */
  60091. + __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  60092. +
  60093. + /* CSC2 - Bypass */
  60094. + __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  60095. + }
  60096. + } else if (input_is_YUV && !output_is_YUV) {
  60097. + /*
  60098. + * Input = YUV, Output = RGB
  60099. + * Use CSC1 to convert to RGB
  60100. + */
  60101. +
  60102. + /* CSC1 - YUV->RGB */
  60103. + __raw_writel(0x84ab01f0, pxp->base + HW_PXP_CSC1_COEF0);
  60104. + __raw_writel(0x01980204, pxp->base + HW_PXP_CSC1_COEF1);
  60105. + __raw_writel(0x0730079c, pxp->base + HW_PXP_CSC1_COEF2);
  60106. +
  60107. + /* CSC2 - Bypass */
  60108. + __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  60109. + } else if (!input_is_YUV && output_is_YUV) {
  60110. + /*
  60111. + * Input = RGB, Output = YUV
  60112. + * Use CSC2 to convert to YUV
  60113. + */
  60114. +
  60115. + /* CSC1 - Bypass */
  60116. + __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  60117. +
  60118. + /* CSC2 - RGB->YUV */
  60119. + __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
  60120. + __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
  60121. + __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
  60122. + __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
  60123. + __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
  60124. + __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
  60125. + __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
  60126. + } else {
  60127. + /*
  60128. + * Input = RGB, Output = RGB
  60129. + * Input & Output both RGB, so bypass both CSCs
  60130. + */
  60131. +
  60132. + /* CSC1 - Bypass */
  60133. + __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  60134. +
  60135. + /* CSC2 - Bypass */
  60136. + __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  60137. + }
  60138. +
  60139. + /* YCrCb colorspace */
  60140. + /* Not sure when we use this...no YCrCb formats are defined for PxP */
  60141. + /*
  60142. + __raw_writel(0x84ab01f0, HW_PXP_CSCCOEFF0_ADDR);
  60143. + __raw_writel(0x01230204, HW_PXP_CSCCOEFF1_ADDR);
  60144. + __raw_writel(0x0730079c, HW_PXP_CSCCOEFF2_ADDR);
  60145. + */
  60146. +
  60147. +}
  60148. +
  60149. +static void pxp_set_s0buf(struct pxps *pxp)
  60150. +{
  60151. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  60152. + struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  60153. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  60154. + dma_addr_t Y, U, V;
  60155. + dma_addr_t Y1, U1, V1;
  60156. + u32 offset, bpp = 1;
  60157. + u32 pitch = s0_params->stride ? s0_params->stride :
  60158. + s0_params->width;
  60159. +
  60160. + Y = s0_params->paddr;
  60161. +
  60162. + if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB565)
  60163. + bpp = 2;
  60164. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB32)
  60165. + bpp = 4;
  60166. + offset = (proc_data->srect.top * s0_params->width +
  60167. + proc_data->srect.left) * bpp;
  60168. + /* clipping or cropping */
  60169. + Y1 = Y + offset;
  60170. + __raw_writel(Y1, pxp->base + HW_PXP_PS_BUF);
  60171. + if ((s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P) ||
  60172. + (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) ||
  60173. + (s0_params->pixel_fmt == PXP_PIX_FMT_GREY) ||
  60174. + (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)) {
  60175. + /* Set to 1 if YUV format is 4:2:2 rather than 4:2:0 */
  60176. + int s = 2;
  60177. + if (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)
  60178. + s = 1;
  60179. +
  60180. + offset = proc_data->srect.top * s0_params->width / 4 +
  60181. + proc_data->srect.left / 2;
  60182. + U = Y + (s0_params->width * s0_params->height);
  60183. + U1 = U + offset;
  60184. + V = U + ((s0_params->width * s0_params->height) >> s);
  60185. + V1 = V + offset;
  60186. + if (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) {
  60187. + __raw_writel(V1, pxp->base + HW_PXP_PS_UBUF);
  60188. + __raw_writel(U1, pxp->base + HW_PXP_PS_VBUF);
  60189. + } else {
  60190. + __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
  60191. + __raw_writel(V1, pxp->base + HW_PXP_PS_VBUF);
  60192. + }
  60193. + } else if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV12) ||
  60194. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV21) ||
  60195. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
  60196. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV61)) {
  60197. + int s = 2;
  60198. + if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
  60199. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV61))
  60200. + s = 1;
  60201. +
  60202. + offset = (proc_data->srect.top * s0_params->width +
  60203. + proc_data->srect.left) / s;
  60204. + U = Y + (s0_params->width * s0_params->height);
  60205. + U1 = U + offset;
  60206. +
  60207. + __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
  60208. + }
  60209. +
  60210. + /* TODO: only support RGB565, Y8, Y4, YUV420 */
  60211. + if (s0_params->pixel_fmt == PXP_PIX_FMT_GREY ||
  60212. + s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P ||
  60213. + s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P ||
  60214. + s0_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
  60215. + s0_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
  60216. + s0_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
  60217. + s0_params->pixel_fmt == PXP_PIX_FMT_NV61 ||
  60218. + s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P) {
  60219. + __raw_writel(pitch, pxp->base + HW_PXP_PS_PITCH);
  60220. + }
  60221. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_GY04)
  60222. + __raw_writel(pitch >> 1,
  60223. + pxp->base + HW_PXP_PS_PITCH);
  60224. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB32)
  60225. + __raw_writel(pitch << 2,
  60226. + pxp->base + HW_PXP_PS_PITCH);
  60227. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
  60228. + s0_params->pixel_fmt == PXP_PIX_FMT_YUYV ||
  60229. + s0_params->pixel_fmt == PXP_PIX_FMT_VYUY ||
  60230. + s0_params->pixel_fmt == PXP_PIX_FMT_YVYU)
  60231. + __raw_writel(pitch << 1,
  60232. + pxp->base + HW_PXP_PS_PITCH);
  60233. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB565)
  60234. + __raw_writel(pitch << 1,
  60235. + pxp->base + HW_PXP_PS_PITCH);
  60236. + else
  60237. + __raw_writel(0, pxp->base + HW_PXP_PS_PITCH);
  60238. +}
  60239. +
  60240. +/**
  60241. + * pxp_config() - configure PxP for a processing task
  60242. + * @pxps: PXP context.
  60243. + * @pxp_chan: PXP channel.
  60244. + * @return: 0 on success or negative error code on failure.
  60245. + */
  60246. +static int pxp_config(struct pxps *pxp, struct pxp_channel *pxp_chan)
  60247. +{
  60248. + struct pxp_config_data *pxp_conf_data = &pxp->pxp_conf_state;
  60249. + int ol_nr;
  60250. + int i;
  60251. +
  60252. + /* Configure PxP regs */
  60253. + pxp_set_ctrl(pxp);
  60254. + pxp_set_s0param(pxp);
  60255. + pxp_set_s0crop(pxp);
  60256. + pxp_set_scaling(pxp);
  60257. + ol_nr = pxp_conf_data->layer_nr - 2;
  60258. + while (ol_nr > 0) {
  60259. + i = pxp_conf_data->layer_nr - 2 - ol_nr;
  60260. + pxp_set_oln(i, pxp);
  60261. + pxp_set_olparam(i, pxp);
  60262. + /* only the color key in higher overlay will take effect. */
  60263. + pxp_set_olcolorkey(i, pxp);
  60264. + ol_nr--;
  60265. + }
  60266. + pxp_set_s0colorkey(pxp);
  60267. + pxp_set_csc(pxp);
  60268. + pxp_set_bg(pxp);
  60269. + pxp_set_lut(pxp);
  60270. +
  60271. + pxp_set_s0buf(pxp);
  60272. + pxp_set_outbuf(pxp);
  60273. +
  60274. + return 0;
  60275. +}
  60276. +
  60277. +static void pxp_clk_enable(struct pxps *pxp)
  60278. +{
  60279. + mutex_lock(&pxp->clk_mutex);
  60280. +
  60281. + if (pxp->clk_stat == CLK_STAT_ON) {
  60282. + mutex_unlock(&pxp->clk_mutex);
  60283. + return;
  60284. + }
  60285. +
  60286. + clk_prepare_enable(pxp->clk);
  60287. + pxp->clk_stat = CLK_STAT_ON;
  60288. +
  60289. + mutex_unlock(&pxp->clk_mutex);
  60290. +}
  60291. +
  60292. +static void pxp_clk_disable(struct pxps *pxp)
  60293. +{
  60294. + unsigned long flags;
  60295. +
  60296. + mutex_lock(&pxp->clk_mutex);
  60297. +
  60298. + if (pxp->clk_stat == CLK_STAT_OFF) {
  60299. + mutex_unlock(&pxp->clk_mutex);
  60300. + return;
  60301. + }
  60302. +
  60303. + spin_lock_irqsave(&pxp->lock, flags);
  60304. + if ((pxp->pxp_ongoing == 0) && list_empty(&head)) {
  60305. + spin_unlock_irqrestore(&pxp->lock, flags);
  60306. + clk_disable_unprepare(pxp->clk);
  60307. + pxp->clk_stat = CLK_STAT_OFF;
  60308. + } else
  60309. + spin_unlock_irqrestore(&pxp->lock, flags);
  60310. +
  60311. + mutex_unlock(&pxp->clk_mutex);
  60312. +}
  60313. +
  60314. +static inline void clkoff_callback(struct work_struct *w)
  60315. +{
  60316. + struct pxps *pxp = container_of(w, struct pxps, work);
  60317. +
  60318. + pxp_clk_disable(pxp);
  60319. +}
  60320. +
  60321. +static void pxp_clkoff_timer(unsigned long arg)
  60322. +{
  60323. + struct pxps *pxp = (struct pxps *)arg;
  60324. +
  60325. + if ((pxp->pxp_ongoing == 0) && list_empty(&head))
  60326. + schedule_work(&pxp->work);
  60327. + else
  60328. + mod_timer(&pxp->clk_timer,
  60329. + jiffies + msecs_to_jiffies(timeout_in_ms));
  60330. +}
  60331. +
  60332. +static struct pxp_tx_desc *pxpdma_first_queued(struct pxp_channel *pxp_chan)
  60333. +{
  60334. + return list_entry(pxp_chan->queue.next, struct pxp_tx_desc, list);
  60335. +}
  60336. +
  60337. +/* called with pxp_chan->lock held */
  60338. +static void __pxpdma_dostart(struct pxp_channel *pxp_chan)
  60339. +{
  60340. + struct pxp_dma *pxp_dma = to_pxp_dma(pxp_chan->dma_chan.device);
  60341. + struct pxps *pxp = to_pxp(pxp_dma);
  60342. + struct pxp_tx_desc *desc;
  60343. + struct pxp_tx_desc *child;
  60344. + int i = 0;
  60345. +
  60346. + /* S0 */
  60347. + desc = list_first_entry(&head, struct pxp_tx_desc, list);
  60348. + memcpy(&pxp->pxp_conf_state.s0_param,
  60349. + &desc->layer_param.s0_param, sizeof(struct pxp_layer_param));
  60350. + memcpy(&pxp->pxp_conf_state.proc_data,
  60351. + &desc->proc_data, sizeof(struct pxp_proc_data));
  60352. +
  60353. + /* Save PxP configuration */
  60354. + list_for_each_entry(child, &desc->tx_list, list) {
  60355. + if (i == 0) { /* Output */
  60356. + memcpy(&pxp->pxp_conf_state.out_param,
  60357. + &child->layer_param.out_param,
  60358. + sizeof(struct pxp_layer_param));
  60359. + } else { /* Overlay */
  60360. + memcpy(&pxp->pxp_conf_state.ol_param[i - 1],
  60361. + &child->layer_param.ol_param,
  60362. + sizeof(struct pxp_layer_param));
  60363. + }
  60364. +
  60365. + i++;
  60366. + }
  60367. + pr_debug("%s:%d S0 w/h %d/%d paddr %08x\n", __func__, __LINE__,
  60368. + pxp->pxp_conf_state.s0_param.width,
  60369. + pxp->pxp_conf_state.s0_param.height,
  60370. + pxp->pxp_conf_state.s0_param.paddr);
  60371. + pr_debug("%s:%d OUT w/h %d/%d paddr %08x\n", __func__, __LINE__,
  60372. + pxp->pxp_conf_state.out_param.width,
  60373. + pxp->pxp_conf_state.out_param.height,
  60374. + pxp->pxp_conf_state.out_param.paddr);
  60375. +}
  60376. +
  60377. +static void pxpdma_dostart_work(struct pxps *pxp)
  60378. +{
  60379. + struct pxp_channel *pxp_chan = NULL;
  60380. + unsigned long flags;
  60381. + struct pxp_tx_desc *desc = NULL;
  60382. +
  60383. + spin_lock_irqsave(&pxp->lock, flags);
  60384. +
  60385. + desc = list_entry(head.next, struct pxp_tx_desc, list);
  60386. + pxp_chan = to_pxp_channel(desc->txd.chan);
  60387. +
  60388. + __pxpdma_dostart(pxp_chan);
  60389. +
  60390. + /* Configure PxP */
  60391. + pxp_config(pxp, pxp_chan);
  60392. +
  60393. + pxp_start(pxp);
  60394. +
  60395. + spin_unlock_irqrestore(&pxp->lock, flags);
  60396. +}
  60397. +
  60398. +static void pxpdma_dequeue(struct pxp_channel *pxp_chan, struct pxps *pxp)
  60399. +{
  60400. + unsigned long flags;
  60401. + struct pxp_tx_desc *desc = NULL;
  60402. +
  60403. + do {
  60404. + desc = pxpdma_first_queued(pxp_chan);
  60405. + spin_lock_irqsave(&pxp->lock, flags);
  60406. + list_move_tail(&desc->list, &head);
  60407. + spin_unlock_irqrestore(&pxp->lock, flags);
  60408. + } while (!list_empty(&pxp_chan->queue));
  60409. +}
  60410. +
  60411. +static dma_cookie_t pxp_tx_submit(struct dma_async_tx_descriptor *tx)
  60412. +{
  60413. + struct pxp_tx_desc *desc = to_tx_desc(tx);
  60414. + struct pxp_channel *pxp_chan = to_pxp_channel(tx->chan);
  60415. + dma_cookie_t cookie;
  60416. +
  60417. + dev_dbg(&pxp_chan->dma_chan.dev->device, "received TX\n");
  60418. +
  60419. + /* pxp_chan->lock can be taken under ichan->lock, but not v.v. */
  60420. + spin_lock(&pxp_chan->lock);
  60421. +
  60422. + cookie = pxp_chan->dma_chan.cookie;
  60423. +
  60424. + if (++cookie < 0)
  60425. + cookie = 1;
  60426. +
  60427. + /* from dmaengine.h: "last cookie value returned to client" */
  60428. + pxp_chan->dma_chan.cookie = cookie;
  60429. + tx->cookie = cookie;
  60430. +
  60431. + /* Here we add the tx descriptor to our PxP task queue. */
  60432. + list_add_tail(&desc->list, &pxp_chan->queue);
  60433. +
  60434. + spin_unlock(&pxp_chan->lock);
  60435. +
  60436. + dev_dbg(&pxp_chan->dma_chan.dev->device, "done TX\n");
  60437. +
  60438. + return cookie;
  60439. +}
  60440. +
  60441. +/**
  60442. + * pxp_init_channel() - initialize a PXP channel.
  60443. + * @pxp_dma: PXP DMA context.
  60444. + * @pchan: pointer to the channel object.
  60445. + * @return 0 on success or negative error code on failure.
  60446. + */
  60447. +static int pxp_init_channel(struct pxp_dma *pxp_dma,
  60448. + struct pxp_channel *pxp_chan)
  60449. +{
  60450. + int ret = 0;
  60451. +
  60452. + /*
  60453. + * We are using _virtual_ channel here.
  60454. + * Each channel contains all parameters of corresponding layers
  60455. + * for one transaction; each layer is represented as one descriptor
  60456. + * (i.e., pxp_tx_desc) here.
  60457. + */
  60458. +
  60459. + INIT_LIST_HEAD(&pxp_chan->queue);
  60460. +
  60461. + return ret;
  60462. +}
  60463. +
  60464. +static irqreturn_t pxp_irq(int irq, void *dev_id)
  60465. +{
  60466. + struct pxps *pxp = dev_id;
  60467. + struct pxp_channel *pxp_chan;
  60468. + struct pxp_tx_desc *desc;
  60469. + struct pxp_tx_desc *child, *_child;
  60470. + dma_async_tx_callback callback;
  60471. + void *callback_param;
  60472. + unsigned long flags;
  60473. + u32 hist_status;
  60474. +
  60475. + dump_pxp_reg(pxp);
  60476. +
  60477. + hist_status =
  60478. + __raw_readl(pxp->base + HW_PXP_HIST_CTRL) & BM_PXP_HIST_CTRL_STATUS;
  60479. +
  60480. + __raw_writel(BM_PXP_STAT_IRQ, pxp->base + HW_PXP_STAT_CLR);
  60481. +
  60482. + spin_lock_irqsave(&pxp->lock, flags);
  60483. +
  60484. + if (list_empty(&head)) {
  60485. + pxp->pxp_ongoing = 0;
  60486. + spin_unlock_irqrestore(&pxp->lock, flags);
  60487. + return IRQ_NONE;
  60488. + }
  60489. +
  60490. + /* Get descriptor and call callback */
  60491. + desc = list_entry(head.next, struct pxp_tx_desc, list);
  60492. + pxp_chan = to_pxp_channel(desc->txd.chan);
  60493. +
  60494. + pxp_chan->completed = desc->txd.cookie;
  60495. +
  60496. + callback = desc->txd.callback;
  60497. + callback_param = desc->txd.callback_param;
  60498. +
  60499. + /* Send histogram status back to caller */
  60500. + desc->hist_status = hist_status;
  60501. +
  60502. + if ((desc->txd.flags & DMA_PREP_INTERRUPT) && callback)
  60503. + callback(callback_param);
  60504. +
  60505. + pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  60506. +
  60507. + list_for_each_entry_safe(child, _child, &desc->tx_list, list) {
  60508. + list_del_init(&child->list);
  60509. + kmem_cache_free(tx_desc_cache, (void *)child);
  60510. + }
  60511. + list_del_init(&desc->list);
  60512. + kmem_cache_free(tx_desc_cache, (void *)desc);
  60513. +
  60514. + complete(&pxp->complete);
  60515. + pxp->pxp_ongoing = 0;
  60516. + mod_timer(&pxp->clk_timer, jiffies + msecs_to_jiffies(timeout_in_ms));
  60517. +
  60518. + spin_unlock_irqrestore(&pxp->lock, flags);
  60519. +
  60520. + return IRQ_HANDLED;
  60521. +}
  60522. +
  60523. +/* allocate/free dma tx descriptor dynamically*/
  60524. +static struct pxp_tx_desc *pxpdma_desc_alloc(struct pxp_channel *pxp_chan)
  60525. +{
  60526. + struct pxp_tx_desc *desc = NULL;
  60527. + struct dma_async_tx_descriptor *txd = NULL;
  60528. +
  60529. + desc = kmem_cache_alloc(tx_desc_cache, GFP_KERNEL | __GFP_ZERO);
  60530. + if (desc == NULL)
  60531. + return NULL;
  60532. +
  60533. + INIT_LIST_HEAD(&desc->list);
  60534. + INIT_LIST_HEAD(&desc->tx_list);
  60535. + txd = &desc->txd;
  60536. + dma_async_tx_descriptor_init(txd, &pxp_chan->dma_chan);
  60537. + txd->tx_submit = pxp_tx_submit;
  60538. +
  60539. + return desc;
  60540. +}
  60541. +
  60542. +/* Allocate and initialise a transfer descriptor. */
  60543. +static struct dma_async_tx_descriptor *pxp_prep_slave_sg(struct dma_chan *chan,
  60544. + struct scatterlist
  60545. + *sgl,
  60546. + unsigned int sg_len,
  60547. + enum
  60548. + dma_transfer_direction
  60549. + direction,
  60550. + unsigned long tx_flags,
  60551. + void *context)
  60552. +{
  60553. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60554. + struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  60555. + struct pxps *pxp = to_pxp(pxp_dma);
  60556. + struct pxp_tx_desc *desc = NULL;
  60557. + struct pxp_tx_desc *first = NULL, *prev = NULL;
  60558. + struct scatterlist *sg;
  60559. + dma_addr_t phys_addr;
  60560. + int i;
  60561. +
  60562. + if (direction != DMA_DEV_TO_MEM && direction != DMA_MEM_TO_DEV) {
  60563. + dev_err(chan->device->dev, "Invalid DMA direction %d!\n",
  60564. + direction);
  60565. + return NULL;
  60566. + }
  60567. +
  60568. + if (unlikely(sg_len < 2))
  60569. + return NULL;
  60570. +
  60571. + for_each_sg(sgl, sg, sg_len, i) {
  60572. + desc = pxpdma_desc_alloc(pxp_chan);
  60573. + if (!desc) {
  60574. + dev_err(chan->device->dev, "no enough memory to allocate tx descriptor\n");
  60575. + return NULL;
  60576. + }
  60577. +
  60578. + phys_addr = sg_dma_address(sg);
  60579. +
  60580. + if (!first) {
  60581. + first = desc;
  60582. +
  60583. + desc->layer_param.s0_param.paddr = phys_addr;
  60584. + } else {
  60585. + list_add_tail(&desc->list, &first->tx_list);
  60586. + prev->next = desc;
  60587. + desc->next = NULL;
  60588. +
  60589. + if (i == 1)
  60590. + desc->layer_param.out_param.paddr = phys_addr;
  60591. + else
  60592. + desc->layer_param.ol_param.paddr = phys_addr;
  60593. + }
  60594. +
  60595. + prev = desc;
  60596. + }
  60597. +
  60598. + pxp->pxp_conf_state.layer_nr = sg_len;
  60599. + first->txd.flags = tx_flags;
  60600. + first->len = sg_len;
  60601. + pr_debug("%s:%d first %p, first->len %d, flags %08x\n",
  60602. + __func__, __LINE__, first, first->len, first->txd.flags);
  60603. +
  60604. + return &first->txd;
  60605. +}
  60606. +
  60607. +static void pxp_issue_pending(struct dma_chan *chan)
  60608. +{
  60609. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60610. + struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  60611. + struct pxps *pxp = to_pxp(pxp_dma);
  60612. +
  60613. + spin_lock(&pxp_chan->lock);
  60614. +
  60615. + if (list_empty(&pxp_chan->queue)) {
  60616. + spin_unlock(&pxp_chan->lock);
  60617. + return;
  60618. + }
  60619. +
  60620. + pxpdma_dequeue(pxp_chan, pxp);
  60621. + pxp_chan->status = PXP_CHANNEL_READY;
  60622. +
  60623. + spin_unlock(&pxp_chan->lock);
  60624. +
  60625. + pxp_clk_enable(pxp);
  60626. + wake_up_interruptible(&pxp->thread_waitq);
  60627. +}
  60628. +
  60629. +static void __pxp_terminate_all(struct dma_chan *chan)
  60630. +{
  60631. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60632. +
  60633. + pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  60634. +}
  60635. +
  60636. +static int pxp_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
  60637. + unsigned long arg)
  60638. +{
  60639. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60640. +
  60641. + /* Only supports DMA_TERMINATE_ALL */
  60642. + if (cmd != DMA_TERMINATE_ALL)
  60643. + return -ENXIO;
  60644. +
  60645. + spin_lock(&pxp_chan->lock);
  60646. + __pxp_terminate_all(chan);
  60647. + spin_unlock(&pxp_chan->lock);
  60648. +
  60649. + return 0;
  60650. +}
  60651. +
  60652. +static int pxp_alloc_chan_resources(struct dma_chan *chan)
  60653. +{
  60654. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60655. + struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  60656. + int ret;
  60657. +
  60658. + /* dmaengine.c now guarantees to only offer free channels */
  60659. + BUG_ON(chan->client_count > 1);
  60660. + WARN_ON(pxp_chan->status != PXP_CHANNEL_FREE);
  60661. +
  60662. + chan->cookie = 1;
  60663. + pxp_chan->completed = -ENXIO;
  60664. +
  60665. + pr_debug("%s dma_chan.chan_id %d\n", __func__, chan->chan_id);
  60666. + ret = pxp_init_channel(pxp_dma, pxp_chan);
  60667. + if (ret < 0)
  60668. + goto err_chan;
  60669. +
  60670. + pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  60671. +
  60672. + dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
  60673. + chan->chan_id, pxp_chan->eof_irq);
  60674. +
  60675. + return ret;
  60676. +
  60677. +err_chan:
  60678. + return ret;
  60679. +}
  60680. +
  60681. +static void pxp_free_chan_resources(struct dma_chan *chan)
  60682. +{
  60683. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60684. +
  60685. + spin_lock(&pxp_chan->lock);
  60686. +
  60687. + __pxp_terminate_all(chan);
  60688. +
  60689. + pxp_chan->status = PXP_CHANNEL_FREE;
  60690. +
  60691. + spin_unlock(&pxp_chan->lock);
  60692. +}
  60693. +
  60694. +static enum dma_status pxp_tx_status(struct dma_chan *chan,
  60695. + dma_cookie_t cookie,
  60696. + struct dma_tx_state *txstate)
  60697. +{
  60698. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60699. +
  60700. + if (cookie != chan->cookie)
  60701. + return DMA_ERROR;
  60702. +
  60703. + if (txstate) {
  60704. + txstate->last = pxp_chan->completed;
  60705. + txstate->used = chan->cookie;
  60706. + txstate->residue = 0;
  60707. + }
  60708. + return DMA_COMPLETE;
  60709. +}
  60710. +
  60711. +static int pxp_hw_init(struct pxps *pxp)
  60712. +{
  60713. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  60714. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  60715. + u32 reg_val;
  60716. +
  60717. + /* Pull PxP out of reset */
  60718. + __raw_writel(0, pxp->base + HW_PXP_CTRL);
  60719. +
  60720. + /* Config defaults */
  60721. +
  60722. + /* Initialize non-channel-specific PxP parameters */
  60723. + proc_data->drect.left = proc_data->srect.left = 0;
  60724. + proc_data->drect.top = proc_data->srect.top = 0;
  60725. + proc_data->drect.width = proc_data->srect.width = 0;
  60726. + proc_data->drect.height = proc_data->srect.height = 0;
  60727. + proc_data->scaling = 0;
  60728. + proc_data->hflip = 0;
  60729. + proc_data->vflip = 0;
  60730. + proc_data->rotate = 0;
  60731. + proc_data->bgcolor = 0;
  60732. +
  60733. + /* Initialize S0 channel parameters */
  60734. + pxp_conf->s0_param.pixel_fmt = pxp_s0_formats[0];
  60735. + pxp_conf->s0_param.width = 0;
  60736. + pxp_conf->s0_param.height = 0;
  60737. + pxp_conf->s0_param.color_key = -1;
  60738. + pxp_conf->s0_param.color_key_enable = false;
  60739. +
  60740. + /* Initialize OL channel parameters */
  60741. + pxp_conf->ol_param[0].combine_enable = false;
  60742. + pxp_conf->ol_param[0].width = 0;
  60743. + pxp_conf->ol_param[0].height = 0;
  60744. + pxp_conf->ol_param[0].pixel_fmt = PXP_PIX_FMT_RGB565;
  60745. + pxp_conf->ol_param[0].color_key_enable = false;
  60746. + pxp_conf->ol_param[0].color_key = -1;
  60747. + pxp_conf->ol_param[0].global_alpha_enable = false;
  60748. + pxp_conf->ol_param[0].global_alpha = 0;
  60749. + pxp_conf->ol_param[0].local_alpha_enable = false;
  60750. +
  60751. + /* Initialize Output channel parameters */
  60752. + pxp_conf->out_param.width = 0;
  60753. + pxp_conf->out_param.height = 0;
  60754. + pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_RGB565;
  60755. +
  60756. + proc_data->overlay_state = 0;
  60757. +
  60758. + /* Write default h/w config */
  60759. + pxp_set_ctrl(pxp);
  60760. + pxp_set_s0param(pxp);
  60761. + pxp_set_s0crop(pxp);
  60762. + /*
  60763. + * simply program the ULC to a higher value than the LRC
  60764. + * to avoid any AS pixels to show up in the output buffer.
  60765. + */
  60766. + __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_OUT_AS_ULC);
  60767. + pxp_set_olparam(0, pxp);
  60768. + pxp_set_olcolorkey(0, pxp);
  60769. +
  60770. + pxp_set_s0colorkey(pxp);
  60771. + pxp_set_csc(pxp);
  60772. + pxp_set_bg(pxp);
  60773. + pxp_set_lut(pxp);
  60774. +
  60775. + /* One-time histogram configuration */
  60776. + reg_val =
  60777. + BF_PXP_HIST_CTRL_PANEL_MODE(BV_PXP_HIST_CTRL_PANEL_MODE__GRAY16);
  60778. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST_CTRL);
  60779. +
  60780. + reg_val = BF_PXP_HIST2_PARAM_VALUE0(0x00) |
  60781. + BF_PXP_HIST2_PARAM_VALUE1(0x00F);
  60782. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST2_PARAM);
  60783. +
  60784. + reg_val = BF_PXP_HIST4_PARAM_VALUE0(0x00) |
  60785. + BF_PXP_HIST4_PARAM_VALUE1(0x05) |
  60786. + BF_PXP_HIST4_PARAM_VALUE2(0x0A) | BF_PXP_HIST4_PARAM_VALUE3(0x0F);
  60787. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST4_PARAM);
  60788. +
  60789. + reg_val = BF_PXP_HIST8_PARAM0_VALUE0(0x00) |
  60790. + BF_PXP_HIST8_PARAM0_VALUE1(0x02) |
  60791. + BF_PXP_HIST8_PARAM0_VALUE2(0x04) | BF_PXP_HIST8_PARAM0_VALUE3(0x06);
  60792. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST8_PARAM0);
  60793. + reg_val = BF_PXP_HIST8_PARAM1_VALUE4(0x09) |
  60794. + BF_PXP_HIST8_PARAM1_VALUE5(0x0B) |
  60795. + BF_PXP_HIST8_PARAM1_VALUE6(0x0D) | BF_PXP_HIST8_PARAM1_VALUE7(0x0F);
  60796. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST8_PARAM1);
  60797. +
  60798. + reg_val = BF_PXP_HIST16_PARAM0_VALUE0(0x00) |
  60799. + BF_PXP_HIST16_PARAM0_VALUE1(0x01) |
  60800. + BF_PXP_HIST16_PARAM0_VALUE2(0x02) |
  60801. + BF_PXP_HIST16_PARAM0_VALUE3(0x03);
  60802. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM0);
  60803. + reg_val = BF_PXP_HIST16_PARAM1_VALUE4(0x04) |
  60804. + BF_PXP_HIST16_PARAM1_VALUE5(0x05) |
  60805. + BF_PXP_HIST16_PARAM1_VALUE6(0x06) |
  60806. + BF_PXP_HIST16_PARAM1_VALUE7(0x07);
  60807. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM1);
  60808. + reg_val = BF_PXP_HIST16_PARAM2_VALUE8(0x08) |
  60809. + BF_PXP_HIST16_PARAM2_VALUE9(0x09) |
  60810. + BF_PXP_HIST16_PARAM2_VALUE10(0x0A) |
  60811. + BF_PXP_HIST16_PARAM2_VALUE11(0x0B);
  60812. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM2);
  60813. + reg_val = BF_PXP_HIST16_PARAM3_VALUE12(0x0C) |
  60814. + BF_PXP_HIST16_PARAM3_VALUE13(0x0D) |
  60815. + BF_PXP_HIST16_PARAM3_VALUE14(0x0E) |
  60816. + BF_PXP_HIST16_PARAM3_VALUE15(0x0F);
  60817. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM3);
  60818. +
  60819. + return 0;
  60820. +}
  60821. +
  60822. +static int pxp_dma_init(struct pxps *pxp)
  60823. +{
  60824. + struct pxp_dma *pxp_dma = &pxp->pxp_dma;
  60825. + struct dma_device *dma = &pxp_dma->dma;
  60826. + int i;
  60827. +
  60828. + dma_cap_set(DMA_SLAVE, dma->cap_mask);
  60829. + dma_cap_set(DMA_PRIVATE, dma->cap_mask);
  60830. +
  60831. + /* Compulsory common fields */
  60832. + dma->dev = pxp->dev;
  60833. + dma->device_alloc_chan_resources = pxp_alloc_chan_resources;
  60834. + dma->device_free_chan_resources = pxp_free_chan_resources;
  60835. + dma->device_tx_status = pxp_tx_status;
  60836. + dma->device_issue_pending = pxp_issue_pending;
  60837. +
  60838. + /* Compulsory for DMA_SLAVE fields */
  60839. + dma->device_prep_slave_sg = pxp_prep_slave_sg;
  60840. + dma->device_control = pxp_control;
  60841. +
  60842. + /* Initialize PxP Channels */
  60843. + INIT_LIST_HEAD(&dma->channels);
  60844. + for (i = 0; i < NR_PXP_VIRT_CHANNEL; i++) {
  60845. + struct pxp_channel *pxp_chan = pxp->channel + i;
  60846. + struct dma_chan *dma_chan = &pxp_chan->dma_chan;
  60847. +
  60848. + spin_lock_init(&pxp_chan->lock);
  60849. +
  60850. + /* Only one EOF IRQ for PxP, shared by all channels */
  60851. + pxp_chan->eof_irq = pxp->irq;
  60852. + pxp_chan->status = PXP_CHANNEL_FREE;
  60853. + pxp_chan->completed = -ENXIO;
  60854. + snprintf(pxp_chan->eof_name, sizeof(pxp_chan->eof_name),
  60855. + "PXP EOF %d", i);
  60856. +
  60857. + dma_chan->device = &pxp_dma->dma;
  60858. + dma_chan->cookie = 1;
  60859. + dma_chan->chan_id = i;
  60860. + list_add_tail(&dma_chan->device_node, &dma->channels);
  60861. + }
  60862. +
  60863. + return dma_async_device_register(&pxp_dma->dma);
  60864. +}
  60865. +
  60866. +static ssize_t clk_off_timeout_show(struct device *dev,
  60867. + struct device_attribute *attr, char *buf)
  60868. +{
  60869. + return sprintf(buf, "%d\n", timeout_in_ms);
  60870. +}
  60871. +
  60872. +static ssize_t clk_off_timeout_store(struct device *dev,
  60873. + struct device_attribute *attr,
  60874. + const char *buf, size_t count)
  60875. +{
  60876. + int val;
  60877. + if (sscanf(buf, "%d", &val) > 0) {
  60878. + timeout_in_ms = val;
  60879. + return count;
  60880. + }
  60881. + return -EINVAL;
  60882. +}
  60883. +
  60884. +static DEVICE_ATTR(clk_off_timeout, 0644, clk_off_timeout_show,
  60885. + clk_off_timeout_store);
  60886. +
  60887. +static ssize_t block_size_show(struct device *dev,
  60888. + struct device_attribute *attr,
  60889. + char *buf)
  60890. +{
  60891. + return sprintf(buf, "%d\n", block_size);
  60892. +}
  60893. +
  60894. +static ssize_t block_size_store(struct device *dev,
  60895. + struct device_attribute *attr,
  60896. + const char *buf, size_t count)
  60897. +{
  60898. + char **last = NULL;
  60899. +
  60900. + block_size = simple_strtoul(buf, last, 0);
  60901. + if (block_size > 1)
  60902. + block_size = 1;
  60903. +
  60904. + return count;
  60905. +}
  60906. +static DEVICE_ATTR(block_size, S_IWUSR | S_IRUGO,
  60907. + block_size_show, block_size_store);
  60908. +
  60909. +static const struct of_device_id imx_pxpdma_dt_ids[] = {
  60910. + { .compatible = "fsl,imx6dl-pxp-dma", },
  60911. + { /* sentinel */ }
  60912. +};
  60913. +MODULE_DEVICE_TABLE(of, imx_pxpdma_dt_ids);
  60914. +
  60915. +static int has_pending_task(struct pxps *pxp, struct pxp_channel *task)
  60916. +{
  60917. + int found;
  60918. + unsigned long flags;
  60919. +
  60920. + spin_lock_irqsave(&pxp->lock, flags);
  60921. + found = !list_empty(&head);
  60922. + spin_unlock_irqrestore(&pxp->lock, flags);
  60923. +
  60924. + return found;
  60925. +}
  60926. +
  60927. +static int pxp_dispatch_thread(void *argv)
  60928. +{
  60929. + struct pxps *pxp = (struct pxps *)argv;
  60930. + struct pxp_channel *pending = NULL;
  60931. + unsigned long flags;
  60932. +
  60933. + while (!kthread_should_stop()) {
  60934. + int ret;
  60935. + ret = wait_event_interruptible(pxp->thread_waitq,
  60936. + has_pending_task(pxp, pending));
  60937. + if (signal_pending(current))
  60938. + continue;
  60939. +
  60940. + if (kthread_should_stop())
  60941. + break;
  60942. +
  60943. + spin_lock_irqsave(&pxp->lock, flags);
  60944. + pxp->pxp_ongoing = 1;
  60945. + spin_unlock_irqrestore(&pxp->lock, flags);
  60946. + init_completion(&pxp->complete);
  60947. + pxpdma_dostart_work(pxp);
  60948. + ret = wait_for_completion_timeout(&pxp->complete, 2 * HZ);
  60949. + if (ret == 0) {
  60950. + printk(KERN_EMERG "%s: task is timeout\n\n", __func__);
  60951. + break;
  60952. + }
  60953. + }
  60954. +
  60955. + return 0;
  60956. +}
  60957. +
  60958. +static int pxp_probe(struct platform_device *pdev)
  60959. +{
  60960. + struct pxps *pxp;
  60961. + struct resource *res;
  60962. + int irq;
  60963. + int err = 0;
  60964. +
  60965. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  60966. + irq = platform_get_irq(pdev, 0);
  60967. + if (!res || irq < 0) {
  60968. + err = -ENODEV;
  60969. + goto exit;
  60970. + }
  60971. +
  60972. + pxp = devm_kzalloc(&pdev->dev, sizeof(*pxp), GFP_KERNEL);
  60973. + if (!pxp) {
  60974. + dev_err(&pdev->dev, "failed to allocate control object\n");
  60975. + err = -ENOMEM;
  60976. + goto exit;
  60977. + }
  60978. +
  60979. + pxp->dev = &pdev->dev;
  60980. +
  60981. + platform_set_drvdata(pdev, pxp);
  60982. + pxp->irq = irq;
  60983. +
  60984. + pxp->pxp_ongoing = 0;
  60985. + pxp->lut_state = 0;
  60986. +
  60987. + spin_lock_init(&pxp->lock);
  60988. + mutex_init(&pxp->clk_mutex);
  60989. +
  60990. + pxp->base = devm_request_and_ioremap(&pdev->dev, res);
  60991. + if (pxp->base == NULL) {
  60992. + dev_err(&pdev->dev, "Couldn't ioremap regs\n");
  60993. + err = -ENODEV;
  60994. + goto exit;
  60995. + }
  60996. +
  60997. + pxp->pdev = pdev;
  60998. +
  60999. + pxp->clk = devm_clk_get(&pdev->dev, "pxp-axi");
  61000. + clk_prepare_enable(pxp->clk);
  61001. +
  61002. + err = pxp_hw_init(pxp);
  61003. + clk_disable_unprepare(pxp->clk);
  61004. + if (err) {
  61005. + dev_err(&pdev->dev, "failed to initialize hardware\n");
  61006. + goto exit;
  61007. + }
  61008. +
  61009. + err = devm_request_irq(&pdev->dev, pxp->irq, pxp_irq, 0,
  61010. + "pxp-dmaengine", pxp);
  61011. + if (err)
  61012. + goto exit;
  61013. + /* Initialize DMA engine */
  61014. + err = pxp_dma_init(pxp);
  61015. + if (err < 0)
  61016. + goto exit;
  61017. +
  61018. + if (device_create_file(&pdev->dev, &dev_attr_clk_off_timeout)) {
  61019. + dev_err(&pdev->dev,
  61020. + "Unable to create file from clk_off_timeout\n");
  61021. + goto exit;
  61022. + }
  61023. +
  61024. + device_create_file(&pdev->dev, &dev_attr_block_size);
  61025. + dump_pxp_reg(pxp);
  61026. +
  61027. + INIT_WORK(&pxp->work, clkoff_callback);
  61028. + init_timer(&pxp->clk_timer);
  61029. + pxp->clk_timer.function = pxp_clkoff_timer;
  61030. + pxp->clk_timer.data = (unsigned long)pxp;
  61031. +
  61032. + /* allocate a kernel thread to dispatch pxp conf */
  61033. + pxp->dispatch = kthread_run(pxp_dispatch_thread, pxp, "pxp_dispatch");
  61034. + if (IS_ERR(pxp->dispatch)) {
  61035. + err = PTR_ERR(pxp->dispatch);
  61036. + goto exit;
  61037. + }
  61038. + init_waitqueue_head(&pxp->thread_waitq);
  61039. + tx_desc_cache = kmem_cache_create("tx_desc", sizeof(struct pxp_tx_desc),
  61040. + 0, SLAB_HWCACHE_ALIGN, NULL);
  61041. + if (!tx_desc_cache) {
  61042. + err = -ENOMEM;
  61043. + goto exit;
  61044. + }
  61045. +
  61046. + register_pxp_device();
  61047. +
  61048. +exit:
  61049. + if (err)
  61050. + dev_err(&pdev->dev, "Exiting (unsuccessfully) pxp_probe()\n");
  61051. + return err;
  61052. +}
  61053. +
  61054. +static int pxp_remove(struct platform_device *pdev)
  61055. +{
  61056. + struct pxps *pxp = platform_get_drvdata(pdev);
  61057. +
  61058. + unregister_pxp_device();
  61059. + kmem_cache_destroy(tx_desc_cache);
  61060. + kthread_stop(pxp->dispatch);
  61061. + cancel_work_sync(&pxp->work);
  61062. + del_timer_sync(&pxp->clk_timer);
  61063. + clk_disable_unprepare(pxp->clk);
  61064. + device_remove_file(&pdev->dev, &dev_attr_clk_off_timeout);
  61065. + device_remove_file(&pdev->dev, &dev_attr_block_size);
  61066. + dma_async_device_unregister(&(pxp->pxp_dma.dma));
  61067. +
  61068. + return 0;
  61069. +}
  61070. +
  61071. +#ifdef CONFIG_PM
  61072. +static int pxp_suspend(struct platform_device *pdev, pm_message_t state)
  61073. +{
  61074. + struct pxps *pxp = platform_get_drvdata(pdev);
  61075. +
  61076. + pxp_clk_enable(pxp);
  61077. + while (__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_ENABLE)
  61078. + ;
  61079. +
  61080. + __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL);
  61081. + pxp_clk_disable(pxp);
  61082. +
  61083. + return 0;
  61084. +}
  61085. +
  61086. +static int pxp_resume(struct platform_device *pdev)
  61087. +{
  61088. + struct pxps *pxp = platform_get_drvdata(pdev);
  61089. +
  61090. + pxp_clk_enable(pxp);
  61091. + /* Pull PxP out of reset */
  61092. + __raw_writel(0, pxp->base + HW_PXP_CTRL);
  61093. + pxp_clk_disable(pxp);
  61094. +
  61095. + return 0;
  61096. +}
  61097. +#else
  61098. +#define pxp_suspend NULL
  61099. +#define pxp_resume NULL
  61100. +#endif
  61101. +
  61102. +static struct platform_driver pxp_driver = {
  61103. + .driver = {
  61104. + .name = "imx-pxp",
  61105. + .of_match_table = of_match_ptr(imx_pxpdma_dt_ids),
  61106. + },
  61107. + .probe = pxp_probe,
  61108. + .remove = pxp_remove,
  61109. + .suspend = pxp_suspend,
  61110. + .resume = pxp_resume,
  61111. +};
  61112. +
  61113. +module_platform_driver(pxp_driver);
  61114. +
  61115. +
  61116. +MODULE_DESCRIPTION("i.MX PxP driver");
  61117. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  61118. +MODULE_LICENSE("GPL");
  61119. diff -Nur linux-3.14.14/drivers/dma/pxp/regs-pxp_v2.h linux-imx6-3.14/drivers/dma/pxp/regs-pxp_v2.h
  61120. --- linux-3.14.14/drivers/dma/pxp/regs-pxp_v2.h 1969-12-31 18:00:00.000000000 -0600
  61121. +++ linux-imx6-3.14/drivers/dma/pxp/regs-pxp_v2.h 2014-12-08 00:31:52.576418001 -0600
  61122. @@ -0,0 +1,1152 @@
  61123. +/*
  61124. + * Freescale PXP Register Definitions
  61125. + *
  61126. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  61127. + *
  61128. + * This program is free software; you can redistribute it and/or modify
  61129. + * it under the terms of the GNU General Public License as published by
  61130. + * the Free Software Foundation; either version 2 of the License, or
  61131. + * (at your option) any later version.
  61132. + *
  61133. + * This program is distributed in the hope that it will be useful,
  61134. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  61135. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  61136. + * GNU General Public License for more details.
  61137. + *
  61138. + * You should have received a copy of the GNU General Public License
  61139. + * along with this program; if not, write to the Free Software
  61140. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  61141. + *
  61142. + * This file is created by xml file. Don't Edit it.
  61143. + *
  61144. + * Xml Revision: 1.29
  61145. + * Template revision: 1.3
  61146. + */
  61147. +
  61148. +#ifndef __ARCH_ARM___PXP_H
  61149. +#define __ARCH_ARM___PXP_H
  61150. +
  61151. +#define HW_PXP_CTRL (0x00000000)
  61152. +#define HW_PXP_CTRL_SET (0x00000004)
  61153. +#define HW_PXP_CTRL_CLR (0x00000008)
  61154. +#define HW_PXP_CTRL_TOG (0x0000000c)
  61155. +
  61156. +#define BM_PXP_CTRL_SFTRST 0x80000000
  61157. +#define BM_PXP_CTRL_CLKGATE 0x40000000
  61158. +#define BM_PXP_CTRL_RSVD4 0x20000000
  61159. +#define BM_PXP_CTRL_EN_REPEAT 0x10000000
  61160. +#define BP_PXP_CTRL_RSVD3 26
  61161. +#define BM_PXP_CTRL_RSVD3 0x0C000000
  61162. +#define BF_PXP_CTRL_RSVD3(v) \
  61163. + (((v) << 26) & BM_PXP_CTRL_RSVD3)
  61164. +#define BP_PXP_CTRL_INTERLACED_INPUT 24
  61165. +#define BM_PXP_CTRL_INTERLACED_INPUT 0x03000000
  61166. +#define BF_PXP_CTRL_INTERLACED_INPUT(v) \
  61167. + (((v) << 24) & BM_PXP_CTRL_INTERLACED_INPUT)
  61168. +#define BV_PXP_CTRL_INTERLACED_INPUT__PROGRESSIVE 0x0
  61169. +#define BV_PXP_CTRL_INTERLACED_INPUT__FIELD0 0x2
  61170. +#define BV_PXP_CTRL_INTERLACED_INPUT__FIELD1 0x3
  61171. +#define BM_PXP_CTRL_BLOCK_SIZE 0x00800000
  61172. +#define BV_PXP_CTRL_BLOCK_SIZE__8X8 0x0
  61173. +#define BV_PXP_CTRL_BLOCK_SIZE__16X16 0x1
  61174. +#define BM_PXP_CTRL_ROT_POS 0x00400000
  61175. +#define BM_PXP_CTRL_IN_PLACE 0x00200000
  61176. +#define BP_PXP_CTRL_RSVD1 12
  61177. +#define BM_PXP_CTRL_RSVD1 0x001FF000
  61178. +#define BF_PXP_CTRL_RSVD1(v) \
  61179. + (((v) << 12) & BM_PXP_CTRL_RSVD1)
  61180. +#define BM_PXP_CTRL_VFLIP 0x00000800
  61181. +#define BM_PXP_CTRL_HFLIP 0x00000400
  61182. +#define BP_PXP_CTRL_ROTATE 8
  61183. +#define BM_PXP_CTRL_ROTATE 0x00000300
  61184. +#define BF_PXP_CTRL_ROTATE(v) \
  61185. + (((v) << 8) & BM_PXP_CTRL_ROTATE)
  61186. +#define BV_PXP_CTRL_ROTATE__ROT_0 0x0
  61187. +#define BV_PXP_CTRL_ROTATE__ROT_90 0x1
  61188. +#define BV_PXP_CTRL_ROTATE__ROT_180 0x2
  61189. +#define BV_PXP_CTRL_ROTATE__ROT_270 0x3
  61190. +#define BP_PXP_CTRL_RSVD0 5
  61191. +#define BM_PXP_CTRL_RSVD0 0x000000E0
  61192. +#define BF_PXP_CTRL_RSVD0(v) \
  61193. + (((v) << 5) & BM_PXP_CTRL_RSVD0)
  61194. +#define BM_PXP_CTRL_ENABLE_LCD_HANDSHAKE 0x00000010
  61195. +#define BM_PXP_CTRL_LUT_DMA_IRQ_ENABLE 0x00000008
  61196. +#define BM_PXP_CTRL_NEXT_IRQ_ENABLE 0x00000004
  61197. +#define BM_PXP_CTRL_IRQ_ENABLE 0x00000002
  61198. +#define BM_PXP_CTRL_ENABLE 0x00000001
  61199. +
  61200. +#define HW_PXP_STAT (0x00000010)
  61201. +#define HW_PXP_STAT_SET (0x00000014)
  61202. +#define HW_PXP_STAT_CLR (0x00000018)
  61203. +#define HW_PXP_STAT_TOG (0x0000001c)
  61204. +
  61205. +#define BP_PXP_STAT_BLOCKX 24
  61206. +#define BM_PXP_STAT_BLOCKX 0xFF000000
  61207. +#define BF_PXP_STAT_BLOCKX(v) \
  61208. + (((v) << 24) & BM_PXP_STAT_BLOCKX)
  61209. +#define BP_PXP_STAT_BLOCKY 16
  61210. +#define BM_PXP_STAT_BLOCKY 0x00FF0000
  61211. +#define BF_PXP_STAT_BLOCKY(v) \
  61212. + (((v) << 16) & BM_PXP_STAT_BLOCKY)
  61213. +#define BP_PXP_STAT_RSVD2 9
  61214. +#define BM_PXP_STAT_RSVD2 0x0000FE00
  61215. +#define BF_PXP_STAT_RSVD2(v) \
  61216. + (((v) << 9) & BM_PXP_STAT_RSVD2)
  61217. +#define BM_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ 0x00000100
  61218. +#define BP_PXP_STAT_AXI_ERROR_ID 4
  61219. +#define BM_PXP_STAT_AXI_ERROR_ID 0x000000F0
  61220. +#define BF_PXP_STAT_AXI_ERROR_ID(v) \
  61221. + (((v) << 4) & BM_PXP_STAT_AXI_ERROR_ID)
  61222. +#define BM_PXP_STAT_NEXT_IRQ 0x00000008
  61223. +#define BM_PXP_STAT_AXI_READ_ERROR 0x00000004
  61224. +#define BM_PXP_STAT_AXI_WRITE_ERROR 0x00000002
  61225. +#define BM_PXP_STAT_IRQ 0x00000001
  61226. +
  61227. +#define HW_PXP_OUT_CTRL (0x00000020)
  61228. +#define HW_PXP_OUT_CTRL_SET (0x00000024)
  61229. +#define HW_PXP_OUT_CTRL_CLR (0x00000028)
  61230. +#define HW_PXP_OUT_CTRL_TOG (0x0000002c)
  61231. +
  61232. +#define BP_PXP_OUT_CTRL_ALPHA 24
  61233. +#define BM_PXP_OUT_CTRL_ALPHA 0xFF000000
  61234. +#define BF_PXP_OUT_CTRL_ALPHA(v) \
  61235. + (((v) << 24) & BM_PXP_OUT_CTRL_ALPHA)
  61236. +#define BM_PXP_OUT_CTRL_ALPHA_OUTPUT 0x00800000
  61237. +#define BP_PXP_OUT_CTRL_RSVD1 10
  61238. +#define BM_PXP_OUT_CTRL_RSVD1 0x007FFC00
  61239. +#define BF_PXP_OUT_CTRL_RSVD1(v) \
  61240. + (((v) << 10) & BM_PXP_OUT_CTRL_RSVD1)
  61241. +#define BP_PXP_OUT_CTRL_INTERLACED_OUTPUT 8
  61242. +#define BM_PXP_OUT_CTRL_INTERLACED_OUTPUT 0x00000300
  61243. +#define BF_PXP_OUT_CTRL_INTERLACED_OUTPUT(v) \
  61244. + (((v) << 8) & BM_PXP_OUT_CTRL_INTERLACED_OUTPUT)
  61245. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__PROGRESSIVE 0x0
  61246. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD0 0x1
  61247. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD1 0x2
  61248. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__INTERLACED 0x3
  61249. +#define BP_PXP_OUT_CTRL_RSVD0 5
  61250. +#define BM_PXP_OUT_CTRL_RSVD0 0x000000E0
  61251. +#define BF_PXP_OUT_CTRL_RSVD0(v) \
  61252. + (((v) << 5) & BM_PXP_OUT_CTRL_RSVD0)
  61253. +#define BP_PXP_OUT_CTRL_FORMAT 0
  61254. +#define BM_PXP_OUT_CTRL_FORMAT 0x0000001F
  61255. +#define BF_PXP_OUT_CTRL_FORMAT(v) \
  61256. + (((v) << 0) & BM_PXP_OUT_CTRL_FORMAT)
  61257. +#define BV_PXP_OUT_CTRL_FORMAT__ARGB8888 0x0
  61258. +#define BV_PXP_OUT_CTRL_FORMAT__RGB888 0x4
  61259. +#define BV_PXP_OUT_CTRL_FORMAT__RGB888P 0x5
  61260. +#define BV_PXP_OUT_CTRL_FORMAT__ARGB1555 0x8
  61261. +#define BV_PXP_OUT_CTRL_FORMAT__ARGB4444 0x9
  61262. +#define BV_PXP_OUT_CTRL_FORMAT__RGB555 0xC
  61263. +#define BV_PXP_OUT_CTRL_FORMAT__RGB444 0xD
  61264. +#define BV_PXP_OUT_CTRL_FORMAT__RGB565 0xE
  61265. +#define BV_PXP_OUT_CTRL_FORMAT__YUV1P444 0x10
  61266. +#define BV_PXP_OUT_CTRL_FORMAT__UYVY1P422 0x12
  61267. +#define BV_PXP_OUT_CTRL_FORMAT__VYUY1P422 0x13
  61268. +#define BV_PXP_OUT_CTRL_FORMAT__Y8 0x14
  61269. +#define BV_PXP_OUT_CTRL_FORMAT__Y4 0x15
  61270. +#define BV_PXP_OUT_CTRL_FORMAT__YUV2P422 0x18
  61271. +#define BV_PXP_OUT_CTRL_FORMAT__YUV2P420 0x19
  61272. +#define BV_PXP_OUT_CTRL_FORMAT__YVU2P422 0x1A
  61273. +#define BV_PXP_OUT_CTRL_FORMAT__YVU2P420 0x1B
  61274. +
  61275. +#define HW_PXP_OUT_BUF (0x00000030)
  61276. +
  61277. +#define BP_PXP_OUT_BUF_ADDR 0
  61278. +#define BM_PXP_OUT_BUF_ADDR 0xFFFFFFFF
  61279. +#define BF_PXP_OUT_BUF_ADDR(v) (v)
  61280. +
  61281. +#define HW_PXP_OUT_BUF2 (0x00000040)
  61282. +
  61283. +#define BP_PXP_OUT_BUF2_ADDR 0
  61284. +#define BM_PXP_OUT_BUF2_ADDR 0xFFFFFFFF
  61285. +#define BF_PXP_OUT_BUF2_ADDR(v) (v)
  61286. +
  61287. +#define HW_PXP_OUT_PITCH (0x00000050)
  61288. +
  61289. +#define BP_PXP_OUT_PITCH_RSVD 16
  61290. +#define BM_PXP_OUT_PITCH_RSVD 0xFFFF0000
  61291. +#define BF_PXP_OUT_PITCH_RSVD(v) \
  61292. + (((v) << 16) & BM_PXP_OUT_PITCH_RSVD)
  61293. +#define BP_PXP_OUT_PITCH_PITCH 0
  61294. +#define BM_PXP_OUT_PITCH_PITCH 0x0000FFFF
  61295. +#define BF_PXP_OUT_PITCH_PITCH(v) \
  61296. + (((v) << 0) & BM_PXP_OUT_PITCH_PITCH)
  61297. +
  61298. +#define HW_PXP_OUT_LRC (0x00000060)
  61299. +
  61300. +#define BP_PXP_OUT_LRC_RSVD1 30
  61301. +#define BM_PXP_OUT_LRC_RSVD1 0xC0000000
  61302. +#define BF_PXP_OUT_LRC_RSVD1(v) \
  61303. + (((v) << 30) & BM_PXP_OUT_LRC_RSVD1)
  61304. +#define BP_PXP_OUT_LRC_X 16
  61305. +#define BM_PXP_OUT_LRC_X 0x3FFF0000
  61306. +#define BF_PXP_OUT_LRC_X(v) \
  61307. + (((v) << 16) & BM_PXP_OUT_LRC_X)
  61308. +#define BP_PXP_OUT_LRC_RSVD0 14
  61309. +#define BM_PXP_OUT_LRC_RSVD0 0x0000C000
  61310. +#define BF_PXP_OUT_LRC_RSVD0(v) \
  61311. + (((v) << 14) & BM_PXP_OUT_LRC_RSVD0)
  61312. +#define BP_PXP_OUT_LRC_Y 0
  61313. +#define BM_PXP_OUT_LRC_Y 0x00003FFF
  61314. +#define BF_PXP_OUT_LRC_Y(v) \
  61315. + (((v) << 0) & BM_PXP_OUT_LRC_Y)
  61316. +
  61317. +#define HW_PXP_OUT_PS_ULC (0x00000070)
  61318. +
  61319. +#define BP_PXP_OUT_PS_ULC_RSVD1 30
  61320. +#define BM_PXP_OUT_PS_ULC_RSVD1 0xC0000000
  61321. +#define BF_PXP_OUT_PS_ULC_RSVD1(v) \
  61322. + (((v) << 30) & BM_PXP_OUT_PS_ULC_RSVD1)
  61323. +#define BP_PXP_OUT_PS_ULC_X 16
  61324. +#define BM_PXP_OUT_PS_ULC_X 0x3FFF0000
  61325. +#define BF_PXP_OUT_PS_ULC_X(v) \
  61326. + (((v) << 16) & BM_PXP_OUT_PS_ULC_X)
  61327. +#define BP_PXP_OUT_PS_ULC_RSVD0 14
  61328. +#define BM_PXP_OUT_PS_ULC_RSVD0 0x0000C000
  61329. +#define BF_PXP_OUT_PS_ULC_RSVD0(v) \
  61330. + (((v) << 14) & BM_PXP_OUT_PS_ULC_RSVD0)
  61331. +#define BP_PXP_OUT_PS_ULC_Y 0
  61332. +#define BM_PXP_OUT_PS_ULC_Y 0x00003FFF
  61333. +#define BF_PXP_OUT_PS_ULC_Y(v) \
  61334. + (((v) << 0) & BM_PXP_OUT_PS_ULC_Y)
  61335. +
  61336. +#define HW_PXP_OUT_PS_LRC (0x00000080)
  61337. +
  61338. +#define BP_PXP_OUT_PS_LRC_RSVD1 30
  61339. +#define BM_PXP_OUT_PS_LRC_RSVD1 0xC0000000
  61340. +#define BF_PXP_OUT_PS_LRC_RSVD1(v) \
  61341. + (((v) << 30) & BM_PXP_OUT_PS_LRC_RSVD1)
  61342. +#define BP_PXP_OUT_PS_LRC_X 16
  61343. +#define BM_PXP_OUT_PS_LRC_X 0x3FFF0000
  61344. +#define BF_PXP_OUT_PS_LRC_X(v) \
  61345. + (((v) << 16) & BM_PXP_OUT_PS_LRC_X)
  61346. +#define BP_PXP_OUT_PS_LRC_RSVD0 14
  61347. +#define BM_PXP_OUT_PS_LRC_RSVD0 0x0000C000
  61348. +#define BF_PXP_OUT_PS_LRC_RSVD0(v) \
  61349. + (((v) << 14) & BM_PXP_OUT_PS_LRC_RSVD0)
  61350. +#define BP_PXP_OUT_PS_LRC_Y 0
  61351. +#define BM_PXP_OUT_PS_LRC_Y 0x00003FFF
  61352. +#define BF_PXP_OUT_PS_LRC_Y(v) \
  61353. + (((v) << 0) & BM_PXP_OUT_PS_LRC_Y)
  61354. +
  61355. +#define HW_PXP_OUT_AS_ULC (0x00000090)
  61356. +
  61357. +#define BP_PXP_OUT_AS_ULC_RSVD1 30
  61358. +#define BM_PXP_OUT_AS_ULC_RSVD1 0xC0000000
  61359. +#define BF_PXP_OUT_AS_ULC_RSVD1(v) \
  61360. + (((v) << 30) & BM_PXP_OUT_AS_ULC_RSVD1)
  61361. +#define BP_PXP_OUT_AS_ULC_X 16
  61362. +#define BM_PXP_OUT_AS_ULC_X 0x3FFF0000
  61363. +#define BF_PXP_OUT_AS_ULC_X(v) \
  61364. + (((v) << 16) & BM_PXP_OUT_AS_ULC_X)
  61365. +#define BP_PXP_OUT_AS_ULC_RSVD0 14
  61366. +#define BM_PXP_OUT_AS_ULC_RSVD0 0x0000C000
  61367. +#define BF_PXP_OUT_AS_ULC_RSVD0(v) \
  61368. + (((v) << 14) & BM_PXP_OUT_AS_ULC_RSVD0)
  61369. +#define BP_PXP_OUT_AS_ULC_Y 0
  61370. +#define BM_PXP_OUT_AS_ULC_Y 0x00003FFF
  61371. +#define BF_PXP_OUT_AS_ULC_Y(v) \
  61372. + (((v) << 0) & BM_PXP_OUT_AS_ULC_Y)
  61373. +
  61374. +#define HW_PXP_OUT_AS_LRC (0x000000a0)
  61375. +
  61376. +#define BP_PXP_OUT_AS_LRC_RSVD1 30
  61377. +#define BM_PXP_OUT_AS_LRC_RSVD1 0xC0000000
  61378. +#define BF_PXP_OUT_AS_LRC_RSVD1(v) \
  61379. + (((v) << 30) & BM_PXP_OUT_AS_LRC_RSVD1)
  61380. +#define BP_PXP_OUT_AS_LRC_X 16
  61381. +#define BM_PXP_OUT_AS_LRC_X 0x3FFF0000
  61382. +#define BF_PXP_OUT_AS_LRC_X(v) \
  61383. + (((v) << 16) & BM_PXP_OUT_AS_LRC_X)
  61384. +#define BP_PXP_OUT_AS_LRC_RSVD0 14
  61385. +#define BM_PXP_OUT_AS_LRC_RSVD0 0x0000C000
  61386. +#define BF_PXP_OUT_AS_LRC_RSVD0(v) \
  61387. + (((v) << 14) & BM_PXP_OUT_AS_LRC_RSVD0)
  61388. +#define BP_PXP_OUT_AS_LRC_Y 0
  61389. +#define BM_PXP_OUT_AS_LRC_Y 0x00003FFF
  61390. +#define BF_PXP_OUT_AS_LRC_Y(v) \
  61391. + (((v) << 0) & BM_PXP_OUT_AS_LRC_Y)
  61392. +
  61393. +#define HW_PXP_PS_CTRL (0x000000b0)
  61394. +#define HW_PXP_PS_CTRL_SET (0x000000b4)
  61395. +#define HW_PXP_PS_CTRL_CLR (0x000000b8)
  61396. +#define HW_PXP_PS_CTRL_TOG (0x000000bc)
  61397. +
  61398. +#define BP_PXP_PS_CTRL_RSVD1 12
  61399. +#define BM_PXP_PS_CTRL_RSVD1 0xFFFFF000
  61400. +#define BF_PXP_PS_CTRL_RSVD1(v) \
  61401. + (((v) << 12) & BM_PXP_PS_CTRL_RSVD1)
  61402. +#define BP_PXP_PS_CTRL_DECX 10
  61403. +#define BM_PXP_PS_CTRL_DECX 0x00000C00
  61404. +#define BF_PXP_PS_CTRL_DECX(v) \
  61405. + (((v) << 10) & BM_PXP_PS_CTRL_DECX)
  61406. +#define BV_PXP_PS_CTRL_DECX__DISABLE 0x0
  61407. +#define BV_PXP_PS_CTRL_DECX__DECX2 0x1
  61408. +#define BV_PXP_PS_CTRL_DECX__DECX4 0x2
  61409. +#define BV_PXP_PS_CTRL_DECX__DECX8 0x3
  61410. +#define BP_PXP_PS_CTRL_DECY 8
  61411. +#define BM_PXP_PS_CTRL_DECY 0x00000300
  61412. +#define BF_PXP_PS_CTRL_DECY(v) \
  61413. + (((v) << 8) & BM_PXP_PS_CTRL_DECY)
  61414. +#define BV_PXP_PS_CTRL_DECY__DISABLE 0x0
  61415. +#define BV_PXP_PS_CTRL_DECY__DECY2 0x1
  61416. +#define BV_PXP_PS_CTRL_DECY__DECY4 0x2
  61417. +#define BV_PXP_PS_CTRL_DECY__DECY8 0x3
  61418. +#define BP_PXP_PS_CTRL_SWAP 5
  61419. +#define BM_PXP_PS_CTRL_SWAP 0x000000E0
  61420. +#define BF_PXP_PS_CTRL_SWAP(v) \
  61421. + (((v) << 5) & BM_PXP_PS_CTRL_SWAP)
  61422. +#define BP_PXP_PS_CTRL_FORMAT 0
  61423. +#define BM_PXP_PS_CTRL_FORMAT 0x0000001F
  61424. +#define BF_PXP_PS_CTRL_FORMAT(v) \
  61425. + (((v) << 0) & BM_PXP_PS_CTRL_FORMAT)
  61426. +#define BV_PXP_PS_CTRL_FORMAT__RGB888 0x4
  61427. +#define BV_PXP_PS_CTRL_FORMAT__RGB555 0xC
  61428. +#define BV_PXP_PS_CTRL_FORMAT__RGB444 0xD
  61429. +#define BV_PXP_PS_CTRL_FORMAT__RGB565 0xE
  61430. +#define BV_PXP_PS_CTRL_FORMAT__YUV1P444 0x10
  61431. +#define BV_PXP_PS_CTRL_FORMAT__UYVY1P422 0x12
  61432. +#define BV_PXP_PS_CTRL_FORMAT__VYUY1P422 0x13
  61433. +#define BV_PXP_PS_CTRL_FORMAT__Y8 0x14
  61434. +#define BV_PXP_PS_CTRL_FORMAT__Y4 0x15
  61435. +#define BV_PXP_PS_CTRL_FORMAT__YUV2P422 0x18
  61436. +#define BV_PXP_PS_CTRL_FORMAT__YUV2P420 0x19
  61437. +#define BV_PXP_PS_CTRL_FORMAT__YVU2P422 0x1A
  61438. +#define BV_PXP_PS_CTRL_FORMAT__YVU2P420 0x1B
  61439. +#define BV_PXP_PS_CTRL_FORMAT__YUV422 0x1E
  61440. +#define BV_PXP_PS_CTRL_FORMAT__YUV420 0x1F
  61441. +
  61442. +#define HW_PXP_PS_BUF (0x000000c0)
  61443. +
  61444. +#define BP_PXP_PS_BUF_ADDR 0
  61445. +#define BM_PXP_PS_BUF_ADDR 0xFFFFFFFF
  61446. +#define BF_PXP_PS_BUF_ADDR(v) (v)
  61447. +
  61448. +#define HW_PXP_PS_UBUF (0x000000d0)
  61449. +
  61450. +#define BP_PXP_PS_UBUF_ADDR 0
  61451. +#define BM_PXP_PS_UBUF_ADDR 0xFFFFFFFF
  61452. +#define BF_PXP_PS_UBUF_ADDR(v) (v)
  61453. +
  61454. +#define HW_PXP_PS_VBUF (0x000000e0)
  61455. +
  61456. +#define BP_PXP_PS_VBUF_ADDR 0
  61457. +#define BM_PXP_PS_VBUF_ADDR 0xFFFFFFFF
  61458. +#define BF_PXP_PS_VBUF_ADDR(v) (v)
  61459. +
  61460. +#define HW_PXP_PS_PITCH (0x000000f0)
  61461. +
  61462. +#define BP_PXP_PS_PITCH_RSVD 16
  61463. +#define BM_PXP_PS_PITCH_RSVD 0xFFFF0000
  61464. +#define BF_PXP_PS_PITCH_RSVD(v) \
  61465. + (((v) << 16) & BM_PXP_PS_PITCH_RSVD)
  61466. +#define BP_PXP_PS_PITCH_PITCH 0
  61467. +#define BM_PXP_PS_PITCH_PITCH 0x0000FFFF
  61468. +#define BF_PXP_PS_PITCH_PITCH(v) \
  61469. + (((v) << 0) & BM_PXP_PS_PITCH_PITCH)
  61470. +
  61471. +#define HW_PXP_PS_BACKGROUND (0x00000100)
  61472. +
  61473. +#define BP_PXP_PS_BACKGROUND_RSVD 24
  61474. +#define BM_PXP_PS_BACKGROUND_RSVD 0xFF000000
  61475. +#define BF_PXP_PS_BACKGROUND_RSVD(v) \
  61476. + (((v) << 24) & BM_PXP_PS_BACKGROUND_RSVD)
  61477. +#define BP_PXP_PS_BACKGROUND_COLOR 0
  61478. +#define BM_PXP_PS_BACKGROUND_COLOR 0x00FFFFFF
  61479. +#define BF_PXP_PS_BACKGROUND_COLOR(v) \
  61480. + (((v) << 0) & BM_PXP_PS_BACKGROUND_COLOR)
  61481. +
  61482. +#define HW_PXP_PS_SCALE (0x00000110)
  61483. +
  61484. +#define BM_PXP_PS_SCALE_RSVD2 0x80000000
  61485. +#define BP_PXP_PS_SCALE_YSCALE 16
  61486. +#define BM_PXP_PS_SCALE_YSCALE 0x7FFF0000
  61487. +#define BF_PXP_PS_SCALE_YSCALE(v) \
  61488. + (((v) << 16) & BM_PXP_PS_SCALE_YSCALE)
  61489. +#define BM_PXP_PS_SCALE_RSVD1 0x00008000
  61490. +#define BP_PXP_PS_SCALE_XSCALE 0
  61491. +#define BM_PXP_PS_SCALE_XSCALE 0x00007FFF
  61492. +#define BF_PXP_PS_SCALE_XSCALE(v) \
  61493. + (((v) << 0) & BM_PXP_PS_SCALE_XSCALE)
  61494. +
  61495. +#define HW_PXP_PS_OFFSET (0x00000120)
  61496. +
  61497. +#define BP_PXP_PS_OFFSET_RSVD2 28
  61498. +#define BM_PXP_PS_OFFSET_RSVD2 0xF0000000
  61499. +#define BF_PXP_PS_OFFSET_RSVD2(v) \
  61500. + (((v) << 28) & BM_PXP_PS_OFFSET_RSVD2)
  61501. +#define BP_PXP_PS_OFFSET_YOFFSET 16
  61502. +#define BM_PXP_PS_OFFSET_YOFFSET 0x0FFF0000
  61503. +#define BF_PXP_PS_OFFSET_YOFFSET(v) \
  61504. + (((v) << 16) & BM_PXP_PS_OFFSET_YOFFSET)
  61505. +#define BP_PXP_PS_OFFSET_RSVD1 12
  61506. +#define BM_PXP_PS_OFFSET_RSVD1 0x0000F000
  61507. +#define BF_PXP_PS_OFFSET_RSVD1(v) \
  61508. + (((v) << 12) & BM_PXP_PS_OFFSET_RSVD1)
  61509. +#define BP_PXP_PS_OFFSET_XOFFSET 0
  61510. +#define BM_PXP_PS_OFFSET_XOFFSET 0x00000FFF
  61511. +#define BF_PXP_PS_OFFSET_XOFFSET(v) \
  61512. + (((v) << 0) & BM_PXP_PS_OFFSET_XOFFSET)
  61513. +
  61514. +#define HW_PXP_PS_CLRKEYLOW (0x00000130)
  61515. +
  61516. +#define BP_PXP_PS_CLRKEYLOW_RSVD1 24
  61517. +#define BM_PXP_PS_CLRKEYLOW_RSVD1 0xFF000000
  61518. +#define BF_PXP_PS_CLRKEYLOW_RSVD1(v) \
  61519. + (((v) << 24) & BM_PXP_PS_CLRKEYLOW_RSVD1)
  61520. +#define BP_PXP_PS_CLRKEYLOW_PIXEL 0
  61521. +#define BM_PXP_PS_CLRKEYLOW_PIXEL 0x00FFFFFF
  61522. +#define BF_PXP_PS_CLRKEYLOW_PIXEL(v) \
  61523. + (((v) << 0) & BM_PXP_PS_CLRKEYLOW_PIXEL)
  61524. +
  61525. +#define HW_PXP_PS_CLRKEYHIGH (0x00000140)
  61526. +
  61527. +#define BP_PXP_PS_CLRKEYHIGH_RSVD1 24
  61528. +#define BM_PXP_PS_CLRKEYHIGH_RSVD1 0xFF000000
  61529. +#define BF_PXP_PS_CLRKEYHIGH_RSVD1(v) \
  61530. + (((v) << 24) & BM_PXP_PS_CLRKEYHIGH_RSVD1)
  61531. +#define BP_PXP_PS_CLRKEYHIGH_PIXEL 0
  61532. +#define BM_PXP_PS_CLRKEYHIGH_PIXEL 0x00FFFFFF
  61533. +#define BF_PXP_PS_CLRKEYHIGH_PIXEL(v) \
  61534. + (((v) << 0) & BM_PXP_PS_CLRKEYHIGH_PIXEL)
  61535. +
  61536. +#define HW_PXP_AS_CTRL (0x00000150)
  61537. +
  61538. +#define BP_PXP_AS_CTRL_RSVD1 21
  61539. +#define BM_PXP_AS_CTRL_RSVD1 0xFFE00000
  61540. +#define BF_PXP_AS_CTRL_RSVD1(v) \
  61541. + (((v) << 21) & BM_PXP_AS_CTRL_RSVD1)
  61542. +#define BM_PXP_AS_CTRL_ALPHA_INVERT 0x00100000
  61543. +#define BP_PXP_AS_CTRL_ROP 16
  61544. +#define BM_PXP_AS_CTRL_ROP 0x000F0000
  61545. +#define BF_PXP_AS_CTRL_ROP(v) \
  61546. + (((v) << 16) & BM_PXP_AS_CTRL_ROP)
  61547. +#define BV_PXP_AS_CTRL_ROP__MASKAS 0x0
  61548. +#define BV_PXP_AS_CTRL_ROP__MASKNOTAS 0x1
  61549. +#define BV_PXP_AS_CTRL_ROP__MASKASNOT 0x2
  61550. +#define BV_PXP_AS_CTRL_ROP__MERGEAS 0x3
  61551. +#define BV_PXP_AS_CTRL_ROP__MERGENOTAS 0x4
  61552. +#define BV_PXP_AS_CTRL_ROP__MERGEASNOT 0x5
  61553. +#define BV_PXP_AS_CTRL_ROP__NOTCOPYAS 0x6
  61554. +#define BV_PXP_AS_CTRL_ROP__NOT 0x7
  61555. +#define BV_PXP_AS_CTRL_ROP__NOTMASKAS 0x8
  61556. +#define BV_PXP_AS_CTRL_ROP__NOTMERGEAS 0x9
  61557. +#define BV_PXP_AS_CTRL_ROP__XORAS 0xA
  61558. +#define BV_PXP_AS_CTRL_ROP__NOTXORAS 0xB
  61559. +#define BP_PXP_AS_CTRL_ALPHA 8
  61560. +#define BM_PXP_AS_CTRL_ALPHA 0x0000FF00
  61561. +#define BF_PXP_AS_CTRL_ALPHA(v) \
  61562. + (((v) << 8) & BM_PXP_AS_CTRL_ALPHA)
  61563. +#define BP_PXP_AS_CTRL_FORMAT 4
  61564. +#define BM_PXP_AS_CTRL_FORMAT 0x000000F0
  61565. +#define BF_PXP_AS_CTRL_FORMAT(v) \
  61566. + (((v) << 4) & BM_PXP_AS_CTRL_FORMAT)
  61567. +#define BV_PXP_AS_CTRL_FORMAT__ARGB8888 0x0
  61568. +#define BV_PXP_AS_CTRL_FORMAT__RGB888 0x4
  61569. +#define BV_PXP_AS_CTRL_FORMAT__ARGB1555 0x8
  61570. +#define BV_PXP_AS_CTRL_FORMAT__ARGB4444 0x9
  61571. +#define BV_PXP_AS_CTRL_FORMAT__RGB555 0xC
  61572. +#define BV_PXP_AS_CTRL_FORMAT__RGB444 0xD
  61573. +#define BV_PXP_AS_CTRL_FORMAT__RGB565 0xE
  61574. +#define BM_PXP_AS_CTRL_ENABLE_COLORKEY 0x00000008
  61575. +#define BP_PXP_AS_CTRL_ALPHA_CTRL 1
  61576. +#define BM_PXP_AS_CTRL_ALPHA_CTRL 0x00000006
  61577. +#define BF_PXP_AS_CTRL_ALPHA_CTRL(v) \
  61578. + (((v) << 1) & BM_PXP_AS_CTRL_ALPHA_CTRL)
  61579. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Embedded 0x0
  61580. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Override 0x1
  61581. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply 0x2
  61582. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs 0x3
  61583. +#define BM_PXP_AS_CTRL_RSVD0 0x00000001
  61584. +
  61585. +#define HW_PXP_AS_BUF (0x00000160)
  61586. +
  61587. +#define BP_PXP_AS_BUF_ADDR 0
  61588. +#define BM_PXP_AS_BUF_ADDR 0xFFFFFFFF
  61589. +#define BF_PXP_AS_BUF_ADDR(v) (v)
  61590. +
  61591. +#define HW_PXP_AS_PITCH (0x00000170)
  61592. +
  61593. +#define BP_PXP_AS_PITCH_RSVD 16
  61594. +#define BM_PXP_AS_PITCH_RSVD 0xFFFF0000
  61595. +#define BF_PXP_AS_PITCH_RSVD(v) \
  61596. + (((v) << 16) & BM_PXP_AS_PITCH_RSVD)
  61597. +#define BP_PXP_AS_PITCH_PITCH 0
  61598. +#define BM_PXP_AS_PITCH_PITCH 0x0000FFFF
  61599. +#define BF_PXP_AS_PITCH_PITCH(v) \
  61600. + (((v) << 0) & BM_PXP_AS_PITCH_PITCH)
  61601. +
  61602. +#define HW_PXP_AS_CLRKEYLOW (0x00000180)
  61603. +
  61604. +#define BP_PXP_AS_CLRKEYLOW_RSVD1 24
  61605. +#define BM_PXP_AS_CLRKEYLOW_RSVD1 0xFF000000
  61606. +#define BF_PXP_AS_CLRKEYLOW_RSVD1(v) \
  61607. + (((v) << 24) & BM_PXP_AS_CLRKEYLOW_RSVD1)
  61608. +#define BP_PXP_AS_CLRKEYLOW_PIXEL 0
  61609. +#define BM_PXP_AS_CLRKEYLOW_PIXEL 0x00FFFFFF
  61610. +#define BF_PXP_AS_CLRKEYLOW_PIXEL(v) \
  61611. + (((v) << 0) & BM_PXP_AS_CLRKEYLOW_PIXEL)
  61612. +
  61613. +#define HW_PXP_AS_CLRKEYHIGH (0x00000190)
  61614. +
  61615. +#define BP_PXP_AS_CLRKEYHIGH_RSVD1 24
  61616. +#define BM_PXP_AS_CLRKEYHIGH_RSVD1 0xFF000000
  61617. +#define BF_PXP_AS_CLRKEYHIGH_RSVD1(v) \
  61618. + (((v) << 24) & BM_PXP_AS_CLRKEYHIGH_RSVD1)
  61619. +#define BP_PXP_AS_CLRKEYHIGH_PIXEL 0
  61620. +#define BM_PXP_AS_CLRKEYHIGH_PIXEL 0x00FFFFFF
  61621. +#define BF_PXP_AS_CLRKEYHIGH_PIXEL(v) \
  61622. + (((v) << 0) & BM_PXP_AS_CLRKEYHIGH_PIXEL)
  61623. +
  61624. +#define HW_PXP_CSC1_COEF0 (0x000001a0)
  61625. +
  61626. +#define BM_PXP_CSC1_COEF0_YCBCR_MODE 0x80000000
  61627. +#define BM_PXP_CSC1_COEF0_BYPASS 0x40000000
  61628. +#define BM_PXP_CSC1_COEF0_RSVD1 0x20000000
  61629. +#define BP_PXP_CSC1_COEF0_C0 18
  61630. +#define BM_PXP_CSC1_COEF0_C0 0x1FFC0000
  61631. +#define BF_PXP_CSC1_COEF0_C0(v) \
  61632. + (((v) << 18) & BM_PXP_CSC1_COEF0_C0)
  61633. +#define BP_PXP_CSC1_COEF0_UV_OFFSET 9
  61634. +#define BM_PXP_CSC1_COEF0_UV_OFFSET 0x0003FE00
  61635. +#define BF_PXP_CSC1_COEF0_UV_OFFSET(v) \
  61636. + (((v) << 9) & BM_PXP_CSC1_COEF0_UV_OFFSET)
  61637. +#define BP_PXP_CSC1_COEF0_Y_OFFSET 0
  61638. +#define BM_PXP_CSC1_COEF0_Y_OFFSET 0x000001FF
  61639. +#define BF_PXP_CSC1_COEF0_Y_OFFSET(v) \
  61640. + (((v) << 0) & BM_PXP_CSC1_COEF0_Y_OFFSET)
  61641. +
  61642. +#define HW_PXP_CSC1_COEF1 (0x000001b0)
  61643. +
  61644. +#define BP_PXP_CSC1_COEF1_RSVD1 27
  61645. +#define BM_PXP_CSC1_COEF1_RSVD1 0xF8000000
  61646. +#define BF_PXP_CSC1_COEF1_RSVD1(v) \
  61647. + (((v) << 27) & BM_PXP_CSC1_COEF1_RSVD1)
  61648. +#define BP_PXP_CSC1_COEF1_C1 16
  61649. +#define BM_PXP_CSC1_COEF1_C1 0x07FF0000
  61650. +#define BF_PXP_CSC1_COEF1_C1(v) \
  61651. + (((v) << 16) & BM_PXP_CSC1_COEF1_C1)
  61652. +#define BP_PXP_CSC1_COEF1_RSVD0 11
  61653. +#define BM_PXP_CSC1_COEF1_RSVD0 0x0000F800
  61654. +#define BF_PXP_CSC1_COEF1_RSVD0(v) \
  61655. + (((v) << 11) & BM_PXP_CSC1_COEF1_RSVD0)
  61656. +#define BP_PXP_CSC1_COEF1_C4 0
  61657. +#define BM_PXP_CSC1_COEF1_C4 0x000007FF
  61658. +#define BF_PXP_CSC1_COEF1_C4(v) \
  61659. + (((v) << 0) & BM_PXP_CSC1_COEF1_C4)
  61660. +
  61661. +#define HW_PXP_CSC1_COEF2 (0x000001c0)
  61662. +
  61663. +#define BP_PXP_CSC1_COEF2_RSVD1 27
  61664. +#define BM_PXP_CSC1_COEF2_RSVD1 0xF8000000
  61665. +#define BF_PXP_CSC1_COEF2_RSVD1(v) \
  61666. + (((v) << 27) & BM_PXP_CSC1_COEF2_RSVD1)
  61667. +#define BP_PXP_CSC1_COEF2_C2 16
  61668. +#define BM_PXP_CSC1_COEF2_C2 0x07FF0000
  61669. +#define BF_PXP_CSC1_COEF2_C2(v) \
  61670. + (((v) << 16) & BM_PXP_CSC1_COEF2_C2)
  61671. +#define BP_PXP_CSC1_COEF2_RSVD0 11
  61672. +#define BM_PXP_CSC1_COEF2_RSVD0 0x0000F800
  61673. +#define BF_PXP_CSC1_COEF2_RSVD0(v) \
  61674. + (((v) << 11) & BM_PXP_CSC1_COEF2_RSVD0)
  61675. +#define BP_PXP_CSC1_COEF2_C3 0
  61676. +#define BM_PXP_CSC1_COEF2_C3 0x000007FF
  61677. +#define BF_PXP_CSC1_COEF2_C3(v) \
  61678. + (((v) << 0) & BM_PXP_CSC1_COEF2_C3)
  61679. +
  61680. +#define HW_PXP_CSC2_CTRL (0x000001d0)
  61681. +
  61682. +#define BP_PXP_CSC2_CTRL_RSVD 3
  61683. +#define BM_PXP_CSC2_CTRL_RSVD 0xFFFFFFF8
  61684. +#define BF_PXP_CSC2_CTRL_RSVD(v) \
  61685. + (((v) << 3) & BM_PXP_CSC2_CTRL_RSVD)
  61686. +#define BP_PXP_CSC2_CTRL_CSC_MODE 1
  61687. +#define BM_PXP_CSC2_CTRL_CSC_MODE 0x00000006
  61688. +#define BF_PXP_CSC2_CTRL_CSC_MODE(v) \
  61689. + (((v) << 1) & BM_PXP_CSC2_CTRL_CSC_MODE)
  61690. +#define BV_PXP_CSC2_CTRL_CSC_MODE__YUV2RGB 0x0
  61691. +#define BV_PXP_CSC2_CTRL_CSC_MODE__YCbCr2RGB 0x1
  61692. +#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YUV 0x2
  61693. +#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YCbCr 0x3
  61694. +#define BM_PXP_CSC2_CTRL_BYPASS 0x00000001
  61695. +
  61696. +#define HW_PXP_CSC2_COEF0 (0x000001e0)
  61697. +
  61698. +#define BP_PXP_CSC2_COEF0_RSVD1 27
  61699. +#define BM_PXP_CSC2_COEF0_RSVD1 0xF8000000
  61700. +#define BF_PXP_CSC2_COEF0_RSVD1(v) \
  61701. + (((v) << 27) & BM_PXP_CSC2_COEF0_RSVD1)
  61702. +#define BP_PXP_CSC2_COEF0_A2 16
  61703. +#define BM_PXP_CSC2_COEF0_A2 0x07FF0000
  61704. +#define BF_PXP_CSC2_COEF0_A2(v) \
  61705. + (((v) << 16) & BM_PXP_CSC2_COEF0_A2)
  61706. +#define BP_PXP_CSC2_COEF0_RSVD0 11
  61707. +#define BM_PXP_CSC2_COEF0_RSVD0 0x0000F800
  61708. +#define BF_PXP_CSC2_COEF0_RSVD0(v) \
  61709. + (((v) << 11) & BM_PXP_CSC2_COEF0_RSVD0)
  61710. +#define BP_PXP_CSC2_COEF0_A1 0
  61711. +#define BM_PXP_CSC2_COEF0_A1 0x000007FF
  61712. +#define BF_PXP_CSC2_COEF0_A1(v) \
  61713. + (((v) << 0) & BM_PXP_CSC2_COEF0_A1)
  61714. +
  61715. +#define HW_PXP_CSC2_COEF1 (0x000001f0)
  61716. +
  61717. +#define BP_PXP_CSC2_COEF1_RSVD1 27
  61718. +#define BM_PXP_CSC2_COEF1_RSVD1 0xF8000000
  61719. +#define BF_PXP_CSC2_COEF1_RSVD1(v) \
  61720. + (((v) << 27) & BM_PXP_CSC2_COEF1_RSVD1)
  61721. +#define BP_PXP_CSC2_COEF1_B1 16
  61722. +#define BM_PXP_CSC2_COEF1_B1 0x07FF0000
  61723. +#define BF_PXP_CSC2_COEF1_B1(v) \
  61724. + (((v) << 16) & BM_PXP_CSC2_COEF1_B1)
  61725. +#define BP_PXP_CSC2_COEF1_RSVD0 11
  61726. +#define BM_PXP_CSC2_COEF1_RSVD0 0x0000F800
  61727. +#define BF_PXP_CSC2_COEF1_RSVD0(v) \
  61728. + (((v) << 11) & BM_PXP_CSC2_COEF1_RSVD0)
  61729. +#define BP_PXP_CSC2_COEF1_A3 0
  61730. +#define BM_PXP_CSC2_COEF1_A3 0x000007FF
  61731. +#define BF_PXP_CSC2_COEF1_A3(v) \
  61732. + (((v) << 0) & BM_PXP_CSC2_COEF1_A3)
  61733. +
  61734. +#define HW_PXP_CSC2_COEF2 (0x00000200)
  61735. +
  61736. +#define BP_PXP_CSC2_COEF2_RSVD1 27
  61737. +#define BM_PXP_CSC2_COEF2_RSVD1 0xF8000000
  61738. +#define BF_PXP_CSC2_COEF2_RSVD1(v) \
  61739. + (((v) << 27) & BM_PXP_CSC2_COEF2_RSVD1)
  61740. +#define BP_PXP_CSC2_COEF2_B3 16
  61741. +#define BM_PXP_CSC2_COEF2_B3 0x07FF0000
  61742. +#define BF_PXP_CSC2_COEF2_B3(v) \
  61743. + (((v) << 16) & BM_PXP_CSC2_COEF2_B3)
  61744. +#define BP_PXP_CSC2_COEF2_RSVD0 11
  61745. +#define BM_PXP_CSC2_COEF2_RSVD0 0x0000F800
  61746. +#define BF_PXP_CSC2_COEF2_RSVD0(v) \
  61747. + (((v) << 11) & BM_PXP_CSC2_COEF2_RSVD0)
  61748. +#define BP_PXP_CSC2_COEF2_B2 0
  61749. +#define BM_PXP_CSC2_COEF2_B2 0x000007FF
  61750. +#define BF_PXP_CSC2_COEF2_B2(v) \
  61751. + (((v) << 0) & BM_PXP_CSC2_COEF2_B2)
  61752. +
  61753. +#define HW_PXP_CSC2_COEF3 (0x00000210)
  61754. +
  61755. +#define BP_PXP_CSC2_COEF3_RSVD1 27
  61756. +#define BM_PXP_CSC2_COEF3_RSVD1 0xF8000000
  61757. +#define BF_PXP_CSC2_COEF3_RSVD1(v) \
  61758. + (((v) << 27) & BM_PXP_CSC2_COEF3_RSVD1)
  61759. +#define BP_PXP_CSC2_COEF3_C2 16
  61760. +#define BM_PXP_CSC2_COEF3_C2 0x07FF0000
  61761. +#define BF_PXP_CSC2_COEF3_C2(v) \
  61762. + (((v) << 16) & BM_PXP_CSC2_COEF3_C2)
  61763. +#define BP_PXP_CSC2_COEF3_RSVD0 11
  61764. +#define BM_PXP_CSC2_COEF3_RSVD0 0x0000F800
  61765. +#define BF_PXP_CSC2_COEF3_RSVD0(v) \
  61766. + (((v) << 11) & BM_PXP_CSC2_COEF3_RSVD0)
  61767. +#define BP_PXP_CSC2_COEF3_C1 0
  61768. +#define BM_PXP_CSC2_COEF3_C1 0x000007FF
  61769. +#define BF_PXP_CSC2_COEF3_C1(v) \
  61770. + (((v) << 0) & BM_PXP_CSC2_COEF3_C1)
  61771. +
  61772. +#define HW_PXP_CSC2_COEF4 (0x00000220)
  61773. +
  61774. +#define BP_PXP_CSC2_COEF4_RSVD1 25
  61775. +#define BM_PXP_CSC2_COEF4_RSVD1 0xFE000000
  61776. +#define BF_PXP_CSC2_COEF4_RSVD1(v) \
  61777. + (((v) << 25) & BM_PXP_CSC2_COEF4_RSVD1)
  61778. +#define BP_PXP_CSC2_COEF4_D1 16
  61779. +#define BM_PXP_CSC2_COEF4_D1 0x01FF0000
  61780. +#define BF_PXP_CSC2_COEF4_D1(v) \
  61781. + (((v) << 16) & BM_PXP_CSC2_COEF4_D1)
  61782. +#define BP_PXP_CSC2_COEF4_RSVD0 11
  61783. +#define BM_PXP_CSC2_COEF4_RSVD0 0x0000F800
  61784. +#define BF_PXP_CSC2_COEF4_RSVD0(v) \
  61785. + (((v) << 11) & BM_PXP_CSC2_COEF4_RSVD0)
  61786. +#define BP_PXP_CSC2_COEF4_C3 0
  61787. +#define BM_PXP_CSC2_COEF4_C3 0x000007FF
  61788. +#define BF_PXP_CSC2_COEF4_C3(v) \
  61789. + (((v) << 0) & BM_PXP_CSC2_COEF4_C3)
  61790. +
  61791. +#define HW_PXP_CSC2_COEF5 (0x00000230)
  61792. +
  61793. +#define BP_PXP_CSC2_COEF5_RSVD1 25
  61794. +#define BM_PXP_CSC2_COEF5_RSVD1 0xFE000000
  61795. +#define BF_PXP_CSC2_COEF5_RSVD1(v) \
  61796. + (((v) << 25) & BM_PXP_CSC2_COEF5_RSVD1)
  61797. +#define BP_PXP_CSC2_COEF5_D3 16
  61798. +#define BM_PXP_CSC2_COEF5_D3 0x01FF0000
  61799. +#define BF_PXP_CSC2_COEF5_D3(v) \
  61800. + (((v) << 16) & BM_PXP_CSC2_COEF5_D3)
  61801. +#define BP_PXP_CSC2_COEF5_RSVD0 9
  61802. +#define BM_PXP_CSC2_COEF5_RSVD0 0x0000FE00
  61803. +#define BF_PXP_CSC2_COEF5_RSVD0(v) \
  61804. + (((v) << 9) & BM_PXP_CSC2_COEF5_RSVD0)
  61805. +#define BP_PXP_CSC2_COEF5_D2 0
  61806. +#define BM_PXP_CSC2_COEF5_D2 0x000001FF
  61807. +#define BF_PXP_CSC2_COEF5_D2(v) \
  61808. + (((v) << 0) & BM_PXP_CSC2_COEF5_D2)
  61809. +
  61810. +#define HW_PXP_LUT_CTRL (0x00000240)
  61811. +
  61812. +#define BM_PXP_LUT_CTRL_BYPASS 0x80000000
  61813. +#define BP_PXP_LUT_CTRL_RSVD3 26
  61814. +#define BM_PXP_LUT_CTRL_RSVD3 0x7C000000
  61815. +#define BF_PXP_LUT_CTRL_RSVD3(v) \
  61816. + (((v) << 26) & BM_PXP_LUT_CTRL_RSVD3)
  61817. +#define BP_PXP_LUT_CTRL_LOOKUP_MODE 24
  61818. +#define BM_PXP_LUT_CTRL_LOOKUP_MODE 0x03000000
  61819. +#define BF_PXP_LUT_CTRL_LOOKUP_MODE(v) \
  61820. + (((v) << 24) & BM_PXP_LUT_CTRL_LOOKUP_MODE)
  61821. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__CACHE_RGB565 0x0
  61822. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8 0x1
  61823. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB444 0x2
  61824. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB454 0x3
  61825. +#define BP_PXP_LUT_CTRL_RSVD2 18
  61826. +#define BM_PXP_LUT_CTRL_RSVD2 0x00FC0000
  61827. +#define BF_PXP_LUT_CTRL_RSVD2(v) \
  61828. + (((v) << 18) & BM_PXP_LUT_CTRL_RSVD2)
  61829. +#define BP_PXP_LUT_CTRL_OUT_MODE 16
  61830. +#define BM_PXP_LUT_CTRL_OUT_MODE 0x00030000
  61831. +#define BF_PXP_LUT_CTRL_OUT_MODE(v) \
  61832. + (((v) << 16) & BM_PXP_LUT_CTRL_OUT_MODE)
  61833. +#define BV_PXP_LUT_CTRL_OUT_MODE__RESERVED 0x0
  61834. +#define BV_PXP_LUT_CTRL_OUT_MODE__Y8 0x1
  61835. +#define BV_PXP_LUT_CTRL_OUT_MODE__RGBW4444CFA 0x2
  61836. +#define BV_PXP_LUT_CTRL_OUT_MODE__RGB888 0x3
  61837. +#define BP_PXP_LUT_CTRL_RSVD1 11
  61838. +#define BM_PXP_LUT_CTRL_RSVD1 0x0000F800
  61839. +#define BF_PXP_LUT_CTRL_RSVD1(v) \
  61840. + (((v) << 11) & BM_PXP_LUT_CTRL_RSVD1)
  61841. +#define BM_PXP_LUT_CTRL_SEL_8KB 0x00000400
  61842. +#define BM_PXP_LUT_CTRL_LRU_UPD 0x00000200
  61843. +#define BM_PXP_LUT_CTRL_INVALID 0x00000100
  61844. +#define BP_PXP_LUT_CTRL_RSVD0 1
  61845. +#define BM_PXP_LUT_CTRL_RSVD0 0x000000FE
  61846. +#define BF_PXP_LUT_CTRL_RSVD0(v) \
  61847. + (((v) << 1) & BM_PXP_LUT_CTRL_RSVD0)
  61848. +#define BM_PXP_LUT_CTRL_DMA_START 0x00000001
  61849. +
  61850. +#define HW_PXP_LUT_ADDR (0x00000250)
  61851. +
  61852. +#define BM_PXP_LUT_ADDR_RSVD2 0x80000000
  61853. +#define BP_PXP_LUT_ADDR_NUM_BYTES 16
  61854. +#define BM_PXP_LUT_ADDR_NUM_BYTES 0x7FFF0000
  61855. +#define BF_PXP_LUT_ADDR_NUM_BYTES(v) \
  61856. + (((v) << 16) & BM_PXP_LUT_ADDR_NUM_BYTES)
  61857. +#define BP_PXP_LUT_ADDR_RSVD1 14
  61858. +#define BM_PXP_LUT_ADDR_RSVD1 0x0000C000
  61859. +#define BF_PXP_LUT_ADDR_RSVD1(v) \
  61860. + (((v) << 14) & BM_PXP_LUT_ADDR_RSVD1)
  61861. +#define BP_PXP_LUT_ADDR_ADDR 0
  61862. +#define BM_PXP_LUT_ADDR_ADDR 0x00003FFF
  61863. +#define BF_PXP_LUT_ADDR_ADDR(v) \
  61864. + (((v) << 0) & BM_PXP_LUT_ADDR_ADDR)
  61865. +
  61866. +#define HW_PXP_LUT_DATA (0x00000260)
  61867. +
  61868. +#define BP_PXP_LUT_DATA_DATA 0
  61869. +#define BM_PXP_LUT_DATA_DATA 0xFFFFFFFF
  61870. +#define BF_PXP_LUT_DATA_DATA(v) (v)
  61871. +
  61872. +#define HW_PXP_LUT_EXTMEM (0x00000270)
  61873. +
  61874. +#define BP_PXP_LUT_EXTMEM_ADDR 0
  61875. +#define BM_PXP_LUT_EXTMEM_ADDR 0xFFFFFFFF
  61876. +#define BF_PXP_LUT_EXTMEM_ADDR(v) (v)
  61877. +
  61878. +#define HW_PXP_CFA (0x00000280)
  61879. +
  61880. +#define BP_PXP_CFA_DATA 0
  61881. +#define BM_PXP_CFA_DATA 0xFFFFFFFF
  61882. +#define BF_PXP_CFA_DATA(v) (v)
  61883. +
  61884. +#define HW_PXP_HIST_CTRL (0x00000290)
  61885. +
  61886. +#define BP_PXP_HIST_CTRL_RSVD 6
  61887. +#define BM_PXP_HIST_CTRL_RSVD 0xFFFFFFC0
  61888. +#define BF_PXP_HIST_CTRL_RSVD(v) \
  61889. + (((v) << 6) & BM_PXP_HIST_CTRL_RSVD)
  61890. +#define BP_PXP_HIST_CTRL_PANEL_MODE 4
  61891. +#define BM_PXP_HIST_CTRL_PANEL_MODE 0x00000030
  61892. +#define BF_PXP_HIST_CTRL_PANEL_MODE(v) \
  61893. + (((v) << 4) & BM_PXP_HIST_CTRL_PANEL_MODE)
  61894. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY4 0x0
  61895. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY8 0x1
  61896. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY16 0x2
  61897. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY32 0x3
  61898. +#define BP_PXP_HIST_CTRL_STATUS 0
  61899. +#define BM_PXP_HIST_CTRL_STATUS 0x0000000F
  61900. +#define BF_PXP_HIST_CTRL_STATUS(v) \
  61901. + (((v) << 0) & BM_PXP_HIST_CTRL_STATUS)
  61902. +
  61903. +#define HW_PXP_HIST2_PARAM (0x000002a0)
  61904. +
  61905. +#define BP_PXP_HIST2_PARAM_RSVD 16
  61906. +#define BM_PXP_HIST2_PARAM_RSVD 0xFFFF0000
  61907. +#define BF_PXP_HIST2_PARAM_RSVD(v) \
  61908. + (((v) << 16) & BM_PXP_HIST2_PARAM_RSVD)
  61909. +#define BP_PXP_HIST2_PARAM_RSVD1 13
  61910. +#define BM_PXP_HIST2_PARAM_RSVD1 0x0000E000
  61911. +#define BF_PXP_HIST2_PARAM_RSVD1(v) \
  61912. + (((v) << 13) & BM_PXP_HIST2_PARAM_RSVD1)
  61913. +#define BP_PXP_HIST2_PARAM_VALUE1 8
  61914. +#define BM_PXP_HIST2_PARAM_VALUE1 0x00001F00
  61915. +#define BF_PXP_HIST2_PARAM_VALUE1(v) \
  61916. + (((v) << 8) & BM_PXP_HIST2_PARAM_VALUE1)
  61917. +#define BP_PXP_HIST2_PARAM_RSVD0 5
  61918. +#define BM_PXP_HIST2_PARAM_RSVD0 0x000000E0
  61919. +#define BF_PXP_HIST2_PARAM_RSVD0(v) \
  61920. + (((v) << 5) & BM_PXP_HIST2_PARAM_RSVD0)
  61921. +#define BP_PXP_HIST2_PARAM_VALUE0 0
  61922. +#define BM_PXP_HIST2_PARAM_VALUE0 0x0000001F
  61923. +#define BF_PXP_HIST2_PARAM_VALUE0(v) \
  61924. + (((v) << 0) & BM_PXP_HIST2_PARAM_VALUE0)
  61925. +
  61926. +#define HW_PXP_HIST4_PARAM (0x000002b0)
  61927. +
  61928. +#define BP_PXP_HIST4_PARAM_RSVD3 29
  61929. +#define BM_PXP_HIST4_PARAM_RSVD3 0xE0000000
  61930. +#define BF_PXP_HIST4_PARAM_RSVD3(v) \
  61931. + (((v) << 29) & BM_PXP_HIST4_PARAM_RSVD3)
  61932. +#define BP_PXP_HIST4_PARAM_VALUE3 24
  61933. +#define BM_PXP_HIST4_PARAM_VALUE3 0x1F000000
  61934. +#define BF_PXP_HIST4_PARAM_VALUE3(v) \
  61935. + (((v) << 24) & BM_PXP_HIST4_PARAM_VALUE3)
  61936. +#define BP_PXP_HIST4_PARAM_RSVD2 21
  61937. +#define BM_PXP_HIST4_PARAM_RSVD2 0x00E00000
  61938. +#define BF_PXP_HIST4_PARAM_RSVD2(v) \
  61939. + (((v) << 21) & BM_PXP_HIST4_PARAM_RSVD2)
  61940. +#define BP_PXP_HIST4_PARAM_VALUE2 16
  61941. +#define BM_PXP_HIST4_PARAM_VALUE2 0x001F0000
  61942. +#define BF_PXP_HIST4_PARAM_VALUE2(v) \
  61943. + (((v) << 16) & BM_PXP_HIST4_PARAM_VALUE2)
  61944. +#define BP_PXP_HIST4_PARAM_RSVD1 13
  61945. +#define BM_PXP_HIST4_PARAM_RSVD1 0x0000E000
  61946. +#define BF_PXP_HIST4_PARAM_RSVD1(v) \
  61947. + (((v) << 13) & BM_PXP_HIST4_PARAM_RSVD1)
  61948. +#define BP_PXP_HIST4_PARAM_VALUE1 8
  61949. +#define BM_PXP_HIST4_PARAM_VALUE1 0x00001F00
  61950. +#define BF_PXP_HIST4_PARAM_VALUE1(v) \
  61951. + (((v) << 8) & BM_PXP_HIST4_PARAM_VALUE1)
  61952. +#define BP_PXP_HIST4_PARAM_RSVD0 5
  61953. +#define BM_PXP_HIST4_PARAM_RSVD0 0x000000E0
  61954. +#define BF_PXP_HIST4_PARAM_RSVD0(v) \
  61955. + (((v) << 5) & BM_PXP_HIST4_PARAM_RSVD0)
  61956. +#define BP_PXP_HIST4_PARAM_VALUE0 0
  61957. +#define BM_PXP_HIST4_PARAM_VALUE0 0x0000001F
  61958. +#define BF_PXP_HIST4_PARAM_VALUE0(v) \
  61959. + (((v) << 0) & BM_PXP_HIST4_PARAM_VALUE0)
  61960. +
  61961. +#define HW_PXP_HIST8_PARAM0 (0x000002c0)
  61962. +
  61963. +#define BP_PXP_HIST8_PARAM0_RSVD3 29
  61964. +#define BM_PXP_HIST8_PARAM0_RSVD3 0xE0000000
  61965. +#define BF_PXP_HIST8_PARAM0_RSVD3(v) \
  61966. + (((v) << 29) & BM_PXP_HIST8_PARAM0_RSVD3)
  61967. +#define BP_PXP_HIST8_PARAM0_VALUE3 24
  61968. +#define BM_PXP_HIST8_PARAM0_VALUE3 0x1F000000
  61969. +#define BF_PXP_HIST8_PARAM0_VALUE3(v) \
  61970. + (((v) << 24) & BM_PXP_HIST8_PARAM0_VALUE3)
  61971. +#define BP_PXP_HIST8_PARAM0_RSVD2 21
  61972. +#define BM_PXP_HIST8_PARAM0_RSVD2 0x00E00000
  61973. +#define BF_PXP_HIST8_PARAM0_RSVD2(v) \
  61974. + (((v) << 21) & BM_PXP_HIST8_PARAM0_RSVD2)
  61975. +#define BP_PXP_HIST8_PARAM0_VALUE2 16
  61976. +#define BM_PXP_HIST8_PARAM0_VALUE2 0x001F0000
  61977. +#define BF_PXP_HIST8_PARAM0_VALUE2(v) \
  61978. + (((v) << 16) & BM_PXP_HIST8_PARAM0_VALUE2)
  61979. +#define BP_PXP_HIST8_PARAM0_RSVD1 13
  61980. +#define BM_PXP_HIST8_PARAM0_RSVD1 0x0000E000
  61981. +#define BF_PXP_HIST8_PARAM0_RSVD1(v) \
  61982. + (((v) << 13) & BM_PXP_HIST8_PARAM0_RSVD1)
  61983. +#define BP_PXP_HIST8_PARAM0_VALUE1 8
  61984. +#define BM_PXP_HIST8_PARAM0_VALUE1 0x00001F00
  61985. +#define BF_PXP_HIST8_PARAM0_VALUE1(v) \
  61986. + (((v) << 8) & BM_PXP_HIST8_PARAM0_VALUE1)
  61987. +#define BP_PXP_HIST8_PARAM0_RSVD0 5
  61988. +#define BM_PXP_HIST8_PARAM0_RSVD0 0x000000E0
  61989. +#define BF_PXP_HIST8_PARAM0_RSVD0(v) \
  61990. + (((v) << 5) & BM_PXP_HIST8_PARAM0_RSVD0)
  61991. +#define BP_PXP_HIST8_PARAM0_VALUE0 0
  61992. +#define BM_PXP_HIST8_PARAM0_VALUE0 0x0000001F
  61993. +#define BF_PXP_HIST8_PARAM0_VALUE0(v) \
  61994. + (((v) << 0) & BM_PXP_HIST8_PARAM0_VALUE0)
  61995. +
  61996. +#define HW_PXP_HIST8_PARAM1 (0x000002d0)
  61997. +
  61998. +#define BP_PXP_HIST8_PARAM1_RSVD7 29
  61999. +#define BM_PXP_HIST8_PARAM1_RSVD7 0xE0000000
  62000. +#define BF_PXP_HIST8_PARAM1_RSVD7(v) \
  62001. + (((v) << 29) & BM_PXP_HIST8_PARAM1_RSVD7)
  62002. +#define BP_PXP_HIST8_PARAM1_VALUE7 24
  62003. +#define BM_PXP_HIST8_PARAM1_VALUE7 0x1F000000
  62004. +#define BF_PXP_HIST8_PARAM1_VALUE7(v) \
  62005. + (((v) << 24) & BM_PXP_HIST8_PARAM1_VALUE7)
  62006. +#define BP_PXP_HIST8_PARAM1_RSVD6 21
  62007. +#define BM_PXP_HIST8_PARAM1_RSVD6 0x00E00000
  62008. +#define BF_PXP_HIST8_PARAM1_RSVD6(v) \
  62009. + (((v) << 21) & BM_PXP_HIST8_PARAM1_RSVD6)
  62010. +#define BP_PXP_HIST8_PARAM1_VALUE6 16
  62011. +#define BM_PXP_HIST8_PARAM1_VALUE6 0x001F0000
  62012. +#define BF_PXP_HIST8_PARAM1_VALUE6(v) \
  62013. + (((v) << 16) & BM_PXP_HIST8_PARAM1_VALUE6)
  62014. +#define BP_PXP_HIST8_PARAM1_RSVD5 13
  62015. +#define BM_PXP_HIST8_PARAM1_RSVD5 0x0000E000
  62016. +#define BF_PXP_HIST8_PARAM1_RSVD5(v) \
  62017. + (((v) << 13) & BM_PXP_HIST8_PARAM1_RSVD5)
  62018. +#define BP_PXP_HIST8_PARAM1_VALUE5 8
  62019. +#define BM_PXP_HIST8_PARAM1_VALUE5 0x00001F00
  62020. +#define BF_PXP_HIST8_PARAM1_VALUE5(v) \
  62021. + (((v) << 8) & BM_PXP_HIST8_PARAM1_VALUE5)
  62022. +#define BP_PXP_HIST8_PARAM1_RSVD4 5
  62023. +#define BM_PXP_HIST8_PARAM1_RSVD4 0x000000E0
  62024. +#define BF_PXP_HIST8_PARAM1_RSVD4(v) \
  62025. + (((v) << 5) & BM_PXP_HIST8_PARAM1_RSVD4)
  62026. +#define BP_PXP_HIST8_PARAM1_VALUE4 0
  62027. +#define BM_PXP_HIST8_PARAM1_VALUE4 0x0000001F
  62028. +#define BF_PXP_HIST8_PARAM1_VALUE4(v) \
  62029. + (((v) << 0) & BM_PXP_HIST8_PARAM1_VALUE4)
  62030. +
  62031. +#define HW_PXP_HIST16_PARAM0 (0x000002e0)
  62032. +
  62033. +#define BP_PXP_HIST16_PARAM0_RSVD3 29
  62034. +#define BM_PXP_HIST16_PARAM0_RSVD3 0xE0000000
  62035. +#define BF_PXP_HIST16_PARAM0_RSVD3(v) \
  62036. + (((v) << 29) & BM_PXP_HIST16_PARAM0_RSVD3)
  62037. +#define BP_PXP_HIST16_PARAM0_VALUE3 24
  62038. +#define BM_PXP_HIST16_PARAM0_VALUE3 0x1F000000
  62039. +#define BF_PXP_HIST16_PARAM0_VALUE3(v) \
  62040. + (((v) << 24) & BM_PXP_HIST16_PARAM0_VALUE3)
  62041. +#define BP_PXP_HIST16_PARAM0_RSVD2 21
  62042. +#define BM_PXP_HIST16_PARAM0_RSVD2 0x00E00000
  62043. +#define BF_PXP_HIST16_PARAM0_RSVD2(v) \
  62044. + (((v) << 21) & BM_PXP_HIST16_PARAM0_RSVD2)
  62045. +#define BP_PXP_HIST16_PARAM0_VALUE2 16
  62046. +#define BM_PXP_HIST16_PARAM0_VALUE2 0x001F0000
  62047. +#define BF_PXP_HIST16_PARAM0_VALUE2(v) \
  62048. + (((v) << 16) & BM_PXP_HIST16_PARAM0_VALUE2)
  62049. +#define BP_PXP_HIST16_PARAM0_RSVD1 13
  62050. +#define BM_PXP_HIST16_PARAM0_RSVD1 0x0000E000
  62051. +#define BF_PXP_HIST16_PARAM0_RSVD1(v) \
  62052. + (((v) << 13) & BM_PXP_HIST16_PARAM0_RSVD1)
  62053. +#define BP_PXP_HIST16_PARAM0_VALUE1 8
  62054. +#define BM_PXP_HIST16_PARAM0_VALUE1 0x00001F00
  62055. +#define BF_PXP_HIST16_PARAM0_VALUE1(v) \
  62056. + (((v) << 8) & BM_PXP_HIST16_PARAM0_VALUE1)
  62057. +#define BP_PXP_HIST16_PARAM0_RSVD0 5
  62058. +#define BM_PXP_HIST16_PARAM0_RSVD0 0x000000E0
  62059. +#define BF_PXP_HIST16_PARAM0_RSVD0(v) \
  62060. + (((v) << 5) & BM_PXP_HIST16_PARAM0_RSVD0)
  62061. +#define BP_PXP_HIST16_PARAM0_VALUE0 0
  62062. +#define BM_PXP_HIST16_PARAM0_VALUE0 0x0000001F
  62063. +#define BF_PXP_HIST16_PARAM0_VALUE0(v) \
  62064. + (((v) << 0) & BM_PXP_HIST16_PARAM0_VALUE0)
  62065. +
  62066. +#define HW_PXP_HIST16_PARAM1 (0x000002f0)
  62067. +
  62068. +#define BP_PXP_HIST16_PARAM1_RSVD7 29
  62069. +#define BM_PXP_HIST16_PARAM1_RSVD7 0xE0000000
  62070. +#define BF_PXP_HIST16_PARAM1_RSVD7(v) \
  62071. + (((v) << 29) & BM_PXP_HIST16_PARAM1_RSVD7)
  62072. +#define BP_PXP_HIST16_PARAM1_VALUE7 24
  62073. +#define BM_PXP_HIST16_PARAM1_VALUE7 0x1F000000
  62074. +#define BF_PXP_HIST16_PARAM1_VALUE7(v) \
  62075. + (((v) << 24) & BM_PXP_HIST16_PARAM1_VALUE7)
  62076. +#define BP_PXP_HIST16_PARAM1_RSVD6 21
  62077. +#define BM_PXP_HIST16_PARAM1_RSVD6 0x00E00000
  62078. +#define BF_PXP_HIST16_PARAM1_RSVD6(v) \
  62079. + (((v) << 21) & BM_PXP_HIST16_PARAM1_RSVD6)
  62080. +#define BP_PXP_HIST16_PARAM1_VALUE6 16
  62081. +#define BM_PXP_HIST16_PARAM1_VALUE6 0x001F0000
  62082. +#define BF_PXP_HIST16_PARAM1_VALUE6(v) \
  62083. + (((v) << 16) & BM_PXP_HIST16_PARAM1_VALUE6)
  62084. +#define BP_PXP_HIST16_PARAM1_RSVD5 13
  62085. +#define BM_PXP_HIST16_PARAM1_RSVD5 0x0000E000
  62086. +#define BF_PXP_HIST16_PARAM1_RSVD5(v) \
  62087. + (((v) << 13) & BM_PXP_HIST16_PARAM1_RSVD5)
  62088. +#define BP_PXP_HIST16_PARAM1_VALUE5 8
  62089. +#define BM_PXP_HIST16_PARAM1_VALUE5 0x00001F00
  62090. +#define BF_PXP_HIST16_PARAM1_VALUE5(v) \
  62091. + (((v) << 8) & BM_PXP_HIST16_PARAM1_VALUE5)
  62092. +#define BP_PXP_HIST16_PARAM1_RSVD4 5
  62093. +#define BM_PXP_HIST16_PARAM1_RSVD4 0x000000E0
  62094. +#define BF_PXP_HIST16_PARAM1_RSVD4(v) \
  62095. + (((v) << 5) & BM_PXP_HIST16_PARAM1_RSVD4)
  62096. +#define BP_PXP_HIST16_PARAM1_VALUE4 0
  62097. +#define BM_PXP_HIST16_PARAM1_VALUE4 0x0000001F
  62098. +#define BF_PXP_HIST16_PARAM1_VALUE4(v) \
  62099. + (((v) << 0) & BM_PXP_HIST16_PARAM1_VALUE4)
  62100. +
  62101. +#define HW_PXP_HIST16_PARAM2 (0x00000300)
  62102. +
  62103. +#define BP_PXP_HIST16_PARAM2_RSVD11 29
  62104. +#define BM_PXP_HIST16_PARAM2_RSVD11 0xE0000000
  62105. +#define BF_PXP_HIST16_PARAM2_RSVD11(v) \
  62106. + (((v) << 29) & BM_PXP_HIST16_PARAM2_RSVD11)
  62107. +#define BP_PXP_HIST16_PARAM2_VALUE11 24
  62108. +#define BM_PXP_HIST16_PARAM2_VALUE11 0x1F000000
  62109. +#define BF_PXP_HIST16_PARAM2_VALUE11(v) \
  62110. + (((v) << 24) & BM_PXP_HIST16_PARAM2_VALUE11)
  62111. +#define BP_PXP_HIST16_PARAM2_RSVD10 21
  62112. +#define BM_PXP_HIST16_PARAM2_RSVD10 0x00E00000
  62113. +#define BF_PXP_HIST16_PARAM2_RSVD10(v) \
  62114. + (((v) << 21) & BM_PXP_HIST16_PARAM2_RSVD10)
  62115. +#define BP_PXP_HIST16_PARAM2_VALUE10 16
  62116. +#define BM_PXP_HIST16_PARAM2_VALUE10 0x001F0000
  62117. +#define BF_PXP_HIST16_PARAM2_VALUE10(v) \
  62118. + (((v) << 16) & BM_PXP_HIST16_PARAM2_VALUE10)
  62119. +#define BP_PXP_HIST16_PARAM2_RSVD9 13
  62120. +#define BM_PXP_HIST16_PARAM2_RSVD9 0x0000E000
  62121. +#define BF_PXP_HIST16_PARAM2_RSVD9(v) \
  62122. + (((v) << 13) & BM_PXP_HIST16_PARAM2_RSVD9)
  62123. +#define BP_PXP_HIST16_PARAM2_VALUE9 8
  62124. +#define BM_PXP_HIST16_PARAM2_VALUE9 0x00001F00
  62125. +#define BF_PXP_HIST16_PARAM2_VALUE9(v) \
  62126. + (((v) << 8) & BM_PXP_HIST16_PARAM2_VALUE9)
  62127. +#define BP_PXP_HIST16_PARAM2_RSVD8 5
  62128. +#define BM_PXP_HIST16_PARAM2_RSVD8 0x000000E0
  62129. +#define BF_PXP_HIST16_PARAM2_RSVD8(v) \
  62130. + (((v) << 5) & BM_PXP_HIST16_PARAM2_RSVD8)
  62131. +#define BP_PXP_HIST16_PARAM2_VALUE8 0
  62132. +#define BM_PXP_HIST16_PARAM2_VALUE8 0x0000001F
  62133. +#define BF_PXP_HIST16_PARAM2_VALUE8(v) \
  62134. + (((v) << 0) & BM_PXP_HIST16_PARAM2_VALUE8)
  62135. +
  62136. +#define HW_PXP_HIST16_PARAM3 (0x00000310)
  62137. +
  62138. +#define BP_PXP_HIST16_PARAM3_RSVD15 29
  62139. +#define BM_PXP_HIST16_PARAM3_RSVD15 0xE0000000
  62140. +#define BF_PXP_HIST16_PARAM3_RSVD15(v) \
  62141. + (((v) << 29) & BM_PXP_HIST16_PARAM3_RSVD15)
  62142. +#define BP_PXP_HIST16_PARAM3_VALUE15 24
  62143. +#define BM_PXP_HIST16_PARAM3_VALUE15 0x1F000000
  62144. +#define BF_PXP_HIST16_PARAM3_VALUE15(v) \
  62145. + (((v) << 24) & BM_PXP_HIST16_PARAM3_VALUE15)
  62146. +#define BP_PXP_HIST16_PARAM3_RSVD14 21
  62147. +#define BM_PXP_HIST16_PARAM3_RSVD14 0x00E00000
  62148. +#define BF_PXP_HIST16_PARAM3_RSVD14(v) \
  62149. + (((v) << 21) & BM_PXP_HIST16_PARAM3_RSVD14)
  62150. +#define BP_PXP_HIST16_PARAM3_VALUE14 16
  62151. +#define BM_PXP_HIST16_PARAM3_VALUE14 0x001F0000
  62152. +#define BF_PXP_HIST16_PARAM3_VALUE14(v) \
  62153. + (((v) << 16) & BM_PXP_HIST16_PARAM3_VALUE14)
  62154. +#define BP_PXP_HIST16_PARAM3_RSVD13 13
  62155. +#define BM_PXP_HIST16_PARAM3_RSVD13 0x0000E000
  62156. +#define BF_PXP_HIST16_PARAM3_RSVD13(v) \
  62157. + (((v) << 13) & BM_PXP_HIST16_PARAM3_RSVD13)
  62158. +#define BP_PXP_HIST16_PARAM3_VALUE13 8
  62159. +#define BM_PXP_HIST16_PARAM3_VALUE13 0x00001F00
  62160. +#define BF_PXP_HIST16_PARAM3_VALUE13(v) \
  62161. + (((v) << 8) & BM_PXP_HIST16_PARAM3_VALUE13)
  62162. +#define BP_PXP_HIST16_PARAM3_RSVD12 5
  62163. +#define BM_PXP_HIST16_PARAM3_RSVD12 0x000000E0
  62164. +#define BF_PXP_HIST16_PARAM3_RSVD12(v) \
  62165. + (((v) << 5) & BM_PXP_HIST16_PARAM3_RSVD12)
  62166. +#define BP_PXP_HIST16_PARAM3_VALUE12 0
  62167. +#define BM_PXP_HIST16_PARAM3_VALUE12 0x0000001F
  62168. +#define BF_PXP_HIST16_PARAM3_VALUE12(v) \
  62169. + (((v) << 0) & BM_PXP_HIST16_PARAM3_VALUE12)
  62170. +
  62171. +#define HW_PXP_POWER (0x00000320)
  62172. +
  62173. +#define BP_PXP_POWER_CTRL 12
  62174. +#define BM_PXP_POWER_CTRL 0xFFFFF000
  62175. +#define BF_PXP_POWER_CTRL(v) \
  62176. + (((v) << 12) & BM_PXP_POWER_CTRL)
  62177. +#define BP_PXP_POWER_ROT_MEM_LP_STATE 9
  62178. +#define BM_PXP_POWER_ROT_MEM_LP_STATE 0x00000E00
  62179. +#define BF_PXP_POWER_ROT_MEM_LP_STATE(v) \
  62180. + (((v) << 9) & BM_PXP_POWER_ROT_MEM_LP_STATE)
  62181. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__NONE 0x0
  62182. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__LS 0x1
  62183. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__DS 0x2
  62184. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__SD 0x4
  62185. +#define BP_PXP_POWER_LUT_LP_STATE_WAY1_BANKN 6
  62186. +#define BM_PXP_POWER_LUT_LP_STATE_WAY1_BANKN 0x000001C0
  62187. +#define BF_PXP_POWER_LUT_LP_STATE_WAY1_BANKN(v) \
  62188. + (((v) << 6) & BM_PXP_POWER_LUT_LP_STATE_WAY1_BANKN)
  62189. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__NONE 0x0
  62190. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__LS 0x1
  62191. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__DS 0x2
  62192. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__SD 0x4
  62193. +#define BP_PXP_POWER_LUT_LP_STATE_WAY0_BANKN 3
  62194. +#define BM_PXP_POWER_LUT_LP_STATE_WAY0_BANKN 0x00000038
  62195. +#define BF_PXP_POWER_LUT_LP_STATE_WAY0_BANKN(v) \
  62196. + (((v) << 3) & BM_PXP_POWER_LUT_LP_STATE_WAY0_BANKN)
  62197. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__NONE 0x0
  62198. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__LS 0x1
  62199. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__DS 0x2
  62200. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__SD 0x4
  62201. +#define BP_PXP_POWER_LUT_LP_STATE_WAY0_BANK0 0
  62202. +#define BM_PXP_POWER_LUT_LP_STATE_WAY0_BANK0 0x00000007
  62203. +#define BF_PXP_POWER_LUT_LP_STATE_WAY0_BANK0(v) \
  62204. + (((v) << 0) & BM_PXP_POWER_LUT_LP_STATE_WAY0_BANK0)
  62205. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__NONE 0x0
  62206. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__LS 0x1
  62207. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__DS 0x2
  62208. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__SD 0x4
  62209. +
  62210. +#define HW_PXP_NEXT (0x00000400)
  62211. +
  62212. +#define BP_PXP_NEXT_POINTER 2
  62213. +#define BM_PXP_NEXT_POINTER 0xFFFFFFFC
  62214. +#define BF_PXP_NEXT_POINTER(v) \
  62215. + (((v) << 2) & BM_PXP_NEXT_POINTER)
  62216. +#define BM_PXP_NEXT_RSVD 0x00000002
  62217. +#define BM_PXP_NEXT_ENABLED 0x00000001
  62218. +
  62219. +#define HW_PXP_DEBUGCTRL (0x00000410)
  62220. +
  62221. +#define BP_PXP_DEBUGCTRL_RSVD 12
  62222. +#define BM_PXP_DEBUGCTRL_RSVD 0xFFFFF000
  62223. +#define BF_PXP_DEBUGCTRL_RSVD(v) \
  62224. + (((v) << 12) & BM_PXP_DEBUGCTRL_RSVD)
  62225. +#define BP_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 8
  62226. +#define BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 0x00000F00
  62227. +#define BF_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT(v) \
  62228. + (((v) << 8) & BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT)
  62229. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__NONE 0x0
  62230. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MISS_CNT 0x1
  62231. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__HIT_CNT 0x2
  62232. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__LAT_CNT 0x4
  62233. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MAX_LAT 0x8
  62234. +#define BP_PXP_DEBUGCTRL_SELECT 0
  62235. +#define BM_PXP_DEBUGCTRL_SELECT 0x000000FF
  62236. +#define BF_PXP_DEBUGCTRL_SELECT(v) \
  62237. + (((v) << 0) & BM_PXP_DEBUGCTRL_SELECT)
  62238. +#define BV_PXP_DEBUGCTRL_SELECT__NONE 0x0
  62239. +#define BV_PXP_DEBUGCTRL_SELECT__CTRL 0x1
  62240. +#define BV_PXP_DEBUGCTRL_SELECT__PSBUF 0x2
  62241. +#define BV_PXP_DEBUGCTRL_SELECT__PSBAX 0x3
  62242. +#define BV_PXP_DEBUGCTRL_SELECT__PSBAY 0x4
  62243. +#define BV_PXP_DEBUGCTRL_SELECT__ASBUF 0x5
  62244. +#define BV_PXP_DEBUGCTRL_SELECT__ROTATION 0x6
  62245. +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF0 0x7
  62246. +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF1 0x8
  62247. +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF2 0x9
  62248. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_STAT 0x10
  62249. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_MISS 0x11
  62250. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_HIT 0x12
  62251. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_LAT 0x13
  62252. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_MAX_LAT 0x14
  62253. +
  62254. +#define HW_PXP_DEBUG (0x00000420)
  62255. +
  62256. +#define BP_PXP_DEBUG_DATA 0
  62257. +#define BM_PXP_DEBUG_DATA 0xFFFFFFFF
  62258. +#define BF_PXP_DEBUG_DATA(v) (v)
  62259. +
  62260. +#define HW_PXP_VERSION (0x00000430)
  62261. +
  62262. +#define BP_PXP_VERSION_MAJOR 24
  62263. +#define BM_PXP_VERSION_MAJOR 0xFF000000
  62264. +#define BF_PXP_VERSION_MAJOR(v) \
  62265. + (((v) << 24) & BM_PXP_VERSION_MAJOR)
  62266. +#define BP_PXP_VERSION_MINOR 16
  62267. +#define BM_PXP_VERSION_MINOR 0x00FF0000
  62268. +#define BF_PXP_VERSION_MINOR(v) \
  62269. + (((v) << 16) & BM_PXP_VERSION_MINOR)
  62270. +#define BP_PXP_VERSION_STEP 0
  62271. +#define BM_PXP_VERSION_STEP 0x0000FFFF
  62272. +#define BF_PXP_VERSION_STEP(v) \
  62273. + (((v) << 0) & BM_PXP_VERSION_STEP)
  62274. +#endif /* __ARCH_ARM___PXP_H */
  62275. diff -Nur linux-3.14.14/drivers/gpio/gpio-pca953x.c linux-imx6-3.14/drivers/gpio/gpio-pca953x.c
  62276. --- linux-3.14.14/drivers/gpio/gpio-pca953x.c 2014-07-28 10:07:25.000000000 -0500
  62277. +++ linux-imx6-3.14/drivers/gpio/gpio-pca953x.c 2014-12-08 00:31:52.600418001 -0600
  62278. @@ -19,6 +19,7 @@
  62279. #include <linux/irqdomain.h>
  62280. #include <linux/i2c.h>
  62281. #include <linux/platform_data/pca953x.h>
  62282. +#include <linux/reset.h>
  62283. #include <linux/slab.h>
  62284. #ifdef CONFIG_OF_GPIO
  62285. #include <linux/of_platform.h>
  62286. @@ -741,6 +742,10 @@
  62287. mutex_init(&chip->i2c_lock);
  62288. + ret = device_reset(&client->dev);
  62289. + if (ret == -ENODEV)
  62290. + return -EPROBE_DEFER;
  62291. +
  62292. /* initialize cached registers from their original values.
  62293. * we can't share this chip with another i2c master.
  62294. */
  62295. diff -Nur linux-3.14.14/drivers/gpu/drm/drm_crtc_helper.c linux-imx6-3.14/drivers/gpu/drm/drm_crtc_helper.c
  62296. --- linux-3.14.14/drivers/gpu/drm/drm_crtc_helper.c 2014-07-28 10:07:25.000000000 -0500
  62297. +++ linux-imx6-3.14/drivers/gpu/drm/drm_crtc_helper.c 2014-12-08 00:31:52.608418001 -0600
  62298. @@ -564,7 +564,7 @@
  62299. * Caller must hold mode config lock.
  62300. *
  62301. * Setup a new configuration, provided by the upper layers (either an ioctl call
  62302. - * from userspace or internally e.g. from the fbdev suppport code) in @set, and
  62303. + * from userspace or internally e.g. from the fbdev support code) in @set, and
  62304. * enable it. This is the main helper functions for drivers that implement
  62305. * kernel mode setting with the crtc helper functions and the assorted
  62306. * ->prepare(), ->modeset() and ->commit() helper callbacks.
  62307. diff -Nur linux-3.14.14/drivers/gpu/drm/drm_prime.c linux-imx6-3.14/drivers/gpu/drm/drm_prime.c
  62308. --- linux-3.14.14/drivers/gpu/drm/drm_prime.c 2014-07-28 10:07:25.000000000 -0500
  62309. +++ linux-imx6-3.14/drivers/gpu/drm/drm_prime.c 2014-12-08 00:31:52.612418001 -0600
  62310. @@ -471,7 +471,7 @@
  62311. get_dma_buf(dma_buf);
  62312. sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
  62313. - if (IS_ERR_OR_NULL(sgt)) {
  62314. + if (IS_ERR(sgt)) {
  62315. ret = PTR_ERR(sgt);
  62316. goto fail_detach;
  62317. }
  62318. diff -Nur linux-3.14.14/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c linux-imx6-3.14/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
  62319. --- linux-3.14.14/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 2014-07-28 10:07:25.000000000 -0500
  62320. +++ linux-imx6-3.14/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 2014-12-08 00:31:52.616418001 -0600
  62321. @@ -224,7 +224,7 @@
  62322. get_dma_buf(dma_buf);
  62323. sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
  62324. - if (IS_ERR_OR_NULL(sgt)) {
  62325. + if (IS_ERR(sgt)) {
  62326. ret = PTR_ERR(sgt);
  62327. goto err_buf_detach;
  62328. }
  62329. diff -Nur linux-3.14.14/drivers/gpu/drm/Kconfig linux-imx6-3.14/drivers/gpu/drm/Kconfig
  62330. --- linux-3.14.14/drivers/gpu/drm/Kconfig 2014-07-28 10:07:25.000000000 -0500
  62331. +++ linux-imx6-3.14/drivers/gpu/drm/Kconfig 2014-12-08 00:31:52.604418001 -0600
  62332. @@ -166,6 +166,13 @@
  62333. Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
  62334. chipset. If M is selected the module will be called savage.
  62335. +config DRM_VIVANTE
  62336. + tristate "Vivante GCCore"
  62337. + depends on DRM
  62338. + help
  62339. + Choose this option if you have a Vivante graphics card.
  62340. + If M is selected, the module will be called vivante.
  62341. +
  62342. source "drivers/gpu/drm/exynos/Kconfig"
  62343. source "drivers/gpu/drm/vmwgfx/Kconfig"
  62344. diff -Nur linux-3.14.14/drivers/gpu/drm/Makefile linux-imx6-3.14/drivers/gpu/drm/Makefile
  62345. --- linux-3.14.14/drivers/gpu/drm/Makefile 2014-07-28 10:07:25.000000000 -0500
  62346. +++ linux-imx6-3.14/drivers/gpu/drm/Makefile 2014-12-08 00:31:52.604418001 -0600
  62347. @@ -1,3 +1,24 @@
  62348. +##############################################################################
  62349. +#
  62350. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  62351. +#
  62352. +# This program is free software; you can redistribute it and/or modify
  62353. +# it under the terms of the GNU General Public License as published by
  62354. +# the Free Software Foundation; either version 2 of the license, or
  62355. +# (at your option) any later version.
  62356. +#
  62357. +# This program is distributed in the hope that it will be useful,
  62358. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  62359. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  62360. +# GNU General Public License for more details.
  62361. +#
  62362. +# You should have received a copy of the GNU General Public License
  62363. +# along with this program; if not write to the Free Software
  62364. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  62365. +#
  62366. +##############################################################################
  62367. +
  62368. +
  62369. #
  62370. # Makefile for the drm device driver. This driver provides support for the
  62371. # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
  62372. @@ -35,6 +56,7 @@
  62373. obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
  62374. obj-$(CONFIG_DRM_USB) += drm_usb.o
  62375. obj-$(CONFIG_DRM_TTM) += ttm/
  62376. +obj-$(CONFIG_DRM_VIVANTE) += vivante/
  62377. obj-$(CONFIG_DRM_TDFX) += tdfx/
  62378. obj-$(CONFIG_DRM_R128) += r128/
  62379. obj-$(CONFIG_DRM_RADEON)+= radeon/
  62380. diff -Nur linux-3.14.14/drivers/gpu/drm/vivante/Makefile linux-imx6-3.14/drivers/gpu/drm/vivante/Makefile
  62381. --- linux-3.14.14/drivers/gpu/drm/vivante/Makefile 1969-12-31 18:00:00.000000000 -0600
  62382. +++ linux-imx6-3.14/drivers/gpu/drm/vivante/Makefile 2014-12-08 00:31:52.828418001 -0600
  62383. @@ -0,0 +1,29 @@
  62384. +##############################################################################
  62385. +#
  62386. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  62387. +#
  62388. +# This program is free software; you can redistribute it and/or modify
  62389. +# it under the terms of the GNU General Public License as published by
  62390. +# the Free Software Foundation; either version 2 of the license, or
  62391. +# (at your option) any later version.
  62392. +#
  62393. +# This program is distributed in the hope that it will be useful,
  62394. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  62395. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  62396. +# GNU General Public License for more details.
  62397. +#
  62398. +# You should have received a copy of the GNU General Public License
  62399. +# along with this program; if not write to the Free Software
  62400. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  62401. +#
  62402. +##############################################################################
  62403. +
  62404. +
  62405. +#
  62406. +# Makefile for the drm device driver. This driver provides support for the
  62407. +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
  62408. +
  62409. +ccflags-y := -Iinclude/drm
  62410. +vivante-y := vivante_drv.o
  62411. +
  62412. +obj-$(CONFIG_DRM_VIVANTE) += vivante.o
  62413. diff -Nur linux-3.14.14/drivers/gpu/drm/vivante/vivante_drv.c linux-imx6-3.14/drivers/gpu/drm/vivante/vivante_drv.c
  62414. --- linux-3.14.14/drivers/gpu/drm/vivante/vivante_drv.c 1969-12-31 18:00:00.000000000 -0600
  62415. +++ linux-imx6-3.14/drivers/gpu/drm/vivante/vivante_drv.c 2014-12-08 00:31:52.828418001 -0600
  62416. @@ -0,0 +1,108 @@
  62417. +/****************************************************************************
  62418. +*
  62419. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  62420. +*
  62421. +* This program is free software; you can redistribute it and/or modify
  62422. +* it under the terms of the GNU General Public License as published by
  62423. +* the Free Software Foundation; either version 2 of the license, or
  62424. +* (at your option) any later version.
  62425. +*
  62426. +* This program is distributed in the hope that it will be useful,
  62427. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  62428. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  62429. +* GNU General Public License for more details.
  62430. +*
  62431. +* You should have received a copy of the GNU General Public License
  62432. +* along with this program; if not write to the Free Software
  62433. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  62434. +*
  62435. +*****************************************************************************/
  62436. +
  62437. +
  62438. +/* vivante_drv.c -- vivante driver -*- linux-c -*-
  62439. + *
  62440. + *
  62441. + * Permission is hereby granted, free of charge, to any person obtaining a
  62442. + * copy of this software and associated documentation files (the "Software"),
  62443. + * to deal in the Software without restriction, including without limitation
  62444. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  62445. + * and/or sell copies of the Software, and to permit persons to whom the
  62446. + * Software is furnished to do so, subject to the following conditions:
  62447. + *
  62448. + * The above copyright notice and this permission notice (including the next
  62449. + * paragraph) shall be included in all copies or substantial portions of the
  62450. + * Software.
  62451. + *
  62452. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  62453. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  62454. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  62455. + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  62456. + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  62457. + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  62458. + * DEALINGS IN THE SOFTWARE.
  62459. + *
  62460. + * Authors:
  62461. + * Rickard E. (Rik) Faith <faith@valinux.com>
  62462. + * Daryll Strauss <daryll@valinux.com>
  62463. + * Gareth Hughes <gareth@valinux.com>
  62464. + */
  62465. +
  62466. +#include <linux/version.h>
  62467. +#include <linux/module.h>
  62468. +
  62469. +#include "drmP.h"
  62470. +#include "vivante_drv.h"
  62471. +
  62472. +#include "drm_pciids.h"
  62473. +
  62474. +static char platformdevicename[] = "Vivante GCCore";
  62475. +static struct platform_device *pplatformdev;
  62476. +
  62477. +static const struct file_operations viv_driver_fops = {
  62478. + .owner = THIS_MODULE,
  62479. + .open = drm_open,
  62480. + .release = drm_release,
  62481. + .unlocked_ioctl = drm_ioctl,
  62482. + .mmap = drm_mmap,
  62483. + .poll = drm_poll,
  62484. + .llseek = noop_llseek,
  62485. +};
  62486. +
  62487. +static struct drm_driver driver = {
  62488. + .fops = &viv_driver_fops,
  62489. + .name = DRIVER_NAME,
  62490. + .desc = DRIVER_DESC,
  62491. + .date = DRIVER_DATE,
  62492. + .major = DRIVER_MAJOR,
  62493. + .minor = DRIVER_MINOR,
  62494. + .patchlevel = DRIVER_PATCHLEVEL,
  62495. +};
  62496. +
  62497. +static int __init vivante_init(void)
  62498. +{
  62499. + int retcode;
  62500. +
  62501. + pplatformdev = platform_device_register_simple(platformdevicename,
  62502. + -1, NULL, 0);
  62503. + if (pplatformdev == NULL)
  62504. + printk(KERN_ERR"Platform device is null\n");
  62505. +
  62506. + retcode = drm_platform_init(&driver, pplatformdev);
  62507. +
  62508. + return retcode;
  62509. +}
  62510. +
  62511. +static void __exit vivante_exit(void)
  62512. +{
  62513. + if (pplatformdev) {
  62514. + platform_device_unregister(pplatformdev);
  62515. + pplatformdev = NULL;
  62516. + }
  62517. +}
  62518. +
  62519. +module_init(vivante_init);
  62520. +module_exit(vivante_exit);
  62521. +
  62522. +MODULE_AUTHOR(DRIVER_AUTHOR);
  62523. +MODULE_DESCRIPTION(DRIVER_DESC);
  62524. +MODULE_LICENSE("GPL and additional rights");
  62525. diff -Nur linux-3.14.14/drivers/gpu/drm/vivante/vivante_drv.h linux-imx6-3.14/drivers/gpu/drm/vivante/vivante_drv.h
  62526. --- linux-3.14.14/drivers/gpu/drm/vivante/vivante_drv.h 1969-12-31 18:00:00.000000000 -0600
  62527. +++ linux-imx6-3.14/drivers/gpu/drm/vivante/vivante_drv.h 2014-12-08 00:31:52.828418001 -0600
  62528. @@ -0,0 +1,66 @@
  62529. +/****************************************************************************
  62530. +*
  62531. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  62532. +*
  62533. +* This program is free software; you can redistribute it and/or modify
  62534. +* it under the terms of the GNU General Public License as published by
  62535. +* the Free Software Foundation; either version 2 of the license, or
  62536. +* (at your option) any later version.
  62537. +*
  62538. +* This program is distributed in the hope that it will be useful,
  62539. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  62540. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  62541. +* GNU General Public License for more details.
  62542. +*
  62543. +* You should have received a copy of the GNU General Public License
  62544. +* along with this program; if not write to the Free Software
  62545. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  62546. +*
  62547. +*****************************************************************************/
  62548. +
  62549. +
  62550. +/* vivante_drv.h -- Vivante DRM template customization -*- linux-c -*-
  62551. + * Created: Wed Feb 14 12:32:32 2012 by John Zhao
  62552. + */
  62553. +/*
  62554. + *
  62555. + * Permission is hereby granted, free of charge, to any person obtaining a
  62556. + * copy of this software and associated documentation files (the "Software"),
  62557. + * to deal in the Software without restriction, including without limitation
  62558. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  62559. + * and/or sell copies of the Software, and to permit persons to whom the
  62560. + * Software is furnished to do so, subject to the following conditions:
  62561. + *
  62562. + * The above copyright notice and this permission notice (including the next
  62563. + * paragraph) shall be included in all copies or substantial portions of the
  62564. + * Software.
  62565. + *
  62566. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  62567. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  62568. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  62569. + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  62570. + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  62571. + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  62572. + * OTHER DEALINGS IN THE SOFTWARE.
  62573. + *
  62574. + * Authors:
  62575. + * Gareth Hughes <gareth@valinux.com>
  62576. + */
  62577. +
  62578. +#ifndef __VIVANTE_DRV_H__
  62579. +#define __VIVANTE_DRV_H__
  62580. +
  62581. +/* General customization:
  62582. + */
  62583. +
  62584. +#define DRIVER_AUTHOR "Vivante Inc."
  62585. +
  62586. +#define DRIVER_NAME "vivante"
  62587. +#define DRIVER_DESC "Vivante GCCore"
  62588. +#define DRIVER_DATE "20120216"
  62589. +
  62590. +#define DRIVER_MAJOR 1
  62591. +#define DRIVER_MINOR 0
  62592. +#define DRIVER_PATCHLEVEL 0
  62593. +
  62594. +#endif
  62595. diff -Nur linux-3.14.14/drivers/hwmon/Kconfig linux-imx6-3.14/drivers/hwmon/Kconfig
  62596. --- linux-3.14.14/drivers/hwmon/Kconfig 2014-07-28 10:07:25.000000000 -0500
  62597. +++ linux-imx6-3.14/drivers/hwmon/Kconfig 2014-12-08 00:31:52.852418001 -0600
  62598. @@ -1584,4 +1584,19 @@
  62599. endif # ACPI
  62600. +config SENSORS_MAG3110
  62601. + tristate "Freescale MAG3110 e-compass sensor"
  62602. + depends on I2C && SYSFS
  62603. + help
  62604. + If you say yes here you get support for the Freescale MAG3110
  62605. + e-compass sensor.
  62606. + This driver can also be built as a module. If so, the module
  62607. + will be called mag3110.
  62608. +
  62609. +config MXC_MMA8451
  62610. + tristate "MMA8451 device driver"
  62611. + depends on I2C
  62612. + depends on INPUT_POLLDEV
  62613. + default y
  62614. +
  62615. endif # HWMON
  62616. diff -Nur linux-3.14.14/drivers/hwmon/mag3110.c linux-imx6-3.14/drivers/hwmon/mag3110.c
  62617. --- linux-3.14.14/drivers/hwmon/mag3110.c 1969-12-31 18:00:00.000000000 -0600
  62618. +++ linux-imx6-3.14/drivers/hwmon/mag3110.c 2014-12-08 00:31:52.868418001 -0600
  62619. @@ -0,0 +1,611 @@
  62620. +/*
  62621. + *
  62622. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  62623. + *
  62624. + * This program is free software; you can redistribute it and/or modify
  62625. + * it under the terms of the GNU General Public License as published by
  62626. + * the Free Software Foundation; either version 2 of the License, or
  62627. + * (at your option) any later version.
  62628. +
  62629. + * This program is distributed in the hope that it will be useful,
  62630. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  62631. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  62632. + * GNU General Public License for more details.
  62633. +
  62634. + * You should have received a copy of the GNU General Public License along
  62635. + * with this program; if not, write to the Free Software Foundation, Inc.,
  62636. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  62637. + */
  62638. +
  62639. +#include <linux/module.h>
  62640. +#include <linux/kernel.h>
  62641. +#include <linux/slab.h>
  62642. +#include <linux/interrupt.h>
  62643. +#include <linux/delay.h>
  62644. +#include <linux/i2c.h>
  62645. +#include <linux/irq.h>
  62646. +#include <linux/platform_device.h>
  62647. +#include <linux/input-polldev.h>
  62648. +#include <linux/hwmon.h>
  62649. +#include <linux/input.h>
  62650. +#include <linux/wait.h>
  62651. +#include <linux/workqueue.h>
  62652. +#include <linux/of.h>
  62653. +#include <linux/regulator/consumer.h>
  62654. +
  62655. +#define MAG3110_DRV_NAME "mag3110"
  62656. +#define MAG3110_ID 0xC4
  62657. +#define MAG3110_XYZ_DATA_LEN 6
  62658. +#define MAG3110_STATUS_ZYXDR 0x08
  62659. +
  62660. +#define MAG3110_AC_MASK (0x01)
  62661. +#define MAG3110_AC_OFFSET 0
  62662. +#define MAG3110_DR_MODE_MASK (0x7 << 5)
  62663. +#define MAG3110_DR_MODE_OFFSET 5
  62664. +#define MAG3110_IRQ_USED 0
  62665. +
  62666. +#define POLL_INTERVAL_MAX 500
  62667. +#define POLL_INTERVAL 100
  62668. +#define INT_TIMEOUT 1000
  62669. +#define DEFAULT_POSITION 2
  62670. +/* register enum for mag3110 registers */
  62671. +enum {
  62672. + MAG3110_DR_STATUS = 0x00,
  62673. + MAG3110_OUT_X_MSB,
  62674. + MAG3110_OUT_X_LSB,
  62675. + MAG3110_OUT_Y_MSB,
  62676. + MAG3110_OUT_Y_LSB,
  62677. + MAG3110_OUT_Z_MSB,
  62678. + MAG3110_OUT_Z_LSB,
  62679. + MAG3110_WHO_AM_I,
  62680. +
  62681. + MAG3110_OFF_X_MSB,
  62682. + MAG3110_OFF_X_LSB,
  62683. + MAG3110_OFF_Y_MSB,
  62684. + MAG3110_OFF_Y_LSB,
  62685. + MAG3110_OFF_Z_MSB,
  62686. + MAG3110_OFF_Z_LSB,
  62687. +
  62688. + MAG3110_DIE_TEMP,
  62689. +
  62690. + MAG3110_CTRL_REG1 = 0x10,
  62691. + MAG3110_CTRL_REG2,
  62692. +};
  62693. +enum {
  62694. + MAG_STANDBY,
  62695. + MAG_ACTIVED
  62696. +};
  62697. +struct mag3110_data {
  62698. + struct i2c_client *client;
  62699. + struct input_polled_dev *poll_dev;
  62700. + struct device *hwmon_dev;
  62701. + wait_queue_head_t waitq;
  62702. + bool data_ready;
  62703. + u8 ctl_reg1;
  62704. + int active;
  62705. + int position;
  62706. +};
  62707. +static short MAGHAL[8][3][3] = {
  62708. + { {0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
  62709. + { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} },
  62710. + { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} },
  62711. + { {-1, 0, 0}, {0, -1, 0}, {0, 0, 1} },
  62712. +
  62713. + { {0, 1, 0}, {1, 0, 0}, {0, 0, -1} },
  62714. + { {1, 0, 0}, {0, -1, 0}, {0, 0, -1} },
  62715. + { {0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
  62716. + { {-1, 0, 0}, {0, 1, 0}, {0, 0, -1} },
  62717. +};
  62718. +
  62719. +static struct mag3110_data *mag3110_pdata;
  62720. +/*!
  62721. + * This function do one mag3110 register read.
  62722. + */
  62723. +static DEFINE_MUTEX(mag3110_lock);
  62724. +static int mag3110_adjust_position(short *x, short *y, short *z)
  62725. +{
  62726. + short rawdata[3], data[3];
  62727. + int i, j;
  62728. + int position = mag3110_pdata->position;
  62729. + if (position < 0 || position > 7)
  62730. + position = 0;
  62731. + rawdata[0] = *x;
  62732. + rawdata[1] = *y;
  62733. + rawdata[2] = *z;
  62734. + for (i = 0; i < 3; i++) {
  62735. + data[i] = 0;
  62736. + for (j = 0; j < 3; j++)
  62737. + data[i] += rawdata[j] * MAGHAL[position][i][j];
  62738. + }
  62739. + *x = data[0];
  62740. + *y = data[1];
  62741. + *z = data[2];
  62742. + return 0;
  62743. +}
  62744. +
  62745. +static int mag3110_read_reg(struct i2c_client *client, u8 reg)
  62746. +{
  62747. + return i2c_smbus_read_byte_data(client, reg);
  62748. +}
  62749. +
  62750. +/*!
  62751. + * This function do one mag3110 register write.
  62752. + */
  62753. +static int mag3110_write_reg(struct i2c_client *client, u8 reg, char value)
  62754. +{
  62755. + int ret;
  62756. +
  62757. + ret = i2c_smbus_write_byte_data(client, reg, value);
  62758. + if (ret < 0)
  62759. + dev_err(&client->dev, "i2c write failed\n");
  62760. + return ret;
  62761. +}
  62762. +
  62763. +/*!
  62764. + * This function do multiple mag3110 registers read.
  62765. + */
  62766. +static int mag3110_read_block_data(struct i2c_client *client, u8 reg,
  62767. + int count, u8 *addr)
  62768. +{
  62769. + if (i2c_smbus_read_i2c_block_data(client, reg, count, addr) < count) {
  62770. + dev_err(&client->dev, "i2c block read failed\n");
  62771. + return -1;
  62772. + }
  62773. +
  62774. + return count;
  62775. +}
  62776. +
  62777. +/*
  62778. + * Initialization function
  62779. + */
  62780. +static int mag3110_init_client(struct i2c_client *client)
  62781. +{
  62782. + int val, ret;
  62783. +
  62784. + /* enable automatic resets */
  62785. + val = 0x80;
  62786. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG2, val);
  62787. +
  62788. + /* set default data rate to 10HZ */
  62789. + val = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  62790. + val |= (0x0 << MAG3110_DR_MODE_OFFSET);
  62791. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, val);
  62792. +
  62793. + return ret;
  62794. +}
  62795. +
  62796. +/***************************************************************
  62797. +*
  62798. +* read sensor data from mag3110
  62799. +*
  62800. +***************************************************************/
  62801. +static int mag3110_read_data(short *x, short *y, short *z)
  62802. +{
  62803. + struct mag3110_data *data;
  62804. + int retry = 3;
  62805. + u8 tmp_data[MAG3110_XYZ_DATA_LEN];
  62806. + int result;
  62807. + if (!mag3110_pdata || mag3110_pdata->active == MAG_STANDBY)
  62808. + return -EINVAL;
  62809. +
  62810. + data = mag3110_pdata;
  62811. +#if MAG3110_IRQ_USED
  62812. + if (!wait_event_interruptible_timeout
  62813. + (data->waitq, data->data_ready != 0,
  62814. + msecs_to_jiffies(INT_TIMEOUT))) {
  62815. + dev_dbg(&data->client->dev, "interrupt not received\n");
  62816. + return -ETIME;
  62817. + }
  62818. +#else
  62819. + do {
  62820. + msleep(1);
  62821. + result = i2c_smbus_read_byte_data(data->client,
  62822. + MAG3110_DR_STATUS);
  62823. + retry--;
  62824. + } while (!(result & MAG3110_STATUS_ZYXDR) && retry > 0);
  62825. + /* Clear data_ready flag after data is read out */
  62826. + if (retry == 0)
  62827. + return -EINVAL;
  62828. +#endif
  62829. +
  62830. + data->data_ready = 0;
  62831. +
  62832. + if (mag3110_read_block_data(data->client,
  62833. + MAG3110_OUT_X_MSB, MAG3110_XYZ_DATA_LEN,
  62834. + tmp_data) < 0)
  62835. + return -1;
  62836. +
  62837. + *x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
  62838. + *y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
  62839. + *z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
  62840. +
  62841. + return 0;
  62842. +}
  62843. +
  62844. +static void report_abs(void)
  62845. +{
  62846. + struct input_dev *idev;
  62847. + short x, y, z;
  62848. +
  62849. + mutex_lock(&mag3110_lock);
  62850. + if (mag3110_read_data(&x, &y, &z) != 0)
  62851. + goto out;
  62852. + mag3110_adjust_position(&x, &y, &z);
  62853. + idev = mag3110_pdata->poll_dev->input;
  62854. + input_report_abs(idev, ABS_X, x);
  62855. + input_report_abs(idev, ABS_Y, y);
  62856. + input_report_abs(idev, ABS_Z, z);
  62857. + input_sync(idev);
  62858. +out:
  62859. + mutex_unlock(&mag3110_lock);
  62860. +}
  62861. +
  62862. +static void mag3110_dev_poll(struct input_polled_dev *dev)
  62863. +{
  62864. + report_abs();
  62865. +}
  62866. +
  62867. +#if MAG3110_IRQ_USED
  62868. +static irqreturn_t mag3110_irq_handler(int irq, void *dev_id)
  62869. +{
  62870. + mag3110_pdata->data_ready = 1;
  62871. + wake_up_interruptible(&mag3110_pdata->waitq);
  62872. +
  62873. + return IRQ_HANDLED;
  62874. +}
  62875. +#endif
  62876. +static ssize_t mag3110_enable_show(struct device *dev,
  62877. + struct device_attribute *attr, char *buf)
  62878. +{
  62879. + struct i2c_client *client;
  62880. + int val;
  62881. + mutex_lock(&mag3110_lock);
  62882. + client = mag3110_pdata->client;
  62883. + val = mag3110_read_reg(client, MAG3110_CTRL_REG1) & MAG3110_AC_MASK;
  62884. +
  62885. + mutex_unlock(&mag3110_lock);
  62886. + return sprintf(buf, "%d\n", val);
  62887. +}
  62888. +
  62889. +static ssize_t mag3110_enable_store(struct device *dev,
  62890. + struct device_attribute *attr,
  62891. + const char *buf, size_t count)
  62892. +{
  62893. + struct i2c_client *client;
  62894. + int reg, ret;
  62895. + long enable;
  62896. + u8 tmp_data[MAG3110_XYZ_DATA_LEN];
  62897. +
  62898. + ret = strict_strtol(buf, 10, &enable);
  62899. + if (ret) {
  62900. + dev_err(dev, "string to long error\n");
  62901. + return ret;
  62902. + }
  62903. +
  62904. + mutex_lock(&mag3110_lock);
  62905. + client = mag3110_pdata->client;
  62906. + reg = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  62907. + if (enable && mag3110_pdata->active == MAG_STANDBY) {
  62908. + reg |= MAG3110_AC_MASK;
  62909. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
  62910. + if (!ret)
  62911. + mag3110_pdata->active = MAG_ACTIVED;
  62912. + } else if (!enable && mag3110_pdata->active == MAG_ACTIVED) {
  62913. + reg &= ~MAG3110_AC_MASK;
  62914. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
  62915. + if (!ret)
  62916. + mag3110_pdata->active = MAG_STANDBY;
  62917. + }
  62918. +
  62919. + if (mag3110_pdata->active == MAG_ACTIVED) {
  62920. + msleep(100);
  62921. + /* Read out MSB data to clear interrupt flag automatically */
  62922. + mag3110_read_block_data(client, MAG3110_OUT_X_MSB,
  62923. + MAG3110_XYZ_DATA_LEN, tmp_data);
  62924. + }
  62925. + mutex_unlock(&mag3110_lock);
  62926. + return count;
  62927. +}
  62928. +
  62929. +static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
  62930. + mag3110_enable_show, mag3110_enable_store);
  62931. +
  62932. +static ssize_t mag3110_dr_mode_show(struct device *dev,
  62933. + struct device_attribute *attr, char *buf)
  62934. +{
  62935. + struct i2c_client *client;
  62936. + int val;
  62937. +
  62938. + client = mag3110_pdata->client;
  62939. + val = (mag3110_read_reg(client, MAG3110_CTRL_REG1)
  62940. + & MAG3110_DR_MODE_MASK) >> MAG3110_DR_MODE_OFFSET;
  62941. +
  62942. + return sprintf(buf, "%d\n", val);
  62943. +}
  62944. +
  62945. +static ssize_t mag3110_dr_mode_store(struct device *dev,
  62946. + struct device_attribute *attr,
  62947. + const char *buf, size_t count)
  62948. +{
  62949. + struct i2c_client *client;
  62950. + int reg, ret;
  62951. + unsigned long val;
  62952. +
  62953. + /* This must be done when mag3110 is disabled */
  62954. + if ((strict_strtoul(buf, 10, &val) < 0) || (val > 7))
  62955. + return -EINVAL;
  62956. +
  62957. + client = mag3110_pdata->client;
  62958. + reg = mag3110_read_reg(client, MAG3110_CTRL_REG1) &
  62959. + ~MAG3110_DR_MODE_MASK;
  62960. + reg |= (val << MAG3110_DR_MODE_OFFSET);
  62961. + /* MAG3110_CTRL_REG1 bit 5-7: data rate mode */
  62962. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
  62963. + if (ret < 0)
  62964. + return ret;
  62965. +
  62966. + return count;
  62967. +}
  62968. +
  62969. +static DEVICE_ATTR(dr_mode, S_IWUSR | S_IRUGO,
  62970. + mag3110_dr_mode_show, mag3110_dr_mode_store);
  62971. +
  62972. +static ssize_t mag3110_position_show(struct device *dev,
  62973. + struct device_attribute *attr, char *buf)
  62974. +{
  62975. + int val;
  62976. + mutex_lock(&mag3110_lock);
  62977. + val = mag3110_pdata->position;
  62978. + mutex_unlock(&mag3110_lock);
  62979. + return sprintf(buf, "%d\n", val);
  62980. +}
  62981. +
  62982. +static ssize_t mag3110_position_store(struct device *dev,
  62983. + struct device_attribute *attr,
  62984. + const char *buf, size_t count)
  62985. +{
  62986. + long position;
  62987. + int ret;
  62988. + ret = strict_strtol(buf, 10, &position);
  62989. + if (ret) {
  62990. + dev_err(dev, "string to long error\n");
  62991. + return ret;
  62992. + }
  62993. +
  62994. + mutex_lock(&mag3110_lock);
  62995. + mag3110_pdata->position = (int)position;
  62996. + mutex_unlock(&mag3110_lock);
  62997. + return count;
  62998. +}
  62999. +
  63000. +static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
  63001. + mag3110_position_show, mag3110_position_store);
  63002. +
  63003. +static struct attribute *mag3110_attributes[] = {
  63004. + &dev_attr_enable.attr,
  63005. + &dev_attr_dr_mode.attr,
  63006. + &dev_attr_position.attr,
  63007. + NULL
  63008. +};
  63009. +
  63010. +static const struct attribute_group mag3110_attr_group = {
  63011. + .attrs = mag3110_attributes,
  63012. +};
  63013. +
  63014. +static int mag3110_probe(struct i2c_client *client,
  63015. + const struct i2c_device_id *id)
  63016. +{
  63017. + struct i2c_adapter *adapter;
  63018. + struct input_dev *idev;
  63019. + struct mag3110_data *data;
  63020. + int ret = 0;
  63021. + struct regulator *vdd, *vdd_io;
  63022. + u32 pos = 0;
  63023. + struct device_node *of_node = client->dev.of_node;
  63024. + vdd = NULL;
  63025. + vdd_io = NULL;
  63026. +
  63027. + vdd = devm_regulator_get(&client->dev, "vdd");
  63028. + if (!IS_ERR(vdd)) {
  63029. + ret = regulator_enable(vdd);
  63030. + if (ret) {
  63031. + dev_err(&client->dev, "vdd set voltage error\n");
  63032. + return ret;
  63033. + }
  63034. + }
  63035. +
  63036. + vdd_io = devm_regulator_get(&client->dev, "vddio");
  63037. + if (!IS_ERR(vdd_io)) {
  63038. + ret = regulator_enable(vdd_io);
  63039. + if (ret) {
  63040. + dev_err(&client->dev, "vddio set voltage error\n");
  63041. + return ret;
  63042. + }
  63043. + }
  63044. +
  63045. + adapter = to_i2c_adapter(client->dev.parent);
  63046. + if (!i2c_check_functionality(adapter,
  63047. + I2C_FUNC_SMBUS_BYTE |
  63048. + I2C_FUNC_SMBUS_BYTE_DATA |
  63049. + I2C_FUNC_SMBUS_I2C_BLOCK))
  63050. + return -EIO;
  63051. +
  63052. + dev_info(&client->dev, "check mag3110 chip ID\n");
  63053. + ret = mag3110_read_reg(client, MAG3110_WHO_AM_I);
  63054. +
  63055. + if (MAG3110_ID != ret) {
  63056. + dev_err(&client->dev,
  63057. + "read chip ID 0x%x is not equal to 0x%x!\n", ret,
  63058. + MAG3110_ID);
  63059. + return -EINVAL;
  63060. + }
  63061. + data = kzalloc(sizeof(struct mag3110_data), GFP_KERNEL);
  63062. + if (!data)
  63063. + return -ENOMEM;
  63064. + data->client = client;
  63065. + i2c_set_clientdata(client, data);
  63066. + /* Init queue */
  63067. + init_waitqueue_head(&data->waitq);
  63068. +
  63069. + data->hwmon_dev = hwmon_device_register(&client->dev);
  63070. + if (IS_ERR(data->hwmon_dev)) {
  63071. + dev_err(&client->dev, "hwmon register failed!\n");
  63072. + ret = PTR_ERR(data->hwmon_dev);
  63073. + goto error_rm_dev_sysfs;
  63074. + }
  63075. +
  63076. + /*input poll device register */
  63077. + data->poll_dev = input_allocate_polled_device();
  63078. + if (!data->poll_dev) {
  63079. + dev_err(&client->dev, "alloc poll device failed!\n");
  63080. + ret = -ENOMEM;
  63081. + goto error_rm_hwmon_dev;
  63082. + }
  63083. + data->poll_dev->poll = mag3110_dev_poll;
  63084. + data->poll_dev->poll_interval = POLL_INTERVAL;
  63085. + data->poll_dev->poll_interval_max = POLL_INTERVAL_MAX;
  63086. + idev = data->poll_dev->input;
  63087. + idev->name = MAG3110_DRV_NAME;
  63088. + idev->id.bustype = BUS_I2C;
  63089. + idev->evbit[0] = BIT_MASK(EV_ABS);
  63090. + input_set_abs_params(idev, ABS_X, -15000, 15000, 0, 0);
  63091. + input_set_abs_params(idev, ABS_Y, -15000, 15000, 0, 0);
  63092. + input_set_abs_params(idev, ABS_Z, -15000, 15000, 0, 0);
  63093. + ret = input_register_polled_device(data->poll_dev);
  63094. + if (ret) {
  63095. + dev_err(&client->dev, "register poll device failed!\n");
  63096. + goto error_free_poll_dev;
  63097. + }
  63098. +
  63099. + /*create device group in sysfs as user interface */
  63100. + ret = sysfs_create_group(&idev->dev.kobj, &mag3110_attr_group);
  63101. + if (ret) {
  63102. + dev_err(&client->dev, "create device file failed!\n");
  63103. + ret = -EINVAL;
  63104. + goto error_rm_poll_dev;
  63105. + }
  63106. + /* set irq type to edge rising */
  63107. +#if MAG3110_IRQ_USED
  63108. + ret = request_irq(client->irq, mag3110_irq_handler,
  63109. + IRQF_TRIGGER_RISING, client->dev.driver->name, idev);
  63110. + if (ret < 0) {
  63111. + dev_err(&client->dev, "failed to register irq %d!\n",
  63112. + client->irq);
  63113. + goto error_rm_dev_sysfs;
  63114. + }
  63115. +#endif
  63116. + /* Initialize mag3110 chip */
  63117. + mag3110_init_client(client);
  63118. + mag3110_pdata = data;
  63119. + mag3110_pdata->active = MAG_STANDBY;
  63120. + ret = of_property_read_u32(of_node, "position", &pos);
  63121. + if (ret)
  63122. + pos = DEFAULT_POSITION;
  63123. + mag3110_pdata->position = (int)pos;
  63124. + dev_info(&client->dev, "mag3110 is probed\n");
  63125. + return 0;
  63126. +error_rm_dev_sysfs:
  63127. + sysfs_remove_group(&client->dev.kobj, &mag3110_attr_group);
  63128. +error_rm_poll_dev:
  63129. + input_unregister_polled_device(data->poll_dev);
  63130. +error_free_poll_dev:
  63131. + input_free_polled_device(data->poll_dev);
  63132. +error_rm_hwmon_dev:
  63133. + hwmon_device_unregister(data->hwmon_dev);
  63134. +
  63135. + kfree(data);
  63136. + mag3110_pdata = NULL;
  63137. +
  63138. + return ret;
  63139. +}
  63140. +
  63141. +static int mag3110_remove(struct i2c_client *client)
  63142. +{
  63143. + struct mag3110_data *data;
  63144. + int ret;
  63145. +
  63146. + data = i2c_get_clientdata(client);
  63147. +
  63148. + data->ctl_reg1 = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  63149. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
  63150. + data->ctl_reg1 & ~MAG3110_AC_MASK);
  63151. +
  63152. + free_irq(client->irq, data);
  63153. + input_unregister_polled_device(data->poll_dev);
  63154. + input_free_polled_device(data->poll_dev);
  63155. + hwmon_device_unregister(data->hwmon_dev);
  63156. + sysfs_remove_group(&client->dev.kobj, &mag3110_attr_group);
  63157. + kfree(data);
  63158. + mag3110_pdata = NULL;
  63159. +
  63160. + return ret;
  63161. +}
  63162. +
  63163. +#ifdef CONFIG_PM
  63164. +static int mag3110_suspend(struct i2c_client *client, pm_message_t mesg)
  63165. +{
  63166. + int ret = 0;
  63167. + struct mag3110_data *data = i2c_get_clientdata(client);
  63168. + if (data->active == MAG_ACTIVED) {
  63169. + data->ctl_reg1 = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  63170. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
  63171. + data->ctl_reg1 & ~MAG3110_AC_MASK);
  63172. + }
  63173. + return ret;
  63174. +}
  63175. +
  63176. +static int mag3110_resume(struct i2c_client *client)
  63177. +{
  63178. + int ret = 0;
  63179. + u8 tmp_data[MAG3110_XYZ_DATA_LEN];
  63180. + struct mag3110_data *data = i2c_get_clientdata(client);
  63181. + if (data->active == MAG_ACTIVED) {
  63182. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
  63183. + data->ctl_reg1);
  63184. +
  63185. + if (data->ctl_reg1 & MAG3110_AC_MASK) {
  63186. + /* Read out MSB data to clear interrupt
  63187. + flag automatically */
  63188. + mag3110_read_block_data(client, MAG3110_OUT_X_MSB,
  63189. + MAG3110_XYZ_DATA_LEN, tmp_data);
  63190. + }
  63191. + }
  63192. + return ret;
  63193. +}
  63194. +
  63195. +#else
  63196. +#define mag3110_suspend NULL
  63197. +#define mag3110_resume NULL
  63198. +#endif /* CONFIG_PM */
  63199. +
  63200. +static const struct i2c_device_id mag3110_id[] = {
  63201. + {MAG3110_DRV_NAME, 0},
  63202. + {}
  63203. +};
  63204. +
  63205. +MODULE_DEVICE_TABLE(i2c, mag3110_id);
  63206. +static struct i2c_driver mag3110_driver = {
  63207. + .driver = {.name = MAG3110_DRV_NAME,
  63208. + .owner = THIS_MODULE,},
  63209. + .suspend = mag3110_suspend,
  63210. + .resume = mag3110_resume,
  63211. + .probe = mag3110_probe,
  63212. + .remove = mag3110_remove,
  63213. + .id_table = mag3110_id,
  63214. +};
  63215. +
  63216. +static int __init mag3110_init(void)
  63217. +{
  63218. + return i2c_add_driver(&mag3110_driver);
  63219. +}
  63220. +
  63221. +static void __exit mag3110_exit(void)
  63222. +{
  63223. + i2c_del_driver(&mag3110_driver);
  63224. +}
  63225. +
  63226. +module_init(mag3110_init);
  63227. +module_exit(mag3110_exit);
  63228. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  63229. +MODULE_DESCRIPTION("Freescale mag3110 3-axis magnetometer driver");
  63230. +MODULE_LICENSE("GPL");
  63231. diff -Nur linux-3.14.14/drivers/hwmon/Makefile linux-imx6-3.14/drivers/hwmon/Makefile
  63232. --- linux-3.14.14/drivers/hwmon/Makefile 2014-07-28 10:07:25.000000000 -0500
  63233. +++ linux-imx6-3.14/drivers/hwmon/Makefile 2014-12-08 00:31:52.852418001 -0600
  63234. @@ -142,6 +142,8 @@
  63235. obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o
  63236. obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
  63237. obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
  63238. +obj-$(CONFIG_SENSORS_MAG3110) += mag3110.o
  63239. +obj-$(CONFIG_MXC_MMA8451) += mxc_mma8451.o
  63240. obj-$(CONFIG_PMBUS) += pmbus/
  63241. diff -Nur linux-3.14.14/drivers/hwmon/mxc_mma8451.c linux-imx6-3.14/drivers/hwmon/mxc_mma8451.c
  63242. --- linux-3.14.14/drivers/hwmon/mxc_mma8451.c 1969-12-31 18:00:00.000000000 -0600
  63243. +++ linux-imx6-3.14/drivers/hwmon/mxc_mma8451.c 2014-12-08 00:31:52.868418001 -0600
  63244. @@ -0,0 +1,598 @@
  63245. +/*
  63246. + * mma8451.c - Linux kernel modules for 3-Axis Orientation/Motion
  63247. + * Detection Sensor
  63248. + *
  63249. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  63250. + *
  63251. + * This program is free software; you can redistribute it and/or modify
  63252. + * it under the terms of the GNU General Public License as published by
  63253. + * the Free Software Foundation; either version 2 of the License, or
  63254. + * (at your option) any later version.
  63255. + *
  63256. + * This program is distributed in the hope that it will be useful,
  63257. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  63258. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  63259. + * GNU General Public License for more details.
  63260. + *
  63261. + * You should have received a copy of the GNU General Public License
  63262. + * along with this program; if not, write to the Free Software
  63263. + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  63264. + */
  63265. +
  63266. +#include <linux/module.h>
  63267. +#include <linux/init.h>
  63268. +#include <linux/slab.h>
  63269. +#include <linux/i2c.h>
  63270. +#include <linux/pm.h>
  63271. +#include <linux/mutex.h>
  63272. +#include <linux/delay.h>
  63273. +#include <linux/interrupt.h>
  63274. +#include <linux/irq.h>
  63275. +#include <linux/hwmon-sysfs.h>
  63276. +#include <linux/err.h>
  63277. +#include <linux/hwmon.h>
  63278. +#include <linux/input-polldev.h>
  63279. +#include <linux/of.h>
  63280. +#include <linux/regulator/consumer.h>
  63281. +
  63282. +#define MMA8451_I2C_ADDR 0x1C
  63283. +#define MMA8451_ID 0x1A
  63284. +#define MMA8452_ID 0x2A
  63285. +#define MMA8453_ID 0x3A
  63286. +
  63287. +#define POLL_INTERVAL_MIN 1
  63288. +#define POLL_INTERVAL_MAX 500
  63289. +#define POLL_INTERVAL 100 /* msecs */
  63290. +#define INPUT_FUZZ 32
  63291. +#define INPUT_FLAT 32
  63292. +#define MODE_CHANGE_DELAY_MS 100
  63293. +
  63294. +#define MMA8451_STATUS_ZYXDR 0x08
  63295. +#define MMA8451_BUF_SIZE 7
  63296. +#define DEFAULT_POSITION 0
  63297. +
  63298. +/* register enum for mma8451 registers */
  63299. +enum {
  63300. + MMA8451_STATUS = 0x00,
  63301. + MMA8451_OUT_X_MSB,
  63302. + MMA8451_OUT_X_LSB,
  63303. + MMA8451_OUT_Y_MSB,
  63304. + MMA8451_OUT_Y_LSB,
  63305. + MMA8451_OUT_Z_MSB,
  63306. + MMA8451_OUT_Z_LSB,
  63307. +
  63308. + MMA8451_F_SETUP = 0x09,
  63309. + MMA8451_TRIG_CFG,
  63310. + MMA8451_SYSMOD,
  63311. + MMA8451_INT_SOURCE,
  63312. + MMA8451_WHO_AM_I,
  63313. + MMA8451_XYZ_DATA_CFG,
  63314. + MMA8451_HP_FILTER_CUTOFF,
  63315. +
  63316. + MMA8451_PL_STATUS,
  63317. + MMA8451_PL_CFG,
  63318. + MMA8451_PL_COUNT,
  63319. + MMA8451_PL_BF_ZCOMP,
  63320. + MMA8451_P_L_THS_REG,
  63321. +
  63322. + MMA8451_FF_MT_CFG,
  63323. + MMA8451_FF_MT_SRC,
  63324. + MMA8451_FF_MT_THS,
  63325. + MMA8451_FF_MT_COUNT,
  63326. +
  63327. + MMA8451_TRANSIENT_CFG = 0x1D,
  63328. + MMA8451_TRANSIENT_SRC,
  63329. + MMA8451_TRANSIENT_THS,
  63330. + MMA8451_TRANSIENT_COUNT,
  63331. +
  63332. + MMA8451_PULSE_CFG,
  63333. + MMA8451_PULSE_SRC,
  63334. + MMA8451_PULSE_THSX,
  63335. + MMA8451_PULSE_THSY,
  63336. + MMA8451_PULSE_THSZ,
  63337. + MMA8451_PULSE_TMLT,
  63338. + MMA8451_PULSE_LTCY,
  63339. + MMA8451_PULSE_WIND,
  63340. +
  63341. + MMA8451_ASLP_COUNT,
  63342. + MMA8451_CTRL_REG1,
  63343. + MMA8451_CTRL_REG2,
  63344. + MMA8451_CTRL_REG3,
  63345. + MMA8451_CTRL_REG4,
  63346. + MMA8451_CTRL_REG5,
  63347. +
  63348. + MMA8451_OFF_X,
  63349. + MMA8451_OFF_Y,
  63350. + MMA8451_OFF_Z,
  63351. +
  63352. + MMA8451_REG_END,
  63353. +};
  63354. +
  63355. +/* The sensitivity is represented in counts/g. In 2g mode the
  63356. +sensitivity is 1024 counts/g. In 4g mode the sensitivity is 512
  63357. +counts/g and in 8g mode the sensitivity is 256 counts/g.
  63358. + */
  63359. +enum {
  63360. + MODE_2G = 0,
  63361. + MODE_4G,
  63362. + MODE_8G,
  63363. +};
  63364. +
  63365. +enum {
  63366. + MMA_STANDBY = 0,
  63367. + MMA_ACTIVED,
  63368. +};
  63369. +
  63370. +/* mma8451 status */
  63371. +struct mma8451_status {
  63372. + u8 mode;
  63373. + u8 ctl_reg1;
  63374. + int active;
  63375. + int position;
  63376. +};
  63377. +
  63378. +static struct mma8451_status mma_status;
  63379. +static struct input_polled_dev *mma8451_idev;
  63380. +static struct device *hwmon_dev;
  63381. +static struct i2c_client *mma8451_i2c_client;
  63382. +
  63383. +static int senstive_mode = MODE_2G;
  63384. +static int ACCHAL[8][3][3] = {
  63385. + { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} },
  63386. + { {-1, 0, 0}, {0, -1, 0}, {0, 0, 1} },
  63387. + { {0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
  63388. + { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} },
  63389. +
  63390. + { {0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
  63391. + { {-1, 0, 0}, {0, 1, 0}, {0, 0, -1} },
  63392. + { {0, 1, 0}, {1, 0, 0}, {0, 0, -1} },
  63393. + { {1, 0, 0}, {0, -1, 0}, {0, 0, -1} },
  63394. +};
  63395. +
  63396. +static DEFINE_MUTEX(mma8451_lock);
  63397. +static int mma8451_adjust_position(short *x, short *y, short *z)
  63398. +{
  63399. + short rawdata[3], data[3];
  63400. + int i, j;
  63401. + int position = mma_status.position;
  63402. + if (position < 0 || position > 7)
  63403. + position = 0;
  63404. + rawdata[0] = *x;
  63405. + rawdata[1] = *y;
  63406. + rawdata[2] = *z;
  63407. + for (i = 0; i < 3; i++) {
  63408. + data[i] = 0;
  63409. + for (j = 0; j < 3; j++)
  63410. + data[i] += rawdata[j] * ACCHAL[position][i][j];
  63411. + }
  63412. + *x = data[0];
  63413. + *y = data[1];
  63414. + *z = data[2];
  63415. + return 0;
  63416. +}
  63417. +
  63418. +static int mma8451_change_mode(struct i2c_client *client, int mode)
  63419. +{
  63420. + int result;
  63421. +
  63422. + mma_status.ctl_reg1 = 0;
  63423. + result = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, 0);
  63424. + if (result < 0)
  63425. + goto out;
  63426. + mma_status.active = MMA_STANDBY;
  63427. +
  63428. + result = i2c_smbus_write_byte_data(client, MMA8451_XYZ_DATA_CFG,
  63429. + mode);
  63430. + if (result < 0)
  63431. + goto out;
  63432. + mdelay(MODE_CHANGE_DELAY_MS);
  63433. + mma_status.mode = mode;
  63434. +
  63435. + return 0;
  63436. +out:
  63437. + dev_err(&client->dev, "error when init mma8451:(%d)", result);
  63438. + return result;
  63439. +}
  63440. +
  63441. +static int mma8451_read_data(short *x, short *y, short *z)
  63442. +{
  63443. + u8 tmp_data[MMA8451_BUF_SIZE];
  63444. + int ret;
  63445. +
  63446. + ret = i2c_smbus_read_i2c_block_data(mma8451_i2c_client,
  63447. + MMA8451_OUT_X_MSB, 7, tmp_data);
  63448. + if (ret < MMA8451_BUF_SIZE) {
  63449. + dev_err(&mma8451_i2c_client->dev, "i2c block read failed\n");
  63450. + return -EIO;
  63451. + }
  63452. +
  63453. + *x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
  63454. + *y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
  63455. + *z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
  63456. + return 0;
  63457. +}
  63458. +
  63459. +static void report_abs(void)
  63460. +{
  63461. + short x, y, z;
  63462. + int result;
  63463. + int retry = 3;
  63464. +
  63465. + mutex_lock(&mma8451_lock);
  63466. + if (mma_status.active == MMA_STANDBY)
  63467. + goto out;
  63468. + /* wait for the data ready */
  63469. + do {
  63470. + result = i2c_smbus_read_byte_data(mma8451_i2c_client,
  63471. + MMA8451_STATUS);
  63472. + retry--;
  63473. + msleep(1);
  63474. + } while (!(result & MMA8451_STATUS_ZYXDR) && retry > 0);
  63475. + if (retry == 0)
  63476. + goto out;
  63477. + if (mma8451_read_data(&x, &y, &z) != 0)
  63478. + goto out;
  63479. + mma8451_adjust_position(&x, &y, &z);
  63480. + input_report_abs(mma8451_idev->input, ABS_X, x);
  63481. + input_report_abs(mma8451_idev->input, ABS_Y, y);
  63482. + input_report_abs(mma8451_idev->input, ABS_Z, z);
  63483. + input_sync(mma8451_idev->input);
  63484. +out:
  63485. + mutex_unlock(&mma8451_lock);
  63486. +}
  63487. +
  63488. +static void mma8451_dev_poll(struct input_polled_dev *dev)
  63489. +{
  63490. + report_abs();
  63491. +}
  63492. +
  63493. +static ssize_t mma8451_enable_show(struct device *dev,
  63494. + struct device_attribute *attr, char *buf)
  63495. +{
  63496. + struct i2c_client *client;
  63497. + u8 val;
  63498. + int enable;
  63499. +
  63500. + mutex_lock(&mma8451_lock);
  63501. + client = mma8451_i2c_client;
  63502. + val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
  63503. + if ((val & 0x01) && mma_status.active == MMA_ACTIVED)
  63504. + enable = 1;
  63505. + else
  63506. + enable = 0;
  63507. + mutex_unlock(&mma8451_lock);
  63508. + return sprintf(buf, "%d\n", enable);
  63509. +}
  63510. +
  63511. +static ssize_t mma8451_enable_store(struct device *dev,
  63512. + struct device_attribute *attr,
  63513. + const char *buf, size_t count)
  63514. +{
  63515. + struct i2c_client *client;
  63516. + int ret;
  63517. + unsigned long enable;
  63518. + u8 val = 0;
  63519. +
  63520. + ret = strict_strtoul(buf, 10, &enable);
  63521. + if (ret) {
  63522. + dev_err(dev, "string transform error\n");
  63523. + return ret;
  63524. + }
  63525. +
  63526. + mutex_lock(&mma8451_lock);
  63527. + client = mma8451_i2c_client;
  63528. + enable = (enable > 0) ? 1 : 0;
  63529. + if (enable && mma_status.active == MMA_STANDBY) {
  63530. + val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
  63531. + ret =
  63532. + i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  63533. + val | 0x01);
  63534. + if (!ret)
  63535. + mma_status.active = MMA_ACTIVED;
  63536. +
  63537. + } else if (enable == 0 && mma_status.active == MMA_ACTIVED) {
  63538. + val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
  63539. + ret =
  63540. + i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  63541. + val & 0xFE);
  63542. + if (!ret)
  63543. + mma_status.active = MMA_STANDBY;
  63544. +
  63545. + }
  63546. + mutex_unlock(&mma8451_lock);
  63547. + return count;
  63548. +}
  63549. +
  63550. +static ssize_t mma8451_position_show(struct device *dev,
  63551. + struct device_attribute *attr, char *buf)
  63552. +{
  63553. + int position = 0;
  63554. + mutex_lock(&mma8451_lock);
  63555. + position = mma_status.position;
  63556. + mutex_unlock(&mma8451_lock);
  63557. + return sprintf(buf, "%d\n", position);
  63558. +}
  63559. +
  63560. +static ssize_t mma8451_position_store(struct device *dev,
  63561. + struct device_attribute *attr,
  63562. + const char *buf, size_t count)
  63563. +{
  63564. + unsigned long position;
  63565. + int ret;
  63566. + ret = strict_strtoul(buf, 10, &position);
  63567. + if (ret) {
  63568. + dev_err(dev, "string transform error\n");
  63569. + return ret;
  63570. + }
  63571. +
  63572. + mutex_lock(&mma8451_lock);
  63573. + mma_status.position = (int)position;
  63574. + mutex_unlock(&mma8451_lock);
  63575. + return count;
  63576. +}
  63577. +
  63578. +static ssize_t mma8451_scalemode_show(struct device *dev,
  63579. + struct device_attribute *attr,
  63580. + char *buf)
  63581. +{
  63582. + int mode = 0;
  63583. + mutex_lock(&mma8451_lock);
  63584. + mode = (int)mma_status.mode;
  63585. + mutex_unlock(&mma8451_lock);
  63586. +
  63587. + return sprintf(buf, "%d\n", mode);
  63588. +}
  63589. +
  63590. +static ssize_t mma8451_scalemode_store(struct device *dev,
  63591. + struct device_attribute *attr,
  63592. + const char *buf, size_t count)
  63593. +{
  63594. + unsigned long mode;
  63595. + int ret, active_save;
  63596. + struct i2c_client *client = mma8451_i2c_client;
  63597. +
  63598. + ret = strict_strtoul(buf, 10, &mode);
  63599. + if (ret) {
  63600. + dev_err(dev, "string transform error\n");
  63601. + goto out;
  63602. + }
  63603. +
  63604. + if (mode > MODE_8G) {
  63605. + dev_warn(dev, "not supported mode\n");
  63606. + ret = count;
  63607. + goto out;
  63608. + }
  63609. +
  63610. + mutex_lock(&mma8451_lock);
  63611. + if (mode == mma_status.mode) {
  63612. + ret = count;
  63613. + goto out_unlock;
  63614. + }
  63615. +
  63616. + active_save = mma_status.active;
  63617. + ret = mma8451_change_mode(client, mode);
  63618. + if (ret)
  63619. + goto out_unlock;
  63620. +
  63621. + if (active_save == MMA_ACTIVED) {
  63622. + ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, 1);
  63623. +
  63624. + if (ret)
  63625. + goto out_unlock;
  63626. + mma_status.active = active_save;
  63627. + }
  63628. +
  63629. +out_unlock:
  63630. + mutex_unlock(&mma8451_lock);
  63631. +out:
  63632. + return ret;
  63633. +}
  63634. +
  63635. +static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
  63636. + mma8451_enable_show, mma8451_enable_store);
  63637. +static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
  63638. + mma8451_position_show, mma8451_position_store);
  63639. +static DEVICE_ATTR(scalemode, S_IWUSR | S_IRUGO,
  63640. + mma8451_scalemode_show, mma8451_scalemode_store);
  63641. +
  63642. +static struct attribute *mma8451_attributes[] = {
  63643. + &dev_attr_enable.attr,
  63644. + &dev_attr_position.attr,
  63645. + &dev_attr_scalemode.attr,
  63646. + NULL
  63647. +};
  63648. +
  63649. +static const struct attribute_group mma8451_attr_group = {
  63650. + .attrs = mma8451_attributes,
  63651. +};
  63652. +
  63653. +static int mma8451_probe(struct i2c_client *client,
  63654. + const struct i2c_device_id *id)
  63655. +{
  63656. + int result, client_id;
  63657. + struct input_dev *idev;
  63658. + struct i2c_adapter *adapter;
  63659. + u32 pos;
  63660. + struct device_node *of_node = client->dev.of_node;
  63661. + struct regulator *vdd, *vdd_io;
  63662. +
  63663. + mma8451_i2c_client = client;
  63664. +
  63665. + vdd = devm_regulator_get(&client->dev, "vdd");
  63666. + if (!IS_ERR(vdd)) {
  63667. + result = regulator_enable(vdd);
  63668. + if (result) {
  63669. + dev_err(&client->dev, "vdd set voltage error\n");
  63670. + return result;
  63671. + }
  63672. + }
  63673. +
  63674. + vdd_io = devm_regulator_get(&client->dev, "vddio");
  63675. + if (!IS_ERR(vdd_io)) {
  63676. + result = regulator_enable(vdd_io);
  63677. + if (result) {
  63678. + dev_err(&client->dev, "vddio set voltage error\n");
  63679. + return result;
  63680. + }
  63681. + }
  63682. +
  63683. + adapter = to_i2c_adapter(client->dev.parent);
  63684. + result = i2c_check_functionality(adapter,
  63685. + I2C_FUNC_SMBUS_BYTE |
  63686. + I2C_FUNC_SMBUS_BYTE_DATA);
  63687. + if (!result)
  63688. + goto err_out;
  63689. +
  63690. + client_id = i2c_smbus_read_byte_data(client, MMA8451_WHO_AM_I);
  63691. + if (client_id != MMA8451_ID && client_id != MMA8452_ID
  63692. + && client_id != MMA8453_ID) {
  63693. + dev_err(&client->dev,
  63694. + "read chip ID 0x%x is not equal to 0x%x or 0x%x!\n",
  63695. + result, MMA8451_ID, MMA8452_ID);
  63696. + result = -EINVAL;
  63697. + goto err_out;
  63698. + }
  63699. +
  63700. + /* Initialize the MMA8451 chip */
  63701. + result = mma8451_change_mode(client, senstive_mode);
  63702. + if (result) {
  63703. + dev_err(&client->dev,
  63704. + "error when init mma8451 chip:(%d)\n", result);
  63705. + goto err_out;
  63706. + }
  63707. +
  63708. + hwmon_dev = hwmon_device_register(&client->dev);
  63709. + if (!hwmon_dev) {
  63710. + result = -ENOMEM;
  63711. + dev_err(&client->dev, "error when register hwmon device\n");
  63712. + goto err_out;
  63713. + }
  63714. +
  63715. + mma8451_idev = input_allocate_polled_device();
  63716. + if (!mma8451_idev) {
  63717. + result = -ENOMEM;
  63718. + dev_err(&client->dev, "alloc poll device failed!\n");
  63719. + goto err_alloc_poll_device;
  63720. + }
  63721. + mma8451_idev->poll = mma8451_dev_poll;
  63722. + mma8451_idev->poll_interval = POLL_INTERVAL;
  63723. + mma8451_idev->poll_interval_min = POLL_INTERVAL_MIN;
  63724. + mma8451_idev->poll_interval_max = POLL_INTERVAL_MAX;
  63725. + idev = mma8451_idev->input;
  63726. + idev->name = "mma845x";
  63727. + idev->id.bustype = BUS_I2C;
  63728. + idev->evbit[0] = BIT_MASK(EV_ABS);
  63729. +
  63730. + input_set_abs_params(idev, ABS_X, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
  63731. + input_set_abs_params(idev, ABS_Y, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
  63732. + input_set_abs_params(idev, ABS_Z, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
  63733. +
  63734. + result = input_register_polled_device(mma8451_idev);
  63735. + if (result) {
  63736. + dev_err(&client->dev, "register poll device failed!\n");
  63737. + goto err_register_polled_device;
  63738. + }
  63739. + result = sysfs_create_group(&idev->dev.kobj, &mma8451_attr_group);
  63740. + if (result) {
  63741. + dev_err(&client->dev, "create device file failed!\n");
  63742. + result = -EINVAL;
  63743. + goto err_register_polled_device;
  63744. + }
  63745. +
  63746. + result = of_property_read_u32(of_node, "position", &pos);
  63747. + if (result)
  63748. + pos = DEFAULT_POSITION;
  63749. + mma_status.position = (int)pos;
  63750. +
  63751. + return 0;
  63752. +err_register_polled_device:
  63753. + input_free_polled_device(mma8451_idev);
  63754. +err_alloc_poll_device:
  63755. + hwmon_device_unregister(&client->dev);
  63756. +err_out:
  63757. + return result;
  63758. +}
  63759. +
  63760. +static int mma8451_stop_chip(struct i2c_client *client)
  63761. +{
  63762. + int ret = 0;
  63763. + if (mma_status.active == MMA_ACTIVED) {
  63764. + mma_status.ctl_reg1 = i2c_smbus_read_byte_data(client,
  63765. + MMA8451_CTRL_REG1);
  63766. + ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  63767. + mma_status.ctl_reg1 & 0xFE);
  63768. + }
  63769. + return ret;
  63770. +}
  63771. +
  63772. +static int mma8451_remove(struct i2c_client *client)
  63773. +{
  63774. + int ret;
  63775. + ret = mma8451_stop_chip(client);
  63776. + hwmon_device_unregister(hwmon_dev);
  63777. +
  63778. + return ret;
  63779. +}
  63780. +
  63781. +#ifdef CONFIG_PM_SLEEP
  63782. +static int mma8451_suspend(struct device *dev)
  63783. +{
  63784. + struct i2c_client *client = to_i2c_client(dev);
  63785. +
  63786. + return mma8451_stop_chip(client);
  63787. +}
  63788. +
  63789. +static int mma8451_resume(struct device *dev)
  63790. +{
  63791. + int ret = 0;
  63792. + struct i2c_client *client = to_i2c_client(dev);
  63793. + if (mma_status.active == MMA_ACTIVED)
  63794. + ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  63795. + mma_status.ctl_reg1);
  63796. + return ret;
  63797. +
  63798. +}
  63799. +#endif
  63800. +
  63801. +static const struct i2c_device_id mma8451_id[] = {
  63802. + {"mma8451", 0},
  63803. +};
  63804. +
  63805. +MODULE_DEVICE_TABLE(i2c, mma8451_id);
  63806. +
  63807. +static SIMPLE_DEV_PM_OPS(mma8451_pm_ops, mma8451_suspend, mma8451_resume);
  63808. +static struct i2c_driver mma8451_driver = {
  63809. + .driver = {
  63810. + .name = "mma8451",
  63811. + .owner = THIS_MODULE,
  63812. + .pm = &mma8451_pm_ops,
  63813. + },
  63814. + .probe = mma8451_probe,
  63815. + .remove = mma8451_remove,
  63816. + .id_table = mma8451_id,
  63817. +};
  63818. +
  63819. +static int __init mma8451_init(void)
  63820. +{
  63821. + /* register driver */
  63822. + int res;
  63823. +
  63824. + res = i2c_add_driver(&mma8451_driver);
  63825. + if (res < 0) {
  63826. + printk(KERN_INFO "add mma8451 i2c driver failed\n");
  63827. + return -ENODEV;
  63828. + }
  63829. + return res;
  63830. +}
  63831. +
  63832. +static void __exit mma8451_exit(void)
  63833. +{
  63834. + i2c_del_driver(&mma8451_driver);
  63835. +}
  63836. +
  63837. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  63838. +MODULE_DESCRIPTION("MMA8451 3-Axis Orientation/Motion Detection Sensor driver");
  63839. +MODULE_LICENSE("GPL");
  63840. +
  63841. +module_init(mma8451_init);
  63842. +module_exit(mma8451_exit);
  63843. diff -Nur linux-3.14.14/drivers/i2c/busses/i2c-imx.c linux-imx6-3.14/drivers/i2c/busses/i2c-imx.c
  63844. --- linux-3.14.14/drivers/i2c/busses/i2c-imx.c 2014-07-28 10:07:25.000000000 -0500
  63845. +++ linux-imx6-3.14/drivers/i2c/busses/i2c-imx.c 2014-12-08 00:31:52.884418001 -0600
  63846. @@ -184,6 +184,9 @@
  63847. int stopped;
  63848. unsigned int ifdr; /* IMX_I2C_IFDR */
  63849. const struct imx_i2c_hwdata *hwdata;
  63850. +
  63851. + unsigned int cur_clk;
  63852. + unsigned int bitrate;
  63853. };
  63854. static const struct imx_i2c_hwdata imx1_i2c_hwdata = {
  63855. @@ -305,6 +308,51 @@
  63856. return 0;
  63857. }
  63858. +static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx)
  63859. +{
  63860. + struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div;
  63861. + unsigned ndivs = i2c_imx->hwdata->ndivs;
  63862. + unsigned int i2c_clk_rate;
  63863. + unsigned int div;
  63864. + int i;
  63865. +
  63866. + /* Divider value calculation */
  63867. + i2c_clk_rate = clk_get_rate(i2c_imx->clk);
  63868. + if (i2c_imx->cur_clk == i2c_clk_rate)
  63869. + return;
  63870. + else
  63871. + i2c_imx->cur_clk = i2c_clk_rate;
  63872. +
  63873. + div = (i2c_clk_rate + i2c_imx->bitrate - 1) / i2c_imx->bitrate;
  63874. + if (div < i2c_clk_div[0].div)
  63875. + i = 0;
  63876. + else if (div > i2c_clk_div[ndivs - 1].div)
  63877. + i = ndivs - 1;
  63878. + else
  63879. + for (i = 0; i2c_clk_div[i].div < div; i++)
  63880. + ;
  63881. +
  63882. + /* Store divider value */
  63883. + i2c_imx->ifdr = imx_i2c_clk_div[i].val;
  63884. +
  63885. + /*
  63886. + * There dummy delay is calculated.
  63887. + * It should be about one I2C clock period long.
  63888. + * This delay is used in I2C bus disable function
  63889. + * to fix chip hardware bug.
  63890. + */
  63891. + i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div
  63892. + + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
  63893. +
  63894. + /* dev_dbg() can't be used, because adapter is not yet registered */
  63895. +#ifdef CONFIG_I2C_DEBUG_BUS
  63896. + dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
  63897. + __func__, i2c_clk_rate, div);
  63898. + dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
  63899. + __func__, i2c_clk_div[i].val, i2c_clk_div[i].div);
  63900. +#endif
  63901. +}
  63902. +
  63903. static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
  63904. {
  63905. unsigned int temp = 0;
  63906. @@ -312,6 +360,7 @@
  63907. dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
  63908. + i2c_imx_set_clk(i2c_imx);
  63909. result = clk_prepare_enable(i2c_imx->clk);
  63910. if (result)
  63911. return result;
  63912. @@ -367,45 +416,6 @@
  63913. clk_disable_unprepare(i2c_imx->clk);
  63914. }
  63915. -static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
  63916. - unsigned int rate)
  63917. -{
  63918. - struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div;
  63919. - unsigned int i2c_clk_rate;
  63920. - unsigned int div;
  63921. - int i;
  63922. -
  63923. - /* Divider value calculation */
  63924. - i2c_clk_rate = clk_get_rate(i2c_imx->clk);
  63925. - div = (i2c_clk_rate + rate - 1) / rate;
  63926. - if (div < i2c_clk_div[0].div)
  63927. - i = 0;
  63928. - else if (div > i2c_clk_div[i2c_imx->hwdata->ndivs - 1].div)
  63929. - i = i2c_imx->hwdata->ndivs - 1;
  63930. - else
  63931. - for (i = 0; i2c_clk_div[i].div < div; i++);
  63932. -
  63933. - /* Store divider value */
  63934. - i2c_imx->ifdr = i2c_clk_div[i].val;
  63935. -
  63936. - /*
  63937. - * There dummy delay is calculated.
  63938. - * It should be about one I2C clock period long.
  63939. - * This delay is used in I2C bus disable function
  63940. - * to fix chip hardware bug.
  63941. - */
  63942. - i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div
  63943. - + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
  63944. -
  63945. - /* dev_dbg() can't be used, because adapter is not yet registered */
  63946. -#ifdef CONFIG_I2C_DEBUG_BUS
  63947. - dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
  63948. - __func__, i2c_clk_rate, div);
  63949. - dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
  63950. - __func__, i2c_clk_div[i].val, i2c_clk_div[i].div);
  63951. -#endif
  63952. -}
  63953. -
  63954. static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
  63955. {
  63956. struct imx_i2c_struct *i2c_imx = dev_id;
  63957. @@ -600,7 +610,6 @@
  63958. struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
  63959. void __iomem *base;
  63960. int irq, ret;
  63961. - u32 bitrate;
  63962. dev_dbg(&pdev->dev, "<%s>\n", __func__);
  63963. @@ -664,12 +673,12 @@
  63964. i2c_set_adapdata(&i2c_imx->adapter, i2c_imx);
  63965. /* Set up clock divider */
  63966. - bitrate = IMX_I2C_BIT_RATE;
  63967. + i2c_imx->bitrate = IMX_I2C_BIT_RATE;
  63968. ret = of_property_read_u32(pdev->dev.of_node,
  63969. - "clock-frequency", &bitrate);
  63970. + "clock-frequency", &i2c_imx->bitrate);
  63971. if (ret < 0 && pdata && pdata->bitrate)
  63972. - bitrate = pdata->bitrate;
  63973. - i2c_imx_set_clk(i2c_imx, bitrate);
  63974. + i2c_imx->bitrate = pdata->bitrate;
  63975. + i2c_imx_set_clk(i2c_imx);
  63976. /* Set up chip registers to defaults */
  63977. imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
  63978. diff -Nur linux-3.14.14/drivers/input/keyboard/gpio_keys.c linux-imx6-3.14/drivers/input/keyboard/gpio_keys.c
  63979. --- linux-3.14.14/drivers/input/keyboard/gpio_keys.c 2014-07-28 10:07:25.000000000 -0500
  63980. +++ linux-imx6-3.14/drivers/input/keyboard/gpio_keys.c 2014-12-08 00:31:52.992418001 -0600
  63981. @@ -3,6 +3,7 @@
  63982. *
  63983. * Copyright 2005 Phil Blundell
  63984. * Copyright 2010, 2011 David Jander <david@protonic.nl>
  63985. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  63986. *
  63987. * This program is free software; you can redistribute it and/or modify
  63988. * it under the terms of the GNU General Public License version 2 as
  63989. @@ -473,6 +474,8 @@
  63990. isr = gpio_keys_gpio_isr;
  63991. irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
  63992. + if (bdata->button->wakeup)
  63993. + irqflags |= IRQF_NO_SUSPEND;
  63994. } else {
  63995. if (!button->irq) {
  63996. diff -Nur linux-3.14.14/drivers/input/keyboard/imx_keypad.c linux-imx6-3.14/drivers/input/keyboard/imx_keypad.c
  63997. --- linux-3.14.14/drivers/input/keyboard/imx_keypad.c 2014-07-28 10:07:25.000000000 -0500
  63998. +++ linux-imx6-3.14/drivers/input/keyboard/imx_keypad.c 2014-12-08 00:31:52.992418001 -0600
  63999. @@ -1,6 +1,7 @@
  64000. /*
  64001. * Driver for the IMX keypad port.
  64002. * Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
  64003. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  64004. *
  64005. * This program is free software; you can redistribute it and/or modify
  64006. * it under the terms of the GNU General Public License version 2 as
  64007. @@ -548,6 +549,8 @@
  64008. if (device_may_wakeup(&pdev->dev))
  64009. enable_irq_wake(kbd->irq);
  64010. + else
  64011. + pinctrl_pm_select_sleep_state(dev);
  64012. return 0;
  64013. }
  64014. @@ -561,6 +564,8 @@
  64015. if (device_may_wakeup(&pdev->dev))
  64016. disable_irq_wake(kbd->irq);
  64017. + else
  64018. + pinctrl_pm_select_default_state(dev);
  64019. mutex_lock(&input_dev->mutex);
  64020. diff -Nur linux-3.14.14/drivers/input/misc/mma8450.c linux-imx6-3.14/drivers/input/misc/mma8450.c
  64021. --- linux-3.14.14/drivers/input/misc/mma8450.c 2014-07-28 10:07:25.000000000 -0500
  64022. +++ linux-imx6-3.14/drivers/input/misc/mma8450.c 2014-12-08 00:31:53.000418001 -0600
  64023. @@ -1,7 +1,7 @@
  64024. /*
  64025. * Driver for Freescale's 3-Axis Accelerometer MMA8450
  64026. *
  64027. - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
  64028. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  64029. *
  64030. * This program is free software; you can redistribute it and/or modify
  64031. * it under the terms of the GNU General Public License as published by
  64032. @@ -25,6 +25,7 @@
  64033. #include <linux/i2c.h>
  64034. #include <linux/input-polldev.h>
  64035. #include <linux/of_device.h>
  64036. +#include <linux/mutex.h>
  64037. #define MMA8450_DRV_NAME "mma8450"
  64038. @@ -51,11 +52,22 @@
  64039. #define MMA8450_CTRL_REG1 0x38
  64040. #define MMA8450_CTRL_REG2 0x39
  64041. +#define MMA8450_ID 0xC6
  64042. +#define MMA8450_WHO_AM_I 0x0F
  64043. +
  64044. +enum {
  64045. + MODE_STANDBY = 0,
  64046. + MODE_2G,
  64047. + MODE_4G,
  64048. + MODE_8G,
  64049. +};
  64050. /* mma8450 status */
  64051. struct mma8450 {
  64052. struct i2c_client *client;
  64053. struct input_polled_dev *idev;
  64054. + struct mutex mma8450_lock;
  64055. + u8 mode;
  64056. };
  64057. static int mma8450_read(struct mma8450 *m, unsigned off)
  64058. @@ -112,16 +124,19 @@
  64059. int ret;
  64060. u8 buf[6];
  64061. - ret = mma8450_read(m, MMA8450_STATUS);
  64062. - if (ret < 0)
  64063. - return;
  64064. + mutex_lock(&m->mma8450_lock);
  64065. - if (!(ret & MMA8450_STATUS_ZXYDR))
  64066. + ret = mma8450_read(m, MMA8450_STATUS);
  64067. + if (ret < 0 || !(ret & MMA8450_STATUS_ZXYDR)) {
  64068. + mutex_unlock(&m->mma8450_lock);
  64069. return;
  64070. + }
  64071. ret = mma8450_read_block(m, MMA8450_OUT_X_LSB, buf, sizeof(buf));
  64072. - if (ret < 0)
  64073. + if (ret < 0) {
  64074. + mutex_unlock(&m->mma8450_lock);
  64075. return;
  64076. + }
  64077. x = ((int)(s8)buf[1] << 4) | (buf[0] & 0xf);
  64078. y = ((int)(s8)buf[3] << 4) | (buf[2] & 0xf);
  64079. @@ -131,10 +146,12 @@
  64080. input_report_abs(dev->input, ABS_Y, y);
  64081. input_report_abs(dev->input, ABS_Z, z);
  64082. input_sync(dev->input);
  64083. +
  64084. + mutex_unlock(&m->mma8450_lock);
  64085. }
  64086. /* Initialize the MMA8450 chip */
  64087. -static void mma8450_open(struct input_polled_dev *dev)
  64088. +static s32 mma8450_open(struct input_polled_dev *dev)
  64089. {
  64090. struct mma8450 *m = dev->private;
  64091. int err;
  64092. @@ -142,18 +159,20 @@
  64093. /* enable all events from X/Y/Z, no FIFO */
  64094. err = mma8450_write(m, MMA8450_XYZ_DATA_CFG, 0x07);
  64095. if (err)
  64096. - return;
  64097. + return err;
  64098. /*
  64099. * Sleep mode poll rate - 50Hz
  64100. * System output data rate - 400Hz
  64101. - * Full scale selection - Active, +/- 2G
  64102. + * Standby mode
  64103. */
  64104. - err = mma8450_write(m, MMA8450_CTRL_REG1, 0x01);
  64105. - if (err < 0)
  64106. - return;
  64107. -
  64108. + err = mma8450_write(m, MMA8450_CTRL_REG1, MODE_STANDBY);
  64109. + if (err)
  64110. + return err;
  64111. + m->mode = MODE_STANDBY;
  64112. msleep(MODE_CHANGE_DELAY_MS);
  64113. +
  64114. + return 0;
  64115. }
  64116. static void mma8450_close(struct input_polled_dev *dev)
  64117. @@ -164,6 +183,76 @@
  64118. mma8450_write(m, MMA8450_CTRL_REG2, 0x01);
  64119. }
  64120. +static ssize_t mma8450_scalemode_show(struct device *dev,
  64121. + struct device_attribute *attr,
  64122. + char *buf)
  64123. +{
  64124. + int mode = 0;
  64125. + struct mma8450 *m;
  64126. + struct i2c_client *client = to_i2c_client(dev);
  64127. +
  64128. + m = i2c_get_clientdata(client);
  64129. +
  64130. + mutex_lock(&m->mma8450_lock);
  64131. + mode = (int)m->mode;
  64132. + mutex_unlock(&m->mma8450_lock);
  64133. +
  64134. + return sprintf(buf, "%d\n", mode);
  64135. +}
  64136. +
  64137. +static ssize_t mma8450_scalemode_store(struct device *dev,
  64138. + struct device_attribute *attr,
  64139. + const char *buf, size_t count)
  64140. +{
  64141. + unsigned long mode;
  64142. + int ret;
  64143. + struct mma8450 *m = NULL;
  64144. + struct i2c_client *client = to_i2c_client(dev);
  64145. +
  64146. + ret = strict_strtoul(buf, 10, &mode);
  64147. + if (ret) {
  64148. + dev_err(dev, "string transform error\n");
  64149. + return ret;
  64150. + }
  64151. +
  64152. + if (mode > MODE_8G) {
  64153. + dev_warn(dev, "not supported mode %d\n", (int)mode);
  64154. + return count;
  64155. + }
  64156. +
  64157. + m = i2c_get_clientdata(client);
  64158. +
  64159. + mutex_lock(&m->mma8450_lock);
  64160. + if (mode == m->mode) {
  64161. + mutex_unlock(&m->mma8450_lock);
  64162. + return count;
  64163. + }
  64164. +
  64165. + ret = mma8450_write(m, MMA8450_CTRL_REG1, mode);
  64166. + if (ret < 0) {
  64167. + mutex_unlock(&m->mma8450_lock);
  64168. + return ret;
  64169. + }
  64170. +
  64171. + msleep(MODE_CHANGE_DELAY_MS);
  64172. + m->mode = (u8)mode;
  64173. + mutex_unlock(&m->mma8450_lock);
  64174. +
  64175. + return count;
  64176. +}
  64177. +
  64178. +static DEVICE_ATTR(scalemode, S_IWUSR | S_IRUGO,
  64179. + mma8450_scalemode_show, mma8450_scalemode_store);
  64180. +
  64181. +static struct attribute *mma8450_attributes[] = {
  64182. + &dev_attr_scalemode.attr,
  64183. + NULL
  64184. +};
  64185. +
  64186. +static const struct attribute_group mma8450_attr_group = {
  64187. + .attrs = mma8450_attributes,
  64188. +};
  64189. +
  64190. /*
  64191. * I2C init/probing/exit functions
  64192. */
  64193. @@ -172,7 +261,25 @@
  64194. {
  64195. struct input_polled_dev *idev;
  64196. struct mma8450 *m;
  64197. - int err;
  64198. + int err, client_id;
  64199. + struct i2c_adapter *adapter = NULL;
  64200. +
  64201. + adapter = to_i2c_adapter(c->dev.parent);
  64202. + err = i2c_check_functionality(adapter,
  64203. + I2C_FUNC_SMBUS_BYTE |
  64204. + I2C_FUNC_SMBUS_BYTE_DATA);
  64205. + if (!err)
  64206. + goto err_out;
  64207. +
  64208. + client_id = i2c_smbus_read_byte_data(c, MMA8450_WHO_AM_I);
  64209. +
  64210. + if (MMA8450_ID != client_id) {
  64211. + dev_err(&c->dev,
  64212. + "read chip ID 0x%x is not equal to 0x%x!\n", client_id,
  64213. + MMA8450_ID);
  64214. + err = -EINVAL;
  64215. + goto err_out;
  64216. + }
  64217. m = kzalloc(sizeof(struct mma8450), GFP_KERNEL);
  64218. idev = input_allocate_polled_device();
  64219. @@ -183,6 +290,7 @@
  64220. m->client = c;
  64221. m->idev = idev;
  64222. + i2c_set_clientdata(c, m);
  64223. idev->private = m;
  64224. idev->input->name = MMA8450_DRV_NAME;
  64225. @@ -190,8 +298,6 @@
  64226. idev->poll = mma8450_poll;
  64227. idev->poll_interval = POLL_INTERVAL;
  64228. idev->poll_interval_max = POLL_INTERVAL_MAX;
  64229. - idev->open = mma8450_open;
  64230. - idev->close = mma8450_close;
  64231. __set_bit(EV_ABS, idev->input->evbit);
  64232. input_set_abs_params(idev->input, ABS_X, -2048, 2047, 32, 32);
  64233. @@ -206,11 +312,32 @@
  64234. i2c_set_clientdata(c, m);
  64235. + mutex_init(&m->mma8450_lock);
  64236. +
  64237. + err = mma8450_open(idev);
  64238. + if (err) {
  64239. + dev_err(&c->dev, "failed to initialize mma8450\n");
  64240. + goto err_unreg_dev;
  64241. + }
  64242. +
  64243. + err = sysfs_create_group(&c->dev.kobj, &mma8450_attr_group);
  64244. + if (err) {
  64245. + dev_err(&c->dev, "create device file failed!\n");
  64246. + err = -EINVAL;
  64247. + goto err_close;
  64248. + }
  64249. +
  64250. return 0;
  64251. +err_close:
  64252. + mma8450_close(idev);
  64253. +err_unreg_dev:
  64254. + mutex_destroy(&m->mma8450_lock);
  64255. + input_unregister_polled_device(idev);
  64256. err_free_mem:
  64257. input_free_polled_device(idev);
  64258. kfree(m);
  64259. +err_out:
  64260. return err;
  64261. }
  64262. @@ -219,6 +346,9 @@
  64263. struct mma8450 *m = i2c_get_clientdata(c);
  64264. struct input_polled_dev *idev = m->idev;
  64265. + sysfs_remove_group(&c->dev.kobj, &mma8450_attr_group);
  64266. + mma8450_close(idev);
  64267. + mutex_destroy(&m->mma8450_lock);
  64268. input_unregister_polled_device(idev);
  64269. input_free_polled_device(idev);
  64270. kfree(m);
  64271. diff -Nur linux-3.14.14/drivers/input/sparse-keymap.c linux-imx6-3.14/drivers/input/sparse-keymap.c
  64272. --- linux-3.14.14/drivers/input/sparse-keymap.c 2014-07-28 10:07:25.000000000 -0500
  64273. +++ linux-imx6-3.14/drivers/input/sparse-keymap.c 2014-12-08 00:31:53.012418001 -0600
  64274. @@ -236,7 +236,7 @@
  64275. * in an input device that was set up by sparse_keymap_setup().
  64276. * NOTE: It is safe to cal this function while input device is
  64277. * still registered (however the drivers should care not to try to
  64278. - * use freed keymap and thus have to shut off interrups/polling
  64279. + * use freed keymap and thus have to shut off interrupts/polling
  64280. * before freeing the keymap).
  64281. */
  64282. void sparse_keymap_free(struct input_dev *dev)
  64283. diff -Nur linux-3.14.14/drivers/Kconfig linux-imx6-3.14/drivers/Kconfig
  64284. --- linux-3.14.14/drivers/Kconfig 2014-07-28 10:07:25.000000000 -0500
  64285. +++ linux-imx6-3.14/drivers/Kconfig 2014-12-08 00:31:52.392418001 -0600
  64286. @@ -96,6 +96,8 @@
  64287. source "drivers/memstick/Kconfig"
  64288. +source "drivers/mxc/Kconfig"
  64289. +
  64290. source "drivers/leds/Kconfig"
  64291. source "drivers/accessibility/Kconfig"
  64292. diff -Nur linux-3.14.14/drivers/leds/leds-gpio.c linux-imx6-3.14/drivers/leds/leds-gpio.c
  64293. --- linux-3.14.14/drivers/leds/leds-gpio.c 2014-07-28 10:07:25.000000000 -0500
  64294. +++ linux-imx6-3.14/drivers/leds/leds-gpio.c 2014-12-08 00:31:53.080418001 -0600
  64295. @@ -3,7 +3,7 @@
  64296. *
  64297. * Copyright (C) 2007 8D Technologies inc.
  64298. * Raphael Assenat <raph@8d.com>
  64299. - * Copyright (C) 2008 Freescale Semiconductor, Inc.
  64300. + * Copyright (C) 2008, 2014 Freescale Semiconductor, Inc.
  64301. *
  64302. * This program is free software; you can redistribute it and/or modify
  64303. * it under the terms of the GNU General Public License version 2 as
  64304. @@ -203,6 +203,8 @@
  64305. else
  64306. led.default_state = LEDS_GPIO_DEFSTATE_OFF;
  64307. }
  64308. + if (of_get_property(child, "retain-state-suspended", NULL))
  64309. + led.retain_state_suspended = 1;
  64310. ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
  64311. &pdev->dev, NULL);
  64312. diff -Nur linux-3.14.14/drivers/leds/leds-pwm.c linux-imx6-3.14/drivers/leds/leds-pwm.c
  64313. --- linux-3.14.14/drivers/leds/leds-pwm.c 2014-07-28 10:07:25.000000000 -0500
  64314. +++ linux-imx6-3.14/drivers/leds/leds-pwm.c 2014-12-08 00:31:53.080418001 -0600
  64315. @@ -70,6 +70,10 @@
  64316. duty *= brightness;
  64317. do_div(duty, max);
  64318. +
  64319. + if (led_dat->active_low)
  64320. + duty = led_dat->period - duty;
  64321. +
  64322. led_dat->duty = duty;
  64323. if (led_dat->can_sleep)
  64324. @@ -93,55 +97,75 @@
  64325. }
  64326. }
  64327. -static int led_pwm_create_of(struct platform_device *pdev,
  64328. - struct led_pwm_priv *priv)
  64329. +static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
  64330. + struct led_pwm *led, struct device_node *child)
  64331. {
  64332. - struct device_node *child;
  64333. + struct led_pwm_data *led_data = &priv->leds[priv->num_leds];
  64334. int ret;
  64335. - for_each_child_of_node(pdev->dev.of_node, child) {
  64336. - struct led_pwm_data *led_dat = &priv->leds[priv->num_leds];
  64337. + led_data->active_low = led->active_low;
  64338. + led_data->period = led->pwm_period_ns;
  64339. + led_data->cdev.name = led->name;
  64340. + led_data->cdev.default_trigger = led->default_trigger;
  64341. + led_data->cdev.brightness_set = led_pwm_set;
  64342. + led_data->cdev.brightness = LED_OFF;
  64343. + led_data->cdev.max_brightness = led->max_brightness;
  64344. + led_data->cdev.flags = LED_CORE_SUSPENDRESUME;
  64345. +
  64346. + if (child)
  64347. + led_data->pwm = devm_of_pwm_get(dev, child, NULL);
  64348. + else
  64349. + led_data->pwm = devm_pwm_get(dev, led->name);
  64350. + if (IS_ERR(led_data->pwm)) {
  64351. + ret = PTR_ERR(led_data->pwm);
  64352. + dev_err(dev, "unable to request PWM for %s: %d\n",
  64353. + led->name, ret);
  64354. + return ret;
  64355. + }
  64356. - led_dat->cdev.name = of_get_property(child, "label",
  64357. - NULL) ? : child->name;
  64358. + if (child)
  64359. + led_data->period = pwm_get_period(led_data->pwm);
  64360. - led_dat->pwm = devm_of_pwm_get(&pdev->dev, child, NULL);
  64361. - if (IS_ERR(led_dat->pwm)) {
  64362. - dev_err(&pdev->dev, "unable to request PWM for %s\n",
  64363. - led_dat->cdev.name);
  64364. - ret = PTR_ERR(led_dat->pwm);
  64365. - goto err;
  64366. - }
  64367. - /* Get the period from PWM core when n*/
  64368. - led_dat->period = pwm_get_period(led_dat->pwm);
  64369. + led_data->can_sleep = pwm_can_sleep(led_data->pwm);
  64370. + if (led_data->can_sleep)
  64371. + INIT_WORK(&led_data->work, led_pwm_work);
  64372. - led_dat->cdev.default_trigger = of_get_property(child,
  64373. + ret = led_classdev_register(dev, &led_data->cdev);
  64374. + if (ret == 0) {
  64375. + priv->num_leds++;
  64376. + } else {
  64377. + dev_err(dev, "failed to register PWM led for %s: %d\n",
  64378. + led->name, ret);
  64379. + }
  64380. +
  64381. + return ret;
  64382. +}
  64383. +
  64384. +static int led_pwm_create_of(struct device *dev, struct led_pwm_priv *priv)
  64385. +{
  64386. + struct device_node *child;
  64387. + struct led_pwm led;
  64388. + int ret = 0;
  64389. +
  64390. + memset(&led, 0, sizeof(led));
  64391. +
  64392. + for_each_child_of_node(dev->of_node, child) {
  64393. + led.name = of_get_property(child, "label", NULL) ? :
  64394. + child->name;
  64395. +
  64396. + led.default_trigger = of_get_property(child,
  64397. "linux,default-trigger", NULL);
  64398. + led.active_low = of_property_read_bool(child, "active-low");
  64399. of_property_read_u32(child, "max-brightness",
  64400. - &led_dat->cdev.max_brightness);
  64401. + &led.max_brightness);
  64402. - led_dat->cdev.brightness_set = led_pwm_set;
  64403. - led_dat->cdev.brightness = LED_OFF;
  64404. - led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
  64405. -
  64406. - led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
  64407. - if (led_dat->can_sleep)
  64408. - INIT_WORK(&led_dat->work, led_pwm_work);
  64409. -
  64410. - ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
  64411. - if (ret < 0) {
  64412. - dev_err(&pdev->dev, "failed to register for %s\n",
  64413. - led_dat->cdev.name);
  64414. + ret = led_pwm_add(dev, priv, &led, child);
  64415. + if (ret) {
  64416. of_node_put(child);
  64417. - goto err;
  64418. + break;
  64419. }
  64420. - priv->num_leds++;
  64421. }
  64422. - return 0;
  64423. -err:
  64424. - led_pwm_cleanup(priv);
  64425. -
  64426. return ret;
  64427. }
  64428. @@ -167,51 +191,23 @@
  64429. if (pdata) {
  64430. for (i = 0; i < count; i++) {
  64431. - struct led_pwm *cur_led = &pdata->leds[i];
  64432. - struct led_pwm_data *led_dat = &priv->leds[i];
  64433. -
  64434. - led_dat->pwm = devm_pwm_get(&pdev->dev, cur_led->name);
  64435. - if (IS_ERR(led_dat->pwm)) {
  64436. - ret = PTR_ERR(led_dat->pwm);
  64437. - dev_err(&pdev->dev,
  64438. - "unable to request PWM for %s\n",
  64439. - cur_led->name);
  64440. - goto err;
  64441. - }
  64442. -
  64443. - led_dat->cdev.name = cur_led->name;
  64444. - led_dat->cdev.default_trigger = cur_led->default_trigger;
  64445. - led_dat->active_low = cur_led->active_low;
  64446. - led_dat->period = cur_led->pwm_period_ns;
  64447. - led_dat->cdev.brightness_set = led_pwm_set;
  64448. - led_dat->cdev.brightness = LED_OFF;
  64449. - led_dat->cdev.max_brightness = cur_led->max_brightness;
  64450. - led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
  64451. -
  64452. - led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
  64453. - if (led_dat->can_sleep)
  64454. - INIT_WORK(&led_dat->work, led_pwm_work);
  64455. -
  64456. - ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
  64457. - if (ret < 0)
  64458. - goto err;
  64459. + ret = led_pwm_add(&pdev->dev, priv, &pdata->leds[i],
  64460. + NULL);
  64461. + if (ret)
  64462. + break;
  64463. }
  64464. - priv->num_leds = count;
  64465. } else {
  64466. - ret = led_pwm_create_of(pdev, priv);
  64467. - if (ret)
  64468. - return ret;
  64469. + ret = led_pwm_create_of(&pdev->dev, priv);
  64470. + }
  64471. +
  64472. + if (ret) {
  64473. + led_pwm_cleanup(priv);
  64474. + return ret;
  64475. }
  64476. platform_set_drvdata(pdev, priv);
  64477. return 0;
  64478. -
  64479. -err:
  64480. - priv->num_leds = i;
  64481. - led_pwm_cleanup(priv);
  64482. -
  64483. - return ret;
  64484. }
  64485. static int led_pwm_remove(struct platform_device *pdev)
  64486. diff -Nur linux-3.14.14/drivers/mailbox/mailbox.c linux-imx6-3.14/drivers/mailbox/mailbox.c
  64487. --- linux-3.14.14/drivers/mailbox/mailbox.c 1969-12-31 18:00:00.000000000 -0600
  64488. +++ linux-imx6-3.14/drivers/mailbox/mailbox.c 2014-12-08 00:31:53.092418001 -0600
  64489. @@ -0,0 +1,488 @@
  64490. +/*
  64491. + * Mailbox: Common code for Mailbox controllers and users
  64492. + *
  64493. + * Copyright (C) 2014 Linaro Ltd.
  64494. + * Author: Jassi Brar <jassisinghbrar@gmail.com>
  64495. + *
  64496. + * This program is free software; you can redistribute it and/or modify
  64497. + * it under the terms of the GNU General Public License version 2 as
  64498. + * published by the Free Software Foundation.
  64499. + */
  64500. +
  64501. +#include <linux/interrupt.h>
  64502. +#include <linux/spinlock.h>
  64503. +#include <linux/mutex.h>
  64504. +#include <linux/delay.h>
  64505. +#include <linux/slab.h>
  64506. +#include <linux/err.h>
  64507. +#include <linux/module.h>
  64508. +#include <linux/device.h>
  64509. +#include <linux/mailbox_client.h>
  64510. +#include <linux/mailbox_controller.h>
  64511. +
  64512. +#define TXDONE_BY_IRQ (1 << 0) /* controller has remote RTR irq */
  64513. +#define TXDONE_BY_POLL (1 << 1) /* controller can read status of last TX */
  64514. +#define TXDONE_BY_ACK (1 << 2) /* S/W ACK recevied by Client ticks the TX */
  64515. +
  64516. +static LIST_HEAD(mbox_cons);
  64517. +static DEFINE_MUTEX(con_mutex);
  64518. +
  64519. +static int _add_to_rbuf(struct mbox_chan *chan, void *mssg)
  64520. +{
  64521. + int idx;
  64522. + unsigned long flags;
  64523. +
  64524. + spin_lock_irqsave(&chan->lock, flags);
  64525. +
  64526. + /* See if there is any space left */
  64527. + if (chan->msg_count == MBOX_TX_QUEUE_LEN) {
  64528. + spin_unlock_irqrestore(&chan->lock, flags);
  64529. + return -ENOMEM;
  64530. + }
  64531. +
  64532. + idx = chan->msg_free;
  64533. + chan->msg_data[idx] = mssg;
  64534. + chan->msg_count++;
  64535. +
  64536. + if (idx == MBOX_TX_QUEUE_LEN - 1)
  64537. + chan->msg_free = 0;
  64538. + else
  64539. + chan->msg_free++;
  64540. +
  64541. + spin_unlock_irqrestore(&chan->lock, flags);
  64542. +
  64543. + return idx;
  64544. +}
  64545. +
  64546. +static void _msg_submit(struct mbox_chan *chan)
  64547. +{
  64548. + unsigned count, idx;
  64549. + unsigned long flags;
  64550. + void *data;
  64551. + int err;
  64552. +
  64553. + spin_lock_irqsave(&chan->lock, flags);
  64554. +
  64555. + if (!chan->msg_count || chan->active_req) {
  64556. + spin_unlock_irqrestore(&chan->lock, flags);
  64557. + return;
  64558. + }
  64559. +
  64560. + count = chan->msg_count;
  64561. + idx = chan->msg_free;
  64562. + if (idx >= count)
  64563. + idx -= count;
  64564. + else
  64565. + idx += MBOX_TX_QUEUE_LEN - count;
  64566. +
  64567. + data = chan->msg_data[idx];
  64568. +
  64569. + /* Try to submit a message to the MBOX controller */
  64570. + err = chan->mbox->ops->send_data(chan, data);
  64571. + if (!err) {
  64572. + chan->active_req = data;
  64573. + chan->msg_count--;
  64574. + }
  64575. +
  64576. + spin_unlock_irqrestore(&chan->lock, flags);
  64577. +}
  64578. +
  64579. +static void tx_tick(struct mbox_chan *chan, int r)
  64580. +{
  64581. + unsigned long flags;
  64582. + void *mssg;
  64583. +
  64584. + spin_lock_irqsave(&chan->lock, flags);
  64585. + mssg = chan->active_req;
  64586. + chan->active_req = NULL;
  64587. + spin_unlock_irqrestore(&chan->lock, flags);
  64588. +
  64589. + /* Submit next message */
  64590. + _msg_submit(chan);
  64591. +
  64592. + /* Notify the client */
  64593. + if (chan->cl->tx_block)
  64594. + complete(&chan->tx_complete);
  64595. + else if (mssg && chan->cl->tx_done)
  64596. + chan->cl->tx_done(chan->cl, mssg, r);
  64597. +}
  64598. +
  64599. +static void poll_txdone(unsigned long data)
  64600. +{
  64601. + struct mbox_controller *mbox = (struct mbox_controller *)data;
  64602. + bool txdone, resched = false;
  64603. + int i;
  64604. +
  64605. + for (i = 0; i < mbox->num_chans; i++) {
  64606. + struct mbox_chan *chan = &mbox->chans[i];
  64607. +
  64608. + if (chan->active_req && chan->cl) {
  64609. + resched = true;
  64610. + txdone = chan->mbox->ops->last_tx_done(chan);
  64611. + if (txdone)
  64612. + tx_tick(chan, 0);
  64613. + }
  64614. + }
  64615. +
  64616. + if (resched)
  64617. + mod_timer(&mbox->poll,
  64618. + jiffies + msecs_to_jiffies(mbox->period));
  64619. +}
  64620. +
  64621. +/**
  64622. + * mbox_chan_received_data - A way for controller driver to push data
  64623. + * received from remote to the upper layer.
  64624. + * @chan: Pointer to the mailbox channel on which RX happened.
  64625. + * @data: Client specific message typecasted as void *
  64626. + *
  64627. + * After startup and before shutdown any data received on the chan
  64628. + * is passed on to the API via atomic mbox_chan_received_data().
  64629. + * The controller should ACK the RX only after this call returns.
  64630. + */
  64631. +void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)
  64632. +{
  64633. + /* No buffering the received data */
  64634. + if (chan->cl->rx_callback)
  64635. + chan->cl->rx_callback(chan->cl, mssg);
  64636. +}
  64637. +EXPORT_SYMBOL_GPL(mbox_chan_received_data);
  64638. +
  64639. +/**
  64640. + * mbox_chan_txdone - A way for controller driver to notify the
  64641. + * framework that the last TX has completed.
  64642. + * @chan: Pointer to the mailbox chan on which TX happened.
  64643. + * @r: Status of last TX - OK or ERROR
  64644. + *
  64645. + * The controller that has IRQ for TX ACK calls this atomic API
  64646. + * to tick the TX state machine. It works only if txdone_irq
  64647. + * is set by the controller.
  64648. + */
  64649. +void mbox_chan_txdone(struct mbox_chan *chan, int r)
  64650. +{
  64651. + if (unlikely(!(chan->txdone_method & TXDONE_BY_IRQ))) {
  64652. + pr_err("Controller can't run the TX ticker\n");
  64653. + return;
  64654. + }
  64655. +
  64656. + tx_tick(chan, r);
  64657. +}
  64658. +EXPORT_SYMBOL_GPL(mbox_chan_txdone);
  64659. +
  64660. +/**
  64661. + * mbox_client_txdone - The way for a client to run the TX state machine.
  64662. + * @chan: Mailbox channel assigned to this client.
  64663. + * @r: Success status of last transmission.
  64664. + *
  64665. + * The client/protocol had received some 'ACK' packet and it notifies
  64666. + * the API that the last packet was sent successfully. This only works
  64667. + * if the controller can't sense TX-Done.
  64668. + */
  64669. +void mbox_client_txdone(struct mbox_chan *chan, int r)
  64670. +{
  64671. + if (unlikely(!(chan->txdone_method & TXDONE_BY_ACK))) {
  64672. + pr_err("Client can't run the TX ticker\n");
  64673. + return;
  64674. + }
  64675. +
  64676. + tx_tick(chan, r);
  64677. +}
  64678. +EXPORT_SYMBOL_GPL(mbox_client_txdone);
  64679. +
  64680. +/**
  64681. + * mbox_client_peek_data - A way for client driver to pull data
  64682. + * received from remote by the controller.
  64683. + * @chan: Mailbox channel assigned to this client.
  64684. + *
  64685. + * A poke to controller driver for any received data.
  64686. + * The data is actually passed onto client via the
  64687. + * mbox_chan_received_data()
  64688. + * The call can be made from atomic context, so the controller's
  64689. + * implementation of peek_data() must not sleep.
  64690. + *
  64691. + * Return: True, if controller has, and is going to push after this,
  64692. + * some data.
  64693. + * False, if controller doesn't have any data to be read.
  64694. + */
  64695. +bool mbox_client_peek_data(struct mbox_chan *chan)
  64696. +{
  64697. + if (chan->mbox->ops->peek_data)
  64698. + return chan->mbox->ops->peek_data(chan);
  64699. +
  64700. + return false;
  64701. +}
  64702. +EXPORT_SYMBOL_GPL(mbox_client_peek_data);
  64703. +
  64704. +/**
  64705. + * mbox_send_message - For client to submit a message to be
  64706. + * sent to the remote.
  64707. + * @chan: Mailbox channel assigned to this client.
  64708. + * @mssg: Client specific message typecasted.
  64709. + *
  64710. + * For client to submit data to the controller destined for a remote
  64711. + * processor. If the client had set 'tx_block', the call will return
  64712. + * either when the remote receives the data or when 'tx_tout' millisecs
  64713. + * run out.
  64714. + * In non-blocking mode, the requests are buffered by the API and a
  64715. + * non-negative token is returned for each queued request. If the request
  64716. + * is not queued, a negative token is returned. Upon failure or successful
  64717. + * TX, the API calls 'tx_done' from atomic context, from which the client
  64718. + * could submit yet another request.
  64719. + * In blocking mode, 'tx_done' is not called, effectively making the
  64720. + * queue length 1.
  64721. + * The pointer to message should be preserved until it is sent
  64722. + * over the chan, i.e, tx_done() is made.
  64723. + * This function could be called from atomic context as it simply
  64724. + * queues the data and returns a token against the request.
  64725. + *
  64726. + * Return: Non-negative integer for successful submission (non-blocking mode)
  64727. + * or transmission over chan (blocking mode).
  64728. + * Negative value denotes failure.
  64729. + */
  64730. +int mbox_send_message(struct mbox_chan *chan, void *mssg)
  64731. +{
  64732. + int t;
  64733. +
  64734. + if (!chan || !chan->cl)
  64735. + return -EINVAL;
  64736. +
  64737. + t = _add_to_rbuf(chan, mssg);
  64738. + if (t < 0) {
  64739. + pr_err("Try increasing MBOX_TX_QUEUE_LEN\n");
  64740. + return t;
  64741. + }
  64742. +
  64743. + _msg_submit(chan);
  64744. +
  64745. + reinit_completion(&chan->tx_complete);
  64746. +
  64747. + if (chan->txdone_method == TXDONE_BY_POLL)
  64748. + poll_txdone((unsigned long)chan->mbox);
  64749. +
  64750. + if (chan->cl->tx_block && chan->active_req) {
  64751. + unsigned long wait;
  64752. + int ret;
  64753. +
  64754. + if (!chan->cl->tx_tout) /* wait for ever */
  64755. + wait = msecs_to_jiffies(3600000);
  64756. + else
  64757. + wait = msecs_to_jiffies(chan->cl->tx_tout);
  64758. +
  64759. + ret = wait_for_completion_timeout(&chan->tx_complete, wait);
  64760. + if (ret == 0) {
  64761. + t = -EIO;
  64762. + tx_tick(chan, -EIO);
  64763. + }
  64764. + }
  64765. +
  64766. + return t;
  64767. +}
  64768. +EXPORT_SYMBOL_GPL(mbox_send_message);
  64769. +
  64770. +/**
  64771. + * mbox_request_channel - Request a mailbox channel.
  64772. + * @cl: Identity of the client requesting the channel.
  64773. + *
  64774. + * The Client specifies its requirements and capabilities while asking for
  64775. + * a mailbox channel. It can't be called from atomic context.
  64776. + * The channel is exclusively allocated and can't be used by another
  64777. + * client before the owner calls mbox_free_channel.
  64778. + * After assignment, any packet received on this channel will be
  64779. + * handed over to the client via the 'rx_callback'.
  64780. + * The framework holds reference to the client, so the mbox_client
  64781. + * structure shouldn't be modified until the mbox_free_channel returns.
  64782. + *
  64783. + * Return: Pointer to the channel assigned to the client if successful.
  64784. + * ERR_PTR for request failure.
  64785. + */
  64786. +struct mbox_chan *mbox_request_channel(struct mbox_client *cl)
  64787. +{
  64788. + struct device *dev = cl->dev;
  64789. + struct mbox_controller *mbox;
  64790. + struct of_phandle_args spec;
  64791. + struct mbox_chan *chan;
  64792. + unsigned long flags;
  64793. + int count, i, ret;
  64794. +
  64795. + if (!dev || !dev->of_node) {
  64796. + pr_err("%s: No owner device node\n", __func__);
  64797. + return ERR_PTR(-ENODEV);
  64798. + }
  64799. +
  64800. + count = of_property_count_strings(dev->of_node, "mbox-names");
  64801. + if (count < 0) {
  64802. + pr_err("%s: mbox-names property of node '%s' missing\n",
  64803. + __func__, dev->of_node->full_name);
  64804. + return ERR_PTR(-ENODEV);
  64805. + }
  64806. +
  64807. + mutex_lock(&con_mutex);
  64808. +
  64809. + ret = -ENODEV;
  64810. + for (i = 0; i < count; i++) {
  64811. + const char *s;
  64812. +
  64813. + if (of_property_read_string_index(dev->of_node,
  64814. + "mbox-names", i, &s))
  64815. + continue;
  64816. +
  64817. + if (strcmp(cl->chan_name, s))
  64818. + continue;
  64819. +
  64820. + if (of_parse_phandle_with_args(dev->of_node,
  64821. + "mbox", "#mbox-cells", i, &spec))
  64822. + continue;
  64823. +
  64824. + chan = NULL;
  64825. + list_for_each_entry(mbox, &mbox_cons, node)
  64826. + if (mbox->dev->of_node == spec.np) {
  64827. + chan = mbox->of_xlate(mbox, &spec);
  64828. + break;
  64829. + }
  64830. +
  64831. + of_node_put(spec.np);
  64832. +
  64833. + if (!chan)
  64834. + continue;
  64835. +
  64836. + ret = -EBUSY;
  64837. + if (!chan->cl && try_module_get(mbox->dev->driver->owner))
  64838. + break;
  64839. + }
  64840. +
  64841. + if (i == count) {
  64842. + mutex_unlock(&con_mutex);
  64843. + return ERR_PTR(ret);
  64844. + }
  64845. +
  64846. + spin_lock_irqsave(&chan->lock, flags);
  64847. + chan->msg_free = 0;
  64848. + chan->msg_count = 0;
  64849. + chan->active_req = NULL;
  64850. + chan->cl = cl;
  64851. + init_completion(&chan->tx_complete);
  64852. +
  64853. + if (chan->txdone_method == TXDONE_BY_POLL
  64854. + && cl->knows_txdone)
  64855. + chan->txdone_method |= TXDONE_BY_ACK;
  64856. + spin_unlock_irqrestore(&chan->lock, flags);
  64857. +
  64858. + ret = chan->mbox->ops->startup(chan);
  64859. + if (ret) {
  64860. + pr_err("Unable to startup the chan (%d)\n", ret);
  64861. + mbox_free_channel(chan);
  64862. + chan = ERR_PTR(ret);
  64863. + }
  64864. +
  64865. + mutex_unlock(&con_mutex);
  64866. + return chan;
  64867. +}
  64868. +EXPORT_SYMBOL_GPL(mbox_request_channel);
  64869. +
  64870. +/**
  64871. + * mbox_free_channel - The client relinquishes control of a mailbox
  64872. + * channel by this call.
  64873. + * @chan: The mailbox channel to be freed.
  64874. + */
  64875. +void mbox_free_channel(struct mbox_chan *chan)
  64876. +{
  64877. + unsigned long flags;
  64878. +
  64879. + if (!chan || !chan->cl)
  64880. + return;
  64881. +
  64882. + chan->mbox->ops->shutdown(chan);
  64883. +
  64884. + /* The queued TX requests are simply aborted, no callbacks are made */
  64885. + spin_lock_irqsave(&chan->lock, flags);
  64886. + chan->cl = NULL;
  64887. + chan->active_req = NULL;
  64888. + if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK))
  64889. + chan->txdone_method = TXDONE_BY_POLL;
  64890. +
  64891. + module_put(chan->mbox->dev->driver->owner);
  64892. + spin_unlock_irqrestore(&chan->lock, flags);
  64893. +}
  64894. +EXPORT_SYMBOL_GPL(mbox_free_channel);
  64895. +
  64896. +static struct mbox_chan *
  64897. +of_mbox_index_xlate(struct mbox_controller *mbox,
  64898. + const struct of_phandle_args *sp)
  64899. +{
  64900. + int ind = sp->args[0];
  64901. +
  64902. + if (ind >= mbox->num_chans)
  64903. + return NULL;
  64904. +
  64905. + return &mbox->chans[ind];
  64906. +}
  64907. +
  64908. +/**
  64909. + * mbox_controller_register - Register the mailbox controller
  64910. + * @mbox: Pointer to the mailbox controller.
  64911. + *
  64912. + * The controller driver registers its communication chans
  64913. + */
  64914. +int mbox_controller_register(struct mbox_controller *mbox)
  64915. +{
  64916. + int i, txdone;
  64917. +
  64918. + /* Sanity check */
  64919. + if (!mbox || !mbox->dev || !mbox->ops || !mbox->num_chans)
  64920. + return -EINVAL;
  64921. +
  64922. + if (mbox->txdone_irq)
  64923. + txdone = TXDONE_BY_IRQ;
  64924. + else if (mbox->txdone_poll)
  64925. + txdone = TXDONE_BY_POLL;
  64926. + else /* It has to be ACK then */
  64927. + txdone = TXDONE_BY_ACK;
  64928. +
  64929. + if (txdone == TXDONE_BY_POLL) {
  64930. + mbox->poll.function = &poll_txdone;
  64931. + mbox->poll.data = (unsigned long)mbox;
  64932. + init_timer(&mbox->poll);
  64933. + }
  64934. +
  64935. + for (i = 0; i < mbox->num_chans; i++) {
  64936. + struct mbox_chan *chan = &mbox->chans[i];
  64937. + chan->cl = NULL;
  64938. + chan->mbox = mbox;
  64939. + chan->txdone_method = txdone;
  64940. + spin_lock_init(&chan->lock);
  64941. + }
  64942. +
  64943. + if (!mbox->of_xlate)
  64944. + mbox->of_xlate = of_mbox_index_xlate;
  64945. +
  64946. + mutex_lock(&con_mutex);
  64947. + list_add_tail(&mbox->node, &mbox_cons);
  64948. + mutex_unlock(&con_mutex);
  64949. +
  64950. + return 0;
  64951. +}
  64952. +EXPORT_SYMBOL_GPL(mbox_controller_register);
  64953. +
  64954. +/**
  64955. + * mbox_controller_unregister - UnRegister the mailbox controller
  64956. + * @mbox: Pointer to the mailbox controller.
  64957. + */
  64958. +void mbox_controller_unregister(struct mbox_controller *mbox)
  64959. +{
  64960. + int i;
  64961. +
  64962. + if (!mbox)
  64963. + return;
  64964. +
  64965. + mutex_lock(&con_mutex);
  64966. +
  64967. + list_del(&mbox->node);
  64968. +
  64969. + for (i = 0; i < mbox->num_chans; i++)
  64970. + mbox_free_channel(&mbox->chans[i]);
  64971. +
  64972. + if (mbox->txdone_poll)
  64973. + del_timer_sync(&mbox->poll);
  64974. +
  64975. + mutex_unlock(&con_mutex);
  64976. +}
  64977. +EXPORT_SYMBOL_GPL(mbox_controller_unregister);
  64978. diff -Nur linux-3.14.14/drivers/mailbox/Makefile linux-imx6-3.14/drivers/mailbox/Makefile
  64979. --- linux-3.14.14/drivers/mailbox/Makefile 2014-07-28 10:07:25.000000000 -0500
  64980. +++ linux-imx6-3.14/drivers/mailbox/Makefile 2014-12-08 00:31:53.092418001 -0600
  64981. @@ -1,3 +1,7 @@
  64982. +# Generic MAILBOX API
  64983. +
  64984. +obj-$(CONFIG_MAILBOX) += mailbox.o
  64985. +
  64986. obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
  64987. obj-$(CONFIG_OMAP_MBOX) += omap-mailbox.o
  64988. diff -Nur linux-3.14.14/drivers/mailbox/pl320-ipc.c linux-imx6-3.14/drivers/mailbox/pl320-ipc.c
  64989. --- linux-3.14.14/drivers/mailbox/pl320-ipc.c 2014-07-28 10:07:25.000000000 -0500
  64990. +++ linux-imx6-3.14/drivers/mailbox/pl320-ipc.c 2014-12-08 00:31:53.092418001 -0600
  64991. @@ -26,7 +26,7 @@
  64992. #include <linux/device.h>
  64993. #include <linux/amba/bus.h>
  64994. -#include <linux/mailbox.h>
  64995. +#include <linux/pl320-ipc.h>
  64996. #define IPCMxSOURCE(m) ((m) * 0x40)
  64997. #define IPCMxDSET(m) (((m) * 0x40) + 0x004)
  64998. diff -Nur linux-3.14.14/drivers/Makefile linux-imx6-3.14/drivers/Makefile
  64999. --- linux-3.14.14/drivers/Makefile 2014-07-28 10:07:25.000000000 -0500
  65000. +++ linux-imx6-3.14/drivers/Makefile 2014-12-08 00:31:52.392418001 -0600
  65001. @@ -111,6 +111,7 @@
  65002. obj-$(CONFIG_CPU_FREQ) += cpufreq/
  65003. obj-$(CONFIG_CPU_IDLE) += cpuidle/
  65004. obj-y += mmc/
  65005. +obj-$(CONFIG_ARCH_MXC) += mxc/
  65006. obj-$(CONFIG_MEMSTICK) += memstick/
  65007. obj-y += leds/
  65008. obj-$(CONFIG_INFINIBAND) += infiniband/
  65009. diff -Nur linux-3.14.14/drivers/media/platform/Kconfig linux-imx6-3.14/drivers/media/platform/Kconfig
  65010. --- linux-3.14.14/drivers/media/platform/Kconfig 2014-07-28 10:07:25.000000000 -0500
  65011. +++ linux-imx6-3.14/drivers/media/platform/Kconfig 2014-12-08 00:31:53.232418001 -0600
  65012. @@ -115,6 +115,21 @@
  65013. To compile this driver as a module, choose M here: the module
  65014. will be called s3c-camif.
  65015. +config VIDEO_MXC_OUTPUT
  65016. + tristate "MXC Video For Linux Video Output"
  65017. + depends on VIDEO_DEV && ARCH_MXC && FB_MXC
  65018. + select VIDEOBUF_DMA_CONTIG
  65019. + ---help---
  65020. + This is the video4linux2 output driver based on MXC module.
  65021. +
  65022. +config VIDEO_MXC_CAPTURE
  65023. + tristate "MXC Video For Linux Video Capture"
  65024. + depends on VIDEO_V4L2 && VIDEO_V4L2_INT_DEVICE
  65025. + ---help---
  65026. + This is the video4linux2 capture driver based on i.MX video-in module.
  65027. +
  65028. +source "drivers/media/platform/mxc/capture/Kconfig"
  65029. +source "drivers/media/platform/mxc/output/Kconfig"
  65030. source "drivers/media/platform/soc_camera/Kconfig"
  65031. source "drivers/media/platform/exynos4-is/Kconfig"
  65032. source "drivers/media/platform/s5p-tv/Kconfig"
  65033. diff -Nur linux-3.14.14/drivers/media/platform/Makefile linux-imx6-3.14/drivers/media/platform/Makefile
  65034. --- linux-3.14.14/drivers/media/platform/Makefile 2014-07-28 10:07:25.000000000 -0500
  65035. +++ linux-imx6-3.14/drivers/media/platform/Makefile 2014-12-08 00:31:53.232418001 -0600
  65036. @@ -51,4 +51,7 @@
  65037. obj-$(CONFIG_ARCH_OMAP) += omap/
  65038. +obj-$(CONFIG_VIDEO_MXC_CAPTURE) += mxc/capture/
  65039. +obj-$(CONFIG_VIDEO_MXC_OUTPUT) += mxc/output/
  65040. +
  65041. ccflags-y += -I$(srctree)/drivers/media/i2c
  65042. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/adv7180.c linux-imx6-3.14/drivers/media/platform/mxc/capture/adv7180.c
  65043. --- linux-3.14.14/drivers/media/platform/mxc/capture/adv7180.c 1969-12-31 18:00:00.000000000 -0600
  65044. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/adv7180.c 2014-12-08 00:31:53.252418001 -0600
  65045. @@ -0,0 +1,1344 @@
  65046. +/*
  65047. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  65048. + */
  65049. +
  65050. +/*
  65051. + * The code contained herein is licensed under the GNU General Public
  65052. + * License. You may obtain a copy of the GNU General Public License
  65053. + * Version 2 or later at the following locations:
  65054. + *
  65055. + * http://www.opensource.org/licenses/gpl-license.html
  65056. + * http://www.gnu.org/copyleft/gpl.html
  65057. + */
  65058. +
  65059. +/*!
  65060. + * @file adv7180.c
  65061. + *
  65062. + * @brief Analog Device ADV7180 video decoder functions
  65063. + *
  65064. + * @ingroup Camera
  65065. + */
  65066. +
  65067. +#include <linux/clk.h>
  65068. +#include <linux/delay.h>
  65069. +#include <linux/device.h>
  65070. +#include <linux/i2c.h>
  65071. +#include <linux/init.h>
  65072. +#include <linux/module.h>
  65073. +#include <linux/of_device.h>
  65074. +#include <linux/of_gpio.h>
  65075. +#include <linux/pinctrl/consumer.h>
  65076. +#include <linux/regulator/consumer.h>
  65077. +#include <media/v4l2-chip-ident.h>
  65078. +#include <media/v4l2-int-device.h>
  65079. +#include "mxc_v4l2_capture.h"
  65080. +
  65081. +#define ADV7180_VOLTAGE_ANALOG 1800000
  65082. +#define ADV7180_VOLTAGE_DIGITAL_CORE 1800000
  65083. +#define ADV7180_VOLTAGE_DIGITAL_IO 3300000
  65084. +#define ADV7180_VOLTAGE_PLL 1800000
  65085. +
  65086. +static struct regulator *dvddio_regulator;
  65087. +static struct regulator *dvdd_regulator;
  65088. +static struct regulator *avdd_regulator;
  65089. +static struct regulator *pvdd_regulator;
  65090. +static int pwn_gpio;
  65091. +
  65092. +static int adv7180_probe(struct i2c_client *adapter,
  65093. + const struct i2c_device_id *id);
  65094. +static int adv7180_detach(struct i2c_client *client);
  65095. +
  65096. +static const struct i2c_device_id adv7180_id[] = {
  65097. + {"adv7180", 0},
  65098. + {},
  65099. +};
  65100. +
  65101. +MODULE_DEVICE_TABLE(i2c, adv7180_id);
  65102. +
  65103. +static struct i2c_driver adv7180_i2c_driver = {
  65104. + .driver = {
  65105. + .owner = THIS_MODULE,
  65106. + .name = "adv7180",
  65107. + },
  65108. + .probe = adv7180_probe,
  65109. + .remove = adv7180_detach,
  65110. + .id_table = adv7180_id,
  65111. +};
  65112. +
  65113. +/*!
  65114. + * Maintains the information on the current state of the sensor.
  65115. + */
  65116. +struct sensor {
  65117. + struct sensor_data sen;
  65118. + v4l2_std_id std_id;
  65119. +} adv7180_data;
  65120. +
  65121. +
  65122. +/*! List of input video formats supported. The video formats is corresponding
  65123. + * with v4l2 id in video_fmt_t
  65124. + */
  65125. +typedef enum {
  65126. + ADV7180_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
  65127. + ADV7180_PAL, /*!< (B, G, H, I, N)PAL video signal. */
  65128. + ADV7180_NOT_LOCKED, /*!< Not locked on a signal. */
  65129. +} video_fmt_idx;
  65130. +
  65131. +/*! Number of video standards supported (including 'not locked' signal). */
  65132. +#define ADV7180_STD_MAX (ADV7180_PAL + 1)
  65133. +
  65134. +/*! Video format structure. */
  65135. +typedef struct {
  65136. + int v4l2_id; /*!< Video for linux ID. */
  65137. + char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
  65138. + u16 raw_width; /*!< Raw width. */
  65139. + u16 raw_height; /*!< Raw height. */
  65140. + u16 active_width; /*!< Active width. */
  65141. + u16 active_height; /*!< Active height. */
  65142. +} video_fmt_t;
  65143. +
  65144. +/*! Description of video formats supported.
  65145. + *
  65146. + * PAL: raw=720x625, active=720x576.
  65147. + * NTSC: raw=720x525, active=720x480.
  65148. + */
  65149. +static video_fmt_t video_fmts[] = {
  65150. + { /*! NTSC */
  65151. + .v4l2_id = V4L2_STD_NTSC,
  65152. + .name = "NTSC",
  65153. + .raw_width = 720, /* SENS_FRM_WIDTH */
  65154. + .raw_height = 525, /* SENS_FRM_HEIGHT */
  65155. + .active_width = 720, /* ACT_FRM_WIDTH plus 1 */
  65156. + .active_height = 480, /* ACT_FRM_WIDTH plus 1 */
  65157. + },
  65158. + { /*! (B, G, H, I, N) PAL */
  65159. + .v4l2_id = V4L2_STD_PAL,
  65160. + .name = "PAL",
  65161. + .raw_width = 720,
  65162. + .raw_height = 625,
  65163. + .active_width = 720,
  65164. + .active_height = 576,
  65165. + },
  65166. + { /*! Unlocked standard */
  65167. + .v4l2_id = V4L2_STD_ALL,
  65168. + .name = "Autodetect",
  65169. + .raw_width = 720,
  65170. + .raw_height = 625,
  65171. + .active_width = 720,
  65172. + .active_height = 576,
  65173. + },
  65174. +};
  65175. +
  65176. +/*!* Standard index of ADV7180. */
  65177. +static video_fmt_idx video_idx = ADV7180_PAL;
  65178. +
  65179. +/*! @brief This mutex is used to provide mutual exclusion.
  65180. + *
  65181. + * Create a mutex that can be used to provide mutually exclusive
  65182. + * read/write access to the globally accessible data structures
  65183. + * and variables that were defined above.
  65184. + */
  65185. +static DEFINE_MUTEX(mutex);
  65186. +
  65187. +#define IF_NAME "adv7180"
  65188. +#define ADV7180_INPUT_CTL 0x00 /* Input Control */
  65189. +#define ADV7180_STATUS_1 0x10 /* Status #1 */
  65190. +#define ADV7180_BRIGHTNESS 0x0a /* Brightness */
  65191. +#define ADV7180_IDENT 0x11 /* IDENT */
  65192. +#define ADV7180_VSYNC_FIELD_CTL_1 0x31 /* VSYNC Field Control #1 */
  65193. +#define ADV7180_MANUAL_WIN_CTL 0x3d /* Manual Window Control */
  65194. +#define ADV7180_SD_SATURATION_CB 0xe3 /* SD Saturation Cb */
  65195. +#define ADV7180_SD_SATURATION_CR 0xe4 /* SD Saturation Cr */
  65196. +#define ADV7180_PWR_MNG 0x0f /* Power Management */
  65197. +
  65198. +/* supported controls */
  65199. +/* This hasn't been fully implemented yet.
  65200. + * This is how it should work, though. */
  65201. +static struct v4l2_queryctrl adv7180_qctrl[] = {
  65202. + {
  65203. + .id = V4L2_CID_BRIGHTNESS,
  65204. + .type = V4L2_CTRL_TYPE_INTEGER,
  65205. + .name = "Brightness",
  65206. + .minimum = 0, /* check this value */
  65207. + .maximum = 255, /* check this value */
  65208. + .step = 1, /* check this value */
  65209. + .default_value = 127, /* check this value */
  65210. + .flags = 0,
  65211. + }, {
  65212. + .id = V4L2_CID_SATURATION,
  65213. + .type = V4L2_CTRL_TYPE_INTEGER,
  65214. + .name = "Saturation",
  65215. + .minimum = 0, /* check this value */
  65216. + .maximum = 255, /* check this value */
  65217. + .step = 0x1, /* check this value */
  65218. + .default_value = 127, /* check this value */
  65219. + .flags = 0,
  65220. + }
  65221. +};
  65222. +
  65223. +static inline void adv7180_power_down(int enable)
  65224. +{
  65225. + gpio_set_value_cansleep(pwn_gpio, !enable);
  65226. + msleep(2);
  65227. +}
  65228. +
  65229. +static int adv7180_regulator_enable(struct device *dev)
  65230. +{
  65231. + int ret = 0;
  65232. +
  65233. + dvddio_regulator = devm_regulator_get(dev, "DOVDD");
  65234. +
  65235. + if (!IS_ERR(dvddio_regulator)) {
  65236. + regulator_set_voltage(dvddio_regulator,
  65237. + ADV7180_VOLTAGE_DIGITAL_IO,
  65238. + ADV7180_VOLTAGE_DIGITAL_IO);
  65239. + ret = regulator_enable(dvddio_regulator);
  65240. + if (ret) {
  65241. + dev_err(dev, "set io voltage failed\n");
  65242. + return ret;
  65243. + } else {
  65244. + dev_dbg(dev, "set io voltage ok\n");
  65245. + }
  65246. + } else {
  65247. + dev_warn(dev, "cannot get io voltage\n");
  65248. + }
  65249. +
  65250. + dvdd_regulator = devm_regulator_get(dev, "DVDD");
  65251. + if (!IS_ERR(dvdd_regulator)) {
  65252. + regulator_set_voltage(dvdd_regulator,
  65253. + ADV7180_VOLTAGE_DIGITAL_CORE,
  65254. + ADV7180_VOLTAGE_DIGITAL_CORE);
  65255. + ret = regulator_enable(dvdd_regulator);
  65256. + if (ret) {
  65257. + dev_err(dev, "set core voltage failed\n");
  65258. + return ret;
  65259. + } else {
  65260. + dev_dbg(dev, "set core voltage ok\n");
  65261. + }
  65262. + } else {
  65263. + dev_warn(dev, "cannot get core voltage\n");
  65264. + }
  65265. +
  65266. + avdd_regulator = devm_regulator_get(dev, "AVDD");
  65267. + if (!IS_ERR(avdd_regulator)) {
  65268. + regulator_set_voltage(avdd_regulator,
  65269. + ADV7180_VOLTAGE_ANALOG,
  65270. + ADV7180_VOLTAGE_ANALOG);
  65271. + ret = regulator_enable(avdd_regulator);
  65272. + if (ret) {
  65273. + dev_err(dev, "set analog voltage failed\n");
  65274. + return ret;
  65275. + } else {
  65276. + dev_dbg(dev, "set analog voltage ok\n");
  65277. + }
  65278. + } else {
  65279. + dev_warn(dev, "cannot get analog voltage\n");
  65280. + }
  65281. +
  65282. + pvdd_regulator = devm_regulator_get(dev, "PVDD");
  65283. + if (!IS_ERR(pvdd_regulator)) {
  65284. + regulator_set_voltage(pvdd_regulator,
  65285. + ADV7180_VOLTAGE_PLL,
  65286. + ADV7180_VOLTAGE_PLL);
  65287. + ret = regulator_enable(pvdd_regulator);
  65288. + if (ret) {
  65289. + dev_err(dev, "set pll voltage failed\n");
  65290. + return ret;
  65291. + } else {
  65292. + dev_dbg(dev, "set pll voltage ok\n");
  65293. + }
  65294. + } else {
  65295. + dev_warn(dev, "cannot get pll voltage\n");
  65296. + }
  65297. +
  65298. + return ret;
  65299. +}
  65300. +
  65301. +
  65302. +/***********************************************************************
  65303. + * I2C transfert.
  65304. + ***********************************************************************/
  65305. +
  65306. +/*! Read one register from a ADV7180 i2c slave device.
  65307. + *
  65308. + * @param *reg register in the device we wish to access.
  65309. + *
  65310. + * @return 0 if success, an error code otherwise.
  65311. + */
  65312. +static inline int adv7180_read(u8 reg)
  65313. +{
  65314. + int val;
  65315. +
  65316. + val = i2c_smbus_read_byte_data(adv7180_data.sen.i2c_client, reg);
  65317. + if (val < 0) {
  65318. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65319. + "%s:read reg error: reg=%2x\n", __func__, reg);
  65320. + return -1;
  65321. + }
  65322. + return val;
  65323. +}
  65324. +
  65325. +/*! Write one register of a ADV7180 i2c slave device.
  65326. + *
  65327. + * @param *reg register in the device we wish to access.
  65328. + *
  65329. + * @return 0 if success, an error code otherwise.
  65330. + */
  65331. +static int adv7180_write_reg(u8 reg, u8 val)
  65332. +{
  65333. + s32 ret;
  65334. +
  65335. + ret = i2c_smbus_write_byte_data(adv7180_data.sen.i2c_client, reg, val);
  65336. + if (ret < 0) {
  65337. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65338. + "%s:write reg error:reg=%2x,val=%2x\n", __func__,
  65339. + reg, val);
  65340. + return -1;
  65341. + }
  65342. + return 0;
  65343. +}
  65344. +
  65345. +/***********************************************************************
  65346. + * mxc_v4l2_capture interface.
  65347. + ***********************************************************************/
  65348. +
  65349. +/*!
  65350. + * Return attributes of current video standard.
  65351. + * Since this device autodetects the current standard, this function also
  65352. + * sets the values that need to be changed if the standard changes.
  65353. + * There is no set std equivalent function.
  65354. + *
  65355. + * @return None.
  65356. + */
  65357. +static void adv7180_get_std(v4l2_std_id *std)
  65358. +{
  65359. + int tmp;
  65360. + int idx;
  65361. +
  65362. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_get_std\n");
  65363. +
  65364. + /* Read the AD_RESULT to get the detect output video standard */
  65365. + tmp = adv7180_read(ADV7180_STATUS_1) & 0x70;
  65366. +
  65367. + mutex_lock(&mutex);
  65368. + if (tmp == 0x40) {
  65369. + /* PAL */
  65370. + *std = V4L2_STD_PAL;
  65371. + idx = ADV7180_PAL;
  65372. + } else if (tmp == 0) {
  65373. + /*NTSC*/
  65374. + *std = V4L2_STD_NTSC;
  65375. + idx = ADV7180_NTSC;
  65376. + } else {
  65377. + *std = V4L2_STD_ALL;
  65378. + idx = ADV7180_NOT_LOCKED;
  65379. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65380. + "Got invalid video standard!\n");
  65381. + }
  65382. + mutex_unlock(&mutex);
  65383. +
  65384. + /* This assumes autodetect which this device uses. */
  65385. + if (*std != adv7180_data.std_id) {
  65386. + video_idx = idx;
  65387. + adv7180_data.std_id = *std;
  65388. + adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
  65389. + adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
  65390. + }
  65391. +}
  65392. +
  65393. +/***********************************************************************
  65394. + * IOCTL Functions from v4l2_int_ioctl_desc.
  65395. + ***********************************************************************/
  65396. +
  65397. +/*!
  65398. + * ioctl_g_ifparm - V4L2 sensor interface handler for vidioc_int_g_ifparm_num
  65399. + * s: pointer to standard V4L2 device structure
  65400. + * p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure
  65401. + *
  65402. + * Gets slave interface parameters.
  65403. + * Calculates the required xclk value to support the requested
  65404. + * clock parameters in p. This value is returned in the p
  65405. + * parameter.
  65406. + *
  65407. + * vidioc_int_g_ifparm returns platform-specific information about the
  65408. + * interface settings used by the sensor.
  65409. + *
  65410. + * Called on open.
  65411. + */
  65412. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  65413. +{
  65414. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_ifparm\n");
  65415. +
  65416. + if (s == NULL) {
  65417. + pr_err(" ERROR!! no slave device set!\n");
  65418. + return -1;
  65419. + }
  65420. +
  65421. + /* Initialize structure to 0s then set any non-0 values. */
  65422. + memset(p, 0, sizeof(*p));
  65423. + p->if_type = V4L2_IF_TYPE_BT656; /* This is the only possibility. */
  65424. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  65425. + p->u.bt656.nobt_hs_inv = 1;
  65426. + p->u.bt656.bt_sync_correct = 1;
  65427. +
  65428. + /* ADV7180 has a dedicated clock so no clock settings needed. */
  65429. +
  65430. + return 0;
  65431. +}
  65432. +
  65433. +/*!
  65434. + * Sets the camera power.
  65435. + *
  65436. + * s pointer to the camera device
  65437. + * on if 1, power is to be turned on. 0 means power is to be turned off
  65438. + *
  65439. + * ioctl_s_power - V4L2 sensor interface handler for vidioc_int_s_power_num
  65440. + * @s: pointer to standard V4L2 device structure
  65441. + * @on: power state to which device is to be set
  65442. + *
  65443. + * Sets devices power state to requrested state, if possible.
  65444. + * This is called on open, close, suspend and resume.
  65445. + */
  65446. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  65447. +{
  65448. + struct sensor *sensor = s->priv;
  65449. +
  65450. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_s_power\n");
  65451. +
  65452. + if (on && !sensor->sen.on) {
  65453. + if (adv7180_write_reg(ADV7180_PWR_MNG, 0x04) != 0)
  65454. + return -EIO;
  65455. +
  65456. + /*
  65457. + * FIXME:Additional 400ms to wait the chip to be stable?
  65458. + * This is a workaround for preview scrolling issue.
  65459. + */
  65460. + msleep(400);
  65461. + } else if (!on && sensor->sen.on) {
  65462. + if (adv7180_write_reg(ADV7180_PWR_MNG, 0x24) != 0)
  65463. + return -EIO;
  65464. + }
  65465. +
  65466. + sensor->sen.on = on;
  65467. +
  65468. + return 0;
  65469. +}
  65470. +
  65471. +/*!
  65472. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  65473. + * @s: pointer to standard V4L2 device structure
  65474. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  65475. + *
  65476. + * Returns the sensor's video CAPTURE parameters.
  65477. + */
  65478. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  65479. +{
  65480. + struct sensor *sensor = s->priv;
  65481. + struct v4l2_captureparm *cparm = &a->parm.capture;
  65482. +
  65483. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_parm\n");
  65484. +
  65485. + switch (a->type) {
  65486. + /* These are all the possible cases. */
  65487. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  65488. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  65489. + memset(a, 0, sizeof(*a));
  65490. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  65491. + cparm->capability = sensor->sen.streamcap.capability;
  65492. + cparm->timeperframe = sensor->sen.streamcap.timeperframe;
  65493. + cparm->capturemode = sensor->sen.streamcap.capturemode;
  65494. + break;
  65495. +
  65496. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  65497. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  65498. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  65499. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  65500. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  65501. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  65502. + break;
  65503. +
  65504. + default:
  65505. + pr_debug("ioctl_g_parm:type is unknown %d\n", a->type);
  65506. + break;
  65507. + }
  65508. +
  65509. + return 0;
  65510. +}
  65511. +
  65512. +/*!
  65513. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  65514. + * @s: pointer to standard V4L2 device structure
  65515. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  65516. + *
  65517. + * Configures the sensor to use the input parameters, if possible. If
  65518. + * not possible, reverts to the old parameters and returns the
  65519. + * appropriate error code.
  65520. + *
  65521. + * This driver cannot change these settings.
  65522. + */
  65523. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  65524. +{
  65525. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_parm\n");
  65526. +
  65527. + switch (a->type) {
  65528. + /* These are all the possible cases. */
  65529. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  65530. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  65531. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  65532. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  65533. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  65534. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  65535. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  65536. + break;
  65537. +
  65538. + default:
  65539. + pr_debug(" type is unknown - %d\n", a->type);
  65540. + break;
  65541. + }
  65542. +
  65543. + return 0;
  65544. +}
  65545. +
  65546. +/*!
  65547. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  65548. + * @s: pointer to standard V4L2 device structure
  65549. + * @f: pointer to standard V4L2 v4l2_format structure
  65550. + *
  65551. + * Returns the sensor's current pixel format in the v4l2_format
  65552. + * parameter.
  65553. + */
  65554. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  65555. +{
  65556. + struct sensor *sensor = s->priv;
  65557. +
  65558. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_fmt_cap\n");
  65559. +
  65560. + switch (f->type) {
  65561. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  65562. + pr_debug(" Returning size of %dx%d\n",
  65563. + sensor->sen.pix.width, sensor->sen.pix.height);
  65564. + f->fmt.pix = sensor->sen.pix;
  65565. + break;
  65566. +
  65567. + case V4L2_BUF_TYPE_PRIVATE: {
  65568. + v4l2_std_id std;
  65569. + adv7180_get_std(&std);
  65570. + f->fmt.pix.pixelformat = (u32)std;
  65571. + }
  65572. + break;
  65573. +
  65574. + default:
  65575. + f->fmt.pix = sensor->sen.pix;
  65576. + break;
  65577. + }
  65578. +
  65579. + return 0;
  65580. +}
  65581. +
  65582. +/*!
  65583. + * ioctl_queryctrl - V4L2 sensor interface handler for VIDIOC_QUERYCTRL ioctl
  65584. + * @s: pointer to standard V4L2 device structure
  65585. + * @qc: standard V4L2 VIDIOC_QUERYCTRL ioctl structure
  65586. + *
  65587. + * If the requested control is supported, returns the control information
  65588. + * from the video_control[] array. Otherwise, returns -EINVAL if the
  65589. + * control is not supported.
  65590. + */
  65591. +static int ioctl_queryctrl(struct v4l2_int_device *s,
  65592. + struct v4l2_queryctrl *qc)
  65593. +{
  65594. + int i;
  65595. +
  65596. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_queryctrl\n");
  65597. +
  65598. + for (i = 0; i < ARRAY_SIZE(adv7180_qctrl); i++)
  65599. + if (qc->id && qc->id == adv7180_qctrl[i].id) {
  65600. + memcpy(qc, &(adv7180_qctrl[i]),
  65601. + sizeof(*qc));
  65602. + return 0;
  65603. + }
  65604. +
  65605. + return -EINVAL;
  65606. +}
  65607. +
  65608. +/*!
  65609. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  65610. + * @s: pointer to standard V4L2 device structure
  65611. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  65612. + *
  65613. + * If the requested control is supported, returns the control's current
  65614. + * value from the video_control[] array. Otherwise, returns -EINVAL
  65615. + * if the control is not supported.
  65616. + */
  65617. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  65618. +{
  65619. + int ret = 0;
  65620. + int sat = 0;
  65621. +
  65622. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_ctrl\n");
  65623. +
  65624. + switch (vc->id) {
  65625. + case V4L2_CID_BRIGHTNESS:
  65626. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65627. + " V4L2_CID_BRIGHTNESS\n");
  65628. + adv7180_data.sen.brightness = adv7180_read(ADV7180_BRIGHTNESS);
  65629. + vc->value = adv7180_data.sen.brightness;
  65630. + break;
  65631. + case V4L2_CID_CONTRAST:
  65632. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65633. + " V4L2_CID_CONTRAST\n");
  65634. + vc->value = adv7180_data.sen.contrast;
  65635. + break;
  65636. + case V4L2_CID_SATURATION:
  65637. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65638. + " V4L2_CID_SATURATION\n");
  65639. + sat = adv7180_read(ADV7180_SD_SATURATION_CB);
  65640. + adv7180_data.sen.saturation = sat;
  65641. + vc->value = adv7180_data.sen.saturation;
  65642. + break;
  65643. + case V4L2_CID_HUE:
  65644. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65645. + " V4L2_CID_HUE\n");
  65646. + vc->value = adv7180_data.sen.hue;
  65647. + break;
  65648. + case V4L2_CID_AUTO_WHITE_BALANCE:
  65649. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65650. + " V4L2_CID_AUTO_WHITE_BALANCE\n");
  65651. + break;
  65652. + case V4L2_CID_DO_WHITE_BALANCE:
  65653. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65654. + " V4L2_CID_DO_WHITE_BALANCE\n");
  65655. + break;
  65656. + case V4L2_CID_RED_BALANCE:
  65657. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65658. + " V4L2_CID_RED_BALANCE\n");
  65659. + vc->value = adv7180_data.sen.red;
  65660. + break;
  65661. + case V4L2_CID_BLUE_BALANCE:
  65662. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65663. + " V4L2_CID_BLUE_BALANCE\n");
  65664. + vc->value = adv7180_data.sen.blue;
  65665. + break;
  65666. + case V4L2_CID_GAMMA:
  65667. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65668. + " V4L2_CID_GAMMA\n");
  65669. + break;
  65670. + case V4L2_CID_EXPOSURE:
  65671. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65672. + " V4L2_CID_EXPOSURE\n");
  65673. + vc->value = adv7180_data.sen.ae_mode;
  65674. + break;
  65675. + case V4L2_CID_AUTOGAIN:
  65676. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65677. + " V4L2_CID_AUTOGAIN\n");
  65678. + break;
  65679. + case V4L2_CID_GAIN:
  65680. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65681. + " V4L2_CID_GAIN\n");
  65682. + break;
  65683. + case V4L2_CID_HFLIP:
  65684. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65685. + " V4L2_CID_HFLIP\n");
  65686. + break;
  65687. + case V4L2_CID_VFLIP:
  65688. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65689. + " V4L2_CID_VFLIP\n");
  65690. + break;
  65691. + default:
  65692. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65693. + " Default case\n");
  65694. + vc->value = 0;
  65695. + ret = -EPERM;
  65696. + break;
  65697. + }
  65698. +
  65699. + return ret;
  65700. +}
  65701. +
  65702. +/*!
  65703. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  65704. + * @s: pointer to standard V4L2 device structure
  65705. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  65706. + *
  65707. + * If the requested control is supported, sets the control's current
  65708. + * value in HW (and updates the video_control[] array). Otherwise,
  65709. + * returns -EINVAL if the control is not supported.
  65710. + */
  65711. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  65712. +{
  65713. + int retval = 0;
  65714. + u8 tmp;
  65715. +
  65716. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_ctrl\n");
  65717. +
  65718. + switch (vc->id) {
  65719. + case V4L2_CID_BRIGHTNESS:
  65720. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65721. + " V4L2_CID_BRIGHTNESS\n");
  65722. + tmp = vc->value;
  65723. + adv7180_write_reg(ADV7180_BRIGHTNESS, tmp);
  65724. + adv7180_data.sen.brightness = vc->value;
  65725. + break;
  65726. + case V4L2_CID_CONTRAST:
  65727. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65728. + " V4L2_CID_CONTRAST\n");
  65729. + break;
  65730. + case V4L2_CID_SATURATION:
  65731. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65732. + " V4L2_CID_SATURATION\n");
  65733. + tmp = vc->value;
  65734. + adv7180_write_reg(ADV7180_SD_SATURATION_CB, tmp);
  65735. + adv7180_write_reg(ADV7180_SD_SATURATION_CR, tmp);
  65736. + adv7180_data.sen.saturation = vc->value;
  65737. + break;
  65738. + case V4L2_CID_HUE:
  65739. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65740. + " V4L2_CID_HUE\n");
  65741. + break;
  65742. + case V4L2_CID_AUTO_WHITE_BALANCE:
  65743. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65744. + " V4L2_CID_AUTO_WHITE_BALANCE\n");
  65745. + break;
  65746. + case V4L2_CID_DO_WHITE_BALANCE:
  65747. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65748. + " V4L2_CID_DO_WHITE_BALANCE\n");
  65749. + break;
  65750. + case V4L2_CID_RED_BALANCE:
  65751. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65752. + " V4L2_CID_RED_BALANCE\n");
  65753. + break;
  65754. + case V4L2_CID_BLUE_BALANCE:
  65755. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65756. + " V4L2_CID_BLUE_BALANCE\n");
  65757. + break;
  65758. + case V4L2_CID_GAMMA:
  65759. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65760. + " V4L2_CID_GAMMA\n");
  65761. + break;
  65762. + case V4L2_CID_EXPOSURE:
  65763. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65764. + " V4L2_CID_EXPOSURE\n");
  65765. + break;
  65766. + case V4L2_CID_AUTOGAIN:
  65767. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65768. + " V4L2_CID_AUTOGAIN\n");
  65769. + break;
  65770. + case V4L2_CID_GAIN:
  65771. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65772. + " V4L2_CID_GAIN\n");
  65773. + break;
  65774. + case V4L2_CID_HFLIP:
  65775. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65776. + " V4L2_CID_HFLIP\n");
  65777. + break;
  65778. + case V4L2_CID_VFLIP:
  65779. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65780. + " V4L2_CID_VFLIP\n");
  65781. + break;
  65782. + default:
  65783. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65784. + " Default case\n");
  65785. + retval = -EPERM;
  65786. + break;
  65787. + }
  65788. +
  65789. + return retval;
  65790. +}
  65791. +
  65792. +/*!
  65793. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  65794. + * VIDIOC_ENUM_FRAMESIZES ioctl
  65795. + * @s: pointer to standard V4L2 device structure
  65796. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  65797. + *
  65798. + * Return 0 if successful, otherwise -EINVAL.
  65799. + */
  65800. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  65801. + struct v4l2_frmsizeenum *fsize)
  65802. +{
  65803. + if (fsize->index >= 1)
  65804. + return -EINVAL;
  65805. +
  65806. + fsize->discrete.width = video_fmts[video_idx].active_width;
  65807. + fsize->discrete.height = video_fmts[video_idx].active_height;
  65808. +
  65809. + return 0;
  65810. +}
  65811. +
  65812. +/*!
  65813. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  65814. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  65815. + * @s: pointer to standard V4L2 device structure
  65816. + * @id: pointer to int
  65817. + *
  65818. + * Return 0.
  65819. + */
  65820. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  65821. +{
  65822. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  65823. + V4L2_CHIP_MATCH_I2C_DRIVER;
  65824. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
  65825. + "adv7180_decoder");
  65826. + ((struct v4l2_dbg_chip_ident *)id)->ident = V4L2_IDENT_ADV7180;
  65827. +
  65828. + return 0;
  65829. +}
  65830. +
  65831. +/*!
  65832. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  65833. + * @s: pointer to standard V4L2 device structure
  65834. + */
  65835. +static int ioctl_init(struct v4l2_int_device *s)
  65836. +{
  65837. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_init\n");
  65838. + return 0;
  65839. +}
  65840. +
  65841. +/*!
  65842. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  65843. + * @s: pointer to standard V4L2 device structure
  65844. + *
  65845. + * Initialise the device when slave attaches to the master.
  65846. + */
  65847. +static int ioctl_dev_init(struct v4l2_int_device *s)
  65848. +{
  65849. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_dev_init\n");
  65850. + return 0;
  65851. +}
  65852. +
  65853. +/*!
  65854. + * This structure defines all the ioctls for this module.
  65855. + */
  65856. +static struct v4l2_int_ioctl_desc adv7180_ioctl_desc[] = {
  65857. +
  65858. + {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*)ioctl_dev_init},
  65859. +
  65860. + /*!
  65861. + * Delinitialise the dev. at slave detach.
  65862. + * The complement of ioctl_dev_init.
  65863. + */
  65864. +/* {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func *)ioctl_dev_exit}, */
  65865. +
  65866. + {vidioc_int_s_power_num, (v4l2_int_ioctl_func*)ioctl_s_power},
  65867. + {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*)ioctl_g_ifparm},
  65868. +/* {vidioc_int_g_needs_reset_num,
  65869. + (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
  65870. +/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
  65871. + {vidioc_int_init_num, (v4l2_int_ioctl_func*)ioctl_init},
  65872. +
  65873. + /*!
  65874. + * VIDIOC_ENUM_FMT ioctl for the CAPTURE buffer type.
  65875. + */
  65876. +/* {vidioc_int_enum_fmt_cap_num,
  65877. + (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap}, */
  65878. +
  65879. + /*!
  65880. + * VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type.
  65881. + * This ioctl is used to negotiate the image capture size and
  65882. + * pixel format without actually making it take effect.
  65883. + */
  65884. +/* {vidioc_int_try_fmt_cap_num,
  65885. + (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
  65886. +
  65887. + {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func*)ioctl_g_fmt_cap},
  65888. +
  65889. + /*!
  65890. + * If the requested format is supported, configures the HW to use that
  65891. + * format, returns error code if format not supported or HW can't be
  65892. + * correctly configured.
  65893. + */
  65894. +/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *)ioctl_s_fmt_cap}, */
  65895. +
  65896. + {vidioc_int_g_parm_num, (v4l2_int_ioctl_func*)ioctl_g_parm},
  65897. + {vidioc_int_s_parm_num, (v4l2_int_ioctl_func*)ioctl_s_parm},
  65898. + {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func*)ioctl_queryctrl},
  65899. + {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func*)ioctl_g_ctrl},
  65900. + {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func*)ioctl_s_ctrl},
  65901. + {vidioc_int_enum_framesizes_num,
  65902. + (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
  65903. + {vidioc_int_g_chip_ident_num,
  65904. + (v4l2_int_ioctl_func *)ioctl_g_chip_ident},
  65905. +};
  65906. +
  65907. +static struct v4l2_int_slave adv7180_slave = {
  65908. + .ioctls = adv7180_ioctl_desc,
  65909. + .num_ioctls = ARRAY_SIZE(adv7180_ioctl_desc),
  65910. +};
  65911. +
  65912. +static struct v4l2_int_device adv7180_int_device = {
  65913. + .module = THIS_MODULE,
  65914. + .name = "adv7180",
  65915. + .type = v4l2_int_type_slave,
  65916. + .u = {
  65917. + .slave = &adv7180_slave,
  65918. + },
  65919. +};
  65920. +
  65921. +
  65922. +/***********************************************************************
  65923. + * I2C client and driver.
  65924. + ***********************************************************************/
  65925. +
  65926. +/*! ADV7180 Reset function.
  65927. + *
  65928. + * @return None.
  65929. + */
  65930. +static void adv7180_hard_reset(bool cvbs)
  65931. +{
  65932. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  65933. + "In adv7180:adv7180_hard_reset\n");
  65934. +
  65935. + if (cvbs) {
  65936. + /* Set CVBS input on AIN1 */
  65937. + adv7180_write_reg(ADV7180_INPUT_CTL, 0x00);
  65938. + } else {
  65939. + /*
  65940. + * Set YPbPr input on AIN1,4,5 and normal
  65941. + * operations(autodection of all stds).
  65942. + */
  65943. + adv7180_write_reg(ADV7180_INPUT_CTL, 0x09);
  65944. + }
  65945. +
  65946. + /* Datasheet recommends */
  65947. + adv7180_write_reg(0x01, 0xc8);
  65948. + adv7180_write_reg(0x02, 0x04);
  65949. + adv7180_write_reg(0x03, 0x00);
  65950. + adv7180_write_reg(0x04, 0x45);
  65951. + adv7180_write_reg(0x05, 0x00);
  65952. + adv7180_write_reg(0x06, 0x02);
  65953. + adv7180_write_reg(0x07, 0x7F);
  65954. + adv7180_write_reg(0x08, 0x80);
  65955. + adv7180_write_reg(0x0A, 0x00);
  65956. + adv7180_write_reg(0x0B, 0x00);
  65957. + adv7180_write_reg(0x0C, 0x36);
  65958. + adv7180_write_reg(0x0D, 0x7C);
  65959. + adv7180_write_reg(0x0E, 0x00);
  65960. + adv7180_write_reg(0x0F, 0x00);
  65961. + adv7180_write_reg(0x13, 0x00);
  65962. + adv7180_write_reg(0x14, 0x12);
  65963. + adv7180_write_reg(0x15, 0x00);
  65964. + adv7180_write_reg(0x16, 0x00);
  65965. + adv7180_write_reg(0x17, 0x01);
  65966. + adv7180_write_reg(0x18, 0x93);
  65967. + adv7180_write_reg(0xF1, 0x19);
  65968. + adv7180_write_reg(0x1A, 0x00);
  65969. + adv7180_write_reg(0x1B, 0x00);
  65970. + adv7180_write_reg(0x1C, 0x00);
  65971. + adv7180_write_reg(0x1D, 0x40);
  65972. + adv7180_write_reg(0x1E, 0x00);
  65973. + adv7180_write_reg(0x1F, 0x00);
  65974. + adv7180_write_reg(0x20, 0x00);
  65975. + adv7180_write_reg(0x21, 0x00);
  65976. + adv7180_write_reg(0x22, 0x00);
  65977. + adv7180_write_reg(0x23, 0xC0);
  65978. + adv7180_write_reg(0x24, 0x00);
  65979. + adv7180_write_reg(0x25, 0x00);
  65980. + adv7180_write_reg(0x26, 0x00);
  65981. + adv7180_write_reg(0x27, 0x58);
  65982. + adv7180_write_reg(0x28, 0x00);
  65983. + adv7180_write_reg(0x29, 0x00);
  65984. + adv7180_write_reg(0x2A, 0x00);
  65985. + adv7180_write_reg(0x2B, 0xE1);
  65986. + adv7180_write_reg(0x2C, 0xAE);
  65987. + adv7180_write_reg(0x2D, 0xF4);
  65988. + adv7180_write_reg(0x2E, 0x00);
  65989. + adv7180_write_reg(0x2F, 0xF0);
  65990. + adv7180_write_reg(0x30, 0x00);
  65991. + adv7180_write_reg(0x31, 0x12);
  65992. + adv7180_write_reg(0x32, 0x41);
  65993. + adv7180_write_reg(0x33, 0x84);
  65994. + adv7180_write_reg(0x34, 0x00);
  65995. + adv7180_write_reg(0x35, 0x02);
  65996. + adv7180_write_reg(0x36, 0x00);
  65997. + adv7180_write_reg(0x37, 0x01);
  65998. + adv7180_write_reg(0x38, 0x80);
  65999. + adv7180_write_reg(0x39, 0xC0);
  66000. + adv7180_write_reg(0x3A, 0x10);
  66001. + adv7180_write_reg(0x3B, 0x05);
  66002. + adv7180_write_reg(0x3C, 0x58);
  66003. + adv7180_write_reg(0x3D, 0xB2);
  66004. + adv7180_write_reg(0x3E, 0x64);
  66005. + adv7180_write_reg(0x3F, 0xE4);
  66006. + adv7180_write_reg(0x40, 0x90);
  66007. + adv7180_write_reg(0x41, 0x01);
  66008. + adv7180_write_reg(0x42, 0x7E);
  66009. + adv7180_write_reg(0x43, 0xA4);
  66010. + adv7180_write_reg(0x44, 0xFF);
  66011. + adv7180_write_reg(0x45, 0xB6);
  66012. + adv7180_write_reg(0x46, 0x12);
  66013. + adv7180_write_reg(0x48, 0x00);
  66014. + adv7180_write_reg(0x49, 0x00);
  66015. + adv7180_write_reg(0x4A, 0x00);
  66016. + adv7180_write_reg(0x4B, 0x00);
  66017. + adv7180_write_reg(0x4C, 0x00);
  66018. + adv7180_write_reg(0x4D, 0xEF);
  66019. + adv7180_write_reg(0x4E, 0x08);
  66020. + adv7180_write_reg(0x4F, 0x08);
  66021. + adv7180_write_reg(0x50, 0x08);
  66022. + adv7180_write_reg(0x51, 0x24);
  66023. + adv7180_write_reg(0x52, 0x0B);
  66024. + adv7180_write_reg(0x53, 0x4E);
  66025. + adv7180_write_reg(0x54, 0x80);
  66026. + adv7180_write_reg(0x55, 0x00);
  66027. + adv7180_write_reg(0x56, 0x10);
  66028. + adv7180_write_reg(0x57, 0x00);
  66029. + adv7180_write_reg(0x58, 0x00);
  66030. + adv7180_write_reg(0x59, 0x00);
  66031. + adv7180_write_reg(0x5A, 0x00);
  66032. + adv7180_write_reg(0x5B, 0x00);
  66033. + adv7180_write_reg(0x5C, 0x00);
  66034. + adv7180_write_reg(0x5D, 0x00);
  66035. + adv7180_write_reg(0x5E, 0x00);
  66036. + adv7180_write_reg(0x5F, 0x00);
  66037. + adv7180_write_reg(0x60, 0x00);
  66038. + adv7180_write_reg(0x61, 0x00);
  66039. + adv7180_write_reg(0x62, 0x20);
  66040. + adv7180_write_reg(0x63, 0x00);
  66041. + adv7180_write_reg(0x64, 0x00);
  66042. + adv7180_write_reg(0x65, 0x00);
  66043. + adv7180_write_reg(0x66, 0x00);
  66044. + adv7180_write_reg(0x67, 0x03);
  66045. + adv7180_write_reg(0x68, 0x01);
  66046. + adv7180_write_reg(0x69, 0x00);
  66047. + adv7180_write_reg(0x6A, 0x00);
  66048. + adv7180_write_reg(0x6B, 0xC0);
  66049. + adv7180_write_reg(0x6C, 0x00);
  66050. + adv7180_write_reg(0x6D, 0x00);
  66051. + adv7180_write_reg(0x6E, 0x00);
  66052. + adv7180_write_reg(0x6F, 0x00);
  66053. + adv7180_write_reg(0x70, 0x00);
  66054. + adv7180_write_reg(0x71, 0x00);
  66055. + adv7180_write_reg(0x72, 0x00);
  66056. + adv7180_write_reg(0x73, 0x10);
  66057. + adv7180_write_reg(0x74, 0x04);
  66058. + adv7180_write_reg(0x75, 0x01);
  66059. + adv7180_write_reg(0x76, 0x00);
  66060. + adv7180_write_reg(0x77, 0x3F);
  66061. + adv7180_write_reg(0x78, 0xFF);
  66062. + adv7180_write_reg(0x79, 0xFF);
  66063. + adv7180_write_reg(0x7A, 0xFF);
  66064. + adv7180_write_reg(0x7B, 0x1E);
  66065. + adv7180_write_reg(0x7C, 0xC0);
  66066. + adv7180_write_reg(0x7D, 0x00);
  66067. + adv7180_write_reg(0x7E, 0x00);
  66068. + adv7180_write_reg(0x7F, 0x00);
  66069. + adv7180_write_reg(0x80, 0x00);
  66070. + adv7180_write_reg(0x81, 0xC0);
  66071. + adv7180_write_reg(0x82, 0x04);
  66072. + adv7180_write_reg(0x83, 0x00);
  66073. + adv7180_write_reg(0x84, 0x0C);
  66074. + adv7180_write_reg(0x85, 0x02);
  66075. + adv7180_write_reg(0x86, 0x03);
  66076. + adv7180_write_reg(0x87, 0x63);
  66077. + adv7180_write_reg(0x88, 0x5A);
  66078. + adv7180_write_reg(0x89, 0x08);
  66079. + adv7180_write_reg(0x8A, 0x10);
  66080. + adv7180_write_reg(0x8B, 0x00);
  66081. + adv7180_write_reg(0x8C, 0x40);
  66082. + adv7180_write_reg(0x8D, 0x00);
  66083. + adv7180_write_reg(0x8E, 0x40);
  66084. + adv7180_write_reg(0x8F, 0x00);
  66085. + adv7180_write_reg(0x90, 0x00);
  66086. + adv7180_write_reg(0x91, 0x50);
  66087. + adv7180_write_reg(0x92, 0x00);
  66088. + adv7180_write_reg(0x93, 0x00);
  66089. + adv7180_write_reg(0x94, 0x00);
  66090. + adv7180_write_reg(0x95, 0x00);
  66091. + adv7180_write_reg(0x96, 0x00);
  66092. + adv7180_write_reg(0x97, 0xF0);
  66093. + adv7180_write_reg(0x98, 0x00);
  66094. + adv7180_write_reg(0x99, 0x00);
  66095. + adv7180_write_reg(0x9A, 0x00);
  66096. + adv7180_write_reg(0x9B, 0x00);
  66097. + adv7180_write_reg(0x9C, 0x00);
  66098. + adv7180_write_reg(0x9D, 0x00);
  66099. + adv7180_write_reg(0x9E, 0x00);
  66100. + adv7180_write_reg(0x9F, 0x00);
  66101. + adv7180_write_reg(0xA0, 0x00);
  66102. + adv7180_write_reg(0xA1, 0x00);
  66103. + adv7180_write_reg(0xA2, 0x00);
  66104. + adv7180_write_reg(0xA3, 0x00);
  66105. + adv7180_write_reg(0xA4, 0x00);
  66106. + adv7180_write_reg(0xA5, 0x00);
  66107. + adv7180_write_reg(0xA6, 0x00);
  66108. + adv7180_write_reg(0xA7, 0x00);
  66109. + adv7180_write_reg(0xA8, 0x00);
  66110. + adv7180_write_reg(0xA9, 0x00);
  66111. + adv7180_write_reg(0xAA, 0x00);
  66112. + adv7180_write_reg(0xAB, 0x00);
  66113. + adv7180_write_reg(0xAC, 0x00);
  66114. + adv7180_write_reg(0xAD, 0x00);
  66115. + adv7180_write_reg(0xAE, 0x60);
  66116. + adv7180_write_reg(0xAF, 0x00);
  66117. + adv7180_write_reg(0xB0, 0x00);
  66118. + adv7180_write_reg(0xB1, 0x60);
  66119. + adv7180_write_reg(0xB2, 0x1C);
  66120. + adv7180_write_reg(0xB3, 0x54);
  66121. + adv7180_write_reg(0xB4, 0x00);
  66122. + adv7180_write_reg(0xB5, 0x00);
  66123. + adv7180_write_reg(0xB6, 0x00);
  66124. + adv7180_write_reg(0xB7, 0x13);
  66125. + adv7180_write_reg(0xB8, 0x03);
  66126. + adv7180_write_reg(0xB9, 0x33);
  66127. + adv7180_write_reg(0xBF, 0x02);
  66128. + adv7180_write_reg(0xC0, 0x00);
  66129. + adv7180_write_reg(0xC1, 0x00);
  66130. + adv7180_write_reg(0xC2, 0x00);
  66131. + adv7180_write_reg(0xC3, 0x00);
  66132. + adv7180_write_reg(0xC4, 0x00);
  66133. + adv7180_write_reg(0xC5, 0x81);
  66134. + adv7180_write_reg(0xC6, 0x00);
  66135. + adv7180_write_reg(0xC7, 0x00);
  66136. + adv7180_write_reg(0xC8, 0x00);
  66137. + adv7180_write_reg(0xC9, 0x04);
  66138. + adv7180_write_reg(0xCC, 0x69);
  66139. + adv7180_write_reg(0xCD, 0x00);
  66140. + adv7180_write_reg(0xCE, 0x01);
  66141. + adv7180_write_reg(0xCF, 0xB4);
  66142. + adv7180_write_reg(0xD0, 0x00);
  66143. + adv7180_write_reg(0xD1, 0x10);
  66144. + adv7180_write_reg(0xD2, 0xFF);
  66145. + adv7180_write_reg(0xD3, 0xFF);
  66146. + adv7180_write_reg(0xD4, 0x7F);
  66147. + adv7180_write_reg(0xD5, 0x7F);
  66148. + adv7180_write_reg(0xD6, 0x3E);
  66149. + adv7180_write_reg(0xD7, 0x08);
  66150. + adv7180_write_reg(0xD8, 0x3C);
  66151. + adv7180_write_reg(0xD9, 0x08);
  66152. + adv7180_write_reg(0xDA, 0x3C);
  66153. + adv7180_write_reg(0xDB, 0x9B);
  66154. + adv7180_write_reg(0xDC, 0xAC);
  66155. + adv7180_write_reg(0xDD, 0x4C);
  66156. + adv7180_write_reg(0xDE, 0x00);
  66157. + adv7180_write_reg(0xDF, 0x00);
  66158. + adv7180_write_reg(0xE0, 0x14);
  66159. + adv7180_write_reg(0xE1, 0x80);
  66160. + adv7180_write_reg(0xE2, 0x80);
  66161. + adv7180_write_reg(0xE3, 0x80);
  66162. + adv7180_write_reg(0xE4, 0x80);
  66163. + adv7180_write_reg(0xE5, 0x25);
  66164. + adv7180_write_reg(0xE6, 0x44);
  66165. + adv7180_write_reg(0xE7, 0x63);
  66166. + adv7180_write_reg(0xE8, 0x65);
  66167. + adv7180_write_reg(0xE9, 0x14);
  66168. + adv7180_write_reg(0xEA, 0x63);
  66169. + adv7180_write_reg(0xEB, 0x55);
  66170. + adv7180_write_reg(0xEC, 0x55);
  66171. + adv7180_write_reg(0xEE, 0x00);
  66172. + adv7180_write_reg(0xEF, 0x4A);
  66173. + adv7180_write_reg(0xF0, 0x44);
  66174. + adv7180_write_reg(0xF1, 0x0C);
  66175. + adv7180_write_reg(0xF2, 0x32);
  66176. + adv7180_write_reg(0xF3, 0x00);
  66177. + adv7180_write_reg(0xF4, 0x3F);
  66178. + adv7180_write_reg(0xF5, 0xE0);
  66179. + adv7180_write_reg(0xF6, 0x69);
  66180. + adv7180_write_reg(0xF7, 0x10);
  66181. + adv7180_write_reg(0xF8, 0x00);
  66182. + adv7180_write_reg(0xF9, 0x03);
  66183. + adv7180_write_reg(0xFA, 0xFA);
  66184. + adv7180_write_reg(0xFB, 0x40);
  66185. +}
  66186. +
  66187. +/*! ADV7180 I2C attach function.
  66188. + *
  66189. + * @param *adapter struct i2c_adapter *.
  66190. + *
  66191. + * @return Error code indicating success or failure.
  66192. + */
  66193. +
  66194. +/*!
  66195. + * ADV7180 I2C probe function.
  66196. + * Function set in i2c_driver struct.
  66197. + * Called by insmod.
  66198. + *
  66199. + * @param *adapter I2C adapter descriptor.
  66200. + *
  66201. + * @return Error code indicating success or failure.
  66202. + */
  66203. +static int adv7180_probe(struct i2c_client *client,
  66204. + const struct i2c_device_id *id)
  66205. +{
  66206. + int rev_id;
  66207. + int ret = 0;
  66208. + u32 cvbs = true;
  66209. + struct pinctrl *pinctrl;
  66210. + struct device *dev = &client->dev;
  66211. +
  66212. + printk(KERN_ERR"DBG sensor data is at %p\n", &adv7180_data);
  66213. +
  66214. + /* ov5640 pinctrl */
  66215. + pinctrl = devm_pinctrl_get_select_default(dev);
  66216. + if (IS_ERR(pinctrl)) {
  66217. + dev_err(dev, "setup pinctrl failed\n");
  66218. + return PTR_ERR(pinctrl);
  66219. + }
  66220. +
  66221. + /* request power down pin */
  66222. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  66223. + if (!gpio_is_valid(pwn_gpio)) {
  66224. + dev_err(dev, "no sensor pwdn pin available\n");
  66225. + return -ENODEV;
  66226. + }
  66227. + ret = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  66228. + "adv7180_pwdn");
  66229. + if (ret < 0) {
  66230. + dev_err(dev, "no power pin available!\n");
  66231. + return ret;
  66232. + }
  66233. +
  66234. + adv7180_regulator_enable(dev);
  66235. +
  66236. + adv7180_power_down(0);
  66237. +
  66238. + msleep(1);
  66239. +
  66240. + /* Set initial values for the sensor struct. */
  66241. + memset(&adv7180_data, 0, sizeof(adv7180_data));
  66242. + adv7180_data.sen.i2c_client = client;
  66243. + adv7180_data.sen.streamcap.timeperframe.denominator = 30;
  66244. + adv7180_data.sen.streamcap.timeperframe.numerator = 1;
  66245. + adv7180_data.std_id = V4L2_STD_ALL;
  66246. + video_idx = ADV7180_NOT_LOCKED;
  66247. + adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
  66248. + adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
  66249. + adv7180_data.sen.pix.pixelformat = V4L2_PIX_FMT_UYVY; /* YUV422 */
  66250. + adv7180_data.sen.pix.priv = 1; /* 1 is used to indicate TV in */
  66251. + adv7180_data.sen.on = true;
  66252. +
  66253. + adv7180_data.sen.sensor_clk = devm_clk_get(dev, "csi_mclk");
  66254. + if (IS_ERR(adv7180_data.sen.sensor_clk)) {
  66255. + dev_err(dev, "get mclk failed\n");
  66256. + return PTR_ERR(adv7180_data.sen.sensor_clk);
  66257. + }
  66258. +
  66259. + ret = of_property_read_u32(dev->of_node, "mclk",
  66260. + &adv7180_data.sen.mclk);
  66261. + if (ret) {
  66262. + dev_err(dev, "mclk frequency is invalid\n");
  66263. + return ret;
  66264. + }
  66265. +
  66266. + ret = of_property_read_u32(
  66267. + dev->of_node, "mclk_source",
  66268. + (u32 *) &(adv7180_data.sen.mclk_source));
  66269. + if (ret) {
  66270. + dev_err(dev, "mclk_source invalid\n");
  66271. + return ret;
  66272. + }
  66273. +
  66274. + ret = of_property_read_u32(dev->of_node, "csi_id",
  66275. + &(adv7180_data.sen.csi));
  66276. + if (ret) {
  66277. + dev_err(dev, "csi_id invalid\n");
  66278. + return ret;
  66279. + }
  66280. +
  66281. + clk_prepare_enable(adv7180_data.sen.sensor_clk);
  66282. +
  66283. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  66284. + "%s:adv7180 probe i2c address is 0x%02X\n",
  66285. + __func__, adv7180_data.sen.i2c_client->addr);
  66286. +
  66287. + /*! Read the revision ID of the tvin chip */
  66288. + rev_id = adv7180_read(ADV7180_IDENT);
  66289. + dev_dbg(dev,
  66290. + "%s:Analog Device adv7%2X0 detected!\n", __func__,
  66291. + rev_id);
  66292. +
  66293. + ret = of_property_read_u32(dev->of_node, "cvbs", &(cvbs));
  66294. + if (ret) {
  66295. + dev_err(dev, "cvbs setting is not found\n");
  66296. + cvbs = true;
  66297. + }
  66298. +
  66299. + /*! ADV7180 initialization. */
  66300. + adv7180_hard_reset(cvbs);
  66301. +
  66302. + pr_debug(" type is %d (expect %d)\n",
  66303. + adv7180_int_device.type, v4l2_int_type_slave);
  66304. + pr_debug(" num ioctls is %d\n",
  66305. + adv7180_int_device.u.slave->num_ioctls);
  66306. +
  66307. + /* This function attaches this structure to the /dev/video0 device.
  66308. + * The pointer in priv points to the adv7180_data structure here.*/
  66309. + adv7180_int_device.priv = &adv7180_data;
  66310. + ret = v4l2_int_device_register(&adv7180_int_device);
  66311. +
  66312. + clk_disable_unprepare(adv7180_data.sen.sensor_clk);
  66313. +
  66314. + return ret;
  66315. +}
  66316. +
  66317. +/*!
  66318. + * ADV7180 I2C detach function.
  66319. + * Called on rmmod.
  66320. + *
  66321. + * @param *client struct i2c_client*.
  66322. + *
  66323. + * @return Error code indicating success or failure.
  66324. + */
  66325. +static int adv7180_detach(struct i2c_client *client)
  66326. +{
  66327. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  66328. + "%s:Removing %s video decoder @ 0x%02X from adapter %s\n",
  66329. + __func__, IF_NAME, client->addr << 1, client->adapter->name);
  66330. +
  66331. + /* Power down via i2c */
  66332. + adv7180_write_reg(ADV7180_PWR_MNG, 0x24);
  66333. +
  66334. + if (dvddio_regulator)
  66335. + regulator_disable(dvddio_regulator);
  66336. +
  66337. + if (dvdd_regulator)
  66338. + regulator_disable(dvdd_regulator);
  66339. +
  66340. + if (avdd_regulator)
  66341. + regulator_disable(avdd_regulator);
  66342. +
  66343. + if (pvdd_regulator)
  66344. + regulator_disable(pvdd_regulator);
  66345. +
  66346. + v4l2_int_device_unregister(&adv7180_int_device);
  66347. +
  66348. + return 0;
  66349. +}
  66350. +
  66351. +/*!
  66352. + * ADV7180 init function.
  66353. + * Called on insmod.
  66354. + *
  66355. + * @return Error code indicating success or failure.
  66356. + */
  66357. +static __init int adv7180_init(void)
  66358. +{
  66359. + u8 err = 0;
  66360. +
  66361. + pr_debug("In adv7180_init\n");
  66362. +
  66363. + /* Tells the i2c driver what functions to call for this driver. */
  66364. + err = i2c_add_driver(&adv7180_i2c_driver);
  66365. + if (err != 0)
  66366. + pr_err("%s:driver registration failed, error=%d\n",
  66367. + __func__, err);
  66368. +
  66369. + return err;
  66370. +}
  66371. +
  66372. +/*!
  66373. + * ADV7180 cleanup function.
  66374. + * Called on rmmod.
  66375. + *
  66376. + * @return Error code indicating success or failure.
  66377. + */
  66378. +static void __exit adv7180_clean(void)
  66379. +{
  66380. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_clean\n");
  66381. + i2c_del_driver(&adv7180_i2c_driver);
  66382. +}
  66383. +
  66384. +module_init(adv7180_init);
  66385. +module_exit(adv7180_clean);
  66386. +
  66387. +MODULE_AUTHOR("Freescale Semiconductor");
  66388. +MODULE_DESCRIPTION("Anolog Device ADV7180 video decoder driver");
  66389. +MODULE_LICENSE("GPL");
  66390. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/csi_v4l2_capture.c linux-imx6-3.14/drivers/media/platform/mxc/capture/csi_v4l2_capture.c
  66391. --- linux-3.14.14/drivers/media/platform/mxc/capture/csi_v4l2_capture.c 1969-12-31 18:00:00.000000000 -0600
  66392. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/csi_v4l2_capture.c 2014-12-08 00:31:53.256418001 -0600
  66393. @@ -0,0 +1,2047 @@
  66394. +/*
  66395. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  66396. + */
  66397. +
  66398. +/*
  66399. + * The code contained herein is licensed under the GNU General Public
  66400. + * License. You may obtain a copy of the GNU General Public License
  66401. + * Version 2 or later at the following locations:
  66402. + *
  66403. + * http://www.opensource.org/licenses/gpl-license.html
  66404. + * http://www.gnu.org/copyleft/gpl.html
  66405. + */
  66406. +
  66407. +/*!
  66408. + * @file drivers/media/video/mxc/capture/csi_v4l2_capture.c
  66409. + * This file is derived from mxc_v4l2_capture.c
  66410. + *
  66411. + * @brief Video For Linux 2 capture driver
  66412. + *
  66413. + * @ingroup MXC_V4L2_CAPTURE
  66414. + */
  66415. +#include <linux/version.h>
  66416. +#include <linux/module.h>
  66417. +#include <linux/init.h>
  66418. +#include <linux/platform_device.h>
  66419. +#include <linux/fs.h>
  66420. +#include <linux/slab.h>
  66421. +#include <linux/ctype.h>
  66422. +#include <linux/clk.h>
  66423. +#include <linux/io.h>
  66424. +#include <linux/semaphore.h>
  66425. +#include <linux/pagemap.h>
  66426. +#include <linux/vmalloc.h>
  66427. +#include <linux/types.h>
  66428. +#include <linux/fb.h>
  66429. +#include <linux/mxcfb.h>
  66430. +#include <linux/dma-mapping.h>
  66431. +#include <media/v4l2-ioctl.h>
  66432. +#include <media/v4l2-int-device.h>
  66433. +#include <media/v4l2-chip-ident.h>
  66434. +#include "mxc_v4l2_capture.h"
  66435. +#include "fsl_csi.h"
  66436. +
  66437. +static int video_nr = -1;
  66438. +static cam_data *g_cam;
  66439. +static int req_buf_number;
  66440. +
  66441. +static int csi_v4l2_master_attach(struct v4l2_int_device *slave);
  66442. +static void csi_v4l2_master_detach(struct v4l2_int_device *slave);
  66443. +static u8 camera_power(cam_data *cam, bool cameraOn);
  66444. +struct v4l2_crop crop_current;
  66445. +struct v4l2_window win_current;
  66446. +
  66447. +/*! Information about this driver. */
  66448. +static struct v4l2_int_master csi_v4l2_master = {
  66449. + .attach = csi_v4l2_master_attach,
  66450. + .detach = csi_v4l2_master_detach,
  66451. +};
  66452. +
  66453. +static struct v4l2_int_device csi_v4l2_int_device = {
  66454. + .module = THIS_MODULE,
  66455. + .name = "csi_v4l2_cap",
  66456. + .type = v4l2_int_type_master,
  66457. + .u = {
  66458. + .master = &csi_v4l2_master,
  66459. + },
  66460. +};
  66461. +
  66462. +static struct v4l2_queryctrl pxp_controls[] = {
  66463. + {
  66464. + .id = V4L2_CID_HFLIP,
  66465. + .type = V4L2_CTRL_TYPE_BOOLEAN,
  66466. + .name = "Horizontal Flip",
  66467. + .minimum = 0,
  66468. + .maximum = 1,
  66469. + .step = 1,
  66470. + .default_value = 0,
  66471. + .flags = 0,
  66472. + }, {
  66473. + .id = V4L2_CID_VFLIP,
  66474. + .type = V4L2_CTRL_TYPE_BOOLEAN,
  66475. + .name = "Vertical Flip",
  66476. + .minimum = 0,
  66477. + .maximum = 1,
  66478. + .step = 1,
  66479. + .default_value = 0,
  66480. + .flags = 0,
  66481. + }, {
  66482. + .id = V4L2_CID_PRIVATE_BASE,
  66483. + .type = V4L2_CTRL_TYPE_INTEGER,
  66484. + .name = "Rotation",
  66485. + .minimum = 0,
  66486. + .maximum = 270,
  66487. + .step = 90,
  66488. + .default_value = 0,
  66489. + .flags = 0,
  66490. + },
  66491. +};
  66492. +
  66493. +/* Callback function triggered after PxP receives an EOF interrupt */
  66494. +static void pxp_dma_done(void *arg)
  66495. +{
  66496. + struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
  66497. + struct dma_chan *chan = tx_desc->txd.chan;
  66498. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  66499. + cam_data *cam = pxp_chan->client;
  66500. +
  66501. + /* This call will signal wait_for_completion_timeout() */
  66502. + complete(&cam->pxp_tx_cmpl);
  66503. +}
  66504. +
  66505. +static bool chan_filter(struct dma_chan *chan, void *arg)
  66506. +{
  66507. + if (imx_dma_is_pxp(chan))
  66508. + return true;
  66509. + else
  66510. + return false;
  66511. +}
  66512. +
  66513. +/* Function to request PXP DMA channel */
  66514. +static int pxp_chan_init(cam_data *cam)
  66515. +{
  66516. + dma_cap_mask_t mask;
  66517. + struct dma_chan *chan;
  66518. +
  66519. + /* Request a free channel */
  66520. + dma_cap_zero(mask);
  66521. + dma_cap_set(DMA_SLAVE, mask);
  66522. + dma_cap_set(DMA_PRIVATE, mask);
  66523. + chan = dma_request_channel(mask, chan_filter, NULL);
  66524. + if (!chan) {
  66525. + pr_err("Unsuccessfully request channel!\n");
  66526. + return -EBUSY;
  66527. + }
  66528. +
  66529. + cam->pxp_chan = to_pxp_channel(chan);
  66530. + cam->pxp_chan->client = cam;
  66531. +
  66532. + init_completion(&cam->pxp_tx_cmpl);
  66533. +
  66534. + return 0;
  66535. +}
  66536. +
  66537. +/*
  66538. + * Function to call PxP DMA driver and send our new V4L2 buffer
  66539. + * through the PxP.
  66540. + * Note: This is a blocking call, so upon return the PxP tx should be complete.
  66541. + */
  66542. +static int pxp_process_update(cam_data *cam)
  66543. +{
  66544. + dma_cookie_t cookie;
  66545. + struct scatterlist *sg = cam->sg;
  66546. + struct dma_chan *dma_chan;
  66547. + struct pxp_tx_desc *desc;
  66548. + struct dma_async_tx_descriptor *txd;
  66549. + struct pxp_config_data *pxp_conf = &cam->pxp_conf;
  66550. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  66551. + int i, ret;
  66552. + int length;
  66553. +
  66554. + pr_debug("Starting PxP Send Buffer\n");
  66555. +
  66556. + /* First, check to see that we have acquired a PxP Channel object */
  66557. + if (cam->pxp_chan == NULL) {
  66558. + /*
  66559. + * PxP Channel has not yet been created and initialized,
  66560. + * so let's go ahead and try
  66561. + */
  66562. + ret = pxp_chan_init(cam);
  66563. + if (ret) {
  66564. + /*
  66565. + * PxP channel init failed, and we can't use the
  66566. + * PxP until the PxP DMA driver has loaded, so we abort
  66567. + */
  66568. + pr_err("PxP chan init failed\n");
  66569. + return -ENODEV;
  66570. + }
  66571. + }
  66572. +
  66573. + /*
  66574. + * Init completion, so that we can be properly informed of
  66575. + * the completion of the PxP task when it is done.
  66576. + */
  66577. + init_completion(&cam->pxp_tx_cmpl);
  66578. +
  66579. + dma_chan = &cam->pxp_chan->dma_chan;
  66580. +
  66581. + txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg, 2,
  66582. + DMA_TO_DEVICE,
  66583. + DMA_PREP_INTERRUPT,
  66584. + NULL);
  66585. + if (!txd) {
  66586. + pr_err("Error preparing a DMA transaction descriptor.\n");
  66587. + return -EIO;
  66588. + }
  66589. +
  66590. + txd->callback_param = txd;
  66591. + txd->callback = pxp_dma_done;
  66592. +
  66593. + /*
  66594. + * Configure PxP for processing of new v4l2 buf
  66595. + */
  66596. + pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_UYVY;
  66597. + pxp_conf->s0_param.color_key = -1;
  66598. + pxp_conf->s0_param.color_key_enable = false;
  66599. + pxp_conf->s0_param.width = cam->v2f.fmt.pix.width;
  66600. + pxp_conf->s0_param.height = cam->v2f.fmt.pix.height;
  66601. +
  66602. + pxp_conf->ol_param[0].combine_enable = false;
  66603. +
  66604. + proc_data->srect.top = 0;
  66605. + proc_data->srect.left = 0;
  66606. + proc_data->srect.width = pxp_conf->s0_param.width;
  66607. + proc_data->srect.height = pxp_conf->s0_param.height;
  66608. +
  66609. + if (crop_current.c.top != 0)
  66610. + proc_data->srect.top = crop_current.c.top;
  66611. + if (crop_current.c.left != 0)
  66612. + proc_data->srect.left = crop_current.c.left;
  66613. + if (crop_current.c.width != 0)
  66614. + proc_data->srect.width = crop_current.c.width;
  66615. + if (crop_current.c.height != 0)
  66616. + proc_data->srect.height = crop_current.c.height;
  66617. +
  66618. + proc_data->drect.left = 0;
  66619. + proc_data->drect.top = 0;
  66620. + proc_data->drect.width = proc_data->srect.width;
  66621. + proc_data->drect.height = proc_data->srect.height;
  66622. +
  66623. + if (win_current.w.left != 0)
  66624. + proc_data->drect.left = win_current.w.left;
  66625. + if (win_current.w.top != 0)
  66626. + proc_data->drect.top = win_current.w.top;
  66627. + if (win_current.w.width != 0)
  66628. + proc_data->drect.width = win_current.w.width;
  66629. + if (win_current.w.height != 0)
  66630. + proc_data->drect.height = win_current.w.height;
  66631. +
  66632. + pr_debug("srect l: %d, t: %d, w: %d, h: %d; "
  66633. + "drect l: %d, t: %d, w: %d, h: %d\n",
  66634. + proc_data->srect.left, proc_data->srect.top,
  66635. + proc_data->srect.width, proc_data->srect.height,
  66636. + proc_data->drect.left, proc_data->drect.top,
  66637. + proc_data->drect.width, proc_data->drect.height);
  66638. +
  66639. + pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_RGB565;
  66640. + pxp_conf->out_param.width = proc_data->drect.width;
  66641. + pxp_conf->out_param.height = proc_data->drect.height;
  66642. +
  66643. + if (cam->rotation % 180)
  66644. + pxp_conf->out_param.stride = pxp_conf->out_param.height;
  66645. + else
  66646. + pxp_conf->out_param.stride = pxp_conf->out_param.width;
  66647. +
  66648. + desc = to_tx_desc(txd);
  66649. + length = desc->len;
  66650. + for (i = 0; i < length; i++) {
  66651. + if (i == 0) {/* S0 */
  66652. + memcpy(&desc->proc_data, proc_data,
  66653. + sizeof(struct pxp_proc_data));
  66654. + pxp_conf->s0_param.paddr = sg_dma_address(&sg[0]);
  66655. + memcpy(&desc->layer_param.s0_param, &pxp_conf->s0_param,
  66656. + sizeof(struct pxp_layer_param));
  66657. + } else if (i == 1) {
  66658. + pxp_conf->out_param.paddr = sg_dma_address(&sg[1]);
  66659. + memcpy(&desc->layer_param.out_param,
  66660. + &pxp_conf->out_param,
  66661. + sizeof(struct pxp_layer_param));
  66662. + }
  66663. +
  66664. + desc = desc->next;
  66665. + }
  66666. +
  66667. + /* Submitting our TX starts the PxP processing task */
  66668. + cookie = txd->tx_submit(txd);
  66669. + if (cookie < 0) {
  66670. + pr_err("Error sending FB through PxP\n");
  66671. + return -EIO;
  66672. + }
  66673. +
  66674. + cam->txd = txd;
  66675. +
  66676. + /* trigger PxP */
  66677. + dma_async_issue_pending(dma_chan);
  66678. +
  66679. + return 0;
  66680. +}
  66681. +
  66682. +static int pxp_complete_update(cam_data *cam)
  66683. +{
  66684. + int ret;
  66685. + /*
  66686. + * Wait for completion event, which will be set
  66687. + * through our TX callback function.
  66688. + */
  66689. + ret = wait_for_completion_timeout(&cam->pxp_tx_cmpl, HZ / 10);
  66690. + if (ret <= 0) {
  66691. + pr_warning("PxP operation failed due to %s\n",
  66692. + ret < 0 ? "user interrupt" : "timeout");
  66693. + dma_release_channel(&cam->pxp_chan->dma_chan);
  66694. + cam->pxp_chan = NULL;
  66695. + return ret ? : -ETIMEDOUT;
  66696. + }
  66697. +
  66698. + dma_release_channel(&cam->pxp_chan->dma_chan);
  66699. + cam->pxp_chan = NULL;
  66700. +
  66701. + pr_debug("TX completed\n");
  66702. +
  66703. + return 0;
  66704. +}
  66705. +
  66706. +/*!
  66707. + * Camera V4l2 callback function.
  66708. + *
  66709. + * @param mask u32
  66710. + * @param dev void device structure
  66711. + *
  66712. + * @return none
  66713. + */
  66714. +static void camera_callback(u32 mask, void *dev)
  66715. +{
  66716. + struct mxc_v4l_frame *done_frame;
  66717. + struct mxc_v4l_frame *ready_frame;
  66718. + cam_data *cam;
  66719. +
  66720. + cam = (cam_data *) dev;
  66721. + if (cam == NULL)
  66722. + return;
  66723. +
  66724. + spin_lock(&cam->queue_int_lock);
  66725. + spin_lock(&cam->dqueue_int_lock);
  66726. + if (!list_empty(&cam->working_q)) {
  66727. + done_frame = list_entry(cam->working_q.next,
  66728. + struct mxc_v4l_frame, queue);
  66729. +
  66730. + if (done_frame->csi_buf_num != cam->ping_pong_csi)
  66731. + goto next;
  66732. +
  66733. + if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  66734. + done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE;
  66735. + done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  66736. +
  66737. + /* Added to the done queue */
  66738. + list_del(cam->working_q.next);
  66739. + list_add_tail(&done_frame->queue, &cam->done_q);
  66740. + cam->enc_counter++;
  66741. + wake_up_interruptible(&cam->enc_queue);
  66742. + } else {
  66743. + pr_err("ERROR: v4l2 capture: %s: "
  66744. + "buffer not queued\n", __func__);
  66745. + }
  66746. + }
  66747. +
  66748. +next:
  66749. + if (!list_empty(&cam->ready_q)) {
  66750. + ready_frame = list_entry(cam->ready_q.next,
  66751. + struct mxc_v4l_frame, queue);
  66752. + list_del(cam->ready_q.next);
  66753. + list_add_tail(&ready_frame->queue, &cam->working_q);
  66754. +
  66755. + __raw_writel(ready_frame->paddress,
  66756. + cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 :
  66757. + CSI_CSIDMASA_FB2);
  66758. + ready_frame->csi_buf_num = cam->ping_pong_csi;
  66759. + } else {
  66760. + __raw_writel(cam->dummy_frame.paddress,
  66761. + cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 :
  66762. + CSI_CSIDMASA_FB2);
  66763. + }
  66764. + spin_unlock(&cam->dqueue_int_lock);
  66765. + spin_unlock(&cam->queue_int_lock);
  66766. +
  66767. + return;
  66768. +}
  66769. +
  66770. +/*!
  66771. + * Make csi ready for capture image.
  66772. + *
  66773. + * @param cam structure cam_data *
  66774. + *
  66775. + * @return status 0 success
  66776. + */
  66777. +static int csi_cap_image(cam_data *cam)
  66778. +{
  66779. + unsigned int value;
  66780. +
  66781. + value = __raw_readl(CSI_CSICR3);
  66782. + __raw_writel(value | BIT_FRMCNT_RST, CSI_CSICR3);
  66783. + value = __raw_readl(CSI_CSISR);
  66784. + __raw_writel(value, CSI_CSISR);
  66785. +
  66786. + return 0;
  66787. +}
  66788. +
  66789. +/***************************************************************************
  66790. + * Functions for handling Frame buffers.
  66791. + **************************************************************************/
  66792. +
  66793. +/*!
  66794. + * Free frame buffers
  66795. + *
  66796. + * @param cam Structure cam_data *
  66797. + *
  66798. + * @return status 0 success.
  66799. + */
  66800. +static int csi_free_frame_buf(cam_data *cam)
  66801. +{
  66802. + int i;
  66803. +
  66804. + pr_debug("MVC: In %s\n", __func__);
  66805. +
  66806. + for (i = 0; i < FRAME_NUM; i++) {
  66807. + if (cam->frame[i].vaddress != 0) {
  66808. + dma_free_coherent(0, cam->frame[i].buffer.length,
  66809. + cam->frame[i].vaddress,
  66810. + cam->frame[i].paddress);
  66811. + cam->frame[i].vaddress = 0;
  66812. + }
  66813. + }
  66814. +
  66815. + if (cam->dummy_frame.vaddress != 0) {
  66816. + dma_free_coherent(0, cam->dummy_frame.buffer.length,
  66817. + cam->dummy_frame.vaddress,
  66818. + cam->dummy_frame.paddress);
  66819. + cam->dummy_frame.vaddress = 0;
  66820. + }
  66821. +
  66822. + return 0;
  66823. +}
  66824. +
  66825. +/*!
  66826. + * Allocate frame buffers
  66827. + *
  66828. + * @param cam Structure cam_data *
  66829. + * @param count int number of buffer need to allocated
  66830. + *
  66831. + * @return status -0 Successfully allocated a buffer, -ENOBUFS failed.
  66832. + */
  66833. +static int csi_allocate_frame_buf(cam_data *cam, int count)
  66834. +{
  66835. + int i;
  66836. +
  66837. + pr_debug("In MVC:%s- size=%d\n",
  66838. + __func__, cam->v2f.fmt.pix.sizeimage);
  66839. + for (i = 0; i < count; i++) {
  66840. + cam->frame[i].vaddress = dma_alloc_coherent(0, PAGE_ALIGN
  66841. + (cam->v2f.fmt.
  66842. + pix.sizeimage),
  66843. + &cam->frame[i].
  66844. + paddress,
  66845. + GFP_DMA |
  66846. + GFP_KERNEL);
  66847. + if (cam->frame[i].vaddress == 0) {
  66848. + pr_err("ERROR: v4l2 capture: "
  66849. + "%s failed.\n", __func__);
  66850. + csi_free_frame_buf(cam);
  66851. + return -ENOBUFS;
  66852. + }
  66853. + cam->frame[i].buffer.index = i;
  66854. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  66855. + cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  66856. + cam->frame[i].buffer.length = cam->v2f.fmt.pix.sizeimage;
  66857. + cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP;
  66858. + cam->frame[i].buffer.m.offset = cam->frame[i].paddress;
  66859. + cam->frame[i].index = i;
  66860. + cam->frame[i].csi_buf_num = 0;
  66861. + }
  66862. +
  66863. + return 0;
  66864. +}
  66865. +
  66866. +/*!
  66867. + * Free frame buffers status
  66868. + *
  66869. + * @param cam Structure cam_data *
  66870. + *
  66871. + * @return none
  66872. + */
  66873. +static void csi_free_frames(cam_data *cam)
  66874. +{
  66875. + int i;
  66876. +
  66877. + pr_debug("In MVC: %s\n", __func__);
  66878. +
  66879. + for (i = 0; i < FRAME_NUM; i++)
  66880. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  66881. +
  66882. + cam->enc_counter = 0;
  66883. + INIT_LIST_HEAD(&cam->ready_q);
  66884. + INIT_LIST_HEAD(&cam->working_q);
  66885. + INIT_LIST_HEAD(&cam->done_q);
  66886. +
  66887. + return;
  66888. +}
  66889. +
  66890. +/*!
  66891. + * Return the buffer status
  66892. + *
  66893. + * @param cam Structure cam_data *
  66894. + * @param buf Structure v4l2_buffer *
  66895. + *
  66896. + * @return status 0 success, EINVAL failed.
  66897. + */
  66898. +static int csi_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf)
  66899. +{
  66900. + pr_debug("In MVC: %s\n", __func__);
  66901. +
  66902. + if (buf->index < 0 || buf->index >= FRAME_NUM) {
  66903. + pr_err("ERROR: v4l2 capture: %s buffers "
  66904. + "not allocated\n", __func__);
  66905. + return -EINVAL;
  66906. + }
  66907. +
  66908. + memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf));
  66909. +
  66910. + return 0;
  66911. +}
  66912. +
  66913. +static int csi_v4l2_release_bufs(cam_data *cam)
  66914. +{
  66915. + pr_debug("In MVC:csi_v4l2_release_bufs\n");
  66916. + return 0;
  66917. +}
  66918. +
  66919. +static int csi_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf)
  66920. +{
  66921. + pr_debug("In MVC:csi_v4l2_prepare_bufs\n");
  66922. +
  66923. + if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length <
  66924. + cam->v2f.fmt.pix.sizeimage) {
  66925. + pr_err("ERROR: v4l2 capture: csi_v4l2_prepare_bufs buffers "
  66926. + "not allocated,index=%d, length=%d\n", buf->index,
  66927. + buf->length);
  66928. + return -EINVAL;
  66929. + }
  66930. +
  66931. + cam->frame[buf->index].buffer.index = buf->index;
  66932. + cam->frame[buf->index].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  66933. + cam->frame[buf->index].buffer.length = buf->length;
  66934. + cam->frame[buf->index].buffer.m.offset = cam->frame[buf->index].paddress
  66935. + = buf->m.offset;
  66936. + cam->frame[buf->index].buffer.type = buf->type;
  66937. + cam->frame[buf->index].buffer.memory = V4L2_MEMORY_USERPTR;
  66938. + cam->frame[buf->index].index = buf->index;
  66939. +
  66940. + return 0;
  66941. +}
  66942. +
  66943. +/*!
  66944. + * Indicates whether the palette is supported.
  66945. + *
  66946. + * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_UYVY or V4L2_PIX_FMT_YUV420
  66947. + *
  66948. + * @return 0 if failed
  66949. + */
  66950. +static inline int valid_mode(u32 palette)
  66951. +{
  66952. + return (palette == V4L2_PIX_FMT_RGB565) ||
  66953. + (palette == V4L2_PIX_FMT_YUYV) ||
  66954. + (palette == V4L2_PIX_FMT_UYVY) || (palette == V4L2_PIX_FMT_YUV420);
  66955. +}
  66956. +
  66957. +/*!
  66958. + * Start stream I/O
  66959. + *
  66960. + * @param cam structure cam_data *
  66961. + *
  66962. + * @return status 0 Success
  66963. + */
  66964. +static int csi_streamon(cam_data *cam)
  66965. +{
  66966. + struct mxc_v4l_frame *frame;
  66967. + unsigned long flags;
  66968. + unsigned long val;
  66969. + int timeout, timeout2;
  66970. +
  66971. + pr_debug("In MVC: %s\n", __func__);
  66972. +
  66973. + if (NULL == cam) {
  66974. + pr_err("ERROR: v4l2 capture: %s cam parameter is NULL\n",
  66975. + __func__);
  66976. + return -1;
  66977. + }
  66978. + cam->dummy_frame.vaddress = dma_alloc_coherent(0,
  66979. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  66980. + &cam->dummy_frame.paddress,
  66981. + GFP_DMA | GFP_KERNEL);
  66982. + if (cam->dummy_frame.vaddress == 0) {
  66983. + pr_err("ERROR: v4l2 capture: Allocate dummy frame "
  66984. + "failed.\n");
  66985. + return -ENOBUFS;
  66986. + }
  66987. + cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
  66988. + cam->dummy_frame.buffer.length = cam->v2f.fmt.pix.sizeimage;
  66989. + cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
  66990. +
  66991. + spin_lock_irqsave(&cam->queue_int_lock, flags);
  66992. + /* move the frame from readyq to workingq */
  66993. + if (list_empty(&cam->ready_q)) {
  66994. + pr_err("ERROR: v4l2 capture: %s: "
  66995. + "ready_q queue empty\n", __func__);
  66996. + spin_unlock_irqrestore(&cam->queue_int_lock, flags);
  66997. + return -1;
  66998. + }
  66999. + frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  67000. + list_del(cam->ready_q.next);
  67001. + list_add_tail(&frame->queue, &cam->working_q);
  67002. + __raw_writel(frame->paddress, CSI_CSIDMASA_FB1);
  67003. + frame->csi_buf_num = 1;
  67004. +
  67005. + if (list_empty(&cam->ready_q)) {
  67006. + pr_err("ERROR: v4l2 capture: %s: "
  67007. + "ready_q queue empty\n", __func__);
  67008. + spin_unlock_irqrestore(&cam->queue_int_lock, flags);
  67009. + return -1;
  67010. + }
  67011. + frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  67012. + list_del(cam->ready_q.next);
  67013. + list_add_tail(&frame->queue, &cam->working_q);
  67014. + __raw_writel(frame->paddress, CSI_CSIDMASA_FB2);
  67015. + frame->csi_buf_num = 2;
  67016. + spin_unlock_irqrestore(&cam->queue_int_lock, flags);
  67017. +
  67018. + cam->capture_pid = current->pid;
  67019. + cam->capture_on = true;
  67020. + csi_cap_image(cam);
  67021. +
  67022. + local_irq_save(flags);
  67023. + for (timeout = 1000000; timeout > 0; timeout--) {
  67024. + if (__raw_readl(CSI_CSISR) & BIT_SOF_INT) {
  67025. + val = __raw_readl(CSI_CSICR3);
  67026. + __raw_writel(val | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  67027. + for (timeout2 = 1000000; timeout2 > 0; timeout2--) {
  67028. + if (__raw_readl(CSI_CSICR3) &
  67029. + BIT_DMA_REFLASH_RFF)
  67030. + cpu_relax();
  67031. + else
  67032. + break;
  67033. + }
  67034. + if (timeout2 <= 0) {
  67035. + pr_err("timeout when wait for reflash done.\n");
  67036. + local_irq_restore(flags);
  67037. + return -ETIME;
  67038. + }
  67039. +
  67040. + csi_dmareq_rff_enable();
  67041. + csi_enable_int(1);
  67042. + break;
  67043. + } else
  67044. + cpu_relax();
  67045. + }
  67046. + if (timeout <= 0) {
  67047. + pr_err("timeout when wait for SOF\n");
  67048. + local_irq_restore(flags);
  67049. + return -ETIME;
  67050. + }
  67051. + local_irq_restore(flags);
  67052. +
  67053. + return 0;
  67054. +}
  67055. +
  67056. +/*!
  67057. + * Stop stream I/O
  67058. + *
  67059. + * @param cam structure cam_data *
  67060. + *
  67061. + * @return status 0 Success
  67062. + */
  67063. +static int csi_streamoff(cam_data *cam)
  67064. +{
  67065. + pr_debug("In MVC: %s\n", __func__);
  67066. +
  67067. + if (cam->capture_on == false)
  67068. + return 0;
  67069. +
  67070. + csi_dmareq_rff_disable();
  67071. + csi_disable_int();
  67072. + cam->capture_on = false;
  67073. +
  67074. + /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
  67075. + __raw_writel(0, CSI_CSIDMASA_FB1);
  67076. + __raw_writel(0, CSI_CSIDMASA_FB2);
  67077. +
  67078. + csi_free_frames(cam);
  67079. + csi_free_frame_buf(cam);
  67080. +
  67081. + return 0;
  67082. +}
  67083. +
  67084. +/*!
  67085. + * start the viewfinder job
  67086. + *
  67087. + * @param cam structure cam_data *
  67088. + *
  67089. + * @return status 0 Success
  67090. + */
  67091. +static int start_preview(cam_data *cam)
  67092. +{
  67093. + unsigned long fb_addr = (unsigned long)cam->v4l2_fb.base;
  67094. +
  67095. + __raw_writel(fb_addr, CSI_CSIDMASA_FB1);
  67096. + __raw_writel(fb_addr, CSI_CSIDMASA_FB2);
  67097. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  67098. +
  67099. + csi_enable_int(0);
  67100. +
  67101. + return 0;
  67102. +}
  67103. +
  67104. +/*!
  67105. + * shut down the viewfinder job
  67106. + *
  67107. + * @param cam structure cam_data *
  67108. + *
  67109. + * @return status 0 Success
  67110. + */
  67111. +static int stop_preview(cam_data *cam)
  67112. +{
  67113. + csi_disable_int();
  67114. +
  67115. + /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
  67116. + __raw_writel(0, CSI_CSIDMASA_FB1);
  67117. + __raw_writel(0, CSI_CSIDMASA_FB2);
  67118. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  67119. +
  67120. + return 0;
  67121. +}
  67122. +
  67123. +/***************************************************************************
  67124. + * VIDIOC Functions.
  67125. + **************************************************************************/
  67126. +
  67127. +/*!
  67128. + *
  67129. + * @param cam structure cam_data *
  67130. + *
  67131. + * @param f structure v4l2_format *
  67132. + *
  67133. + * @return status 0 success, EINVAL failed
  67134. + */
  67135. +static int csi_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f)
  67136. +{
  67137. + int retval = 0;
  67138. +
  67139. + switch (f->type) {
  67140. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  67141. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  67142. + f->fmt.pix = cam->v2f.fmt.pix;
  67143. + break;
  67144. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  67145. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  67146. + f->fmt.win = cam->win;
  67147. + break;
  67148. + default:
  67149. + pr_debug(" type is invalid\n");
  67150. + retval = -EINVAL;
  67151. + }
  67152. +
  67153. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  67154. + __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  67155. +
  67156. + return retval;
  67157. +}
  67158. +
  67159. +/*!
  67160. + * V4L2 - csi_v4l2_s_fmt function
  67161. + *
  67162. + * @param cam structure cam_data *
  67163. + *
  67164. + * @param f structure v4l2_format *
  67165. + *
  67166. + * @return status 0 success, EINVAL failed
  67167. + */
  67168. +static int csi_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
  67169. +{
  67170. + int retval = 0;
  67171. + int size = 0;
  67172. + int bytesperline = 0;
  67173. + int *width, *height;
  67174. +
  67175. + pr_debug("In MVC: %s\n", __func__);
  67176. +
  67177. + switch (f->type) {
  67178. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  67179. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  67180. + if (!valid_mode(f->fmt.pix.pixelformat)) {
  67181. + pr_err("ERROR: v4l2 capture: %s: format "
  67182. + "not supported\n", __func__);
  67183. + return -EINVAL;
  67184. + }
  67185. +
  67186. + /* Handle case where size requested is larger than cuurent
  67187. + * camera setting. */
  67188. + if ((f->fmt.pix.width > cam->crop_bounds.width)
  67189. + || (f->fmt.pix.height > cam->crop_bounds.height)) {
  67190. + /* Need the logic here, calling vidioc_s_param if
  67191. + * camera can change. */
  67192. + pr_debug("csi_v4l2_s_fmt size changed\n");
  67193. + }
  67194. + if (cam->rotation % 180) {
  67195. + height = &f->fmt.pix.width;
  67196. + width = &f->fmt.pix.height;
  67197. + } else {
  67198. + width = &f->fmt.pix.width;
  67199. + height = &f->fmt.pix.height;
  67200. + }
  67201. +
  67202. + if ((cam->crop_bounds.width / *width > 8) ||
  67203. + ((cam->crop_bounds.width / *width == 8) &&
  67204. + (cam->crop_bounds.width % *width))) {
  67205. + *width = cam->crop_bounds.width / 8;
  67206. + if (*width % 8)
  67207. + *width += 8 - *width % 8;
  67208. + pr_err("ERROR: v4l2 capture: width exceeds limit "
  67209. + "resize to %d.\n", *width);
  67210. + }
  67211. +
  67212. + if ((cam->crop_bounds.height / *height > 8) ||
  67213. + ((cam->crop_bounds.height / *height == 8) &&
  67214. + (cam->crop_bounds.height % *height))) {
  67215. + *height = cam->crop_bounds.height / 8;
  67216. + if (*height % 8)
  67217. + *height += 8 - *height % 8;
  67218. + pr_err("ERROR: v4l2 capture: height exceeds limit "
  67219. + "resize to %d.\n", *height);
  67220. + }
  67221. +
  67222. + switch (f->fmt.pix.pixelformat) {
  67223. + case V4L2_PIX_FMT_RGB565:
  67224. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  67225. + csi_init_format(V4L2_PIX_FMT_UYVY);
  67226. + csi_set_16bit_imagpara(f->fmt.pix.width,
  67227. + f->fmt.pix.height);
  67228. + bytesperline = f->fmt.pix.width * 2;
  67229. + break;
  67230. + case V4L2_PIX_FMT_UYVY:
  67231. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  67232. + csi_init_format(f->fmt.pix.pixelformat);
  67233. + csi_set_16bit_imagpara(f->fmt.pix.width,
  67234. + f->fmt.pix.height);
  67235. + bytesperline = f->fmt.pix.width * 2;
  67236. + break;
  67237. + case V4L2_PIX_FMT_YUYV:
  67238. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  67239. + csi_init_format(f->fmt.pix.pixelformat);
  67240. + csi_set_16bit_imagpara(f->fmt.pix.width,
  67241. + f->fmt.pix.height);
  67242. + bytesperline = f->fmt.pix.width * 2;
  67243. + break;
  67244. + case V4L2_PIX_FMT_YUV420:
  67245. + size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
  67246. + csi_set_12bit_imagpara(f->fmt.pix.width,
  67247. + f->fmt.pix.height);
  67248. + bytesperline = f->fmt.pix.width;
  67249. + break;
  67250. + case V4L2_PIX_FMT_YUV422P:
  67251. + case V4L2_PIX_FMT_RGB24:
  67252. + case V4L2_PIX_FMT_BGR24:
  67253. + case V4L2_PIX_FMT_BGR32:
  67254. + case V4L2_PIX_FMT_RGB32:
  67255. + case V4L2_PIX_FMT_NV12:
  67256. + default:
  67257. + pr_debug(" case not supported\n");
  67258. + break;
  67259. + }
  67260. +
  67261. + if (f->fmt.pix.bytesperline < bytesperline)
  67262. + f->fmt.pix.bytesperline = bytesperline;
  67263. + else
  67264. + bytesperline = f->fmt.pix.bytesperline;
  67265. +
  67266. + if (f->fmt.pix.sizeimage < size)
  67267. + f->fmt.pix.sizeimage = size;
  67268. + else
  67269. + size = f->fmt.pix.sizeimage;
  67270. +
  67271. + cam->v2f.fmt.pix = f->fmt.pix;
  67272. +
  67273. + if (cam->v2f.fmt.pix.priv != 0) {
  67274. + if (copy_from_user(&cam->offset,
  67275. + (void *)cam->v2f.fmt.pix.priv,
  67276. + sizeof(cam->offset))) {
  67277. + retval = -EFAULT;
  67278. + break;
  67279. + }
  67280. + }
  67281. + break;
  67282. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  67283. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  67284. + cam->win = f->fmt.win;
  67285. + win_current = f->fmt.win;
  67286. + size = win_current.w.width * win_current.w.height * 2;
  67287. + if (cam->v2f.fmt.pix.sizeimage < size)
  67288. + cam->v2f.fmt.pix.sizeimage = size;
  67289. +
  67290. + break;
  67291. + default:
  67292. + retval = -EINVAL;
  67293. + }
  67294. +
  67295. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  67296. + __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  67297. +
  67298. + return retval;
  67299. +}
  67300. +
  67301. +/*!
  67302. + * V4L2 - csi_v4l2_s_param function
  67303. + * Allows setting of capturemode and frame rate.
  67304. + *
  67305. + * @param cam structure cam_data *
  67306. + * @param parm structure v4l2_streamparm *
  67307. + *
  67308. + * @return status 0 success, EINVAL failed
  67309. + */
  67310. +static int csi_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
  67311. +{
  67312. + struct v4l2_ifparm ifparm;
  67313. + struct v4l2_format cam_fmt;
  67314. + struct v4l2_streamparm currentparm;
  67315. + int err = 0;
  67316. +
  67317. + pr_debug("In %s\n", __func__);
  67318. +
  67319. + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  67320. + pr_err(KERN_ERR "%s invalid type\n", __func__);
  67321. + return -EINVAL;
  67322. + }
  67323. +
  67324. + /* Stop the viewfinder */
  67325. + if (cam->overlay_on == true)
  67326. + stop_preview(cam);
  67327. +
  67328. + currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  67329. +
  67330. + /* First check that this device can support the changes requested. */
  67331. + err = vidioc_int_g_parm(cam->sensor, &currentparm);
  67332. + if (err) {
  67333. + pr_err("%s: vidioc_int_g_parm returned an error %d\n",
  67334. + __func__, err);
  67335. + goto exit;
  67336. + }
  67337. +
  67338. + pr_debug(" Current capabilities are %x\n",
  67339. + currentparm.parm.capture.capability);
  67340. + pr_debug(" Current capturemode is %d change to %d\n",
  67341. + currentparm.parm.capture.capturemode,
  67342. + parm->parm.capture.capturemode);
  67343. + pr_debug(" Current framerate is %d change to %d\n",
  67344. + currentparm.parm.capture.timeperframe.denominator,
  67345. + parm->parm.capture.timeperframe.denominator);
  67346. +
  67347. + err = vidioc_int_s_parm(cam->sensor, parm);
  67348. + if (err) {
  67349. + pr_err("%s: vidioc_int_s_parm returned an error %d\n",
  67350. + __func__, err);
  67351. + goto exit;
  67352. + }
  67353. +
  67354. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  67355. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  67356. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  67357. + pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n",
  67358. + cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
  67359. +
  67360. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  67361. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  67362. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  67363. + cam->crop_current.width = cam->crop_bounds.width;
  67364. + cam->crop_current.height = cam->crop_bounds.height;
  67365. +
  67366. +exit:
  67367. + return err;
  67368. +}
  67369. +
  67370. +static int pxp_set_cstate(cam_data *cam, struct v4l2_control *vc)
  67371. +{
  67372. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  67373. +
  67374. + if (vc->id == V4L2_CID_HFLIP) {
  67375. + proc_data->hflip = vc->value;
  67376. + } else if (vc->id == V4L2_CID_VFLIP) {
  67377. + proc_data->vflip = vc->value;
  67378. + } else if (vc->id == V4L2_CID_PRIVATE_BASE) {
  67379. + if (vc->value % 90)
  67380. + return -ERANGE;
  67381. + proc_data->rotate = vc->value;
  67382. + cam->rotation = vc->value;
  67383. + }
  67384. +
  67385. + return 0;
  67386. +}
  67387. +
  67388. +static int pxp_get_cstate(cam_data *cam, struct v4l2_control *vc)
  67389. +{
  67390. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  67391. +
  67392. + if (vc->id == V4L2_CID_HFLIP)
  67393. + vc->value = proc_data->hflip;
  67394. + else if (vc->id == V4L2_CID_VFLIP)
  67395. + vc->value = proc_data->vflip;
  67396. + else if (vc->id == V4L2_CID_PRIVATE_BASE)
  67397. + vc->value = proc_data->rotate;
  67398. +
  67399. + return 0;
  67400. +}
  67401. +
  67402. +
  67403. +/*!
  67404. + * Dequeue one V4L capture buffer
  67405. + *
  67406. + * @param cam structure cam_data *
  67407. + * @param buf structure v4l2_buffer *
  67408. + *
  67409. + * @return status 0 success, EINVAL invalid frame number
  67410. + * ETIME timeout, ERESTARTSYS interrupted by user
  67411. + */
  67412. +static int csi_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
  67413. +{
  67414. + int retval = 0;
  67415. + struct mxc_v4l_frame *frame;
  67416. + unsigned long lock_flags;
  67417. +
  67418. + if (!wait_event_interruptible_timeout(cam->enc_queue,
  67419. + cam->enc_counter != 0, 10 * HZ)) {
  67420. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout "
  67421. + "enc_counter %x\n", cam->enc_counter);
  67422. + return -ETIME;
  67423. + } else if (signal_pending(current)) {
  67424. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() "
  67425. + "interrupt received\n");
  67426. + return -ERESTARTSYS;
  67427. + }
  67428. +
  67429. + if (down_interruptible(&cam->busy_lock))
  67430. + return -EBUSY;
  67431. +
  67432. + spin_lock_irqsave(&cam->dqueue_int_lock, lock_flags);
  67433. +
  67434. + if (list_empty(&cam->done_q)) {
  67435. + spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
  67436. + up(&cam->busy_lock);
  67437. + return -EINVAL;
  67438. + }
  67439. +
  67440. + cam->enc_counter--;
  67441. +
  67442. + frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue);
  67443. + list_del(cam->done_q.next);
  67444. +
  67445. + if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) {
  67446. + frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE;
  67447. + } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  67448. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  67449. + "Buffer not filled.\n");
  67450. + frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  67451. + retval = -EINVAL;
  67452. + } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) {
  67453. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  67454. + "Buffer not queued.\n");
  67455. + retval = -EINVAL;
  67456. + }
  67457. +
  67458. + spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
  67459. +
  67460. + buf->bytesused = cam->v2f.fmt.pix.sizeimage;
  67461. + buf->index = frame->index;
  67462. + buf->flags = frame->buffer.flags;
  67463. + buf->m = cam->frame[frame->index].buffer.m;
  67464. +
  67465. + /*
  67466. + * Note:
  67467. + * If want to do preview on LCD, use PxP CSC to convert from UYVY
  67468. + * to RGB565; but for encoding, usually we don't use RGB format.
  67469. + */
  67470. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
  67471. + sg_dma_address(&cam->sg[0]) = buf->m.offset;
  67472. + sg_dma_address(&cam->sg[1]) =
  67473. + cam->frame[req_buf_number].paddress;
  67474. + retval = pxp_process_update(cam);
  67475. + if (retval) {
  67476. + pr_err("Unable to submit PxP update task.\n");
  67477. + return retval;
  67478. + }
  67479. + pxp_complete_update(cam);
  67480. + if (cam->frame[buf->index].vaddress)
  67481. + memcpy(cam->frame[buf->index].vaddress,
  67482. + cam->frame[req_buf_number].vaddress,
  67483. + cam->v2f.fmt.pix.sizeimage);
  67484. + }
  67485. + up(&cam->busy_lock);
  67486. +
  67487. + return retval;
  67488. +}
  67489. +
  67490. +/*!
  67491. + * V4L interface - open function
  67492. + *
  67493. + * @param file structure file *
  67494. + *
  67495. + * @return status 0 success, ENODEV invalid device instance,
  67496. + * ENODEV timeout, ERESTARTSYS interrupted by user
  67497. + */
  67498. +static int csi_v4l_open(struct file *file)
  67499. +{
  67500. + struct v4l2_ifparm ifparm;
  67501. + struct v4l2_format cam_fmt;
  67502. + struct video_device *dev = video_devdata(file);
  67503. + cam_data *cam = video_get_drvdata(dev);
  67504. + struct sensor_data *sensor;
  67505. + int err = 0;
  67506. +
  67507. + pr_debug(" device name is %s\n", dev->name);
  67508. +
  67509. + if (!cam) {
  67510. + pr_err("%s: Internal error, cam_data not found!\n", __func__);
  67511. + return -EBADF;
  67512. + }
  67513. +
  67514. + if (!cam->sensor) {
  67515. + pr_err("%s: Internal error, camera is not found!\n", __func__);
  67516. + return -EBADF;
  67517. + }
  67518. +
  67519. + sensor = cam->sensor->priv;
  67520. + if (!sensor) {
  67521. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  67522. + return -EBADF;
  67523. + }
  67524. +
  67525. + down(&cam->busy_lock);
  67526. + err = 0;
  67527. + if (signal_pending(current))
  67528. + goto oops;
  67529. +
  67530. + if (cam->open_count++ == 0) {
  67531. + wait_event_interruptible(cam->power_queue,
  67532. + cam->low_power == false);
  67533. +
  67534. + cam->enc_counter = 0;
  67535. + INIT_LIST_HEAD(&cam->ready_q);
  67536. + INIT_LIST_HEAD(&cam->working_q);
  67537. + INIT_LIST_HEAD(&cam->done_q);
  67538. +
  67539. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  67540. +
  67541. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  67542. + clk_prepare_enable(sensor->sensor_clk);
  67543. + vidioc_int_s_power(cam->sensor, 1);
  67544. + vidioc_int_init(cam->sensor);
  67545. + vidioc_int_dev_init(cam->sensor);
  67546. + }
  67547. +
  67548. + file->private_data = dev;
  67549. +
  67550. +oops:
  67551. + up(&cam->busy_lock);
  67552. + return err;
  67553. +}
  67554. +
  67555. +/*!
  67556. + * V4L interface - close function
  67557. + *
  67558. + * @param file struct file *
  67559. + *
  67560. + * @return 0 success
  67561. + */
  67562. +static int csi_v4l_close(struct file *file)
  67563. +{
  67564. + struct video_device *dev = video_devdata(file);
  67565. + int err = 0;
  67566. + cam_data *cam = video_get_drvdata(dev);
  67567. + struct sensor_data *sensor;
  67568. +
  67569. + pr_debug("In MVC:%s\n", __func__);
  67570. +
  67571. + if (!cam) {
  67572. + pr_err("%s: Internal error, cam_data not found!\n", __func__);
  67573. + return -EBADF;
  67574. + }
  67575. +
  67576. + if (!cam->sensor) {
  67577. + pr_err("%s: Internal error, camera is not found!\n", __func__);
  67578. + return -EBADF;
  67579. + }
  67580. +
  67581. + sensor = cam->sensor->priv;
  67582. + if (!sensor) {
  67583. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  67584. + return -EBADF;
  67585. + }
  67586. +
  67587. + /* for the case somebody hit the ctrl C */
  67588. + if (cam->overlay_pid == current->pid) {
  67589. + err = stop_preview(cam);
  67590. + cam->overlay_on = false;
  67591. + }
  67592. +
  67593. + if (--cam->open_count == 0) {
  67594. + wait_event_interruptible(cam->power_queue,
  67595. + cam->low_power == false);
  67596. + file->private_data = NULL;
  67597. + vidioc_int_s_power(cam->sensor, 0);
  67598. + clk_disable_unprepare(sensor->sensor_clk);
  67599. + }
  67600. +
  67601. + return err;
  67602. +}
  67603. +
  67604. +/*
  67605. + * V4L interface - read function
  67606. + *
  67607. + * @param file struct file *
  67608. + * @param read buf char *
  67609. + * @param count size_t
  67610. + * @param ppos structure loff_t *
  67611. + *
  67612. + * @return bytes read
  67613. + */
  67614. +static ssize_t csi_v4l_read(struct file *file, char *buf, size_t count,
  67615. + loff_t *ppos)
  67616. +{
  67617. + int err = 0;
  67618. + struct video_device *dev = video_devdata(file);
  67619. + cam_data *cam = video_get_drvdata(dev);
  67620. +
  67621. + if (down_interruptible(&cam->busy_lock))
  67622. + return -EINTR;
  67623. +
  67624. + /* Stop the viewfinder */
  67625. + if (cam->overlay_on == true)
  67626. + stop_preview(cam);
  67627. +
  67628. + if (cam->still_buf_vaddr == NULL) {
  67629. + cam->still_buf_vaddr = dma_alloc_coherent(0,
  67630. + PAGE_ALIGN
  67631. + (cam->v2f.fmt.
  67632. + pix.sizeimage),
  67633. + &cam->
  67634. + still_buf[0],
  67635. + GFP_DMA | GFP_KERNEL);
  67636. + if (cam->still_buf_vaddr == NULL) {
  67637. + pr_err("alloc dma memory failed\n");
  67638. + return -ENOMEM;
  67639. + }
  67640. + cam->still_counter = 0;
  67641. + __raw_writel(cam->still_buf[0], CSI_CSIDMASA_FB2);
  67642. + __raw_writel(cam->still_buf[0], CSI_CSIDMASA_FB1);
  67643. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF,
  67644. + CSI_CSICR3);
  67645. + __raw_writel(__raw_readl(CSI_CSISR), CSI_CSISR);
  67646. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_FRMCNT_RST,
  67647. + CSI_CSICR3);
  67648. + csi_enable_int(1);
  67649. + }
  67650. +
  67651. + wait_event_interruptible(cam->still_queue, cam->still_counter);
  67652. + csi_disable_int();
  67653. + err = copy_to_user(buf, cam->still_buf_vaddr,
  67654. + cam->v2f.fmt.pix.sizeimage);
  67655. +
  67656. + if (cam->still_buf_vaddr != NULL) {
  67657. + dma_free_coherent(0, PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  67658. + cam->still_buf_vaddr, cam->still_buf[0]);
  67659. + cam->still_buf[0] = 0;
  67660. + cam->still_buf_vaddr = NULL;
  67661. + }
  67662. +
  67663. + if (cam->overlay_on == true)
  67664. + start_preview(cam);
  67665. +
  67666. + up(&cam->busy_lock);
  67667. + if (err < 0)
  67668. + return err;
  67669. +
  67670. + return cam->v2f.fmt.pix.sizeimage - err;
  67671. +}
  67672. +
  67673. +/*!
  67674. + * V4L interface - ioctl function
  67675. + *
  67676. + * @param file struct file*
  67677. + *
  67678. + * @param ioctlnr unsigned int
  67679. + *
  67680. + * @param arg void*
  67681. + *
  67682. + * @return 0 success, ENODEV for invalid device instance,
  67683. + * -1 for other errors.
  67684. + */
  67685. +static long csi_v4l_do_ioctl(struct file *file,
  67686. + unsigned int ioctlnr, void *arg)
  67687. +{
  67688. + struct video_device *dev = video_devdata(file);
  67689. + cam_data *cam = video_get_drvdata(dev);
  67690. + int retval = 0;
  67691. + unsigned long lock_flags;
  67692. +
  67693. + pr_debug("In MVC: %s, %x\n", __func__, ioctlnr);
  67694. + wait_event_interruptible(cam->power_queue, cam->low_power == false);
  67695. + /* make this _really_ smp-safe */
  67696. + if (ioctlnr != VIDIOC_DQBUF)
  67697. + if (down_interruptible(&cam->busy_lock))
  67698. + return -EBUSY;
  67699. +
  67700. + switch (ioctlnr) {
  67701. + /*!
  67702. + * V4l2 VIDIOC_G_FMT ioctl
  67703. + */
  67704. + case VIDIOC_G_FMT:{
  67705. + struct v4l2_format *gf = arg;
  67706. + pr_debug(" case VIDIOC_G_FMT\n");
  67707. + retval = csi_v4l2_g_fmt(cam, gf);
  67708. + break;
  67709. + }
  67710. +
  67711. + /*!
  67712. + * V4l2 VIDIOC_S_FMT ioctl
  67713. + */
  67714. + case VIDIOC_S_FMT:{
  67715. + struct v4l2_format *sf = arg;
  67716. + pr_debug(" case VIDIOC_S_FMT\n");
  67717. + retval = csi_v4l2_s_fmt(cam, sf);
  67718. + vidioc_int_s_fmt_cap(cam->sensor, sf);
  67719. + break;
  67720. + }
  67721. +
  67722. + /*!
  67723. + * V4l2 VIDIOC_OVERLAY ioctl
  67724. + */
  67725. + case VIDIOC_OVERLAY:{
  67726. + int *on = arg;
  67727. + pr_debug(" case VIDIOC_OVERLAY\n");
  67728. + if (*on) {
  67729. + cam->overlay_on = true;
  67730. + cam->overlay_pid = current->pid;
  67731. + start_preview(cam);
  67732. + }
  67733. + if (!*on) {
  67734. + stop_preview(cam);
  67735. + cam->overlay_on = false;
  67736. + }
  67737. + break;
  67738. + }
  67739. +
  67740. + /*!
  67741. + * V4l2 VIDIOC_G_FBUF ioctl
  67742. + */
  67743. + case VIDIOC_G_FBUF:{
  67744. + struct v4l2_framebuffer *fb = arg;
  67745. + *fb = cam->v4l2_fb;
  67746. + fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
  67747. + break;
  67748. + }
  67749. +
  67750. + /*!
  67751. + * V4l2 VIDIOC_S_FBUF ioctl
  67752. + */
  67753. + case VIDIOC_S_FBUF:{
  67754. + struct v4l2_framebuffer *fb = arg;
  67755. + cam->v4l2_fb = *fb;
  67756. + break;
  67757. + }
  67758. +
  67759. + case VIDIOC_G_PARM:{
  67760. + struct v4l2_streamparm *parm = arg;
  67761. + pr_debug(" case VIDIOC_G_PARM\n");
  67762. + vidioc_int_g_parm(cam->sensor, parm);
  67763. + break;
  67764. + }
  67765. +
  67766. + case VIDIOC_S_PARM:{
  67767. + struct v4l2_streamparm *parm = arg;
  67768. + pr_debug(" case VIDIOC_S_PARM\n");
  67769. + retval = csi_v4l2_s_param(cam, parm);
  67770. + break;
  67771. + }
  67772. +
  67773. + case VIDIOC_QUERYCAP:{
  67774. + struct v4l2_capability *cap = arg;
  67775. + pr_debug(" case VIDIOC_QUERYCAP\n");
  67776. + strcpy(cap->driver, "csi_v4l2");
  67777. + cap->version = KERNEL_VERSION(0, 1, 11);
  67778. + cap->capabilities = V4L2_CAP_VIDEO_OVERLAY |
  67779. + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
  67780. + V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_READWRITE;
  67781. + cap->card[0] = '\0';
  67782. + cap->bus_info[0] = '\0';
  67783. + break;
  67784. + }
  67785. +
  67786. + case VIDIOC_CROPCAP:
  67787. + {
  67788. + struct v4l2_cropcap *cap = arg;
  67789. +
  67790. + if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  67791. + cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  67792. + retval = -EINVAL;
  67793. + break;
  67794. + }
  67795. + cap->bounds = cam->crop_bounds;
  67796. + cap->defrect = cam->crop_defrect;
  67797. + break;
  67798. + }
  67799. + case VIDIOC_S_CROP:
  67800. + {
  67801. + struct v4l2_crop *crop = arg;
  67802. + struct v4l2_rect *b = &cam->crop_bounds;
  67803. +
  67804. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  67805. + retval = -EINVAL;
  67806. + break;
  67807. + }
  67808. +
  67809. + crop->c.top = (crop->c.top < b->top) ? b->top
  67810. + : crop->c.top;
  67811. + if (crop->c.top > b->top + b->height)
  67812. + crop->c.top = b->top + b->height - 1;
  67813. + if (crop->c.height > b->top + b->height - crop->c.top)
  67814. + crop->c.height =
  67815. + b->top + b->height - crop->c.top;
  67816. +
  67817. + crop->c.left = (crop->c.left < b->left) ? b->left
  67818. + : crop->c.left;
  67819. + if (crop->c.left > b->left + b->width)
  67820. + crop->c.left = b->left + b->width - 1;
  67821. + if (crop->c.width > b->left - crop->c.left + b->width)
  67822. + crop->c.width =
  67823. + b->left - crop->c.left + b->width;
  67824. +
  67825. + crop->c.width -= crop->c.width % 8;
  67826. + crop->c.height -= crop->c.height % 8;
  67827. +
  67828. + crop_current.c = crop->c;
  67829. +
  67830. + break;
  67831. + }
  67832. + case VIDIOC_G_CROP:
  67833. + {
  67834. + struct v4l2_crop *crop = arg;
  67835. +
  67836. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  67837. + retval = -EINVAL;
  67838. + break;
  67839. + }
  67840. + crop->c = crop_current.c;
  67841. +
  67842. + break;
  67843. +
  67844. + }
  67845. + case VIDIOC_REQBUFS: {
  67846. + struct v4l2_requestbuffers *req = arg;
  67847. + pr_debug(" case VIDIOC_REQBUFS\n");
  67848. +
  67849. + if (req->count > FRAME_NUM) {
  67850. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  67851. + "not enough buffers\n");
  67852. + req->count = FRAME_NUM;
  67853. + }
  67854. +
  67855. + if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  67856. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  67857. + "wrong buffer type\n");
  67858. + retval = -EINVAL;
  67859. + break;
  67860. + }
  67861. +
  67862. + csi_streamoff(cam);
  67863. + if (req->memory & V4L2_MEMORY_MMAP) {
  67864. + csi_free_frame_buf(cam);
  67865. + retval = csi_allocate_frame_buf(cam, req->count + 1);
  67866. + req_buf_number = req->count;
  67867. + }
  67868. + break;
  67869. + }
  67870. +
  67871. + case VIDIOC_QUERYBUF: {
  67872. + struct v4l2_buffer *buf = arg;
  67873. + int index = buf->index;
  67874. + pr_debug(" case VIDIOC_QUERYBUF\n");
  67875. +
  67876. + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  67877. + retval = -EINVAL;
  67878. + break;
  67879. + }
  67880. +
  67881. + if (buf->memory & V4L2_MEMORY_MMAP) {
  67882. + memset(buf, 0, sizeof(buf));
  67883. + buf->index = index;
  67884. + }
  67885. +
  67886. + down(&cam->param_lock);
  67887. + if (buf->memory & V4L2_MEMORY_USERPTR) {
  67888. + csi_v4l2_release_bufs(cam);
  67889. + retval = csi_v4l2_prepare_bufs(cam, buf);
  67890. + }
  67891. + if (buf->memory & V4L2_MEMORY_MMAP)
  67892. + retval = csi_v4l2_buffer_status(cam, buf);
  67893. + up(&cam->param_lock);
  67894. + break;
  67895. + }
  67896. +
  67897. + case VIDIOC_QBUF: {
  67898. + struct v4l2_buffer *buf = arg;
  67899. + int index = buf->index;
  67900. + pr_debug(" case VIDIOC_QBUF\n");
  67901. +
  67902. + spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
  67903. + cam->frame[index].buffer.m.offset = buf->m.offset;
  67904. + if ((cam->frame[index].buffer.flags & 0x7) ==
  67905. + V4L2_BUF_FLAG_MAPPED) {
  67906. + cam->frame[index].buffer.flags |= V4L2_BUF_FLAG_QUEUED;
  67907. + list_add_tail(&cam->frame[index].queue, &cam->ready_q);
  67908. + } else if (cam->frame[index].buffer.flags &
  67909. + V4L2_BUF_FLAG_QUEUED) {
  67910. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  67911. + "buffer already queued\n");
  67912. + retval = -EINVAL;
  67913. + } else if (cam->frame[index].buffer.
  67914. + flags & V4L2_BUF_FLAG_DONE) {
  67915. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  67916. + "overwrite done buffer.\n");
  67917. + cam->frame[index].buffer.flags &=
  67918. + ~V4L2_BUF_FLAG_DONE;
  67919. + cam->frame[index].buffer.flags |=
  67920. + V4L2_BUF_FLAG_QUEUED;
  67921. + retval = -EINVAL;
  67922. + }
  67923. + buf->flags = cam->frame[index].buffer.flags;
  67924. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  67925. +
  67926. + break;
  67927. + }
  67928. +
  67929. + case VIDIOC_DQBUF: {
  67930. + struct v4l2_buffer *buf = arg;
  67931. + pr_debug(" case VIDIOC_DQBUF\n");
  67932. +
  67933. + retval = csi_v4l_dqueue(cam, buf);
  67934. +
  67935. + break;
  67936. + }
  67937. +
  67938. + case VIDIOC_STREAMON: {
  67939. + pr_debug(" case VIDIOC_STREAMON\n");
  67940. + retval = csi_streamon(cam);
  67941. + break;
  67942. + }
  67943. +
  67944. + case VIDIOC_STREAMOFF: {
  67945. + pr_debug(" case VIDIOC_STREAMOFF\n");
  67946. + retval = csi_streamoff(cam);
  67947. + break;
  67948. + }
  67949. + case VIDIOC_ENUM_FMT: {
  67950. + struct v4l2_fmtdesc *fmt = arg;
  67951. + if (cam->sensor)
  67952. + retval = vidioc_int_enum_fmt_cap(cam->sensor, fmt);
  67953. + else {
  67954. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  67955. + retval = -ENODEV;
  67956. + }
  67957. + break;
  67958. + }
  67959. + case VIDIOC_ENUM_FRAMESIZES: {
  67960. + struct v4l2_frmsizeenum *fsize = arg;
  67961. + if (cam->sensor)
  67962. + retval = vidioc_int_enum_framesizes(cam->sensor, fsize);
  67963. + else {
  67964. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  67965. + retval = -ENODEV;
  67966. + }
  67967. + break;
  67968. + }
  67969. + case VIDIOC_ENUM_FRAMEINTERVALS: {
  67970. + struct v4l2_frmivalenum *fival = arg;
  67971. + if (cam->sensor)
  67972. + retval = vidioc_int_enum_frameintervals(cam->sensor,
  67973. + fival);
  67974. + else {
  67975. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  67976. + retval = -ENODEV;
  67977. + }
  67978. + break;
  67979. + }
  67980. + case VIDIOC_DBG_G_CHIP_IDENT: {
  67981. + struct v4l2_dbg_chip_ident *p = arg;
  67982. + p->ident = V4L2_IDENT_NONE;
  67983. + p->revision = 0;
  67984. + if (cam->sensor)
  67985. + retval = vidioc_int_g_chip_ident(cam->sensor, (int *)p);
  67986. + else {
  67987. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  67988. + retval = -ENODEV;
  67989. + }
  67990. + break;
  67991. + }
  67992. +
  67993. + case VIDIOC_S_CTRL:
  67994. + {
  67995. + struct v4l2_control *vc = arg;
  67996. + int i;
  67997. +
  67998. + for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
  67999. + if (vc->id == pxp_controls[i].id) {
  68000. + if (vc->value < pxp_controls[i].minimum ||
  68001. + vc->value > pxp_controls[i].maximum) {
  68002. + retval = -ERANGE;
  68003. + break;
  68004. + }
  68005. + retval = pxp_set_cstate(cam, vc);
  68006. + break;
  68007. + }
  68008. +
  68009. + if (i >= ARRAY_SIZE(pxp_controls))
  68010. + retval = -EINVAL;
  68011. + break;
  68012. +
  68013. + }
  68014. + case VIDIOC_G_CTRL:
  68015. + {
  68016. + struct v4l2_control *vc = arg;
  68017. + int i;
  68018. +
  68019. + for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
  68020. + if (vc->id == pxp_controls[i].id) {
  68021. + retval = pxp_get_cstate(cam, vc);
  68022. + break;
  68023. + }
  68024. +
  68025. + if (i >= ARRAY_SIZE(pxp_controls))
  68026. + retval = -EINVAL;
  68027. + break;
  68028. + }
  68029. + case VIDIOC_QUERYCTRL:
  68030. + {
  68031. + struct v4l2_queryctrl *qc = arg;
  68032. + int i;
  68033. +
  68034. + for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
  68035. + if (qc->id && qc->id == pxp_controls[i].id) {
  68036. + memcpy(qc, &(pxp_controls[i]), sizeof(*qc));
  68037. + break;
  68038. + }
  68039. +
  68040. + if (i >= ARRAY_SIZE(pxp_controls))
  68041. + retval = -EINVAL;
  68042. + break;
  68043. + }
  68044. + case VIDIOC_G_STD:
  68045. + case VIDIOC_G_OUTPUT:
  68046. + case VIDIOC_S_OUTPUT:
  68047. + case VIDIOC_ENUMSTD:
  68048. + case VIDIOC_S_STD:
  68049. + case VIDIOC_TRY_FMT:
  68050. + case VIDIOC_ENUMINPUT:
  68051. + case VIDIOC_G_INPUT:
  68052. + case VIDIOC_S_INPUT:
  68053. + case VIDIOC_G_TUNER:
  68054. + case VIDIOC_S_TUNER:
  68055. + case VIDIOC_G_FREQUENCY:
  68056. + case VIDIOC_S_FREQUENCY:
  68057. + case VIDIOC_ENUMOUTPUT:
  68058. + default:
  68059. + pr_debug(" case not supported\n");
  68060. + retval = -EINVAL;
  68061. + break;
  68062. + }
  68063. +
  68064. + if (ioctlnr != VIDIOC_DQBUF)
  68065. + up(&cam->busy_lock);
  68066. + return retval;
  68067. +}
  68068. +
  68069. +/*
  68070. + * V4L interface - ioctl function
  68071. + *
  68072. + * @return None
  68073. + */
  68074. +static long csi_v4l_ioctl(struct file *file,
  68075. + unsigned int cmd, unsigned long arg)
  68076. +{
  68077. + return video_usercopy(file, cmd, arg, csi_v4l_do_ioctl);
  68078. +}
  68079. +
  68080. +/*!
  68081. + * V4L interface - mmap function
  68082. + *
  68083. + * @param file structure file *
  68084. + *
  68085. + * @param vma structure vm_area_struct *
  68086. + *
  68087. + * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error
  68088. + */
  68089. +static int csi_mmap(struct file *file, struct vm_area_struct *vma)
  68090. +{
  68091. + struct video_device *dev = video_devdata(file);
  68092. + unsigned long size;
  68093. + int res = 0;
  68094. + cam_data *cam = video_get_drvdata(dev);
  68095. +
  68096. + pr_debug("%s\n", __func__);
  68097. + pr_debug("\npgoff=0x%lx, start=0x%lx, end=0x%lx\n",
  68098. + vma->vm_pgoff, vma->vm_start, vma->vm_end);
  68099. +
  68100. + /* make this _really_ smp-safe */
  68101. + if (down_interruptible(&cam->busy_lock))
  68102. + return -EINTR;
  68103. +
  68104. + size = vma->vm_end - vma->vm_start;
  68105. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  68106. +
  68107. + if (remap_pfn_range(vma, vma->vm_start,
  68108. + vma->vm_pgoff, size, vma->vm_page_prot)) {
  68109. + pr_err("ERROR: v4l2 capture: %s : "
  68110. + "remap_pfn_range failed\n", __func__);
  68111. + res = -ENOBUFS;
  68112. + goto csi_mmap_exit;
  68113. + }
  68114. +
  68115. + vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
  68116. +
  68117. +csi_mmap_exit:
  68118. + up(&cam->busy_lock);
  68119. + return res;
  68120. +}
  68121. +
  68122. +/*!
  68123. + * This structure defines the functions to be called in this driver.
  68124. + */
  68125. +static struct v4l2_file_operations csi_v4l_fops = {
  68126. + .owner = THIS_MODULE,
  68127. + .open = csi_v4l_open,
  68128. + .release = csi_v4l_close,
  68129. + .read = csi_v4l_read,
  68130. + .ioctl = csi_v4l_ioctl,
  68131. + .mmap = csi_mmap,
  68132. +};
  68133. +
  68134. +static struct video_device csi_v4l_template = {
  68135. + .name = "Mx25 Camera",
  68136. + .fops = &csi_v4l_fops,
  68137. + .release = video_device_release,
  68138. +};
  68139. +
  68140. +/*!
  68141. + * initialize cam_data structure
  68142. + *
  68143. + * @param cam structure cam_data *
  68144. + *
  68145. + * @return status 0 Success
  68146. + */
  68147. +static void init_camera_struct(cam_data *cam)
  68148. +{
  68149. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  68150. + pr_debug("In MVC: %s\n", __func__);
  68151. +
  68152. + proc_data->hflip = 0;
  68153. + proc_data->vflip = 0;
  68154. + proc_data->rotate = 0;
  68155. + proc_data->bgcolor = 0;
  68156. +
  68157. + /* Default everything to 0 */
  68158. + memset(cam, 0, sizeof(cam_data));
  68159. +
  68160. + sema_init(&cam->param_lock, 1);
  68161. + sema_init(&cam->busy_lock, 1);
  68162. +
  68163. + cam->video_dev = video_device_alloc();
  68164. + if (cam->video_dev == NULL)
  68165. + return;
  68166. +
  68167. + *(cam->video_dev) = csi_v4l_template;
  68168. +
  68169. + video_set_drvdata(cam->video_dev, cam);
  68170. + cam->video_dev->minor = -1;
  68171. +
  68172. + init_waitqueue_head(&cam->enc_queue);
  68173. + init_waitqueue_head(&cam->still_queue);
  68174. +
  68175. + cam->streamparm.parm.capture.capturemode = 0;
  68176. +
  68177. + cam->standard.index = 0;
  68178. + cam->standard.id = V4L2_STD_UNKNOWN;
  68179. + cam->standard.frameperiod.denominator = 30;
  68180. + cam->standard.frameperiod.numerator = 1;
  68181. + cam->standard.framelines = 480;
  68182. + cam->standard_autodetect = true;
  68183. + cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  68184. + cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
  68185. + cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
  68186. + cam->overlay_on = false;
  68187. + cam->capture_on = false;
  68188. + cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
  68189. +
  68190. + cam->v2f.fmt.pix.sizeimage = 480 * 640 * 2;
  68191. + cam->v2f.fmt.pix.bytesperline = 640 * 2;
  68192. + cam->v2f.fmt.pix.width = 640;
  68193. + cam->v2f.fmt.pix.height = 480;
  68194. + cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
  68195. + cam->win.w.width = 160;
  68196. + cam->win.w.height = 160;
  68197. + cam->win.w.left = 0;
  68198. + cam->win.w.top = 0;
  68199. + cam->still_counter = 0;
  68200. + /* setup cropping */
  68201. + cam->crop_bounds.left = 0;
  68202. + cam->crop_bounds.width = 640;
  68203. + cam->crop_bounds.top = 0;
  68204. + cam->crop_bounds.height = 480;
  68205. + cam->crop_current = cam->crop_defrect = cam->crop_bounds;
  68206. +
  68207. + cam->enc_callback = camera_callback;
  68208. + csi_start_callback(cam);
  68209. + init_waitqueue_head(&cam->power_queue);
  68210. + spin_lock_init(&cam->queue_int_lock);
  68211. + spin_lock_init(&cam->dqueue_int_lock);
  68212. +}
  68213. +
  68214. +/*!
  68215. + * camera_power function
  68216. + * Turns Sensor power On/Off
  68217. + *
  68218. + * @param cam cam data struct
  68219. + * @param cameraOn true to turn camera on, false to turn off power.
  68220. + *
  68221. + * @return status
  68222. + */
  68223. +static u8 camera_power(cam_data *cam, bool cameraOn)
  68224. +{
  68225. + pr_debug("In MVC: %s on=%d\n", __func__, cameraOn);
  68226. +
  68227. + if (cameraOn == true) {
  68228. + vidioc_int_s_power(cam->sensor, 1);
  68229. + } else {
  68230. + vidioc_int_s_power(cam->sensor, 0);
  68231. + }
  68232. + return 0;
  68233. +}
  68234. +
  68235. +static const struct of_device_id imx_csi_v4l2_dt_ids[] = {
  68236. + { .compatible = "fsl,imx6sl-csi-v4l2", },
  68237. + { /* sentinel */ }
  68238. +};
  68239. +MODULE_DEVICE_TABLE(of, imx_csi_v4l2_dt_ids);
  68240. +
  68241. +static int csi_v4l2_probe(struct platform_device *pdev)
  68242. +{
  68243. + struct scatterlist *sg;
  68244. + u8 err = 0;
  68245. +
  68246. + /* Create g_cam and initialize it. */
  68247. + g_cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
  68248. + if (g_cam == NULL) {
  68249. + pr_err("ERROR: v4l2 capture: failed to register camera\n");
  68250. + err = -ENOMEM;
  68251. + goto out;
  68252. + }
  68253. + memset(&crop_current, 0, sizeof(crop_current));
  68254. + memset(&win_current, 0, sizeof(win_current));
  68255. + init_camera_struct(g_cam);
  68256. + platform_set_drvdata(pdev, (void *)g_cam);
  68257. +
  68258. + /* Set up the v4l2 device and register it */
  68259. + csi_v4l2_int_device.priv = g_cam;
  68260. + /* This function contains a bug that won't let this be rmmod'd. */
  68261. + v4l2_int_device_register(&csi_v4l2_int_device);
  68262. +
  68263. + /* register v4l video device */
  68264. + if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr)
  68265. + == -1) {
  68266. + kfree(g_cam);
  68267. + g_cam = NULL;
  68268. + pr_err("ERROR: v4l2 capture: video_register_device failed\n");
  68269. + err = -ENODEV;
  68270. + goto out;
  68271. + }
  68272. + pr_debug(" Video device registered: %s #%d\n",
  68273. + g_cam->video_dev->name, g_cam->video_dev->minor);
  68274. +
  68275. + g_cam->pxp_chan = NULL;
  68276. + /* Initialize Scatter-gather list containing 2 buffer addresses. */
  68277. + sg = g_cam->sg;
  68278. + sg_init_table(sg, 2);
  68279. +
  68280. +out:
  68281. + return err;
  68282. +}
  68283. +
  68284. +static int csi_v4l2_remove(struct platform_device *pdev)
  68285. +{
  68286. + if (g_cam->open_count) {
  68287. + pr_err("ERROR: v4l2 capture:camera open "
  68288. + "-- setting ops to NULL\n");
  68289. + } else {
  68290. + pr_info("V4L2 freeing image input device\n");
  68291. + v4l2_int_device_unregister(&csi_v4l2_int_device);
  68292. + csi_stop_callback(g_cam);
  68293. + video_unregister_device(g_cam->video_dev);
  68294. + platform_set_drvdata(pdev, NULL);
  68295. +
  68296. + kfree(g_cam);
  68297. + g_cam = NULL;
  68298. + }
  68299. +
  68300. + return 0;
  68301. +}
  68302. +
  68303. +/*!
  68304. + * This function is called to put the sensor in a low power state.
  68305. + * Refer to the document driver-model/driver.txt in the kernel source tree
  68306. + * for more information.
  68307. + *
  68308. + * @param pdev the device structure used to give information on which I2C
  68309. + * to suspend
  68310. + * @param state the power state the device is entering
  68311. + *
  68312. + * @return The function returns 0 on success and -1 on failure.
  68313. + */
  68314. +static int csi_v4l2_suspend(struct platform_device *pdev, pm_message_t state)
  68315. +{
  68316. + cam_data *cam = platform_get_drvdata(pdev);
  68317. +
  68318. + pr_debug("In MVC: %s\n", __func__);
  68319. +
  68320. + if (cam == NULL)
  68321. + return -1;
  68322. +
  68323. + cam->low_power = true;
  68324. +
  68325. + if (cam->overlay_on == true)
  68326. + stop_preview(cam);
  68327. +
  68328. + if (cam->capture_on == true || cam->overlay_on == true)
  68329. + camera_power(cam, false);
  68330. +
  68331. + return 0;
  68332. +}
  68333. +
  68334. +/*!
  68335. + * This function is called to bring the sensor back from a low power state.
  68336. + * Refer to the document driver-model/driver.txt in the kernel source tree
  68337. + * for more information.
  68338. + *
  68339. + * @param pdev the device structure
  68340. + *
  68341. + * @return The function returns 0 on success and -1 on failure
  68342. + */
  68343. +static int csi_v4l2_resume(struct platform_device *pdev)
  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 = false;
  68353. + wake_up_interruptible(&cam->power_queue);
  68354. + if (cam->capture_on == true || cam->overlay_on == true)
  68355. + camera_power(cam, true);
  68356. +
  68357. + if (cam->overlay_on == true)
  68358. + start_preview(cam);
  68359. +
  68360. + return 0;
  68361. +}
  68362. +
  68363. +/*!
  68364. + * This structure contains pointers to the power management callback functions.
  68365. + */
  68366. +static struct platform_driver csi_v4l2_driver = {
  68367. + .driver = {
  68368. + .name = "csi_v4l2",
  68369. + .of_match_table = of_match_ptr(imx_csi_v4l2_dt_ids),
  68370. + },
  68371. + .probe = csi_v4l2_probe,
  68372. + .remove = csi_v4l2_remove,
  68373. +#ifdef CONFIG_PM
  68374. + .suspend = csi_v4l2_suspend,
  68375. + .resume = csi_v4l2_resume,
  68376. +#endif
  68377. + .shutdown = NULL,
  68378. +};
  68379. +
  68380. +/*!
  68381. + * Initializes the camera driver.
  68382. + */
  68383. +static int csi_v4l2_master_attach(struct v4l2_int_device *slave)
  68384. +{
  68385. + cam_data *cam = slave->u.slave->master->priv;
  68386. + struct v4l2_format cam_fmt;
  68387. +
  68388. + pr_debug("In MVC: %s\n", __func__);
  68389. + pr_debug(" slave.name = %s\n", slave->name);
  68390. + pr_debug(" master.name = %s\n", slave->u.slave->master->name);
  68391. +
  68392. + cam->sensor = slave;
  68393. + if (slave == NULL) {
  68394. + pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
  68395. + return -1;
  68396. + }
  68397. +
  68398. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  68399. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  68400. +
  68401. + /* Used to detect TV in (type 1) vs. camera (type 0) */
  68402. + cam->device_type = cam_fmt.fmt.pix.priv;
  68403. +
  68404. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  68405. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  68406. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  68407. +
  68408. + /* This also is the max crop size for this device. */
  68409. + cam->crop_defrect.top = cam->crop_defrect.left = 0;
  68410. + cam->crop_defrect.width = cam_fmt.fmt.pix.width;
  68411. + cam->crop_defrect.height = cam_fmt.fmt.pix.height;
  68412. +
  68413. + /* At this point, this is also the current image size. */
  68414. + cam->crop_current.top = cam->crop_current.left = 0;
  68415. + cam->crop_current.width = cam_fmt.fmt.pix.width;
  68416. + cam->crop_current.height = cam_fmt.fmt.pix.height;
  68417. +
  68418. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  68419. + __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  68420. +
  68421. + return 0;
  68422. +}
  68423. +
  68424. +/*!
  68425. + * Disconnects the camera driver.
  68426. + */
  68427. +static void csi_v4l2_master_detach(struct v4l2_int_device *slave)
  68428. +{
  68429. + pr_debug("In MVC: %s\n", __func__);
  68430. +
  68431. + vidioc_int_dev_exit(slave);
  68432. +}
  68433. +
  68434. +module_platform_driver(csi_v4l2_driver);
  68435. +
  68436. +module_param(video_nr, int, 0444);
  68437. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  68438. +MODULE_DESCRIPTION("V4L2 capture driver for Mx25 based cameras");
  68439. +MODULE_LICENSE("GPL");
  68440. +MODULE_SUPPORTED_DEVICE("video");
  68441. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/fsl_csi.c linux-imx6-3.14/drivers/media/platform/mxc/capture/fsl_csi.c
  68442. --- linux-3.14.14/drivers/media/platform/mxc/capture/fsl_csi.c 1969-12-31 18:00:00.000000000 -0600
  68443. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/fsl_csi.c 2014-12-08 00:31:53.256418001 -0600
  68444. @@ -0,0 +1,302 @@
  68445. +/*
  68446. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  68447. + */
  68448. +
  68449. +/*
  68450. + * The code contained herein is licensed under the GNU General Public
  68451. + * License. You may obtain a copy of the GNU General Public License
  68452. + * Version 2 or later at the following locations:
  68453. + *
  68454. + * http://www.opensource.org/licenses/gpl-license.html
  68455. + * http://www.gnu.org/copyleft/gpl.html
  68456. + */
  68457. +
  68458. +/*!
  68459. + * @file fsl_csi.c, this file is derived from mx27_csi.c
  68460. + *
  68461. + * @brief mx25 CMOS Sensor interface functions
  68462. + *
  68463. + * @ingroup CSI
  68464. + */
  68465. +#include <linux/types.h>
  68466. +#include <linux/init.h>
  68467. +#include <linux/platform_device.h>
  68468. +#include <linux/device.h>
  68469. +#include <linux/err.h>
  68470. +#include <linux/interrupt.h>
  68471. +#include <linux/spinlock.h>
  68472. +#include <linux/module.h>
  68473. +#include <linux/clk.h>
  68474. +#include <linux/of.h>
  68475. +#include <linux/sched.h>
  68476. +
  68477. +#include "mxc_v4l2_capture.h"
  68478. +#include "fsl_csi.h"
  68479. +
  68480. +void __iomem *csi_regbase;
  68481. +EXPORT_SYMBOL(csi_regbase);
  68482. +static int irq_nr;
  68483. +static csi_irq_callback_t g_callback;
  68484. +static void *g_callback_data;
  68485. +
  68486. +static irqreturn_t csi_irq_handler(int irq, void *data)
  68487. +{
  68488. + cam_data *cam = (cam_data *) data;
  68489. + unsigned long status = __raw_readl(CSI_CSISR);
  68490. +
  68491. + __raw_writel(status, CSI_CSISR);
  68492. +
  68493. + if (status & BIT_HRESP_ERR_INT)
  68494. + pr_warning("Hresponse error is detected.\n");
  68495. +
  68496. + if (status & BIT_DMA_TSF_DONE_FB1) {
  68497. + if (cam->capture_on) {
  68498. + spin_lock(&cam->queue_int_lock);
  68499. + cam->ping_pong_csi = 1;
  68500. + spin_unlock(&cam->queue_int_lock);
  68501. + cam->enc_callback(0, cam);
  68502. + } else {
  68503. + cam->still_counter++;
  68504. + wake_up_interruptible(&cam->still_queue);
  68505. + }
  68506. + }
  68507. +
  68508. + if (status & BIT_DMA_TSF_DONE_FB2) {
  68509. + if (cam->capture_on) {
  68510. + spin_lock(&cam->queue_int_lock);
  68511. + cam->ping_pong_csi = 2;
  68512. + spin_unlock(&cam->queue_int_lock);
  68513. + cam->enc_callback(0, cam);
  68514. + } else {
  68515. + cam->still_counter++;
  68516. + wake_up_interruptible(&cam->still_queue);
  68517. + }
  68518. + }
  68519. +
  68520. + if (g_callback)
  68521. + g_callback(g_callback_data, status);
  68522. +
  68523. + pr_debug("CSI status = 0x%08lX\n", status);
  68524. +
  68525. + return IRQ_HANDLED;
  68526. +}
  68527. +
  68528. +static void csihw_reset_frame_count(void)
  68529. +{
  68530. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_FRMCNT_RST, CSI_CSICR3);
  68531. +}
  68532. +
  68533. +static void csihw_reset(void)
  68534. +{
  68535. + csihw_reset_frame_count();
  68536. + __raw_writel(CSICR1_RESET_VAL, CSI_CSICR1);
  68537. + __raw_writel(CSICR2_RESET_VAL, CSI_CSICR2);
  68538. + __raw_writel(CSICR3_RESET_VAL, CSI_CSICR3);
  68539. +}
  68540. +
  68541. +/*!
  68542. + * csi_init_interface
  68543. + * Init csi interface
  68544. + */
  68545. +void csi_init_interface(void)
  68546. +{
  68547. + unsigned int val = 0;
  68548. + unsigned int imag_para;
  68549. +
  68550. + val |= BIT_SOF_POL;
  68551. + val |= BIT_REDGE;
  68552. + val |= BIT_GCLK_MODE;
  68553. + val |= BIT_HSYNC_POL;
  68554. + val |= BIT_PACK_DIR;
  68555. + val |= BIT_FCC;
  68556. + val |= BIT_SWAP16_EN;
  68557. + val |= 1 << SHIFT_MCLKDIV;
  68558. + val |= BIT_MCLKEN;
  68559. + __raw_writel(val, CSI_CSICR1);
  68560. +
  68561. + imag_para = (640 << 16) | 960;
  68562. + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  68563. +
  68564. + val = 0x1010;
  68565. + val |= BIT_DMA_REFLASH_RFF;
  68566. + __raw_writel(val, CSI_CSICR3);
  68567. +}
  68568. +EXPORT_SYMBOL(csi_init_interface);
  68569. +
  68570. +void csi_init_format(int fmt)
  68571. +{
  68572. + unsigned int val;
  68573. +
  68574. + val = __raw_readl(CSI_CSICR1);
  68575. + if (fmt == V4L2_PIX_FMT_YUYV) {
  68576. + val &= ~BIT_PACK_DIR;
  68577. + val &= ~BIT_SWAP16_EN;
  68578. + } else if (fmt == V4L2_PIX_FMT_UYVY) {
  68579. + val |= BIT_PACK_DIR;
  68580. + val |= BIT_SWAP16_EN;
  68581. + } else
  68582. + pr_warning("unsupported format, old format remains.\n");
  68583. +
  68584. + __raw_writel(val, CSI_CSICR1);
  68585. +}
  68586. +EXPORT_SYMBOL(csi_init_format);
  68587. +
  68588. +/*!
  68589. + * csi_read_mclk_flag
  68590. + *
  68591. + * @return gcsi_mclk_source
  68592. + */
  68593. +int csi_read_mclk_flag(void)
  68594. +{
  68595. + return 0;
  68596. +}
  68597. +EXPORT_SYMBOL(csi_read_mclk_flag);
  68598. +
  68599. +void csi_start_callback(void *data)
  68600. +{
  68601. + cam_data *cam = (cam_data *) data;
  68602. +
  68603. + if (request_irq(irq_nr, csi_irq_handler, 0, "csi", cam) < 0)
  68604. + pr_debug("CSI error: irq request fail\n");
  68605. +
  68606. +}
  68607. +EXPORT_SYMBOL(csi_start_callback);
  68608. +
  68609. +void csi_stop_callback(void *data)
  68610. +{
  68611. + cam_data *cam = (cam_data *) data;
  68612. +
  68613. + free_irq(irq_nr, cam);
  68614. +}
  68615. +EXPORT_SYMBOL(csi_stop_callback);
  68616. +
  68617. +void csi_enable_int(int arg)
  68618. +{
  68619. + unsigned long cr1 = __raw_readl(CSI_CSICR1);
  68620. +
  68621. + cr1 |= BIT_SOF_INTEN;
  68622. + if (arg == 1) {
  68623. + /* still capture needs DMA intterrupt */
  68624. + cr1 |= BIT_FB1_DMA_DONE_INTEN;
  68625. + cr1 |= BIT_FB2_DMA_DONE_INTEN;
  68626. + }
  68627. + __raw_writel(cr1, CSI_CSICR1);
  68628. +}
  68629. +EXPORT_SYMBOL(csi_enable_int);
  68630. +
  68631. +void csi_disable_int(void)
  68632. +{
  68633. + unsigned long cr1 = __raw_readl(CSI_CSICR1);
  68634. +
  68635. + cr1 &= ~BIT_SOF_INTEN;
  68636. + cr1 &= ~BIT_FB1_DMA_DONE_INTEN;
  68637. + cr1 &= ~BIT_FB2_DMA_DONE_INTEN;
  68638. + __raw_writel(cr1, CSI_CSICR1);
  68639. +}
  68640. +EXPORT_SYMBOL(csi_disable_int);
  68641. +
  68642. +void csi_set_16bit_imagpara(int width, int height)
  68643. +{
  68644. + int imag_para = 0;
  68645. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  68646. +
  68647. + imag_para = (width << 16) | (height * 2);
  68648. + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  68649. +
  68650. + /* reflash the embeded DMA controller */
  68651. + __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  68652. +}
  68653. +EXPORT_SYMBOL(csi_set_16bit_imagpara);
  68654. +
  68655. +void csi_set_12bit_imagpara(int width, int height)
  68656. +{
  68657. + int imag_para = 0;
  68658. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  68659. +
  68660. + imag_para = (width << 16) | (height * 3 / 2);
  68661. + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  68662. +
  68663. + /* reflash the embeded DMA controller */
  68664. + __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  68665. +}
  68666. +EXPORT_SYMBOL(csi_set_12bit_imagpara);
  68667. +
  68668. +void csi_dmareq_rff_enable(void)
  68669. +{
  68670. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  68671. +
  68672. + cr3 |= BIT_DMA_REQ_EN_RFF;
  68673. + cr3 |= BIT_HRESP_ERR_EN;
  68674. + __raw_writel(cr3, CSI_CSICR3);
  68675. +}
  68676. +EXPORT_SYMBOL(csi_dmareq_rff_enable);
  68677. +
  68678. +void csi_dmareq_rff_disable(void)
  68679. +{
  68680. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  68681. +
  68682. + cr3 &= ~BIT_DMA_REQ_EN_RFF;
  68683. + cr3 &= ~BIT_HRESP_ERR_EN;
  68684. + __raw_writel(cr3, CSI_CSICR3);
  68685. +}
  68686. +EXPORT_SYMBOL(csi_dmareq_rff_disable);
  68687. +
  68688. +static const struct of_device_id fsl_csi_dt_ids[] = {
  68689. + { .compatible = "fsl,imx6sl-csi", },
  68690. + { /* sentinel */ }
  68691. +};
  68692. +MODULE_DEVICE_TABLE(of, fsl_csi_dt_ids);
  68693. +
  68694. +static int csi_probe(struct platform_device *pdev)
  68695. +{
  68696. + int ret = 0;
  68697. + struct resource *res;
  68698. +
  68699. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  68700. + if (!res) {
  68701. + dev_err(&pdev->dev, "No csi irq found.\n");
  68702. + ret = -ENODEV;
  68703. + goto err;
  68704. + }
  68705. + irq_nr = res->start;
  68706. +
  68707. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  68708. + if (!res) {
  68709. + dev_err(&pdev->dev, "No csi base address found.\n");
  68710. + ret = -ENODEV;
  68711. + goto err;
  68712. + }
  68713. + csi_regbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
  68714. + if (!csi_regbase) {
  68715. + dev_err(&pdev->dev, "ioremap failed with csi base\n");
  68716. + ret = -ENOMEM;
  68717. + goto err;
  68718. + }
  68719. +
  68720. + csihw_reset();
  68721. + csi_init_interface();
  68722. + csi_dmareq_rff_disable();
  68723. +
  68724. +err:
  68725. + return ret;
  68726. +}
  68727. +
  68728. +static int csi_remove(struct platform_device *pdev)
  68729. +{
  68730. + return 0;
  68731. +}
  68732. +
  68733. +static struct platform_driver csi_driver = {
  68734. + .driver = {
  68735. + .name = "fsl_csi",
  68736. + .of_match_table = of_match_ptr(fsl_csi_dt_ids),
  68737. + },
  68738. + .probe = csi_probe,
  68739. + .remove = csi_remove,
  68740. +};
  68741. +
  68742. +module_platform_driver(csi_driver);
  68743. +
  68744. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  68745. +MODULE_DESCRIPTION("fsl CSI driver");
  68746. +MODULE_LICENSE("GPL");
  68747. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/fsl_csi.h linux-imx6-3.14/drivers/media/platform/mxc/capture/fsl_csi.h
  68748. --- linux-3.14.14/drivers/media/platform/mxc/capture/fsl_csi.h 1969-12-31 18:00:00.000000000 -0600
  68749. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/fsl_csi.h 2014-12-08 00:31:53.256418001 -0600
  68750. @@ -0,0 +1,198 @@
  68751. +/*
  68752. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  68753. + */
  68754. +
  68755. +/*
  68756. + * The code contained herein is licensed under the GNU General Public
  68757. + * License. You may obtain a copy of the GNU General Public License
  68758. + * Version 2 or later at the following locations:
  68759. + *
  68760. + * http://www.opensource.org/licenses/gpl-license.html
  68761. + * http://www.gnu.org/copyleft/gpl.html
  68762. + */
  68763. +
  68764. +/*!
  68765. + * @file fsl_csi.h
  68766. + *
  68767. + * @brief mx25 CMOS Sensor interface functions
  68768. + *
  68769. + * @ingroup CSI
  68770. + */
  68771. +
  68772. +#ifndef MX25_CSI_H
  68773. +#define MX25_CSI_H
  68774. +
  68775. +#include <linux/io.h>
  68776. +
  68777. +/* reset values */
  68778. +#define CSICR1_RESET_VAL 0x40000800
  68779. +#define CSICR2_RESET_VAL 0x0
  68780. +#define CSICR3_RESET_VAL 0x0
  68781. +
  68782. +/* csi control reg 1 */
  68783. +#define BIT_SWAP16_EN (0x1 << 31)
  68784. +#define BIT_EXT_VSYNC (0x1 << 30)
  68785. +#define BIT_EOF_INT_EN (0x1 << 29)
  68786. +#define BIT_PRP_IF_EN (0x1 << 28)
  68787. +#define BIT_CCIR_MODE (0x1 << 27)
  68788. +#define BIT_COF_INT_EN (0x1 << 26)
  68789. +#define BIT_SF_OR_INTEN (0x1 << 25)
  68790. +#define BIT_RF_OR_INTEN (0x1 << 24)
  68791. +#define BIT_SFF_DMA_DONE_INTEN (0x1 << 22)
  68792. +#define BIT_STATFF_INTEN (0x1 << 21)
  68793. +#define BIT_FB2_DMA_DONE_INTEN (0x1 << 20)
  68794. +#define BIT_FB1_DMA_DONE_INTEN (0x1 << 19)
  68795. +#define BIT_RXFF_INTEN (0x1 << 18)
  68796. +#define BIT_SOF_POL (0x1 << 17)
  68797. +#define BIT_SOF_INTEN (0x1 << 16)
  68798. +#define BIT_MCLKDIV (0xF << 12)
  68799. +#define BIT_HSYNC_POL (0x1 << 11)
  68800. +#define BIT_CCIR_EN (0x1 << 10)
  68801. +#define BIT_MCLKEN (0x1 << 9)
  68802. +#define BIT_FCC (0x1 << 8)
  68803. +#define BIT_PACK_DIR (0x1 << 7)
  68804. +#define BIT_CLR_STATFIFO (0x1 << 6)
  68805. +#define BIT_CLR_RXFIFO (0x1 << 5)
  68806. +#define BIT_GCLK_MODE (0x1 << 4)
  68807. +#define BIT_INV_DATA (0x1 << 3)
  68808. +#define BIT_INV_PCLK (0x1 << 2)
  68809. +#define BIT_REDGE (0x1 << 1)
  68810. +#define BIT_PIXEL_BIT (0x1 << 0)
  68811. +
  68812. +#define SHIFT_MCLKDIV 12
  68813. +
  68814. +/* control reg 3 */
  68815. +#define BIT_FRMCNT (0xFFFF << 16)
  68816. +#define BIT_FRMCNT_RST (0x1 << 15)
  68817. +#define BIT_DMA_REFLASH_RFF (0x1 << 14)
  68818. +#define BIT_DMA_REFLASH_SFF (0x1 << 13)
  68819. +#define BIT_DMA_REQ_EN_RFF (0x1 << 12)
  68820. +#define BIT_DMA_REQ_EN_SFF (0x1 << 11)
  68821. +#define BIT_STATFF_LEVEL (0x7 << 8)
  68822. +#define BIT_HRESP_ERR_EN (0x1 << 7)
  68823. +#define BIT_RXFF_LEVEL (0x7 << 4)
  68824. +#define BIT_TWO_8BIT_SENSOR (0x1 << 3)
  68825. +#define BIT_ZERO_PACK_EN (0x1 << 2)
  68826. +#define BIT_ECC_INT_EN (0x1 << 1)
  68827. +#define BIT_ECC_AUTO_EN (0x1 << 0)
  68828. +
  68829. +#define SHIFT_FRMCNT 16
  68830. +
  68831. +/* csi status reg */
  68832. +#define BIT_SFF_OR_INT (0x1 << 25)
  68833. +#define BIT_RFF_OR_INT (0x1 << 24)
  68834. +#define BIT_DMA_TSF_DONE_SFF (0x1 << 22)
  68835. +#define BIT_STATFF_INT (0x1 << 21)
  68836. +#define BIT_DMA_TSF_DONE_FB2 (0x1 << 20)
  68837. +#define BIT_DMA_TSF_DONE_FB1 (0x1 << 19)
  68838. +#define BIT_RXFF_INT (0x1 << 18)
  68839. +#define BIT_EOF_INT (0x1 << 17)
  68840. +#define BIT_SOF_INT (0x1 << 16)
  68841. +#define BIT_F2_INT (0x1 << 15)
  68842. +#define BIT_F1_INT (0x1 << 14)
  68843. +#define BIT_COF_INT (0x1 << 13)
  68844. +#define BIT_HRESP_ERR_INT (0x1 << 7)
  68845. +#define BIT_ECC_INT (0x1 << 1)
  68846. +#define BIT_DRDY (0x1 << 0)
  68847. +
  68848. +#define CSI_MCLK_VF 1
  68849. +#define CSI_MCLK_ENC 2
  68850. +#define CSI_MCLK_RAW 4
  68851. +#define CSI_MCLK_I2C 8
  68852. +#endif
  68853. +
  68854. +extern void __iomem *csi_regbase;
  68855. +#define CSI_CSICR1 (csi_regbase)
  68856. +#define CSI_CSICR2 (csi_regbase + 0x4)
  68857. +#define CSI_CSICR3 (csi_regbase + 0x8)
  68858. +#define CSI_STATFIFO (csi_regbase + 0xC)
  68859. +#define CSI_CSIRXFIFO (csi_regbase + 0x10)
  68860. +#define CSI_CSIRXCNT (csi_regbase + 0x14)
  68861. +#define CSI_CSISR (csi_regbase + 0x18)
  68862. +
  68863. +#define CSI_CSIDBG (csi_regbase + 0x1C)
  68864. +#define CSI_CSIDMASA_STATFIFO (csi_regbase + 0x20)
  68865. +#define CSI_CSIDMATS_STATFIFO (csi_regbase + 0x24)
  68866. +#define CSI_CSIDMASA_FB1 (csi_regbase + 0x28)
  68867. +#define CSI_CSIDMASA_FB2 (csi_regbase + 0x2C)
  68868. +#define CSI_CSIFBUF_PARA (csi_regbase + 0x30)
  68869. +#define CSI_CSIIMAG_PARA (csi_regbase + 0x34)
  68870. +
  68871. +static inline void csi_clear_status(unsigned long status)
  68872. +{
  68873. + __raw_writel(status, CSI_CSISR);
  68874. +}
  68875. +
  68876. +struct csi_signal_cfg_t {
  68877. + unsigned data_width:3;
  68878. + unsigned clk_mode:2;
  68879. + unsigned ext_vsync:1;
  68880. + unsigned Vsync_pol:1;
  68881. + unsigned Hsync_pol:1;
  68882. + unsigned pixclk_pol:1;
  68883. + unsigned data_pol:1;
  68884. + unsigned sens_clksrc:1;
  68885. +};
  68886. +
  68887. +struct csi_config_t {
  68888. + /* control reg 1 */
  68889. + unsigned int swap16_en:1;
  68890. + unsigned int ext_vsync:1;
  68891. + unsigned int eof_int_en:1;
  68892. + unsigned int prp_if_en:1;
  68893. + unsigned int ccir_mode:1;
  68894. + unsigned int cof_int_en:1;
  68895. + unsigned int sf_or_inten:1;
  68896. + unsigned int rf_or_inten:1;
  68897. + unsigned int sff_dma_done_inten:1;
  68898. + unsigned int statff_inten:1;
  68899. + unsigned int fb2_dma_done_inten:1;
  68900. + unsigned int fb1_dma_done_inten:1;
  68901. + unsigned int rxff_inten:1;
  68902. + unsigned int sof_pol:1;
  68903. + unsigned int sof_inten:1;
  68904. + unsigned int mclkdiv:4;
  68905. + unsigned int hsync_pol:1;
  68906. + unsigned int ccir_en:1;
  68907. + unsigned int mclken:1;
  68908. + unsigned int fcc:1;
  68909. + unsigned int pack_dir:1;
  68910. + unsigned int gclk_mode:1;
  68911. + unsigned int inv_data:1;
  68912. + unsigned int inv_pclk:1;
  68913. + unsigned int redge:1;
  68914. + unsigned int pixel_bit:1;
  68915. +
  68916. + /* control reg 3 */
  68917. + unsigned int frmcnt:16;
  68918. + unsigned int frame_reset:1;
  68919. + unsigned int dma_reflash_rff:1;
  68920. + unsigned int dma_reflash_sff:1;
  68921. + unsigned int dma_req_en_rff:1;
  68922. + unsigned int dma_req_en_sff:1;
  68923. + unsigned int statff_level:3;
  68924. + unsigned int hresp_err_en:1;
  68925. + unsigned int rxff_level:3;
  68926. + unsigned int two_8bit_sensor:1;
  68927. + unsigned int zero_pack_en:1;
  68928. + unsigned int ecc_int_en:1;
  68929. + unsigned int ecc_auto_en:1;
  68930. + /* fifo counter */
  68931. + unsigned int rxcnt;
  68932. +};
  68933. +
  68934. +typedef void (*csi_irq_callback_t) (void *data, unsigned long status);
  68935. +
  68936. +void csi_init_interface(void);
  68937. +void csi_init_format(int fmt);
  68938. +void csi_set_16bit_imagpara(int width, int height);
  68939. +void csi_set_12bit_imagpara(int width, int height);
  68940. +int csi_read_mclk_flag(void);
  68941. +void csi_start_callback(void *data);
  68942. +void csi_stop_callback(void *data);
  68943. +void csi_enable_int(int arg);
  68944. +void csi_disable_int(void);
  68945. +void csi_mclk_enable(void);
  68946. +void csi_mclk_disable(void);
  68947. +void csi_dmareq_rff_enable(void);
  68948. +void csi_dmareq_rff_disable(void);
  68949. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c
  68950. --- linux-3.14.14/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c 1969-12-31 18:00:00.000000000 -0600
  68951. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c 2014-12-08 00:31:53.256418001 -0600
  68952. @@ -0,0 +1,546 @@
  68953. +
  68954. +/*
  68955. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  68956. + */
  68957. +
  68958. +/*
  68959. + * The code contained herein is licensed under the GNU General Public
  68960. + * License. You may obtain a copy of the GNU General Public License
  68961. + * Version 2 or later at the following locations:
  68962. + *
  68963. + * http://www.opensource.org/licenses/gpl-license.html
  68964. + * http://www.gnu.org/copyleft/gpl.html
  68965. + */
  68966. +
  68967. +/*!
  68968. + * @file ipu_bg_overlay_sdc_bg.c
  68969. + *
  68970. + * @brief IPU Use case for PRP-VF back-ground
  68971. + *
  68972. + * @ingroup IPU
  68973. + */
  68974. +#include <linux/module.h>
  68975. +#include <linux/dma-mapping.h>
  68976. +#include <linux/fb.h>
  68977. +#include <linux/ipu.h>
  68978. +#include <linux/mipi_csi2.h>
  68979. +#include "mxc_v4l2_capture.h"
  68980. +#include "ipu_prp_sw.h"
  68981. +
  68982. +static int csi_buffer_num;
  68983. +static u32 bpp, csi_mem_bufsize = 3;
  68984. +static u32 out_format;
  68985. +static struct ipu_soc *disp_ipu;
  68986. +static u32 offset;
  68987. +
  68988. +static void csi_buf_work_func(struct work_struct *work)
  68989. +{
  68990. + int err = 0;
  68991. + cam_data *cam =
  68992. + container_of(work, struct _cam_data, csi_work_struct);
  68993. +
  68994. + struct ipu_task task;
  68995. + memset(&task, 0, sizeof(task));
  68996. +
  68997. + if (csi_buffer_num)
  68998. + task.input.paddr = cam->vf_bufs[0];
  68999. + else
  69000. + task.input.paddr = cam->vf_bufs[1];
  69001. + task.input.width = cam->crop_current.width;
  69002. + task.input.height = cam->crop_current.height;
  69003. + task.input.format = IPU_PIX_FMT_UYVY;
  69004. +
  69005. + task.output.paddr = offset;
  69006. + task.output.width = cam->overlay_fb->var.xres;
  69007. + task.output.height = cam->overlay_fb->var.yres;
  69008. + task.output.format = out_format;
  69009. + task.output.rotate = cam->rotation;
  69010. + task.output.crop.pos.x = cam->win.w.left;
  69011. + task.output.crop.pos.y = cam->win.w.top;
  69012. + if (cam->win.w.width > 1024 || cam->win.w.height > 1024) {
  69013. + task.output.crop.w = cam->overlay_fb->var.xres;
  69014. + task.output.crop.h = cam->overlay_fb->var.yres;
  69015. + } else {
  69016. + task.output.crop.w = cam->win.w.width;
  69017. + task.output.crop.h = cam->win.w.height;
  69018. + }
  69019. +again:
  69020. + err = ipu_check_task(&task);
  69021. + if (err != IPU_CHECK_OK) {
  69022. + if (err > IPU_CHECK_ERR_MIN) {
  69023. + if (err == IPU_CHECK_ERR_SPLIT_INPUTW_OVER) {
  69024. + task.input.crop.w -= 8;
  69025. + goto again;
  69026. + }
  69027. + if (err == IPU_CHECK_ERR_SPLIT_INPUTH_OVER) {
  69028. + task.input.crop.h -= 8;
  69029. + goto again;
  69030. + }
  69031. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
  69032. + task.output.width -= 8;
  69033. + task.output.crop.w = task.output.width;
  69034. + goto again;
  69035. + }
  69036. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
  69037. + task.output.height -= 8;
  69038. + task.output.crop.h = task.output.height;
  69039. + goto again;
  69040. + }
  69041. + printk(KERN_ERR "check ipu taks fail\n");
  69042. + return;
  69043. + }
  69044. + printk(KERN_ERR "check ipu taks fail\n");
  69045. + return;
  69046. + }
  69047. + err = ipu_queue_task(&task);
  69048. + if (err < 0)
  69049. + printk(KERN_ERR "queue ipu task error\n");
  69050. +}
  69051. +
  69052. +static void get_disp_ipu(cam_data *cam)
  69053. +{
  69054. + if (cam->output > 2)
  69055. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  69056. + else
  69057. + disp_ipu = ipu_get_soc(0);
  69058. +}
  69059. +
  69060. +
  69061. +/*!
  69062. + * csi ENC callback function.
  69063. + *
  69064. + * @param irq int irq line
  69065. + * @param dev_id void * device id
  69066. + *
  69067. + * @return status IRQ_HANDLED for handled
  69068. + */
  69069. +static irqreturn_t csi_enc_callback(int irq, void *dev_id)
  69070. +{
  69071. + cam_data *cam = (cam_data *) dev_id;
  69072. +
  69073. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, csi_buffer_num);
  69074. + schedule_work(&cam->csi_work_struct);
  69075. + csi_buffer_num = (csi_buffer_num == 0) ? 1 : 0;
  69076. + return IRQ_HANDLED;
  69077. +}
  69078. +
  69079. +static int csi_enc_setup(cam_data *cam)
  69080. +{
  69081. + ipu_channel_params_t params;
  69082. + u32 pixel_fmt;
  69083. + int err = 0, sensor_protocol = 0;
  69084. +#ifdef CONFIG_MXC_MIPI_CSI2
  69085. + void *mipi_csi2_info;
  69086. + int ipu_id;
  69087. + int csi_id;
  69088. +#endif
  69089. +
  69090. + if (!cam) {
  69091. + printk(KERN_ERR "cam private is NULL\n");
  69092. + return -ENXIO;
  69093. + }
  69094. +
  69095. + memset(&params, 0, sizeof(ipu_channel_params_t));
  69096. + params.csi_mem.csi = cam->csi;
  69097. +
  69098. + sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
  69099. + switch (sensor_protocol) {
  69100. + case IPU_CSI_CLK_MODE_GATED_CLK:
  69101. + case IPU_CSI_CLK_MODE_NONGATED_CLK:
  69102. + case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
  69103. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
  69104. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
  69105. + params.csi_mem.interlaced = false;
  69106. + break;
  69107. + case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
  69108. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
  69109. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
  69110. + params.csi_mem.interlaced = true;
  69111. + break;
  69112. + default:
  69113. + printk(KERN_ERR "sensor protocol unsupported\n");
  69114. + return -EINVAL;
  69115. + }
  69116. +
  69117. +#ifdef CONFIG_MXC_MIPI_CSI2
  69118. + mipi_csi2_info = mipi_csi2_get_info();
  69119. +
  69120. + if (mipi_csi2_info) {
  69121. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  69122. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  69123. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  69124. +
  69125. + if (cam->ipu == ipu_get_soc(ipu_id)
  69126. + && cam->csi == csi_id) {
  69127. + params.csi_mem.mipi_en = true;
  69128. + params.csi_mem.mipi_vc =
  69129. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  69130. + params.csi_mem.mipi_id =
  69131. + mipi_csi2_get_datatype(mipi_csi2_info);
  69132. +
  69133. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  69134. + } else {
  69135. + params.csi_mem.mipi_en = false;
  69136. + params.csi_mem.mipi_vc = 0;
  69137. + params.csi_mem.mipi_id = 0;
  69138. + }
  69139. + } else {
  69140. + params.csi_mem.mipi_en = false;
  69141. + params.csi_mem.mipi_vc = 0;
  69142. + params.csi_mem.mipi_id = 0;
  69143. + }
  69144. + }
  69145. +#endif
  69146. +
  69147. + if (cam->vf_bufs_vaddr[0]) {
  69148. + dma_free_coherent(0, cam->vf_bufs_size[0],
  69149. + cam->vf_bufs_vaddr[0],
  69150. + (dma_addr_t) cam->vf_bufs[0]);
  69151. + }
  69152. + if (cam->vf_bufs_vaddr[1]) {
  69153. + dma_free_coherent(0, cam->vf_bufs_size[1],
  69154. + cam->vf_bufs_vaddr[1],
  69155. + (dma_addr_t) cam->vf_bufs[1]);
  69156. + }
  69157. + csi_mem_bufsize =
  69158. + cam->crop_current.width * cam->crop_current.height * 2;
  69159. + cam->vf_bufs_size[0] = PAGE_ALIGN(csi_mem_bufsize);
  69160. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  69161. + cam->vf_bufs_size[0],
  69162. + (dma_addr_t *) &
  69163. + cam->vf_bufs[0],
  69164. + GFP_DMA |
  69165. + GFP_KERNEL);
  69166. + if (cam->vf_bufs_vaddr[0] == NULL) {
  69167. + printk(KERN_ERR "Error to allocate vf buffer\n");
  69168. + err = -ENOMEM;
  69169. + goto out_2;
  69170. + }
  69171. + cam->vf_bufs_size[1] = PAGE_ALIGN(csi_mem_bufsize);
  69172. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  69173. + cam->vf_bufs_size[1],
  69174. + (dma_addr_t *) &
  69175. + cam->vf_bufs[1],
  69176. + GFP_DMA |
  69177. + GFP_KERNEL);
  69178. + if (cam->vf_bufs_vaddr[1] == NULL) {
  69179. + printk(KERN_ERR "Error to allocate vf buffer\n");
  69180. + err = -ENOMEM;
  69181. + goto out_1;
  69182. + }
  69183. + pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
  69184. +
  69185. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  69186. + if (err != 0) {
  69187. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  69188. + goto out_1;
  69189. + }
  69190. +
  69191. + pixel_fmt = IPU_PIX_FMT_UYVY;
  69192. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  69193. + pixel_fmt, cam->crop_current.width,
  69194. + cam->crop_current.height,
  69195. + cam->crop_current.width, IPU_ROTATE_NONE,
  69196. + cam->vf_bufs[0], cam->vf_bufs[1], 0,
  69197. + cam->offset.u_offset, cam->offset.u_offset);
  69198. + if (err != 0) {
  69199. + printk(KERN_ERR "CSI_MEM output buffer\n");
  69200. + goto out_1;
  69201. + }
  69202. + err = ipu_enable_channel(cam->ipu, CSI_MEM);
  69203. + if (err < 0) {
  69204. + printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
  69205. + goto out_1;
  69206. + }
  69207. +
  69208. + csi_buffer_num = 0;
  69209. +
  69210. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 0);
  69211. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 1);
  69212. + return err;
  69213. +out_1:
  69214. + if (cam->vf_bufs_vaddr[0]) {
  69215. + dma_free_coherent(0, cam->vf_bufs_size[0],
  69216. + cam->vf_bufs_vaddr[0],
  69217. + (dma_addr_t) cam->vf_bufs[0]);
  69218. + cam->vf_bufs_vaddr[0] = NULL;
  69219. + cam->vf_bufs[0] = 0;
  69220. + }
  69221. + if (cam->vf_bufs_vaddr[1]) {
  69222. + dma_free_coherent(0, cam->vf_bufs_size[1],
  69223. + cam->vf_bufs_vaddr[1],
  69224. + (dma_addr_t) cam->vf_bufs[1]);
  69225. + cam->vf_bufs_vaddr[1] = NULL;
  69226. + cam->vf_bufs[1] = 0;
  69227. + }
  69228. +out_2:
  69229. + return err;
  69230. +}
  69231. +
  69232. +/*!
  69233. + * Enable encoder task
  69234. + * @param private struct cam_data * mxc capture instance
  69235. + *
  69236. + * @return status
  69237. + */
  69238. +static int csi_enc_enabling_tasks(void *private)
  69239. +{
  69240. + cam_data *cam = (cam_data *) private;
  69241. + int err = 0;
  69242. +
  69243. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  69244. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  69245. + csi_enc_callback, 0, "Mxc Camera", cam);
  69246. + if (err != 0) {
  69247. + printk(KERN_ERR "Error registering CSI0_OUT_EOF irq\n");
  69248. + return err;
  69249. + }
  69250. +
  69251. + INIT_WORK(&cam->csi_work_struct, csi_buf_work_func);
  69252. +
  69253. + err = csi_enc_setup(cam);
  69254. + if (err != 0) {
  69255. + printk(KERN_ERR "csi_enc_setup %d\n", err);
  69256. + goto out1;
  69257. + }
  69258. +
  69259. + return err;
  69260. +out1:
  69261. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  69262. + return err;
  69263. +}
  69264. +
  69265. +/*!
  69266. + * bg_overlay_start - start the overlay task
  69267. + *
  69268. + * @param private cam_data * mxc v4l2 main structure
  69269. + *
  69270. + */
  69271. +static int bg_overlay_start(void *private)
  69272. +{
  69273. + cam_data *cam = (cam_data *) private;
  69274. + int err = 0;
  69275. +
  69276. + if (!cam) {
  69277. + printk(KERN_ERR "private is NULL\n");
  69278. + return -EIO;
  69279. + }
  69280. +
  69281. + if (cam->overlay_active == true) {
  69282. + pr_debug("already start.\n");
  69283. + return 0;
  69284. + }
  69285. +
  69286. + get_disp_ipu(cam);
  69287. +
  69288. + out_format = cam->v4l2_fb.fmt.pixelformat;
  69289. + if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR24) {
  69290. + bpp = 3, csi_mem_bufsize = 3;
  69291. + pr_info("BGR24\n");
  69292. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_RGB565) {
  69293. + bpp = 2, csi_mem_bufsize = 2;
  69294. + pr_info("RGB565\n");
  69295. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR32) {
  69296. + bpp = 4, csi_mem_bufsize = 4;
  69297. + pr_info("BGR32\n");
  69298. + } else {
  69299. + printk(KERN_ERR
  69300. + "unsupported fix format from the framebuffer.\n");
  69301. + return -EINVAL;
  69302. + }
  69303. +
  69304. + offset = cam->v4l2_fb.fmt.bytesperline * cam->win.w.top +
  69305. + csi_mem_bufsize * cam->win.w.left;
  69306. +
  69307. + if (cam->v4l2_fb.base == 0)
  69308. + printk(KERN_ERR "invalid frame buffer address.\n");
  69309. + else
  69310. + offset += (u32) cam->v4l2_fb.base;
  69311. +
  69312. + csi_mem_bufsize = cam->win.w.width * cam->win.w.height
  69313. + * csi_mem_bufsize;
  69314. +
  69315. + err = csi_enc_enabling_tasks(cam);
  69316. + if (err != 0) {
  69317. + printk(KERN_ERR "Error csi enc enable fail\n");
  69318. + return err;
  69319. + }
  69320. +
  69321. + cam->overlay_active = true;
  69322. + return err;
  69323. +}
  69324. +
  69325. +/*!
  69326. + * bg_overlay_stop - stop the overlay task
  69327. + *
  69328. + * @param private cam_data * mxc v4l2 main structure
  69329. + *
  69330. + */
  69331. +static int bg_overlay_stop(void *private)
  69332. +{
  69333. + int err = 0;
  69334. + cam_data *cam = (cam_data *) private;
  69335. +#ifdef CONFIG_MXC_MIPI_CSI2
  69336. + void *mipi_csi2_info;
  69337. + int ipu_id;
  69338. + int csi_id;
  69339. +#endif
  69340. +
  69341. + if (cam->overlay_active == false)
  69342. + return 0;
  69343. +
  69344. + err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
  69345. +
  69346. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  69347. +
  69348. + csi_buffer_num = 0;
  69349. +
  69350. +#ifdef CONFIG_MXC_MIPI_CSI2
  69351. + mipi_csi2_info = mipi_csi2_get_info();
  69352. +
  69353. + if (mipi_csi2_info) {
  69354. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  69355. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  69356. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  69357. +
  69358. + if (cam->ipu == ipu_get_soc(ipu_id)
  69359. + && cam->csi == csi_id)
  69360. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  69361. + }
  69362. + }
  69363. +#endif
  69364. +
  69365. + flush_work(&cam->csi_work_struct);
  69366. + cancel_work_sync(&cam->csi_work_struct);
  69367. +
  69368. + if (cam->vf_bufs_vaddr[0]) {
  69369. + dma_free_coherent(0, cam->vf_bufs_size[0],
  69370. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  69371. + cam->vf_bufs_vaddr[0] = NULL;
  69372. + cam->vf_bufs[0] = 0;
  69373. + }
  69374. + if (cam->vf_bufs_vaddr[1]) {
  69375. + dma_free_coherent(0, cam->vf_bufs_size[1],
  69376. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  69377. + cam->vf_bufs_vaddr[1] = NULL;
  69378. + cam->vf_bufs[1] = 0;
  69379. + }
  69380. + if (cam->rot_vf_bufs_vaddr[0]) {
  69381. + dma_free_coherent(0, cam->rot_vf_buf_size[0],
  69382. + cam->rot_vf_bufs_vaddr[0],
  69383. + cam->rot_vf_bufs[0]);
  69384. + cam->rot_vf_bufs_vaddr[0] = NULL;
  69385. + cam->rot_vf_bufs[0] = 0;
  69386. + }
  69387. + if (cam->rot_vf_bufs_vaddr[1]) {
  69388. + dma_free_coherent(0, cam->rot_vf_buf_size[1],
  69389. + cam->rot_vf_bufs_vaddr[1],
  69390. + cam->rot_vf_bufs[1]);
  69391. + cam->rot_vf_bufs_vaddr[1] = NULL;
  69392. + cam->rot_vf_bufs[1] = 0;
  69393. + }
  69394. +
  69395. + cam->overlay_active = false;
  69396. + return err;
  69397. +}
  69398. +
  69399. +/*!
  69400. + * Enable csi
  69401. + * @param private struct cam_data * mxc capture instance
  69402. + *
  69403. + * @return status
  69404. + */
  69405. +static int bg_overlay_enable_csi(void *private)
  69406. +{
  69407. + cam_data *cam = (cam_data *) private;
  69408. +
  69409. + return ipu_enable_csi(cam->ipu, cam->csi);
  69410. +}
  69411. +
  69412. +/*!
  69413. + * Disable csi
  69414. + * @param private struct cam_data * mxc capture instance
  69415. + *
  69416. + * @return status
  69417. + */
  69418. +static int bg_overlay_disable_csi(void *private)
  69419. +{
  69420. + cam_data *cam = (cam_data *) private;
  69421. +
  69422. + /* free csi eof irq firstly.
  69423. + * when disable csi, wait for idmac eof.
  69424. + * it requests eof irq again */
  69425. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  69426. +
  69427. + return ipu_disable_csi(cam->ipu, cam->csi);
  69428. +}
  69429. +
  69430. +/*!
  69431. + * function to select bg as the working path
  69432. + *
  69433. + * @param private cam_data * mxc v4l2 main structure
  69434. + *
  69435. + * @return status
  69436. + */
  69437. +int bg_overlay_sdc_select(void *private)
  69438. +{
  69439. + cam_data *cam = (cam_data *) private;
  69440. +
  69441. + if (cam) {
  69442. + cam->vf_start_sdc = bg_overlay_start;
  69443. + cam->vf_stop_sdc = bg_overlay_stop;
  69444. + cam->vf_enable_csi = bg_overlay_enable_csi;
  69445. + cam->vf_disable_csi = bg_overlay_disable_csi;
  69446. + cam->overlay_active = false;
  69447. + }
  69448. +
  69449. + return 0;
  69450. +}
  69451. +EXPORT_SYMBOL(bg_overlay_sdc_select);
  69452. +
  69453. +/*!
  69454. + * function to de-select bg as the working path
  69455. + *
  69456. + * @param private cam_data * mxc v4l2 main structure
  69457. + *
  69458. + * @return status
  69459. + */
  69460. +int bg_overlay_sdc_deselect(void *private)
  69461. +{
  69462. + cam_data *cam = (cam_data *) private;
  69463. +
  69464. + if (cam) {
  69465. + cam->vf_start_sdc = NULL;
  69466. + cam->vf_stop_sdc = NULL;
  69467. + cam->vf_enable_csi = NULL;
  69468. + cam->vf_disable_csi = NULL;
  69469. + }
  69470. + return 0;
  69471. +}
  69472. +EXPORT_SYMBOL(bg_overlay_sdc_deselect);
  69473. +
  69474. +/*!
  69475. + * Init background overlay task.
  69476. + *
  69477. + * @return Error code indicating success or failure
  69478. + */
  69479. +__init int bg_overlay_sdc_init(void)
  69480. +{
  69481. + return 0;
  69482. +}
  69483. +
  69484. +/*!
  69485. + * Deinit background overlay task.
  69486. + *
  69487. + * @return Error code indicating success or failure
  69488. + */
  69489. +void __exit bg_overlay_sdc_exit(void)
  69490. +{
  69491. +}
  69492. +
  69493. +module_init(bg_overlay_sdc_init);
  69494. +module_exit(bg_overlay_sdc_exit);
  69495. +
  69496. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  69497. +MODULE_DESCRIPTION("IPU PRP VF SDC Backgroud Driver");
  69498. +MODULE_LICENSE("GPL");
  69499. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/ipu_csi_enc.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_csi_enc.c
  69500. --- linux-3.14.14/drivers/media/platform/mxc/capture/ipu_csi_enc.c 1969-12-31 18:00:00.000000000 -0600
  69501. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_csi_enc.c 2014-12-08 00:31:53.256418001 -0600
  69502. @@ -0,0 +1,418 @@
  69503. +/*
  69504. + * Copyright 2009-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  69505. + */
  69506. +
  69507. +/*
  69508. + * The code contained herein is licensed under the GNU General Public
  69509. + * License. You may obtain a copy of the GNU General Public License
  69510. + * Version 2 or later at the following locations:
  69511. + *
  69512. + * http://www.opensource.org/licenses/gpl-license.html
  69513. + * http://www.gnu.org/copyleft/gpl.html
  69514. + */
  69515. +
  69516. +/*!
  69517. + * @file ipu_csi_enc.c
  69518. + *
  69519. + * @brief CSI Use case for video capture
  69520. + *
  69521. + * @ingroup IPU
  69522. + */
  69523. +
  69524. +#include <linux/module.h>
  69525. +#include <linux/platform_device.h>
  69526. +#include <linux/dma-mapping.h>
  69527. +#include <linux/ipu.h>
  69528. +#include <linux/mipi_csi2.h>
  69529. +#include "mxc_v4l2_capture.h"
  69530. +#include "ipu_prp_sw.h"
  69531. +
  69532. +#ifdef CAMERA_DBG
  69533. + #define CAMERA_TRACE(x) (printk)x
  69534. +#else
  69535. + #define CAMERA_TRACE(x)
  69536. +#endif
  69537. +
  69538. +/*
  69539. + * Function definitions
  69540. + */
  69541. +
  69542. +/*!
  69543. + * csi ENC callback function.
  69544. + *
  69545. + * @param irq int irq line
  69546. + * @param dev_id void * device id
  69547. + *
  69548. + * @return status IRQ_HANDLED for handled
  69549. + */
  69550. +static irqreturn_t csi_enc_callback(int irq, void *dev_id)
  69551. +{
  69552. + cam_data *cam = (cam_data *) dev_id;
  69553. +
  69554. + if (cam->enc_callback == NULL)
  69555. + return IRQ_HANDLED;
  69556. +
  69557. + cam->enc_callback(irq, dev_id);
  69558. + return IRQ_HANDLED;
  69559. +}
  69560. +
  69561. +/*!
  69562. + * CSI ENC enable channel setup function
  69563. + *
  69564. + * @param cam struct cam_data * mxc capture instance
  69565. + *
  69566. + * @return status
  69567. + */
  69568. +static int csi_enc_setup(cam_data *cam)
  69569. +{
  69570. + ipu_channel_params_t params;
  69571. + u32 pixel_fmt;
  69572. + int err = 0, sensor_protocol = 0;
  69573. + dma_addr_t dummy = cam->dummy_frame.buffer.m.offset;
  69574. +#ifdef CONFIG_MXC_MIPI_CSI2
  69575. + void *mipi_csi2_info;
  69576. + int ipu_id;
  69577. + int csi_id;
  69578. +#endif
  69579. +
  69580. + CAMERA_TRACE("In csi_enc_setup\n");
  69581. + if (!cam) {
  69582. + printk(KERN_ERR "cam private is NULL\n");
  69583. + return -ENXIO;
  69584. + }
  69585. +
  69586. + memset(&params, 0, sizeof(ipu_channel_params_t));
  69587. + params.csi_mem.csi = cam->csi;
  69588. +
  69589. + sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
  69590. + switch (sensor_protocol) {
  69591. + case IPU_CSI_CLK_MODE_GATED_CLK:
  69592. + case IPU_CSI_CLK_MODE_NONGATED_CLK:
  69593. + case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
  69594. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
  69595. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
  69596. + params.csi_mem.interlaced = false;
  69597. + break;
  69598. + case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
  69599. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
  69600. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
  69601. + params.csi_mem.interlaced = true;
  69602. + break;
  69603. + default:
  69604. + printk(KERN_ERR "sensor protocol unsupported\n");
  69605. + return -EINVAL;
  69606. + }
  69607. +
  69608. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
  69609. + pixel_fmt = IPU_PIX_FMT_YUV420P;
  69610. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420)
  69611. + pixel_fmt = IPU_PIX_FMT_YVU420P;
  69612. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P)
  69613. + pixel_fmt = IPU_PIX_FMT_YUV422P;
  69614. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
  69615. + pixel_fmt = IPU_PIX_FMT_UYVY;
  69616. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
  69617. + pixel_fmt = IPU_PIX_FMT_YUYV;
  69618. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)
  69619. + pixel_fmt = IPU_PIX_FMT_NV12;
  69620. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
  69621. + pixel_fmt = IPU_PIX_FMT_BGR24;
  69622. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
  69623. + pixel_fmt = IPU_PIX_FMT_RGB24;
  69624. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565)
  69625. + pixel_fmt = IPU_PIX_FMT_RGB565;
  69626. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32)
  69627. + pixel_fmt = IPU_PIX_FMT_BGR32;
  69628. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32)
  69629. + pixel_fmt = IPU_PIX_FMT_RGB32;
  69630. + else {
  69631. + printk(KERN_ERR "format not supported\n");
  69632. + return -EINVAL;
  69633. + }
  69634. +
  69635. +#ifdef CONFIG_MXC_MIPI_CSI2
  69636. + mipi_csi2_info = mipi_csi2_get_info();
  69637. +
  69638. + if (mipi_csi2_info) {
  69639. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  69640. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  69641. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  69642. +
  69643. + if (cam->ipu == ipu_get_soc(ipu_id)
  69644. + && cam->csi == csi_id) {
  69645. + params.csi_mem.mipi_en = true;
  69646. + params.csi_mem.mipi_vc =
  69647. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  69648. + params.csi_mem.mipi_id =
  69649. + mipi_csi2_get_datatype(mipi_csi2_info);
  69650. +
  69651. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  69652. + } else {
  69653. + params.csi_mem.mipi_en = false;
  69654. + params.csi_mem.mipi_vc = 0;
  69655. + params.csi_mem.mipi_id = 0;
  69656. + }
  69657. + } else {
  69658. + params.csi_mem.mipi_en = false;
  69659. + params.csi_mem.mipi_vc = 0;
  69660. + params.csi_mem.mipi_id = 0;
  69661. + }
  69662. + }
  69663. +#endif
  69664. +
  69665. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  69666. + if (err != 0) {
  69667. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  69668. + return err;
  69669. + }
  69670. +
  69671. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  69672. + pixel_fmt, cam->v2f.fmt.pix.width,
  69673. + cam->v2f.fmt.pix.height,
  69674. + cam->v2f.fmt.pix.bytesperline,
  69675. + IPU_ROTATE_NONE,
  69676. + dummy, dummy, 0,
  69677. + cam->offset.u_offset,
  69678. + cam->offset.v_offset);
  69679. + if (err != 0) {
  69680. + printk(KERN_ERR "CSI_MEM output buffer\n");
  69681. + return err;
  69682. + }
  69683. + err = ipu_enable_channel(cam->ipu, CSI_MEM);
  69684. + if (err < 0) {
  69685. + printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
  69686. + return err;
  69687. + }
  69688. +
  69689. + return err;
  69690. +}
  69691. +
  69692. +/*!
  69693. + * function to update physical buffer address for encorder IDMA channel
  69694. + *
  69695. + * @param eba physical buffer address for encorder IDMA channel
  69696. + * @param buffer_num int buffer 0 or buffer 1
  69697. + *
  69698. + * @return status
  69699. + */
  69700. +static int csi_enc_eba_update(struct ipu_soc *ipu, dma_addr_t eba,
  69701. + int *buffer_num)
  69702. +{
  69703. + int err = 0;
  69704. +
  69705. + pr_debug("eba %x\n", eba);
  69706. + err = ipu_update_channel_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  69707. + *buffer_num, eba);
  69708. + if (err != 0) {
  69709. + ipu_clear_buffer_ready(ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  69710. + *buffer_num);
  69711. +
  69712. + err = ipu_update_channel_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  69713. + *buffer_num, eba);
  69714. + if (err != 0) {
  69715. + pr_err("ERROR: v4l2 capture: fail to update "
  69716. + "buf%d\n", *buffer_num);
  69717. + return err;
  69718. + }
  69719. + }
  69720. +
  69721. + ipu_select_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num);
  69722. +
  69723. + *buffer_num = (*buffer_num == 0) ? 1 : 0;
  69724. +
  69725. + return 0;
  69726. +}
  69727. +
  69728. +/*!
  69729. + * Enable encoder task
  69730. + * @param private struct cam_data * mxc capture instance
  69731. + *
  69732. + * @return status
  69733. + */
  69734. +static int csi_enc_enabling_tasks(void *private)
  69735. +{
  69736. + cam_data *cam = (cam_data *) private;
  69737. + int err = 0;
  69738. + CAMERA_TRACE("IPU:In csi_enc_enabling_tasks\n");
  69739. +
  69740. + cam->dummy_frame.vaddress = dma_alloc_coherent(0,
  69741. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  69742. + &cam->dummy_frame.paddress,
  69743. + GFP_DMA | GFP_KERNEL);
  69744. + if (cam->dummy_frame.vaddress == 0) {
  69745. + pr_err("ERROR: v4l2 capture: Allocate dummy frame "
  69746. + "failed.\n");
  69747. + return -ENOBUFS;
  69748. + }
  69749. + cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
  69750. + cam->dummy_frame.buffer.length =
  69751. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  69752. + cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
  69753. +
  69754. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  69755. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  69756. + csi_enc_callback, 0, "Mxc Camera", cam);
  69757. + if (err != 0) {
  69758. + printk(KERN_ERR "Error registering rot irq\n");
  69759. + return err;
  69760. + }
  69761. +
  69762. + err = csi_enc_setup(cam);
  69763. + if (err != 0) {
  69764. + printk(KERN_ERR "csi_enc_setup %d\n", err);
  69765. + return err;
  69766. + }
  69767. +
  69768. + return err;
  69769. +}
  69770. +
  69771. +/*!
  69772. + * Disable encoder task
  69773. + * @param private struct cam_data * mxc capture instance
  69774. + *
  69775. + * @return int
  69776. + */
  69777. +static int csi_enc_disabling_tasks(void *private)
  69778. +{
  69779. + cam_data *cam = (cam_data *) private;
  69780. + int err = 0;
  69781. +#ifdef CONFIG_MXC_MIPI_CSI2
  69782. + void *mipi_csi2_info;
  69783. + int ipu_id;
  69784. + int csi_id;
  69785. +#endif
  69786. +
  69787. + err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
  69788. +
  69789. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  69790. +
  69791. + if (cam->dummy_frame.vaddress != 0) {
  69792. + dma_free_coherent(0, cam->dummy_frame.buffer.length,
  69793. + cam->dummy_frame.vaddress,
  69794. + cam->dummy_frame.paddress);
  69795. + cam->dummy_frame.vaddress = 0;
  69796. + }
  69797. +
  69798. +#ifdef CONFIG_MXC_MIPI_CSI2
  69799. + mipi_csi2_info = mipi_csi2_get_info();
  69800. +
  69801. + if (mipi_csi2_info) {
  69802. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  69803. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  69804. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  69805. +
  69806. + if (cam->ipu == ipu_get_soc(ipu_id)
  69807. + && cam->csi == csi_id)
  69808. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  69809. + }
  69810. + }
  69811. +#endif
  69812. +
  69813. + return err;
  69814. +}
  69815. +
  69816. +/*!
  69817. + * Enable csi
  69818. + * @param private struct cam_data * mxc capture instance
  69819. + *
  69820. + * @return status
  69821. + */
  69822. +static int csi_enc_enable_csi(void *private)
  69823. +{
  69824. + cam_data *cam = (cam_data *) private;
  69825. +
  69826. + return ipu_enable_csi(cam->ipu, cam->csi);
  69827. +}
  69828. +
  69829. +/*!
  69830. + * Disable csi
  69831. + * @param private struct cam_data * mxc capture instance
  69832. + *
  69833. + * @return status
  69834. + */
  69835. +static int csi_enc_disable_csi(void *private)
  69836. +{
  69837. + cam_data *cam = (cam_data *) private;
  69838. +
  69839. + /* free csi eof irq firstly.
  69840. + * when disable csi, wait for idmac eof.
  69841. + * it requests eof irq again */
  69842. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  69843. +
  69844. + return ipu_disable_csi(cam->ipu, cam->csi);
  69845. +}
  69846. +
  69847. +/*!
  69848. + * function to select CSI ENC as the working path
  69849. + *
  69850. + * @param private struct cam_data * mxc capture instance
  69851. + *
  69852. + * @return int
  69853. + */
  69854. +int csi_enc_select(void *private)
  69855. +{
  69856. + cam_data *cam = (cam_data *) private;
  69857. + int err = 0;
  69858. +
  69859. + if (cam) {
  69860. + cam->enc_update_eba = csi_enc_eba_update;
  69861. + cam->enc_enable = csi_enc_enabling_tasks;
  69862. + cam->enc_disable = csi_enc_disabling_tasks;
  69863. + cam->enc_enable_csi = csi_enc_enable_csi;
  69864. + cam->enc_disable_csi = csi_enc_disable_csi;
  69865. + } else {
  69866. + err = -EIO;
  69867. + }
  69868. +
  69869. + return err;
  69870. +}
  69871. +EXPORT_SYMBOL(csi_enc_select);
  69872. +
  69873. +/*!
  69874. + * function to de-select CSI ENC as the working path
  69875. + *
  69876. + * @param private struct cam_data * mxc capture instance
  69877. + *
  69878. + * @return int
  69879. + */
  69880. +int csi_enc_deselect(void *private)
  69881. +{
  69882. + cam_data *cam = (cam_data *) private;
  69883. + int err = 0;
  69884. +
  69885. + if (cam) {
  69886. + cam->enc_update_eba = NULL;
  69887. + cam->enc_enable = NULL;
  69888. + cam->enc_disable = NULL;
  69889. + cam->enc_enable_csi = NULL;
  69890. + cam->enc_disable_csi = NULL;
  69891. + }
  69892. +
  69893. + return err;
  69894. +}
  69895. +EXPORT_SYMBOL(csi_enc_deselect);
  69896. +
  69897. +/*!
  69898. + * Init the Encorder channels
  69899. + *
  69900. + * @return Error code indicating success or failure
  69901. + */
  69902. +__init int csi_enc_init(void)
  69903. +{
  69904. + return 0;
  69905. +}
  69906. +
  69907. +/*!
  69908. + * Deinit the Encorder channels
  69909. + *
  69910. + */
  69911. +void __exit csi_enc_exit(void)
  69912. +{
  69913. +}
  69914. +
  69915. +module_init(csi_enc_init);
  69916. +module_exit(csi_enc_exit);
  69917. +
  69918. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  69919. +MODULE_DESCRIPTION("CSI ENC Driver");
  69920. +MODULE_LICENSE("GPL");
  69921. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c
  69922. --- linux-3.14.14/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c 1969-12-31 18:00:00.000000000 -0600
  69923. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c 2014-12-08 00:31:53.256418001 -0600
  69924. @@ -0,0 +1,634 @@
  69925. +/*
  69926. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  69927. + */
  69928. +/* * The code contained herein is licensed under the GNU General Public
  69929. + * License. You may obtain a copy of the GNU General Public License
  69930. + * Version 2 or later at the following locations:
  69931. + *
  69932. + * http://www.opensource.org/licenses/gpl-license.html
  69933. + * http://www.gnu.org/copyleft/gpl.html
  69934. + */
  69935. +
  69936. +/*!
  69937. + * @file ipu_foreground_sdc.c
  69938. + *
  69939. + * @brief IPU Use case for PRP-VF
  69940. + *
  69941. + * @ingroup IPU
  69942. + */
  69943. +
  69944. +#include <linux/module.h>
  69945. +#include <linux/dma-mapping.h>
  69946. +#include <linux/console.h>
  69947. +#include <linux/ipu.h>
  69948. +#include <linux/mxcfb.h>
  69949. +#include <linux/mipi_csi2.h>
  69950. +
  69951. +#include "mxc_v4l2_capture.h"
  69952. +#include "ipu_prp_sw.h"
  69953. +
  69954. +#ifdef CAMERA_DBG
  69955. + #define CAMERA_TRACE(x) (printk)x
  69956. +#else
  69957. + #define CAMERA_TRACE(x)
  69958. +#endif
  69959. +
  69960. +static int csi_buffer_num, buffer_num;
  69961. +static u32 csi_mem_bufsize;
  69962. +static struct ipu_soc *disp_ipu;
  69963. +static struct fb_info *fbi;
  69964. +static struct fb_var_screeninfo fbvar;
  69965. +static u32 vf_out_format;
  69966. +static void csi_buf_work_func(struct work_struct *work)
  69967. +{
  69968. + int err = 0;
  69969. + cam_data *cam =
  69970. + container_of(work, struct _cam_data, csi_work_struct);
  69971. +
  69972. + struct ipu_task task;
  69973. + memset(&task, 0, sizeof(task));
  69974. +
  69975. + if (csi_buffer_num)
  69976. + task.input.paddr = cam->vf_bufs[0];
  69977. + else
  69978. + task.input.paddr = cam->vf_bufs[1];
  69979. + task.input.width = cam->crop_current.width;
  69980. + task.input.height = cam->crop_current.height;
  69981. + task.input.format = IPU_PIX_FMT_NV12;
  69982. +
  69983. + if (buffer_num == 0)
  69984. + task.output.paddr = fbi->fix.smem_start +
  69985. + (fbi->fix.line_length * fbvar.yres);
  69986. + else
  69987. + task.output.paddr = fbi->fix.smem_start;
  69988. + task.output.width = cam->win.w.width;
  69989. + task.output.height = cam->win.w.height;
  69990. + task.output.format = vf_out_format;
  69991. + task.output.rotate = cam->rotation;
  69992. +again:
  69993. + err = ipu_check_task(&task);
  69994. + if (err != IPU_CHECK_OK) {
  69995. + if (err > IPU_CHECK_ERR_MIN) {
  69996. + if (err == IPU_CHECK_ERR_SPLIT_INPUTW_OVER) {
  69997. + task.input.crop.w -= 8;
  69998. + goto again;
  69999. + }
  70000. + if (err == IPU_CHECK_ERR_SPLIT_INPUTH_OVER) {
  70001. + task.input.crop.h -= 8;
  70002. + goto again;
  70003. + }
  70004. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
  70005. + task.output.width -= 8;
  70006. + task.output.crop.w = task.output.width;
  70007. + goto again;
  70008. + }
  70009. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
  70010. + task.output.height -= 8;
  70011. + task.output.crop.h = task.output.height;
  70012. + goto again;
  70013. + }
  70014. + printk(KERN_ERR "check ipu taks fail\n");
  70015. + return;
  70016. + }
  70017. + printk(KERN_ERR "check ipu taks fail\n");
  70018. + return;
  70019. + }
  70020. + err = ipu_queue_task(&task);
  70021. + if (err < 0)
  70022. + printk(KERN_ERR "queue ipu task error\n");
  70023. + ipu_select_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER, buffer_num);
  70024. + buffer_num = (buffer_num == 0) ? 1 : 0;
  70025. +}
  70026. +
  70027. +static void get_disp_ipu(cam_data *cam)
  70028. +{
  70029. + if (cam->output > 2)
  70030. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  70031. + else
  70032. + disp_ipu = ipu_get_soc(0);
  70033. +}
  70034. +
  70035. +/*!
  70036. + * csi ENC callback function.
  70037. + *
  70038. + * @param irq int irq line
  70039. + * @param dev_id void * device id
  70040. + *
  70041. + * @return status IRQ_HANDLED for handled
  70042. + */
  70043. +static irqreturn_t csi_enc_callback(int irq, void *dev_id)
  70044. +{
  70045. + cam_data *cam = (cam_data *) dev_id;
  70046. +
  70047. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, csi_buffer_num);
  70048. + if ((cam->crop_current.width != cam->win.w.width) ||
  70049. + (cam->crop_current.height != cam->win.w.height) ||
  70050. + (vf_out_format != IPU_PIX_FMT_NV12) ||
  70051. + (cam->rotation >= IPU_ROTATE_VERT_FLIP))
  70052. + schedule_work(&cam->csi_work_struct);
  70053. + csi_buffer_num = (csi_buffer_num == 0) ? 1 : 0;
  70054. + return IRQ_HANDLED;
  70055. +}
  70056. +
  70057. +static int csi_enc_setup(cam_data *cam)
  70058. +{
  70059. + ipu_channel_params_t params;
  70060. + int err = 0, sensor_protocol = 0;
  70061. +#ifdef CONFIG_MXC_MIPI_CSI2
  70062. + void *mipi_csi2_info;
  70063. + int ipu_id;
  70064. + int csi_id;
  70065. +#endif
  70066. +
  70067. + CAMERA_TRACE("In csi_enc_setup\n");
  70068. + if (!cam) {
  70069. + printk(KERN_ERR "cam private is NULL\n");
  70070. + return -ENXIO;
  70071. + }
  70072. +
  70073. + memset(&params, 0, sizeof(ipu_channel_params_t));
  70074. + params.csi_mem.csi = cam->csi;
  70075. +
  70076. + sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
  70077. + switch (sensor_protocol) {
  70078. + case IPU_CSI_CLK_MODE_GATED_CLK:
  70079. + case IPU_CSI_CLK_MODE_NONGATED_CLK:
  70080. + case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
  70081. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
  70082. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
  70083. + params.csi_mem.interlaced = false;
  70084. + break;
  70085. + case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
  70086. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
  70087. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
  70088. + params.csi_mem.interlaced = true;
  70089. + break;
  70090. + default:
  70091. + printk(KERN_ERR "sensor protocol unsupported\n");
  70092. + return -EINVAL;
  70093. + }
  70094. +
  70095. +#ifdef CONFIG_MXC_MIPI_CSI2
  70096. + mipi_csi2_info = mipi_csi2_get_info();
  70097. +
  70098. + if (mipi_csi2_info) {
  70099. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  70100. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  70101. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  70102. +
  70103. + if (cam->ipu == ipu_get_soc(ipu_id)
  70104. + && cam->csi == csi_id) {
  70105. + params.csi_mem.mipi_en = true;
  70106. + params.csi_mem.mipi_vc =
  70107. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  70108. + params.csi_mem.mipi_id =
  70109. + mipi_csi2_get_datatype(mipi_csi2_info);
  70110. +
  70111. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  70112. + } else {
  70113. + params.csi_mem.mipi_en = false;
  70114. + params.csi_mem.mipi_vc = 0;
  70115. + params.csi_mem.mipi_id = 0;
  70116. + }
  70117. + } else {
  70118. + params.csi_mem.mipi_en = false;
  70119. + params.csi_mem.mipi_vc = 0;
  70120. + params.csi_mem.mipi_id = 0;
  70121. + }
  70122. + }
  70123. +#endif
  70124. +
  70125. + if (cam->vf_bufs_vaddr[0]) {
  70126. + dma_free_coherent(0, cam->vf_bufs_size[0],
  70127. + cam->vf_bufs_vaddr[0],
  70128. + (dma_addr_t) cam->vf_bufs[0]);
  70129. + }
  70130. + if (cam->vf_bufs_vaddr[1]) {
  70131. + dma_free_coherent(0, cam->vf_bufs_size[1],
  70132. + cam->vf_bufs_vaddr[1],
  70133. + (dma_addr_t) cam->vf_bufs[1]);
  70134. + }
  70135. + csi_mem_bufsize = cam->crop_current.width *
  70136. + cam->crop_current.height * 3/2;
  70137. + cam->vf_bufs_size[0] = PAGE_ALIGN(csi_mem_bufsize);
  70138. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  70139. + cam->vf_bufs_size[0],
  70140. + (dma_addr_t *) &
  70141. + cam->vf_bufs[0],
  70142. + GFP_DMA |
  70143. + GFP_KERNEL);
  70144. + if (cam->vf_bufs_vaddr[0] == NULL) {
  70145. + printk(KERN_ERR "Error to allocate vf buffer\n");
  70146. + err = -ENOMEM;
  70147. + goto out_2;
  70148. + }
  70149. + cam->vf_bufs_size[1] = PAGE_ALIGN(csi_mem_bufsize);
  70150. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  70151. + cam->vf_bufs_size[1],
  70152. + (dma_addr_t *) &
  70153. + cam->vf_bufs[1],
  70154. + GFP_DMA |
  70155. + GFP_KERNEL);
  70156. + if (cam->vf_bufs_vaddr[1] == NULL) {
  70157. + printk(KERN_ERR "Error to allocate vf buffer\n");
  70158. + err = -ENOMEM;
  70159. + goto out_1;
  70160. + }
  70161. + pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
  70162. +
  70163. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  70164. + if (err != 0) {
  70165. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  70166. + goto out_1;
  70167. + }
  70168. +
  70169. + if ((cam->crop_current.width == cam->win.w.width) &&
  70170. + (cam->crop_current.height == cam->win.w.height) &&
  70171. + (vf_out_format == IPU_PIX_FMT_NV12) &&
  70172. + (cam->rotation < IPU_ROTATE_VERT_FLIP)) {
  70173. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM,
  70174. + IPU_OUTPUT_BUFFER,
  70175. + IPU_PIX_FMT_NV12,
  70176. + cam->crop_current.width,
  70177. + cam->crop_current.height,
  70178. + cam->crop_current.width, IPU_ROTATE_NONE,
  70179. + fbi->fix.smem_start +
  70180. + (fbi->fix.line_length * fbvar.yres),
  70181. + fbi->fix.smem_start, 0,
  70182. + cam->offset.u_offset, cam->offset.u_offset);
  70183. + } else {
  70184. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM,
  70185. + IPU_OUTPUT_BUFFER,
  70186. + IPU_PIX_FMT_NV12,
  70187. + cam->crop_current.width,
  70188. + cam->crop_current.height,
  70189. + cam->crop_current.width, IPU_ROTATE_NONE,
  70190. + cam->vf_bufs[0], cam->vf_bufs[1], 0,
  70191. + cam->offset.u_offset, cam->offset.u_offset);
  70192. + }
  70193. + if (err != 0) {
  70194. + printk(KERN_ERR "CSI_MEM output buffer\n");
  70195. + goto out_1;
  70196. + }
  70197. + err = ipu_enable_channel(cam->ipu, CSI_MEM);
  70198. + if (err < 0) {
  70199. + printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
  70200. + goto out_1;
  70201. + }
  70202. +
  70203. + csi_buffer_num = 0;
  70204. +
  70205. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 0);
  70206. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 1);
  70207. + return err;
  70208. +out_1:
  70209. + if (cam->vf_bufs_vaddr[0]) {
  70210. + dma_free_coherent(0, cam->vf_bufs_size[0],
  70211. + cam->vf_bufs_vaddr[0],
  70212. + (dma_addr_t) cam->vf_bufs[0]);
  70213. + cam->vf_bufs_vaddr[0] = NULL;
  70214. + cam->vf_bufs[0] = 0;
  70215. + }
  70216. + if (cam->vf_bufs_vaddr[1]) {
  70217. + dma_free_coherent(0, cam->vf_bufs_size[1],
  70218. + cam->vf_bufs_vaddr[1],
  70219. + (dma_addr_t) cam->vf_bufs[1]);
  70220. + cam->vf_bufs_vaddr[1] = NULL;
  70221. + cam->vf_bufs[1] = 0;
  70222. + }
  70223. +out_2:
  70224. + return err;
  70225. +}
  70226. +
  70227. +/*!
  70228. + * Enable encoder task
  70229. + * @param private struct cam_data * mxc capture instance
  70230. + *
  70231. + * @return status
  70232. + */
  70233. +static int csi_enc_enabling_tasks(void *private)
  70234. +{
  70235. + cam_data *cam = (cam_data *) private;
  70236. + int err = 0;
  70237. + CAMERA_TRACE("IPU:In csi_enc_enabling_tasks\n");
  70238. +
  70239. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  70240. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  70241. + csi_enc_callback, 0, "Mxc Camera", cam);
  70242. + if (err != 0) {
  70243. + printk(KERN_ERR "Error registering CSI0_OUT_EOF irq\n");
  70244. + return err;
  70245. + }
  70246. +
  70247. + INIT_WORK(&cam->csi_work_struct, csi_buf_work_func);
  70248. +
  70249. + err = csi_enc_setup(cam);
  70250. + if (err != 0) {
  70251. + printk(KERN_ERR "csi_enc_setup %d\n", err);
  70252. + goto out1;
  70253. + }
  70254. +
  70255. + return err;
  70256. +out1:
  70257. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  70258. + return err;
  70259. +}
  70260. +
  70261. +/*
  70262. + * Function definitions
  70263. + */
  70264. +
  70265. +/*!
  70266. + * foreground_start - start the vf task
  70267. + *
  70268. + * @param private cam_data * mxc v4l2 main structure
  70269. + *
  70270. + */
  70271. +static int foreground_start(void *private)
  70272. +{
  70273. + cam_data *cam = (cam_data *) private;
  70274. + int err = 0, i = 0, screen_size;
  70275. + char *base;
  70276. +
  70277. + if (!cam) {
  70278. + printk(KERN_ERR "private is NULL\n");
  70279. + return -EIO;
  70280. + }
  70281. +
  70282. + if (cam->overlay_active == true) {
  70283. + pr_debug("already started.\n");
  70284. + return 0;
  70285. + }
  70286. +
  70287. + get_disp_ipu(cam);
  70288. +
  70289. + for (i = 0; i < num_registered_fb; i++) {
  70290. + char *idstr = registered_fb[i]->fix.id;
  70291. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  70292. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  70293. + fbi = registered_fb[i];
  70294. + break;
  70295. + }
  70296. + }
  70297. +
  70298. + if (fbi == NULL) {
  70299. + printk(KERN_ERR "DISP FG fb not found\n");
  70300. + return -EPERM;
  70301. + }
  70302. +
  70303. + fbvar = fbi->var;
  70304. +
  70305. + /* Store the overlay frame buffer's original std */
  70306. + cam->fb_origin_std = fbvar.nonstd;
  70307. +
  70308. + if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
  70309. + /* Use DP to do CSC so that we can get better performance */
  70310. + vf_out_format = IPU_PIX_FMT_NV12;
  70311. + fbvar.nonstd = vf_out_format;
  70312. + } else {
  70313. + vf_out_format = IPU_PIX_FMT_RGB565;
  70314. + fbvar.nonstd = 0;
  70315. + }
  70316. +
  70317. + fbvar.bits_per_pixel = 16;
  70318. + fbvar.xres = fbvar.xres_virtual = cam->win.w.width;
  70319. + fbvar.yres = cam->win.w.height;
  70320. + fbvar.yres_virtual = cam->win.w.height * 2;
  70321. + fbvar.yoffset = 0;
  70322. + fbvar.vmode &= ~FB_VMODE_YWRAP;
  70323. + fbvar.accel_flags = FB_ACCEL_DOUBLE_FLAG;
  70324. + fbvar.activate |= FB_ACTIVATE_FORCE;
  70325. + fb_set_var(fbi, &fbvar);
  70326. +
  70327. + ipu_disp_set_window_pos(disp_ipu, MEM_FG_SYNC, cam->win.w.left,
  70328. + cam->win.w.top);
  70329. +
  70330. + /* Fill black color for framebuffer */
  70331. + base = (char *) fbi->screen_base;
  70332. + screen_size = fbi->var.xres * fbi->var.yres;
  70333. + if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
  70334. + memset(base, 0, screen_size);
  70335. + base += screen_size;
  70336. + for (i = 0; i < screen_size / 2; i++, base++)
  70337. + *base = 0x80;
  70338. + } else {
  70339. + for (i = 0; i < screen_size * 2; i++, base++)
  70340. + *base = 0x00;
  70341. + }
  70342. +
  70343. + console_lock();
  70344. + fb_blank(fbi, FB_BLANK_UNBLANK);
  70345. + console_unlock();
  70346. +
  70347. + /* correct display ch buffer address */
  70348. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  70349. + 0, fbi->fix.smem_start +
  70350. + (fbi->fix.line_length * fbvar.yres));
  70351. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  70352. + 1, fbi->fix.smem_start);
  70353. +
  70354. + err = csi_enc_enabling_tasks(cam);
  70355. + if (err != 0) {
  70356. + printk(KERN_ERR "Error csi enc enable fail\n");
  70357. + return err;
  70358. + }
  70359. +
  70360. + cam->overlay_active = true;
  70361. + return err;
  70362. +
  70363. +}
  70364. +
  70365. +/*!
  70366. + * foreground_stop - stop the vf task
  70367. + *
  70368. + * @param private cam_data * mxc v4l2 main structure
  70369. + *
  70370. + */
  70371. +static int foreground_stop(void *private)
  70372. +{
  70373. + cam_data *cam = (cam_data *) private;
  70374. + int err = 0, i = 0;
  70375. + struct fb_info *fbi = NULL;
  70376. + struct fb_var_screeninfo fbvar;
  70377. +
  70378. +#ifdef CONFIG_MXC_MIPI_CSI2
  70379. + void *mipi_csi2_info;
  70380. + int ipu_id;
  70381. + int csi_id;
  70382. +#endif
  70383. +
  70384. + if (cam->overlay_active == false)
  70385. + return 0;
  70386. +
  70387. + err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
  70388. +
  70389. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  70390. +
  70391. + csi_buffer_num = 0;
  70392. + buffer_num = 0;
  70393. +
  70394. + for (i = 0; i < num_registered_fb; i++) {
  70395. + char *idstr = registered_fb[i]->fix.id;
  70396. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  70397. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  70398. + fbi = registered_fb[i];
  70399. + break;
  70400. + }
  70401. + }
  70402. +
  70403. + if (fbi == NULL) {
  70404. + printk(KERN_ERR "DISP FG fb not found\n");
  70405. + return -EPERM;
  70406. + }
  70407. +
  70408. + console_lock();
  70409. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  70410. + console_unlock();
  70411. +
  70412. + /* Set the overlay frame buffer std to what it is used to be */
  70413. + fbvar = fbi->var;
  70414. + fbvar.accel_flags = FB_ACCEL_TRIPLE_FLAG;
  70415. + fbvar.nonstd = cam->fb_origin_std;
  70416. + fbvar.activate |= FB_ACTIVATE_FORCE;
  70417. + fb_set_var(fbi, &fbvar);
  70418. +
  70419. +#ifdef CONFIG_MXC_MIPI_CSI2
  70420. + mipi_csi2_info = mipi_csi2_get_info();
  70421. +
  70422. + if (mipi_csi2_info) {
  70423. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  70424. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  70425. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  70426. +
  70427. + if (cam->ipu == ipu_get_soc(ipu_id)
  70428. + && cam->csi == csi_id)
  70429. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  70430. + }
  70431. + }
  70432. +#endif
  70433. +
  70434. + flush_work(&cam->csi_work_struct);
  70435. + cancel_work_sync(&cam->csi_work_struct);
  70436. +
  70437. + if (cam->vf_bufs_vaddr[0]) {
  70438. + dma_free_coherent(0, cam->vf_bufs_size[0],
  70439. + cam->vf_bufs_vaddr[0],
  70440. + (dma_addr_t) cam->vf_bufs[0]);
  70441. + cam->vf_bufs_vaddr[0] = NULL;
  70442. + cam->vf_bufs[0] = 0;
  70443. + }
  70444. + if (cam->vf_bufs_vaddr[1]) {
  70445. + dma_free_coherent(0, cam->vf_bufs_size[1],
  70446. + cam->vf_bufs_vaddr[1],
  70447. + (dma_addr_t) cam->vf_bufs[1]);
  70448. + cam->vf_bufs_vaddr[1] = NULL;
  70449. + cam->vf_bufs[1] = 0;
  70450. + }
  70451. +
  70452. + cam->overlay_active = false;
  70453. + return err;
  70454. +}
  70455. +
  70456. +/*!
  70457. + * Enable csi
  70458. + * @param private struct cam_data * mxc capture instance
  70459. + *
  70460. + * @return status
  70461. + */
  70462. +static int foreground_enable_csi(void *private)
  70463. +{
  70464. + cam_data *cam = (cam_data *) private;
  70465. +
  70466. + return ipu_enable_csi(cam->ipu, cam->csi);
  70467. +}
  70468. +
  70469. +/*!
  70470. + * Disable csi
  70471. + * @param private struct cam_data * mxc capture instance
  70472. + *
  70473. + * @return status
  70474. + */
  70475. +static int foreground_disable_csi(void *private)
  70476. +{
  70477. + cam_data *cam = (cam_data *) private;
  70478. +
  70479. + /* free csi eof irq firstly.
  70480. + * when disable csi, wait for idmac eof.
  70481. + * it requests eof irq again */
  70482. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  70483. +
  70484. + return ipu_disable_csi(cam->ipu, cam->csi);
  70485. +}
  70486. +
  70487. +/*!
  70488. + * function to select foreground as the working path
  70489. + *
  70490. + * @param private cam_data * mxc v4l2 main structure
  70491. + *
  70492. + * @return status
  70493. + */
  70494. +int foreground_sdc_select(void *private)
  70495. +{
  70496. + cam_data *cam;
  70497. + int err = 0;
  70498. + if (private) {
  70499. + cam = (cam_data *) private;
  70500. + cam->vf_start_sdc = foreground_start;
  70501. + cam->vf_stop_sdc = foreground_stop;
  70502. + cam->vf_enable_csi = foreground_enable_csi;
  70503. + cam->vf_disable_csi = foreground_disable_csi;
  70504. + cam->overlay_active = false;
  70505. + } else
  70506. + err = -EIO;
  70507. +
  70508. + return err;
  70509. +}
  70510. +EXPORT_SYMBOL(foreground_sdc_select);
  70511. +
  70512. +/*!
  70513. + * function to de-select foreground as the working path
  70514. + *
  70515. + * @param private cam_data * mxc v4l2 main structure
  70516. + *
  70517. + * @return int
  70518. + */
  70519. +int foreground_sdc_deselect(void *private)
  70520. +{
  70521. + cam_data *cam;
  70522. +
  70523. + if (private) {
  70524. + cam = (cam_data *) private;
  70525. + cam->vf_start_sdc = NULL;
  70526. + cam->vf_stop_sdc = NULL;
  70527. + cam->vf_enable_csi = NULL;
  70528. + cam->vf_disable_csi = NULL;
  70529. + }
  70530. + return 0;
  70531. +}
  70532. +EXPORT_SYMBOL(foreground_sdc_deselect);
  70533. +
  70534. +/*!
  70535. + * Init viewfinder task.
  70536. + *
  70537. + * @return Error code indicating success or failure
  70538. + */
  70539. +__init int foreground_sdc_init(void)
  70540. +{
  70541. + return 0;
  70542. +}
  70543. +
  70544. +/*!
  70545. + * Deinit viewfinder task.
  70546. + *
  70547. + * @return Error code indicating success or failure
  70548. + */
  70549. +void __exit foreground_sdc_exit(void)
  70550. +{
  70551. +}
  70552. +
  70553. +module_init(foreground_sdc_init);
  70554. +module_exit(foreground_sdc_exit);
  70555. +
  70556. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  70557. +MODULE_DESCRIPTION("IPU PRP VF SDC Driver");
  70558. +MODULE_LICENSE("GPL");
  70559. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/ipu_prp_enc.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_enc.c
  70560. --- linux-3.14.14/drivers/media/platform/mxc/capture/ipu_prp_enc.c 1969-12-31 18:00:00.000000000 -0600
  70561. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_enc.c 2014-12-08 00:31:53.256418001 -0600
  70562. @@ -0,0 +1,595 @@
  70563. +/*
  70564. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  70565. + */
  70566. +
  70567. +/*
  70568. + * The code contained herein is licensed under the GNU General Public
  70569. + * License. You may obtain a copy of the GNU General Public License
  70570. + * Version 2 or later at the following locations:
  70571. + *
  70572. + * http://www.opensource.org/licenses/gpl-license.html
  70573. + * http://www.gnu.org/copyleft/gpl.html
  70574. + */
  70575. +
  70576. +/*!
  70577. + * @file ipu_prp_enc.c
  70578. + *
  70579. + * @brief IPU Use case for PRP-ENC
  70580. + *
  70581. + * @ingroup IPU
  70582. + */
  70583. +
  70584. +#include <linux/module.h>
  70585. +#include <linux/dma-mapping.h>
  70586. +#include <linux/platform_device.h>
  70587. +#include <linux/ipu.h>
  70588. +#include <linux/mipi_csi2.h>
  70589. +#include "mxc_v4l2_capture.h"
  70590. +#include "ipu_prp_sw.h"
  70591. +
  70592. +#ifdef CAMERA_DBG
  70593. + #define CAMERA_TRACE(x) (printk)x
  70594. +#else
  70595. + #define CAMERA_TRACE(x)
  70596. +#endif
  70597. +
  70598. +static ipu_rotate_mode_t grotation = IPU_ROTATE_NONE;
  70599. +
  70600. +/*
  70601. + * Function definitions
  70602. + */
  70603. +
  70604. +/*!
  70605. + * IPU ENC callback function.
  70606. + *
  70607. + * @param irq int irq line
  70608. + * @param dev_id void * device id
  70609. + *
  70610. + * @return status IRQ_HANDLED for handled
  70611. + */
  70612. +static irqreturn_t prp_enc_callback(int irq, void *dev_id)
  70613. +{
  70614. + cam_data *cam = (cam_data *) dev_id;
  70615. +
  70616. + if (cam->enc_callback == NULL)
  70617. + return IRQ_HANDLED;
  70618. +
  70619. + cam->enc_callback(irq, dev_id);
  70620. +
  70621. + return IRQ_HANDLED;
  70622. +}
  70623. +
  70624. +/*!
  70625. + * PrpENC enable channel setup function
  70626. + *
  70627. + * @param cam struct cam_data * mxc capture instance
  70628. + *
  70629. + * @return status
  70630. + */
  70631. +static int prp_enc_setup(cam_data *cam)
  70632. +{
  70633. + ipu_channel_params_t enc;
  70634. + int err = 0;
  70635. + dma_addr_t dummy = cam->dummy_frame.buffer.m.offset;
  70636. +#ifdef CONFIG_MXC_MIPI_CSI2
  70637. + void *mipi_csi2_info;
  70638. + int ipu_id;
  70639. + int csi_id;
  70640. +#endif
  70641. +
  70642. + CAMERA_TRACE("In prp_enc_setup\n");
  70643. + if (!cam) {
  70644. + printk(KERN_ERR "cam private is NULL\n");
  70645. + return -ENXIO;
  70646. + }
  70647. + memset(&enc, 0, sizeof(ipu_channel_params_t));
  70648. +
  70649. + ipu_csi_get_window_size(cam->ipu, &enc.csi_prp_enc_mem.in_width,
  70650. + &enc.csi_prp_enc_mem.in_height, cam->csi);
  70651. +
  70652. + enc.csi_prp_enc_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
  70653. + enc.csi_prp_enc_mem.out_width = cam->v2f.fmt.pix.width;
  70654. + enc.csi_prp_enc_mem.out_height = cam->v2f.fmt.pix.height;
  70655. + enc.csi_prp_enc_mem.csi = cam->csi;
  70656. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  70657. + enc.csi_prp_enc_mem.out_width = cam->v2f.fmt.pix.height;
  70658. + enc.csi_prp_enc_mem.out_height = cam->v2f.fmt.pix.width;
  70659. + }
  70660. +
  70661. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
  70662. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUV420P;
  70663. + pr_info("YUV420\n");
  70664. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) {
  70665. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YVU420P;
  70666. + pr_info("YVU420\n");
  70667. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) {
  70668. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUV422P;
  70669. + pr_info("YUV422P\n");
  70670. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
  70671. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUYV;
  70672. + pr_info("YUYV\n");
  70673. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) {
  70674. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_UYVY;
  70675. + pr_info("UYVY\n");
  70676. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12) {
  70677. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_NV12;
  70678. + pr_info("NV12\n");
  70679. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) {
  70680. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_BGR24;
  70681. + pr_info("BGR24\n");
  70682. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
  70683. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB24;
  70684. + pr_info("RGB24\n");
  70685. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
  70686. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB565;
  70687. + pr_info("RGB565\n");
  70688. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32) {
  70689. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_BGR32;
  70690. + pr_info("BGR32\n");
  70691. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32) {
  70692. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB32;
  70693. + pr_info("RGB32\n");
  70694. + } else {
  70695. + printk(KERN_ERR "format not supported\n");
  70696. + return -EINVAL;
  70697. + }
  70698. +
  70699. +#ifdef CONFIG_MXC_MIPI_CSI2
  70700. + mipi_csi2_info = mipi_csi2_get_info();
  70701. +
  70702. + if (mipi_csi2_info) {
  70703. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  70704. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  70705. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  70706. +
  70707. + if (cam->ipu == ipu_get_soc(ipu_id)
  70708. + && cam->csi == csi_id) {
  70709. + enc.csi_prp_enc_mem.mipi_en = true;
  70710. + enc.csi_prp_enc_mem.mipi_vc =
  70711. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  70712. + enc.csi_prp_enc_mem.mipi_id =
  70713. + mipi_csi2_get_datatype(mipi_csi2_info);
  70714. +
  70715. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  70716. + } else {
  70717. + enc.csi_prp_enc_mem.mipi_en = false;
  70718. + enc.csi_prp_enc_mem.mipi_vc = 0;
  70719. + enc.csi_prp_enc_mem.mipi_id = 0;
  70720. + }
  70721. + } else {
  70722. + enc.csi_prp_enc_mem.mipi_en = false;
  70723. + enc.csi_prp_enc_mem.mipi_vc = 0;
  70724. + enc.csi_prp_enc_mem.mipi_id = 0;
  70725. + }
  70726. + }
  70727. +#endif
  70728. +
  70729. + err = ipu_init_channel(cam->ipu, CSI_PRP_ENC_MEM, &enc);
  70730. + if (err != 0) {
  70731. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  70732. + return err;
  70733. + }
  70734. +
  70735. + grotation = cam->rotation;
  70736. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  70737. + if (cam->rot_enc_bufs_vaddr[0]) {
  70738. + dma_free_coherent(0, cam->rot_enc_buf_size[0],
  70739. + cam->rot_enc_bufs_vaddr[0],
  70740. + cam->rot_enc_bufs[0]);
  70741. + }
  70742. + if (cam->rot_enc_bufs_vaddr[1]) {
  70743. + dma_free_coherent(0, cam->rot_enc_buf_size[1],
  70744. + cam->rot_enc_bufs_vaddr[1],
  70745. + cam->rot_enc_bufs[1]);
  70746. + }
  70747. + cam->rot_enc_buf_size[0] =
  70748. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  70749. + cam->rot_enc_bufs_vaddr[0] =
  70750. + (void *)dma_alloc_coherent(0, cam->rot_enc_buf_size[0],
  70751. + &cam->rot_enc_bufs[0],
  70752. + GFP_DMA | GFP_KERNEL);
  70753. + if (!cam->rot_enc_bufs_vaddr[0]) {
  70754. + printk(KERN_ERR "alloc enc_bufs0\n");
  70755. + return -ENOMEM;
  70756. + }
  70757. + cam->rot_enc_buf_size[1] =
  70758. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  70759. + cam->rot_enc_bufs_vaddr[1] =
  70760. + (void *)dma_alloc_coherent(0, cam->rot_enc_buf_size[1],
  70761. + &cam->rot_enc_bufs[1],
  70762. + GFP_DMA | GFP_KERNEL);
  70763. + if (!cam->rot_enc_bufs_vaddr[1]) {
  70764. + dma_free_coherent(0, cam->rot_enc_buf_size[0],
  70765. + cam->rot_enc_bufs_vaddr[0],
  70766. + cam->rot_enc_bufs[0]);
  70767. + cam->rot_enc_bufs_vaddr[0] = NULL;
  70768. + cam->rot_enc_bufs[0] = 0;
  70769. + printk(KERN_ERR "alloc enc_bufs1\n");
  70770. + return -ENOMEM;
  70771. + }
  70772. +
  70773. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  70774. + IPU_OUTPUT_BUFFER,
  70775. + enc.csi_prp_enc_mem.out_pixel_fmt,
  70776. + enc.csi_prp_enc_mem.out_width,
  70777. + enc.csi_prp_enc_mem.out_height,
  70778. + enc.csi_prp_enc_mem.out_width,
  70779. + IPU_ROTATE_NONE,
  70780. + cam->rot_enc_bufs[0],
  70781. + cam->rot_enc_bufs[1], 0, 0, 0);
  70782. + if (err != 0) {
  70783. + printk(KERN_ERR "CSI_PRP_ENC_MEM err\n");
  70784. + return err;
  70785. + }
  70786. +
  70787. + err = ipu_init_channel(cam->ipu, MEM_ROT_ENC_MEM, NULL);
  70788. + if (err != 0) {
  70789. + printk(KERN_ERR "MEM_ROT_ENC_MEM channel err\n");
  70790. + return err;
  70791. + }
  70792. +
  70793. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_ENC_MEM,
  70794. + IPU_INPUT_BUFFER,
  70795. + enc.csi_prp_enc_mem.out_pixel_fmt,
  70796. + enc.csi_prp_enc_mem.out_width,
  70797. + enc.csi_prp_enc_mem.out_height,
  70798. + enc.csi_prp_enc_mem.out_width,
  70799. + cam->rotation,
  70800. + cam->rot_enc_bufs[0],
  70801. + cam->rot_enc_bufs[1], 0, 0, 0);
  70802. + if (err != 0) {
  70803. + printk(KERN_ERR "MEM_ROT_ENC_MEM input buffer\n");
  70804. + return err;
  70805. + }
  70806. +
  70807. + err =
  70808. + ipu_init_channel_buffer(cam->ipu, MEM_ROT_ENC_MEM,
  70809. + IPU_OUTPUT_BUFFER,
  70810. + enc.csi_prp_enc_mem.out_pixel_fmt,
  70811. + enc.csi_prp_enc_mem.out_height,
  70812. + enc.csi_prp_enc_mem.out_width,
  70813. + cam->v2f.fmt.pix.bytesperline /
  70814. + bytes_per_pixel(enc.csi_prp_enc_mem.
  70815. + out_pixel_fmt),
  70816. + IPU_ROTATE_NONE,
  70817. + dummy, dummy, 0,
  70818. + cam->offset.u_offset,
  70819. + cam->offset.v_offset);
  70820. + if (err != 0) {
  70821. + printk(KERN_ERR "MEM_ROT_ENC_MEM output buffer\n");
  70822. + return err;
  70823. + }
  70824. +
  70825. + err = ipu_link_channels(cam->ipu,
  70826. + CSI_PRP_ENC_MEM, MEM_ROT_ENC_MEM);
  70827. + if (err < 0) {
  70828. + printk(KERN_ERR
  70829. + "link CSI_PRP_ENC_MEM-MEM_ROT_ENC_MEM\n");
  70830. + return err;
  70831. + }
  70832. +
  70833. + err = ipu_enable_channel(cam->ipu, CSI_PRP_ENC_MEM);
  70834. + if (err < 0) {
  70835. + printk(KERN_ERR "ipu_enable_channel CSI_PRP_ENC_MEM\n");
  70836. + return err;
  70837. + }
  70838. + err = ipu_enable_channel(cam->ipu, MEM_ROT_ENC_MEM);
  70839. + if (err < 0) {
  70840. + printk(KERN_ERR "ipu_enable_channel MEM_ROT_ENC_MEM\n");
  70841. + return err;
  70842. + }
  70843. +
  70844. + ipu_select_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  70845. + IPU_OUTPUT_BUFFER, 0);
  70846. + ipu_select_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  70847. + IPU_OUTPUT_BUFFER, 1);
  70848. + } else {
  70849. + err =
  70850. + ipu_init_channel_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  70851. + IPU_OUTPUT_BUFFER,
  70852. + enc.csi_prp_enc_mem.out_pixel_fmt,
  70853. + enc.csi_prp_enc_mem.out_width,
  70854. + enc.csi_prp_enc_mem.out_height,
  70855. + cam->v2f.fmt.pix.bytesperline /
  70856. + bytes_per_pixel(enc.csi_prp_enc_mem.
  70857. + out_pixel_fmt),
  70858. + cam->rotation,
  70859. + dummy, dummy, 0,
  70860. + cam->offset.u_offset,
  70861. + cam->offset.v_offset);
  70862. + if (err != 0) {
  70863. + printk(KERN_ERR "CSI_PRP_ENC_MEM output buffer\n");
  70864. + return err;
  70865. + }
  70866. + err = ipu_enable_channel(cam->ipu, CSI_PRP_ENC_MEM);
  70867. + if (err < 0) {
  70868. + printk(KERN_ERR "ipu_enable_channel CSI_PRP_ENC_MEM\n");
  70869. + return err;
  70870. + }
  70871. + }
  70872. +
  70873. + return err;
  70874. +}
  70875. +
  70876. +/*!
  70877. + * function to update physical buffer address for encorder IDMA channel
  70878. + *
  70879. + * @param eba physical buffer address for encorder IDMA channel
  70880. + * @param buffer_num int buffer 0 or buffer 1
  70881. + *
  70882. + * @return status
  70883. + */
  70884. +static int prp_enc_eba_update(struct ipu_soc *ipu, dma_addr_t eba,
  70885. + int *buffer_num)
  70886. +{
  70887. + int err = 0;
  70888. +
  70889. + pr_debug("eba %x\n", eba);
  70890. + if (grotation >= IPU_ROTATE_90_RIGHT) {
  70891. + err = ipu_update_channel_buffer(ipu, MEM_ROT_ENC_MEM,
  70892. + IPU_OUTPUT_BUFFER, *buffer_num,
  70893. + eba);
  70894. + } else {
  70895. + err = ipu_update_channel_buffer(ipu, CSI_PRP_ENC_MEM,
  70896. + IPU_OUTPUT_BUFFER, *buffer_num,
  70897. + eba);
  70898. + }
  70899. + if (err != 0) {
  70900. + if (grotation >= IPU_ROTATE_90_RIGHT) {
  70901. + ipu_clear_buffer_ready(ipu, MEM_ROT_ENC_MEM,
  70902. + IPU_OUTPUT_BUFFER,
  70903. + *buffer_num);
  70904. + err = ipu_update_channel_buffer(ipu, MEM_ROT_ENC_MEM,
  70905. + IPU_OUTPUT_BUFFER,
  70906. + *buffer_num,
  70907. + eba);
  70908. + } else {
  70909. + ipu_clear_buffer_ready(ipu, CSI_PRP_ENC_MEM,
  70910. + IPU_OUTPUT_BUFFER,
  70911. + *buffer_num);
  70912. + err = ipu_update_channel_buffer(ipu, CSI_PRP_ENC_MEM,
  70913. + IPU_OUTPUT_BUFFER,
  70914. + *buffer_num,
  70915. + eba);
  70916. + }
  70917. +
  70918. + if (err != 0) {
  70919. + pr_err("ERROR: v4l2 capture: fail to update "
  70920. + "buf%d\n", *buffer_num);
  70921. + return err;
  70922. + }
  70923. + }
  70924. +
  70925. + if (grotation >= IPU_ROTATE_90_RIGHT) {
  70926. + ipu_select_buffer(ipu, MEM_ROT_ENC_MEM, IPU_OUTPUT_BUFFER,
  70927. + *buffer_num);
  70928. + } else {
  70929. + ipu_select_buffer(ipu, CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER,
  70930. + *buffer_num);
  70931. + }
  70932. +
  70933. + *buffer_num = (*buffer_num == 0) ? 1 : 0;
  70934. + return 0;
  70935. +}
  70936. +
  70937. +/*!
  70938. + * Enable encoder task
  70939. + * @param private struct cam_data * mxc capture instance
  70940. + *
  70941. + * @return status
  70942. + */
  70943. +static int prp_enc_enabling_tasks(void *private)
  70944. +{
  70945. + cam_data *cam = (cam_data *) private;
  70946. + int err = 0;
  70947. + CAMERA_TRACE("IPU:In prp_enc_enabling_tasks\n");
  70948. +
  70949. + cam->dummy_frame.vaddress = dma_alloc_coherent(0,
  70950. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  70951. + &cam->dummy_frame.paddress,
  70952. + GFP_DMA | GFP_KERNEL);
  70953. + if (cam->dummy_frame.vaddress == 0) {
  70954. + pr_err("ERROR: v4l2 capture: Allocate dummy frame "
  70955. + "failed.\n");
  70956. + return -ENOBUFS;
  70957. + }
  70958. + cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
  70959. + cam->dummy_frame.buffer.length =
  70960. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  70961. + cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
  70962. +
  70963. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  70964. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_ENC_ROT_OUT_EOF,
  70965. + prp_enc_callback, 0, "Mxc Camera", cam);
  70966. + } else {
  70967. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_ENC_OUT_EOF,
  70968. + prp_enc_callback, 0, "Mxc Camera", cam);
  70969. + }
  70970. + if (err != 0) {
  70971. + printk(KERN_ERR "Error registering rot irq\n");
  70972. + return err;
  70973. + }
  70974. +
  70975. + err = prp_enc_setup(cam);
  70976. + if (err != 0) {
  70977. + printk(KERN_ERR "prp_enc_setup %d\n", err);
  70978. + return err;
  70979. + }
  70980. +
  70981. + return err;
  70982. +}
  70983. +
  70984. +/*!
  70985. + * Disable encoder task
  70986. + * @param private struct cam_data * mxc capture instance
  70987. + *
  70988. + * @return int
  70989. + */
  70990. +static int prp_enc_disabling_tasks(void *private)
  70991. +{
  70992. + cam_data *cam = (cam_data *) private;
  70993. + int err = 0;
  70994. +#ifdef CONFIG_MXC_MIPI_CSI2
  70995. + void *mipi_csi2_info;
  70996. + int ipu_id;
  70997. + int csi_id;
  70998. +#endif
  70999. +
  71000. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  71001. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_ENC_ROT_OUT_EOF, cam);
  71002. + ipu_unlink_channels(cam->ipu, CSI_PRP_ENC_MEM, MEM_ROT_ENC_MEM);
  71003. + }
  71004. +
  71005. + err = ipu_disable_channel(cam->ipu, CSI_PRP_ENC_MEM, true);
  71006. + if (cam->rotation >= IPU_ROTATE_90_RIGHT)
  71007. + err |= ipu_disable_channel(cam->ipu, MEM_ROT_ENC_MEM, true);
  71008. +
  71009. + ipu_uninit_channel(cam->ipu, CSI_PRP_ENC_MEM);
  71010. + if (cam->rotation >= IPU_ROTATE_90_RIGHT)
  71011. + ipu_uninit_channel(cam->ipu, MEM_ROT_ENC_MEM);
  71012. +
  71013. + if (cam->dummy_frame.vaddress != 0) {
  71014. + dma_free_coherent(0, cam->dummy_frame.buffer.length,
  71015. + cam->dummy_frame.vaddress,
  71016. + cam->dummy_frame.paddress);
  71017. + cam->dummy_frame.vaddress = 0;
  71018. + }
  71019. +
  71020. +#ifdef CONFIG_MXC_MIPI_CSI2
  71021. + mipi_csi2_info = mipi_csi2_get_info();
  71022. +
  71023. + if (mipi_csi2_info) {
  71024. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  71025. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  71026. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  71027. +
  71028. + if (cam->ipu == ipu_get_soc(ipu_id)
  71029. + && cam->csi == csi_id)
  71030. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  71031. + }
  71032. + }
  71033. +#endif
  71034. +
  71035. + return err;
  71036. +}
  71037. +
  71038. +/*!
  71039. + * Enable csi
  71040. + * @param private struct cam_data * mxc capture instance
  71041. + *
  71042. + * @return status
  71043. + */
  71044. +static int prp_enc_enable_csi(void *private)
  71045. +{
  71046. + cam_data *cam = (cam_data *) private;
  71047. +
  71048. + return ipu_enable_csi(cam->ipu, cam->csi);
  71049. +}
  71050. +
  71051. +/*!
  71052. + * Disable csi
  71053. + * @param private struct cam_data * mxc capture instance
  71054. + *
  71055. + * @return status
  71056. + */
  71057. +static int prp_enc_disable_csi(void *private)
  71058. +{
  71059. + cam_data *cam = (cam_data *) private;
  71060. +
  71061. + /* free csi eof irq firstly.
  71062. + * when disable csi, wait for idmac eof.
  71063. + * it requests eof irq again */
  71064. + if (cam->rotation < IPU_ROTATE_90_RIGHT)
  71065. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_ENC_OUT_EOF, cam);
  71066. +
  71067. + return ipu_disable_csi(cam->ipu, cam->csi);
  71068. +}
  71069. +
  71070. +/*!
  71071. + * function to select PRP-ENC as the working path
  71072. + *
  71073. + * @param private struct cam_data * mxc capture instance
  71074. + *
  71075. + * @return int
  71076. + */
  71077. +int prp_enc_select(void *private)
  71078. +{
  71079. + cam_data *cam = (cam_data *) private;
  71080. + int err = 0;
  71081. +
  71082. + if (cam) {
  71083. + cam->enc_update_eba = prp_enc_eba_update;
  71084. + cam->enc_enable = prp_enc_enabling_tasks;
  71085. + cam->enc_disable = prp_enc_disabling_tasks;
  71086. + cam->enc_enable_csi = prp_enc_enable_csi;
  71087. + cam->enc_disable_csi = prp_enc_disable_csi;
  71088. + } else {
  71089. + err = -EIO;
  71090. + }
  71091. +
  71092. + return err;
  71093. +}
  71094. +EXPORT_SYMBOL(prp_enc_select);
  71095. +
  71096. +/*!
  71097. + * function to de-select PRP-ENC as the working path
  71098. + *
  71099. + * @param private struct cam_data * mxc capture instance
  71100. + *
  71101. + * @return int
  71102. + */
  71103. +int prp_enc_deselect(void *private)
  71104. +{
  71105. + cam_data *cam = (cam_data *) private;
  71106. + int err = 0;
  71107. +
  71108. + if (cam) {
  71109. + cam->enc_update_eba = NULL;
  71110. + cam->enc_enable = NULL;
  71111. + cam->enc_disable = NULL;
  71112. + cam->enc_enable_csi = NULL;
  71113. + cam->enc_disable_csi = NULL;
  71114. + if (cam->rot_enc_bufs_vaddr[0]) {
  71115. + dma_free_coherent(0, cam->rot_enc_buf_size[0],
  71116. + cam->rot_enc_bufs_vaddr[0],
  71117. + cam->rot_enc_bufs[0]);
  71118. + cam->rot_enc_bufs_vaddr[0] = NULL;
  71119. + cam->rot_enc_bufs[0] = 0;
  71120. + }
  71121. + if (cam->rot_enc_bufs_vaddr[1]) {
  71122. + dma_free_coherent(0, cam->rot_enc_buf_size[1],
  71123. + cam->rot_enc_bufs_vaddr[1],
  71124. + cam->rot_enc_bufs[1]);
  71125. + cam->rot_enc_bufs_vaddr[1] = NULL;
  71126. + cam->rot_enc_bufs[1] = 0;
  71127. + }
  71128. + }
  71129. +
  71130. + return err;
  71131. +}
  71132. +EXPORT_SYMBOL(prp_enc_deselect);
  71133. +
  71134. +/*!
  71135. + * Init the Encorder channels
  71136. + *
  71137. + * @return Error code indicating success or failure
  71138. + */
  71139. +__init int prp_enc_init(void)
  71140. +{
  71141. + return 0;
  71142. +}
  71143. +
  71144. +/*!
  71145. + * Deinit the Encorder channels
  71146. + *
  71147. + */
  71148. +void __exit prp_enc_exit(void)
  71149. +{
  71150. +}
  71151. +
  71152. +module_init(prp_enc_init);
  71153. +module_exit(prp_enc_exit);
  71154. +
  71155. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  71156. +MODULE_DESCRIPTION("IPU PRP ENC Driver");
  71157. +MODULE_LICENSE("GPL");
  71158. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/ipu_prp_sw.h linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_sw.h
  71159. --- linux-3.14.14/drivers/media/platform/mxc/capture/ipu_prp_sw.h 1969-12-31 18:00:00.000000000 -0600
  71160. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_sw.h 2014-12-08 00:31:53.256418001 -0600
  71161. @@ -0,0 +1,43 @@
  71162. +/*
  71163. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  71164. + */
  71165. +
  71166. +/*
  71167. + * The code contained herein is licensed under the GNU General Public
  71168. + * License. You may obtain a copy of the GNU General Public License
  71169. + * Version 2 or later at the following locations:
  71170. + *
  71171. + * http://www.opensource.org/licenses/gpl-license.html
  71172. + * http://www.gnu.org/copyleft/gpl.html
  71173. + */
  71174. +
  71175. +/*!
  71176. + * @file ipu_prp_sw.h
  71177. + *
  71178. + * @brief This file contains the IPU PRP use case driver header.
  71179. + *
  71180. + * @ingroup IPU
  71181. + */
  71182. +
  71183. +#ifndef _INCLUDE_IPU__PRP_SW_H_
  71184. +#define _INCLUDE_IPU__PRP_SW_H_
  71185. +
  71186. +int csi_enc_select(void *private);
  71187. +int csi_enc_deselect(void *private);
  71188. +int prp_enc_select(void *private);
  71189. +int prp_enc_deselect(void *private);
  71190. +#ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  71191. +int prp_vf_sdc_select(void *private);
  71192. +int prp_vf_sdc_deselect(void *private);
  71193. +int prp_vf_sdc_select_bg(void *private);
  71194. +int prp_vf_sdc_deselect_bg(void *private);
  71195. +#else
  71196. +int foreground_sdc_select(void *private);
  71197. +int foreground_sdc_deselect(void *private);
  71198. +int bg_overlay_sdc_select(void *private);
  71199. +int bg_overlay_sdc_deselect(void *private);
  71200. +#endif
  71201. +int prp_still_select(void *private);
  71202. +int prp_still_deselect(void *private);
  71203. +
  71204. +#endif
  71205. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c
  71206. --- linux-3.14.14/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c 1969-12-31 18:00:00.000000000 -0600
  71207. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c 2014-12-08 00:31:53.256418001 -0600
  71208. @@ -0,0 +1,521 @@
  71209. +/*
  71210. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  71211. + */
  71212. +
  71213. +/*
  71214. + * The code contained herein is licensed under the GNU General Public
  71215. + * License. You may obtain a copy of the GNU General Public License
  71216. + * Version 2 or later at the following locations:
  71217. + *
  71218. + * http://www.opensource.org/licenses/gpl-license.html
  71219. + * http://www.gnu.org/copyleft/gpl.html
  71220. + */
  71221. +
  71222. +/*!
  71223. + * @file ipu_prp_vf_sdc_bg.c
  71224. + *
  71225. + * @brief IPU Use case for PRP-VF back-ground
  71226. + *
  71227. + * @ingroup IPU
  71228. + */
  71229. +#include <linux/dma-mapping.h>
  71230. +#include <linux/fb.h>
  71231. +#include <linux/ipu.h>
  71232. +#include <linux/module.h>
  71233. +#include <mach/mipi_csi2.h>
  71234. +#include "mxc_v4l2_capture.h"
  71235. +#include "ipu_prp_sw.h"
  71236. +
  71237. +static int buffer_num;
  71238. +static int buffer_ready;
  71239. +static struct ipu_soc *disp_ipu;
  71240. +
  71241. +static void get_disp_ipu(cam_data *cam)
  71242. +{
  71243. + if (cam->output > 2)
  71244. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  71245. + else
  71246. + disp_ipu = ipu_get_soc(0);
  71247. +}
  71248. +
  71249. +/*
  71250. + * Function definitions
  71251. + */
  71252. +
  71253. +/*!
  71254. + * SDC V-Sync callback function.
  71255. + *
  71256. + * @param irq int irq line
  71257. + * @param dev_id void * device id
  71258. + *
  71259. + * @return status IRQ_HANDLED for handled
  71260. + */
  71261. +static irqreturn_t prpvf_sdc_vsync_callback(int irq, void *dev_id)
  71262. +{
  71263. + cam_data *cam = dev_id;
  71264. + if (buffer_ready > 0) {
  71265. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71266. + IPU_OUTPUT_BUFFER, 0);
  71267. + buffer_ready--;
  71268. + }
  71269. +
  71270. + return IRQ_HANDLED;
  71271. +}
  71272. +
  71273. +/*!
  71274. + * VF EOF callback function.
  71275. + *
  71276. + * @param irq int irq line
  71277. + * @param dev_id void * device id
  71278. + *
  71279. + * @return status IRQ_HANDLED for handled
  71280. + */
  71281. +static irqreturn_t prpvf_vf_eof_callback(int irq, void *dev_id)
  71282. +{
  71283. + cam_data *cam = dev_id;
  71284. + pr_debug("buffer_ready %d buffer_num %d\n", buffer_ready, buffer_num);
  71285. +
  71286. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71287. + IPU_INPUT_BUFFER, buffer_num);
  71288. + buffer_num = (buffer_num == 0) ? 1 : 0;
  71289. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  71290. + IPU_OUTPUT_BUFFER, buffer_num);
  71291. + buffer_ready++;
  71292. + return IRQ_HANDLED;
  71293. +}
  71294. +
  71295. +/*!
  71296. + * prpvf_start - start the vf task
  71297. + *
  71298. + * @param private cam_data * mxc v4l2 main structure
  71299. + *
  71300. + */
  71301. +static int prpvf_start(void *private)
  71302. +{
  71303. + cam_data *cam = (cam_data *) private;
  71304. + ipu_channel_params_t vf;
  71305. + u32 format;
  71306. + u32 offset;
  71307. + u32 bpp, size = 3;
  71308. + int err = 0;
  71309. +#ifdef CONFIG_MXC_MIPI_CSI2
  71310. + void *mipi_csi2_info;
  71311. + int ipu_id;
  71312. + int csi_id;
  71313. +#endif
  71314. +
  71315. + if (!cam) {
  71316. + printk(KERN_ERR "private is NULL\n");
  71317. + return -EIO;
  71318. + }
  71319. +
  71320. + if (cam->overlay_active == true) {
  71321. + pr_debug("already start.\n");
  71322. + return 0;
  71323. + }
  71324. +
  71325. + get_disp_ipu(cam);
  71326. +
  71327. + format = cam->v4l2_fb.fmt.pixelformat;
  71328. + if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR24) {
  71329. + bpp = 3, size = 3;
  71330. + pr_info("BGR24\n");
  71331. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_RGB565) {
  71332. + bpp = 2, size = 2;
  71333. + pr_info("RGB565\n");
  71334. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR32) {
  71335. + bpp = 4, size = 4;
  71336. + pr_info("BGR32\n");
  71337. + } else {
  71338. + printk(KERN_ERR
  71339. + "unsupported fix format from the framebuffer.\n");
  71340. + return -EINVAL;
  71341. + }
  71342. +
  71343. + offset = cam->v4l2_fb.fmt.bytesperline * cam->win.w.top +
  71344. + size * cam->win.w.left;
  71345. +
  71346. + if (cam->v4l2_fb.base == 0)
  71347. + printk(KERN_ERR "invalid frame buffer address.\n");
  71348. + else
  71349. + offset += (u32) cam->v4l2_fb.base;
  71350. +
  71351. + memset(&vf, 0, sizeof(ipu_channel_params_t));
  71352. + ipu_csi_get_window_size(cam->ipu, &vf.csi_prp_vf_mem.in_width,
  71353. + &vf.csi_prp_vf_mem.in_height, cam->csi);
  71354. + vf.csi_prp_vf_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
  71355. + vf.csi_prp_vf_mem.out_width = cam->win.w.width;
  71356. + vf.csi_prp_vf_mem.out_height = cam->win.w.height;
  71357. + vf.csi_prp_vf_mem.csi = cam->csi;
  71358. + if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
  71359. + vf.csi_prp_vf_mem.out_width = cam->win.w.height;
  71360. + vf.csi_prp_vf_mem.out_height = cam->win.w.width;
  71361. + }
  71362. + vf.csi_prp_vf_mem.out_pixel_fmt = format;
  71363. + size = cam->win.w.width * cam->win.w.height * size;
  71364. +
  71365. +#ifdef CONFIG_MXC_MIPI_CSI2
  71366. + mipi_csi2_info = mipi_csi2_get_info();
  71367. +
  71368. + if (mipi_csi2_info) {
  71369. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  71370. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  71371. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  71372. +
  71373. + if (cam->ipu == ipu_get_soc(ipu_id)
  71374. + && cam->csi == csi_id) {
  71375. + vf.csi_prp_vf_mem.mipi_en = true;
  71376. + vf.csi_prp_vf_mem.mipi_vc =
  71377. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  71378. + vf.csi_prp_vf_mem.mipi_id =
  71379. + mipi_csi2_get_datatype(mipi_csi2_info);
  71380. +
  71381. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  71382. + } else {
  71383. + vf.csi_prp_vf_mem.mipi_en = false;
  71384. + vf.csi_prp_vf_mem.mipi_vc = 0;
  71385. + vf.csi_prp_vf_mem.mipi_id = 0;
  71386. + }
  71387. + } else {
  71388. + vf.csi_prp_vf_mem.mipi_en = false;
  71389. + vf.csi_prp_vf_mem.mipi_vc = 0;
  71390. + vf.csi_prp_vf_mem.mipi_id = 0;
  71391. + }
  71392. + }
  71393. +#endif
  71394. +
  71395. + err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
  71396. + if (err != 0)
  71397. + goto out_4;
  71398. +
  71399. + if (cam->vf_bufs_vaddr[0]) {
  71400. + dma_free_coherent(0, cam->vf_bufs_size[0],
  71401. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  71402. + }
  71403. + if (cam->vf_bufs_vaddr[1]) {
  71404. + dma_free_coherent(0, cam->vf_bufs_size[1],
  71405. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  71406. + }
  71407. + cam->vf_bufs_size[0] = PAGE_ALIGN(size);
  71408. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  71409. + cam->vf_bufs_size[0],
  71410. + &cam->vf_bufs[0],
  71411. + GFP_DMA |
  71412. + GFP_KERNEL);
  71413. + if (cam->vf_bufs_vaddr[0] == NULL) {
  71414. + printk(KERN_ERR "Error to allocate vf buffer\n");
  71415. + err = -ENOMEM;
  71416. + goto out_3;
  71417. + }
  71418. + cam->vf_bufs_size[1] = PAGE_ALIGN(size);
  71419. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  71420. + cam->vf_bufs_size[1],
  71421. + &cam->vf_bufs[1],
  71422. + GFP_DMA |
  71423. + GFP_KERNEL);
  71424. + if (cam->vf_bufs_vaddr[1] == NULL) {
  71425. + printk(KERN_ERR "Error to allocate vf buffer\n");
  71426. + err = -ENOMEM;
  71427. + goto out_3;
  71428. + }
  71429. +
  71430. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
  71431. + IPU_OUTPUT_BUFFER,
  71432. + format, vf.csi_prp_vf_mem.out_width,
  71433. + vf.csi_prp_vf_mem.out_height,
  71434. + vf.csi_prp_vf_mem.out_width,
  71435. + IPU_ROTATE_NONE,
  71436. + cam->vf_bufs[0],
  71437. + cam->vf_bufs[1],
  71438. + 0, 0, 0);
  71439. + if (err != 0) {
  71440. + printk(KERN_ERR "Error initializing CSI_PRP_VF_MEM\n");
  71441. + goto out_3;
  71442. + }
  71443. + err = ipu_init_channel(cam->ipu, MEM_ROT_VF_MEM, NULL);
  71444. + if (err != 0) {
  71445. + printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n");
  71446. + goto out_3;
  71447. + }
  71448. +
  71449. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71450. + IPU_INPUT_BUFFER,
  71451. + format, vf.csi_prp_vf_mem.out_width,
  71452. + vf.csi_prp_vf_mem.out_height,
  71453. + vf.csi_prp_vf_mem.out_width,
  71454. + cam->vf_rotation,
  71455. + cam->vf_bufs[0],
  71456. + cam->vf_bufs[1],
  71457. + 0, 0, 0);
  71458. + if (err != 0) {
  71459. + printk(KERN_ERR "Error MEM_ROT_VF_MEM input buffer\n");
  71460. + goto out_2;
  71461. + }
  71462. +
  71463. + if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
  71464. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71465. + IPU_OUTPUT_BUFFER,
  71466. + format,
  71467. + vf.csi_prp_vf_mem.out_height,
  71468. + vf.csi_prp_vf_mem.out_width,
  71469. + cam->overlay_fb->var.xres * bpp,
  71470. + IPU_ROTATE_NONE,
  71471. + offset, 0, 0, 0, 0);
  71472. +
  71473. + if (err != 0) {
  71474. + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
  71475. + goto out_2;
  71476. + }
  71477. + } else {
  71478. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71479. + IPU_OUTPUT_BUFFER,
  71480. + format,
  71481. + vf.csi_prp_vf_mem.out_width,
  71482. + vf.csi_prp_vf_mem.out_height,
  71483. + cam->overlay_fb->var.xres * bpp,
  71484. + IPU_ROTATE_NONE,
  71485. + offset, 0, 0, 0, 0);
  71486. + if (err != 0) {
  71487. + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
  71488. + goto out_2;
  71489. + }
  71490. + }
  71491. +
  71492. + ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF);
  71493. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF,
  71494. + prpvf_vf_eof_callback,
  71495. + 0, "Mxc Camera", cam);
  71496. + if (err != 0) {
  71497. + printk(KERN_ERR
  71498. + "Error registering IPU_IRQ_PRP_VF_OUT_EOF irq.\n");
  71499. + goto out_2;
  71500. + }
  71501. +
  71502. + ipu_clear_irq(disp_ipu, IPU_IRQ_BG_SF_END);
  71503. + err = ipu_request_irq(disp_ipu, IPU_IRQ_BG_SF_END,
  71504. + prpvf_sdc_vsync_callback,
  71505. + 0, "Mxc Camera", cam);
  71506. + if (err != 0) {
  71507. + printk(KERN_ERR "Error registering IPU_IRQ_BG_SF_END irq.\n");
  71508. + goto out_1;
  71509. + }
  71510. +
  71511. + ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
  71512. + ipu_enable_channel(cam->ipu, MEM_ROT_VF_MEM);
  71513. +
  71514. + buffer_num = 0;
  71515. + buffer_ready = 0;
  71516. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, 0);
  71517. +
  71518. + cam->overlay_active = true;
  71519. + return err;
  71520. +
  71521. +out_1:
  71522. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, NULL);
  71523. +out_2:
  71524. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  71525. +out_3:
  71526. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  71527. +out_4:
  71528. + if (cam->vf_bufs_vaddr[0]) {
  71529. + dma_free_coherent(0, cam->vf_bufs_size[0],
  71530. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  71531. + cam->vf_bufs_vaddr[0] = NULL;
  71532. + cam->vf_bufs[0] = 0;
  71533. + }
  71534. + if (cam->vf_bufs_vaddr[1]) {
  71535. + dma_free_coherent(0, cam->vf_bufs_size[1],
  71536. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  71537. + cam->vf_bufs_vaddr[1] = NULL;
  71538. + cam->vf_bufs[1] = 0;
  71539. + }
  71540. + if (cam->rot_vf_bufs_vaddr[0]) {
  71541. + dma_free_coherent(0, cam->rot_vf_buf_size[0],
  71542. + cam->rot_vf_bufs_vaddr[0],
  71543. + cam->rot_vf_bufs[0]);
  71544. + cam->rot_vf_bufs_vaddr[0] = NULL;
  71545. + cam->rot_vf_bufs[0] = 0;
  71546. + }
  71547. + if (cam->rot_vf_bufs_vaddr[1]) {
  71548. + dma_free_coherent(0, cam->rot_vf_buf_size[1],
  71549. + cam->rot_vf_bufs_vaddr[1],
  71550. + cam->rot_vf_bufs[1]);
  71551. + cam->rot_vf_bufs_vaddr[1] = NULL;
  71552. + cam->rot_vf_bufs[1] = 0;
  71553. + }
  71554. + return err;
  71555. +}
  71556. +
  71557. +/*!
  71558. + * prpvf_stop - stop the vf task
  71559. + *
  71560. + * @param private cam_data * mxc v4l2 main structure
  71561. + *
  71562. + */
  71563. +static int prpvf_stop(void *private)
  71564. +{
  71565. + cam_data *cam = (cam_data *) private;
  71566. +#ifdef CONFIG_MXC_MIPI_CSI2
  71567. + void *mipi_csi2_info;
  71568. + int ipu_id;
  71569. + int csi_id;
  71570. +#endif
  71571. +
  71572. + if (cam->overlay_active == false)
  71573. + return 0;
  71574. +
  71575. + ipu_free_irq(disp_ipu, IPU_IRQ_BG_SF_END, cam);
  71576. +
  71577. + ipu_disable_channel(cam->ipu, CSI_PRP_VF_MEM, true);
  71578. + ipu_disable_channel(cam->ipu, MEM_ROT_VF_MEM, true);
  71579. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  71580. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  71581. +
  71582. +#ifdef CONFIG_MXC_MIPI_CSI2
  71583. + mipi_csi2_info = mipi_csi2_get_info();
  71584. +
  71585. + if (mipi_csi2_info) {
  71586. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  71587. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  71588. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  71589. +
  71590. + if (cam->ipu == ipu_get_soc(ipu_id)
  71591. + && cam->csi == csi_id)
  71592. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  71593. + }
  71594. + }
  71595. +#endif
  71596. +
  71597. + if (cam->vf_bufs_vaddr[0]) {
  71598. + dma_free_coherent(0, cam->vf_bufs_size[0],
  71599. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  71600. + cam->vf_bufs_vaddr[0] = NULL;
  71601. + cam->vf_bufs[0] = 0;
  71602. + }
  71603. + if (cam->vf_bufs_vaddr[1]) {
  71604. + dma_free_coherent(0, cam->vf_bufs_size[1],
  71605. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  71606. + cam->vf_bufs_vaddr[1] = NULL;
  71607. + cam->vf_bufs[1] = 0;
  71608. + }
  71609. + if (cam->rot_vf_bufs_vaddr[0]) {
  71610. + dma_free_coherent(0, cam->rot_vf_buf_size[0],
  71611. + cam->rot_vf_bufs_vaddr[0],
  71612. + cam->rot_vf_bufs[0]);
  71613. + cam->rot_vf_bufs_vaddr[0] = NULL;
  71614. + cam->rot_vf_bufs[0] = 0;
  71615. + }
  71616. + if (cam->rot_vf_bufs_vaddr[1]) {
  71617. + dma_free_coherent(0, cam->rot_vf_buf_size[1],
  71618. + cam->rot_vf_bufs_vaddr[1],
  71619. + cam->rot_vf_bufs[1]);
  71620. + cam->rot_vf_bufs_vaddr[1] = NULL;
  71621. + cam->rot_vf_bufs[1] = 0;
  71622. + }
  71623. +
  71624. + buffer_num = 0;
  71625. + buffer_ready = 0;
  71626. + cam->overlay_active = false;
  71627. + return 0;
  71628. +}
  71629. +
  71630. +/*!
  71631. + * Enable csi
  71632. + * @param private struct cam_data * mxc capture instance
  71633. + *
  71634. + * @return status
  71635. + */
  71636. +static int prp_vf_enable_csi(void *private)
  71637. +{
  71638. + cam_data *cam = (cam_data *) private;
  71639. +
  71640. + return ipu_enable_csi(cam->ipu, cam->csi);
  71641. +}
  71642. +
  71643. +/*!
  71644. + * Disable csi
  71645. + * @param private struct cam_data * mxc capture instance
  71646. + *
  71647. + * @return status
  71648. + */
  71649. +static int prp_vf_disable_csi(void *private)
  71650. +{
  71651. + cam_data *cam = (cam_data *) private;
  71652. +
  71653. + /* free csi eof irq firstly.
  71654. + * when disable csi, wait for idmac eof.
  71655. + * it requests eof irq again */
  71656. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, cam);
  71657. +
  71658. + return ipu_disable_csi(cam->ipu, cam->csi);
  71659. +}
  71660. +
  71661. +/*!
  71662. + * function to select PRP-VF as the working path
  71663. + *
  71664. + * @param private cam_data * mxc v4l2 main structure
  71665. + *
  71666. + * @return status
  71667. + */
  71668. +int prp_vf_sdc_select_bg(void *private)
  71669. +{
  71670. + cam_data *cam = (cam_data *) private;
  71671. +
  71672. + if (cam) {
  71673. + cam->vf_start_sdc = prpvf_start;
  71674. + cam->vf_stop_sdc = prpvf_stop;
  71675. + cam->vf_enable_csi = prp_vf_enable_csi;
  71676. + cam->vf_disable_csi = prp_vf_disable_csi;
  71677. + cam->overlay_active = false;
  71678. + }
  71679. +
  71680. + return 0;
  71681. +}
  71682. +EXPORT_SYMBOL(prp_vf_sdc_select_bg);
  71683. +
  71684. +/*!
  71685. + * function to de-select PRP-VF as the working path
  71686. + *
  71687. + * @param private cam_data * mxc v4l2 main structure
  71688. + *
  71689. + * @return status
  71690. + */
  71691. +int prp_vf_sdc_deselect_bg(void *private)
  71692. +{
  71693. + cam_data *cam = (cam_data *) private;
  71694. +
  71695. + if (cam) {
  71696. + cam->vf_start_sdc = NULL;
  71697. + cam->vf_stop_sdc = NULL;
  71698. + cam->vf_enable_csi = NULL;
  71699. + cam->vf_disable_csi = NULL;
  71700. + }
  71701. + return 0;
  71702. +}
  71703. +EXPORT_SYMBOL(prp_vf_sdc_deselect_bg);
  71704. +
  71705. +/*!
  71706. + * Init viewfinder task.
  71707. + *
  71708. + * @return Error code indicating success or failure
  71709. + */
  71710. +__init int prp_vf_sdc_init_bg(void)
  71711. +{
  71712. + return 0;
  71713. +}
  71714. +
  71715. +/*!
  71716. + * Deinit viewfinder task.
  71717. + *
  71718. + * @return Error code indicating success or failure
  71719. + */
  71720. +void __exit prp_vf_sdc_exit_bg(void)
  71721. +{
  71722. +}
  71723. +
  71724. +module_init(prp_vf_sdc_init_bg);
  71725. +module_exit(prp_vf_sdc_exit_bg);
  71726. +
  71727. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  71728. +MODULE_DESCRIPTION("IPU PRP VF SDC Backgroud Driver");
  71729. +MODULE_LICENSE("GPL");
  71730. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c
  71731. --- linux-3.14.14/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c 1969-12-31 18:00:00.000000000 -0600
  71732. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c 2014-12-08 00:31:53.256418001 -0600
  71733. @@ -0,0 +1,582 @@
  71734. +/*
  71735. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  71736. + */
  71737. +/* * The code contained herein is licensed under the GNU General Public
  71738. + * License. You may obtain a copy of the GNU General Public License
  71739. + * Version 2 or later at the following locations:
  71740. + *
  71741. + * http://www.opensource.org/licenses/gpl-license.html
  71742. + * http://www.gnu.org/copyleft/gpl.html
  71743. + */
  71744. +
  71745. +/*!
  71746. + * @file ipu_prp_vf_sdc.c
  71747. + *
  71748. + * @brief IPU Use case for PRP-VF
  71749. + *
  71750. + * @ingroup IPU
  71751. + */
  71752. +
  71753. +#include <linux/dma-mapping.h>
  71754. +#include <linux/console.h>
  71755. +#include <linux/ipu.h>
  71756. +#include <linux/module.h>
  71757. +#include <linux/mxcfb.h>
  71758. +#include <mach/hardware.h>
  71759. +#include <mach/mipi_csi2.h>
  71760. +#include "mxc_v4l2_capture.h"
  71761. +#include "ipu_prp_sw.h"
  71762. +
  71763. +static int buffer_num;
  71764. +static struct ipu_soc *disp_ipu;
  71765. +
  71766. +static void get_disp_ipu(cam_data *cam)
  71767. +{
  71768. + if (cam->output > 2)
  71769. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  71770. + else
  71771. + disp_ipu = ipu_get_soc(0);
  71772. +}
  71773. +
  71774. +static irqreturn_t prpvf_rot_eof_callback(int irq, void *dev_id)
  71775. +{
  71776. + cam_data *cam = dev_id;
  71777. + pr_debug("buffer_num %d\n", buffer_num);
  71778. +
  71779. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  71780. + ipu_select_buffer(disp_ipu, MEM_FG_SYNC,
  71781. + IPU_INPUT_BUFFER, buffer_num);
  71782. + buffer_num = (buffer_num == 0) ? 1 : 0;
  71783. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71784. + IPU_OUTPUT_BUFFER, buffer_num);
  71785. + } else {
  71786. + ipu_select_buffer(disp_ipu, MEM_FG_SYNC,
  71787. + IPU_INPUT_BUFFER, buffer_num);
  71788. + buffer_num = (buffer_num == 0) ? 1 : 0;
  71789. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  71790. + IPU_OUTPUT_BUFFER, buffer_num);
  71791. + }
  71792. + return IRQ_HANDLED;
  71793. +}
  71794. +/*
  71795. + * Function definitions
  71796. + */
  71797. +
  71798. +/*!
  71799. + * prpvf_start - start the vf task
  71800. + *
  71801. + * @param private cam_data * mxc v4l2 main structure
  71802. + *
  71803. + */
  71804. +static int prpvf_start(void *private)
  71805. +{
  71806. + struct fb_var_screeninfo fbvar;
  71807. + struct fb_info *fbi = NULL;
  71808. + cam_data *cam = (cam_data *) private;
  71809. + ipu_channel_params_t vf;
  71810. + u32 vf_out_format = 0;
  71811. + u32 size = 2, temp = 0;
  71812. + int err = 0, i = 0;
  71813. + short *tmp, color;
  71814. +#ifdef CONFIG_MXC_MIPI_CSI2
  71815. + void *mipi_csi2_info;
  71816. + int ipu_id;
  71817. + int csi_id;
  71818. +#endif
  71819. +
  71820. + if (!cam) {
  71821. + printk(KERN_ERR "private is NULL\n");
  71822. + return -EIO;
  71823. + }
  71824. +
  71825. + if (cam->overlay_active == true) {
  71826. + pr_debug("already started.\n");
  71827. + return 0;
  71828. + }
  71829. +
  71830. + get_disp_ipu(cam);
  71831. +
  71832. + for (i = 0; i < num_registered_fb; i++) {
  71833. + char *idstr = registered_fb[i]->fix.id;
  71834. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  71835. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  71836. + fbi = registered_fb[i];
  71837. + break;
  71838. + }
  71839. + }
  71840. +
  71841. + if (fbi == NULL) {
  71842. + printk(KERN_ERR "DISP FG fb not found\n");
  71843. + return -EPERM;
  71844. + }
  71845. +
  71846. + fbvar = fbi->var;
  71847. +
  71848. + /* Store the overlay frame buffer's original std */
  71849. + cam->fb_origin_std = fbvar.nonstd;
  71850. +
  71851. + if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
  71852. + /* Use DP to do CSC so that we can get better performance */
  71853. + vf_out_format = IPU_PIX_FMT_UYVY;
  71854. + fbvar.nonstd = vf_out_format;
  71855. + color = 0x80;
  71856. + } else {
  71857. + vf_out_format = IPU_PIX_FMT_RGB565;
  71858. + fbvar.nonstd = 0;
  71859. + color = 0x0;
  71860. + }
  71861. +
  71862. + fbvar.bits_per_pixel = 16;
  71863. + fbvar.xres = fbvar.xres_virtual = cam->win.w.width;
  71864. + fbvar.yres = cam->win.w.height;
  71865. + fbvar.yres_virtual = cam->win.w.height * 2;
  71866. + fbvar.yoffset = 0;
  71867. + fbvar.accel_flags = FB_ACCEL_DOUBLE_FLAG;
  71868. + fbvar.activate |= FB_ACTIVATE_FORCE;
  71869. + fb_set_var(fbi, &fbvar);
  71870. +
  71871. + ipu_disp_set_window_pos(disp_ipu, MEM_FG_SYNC, cam->win.w.left,
  71872. + cam->win.w.top);
  71873. +
  71874. + /* Fill black color for framebuffer */
  71875. + tmp = (short *) fbi->screen_base;
  71876. + for (i = 0; i < (fbi->fix.line_length * fbi->var.yres)/2;
  71877. + i++, tmp++)
  71878. + *tmp = color;
  71879. +
  71880. + console_lock();
  71881. + fb_blank(fbi, FB_BLANK_UNBLANK);
  71882. + console_unlock();
  71883. +
  71884. + /* correct display ch buffer address */
  71885. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  71886. + 0, fbi->fix.smem_start +
  71887. + (fbi->fix.line_length * fbvar.yres));
  71888. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  71889. + 1, fbi->fix.smem_start);
  71890. +
  71891. + memset(&vf, 0, sizeof(ipu_channel_params_t));
  71892. + ipu_csi_get_window_size(cam->ipu, &vf.csi_prp_vf_mem.in_width,
  71893. + &vf.csi_prp_vf_mem.in_height, cam->csi);
  71894. + vf.csi_prp_vf_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
  71895. + vf.csi_prp_vf_mem.out_width = cam->win.w.width;
  71896. + vf.csi_prp_vf_mem.out_height = cam->win.w.height;
  71897. + vf.csi_prp_vf_mem.csi = cam->csi;
  71898. + if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
  71899. + vf.csi_prp_vf_mem.out_width = cam->win.w.height;
  71900. + vf.csi_prp_vf_mem.out_height = cam->win.w.width;
  71901. + }
  71902. + vf.csi_prp_vf_mem.out_pixel_fmt = vf_out_format;
  71903. + size = cam->win.w.width * cam->win.w.height * size;
  71904. +
  71905. +#ifdef CONFIG_MXC_MIPI_CSI2
  71906. + mipi_csi2_info = mipi_csi2_get_info();
  71907. +
  71908. + if (mipi_csi2_info) {
  71909. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  71910. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  71911. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  71912. +
  71913. + if (cam->ipu == ipu_get_soc(ipu_id)
  71914. + && cam->csi == csi_id) {
  71915. + vf.csi_prp_vf_mem.mipi_en = true;
  71916. + vf.csi_prp_vf_mem.mipi_vc =
  71917. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  71918. + vf.csi_prp_vf_mem.mipi_id =
  71919. + mipi_csi2_get_datatype(mipi_csi2_info);
  71920. +
  71921. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  71922. + } else {
  71923. + vf.csi_prp_vf_mem.mipi_en = false;
  71924. + vf.csi_prp_vf_mem.mipi_vc = 0;
  71925. + vf.csi_prp_vf_mem.mipi_id = 0;
  71926. + }
  71927. + } else {
  71928. + vf.csi_prp_vf_mem.mipi_en = false;
  71929. + vf.csi_prp_vf_mem.mipi_vc = 0;
  71930. + vf.csi_prp_vf_mem.mipi_id = 0;
  71931. + }
  71932. + }
  71933. +#endif
  71934. +
  71935. + err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
  71936. + if (err != 0)
  71937. + goto out_5;
  71938. +
  71939. + if (cam->vf_bufs_vaddr[0]) {
  71940. + dma_free_coherent(0, cam->vf_bufs_size[0],
  71941. + cam->vf_bufs_vaddr[0],
  71942. + (dma_addr_t) cam->vf_bufs[0]);
  71943. + }
  71944. + if (cam->vf_bufs_vaddr[1]) {
  71945. + dma_free_coherent(0, cam->vf_bufs_size[1],
  71946. + cam->vf_bufs_vaddr[1],
  71947. + (dma_addr_t) cam->vf_bufs[1]);
  71948. + }
  71949. + cam->vf_bufs_size[0] = PAGE_ALIGN(size);
  71950. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  71951. + cam->vf_bufs_size[0],
  71952. + (dma_addr_t *) &
  71953. + cam->vf_bufs[0],
  71954. + GFP_DMA |
  71955. + GFP_KERNEL);
  71956. + if (cam->vf_bufs_vaddr[0] == NULL) {
  71957. + printk(KERN_ERR "Error to allocate vf buffer\n");
  71958. + err = -ENOMEM;
  71959. + goto out_4;
  71960. + }
  71961. + cam->vf_bufs_size[1] = PAGE_ALIGN(size);
  71962. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  71963. + cam->vf_bufs_size[1],
  71964. + (dma_addr_t *) &
  71965. + cam->vf_bufs[1],
  71966. + GFP_DMA |
  71967. + GFP_KERNEL);
  71968. + if (cam->vf_bufs_vaddr[1] == NULL) {
  71969. + printk(KERN_ERR "Error to allocate vf buffer\n");
  71970. + err = -ENOMEM;
  71971. + goto out_3;
  71972. + }
  71973. + pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
  71974. +
  71975. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  71976. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
  71977. + IPU_OUTPUT_BUFFER,
  71978. + vf_out_format,
  71979. + vf.csi_prp_vf_mem.out_width,
  71980. + vf.csi_prp_vf_mem.out_height,
  71981. + vf.csi_prp_vf_mem.out_width,
  71982. + IPU_ROTATE_NONE,
  71983. + cam->vf_bufs[0], cam->vf_bufs[1],
  71984. + 0, 0, 0);
  71985. + if (err != 0)
  71986. + goto out_3;
  71987. +
  71988. + err = ipu_init_channel(cam->ipu, MEM_ROT_VF_MEM, NULL);
  71989. + if (err != 0) {
  71990. + printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n");
  71991. + goto out_3;
  71992. + }
  71993. +
  71994. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  71995. + IPU_INPUT_BUFFER,
  71996. + vf_out_format,
  71997. + vf.csi_prp_vf_mem.out_width,
  71998. + vf.csi_prp_vf_mem.out_height,
  71999. + vf.csi_prp_vf_mem.out_width,
  72000. + cam->vf_rotation,
  72001. + cam->vf_bufs[0],
  72002. + cam->vf_bufs[1],
  72003. + 0, 0, 0);
  72004. + if (err != 0) {
  72005. + printk(KERN_ERR "Error MEM_ROT_VF_MEM input buffer\n");
  72006. + goto out_2;
  72007. + }
  72008. +
  72009. + if (cam->vf_rotation < IPU_ROTATE_90_RIGHT) {
  72010. + temp = vf.csi_prp_vf_mem.out_width;
  72011. + vf.csi_prp_vf_mem.out_width =
  72012. + vf.csi_prp_vf_mem.out_height;
  72013. + vf.csi_prp_vf_mem.out_height = temp;
  72014. + }
  72015. +
  72016. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  72017. + IPU_OUTPUT_BUFFER,
  72018. + vf_out_format,
  72019. + vf.csi_prp_vf_mem.out_height,
  72020. + vf.csi_prp_vf_mem.out_width,
  72021. + vf.csi_prp_vf_mem.out_height,
  72022. + IPU_ROTATE_NONE,
  72023. + fbi->fix.smem_start +
  72024. + (fbi->fix.line_length *
  72025. + fbi->var.yres),
  72026. + fbi->fix.smem_start, 0, 0, 0);
  72027. +
  72028. + if (err != 0) {
  72029. + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
  72030. + goto out_2;
  72031. + }
  72032. +
  72033. + ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF);
  72034. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF,
  72035. + prpvf_rot_eof_callback,
  72036. + 0, "Mxc Camera", cam);
  72037. + if (err < 0) {
  72038. + printk(KERN_ERR "Error request irq:IPU_IRQ_PRP_VF_ROT_OUT_EOF\n");
  72039. + goto out_2;
  72040. + }
  72041. +
  72042. + err = ipu_link_channels(cam->ipu,
  72043. + CSI_PRP_VF_MEM, MEM_ROT_VF_MEM);
  72044. + if (err < 0) {
  72045. + printk(KERN_ERR
  72046. + "Error link CSI_PRP_VF_MEM-MEM_ROT_VF_MEM\n");
  72047. + goto out_1;
  72048. + }
  72049. +
  72050. + ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
  72051. + ipu_enable_channel(cam->ipu, MEM_ROT_VF_MEM);
  72052. +
  72053. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  72054. + IPU_OUTPUT_BUFFER, 0);
  72055. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  72056. + IPU_OUTPUT_BUFFER, 1);
  72057. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  72058. + IPU_OUTPUT_BUFFER, 0);
  72059. + } else {
  72060. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
  72061. + IPU_OUTPUT_BUFFER,
  72062. + vf_out_format, cam->win.w.width,
  72063. + cam->win.w.height,
  72064. + cam->win.w.width,
  72065. + cam->vf_rotation,
  72066. + fbi->fix.smem_start +
  72067. + (fbi->fix.line_length *
  72068. + fbi->var.yres),
  72069. + fbi->fix.smem_start, 0, 0, 0);
  72070. + if (err != 0) {
  72071. + printk(KERN_ERR "Error initializing CSI_PRP_VF_MEM\n");
  72072. + goto out_4;
  72073. + }
  72074. + ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF);
  72075. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF,
  72076. + prpvf_rot_eof_callback,
  72077. + 0, "Mxc Camera", cam);
  72078. + if (err < 0) {
  72079. + printk(KERN_ERR "Error request irq:IPU_IRQ_PRP_VF_OUT_EOF\n");
  72080. + goto out_4;
  72081. + }
  72082. +
  72083. + ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
  72084. +
  72085. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  72086. + IPU_OUTPUT_BUFFER, 0);
  72087. + }
  72088. +
  72089. + cam->overlay_active = true;
  72090. + return err;
  72091. +
  72092. +out_1:
  72093. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, NULL);
  72094. +out_2:
  72095. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP)
  72096. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  72097. +out_3:
  72098. + if (cam->vf_bufs_vaddr[0]) {
  72099. + dma_free_coherent(0, cam->vf_bufs_size[0],
  72100. + cam->vf_bufs_vaddr[0],
  72101. + (dma_addr_t) cam->vf_bufs[0]);
  72102. + cam->vf_bufs_vaddr[0] = NULL;
  72103. + cam->vf_bufs[0] = 0;
  72104. + }
  72105. + if (cam->vf_bufs_vaddr[1]) {
  72106. + dma_free_coherent(0, cam->vf_bufs_size[1],
  72107. + cam->vf_bufs_vaddr[1],
  72108. + (dma_addr_t) cam->vf_bufs[1]);
  72109. + cam->vf_bufs_vaddr[1] = NULL;
  72110. + cam->vf_bufs[1] = 0;
  72111. + }
  72112. +out_4:
  72113. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  72114. +out_5:
  72115. + return err;
  72116. +}
  72117. +
  72118. +/*!
  72119. + * prpvf_stop - stop the vf task
  72120. + *
  72121. + * @param private cam_data * mxc v4l2 main structure
  72122. + *
  72123. + */
  72124. +static int prpvf_stop(void *private)
  72125. +{
  72126. + cam_data *cam = (cam_data *) private;
  72127. + int err = 0, i = 0;
  72128. + struct fb_info *fbi = NULL;
  72129. + struct fb_var_screeninfo fbvar;
  72130. +#ifdef CONFIG_MXC_MIPI_CSI2
  72131. + void *mipi_csi2_info;
  72132. + int ipu_id;
  72133. + int csi_id;
  72134. +#endif
  72135. +
  72136. + if (cam->overlay_active == false)
  72137. + return 0;
  72138. +
  72139. + for (i = 0; i < num_registered_fb; i++) {
  72140. + char *idstr = registered_fb[i]->fix.id;
  72141. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  72142. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  72143. + fbi = registered_fb[i];
  72144. + break;
  72145. + }
  72146. + }
  72147. +
  72148. + if (fbi == NULL) {
  72149. + printk(KERN_ERR "DISP FG fb not found\n");
  72150. + return -EPERM;
  72151. + }
  72152. +
  72153. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  72154. + ipu_unlink_channels(cam->ipu, CSI_PRP_VF_MEM, MEM_ROT_VF_MEM);
  72155. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF, cam);
  72156. + }
  72157. + buffer_num = 0;
  72158. +
  72159. + ipu_disable_channel(cam->ipu, CSI_PRP_VF_MEM, true);
  72160. +
  72161. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  72162. + ipu_disable_channel(cam->ipu, MEM_ROT_VF_MEM, true);
  72163. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  72164. + }
  72165. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  72166. +
  72167. + console_lock();
  72168. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  72169. + console_unlock();
  72170. +
  72171. + /* Set the overlay frame buffer std to what it is used to be */
  72172. + fbvar = fbi->var;
  72173. + fbvar.accel_flags = FB_ACCEL_TRIPLE_FLAG;
  72174. + fbvar.nonstd = cam->fb_origin_std;
  72175. + fbvar.activate |= FB_ACTIVATE_FORCE;
  72176. + fb_set_var(fbi, &fbvar);
  72177. +
  72178. +#ifdef CONFIG_MXC_MIPI_CSI2
  72179. + mipi_csi2_info = mipi_csi2_get_info();
  72180. +
  72181. + if (mipi_csi2_info) {
  72182. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  72183. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  72184. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  72185. +
  72186. + if (cam->ipu == ipu_get_soc(ipu_id)
  72187. + && cam->csi == csi_id)
  72188. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  72189. + }
  72190. + }
  72191. +#endif
  72192. +
  72193. + if (cam->vf_bufs_vaddr[0]) {
  72194. + dma_free_coherent(0, cam->vf_bufs_size[0],
  72195. + cam->vf_bufs_vaddr[0],
  72196. + (dma_addr_t) cam->vf_bufs[0]);
  72197. + cam->vf_bufs_vaddr[0] = NULL;
  72198. + cam->vf_bufs[0] = 0;
  72199. + }
  72200. + if (cam->vf_bufs_vaddr[1]) {
  72201. + dma_free_coherent(0, cam->vf_bufs_size[1],
  72202. + cam->vf_bufs_vaddr[1],
  72203. + (dma_addr_t) cam->vf_bufs[1]);
  72204. + cam->vf_bufs_vaddr[1] = NULL;
  72205. + cam->vf_bufs[1] = 0;
  72206. + }
  72207. +
  72208. + cam->overlay_active = false;
  72209. + return err;
  72210. +}
  72211. +
  72212. +/*!
  72213. + * Enable csi
  72214. + * @param private struct cam_data * mxc capture instance
  72215. + *
  72216. + * @return status
  72217. + */
  72218. +static int prp_vf_enable_csi(void *private)
  72219. +{
  72220. + cam_data *cam = (cam_data *) private;
  72221. +
  72222. + return ipu_enable_csi(cam->ipu, cam->csi);
  72223. +}
  72224. +
  72225. +/*!
  72226. + * Disable csi
  72227. + * @param private struct cam_data * mxc capture instance
  72228. + *
  72229. + * @return status
  72230. + */
  72231. +static int prp_vf_disable_csi(void *private)
  72232. +{
  72233. + cam_data *cam = (cam_data *) private;
  72234. +
  72235. + /* free csi eof irq firstly.
  72236. + * when disable csi, wait for idmac eof.
  72237. + * it requests eof irq again */
  72238. + if (cam->vf_rotation < IPU_ROTATE_VERT_FLIP)
  72239. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, cam);
  72240. +
  72241. + return ipu_disable_csi(cam->ipu, cam->csi);
  72242. +}
  72243. +
  72244. +/*!
  72245. + * function to select PRP-VF as the working path
  72246. + *
  72247. + * @param private cam_data * mxc v4l2 main structure
  72248. + *
  72249. + * @return status
  72250. + */
  72251. +int prp_vf_sdc_select(void *private)
  72252. +{
  72253. + cam_data *cam;
  72254. + int err = 0;
  72255. + if (private) {
  72256. + cam = (cam_data *) private;
  72257. + cam->vf_start_sdc = prpvf_start;
  72258. + cam->vf_stop_sdc = prpvf_stop;
  72259. + cam->vf_enable_csi = prp_vf_enable_csi;
  72260. + cam->vf_disable_csi = prp_vf_disable_csi;
  72261. + cam->overlay_active = false;
  72262. + } else
  72263. + err = -EIO;
  72264. +
  72265. + return err;
  72266. +}
  72267. +EXPORT_SYMBOL(prp_vf_sdc_select);
  72268. +
  72269. +/*!
  72270. + * function to de-select PRP-VF as the working path
  72271. + *
  72272. + * @param private cam_data * mxc v4l2 main structure
  72273. + *
  72274. + * @return int
  72275. + */
  72276. +int prp_vf_sdc_deselect(void *private)
  72277. +{
  72278. + cam_data *cam;
  72279. +
  72280. + if (private) {
  72281. + cam = (cam_data *) private;
  72282. + cam->vf_start_sdc = NULL;
  72283. + cam->vf_stop_sdc = NULL;
  72284. + cam->vf_enable_csi = NULL;
  72285. + cam->vf_disable_csi = NULL;
  72286. + }
  72287. + return 0;
  72288. +}
  72289. +EXPORT_SYMBOL(prp_vf_sdc_deselect);
  72290. +
  72291. +/*!
  72292. + * Init viewfinder task.
  72293. + *
  72294. + * @return Error code indicating success or failure
  72295. + */
  72296. +__init int prp_vf_sdc_init(void)
  72297. +{
  72298. + return 0;
  72299. +}
  72300. +
  72301. +/*!
  72302. + * Deinit viewfinder task.
  72303. + *
  72304. + * @return Error code indicating success or failure
  72305. + */
  72306. +void __exit prp_vf_sdc_exit(void)
  72307. +{
  72308. +}
  72309. +
  72310. +module_init(prp_vf_sdc_init);
  72311. +module_exit(prp_vf_sdc_exit);
  72312. +
  72313. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  72314. +MODULE_DESCRIPTION("IPU PRP VF SDC Driver");
  72315. +MODULE_LICENSE("GPL");
  72316. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/ipu_still.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_still.c
  72317. --- linux-3.14.14/drivers/media/platform/mxc/capture/ipu_still.c 1969-12-31 18:00:00.000000000 -0600
  72318. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_still.c 2014-12-08 00:31:53.256418001 -0600
  72319. @@ -0,0 +1,268 @@
  72320. +/*
  72321. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  72322. + */
  72323. +
  72324. +/*
  72325. + * The code contained herein is licensed under the GNU General Public
  72326. + * License. You may obtain a copy of the GNU General Public License
  72327. + * Version 2 or later at the following locations:
  72328. + *
  72329. + * http://www.opensource.org/licenses/gpl-license.html
  72330. + * http://www.gnu.org/copyleft/gpl.html
  72331. + */
  72332. +
  72333. +/*!
  72334. + * @file ipu_still.c
  72335. + *
  72336. + * @brief IPU Use case for still image capture
  72337. + *
  72338. + * @ingroup IPU
  72339. + */
  72340. +
  72341. +#include <linux/module.h>
  72342. +#include <linux/semaphore.h>
  72343. +#include <linux/sched.h>
  72344. +#include <linux/ipu.h>
  72345. +#include "mxc_v4l2_capture.h"
  72346. +#include "ipu_prp_sw.h"
  72347. +
  72348. +static int callback_eof_flag;
  72349. +#ifndef CONFIG_MXC_IPU_V1
  72350. +static int buffer_num;
  72351. +#endif
  72352. +
  72353. +#ifdef CONFIG_MXC_IPU_V1
  72354. +static int callback_flag;
  72355. +/*
  72356. + * Function definitions
  72357. + */
  72358. +/*!
  72359. + * CSI EOF callback function.
  72360. + *
  72361. + * @param irq int irq line
  72362. + * @param dev_id void * device id
  72363. + *
  72364. + * @return status IRQ_HANDLED for handled
  72365. + */
  72366. +static irqreturn_t prp_csi_eof_callback(int irq, void *dev_id)
  72367. +{
  72368. + cam_data *cam = devid;
  72369. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  72370. + callback_flag%2 ? 1 : 0);
  72371. + if (callback_flag == 0)
  72372. + ipu_enable_channel(cam->ipu, CSI_MEM);
  72373. +
  72374. + callback_flag++;
  72375. + return IRQ_HANDLED;
  72376. +}
  72377. +#endif
  72378. +
  72379. +/*!
  72380. + * CSI callback function.
  72381. + *
  72382. + * @param irq int irq line
  72383. + * @param dev_id void * device id
  72384. + *
  72385. + * @return status IRQ_HANDLED for handled
  72386. + */
  72387. +static irqreturn_t prp_still_callback(int irq, void *dev_id)
  72388. +{
  72389. + cam_data *cam = (cam_data *) dev_id;
  72390. +
  72391. + callback_eof_flag++;
  72392. + if (callback_eof_flag < 5) {
  72393. +#ifndef CONFIG_MXC_IPU_V1
  72394. + buffer_num = (buffer_num == 0) ? 1 : 0;
  72395. + ipu_select_buffer(cam->ipu, CSI_MEM,
  72396. + IPU_OUTPUT_BUFFER, buffer_num);
  72397. +#endif
  72398. + } else {
  72399. + cam->still_counter++;
  72400. + wake_up_interruptible(&cam->still_queue);
  72401. + }
  72402. +
  72403. + return IRQ_HANDLED;
  72404. +}
  72405. +
  72406. +/*!
  72407. + * start csi->mem task
  72408. + * @param private struct cam_data * mxc capture instance
  72409. + *
  72410. + * @return status
  72411. + */
  72412. +static int prp_still_start(void *private)
  72413. +{
  72414. + cam_data *cam = (cam_data *) private;
  72415. + u32 pixel_fmt;
  72416. + int err;
  72417. + ipu_channel_params_t params;
  72418. +
  72419. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
  72420. + pixel_fmt = IPU_PIX_FMT_YUV420P;
  72421. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)
  72422. + pixel_fmt = IPU_PIX_FMT_NV12;
  72423. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P)
  72424. + pixel_fmt = IPU_PIX_FMT_YUV422P;
  72425. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
  72426. + pixel_fmt = IPU_PIX_FMT_UYVY;
  72427. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
  72428. + pixel_fmt = IPU_PIX_FMT_YUYV;
  72429. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
  72430. + pixel_fmt = IPU_PIX_FMT_BGR24;
  72431. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
  72432. + pixel_fmt = IPU_PIX_FMT_RGB24;
  72433. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565)
  72434. + pixel_fmt = IPU_PIX_FMT_RGB565;
  72435. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32)
  72436. + pixel_fmt = IPU_PIX_FMT_BGR32;
  72437. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32)
  72438. + pixel_fmt = IPU_PIX_FMT_RGB32;
  72439. + else {
  72440. + printk(KERN_ERR "format not supported\n");
  72441. + return -EINVAL;
  72442. + }
  72443. +
  72444. + memset(&params, 0, sizeof(params));
  72445. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  72446. + if (err != 0)
  72447. + return err;
  72448. +
  72449. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  72450. + pixel_fmt, cam->v2f.fmt.pix.width,
  72451. + cam->v2f.fmt.pix.height,
  72452. + cam->v2f.fmt.pix.width, IPU_ROTATE_NONE,
  72453. + cam->still_buf[0], cam->still_buf[1], 0,
  72454. + 0, 0);
  72455. + if (err != 0)
  72456. + return err;
  72457. +
  72458. +#ifdef CONFIG_MXC_IPU_V1
  72459. + ipu_clear_irq(IPU_IRQ_SENSOR_OUT_EOF);
  72460. + err = ipu_request_irq(IPU_IRQ_SENSOR_OUT_EOF, prp_still_callback,
  72461. + 0, "Mxc Camera", cam);
  72462. + if (err != 0) {
  72463. + printk(KERN_ERR "Error registering irq.\n");
  72464. + return err;
  72465. + }
  72466. + callback_flag = 0;
  72467. + callback_eof_flag = 0;
  72468. + ipu_clear_irq(IPU_IRQ_SENSOR_EOF);
  72469. + err = ipu_request_irq(IPU_IRQ_SENSOR_EOF, prp_csi_eof_callback,
  72470. + 0, "Mxc Camera", cam);
  72471. + if (err != 0) {
  72472. + printk(KERN_ERR "Error IPU_IRQ_SENSOR_EOF\n");
  72473. + return err;
  72474. + }
  72475. +#else
  72476. + callback_eof_flag = 0;
  72477. + buffer_num = 0;
  72478. +
  72479. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  72480. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  72481. + prp_still_callback,
  72482. + 0, "Mxc Camera", cam);
  72483. + if (err != 0) {
  72484. + printk(KERN_ERR "Error registering irq.\n");
  72485. + return err;
  72486. + }
  72487. +
  72488. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 0);
  72489. + ipu_enable_channel(cam->ipu, CSI_MEM);
  72490. + ipu_enable_csi(cam->ipu, cam->csi);
  72491. +#endif
  72492. +
  72493. + return err;
  72494. +}
  72495. +
  72496. +/*!
  72497. + * stop csi->mem encoder task
  72498. + * @param private struct cam_data * mxc capture instance
  72499. + *
  72500. + * @return status
  72501. + */
  72502. +static int prp_still_stop(void *private)
  72503. +{
  72504. + cam_data *cam = (cam_data *) private;
  72505. + int err = 0;
  72506. +
  72507. +#ifdef CONFIG_MXC_IPU_V1
  72508. + ipu_free_irq(IPU_IRQ_SENSOR_EOF, NULL);
  72509. + ipu_free_irq(IPU_IRQ_SENSOR_OUT_EOF, cam);
  72510. +#else
  72511. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  72512. +#endif
  72513. +
  72514. + ipu_disable_csi(cam->ipu, cam->csi);
  72515. + ipu_disable_channel(cam->ipu, CSI_MEM, true);
  72516. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  72517. +
  72518. + return err;
  72519. +}
  72520. +
  72521. +/*!
  72522. + * function to select CSI_MEM as the working path
  72523. + *
  72524. + * @param private struct cam_data * mxc capture instance
  72525. + *
  72526. + * @return status
  72527. + */
  72528. +int prp_still_select(void *private)
  72529. +{
  72530. + cam_data *cam = (cam_data *) private;
  72531. +
  72532. + if (cam) {
  72533. + cam->csi_start = prp_still_start;
  72534. + cam->csi_stop = prp_still_stop;
  72535. + }
  72536. +
  72537. + return 0;
  72538. +}
  72539. +EXPORT_SYMBOL(prp_still_select);
  72540. +
  72541. +/*!
  72542. + * function to de-select CSI_MEM as the working path
  72543. + *
  72544. + * @param private struct cam_data * mxc capture instance
  72545. + *
  72546. + * @return status
  72547. + */
  72548. +int prp_still_deselect(void *private)
  72549. +{
  72550. + cam_data *cam = (cam_data *) private;
  72551. + int err = 0;
  72552. +
  72553. + err = prp_still_stop(cam);
  72554. +
  72555. + if (cam) {
  72556. + cam->csi_start = NULL;
  72557. + cam->csi_stop = NULL;
  72558. + }
  72559. +
  72560. + return err;
  72561. +}
  72562. +EXPORT_SYMBOL(prp_still_deselect);
  72563. +
  72564. +/*!
  72565. + * Init the Encorder channels
  72566. + *
  72567. + * @return Error code indicating success or failure
  72568. + */
  72569. +__init int prp_still_init(void)
  72570. +{
  72571. + return 0;
  72572. +}
  72573. +
  72574. +/*!
  72575. + * Deinit the Encorder channels
  72576. + *
  72577. + */
  72578. +void __exit prp_still_exit(void)
  72579. +{
  72580. +}
  72581. +
  72582. +module_init(prp_still_init);
  72583. +module_exit(prp_still_exit);
  72584. +
  72585. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  72586. +MODULE_DESCRIPTION("IPU PRP STILL IMAGE Driver");
  72587. +MODULE_LICENSE("GPL");
  72588. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/Kconfig linux-imx6-3.14/drivers/media/platform/mxc/capture/Kconfig
  72589. --- linux-3.14.14/drivers/media/platform/mxc/capture/Kconfig 1969-12-31 18:00:00.000000000 -0600
  72590. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/Kconfig 2014-12-08 00:31:53.252418001 -0600
  72591. @@ -0,0 +1,86 @@
  72592. +if VIDEO_MXC_CAPTURE
  72593. +
  72594. +menu "MXC Camera/V4L2 PRP Features support"
  72595. +config VIDEO_MXC_IPU_CAMERA
  72596. + bool
  72597. + depends on VIDEO_MXC_CAPTURE && MXC_IPU
  72598. + default y
  72599. +
  72600. +config VIDEO_MXC_CSI_CAMERA
  72601. + tristate "CSI camera support"
  72602. + depends on VIDEO_MXC_CAPTURE && VIDEO_V4L2
  72603. + ---help---
  72604. + This is the video4linux2 capture driver based on CSI module.
  72605. +
  72606. +config MXC_CAMERA_OV5640
  72607. + tristate "OmniVision ov5640 camera support"
  72608. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  72609. + ---help---
  72610. + If you plan to use the ov5640 Camera with your MXC system, say Y here.
  72611. +
  72612. +config MXC_CAMERA_OV5642
  72613. + tristate "OmniVision ov5642 camera support"
  72614. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  72615. + ---help---
  72616. + If you plan to use the ov5642 Camera with your MXC system, say Y here.
  72617. +
  72618. +config MXC_CAMERA_OV5640_MIPI
  72619. + tristate "OmniVision ov5640 camera support using mipi"
  72620. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  72621. + ---help---
  72622. + If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here.
  72623. +
  72624. +config MXC_TVIN_ADV7180
  72625. + tristate "Analog Device adv7180 TV Decoder Input support"
  72626. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  72627. + ---help---
  72628. + If you plan to use the adv7180 video decoder with your MXC system, say Y here.
  72629. +
  72630. +choice
  72631. + prompt "Select Overlay Rounting"
  72632. + default MXC_IPU_DEVICE_QUEUE_SDC
  72633. + depends on VIDEO_MXC_IPU_CAMERA && FB_MXC_SYNC_PANEL
  72634. +
  72635. +config MXC_IPU_DEVICE_QUEUE_SDC
  72636. + tristate "Queue ipu device for overlay library"
  72637. + depends on VIDEO_MXC_IPU_CAMERA
  72638. + ---help---
  72639. + Use case CSI->MEM->IPU DEVICE->SDC:
  72640. + Images from sensor will be frist recieved in memory,then
  72641. + queue to ipu device for processing if needed, and displaying
  72642. + it on synchronous display with SDC use case.
  72643. +
  72644. +config MXC_IPU_PRP_VF_SDC
  72645. + bool "Pre-Processor VF SDC library"
  72646. + depends on VIDEO_MXC_IPU_CAMERA
  72647. + ---help---
  72648. + Use case PRP_VF_SDC:
  72649. + Preprocessing image from smart sensor for viewfinder and
  72650. + displaying it on synchronous display with SDC use case.
  72651. + If SDC BG is selected, Rotation will not be supported.
  72652. + CSI -> IC (PRP VF) -> MEM
  72653. + MEM -> IC (ROT) -> MEM
  72654. + MEM -> SDC (FG/BG)
  72655. +
  72656. +endchoice
  72657. +
  72658. +config MXC_IPU_PRP_ENC
  72659. + tristate "Pre-processor Encoder library"
  72660. + depends on VIDEO_MXC_IPU_CAMERA
  72661. + default y
  72662. + ---help---
  72663. + Use case PRP_ENC:
  72664. + Preprocessing image from smart sensor for encoder.
  72665. + CSI -> IC (PRP ENC) -> MEM
  72666. +
  72667. +config MXC_IPU_CSI_ENC
  72668. + tristate "IPU CSI Encoder library"
  72669. + depends on VIDEO_MXC_IPU_CAMERA
  72670. + default y
  72671. + ---help---
  72672. + Use case IPU_CSI_ENC:
  72673. + Get raw image with CSI from smart sensor for encoder.
  72674. + CSI -> MEM
  72675. +endmenu
  72676. +
  72677. +endif
  72678. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/Makefile linux-imx6-3.14/drivers/media/platform/mxc/capture/Makefile
  72679. --- linux-3.14.14/drivers/media/platform/mxc/capture/Makefile 1969-12-31 18:00:00.000000000 -0600
  72680. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/Makefile 2014-12-08 00:31:53.252418001 -0600
  72681. @@ -0,0 +1,21 @@
  72682. +obj-$(CONFIG_VIDEO_MXC_CSI_CAMERA) += fsl_csi.o csi_v4l2_capture.o
  72683. +
  72684. +ifeq ($(CONFIG_VIDEO_MXC_IPU_CAMERA),y)
  72685. + obj-$(CONFIG_VIDEO_MXC_CAPTURE) += mxc_v4l2_capture.o
  72686. + obj-$(CONFIG_MXC_IPU_PRP_VF_SDC) += ipu_prp_vf_sdc.o ipu_prp_vf_sdc_bg.o
  72687. + obj-$(CONFIG_MXC_IPU_DEVICE_QUEUE_SDC) += ipu_fg_overlay_sdc.o ipu_bg_overlay_sdc.o
  72688. + obj-$(CONFIG_MXC_IPU_PRP_ENC) += ipu_prp_enc.o ipu_still.o
  72689. + obj-$(CONFIG_MXC_IPU_CSI_ENC) += ipu_csi_enc.o ipu_still.o
  72690. +endif
  72691. +
  72692. +ov5640_camera-objs := ov5640.o
  72693. +obj-$(CONFIG_MXC_CAMERA_OV5640) += ov5640_camera.o
  72694. +
  72695. +ov5642_camera-objs := ov5642.o
  72696. +obj-$(CONFIG_MXC_CAMERA_OV5642) += ov5642_camera.o
  72697. +
  72698. +ov5640_camera_mipi-objs := ov5640_mipi.o
  72699. +obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI) += ov5640_camera_mipi.o
  72700. +
  72701. +adv7180_tvin-objs := adv7180.o
  72702. +obj-$(CONFIG_MXC_TVIN_ADV7180) += adv7180_tvin.o
  72703. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c linux-imx6-3.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c
  72704. --- linux-3.14.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c 1969-12-31 18:00:00.000000000 -0600
  72705. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c 2014-12-08 00:31:53.256418001 -0600
  72706. @@ -0,0 +1,3102 @@
  72707. +/*
  72708. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  72709. + */
  72710. +
  72711. +/*
  72712. + * The code contained herein is licensed under the GNU General Public
  72713. + * License. You may obtain a copy of the GNU General Public License
  72714. + * Version 2 or later at the following locations:
  72715. + *
  72716. + * http://www.opensource.org/licenses/gpl-license.html
  72717. + * http://www.gnu.org/copyleft/gpl.html
  72718. + */
  72719. +
  72720. +/*!
  72721. + * @file drivers/media/video/mxc/capture/mxc_v4l2_capture.c
  72722. + *
  72723. + * @brief Mxc Video For Linux 2 driver
  72724. + *
  72725. + * @ingroup MXC_V4L2_CAPTURE
  72726. + */
  72727. +#include <linux/version.h>
  72728. +#include <linux/module.h>
  72729. +#include <linux/init.h>
  72730. +#include <linux/platform_device.h>
  72731. +#include <linux/fs.h>
  72732. +#include <linux/slab.h>
  72733. +#include <linux/ctype.h>
  72734. +#include <linux/clk.h>
  72735. +#include <linux/io.h>
  72736. +#include <linux/semaphore.h>
  72737. +#include <linux/pagemap.h>
  72738. +#include <linux/vmalloc.h>
  72739. +#include <linux/types.h>
  72740. +#include <linux/fb.h>
  72741. +#include <linux/dma-mapping.h>
  72742. +#include <linux/delay.h>
  72743. +#include <linux/mxcfb.h>
  72744. +#include <linux/of_device.h>
  72745. +#include <media/v4l2-chip-ident.h>
  72746. +#include <media/v4l2-ioctl.h>
  72747. +#include <media/v4l2-int-device.h>
  72748. +#include <linux/fsl_devices.h>
  72749. +#include "mxc_v4l2_capture.h"
  72750. +#include "ipu_prp_sw.h"
  72751. +
  72752. +#define init_MUTEX(sem) sema_init(sem, 1)
  72753. +
  72754. +static struct platform_device_id imx_v4l2_devtype[] = {
  72755. + {
  72756. + .name = "v4l2-capture-imx5",
  72757. + .driver_data = IMX5_V4L2,
  72758. + }, {
  72759. + .name = "v4l2-capture-imx6",
  72760. + .driver_data = IMX6_V4L2,
  72761. + }, {
  72762. + /* sentinel */
  72763. + }
  72764. +};
  72765. +MODULE_DEVICE_TABLE(platform, imx_v4l2_devtype);
  72766. +
  72767. +static const struct of_device_id mxc_v4l2_dt_ids[] = {
  72768. + {
  72769. + .compatible = "fsl,imx6q-v4l2-capture",
  72770. + .data = &imx_v4l2_devtype[IMX6_V4L2],
  72771. + }, {
  72772. + /* sentinel */
  72773. + }
  72774. +};
  72775. +MODULE_DEVICE_TABLE(of, mxc_v4l2_dt_ids);
  72776. +
  72777. +static int video_nr = -1;
  72778. +
  72779. +/*! This data is used for the output to the display. */
  72780. +#define MXC_V4L2_CAPTURE_NUM_OUTPUTS 6
  72781. +#define MXC_V4L2_CAPTURE_NUM_INPUTS 2
  72782. +static struct v4l2_output mxc_capture_outputs[MXC_V4L2_CAPTURE_NUM_OUTPUTS] = {
  72783. + {
  72784. + .index = 0,
  72785. + .name = "DISP3 BG",
  72786. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72787. + .audioset = 0,
  72788. + .modulator = 0,
  72789. + .std = V4L2_STD_UNKNOWN,
  72790. + },
  72791. + {
  72792. + .index = 1,
  72793. + .name = "DISP3 BG - DI1",
  72794. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72795. + .audioset = 0,
  72796. + .modulator = 0,
  72797. + .std = V4L2_STD_UNKNOWN,
  72798. + },
  72799. + {
  72800. + .index = 2,
  72801. + .name = "DISP3 FG",
  72802. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72803. + .audioset = 0,
  72804. + .modulator = 0,
  72805. + .std = V4L2_STD_UNKNOWN,
  72806. + },
  72807. + {
  72808. + .index = 3,
  72809. + .name = "DISP4 BG",
  72810. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72811. + .audioset = 0,
  72812. + .modulator = 0,
  72813. + .std = V4L2_STD_UNKNOWN,
  72814. + },
  72815. + {
  72816. + .index = 4,
  72817. + .name = "DISP4 BG - DI1",
  72818. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72819. + .audioset = 0,
  72820. + .modulator = 0,
  72821. + .std = V4L2_STD_UNKNOWN,
  72822. + },
  72823. + {
  72824. + .index = 5,
  72825. + .name = "DISP4 FG",
  72826. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  72827. + .audioset = 0,
  72828. + .modulator = 0,
  72829. + .std = V4L2_STD_UNKNOWN,
  72830. + },
  72831. +};
  72832. +
  72833. +static struct v4l2_input mxc_capture_inputs[MXC_V4L2_CAPTURE_NUM_INPUTS] = {
  72834. + {
  72835. + .index = 0,
  72836. + .name = "CSI IC MEM",
  72837. + .type = V4L2_INPUT_TYPE_CAMERA,
  72838. + .audioset = 0,
  72839. + .tuner = 0,
  72840. + .std = V4L2_STD_UNKNOWN,
  72841. + .status = 0,
  72842. + },
  72843. + {
  72844. + .index = 1,
  72845. + .name = "CSI MEM",
  72846. + .type = V4L2_INPUT_TYPE_CAMERA,
  72847. + .audioset = 0,
  72848. + .tuner = 0,
  72849. + .std = V4L2_STD_UNKNOWN,
  72850. + .status = V4L2_IN_ST_NO_POWER,
  72851. + },
  72852. +};
  72853. +
  72854. +/*! List of TV input video formats supported. The video formats is corresponding
  72855. + * to the v4l2_id in video_fmt_t.
  72856. + * Currently, only PAL and NTSC is supported. Needs to be expanded in the
  72857. + * future.
  72858. + */
  72859. +typedef enum {
  72860. + TV_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
  72861. + TV_PAL, /*!< (B, G, H, I, N)PAL video signal. */
  72862. + TV_NOT_LOCKED, /*!< Not locked on a signal. */
  72863. +} video_fmt_idx;
  72864. +
  72865. +/*! Number of video standards supported (including 'not locked' signal). */
  72866. +#define TV_STD_MAX (TV_NOT_LOCKED + 1)
  72867. +
  72868. +/*! Video format structure. */
  72869. +typedef struct {
  72870. + int v4l2_id; /*!< Video for linux ID. */
  72871. + char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
  72872. + u16 raw_width; /*!< Raw width. */
  72873. + u16 raw_height; /*!< Raw height. */
  72874. + u16 active_width; /*!< Active width. */
  72875. + u16 active_height; /*!< Active height. */
  72876. + u16 active_top; /*!< Active top. */
  72877. + u16 active_left; /*!< Active left. */
  72878. +} video_fmt_t;
  72879. +
  72880. +/*!
  72881. + * Description of video formats supported.
  72882. + *
  72883. + * PAL: raw=720x625, active=720x576.
  72884. + * NTSC: raw=720x525, active=720x480.
  72885. + */
  72886. +static video_fmt_t video_fmts[] = {
  72887. + { /*! NTSC */
  72888. + .v4l2_id = V4L2_STD_NTSC,
  72889. + .name = "NTSC",
  72890. + .raw_width = 720, /* SENS_FRM_WIDTH */
  72891. + .raw_height = 525, /* SENS_FRM_HEIGHT */
  72892. + .active_width = 720, /* ACT_FRM_WIDTH */
  72893. + .active_height = 480, /* ACT_FRM_HEIGHT */
  72894. + .active_top = 13,
  72895. + .active_left = 0,
  72896. + },
  72897. + { /*! (B, G, H, I, N) PAL */
  72898. + .v4l2_id = V4L2_STD_PAL,
  72899. + .name = "PAL",
  72900. + .raw_width = 720,
  72901. + .raw_height = 625,
  72902. + .active_width = 720,
  72903. + .active_height = 576,
  72904. + .active_top = 0,
  72905. + .active_left = 0,
  72906. + },
  72907. + { /*! Unlocked standard */
  72908. + .v4l2_id = V4L2_STD_ALL,
  72909. + .name = "Autodetect",
  72910. + .raw_width = 720,
  72911. + .raw_height = 625,
  72912. + .active_width = 720,
  72913. + .active_height = 576,
  72914. + .active_top = 0,
  72915. + .active_left = 0,
  72916. + },
  72917. +};
  72918. +
  72919. +/*!* Standard index of TV. */
  72920. +static video_fmt_idx video_index = TV_NOT_LOCKED;
  72921. +
  72922. +static int mxc_v4l2_master_attach(struct v4l2_int_device *slave);
  72923. +static void mxc_v4l2_master_detach(struct v4l2_int_device *slave);
  72924. +static int start_preview(cam_data *cam);
  72925. +static int stop_preview(cam_data *cam);
  72926. +
  72927. +/*! Information about this driver. */
  72928. +static struct v4l2_int_master mxc_v4l2_master = {
  72929. + .attach = mxc_v4l2_master_attach,
  72930. + .detach = mxc_v4l2_master_detach,
  72931. +};
  72932. +
  72933. +/***************************************************************************
  72934. + * Functions for handling Frame buffers.
  72935. + **************************************************************************/
  72936. +
  72937. +/*!
  72938. + * Free frame buffers
  72939. + *
  72940. + * @param cam Structure cam_data *
  72941. + *
  72942. + * @return status 0 success.
  72943. + */
  72944. +static int mxc_free_frame_buf(cam_data *cam)
  72945. +{
  72946. + int i;
  72947. +
  72948. + pr_debug("MVC: In mxc_free_frame_buf\n");
  72949. +
  72950. + for (i = 0; i < FRAME_NUM; i++) {
  72951. + if (cam->frame[i].vaddress != 0) {
  72952. + dma_free_coherent(0, cam->frame[i].buffer.length,
  72953. + cam->frame[i].vaddress,
  72954. + cam->frame[i].paddress);
  72955. + cam->frame[i].vaddress = 0;
  72956. + }
  72957. + }
  72958. +
  72959. + return 0;
  72960. +}
  72961. +
  72962. +/*!
  72963. + * Allocate frame buffers
  72964. + *
  72965. + * @param cam Structure cam_data*
  72966. + * @param count int number of buffer need to allocated
  72967. + *
  72968. + * @return status -0 Successfully allocated a buffer, -ENOBUFS failed.
  72969. + */
  72970. +static int mxc_allocate_frame_buf(cam_data *cam, int count)
  72971. +{
  72972. + int i;
  72973. +
  72974. + pr_debug("In MVC:mxc_allocate_frame_buf - size=%d\n",
  72975. + cam->v2f.fmt.pix.sizeimage);
  72976. +
  72977. + for (i = 0; i < count; i++) {
  72978. + cam->frame[i].vaddress =
  72979. + dma_alloc_coherent(0,
  72980. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  72981. + &cam->frame[i].paddress,
  72982. + GFP_DMA | GFP_KERNEL);
  72983. + if (cam->frame[i].vaddress == 0) {
  72984. + pr_err("ERROR: v4l2 capture: "
  72985. + "mxc_allocate_frame_buf failed.\n");
  72986. + mxc_free_frame_buf(cam);
  72987. + return -ENOBUFS;
  72988. + }
  72989. + cam->frame[i].buffer.index = i;
  72990. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  72991. + cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  72992. + cam->frame[i].buffer.length =
  72993. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  72994. + cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP;
  72995. + cam->frame[i].buffer.m.offset = cam->frame[i].paddress;
  72996. + cam->frame[i].index = i;
  72997. + }
  72998. +
  72999. + return 0;
  73000. +}
  73001. +
  73002. +/*!
  73003. + * Free frame buffers status
  73004. + *
  73005. + * @param cam Structure cam_data *
  73006. + *
  73007. + * @return none
  73008. + */
  73009. +static void mxc_free_frames(cam_data *cam)
  73010. +{
  73011. + int i;
  73012. +
  73013. + pr_debug("In MVC:mxc_free_frames\n");
  73014. +
  73015. + for (i = 0; i < FRAME_NUM; i++)
  73016. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  73017. +
  73018. + cam->enc_counter = 0;
  73019. + INIT_LIST_HEAD(&cam->ready_q);
  73020. + INIT_LIST_HEAD(&cam->working_q);
  73021. + INIT_LIST_HEAD(&cam->done_q);
  73022. +}
  73023. +
  73024. +/*!
  73025. + * Return the buffer status
  73026. + *
  73027. + * @param cam Structure cam_data *
  73028. + * @param buf Structure v4l2_buffer *
  73029. + *
  73030. + * @return status 0 success, EINVAL failed.
  73031. + */
  73032. +static int mxc_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf)
  73033. +{
  73034. + pr_debug("In MVC:mxc_v4l2_buffer_status\n");
  73035. +
  73036. + if (buf->index < 0 || buf->index >= FRAME_NUM) {
  73037. + pr_err("ERROR: v4l2 capture: mxc_v4l2_buffer_status buffers "
  73038. + "not allocated\n");
  73039. + return -EINVAL;
  73040. + }
  73041. +
  73042. + memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf));
  73043. + return 0;
  73044. +}
  73045. +
  73046. +static int mxc_v4l2_release_bufs(cam_data *cam)
  73047. +{
  73048. + pr_debug("In MVC:mxc_v4l2_release_bufs\n");
  73049. + return 0;
  73050. +}
  73051. +
  73052. +static int mxc_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf)
  73053. +{
  73054. + pr_debug("In MVC:mxc_v4l2_prepare_bufs\n");
  73055. +
  73056. + if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length <
  73057. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage)) {
  73058. + pr_err("ERROR: v4l2 capture: mxc_v4l2_prepare_bufs buffers "
  73059. + "not allocated,index=%d, length=%d\n", buf->index,
  73060. + buf->length);
  73061. + return -EINVAL;
  73062. + }
  73063. +
  73064. + cam->frame[buf->index].buffer.index = buf->index;
  73065. + cam->frame[buf->index].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  73066. + cam->frame[buf->index].buffer.length = buf->length;
  73067. + cam->frame[buf->index].buffer.m.offset = cam->frame[buf->index].paddress
  73068. + = buf->m.offset;
  73069. + cam->frame[buf->index].buffer.type = buf->type;
  73070. + cam->frame[buf->index].buffer.memory = V4L2_MEMORY_USERPTR;
  73071. + cam->frame[buf->index].index = buf->index;
  73072. +
  73073. + return 0;
  73074. +}
  73075. +
  73076. +/***************************************************************************
  73077. + * Functions for handling the video stream.
  73078. + **************************************************************************/
  73079. +
  73080. +/*!
  73081. + * Indicates whether the palette is supported.
  73082. + *
  73083. + * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_BGR24 or V4L2_PIX_FMT_BGR32
  73084. + *
  73085. + * @return 0 if failed
  73086. + */
  73087. +static inline int valid_mode(u32 palette)
  73088. +{
  73089. + return ((palette == V4L2_PIX_FMT_RGB565) ||
  73090. + (palette == V4L2_PIX_FMT_BGR24) ||
  73091. + (palette == V4L2_PIX_FMT_RGB24) ||
  73092. + (palette == V4L2_PIX_FMT_BGR32) ||
  73093. + (palette == V4L2_PIX_FMT_RGB32) ||
  73094. + (palette == V4L2_PIX_FMT_YUV422P) ||
  73095. + (palette == V4L2_PIX_FMT_UYVY) ||
  73096. + (palette == V4L2_PIX_FMT_YUYV) ||
  73097. + (palette == V4L2_PIX_FMT_YUV420) ||
  73098. + (palette == V4L2_PIX_FMT_YVU420) ||
  73099. + (palette == V4L2_PIX_FMT_NV12));
  73100. +}
  73101. +
  73102. +/*!
  73103. + * Start the encoder job
  73104. + *
  73105. + * @param cam structure cam_data *
  73106. + *
  73107. + * @return status 0 Success
  73108. + */
  73109. +static int mxc_streamon(cam_data *cam)
  73110. +{
  73111. + struct mxc_v4l_frame *frame;
  73112. + unsigned long lock_flags;
  73113. + int err = 0;
  73114. +
  73115. + pr_debug("In MVC:mxc_streamon\n");
  73116. +
  73117. + if (NULL == cam) {
  73118. + pr_err("ERROR! cam parameter is NULL\n");
  73119. + return -1;
  73120. + }
  73121. +
  73122. + if (cam->capture_on) {
  73123. + pr_err("ERROR: v4l2 capture: Capture stream has been turned "
  73124. + " on\n");
  73125. + return -1;
  73126. + }
  73127. +
  73128. + if (list_empty(&cam->ready_q)) {
  73129. + pr_err("ERROR: v4l2 capture: mxc_streamon buffer has not been "
  73130. + "queued yet\n");
  73131. + return -EINVAL;
  73132. + }
  73133. + if (cam->enc_update_eba &&
  73134. + cam->ready_q.prev == cam->ready_q.next) {
  73135. + pr_err("ERROR: v4l2 capture: mxc_streamon buffer need "
  73136. + "ping pong at least two buffers\n");
  73137. + return -EINVAL;
  73138. + }
  73139. +
  73140. + cam->capture_pid = current->pid;
  73141. +
  73142. + if (cam->overlay_on == true)
  73143. + stop_preview(cam);
  73144. +
  73145. + if (cam->enc_enable) {
  73146. + err = cam->enc_enable(cam);
  73147. + if (err != 0)
  73148. + return err;
  73149. + }
  73150. +
  73151. + spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
  73152. + cam->ping_pong_csi = 0;
  73153. + cam->local_buf_num = 0;
  73154. + if (cam->enc_update_eba) {
  73155. + frame =
  73156. + list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  73157. + list_del(cam->ready_q.next);
  73158. + list_add_tail(&frame->queue, &cam->working_q);
  73159. + frame->ipu_buf_num = cam->ping_pong_csi;
  73160. + err = cam->enc_update_eba(cam->ipu, frame->buffer.m.offset,
  73161. + &cam->ping_pong_csi);
  73162. +
  73163. + frame =
  73164. + list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  73165. + list_del(cam->ready_q.next);
  73166. + list_add_tail(&frame->queue, &cam->working_q);
  73167. + frame->ipu_buf_num = cam->ping_pong_csi;
  73168. + err |= cam->enc_update_eba(cam->ipu, frame->buffer.m.offset,
  73169. + &cam->ping_pong_csi);
  73170. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  73171. + } else {
  73172. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  73173. + return -EINVAL;
  73174. + }
  73175. +
  73176. + if (cam->overlay_on == true)
  73177. + start_preview(cam);
  73178. +
  73179. + if (cam->enc_enable_csi) {
  73180. + err = cam->enc_enable_csi(cam);
  73181. + if (err != 0)
  73182. + return err;
  73183. + }
  73184. +
  73185. + cam->capture_on = true;
  73186. +
  73187. + return err;
  73188. +}
  73189. +
  73190. +/*!
  73191. + * Shut down the encoder job
  73192. + *
  73193. + * @param cam structure cam_data *
  73194. + *
  73195. + * @return status 0 Success
  73196. + */
  73197. +static int mxc_streamoff(cam_data *cam)
  73198. +{
  73199. + int err = 0;
  73200. +
  73201. + pr_debug("In MVC:mxc_streamoff\n");
  73202. +
  73203. + if (cam->capture_on == false)
  73204. + return 0;
  73205. +
  73206. + /* For both CSI--MEM and CSI--IC--MEM
  73207. + * 1. wait for idmac eof
  73208. + * 2. disable csi first
  73209. + * 3. disable idmac
  73210. + * 4. disable smfc (CSI--MEM channel)
  73211. + */
  73212. + if (mxc_capture_inputs[cam->current_input].name != NULL) {
  73213. + if (cam->enc_disable_csi) {
  73214. + err = cam->enc_disable_csi(cam);
  73215. + if (err != 0)
  73216. + return err;
  73217. + }
  73218. + if (cam->enc_disable) {
  73219. + err = cam->enc_disable(cam);
  73220. + if (err != 0)
  73221. + return err;
  73222. + }
  73223. + }
  73224. +
  73225. + mxc_free_frames(cam);
  73226. + mxc_capture_inputs[cam->current_input].status |= V4L2_IN_ST_NO_POWER;
  73227. + cam->capture_on = false;
  73228. + return err;
  73229. +}
  73230. +
  73231. +/*!
  73232. + * Valid and adjust the overlay window size, position
  73233. + *
  73234. + * @param cam structure cam_data *
  73235. + * @param win struct v4l2_window *
  73236. + *
  73237. + * @return 0
  73238. + */
  73239. +static int verify_preview(cam_data *cam, struct v4l2_window *win)
  73240. +{
  73241. + int i = 0, width_bound = 0, height_bound = 0;
  73242. + int *width, *height;
  73243. + unsigned int ipu_ch = CHAN_NONE;
  73244. + struct fb_info *bg_fbi = NULL, *fbi = NULL;
  73245. + bool foregound_fb = false;
  73246. + mm_segment_t old_fs;
  73247. +
  73248. + pr_debug("In MVC: verify_preview\n");
  73249. +
  73250. + do {
  73251. + fbi = (struct fb_info *)registered_fb[i];
  73252. + if (fbi == NULL) {
  73253. + pr_err("ERROR: verify_preview frame buffer NULL.\n");
  73254. + return -1;
  73255. + }
  73256. +
  73257. + /* Which DI supports 2 layers? */
  73258. + if (((strncmp(fbi->fix.id, "DISP3 BG", 8) == 0) &&
  73259. + (cam->output < 3)) ||
  73260. + ((strncmp(fbi->fix.id, "DISP4 BG", 8) == 0) &&
  73261. + (cam->output >= 3))) {
  73262. + if (fbi->fbops->fb_ioctl) {
  73263. + old_fs = get_fs();
  73264. + set_fs(KERNEL_DS);
  73265. + fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_IPU_CHAN,
  73266. + (unsigned long)&ipu_ch);
  73267. + set_fs(old_fs);
  73268. + }
  73269. + if (ipu_ch == MEM_BG_SYNC) {
  73270. + bg_fbi = fbi;
  73271. + pr_debug("Found background frame buffer.\n");
  73272. + }
  73273. + }
  73274. +
  73275. + /* Found the frame buffer to preview on. */
  73276. + if (strcmp(fbi->fix.id,
  73277. + mxc_capture_outputs[cam->output].name) == 0) {
  73278. + if (((strcmp(fbi->fix.id, "DISP3 FG") == 0) &&
  73279. + (cam->output < 3)) ||
  73280. + ((strcmp(fbi->fix.id, "DISP4 FG") == 0) &&
  73281. + (cam->output >= 3)))
  73282. + foregound_fb = true;
  73283. +
  73284. + cam->overlay_fb = fbi;
  73285. + break;
  73286. + }
  73287. + } while (++i < FB_MAX);
  73288. +
  73289. + if (foregound_fb) {
  73290. + width_bound = bg_fbi->var.xres;
  73291. + height_bound = bg_fbi->var.yres;
  73292. +
  73293. + if (win->w.width + win->w.left > bg_fbi->var.xres ||
  73294. + win->w.height + win->w.top > bg_fbi->var.yres) {
  73295. + pr_err("ERROR: FG window position exceeds.\n");
  73296. + return -1;
  73297. + }
  73298. + } else {
  73299. + /* 4 bytes alignment for BG */
  73300. + width_bound = cam->overlay_fb->var.xres;
  73301. + height_bound = cam->overlay_fb->var.yres;
  73302. +
  73303. + if (cam->overlay_fb->var.bits_per_pixel == 24)
  73304. + win->w.left -= win->w.left % 4;
  73305. + else if (cam->overlay_fb->var.bits_per_pixel == 16)
  73306. + win->w.left -= win->w.left % 2;
  73307. +
  73308. + if (win->w.width + win->w.left > cam->overlay_fb->var.xres)
  73309. + win->w.width = cam->overlay_fb->var.xres - win->w.left;
  73310. + if (win->w.height + win->w.top > cam->overlay_fb->var.yres)
  73311. + win->w.height = cam->overlay_fb->var.yres - win->w.top;
  73312. + }
  73313. +
  73314. + /* stride line limitation */
  73315. + win->w.height -= win->w.height % 8;
  73316. + win->w.width -= win->w.width % 8;
  73317. +
  73318. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  73319. + height = &win->w.width;
  73320. + width = &win->w.height;
  73321. + } else {
  73322. + width = &win->w.width;
  73323. + height = &win->w.height;
  73324. + }
  73325. +
  73326. + if (*width == 0 || *height == 0) {
  73327. + pr_err("ERROR: v4l2 capture: width or height"
  73328. + " too small.\n");
  73329. + return -EINVAL;
  73330. + }
  73331. +
  73332. + if ((cam->crop_bounds.width / *width > 8) ||
  73333. + ((cam->crop_bounds.width / *width == 8) &&
  73334. + (cam->crop_bounds.width % *width))) {
  73335. + *width = cam->crop_bounds.width / 8;
  73336. + if (*width % 8)
  73337. + *width += 8 - *width % 8;
  73338. + if (*width + win->w.left > width_bound) {
  73339. + pr_err("ERROR: v4l2 capture: width exceeds "
  73340. + "resize limit.\n");
  73341. + return -1;
  73342. + }
  73343. + pr_err("ERROR: v4l2 capture: width exceeds limit. "
  73344. + "Resize to %d.\n",
  73345. + *width);
  73346. + }
  73347. +
  73348. + if ((cam->crop_bounds.height / *height > 8) ||
  73349. + ((cam->crop_bounds.height / *height == 8) &&
  73350. + (cam->crop_bounds.height % *height))) {
  73351. + *height = cam->crop_bounds.height / 8;
  73352. + if (*height % 8)
  73353. + *height += 8 - *height % 8;
  73354. + if (*height + win->w.top > height_bound) {
  73355. + pr_err("ERROR: v4l2 capture: height exceeds "
  73356. + "resize limit.\n");
  73357. + return -1;
  73358. + }
  73359. + pr_err("ERROR: v4l2 capture: height exceeds limit "
  73360. + "resize to %d.\n",
  73361. + *height);
  73362. + }
  73363. +
  73364. + return 0;
  73365. +}
  73366. +
  73367. +/*!
  73368. + * start the viewfinder job
  73369. + *
  73370. + * @param cam structure cam_data *
  73371. + *
  73372. + * @return status 0 Success
  73373. + */
  73374. +static int start_preview(cam_data *cam)
  73375. +{
  73376. + int err = 0;
  73377. +
  73378. + pr_debug("MVC: start_preview\n");
  73379. +
  73380. + if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
  73381. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  73382. + err = prp_vf_sdc_select(cam);
  73383. + #else
  73384. + err = foreground_sdc_select(cam);
  73385. + #endif
  73386. + else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
  73387. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  73388. + err = prp_vf_sdc_select_bg(cam);
  73389. + #else
  73390. + err = bg_overlay_sdc_select(cam);
  73391. + #endif
  73392. + if (err != 0)
  73393. + return err;
  73394. +
  73395. + if (cam->vf_start_sdc) {
  73396. + err = cam->vf_start_sdc(cam);
  73397. + if (err != 0)
  73398. + return err;
  73399. + }
  73400. +
  73401. + if (cam->vf_enable_csi)
  73402. + err = cam->vf_enable_csi(cam);
  73403. +
  73404. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  73405. + __func__,
  73406. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  73407. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  73408. + __func__,
  73409. + cam->crop_bounds.width, cam->crop_bounds.height);
  73410. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  73411. + __func__,
  73412. + cam->crop_defrect.width, cam->crop_defrect.height);
  73413. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  73414. + __func__,
  73415. + cam->crop_current.width, cam->crop_current.height);
  73416. +
  73417. + return err;
  73418. +}
  73419. +
  73420. +/*!
  73421. + * shut down the viewfinder job
  73422. + *
  73423. + * @param cam structure cam_data *
  73424. + *
  73425. + * @return status 0 Success
  73426. + */
  73427. +static int stop_preview(cam_data *cam)
  73428. +{
  73429. + int err = 0;
  73430. +
  73431. + if (cam->vf_disable_csi) {
  73432. + err = cam->vf_disable_csi(cam);
  73433. + if (err != 0)
  73434. + return err;
  73435. + }
  73436. +
  73437. + if (cam->vf_stop_sdc) {
  73438. + err = cam->vf_stop_sdc(cam);
  73439. + if (err != 0)
  73440. + return err;
  73441. + }
  73442. +
  73443. + if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
  73444. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  73445. + err = prp_vf_sdc_deselect(cam);
  73446. + #else
  73447. + err = foreground_sdc_deselect(cam);
  73448. + #endif
  73449. + else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
  73450. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  73451. + err = prp_vf_sdc_deselect_bg(cam);
  73452. + #else
  73453. + err = bg_overlay_sdc_deselect(cam);
  73454. + #endif
  73455. +
  73456. + return err;
  73457. +}
  73458. +
  73459. +/***************************************************************************
  73460. + * VIDIOC Functions.
  73461. + **************************************************************************/
  73462. +
  73463. +/*!
  73464. + * V4L2 - mxc_v4l2_g_fmt function
  73465. + *
  73466. + * @param cam structure cam_data *
  73467. + *
  73468. + * @param f structure v4l2_format *
  73469. + *
  73470. + * @return status 0 success, EINVAL failed
  73471. + */
  73472. +static int mxc_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f)
  73473. +{
  73474. + int retval = 0;
  73475. +
  73476. + pr_debug("In MVC: mxc_v4l2_g_fmt type=%d\n", f->type);
  73477. +
  73478. + switch (f->type) {
  73479. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  73480. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  73481. + f->fmt.pix = cam->v2f.fmt.pix;
  73482. + break;
  73483. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  73484. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  73485. + f->fmt.win = cam->win;
  73486. + break;
  73487. + default:
  73488. + pr_debug(" type is invalid\n");
  73489. + retval = -EINVAL;
  73490. + }
  73491. +
  73492. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  73493. + __func__,
  73494. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  73495. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  73496. + __func__,
  73497. + cam->crop_bounds.width, cam->crop_bounds.height);
  73498. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  73499. + __func__,
  73500. + cam->crop_defrect.width, cam->crop_defrect.height);
  73501. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  73502. + __func__,
  73503. + cam->crop_current.width, cam->crop_current.height);
  73504. +
  73505. + return retval;
  73506. +}
  73507. +
  73508. +/*!
  73509. + * V4L2 - mxc_v4l2_s_fmt function
  73510. + *
  73511. + * @param cam structure cam_data *
  73512. + *
  73513. + * @param f structure v4l2_format *
  73514. + *
  73515. + * @return status 0 success, EINVAL failed
  73516. + */
  73517. +static int mxc_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
  73518. +{
  73519. + int retval = 0;
  73520. + int size = 0;
  73521. + int bytesperline = 0;
  73522. + int *width, *height;
  73523. +
  73524. + pr_debug("In MVC: mxc_v4l2_s_fmt\n");
  73525. +
  73526. + switch (f->type) {
  73527. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  73528. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  73529. + if (!valid_mode(f->fmt.pix.pixelformat)) {
  73530. + pr_err("ERROR: v4l2 capture: mxc_v4l2_s_fmt: format "
  73531. + "not supported\n");
  73532. + return -EINVAL;
  73533. + }
  73534. +
  73535. + /*
  73536. + * Force the capture window resolution to be crop bounds
  73537. + * for CSI MEM input mode.
  73538. + */
  73539. + if (strcmp(mxc_capture_inputs[cam->current_input].name,
  73540. + "CSI MEM") == 0) {
  73541. + f->fmt.pix.width = cam->crop_current.width;
  73542. + f->fmt.pix.height = cam->crop_current.height;
  73543. + }
  73544. +
  73545. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  73546. + height = &f->fmt.pix.width;
  73547. + width = &f->fmt.pix.height;
  73548. + } else {
  73549. + width = &f->fmt.pix.width;
  73550. + height = &f->fmt.pix.height;
  73551. + }
  73552. +
  73553. + /* stride line limitation */
  73554. + *width -= *width % 8;
  73555. + *height -= *height % 8;
  73556. +
  73557. + if (*width == 0 || *height == 0) {
  73558. + pr_err("ERROR: v4l2 capture: width or height"
  73559. + " too small.\n");
  73560. + return -EINVAL;
  73561. + }
  73562. +
  73563. + if ((cam->crop_current.width / *width > 8) ||
  73564. + ((cam->crop_current.width / *width == 8) &&
  73565. + (cam->crop_current.width % *width))) {
  73566. + *width = cam->crop_current.width / 8;
  73567. + if (*width % 8)
  73568. + *width += 8 - *width % 8;
  73569. + pr_err("ERROR: v4l2 capture: width exceeds limit "
  73570. + "resize to %d.\n",
  73571. + *width);
  73572. + }
  73573. +
  73574. + if ((cam->crop_current.height / *height > 8) ||
  73575. + ((cam->crop_current.height / *height == 8) &&
  73576. + (cam->crop_current.height % *height))) {
  73577. + *height = cam->crop_current.height / 8;
  73578. + if (*height % 8)
  73579. + *height += 8 - *height % 8;
  73580. + pr_err("ERROR: v4l2 capture: height exceeds limit "
  73581. + "resize to %d.\n",
  73582. + *height);
  73583. + }
  73584. +
  73585. + switch (f->fmt.pix.pixelformat) {
  73586. + case V4L2_PIX_FMT_RGB565:
  73587. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  73588. + bytesperline = f->fmt.pix.width * 2;
  73589. + break;
  73590. + case V4L2_PIX_FMT_BGR24:
  73591. + size = f->fmt.pix.width * f->fmt.pix.height * 3;
  73592. + bytesperline = f->fmt.pix.width * 3;
  73593. + break;
  73594. + case V4L2_PIX_FMT_RGB24:
  73595. + size = f->fmt.pix.width * f->fmt.pix.height * 3;
  73596. + bytesperline = f->fmt.pix.width * 3;
  73597. + break;
  73598. + case V4L2_PIX_FMT_BGR32:
  73599. + size = f->fmt.pix.width * f->fmt.pix.height * 4;
  73600. + bytesperline = f->fmt.pix.width * 4;
  73601. + break;
  73602. + case V4L2_PIX_FMT_RGB32:
  73603. + size = f->fmt.pix.width * f->fmt.pix.height * 4;
  73604. + bytesperline = f->fmt.pix.width * 4;
  73605. + break;
  73606. + case V4L2_PIX_FMT_YUV422P:
  73607. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  73608. + bytesperline = f->fmt.pix.width;
  73609. + break;
  73610. + case V4L2_PIX_FMT_UYVY:
  73611. + case V4L2_PIX_FMT_YUYV:
  73612. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  73613. + bytesperline = f->fmt.pix.width * 2;
  73614. + break;
  73615. + case V4L2_PIX_FMT_YUV420:
  73616. + case V4L2_PIX_FMT_YVU420:
  73617. + size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
  73618. + bytesperline = f->fmt.pix.width;
  73619. + break;
  73620. + case V4L2_PIX_FMT_NV12:
  73621. + size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
  73622. + bytesperline = f->fmt.pix.width;
  73623. + break;
  73624. + default:
  73625. + break;
  73626. + }
  73627. +
  73628. + if (f->fmt.pix.bytesperline < bytesperline)
  73629. + f->fmt.pix.bytesperline = bytesperline;
  73630. + else
  73631. + bytesperline = f->fmt.pix.bytesperline;
  73632. +
  73633. + if (f->fmt.pix.sizeimage < size)
  73634. + f->fmt.pix.sizeimage = size;
  73635. + else
  73636. + size = f->fmt.pix.sizeimage;
  73637. +
  73638. + cam->v2f.fmt.pix = f->fmt.pix;
  73639. +
  73640. + if (cam->v2f.fmt.pix.priv != 0) {
  73641. + if (copy_from_user(&cam->offset,
  73642. + (void *)cam->v2f.fmt.pix.priv,
  73643. + sizeof(cam->offset))) {
  73644. + retval = -EFAULT;
  73645. + break;
  73646. + }
  73647. + }
  73648. + break;
  73649. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  73650. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  73651. + retval = verify_preview(cam, &f->fmt.win);
  73652. + cam->win = f->fmt.win;
  73653. + break;
  73654. + default:
  73655. + retval = -EINVAL;
  73656. + }
  73657. +
  73658. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  73659. + __func__,
  73660. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  73661. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  73662. + __func__,
  73663. + cam->crop_bounds.width, cam->crop_bounds.height);
  73664. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  73665. + __func__,
  73666. + cam->crop_defrect.width, cam->crop_defrect.height);
  73667. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  73668. + __func__,
  73669. + cam->crop_current.width, cam->crop_current.height);
  73670. +
  73671. + return retval;
  73672. +}
  73673. +
  73674. +/*!
  73675. + * get control param
  73676. + *
  73677. + * @param cam structure cam_data *
  73678. + *
  73679. + * @param c structure v4l2_control *
  73680. + *
  73681. + * @return status 0 success, EINVAL failed
  73682. + */
  73683. +static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
  73684. +{
  73685. + int status = 0;
  73686. +
  73687. + pr_debug("In MVC:mxc_v4l2_g_ctrl\n");
  73688. +
  73689. + /* probably don't need to store the values that can be retrieved,
  73690. + * locally, but they are for now. */
  73691. + switch (c->id) {
  73692. + case V4L2_CID_HFLIP:
  73693. + /* This is handled in the ipu. */
  73694. + if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
  73695. + c->value = 1;
  73696. + break;
  73697. + case V4L2_CID_VFLIP:
  73698. + /* This is handled in the ipu. */
  73699. + if (cam->rotation == IPU_ROTATE_VERT_FLIP)
  73700. + c->value = 1;
  73701. + break;
  73702. + case V4L2_CID_MXC_ROT:
  73703. + /* This is handled in the ipu. */
  73704. + c->value = cam->rotation;
  73705. + break;
  73706. + case V4L2_CID_BRIGHTNESS:
  73707. + if (cam->sensor) {
  73708. + c->value = cam->bright;
  73709. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73710. + cam->bright = c->value;
  73711. + } else {
  73712. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73713. + status = -ENODEV;
  73714. + }
  73715. + break;
  73716. + case V4L2_CID_HUE:
  73717. + if (cam->sensor) {
  73718. + c->value = cam->hue;
  73719. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73720. + cam->hue = c->value;
  73721. + } else {
  73722. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73723. + status = -ENODEV;
  73724. + }
  73725. + break;
  73726. + case V4L2_CID_CONTRAST:
  73727. + if (cam->sensor) {
  73728. + c->value = cam->contrast;
  73729. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73730. + cam->contrast = c->value;
  73731. + } else {
  73732. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73733. + status = -ENODEV;
  73734. + }
  73735. + break;
  73736. + case V4L2_CID_SATURATION:
  73737. + if (cam->sensor) {
  73738. + c->value = cam->saturation;
  73739. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73740. + cam->saturation = c->value;
  73741. + } else {
  73742. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73743. + status = -ENODEV;
  73744. + }
  73745. + break;
  73746. + case V4L2_CID_RED_BALANCE:
  73747. + if (cam->sensor) {
  73748. + c->value = cam->red;
  73749. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73750. + cam->red = c->value;
  73751. + } else {
  73752. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73753. + status = -ENODEV;
  73754. + }
  73755. + break;
  73756. + case V4L2_CID_BLUE_BALANCE:
  73757. + if (cam->sensor) {
  73758. + c->value = cam->blue;
  73759. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73760. + cam->blue = c->value;
  73761. + } else {
  73762. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73763. + status = -ENODEV;
  73764. + }
  73765. + break;
  73766. + case V4L2_CID_BLACK_LEVEL:
  73767. + if (cam->sensor) {
  73768. + c->value = cam->ae_mode;
  73769. + status = vidioc_int_g_ctrl(cam->sensor, c);
  73770. + cam->ae_mode = c->value;
  73771. + } else {
  73772. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73773. + status = -ENODEV;
  73774. + }
  73775. + break;
  73776. + default:
  73777. + pr_err("ERROR: v4l2 capture: unsupported ioctrl!\n");
  73778. + }
  73779. +
  73780. + return status;
  73781. +}
  73782. +
  73783. +/*!
  73784. + * V4L2 - set_control function
  73785. + * V4L2_CID_PRIVATE_BASE is the extention for IPU preprocessing.
  73786. + * 0 for normal operation
  73787. + * 1 for vertical flip
  73788. + * 2 for horizontal flip
  73789. + * 3 for horizontal and vertical flip
  73790. + * 4 for 90 degree rotation
  73791. + * @param cam structure cam_data *
  73792. + *
  73793. + * @param c structure v4l2_control *
  73794. + *
  73795. + * @return status 0 success, EINVAL failed
  73796. + */
  73797. +static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
  73798. +{
  73799. + int i, ret = 0;
  73800. + int tmp_rotation = IPU_ROTATE_NONE;
  73801. + struct sensor_data *sensor_data;
  73802. +
  73803. + pr_debug("In MVC:mxc_v4l2_s_ctrl\n");
  73804. +
  73805. + switch (c->id) {
  73806. + case V4L2_CID_HFLIP:
  73807. + /* This is done by the IPU */
  73808. + if (c->value == 1) {
  73809. + if ((cam->rotation != IPU_ROTATE_VERT_FLIP) &&
  73810. + (cam->rotation != IPU_ROTATE_180))
  73811. + cam->rotation = IPU_ROTATE_HORIZ_FLIP;
  73812. + else
  73813. + cam->rotation = IPU_ROTATE_180;
  73814. + } else {
  73815. + if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
  73816. + cam->rotation = IPU_ROTATE_NONE;
  73817. + if (cam->rotation == IPU_ROTATE_180)
  73818. + cam->rotation = IPU_ROTATE_VERT_FLIP;
  73819. + }
  73820. + break;
  73821. + case V4L2_CID_VFLIP:
  73822. + /* This is done by the IPU */
  73823. + if (c->value == 1) {
  73824. + if ((cam->rotation != IPU_ROTATE_HORIZ_FLIP) &&
  73825. + (cam->rotation != IPU_ROTATE_180))
  73826. + cam->rotation = IPU_ROTATE_VERT_FLIP;
  73827. + else
  73828. + cam->rotation = IPU_ROTATE_180;
  73829. + } else {
  73830. + if (cam->rotation == IPU_ROTATE_VERT_FLIP)
  73831. + cam->rotation = IPU_ROTATE_NONE;
  73832. + if (cam->rotation == IPU_ROTATE_180)
  73833. + cam->rotation = IPU_ROTATE_HORIZ_FLIP;
  73834. + }
  73835. + break;
  73836. + case V4L2_CID_MXC_ROT:
  73837. + case V4L2_CID_MXC_VF_ROT:
  73838. + /* This is done by the IPU */
  73839. + switch (c->value) {
  73840. + case V4L2_MXC_ROTATE_NONE:
  73841. + tmp_rotation = IPU_ROTATE_NONE;
  73842. + break;
  73843. + case V4L2_MXC_ROTATE_VERT_FLIP:
  73844. + tmp_rotation = IPU_ROTATE_VERT_FLIP;
  73845. + break;
  73846. + case V4L2_MXC_ROTATE_HORIZ_FLIP:
  73847. + tmp_rotation = IPU_ROTATE_HORIZ_FLIP;
  73848. + break;
  73849. + case V4L2_MXC_ROTATE_180:
  73850. + tmp_rotation = IPU_ROTATE_180;
  73851. + break;
  73852. + case V4L2_MXC_ROTATE_90_RIGHT:
  73853. + tmp_rotation = IPU_ROTATE_90_RIGHT;
  73854. + break;
  73855. + case V4L2_MXC_ROTATE_90_RIGHT_VFLIP:
  73856. + tmp_rotation = IPU_ROTATE_90_RIGHT_VFLIP;
  73857. + break;
  73858. + case V4L2_MXC_ROTATE_90_RIGHT_HFLIP:
  73859. + tmp_rotation = IPU_ROTATE_90_RIGHT_HFLIP;
  73860. + break;
  73861. + case V4L2_MXC_ROTATE_90_LEFT:
  73862. + tmp_rotation = IPU_ROTATE_90_LEFT;
  73863. + break;
  73864. + default:
  73865. + ret = -EINVAL;
  73866. + }
  73867. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  73868. + if (c->id == V4L2_CID_MXC_VF_ROT)
  73869. + cam->vf_rotation = tmp_rotation;
  73870. + else
  73871. + cam->rotation = tmp_rotation;
  73872. + #else
  73873. + cam->rotation = tmp_rotation;
  73874. + #endif
  73875. +
  73876. + break;
  73877. + case V4L2_CID_HUE:
  73878. + if (cam->sensor) {
  73879. + cam->hue = c->value;
  73880. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73881. + } else {
  73882. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73883. + ret = -ENODEV;
  73884. + }
  73885. + break;
  73886. + case V4L2_CID_CONTRAST:
  73887. + if (cam->sensor) {
  73888. + cam->contrast = c->value;
  73889. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73890. + } else {
  73891. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73892. + ret = -ENODEV;
  73893. + }
  73894. + break;
  73895. + case V4L2_CID_BRIGHTNESS:
  73896. + if (cam->sensor) {
  73897. + cam->bright = c->value;
  73898. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73899. + } else {
  73900. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73901. + ret = -ENODEV;
  73902. + }
  73903. + break;
  73904. + case V4L2_CID_SATURATION:
  73905. + if (cam->sensor) {
  73906. + cam->saturation = c->value;
  73907. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73908. + } else {
  73909. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73910. + ret = -ENODEV;
  73911. + }
  73912. + break;
  73913. + case V4L2_CID_RED_BALANCE:
  73914. + if (cam->sensor) {
  73915. + cam->red = c->value;
  73916. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73917. + } else {
  73918. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73919. + ret = -ENODEV;
  73920. + }
  73921. + break;
  73922. + case V4L2_CID_BLUE_BALANCE:
  73923. + if (cam->sensor) {
  73924. + cam->blue = c->value;
  73925. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73926. + } else {
  73927. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73928. + ret = -ENODEV;
  73929. + }
  73930. + break;
  73931. + case V4L2_CID_EXPOSURE:
  73932. + if (cam->sensor) {
  73933. + cam->ae_mode = c->value;
  73934. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  73935. + } else {
  73936. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  73937. + ret = -ENODEV;
  73938. + }
  73939. + break;
  73940. + case V4L2_CID_MXC_FLASH:
  73941. +#ifdef CONFIG_MXC_IPU_V1
  73942. + ipu_csi_flash_strobe(true);
  73943. +#endif
  73944. + break;
  73945. + case V4L2_CID_MXC_SWITCH_CAM:
  73946. + if (cam->sensor == cam->all_sensors[c->value])
  73947. + break;
  73948. +
  73949. + /* power down other cameraes before enable new one */
  73950. + for (i = 0; i < cam->sensor_index; i++) {
  73951. + if (i != c->value) {
  73952. + vidioc_int_dev_exit(cam->all_sensors[i]);
  73953. + vidioc_int_s_power(cam->all_sensors[i], 0);
  73954. + if (cam->mclk_on[cam->mclk_source]) {
  73955. + ipu_csi_enable_mclk_if(cam->ipu,
  73956. + CSI_MCLK_I2C,
  73957. + cam->mclk_source,
  73958. + false, false);
  73959. + cam->mclk_on[cam->mclk_source] =
  73960. + false;
  73961. + }
  73962. + }
  73963. + }
  73964. + sensor_data = cam->all_sensors[c->value]->priv;
  73965. + if (sensor_data->io_init)
  73966. + sensor_data->io_init();
  73967. + cam->sensor = cam->all_sensors[c->value];
  73968. + cam->mclk_source = sensor_data->mclk_source;
  73969. + ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
  73970. + cam->mclk_source, true, true);
  73971. + cam->mclk_on[cam->mclk_source] = true;
  73972. + vidioc_int_s_power(cam->sensor, 1);
  73973. + vidioc_int_dev_init(cam->sensor);
  73974. + break;
  73975. + default:
  73976. + pr_debug(" default case\n");
  73977. + ret = -EINVAL;
  73978. + break;
  73979. + }
  73980. +
  73981. + return ret;
  73982. +}
  73983. +
  73984. +/*!
  73985. + * V4L2 - mxc_v4l2_s_param function
  73986. + * Allows setting of capturemode and frame rate.
  73987. + *
  73988. + * @param cam structure cam_data *
  73989. + * @param parm structure v4l2_streamparm *
  73990. + *
  73991. + * @return status 0 success, EINVAL failed
  73992. + */
  73993. +static int mxc_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
  73994. +{
  73995. + struct v4l2_ifparm ifparm;
  73996. + struct v4l2_format cam_fmt;
  73997. + struct v4l2_streamparm currentparm;
  73998. + ipu_csi_signal_cfg_t csi_param;
  73999. + u32 current_fps, parm_fps;
  74000. + int err = 0;
  74001. +
  74002. + pr_debug("In mxc_v4l2_s_param\n");
  74003. +
  74004. + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  74005. + pr_err(KERN_ERR "mxc_v4l2_s_param invalid type\n");
  74006. + return -EINVAL;
  74007. + }
  74008. +
  74009. + /* Stop the viewfinder */
  74010. + if (cam->overlay_on == true)
  74011. + stop_preview(cam);
  74012. +
  74013. + currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  74014. +
  74015. + /* First check that this device can support the changes requested. */
  74016. + err = vidioc_int_g_parm(cam->sensor, &currentparm);
  74017. + if (err) {
  74018. + pr_err("%s: vidioc_int_g_parm returned an error %d\n",
  74019. + __func__, err);
  74020. + goto exit;
  74021. + }
  74022. +
  74023. + current_fps = currentparm.parm.capture.timeperframe.denominator
  74024. + / currentparm.parm.capture.timeperframe.numerator;
  74025. + parm_fps = parm->parm.capture.timeperframe.denominator
  74026. + / parm->parm.capture.timeperframe.numerator;
  74027. +
  74028. + pr_debug(" Current capabilities are %x\n",
  74029. + currentparm.parm.capture.capability);
  74030. + pr_debug(" Current capturemode is %d change to %d\n",
  74031. + currentparm.parm.capture.capturemode,
  74032. + parm->parm.capture.capturemode);
  74033. + pr_debug(" Current framerate is %d change to %d\n",
  74034. + current_fps, parm_fps);
  74035. +
  74036. + /* This will change any camera settings needed. */
  74037. + err = vidioc_int_s_parm(cam->sensor, parm);
  74038. + if (err) {
  74039. + pr_err("%s: vidioc_int_s_parm returned an error %d\n",
  74040. + __func__, err);
  74041. + goto exit;
  74042. + }
  74043. +
  74044. + /* If resolution changed, need to re-program the CSI */
  74045. + /* Get new values. */
  74046. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  74047. +
  74048. + csi_param.data_width = 0;
  74049. + csi_param.clk_mode = 0;
  74050. + csi_param.ext_vsync = 0;
  74051. + csi_param.Vsync_pol = 0;
  74052. + csi_param.Hsync_pol = 0;
  74053. + csi_param.pixclk_pol = 0;
  74054. + csi_param.data_pol = 0;
  74055. + csi_param.sens_clksrc = 0;
  74056. + csi_param.pack_tight = 0;
  74057. + csi_param.force_eof = 0;
  74058. + csi_param.data_en_pol = 0;
  74059. + csi_param.data_fmt = 0;
  74060. + csi_param.csi = cam->csi;
  74061. + csi_param.mclk = 0;
  74062. +
  74063. + pr_debug(" clock_curr=mclk=%d\n", ifparm.u.bt656.clock_curr);
  74064. + if (ifparm.u.bt656.clock_curr == 0)
  74065. + csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_INTERLACED;
  74066. + else
  74067. + csi_param.clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;
  74068. +
  74069. + csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
  74070. +
  74071. + if (ifparm.u.bt656.mode == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT) {
  74072. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  74073. + } else if (ifparm.u.bt656.mode
  74074. + == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT) {
  74075. + csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
  74076. + } else {
  74077. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  74078. + }
  74079. +
  74080. + csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
  74081. + csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
  74082. + csi_param.ext_vsync = ifparm.u.bt656.bt_sync_correct;
  74083. +
  74084. + /* if the capturemode changed, the size bounds will have changed. */
  74085. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  74086. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  74087. + pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n",
  74088. + cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
  74089. +
  74090. + csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
  74091. +
  74092. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  74093. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  74094. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  74095. +
  74096. + /*
  74097. + * Set the default current cropped resolution to be the same with
  74098. + * the cropping boundary(except for tvin module).
  74099. + */
  74100. + if (cam->device_type != 1) {
  74101. + cam->crop_current.width = cam->crop_bounds.width;
  74102. + cam->crop_current.height = cam->crop_bounds.height;
  74103. + }
  74104. +
  74105. + /* This essentially loses the data at the left and bottom of the image
  74106. + * giving a digital zoom image, if crop_current is less than the full
  74107. + * size of the image. */
  74108. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  74109. + cam->crop_current.height, cam->csi);
  74110. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  74111. + cam->crop_current.top,
  74112. + cam->csi);
  74113. + ipu_csi_init_interface(cam->ipu, cam->crop_bounds.width,
  74114. + cam->crop_bounds.height,
  74115. + cam_fmt.fmt.pix.pixelformat, csi_param);
  74116. +
  74117. +
  74118. +exit:
  74119. + if (cam->overlay_on == true)
  74120. + start_preview(cam);
  74121. +
  74122. + return err;
  74123. +}
  74124. +
  74125. +/*!
  74126. + * V4L2 - mxc_v4l2_s_std function
  74127. + *
  74128. + * Sets the TV standard to be used.
  74129. + *
  74130. + * @param cam structure cam_data *
  74131. + * @param parm structure v4l2_streamparm *
  74132. + *
  74133. + * @return status 0 success, EINVAL failed
  74134. + */
  74135. +static int mxc_v4l2_s_std(cam_data *cam, v4l2_std_id e)
  74136. +{
  74137. + pr_debug("In mxc_v4l2_s_std %Lx\n", e);
  74138. +
  74139. + if (e == V4L2_STD_PAL) {
  74140. + pr_debug(" Setting standard to PAL %Lx\n", V4L2_STD_PAL);
  74141. + cam->standard.id = V4L2_STD_PAL;
  74142. + video_index = TV_PAL;
  74143. + } else if (e == V4L2_STD_NTSC) {
  74144. + pr_debug(" Setting standard to NTSC %Lx\n",
  74145. + V4L2_STD_NTSC);
  74146. + /* Get rid of the white dot line in NTSC signal input */
  74147. + cam->standard.id = V4L2_STD_NTSC;
  74148. + video_index = TV_NTSC;
  74149. + } else {
  74150. + cam->standard.id = V4L2_STD_ALL;
  74151. + video_index = TV_NOT_LOCKED;
  74152. + pr_err("ERROR: unrecognized std! %Lx (PAL=%Lx, NTSC=%Lx\n",
  74153. + e, V4L2_STD_PAL, V4L2_STD_NTSC);
  74154. + }
  74155. +
  74156. + cam->standard.index = video_index;
  74157. + strcpy(cam->standard.name, video_fmts[video_index].name);
  74158. + cam->crop_bounds.width = video_fmts[video_index].raw_width;
  74159. + cam->crop_bounds.height = video_fmts[video_index].raw_height;
  74160. + cam->crop_current.width = video_fmts[video_index].active_width;
  74161. + cam->crop_current.height = video_fmts[video_index].active_height;
  74162. + cam->crop_current.top = video_fmts[video_index].active_top;
  74163. + cam->crop_current.left = video_fmts[video_index].active_left;
  74164. +
  74165. + return 0;
  74166. +}
  74167. +
  74168. +/*!
  74169. + * V4L2 - mxc_v4l2_g_std function
  74170. + *
  74171. + * Gets the TV standard from the TV input device.
  74172. + *
  74173. + * @param cam structure cam_data *
  74174. + *
  74175. + * @param e structure v4l2_streamparm *
  74176. + *
  74177. + * @return status 0 success, EINVAL failed
  74178. + */
  74179. +static int mxc_v4l2_g_std(cam_data *cam, v4l2_std_id *e)
  74180. +{
  74181. + struct v4l2_format tv_fmt;
  74182. +
  74183. + pr_debug("In mxc_v4l2_g_std\n");
  74184. +
  74185. + if (cam->device_type == 1) {
  74186. + /* Use this function to get what the TV-In device detects the
  74187. + * format to be. pixelformat is used to return the std value
  74188. + * since the interface has no vidioc_g_std.*/
  74189. + tv_fmt.type = V4L2_BUF_TYPE_PRIVATE;
  74190. + vidioc_int_g_fmt_cap(cam->sensor, &tv_fmt);
  74191. +
  74192. + /* If the TV-in automatically detects the standard, then if it
  74193. + * changes, the settings need to change. */
  74194. + if (cam->standard_autodetect) {
  74195. + if (cam->standard.id != tv_fmt.fmt.pix.pixelformat) {
  74196. + pr_debug("MVC: mxc_v4l2_g_std: "
  74197. + "Changing standard\n");
  74198. + mxc_v4l2_s_std(cam, tv_fmt.fmt.pix.pixelformat);
  74199. + }
  74200. + }
  74201. +
  74202. + *e = tv_fmt.fmt.pix.pixelformat;
  74203. + }
  74204. +
  74205. + return 0;
  74206. +}
  74207. +
  74208. +/*!
  74209. + * Dequeue one V4L capture buffer
  74210. + *
  74211. + * @param cam structure cam_data *
  74212. + * @param buf structure v4l2_buffer *
  74213. + *
  74214. + * @return status 0 success, EINVAL invalid frame number,
  74215. + * ETIME timeout, ERESTARTSYS interrupted by user
  74216. + */
  74217. +static int mxc_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
  74218. +{
  74219. + int retval = 0;
  74220. + struct mxc_v4l_frame *frame;
  74221. + unsigned long lock_flags;
  74222. +
  74223. + pr_debug("In MVC:mxc_v4l_dqueue\n");
  74224. +
  74225. + if (!wait_event_interruptible_timeout(cam->enc_queue,
  74226. + cam->enc_counter != 0, 10 * HZ)) {
  74227. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout "
  74228. + "enc_counter %x\n",
  74229. + cam->enc_counter);
  74230. + return -ETIME;
  74231. + } else if (signal_pending(current)) {
  74232. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() "
  74233. + "interrupt received\n");
  74234. + return -ERESTARTSYS;
  74235. + }
  74236. +
  74237. + if (down_interruptible(&cam->busy_lock))
  74238. + return -EBUSY;
  74239. +
  74240. + spin_lock_irqsave(&cam->dqueue_int_lock, lock_flags);
  74241. + cam->enc_counter--;
  74242. +
  74243. + frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue);
  74244. + list_del(cam->done_q.next);
  74245. + if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) {
  74246. + frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE;
  74247. + } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  74248. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  74249. + "Buffer not filled.\n");
  74250. + frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  74251. + retval = -EINVAL;
  74252. + } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) {
  74253. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  74254. + "Buffer not queued.\n");
  74255. + retval = -EINVAL;
  74256. + }
  74257. +
  74258. + cam->frame[frame->index].buffer.field = cam->device_type ?
  74259. + V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
  74260. +
  74261. + buf->bytesused = cam->v2f.fmt.pix.sizeimage;
  74262. + buf->index = frame->index;
  74263. + buf->flags = frame->buffer.flags;
  74264. + buf->m = cam->frame[frame->index].buffer.m;
  74265. + buf->timestamp = cam->frame[frame->index].buffer.timestamp;
  74266. + buf->field = cam->frame[frame->index].buffer.field;
  74267. + spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
  74268. +
  74269. + up(&cam->busy_lock);
  74270. + return retval;
  74271. +}
  74272. +
  74273. +/*!
  74274. + * V4L interface - open function
  74275. + *
  74276. + * @param file structure file *
  74277. + *
  74278. + * @return status 0 success, ENODEV invalid device instance,
  74279. + * ENODEV timeout, ERESTARTSYS interrupted by user
  74280. + */
  74281. +static int mxc_v4l_open(struct file *file)
  74282. +{
  74283. + struct v4l2_ifparm ifparm;
  74284. + struct v4l2_format cam_fmt;
  74285. + ipu_csi_signal_cfg_t csi_param;
  74286. + struct video_device *dev = video_devdata(file);
  74287. + cam_data *cam = video_get_drvdata(dev);
  74288. + int err = 0;
  74289. + struct sensor_data *sensor;
  74290. +
  74291. + pr_debug("\nIn MVC: mxc_v4l_open\n");
  74292. + pr_debug(" device name is %s\n", dev->name);
  74293. +
  74294. + if (!cam) {
  74295. + pr_err("ERROR: v4l2 capture: Internal error, "
  74296. + "cam_data not found!\n");
  74297. + return -EBADF;
  74298. + }
  74299. +
  74300. + if (cam->sensor == NULL ||
  74301. + cam->sensor->type != v4l2_int_type_slave) {
  74302. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  74303. + return -EAGAIN;
  74304. + }
  74305. +
  74306. + sensor = cam->sensor->priv;
  74307. + if (!sensor) {
  74308. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  74309. + return -EBADF;
  74310. + }
  74311. +
  74312. + down(&cam->busy_lock);
  74313. + err = 0;
  74314. + if (signal_pending(current))
  74315. + goto oops;
  74316. +
  74317. + if (cam->open_count++ == 0) {
  74318. + wait_event_interruptible(cam->power_queue,
  74319. + cam->low_power == false);
  74320. +
  74321. + if (strcmp(mxc_capture_inputs[cam->current_input].name,
  74322. + "CSI MEM") == 0) {
  74323. +#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  74324. + err = csi_enc_select(cam);
  74325. +#endif
  74326. + } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
  74327. + "CSI IC MEM") == 0) {
  74328. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
  74329. + err = prp_enc_select(cam);
  74330. +#endif
  74331. + }
  74332. +
  74333. + cam->enc_counter = 0;
  74334. + INIT_LIST_HEAD(&cam->ready_q);
  74335. + INIT_LIST_HEAD(&cam->working_q);
  74336. + INIT_LIST_HEAD(&cam->done_q);
  74337. +
  74338. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  74339. +
  74340. + csi_param.sens_clksrc = 0;
  74341. +
  74342. + csi_param.clk_mode = 0;
  74343. + csi_param.data_pol = 0;
  74344. + csi_param.ext_vsync = 0;
  74345. +
  74346. + csi_param.pack_tight = 0;
  74347. + csi_param.force_eof = 0;
  74348. + csi_param.data_en_pol = 0;
  74349. +
  74350. + csi_param.mclk = ifparm.u.bt656.clock_curr;
  74351. +
  74352. + csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
  74353. +
  74354. + if (ifparm.u.bt656.mode
  74355. + == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT)
  74356. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  74357. + else if (ifparm.u.bt656.mode
  74358. + == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT)
  74359. + csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
  74360. + else
  74361. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  74362. +
  74363. +
  74364. + csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
  74365. + csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
  74366. +
  74367. + csi_param.csi = cam->csi;
  74368. +
  74369. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  74370. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  74371. +
  74372. + /* Reset the sizes. Needed to prevent carryover of last
  74373. + * operation.*/
  74374. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  74375. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  74376. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  74377. +
  74378. + /* This also is the max crop size for this device. */
  74379. + cam->crop_defrect.top = cam->crop_defrect.left = 0;
  74380. + cam->crop_defrect.width = cam_fmt.fmt.pix.width;
  74381. + cam->crop_defrect.height = cam_fmt.fmt.pix.height;
  74382. +
  74383. + /* At this point, this is also the current image size. */
  74384. + cam->crop_current.top = cam->crop_current.left = 0;
  74385. + cam->crop_current.width = cam_fmt.fmt.pix.width;
  74386. + cam->crop_current.height = cam_fmt.fmt.pix.height;
  74387. +
  74388. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  74389. + __func__,
  74390. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  74391. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  74392. + __func__,
  74393. + cam->crop_bounds.width, cam->crop_bounds.height);
  74394. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  74395. + __func__,
  74396. + cam->crop_defrect.width, cam->crop_defrect.height);
  74397. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  74398. + __func__,
  74399. + cam->crop_current.width, cam->crop_current.height);
  74400. +
  74401. + csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
  74402. + pr_debug("On Open: Input to ipu size is %d x %d\n",
  74403. + cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
  74404. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  74405. + cam->crop_current.height,
  74406. + cam->csi);
  74407. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  74408. + cam->crop_current.top,
  74409. + cam->csi);
  74410. + ipu_csi_init_interface(cam->ipu, cam->crop_bounds.width,
  74411. + cam->crop_bounds.height,
  74412. + cam_fmt.fmt.pix.pixelformat,
  74413. + csi_param);
  74414. + clk_prepare_enable(sensor->sensor_clk);
  74415. + vidioc_int_s_power(cam->sensor, 1);
  74416. + vidioc_int_init(cam->sensor);
  74417. + vidioc_int_dev_init(cam->sensor);
  74418. + }
  74419. +
  74420. + file->private_data = dev;
  74421. +
  74422. +oops:
  74423. + up(&cam->busy_lock);
  74424. + return err;
  74425. +}
  74426. +
  74427. +/*!
  74428. + * V4L interface - close function
  74429. + *
  74430. + * @param file struct file *
  74431. + *
  74432. + * @return 0 success
  74433. + */
  74434. +static int mxc_v4l_close(struct file *file)
  74435. +{
  74436. + struct video_device *dev = video_devdata(file);
  74437. + int err = 0;
  74438. + cam_data *cam = video_get_drvdata(dev);
  74439. + struct sensor_data *sensor;
  74440. + pr_debug("In MVC:mxc_v4l_close\n");
  74441. +
  74442. + if (!cam) {
  74443. + pr_err("ERROR: v4l2 capture: Internal error, "
  74444. + "cam_data not found!\n");
  74445. + return -EBADF;
  74446. + }
  74447. +
  74448. + if (!cam->sensor) {
  74449. + pr_err("%s: Internal error, camera is not found!\n", __func__);
  74450. + return -EBADF;
  74451. + }
  74452. +
  74453. + sensor = cam->sensor->priv;
  74454. + if (!sensor) {
  74455. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  74456. + return -EBADF;
  74457. + }
  74458. +
  74459. + down(&cam->busy_lock);
  74460. +
  74461. + /* for the case somebody hit the ctrl C */
  74462. + if (cam->overlay_pid == current->pid && cam->overlay_on) {
  74463. + err = stop_preview(cam);
  74464. + cam->overlay_on = false;
  74465. + }
  74466. + if (cam->capture_pid == current->pid) {
  74467. + err |= mxc_streamoff(cam);
  74468. + wake_up_interruptible(&cam->enc_queue);
  74469. + }
  74470. +
  74471. + if (--cam->open_count == 0) {
  74472. + vidioc_int_s_power(cam->sensor, 0);
  74473. + clk_disable_unprepare(sensor->sensor_clk);
  74474. + wait_event_interruptible(cam->power_queue,
  74475. + cam->low_power == false);
  74476. + pr_debug("mxc_v4l_close: release resource\n");
  74477. +
  74478. + if (strcmp(mxc_capture_inputs[cam->current_input].name,
  74479. + "CSI MEM") == 0) {
  74480. +#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  74481. + err |= csi_enc_deselect(cam);
  74482. +#endif
  74483. + } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
  74484. + "CSI IC MEM") == 0) {
  74485. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
  74486. + err |= prp_enc_deselect(cam);
  74487. +#endif
  74488. + }
  74489. +
  74490. + mxc_free_frame_buf(cam);
  74491. + file->private_data = NULL;
  74492. +
  74493. + /* capture off */
  74494. + wake_up_interruptible(&cam->enc_queue);
  74495. + mxc_free_frames(cam);
  74496. + cam->enc_counter++;
  74497. + }
  74498. +
  74499. + up(&cam->busy_lock);
  74500. +
  74501. + return err;
  74502. +}
  74503. +
  74504. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC) || \
  74505. + defined(CONFIG_MXC_IPU_PRP_ENC_MODULE) || \
  74506. + defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  74507. +/*
  74508. + * V4L interface - read function
  74509. + *
  74510. + * @param file struct file *
  74511. + * @param read buf char *
  74512. + * @param count size_t
  74513. + * @param ppos structure loff_t *
  74514. + *
  74515. + * @return bytes read
  74516. + */
  74517. +static ssize_t mxc_v4l_read(struct file *file, char *buf, size_t count,
  74518. + loff_t *ppos)
  74519. +{
  74520. + int err = 0;
  74521. + u8 *v_address[2];
  74522. + struct video_device *dev = video_devdata(file);
  74523. + cam_data *cam = video_get_drvdata(dev);
  74524. +
  74525. + if (down_interruptible(&cam->busy_lock))
  74526. + return -EINTR;
  74527. +
  74528. + /* Stop the viewfinder */
  74529. + if (cam->overlay_on == true)
  74530. + stop_preview(cam);
  74531. +
  74532. + v_address[0] = dma_alloc_coherent(0,
  74533. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  74534. + &cam->still_buf[0],
  74535. + GFP_DMA | GFP_KERNEL);
  74536. +
  74537. + v_address[1] = dma_alloc_coherent(0,
  74538. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  74539. + &cam->still_buf[1],
  74540. + GFP_DMA | GFP_KERNEL);
  74541. +
  74542. + if (!v_address[0] || !v_address[1]) {
  74543. + err = -ENOBUFS;
  74544. + goto exit0;
  74545. + }
  74546. +
  74547. + err = prp_still_select(cam);
  74548. + if (err != 0) {
  74549. + err = -EIO;
  74550. + goto exit0;
  74551. + }
  74552. +
  74553. + cam->still_counter = 0;
  74554. + err = cam->csi_start(cam);
  74555. + if (err != 0) {
  74556. + err = -EIO;
  74557. + goto exit1;
  74558. + }
  74559. +
  74560. + if (!wait_event_interruptible_timeout(cam->still_queue,
  74561. + cam->still_counter != 0,
  74562. + 10 * HZ)) {
  74563. + pr_err("ERROR: v4l2 capture: mxc_v4l_read timeout counter %x\n",
  74564. + cam->still_counter);
  74565. + err = -ETIME;
  74566. + goto exit1;
  74567. + }
  74568. + err = copy_to_user(buf, v_address[1], cam->v2f.fmt.pix.sizeimage);
  74569. +
  74570. +exit1:
  74571. + prp_still_deselect(cam);
  74572. +
  74573. +exit0:
  74574. + if (v_address[0] != 0)
  74575. + dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[0],
  74576. + cam->still_buf[0]);
  74577. + if (v_address[1] != 0)
  74578. + dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[1],
  74579. + cam->still_buf[1]);
  74580. +
  74581. + cam->still_buf[0] = cam->still_buf[1] = 0;
  74582. +
  74583. + if (cam->overlay_on == true)
  74584. + start_preview(cam);
  74585. +
  74586. + up(&cam->busy_lock);
  74587. + if (err < 0)
  74588. + return err;
  74589. +
  74590. + return cam->v2f.fmt.pix.sizeimage - err;
  74591. +}
  74592. +#endif
  74593. +
  74594. +/*!
  74595. + * V4L interface - ioctl function
  74596. + *
  74597. + * @param file struct file*
  74598. + *
  74599. + * @param ioctlnr unsigned int
  74600. + *
  74601. + * @param arg void*
  74602. + *
  74603. + * @return 0 success, ENODEV for invalid device instance,
  74604. + * -1 for other errors.
  74605. + */
  74606. +static long mxc_v4l_do_ioctl(struct file *file,
  74607. + unsigned int ioctlnr, void *arg)
  74608. +{
  74609. + struct video_device *dev = video_devdata(file);
  74610. + cam_data *cam = video_get_drvdata(dev);
  74611. + int retval = 0;
  74612. + unsigned long lock_flags;
  74613. +
  74614. + pr_debug("In MVC: mxc_v4l_do_ioctl %x\n", ioctlnr);
  74615. + wait_event_interruptible(cam->power_queue, cam->low_power == false);
  74616. + /* make this _really_ smp-safe */
  74617. + if (ioctlnr != VIDIOC_DQBUF)
  74618. + if (down_interruptible(&cam->busy_lock))
  74619. + return -EBUSY;
  74620. +
  74621. + switch (ioctlnr) {
  74622. + /*!
  74623. + * V4l2 VIDIOC_QUERYCAP ioctl
  74624. + */
  74625. + case VIDIOC_QUERYCAP: {
  74626. + struct v4l2_capability *cap = arg;
  74627. + pr_debug(" case VIDIOC_QUERYCAP\n");
  74628. + strcpy(cap->driver, "mxc_v4l2");
  74629. + cap->version = KERNEL_VERSION(0, 1, 11);
  74630. + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
  74631. + V4L2_CAP_VIDEO_OVERLAY |
  74632. + V4L2_CAP_STREAMING |
  74633. + V4L2_CAP_READWRITE;
  74634. + cap->card[0] = '\0';
  74635. + cap->bus_info[0] = '\0';
  74636. + break;
  74637. + }
  74638. +
  74639. + /*!
  74640. + * V4l2 VIDIOC_G_FMT ioctl
  74641. + */
  74642. + case VIDIOC_G_FMT: {
  74643. + struct v4l2_format *gf = arg;
  74644. + pr_debug(" case VIDIOC_G_FMT\n");
  74645. + retval = mxc_v4l2_g_fmt(cam, gf);
  74646. + break;
  74647. + }
  74648. +
  74649. + /*!
  74650. + * V4l2 VIDIOC_S_FMT ioctl
  74651. + */
  74652. + case VIDIOC_S_FMT: {
  74653. + struct v4l2_format *sf = arg;
  74654. + pr_debug(" case VIDIOC_S_FMT\n");
  74655. + retval = mxc_v4l2_s_fmt(cam, sf);
  74656. + break;
  74657. + }
  74658. +
  74659. + /*!
  74660. + * V4l2 VIDIOC_REQBUFS ioctl
  74661. + */
  74662. + case VIDIOC_REQBUFS: {
  74663. + struct v4l2_requestbuffers *req = arg;
  74664. + pr_debug(" case VIDIOC_REQBUFS\n");
  74665. +
  74666. + if (req->count > FRAME_NUM) {
  74667. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  74668. + "not enough buffers\n");
  74669. + req->count = FRAME_NUM;
  74670. + }
  74671. +
  74672. + if ((req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
  74673. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  74674. + "wrong buffer type\n");
  74675. + retval = -EINVAL;
  74676. + break;
  74677. + }
  74678. +
  74679. + mxc_streamoff(cam);
  74680. + if (req->memory & V4L2_MEMORY_MMAP) {
  74681. + mxc_free_frame_buf(cam);
  74682. + retval = mxc_allocate_frame_buf(cam, req->count);
  74683. + }
  74684. + break;
  74685. + }
  74686. +
  74687. + /*!
  74688. + * V4l2 VIDIOC_QUERYBUF ioctl
  74689. + */
  74690. + case VIDIOC_QUERYBUF: {
  74691. + struct v4l2_buffer *buf = arg;
  74692. + int index = buf->index;
  74693. + pr_debug(" case VIDIOC_QUERYBUF\n");
  74694. +
  74695. + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  74696. + pr_err("ERROR: v4l2 capture: "
  74697. + "VIDIOC_QUERYBUFS: "
  74698. + "wrong buffer type\n");
  74699. + retval = -EINVAL;
  74700. + break;
  74701. + }
  74702. +
  74703. + if (buf->memory & V4L2_MEMORY_MMAP) {
  74704. + memset(buf, 0, sizeof(buf));
  74705. + buf->index = index;
  74706. + }
  74707. +
  74708. + down(&cam->param_lock);
  74709. + if (buf->memory & V4L2_MEMORY_USERPTR) {
  74710. + mxc_v4l2_release_bufs(cam);
  74711. + retval = mxc_v4l2_prepare_bufs(cam, buf);
  74712. + }
  74713. +
  74714. + if (buf->memory & V4L2_MEMORY_MMAP)
  74715. + retval = mxc_v4l2_buffer_status(cam, buf);
  74716. + up(&cam->param_lock);
  74717. + break;
  74718. + }
  74719. +
  74720. + /*!
  74721. + * V4l2 VIDIOC_QBUF ioctl
  74722. + */
  74723. + case VIDIOC_QBUF: {
  74724. + struct v4l2_buffer *buf = arg;
  74725. + int index = buf->index;
  74726. + pr_debug(" case VIDIOC_QBUF\n");
  74727. +
  74728. + spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
  74729. + if ((cam->frame[index].buffer.flags & 0x7) ==
  74730. + V4L2_BUF_FLAG_MAPPED) {
  74731. + cam->frame[index].buffer.flags |=
  74732. + V4L2_BUF_FLAG_QUEUED;
  74733. + list_add_tail(&cam->frame[index].queue,
  74734. + &cam->ready_q);
  74735. + } else if (cam->frame[index].buffer.
  74736. + flags & V4L2_BUF_FLAG_QUEUED) {
  74737. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  74738. + "buffer already queued\n");
  74739. + retval = -EINVAL;
  74740. + } else if (cam->frame[index].buffer.
  74741. + flags & V4L2_BUF_FLAG_DONE) {
  74742. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  74743. + "overwrite done buffer.\n");
  74744. + cam->frame[index].buffer.flags &=
  74745. + ~V4L2_BUF_FLAG_DONE;
  74746. + cam->frame[index].buffer.flags |=
  74747. + V4L2_BUF_FLAG_QUEUED;
  74748. + retval = -EINVAL;
  74749. + }
  74750. +
  74751. + buf->flags = cam->frame[index].buffer.flags;
  74752. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  74753. + break;
  74754. + }
  74755. +
  74756. + /*!
  74757. + * V4l2 VIDIOC_DQBUF ioctl
  74758. + */
  74759. + case VIDIOC_DQBUF: {
  74760. + struct v4l2_buffer *buf = arg;
  74761. + pr_debug(" case VIDIOC_DQBUF\n");
  74762. +
  74763. + if ((cam->enc_counter == 0) &&
  74764. + (file->f_flags & O_NONBLOCK)) {
  74765. + retval = -EAGAIN;
  74766. + break;
  74767. + }
  74768. +
  74769. + retval = mxc_v4l_dqueue(cam, buf);
  74770. + break;
  74771. + }
  74772. +
  74773. + /*!
  74774. + * V4l2 VIDIOC_STREAMON ioctl
  74775. + */
  74776. + case VIDIOC_STREAMON: {
  74777. + pr_debug(" case VIDIOC_STREAMON\n");
  74778. + retval = mxc_streamon(cam);
  74779. + break;
  74780. + }
  74781. +
  74782. + /*!
  74783. + * V4l2 VIDIOC_STREAMOFF ioctl
  74784. + */
  74785. + case VIDIOC_STREAMOFF: {
  74786. + pr_debug(" case VIDIOC_STREAMOFF\n");
  74787. + retval = mxc_streamoff(cam);
  74788. + break;
  74789. + }
  74790. +
  74791. + /*!
  74792. + * V4l2 VIDIOC_G_CTRL ioctl
  74793. + */
  74794. + case VIDIOC_G_CTRL: {
  74795. + pr_debug(" case VIDIOC_G_CTRL\n");
  74796. + retval = mxc_v4l2_g_ctrl(cam, arg);
  74797. + break;
  74798. + }
  74799. +
  74800. + /*!
  74801. + * V4l2 VIDIOC_S_CTRL ioctl
  74802. + */
  74803. + case VIDIOC_S_CTRL: {
  74804. + pr_debug(" case VIDIOC_S_CTRL\n");
  74805. + retval = mxc_v4l2_s_ctrl(cam, arg);
  74806. + break;
  74807. + }
  74808. +
  74809. + /*!
  74810. + * V4l2 VIDIOC_CROPCAP ioctl
  74811. + */
  74812. + case VIDIOC_CROPCAP: {
  74813. + struct v4l2_cropcap *cap = arg;
  74814. + pr_debug(" case VIDIOC_CROPCAP\n");
  74815. + if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  74816. + cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  74817. + retval = -EINVAL;
  74818. + break;
  74819. + }
  74820. + cap->bounds = cam->crop_bounds;
  74821. + cap->defrect = cam->crop_defrect;
  74822. + break;
  74823. + }
  74824. +
  74825. + /*!
  74826. + * V4l2 VIDIOC_G_CROP ioctl
  74827. + */
  74828. + case VIDIOC_G_CROP: {
  74829. + struct v4l2_crop *crop = arg;
  74830. + pr_debug(" case VIDIOC_G_CROP\n");
  74831. +
  74832. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  74833. + crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  74834. + retval = -EINVAL;
  74835. + break;
  74836. + }
  74837. + crop->c = cam->crop_current;
  74838. + break;
  74839. + }
  74840. +
  74841. + /*!
  74842. + * V4l2 VIDIOC_S_CROP ioctl
  74843. + */
  74844. + case VIDIOC_S_CROP: {
  74845. + struct v4l2_crop *crop = arg;
  74846. + struct v4l2_rect *b = &cam->crop_bounds;
  74847. + pr_debug(" case VIDIOC_S_CROP\n");
  74848. +
  74849. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  74850. + crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  74851. + retval = -EINVAL;
  74852. + break;
  74853. + }
  74854. +
  74855. + crop->c.top = (crop->c.top < b->top) ? b->top
  74856. + : crop->c.top;
  74857. + if (crop->c.top > b->top + b->height)
  74858. + crop->c.top = b->top + b->height - 1;
  74859. + if (crop->c.height > b->top + b->height - crop->c.top)
  74860. + crop->c.height =
  74861. + b->top + b->height - crop->c.top;
  74862. +
  74863. + crop->c.left = (crop->c.left < b->left) ? b->left
  74864. + : crop->c.left;
  74865. + if (crop->c.left > b->left + b->width)
  74866. + crop->c.left = b->left + b->width - 1;
  74867. + if (crop->c.width > b->left - crop->c.left + b->width)
  74868. + crop->c.width =
  74869. + b->left - crop->c.left + b->width;
  74870. +
  74871. + crop->c.width -= crop->c.width % 8;
  74872. + crop->c.left -= crop->c.left % 4;
  74873. + cam->crop_current = crop->c;
  74874. +
  74875. + pr_debug(" Cropping Input to ipu size %d x %d\n",
  74876. + cam->crop_current.width,
  74877. + cam->crop_current.height);
  74878. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  74879. + cam->crop_current.height,
  74880. + cam->csi);
  74881. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  74882. + cam->crop_current.top,
  74883. + cam->csi);
  74884. + break;
  74885. + }
  74886. +
  74887. + /*!
  74888. + * V4l2 VIDIOC_OVERLAY ioctl
  74889. + */
  74890. + case VIDIOC_OVERLAY: {
  74891. + int *on = arg;
  74892. + pr_debug(" VIDIOC_OVERLAY on=%d\n", *on);
  74893. + if (*on) {
  74894. + cam->overlay_on = true;
  74895. + cam->overlay_pid = current->pid;
  74896. + retval = start_preview(cam);
  74897. + }
  74898. + if (!*on) {
  74899. + retval = stop_preview(cam);
  74900. + cam->overlay_on = false;
  74901. + }
  74902. + break;
  74903. + }
  74904. +
  74905. + /*!
  74906. + * V4l2 VIDIOC_G_FBUF ioctl
  74907. + */
  74908. + case VIDIOC_G_FBUF: {
  74909. + struct v4l2_framebuffer *fb = arg;
  74910. + pr_debug(" case VIDIOC_G_FBUF\n");
  74911. + *fb = cam->v4l2_fb;
  74912. + fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
  74913. + break;
  74914. + }
  74915. +
  74916. + /*!
  74917. + * V4l2 VIDIOC_S_FBUF ioctl
  74918. + */
  74919. + case VIDIOC_S_FBUF: {
  74920. + struct v4l2_framebuffer *fb = arg;
  74921. + pr_debug(" case VIDIOC_S_FBUF\n");
  74922. + cam->v4l2_fb = *fb;
  74923. + break;
  74924. + }
  74925. +
  74926. + case VIDIOC_G_PARM: {
  74927. + struct v4l2_streamparm *parm = arg;
  74928. + pr_debug(" case VIDIOC_G_PARM\n");
  74929. + if (cam->sensor)
  74930. + retval = vidioc_int_g_parm(cam->sensor, parm);
  74931. + else {
  74932. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  74933. + retval = -ENODEV;
  74934. + }
  74935. + break;
  74936. + }
  74937. +
  74938. + case VIDIOC_S_PARM: {
  74939. + struct v4l2_streamparm *parm = arg;
  74940. + pr_debug(" case VIDIOC_S_PARM\n");
  74941. + if (cam->sensor)
  74942. + retval = mxc_v4l2_s_param(cam, parm);
  74943. + else {
  74944. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  74945. + retval = -ENODEV;
  74946. + }
  74947. + break;
  74948. + }
  74949. +
  74950. + /* linux v4l2 bug, kernel c0485619 user c0405619 */
  74951. + case VIDIOC_ENUMSTD: {
  74952. + struct v4l2_standard *e = arg;
  74953. + pr_debug(" case VIDIOC_ENUMSTD\n");
  74954. + *e = cam->standard;
  74955. + break;
  74956. + }
  74957. +
  74958. + case VIDIOC_G_STD: {
  74959. + v4l2_std_id *e = arg;
  74960. + pr_debug(" case VIDIOC_G_STD\n");
  74961. + if (cam->sensor)
  74962. + retval = mxc_v4l2_g_std(cam, e);
  74963. + else {
  74964. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  74965. + retval = -ENODEV;
  74966. + }
  74967. + break;
  74968. + }
  74969. +
  74970. + case VIDIOC_S_STD: {
  74971. + v4l2_std_id *e = arg;
  74972. + pr_debug(" case VIDIOC_S_STD\n");
  74973. + retval = mxc_v4l2_s_std(cam, *e);
  74974. +
  74975. + break;
  74976. + }
  74977. +
  74978. + case VIDIOC_ENUMOUTPUT: {
  74979. + struct v4l2_output *output = arg;
  74980. + pr_debug(" case VIDIOC_ENUMOUTPUT\n");
  74981. + if (output->index >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
  74982. + retval = -EINVAL;
  74983. + break;
  74984. + }
  74985. + *output = mxc_capture_outputs[output->index];
  74986. +
  74987. + break;
  74988. + }
  74989. + case VIDIOC_G_OUTPUT: {
  74990. + int *p_output_num = arg;
  74991. + pr_debug(" case VIDIOC_G_OUTPUT\n");
  74992. + *p_output_num = cam->output;
  74993. + break;
  74994. + }
  74995. +
  74996. + case VIDIOC_S_OUTPUT: {
  74997. + int *p_output_num = arg;
  74998. + pr_debug(" case VIDIOC_S_OUTPUT\n");
  74999. + if (*p_output_num >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
  75000. + retval = -EINVAL;
  75001. + break;
  75002. + }
  75003. + cam->output = *p_output_num;
  75004. + break;
  75005. + }
  75006. +
  75007. + case VIDIOC_ENUMINPUT: {
  75008. + struct v4l2_input *input = arg;
  75009. + pr_debug(" case VIDIOC_ENUMINPUT\n");
  75010. + if (input->index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
  75011. + retval = -EINVAL;
  75012. + break;
  75013. + }
  75014. + *input = mxc_capture_inputs[input->index];
  75015. + break;
  75016. + }
  75017. +
  75018. + case VIDIOC_G_INPUT: {
  75019. + int *index = arg;
  75020. + pr_debug(" case VIDIOC_G_INPUT\n");
  75021. + *index = cam->current_input;
  75022. + break;
  75023. + }
  75024. +
  75025. + case VIDIOC_S_INPUT: {
  75026. + int *index = arg;
  75027. + pr_debug(" case VIDIOC_S_INPUT\n");
  75028. + if (*index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
  75029. + retval = -EINVAL;
  75030. + break;
  75031. + }
  75032. +
  75033. + if (*index == cam->current_input)
  75034. + break;
  75035. +
  75036. + if ((mxc_capture_inputs[cam->current_input].status &
  75037. + V4L2_IN_ST_NO_POWER) == 0) {
  75038. + retval = mxc_streamoff(cam);
  75039. + if (retval)
  75040. + break;
  75041. + mxc_capture_inputs[cam->current_input].status |=
  75042. + V4L2_IN_ST_NO_POWER;
  75043. + }
  75044. +
  75045. + if (strcmp(mxc_capture_inputs[*index].name, "CSI MEM") == 0) {
  75046. +#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  75047. + retval = csi_enc_select(cam);
  75048. + if (retval)
  75049. + break;
  75050. +#endif
  75051. + } else if (strcmp(mxc_capture_inputs[*index].name,
  75052. + "CSI IC MEM") == 0) {
  75053. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
  75054. + retval = prp_enc_select(cam);
  75055. + if (retval)
  75056. + break;
  75057. +#endif
  75058. + }
  75059. +
  75060. + mxc_capture_inputs[*index].status &= ~V4L2_IN_ST_NO_POWER;
  75061. + cam->current_input = *index;
  75062. + break;
  75063. + }
  75064. + case VIDIOC_ENUM_FMT: {
  75065. + struct v4l2_fmtdesc *f = arg;
  75066. + if (cam->sensor)
  75067. + retval = vidioc_int_enum_fmt_cap(cam->sensor, f);
  75068. + else {
  75069. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  75070. + retval = -ENODEV;
  75071. + }
  75072. + break;
  75073. + }
  75074. + case VIDIOC_ENUM_FRAMESIZES: {
  75075. + struct v4l2_frmsizeenum *fsize = arg;
  75076. + if (cam->sensor)
  75077. + retval = vidioc_int_enum_framesizes(cam->sensor, fsize);
  75078. + else {
  75079. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  75080. + retval = -ENODEV;
  75081. + }
  75082. + break;
  75083. + }
  75084. + case VIDIOC_DBG_G_CHIP_IDENT: {
  75085. + struct v4l2_dbg_chip_ident *p = arg;
  75086. + p->ident = V4L2_IDENT_NONE;
  75087. + p->revision = 0;
  75088. + if (cam->sensor)
  75089. + retval = vidioc_int_g_chip_ident(cam->sensor, (int *)p);
  75090. + else {
  75091. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  75092. + retval = -ENODEV;
  75093. + }
  75094. + break;
  75095. + }
  75096. + case VIDIOC_TRY_FMT:
  75097. + case VIDIOC_QUERYCTRL:
  75098. + case VIDIOC_G_TUNER:
  75099. + case VIDIOC_S_TUNER:
  75100. + case VIDIOC_G_FREQUENCY:
  75101. + case VIDIOC_S_FREQUENCY:
  75102. + default:
  75103. + pr_debug(" case default or not supported\n");
  75104. + retval = -EINVAL;
  75105. + break;
  75106. + }
  75107. +
  75108. + if (ioctlnr != VIDIOC_DQBUF)
  75109. + up(&cam->busy_lock);
  75110. + return retval;
  75111. +}
  75112. +
  75113. +/*
  75114. + * V4L interface - ioctl function
  75115. + *
  75116. + * @return None
  75117. + */
  75118. +static long mxc_v4l_ioctl(struct file *file, unsigned int cmd,
  75119. + unsigned long arg)
  75120. +{
  75121. + pr_debug("In MVC:mxc_v4l_ioctl\n");
  75122. + return video_usercopy(file, cmd, arg, mxc_v4l_do_ioctl);
  75123. +}
  75124. +
  75125. +/*!
  75126. + * V4L interface - mmap function
  75127. + *
  75128. + * @param file structure file *
  75129. + *
  75130. + * @param vma structure vm_area_struct *
  75131. + *
  75132. + * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error
  75133. + */
  75134. +static int mxc_mmap(struct file *file, struct vm_area_struct *vma)
  75135. +{
  75136. + struct video_device *dev = video_devdata(file);
  75137. + unsigned long size;
  75138. + int res = 0;
  75139. + cam_data *cam = video_get_drvdata(dev);
  75140. +
  75141. + pr_debug("In MVC:mxc_mmap\n");
  75142. + pr_debug(" pgoff=0x%lx, start=0x%lx, end=0x%lx\n",
  75143. + vma->vm_pgoff, vma->vm_start, vma->vm_end);
  75144. +
  75145. + /* make this _really_ smp-safe */
  75146. + if (down_interruptible(&cam->busy_lock))
  75147. + return -EINTR;
  75148. +
  75149. + size = vma->vm_end - vma->vm_start;
  75150. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  75151. +
  75152. + if (remap_pfn_range(vma, vma->vm_start,
  75153. + vma->vm_pgoff, size, vma->vm_page_prot)) {
  75154. + pr_err("ERROR: v4l2 capture: mxc_mmap: "
  75155. + "remap_pfn_range failed\n");
  75156. + res = -ENOBUFS;
  75157. + goto mxc_mmap_exit;
  75158. + }
  75159. +
  75160. + vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
  75161. +
  75162. +mxc_mmap_exit:
  75163. + up(&cam->busy_lock);
  75164. + return res;
  75165. +}
  75166. +
  75167. +/*!
  75168. + * V4L interface - poll function
  75169. + *
  75170. + * @param file structure file *
  75171. + *
  75172. + * @param wait structure poll_table_struct *
  75173. + *
  75174. + * @return status POLLIN | POLLRDNORM
  75175. + */
  75176. +static unsigned int mxc_poll(struct file *file, struct poll_table_struct *wait)
  75177. +{
  75178. + struct video_device *dev = video_devdata(file);
  75179. + cam_data *cam = video_get_drvdata(dev);
  75180. + wait_queue_head_t *queue = NULL;
  75181. + int res = POLLIN | POLLRDNORM;
  75182. +
  75183. + pr_debug("In MVC:mxc_poll\n");
  75184. +
  75185. + if (down_interruptible(&cam->busy_lock))
  75186. + return -EINTR;
  75187. +
  75188. + queue = &cam->enc_queue;
  75189. + poll_wait(file, queue, wait);
  75190. +
  75191. + up(&cam->busy_lock);
  75192. +
  75193. + return res;
  75194. +}
  75195. +
  75196. +/*!
  75197. + * This structure defines the functions to be called in this driver.
  75198. + */
  75199. +static struct v4l2_file_operations mxc_v4l_fops = {
  75200. + .owner = THIS_MODULE,
  75201. + .open = mxc_v4l_open,
  75202. + .release = mxc_v4l_close,
  75203. + .read = mxc_v4l_read,
  75204. + .ioctl = mxc_v4l_ioctl,
  75205. + .mmap = mxc_mmap,
  75206. + .poll = mxc_poll,
  75207. +};
  75208. +
  75209. +static struct video_device mxc_v4l_template = {
  75210. + .name = "Mxc Camera",
  75211. + .fops = &mxc_v4l_fops,
  75212. + .release = video_device_release,
  75213. +};
  75214. +
  75215. +/*!
  75216. + * This function can be used to release any platform data on closing.
  75217. + */
  75218. +static void camera_platform_release(struct device *device)
  75219. +{
  75220. +}
  75221. +
  75222. +/*!
  75223. + * Camera V4l2 callback function.
  75224. + *
  75225. + * @param mask u32
  75226. + *
  75227. + * @param dev void device structure
  75228. + *
  75229. + * @return status
  75230. + */
  75231. +static void camera_callback(u32 mask, void *dev)
  75232. +{
  75233. + struct mxc_v4l_frame *done_frame;
  75234. + struct mxc_v4l_frame *ready_frame;
  75235. + struct timeval cur_time;
  75236. +
  75237. + cam_data *cam = (cam_data *) dev;
  75238. + if (cam == NULL)
  75239. + return;
  75240. +
  75241. + pr_debug("In MVC:camera_callback\n");
  75242. +
  75243. + spin_lock(&cam->queue_int_lock);
  75244. + spin_lock(&cam->dqueue_int_lock);
  75245. + if (!list_empty(&cam->working_q)) {
  75246. + do_gettimeofday(&cur_time);
  75247. +
  75248. + done_frame = list_entry(cam->working_q.next,
  75249. + struct mxc_v4l_frame,
  75250. + queue);
  75251. +
  75252. + if (done_frame->ipu_buf_num != cam->local_buf_num)
  75253. + goto next;
  75254. +
  75255. + /*
  75256. + * Set the current time to done frame buffer's
  75257. + * timestamp. Users can use this information to judge
  75258. + * the frame's usage.
  75259. + */
  75260. + done_frame->buffer.timestamp = cur_time;
  75261. +
  75262. + if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  75263. + done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE;
  75264. + done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  75265. +
  75266. + /* Added to the done queue */
  75267. + list_del(cam->working_q.next);
  75268. + list_add_tail(&done_frame->queue, &cam->done_q);
  75269. +
  75270. + /* Wake up the queue */
  75271. + cam->enc_counter++;
  75272. + wake_up_interruptible(&cam->enc_queue);
  75273. + } else
  75274. + pr_err("ERROR: v4l2 capture: camera_callback: "
  75275. + "buffer not queued\n");
  75276. + }
  75277. +
  75278. +next:
  75279. + if (!list_empty(&cam->ready_q)) {
  75280. + ready_frame = list_entry(cam->ready_q.next,
  75281. + struct mxc_v4l_frame,
  75282. + queue);
  75283. + if (cam->enc_update_eba)
  75284. + if (cam->enc_update_eba(cam->ipu,
  75285. + ready_frame->buffer.m.offset,
  75286. + &cam->ping_pong_csi) == 0) {
  75287. + list_del(cam->ready_q.next);
  75288. + list_add_tail(&ready_frame->queue,
  75289. + &cam->working_q);
  75290. + ready_frame->ipu_buf_num = cam->local_buf_num;
  75291. + }
  75292. + } else {
  75293. + if (cam->enc_update_eba)
  75294. + cam->enc_update_eba(
  75295. + cam->ipu, cam->dummy_frame.buffer.m.offset,
  75296. + &cam->ping_pong_csi);
  75297. + }
  75298. +
  75299. + cam->local_buf_num = (cam->local_buf_num == 0) ? 1 : 0;
  75300. + spin_unlock(&cam->dqueue_int_lock);
  75301. + spin_unlock(&cam->queue_int_lock);
  75302. +
  75303. + return;
  75304. +}
  75305. +
  75306. +/*!
  75307. + * initialize cam_data structure
  75308. + *
  75309. + * @param cam structure cam_data *
  75310. + *
  75311. + * @return status 0 Success
  75312. + */
  75313. +static int init_camera_struct(cam_data *cam, struct platform_device *pdev)
  75314. +{
  75315. + const struct of_device_id *of_id =
  75316. + of_match_device(mxc_v4l2_dt_ids, &pdev->dev);
  75317. + struct device_node *np = pdev->dev.of_node;
  75318. + int ipu_id, csi_id, mclk_source;
  75319. + int ret = 0;
  75320. +
  75321. + pr_debug("In MVC: init_camera_struct\n");
  75322. +
  75323. + ret = of_property_read_u32(np, "ipu_id", &ipu_id);
  75324. + if (ret) {
  75325. + dev_err(&pdev->dev, "ipu_id missing or invalid\n");
  75326. + return ret;
  75327. + }
  75328. +
  75329. + ret = of_property_read_u32(np, "csi_id", &csi_id);
  75330. + if (ret) {
  75331. + dev_err(&pdev->dev, "csi_id missing or invalid\n");
  75332. + return ret;
  75333. + }
  75334. +
  75335. + ret = of_property_read_u32(np, "mclk_source", &mclk_source);
  75336. + if (ret) {
  75337. + dev_err(&pdev->dev, "sensor mclk missing or invalid\n");
  75338. + return ret;
  75339. + }
  75340. +
  75341. + /* Default everything to 0 */
  75342. + memset(cam, 0, sizeof(cam_data));
  75343. +
  75344. + /* get devtype to distinguish if the cpu is imx5 or imx6
  75345. + * IMX5_V4L2 specify the cpu is imx5
  75346. + * IMX6_V4L2 specify the cpu is imx6q or imx6sdl
  75347. + */
  75348. + if (of_id)
  75349. + pdev->id_entry = of_id->data;
  75350. + cam->devtype = pdev->id_entry->driver_data;
  75351. +
  75352. + cam->ipu = ipu_get_soc(ipu_id);
  75353. + if (cam->ipu == NULL) {
  75354. + pr_err("ERROR: v4l2 capture: failed to get ipu\n");
  75355. + return -EINVAL;
  75356. + } else if (cam->ipu == ERR_PTR(-ENODEV)) {
  75357. + pr_err("ERROR: v4l2 capture: get invalid ipu\n");
  75358. + return -ENODEV;
  75359. + }
  75360. +
  75361. + init_MUTEX(&cam->param_lock);
  75362. + init_MUTEX(&cam->busy_lock);
  75363. +
  75364. + cam->video_dev = video_device_alloc();
  75365. + if (cam->video_dev == NULL)
  75366. + return -ENODEV;
  75367. +
  75368. + *(cam->video_dev) = mxc_v4l_template;
  75369. +
  75370. + video_set_drvdata(cam->video_dev, cam);
  75371. + dev_set_drvdata(&pdev->dev, (void *)cam);
  75372. + cam->video_dev->minor = -1;
  75373. +
  75374. + init_waitqueue_head(&cam->enc_queue);
  75375. + init_waitqueue_head(&cam->still_queue);
  75376. +
  75377. + /* setup cropping */
  75378. + cam->crop_bounds.left = 0;
  75379. + cam->crop_bounds.width = 640;
  75380. + cam->crop_bounds.top = 0;
  75381. + cam->crop_bounds.height = 480;
  75382. + cam->crop_current = cam->crop_defrect = cam->crop_bounds;
  75383. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  75384. + cam->crop_current.height, cam->csi);
  75385. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  75386. + cam->crop_current.top, cam->csi);
  75387. + cam->streamparm.parm.capture.capturemode = 0;
  75388. +
  75389. + cam->standard.index = 0;
  75390. + cam->standard.id = V4L2_STD_UNKNOWN;
  75391. + cam->standard.frameperiod.denominator = 30;
  75392. + cam->standard.frameperiod.numerator = 1;
  75393. + cam->standard.framelines = 480;
  75394. + cam->standard_autodetect = true;
  75395. + cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  75396. + cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
  75397. + cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
  75398. + cam->overlay_on = false;
  75399. + cam->capture_on = false;
  75400. + cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
  75401. +
  75402. + cam->v2f.fmt.pix.sizeimage = 352 * 288 * 3 / 2;
  75403. + cam->v2f.fmt.pix.bytesperline = 288 * 3 / 2;
  75404. + cam->v2f.fmt.pix.width = 288;
  75405. + cam->v2f.fmt.pix.height = 352;
  75406. + cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
  75407. + cam->win.w.width = 160;
  75408. + cam->win.w.height = 160;
  75409. + cam->win.w.left = 0;
  75410. + cam->win.w.top = 0;
  75411. +
  75412. + cam->ipu_id = ipu_id;
  75413. + cam->csi = csi_id;
  75414. + cam->mclk_source = mclk_source;
  75415. + cam->mclk_on[cam->mclk_source] = false;
  75416. +
  75417. + cam->enc_callback = camera_callback;
  75418. + init_waitqueue_head(&cam->power_queue);
  75419. + spin_lock_init(&cam->queue_int_lock);
  75420. + spin_lock_init(&cam->dqueue_int_lock);
  75421. +
  75422. + cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);
  75423. + cam->self->module = THIS_MODULE;
  75424. + sprintf(cam->self->name, "mxc_v4l2_cap%d", cam->csi);
  75425. + cam->self->type = v4l2_int_type_master;
  75426. + cam->self->u.master = &mxc_v4l2_master;
  75427. +
  75428. + return 0;
  75429. +}
  75430. +
  75431. +static ssize_t show_streaming(struct device *dev,
  75432. + struct device_attribute *attr, char *buf)
  75433. +{
  75434. + struct video_device *video_dev = container_of(dev,
  75435. + struct video_device, dev);
  75436. + cam_data *cam = video_get_drvdata(video_dev);
  75437. +
  75438. + if (cam->capture_on)
  75439. + return sprintf(buf, "stream on\n");
  75440. + else
  75441. + return sprintf(buf, "stream off\n");
  75442. +}
  75443. +static DEVICE_ATTR(fsl_v4l2_capture_property, S_IRUGO, show_streaming, NULL);
  75444. +
  75445. +static ssize_t show_overlay(struct device *dev,
  75446. + struct device_attribute *attr, char *buf)
  75447. +{
  75448. + struct video_device *video_dev = container_of(dev,
  75449. + struct video_device, dev);
  75450. + cam_data *cam = video_get_drvdata(video_dev);
  75451. +
  75452. + if (cam->overlay_on)
  75453. + return sprintf(buf, "overlay on\n");
  75454. + else
  75455. + return sprintf(buf, "overlay off\n");
  75456. +}
  75457. +static DEVICE_ATTR(fsl_v4l2_overlay_property, S_IRUGO, show_overlay, NULL);
  75458. +
  75459. +static ssize_t show_csi(struct device *dev,
  75460. + struct device_attribute *attr, char *buf)
  75461. +{
  75462. + struct video_device *video_dev = container_of(dev,
  75463. + struct video_device, dev);
  75464. + cam_data *cam = video_get_drvdata(video_dev);
  75465. +
  75466. + return sprintf(buf, "ipu%d_csi%d\n", cam->ipu_id, cam->csi);
  75467. +}
  75468. +static DEVICE_ATTR(fsl_csi_property, S_IRUGO, show_csi, NULL);
  75469. +
  75470. +/*!
  75471. + * This function is called to probe the devices if registered.
  75472. + *
  75473. + * @param pdev the device structure used to give information on which device
  75474. + * to probe
  75475. + *
  75476. + * @return The function returns 0 on success and -1 on failure.
  75477. + */
  75478. +static int mxc_v4l2_probe(struct platform_device *pdev)
  75479. +{
  75480. + /* Create cam and initialize it. */
  75481. + cam_data *cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
  75482. + if (cam == NULL) {
  75483. + pr_err("ERROR: v4l2 capture: failed to register camera\n");
  75484. + return -1;
  75485. + }
  75486. +
  75487. + init_camera_struct(cam, pdev);
  75488. + pdev->dev.release = camera_platform_release;
  75489. +
  75490. + /* Set up the v4l2 device and register it*/
  75491. + cam->self->priv = cam;
  75492. + v4l2_int_device_register(cam->self);
  75493. +
  75494. + /* register v4l video device */
  75495. + if (video_register_device(cam->video_dev, VFL_TYPE_GRABBER, video_nr)
  75496. + == -1) {
  75497. + kfree(cam);
  75498. + cam = NULL;
  75499. + pr_err("ERROR: v4l2 capture: video_register_device failed\n");
  75500. + return -1;
  75501. + }
  75502. + pr_debug(" Video device registered: %s #%d\n",
  75503. + cam->video_dev->name, cam->video_dev->minor);
  75504. +
  75505. + if (device_create_file(&cam->video_dev->dev,
  75506. + &dev_attr_fsl_v4l2_capture_property))
  75507. + dev_err(&pdev->dev, "Error on creating sysfs file"
  75508. + " for capture\n");
  75509. +
  75510. + if (device_create_file(&cam->video_dev->dev,
  75511. + &dev_attr_fsl_v4l2_overlay_property))
  75512. + dev_err(&pdev->dev, "Error on creating sysfs file"
  75513. + " for overlay\n");
  75514. +
  75515. + if (device_create_file(&cam->video_dev->dev,
  75516. + &dev_attr_fsl_csi_property))
  75517. + dev_err(&pdev->dev, "Error on creating sysfs file"
  75518. + " for csi number\n");
  75519. +
  75520. + return 0;
  75521. +}
  75522. +
  75523. +/*!
  75524. + * This function is called to remove the devices when device unregistered.
  75525. + *
  75526. + * @param pdev the device structure used to give information on which device
  75527. + * to remove
  75528. + *
  75529. + * @return The function returns 0 on success and -1 on failure.
  75530. + */
  75531. +static int mxc_v4l2_remove(struct platform_device *pdev)
  75532. +{
  75533. + cam_data *cam = (cam_data *)platform_get_drvdata(pdev);
  75534. + if (cam->open_count) {
  75535. + pr_err("ERROR: v4l2 capture:camera open "
  75536. + "-- setting ops to NULL\n");
  75537. + return -EBUSY;
  75538. + } else {
  75539. + device_remove_file(&cam->video_dev->dev,
  75540. + &dev_attr_fsl_v4l2_capture_property);
  75541. + device_remove_file(&cam->video_dev->dev,
  75542. + &dev_attr_fsl_v4l2_overlay_property);
  75543. + device_remove_file(&cam->video_dev->dev,
  75544. + &dev_attr_fsl_csi_property);
  75545. +
  75546. + pr_info("V4L2 freeing image input device\n");
  75547. + v4l2_int_device_unregister(cam->self);
  75548. + video_unregister_device(cam->video_dev);
  75549. +
  75550. + mxc_free_frame_buf(cam);
  75551. + kfree(cam);
  75552. + }
  75553. +
  75554. + pr_info("V4L2 unregistering video\n");
  75555. + return 0;
  75556. +}
  75557. +
  75558. +/*!
  75559. + * This function is called to put the sensor in a low power state.
  75560. + * Refer to the document driver-model/driver.txt in the kernel source tree
  75561. + * for more information.
  75562. + *
  75563. + * @param pdev the device structure used to give information on which I2C
  75564. + * to suspend
  75565. + * @param state the power state the device is entering
  75566. + *
  75567. + * @return The function returns 0 on success and -1 on failure.
  75568. + */
  75569. +static int mxc_v4l2_suspend(struct platform_device *pdev, pm_message_t state)
  75570. +{
  75571. + cam_data *cam = platform_get_drvdata(pdev);
  75572. +
  75573. + pr_debug("In MVC:mxc_v4l2_suspend\n");
  75574. +
  75575. + if (cam == NULL)
  75576. + return -1;
  75577. +
  75578. + down(&cam->busy_lock);
  75579. +
  75580. + cam->low_power = true;
  75581. +
  75582. + if (cam->overlay_on == true)
  75583. + stop_preview(cam);
  75584. + if ((cam->capture_on == true) && cam->enc_disable)
  75585. + cam->enc_disable(cam);
  75586. +
  75587. + if (cam->sensor && cam->open_count) {
  75588. + if (cam->mclk_on[cam->mclk_source]) {
  75589. + ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
  75590. + cam->mclk_source,
  75591. + false, false);
  75592. + cam->mclk_on[cam->mclk_source] = false;
  75593. + }
  75594. + vidioc_int_s_power(cam->sensor, 0);
  75595. + }
  75596. +
  75597. + up(&cam->busy_lock);
  75598. +
  75599. + return 0;
  75600. +}
  75601. +
  75602. +/*!
  75603. + * This function is called to bring the sensor back from a low power state.
  75604. + * Refer to the document driver-model/driver.txt in the kernel source tree
  75605. + * for more information.
  75606. + *
  75607. + * @param pdev the device structure
  75608. + *
  75609. + * @return The function returns 0 on success and -1 on failure
  75610. + */
  75611. +static int mxc_v4l2_resume(struct platform_device *pdev)
  75612. +{
  75613. + cam_data *cam = platform_get_drvdata(pdev);
  75614. +
  75615. + pr_debug("In MVC:mxc_v4l2_resume\n");
  75616. +
  75617. + if (cam == NULL)
  75618. + return -1;
  75619. +
  75620. + down(&cam->busy_lock);
  75621. +
  75622. + cam->low_power = false;
  75623. + wake_up_interruptible(&cam->power_queue);
  75624. +
  75625. + if (cam->sensor && cam->open_count) {
  75626. + vidioc_int_s_power(cam->sensor, 1);
  75627. +
  75628. + if (!cam->mclk_on[cam->mclk_source]) {
  75629. + ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
  75630. + cam->mclk_source,
  75631. + true, true);
  75632. + cam->mclk_on[cam->mclk_source] = true;
  75633. + }
  75634. + }
  75635. +
  75636. + if (cam->overlay_on == true)
  75637. + start_preview(cam);
  75638. + if (cam->capture_on == true)
  75639. + mxc_streamon(cam);
  75640. +
  75641. + up(&cam->busy_lock);
  75642. +
  75643. + return 0;
  75644. +}
  75645. +
  75646. +/*!
  75647. + * This structure contains pointers to the power management callback functions.
  75648. + */
  75649. +static struct platform_driver mxc_v4l2_driver = {
  75650. + .driver = {
  75651. + .name = "mxc_v4l2_capture",
  75652. + .owner = THIS_MODULE,
  75653. + .of_match_table = mxc_v4l2_dt_ids,
  75654. + },
  75655. + .id_table = imx_v4l2_devtype,
  75656. + .probe = mxc_v4l2_probe,
  75657. + .remove = mxc_v4l2_remove,
  75658. + .suspend = mxc_v4l2_suspend,
  75659. + .resume = mxc_v4l2_resume,
  75660. + .shutdown = NULL,
  75661. +};
  75662. +
  75663. +/*!
  75664. + * Initializes the camera driver.
  75665. + */
  75666. +static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)
  75667. +{
  75668. + cam_data *cam = slave->u.slave->master->priv;
  75669. + struct v4l2_format cam_fmt;
  75670. + int i;
  75671. + struct sensor_data *sdata = slave->priv;
  75672. +
  75673. + pr_debug("In MVC: mxc_v4l2_master_attach\n");
  75674. + pr_debug(" slave.name = %s\n", slave->name);
  75675. + pr_debug(" master.name = %s\n", slave->u.slave->master->name);
  75676. +
  75677. + if (slave == NULL) {
  75678. + pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
  75679. + return -1;
  75680. + }
  75681. +
  75682. + if (sdata->csi != cam->csi) {
  75683. + pr_debug("%s: csi doesn't match\n", __func__);
  75684. + return -1;
  75685. + }
  75686. +
  75687. + cam->sensor = slave;
  75688. +
  75689. + if (cam->sensor_index < MXC_SENSOR_NUM) {
  75690. + cam->all_sensors[cam->sensor_index] = slave;
  75691. + cam->sensor_index++;
  75692. + } else {
  75693. + pr_err("ERROR: v4l2 capture: slave number exceeds the maximum.\n");
  75694. + return -1;
  75695. + }
  75696. +
  75697. + for (i = 0; i < cam->sensor_index; i++) {
  75698. + vidioc_int_dev_exit(cam->all_sensors[i]);
  75699. + vidioc_int_s_power(cam->all_sensors[i], 0);
  75700. + }
  75701. +
  75702. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  75703. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  75704. +
  75705. + /* Used to detect TV in (type 1) vs. camera (type 0)*/
  75706. + cam->device_type = cam_fmt.fmt.pix.priv;
  75707. +
  75708. + /* Set the input size to the ipu for this device */
  75709. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  75710. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  75711. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  75712. +
  75713. + /* This also is the max crop size for this device. */
  75714. + cam->crop_defrect.top = cam->crop_defrect.left = 0;
  75715. + cam->crop_defrect.width = cam_fmt.fmt.pix.width;
  75716. + cam->crop_defrect.height = cam_fmt.fmt.pix.height;
  75717. +
  75718. + /* At this point, this is also the current image size. */
  75719. + cam->crop_current.top = cam->crop_current.left = 0;
  75720. + cam->crop_current.width = cam_fmt.fmt.pix.width;
  75721. + cam->crop_current.height = cam_fmt.fmt.pix.height;
  75722. +
  75723. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  75724. + __func__,
  75725. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  75726. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  75727. + __func__,
  75728. + cam->crop_bounds.width, cam->crop_bounds.height);
  75729. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  75730. + __func__,
  75731. + cam->crop_defrect.width, cam->crop_defrect.height);
  75732. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  75733. + __func__,
  75734. + cam->crop_current.width, cam->crop_current.height);
  75735. +
  75736. + return 0;
  75737. +}
  75738. +
  75739. +/*!
  75740. + * Disconnects the camera driver.
  75741. + */
  75742. +static void mxc_v4l2_master_detach(struct v4l2_int_device *slave)
  75743. +{
  75744. + unsigned int i;
  75745. + cam_data *cam = slave->u.slave->master->priv;
  75746. +
  75747. + pr_debug("In MVC:mxc_v4l2_master_detach\n");
  75748. +
  75749. + if (cam->sensor_index > 1) {
  75750. + for (i = 0; i < cam->sensor_index; i++) {
  75751. + if (cam->all_sensors[i] != slave)
  75752. + continue;
  75753. + /* Move all the sensors behind this
  75754. + * sensor one step forward
  75755. + */
  75756. + for (; i <= MXC_SENSOR_NUM - 2; i++)
  75757. + cam->all_sensors[i] = cam->all_sensors[i+1];
  75758. + break;
  75759. + }
  75760. + /* Point current sensor to the last one */
  75761. + cam->sensor = cam->all_sensors[cam->sensor_index - 2];
  75762. + } else
  75763. + cam->sensor = NULL;
  75764. +
  75765. + cam->sensor_index--;
  75766. + vidioc_int_dev_exit(slave);
  75767. +}
  75768. +
  75769. +/*!
  75770. + * Entry point for the V4L2
  75771. + *
  75772. + * @return Error code indicating success or failure
  75773. + */
  75774. +static __init int camera_init(void)
  75775. +{
  75776. + u8 err = 0;
  75777. +
  75778. + pr_debug("In MVC:camera_init\n");
  75779. +
  75780. + /* Register the device driver structure. */
  75781. + err = platform_driver_register(&mxc_v4l2_driver);
  75782. + if (err != 0) {
  75783. + pr_err("ERROR: v4l2 capture:camera_init: "
  75784. + "platform_driver_register failed.\n");
  75785. + return err;
  75786. + }
  75787. +
  75788. + return err;
  75789. +}
  75790. +
  75791. +/*!
  75792. + * Exit and cleanup for the V4L2
  75793. + */
  75794. +static void __exit camera_exit(void)
  75795. +{
  75796. + pr_debug("In MVC: camera_exit\n");
  75797. +
  75798. + platform_driver_unregister(&mxc_v4l2_driver);
  75799. +}
  75800. +
  75801. +module_init(camera_init);
  75802. +module_exit(camera_exit);
  75803. +
  75804. +module_param(video_nr, int, 0444);
  75805. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  75806. +MODULE_DESCRIPTION("V4L2 capture driver for Mxc based cameras");
  75807. +MODULE_LICENSE("GPL");
  75808. +MODULE_SUPPORTED_DEVICE("video");
  75809. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h linux-imx6-3.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
  75810. --- linux-3.14.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h 1969-12-31 18:00:00.000000000 -0600
  75811. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h 2014-12-08 00:31:53.256418001 -0600
  75812. @@ -0,0 +1,260 @@
  75813. +/*
  75814. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  75815. + */
  75816. +
  75817. +/*
  75818. + * The code contained herein is licensed under the GNU General Public
  75819. + * License. You may obtain a copy of the GNU General Public License
  75820. + * Version 2 or later at the following locations:
  75821. + *
  75822. + * http://www.opensource.org/licenses/gpl-license.html
  75823. + * http://www.gnu.org/copyleft/gpl.html
  75824. + */
  75825. +
  75826. +/*!
  75827. + * @defgroup MXC_V4L2_CAPTURE MXC V4L2 Video Capture Driver
  75828. + */
  75829. +/*!
  75830. + * @file mxc_v4l2_capture.h
  75831. + *
  75832. + * @brief mxc V4L2 capture device API Header file
  75833. + *
  75834. + * It include all the defines for frame operations, also three structure defines
  75835. + * use case ops structure, common v4l2 driver structure and frame structure.
  75836. + *
  75837. + * @ingroup MXC_V4L2_CAPTURE
  75838. + */
  75839. +#ifndef __MXC_V4L2_CAPTURE_H__
  75840. +#define __MXC_V4L2_CAPTURE_H__
  75841. +
  75842. +#include <linux/uaccess.h>
  75843. +#include <linux/list.h>
  75844. +#include <linux/mxc_v4l2.h>
  75845. +#include <linux/completion.h>
  75846. +#include <linux/dmaengine.h>
  75847. +#include <linux/pxp_dma.h>
  75848. +#include <linux/ipu-v3.h>
  75849. +#include <linux/platform_data/dma-imx.h>
  75850. +
  75851. +#include <media/v4l2-dev.h>
  75852. +#include <media/v4l2-int-device.h>
  75853. +
  75854. +
  75855. +#define FRAME_NUM 10
  75856. +#define MXC_SENSOR_NUM 2
  75857. +
  75858. +enum imx_v4l2_devtype {
  75859. + IMX5_V4L2,
  75860. + IMX6_V4L2,
  75861. +};
  75862. +
  75863. +/*!
  75864. + * v4l2 frame structure.
  75865. + */
  75866. +struct mxc_v4l_frame {
  75867. + u32 paddress;
  75868. + void *vaddress;
  75869. + int count;
  75870. + int width;
  75871. + int height;
  75872. +
  75873. + struct v4l2_buffer buffer;
  75874. + struct list_head queue;
  75875. + int index;
  75876. + union {
  75877. + int ipu_buf_num;
  75878. + int csi_buf_num;
  75879. + };
  75880. +};
  75881. +
  75882. +/* Only for old version. Will go away soon. */
  75883. +typedef struct {
  75884. + u8 clk_mode;
  75885. + u8 ext_vsync;
  75886. + u8 Vsync_pol;
  75887. + u8 Hsync_pol;
  75888. + u8 pixclk_pol;
  75889. + u8 data_pol;
  75890. + u8 data_width;
  75891. + u8 pack_tight;
  75892. + u8 force_eof;
  75893. + u8 data_en_pol;
  75894. + u16 width;
  75895. + u16 height;
  75896. + u32 pixel_fmt;
  75897. + u32 mclk;
  75898. + u16 active_width;
  75899. + u16 active_height;
  75900. +} sensor_interface;
  75901. +
  75902. +/* Sensor control function */
  75903. +/* Only for old version. Will go away soon. */
  75904. +struct camera_sensor {
  75905. + void (*set_color) (int bright, int saturation, int red, int green,
  75906. + int blue);
  75907. + void (*get_color) (int *bright, int *saturation, int *red, int *green,
  75908. + int *blue);
  75909. + void (*set_ae_mode) (int ae_mode);
  75910. + void (*get_ae_mode) (int *ae_mode);
  75911. + sensor_interface *(*config) (int *frame_rate, int high_quality);
  75912. + sensor_interface *(*reset) (void);
  75913. + void (*get_std) (v4l2_std_id *std);
  75914. + void (*set_std) (v4l2_std_id std);
  75915. + unsigned int csi;
  75916. +};
  75917. +
  75918. +/*!
  75919. + * common v4l2 driver structure.
  75920. + */
  75921. +typedef struct _cam_data {
  75922. + struct video_device *video_dev;
  75923. + int device_type;
  75924. +
  75925. + /* semaphore guard against SMP multithreading */
  75926. + struct semaphore busy_lock;
  75927. +
  75928. + int open_count;
  75929. +
  75930. + /* params lock for this camera */
  75931. + struct semaphore param_lock;
  75932. +
  75933. + /* Encoder */
  75934. + struct list_head ready_q;
  75935. + struct list_head done_q;
  75936. + struct list_head working_q;
  75937. + int ping_pong_csi;
  75938. + spinlock_t queue_int_lock;
  75939. + spinlock_t dqueue_int_lock;
  75940. + struct mxc_v4l_frame frame[FRAME_NUM];
  75941. + struct mxc_v4l_frame dummy_frame;
  75942. + wait_queue_head_t enc_queue;
  75943. + int enc_counter;
  75944. + dma_addr_t rot_enc_bufs[2];
  75945. + void *rot_enc_bufs_vaddr[2];
  75946. + int rot_enc_buf_size[2];
  75947. + enum v4l2_buf_type type;
  75948. +
  75949. + /* still image capture */
  75950. + wait_queue_head_t still_queue;
  75951. + int still_counter;
  75952. + dma_addr_t still_buf[2];
  75953. + void *still_buf_vaddr;
  75954. +
  75955. + /* overlay */
  75956. + struct v4l2_window win;
  75957. + struct v4l2_framebuffer v4l2_fb;
  75958. + dma_addr_t vf_bufs[2];
  75959. + void *vf_bufs_vaddr[2];
  75960. + int vf_bufs_size[2];
  75961. + dma_addr_t rot_vf_bufs[2];
  75962. + void *rot_vf_bufs_vaddr[2];
  75963. + int rot_vf_buf_size[2];
  75964. + bool overlay_active;
  75965. + int output;
  75966. + struct fb_info *overlay_fb;
  75967. + int fb_origin_std;
  75968. + struct work_struct csi_work_struct;
  75969. +
  75970. + /* v4l2 format */
  75971. + struct v4l2_format v2f;
  75972. + int rotation; /* for IPUv1 and IPUv3, this means encoder rotation */
  75973. + int vf_rotation; /* viewfinder rotation only for IPUv1 and IPUv3 */
  75974. + struct v4l2_mxc_offset offset;
  75975. +
  75976. + /* V4l2 control bit */
  75977. + int bright;
  75978. + int hue;
  75979. + int contrast;
  75980. + int saturation;
  75981. + int red;
  75982. + int green;
  75983. + int blue;
  75984. + int ae_mode;
  75985. +
  75986. + /* standard */
  75987. + struct v4l2_streamparm streamparm;
  75988. + struct v4l2_standard standard;
  75989. + bool standard_autodetect;
  75990. +
  75991. + /* crop */
  75992. + struct v4l2_rect crop_bounds;
  75993. + struct v4l2_rect crop_defrect;
  75994. + struct v4l2_rect crop_current;
  75995. +
  75996. + int (*enc_update_eba) (struct ipu_soc *ipu, dma_addr_t eba,
  75997. + int *bufferNum);
  75998. + int (*enc_enable) (void *private);
  75999. + int (*enc_disable) (void *private);
  76000. + int (*enc_enable_csi) (void *private);
  76001. + int (*enc_disable_csi) (void *private);
  76002. + void (*enc_callback) (u32 mask, void *dev);
  76003. + int (*vf_start_adc) (void *private);
  76004. + int (*vf_stop_adc) (void *private);
  76005. + int (*vf_start_sdc) (void *private);
  76006. + int (*vf_stop_sdc) (void *private);
  76007. + int (*vf_enable_csi) (void *private);
  76008. + int (*vf_disable_csi) (void *private);
  76009. + int (*csi_start) (void *private);
  76010. + int (*csi_stop) (void *private);
  76011. +
  76012. + /* misc status flag */
  76013. + bool overlay_on;
  76014. + bool capture_on;
  76015. + int overlay_pid;
  76016. + int capture_pid;
  76017. + bool low_power;
  76018. + wait_queue_head_t power_queue;
  76019. + unsigned int ipu_id;
  76020. + unsigned int csi;
  76021. + u8 mclk_source;
  76022. + bool mclk_on[2]; /* two mclk sources at most now */
  76023. + int current_input;
  76024. +
  76025. + int local_buf_num;
  76026. +
  76027. + /* camera sensor interface */
  76028. + struct camera_sensor *cam_sensor; /* old version */
  76029. + struct v4l2_int_device *all_sensors[MXC_SENSOR_NUM];
  76030. + struct v4l2_int_device *sensor;
  76031. + struct v4l2_int_device *self;
  76032. + int sensor_index;
  76033. + void *ipu;
  76034. + enum imx_v4l2_devtype devtype;
  76035. +
  76036. + /* v4l2 buf elements related to PxP DMA */
  76037. + struct completion pxp_tx_cmpl;
  76038. + struct pxp_channel *pxp_chan;
  76039. + struct pxp_config_data pxp_conf;
  76040. + struct dma_async_tx_descriptor *txd;
  76041. + dma_cookie_t cookie;
  76042. + struct scatterlist sg[2];
  76043. +} cam_data;
  76044. +
  76045. +struct sensor_data {
  76046. + const struct ov5642_platform_data *platform_data;
  76047. + struct v4l2_int_device *v4l2_int_device;
  76048. + struct i2c_client *i2c_client;
  76049. + struct v4l2_pix_format pix;
  76050. + struct v4l2_captureparm streamcap;
  76051. + bool on;
  76052. +
  76053. + /* control settings */
  76054. + int brightness;
  76055. + int hue;
  76056. + int contrast;
  76057. + int saturation;
  76058. + int red;
  76059. + int green;
  76060. + int blue;
  76061. + int ae_mode;
  76062. +
  76063. + u32 mclk;
  76064. + u8 mclk_source;
  76065. + struct clk *sensor_clk;
  76066. + int csi;
  76067. +
  76068. + void (*io_init)(void);
  76069. +};
  76070. +
  76071. +void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi);
  76072. +#endif /* __MXC_V4L2_CAPTURE_H__ */
  76073. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/ov5640.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5640.c
  76074. --- linux-3.14.14/drivers/media/platform/mxc/capture/ov5640.c 1969-12-31 18:00:00.000000000 -0600
  76075. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5640.c 2014-12-08 00:31:53.256418001 -0600
  76076. @@ -0,0 +1,1951 @@
  76077. +/*
  76078. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  76079. + */
  76080. +
  76081. +/*
  76082. + * This program is free software; you can redistribute it and/or modify
  76083. + * it under the terms of the GNU General Public License as published by
  76084. + * the Free Software Foundation; either version 2 of the License, or
  76085. + * (at your option) any later version.
  76086. +
  76087. + * This program is distributed in the hope that it will be useful,
  76088. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  76089. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  76090. + * GNU General Public License for more details.
  76091. +
  76092. + * You should have received a copy of the GNU General Public License along
  76093. + * with this program; if not, write to the Free Software Foundation, Inc.,
  76094. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  76095. + */
  76096. +
  76097. +#include <linux/clk.h>
  76098. +#include <linux/delay.h>
  76099. +#include <linux/device.h>
  76100. +#include <linux/i2c.h>
  76101. +#include <linux/init.h>
  76102. +#include <linux/module.h>
  76103. +#include <linux/of_device.h>
  76104. +#include <linux/of_gpio.h>
  76105. +#include <linux/pinctrl/consumer.h>
  76106. +#include <linux/regulator/consumer.h>
  76107. +#include <media/v4l2-chip-ident.h>
  76108. +#include <media/v4l2-int-device.h>
  76109. +#include "mxc_v4l2_capture.h"
  76110. +
  76111. +#define OV5640_VOLTAGE_ANALOG 2800000
  76112. +#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
  76113. +#define OV5640_VOLTAGE_DIGITAL_IO 1800000
  76114. +
  76115. +#define MIN_FPS 15
  76116. +#define MAX_FPS 30
  76117. +#define DEFAULT_FPS 30
  76118. +
  76119. +#define OV5640_XCLK_MIN 6000000
  76120. +#define OV5640_XCLK_MAX 24000000
  76121. +
  76122. +#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
  76123. +#define OV5640_CHIP_ID_LOW_BYTE 0x300B
  76124. +
  76125. +enum ov5640_mode {
  76126. + ov5640_mode_MIN = 0,
  76127. + ov5640_mode_VGA_640_480 = 0,
  76128. + ov5640_mode_QVGA_320_240 = 1,
  76129. + ov5640_mode_NTSC_720_480 = 2,
  76130. + ov5640_mode_PAL_720_576 = 3,
  76131. + ov5640_mode_720P_1280_720 = 4,
  76132. + ov5640_mode_1080P_1920_1080 = 5,
  76133. + ov5640_mode_QSXGA_2592_1944 = 6,
  76134. + ov5640_mode_QCIF_176_144 = 7,
  76135. + ov5640_mode_XGA_1024_768 = 8,
  76136. + ov5640_mode_MAX = 8
  76137. +};
  76138. +
  76139. +enum ov5640_frame_rate {
  76140. + ov5640_15_fps,
  76141. + ov5640_30_fps
  76142. +};
  76143. +
  76144. +static int ov5640_framerates[] = {
  76145. + [ov5640_15_fps] = 15,
  76146. + [ov5640_30_fps] = 30,
  76147. +};
  76148. +
  76149. +struct reg_value {
  76150. + u16 u16RegAddr;
  76151. + u8 u8Val;
  76152. + u8 u8Mask;
  76153. + u32 u32Delay_ms;
  76154. +};
  76155. +
  76156. +struct ov5640_mode_info {
  76157. + enum ov5640_mode mode;
  76158. + u32 width;
  76159. + u32 height;
  76160. + struct reg_value *init_data_ptr;
  76161. + u32 init_data_size;
  76162. +};
  76163. +
  76164. +/*!
  76165. + * Maintains the information on the current state of the sesor.
  76166. + */
  76167. +static struct sensor_data ov5640_data;
  76168. +static int pwn_gpio, rst_gpio;
  76169. +static int prev_sysclk;
  76170. +static int AE_Target = 52, night_mode;
  76171. +static int prev_HTS;
  76172. +static int AE_high, AE_low;
  76173. +
  76174. +static struct reg_value ov5640_global_init_setting[] = {
  76175. + {0x3008, 0x42, 0, 0},
  76176. + {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
  76177. + {0x3034, 0x1a, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0},
  76178. + {0x3630, 0x36, 0, 0}, {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0},
  76179. + {0x3633, 0x12, 0, 0}, {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0},
  76180. + {0x3703, 0x5a, 0, 0}, {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0},
  76181. + {0x370b, 0x60, 0, 0}, {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0},
  76182. + {0x3906, 0x10, 0, 0}, {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0},
  76183. + {0x3600, 0x08, 0, 0}, {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0},
  76184. + {0x3620, 0x52, 0, 0}, {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0},
  76185. + {0x3a13, 0x43, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  76186. + {0x3635, 0x13, 0, 0}, {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0},
  76187. + {0x3622, 0x01, 0, 0}, {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0},
  76188. + {0x3c05, 0x98, 0, 0}, {0x3c06, 0x00, 0, 0}, {0x3c07, 0x07, 0, 0},
  76189. + {0x3c08, 0x00, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0},
  76190. + {0x3c0b, 0x40, 0, 0}, {0x3810, 0x00, 0, 0}, {0x3811, 0x10, 0, 0},
  76191. + {0x3812, 0x00, 0, 0}, {0x3708, 0x64, 0, 0}, {0x4001, 0x02, 0, 0},
  76192. + {0x4005, 0x1a, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
  76193. + {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
  76194. + {0x501f, 0x00, 0, 0}, {0x440e, 0x00, 0, 0}, {0x5000, 0xa7, 0, 0},
  76195. + {0x3008, 0x02, 0, 0},
  76196. +};
  76197. +
  76198. +static struct reg_value ov5640_init_setting_30fps_VGA[] = {
  76199. + {0x3008, 0x42, 0, 0},
  76200. + {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
  76201. + {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0}, {0x3036, 0x46, 0, 0},
  76202. + {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
  76203. + {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
  76204. + {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
  76205. + {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
  76206. + {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
  76207. + {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
  76208. + {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
  76209. + {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
  76210. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
  76211. + {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
  76212. + {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
  76213. + {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
  76214. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  76215. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  76216. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  76217. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  76218. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  76219. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  76220. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  76221. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  76222. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  76223. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  76224. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  76225. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  76226. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  76227. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  76228. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
  76229. + {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
  76230. + {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
  76231. + {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
  76232. + {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  76233. + {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5000, 0xa7, 0, 0},
  76234. + {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0},
  76235. + {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  76236. + {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0},
  76237. + {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0}, {0x518a, 0x54, 0, 0},
  76238. + {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x50, 0, 0},
  76239. + {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0}, {0x5190, 0x46, 0, 0},
  76240. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  76241. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  76242. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x6c, 0, 0},
  76243. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x09, 0, 0},
  76244. + {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0}, {0x5381, 0x1e, 0, 0},
  76245. + {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0}, {0x5384, 0x0a, 0, 0},
  76246. + {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0},
  76247. + {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0},
  76248. + {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0},
  76249. + {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0},
  76250. + {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0},
  76251. + {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0},
  76252. + {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0}, {0x5481, 0x08, 0, 0},
  76253. + {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0}, {0x5484, 0x51, 0, 0},
  76254. + {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0}, {0x5487, 0x7d, 0, 0},
  76255. + {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0}, {0x548a, 0x9a, 0, 0},
  76256. + {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0}, {0x548d, 0xcd, 0, 0},
  76257. + {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0}, {0x5490, 0x1d, 0, 0},
  76258. + {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x10, 0, 0},
  76259. + {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0}, {0x558b, 0xf8, 0, 0},
  76260. + {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0}, {0x5802, 0x0f, 0, 0},
  76261. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0}, {0x5805, 0x26, 0, 0},
  76262. + {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0}, {0x5808, 0x05, 0, 0},
  76263. + {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0}, {0x580b, 0x0d, 0, 0},
  76264. + {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0}, {0x580e, 0x00, 0, 0},
  76265. + {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0}, {0x5811, 0x09, 0, 0},
  76266. + {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x00, 0, 0},
  76267. + {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0}, {0x5817, 0x08, 0, 0},
  76268. + {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0}, {0x581a, 0x05, 0, 0},
  76269. + {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0}, {0x581d, 0x0e, 0, 0},
  76270. + {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0}, {0x5820, 0x11, 0, 0},
  76271. + {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0}, {0x5823, 0x28, 0, 0},
  76272. + {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0}, {0x5826, 0x08, 0, 0},
  76273. + {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0}, {0x5829, 0x26, 0, 0},
  76274. + {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0}, {0x582c, 0x24, 0, 0},
  76275. + {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0}, {0x582f, 0x22, 0, 0},
  76276. + {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0}, {0x5832, 0x24, 0, 0},
  76277. + {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0}, {0x5835, 0x22, 0, 0},
  76278. + {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0}, {0x5838, 0x44, 0, 0},
  76279. + {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0}, {0x583b, 0x28, 0, 0},
  76280. + {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0}, {0x5025, 0x00, 0, 0},
  76281. + {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
  76282. + {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
  76283. + {0x3008, 0x02, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76284. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76285. +};
  76286. +
  76287. +static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
  76288. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76289. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76290. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76291. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76292. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
  76293. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  76294. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76295. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76296. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76297. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76298. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76299. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76300. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76301. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76302. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
  76303. +};
  76304. +
  76305. +static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
  76306. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76307. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76308. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76309. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76310. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
  76311. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  76312. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76313. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76314. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76315. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76316. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76317. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76318. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76319. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76320. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
  76321. +};
  76322. +
  76323. +static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
  76324. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76325. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76326. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76327. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76328. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
  76329. + {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
  76330. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76331. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76332. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76333. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76334. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76335. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76336. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76337. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76338. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76339. +};
  76340. +
  76341. +static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
  76342. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76343. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76344. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76345. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76346. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
  76347. + {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
  76348. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76349. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76350. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76351. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76352. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76353. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76354. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76355. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76356. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76357. +};
  76358. +
  76359. +static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
  76360. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76361. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76362. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76363. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
  76364. + {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  76365. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  76366. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76367. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76368. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76369. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76370. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76371. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76372. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76373. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76374. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76375. +};
  76376. +
  76377. +static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
  76378. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76379. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76380. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76381. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
  76382. + {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  76383. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  76384. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76385. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76386. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76387. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76388. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76389. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76390. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76391. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76392. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76393. +};
  76394. +
  76395. +static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
  76396. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76397. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76398. + {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76399. + {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
  76400. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  76401. + {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
  76402. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76403. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76404. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76405. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76406. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76407. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76408. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76409. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76410. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76411. +};
  76412. +
  76413. +static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
  76414. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76415. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76416. + {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76417. + {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
  76418. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  76419. + {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
  76420. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76421. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76422. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76423. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76424. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76425. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76426. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76427. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76428. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76429. +};
  76430. +
  76431. +static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
  76432. + {0x3035, 0x21, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
  76433. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  76434. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  76435. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  76436. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  76437. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  76438. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  76439. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
  76440. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
  76441. + {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
  76442. + {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
  76443. + {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
  76444. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  76445. + {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
  76446. + {0x3503, 0x00, 0, 0},
  76447. +};
  76448. +
  76449. +static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
  76450. + {0x3035, 0x41, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
  76451. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  76452. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  76453. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  76454. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  76455. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  76456. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  76457. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
  76458. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
  76459. + {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
  76460. + {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
  76461. + {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
  76462. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  76463. + {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
  76464. + {0x3503, 0x00, 0, 0},
  76465. +};
  76466. +
  76467. +static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
  76468. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76469. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76470. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76471. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76472. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
  76473. + {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
  76474. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76475. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76476. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76477. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76478. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76479. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76480. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76481. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  76482. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76483. +};
  76484. +
  76485. +static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
  76486. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76487. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76488. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76489. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76490. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
  76491. + {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
  76492. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76493. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76494. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76495. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76496. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76497. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76498. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  76499. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76500. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76501. +};
  76502. +
  76503. +static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
  76504. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76505. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76506. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76507. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76508. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
  76509. + {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
  76510. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76511. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76512. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76513. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76514. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76515. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76516. + {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
  76517. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76518. + {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
  76519. +};
  76520. +
  76521. +static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
  76522. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  76523. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  76524. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  76525. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76526. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
  76527. + {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
  76528. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  76529. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  76530. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  76531. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  76532. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76533. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  76534. + {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
  76535. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76536. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  76537. +};
  76538. +
  76539. +
  76540. +static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
  76541. + {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
  76542. + {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
  76543. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0xee, 0, 0},
  76544. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x05, 0, 0},
  76545. + {0x3807, 0xc3, 0, 0}, {0x3808, 0x07, 0, 0}, {0x3809, 0x80, 0, 0},
  76546. + {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0}, {0x380c, 0x0b, 0, 0},
  76547. + {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
  76548. + {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
  76549. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
  76550. + {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
  76551. + {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76552. + {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
  76553. + {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
  76554. + {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76555. + {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
  76556. +};
  76557. +
  76558. +static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
  76559. + {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
  76560. + {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
  76561. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0},
  76562. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  76563. + {0x3807, 0x9f, 0, 0}, {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0},
  76564. + {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0},
  76565. + {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
  76566. + {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
  76567. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
  76568. + {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
  76569. + {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  76570. + {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
  76571. + {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
  76572. + {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  76573. + {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
  76574. +};
  76575. +
  76576. +static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
  76577. + {
  76578. + {ov5640_mode_VGA_640_480, 640, 480,
  76579. + ov5640_setting_15fps_VGA_640_480,
  76580. + ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
  76581. + {ov5640_mode_QVGA_320_240, 320, 240,
  76582. + ov5640_setting_15fps_QVGA_320_240,
  76583. + ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
  76584. + {ov5640_mode_NTSC_720_480, 720, 480,
  76585. + ov5640_setting_15fps_NTSC_720_480,
  76586. + ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
  76587. + {ov5640_mode_PAL_720_576, 720, 576,
  76588. + ov5640_setting_15fps_PAL_720_576,
  76589. + ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
  76590. + {ov5640_mode_720P_1280_720, 1280, 720,
  76591. + ov5640_setting_15fps_720P_1280_720,
  76592. + ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
  76593. + {ov5640_mode_1080P_1920_1080, 1920, 1080,
  76594. + ov5640_setting_15fps_1080P_1920_1080,
  76595. + ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
  76596. + {ov5640_mode_QSXGA_2592_1944, 2592, 1944,
  76597. + ov5640_setting_15fps_QSXGA_2592_1944,
  76598. + ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
  76599. + {ov5640_mode_QCIF_176_144, 176, 144,
  76600. + ov5640_setting_15fps_QCIF_176_144,
  76601. + ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
  76602. + {ov5640_mode_XGA_1024_768, 1024, 768,
  76603. + ov5640_setting_15fps_XGA_1024_768,
  76604. + ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
  76605. + },
  76606. + {
  76607. + {ov5640_mode_VGA_640_480, 640, 480,
  76608. + ov5640_setting_30fps_VGA_640_480,
  76609. + ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
  76610. + {ov5640_mode_QVGA_320_240, 320, 240,
  76611. + ov5640_setting_30fps_QVGA_320_240,
  76612. + ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
  76613. + {ov5640_mode_NTSC_720_480, 720, 480,
  76614. + ov5640_setting_30fps_NTSC_720_480,
  76615. + ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
  76616. + {ov5640_mode_PAL_720_576, 720, 576,
  76617. + ov5640_setting_30fps_PAL_720_576,
  76618. + ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
  76619. + {ov5640_mode_720P_1280_720, 1280, 720,
  76620. + ov5640_setting_30fps_720P_1280_720,
  76621. + ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
  76622. + {ov5640_mode_1080P_1920_1080, 0, 0, NULL, 0},
  76623. + {ov5640_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
  76624. + {ov5640_mode_QCIF_176_144, 176, 144,
  76625. + ov5640_setting_30fps_QCIF_176_144,
  76626. + ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
  76627. + {ov5640_mode_XGA_1024_768, 1024, 768,
  76628. + ov5640_setting_30fps_XGA_1024_768,
  76629. + ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
  76630. + },
  76631. +};
  76632. +
  76633. +static struct regulator *io_regulator;
  76634. +static struct regulator *core_regulator;
  76635. +static struct regulator *analog_regulator;
  76636. +
  76637. +static int ov5640_probe(struct i2c_client *adapter,
  76638. + const struct i2c_device_id *device_id);
  76639. +static int ov5640_remove(struct i2c_client *client);
  76640. +
  76641. +static s32 ov5640_read_reg(u16 reg, u8 *val);
  76642. +static s32 ov5640_write_reg(u16 reg, u8 val);
  76643. +
  76644. +static const struct i2c_device_id ov5640_id[] = {
  76645. + {"ov5640", 0},
  76646. + {"ov564x", 0},
  76647. + {},
  76648. +};
  76649. +
  76650. +MODULE_DEVICE_TABLE(i2c, ov5640_id);
  76651. +
  76652. +static struct i2c_driver ov5640_i2c_driver = {
  76653. + .driver = {
  76654. + .owner = THIS_MODULE,
  76655. + .name = "ov5640",
  76656. + },
  76657. + .probe = ov5640_probe,
  76658. + .remove = ov5640_remove,
  76659. + .id_table = ov5640_id,
  76660. +};
  76661. +
  76662. +static inline void ov5640_power_down(int enable)
  76663. +{
  76664. + gpio_set_value(pwn_gpio, enable);
  76665. +
  76666. + msleep(2);
  76667. +}
  76668. +
  76669. +static inline void ov5640_reset(void)
  76670. +{
  76671. + /* camera reset */
  76672. + gpio_set_value(rst_gpio, 1);
  76673. +
  76674. + /* camera power down */
  76675. + gpio_set_value(pwn_gpio, 1);
  76676. + msleep(5);
  76677. + gpio_set_value(pwn_gpio, 0);
  76678. + msleep(5);
  76679. + gpio_set_value(rst_gpio, 0);
  76680. + msleep(1);
  76681. + gpio_set_value(rst_gpio, 1);
  76682. + msleep(5);
  76683. + gpio_set_value(pwn_gpio, 1);
  76684. +}
  76685. +
  76686. +static int ov5640_regulator_enable(struct device *dev)
  76687. +{
  76688. + int ret = 0;
  76689. +
  76690. + io_regulator = devm_regulator_get(dev, "DOVDD");
  76691. + if (!IS_ERR(io_regulator)) {
  76692. + regulator_set_voltage(io_regulator,
  76693. + OV5640_VOLTAGE_DIGITAL_IO,
  76694. + OV5640_VOLTAGE_DIGITAL_IO);
  76695. + ret = regulator_enable(io_regulator);
  76696. + if (ret) {
  76697. + dev_err(dev, "set io voltage failed\n");
  76698. + return ret;
  76699. + } else {
  76700. + dev_dbg(dev, "set io voltage ok\n");
  76701. + }
  76702. + } else {
  76703. + io_regulator = NULL;
  76704. + dev_warn(dev, "cannot get io voltage\n");
  76705. + }
  76706. +
  76707. + core_regulator = devm_regulator_get(dev, "DVDD");
  76708. + if (!IS_ERR(core_regulator)) {
  76709. + regulator_set_voltage(core_regulator,
  76710. + OV5640_VOLTAGE_DIGITAL_CORE,
  76711. + OV5640_VOLTAGE_DIGITAL_CORE);
  76712. + ret = regulator_enable(core_regulator);
  76713. + if (ret) {
  76714. + dev_err(dev, "set core voltage failed\n");
  76715. + return ret;
  76716. + } else {
  76717. + dev_dbg(dev, "set core voltage ok\n");
  76718. + }
  76719. + } else {
  76720. + core_regulator = NULL;
  76721. + dev_warn(dev, "cannot get core voltage\n");
  76722. + }
  76723. +
  76724. + analog_regulator = devm_regulator_get(dev, "AVDD");
  76725. + if (!IS_ERR(analog_regulator)) {
  76726. + regulator_set_voltage(analog_regulator,
  76727. + OV5640_VOLTAGE_ANALOG,
  76728. + OV5640_VOLTAGE_ANALOG);
  76729. + ret = regulator_enable(analog_regulator);
  76730. + if (ret) {
  76731. + dev_err(dev, "set analog voltage failed\n");
  76732. + return ret;
  76733. + } else {
  76734. + dev_dbg(dev, "set analog voltage ok\n");
  76735. + }
  76736. + } else {
  76737. + analog_regulator = NULL;
  76738. + dev_warn(dev, "cannot get analog voltage\n");
  76739. + }
  76740. +
  76741. + return ret;
  76742. +}
  76743. +
  76744. +static s32 ov5640_write_reg(u16 reg, u8 val)
  76745. +{
  76746. + u8 au8Buf[3] = {0};
  76747. +
  76748. + au8Buf[0] = reg >> 8;
  76749. + au8Buf[1] = reg & 0xff;
  76750. + au8Buf[2] = val;
  76751. +
  76752. + if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
  76753. + pr_err("%s:write reg error:reg=%x,val=%x\n",
  76754. + __func__, reg, val);
  76755. + return -1;
  76756. + }
  76757. +
  76758. + return 0;
  76759. +}
  76760. +
  76761. +static s32 ov5640_read_reg(u16 reg, u8 *val)
  76762. +{
  76763. + u8 au8RegBuf[2] = {0};
  76764. + u8 u8RdVal = 0;
  76765. +
  76766. + au8RegBuf[0] = reg >> 8;
  76767. + au8RegBuf[1] = reg & 0xff;
  76768. +
  76769. + if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
  76770. + pr_err("%s:write reg error:reg=%x\n",
  76771. + __func__, reg);
  76772. + return -1;
  76773. + }
  76774. +
  76775. + if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
  76776. + pr_err("%s:read reg error:reg=%x,val=%x\n",
  76777. + __func__, reg, u8RdVal);
  76778. + return -1;
  76779. + }
  76780. +
  76781. + *val = u8RdVal;
  76782. +
  76783. + return u8RdVal;
  76784. +}
  76785. +
  76786. +static void ov5640_soft_reset(void)
  76787. +{
  76788. + /* sysclk from pad */
  76789. + ov5640_write_reg(0x3103, 0x11);
  76790. +
  76791. + /* software reset */
  76792. + ov5640_write_reg(0x3008, 0x82);
  76793. +
  76794. + /* delay at least 5ms */
  76795. + msleep(10);
  76796. +}
  76797. +
  76798. +/* set sensor driver capability
  76799. + * 0x302c[7:6] - strength
  76800. + 00 - 1x
  76801. + 01 - 2x
  76802. + 10 - 3x
  76803. + 11 - 4x
  76804. + */
  76805. +static int ov5640_driver_capability(int strength)
  76806. +{
  76807. + u8 temp = 0;
  76808. +
  76809. + if (strength > 4 || strength < 1) {
  76810. + pr_err("The valid driver capability of ov5640 is 1x~4x\n");
  76811. + return -EINVAL;
  76812. + }
  76813. +
  76814. + ov5640_read_reg(0x302c, &temp);
  76815. +
  76816. + temp &= ~0xc0; /* clear [7:6] */
  76817. + temp |= ((strength - 1) << 6); /* set [7:6] */
  76818. +
  76819. + ov5640_write_reg(0x302c, temp);
  76820. +
  76821. + return 0;
  76822. +}
  76823. +
  76824. +/* calculate sysclk */
  76825. +static int ov5640_get_sysclk(void)
  76826. +{
  76827. + int xvclk = ov5640_data.mclk / 10000;
  76828. + int sysclk;
  76829. + int temp1, temp2;
  76830. + int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv, Bit_div2x, sclk_rdiv;
  76831. + int sclk_rdiv_map[] = {1, 2, 4, 8};
  76832. + u8 regval = 0;
  76833. +
  76834. + temp1 = ov5640_read_reg(0x3034, &regval);
  76835. + temp2 = temp1 & 0x0f;
  76836. + if (temp2 == 8 || temp2 == 10) {
  76837. + Bit_div2x = temp2 / 2;
  76838. + } else {
  76839. + pr_err("ov5640: unsupported bit mode %d\n", temp2);
  76840. + return -1;
  76841. + }
  76842. +
  76843. + temp1 = ov5640_read_reg(0x3035, &regval);
  76844. + SysDiv = temp1 >> 4;
  76845. + if (SysDiv == 0)
  76846. + SysDiv = 16;
  76847. +
  76848. + temp1 = ov5640_read_reg(0x3036, &regval);
  76849. + Multiplier = temp1;
  76850. + temp1 = ov5640_read_reg(0x3037, &regval);
  76851. + PreDiv = temp1 & 0x0f;
  76852. + Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
  76853. +
  76854. + temp1 = ov5640_read_reg(0x3108, &regval);
  76855. + temp2 = temp1 & 0x03;
  76856. +
  76857. + sclk_rdiv = sclk_rdiv_map[temp2];
  76858. + VCO = xvclk * Multiplier / PreDiv;
  76859. + sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
  76860. +
  76861. + return sysclk;
  76862. +}
  76863. +
  76864. +/* read HTS from register settings */
  76865. +static int ov5640_get_HTS(void)
  76866. +{
  76867. + int HTS;
  76868. + u8 temp = 0;
  76869. +
  76870. + HTS = ov5640_read_reg(0x380c, &temp);
  76871. + HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
  76872. + return HTS;
  76873. +}
  76874. +
  76875. +/* read VTS from register settings */
  76876. +static int ov5640_get_VTS(void)
  76877. +{
  76878. + int VTS;
  76879. + u8 temp = 0;
  76880. +
  76881. + VTS = ov5640_read_reg(0x380e, &temp);
  76882. + VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
  76883. +
  76884. + return VTS;
  76885. +}
  76886. +
  76887. +/* write VTS to registers */
  76888. +static int ov5640_set_VTS(int VTS)
  76889. +{
  76890. + int temp;
  76891. +
  76892. + temp = VTS & 0xff;
  76893. + ov5640_write_reg(0x380f, temp);
  76894. +
  76895. + temp = VTS>>8;
  76896. + ov5640_write_reg(0x380e, temp);
  76897. + return 0;
  76898. +}
  76899. +
  76900. +/* read shutter, in number of line period */
  76901. +static int ov5640_get_shutter(void)
  76902. +{
  76903. + int shutter;
  76904. + u8 regval;
  76905. +
  76906. + shutter = (ov5640_read_reg(0x03500, &regval) & 0x0f);
  76907. +
  76908. + shutter = (shutter<<8) + ov5640_read_reg(0x3501, &regval);
  76909. + shutter = (shutter<<4) + (ov5640_read_reg(0x3502, &regval)>>4);
  76910. +
  76911. + return shutter;
  76912. +}
  76913. +
  76914. +/* write shutter, in number of line period */
  76915. +static int ov5640_set_shutter(int shutter)
  76916. +{
  76917. + int temp;
  76918. +
  76919. + shutter = shutter & 0xffff;
  76920. + temp = shutter & 0x0f;
  76921. + temp = temp<<4;
  76922. + ov5640_write_reg(0x3502, temp);
  76923. +
  76924. + temp = shutter & 0xfff;
  76925. + temp = temp>>4;
  76926. + ov5640_write_reg(0x3501, temp);
  76927. +
  76928. + temp = shutter>>12;
  76929. + ov5640_write_reg(0x3500, temp);
  76930. +
  76931. + return 0;
  76932. +}
  76933. +
  76934. +/* read gain, 16 = 1x */
  76935. +static int ov5640_get_gain16(void)
  76936. +{
  76937. + int gain16;
  76938. + u8 regval;
  76939. +
  76940. + gain16 = ov5640_read_reg(0x350a, &regval) & 0x03;
  76941. + gain16 = (gain16<<8) + ov5640_read_reg(0x350b, &regval);
  76942. +
  76943. + return gain16;
  76944. +}
  76945. +
  76946. +/* write gain, 16 = 1x */
  76947. +static int ov5640_set_gain16(int gain16)
  76948. +{
  76949. + int temp;
  76950. +
  76951. + gain16 = gain16 & 0x3ff;
  76952. + temp = gain16 & 0xff;
  76953. +
  76954. + ov5640_write_reg(0x350b, temp);
  76955. + temp = gain16>>8;
  76956. +
  76957. + ov5640_write_reg(0x350a, temp);
  76958. + return 0;
  76959. +}
  76960. +
  76961. +/* get banding filter value */
  76962. +static int ov5640_get_light_freq(void)
  76963. +{
  76964. + int temp, temp1, light_frequency;
  76965. + u8 regval;
  76966. +
  76967. + temp = ov5640_read_reg(0x3c01, &regval);
  76968. + if (temp & 0x80) {
  76969. + /* manual */
  76970. + temp1 = ov5640_read_reg(0x3c00, &regval);
  76971. + if (temp1 & 0x04) {
  76972. + /* 50Hz */
  76973. + light_frequency = 50;
  76974. + } else {
  76975. + /* 60Hz */
  76976. + light_frequency = 60;
  76977. + }
  76978. + } else {
  76979. + /* auto */
  76980. + temp1 = ov5640_read_reg(0x3c0c, &regval);
  76981. + if (temp1 & 0x01) {
  76982. + /* 50Hz */
  76983. + light_frequency = 50;
  76984. + } else {
  76985. + /* 60Hz */
  76986. + light_frequency = 60;
  76987. + }
  76988. + }
  76989. +
  76990. + return light_frequency;
  76991. +}
  76992. +
  76993. +static void ov5640_set_bandingfilter(void)
  76994. +{
  76995. + int prev_VTS;
  76996. + int band_step60, max_band60, band_step50, max_band50;
  76997. +
  76998. + /* read preview PCLK */
  76999. + prev_sysclk = ov5640_get_sysclk();
  77000. +
  77001. + /* read preview HTS */
  77002. + prev_HTS = ov5640_get_HTS();
  77003. +
  77004. + /* read preview VTS */
  77005. + prev_VTS = ov5640_get_VTS();
  77006. +
  77007. + /* calculate banding filter */
  77008. + /* 60Hz */
  77009. + band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
  77010. + ov5640_write_reg(0x3a0a, (band_step60 >> 8));
  77011. + ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
  77012. +
  77013. + max_band60 = (int)((prev_VTS-4)/band_step60);
  77014. + ov5640_write_reg(0x3a0d, max_band60);
  77015. +
  77016. + /* 50Hz */
  77017. + band_step50 = prev_sysclk * 100/prev_HTS;
  77018. + ov5640_write_reg(0x3a08, (band_step50 >> 8));
  77019. + ov5640_write_reg(0x3a09, (band_step50 & 0xff));
  77020. +
  77021. + max_band50 = (int)((prev_VTS-4)/band_step50);
  77022. + ov5640_write_reg(0x3a0e, max_band50);
  77023. +}
  77024. +
  77025. +/* stable in high */
  77026. +static int ov5640_set_AE_target(int target)
  77027. +{
  77028. + int fast_high, fast_low;
  77029. +
  77030. + AE_low = target * 23 / 25; /* 0.92 */
  77031. + AE_high = target * 27 / 25; /* 1.08 */
  77032. + fast_high = AE_high << 1;
  77033. +
  77034. + if (fast_high > 255)
  77035. + fast_high = 255;
  77036. + fast_low = AE_low >> 1;
  77037. +
  77038. + ov5640_write_reg(0x3a0f, AE_high);
  77039. + ov5640_write_reg(0x3a10, AE_low);
  77040. + ov5640_write_reg(0x3a1b, AE_high);
  77041. + ov5640_write_reg(0x3a1e, AE_low);
  77042. + ov5640_write_reg(0x3a11, fast_high);
  77043. + ov5640_write_reg(0x3a1f, fast_low);
  77044. +
  77045. + return 0;
  77046. +}
  77047. +
  77048. +/* enable = 0 to turn off night mode
  77049. + enable = 1 to turn on night mode */
  77050. +static int ov5640_set_night_mode(int enable)
  77051. +{
  77052. + u8 mode;
  77053. +
  77054. + ov5640_read_reg(0x3a00, &mode);
  77055. +
  77056. + if (enable) {
  77057. + /* night mode on */
  77058. + mode |= 0x04;
  77059. + ov5640_write_reg(0x3a00, mode);
  77060. + } else {
  77061. + /* night mode off */
  77062. + mode &= 0xfb;
  77063. + ov5640_write_reg(0x3a00, mode);
  77064. + }
  77065. +
  77066. + return 0;
  77067. +}
  77068. +
  77069. +/* enable = 0 to turn off AEC/AGC
  77070. + enable = 1 to turn on AEC/AGC */
  77071. +void ov5640_turn_on_AE_AG(int enable)
  77072. +{
  77073. + u8 ae_ag_ctrl;
  77074. +
  77075. + ov5640_read_reg(0x3503, &ae_ag_ctrl);
  77076. + if (enable) {
  77077. + /* turn on auto AE/AG */
  77078. + ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
  77079. + } else {
  77080. + /* turn off AE/AG */
  77081. + ae_ag_ctrl = ae_ag_ctrl | 0x03;
  77082. + }
  77083. + ov5640_write_reg(0x3503, ae_ag_ctrl);
  77084. +}
  77085. +
  77086. +/* download ov5640 settings to sensor through i2c */
  77087. +static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
  77088. +{
  77089. + register u32 Delay_ms = 0;
  77090. + register u16 RegAddr = 0;
  77091. + register u8 Mask = 0;
  77092. + register u8 Val = 0;
  77093. + u8 RegVal = 0;
  77094. + int i, retval = 0;
  77095. +
  77096. + for (i = 0; i < ArySize; ++i, ++pModeSetting) {
  77097. + Delay_ms = pModeSetting->u32Delay_ms;
  77098. + RegAddr = pModeSetting->u16RegAddr;
  77099. + Val = pModeSetting->u8Val;
  77100. + Mask = pModeSetting->u8Mask;
  77101. +
  77102. + if (Mask) {
  77103. + retval = ov5640_read_reg(RegAddr, &RegVal);
  77104. + if (retval < 0)
  77105. + goto err;
  77106. +
  77107. + RegVal &= ~(u8)Mask;
  77108. + Val &= Mask;
  77109. + Val |= RegVal;
  77110. + }
  77111. +
  77112. + retval = ov5640_write_reg(RegAddr, Val);
  77113. + if (retval < 0)
  77114. + goto err;
  77115. +
  77116. + if (Delay_ms)
  77117. + msleep(Delay_ms);
  77118. + }
  77119. +err:
  77120. + return retval;
  77121. +}
  77122. +
  77123. +static int ov5640_init_mode(void)
  77124. +{
  77125. + struct reg_value *pModeSetting = NULL;
  77126. + int ArySize = 0, retval = 0;
  77127. +
  77128. + ov5640_soft_reset();
  77129. +
  77130. + pModeSetting = ov5640_global_init_setting;
  77131. + ArySize = ARRAY_SIZE(ov5640_global_init_setting);
  77132. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  77133. + if (retval < 0)
  77134. + goto err;
  77135. +
  77136. + pModeSetting = ov5640_init_setting_30fps_VGA;
  77137. + ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
  77138. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  77139. + if (retval < 0)
  77140. + goto err;
  77141. +
  77142. + /* change driver capability to 2x according to validation board.
  77143. + * if the image is not stable, please increase the driver strength.
  77144. + */
  77145. + ov5640_driver_capability(2);
  77146. + ov5640_set_bandingfilter();
  77147. + ov5640_set_AE_target(AE_Target);
  77148. + ov5640_set_night_mode(night_mode);
  77149. +
  77150. + /* skip 9 vysnc: start capture at 10th vsync */
  77151. + msleep(300);
  77152. +
  77153. + /* turn off night mode */
  77154. + night_mode = 0;
  77155. + ov5640_data.pix.width = 640;
  77156. + ov5640_data.pix.height = 480;
  77157. +err:
  77158. + return retval;
  77159. +}
  77160. +
  77161. +/* change to or back to subsampling mode set the mode directly
  77162. + * image size below 1280 * 960 is subsampling mode */
  77163. +static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
  77164. + enum ov5640_mode mode)
  77165. +{
  77166. + struct reg_value *pModeSetting = NULL;
  77167. + s32 ArySize = 0;
  77168. + int retval = 0;
  77169. +
  77170. + if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
  77171. + pr_err("Wrong ov5640 mode detected!\n");
  77172. + return -1;
  77173. + }
  77174. +
  77175. + pModeSetting = ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  77176. + ArySize =
  77177. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  77178. +
  77179. + ov5640_data.pix.width = ov5640_mode_info_data[frame_rate][mode].width;
  77180. + ov5640_data.pix.height = ov5640_mode_info_data[frame_rate][mode].height;
  77181. +
  77182. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  77183. + pModeSetting == NULL || ArySize == 0)
  77184. + return -EINVAL;
  77185. +
  77186. + /* set ov5640 to subsampling mode */
  77187. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  77188. +
  77189. + /* turn on AE AG for subsampling mode, in case the firmware didn't */
  77190. + ov5640_turn_on_AE_AG(1);
  77191. +
  77192. + /* calculate banding filter */
  77193. + ov5640_set_bandingfilter();
  77194. +
  77195. + /* set AE target */
  77196. + ov5640_set_AE_target(AE_Target);
  77197. +
  77198. + /* update night mode setting */
  77199. + ov5640_set_night_mode(night_mode);
  77200. +
  77201. + /* skip 9 vysnc: start capture at 10th vsync */
  77202. + if (mode == ov5640_mode_XGA_1024_768 && frame_rate == ov5640_30_fps) {
  77203. + pr_warning("ov5640: actual frame rate of XGA is 22.5fps\n");
  77204. + /* 1/22.5 * 9*/
  77205. + msleep(400);
  77206. + return retval;
  77207. + }
  77208. +
  77209. + if (frame_rate == ov5640_15_fps) {
  77210. + /* 1/15 * 9*/
  77211. + msleep(600);
  77212. + } else if (frame_rate == ov5640_30_fps) {
  77213. + /* 1/30 * 9*/
  77214. + msleep(300);
  77215. + }
  77216. +
  77217. + return retval;
  77218. +}
  77219. +
  77220. +/* change to scaling mode go through exposure calucation
  77221. + * image size above 1280 * 960 is scaling mode */
  77222. +static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
  77223. + enum ov5640_mode mode)
  77224. +{
  77225. + int prev_shutter, prev_gain16, average;
  77226. + int cap_shutter, cap_gain16;
  77227. + int cap_sysclk, cap_HTS, cap_VTS;
  77228. + int light_freq, cap_bandfilt, cap_maxband;
  77229. + long cap_gain16_shutter;
  77230. + u8 temp;
  77231. + struct reg_value *pModeSetting = NULL;
  77232. + s32 ArySize = 0;
  77233. + int retval = 0;
  77234. +
  77235. + /* check if the input mode and frame rate is valid */
  77236. + pModeSetting =
  77237. + ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  77238. + ArySize =
  77239. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  77240. +
  77241. + ov5640_data.pix.width =
  77242. + ov5640_mode_info_data[frame_rate][mode].width;
  77243. + ov5640_data.pix.height =
  77244. + ov5640_mode_info_data[frame_rate][mode].height;
  77245. +
  77246. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  77247. + pModeSetting == NULL || ArySize == 0)
  77248. + return -EINVAL;
  77249. +
  77250. + /* read preview shutter */
  77251. + prev_shutter = ov5640_get_shutter();
  77252. +
  77253. + /* read preview gain */
  77254. + prev_gain16 = ov5640_get_gain16();
  77255. +
  77256. + /* get average */
  77257. + average = ov5640_read_reg(0x56a1, &temp);
  77258. +
  77259. + /* turn off night mode for capture */
  77260. + ov5640_set_night_mode(0);
  77261. +
  77262. + /* turn off overlay */
  77263. + ov5640_write_reg(0x3022, 0x06);
  77264. +
  77265. + /* Write capture setting */
  77266. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  77267. + if (retval < 0)
  77268. + goto err;
  77269. +
  77270. + /* turn off AE AG when capture image. */
  77271. + ov5640_turn_on_AE_AG(0);
  77272. +
  77273. + /* read capture VTS */
  77274. + cap_VTS = ov5640_get_VTS();
  77275. + cap_HTS = ov5640_get_HTS();
  77276. + cap_sysclk = ov5640_get_sysclk();
  77277. +
  77278. + /* calculate capture banding filter */
  77279. + light_freq = ov5640_get_light_freq();
  77280. + if (light_freq == 60) {
  77281. + /* 60Hz */
  77282. + cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
  77283. + } else {
  77284. + /* 50Hz */
  77285. + cap_bandfilt = cap_sysclk * 100 / cap_HTS;
  77286. + }
  77287. + cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
  77288. + /* calculate capture shutter/gain16 */
  77289. + if (average > AE_low && average < AE_high) {
  77290. + /* in stable range */
  77291. + cap_gain16_shutter =
  77292. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
  77293. + prev_HTS/cap_HTS * AE_Target / average;
  77294. + } else {
  77295. + cap_gain16_shutter =
  77296. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
  77297. + prev_HTS/cap_HTS;
  77298. + }
  77299. +
  77300. + /* gain to shutter */
  77301. + if (cap_gain16_shutter < (cap_bandfilt * 16)) {
  77302. + /* shutter < 1/100 */
  77303. + cap_shutter = cap_gain16_shutter/16;
  77304. + if (cap_shutter < 1)
  77305. + cap_shutter = 1;
  77306. + cap_gain16 = cap_gain16_shutter/cap_shutter;
  77307. + if (cap_gain16 < 16)
  77308. + cap_gain16 = 16;
  77309. + } else {
  77310. + if (cap_gain16_shutter > (cap_bandfilt*cap_maxband*16)) {
  77311. + /* exposure reach max */
  77312. + cap_shutter = cap_bandfilt*cap_maxband;
  77313. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  77314. + } else {
  77315. + /* 1/100 < cap_shutter =< max, cap_shutter = n/100 */
  77316. + cap_shutter =
  77317. + ((int)(cap_gain16_shutter/16/cap_bandfilt))
  77318. + * cap_bandfilt;
  77319. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  77320. + }
  77321. + }
  77322. +
  77323. + /* write capture gain */
  77324. + ov5640_set_gain16(cap_gain16);
  77325. +
  77326. + /* write capture shutter */
  77327. + if (cap_shutter > (cap_VTS - 4)) {
  77328. + cap_VTS = cap_shutter + 4;
  77329. + ov5640_set_VTS(cap_VTS);
  77330. + }
  77331. +
  77332. + ov5640_set_shutter(cap_shutter);
  77333. +
  77334. + /* skip 2 vysnc: start capture at 3rd vsync
  77335. + * frame rate of QSXGA and 1080P is 7.5fps: 1/7.5 * 2
  77336. + */
  77337. + pr_warning("ov5640: the actual frame rate of %s is 7.5fps\n",
  77338. + mode == ov5640_mode_1080P_1920_1080 ? "1080P" : "QSXGA");
  77339. + msleep(267);
  77340. +err:
  77341. + return retval;
  77342. +}
  77343. +
  77344. +static int ov5640_change_mode(enum ov5640_frame_rate frame_rate,
  77345. + enum ov5640_mode mode)
  77346. +{
  77347. + int retval = 0;
  77348. +
  77349. + if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
  77350. + pr_err("Wrong ov5640 mode detected!\n");
  77351. + return -1;
  77352. + }
  77353. +
  77354. + if (mode == ov5640_mode_1080P_1920_1080 ||
  77355. + mode == ov5640_mode_QSXGA_2592_1944) {
  77356. + /* change to scaling mode go through exposure calucation
  77357. + * image size above 1280 * 960 is scaling mode */
  77358. + retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
  77359. + } else {
  77360. + /* change back to subsampling modem download firmware directly
  77361. + * image size below 1280 * 960 is subsampling mode */
  77362. + retval = ov5640_change_mode_direct(frame_rate, mode);
  77363. + }
  77364. +
  77365. + return retval;
  77366. +}
  77367. +
  77368. +/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
  77369. +
  77370. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  77371. +{
  77372. + if (s == NULL) {
  77373. + pr_err(" ERROR!! no slave device set!\n");
  77374. + return -1;
  77375. + }
  77376. +
  77377. + memset(p, 0, sizeof(*p));
  77378. + p->u.bt656.clock_curr = ov5640_data.mclk;
  77379. + pr_debug(" clock_curr=mclk=%d\n", ov5640_data.mclk);
  77380. + p->if_type = V4L2_IF_TYPE_BT656;
  77381. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  77382. + p->u.bt656.clock_min = OV5640_XCLK_MIN;
  77383. + p->u.bt656.clock_max = OV5640_XCLK_MAX;
  77384. + p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
  77385. +
  77386. + return 0;
  77387. +}
  77388. +
  77389. +/*!
  77390. + * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
  77391. + * @s: pointer to standard V4L2 device structure
  77392. + * @on: indicates power mode (on or off)
  77393. + *
  77394. + * Turns the power on or off, depending on the value of on and returns the
  77395. + * appropriate error code.
  77396. + */
  77397. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  77398. +{
  77399. + struct sensor_data *sensor = s->priv;
  77400. +
  77401. + if (on && !sensor->on) {
  77402. + if (io_regulator)
  77403. + if (regulator_enable(io_regulator) != 0)
  77404. + return -EIO;
  77405. + if (core_regulator)
  77406. + if (regulator_enable(core_regulator) != 0)
  77407. + return -EIO;
  77408. + if (analog_regulator)
  77409. + if (regulator_enable(analog_regulator) != 0)
  77410. + return -EIO;
  77411. + /* Make sure power on */
  77412. + ov5640_power_down(0);
  77413. + } else if (!on && sensor->on) {
  77414. + if (analog_regulator)
  77415. + regulator_disable(analog_regulator);
  77416. + if (core_regulator)
  77417. + regulator_disable(core_regulator);
  77418. + if (io_regulator)
  77419. + regulator_disable(io_regulator);
  77420. +
  77421. + ov5640_power_down(1);
  77422. +}
  77423. +
  77424. + sensor->on = on;
  77425. +
  77426. + return 0;
  77427. +}
  77428. +
  77429. +/*!
  77430. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  77431. + * @s: pointer to standard V4L2 device structure
  77432. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  77433. + *
  77434. + * Returns the sensor's video CAPTURE parameters.
  77435. + */
  77436. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  77437. +{
  77438. + struct sensor_data *sensor = s->priv;
  77439. + struct v4l2_captureparm *cparm = &a->parm.capture;
  77440. + int ret = 0;
  77441. +
  77442. + switch (a->type) {
  77443. + /* This is the only case currently handled. */
  77444. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  77445. + memset(a, 0, sizeof(*a));
  77446. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  77447. + cparm->capability = sensor->streamcap.capability;
  77448. + cparm->timeperframe = sensor->streamcap.timeperframe;
  77449. + cparm->capturemode = sensor->streamcap.capturemode;
  77450. + ret = 0;
  77451. + break;
  77452. +
  77453. + /* These are all the possible cases. */
  77454. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  77455. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  77456. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  77457. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  77458. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  77459. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  77460. + ret = -EINVAL;
  77461. + break;
  77462. +
  77463. + default:
  77464. + pr_debug(" type is unknown - %d\n", a->type);
  77465. + ret = -EINVAL;
  77466. + break;
  77467. + }
  77468. +
  77469. + return ret;
  77470. +}
  77471. +
  77472. +/*!
  77473. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  77474. + * @s: pointer to standard V4L2 device structure
  77475. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  77476. + *
  77477. + * Configures the sensor to use the input parameters, if possible. If
  77478. + * not possible, reverts to the old parameters and returns the
  77479. + * appropriate error code.
  77480. + */
  77481. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  77482. +{
  77483. + struct sensor_data *sensor = s->priv;
  77484. + struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
  77485. + u32 tgt_fps; /* target frames per secound */
  77486. + enum ov5640_frame_rate frame_rate;
  77487. + int ret = 0;
  77488. +
  77489. + /* Make sure power on */
  77490. + ov5640_power_down(0);
  77491. +
  77492. + switch (a->type) {
  77493. + /* This is the only case currently handled. */
  77494. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  77495. + /* Check that the new frame rate is allowed. */
  77496. + if ((timeperframe->numerator == 0) ||
  77497. + (timeperframe->denominator == 0)) {
  77498. + timeperframe->denominator = DEFAULT_FPS;
  77499. + timeperframe->numerator = 1;
  77500. + }
  77501. +
  77502. + tgt_fps = timeperframe->denominator /
  77503. + timeperframe->numerator;
  77504. +
  77505. + if (tgt_fps > MAX_FPS) {
  77506. + timeperframe->denominator = MAX_FPS;
  77507. + timeperframe->numerator = 1;
  77508. + } else if (tgt_fps < MIN_FPS) {
  77509. + timeperframe->denominator = MIN_FPS;
  77510. + timeperframe->numerator = 1;
  77511. + }
  77512. +
  77513. + /* Actual frame rate we use */
  77514. + tgt_fps = timeperframe->denominator /
  77515. + timeperframe->numerator;
  77516. +
  77517. + if (tgt_fps == 15)
  77518. + frame_rate = ov5640_15_fps;
  77519. + else if (tgt_fps == 30)
  77520. + frame_rate = ov5640_30_fps;
  77521. + else {
  77522. + pr_err(" The camera frame rate is not supported!\n");
  77523. + return -EINVAL;
  77524. + }
  77525. +
  77526. + ret = ov5640_change_mode(frame_rate,
  77527. + a->parm.capture.capturemode);
  77528. + if (ret < 0)
  77529. + return ret;
  77530. +
  77531. + sensor->streamcap.timeperframe = *timeperframe;
  77532. + sensor->streamcap.capturemode = a->parm.capture.capturemode;
  77533. +
  77534. + break;
  77535. +
  77536. + /* These are all the possible cases. */
  77537. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  77538. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  77539. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  77540. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  77541. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  77542. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  77543. + pr_debug(" type is not " \
  77544. + "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
  77545. + a->type);
  77546. + ret = -EINVAL;
  77547. + break;
  77548. +
  77549. + default:
  77550. + pr_debug(" type is unknown - %d\n", a->type);
  77551. + ret = -EINVAL;
  77552. + break;
  77553. + }
  77554. +
  77555. + return ret;
  77556. +}
  77557. +
  77558. +/*!
  77559. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  77560. + * @s: pointer to standard V4L2 device structure
  77561. + * @f: pointer to standard V4L2 v4l2_format structure
  77562. + *
  77563. + * Returns the sensor's current pixel format in the v4l2_format
  77564. + * parameter.
  77565. + */
  77566. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  77567. +{
  77568. + struct sensor_data *sensor = s->priv;
  77569. +
  77570. + f->fmt.pix = sensor->pix;
  77571. +
  77572. + return 0;
  77573. +}
  77574. +
  77575. +/*!
  77576. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  77577. + * @s: pointer to standard V4L2 device structure
  77578. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  77579. + *
  77580. + * If the requested control is supported, returns the control's current
  77581. + * value from the video_control[] array. Otherwise, returns -EINVAL
  77582. + * if the control is not supported.
  77583. + */
  77584. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  77585. +{
  77586. + int ret = 0;
  77587. +
  77588. + switch (vc->id) {
  77589. + case V4L2_CID_BRIGHTNESS:
  77590. + vc->value = ov5640_data.brightness;
  77591. + break;
  77592. + case V4L2_CID_HUE:
  77593. + vc->value = ov5640_data.hue;
  77594. + break;
  77595. + case V4L2_CID_CONTRAST:
  77596. + vc->value = ov5640_data.contrast;
  77597. + break;
  77598. + case V4L2_CID_SATURATION:
  77599. + vc->value = ov5640_data.saturation;
  77600. + break;
  77601. + case V4L2_CID_RED_BALANCE:
  77602. + vc->value = ov5640_data.red;
  77603. + break;
  77604. + case V4L2_CID_BLUE_BALANCE:
  77605. + vc->value = ov5640_data.blue;
  77606. + break;
  77607. + case V4L2_CID_EXPOSURE:
  77608. + vc->value = ov5640_data.ae_mode;
  77609. + break;
  77610. + default:
  77611. + ret = -EINVAL;
  77612. + }
  77613. +
  77614. + return ret;
  77615. +}
  77616. +
  77617. +/*!
  77618. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  77619. + * @s: pointer to standard V4L2 device structure
  77620. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  77621. + *
  77622. + * If the requested control is supported, sets the control's current
  77623. + * value in HW (and updates the video_control[] array). Otherwise,
  77624. + * returns -EINVAL if the control is not supported.
  77625. + */
  77626. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  77627. +{
  77628. + int retval = 0;
  77629. +
  77630. + pr_debug("In ov5640:ioctl_s_ctrl %d\n",
  77631. + vc->id);
  77632. +
  77633. + switch (vc->id) {
  77634. + case V4L2_CID_BRIGHTNESS:
  77635. + break;
  77636. + case V4L2_CID_CONTRAST:
  77637. + break;
  77638. + case V4L2_CID_SATURATION:
  77639. + break;
  77640. + case V4L2_CID_HUE:
  77641. + break;
  77642. + case V4L2_CID_AUTO_WHITE_BALANCE:
  77643. + break;
  77644. + case V4L2_CID_DO_WHITE_BALANCE:
  77645. + break;
  77646. + case V4L2_CID_RED_BALANCE:
  77647. + break;
  77648. + case V4L2_CID_BLUE_BALANCE:
  77649. + break;
  77650. + case V4L2_CID_GAMMA:
  77651. + break;
  77652. + case V4L2_CID_EXPOSURE:
  77653. + break;
  77654. + case V4L2_CID_AUTOGAIN:
  77655. + break;
  77656. + case V4L2_CID_GAIN:
  77657. + break;
  77658. + case V4L2_CID_HFLIP:
  77659. + break;
  77660. + case V4L2_CID_VFLIP:
  77661. + break;
  77662. + default:
  77663. + retval = -EPERM;
  77664. + break;
  77665. + }
  77666. +
  77667. + return retval;
  77668. +}
  77669. +
  77670. +/*!
  77671. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  77672. + * VIDIOC_ENUM_FRAMESIZES ioctl
  77673. + * @s: pointer to standard V4L2 device structure
  77674. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  77675. + *
  77676. + * Return 0 if successful, otherwise -EINVAL.
  77677. + */
  77678. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  77679. + struct v4l2_frmsizeenum *fsize)
  77680. +{
  77681. + if (fsize->index > ov5640_mode_MAX)
  77682. + return -EINVAL;
  77683. +
  77684. + fsize->pixel_format = ov5640_data.pix.pixelformat;
  77685. + fsize->discrete.width =
  77686. + max(ov5640_mode_info_data[0][fsize->index].width,
  77687. + ov5640_mode_info_data[1][fsize->index].width);
  77688. + fsize->discrete.height =
  77689. + max(ov5640_mode_info_data[0][fsize->index].height,
  77690. + ov5640_mode_info_data[1][fsize->index].height);
  77691. + return 0;
  77692. +}
  77693. +
  77694. +/*!
  77695. + * ioctl_enum_frameintervals - V4L2 sensor interface handler for
  77696. + * VIDIOC_ENUM_FRAMEINTERVALS ioctl
  77697. + * @s: pointer to standard V4L2 device structure
  77698. + * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
  77699. + *
  77700. + * Return 0 if successful, otherwise -EINVAL.
  77701. + */
  77702. +static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
  77703. + struct v4l2_frmivalenum *fival)
  77704. +{
  77705. + int i, j, count;
  77706. +
  77707. + if (fival->index < 0 || fival->index > ov5640_mode_MAX)
  77708. + return -EINVAL;
  77709. +
  77710. + if (fival->width == 0 || fival->height == 0 ||
  77711. + fival->pixel_format == 0) {
  77712. + pr_warning("Please assign pixelformat, width and height.\n");
  77713. + return -EINVAL;
  77714. + }
  77715. +
  77716. + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
  77717. + fival->discrete.numerator = 1;
  77718. +
  77719. + count = 0;
  77720. + for (i = 0; i < ARRAY_SIZE(ov5640_mode_info_data); i++) {
  77721. + for (j = 0; j < (ov5640_mode_MAX + 1); j++) {
  77722. + if (fival->pixel_format == ov5640_data.pix.pixelformat
  77723. + && fival->width == ov5640_mode_info_data[i][j].width
  77724. + && fival->height == ov5640_mode_info_data[i][j].height
  77725. + && ov5640_mode_info_data[i][j].init_data_ptr != NULL) {
  77726. + count++;
  77727. + }
  77728. + if (fival->index == (count - 1)) {
  77729. + fival->discrete.denominator =
  77730. + ov5640_framerates[i];
  77731. + return 0;
  77732. + }
  77733. + }
  77734. + }
  77735. +
  77736. + return -EINVAL;
  77737. +}
  77738. +
  77739. +/*!
  77740. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  77741. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  77742. + * @s: pointer to standard V4L2 device structure
  77743. + * @id: pointer to int
  77744. + *
  77745. + * Return 0.
  77746. + */
  77747. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  77748. +{
  77749. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  77750. + V4L2_CHIP_MATCH_I2C_DRIVER;
  77751. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name, "ov5640_camera");
  77752. +
  77753. + return 0;
  77754. +}
  77755. +
  77756. +/*!
  77757. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  77758. + * @s: pointer to standard V4L2 device structure
  77759. + */
  77760. +static int ioctl_init(struct v4l2_int_device *s)
  77761. +{
  77762. +
  77763. + return 0;
  77764. +}
  77765. +
  77766. +/*!
  77767. + * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
  77768. + * @s: pointer to standard V4L2 device structure
  77769. + * @fmt: pointer to standard V4L2 fmt description structure
  77770. + *
  77771. + * Return 0.
  77772. + */
  77773. +static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
  77774. + struct v4l2_fmtdesc *fmt)
  77775. +{
  77776. + if (fmt->index > ov5640_mode_MAX)
  77777. + return -EINVAL;
  77778. +
  77779. + fmt->pixelformat = ov5640_data.pix.pixelformat;
  77780. +
  77781. + return 0;
  77782. +}
  77783. +
  77784. +/*!
  77785. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  77786. + * @s: pointer to standard V4L2 device structure
  77787. + *
  77788. + * Initialise the device when slave attaches to the master.
  77789. + */
  77790. +static int ioctl_dev_init(struct v4l2_int_device *s)
  77791. +{
  77792. + struct sensor_data *sensor = s->priv;
  77793. + u32 tgt_xclk; /* target xclk */
  77794. + u32 tgt_fps; /* target frames per secound */
  77795. + enum ov5640_frame_rate frame_rate;
  77796. + int ret;
  77797. +
  77798. + ov5640_data.on = true;
  77799. +
  77800. + /* mclk */
  77801. + tgt_xclk = ov5640_data.mclk;
  77802. + tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
  77803. + tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
  77804. + ov5640_data.mclk = tgt_xclk;
  77805. +
  77806. + pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
  77807. + clk_set_rate(ov5640_data.sensor_clk, ov5640_data.mclk);
  77808. +
  77809. + /* Default camera frame rate is set in probe */
  77810. + tgt_fps = sensor->streamcap.timeperframe.denominator /
  77811. + sensor->streamcap.timeperframe.numerator;
  77812. +
  77813. + if (tgt_fps == 15)
  77814. + frame_rate = ov5640_15_fps;
  77815. + else if (tgt_fps == 30)
  77816. + frame_rate = ov5640_30_fps;
  77817. + else
  77818. + return -EINVAL; /* Only support 15fps or 30fps now. */
  77819. +
  77820. + ret = ov5640_init_mode();
  77821. + return ret;
  77822. +}
  77823. +
  77824. +/*!
  77825. + * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
  77826. + * @s: pointer to standard V4L2 device structure
  77827. + *
  77828. + * Delinitialise the device when slave detaches to the master.
  77829. + */
  77830. +static int ioctl_dev_exit(struct v4l2_int_device *s)
  77831. +{
  77832. + return 0;
  77833. +}
  77834. +
  77835. +/*!
  77836. + * This structure defines all the ioctls for this module and links them to the
  77837. + * enumeration.
  77838. + */
  77839. +static struct v4l2_int_ioctl_desc ov5640_ioctl_desc[] = {
  77840. + { vidioc_int_dev_init_num,
  77841. + (v4l2_int_ioctl_func *)ioctl_dev_init },
  77842. + { vidioc_int_dev_exit_num,
  77843. + ioctl_dev_exit},
  77844. + { vidioc_int_s_power_num,
  77845. + (v4l2_int_ioctl_func *)ioctl_s_power },
  77846. + { vidioc_int_g_ifparm_num,
  77847. + (v4l2_int_ioctl_func *)ioctl_g_ifparm },
  77848. + { vidioc_int_init_num,
  77849. + (v4l2_int_ioctl_func *)ioctl_init },
  77850. + { vidioc_int_enum_fmt_cap_num,
  77851. + (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
  77852. + { vidioc_int_g_fmt_cap_num,
  77853. + (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
  77854. + { vidioc_int_g_parm_num,
  77855. + (v4l2_int_ioctl_func *)ioctl_g_parm },
  77856. + { vidioc_int_s_parm_num,
  77857. + (v4l2_int_ioctl_func *)ioctl_s_parm },
  77858. + { vidioc_int_g_ctrl_num,
  77859. + (v4l2_int_ioctl_func *)ioctl_g_ctrl },
  77860. + { vidioc_int_s_ctrl_num,
  77861. + (v4l2_int_ioctl_func *)ioctl_s_ctrl },
  77862. + { vidioc_int_enum_framesizes_num,
  77863. + (v4l2_int_ioctl_func *)ioctl_enum_framesizes },
  77864. + { vidioc_int_enum_frameintervals_num,
  77865. + (v4l2_int_ioctl_func *)ioctl_enum_frameintervals },
  77866. + { vidioc_int_g_chip_ident_num,
  77867. + (v4l2_int_ioctl_func *)ioctl_g_chip_ident },
  77868. +};
  77869. +
  77870. +static struct v4l2_int_slave ov5640_slave = {
  77871. + .ioctls = ov5640_ioctl_desc,
  77872. + .num_ioctls = ARRAY_SIZE(ov5640_ioctl_desc),
  77873. +};
  77874. +
  77875. +static struct v4l2_int_device ov5640_int_device = {
  77876. + .module = THIS_MODULE,
  77877. + .name = "ov5640",
  77878. + .type = v4l2_int_type_slave,
  77879. + .u = {
  77880. + .slave = &ov5640_slave,
  77881. + },
  77882. +};
  77883. +
  77884. +/*!
  77885. + * ov5640 I2C probe function
  77886. + *
  77887. + * @param adapter struct i2c_adapter *
  77888. + * @return Error code indicating success or failure
  77889. + */
  77890. +static int ov5640_probe(struct i2c_client *client,
  77891. + const struct i2c_device_id *id)
  77892. +{
  77893. + struct pinctrl *pinctrl;
  77894. + struct device *dev = &client->dev;
  77895. + int retval;
  77896. + u8 chip_id_high, chip_id_low;
  77897. +
  77898. + /* ov5640 pinctrl */
  77899. + pinctrl = devm_pinctrl_get_select_default(dev);
  77900. + if (IS_ERR(pinctrl)) {
  77901. + dev_err(dev, "setup pinctrl failed\n");
  77902. + return PTR_ERR(pinctrl);
  77903. + }
  77904. +
  77905. + /* request power down pin */
  77906. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  77907. + if (!gpio_is_valid(pwn_gpio)) {
  77908. + dev_err(dev, "no sensor pwdn pin available\n");
  77909. + return -ENODEV;
  77910. + }
  77911. + retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  77912. + "ov5640_pwdn");
  77913. + if (retval < 0)
  77914. + return retval;
  77915. +
  77916. + /* request reset pin */
  77917. + rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
  77918. + if (!gpio_is_valid(rst_gpio)) {
  77919. + dev_err(dev, "no sensor reset pin available\n");
  77920. + return -EINVAL;
  77921. + }
  77922. + retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
  77923. + "ov5640_reset");
  77924. + if (retval < 0)
  77925. + return retval;
  77926. +
  77927. + /* Set initial values for the sensor struct. */
  77928. + memset(&ov5640_data, 0, sizeof(ov5640_data));
  77929. + ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
  77930. + if (IS_ERR(ov5640_data.sensor_clk)) {
  77931. + dev_err(dev, "get mclk failed\n");
  77932. + return PTR_ERR(ov5640_data.sensor_clk);
  77933. + }
  77934. +
  77935. + retval = of_property_read_u32(dev->of_node, "mclk",
  77936. + &ov5640_data.mclk);
  77937. + if (retval) {
  77938. + dev_err(dev, "mclk frequency is invalid\n");
  77939. + return retval;
  77940. + }
  77941. +
  77942. + retval = of_property_read_u32(dev->of_node, "mclk_source",
  77943. + (u32 *) &(ov5640_data.mclk_source));
  77944. + if (retval) {
  77945. + dev_err(dev, "mclk_source invalid\n");
  77946. + return retval;
  77947. + }
  77948. +
  77949. + retval = of_property_read_u32(dev->of_node, "csi_id",
  77950. + &(ov5640_data.csi));
  77951. + if (retval) {
  77952. + dev_err(dev, "csi_id invalid\n");
  77953. + return retval;
  77954. + }
  77955. +
  77956. + clk_prepare_enable(ov5640_data.sensor_clk);
  77957. +
  77958. + ov5640_data.io_init = ov5640_reset;
  77959. + ov5640_data.i2c_client = client;
  77960. + ov5640_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  77961. + ov5640_data.pix.width = 640;
  77962. + ov5640_data.pix.height = 480;
  77963. + ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
  77964. + V4L2_CAP_TIMEPERFRAME;
  77965. + ov5640_data.streamcap.capturemode = 0;
  77966. + ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
  77967. + ov5640_data.streamcap.timeperframe.numerator = 1;
  77968. +
  77969. + ov5640_regulator_enable(&client->dev);
  77970. +
  77971. + ov5640_reset();
  77972. +
  77973. + ov5640_power_down(0);
  77974. +
  77975. + retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
  77976. + if (retval < 0 || chip_id_high != 0x56) {
  77977. + clk_disable_unprepare(ov5640_data.sensor_clk);
  77978. + pr_warning("camera ov5640 is not found\n");
  77979. + return -ENODEV;
  77980. + }
  77981. + retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
  77982. + if (retval < 0 || chip_id_low != 0x40) {
  77983. + clk_disable_unprepare(ov5640_data.sensor_clk);
  77984. + pr_warning("camera ov5640 is not found\n");
  77985. + return -ENODEV;
  77986. + }
  77987. +
  77988. + ov5640_power_down(1);
  77989. +
  77990. + clk_disable_unprepare(ov5640_data.sensor_clk);
  77991. +
  77992. + ov5640_int_device.priv = &ov5640_data;
  77993. + retval = v4l2_int_device_register(&ov5640_int_device);
  77994. +
  77995. + pr_info("camera ov5640 is found\n");
  77996. + return retval;
  77997. +}
  77998. +
  77999. +/*!
  78000. + * ov5640 I2C detach function
  78001. + *
  78002. + * @param client struct i2c_client *
  78003. + * @return Error code indicating success or failure
  78004. + */
  78005. +static int ov5640_remove(struct i2c_client *client)
  78006. +{
  78007. + v4l2_int_device_unregister(&ov5640_int_device);
  78008. +
  78009. + if (analog_regulator)
  78010. + regulator_disable(analog_regulator);
  78011. +
  78012. + if (core_regulator)
  78013. + regulator_disable(core_regulator);
  78014. +
  78015. + if (io_regulator)
  78016. + regulator_disable(io_regulator);
  78017. +
  78018. + return 0;
  78019. +}
  78020. +
  78021. +module_i2c_driver(ov5640_i2c_driver);
  78022. +
  78023. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  78024. +MODULE_DESCRIPTION("OV5640 Camera Driver");
  78025. +MODULE_LICENSE("GPL");
  78026. +MODULE_VERSION("1.0");
  78027. +MODULE_ALIAS("CSI");
  78028. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/ov5640_mipi.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5640_mipi.c
  78029. --- linux-3.14.14/drivers/media/platform/mxc/capture/ov5640_mipi.c 1969-12-31 18:00:00.000000000 -0600
  78030. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5640_mipi.c 2014-12-08 00:31:53.256418001 -0600
  78031. @@ -0,0 +1,2104 @@
  78032. +/*
  78033. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  78034. + */
  78035. +
  78036. +/*
  78037. + * This program is free software; you can redistribute it and/or modify
  78038. + * it under the terms of the GNU General Public License as published by
  78039. + * the Free Software Foundation; either version 2 of the License, or
  78040. + * (at your option) any later version.
  78041. +
  78042. + * This program is distributed in the hope that it will be useful,
  78043. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  78044. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  78045. + * GNU General Public License for more details.
  78046. +
  78047. + * You should have received a copy of the GNU General Public License along
  78048. + * with this program; if not, write to the Free Software Foundation, Inc.,
  78049. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  78050. + */
  78051. +
  78052. +#include <linux/module.h>
  78053. +#include <linux/init.h>
  78054. +#include <linux/slab.h>
  78055. +#include <linux/ctype.h>
  78056. +#include <linux/types.h>
  78057. +#include <linux/delay.h>
  78058. +#include <linux/clk.h>
  78059. +#include <linux/of_device.h>
  78060. +#include <linux/i2c.h>
  78061. +#include <linux/of_gpio.h>
  78062. +#include <linux/pinctrl/consumer.h>
  78063. +#include <linux/regulator/consumer.h>
  78064. +#include <linux/fsl_devices.h>
  78065. +#include <linux/mipi_csi2.h>
  78066. +#include <media/v4l2-chip-ident.h>
  78067. +#include <media/v4l2-int-device.h>
  78068. +#include "mxc_v4l2_capture.h"
  78069. +
  78070. +#define OV5640_VOLTAGE_ANALOG 2800000
  78071. +#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
  78072. +#define OV5640_VOLTAGE_DIGITAL_IO 1800000
  78073. +
  78074. +#define MIN_FPS 15
  78075. +#define MAX_FPS 30
  78076. +#define DEFAULT_FPS 30
  78077. +
  78078. +#define OV5640_XCLK_MIN 6000000
  78079. +#define OV5640_XCLK_MAX 24000000
  78080. +
  78081. +#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
  78082. +#define OV5640_CHIP_ID_LOW_BYTE 0x300B
  78083. +
  78084. +enum ov5640_mode {
  78085. + ov5640_mode_MIN = 0,
  78086. + ov5640_mode_VGA_640_480 = 0,
  78087. + ov5640_mode_QVGA_320_240 = 1,
  78088. + ov5640_mode_NTSC_720_480 = 2,
  78089. + ov5640_mode_PAL_720_576 = 3,
  78090. + ov5640_mode_720P_1280_720 = 4,
  78091. + ov5640_mode_1080P_1920_1080 = 5,
  78092. + ov5640_mode_QSXGA_2592_1944 = 6,
  78093. + ov5640_mode_QCIF_176_144 = 7,
  78094. + ov5640_mode_XGA_1024_768 = 8,
  78095. + ov5640_mode_MAX = 8,
  78096. + ov5640_mode_INIT = 0xff, /*only for sensor init*/
  78097. +};
  78098. +
  78099. +enum ov5640_frame_rate {
  78100. + ov5640_15_fps,
  78101. + ov5640_30_fps
  78102. +};
  78103. +
  78104. +/* image size under 1280 * 960 are SUBSAMPLING
  78105. + * image size upper 1280 * 960 are SCALING
  78106. + */
  78107. +enum ov5640_downsize_mode {
  78108. + SUBSAMPLING,
  78109. + SCALING,
  78110. +};
  78111. +
  78112. +struct reg_value {
  78113. + u16 u16RegAddr;
  78114. + u8 u8Val;
  78115. + u8 u8Mask;
  78116. + u32 u32Delay_ms;
  78117. +};
  78118. +
  78119. +struct ov5640_mode_info {
  78120. + enum ov5640_mode mode;
  78121. + enum ov5640_downsize_mode dn_mode;
  78122. + u32 width;
  78123. + u32 height;
  78124. + struct reg_value *init_data_ptr;
  78125. + u32 init_data_size;
  78126. +};
  78127. +
  78128. +/*!
  78129. + * Maintains the information on the current state of the sesor.
  78130. + */
  78131. +static struct sensor_data ov5640_data;
  78132. +static int pwn_gpio, rst_gpio;
  78133. +
  78134. +static struct reg_value ov5640_init_setting_30fps_VGA[] = {
  78135. +
  78136. + {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
  78137. + {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
  78138. + {0x3034, 0x18, 0, 0}, {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0},
  78139. + {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
  78140. + {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
  78141. + {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
  78142. + {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
  78143. + {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
  78144. + {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
  78145. + {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
  78146. + {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
  78147. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
  78148. + {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
  78149. + {0x3c01, 0xa4, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
  78150. + {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
  78151. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78152. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78153. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78154. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78155. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78156. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  78157. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78158. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78159. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78160. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78161. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78162. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78163. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78164. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78165. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
  78166. + {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
  78167. + {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
  78168. + {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
  78169. + {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78170. + {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
  78171. + {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
  78172. + {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
  78173. + {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
  78174. + {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0},
  78175. + {0x518a, 0x54, 0, 0}, {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0},
  78176. + {0x518d, 0x50, 0, 0}, {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0},
  78177. + {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
  78178. + {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
  78179. + {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
  78180. + {0x5199, 0x6c, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
  78181. + {0x519c, 0x09, 0, 0}, {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0},
  78182. + {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
  78183. + {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
  78184. + {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
  78185. + {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
  78186. + {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
  78187. + {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
  78188. + {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
  78189. + {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
  78190. + {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
  78191. + {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
  78192. + {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
  78193. + {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
  78194. + {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
  78195. + {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
  78196. + {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
  78197. + {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
  78198. + {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
  78199. + {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
  78200. + {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
  78201. + {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
  78202. + {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
  78203. + {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
  78204. + {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
  78205. + {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
  78206. + {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
  78207. + {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
  78208. + {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
  78209. + {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
  78210. + {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
  78211. + {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
  78212. + {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
  78213. + {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
  78214. + {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
  78215. + {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
  78216. + {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
  78217. + {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
  78218. + {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
  78219. + {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
  78220. + {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3c00, 0x04, 0, 300},
  78221. +};
  78222. +
  78223. +static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
  78224. +
  78225. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78226. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78227. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78228. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78229. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78230. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78231. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  78232. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78233. + {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
  78234. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78235. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78236. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78237. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
  78238. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78239. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78240. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78241. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78242. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
  78243. +};
  78244. +
  78245. +static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
  78246. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78247. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78248. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78249. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78250. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78251. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78252. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  78253. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78254. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78255. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78256. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78257. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78258. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78259. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78260. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78261. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78262. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78263. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78264. +};
  78265. +
  78266. +static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
  78267. +
  78268. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78269. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78270. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78271. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78272. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78273. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78274. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  78275. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78276. + {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
  78277. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78278. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78279. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78280. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
  78281. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78282. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78283. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78284. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78285. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
  78286. + {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
  78287. + {0x380b, 0x00, 0, 0}, {0x3035, 0x12, 0, 0},
  78288. +};
  78289. +
  78290. +static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
  78291. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78292. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78293. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78294. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78295. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78296. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78297. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  78298. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78299. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78300. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78301. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78302. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78303. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78304. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78305. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78306. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78307. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78308. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3808, 0x04, 0, 0},
  78309. + {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0},
  78310. +};
  78311. +
  78312. +static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
  78313. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78314. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78315. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78316. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78317. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78318. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78319. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  78320. + {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78321. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78322. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78323. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78324. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78325. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78326. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78327. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78328. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78329. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78330. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78331. +};
  78332. +
  78333. +static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
  78334. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78335. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78336. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78337. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78338. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78339. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78340. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  78341. + {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78342. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78343. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78344. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78345. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78346. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78347. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78348. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78349. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78350. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78351. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78352. +};
  78353. +
  78354. +static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
  78355. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78356. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78357. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78358. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78359. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78360. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78361. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  78362. + {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78363. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78364. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78365. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78366. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78367. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78368. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78369. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78370. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78371. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78372. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78373. +};
  78374. +static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
  78375. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78376. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78377. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78378. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78379. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78380. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78381. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  78382. + {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78383. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78384. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78385. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78386. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78387. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78388. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78389. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78390. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78391. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78392. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78393. +};
  78394. +
  78395. +static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
  78396. + {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78397. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78398. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78399. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78400. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78401. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78402. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
  78403. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78404. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78405. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
  78406. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78407. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78408. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78409. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78410. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78411. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78412. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78413. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78414. +};
  78415. +
  78416. +static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
  78417. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78418. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78419. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78420. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78421. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78422. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78423. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
  78424. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78425. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78426. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
  78427. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78428. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78429. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78430. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78431. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78432. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78433. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78434. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78435. +};
  78436. +
  78437. +static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
  78438. + {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78439. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78440. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78441. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78442. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78443. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78444. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0},
  78445. + {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78446. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78447. + {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78448. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78449. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78450. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78451. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78452. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78453. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78454. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78455. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78456. +};
  78457. +
  78458. +static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
  78459. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  78460. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78461. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78462. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78463. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78464. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78465. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0},
  78466. + {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78467. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78468. + {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78469. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78470. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78471. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78472. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78473. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78474. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  78475. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78476. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  78477. +};
  78478. +
  78479. +static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
  78480. + {0x3008, 0x42, 0, 0},
  78481. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
  78482. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78483. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78484. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78485. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  78486. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  78487. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  78488. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  78489. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
  78490. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  78491. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78492. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
  78493. + {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
  78494. + {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
  78495. + {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
  78496. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
  78497. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  78498. + {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0}, {0x4005, 0x1a, 0, 0},
  78499. + {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
  78500. +};
  78501. +
  78502. +static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
  78503. + {0x3035, 0x41, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
  78504. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78505. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78506. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78507. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  78508. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  78509. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  78510. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  78511. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
  78512. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  78513. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78514. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
  78515. + {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
  78516. + {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
  78517. + {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
  78518. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
  78519. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  78520. + {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
  78521. +};
  78522. +
  78523. +static struct reg_value ov5640_setting_30fps_1080P_1920_1080[] = {
  78524. + {0x3008, 0x42, 0, 0},
  78525. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
  78526. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78527. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
  78528. + {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78529. + {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
  78530. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
  78531. + {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
  78532. + {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
  78533. + {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
  78534. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  78535. + {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
  78536. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
  78537. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78538. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78539. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78540. + {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
  78541. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78542. + {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x11, 0, 0},
  78543. + {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
  78544. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78545. + {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
  78546. + {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
  78547. + {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
  78548. + {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
  78549. + {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
  78550. + {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
  78551. + {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
  78552. + {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
  78553. + {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
  78554. + {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
  78555. + {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
  78556. + {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0},
  78557. + {0x3503, 0, 0, 0},
  78558. +};
  78559. +
  78560. +static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
  78561. + {0x3008, 0x42, 0, 0},
  78562. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
  78563. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78564. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
  78565. + {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78566. + {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
  78567. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
  78568. + {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
  78569. + {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
  78570. + {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
  78571. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  78572. + {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
  78573. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
  78574. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78575. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78576. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78577. + {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
  78578. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78579. + {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x21, 0, 0},
  78580. + {0x3036, 0x54, 0, 1}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
  78581. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78582. + {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
  78583. + {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
  78584. + {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
  78585. + {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
  78586. + {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
  78587. + {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
  78588. + {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
  78589. + {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
  78590. + {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
  78591. + {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
  78592. + {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
  78593. + {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
  78594. +};
  78595. +
  78596. +static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
  78597. + {0x4202, 0x0f, 0, 0}, /* stream off the sensor */
  78598. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, /*disable flip*/
  78599. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
  78600. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78601. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
  78602. + {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78603. + {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
  78604. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
  78605. + {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
  78606. + {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
  78607. + {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
  78608. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  78609. + {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
  78610. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
  78611. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78612. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78613. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78614. + {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
  78615. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78616. + {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 70},
  78617. + {0x4202, 0x00, 0, 0}, /* stream on the sensor */
  78618. +};
  78619. +
  78620. +static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
  78621. + {
  78622. + {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
  78623. + ov5640_setting_15fps_VGA_640_480,
  78624. + ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
  78625. + {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
  78626. + ov5640_setting_15fps_QVGA_320_240,
  78627. + ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
  78628. + {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
  78629. + ov5640_setting_15fps_NTSC_720_480,
  78630. + ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
  78631. + {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576,
  78632. + ov5640_setting_15fps_PAL_720_576,
  78633. + ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
  78634. + {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
  78635. + ov5640_setting_15fps_720P_1280_720,
  78636. + ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
  78637. + {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
  78638. + ov5640_setting_15fps_1080P_1920_1080,
  78639. + ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
  78640. + {ov5640_mode_QSXGA_2592_1944, SCALING, 2592, 1944,
  78641. + ov5640_setting_15fps_QSXGA_2592_1944,
  78642. + ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
  78643. + {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144,
  78644. + ov5640_setting_15fps_QCIF_176_144,
  78645. + ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
  78646. + {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768,
  78647. + ov5640_setting_15fps_XGA_1024_768,
  78648. + ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
  78649. + },
  78650. + {
  78651. + {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
  78652. + ov5640_setting_30fps_VGA_640_480,
  78653. + ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
  78654. + {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
  78655. + ov5640_setting_30fps_QVGA_320_240,
  78656. + ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
  78657. + {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
  78658. + ov5640_setting_30fps_NTSC_720_480,
  78659. + ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
  78660. + {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576,
  78661. + ov5640_setting_30fps_PAL_720_576,
  78662. + ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
  78663. + {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
  78664. + ov5640_setting_30fps_720P_1280_720,
  78665. + ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
  78666. + {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
  78667. + ov5640_setting_30fps_1080P_1920_1080,
  78668. + ARRAY_SIZE(ov5640_setting_30fps_1080P_1920_1080)},
  78669. + {ov5640_mode_QSXGA_2592_1944, -1, 0, 0, NULL, 0},
  78670. + {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144,
  78671. + ov5640_setting_30fps_QCIF_176_144,
  78672. + ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
  78673. + {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768,
  78674. + ov5640_setting_30fps_XGA_1024_768,
  78675. + ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
  78676. + },
  78677. +};
  78678. +
  78679. +static struct regulator *io_regulator;
  78680. +static struct regulator *core_regulator;
  78681. +static struct regulator *analog_regulator;
  78682. +static struct regulator *gpo_regulator;
  78683. +
  78684. +static int ov5640_probe(struct i2c_client *adapter,
  78685. + const struct i2c_device_id *device_id);
  78686. +static int ov5640_remove(struct i2c_client *client);
  78687. +
  78688. +static s32 ov5640_read_reg(u16 reg, u8 *val);
  78689. +static s32 ov5640_write_reg(u16 reg, u8 val);
  78690. +
  78691. +static const struct i2c_device_id ov5640_id[] = {
  78692. + {"ov5640_mipi", 0},
  78693. + {},
  78694. +};
  78695. +
  78696. +MODULE_DEVICE_TABLE(i2c, ov5640_id);
  78697. +
  78698. +static struct i2c_driver ov5640_i2c_driver = {
  78699. + .driver = {
  78700. + .owner = THIS_MODULE,
  78701. + .name = "ov5640_mipi",
  78702. + },
  78703. + .probe = ov5640_probe,
  78704. + .remove = ov5640_remove,
  78705. + .id_table = ov5640_id,
  78706. +};
  78707. +
  78708. +static void ov5640_standby(s32 enable)
  78709. +{
  78710. + if (enable)
  78711. + gpio_set_value(pwn_gpio, 1);
  78712. + else
  78713. + gpio_set_value(pwn_gpio, 0);
  78714. +
  78715. + msleep(2);
  78716. +}
  78717. +
  78718. +static void ov5640_reset(void)
  78719. +{
  78720. + /* camera reset */
  78721. + gpio_set_value(rst_gpio, 1);
  78722. +
  78723. + /* camera power dowmn */
  78724. + gpio_set_value(pwn_gpio, 1);
  78725. + msleep(5);
  78726. +
  78727. + gpio_set_value(pwn_gpio, 0);
  78728. + msleep(5);
  78729. +
  78730. + gpio_set_value(rst_gpio, 0);
  78731. + msleep(1);
  78732. +
  78733. + gpio_set_value(rst_gpio, 1);
  78734. + msleep(5);
  78735. +
  78736. + gpio_set_value(pwn_gpio, 1);
  78737. +}
  78738. +
  78739. +static int ov5640_power_on(struct device *dev)
  78740. +{
  78741. + int ret = 0;
  78742. +
  78743. + io_regulator = devm_regulator_get(dev, "DOVDD");
  78744. + if (!IS_ERR(io_regulator)) {
  78745. + regulator_set_voltage(io_regulator,
  78746. + OV5640_VOLTAGE_DIGITAL_IO,
  78747. + OV5640_VOLTAGE_DIGITAL_IO);
  78748. + ret = regulator_enable(io_regulator);
  78749. + if (ret) {
  78750. + pr_err("%s:io set voltage error\n", __func__);
  78751. + return ret;
  78752. + } else {
  78753. + dev_dbg(dev,
  78754. + "%s:io set voltage ok\n", __func__);
  78755. + }
  78756. + } else {
  78757. + pr_err("%s: cannot get io voltage error\n", __func__);
  78758. + io_regulator = NULL;
  78759. + }
  78760. +
  78761. + core_regulator = devm_regulator_get(dev, "DVDD");
  78762. + if (!IS_ERR(core_regulator)) {
  78763. + regulator_set_voltage(core_regulator,
  78764. + OV5640_VOLTAGE_DIGITAL_CORE,
  78765. + OV5640_VOLTAGE_DIGITAL_CORE);
  78766. + ret = regulator_enable(core_regulator);
  78767. + if (ret) {
  78768. + pr_err("%s:core set voltage error\n", __func__);
  78769. + return ret;
  78770. + } else {
  78771. + dev_dbg(dev,
  78772. + "%s:core set voltage ok\n", __func__);
  78773. + }
  78774. + } else {
  78775. + core_regulator = NULL;
  78776. + pr_err("%s: cannot get core voltage error\n", __func__);
  78777. + }
  78778. +
  78779. + analog_regulator = devm_regulator_get(dev, "AVDD");
  78780. + if (!IS_ERR(analog_regulator)) {
  78781. + regulator_set_voltage(analog_regulator,
  78782. + OV5640_VOLTAGE_ANALOG,
  78783. + OV5640_VOLTAGE_ANALOG);
  78784. + ret = regulator_enable(analog_regulator);
  78785. + if (ret) {
  78786. + pr_err("%s:analog set voltage error\n",
  78787. + __func__);
  78788. + return ret;
  78789. + } else {
  78790. + dev_dbg(dev,
  78791. + "%s:analog set voltage ok\n", __func__);
  78792. + }
  78793. + } else {
  78794. + analog_regulator = NULL;
  78795. + pr_err("%s: cannot get analog voltage error\n", __func__);
  78796. + }
  78797. +
  78798. + return ret;
  78799. +}
  78800. +
  78801. +static s32 ov5640_write_reg(u16 reg, u8 val)
  78802. +{
  78803. + u8 au8Buf[3] = {0};
  78804. +
  78805. + au8Buf[0] = reg >> 8;
  78806. + au8Buf[1] = reg & 0xff;
  78807. + au8Buf[2] = val;
  78808. +
  78809. + if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
  78810. + pr_err("%s:write reg error:reg=%x,val=%x\n",
  78811. + __func__, reg, val);
  78812. + return -1;
  78813. + }
  78814. +
  78815. + return 0;
  78816. +}
  78817. +
  78818. +static s32 ov5640_read_reg(u16 reg, u8 *val)
  78819. +{
  78820. + u8 au8RegBuf[2] = {0};
  78821. + u8 u8RdVal = 0;
  78822. +
  78823. + au8RegBuf[0] = reg >> 8;
  78824. + au8RegBuf[1] = reg & 0xff;
  78825. +
  78826. + if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
  78827. + pr_err("%s:write reg error:reg=%x\n",
  78828. + __func__, reg);
  78829. + return -1;
  78830. + }
  78831. +
  78832. + if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
  78833. + pr_err("%s:read reg error:reg=%x,val=%x\n",
  78834. + __func__, reg, u8RdVal);
  78835. + return -1;
  78836. + }
  78837. +
  78838. + *val = u8RdVal;
  78839. +
  78840. + return u8RdVal;
  78841. +}
  78842. +
  78843. +static int prev_sysclk, prev_HTS;
  78844. +static int AE_low, AE_high, AE_Target = 52;
  78845. +
  78846. +void OV5640_stream_on(void)
  78847. +{
  78848. + ov5640_write_reg(0x4202, 0x00);
  78849. +}
  78850. +
  78851. +void OV5640_stream_off(void)
  78852. +{
  78853. + ov5640_write_reg(0x4202, 0x0f);
  78854. +}
  78855. +
  78856. +
  78857. +int OV5640_get_sysclk(void)
  78858. +{
  78859. + /* calculate sysclk */
  78860. + int xvclk = ov5640_data.mclk / 10000;
  78861. + int temp1, temp2;
  78862. + int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv;
  78863. + int Bit_div2x = 1, sclk_rdiv, sysclk;
  78864. + u8 temp;
  78865. +
  78866. + int sclk_rdiv_map[] = {1, 2, 4, 8};
  78867. +
  78868. + temp1 = ov5640_read_reg(0x3034, &temp);
  78869. + temp2 = temp1 & 0x0f;
  78870. + if (temp2 == 8 || temp2 == 10)
  78871. + Bit_div2x = temp2 / 2;
  78872. +
  78873. + temp1 = ov5640_read_reg(0x3035, &temp);
  78874. + SysDiv = temp1>>4;
  78875. + if (SysDiv == 0)
  78876. + SysDiv = 16;
  78877. +
  78878. + temp1 = ov5640_read_reg(0x3036, &temp);
  78879. + Multiplier = temp1;
  78880. +
  78881. + temp1 = ov5640_read_reg(0x3037, &temp);
  78882. + PreDiv = temp1 & 0x0f;
  78883. + Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
  78884. +
  78885. + temp1 = ov5640_read_reg(0x3108, &temp);
  78886. + temp2 = temp1 & 0x03;
  78887. + sclk_rdiv = sclk_rdiv_map[temp2];
  78888. +
  78889. + VCO = xvclk * Multiplier / PreDiv;
  78890. +
  78891. + sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
  78892. +
  78893. + return sysclk;
  78894. +}
  78895. +
  78896. +void OV5640_set_night_mode(void)
  78897. +{
  78898. + /* read HTS from register settings */
  78899. + u8 mode;
  78900. +
  78901. + ov5640_read_reg(0x3a00, &mode);
  78902. + mode &= 0xfb;
  78903. + ov5640_write_reg(0x3a00, mode);
  78904. +}
  78905. +
  78906. +int OV5640_get_HTS(void)
  78907. +{
  78908. + /* read HTS from register settings */
  78909. + int HTS;
  78910. + u8 temp;
  78911. +
  78912. + HTS = ov5640_read_reg(0x380c, &temp);
  78913. + HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
  78914. +
  78915. + return HTS;
  78916. +}
  78917. +
  78918. +int OV5640_get_VTS(void)
  78919. +{
  78920. + /* read VTS from register settings */
  78921. + int VTS;
  78922. + u8 temp;
  78923. +
  78924. + /* total vertical size[15:8] high byte */
  78925. + VTS = ov5640_read_reg(0x380e, &temp);
  78926. +
  78927. + VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
  78928. +
  78929. + return VTS;
  78930. +}
  78931. +
  78932. +int OV5640_set_VTS(int VTS)
  78933. +{
  78934. + /* write VTS to registers */
  78935. + int temp;
  78936. +
  78937. + temp = VTS & 0xff;
  78938. + ov5640_write_reg(0x380f, temp);
  78939. +
  78940. + temp = VTS>>8;
  78941. + ov5640_write_reg(0x380e, temp);
  78942. +
  78943. + return 0;
  78944. +}
  78945. +
  78946. +int OV5640_get_shutter(void)
  78947. +{
  78948. + /* read shutter, in number of line period */
  78949. + int shutter;
  78950. + u8 temp;
  78951. +
  78952. + shutter = (ov5640_read_reg(0x03500, &temp) & 0x0f);
  78953. + shutter = (shutter<<8) + ov5640_read_reg(0x3501, &temp);
  78954. + shutter = (shutter<<4) + (ov5640_read_reg(0x3502, &temp)>>4);
  78955. +
  78956. + return shutter;
  78957. +}
  78958. +
  78959. +int OV5640_set_shutter(int shutter)
  78960. +{
  78961. + /* write shutter, in number of line period */
  78962. + int temp;
  78963. +
  78964. + shutter = shutter & 0xffff;
  78965. +
  78966. + temp = shutter & 0x0f;
  78967. + temp = temp<<4;
  78968. + ov5640_write_reg(0x3502, temp);
  78969. +
  78970. + temp = shutter & 0xfff;
  78971. + temp = temp>>4;
  78972. + ov5640_write_reg(0x3501, temp);
  78973. +
  78974. + temp = shutter>>12;
  78975. + ov5640_write_reg(0x3500, temp);
  78976. +
  78977. + return 0;
  78978. +}
  78979. +
  78980. +int OV5640_get_gain16(void)
  78981. +{
  78982. + /* read gain, 16 = 1x */
  78983. + int gain16;
  78984. + u8 temp;
  78985. +
  78986. + gain16 = ov5640_read_reg(0x350a, &temp) & 0x03;
  78987. + gain16 = (gain16<<8) + ov5640_read_reg(0x350b, &temp);
  78988. +
  78989. + return gain16;
  78990. +}
  78991. +
  78992. +int OV5640_set_gain16(int gain16)
  78993. +{
  78994. + /* write gain, 16 = 1x */
  78995. + u8 temp;
  78996. + gain16 = gain16 & 0x3ff;
  78997. +
  78998. + temp = gain16 & 0xff;
  78999. + ov5640_write_reg(0x350b, temp);
  79000. +
  79001. + temp = gain16>>8;
  79002. + ov5640_write_reg(0x350a, temp);
  79003. +
  79004. + return 0;
  79005. +}
  79006. +
  79007. +int OV5640_get_light_freq(void)
  79008. +{
  79009. + /* get banding filter value */
  79010. + int temp, temp1, light_freq = 0;
  79011. + u8 tmp;
  79012. +
  79013. + temp = ov5640_read_reg(0x3c01, &tmp);
  79014. +
  79015. + if (temp & 0x80) {
  79016. + /* manual */
  79017. + temp1 = ov5640_read_reg(0x3c00, &tmp);
  79018. + if (temp1 & 0x04) {
  79019. + /* 50Hz */
  79020. + light_freq = 50;
  79021. + } else {
  79022. + /* 60Hz */
  79023. + light_freq = 60;
  79024. + }
  79025. + } else {
  79026. + /* auto */
  79027. + temp1 = ov5640_read_reg(0x3c0c, &tmp);
  79028. + if (temp1 & 0x01) {
  79029. + /* 50Hz */
  79030. + light_freq = 50;
  79031. + } else {
  79032. + /* 60Hz */
  79033. + }
  79034. + }
  79035. + return light_freq;
  79036. +}
  79037. +
  79038. +void OV5640_set_bandingfilter(void)
  79039. +{
  79040. + int prev_VTS;
  79041. + int band_step60, max_band60, band_step50, max_band50;
  79042. +
  79043. + /* read preview PCLK */
  79044. + prev_sysclk = OV5640_get_sysclk();
  79045. + /* read preview HTS */
  79046. + prev_HTS = OV5640_get_HTS();
  79047. +
  79048. + /* read preview VTS */
  79049. + prev_VTS = OV5640_get_VTS();
  79050. +
  79051. + /* calculate banding filter */
  79052. + /* 60Hz */
  79053. + band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
  79054. + ov5640_write_reg(0x3a0a, (band_step60 >> 8));
  79055. + ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
  79056. +
  79057. + max_band60 = (int)((prev_VTS-4)/band_step60);
  79058. + ov5640_write_reg(0x3a0d, max_band60);
  79059. +
  79060. + /* 50Hz */
  79061. + band_step50 = prev_sysclk * 100/prev_HTS;
  79062. + ov5640_write_reg(0x3a08, (band_step50 >> 8));
  79063. + ov5640_write_reg(0x3a09, (band_step50 & 0xff));
  79064. +
  79065. + max_band50 = (int)((prev_VTS-4)/band_step50);
  79066. + ov5640_write_reg(0x3a0e, max_band50);
  79067. +}
  79068. +
  79069. +int OV5640_set_AE_target(int target)
  79070. +{
  79071. + /* stable in high */
  79072. + int fast_high, fast_low;
  79073. + AE_low = target * 23 / 25; /* 0.92 */
  79074. + AE_high = target * 27 / 25; /* 1.08 */
  79075. +
  79076. + fast_high = AE_high<<1;
  79077. + if (fast_high > 255)
  79078. + fast_high = 255;
  79079. +
  79080. + fast_low = AE_low >> 1;
  79081. +
  79082. + ov5640_write_reg(0x3a0f, AE_high);
  79083. + ov5640_write_reg(0x3a10, AE_low);
  79084. + ov5640_write_reg(0x3a1b, AE_high);
  79085. + ov5640_write_reg(0x3a1e, AE_low);
  79086. + ov5640_write_reg(0x3a11, fast_high);
  79087. + ov5640_write_reg(0x3a1f, fast_low);
  79088. +
  79089. + return 0;
  79090. +}
  79091. +
  79092. +void OV5640_turn_on_AE_AG(int enable)
  79093. +{
  79094. + u8 ae_ag_ctrl;
  79095. +
  79096. + ov5640_read_reg(0x3503, &ae_ag_ctrl);
  79097. + if (enable) {
  79098. + /* turn on auto AE/AG */
  79099. + ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
  79100. + } else {
  79101. + /* turn off AE/AG */
  79102. + ae_ag_ctrl = ae_ag_ctrl | 0x03;
  79103. + }
  79104. + ov5640_write_reg(0x3503, ae_ag_ctrl);
  79105. +}
  79106. +
  79107. +bool binning_on(void)
  79108. +{
  79109. + u8 temp;
  79110. + ov5640_read_reg(0x3821, &temp);
  79111. + temp &= 0xfe;
  79112. + if (temp)
  79113. + return true;
  79114. + else
  79115. + return false;
  79116. +}
  79117. +
  79118. +static void ov5640_set_virtual_channel(int channel)
  79119. +{
  79120. + u8 channel_id;
  79121. +
  79122. + ov5640_read_reg(0x4814, &channel_id);
  79123. + channel_id &= ~(3 << 6);
  79124. + ov5640_write_reg(0x4814, channel_id | (channel << 6));
  79125. +}
  79126. +
  79127. +/* download ov5640 settings to sensor through i2c */
  79128. +static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
  79129. +{
  79130. + register u32 Delay_ms = 0;
  79131. + register u16 RegAddr = 0;
  79132. + register u8 Mask = 0;
  79133. + register u8 Val = 0;
  79134. + u8 RegVal = 0;
  79135. + int i, retval = 0;
  79136. +
  79137. + for (i = 0; i < ArySize; ++i, ++pModeSetting) {
  79138. + Delay_ms = pModeSetting->u32Delay_ms;
  79139. + RegAddr = pModeSetting->u16RegAddr;
  79140. + Val = pModeSetting->u8Val;
  79141. + Mask = pModeSetting->u8Mask;
  79142. +
  79143. + if (Mask) {
  79144. + retval = ov5640_read_reg(RegAddr, &RegVal);
  79145. + if (retval < 0)
  79146. + goto err;
  79147. +
  79148. + RegVal &= ~(u8)Mask;
  79149. + Val &= Mask;
  79150. + Val |= RegVal;
  79151. + }
  79152. +
  79153. + retval = ov5640_write_reg(RegAddr, Val);
  79154. + if (retval < 0)
  79155. + goto err;
  79156. +
  79157. + if (Delay_ms)
  79158. + msleep(Delay_ms);
  79159. + }
  79160. +err:
  79161. + return retval;
  79162. +}
  79163. +
  79164. +/* sensor changes between scaling and subsampling
  79165. + * go through exposure calcualtion
  79166. + */
  79167. +static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
  79168. + enum ov5640_mode mode)
  79169. +{
  79170. + struct reg_value *pModeSetting = NULL;
  79171. + s32 ArySize = 0;
  79172. + u8 average;
  79173. + int prev_shutter, prev_gain16;
  79174. + int cap_shutter, cap_gain16;
  79175. + int cap_sysclk, cap_HTS, cap_VTS;
  79176. + int light_freq, cap_bandfilt, cap_maxband;
  79177. + long cap_gain16_shutter;
  79178. + int retval = 0;
  79179. +
  79180. + /* check if the input mode and frame rate is valid */
  79181. + pModeSetting =
  79182. + ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  79183. + ArySize =
  79184. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  79185. +
  79186. + ov5640_data.pix.width =
  79187. + ov5640_mode_info_data[frame_rate][mode].width;
  79188. + ov5640_data.pix.height =
  79189. + ov5640_mode_info_data[frame_rate][mode].height;
  79190. +
  79191. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  79192. + pModeSetting == NULL || ArySize == 0)
  79193. + return -EINVAL;
  79194. +
  79195. + /* auto focus */
  79196. + /* OV5640_auto_focus();//if no af function, just skip it */
  79197. +
  79198. + /* turn off AE/AG */
  79199. + OV5640_turn_on_AE_AG(0);
  79200. +
  79201. + /* read preview shutter */
  79202. + prev_shutter = OV5640_get_shutter();
  79203. + if ((binning_on()) && (mode != ov5640_mode_720P_1280_720)
  79204. + && (mode != ov5640_mode_1080P_1920_1080))
  79205. + prev_shutter *= 2;
  79206. +
  79207. + /* read preview gain */
  79208. + prev_gain16 = OV5640_get_gain16();
  79209. +
  79210. + /* get average */
  79211. + ov5640_read_reg(0x56a1, &average);
  79212. +
  79213. + /* turn off night mode for capture */
  79214. + OV5640_set_night_mode();
  79215. +
  79216. + /* turn off overlay */
  79217. + /* ov5640_write_reg(0x3022, 0x06);//if no af function, just skip it */
  79218. +
  79219. + OV5640_stream_off();
  79220. +
  79221. + /* Write capture setting */
  79222. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79223. + if (retval < 0)
  79224. + goto err;
  79225. +
  79226. + /* read capture VTS */
  79227. + cap_VTS = OV5640_get_VTS();
  79228. + cap_HTS = OV5640_get_HTS();
  79229. + cap_sysclk = OV5640_get_sysclk();
  79230. +
  79231. + /* calculate capture banding filter */
  79232. + light_freq = OV5640_get_light_freq();
  79233. + if (light_freq == 60) {
  79234. + /* 60Hz */
  79235. + cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
  79236. + } else {
  79237. + /* 50Hz */
  79238. + cap_bandfilt = cap_sysclk * 100 / cap_HTS;
  79239. + }
  79240. + cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
  79241. +
  79242. + /* calculate capture shutter/gain16 */
  79243. + if (average > AE_low && average < AE_high) {
  79244. + /* in stable range */
  79245. + cap_gain16_shutter =
  79246. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
  79247. + * prev_HTS/cap_HTS * AE_Target / average;
  79248. + } else {
  79249. + cap_gain16_shutter =
  79250. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
  79251. + * prev_HTS/cap_HTS;
  79252. + }
  79253. +
  79254. + /* gain to shutter */
  79255. + if (cap_gain16_shutter < (cap_bandfilt * 16)) {
  79256. + /* shutter < 1/100 */
  79257. + cap_shutter = cap_gain16_shutter/16;
  79258. + if (cap_shutter < 1)
  79259. + cap_shutter = 1;
  79260. +
  79261. + cap_gain16 = cap_gain16_shutter/cap_shutter;
  79262. + if (cap_gain16 < 16)
  79263. + cap_gain16 = 16;
  79264. + } else {
  79265. + if (cap_gain16_shutter >
  79266. + (cap_bandfilt * cap_maxband * 16)) {
  79267. + /* exposure reach max */
  79268. + cap_shutter = cap_bandfilt * cap_maxband;
  79269. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  79270. + } else {
  79271. + /* 1/100 < (cap_shutter = n/100) =< max */
  79272. + cap_shutter =
  79273. + ((int) (cap_gain16_shutter/16 / cap_bandfilt))
  79274. + *cap_bandfilt;
  79275. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  79276. + }
  79277. + }
  79278. +
  79279. + /* write capture gain */
  79280. + OV5640_set_gain16(cap_gain16);
  79281. +
  79282. + /* write capture shutter */
  79283. + if (cap_shutter > (cap_VTS - 4)) {
  79284. + cap_VTS = cap_shutter + 4;
  79285. + OV5640_set_VTS(cap_VTS);
  79286. + }
  79287. + OV5640_set_shutter(cap_shutter);
  79288. +
  79289. + OV5640_stream_on();
  79290. +
  79291. +err:
  79292. + return retval;
  79293. +}
  79294. +
  79295. +/* if sensor changes inside scaling or subsampling
  79296. + * change mode directly
  79297. + * */
  79298. +static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
  79299. + enum ov5640_mode mode)
  79300. +{
  79301. + struct reg_value *pModeSetting = NULL;
  79302. + s32 ArySize = 0;
  79303. + int retval = 0;
  79304. +
  79305. + /* check if the input mode and frame rate is valid */
  79306. + pModeSetting =
  79307. + ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  79308. + ArySize =
  79309. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  79310. +
  79311. + ov5640_data.pix.width =
  79312. + ov5640_mode_info_data[frame_rate][mode].width;
  79313. + ov5640_data.pix.height =
  79314. + ov5640_mode_info_data[frame_rate][mode].height;
  79315. +
  79316. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  79317. + pModeSetting == NULL || ArySize == 0)
  79318. + return -EINVAL;
  79319. +
  79320. + /* turn off AE/AG */
  79321. + OV5640_turn_on_AE_AG(0);
  79322. +
  79323. + OV5640_stream_off();
  79324. +
  79325. + /* Write capture setting */
  79326. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79327. + if (retval < 0)
  79328. + goto err;
  79329. +
  79330. + OV5640_stream_on();
  79331. +
  79332. + OV5640_turn_on_AE_AG(1);
  79333. +
  79334. +err:
  79335. + return retval;
  79336. +}
  79337. +
  79338. +static int ov5640_init_mode(enum ov5640_frame_rate frame_rate,
  79339. + enum ov5640_mode mode, enum ov5640_mode orig_mode)
  79340. +{
  79341. + struct reg_value *pModeSetting = NULL;
  79342. + s32 ArySize = 0;
  79343. + int retval = 0;
  79344. + void *mipi_csi2_info;
  79345. + u32 mipi_reg, msec_wait4stable = 0;
  79346. + enum ov5640_downsize_mode dn_mode, orig_dn_mode;
  79347. +
  79348. + if ((mode > ov5640_mode_MAX || mode < ov5640_mode_MIN)
  79349. + && (mode != ov5640_mode_INIT)) {
  79350. + pr_err("Wrong ov5640 mode detected!\n");
  79351. + return -1;
  79352. + }
  79353. +
  79354. + mipi_csi2_info = mipi_csi2_get_info();
  79355. +
  79356. + /* initial mipi dphy */
  79357. + if (!mipi_csi2_info) {
  79358. + printk(KERN_ERR "%s() in %s: Fail to get mipi_csi2_info!\n",
  79359. + __func__, __FILE__);
  79360. + return -1;
  79361. + }
  79362. +
  79363. + if (!mipi_csi2_get_status(mipi_csi2_info))
  79364. + mipi_csi2_enable(mipi_csi2_info);
  79365. +
  79366. + if (!mipi_csi2_get_status(mipi_csi2_info)) {
  79367. + pr_err("Can not enable mipi csi2 driver!\n");
  79368. + return -1;
  79369. + }
  79370. +
  79371. + mipi_csi2_set_lanes(mipi_csi2_info);
  79372. +
  79373. + /*Only reset MIPI CSI2 HW at sensor initialize*/
  79374. + if (mode == ov5640_mode_INIT)
  79375. + mipi_csi2_reset(mipi_csi2_info);
  79376. +
  79377. + if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_UYVY)
  79378. + mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_YUV422);
  79379. + else if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_RGB565)
  79380. + mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_RGB565);
  79381. + else
  79382. + pr_err("currently this sensor format can not be supported!\n");
  79383. +
  79384. + dn_mode = ov5640_mode_info_data[frame_rate][mode].dn_mode;
  79385. + orig_dn_mode = ov5640_mode_info_data[frame_rate][orig_mode].dn_mode;
  79386. + if (mode == ov5640_mode_INIT) {
  79387. + pModeSetting = ov5640_init_setting_30fps_VGA;
  79388. + ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
  79389. +
  79390. + ov5640_data.pix.width = 640;
  79391. + ov5640_data.pix.height = 480;
  79392. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79393. + if (retval < 0)
  79394. + goto err;
  79395. +
  79396. + pModeSetting = ov5640_setting_30fps_VGA_640_480;
  79397. + ArySize = ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480);
  79398. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79399. + } else if ((dn_mode == SUBSAMPLING && orig_dn_mode == SCALING) ||
  79400. + (dn_mode == SCALING && orig_dn_mode == SUBSAMPLING)) {
  79401. + /* change between subsampling and scaling
  79402. + * go through exposure calucation */
  79403. + retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
  79404. + } else {
  79405. + /* change inside subsampling or scaling
  79406. + * download firmware directly */
  79407. + retval = ov5640_change_mode_direct(frame_rate, mode);
  79408. + }
  79409. +
  79410. + if (retval < 0)
  79411. + goto err;
  79412. +
  79413. + OV5640_set_AE_target(AE_Target);
  79414. + OV5640_get_light_freq();
  79415. + OV5640_set_bandingfilter();
  79416. + ov5640_set_virtual_channel(ov5640_data.csi);
  79417. +
  79418. + /* add delay to wait for sensor stable */
  79419. + if (mode == ov5640_mode_QSXGA_2592_1944) {
  79420. + /* dump the first two frames: 1/7.5*2
  79421. + * the frame rate of QSXGA is 7.5fps */
  79422. + msec_wait4stable = 267;
  79423. + } else if (frame_rate == ov5640_15_fps) {
  79424. + /* dump the first nine frames: 1/15*9 */
  79425. + msec_wait4stable = 600;
  79426. + } else if (frame_rate == ov5640_30_fps) {
  79427. + /* dump the first nine frames: 1/30*9 */
  79428. + msec_wait4stable = 300;
  79429. + }
  79430. + msleep(msec_wait4stable);
  79431. +
  79432. + if (mipi_csi2_info) {
  79433. + unsigned int i;
  79434. +
  79435. + i = 0;
  79436. +
  79437. + /* wait for mipi sensor ready */
  79438. + mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
  79439. + while ((mipi_reg == 0x200) && (i < 10)) {
  79440. + mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
  79441. + i++;
  79442. + msleep(10);
  79443. + }
  79444. +
  79445. + if (i >= 10) {
  79446. + pr_err("mipi csi2 can not receive sensor clk!\n");
  79447. + return -1;
  79448. + }
  79449. +
  79450. + i = 0;
  79451. +
  79452. + /* wait for mipi stable */
  79453. + mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
  79454. + while ((mipi_reg != 0x0) && (i < 10)) {
  79455. + mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
  79456. + i++;
  79457. + msleep(10);
  79458. + }
  79459. +
  79460. + if (i >= 10) {
  79461. + pr_err("mipi csi2 can not reveive data correctly!\n");
  79462. + return -1;
  79463. + }
  79464. + }
  79465. +err:
  79466. + return retval;
  79467. +}
  79468. +
  79469. +/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
  79470. +
  79471. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  79472. +{
  79473. + if (s == NULL) {
  79474. + pr_err(" ERROR!! no slave device set!\n");
  79475. + return -1;
  79476. + }
  79477. +
  79478. + memset(p, 0, sizeof(*p));
  79479. + p->u.bt656.clock_curr = ov5640_data.mclk;
  79480. + pr_debug(" clock_curr=mclk=%d\n", ov5640_data.mclk);
  79481. + p->if_type = V4L2_IF_TYPE_BT656;
  79482. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  79483. + p->u.bt656.clock_min = OV5640_XCLK_MIN;
  79484. + p->u.bt656.clock_max = OV5640_XCLK_MAX;
  79485. + p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
  79486. +
  79487. + return 0;
  79488. +}
  79489. +
  79490. +/*!
  79491. + * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
  79492. + * @s: pointer to standard V4L2 device structure
  79493. + * @on: indicates power mode (on or off)
  79494. + *
  79495. + * Turns the power on or off, depending on the value of on and returns the
  79496. + * appropriate error code.
  79497. + */
  79498. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  79499. +{
  79500. + struct sensor_data *sensor = s->priv;
  79501. +
  79502. + if (on && !sensor->on) {
  79503. + if (io_regulator)
  79504. + if (regulator_enable(io_regulator) != 0)
  79505. + return -EIO;
  79506. + if (core_regulator)
  79507. + if (regulator_enable(core_regulator) != 0)
  79508. + return -EIO;
  79509. + if (gpo_regulator)
  79510. + if (regulator_enable(gpo_regulator) != 0)
  79511. + return -EIO;
  79512. + if (analog_regulator)
  79513. + if (regulator_enable(analog_regulator) != 0)
  79514. + return -EIO;
  79515. + /* Make sure power on */
  79516. + ov5640_standby(0);
  79517. + } else if (!on && sensor->on) {
  79518. + if (analog_regulator)
  79519. + regulator_disable(analog_regulator);
  79520. + if (core_regulator)
  79521. + regulator_disable(core_regulator);
  79522. + if (io_regulator)
  79523. + regulator_disable(io_regulator);
  79524. + if (gpo_regulator)
  79525. + regulator_disable(gpo_regulator);
  79526. +
  79527. + ov5640_standby(1);
  79528. + }
  79529. +
  79530. + sensor->on = on;
  79531. +
  79532. + return 0;
  79533. +}
  79534. +
  79535. +/*!
  79536. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  79537. + * @s: pointer to standard V4L2 device structure
  79538. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  79539. + *
  79540. + * Returns the sensor's video CAPTURE parameters.
  79541. + */
  79542. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  79543. +{
  79544. + struct sensor_data *sensor = s->priv;
  79545. + struct v4l2_captureparm *cparm = &a->parm.capture;
  79546. + int ret = 0;
  79547. +
  79548. + switch (a->type) {
  79549. + /* This is the only case currently handled. */
  79550. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  79551. + memset(a, 0, sizeof(*a));
  79552. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  79553. + cparm->capability = sensor->streamcap.capability;
  79554. + cparm->timeperframe = sensor->streamcap.timeperframe;
  79555. + cparm->capturemode = sensor->streamcap.capturemode;
  79556. + ret = 0;
  79557. + break;
  79558. +
  79559. + /* These are all the possible cases. */
  79560. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  79561. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  79562. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  79563. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  79564. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  79565. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  79566. + ret = -EINVAL;
  79567. + break;
  79568. +
  79569. + default:
  79570. + pr_debug(" type is unknown - %d\n", a->type);
  79571. + ret = -EINVAL;
  79572. + break;
  79573. + }
  79574. +
  79575. + return ret;
  79576. +}
  79577. +
  79578. +/*!
  79579. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  79580. + * @s: pointer to standard V4L2 device structure
  79581. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  79582. + *
  79583. + * Configures the sensor to use the input parameters, if possible. If
  79584. + * not possible, reverts to the old parameters and returns the
  79585. + * appropriate error code.
  79586. + */
  79587. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  79588. +{
  79589. + struct sensor_data *sensor = s->priv;
  79590. + struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
  79591. + u32 tgt_fps; /* target frames per secound */
  79592. + enum ov5640_frame_rate frame_rate;
  79593. + enum ov5640_mode orig_mode;
  79594. + int ret = 0;
  79595. +
  79596. + /* Make sure power on */
  79597. + ov5640_standby(0);
  79598. +
  79599. + switch (a->type) {
  79600. + /* This is the only case currently handled. */
  79601. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  79602. + /* Check that the new frame rate is allowed. */
  79603. + if ((timeperframe->numerator == 0) ||
  79604. + (timeperframe->denominator == 0)) {
  79605. + timeperframe->denominator = DEFAULT_FPS;
  79606. + timeperframe->numerator = 1;
  79607. + }
  79608. +
  79609. + tgt_fps = timeperframe->denominator /
  79610. + timeperframe->numerator;
  79611. +
  79612. + if (tgt_fps > MAX_FPS) {
  79613. + timeperframe->denominator = MAX_FPS;
  79614. + timeperframe->numerator = 1;
  79615. + } else if (tgt_fps < MIN_FPS) {
  79616. + timeperframe->denominator = MIN_FPS;
  79617. + timeperframe->numerator = 1;
  79618. + }
  79619. +
  79620. + /* Actual frame rate we use */
  79621. + tgt_fps = timeperframe->denominator /
  79622. + timeperframe->numerator;
  79623. +
  79624. + if (tgt_fps == 15)
  79625. + frame_rate = ov5640_15_fps;
  79626. + else if (tgt_fps == 30)
  79627. + frame_rate = ov5640_30_fps;
  79628. + else {
  79629. + pr_err(" The camera frame rate is not supported!\n");
  79630. + return -EINVAL;
  79631. + }
  79632. +
  79633. + orig_mode = sensor->streamcap.capturemode;
  79634. + ret = ov5640_init_mode(frame_rate,
  79635. + (u32)a->parm.capture.capturemode, orig_mode);
  79636. + if (ret < 0)
  79637. + return ret;
  79638. +
  79639. + sensor->streamcap.timeperframe = *timeperframe;
  79640. + sensor->streamcap.capturemode =
  79641. + (u32)a->parm.capture.capturemode;
  79642. +
  79643. + break;
  79644. +
  79645. + /* These are all the possible cases. */
  79646. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  79647. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  79648. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  79649. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  79650. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  79651. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  79652. + pr_debug(" type is not " \
  79653. + "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
  79654. + a->type);
  79655. + ret = -EINVAL;
  79656. + break;
  79657. +
  79658. + default:
  79659. + pr_debug(" type is unknown - %d\n", a->type);
  79660. + ret = -EINVAL;
  79661. + break;
  79662. + }
  79663. +
  79664. + return ret;
  79665. +}
  79666. +
  79667. +/*!
  79668. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  79669. + * @s: pointer to standard V4L2 device structure
  79670. + * @f: pointer to standard V4L2 v4l2_format structure
  79671. + *
  79672. + * Returns the sensor's current pixel format in the v4l2_format
  79673. + * parameter.
  79674. + */
  79675. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  79676. +{
  79677. + struct sensor_data *sensor = s->priv;
  79678. +
  79679. + f->fmt.pix = sensor->pix;
  79680. +
  79681. + return 0;
  79682. +}
  79683. +
  79684. +/*!
  79685. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  79686. + * @s: pointer to standard V4L2 device structure
  79687. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  79688. + *
  79689. + * If the requested control is supported, returns the control's current
  79690. + * value from the video_control[] array. Otherwise, returns -EINVAL
  79691. + * if the control is not supported.
  79692. + */
  79693. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  79694. +{
  79695. + int ret = 0;
  79696. +
  79697. + switch (vc->id) {
  79698. + case V4L2_CID_BRIGHTNESS:
  79699. + vc->value = ov5640_data.brightness;
  79700. + break;
  79701. + case V4L2_CID_HUE:
  79702. + vc->value = ov5640_data.hue;
  79703. + break;
  79704. + case V4L2_CID_CONTRAST:
  79705. + vc->value = ov5640_data.contrast;
  79706. + break;
  79707. + case V4L2_CID_SATURATION:
  79708. + vc->value = ov5640_data.saturation;
  79709. + break;
  79710. + case V4L2_CID_RED_BALANCE:
  79711. + vc->value = ov5640_data.red;
  79712. + break;
  79713. + case V4L2_CID_BLUE_BALANCE:
  79714. + vc->value = ov5640_data.blue;
  79715. + break;
  79716. + case V4L2_CID_EXPOSURE:
  79717. + vc->value = ov5640_data.ae_mode;
  79718. + break;
  79719. + default:
  79720. + ret = -EINVAL;
  79721. + }
  79722. +
  79723. + return ret;
  79724. +}
  79725. +
  79726. +/*!
  79727. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  79728. + * @s: pointer to standard V4L2 device structure
  79729. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  79730. + *
  79731. + * If the requested control is supported, sets the control's current
  79732. + * value in HW (and updates the video_control[] array). Otherwise,
  79733. + * returns -EINVAL if the control is not supported.
  79734. + */
  79735. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  79736. +{
  79737. + int retval = 0;
  79738. +
  79739. + pr_debug("In ov5640:ioctl_s_ctrl %d\n",
  79740. + vc->id);
  79741. +
  79742. + switch (vc->id) {
  79743. + case V4L2_CID_BRIGHTNESS:
  79744. + break;
  79745. + case V4L2_CID_CONTRAST:
  79746. + break;
  79747. + case V4L2_CID_SATURATION:
  79748. + break;
  79749. + case V4L2_CID_HUE:
  79750. + break;
  79751. + case V4L2_CID_AUTO_WHITE_BALANCE:
  79752. + break;
  79753. + case V4L2_CID_DO_WHITE_BALANCE:
  79754. + break;
  79755. + case V4L2_CID_RED_BALANCE:
  79756. + break;
  79757. + case V4L2_CID_BLUE_BALANCE:
  79758. + break;
  79759. + case V4L2_CID_GAMMA:
  79760. + break;
  79761. + case V4L2_CID_EXPOSURE:
  79762. + break;
  79763. + case V4L2_CID_AUTOGAIN:
  79764. + break;
  79765. + case V4L2_CID_GAIN:
  79766. + break;
  79767. + case V4L2_CID_HFLIP:
  79768. + break;
  79769. + case V4L2_CID_VFLIP:
  79770. + break;
  79771. + default:
  79772. + retval = -EPERM;
  79773. + break;
  79774. + }
  79775. +
  79776. + return retval;
  79777. +}
  79778. +
  79779. +/*!
  79780. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  79781. + * VIDIOC_ENUM_FRAMESIZES ioctl
  79782. + * @s: pointer to standard V4L2 device structure
  79783. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  79784. + *
  79785. + * Return 0 if successful, otherwise -EINVAL.
  79786. + */
  79787. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  79788. + struct v4l2_frmsizeenum *fsize)
  79789. +{
  79790. + if (fsize->index > ov5640_mode_MAX)
  79791. + return -EINVAL;
  79792. +
  79793. + fsize->pixel_format = ov5640_data.pix.pixelformat;
  79794. + fsize->discrete.width =
  79795. + max(ov5640_mode_info_data[0][fsize->index].width,
  79796. + ov5640_mode_info_data[1][fsize->index].width);
  79797. + fsize->discrete.height =
  79798. + max(ov5640_mode_info_data[0][fsize->index].height,
  79799. + ov5640_mode_info_data[1][fsize->index].height);
  79800. + return 0;
  79801. +}
  79802. +
  79803. +/*!
  79804. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  79805. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  79806. + * @s: pointer to standard V4L2 device structure
  79807. + * @id: pointer to int
  79808. + *
  79809. + * Return 0.
  79810. + */
  79811. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  79812. +{
  79813. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  79814. + V4L2_CHIP_MATCH_I2C_DRIVER;
  79815. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
  79816. + "ov5640_mipi_camera");
  79817. +
  79818. + return 0;
  79819. +}
  79820. +
  79821. +/*!
  79822. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  79823. + * @s: pointer to standard V4L2 device structure
  79824. + */
  79825. +static int ioctl_init(struct v4l2_int_device *s)
  79826. +{
  79827. +
  79828. + return 0;
  79829. +}
  79830. +
  79831. +/*!
  79832. + * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
  79833. + * @s: pointer to standard V4L2 device structure
  79834. + * @fmt: pointer to standard V4L2 fmt description structure
  79835. + *
  79836. + * Return 0.
  79837. + */
  79838. +static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
  79839. + struct v4l2_fmtdesc *fmt)
  79840. +{
  79841. + if (fmt->index > ov5640_mode_MAX)
  79842. + return -EINVAL;
  79843. +
  79844. + fmt->pixelformat = ov5640_data.pix.pixelformat;
  79845. +
  79846. + return 0;
  79847. +}
  79848. +
  79849. +/*!
  79850. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  79851. + * @s: pointer to standard V4L2 device structure
  79852. + *
  79853. + * Initialise the device when slave attaches to the master.
  79854. + */
  79855. +static int ioctl_dev_init(struct v4l2_int_device *s)
  79856. +{
  79857. + struct sensor_data *sensor = s->priv;
  79858. + u32 tgt_xclk; /* target xclk */
  79859. + u32 tgt_fps; /* target frames per secound */
  79860. + int ret;
  79861. + enum ov5640_frame_rate frame_rate;
  79862. + void *mipi_csi2_info;
  79863. +
  79864. + ov5640_data.on = true;
  79865. +
  79866. + /* mclk */
  79867. + tgt_xclk = ov5640_data.mclk;
  79868. + tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
  79869. + tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
  79870. + ov5640_data.mclk = tgt_xclk;
  79871. +
  79872. + pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
  79873. +
  79874. + /* Default camera frame rate is set in probe */
  79875. + tgt_fps = sensor->streamcap.timeperframe.denominator /
  79876. + sensor->streamcap.timeperframe.numerator;
  79877. +
  79878. + if (tgt_fps == 15)
  79879. + frame_rate = ov5640_15_fps;
  79880. + else if (tgt_fps == 30)
  79881. + frame_rate = ov5640_30_fps;
  79882. + else
  79883. + return -EINVAL; /* Only support 15fps or 30fps now. */
  79884. +
  79885. + mipi_csi2_info = mipi_csi2_get_info();
  79886. +
  79887. + /* enable mipi csi2 */
  79888. + if (mipi_csi2_info)
  79889. + mipi_csi2_enable(mipi_csi2_info);
  79890. + else {
  79891. + printk(KERN_ERR "%s() in %s: Fail to get mipi_csi2_info!\n",
  79892. + __func__, __FILE__);
  79893. + return -EPERM;
  79894. + }
  79895. +
  79896. + ret = ov5640_init_mode(frame_rate, ov5640_mode_INIT, ov5640_mode_INIT);
  79897. +
  79898. + return ret;
  79899. +}
  79900. +
  79901. +/*!
  79902. + * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
  79903. + * @s: pointer to standard V4L2 device structure
  79904. + *
  79905. + * Delinitialise the device when slave detaches to the master.
  79906. + */
  79907. +static int ioctl_dev_exit(struct v4l2_int_device *s)
  79908. +{
  79909. + void *mipi_csi2_info;
  79910. +
  79911. + mipi_csi2_info = mipi_csi2_get_info();
  79912. +
  79913. + /* disable mipi csi2 */
  79914. + if (mipi_csi2_info)
  79915. + if (mipi_csi2_get_status(mipi_csi2_info))
  79916. + mipi_csi2_disable(mipi_csi2_info);
  79917. +
  79918. + return 0;
  79919. +}
  79920. +
  79921. +/*!
  79922. + * This structure defines all the ioctls for this module and links them to the
  79923. + * enumeration.
  79924. + */
  79925. +static struct v4l2_int_ioctl_desc ov5640_ioctl_desc[] = {
  79926. + {vidioc_int_dev_init_num, (v4l2_int_ioctl_func *) ioctl_dev_init},
  79927. + {vidioc_int_dev_exit_num, ioctl_dev_exit},
  79928. + {vidioc_int_s_power_num, (v4l2_int_ioctl_func *) ioctl_s_power},
  79929. + {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func *) ioctl_g_ifparm},
  79930. +/* {vidioc_int_g_needs_reset_num,
  79931. + (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
  79932. +/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
  79933. + {vidioc_int_init_num, (v4l2_int_ioctl_func *) ioctl_init},
  79934. + {vidioc_int_enum_fmt_cap_num,
  79935. + (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
  79936. +/* {vidioc_int_try_fmt_cap_num,
  79937. + (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
  79938. + {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
  79939. +/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_s_fmt_cap}, */
  79940. + {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
  79941. + {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
  79942. +/* {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func *)ioctl_queryctrl}, */
  79943. + {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
  79944. + {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
  79945. + {vidioc_int_enum_framesizes_num,
  79946. + (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
  79947. + {vidioc_int_g_chip_ident_num,
  79948. + (v4l2_int_ioctl_func *) ioctl_g_chip_ident},
  79949. +};
  79950. +
  79951. +static struct v4l2_int_slave ov5640_slave = {
  79952. + .ioctls = ov5640_ioctl_desc,
  79953. + .num_ioctls = ARRAY_SIZE(ov5640_ioctl_desc),
  79954. +};
  79955. +
  79956. +static struct v4l2_int_device ov5640_int_device = {
  79957. + .module = THIS_MODULE,
  79958. + .name = "ov5640",
  79959. + .type = v4l2_int_type_slave,
  79960. + .u = {
  79961. + .slave = &ov5640_slave,
  79962. + },
  79963. +};
  79964. +
  79965. +/*!
  79966. + * ov5640 I2C probe function
  79967. + *
  79968. + * @param adapter struct i2c_adapter *
  79969. + * @return Error code indicating success or failure
  79970. + */
  79971. +static int ov5640_probe(struct i2c_client *client,
  79972. + const struct i2c_device_id *id)
  79973. +{
  79974. + struct device *dev = &client->dev;
  79975. + int retval;
  79976. + u8 chip_id_high, chip_id_low;
  79977. +
  79978. + /* request power down pin */
  79979. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  79980. + if (!gpio_is_valid(pwn_gpio)) {
  79981. + dev_warn(dev, "no sensor pwdn pin available");
  79982. + return -EINVAL;
  79983. + }
  79984. + retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  79985. + "ov5640_mipi_pwdn");
  79986. + if (retval < 0)
  79987. + return retval;
  79988. +
  79989. + /* request reset pin */
  79990. + rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
  79991. + if (!gpio_is_valid(rst_gpio)) {
  79992. + dev_warn(dev, "no sensor reset pin available");
  79993. + return -EINVAL;
  79994. + }
  79995. + retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
  79996. + "ov5640_mipi_reset");
  79997. + if (retval < 0)
  79998. + return retval;
  79999. +
  80000. + /* Set initial values for the sensor struct. */
  80001. + memset(&ov5640_data, 0, sizeof(ov5640_data));
  80002. + ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
  80003. + if (IS_ERR(ov5640_data.sensor_clk)) {
  80004. + /* assuming clock enabled by default */
  80005. + ov5640_data.sensor_clk = NULL;
  80006. + dev_err(dev, "clock-frequency missing or invalid\n");
  80007. + return PTR_ERR(ov5640_data.sensor_clk);
  80008. + }
  80009. +
  80010. + retval = of_property_read_u32(dev->of_node, "mclk",
  80011. + &(ov5640_data.mclk));
  80012. + if (retval) {
  80013. + dev_err(dev, "mclk missing or invalid\n");
  80014. + return retval;
  80015. + }
  80016. +
  80017. + retval = of_property_read_u32(dev->of_node, "mclk_source",
  80018. + (u32 *) &(ov5640_data.mclk_source));
  80019. + if (retval) {
  80020. + dev_err(dev, "mclk_source missing or invalid\n");
  80021. + return retval;
  80022. + }
  80023. +
  80024. + retval = of_property_read_u32(dev->of_node, "csi_id",
  80025. + &(ov5640_data.csi));
  80026. + if (retval) {
  80027. + dev_err(dev, "csi id missing or invalid\n");
  80028. + return retval;
  80029. + }
  80030. +
  80031. + clk_prepare_enable(ov5640_data.sensor_clk);
  80032. +
  80033. + ov5640_data.io_init = ov5640_reset;
  80034. + ov5640_data.i2c_client = client;
  80035. + ov5640_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
  80036. + ov5640_data.pix.width = 640;
  80037. + ov5640_data.pix.height = 480;
  80038. + ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
  80039. + V4L2_CAP_TIMEPERFRAME;
  80040. + ov5640_data.streamcap.capturemode = 0;
  80041. + ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
  80042. + ov5640_data.streamcap.timeperframe.numerator = 1;
  80043. +
  80044. + ov5640_power_on(dev);
  80045. +
  80046. + ov5640_reset();
  80047. +
  80048. + ov5640_standby(0);
  80049. +
  80050. + retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
  80051. + if (retval < 0 || chip_id_high != 0x56) {
  80052. + pr_warning("camera ov5640_mipi is not found\n");
  80053. + clk_disable_unprepare(ov5640_data.sensor_clk);
  80054. + return -ENODEV;
  80055. + }
  80056. + retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
  80057. + if (retval < 0 || chip_id_low != 0x40) {
  80058. + pr_warning("camera ov5640_mipi is not found\n");
  80059. + clk_disable_unprepare(ov5640_data.sensor_clk);
  80060. + return -ENODEV;
  80061. + }
  80062. +
  80063. + ov5640_standby(1);
  80064. +
  80065. + ov5640_int_device.priv = &ov5640_data;
  80066. + retval = v4l2_int_device_register(&ov5640_int_device);
  80067. +
  80068. + clk_disable_unprepare(ov5640_data.sensor_clk);
  80069. +
  80070. + pr_info("camera ov5640_mipi is found\n");
  80071. + return retval;
  80072. +}
  80073. +
  80074. +/*!
  80075. + * ov5640 I2C detach function
  80076. + *
  80077. + * @param client struct i2c_client *
  80078. + * @return Error code indicating success or failure
  80079. + */
  80080. +static int ov5640_remove(struct i2c_client *client)
  80081. +{
  80082. + v4l2_int_device_unregister(&ov5640_int_device);
  80083. +
  80084. + if (gpo_regulator)
  80085. + regulator_disable(gpo_regulator);
  80086. +
  80087. + if (analog_regulator)
  80088. + regulator_disable(analog_regulator);
  80089. +
  80090. + if (core_regulator)
  80091. + regulator_disable(core_regulator);
  80092. +
  80093. + if (io_regulator)
  80094. + regulator_disable(io_regulator);
  80095. +
  80096. + return 0;
  80097. +}
  80098. +
  80099. +/*!
  80100. + * ov5640 init function
  80101. + * Called by insmod ov5640_camera.ko.
  80102. + *
  80103. + * @return Error code indicating success or failure
  80104. + */
  80105. +static __init int ov5640_init(void)
  80106. +{
  80107. + u8 err;
  80108. +
  80109. + err = i2c_add_driver(&ov5640_i2c_driver);
  80110. + if (err != 0)
  80111. + pr_err("%s:driver registration failed, error=%d\n",
  80112. + __func__, err);
  80113. +
  80114. + return err;
  80115. +}
  80116. +
  80117. +/*!
  80118. + * OV5640 cleanup function
  80119. + * Called on rmmod ov5640_camera.ko
  80120. + *
  80121. + * @return Error code indicating success or failure
  80122. + */
  80123. +static void __exit ov5640_clean(void)
  80124. +{
  80125. + i2c_del_driver(&ov5640_i2c_driver);
  80126. +}
  80127. +
  80128. +module_init(ov5640_init);
  80129. +module_exit(ov5640_clean);
  80130. +
  80131. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  80132. +MODULE_DESCRIPTION("OV5640 MIPI Camera Driver");
  80133. +MODULE_LICENSE("GPL");
  80134. +MODULE_VERSION("1.0");
  80135. +MODULE_ALIAS("CSI");
  80136. diff -Nur linux-3.14.14/drivers/media/platform/mxc/capture/ov5642.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5642.c
  80137. --- linux-3.14.14/drivers/media/platform/mxc/capture/ov5642.c 1969-12-31 18:00:00.000000000 -0600
  80138. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5642.c 2014-12-08 00:31:53.256418001 -0600
  80139. @@ -0,0 +1,4252 @@
  80140. +/*
  80141. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  80142. + */
  80143. +
  80144. +/*
  80145. + * This program is free software; you can redistribute it and/or modify
  80146. + * it under the terms of the GNU General Public License as published by
  80147. + * the Free Software Foundation; either version 2 of the License, or
  80148. + * (at your option) any later version.
  80149. +
  80150. + * This program is distributed in the hope that it will be useful,
  80151. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  80152. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  80153. + * GNU General Public License for more details.
  80154. +
  80155. + * You should have received a copy of the GNU General Public License along
  80156. + * with this program; if not, write to the Free Software Foundation, Inc.,
  80157. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  80158. + */
  80159. +
  80160. +#include <linux/module.h>
  80161. +#include <linux/init.h>
  80162. +#include <linux/slab.h>
  80163. +#include <linux/ctype.h>
  80164. +#include <linux/types.h>
  80165. +#include <linux/delay.h>
  80166. +#include <linux/clk.h>
  80167. +#include <linux/of_device.h>
  80168. +#include <linux/i2c.h>
  80169. +#include <linux/of_gpio.h>
  80170. +#include <linux/pinctrl/consumer.h>
  80171. +#include <linux/regulator/consumer.h>
  80172. +#include <linux/fsl_devices.h>
  80173. +#include <media/v4l2-chip-ident.h>
  80174. +#include <media/v4l2-int-device.h>
  80175. +#include "mxc_v4l2_capture.h"
  80176. +
  80177. +#define OV5642_VOLTAGE_ANALOG 2800000
  80178. +#define OV5642_VOLTAGE_DIGITAL_CORE 1500000
  80179. +#define OV5642_VOLTAGE_DIGITAL_IO 1800000
  80180. +
  80181. +#define MIN_FPS 15
  80182. +#define MAX_FPS 30
  80183. +#define DEFAULT_FPS 30
  80184. +
  80185. +#define OV5642_XCLK_MIN 6000000
  80186. +#define OV5642_XCLK_MAX 24000000
  80187. +
  80188. +#define OV5642_CHIP_ID_HIGH_BYTE 0x300A
  80189. +#define OV5642_CHIP_ID_LOW_BYTE 0x300B
  80190. +
  80191. +enum ov5642_mode {
  80192. + ov5642_mode_MIN = 0,
  80193. + ov5642_mode_VGA_640_480 = 0,
  80194. + ov5642_mode_QVGA_320_240 = 1,
  80195. + ov5642_mode_NTSC_720_480 = 2,
  80196. + ov5642_mode_PAL_720_576 = 3,
  80197. + ov5642_mode_720P_1280_720 = 4,
  80198. + ov5642_mode_1080P_1920_1080 = 5,
  80199. + ov5642_mode_QSXGA_2592_1944 = 6,
  80200. + ov5642_mode_QCIF_176_144 = 7,
  80201. + ov5642_mode_XGA_1024_768 = 8,
  80202. + ov5642_mode_MAX = 8
  80203. +};
  80204. +
  80205. +enum ov5642_frame_rate {
  80206. + ov5642_15_fps,
  80207. + ov5642_30_fps
  80208. +};
  80209. +
  80210. +static int ov5642_framerates[] = {
  80211. + [ov5642_15_fps] = 15,
  80212. + [ov5642_30_fps] = 30,
  80213. +};
  80214. +
  80215. +struct reg_value {
  80216. + u16 u16RegAddr;
  80217. + u8 u8Val;
  80218. + u8 u8Mask;
  80219. + u32 u32Delay_ms;
  80220. +};
  80221. +
  80222. +struct ov5642_mode_info {
  80223. + enum ov5642_mode mode;
  80224. + u32 width;
  80225. + u32 height;
  80226. + struct reg_value *init_data_ptr;
  80227. + u32 init_data_size;
  80228. +};
  80229. +
  80230. +/*!
  80231. + * Maintains the information on the current state of the sesor.
  80232. + */
  80233. +static struct sensor_data ov5642_data;
  80234. +static int pwn_gpio, rst_gpio;
  80235. +
  80236. +static struct reg_value ov5642_rot_none_VGA[] = {
  80237. + {0x3818, 0xc1, 0x00, 0x00}, {0x3621, 0x87, 0x00, 0x00},
  80238. +};
  80239. +
  80240. +static struct reg_value ov5642_rot_vert_flip_VGA[] = {
  80241. + {0x3818, 0x20, 0xbf, 0x00}, {0x3621, 0x20, 0xff, 0x00},
  80242. +};
  80243. +
  80244. +static struct reg_value ov5642_rot_horiz_flip_VGA[] = {
  80245. + {0x3818, 0x81, 0x00, 0x01}, {0x3621, 0xa7, 0x00, 0x00},
  80246. +};
  80247. +
  80248. +static struct reg_value ov5642_rot_180_VGA[] = {
  80249. + {0x3818, 0x60, 0xff, 0x00}, {0x3621, 0x00, 0xdf, 0x00},
  80250. +};
  80251. +
  80252. +
  80253. +static struct reg_value ov5642_rot_none_FULL[] = {
  80254. + {0x3818, 0xc0, 0x00, 0x00}, {0x3621, 0x09, 0x00, 0x00},
  80255. +};
  80256. +
  80257. +static struct reg_value ov5642_rot_vert_flip_FULL[] = {
  80258. + {0x3818, 0x20, 0xbf, 0x01}, {0x3621, 0x20, 0xff, 0x00},
  80259. +};
  80260. +
  80261. +static struct reg_value ov5642_rot_horiz_flip_FULL[] = {
  80262. + {0x3818, 0x80, 0x00, 0x01}, {0x3621, 0x29, 0x00, 0x00},
  80263. +};
  80264. +
  80265. +static struct reg_value ov5642_rot_180_FULL[] = {
  80266. + {0x3818, 0x60, 0xff, 0x00}, {0x3621, 0x00, 0xdf, 0x00},
  80267. +};
  80268. +
  80269. +
  80270. +static struct reg_value ov5642_initial_setting[] = {
  80271. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  80272. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  80273. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  80274. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  80275. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  80276. + {0x3010, 0x00, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  80277. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  80278. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  80279. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  80280. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  80281. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  80282. + {0x3606, 0x3f, 0, 0}, {0x3c00, 0x04, 0, 0}, {0x3c01, 0x80, 0, 0},
  80283. + {0x5000, 0x4f, 0, 0}, {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0},
  80284. + {0x5182, 0x00, 0, 0}, {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0},
  80285. + {0x5001, 0xff, 0, 0}, {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0},
  80286. + {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0},
  80287. + {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0},
  80288. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  80289. + {0x380b, 0xe0, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0},
  80290. + {0x501f, 0x00, 0, 0}, {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0},
  80291. + {0x3503, 0x07, 0, 0}, {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0},
  80292. + {0x350b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0},
  80293. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  80294. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0},
  80295. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80296. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  80297. + {0x3801, 0x80, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0},
  80298. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0},
  80299. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  80300. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  80301. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  80302. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  80303. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  80304. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  80305. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  80306. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  80307. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  80308. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  80309. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  80310. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  80311. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  80312. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  80313. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  80314. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  80315. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  80316. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x0b, 0, 0}, {0x3a02, 0x00, 0, 0},
  80317. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  80318. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  80319. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  80320. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  80321. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  80322. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  80323. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  80324. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  80325. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  80326. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  80327. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  80328. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  80329. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  80330. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  80331. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  80332. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  80333. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  80334. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  80335. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  80336. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  80337. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  80338. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  80339. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  80340. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  80341. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  80342. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  80343. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  80344. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  80345. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  80346. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  80347. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  80348. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  80349. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  80350. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  80351. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  80352. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  80353. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  80354. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  80355. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  80356. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  80357. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  80358. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  80359. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  80360. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  80361. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  80362. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  80363. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  80364. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  80365. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  80366. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  80367. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  80368. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  80369. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  80370. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  80371. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  80372. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  80373. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  80374. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  80375. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  80376. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  80377. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  80378. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  80379. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  80380. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  80381. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  80382. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  80383. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  80384. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  80385. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  80386. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  80387. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  80388. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  80389. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  80390. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  80391. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  80392. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  80393. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  80394. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  80395. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  80396. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  80397. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  80398. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  80399. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  80400. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  80401. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  80402. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  80403. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  80404. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  80405. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  80406. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  80407. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  80408. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  80409. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  80410. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  80411. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  80412. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  80413. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  80414. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  80415. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  80416. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  80417. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  80418. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  80419. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  80420. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  80421. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  80422. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  80423. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  80424. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  80425. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  80426. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  80427. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  80428. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  80429. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  80430. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  80431. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  80432. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  80433. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  80434. + {0x302b, 0x00, 0, 300},
  80435. +};
  80436. +
  80437. +static struct reg_value ov5642_setting_15fps_QCIF_176_144[] = {
  80438. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  80439. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  80440. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  80441. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  80442. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  80443. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  80444. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  80445. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  80446. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  80447. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  80448. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  80449. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  80450. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  80451. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  80452. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  80453. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  80454. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  80455. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  80456. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  80457. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  80458. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  80459. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  80460. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  80461. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  80462. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  80463. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  80464. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  80465. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  80466. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  80467. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  80468. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  80469. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  80470. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  80471. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  80472. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  80473. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  80474. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  80475. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  80476. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  80477. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  80478. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  80479. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  80480. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  80481. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  80482. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  80483. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  80484. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  80485. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  80486. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  80487. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  80488. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  80489. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  80490. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  80491. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  80492. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  80493. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  80494. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  80495. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  80496. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  80497. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  80498. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  80499. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  80500. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  80501. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  80502. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  80503. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  80504. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  80505. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  80506. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  80507. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  80508. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  80509. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  80510. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  80511. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  80512. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  80513. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  80514. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  80515. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  80516. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  80517. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  80518. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  80519. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  80520. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  80521. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  80522. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  80523. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  80524. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  80525. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  80526. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  80527. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  80528. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  80529. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  80530. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  80531. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  80532. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  80533. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  80534. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  80535. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  80536. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  80537. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  80538. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  80539. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  80540. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  80541. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  80542. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  80543. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  80544. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  80545. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  80546. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  80547. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  80548. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  80549. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  80550. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  80551. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  80552. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  80553. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  80554. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  80555. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  80556. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  80557. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  80558. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  80559. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  80560. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  80561. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  80562. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  80563. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  80564. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  80565. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  80566. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  80567. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  80568. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  80569. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  80570. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  80571. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  80572. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  80573. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  80574. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  80575. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  80576. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  80577. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  80578. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  80579. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  80580. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  80581. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  80582. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  80583. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  80584. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  80585. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  80586. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  80587. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  80588. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  80589. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  80590. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  80591. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  80592. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  80593. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  80594. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  80595. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  80596. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  80597. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  80598. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  80599. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  80600. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  80601. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  80602. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  80603. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  80604. + {0x380b, 0x90, 0, 0}, {0x3a00, 0x78, 0, 0},
  80605. +};
  80606. +
  80607. +static struct reg_value ov5642_setting_30fps_QCIF_176_144[] = {
  80608. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  80609. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  80610. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  80611. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  80612. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x10, 0, 0},
  80613. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  80614. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  80615. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  80616. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  80617. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  80618. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  80619. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  80620. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  80621. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  80622. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  80623. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  80624. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  80625. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  80626. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  80627. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  80628. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  80629. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  80630. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  80631. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  80632. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  80633. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  80634. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  80635. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  80636. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  80637. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  80638. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  80639. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  80640. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  80641. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  80642. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  80643. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  80644. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  80645. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  80646. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  80647. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  80648. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  80649. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  80650. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  80651. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  80652. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  80653. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  80654. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  80655. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  80656. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  80657. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  80658. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  80659. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  80660. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  80661. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  80662. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  80663. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  80664. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  80665. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  80666. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  80667. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  80668. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  80669. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  80670. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  80671. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  80672. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  80673. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  80674. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  80675. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  80676. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  80677. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  80678. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  80679. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  80680. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  80681. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  80682. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  80683. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  80684. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  80685. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  80686. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  80687. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  80688. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  80689. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  80690. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  80691. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  80692. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  80693. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  80694. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  80695. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  80696. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  80697. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  80698. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  80699. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  80700. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  80701. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  80702. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  80703. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  80704. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  80705. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  80706. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  80707. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  80708. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  80709. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  80710. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  80711. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  80712. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  80713. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  80714. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  80715. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  80716. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  80717. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  80718. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  80719. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  80720. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  80721. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  80722. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  80723. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  80724. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  80725. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  80726. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  80727. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  80728. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  80729. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  80730. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  80731. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  80732. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  80733. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  80734. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  80735. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  80736. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  80737. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  80738. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  80739. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  80740. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  80741. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  80742. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  80743. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  80744. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  80745. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  80746. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  80747. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  80748. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  80749. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  80750. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  80751. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  80752. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  80753. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  80754. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  80755. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  80756. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  80757. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  80758. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  80759. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  80760. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  80761. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  80762. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  80763. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  80764. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  80765. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  80766. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  80767. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  80768. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  80769. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  80770. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  80771. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  80772. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  80773. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  80774. + {0x380b, 0x90, 0, 0}, {0x3a00, 0x78, 0, 0},
  80775. +};
  80776. +
  80777. +static struct reg_value ov5642_setting_15fps_QSXGA_2592_1944[] = {
  80778. + {0x3503, 0x07, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0},
  80779. + {0x3002, 0x00, 0, 0}, {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
  80780. + {0x3005, 0xff, 0, 0}, {0x3006, 0xff, 0, 0}, {0x3007, 0x3f, 0, 0},
  80781. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3818, 0xc0, 0, 0},
  80782. + {0x3621, 0x09, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  80783. + {0x3602, 0xe4, 0, 0}, {0x3612, 0xac, 0, 0}, {0x3613, 0x44, 0, 0},
  80784. + {0x3622, 0x60, 0, 0}, {0x3623, 0x22, 0, 0}, {0x3604, 0x48, 0, 0},
  80785. + {0x3705, 0xda, 0, 0}, {0x370a, 0x80, 0, 0}, {0x3801, 0x95, 0, 0},
  80786. + {0x3803, 0x0e, 0, 0}, {0x3804, 0x0a, 0, 0}, {0x3805, 0x20, 0, 0},
  80787. + {0x3806, 0x07, 0, 0}, {0x3807, 0x98, 0, 0}, {0x3808, 0x0a, 0, 0},
  80788. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  80789. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  80790. + {0x380f, 0xd0, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3815, 0x44, 0, 0},
  80791. + {0x3824, 0x11, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  80792. + {0x3a00, 0x78, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  80793. + {0x5682, 0x0a, 0, 0}, {0x5683, 0x20, 0, 0}, {0x5686, 0x07, 0, 0},
  80794. + {0x5687, 0x98, 0, 0}, {0x5001, 0xff, 0, 0}, {0x589b, 0x00, 0, 0},
  80795. + {0x589a, 0xc0, 0, 0}, {0x4407, 0x04, 0, 0}, {0x3008, 0x02, 0, 0},
  80796. + {0x460b, 0x37, 0, 0}, {0x460c, 0x22, 0, 0}, {0x471d, 0x05, 0, 0},
  80797. + {0x4713, 0x03, 0, 0}, {0x471c, 0xd0, 0, 0}, {0x3815, 0x01, 0, 0},
  80798. + {0x501f, 0x00, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3819, 0x80, 0, 0},
  80799. + {0x5002, 0xe0, 0, 0}, {0x530a, 0x01, 0, 0}, {0x530d, 0x10, 0, 0},
  80800. + {0x530c, 0x04, 0, 0}, {0x5312, 0x20, 0, 0}, {0x5282, 0x01, 0, 0},
  80801. + {0x3010, 0x10, 0, 0}, {0x3012, 0x00, 0, 0},
  80802. +};
  80803. +
  80804. +
  80805. +static struct reg_value ov5642_setting_VGA_2_QVGA[] = {
  80806. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  80807. + {0x380b, 0xf0, 0, 0}, {0x3815, 0x04, 0, 0},
  80808. +};
  80809. +
  80810. +static struct reg_value ov5642_setting_QSXGA_2_VGA[] = {
  80811. + {0x3503, 0x00, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0},
  80812. + {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
  80813. + {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0},
  80814. + {0x3010, 0x00, 0, 0}, {0x3818, 0xc1, 0, 0}, {0x3621, 0x87, 0, 0},
  80815. + {0x350c, 0x03, 0, 0}, {0x350d, 0xe8, 0, 0}, {0x3602, 0xfc, 0, 0},
  80816. + {0x3612, 0xff, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3622, 0x60, 0, 0},
  80817. + {0x3623, 0x01, 0, 0}, {0x3604, 0x48, 0, 0}, {0x3705, 0xdb, 0, 0},
  80818. + {0x370a, 0x81, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  80819. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x3806, 0x03, 0, 0},
  80820. + {0x3807, 0xc0, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
  80821. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x0c, 0, 0},
  80822. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  80823. + {0x3810, 0x40, 0, 0}, {0x3815, 0x04, 0, 0}, {0x3824, 0x11, 0, 0},
  80824. + {0x3825, 0xb4, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3a00, 0x78, 0, 0},
  80825. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x5682, 0x05, 0, 0},
  80826. + {0x5683, 0x00, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0},
  80827. + {0x5001, 0xff, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  80828. + {0x4407, 0x0c, 0, 0}, {0x3008, 0x02, 0, 0}, {0x460b, 0x37, 0, 0},
  80829. + {0x460c, 0x22, 0, 0}, {0x471d, 0x05, 0, 0}, {0x4713, 0x02, 0, 0},
  80830. + {0x471c, 0xd0, 0, 0}, {0x3815, 0x04, 0, 0}, {0x501f, 0x00, 0, 0},
  80831. + {0x3002, 0x5c, 0, 0}, {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0},
  80832. + {0x530a, 0x01, 0, 0}, {0x530d, 0x0c, 0, 0}, {0x530c, 0x00, 0, 0},
  80833. + {0x5312, 0x40, 0, 0}, {0x5282, 0x00, 0, 0},
  80834. + {0x3012, 0x02, 0, 0}, {0x3010, 0x00, 0, 0},
  80835. +};
  80836. +
  80837. +static struct reg_value ov5642_setting_30fps_VGA_640_480[] = {
  80838. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  80839. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  80840. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  80841. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  80842. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  80843. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  80844. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  80845. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  80846. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  80847. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  80848. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  80849. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  80850. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  80851. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  80852. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  80853. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  80854. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  80855. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  80856. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  80857. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  80858. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  80859. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  80860. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  80861. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  80862. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80863. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  80864. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  80865. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  80866. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  80867. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  80868. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  80869. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  80870. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  80871. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  80872. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  80873. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  80874. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  80875. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  80876. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  80877. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  80878. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  80879. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  80880. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  80881. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  80882. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  80883. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  80884. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  80885. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  80886. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  80887. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80888. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  80889. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  80890. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  80891. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  80892. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  80893. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  80894. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  80895. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  80896. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  80897. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  80898. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  80899. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  80900. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  80901. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  80902. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  80903. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  80904. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  80905. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  80906. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  80907. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  80908. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  80909. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  80910. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  80911. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  80912. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  80913. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  80914. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  80915. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  80916. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  80917. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  80918. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  80919. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  80920. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  80921. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  80922. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  80923. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  80924. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  80925. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  80926. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  80927. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  80928. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  80929. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  80930. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  80931. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  80932. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  80933. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  80934. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  80935. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  80936. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  80937. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  80938. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  80939. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  80940. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  80941. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  80942. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  80943. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  80944. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  80945. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  80946. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  80947. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  80948. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  80949. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  80950. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  80951. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  80952. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  80953. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  80954. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  80955. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  80956. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  80957. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  80958. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  80959. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  80960. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  80961. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  80962. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  80963. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  80964. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  80965. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  80966. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  80967. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  80968. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  80969. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  80970. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  80971. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  80972. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  80973. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  80974. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  80975. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  80976. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  80977. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  80978. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  80979. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  80980. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  80981. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  80982. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  80983. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  80984. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  80985. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  80986. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  80987. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  80988. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  80989. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  80990. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  80991. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  80992. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  80993. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  80994. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  80995. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  80996. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  80997. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  80998. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  80999. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81000. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81001. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81002. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81003. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  81004. +};
  81005. +
  81006. +static struct reg_value ov5642_setting_15fps_VGA_640_480[] = {
  81007. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81008. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81009. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81010. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81011. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81012. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81013. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81014. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81015. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81016. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81017. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81018. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81019. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81020. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81021. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81022. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81023. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81024. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  81025. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81026. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81027. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81028. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  81029. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81030. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x07, 0, 0},
  81031. + {0x380f, 0xd0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81032. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81033. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81034. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  81035. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  81036. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  81037. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  81038. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81039. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81040. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81041. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81042. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81043. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81044. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81045. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81046. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81047. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81048. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81049. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81050. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81051. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81052. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81053. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81054. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81055. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81056. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81057. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81058. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81059. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81060. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81061. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81062. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81063. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81064. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81065. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81066. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81067. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81068. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81069. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81070. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81071. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81072. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81073. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81074. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81075. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81076. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81077. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81078. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81079. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81080. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81081. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81082. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81083. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81084. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81085. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81086. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81087. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81088. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81089. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81090. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81091. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81092. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81093. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81094. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81095. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81096. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81097. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81098. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81099. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81100. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81101. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81102. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81103. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81104. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81105. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81106. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81107. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81108. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81109. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81110. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81111. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81112. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81113. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81114. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81115. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81116. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81117. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81118. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  81119. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  81120. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  81121. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  81122. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  81123. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  81124. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  81125. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  81126. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  81127. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  81128. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  81129. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  81130. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  81131. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  81132. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  81133. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  81134. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  81135. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  81136. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  81137. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  81138. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  81139. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81140. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81141. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81142. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81143. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81144. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81145. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81146. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81147. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  81148. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  81149. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  81150. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  81151. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  81152. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  81153. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  81154. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  81155. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  81156. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  81157. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  81158. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  81159. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  81160. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  81161. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  81162. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  81163. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  81164. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  81165. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  81166. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  81167. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  81168. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81169. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81170. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81171. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81172. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  81173. +};
  81174. +
  81175. +
  81176. +static struct reg_value ov5642_setting_30fps_XGA_1024_768[] = {
  81177. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81178. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81179. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81180. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81181. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81182. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81183. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81184. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81185. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81186. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81187. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81188. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81189. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81190. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81191. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81192. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81193. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81194. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  81195. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81196. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81197. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81198. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  81199. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81200. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  81201. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81202. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81203. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81204. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  81205. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  81206. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  81207. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  81208. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81209. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81210. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81211. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81212. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81213. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81214. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81215. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81216. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81217. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81218. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81219. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81220. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81221. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81222. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81223. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81224. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81225. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81226. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81227. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81228. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81229. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81230. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81231. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81232. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81233. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81234. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81235. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81236. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81237. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81238. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81239. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81240. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81241. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81242. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81243. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81244. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81245. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81246. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81247. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81248. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81249. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81250. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81251. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81252. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81253. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81254. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81255. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81256. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81257. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81258. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81259. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81260. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81261. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81262. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81263. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81264. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81265. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81266. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81267. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81268. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81269. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81270. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81271. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81272. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81273. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81274. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81275. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81276. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81277. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81278. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81279. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81280. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81281. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81282. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81283. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81284. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81285. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81286. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81287. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81288. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  81289. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  81290. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  81291. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  81292. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  81293. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  81294. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  81295. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  81296. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  81297. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  81298. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  81299. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  81300. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  81301. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  81302. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  81303. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  81304. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  81305. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  81306. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  81307. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  81308. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  81309. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81310. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81311. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81312. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81313. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81314. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81315. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81316. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81317. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  81318. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  81319. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  81320. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  81321. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  81322. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  81323. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  81324. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  81325. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  81326. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  81327. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  81328. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  81329. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  81330. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  81331. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  81332. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  81333. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  81334. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  81335. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  81336. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  81337. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  81338. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81339. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81340. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81341. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81342. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  81343. + {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
  81344. + {0x380b, 0x00, 0, 0}, {0x3815, 0x02, 0, 0}, {0x302c, 0x60, 0x60, 0},
  81345. +};
  81346. +
  81347. +static struct reg_value ov5642_setting_15fps_XGA_1024_768[] = {
  81348. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81349. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81350. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81351. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81352. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81353. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81354. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81355. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81356. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81357. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81358. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81359. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81360. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81361. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81362. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81363. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81364. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81365. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  81366. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81367. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81368. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81369. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  81370. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81371. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x07, 0, 0},
  81372. + {0x380f, 0xd0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81373. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81374. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81375. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  81376. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  81377. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  81378. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  81379. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81380. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81381. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81382. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81383. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81384. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81385. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81386. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81387. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81388. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81389. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81390. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81391. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81392. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81393. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81394. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81395. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81396. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81397. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81398. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81399. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81400. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81401. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81402. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81403. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81404. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81405. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81406. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81407. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81408. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81409. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81410. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81411. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81412. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81413. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81414. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81415. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81416. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81417. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81418. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81419. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81420. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81421. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81422. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81423. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81424. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81425. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81426. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81427. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81428. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81429. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81430. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81431. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81432. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81433. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81434. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81435. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81436. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81437. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81438. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81439. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81440. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81441. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81442. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81443. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81444. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81445. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81446. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81447. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81448. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81449. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81450. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81451. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81452. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81453. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81454. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81455. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81456. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81457. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81458. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81459. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  81460. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  81461. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  81462. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  81463. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  81464. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  81465. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  81466. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  81467. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  81468. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  81469. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  81470. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  81471. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  81472. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  81473. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  81474. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  81475. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  81476. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  81477. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  81478. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  81479. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  81480. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81481. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81482. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81483. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81484. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81485. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81486. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81487. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81488. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  81489. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  81490. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  81491. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  81492. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  81493. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  81494. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  81495. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  81496. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  81497. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  81498. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  81499. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  81500. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  81501. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  81502. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  81503. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  81504. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  81505. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  81506. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  81507. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  81508. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  81509. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81510. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81511. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81512. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81513. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  81514. + {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
  81515. + {0x380b, 0x00, 0, 0}, {0x3815, 0x02, 0, 0}, {0x302c, 0x60, 0x60, 0},
  81516. +};
  81517. +
  81518. +static struct reg_value ov5642_setting_30fps_QVGA_320_240[] = {
  81519. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81520. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81521. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81522. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81523. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81524. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81525. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81526. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81527. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81528. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81529. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81530. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81531. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81532. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81533. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81534. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81535. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81536. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  81537. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81538. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81539. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81540. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  81541. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81542. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  81543. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81544. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81545. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81546. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  81547. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  81548. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  81549. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  81550. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81551. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81552. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81553. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81554. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81555. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81556. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81557. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81558. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81559. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81560. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81561. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81562. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81563. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81564. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81565. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81566. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81567. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81568. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81569. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81570. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81571. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81572. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81573. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81574. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81575. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81576. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81577. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81578. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81579. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81580. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81581. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81582. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81583. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81584. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81585. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81586. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81587. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81588. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81589. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81590. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81591. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81592. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81593. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81594. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81595. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81596. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81597. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81598. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81599. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81600. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81601. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81602. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81603. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81604. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81605. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81606. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81607. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81608. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81609. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81610. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81611. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81612. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81613. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81614. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81615. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81616. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81617. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81618. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81619. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81620. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81621. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81622. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81623. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81624. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81625. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81626. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81627. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81628. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81629. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81630. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  81631. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  81632. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  81633. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  81634. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  81635. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  81636. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  81637. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  81638. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  81639. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  81640. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  81641. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  81642. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  81643. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  81644. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  81645. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  81646. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  81647. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  81648. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  81649. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  81650. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  81651. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81652. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81653. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81654. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81655. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81656. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81657. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81658. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81659. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  81660. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  81661. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  81662. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  81663. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  81664. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  81665. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  81666. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  81667. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  81668. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  81669. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  81670. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  81671. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  81672. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  81673. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  81674. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  81675. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  81676. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  81677. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  81678. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  81679. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  81680. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81681. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81682. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81683. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81684. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3808, 0x01, 0, 0},
  81685. + {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0},
  81686. +};
  81687. +
  81688. +static struct reg_value ov5642_setting_30fps_NTSC_720_480[] = {
  81689. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81690. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81691. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81692. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81693. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81694. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81695. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81696. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81697. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81698. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81699. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81700. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81701. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81702. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81703. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81704. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81705. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81706. + {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  81707. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81708. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81709. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81710. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  81711. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81712. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  81713. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81714. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81715. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81716. + {0x3803, 0x08, 0, 0}, {0x3827, 0x3c, 0, 0}, {0x3810, 0x80, 0, 0},
  81717. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  81718. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0x58, 0, 0},
  81719. + {0x5686, 0x03, 0, 0}, {0x5687, 0x58, 0, 0}, {0x3a00, 0x78, 0, 0},
  81720. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81721. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81722. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81723. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81724. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81725. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81726. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81727. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81728. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81729. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81730. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81731. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81732. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81733. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81734. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81735. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81736. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81737. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81738. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81739. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81740. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81741. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81742. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81743. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81744. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81745. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81746. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81747. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81748. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81749. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81750. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81751. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81752. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81753. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81754. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81755. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81756. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81757. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81758. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81759. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81760. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81761. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81762. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81763. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81764. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81765. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81766. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81767. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81768. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81769. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81770. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81771. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81772. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81773. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81774. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81775. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81776. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81777. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81778. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81779. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81780. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81781. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81782. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81783. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81784. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81785. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81786. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81787. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81788. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81789. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81790. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81791. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81792. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81793. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81794. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81795. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81796. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81797. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81798. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81799. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81800. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  81801. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  81802. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  81803. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  81804. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  81805. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  81806. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  81807. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  81808. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  81809. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  81810. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  81811. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  81812. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  81813. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  81814. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  81815. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  81816. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  81817. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  81818. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  81819. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  81820. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  81821. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81822. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81823. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81824. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81825. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81826. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81827. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81828. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81829. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  81830. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  81831. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  81832. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  81833. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  81834. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  81835. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  81836. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  81837. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  81838. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  81839. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  81840. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  81841. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  81842. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  81843. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  81844. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  81845. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  81846. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  81847. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  81848. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  81849. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  81850. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  81851. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  81852. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  81853. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  81854. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  81855. + {0x302c, 0x60, 0x60, 0},
  81856. +};
  81857. +
  81858. +static struct reg_value ov5642_setting_30fps_PAL_720_576[] = {
  81859. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  81860. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  81861. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  81862. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  81863. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  81864. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  81865. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  81866. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  81867. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  81868. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  81869. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  81870. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  81871. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  81872. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  81873. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  81874. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  81875. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  81876. + {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0},
  81877. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  81878. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  81879. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  81880. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xd8, 0, 0},
  81881. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  81882. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  81883. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81884. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  81885. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  81886. + {0x3803, 0x08, 0, 0}, {0x3827, 0x3c, 0, 0}, {0x3810, 0x80, 0, 0},
  81887. + {0x3804, 0x04, 0, 0}, {0x3805, 0xb0, 0, 0}, {0x5682, 0x04, 0, 0},
  81888. + {0x5683, 0xb0, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0x58, 0, 0},
  81889. + {0x5686, 0x03, 0, 0}, {0x5687, 0x58, 0, 0}, {0x3a00, 0x78, 0, 0},
  81890. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  81891. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  81892. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  81893. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  81894. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  81895. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  81896. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  81897. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  81898. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  81899. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  81900. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  81901. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  81902. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  81903. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  81904. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  81905. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  81906. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  81907. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  81908. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  81909. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  81910. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  81911. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  81912. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  81913. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  81914. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  81915. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  81916. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  81917. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  81918. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  81919. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  81920. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  81921. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  81922. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  81923. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  81924. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  81925. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  81926. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  81927. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  81928. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  81929. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  81930. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  81931. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  81932. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  81933. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  81934. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  81935. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  81936. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  81937. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  81938. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  81939. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  81940. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  81941. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  81942. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  81943. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  81944. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  81945. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  81946. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  81947. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  81948. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  81949. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  81950. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  81951. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  81952. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  81953. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  81954. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  81955. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  81956. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  81957. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  81958. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  81959. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  81960. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  81961. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  81962. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  81963. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  81964. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  81965. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  81966. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  81967. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  81968. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  81969. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  81970. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  81971. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  81972. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  81973. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  81974. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  81975. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  81976. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  81977. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  81978. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  81979. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  81980. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  81981. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  81982. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  81983. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  81984. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  81985. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  81986. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  81987. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  81988. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  81989. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  81990. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  81991. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  81992. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  81993. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  81994. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  81995. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  81996. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  81997. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  81998. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  81999. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  82000. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  82001. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  82002. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  82003. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  82004. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  82005. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  82006. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  82007. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  82008. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  82009. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  82010. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  82011. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  82012. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  82013. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  82014. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  82015. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  82016. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  82017. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  82018. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  82019. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  82020. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  82021. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  82022. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  82023. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  82024. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  82025. + {0x302c, 0x60, 0x60, 0},
  82026. +};
  82027. +
  82028. +static struct reg_value ov5642_setting_15fps_720P_1280_720[] = {
  82029. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82030. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82031. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
  82032. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
  82033. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
  82034. + {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
  82035. + {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
  82036. + {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
  82037. + {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
  82038. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82039. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
  82040. + {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
  82041. + {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
  82042. + {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
  82043. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  82044. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  82045. + {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
  82046. + {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
  82047. + {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
  82048. + {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
  82049. + {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
  82050. + {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
  82051. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82052. + {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
  82053. + {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
  82054. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
  82055. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
  82056. + {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
  82057. + {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  82058. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  82059. + {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
  82060. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
  82061. + {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  82062. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  82063. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  82064. + {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
  82065. + {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  82066. + {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
  82067. + {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
  82068. + {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  82069. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82070. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  82071. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  82072. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  82073. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  82074. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  82075. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  82076. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  82077. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  82078. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  82079. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  82080. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  82081. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  82082. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  82083. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  82084. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  82085. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  82086. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  82087. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  82088. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  82089. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  82090. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  82091. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  82092. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  82093. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  82094. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  82095. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  82096. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  82097. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  82098. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  82099. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  82100. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  82101. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  82102. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  82103. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  82104. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  82105. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  82106. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  82107. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  82108. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  82109. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  82110. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  82111. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  82112. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  82113. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  82114. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  82115. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  82116. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  82117. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  82118. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  82119. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  82120. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  82121. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  82122. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82123. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  82124. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  82125. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  82126. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  82127. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  82128. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  82129. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  82130. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  82131. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  82132. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  82133. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  82134. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  82135. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  82136. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  82137. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  82138. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  82139. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  82140. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  82141. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  82142. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  82143. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  82144. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  82145. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  82146. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  82147. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  82148. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  82149. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  82150. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  82151. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  82152. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  82153. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  82154. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  82155. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  82156. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  82157. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  82158. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  82159. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  82160. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  82161. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  82162. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  82163. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  82164. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  82165. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  82166. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  82167. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  82168. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  82169. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  82170. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  82171. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  82172. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  82173. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  82174. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  82175. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  82176. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  82177. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  82178. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  82179. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  82180. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  82181. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  82182. + {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x08, 0, 0},
  82183. + {0x350c, 0x02, 0, 0}, {0x350d, 0xe4, 0, 0}, {0x3621, 0xc9, 0, 0},
  82184. + {0x370a, 0x81, 0, 0}, {0x3803, 0x08, 0, 0}, {0x3804, 0x05, 0, 0},
  82185. + {0x3805, 0x00, 0, 0}, {0x3806, 0x02, 0, 0}, {0x3807, 0xd0, 0, 0},
  82186. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  82187. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x08, 0, 0}, {0x380d, 0x72, 0, 0},
  82188. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0xc0, 0, 0},
  82189. + {0x3818, 0xc9, 0, 0}, {0x381c, 0x10, 0, 0}, {0x381d, 0xa0, 0, 0},
  82190. + {0x381e, 0x05, 0, 0}, {0x381f, 0xb0, 0, 0}, {0x3820, 0x00, 0, 0},
  82191. + {0x3821, 0x00, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3a08, 0x1b, 0, 0},
  82192. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x17, 0, 0}, {0x3a0b, 0x20, 0, 0},
  82193. + {0x3a0d, 0x02, 0, 0}, {0x3a0e, 0x01, 0, 0}, {0x401c, 0x04, 0, 0},
  82194. + {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0}, {0x5686, 0x02, 0, 0},
  82195. + {0x5687, 0xcc, 0, 0}, {0x5001, 0x7f, 0, 0}, {0x589b, 0x06, 0, 0},
  82196. + {0x589a, 0xc5, 0, 0}, {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0},
  82197. + {0x460c, 0x20, 0, 0}, {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0},
  82198. + {0x471d, 0x05, 0, 0}, {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0},
  82199. + {0x501f, 0x00, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0},
  82200. + {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0}, {0x3010, 0x30, 0, 0},
  82201. + {0x3a08, 0x06, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x05, 0, 0},
  82202. + {0x3a0b, 0x50, 0, 0}, {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x07, 0, 0},
  82203. +};
  82204. +
  82205. +static struct reg_value ov5642_setting_30fps_720P_1280_720[] = {
  82206. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82207. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82208. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
  82209. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
  82210. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
  82211. + {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
  82212. + {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
  82213. + {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
  82214. + {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
  82215. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82216. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
  82217. + {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
  82218. + {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
  82219. + {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
  82220. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  82221. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  82222. + {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
  82223. + {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
  82224. + {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
  82225. + {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
  82226. + {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
  82227. + {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
  82228. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82229. + {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
  82230. + {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
  82231. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
  82232. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
  82233. + {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
  82234. + {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  82235. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  82236. + {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
  82237. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
  82238. + {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  82239. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  82240. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  82241. + {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
  82242. + {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  82243. + {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
  82244. + {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
  82245. + {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  82246. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82247. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  82248. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  82249. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  82250. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  82251. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  82252. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  82253. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  82254. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  82255. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  82256. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  82257. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  82258. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  82259. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  82260. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  82261. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  82262. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  82263. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  82264. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  82265. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  82266. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  82267. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  82268. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  82269. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  82270. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  82271. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  82272. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  82273. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  82274. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  82275. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  82276. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  82277. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  82278. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  82279. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  82280. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  82281. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  82282. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  82283. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  82284. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  82285. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  82286. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  82287. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  82288. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  82289. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  82290. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  82291. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  82292. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  82293. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  82294. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  82295. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  82296. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  82297. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  82298. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  82299. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82300. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  82301. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  82302. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  82303. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  82304. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  82305. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  82306. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  82307. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  82308. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  82309. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  82310. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  82311. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  82312. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  82313. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  82314. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  82315. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  82316. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  82317. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  82318. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  82319. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  82320. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  82321. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  82322. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  82323. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  82324. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  82325. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  82326. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  82327. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  82328. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  82329. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  82330. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  82331. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  82332. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  82333. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  82334. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  82335. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  82336. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  82337. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  82338. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  82339. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  82340. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  82341. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  82342. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  82343. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  82344. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  82345. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  82346. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  82347. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  82348. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  82349. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  82350. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  82351. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  82352. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  82353. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  82354. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  82355. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  82356. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  82357. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  82358. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  82359. + {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x08, 0, 0},
  82360. + {0x350c, 0x02, 0, 0}, {0x350d, 0xe4, 0, 0}, {0x3621, 0xc9, 0, 0},
  82361. + {0x370a, 0x81, 0, 0}, {0x3803, 0x08, 0, 0}, {0x3804, 0x05, 0, 0},
  82362. + {0x3805, 0x00, 0, 0}, {0x3806, 0x02, 0, 0}, {0x3807, 0xd0, 0, 0},
  82363. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  82364. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x08, 0, 0}, {0x380d, 0x72, 0, 0},
  82365. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0xc0, 0, 0},
  82366. + {0x3818, 0xc9, 0, 0}, {0x381c, 0x10, 0, 0}, {0x381d, 0xa0, 0, 0},
  82367. + {0x381e, 0x05, 0, 0}, {0x381f, 0xb0, 0, 0}, {0x3820, 0x00, 0, 0},
  82368. + {0x3821, 0x00, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3a08, 0x1b, 0, 0},
  82369. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x17, 0, 0}, {0x3a0b, 0x20, 0, 0},
  82370. + {0x3a0d, 0x02, 0, 0}, {0x3a0e, 0x01, 0, 0}, {0x401c, 0x04, 0, 0},
  82371. + {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0}, {0x5686, 0x02, 0, 0},
  82372. + {0x5687, 0xcc, 0, 0}, {0x5001, 0x7f, 0, 0}, {0x589b, 0x06, 0, 0},
  82373. + {0x589a, 0xc5, 0, 0}, {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0},
  82374. + {0x460c, 0x20, 0, 0}, {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0},
  82375. + {0x471d, 0x05, 0, 0}, {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0},
  82376. + {0x501f, 0x00, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0},
  82377. + {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0},
  82378. +};
  82379. +
  82380. +static struct reg_value ov5642_setting_15fps_1080P_1920_1080[] = {
  82381. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82382. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82383. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
  82384. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
  82385. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
  82386. + {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
  82387. + {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
  82388. + {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
  82389. + {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
  82390. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82391. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
  82392. + {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
  82393. + {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
  82394. + {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
  82395. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  82396. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  82397. + {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
  82398. + {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
  82399. + {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
  82400. + {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
  82401. + {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
  82402. + {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
  82403. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82404. + {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
  82405. + {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
  82406. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
  82407. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
  82408. + {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
  82409. + {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  82410. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  82411. + {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
  82412. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
  82413. + {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  82414. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  82415. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  82416. + {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
  82417. + {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  82418. + {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
  82419. + {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
  82420. + {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  82421. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82422. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  82423. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  82424. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  82425. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  82426. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  82427. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  82428. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  82429. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  82430. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  82431. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  82432. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  82433. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  82434. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  82435. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  82436. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  82437. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  82438. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  82439. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  82440. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  82441. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  82442. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  82443. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  82444. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  82445. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  82446. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  82447. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  82448. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  82449. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  82450. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  82451. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  82452. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  82453. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  82454. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  82455. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  82456. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  82457. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  82458. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  82459. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  82460. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  82461. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  82462. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  82463. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  82464. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  82465. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  82466. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  82467. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  82468. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  82469. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  82470. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  82471. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  82472. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  82473. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  82474. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82475. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  82476. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  82477. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  82478. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  82479. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  82480. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  82481. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  82482. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  82483. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  82484. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  82485. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  82486. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  82487. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  82488. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  82489. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  82490. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  82491. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  82492. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  82493. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  82494. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  82495. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  82496. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  82497. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  82498. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  82499. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  82500. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  82501. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  82502. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  82503. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  82504. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  82505. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  82506. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  82507. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  82508. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  82509. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  82510. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  82511. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  82512. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  82513. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  82514. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  82515. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  82516. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  82517. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  82518. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  82519. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  82520. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  82521. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  82522. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  82523. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  82524. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  82525. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  82526. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  82527. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  82528. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  82529. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  82530. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  82531. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  82532. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  82533. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  82534. + {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x07, 0, 0},
  82535. + {0x350c, 0x04, 0, 0}, {0x350d, 0x58, 0, 0}, {0x3801, 0x8a, 0, 0},
  82536. + {0x3803, 0x0a, 0, 0}, {0x3804, 0x07, 0, 0}, {0x3805, 0x80, 0, 0},
  82537. + {0x3806, 0x04, 0, 0}, {0x3807, 0x39, 0, 0}, {0x3808, 0x07, 0, 0},
  82538. + {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
  82539. + {0x380c, 0x09, 0, 0}, {0x380d, 0xd6, 0, 0}, {0x380e, 0x04, 0, 0},
  82540. + {0x380f, 0x58, 0, 0}, {0x381c, 0x11, 0, 0}, {0x381d, 0xba, 0, 0},
  82541. + {0x381e, 0x04, 0, 0}, {0x381f, 0x48, 0, 0}, {0x3820, 0x04, 0, 0},
  82542. + {0x3821, 0x18, 0, 0}, {0x3a08, 0x14, 0, 0}, {0x3a09, 0xe0, 0, 0},
  82543. + {0x3a0a, 0x11, 0, 0}, {0x3a0b, 0x60, 0, 0}, {0x3a0d, 0x04, 0, 0},
  82544. + {0x3a0e, 0x03, 0, 0}, {0x5682, 0x07, 0, 0}, {0x5683, 0x60, 0, 0},
  82545. + {0x5686, 0x04, 0, 0}, {0x5687, 0x1c, 0, 0}, {0x5001, 0x7f, 0, 0},
  82546. + {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0}, {0x460c, 0x20, 0, 0},
  82547. + {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0}, {0x471d, 0x05, 0, 0},
  82548. + {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0}, {0x501f, 0x00, 0, 0},
  82549. + {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3819, 0x80, 0, 0},
  82550. + {0x5002, 0xe0, 0, 0},
  82551. +};
  82552. +
  82553. +static struct reg_value ov5642_setting_15fps_QVGA_320_240[] = {
  82554. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82555. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82556. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  82557. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  82558. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  82559. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  82560. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  82561. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  82562. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  82563. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  82564. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  82565. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  82566. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82567. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  82568. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  82569. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  82570. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  82571. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  82572. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  82573. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  82574. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82575. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  82576. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  82577. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  82578. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  82579. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  82580. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  82581. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  82582. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  82583. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  82584. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  82585. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  82586. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  82587. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  82588. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  82589. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  82590. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82591. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  82592. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  82593. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  82594. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  82595. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  82596. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  82597. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  82598. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82599. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  82600. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  82601. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  82602. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  82603. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  82604. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  82605. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  82606. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  82607. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  82608. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  82609. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  82610. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  82611. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  82612. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  82613. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  82614. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  82615. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  82616. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  82617. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  82618. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  82619. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  82620. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  82621. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  82622. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  82623. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  82624. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  82625. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  82626. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  82627. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  82628. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  82629. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  82630. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  82631. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  82632. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  82633. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  82634. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  82635. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  82636. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  82637. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  82638. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  82639. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  82640. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  82641. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  82642. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  82643. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  82644. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  82645. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  82646. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  82647. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  82648. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  82649. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  82650. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  82651. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  82652. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  82653. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  82654. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  82655. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  82656. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  82657. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  82658. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  82659. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  82660. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  82661. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  82662. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  82663. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  82664. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  82665. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  82666. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  82667. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  82668. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  82669. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  82670. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  82671. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  82672. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  82673. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  82674. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  82675. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  82676. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  82677. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  82678. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  82679. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  82680. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  82681. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  82682. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  82683. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  82684. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  82685. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  82686. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  82687. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  82688. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  82689. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  82690. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  82691. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  82692. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  82693. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  82694. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  82695. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  82696. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  82697. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  82698. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  82699. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  82700. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  82701. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  82702. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  82703. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  82704. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  82705. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  82706. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  82707. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  82708. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  82709. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  82710. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  82711. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  82712. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  82713. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  82714. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  82715. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  82716. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  82717. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  82718. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  82719. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  82720. + {0x380b, 0xf0, 0, 0}, {0x3a00, 0x78, 0, 0},
  82721. +};
  82722. +
  82723. +static struct reg_value ov5642_setting_15fps_NTSC_720_480[] = {
  82724. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82725. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82726. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  82727. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  82728. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  82729. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  82730. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  82731. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  82732. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  82733. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  82734. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  82735. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  82736. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82737. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  82738. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  82739. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  82740. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  82741. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  82742. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  82743. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  82744. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82745. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  82746. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  82747. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  82748. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  82749. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  82750. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  82751. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  82752. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  82753. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  82754. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  82755. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  82756. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  82757. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  82758. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  82759. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  82760. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82761. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  82762. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  82763. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  82764. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  82765. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  82766. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  82767. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  82768. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82769. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  82770. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  82771. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  82772. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  82773. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  82774. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  82775. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  82776. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  82777. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  82778. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  82779. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  82780. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  82781. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  82782. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  82783. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  82784. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  82785. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  82786. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  82787. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  82788. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  82789. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  82790. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  82791. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  82792. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  82793. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  82794. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  82795. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  82796. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  82797. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  82798. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  82799. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  82800. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  82801. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  82802. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  82803. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  82804. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  82805. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  82806. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  82807. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  82808. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  82809. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  82810. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  82811. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  82812. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  82813. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  82814. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  82815. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  82816. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  82817. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  82818. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  82819. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  82820. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  82821. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  82822. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  82823. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  82824. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  82825. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  82826. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  82827. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  82828. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  82829. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  82830. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  82831. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  82832. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  82833. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  82834. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  82835. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  82836. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  82837. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  82838. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  82839. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  82840. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  82841. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  82842. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  82843. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  82844. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  82845. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  82846. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  82847. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  82848. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  82849. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  82850. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  82851. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  82852. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  82853. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  82854. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  82855. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  82856. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  82857. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  82858. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  82859. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  82860. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  82861. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  82862. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  82863. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  82864. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  82865. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  82866. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  82867. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  82868. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  82869. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  82870. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  82871. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  82872. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  82873. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  82874. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  82875. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  82876. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  82877. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  82878. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  82879. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  82880. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  82881. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  82882. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  82883. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  82884. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  82885. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  82886. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  82887. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  82888. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  82889. + {0x3824, 0x11, 0, 0}, {0x3825, 0xb4, 0, 0}, {0x3826, 0x00, 0, 0},
  82890. + {0x3827, 0x3d, 0, 0}, {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0},
  82891. + {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0}, {0x3808, 0x02, 0, 0},
  82892. + {0x3809, 0xd0, 0, 0}, {0x380A, 0x01, 0, 0}, {0x380B, 0xe0, 0, 0},
  82893. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x3806, 0x03, 0, 0},
  82894. + {0x3807, 0x55, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0x55, 0, 0},
  82895. + {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  82896. +};
  82897. +
  82898. +static struct reg_value ov5642_setting_15fps_PAL_720_576[] = {
  82899. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82900. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82901. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  82902. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  82903. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  82904. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  82905. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  82906. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  82907. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  82908. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  82909. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  82910. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  82911. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82912. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  82913. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  82914. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  82915. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  82916. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  82917. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  82918. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  82919. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82920. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  82921. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  82922. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  82923. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  82924. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  82925. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  82926. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  82927. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  82928. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  82929. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  82930. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  82931. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  82932. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  82933. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  82934. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  82935. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82936. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  82937. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  82938. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  82939. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  82940. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  82941. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  82942. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  82943. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82944. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  82945. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  82946. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  82947. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  82948. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  82949. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  82950. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  82951. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  82952. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  82953. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  82954. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  82955. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  82956. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  82957. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  82958. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  82959. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  82960. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  82961. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  82962. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  82963. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  82964. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  82965. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  82966. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  82967. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  82968. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  82969. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  82970. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  82971. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  82972. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  82973. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  82974. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  82975. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  82976. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  82977. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  82978. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  82979. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  82980. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  82981. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  82982. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  82983. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  82984. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  82985. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  82986. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  82987. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  82988. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  82989. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  82990. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  82991. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  82992. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  82993. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  82994. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  82995. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  82996. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  82997. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  82998. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  82999. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  83000. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  83001. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  83002. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  83003. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  83004. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  83005. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  83006. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  83007. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  83008. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  83009. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  83010. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  83011. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  83012. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  83013. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  83014. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  83015. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  83016. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  83017. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  83018. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  83019. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  83020. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  83021. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  83022. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  83023. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  83024. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  83025. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  83026. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  83027. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  83028. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  83029. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  83030. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  83031. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  83032. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  83033. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  83034. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  83035. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  83036. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  83037. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  83038. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  83039. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  83040. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  83041. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  83042. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  83043. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  83044. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  83045. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  83046. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  83047. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  83048. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  83049. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  83050. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  83051. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  83052. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  83053. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  83054. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  83055. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  83056. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  83057. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  83058. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  83059. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  83060. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  83061. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  83062. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  83063. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  83064. + {0x3824, 0x11, 0, 0}, {0x3825, 0xdc, 0, 0}, {0x3826, 0x00, 0, 0},
  83065. + {0x3827, 0x08, 0, 0}, {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0},
  83066. + {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0}, {0x3808, 0x02, 0, 0},
  83067. + {0x3809, 0xd0, 0, 0}, {0x380A, 0x02, 0, 0}, {0x380B, 0x40, 0, 0},
  83068. + {0x3804, 0x04, 0, 0}, {0x3805, 0xb0, 0, 0}, {0x3806, 0x03, 0, 0},
  83069. + {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0xc0, 0, 0},
  83070. + {0x5682, 0x04, 0, 0}, {0x5683, 0xb0, 0, 0},
  83071. +};
  83072. +
  83073. +static struct ov5642_mode_info ov5642_mode_info_data[2][ov5642_mode_MAX + 1] = {
  83074. + {
  83075. + {ov5642_mode_VGA_640_480, 640, 480,
  83076. + ov5642_setting_15fps_VGA_640_480,
  83077. + ARRAY_SIZE(ov5642_setting_15fps_VGA_640_480)},
  83078. + {ov5642_mode_QVGA_320_240, 320, 240,
  83079. + ov5642_setting_15fps_QVGA_320_240,
  83080. + ARRAY_SIZE(ov5642_setting_15fps_QVGA_320_240)},
  83081. + {ov5642_mode_NTSC_720_480, 720, 480,
  83082. + ov5642_setting_15fps_NTSC_720_480,
  83083. + ARRAY_SIZE(ov5642_setting_15fps_NTSC_720_480)},
  83084. + {ov5642_mode_PAL_720_576, 720, 576,
  83085. + ov5642_setting_15fps_PAL_720_576,
  83086. + ARRAY_SIZE(ov5642_setting_15fps_PAL_720_576)},
  83087. + {ov5642_mode_720P_1280_720, 1280, 720,
  83088. + ov5642_setting_15fps_720P_1280_720,
  83089. + ARRAY_SIZE(ov5642_setting_15fps_720P_1280_720)},
  83090. + {ov5642_mode_1080P_1920_1080, 1920, 1080,
  83091. + ov5642_setting_15fps_1080P_1920_1080,
  83092. + ARRAY_SIZE(ov5642_setting_15fps_1080P_1920_1080)},
  83093. + {ov5642_mode_QSXGA_2592_1944, 2592, 1944,
  83094. + ov5642_setting_15fps_QSXGA_2592_1944,
  83095. + ARRAY_SIZE(ov5642_setting_15fps_QSXGA_2592_1944)},
  83096. + {ov5642_mode_QCIF_176_144, 176, 144,
  83097. + ov5642_setting_15fps_QCIF_176_144,
  83098. + ARRAY_SIZE(ov5642_setting_15fps_QCIF_176_144)},
  83099. + {ov5642_mode_XGA_1024_768, 1024, 768,
  83100. + ov5642_setting_15fps_XGA_1024_768,
  83101. + ARRAY_SIZE(ov5642_setting_15fps_XGA_1024_768)},
  83102. + },
  83103. + {
  83104. + {ov5642_mode_VGA_640_480, 640, 480,
  83105. + ov5642_setting_30fps_VGA_640_480,
  83106. + ARRAY_SIZE(ov5642_setting_30fps_VGA_640_480)},
  83107. + {ov5642_mode_QVGA_320_240, 320, 240,
  83108. + ov5642_setting_30fps_QVGA_320_240,
  83109. + ARRAY_SIZE(ov5642_setting_30fps_QVGA_320_240)},
  83110. + {ov5642_mode_NTSC_720_480, 720, 480,
  83111. + ov5642_setting_30fps_NTSC_720_480,
  83112. + ARRAY_SIZE(ov5642_setting_30fps_NTSC_720_480)},
  83113. + {ov5642_mode_PAL_720_576, 720, 576,
  83114. + ov5642_setting_30fps_PAL_720_576,
  83115. + ARRAY_SIZE(ov5642_setting_30fps_PAL_720_576)},
  83116. + {ov5642_mode_720P_1280_720, 1280, 720,
  83117. + ov5642_setting_30fps_720P_1280_720,
  83118. + ARRAY_SIZE(ov5642_setting_30fps_720P_1280_720)},
  83119. + {ov5642_mode_1080P_1920_1080, 0, 0, NULL, 0},
  83120. + {ov5642_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
  83121. + {ov5642_mode_QCIF_176_144, 176, 144,
  83122. + ov5642_setting_30fps_QCIF_176_144,
  83123. + ARRAY_SIZE(ov5642_setting_30fps_QCIF_176_144)},
  83124. + {ov5642_mode_XGA_1024_768, 1024, 768,
  83125. + ov5642_setting_30fps_XGA_1024_768,
  83126. + ARRAY_SIZE(ov5642_setting_30fps_XGA_1024_768)},
  83127. + },
  83128. +};
  83129. +
  83130. +static struct regulator *io_regulator;
  83131. +static struct regulator *core_regulator;
  83132. +static struct regulator *analog_regulator;
  83133. +static struct regulator *gpo_regulator;
  83134. +
  83135. +static int ov5642_probe(struct i2c_client *adapter,
  83136. + const struct i2c_device_id *device_id);
  83137. +static int ov5642_remove(struct i2c_client *client);
  83138. +
  83139. +static s32 ov5642_read_reg(u16 reg, u8 *val);
  83140. +static s32 ov5642_write_reg(u16 reg, u8 val);
  83141. +
  83142. +static const struct i2c_device_id ov5642_id[] = {
  83143. + {"ov5642", 0},
  83144. + {"ov564x", 0},
  83145. + {},
  83146. +};
  83147. +
  83148. +MODULE_DEVICE_TABLE(i2c, ov5642_id);
  83149. +
  83150. +static struct i2c_driver ov5642_i2c_driver = {
  83151. + .driver = {
  83152. + .owner = THIS_MODULE,
  83153. + .name = "ov5642",
  83154. + },
  83155. + .probe = ov5642_probe,
  83156. + .remove = ov5642_remove,
  83157. + .id_table = ov5642_id,
  83158. +};
  83159. +
  83160. +static void ov5642_standby(s32 enable)
  83161. +{
  83162. + if (enable)
  83163. + gpio_set_value(pwn_gpio, 1);
  83164. + else
  83165. + gpio_set_value(pwn_gpio, 0);
  83166. +
  83167. + msleep(2);
  83168. +}
  83169. +
  83170. +static void ov5642_reset(void)
  83171. +{
  83172. + /* camera reset */
  83173. + gpio_set_value(rst_gpio, 1);
  83174. +
  83175. + /* camera power down */
  83176. + gpio_set_value(pwn_gpio, 1);
  83177. + msleep(5);
  83178. +
  83179. + gpio_set_value(pwn_gpio, 0);
  83180. + msleep(5);
  83181. +
  83182. + gpio_set_value(rst_gpio, 0);
  83183. + msleep(1);
  83184. +
  83185. + gpio_set_value(rst_gpio, 1);
  83186. + msleep(5);
  83187. +
  83188. + gpio_set_value(pwn_gpio, 1);
  83189. +}
  83190. +
  83191. +static int ov5642_power_on(struct device *dev)
  83192. +{
  83193. + int ret = 0;
  83194. +
  83195. + io_regulator = devm_regulator_get(dev, "DOVDD");
  83196. + if (!IS_ERR(io_regulator)) {
  83197. + regulator_set_voltage(io_regulator,
  83198. + OV5642_VOLTAGE_DIGITAL_IO,
  83199. + OV5642_VOLTAGE_DIGITAL_IO);
  83200. + ret = regulator_enable(io_regulator);
  83201. + if (ret) {
  83202. + pr_err("%s:io set voltage error\n", __func__);
  83203. + return ret;
  83204. + } else {
  83205. + dev_dbg(dev,
  83206. + "%s:io set voltage ok\n", __func__);
  83207. + }
  83208. + } else {
  83209. + pr_err("%s: cannot get io voltage error\n", __func__);
  83210. + io_regulator = NULL;
  83211. + }
  83212. +
  83213. + core_regulator = devm_regulator_get(dev, "DVDD");
  83214. + if (!IS_ERR(core_regulator)) {
  83215. + regulator_set_voltage(core_regulator,
  83216. + OV5642_VOLTAGE_DIGITAL_CORE,
  83217. + OV5642_VOLTAGE_DIGITAL_CORE);
  83218. + ret = regulator_enable(core_regulator);
  83219. + if (ret) {
  83220. + pr_err("%s:core set voltage error\n", __func__);
  83221. + return ret;
  83222. + } else {
  83223. + dev_dbg(dev,
  83224. + "%s:core set voltage ok\n", __func__);
  83225. + }
  83226. + } else {
  83227. + core_regulator = NULL;
  83228. + pr_err("%s: cannot get core voltage error\n", __func__);
  83229. + }
  83230. +
  83231. + analog_regulator = devm_regulator_get(dev, "AVDD");
  83232. + if (!IS_ERR(analog_regulator)) {
  83233. + regulator_set_voltage(analog_regulator,
  83234. + OV5642_VOLTAGE_ANALOG,
  83235. + OV5642_VOLTAGE_ANALOG);
  83236. + ret = regulator_enable(analog_regulator);
  83237. + if (ret) {
  83238. + pr_err("%s:analog set voltage error\n",
  83239. + __func__);
  83240. + return ret;
  83241. + } else {
  83242. + dev_dbg(dev,
  83243. + "%s:analog set voltage ok\n", __func__);
  83244. + }
  83245. + } else {
  83246. + analog_regulator = NULL;
  83247. + pr_err("%s: cannot get analog voltage error\n", __func__);
  83248. + }
  83249. +
  83250. + return ret;
  83251. +}
  83252. +
  83253. +static s32 ov5642_write_reg(u16 reg, u8 val)
  83254. +{
  83255. + u8 au8Buf[3] = {0};
  83256. +
  83257. + au8Buf[0] = reg >> 8;
  83258. + au8Buf[1] = reg & 0xff;
  83259. + au8Buf[2] = val;
  83260. +
  83261. + if (i2c_master_send(ov5642_data.i2c_client, au8Buf, 3) < 0) {
  83262. + pr_err("%s:write reg error:reg=%x,val=%x\n",
  83263. + __func__, reg, val);
  83264. + return -1;
  83265. + }
  83266. +
  83267. + return 0;
  83268. +}
  83269. +
  83270. +static s32 ov5642_read_reg(u16 reg, u8 *val)
  83271. +{
  83272. + u8 au8RegBuf[2] = {0};
  83273. + u8 u8RdVal = 0;
  83274. +
  83275. + au8RegBuf[0] = reg >> 8;
  83276. + au8RegBuf[1] = reg & 0xff;
  83277. +
  83278. + if (2 != i2c_master_send(ov5642_data.i2c_client, au8RegBuf, 2)) {
  83279. + pr_err("%s:write reg error:reg=%x\n",
  83280. + __func__, reg);
  83281. + return -1;
  83282. + }
  83283. +
  83284. + if (1 != i2c_master_recv(ov5642_data.i2c_client, &u8RdVal, 1)) {
  83285. + pr_err("%s:read reg error:reg=%x,val=%x\n",
  83286. + __func__, reg, u8RdVal);
  83287. + return -1;
  83288. + }
  83289. +
  83290. + *val = u8RdVal;
  83291. +
  83292. + return u8RdVal;
  83293. +}
  83294. +
  83295. +static int ov5642_set_rot_mode(struct reg_value *rot_mode)
  83296. +{
  83297. + s32 i = 0;
  83298. + s32 iModeSettingArySize = 2;
  83299. + register u32 Delay_ms = 0;
  83300. + register u16 RegAddr = 0;
  83301. + register u8 Mask = 0;
  83302. + register u8 Val = 0;
  83303. + u8 RegVal = 0;
  83304. + int retval = 0;
  83305. + for (i = 0; i < iModeSettingArySize; ++i, ++rot_mode) {
  83306. + Delay_ms = rot_mode->u32Delay_ms;
  83307. + RegAddr = rot_mode->u16RegAddr;
  83308. + Val = rot_mode->u8Val;
  83309. + Mask = rot_mode->u8Mask;
  83310. +
  83311. + if (Mask) {
  83312. + retval = ov5642_read_reg(RegAddr, &RegVal);
  83313. + if (retval < 0) {
  83314. + pr_err("%s, read reg 0x%x failed\n",
  83315. + __func__, RegAddr);
  83316. + goto err;
  83317. + }
  83318. +
  83319. + Val |= RegVal;
  83320. + Val &= Mask;
  83321. + }
  83322. +
  83323. + retval = ov5642_write_reg(RegAddr, Val);
  83324. + if (retval < 0) {
  83325. + pr_err("%s, write reg 0x%x failed\n",
  83326. + __func__, RegAddr);
  83327. + goto err;
  83328. + }
  83329. +
  83330. + if (Delay_ms)
  83331. + mdelay(Delay_ms);
  83332. + }
  83333. +err:
  83334. + return retval;
  83335. +}
  83336. +static int ov5642_init_mode(enum ov5642_frame_rate frame_rate,
  83337. + enum ov5642_mode mode);
  83338. +static int ov5642_write_snapshot_para(enum ov5642_frame_rate frame_rate,
  83339. + enum ov5642_mode mode);
  83340. +static int ov5642_change_mode(enum ov5642_frame_rate new_frame_rate,
  83341. + enum ov5642_frame_rate old_frame_rate,
  83342. + enum ov5642_mode new_mode,
  83343. + enum ov5642_mode orig_mode)
  83344. +{
  83345. + struct reg_value *pModeSetting = NULL;
  83346. + s32 i = 0;
  83347. + s32 iModeSettingArySize = 0;
  83348. + register u32 Delay_ms = 0;
  83349. + register u16 RegAddr = 0;
  83350. + register u8 Mask = 0;
  83351. + register u8 Val = 0;
  83352. + u8 RegVal = 0;
  83353. + int retval = 0;
  83354. +
  83355. + if (new_mode > ov5642_mode_MAX || new_mode < ov5642_mode_MIN) {
  83356. + pr_err("Wrong ov5642 mode detected!\n");
  83357. + return -1;
  83358. + }
  83359. +
  83360. + if ((new_frame_rate == old_frame_rate) &&
  83361. + (new_mode == ov5642_mode_VGA_640_480) &&
  83362. + (orig_mode == ov5642_mode_QSXGA_2592_1944)) {
  83363. + pModeSetting = ov5642_setting_QSXGA_2_VGA;
  83364. + iModeSettingArySize = ARRAY_SIZE(ov5642_setting_QSXGA_2_VGA);
  83365. + ov5642_data.pix.width = 640;
  83366. + ov5642_data.pix.height = 480;
  83367. + } else if ((new_frame_rate == old_frame_rate) &&
  83368. + (new_mode == ov5642_mode_QVGA_320_240) &&
  83369. + (orig_mode == ov5642_mode_VGA_640_480)) {
  83370. + pModeSetting = ov5642_setting_VGA_2_QVGA;
  83371. + iModeSettingArySize = ARRAY_SIZE(ov5642_setting_VGA_2_QVGA);
  83372. + ov5642_data.pix.width = 320;
  83373. + ov5642_data.pix.height = 240;
  83374. + } else {
  83375. + retval = ov5642_write_snapshot_para(new_frame_rate, new_mode);
  83376. + goto err;
  83377. + }
  83378. +
  83379. + if (ov5642_data.pix.width == 0 || ov5642_data.pix.height == 0 ||
  83380. + pModeSetting == NULL || iModeSettingArySize == 0)
  83381. + return -EINVAL;
  83382. +
  83383. + for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
  83384. + Delay_ms = pModeSetting->u32Delay_ms;
  83385. + RegAddr = pModeSetting->u16RegAddr;
  83386. + Val = pModeSetting->u8Val;
  83387. + Mask = pModeSetting->u8Mask;
  83388. +
  83389. + if (Mask) {
  83390. + retval = ov5642_read_reg(RegAddr, &RegVal);
  83391. + if (retval < 0) {
  83392. + pr_err("read reg error addr=0x%x", RegAddr);
  83393. + goto err;
  83394. + }
  83395. +
  83396. + RegVal &= ~(u8)Mask;
  83397. + Val &= Mask;
  83398. + Val |= RegVal;
  83399. + }
  83400. +
  83401. + retval = ov5642_write_reg(RegAddr, Val);
  83402. + if (retval < 0) {
  83403. + pr_err("write reg error addr=0x%x", RegAddr);
  83404. + goto err;
  83405. + }
  83406. +
  83407. + if (Delay_ms)
  83408. + msleep(Delay_ms);
  83409. + }
  83410. +err:
  83411. + return retval;
  83412. +}
  83413. +static int ov5642_init_mode(enum ov5642_frame_rate frame_rate,
  83414. + enum ov5642_mode mode)
  83415. +{
  83416. + struct reg_value *pModeSetting = NULL;
  83417. + s32 i = 0;
  83418. + s32 iModeSettingArySize = 0;
  83419. + register u32 Delay_ms = 0;
  83420. + register u16 RegAddr = 0;
  83421. + register u8 Mask = 0;
  83422. + register u8 Val = 0;
  83423. + u8 RegVal = 0;
  83424. + int retval = 0;
  83425. +
  83426. + if (mode > ov5642_mode_MAX || mode < ov5642_mode_MIN) {
  83427. + pr_err("Wrong ov5642 mode detected!\n");
  83428. + return -1;
  83429. + }
  83430. +
  83431. + pModeSetting = ov5642_mode_info_data[frame_rate][mode].init_data_ptr;
  83432. + iModeSettingArySize =
  83433. + ov5642_mode_info_data[frame_rate][mode].init_data_size;
  83434. +
  83435. + ov5642_data.pix.width = ov5642_mode_info_data[frame_rate][mode].width;
  83436. + ov5642_data.pix.height = ov5642_mode_info_data[frame_rate][mode].height;
  83437. +
  83438. + if (ov5642_data.pix.width == 0 || ov5642_data.pix.height == 0 ||
  83439. + pModeSetting == NULL || iModeSettingArySize == 0)
  83440. + return -EINVAL;
  83441. +
  83442. + for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
  83443. + Delay_ms = pModeSetting->u32Delay_ms;
  83444. + RegAddr = pModeSetting->u16RegAddr;
  83445. + Val = pModeSetting->u8Val;
  83446. + Mask = pModeSetting->u8Mask;
  83447. +
  83448. + if (Mask) {
  83449. + retval = ov5642_read_reg(RegAddr, &RegVal);
  83450. + if (retval < 0) {
  83451. + pr_err("read reg error addr=0x%x", RegAddr);
  83452. + goto err;
  83453. + }
  83454. +
  83455. + RegVal &= ~(u8)Mask;
  83456. + Val &= Mask;
  83457. + Val |= RegVal;
  83458. + }
  83459. +
  83460. + retval = ov5642_write_reg(RegAddr, Val);
  83461. + if (retval < 0) {
  83462. + pr_err("write reg error addr=0x%x", RegAddr);
  83463. + goto err;
  83464. + }
  83465. +
  83466. + if (Delay_ms)
  83467. + msleep(Delay_ms);
  83468. + }
  83469. +err:
  83470. + return retval;
  83471. +}
  83472. +
  83473. +static int ov5642_write_snapshot_para(enum ov5642_frame_rate frame_rate,
  83474. + enum ov5642_mode mode)
  83475. +{
  83476. + int ret = 0;
  83477. + bool m_60Hz = false;
  83478. + u16 cap_frame_rate = 50;
  83479. + u16 g_prev_frame_rate = 225;
  83480. +
  83481. + u8 ev_low, ev_mid, ev_high;
  83482. + u8 ret_l, ret_m, ret_h, gain, lines_10ms;
  83483. + u16 ulcap_ev, icap_gain, prev_maxlines;
  83484. + u32 ulcap_ev_gain, cap_maxlines, g_prev_ev;
  83485. +
  83486. + ov5642_write_reg(0x3503, 0x07);
  83487. +
  83488. + ret_h = ret_m = ret_l = 0;
  83489. + g_prev_ev = 0;
  83490. + ov5642_read_reg(0x3500, &ret_h);
  83491. + ov5642_read_reg(0x3501, &ret_m);
  83492. + ov5642_read_reg(0x3502, &ret_l);
  83493. + g_prev_ev = (ret_h << 12) + (ret_m << 4) + (ret_l >> 4);
  83494. +
  83495. + ret_h = ret_m = ret_l = 0;
  83496. + prev_maxlines = 0;
  83497. + ov5642_read_reg(0x380e, &ret_h);
  83498. + ov5642_read_reg(0x380f, &ret_l);
  83499. + prev_maxlines = (ret_h << 8) + ret_l;
  83500. + /*Read back AGC Gain for preview*/
  83501. + gain = 0;
  83502. + ov5642_read_reg(0x350b, &gain);
  83503. +
  83504. + ret = ov5642_init_mode(frame_rate, mode);
  83505. + if (ret < 0)
  83506. + return ret;
  83507. +
  83508. + ret_h = ret_m = ret_l = 0;
  83509. + ov5642_read_reg(0x380e, &ret_h);
  83510. + ov5642_read_reg(0x380f, &ret_l);
  83511. + cap_maxlines = (ret_h << 8) + ret_l;
  83512. + if (m_60Hz == true)
  83513. + lines_10ms = cap_frame_rate * cap_maxlines/12000;
  83514. + else
  83515. + lines_10ms = cap_frame_rate * cap_maxlines/10000;
  83516. +
  83517. + if (prev_maxlines == 0)
  83518. + prev_maxlines = 1;
  83519. +
  83520. + ulcap_ev = (g_prev_ev*(cap_frame_rate)*(cap_maxlines))/
  83521. + (((prev_maxlines)*(g_prev_frame_rate)));
  83522. + icap_gain = (gain & 0x0f) + 16;
  83523. + if (gain & 0x10)
  83524. + icap_gain = icap_gain << 1;
  83525. +
  83526. + if (gain & 0x20)
  83527. + icap_gain = icap_gain << 1;
  83528. +
  83529. + if (gain & 0x40)
  83530. + icap_gain = icap_gain << 1;
  83531. +
  83532. + if (gain & 0x80)
  83533. + icap_gain = icap_gain << 1;
  83534. +
  83535. + ulcap_ev_gain = 2 * ulcap_ev * icap_gain;
  83536. +
  83537. + if (ulcap_ev_gain < cap_maxlines*16) {
  83538. + ulcap_ev = ulcap_ev_gain/16;
  83539. + if (ulcap_ev > lines_10ms) {
  83540. + ulcap_ev /= lines_10ms;
  83541. + ulcap_ev *= lines_10ms;
  83542. + }
  83543. + } else
  83544. + ulcap_ev = cap_maxlines;
  83545. +
  83546. + if (ulcap_ev == 0)
  83547. + ulcap_ev = 1;
  83548. +
  83549. + icap_gain = (ulcap_ev_gain*2/ulcap_ev + 1)/2;
  83550. + ev_low = ((unsigned char)ulcap_ev)<<4;
  83551. + ev_mid = (unsigned char)(ulcap_ev >> 4) & 0xff;
  83552. + ev_high = (unsigned char)(ulcap_ev >> 12);
  83553. +
  83554. + gain = 0;
  83555. + if (icap_gain > 31) {
  83556. + gain |= 0x10;
  83557. + icap_gain = icap_gain >> 1;
  83558. + }
  83559. + if (icap_gain > 31) {
  83560. + gain |= 0x20;
  83561. + icap_gain = icap_gain >> 1;
  83562. + }
  83563. + if (icap_gain > 31) {
  83564. + gain |= 0x40;
  83565. + icap_gain = icap_gain >> 1;
  83566. + }
  83567. + if (icap_gain > 31) {
  83568. + gain |= 0x80;
  83569. + icap_gain = icap_gain >> 1;
  83570. + }
  83571. + if (icap_gain > 16)
  83572. + gain |= ((icap_gain - 16) & 0x0f);
  83573. +
  83574. + if (gain == 0x10)
  83575. + gain = 0x11;
  83576. +
  83577. + ov5642_write_reg(0x350b, gain);
  83578. + ov5642_write_reg(0x3502, ev_low);
  83579. + ov5642_write_reg(0x3501, ev_mid);
  83580. + ov5642_write_reg(0x3500, ev_high);
  83581. + msleep(500);
  83582. +
  83583. + return ret ;
  83584. +}
  83585. +
  83586. +
  83587. +/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
  83588. +
  83589. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  83590. +{
  83591. + if (s == NULL) {
  83592. + pr_err(" ERROR!! no slave device set!\n");
  83593. + return -1;
  83594. + }
  83595. +
  83596. + memset(p, 0, sizeof(*p));
  83597. + p->u.bt656.clock_curr = ov5642_data.mclk;
  83598. + pr_debug(" clock_curr=mclk=%d\n", ov5642_data.mclk);
  83599. + p->if_type = V4L2_IF_TYPE_BT656;
  83600. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  83601. + p->u.bt656.clock_min = OV5642_XCLK_MIN;
  83602. + p->u.bt656.clock_max = OV5642_XCLK_MAX;
  83603. + p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
  83604. +
  83605. + return 0;
  83606. +}
  83607. +
  83608. +/*!
  83609. + * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
  83610. + * @s: pointer to standard V4L2 device structure
  83611. + * @on: indicates power mode (on or off)
  83612. + *
  83613. + * Turns the power on or off, depending on the value of on and returns the
  83614. + * appropriate error code.
  83615. + */
  83616. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  83617. +{
  83618. + struct sensor_data *sensor = s->priv;
  83619. +
  83620. + if (on && !sensor->on) {
  83621. + if (io_regulator)
  83622. + if (regulator_enable(io_regulator) != 0)
  83623. + return -EIO;
  83624. + if (core_regulator)
  83625. + if (regulator_enable(core_regulator) != 0)
  83626. + return -EIO;
  83627. + if (gpo_regulator)
  83628. + if (regulator_enable(gpo_regulator) != 0)
  83629. + return -EIO;
  83630. + if (analog_regulator)
  83631. + if (regulator_enable(analog_regulator) != 0)
  83632. + return -EIO;
  83633. + /* Make sure power on */
  83634. + ov5642_standby(0);
  83635. + } else if (!on && sensor->on) {
  83636. + if (analog_regulator)
  83637. + regulator_disable(analog_regulator);
  83638. + if (core_regulator)
  83639. + regulator_disable(core_regulator);
  83640. + if (io_regulator)
  83641. + regulator_disable(io_regulator);
  83642. + if (gpo_regulator)
  83643. + regulator_disable(gpo_regulator);
  83644. +
  83645. + ov5642_standby(1);
  83646. + }
  83647. +
  83648. + sensor->on = on;
  83649. +
  83650. + return 0;
  83651. +}
  83652. +
  83653. +/*!
  83654. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  83655. + * @s: pointer to standard V4L2 device structure
  83656. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  83657. + *
  83658. + * Returns the sensor's video CAPTURE parameters.
  83659. + */
  83660. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  83661. +{
  83662. + struct sensor_data *sensor = s->priv;
  83663. + struct v4l2_captureparm *cparm = &a->parm.capture;
  83664. + int ret = 0;
  83665. +
  83666. + switch (a->type) {
  83667. + /* This is the only case currently handled. */
  83668. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  83669. + memset(a, 0, sizeof(*a));
  83670. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  83671. + cparm->capability = sensor->streamcap.capability;
  83672. + cparm->timeperframe = sensor->streamcap.timeperframe;
  83673. + cparm->capturemode = sensor->streamcap.capturemode;
  83674. + ret = 0;
  83675. + break;
  83676. +
  83677. + /* These are all the possible cases. */
  83678. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  83679. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  83680. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  83681. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  83682. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  83683. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  83684. + ret = -EINVAL;
  83685. + break;
  83686. +
  83687. + default:
  83688. + pr_debug(" type is unknown - %d\n", a->type);
  83689. + ret = -EINVAL;
  83690. + break;
  83691. + }
  83692. +
  83693. + return ret;
  83694. +}
  83695. +
  83696. +/*!
  83697. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  83698. + * @s: pointer to standard V4L2 device structure
  83699. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  83700. + *
  83701. + * Configures the sensor to use the input parameters, if possible. If
  83702. + * not possible, reverts to the old parameters and returns the
  83703. + * appropriate error code.
  83704. + */
  83705. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  83706. +{
  83707. + struct sensor_data *sensor = s->priv;
  83708. + struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
  83709. + u32 tgt_fps, old_fps; /* target frames per secound */
  83710. + enum ov5642_frame_rate new_frame_rate, old_frame_rate;
  83711. + int ret = 0;
  83712. +
  83713. + /* Make sure power on */
  83714. + ov5642_standby(0);
  83715. +
  83716. + switch (a->type) {
  83717. + /* This is the only case currently handled. */
  83718. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  83719. + /* Check that the new frame rate is allowed. */
  83720. + if ((timeperframe->numerator == 0) ||
  83721. + (timeperframe->denominator == 0)) {
  83722. + timeperframe->denominator = DEFAULT_FPS;
  83723. + timeperframe->numerator = 1;
  83724. + }
  83725. +
  83726. + tgt_fps = timeperframe->denominator /
  83727. + timeperframe->numerator;
  83728. +
  83729. + if (tgt_fps > MAX_FPS) {
  83730. + timeperframe->denominator = MAX_FPS;
  83731. + timeperframe->numerator = 1;
  83732. + } else if (tgt_fps < MIN_FPS) {
  83733. + timeperframe->denominator = MIN_FPS;
  83734. + timeperframe->numerator = 1;
  83735. + }
  83736. +
  83737. + /* Actual frame rate we use */
  83738. + tgt_fps = timeperframe->denominator /
  83739. + timeperframe->numerator;
  83740. +
  83741. + if (tgt_fps == 15)
  83742. + new_frame_rate = ov5642_15_fps;
  83743. + else if (tgt_fps == 30)
  83744. + new_frame_rate = ov5642_30_fps;
  83745. + else {
  83746. + pr_err(" The camera frame rate is not supported!\n");
  83747. + return -EINVAL;
  83748. + }
  83749. +
  83750. + if (sensor->streamcap.timeperframe.numerator != 0)
  83751. + old_fps = sensor->streamcap.timeperframe.denominator /
  83752. + sensor->streamcap.timeperframe.numerator;
  83753. + else
  83754. + old_fps = 30;
  83755. +
  83756. + if (old_fps == 15)
  83757. + old_frame_rate = ov5642_15_fps;
  83758. + else if (old_fps == 30)
  83759. + old_frame_rate = ov5642_30_fps;
  83760. + else {
  83761. + pr_warning(" No valid frame rate set!\n");
  83762. + old_frame_rate = ov5642_30_fps;
  83763. + }
  83764. +
  83765. + ret = ov5642_change_mode(new_frame_rate, old_frame_rate,
  83766. + a->parm.capture.capturemode,
  83767. + sensor->streamcap.capturemode);
  83768. + if (ret < 0)
  83769. + return ret;
  83770. +
  83771. + sensor->streamcap.timeperframe = *timeperframe;
  83772. + sensor->streamcap.capturemode =
  83773. + (u32)a->parm.capture.capturemode;
  83774. + break;
  83775. +
  83776. + /* These are all the possible cases. */
  83777. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  83778. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  83779. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  83780. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  83781. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  83782. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  83783. + pr_debug(" type is not " \
  83784. + "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
  83785. + a->type);
  83786. + ret = -EINVAL;
  83787. + break;
  83788. +
  83789. + default:
  83790. + pr_debug(" type is unknown - %d\n", a->type);
  83791. + ret = -EINVAL;
  83792. + break;
  83793. + }
  83794. +
  83795. + return ret;
  83796. +}
  83797. +
  83798. +/*!
  83799. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  83800. + * @s: pointer to standard V4L2 device structure
  83801. + * @f: pointer to standard V4L2 v4l2_format structure
  83802. + *
  83803. + * Returns the sensor's current pixel format in the v4l2_format
  83804. + * parameter.
  83805. + */
  83806. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  83807. +{
  83808. + struct sensor_data *sensor = s->priv;
  83809. +
  83810. + f->fmt.pix = sensor->pix;
  83811. +
  83812. + return 0;
  83813. +}
  83814. +
  83815. +/*!
  83816. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  83817. + * @s: pointer to standard V4L2 device structure
  83818. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  83819. + *
  83820. + * If the requested control is supported, returns the control's current
  83821. + * value from the video_control[] array. Otherwise, returns -EINVAL
  83822. + * if the control is not supported.
  83823. + */
  83824. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  83825. +{
  83826. + int ret = 0;
  83827. +
  83828. + switch (vc->id) {
  83829. + case V4L2_CID_BRIGHTNESS:
  83830. + vc->value = ov5642_data.brightness;
  83831. + break;
  83832. + case V4L2_CID_HUE:
  83833. + vc->value = ov5642_data.hue;
  83834. + break;
  83835. + case V4L2_CID_CONTRAST:
  83836. + vc->value = ov5642_data.contrast;
  83837. + break;
  83838. + case V4L2_CID_SATURATION:
  83839. + vc->value = ov5642_data.saturation;
  83840. + break;
  83841. + case V4L2_CID_RED_BALANCE:
  83842. + vc->value = ov5642_data.red;
  83843. + break;
  83844. + case V4L2_CID_BLUE_BALANCE:
  83845. + vc->value = ov5642_data.blue;
  83846. + break;
  83847. + case V4L2_CID_EXPOSURE:
  83848. + vc->value = ov5642_data.ae_mode;
  83849. + break;
  83850. + default:
  83851. + ret = -EINVAL;
  83852. + }
  83853. +
  83854. + return ret;
  83855. +}
  83856. +
  83857. +/*!
  83858. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  83859. + * @s: pointer to standard V4L2 device structure
  83860. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  83861. + *
  83862. + * If the requested control is supported, sets the control's current
  83863. + * value in HW (and updates the video_control[] array). Otherwise,
  83864. + * returns -EINVAL if the control is not supported.
  83865. + */
  83866. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  83867. +{
  83868. + int retval = 0;
  83869. + struct sensor_data *sensor = s->priv;
  83870. + __u32 captureMode = sensor->streamcap.capturemode;
  83871. + struct reg_value *rot_mode = NULL;
  83872. +
  83873. + pr_debug("In ov5642:ioctl_s_ctrl %d\n",
  83874. + vc->id);
  83875. +
  83876. + switch (vc->id) {
  83877. + case V4L2_CID_BRIGHTNESS:
  83878. + break;
  83879. + case V4L2_CID_CONTRAST:
  83880. + break;
  83881. + case V4L2_CID_SATURATION:
  83882. + break;
  83883. + case V4L2_CID_HUE:
  83884. + break;
  83885. + case V4L2_CID_AUTO_WHITE_BALANCE:
  83886. + break;
  83887. + case V4L2_CID_DO_WHITE_BALANCE:
  83888. + break;
  83889. + case V4L2_CID_RED_BALANCE:
  83890. + break;
  83891. + case V4L2_CID_BLUE_BALANCE:
  83892. + break;
  83893. + case V4L2_CID_GAMMA:
  83894. + break;
  83895. + case V4L2_CID_EXPOSURE:
  83896. + break;
  83897. + case V4L2_CID_AUTOGAIN:
  83898. + break;
  83899. + case V4L2_CID_GAIN:
  83900. + break;
  83901. + case V4L2_CID_HFLIP:
  83902. + break;
  83903. + case V4L2_CID_VFLIP:
  83904. + break;
  83905. + case V4L2_CID_MXC_ROT:
  83906. + case V4L2_CID_MXC_VF_ROT:
  83907. + switch (vc->value) {
  83908. + case V4L2_MXC_ROTATE_NONE:
  83909. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  83910. + rot_mode = ov5642_rot_none_FULL;
  83911. + else
  83912. + rot_mode = ov5642_rot_none_VGA;
  83913. +
  83914. + if (ov5642_set_rot_mode(rot_mode))
  83915. + retval = -EPERM;
  83916. + break;
  83917. + case V4L2_MXC_ROTATE_VERT_FLIP:
  83918. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  83919. + rot_mode = ov5642_rot_vert_flip_FULL;
  83920. + else
  83921. + rot_mode = ov5642_rot_vert_flip_VGA ;
  83922. +
  83923. + if (ov5642_set_rot_mode(rot_mode))
  83924. + retval = -EPERM;
  83925. + break;
  83926. + case V4L2_MXC_ROTATE_HORIZ_FLIP:
  83927. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  83928. + rot_mode = ov5642_rot_horiz_flip_FULL;
  83929. + else
  83930. + rot_mode = ov5642_rot_horiz_flip_VGA;
  83931. +
  83932. + if (ov5642_set_rot_mode(rot_mode))
  83933. + retval = -EPERM;
  83934. + break;
  83935. + case V4L2_MXC_ROTATE_180:
  83936. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  83937. + rot_mode = ov5642_rot_180_FULL;
  83938. + else
  83939. + rot_mode = ov5642_rot_180_VGA;
  83940. +
  83941. + if (ov5642_set_rot_mode(rot_mode))
  83942. + retval = -EPERM;
  83943. + break;
  83944. + default:
  83945. + retval = -EPERM;
  83946. + break;
  83947. + }
  83948. + break;
  83949. + default:
  83950. + retval = -EPERM;
  83951. + break;
  83952. + }
  83953. +
  83954. + return retval;
  83955. +}
  83956. +
  83957. +/*!
  83958. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  83959. + * VIDIOC_ENUM_FRAMESIZES ioctl
  83960. + * @s: pointer to standard V4L2 device structure
  83961. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  83962. + *
  83963. + * Return 0 if successful, otherwise -EINVAL.
  83964. + */
  83965. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  83966. + struct v4l2_frmsizeenum *fsize)
  83967. +{
  83968. + if (fsize->index > ov5642_mode_MAX)
  83969. + return -EINVAL;
  83970. +
  83971. + fsize->pixel_format = ov5642_data.pix.pixelformat;
  83972. + fsize->discrete.width =
  83973. + max(ov5642_mode_info_data[0][fsize->index].width,
  83974. + ov5642_mode_info_data[1][fsize->index].width);
  83975. + fsize->discrete.height =
  83976. + max(ov5642_mode_info_data[0][fsize->index].height,
  83977. + ov5642_mode_info_data[1][fsize->index].height);
  83978. + return 0;
  83979. +}
  83980. +
  83981. +/*!
  83982. + * ioctl_enum_frameintervals - V4L2 sensor interface handler for
  83983. + * VIDIOC_ENUM_FRAMEINTERVALS ioctl
  83984. + * @s: pointer to standard V4L2 device structure
  83985. + * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
  83986. + *
  83987. + * Return 0 if successful, otherwise -EINVAL.
  83988. + */
  83989. +static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
  83990. + struct v4l2_frmivalenum *fival)
  83991. +{
  83992. + int i, j, count;
  83993. +
  83994. + if (fival->index < 0 || fival->index > ov5642_mode_MAX)
  83995. + return -EINVAL;
  83996. +
  83997. + if (fival->pixel_format == 0 || fival->width == 0 ||
  83998. + fival->height == 0) {
  83999. + pr_warning("Please assign pixelformat, width and height.\n");
  84000. + return -EINVAL;
  84001. + }
  84002. +
  84003. + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
  84004. + fival->discrete.numerator = 1;
  84005. +
  84006. + count = 0;
  84007. + for (i = 0; i < ARRAY_SIZE(ov5642_mode_info_data); i++) {
  84008. + for (j = 0; j < (ov5642_mode_MAX + 1); j++) {
  84009. + if (fival->pixel_format == ov5642_data.pix.pixelformat
  84010. + && fival->width == ov5642_mode_info_data[i][j].width
  84011. + && fival->height == ov5642_mode_info_data[i][j].height
  84012. + && ov5642_mode_info_data[i][j].init_data_ptr != NULL) {
  84013. + count++;
  84014. + }
  84015. + if (fival->index == (count - 1)) {
  84016. + fival->discrete.denominator =
  84017. + ov5642_framerates[i];
  84018. + return 0;
  84019. + }
  84020. + }
  84021. + }
  84022. +
  84023. + return -EINVAL;
  84024. +}
  84025. +
  84026. +/*!
  84027. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  84028. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  84029. + * @s: pointer to standard V4L2 device structure
  84030. + * @id: pointer to int
  84031. + *
  84032. + * Return 0.
  84033. + */
  84034. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  84035. +{
  84036. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  84037. + V4L2_CHIP_MATCH_I2C_DRIVER;
  84038. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name, "ov5642_camera");
  84039. +
  84040. + return 0;
  84041. +}
  84042. +
  84043. +/*!
  84044. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  84045. + * @s: pointer to standard V4L2 device structure
  84046. + */
  84047. +static int ioctl_init(struct v4l2_int_device *s)
  84048. +{
  84049. +
  84050. + return 0;
  84051. +}
  84052. +
  84053. +/*!
  84054. + * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
  84055. + * @s: pointer to standard V4L2 device structure
  84056. + * @fmt: pointer to standard V4L2 fmt description structure
  84057. + *
  84058. + * Return 0.
  84059. + */
  84060. +static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
  84061. + struct v4l2_fmtdesc *fmt)
  84062. +{
  84063. + if (fmt->index > 0) /* only 1 pixelformat support so far */
  84064. + return -EINVAL;
  84065. +
  84066. + fmt->pixelformat = ov5642_data.pix.pixelformat;
  84067. +
  84068. + return 0;
  84069. +}
  84070. +
  84071. +/*!
  84072. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  84073. + * @s: pointer to standard V4L2 device structure
  84074. + *
  84075. + * Initialise the device when slave attaches to the master.
  84076. + */
  84077. +static int ioctl_dev_init(struct v4l2_int_device *s)
  84078. +{
  84079. + struct reg_value *pModeSetting = NULL;
  84080. + s32 i = 0;
  84081. + s32 iModeSettingArySize = 0;
  84082. + register u32 Delay_ms = 0;
  84083. + register u16 RegAddr = 0;
  84084. + register u8 Mask = 0;
  84085. + register u8 Val = 0;
  84086. + u8 RegVal = 0;
  84087. + int retval = 0;
  84088. +
  84089. + struct sensor_data *sensor = s->priv;
  84090. + u32 tgt_xclk; /* target xclk */
  84091. + u32 tgt_fps; /* target frames per secound */
  84092. + enum ov5642_frame_rate frame_rate;
  84093. +
  84094. + ov5642_data.on = true;
  84095. +
  84096. + /* mclk */
  84097. + tgt_xclk = ov5642_data.mclk;
  84098. + tgt_xclk = min(tgt_xclk, (u32)OV5642_XCLK_MAX);
  84099. + tgt_xclk = max(tgt_xclk, (u32)OV5642_XCLK_MIN);
  84100. + ov5642_data.mclk = tgt_xclk;
  84101. +
  84102. + pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
  84103. +
  84104. + /* Default camera frame rate is set in probe */
  84105. + tgt_fps = sensor->streamcap.timeperframe.denominator /
  84106. + sensor->streamcap.timeperframe.numerator;
  84107. +
  84108. + if (tgt_fps == 15)
  84109. + frame_rate = ov5642_15_fps;
  84110. + else if (tgt_fps == 30)
  84111. + frame_rate = ov5642_30_fps;
  84112. + else
  84113. + return -EINVAL; /* Only support 15fps or 30fps now. */
  84114. +
  84115. + pModeSetting = ov5642_initial_setting;
  84116. + iModeSettingArySize = ARRAY_SIZE(ov5642_initial_setting);
  84117. +
  84118. + for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
  84119. + Delay_ms = pModeSetting->u32Delay_ms;
  84120. + RegAddr = pModeSetting->u16RegAddr;
  84121. + Val = pModeSetting->u8Val;
  84122. + Mask = pModeSetting->u8Mask;
  84123. + if (Mask) {
  84124. + retval = ov5642_read_reg(RegAddr, &RegVal);
  84125. + if (retval < 0)
  84126. + goto err;
  84127. +
  84128. + RegVal &= ~(u8)Mask;
  84129. + Val &= Mask;
  84130. + Val |= RegVal;
  84131. + }
  84132. +
  84133. + retval = ov5642_write_reg(RegAddr, Val);
  84134. + if (retval < 0)
  84135. + goto err;
  84136. +
  84137. + if (Delay_ms)
  84138. + msleep(Delay_ms);
  84139. + }
  84140. +err:
  84141. + return retval;
  84142. +}
  84143. +
  84144. +/*!
  84145. + * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
  84146. + * @s: pointer to standard V4L2 device structure
  84147. + *
  84148. + * Delinitialise the device when slave detaches to the master.
  84149. + */
  84150. +static int ioctl_dev_exit(struct v4l2_int_device *s)
  84151. +{
  84152. + return 0;
  84153. +}
  84154. +
  84155. +/*!
  84156. + * This structure defines all the ioctls for this module and links them to the
  84157. + * enumeration.
  84158. + */
  84159. +static struct v4l2_int_ioctl_desc ov5642_ioctl_desc[] = {
  84160. + { vidioc_int_dev_init_num,
  84161. + (v4l2_int_ioctl_func *)ioctl_dev_init },
  84162. + { vidioc_int_dev_exit_num, ioctl_dev_exit},
  84163. + { vidioc_int_s_power_num,
  84164. + (v4l2_int_ioctl_func *)ioctl_s_power },
  84165. + { vidioc_int_g_ifparm_num,
  84166. + (v4l2_int_ioctl_func *)ioctl_g_ifparm },
  84167. +/* { vidioc_int_g_needs_reset_num,
  84168. + (v4l2_int_ioctl_func *)ioctl_g_needs_reset }, */
  84169. +/* { vidioc_int_reset_num,
  84170. + (v4l2_int_ioctl_func *)ioctl_reset }, */
  84171. + { vidioc_int_init_num,
  84172. + (v4l2_int_ioctl_func *)ioctl_init },
  84173. + { vidioc_int_enum_fmt_cap_num,
  84174. + (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
  84175. +/* { vidioc_int_try_fmt_cap_num,
  84176. + (v4l2_int_ioctl_func *)ioctl_try_fmt_cap }, */
  84177. + { vidioc_int_g_fmt_cap_num,
  84178. + (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
  84179. +/* { vidioc_int_s_fmt_cap_num,
  84180. + (v4l2_int_ioctl_func *)ioctl_s_fmt_cap }, */
  84181. + { vidioc_int_g_parm_num,
  84182. + (v4l2_int_ioctl_func *)ioctl_g_parm },
  84183. + { vidioc_int_s_parm_num,
  84184. + (v4l2_int_ioctl_func *)ioctl_s_parm },
  84185. +/* { vidioc_int_queryctrl_num,
  84186. + (v4l2_int_ioctl_func *)ioctl_queryctrl }, */
  84187. + { vidioc_int_g_ctrl_num,
  84188. + (v4l2_int_ioctl_func *)ioctl_g_ctrl },
  84189. + { vidioc_int_s_ctrl_num,
  84190. + (v4l2_int_ioctl_func *)ioctl_s_ctrl },
  84191. + { vidioc_int_enum_framesizes_num,
  84192. + (v4l2_int_ioctl_func *)ioctl_enum_framesizes },
  84193. + { vidioc_int_enum_frameintervals_num,
  84194. + (v4l2_int_ioctl_func *)ioctl_enum_frameintervals },
  84195. + { vidioc_int_g_chip_ident_num,
  84196. + (v4l2_int_ioctl_func *)ioctl_g_chip_ident },
  84197. +};
  84198. +
  84199. +static struct v4l2_int_slave ov5642_slave = {
  84200. + .ioctls = ov5642_ioctl_desc,
  84201. + .num_ioctls = ARRAY_SIZE(ov5642_ioctl_desc),
  84202. +};
  84203. +
  84204. +static struct v4l2_int_device ov5642_int_device = {
  84205. + .module = THIS_MODULE,
  84206. + .name = "ov5642",
  84207. + .type = v4l2_int_type_slave,
  84208. + .u = {
  84209. + .slave = &ov5642_slave,
  84210. + },
  84211. +};
  84212. +
  84213. +/*!
  84214. + * ov5642 I2C probe function
  84215. + *
  84216. + * @param adapter struct i2c_adapter *
  84217. + * @return Error code indicating success or failure
  84218. + */
  84219. +static int ov5642_probe(struct i2c_client *client,
  84220. + const struct i2c_device_id *id)
  84221. +{
  84222. + struct pinctrl *pinctrl;
  84223. + struct device *dev = &client->dev;
  84224. + int retval;
  84225. + u8 chip_id_high, chip_id_low;
  84226. +
  84227. + /* ov5642 pinctrl */
  84228. + pinctrl = devm_pinctrl_get_select_default(dev);
  84229. + if (IS_ERR(pinctrl)) {
  84230. + dev_err(dev, "ov5642 setup pinctrl failed!");
  84231. + return PTR_ERR(pinctrl);
  84232. + }
  84233. +
  84234. + /* request power down pin */
  84235. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  84236. + if (!gpio_is_valid(pwn_gpio)) {
  84237. + dev_warn(dev, "no sensor pwdn pin available");
  84238. + return -EINVAL;
  84239. + }
  84240. + retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  84241. + "ov5642_pwdn");
  84242. + if (retval < 0)
  84243. + return retval;
  84244. +
  84245. + /* request reset pin */
  84246. + rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
  84247. + if (!gpio_is_valid(rst_gpio)) {
  84248. + dev_warn(dev, "no sensor reset pin available");
  84249. + return -EINVAL;
  84250. + }
  84251. + retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
  84252. + "ov5642_reset");
  84253. + if (retval < 0)
  84254. + return retval;
  84255. +
  84256. + /* Set initial values for the sensor struct. */
  84257. + memset(&ov5642_data, 0, sizeof(ov5642_data));
  84258. + ov5642_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
  84259. + if (IS_ERR(ov5642_data.sensor_clk)) {
  84260. + /* assuming clock enabled by default */
  84261. + ov5642_data.sensor_clk = NULL;
  84262. + dev_err(dev, "clock-frequency missing or invalid\n");
  84263. + return PTR_ERR(ov5642_data.sensor_clk);
  84264. + }
  84265. +
  84266. + retval = of_property_read_u32(dev->of_node, "mclk",
  84267. + (u32 *) &(ov5642_data.mclk));
  84268. + if (retval) {
  84269. + dev_err(dev, "mclk missing or invalid\n");
  84270. + return retval;
  84271. + }
  84272. +
  84273. + retval = of_property_read_u32(dev->of_node, "mclk_source",
  84274. + (u32 *) &(ov5642_data.mclk_source));
  84275. + if (retval) {
  84276. + dev_err(dev, "mclk_source missing or invalid\n");
  84277. + return retval;
  84278. + }
  84279. +
  84280. + retval = of_property_read_u32(dev->of_node, "csi_id",
  84281. + &(ov5642_data.csi));
  84282. + if (retval) {
  84283. + dev_err(dev, "csi_id missing or invalid\n");
  84284. + return retval;
  84285. + }
  84286. +
  84287. + clk_prepare_enable(ov5642_data.sensor_clk);
  84288. +
  84289. + ov5642_data.io_init = ov5642_reset;
  84290. + ov5642_data.i2c_client = client;
  84291. + ov5642_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  84292. + ov5642_data.pix.width = 640;
  84293. + ov5642_data.pix.height = 480;
  84294. + ov5642_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
  84295. + V4L2_CAP_TIMEPERFRAME;
  84296. + ov5642_data.streamcap.capturemode = 0;
  84297. + ov5642_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
  84298. + ov5642_data.streamcap.timeperframe.numerator = 1;
  84299. +
  84300. + ov5642_power_on(&client->dev);
  84301. +
  84302. + ov5642_reset();
  84303. +
  84304. + ov5642_standby(0);
  84305. +
  84306. + retval = ov5642_read_reg(OV5642_CHIP_ID_HIGH_BYTE, &chip_id_high);
  84307. + if (retval < 0 || chip_id_high != 0x56) {
  84308. + pr_warning("camera ov5642 is not found\n");
  84309. + clk_disable_unprepare(ov5642_data.sensor_clk);
  84310. + return -ENODEV;
  84311. + }
  84312. + retval = ov5642_read_reg(OV5642_CHIP_ID_LOW_BYTE, &chip_id_low);
  84313. + if (retval < 0 || chip_id_low != 0x42) {
  84314. + pr_warning("camera ov5642 is not found\n");
  84315. + clk_disable_unprepare(ov5642_data.sensor_clk);
  84316. + return -ENODEV;
  84317. + }
  84318. +
  84319. + ov5642_standby(1);
  84320. +
  84321. + ov5642_int_device.priv = &ov5642_data;
  84322. + retval = v4l2_int_device_register(&ov5642_int_device);
  84323. +
  84324. + clk_disable_unprepare(ov5642_data.sensor_clk);
  84325. +
  84326. + pr_info("camera ov5642 is found\n");
  84327. + return retval;
  84328. +}
  84329. +
  84330. +/*!
  84331. + * ov5642 I2C detach function
  84332. + *
  84333. + * @param client struct i2c_client *
  84334. + * @return Error code indicating success or failure
  84335. + */
  84336. +static int ov5642_remove(struct i2c_client *client)
  84337. +{
  84338. + v4l2_int_device_unregister(&ov5642_int_device);
  84339. +
  84340. + if (gpo_regulator)
  84341. + regulator_disable(gpo_regulator);
  84342. +
  84343. + if (analog_regulator)
  84344. + regulator_disable(analog_regulator);
  84345. +
  84346. + if (core_regulator)
  84347. + regulator_disable(core_regulator);
  84348. +
  84349. + if (io_regulator)
  84350. + regulator_disable(io_regulator);
  84351. +
  84352. + return 0;
  84353. +}
  84354. +
  84355. +/*!
  84356. + * ov5642 init function
  84357. + * Called by insmod ov5642_camera.ko.
  84358. + *
  84359. + * @return Error code indicating success or failure
  84360. + */
  84361. +static __init int ov5642_init(void)
  84362. +{
  84363. + u8 err;
  84364. +
  84365. + err = i2c_add_driver(&ov5642_i2c_driver);
  84366. + if (err != 0)
  84367. + pr_err("%s:driver registration failed, error=%d\n",
  84368. + __func__, err);
  84369. +
  84370. + return err;
  84371. +}
  84372. +
  84373. +/*!
  84374. + * OV5642 cleanup function
  84375. + * Called on rmmod ov5642_camera.ko
  84376. + *
  84377. + * @return Error code indicating success or failure
  84378. + */
  84379. +static void __exit ov5642_clean(void)
  84380. +{
  84381. + i2c_del_driver(&ov5642_i2c_driver);
  84382. +}
  84383. +
  84384. +module_init(ov5642_init);
  84385. +module_exit(ov5642_clean);
  84386. +
  84387. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  84388. +MODULE_DESCRIPTION("OV5642 Camera Driver");
  84389. +MODULE_LICENSE("GPL");
  84390. +MODULE_VERSION("1.0");
  84391. +MODULE_ALIAS("CSI");
  84392. diff -Nur linux-3.14.14/drivers/media/platform/mxc/output/Kconfig linux-imx6-3.14/drivers/media/platform/mxc/output/Kconfig
  84393. --- linux-3.14.14/drivers/media/platform/mxc/output/Kconfig 1969-12-31 18:00:00.000000000 -0600
  84394. +++ linux-imx6-3.14/drivers/media/platform/mxc/output/Kconfig 2014-12-08 00:31:53.256418001 -0600
  84395. @@ -0,0 +1,5 @@
  84396. +config VIDEO_MXC_IPU_OUTPUT
  84397. + tristate "IPU v4l2 output support"
  84398. + depends on VIDEO_MXC_OUTPUT && MXC_IPU
  84399. + ---help---
  84400. + This is the video4linux2 driver for IPU post processing video output.
  84401. diff -Nur linux-3.14.14/drivers/media/platform/mxc/output/Makefile linux-imx6-3.14/drivers/media/platform/mxc/output/Makefile
  84402. --- linux-3.14.14/drivers/media/platform/mxc/output/Makefile 1969-12-31 18:00:00.000000000 -0600
  84403. +++ linux-imx6-3.14/drivers/media/platform/mxc/output/Makefile 2014-12-08 00:31:53.256418001 -0600
  84404. @@ -0,0 +1 @@
  84405. +obj-$(CONFIG_VIDEO_MXC_IPU_OUTPUT) += mxc_vout.o
  84406. diff -Nur linux-3.14.14/drivers/media/platform/mxc/output/mxc_vout.c linux-imx6-3.14/drivers/media/platform/mxc/output/mxc_vout.c
  84407. --- linux-3.14.14/drivers/media/platform/mxc/output/mxc_vout.c 1969-12-31 18:00:00.000000000 -0600
  84408. +++ linux-imx6-3.14/drivers/media/platform/mxc/output/mxc_vout.c 2014-12-08 00:31:53.256418001 -0600
  84409. @@ -0,0 +1,2265 @@
  84410. +/*
  84411. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  84412. + */
  84413. +
  84414. +/*
  84415. + * The code contained herein is licensed under the GNU General Public
  84416. + * License. You may obtain a copy of the GNU General Public License
  84417. + * Version 2 or later at the following locations:
  84418. + *
  84419. + * http://www.opensource.org/licenses/gpl-license.html
  84420. + * http://www.gnu.org/copyleft/gpl.html
  84421. + */
  84422. +
  84423. +#include <linux/console.h>
  84424. +#include <linux/dma-mapping.h>
  84425. +#include <linux/init.h>
  84426. +#include <linux/ipu-v3.h>
  84427. +#include <linux/module.h>
  84428. +#include <linux/mxcfb.h>
  84429. +#include <linux/mxc_v4l2.h>
  84430. +#include <linux/platform_device.h>
  84431. +#include <linux/sched.h>
  84432. +#include <linux/types.h>
  84433. +#include <linux/videodev2.h>
  84434. +#include <linux/vmalloc.h>
  84435. +
  84436. +#include <media/videobuf-dma-contig.h>
  84437. +#include <media/v4l2-device.h>
  84438. +#include <media/v4l2-ioctl.h>
  84439. +
  84440. +#define UYVY_BLACK (0x00800080)
  84441. +#define RGB_BLACK (0x0)
  84442. +#define UV_BLACK (0x80)
  84443. +#define Y_BLACK (0x0)
  84444. +
  84445. +#define MAX_FB_NUM 6
  84446. +#define FB_BUFS 3
  84447. +#define VDOA_FB_BUFS (FB_BUFS - 1)
  84448. +#define VALID_HEIGHT_1080P (1080)
  84449. +#define FRAME_HEIGHT_1080P (1088)
  84450. +#define FRAME_WIDTH_1080P (1920)
  84451. +#define CHECK_TILED_1080P_DISPLAY(vout) \
  84452. + ((((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12) || \
  84453. + ((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12F)) &&\
  84454. + ((vout)->task.input.width == FRAME_WIDTH_1080P) && \
  84455. + ((vout)->task.input.height == FRAME_HEIGHT_1080P) && \
  84456. + ((vout)->task.input.crop.w == FRAME_WIDTH_1080P) && \
  84457. + (((vout)->task.input.crop.h == FRAME_HEIGHT_1080P) || \
  84458. + ((vout)->task.input.crop.h == VALID_HEIGHT_1080P)) && \
  84459. + ((vout)->task.output.width == FRAME_WIDTH_1080P) && \
  84460. + ((vout)->task.output.height == VALID_HEIGHT_1080P) && \
  84461. + ((vout)->task.output.crop.w == FRAME_WIDTH_1080P) && \
  84462. + ((vout)->task.output.crop.h == VALID_HEIGHT_1080P))
  84463. +#define CHECK_TILED_1080P_STREAM(vout) \
  84464. + ((((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12) || \
  84465. + ((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12F)) &&\
  84466. + ((vout)->task.input.width == FRAME_WIDTH_1080P) && \
  84467. + ((vout)->task.input.crop.w == FRAME_WIDTH_1080P) && \
  84468. + ((vout)->task.input.height == FRAME_HEIGHT_1080P) && \
  84469. + ((vout)->task.input.crop.h == FRAME_HEIGHT_1080P))
  84470. +#define IS_PLANAR_PIXEL_FORMAT(format) \
  84471. + (format == IPU_PIX_FMT_NV12 || \
  84472. + format == IPU_PIX_FMT_YUV420P2 || \
  84473. + format == IPU_PIX_FMT_YUV420P || \
  84474. + format == IPU_PIX_FMT_YVU420P || \
  84475. + format == IPU_PIX_FMT_YUV422P || \
  84476. + format == IPU_PIX_FMT_YVU422P || \
  84477. + format == IPU_PIX_FMT_YUV444P)
  84478. +
  84479. +#define NSEC_PER_FRAME_30FPS (33333333)
  84480. +
  84481. +struct mxc_vout_fb {
  84482. + char *name;
  84483. + int ipu_id;
  84484. + struct v4l2_rect crop_bounds;
  84485. + unsigned int disp_fmt;
  84486. + bool disp_support_csc;
  84487. + bool disp_support_windows;
  84488. +};
  84489. +
  84490. +struct dma_mem {
  84491. + void *vaddr;
  84492. + dma_addr_t paddr;
  84493. + size_t size;
  84494. +};
  84495. +
  84496. +struct mxc_vout_output {
  84497. + int open_cnt;
  84498. + struct fb_info *fbi;
  84499. + unsigned long fb_smem_start;
  84500. + unsigned long fb_smem_len;
  84501. + struct video_device *vfd;
  84502. + struct mutex mutex;
  84503. + struct mutex task_lock;
  84504. + enum v4l2_buf_type type;
  84505. +
  84506. + struct videobuf_queue vbq;
  84507. + spinlock_t vbq_lock;
  84508. +
  84509. + struct list_head queue_list;
  84510. + struct list_head active_list;
  84511. +
  84512. + struct v4l2_rect crop_bounds;
  84513. + unsigned int disp_fmt;
  84514. + struct mxcfb_pos win_pos;
  84515. + bool disp_support_windows;
  84516. + bool disp_support_csc;
  84517. +
  84518. + bool fmt_init;
  84519. + bool release;
  84520. + bool linear_bypass_pp;
  84521. + bool vdoa_1080p;
  84522. + bool tiled_bypass_pp;
  84523. + struct v4l2_rect in_rect;
  84524. + struct ipu_task task;
  84525. + struct ipu_task vdoa_task;
  84526. + struct dma_mem vdoa_work;
  84527. + struct dma_mem vdoa_output[VDOA_FB_BUFS];
  84528. +
  84529. + bool timer_stop;
  84530. + struct hrtimer timer;
  84531. + struct workqueue_struct *v4l_wq;
  84532. + struct work_struct disp_work;
  84533. + unsigned long frame_count;
  84534. + unsigned long vdi_frame_cnt;
  84535. + ktime_t start_ktime;
  84536. +
  84537. + int ctrl_rotate;
  84538. + int ctrl_vflip;
  84539. + int ctrl_hflip;
  84540. +
  84541. + dma_addr_t disp_bufs[FB_BUFS];
  84542. +
  84543. + struct videobuf_buffer *pre1_vb;
  84544. + struct videobuf_buffer *pre2_vb;
  84545. +};
  84546. +
  84547. +struct mxc_vout_dev {
  84548. + struct device *dev;
  84549. + struct v4l2_device v4l2_dev;
  84550. + struct mxc_vout_output *out[MAX_FB_NUM];
  84551. + int out_num;
  84552. +};
  84553. +
  84554. +/* Driver Configuration macros */
  84555. +#define VOUT_NAME "mxc_vout"
  84556. +
  84557. +/* Variables configurable through module params*/
  84558. +static int debug;
  84559. +static int vdi_rate_double;
  84560. +static int video_nr = 16;
  84561. +
  84562. +/* Module parameters */
  84563. +module_param(video_nr, int, S_IRUGO);
  84564. +MODULE_PARM_DESC(video_nr, "video device numbers");
  84565. +module_param(debug, int, 0600);
  84566. +MODULE_PARM_DESC(debug, "Debug level (0-1)");
  84567. +module_param(vdi_rate_double, int, 0600);
  84568. +MODULE_PARM_DESC(vdi_rate_double, "vdi frame rate double on/off");
  84569. +
  84570. +static const struct v4l2_fmtdesc mxc_formats[] = {
  84571. + {
  84572. + .description = "RGB565",
  84573. + .pixelformat = V4L2_PIX_FMT_RGB565,
  84574. + },
  84575. + {
  84576. + .description = "BGR24",
  84577. + .pixelformat = V4L2_PIX_FMT_BGR24,
  84578. + },
  84579. + {
  84580. + .description = "RGB24",
  84581. + .pixelformat = V4L2_PIX_FMT_RGB24,
  84582. + },
  84583. + {
  84584. + .description = "RGB32",
  84585. + .pixelformat = V4L2_PIX_FMT_RGB32,
  84586. + },
  84587. + {
  84588. + .description = "BGR32",
  84589. + .pixelformat = V4L2_PIX_FMT_BGR32,
  84590. + },
  84591. + {
  84592. + .description = "NV12",
  84593. + .pixelformat = V4L2_PIX_FMT_NV12,
  84594. + },
  84595. + {
  84596. + .description = "UYVY",
  84597. + .pixelformat = V4L2_PIX_FMT_UYVY,
  84598. + },
  84599. + {
  84600. + .description = "YUYV",
  84601. + .pixelformat = V4L2_PIX_FMT_YUYV,
  84602. + },
  84603. + {
  84604. + .description = "YUV422 planar",
  84605. + .pixelformat = V4L2_PIX_FMT_YUV422P,
  84606. + },
  84607. + {
  84608. + .description = "YUV444",
  84609. + .pixelformat = V4L2_PIX_FMT_YUV444,
  84610. + },
  84611. + {
  84612. + .description = "YUV420",
  84613. + .pixelformat = V4L2_PIX_FMT_YUV420,
  84614. + },
  84615. + {
  84616. + .description = "YVU420",
  84617. + .pixelformat = V4L2_PIX_FMT_YVU420,
  84618. + },
  84619. + {
  84620. + .description = "TILED NV12P",
  84621. + .pixelformat = IPU_PIX_FMT_TILED_NV12,
  84622. + },
  84623. + {
  84624. + .description = "TILED NV12F",
  84625. + .pixelformat = IPU_PIX_FMT_TILED_NV12F,
  84626. + },
  84627. + {
  84628. + .description = "YUV444 planar",
  84629. + .pixelformat = IPU_PIX_FMT_YUV444P,
  84630. + },
  84631. +};
  84632. +
  84633. +#define NUM_MXC_VOUT_FORMATS (ARRAY_SIZE(mxc_formats))
  84634. +
  84635. +#define DEF_INPUT_WIDTH 320
  84636. +#define DEF_INPUT_HEIGHT 240
  84637. +
  84638. +static int mxc_vidioc_streamoff(struct file *file, void *fh,
  84639. + enum v4l2_buf_type i);
  84640. +
  84641. +static struct mxc_vout_fb g_fb_setting[MAX_FB_NUM];
  84642. +static int config_disp_output(struct mxc_vout_output *vout);
  84643. +static void release_disp_output(struct mxc_vout_output *vout);
  84644. +
  84645. +static unsigned int get_frame_size(struct mxc_vout_output *vout)
  84646. +{
  84647. + unsigned int size;
  84648. +
  84649. + if (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format)
  84650. + size = TILED_NV12_FRAME_SIZE(vout->task.input.width,
  84651. + vout->task.input.height);
  84652. + else if (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format) {
  84653. + size = TILED_NV12_FRAME_SIZE(vout->task.input.width,
  84654. + vout->task.input.height/2);
  84655. + size *= 2;
  84656. + } else
  84657. + size = vout->task.input.width * vout->task.input.height *
  84658. + fmt_to_bpp(vout->task.input.format)/8;
  84659. +
  84660. + return size;
  84661. +}
  84662. +
  84663. +static void free_dma_buf(struct mxc_vout_output *vout, struct dma_mem *buf)
  84664. +{
  84665. + dma_free_coherent(vout->vbq.dev, buf->size, buf->vaddr, buf->paddr);
  84666. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84667. + "free dma size:0x%x, paddr:0x%x\n",
  84668. + buf->size, buf->paddr);
  84669. + memset(buf, 0, sizeof(*buf));
  84670. +}
  84671. +
  84672. +static int alloc_dma_buf(struct mxc_vout_output *vout, struct dma_mem *buf)
  84673. +{
  84674. +
  84675. + buf->vaddr = dma_alloc_coherent(vout->vbq.dev, buf->size, &buf->paddr,
  84676. + GFP_DMA | GFP_KERNEL);
  84677. + if (!buf->vaddr) {
  84678. + v4l2_err(vout->vfd->v4l2_dev,
  84679. + "cannot get dma buf size:0x%x\n", buf->size);
  84680. + return -ENOMEM;
  84681. + }
  84682. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84683. + "alloc dma buf size:0x%x, paddr:0x%x\n", buf->size, buf->paddr);
  84684. + return 0;
  84685. +}
  84686. +
  84687. +static ipu_channel_t get_ipu_channel(struct fb_info *fbi)
  84688. +{
  84689. + ipu_channel_t ipu_ch = CHAN_NONE;
  84690. + mm_segment_t old_fs;
  84691. +
  84692. + if (fbi->fbops->fb_ioctl) {
  84693. + old_fs = get_fs();
  84694. + set_fs(KERNEL_DS);
  84695. + fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_IPU_CHAN,
  84696. + (unsigned long)&ipu_ch);
  84697. + set_fs(old_fs);
  84698. + }
  84699. +
  84700. + return ipu_ch;
  84701. +}
  84702. +
  84703. +static unsigned int get_ipu_fmt(struct fb_info *fbi)
  84704. +{
  84705. + mm_segment_t old_fs;
  84706. + unsigned int fb_fmt;
  84707. +
  84708. + if (fbi->fbops->fb_ioctl) {
  84709. + old_fs = get_fs();
  84710. + set_fs(KERNEL_DS);
  84711. + fbi->fbops->fb_ioctl(fbi, MXCFB_GET_DIFMT,
  84712. + (unsigned long)&fb_fmt);
  84713. + set_fs(old_fs);
  84714. + }
  84715. +
  84716. + return fb_fmt;
  84717. +}
  84718. +
  84719. +static void update_display_setting(void)
  84720. +{
  84721. + int i;
  84722. + struct fb_info *fbi;
  84723. + struct v4l2_rect bg_crop_bounds[2];
  84724. +
  84725. + for (i = 0; i < num_registered_fb; i++) {
  84726. + fbi = registered_fb[i];
  84727. +
  84728. + memset(&g_fb_setting[i], 0, sizeof(struct mxc_vout_fb));
  84729. +
  84730. + if (!strncmp(fbi->fix.id, "DISP3", 5))
  84731. + g_fb_setting[i].ipu_id = 0;
  84732. + else
  84733. + g_fb_setting[i].ipu_id = 1;
  84734. +
  84735. + g_fb_setting[i].name = fbi->fix.id;
  84736. + g_fb_setting[i].crop_bounds.left = 0;
  84737. + g_fb_setting[i].crop_bounds.top = 0;
  84738. + g_fb_setting[i].crop_bounds.width = fbi->var.xres;
  84739. + g_fb_setting[i].crop_bounds.height = fbi->var.yres;
  84740. + g_fb_setting[i].disp_fmt = get_ipu_fmt(fbi);
  84741. +
  84742. + if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
  84743. + bg_crop_bounds[g_fb_setting[i].ipu_id] =
  84744. + g_fb_setting[i].crop_bounds;
  84745. + g_fb_setting[i].disp_support_csc = true;
  84746. + } else if (get_ipu_channel(fbi) == MEM_FG_SYNC) {
  84747. + g_fb_setting[i].disp_support_csc = true;
  84748. + g_fb_setting[i].disp_support_windows = true;
  84749. + }
  84750. + }
  84751. +
  84752. + for (i = 0; i < num_registered_fb; i++) {
  84753. + fbi = registered_fb[i];
  84754. +
  84755. + if (get_ipu_channel(fbi) == MEM_FG_SYNC)
  84756. + g_fb_setting[i].crop_bounds =
  84757. + bg_crop_bounds[g_fb_setting[i].ipu_id];
  84758. + }
  84759. +}
  84760. +
  84761. +/* called after g_fb_setting filled by update_display_setting */
  84762. +static int update_setting_from_fbi(struct mxc_vout_output *vout,
  84763. + struct fb_info *fbi)
  84764. +{
  84765. + int i;
  84766. + bool found = false;
  84767. +
  84768. + for (i = 0; i < MAX_FB_NUM; i++) {
  84769. + if (g_fb_setting[i].name) {
  84770. + if (!strcmp(fbi->fix.id, g_fb_setting[i].name)) {
  84771. + vout->crop_bounds = g_fb_setting[i].crop_bounds;
  84772. + vout->disp_fmt = g_fb_setting[i].disp_fmt;
  84773. + vout->disp_support_csc =
  84774. + g_fb_setting[i].disp_support_csc;
  84775. + vout->disp_support_windows =
  84776. + g_fb_setting[i].disp_support_windows;
  84777. + found = true;
  84778. + break;
  84779. + }
  84780. + }
  84781. + }
  84782. +
  84783. + if (!found) {
  84784. + v4l2_err(vout->vfd->v4l2_dev, "can not find output\n");
  84785. + return -EINVAL;
  84786. + }
  84787. + strlcpy(vout->vfd->name, fbi->fix.id, sizeof(vout->vfd->name));
  84788. +
  84789. + memset(&vout->task, 0, sizeof(struct ipu_task));
  84790. +
  84791. + vout->task.input.width = DEF_INPUT_WIDTH;
  84792. + vout->task.input.height = DEF_INPUT_HEIGHT;
  84793. + vout->task.input.crop.pos.x = 0;
  84794. + vout->task.input.crop.pos.y = 0;
  84795. + vout->task.input.crop.w = DEF_INPUT_WIDTH;
  84796. + vout->task.input.crop.h = DEF_INPUT_HEIGHT;
  84797. +
  84798. + vout->task.output.width = vout->crop_bounds.width;
  84799. + vout->task.output.height = vout->crop_bounds.height;
  84800. + vout->task.output.crop.pos.x = 0;
  84801. + vout->task.output.crop.pos.y = 0;
  84802. + vout->task.output.crop.w = vout->crop_bounds.width;
  84803. + vout->task.output.crop.h = vout->crop_bounds.height;
  84804. + if (colorspaceofpixel(vout->disp_fmt) == YUV_CS)
  84805. + vout->task.output.format = IPU_PIX_FMT_UYVY;
  84806. + else
  84807. + vout->task.output.format = IPU_PIX_FMT_RGB565;
  84808. +
  84809. + return 0;
  84810. +}
  84811. +
  84812. +static inline unsigned long get_jiffies(struct timeval *t)
  84813. +{
  84814. + struct timeval cur;
  84815. +
  84816. + if (t->tv_usec >= 1000000) {
  84817. + t->tv_sec += t->tv_usec / 1000000;
  84818. + t->tv_usec = t->tv_usec % 1000000;
  84819. + }
  84820. +
  84821. + do_gettimeofday(&cur);
  84822. + if ((t->tv_sec < cur.tv_sec)
  84823. + || ((t->tv_sec == cur.tv_sec) && (t->tv_usec < cur.tv_usec)))
  84824. + return jiffies;
  84825. +
  84826. + if (t->tv_usec < cur.tv_usec) {
  84827. + cur.tv_sec = t->tv_sec - cur.tv_sec - 1;
  84828. + cur.tv_usec = t->tv_usec + 1000000 - cur.tv_usec;
  84829. + } else {
  84830. + cur.tv_sec = t->tv_sec - cur.tv_sec;
  84831. + cur.tv_usec = t->tv_usec - cur.tv_usec;
  84832. + }
  84833. +
  84834. + return jiffies + timeval_to_jiffies(&cur);
  84835. +}
  84836. +
  84837. +static bool deinterlace_3_field(struct mxc_vout_output *vout)
  84838. +{
  84839. + return (vout->task.input.deinterlace.enable &&
  84840. + (vout->task.input.deinterlace.motion != HIGH_MOTION));
  84841. +}
  84842. +
  84843. +static int set_field_fmt(struct mxc_vout_output *vout, enum v4l2_field field)
  84844. +{
  84845. + struct ipu_deinterlace *deinterlace = &vout->task.input.deinterlace;
  84846. +
  84847. + switch (field) {
  84848. + /* Images are in progressive format, not interlaced */
  84849. + case V4L2_FIELD_NONE:
  84850. + case V4L2_FIELD_ANY:
  84851. + deinterlace->enable = false;
  84852. + deinterlace->field_fmt = 0;
  84853. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "Progressive frame.\n");
  84854. + break;
  84855. + case V4L2_FIELD_INTERLACED_TB:
  84856. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84857. + "Enable deinterlace TB.\n");
  84858. + deinterlace->enable = true;
  84859. + deinterlace->field_fmt = IPU_DEINTERLACE_FIELD_TOP;
  84860. + break;
  84861. + case V4L2_FIELD_INTERLACED_BT:
  84862. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84863. + "Enable deinterlace BT.\n");
  84864. + deinterlace->enable = true;
  84865. + deinterlace->field_fmt = IPU_DEINTERLACE_FIELD_BOTTOM;
  84866. + break;
  84867. + default:
  84868. + v4l2_err(vout->vfd->v4l2_dev,
  84869. + "field format:%d not supported yet!\n", field);
  84870. + return -EINVAL;
  84871. + }
  84872. +
  84873. + if (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format) {
  84874. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84875. + "tiled fmt enable deinterlace.\n");
  84876. + deinterlace->enable = true;
  84877. + }
  84878. +
  84879. + if (deinterlace->enable && vdi_rate_double)
  84880. + deinterlace->field_fmt |= IPU_DEINTERLACE_RATE_EN;
  84881. +
  84882. + return 0;
  84883. +}
  84884. +
  84885. +static bool is_pp_bypass(struct mxc_vout_output *vout)
  84886. +{
  84887. + if ((IPU_PIX_FMT_TILED_NV12 == vout->task.input.format) ||
  84888. + (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format))
  84889. + return false;
  84890. + if ((vout->task.input.width == vout->task.output.width) &&
  84891. + (vout->task.input.height == vout->task.output.height) &&
  84892. + (vout->task.input.crop.w == vout->task.output.crop.w) &&
  84893. + (vout->task.input.crop.h == vout->task.output.crop.h) &&
  84894. + (vout->task.output.rotate < IPU_ROTATE_HORIZ_FLIP) &&
  84895. + !vout->task.input.deinterlace.enable) {
  84896. + if (vout->disp_support_csc)
  84897. + return true;
  84898. + else if (!need_csc(vout->task.input.format, vout->disp_fmt))
  84899. + return true;
  84900. + /*
  84901. + * input crop show to full output which can show based on
  84902. + * xres_virtual/yres_virtual
  84903. + */
  84904. + } else if ((vout->task.input.crop.w == vout->task.output.crop.w) &&
  84905. + (vout->task.output.crop.w == vout->task.output.width) &&
  84906. + (vout->task.input.crop.h == vout->task.output.crop.h) &&
  84907. + (vout->task.output.crop.h ==
  84908. + vout->task.output.height) &&
  84909. + (vout->task.output.rotate < IPU_ROTATE_HORIZ_FLIP) &&
  84910. + !vout->task.input.deinterlace.enable) {
  84911. + if (vout->disp_support_csc)
  84912. + return true;
  84913. + else if (!need_csc(vout->task.input.format, vout->disp_fmt))
  84914. + return true;
  84915. + }
  84916. + return false;
  84917. +}
  84918. +
  84919. +static void setup_buf_timer(struct mxc_vout_output *vout,
  84920. + struct videobuf_buffer *vb)
  84921. +{
  84922. + ktime_t expiry_time, now;
  84923. +
  84924. + /* if timestamp is 0, then default to 30fps */
  84925. + if ((vb->ts.tv_sec == 0) && (vb->ts.tv_usec == 0))
  84926. + expiry_time = ktime_add_ns(vout->start_ktime,
  84927. + NSEC_PER_FRAME_30FPS * vout->frame_count);
  84928. + else
  84929. + expiry_time = timeval_to_ktime(vb->ts);
  84930. +
  84931. + now = hrtimer_cb_get_time(&vout->timer);
  84932. + if ((now.tv64 > expiry_time.tv64)) {
  84933. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  84934. + "warning: timer timeout already expired.\n");
  84935. + expiry_time = now;
  84936. + }
  84937. +
  84938. + hrtimer_start(&vout->timer, expiry_time, HRTIMER_MODE_ABS);
  84939. +
  84940. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "timer handler next "
  84941. + "schedule: %lldnsecs\n", expiry_time.tv64);
  84942. +}
  84943. +
  84944. +static int show_buf(struct mxc_vout_output *vout, int idx,
  84945. + struct ipu_pos *ipos)
  84946. +{
  84947. + struct fb_info *fbi = vout->fbi;
  84948. + struct fb_var_screeninfo var;
  84949. + int ret;
  84950. + u32 fb_base = 0;
  84951. +
  84952. + memcpy(&var, &fbi->var, sizeof(var));
  84953. +
  84954. + if (vout->linear_bypass_pp || vout->tiled_bypass_pp) {
  84955. + /*
  84956. + * crack fb base
  84957. + * NOTE: should not do other fb operation during v4l2
  84958. + */
  84959. + console_lock();
  84960. + fb_base = fbi->fix.smem_start;
  84961. + fbi->fix.smem_start = vout->task.output.paddr;
  84962. + fbi->var.yoffset = ipos->y + 1;
  84963. + var.xoffset = ipos->x;
  84964. + var.yoffset = ipos->y;
  84965. + var.vmode |= FB_VMODE_YWRAP;
  84966. + ret = fb_pan_display(fbi, &var);
  84967. + fbi->fix.smem_start = fb_base;
  84968. + console_unlock();
  84969. + } else {
  84970. + console_lock();
  84971. + var.yoffset = idx * fbi->var.yres;
  84972. + var.vmode &= ~FB_VMODE_YWRAP;
  84973. + ret = fb_pan_display(fbi, &var);
  84974. + console_unlock();
  84975. + }
  84976. +
  84977. + return ret;
  84978. +}
  84979. +
  84980. +static void disp_work_func(struct work_struct *work)
  84981. +{
  84982. + struct mxc_vout_output *vout =
  84983. + container_of(work, struct mxc_vout_output, disp_work);
  84984. + struct videobuf_queue *q = &vout->vbq;
  84985. + struct videobuf_buffer *vb, *vb_next = NULL;
  84986. + unsigned long flags = 0;
  84987. + struct ipu_pos ipos;
  84988. + int ret = 0;
  84989. + u32 in_fmt = 0;
  84990. + u32 vdi_cnt = 0;
  84991. + u32 vdi_frame;
  84992. + u32 index = 0;
  84993. + u32 ocrop_h = 0;
  84994. + u32 o_height = 0;
  84995. + u32 tiled_interlaced = 0;
  84996. + bool tiled_fmt = false;
  84997. +
  84998. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "disp work begin one frame\n");
  84999. +
  85000. + spin_lock_irqsave(q->irqlock, flags);
  85001. +
  85002. + if (list_empty(&vout->active_list)) {
  85003. + v4l2_warn(vout->vfd->v4l2_dev,
  85004. + "no entry in active_list, should not be here\n");
  85005. + spin_unlock_irqrestore(q->irqlock, flags);
  85006. + return;
  85007. + }
  85008. +
  85009. + vb = list_first_entry(&vout->active_list,
  85010. + struct videobuf_buffer, queue);
  85011. + ret = set_field_fmt(vout, vb->field);
  85012. + if (ret < 0) {
  85013. + spin_unlock_irqrestore(q->irqlock, flags);
  85014. + return;
  85015. + }
  85016. + if (deinterlace_3_field(vout)) {
  85017. + if (list_is_singular(&vout->active_list)) {
  85018. + if (list_empty(&vout->queue_list)) {
  85019. + vout->timer_stop = true;
  85020. + spin_unlock_irqrestore(q->irqlock, flags);
  85021. + v4l2_warn(vout->vfd->v4l2_dev,
  85022. + "no enough entry for 3 fields "
  85023. + "deinterlacer\n");
  85024. + return;
  85025. + }
  85026. +
  85027. + /*
  85028. + * We need to use the next vb even if it is
  85029. + * not on the active list.
  85030. + */
  85031. + vb_next = list_first_entry(&vout->queue_list,
  85032. + struct videobuf_buffer, queue);
  85033. + } else
  85034. + vb_next = list_first_entry(vout->active_list.next,
  85035. + struct videobuf_buffer, queue);
  85036. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85037. + "cur field_fmt:%d, next field_fmt:%d.\n",
  85038. + vb->field, vb_next->field);
  85039. + /* repeat the last field during field format changing */
  85040. + if ((vb->field != vb_next->field) &&
  85041. + (vb_next->field != V4L2_FIELD_NONE))
  85042. + vb_next = vb;
  85043. + }
  85044. +
  85045. + spin_unlock_irqrestore(q->irqlock, flags);
  85046. +
  85047. +vdi_frame_rate_double:
  85048. + mutex_lock(&vout->task_lock);
  85049. +
  85050. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85051. + "v4l2 frame_cnt:%ld, vb_field:%d, fmt:%d\n",
  85052. + vout->frame_count, vb->field,
  85053. + vout->task.input.deinterlace.field_fmt);
  85054. + if (vb->memory == V4L2_MEMORY_USERPTR)
  85055. + vout->task.input.paddr = vb->baddr;
  85056. + else
  85057. + vout->task.input.paddr = videobuf_to_dma_contig(vb);
  85058. +
  85059. + if (vout->task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN)
  85060. + index = vout->vdi_frame_cnt % FB_BUFS;
  85061. + else
  85062. + index = vout->frame_count % FB_BUFS;
  85063. + if (vout->linear_bypass_pp) {
  85064. + vout->task.output.paddr = vout->task.input.paddr;
  85065. + ipos.x = vout->task.input.crop.pos.x;
  85066. + ipos.y = vout->task.input.crop.pos.y;
  85067. + } else {
  85068. + if (deinterlace_3_field(vout)) {
  85069. + if (vb->memory == V4L2_MEMORY_USERPTR)
  85070. + vout->task.input.paddr_n = vb_next->baddr;
  85071. + else
  85072. + vout->task.input.paddr_n =
  85073. + videobuf_to_dma_contig(vb_next);
  85074. + }
  85075. + vout->task.output.paddr = vout->disp_bufs[index];
  85076. + if (vout->vdoa_1080p) {
  85077. + o_height = vout->task.output.height;
  85078. + ocrop_h = vout->task.output.crop.h;
  85079. + vout->task.output.height = FRAME_HEIGHT_1080P;
  85080. + vout->task.output.crop.h = FRAME_HEIGHT_1080P;
  85081. + }
  85082. + tiled_fmt =
  85083. + (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format) ||
  85084. + (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format);
  85085. + if (vout->tiled_bypass_pp) {
  85086. + ipos.x = vout->task.input.crop.pos.x;
  85087. + ipos.y = vout->task.input.crop.pos.y;
  85088. + } else if (tiled_fmt) {
  85089. + vout->vdoa_task.input.paddr = vout->task.input.paddr;
  85090. + if (deinterlace_3_field(vout))
  85091. + vout->vdoa_task.input.paddr_n =
  85092. + vout->task.input.paddr_n;
  85093. + vout->vdoa_task.output.paddr = vout->vdoa_work.paddr;
  85094. + ret = ipu_queue_task(&vout->vdoa_task);
  85095. + if (ret < 0) {
  85096. + mutex_unlock(&vout->task_lock);
  85097. + goto err;
  85098. + }
  85099. + vout->task.input.paddr = vout->vdoa_task.output.paddr;
  85100. + in_fmt = vout->task.input.format;
  85101. + vout->task.input.format = vout->vdoa_task.output.format;
  85102. + if (vout->task.input.deinterlace.enable) {
  85103. + tiled_interlaced = 1;
  85104. + vout->task.input.deinterlace.enable = 0;
  85105. + }
  85106. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85107. + "tiled queue task\n");
  85108. + }
  85109. + ret = ipu_queue_task(&vout->task);
  85110. + if ((!vout->tiled_bypass_pp) && tiled_fmt)
  85111. + vout->task.input.format = in_fmt;
  85112. + if (tiled_interlaced)
  85113. + vout->task.input.deinterlace.enable = 1;
  85114. + if (ret < 0) {
  85115. + mutex_unlock(&vout->task_lock);
  85116. + goto err;
  85117. + }
  85118. + if (vout->vdoa_1080p) {
  85119. + vout->task.output.crop.h = ocrop_h;
  85120. + vout->task.output.height = o_height;
  85121. + }
  85122. + }
  85123. +
  85124. + mutex_unlock(&vout->task_lock);
  85125. +
  85126. + ret = show_buf(vout, index, &ipos);
  85127. + if (ret < 0)
  85128. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85129. + "show buf with ret %d\n", ret);
  85130. +
  85131. + if (vout->task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN) {
  85132. + vdi_frame = vout->task.input.deinterlace.field_fmt
  85133. + & IPU_DEINTERLACE_RATE_FRAME1;
  85134. + if (vdi_frame)
  85135. + vout->task.input.deinterlace.field_fmt &=
  85136. + ~IPU_DEINTERLACE_RATE_FRAME1;
  85137. + else
  85138. + vout->task.input.deinterlace.field_fmt |=
  85139. + IPU_DEINTERLACE_RATE_FRAME1;
  85140. + vout->vdi_frame_cnt++;
  85141. + vdi_cnt++;
  85142. + if (vdi_cnt < IPU_DEINTERLACE_MAX_FRAME)
  85143. + goto vdi_frame_rate_double;
  85144. + }
  85145. + spin_lock_irqsave(q->irqlock, flags);
  85146. +
  85147. + list_del(&vb->queue);
  85148. +
  85149. + /*
  85150. + * The videobuf before the last one has been shown. Set
  85151. + * VIDEOBUF_DONE state here to avoid tearing issue in ic bypass
  85152. + * case, which makes sure a buffer being shown will not be
  85153. + * dequeued to be overwritten. It also brings side-effect that
  85154. + * the last 2 buffers can not be dequeued correctly, apps need
  85155. + * to take care of it.
  85156. + */
  85157. + if (vout->pre2_vb) {
  85158. + vout->pre2_vb->state = VIDEOBUF_DONE;
  85159. + wake_up_interruptible(&vout->pre2_vb->done);
  85160. + vout->pre2_vb = NULL;
  85161. + }
  85162. +
  85163. + if (vout->linear_bypass_pp) {
  85164. + vout->pre2_vb = vout->pre1_vb;
  85165. + vout->pre1_vb = vb;
  85166. + } else {
  85167. + if (vout->pre1_vb) {
  85168. + vout->pre1_vb->state = VIDEOBUF_DONE;
  85169. + wake_up_interruptible(&vout->pre1_vb->done);
  85170. + vout->pre1_vb = NULL;
  85171. + }
  85172. + vb->state = VIDEOBUF_DONE;
  85173. + wake_up_interruptible(&vb->done);
  85174. + }
  85175. +
  85176. + vout->frame_count++;
  85177. +
  85178. + /* pick next queue buf to setup timer */
  85179. + if (list_empty(&vout->queue_list))
  85180. + vout->timer_stop = true;
  85181. + else {
  85182. + vb = list_first_entry(&vout->queue_list,
  85183. + struct videobuf_buffer, queue);
  85184. + setup_buf_timer(vout, vb);
  85185. + }
  85186. +
  85187. + spin_unlock_irqrestore(q->irqlock, flags);
  85188. +
  85189. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "disp work finish one frame\n");
  85190. +
  85191. + return;
  85192. +err:
  85193. + v4l2_err(vout->vfd->v4l2_dev, "display work fail ret = %d\n", ret);
  85194. + vout->timer_stop = true;
  85195. + vb->state = VIDEOBUF_ERROR;
  85196. + return;
  85197. +}
  85198. +
  85199. +static enum hrtimer_restart mxc_vout_timer_handler(struct hrtimer *timer)
  85200. +{
  85201. + struct mxc_vout_output *vout = container_of(timer,
  85202. + struct mxc_vout_output,
  85203. + timer);
  85204. + struct videobuf_queue *q = &vout->vbq;
  85205. + struct videobuf_buffer *vb;
  85206. + unsigned long flags = 0;
  85207. +
  85208. + spin_lock_irqsave(q->irqlock, flags);
  85209. +
  85210. + /*
  85211. + * put first queued entry into active, if previous entry did not
  85212. + * finish, setup current entry's timer again.
  85213. + */
  85214. + if (list_empty(&vout->queue_list)) {
  85215. + spin_unlock_irqrestore(q->irqlock, flags);
  85216. + return HRTIMER_NORESTART;
  85217. + }
  85218. +
  85219. + /* move videobuf from queued list to active list */
  85220. + vb = list_first_entry(&vout->queue_list,
  85221. + struct videobuf_buffer, queue);
  85222. + list_del(&vb->queue);
  85223. + list_add_tail(&vb->queue, &vout->active_list);
  85224. +
  85225. + if (queue_work(vout->v4l_wq, &vout->disp_work) == 0) {
  85226. + v4l2_warn(vout->vfd->v4l2_dev,
  85227. + "disp work was in queue already, queue buf again next time\n");
  85228. + list_del(&vb->queue);
  85229. + list_add(&vb->queue, &vout->queue_list);
  85230. + spin_unlock_irqrestore(q->irqlock, flags);
  85231. + return HRTIMER_NORESTART;
  85232. + }
  85233. +
  85234. + vb->state = VIDEOBUF_ACTIVE;
  85235. +
  85236. + spin_unlock_irqrestore(q->irqlock, flags);
  85237. +
  85238. + return HRTIMER_NORESTART;
  85239. +}
  85240. +
  85241. +/* Video buffer call backs */
  85242. +
  85243. +/*
  85244. + * Buffer setup function is called by videobuf layer when REQBUF ioctl is
  85245. + * called. This is used to setup buffers and return size and count of
  85246. + * buffers allocated. After the call to this buffer, videobuf layer will
  85247. + * setup buffer queue depending on the size and count of buffers
  85248. + */
  85249. +static int mxc_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
  85250. + unsigned int *size)
  85251. +{
  85252. + struct mxc_vout_output *vout = q->priv_data;
  85253. + unsigned int frame_size;
  85254. +
  85255. + if (!vout)
  85256. + return -EINVAL;
  85257. +
  85258. + if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
  85259. + return -EINVAL;
  85260. +
  85261. + frame_size = get_frame_size(vout);
  85262. + *size = PAGE_ALIGN(frame_size);
  85263. +
  85264. + return 0;
  85265. +}
  85266. +
  85267. +/*
  85268. + * This function will be called when VIDIOC_QBUF ioctl is called.
  85269. + * It prepare buffers before give out for the display. This function
  85270. + * converts user space virtual address into physical address if userptr memory
  85271. + * exchange mechanism is used.
  85272. + */
  85273. +static int mxc_vout_buffer_prepare(struct videobuf_queue *q,
  85274. + struct videobuf_buffer *vb,
  85275. + enum v4l2_field field)
  85276. +{
  85277. + vb->state = VIDEOBUF_PREPARED;
  85278. + return 0;
  85279. +}
  85280. +
  85281. +/*
  85282. + * Buffer queue funtion will be called from the videobuf layer when _QBUF
  85283. + * ioctl is called. It is used to enqueue buffer, which is ready to be
  85284. + * displayed.
  85285. + * This function is protected by q->irqlock.
  85286. + */
  85287. +static void mxc_vout_buffer_queue(struct videobuf_queue *q,
  85288. + struct videobuf_buffer *vb)
  85289. +{
  85290. + struct mxc_vout_output *vout = q->priv_data;
  85291. + struct videobuf_buffer *active_vb;
  85292. +
  85293. + list_add_tail(&vb->queue, &vout->queue_list);
  85294. + vb->state = VIDEOBUF_QUEUED;
  85295. +
  85296. + if (vout->timer_stop) {
  85297. + if (deinterlace_3_field(vout) &&
  85298. + !list_empty(&vout->active_list)) {
  85299. + active_vb = list_first_entry(&vout->active_list,
  85300. + struct videobuf_buffer, queue);
  85301. + setup_buf_timer(vout, active_vb);
  85302. + } else {
  85303. + setup_buf_timer(vout, vb);
  85304. + }
  85305. + vout->timer_stop = false;
  85306. + }
  85307. +}
  85308. +
  85309. +/*
  85310. + * Buffer release function is called from videobuf layer to release buffer
  85311. + * which are already allocated
  85312. + */
  85313. +static void mxc_vout_buffer_release(struct videobuf_queue *q,
  85314. + struct videobuf_buffer *vb)
  85315. +{
  85316. + vb->state = VIDEOBUF_NEEDS_INIT;
  85317. +}
  85318. +
  85319. +static int mxc_vout_mmap(struct file *file, struct vm_area_struct *vma)
  85320. +{
  85321. + int ret;
  85322. + struct mxc_vout_output *vout = file->private_data;
  85323. +
  85324. + if (!vout)
  85325. + return -ENODEV;
  85326. +
  85327. + ret = videobuf_mmap_mapper(&vout->vbq, vma);
  85328. + if (ret < 0)
  85329. + v4l2_err(vout->vfd->v4l2_dev,
  85330. + "offset invalid [offset=0x%lx]\n",
  85331. + (vma->vm_pgoff << PAGE_SHIFT));
  85332. +
  85333. + return ret;
  85334. +}
  85335. +
  85336. +static int mxc_vout_release(struct file *file)
  85337. +{
  85338. + unsigned int ret = 0;
  85339. + struct videobuf_queue *q;
  85340. + struct mxc_vout_output *vout = file->private_data;
  85341. +
  85342. + if (!vout)
  85343. + return 0;
  85344. +
  85345. + if (--vout->open_cnt == 0) {
  85346. + q = &vout->vbq;
  85347. + if (q->streaming)
  85348. + mxc_vidioc_streamoff(file, vout, vout->type);
  85349. + else {
  85350. + release_disp_output(vout);
  85351. + videobuf_queue_cancel(q);
  85352. + }
  85353. + destroy_workqueue(vout->v4l_wq);
  85354. + ret = videobuf_mmap_free(q);
  85355. + }
  85356. +
  85357. + return ret;
  85358. +}
  85359. +
  85360. +static int mxc_vout_open(struct file *file)
  85361. +{
  85362. + struct mxc_vout_output *vout = NULL;
  85363. + int ret = 0;
  85364. +
  85365. + vout = video_drvdata(file);
  85366. +
  85367. + if (vout == NULL)
  85368. + return -ENODEV;
  85369. +
  85370. + if (vout->open_cnt++ == 0) {
  85371. + vout->ctrl_rotate = 0;
  85372. + vout->ctrl_vflip = 0;
  85373. + vout->ctrl_hflip = 0;
  85374. + update_display_setting();
  85375. + ret = update_setting_from_fbi(vout, vout->fbi);
  85376. + if (ret < 0)
  85377. + goto err;
  85378. +
  85379. + vout->v4l_wq = create_singlethread_workqueue("v4l2q");
  85380. + if (!vout->v4l_wq) {
  85381. + v4l2_err(vout->vfd->v4l2_dev,
  85382. + "Could not create work queue\n");
  85383. + ret = -ENOMEM;
  85384. + goto err;
  85385. + }
  85386. +
  85387. + INIT_WORK(&vout->disp_work, disp_work_func);
  85388. +
  85389. + INIT_LIST_HEAD(&vout->queue_list);
  85390. + INIT_LIST_HEAD(&vout->active_list);
  85391. +
  85392. + vout->fmt_init = false;
  85393. + vout->frame_count = 0;
  85394. + vout->vdi_frame_cnt = 0;
  85395. +
  85396. + vout->win_pos.x = 0;
  85397. + vout->win_pos.y = 0;
  85398. + vout->release = true;
  85399. + }
  85400. +
  85401. + file->private_data = vout;
  85402. +
  85403. +err:
  85404. + return ret;
  85405. +}
  85406. +
  85407. +/*
  85408. + * V4L2 ioctls
  85409. + */
  85410. +static int mxc_vidioc_querycap(struct file *file, void *fh,
  85411. + struct v4l2_capability *cap)
  85412. +{
  85413. + struct mxc_vout_output *vout = fh;
  85414. +
  85415. + strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
  85416. + strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
  85417. + cap->bus_info[0] = '\0';
  85418. + cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT;
  85419. +
  85420. + return 0;
  85421. +}
  85422. +
  85423. +static int mxc_vidioc_enum_fmt_vid_out(struct file *file, void *fh,
  85424. + struct v4l2_fmtdesc *fmt)
  85425. +{
  85426. + if (fmt->index >= NUM_MXC_VOUT_FORMATS)
  85427. + return -EINVAL;
  85428. +
  85429. + strlcpy(fmt->description, mxc_formats[fmt->index].description,
  85430. + sizeof(fmt->description));
  85431. + fmt->pixelformat = mxc_formats[fmt->index].pixelformat;
  85432. +
  85433. + return 0;
  85434. +}
  85435. +
  85436. +static int mxc_vidioc_g_fmt_vid_out(struct file *file, void *fh,
  85437. + struct v4l2_format *f)
  85438. +{
  85439. + struct mxc_vout_output *vout = fh;
  85440. + struct v4l2_rect rect;
  85441. +
  85442. + f->fmt.pix.width = vout->task.input.width;
  85443. + f->fmt.pix.height = vout->task.input.height;
  85444. + f->fmt.pix.pixelformat = vout->task.input.format;
  85445. + f->fmt.pix.sizeimage = get_frame_size(vout);
  85446. +
  85447. + if (f->fmt.pix.priv) {
  85448. + rect.left = vout->task.input.crop.pos.x;
  85449. + rect.top = vout->task.input.crop.pos.y;
  85450. + rect.width = vout->task.input.crop.w;
  85451. + rect.height = vout->task.input.crop.h;
  85452. + if (copy_to_user((void __user *)f->fmt.pix.priv,
  85453. + &rect, sizeof(rect)))
  85454. + return -EFAULT;
  85455. + }
  85456. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85457. + "frame_size:0x%x, pix_fmt:0x%x\n",
  85458. + f->fmt.pix.sizeimage,
  85459. + vout->task.input.format);
  85460. +
  85461. + return 0;
  85462. +}
  85463. +
  85464. +static inline int ipu_try_task(struct mxc_vout_output *vout)
  85465. +{
  85466. + int ret;
  85467. + struct ipu_task *task = &vout->task;
  85468. +
  85469. +again:
  85470. + ret = ipu_check_task(task);
  85471. + if (ret != IPU_CHECK_OK) {
  85472. + if (ret > IPU_CHECK_ERR_MIN) {
  85473. + if (ret == IPU_CHECK_ERR_SPLIT_INPUTW_OVER ||
  85474. + ret == IPU_CHECK_ERR_W_DOWNSIZE_OVER) {
  85475. + task->input.crop.w -= 8;
  85476. + goto again;
  85477. + }
  85478. + if (ret == IPU_CHECK_ERR_SPLIT_INPUTH_OVER ||
  85479. + ret == IPU_CHECK_ERR_H_DOWNSIZE_OVER) {
  85480. + task->input.crop.h -= 8;
  85481. + goto again;
  85482. + }
  85483. + if (ret == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
  85484. + if (vout->disp_support_windows) {
  85485. + task->output.width -= 8;
  85486. + task->output.crop.w =
  85487. + task->output.width;
  85488. + } else
  85489. + task->output.crop.w -= 8;
  85490. + goto again;
  85491. + }
  85492. + if (ret == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
  85493. + if (vout->disp_support_windows) {
  85494. + task->output.height -= 8;
  85495. + task->output.crop.h =
  85496. + task->output.height;
  85497. + } else
  85498. + task->output.crop.h -= 8;
  85499. + goto again;
  85500. + }
  85501. + ret = -EINVAL;
  85502. + }
  85503. + } else
  85504. + ret = 0;
  85505. +
  85506. + return ret;
  85507. +}
  85508. +
  85509. +static inline int vdoaipu_try_task(struct mxc_vout_output *vout)
  85510. +{
  85511. + int ret;
  85512. + int is_1080p_stream;
  85513. + size_t size;
  85514. + struct ipu_task *ipu_task = &vout->task;
  85515. + struct ipu_crop *icrop = &ipu_task->input.crop;
  85516. + struct ipu_task *vdoa_task = &vout->vdoa_task;
  85517. + u32 deinterlace = 0;
  85518. + u32 in_fmt;
  85519. +
  85520. + if (vout->task.input.deinterlace.enable)
  85521. + deinterlace = 1;
  85522. +
  85523. + memset(vdoa_task, 0, sizeof(*vdoa_task));
  85524. + vdoa_task->output.format = IPU_PIX_FMT_NV12;
  85525. + memcpy(&vdoa_task->input, &ipu_task->input,
  85526. + sizeof(ipu_task->input));
  85527. + if ((icrop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  85528. + (icrop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
  85529. + vdoa_task->input.crop.w =
  85530. + ALIGN(icrop->w, IPU_PIX_FMT_TILED_NV12_MBALIGN);
  85531. + vdoa_task->input.crop.h =
  85532. + ALIGN(icrop->h, IPU_PIX_FMT_TILED_NV12_MBALIGN);
  85533. + }
  85534. + vdoa_task->output.width = vdoa_task->input.crop.w;
  85535. + vdoa_task->output.height = vdoa_task->input.crop.h;
  85536. + vdoa_task->output.crop.w = vdoa_task->input.crop.w;
  85537. + vdoa_task->output.crop.h = vdoa_task->input.crop.h;
  85538. +
  85539. + size = PAGE_ALIGN(vdoa_task->input.crop.w *
  85540. + vdoa_task->input.crop.h *
  85541. + fmt_to_bpp(vdoa_task->output.format)/8);
  85542. + if (size > vout->vdoa_work.size) {
  85543. + if (vout->vdoa_work.vaddr)
  85544. + free_dma_buf(vout, &vout->vdoa_work);
  85545. + vout->vdoa_work.size = size;
  85546. + ret = alloc_dma_buf(vout, &vout->vdoa_work);
  85547. + if (ret < 0)
  85548. + return ret;
  85549. + }
  85550. + ret = ipu_check_task(vdoa_task);
  85551. + if (ret != IPU_CHECK_OK)
  85552. + return -EINVAL;
  85553. +
  85554. + is_1080p_stream = CHECK_TILED_1080P_STREAM(vout);
  85555. + if (is_1080p_stream)
  85556. + ipu_task->input.crop.h = VALID_HEIGHT_1080P;
  85557. + in_fmt = ipu_task->input.format;
  85558. + ipu_task->input.format = vdoa_task->output.format;
  85559. + ipu_task->input.height = vdoa_task->output.height;
  85560. + ipu_task->input.width = vdoa_task->output.width;
  85561. + if (deinterlace)
  85562. + ipu_task->input.deinterlace.enable = 0;
  85563. + ret = ipu_try_task(vout);
  85564. + if (deinterlace)
  85565. + ipu_task->input.deinterlace.enable = 1;
  85566. + ipu_task->input.format = in_fmt;
  85567. +
  85568. + return ret;
  85569. +}
  85570. +
  85571. +static int mxc_vout_try_task(struct mxc_vout_output *vout)
  85572. +{
  85573. + int ret = 0;
  85574. + struct ipu_output *output = &vout->task.output;
  85575. + struct ipu_input *input = &vout->task.input;
  85576. + struct ipu_crop *crop = &input->crop;
  85577. + u32 o_height = 0;
  85578. + u32 ocrop_h = 0;
  85579. + bool tiled_fmt = false;
  85580. + bool tiled_need_pp = false;
  85581. +
  85582. + vout->vdoa_1080p = CHECK_TILED_1080P_DISPLAY(vout);
  85583. + if (vout->vdoa_1080p) {
  85584. + input->crop.h = FRAME_HEIGHT_1080P;
  85585. + o_height = output->height;
  85586. + ocrop_h = output->crop.h;
  85587. + output->height = FRAME_HEIGHT_1080P;
  85588. + output->crop.h = FRAME_HEIGHT_1080P;
  85589. + }
  85590. +
  85591. + if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
  85592. + (IPU_PIX_FMT_TILED_NV12F == input->format)) {
  85593. + if ((input->width % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  85594. + (input->height % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  85595. + (crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  85596. + (crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
  85597. + v4l2_err(vout->vfd->v4l2_dev,
  85598. + "ERR: tiled fmt needs 16 pixel align.\n");
  85599. + return -EINVAL;
  85600. + }
  85601. + if ((crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  85602. + (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  85603. + tiled_need_pp = true;
  85604. + } else {
  85605. + crop->w -= crop->w % 8;
  85606. + crop->h -= crop->h % 8;
  85607. + }
  85608. + /* assume task.output already set by S_CROP */
  85609. + vout->linear_bypass_pp = is_pp_bypass(vout);
  85610. + if (vout->linear_bypass_pp) {
  85611. + v4l2_info(vout->vfd->v4l2_dev, "Bypass IC.\n");
  85612. + output->format = input->format;
  85613. + } else {
  85614. + /* if need CSC, choose IPU-DP or IPU_IC do it */
  85615. + if (vout->disp_support_csc) {
  85616. + if (colorspaceofpixel(input->format) == YUV_CS)
  85617. + output->format = IPU_PIX_FMT_UYVY;
  85618. + else
  85619. + output->format = IPU_PIX_FMT_RGB565;
  85620. + } else {
  85621. + if (colorspaceofpixel(vout->disp_fmt) == YUV_CS)
  85622. + output->format = IPU_PIX_FMT_UYVY;
  85623. + else
  85624. + output->format = IPU_PIX_FMT_RGB565;
  85625. + }
  85626. +
  85627. + vout->tiled_bypass_pp = false;
  85628. + if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
  85629. + (IPU_PIX_FMT_TILED_NV12F == input->format)) {
  85630. + /* check resize/rotate/flip, or csc task */
  85631. + if (!(tiled_need_pp ||
  85632. + (IPU_ROTATE_NONE != output->rotate) ||
  85633. + (input->crop.w != output->crop.w) ||
  85634. + (input->crop.h != output->crop.h) ||
  85635. + (!vout->disp_support_csc &&
  85636. + (colorspaceofpixel(vout->disp_fmt) == RGB_CS)))
  85637. + ) {
  85638. + /* IC bypass */
  85639. + output->format = IPU_PIX_FMT_NV12;
  85640. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85641. + "tiled bypass pp\n");
  85642. + vout->tiled_bypass_pp = true;
  85643. + }
  85644. + tiled_fmt = true;
  85645. + }
  85646. +
  85647. + if ((!vout->tiled_bypass_pp) && tiled_fmt)
  85648. + ret = vdoaipu_try_task(vout);
  85649. + else
  85650. + ret = ipu_try_task(vout);
  85651. + }
  85652. +
  85653. + if (vout->vdoa_1080p) {
  85654. + output->height = o_height;
  85655. + output->crop.h = ocrop_h;
  85656. + }
  85657. +
  85658. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  85659. + "icrop.w:%u, icrop.h:%u, iw:%u, ih:%u,"
  85660. + "ocrop.w:%u, ocrop.h:%u, ow:%u, oh:%u\n",
  85661. + input->crop.w, input->crop.h,
  85662. + input->width, input->height,
  85663. + output->crop.w, output->crop.h,
  85664. + output->width, output->height);
  85665. + return ret;
  85666. +}
  85667. +
  85668. +static int mxc_vout_try_format(struct mxc_vout_output *vout,
  85669. + struct v4l2_format *f)
  85670. +{
  85671. + int ret = 0;
  85672. + struct v4l2_rect rect;
  85673. +
  85674. + if ((f->fmt.pix.field != V4L2_FIELD_NONE) &&
  85675. + (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format)) {
  85676. + v4l2_err(vout->vfd->v4l2_dev,
  85677. + "progressive tiled fmt should used V4L2_FIELD_NONE!\n");
  85678. + return -EINVAL;
  85679. + }
  85680. +
  85681. + if (f->fmt.pix.priv && copy_from_user(&rect,
  85682. + (void __user *)f->fmt.pix.priv, sizeof(rect)))
  85683. + return -EFAULT;
  85684. +
  85685. + vout->task.input.width = f->fmt.pix.width;
  85686. + vout->task.input.height = f->fmt.pix.height;
  85687. + vout->task.input.format = f->fmt.pix.pixelformat;
  85688. +
  85689. + ret = set_field_fmt(vout, f->fmt.pix.field);
  85690. + if (ret < 0)
  85691. + return ret;
  85692. +
  85693. + if (f->fmt.pix.priv) {
  85694. + vout->task.input.crop.pos.x = rect.left;
  85695. + vout->task.input.crop.pos.y = rect.top;
  85696. + vout->task.input.crop.w = rect.width;
  85697. + vout->task.input.crop.h = rect.height;
  85698. + } else {
  85699. + vout->task.input.crop.pos.x = 0;
  85700. + vout->task.input.crop.pos.y = 0;
  85701. + vout->task.input.crop.w = f->fmt.pix.width;
  85702. + vout->task.input.crop.h = f->fmt.pix.height;
  85703. + }
  85704. + memcpy(&vout->in_rect, &vout->task.input.crop, sizeof(vout->in_rect));
  85705. +
  85706. + ret = mxc_vout_try_task(vout);
  85707. + if (!ret) {
  85708. + if (f->fmt.pix.priv) {
  85709. + rect.width = vout->task.input.crop.w;
  85710. + rect.height = vout->task.input.crop.h;
  85711. + if (copy_to_user((void __user *)f->fmt.pix.priv,
  85712. + &rect, sizeof(rect)))
  85713. + ret = -EFAULT;
  85714. + } else {
  85715. + f->fmt.pix.width = vout->task.input.crop.w;
  85716. + f->fmt.pix.height = vout->task.input.crop.h;
  85717. + }
  85718. + }
  85719. +
  85720. + return ret;
  85721. +}
  85722. +
  85723. +static bool mxc_vout_need_fb_reconfig(struct mxc_vout_output *vout,
  85724. + struct mxc_vout_output *pre_vout)
  85725. +{
  85726. + if (!vout->vbq.streaming)
  85727. + return false;
  85728. +
  85729. + if (vout->tiled_bypass_pp)
  85730. + return true;
  85731. +
  85732. + if (vout->linear_bypass_pp != pre_vout->linear_bypass_pp)
  85733. + return true;
  85734. +
  85735. + /* cropped output resolution or format are changed */
  85736. + if (vout->task.output.format != pre_vout->task.output.format ||
  85737. + vout->task.output.crop.w != pre_vout->task.output.crop.w ||
  85738. + vout->task.output.crop.h != pre_vout->task.output.crop.h)
  85739. + return true;
  85740. +
  85741. + /* overlay: window position or resolution are changed */
  85742. + if (vout->disp_support_windows &&
  85743. + (vout->win_pos.x != pre_vout->win_pos.x ||
  85744. + vout->win_pos.y != pre_vout->win_pos.y ||
  85745. + vout->task.output.width != pre_vout->task.output.width ||
  85746. + vout->task.output.height != pre_vout->task.output.height))
  85747. + return true;
  85748. +
  85749. + /* background: cropped position is changed */
  85750. + if (!vout->disp_support_windows &&
  85751. + (vout->task.output.crop.pos.x !=
  85752. + pre_vout->task.output.crop.pos.x ||
  85753. + vout->task.output.crop.pos.y !=
  85754. + pre_vout->task.output.crop.pos.y))
  85755. + return true;
  85756. +
  85757. + return false;
  85758. +}
  85759. +
  85760. +static int mxc_vidioc_s_fmt_vid_out(struct file *file, void *fh,
  85761. + struct v4l2_format *f)
  85762. +{
  85763. + struct mxc_vout_output *vout = fh;
  85764. + int ret = 0;
  85765. +
  85766. + if (vout->vbq.streaming)
  85767. + return -EBUSY;
  85768. +
  85769. + mutex_lock(&vout->task_lock);
  85770. + ret = mxc_vout_try_format(vout, f);
  85771. + if (ret >= 0)
  85772. + vout->fmt_init = true;
  85773. + mutex_unlock(&vout->task_lock);
  85774. +
  85775. + return ret;
  85776. +}
  85777. +
  85778. +static int mxc_vidioc_cropcap(struct file *file, void *fh,
  85779. + struct v4l2_cropcap *cropcap)
  85780. +{
  85781. + struct mxc_vout_output *vout = fh;
  85782. +
  85783. + if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  85784. + return -EINVAL;
  85785. +
  85786. + cropcap->bounds = vout->crop_bounds;
  85787. + cropcap->defrect = vout->crop_bounds;
  85788. +
  85789. + return 0;
  85790. +}
  85791. +
  85792. +static int mxc_vidioc_g_crop(struct file *file, void *fh,
  85793. + struct v4l2_crop *crop)
  85794. +{
  85795. + struct mxc_vout_output *vout = fh;
  85796. +
  85797. + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  85798. + return -EINVAL;
  85799. +
  85800. + if (vout->disp_support_windows) {
  85801. + crop->c.left = vout->win_pos.x;
  85802. + crop->c.top = vout->win_pos.y;
  85803. + crop->c.width = vout->task.output.width;
  85804. + crop->c.height = vout->task.output.height;
  85805. + } else {
  85806. + if (vout->task.output.crop.w && vout->task.output.crop.h) {
  85807. + crop->c.left = vout->task.output.crop.pos.x;
  85808. + crop->c.top = vout->task.output.crop.pos.y;
  85809. + crop->c.width = vout->task.output.crop.w;
  85810. + crop->c.height = vout->task.output.crop.h;
  85811. + } else {
  85812. + crop->c.left = 0;
  85813. + crop->c.top = 0;
  85814. + crop->c.width = vout->task.output.width;
  85815. + crop->c.height = vout->task.output.height;
  85816. + }
  85817. + }
  85818. +
  85819. + return 0;
  85820. +}
  85821. +
  85822. +static int mxc_vidioc_s_crop(struct file *file, void *fh,
  85823. + const struct v4l2_crop *crop)
  85824. +{
  85825. + struct mxc_vout_output *vout = fh, *pre_vout;
  85826. + struct v4l2_rect *b = &vout->crop_bounds;
  85827. + struct v4l2_crop fix_up_crop;
  85828. + int ret = 0;
  85829. +
  85830. + memcpy(&fix_up_crop, crop, sizeof(*crop));
  85831. +
  85832. + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  85833. + return -EINVAL;
  85834. +
  85835. + if (crop->c.width < 0 || crop->c.height < 0)
  85836. + return -EINVAL;
  85837. +
  85838. + if (crop->c.width == 0)
  85839. + fix_up_crop.c.width = b->width - b->left;
  85840. + if (crop->c.height == 0)
  85841. + fix_up_crop.c.height = b->height - b->top;
  85842. +
  85843. + if (crop->c.top < b->top)
  85844. + fix_up_crop.c.top = b->top;
  85845. + if (crop->c.top >= b->top + b->height)
  85846. + fix_up_crop.c.top = b->top + b->height - 1;
  85847. + if (crop->c.height > b->top - crop->c.top + b->height)
  85848. + fix_up_crop.c.height =
  85849. + b->top - fix_up_crop.c.top + b->height;
  85850. +
  85851. + if (crop->c.left < b->left)
  85852. + fix_up_crop.c.left = b->left;
  85853. + if (crop->c.left >= b->left + b->width)
  85854. + fix_up_crop.c.left = b->left + b->width - 1;
  85855. + if (crop->c.width > b->left - crop->c.left + b->width)
  85856. + fix_up_crop.c.width =
  85857. + b->left - fix_up_crop.c.left + b->width;
  85858. +
  85859. + /* stride line limitation */
  85860. + fix_up_crop.c.height -= fix_up_crop.c.height % 8;
  85861. + fix_up_crop.c.width -= fix_up_crop.c.width % 8;
  85862. + if ((fix_up_crop.c.width <= 0) || (fix_up_crop.c.height <= 0) ||
  85863. + ((fix_up_crop.c.left + fix_up_crop.c.width) >
  85864. + (b->left + b->width)) ||
  85865. + ((fix_up_crop.c.top + fix_up_crop.c.height) >
  85866. + (b->top + b->height))) {
  85867. + v4l2_err(vout->vfd->v4l2_dev, "s_crop err: %d, %d, %d, %d",
  85868. + fix_up_crop.c.left, fix_up_crop.c.top,
  85869. + fix_up_crop.c.width, fix_up_crop.c.height);
  85870. + return -EINVAL;
  85871. + }
  85872. +
  85873. + /* the same setting, return */
  85874. + if (vout->disp_support_windows) {
  85875. + if ((vout->win_pos.x == fix_up_crop.c.left) &&
  85876. + (vout->win_pos.y == fix_up_crop.c.top) &&
  85877. + (vout->task.output.crop.w == fix_up_crop.c.width) &&
  85878. + (vout->task.output.crop.h == fix_up_crop.c.height))
  85879. + return 0;
  85880. + } else {
  85881. + if ((vout->task.output.crop.pos.x == fix_up_crop.c.left) &&
  85882. + (vout->task.output.crop.pos.y == fix_up_crop.c.top) &&
  85883. + (vout->task.output.crop.w == fix_up_crop.c.width) &&
  85884. + (vout->task.output.crop.h == fix_up_crop.c.height))
  85885. + return 0;
  85886. + }
  85887. +
  85888. + pre_vout = vmalloc(sizeof(*pre_vout));
  85889. + if (!pre_vout)
  85890. + return -ENOMEM;
  85891. +
  85892. + /* wait current work finish */
  85893. + if (vout->vbq.streaming)
  85894. + flush_workqueue(vout->v4l_wq);
  85895. +
  85896. + mutex_lock(&vout->task_lock);
  85897. +
  85898. + memcpy(pre_vout, vout, sizeof(*vout));
  85899. +
  85900. + if (vout->disp_support_windows) {
  85901. + vout->task.output.crop.pos.x = 0;
  85902. + vout->task.output.crop.pos.y = 0;
  85903. + vout->win_pos.x = fix_up_crop.c.left;
  85904. + vout->win_pos.y = fix_up_crop.c.top;
  85905. + vout->task.output.width = fix_up_crop.c.width;
  85906. + vout->task.output.height = fix_up_crop.c.height;
  85907. + } else {
  85908. + vout->task.output.crop.pos.x = fix_up_crop.c.left;
  85909. + vout->task.output.crop.pos.y = fix_up_crop.c.top;
  85910. + }
  85911. +
  85912. + vout->task.output.crop.w = fix_up_crop.c.width;
  85913. + vout->task.output.crop.h = fix_up_crop.c.height;
  85914. +
  85915. + /*
  85916. + * must S_CROP before S_FMT, for fist time S_CROP, will not check
  85917. + * ipu task, it will check in S_FMT, after S_FMT, S_CROP should
  85918. + * check ipu task too.
  85919. + */
  85920. + if (vout->fmt_init) {
  85921. + memcpy(&vout->task.input.crop, &vout->in_rect,
  85922. + sizeof(vout->in_rect));
  85923. + ret = mxc_vout_try_task(vout);
  85924. + if (ret < 0) {
  85925. + v4l2_err(vout->vfd->v4l2_dev,
  85926. + "vout check task failed\n");
  85927. + memcpy(vout, pre_vout, sizeof(*vout));
  85928. + goto done;
  85929. + }
  85930. +
  85931. + if (mxc_vout_need_fb_reconfig(vout, pre_vout)) {
  85932. + ret = config_disp_output(vout);
  85933. + if (ret < 0)
  85934. + v4l2_err(vout->vfd->v4l2_dev,
  85935. + "Config display output failed\n");
  85936. + }
  85937. + }
  85938. +
  85939. +done:
  85940. + vfree(pre_vout);
  85941. + mutex_unlock(&vout->task_lock);
  85942. +
  85943. + return ret;
  85944. +}
  85945. +
  85946. +static int mxc_vidioc_queryctrl(struct file *file, void *fh,
  85947. + struct v4l2_queryctrl *ctrl)
  85948. +{
  85949. + int ret = 0;
  85950. +
  85951. + switch (ctrl->id) {
  85952. + case V4L2_CID_ROTATE:
  85953. + ret = v4l2_ctrl_query_fill(ctrl, 0, 270, 90, 0);
  85954. + break;
  85955. + case V4L2_CID_VFLIP:
  85956. + ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
  85957. + break;
  85958. + case V4L2_CID_HFLIP:
  85959. + ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
  85960. + break;
  85961. + case V4L2_CID_MXC_MOTION:
  85962. + ret = v4l2_ctrl_query_fill(ctrl, 0, 2, 1, 0);
  85963. + break;
  85964. + default:
  85965. + ctrl->name[0] = '\0';
  85966. + ret = -EINVAL;
  85967. + }
  85968. + return ret;
  85969. +}
  85970. +
  85971. +static int mxc_vidioc_g_ctrl(struct file *file, void *fh,
  85972. + struct v4l2_control *ctrl)
  85973. +{
  85974. + int ret = 0;
  85975. + struct mxc_vout_output *vout = fh;
  85976. +
  85977. + switch (ctrl->id) {
  85978. + case V4L2_CID_ROTATE:
  85979. + ctrl->value = vout->ctrl_rotate;
  85980. + break;
  85981. + case V4L2_CID_VFLIP:
  85982. + ctrl->value = vout->ctrl_vflip;
  85983. + break;
  85984. + case V4L2_CID_HFLIP:
  85985. + ctrl->value = vout->ctrl_hflip;
  85986. + break;
  85987. + case V4L2_CID_MXC_MOTION:
  85988. + if (vout->task.input.deinterlace.enable)
  85989. + ctrl->value = vout->task.input.deinterlace.motion;
  85990. + else
  85991. + ctrl->value = 0;
  85992. + break;
  85993. + default:
  85994. + ret = -EINVAL;
  85995. + }
  85996. + return ret;
  85997. +}
  85998. +
  85999. +static void setup_task_rotation(struct mxc_vout_output *vout)
  86000. +{
  86001. + if (vout->ctrl_rotate == 0) {
  86002. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  86003. + vout->task.output.rotate = IPU_ROTATE_180;
  86004. + else if (vout->ctrl_vflip)
  86005. + vout->task.output.rotate = IPU_ROTATE_VERT_FLIP;
  86006. + else if (vout->ctrl_hflip)
  86007. + vout->task.output.rotate = IPU_ROTATE_HORIZ_FLIP;
  86008. + else
  86009. + vout->task.output.rotate = IPU_ROTATE_NONE;
  86010. + } else if (vout->ctrl_rotate == 90) {
  86011. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  86012. + vout->task.output.rotate = IPU_ROTATE_90_LEFT;
  86013. + else if (vout->ctrl_vflip)
  86014. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_VFLIP;
  86015. + else if (vout->ctrl_hflip)
  86016. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_HFLIP;
  86017. + else
  86018. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT;
  86019. + } else if (vout->ctrl_rotate == 180) {
  86020. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  86021. + vout->task.output.rotate = IPU_ROTATE_NONE;
  86022. + else if (vout->ctrl_vflip)
  86023. + vout->task.output.rotate = IPU_ROTATE_HORIZ_FLIP;
  86024. + else if (vout->ctrl_hflip)
  86025. + vout->task.output.rotate = IPU_ROTATE_VERT_FLIP;
  86026. + else
  86027. + vout->task.output.rotate = IPU_ROTATE_180;
  86028. + } else if (vout->ctrl_rotate == 270) {
  86029. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  86030. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT;
  86031. + else if (vout->ctrl_vflip)
  86032. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_HFLIP;
  86033. + else if (vout->ctrl_hflip)
  86034. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_VFLIP;
  86035. + else
  86036. + vout->task.output.rotate = IPU_ROTATE_90_LEFT;
  86037. + }
  86038. +}
  86039. +
  86040. +static int mxc_vidioc_s_ctrl(struct file *file, void *fh,
  86041. + struct v4l2_control *ctrl)
  86042. +{
  86043. + int ret = 0;
  86044. + struct mxc_vout_output *vout = fh, *pre_vout;
  86045. +
  86046. + pre_vout = vmalloc(sizeof(*pre_vout));
  86047. + if (!pre_vout)
  86048. + return -ENOMEM;
  86049. +
  86050. + /* wait current work finish */
  86051. + if (vout->vbq.streaming)
  86052. + flush_workqueue(vout->v4l_wq);
  86053. +
  86054. + mutex_lock(&vout->task_lock);
  86055. +
  86056. + memcpy(pre_vout, vout, sizeof(*vout));
  86057. +
  86058. + switch (ctrl->id) {
  86059. + case V4L2_CID_ROTATE:
  86060. + {
  86061. + vout->ctrl_rotate = (ctrl->value/90) * 90;
  86062. + if (vout->ctrl_rotate > 270)
  86063. + vout->ctrl_rotate = 270;
  86064. + setup_task_rotation(vout);
  86065. + break;
  86066. + }
  86067. + case V4L2_CID_VFLIP:
  86068. + {
  86069. + vout->ctrl_vflip = ctrl->value;
  86070. + setup_task_rotation(vout);
  86071. + break;
  86072. + }
  86073. + case V4L2_CID_HFLIP:
  86074. + {
  86075. + vout->ctrl_hflip = ctrl->value;
  86076. + setup_task_rotation(vout);
  86077. + break;
  86078. + }
  86079. + case V4L2_CID_MXC_MOTION:
  86080. + {
  86081. + vout->task.input.deinterlace.motion = ctrl->value;
  86082. + break;
  86083. + }
  86084. + default:
  86085. + ret = -EINVAL;
  86086. + goto done;
  86087. + }
  86088. +
  86089. + if (vout->fmt_init) {
  86090. + memcpy(&vout->task.input.crop, &vout->in_rect,
  86091. + sizeof(vout->in_rect));
  86092. + ret = mxc_vout_try_task(vout);
  86093. + if (ret < 0) {
  86094. + v4l2_err(vout->vfd->v4l2_dev,
  86095. + "vout check task failed\n");
  86096. + memcpy(vout, pre_vout, sizeof(*vout));
  86097. + goto done;
  86098. + }
  86099. +
  86100. + if (mxc_vout_need_fb_reconfig(vout, pre_vout)) {
  86101. + ret = config_disp_output(vout);
  86102. + if (ret < 0)
  86103. + v4l2_err(vout->vfd->v4l2_dev,
  86104. + "Config display output failed\n");
  86105. + }
  86106. + }
  86107. +
  86108. +done:
  86109. + vfree(pre_vout);
  86110. + mutex_unlock(&vout->task_lock);
  86111. +
  86112. + return ret;
  86113. +}
  86114. +
  86115. +static int mxc_vidioc_reqbufs(struct file *file, void *fh,
  86116. + struct v4l2_requestbuffers *req)
  86117. +{
  86118. + int ret = 0;
  86119. + struct mxc_vout_output *vout = fh;
  86120. + struct videobuf_queue *q = &vout->vbq;
  86121. +
  86122. + if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  86123. + return -EINVAL;
  86124. +
  86125. + /* should not be here after streaming, videobuf_reqbufs will control */
  86126. + mutex_lock(&vout->task_lock);
  86127. +
  86128. + ret = videobuf_reqbufs(q, req);
  86129. +
  86130. + mutex_unlock(&vout->task_lock);
  86131. + return ret;
  86132. +}
  86133. +
  86134. +static int mxc_vidioc_querybuf(struct file *file, void *fh,
  86135. + struct v4l2_buffer *b)
  86136. +{
  86137. + int ret;
  86138. + struct mxc_vout_output *vout = fh;
  86139. +
  86140. + ret = videobuf_querybuf(&vout->vbq, b);
  86141. + if (!ret) {
  86142. + /* return physical address */
  86143. + struct videobuf_buffer *vb = vout->vbq.bufs[b->index];
  86144. + if (b->flags & V4L2_BUF_FLAG_MAPPED)
  86145. + b->m.offset = videobuf_to_dma_contig(vb);
  86146. + }
  86147. +
  86148. + return ret;
  86149. +}
  86150. +
  86151. +static int mxc_vidioc_qbuf(struct file *file, void *fh,
  86152. + struct v4l2_buffer *buffer)
  86153. +{
  86154. + struct mxc_vout_output *vout = fh;
  86155. +
  86156. + return videobuf_qbuf(&vout->vbq, buffer);
  86157. +}
  86158. +
  86159. +static int mxc_vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
  86160. +{
  86161. + struct mxc_vout_output *vout = fh;
  86162. +
  86163. + if (!vout->vbq.streaming)
  86164. + return -EINVAL;
  86165. +
  86166. + if (file->f_flags & O_NONBLOCK)
  86167. + return videobuf_dqbuf(&vout->vbq, (struct v4l2_buffer *)b, 1);
  86168. + else
  86169. + return videobuf_dqbuf(&vout->vbq, (struct v4l2_buffer *)b, 0);
  86170. +}
  86171. +
  86172. +static int set_window_position(struct mxc_vout_output *vout,
  86173. + struct mxcfb_pos *pos)
  86174. +{
  86175. + struct fb_info *fbi = vout->fbi;
  86176. + mm_segment_t old_fs;
  86177. + int ret = 0;
  86178. +
  86179. + if (vout->disp_support_windows) {
  86180. + old_fs = get_fs();
  86181. + set_fs(KERNEL_DS);
  86182. + ret = fbi->fbops->fb_ioctl(fbi, MXCFB_SET_OVERLAY_POS,
  86183. + (unsigned long)pos);
  86184. + set_fs(old_fs);
  86185. + }
  86186. +
  86187. + return ret;
  86188. +}
  86189. +
  86190. +static int config_disp_output(struct mxc_vout_output *vout)
  86191. +{
  86192. + struct dma_mem *buf = NULL;
  86193. + struct fb_info *fbi = vout->fbi;
  86194. + struct fb_var_screeninfo var;
  86195. + struct mxcfb_pos pos;
  86196. + int i, fb_num, ret;
  86197. + u32 fb_base;
  86198. + u32 size;
  86199. + u32 display_buf_size;
  86200. + u32 *pixel = NULL;
  86201. + u32 color;
  86202. + int j;
  86203. +
  86204. + memcpy(&var, &fbi->var, sizeof(var));
  86205. + fb_base = fbi->fix.smem_start;
  86206. +
  86207. + var.xres = vout->task.output.width;
  86208. + var.yres = vout->task.output.height;
  86209. + if (vout->linear_bypass_pp || vout->tiled_bypass_pp) {
  86210. + fb_num = 1;
  86211. + /* input crop */
  86212. + if (vout->task.input.width > vout->task.output.width)
  86213. + var.xres_virtual = vout->task.input.width;
  86214. + else
  86215. + var.xres_virtual = var.xres;
  86216. + if (vout->task.input.height > vout->task.output.height)
  86217. + var.yres_virtual = vout->task.input.height;
  86218. + else
  86219. + var.yres_virtual = var.yres;
  86220. + var.rotate = vout->task.output.rotate;
  86221. + var.vmode |= FB_VMODE_YWRAP;
  86222. + } else {
  86223. + fb_num = FB_BUFS;
  86224. + var.xres_virtual = var.xres;
  86225. + var.yres_virtual = fb_num * var.yres;
  86226. + var.vmode &= ~FB_VMODE_YWRAP;
  86227. + }
  86228. + var.bits_per_pixel = fmt_to_bpp(vout->task.output.format);
  86229. + var.nonstd = vout->task.output.format;
  86230. +
  86231. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  86232. + "set display fb to %d %d\n",
  86233. + var.xres, var.yres);
  86234. +
  86235. + /*
  86236. + * To setup the overlay fb from scratch without
  86237. + * the last time overlay fb position or resolution's
  86238. + * impact, we take the following steps:
  86239. + * - blank fb
  86240. + * - set fb position to the starting point
  86241. + * - reconfigure fb
  86242. + * - set fb position to a specific point
  86243. + * - unblank fb
  86244. + * This procedure applies to non-overlay fbs as well.
  86245. + */
  86246. + console_lock();
  86247. + fbi->flags |= FBINFO_MISC_USEREVENT;
  86248. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  86249. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  86250. + console_unlock();
  86251. +
  86252. + pos.x = 0;
  86253. + pos.y = 0;
  86254. + ret = set_window_position(vout, &pos);
  86255. + if (ret < 0) {
  86256. + v4l2_err(vout->vfd->v4l2_dev, "failed to set fb position "
  86257. + "to starting point\n");
  86258. + return ret;
  86259. + }
  86260. +
  86261. + /* Init display channel through fb API */
  86262. + var.yoffset = 0;
  86263. + var.activate |= FB_ACTIVATE_FORCE;
  86264. + console_lock();
  86265. + fbi->flags |= FBINFO_MISC_USEREVENT;
  86266. + ret = fb_set_var(fbi, &var);
  86267. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  86268. + console_unlock();
  86269. + if (ret < 0) {
  86270. + v4l2_err(vout->vfd->v4l2_dev,
  86271. + "ERR:%s fb_set_var ret:%d\n", __func__, ret);
  86272. + return ret;
  86273. + }
  86274. +
  86275. + ret = set_window_position(vout, &vout->win_pos);
  86276. + if (ret < 0) {
  86277. + v4l2_err(vout->vfd->v4l2_dev, "failed to set fb position\n");
  86278. + return ret;
  86279. + }
  86280. +
  86281. + if (vout->linear_bypass_pp || vout->tiled_bypass_pp)
  86282. + display_buf_size = fbi->fix.line_length * fbi->var.yres_virtual;
  86283. + else
  86284. + display_buf_size = fbi->fix.line_length * fbi->var.yres;
  86285. + for (i = 0; i < fb_num; i++)
  86286. + vout->disp_bufs[i] = fbi->fix.smem_start + i * display_buf_size;
  86287. + if (vout->tiled_bypass_pp) {
  86288. + size = PAGE_ALIGN(vout->task.input.crop.w *
  86289. + vout->task.input.crop.h *
  86290. + fmt_to_bpp(vout->task.output.format)/8);
  86291. + if (size > vout->vdoa_output[0].size) {
  86292. + for (i = 0; i < VDOA_FB_BUFS; i++) {
  86293. + buf = &vout->vdoa_output[i];
  86294. + if (buf->vaddr)
  86295. + free_dma_buf(vout, buf);
  86296. + buf->size = size;
  86297. + ret = alloc_dma_buf(vout, buf);
  86298. + if (ret < 0)
  86299. + goto err;
  86300. + }
  86301. + }
  86302. + for (i = fb_num; i < (fb_num + VDOA_FB_BUFS); i++)
  86303. + vout->disp_bufs[i] =
  86304. + vout->vdoa_output[i - fb_num].paddr;
  86305. + }
  86306. + vout->fb_smem_len = fbi->fix.smem_len;
  86307. + vout->fb_smem_start = fbi->fix.smem_start;
  86308. + if (fb_base != fbi->fix.smem_start) {
  86309. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  86310. + "realloc fb mem size:0x%x@0x%lx,old paddr @0x%x\n",
  86311. + fbi->fix.smem_len, fbi->fix.smem_start, fb_base);
  86312. + }
  86313. +
  86314. + /* fill black when video config changed */
  86315. + color = colorspaceofpixel(vout->task.output.format) == YUV_CS ?
  86316. + UYVY_BLACK : RGB_BLACK;
  86317. + if (IS_PLANAR_PIXEL_FORMAT(vout->task.output.format)) {
  86318. + size = display_buf_size * 8 /
  86319. + fmt_to_bpp(vout->task.output.format);
  86320. + memset(fbi->screen_base, Y_BLACK, size);
  86321. + memset(fbi->screen_base + size, UV_BLACK,
  86322. + display_buf_size - size);
  86323. + } else {
  86324. + pixel = (u32 *)fbi->screen_base;
  86325. + for (i = 0; i < (display_buf_size >> 2); i++)
  86326. + *pixel++ = color;
  86327. + }
  86328. + console_lock();
  86329. + fbi->flags |= FBINFO_MISC_USEREVENT;
  86330. + ret = fb_blank(fbi, FB_BLANK_UNBLANK);
  86331. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  86332. + console_unlock();
  86333. + vout->release = false;
  86334. +
  86335. + return ret;
  86336. +err:
  86337. + for (j = i - 1; j >= 0; j--) {
  86338. + buf = &vout->vdoa_output[j];
  86339. + if (buf->vaddr)
  86340. + free_dma_buf(vout, buf);
  86341. + }
  86342. + return ret;
  86343. +}
  86344. +
  86345. +static inline void wait_for_vsync(struct mxc_vout_output *vout)
  86346. +{
  86347. + struct fb_info *fbi = vout->fbi;
  86348. + mm_segment_t old_fs;
  86349. +
  86350. + if (fbi->fbops->fb_ioctl) {
  86351. + old_fs = get_fs();
  86352. + set_fs(KERNEL_DS);
  86353. + fbi->fbops->fb_ioctl(fbi, MXCFB_WAIT_FOR_VSYNC,
  86354. + (unsigned long)NULL);
  86355. + set_fs(old_fs);
  86356. + }
  86357. +
  86358. + return;
  86359. +}
  86360. +
  86361. +static void release_disp_output(struct mxc_vout_output *vout)
  86362. +{
  86363. + struct fb_info *fbi = vout->fbi;
  86364. + struct mxcfb_pos pos;
  86365. +
  86366. + if (vout->release)
  86367. + return;
  86368. + console_lock();
  86369. + fbi->flags |= FBINFO_MISC_USEREVENT;
  86370. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  86371. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  86372. + console_unlock();
  86373. +
  86374. + /* restore pos to 0,0 avoid fb pan display hang? */
  86375. + pos.x = 0;
  86376. + pos.y = 0;
  86377. + set_window_position(vout, &pos);
  86378. +
  86379. + if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
  86380. + console_lock();
  86381. + fbi->fix.smem_start = vout->disp_bufs[0];
  86382. + fbi->flags |= FBINFO_MISC_USEREVENT;
  86383. + fb_blank(fbi, FB_BLANK_UNBLANK);
  86384. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  86385. + console_unlock();
  86386. +
  86387. + }
  86388. +
  86389. + vout->release = true;
  86390. +}
  86391. +
  86392. +static int mxc_vidioc_streamon(struct file *file, void *fh,
  86393. + enum v4l2_buf_type i)
  86394. +{
  86395. + struct mxc_vout_output *vout = fh;
  86396. + struct videobuf_queue *q = &vout->vbq;
  86397. + int ret;
  86398. +
  86399. + if (q->streaming) {
  86400. + v4l2_err(vout->vfd->v4l2_dev,
  86401. + "video output already run\n");
  86402. + ret = -EBUSY;
  86403. + goto done;
  86404. + }
  86405. +
  86406. + if (deinterlace_3_field(vout) && list_is_singular(&q->stream)) {
  86407. + v4l2_err(vout->vfd->v4l2_dev,
  86408. + "deinterlacing: need queue 2 frame before streamon\n");
  86409. + ret = -EINVAL;
  86410. + goto done;
  86411. + }
  86412. +
  86413. + ret = config_disp_output(vout);
  86414. + if (ret < 0) {
  86415. + v4l2_err(vout->vfd->v4l2_dev,
  86416. + "Config display output failed\n");
  86417. + goto done;
  86418. + }
  86419. +
  86420. + hrtimer_init(&vout->timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
  86421. + vout->timer.function = mxc_vout_timer_handler;
  86422. + vout->timer_stop = true;
  86423. +
  86424. + vout->start_ktime = hrtimer_cb_get_time(&vout->timer);
  86425. +
  86426. + vout->pre1_vb = NULL;
  86427. + vout->pre2_vb = NULL;
  86428. +
  86429. + ret = videobuf_streamon(q);
  86430. +done:
  86431. + return ret;
  86432. +}
  86433. +
  86434. +static int mxc_vidioc_streamoff(struct file *file, void *fh,
  86435. + enum v4l2_buf_type i)
  86436. +{
  86437. + struct mxc_vout_output *vout = fh;
  86438. + struct videobuf_queue *q = &vout->vbq;
  86439. + int ret = 0;
  86440. +
  86441. + if (q->streaming) {
  86442. + flush_workqueue(vout->v4l_wq);
  86443. +
  86444. + hrtimer_cancel(&vout->timer);
  86445. +
  86446. + /*
  86447. + * Wait for 2 vsyncs to make sure
  86448. + * frames are drained on triple
  86449. + * buffer.
  86450. + */
  86451. + wait_for_vsync(vout);
  86452. + wait_for_vsync(vout);
  86453. +
  86454. + release_disp_output(vout);
  86455. +
  86456. + ret = videobuf_streamoff(&vout->vbq);
  86457. + }
  86458. + INIT_LIST_HEAD(&vout->queue_list);
  86459. + INIT_LIST_HEAD(&vout->active_list);
  86460. +
  86461. + return ret;
  86462. +}
  86463. +
  86464. +static const struct v4l2_ioctl_ops mxc_vout_ioctl_ops = {
  86465. + .vidioc_querycap = mxc_vidioc_querycap,
  86466. + .vidioc_enum_fmt_vid_out = mxc_vidioc_enum_fmt_vid_out,
  86467. + .vidioc_g_fmt_vid_out = mxc_vidioc_g_fmt_vid_out,
  86468. + .vidioc_s_fmt_vid_out = mxc_vidioc_s_fmt_vid_out,
  86469. + .vidioc_cropcap = mxc_vidioc_cropcap,
  86470. + .vidioc_g_crop = mxc_vidioc_g_crop,
  86471. + .vidioc_s_crop = mxc_vidioc_s_crop,
  86472. + .vidioc_queryctrl = mxc_vidioc_queryctrl,
  86473. + .vidioc_g_ctrl = mxc_vidioc_g_ctrl,
  86474. + .vidioc_s_ctrl = mxc_vidioc_s_ctrl,
  86475. + .vidioc_reqbufs = mxc_vidioc_reqbufs,
  86476. + .vidioc_querybuf = mxc_vidioc_querybuf,
  86477. + .vidioc_qbuf = mxc_vidioc_qbuf,
  86478. + .vidioc_dqbuf = mxc_vidioc_dqbuf,
  86479. + .vidioc_streamon = mxc_vidioc_streamon,
  86480. + .vidioc_streamoff = mxc_vidioc_streamoff,
  86481. +};
  86482. +
  86483. +static const struct v4l2_file_operations mxc_vout_fops = {
  86484. + .owner = THIS_MODULE,
  86485. + .unlocked_ioctl = video_ioctl2,
  86486. + .mmap = mxc_vout_mmap,
  86487. + .open = mxc_vout_open,
  86488. + .release = mxc_vout_release,
  86489. +};
  86490. +
  86491. +static struct video_device mxc_vout_template = {
  86492. + .name = "MXC Video Output",
  86493. + .fops = &mxc_vout_fops,
  86494. + .ioctl_ops = &mxc_vout_ioctl_ops,
  86495. + .release = video_device_release,
  86496. +};
  86497. +
  86498. +static struct videobuf_queue_ops mxc_vout_vbq_ops = {
  86499. + .buf_setup = mxc_vout_buffer_setup,
  86500. + .buf_prepare = mxc_vout_buffer_prepare,
  86501. + .buf_release = mxc_vout_buffer_release,
  86502. + .buf_queue = mxc_vout_buffer_queue,
  86503. +};
  86504. +
  86505. +static void mxc_vout_free_output(struct mxc_vout_dev *dev)
  86506. +{
  86507. + int i;
  86508. + int j;
  86509. + struct mxc_vout_output *vout;
  86510. + struct video_device *vfd;
  86511. +
  86512. + for (i = 0; i < dev->out_num; i++) {
  86513. + vout = dev->out[i];
  86514. + vfd = vout->vfd;
  86515. + if (vout->vdoa_work.vaddr)
  86516. + free_dma_buf(vout, &vout->vdoa_work);
  86517. + for (j = 0; j < VDOA_FB_BUFS; j++) {
  86518. + if (vout->vdoa_output[j].vaddr)
  86519. + free_dma_buf(vout, &vout->vdoa_output[j]);
  86520. + }
  86521. + if (vfd) {
  86522. + if (!video_is_registered(vfd))
  86523. + video_device_release(vfd);
  86524. + else
  86525. + video_unregister_device(vfd);
  86526. + }
  86527. + kfree(vout);
  86528. + }
  86529. +}
  86530. +
  86531. +static int mxc_vout_setup_output(struct mxc_vout_dev *dev)
  86532. +{
  86533. + struct videobuf_queue *q;
  86534. + struct fb_info *fbi;
  86535. + struct mxc_vout_output *vout;
  86536. + int i, ret = 0;
  86537. +
  86538. + update_display_setting();
  86539. +
  86540. + /* all output/overlay based on fb */
  86541. + for (i = 0; i < num_registered_fb; i++) {
  86542. + fbi = registered_fb[i];
  86543. +
  86544. + vout = kzalloc(sizeof(struct mxc_vout_output), GFP_KERNEL);
  86545. + if (!vout) {
  86546. + ret = -ENOMEM;
  86547. + break;
  86548. + }
  86549. +
  86550. + dev->out[dev->out_num] = vout;
  86551. + dev->out_num++;
  86552. +
  86553. + vout->fbi = fbi;
  86554. + vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  86555. + vout->vfd = video_device_alloc();
  86556. + if (!vout->vfd) {
  86557. + ret = -ENOMEM;
  86558. + break;
  86559. + }
  86560. +
  86561. + *vout->vfd = mxc_vout_template;
  86562. + vout->vfd->debug = debug;
  86563. + vout->vfd->v4l2_dev = &dev->v4l2_dev;
  86564. + vout->vfd->lock = &vout->mutex;
  86565. + vout->vfd->vfl_dir = VFL_DIR_TX;
  86566. +
  86567. + mutex_init(&vout->mutex);
  86568. + mutex_init(&vout->task_lock);
  86569. +
  86570. + strlcpy(vout->vfd->name, fbi->fix.id, sizeof(vout->vfd->name));
  86571. +
  86572. + video_set_drvdata(vout->vfd, vout);
  86573. +
  86574. + if (video_register_device(vout->vfd,
  86575. + VFL_TYPE_GRABBER, video_nr + i) < 0) {
  86576. + ret = -ENODEV;
  86577. + break;
  86578. + }
  86579. +
  86580. + q = &vout->vbq;
  86581. + q->dev = dev->dev;
  86582. + spin_lock_init(&vout->vbq_lock);
  86583. + videobuf_queue_dma_contig_init(q, &mxc_vout_vbq_ops, q->dev,
  86584. + &vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
  86585. + sizeof(struct videobuf_buffer), vout, NULL);
  86586. +
  86587. + v4l2_info(vout->vfd->v4l2_dev, "V4L2 device registered as %s\n",
  86588. + video_device_node_name(vout->vfd));
  86589. +
  86590. + }
  86591. +
  86592. + return ret;
  86593. +}
  86594. +
  86595. +static int mxc_vout_probe(struct platform_device *pdev)
  86596. +{
  86597. + int ret;
  86598. + struct mxc_vout_dev *dev;
  86599. +
  86600. + dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  86601. + if (!dev)
  86602. + return -ENOMEM;
  86603. +
  86604. + dev->dev = &pdev->dev;
  86605. + dev->dev->dma_mask = kmalloc(sizeof(*dev->dev->dma_mask), GFP_KERNEL);
  86606. + *dev->dev->dma_mask = DMA_BIT_MASK(32);
  86607. + dev->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  86608. +
  86609. + ret = v4l2_device_register(dev->dev, &dev->v4l2_dev);
  86610. + if (ret) {
  86611. + dev_err(dev->dev, "v4l2_device_register failed\n");
  86612. + goto free_dev;
  86613. + }
  86614. +
  86615. + ret = mxc_vout_setup_output(dev);
  86616. + if (ret < 0)
  86617. + goto rel_vdev;
  86618. +
  86619. + return 0;
  86620. +
  86621. +rel_vdev:
  86622. + mxc_vout_free_output(dev);
  86623. + v4l2_device_unregister(&dev->v4l2_dev);
  86624. +free_dev:
  86625. + kfree(dev);
  86626. + return ret;
  86627. +}
  86628. +
  86629. +static int mxc_vout_remove(struct platform_device *pdev)
  86630. +{
  86631. + struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
  86632. + struct mxc_vout_dev *dev = container_of(v4l2_dev, struct
  86633. + mxc_vout_dev, v4l2_dev);
  86634. +
  86635. + mxc_vout_free_output(dev);
  86636. + v4l2_device_unregister(v4l2_dev);
  86637. + kfree(dev);
  86638. + return 0;
  86639. +}
  86640. +
  86641. +static const struct of_device_id mxc_v4l2_dt_ids[] = {
  86642. + { .compatible = "fsl,mxc_v4l2_output", },
  86643. + { /* sentinel */ }
  86644. +};
  86645. +
  86646. +static struct platform_driver mxc_vout_driver = {
  86647. + .driver = {
  86648. + .name = "mxc_v4l2_output",
  86649. + .of_match_table = mxc_v4l2_dt_ids,
  86650. + },
  86651. + .probe = mxc_vout_probe,
  86652. + .remove = mxc_vout_remove,
  86653. +};
  86654. +
  86655. +static int __init mxc_vout_init(void)
  86656. +{
  86657. + if (platform_driver_register(&mxc_vout_driver) != 0) {
  86658. + printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
  86659. + return -EINVAL;
  86660. + }
  86661. + return 0;
  86662. +}
  86663. +
  86664. +static void mxc_vout_cleanup(void)
  86665. +{
  86666. + platform_driver_unregister(&mxc_vout_driver);
  86667. +}
  86668. +
  86669. +module_init(mxc_vout_init);
  86670. +module_exit(mxc_vout_cleanup);
  86671. +
  86672. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  86673. +MODULE_DESCRIPTION("V4L2-driver for MXC video output");
  86674. +MODULE_LICENSE("GPL");
  86675. diff -Nur linux-3.14.14/drivers/media/v4l2-core/videobuf2-dma-contig.c linux-imx6-3.14/drivers/media/v4l2-core/videobuf2-dma-contig.c
  86676. --- linux-3.14.14/drivers/media/v4l2-core/videobuf2-dma-contig.c 2014-07-28 10:07:25.000000000 -0500
  86677. +++ linux-imx6-3.14/drivers/media/v4l2-core/videobuf2-dma-contig.c 2014-12-08 00:31:53.360418001 -0600
  86678. @@ -719,7 +719,7 @@
  86679. /* get the associated scatterlist for this buffer */
  86680. sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
  86681. - if (IS_ERR_OR_NULL(sgt)) {
  86682. + if (IS_ERR(sgt)) {
  86683. pr_err("Error getting dmabuf scatterlist\n");
  86684. return -EINVAL;
  86685. }
  86686. diff -Nur linux-3.14.14/drivers/media/v4l2-core/videobuf-dma-contig.c linux-imx6-3.14/drivers/media/v4l2-core/videobuf-dma-contig.c
  86687. --- linux-3.14.14/drivers/media/v4l2-core/videobuf-dma-contig.c 2014-07-28 10:07:25.000000000 -0500
  86688. +++ linux-imx6-3.14/drivers/media/v4l2-core/videobuf-dma-contig.c 2014-12-08 00:31:53.360418001 -0600
  86689. @@ -304,7 +304,7 @@
  86690. /* Try to remap memory */
  86691. size = vma->vm_end - vma->vm_start;
  86692. - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  86693. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  86694. retval = vm_iomap_memory(vma, vma->vm_start, size);
  86695. if (retval) {
  86696. dev_err(q->dev, "mmap: remap failed with error %d. ",
  86697. diff -Nur linux-3.14.14/drivers/mfd/ab8500-core.c linux-imx6-3.14/drivers/mfd/ab8500-core.c
  86698. --- linux-3.14.14/drivers/mfd/ab8500-core.c 2014-07-28 10:07:25.000000000 -0500
  86699. +++ linux-imx6-3.14/drivers/mfd/ab8500-core.c 2014-12-08 00:31:53.376418001 -0600
  86700. @@ -592,7 +592,7 @@
  86701. /* If ->irq_base is zero this will give a linear mapping */
  86702. ab8500->domain = irq_domain_add_simple(NULL,
  86703. - num_irqs, ab8500->irq_base,
  86704. + num_irqs, 0,
  86705. &ab8500_irq_ops, ab8500);
  86706. if (!ab8500->domain) {
  86707. @@ -1583,14 +1583,13 @@
  86708. if (!ab8500)
  86709. return -ENOMEM;
  86710. - if (plat)
  86711. - ab8500->irq_base = plat->irq_base;
  86712. -
  86713. ab8500->dev = &pdev->dev;
  86714. resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  86715. - if (!resource)
  86716. + if (!resource) {
  86717. + dev_err(&pdev->dev, "no IRQ resource\n");
  86718. return -ENODEV;
  86719. + }
  86720. ab8500->irq = resource->start;
  86721. @@ -1612,8 +1611,10 @@
  86722. else {
  86723. ret = get_register_interruptible(ab8500, AB8500_MISC,
  86724. AB8500_IC_NAME_REG, &value);
  86725. - if (ret < 0)
  86726. + if (ret < 0) {
  86727. + dev_err(&pdev->dev, "could not probe HW\n");
  86728. return ret;
  86729. + }
  86730. ab8500->version = value;
  86731. }
  86732. @@ -1759,30 +1760,30 @@
  86733. if (is_ab9540(ab8500))
  86734. ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
  86735. ARRAY_SIZE(ab9540_devs), NULL,
  86736. - ab8500->irq_base, ab8500->domain);
  86737. + 0, ab8500->domain);
  86738. else if (is_ab8540(ab8500)) {
  86739. ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs,
  86740. ARRAY_SIZE(ab8540_devs), NULL,
  86741. - ab8500->irq_base, NULL);
  86742. + 0, ab8500->domain);
  86743. if (ret)
  86744. return ret;
  86745. if (is_ab8540_1p2_or_earlier(ab8500))
  86746. ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut1_devs,
  86747. ARRAY_SIZE(ab8540_cut1_devs), NULL,
  86748. - ab8500->irq_base, NULL);
  86749. + 0, ab8500->domain);
  86750. else /* ab8540 >= cut2 */
  86751. ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut2_devs,
  86752. ARRAY_SIZE(ab8540_cut2_devs), NULL,
  86753. - ab8500->irq_base, NULL);
  86754. + 0, ab8500->domain);
  86755. } else if (is_ab8505(ab8500))
  86756. ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs,
  86757. ARRAY_SIZE(ab8505_devs), NULL,
  86758. - ab8500->irq_base, ab8500->domain);
  86759. + 0, ab8500->domain);
  86760. else
  86761. ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
  86762. ARRAY_SIZE(ab8500_devs), NULL,
  86763. - ab8500->irq_base, ab8500->domain);
  86764. + 0, ab8500->domain);
  86765. if (ret)
  86766. return ret;
  86767. @@ -1790,7 +1791,7 @@
  86768. /* Add battery management devices */
  86769. ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,
  86770. ARRAY_SIZE(ab8500_bm_devs), NULL,
  86771. - ab8500->irq_base, ab8500->domain);
  86772. + 0, ab8500->domain);
  86773. if (ret)
  86774. dev_err(ab8500->dev, "error adding bm devices\n");
  86775. }
  86776. diff -Nur linux-3.14.14/drivers/mfd/db8500-prcmu.c linux-imx6-3.14/drivers/mfd/db8500-prcmu.c
  86777. --- linux-3.14.14/drivers/mfd/db8500-prcmu.c 2014-07-28 10:07:25.000000000 -0500
  86778. +++ linux-imx6-3.14/drivers/mfd/db8500-prcmu.c 2014-12-08 00:31:53.380418001 -0600
  86779. @@ -25,6 +25,7 @@
  86780. #include <linux/bitops.h>
  86781. #include <linux/fs.h>
  86782. #include <linux/of.h>
  86783. +#include <linux/of_irq.h>
  86784. #include <linux/platform_device.h>
  86785. #include <linux/uaccess.h>
  86786. #include <linux/mfd/core.h>
  86787. @@ -2678,16 +2679,12 @@
  86788. .xlate = irq_domain_xlate_twocell,
  86789. };
  86790. -static int db8500_irq_init(struct device_node *np, int irq_base)
  86791. +static int db8500_irq_init(struct device_node *np)
  86792. {
  86793. int i;
  86794. - /* In the device tree case, just take some IRQs */
  86795. - if (np)
  86796. - irq_base = 0;
  86797. -
  86798. db8500_irq_domain = irq_domain_add_simple(
  86799. - np, NUM_PRCMU_WAKEUPS, irq_base,
  86800. + np, NUM_PRCMU_WAKEUPS, 0,
  86801. &db8500_irq_ops, NULL);
  86802. if (!db8500_irq_domain) {
  86803. @@ -3114,10 +3111,10 @@
  86804. }
  86805. static int db8500_prcmu_register_ab8500(struct device *parent,
  86806. - struct ab8500_platform_data *pdata,
  86807. - int irq)
  86808. + struct ab8500_platform_data *pdata)
  86809. {
  86810. - struct resource ab8500_resource = DEFINE_RES_IRQ(irq);
  86811. + struct device_node *np;
  86812. + struct resource ab8500_resource;
  86813. struct mfd_cell ab8500_cell = {
  86814. .name = "ab8500-core",
  86815. .of_compatible = "stericsson,ab8500",
  86816. @@ -3128,6 +3125,20 @@
  86817. .num_resources = 1,
  86818. };
  86819. + if (!parent->of_node)
  86820. + return -ENODEV;
  86821. +
  86822. + /* Look up the device node, sneak the IRQ out of it */
  86823. + for_each_child_of_node(parent->of_node, np) {
  86824. + if (of_device_is_compatible(np, ab8500_cell.of_compatible))
  86825. + break;
  86826. + }
  86827. + if (!np) {
  86828. + dev_info(parent, "could not find AB8500 node in the device tree\n");
  86829. + return -ENODEV;
  86830. + }
  86831. + of_irq_to_resource_table(np, &ab8500_resource, 1);
  86832. +
  86833. return mfd_add_devices(parent, 0, &ab8500_cell, 1, NULL, 0, NULL);
  86834. }
  86835. @@ -3180,7 +3191,7 @@
  86836. goto no_irq_return;
  86837. }
  86838. - db8500_irq_init(np, pdata->irq_base);
  86839. + db8500_irq_init(np);
  86840. prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
  86841. @@ -3205,8 +3216,7 @@
  86842. }
  86843. }
  86844. - err = db8500_prcmu_register_ab8500(&pdev->dev, pdata->ab_platdata,
  86845. - pdata->ab_irq);
  86846. + err = db8500_prcmu_register_ab8500(&pdev->dev, pdata->ab_platdata);
  86847. if (err) {
  86848. mfd_remove_devices(&pdev->dev);
  86849. pr_err("prcmu: Failed to add ab8500 subdevice\n");
  86850. diff -Nur linux-3.14.14/drivers/mfd/Kconfig linux-imx6-3.14/drivers/mfd/Kconfig
  86851. --- linux-3.14.14/drivers/mfd/Kconfig 2014-07-28 10:07:25.000000000 -0500
  86852. +++ linux-imx6-3.14/drivers/mfd/Kconfig 2014-12-08 00:31:53.376418001 -0600
  86853. @@ -163,6 +163,14 @@
  86854. Additional drivers must be enabled in order to use the functionality
  86855. of the device.
  86856. +config MFD_MXC_HDMI
  86857. + tristate "Freescale HDMI Core"
  86858. + select MFD_CORE
  86859. + help
  86860. + This is the core driver for the Freescale i.MX6 on-chip HDMI.
  86861. + This MFD driver connects with the video and audio drivers for HDMI.
  86862. +
  86863. +
  86864. config MFD_MC13XXX
  86865. tristate
  86866. depends on (SPI_MASTER || I2C)
  86867. @@ -1226,3 +1234,4 @@
  86868. help
  86869. Platform configuration infrastructure for the ARM Ltd.
  86870. Versatile Express.
  86871. +
  86872. diff -Nur linux-3.14.14/drivers/mfd/Makefile linux-imx6-3.14/drivers/mfd/Makefile
  86873. --- linux-3.14.14/drivers/mfd/Makefile 2014-07-28 10:07:25.000000000 -0500
  86874. +++ linux-imx6-3.14/drivers/mfd/Makefile 2014-12-08 00:31:53.376418001 -0600
  86875. @@ -166,3 +166,4 @@
  86876. obj-$(CONFIG_MFD_AS3711) += as3711.o
  86877. obj-$(CONFIG_MFD_AS3722) += as3722.o
  86878. obj-$(CONFIG_MFD_STW481X) += stw481x.o
  86879. +obj-$(CONFIG_MFD_MXC_HDMI) += mxc-hdmi-core.o
  86880. diff -Nur linux-3.14.14/drivers/mfd/mxc-hdmi-core.c linux-imx6-3.14/drivers/mfd/mxc-hdmi-core.c
  86881. --- linux-3.14.14/drivers/mfd/mxc-hdmi-core.c 1969-12-31 18:00:00.000000000 -0600
  86882. +++ linux-imx6-3.14/drivers/mfd/mxc-hdmi-core.c 2014-12-08 00:31:53.384418001 -0600
  86883. @@ -0,0 +1,798 @@
  86884. +/*
  86885. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
  86886. + *
  86887. + * This program is free software; you can redistribute it and/or modify
  86888. + * it under the terms of the GNU General Public License as published by
  86889. + * the Free Software Foundation; either version 2 of the License, or
  86890. + * (at your option) any later version.
  86891. + *
  86892. + * This program is distributed in the hope that it will be useful,
  86893. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  86894. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  86895. + * GNU General Public License for more details.
  86896. + *
  86897. + * You should have received a copy of the GNU General Public License
  86898. + * along with this program; if not, write to the Free Software
  86899. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  86900. + *
  86901. + */
  86902. +#include <linux/kernel.h>
  86903. +#include <linux/module.h>
  86904. +#include <linux/init.h>
  86905. +#include <linux/slab.h>
  86906. +#include <linux/device.h>
  86907. +#include <linux/err.h>
  86908. +#include <linux/io.h>
  86909. +#include <linux/clk.h>
  86910. +#include <linux/spinlock.h>
  86911. +#include <linux/irq.h>
  86912. +#include <linux/interrupt.h>
  86913. +
  86914. +#include <linux/platform_device.h>
  86915. +#include <linux/regulator/machine.h>
  86916. +#include <asm/mach-types.h>
  86917. +
  86918. +#include <video/mxc_hdmi.h>
  86919. +#include <linux/ipu-v3.h>
  86920. +#include <video/mxc_edid.h>
  86921. +#include "../mxc/ipu3/ipu_prv.h"
  86922. +#include <linux/mfd/mxc-hdmi-core.h>
  86923. +#include <linux/of_device.h>
  86924. +#include <linux/mod_devicetable.h>
  86925. +
  86926. +struct mxc_hdmi_data {
  86927. + struct platform_device *pdev;
  86928. + unsigned long __iomem *reg_base;
  86929. + unsigned long reg_phys_base;
  86930. + struct device *dev;
  86931. +};
  86932. +
  86933. +static void __iomem *hdmi_base;
  86934. +static struct clk *isfr_clk;
  86935. +static struct clk *iahb_clk;
  86936. +static spinlock_t irq_spinlock;
  86937. +static spinlock_t edid_spinlock;
  86938. +static unsigned int sample_rate;
  86939. +static unsigned long pixel_clk_rate;
  86940. +static struct clk *pixel_clk;
  86941. +static int hdmi_ratio;
  86942. +int mxc_hdmi_ipu_id;
  86943. +int mxc_hdmi_disp_id;
  86944. +static int hdmi_core_edid_status;
  86945. +static struct mxc_edid_cfg hdmi_core_edid_cfg;
  86946. +static int hdmi_core_init;
  86947. +static unsigned int hdmi_dma_running;
  86948. +static struct snd_pcm_substream *hdmi_audio_stream_playback;
  86949. +static unsigned int hdmi_cable_state;
  86950. +static unsigned int hdmi_blank_state;
  86951. +static unsigned int hdmi_abort_state;
  86952. +static spinlock_t hdmi_audio_lock, hdmi_blank_state_lock, hdmi_cable_state_lock;
  86953. +
  86954. +void hdmi_set_dvi_mode(unsigned int state)
  86955. +{
  86956. + if (state) {
  86957. + mxc_hdmi_abort_stream();
  86958. + hdmi_cec_stop_device();
  86959. + } else {
  86960. + hdmi_cec_start_device();
  86961. + }
  86962. +}
  86963. +EXPORT_SYMBOL(hdmi_set_dvi_mode);
  86964. +
  86965. +unsigned int hdmi_set_cable_state(unsigned int state)
  86966. +{
  86967. + unsigned long flags;
  86968. + struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
  86969. +
  86970. + spin_lock_irqsave(&hdmi_cable_state_lock, flags);
  86971. + hdmi_cable_state = state;
  86972. + spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
  86973. +
  86974. + if (check_hdmi_state() && substream && hdmi_abort_state) {
  86975. + hdmi_abort_state = 0;
  86976. + substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
  86977. + }
  86978. + return 0;
  86979. +}
  86980. +EXPORT_SYMBOL(hdmi_set_cable_state);
  86981. +
  86982. +unsigned int hdmi_set_blank_state(unsigned int state)
  86983. +{
  86984. + unsigned long flags;
  86985. + struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
  86986. +
  86987. + spin_lock_irqsave(&hdmi_blank_state_lock, flags);
  86988. + hdmi_blank_state = state;
  86989. + spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
  86990. +
  86991. + if (check_hdmi_state() && substream && hdmi_abort_state) {
  86992. + hdmi_abort_state = 0;
  86993. + substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
  86994. + }
  86995. + return 0;
  86996. +}
  86997. +EXPORT_SYMBOL(hdmi_set_blank_state);
  86998. +
  86999. +static void hdmi_audio_abort_stream(struct snd_pcm_substream *substream)
  87000. +{
  87001. + unsigned long flags;
  87002. +
  87003. + snd_pcm_stream_lock_irqsave(substream, flags);
  87004. +
  87005. + if (snd_pcm_running(substream)) {
  87006. + hdmi_abort_state = 1;
  87007. + substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
  87008. + }
  87009. +
  87010. + snd_pcm_stream_unlock_irqrestore(substream, flags);
  87011. +}
  87012. +
  87013. +int mxc_hdmi_abort_stream(void)
  87014. +{
  87015. + unsigned long flags;
  87016. + spin_lock_irqsave(&hdmi_audio_lock, flags);
  87017. + if (hdmi_audio_stream_playback)
  87018. + hdmi_audio_abort_stream(hdmi_audio_stream_playback);
  87019. + spin_unlock_irqrestore(&hdmi_audio_lock, flags);
  87020. +
  87021. + return 0;
  87022. +}
  87023. +EXPORT_SYMBOL(mxc_hdmi_abort_stream);
  87024. +
  87025. +int check_hdmi_state(void)
  87026. +{
  87027. + unsigned long flags1, flags2;
  87028. + unsigned int ret;
  87029. +
  87030. + spin_lock_irqsave(&hdmi_cable_state_lock, flags1);
  87031. + spin_lock_irqsave(&hdmi_blank_state_lock, flags2);
  87032. +
  87033. + ret = hdmi_cable_state && hdmi_blank_state;
  87034. +
  87035. + spin_unlock_irqrestore(&hdmi_blank_state_lock, flags2);
  87036. + spin_unlock_irqrestore(&hdmi_cable_state_lock, flags1);
  87037. +
  87038. + return ret;
  87039. +}
  87040. +EXPORT_SYMBOL(check_hdmi_state);
  87041. +
  87042. +int mxc_hdmi_register_audio(struct snd_pcm_substream *substream)
  87043. +{
  87044. + unsigned long flags, flags1;
  87045. + int ret = 0;
  87046. +
  87047. + snd_pcm_stream_lock_irqsave(substream, flags);
  87048. +
  87049. + if (substream && check_hdmi_state()) {
  87050. + spin_lock_irqsave(&hdmi_audio_lock, flags1);
  87051. + if (hdmi_audio_stream_playback) {
  87052. + pr_err("%s unconsist hdmi auido stream!\n", __func__);
  87053. + ret = -EINVAL;
  87054. + }
  87055. + hdmi_audio_stream_playback = substream;
  87056. + hdmi_abort_state = 0;
  87057. + spin_unlock_irqrestore(&hdmi_audio_lock, flags1);
  87058. + } else
  87059. + ret = -EINVAL;
  87060. +
  87061. + snd_pcm_stream_unlock_irqrestore(substream, flags);
  87062. +
  87063. + return ret;
  87064. +}
  87065. +EXPORT_SYMBOL(mxc_hdmi_register_audio);
  87066. +
  87067. +void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream)
  87068. +{
  87069. + unsigned long flags;
  87070. +
  87071. + spin_lock_irqsave(&hdmi_audio_lock, flags);
  87072. + hdmi_audio_stream_playback = NULL;
  87073. + hdmi_abort_state = 0;
  87074. + spin_unlock_irqrestore(&hdmi_audio_lock, flags);
  87075. +}
  87076. +EXPORT_SYMBOL(mxc_hdmi_unregister_audio);
  87077. +
  87078. +u8 hdmi_readb(unsigned int reg)
  87079. +{
  87080. + u8 value;
  87081. +
  87082. + value = __raw_readb(hdmi_base + reg);
  87083. +
  87084. + return value;
  87085. +}
  87086. +EXPORT_SYMBOL(hdmi_readb);
  87087. +
  87088. +#ifdef DEBUG
  87089. +static bool overflow_lo;
  87090. +static bool overflow_hi;
  87091. +
  87092. +bool hdmi_check_overflow(void)
  87093. +{
  87094. + u8 val, lo, hi;
  87095. +
  87096. + val = hdmi_readb(HDMI_IH_FC_STAT2);
  87097. + lo = (val & HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW) != 0;
  87098. + hi = (val & HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW) != 0;
  87099. +
  87100. + if ((lo != overflow_lo) || (hi != overflow_hi)) {
  87101. + pr_debug("%s LowPriority=%d HighPriority=%d <=======================\n",
  87102. + __func__, lo, hi);
  87103. + overflow_lo = lo;
  87104. + overflow_hi = hi;
  87105. + return true;
  87106. + }
  87107. + return false;
  87108. +}
  87109. +#else
  87110. +bool hdmi_check_overflow(void)
  87111. +{
  87112. + return false;
  87113. +}
  87114. +#endif
  87115. +EXPORT_SYMBOL(hdmi_check_overflow);
  87116. +
  87117. +void hdmi_writeb(u8 value, unsigned int reg)
  87118. +{
  87119. + hdmi_check_overflow();
  87120. + __raw_writeb(value, hdmi_base + reg);
  87121. + hdmi_check_overflow();
  87122. +}
  87123. +EXPORT_SYMBOL(hdmi_writeb);
  87124. +
  87125. +void hdmi_mask_writeb(u8 data, unsigned int reg, u8 shift, u8 mask)
  87126. +{
  87127. + u8 value = hdmi_readb(reg) & ~mask;
  87128. + value |= (data << shift) & mask;
  87129. + hdmi_writeb(value, reg);
  87130. +}
  87131. +EXPORT_SYMBOL(hdmi_mask_writeb);
  87132. +
  87133. +unsigned int hdmi_read4(unsigned int reg)
  87134. +{
  87135. + /* read a four byte address from registers */
  87136. + return (hdmi_readb(reg + 3) << 24) |
  87137. + (hdmi_readb(reg + 2) << 16) |
  87138. + (hdmi_readb(reg + 1) << 8) |
  87139. + hdmi_readb(reg);
  87140. +}
  87141. +EXPORT_SYMBOL(hdmi_read4);
  87142. +
  87143. +void hdmi_write4(unsigned int value, unsigned int reg)
  87144. +{
  87145. + /* write a four byte address to hdmi regs */
  87146. + hdmi_writeb(value & 0xff, reg);
  87147. + hdmi_writeb((value >> 8) & 0xff, reg + 1);
  87148. + hdmi_writeb((value >> 16) & 0xff, reg + 2);
  87149. + hdmi_writeb((value >> 24) & 0xff, reg + 3);
  87150. +}
  87151. +EXPORT_SYMBOL(hdmi_write4);
  87152. +
  87153. +static void initialize_hdmi_ih_mutes(void)
  87154. +{
  87155. + u8 ih_mute;
  87156. +
  87157. + /*
  87158. + * Boot up defaults are:
  87159. + * HDMI_IH_MUTE = 0x03 (disabled)
  87160. + * HDMI_IH_MUTE_* = 0x00 (enabled)
  87161. + */
  87162. +
  87163. + /* Disable top level interrupt bits in HDMI block */
  87164. + ih_mute = hdmi_readb(HDMI_IH_MUTE) |
  87165. + HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
  87166. + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
  87167. +
  87168. + hdmi_writeb(ih_mute, HDMI_IH_MUTE);
  87169. +
  87170. + /* by default mask all interrupts */
  87171. + hdmi_writeb(0xff, HDMI_VP_MASK);
  87172. + hdmi_writeb(0xff, HDMI_FC_MASK0);
  87173. + hdmi_writeb(0xff, HDMI_FC_MASK1);
  87174. + hdmi_writeb(0xff, HDMI_FC_MASK2);
  87175. + hdmi_writeb(0xff, HDMI_PHY_MASK0);
  87176. + hdmi_writeb(0xff, HDMI_PHY_I2CM_INT_ADDR);
  87177. + hdmi_writeb(0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
  87178. + hdmi_writeb(0xff, HDMI_AUD_INT);
  87179. + hdmi_writeb(0xff, HDMI_AUD_SPDIFINT);
  87180. + hdmi_writeb(0xff, HDMI_AUD_HBR_MASK);
  87181. + hdmi_writeb(0xff, HDMI_GP_MASK);
  87182. + hdmi_writeb(0xff, HDMI_A_APIINTMSK);
  87183. + hdmi_writeb(0xff, HDMI_CEC_MASK);
  87184. + hdmi_writeb(0xff, HDMI_I2CM_INT);
  87185. + hdmi_writeb(0xff, HDMI_I2CM_CTLINT);
  87186. +
  87187. + /* Disable interrupts in the IH_MUTE_* registers */
  87188. + hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT0);
  87189. + hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT1);
  87190. + hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT2);
  87191. + hdmi_writeb(0xff, HDMI_IH_MUTE_AS_STAT0);
  87192. + hdmi_writeb(0xff, HDMI_IH_MUTE_PHY_STAT0);
  87193. + hdmi_writeb(0xff, HDMI_IH_MUTE_I2CM_STAT0);
  87194. + hdmi_writeb(0xff, HDMI_IH_MUTE_CEC_STAT0);
  87195. + hdmi_writeb(0xff, HDMI_IH_MUTE_VP_STAT0);
  87196. + hdmi_writeb(0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
  87197. + hdmi_writeb(0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  87198. +
  87199. + /* Enable top level interrupt bits in HDMI block */
  87200. + ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
  87201. + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT);
  87202. + hdmi_writeb(ih_mute, HDMI_IH_MUTE);
  87203. +}
  87204. +
  87205. +static void hdmi_set_clock_regenerator_n(unsigned int value)
  87206. +{
  87207. + u8 val;
  87208. +
  87209. + if (!hdmi_dma_running) {
  87210. + hdmi_writeb(value & 0xff, HDMI_AUD_N1);
  87211. + hdmi_writeb(0, HDMI_AUD_N2);
  87212. + hdmi_writeb(0, HDMI_AUD_N3);
  87213. + }
  87214. +
  87215. + hdmi_writeb(value & 0xff, HDMI_AUD_N1);
  87216. + hdmi_writeb((value >> 8) & 0xff, HDMI_AUD_N2);
  87217. + hdmi_writeb((value >> 16) & 0x0f, HDMI_AUD_N3);
  87218. +
  87219. + /* nshift factor = 0 */
  87220. + val = hdmi_readb(HDMI_AUD_CTS3);
  87221. + val &= ~HDMI_AUD_CTS3_N_SHIFT_MASK;
  87222. + hdmi_writeb(val, HDMI_AUD_CTS3);
  87223. +}
  87224. +
  87225. +static void hdmi_set_clock_regenerator_cts(unsigned int cts)
  87226. +{
  87227. + u8 val;
  87228. +
  87229. + if (!hdmi_dma_running) {
  87230. + hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
  87231. + hdmi_writeb(0, HDMI_AUD_CTS2);
  87232. + hdmi_writeb(0, HDMI_AUD_CTS3);
  87233. + }
  87234. +
  87235. + /* Must be set/cleared first */
  87236. + val = hdmi_readb(HDMI_AUD_CTS3);
  87237. + val &= ~HDMI_AUD_CTS3_CTS_MANUAL;
  87238. + hdmi_writeb(val, HDMI_AUD_CTS3);
  87239. +
  87240. + hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
  87241. + hdmi_writeb((cts >> 8) & 0xff, HDMI_AUD_CTS2);
  87242. + hdmi_writeb(((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
  87243. + HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
  87244. +}
  87245. +
  87246. +static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
  87247. + unsigned int ratio)
  87248. +{
  87249. + unsigned int n = (128 * freq) / 1000;
  87250. +
  87251. + switch (freq) {
  87252. + case 32000:
  87253. + if (pixel_clk == 25174000)
  87254. + n = (ratio == 150) ? 9152 : 4576;
  87255. + else if (pixel_clk == 27020000)
  87256. + n = (ratio == 150) ? 8192 : 4096;
  87257. + else if (pixel_clk == 74170000 || pixel_clk == 148350000)
  87258. + n = 11648;
  87259. + else if (pixel_clk == 297000000)
  87260. + n = (ratio == 150) ? 6144 : 3072;
  87261. + else
  87262. + n = 4096;
  87263. + break;
  87264. +
  87265. + case 44100:
  87266. + if (pixel_clk == 25174000)
  87267. + n = 7007;
  87268. + else if (pixel_clk == 74170000)
  87269. + n = 17836;
  87270. + else if (pixel_clk == 148350000)
  87271. + n = (ratio == 150) ? 17836 : 8918;
  87272. + else if (pixel_clk == 297000000)
  87273. + n = (ratio == 150) ? 9408 : 4704;
  87274. + else
  87275. + n = 6272;
  87276. + break;
  87277. +
  87278. + case 48000:
  87279. + if (pixel_clk == 25174000)
  87280. + n = (ratio == 150) ? 9152 : 6864;
  87281. + else if (pixel_clk == 27020000)
  87282. + n = (ratio == 150) ? 8192 : 6144;
  87283. + else if (pixel_clk == 74170000)
  87284. + n = 11648;
  87285. + else if (pixel_clk == 148350000)
  87286. + n = (ratio == 150) ? 11648 : 5824;
  87287. + else if (pixel_clk == 297000000)
  87288. + n = (ratio == 150) ? 10240 : 5120;
  87289. + else
  87290. + n = 6144;
  87291. + break;
  87292. +
  87293. + case 88200:
  87294. + n = hdmi_compute_n(44100, pixel_clk, ratio) * 2;
  87295. + break;
  87296. +
  87297. + case 96000:
  87298. + n = hdmi_compute_n(48000, pixel_clk, ratio) * 2;
  87299. + break;
  87300. +
  87301. + case 176400:
  87302. + n = hdmi_compute_n(44100, pixel_clk, ratio) * 4;
  87303. + break;
  87304. +
  87305. + case 192000:
  87306. + n = hdmi_compute_n(48000, pixel_clk, ratio) * 4;
  87307. + break;
  87308. +
  87309. + default:
  87310. + break;
  87311. + }
  87312. +
  87313. + return n;
  87314. +}
  87315. +
  87316. +static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
  87317. + unsigned int ratio)
  87318. +{
  87319. + unsigned int cts = 0;
  87320. + switch (freq) {
  87321. + case 32000:
  87322. + if (pixel_clk == 297000000) {
  87323. + cts = 222750;
  87324. + break;
  87325. + } else if (pixel_clk == 25174000) {
  87326. + cts = 28125;
  87327. + break;
  87328. + }
  87329. + case 48000:
  87330. + case 96000:
  87331. + case 192000:
  87332. + switch (pixel_clk) {
  87333. + case 25200000:
  87334. + case 27000000:
  87335. + case 54000000:
  87336. + case 74250000:
  87337. + case 148500000:
  87338. + cts = pixel_clk / 1000;
  87339. + break;
  87340. + case 297000000:
  87341. + cts = 247500;
  87342. + break;
  87343. + case 25174000:
  87344. + cts = 28125l;
  87345. + break;
  87346. + /*
  87347. + * All other TMDS clocks are not supported by
  87348. + * DWC_hdmi_tx. The TMDS clocks divided or
  87349. + * multiplied by 1,001 coefficients are not
  87350. + * supported.
  87351. + */
  87352. + default:
  87353. + break;
  87354. + }
  87355. + break;
  87356. + case 44100:
  87357. + case 88200:
  87358. + case 176400:
  87359. + switch (pixel_clk) {
  87360. + case 25200000:
  87361. + cts = 28000;
  87362. + break;
  87363. + case 25174000:
  87364. + cts = 31250;
  87365. + break;
  87366. + case 27000000:
  87367. + cts = 30000;
  87368. + break;
  87369. + case 54000000:
  87370. + cts = 60000;
  87371. + break;
  87372. + case 74250000:
  87373. + cts = 82500;
  87374. + break;
  87375. + case 148500000:
  87376. + cts = 165000;
  87377. + break;
  87378. + case 297000000:
  87379. + cts = 247500;
  87380. + break;
  87381. + default:
  87382. + break;
  87383. + }
  87384. + break;
  87385. + default:
  87386. + break;
  87387. + }
  87388. + if (ratio == 100)
  87389. + return cts;
  87390. + else
  87391. + return (cts * ratio) / 100;
  87392. +}
  87393. +
  87394. +static void hdmi_set_clk_regenerator(void)
  87395. +{
  87396. + unsigned int clk_n, clk_cts;
  87397. +
  87398. + clk_n = hdmi_compute_n(sample_rate, pixel_clk_rate, hdmi_ratio);
  87399. + clk_cts = hdmi_compute_cts(sample_rate, pixel_clk_rate, hdmi_ratio);
  87400. +
  87401. + if (clk_cts == 0) {
  87402. + pr_debug("%s: pixel clock not supported: %d\n",
  87403. + __func__, (int)pixel_clk_rate);
  87404. + return;
  87405. + }
  87406. +
  87407. + pr_debug("%s: samplerate=%d ratio=%d pixelclk=%d N=%d cts=%d\n",
  87408. + __func__, sample_rate, hdmi_ratio, (int)pixel_clk_rate,
  87409. + clk_n, clk_cts);
  87410. +
  87411. + hdmi_set_clock_regenerator_cts(clk_cts);
  87412. + hdmi_set_clock_regenerator_n(clk_n);
  87413. +}
  87414. +
  87415. +static int hdmi_core_get_of_property(struct platform_device *pdev)
  87416. +{
  87417. + struct device_node *np = pdev->dev.of_node;
  87418. + int err;
  87419. + int ipu_id, disp_id;
  87420. +
  87421. + err = of_property_read_u32(np, "ipu_id", &ipu_id);
  87422. + if (err) {
  87423. + dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
  87424. + return err;
  87425. + }
  87426. + err = of_property_read_u32(np, "disp_id", &disp_id);
  87427. + if (err) {
  87428. + dev_dbg(&pdev->dev, "get of property disp_id fail\n");
  87429. + return err;
  87430. + }
  87431. +
  87432. + mxc_hdmi_ipu_id = ipu_id;
  87433. + mxc_hdmi_disp_id = disp_id;
  87434. +
  87435. + return err;
  87436. +}
  87437. +
  87438. +/* Need to run this before phy is enabled the first time to prevent
  87439. + * overflow condition in HDMI_IH_FC_STAT2 */
  87440. +void hdmi_init_clk_regenerator(void)
  87441. +{
  87442. + if (pixel_clk_rate == 0) {
  87443. + pixel_clk_rate = 74250000;
  87444. + hdmi_set_clk_regenerator();
  87445. + }
  87446. +}
  87447. +EXPORT_SYMBOL(hdmi_init_clk_regenerator);
  87448. +
  87449. +void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock)
  87450. +{
  87451. +
  87452. + /* Translate pixel clock in ps (pico seconds) to Hz */
  87453. + pixel_clk_rate = PICOS2KHZ(pixclock) * 1000UL;
  87454. + hdmi_set_clk_regenerator();
  87455. +}
  87456. +EXPORT_SYMBOL(hdmi_clk_regenerator_update_pixel_clock);
  87457. +
  87458. +void hdmi_set_dma_mode(unsigned int dma_running)
  87459. +{
  87460. + hdmi_dma_running = dma_running;
  87461. + hdmi_set_clk_regenerator();
  87462. +}
  87463. +EXPORT_SYMBOL(hdmi_set_dma_mode);
  87464. +
  87465. +void hdmi_set_sample_rate(unsigned int rate)
  87466. +{
  87467. + sample_rate = rate;
  87468. +}
  87469. +EXPORT_SYMBOL(hdmi_set_sample_rate);
  87470. +
  87471. +void hdmi_set_edid_cfg(int edid_status, struct mxc_edid_cfg *cfg)
  87472. +{
  87473. + unsigned long flags;
  87474. +
  87475. + spin_lock_irqsave(&edid_spinlock, flags);
  87476. + hdmi_core_edid_status = edid_status;
  87477. + memcpy(&hdmi_core_edid_cfg, cfg, sizeof(struct mxc_edid_cfg));
  87478. + spin_unlock_irqrestore(&edid_spinlock, flags);
  87479. +}
  87480. +EXPORT_SYMBOL(hdmi_set_edid_cfg);
  87481. +
  87482. +int hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg)
  87483. +{
  87484. + unsigned long flags;
  87485. +
  87486. + spin_lock_irqsave(&edid_spinlock, flags);
  87487. + memcpy(cfg, &hdmi_core_edid_cfg, sizeof(struct mxc_edid_cfg));
  87488. + spin_unlock_irqrestore(&edid_spinlock, flags);
  87489. +
  87490. + return hdmi_core_edid_status;
  87491. +}
  87492. +EXPORT_SYMBOL(hdmi_get_edid_cfg);
  87493. +
  87494. +void hdmi_set_registered(int registered)
  87495. +{
  87496. + hdmi_core_init = registered;
  87497. +}
  87498. +EXPORT_SYMBOL(hdmi_set_registered);
  87499. +
  87500. +int hdmi_get_registered(void)
  87501. +{
  87502. + return hdmi_core_init;
  87503. +}
  87504. +EXPORT_SYMBOL(hdmi_get_registered);
  87505. +
  87506. +static int mxc_hdmi_core_probe(struct platform_device *pdev)
  87507. +{
  87508. + struct mxc_hdmi_data *hdmi_data;
  87509. + struct resource *res;
  87510. + unsigned long flags;
  87511. + int ret = 0;
  87512. +
  87513. +#ifdef DEBUG
  87514. + overflow_lo = false;
  87515. + overflow_hi = false;
  87516. +#endif
  87517. +
  87518. + hdmi_core_init = 0;
  87519. + hdmi_dma_running = 0;
  87520. +
  87521. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  87522. + if (!res)
  87523. + return -ENOENT;
  87524. +
  87525. + ret = hdmi_core_get_of_property(pdev);
  87526. + if (ret < 0) {
  87527. + dev_err(&pdev->dev, "get hdmi of property fail\n");
  87528. + return -ENOENT;
  87529. + }
  87530. +
  87531. + hdmi_data = devm_kzalloc(&pdev->dev, sizeof(struct mxc_hdmi_data), GFP_KERNEL);
  87532. + if (!hdmi_data) {
  87533. + dev_err(&pdev->dev, "Couldn't allocate mxc hdmi mfd device\n");
  87534. + return -ENOMEM;
  87535. + }
  87536. + hdmi_data->pdev = pdev;
  87537. +
  87538. + pixel_clk = NULL;
  87539. + sample_rate = 48000;
  87540. + pixel_clk_rate = 0;
  87541. + hdmi_ratio = 100;
  87542. +
  87543. + spin_lock_init(&irq_spinlock);
  87544. + spin_lock_init(&edid_spinlock);
  87545. +
  87546. +
  87547. + spin_lock_init(&hdmi_cable_state_lock);
  87548. + spin_lock_init(&hdmi_blank_state_lock);
  87549. + spin_lock_init(&hdmi_audio_lock);
  87550. +
  87551. + spin_lock_irqsave(&hdmi_cable_state_lock, flags);
  87552. + hdmi_cable_state = 0;
  87553. + spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
  87554. +
  87555. + spin_lock_irqsave(&hdmi_blank_state_lock, flags);
  87556. + hdmi_blank_state = 0;
  87557. + spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
  87558. +
  87559. + spin_lock_irqsave(&hdmi_audio_lock, flags);
  87560. + hdmi_audio_stream_playback = NULL;
  87561. + hdmi_abort_state = 0;
  87562. + spin_unlock_irqrestore(&hdmi_audio_lock, flags);
  87563. +
  87564. + isfr_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_isfr");
  87565. + if (IS_ERR(isfr_clk)) {
  87566. + ret = PTR_ERR(isfr_clk);
  87567. + dev_err(&hdmi_data->pdev->dev,
  87568. + "Unable to get HDMI isfr clk: %d\n", ret);
  87569. + goto eclkg;
  87570. + }
  87571. +
  87572. + ret = clk_prepare_enable(isfr_clk);
  87573. + if (ret < 0) {
  87574. + dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret);
  87575. + goto eclke;
  87576. + }
  87577. +
  87578. + pr_debug("%s isfr_clk:%d\n", __func__,
  87579. + (int)clk_get_rate(isfr_clk));
  87580. +
  87581. + iahb_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_iahb");
  87582. + if (IS_ERR(iahb_clk)) {
  87583. + ret = PTR_ERR(iahb_clk);
  87584. + dev_err(&hdmi_data->pdev->dev,
  87585. + "Unable to get HDMI iahb clk: %d\n", ret);
  87586. + goto eclkg2;
  87587. + }
  87588. +
  87589. + ret = clk_prepare_enable(iahb_clk);
  87590. + if (ret < 0) {
  87591. + dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret);
  87592. + goto eclke2;
  87593. + }
  87594. +
  87595. + hdmi_data->reg_phys_base = res->start;
  87596. + if (!request_mem_region(res->start, resource_size(res),
  87597. + dev_name(&pdev->dev))) {
  87598. + dev_err(&pdev->dev, "request_mem_region failed\n");
  87599. + ret = -EBUSY;
  87600. + goto emem;
  87601. + }
  87602. +
  87603. + hdmi_data->reg_base = ioremap(res->start, resource_size(res));
  87604. + if (!hdmi_data->reg_base) {
  87605. + dev_err(&pdev->dev, "ioremap failed\n");
  87606. + ret = -ENOMEM;
  87607. + goto eirq;
  87608. + }
  87609. + hdmi_base = hdmi_data->reg_base;
  87610. +
  87611. + pr_debug("\n%s hdmi hw base = 0x%08x\n\n", __func__, (int)res->start);
  87612. +
  87613. + initialize_hdmi_ih_mutes();
  87614. +
  87615. + /* Disable HDMI clocks until video/audio sub-drivers are initialized */
  87616. + clk_disable_unprepare(isfr_clk);
  87617. + clk_disable_unprepare(iahb_clk);
  87618. +
  87619. + /* Replace platform data coming in with a local struct */
  87620. + platform_set_drvdata(pdev, hdmi_data);
  87621. +
  87622. + return ret;
  87623. +
  87624. +eirq:
  87625. + release_mem_region(res->start, resource_size(res));
  87626. +emem:
  87627. + clk_disable_unprepare(iahb_clk);
  87628. +eclke2:
  87629. + clk_put(iahb_clk);
  87630. +eclkg2:
  87631. + clk_disable_unprepare(isfr_clk);
  87632. +eclke:
  87633. + clk_put(isfr_clk);
  87634. +eclkg:
  87635. + return ret;
  87636. +}
  87637. +
  87638. +
  87639. +static int __exit mxc_hdmi_core_remove(struct platform_device *pdev)
  87640. +{
  87641. + struct mxc_hdmi_data *hdmi_data = platform_get_drvdata(pdev);
  87642. + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  87643. +
  87644. + iounmap(hdmi_data->reg_base);
  87645. + release_mem_region(res->start, resource_size(res));
  87646. +
  87647. + return 0;
  87648. +}
  87649. +
  87650. +static const struct of_device_id imx_hdmi_dt_ids[] = {
  87651. + { .compatible = "fsl,imx6q-hdmi-core", },
  87652. + { .compatible = "fsl,imx6dl-hdmi-core", },
  87653. + { /* sentinel */ }
  87654. +};
  87655. +
  87656. +static struct platform_driver mxc_hdmi_core_driver = {
  87657. + .driver = {
  87658. + .name = "mxc_hdmi_core",
  87659. + .of_match_table = imx_hdmi_dt_ids,
  87660. + .owner = THIS_MODULE,
  87661. + },
  87662. + .remove = __exit_p(mxc_hdmi_core_remove),
  87663. +};
  87664. +
  87665. +static int __init mxc_hdmi_core_init(void)
  87666. +{
  87667. + return platform_driver_probe(&mxc_hdmi_core_driver,
  87668. + mxc_hdmi_core_probe);
  87669. +}
  87670. +
  87671. +static void __exit mxc_hdmi_core_exit(void)
  87672. +{
  87673. + platform_driver_unregister(&mxc_hdmi_core_driver);
  87674. +}
  87675. +
  87676. +subsys_initcall(mxc_hdmi_core_init);
  87677. +module_exit(mxc_hdmi_core_exit);
  87678. +
  87679. +MODULE_DESCRIPTION("Core driver for Freescale i.Mx on-chip HDMI");
  87680. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  87681. +MODULE_LICENSE("GPL");
  87682. diff -Nur linux-3.14.14/drivers/mfd/si476x-cmd.c linux-imx6-3.14/drivers/mfd/si476x-cmd.c
  87683. --- linux-3.14.14/drivers/mfd/si476x-cmd.c 2014-07-28 10:07:25.000000000 -0500
  87684. +++ linux-imx6-3.14/drivers/mfd/si476x-cmd.c 2014-12-08 00:31:53.384418001 -0600
  87685. @@ -303,13 +303,13 @@
  87686. * possible racing conditions when working in polling mode */
  87687. atomic_set(&core->cts, 0);
  87688. - /* if (unlikely(command == CMD_POWER_DOWN) */
  87689. - if (!wait_event_timeout(core->command,
  87690. - atomic_read(&core->cts),
  87691. - usecs_to_jiffies(usecs) + 1))
  87692. - dev_warn(&core->client->dev,
  87693. - "(%s) [CMD 0x%02x] Answer timeout.\n",
  87694. - __func__, command);
  87695. + if (!(command == CMD_POWER_DOWN))
  87696. + if (!wait_event_timeout(core->command,
  87697. + atomic_read(&core->cts),
  87698. + usecs_to_jiffies(usecs) + 1))
  87699. + dev_warn(&core->client->dev,
  87700. + "(%s) [CMD 0x%02x] Answer timeout.\n",
  87701. + __func__, command);
  87702. /*
  87703. When working in polling mode, for some reason the tuner will
  87704. diff -Nur linux-3.14.14/drivers/mfd/si476x-i2c.c linux-imx6-3.14/drivers/mfd/si476x-i2c.c
  87705. --- linux-3.14.14/drivers/mfd/si476x-i2c.c 2014-07-28 10:07:25.000000000 -0500
  87706. +++ linux-imx6-3.14/drivers/mfd/si476x-i2c.c 2014-12-08 00:31:53.384418001 -0600
  87707. @@ -303,7 +303,7 @@
  87708. */
  87709. udelay(100);
  87710. - err = si476x_core_start(core, false);
  87711. + err = si476x_core_start(core, true);
  87712. if (err < 0)
  87713. goto disable_regulators;
  87714. @@ -312,7 +312,7 @@
  87715. case SI476X_POWER_DOWN:
  87716. core->power_state = next_state;
  87717. - err = si476x_core_stop(core, false);
  87718. + err = si476x_core_stop(core, true);
  87719. if (err < 0)
  87720. core->power_state = SI476X_POWER_INCONSISTENT;
  87721. disable_regulators:
  87722. @@ -740,8 +740,15 @@
  87723. memcpy(&core->pinmux, &pdata->pinmux,
  87724. sizeof(struct si476x_pinmux));
  87725. } else {
  87726. - dev_err(&client->dev, "No platform data provided\n");
  87727. - return -EINVAL;
  87728. + dev_warn(&client->dev, "Using default platform data.\n");
  87729. + core->power_up_parameters.xcload = 0x28;
  87730. + core->power_up_parameters.func = SI476X_FUNC_FM_RECEIVER;
  87731. + core->power_up_parameters.freq = SI476X_FREQ_37P209375_MHZ;
  87732. + core->diversity_mode = SI476X_PHDIV_DISABLED;
  87733. + core->pinmux.dclk = SI476X_DCLK_DAUDIO;
  87734. + core->pinmux.dfs = SI476X_DFS_DAUDIO;
  87735. + core->pinmux.dout = SI476X_DOUT_I2S_OUTPUT;
  87736. + core->pinmux.xout = SI476X_XOUT_TRISTATE;
  87737. }
  87738. core->supplies[0].supply = "vd";
  87739. @@ -799,6 +806,10 @@
  87740. core->chip_id = id->driver_data;
  87741. + /* Power down si476x first */
  87742. + core->power_state = SI476X_POWER_UP_FULL;
  87743. + si476x_core_set_power_state(core, SI476X_POWER_DOWN);
  87744. +
  87745. rval = si476x_core_get_revision_info(core);
  87746. if (rval < 0) {
  87747. rval = -ENODEV;
  87748. diff -Nur linux-3.14.14/drivers/mfd/si476x-prop.c linux-imx6-3.14/drivers/mfd/si476x-prop.c
  87749. --- linux-3.14.14/drivers/mfd/si476x-prop.c 2014-07-28 10:07:25.000000000 -0500
  87750. +++ linux-imx6-3.14/drivers/mfd/si476x-prop.c 2014-12-08 00:31:53.388418001 -0600
  87751. @@ -217,15 +217,36 @@
  87752. return 0;
  87753. }
  87754. +static bool si476x_core_regmap_volatile_register(struct device *dev, unsigned int reg)
  87755. +{
  87756. + switch (reg) {
  87757. + case SI476X_PROP_DIGITAL_IO_OUTPUT_SAMPLE_RATE:
  87758. + case SI476X_PROP_DIGITAL_IO_OUTPUT_FORMAT:
  87759. + return false;
  87760. + default:
  87761. + return true;
  87762. + }
  87763. +
  87764. + return true;
  87765. +}
  87766. +
  87767. +/* These two register is used by the codec, so add reg_default here */
  87768. +static struct reg_default si476x_core_reg[] = {
  87769. + { 0x202, 0xBB80 },
  87770. + { 0x203, 0x1700 },
  87771. +};
  87772. static const struct regmap_config si476x_regmap_config = {
  87773. .reg_bits = 16,
  87774. .val_bits = 16,
  87775. .max_register = 0x4003,
  87776. + .reg_defaults = si476x_core_reg,
  87777. + .num_reg_defaults = ARRAY_SIZE(si476x_core_reg),
  87778. .writeable_reg = si476x_core_regmap_writable_register,
  87779. .readable_reg = si476x_core_regmap_readable_register,
  87780. + .volatile_reg = si476x_core_regmap_volatile_register,
  87781. .reg_read = si476x_core_regmap_read,
  87782. .reg_write = si476x_core_regmap_write,
  87783. diff -Nur linux-3.14.14/drivers/misc/sram.c linux-imx6-3.14/drivers/misc/sram.c
  87784. --- linux-3.14.14/drivers/misc/sram.c 2014-07-28 10:07:25.000000000 -0500
  87785. +++ linux-imx6-3.14/drivers/misc/sram.c 2014-12-08 00:31:53.412418001 -0600
  87786. @@ -29,7 +29,7 @@
  87787. #include <linux/spinlock.h>
  87788. #include <linux/genalloc.h>
  87789. -#define SRAM_GRANULARITY 32
  87790. +#define SRAM_GRANULARITY 4096
  87791. struct sram_dev {
  87792. struct gen_pool *pool;
  87793. diff -Nur linux-3.14.14/drivers/mmc/core/core.c linux-imx6-3.14/drivers/mmc/core/core.c
  87794. --- linux-3.14.14/drivers/mmc/core/core.c 2014-07-28 10:07:25.000000000 -0500
  87795. +++ linux-imx6-3.14/drivers/mmc/core/core.c 2014-12-08 00:31:53.416418001 -0600
  87796. @@ -13,11 +13,13 @@
  87797. #include <linux/module.h>
  87798. #include <linux/init.h>
  87799. #include <linux/interrupt.h>
  87800. +#include <linux/clk.h>
  87801. #include <linux/completion.h>
  87802. #include <linux/device.h>
  87803. #include <linux/delay.h>
  87804. #include <linux/pagemap.h>
  87805. #include <linux/err.h>
  87806. +#include <linux/gpio.h>
  87807. #include <linux/leds.h>
  87808. #include <linux/scatterlist.h>
  87809. #include <linux/log2.h>
  87810. @@ -1519,6 +1521,43 @@
  87811. mmc_host_clk_release(host);
  87812. }
  87813. +static void mmc_card_power_up(struct mmc_host *host)
  87814. +{
  87815. + int i;
  87816. + struct gpio_desc **gds = host->card_reset_gpios;
  87817. +
  87818. + for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
  87819. + if (gds[i]) {
  87820. + dev_dbg(host->parent, "Asserting reset line %d", i);
  87821. + gpiod_set_value(gds[i], 1);
  87822. + }
  87823. + }
  87824. +
  87825. + if (host->card_regulator) {
  87826. + dev_dbg(host->parent, "Enabling external regulator");
  87827. + if (regulator_enable(host->card_regulator))
  87828. + dev_err(host->parent, "Failed to enable external regulator");
  87829. + }
  87830. +
  87831. + if (host->card_clk) {
  87832. + dev_dbg(host->parent, "Enabling external clock");
  87833. + clk_prepare_enable(host->card_clk);
  87834. + }
  87835. +
  87836. + /* 2ms delay to let clocks and power settle */
  87837. + mmc_delay(20);
  87838. +
  87839. + for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
  87840. + if (gds[i]) {
  87841. + dev_dbg(host->parent, "Deasserting reset line %d", i);
  87842. + gpiod_set_value(gds[i], 0);
  87843. + }
  87844. + }
  87845. +
  87846. + /* 2ms delay to after reset release */
  87847. + mmc_delay(20);
  87848. +}
  87849. +
  87850. /*
  87851. * Apply power to the MMC stack. This is a two-stage process.
  87852. * First, we enable power to the card without the clock running.
  87853. @@ -1535,6 +1574,9 @@
  87854. if (host->ios.power_mode == MMC_POWER_ON)
  87855. return;
  87856. + /* Power up the card/module first, if needed */
  87857. + mmc_card_power_up(host);
  87858. +
  87859. mmc_host_clk_hold(host);
  87860. host->ios.vdd = fls(ocr) - 1;
  87861. diff -Nur linux-3.14.14/drivers/mmc/core/host.c linux-imx6-3.14/drivers/mmc/core/host.c
  87862. --- linux-3.14.14/drivers/mmc/core/host.c 2014-07-28 10:07:25.000000000 -0500
  87863. +++ linux-imx6-3.14/drivers/mmc/core/host.c 2014-12-08 00:31:53.416418001 -0600
  87864. @@ -12,14 +12,18 @@
  87865. * MMC host class device management
  87866. */
  87867. +#include <linux/kernel.h>
  87868. +#include <linux/clk.h>
  87869. #include <linux/device.h>
  87870. #include <linux/err.h>
  87871. +#include <linux/gpio/consumer.h>
  87872. #include <linux/idr.h>
  87873. #include <linux/of.h>
  87874. #include <linux/of_gpio.h>
  87875. #include <linux/pagemap.h>
  87876. #include <linux/export.h>
  87877. #include <linux/leds.h>
  87878. +#include <linux/regulator/consumer.h>
  87879. #include <linux/slab.h>
  87880. #include <linux/suspend.h>
  87881. @@ -439,6 +443,66 @@
  87882. EXPORT_SYMBOL(mmc_of_parse);
  87883. +static int mmc_of_parse_child(struct mmc_host *host)
  87884. +{
  87885. + struct device_node *np;
  87886. + struct clk *clk;
  87887. + int i;
  87888. +
  87889. + if (!host->parent || !host->parent->of_node)
  87890. + return 0;
  87891. +
  87892. + np = host->parent->of_node;
  87893. +
  87894. + host->card_regulator = regulator_get(host->parent, "card-external-vcc");
  87895. + if (IS_ERR(host->card_regulator)) {
  87896. + if (PTR_ERR(host->card_regulator) == -EPROBE_DEFER)
  87897. + return PTR_ERR(host->card_regulator);
  87898. + host->card_regulator = NULL;
  87899. + }
  87900. +
  87901. + /* Parse card power/reset/clock control */
  87902. + if (of_find_property(np, "card-reset-gpios", NULL)) {
  87903. + struct gpio_desc *gpd;
  87904. + int level = 0;
  87905. +
  87906. + /*
  87907. + * If the regulator is enabled, then we can hold the
  87908. + * card in reset with an active high resets. Otherwise,
  87909. + * hold the resets low.
  87910. + */
  87911. + if (host->card_regulator && regulator_is_enabled(host->card_regulator))
  87912. + level = 1;
  87913. +
  87914. + for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
  87915. + gpd = devm_gpiod_get_index(host->parent, "card-reset", i);
  87916. + if (IS_ERR(gpd)) {
  87917. + if (PTR_ERR(gpd) == -EPROBE_DEFER)
  87918. + return PTR_ERR(gpd);
  87919. + break;
  87920. + }
  87921. + gpiod_direction_output(gpd, gpiod_is_active_low(gpd) | level);
  87922. + host->card_reset_gpios[i] = gpd;
  87923. + }
  87924. +
  87925. + gpd = devm_gpiod_get_index(host->parent, "card-reset", ARRAY_SIZE(host->card_reset_gpios));
  87926. + if (!IS_ERR(gpd)) {
  87927. + dev_warn(host->parent, "More reset gpios than we can handle");
  87928. + gpiod_put(gpd);
  87929. + }
  87930. + }
  87931. +
  87932. + clk = of_clk_get_by_name(np, "card_ext_clock");
  87933. + if (IS_ERR(clk)) {
  87934. + if (PTR_ERR(clk) == -EPROBE_DEFER)
  87935. + return PTR_ERR(clk);
  87936. + clk = NULL;
  87937. + }
  87938. + host->card_clk = clk;
  87939. +
  87940. + return 0;
  87941. +}
  87942. +
  87943. /**
  87944. * mmc_alloc_host - initialise the per-host structure.
  87945. * @extra: sizeof private data structure
  87946. @@ -518,6 +582,10 @@
  87947. {
  87948. int err;
  87949. + err = mmc_of_parse_child(host);
  87950. + if (err)
  87951. + return err;
  87952. +
  87953. WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
  87954. !host->ops->enable_sdio_irq);
  87955. diff -Nur linux-3.14.14/drivers/mmc/core/mmc.c linux-imx6-3.14/drivers/mmc/core/mmc.c
  87956. --- linux-3.14.14/drivers/mmc/core/mmc.c 2014-07-28 10:07:25.000000000 -0500
  87957. +++ linux-imx6-3.14/drivers/mmc/core/mmc.c 2014-12-08 00:31:53.420418001 -0600
  87958. @@ -317,6 +317,11 @@
  87959. mmc_card_set_blockaddr(card);
  87960. }
  87961. + card->ext_csd.boot_info = ext_csd[EXT_CSD_BOOT_INFO];
  87962. + card->ext_csd.boot_config = ext_csd[EXT_CSD_PART_CONFIG];
  87963. + card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT];
  87964. + card->ext_csd.boot_bus_width = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
  87965. +
  87966. card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
  87967. mmc_select_card_type(card);
  87968. @@ -655,6 +660,372 @@
  87969. return err;
  87970. }
  87971. +static ssize_t mmc_boot_info_show(struct device *dev,
  87972. + struct device_attribute *attr, char *buf)
  87973. +{
  87974. + char *boot_partition[8] = {
  87975. + "Device not boot enabled",
  87976. + "Boot partition 1 enabled",
  87977. + "Boot partition 2 enabled",
  87978. + "Reserved",
  87979. + "Reserved",
  87980. + "Reserved",
  87981. + "Reserved",
  87982. + "User area enabled for boot"};
  87983. +
  87984. + char *bus_width[4] = {
  87985. + "x1 (sdr) or x4 (ddr) bus width in boot operation mode",
  87986. + "x4 (sdr/ddr) bus width in boot operation mode",
  87987. + "x8 (sdr/ddr) bus width in boot operation mode",
  87988. + "Reserved"};
  87989. +
  87990. + char *boot_mode[4] = {
  87991. + "Use single data rate + backward compatible timings in boot operation",
  87992. + "Use single data rate + high speed timings in boot operation mode",
  87993. + "Use dual data rate in boot operation",
  87994. + "Reserved"};
  87995. +
  87996. + int partition;
  87997. + int width;
  87998. + int mode;
  87999. + int err;
  88000. + u8 *ext_csd = NULL;
  88001. + struct mmc_card *card = container_of(dev, struct mmc_card, dev);
  88002. +
  88003. + /* read it again because user may change it */
  88004. + mmc_claim_host(card->host);
  88005. + err = mmc_get_ext_csd(card, &ext_csd);
  88006. + mmc_release_host(card->host);
  88007. + if (err || !ext_csd) {
  88008. + pr_err("%s: failed to get ext_csd, err=%d\n",
  88009. + mmc_hostname(card->host),
  88010. + err);
  88011. + return err;
  88012. + }
  88013. +
  88014. + mmc_read_ext_csd(card, ext_csd);
  88015. + mmc_free_ext_csd(ext_csd);
  88016. +
  88017. + partition = (card->ext_csd.boot_config >> 3) & 0x7;
  88018. + width = card->ext_csd.boot_bus_width & 0x3;
  88019. + mode = (card->ext_csd.boot_bus_width >> 3) & 0x3;
  88020. +
  88021. + return sprintf(buf,
  88022. + "boot_info:0x%02x;\n"
  88023. + " ALT_BOOT_MODE:%x - %s\n"
  88024. + " DDR_BOOT_MODE:%x - %s\n"
  88025. + " HS_BOOTMODE:%x - %s\n"
  88026. + "boot_size:%04dKB\n"
  88027. + "boot_partition:0x%02x;\n"
  88028. + " BOOT_ACK:%x - %s\n"
  88029. + " BOOT_PARTITION-ENABLE: %x - %s\n"
  88030. + "boot_bus:0x%02x\n"
  88031. + " BOOT_MODE:%x - %s\n"
  88032. + " RESET_BOOT_BUS_WIDTH:%x - %s\n"
  88033. + " BOOT_BUS_WIDTH:%x - %s\n",
  88034. +
  88035. + card->ext_csd.boot_info,
  88036. + !!(card->ext_csd.boot_info & 0x1),
  88037. + (card->ext_csd.boot_info & 0x1) ?
  88038. + "Supports alternate boot method" :
  88039. + "Does not support alternate boot method",
  88040. + !!(card->ext_csd.boot_info & 0x2),
  88041. + (card->ext_csd.boot_info & 0x2) ?
  88042. + "Supports alternate dual data rate during boot" :
  88043. + "Does not support dual data rate during boot",
  88044. + !!(card->ext_csd.boot_info & 0x4),
  88045. + (card->ext_csd.boot_info & 0x4) ?
  88046. + "Supports high speed timing during boot" :
  88047. + "Does not support high speed timing during boot",
  88048. +
  88049. + card->ext_csd.boot_size * 128,
  88050. +
  88051. + card->ext_csd.boot_config,
  88052. + !!(card->ext_csd.boot_config & 0x40),
  88053. + (card->ext_csd.boot_config & 0x40) ?
  88054. + "Boot acknowledge sent during boot operation" :
  88055. + "No boot acknowledge sent",
  88056. + partition,
  88057. + boot_partition[partition],
  88058. +
  88059. + card->ext_csd.boot_bus_width,
  88060. + mode,
  88061. + boot_mode[mode],
  88062. + !!(card->ext_csd.boot_bus_width & 0x4),
  88063. + (card->ext_csd.boot_bus_width & 0x4) ?
  88064. + "Retain boot bus width and boot mode after boot operation" :
  88065. + "Reset bus width to x1, single data rate and backward"
  88066. + "compatible timings after boot operation",
  88067. + width,
  88068. + bus_width[width]);
  88069. +}
  88070. +
  88071. +/* set up boot partitions */
  88072. +static ssize_t
  88073. +setup_boot_partitions(struct device *dev, struct device_attribute *attr,
  88074. + const char *buf, size_t count)
  88075. +{
  88076. + int err, busy = 0;
  88077. + u32 part;
  88078. + u8 *ext_csd, boot_config;
  88079. + struct mmc_command cmd;
  88080. + struct mmc_card *card = container_of(dev, struct mmc_card, dev);
  88081. +
  88082. + BUG_ON(!card);
  88083. +
  88084. + sscanf(buf, "%d\n", &part);
  88085. +
  88086. + if (card->csd.mmca_vsn < CSD_SPEC_VER_4) {
  88087. + pr_err("%s: invalid mmc version" \
  88088. + " mmc version is below version 4!)\n",
  88089. + mmc_hostname(card->host));
  88090. + return -EINVAL;
  88091. + }
  88092. +
  88093. + /* it's a normal SD/MMC but user request to configure boot partition */
  88094. + if (card->ext_csd.boot_size <= 0) {
  88095. + pr_err("%s: fail to send SWITCH command to card " \
  88096. + "to update boot_config of the EXT_CSD!\n",
  88097. + mmc_hostname(card->host));
  88098. + return -EINVAL;
  88099. + }
  88100. +
  88101. + /*
  88102. + * partition must be -
  88103. + * 0 - user area
  88104. + * 1 - boot partition 1
  88105. + * 2 - boot partition 2
  88106. + * DO NOT switch the partitions that used to be accessed
  88107. + * in OS layer HERE
  88108. + */
  88109. + if (part & EXT_CSD_BOOT_PARTITION_ACCESS_MASK) {
  88110. + pr_err("%s: DO NOT switch the partitions that used to be\n" \
  88111. + " accessed in OS layer HERE. please following the\n" \
  88112. + " guidance of Documentation/mmc/mmc-dev-parts.txt.\n",
  88113. + mmc_hostname(card->host));
  88114. + return -EINVAL;
  88115. + }
  88116. +
  88117. + ext_csd = kmalloc(512, GFP_KERNEL);
  88118. + if (!ext_csd) {
  88119. + pr_err("%s: could not allocate a buffer to " \
  88120. + "receive the ext_csd.\n", mmc_hostname(card->host));
  88121. + return -ENOMEM;
  88122. + }
  88123. +
  88124. + mmc_claim_host(card->host);
  88125. + err = mmc_send_ext_csd(card, ext_csd);
  88126. + if (err) {
  88127. + pr_err("%s: unable to read EXT_CSD.\n",
  88128. + mmc_hostname(card->host));
  88129. + goto err_rtn;
  88130. + }
  88131. +
  88132. + /* enable the boot partition in boot mode */
  88133. + /* boot enable be -
  88134. + * 0x00 - disable boot enable.
  88135. + * 0x08 - boot partition 1 is enabled for boot.
  88136. + * 0x10 - boot partition 2 is enabled for boot.
  88137. + * 0x38 - User area is enabled for boot.
  88138. + */
  88139. + switch (part & EXT_CSD_BOOT_PARTITION_ENABLE_MASK) {
  88140. + case 0:
  88141. + boot_config = (ext_csd[EXT_CSD_PART_CONFIG]
  88142. + & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK
  88143. + & ~EXT_CSD_BOOT_ACK_ENABLE);
  88144. + break;
  88145. + case EXT_CSD_BOOT_PARTITION_PART1:
  88146. + boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
  88147. + & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
  88148. + | EXT_CSD_BOOT_PARTITION_PART1
  88149. + | EXT_CSD_BOOT_ACK_ENABLE);
  88150. + break;
  88151. + case EXT_CSD_BOOT_PARTITION_PART2:
  88152. + boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
  88153. + & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
  88154. + | EXT_CSD_BOOT_PARTITION_PART2
  88155. + | EXT_CSD_BOOT_ACK_ENABLE);
  88156. + break;
  88157. + case EXT_CSD_BOOT_PARTITION_ENABLE_MASK:
  88158. + boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
  88159. + | EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
  88160. + & ~EXT_CSD_BOOT_ACK_ENABLE);
  88161. + break;
  88162. + default:
  88163. + pr_err("%s: wrong boot config parameter" \
  88164. + " 00 (disable boot), 08 (enable boot1)," \
  88165. + "16 (enable boot2), 56 (User area)\n",
  88166. + mmc_hostname(card->host));
  88167. + err = -EINVAL;
  88168. + goto err_rtn;
  88169. + }
  88170. +
  88171. + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
  88172. + EXT_CSD_PART_CONFIG, boot_config, card->ext_csd.part_time);
  88173. + if (err) {
  88174. + pr_err("%s: fail to send SWITCH command to card " \
  88175. + "to update boot_config of the EXT_CSD!\n",
  88176. + mmc_hostname(card->host));
  88177. + goto err_rtn;
  88178. + }
  88179. +
  88180. + /* waiting for the card to finish the busy state */
  88181. + do {
  88182. + memset(&cmd, 0, sizeof(struct mmc_command));
  88183. +
  88184. + cmd.opcode = MMC_SEND_STATUS;
  88185. + cmd.arg = card->rca << 16;
  88186. + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
  88187. +
  88188. + err = mmc_wait_for_cmd(card->host, &cmd, 0);
  88189. + if (err || busy > 100) {
  88190. + pr_err("%s: failed to wait for" \
  88191. + "the busy state to end.\n",
  88192. + mmc_hostname(card->host));
  88193. + break;
  88194. + }
  88195. +
  88196. + if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
  88197. + pr_info("%s: card is in busy state" \
  88198. + "pls wait for busy state to end.\n",
  88199. + mmc_hostname(card->host));
  88200. + }
  88201. + busy++;
  88202. + } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
  88203. +
  88204. + /* Now check whether it works */
  88205. + err = mmc_send_ext_csd(card, ext_csd);
  88206. + if (err) {
  88207. + pr_err("%s: %d unable to re-read EXT_CSD.\n",
  88208. + mmc_hostname(card->host), err);
  88209. + goto err_rtn;
  88210. + }
  88211. +
  88212. + card->ext_csd.boot_config = ext_csd[EXT_CSD_PART_CONFIG];
  88213. +
  88214. +err_rtn:
  88215. + mmc_release_host(card->host);
  88216. + kfree(ext_csd);
  88217. + if (err)
  88218. + return err;
  88219. + else
  88220. + return count;
  88221. +}
  88222. +
  88223. +/* configure the boot bus */
  88224. +static ssize_t
  88225. +setup_boot_bus(struct device *dev, struct device_attribute *attr,
  88226. + const char *buf, size_t count)
  88227. +{
  88228. + int err, busy = 0;
  88229. + u32 boot_bus, new_bus;
  88230. + u8 *ext_csd;
  88231. + struct mmc_command cmd;
  88232. + struct mmc_card *card = container_of(dev, struct mmc_card, dev);
  88233. +
  88234. + BUG_ON(!card);
  88235. +
  88236. + sscanf(buf, "%d\n", &boot_bus);
  88237. +
  88238. + if (card->csd.mmca_vsn < CSD_SPEC_VER_4) {
  88239. + pr_err("%s: invalid mmc version" \
  88240. + " mmc version is below version 4!)\n",
  88241. + mmc_hostname(card->host));
  88242. + return -EINVAL;
  88243. + }
  88244. +
  88245. + /* it's a normal SD/MMC but user request to configure boot bus */
  88246. + if (card->ext_csd.boot_size <= 0) {
  88247. + pr_err("%s: this is a normal SD/MMC card" \
  88248. + " but you request to configure boot bus !\n",
  88249. + mmc_hostname(card->host));
  88250. + return -EINVAL;
  88251. + }
  88252. +
  88253. + ext_csd = kmalloc(512, GFP_KERNEL);
  88254. + if (!ext_csd) {
  88255. + pr_err("%s: could not allocate a buffer to " \
  88256. + "receive the ext_csd.\n", mmc_hostname(card->host));
  88257. + return -ENOMEM;
  88258. + }
  88259. +
  88260. + mmc_claim_host(card->host);
  88261. + err = mmc_send_ext_csd(card, ext_csd);
  88262. + if (err) {
  88263. + pr_err("%s: unable to read EXT_CSD.\n",
  88264. + mmc_hostname(card->host));
  88265. + goto err_rtn;
  88266. + }
  88267. +
  88268. + /* Configure the boot bus width when boot partition is enabled */
  88269. + if (((boot_bus & EXT_CSD_BOOT_BUS_WIDTH_MODE_MASK) >> 3) > 2
  88270. + || (boot_bus & EXT_CSD_BOOT_BUS_WIDTH_WIDTH_MASK) > 2
  88271. + || (boot_bus & ~EXT_CSD_BOOT_BUS_WIDTH_MASK) > 0) {
  88272. + pr_err("%s: Invalid inputs!\n",
  88273. + mmc_hostname(card->host));
  88274. + err = -EINVAL;
  88275. + goto err_rtn;
  88276. + }
  88277. +
  88278. + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
  88279. + EXT_CSD_BOOT_BUS_WIDTH, boot_bus, card->ext_csd.part_time);
  88280. + if (err) {
  88281. + pr_err("%s: fail to send SWITCH command to card " \
  88282. + "to update boot_config of the EXT_CSD!\n",
  88283. + mmc_hostname(card->host));
  88284. + goto err_rtn;
  88285. + }
  88286. +
  88287. + /* waiting for the card to finish the busy state */
  88288. + do {
  88289. + memset(&cmd, 0, sizeof(struct mmc_command));
  88290. +
  88291. + cmd.opcode = MMC_SEND_STATUS;
  88292. + cmd.arg = card->rca << 16;
  88293. + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
  88294. +
  88295. + err = mmc_wait_for_cmd(card->host, &cmd, 0);
  88296. + if (err || busy > 100) {
  88297. + pr_err("%s: failed to wait for" \
  88298. + "the busy state to end.\n",
  88299. + mmc_hostname(card->host));
  88300. + break;
  88301. + }
  88302. +
  88303. + if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
  88304. + pr_info("%s: card is in busy state" \
  88305. + "pls wait for busy state to end.\n",
  88306. + mmc_hostname(card->host));
  88307. + }
  88308. + busy++;
  88309. + } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
  88310. +
  88311. + /* Now check whether it works */
  88312. + err = mmc_send_ext_csd(card, ext_csd);
  88313. + if (err) {
  88314. + pr_err("%s: %d unable to re-read EXT_CSD.\n",
  88315. + mmc_hostname(card->host), err);
  88316. + goto err_rtn;
  88317. + }
  88318. +
  88319. + new_bus = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
  88320. + if (boot_bus != new_bus) {
  88321. + pr_err("%s: after SWITCH, current boot bus mode %d" \
  88322. + " is not same as requested bus mode %d!\n",
  88323. + mmc_hostname(card->host), new_bus, boot_bus);
  88324. + goto err_rtn;
  88325. + }
  88326. + card->ext_csd.boot_bus_width = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
  88327. +
  88328. +err_rtn:
  88329. + mmc_release_host(card->host);
  88330. + mmc_free_ext_csd(ext_csd);
  88331. + if (err)
  88332. + return err;
  88333. + else
  88334. + return count;
  88335. +}
  88336. +
  88337. MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
  88338. card->raw_cid[2], card->raw_cid[3]);
  88339. MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
  88340. @@ -674,6 +1045,9 @@
  88341. MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
  88342. MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
  88343. MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
  88344. +DEVICE_ATTR(boot_info, S_IRUGO, mmc_boot_info_show, NULL);
  88345. +DEVICE_ATTR(boot_config, S_IWUGO, NULL, setup_boot_partitions);
  88346. +DEVICE_ATTR(boot_bus_config, S_IWUGO, NULL, setup_boot_bus);
  88347. static struct attribute *mmc_std_attrs[] = {
  88348. &dev_attr_cid.attr,
  88349. @@ -692,6 +1066,9 @@
  88350. &dev_attr_enhanced_area_size.attr,
  88351. &dev_attr_raw_rpmb_size_mult.attr,
  88352. &dev_attr_rel_sectors.attr,
  88353. + &dev_attr_boot_info.attr,
  88354. + &dev_attr_boot_config.attr,
  88355. + &dev_attr_boot_bus_config.attr,
  88356. NULL,
  88357. };
  88358. diff -Nur linux-3.14.14/drivers/mmc/core/sdio_irq.c linux-imx6-3.14/drivers/mmc/core/sdio_irq.c
  88359. --- linux-3.14.14/drivers/mmc/core/sdio_irq.c 2014-07-28 10:07:25.000000000 -0500
  88360. +++ linux-imx6-3.14/drivers/mmc/core/sdio_irq.c 2014-12-08 00:31:53.420418001 -0600
  88361. @@ -90,6 +90,15 @@
  88362. return ret;
  88363. }
  88364. +void sdio_run_irqs(struct mmc_host *host)
  88365. +{
  88366. + mmc_claim_host(host);
  88367. + host->sdio_irq_pending = true;
  88368. + process_sdio_pending_irqs(host);
  88369. + mmc_release_host(host);
  88370. +}
  88371. +EXPORT_SYMBOL_GPL(sdio_run_irqs);
  88372. +
  88373. static int sdio_irq_thread(void *_host)
  88374. {
  88375. struct mmc_host *host = _host;
  88376. @@ -189,14 +198,20 @@
  88377. WARN_ON(!host->claimed);
  88378. if (!host->sdio_irqs++) {
  88379. - atomic_set(&host->sdio_irq_thread_abort, 0);
  88380. - host->sdio_irq_thread =
  88381. - kthread_run(sdio_irq_thread, host, "ksdioirqd/%s",
  88382. - mmc_hostname(host));
  88383. - if (IS_ERR(host->sdio_irq_thread)) {
  88384. - int err = PTR_ERR(host->sdio_irq_thread);
  88385. - host->sdio_irqs--;
  88386. - return err;
  88387. + if (!(host->caps2 & MMC_CAP2_SDIO_NOTHREAD)) {
  88388. + atomic_set(&host->sdio_irq_thread_abort, 0);
  88389. + host->sdio_irq_thread =
  88390. + kthread_run(sdio_irq_thread, host,
  88391. + "ksdioirqd/%s", mmc_hostname(host));
  88392. + if (IS_ERR(host->sdio_irq_thread)) {
  88393. + int err = PTR_ERR(host->sdio_irq_thread);
  88394. + host->sdio_irqs--;
  88395. + return err;
  88396. + }
  88397. + } else {
  88398. + mmc_host_clk_hold(host);
  88399. + host->ops->enable_sdio_irq(host, 1);
  88400. + mmc_host_clk_release(host);
  88401. }
  88402. }
  88403. @@ -211,8 +226,14 @@
  88404. BUG_ON(host->sdio_irqs < 1);
  88405. if (!--host->sdio_irqs) {
  88406. - atomic_set(&host->sdio_irq_thread_abort, 1);
  88407. - kthread_stop(host->sdio_irq_thread);
  88408. + if (!(host->caps2 & MMC_CAP2_SDIO_NOTHREAD)) {
  88409. + atomic_set(&host->sdio_irq_thread_abort, 1);
  88410. + kthread_stop(host->sdio_irq_thread);
  88411. + } else {
  88412. + mmc_host_clk_hold(host);
  88413. + host->ops->enable_sdio_irq(host, 0);
  88414. + mmc_host_clk_release(host);
  88415. + }
  88416. }
  88417. return 0;
  88418. diff -Nur linux-3.14.14/drivers/mmc/host/dw_mmc.c linux-imx6-3.14/drivers/mmc/host/dw_mmc.c
  88419. --- linux-3.14.14/drivers/mmc/host/dw_mmc.c 2014-07-28 10:07:25.000000000 -0500
  88420. +++ linux-imx6-3.14/drivers/mmc/host/dw_mmc.c 2014-12-08 00:31:53.424418001 -0600
  88421. @@ -2140,6 +2140,8 @@
  88422. if (!mmc)
  88423. return -ENOMEM;
  88424. + mmc_of_parse(mmc);
  88425. +
  88426. slot = mmc_priv(mmc);
  88427. slot->id = id;
  88428. slot->mmc = mmc;
  88429. diff -Nur linux-3.14.14/drivers/mmc/host/Kconfig linux-imx6-3.14/drivers/mmc/host/Kconfig
  88430. --- linux-3.14.14/drivers/mmc/host/Kconfig 2014-07-28 10:07:25.000000000 -0500
  88431. +++ linux-imx6-3.14/drivers/mmc/host/Kconfig 2014-12-08 00:31:53.420418001 -0600
  88432. @@ -25,8 +25,7 @@
  88433. If unsure, say N.
  88434. config MMC_SDHCI
  88435. - tristate "Secure Digital Host Controller Interface support"
  88436. - depends on HAS_DMA
  88437. + tristate
  88438. help
  88439. This selects the generic Secure Digital Host Controller Interface.
  88440. It is used by manufacturers such as Texas Instruments(R), Ricoh(R)
  88441. @@ -59,7 +58,8 @@
  88442. config MMC_SDHCI_PCI
  88443. tristate "SDHCI support on PCI bus"
  88444. - depends on MMC_SDHCI && PCI
  88445. + depends on PCI && HAS_DMA
  88446. + select MMC_SDHCI
  88447. help
  88448. This selects the PCI Secure Digital Host Controller Interface.
  88449. Most controllers found today are PCI devices.
  88450. @@ -83,7 +83,8 @@
  88451. config MMC_SDHCI_ACPI
  88452. tristate "SDHCI support for ACPI enumerated SDHCI controllers"
  88453. - depends on MMC_SDHCI && ACPI
  88454. + depends on ACPI && HAS_DMA
  88455. + select MMC_SDHCI
  88456. help
  88457. This selects support for ACPI enumerated SDHCI controllers,
  88458. identified by ACPI Compatibility ID PNP0D40 or specific
  88459. @@ -94,8 +95,8 @@
  88460. If unsure, say N.
  88461. config MMC_SDHCI_PLTFM
  88462. - tristate "SDHCI platform and OF driver helper"
  88463. - depends on MMC_SDHCI
  88464. + tristate
  88465. + select MMC_SDHCI
  88466. help
  88467. This selects the common helper functions support for Secure Digital
  88468. Host Controller Interface based platform and OF drivers.
  88469. @@ -106,8 +107,8 @@
  88470. config MMC_SDHCI_OF_ARASAN
  88471. tristate "SDHCI OF support for the Arasan SDHCI controllers"
  88472. - depends on MMC_SDHCI_PLTFM
  88473. - depends on OF
  88474. + depends on OF && HAS_DMA
  88475. + select MMC_SDHCI_PLTFM
  88476. help
  88477. This selects the Arasan Secure Digital Host Controller Interface
  88478. (SDHCI). This hardware is found e.g. in Xilinx' Zynq SoC.
  88479. @@ -118,9 +119,9 @@
  88480. config MMC_SDHCI_OF_ESDHC
  88481. tristate "SDHCI OF support for the Freescale eSDHC controller"
  88482. - depends on MMC_SDHCI_PLTFM
  88483. - depends on PPC_OF
  88484. + depends on PPC_OF && HAS_DMA
  88485. select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
  88486. + select MMC_SDHCI_PLTFM
  88487. help
  88488. This selects the Freescale eSDHC controller support.
  88489. @@ -130,9 +131,9 @@
  88490. config MMC_SDHCI_OF_HLWD
  88491. tristate "SDHCI OF support for the Nintendo Wii SDHCI controllers"
  88492. - depends on MMC_SDHCI_PLTFM
  88493. - depends on PPC_OF
  88494. + depends on PPC_OF && HAS_DMA
  88495. select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
  88496. + select MMC_SDHCI_PLTFM
  88497. help
  88498. This selects the Secure Digital Host Controller Interface (SDHCI)
  88499. found in the "Hollywood" chipset of the Nintendo Wii video game
  88500. @@ -144,8 +145,8 @@
  88501. config MMC_SDHCI_CNS3XXX
  88502. tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
  88503. - depends on ARCH_CNS3XXX
  88504. - depends on MMC_SDHCI_PLTFM
  88505. + depends on ARCH_CNS3XXX && HAS_DMA
  88506. + select MMC_SDHCI_PLTFM
  88507. help
  88508. This selects the SDHCI support for CNS3xxx System-on-Chip devices.
  88509. @@ -155,9 +156,9 @@
  88510. config MMC_SDHCI_ESDHC_IMX
  88511. tristate "SDHCI support for the Freescale eSDHC/uSDHC i.MX controller"
  88512. - depends on ARCH_MXC
  88513. - depends on MMC_SDHCI_PLTFM
  88514. + depends on ARCH_MXC && HAS_DMA
  88515. select MMC_SDHCI_IO_ACCESSORS
  88516. + select MMC_SDHCI_PLTFM
  88517. help
  88518. This selects the Freescale eSDHC/uSDHC controller support
  88519. found on i.MX25, i.MX35 i.MX5x and i.MX6x.
  88520. @@ -168,9 +169,9 @@
  88521. config MMC_SDHCI_DOVE
  88522. tristate "SDHCI support on Marvell's Dove SoC"
  88523. - depends on ARCH_DOVE
  88524. - depends on MMC_SDHCI_PLTFM
  88525. + depends on ARCH_DOVE && HAS_DMA
  88526. select MMC_SDHCI_IO_ACCESSORS
  88527. + select MMC_SDHCI_PLTFM
  88528. help
  88529. This selects the Secure Digital Host Controller Interface in
  88530. Marvell's Dove SoC.
  88531. @@ -181,9 +182,9 @@
  88532. config MMC_SDHCI_TEGRA
  88533. tristate "SDHCI platform support for the Tegra SD/MMC Controller"
  88534. - depends on ARCH_TEGRA
  88535. - depends on MMC_SDHCI_PLTFM
  88536. + depends on ARCH_TEGRA && HAS_DMA
  88537. select MMC_SDHCI_IO_ACCESSORS
  88538. + select MMC_SDHCI_PLTFM
  88539. help
  88540. This selects the Tegra SD/MMC controller. If you have a Tegra
  88541. platform with SD or MMC devices, say Y or M here.
  88542. @@ -192,7 +193,8 @@
  88543. config MMC_SDHCI_S3C
  88544. tristate "SDHCI support on Samsung S3C SoC"
  88545. - depends on MMC_SDHCI && PLAT_SAMSUNG
  88546. + depends on PLAT_SAMSUNG && HAS_DMA
  88547. + select MMC_SDHCI
  88548. help
  88549. This selects the Secure Digital Host Controller Interface (SDHCI)
  88550. often referrered to as the HSMMC block in some of the Samsung S3C
  88551. @@ -204,8 +206,8 @@
  88552. config MMC_SDHCI_SIRF
  88553. tristate "SDHCI support on CSR SiRFprimaII and SiRFmarco SoCs"
  88554. - depends on ARCH_SIRF
  88555. - depends on MMC_SDHCI_PLTFM
  88556. + depends on ARCH_SIRF && HAS_DMA
  88557. + select MMC_SDHCI_PLTFM
  88558. help
  88559. This selects the SDHCI support for SiRF System-on-Chip devices.
  88560. @@ -215,8 +217,7 @@
  88561. config MMC_SDHCI_PXAV3
  88562. tristate "Marvell MMP2 SD Host Controller support (PXAV3)"
  88563. - depends on CLKDEV_LOOKUP
  88564. - select MMC_SDHCI
  88565. + depends on CLKDEV_LOOKUP && HAS_DMA
  88566. select MMC_SDHCI_PLTFM
  88567. default CPU_MMP2
  88568. help
  88569. @@ -228,8 +229,7 @@
  88570. config MMC_SDHCI_PXAV2
  88571. tristate "Marvell PXA9XX SD Host Controller support (PXAV2)"
  88572. - depends on CLKDEV_LOOKUP
  88573. - select MMC_SDHCI
  88574. + depends on CLKDEV_LOOKUP && HAS_DMA
  88575. select MMC_SDHCI_PLTFM
  88576. default CPU_PXA910
  88577. help
  88578. @@ -241,7 +241,8 @@
  88579. config MMC_SDHCI_SPEAR
  88580. tristate "SDHCI support on ST SPEAr platform"
  88581. - depends on MMC_SDHCI && PLAT_SPEAR
  88582. + depends on PLAT_SPEAR && HAS_DMA
  88583. + select MMC_SDHCI
  88584. help
  88585. This selects the Secure Digital Host Controller Interface (SDHCI)
  88586. often referrered to as the HSMMC block in some of the ST SPEAR range
  88587. @@ -263,7 +264,7 @@
  88588. config MMC_SDHCI_BCM_KONA
  88589. tristate "SDHCI support on Broadcom KONA platform"
  88590. - depends on ARCH_BCM
  88591. + depends on ARCH_BCM && HAS_DMA
  88592. select MMC_SDHCI_PLTFM
  88593. help
  88594. This selects the Broadcom Kona Secure Digital Host Controller
  88595. @@ -274,9 +275,9 @@
  88596. config MMC_SDHCI_BCM2835
  88597. tristate "SDHCI platform support for the BCM2835 SD/MMC Controller"
  88598. - depends on ARCH_BCM2835
  88599. - depends on MMC_SDHCI_PLTFM
  88600. + depends on ARCH_BCM2835 && HAS_DMA
  88601. select MMC_SDHCI_IO_ACCESSORS
  88602. + select MMC_SDHCI_PLTFM
  88603. help
  88604. This selects the BCM2835 SD/MMC controller. If you have a BCM2835
  88605. platform with SD or MMC devices, say Y or M here.
  88606. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-acpi.c linux-imx6-3.14/drivers/mmc/host/sdhci-acpi.c
  88607. --- linux-3.14.14/drivers/mmc/host/sdhci-acpi.c 2014-07-28 10:07:25.000000000 -0500
  88608. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-acpi.c 2014-12-08 00:31:53.428418001 -0600
  88609. @@ -101,11 +101,19 @@
  88610. }
  88611. static const struct sdhci_ops sdhci_acpi_ops_dflt = {
  88612. + .set_clock = sdhci_set_clock,
  88613. .enable_dma = sdhci_acpi_enable_dma,
  88614. + .set_bus_width = sdhci_set_bus_width,
  88615. + .reset = sdhci_reset,
  88616. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  88617. };
  88618. static const struct sdhci_ops sdhci_acpi_ops_int = {
  88619. + .set_clock = sdhci_set_clock,
  88620. .enable_dma = sdhci_acpi_enable_dma,
  88621. + .set_bus_width = sdhci_set_bus_width,
  88622. + .reset = sdhci_reset,
  88623. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  88624. .hw_reset = sdhci_acpi_int_hw_reset,
  88625. };
  88626. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-bcm2835.c linux-imx6-3.14/drivers/mmc/host/sdhci-bcm2835.c
  88627. --- linux-3.14.14/drivers/mmc/host/sdhci-bcm2835.c 2014-07-28 10:07:25.000000000 -0500
  88628. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-bcm2835.c 2014-12-08 00:31:53.428418001 -0600
  88629. @@ -131,8 +131,12 @@
  88630. .read_l = bcm2835_sdhci_readl,
  88631. .read_w = bcm2835_sdhci_readw,
  88632. .read_b = bcm2835_sdhci_readb,
  88633. + .set_clock = sdhci_set_clock,
  88634. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  88635. .get_min_clock = bcm2835_sdhci_get_min_clock,
  88636. + .set_bus_width = sdhci_set_bus_width,
  88637. + .reset = sdhci_reset,
  88638. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  88639. };
  88640. static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
  88641. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-bcm-kona.c linux-imx6-3.14/drivers/mmc/host/sdhci-bcm-kona.c
  88642. --- linux-3.14.14/drivers/mmc/host/sdhci-bcm-kona.c 2014-07-28 10:07:25.000000000 -0500
  88643. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-bcm-kona.c 2014-12-08 00:31:53.428418001 -0600
  88644. @@ -205,9 +205,13 @@
  88645. }
  88646. static struct sdhci_ops sdhci_bcm_kona_ops = {
  88647. + .set_clock = sdhci_set_clock,
  88648. .get_max_clock = sdhci_bcm_kona_get_max_clk,
  88649. .get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
  88650. .platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
  88651. + .set_bus_width = sdhci_set_bus_width,
  88652. + .reset = sdhci_reset,
  88653. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  88654. .card_event = sdhci_bcm_kona_card_event,
  88655. };
  88656. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci.c linux-imx6-3.14/drivers/mmc/host/sdhci.c
  88657. --- linux-3.14.14/drivers/mmc/host/sdhci.c 2014-07-28 10:07:25.000000000 -0500
  88658. +++ linux-imx6-3.14/drivers/mmc/host/sdhci.c 2014-12-08 00:31:53.428418001 -0600
  88659. @@ -44,6 +44,8 @@
  88660. #define MAX_TUNING_LOOP 40
  88661. +#define ADMA_SIZE ((128 * 2 + 1) * 4)
  88662. +
  88663. static unsigned int debug_quirks = 0;
  88664. static unsigned int debug_quirks2;
  88665. @@ -131,43 +133,28 @@
  88666. * *
  88667. \*****************************************************************************/
  88668. -static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
  88669. -{
  88670. - u32 ier;
  88671. -
  88672. - ier = sdhci_readl(host, SDHCI_INT_ENABLE);
  88673. - ier &= ~clear;
  88674. - ier |= set;
  88675. - sdhci_writel(host, ier, SDHCI_INT_ENABLE);
  88676. - sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
  88677. -}
  88678. -
  88679. -static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
  88680. -{
  88681. - sdhci_clear_set_irqs(host, 0, irqs);
  88682. -}
  88683. -
  88684. -static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
  88685. -{
  88686. - sdhci_clear_set_irqs(host, irqs, 0);
  88687. -}
  88688. -
  88689. static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
  88690. {
  88691. - u32 present, irqs;
  88692. + u32 present;
  88693. + int gpio_cd = mmc_gpio_get_cd(host->mmc);
  88694. if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
  88695. - (host->mmc->caps & MMC_CAP_NONREMOVABLE))
  88696. + (host->mmc->caps & MMC_CAP_NONREMOVABLE) ||
  88697. + !IS_ERR_VALUE(gpio_cd))
  88698. return;
  88699. - present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  88700. - SDHCI_CARD_PRESENT;
  88701. - irqs = present ? SDHCI_INT_CARD_REMOVE : SDHCI_INT_CARD_INSERT;
  88702. + if (enable) {
  88703. + present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  88704. + SDHCI_CARD_PRESENT;
  88705. - if (enable)
  88706. - sdhci_unmask_irqs(host, irqs);
  88707. - else
  88708. - sdhci_mask_irqs(host, irqs);
  88709. + host->ier |= present ? SDHCI_INT_CARD_REMOVE :
  88710. + SDHCI_INT_CARD_INSERT;
  88711. + } else {
  88712. + host->ier &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
  88713. + }
  88714. +
  88715. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  88716. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  88717. }
  88718. static void sdhci_enable_card_detection(struct sdhci_host *host)
  88719. @@ -180,22 +167,9 @@
  88720. sdhci_set_card_detection(host, false);
  88721. }
  88722. -static void sdhci_reset(struct sdhci_host *host, u8 mask)
  88723. +void sdhci_reset(struct sdhci_host *host, u8 mask)
  88724. {
  88725. unsigned long timeout;
  88726. - u32 uninitialized_var(ier);
  88727. -
  88728. - if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
  88729. - if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
  88730. - SDHCI_CARD_PRESENT))
  88731. - return;
  88732. - }
  88733. -
  88734. - if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
  88735. - ier = sdhci_readl(host, SDHCI_INT_ENABLE);
  88736. -
  88737. - if (host->ops->platform_reset_enter)
  88738. - host->ops->platform_reset_enter(host, mask);
  88739. sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
  88740. @@ -220,16 +194,27 @@
  88741. timeout--;
  88742. mdelay(1);
  88743. }
  88744. +}
  88745. +EXPORT_SYMBOL_GPL(sdhci_reset);
  88746. - if (host->ops->platform_reset_exit)
  88747. - host->ops->platform_reset_exit(host, mask);
  88748. +static void sdhci_do_reset(struct sdhci_host *host, u8 mask)
  88749. +{
  88750. + if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
  88751. + if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
  88752. + SDHCI_CARD_PRESENT))
  88753. + return;
  88754. + }
  88755. - if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
  88756. - sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
  88757. + host->ops->reset(host, mask);
  88758. - if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
  88759. - if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
  88760. - host->ops->enable_dma(host);
  88761. + if (mask & SDHCI_RESET_ALL) {
  88762. + if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
  88763. + if (host->ops->enable_dma)
  88764. + host->ops->enable_dma(host);
  88765. + }
  88766. +
  88767. + /* Resetting the controller clears many */
  88768. + host->preset_enabled = false;
  88769. }
  88770. }
  88771. @@ -238,15 +223,18 @@
  88772. static void sdhci_init(struct sdhci_host *host, int soft)
  88773. {
  88774. if (soft)
  88775. - sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
  88776. + sdhci_do_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
  88777. else
  88778. - sdhci_reset(host, SDHCI_RESET_ALL);
  88779. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  88780. - sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
  88781. - SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
  88782. - SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
  88783. - SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
  88784. - SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
  88785. + host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
  88786. + SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
  88787. + SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC |
  88788. + SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END |
  88789. + SDHCI_INT_RESPONSE;
  88790. +
  88791. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  88792. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  88793. if (soft) {
  88794. /* force clock reconfiguration */
  88795. @@ -502,11 +490,6 @@
  88796. else
  88797. direction = DMA_TO_DEVICE;
  88798. - /*
  88799. - * The ADMA descriptor table is mapped further down as we
  88800. - * need to fill it with data first.
  88801. - */
  88802. -
  88803. host->align_addr = dma_map_single(mmc_dev(host->mmc),
  88804. host->align_buffer, 128 * 4, direction);
  88805. if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
  88806. @@ -567,7 +550,7 @@
  88807. * If this triggers then we have a calculation bug
  88808. * somewhere. :/
  88809. */
  88810. - WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
  88811. + WARN_ON((desc - host->adma_desc) > ADMA_SIZE);
  88812. }
  88813. if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) {
  88814. @@ -595,17 +578,8 @@
  88815. host->align_addr, 128 * 4, direction);
  88816. }
  88817. - host->adma_addr = dma_map_single(mmc_dev(host->mmc),
  88818. - host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE);
  88819. - if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr))
  88820. - goto unmap_entries;
  88821. - BUG_ON(host->adma_addr & 0x3);
  88822. -
  88823. return 0;
  88824. -unmap_entries:
  88825. - dma_unmap_sg(mmc_dev(host->mmc), data->sg,
  88826. - data->sg_len, direction);
  88827. unmap_align:
  88828. dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
  88829. 128 * 4, direction);
  88830. @@ -623,19 +597,25 @@
  88831. u8 *align;
  88832. char *buffer;
  88833. unsigned long flags;
  88834. + bool has_unaligned;
  88835. if (data->flags & MMC_DATA_READ)
  88836. direction = DMA_FROM_DEVICE;
  88837. else
  88838. direction = DMA_TO_DEVICE;
  88839. - dma_unmap_single(mmc_dev(host->mmc), host->adma_addr,
  88840. - (128 * 2 + 1) * 4, DMA_TO_DEVICE);
  88841. -
  88842. dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
  88843. 128 * 4, direction);
  88844. - if (data->flags & MMC_DATA_READ) {
  88845. + /* Do a quick scan of the SG list for any unaligned mappings */
  88846. + has_unaligned = false;
  88847. + for_each_sg(data->sg, sg, host->sg_count, i)
  88848. + if (sg_dma_address(sg) & 3) {
  88849. + has_unaligned = true;
  88850. + break;
  88851. + }
  88852. +
  88853. + if (has_unaligned && data->flags & MMC_DATA_READ) {
  88854. dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
  88855. data->sg_len, direction);
  88856. @@ -721,9 +701,12 @@
  88857. u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
  88858. if (host->flags & SDHCI_REQ_USE_DMA)
  88859. - sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
  88860. + host->ier = (host->ier & ~pio_irqs) | dma_irqs;
  88861. else
  88862. - sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
  88863. + host->ier = (host->ier & ~dma_irqs) | pio_irqs;
  88864. +
  88865. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  88866. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  88867. }
  88868. static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
  88869. @@ -976,8 +959,8 @@
  88870. * upon error conditions.
  88871. */
  88872. if (data->error) {
  88873. - sdhci_reset(host, SDHCI_RESET_CMD);
  88874. - sdhci_reset(host, SDHCI_RESET_DATA);
  88875. + sdhci_do_reset(host, SDHCI_RESET_CMD);
  88876. + sdhci_do_reset(host, SDHCI_RESET_DATA);
  88877. }
  88878. sdhci_send_command(host, data->stop);
  88879. @@ -1107,24 +1090,23 @@
  88880. static u16 sdhci_get_preset_value(struct sdhci_host *host)
  88881. {
  88882. - u16 ctrl, preset = 0;
  88883. -
  88884. - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  88885. + u16 preset = 0;
  88886. - switch (ctrl & SDHCI_CTRL_UHS_MASK) {
  88887. - case SDHCI_CTRL_UHS_SDR12:
  88888. + switch (host->timing) {
  88889. + case MMC_TIMING_UHS_SDR12:
  88890. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
  88891. break;
  88892. - case SDHCI_CTRL_UHS_SDR25:
  88893. + case MMC_TIMING_UHS_SDR25:
  88894. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR25);
  88895. break;
  88896. - case SDHCI_CTRL_UHS_SDR50:
  88897. + case MMC_TIMING_UHS_SDR50:
  88898. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR50);
  88899. break;
  88900. - case SDHCI_CTRL_UHS_SDR104:
  88901. + case MMC_TIMING_UHS_SDR104:
  88902. + case MMC_TIMING_MMC_HS200:
  88903. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104);
  88904. break;
  88905. - case SDHCI_CTRL_UHS_DDR50:
  88906. + case MMC_TIMING_UHS_DDR50:
  88907. preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
  88908. break;
  88909. default:
  88910. @@ -1136,32 +1118,22 @@
  88911. return preset;
  88912. }
  88913. -static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
  88914. +void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
  88915. {
  88916. int div = 0; /* Initialized for compiler warning */
  88917. int real_div = div, clk_mul = 1;
  88918. u16 clk = 0;
  88919. unsigned long timeout;
  88920. - if (clock && clock == host->clock)
  88921. - return;
  88922. -
  88923. host->mmc->actual_clock = 0;
  88924. - if (host->ops->set_clock) {
  88925. - host->ops->set_clock(host, clock);
  88926. - if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
  88927. - return;
  88928. - }
  88929. -
  88930. sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
  88931. if (clock == 0)
  88932. - goto out;
  88933. + return;
  88934. if (host->version >= SDHCI_SPEC_300) {
  88935. - if (sdhci_readw(host, SDHCI_HOST_CONTROL2) &
  88936. - SDHCI_CTRL_PRESET_VAL_ENABLE) {
  88937. + if (host->preset_enabled) {
  88938. u16 pre_val;
  88939. clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
  88940. @@ -1247,26 +1219,16 @@
  88941. clk |= SDHCI_CLOCK_CARD_EN;
  88942. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  88943. -
  88944. -out:
  88945. - host->clock = clock;
  88946. -}
  88947. -
  88948. -static inline void sdhci_update_clock(struct sdhci_host *host)
  88949. -{
  88950. - unsigned int clock;
  88951. -
  88952. - clock = host->clock;
  88953. - host->clock = 0;
  88954. - sdhci_set_clock(host, clock);
  88955. }
  88956. +EXPORT_SYMBOL_GPL(sdhci_set_clock);
  88957. -static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
  88958. +static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
  88959. + unsigned short vdd)
  88960. {
  88961. u8 pwr = 0;
  88962. - if (power != (unsigned short)-1) {
  88963. - switch (1 << power) {
  88964. + if (mode != MMC_POWER_OFF) {
  88965. + switch (1 << vdd) {
  88966. case MMC_VDD_165_195:
  88967. pwr = SDHCI_POWER_180;
  88968. break;
  88969. @@ -1284,7 +1246,7 @@
  88970. }
  88971. if (host->pwr == pwr)
  88972. - return -1;
  88973. + return;
  88974. host->pwr = pwr;
  88975. @@ -1292,38 +1254,43 @@
  88976. sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
  88977. if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
  88978. sdhci_runtime_pm_bus_off(host);
  88979. - return 0;
  88980. - }
  88981. -
  88982. - /*
  88983. - * Spec says that we should clear the power reg before setting
  88984. - * a new value. Some controllers don't seem to like this though.
  88985. - */
  88986. - if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
  88987. - sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
  88988. + vdd = 0;
  88989. + } else {
  88990. + /*
  88991. + * Spec says that we should clear the power reg before setting
  88992. + * a new value. Some controllers don't seem to like this though.
  88993. + */
  88994. + if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
  88995. + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
  88996. - /*
  88997. - * At least the Marvell CaFe chip gets confused if we set the voltage
  88998. - * and set turn on power at the same time, so set the voltage first.
  88999. - */
  89000. - if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)
  89001. - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  89002. + /*
  89003. + * At least the Marvell CaFe chip gets confused if we set the
  89004. + * voltage and set turn on power at the same time, so set the
  89005. + * voltage first.
  89006. + */
  89007. + if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)
  89008. + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  89009. - pwr |= SDHCI_POWER_ON;
  89010. + pwr |= SDHCI_POWER_ON;
  89011. - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  89012. + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  89013. - if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
  89014. - sdhci_runtime_pm_bus_on(host);
  89015. + if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
  89016. + sdhci_runtime_pm_bus_on(host);
  89017. - /*
  89018. - * Some controllers need an extra 10ms delay of 10ms before they
  89019. - * can apply clock after applying power
  89020. - */
  89021. - if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
  89022. - mdelay(10);
  89023. + /*
  89024. + * Some controllers need an extra 10ms delay of 10ms before
  89025. + * they can apply clock after applying power
  89026. + */
  89027. + if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
  89028. + mdelay(10);
  89029. + }
  89030. - return power;
  89031. + if (host->vmmc) {
  89032. + spin_unlock_irq(&host->lock);
  89033. + mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd);
  89034. + spin_lock_irq(&host->lock);
  89035. + }
  89036. }
  89037. /*****************************************************************************\
  89038. @@ -1427,10 +1394,52 @@
  89039. spin_unlock_irqrestore(&host->lock, flags);
  89040. }
  89041. +void sdhci_set_bus_width(struct sdhci_host *host, int width)
  89042. +{
  89043. + u8 ctrl;
  89044. +
  89045. + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
  89046. + if (width == MMC_BUS_WIDTH_8) {
  89047. + ctrl &= ~SDHCI_CTRL_4BITBUS;
  89048. + if (host->version >= SDHCI_SPEC_300)
  89049. + ctrl |= SDHCI_CTRL_8BITBUS;
  89050. + } else {
  89051. + if (host->version >= SDHCI_SPEC_300)
  89052. + ctrl &= ~SDHCI_CTRL_8BITBUS;
  89053. + if (width == MMC_BUS_WIDTH_4)
  89054. + ctrl |= SDHCI_CTRL_4BITBUS;
  89055. + else
  89056. + ctrl &= ~SDHCI_CTRL_4BITBUS;
  89057. + }
  89058. + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  89059. +}
  89060. +EXPORT_SYMBOL_GPL(sdhci_set_bus_width);
  89061. +
  89062. +void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
  89063. +{
  89064. + u16 ctrl_2;
  89065. +
  89066. + ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89067. + /* Select Bus Speed Mode for host */
  89068. + ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
  89069. + if ((timing == MMC_TIMING_MMC_HS200) ||
  89070. + (timing == MMC_TIMING_UHS_SDR104))
  89071. + ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
  89072. + else if (timing == MMC_TIMING_UHS_SDR12)
  89073. + ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
  89074. + else if (timing == MMC_TIMING_UHS_SDR25)
  89075. + ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
  89076. + else if (timing == MMC_TIMING_UHS_SDR50)
  89077. + ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
  89078. + else if (timing == MMC_TIMING_UHS_DDR50)
  89079. + ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
  89080. + sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
  89081. +}
  89082. +EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
  89083. +
  89084. static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
  89085. {
  89086. unsigned long flags;
  89087. - int vdd_bit = -1;
  89088. u8 ctrl;
  89089. spin_lock_irqsave(&host->lock, flags);
  89090. @@ -1456,45 +1465,17 @@
  89091. !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
  89092. sdhci_enable_preset_value(host, false);
  89093. - sdhci_set_clock(host, ios->clock);
  89094. -
  89095. - if (ios->power_mode == MMC_POWER_OFF)
  89096. - vdd_bit = sdhci_set_power(host, -1);
  89097. - else
  89098. - vdd_bit = sdhci_set_power(host, ios->vdd);
  89099. -
  89100. - if (host->vmmc && vdd_bit != -1) {
  89101. - spin_unlock_irqrestore(&host->lock, flags);
  89102. - mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
  89103. - spin_lock_irqsave(&host->lock, flags);
  89104. + if (!ios->clock || ios->clock != host->clock) {
  89105. + host->ops->set_clock(host, ios->clock);
  89106. + host->clock = ios->clock;
  89107. }
  89108. + sdhci_set_power(host, ios->power_mode, ios->vdd);
  89109. +
  89110. if (host->ops->platform_send_init_74_clocks)
  89111. host->ops->platform_send_init_74_clocks(host, ios->power_mode);
  89112. - /*
  89113. - * If your platform has 8-bit width support but is not a v3 controller,
  89114. - * or if it requires special setup code, you should implement that in
  89115. - * platform_bus_width().
  89116. - */
  89117. - if (host->ops->platform_bus_width) {
  89118. - host->ops->platform_bus_width(host, ios->bus_width);
  89119. - } else {
  89120. - ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
  89121. - if (ios->bus_width == MMC_BUS_WIDTH_8) {
  89122. - ctrl &= ~SDHCI_CTRL_4BITBUS;
  89123. - if (host->version >= SDHCI_SPEC_300)
  89124. - ctrl |= SDHCI_CTRL_8BITBUS;
  89125. - } else {
  89126. - if (host->version >= SDHCI_SPEC_300)
  89127. - ctrl &= ~SDHCI_CTRL_8BITBUS;
  89128. - if (ios->bus_width == MMC_BUS_WIDTH_4)
  89129. - ctrl |= SDHCI_CTRL_4BITBUS;
  89130. - else
  89131. - ctrl &= ~SDHCI_CTRL_4BITBUS;
  89132. - }
  89133. - sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  89134. - }
  89135. + host->ops->set_bus_width(host, ios->bus_width);
  89136. ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
  89137. @@ -1516,13 +1497,13 @@
  89138. (ios->timing == MMC_TIMING_UHS_SDR25))
  89139. ctrl |= SDHCI_CTRL_HISPD;
  89140. - ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89141. - if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
  89142. + if (!host->preset_enabled) {
  89143. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  89144. /*
  89145. * We only need to set Driver Strength if the
  89146. * preset value enable is not set.
  89147. */
  89148. + ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89149. ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK;
  89150. if (ios->drv_type == MMC_SET_DRIVER_TYPE_A)
  89151. ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A;
  89152. @@ -1546,34 +1527,16 @@
  89153. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  89154. /* Re-enable SD Clock */
  89155. - sdhci_update_clock(host);
  89156. + host->ops->set_clock(host, host->clock);
  89157. }
  89158. -
  89159. /* Reset SD Clock Enable */
  89160. clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
  89161. clk &= ~SDHCI_CLOCK_CARD_EN;
  89162. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  89163. - if (host->ops->set_uhs_signaling)
  89164. - host->ops->set_uhs_signaling(host, ios->timing);
  89165. - else {
  89166. - ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89167. - /* Select Bus Speed Mode for host */
  89168. - ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
  89169. - if ((ios->timing == MMC_TIMING_MMC_HS200) ||
  89170. - (ios->timing == MMC_TIMING_UHS_SDR104))
  89171. - ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
  89172. - else if (ios->timing == MMC_TIMING_UHS_SDR12)
  89173. - ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
  89174. - else if (ios->timing == MMC_TIMING_UHS_SDR25)
  89175. - ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
  89176. - else if (ios->timing == MMC_TIMING_UHS_SDR50)
  89177. - ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
  89178. - else if (ios->timing == MMC_TIMING_UHS_DDR50)
  89179. - ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
  89180. - sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
  89181. - }
  89182. + host->ops->set_uhs_signaling(host, ios->timing);
  89183. + host->timing = ios->timing;
  89184. if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
  89185. ((ios->timing == MMC_TIMING_UHS_SDR12) ||
  89186. @@ -1589,8 +1552,7 @@
  89187. >> SDHCI_PRESET_DRV_SHIFT;
  89188. }
  89189. - /* Re-enable SD Clock */
  89190. - sdhci_update_clock(host);
  89191. + host->ops->set_clock(host, host->clock);
  89192. } else
  89193. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  89194. @@ -1600,7 +1562,7 @@
  89195. * it on each ios seems to solve the problem.
  89196. */
  89197. if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
  89198. - sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
  89199. + sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
  89200. mmiowb();
  89201. spin_unlock_irqrestore(&host->lock, flags);
  89202. @@ -1709,24 +1671,16 @@
  89203. static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
  89204. {
  89205. - if (host->flags & SDHCI_DEVICE_DEAD)
  89206. - goto out;
  89207. -
  89208. - if (enable)
  89209. - host->flags |= SDHCI_SDIO_IRQ_ENABLED;
  89210. - else
  89211. - host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
  89212. -
  89213. - /* SDIO IRQ will be enabled as appropriate in runtime resume */
  89214. - if (host->runtime_suspended)
  89215. - goto out;
  89216. + if (!(host->flags & SDHCI_DEVICE_DEAD)) {
  89217. + if (enable)
  89218. + host->ier |= SDHCI_INT_CARD_INT;
  89219. + else
  89220. + host->ier &= ~SDHCI_INT_CARD_INT;
  89221. - if (enable)
  89222. - sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
  89223. - else
  89224. - sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
  89225. -out:
  89226. - mmiowb();
  89227. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  89228. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  89229. + mmiowb();
  89230. + }
  89231. }
  89232. static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
  89233. @@ -1734,9 +1688,18 @@
  89234. struct sdhci_host *host = mmc_priv(mmc);
  89235. unsigned long flags;
  89236. + sdhci_runtime_pm_get(host);
  89237. +
  89238. spin_lock_irqsave(&host->lock, flags);
  89239. + if (enable)
  89240. + host->flags |= SDHCI_SDIO_IRQ_ENABLED;
  89241. + else
  89242. + host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
  89243. +
  89244. sdhci_enable_sdio_irq_nolock(host, enable);
  89245. spin_unlock_irqrestore(&host->lock, flags);
  89246. +
  89247. + sdhci_runtime_pm_put(host);
  89248. }
  89249. static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
  89250. @@ -1855,22 +1818,16 @@
  89251. static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
  89252. {
  89253. - struct sdhci_host *host;
  89254. + struct sdhci_host *host = mmc_priv(mmc);
  89255. u16 ctrl;
  89256. - u32 ier;
  89257. int tuning_loop_counter = MAX_TUNING_LOOP;
  89258. unsigned long timeout;
  89259. int err = 0;
  89260. - bool requires_tuning_nonuhs = false;
  89261. unsigned long flags;
  89262. - host = mmc_priv(mmc);
  89263. -
  89264. sdhci_runtime_pm_get(host);
  89265. spin_lock_irqsave(&host->lock, flags);
  89266. - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89267. -
  89268. /*
  89269. * The Host Controller needs tuning only in case of SDR104 mode
  89270. * and for SDR50 mode when Use Tuning for SDR50 is set in the
  89271. @@ -1878,15 +1835,18 @@
  89272. * If the Host Controller supports the HS200 mode then the
  89273. * tuning function has to be executed.
  89274. */
  89275. - if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
  89276. - (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
  89277. - host->flags & SDHCI_SDR104_NEEDS_TUNING))
  89278. - requires_tuning_nonuhs = true;
  89279. -
  89280. - if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
  89281. - requires_tuning_nonuhs)
  89282. - ctrl |= SDHCI_CTRL_EXEC_TUNING;
  89283. - else {
  89284. + switch (host->timing) {
  89285. + case MMC_TIMING_MMC_HS200:
  89286. + case MMC_TIMING_UHS_SDR104:
  89287. + break;
  89288. +
  89289. + case MMC_TIMING_UHS_SDR50:
  89290. + if (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
  89291. + host->flags & SDHCI_SDR104_NEEDS_TUNING)
  89292. + break;
  89293. + /* FALLTHROUGH */
  89294. +
  89295. + default:
  89296. spin_unlock_irqrestore(&host->lock, flags);
  89297. sdhci_runtime_pm_put(host);
  89298. return 0;
  89299. @@ -1899,6 +1859,8 @@
  89300. return err;
  89301. }
  89302. + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89303. + ctrl |= SDHCI_CTRL_EXEC_TUNING;
  89304. sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
  89305. /*
  89306. @@ -1911,8 +1873,8 @@
  89307. * to make sure we don't hit a controller bug, we _only_
  89308. * enable Buffer Read Ready interrupt here.
  89309. */
  89310. - ier = sdhci_readl(host, SDHCI_INT_ENABLE);
  89311. - sdhci_clear_set_irqs(host, ier, SDHCI_INT_DATA_AVAIL);
  89312. + sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
  89313. + sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
  89314. /*
  89315. * Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number
  89316. @@ -2045,7 +2007,8 @@
  89317. if (err && (host->flags & SDHCI_USING_RETUNING_TIMER))
  89318. err = 0;
  89319. - sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
  89320. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  89321. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  89322. spin_unlock_irqrestore(&host->lock, flags);
  89323. sdhci_runtime_pm_put(host);
  89324. @@ -2055,26 +2018,30 @@
  89325. static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
  89326. {
  89327. - u16 ctrl;
  89328. -
  89329. /* Host Controller v3.00 defines preset value registers */
  89330. if (host->version < SDHCI_SPEC_300)
  89331. return;
  89332. - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89333. -
  89334. /*
  89335. * We only enable or disable Preset Value if they are not already
  89336. * enabled or disabled respectively. Otherwise, we bail out.
  89337. */
  89338. - if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
  89339. - ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
  89340. - sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
  89341. - host->flags |= SDHCI_PV_ENABLED;
  89342. - } else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
  89343. - ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
  89344. + if (host->preset_enabled != enable) {
  89345. + u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  89346. +
  89347. + if (enable)
  89348. + ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
  89349. + else
  89350. + ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
  89351. +
  89352. sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
  89353. - host->flags &= ~SDHCI_PV_ENABLED;
  89354. +
  89355. + if (enable)
  89356. + host->flags |= SDHCI_PV_ENABLED;
  89357. + else
  89358. + host->flags &= ~SDHCI_PV_ENABLED;
  89359. +
  89360. + host->preset_enabled = enable;
  89361. }
  89362. }
  89363. @@ -2096,8 +2063,8 @@
  89364. pr_err("%s: Resetting controller.\n",
  89365. mmc_hostname(host->mmc));
  89366. - sdhci_reset(host, SDHCI_RESET_CMD);
  89367. - sdhci_reset(host, SDHCI_RESET_DATA);
  89368. + sdhci_do_reset(host, SDHCI_RESET_CMD);
  89369. + sdhci_do_reset(host, SDHCI_RESET_DATA);
  89370. host->mrq->cmd->error = -ENOMEDIUM;
  89371. tasklet_schedule(&host->finish_tasklet);
  89372. @@ -2125,15 +2092,6 @@
  89373. * *
  89374. \*****************************************************************************/
  89375. -static void sdhci_tasklet_card(unsigned long param)
  89376. -{
  89377. - struct sdhci_host *host = (struct sdhci_host*)param;
  89378. -
  89379. - sdhci_card_event(host->mmc);
  89380. -
  89381. - mmc_detect_change(host->mmc, msecs_to_jiffies(200));
  89382. -}
  89383. -
  89384. static void sdhci_tasklet_finish(unsigned long param)
  89385. {
  89386. struct sdhci_host *host;
  89387. @@ -2170,12 +2128,12 @@
  89388. /* Some controllers need this kick or reset won't work here */
  89389. if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
  89390. /* This is to force an update */
  89391. - sdhci_update_clock(host);
  89392. + host->ops->set_clock(host, host->clock);
  89393. /* Spec says we should do both at the same time, but Ricoh
  89394. controllers do not like that. */
  89395. - sdhci_reset(host, SDHCI_RESET_CMD);
  89396. - sdhci_reset(host, SDHCI_RESET_DATA);
  89397. + sdhci_do_reset(host, SDHCI_RESET_CMD);
  89398. + sdhci_do_reset(host, SDHCI_RESET_DATA);
  89399. }
  89400. host->mrq = NULL;
  89401. @@ -2425,14 +2383,14 @@
  89402. static irqreturn_t sdhci_irq(int irq, void *dev_id)
  89403. {
  89404. - irqreturn_t result;
  89405. + irqreturn_t result = IRQ_NONE;
  89406. struct sdhci_host *host = dev_id;
  89407. - u32 intmask, unexpected = 0;
  89408. - int cardint = 0, max_loops = 16;
  89409. + u32 intmask, mask, unexpected = 0;
  89410. + int max_loops = 16;
  89411. spin_lock(&host->lock);
  89412. - if (host->runtime_suspended) {
  89413. + if (host->runtime_suspended && !sdhci_sdio_irq_enabled(host)) {
  89414. spin_unlock(&host->lock);
  89415. pr_warning("%s: got irq while runtime suspended\n",
  89416. mmc_hostname(host->mmc));
  89417. @@ -2440,88 +2398,81 @@
  89418. }
  89419. intmask = sdhci_readl(host, SDHCI_INT_STATUS);
  89420. -
  89421. if (!intmask || intmask == 0xffffffff) {
  89422. result = IRQ_NONE;
  89423. goto out;
  89424. }
  89425. -again:
  89426. - DBG("*** %s got interrupt: 0x%08x\n",
  89427. - mmc_hostname(host->mmc), intmask);
  89428. -
  89429. - if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
  89430. - u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  89431. - SDHCI_CARD_PRESENT;
  89432. -
  89433. - /*
  89434. - * There is a observation on i.mx esdhc. INSERT bit will be
  89435. - * immediately set again when it gets cleared, if a card is
  89436. - * inserted. We have to mask the irq to prevent interrupt
  89437. - * storm which will freeze the system. And the REMOVE gets
  89438. - * the same situation.
  89439. - *
  89440. - * More testing are needed here to ensure it works for other
  89441. - * platforms though.
  89442. - */
  89443. - sdhci_mask_irqs(host, present ? SDHCI_INT_CARD_INSERT :
  89444. - SDHCI_INT_CARD_REMOVE);
  89445. - sdhci_unmask_irqs(host, present ? SDHCI_INT_CARD_REMOVE :
  89446. - SDHCI_INT_CARD_INSERT);
  89447. -
  89448. - sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
  89449. - SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
  89450. - intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
  89451. - tasklet_schedule(&host->card_tasklet);
  89452. - }
  89453. -
  89454. - if (intmask & SDHCI_INT_CMD_MASK) {
  89455. - sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
  89456. - SDHCI_INT_STATUS);
  89457. - sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
  89458. - }
  89459. + do {
  89460. + /* Clear selected interrupts. */
  89461. + mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
  89462. + SDHCI_INT_BUS_POWER);
  89463. + sdhci_writel(host, mask, SDHCI_INT_STATUS);
  89464. +
  89465. + DBG("*** %s got interrupt: 0x%08x\n",
  89466. + mmc_hostname(host->mmc), intmask);
  89467. +
  89468. + if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
  89469. + u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  89470. + SDHCI_CARD_PRESENT;
  89471. - if (intmask & SDHCI_INT_DATA_MASK) {
  89472. - sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
  89473. - SDHCI_INT_STATUS);
  89474. - sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
  89475. - }
  89476. + /*
  89477. + * There is a observation on i.mx esdhc. INSERT
  89478. + * bit will be immediately set again when it gets
  89479. + * cleared, if a card is inserted. We have to mask
  89480. + * the irq to prevent interrupt storm which will
  89481. + * freeze the system. And the REMOVE gets the
  89482. + * same situation.
  89483. + *
  89484. + * More testing are needed here to ensure it works
  89485. + * for other platforms though.
  89486. + */
  89487. + host->ier &= ~(SDHCI_INT_CARD_INSERT |
  89488. + SDHCI_INT_CARD_REMOVE);
  89489. + host->ier |= present ? SDHCI_INT_CARD_REMOVE :
  89490. + SDHCI_INT_CARD_INSERT;
  89491. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  89492. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  89493. - intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
  89494. + sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
  89495. + SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
  89496. - intmask &= ~SDHCI_INT_ERROR;
  89497. + host->thread_isr |= intmask & (SDHCI_INT_CARD_INSERT |
  89498. + SDHCI_INT_CARD_REMOVE);
  89499. + result = IRQ_WAKE_THREAD;
  89500. + }
  89501. - if (intmask & SDHCI_INT_BUS_POWER) {
  89502. - pr_err("%s: Card is consuming too much power!\n",
  89503. - mmc_hostname(host->mmc));
  89504. - sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
  89505. - }
  89506. + if (intmask & SDHCI_INT_CMD_MASK)
  89507. + sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
  89508. - intmask &= ~SDHCI_INT_BUS_POWER;
  89509. + if (intmask & SDHCI_INT_DATA_MASK)
  89510. + sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
  89511. - if (intmask & SDHCI_INT_CARD_INT)
  89512. - cardint = 1;
  89513. + if (intmask & SDHCI_INT_BUS_POWER)
  89514. + pr_err("%s: Card is consuming too much power!\n",
  89515. + mmc_hostname(host->mmc));
  89516. - intmask &= ~SDHCI_INT_CARD_INT;
  89517. + if (intmask & SDHCI_INT_CARD_INT) {
  89518. + sdhci_enable_sdio_irq_nolock(host, false);
  89519. + host->thread_isr |= SDHCI_INT_CARD_INT;
  89520. + result = IRQ_WAKE_THREAD;
  89521. + }
  89522. - if (intmask) {
  89523. - unexpected |= intmask;
  89524. - sdhci_writel(host, intmask, SDHCI_INT_STATUS);
  89525. - }
  89526. + intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
  89527. + SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
  89528. + SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER |
  89529. + SDHCI_INT_CARD_INT);
  89530. - result = IRQ_HANDLED;
  89531. + if (intmask) {
  89532. + unexpected |= intmask;
  89533. + sdhci_writel(host, intmask, SDHCI_INT_STATUS);
  89534. + }
  89535. - intmask = sdhci_readl(host, SDHCI_INT_STATUS);
  89536. + if (result == IRQ_NONE)
  89537. + result = IRQ_HANDLED;
  89538. - /*
  89539. - * If we know we'll call the driver to signal SDIO IRQ, disregard
  89540. - * further indications of Card Interrupt in the status to avoid a
  89541. - * needless loop.
  89542. - */
  89543. - if (cardint)
  89544. - intmask &= ~SDHCI_INT_CARD_INT;
  89545. - if (intmask && --max_loops)
  89546. - goto again;
  89547. + intmask = sdhci_readl(host, SDHCI_INT_STATUS);
  89548. + } while (intmask && --max_loops);
  89549. out:
  89550. spin_unlock(&host->lock);
  89551. @@ -2530,15 +2481,38 @@
  89552. mmc_hostname(host->mmc), unexpected);
  89553. sdhci_dumpregs(host);
  89554. }
  89555. - /*
  89556. - * We have to delay this as it calls back into the driver.
  89557. - */
  89558. - if (cardint)
  89559. - mmc_signal_sdio_irq(host->mmc);
  89560. return result;
  89561. }
  89562. +static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
  89563. +{
  89564. + struct sdhci_host *host = dev_id;
  89565. + unsigned long flags;
  89566. + u32 isr;
  89567. +
  89568. + spin_lock_irqsave(&host->lock, flags);
  89569. + isr = host->thread_isr;
  89570. + host->thread_isr = 0;
  89571. + spin_unlock_irqrestore(&host->lock, flags);
  89572. +
  89573. + if (isr & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
  89574. + sdhci_card_event(host->mmc);
  89575. + mmc_detect_change(host->mmc, msecs_to_jiffies(200));
  89576. + }
  89577. +
  89578. + if (isr & SDHCI_INT_CARD_INT) {
  89579. + sdio_run_irqs(host->mmc);
  89580. +
  89581. + spin_lock_irqsave(&host->lock, flags);
  89582. + if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
  89583. + sdhci_enable_sdio_irq_nolock(host, true);
  89584. + spin_unlock_irqrestore(&host->lock, flags);
  89585. + }
  89586. +
  89587. + return isr ? IRQ_HANDLED : IRQ_NONE;
  89588. +}
  89589. +
  89590. /*****************************************************************************\
  89591. * *
  89592. * Suspend/resume *
  89593. @@ -2548,6 +2522,7 @@
  89594. #ifdef CONFIG_PM
  89595. void sdhci_enable_irq_wakeups(struct sdhci_host *host)
  89596. {
  89597. + int gpio_cd = mmc_gpio_get_cd(host->mmc);
  89598. u8 val;
  89599. u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE
  89600. | SDHCI_WAKE_ON_INT;
  89601. @@ -2555,7 +2530,8 @@
  89602. val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
  89603. val |= mask ;
  89604. /* Avoid fake wake up */
  89605. - if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
  89606. + if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION ||
  89607. + !IS_ERR_VALUE(gpio_cd))
  89608. val &= ~(SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE);
  89609. sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
  89610. }
  89611. @@ -2575,9 +2551,6 @@
  89612. int sdhci_suspend_host(struct sdhci_host *host)
  89613. {
  89614. - if (host->ops->platform_suspend)
  89615. - host->ops->platform_suspend(host);
  89616. -
  89617. sdhci_disable_card_detection(host);
  89618. /* Disable tuning since we are suspending */
  89619. @@ -2587,7 +2560,9 @@
  89620. }
  89621. if (!device_may_wakeup(mmc_dev(host->mmc))) {
  89622. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  89623. + host->ier = 0;
  89624. + sdhci_writel(host, 0, SDHCI_INT_ENABLE);
  89625. + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
  89626. free_irq(host->irq, host);
  89627. } else {
  89628. sdhci_enable_irq_wakeups(host);
  89629. @@ -2608,8 +2583,9 @@
  89630. }
  89631. if (!device_may_wakeup(mmc_dev(host->mmc))) {
  89632. - ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
  89633. - mmc_hostname(host->mmc), host);
  89634. + ret = request_threaded_irq(host->irq, sdhci_irq,
  89635. + sdhci_thread_irq, IRQF_SHARED,
  89636. + mmc_hostname(host->mmc), host);
  89637. if (ret)
  89638. return ret;
  89639. } else {
  89640. @@ -2631,9 +2607,6 @@
  89641. sdhci_enable_card_detection(host);
  89642. - if (host->ops->platform_resume)
  89643. - host->ops->platform_resume(host);
  89644. -
  89645. /* Set the re-tuning expiration flag */
  89646. if (host->flags & SDHCI_USING_RETUNING_TIMER)
  89647. host->flags |= SDHCI_NEEDS_RETUNING;
  89648. @@ -2685,10 +2658,12 @@
  89649. }
  89650. spin_lock_irqsave(&host->lock, flags);
  89651. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  89652. + host->ier &= SDHCI_INT_CARD_INT;
  89653. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  89654. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  89655. spin_unlock_irqrestore(&host->lock, flags);
  89656. - synchronize_irq(host->irq);
  89657. + synchronize_hardirq(host->irq);
  89658. spin_lock_irqsave(&host->lock, flags);
  89659. host->runtime_suspended = true;
  89660. @@ -2732,7 +2707,7 @@
  89661. host->runtime_suspended = false;
  89662. /* Enable SDIO IRQ */
  89663. - if ((host->flags & SDHCI_SDIO_IRQ_ENABLED))
  89664. + if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
  89665. sdhci_enable_sdio_irq_nolock(host, true);
  89666. /* Enable Card Detection */
  89667. @@ -2791,7 +2766,7 @@
  89668. if (debug_quirks2)
  89669. host->quirks2 = debug_quirks2;
  89670. - sdhci_reset(host, SDHCI_RESET_ALL);
  89671. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  89672. host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
  89673. host->version = (host->version & SDHCI_SPEC_VER_MASK)
  89674. @@ -2851,15 +2826,29 @@
  89675. * (128) and potentially one alignment transfer for
  89676. * each of those entries.
  89677. */
  89678. - host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL);
  89679. + host->adma_desc = dma_alloc_coherent(mmc_dev(host->mmc),
  89680. + ADMA_SIZE, &host->adma_addr,
  89681. + GFP_KERNEL);
  89682. host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
  89683. if (!host->adma_desc || !host->align_buffer) {
  89684. - kfree(host->adma_desc);
  89685. + dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
  89686. + host->adma_desc, host->adma_addr);
  89687. kfree(host->align_buffer);
  89688. pr_warning("%s: Unable to allocate ADMA "
  89689. "buffers. Falling back to standard DMA.\n",
  89690. mmc_hostname(mmc));
  89691. host->flags &= ~SDHCI_USE_ADMA;
  89692. + host->adma_desc = NULL;
  89693. + host->align_buffer = NULL;
  89694. + } else if (host->adma_addr & 3) {
  89695. + pr_warning("%s: unable to allocate aligned ADMA descriptor\n",
  89696. + mmc_hostname(mmc));
  89697. + host->flags &= ~SDHCI_USE_ADMA;
  89698. + dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
  89699. + host->adma_desc, host->adma_addr);
  89700. + kfree(host->align_buffer);
  89701. + host->adma_desc = NULL;
  89702. + host->align_buffer = NULL;
  89703. }
  89704. }
  89705. @@ -2941,9 +2930,22 @@
  89706. if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
  89707. host->timeout_clk = mmc->f_max / 1000;
  89708. - mmc->max_discard_to = (1 << 27) / host->timeout_clk;
  89709. + if (host->quirks2 & SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER) {
  89710. + if (host->ops->get_max_timeout_counter) {
  89711. + mmc->max_discard_to =
  89712. + host->ops->get_max_timeout_counter(host)
  89713. + / host->timeout_clk;
  89714. + } else {
  89715. + pr_err("%s: Hardware doesn't specify max timeout "
  89716. + "counter\n", mmc_hostname(mmc));
  89717. + return -ENODEV;
  89718. + }
  89719. + } else {
  89720. + mmc->max_discard_to = (1 << 27) / host->timeout_clk;
  89721. + }
  89722. mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
  89723. + mmc->caps2 |= MMC_CAP2_SDIO_NOTHREAD;
  89724. if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
  89725. host->flags |= SDHCI_AUTO_CMD12;
  89726. @@ -3214,8 +3216,6 @@
  89727. /*
  89728. * Init tasklets.
  89729. */
  89730. - tasklet_init(&host->card_tasklet,
  89731. - sdhci_tasklet_card, (unsigned long)host);
  89732. tasklet_init(&host->finish_tasklet,
  89733. sdhci_tasklet_finish, (unsigned long)host);
  89734. @@ -3232,8 +3232,8 @@
  89735. sdhci_init(host, 0);
  89736. - ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
  89737. - mmc_hostname(mmc), host);
  89738. + ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq,
  89739. + IRQF_SHARED, mmc_hostname(mmc), host);
  89740. if (ret) {
  89741. pr_err("%s: Failed to request IRQ %d: %d\n",
  89742. mmc_hostname(mmc), host->irq, ret);
  89743. @@ -3275,12 +3275,12 @@
  89744. #ifdef SDHCI_USE_LEDS_CLASS
  89745. reset:
  89746. - sdhci_reset(host, SDHCI_RESET_ALL);
  89747. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  89748. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  89749. + sdhci_writel(host, 0, SDHCI_INT_ENABLE);
  89750. + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
  89751. free_irq(host->irq, host);
  89752. #endif
  89753. untasklet:
  89754. - tasklet_kill(&host->card_tasklet);
  89755. tasklet_kill(&host->finish_tasklet);
  89756. return ret;
  89757. @@ -3317,14 +3317,14 @@
  89758. #endif
  89759. if (!dead)
  89760. - sdhci_reset(host, SDHCI_RESET_ALL);
  89761. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  89762. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  89763. + sdhci_writel(host, 0, SDHCI_INT_ENABLE);
  89764. + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
  89765. free_irq(host->irq, host);
  89766. del_timer_sync(&host->timer);
  89767. - tasklet_kill(&host->card_tasklet);
  89768. tasklet_kill(&host->finish_tasklet);
  89769. if (host->vmmc) {
  89770. @@ -3337,7 +3337,9 @@
  89771. regulator_put(host->vqmmc);
  89772. }
  89773. - kfree(host->adma_desc);
  89774. + if (host->adma_desc)
  89775. + dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
  89776. + host->adma_desc, host->adma_addr);
  89777. kfree(host->align_buffer);
  89778. host->adma_desc = NULL;
  89779. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-cns3xxx.c linux-imx6-3.14/drivers/mmc/host/sdhci-cns3xxx.c
  89780. --- linux-3.14.14/drivers/mmc/host/sdhci-cns3xxx.c 2014-07-28 10:07:25.000000000 -0500
  89781. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-cns3xxx.c 2014-12-08 00:31:53.428418001 -0600
  89782. @@ -30,13 +30,12 @@
  89783. u16 clk;
  89784. unsigned long timeout;
  89785. - if (clock == host->clock)
  89786. - return;
  89787. + host->mmc->actual_clock = 0;
  89788. sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
  89789. if (clock == 0)
  89790. - goto out;
  89791. + return;
  89792. while (host->max_clk / div > clock) {
  89793. /*
  89794. @@ -75,13 +74,14 @@
  89795. clk |= SDHCI_CLOCK_CARD_EN;
  89796. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  89797. -out:
  89798. - host->clock = clock;
  89799. }
  89800. static const struct sdhci_ops sdhci_cns3xxx_ops = {
  89801. .get_max_clock = sdhci_cns3xxx_get_max_clk,
  89802. .set_clock = sdhci_cns3xxx_set_clock,
  89803. + .set_bus_width = sdhci_set_bus_width,
  89804. + .reset = sdhci_reset,
  89805. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  89806. };
  89807. static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
  89808. @@ -90,8 +90,7 @@
  89809. SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
  89810. SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
  89811. SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
  89812. - SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
  89813. - SDHCI_QUIRK_NONSTANDARD_CLOCK,
  89814. + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
  89815. };
  89816. static int sdhci_cns3xxx_probe(struct platform_device *pdev)
  89817. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-dove.c linux-imx6-3.14/drivers/mmc/host/sdhci-dove.c
  89818. --- linux-3.14.14/drivers/mmc/host/sdhci-dove.c 2014-07-28 10:07:25.000000000 -0500
  89819. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-dove.c 2014-12-08 00:31:53.428418001 -0600
  89820. @@ -86,6 +86,10 @@
  89821. static const struct sdhci_ops sdhci_dove_ops = {
  89822. .read_w = sdhci_dove_readw,
  89823. .read_l = sdhci_dove_readl,
  89824. + .set_clock = sdhci_set_clock,
  89825. + .set_bus_width = sdhci_set_bus_width,
  89826. + .reset = sdhci_reset,
  89827. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  89828. };
  89829. static const struct sdhci_pltfm_data sdhci_dove_pdata = {
  89830. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-esdhc.h linux-imx6-3.14/drivers/mmc/host/sdhci-esdhc.h
  89831. --- linux-3.14.14/drivers/mmc/host/sdhci-esdhc.h 2014-07-28 10:07:25.000000000 -0500
  89832. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-esdhc.h 2014-12-08 00:31:53.428418001 -0600
  89833. @@ -20,12 +20,11 @@
  89834. #define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
  89835. SDHCI_QUIRK_NO_BUSY_IRQ | \
  89836. - SDHCI_QUIRK_NONSTANDARD_CLOCK | \
  89837. SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
  89838. - SDHCI_QUIRK_PIO_NEEDS_DELAY | \
  89839. - SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
  89840. + SDHCI_QUIRK_PIO_NEEDS_DELAY)
  89841. #define ESDHC_SYSTEM_CONTROL 0x2c
  89842. +#define ESDHC_SYS_CTRL_RSTA (1 << 24)
  89843. #define ESDHC_CLOCK_MASK 0x0000fff0
  89844. #define ESDHC_PREDIV_SHIFT 8
  89845. #define ESDHC_DIVIDER_SHIFT 4
  89846. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-esdhc-imx.c linux-imx6-3.14/drivers/mmc/host/sdhci-esdhc-imx.c
  89847. --- linux-3.14.14/drivers/mmc/host/sdhci-esdhc-imx.c 2014-07-28 10:07:25.000000000 -0500
  89848. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-esdhc-imx.c 2014-12-08 00:31:53.428418001 -0600
  89849. @@ -11,6 +11,7 @@
  89850. * the Free Software Foundation; either version 2 of the License.
  89851. */
  89852. +#include <linux/busfreq-imx6.h>
  89853. #include <linux/io.h>
  89854. #include <linux/delay.h>
  89855. #include <linux/err.h>
  89856. @@ -114,6 +115,10 @@
  89857. #define ESDHC_FLAG_STD_TUNING BIT(5)
  89858. /* The IP has SDHCI_CAPABILITIES_1 register */
  89859. #define ESDHC_FLAG_HAVE_CAP1 BIT(6)
  89860. +/* The IP has errata ERR004536 */
  89861. +#define ESDHC_FLAG_ERR004536 BIT(7)
  89862. +/* need request bus freq during low power */
  89863. +#define ESDHC_FLAG_BUSFREQ BIT(8)
  89864. struct esdhc_soc_data {
  89865. u32 flags;
  89866. @@ -141,7 +146,8 @@
  89867. static struct esdhc_soc_data usdhc_imx6sl_data = {
  89868. .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
  89869. - | ESDHC_FLAG_HAVE_CAP1,
  89870. + | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_ERR004536
  89871. + | ESDHC_FLAG_BUSFREQ,
  89872. };
  89873. struct pltfm_imx_data {
  89874. @@ -160,7 +166,6 @@
  89875. MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */
  89876. WAIT_FOR_INT, /* sent CMD12, waiting for response INT */
  89877. } multiblock_status;
  89878. - u32 uhs_mode;
  89879. u32 is_ddr;
  89880. };
  89881. @@ -382,7 +387,6 @@
  89882. if (val & ESDHC_MIX_CTRL_SMPCLK_SEL)
  89883. ret |= SDHCI_CTRL_TUNED_CLK;
  89884. - ret |= (imx_data->uhs_mode & SDHCI_CTRL_UHS_MASK);
  89885. ret &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
  89886. return ret;
  89887. @@ -429,7 +433,6 @@
  89888. else
  89889. new_val &= ~ESDHC_VENDOR_SPEC_VSELECT;
  89890. writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC);
  89891. - imx_data->uhs_mode = val & SDHCI_CTRL_UHS_MASK;
  89892. if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) {
  89893. new_val = readl(host->ioaddr + ESDHC_MIX_CTRL);
  89894. if (val & SDHCI_CTRL_TUNED_CLK)
  89895. @@ -600,12 +603,14 @@
  89896. u32 temp, val;
  89897. if (clock == 0) {
  89898. + host->mmc->actual_clock = 0;
  89899. +
  89900. if (esdhc_is_usdhc(imx_data)) {
  89901. val = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
  89902. writel(val & ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
  89903. host->ioaddr + ESDHC_VENDOR_SPEC);
  89904. }
  89905. - goto out;
  89906. + return;
  89907. }
  89908. if (esdhc_is_usdhc(imx_data) && !imx_data->is_ddr)
  89909. @@ -645,8 +650,6 @@
  89910. }
  89911. mdelay(1);
  89912. -out:
  89913. - host->clock = clock;
  89914. }
  89915. static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
  89916. @@ -668,7 +671,7 @@
  89917. return -ENOSYS;
  89918. }
  89919. -static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
  89920. +static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
  89921. {
  89922. u32 ctrl;
  89923. @@ -686,17 +689,56 @@
  89924. esdhc_clrset_le(host, ESDHC_CTRL_BUSWIDTH_MASK, ctrl,
  89925. SDHCI_HOST_CONTROL);
  89926. +}
  89927. - return 0;
  89928. +static void esdhc_tuning_reset(struct sdhci_host *host, u32 rst_bits)
  89929. +{
  89930. + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  89931. + struct pltfm_imx_data *imx_data = pltfm_host->priv;
  89932. + u32 timeout;
  89933. + u32 reg;
  89934. +
  89935. + reg = readl(host->ioaddr + ESDHC_SYSTEM_CONTROL);
  89936. + reg |= rst_bits;
  89937. + writel(reg, host->ioaddr + ESDHC_SYSTEM_CONTROL);
  89938. +
  89939. + /* Wait for max 100ms */
  89940. + timeout = 100;
  89941. +
  89942. + /* hw clears the bit when it's done */
  89943. + while (readl(host->ioaddr + ESDHC_SYSTEM_CONTROL) & rst_bits) {
  89944. + if (timeout == 0) {
  89945. + dev_err(mmc_dev(host->mmc),
  89946. + "Reset never completes!\n");
  89947. + return;
  89948. + }
  89949. + timeout--;
  89950. + mdelay(1);
  89951. + }
  89952. +
  89953. + /*
  89954. + * The RSTA, reset all, on usdhc will not clear following regs:
  89955. + * > SDHCI_MIX_CTRL
  89956. + * > SDHCI_TUNE_CTRL_STATUS
  89957. + *
  89958. + * Do it manually here.
  89959. + */
  89960. + if ((rst_bits & ESDHC_SYS_CTRL_RSTA) && is_imx6q_usdhc(imx_data)) {
  89961. + writel(0, host->ioaddr + ESDHC_MIX_CTRL);
  89962. + writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS);
  89963. + /* FIXME: delay for clear tuning status or some cards may not work */
  89964. + mdelay(1);
  89965. + }
  89966. }
  89967. static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
  89968. {
  89969. u32 reg;
  89970. - /* FIXME: delay a bit for card to be ready for next tuning due to errors */
  89971. - mdelay(1);
  89972. + /* reset controller before tuning or it may fail on some cards */
  89973. + esdhc_tuning_reset(host, ESDHC_SYS_CTRL_RSTA);
  89974. + /* This is balanced by the runtime put in sdhci_tasklet_finish */
  89975. pm_runtime_get_sync(host->mmc->parent);
  89976. reg = readl(host->ioaddr + ESDHC_MIX_CTRL);
  89977. reg |= ESDHC_MIX_CTRL_EXE_TUNE | ESDHC_MIX_CTRL_SMPCLK_SEL |
  89978. @@ -713,13 +755,12 @@
  89979. complete(&mrq->completion);
  89980. }
  89981. -static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode)
  89982. +static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode,
  89983. + struct scatterlist *sg)
  89984. {
  89985. struct mmc_command cmd = {0};
  89986. struct mmc_request mrq = {NULL};
  89987. struct mmc_data data = {0};
  89988. - struct scatterlist sg;
  89989. - char tuning_pattern[ESDHC_TUNING_BLOCK_PATTERN_LEN];
  89990. cmd.opcode = opcode;
  89991. cmd.arg = 0;
  89992. @@ -728,11 +769,9 @@
  89993. data.blksz = ESDHC_TUNING_BLOCK_PATTERN_LEN;
  89994. data.blocks = 1;
  89995. data.flags = MMC_DATA_READ;
  89996. - data.sg = &sg;
  89997. + data.sg = sg;
  89998. data.sg_len = 1;
  89999. - sg_init_one(&sg, tuning_pattern, sizeof(tuning_pattern));
  90000. -
  90001. mrq.cmd = &cmd;
  90002. mrq.cmd->mrq = &mrq;
  90003. mrq.data = &data;
  90004. @@ -742,14 +781,12 @@
  90005. mrq.done = esdhc_request_done;
  90006. init_completion(&(mrq.completion));
  90007. - disable_irq(host->irq);
  90008. - spin_lock(&host->lock);
  90009. + spin_lock_irq(&host->lock);
  90010. host->mrq = &mrq;
  90011. sdhci_send_command(host, mrq.cmd);
  90012. - spin_unlock(&host->lock);
  90013. - enable_irq(host->irq);
  90014. + spin_unlock_irq(&host->lock);
  90015. wait_for_completion(&mrq.completion);
  90016. @@ -772,13 +809,21 @@
  90017. static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
  90018. {
  90019. + struct scatterlist sg;
  90020. + char *tuning_pattern;
  90021. int min, max, avg, ret;
  90022. + tuning_pattern = kmalloc(ESDHC_TUNING_BLOCK_PATTERN_LEN, GFP_KERNEL);
  90023. + if (!tuning_pattern)
  90024. + return -ENOMEM;
  90025. +
  90026. + sg_init_one(&sg, tuning_pattern, ESDHC_TUNING_BLOCK_PATTERN_LEN);
  90027. +
  90028. /* find the mininum delay first which can pass tuning */
  90029. min = ESDHC_TUNE_CTRL_MIN;
  90030. while (min < ESDHC_TUNE_CTRL_MAX) {
  90031. esdhc_prepare_tuning(host, min);
  90032. - if (!esdhc_send_tuning_cmd(host, opcode))
  90033. + if (!esdhc_send_tuning_cmd(host, opcode, &sg))
  90034. break;
  90035. min += ESDHC_TUNE_CTRL_STEP;
  90036. }
  90037. @@ -787,7 +832,7 @@
  90038. max = min + ESDHC_TUNE_CTRL_STEP;
  90039. while (max < ESDHC_TUNE_CTRL_MAX) {
  90040. esdhc_prepare_tuning(host, max);
  90041. - if (esdhc_send_tuning_cmd(host, opcode)) {
  90042. + if (esdhc_send_tuning_cmd(host, opcode, &sg)) {
  90043. max -= ESDHC_TUNE_CTRL_STEP;
  90044. break;
  90045. }
  90046. @@ -797,9 +842,11 @@
  90047. /* use average delay to get the best timing */
  90048. avg = (min + max) / 2;
  90049. esdhc_prepare_tuning(host, avg);
  90050. - ret = esdhc_send_tuning_cmd(host, opcode);
  90051. + ret = esdhc_send_tuning_cmd(host, opcode, &sg);
  90052. esdhc_post_tuning(host);
  90053. + kfree(tuning_pattern);
  90054. +
  90055. dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n",
  90056. ret ? "failed" : "passed", avg, ret);
  90057. @@ -837,28 +884,20 @@
  90058. return pinctrl_select_state(imx_data->pinctrl, pinctrl);
  90059. }
  90060. -static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
  90061. +static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
  90062. {
  90063. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  90064. struct pltfm_imx_data *imx_data = pltfm_host->priv;
  90065. struct esdhc_platform_data *boarddata = &imx_data->boarddata;
  90066. - switch (uhs) {
  90067. + switch (timing) {
  90068. case MMC_TIMING_UHS_SDR12:
  90069. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR12;
  90070. - break;
  90071. case MMC_TIMING_UHS_SDR25:
  90072. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR25;
  90073. - break;
  90074. case MMC_TIMING_UHS_SDR50:
  90075. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR50;
  90076. - break;
  90077. case MMC_TIMING_UHS_SDR104:
  90078. case MMC_TIMING_MMC_HS200:
  90079. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR104;
  90080. break;
  90081. case MMC_TIMING_UHS_DDR50:
  90082. - imx_data->uhs_mode = SDHCI_CTRL_UHS_DDR50;
  90083. writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
  90084. ESDHC_MIX_CTRL_DDREN,
  90085. host->ioaddr + ESDHC_MIX_CTRL);
  90086. @@ -875,7 +914,20 @@
  90087. break;
  90088. }
  90089. - return esdhc_change_pinstate(host, uhs);
  90090. + esdhc_change_pinstate(host, timing);
  90091. +}
  90092. +
  90093. +static void esdhc_reset(struct sdhci_host *host, u8 mask)
  90094. +{
  90095. + sdhci_reset(host, mask);
  90096. +
  90097. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  90098. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  90099. +}
  90100. +
  90101. +static unsigned int esdhc_get_max_timeout_counter(struct sdhci_host *host)
  90102. +{
  90103. + return 1 << 28;
  90104. }
  90105. static struct sdhci_ops sdhci_esdhc_ops = {
  90106. @@ -888,8 +940,9 @@
  90107. .get_max_clock = esdhc_pltfm_get_max_clock,
  90108. .get_min_clock = esdhc_pltfm_get_min_clock,
  90109. .get_ro = esdhc_pltfm_get_ro,
  90110. - .platform_bus_width = esdhc_pltfm_bus_width,
  90111. + .set_bus_width = esdhc_pltfm_set_bus_width,
  90112. .set_uhs_signaling = esdhc_set_uhs_signaling,
  90113. + .reset = esdhc_reset,
  90114. };
  90115. static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
  90116. @@ -906,6 +959,7 @@
  90117. struct esdhc_platform_data *boarddata)
  90118. {
  90119. struct device_node *np = pdev->dev.of_node;
  90120. + struct sdhci_host *host = platform_get_drvdata(pdev);
  90121. if (!np)
  90122. return -ENODEV;
  90123. @@ -939,6 +993,12 @@
  90124. if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line))
  90125. boarddata->delay_line = 0;
  90126. + if (of_find_property(np, "keep-power-in-suspend", NULL))
  90127. + host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
  90128. +
  90129. + if (of_find_property(np, "enable-sdio-wakeup", NULL))
  90130. + host->mmc->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
  90131. +
  90132. return 0;
  90133. }
  90134. #else
  90135. @@ -994,6 +1054,9 @@
  90136. goto free_sdhci;
  90137. }
  90138. + if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
  90139. + request_bus_freq(BUS_FREQ_HIGH);
  90140. +
  90141. pltfm_host->clk = imx_data->clk_per;
  90142. pltfm_host->clock = clk_get_rate(pltfm_host->clk);
  90143. clk_prepare_enable(imx_data->clk_per);
  90144. @@ -1027,8 +1090,17 @@
  90145. */
  90146. if (esdhc_is_usdhc(imx_data)) {
  90147. writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
  90148. - host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
  90149. + host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
  90150. + SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER;
  90151. host->mmc->caps |= MMC_CAP_1_8V_DDR;
  90152. +
  90153. + /*
  90154. + * errata ESDHC_FLAG_ERR004536 fix for MX6Q TO1.2 and MX6DL
  90155. + * TO1.1, it's harmless for MX6SL
  90156. + */
  90157. + writel(readl(host->ioaddr + 0x6c) | BIT(7), host->ioaddr + 0x6c);
  90158. + sdhci_esdhc_ops.get_max_timeout_counter =
  90159. + esdhc_get_max_timeout_counter;
  90160. }
  90161. if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
  90162. @@ -1040,6 +1112,9 @@
  90163. ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP,
  90164. host->ioaddr + ESDHC_TUNING_CTRL);
  90165. + if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
  90166. + host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
  90167. +
  90168. boarddata = &imx_data->boarddata;
  90169. if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
  90170. if (!host->mmc->parent->platform_data) {
  90171. @@ -1116,6 +1191,10 @@
  90172. host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
  90173. }
  90174. + if (host->mmc->pm_caps & MMC_PM_KEEP_POWER &&
  90175. + host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ)
  90176. + device_init_wakeup(&pdev->dev, 1);
  90177. +
  90178. err = sdhci_add_host(host);
  90179. if (err)
  90180. goto disable_clk;
  90181. @@ -1132,6 +1211,8 @@
  90182. clk_disable_unprepare(imx_data->clk_per);
  90183. clk_disable_unprepare(imx_data->clk_ipg);
  90184. clk_disable_unprepare(imx_data->clk_ahb);
  90185. + if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
  90186. + release_bus_freq(BUS_FREQ_HIGH);
  90187. free_sdhci:
  90188. sdhci_pltfm_free(pdev);
  90189. return err;
  90190. @@ -1170,10 +1251,15 @@
  90191. ret = sdhci_runtime_suspend_host(host);
  90192. - clk_disable_unprepare(imx_data->clk_per);
  90193. - clk_disable_unprepare(imx_data->clk_ipg);
  90194. + if (!sdhci_sdio_irq_enabled(host)) {
  90195. + clk_disable_unprepare(imx_data->clk_per);
  90196. + clk_disable_unprepare(imx_data->clk_ipg);
  90197. + }
  90198. clk_disable_unprepare(imx_data->clk_ahb);
  90199. + if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
  90200. + release_bus_freq(BUS_FREQ_HIGH);
  90201. +
  90202. return ret;
  90203. }
  90204. @@ -1183,8 +1269,10 @@
  90205. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  90206. struct pltfm_imx_data *imx_data = pltfm_host->priv;
  90207. - clk_prepare_enable(imx_data->clk_per);
  90208. - clk_prepare_enable(imx_data->clk_ipg);
  90209. + if (!sdhci_sdio_irq_enabled(host)) {
  90210. + clk_prepare_enable(imx_data->clk_per);
  90211. + clk_prepare_enable(imx_data->clk_ipg);
  90212. + }
  90213. clk_prepare_enable(imx_data->clk_ahb);
  90214. return sdhci_runtime_resume_host(host);
  90215. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci.h linux-imx6-3.14/drivers/mmc/host/sdhci.h
  90216. --- linux-3.14.14/drivers/mmc/host/sdhci.h 2014-07-28 10:07:25.000000000 -0500
  90217. +++ linux-imx6-3.14/drivers/mmc/host/sdhci.h 2014-12-08 00:31:53.428418001 -0600
  90218. @@ -281,18 +281,15 @@
  90219. unsigned int (*get_max_clock)(struct sdhci_host *host);
  90220. unsigned int (*get_min_clock)(struct sdhci_host *host);
  90221. unsigned int (*get_timeout_clock)(struct sdhci_host *host);
  90222. - int (*platform_bus_width)(struct sdhci_host *host,
  90223. - int width);
  90224. + unsigned int (*get_max_timeout_counter)(struct sdhci_host *host);
  90225. + void (*set_bus_width)(struct sdhci_host *host, int width);
  90226. void (*platform_send_init_74_clocks)(struct sdhci_host *host,
  90227. u8 power_mode);
  90228. unsigned int (*get_ro)(struct sdhci_host *host);
  90229. - void (*platform_reset_enter)(struct sdhci_host *host, u8 mask);
  90230. - void (*platform_reset_exit)(struct sdhci_host *host, u8 mask);
  90231. + void (*reset)(struct sdhci_host *host, u8 mask);
  90232. int (*platform_execute_tuning)(struct sdhci_host *host, u32 opcode);
  90233. - int (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
  90234. + void (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
  90235. void (*hw_reset)(struct sdhci_host *host);
  90236. - void (*platform_suspend)(struct sdhci_host *host);
  90237. - void (*platform_resume)(struct sdhci_host *host);
  90238. void (*adma_workaround)(struct sdhci_host *host, u32 intmask);
  90239. void (*platform_init)(struct sdhci_host *host);
  90240. void (*card_event)(struct sdhci_host *host);
  90241. @@ -397,6 +394,16 @@
  90242. extern void sdhci_send_command(struct sdhci_host *host,
  90243. struct mmc_command *cmd);
  90244. +static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
  90245. +{
  90246. + return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
  90247. +}
  90248. +
  90249. +void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
  90250. +void sdhci_set_bus_width(struct sdhci_host *host, int width);
  90251. +void sdhci_reset(struct sdhci_host *host, u8 mask);
  90252. +void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
  90253. +
  90254. #ifdef CONFIG_PM
  90255. extern int sdhci_suspend_host(struct sdhci_host *host);
  90256. extern int sdhci_resume_host(struct sdhci_host *host);
  90257. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-of-arasan.c linux-imx6-3.14/drivers/mmc/host/sdhci-of-arasan.c
  90258. --- linux-3.14.14/drivers/mmc/host/sdhci-of-arasan.c 2014-07-28 10:07:25.000000000 -0500
  90259. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-of-arasan.c 2014-12-08 00:31:53.428418001 -0600
  90260. @@ -52,8 +52,12 @@
  90261. }
  90262. static struct sdhci_ops sdhci_arasan_ops = {
  90263. + .set_clock = sdhci_set_clock,
  90264. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  90265. .get_timeout_clock = sdhci_arasan_get_timeout_clock,
  90266. + .set_bus_width = sdhci_set_bus_width,
  90267. + .reset = sdhci_reset,
  90268. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90269. };
  90270. static struct sdhci_pltfm_data sdhci_arasan_pdata = {
  90271. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-of-esdhc.c linux-imx6-3.14/drivers/mmc/host/sdhci-of-esdhc.c
  90272. --- linux-3.14.14/drivers/mmc/host/sdhci-of-esdhc.c 2014-07-28 10:07:25.000000000 -0500
  90273. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-of-esdhc.c 2014-12-08 00:31:53.428418001 -0600
  90274. @@ -199,13 +199,14 @@
  90275. static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
  90276. {
  90277. -
  90278. int pre_div = 2;
  90279. int div = 1;
  90280. u32 temp;
  90281. + host->mmc->actual_clock = 0;
  90282. +
  90283. if (clock == 0)
  90284. - goto out;
  90285. + return;
  90286. /* Workaround to reduce the clock frequency for p1010 esdhc */
  90287. if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
  90288. @@ -238,24 +239,8 @@
  90289. | (pre_div << ESDHC_PREDIV_SHIFT));
  90290. sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
  90291. mdelay(1);
  90292. -out:
  90293. - host->clock = clock;
  90294. }
  90295. -#ifdef CONFIG_PM
  90296. -static u32 esdhc_proctl;
  90297. -static void esdhc_of_suspend(struct sdhci_host *host)
  90298. -{
  90299. - esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
  90300. -}
  90301. -
  90302. -static void esdhc_of_resume(struct sdhci_host *host)
  90303. -{
  90304. - esdhc_of_enable_dma(host);
  90305. - sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
  90306. -}
  90307. -#endif
  90308. -
  90309. static void esdhc_of_platform_init(struct sdhci_host *host)
  90310. {
  90311. u32 vvn;
  90312. @@ -269,7 +254,7 @@
  90313. host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
  90314. }
  90315. -static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
  90316. +static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
  90317. {
  90318. u32 ctrl;
  90319. @@ -289,8 +274,6 @@
  90320. clrsetbits_be32(host->ioaddr + SDHCI_HOST_CONTROL,
  90321. ESDHC_CTRL_BUSWIDTH_MASK, ctrl);
  90322. -
  90323. - return 0;
  90324. }
  90325. static const struct sdhci_ops sdhci_esdhc_ops = {
  90326. @@ -305,13 +288,46 @@
  90327. .get_max_clock = esdhc_of_get_max_clock,
  90328. .get_min_clock = esdhc_of_get_min_clock,
  90329. .platform_init = esdhc_of_platform_init,
  90330. -#ifdef CONFIG_PM
  90331. - .platform_suspend = esdhc_of_suspend,
  90332. - .platform_resume = esdhc_of_resume,
  90333. -#endif
  90334. .adma_workaround = esdhci_of_adma_workaround,
  90335. - .platform_bus_width = esdhc_pltfm_bus_width,
  90336. + .set_bus_width = esdhc_pltfm_set_bus_width,
  90337. + .reset = sdhci_reset,
  90338. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90339. +};
  90340. +
  90341. +#ifdef CONFIG_PM
  90342. +
  90343. +static u32 esdhc_proctl;
  90344. +static int esdhc_of_suspend(struct device *dev)
  90345. +{
  90346. + struct sdhci_host *host = dev_get_drvdata(dev);
  90347. +
  90348. + esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
  90349. +
  90350. + return sdhci_suspend_host(host);
  90351. +}
  90352. +
  90353. +static void esdhc_of_resume(device *dev)
  90354. +{
  90355. + struct sdhci_host *host = dev_get_drvdata(dev);
  90356. + int ret = sdhci_resume_host(host);
  90357. +
  90358. + if (ret == 0) {
  90359. + /* Isn't this already done by sdhci_resume_host() ? --rmk */
  90360. + esdhc_of_enable_dma(host);
  90361. + sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
  90362. + }
  90363. +
  90364. + return ret;
  90365. +}
  90366. +
  90367. +static const struct dev_pm_ops esdhc_pmops = {
  90368. + .suspend = esdhci_of_suspend,
  90369. + .resume = esdhci_of_resume,
  90370. };
  90371. +#define ESDHC_PMOPS (&esdhc_pmops)
  90372. +#else
  90373. +#define ESDHC_PMOPS NULL
  90374. +#endif
  90375. static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
  90376. /*
  90377. @@ -374,7 +390,7 @@
  90378. .name = "sdhci-esdhc",
  90379. .owner = THIS_MODULE,
  90380. .of_match_table = sdhci_esdhc_of_match,
  90381. - .pm = SDHCI_PLTFM_PMOPS,
  90382. + .pm = ESDHC_PMOPS,
  90383. },
  90384. .probe = sdhci_esdhc_probe,
  90385. .remove = sdhci_esdhc_remove,
  90386. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-of-hlwd.c linux-imx6-3.14/drivers/mmc/host/sdhci-of-hlwd.c
  90387. --- linux-3.14.14/drivers/mmc/host/sdhci-of-hlwd.c 2014-07-28 10:07:25.000000000 -0500
  90388. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-of-hlwd.c 2014-12-08 00:31:53.428418001 -0600
  90389. @@ -58,6 +58,10 @@
  90390. .write_l = sdhci_hlwd_writel,
  90391. .write_w = sdhci_hlwd_writew,
  90392. .write_b = sdhci_hlwd_writeb,
  90393. + .set_clock = sdhci_set_clock,
  90394. + .set_bus_width = sdhci_set_bus_width,
  90395. + .reset = sdhci_reset,
  90396. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90397. };
  90398. static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
  90399. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-pci.c linux-imx6-3.14/drivers/mmc/host/sdhci-pci.c
  90400. --- linux-3.14.14/drivers/mmc/host/sdhci-pci.c 2014-07-28 10:07:25.000000000 -0500
  90401. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-pci.c 2014-12-08 00:31:53.428418001 -0600
  90402. @@ -1011,7 +1011,7 @@
  90403. return 0;
  90404. }
  90405. -static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
  90406. +static void sdhci_pci_set_bus_width(struct sdhci_host *host, int width)
  90407. {
  90408. u8 ctrl;
  90409. @@ -1032,8 +1032,6 @@
  90410. }
  90411. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  90412. -
  90413. - return 0;
  90414. }
  90415. static void sdhci_pci_gpio_hw_reset(struct sdhci_host *host)
  90416. @@ -1060,8 +1058,11 @@
  90417. }
  90418. static const struct sdhci_ops sdhci_pci_ops = {
  90419. + .set_clock = sdhci_set_clock,
  90420. .enable_dma = sdhci_pci_enable_dma,
  90421. - .platform_bus_width = sdhci_pci_bus_width,
  90422. + .set_bus_width = sdhci_pci_set_bus_width,
  90423. + .reset = sdhci_reset,
  90424. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90425. .hw_reset = sdhci_pci_hw_reset,
  90426. };
  90427. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-pltfm.c linux-imx6-3.14/drivers/mmc/host/sdhci-pltfm.c
  90428. --- linux-3.14.14/drivers/mmc/host/sdhci-pltfm.c 2014-07-28 10:07:25.000000000 -0500
  90429. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-pltfm.c 2014-12-08 00:31:53.428418001 -0600
  90430. @@ -45,6 +45,10 @@
  90431. EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
  90432. static const struct sdhci_ops sdhci_pltfm_ops = {
  90433. + .set_clock = sdhci_set_clock,
  90434. + .set_bus_width = sdhci_set_bus_width,
  90435. + .reset = sdhci_reset,
  90436. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90437. };
  90438. #ifdef CONFIG_OF
  90439. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-pxav2.c linux-imx6-3.14/drivers/mmc/host/sdhci-pxav2.c
  90440. --- linux-3.14.14/drivers/mmc/host/sdhci-pxav2.c 2014-07-28 10:07:25.000000000 -0500
  90441. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-pxav2.c 2014-12-08 00:31:53.428418001 -0600
  90442. @@ -51,11 +51,13 @@
  90443. #define MMC_CARD 0x1000
  90444. #define MMC_WIDTH 0x0100
  90445. -static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask)
  90446. +static void pxav2_reset(struct sdhci_host *host, u8 mask)
  90447. {
  90448. struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
  90449. struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
  90450. + sdhci_reset(host, mask);
  90451. +
  90452. if (mask == SDHCI_RESET_ALL) {
  90453. u16 tmp = 0;
  90454. @@ -88,7 +90,7 @@
  90455. }
  90456. }
  90457. -static int pxav2_mmc_set_width(struct sdhci_host *host, int width)
  90458. +static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
  90459. {
  90460. u8 ctrl;
  90461. u16 tmp;
  90462. @@ -107,14 +109,14 @@
  90463. }
  90464. writew(tmp, host->ioaddr + SD_CE_ATA_2);
  90465. writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
  90466. -
  90467. - return 0;
  90468. }
  90469. static const struct sdhci_ops pxav2_sdhci_ops = {
  90470. + .set_clock = sdhci_set_clock,
  90471. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  90472. - .platform_reset_exit = pxav2_set_private_registers,
  90473. - .platform_bus_width = pxav2_mmc_set_width,
  90474. + .set_bus_width = pxav2_mmc_set_bus_width,
  90475. + .reset = pxav2_reset,
  90476. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90477. };
  90478. #ifdef CONFIG_OF
  90479. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-pxav3.c linux-imx6-3.14/drivers/mmc/host/sdhci-pxav3.c
  90480. --- linux-3.14.14/drivers/mmc/host/sdhci-pxav3.c 2014-07-28 10:07:25.000000000 -0500
  90481. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-pxav3.c 2014-12-08 00:31:53.428418001 -0600
  90482. @@ -57,11 +57,13 @@
  90483. #define SDCE_MISC_INT (1<<2)
  90484. #define SDCE_MISC_INT_EN (1<<1)
  90485. -static void pxav3_set_private_registers(struct sdhci_host *host, u8 mask)
  90486. +static void pxav3_reset(struct sdhci_host *host, u8 mask)
  90487. {
  90488. struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
  90489. struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
  90490. + sdhci_reset(host, mask);
  90491. +
  90492. if (mask == SDHCI_RESET_ALL) {
  90493. /*
  90494. * tune timing of read data/command when crc error happen
  90495. @@ -129,7 +131,7 @@
  90496. pxa->power_mode = power_mode;
  90497. }
  90498. -static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
  90499. +static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
  90500. {
  90501. u16 ctrl_2;
  90502. @@ -163,15 +165,16 @@
  90503. dev_dbg(mmc_dev(host->mmc),
  90504. "%s uhs = %d, ctrl_2 = %04X\n",
  90505. __func__, uhs, ctrl_2);
  90506. -
  90507. - return 0;
  90508. }
  90509. static const struct sdhci_ops pxav3_sdhci_ops = {
  90510. - .platform_reset_exit = pxav3_set_private_registers,
  90511. + .set_clock = sdhci_set_clock,
  90512. .set_uhs_signaling = pxav3_set_uhs_signaling,
  90513. .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
  90514. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  90515. + .set_bus_width = sdhci_set_bus_width,
  90516. + .reset = pxav3_reset,
  90517. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90518. };
  90519. static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
  90520. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-s3c.c linux-imx6-3.14/drivers/mmc/host/sdhci-s3c.c
  90521. --- linux-3.14.14/drivers/mmc/host/sdhci-s3c.c 2014-07-28 10:07:25.000000000 -0500
  90522. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-s3c.c 2014-12-08 00:31:53.428418001 -0600
  90523. @@ -57,6 +57,8 @@
  90524. struct clk *clk_io;
  90525. struct clk *clk_bus[MAX_BUS_CLK];
  90526. +
  90527. + bool no_divider;
  90528. };
  90529. /**
  90530. @@ -69,6 +71,7 @@
  90531. */
  90532. struct sdhci_s3c_drv_data {
  90533. unsigned int sdhci_quirks;
  90534. + bool no_divider;
  90535. };
  90536. static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
  90537. @@ -153,7 +156,7 @@
  90538. * If controller uses a non-standard clock division, find the best clock
  90539. * speed possible with selected clock source and skip the division.
  90540. */
  90541. - if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
  90542. + if (ourhost->no_divider) {
  90543. rate = clk_round_rate(clksrc, wanted);
  90544. return wanted - rate;
  90545. }
  90546. @@ -188,9 +191,13 @@
  90547. int src;
  90548. u32 ctrl;
  90549. + host->mmc->actual_clock = 0;
  90550. +
  90551. /* don't bother if the clock is going off. */
  90552. - if (clock == 0)
  90553. + if (clock == 0) {
  90554. + sdhci_set_clock(host, clock);
  90555. return;
  90556. + }
  90557. for (src = 0; src < MAX_BUS_CLK; src++) {
  90558. delta = sdhci_s3c_consider_clock(ourhost, src, clock);
  90559. @@ -240,6 +247,8 @@
  90560. if (clock < 25 * 1000000)
  90561. ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2);
  90562. writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3);
  90563. +
  90564. + sdhci_set_clock(host, clock);
  90565. }
  90566. /**
  90567. @@ -296,10 +305,11 @@
  90568. unsigned long timeout;
  90569. u16 clk = 0;
  90570. + host->mmc->actual_clock = 0;
  90571. +
  90572. /* If the clock is going off, set to 0 at clock control register */
  90573. if (clock == 0) {
  90574. sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
  90575. - host->clock = clock;
  90576. return;
  90577. }
  90578. @@ -307,8 +317,6 @@
  90579. clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
  90580. - host->clock = clock;
  90581. -
  90582. clk = SDHCI_CLOCK_INT_EN;
  90583. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  90584. @@ -330,14 +338,14 @@
  90585. }
  90586. /**
  90587. - * sdhci_s3c_platform_bus_width - support 8bit buswidth
  90588. + * sdhci_s3c_set_bus_width - support 8bit buswidth
  90589. * @host: The SDHCI host being queried
  90590. * @width: MMC_BUS_WIDTH_ macro for the bus width being requested
  90591. *
  90592. * We have 8-bit width support but is not a v3 controller.
  90593. * So we add platform_bus_width() and support 8bit width.
  90594. */
  90595. -static int sdhci_s3c_platform_bus_width(struct sdhci_host *host, int width)
  90596. +static void sdhci_s3c_set_bus_width(struct sdhci_host *host, int width)
  90597. {
  90598. u8 ctrl;
  90599. @@ -359,15 +367,15 @@
  90600. }
  90601. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  90602. -
  90603. - return 0;
  90604. }
  90605. static struct sdhci_ops sdhci_s3c_ops = {
  90606. .get_max_clock = sdhci_s3c_get_max_clk,
  90607. .set_clock = sdhci_s3c_set_clock,
  90608. .get_min_clock = sdhci_s3c_get_min_clock,
  90609. - .platform_bus_width = sdhci_s3c_platform_bus_width,
  90610. + .set_bus_width = sdhci_s3c_set_bus_width,
  90611. + .reset = sdhci_reset,
  90612. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90613. };
  90614. static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
  90615. @@ -617,8 +625,10 @@
  90616. /* Setup quirks for the controller */
  90617. host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
  90618. host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
  90619. - if (drv_data)
  90620. + if (drv_data) {
  90621. host->quirks |= drv_data->sdhci_quirks;
  90622. + sc->no_divider = drv_data->no_divider;
  90623. + }
  90624. #ifndef CONFIG_MMC_SDHCI_S3C_DMA
  90625. @@ -667,7 +677,7 @@
  90626. * If controller does not have internal clock divider,
  90627. * we can use overriding functions instead of default.
  90628. */
  90629. - if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
  90630. + if (sc->no_divider) {
  90631. sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
  90632. sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
  90633. sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
  90634. @@ -813,7 +823,7 @@
  90635. #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
  90636. static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
  90637. - .sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK,
  90638. + .no_divider = true,
  90639. };
  90640. #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
  90641. #else
  90642. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-sirf.c linux-imx6-3.14/drivers/mmc/host/sdhci-sirf.c
  90643. --- linux-3.14.14/drivers/mmc/host/sdhci-sirf.c 2014-07-28 10:07:25.000000000 -0500
  90644. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-sirf.c 2014-12-08 00:31:53.428418001 -0600
  90645. @@ -28,7 +28,11 @@
  90646. }
  90647. static struct sdhci_ops sdhci_sirf_ops = {
  90648. + .set_clock = sdhci_set_clock,
  90649. .get_max_clock = sdhci_sirf_get_max_clk,
  90650. + .set_bus_width = sdhci_set_bus_width,
  90651. + .reset = sdhci_reset,
  90652. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90653. };
  90654. static struct sdhci_pltfm_data sdhci_sirf_pdata = {
  90655. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-spear.c linux-imx6-3.14/drivers/mmc/host/sdhci-spear.c
  90656. --- linux-3.14.14/drivers/mmc/host/sdhci-spear.c 2014-07-28 10:07:25.000000000 -0500
  90657. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-spear.c 2014-12-08 00:31:53.428418001 -0600
  90658. @@ -37,7 +37,10 @@
  90659. /* sdhci ops */
  90660. static const struct sdhci_ops sdhci_pltfm_ops = {
  90661. - /* Nothing to do for now. */
  90662. + .set_clock = sdhci_set_clock,
  90663. + .set_bus_width = sdhci_set_bus_width,
  90664. + .reset = sdhci_reset,
  90665. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90666. };
  90667. /* gpio card detection interrupt handler */
  90668. diff -Nur linux-3.14.14/drivers/mmc/host/sdhci-tegra.c linux-imx6-3.14/drivers/mmc/host/sdhci-tegra.c
  90669. --- linux-3.14.14/drivers/mmc/host/sdhci-tegra.c 2014-07-28 10:07:25.000000000 -0500
  90670. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-tegra.c 2014-12-08 00:31:53.428418001 -0600
  90671. @@ -48,19 +48,6 @@
  90672. int power_gpio;
  90673. };
  90674. -static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg)
  90675. -{
  90676. - u32 val;
  90677. -
  90678. - if (unlikely(reg == SDHCI_PRESENT_STATE)) {
  90679. - /* Use wp_gpio here instead? */
  90680. - val = readl(host->ioaddr + reg);
  90681. - return val | SDHCI_WRITE_PROTECT;
  90682. - }
  90683. -
  90684. - return readl(host->ioaddr + reg);
  90685. -}
  90686. -
  90687. static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
  90688. {
  90689. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  90690. @@ -108,12 +95,14 @@
  90691. return mmc_gpio_get_ro(host->mmc);
  90692. }
  90693. -static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask)
  90694. +static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
  90695. {
  90696. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  90697. struct sdhci_tegra *tegra_host = pltfm_host->priv;
  90698. const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
  90699. + sdhci_reset(host, mask);
  90700. +
  90701. if (!(mask & SDHCI_RESET_ALL))
  90702. return;
  90703. @@ -127,7 +116,7 @@
  90704. }
  90705. }
  90706. -static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width)
  90707. +static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
  90708. {
  90709. u32 ctrl;
  90710. @@ -144,16 +133,16 @@
  90711. ctrl &= ~SDHCI_CTRL_4BITBUS;
  90712. }
  90713. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  90714. - return 0;
  90715. }
  90716. static const struct sdhci_ops tegra_sdhci_ops = {
  90717. .get_ro = tegra_sdhci_get_ro,
  90718. - .read_l = tegra_sdhci_readl,
  90719. .read_w = tegra_sdhci_readw,
  90720. .write_l = tegra_sdhci_writel,
  90721. - .platform_bus_width = tegra_sdhci_buswidth,
  90722. - .platform_reset_exit = tegra_sdhci_reset_exit,
  90723. + .set_clock = sdhci_set_clock,
  90724. + .set_bus_width = tegra_sdhci_set_bus_width,
  90725. + .reset = tegra_sdhci_reset,
  90726. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90727. };
  90728. static const struct sdhci_pltfm_data sdhci_tegra20_pdata = {
  90729. diff -Nur linux-3.14.14/drivers/mtd/chips/cfi_cmdset_0002.c linux-imx6-3.14/drivers/mtd/chips/cfi_cmdset_0002.c
  90730. --- linux-3.14.14/drivers/mtd/chips/cfi_cmdset_0002.c 2014-07-28 10:07:25.000000000 -0500
  90731. +++ linux-imx6-3.14/drivers/mtd/chips/cfi_cmdset_0002.c 2014-12-08 00:31:53.432418001 -0600
  90732. @@ -1058,17 +1058,13 @@
  90733. #define UDELAY(map, chip, adr, usec) \
  90734. do { \
  90735. - mutex_unlock(&chip->mutex); \
  90736. cfi_udelay(usec); \
  90737. - mutex_lock(&chip->mutex); \
  90738. } while (0)
  90739. #define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \
  90740. do { \
  90741. - mutex_unlock(&chip->mutex); \
  90742. INVALIDATE_CACHED_RANGE(map, adr, len); \
  90743. cfi_udelay(usec); \
  90744. - mutex_lock(&chip->mutex); \
  90745. } while (0)
  90746. #endif
  90747. diff -Nur linux-3.14.14/drivers/mtd/ubi/build.c linux-imx6-3.14/drivers/mtd/ubi/build.c
  90748. --- linux-3.14.14/drivers/mtd/ubi/build.c 2014-07-28 10:07:25.000000000 -0500
  90749. +++ linux-imx6-3.14/drivers/mtd/ubi/build.c 2014-12-08 00:31:53.456418001 -0600
  90750. @@ -640,7 +640,7 @@
  90751. dbg_gen("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb));
  90752. dbg_gen("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry));
  90753. - if (ubi->mtd->numeraseregions != 0) {
  90754. + if (ubi->mtd->numeraseregions > 1) {
  90755. /*
  90756. * Some flashes have several erase regions. Different regions
  90757. * may have different eraseblock size and other
  90758. diff -Nur linux-3.14.14/drivers/mxc/asrc/Kconfig linux-imx6-3.14/drivers/mxc/asrc/Kconfig
  90759. --- linux-3.14.14/drivers/mxc/asrc/Kconfig 1969-12-31 18:00:00.000000000 -0600
  90760. +++ linux-imx6-3.14/drivers/mxc/asrc/Kconfig 2014-12-08 00:31:53.460418001 -0600
  90761. @@ -0,0 +1,14 @@
  90762. +#
  90763. +# ASRC configuration
  90764. +#
  90765. +
  90766. +menu "MXC Asynchronous Sample Rate Converter support"
  90767. +
  90768. +config MXC_ASRC
  90769. + tristate "ASRC support"
  90770. + depends on SOC_IMX35 || SOC_IMX53 || SOC_IMX6Q
  90771. + select SND_SOC_FSL_ASRC
  90772. + ---help---
  90773. + Say Y to get the ASRC service.
  90774. +
  90775. +endmenu
  90776. diff -Nur linux-3.14.14/drivers/mxc/asrc/Makefile linux-imx6-3.14/drivers/mxc/asrc/Makefile
  90777. --- linux-3.14.14/drivers/mxc/asrc/Makefile 1969-12-31 18:00:00.000000000 -0600
  90778. +++ linux-imx6-3.14/drivers/mxc/asrc/Makefile 2014-12-08 00:31:53.460418001 -0600
  90779. @@ -0,0 +1,4 @@
  90780. +#
  90781. +# Makefile for the kernel Asynchronous Sample Rate Converter driver
  90782. +#
  90783. +obj-$(CONFIG_MXC_ASRC) += mxc_asrc.o
  90784. diff -Nur linux-3.14.14/drivers/mxc/asrc/mxc_asrc.c linux-imx6-3.14/drivers/mxc/asrc/mxc_asrc.c
  90785. --- linux-3.14.14/drivers/mxc/asrc/mxc_asrc.c 1969-12-31 18:00:00.000000000 -0600
  90786. +++ linux-imx6-3.14/drivers/mxc/asrc/mxc_asrc.c 2014-12-08 00:31:53.460418001 -0600
  90787. @@ -0,0 +1,1957 @@
  90788. +/*
  90789. + * Freescale Asynchronous Sample Rate Converter (ASRC) driver
  90790. + *
  90791. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  90792. + *
  90793. + * This file is licensed under the terms of the GNU General Public License
  90794. + * version 2. This program is licensed "as is" without any warranty of any
  90795. + * kind, whether express or implied.
  90796. + */
  90797. +
  90798. +#include <linux/clk.h>
  90799. +#include <linux/slab.h>
  90800. +#include <linux/delay.h>
  90801. +#include <linux/sched.h>
  90802. +#include <linux/regmap.h>
  90803. +#include <linux/module.h>
  90804. +#include <linux/proc_fs.h>
  90805. +#include <linux/pagemap.h>
  90806. +#include <linux/interrupt.h>
  90807. +#include <linux/miscdevice.h>
  90808. +#include <linux/dma-mapping.h>
  90809. +#include <linux/of_platform.h>
  90810. +#include <linux/platform_data/dma-imx.h>
  90811. +
  90812. +#include <linux/mxc_asrc.h>
  90813. +
  90814. +#define ASRC_PROC_PATH "driver/asrc"
  90815. +
  90816. +#define ASRC_RATIO_DECIMAL_DEPTH 26
  90817. +
  90818. +#define pair_err(fmt, ...) \
  90819. + dev_err(asrc->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
  90820. +
  90821. +#define pair_dbg(fmt, ...) \
  90822. + dev_dbg(asrc->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
  90823. +
  90824. +DEFINE_SPINLOCK(data_lock);
  90825. +DEFINE_SPINLOCK(pair_lock);
  90826. +
  90827. +/* Sample rates are aligned with that defined in pcm.h file */
  90828. +static const unsigned char asrc_process_table[][8][2] = {
  90829. + /* 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */
  90830. + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */
  90831. + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */
  90832. + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */
  90833. + {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */
  90834. + {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */
  90835. + {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */
  90836. + {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */
  90837. + {{0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */
  90838. + {{1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */
  90839. + {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */
  90840. + {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */
  90841. + {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */
  90842. + {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */
  90843. +};
  90844. +
  90845. +static struct asrc_data *asrc;
  90846. +
  90847. +/*
  90848. + * The following tables map the relationship between asrc_inclk/asrc_outclk in
  90849. + * mxc_asrc.h and the registers of ASRCSR
  90850. + */
  90851. +static unsigned char input_clk_map_v1[] = {
  90852. + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
  90853. +};
  90854. +
  90855. +static unsigned char output_clk_map_v1[] = {
  90856. + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
  90857. +};
  90858. +
  90859. +/* V2 uses the same map for input and output */
  90860. +static unsigned char input_clk_map_v2[] = {
  90861. +/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
  90862. + 0x0, 0x1, 0x2, 0x7, 0x4, 0x5, 0x6, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xe, 0xd,
  90863. +};
  90864. +
  90865. +static unsigned char output_clk_map_v2[] = {
  90866. +/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
  90867. + 0x8, 0x9, 0xa, 0x7, 0xc, 0x5, 0x6, 0xb, 0x0, 0x1, 0x2, 0x3, 0x4, 0xf, 0xe, 0xd,
  90868. +};
  90869. +
  90870. +static unsigned char *input_clk_map, *output_clk_map;
  90871. +
  90872. +enum mxc_asrc_type {
  90873. + IMX35_ASRC,
  90874. + IMX53_ASRC,
  90875. +};
  90876. +
  90877. +static const struct platform_device_id mxc_asrc_devtype[] = {
  90878. + {
  90879. + .name = "imx35-asrc",
  90880. + .driver_data = IMX35_ASRC,
  90881. + }, {
  90882. + .name = "imx53-asrc",
  90883. + .driver_data = IMX53_ASRC,
  90884. + }, {
  90885. + /* sentinel */
  90886. + }
  90887. +};
  90888. +MODULE_DEVICE_TABLE(platform, mxc_asrc_devtype);
  90889. +
  90890. +static const struct of_device_id fsl_asrc_ids[] = {
  90891. + {
  90892. + .compatible = "fsl,imx35-asrc",
  90893. + .data = &mxc_asrc_devtype[IMX35_ASRC],
  90894. + }, {
  90895. + .compatible = "fsl,imx53-asrc",
  90896. + .data = &mxc_asrc_devtype[IMX53_ASRC],
  90897. + }, {
  90898. + /* sentinel */
  90899. + }
  90900. +};
  90901. +MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
  90902. +
  90903. +
  90904. +#ifdef DEBUG
  90905. +u32 asrc_reg[] = {
  90906. + REG_ASRCTR,
  90907. + REG_ASRIER,
  90908. + REG_ASRCNCR,
  90909. + REG_ASRCFG,
  90910. + REG_ASRCSR,
  90911. + REG_ASRCDR1,
  90912. + REG_ASRCDR2,
  90913. + REG_ASRSTR,
  90914. + REG_ASRRA,
  90915. + REG_ASRRB,
  90916. + REG_ASRRC,
  90917. + REG_ASRPM1,
  90918. + REG_ASRPM2,
  90919. + REG_ASRPM3,
  90920. + REG_ASRPM4,
  90921. + REG_ASRPM5,
  90922. + REG_ASRTFR1,
  90923. + REG_ASRCCR,
  90924. + REG_ASRIDRHA,
  90925. + REG_ASRIDRLA,
  90926. + REG_ASRIDRHB,
  90927. + REG_ASRIDRLB,
  90928. + REG_ASRIDRHC,
  90929. + REG_ASRIDRLC,
  90930. + REG_ASR76K,
  90931. + REG_ASR56K,
  90932. + REG_ASRMCRA,
  90933. + REG_ASRFSTA,
  90934. + REG_ASRMCRB,
  90935. + REG_ASRFSTB,
  90936. + REG_ASRMCRC,
  90937. + REG_ASRFSTC,
  90938. + REG_ASRMCR1A,
  90939. + REG_ASRMCR1B,
  90940. + REG_ASRMCR1C,
  90941. +};
  90942. +
  90943. +static void dump_regs(void)
  90944. +{
  90945. + u32 reg, val;
  90946. + int i;
  90947. +
  90948. + for (i = 0; i < ARRAY_SIZE(asrc_reg); i++) {
  90949. + reg = asrc_reg[i];
  90950. + regmap_read(asrc->regmap, reg, &val);
  90951. + dev_dbg(asrc->dev, "REG addr=0x%x val=0x%x\n", reg, val);
  90952. + }
  90953. +}
  90954. +#else
  90955. +static void dump_regs(void) {}
  90956. +#endif
  90957. +
  90958. +/* Only used for Ideal Ratio mode */
  90959. +static int asrc_set_clock_ratio(enum asrc_pair_index index,
  90960. + int inrate, int outrate)
  90961. +{
  90962. + unsigned long val = 0;
  90963. + int integ, i;
  90964. +
  90965. + if (outrate == 0) {
  90966. + dev_err(asrc->dev, "wrong output sample rate: %d\n", outrate);
  90967. + return -EINVAL;
  90968. + }
  90969. +
  90970. + /* Formula: r = (1 << ASRC_RATIO_DECIMAL_DEPTH) / outrate * inrate; */
  90971. + for (integ = 0; inrate >= outrate; integ++)
  90972. + inrate -= outrate;
  90973. +
  90974. + val |= (integ << ASRC_RATIO_DECIMAL_DEPTH);
  90975. +
  90976. + for (i = 1; i <= ASRC_RATIO_DECIMAL_DEPTH; i++) {
  90977. + if ((inrate * 2) >= outrate) {
  90978. + val |= (1 << (ASRC_RATIO_DECIMAL_DEPTH - i));
  90979. + inrate = inrate * 2 - outrate;
  90980. + } else
  90981. + inrate = inrate << 1;
  90982. +
  90983. + if (inrate == 0)
  90984. + break;
  90985. + }
  90986. +
  90987. + regmap_write(asrc->regmap, REG_ASRIDRL(index), val);
  90988. + regmap_write(asrc->regmap, REG_ASRIDRH(index), (val >> 24));
  90989. +
  90990. + return 0;
  90991. +}
  90992. +
  90993. +/* Corresponding to asrc_process_table */
  90994. +static int supported_input_rate[] = {
  90995. + 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200,
  90996. + 96000, 176400, 192000,
  90997. +};
  90998. +
  90999. +static int supported_output_rate[] = {
  91000. + 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000,
  91001. +};
  91002. +
  91003. +static int asrc_set_process_configuration(enum asrc_pair_index index,
  91004. + int inrate, int outrate)
  91005. +{
  91006. + int in, out;
  91007. +
  91008. + for (in = 0; in < ARRAY_SIZE(supported_input_rate); in++) {
  91009. + if (inrate == supported_input_rate[in])
  91010. + break;
  91011. + }
  91012. +
  91013. + if (in == ARRAY_SIZE(supported_input_rate)) {
  91014. + dev_err(asrc->dev, "unsupported input sample rate: %d\n", in);
  91015. + return -EINVAL;
  91016. + }
  91017. +
  91018. + for (out = 0; out < ARRAY_SIZE(supported_output_rate); out++) {
  91019. + if (outrate == supported_output_rate[out])
  91020. + break;
  91021. + }
  91022. +
  91023. + if (out == ARRAY_SIZE(supported_output_rate)) {
  91024. + dev_err(asrc->dev, "unsupported output sample rate: %d\n", out);
  91025. + return -EINVAL;
  91026. + }
  91027. +
  91028. + regmap_update_bits(asrc->regmap, REG_ASRCFG,
  91029. + ASRCFG_PREMODx_MASK(index) | ASRCFG_POSTMODx_MASK(index),
  91030. + ASRCFG_PREMOD(index, asrc_process_table[in][out][0]) |
  91031. + ASRCFG_POSTMOD(index, asrc_process_table[in][out][1]));
  91032. +
  91033. + return 0;
  91034. +}
  91035. +
  91036. +static int asrc_get_asrck_clock_divider(int samplerate)
  91037. +{
  91038. + unsigned int prescaler, divider, ratio, ra, i;
  91039. + unsigned long bitclk;
  91040. +
  91041. + if (samplerate == 0) {
  91042. + dev_err(asrc->dev, "invalid sample rate: %d\n", samplerate);
  91043. + return -EINVAL;
  91044. + }
  91045. +
  91046. + bitclk = clk_get_rate(asrc->asrc_clk);
  91047. +
  91048. + ra = bitclk / samplerate;
  91049. + ratio = ra;
  91050. +
  91051. + /* Calculate the prescaler */
  91052. + for (i = 0; ratio > 8; i++)
  91053. + ratio >>= 1;
  91054. +
  91055. + prescaler = i;
  91056. +
  91057. + /* Calculate the divider */
  91058. + divider = i ? (((ra + (1 << (i - 1)) - 1) >> i) - 1) : (ra - 1);
  91059. +
  91060. + /* The totally divider is (2 ^ prescaler) * divider */
  91061. + return (divider << ASRCDRx_AxCPx_WIDTH) + prescaler;
  91062. +}
  91063. +
  91064. +int asrc_req_pair(int chn_num, enum asrc_pair_index *index)
  91065. +{
  91066. + int imax = 0, busy = 0, i, ret = 0;
  91067. + unsigned long lock_flags;
  91068. + struct asrc_pair *pair;
  91069. +
  91070. + spin_lock_irqsave(&data_lock, lock_flags);
  91071. +
  91072. + for (i = ASRC_PAIR_A; i < ASRC_PAIR_MAX_NUM; i++) {
  91073. + pair = &asrc->asrc_pair[i];
  91074. + if (chn_num > pair->chn_max) {
  91075. + imax++;
  91076. + continue;
  91077. + } else if (pair->active) {
  91078. + busy++;
  91079. + continue;
  91080. + }
  91081. + /* Save the current qualified pair */
  91082. + *index = i;
  91083. +
  91084. + /* Check if this pair is a perfect one */
  91085. + if (chn_num == pair->chn_max)
  91086. + break;
  91087. + }
  91088. +
  91089. + if (imax == ASRC_PAIR_MAX_NUM) {
  91090. + dev_err(asrc->dev, "no pair could afford required channel number\n");
  91091. + ret = -EINVAL;
  91092. + } else if (busy == ASRC_PAIR_MAX_NUM) {
  91093. + dev_err(asrc->dev, "all pairs are busy now\n");
  91094. + ret = -EBUSY;
  91095. + } else if (busy + imax >= ASRC_PAIR_MAX_NUM) {
  91096. + dev_err(asrc->dev, "all affordable pairs are busy now\n");
  91097. + ret = -EBUSY;
  91098. + } else {
  91099. + pair = &asrc->asrc_pair[*index];
  91100. + pair->chn_num = chn_num;
  91101. + pair->active = 1;
  91102. + }
  91103. +
  91104. + spin_unlock_irqrestore(&data_lock, lock_flags);
  91105. +
  91106. + if (!ret) {
  91107. + clk_enable(asrc->asrc_clk);
  91108. + clk_prepare_enable(asrc->dma_clk);
  91109. + }
  91110. +
  91111. + return ret;
  91112. +}
  91113. +EXPORT_SYMBOL(asrc_req_pair);
  91114. +
  91115. +void asrc_release_pair(enum asrc_pair_index index)
  91116. +{
  91117. + struct asrc_pair *pair = &asrc->asrc_pair[index];
  91118. + unsigned long lock_flags;
  91119. +
  91120. + spin_lock_irqsave(&data_lock, lock_flags);
  91121. +
  91122. + pair->active = 0;
  91123. + pair->overload_error = 0;
  91124. +
  91125. + spin_unlock_irqrestore(&data_lock, lock_flags);
  91126. +
  91127. + /* Disable PAIR */
  91128. + regmap_update_bits(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEx_MASK(index), 0);
  91129. +}
  91130. +EXPORT_SYMBOL(asrc_release_pair);
  91131. +
  91132. +int asrc_config_pair(struct asrc_config *config)
  91133. +{
  91134. + u32 inrate = config->input_sample_rate, indiv;
  91135. + u32 outrate = config->output_sample_rate, outdiv;
  91136. + int ret, channels, index = config->pair;
  91137. + unsigned long lock_flags;
  91138. +
  91139. + /* Set the channel number */
  91140. + spin_lock_irqsave(&data_lock, lock_flags);
  91141. + asrc->asrc_pair[index].chn_num = config->channel_num;
  91142. + spin_unlock_irqrestore(&data_lock, lock_flags);
  91143. +
  91144. + if (asrc->channel_bits > 3)
  91145. + channels = config->channel_num;
  91146. + else
  91147. + channels = (config->channel_num + 1) / 2;
  91148. +
  91149. + /* Update channel number of current pair */
  91150. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  91151. + ASRCNCR_ANCx_MASK(index, asrc->channel_bits),
  91152. + ASRCNCR_ANCx_set(index, channels, asrc->channel_bits));
  91153. +
  91154. + /* Set the clock source */
  91155. + regmap_update_bits(asrc->regmap, REG_ASRCSR,
  91156. + ASRCSR_AICSx_MASK(index) | ASRCSR_AOCSx_MASK(index),
  91157. + ASRCSR_AICS(index, input_clk_map[config->inclk]) |
  91158. + ASRCSR_AOCS(index, output_clk_map[config->outclk]));
  91159. +
  91160. + /* Default setting: Automatic selection for processing mode */
  91161. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  91162. + ASRCTR_ATSx_MASK(index), ASRCTR_ATS(index));
  91163. + regmap_update_bits(asrc->regmap, REG_ASRCTR, ASRCTR_USRx_MASK(index), 0);
  91164. +
  91165. + /* Default Input Clock Divider Setting */
  91166. + switch (config->inclk & ASRCSR_AxCSx_MASK) {
  91167. + case INCLK_SPDIF_RX:
  91168. + indiv = ASRC_PRESCALER_SPDIF_RX;
  91169. + break;
  91170. + case INCLK_SPDIF_TX:
  91171. + indiv = ASRC_PRESCALER_SPDIF_TX;
  91172. + break;
  91173. + case INCLK_ASRCK1_CLK:
  91174. + indiv = asrc_get_asrck_clock_divider(inrate);
  91175. + break;
  91176. + default:
  91177. + switch (config->input_word_width) {
  91178. + case ASRC_WIDTH_16_BIT:
  91179. + indiv = ASRC_PRESCALER_I2S_16BIT;
  91180. + break;
  91181. + case ASRC_WIDTH_24_BIT:
  91182. + indiv = ASRC_PRESCALER_I2S_24BIT;
  91183. + break;
  91184. + default:
  91185. + pair_err("unsupported input word width %d\n",
  91186. + config->input_word_width);
  91187. + return -EINVAL;
  91188. + }
  91189. + break;
  91190. + }
  91191. +
  91192. + /* Default Output Clock Divider Setting */
  91193. + switch (config->outclk & ASRCSR_AxCSx_MASK) {
  91194. + case OUTCLK_SPDIF_RX:
  91195. + outdiv = ASRC_PRESCALER_SPDIF_RX;
  91196. + break;
  91197. + case OUTCLK_SPDIF_TX:
  91198. + outdiv = ASRC_PRESCALER_SPDIF_TX;
  91199. + break;
  91200. + case OUTCLK_ASRCK1_CLK:
  91201. + if ((config->inclk & ASRCSR_AxCSx_MASK) == INCLK_NONE)
  91202. + outdiv = ASRC_PRESCALER_IDEAL_RATIO;
  91203. + else
  91204. + outdiv = asrc_get_asrck_clock_divider(outrate);
  91205. + break;
  91206. + default:
  91207. + switch (config->output_word_width) {
  91208. + case ASRC_WIDTH_16_BIT:
  91209. + outdiv = ASRC_PRESCALER_I2S_16BIT;
  91210. + break;
  91211. + case ASRC_WIDTH_24_BIT:
  91212. + outdiv = ASRC_PRESCALER_I2S_24BIT;
  91213. + break;
  91214. + default:
  91215. + pair_err("unsupported output word width %d\n",
  91216. + config->input_word_width);
  91217. + return -EINVAL;
  91218. + }
  91219. + break;
  91220. + }
  91221. +
  91222. + /* indiv and outdiv'd include prescaler's value, so add its MASK too */
  91223. + regmap_update_bits(asrc->regmap, REG_ASRCDR(index),
  91224. + ASRCDRx_AOCPx_MASK(index) | ASRCDRx_AICPx_MASK(index) |
  91225. + ASRCDRx_AOCDx_MASK(index) | ASRCDRx_AICDx_MASK(index),
  91226. + ASRCDRx_AOCP(index, outdiv) | ASRCDRx_AICP(index, indiv));
  91227. +
  91228. + /* Check whether ideal ratio is a must */
  91229. + switch (config->inclk & ASRCSR_AxCSx_MASK) {
  91230. + case INCLK_NONE:
  91231. + /* Clear ASTSx bit to use ideal ratio */
  91232. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  91233. + ASRCTR_ATSx_MASK(index), 0);
  91234. +
  91235. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  91236. + ASRCTR_IDRx_MASK(index) | ASRCTR_USRx_MASK(index),
  91237. + ASRCTR_IDR(index) | ASRCTR_USR(index));
  91238. +
  91239. + ret = asrc_set_clock_ratio(index, inrate, outrate);
  91240. + if (ret)
  91241. + return ret;
  91242. +
  91243. + ret = asrc_set_process_configuration(index, inrate, outrate);
  91244. + if (ret)
  91245. + return ret;
  91246. +
  91247. + break;
  91248. + case INCLK_ASRCK1_CLK:
  91249. + /* This case and default are both remained for v1 */
  91250. + if (inrate == 44100 || inrate == 88200) {
  91251. + pair_err("unsupported sample rate %d by selected clock\n",
  91252. + inrate);
  91253. + return -EINVAL;
  91254. + }
  91255. + break;
  91256. + default:
  91257. + if ((config->outclk & ASRCSR_AxCSx_MASK) != OUTCLK_ASRCK1_CLK)
  91258. + break;
  91259. +
  91260. + if (outrate == 44100 || outrate == 88200) {
  91261. + pair_err("unsupported sample rate %d by selected clock\n",
  91262. + outrate);
  91263. + return -EINVAL;
  91264. + }
  91265. + break;
  91266. + }
  91267. +
  91268. + /* Config input and output wordwidth */
  91269. + if (config->output_word_width == ASRC_WIDTH_8_BIT) {
  91270. + pair_err("unsupported wordwidth for output: 8bit\n");
  91271. + pair_err("output only support: 16bit or 24bit\n");
  91272. + return -EINVAL;
  91273. + }
  91274. +
  91275. + regmap_update_bits(asrc->regmap, REG_ASRMCR1(index),
  91276. + ASRMCR1x_OW16_MASK | ASRMCR1x_IWD_MASK,
  91277. + ASRMCR1x_OW16(config->output_word_width) |
  91278. + ASRMCR1x_IWD(config->input_word_width));
  91279. +
  91280. + /* Enable BUFFER STALL */
  91281. + regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
  91282. + ASRMCRx_BUFSTALLx_MASK, ASRMCRx_BUFSTALLx);
  91283. +
  91284. + /* Set Threshold for input and output FIFO */
  91285. + return asrc_set_watermark(index, ASRC_INPUTFIFO_THRESHOLD,
  91286. + ASRC_INPUTFIFO_THRESHOLD);
  91287. +}
  91288. +EXPORT_SYMBOL(asrc_config_pair);
  91289. +
  91290. +int asrc_set_watermark(enum asrc_pair_index index, u32 in_wm, u32 out_wm)
  91291. +{
  91292. + if (in_wm > ASRC_FIFO_THRESHOLD_MAX || out_wm > ASRC_FIFO_THRESHOLD_MAX) {
  91293. + pair_err("invalid watermark!\n");
  91294. + return -EINVAL;
  91295. + }
  91296. +
  91297. + return regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
  91298. + ASRMCRx_EXTTHRSHx_MASK | ASRMCRx_INFIFO_THRESHOLD_MASK |
  91299. + ASRMCRx_OUTFIFO_THRESHOLD_MASK,
  91300. + ASRMCRx_EXTTHRSHx | ASRMCRx_INFIFO_THRESHOLD(in_wm) |
  91301. + ASRMCRx_OUTFIFO_THRESHOLD(out_wm));
  91302. +}
  91303. +EXPORT_SYMBOL(asrc_set_watermark);
  91304. +
  91305. +void asrc_start_conv(enum asrc_pair_index index)
  91306. +{
  91307. + int reg, retry, channels, i;
  91308. +
  91309. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  91310. + ASRCTR_ASRCEx_MASK(index), ASRCTR_ASRCE(index));
  91311. +
  91312. + /* Wait for status of initialization */
  91313. + for (retry = 10, reg = 0; !reg && retry; --retry) {
  91314. + udelay(5);
  91315. + regmap_read(asrc->regmap, REG_ASRCFG, &reg);
  91316. + reg &= ASRCFG_INIRQx_MASK(index);
  91317. + }
  91318. +
  91319. + /* Set the input fifo to ASRC STALL level */
  91320. + regmap_read(asrc->regmap, REG_ASRCNCR, &reg);
  91321. + channels = ASRCNCR_ANCx_get(index, reg, asrc->channel_bits);
  91322. + for (i = 0; i < channels * 4; i++)
  91323. + regmap_write(asrc->regmap, REG_ASRDI(index), 0);
  91324. +
  91325. + /* Overload Interrupt Enable */
  91326. + regmap_write(asrc->regmap, REG_ASRIER, ASRIER_AOLIE);
  91327. +}
  91328. +EXPORT_SYMBOL(asrc_start_conv);
  91329. +
  91330. +void asrc_stop_conv(enum asrc_pair_index index)
  91331. +{
  91332. + regmap_update_bits(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEx_MASK(index), 0);
  91333. +}
  91334. +EXPORT_SYMBOL(asrc_stop_conv);
  91335. +
  91336. +void asrc_finish_conv(enum asrc_pair_index index)
  91337. +{
  91338. + clk_disable_unprepare(asrc->dma_clk);
  91339. + clk_disable(asrc->asrc_clk);
  91340. +}
  91341. +EXPORT_SYMBOL(asrc_finish_conv);
  91342. +
  91343. +#define SET_OVERLOAD_ERR(index, err, msg) \
  91344. + do { \
  91345. + asrc->asrc_pair[index].overload_error |= err; \
  91346. + pair_dbg(msg); \
  91347. + } while (0)
  91348. +
  91349. +static irqreturn_t asrc_isr(int irq, void *dev_id)
  91350. +{
  91351. + enum asrc_pair_index index;
  91352. + u32 status;
  91353. +
  91354. + regmap_read(asrc->regmap, REG_ASRSTR, &status);
  91355. +
  91356. + for (index = ASRC_PAIR_A; index < ASRC_PAIR_MAX_NUM; index++) {
  91357. + if (asrc->asrc_pair[index].active == 0)
  91358. + continue;
  91359. + if (status & ASRSTR_ATQOL)
  91360. + SET_OVERLOAD_ERR(index, ASRC_TASK_Q_OVERLOAD,
  91361. + "Task Queue FIFO overload");
  91362. + if (status & ASRSTR_AOOL(index))
  91363. + SET_OVERLOAD_ERR(index, ASRC_OUTPUT_TASK_OVERLOAD,
  91364. + "Output Task Overload");
  91365. + if (status & ASRSTR_AIOL(index))
  91366. + SET_OVERLOAD_ERR(index, ASRC_INPUT_TASK_OVERLOAD,
  91367. + "Input Task Overload");
  91368. + if (status & ASRSTR_AODO(index))
  91369. + SET_OVERLOAD_ERR(index, ASRC_OUTPUT_BUFFER_OVERFLOW,
  91370. + "Output Data Buffer has overflowed");
  91371. + if (status & ASRSTR_AIDU(index))
  91372. + SET_OVERLOAD_ERR(index, ASRC_INPUT_BUFFER_UNDERRUN,
  91373. + "Input Data Buffer has underflowed");
  91374. + }
  91375. +
  91376. + /* Clean overload error */
  91377. + regmap_write(asrc->regmap, REG_ASRSTR, ASRSTR_AOLE);
  91378. +
  91379. + return IRQ_HANDLED;
  91380. +}
  91381. +
  91382. +void asrc_get_status(struct asrc_status_flags *flags)
  91383. +{
  91384. + enum asrc_pair_index index = flags->index;
  91385. + unsigned long lock_flags;
  91386. +
  91387. + spin_lock_irqsave(&data_lock, lock_flags);
  91388. +
  91389. + flags->overload_error = asrc->asrc_pair[index].overload_error;
  91390. +
  91391. + spin_unlock_irqrestore(&data_lock, lock_flags);
  91392. +}
  91393. +EXPORT_SYMBOL(asrc_get_status);
  91394. +
  91395. +u32 asrc_get_per_addr(enum asrc_pair_index index, bool in)
  91396. +{
  91397. + return asrc->paddr + (in ? REG_ASRDI(index) : REG_ASRDO(index));
  91398. +}
  91399. +EXPORT_SYMBOL(asrc_get_per_addr);
  91400. +
  91401. +static int mxc_init_asrc(void)
  91402. +{
  91403. + /* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
  91404. + regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
  91405. +
  91406. + /* Disable interrupt by default */
  91407. + regmap_write(asrc->regmap, REG_ASRIER, 0x0);
  91408. +
  91409. + /* Default 2: 6: 2 channel assignment */
  91410. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  91411. + ASRCNCR_ANCx_MASK(ASRC_PAIR_A, asrc->channel_bits),
  91412. + ASRCNCR_ANCx_set(ASRC_PAIR_A, 2, asrc->channel_bits));
  91413. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  91414. + ASRCNCR_ANCx_MASK(ASRC_PAIR_B, asrc->channel_bits),
  91415. + ASRCNCR_ANCx_set(ASRC_PAIR_B, 6, asrc->channel_bits));
  91416. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  91417. + ASRCNCR_ANCx_MASK(ASRC_PAIR_C, asrc->channel_bits),
  91418. + ASRCNCR_ANCx_set(ASRC_PAIR_C, 2, asrc->channel_bits));
  91419. +
  91420. + /* Parameter Registers recommended settings */
  91421. + regmap_write(asrc->regmap, REG_ASRPM1, 0x7fffff);
  91422. + regmap_write(asrc->regmap, REG_ASRPM2, 0x255555);
  91423. + regmap_write(asrc->regmap, REG_ASRPM3, 0xff7280);
  91424. + regmap_write(asrc->regmap, REG_ASRPM4, 0xff7280);
  91425. + regmap_write(asrc->regmap, REG_ASRPM5, 0xff7280);
  91426. +
  91427. + /* Base address for task queue FIFO. Set to 0x7C */
  91428. + regmap_update_bits(asrc->regmap, REG_ASRTFR1,
  91429. + ASRTFR1_TF_BASE_MASK, ASRTFR1_TF_BASE(0xfc));
  91430. +
  91431. + /* Set the processing clock for 76KHz, 133M */
  91432. + regmap_write(asrc->regmap, REG_ASR76K, 0x06D6);
  91433. +
  91434. + /* Set the processing clock for 56KHz, 133M */
  91435. + return regmap_write(asrc->regmap, REG_ASR56K, 0x0947);
  91436. +}
  91437. +
  91438. +#define ASRC_xPUT_DMA_CALLBACK(in) \
  91439. + ((in) ? asrc_input_dma_callback : asrc_output_dma_callback)
  91440. +
  91441. +static void asrc_input_dma_callback(void *data)
  91442. +{
  91443. + struct asrc_pair_params *params = (struct asrc_pair_params *)data;
  91444. +
  91445. + dma_unmap_sg(NULL, params->input_sg, params->input_sg_nodes,
  91446. + DMA_MEM_TO_DEV);
  91447. +
  91448. + complete(&params->input_complete);
  91449. +
  91450. + schedule_work(&params->task_output_work);
  91451. +}
  91452. +
  91453. +static void asrc_output_dma_callback(void *data)
  91454. +{
  91455. + struct asrc_pair_params *params = (struct asrc_pair_params *)data;
  91456. +
  91457. + dma_unmap_sg(NULL, params->output_sg, params->output_sg_nodes,
  91458. + DMA_DEV_TO_MEM);
  91459. +
  91460. + complete(&params->output_complete);
  91461. +}
  91462. +
  91463. +static unsigned int asrc_get_output_FIFO_size(enum asrc_pair_index index)
  91464. +{
  91465. + u32 val;
  91466. +
  91467. + regmap_read(asrc->regmap, REG_ASRFST(index), &val);
  91468. +
  91469. + val &= ASRFSTx_OUTPUT_FIFO_MASK;
  91470. +
  91471. + return val >> ASRFSTx_OUTPUT_FIFO_SHIFT;
  91472. +}
  91473. +
  91474. +static u32 asrc_read_one_from_output_FIFO(enum asrc_pair_index index)
  91475. +{
  91476. + u32 val;
  91477. +
  91478. + regmap_read(asrc->regmap, REG_ASRDO(index), &val);
  91479. +
  91480. + return val;
  91481. +}
  91482. +
  91483. +static void asrc_read_output_FIFO(struct asrc_pair_params *params)
  91484. +{
  91485. + u32 *reg24 = params->output_last_period.dma_vaddr;
  91486. + u16 *reg16 = params->output_last_period.dma_vaddr;
  91487. + enum asrc_pair_index index = params->index;
  91488. + u32 i, j, reg, size, t_size;
  91489. + bool bit24 = false;
  91490. +
  91491. + if (params->output_word_width == ASRC_WIDTH_24_BIT)
  91492. + bit24 = true;
  91493. +
  91494. + t_size = 0;
  91495. + do {
  91496. + size = asrc_get_output_FIFO_size(index);
  91497. + for (i = 0; i < size; i++) {
  91498. + for (j = 0; j < params->channel_nums; j++) {
  91499. + reg = asrc_read_one_from_output_FIFO(index);
  91500. + if (bit24) {
  91501. + *(reg24) = reg;
  91502. + reg24++;
  91503. + } else {
  91504. + *(reg16) = (u16)reg;
  91505. + reg16++;
  91506. + }
  91507. + }
  91508. + }
  91509. + t_size += size;
  91510. + } while (size);
  91511. +
  91512. + if (t_size > params->last_period_sample)
  91513. + t_size = params->last_period_sample;
  91514. +
  91515. + params->output_last_period.length = t_size * params->channel_nums * 2;
  91516. + if (bit24)
  91517. + params->output_last_period.length *= 2;
  91518. +}
  91519. +
  91520. +static void asrc_output_task_worker(struct work_struct *w)
  91521. +{
  91522. + struct asrc_pair_params *params =
  91523. + container_of(w, struct asrc_pair_params, task_output_work);
  91524. + enum asrc_pair_index index = params->index;
  91525. + unsigned long lock_flags;
  91526. +
  91527. + if (!wait_for_completion_interruptible_timeout(&params->output_complete, HZ / 10)) {
  91528. + pair_err("output dma task timeout\n");
  91529. + return;
  91530. + }
  91531. +
  91532. + init_completion(&params->output_complete);
  91533. +
  91534. + spin_lock_irqsave(&pair_lock, lock_flags);
  91535. + if (!params->pair_hold) {
  91536. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  91537. + return;
  91538. + }
  91539. + asrc_read_output_FIFO(params);
  91540. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  91541. +
  91542. + complete(&params->lastperiod_complete);
  91543. +}
  91544. +
  91545. +static void mxc_free_dma_buf(struct asrc_pair_params *params)
  91546. +{
  91547. + if (params->input_dma_total.dma_vaddr != NULL) {
  91548. + kfree(params->input_dma_total.dma_vaddr);
  91549. + params->input_dma_total.dma_vaddr = NULL;
  91550. + }
  91551. +
  91552. + if (params->output_dma_total.dma_vaddr != NULL) {
  91553. + kfree(params->output_dma_total.dma_vaddr);
  91554. + params->output_dma_total.dma_vaddr = NULL;
  91555. + }
  91556. +
  91557. + if (params->output_last_period.dma_vaddr) {
  91558. + dma_free_coherent(asrc->dev, 1024 * params->last_period_sample,
  91559. + params->output_last_period.dma_vaddr,
  91560. + params->output_last_period.dma_paddr);
  91561. + params->output_last_period.dma_vaddr = NULL;
  91562. + }
  91563. +}
  91564. +
  91565. +static int mxc_allocate_dma_buf(struct asrc_pair_params *params)
  91566. +{
  91567. + struct dma_block *input_a, *output_a, *last_period;
  91568. + enum asrc_pair_index index = params->index;
  91569. +
  91570. + input_a = &params->input_dma_total;
  91571. + output_a = &params->output_dma_total;
  91572. + last_period = &params->output_last_period;
  91573. +
  91574. + input_a->dma_vaddr = kzalloc(input_a->length, GFP_KERNEL);
  91575. + if (!input_a->dma_vaddr) {
  91576. + pair_err("failed to allocate input dma buffer\n");
  91577. + goto exit;
  91578. + }
  91579. + input_a->dma_paddr = virt_to_dma(NULL, input_a->dma_vaddr);
  91580. +
  91581. + output_a->dma_vaddr = kzalloc(output_a->length, GFP_KERNEL);
  91582. + if (!output_a->dma_vaddr) {
  91583. + pair_err("failed to allocate output dma buffer\n");
  91584. + goto exit;
  91585. + }
  91586. + output_a->dma_paddr = virt_to_dma(NULL, output_a->dma_vaddr);
  91587. +
  91588. + last_period->dma_vaddr = dma_alloc_coherent(asrc->dev,
  91589. + 1024 * params->last_period_sample,
  91590. + &last_period->dma_paddr, GFP_KERNEL);
  91591. + if (!last_period->dma_vaddr) {
  91592. + pair_err("failed to allocate last period buffer\n");
  91593. + goto exit;
  91594. + }
  91595. +
  91596. + return 0;
  91597. +
  91598. +exit:
  91599. + mxc_free_dma_buf(params);
  91600. +
  91601. + return -ENOBUFS;
  91602. +}
  91603. +
  91604. +static struct dma_chan *imx_asrc_get_dma_channel(enum asrc_pair_index index, bool in)
  91605. +{
  91606. + char name[4];
  91607. +
  91608. + sprintf(name, "%cx%c", in ? 'r' : 't', index + 'a');
  91609. +
  91610. + return dma_request_slave_channel(asrc->dev, name);
  91611. +}
  91612. +
  91613. +static int imx_asrc_dma_config(struct asrc_pair_params *params,
  91614. + struct dma_chan *chan, u32 dma_addr,
  91615. + void *buf_addr, u32 buf_len, bool in,
  91616. + enum asrc_word_width word_width)
  91617. +{
  91618. + enum asrc_pair_index index = params->index;
  91619. + struct dma_async_tx_descriptor *desc;
  91620. + struct dma_slave_config slave_config;
  91621. + enum dma_slave_buswidth buswidth;
  91622. + struct scatterlist *sg;
  91623. + unsigned int sg_nent, i;
  91624. + int ret;
  91625. +
  91626. + if (in) {
  91627. + sg = params->input_sg;
  91628. + sg_nent = params->input_sg_nodes;
  91629. + desc = params->desc_in;
  91630. + } else {
  91631. + sg = params->output_sg;
  91632. + sg_nent = params->output_sg_nodes;
  91633. + desc = params->desc_out;
  91634. + }
  91635. +
  91636. + switch (word_width) {
  91637. + case ASRC_WIDTH_16_BIT:
  91638. + buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
  91639. + break;
  91640. + case ASRC_WIDTH_24_BIT:
  91641. + buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
  91642. + break;
  91643. + default:
  91644. + pair_err("invalid word width\n");
  91645. + return -EINVAL;
  91646. + }
  91647. +
  91648. + slave_config.dma_request0 = 0;
  91649. + slave_config.dma_request1 = 0;
  91650. +
  91651. + if (in) {
  91652. + slave_config.direction = DMA_MEM_TO_DEV;
  91653. + slave_config.dst_addr = dma_addr;
  91654. + slave_config.dst_addr_width = buswidth;
  91655. + slave_config.dst_maxburst =
  91656. + params->input_wm * params->channel_nums / buswidth;
  91657. + } else {
  91658. + slave_config.direction = DMA_DEV_TO_MEM;
  91659. + slave_config.src_addr = dma_addr;
  91660. + slave_config.src_addr_width = buswidth;
  91661. + slave_config.src_maxburst =
  91662. + params->output_wm * params->channel_nums / buswidth;
  91663. + }
  91664. + ret = dmaengine_slave_config(chan, &slave_config);
  91665. + if (ret) {
  91666. + pair_err("failed to config dmaengine for %sput task: %d\n",
  91667. + in ? "in" : "out", ret);
  91668. + return -EINVAL;
  91669. + }
  91670. +
  91671. + sg_init_table(sg, sg_nent);
  91672. + switch (sg_nent) {
  91673. + case 1:
  91674. + sg_init_one(sg, buf_addr, buf_len);
  91675. + break;
  91676. + case 2:
  91677. + case 3:
  91678. + case 4:
  91679. + for (i = 0; i < (sg_nent - 1); i++)
  91680. + sg_set_buf(&sg[i], buf_addr + i * ASRC_MAX_BUFFER_SIZE,
  91681. + ASRC_MAX_BUFFER_SIZE);
  91682. +
  91683. + sg_set_buf(&sg[i], buf_addr + i * ASRC_MAX_BUFFER_SIZE,
  91684. + buf_len - ASRC_MAX_BUFFER_SIZE * i);
  91685. + break;
  91686. + default:
  91687. + pair_err("invalid input DMA nodes number: %d\n", sg_nent);
  91688. + return -EINVAL;
  91689. + }
  91690. +
  91691. + ret = dma_map_sg(NULL, sg, sg_nent, slave_config.direction);
  91692. + if (ret != sg_nent) {
  91693. + pair_err("failed to map dma sg for %sput task\n",
  91694. + in ? "in" : "out");
  91695. + return -EINVAL;
  91696. + }
  91697. +
  91698. + desc = dmaengine_prep_slave_sg(chan, sg, sg_nent,
  91699. + slave_config.direction, DMA_PREP_INTERRUPT);
  91700. + if (!desc) {
  91701. + pair_err("failed to prepare slave sg for %sput task\n",
  91702. + in ? "in" : "out");
  91703. + return -EINVAL;
  91704. + }
  91705. +
  91706. + if (in) {
  91707. + params->desc_in = desc;
  91708. + params->desc_in->callback = asrc_input_dma_callback;
  91709. + } else {
  91710. + params->desc_out = desc;
  91711. + params->desc_out->callback = asrc_output_dma_callback;
  91712. + }
  91713. +
  91714. + desc->callback = ASRC_xPUT_DMA_CALLBACK(in);
  91715. + desc->callback_param = params;
  91716. +
  91717. + return 0;
  91718. +}
  91719. +
  91720. +static int mxc_asrc_prepare_io_buffer(struct asrc_pair_params *params,
  91721. + struct asrc_convert_buffer *pbuf, bool in)
  91722. +{
  91723. + enum asrc_pair_index index = params->index;
  91724. + struct dma_chan *dma_channel;
  91725. + enum asrc_word_width width;
  91726. + unsigned int *dma_len, *sg_nodes, buf_len, wm;
  91727. + void __user *buf_vaddr;
  91728. + void *dma_vaddr;
  91729. + u32 word_size, fifo_addr;
  91730. +
  91731. + if (in) {
  91732. + dma_channel = params->input_dma_channel;
  91733. + dma_vaddr = params->input_dma_total.dma_vaddr;
  91734. + dma_len = &params->input_dma_total.length;
  91735. + width = params->input_word_width;
  91736. + sg_nodes = &params->input_sg_nodes;
  91737. + wm = params->input_wm;
  91738. + buf_vaddr = (void __user *)pbuf->input_buffer_vaddr;
  91739. + buf_len = pbuf->input_buffer_length;
  91740. + } else {
  91741. + dma_channel = params->output_dma_channel;
  91742. + dma_vaddr = params->output_dma_total.dma_vaddr;
  91743. + dma_len = &params->output_dma_total.length;
  91744. + width = params->output_word_width;
  91745. + sg_nodes = &params->output_sg_nodes;
  91746. + wm = params->last_period_sample;
  91747. + buf_vaddr = (void __user *)pbuf->output_buffer_vaddr;
  91748. + buf_len = pbuf->output_buffer_length;
  91749. + }
  91750. +
  91751. + switch (width) {
  91752. + case ASRC_WIDTH_24_BIT:
  91753. + word_size = 4;
  91754. + break;
  91755. + case ASRC_WIDTH_16_BIT:
  91756. + case ASRC_WIDTH_8_BIT:
  91757. + word_size = 2;
  91758. + break;
  91759. + default:
  91760. + pair_err("invalid %sput word size!\n", in ? "in" : "out");
  91761. + return -EINVAL;
  91762. + }
  91763. +
  91764. + if (buf_len < word_size * params->channel_nums * wm) {
  91765. + pair_err("%sput buffer size[%d] is too small!\n",
  91766. + in ? "in" : "out", buf_len);
  91767. + return -EINVAL;
  91768. + }
  91769. +
  91770. + /* Copy origin data into input buffer */
  91771. + if (in && copy_from_user(dma_vaddr, buf_vaddr, buf_len))
  91772. + return -EFAULT;
  91773. +
  91774. + *dma_len = buf_len;
  91775. + if (!in)
  91776. + *dma_len -= wm * word_size * params->channel_nums;
  91777. +
  91778. + *sg_nodes = *dma_len / ASRC_MAX_BUFFER_SIZE + 1;
  91779. +
  91780. + fifo_addr = asrc_get_per_addr(params->index, in);
  91781. +
  91782. + return imx_asrc_dma_config(params, dma_channel, fifo_addr, dma_vaddr,
  91783. + *dma_len, in, width);
  91784. +}
  91785. +
  91786. +static int mxc_asrc_prepare_buffer(struct asrc_pair_params *params,
  91787. + struct asrc_convert_buffer *pbuf)
  91788. +{
  91789. + enum asrc_pair_index index = params->index;
  91790. + int ret;
  91791. +
  91792. + ret = mxc_asrc_prepare_io_buffer(params, pbuf, true);
  91793. + if (ret) {
  91794. + pair_err("failed to prepare input buffer: %d\n", ret);
  91795. + return ret;
  91796. + }
  91797. +
  91798. + ret = mxc_asrc_prepare_io_buffer(params, pbuf, false);
  91799. + if (ret) {
  91800. + pair_err("failed to prepare output buffer: %d\n", ret);
  91801. + return ret;
  91802. + }
  91803. +
  91804. + return 0;
  91805. +}
  91806. +
  91807. +int mxc_asrc_process_io_buffer(struct asrc_pair_params *params,
  91808. + struct asrc_convert_buffer *pbuf, bool in)
  91809. +{
  91810. + void *last_vaddr = params->output_last_period.dma_vaddr;
  91811. + unsigned int *last_len = &params->output_last_period.length;
  91812. + enum asrc_pair_index index = params->index;
  91813. + unsigned int dma_len, *buf_len;
  91814. + struct completion *complete;
  91815. + void __user *buf_vaddr;
  91816. + void *dma_vaddr;
  91817. +
  91818. + if (in) {
  91819. + dma_vaddr = params->input_dma_total.dma_vaddr;
  91820. + dma_len = params->input_dma_total.length;
  91821. + buf_len = &pbuf->input_buffer_length;
  91822. + complete = &params->input_complete;
  91823. + buf_vaddr = (void __user *)pbuf->input_buffer_vaddr;
  91824. + } else {
  91825. + dma_vaddr = params->output_dma_total.dma_vaddr;
  91826. + dma_len = params->output_dma_total.length;
  91827. + buf_len = &pbuf->output_buffer_length;
  91828. + complete = &params->lastperiod_complete;
  91829. + buf_vaddr = (void __user *)pbuf->output_buffer_vaddr;
  91830. + }
  91831. +
  91832. + if (!wait_for_completion_interruptible_timeout(complete, 10 * HZ)) {
  91833. + pair_err("%s task timeout\n", in ? "input dma" : "last period");
  91834. + return -ETIME;
  91835. + } else if (signal_pending(current)) {
  91836. + pair_err("%sput task forcibly aborted\n", in ? "in" : "out");
  91837. + return -ERESTARTSYS;
  91838. + }
  91839. +
  91840. + init_completion(complete);
  91841. +
  91842. + *buf_len = dma_len;
  91843. +
  91844. + /* Only output need return data to user space */
  91845. + if (!in) {
  91846. + if (copy_to_user(buf_vaddr, dma_vaddr, dma_len))
  91847. + return -EFAULT;
  91848. +
  91849. + *buf_len += *last_len;
  91850. +
  91851. + if (copy_to_user(buf_vaddr + dma_len, last_vaddr, *last_len))
  91852. + return -EFAULT;
  91853. + }
  91854. +
  91855. + return 0;
  91856. +}
  91857. +
  91858. +int mxc_asrc_process_buffer(struct asrc_pair_params *params,
  91859. + struct asrc_convert_buffer *pbuf)
  91860. +{
  91861. + enum asrc_pair_index index = params->index;
  91862. + int ret;
  91863. +
  91864. + ret = mxc_asrc_process_io_buffer(params, pbuf, true);
  91865. + if (ret) {
  91866. + pair_err("failed to process input buffer: %d\n", ret);
  91867. + return ret;
  91868. + }
  91869. +
  91870. + ret = mxc_asrc_process_io_buffer(params, pbuf, false);
  91871. + if (ret) {
  91872. + pair_err("failed to process output buffer: %d\n", ret);
  91873. + return ret;
  91874. + }
  91875. +
  91876. + return 0;
  91877. +}
  91878. +
  91879. +#ifdef ASRC_POLLING_WITHOUT_DMA
  91880. +static void asrc_write_one_to_input_FIFO(enum asrc_pair_index index, u32 val)
  91881. +{
  91882. + regmap_write(asrc->regmap, REG_ASRDI(index), val);
  91883. +}
  91884. +
  91885. +/* THIS FUNCTION ONLY EXISTS FOR DEBUGGING AND ONLY SUPPORTS TWO CHANNELS */
  91886. +static void asrc_polling_debug(struct asrc_pair_params *params)
  91887. +{
  91888. + enum asrc_pair_index index = params->index;
  91889. + u32 *in24 = params->input_dma_total.dma_vaddr;
  91890. + u32 dma_len = params->input_dma_total.length / (params->channel_nums * 4);
  91891. + u32 size, i, j, t_size, reg;
  91892. + u32 *reg24 = params->output_dma_total.dma_vaddr;
  91893. +
  91894. + t_size = 0;
  91895. +
  91896. + for (i = 0; i < dma_len; ) {
  91897. + for (j = 0; j < 2; j++) {
  91898. + asrc_write_one_to_input_FIFO(index, *in24);
  91899. + in24++;
  91900. + asrc_write_one_to_input_FIFO(index, *in24);
  91901. + in24++;
  91902. + i++;
  91903. + }
  91904. + udelay(50);
  91905. + udelay(50 * params->output_sample_rate / params->input_sample_rate);
  91906. +
  91907. + size = asrc_get_output_FIFO_size(index);
  91908. + for (j = 0; j < size; j++) {
  91909. + reg = asrc_read_one_from_output_FIFO(index);
  91910. + *(reg24) = reg;
  91911. + reg24++;
  91912. + reg = asrc_read_one_from_output_FIFO(index);
  91913. + *(reg24) = reg;
  91914. + reg24++;
  91915. + }
  91916. + t_size += size;
  91917. + }
  91918. +
  91919. + mdelay(1);
  91920. + size = asrc_get_output_FIFO_size(index);
  91921. + for (j = 0; j < size; j++) {
  91922. + reg = asrc_read_one_from_output_FIFO(index);
  91923. + *(reg24) = reg;
  91924. + reg24++;
  91925. + reg = asrc_read_one_from_output_FIFO(index);
  91926. + *(reg24) = reg;
  91927. + reg24++;
  91928. + }
  91929. + t_size += size;
  91930. +
  91931. + params->output_dma_total.length = t_size * params->channel_nums * 4;
  91932. + params->output_last_period.length = 0;
  91933. +
  91934. + dma_unmap_sg(NULL, params->input_sg, params->input_sg_nodes,
  91935. + DMA_MEM_TO_DEV);
  91936. + dma_unmap_sg(NULL, params->output_sg, params->output_sg_nodes,
  91937. + DMA_DEV_TO_MEM);
  91938. +
  91939. + complete(&params->input_complete);
  91940. + complete(&params->lastperiod_complete);
  91941. +}
  91942. +#else
  91943. +static void mxc_asrc_submit_dma(struct asrc_pair_params *params)
  91944. +{
  91945. + enum asrc_pair_index index = params->index;
  91946. + u32 size = asrc_get_output_FIFO_size(params->index);
  91947. + int i, j;
  91948. +
  91949. + /* Read all data in OUTPUT FIFO */
  91950. + while (size) {
  91951. + for (j = 0; j < size; j++)
  91952. + for (i = 0; i < params->channel_nums; i++)
  91953. + asrc_read_one_from_output_FIFO(index);
  91954. + /* Fetch the data every 100us */
  91955. + udelay(100);
  91956. +
  91957. + size = asrc_get_output_FIFO_size(index);
  91958. + }
  91959. +
  91960. + /* Submit dma request */
  91961. + dmaengine_submit(params->desc_in);
  91962. + dma_async_issue_pending(params->desc_in->chan);
  91963. +
  91964. + dmaengine_submit(params->desc_out);
  91965. + dma_async_issue_pending(params->desc_out->chan);
  91966. +
  91967. + /*
  91968. + * Clear dma request during the stall state of ASRC:
  91969. + * During STALL state, the remaining in input fifo would never be
  91970. + * smaller than the input threshold while the output fifo would not
  91971. + * be bigger than output one. Thus the dma request would be cleared.
  91972. + */
  91973. + asrc_set_watermark(index, ASRC_FIFO_THRESHOLD_MIN, ASRC_FIFO_THRESHOLD_MAX);
  91974. +
  91975. + /* Update the real input threshold to raise dma request */
  91976. + asrc_set_watermark(index, params->input_wm, params->output_wm);
  91977. +}
  91978. +#endif
  91979. +
  91980. +static long asrc_ioctl_req_pair(struct asrc_pair_params *params,
  91981. + void __user *user)
  91982. +{
  91983. + struct asrc_req req;
  91984. + long ret;
  91985. +
  91986. + ret = copy_from_user(&req, user, sizeof(req));
  91987. + if (ret) {
  91988. + dev_err(asrc->dev, "failed to get req from user space: %ld\n", ret);
  91989. + return ret;
  91990. + }
  91991. +
  91992. + ret = asrc_req_pair(req.chn_num, &req.index);
  91993. + if (ret) {
  91994. + dev_err(asrc->dev, "failed to request pair: %ld\n", ret);
  91995. + return ret;
  91996. + }
  91997. +
  91998. + params->pair_hold = 1;
  91999. + params->index = req.index;
  92000. + params->channel_nums = req.chn_num;
  92001. +
  92002. + ret = copy_to_user(user, &req, sizeof(req));
  92003. + if (ret) {
  92004. + dev_err(asrc->dev, "failed to send req to user space: %ld\n", ret);
  92005. + return ret;
  92006. + }
  92007. +
  92008. + return 0;
  92009. +}
  92010. +
  92011. +static long asrc_ioctl_config_pair(struct asrc_pair_params *params,
  92012. + void __user *user)
  92013. +{
  92014. + struct asrc_config config;
  92015. + enum asrc_pair_index index;
  92016. + long ret;
  92017. +
  92018. + ret = copy_from_user(&config, user, sizeof(config));
  92019. + if (ret) {
  92020. + dev_err(asrc->dev, "failed to get config from user space: %ld\n", ret);
  92021. + return ret;
  92022. + }
  92023. +
  92024. + index = config.pair;
  92025. +
  92026. + ret = asrc_config_pair(&config);
  92027. + if (ret) {
  92028. + pair_err("failed to config pair: %ld\n", ret);
  92029. + return ret;
  92030. + }
  92031. +
  92032. + params->input_wm = 4;
  92033. + params->output_wm = 2;
  92034. +
  92035. + ret = asrc_set_watermark(index, params->input_wm, params->output_wm);
  92036. + if (ret)
  92037. + return ret;
  92038. +
  92039. + params->output_buffer_size = config.dma_buffer_size;
  92040. + params->input_buffer_size = config.dma_buffer_size;
  92041. + if (config.buffer_num > ASRC_DMA_BUFFER_NUM)
  92042. + params->buffer_num = ASRC_DMA_BUFFER_NUM;
  92043. + else
  92044. + params->buffer_num = config.buffer_num;
  92045. +
  92046. + params->input_dma_total.length = ASRC_DMA_BUFFER_SIZE;
  92047. + params->output_dma_total.length = ASRC_DMA_BUFFER_SIZE;
  92048. +
  92049. + params->input_word_width = config.input_word_width;
  92050. + params->output_word_width = config.output_word_width;
  92051. +
  92052. + params->input_sample_rate = config.input_sample_rate;
  92053. + params->output_sample_rate = config.output_sample_rate;
  92054. +
  92055. + params->last_period_sample = ASRC_OUTPUT_LAST_SAMPLE_DEFAULT;
  92056. +
  92057. + ret = mxc_allocate_dma_buf(params);
  92058. + if (ret) {
  92059. + pair_err("failed to allocate dma buffer: %ld\n", ret);
  92060. + return ret;
  92061. + }
  92062. +
  92063. + /* Request DMA channel for both input and output */
  92064. + params->input_dma_channel = imx_asrc_get_dma_channel(index, true);
  92065. + if (params->input_dma_channel == NULL) {
  92066. + pair_err("failed to request input task dma channel\n");
  92067. + return -EBUSY;
  92068. + }
  92069. +
  92070. + params->output_dma_channel = imx_asrc_get_dma_channel(index, false);
  92071. + if (params->output_dma_channel == NULL) {
  92072. + pair_err("failed to request output task dma channel\n");
  92073. + return -EBUSY;
  92074. + }
  92075. +
  92076. + init_completion(&params->input_complete);
  92077. + init_completion(&params->output_complete);
  92078. + init_completion(&params->lastperiod_complete);
  92079. +
  92080. + /* Add work struct to receive last period of output data */
  92081. + INIT_WORK(&params->task_output_work, asrc_output_task_worker);
  92082. +
  92083. + ret = copy_to_user(user, &config, sizeof(config));
  92084. + if (ret) {
  92085. + pair_err("failed to send config to user space: %ld\n", ret);
  92086. + return ret;
  92087. + }
  92088. +
  92089. + return 0;
  92090. +}
  92091. +
  92092. +static long asrc_ioctl_release_pair(struct asrc_pair_params *params,
  92093. + void __user *user)
  92094. +{
  92095. + enum asrc_pair_index index;
  92096. + unsigned long lock_flags;
  92097. + long ret;
  92098. +
  92099. + ret = copy_from_user(&index, user, sizeof(index));
  92100. + if (ret) {
  92101. + dev_err(asrc->dev, "failed to get index from user space: %ld\n", ret);
  92102. + return ret;
  92103. + }
  92104. +
  92105. + /* index might be not valid due to some application failure. */
  92106. + if (index < 0)
  92107. + return -EINVAL;
  92108. +
  92109. + params->asrc_active = 0;
  92110. +
  92111. + spin_lock_irqsave(&pair_lock, lock_flags);
  92112. + params->pair_hold = 0;
  92113. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  92114. +
  92115. + if (params->input_dma_channel)
  92116. + dma_release_channel(params->input_dma_channel);
  92117. + if (params->output_dma_channel)
  92118. + dma_release_channel(params->output_dma_channel);
  92119. + mxc_free_dma_buf(params);
  92120. + asrc_release_pair(index);
  92121. + asrc_finish_conv(index);
  92122. +
  92123. + return 0;
  92124. +}
  92125. +
  92126. +static long asrc_ioctl_convert(struct asrc_pair_params *params,
  92127. + void __user *user)
  92128. +{
  92129. + enum asrc_pair_index index = params->index;
  92130. + struct asrc_convert_buffer buf;
  92131. + long ret;
  92132. +
  92133. + ret = copy_from_user(&buf, user, sizeof(buf));
  92134. + if (ret) {
  92135. + pair_err("failed to get buf from user space: %ld\n", ret);
  92136. + return ret;
  92137. + }
  92138. +
  92139. + ret = mxc_asrc_prepare_buffer(params, &buf);
  92140. + if (ret) {
  92141. + pair_err("failed to prepare buffer: %ld\n", ret);
  92142. + return ret;
  92143. + }
  92144. +
  92145. +#ifdef ASRC_POLLING_WITHOUT_DMA
  92146. + asrc_polling_debug(params);
  92147. +#else
  92148. + mxc_asrc_submit_dma(params);
  92149. +#endif
  92150. +
  92151. + ret = mxc_asrc_process_buffer(params, &buf);
  92152. + if (ret) {
  92153. + pair_err("failed to process buffer: %ld\n", ret);
  92154. + return ret;
  92155. + }
  92156. +
  92157. + ret = copy_to_user(user, &buf, sizeof(buf));
  92158. + if (ret) {
  92159. + pair_err("failed to send buf to user space: %ld\n", ret);
  92160. + return ret;
  92161. + }
  92162. +
  92163. + return 0;
  92164. +}
  92165. +
  92166. +static long asrc_ioctl_start_conv(struct asrc_pair_params *params,
  92167. + void __user *user)
  92168. +{
  92169. + enum asrc_pair_index index;
  92170. + long ret;
  92171. +
  92172. + ret = copy_from_user(&index, user, sizeof(index));
  92173. + if (ret) {
  92174. + dev_err(asrc->dev, "failed to get index from user space: %ld\n", ret);
  92175. + return ret;
  92176. + }
  92177. +
  92178. + params->asrc_active = 1;
  92179. + asrc_start_conv(index);
  92180. +
  92181. + return 0;
  92182. +}
  92183. +
  92184. +static long asrc_ioctl_stop_conv(struct asrc_pair_params *params,
  92185. + void __user *user)
  92186. +{
  92187. + enum asrc_pair_index index;
  92188. + long ret;
  92189. +
  92190. + ret = copy_from_user(&index, user, sizeof(index));
  92191. + if (ret) {
  92192. + dev_err(asrc->dev, "failed to get index from user space: %ld\n", ret);
  92193. + return ret;
  92194. + }
  92195. +
  92196. + dmaengine_terminate_all(params->input_dma_channel);
  92197. + dmaengine_terminate_all(params->output_dma_channel);
  92198. +
  92199. + asrc_stop_conv(index);
  92200. + params->asrc_active = 0;
  92201. +
  92202. + return 0;
  92203. +}
  92204. +
  92205. +static long asrc_ioctl_status(struct asrc_pair_params *params,
  92206. + void __user *user)
  92207. +{
  92208. + enum asrc_pair_index index = params->index;
  92209. + struct asrc_status_flags flags;
  92210. + long ret;
  92211. +
  92212. + ret = copy_from_user(&flags, user, sizeof(flags));
  92213. + if (ret) {
  92214. + pair_err("failed to get flags from user space: %ld\n", ret);
  92215. + return ret;
  92216. + }
  92217. +
  92218. + asrc_get_status(&flags);
  92219. +
  92220. + ret = copy_to_user(user, &flags, sizeof(flags));
  92221. + if (ret) {
  92222. + pair_err("failed to send flags to user space: %ld\n", ret);
  92223. + return ret;
  92224. + }
  92225. +
  92226. + return 0;
  92227. +}
  92228. +
  92229. +static long asrc_ioctl_flush(struct asrc_pair_params *params,
  92230. + void __user *user)
  92231. +{
  92232. + enum asrc_pair_index index = params->index;
  92233. + init_completion(&params->input_complete);
  92234. + init_completion(&params->output_complete);
  92235. + init_completion(&params->lastperiod_complete);
  92236. +
  92237. + /* Release DMA and request again */
  92238. + dma_release_channel(params->input_dma_channel);
  92239. + dma_release_channel(params->output_dma_channel);
  92240. +
  92241. + params->input_dma_channel = imx_asrc_get_dma_channel(index, true);
  92242. + if (params->input_dma_channel == NULL) {
  92243. + pair_err("failed to request input task dma channel\n");
  92244. + return -EBUSY;
  92245. + }
  92246. +
  92247. + params->output_dma_channel = imx_asrc_get_dma_channel(index, false);
  92248. + if (params->output_dma_channel == NULL) {
  92249. + pair_err("failed to request output task dma channel\n");
  92250. + return -EBUSY;
  92251. + }
  92252. +
  92253. + return 0;
  92254. +}
  92255. +
  92256. +static long asrc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  92257. +{
  92258. + struct asrc_pair_params *params = file->private_data;
  92259. + void __user *user = (void __user *)arg;
  92260. + long ret = 0;
  92261. +
  92262. + switch (cmd) {
  92263. + case ASRC_REQ_PAIR:
  92264. + ret = asrc_ioctl_req_pair(params, user);
  92265. + break;
  92266. + case ASRC_CONFIG_PAIR:
  92267. + ret = asrc_ioctl_config_pair(params, user);
  92268. + break;
  92269. + case ASRC_RELEASE_PAIR:
  92270. + ret = asrc_ioctl_release_pair(params, user);
  92271. + break;
  92272. + case ASRC_CONVERT:
  92273. + ret = asrc_ioctl_convert(params, user);
  92274. + break;
  92275. + case ASRC_START_CONV:
  92276. + ret = asrc_ioctl_start_conv(params, user);
  92277. + dump_regs();
  92278. + break;
  92279. + case ASRC_STOP_CONV:
  92280. + ret = asrc_ioctl_stop_conv(params, user);
  92281. + break;
  92282. + case ASRC_STATUS:
  92283. + ret = asrc_ioctl_status(params, user);
  92284. + break;
  92285. + case ASRC_FLUSH:
  92286. + ret = asrc_ioctl_flush(params, user);
  92287. + break;
  92288. + default:
  92289. + dev_err(asrc->dev, "invalid ioctl cmd!\n");
  92290. + break;
  92291. + }
  92292. +
  92293. + return ret;
  92294. +}
  92295. +
  92296. +static int mxc_asrc_open(struct inode *inode, struct file *file)
  92297. +{
  92298. + struct asrc_pair_params *params;
  92299. + int ret = 0;
  92300. +
  92301. + ret = signal_pending(current);
  92302. + if (ret) {
  92303. + dev_err(asrc->dev, "current process has a signal pending\n");
  92304. + return ret;
  92305. + }
  92306. +
  92307. + params = kzalloc(sizeof(struct asrc_pair_params), GFP_KERNEL);
  92308. + if (params == NULL) {
  92309. + dev_err(asrc->dev, "failed to allocate pair_params\n");
  92310. + return -ENOBUFS;
  92311. + }
  92312. +
  92313. + file->private_data = params;
  92314. +
  92315. + return ret;
  92316. +}
  92317. +
  92318. +static int mxc_asrc_close(struct inode *inode, struct file *file)
  92319. +{
  92320. + struct asrc_pair_params *params;
  92321. + unsigned long lock_flags;
  92322. +
  92323. + params = file->private_data;
  92324. +
  92325. + if (!params)
  92326. + return 0;
  92327. +
  92328. + if (params->asrc_active) {
  92329. + params->asrc_active = 0;
  92330. +
  92331. + dmaengine_terminate_all(params->input_dma_channel);
  92332. + dmaengine_terminate_all(params->output_dma_channel);
  92333. +
  92334. + asrc_stop_conv(params->index);
  92335. +
  92336. + complete(&params->input_complete);
  92337. + complete(&params->output_complete);
  92338. + complete(&params->lastperiod_complete);
  92339. + }
  92340. +
  92341. + if (params->pair_hold) {
  92342. + spin_lock_irqsave(&pair_lock, lock_flags);
  92343. + params->pair_hold = 0;
  92344. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  92345. +
  92346. + if (params->input_dma_channel)
  92347. + dma_release_channel(params->input_dma_channel);
  92348. + if (params->output_dma_channel)
  92349. + dma_release_channel(params->output_dma_channel);
  92350. +
  92351. + mxc_free_dma_buf(params);
  92352. +
  92353. + asrc_release_pair(params->index);
  92354. + asrc_finish_conv(params->index);
  92355. + }
  92356. +
  92357. + kfree(params);
  92358. + file->private_data = NULL;
  92359. +
  92360. + return 0;
  92361. +}
  92362. +
  92363. +static int mxc_asrc_mmap(struct file *file, struct vm_area_struct *vma)
  92364. +{
  92365. + unsigned long size = vma->vm_end - vma->vm_start;
  92366. + int ret;
  92367. +
  92368. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  92369. +
  92370. + ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  92371. + size, vma->vm_page_prot);
  92372. + if (ret) {
  92373. + dev_err(asrc->dev, "failed to memory map!\n");
  92374. + return ret;
  92375. + }
  92376. +
  92377. + vma->vm_flags &= ~VM_IO;
  92378. +
  92379. + return ret;
  92380. +}
  92381. +
  92382. +static const struct file_operations asrc_fops = {
  92383. + .owner = THIS_MODULE,
  92384. + .unlocked_ioctl = asrc_ioctl,
  92385. + .mmap = mxc_asrc_mmap,
  92386. + .open = mxc_asrc_open,
  92387. + .release = mxc_asrc_close,
  92388. +};
  92389. +
  92390. +static struct miscdevice asrc_miscdev = {
  92391. + .name = "mxc_asrc",
  92392. + .fops = &asrc_fops,
  92393. + .minor = MISC_DYNAMIC_MINOR,
  92394. +};
  92395. +
  92396. +static int asrc_read_proc_attr(struct file *file, char __user *buf,
  92397. + size_t count, loff_t *off)
  92398. +{
  92399. + char tmpbuf[80];
  92400. + int len = 0;
  92401. + u32 reg;
  92402. +
  92403. + if (*off)
  92404. + return 0;
  92405. +
  92406. + regmap_read(asrc->regmap, REG_ASRCNCR, &reg);
  92407. +
  92408. + len += sprintf(tmpbuf, "ANCA: %d\nANCB: %d\nANCC: %d\n",
  92409. + ASRCNCR_ANCx_get(ASRC_PAIR_A, reg, asrc->channel_bits),
  92410. + ASRCNCR_ANCx_get(ASRC_PAIR_B, reg, asrc->channel_bits),
  92411. + ASRCNCR_ANCx_get(ASRC_PAIR_C, reg, asrc->channel_bits));
  92412. +
  92413. + if (len > count)
  92414. + return 0;
  92415. +
  92416. + if (copy_to_user(buf, &tmpbuf, len))
  92417. + return -EFAULT;
  92418. +
  92419. + *off += len;
  92420. +
  92421. + return len;
  92422. +}
  92423. +
  92424. +#define ASRC_MAX_PROC_BUFFER_SIZE 63
  92425. +
  92426. +static int asrc_write_proc_attr(struct file *file, const char __user *buffer,
  92427. + size_t count, loff_t *data)
  92428. +{
  92429. + char buf[ASRC_MAX_PROC_BUFFER_SIZE];
  92430. + int na, nb, nc;
  92431. + int total;
  92432. +
  92433. + if (count > ASRC_MAX_PROC_BUFFER_SIZE) {
  92434. + dev_err(asrc->dev, "proc write: the input string was too long\n");
  92435. + return -EINVAL;
  92436. + }
  92437. +
  92438. + if (copy_from_user(buf, buffer, count)) {
  92439. + dev_err(asrc->dev, "proc write: failed to copy buffer from user\n");
  92440. + return -EFAULT;
  92441. + }
  92442. +
  92443. + sscanf(buf, "ANCA: %d\nANCB: %d\nANCC: %d", &na, &nb, &nc);
  92444. +
  92445. + total = asrc->channel_bits > 3 ? 10 : 5;
  92446. +
  92447. + if (na + nb + nc > total) {
  92448. + dev_err(asrc->dev, "don't surpass %d for total\n", total);
  92449. + return -EINVAL;
  92450. + } else if (na % 2 != 0 || nb % 2 != 0 || nc % 2 != 0) {
  92451. + dev_err(asrc->dev, "please set an even number for each pair\n");
  92452. + return -EINVAL;
  92453. + } else if (na < 0 || nb < 0 || nc < 0) {
  92454. + dev_err(asrc->dev, "please set an positive number for each pair\n");
  92455. + return -EINVAL;
  92456. + }
  92457. +
  92458. +
  92459. + asrc->asrc_pair[ASRC_PAIR_A].chn_max = na;
  92460. + asrc->asrc_pair[ASRC_PAIR_B].chn_max = nb;
  92461. + asrc->asrc_pair[ASRC_PAIR_C].chn_max = nc;
  92462. +
  92463. + /* Update channel number settings */
  92464. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  92465. + ASRCNCR_ANCx_MASK(ASRC_PAIR_A, asrc->channel_bits),
  92466. + ASRCNCR_ANCx_set(ASRC_PAIR_A, na, asrc->channel_bits));
  92467. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  92468. + ASRCNCR_ANCx_MASK(ASRC_PAIR_B, asrc->channel_bits),
  92469. + ASRCNCR_ANCx_set(ASRC_PAIR_B, nb, asrc->channel_bits));
  92470. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  92471. + ASRCNCR_ANCx_MASK(ASRC_PAIR_C, asrc->channel_bits),
  92472. + ASRCNCR_ANCx_set(ASRC_PAIR_C, nc, asrc->channel_bits));
  92473. +
  92474. + return count;
  92475. +}
  92476. +
  92477. +static const struct file_operations asrc_proc_fops = {
  92478. + .read = asrc_read_proc_attr,
  92479. + .write = asrc_write_proc_attr,
  92480. +};
  92481. +
  92482. +static void asrc_proc_create(void)
  92483. +{
  92484. + struct proc_dir_entry *proc_attr;
  92485. +
  92486. + asrc->proc_asrc = proc_mkdir(ASRC_PROC_PATH, NULL);
  92487. + if (!asrc->proc_asrc) {
  92488. + dev_err(asrc->dev, "failed to create proc entry %s\n", ASRC_PROC_PATH);
  92489. + return;
  92490. + }
  92491. +
  92492. + proc_attr = proc_create("ChSettings", S_IFREG | S_IRUGO | S_IWUSR,
  92493. + asrc->proc_asrc, &asrc_proc_fops);
  92494. + if (!proc_attr) {
  92495. + remove_proc_entry(ASRC_PROC_PATH, NULL);
  92496. + dev_err(asrc->dev, "failed to create proc attribute entry\n");
  92497. + }
  92498. +}
  92499. +
  92500. +static void asrc_proc_remove(void)
  92501. +{
  92502. + remove_proc_entry("ChSettings", asrc->proc_asrc);
  92503. + remove_proc_entry(ASRC_PROC_PATH, NULL);
  92504. +}
  92505. +
  92506. +
  92507. +static bool asrc_readable_reg(struct device *dev, unsigned int reg)
  92508. +{
  92509. + switch (reg) {
  92510. + case REG_ASRCTR:
  92511. + case REG_ASRIER:
  92512. + case REG_ASRCNCR:
  92513. + case REG_ASRCFG:
  92514. + case REG_ASRCSR:
  92515. + case REG_ASRCDR1:
  92516. + case REG_ASRCDR2:
  92517. + case REG_ASRSTR:
  92518. + case REG_ASRPM1:
  92519. + case REG_ASRPM2:
  92520. + case REG_ASRPM3:
  92521. + case REG_ASRPM4:
  92522. + case REG_ASRPM5:
  92523. + case REG_ASRTFR1:
  92524. + case REG_ASRCCR:
  92525. + case REG_ASRDOA:
  92526. + case REG_ASRDOB:
  92527. + case REG_ASRDOC:
  92528. + case REG_ASRIDRHA:
  92529. + case REG_ASRIDRLA:
  92530. + case REG_ASRIDRHB:
  92531. + case REG_ASRIDRLB:
  92532. + case REG_ASRIDRHC:
  92533. + case REG_ASRIDRLC:
  92534. + case REG_ASR76K:
  92535. + case REG_ASR56K:
  92536. + case REG_ASRMCRA:
  92537. + case REG_ASRFSTA:
  92538. + case REG_ASRMCRB:
  92539. + case REG_ASRFSTB:
  92540. + case REG_ASRMCRC:
  92541. + case REG_ASRFSTC:
  92542. + case REG_ASRMCR1A:
  92543. + case REG_ASRMCR1B:
  92544. + case REG_ASRMCR1C:
  92545. + return true;
  92546. + default:
  92547. + return false;
  92548. + }
  92549. +}
  92550. +
  92551. +static bool asrc_writeable_reg(struct device *dev, unsigned int reg)
  92552. +{
  92553. + switch (reg) {
  92554. + case REG_ASRCTR:
  92555. + case REG_ASRIER:
  92556. + case REG_ASRCNCR:
  92557. + case REG_ASRCFG:
  92558. + case REG_ASRCSR:
  92559. + case REG_ASRCDR1:
  92560. + case REG_ASRCDR2:
  92561. + case REG_ASRSTR:
  92562. + case REG_ASRPM1:
  92563. + case REG_ASRPM2:
  92564. + case REG_ASRPM3:
  92565. + case REG_ASRPM4:
  92566. + case REG_ASRPM5:
  92567. + case REG_ASRTFR1:
  92568. + case REG_ASRCCR:
  92569. + case REG_ASRDIA:
  92570. + case REG_ASRDIB:
  92571. + case REG_ASRDIC:
  92572. + case REG_ASRIDRHA:
  92573. + case REG_ASRIDRLA:
  92574. + case REG_ASRIDRHB:
  92575. + case REG_ASRIDRLB:
  92576. + case REG_ASRIDRHC:
  92577. + case REG_ASRIDRLC:
  92578. + case REG_ASR76K:
  92579. + case REG_ASR56K:
  92580. + case REG_ASRMCRA:
  92581. + case REG_ASRMCRB:
  92582. + case REG_ASRMCRC:
  92583. + case REG_ASRMCR1A:
  92584. + case REG_ASRMCR1B:
  92585. + case REG_ASRMCR1C:
  92586. + return true;
  92587. + default:
  92588. + return false;
  92589. + }
  92590. +}
  92591. +
  92592. +static struct regmap_config asrc_regmap_config = {
  92593. + .reg_bits = 32,
  92594. + .reg_stride = 4,
  92595. + .val_bits = 32,
  92596. +
  92597. + .max_register = REG_ASRMCR1C,
  92598. + .readable_reg = asrc_readable_reg,
  92599. + .writeable_reg = asrc_writeable_reg,
  92600. +};
  92601. +
  92602. +static int mxc_asrc_probe(struct platform_device *pdev)
  92603. +{
  92604. + const struct of_device_id *of_id = of_match_device(fsl_asrc_ids, &pdev->dev);
  92605. + struct device_node *np = pdev->dev.of_node;
  92606. + enum mxc_asrc_type devtype;
  92607. + struct resource *res;
  92608. + void __iomem *regs;
  92609. + int ret;
  92610. +
  92611. + /* Check if the device is existed */
  92612. + if (!np)
  92613. + return -ENODEV;
  92614. +
  92615. + asrc = devm_kzalloc(&pdev->dev, sizeof(struct asrc_data), GFP_KERNEL);
  92616. + if (!asrc)
  92617. + return -ENOMEM;
  92618. +
  92619. + if (of_id) {
  92620. + const struct platform_device_id *id_entry = of_id->data;
  92621. + devtype = id_entry->driver_data;
  92622. + } else {
  92623. + devtype = pdev->id_entry->driver_data;
  92624. + }
  92625. +
  92626. + asrc->dev = &pdev->dev;
  92627. + asrc->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  92628. +
  92629. + asrc->asrc_pair[ASRC_PAIR_A].chn_max = 2;
  92630. + asrc->asrc_pair[ASRC_PAIR_B].chn_max = 6;
  92631. + asrc->asrc_pair[ASRC_PAIR_C].chn_max = 2;
  92632. + asrc->asrc_pair[ASRC_PAIR_A].overload_error = 0;
  92633. + asrc->asrc_pair[ASRC_PAIR_B].overload_error = 0;
  92634. + asrc->asrc_pair[ASRC_PAIR_C].overload_error = 0;
  92635. +
  92636. + /* Map the address */
  92637. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  92638. + if (IS_ERR(res)) {
  92639. + dev_err(&pdev->dev, "could not determine device resources\n");
  92640. + return PTR_ERR(res);
  92641. + }
  92642. +
  92643. + regs = devm_ioremap_resource(&pdev->dev, res);
  92644. + if (IS_ERR(regs)) {
  92645. + dev_err(&pdev->dev, "could not map device resources\n");
  92646. + return PTR_ERR(regs);
  92647. + }
  92648. + asrc->paddr = res->start;
  92649. +
  92650. + /* Register regmap and let it prepare core clock */
  92651. + asrc->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
  92652. + "core", regs, &asrc_regmap_config);
  92653. + if (IS_ERR(asrc->regmap)) {
  92654. + dev_err(&pdev->dev, "regmap init failed\n");
  92655. + return PTR_ERR(asrc->regmap);
  92656. + }
  92657. +
  92658. + asrc->irq = platform_get_irq(pdev, 0);
  92659. + if (asrc->irq == NO_IRQ) {
  92660. + dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
  92661. + return asrc->irq;
  92662. + }
  92663. +
  92664. + ret = devm_request_irq(&pdev->dev, asrc->irq, asrc_isr, 0, np->name, NULL);
  92665. + if (ret) {
  92666. + dev_err(&pdev->dev, "could not claim irq %u: %d\n", asrc->irq, ret);
  92667. + return ret;
  92668. + }
  92669. +
  92670. + asrc->asrc_clk = devm_clk_get(&pdev->dev, "core");
  92671. + if (IS_ERR(asrc->asrc_clk)) {
  92672. + dev_err(&pdev->dev, "failed to get core clock\n");
  92673. + return PTR_ERR(asrc->asrc_clk);
  92674. + }
  92675. +
  92676. + asrc->dma_clk = devm_clk_get(&pdev->dev, "dma");
  92677. + if (IS_ERR(asrc->dma_clk)) {
  92678. + dev_err(&pdev->dev, "failed to get dma script clock\n");
  92679. + return PTR_ERR(asrc->dma_clk);
  92680. + }
  92681. +
  92682. + switch (devtype) {
  92683. + case IMX35_ASRC:
  92684. + asrc->channel_bits = 3;
  92685. + input_clk_map = input_clk_map_v1;
  92686. + output_clk_map = output_clk_map_v1;
  92687. + break;
  92688. + case IMX53_ASRC:
  92689. + asrc->channel_bits = 4;
  92690. + input_clk_map = input_clk_map_v2;
  92691. + output_clk_map = output_clk_map_v2;
  92692. + break;
  92693. + default:
  92694. + dev_err(&pdev->dev, "unsupported device type\n");
  92695. + return -EINVAL;
  92696. + }
  92697. +
  92698. + ret = misc_register(&asrc_miscdev);
  92699. + if (ret) {
  92700. + dev_err(&pdev->dev, "failed to register char device %d\n", ret);
  92701. + return ret;
  92702. + }
  92703. +
  92704. + asrc_proc_create();
  92705. +
  92706. + ret = mxc_init_asrc();
  92707. + if (ret) {
  92708. + dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
  92709. + goto err_misc;
  92710. + }
  92711. +
  92712. + dev_info(&pdev->dev, "mxc_asrc registered\n");
  92713. +
  92714. + return ret;
  92715. +
  92716. +err_misc:
  92717. + misc_deregister(&asrc_miscdev);
  92718. +
  92719. + return ret;
  92720. +}
  92721. +
  92722. +static int mxc_asrc_remove(struct platform_device *pdev)
  92723. +{
  92724. + asrc_proc_remove();
  92725. + misc_deregister(&asrc_miscdev);
  92726. +
  92727. + return 0;
  92728. +}
  92729. +
  92730. +static struct platform_driver mxc_asrc_driver = {
  92731. + .driver = {
  92732. + .name = "mxc_asrc",
  92733. + .of_match_table = fsl_asrc_ids,
  92734. + },
  92735. + .probe = mxc_asrc_probe,
  92736. + .remove = mxc_asrc_remove,
  92737. +};
  92738. +
  92739. +module_platform_driver(mxc_asrc_driver);
  92740. +
  92741. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  92742. +MODULE_DESCRIPTION("Asynchronous Sample Rate Converter");
  92743. +MODULE_LICENSE("GPL");
  92744. +MODULE_ALIAS("platform:mxc_asrc");
  92745. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c
  92746. --- linux-3.14.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c 1969-12-31 18:00:00.000000000 -0600
  92747. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c 2014-12-08 00:31:53.460418001 -0600
  92748. @@ -0,0 +1,932 @@
  92749. +/****************************************************************************
  92750. +*
  92751. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  92752. +*
  92753. +* This program is free software; you can redistribute it and/or modify
  92754. +* it under the terms of the GNU General Public License as published by
  92755. +* the Free Software Foundation; either version 2 of the license, or
  92756. +* (at your option) any later version.
  92757. +*
  92758. +* This program is distributed in the hope that it will be useful,
  92759. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  92760. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  92761. +* GNU General Public License for more details.
  92762. +*
  92763. +* You should have received a copy of the GNU General Public License
  92764. +* along with this program; if not write to the Free Software
  92765. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  92766. +*
  92767. +*****************************************************************************/
  92768. +
  92769. +
  92770. +#include "gc_hal.h"
  92771. +#include "gc_hal_kernel.h"
  92772. +
  92773. +#if gcdENABLE_VG
  92774. +
  92775. +#include "gc_hal_kernel_hardware_command_vg.h"
  92776. +
  92777. +#define _GC_OBJ_ZONE gcvZONE_COMMAND
  92778. +
  92779. +/******************************************************************************\
  92780. +****************************** gckVGCOMMAND API code *****************************
  92781. +\******************************************************************************/
  92782. +
  92783. +/*******************************************************************************
  92784. +**
  92785. +** gckVGCOMMAND_InitializeInfo
  92786. +**
  92787. +** Initialize architecture dependent command buffer information.
  92788. +**
  92789. +** INPUT:
  92790. +**
  92791. +** gckVGCOMMAND Command
  92792. +** Pointer to the Command object.
  92793. +**
  92794. +** OUTPUT:
  92795. +**
  92796. +** Nothing.
  92797. +*/
  92798. +gceSTATUS
  92799. +gckVGCOMMAND_InitializeInfo(
  92800. + IN gckVGCOMMAND Command
  92801. + )
  92802. +{
  92803. + gceSTATUS status;
  92804. + gcmkHEADER_ARG("Command=0x%x", Command);
  92805. +
  92806. + /* Verify the arguments. */
  92807. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  92808. +
  92809. + do
  92810. + {
  92811. + /* Reset interrupts. */
  92812. + Command->info.feBufferInt = -1;
  92813. + Command->info.tsOverflowInt = -1;
  92814. +
  92815. + /* Set command buffer attributes. */
  92816. + Command->info.addressAlignment = 64;
  92817. + Command->info.commandAlignment = 8;
  92818. +
  92819. + /* Determine command alignment address mask. */
  92820. + 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)));
  92821. +
  92822. + /* Query the number of bytes needed by the STATE command. */
  92823. + gcmkERR_BREAK(gckVGCOMMAND_StateCommand(
  92824. + Command, 0x0, gcvNULL, (gctUINT32)~0, 0,
  92825. + &Command->info.stateCommandSize
  92826. + ));
  92827. +
  92828. + /* Query the number of bytes needed by the RESTART command. */
  92829. + gcmkERR_BREAK(gckVGCOMMAND_RestartCommand(
  92830. + Command, gcvNULL, (gctUINT32)~0, 0,
  92831. + &Command->info.restartCommandSize
  92832. + ));
  92833. +
  92834. + /* Query the number of bytes needed by the FETCH command. */
  92835. + gcmkERR_BREAK(gckVGCOMMAND_FetchCommand(
  92836. + Command, gcvNULL, (gctUINT32)~0, 0,
  92837. + &Command->info.fetchCommandSize
  92838. + ));
  92839. +
  92840. + /* Query the number of bytes needed by the CALL command. */
  92841. + gcmkERR_BREAK(gckVGCOMMAND_CallCommand(
  92842. + Command, gcvNULL, (gctUINT32)~0, 0,
  92843. + &Command->info.callCommandSize
  92844. + ));
  92845. +
  92846. + /* Query the number of bytes needed by the RETURN command. */
  92847. + gcmkERR_BREAK(gckVGCOMMAND_ReturnCommand(
  92848. + Command, gcvNULL,
  92849. + &Command->info.returnCommandSize
  92850. + ));
  92851. +
  92852. + /* Query the number of bytes needed by the EVENT command. */
  92853. + gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
  92854. + Command, gcvNULL, gcvBLOCK_PIXEL, -1,
  92855. + &Command->info.eventCommandSize
  92856. + ));
  92857. +
  92858. + /* Query the number of bytes needed by the END command. */
  92859. + gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
  92860. + Command, gcvNULL, -1,
  92861. + &Command->info.endCommandSize
  92862. + ));
  92863. +
  92864. + /* Determine the tail reserve size. */
  92865. + Command->info.staticTailSize = gcmMAX(
  92866. + Command->info.fetchCommandSize,
  92867. + gcmMAX(
  92868. + Command->info.returnCommandSize,
  92869. + Command->info.endCommandSize
  92870. + )
  92871. + );
  92872. +
  92873. + /* Determine the maximum tail size. */
  92874. + Command->info.dynamicTailSize
  92875. + = Command->info.staticTailSize
  92876. + + Command->info.eventCommandSize * gcvBLOCK_COUNT;
  92877. + }
  92878. + while (gcvFALSE);
  92879. +
  92880. + gcmkFOOTER();
  92881. + /* Return status. */
  92882. + return status;
  92883. +}
  92884. +
  92885. +/*******************************************************************************
  92886. +**
  92887. +** gckVGCOMMAND_StateCommand
  92888. +**
  92889. +** Append a STATE command at the specified location in the command buffer.
  92890. +**
  92891. +** INPUT:
  92892. +**
  92893. +** gckVGCOMMAND Command
  92894. +** Pointer to an gckVGCOMMAND object.
  92895. +**
  92896. +** gctUINT32 Pipe
  92897. +** Harwdare destination pipe.
  92898. +**
  92899. +** gctPOINTER Logical
  92900. +** Pointer to the current location inside the command buffer to append
  92901. +** STATE command at or gcvNULL to query the size of the command.
  92902. +**
  92903. +** gctUINT32 Address
  92904. +** Starting register address of the state buffer.
  92905. +** If 'Logical' is gcvNULL, this argument is ignored.
  92906. +**
  92907. +** gctUINT32 Count
  92908. +** Number of states in state buffer.
  92909. +** If 'Logical' is gcvNULL, this argument is ignored.
  92910. +**
  92911. +** gctSIZE_T * Bytes
  92912. +** Pointer to the number of bytes available for the STATE command.
  92913. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  92914. +**
  92915. +** OUTPUT:
  92916. +**
  92917. +** gctSIZE_T * Bytes
  92918. +** Pointer to a variable that will receive the number of bytes required
  92919. +** for the STATE command. If 'Bytes' is gcvNULL, nothing is returned.
  92920. +*/
  92921. +gceSTATUS
  92922. +gckVGCOMMAND_StateCommand(
  92923. + IN gckVGCOMMAND Command,
  92924. + IN gctUINT32 Pipe,
  92925. + IN gctPOINTER Logical,
  92926. + IN gctUINT32 Address,
  92927. + IN gctSIZE_T Count,
  92928. + IN OUT gctSIZE_T * Bytes
  92929. + )
  92930. +{
  92931. + gcmkHEADER_ARG("Command=0x%x Pipe=0x%x Logical=0x%x Address=0x%x Count=0x%x Bytes = 0x%x",
  92932. + Command, Pipe, Logical, Address, Count, Bytes);
  92933. +
  92934. + /* Verify the arguments. */
  92935. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  92936. +
  92937. + if (Command->fe20)
  92938. + {
  92939. + if (Logical != gcvNULL)
  92940. + {
  92941. + gctUINT32_PTR buffer;
  92942. +
  92943. + /* Cast the buffer pointer. */
  92944. + buffer = (gctUINT32_PTR) Logical;
  92945. +
  92946. + /* Append STATE. */
  92947. + buffer[0]
  92948. + = ((((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)))
  92949. + | ((((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)))
  92950. + | ((((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)))
  92951. + | ((((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)));
  92952. + }
  92953. +
  92954. + if (Bytes != gcvNULL)
  92955. + {
  92956. + /* Return number of bytes required by the STATE command. */
  92957. + *Bytes = 4 * (Count + 1);
  92958. + }
  92959. + }
  92960. + else
  92961. + {
  92962. + if (Logical != gcvNULL)
  92963. + {
  92964. + gctUINT32_PTR buffer;
  92965. +
  92966. + /* Cast the buffer pointer. */
  92967. + buffer = (gctUINT32_PTR) Logical;
  92968. +
  92969. + /* Append LOAD_STATE. */
  92970. + buffer[0]
  92971. + = ((((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)))
  92972. + | ((((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)))
  92973. + | ((((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)));
  92974. + }
  92975. +
  92976. + if (Bytes != gcvNULL)
  92977. + {
  92978. + /* Return number of bytes required by the STATE command. */
  92979. + *Bytes = 4 * (Count + 1);
  92980. + }
  92981. + }
  92982. +
  92983. + gcmkFOOTER_NO();
  92984. + /* Success. */
  92985. + return gcvSTATUS_OK;
  92986. +}
  92987. +
  92988. +/*******************************************************************************
  92989. +**
  92990. +** gckVGCOMMAND_RestartCommand
  92991. +**
  92992. +** Form a RESTART command at the specified location in the command buffer.
  92993. +**
  92994. +** INPUT:
  92995. +**
  92996. +** gckVGCOMMAND Command
  92997. +** Pointer to an gckVGCOMMAND object.
  92998. +**
  92999. +** gctPOINTER Logical
  93000. +** Pointer to the current location inside the command buffer to append
  93001. +** RESTART command at or gcvNULL to query the size of the command.
  93002. +**
  93003. +** gctUINT32 FetchAddress
  93004. +** The address of another command buffer to be executed by this RESTART
  93005. +** command. If 'Logical' is gcvNULL, this argument is ignored.
  93006. +**
  93007. +** gctUINT FetchCount
  93008. +** The number of 64-bit data quantities in another command buffer to
  93009. +** be executed by this RESTART command. If 'Logical' is gcvNULL, this
  93010. +** argument is ignored.
  93011. +**
  93012. +** gctSIZE_T * Bytes
  93013. +** Pointer to the number of bytes available for the RESTART command.
  93014. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93015. +**
  93016. +** OUTPUT:
  93017. +**
  93018. +** gctSIZE_T * Bytes
  93019. +** Pointer to a variable that will receive the number of bytes required
  93020. +** for the RESTART command. If 'Bytes' is gcvNULL, nothing is returned.
  93021. +*/
  93022. +gceSTATUS
  93023. +gckVGCOMMAND_RestartCommand(
  93024. + IN gckVGCOMMAND Command,
  93025. + IN gctPOINTER Logical,
  93026. + IN gctUINT32 FetchAddress,
  93027. + IN gctUINT FetchCount,
  93028. + IN OUT gctSIZE_T * Bytes
  93029. + )
  93030. +{
  93031. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
  93032. + Command, Logical, FetchAddress, FetchCount, Bytes);
  93033. + /* Verify the arguments. */
  93034. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93035. +
  93036. + if (Command->fe20)
  93037. + {
  93038. + if (Logical != gcvNULL)
  93039. + {
  93040. + gctUINT32_PTR buffer;
  93041. + gctUINT32 beginEndMark;
  93042. +
  93043. + /* Cast the buffer pointer. */
  93044. + buffer = (gctUINT32_PTR) Logical;
  93045. +
  93046. + /* Determine Begin/End flag. */
  93047. + beginEndMark = (FetchCount > 0)
  93048. + ? ((((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)))
  93049. + : ((((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)));
  93050. +
  93051. + /* Append RESTART. */
  93052. + buffer[0]
  93053. + = ((((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)))
  93054. + | ((((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)))
  93055. + | beginEndMark;
  93056. +
  93057. + buffer[1]
  93058. + = FetchAddress;
  93059. + }
  93060. +
  93061. + if (Bytes != gcvNULL)
  93062. + {
  93063. + /* Return number of bytes required by the RESTART command. */
  93064. + *Bytes = 8;
  93065. + }
  93066. + }
  93067. + else
  93068. + {
  93069. + gcmkFOOTER_NO();
  93070. + return gcvSTATUS_NOT_SUPPORTED;
  93071. + }
  93072. +
  93073. +
  93074. + gcmkFOOTER_NO();
  93075. + /* Success. */
  93076. + return gcvSTATUS_OK;
  93077. +}
  93078. +
  93079. +/*******************************************************************************
  93080. +**
  93081. +** gckVGCOMMAND_FetchCommand
  93082. +**
  93083. +** Form a FETCH command at the specified location in the command buffer.
  93084. +**
  93085. +** INPUT:
  93086. +**
  93087. +** gckVGCOMMAND Command
  93088. +** Pointer to an gckVGCOMMAND object.
  93089. +**
  93090. +** gctPOINTER Logical
  93091. +** Pointer to the current location inside the command buffer to append
  93092. +** FETCH command at or gcvNULL to query the size of the command.
  93093. +**
  93094. +** gctUINT32 FetchAddress
  93095. +** The address of another command buffer to be executed by this FETCH
  93096. +** command. If 'Logical' is gcvNULL, this argument is ignored.
  93097. +**
  93098. +** gctUINT FetchCount
  93099. +** The number of 64-bit data quantities in another command buffer to
  93100. +** be executed by this FETCH command. If 'Logical' is gcvNULL, this
  93101. +** argument is ignored.
  93102. +**
  93103. +** gctSIZE_T * Bytes
  93104. +** Pointer to the number of bytes available for the FETCH command.
  93105. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93106. +**
  93107. +** OUTPUT:
  93108. +**
  93109. +** gctSIZE_T * Bytes
  93110. +** Pointer to a variable that will receive the number of bytes required
  93111. +** for the FETCH command. If 'Bytes' is gcvNULL, nothing is returned.
  93112. +*/
  93113. +gceSTATUS
  93114. +gckVGCOMMAND_FetchCommand(
  93115. + IN gckVGCOMMAND Command,
  93116. + IN gctPOINTER Logical,
  93117. + IN gctUINT32 FetchAddress,
  93118. + IN gctUINT FetchCount,
  93119. + IN OUT gctSIZE_T * Bytes
  93120. + )
  93121. +{
  93122. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
  93123. + Command, Logical, FetchAddress, FetchCount, Bytes);
  93124. + /* Verify the arguments. */
  93125. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93126. +
  93127. + if (Command->fe20)
  93128. + {
  93129. + if (Logical != gcvNULL)
  93130. + {
  93131. + gctUINT32_PTR buffer;
  93132. +
  93133. + /* Cast the buffer pointer. */
  93134. + buffer = (gctUINT32_PTR) Logical;
  93135. +
  93136. + /* Append FETCH. */
  93137. + buffer[0]
  93138. + = ((((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)))
  93139. + | ((((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)));
  93140. +
  93141. + buffer[1]
  93142. + = gcmkFIXADDRESS(FetchAddress);
  93143. + }
  93144. +
  93145. + if (Bytes != gcvNULL)
  93146. + {
  93147. + /* Return number of bytes required by the FETCH command. */
  93148. + *Bytes = 8;
  93149. + }
  93150. + }
  93151. + else
  93152. + {
  93153. + if (Logical != gcvNULL)
  93154. + {
  93155. + gctUINT32_PTR buffer;
  93156. +
  93157. + /* Cast the buffer pointer. */
  93158. + buffer = (gctUINT32_PTR) Logical;
  93159. +
  93160. + /* Append LINK. */
  93161. + buffer[0]
  93162. + = ((((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)))
  93163. + | ((((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)));
  93164. +
  93165. + buffer[1]
  93166. + = gcmkFIXADDRESS(FetchAddress);
  93167. + }
  93168. +
  93169. + if (Bytes != gcvNULL)
  93170. + {
  93171. + /* Return number of bytes required by the LINK command. */
  93172. + *Bytes = 8;
  93173. + }
  93174. + }
  93175. +
  93176. + gcmkFOOTER_NO();
  93177. + /* Success. */
  93178. + return gcvSTATUS_OK;
  93179. +}
  93180. +
  93181. +/*******************************************************************************
  93182. +**
  93183. +** gckVGCOMMAND_CallCommand
  93184. +**
  93185. +** Append a CALL command at the specified location in the command buffer.
  93186. +**
  93187. +** INPUT:
  93188. +**
  93189. +** gckVGCOMMAND Command
  93190. +** Pointer to an gckVGCOMMAND object.
  93191. +**
  93192. +** gctPOINTER Logical
  93193. +** Pointer to the current location inside the command buffer to append
  93194. +** CALL command at or gcvNULL to query the size of the command.
  93195. +**
  93196. +** gctUINT32 FetchAddress
  93197. +** The address of another command buffer to be executed by this CALL
  93198. +** command. If 'Logical' is gcvNULL, this argument is ignored.
  93199. +**
  93200. +** gctUINT FetchCount
  93201. +** The number of 64-bit data quantities in another command buffer to
  93202. +** be executed by this CALL command. If 'Logical' is gcvNULL, this
  93203. +** argument is ignored.
  93204. +**
  93205. +** gctSIZE_T * Bytes
  93206. +** Pointer to the number of bytes available for the CALL command.
  93207. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93208. +**
  93209. +** OUTPUT:
  93210. +**
  93211. +** gctSIZE_T * Bytes
  93212. +** Pointer to a variable that will receive the number of bytes required
  93213. +** for the CALL command. If 'Bytes' is gcvNULL, nothing is returned.
  93214. +*/
  93215. +gceSTATUS
  93216. +gckVGCOMMAND_CallCommand(
  93217. + IN gckVGCOMMAND Command,
  93218. + IN gctPOINTER Logical,
  93219. + IN gctUINT32 FetchAddress,
  93220. + IN gctUINT FetchCount,
  93221. + IN OUT gctSIZE_T * Bytes
  93222. + )
  93223. +{
  93224. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
  93225. + Command, Logical, FetchAddress, FetchCount, Bytes);
  93226. + /* Verify the arguments. */
  93227. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93228. +
  93229. + if (Command->fe20)
  93230. + {
  93231. + if (Logical != gcvNULL)
  93232. + {
  93233. + gctUINT32_PTR buffer;
  93234. +
  93235. + /* Cast the buffer pointer. */
  93236. + buffer = (gctUINT32_PTR) Logical;
  93237. +
  93238. + /* Append CALL. */
  93239. + buffer[0]
  93240. + = ((((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)))
  93241. + | ((((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)));
  93242. +
  93243. + buffer[1]
  93244. + = gcmkFIXADDRESS(FetchAddress);
  93245. + }
  93246. +
  93247. + if (Bytes != gcvNULL)
  93248. + {
  93249. + /* Return number of bytes required by the CALL command. */
  93250. + *Bytes = 8;
  93251. + }
  93252. + }
  93253. + else
  93254. + {
  93255. + gcmkFOOTER_NO();
  93256. + return gcvSTATUS_NOT_SUPPORTED;
  93257. + }
  93258. +
  93259. + gcmkFOOTER_NO();
  93260. + /* Success. */
  93261. + return gcvSTATUS_OK;
  93262. +}
  93263. +
  93264. +/*******************************************************************************
  93265. +**
  93266. +** gckVGCOMMAND_ReturnCommand
  93267. +**
  93268. +** Append a RETURN command at the specified location in the command buffer.
  93269. +**
  93270. +** INPUT:
  93271. +**
  93272. +** gckVGCOMMAND Command
  93273. +** Pointer to an gckVGCOMMAND object.
  93274. +**
  93275. +** gctPOINTER Logical
  93276. +** Pointer to the current location inside the command buffer to append
  93277. +** RETURN command at or gcvNULL to query the size of the command.
  93278. +**
  93279. +** gctSIZE_T * Bytes
  93280. +** Pointer to the number of bytes available for the RETURN command.
  93281. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93282. +**
  93283. +** OUTPUT:
  93284. +**
  93285. +** gctSIZE_T * Bytes
  93286. +** Pointer to a variable that will receive the number of bytes required
  93287. +** for the RETURN command. If 'Bytes' is gcvNULL, nothing is returned.
  93288. +*/
  93289. +gceSTATUS
  93290. +gckVGCOMMAND_ReturnCommand(
  93291. + IN gckVGCOMMAND Command,
  93292. + IN gctPOINTER Logical,
  93293. + IN OUT gctSIZE_T * Bytes
  93294. + )
  93295. +{
  93296. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x Bytes = 0x%x",
  93297. + Command, Logical, Bytes);
  93298. + /* Verify the arguments. */
  93299. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93300. +
  93301. + if (Command->fe20)
  93302. + {
  93303. + if (Logical != gcvNULL)
  93304. + {
  93305. + gctUINT32_PTR buffer;
  93306. +
  93307. + /* Cast the buffer pointer. */
  93308. + buffer = (gctUINT32_PTR) Logical;
  93309. +
  93310. + /* Append RETURN. */
  93311. + buffer[0]
  93312. + = ((((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)));
  93313. + }
  93314. +
  93315. + if (Bytes != gcvNULL)
  93316. + {
  93317. + /* Return number of bytes required by the RETURN command. */
  93318. + *Bytes = 8;
  93319. + }
  93320. + }
  93321. + else
  93322. + {
  93323. + gcmkFOOTER_NO();
  93324. + return gcvSTATUS_NOT_SUPPORTED;
  93325. + }
  93326. +
  93327. + gcmkFOOTER_NO();
  93328. + /* Success. */
  93329. + return gcvSTATUS_OK;
  93330. +}
  93331. +
  93332. +/*******************************************************************************
  93333. +**
  93334. +** gckVGCOMMAND_EventCommand
  93335. +**
  93336. +** Form an EVENT command at the specified location in the command buffer.
  93337. +**
  93338. +** INPUT:
  93339. +**
  93340. +** gckVGCOMMAND Command
  93341. +** Pointer to the Command object.
  93342. +**
  93343. +** gctPOINTER Logical
  93344. +** Pointer to the current location inside the command buffer to append
  93345. +** EVENT command at or gcvNULL to query the size of the command.
  93346. +**
  93347. +** gctINT32 InterruptId
  93348. +** The ID of the interrupt to generate.
  93349. +** If 'Logical' is gcvNULL, this argument is ignored.
  93350. +**
  93351. +** gceBLOCK Block
  93352. +** Block that will generate the interrupt.
  93353. +**
  93354. +** gctSIZE_T * Bytes
  93355. +** Pointer to the number of bytes available for the EVENT command.
  93356. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93357. +**
  93358. +** OUTPUT:
  93359. +**
  93360. +** gctSIZE_T * Bytes
  93361. +** Pointer to a variable that will receive the number of bytes required
  93362. +** for the END command. If 'Bytes' is gcvNULL, nothing is returned.
  93363. +*/
  93364. +gceSTATUS
  93365. +gckVGCOMMAND_EventCommand(
  93366. + IN gckVGCOMMAND Command,
  93367. + IN gctPOINTER Logical,
  93368. + IN gceBLOCK Block,
  93369. + IN gctINT32 InterruptId,
  93370. + IN OUT gctSIZE_T * Bytes
  93371. + )
  93372. +{
  93373. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x Block=0x%x InterruptId=0x%x Bytes = 0x%x",
  93374. + Command, Logical, Block, InterruptId, Bytes);
  93375. + /* Verify the arguments. */
  93376. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93377. +
  93378. + if (Command->fe20)
  93379. + {
  93380. + typedef struct _gcsEVENTSTATES
  93381. + {
  93382. + /* Chips before VG21 use these values. */
  93383. + gctUINT eventFromFE;
  93384. + gctUINT eventFromPE;
  93385. +
  93386. + /* VG21 chips and later use SOURCE field. */
  93387. + gctUINT eventSource;
  93388. + }
  93389. + gcsEVENTSTATES;
  93390. +
  93391. + static gcsEVENTSTATES states[] =
  93392. + {
  93393. + /* gcvBLOCK_COMMAND */
  93394. + {
  93395. + (gctUINT)~0,
  93396. + (gctUINT)~0,
  93397. + (gctUINT)~0
  93398. + },
  93399. +
  93400. + /* gcvBLOCK_TESSELLATOR */
  93401. + {
  93402. + 0x0,
  93403. + 0x1,
  93404. + 0x10
  93405. + },
  93406. +
  93407. + /* gcvBLOCK_TESSELLATOR2 */
  93408. + {
  93409. + 0x0,
  93410. + 0x1,
  93411. + 0x12
  93412. + },
  93413. +
  93414. + /* gcvBLOCK_TESSELLATOR3 */
  93415. + {
  93416. + 0x0,
  93417. + 0x1,
  93418. + 0x14
  93419. + },
  93420. +
  93421. + /* gcvBLOCK_RASTER */
  93422. + {
  93423. + 0x0,
  93424. + 0x1,
  93425. + 0x07,
  93426. + },
  93427. +
  93428. + /* gcvBLOCK_VG */
  93429. + {
  93430. + 0x0,
  93431. + 0x1,
  93432. + 0x0F
  93433. + },
  93434. +
  93435. + /* gcvBLOCK_VG2 */
  93436. + {
  93437. + 0x0,
  93438. + 0x1,
  93439. + 0x11
  93440. + },
  93441. +
  93442. + /* gcvBLOCK_VG3 */
  93443. + {
  93444. + 0x0,
  93445. + 0x1,
  93446. + 0x13
  93447. + },
  93448. +
  93449. + /* gcvBLOCK_PIXEL */
  93450. + {
  93451. + 0x0,
  93452. + 0x1,
  93453. + 0x07
  93454. + },
  93455. + };
  93456. +
  93457. + /* Verify block ID. */
  93458. + gcmkVERIFY_ARGUMENT(gcmIS_VALID_INDEX(Block, states));
  93459. +
  93460. + if (Logical != gcvNULL)
  93461. + {
  93462. + gctUINT32_PTR buffer;
  93463. +
  93464. + /* Verify the event ID. */
  93465. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  93466. + gcmkVERIFY_ARGUMENT(InterruptId <= ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))));
  93467. +
  93468. + /* Cast the buffer pointer. */
  93469. + buffer = (gctUINT32_PTR) Logical;
  93470. +
  93471. + /* Append EVENT. */
  93472. + buffer[0]
  93473. + = ((((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)))
  93474. + | ((((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)))
  93475. + | ((((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)))
  93476. + | ((((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)));
  93477. +
  93478. + /* Determine chip version. */
  93479. + if (Command->vg21)
  93480. + {
  93481. + /* Get the event source for the block. */
  93482. + gctUINT eventSource = states[Block].eventSource;
  93483. +
  93484. + /* Supported? */
  93485. + if (eventSource == ~0)
  93486. + {
  93487. + gcmkFOOTER_NO();
  93488. + return gcvSTATUS_NOT_SUPPORTED;
  93489. + }
  93490. +
  93491. + buffer[1]
  93492. + = ((((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)))
  93493. + | ((((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)));
  93494. + }
  93495. + else
  93496. + {
  93497. + /* Get the event source for the block. */
  93498. + gctUINT eventFromFE = states[Block].eventFromFE;
  93499. + gctUINT eventFromPE = states[Block].eventFromPE;
  93500. +
  93501. + /* Supported? */
  93502. + if (eventFromFE == ~0)
  93503. + {
  93504. + gcmkFOOTER_NO();
  93505. + return gcvSTATUS_NOT_SUPPORTED;
  93506. + }
  93507. +
  93508. + buffer[1]
  93509. + = ((((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)))
  93510. + | ((((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)))
  93511. + | ((((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)));
  93512. + }
  93513. + }
  93514. +
  93515. + if (Bytes != gcvNULL)
  93516. + {
  93517. + /* Make sure the events are directly supported for the block. */
  93518. + if (states[Block].eventSource == ~0)
  93519. + {
  93520. + gcmkFOOTER_NO();
  93521. + return gcvSTATUS_NOT_SUPPORTED;
  93522. + }
  93523. +
  93524. + /* Return number of bytes required by the END command. */
  93525. + *Bytes = 8;
  93526. + }
  93527. + }
  93528. + else
  93529. + {
  93530. + if (Logical != gcvNULL)
  93531. + {
  93532. + gctUINT32_PTR buffer;
  93533. +
  93534. + /* Verify the event ID. */
  93535. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  93536. + gcmkVERIFY_ARGUMENT(InterruptId <= ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))));
  93537. +
  93538. + /* Cast the buffer pointer. */
  93539. + buffer = (gctUINT32_PTR) Logical;
  93540. +
  93541. + /* Append EVENT. */
  93542. + buffer[0]
  93543. + = ((((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)))
  93544. + | ((((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)))
  93545. + | ((((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)));
  93546. +
  93547. + /* Determine event source. */
  93548. + if (Block == gcvBLOCK_COMMAND)
  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 ? 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)));
  93553. + }
  93554. + else
  93555. + {
  93556. + buffer[1]
  93557. + = ((((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)))
  93558. + | ((((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)));
  93559. + }
  93560. + }
  93561. +
  93562. + if (Bytes != gcvNULL)
  93563. + {
  93564. + /* Return number of bytes required by the EVENT and END commands. */
  93565. + *Bytes = 8;
  93566. + }
  93567. + }
  93568. +
  93569. + gcmkFOOTER_NO();
  93570. + /* Success. */
  93571. + return gcvSTATUS_OK;
  93572. +}
  93573. +
  93574. +/*******************************************************************************
  93575. +**
  93576. +** gckVGCOMMAND_EndCommand
  93577. +**
  93578. +** Form an END command at the specified location in the command buffer.
  93579. +**
  93580. +** INPUT:
  93581. +**
  93582. +** gckVGCOMMAND Command
  93583. +** Pointer to the Command object.
  93584. +**
  93585. +** gctPOINTER Logical
  93586. +** Pointer to the current location inside the command buffer to append
  93587. +** END command at or gcvNULL to query the size of the command.
  93588. +**
  93589. +** gctINT32 InterruptId
  93590. +** The ID of the interrupt to generate.
  93591. +** If 'Logical' is gcvNULL, this argument will be ignored.
  93592. +**
  93593. +** gctSIZE_T * Bytes
  93594. +** Pointer to the number of bytes available for the END command.
  93595. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  93596. +**
  93597. +** OUTPUT:
  93598. +**
  93599. +** gctSIZE_T * Bytes
  93600. +** Pointer to a variable that will receive the number of bytes required
  93601. +** for the END command. If 'Bytes' is gcvNULL, nothing is returned.
  93602. +*/
  93603. +gceSTATUS
  93604. +gckVGCOMMAND_EndCommand(
  93605. + IN gckVGCOMMAND Command,
  93606. + IN gctPOINTER Logical,
  93607. + IN gctINT32 InterruptId,
  93608. + IN OUT gctSIZE_T * Bytes
  93609. + )
  93610. +{
  93611. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x InterruptId=0x%x Bytes = 0x%x",
  93612. + Command, Logical, InterruptId, Bytes);
  93613. + /* Verify the arguments. */
  93614. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  93615. +
  93616. + if (Command->fe20)
  93617. + {
  93618. + if (Logical != gcvNULL)
  93619. + {
  93620. + gctUINT32_PTR buffer;
  93621. +
  93622. + /* Verify the event ID. */
  93623. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  93624. +
  93625. + /* Cast the buffer pointer. */
  93626. + buffer = (gctUINT32_PTR) Logical;
  93627. +
  93628. + /* Append END. */
  93629. + buffer[0]
  93630. + = ((((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)))
  93631. + | ((((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)));
  93632. + }
  93633. +
  93634. + if (Bytes != gcvNULL)
  93635. + {
  93636. + /* Return number of bytes required by the END command. */
  93637. + *Bytes = 8;
  93638. + }
  93639. + }
  93640. + else
  93641. + {
  93642. + if (Logical != gcvNULL)
  93643. + {
  93644. + gctUINT32_PTR memory;
  93645. +
  93646. + /* Verify the event ID. */
  93647. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  93648. +
  93649. + /* Cast the buffer pointer. */
  93650. + memory = (gctUINT32_PTR) Logical;
  93651. +
  93652. + /* Append EVENT. */
  93653. + memory[0]
  93654. + = ((((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)))
  93655. + | ((((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)))
  93656. + | ((((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)));
  93657. +
  93658. + memory[1]
  93659. + = ((((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)))
  93660. + | ((((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)));
  93661. +
  93662. + /* Append END. */
  93663. + memory[2]
  93664. + = ((((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)));
  93665. + }
  93666. +
  93667. + if (Bytes != gcvNULL)
  93668. + {
  93669. + /* Return number of bytes required by the EVENT and END commands. */
  93670. + *Bytes = 16;
  93671. + }
  93672. + }
  93673. +
  93674. + gcmkFOOTER_NO();
  93675. + /* Success. */
  93676. + return gcvSTATUS_OK;
  93677. +}
  93678. +
  93679. +#endif /* gcdENABLE_VG */
  93680. +
  93681. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h
  93682. --- linux-3.14.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h 1969-12-31 18:00:00.000000000 -0600
  93683. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h 2014-12-08 00:31:53.460418001 -0600
  93684. @@ -0,0 +1,319 @@
  93685. +/****************************************************************************
  93686. +*
  93687. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  93688. +*
  93689. +* This program is free software; you can redistribute it and/or modify
  93690. +* it under the terms of the GNU General Public License as published by
  93691. +* the Free Software Foundation; either version 2 of the license, or
  93692. +* (at your option) any later version.
  93693. +*
  93694. +* This program is distributed in the hope that it will be useful,
  93695. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  93696. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  93697. +* GNU General Public License for more details.
  93698. +*
  93699. +* You should have received a copy of the GNU General Public License
  93700. +* along with this program; if not write to the Free Software
  93701. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  93702. +*
  93703. +*****************************************************************************/
  93704. +
  93705. +
  93706. +#ifndef __gc_hal_kernel_hardware_command_vg_h_
  93707. +#define __gc_hal_kernel_hardware_command_vg_h_
  93708. +
  93709. +/******************************************************************************\
  93710. +******************* Task and Interrupt Management Structures. ******************
  93711. +\******************************************************************************/
  93712. +
  93713. +/* Task storage header. */
  93714. +typedef struct _gcsTASK_STORAGE * gcsTASK_STORAGE_PTR;
  93715. +typedef struct _gcsTASK_STORAGE
  93716. +{
  93717. + /* Next allocated storage buffer. */
  93718. + gcsTASK_STORAGE_PTR next;
  93719. +}
  93720. +gcsTASK_STORAGE;
  93721. +
  93722. +/* Task container header. */
  93723. +typedef struct _gcsTASK_CONTAINER * gcsTASK_CONTAINER_PTR;
  93724. +typedef struct _gcsTASK_CONTAINER
  93725. +{
  93726. + /* The number of tasks left to be processed in the container. */
  93727. + gctINT referenceCount;
  93728. +
  93729. + /* Size of the buffer. */
  93730. + gctUINT size;
  93731. +
  93732. + /* Link to the previous and the next allocated containers. */
  93733. + gcsTASK_CONTAINER_PTR allocPrev;
  93734. + gcsTASK_CONTAINER_PTR allocNext;
  93735. +
  93736. + /* Link to the previous and the next containers in the free list. */
  93737. + gcsTASK_CONTAINER_PTR freePrev;
  93738. + gcsTASK_CONTAINER_PTR freeNext;
  93739. +}
  93740. +gcsTASK_CONTAINER;
  93741. +
  93742. +/* Kernel space task master table entry. */
  93743. +typedef struct _gcsBLOCK_TASK_ENTRY * gcsBLOCK_TASK_ENTRY_PTR;
  93744. +typedef struct _gcsBLOCK_TASK_ENTRY
  93745. +{
  93746. + /* Pointer to the current task container for the block. */
  93747. + gcsTASK_CONTAINER_PTR container;
  93748. +
  93749. + /* Pointer to the current task data within the container. */
  93750. + gcsTASK_HEADER_PTR task;
  93751. +
  93752. + /* Pointer to the last link task within the container. */
  93753. + gcsTASK_LINK_PTR link;
  93754. +
  93755. + /* Number of interrupts allocated for this block. */
  93756. + gctUINT interruptCount;
  93757. +
  93758. + /* The index of the current interrupt. */
  93759. + gctUINT interruptIndex;
  93760. +
  93761. + /* Interrupt semaphore. */
  93762. + gctSEMAPHORE interruptSemaphore;
  93763. +
  93764. + /* Interrupt value array. */
  93765. + gctINT32 interruptArray[32];
  93766. +}
  93767. +gcsBLOCK_TASK_ENTRY;
  93768. +
  93769. +
  93770. +/******************************************************************************\
  93771. +********************* Command Queue Management Structures. *********************
  93772. +\******************************************************************************/
  93773. +
  93774. +/* Command queue kernel element pointer. */
  93775. +typedef struct _gcsKERNEL_CMDQUEUE * gcsKERNEL_CMDQUEUE_PTR;
  93776. +
  93777. +/* Command queue object handler function type. */
  93778. +typedef gceSTATUS (* gctOBJECT_HANDLER) (
  93779. + gckVGKERNEL Kernel,
  93780. + gcsKERNEL_CMDQUEUE_PTR Entry
  93781. + );
  93782. +
  93783. +/* Command queue kernel element. */
  93784. +typedef struct _gcsKERNEL_CMDQUEUE
  93785. +{
  93786. + /* The number of buffers in the queue. */
  93787. + gcsCMDBUFFER_PTR commandBuffer;
  93788. +
  93789. + /* Pointer to the object handler function. */
  93790. + gctOBJECT_HANDLER handler;
  93791. +}
  93792. +gcsKERNEL_CMDQUEUE;
  93793. +
  93794. +/* Command queue header. */
  93795. +typedef struct _gcsKERNEL_QUEUE_HEADER * gcsKERNEL_QUEUE_HEADER_PTR;
  93796. +typedef struct _gcsKERNEL_QUEUE_HEADER
  93797. +{
  93798. + /* The size of the buffer in bytes. */
  93799. + gctUINT size;
  93800. +
  93801. + /* The number of pending entries to be processed. */
  93802. + volatile gctUINT pending;
  93803. +
  93804. + /* The current command queue entry. */
  93805. + gcsKERNEL_CMDQUEUE_PTR currentEntry;
  93806. +
  93807. + /* Next buffer. */
  93808. + gcsKERNEL_QUEUE_HEADER_PTR next;
  93809. +}
  93810. +gcsKERNEL_QUEUE_HEADER;
  93811. +
  93812. +
  93813. +/******************************************************************************\
  93814. +******************************* gckVGCOMMAND Object *******************************
  93815. +\******************************************************************************/
  93816. +
  93817. +/* gckVGCOMMAND object. */
  93818. +struct _gckVGCOMMAND
  93819. +{
  93820. + /***************************************************************************
  93821. + ** Object data and pointers.
  93822. + */
  93823. +
  93824. + gcsOBJECT object;
  93825. + gckVGKERNEL kernel;
  93826. + gckOS os;
  93827. + gckVGHARDWARE hardware;
  93828. +
  93829. + /* Features. */
  93830. + gctBOOL fe20;
  93831. + gctBOOL vg20;
  93832. + gctBOOL vg21;
  93833. +
  93834. +
  93835. + /***************************************************************************
  93836. + ** Enable command queue dumping.
  93837. + */
  93838. +
  93839. + gctBOOL enableDumping;
  93840. +
  93841. +
  93842. + /***************************************************************************
  93843. + ** Bus Error interrupt.
  93844. + */
  93845. +
  93846. + gctINT32 busErrorInt;
  93847. +
  93848. +
  93849. + /***************************************************************************
  93850. + ** Command buffer information.
  93851. + */
  93852. +
  93853. + gcsCOMMAND_BUFFER_INFO info;
  93854. +
  93855. +
  93856. + /***************************************************************************
  93857. + ** Synchronization objects.
  93858. + */
  93859. +
  93860. + gctPOINTER queueMutex;
  93861. + gctPOINTER taskMutex;
  93862. + gctPOINTER commitMutex;
  93863. +
  93864. +
  93865. + /***************************************************************************
  93866. + ** Task management.
  93867. + */
  93868. +
  93869. + /* The head of the storage buffer linked list. */
  93870. + gcsTASK_STORAGE_PTR taskStorage;
  93871. +
  93872. + /* Allocation size. */
  93873. + gctUINT taskStorageGranularity;
  93874. + gctUINT taskStorageUsable;
  93875. +
  93876. + /* The free container list. */
  93877. + gcsTASK_CONTAINER_PTR taskFreeHead;
  93878. + gcsTASK_CONTAINER_PTR taskFreeTail;
  93879. +
  93880. + /* Task table */
  93881. + gcsBLOCK_TASK_ENTRY taskTable[gcvBLOCK_COUNT];
  93882. +
  93883. +
  93884. + /***************************************************************************
  93885. + ** Command queue.
  93886. + */
  93887. +
  93888. + /* Pointer to the allocated queue memory. */
  93889. + gcsKERNEL_QUEUE_HEADER_PTR queue;
  93890. +
  93891. + /* Pointer to the current available queue from which new queue entries
  93892. + will be allocated. */
  93893. + gcsKERNEL_QUEUE_HEADER_PTR queueHead;
  93894. +
  93895. + /* If different from queueHead, points to the command queue which is
  93896. + currently being executed by the hardware. */
  93897. + gcsKERNEL_QUEUE_HEADER_PTR queueTail;
  93898. +
  93899. + /* Points to the queue to merge the tail with when the tail is processed. */
  93900. + gcsKERNEL_QUEUE_HEADER_PTR mergeQueue;
  93901. +
  93902. + /* Queue overflow counter. */
  93903. + gctUINT queueOverflow;
  93904. +
  93905. +
  93906. + /***************************************************************************
  93907. + ** Context.
  93908. + */
  93909. +
  93910. + /* Context counter used for unique ID. */
  93911. + gctUINT64 contextCounter;
  93912. +
  93913. + /* Current context ID. */
  93914. + gctUINT64 currentContext;
  93915. +
  93916. + /* Command queue power semaphore. */
  93917. + gctPOINTER powerSemaphore;
  93918. + gctINT32 powerStallInt;
  93919. + gcsCMDBUFFER_PTR powerStallBuffer;
  93920. + gctSIGNAL powerStallSignal;
  93921. +
  93922. +};
  93923. +
  93924. +/******************************************************************************\
  93925. +************************ gckVGCOMMAND Object Internal API. ***********************
  93926. +\******************************************************************************/
  93927. +
  93928. +/* Initialize architecture dependent command buffer information. */
  93929. +gceSTATUS
  93930. +gckVGCOMMAND_InitializeInfo(
  93931. + IN gckVGCOMMAND Command
  93932. + );
  93933. +
  93934. +/* Form a STATE command at the specified location in the command buffer. */
  93935. +gceSTATUS
  93936. +gckVGCOMMAND_StateCommand(
  93937. + IN gckVGCOMMAND Command,
  93938. + IN gctUINT32 Pipe,
  93939. + IN gctPOINTER Logical,
  93940. + IN gctUINT32 Address,
  93941. + IN gctSIZE_T Count,
  93942. + IN OUT gctSIZE_T * Bytes
  93943. + );
  93944. +
  93945. +/* Form a RESTART command at the specified location in the command buffer. */
  93946. +gceSTATUS
  93947. +gckVGCOMMAND_RestartCommand(
  93948. + IN gckVGCOMMAND Command,
  93949. + IN gctPOINTER Logical,
  93950. + IN gctUINT32 FetchAddress,
  93951. + IN gctUINT FetchCount,
  93952. + IN OUT gctSIZE_T * Bytes
  93953. + );
  93954. +
  93955. +/* Form a FETCH command at the specified location in the command buffer. */
  93956. +gceSTATUS
  93957. +gckVGCOMMAND_FetchCommand(
  93958. + IN gckVGCOMMAND Command,
  93959. + IN gctPOINTER Logical,
  93960. + IN gctUINT32 FetchAddress,
  93961. + IN gctUINT FetchCount,
  93962. + IN OUT gctSIZE_T * Bytes
  93963. + );
  93964. +
  93965. +/* Form a CALL command at the specified location in the command buffer. */
  93966. +gceSTATUS
  93967. +gckVGCOMMAND_CallCommand(
  93968. + IN gckVGCOMMAND Command,
  93969. + IN gctPOINTER Logical,
  93970. + IN gctUINT32 FetchAddress,
  93971. + IN gctUINT FetchCount,
  93972. + IN OUT gctSIZE_T * Bytes
  93973. + );
  93974. +
  93975. +/* Form a RETURN command at the specified location in the command buffer. */
  93976. +gceSTATUS
  93977. +gckVGCOMMAND_ReturnCommand(
  93978. + IN gckVGCOMMAND Command,
  93979. + IN gctPOINTER Logical,
  93980. + IN OUT gctSIZE_T * Bytes
  93981. + );
  93982. +
  93983. +/* Form an EVENT command at the specified location in the command buffer. */
  93984. +gceSTATUS
  93985. +gckVGCOMMAND_EventCommand(
  93986. + IN gckVGCOMMAND Command,
  93987. + IN gctPOINTER Logical,
  93988. + IN gceBLOCK Block,
  93989. + IN gctINT32 InterruptId,
  93990. + IN OUT gctSIZE_T * Bytes
  93991. + );
  93992. +
  93993. +/* Form an END command at the specified location in the command buffer. */
  93994. +gceSTATUS
  93995. +gckVGCOMMAND_EndCommand(
  93996. + IN gckVGCOMMAND Command,
  93997. + IN gctPOINTER Logical,
  93998. + IN gctINT32 InterruptId,
  93999. + IN OUT gctSIZE_T * Bytes
  94000. + );
  94001. +
  94002. +#endif /* __gc_hal_kernel_hardware_command_h_ */
  94003. +
  94004. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
  94005. --- linux-3.14.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c 1969-12-31 18:00:00.000000000 -0600
  94006. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c 2014-12-08 00:31:53.460418001 -0600
  94007. @@ -0,0 +1,2114 @@
  94008. +/****************************************************************************
  94009. +*
  94010. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  94011. +*
  94012. +* This program is free software; you can redistribute it and/or modify
  94013. +* it under the terms of the GNU General Public License as published by
  94014. +* the Free Software Foundation; either version 2 of the license, or
  94015. +* (at your option) any later version.
  94016. +*
  94017. +* This program is distributed in the hope that it will be useful,
  94018. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  94019. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  94020. +* GNU General Public License for more details.
  94021. +*
  94022. +* You should have received a copy of the GNU General Public License
  94023. +* along with this program; if not write to the Free Software
  94024. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  94025. +*
  94026. +*****************************************************************************/
  94027. +
  94028. +
  94029. +#include "gc_hal.h"
  94030. +#include "gc_hal_kernel.h"
  94031. +#include "gc_hal_kernel_hardware_command_vg.h"
  94032. +
  94033. +#if gcdENABLE_VG
  94034. +
  94035. +#define _GC_OBJ_ZONE gcvZONE_HARDWARE
  94036. +
  94037. +typedef enum
  94038. +{
  94039. + gcvPOWER_FLAG_INITIALIZE = 1 << 0,
  94040. + gcvPOWER_FLAG_STALL = 1 << 1,
  94041. + gcvPOWER_FLAG_STOP = 1 << 2,
  94042. + gcvPOWER_FLAG_START = 1 << 3,
  94043. + gcvPOWER_FLAG_RELEASE = 1 << 4,
  94044. + gcvPOWER_FLAG_DELAY = 1 << 5,
  94045. + gcvPOWER_FLAG_SAVE = 1 << 6,
  94046. + gcvPOWER_FLAG_ACQUIRE = 1 << 7,
  94047. + gcvPOWER_FLAG_POWER_OFF = 1 << 8,
  94048. + gcvPOWER_FLAG_CLOCK_OFF = 1 << 9,
  94049. + gcvPOWER_FLAG_CLOCK_ON = 1 << 10,
  94050. + gcvPOWER_FLAG_NOP = 1 << 11,
  94051. +}
  94052. +gcePOWER_FLAGS;
  94053. +
  94054. +/******************************************************************************\
  94055. +********************************* Support Code *********************************
  94056. +\******************************************************************************/
  94057. +static gceSTATUS
  94058. +_ResetGPU(
  94059. + IN gckOS Os
  94060. + )
  94061. +{
  94062. + gctUINT32 control, idle;
  94063. + gceSTATUS status;
  94064. +
  94065. + /* Read register. */
  94066. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  94067. + gcvCORE_VG,
  94068. + 0x00000,
  94069. + &control));
  94070. +
  94071. + for (;;)
  94072. + {
  94073. + /* Disable clock gating. */
  94074. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  94075. + gcvCORE_VG,
  94076. + 0x00104,
  94077. + 0x00000000));
  94078. +
  94079. + /* Wait for clock being stable. */
  94080. + gcmkONERROR(gckOS_Delay(Os, 1));
  94081. +
  94082. + /* Isolate the GPU. */
  94083. + 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)));
  94084. +
  94085. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  94086. + gcvCORE_VG,
  94087. + 0x00000,
  94088. + control));
  94089. +
  94090. + /* Set soft reset. */
  94091. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  94092. + gcvCORE_VG,
  94093. + 0x00000,
  94094. + ((((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)))));
  94095. +
  94096. + /* Wait for reset. */
  94097. + gcmkONERROR(gckOS_Delay(Os, 1));
  94098. +
  94099. + /* Reset soft reset bit. */
  94100. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  94101. + gcvCORE_VG,
  94102. + 0x00000,
  94103. + ((((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)))));
  94104. +
  94105. + /* Reset GPU isolation. */
  94106. + 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)));
  94107. +
  94108. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  94109. + gcvCORE_VG,
  94110. + 0x00000,
  94111. + control));
  94112. +
  94113. + /* Read idle register. */
  94114. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  94115. + gcvCORE_VG,
  94116. + 0x00004,
  94117. + &idle));
  94118. +
  94119. + 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)
  94120. + {
  94121. + continue;
  94122. + }
  94123. +
  94124. + /* Read reset register. */
  94125. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  94126. + gcvCORE_VG,
  94127. + 0x00000,
  94128. + &control));
  94129. +
  94130. + 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)
  94131. + || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
  94132. + )
  94133. + {
  94134. + continue;
  94135. + }
  94136. +
  94137. + /* GPU is idle. */
  94138. + break;
  94139. + }
  94140. +
  94141. + /* Success. */
  94142. + return gcvSTATUS_OK;
  94143. +
  94144. +OnError:
  94145. +
  94146. + /* Return the error. */
  94147. + return status;
  94148. +}
  94149. +
  94150. +
  94151. +static gceSTATUS
  94152. +_IdentifyHardware(
  94153. + IN gckOS Os,
  94154. + OUT gceCHIPMODEL * ChipModel,
  94155. + OUT gctUINT32 * ChipRevision,
  94156. + OUT gctUINT32 * ChipFeatures,
  94157. + OUT gctUINT32 * ChipMinorFeatures,
  94158. + OUT gctUINT32 * ChipMinorFeatures2
  94159. + )
  94160. +{
  94161. + gceSTATUS status;
  94162. + gctUINT32 chipIdentity;
  94163. +
  94164. + do
  94165. + {
  94166. + /* Read chip identity register. */
  94167. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG, 0x00018, &chipIdentity));
  94168. +
  94169. + /* Special case for older graphic cores. */
  94170. + 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))))))))
  94171. + {
  94172. + *ChipModel = gcv500;
  94173. + *ChipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) );
  94174. + }
  94175. +
  94176. + else
  94177. + {
  94178. + /* Read chip identity register. */
  94179. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG,
  94180. + 0x00020,
  94181. + (gctUINT32 *) ChipModel));
  94182. +
  94183. + /* Read CHIP_REV register. */
  94184. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG,
  94185. + 0x00024,
  94186. + ChipRevision));
  94187. + }
  94188. +
  94189. + /* Read chip feature register. */
  94190. + gcmkERR_BREAK(gckOS_ReadRegisterEx(
  94191. + Os, gcvCORE_VG, 0x0001C, ChipFeatures
  94192. + ));
  94193. +
  94194. + /* Read chip minor feature register. */
  94195. + gcmkERR_BREAK(gckOS_ReadRegisterEx(
  94196. + Os, gcvCORE_VG, 0x00034, ChipMinorFeatures
  94197. + ));
  94198. +
  94199. + /* Read chip minor feature register #2. */
  94200. + gcmkERR_BREAK(gckOS_ReadRegisterEx(
  94201. + Os, gcvCORE_VG, 0x00074, ChipMinorFeatures2
  94202. + ));
  94203. +
  94204. + gcmkTRACE(
  94205. + gcvLEVEL_VERBOSE,
  94206. + "ChipModel=0x%08X\n"
  94207. + "ChipRevision=0x%08X\n"
  94208. + "ChipFeatures=0x%08X\n"
  94209. + "ChipMinorFeatures=0x%08X\n"
  94210. + "ChipMinorFeatures2=0x%08X\n",
  94211. + *ChipModel,
  94212. + *ChipRevision,
  94213. + *ChipFeatures,
  94214. + *ChipMinorFeatures,
  94215. + *ChipMinorFeatures2
  94216. + );
  94217. +
  94218. + /* Success. */
  94219. + return gcvSTATUS_OK;
  94220. + }
  94221. + while (gcvFALSE);
  94222. +
  94223. + /* Return the status. */
  94224. + return status;
  94225. +}
  94226. +
  94227. +#if gcdPOWEROFF_TIMEOUT
  94228. +void
  94229. +_VGPowerTimerFunction(
  94230. + gctPOINTER Data
  94231. + )
  94232. +{
  94233. + gckVGHARDWARE hardware = (gckVGHARDWARE)Data;
  94234. + gcmkVERIFY_OK(
  94235. + gckVGHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
  94236. +}
  94237. +#endif
  94238. +
  94239. +/******************************************************************************\
  94240. +****************************** gckVGHARDWARE API code *****************************
  94241. +\******************************************************************************/
  94242. +
  94243. +/*******************************************************************************
  94244. +**
  94245. +** gckVGHARDWARE_Construct
  94246. +**
  94247. +** Construct a new gckVGHARDWARE object.
  94248. +**
  94249. +** INPUT:
  94250. +**
  94251. +** gckOS Os
  94252. +** Pointer to an initialized gckOS object.
  94253. +**
  94254. +** OUTPUT:
  94255. +**
  94256. +** gckVGHARDWARE * Hardware
  94257. +** Pointer to a variable that will hold the pointer to the gckVGHARDWARE
  94258. +** object.
  94259. +*/
  94260. +gceSTATUS
  94261. +gckVGHARDWARE_Construct(
  94262. + IN gckOS Os,
  94263. + OUT gckVGHARDWARE * Hardware
  94264. + )
  94265. +{
  94266. + gckVGHARDWARE hardware = gcvNULL;
  94267. + gceSTATUS status;
  94268. + gceCHIPMODEL chipModel;
  94269. + gctUINT32 chipRevision;
  94270. + gctUINT32 chipFeatures;
  94271. + gctUINT32 chipMinorFeatures;
  94272. + gctUINT32 chipMinorFeatures2;
  94273. +
  94274. + gcmkHEADER_ARG("Os=0x%x Hardware=0x%x ", Os, Hardware);
  94275. +
  94276. + /* Verify the arguments. */
  94277. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  94278. + gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
  94279. +
  94280. + do
  94281. + {
  94282. + gcmkERR_BREAK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvTRUE, gcvTRUE));
  94283. +
  94284. + status = _ResetGPU(Os);
  94285. +
  94286. + if (status != gcvSTATUS_OK)
  94287. + {
  94288. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  94289. + "_ResetGPU failed: status=%d\n", status);
  94290. + }
  94291. +
  94292. + /* Identify the hardware. */
  94293. + gcmkERR_BREAK(_IdentifyHardware(Os,
  94294. + &chipModel, &chipRevision,
  94295. + &chipFeatures, &chipMinorFeatures, &chipMinorFeatures2
  94296. + ));
  94297. +
  94298. + /* Allocate the gckVGHARDWARE object. */
  94299. + gcmkERR_BREAK(gckOS_Allocate(Os,
  94300. + gcmSIZEOF(struct _gckVGHARDWARE), (gctPOINTER *) &hardware
  94301. + ));
  94302. +
  94303. + /* Initialize the gckVGHARDWARE object. */
  94304. + hardware->object.type = gcvOBJ_HARDWARE;
  94305. + hardware->os = Os;
  94306. +
  94307. + /* Set chip identity. */
  94308. + hardware->chipModel = chipModel;
  94309. + hardware->chipRevision = chipRevision;
  94310. + hardware->chipFeatures = chipFeatures;
  94311. + hardware->chipMinorFeatures = chipMinorFeatures;
  94312. + hardware->chipMinorFeatures2 = chipMinorFeatures2;
  94313. +
  94314. + hardware->powerMutex = gcvNULL;
  94315. + hardware->chipPowerState = gcvPOWER_ON;
  94316. + hardware->chipPowerStateGlobal = gcvPOWER_ON;
  94317. + hardware->clockState = gcvTRUE;
  94318. + hardware->powerState = gcvTRUE;
  94319. +
  94320. +#if gcdPOWEROFF_TIMEOUT
  94321. + hardware->powerOffTime = 0;
  94322. + hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
  94323. +
  94324. + gcmkVERIFY_OK(gckOS_CreateTimer(Os,
  94325. + _VGPowerTimerFunction,
  94326. + (gctPOINTER)hardware,
  94327. + &hardware->powerOffTimer));
  94328. +#endif
  94329. +
  94330. + /* Determine whether FE 2.0 is present. */
  94331. + 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)))))));
  94332. +
  94333. + /* Determine whether VG 2.0 is present. */
  94334. + 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)))))));
  94335. +
  94336. + /* Determine whether VG 2.1 is present. */
  94337. + 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)))))));
  94338. +
  94339. + /* Set default event mask. */
  94340. + hardware->eventMask = 0xFFFFFFFF;
  94341. +
  94342. + gcmkERR_BREAK(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
  94343. +
  94344. + /* Set fast clear to auto. */
  94345. + gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(hardware, -1));
  94346. +
  94347. + gcmkERR_BREAK(gckOS_CreateMutex(Os, &hardware->powerMutex));
  94348. +
  94349. + /* Enable power management by default. */
  94350. + hardware->powerManagement = gcvTRUE;
  94351. +
  94352. + /* Return pointer to the gckVGHARDWARE object. */
  94353. + *Hardware = hardware;
  94354. +
  94355. + gcmkFOOTER_NO();
  94356. + /* Success. */
  94357. + return gcvSTATUS_OK;
  94358. + }
  94359. + while (gcvFALSE);
  94360. +
  94361. +#if gcdPOWEROFF_TIMEOUT
  94362. + if (hardware->powerOffTimer != gcvNULL)
  94363. + {
  94364. + gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
  94365. + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
  94366. + }
  94367. +#endif
  94368. +
  94369. + if (hardware->pageTableDirty != gcvNULL)
  94370. + {
  94371. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
  94372. + }
  94373. +
  94374. + if (hardware != gcvNULL)
  94375. + {
  94376. + gcmkVERIFY_OK(gckOS_Free(Os, hardware));
  94377. + }
  94378. +
  94379. + gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvFALSE, gcvFALSE));
  94380. +
  94381. + gcmkFOOTER();
  94382. + /* Return the status. */
  94383. + return status;
  94384. +}
  94385. +
  94386. +/*******************************************************************************
  94387. +**
  94388. +** gckVGHARDWARE_Destroy
  94389. +**
  94390. +** Destroy an gckVGHARDWARE object.
  94391. +**
  94392. +** INPUT:
  94393. +**
  94394. +** gckVGHARDWARE Hardware
  94395. +** Pointer to the gckVGHARDWARE object that needs to be destroyed.
  94396. +**
  94397. +** OUTPUT:
  94398. +**
  94399. +** Nothing.
  94400. +*/
  94401. +gceSTATUS
  94402. +gckVGHARDWARE_Destroy(
  94403. + IN gckVGHARDWARE Hardware
  94404. + )
  94405. +{
  94406. + gceSTATUS status;
  94407. + gcmkHEADER_ARG("Hardware=0x%x ", Hardware);
  94408. + /* Verify the arguments. */
  94409. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94410. +
  94411. + /* Mark the object as unknown. */
  94412. + Hardware->object.type = gcvOBJ_UNKNOWN;
  94413. +
  94414. + if (Hardware->powerMutex != gcvNULL)
  94415. + {
  94416. + gcmkVERIFY_OK(gckOS_DeleteMutex(
  94417. + Hardware->os, Hardware->powerMutex));
  94418. + }
  94419. +
  94420. +#if gcdPOWEROFF_TIMEOUT
  94421. + gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
  94422. + gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
  94423. +#endif
  94424. +
  94425. + if (Hardware->pageTableDirty != gcvNULL)
  94426. + {
  94427. + gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
  94428. + }
  94429. +
  94430. + /* Free the object. */
  94431. + status = gckOS_Free(Hardware->os, Hardware);
  94432. + gcmkFOOTER();
  94433. + return status;
  94434. +}
  94435. +
  94436. +/*******************************************************************************
  94437. +**
  94438. +** gckVGHARDWARE_QueryMemory
  94439. +**
  94440. +** Query the amount of memory available on the hardware.
  94441. +**
  94442. +** INPUT:
  94443. +**
  94444. +** gckVGHARDWARE Hardware
  94445. +** Pointer to the gckVGHARDWARE object.
  94446. +**
  94447. +** OUTPUT:
  94448. +**
  94449. +** gctSIZE_T * InternalSize
  94450. +** Pointer to a variable that will hold the size of the internal video
  94451. +** memory in bytes. If 'InternalSize' is gcvNULL, no information of the
  94452. +** internal memory will be returned.
  94453. +**
  94454. +** gctUINT32 * InternalBaseAddress
  94455. +** Pointer to a variable that will hold the hardware's base address for
  94456. +** the internal video memory. This pointer cannot be gcvNULL if
  94457. +** 'InternalSize' is also non-gcvNULL.
  94458. +**
  94459. +** gctUINT32 * InternalAlignment
  94460. +** Pointer to a variable that will hold the hardware's base address for
  94461. +** the internal video memory. This pointer cannot be gcvNULL if
  94462. +** 'InternalSize' is also non-gcvNULL.
  94463. +**
  94464. +** gctSIZE_T * ExternalSize
  94465. +** Pointer to a variable that will hold the size of the external video
  94466. +** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the
  94467. +** external memory will be returned.
  94468. +**
  94469. +** gctUINT32 * ExternalBaseAddress
  94470. +** Pointer to a variable that will hold the hardware's base address for
  94471. +** the external video memory. This pointer cannot be gcvNULL if
  94472. +** 'ExternalSize' is also non-gcvNULL.
  94473. +**
  94474. +** gctUINT32 * ExternalAlignment
  94475. +** Pointer to a variable that will hold the hardware's base address for
  94476. +** the external video memory. This pointer cannot be gcvNULL if
  94477. +** 'ExternalSize' is also non-gcvNULL.
  94478. +**
  94479. +** gctUINT32 * HorizontalTileSize
  94480. +** Number of horizontal pixels per tile. If 'HorizontalTileSize' is
  94481. +** gcvNULL, no horizontal pixel per tile will be returned.
  94482. +**
  94483. +** gctUINT32 * VerticalTileSize
  94484. +** Number of vertical pixels per tile. If 'VerticalTileSize' is
  94485. +** gcvNULL, no vertical pixel per tile will be returned.
  94486. +*/
  94487. +gceSTATUS
  94488. +gckVGHARDWARE_QueryMemory(
  94489. + IN gckVGHARDWARE Hardware,
  94490. + OUT gctSIZE_T * InternalSize,
  94491. + OUT gctUINT32 * InternalBaseAddress,
  94492. + OUT gctUINT32 * InternalAlignment,
  94493. + OUT gctSIZE_T * ExternalSize,
  94494. + OUT gctUINT32 * ExternalBaseAddress,
  94495. + OUT gctUINT32 * ExternalAlignment,
  94496. + OUT gctUINT32 * HorizontalTileSize,
  94497. + OUT gctUINT32 * VerticalTileSize
  94498. + )
  94499. +{
  94500. + gcmkHEADER_ARG("Hardware=0x%x InternalSize=0x%x InternalBaseAddress=0x%x InternalAlignment=0x%x"
  94501. + "ExternalSize=0x%x ExternalBaseAddress=0x%x ExternalAlignment=0x%x HorizontalTileSize=0x%x VerticalTileSize=0x%x",
  94502. + Hardware, InternalSize, InternalBaseAddress, InternalAlignment,
  94503. + ExternalSize, ExternalBaseAddress, ExternalAlignment, HorizontalTileSize, VerticalTileSize);
  94504. +
  94505. + /* Verify the arguments. */
  94506. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94507. +
  94508. + if (InternalSize != gcvNULL)
  94509. + {
  94510. + /* No internal memory. */
  94511. + *InternalSize = 0;
  94512. + }
  94513. +
  94514. + if (ExternalSize != gcvNULL)
  94515. + {
  94516. + /* No external memory. */
  94517. + *ExternalSize = 0;
  94518. + }
  94519. +
  94520. + if (HorizontalTileSize != gcvNULL)
  94521. + {
  94522. + /* 4x4 tiles. */
  94523. + *HorizontalTileSize = 4;
  94524. + }
  94525. +
  94526. + if (VerticalTileSize != gcvNULL)
  94527. + {
  94528. + /* 4x4 tiles. */
  94529. + *VerticalTileSize = 4;
  94530. + }
  94531. +
  94532. + gcmkFOOTER_NO();
  94533. + /* Success. */
  94534. + return gcvSTATUS_OK;
  94535. +}
  94536. +
  94537. +/*******************************************************************************
  94538. +**
  94539. +** gckVGHARDWARE_QueryChipIdentity
  94540. +**
  94541. +** Query the identity of the hardware.
  94542. +**
  94543. +** INPUT:
  94544. +**
  94545. +** gckVGHARDWARE Hardware
  94546. +** Pointer to the gckVGHARDWARE object.
  94547. +**
  94548. +** OUTPUT:
  94549. +**
  94550. +** gceCHIPMODEL * ChipModel
  94551. +** If 'ChipModel' is not gcvNULL, the variable it points to will
  94552. +** receive the model of the chip.
  94553. +**
  94554. +** gctUINT32 * ChipRevision
  94555. +** If 'ChipRevision' is not gcvNULL, the variable it points to will
  94556. +** receive the revision of the chip.
  94557. +**
  94558. +** gctUINT32 * ChipFeatures
  94559. +** If 'ChipFeatures' is not gcvNULL, the variable it points to will
  94560. +** receive the feature set of the chip.
  94561. +**
  94562. +** gctUINT32 * ChipMinorFeatures
  94563. +** If 'ChipMinorFeatures' is not gcvNULL, the variable it points to
  94564. +** will receive the minor feature set of the chip.
  94565. +**
  94566. +** gctUINT32 * ChipMinorFeatures2
  94567. +** If 'ChipMinorFeatures2' is not gcvNULL, the variable it points to
  94568. +** will receive the minor feature set of the chip.
  94569. +**
  94570. +*/
  94571. +gceSTATUS
  94572. +gckVGHARDWARE_QueryChipIdentity(
  94573. + IN gckVGHARDWARE Hardware,
  94574. + OUT gceCHIPMODEL * ChipModel,
  94575. + OUT gctUINT32 * ChipRevision,
  94576. + OUT gctUINT32* ChipFeatures,
  94577. + OUT gctUINT32* ChipMinorFeatures,
  94578. + OUT gctUINT32* ChipMinorFeatures2
  94579. + )
  94580. +{
  94581. + gcmkHEADER_ARG("Hardware=0x%x ChipModel=0x%x ChipRevision=0x%x ChipFeatures = 0x%x ChipMinorFeatures = 0x%x ChipMinorFeatures2 = 0x%x",
  94582. + Hardware, ChipModel, ChipRevision, ChipFeatures, ChipMinorFeatures, ChipMinorFeatures2);
  94583. +
  94584. + /* Verify the arguments. */
  94585. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94586. +
  94587. + /* Return chip model. */
  94588. + if (ChipModel != gcvNULL)
  94589. + {
  94590. + *ChipModel = Hardware->chipModel;
  94591. + }
  94592. +
  94593. + /* Return revision number. */
  94594. + if (ChipRevision != gcvNULL)
  94595. + {
  94596. + *ChipRevision = Hardware->chipRevision;
  94597. + }
  94598. +
  94599. + /* Return feature set. */
  94600. + if (ChipFeatures != gcvNULL)
  94601. + {
  94602. + gctUINT32 features = Hardware->chipFeatures;
  94603. +
  94604. + if ((((((gctUINT32) (features)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  94605. + {
  94606. + 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)));
  94607. + }
  94608. +
  94609. + /* Mark 2D pipe as available for GC500.0 since it did not have this *\
  94610. + \* bit. */
  94611. + if ((Hardware->chipModel == gcv500)
  94612. + && (Hardware->chipRevision == 0)
  94613. + )
  94614. + {
  94615. + 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)));
  94616. + }
  94617. +
  94618. + /* Mark 2D pipe as available for GC300 since it did not have this *\
  94619. + \* bit. */
  94620. + if (Hardware->chipModel == gcv300)
  94621. + {
  94622. + 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)));
  94623. + }
  94624. +
  94625. + *ChipFeatures = features;
  94626. + }
  94627. +
  94628. + /* Return minor feature set. */
  94629. + if (ChipMinorFeatures != gcvNULL)
  94630. + {
  94631. + *ChipMinorFeatures = Hardware->chipMinorFeatures;
  94632. + }
  94633. +
  94634. + /* Return minor feature set #2. */
  94635. + if (ChipMinorFeatures2 != gcvNULL)
  94636. + {
  94637. + *ChipMinorFeatures2 = Hardware->chipMinorFeatures2;
  94638. + }
  94639. +
  94640. + gcmkFOOTER_NO();
  94641. + /* Success. */
  94642. + return gcvSTATUS_OK;
  94643. +}
  94644. +
  94645. +/*******************************************************************************
  94646. +**
  94647. +** gckVGHARDWARE_ConvertFormat
  94648. +**
  94649. +** Convert an API format to hardware parameters.
  94650. +**
  94651. +** INPUT:
  94652. +**
  94653. +** gckVGHARDWARE Hardware
  94654. +** Pointer to the gckVGHARDWARE object.
  94655. +**
  94656. +** gceSURF_FORMAT Format
  94657. +** API format to convert.
  94658. +**
  94659. +** OUTPUT:
  94660. +**
  94661. +** gctUINT32 * BitsPerPixel
  94662. +** Pointer to a variable that will hold the number of bits per pixel.
  94663. +**
  94664. +** gctUINT32 * BytesPerTile
  94665. +** Pointer to a variable that will hold the number of bytes per tile.
  94666. +*/
  94667. +gceSTATUS
  94668. +gckVGHARDWARE_ConvertFormat(
  94669. + IN gckVGHARDWARE Hardware,
  94670. + IN gceSURF_FORMAT Format,
  94671. + OUT gctUINT32 * BitsPerPixel,
  94672. + OUT gctUINT32 * BytesPerTile
  94673. + )
  94674. +{
  94675. + gctUINT32 bitsPerPixel;
  94676. + gctUINT32 bytesPerTile;
  94677. +
  94678. + gcmkHEADER_ARG("Hardware=0x%x Format=0x%x BitsPerPixel=0x%x BytesPerTile = 0x%x",
  94679. + Hardware, Format, BitsPerPixel, BytesPerTile);
  94680. +
  94681. + /* Verify the arguments. */
  94682. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94683. +
  94684. + /* Dispatch on format. */
  94685. + switch (Format)
  94686. + {
  94687. + case gcvSURF_A1:
  94688. + case gcvSURF_L1:
  94689. + /* 1-bpp format. */
  94690. + bitsPerPixel = 1;
  94691. + bytesPerTile = (1 * 4 * 4) / 8;
  94692. + break;
  94693. +
  94694. + case gcvSURF_A4:
  94695. + /* 4-bpp format. */
  94696. + bitsPerPixel = 4;
  94697. + bytesPerTile = (4 * 4 * 4) / 8;
  94698. + break;
  94699. +
  94700. + case gcvSURF_INDEX8:
  94701. + case gcvSURF_A8:
  94702. + case gcvSURF_L8:
  94703. + /* 8-bpp format. */
  94704. + bitsPerPixel = 8;
  94705. + bytesPerTile = (8 * 4 * 4) / 8;
  94706. + break;
  94707. +
  94708. + case gcvSURF_YV12:
  94709. + /* 12-bpp planar YUV formats. */
  94710. + bitsPerPixel = 12;
  94711. + bytesPerTile = (12 * 4 * 4) / 8;
  94712. + break;
  94713. +
  94714. + case gcvSURF_NV12:
  94715. + /* 12-bpp planar YUV formats. */
  94716. + bitsPerPixel = 12;
  94717. + bytesPerTile = (12 * 4 * 4) / 8;
  94718. + break;
  94719. +
  94720. + /* 4444 variations. */
  94721. + case gcvSURF_X4R4G4B4:
  94722. + case gcvSURF_A4R4G4B4:
  94723. + case gcvSURF_R4G4B4X4:
  94724. + case gcvSURF_R4G4B4A4:
  94725. + case gcvSURF_B4G4R4X4:
  94726. + case gcvSURF_B4G4R4A4:
  94727. + case gcvSURF_X4B4G4R4:
  94728. + case gcvSURF_A4B4G4R4:
  94729. +
  94730. + /* 1555 variations. */
  94731. + case gcvSURF_X1R5G5B5:
  94732. + case gcvSURF_A1R5G5B5:
  94733. + case gcvSURF_R5G5B5X1:
  94734. + case gcvSURF_R5G5B5A1:
  94735. + case gcvSURF_X1B5G5R5:
  94736. + case gcvSURF_A1B5G5R5:
  94737. + case gcvSURF_B5G5R5X1:
  94738. + case gcvSURF_B5G5R5A1:
  94739. +
  94740. + /* 565 variations. */
  94741. + case gcvSURF_R5G6B5:
  94742. + case gcvSURF_B5G6R5:
  94743. +
  94744. + case gcvSURF_A8L8:
  94745. + case gcvSURF_YUY2:
  94746. + case gcvSURF_UYVY:
  94747. + case gcvSURF_D16:
  94748. + /* 16-bpp format. */
  94749. + bitsPerPixel = 16;
  94750. + bytesPerTile = (16 * 4 * 4) / 8;
  94751. + break;
  94752. +
  94753. + case gcvSURF_X8R8G8B8:
  94754. + case gcvSURF_A8R8G8B8:
  94755. + case gcvSURF_X8B8G8R8:
  94756. + case gcvSURF_A8B8G8R8:
  94757. + case gcvSURF_R8G8B8X8:
  94758. + case gcvSURF_R8G8B8A8:
  94759. + case gcvSURF_B8G8R8X8:
  94760. + case gcvSURF_B8G8R8A8:
  94761. + case gcvSURF_D32:
  94762. + /* 32-bpp format. */
  94763. + bitsPerPixel = 32;
  94764. + bytesPerTile = (32 * 4 * 4) / 8;
  94765. + break;
  94766. +
  94767. + case gcvSURF_D24S8:
  94768. + /* 24-bpp format. */
  94769. + bitsPerPixel = 32;
  94770. + bytesPerTile = (32 * 4 * 4) / 8;
  94771. + break;
  94772. +
  94773. + case gcvSURF_DXT1:
  94774. + case gcvSURF_ETC1:
  94775. + bitsPerPixel = 4;
  94776. + bytesPerTile = (4 * 4 * 4) / 8;
  94777. + break;
  94778. +
  94779. + case gcvSURF_DXT2:
  94780. + case gcvSURF_DXT3:
  94781. + case gcvSURF_DXT4:
  94782. + case gcvSURF_DXT5:
  94783. + bitsPerPixel = 8;
  94784. + bytesPerTile = (8 * 4 * 4) / 8;
  94785. + break;
  94786. +
  94787. + default:
  94788. + /* Invalid format. */
  94789. + gcmkFOOTER_NO();
  94790. + return gcvSTATUS_INVALID_ARGUMENT;
  94791. + }
  94792. +
  94793. + /* Set the result. */
  94794. + if (BitsPerPixel != gcvNULL)
  94795. + {
  94796. + * BitsPerPixel = bitsPerPixel;
  94797. + }
  94798. +
  94799. + if (BytesPerTile != gcvNULL)
  94800. + {
  94801. + * BytesPerTile = bytesPerTile;
  94802. + }
  94803. +
  94804. + gcmkFOOTER_NO();
  94805. + /* Success. */
  94806. + return gcvSTATUS_OK;
  94807. +}
  94808. +
  94809. +/*******************************************************************************
  94810. +**
  94811. +** gckVGHARDWARE_SplitMemory
  94812. +**
  94813. +** Split a hardware specific memory address into a pool and offset.
  94814. +**
  94815. +** INPUT:
  94816. +**
  94817. +** gckVGHARDWARE Hardware
  94818. +** Pointer to the gckVGHARDWARE object.
  94819. +**
  94820. +** gctUINT32 Address
  94821. +** Address in hardware specific format.
  94822. +**
  94823. +** OUTPUT:
  94824. +**
  94825. +** gcePOOL * Pool
  94826. +** Pointer to a variable that will hold the pool type for the address.
  94827. +**
  94828. +** gctUINT32 * Offset
  94829. +** Pointer to a variable that will hold the offset for the address.
  94830. +*/
  94831. +gceSTATUS
  94832. +gckVGHARDWARE_SplitMemory(
  94833. + IN gckVGHARDWARE Hardware,
  94834. + IN gctUINT32 Address,
  94835. + OUT gcePOOL * Pool,
  94836. + OUT gctUINT32 * Offset
  94837. + )
  94838. +{
  94839. + gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Pool=0x%x Offset = 0x%x",
  94840. + Hardware, Address, Pool, Offset);
  94841. + /* Verify the arguments. */
  94842. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94843. + gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
  94844. + gcmkVERIFY_ARGUMENT(Offset != gcvNULL);
  94845. +
  94846. + /* Dispatch on memory type. */
  94847. + switch ((((((gctUINT32) (Address)) >> (0 ? 1:0)) & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1)))))) ))
  94848. + {
  94849. + case 0x0:
  94850. + /* System memory. */
  94851. + *Pool = gcvPOOL_SYSTEM;
  94852. + break;
  94853. +
  94854. + case 0x2:
  94855. + /* Virtual memory. */
  94856. + *Pool = gcvPOOL_VIRTUAL;
  94857. + break;
  94858. +
  94859. + default:
  94860. + /* Invalid memory type. */
  94861. + gcmkFOOTER_NO();
  94862. + return gcvSTATUS_INVALID_ARGUMENT;
  94863. + }
  94864. +
  94865. + /* Return offset of address. */
  94866. + *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)));
  94867. +
  94868. + gcmkFOOTER_NO();
  94869. + /* Success. */
  94870. + return gcvSTATUS_OK;
  94871. +}
  94872. +
  94873. +/*******************************************************************************
  94874. +**
  94875. +** gckVGHARDWARE_Execute
  94876. +**
  94877. +** Kickstart the hardware's command processor with an initialized command
  94878. +** buffer.
  94879. +**
  94880. +** INPUT:
  94881. +**
  94882. +** gckVGHARDWARE Hardware
  94883. +** Pointer to the gckVGHARDWARE object.
  94884. +**
  94885. +** gctUINT32 Address
  94886. +** Address of the command buffer.
  94887. +**
  94888. +** gctSIZE_T Count
  94889. +** Number of command-sized data units to be executed.
  94890. +**
  94891. +** OUTPUT:
  94892. +**
  94893. +** Nothing.
  94894. +*/
  94895. +gceSTATUS
  94896. +gckVGHARDWARE_Execute(
  94897. + IN gckVGHARDWARE Hardware,
  94898. + IN gctUINT32 Address,
  94899. + IN gctSIZE_T Count
  94900. + )
  94901. +{
  94902. + gceSTATUS status;
  94903. +
  94904. + gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Count=0x%x",
  94905. + Hardware, Address, Count);
  94906. +
  94907. + /* Verify the arguments. */
  94908. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  94909. +
  94910. + do
  94911. + {
  94912. + /* Enable all events. */
  94913. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  94914. + Hardware->os,
  94915. + gcvCORE_VG,
  94916. + 0x00014,
  94917. + Hardware->eventMask
  94918. + ));
  94919. +
  94920. + if (Hardware->fe20)
  94921. + {
  94922. + /* Write address register. */
  94923. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  94924. + Hardware->os,
  94925. + gcvCORE_VG,
  94926. + 0x00500,
  94927. + gcmkFIXADDRESS(Address)
  94928. + ));
  94929. +
  94930. + /* Write control register. */
  94931. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  94932. + Hardware->os,
  94933. + gcvCORE_VG,
  94934. + 0x00504,
  94935. + Count
  94936. + ));
  94937. + }
  94938. + else
  94939. + {
  94940. + /* Write address register. */
  94941. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  94942. + Hardware->os,
  94943. + gcvCORE_VG,
  94944. + 0x00654,
  94945. + gcmkFIXADDRESS(Address)
  94946. + ));
  94947. +
  94948. + /* Write control register. */
  94949. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  94950. + Hardware->os,
  94951. + gcvCORE_VG,
  94952. + 0x00658,
  94953. + ((((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))) |
  94954. + ((((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)))
  94955. + ));
  94956. + }
  94957. +
  94958. + /* Success. */
  94959. + gcmkFOOTER();
  94960. + return gcvSTATUS_OK;
  94961. + }
  94962. + while (gcvFALSE);
  94963. +
  94964. +
  94965. + gcmkFOOTER();
  94966. + /* Return the status. */
  94967. + return status;
  94968. +}
  94969. +
  94970. +/*******************************************************************************
  94971. +**
  94972. +** gckVGHARDWARE_AlignToTile
  94973. +**
  94974. +** Align the specified width and height to tile boundaries.
  94975. +**
  94976. +** INPUT:
  94977. +**
  94978. +** gckVGHARDWARE Hardware
  94979. +** Pointer to an gckVGHARDWARE object.
  94980. +**
  94981. +** gceSURF_TYPE Type
  94982. +** Type of alignment.
  94983. +**
  94984. +** gctUINT32 * Width
  94985. +** Pointer to the width to be aligned. If 'Width' is gcvNULL, no width
  94986. +** will be aligned.
  94987. +**
  94988. +** gctUINT32 * Height
  94989. +** Pointer to the height to be aligned. If 'Height' is gcvNULL, no height
  94990. +** will be aligned.
  94991. +**
  94992. +** OUTPUT:
  94993. +**
  94994. +** gctUINT32 * Width
  94995. +** Pointer to a variable that will receive the aligned width.
  94996. +**
  94997. +** gctUINT32 * Height
  94998. +** Pointer to a variable that will receive the aligned height.
  94999. +*/
  95000. +gceSTATUS
  95001. +gckVGHARDWARE_AlignToTile(
  95002. + IN gckVGHARDWARE Hardware,
  95003. + IN gceSURF_TYPE Type,
  95004. + IN OUT gctUINT32 * Width,
  95005. + IN OUT gctUINT32 * Height
  95006. + )
  95007. +{
  95008. + gcmkHEADER_ARG("Hardware=0x%x Type=0x%x Width=0x%x Height=0x%x",
  95009. + Hardware, Type, Width, Height);
  95010. + /* Verify the arguments. */
  95011. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95012. +
  95013. + if (Width != gcvNULL)
  95014. + {
  95015. + /* Align the width. */
  95016. + *Width = gcmALIGN(*Width, (Type == gcvSURF_TEXTURE) ? 4 : 16);
  95017. + }
  95018. +
  95019. + if (Height != gcvNULL)
  95020. + {
  95021. + /* Special case for VG images. */
  95022. + if ((*Height == 0) && (Type == gcvSURF_IMAGE))
  95023. + {
  95024. + *Height = 4;
  95025. + }
  95026. + else
  95027. + {
  95028. + /* Align the height. */
  95029. + *Height = gcmALIGN(*Height, 4);
  95030. + }
  95031. + }
  95032. +
  95033. + gcmkFOOTER_NO();
  95034. + /* Success. */
  95035. + return gcvSTATUS_OK;
  95036. +}
  95037. +
  95038. +/*******************************************************************************
  95039. +**
  95040. +** gckVGHARDWARE_ConvertLogical
  95041. +**
  95042. +** Convert a logical system address into a hardware specific address.
  95043. +**
  95044. +** INPUT:
  95045. +**
  95046. +** gckVGHARDWARE Hardware
  95047. +** Pointer to an gckVGHARDWARE object.
  95048. +**
  95049. +** gctPOINTER Logical
  95050. +** Logical address to convert.
  95051. +**
  95052. +** gctUINT32* Address
  95053. +** Return hardware specific address.
  95054. +**
  95055. +** OUTPUT:
  95056. +**
  95057. +** Nothing.
  95058. +*/
  95059. +gceSTATUS
  95060. +gckVGHARDWARE_ConvertLogical(
  95061. + IN gckVGHARDWARE Hardware,
  95062. + IN gctPOINTER Logical,
  95063. + OUT gctUINT32 * Address
  95064. + )
  95065. +{
  95066. + gctUINT32 address;
  95067. + gceSTATUS status;
  95068. +
  95069. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Address=0x%x",
  95070. + Hardware, Logical, Address);
  95071. +
  95072. + /* Verify the arguments. */
  95073. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95074. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  95075. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  95076. +
  95077. + do
  95078. + {
  95079. + /* Convert logical address into a physical address. */
  95080. + gcmkERR_BREAK(gckOS_GetPhysicalAddress(
  95081. + Hardware->os, Logical, &address
  95082. + ));
  95083. +
  95084. + /* Return hardware specific address. */
  95085. + *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)));
  95086. +
  95087. + /* Success. */
  95088. + gcmkFOOTER();
  95089. + return gcvSTATUS_OK;
  95090. + }
  95091. + while (gcvFALSE);
  95092. +
  95093. + gcmkFOOTER();
  95094. + /* Return the status. */
  95095. + return status;
  95096. +}
  95097. +
  95098. +/*******************************************************************************
  95099. +**
  95100. +** gckVGHARDWARE_QuerySystemMemory
  95101. +**
  95102. +** Query the command buffer alignment and number of reserved bytes.
  95103. +**
  95104. +** INPUT:
  95105. +**
  95106. +** gckVGHARDWARE Harwdare
  95107. +** Pointer to an gckVGHARDWARE object.
  95108. +**
  95109. +** OUTPUT:
  95110. +**
  95111. +** gctSIZE_T * SystemSize
  95112. +** Pointer to a variable that receives the maximum size of the system
  95113. +** memory.
  95114. +**
  95115. +** gctUINT32 * SystemBaseAddress
  95116. +** Poinetr to a variable that receives the base address for system
  95117. +** memory.
  95118. +*/
  95119. +gceSTATUS gckVGHARDWARE_QuerySystemMemory(
  95120. + IN gckVGHARDWARE Hardware,
  95121. + OUT gctSIZE_T * SystemSize,
  95122. + OUT gctUINT32 * SystemBaseAddress
  95123. + )
  95124. +{
  95125. + gcmkHEADER_ARG("Hardware=0x%x SystemSize=0x%x SystemBaseAddress=0x%x",
  95126. + Hardware, SystemSize, SystemBaseAddress);
  95127. +
  95128. + /* Verify the arguments. */
  95129. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95130. +
  95131. + if (SystemSize != gcvNULL)
  95132. + {
  95133. + /* Maximum system memory can be 2GB. */
  95134. + *SystemSize = (gctSIZE_T)(1 << 31);
  95135. + }
  95136. +
  95137. + if (SystemBaseAddress != gcvNULL)
  95138. + {
  95139. + /* Set system memory base address. */
  95140. + *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)));
  95141. + }
  95142. +
  95143. + gcmkFOOTER_NO();
  95144. + /* Success. */
  95145. + return gcvSTATUS_OK;
  95146. +}
  95147. +
  95148. +/*******************************************************************************
  95149. +**
  95150. +** gckVGHARDWARE_SetMMU
  95151. +**
  95152. +** Set the page table base address.
  95153. +**
  95154. +** INPUT:
  95155. +**
  95156. +** gckVGHARDWARE Harwdare
  95157. +** Pointer to an gckVGHARDWARE object.
  95158. +**
  95159. +** gctPOINTER Logical
  95160. +** Logical address of the page table.
  95161. +**
  95162. +** OUTPUT:
  95163. +**
  95164. +** Nothing.
  95165. +*/
  95166. +gceSTATUS gckVGHARDWARE_SetMMU(
  95167. + IN gckVGHARDWARE Hardware,
  95168. + IN gctPOINTER Logical
  95169. + )
  95170. +{
  95171. + gceSTATUS status;
  95172. + gctUINT32 address = 0;
  95173. +
  95174. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x",
  95175. + Hardware, Logical);
  95176. +
  95177. + /* Verify the arguments. */
  95178. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95179. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  95180. +
  95181. + do
  95182. + {
  95183. + /* Convert the logical address into an hardware address. */
  95184. + gcmkERR_BREAK(gckVGHARDWARE_ConvertLogical(Hardware, Logical, &address) );
  95185. +
  95186. + /* Write the AQMemoryFePageTable register. */
  95187. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95188. + 0x00400,
  95189. + gcmkFIXADDRESS(address)) );
  95190. +
  95191. + /* Write the AQMemoryTxPageTable register. */
  95192. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95193. + 0x00404,
  95194. + gcmkFIXADDRESS(address)) );
  95195. +
  95196. + /* Write the AQMemoryPePageTable register. */
  95197. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95198. + 0x00408,
  95199. + gcmkFIXADDRESS(address)) );
  95200. +
  95201. + /* Write the AQMemoryPezPageTable register. */
  95202. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95203. + 0x0040C,
  95204. + gcmkFIXADDRESS(address)) );
  95205. +
  95206. + /* Write the AQMemoryRaPageTable register. */
  95207. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95208. + 0x00410,
  95209. + gcmkFIXADDRESS(address)) );
  95210. + }
  95211. + while (gcvFALSE);
  95212. +
  95213. + gcmkFOOTER();
  95214. + /* Return the status. */
  95215. + return status;
  95216. +}
  95217. +
  95218. +/*******************************************************************************
  95219. +**
  95220. +** gckVGHARDWARE_FlushMMU
  95221. +**
  95222. +** Flush the page table.
  95223. +**
  95224. +** INPUT:
  95225. +**
  95226. +** gckVGHARDWARE Harwdare
  95227. +** Pointer to an gckVGHARDWARE object.
  95228. +**
  95229. +** OUTPUT:
  95230. +**
  95231. +** Nothing.
  95232. +*/
  95233. +gceSTATUS gckVGHARDWARE_FlushMMU(
  95234. + IN gckVGHARDWARE Hardware
  95235. + )
  95236. +{
  95237. + gceSTATUS status;
  95238. + gckVGCOMMAND command;
  95239. +
  95240. + gcmkHEADER_ARG("Hardware=0x%x ", Hardware);
  95241. + /* Verify the arguments. */
  95242. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95243. +
  95244. + do
  95245. + {
  95246. + gcsCMDBUFFER_PTR commandBuffer;
  95247. + gctUINT32_PTR buffer;
  95248. +
  95249. + /* Create a shortcut to the command buffer object. */
  95250. + command = Hardware->kernel->command;
  95251. +
  95252. + /* Allocate command buffer space. */
  95253. + gcmkERR_BREAK(gckVGCOMMAND_Allocate(
  95254. + command, 8, &commandBuffer, (gctPOINTER *) &buffer
  95255. + ));
  95256. +
  95257. + buffer[0]
  95258. + = ((((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)))
  95259. + | ((((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)))
  95260. + | ((((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)));
  95261. +
  95262. + buffer[1]
  95263. + = ((((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)))
  95264. + | ((((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)))
  95265. + | ((((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)))
  95266. + | ((((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)))
  95267. + | ((((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)));
  95268. + }
  95269. + while(gcvFALSE);
  95270. +
  95271. + gcmkFOOTER();
  95272. + /* Return the status. */
  95273. + return status;
  95274. +}
  95275. +
  95276. +/*******************************************************************************
  95277. +**
  95278. +** gckVGHARDWARE_BuildVirtualAddress
  95279. +**
  95280. +** Build a virtual address.
  95281. +**
  95282. +** INPUT:
  95283. +**
  95284. +** gckVGHARDWARE Harwdare
  95285. +** Pointer to an gckVGHARDWARE object.
  95286. +**
  95287. +** gctUINT32 Index
  95288. +** Index into page table.
  95289. +**
  95290. +** gctUINT32 Offset
  95291. +** Offset into page.
  95292. +**
  95293. +** OUTPUT:
  95294. +**
  95295. +** gctUINT32 * Address
  95296. +** Pointer to a variable receiving te hardware address.
  95297. +*/
  95298. +gceSTATUS gckVGHARDWARE_BuildVirtualAddress(
  95299. + IN gckVGHARDWARE Hardware,
  95300. + IN gctUINT32 Index,
  95301. + IN gctUINT32 Offset,
  95302. + OUT gctUINT32 * Address
  95303. + )
  95304. +{
  95305. + gctUINT32 address;
  95306. +
  95307. + gcmkHEADER_ARG("Hardware=0x%x Index=0x%x Offset=0x%x Address=0x%x",
  95308. + Hardware, Index, Offset, Address);
  95309. +
  95310. + /* Verify the arguments. */
  95311. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95312. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  95313. +
  95314. + /* Build virtual address. */
  95315. + address = (Index << 12) | Offset;
  95316. +
  95317. + /* Set virtual type. */
  95318. + 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)));
  95319. +
  95320. + /* Set the result. */
  95321. + *Address = address;
  95322. +
  95323. + gcmkFOOTER_NO();
  95324. + /* Success. */
  95325. + return gcvSTATUS_OK;
  95326. +}
  95327. +
  95328. +gceSTATUS
  95329. +gckVGHARDWARE_GetIdle(
  95330. + IN gckVGHARDWARE Hardware,
  95331. + OUT gctUINT32 * Data
  95332. + )
  95333. +{
  95334. + gceSTATUS status;
  95335. + gcmkHEADER_ARG("Hardware=0x%x Data=0x%x", Hardware, Data);
  95336. + /* Verify the arguments. */
  95337. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95338. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  95339. +
  95340. + /* Read register and return. */
  95341. + status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, 0x00004, Data);
  95342. + gcmkFOOTER();
  95343. + return status;
  95344. +}
  95345. +
  95346. +gceSTATUS
  95347. +gckVGHARDWARE_SetFastClear(
  95348. + IN gckVGHARDWARE Hardware,
  95349. + IN gctINT Enable
  95350. + )
  95351. +{
  95352. + gctUINT32 debug;
  95353. + gceSTATUS status;
  95354. +
  95355. + 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)))))) ))
  95356. + {
  95357. + return gcvSTATUS_OK;
  95358. + }
  95359. +
  95360. + do
  95361. + {
  95362. + if (Enable == -1)
  95363. + {
  95364. + Enable = (Hardware->chipModel > gcv500) ||
  95365. + ((Hardware->chipModel == gcv500) && (Hardware->chipRevision >= 3));
  95366. + }
  95367. +
  95368. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG,
  95369. + 0x00414,
  95370. + &debug));
  95371. +
  95372. + 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)));
  95373. +
  95374. +#ifdef AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION
  95375. + 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)));
  95376. +#endif
  95377. +
  95378. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  95379. + 0x00414,
  95380. + debug));
  95381. +
  95382. + Hardware->allowFastClear = Enable;
  95383. +
  95384. + status = gcvFALSE;
  95385. + }
  95386. + while (gcvFALSE);
  95387. +
  95388. + return status;
  95389. +}
  95390. +
  95391. +gceSTATUS
  95392. +gckVGHARDWARE_ReadInterrupt(
  95393. + IN gckVGHARDWARE Hardware,
  95394. + OUT gctUINT32_PTR IDs
  95395. + )
  95396. +{
  95397. + gceSTATUS status;
  95398. + gcmkHEADER_ARG("Hardware=0x%x IDs=0x%x", Hardware, IDs);
  95399. +
  95400. + /* Verify the arguments. */
  95401. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95402. + gcmkVERIFY_ARGUMENT(IDs != gcvNULL);
  95403. +
  95404. + /* Read AQIntrAcknowledge register. */
  95405. + status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG,
  95406. + 0x00010,
  95407. + IDs);
  95408. + gcmkFOOTER();
  95409. + return status;
  95410. +}
  95411. +
  95412. +static gceSTATUS _CommandStall(
  95413. + gckVGHARDWARE Hardware)
  95414. +{
  95415. + gceSTATUS status;
  95416. + gckVGCOMMAND command;
  95417. +
  95418. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  95419. + /* Verify the arguments. */
  95420. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95421. +
  95422. + do
  95423. + {
  95424. + gctUINT32_PTR buffer;
  95425. + command = Hardware->kernel->command;
  95426. +
  95427. + /* Allocate command buffer space. */
  95428. + gcmkERR_BREAK(gckVGCOMMAND_Allocate(
  95429. + command, 8, &command->powerStallBuffer,
  95430. + (gctPOINTER *) &buffer
  95431. + ));
  95432. +
  95433. + gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
  95434. + command, buffer, gcvBLOCK_PIXEL,
  95435. + command->powerStallInt, gcvNULL));
  95436. +
  95437. + gcmkERR_BREAK(gckVGCOMMAND_Execute(
  95438. + command,
  95439. + command->powerStallBuffer
  95440. + ));
  95441. +
  95442. + /* Wait the signal. */
  95443. + gcmkERR_BREAK(gckOS_WaitSignal(
  95444. + command->os,
  95445. + command->powerStallSignal,
  95446. + gcdGPU_TIMEOUT));
  95447. +
  95448. +
  95449. + }
  95450. + while(gcvFALSE);
  95451. +
  95452. + gcmkFOOTER();
  95453. + /* Return the status. */
  95454. + return status;
  95455. +}
  95456. +
  95457. +/*******************************************************************************
  95458. +**
  95459. +** gckHARDWARE_SetPowerManagementState
  95460. +**
  95461. +** Set GPU to a specified power state.
  95462. +**
  95463. +** INPUT:
  95464. +**
  95465. +** gckHARDWARE Harwdare
  95466. +** Pointer to an gckHARDWARE object.
  95467. +**
  95468. +** gceCHIPPOWERSTATE State
  95469. +** Power State.
  95470. +**
  95471. +*/
  95472. +gceSTATUS
  95473. +gckVGHARDWARE_SetPowerManagementState(
  95474. + IN gckVGHARDWARE Hardware,
  95475. + IN gceCHIPPOWERSTATE State
  95476. + )
  95477. +{
  95478. + gceSTATUS status;
  95479. + gckVGCOMMAND command = gcvNULL;
  95480. + gckOS os;
  95481. + gctUINT flag/*, clock*/;
  95482. +
  95483. + gctBOOL acquired = gcvFALSE;
  95484. + gctBOOL stall = gcvTRUE;
  95485. + gctBOOL commitMutex = gcvFALSE;
  95486. + gctBOOL mutexAcquired = gcvFALSE;
  95487. +
  95488. +#if gcdPOWEROFF_TIMEOUT
  95489. + gctBOOL timeout = gcvFALSE;
  95490. + gctBOOL isAfter = gcvFALSE;
  95491. + gctUINT32 currentTime;
  95492. +#endif
  95493. +
  95494. + gctBOOL broadcast = gcvFALSE;
  95495. + gctUINT32 process, thread;
  95496. + gctBOOL global = gcvFALSE;
  95497. +
  95498. +#if gcdENABLE_PROFILING
  95499. + gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
  95500. + initTime, offTime, startTime, totalTime;
  95501. +#endif
  95502. +
  95503. + /* State transition flags. */
  95504. + static const gctUINT flags[4][4] =
  95505. + {
  95506. + /* gcvPOWER_ON */
  95507. + { /* ON */ 0,
  95508. + /* OFF */ gcvPOWER_FLAG_ACQUIRE |
  95509. + gcvPOWER_FLAG_STALL |
  95510. + gcvPOWER_FLAG_STOP |
  95511. + gcvPOWER_FLAG_POWER_OFF |
  95512. + gcvPOWER_FLAG_CLOCK_OFF,
  95513. + /* IDLE */ gcvPOWER_FLAG_NOP,
  95514. + /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
  95515. + gcvPOWER_FLAG_STALL |
  95516. + gcvPOWER_FLAG_STOP |
  95517. + gcvPOWER_FLAG_CLOCK_OFF,
  95518. + },
  95519. +
  95520. + /* gcvPOWER_OFF */
  95521. + { /* ON */ gcvPOWER_FLAG_INITIALIZE |
  95522. + gcvPOWER_FLAG_START |
  95523. + gcvPOWER_FLAG_RELEASE |
  95524. + gcvPOWER_FLAG_DELAY,
  95525. + /* OFF */ 0,
  95526. + /* IDLE */ gcvPOWER_FLAG_INITIALIZE |
  95527. + gcvPOWER_FLAG_START |
  95528. + gcvPOWER_FLAG_RELEASE |
  95529. + gcvPOWER_FLAG_DELAY,
  95530. + /* SUSPEND */ gcvPOWER_FLAG_INITIALIZE |
  95531. + gcvPOWER_FLAG_CLOCK_OFF,
  95532. + },
  95533. +
  95534. + /* gcvPOWER_IDLE */
  95535. + { /* ON */ gcvPOWER_FLAG_NOP,
  95536. + /* OFF */ gcvPOWER_FLAG_ACQUIRE |
  95537. + gcvPOWER_FLAG_STOP |
  95538. + gcvPOWER_FLAG_POWER_OFF |
  95539. + gcvPOWER_FLAG_CLOCK_OFF,
  95540. + /* IDLE */ 0,
  95541. + /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
  95542. + gcvPOWER_FLAG_STOP |
  95543. + gcvPOWER_FLAG_CLOCK_OFF,
  95544. + },
  95545. +
  95546. + /* gcvPOWER_SUSPEND */
  95547. + { /* ON */ gcvPOWER_FLAG_START |
  95548. + gcvPOWER_FLAG_RELEASE |
  95549. + gcvPOWER_FLAG_DELAY |
  95550. + gcvPOWER_FLAG_CLOCK_ON,
  95551. + /* OFF */ gcvPOWER_FLAG_SAVE |
  95552. + gcvPOWER_FLAG_POWER_OFF |
  95553. + gcvPOWER_FLAG_CLOCK_OFF,
  95554. + /* IDLE */ gcvPOWER_FLAG_START |
  95555. + gcvPOWER_FLAG_DELAY |
  95556. + gcvPOWER_FLAG_RELEASE |
  95557. + gcvPOWER_FLAG_CLOCK_ON,
  95558. + /* SUSPEND */ 0,
  95559. + },
  95560. + };
  95561. +
  95562. + gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
  95563. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  95564. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  95565. + "Switching to power state %d",
  95566. + State);
  95567. +#endif
  95568. +
  95569. + /* Verify the arguments. */
  95570. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95571. +
  95572. + /* Get the gckOS object pointer. */
  95573. + os = Hardware->os;
  95574. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  95575. +
  95576. + /* Get the gckCOMMAND object pointer. */
  95577. + gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
  95578. + command = Hardware->kernel->command;
  95579. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  95580. +
  95581. + if (Hardware->powerManagement == gcvFALSE)
  95582. + {
  95583. + gcmkFOOTER_NO();
  95584. + return gcvSTATUS_OK;
  95585. + }
  95586. +
  95587. + /* Start profiler. */
  95588. + gcmkPROFILE_INIT(freq, time);
  95589. +
  95590. + /* Convert the broadcast power state. */
  95591. + switch (State)
  95592. + {
  95593. + case gcvPOWER_SUSPEND_ATPOWERON:
  95594. + /* Convert to SUSPEND and don't wait for STALL. */
  95595. + State = gcvPOWER_SUSPEND;
  95596. + stall = gcvFALSE;
  95597. + break;
  95598. +
  95599. + case gcvPOWER_OFF_ATPOWERON:
  95600. + /* Convert to OFF and don't wait for STALL. */
  95601. + State = gcvPOWER_OFF;
  95602. + stall = gcvFALSE;
  95603. + break;
  95604. +
  95605. + case gcvPOWER_IDLE_BROADCAST:
  95606. + /* Convert to IDLE and note we are inside broadcast. */
  95607. + State = gcvPOWER_IDLE;
  95608. + broadcast = gcvTRUE;
  95609. + break;
  95610. +
  95611. + case gcvPOWER_SUSPEND_BROADCAST:
  95612. + /* Convert to SUSPEND and note we are inside broadcast. */
  95613. + State = gcvPOWER_SUSPEND;
  95614. + broadcast = gcvTRUE;
  95615. + break;
  95616. +
  95617. + case gcvPOWER_OFF_BROADCAST:
  95618. + /* Convert to OFF and note we are inside broadcast. */
  95619. + State = gcvPOWER_OFF;
  95620. + broadcast = gcvTRUE;
  95621. + break;
  95622. +
  95623. + case gcvPOWER_OFF_RECOVERY:
  95624. + /* Convert to OFF and note we are inside recovery. */
  95625. + State = gcvPOWER_OFF;
  95626. + stall = gcvFALSE;
  95627. + broadcast = gcvTRUE;
  95628. + break;
  95629. +
  95630. + case gcvPOWER_ON_AUTO:
  95631. + /* Convert to ON and note we are inside recovery. */
  95632. + State = gcvPOWER_ON;
  95633. + break;
  95634. +
  95635. + case gcvPOWER_ON:
  95636. + case gcvPOWER_IDLE:
  95637. + case gcvPOWER_SUSPEND:
  95638. + case gcvPOWER_OFF:
  95639. + /* Mark as global power management. */
  95640. + global = gcvTRUE;
  95641. + break;
  95642. +
  95643. +#if gcdPOWEROFF_TIMEOUT
  95644. + case gcvPOWER_OFF_TIMEOUT:
  95645. + /* Convert to OFF and note we are inside broadcast. */
  95646. + State = gcvPOWER_OFF;
  95647. + broadcast = gcvTRUE;
  95648. + /* Check time out */
  95649. + timeout = gcvTRUE;
  95650. + break;
  95651. +#endif
  95652. +
  95653. + default:
  95654. + break;
  95655. + }
  95656. +
  95657. + /* Get current process and thread IDs. */
  95658. + gcmkONERROR(gckOS_GetProcessID(&process));
  95659. + gcmkONERROR(gckOS_GetThreadID(&thread));
  95660. +
  95661. + /* Acquire the power mutex. */
  95662. + if (broadcast)
  95663. + {
  95664. + /* Try to acquire the power mutex. */
  95665. + status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
  95666. +
  95667. + if (status == gcvSTATUS_TIMEOUT)
  95668. + {
  95669. + /* Check if we already own this mutex. */
  95670. + if ((Hardware->powerProcess == process)
  95671. + && (Hardware->powerThread == thread)
  95672. + )
  95673. + {
  95674. + /* Bail out on recursive power management. */
  95675. + gcmkFOOTER_NO();
  95676. + return gcvSTATUS_OK;
  95677. + }
  95678. + else if (State == gcvPOWER_IDLE)
  95679. + {
  95680. + /* gcvPOWER_IDLE_BROADCAST is from IST,
  95681. + ** so waiting here will cause deadlock,
  95682. + ** if lock holder call gckCOMMAND_Stall() */
  95683. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  95684. + }
  95685. + else
  95686. + {
  95687. + /* Acquire the power mutex. */
  95688. + gcmkONERROR(gckOS_AcquireMutex(os,
  95689. + Hardware->powerMutex,
  95690. + gcvINFINITE));
  95691. + }
  95692. + }
  95693. + }
  95694. + else
  95695. + {
  95696. + /* Acquire the power mutex. */
  95697. + gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
  95698. + }
  95699. +
  95700. + /* Get time until mtuex acquired. */
  95701. + gcmkPROFILE_QUERY(time, mutexTime);
  95702. +
  95703. + Hardware->powerProcess = process;
  95704. + Hardware->powerThread = thread;
  95705. + mutexAcquired = gcvTRUE;
  95706. +
  95707. + /* Grab control flags and clock. */
  95708. + flag = flags[Hardware->chipPowerState][State];
  95709. + /*clock = clocks[State];*/
  95710. +
  95711. +#if gcdPOWEROFF_TIMEOUT
  95712. + if (timeout)
  95713. + {
  95714. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  95715. +
  95716. + gcmkONERROR(
  95717. + gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
  95718. +
  95719. + /* powerOffTime is pushed forward, give up.*/
  95720. + if (isAfter
  95721. + /* Expect a transition start from IDLE. */
  95722. + || (Hardware->chipPowerState == gcvPOWER_ON)
  95723. + || (Hardware->chipPowerState == gcvPOWER_OFF)
  95724. + )
  95725. + {
  95726. + /* Release the power mutex. */
  95727. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  95728. +
  95729. + /* No need to do anything. */
  95730. + gcmkFOOTER_NO();
  95731. + return gcvSTATUS_OK;
  95732. + }
  95733. + }
  95734. +#endif
  95735. +
  95736. + if (flag == 0)
  95737. + {
  95738. + /* Release the power mutex. */
  95739. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  95740. +
  95741. + /* No need to do anything. */
  95742. + gcmkFOOTER_NO();
  95743. + return gcvSTATUS_OK;
  95744. + }
  95745. +
  95746. + /* internal power control */
  95747. + if (!global)
  95748. + {
  95749. + if (Hardware->chipPowerStateGlobal == gcvPOWER_OFF)
  95750. + {
  95751. + /* Release the power mutex. */
  95752. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  95753. +
  95754. + /* No need to do anything. */
  95755. + gcmkFOOTER_NO();
  95756. + return gcvSTATUS_OK;
  95757. + }
  95758. + }
  95759. + else
  95760. + {
  95761. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  95762. + {
  95763. + /* Acquire the power management semaphore. */
  95764. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  95765. + acquired = gcvTRUE;
  95766. +
  95767. + /* avoid acquiring again. */
  95768. + flag &= ~gcvPOWER_FLAG_ACQUIRE;
  95769. + }
  95770. + }
  95771. +
  95772. + if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
  95773. + {
  95774. + /* Turn on the power. */
  95775. + gcmkONERROR(gckOS_SetGPUPower(os, gcvCORE_VG, gcvTRUE, gcvTRUE));
  95776. +
  95777. + /* Mark clock and power as enabled. */
  95778. + Hardware->clockState = gcvTRUE;
  95779. + Hardware->powerState = gcvTRUE;
  95780. + }
  95781. +
  95782. + /* Get time until powered on. */
  95783. + gcmkPROFILE_QUERY(time, onTime);
  95784. +
  95785. + if ((flag & gcvPOWER_FLAG_STALL) && stall)
  95786. + {
  95787. + /* Acquire the mutex. */
  95788. + gcmkONERROR(gckOS_AcquireMutex(
  95789. + command->os,
  95790. + command->commitMutex,
  95791. + gcvINFINITE
  95792. + ));
  95793. +
  95794. + commitMutex = gcvTRUE;
  95795. +
  95796. + gcmkONERROR(_CommandStall(Hardware));
  95797. + }
  95798. +
  95799. + /* Get time until stalled. */
  95800. + gcmkPROFILE_QUERY(time, stallTime);
  95801. +
  95802. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  95803. + {
  95804. + /* Acquire the power management semaphore. */
  95805. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  95806. +
  95807. + acquired = gcvTRUE;
  95808. + }
  95809. +
  95810. + if (flag & gcvPOWER_FLAG_STOP)
  95811. + {
  95812. + }
  95813. +
  95814. + /* Get time until stopped. */
  95815. + gcmkPROFILE_QUERY(time, stopTime);
  95816. +
  95817. + /* Only process this when hardware is enabled. */
  95818. + if (Hardware->clockState && Hardware->powerState)
  95819. + {
  95820. + }
  95821. +
  95822. + if (flag & gcvPOWER_FLAG_DELAY)
  95823. + {
  95824. + /* Wait for the specified amount of time to settle coming back from
  95825. + ** power-off or suspend state. */
  95826. + gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
  95827. + }
  95828. +
  95829. + /* Get time until delayed. */
  95830. + gcmkPROFILE_QUERY(time, delayTime);
  95831. +
  95832. + if (flag & gcvPOWER_FLAG_INITIALIZE)
  95833. + {
  95834. + gcmkONERROR(gckVGHARDWARE_SetMMU(Hardware, Hardware->kernel->mmu->pageTableLogical));
  95835. +
  95836. + /* Force the command queue to reload the next context. */
  95837. + command->currentContext = 0;
  95838. + }
  95839. +
  95840. + /* Get time until initialized. */
  95841. + gcmkPROFILE_QUERY(time, initTime);
  95842. +
  95843. + if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
  95844. + {
  95845. + /* Turn off the GPU power. */
  95846. + gcmkONERROR(
  95847. + gckOS_SetGPUPower(os,
  95848. + gcvCORE_VG,
  95849. + (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  95850. + : gcvTRUE,
  95851. + (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  95852. + : gcvTRUE));
  95853. +
  95854. + /* Save current hardware power and clock states. */
  95855. + Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  95856. + : gcvTRUE;
  95857. + Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  95858. + : gcvTRUE;
  95859. + }
  95860. +
  95861. + /* Get time until off. */
  95862. + gcmkPROFILE_QUERY(time, offTime);
  95863. +
  95864. + if (flag & gcvPOWER_FLAG_START)
  95865. + {
  95866. + }
  95867. +
  95868. + /* Get time until started. */
  95869. + gcmkPROFILE_QUERY(time, startTime);
  95870. +
  95871. + if (flag & gcvPOWER_FLAG_RELEASE)
  95872. + {
  95873. + /* Release the power management semaphore. */
  95874. + gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
  95875. + acquired = gcvFALSE;
  95876. + }
  95877. +
  95878. + /* Save the new power state. */
  95879. + Hardware->chipPowerState = State;
  95880. +
  95881. + if (global)
  95882. + {
  95883. + /* Save the new power state. */
  95884. + Hardware->chipPowerStateGlobal = State;
  95885. + }
  95886. +
  95887. + if (commitMutex)
  95888. + {
  95889. + /* Acquire the mutex. */
  95890. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  95891. + command->os,
  95892. + command->commitMutex
  95893. + ));
  95894. + }
  95895. +
  95896. +#if gcdPOWEROFF_TIMEOUT
  95897. + /* Reset power off time */
  95898. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  95899. +
  95900. + Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
  95901. +
  95902. + if (State == gcvPOWER_IDLE)
  95903. + {
  95904. + /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
  95905. + gcmkVERIFY_OK(gckOS_StartTimer(os,
  95906. + Hardware->powerOffTimer,
  95907. + Hardware->powerOffTimeout));
  95908. + }
  95909. + else
  95910. + {
  95911. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
  95912. +
  95913. + /* Cancel running timer when GPU enters ON or OFF. */
  95914. + gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
  95915. + }
  95916. +#endif
  95917. +
  95918. + /* Release the power mutex. */
  95919. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  95920. +
  95921. + /* Get total time. */
  95922. + gcmkPROFILE_QUERY(time, totalTime);
  95923. +#if gcdENABLE_PROFILING
  95924. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  95925. + "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
  95926. + freq, mutexTime, onTime, stallTime, stopTime);
  95927. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  95928. + " delay:%llu init:%llu off:%llu start:%llu total:%llu",
  95929. + delayTime, initTime, offTime, startTime, totalTime);
  95930. +#endif
  95931. +
  95932. + /* Success. */
  95933. + gcmkFOOTER_NO();
  95934. + return gcvSTATUS_OK;
  95935. +
  95936. +OnError:
  95937. +
  95938. + if (acquired)
  95939. + {
  95940. + /* Release semaphore. */
  95941. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
  95942. + command->powerSemaphore));
  95943. + }
  95944. +
  95945. + if (mutexAcquired)
  95946. + {
  95947. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  95948. + }
  95949. +
  95950. + if (commitMutex)
  95951. + {
  95952. + /* Acquire the mutex. */
  95953. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  95954. + command->os,
  95955. + command->commitMutex
  95956. + ));
  95957. + }
  95958. +
  95959. + /* Return the status. */
  95960. + gcmkFOOTER();
  95961. + return status;
  95962. +}
  95963. +
  95964. +/*******************************************************************************
  95965. +**
  95966. +** gckHARDWARE_QueryPowerManagementState
  95967. +**
  95968. +** Get GPU power state.
  95969. +**
  95970. +** INPUT:
  95971. +**
  95972. +** gckHARDWARE Harwdare
  95973. +** Pointer to an gckHARDWARE object.
  95974. +**
  95975. +** gceCHIPPOWERSTATE* State
  95976. +** Power State.
  95977. +**
  95978. +*/
  95979. +gceSTATUS
  95980. +gckVGHARDWARE_QueryPowerManagementState(
  95981. + IN gckVGHARDWARE Hardware,
  95982. + OUT gceCHIPPOWERSTATE* State
  95983. + )
  95984. +{
  95985. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  95986. +
  95987. + /* Verify the arguments. */
  95988. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  95989. + gcmkVERIFY_ARGUMENT(State != gcvNULL);
  95990. +
  95991. + /* Return the statue. */
  95992. + *State = Hardware->chipPowerState;
  95993. +
  95994. + /* Success. */
  95995. + gcmkFOOTER_ARG("*State=%d", *State);
  95996. + return gcvSTATUS_OK;
  95997. +}
  95998. +
  95999. +/*******************************************************************************
  96000. +**
  96001. +** gckVGHARDWARE_SetPowerManagement
  96002. +**
  96003. +** Configure GPU power management function.
  96004. +** Only used in driver initialization stage.
  96005. +**
  96006. +** INPUT:
  96007. +**
  96008. +** gckVGHARDWARE Harwdare
  96009. +** Pointer to an gckHARDWARE object.
  96010. +**
  96011. +** gctBOOL PowerManagement
  96012. +** Power Mangement State.
  96013. +**
  96014. +*/
  96015. +gceSTATUS
  96016. +gckVGHARDWARE_SetPowerManagement(
  96017. + IN gckVGHARDWARE Hardware,
  96018. + IN gctBOOL PowerManagement
  96019. + )
  96020. +{
  96021. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  96022. +
  96023. + /* Verify the arguments. */
  96024. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  96025. +
  96026. + Hardware->powerManagement = PowerManagement;
  96027. +
  96028. + /* Success. */
  96029. + gcmkFOOTER_NO();
  96030. + return gcvSTATUS_OK;
  96031. +}
  96032. +
  96033. +gceSTATUS
  96034. +gckVGHARDWARE_SetPowerOffTimeout(
  96035. + IN gckVGHARDWARE Hardware,
  96036. + IN gctUINT32 Timeout
  96037. + )
  96038. +{
  96039. + gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
  96040. +
  96041. +#if gcdPOWEROFF_TIMEOUT
  96042. + Hardware->powerOffTimeout = Timeout;
  96043. +#endif
  96044. +
  96045. + gcmkFOOTER_NO();
  96046. + return gcvSTATUS_OK;
  96047. +}
  96048. +
  96049. +
  96050. +gceSTATUS
  96051. +gckVGHARDWARE_QueryPowerOffTimeout(
  96052. + IN gckVGHARDWARE Hardware,
  96053. + OUT gctUINT32* Timeout
  96054. + )
  96055. +{
  96056. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  96057. +
  96058. +#if gcdPOWEROFF_TIMEOUT
  96059. + *Timeout = Hardware->powerOffTimeout;
  96060. +#endif
  96061. +
  96062. + gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
  96063. + return gcvSTATUS_OK;
  96064. +}
  96065. +
  96066. +gceSTATUS
  96067. +gckVGHARDWARE_QueryIdle(
  96068. + IN gckVGHARDWARE Hardware,
  96069. + OUT gctBOOL_PTR IsIdle
  96070. + )
  96071. +{
  96072. + gceSTATUS status;
  96073. + gctUINT32 idle;
  96074. +
  96075. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  96076. +
  96077. + /* Verify the arguments. */
  96078. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  96079. + gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL);
  96080. +
  96081. + /* We are idle when the power is not ON. */
  96082. + if (Hardware->chipPowerState != gcvPOWER_ON)
  96083. + {
  96084. + *IsIdle = gcvTRUE;
  96085. + }
  96086. +
  96087. + else
  96088. + {
  96089. + /* Read idle register. */
  96090. + gcmkONERROR(
  96091. + gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, 0x00004, &idle));
  96092. +
  96093. + /* Pipe must be idle. */
  96094. + 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)
  96095. + || ((((((gctUINT32) (idle)) >> (0 ? 8:8)) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) ) != 1)
  96096. + || ((((((gctUINT32) (idle)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) ) != 1)
  96097. + || ((((((gctUINT32) (idle)) >> (0 ? 10:10)) & ((gctUINT32) ((((1 ? 10:10) - (0 ? 10:10) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 10:10) - (0 ? 10:10) + 1)))))) ) != 1)
  96098. + || ((((((gctUINT32) (idle)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) ) != 1)
  96099. + )
  96100. + {
  96101. + /* Something is busy. */
  96102. + *IsIdle = gcvFALSE;
  96103. + }
  96104. +
  96105. + else
  96106. + {
  96107. + *IsIdle = gcvTRUE;
  96108. + }
  96109. + }
  96110. +
  96111. + /* Success. */
  96112. + gcmkFOOTER_NO();
  96113. + return gcvSTATUS_OK;
  96114. +
  96115. +OnError:
  96116. + /* Return the status. */
  96117. + gcmkFOOTER();
  96118. + return status;
  96119. +}
  96120. +#endif /* gcdENABLE_VG */
  96121. +
  96122. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h
  96123. --- linux-3.14.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h 1969-12-31 18:00:00.000000000 -0600
  96124. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h 2014-12-08 00:31:53.460418001 -0600
  96125. @@ -0,0 +1,75 @@
  96126. +/****************************************************************************
  96127. +*
  96128. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  96129. +*
  96130. +* This program is free software; you can redistribute it and/or modify
  96131. +* it under the terms of the GNU General Public License as published by
  96132. +* the Free Software Foundation; either version 2 of the license, or
  96133. +* (at your option) any later version.
  96134. +*
  96135. +* This program is distributed in the hope that it will be useful,
  96136. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  96137. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  96138. +* GNU General Public License for more details.
  96139. +*
  96140. +* You should have received a copy of the GNU General Public License
  96141. +* along with this program; if not write to the Free Software
  96142. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  96143. +*
  96144. +*****************************************************************************/
  96145. +
  96146. +
  96147. +#ifndef __gc_hal_kernel_hardware_vg_h_
  96148. +#define __gc_hal_kernel_hardware_vg_h_
  96149. +
  96150. +/* gckHARDWARE object. */
  96151. +struct _gckVGHARDWARE
  96152. +{
  96153. + /* Object. */
  96154. + gcsOBJECT object;
  96155. +
  96156. + /* Pointer to gckKERNEL object. */
  96157. + gckVGKERNEL kernel;
  96158. +
  96159. + /* Pointer to gckOS object. */
  96160. + gckOS os;
  96161. +
  96162. + /* Chip characteristics. */
  96163. + gceCHIPMODEL chipModel;
  96164. + gctUINT32 chipRevision;
  96165. + gctUINT32 chipFeatures;
  96166. + gctUINT32 chipMinorFeatures;
  96167. + gctUINT32 chipMinorFeatures2;
  96168. + gctBOOL allowFastClear;
  96169. +
  96170. + /* Features. */
  96171. + gctBOOL fe20;
  96172. + gctBOOL vg20;
  96173. + gctBOOL vg21;
  96174. +
  96175. + /* Event mask. */
  96176. + gctUINT32 eventMask;
  96177. +
  96178. + gctBOOL clockState;
  96179. + gctBOOL powerState;
  96180. + gctPOINTER powerMutex;
  96181. + gctUINT32 powerProcess;
  96182. + gctUINT32 powerThread;
  96183. + gceCHIPPOWERSTATE chipPowerState;
  96184. + gceCHIPPOWERSTATE chipPowerStateGlobal;
  96185. + gctISRMANAGERFUNC startIsr;
  96186. + gctISRMANAGERFUNC stopIsr;
  96187. + gctPOINTER isrContext;
  96188. + gctPOINTER pageTableDirty;
  96189. +
  96190. +#if gcdPOWEROFF_TIMEOUT
  96191. + gctUINT32 powerOffTime;
  96192. + gctUINT32 powerOffTimeout;
  96193. + gctPOINTER powerOffTimer;
  96194. +#endif
  96195. +
  96196. + gctBOOL powerManagement;
  96197. +};
  96198. +
  96199. +#endif /* __gc_hal_kernel_hardware_h_ */
  96200. +
  96201. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
  96202. --- linux-3.14.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c 1969-12-31 18:00:00.000000000 -0600
  96203. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c 2014-12-08 00:31:53.460418001 -0600
  96204. @@ -0,0 +1,1735 @@
  96205. +/****************************************************************************
  96206. +*
  96207. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  96208. +*
  96209. +* This program is free software; you can redistribute it and/or modify
  96210. +* it under the terms of the GNU General Public License as published by
  96211. +* the Free Software Foundation; either version 2 of the license, or
  96212. +* (at your option) any later version.
  96213. +*
  96214. +* This program is distributed in the hope that it will be useful,
  96215. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  96216. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  96217. +* GNU General Public License for more details.
  96218. +*
  96219. +* You should have received a copy of the GNU General Public License
  96220. +* along with this program; if not write to the Free Software
  96221. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  96222. +*
  96223. +*****************************************************************************/
  96224. +
  96225. +
  96226. +#include "gc_hal.h"
  96227. +#include "gc_hal_kernel.h"
  96228. +#include "gc_hal_kernel_context.h"
  96229. +#include "gc_hal_kernel_buffer.h"
  96230. +
  96231. +/******************************************************************************\
  96232. +******************************** Debugging Macro *******************************
  96233. +\******************************************************************************/
  96234. +
  96235. +/* Zone used for header/footer. */
  96236. +#define _GC_OBJ_ZONE gcvZONE_HARDWARE
  96237. +
  96238. +
  96239. +/******************************************************************************\
  96240. +************************** Context State Buffer Helpers ************************
  96241. +\******************************************************************************/
  96242. +
  96243. +#define _STATE(reg) \
  96244. + _State(\
  96245. + Context, index, \
  96246. + reg ## _Address >> 2, \
  96247. + reg ## _ResetValue, \
  96248. + reg ## _Count, \
  96249. + gcvFALSE, gcvFALSE \
  96250. + )
  96251. +
  96252. +#define _STATE_COUNT(reg, count) \
  96253. + _State(\
  96254. + Context, index, \
  96255. + reg ## _Address >> 2, \
  96256. + reg ## _ResetValue, \
  96257. + count, \
  96258. + gcvFALSE, gcvFALSE \
  96259. + )
  96260. +
  96261. +#define _STATE_COUNT_OFFSET(reg, offset, count) \
  96262. + _State(\
  96263. + Context, index, \
  96264. + (reg ## _Address >> 2) + offset, \
  96265. + reg ## _ResetValue, \
  96266. + count, \
  96267. + gcvFALSE, gcvFALSE \
  96268. + )
  96269. +
  96270. +#define _STATE_MIRROR_COUNT(reg, mirror, count) \
  96271. + _StateMirror(\
  96272. + Context, \
  96273. + reg ## _Address >> 2, \
  96274. + count, \
  96275. + mirror ## _Address >> 2 \
  96276. + )
  96277. +
  96278. +#define _STATE_HINT(reg) \
  96279. + _State(\
  96280. + Context, index, \
  96281. + reg ## _Address >> 2, \
  96282. + reg ## _ResetValue, \
  96283. + reg ## _Count, \
  96284. + gcvFALSE, gcvTRUE \
  96285. + )
  96286. +
  96287. +#define _STATE_HINT_BLOCK(reg, block, count) \
  96288. + _State(\
  96289. + Context, index, \
  96290. + (reg ## _Address >> 2) + (block << reg ## _BLK), \
  96291. + reg ## _ResetValue, \
  96292. + count, \
  96293. + gcvFALSE, gcvTRUE \
  96294. + )
  96295. +
  96296. +#define _STATE_X(reg) \
  96297. + _State(\
  96298. + Context, index, \
  96299. + reg ## _Address >> 2, \
  96300. + reg ## _ResetValue, \
  96301. + reg ## _Count, \
  96302. + gcvTRUE, gcvFALSE \
  96303. + )
  96304. +
  96305. +#define _CLOSE_RANGE() \
  96306. + _TerminateStateBlock(Context, index)
  96307. +
  96308. +#define _ENABLE(reg, field) \
  96309. + do \
  96310. + { \
  96311. + if (gcmVERIFYFIELDVALUE(data, reg, MASK_ ## field, ENABLED)) \
  96312. + { \
  96313. + enable |= gcmFIELDMASK(reg, field); \
  96314. + } \
  96315. + } \
  96316. + while (gcvFALSE)
  96317. +
  96318. +#define _BLOCK_COUNT(reg) \
  96319. + ((reg ## _Count) >> (reg ## _BLK))
  96320. +
  96321. +
  96322. +/******************************************************************************\
  96323. +*********************** Support Functions and Definitions **********************
  96324. +\******************************************************************************/
  96325. +
  96326. +#define gcdSTATE_MASK \
  96327. + (((((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))))
  96328. +
  96329. +#if !defined(VIVANTE_NO_3D)
  96330. +static gctSIZE_T
  96331. +_TerminateStateBlock(
  96332. + IN gckCONTEXT Context,
  96333. + IN gctSIZE_T Index
  96334. + )
  96335. +{
  96336. + gctUINT32_PTR buffer;
  96337. + gctSIZE_T align;
  96338. +
  96339. + /* Determine if we need alignment. */
  96340. + align = (Index & 1) ? 1 : 0;
  96341. +
  96342. + /* Address correct index. */
  96343. + buffer = (Context->buffer == gcvNULL)
  96344. + ? gcvNULL
  96345. + : Context->buffer->logical;
  96346. +
  96347. + /* Flush the current state block; make sure no pairing with the states
  96348. + to follow happens. */
  96349. + if (align && (buffer != gcvNULL))
  96350. + {
  96351. + buffer[Index] = 0xDEADDEAD;
  96352. + }
  96353. +
  96354. + /* Reset last address. */
  96355. + Context->lastAddress = ~0U;
  96356. +
  96357. + /* Return alignment requirement. */
  96358. + return align;
  96359. +}
  96360. +#endif
  96361. +
  96362. +
  96363. +static gctSIZE_T
  96364. +_FlushPipe(
  96365. + IN gckCONTEXT Context,
  96366. + IN gctSIZE_T Index,
  96367. + IN gcePIPE_SELECT Pipe
  96368. + )
  96369. +{
  96370. + if (Context->buffer != gcvNULL)
  96371. + {
  96372. + gctUINT32_PTR buffer;
  96373. +
  96374. + /* Address correct index. */
  96375. + buffer = Context->buffer->logical + Index;
  96376. +
  96377. + /* Flush the current pipe. */
  96378. + *buffer++
  96379. + = ((((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)))
  96380. + | ((((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)))
  96381. + | ((((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)));
  96382. +
  96383. + *buffer++
  96384. + = (Pipe == gcvPIPE_2D)
  96385. + ? ((((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)))
  96386. + : ((((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)))
  96387. + | ((((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)))
  96388. + | ((((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)))
  96389. + | ((((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)));
  96390. +
  96391. + /* Semaphore from FE to PE. */
  96392. + *buffer++
  96393. + = ((((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)))
  96394. + | ((((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)))
  96395. + | ((((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)));
  96396. +
  96397. + *buffer++
  96398. + = ((((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)))
  96399. + | ((((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)));
  96400. +
  96401. + /* Stall from FE to PE. */
  96402. + *buffer++
  96403. + = ((((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)));
  96404. +
  96405. + *buffer
  96406. + = ((((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)))
  96407. + | ((((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)));
  96408. + }
  96409. +
  96410. + /* Flushing 3D pipe takes 6 slots. */
  96411. + return 6;
  96412. +}
  96413. +
  96414. +#if !defined(VIVANTE_NO_3D)
  96415. +static gctSIZE_T
  96416. +_SemaphoreStall(
  96417. + IN gckCONTEXT Context,
  96418. + IN gctSIZE_T Index
  96419. + )
  96420. +{
  96421. + if (Context->buffer != gcvNULL)
  96422. + {
  96423. + gctUINT32_PTR buffer;
  96424. +
  96425. + /* Address correct index. */
  96426. + buffer = Context->buffer->logical + Index;
  96427. +
  96428. + /* Semaphore from FE to PE. */
  96429. + *buffer++
  96430. + = ((((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)))
  96431. + | ((((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)))
  96432. + | ((((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)));
  96433. +
  96434. + *buffer++
  96435. + = ((((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)))
  96436. + | ((((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)));
  96437. +
  96438. + /* Stall from FE to PE. */
  96439. + *buffer++
  96440. + = ((((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)));
  96441. +
  96442. + *buffer
  96443. + = ((((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)))
  96444. + | ((((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)));
  96445. + }
  96446. +
  96447. + /* Semaphore/stall takes 4 slots. */
  96448. + return 4;
  96449. +}
  96450. +#endif
  96451. +
  96452. +static gctSIZE_T
  96453. +_SwitchPipe(
  96454. + IN gckCONTEXT Context,
  96455. + IN gctSIZE_T Index,
  96456. + IN gcePIPE_SELECT Pipe
  96457. + )
  96458. +{
  96459. + if (Context->buffer != gcvNULL)
  96460. + {
  96461. + gctUINT32_PTR buffer;
  96462. +
  96463. + /* Address correct index. */
  96464. + buffer = Context->buffer->logical + Index;
  96465. +
  96466. + /* LoadState(AQPipeSelect, 1), pipe. */
  96467. + *buffer++
  96468. + = ((((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)))
  96469. + | ((((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)))
  96470. + | ((((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)));
  96471. +
  96472. + *buffer
  96473. + = (Pipe == gcvPIPE_2D)
  96474. + ? 0x1
  96475. + : 0x0;
  96476. + }
  96477. +
  96478. + return 2;
  96479. +}
  96480. +
  96481. +#if !defined(VIVANTE_NO_3D)
  96482. +static gctSIZE_T
  96483. +_State(
  96484. + IN gckCONTEXT Context,
  96485. + IN gctSIZE_T Index,
  96486. + IN gctUINT32 Address,
  96487. + IN gctUINT32 Value,
  96488. + IN gctSIZE_T Size,
  96489. + IN gctBOOL FixedPoint,
  96490. + IN gctBOOL Hinted
  96491. + )
  96492. +{
  96493. + gctUINT32_PTR buffer;
  96494. + gctSIZE_T align, i;
  96495. +
  96496. + /* Determine if we need alignment. */
  96497. + align = (Index & 1) ? 1 : 0;
  96498. +
  96499. + /* Address correct index. */
  96500. + buffer = (Context->buffer == gcvNULL)
  96501. + ? gcvNULL
  96502. + : Context->buffer->logical;
  96503. +
  96504. + if ((buffer == gcvNULL) && (Address + Size > Context->stateCount))
  96505. + {
  96506. + /* Determine maximum state. */
  96507. + Context->stateCount = Address + Size;
  96508. + }
  96509. +
  96510. + /* Do we need a new entry? */
  96511. + if ((Address != Context->lastAddress) || (FixedPoint != Context->lastFixed))
  96512. + {
  96513. + if (buffer != gcvNULL)
  96514. + {
  96515. + if (align)
  96516. + {
  96517. + /* Add filler. */
  96518. + buffer[Index++] = 0xDEADDEAD;
  96519. + }
  96520. +
  96521. + /* LoadState(Address, Count). */
  96522. + gcmkASSERT((Index & 1) == 0);
  96523. +
  96524. + if (FixedPoint)
  96525. + {
  96526. + buffer[Index]
  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 ? 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)))
  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) (Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
  96530. + | ((((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)));
  96531. + }
  96532. + else
  96533. + {
  96534. + buffer[Index]
  96535. + = ((((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)))
  96536. + | ((((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)))
  96537. + | ((((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)))
  96538. + | ((((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)));
  96539. + }
  96540. +
  96541. + /* Walk all the states. */
  96542. + for (i = 0; i < Size; i += 1)
  96543. + {
  96544. + /* Set state to uninitialized value. */
  96545. + buffer[Index + 1 + i] = Value;
  96546. +
  96547. + /* Set index in state mapping table. */
  96548. + Context->map[Address + i].index = Index + 1 + i;
  96549. +
  96550. +#if gcdSECURE_USER
  96551. + /* Save hint. */
  96552. + if (Context->hint != gcvNULL)
  96553. + {
  96554. + Context->hint[Address + i] = Hinted;
  96555. + }
  96556. +#endif
  96557. + }
  96558. + }
  96559. +
  96560. + /* Save information for this LoadState. */
  96561. + Context->lastIndex = Index;
  96562. + Context->lastAddress = Address + Size;
  96563. + Context->lastSize = Size;
  96564. + Context->lastFixed = FixedPoint;
  96565. +
  96566. + /* Return size for load state. */
  96567. + return align + 1 + Size;
  96568. + }
  96569. +
  96570. + /* Append this state to the previous one. */
  96571. + if (buffer != gcvNULL)
  96572. + {
  96573. + /* Update last load state. */
  96574. + buffer[Context->lastIndex] =
  96575. + ((((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)));
  96576. +
  96577. + /* Walk all the states. */
  96578. + for (i = 0; i < Size; i += 1)
  96579. + {
  96580. + /* Set state to uninitialized value. */
  96581. + buffer[Index + i] = Value;
  96582. +
  96583. + /* Set index in state mapping table. */
  96584. + Context->map[Address + i].index = Index + i;
  96585. +
  96586. +#if gcdSECURE_USER
  96587. + /* Save hint. */
  96588. + if (Context->hint != gcvNULL)
  96589. + {
  96590. + Context->hint[Address + i] = Hinted;
  96591. + }
  96592. +#endif
  96593. + }
  96594. + }
  96595. +
  96596. + /* Update last address and size. */
  96597. + Context->lastAddress += Size;
  96598. + Context->lastSize += Size;
  96599. +
  96600. + /* Return number of slots required. */
  96601. + return Size;
  96602. +}
  96603. +
  96604. +static gctSIZE_T
  96605. +_StateMirror(
  96606. + IN gckCONTEXT Context,
  96607. + IN gctUINT32 Address,
  96608. + IN gctSIZE_T Size,
  96609. + IN gctUINT32 AddressMirror
  96610. + )
  96611. +{
  96612. + gctSIZE_T i;
  96613. +
  96614. + /* Process when buffer is set. */
  96615. + if (Context->buffer != gcvNULL)
  96616. + {
  96617. + /* Walk all states. */
  96618. + for (i = 0; i < Size; i++)
  96619. + {
  96620. + /* Copy the mapping address. */
  96621. + Context->map[Address + i].index =
  96622. + Context->map[AddressMirror + i].index;
  96623. + }
  96624. + }
  96625. +
  96626. + /* Return the number of required maps. */
  96627. + return Size;
  96628. +}
  96629. +#endif
  96630. +
  96631. +static gceSTATUS
  96632. +_InitializeContextBuffer(
  96633. + IN gckCONTEXT Context
  96634. + )
  96635. +{
  96636. + gctUINT32_PTR buffer;
  96637. + gctSIZE_T index;
  96638. +
  96639. +#if !defined(VIVANTE_NO_3D)
  96640. + gctUINT i;
  96641. + gctUINT vertexUniforms, fragmentUniforms;
  96642. + gctUINT fe2vsCount;
  96643. + gctBOOL halti0;
  96644. +#endif
  96645. +
  96646. + /* Reset the buffer index. */
  96647. + index = 0;
  96648. +
  96649. + /* Reset the last state address. */
  96650. + Context->lastAddress = ~0U;
  96651. +
  96652. + /* Get the buffer pointer. */
  96653. + buffer = (Context->buffer == gcvNULL)
  96654. + ? gcvNULL
  96655. + : Context->buffer->logical;
  96656. +
  96657. +
  96658. + /**************************************************************************/
  96659. + /* Build 2D states. *******************************************************/
  96660. +
  96661. +
  96662. +#if !defined(VIVANTE_NO_3D)
  96663. + /**************************************************************************/
  96664. + /* Build 3D states. *******************************************************/
  96665. + 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)))))) );
  96666. +
  96667. + /* Query shader support. */
  96668. + gcmkVERIFY_OK(gckHARDWARE_QueryShaderCaps(
  96669. + Context->hardware, &vertexUniforms, &fragmentUniforms, gcvNULL));
  96670. +
  96671. + /* Store the 3D entry index. */
  96672. + Context->entryOffset3D = index * gcmSIZEOF(gctUINT32);
  96673. +
  96674. + /* Flush 2D pipe. */
  96675. + index += _FlushPipe(Context, index, gcvPIPE_2D);
  96676. +
  96677. + /* Switch to 3D pipe. */
  96678. + index += _SwitchPipe(Context, index, gcvPIPE_3D);
  96679. +
  96680. + /* Current context pointer. */
  96681. +#if gcdDEBUG
  96682. + index += _State(Context, index, 0x03850 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96683. +#endif
  96684. +
  96685. + index += _FlushPipe(Context, index, gcvPIPE_3D);
  96686. +
  96687. + /* Global states. */
  96688. + index += _State(Context, index, 0x03814 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
  96689. + index += _State(Context, index, 0x03818 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96690. + index += _State(Context, index, 0x0381C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96691. + index += _State(Context, index, 0x03820 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96692. + index += _State(Context, index, 0x03828 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96693. + index += _State(Context, index, 0x0382C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96694. + index += _State(Context, index, 0x03834 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96695. + index += _State(Context, index, 0x03838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96696. + index += _State(Context, index, 0x0384C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96697. +
  96698. + /* Front End states. */
  96699. + fe2vsCount = 12;
  96700. + 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)))))) ))
  96701. + {
  96702. + fe2vsCount = 16;
  96703. + }
  96704. + index += _State(Context, index, 0x00600 >> 2, 0x00000000, fe2vsCount, gcvFALSE, gcvFALSE);
  96705. + index += _CLOSE_RANGE();
  96706. +
  96707. + index += _State(Context, index, 0x00644 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96708. + index += _State(Context, index, 0x00648 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96709. + index += _State(Context, index, 0x0064C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96710. + index += _State(Context, index, 0x00650 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96711. + index += _State(Context, index, 0x00680 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
  96712. + index += _State(Context, index, 0x006A0 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
  96713. + index += _State(Context, index, 0x00670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96714. + index += _State(Context, index, 0x00678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96715. + index += _State(Context, index, 0x0067C >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
  96716. + index += _State(Context, index, 0x006C0 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  96717. + index += _State(Context, index, 0x00700 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  96718. + index += _State(Context, index, 0x00740 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  96719. + index += _State(Context, index, 0x00780 >> 2, 0x3F800000, 16, gcvFALSE, gcvFALSE);
  96720. +
  96721. + /* Vertex Shader states. */
  96722. + index += _State(Context, index, 0x00800 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96723. + index += _State(Context, index, 0x00804 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96724. + index += _State(Context, index, 0x00808 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96725. + index += _State(Context, index, 0x0080C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96726. + index += _State(Context, index, 0x00810 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  96727. + index += _State(Context, index, 0x00820 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  96728. + index += _State(Context, index, 0x00830 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96729. + index += _State(Context, index, 0x00838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96730. + if (Context->hardware->identity.instructionCount <= 256)
  96731. + {
  96732. + index += _State(Context, index, 0x04000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
  96733. + }
  96734. +
  96735. + index += _CLOSE_RANGE();
  96736. + index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE);
  96737. +
  96738. + /* Primitive Assembly states. */
  96739. + index += _State(Context, index, 0x00A00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96740. + index += _State(Context, index, 0x00A04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96741. + index += _State(Context, index, 0x00A08 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96742. + index += _State(Context, index, 0x00A0C >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96743. + index += _State(Context, index, 0x00A10 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96744. + index += _State(Context, index, 0x00A14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96745. + index += _State(Context, index, 0x00A18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96746. + index += _State(Context, index, 0x00A1C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96747. + index += _State(Context, index, 0x00A28 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96748. + index += _State(Context, index, 0x00A2C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96749. + index += _State(Context, index, 0x00A30 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96750. + index += _State(Context, index, 0x00A40 >> 2, 0x00000000, 10, gcvFALSE, gcvFALSE);
  96751. + index += _State(Context, index, 0x00A34 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96752. + index += _State(Context, index, 0x00A38 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96753. + index += _State(Context, index, 0x00A3C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96754. + index += _State(Context, index, 0x00A80 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96755. + index += _State(Context, index, 0x00A84 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96756. + index += _State(Context, index, 0x00A8C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96757. +
  96758. + /* Setup states. */
  96759. + index += _State(Context, index, 0x00C00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96760. + index += _State(Context, index, 0x00C04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96761. + index += _State(Context, index, 0x00C08 >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
  96762. + index += _State(Context, index, 0x00C0C >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
  96763. + index += _State(Context, index, 0x00C10 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96764. + index += _State(Context, index, 0x00C14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96765. + index += _State(Context, index, 0x00C18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96766. + index += _State(Context, index, 0x00C1C >> 2, 0x42000000, 1, gcvFALSE, gcvFALSE);
  96767. + index += _State(Context, index, 0x00C20 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96768. + index += _State(Context, index, 0x00C24 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  96769. +
  96770. + /* Raster states. */
  96771. + index += _State(Context, index, 0x00E00 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
  96772. + index += _State(Context, index, 0x00E10 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  96773. + index += _State(Context, index, 0x00E04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96774. + index += _State(Context, index, 0x00E40 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  96775. + index += _State(Context, index, 0x00E08 >> 2, 0x00000031, 1, gcvFALSE, gcvFALSE);
  96776. +
  96777. + /* Pixel Shader states. */
  96778. + index += _State(Context, index, 0x01000 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96779. + index += _State(Context, index, 0x01004 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96780. + index += _State(Context, index, 0x01008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96781. + index += _State(Context, index, 0x0100C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96782. + index += _State(Context, index, 0x01010 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96783. + index += _State(Context, index, 0x01018 >> 2, 0x01000000, 1, gcvFALSE, gcvFALSE);
  96784. + if (Context->hardware->identity.instructionCount <= 256)
  96785. + {
  96786. + index += _State(Context, index, 0x06000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
  96787. + }
  96788. +
  96789. + index += _CLOSE_RANGE();
  96790. + index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE);
  96791. +
  96792. + /* Texture states. */
  96793. + index += _State(Context, index, 0x02000 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96794. + index += _State(Context, index, 0x02040 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96795. + index += _State(Context, index, 0x02080 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96796. + index += _State(Context, index, 0x020C0 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96797. + index += _State(Context, index, 0x02100 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96798. + index += _State(Context, index, 0x02140 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96799. + index += _State(Context, index, 0x02180 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96800. + index += _State(Context, index, 0x021C0 >> 2, 0x00321000, 12, gcvFALSE, gcvFALSE);
  96801. + index += _State(Context, index, 0x02200 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96802. + index += _State(Context, index, 0x02240 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  96803. + index += _State(Context, index, (0x02400 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96804. + index += _State(Context, index, (0x02440 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96805. + index += _State(Context, index, (0x02480 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96806. + index += _State(Context, index, (0x024C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96807. + index += _State(Context, index, (0x02500 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96808. + index += _State(Context, index, (0x02540 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96809. + index += _State(Context, index, (0x02580 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96810. + index += _State(Context, index, (0x025C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96811. + index += _State(Context, index, (0x02600 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96812. + index += _State(Context, index, (0x02640 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96813. + index += _State(Context, index, (0x02680 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96814. + index += _State(Context, index, (0x026C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96815. + index += _State(Context, index, (0x02700 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96816. + index += _State(Context, index, (0x02740 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  96817. + index += _CLOSE_RANGE();
  96818. +
  96819. + 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)))))) ))
  96820. + {
  96821. + gctUINT texBlockCount;
  96822. +
  96823. + /* New texture block. */
  96824. + index += _State(Context, index, 0x10000 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96825. + index += _State(Context, index, 0x10080 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96826. + index += _State(Context, index, 0x10100 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96827. + index += _State(Context, index, 0x10180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96828. + index += _State(Context, index, 0x10200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96829. + index += _State(Context, index, 0x10280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96830. + for (i = 0; i < 256 / 16; i += 1)
  96831. + {
  96832. + index += _State(Context, index, (0x02C00 >> 2) + i * 16, 0x00000000, 14, gcvFALSE, gcvFALSE);
  96833. + }
  96834. + index += _State(Context, index, 0x10300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96835. + index += _State(Context, index, 0x10380 >> 2, 0x00321000, 32, gcvFALSE, gcvFALSE);
  96836. + index += _State(Context, index, 0x10400 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96837. + index += _State(Context, index, 0x10480 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  96838. +
  96839. + 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)))))) ))
  96840. + {
  96841. + index += _State(Context, index, 0x12000 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
  96842. + index += _State(Context, index, 0x12400 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
  96843. + }
  96844. +
  96845. + if ((Context->hardware->identity.chipModel == gcv2000)
  96846. + && (Context->hardware->identity.chipRevision == 0x5108))
  96847. + {
  96848. + texBlockCount = 12;
  96849. + }
  96850. + else
  96851. + {
  96852. + texBlockCount = ((512) >> (4));
  96853. + }
  96854. + for (i = 0; i < texBlockCount; i += 1)
  96855. + {
  96856. + index += _State(Context, index, (0x10800 >> 2) + (i << 4), 0x00000000, 14, gcvFALSE, gcvTRUE);
  96857. + }
  96858. + }
  96859. +
  96860. + /* YUV. */
  96861. + index += _State(Context, index, 0x01678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96862. + index += _State(Context, index, 0x0167C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96863. + index += _State(Context, index, 0x01680 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96864. + index += _State(Context, index, 0x01684 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96865. + index += _State(Context, index, 0x01688 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96866. + index += _State(Context, index, 0x0168C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96867. + index += _State(Context, index, 0x01690 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96868. + index += _State(Context, index, 0x01694 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96869. + index += _State(Context, index, 0x01698 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96870. + index += _State(Context, index, 0x0169C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96871. + index += _CLOSE_RANGE();
  96872. +
  96873. + /* Thread walker states. */
  96874. + index += _State(Context, index, 0x00900 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96875. + index += _State(Context, index, 0x00904 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96876. + index += _State(Context, index, 0x00908 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96877. + index += _State(Context, index, 0x0090C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96878. + index += _State(Context, index, 0x00910 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96879. + index += _State(Context, index, 0x00914 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96880. + index += _State(Context, index, 0x00918 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96881. + index += _State(Context, index, 0x0091C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96882. + index += _State(Context, index, 0x00924 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96883. + index += _CLOSE_RANGE();
  96884. +
  96885. + if (Context->hardware->identity.instructionCount > 1024)
  96886. + {
  96887. + /* New Shader instruction memory. */
  96888. + index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96889. + index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
  96890. + index += _State(Context, index, 0x00860 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96891. + index += _CLOSE_RANGE();
  96892. +
  96893. + for (i = 0;
  96894. + i < Context->hardware->identity.instructionCount << 2;
  96895. + i += 256 << 2
  96896. + )
  96897. + {
  96898. + index += _State(Context, index, (0x20000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
  96899. + index += _CLOSE_RANGE();
  96900. + }
  96901. + }
  96902. + else if (Context->hardware->identity.instructionCount > 256)
  96903. + {
  96904. + /* New Shader instruction memory. */
  96905. + index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96906. + index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
  96907. + index += _CLOSE_RANGE();
  96908. +
  96909. + /* VX instruction memory. */
  96910. + for (i = 0;
  96911. + i < Context->hardware->identity.instructionCount << 2;
  96912. + i += 256 << 2
  96913. + )
  96914. + {
  96915. + index += _State(Context, index, (0x0C000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
  96916. + index += _CLOSE_RANGE();
  96917. + }
  96918. +
  96919. + _StateMirror(Context, 0x08000 >> 2, Context->hardware->identity.instructionCount << 2 , 0x0C000 >> 2);
  96920. + }
  96921. +
  96922. + /* Store the index of the "XD" entry. */
  96923. + Context->entryOffsetXDFrom3D = index * gcmSIZEOF(gctUINT32);
  96924. +
  96925. +
  96926. + /* Pixel Engine states. */
  96927. + index += _State(Context, index, 0x01400 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96928. + index += _State(Context, index, 0x01404 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96929. + index += _State(Context, index, 0x01408 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96930. + index += _State(Context, index, 0x0140C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96931. + index += _State(Context, index, 0x01414 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96932. + index += _State(Context, index, 0x01418 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96933. + index += _State(Context, index, 0x0141C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96934. + index += _State(Context, index, 0x01420 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96935. + index += _State(Context, index, 0x01424 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96936. + index += _State(Context, index, 0x01428 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96937. + index += _State(Context, index, 0x0142C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96938. + index += _State(Context, index, 0x01434 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96939. + index += _State(Context, index, 0x01454 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96940. + index += _State(Context, index, 0x01458 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96941. + index += _State(Context, index, 0x0145C >> 2, 0x00000010, 1, gcvFALSE, gcvFALSE);
  96942. + index += _State(Context, index, 0x014A0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96943. + index += _State(Context, index, 0x014A8 >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
  96944. + index += _State(Context, index, 0x014AC >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
  96945. + index += _State(Context, index, 0x014B0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96946. + index += _State(Context, index, 0x014B4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96947. + index += _State(Context, index, 0x014A4 >> 2, 0x000E400C, 1, gcvFALSE, gcvFALSE);
  96948. + index += _State(Context, index, 0x01580 >> 2, 0x00000000, 3, gcvFALSE, gcvFALSE);
  96949. + index += _State(Context, index, 0x014B8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96950. +
  96951. + /* Composition states. */
  96952. + index += _State(Context, index, 0x03008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96953. +
  96954. + if (Context->hardware->identity.pixelPipes == 1)
  96955. + {
  96956. + index += _State(Context, index, 0x01460 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
  96957. +
  96958. + index += _State(Context, index, 0x01430 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96959. + index += _State(Context, index, 0x01410 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96960. + }
  96961. + else
  96962. + {
  96963. + index += _State(Context, index, (0x01460 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  96964. +
  96965. + for (i = 0; i < 2; i++)
  96966. + {
  96967. + index += _State(Context, index, (0x01500 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  96968. + }
  96969. + }
  96970. +
  96971. + if (Context->hardware->identity.pixelPipes > 1 || halti0)
  96972. + {
  96973. + index += _State(Context, index, (0x01480 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  96974. + }
  96975. +
  96976. + /* Resolve states. */
  96977. + index += _State(Context, index, 0x01604 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96978. + index += _State(Context, index, 0x01608 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96979. + index += _State(Context, index, 0x0160C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96980. + index += _State(Context, index, 0x01610 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  96981. + index += _State(Context, index, 0x01614 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96982. + index += _State(Context, index, 0x01620 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96983. + index += _State(Context, index, 0x01630 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
  96984. + index += _State(Context, index, 0x01640 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  96985. + index += _State(Context, index, 0x0163C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96986. + index += _State(Context, index, 0x016A0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96987. + index += _State(Context, index, 0x016B4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  96988. + index += _CLOSE_RANGE();
  96989. +
  96990. + if (Context->hardware->identity.pixelPipes > 1)
  96991. + {
  96992. + index += _State(Context, index, (0x016C0 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  96993. +
  96994. + index += _State(Context, index, (0x016E0 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  96995. +
  96996. + index += _State(Context, index, 0x01700 >> 2, 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvFALSE);
  96997. + }
  96998. +
  96999. + /* Tile status. */
  97000. + index += _State(Context, index, 0x01654 >> 2, 0x00200000, 1, gcvFALSE, gcvFALSE);
  97001. +
  97002. + index += _CLOSE_RANGE();
  97003. + index += _State(Context, index, 0x01658 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97004. + index += _State(Context, index, 0x0165C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97005. + index += _State(Context, index, 0x01660 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97006. + index += _State(Context, index, 0x01664 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97007. + index += _State(Context, index, 0x01668 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97008. + index += _State(Context, index, 0x0166C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97009. + index += _State(Context, index, 0x01670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97010. + index += _State(Context, index, 0x01674 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97011. + index += _State(Context, index, 0x016A4 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  97012. + index += _State(Context, index, 0x016AC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97013. + index += _State(Context, index, 0x016A8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  97014. + index += _State(Context, index, 0x01720 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
  97015. + index += _State(Context, index, 0x01740 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
  97016. + index += _State(Context, index, 0x01760 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
  97017. + index += _CLOSE_RANGE();
  97018. +
  97019. + /* Semaphore/stall. */
  97020. + index += _SemaphoreStall(Context, index);
  97021. +#endif
  97022. +
  97023. + /**************************************************************************/
  97024. + /* Link to another address. ***********************************************/
  97025. +
  97026. + Context->linkIndex3D = index;
  97027. +
  97028. + if (buffer != gcvNULL)
  97029. + {
  97030. + buffer[index + 0]
  97031. + = ((((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)))
  97032. + | ((((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)));
  97033. +
  97034. + buffer[index + 1]
  97035. + = 0;
  97036. + }
  97037. +
  97038. + index += 2;
  97039. +
  97040. + /* Store the end of the context buffer. */
  97041. + Context->bufferSize = index * gcmSIZEOF(gctUINT32);
  97042. +
  97043. +
  97044. + /**************************************************************************/
  97045. + /* Pipe switch for the case where neither 2D nor 3D are used. *************/
  97046. +
  97047. + /* Store the 3D entry index. */
  97048. + Context->entryOffsetXDFrom2D = index * gcmSIZEOF(gctUINT32);
  97049. +
  97050. + /* Flush 2D pipe. */
  97051. + index += _FlushPipe(Context, index, gcvPIPE_2D);
  97052. +
  97053. + /* Switch to 3D pipe. */
  97054. + index += _SwitchPipe(Context, index, gcvPIPE_3D);
  97055. +
  97056. + /* Store the location of the link. */
  97057. + Context->linkIndexXD = index;
  97058. +
  97059. + if (buffer != gcvNULL)
  97060. + {
  97061. + buffer[index + 0]
  97062. + = ((((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)))
  97063. + | ((((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)));
  97064. +
  97065. + buffer[index + 1]
  97066. + = 0;
  97067. + }
  97068. +
  97069. + index += 2;
  97070. +
  97071. +
  97072. + /**************************************************************************/
  97073. + /* Save size for buffer. **************************************************/
  97074. +
  97075. + Context->totalSize = index * gcmSIZEOF(gctUINT32);
  97076. +
  97077. +
  97078. + /* Success. */
  97079. + return gcvSTATUS_OK;
  97080. +}
  97081. +
  97082. +static gceSTATUS
  97083. +_DestroyContext(
  97084. + IN gckCONTEXT Context
  97085. + )
  97086. +{
  97087. + gceSTATUS status = gcvSTATUS_OK;
  97088. +
  97089. + if (Context != gcvNULL)
  97090. + {
  97091. + gcsCONTEXT_PTR bufferHead;
  97092. +
  97093. + /* Free context buffers. */
  97094. + for (bufferHead = Context->buffer; Context->buffer != gcvNULL;)
  97095. + {
  97096. + /* Get a shortcut to the current buffer. */
  97097. + gcsCONTEXT_PTR buffer = Context->buffer;
  97098. +
  97099. + /* Get the next buffer. */
  97100. + gcsCONTEXT_PTR next = buffer->next;
  97101. +
  97102. + /* Last item? */
  97103. + if (next == bufferHead)
  97104. + {
  97105. + next = gcvNULL;
  97106. + }
  97107. +
  97108. + /* Destroy the signal. */
  97109. + if (buffer->signal != gcvNULL)
  97110. + {
  97111. + gcmkONERROR(gckOS_DestroySignal(
  97112. + Context->os, buffer->signal
  97113. + ));
  97114. +
  97115. + buffer->signal = gcvNULL;
  97116. + }
  97117. +
  97118. + /* Free state delta map. */
  97119. + if (buffer->logical != gcvNULL)
  97120. + {
  97121. +#if gcdVIRTUAL_COMMAND_BUFFER
  97122. + gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer(
  97123. + Context->hardware->kernel->eventObj,
  97124. + Context->totalSize,
  97125. + buffer->physical,
  97126. + buffer->logical,
  97127. + gcvKERNEL_PIXEL
  97128. + ));
  97129. +
  97130. +#else
  97131. + gcmkONERROR(gckEVENT_FreeContiguousMemory(
  97132. + Context->hardware->kernel->eventObj,
  97133. + Context->totalSize,
  97134. + buffer->physical,
  97135. + buffer->logical,
  97136. + gcvKERNEL_PIXEL
  97137. + ));
  97138. +#endif
  97139. +
  97140. + buffer->logical = gcvNULL;
  97141. + }
  97142. +
  97143. + /* Free context buffer. */
  97144. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, buffer));
  97145. +
  97146. + /* Remove from the list. */
  97147. + Context->buffer = next;
  97148. + }
  97149. +
  97150. +#if gcdSECURE_USER
  97151. + /* Free the hint array. */
  97152. + if (Context->hint != gcvNULL)
  97153. + {
  97154. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->hint));
  97155. + }
  97156. +#endif
  97157. + /* Free record array copy. */
  97158. + if (Context->recordArray != gcvNULL)
  97159. + {
  97160. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->recordArray));
  97161. + }
  97162. +
  97163. + /* Free the state mapping. */
  97164. + if (Context->map != gcvNULL)
  97165. + {
  97166. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->map));
  97167. + }
  97168. +
  97169. + /* Mark the gckCONTEXT object as unknown. */
  97170. + Context->object.type = gcvOBJ_UNKNOWN;
  97171. +
  97172. + /* Free the gckCONTEXT object. */
  97173. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context));
  97174. + }
  97175. +
  97176. +OnError:
  97177. + return status;
  97178. +}
  97179. +
  97180. +
  97181. +/******************************************************************************\
  97182. +**************************** Context Management API ****************************
  97183. +\******************************************************************************/
  97184. +
  97185. +/******************************************************************************\
  97186. +**
  97187. +** gckCONTEXT_Construct
  97188. +**
  97189. +** Construct a new gckCONTEXT object.
  97190. +**
  97191. +** INPUT:
  97192. +**
  97193. +** gckOS Os
  97194. +** Pointer to gckOS object.
  97195. +**
  97196. +** gctUINT32 ProcessID
  97197. +** Current process ID.
  97198. +**
  97199. +** gckHARDWARE Hardware
  97200. +** Pointer to gckHARDWARE object.
  97201. +**
  97202. +** OUTPUT:
  97203. +**
  97204. +** gckCONTEXT * Context
  97205. +** Pointer to a variable thet will receive the gckCONTEXT object
  97206. +** pointer.
  97207. +*/
  97208. +gceSTATUS
  97209. +gckCONTEXT_Construct(
  97210. + IN gckOS Os,
  97211. + IN gckHARDWARE Hardware,
  97212. + IN gctUINT32 ProcessID,
  97213. + OUT gckCONTEXT * Context
  97214. + )
  97215. +{
  97216. + gceSTATUS status;
  97217. + gckCONTEXT context = gcvNULL;
  97218. + gctSIZE_T allocationSize;
  97219. + gctUINT i;
  97220. + gctPOINTER pointer = gcvNULL;
  97221. +
  97222. + gcmkHEADER_ARG("Os=0x%08X Hardware=0x%08X", Os, Hardware);
  97223. +
  97224. + /* Verify the arguments. */
  97225. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  97226. + gcmkVERIFY_ARGUMENT(Context != gcvNULL);
  97227. +
  97228. +
  97229. + /**************************************************************************/
  97230. + /* Allocate and initialize basic fields of gckCONTEXT. ********************/
  97231. +
  97232. + /* The context object size. */
  97233. + allocationSize = gcmSIZEOF(struct _gckCONTEXT);
  97234. +
  97235. + /* Allocate the object. */
  97236. + gcmkONERROR(gckOS_Allocate(
  97237. + Os, allocationSize, &pointer
  97238. + ));
  97239. +
  97240. + context = pointer;
  97241. +
  97242. + /* Reset the entire object. */
  97243. + gcmkONERROR(gckOS_ZeroMemory(context, allocationSize));
  97244. +
  97245. + /* Initialize the gckCONTEXT object. */
  97246. + context->object.type = gcvOBJ_CONTEXT;
  97247. + context->os = Os;
  97248. + context->hardware = Hardware;
  97249. +
  97250. +
  97251. +#if defined(VIVANTE_NO_3D)
  97252. + context->entryPipe = gcvPIPE_2D;
  97253. + context->exitPipe = gcvPIPE_2D;
  97254. +#elif gcdCMD_NO_2D_CONTEXT
  97255. + context->entryPipe = gcvPIPE_3D;
  97256. + context->exitPipe = gcvPIPE_3D;
  97257. +#else
  97258. + context->entryPipe
  97259. + = (((((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)))))) )
  97260. + ? gcvPIPE_2D
  97261. + : gcvPIPE_3D;
  97262. + context->exitPipe = gcvPIPE_3D;
  97263. +#endif
  97264. +
  97265. + /* Get the command buffer requirements. */
  97266. + gcmkONERROR(gckHARDWARE_QueryCommandBuffer(
  97267. + Hardware,
  97268. + &context->alignment,
  97269. + &context->reservedHead,
  97270. + &context->reservedTail
  97271. + ));
  97272. +
  97273. + /* Mark the context as dirty to force loading of the entire state table
  97274. + the first time. */
  97275. + context->dirty = gcvTRUE;
  97276. +
  97277. +
  97278. + /**************************************************************************/
  97279. + /* Get the size of the context buffer. ************************************/
  97280. +
  97281. + gcmkONERROR(_InitializeContextBuffer(context));
  97282. +
  97283. +
  97284. + /**************************************************************************/
  97285. + /* Compute the size of the record array. **********************************/
  97286. +
  97287. + context->recordArraySize
  97288. + = gcmSIZEOF(gcsSTATE_DELTA_RECORD) * context->stateCount;
  97289. +
  97290. +
  97291. + if (context->stateCount > 0)
  97292. + {
  97293. + /**************************************************************************/
  97294. + /* Allocate and reset the state mapping table. ****************************/
  97295. +
  97296. + /* Allocate the state mapping table. */
  97297. + gcmkONERROR(gckOS_Allocate(
  97298. + Os,
  97299. + gcmSIZEOF(gcsSTATE_MAP) * context->stateCount,
  97300. + &pointer
  97301. + ));
  97302. +
  97303. + context->map = pointer;
  97304. +
  97305. + /* Zero the state mapping table. */
  97306. + gcmkONERROR(gckOS_ZeroMemory(
  97307. + context->map, gcmSIZEOF(gcsSTATE_MAP) * context->stateCount
  97308. + ));
  97309. +
  97310. +
  97311. + /**************************************************************************/
  97312. + /* Allocate the hint array. ***********************************************/
  97313. +
  97314. +#if gcdSECURE_USER
  97315. + /* Allocate hints. */
  97316. + gcmkONERROR(gckOS_Allocate(
  97317. + Os,
  97318. + gcmSIZEOF(gctBOOL) * context->stateCount,
  97319. + &pointer
  97320. + ));
  97321. +
  97322. + context->hint = pointer;
  97323. +#endif
  97324. + }
  97325. +
  97326. + /**************************************************************************/
  97327. + /* Allocate the context and state delta buffers. **************************/
  97328. +
  97329. + for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i += 1)
  97330. + {
  97331. + /* Allocate a context buffer. */
  97332. + gcsCONTEXT_PTR buffer;
  97333. +
  97334. + /* Allocate the context buffer structure. */
  97335. + gcmkONERROR(gckOS_Allocate(
  97336. + Os,
  97337. + gcmSIZEOF(gcsCONTEXT),
  97338. + &pointer
  97339. + ));
  97340. +
  97341. + buffer = pointer;
  97342. +
  97343. + /* Reset the context buffer structure. */
  97344. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  97345. + buffer, gcmSIZEOF(gcsCONTEXT)
  97346. + ));
  97347. +
  97348. + /* Append to the list. */
  97349. + if (context->buffer == gcvNULL)
  97350. + {
  97351. + buffer->next = buffer;
  97352. + context->buffer = buffer;
  97353. + }
  97354. + else
  97355. + {
  97356. + buffer->next = context->buffer->next;
  97357. + context->buffer->next = buffer;
  97358. + }
  97359. +
  97360. + /* Set the number of delta in the order of creation. */
  97361. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  97362. + buffer->num = i;
  97363. +#endif
  97364. +
  97365. + /* Create the busy signal. */
  97366. + gcmkONERROR(gckOS_CreateSignal(
  97367. + Os, gcvFALSE, &buffer->signal
  97368. + ));
  97369. +
  97370. + /* Set the signal, buffer is currently not busy. */
  97371. + gcmkONERROR(gckOS_Signal(
  97372. + Os, buffer->signal, gcvTRUE
  97373. + ));
  97374. +
  97375. + /* Create a new physical context buffer. */
  97376. +#if gcdVIRTUAL_COMMAND_BUFFER
  97377. + gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
  97378. + context->hardware->kernel,
  97379. + gcvFALSE,
  97380. + &context->totalSize,
  97381. + &buffer->physical,
  97382. + &pointer
  97383. + ));
  97384. +
  97385. +#else
  97386. + gcmkONERROR(gckOS_AllocateContiguous(
  97387. + Os,
  97388. + gcvFALSE,
  97389. + &context->totalSize,
  97390. + &buffer->physical,
  97391. + &pointer
  97392. + ));
  97393. +#endif
  97394. +
  97395. + buffer->logical = pointer;
  97396. +
  97397. + /* Set gckEVENT object pointer. */
  97398. + buffer->eventObj = Hardware->kernel->eventObj;
  97399. +
  97400. + /* Set the pointers to the LINK commands. */
  97401. + if (context->linkIndex2D != 0)
  97402. + {
  97403. + buffer->link2D = &buffer->logical[context->linkIndex2D];
  97404. + }
  97405. +
  97406. + if (context->linkIndex3D != 0)
  97407. + {
  97408. + buffer->link3D = &buffer->logical[context->linkIndex3D];
  97409. + }
  97410. +
  97411. + if (context->linkIndexXD != 0)
  97412. + {
  97413. + gctPOINTER xdLink;
  97414. + gctUINT8_PTR xdEntryLogical;
  97415. + gctSIZE_T xdEntrySize;
  97416. + gctSIZE_T linkBytes;
  97417. +
  97418. + /* Determine LINK parameters. */
  97419. + xdLink
  97420. + = &buffer->logical[context->linkIndexXD];
  97421. +
  97422. + xdEntryLogical
  97423. + = (gctUINT8_PTR) buffer->logical
  97424. + + context->entryOffsetXDFrom3D;
  97425. +
  97426. + xdEntrySize
  97427. + = context->bufferSize
  97428. + - context->entryOffsetXDFrom3D;
  97429. +
  97430. + /* Query LINK size. */
  97431. + gcmkONERROR(gckHARDWARE_Link(
  97432. + Hardware, gcvNULL, gcvNULL, 0, &linkBytes
  97433. + ));
  97434. +
  97435. + /* Generate a LINK. */
  97436. + gcmkONERROR(gckHARDWARE_Link(
  97437. + Hardware,
  97438. + xdLink,
  97439. + xdEntryLogical,
  97440. + xdEntrySize,
  97441. + &linkBytes
  97442. + ));
  97443. + }
  97444. + }
  97445. +
  97446. +
  97447. + /**************************************************************************/
  97448. + /* Initialize the context buffers. ****************************************/
  97449. +
  97450. + /* Initialize the current context buffer. */
  97451. + gcmkONERROR(_InitializeContextBuffer(context));
  97452. +
  97453. + /* Make all created contexts equal. */
  97454. + {
  97455. + gcsCONTEXT_PTR currContext, tempContext;
  97456. +
  97457. + /* Set the current context buffer. */
  97458. + currContext = context->buffer;
  97459. +
  97460. + /* Get the next context buffer. */
  97461. + tempContext = currContext->next;
  97462. +
  97463. + /* Loop through all buffers. */
  97464. + while (tempContext != currContext)
  97465. + {
  97466. + if (tempContext == gcvNULL)
  97467. + {
  97468. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  97469. + }
  97470. +
  97471. + /* Copy the current context. */
  97472. + gckOS_MemCopy(
  97473. + tempContext->logical,
  97474. + currContext->logical,
  97475. + context->totalSize
  97476. + );
  97477. +
  97478. + /* Get the next context buffer. */
  97479. + tempContext = tempContext->next;
  97480. + }
  97481. + }
  97482. +
  97483. + /* Return pointer to the gckCONTEXT object. */
  97484. + *Context = context;
  97485. +
  97486. + /* Success. */
  97487. + gcmkFOOTER_ARG("*Context=0x%08X", *Context);
  97488. + return gcvSTATUS_OK;
  97489. +
  97490. +OnError:
  97491. + /* Roll back on error. */
  97492. + gcmkVERIFY_OK(_DestroyContext(context));
  97493. +
  97494. + /* Return the status. */
  97495. + gcmkFOOTER();
  97496. + return status;
  97497. +}
  97498. +
  97499. +/******************************************************************************\
  97500. +**
  97501. +** gckCONTEXT_Destroy
  97502. +**
  97503. +** Destroy a gckCONTEXT object.
  97504. +**
  97505. +** INPUT:
  97506. +**
  97507. +** gckCONTEXT Context
  97508. +** Pointer to an gckCONTEXT object.
  97509. +**
  97510. +** OUTPUT:
  97511. +**
  97512. +** Nothing.
  97513. +*/
  97514. +gceSTATUS
  97515. +gckCONTEXT_Destroy(
  97516. + IN gckCONTEXT Context
  97517. + )
  97518. +{
  97519. + gceSTATUS status;
  97520. +
  97521. + gcmkHEADER_ARG("Context=0x%08X", Context);
  97522. +
  97523. + /* Verify the arguments. */
  97524. + gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
  97525. +
  97526. + /* Destroy the context and all related objects. */
  97527. + status = _DestroyContext(Context);
  97528. +
  97529. + /* Success. */
  97530. + gcmkFOOTER_NO();
  97531. + return status;
  97532. +}
  97533. +
  97534. +/******************************************************************************\
  97535. +**
  97536. +** gckCONTEXT_Update
  97537. +**
  97538. +** Merge all pending state delta buffers into the current context buffer.
  97539. +**
  97540. +** INPUT:
  97541. +**
  97542. +** gckCONTEXT Context
  97543. +** Pointer to an gckCONTEXT object.
  97544. +**
  97545. +** gctUINT32 ProcessID
  97546. +** Current process ID.
  97547. +**
  97548. +** gcsSTATE_DELTA_PTR StateDelta
  97549. +** Pointer to the state delta.
  97550. +**
  97551. +** OUTPUT:
  97552. +**
  97553. +** Nothing.
  97554. +*/
  97555. +gceSTATUS
  97556. +gckCONTEXT_Update(
  97557. + IN gckCONTEXT Context,
  97558. + IN gctUINT32 ProcessID,
  97559. + IN gcsSTATE_DELTA_PTR StateDelta
  97560. + )
  97561. +{
  97562. +#ifndef VIVANTE_NO_3D
  97563. + gceSTATUS status = gcvSTATUS_OK;
  97564. + gcsSTATE_DELTA _stateDelta;
  97565. + gckKERNEL kernel;
  97566. + gcsCONTEXT_PTR buffer;
  97567. + gcsSTATE_MAP_PTR map;
  97568. + gctBOOL needCopy = gcvFALSE;
  97569. + gcsSTATE_DELTA_PTR nDelta;
  97570. + gcsSTATE_DELTA_PTR uDelta = gcvNULL;
  97571. + gcsSTATE_DELTA_PTR kDelta = gcvNULL;
  97572. + gcsSTATE_DELTA_RECORD_PTR record;
  97573. + gcsSTATE_DELTA_RECORD_PTR recordArray = gcvNULL;
  97574. + gctUINT elementCount;
  97575. + gctUINT address;
  97576. + gctUINT32 mask;
  97577. + gctUINT32 data;
  97578. + gctUINT index;
  97579. + gctUINT i, j;
  97580. +
  97581. +#if gcdSECURE_USER
  97582. + gcskSECURE_CACHE_PTR cache;
  97583. +#endif
  97584. +
  97585. + gcmkHEADER_ARG(
  97586. + "Context=0x%08X ProcessID=%d StateDelta=0x%08X",
  97587. + Context, ProcessID, StateDelta
  97588. + );
  97589. +
  97590. + /* Verify the arguments. */
  97591. + gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
  97592. +
  97593. + /* Get a shortcut to the kernel object. */
  97594. + kernel = Context->hardware->kernel;
  97595. +
  97596. + /* Check wehther we need to copy the structures or not. */
  97597. + gcmkONERROR(gckOS_QueryNeedCopy(Context->os, ProcessID, &needCopy));
  97598. +
  97599. + /* Allocate the copy buffer for the user record array. */
  97600. + if (needCopy && (Context->recordArray == gcvNULL))
  97601. + {
  97602. + /* Allocate the buffer. */
  97603. + gcmkONERROR(gckOS_Allocate(
  97604. + Context->os,
  97605. + Context->recordArraySize,
  97606. + (gctPOINTER *) &Context->recordArray
  97607. + ));
  97608. + }
  97609. +
  97610. + /* Get the current context buffer. */
  97611. + buffer = Context->buffer;
  97612. +
  97613. + /* Wait until the context buffer becomes available; this will
  97614. + also reset the signal and mark the buffer as busy. */
  97615. + gcmkONERROR(gckOS_WaitSignal(
  97616. + Context->os, buffer->signal, gcvINFINITE
  97617. + ));
  97618. +
  97619. +#if gcdSECURE_USER
  97620. + /* Get the cache form the database. */
  97621. + gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
  97622. +#endif
  97623. +
  97624. +#if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && !defined(VIVANTE_NO_3D)
  97625. + /* Update current context token. */
  97626. + buffer->logical[Context->map[0x0E14].index]
  97627. + = gcmPTR2INT(Context);
  97628. +#endif
  97629. +
  97630. + /* Are there any pending deltas? */
  97631. + if (buffer->deltaCount != 0)
  97632. + {
  97633. + /* Get the state map. */
  97634. + map = Context->map;
  97635. +
  97636. + /* Get the first delta item. */
  97637. + uDelta = buffer->delta;
  97638. +
  97639. + /* Reset the vertex stream count. */
  97640. + elementCount = 0;
  97641. +
  97642. + /* Merge all pending deltas. */
  97643. + for (i = 0; i < buffer->deltaCount; i += 1)
  97644. + {
  97645. + /* Get access to the state delta. */
  97646. + gcmkONERROR(gckKERNEL_OpenUserData(
  97647. + kernel, needCopy,
  97648. + &_stateDelta,
  97649. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  97650. + (gctPOINTER *) &kDelta
  97651. + ));
  97652. +
  97653. + /* Get access to the state records. */
  97654. + gcmkONERROR(gckKERNEL_OpenUserData(
  97655. + kernel, needCopy,
  97656. + Context->recordArray,
  97657. + gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
  97658. + (gctPOINTER *) &recordArray
  97659. + ));
  97660. +
  97661. + /* Merge all pending states. */
  97662. + for (j = 0; j < kDelta->recordCount; j += 1)
  97663. + {
  97664. + if (j >= Context->stateCount)
  97665. + {
  97666. + break;
  97667. + }
  97668. +
  97669. + /* Get the current state record. */
  97670. + record = &recordArray[j];
  97671. +
  97672. + /* Get the state address. */
  97673. + address = record->address;
  97674. +
  97675. + /* Make sure the state is a part of the mapping table. */
  97676. + if (address >= Context->stateCount)
  97677. + {
  97678. + gcmkTRACE(
  97679. + gcvLEVEL_ERROR,
  97680. + "%s(%d): State 0x%04X is not mapped.\n",
  97681. + __FUNCTION__, __LINE__,
  97682. + address
  97683. + );
  97684. +
  97685. + continue;
  97686. + }
  97687. +
  97688. + /* Get the state index. */
  97689. + index = map[address].index;
  97690. +
  97691. + /* Skip the state if not mapped. */
  97692. + if (index == 0)
  97693. + {
  97694. +#if gcdDEBUG
  97695. + if ((address != 0x0594)
  97696. + && (address != 0x0E00)
  97697. + && (address != 0x0E03)
  97698. + )
  97699. + {
  97700. +#endif
  97701. + gcmkTRACE(
  97702. + gcvLEVEL_ERROR,
  97703. + "%s(%d): State 0x%04X is not mapped.\n",
  97704. + __FUNCTION__, __LINE__,
  97705. + address
  97706. + );
  97707. +#if gcdDEBUG
  97708. + }
  97709. +#endif
  97710. + continue;
  97711. + }
  97712. +
  97713. + /* Get the data mask. */
  97714. + mask = record->mask;
  97715. +
  97716. + /* Masked states that are being completly reset or regular states. */
  97717. + if ((mask == 0) || (mask == ~0U))
  97718. + {
  97719. + /* Get the new data value. */
  97720. + data = record->data;
  97721. +
  97722. + /* Process special states. */
  97723. + if (address == 0x0595)
  97724. + {
  97725. + /* Force auto-disable to be disabled. */
  97726. + 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)));
  97727. + 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)));
  97728. + 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)));
  97729. + }
  97730. +
  97731. +#if gcdSECURE_USER
  97732. + /* Do we need to convert the logical address? */
  97733. + if (Context->hint[address])
  97734. + {
  97735. + /* Map handle into physical address. */
  97736. + gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
  97737. + kernel, cache, (gctPOINTER) &data
  97738. + ));
  97739. + }
  97740. +#endif
  97741. +
  97742. + /* Set new data. */
  97743. + buffer->logical[index] = data;
  97744. + }
  97745. +
  97746. + /* Masked states that are being set partially. */
  97747. + else
  97748. + {
  97749. + buffer->logical[index]
  97750. + = (~mask & buffer->logical[index])
  97751. + | (mask & record->data);
  97752. + }
  97753. + }
  97754. +
  97755. + /* Get the element count. */
  97756. + if (kDelta->elementCount != 0)
  97757. + {
  97758. + elementCount = kDelta->elementCount;
  97759. + }
  97760. +
  97761. + /* Dereference delta. */
  97762. + kDelta->refCount -= 1;
  97763. + gcmkASSERT(kDelta->refCount >= 0);
  97764. +
  97765. + /* Get the next state delta. */
  97766. + nDelta = gcmUINT64_TO_PTR(kDelta->next);
  97767. +
  97768. + /* Get access to the state records. */
  97769. + gcmkONERROR(gckKERNEL_CloseUserData(
  97770. + kernel, needCopy,
  97771. + gcvFALSE,
  97772. + gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
  97773. + (gctPOINTER *) &recordArray
  97774. + ));
  97775. +
  97776. + /* Close access to the current state delta. */
  97777. + gcmkONERROR(gckKERNEL_CloseUserData(
  97778. + kernel, needCopy,
  97779. + gcvTRUE,
  97780. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  97781. + (gctPOINTER *) &kDelta
  97782. + ));
  97783. +
  97784. + /* Update the user delta pointer. */
  97785. + uDelta = nDelta;
  97786. + }
  97787. +
  97788. + /* Hardware disables all input streams when the stream 0 is programmed,
  97789. + it then reenables those streams that were explicitely programmed by
  97790. + the software. Because of this we cannot program the entire array of
  97791. + values, otherwise we'll get all streams reenabled, but rather program
  97792. + only those that are actully needed by the software. */
  97793. + if (elementCount != 0)
  97794. + {
  97795. + gctUINT base;
  97796. + gctUINT nopCount;
  97797. + gctUINT32_PTR nop;
  97798. + gctUINT fe2vsCount = 12;
  97799. +
  97800. + 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)))))) ))
  97801. + {
  97802. + fe2vsCount = 16;
  97803. + }
  97804. +
  97805. + /* Determine the base index of the vertex stream array. */
  97806. + base = map[0x0180].index;
  97807. +
  97808. + /* Set the proper state count. */
  97809. + buffer->logical[base - 1]
  97810. + = ((((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)));
  97811. +
  97812. + /* Determine the number of NOP commands. */
  97813. + nopCount
  97814. + = (fe2vsCount / 2)
  97815. + - (elementCount / 2);
  97816. +
  97817. + /* Determine the location of the first NOP. */
  97818. + nop = &buffer->logical[base + (elementCount | 1)];
  97819. +
  97820. + /* Fill the unused space with NOPs. */
  97821. + for (i = 0; i < nopCount; i += 1)
  97822. + {
  97823. + if (nop >= buffer->logical + Context->totalSize)
  97824. + {
  97825. + break;
  97826. + }
  97827. +
  97828. + /* Generate a NOP command. */
  97829. + *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)));
  97830. +
  97831. + /* Advance. */
  97832. + nop += 2;
  97833. + }
  97834. + }
  97835. +
  97836. + /* Reset pending deltas. */
  97837. + buffer->deltaCount = 0;
  97838. + buffer->delta = gcvNULL;
  97839. + }
  97840. +
  97841. + /* Set state delta user pointer. */
  97842. + uDelta = StateDelta;
  97843. +
  97844. + /* Get access to the state delta. */
  97845. + gcmkONERROR(gckKERNEL_OpenUserData(
  97846. + kernel, needCopy,
  97847. + &_stateDelta,
  97848. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  97849. + (gctPOINTER *) &kDelta
  97850. + ));
  97851. +
  97852. + /* State delta cannot be attached to anything yet. */
  97853. + if (kDelta->refCount != 0)
  97854. + {
  97855. + gcmkTRACE(
  97856. + gcvLEVEL_ERROR,
  97857. + "%s(%d): kDelta->refCount = %d (has to be 0).\n",
  97858. + __FUNCTION__, __LINE__,
  97859. + kDelta->refCount
  97860. + );
  97861. + }
  97862. +
  97863. + /* Attach to all contexts. */
  97864. + buffer = Context->buffer;
  97865. +
  97866. + do
  97867. + {
  97868. + /* Attach to the context if nothing is attached yet. If a delta
  97869. + is allready attached, all we need to do is to increment
  97870. + the number of deltas in the context. */
  97871. + if (buffer->delta == gcvNULL)
  97872. + {
  97873. + buffer->delta = uDelta;
  97874. + }
  97875. +
  97876. + /* Update reference count. */
  97877. + kDelta->refCount += 1;
  97878. +
  97879. + /* Update counters. */
  97880. + buffer->deltaCount += 1;
  97881. +
  97882. + /* Get the next context buffer. */
  97883. + buffer = buffer->next;
  97884. +
  97885. + if (buffer == gcvNULL)
  97886. + {
  97887. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  97888. + }
  97889. + }
  97890. + while (Context->buffer != buffer);
  97891. +
  97892. + /* Close access to the current state delta. */
  97893. + gcmkONERROR(gckKERNEL_CloseUserData(
  97894. + kernel, needCopy,
  97895. + gcvTRUE,
  97896. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  97897. + (gctPOINTER *) &kDelta
  97898. + ));
  97899. +
  97900. + /* Schedule an event to mark the context buffer as available. */
  97901. + gcmkONERROR(gckEVENT_Signal(
  97902. + buffer->eventObj, buffer->signal, gcvKERNEL_PIXEL
  97903. + ));
  97904. +
  97905. + /* Advance to the next context buffer. */
  97906. + Context->buffer = buffer->next;
  97907. +
  97908. + /* Return the status. */
  97909. + gcmkFOOTER();
  97910. + return gcvSTATUS_OK;
  97911. +
  97912. +OnError:
  97913. + /* Get access to the state records. */
  97914. + if (kDelta != gcvNULL)
  97915. + {
  97916. + gcmkVERIFY_OK(gckKERNEL_CloseUserData(
  97917. + kernel, needCopy,
  97918. + gcvFALSE,
  97919. + gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
  97920. + (gctPOINTER *) &recordArray
  97921. + ));
  97922. + }
  97923. +
  97924. + /* Close access to the current state delta. */
  97925. + gcmkVERIFY_OK(gckKERNEL_CloseUserData(
  97926. + kernel, needCopy,
  97927. + gcvTRUE,
  97928. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  97929. + (gctPOINTER *) &kDelta
  97930. + ));
  97931. +
  97932. + /* Return the status. */
  97933. + gcmkFOOTER();
  97934. + return status;
  97935. +#else
  97936. + return gcvSTATUS_OK;
  97937. +#endif
  97938. +}
  97939. +
  97940. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h
  97941. --- linux-3.14.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h 1969-12-31 18:00:00.000000000 -0600
  97942. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h 2014-12-08 00:31:53.460418001 -0600
  97943. @@ -0,0 +1,157 @@
  97944. +/****************************************************************************
  97945. +*
  97946. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  97947. +*
  97948. +* This program is free software; you can redistribute it and/or modify
  97949. +* it under the terms of the GNU General Public License as published by
  97950. +* the Free Software Foundation; either version 2 of the license, or
  97951. +* (at your option) any later version.
  97952. +*
  97953. +* This program is distributed in the hope that it will be useful,
  97954. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  97955. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  97956. +* GNU General Public License for more details.
  97957. +*
  97958. +* You should have received a copy of the GNU General Public License
  97959. +* along with this program; if not write to the Free Software
  97960. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  97961. +*
  97962. +*****************************************************************************/
  97963. +
  97964. +
  97965. +#ifndef __gc_hal_kernel_context_h_
  97966. +#define __gc_hal_kernel_context_h_
  97967. +
  97968. +#include "gc_hal_kernel_buffer.h"
  97969. +
  97970. +#ifdef __cplusplus
  97971. +extern "C" {
  97972. +#endif
  97973. +
  97974. +/* Maps state locations within the context buffer. */
  97975. +typedef struct _gcsSTATE_MAP * gcsSTATE_MAP_PTR;
  97976. +typedef struct _gcsSTATE_MAP
  97977. +{
  97978. + /* Index of the state in the context buffer. */
  97979. + gctUINT index;
  97980. +
  97981. + /* State mask. */
  97982. + gctUINT32 mask;
  97983. +}
  97984. +gcsSTATE_MAP;
  97985. +
  97986. +/* Context buffer. */
  97987. +typedef struct _gcsCONTEXT * gcsCONTEXT_PTR;
  97988. +typedef struct _gcsCONTEXT
  97989. +{
  97990. + /* For debugging: the number of context buffer in the order of creation. */
  97991. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  97992. + gctUINT num;
  97993. +#endif
  97994. +
  97995. + /* Pointer to gckEVENT object. */
  97996. + gckEVENT eventObj;
  97997. +
  97998. + /* Context busy signal. */
  97999. + gctSIGNAL signal;
  98000. +
  98001. + /* Physical address of the context buffer. */
  98002. + gctPHYS_ADDR physical;
  98003. +
  98004. + /* Logical address of the context buffer. */
  98005. + gctUINT32_PTR logical;
  98006. +
  98007. + /* Pointer to the LINK commands. */
  98008. + gctPOINTER link2D;
  98009. + gctPOINTER link3D;
  98010. +
  98011. + /* The number of pending state deltas. */
  98012. + gctUINT deltaCount;
  98013. +
  98014. + /* Pointer to the first delta to be applied. */
  98015. + gcsSTATE_DELTA_PTR delta;
  98016. +
  98017. + /* Next context buffer. */
  98018. + gcsCONTEXT_PTR next;
  98019. +}
  98020. +gcsCONTEXT;
  98021. +
  98022. +/* gckCONTEXT structure that hold the current context. */
  98023. +struct _gckCONTEXT
  98024. +{
  98025. + /* Object. */
  98026. + gcsOBJECT object;
  98027. +
  98028. + /* Pointer to gckOS object. */
  98029. + gckOS os;
  98030. +
  98031. + /* Pointer to gckHARDWARE object. */
  98032. + gckHARDWARE hardware;
  98033. +
  98034. + /* Command buffer alignment. */
  98035. + gctSIZE_T alignment;
  98036. + gctSIZE_T reservedHead;
  98037. + gctSIZE_T reservedTail;
  98038. +
  98039. + /* Context buffer metrics. */
  98040. + gctSIZE_T stateCount;
  98041. + gctSIZE_T totalSize;
  98042. + gctSIZE_T bufferSize;
  98043. + gctUINT32 linkIndex2D;
  98044. + gctUINT32 linkIndex3D;
  98045. + gctUINT32 linkIndexXD;
  98046. + gctUINT32 entryOffset3D;
  98047. + gctUINT32 entryOffsetXDFrom2D;
  98048. + gctUINT32 entryOffsetXDFrom3D;
  98049. +
  98050. + /* Dirty flags. */
  98051. + gctBOOL dirty;
  98052. + gctBOOL dirty2D;
  98053. + gctBOOL dirty3D;
  98054. + gcsCONTEXT_PTR dirtyBuffer;
  98055. +
  98056. + /* State mapping. */
  98057. + gcsSTATE_MAP_PTR map;
  98058. +
  98059. + /* List of context buffers. */
  98060. + gcsCONTEXT_PTR buffer;
  98061. +
  98062. + /* A copy of the user record array. */
  98063. + gctUINT recordArraySize;
  98064. + gcsSTATE_DELTA_RECORD_PTR recordArray;
  98065. +
  98066. + /* Requested pipe select for context. */
  98067. + gcePIPE_SELECT entryPipe;
  98068. + gcePIPE_SELECT exitPipe;
  98069. +
  98070. + /* Variables used for building state buffer. */
  98071. + gctUINT32 lastAddress;
  98072. + gctSIZE_T lastSize;
  98073. + gctUINT32 lastIndex;
  98074. + gctBOOL lastFixed;
  98075. +
  98076. + /* Hint array. */
  98077. +#if gcdSECURE_USER
  98078. + gctBOOL_PTR hint;
  98079. +#endif
  98080. +
  98081. +#if VIVANTE_PROFILER_CONTEXT
  98082. + gcsPROFILER_COUNTERS latestProfiler;
  98083. + gcsPROFILER_COUNTERS histroyProfiler;
  98084. + gctUINT32 prevVSInstCount;
  98085. + gctUINT32 prevVSBranchInstCount;
  98086. + gctUINT32 prevVSTexInstCount;
  98087. + gctUINT32 prevVSVertexCount;
  98088. + gctUINT32 prevPSInstCount;
  98089. + gctUINT32 prevPSBranchInstCount;
  98090. + gctUINT32 prevPSTexInstCount;
  98091. + gctUINT32 prevPSPixelCount;
  98092. +#endif
  98093. +};
  98094. +
  98095. +#ifdef __cplusplus
  98096. +}
  98097. +#endif
  98098. +
  98099. +#endif /* __gc_hal_kernel_context_h_ */
  98100. +
  98101. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
  98102. --- linux-3.14.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c 1969-12-31 18:00:00.000000000 -0600
  98103. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c 2014-12-08 00:31:53.464418001 -0600
  98104. @@ -0,0 +1,7280 @@
  98105. +/****************************************************************************
  98106. +*
  98107. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  98108. +*
  98109. +* This program is free software; you can redistribute it and/or modify
  98110. +* it under the terms of the GNU General Public License as published by
  98111. +* the Free Software Foundation; either version 2 of the license, or
  98112. +* (at your option) any later version.
  98113. +*
  98114. +* This program is distributed in the hope that it will be useful,
  98115. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  98116. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  98117. +* GNU General Public License for more details.
  98118. +*
  98119. +* You should have received a copy of the GNU General Public License
  98120. +* along with this program; if not write to the Free Software
  98121. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  98122. +*
  98123. +*****************************************************************************/
  98124. +
  98125. +
  98126. +#include "gc_hal.h"
  98127. +#include "gc_hal_kernel.h"
  98128. +#if VIVANTE_PROFILER_CONTEXT
  98129. +#include "gc_hal_kernel_context.h"
  98130. +#endif
  98131. +
  98132. +#define _GC_OBJ_ZONE gcvZONE_HARDWARE
  98133. +
  98134. +typedef struct _gcsiDEBUG_REGISTERS * gcsiDEBUG_REGISTERS_PTR;
  98135. +typedef struct _gcsiDEBUG_REGISTERS
  98136. +{
  98137. + gctSTRING module;
  98138. + gctUINT index;
  98139. + gctUINT shift;
  98140. + gctUINT data;
  98141. + gctUINT count;
  98142. + gctUINT32 signature;
  98143. +}
  98144. +gcsiDEBUG_REGISTERS;
  98145. +
  98146. +extern int gpu3DMinClock;
  98147. +/******************************************************************************\
  98148. +********************************* Support Code *********************************
  98149. +\******************************************************************************/
  98150. +static gceSTATUS
  98151. +_ResetGPU(
  98152. + IN gckHARDWARE Hardware,
  98153. + IN gckOS Os,
  98154. + IN gceCORE Core
  98155. + );
  98156. +
  98157. +static gceSTATUS
  98158. +_IdentifyHardware(
  98159. + IN gckOS Os,
  98160. + IN gceCORE Core,
  98161. + OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  98162. + )
  98163. +{
  98164. + gceSTATUS status;
  98165. +
  98166. + gctUINT32 chipIdentity;
  98167. +
  98168. + gctUINT32 streamCount = 0;
  98169. + gctUINT32 registerMax = 0;
  98170. + gctUINT32 threadCount = 0;
  98171. + gctUINT32 shaderCoreCount = 0;
  98172. + gctUINT32 vertexCacheSize = 0;
  98173. + gctUINT32 vertexOutputBufferSize = 0;
  98174. + gctUINT32 pixelPipes = 0;
  98175. + gctUINT32 instructionCount = 0;
  98176. + gctUINT32 numConstants = 0;
  98177. + gctUINT32 bufferSize = 0;
  98178. + gctUINT32 varyingsCount = 0;
  98179. + gctBOOL useHZ;
  98180. +
  98181. + gcmkHEADER_ARG("Os=0x%x", Os);
  98182. +
  98183. + /***************************************************************************
  98184. + ** Get chip ID and revision.
  98185. + */
  98186. +
  98187. + /* Read chip identity register. */
  98188. + gcmkONERROR(
  98189. + gckOS_ReadRegisterEx(Os, Core,
  98190. + 0x00018,
  98191. + &chipIdentity));
  98192. +
  98193. + /* Special case for older graphic cores. */
  98194. + 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))))))))
  98195. + {
  98196. + Identity->chipModel = gcv500;
  98197. + 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)))))) );
  98198. + }
  98199. +
  98200. + else
  98201. + {
  98202. + /* Read chip identity register. */
  98203. + gcmkONERROR(
  98204. + gckOS_ReadRegisterEx(Os, Core,
  98205. + 0x00020,
  98206. + (gctUINT32_PTR) &Identity->chipModel));
  98207. +
  98208. + /* !!!! HACK ALERT !!!! */
  98209. + /* Because people change device IDs without letting software know
  98210. + ** about it - here is the hack to make it all look the same. Only
  98211. + ** for GC400 family. Next time - TELL ME!!! */
  98212. + if (((Identity->chipModel & 0xFF00) == 0x0400)
  98213. + && (Identity->chipModel != 0x0420))
  98214. + {
  98215. + Identity->chipModel = (gceCHIPMODEL) (Identity->chipModel & 0x0400);
  98216. + }
  98217. +
  98218. + /* Read CHIP_REV register. */
  98219. + gcmkONERROR(
  98220. + gckOS_ReadRegisterEx(Os, Core,
  98221. + 0x00024,
  98222. + &Identity->chipRevision));
  98223. +
  98224. + if ((Identity->chipModel == gcv300)
  98225. + && (Identity->chipRevision == 0x2201)
  98226. + )
  98227. + {
  98228. + gctUINT32 chipDate;
  98229. + gctUINT32 chipTime;
  98230. +
  98231. + /* Read date and time registers. */
  98232. + gcmkONERROR(
  98233. + gckOS_ReadRegisterEx(Os, Core,
  98234. + 0x00028,
  98235. + &chipDate));
  98236. +
  98237. + gcmkONERROR(
  98238. + gckOS_ReadRegisterEx(Os, Core,
  98239. + 0x0002C,
  98240. + &chipTime));
  98241. +
  98242. + if ((chipDate == 0x20080814) && (chipTime == 0x12051100))
  98243. + {
  98244. + /* This IP has an ECO; put the correct revision in it. */
  98245. + Identity->chipRevision = 0x1051;
  98246. + }
  98247. + }
  98248. + }
  98249. +
  98250. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98251. + "Identity: chipModel=%X",
  98252. + Identity->chipModel);
  98253. +
  98254. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98255. + "Identity: chipRevision=%X",
  98256. + Identity->chipRevision);
  98257. +
  98258. +
  98259. + /***************************************************************************
  98260. + ** Get chip features.
  98261. + */
  98262. +
  98263. + /* Read chip feature register. */
  98264. + gcmkONERROR(
  98265. + gckOS_ReadRegisterEx(Os, Core,
  98266. + 0x0001C,
  98267. + &Identity->chipFeatures));
  98268. +
  98269. +#ifndef VIVANTE_NO_3D
  98270. + /* Disable fast clear on GC700. */
  98271. + if (Identity->chipModel == gcv700)
  98272. + {
  98273. + Identity->chipFeatures
  98274. + = ((((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)));
  98275. + }
  98276. +#endif
  98277. +
  98278. + if (((Identity->chipModel == gcv500) && (Identity->chipRevision < 2))
  98279. + || ((Identity->chipModel == gcv300) && (Identity->chipRevision < 0x2000))
  98280. + )
  98281. + {
  98282. + /* GC500 rev 1.x and GC300 rev < 2.0 doesn't have these registers. */
  98283. + Identity->chipMinorFeatures = 0;
  98284. + Identity->chipMinorFeatures1 = 0;
  98285. + Identity->chipMinorFeatures2 = 0;
  98286. + Identity->chipMinorFeatures3 = 0;
  98287. + Identity->chipMinorFeatures4 = 0;
  98288. + }
  98289. + else
  98290. + {
  98291. + /* Read chip minor feature register #0. */
  98292. + gcmkONERROR(
  98293. + gckOS_ReadRegisterEx(Os, Core,
  98294. + 0x00034,
  98295. + &Identity->chipMinorFeatures));
  98296. +
  98297. + 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)))))))
  98298. + )
  98299. + {
  98300. + /* Read chip minor featuress register #1. */
  98301. + gcmkONERROR(
  98302. + gckOS_ReadRegisterEx(Os, Core,
  98303. + 0x00074,
  98304. + &Identity->chipMinorFeatures1));
  98305. +
  98306. + /* Read chip minor featuress register #2. */
  98307. + gcmkONERROR(
  98308. + gckOS_ReadRegisterEx(Os, Core,
  98309. + 0x00084,
  98310. + &Identity->chipMinorFeatures2));
  98311. +
  98312. + /*Identity->chipMinorFeatures2 &= ~(0x1 << 3);*/
  98313. +
  98314. + /* Read chip minor featuress register #1. */
  98315. + gcmkONERROR(
  98316. + gckOS_ReadRegisterEx(Os, Core,
  98317. + 0x00088,
  98318. + &Identity->chipMinorFeatures3));
  98319. +
  98320. + /*The BG2 chip has no compression supertiled, and the bit of GCMinorFeature3BugFixes15 is n/a*/
  98321. + if(Identity->chipModel == gcv1000 && Identity->chipRevision == 0x5036)
  98322. + {
  98323. + Identity->chipMinorFeatures3
  98324. + = ((((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)));
  98325. + Identity->chipMinorFeatures3
  98326. + = ((((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)));
  98327. + }
  98328. +
  98329. + /* Read chip minor featuress register #4. */
  98330. + gcmkONERROR(
  98331. + gckOS_ReadRegisterEx(Os, Core,
  98332. + 0x00094,
  98333. + &Identity->chipMinorFeatures4));
  98334. + }
  98335. + else
  98336. + {
  98337. + /* Chip doesn't has minor features register #1 or 2 or 3 or 4. */
  98338. + Identity->chipMinorFeatures1 = 0;
  98339. + Identity->chipMinorFeatures2 = 0;
  98340. + Identity->chipMinorFeatures3 = 0;
  98341. + Identity->chipMinorFeatures4 = 0;
  98342. + }
  98343. + }
  98344. +
  98345. + /* Get the Supertile layout in the hardware. */
  98346. + 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)))))))
  98347. + || ((((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))))))))
  98348. + {
  98349. + Identity->superTileMode = 2;
  98350. + }
  98351. + 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))))))))
  98352. + {
  98353. + Identity->superTileMode = 1;
  98354. + }
  98355. + else
  98356. + {
  98357. + Identity->superTileMode = 0;
  98358. + }
  98359. +
  98360. + /* Exception for GC1000, revision 5035 & GC800, revision 4612 */
  98361. + if (((Identity->chipModel == gcv1000) && ((Identity->chipRevision == 0x5035)
  98362. + || (Identity->chipRevision == 0x5036)
  98363. + || (Identity->chipRevision == 0x5037)))
  98364. + || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612))
  98365. + || ((Identity->chipModel == gcv860) && (Identity->chipRevision == 0x4647)))
  98366. + {
  98367. + Identity->superTileMode = 1;
  98368. + }
  98369. +
  98370. + if (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5245)
  98371. + {
  98372. + 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)))))))
  98373. + || ((((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)))))));
  98374. + }
  98375. + else
  98376. + {
  98377. + useHZ = gcvFALSE;
  98378. + }
  98379. +
  98380. + if (useHZ)
  98381. + {
  98382. + /* Disable EZ. */
  98383. + Identity->chipFeatures
  98384. + = ((((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)));
  98385. + }
  98386. +
  98387. + /* Disable HZ when EZ is present for older chips. */
  98388. + 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))))))))
  98389. + {
  98390. + /* Disable HIERARCHICAL_Z. */
  98391. + Identity->chipMinorFeatures
  98392. + = ((((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)));
  98393. + }
  98394. +
  98395. + /* Disable rectangle primitive when chip is gc880_5_1_0_rc6*/
  98396. + if ((Identity->chipModel == gcv880) && (Identity->chipRevision == 0x5106))
  98397. + {
  98398. + /* Disable rectangle primitive. */
  98399. + Identity->chipMinorFeatures2
  98400. + = ((((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)));
  98401. + }
  98402. +
  98403. + if ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4605))
  98404. + {
  98405. + /* Correct feature bit: RTL does not have such feature. */
  98406. + Identity->chipFeatures
  98407. + = ((((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)));
  98408. + }
  98409. +
  98410. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98411. + "Identity: chipFeatures=0x%08X",
  98412. + Identity->chipFeatures);
  98413. +
  98414. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98415. + "Identity: chipMinorFeatures=0x%08X",
  98416. + Identity->chipMinorFeatures);
  98417. +
  98418. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98419. + "Identity: chipMinorFeatures1=0x%08X",
  98420. + Identity->chipMinorFeatures1);
  98421. +
  98422. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98423. + "Identity: chipMinorFeatures2=0x%08X",
  98424. + Identity->chipMinorFeatures2);
  98425. +
  98426. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98427. + "Identity: chipMinorFeatures3=0x%08X",
  98428. + Identity->chipMinorFeatures3);
  98429. +
  98430. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98431. + "Identity: chipMinorFeatures4=0x%08X",
  98432. + Identity->chipMinorFeatures4);
  98433. +
  98434. + /***************************************************************************
  98435. + ** Get chip specs.
  98436. + */
  98437. +
  98438. + 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))))))))
  98439. + {
  98440. + gctUINT32 specs, specs2, specs3;
  98441. +
  98442. + /* Read gcChipSpecs register. */
  98443. + gcmkONERROR(
  98444. + gckOS_ReadRegisterEx(Os, Core,
  98445. + 0x00048,
  98446. + &specs));
  98447. +
  98448. + /* Extract the fields. */
  98449. + streamCount = (((((gctUINT32) (specs)) >> (0 ? 3:0)) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1)))))) );
  98450. + registerMax = (((((gctUINT32) (specs)) >> (0 ? 7:4)) & ((gctUINT32) ((((1 ? 7:4) - (0 ? 7:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:4) - (0 ? 7:4) + 1)))))) );
  98451. + threadCount = (((((gctUINT32) (specs)) >> (0 ? 11:8)) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1)))))) );
  98452. + shaderCoreCount = (((((gctUINT32) (specs)) >> (0 ? 24:20)) & ((gctUINT32) ((((1 ? 24:20) - (0 ? 24:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:20) - (0 ? 24:20) + 1)))))) );
  98453. + vertexCacheSize = (((((gctUINT32) (specs)) >> (0 ? 16:12)) & ((gctUINT32) ((((1 ? 16:12) - (0 ? 16:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:12) - (0 ? 16:12) + 1)))))) );
  98454. + vertexOutputBufferSize = (((((gctUINT32) (specs)) >> (0 ? 31:28)) & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1)))))) );
  98455. + pixelPipes = (((((gctUINT32) (specs)) >> (0 ? 27:25)) & ((gctUINT32) ((((1 ? 27:25) - (0 ? 27:25) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:25) - (0 ? 27:25) + 1)))))) );
  98456. +
  98457. + /* Read gcChipSpecs2 register. */
  98458. + gcmkONERROR(
  98459. + gckOS_ReadRegisterEx(Os, Core,
  98460. + 0x00080,
  98461. + &specs2));
  98462. +
  98463. + instructionCount = (((((gctUINT32) (specs2)) >> (0 ? 15:8)) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1)))))) );
  98464. + numConstants = (((((gctUINT32) (specs2)) >> (0 ? 31:16)) & ((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1)))))) );
  98465. + bufferSize = (((((gctUINT32) (specs2)) >> (0 ? 7:0)) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1)))))) );
  98466. +
  98467. + /* Read gcChipSpecs3 register. */
  98468. + gcmkONERROR(
  98469. + gckOS_ReadRegisterEx(Os, Core,
  98470. + 0x0008C,
  98471. + &specs3));
  98472. +
  98473. + varyingsCount = (((((gctUINT32) (specs3)) >> (0 ? 8:4)) & ((gctUINT32) ((((1 ? 8:4) - (0 ? 8:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:4) - (0 ? 8:4) + 1)))))) );
  98474. + }
  98475. +
  98476. + /* Get the number of pixel pipes. */
  98477. + Identity->pixelPipes = gcmMAX(pixelPipes, 1);
  98478. +
  98479. + /* Get the stream count. */
  98480. + Identity->streamCount = (streamCount != 0)
  98481. + ? streamCount
  98482. + : (Identity->chipModel >= gcv1000) ? 4 : 1;
  98483. +
  98484. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98485. + "Specs: streamCount=%u%s",
  98486. + Identity->streamCount,
  98487. + (streamCount == 0) ? " (default)" : "");
  98488. +
  98489. + /* Get the vertex output buffer size. */
  98490. + Identity->vertexOutputBufferSize = (vertexOutputBufferSize != 0)
  98491. + ? 1 << vertexOutputBufferSize
  98492. + : (Identity->chipModel == gcv400)
  98493. + ? (Identity->chipRevision < 0x4000) ? 512
  98494. + : (Identity->chipRevision < 0x4200) ? 256
  98495. + : 128
  98496. + : (Identity->chipModel == gcv530)
  98497. + ? (Identity->chipRevision < 0x4200) ? 512
  98498. + : 128
  98499. + : 512;
  98500. +
  98501. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98502. + "Specs: vertexOutputBufferSize=%u%s",
  98503. + Identity->vertexOutputBufferSize,
  98504. + (vertexOutputBufferSize == 0) ? " (default)" : "");
  98505. +
  98506. + /* Get the maximum number of threads. */
  98507. + Identity->threadCount = (threadCount != 0)
  98508. + ? 1 << threadCount
  98509. + : (Identity->chipModel == gcv400) ? 64
  98510. + : (Identity->chipModel == gcv500) ? 128
  98511. + : (Identity->chipModel == gcv530) ? 128
  98512. + : 256;
  98513. +
  98514. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98515. + "Specs: threadCount=%u%s",
  98516. + Identity->threadCount,
  98517. + (threadCount == 0) ? " (default)" : "");
  98518. +
  98519. + /* Get the number of shader cores. */
  98520. + Identity->shaderCoreCount = (shaderCoreCount != 0)
  98521. + ? shaderCoreCount
  98522. + : (Identity->chipModel >= gcv1000) ? 2
  98523. + : 1;
  98524. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98525. + "Specs: shaderCoreCount=%u%s",
  98526. + Identity->shaderCoreCount,
  98527. + (shaderCoreCount == 0) ? " (default)" : "");
  98528. +
  98529. + /* Get the vertex cache size. */
  98530. + Identity->vertexCacheSize = (vertexCacheSize != 0)
  98531. + ? vertexCacheSize
  98532. + : 8;
  98533. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98534. + "Specs: vertexCacheSize=%u%s",
  98535. + Identity->vertexCacheSize,
  98536. + (vertexCacheSize == 0) ? " (default)" : "");
  98537. +
  98538. + /* Get the maximum number of temporary registers. */
  98539. + Identity->registerMax = (registerMax != 0)
  98540. + /* Maximum of registerMax/4 registers are accessible to 1 shader */
  98541. + ? 1 << registerMax
  98542. + : (Identity->chipModel == gcv400) ? 32
  98543. + : 64;
  98544. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98545. + "Specs: registerMax=%u%s",
  98546. + Identity->registerMax,
  98547. + (registerMax == 0) ? " (default)" : "");
  98548. +
  98549. + /* Get the instruction count. */
  98550. + Identity->instructionCount = (instructionCount == 0) ? 256
  98551. + : (instructionCount == 1) ? 1024
  98552. + : (instructionCount == 2) ? 2048
  98553. + : (instructionCount == 0xFF) ? 512
  98554. + : 256;
  98555. +
  98556. + if (Identity->instructionCount == 256)
  98557. + {
  98558. + if ((Identity->chipModel == gcv2000 && Identity->chipRevision == 0x5108)
  98559. + || Identity->chipModel == gcv880)
  98560. + {
  98561. + Identity->instructionCount = 512;
  98562. + }
  98563. + }
  98564. +
  98565. + 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))))))))
  98566. + {
  98567. + Identity->instructionCount = 512;
  98568. + }
  98569. +
  98570. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98571. + "Specs: instructionCount=%u%s",
  98572. + Identity->instructionCount,
  98573. + (instructionCount == 0) ? " (default)" : "");
  98574. +
  98575. + /* Get the number of constants. */
  98576. + Identity->numConstants = (numConstants == 0) ? 168 : numConstants;
  98577. +
  98578. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98579. + "Specs: numConstants=%u%s",
  98580. + Identity->numConstants,
  98581. + (numConstants == 0) ? " (default)" : "");
  98582. +
  98583. + /* Get the buffer size. */
  98584. + Identity->bufferSize = bufferSize;
  98585. +
  98586. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98587. + "Specs: bufferSize=%u%s",
  98588. + Identity->bufferSize,
  98589. + (bufferSize == 0) ? " (default)" : "");
  98590. +
  98591. +
  98592. + if (varyingsCount != 0)
  98593. + {
  98594. + /* Bug 4480. */
  98595. + /*Identity->varyingsCount = varyingsCount;*/
  98596. + Identity->varyingsCount = 12;
  98597. + }
  98598. + 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))))))))
  98599. + {
  98600. + Identity->varyingsCount = 12;
  98601. + }
  98602. + else
  98603. + {
  98604. + Identity->varyingsCount = 8;
  98605. + }
  98606. +
  98607. + /* For some cores, it consumes two varying for position, so the max varying vectors should minus one. */
  98608. + if ((Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5222) ||
  98609. + (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5208) ||
  98610. + ((Identity->chipModel == gcv2100 || Identity->chipModel == gcv2000) && Identity->chipRevision == 0x5108) ||
  98611. + (Identity->chipModel == gcv880 && (Identity->chipRevision == 0x5107 || Identity->chipRevision == 0x5106)))
  98612. + {
  98613. + Identity->varyingsCount -= 1;
  98614. + }
  98615. +
  98616. + Identity->chip2DControl = 0;
  98617. + if (Identity->chipModel == gcv320)
  98618. + {
  98619. + gctUINT32 data;
  98620. +
  98621. + gcmkONERROR(
  98622. + gckOS_ReadRegisterEx(Os,
  98623. + Core,
  98624. + 0x0002C,
  98625. + &data));
  98626. +
  98627. + if ((data != 33956864) &&
  98628. + ((Identity->chipRevision == 0x5007) ||
  98629. + (Identity->chipRevision == 0x5220)))
  98630. + {
  98631. + Identity->chip2DControl |= 0xFF &
  98632. + (Identity->chipRevision == 0x5220 ? 8 :
  98633. + (Identity->chipRevision == 0x5007 ? 12 : 0));
  98634. + }
  98635. +
  98636. + if (Identity->chipRevision == 0x5007)
  98637. + {
  98638. + /* Disable splitting rectangle. */
  98639. + Identity->chip2DControl |= 0x100;
  98640. +
  98641. + /* Enable 2D Flush. */
  98642. + Identity->chip2DControl |= 0x200;
  98643. + }
  98644. + }
  98645. +
  98646. + /* Success. */
  98647. + gcmkFOOTER();
  98648. + return gcvSTATUS_OK;
  98649. +
  98650. +OnError:
  98651. + /* Return the status. */
  98652. + gcmkFOOTER();
  98653. + return status;
  98654. +}
  98655. +
  98656. +#if gcdPOWEROFF_TIMEOUT
  98657. +void
  98658. +_PowerTimerFunction(
  98659. + gctPOINTER Data
  98660. + )
  98661. +{
  98662. + gckHARDWARE hardware = (gckHARDWARE)Data;
  98663. + gcmkVERIFY_OK(
  98664. + gckHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
  98665. +}
  98666. +#endif
  98667. +
  98668. +static gceSTATUS
  98669. +_VerifyDMA(
  98670. + IN gckOS Os,
  98671. + IN gceCORE Core,
  98672. + gctUINT32_PTR Address1,
  98673. + gctUINT32_PTR Address2,
  98674. + gctUINT32_PTR State1,
  98675. + gctUINT32_PTR State2
  98676. + )
  98677. +{
  98678. + gceSTATUS status;
  98679. + gctUINT32 i;
  98680. +
  98681. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x660, State1));
  98682. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x664, Address1));
  98683. +
  98684. + for (i = 0; i < 500; i += 1)
  98685. + {
  98686. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x660, State2));
  98687. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x664, Address2));
  98688. +
  98689. + if (*Address1 != *Address2)
  98690. + {
  98691. + break;
  98692. + }
  98693. +
  98694. + if (*State1 != *State2)
  98695. + {
  98696. + break;
  98697. + }
  98698. + }
  98699. +
  98700. +OnError:
  98701. + return status;
  98702. +}
  98703. +
  98704. +static gceSTATUS
  98705. +_DumpDebugRegisters(
  98706. + IN gckOS Os,
  98707. + IN gceCORE Core,
  98708. + IN gcsiDEBUG_REGISTERS_PTR Descriptor
  98709. + )
  98710. +{
  98711. + gceSTATUS status = gcvSTATUS_OK;
  98712. + gctUINT32 select;
  98713. + gctUINT32 data = 0;
  98714. + gctUINT i;
  98715. +
  98716. + gcmkHEADER_ARG("Os=0x%X Descriptor=0x%X", Os, Descriptor);
  98717. +
  98718. + gcmkPRINT_N(4, " %s debug registers:\n", Descriptor->module);
  98719. +
  98720. + for (i = 0; i < Descriptor->count; i += 1)
  98721. + {
  98722. + select = i << Descriptor->shift;
  98723. +
  98724. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, select));
  98725. +#if gcdFPGA_BUILD
  98726. + gcmkONERROR(gckOS_Delay(Os, 1000));
  98727. +#endif
  98728. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &data));
  98729. +
  98730. + gcmkPRINT_N(12, " [0x%02X] 0x%08X\n", i, data);
  98731. + }
  98732. +
  98733. + select = 0xF << Descriptor->shift;
  98734. +
  98735. + for (i = 0; i < 500; i += 1)
  98736. + {
  98737. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, select));
  98738. +#if gcdFPGA_BUILD
  98739. + gcmkONERROR(gckOS_Delay(Os, 1000));
  98740. +#endif
  98741. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &data));
  98742. +
  98743. + if (data == Descriptor->signature)
  98744. + {
  98745. + break;
  98746. + }
  98747. + }
  98748. +
  98749. + if (i == 500)
  98750. + {
  98751. + gcmkPRINT_N(4, " failed to obtain the signature (read 0x%08X).\n", data);
  98752. + }
  98753. + else
  98754. + {
  98755. + gcmkPRINT_N(8, " signature = 0x%08X (%d read attempt(s))\n", data, i + 1);
  98756. + }
  98757. +
  98758. +OnError:
  98759. + /* Return the error. */
  98760. + gcmkFOOTER();
  98761. + return status;
  98762. +}
  98763. +
  98764. +static gceSTATUS
  98765. +_IsGPUPresent(
  98766. + IN gckHARDWARE Hardware
  98767. + )
  98768. +{
  98769. + gceSTATUS status;
  98770. + gcsHAL_QUERY_CHIP_IDENTITY identity;
  98771. + gctUINT32 control;
  98772. +
  98773. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  98774. +
  98775. + /* Verify the arguments. */
  98776. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  98777. +
  98778. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  98779. + Hardware->core,
  98780. + 0x00000,
  98781. + &control));
  98782. +
  98783. + 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)));
  98784. + 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)));
  98785. +
  98786. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  98787. + Hardware->core,
  98788. + 0x00000,
  98789. + control));
  98790. +
  98791. + /* Identify the hardware. */
  98792. + gcmkONERROR(_IdentifyHardware(Hardware->os,
  98793. + Hardware->core,
  98794. + &identity));
  98795. +
  98796. + /* Check if these are the same values as saved before. */
  98797. + if ((Hardware->identity.chipModel != identity.chipModel)
  98798. + || (Hardware->identity.chipRevision != identity.chipRevision)
  98799. + || (Hardware->identity.chipFeatures != identity.chipFeatures)
  98800. + || (Hardware->identity.chipMinorFeatures != identity.chipMinorFeatures)
  98801. + || (Hardware->identity.chipMinorFeatures1 != identity.chipMinorFeatures1)
  98802. + || (Hardware->identity.chipMinorFeatures2 != identity.chipMinorFeatures2)
  98803. + )
  98804. + {
  98805. + gcmkPRINT("[galcore]: GPU is not present.");
  98806. + gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
  98807. + }
  98808. +
  98809. + /* Success. */
  98810. + gcmkFOOTER_NO();
  98811. + return gcvSTATUS_OK;
  98812. +
  98813. +OnError:
  98814. + /* Return the error. */
  98815. + gcmkFOOTER();
  98816. + return status;
  98817. +}
  98818. +
  98819. +gceSTATUS
  98820. +_FlushCache(
  98821. + gckHARDWARE Hardware,
  98822. + gckCOMMAND Command
  98823. + )
  98824. +{
  98825. + gceSTATUS status;
  98826. + gctSIZE_T bytes, requested;
  98827. + gctPOINTER buffer;
  98828. +
  98829. + /* Get the size of the flush command. */
  98830. + gcmkONERROR(gckHARDWARE_Flush(Hardware,
  98831. + gcvFLUSH_ALL,
  98832. + gcvNULL,
  98833. + &requested));
  98834. +
  98835. + /* Reserve space in the command queue. */
  98836. + gcmkONERROR(gckCOMMAND_Reserve(Command,
  98837. + requested,
  98838. + &buffer,
  98839. + &bytes));
  98840. +
  98841. + /* Append a flush. */
  98842. + gcmkONERROR(gckHARDWARE_Flush(
  98843. + Hardware, gcvFLUSH_ALL, buffer, &bytes
  98844. + ));
  98845. +
  98846. + /* Execute the command queue. */
  98847. + gcmkONERROR(gckCOMMAND_Execute(Command, requested));
  98848. +
  98849. + return gcvSTATUS_OK;
  98850. +
  98851. +OnError:
  98852. + return status;
  98853. +}
  98854. +
  98855. +/******************************************************************************\
  98856. +****************************** gckHARDWARE API code *****************************
  98857. +\******************************************************************************/
  98858. +
  98859. +/*******************************************************************************
  98860. +**
  98861. +** gckHARDWARE_Construct
  98862. +**
  98863. +** Construct a new gckHARDWARE object.
  98864. +**
  98865. +** INPUT:
  98866. +**
  98867. +** gckOS Os
  98868. +** Pointer to an initialized gckOS object.
  98869. +**
  98870. +** gceCORE Core
  98871. +** Specified core.
  98872. +**
  98873. +** OUTPUT:
  98874. +**
  98875. +** gckHARDWARE * Hardware
  98876. +** Pointer to a variable that will hold the pointer to the gckHARDWARE
  98877. +** object.
  98878. +*/
  98879. +gceSTATUS
  98880. +gckHARDWARE_Construct(
  98881. + IN gckOS Os,
  98882. + IN gceCORE Core,
  98883. + OUT gckHARDWARE * Hardware
  98884. + )
  98885. +{
  98886. + gceSTATUS status;
  98887. + gckHARDWARE hardware = gcvNULL;
  98888. + gctUINT16 data = 0xff00;
  98889. + gctUINT32 axi_ot;
  98890. + gctPOINTER pointer = gcvNULL;
  98891. +
  98892. + gcmkHEADER_ARG("Os=0x%x", Os);
  98893. +
  98894. + /* Verify the arguments. */
  98895. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  98896. + gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
  98897. +
  98898. + /* Enable the GPU. */
  98899. + gcmkONERROR(gckOS_SetGPUPower(Os, Core, gcvTRUE, gcvTRUE));
  98900. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  98901. + Core,
  98902. + 0x00000,
  98903. + 0x00000900));
  98904. +
  98905. + /* Allocate the gckHARDWARE object. */
  98906. + gcmkONERROR(gckOS_Allocate(Os,
  98907. + gcmSIZEOF(struct _gckHARDWARE),
  98908. + &pointer));
  98909. +
  98910. + hardware = (gckHARDWARE) pointer;
  98911. +
  98912. + /* Initialize the gckHARDWARE object. */
  98913. + hardware->object.type = gcvOBJ_HARDWARE;
  98914. + hardware->os = Os;
  98915. + hardware->core = Core;
  98916. +
  98917. + /* Identify the hardware. */
  98918. + gcmkONERROR(_IdentifyHardware(Os, Core, &hardware->identity));
  98919. +
  98920. + /* Determine the hardware type */
  98921. + switch (hardware->identity.chipModel)
  98922. + {
  98923. + case gcv350:
  98924. + case gcv355:
  98925. + hardware->type = gcvHARDWARE_VG;
  98926. + break;
  98927. +
  98928. + case gcv300:
  98929. + case gcv320:
  98930. + case gcv420:
  98931. + hardware->type = gcvHARDWARE_2D;
  98932. + /*set outstanding limit*/
  98933. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
  98934. + axi_ot = (axi_ot & (~0xFF)) | 0x10;
  98935. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot));
  98936. + break;
  98937. +
  98938. + default:
  98939. + hardware->type = gcvHARDWARE_3D;
  98940. + if(hardware->identity.chipModel == gcv880)
  98941. + {
  98942. + /*set outstanding limit*/
  98943. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
  98944. + axi_ot = (axi_ot & (~0xFF)) | 0x10;
  98945. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot));
  98946. + }
  98947. +
  98948. + 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)))))) ))
  98949. + {
  98950. + hardware->type = (gceHARDWARE_TYPE) (hardware->type | gcvHARDWARE_2D);
  98951. + }
  98952. + }
  98953. +
  98954. + hardware->powerBaseAddress
  98955. + = ((hardware->identity.chipModel == gcv300)
  98956. + && (hardware->identity.chipRevision < 0x2000))
  98957. + ? 0x0100
  98958. + : 0x0000;
  98959. +
  98960. + /* _ResetGPU need powerBaseAddress. */
  98961. + status = _ResetGPU(hardware, Os, Core);
  98962. +
  98963. + if (status != gcvSTATUS_OK)
  98964. + {
  98965. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98966. + "_ResetGPU failed: status=%d\n", status);
  98967. + }
  98968. +
  98969. + hardware->powerMutex = gcvNULL;
  98970. +
  98971. + hardware->mmuVersion
  98972. + = (((((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)))))) );
  98973. +
  98974. + /* Determine whether bug fixes #1 are present. */
  98975. + 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)))))));
  98976. +
  98977. + /* Check if big endian */
  98978. + hardware->bigEndian = (*(gctUINT8 *)&data == 0xff);
  98979. +
  98980. + /* Initialize the fast clear. */
  98981. + gcmkONERROR(gckHARDWARE_SetFastClear(hardware, -1, -1));
  98982. +
  98983. +#if !gcdENABLE_128B_MERGE
  98984. +
  98985. + 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))))))))
  98986. + {
  98987. + /* 128B merge is turned on by default. Disable it. */
  98988. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00558, 0));
  98989. + }
  98990. +
  98991. +#endif
  98992. +
  98993. + /* Set power state to ON. */
  98994. + hardware->chipPowerState = gcvPOWER_ON;
  98995. + hardware->clockState = gcvTRUE;
  98996. + hardware->powerState = gcvTRUE;
  98997. + hardware->lastWaitLink = ~0U;
  98998. + hardware->globalSemaphore = gcvNULL;
  98999. +#if gcdENABLE_FSCALE_VAL_ADJUST
  99000. + hardware->powerOnFscaleVal = 64;
  99001. +#endif
  99002. +
  99003. + gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerMutex));
  99004. + gcmkONERROR(gckOS_CreateSemaphore(Os, &hardware->globalSemaphore));
  99005. + hardware->startIsr = gcvNULL;
  99006. + hardware->stopIsr = gcvNULL;
  99007. +
  99008. +#if gcdPOWEROFF_TIMEOUT
  99009. + hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
  99010. +
  99011. + gcmkVERIFY_OK(gckOS_CreateTimer(Os,
  99012. + _PowerTimerFunction,
  99013. + (gctPOINTER)hardware,
  99014. + &hardware->powerOffTimer));
  99015. +#endif
  99016. +
  99017. + gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
  99018. +
  99019. +#if gcdLINK_QUEUE_SIZE
  99020. + hardware->linkQueue.front = 0;
  99021. + hardware->linkQueue.rear = 0;
  99022. + hardware->linkQueue.count = 0;
  99023. +#endif
  99024. +
  99025. + /* Enable power management by default. */
  99026. + hardware->powerManagement = gcvTRUE;
  99027. +
  99028. + /* Disable profiler by default */
  99029. + hardware->gpuProfiler = gcvFALSE;
  99030. +
  99031. + /* Return pointer to the gckHARDWARE object. */
  99032. + *Hardware = hardware;
  99033. +
  99034. + /* Success. */
  99035. + gcmkFOOTER_ARG("*Hardware=0x%x", *Hardware);
  99036. + return gcvSTATUS_OK;
  99037. +
  99038. +OnError:
  99039. + /* Roll back. */
  99040. + if (hardware != gcvNULL)
  99041. + {
  99042. + /* Turn off the power. */
  99043. + gcmkVERIFY_OK(gckOS_SetGPUPower(Os, Core, gcvFALSE, gcvFALSE));
  99044. +
  99045. + if (hardware->globalSemaphore != gcvNULL)
  99046. + {
  99047. + /* Destroy the global semaphore. */
  99048. + gcmkVERIFY_OK(gckOS_DestroySemaphore(Os,
  99049. + hardware->globalSemaphore));
  99050. + }
  99051. +
  99052. + if (hardware->powerMutex != gcvNULL)
  99053. + {
  99054. + /* Destroy the power mutex. */
  99055. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, hardware->powerMutex));
  99056. + }
  99057. +
  99058. +#if gcdPOWEROFF_TIMEOUT
  99059. + if (hardware->powerOffTimer != gcvNULL)
  99060. + {
  99061. + gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
  99062. + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
  99063. + }
  99064. +#endif
  99065. +
  99066. + if (hardware->pageTableDirty != gcvNULL)
  99067. + {
  99068. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
  99069. + }
  99070. +
  99071. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, hardware));
  99072. + }
  99073. +
  99074. + /* Return the status. */
  99075. + gcmkFOOTER();
  99076. + return status;
  99077. +}
  99078. +
  99079. +/*******************************************************************************
  99080. +**
  99081. +** gckHARDWARE_Destroy
  99082. +**
  99083. +** Destroy an gckHARDWARE object.
  99084. +**
  99085. +** INPUT:
  99086. +**
  99087. +** gckHARDWARE Hardware
  99088. +** Pointer to the gckHARDWARE object that needs to be destroyed.
  99089. +**
  99090. +** OUTPUT:
  99091. +**
  99092. +** Nothing.
  99093. +*/
  99094. +gceSTATUS
  99095. +gckHARDWARE_Destroy(
  99096. + IN gckHARDWARE Hardware
  99097. + )
  99098. +{
  99099. + gceSTATUS status;
  99100. +
  99101. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  99102. +
  99103. + /* Verify the arguments. */
  99104. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99105. +
  99106. + /* Destroy the power semaphore. */
  99107. + gcmkVERIFY_OK(gckOS_DestroySemaphore(Hardware->os,
  99108. + Hardware->globalSemaphore));
  99109. +
  99110. + /* Destroy the power mutex. */
  99111. + gcmkVERIFY_OK(gckOS_DeleteMutex(Hardware->os, Hardware->powerMutex));
  99112. +
  99113. +#if gcdPOWEROFF_TIMEOUT
  99114. + gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
  99115. + gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
  99116. +#endif
  99117. +
  99118. + gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
  99119. +
  99120. + /* Mark the object as unknown. */
  99121. + Hardware->object.type = gcvOBJ_UNKNOWN;
  99122. +
  99123. + /* Free the object. */
  99124. + gcmkONERROR(gcmkOS_SAFE_FREE(Hardware->os, Hardware));
  99125. +
  99126. + /* Success. */
  99127. + gcmkFOOTER_NO();
  99128. + return gcvSTATUS_OK;
  99129. +
  99130. +OnError:
  99131. + gcmkFOOTER();
  99132. + return status;
  99133. +}
  99134. +
  99135. +/*******************************************************************************
  99136. +**
  99137. +** gckHARDWARE_GetType
  99138. +**
  99139. +** Get the hardware type.
  99140. +**
  99141. +** INPUT:
  99142. +**
  99143. +** gckHARDWARE Harwdare
  99144. +** Pointer to an gckHARDWARE object.
  99145. +**
  99146. +** OUTPUT:
  99147. +**
  99148. +** gceHARDWARE_TYPE * Type
  99149. +** Pointer to a variable that receives the type of hardware object.
  99150. +*/
  99151. +gceSTATUS
  99152. +gckHARDWARE_GetType(
  99153. + IN gckHARDWARE Hardware,
  99154. + OUT gceHARDWARE_TYPE * Type
  99155. + )
  99156. +{
  99157. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  99158. + gcmkVERIFY_ARGUMENT(Type != gcvNULL);
  99159. +
  99160. + *Type = Hardware->type;
  99161. +
  99162. + gcmkFOOTER_ARG("*Type=%d", *Type);
  99163. + return gcvSTATUS_OK;
  99164. +}
  99165. +
  99166. +/*******************************************************************************
  99167. +**
  99168. +** gckHARDWARE_InitializeHardware
  99169. +**
  99170. +** Initialize the hardware.
  99171. +**
  99172. +** INPUT:
  99173. +**
  99174. +** gckHARDWARE Hardware
  99175. +** Pointer to the gckHARDWARE object.
  99176. +**
  99177. +** OUTPUT:
  99178. +**
  99179. +** Nothing.
  99180. +*/
  99181. +gceSTATUS
  99182. +gckHARDWARE_InitializeHardware(
  99183. + IN gckHARDWARE Hardware
  99184. + )
  99185. +{
  99186. + gceSTATUS status;
  99187. + gctUINT32 baseAddress;
  99188. + gctUINT32 chipRev;
  99189. + gctUINT32 control;
  99190. +
  99191. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  99192. +
  99193. + /* Verify the arguments. */
  99194. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99195. +
  99196. + /* Read the chip revision register. */
  99197. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  99198. + Hardware->core,
  99199. + 0x00024,
  99200. + &chipRev));
  99201. +
  99202. + if (chipRev != Hardware->identity.chipRevision)
  99203. + {
  99204. + /* Chip is not there! */
  99205. + gcmkONERROR(gcvSTATUS_CONTEXT_LOSSED);
  99206. + }
  99207. +
  99208. + /* Disable isolate GPU bit. */
  99209. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99210. + Hardware->core,
  99211. + 0x00000,
  99212. + ((((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)))));
  99213. +
  99214. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  99215. + Hardware->core,
  99216. + 0x00000,
  99217. + &control));
  99218. +
  99219. + /* Enable debug register. */
  99220. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99221. + Hardware->core,
  99222. + 0x00000,
  99223. + ((((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)))));
  99224. +
  99225. + /* Reset memory counters. */
  99226. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99227. + Hardware->core,
  99228. + 0x0003C,
  99229. + ~0U));
  99230. +
  99231. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99232. + Hardware->core,
  99233. + 0x0003C,
  99234. + 0));
  99235. +
  99236. + /* Get the system's physical base address. */
  99237. + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  99238. +
  99239. + /* Program the base addesses. */
  99240. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99241. + Hardware->core,
  99242. + 0x0041C,
  99243. + baseAddress));
  99244. +
  99245. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99246. + Hardware->core,
  99247. + 0x00418,
  99248. + baseAddress));
  99249. +
  99250. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99251. + Hardware->core,
  99252. + 0x00428,
  99253. + baseAddress));
  99254. +
  99255. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99256. + Hardware->core,
  99257. + 0x00420,
  99258. + baseAddress));
  99259. +
  99260. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99261. + Hardware->core,
  99262. + 0x00424,
  99263. + baseAddress));
  99264. +
  99265. +#if !VIVANTE_PROFILER
  99266. + {
  99267. + gctUINT32 data;
  99268. +
  99269. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  99270. + Hardware->core,
  99271. + Hardware->powerBaseAddress +
  99272. + 0x00100,
  99273. + &data));
  99274. +
  99275. + /* Enable clock gating. */
  99276. + 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)));
  99277. +
  99278. + if ((Hardware->identity.chipRevision == 0x4301)
  99279. + || (Hardware->identity.chipRevision == 0x4302)
  99280. + )
  99281. + {
  99282. + /* Disable stall module level clock gating for 4.3.0.1 and 4.3.0.2
  99283. + ** revisions. */
  99284. + 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)));
  99285. + }
  99286. +
  99287. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99288. + Hardware->core,
  99289. + Hardware->powerBaseAddress
  99290. + + 0x00100,
  99291. + data));
  99292. +
  99293. +#ifndef VIVANTE_NO_3D
  99294. + /* Disable PE clock gating on revs < 5.0 when HZ is present without a
  99295. + ** bug fix. */
  99296. + if ((Hardware->identity.chipRevision < 0x5000)
  99297. + && ((((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)))))))
  99298. + && ((((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)))))))
  99299. + )
  99300. + {
  99301. + gcmkONERROR(
  99302. + gckOS_ReadRegisterEx(Hardware->os,
  99303. + Hardware->core,
  99304. + Hardware->powerBaseAddress
  99305. + + 0x00104,
  99306. + &data));
  99307. +
  99308. + /* Disable PE clock gating. */
  99309. + 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)));
  99310. +
  99311. + gcmkONERROR(
  99312. + gckOS_WriteRegisterEx(Hardware->os,
  99313. + Hardware->core,
  99314. + Hardware->powerBaseAddress
  99315. + + 0x00104,
  99316. + data));
  99317. + }
  99318. +
  99319. +#endif
  99320. + }
  99321. +#endif
  99322. +
  99323. + /* Special workaround for this core
  99324. + ** Make sure pulse eater kicks in only when SH is idle */
  99325. + if (Hardware->identity.chipModel == gcv4000 &&
  99326. + Hardware->identity.chipRevision == 0x5208)
  99327. + {
  99328. + gcmkONERROR(
  99329. + gckOS_WriteRegisterEx(Hardware->os,
  99330. + Hardware->core,
  99331. + 0x0010C,
  99332. + ((((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)))));
  99333. + }
  99334. +
  99335. + if ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) == gcvFALSE)
  99336. + || (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) && (Hardware->identity.chipRevision < 0x5422))
  99337. + )
  99338. + {
  99339. + gctUINT32 data;
  99340. +
  99341. + gcmkONERROR(
  99342. + gckOS_ReadRegisterEx(Hardware->os,
  99343. + Hardware->core,
  99344. + Hardware->powerBaseAddress
  99345. + + 0x00104,
  99346. + &data));
  99347. +
  99348. +
  99349. + 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)));
  99350. +
  99351. +
  99352. + gcmkONERROR(
  99353. + gckOS_WriteRegisterEx(Hardware->os,
  99354. + Hardware->core,
  99355. + Hardware->powerBaseAddress
  99356. + + 0x00104,
  99357. + data));
  99358. + }
  99359. +
  99360. + /* Special workaround for this core
  99361. + ** Make sure FE and TX are on different buses */
  99362. + if ((Hardware->identity.chipModel == gcv2000)
  99363. + && (Hardware->identity.chipRevision == 0x5108))
  99364. + {
  99365. + gctUINT32 data;
  99366. +
  99367. + gcmkONERROR(
  99368. + gckOS_ReadRegisterEx(Hardware->os,
  99369. + Hardware->core,
  99370. + 0x00480,
  99371. + &data));
  99372. +
  99373. + /* Set FE bus to one, TX bus to zero */
  99374. + 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)));
  99375. + 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)));
  99376. +
  99377. + gcmkONERROR(
  99378. + gckOS_WriteRegisterEx(Hardware->os,
  99379. + Hardware->core,
  99380. + 0x00480,
  99381. + data));
  99382. + }
  99383. +
  99384. + /* Test if MMU is initialized. */
  99385. + if ((Hardware->kernel != gcvNULL)
  99386. + && (Hardware->kernel->mmu != gcvNULL)
  99387. + )
  99388. + {
  99389. + /* Reset MMU. */
  99390. + if (Hardware->mmuVersion == 0)
  99391. + {
  99392. + gcmkONERROR(
  99393. + gckHARDWARE_SetMMU(Hardware,
  99394. + Hardware->kernel->mmu->pageTableLogical));
  99395. + }
  99396. + }
  99397. +
  99398. + if (Hardware->identity.chipModel >= gcv400
  99399. + && Hardware->identity.chipModel != gcv420
  99400. + && (((((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)
  99401. + )
  99402. + {
  99403. + gctUINT32 data;
  99404. +
  99405. + gcmkONERROR(
  99406. + gckOS_ReadRegisterEx(Hardware->os,
  99407. + Hardware->core,
  99408. + Hardware->powerBaseAddress
  99409. + + 0x00104,
  99410. + &data));
  99411. +
  99412. + /* Disable PA clock gating. */
  99413. + 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)));
  99414. +
  99415. + gcmkONERROR(
  99416. + gckOS_WriteRegisterEx(Hardware->os,
  99417. + Hardware->core,
  99418. + Hardware->powerBaseAddress
  99419. + + 0x00104,
  99420. + data));
  99421. + }
  99422. +
  99423. +#if gcdHZ_L2_DISALBE
  99424. + /* Disable HZ-L2. */
  99425. + 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 ||
  99426. + ((((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)
  99427. + {
  99428. + gctUINT32 data;
  99429. +
  99430. + gcmkONERROR(
  99431. + gckOS_ReadRegisterEx(Hardware->os,
  99432. + Hardware->core,
  99433. + 0x00414,
  99434. + &data));
  99435. +
  99436. + 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)));
  99437. +
  99438. + gcmkONERROR(
  99439. + gckOS_WriteRegisterEx(Hardware->os,
  99440. + Hardware->core,
  99441. + 0x00414,
  99442. + data));
  99443. + }
  99444. +#endif
  99445. +
  99446. + /* Limit 2D outstanding request. */
  99447. + if(Hardware->identity.chipModel == gcv880)
  99448. + {
  99449. + gctUINT32 axi_ot;
  99450. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &axi_ot));
  99451. + axi_ot = (axi_ot & (~0xFF)) | 0x10;
  99452. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00414, axi_ot));
  99453. + }
  99454. +
  99455. + if (Hardware->identity.chip2DControl & 0xFF)
  99456. + {
  99457. + gctUINT32 data;
  99458. +
  99459. + gcmkONERROR(
  99460. + gckOS_ReadRegisterEx(Hardware->os,
  99461. + Hardware->core,
  99462. + 0x00414,
  99463. + &data));
  99464. + 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)));
  99465. +
  99466. + gcmkONERROR(
  99467. + gckOS_WriteRegisterEx(Hardware->os,
  99468. + Hardware->core,
  99469. + 0x00414,
  99470. + data));
  99471. + }
  99472. +
  99473. + /* Update GPU AXI cache atttribute. */
  99474. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  99475. + Hardware->core,
  99476. + 0x00008,
  99477. + 0x00002200));
  99478. +
  99479. + /* Success. */
  99480. + gcmkFOOTER_NO();
  99481. + return gcvSTATUS_OK;
  99482. +
  99483. +OnError:
  99484. + /* Return the error. */
  99485. + gcmkFOOTER();
  99486. + return status;
  99487. +}
  99488. +
  99489. +/*******************************************************************************
  99490. +**
  99491. +** gckHARDWARE_QueryMemory
  99492. +**
  99493. +** Query the amount of memory available on the hardware.
  99494. +**
  99495. +** INPUT:
  99496. +**
  99497. +** gckHARDWARE Hardware
  99498. +** Pointer to the gckHARDWARE object.
  99499. +**
  99500. +** OUTPUT:
  99501. +**
  99502. +** gctSIZE_T * InternalSize
  99503. +** Pointer to a variable that will hold the size of the internal video
  99504. +** memory in bytes. If 'InternalSize' is gcvNULL, no information of the
  99505. +** internal memory will be returned.
  99506. +**
  99507. +** gctUINT32 * InternalBaseAddress
  99508. +** Pointer to a variable that will hold the hardware's base address for
  99509. +** the internal video memory. This pointer cannot be gcvNULL if
  99510. +** 'InternalSize' is also non-gcvNULL.
  99511. +**
  99512. +** gctUINT32 * InternalAlignment
  99513. +** Pointer to a variable that will hold the hardware's base address for
  99514. +** the internal video memory. This pointer cannot be gcvNULL if
  99515. +** 'InternalSize' is also non-gcvNULL.
  99516. +**
  99517. +** gctSIZE_T * ExternalSize
  99518. +** Pointer to a variable that will hold the size of the external video
  99519. +** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the
  99520. +** external memory will be returned.
  99521. +**
  99522. +** gctUINT32 * ExternalBaseAddress
  99523. +** Pointer to a variable that will hold the hardware's base address for
  99524. +** the external video memory. This pointer cannot be gcvNULL if
  99525. +** 'ExternalSize' is also non-gcvNULL.
  99526. +**
  99527. +** gctUINT32 * ExternalAlignment
  99528. +** Pointer to a variable that will hold the hardware's base address for
  99529. +** the external video memory. This pointer cannot be gcvNULL if
  99530. +** 'ExternalSize' is also non-gcvNULL.
  99531. +**
  99532. +** gctUINT32 * HorizontalTileSize
  99533. +** Number of horizontal pixels per tile. If 'HorizontalTileSize' is
  99534. +** gcvNULL, no horizontal pixel per tile will be returned.
  99535. +**
  99536. +** gctUINT32 * VerticalTileSize
  99537. +** Number of vertical pixels per tile. If 'VerticalTileSize' is
  99538. +** gcvNULL, no vertical pixel per tile will be returned.
  99539. +*/
  99540. +gceSTATUS
  99541. +gckHARDWARE_QueryMemory(
  99542. + IN gckHARDWARE Hardware,
  99543. + OUT gctSIZE_T * InternalSize,
  99544. + OUT gctUINT32 * InternalBaseAddress,
  99545. + OUT gctUINT32 * InternalAlignment,
  99546. + OUT gctSIZE_T * ExternalSize,
  99547. + OUT gctUINT32 * ExternalBaseAddress,
  99548. + OUT gctUINT32 * ExternalAlignment,
  99549. + OUT gctUINT32 * HorizontalTileSize,
  99550. + OUT gctUINT32 * VerticalTileSize
  99551. + )
  99552. +{
  99553. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  99554. +
  99555. + /* Verify the arguments. */
  99556. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99557. +
  99558. + if (InternalSize != gcvNULL)
  99559. + {
  99560. + /* No internal memory. */
  99561. + *InternalSize = 0;
  99562. + }
  99563. +
  99564. + if (ExternalSize != gcvNULL)
  99565. + {
  99566. + /* No external memory. */
  99567. + *ExternalSize = 0;
  99568. + }
  99569. +
  99570. + if (HorizontalTileSize != gcvNULL)
  99571. + {
  99572. + /* 4x4 tiles. */
  99573. + *HorizontalTileSize = 4;
  99574. + }
  99575. +
  99576. + if (VerticalTileSize != gcvNULL)
  99577. + {
  99578. + /* 4x4 tiles. */
  99579. + *VerticalTileSize = 4;
  99580. + }
  99581. +
  99582. + /* Success. */
  99583. + gcmkFOOTER_ARG("*InternalSize=%lu *InternalBaseAddress=0x%08x "
  99584. + "*InternalAlignment=0x%08x *ExternalSize=%lu "
  99585. + "*ExternalBaseAddress=0x%08x *ExtenalAlignment=0x%08x "
  99586. + "*HorizontalTileSize=%u *VerticalTileSize=%u",
  99587. + gcmOPT_VALUE(InternalSize),
  99588. + gcmOPT_VALUE(InternalBaseAddress),
  99589. + gcmOPT_VALUE(InternalAlignment),
  99590. + gcmOPT_VALUE(ExternalSize),
  99591. + gcmOPT_VALUE(ExternalBaseAddress),
  99592. + gcmOPT_VALUE(ExternalAlignment),
  99593. + gcmOPT_VALUE(HorizontalTileSize),
  99594. + gcmOPT_VALUE(VerticalTileSize));
  99595. + return gcvSTATUS_OK;
  99596. +}
  99597. +
  99598. +/*******************************************************************************
  99599. +**
  99600. +** gckHARDWARE_QueryChipIdentity
  99601. +**
  99602. +** Query the identity of the hardware.
  99603. +**
  99604. +** INPUT:
  99605. +**
  99606. +** gckHARDWARE Hardware
  99607. +** Pointer to the gckHARDWARE object.
  99608. +**
  99609. +** OUTPUT:
  99610. +**
  99611. +** gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  99612. +** Pointer to the identity structure.
  99613. +**
  99614. +*/
  99615. +gceSTATUS
  99616. +gckHARDWARE_QueryChipIdentity(
  99617. + IN gckHARDWARE Hardware,
  99618. + OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  99619. + )
  99620. +{
  99621. + gctUINT32 features;
  99622. +
  99623. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  99624. +
  99625. + /* Verify the arguments. */
  99626. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99627. + gcmkVERIFY_ARGUMENT(Identity != gcvNULL);
  99628. +
  99629. + /* Return chip model and revision. */
  99630. + Identity->chipModel = Hardware->identity.chipModel;
  99631. + Identity->chipRevision = Hardware->identity.chipRevision;
  99632. +
  99633. + /* Return feature set. */
  99634. + features = Hardware->identity.chipFeatures;
  99635. +
  99636. + if ((((((gctUINT32) (features)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  99637. + {
  99638. + /* Override fast clear by command line. */
  99639. + 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)));
  99640. + }
  99641. +
  99642. + if ((((((gctUINT32) (features)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ))
  99643. + {
  99644. + /* Override compression by command line. */
  99645. + 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)));
  99646. + }
  99647. +
  99648. + /* Mark 2D pipe as available for GC500.0 through GC500.2 and GC300,
  99649. + ** since they did not have this bit. */
  99650. + if (((Hardware->identity.chipModel == gcv500) && (Hardware->identity.chipRevision <= 2))
  99651. + || (Hardware->identity.chipModel == gcv300)
  99652. + )
  99653. + {
  99654. + 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)));
  99655. + }
  99656. +
  99657. + Identity->chipFeatures = features;
  99658. +
  99659. + /* Return minor features. */
  99660. + Identity->chipMinorFeatures = Hardware->identity.chipMinorFeatures;
  99661. + Identity->chipMinorFeatures1 = Hardware->identity.chipMinorFeatures1;
  99662. + Identity->chipMinorFeatures2 = Hardware->identity.chipMinorFeatures2;
  99663. + Identity->chipMinorFeatures3 = Hardware->identity.chipMinorFeatures3;
  99664. + Identity->chipMinorFeatures4 = Hardware->identity.chipMinorFeatures4;
  99665. +
  99666. + /* Return chip specs. */
  99667. + Identity->streamCount = Hardware->identity.streamCount;
  99668. + Identity->registerMax = Hardware->identity.registerMax;
  99669. + Identity->threadCount = Hardware->identity.threadCount;
  99670. + Identity->shaderCoreCount = Hardware->identity.shaderCoreCount;
  99671. + Identity->vertexCacheSize = Hardware->identity.vertexCacheSize;
  99672. + Identity->vertexOutputBufferSize = Hardware->identity.vertexOutputBufferSize;
  99673. + Identity->pixelPipes = Hardware->identity.pixelPipes;
  99674. + Identity->instructionCount = Hardware->identity.instructionCount;
  99675. + Identity->numConstants = Hardware->identity.numConstants;
  99676. + Identity->bufferSize = Hardware->identity.bufferSize;
  99677. + Identity->varyingsCount = Hardware->identity.varyingsCount;
  99678. + Identity->superTileMode = Hardware->identity.superTileMode;
  99679. + Identity->chip2DControl = Hardware->identity.chip2DControl;
  99680. +
  99681. + /* Success. */
  99682. + gcmkFOOTER_NO();
  99683. + return gcvSTATUS_OK;
  99684. +}
  99685. +
  99686. +/*******************************************************************************
  99687. +**
  99688. +** gckHARDWARE_SplitMemory
  99689. +**
  99690. +** Split a hardware specific memory address into a pool and offset.
  99691. +**
  99692. +** INPUT:
  99693. +**
  99694. +** gckHARDWARE Hardware
  99695. +** Pointer to the gckHARDWARE object.
  99696. +**
  99697. +** gctUINT32 Address
  99698. +** Address in hardware specific format.
  99699. +**
  99700. +** OUTPUT:
  99701. +**
  99702. +** gcePOOL * Pool
  99703. +** Pointer to a variable that will hold the pool type for the address.
  99704. +**
  99705. +** gctUINT32 * Offset
  99706. +** Pointer to a variable that will hold the offset for the address.
  99707. +*/
  99708. +gceSTATUS
  99709. +gckHARDWARE_SplitMemory(
  99710. + IN gckHARDWARE Hardware,
  99711. + IN gctUINT32 Address,
  99712. + OUT gcePOOL * Pool,
  99713. + OUT gctUINT32 * Offset
  99714. + )
  99715. +{
  99716. + gcmkHEADER_ARG("Hardware=0x%x Addres=0x%08x", Hardware, Address);
  99717. +
  99718. + /* Verify the arguments. */
  99719. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99720. + gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
  99721. + gcmkVERIFY_ARGUMENT(Offset != gcvNULL);
  99722. +
  99723. + if (Hardware->mmuVersion == 0)
  99724. + {
  99725. + /* Dispatch on memory type. */
  99726. + switch ((((((gctUINT32) (Address)) >> (0 ? 31:31)) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) ))
  99727. + {
  99728. + case 0x0:
  99729. + /* System memory. */
  99730. + *Pool = gcvPOOL_SYSTEM;
  99731. + break;
  99732. +
  99733. + case 0x1:
  99734. + /* Virtual memory. */
  99735. + *Pool = gcvPOOL_VIRTUAL;
  99736. + break;
  99737. +
  99738. + default:
  99739. + /* Invalid memory type. */
  99740. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  99741. + return gcvSTATUS_INVALID_ARGUMENT;
  99742. + }
  99743. +
  99744. + /* Return offset of address. */
  99745. + *Offset = (((((gctUINT32) (Address)) >> (0 ? 30:0)) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1)))))) );
  99746. + }
  99747. + else
  99748. + {
  99749. + *Pool = gcvPOOL_SYSTEM;
  99750. + *Offset = Address;
  99751. + }
  99752. +
  99753. + /* Success. */
  99754. + gcmkFOOTER_ARG("*Pool=%d *Offset=0x%08x", *Pool, *Offset);
  99755. + return gcvSTATUS_OK;
  99756. +}
  99757. +
  99758. +/*******************************************************************************
  99759. +**
  99760. +** gckHARDWARE_Execute
  99761. +**
  99762. +** Kickstart the hardware's command processor with an initialized command
  99763. +** buffer.
  99764. +**
  99765. +** INPUT:
  99766. +**
  99767. +** gckHARDWARE Hardware
  99768. +** Pointer to the gckHARDWARE object.
  99769. +**
  99770. +** gctPOINTER Logical
  99771. +** Logical address of command buffer.
  99772. +**
  99773. +** gctSIZE_T Bytes
  99774. +** Number of bytes for the prefetch unit (until after the first LINK).
  99775. +**
  99776. +** OUTPUT:
  99777. +**
  99778. +** Nothing.
  99779. +*/
  99780. +gceSTATUS
  99781. +gckHARDWARE_Execute(
  99782. + IN gckHARDWARE Hardware,
  99783. + IN gctPOINTER Logical,
  99784. +#ifdef __QNXNTO__
  99785. + IN gctPOINTER Physical,
  99786. + IN gctBOOL PhysicalAddresses,
  99787. +#endif
  99788. + IN gctSIZE_T Bytes
  99789. + )
  99790. +{
  99791. + gceSTATUS status;
  99792. + gctUINT32 address = 0, control;
  99793. +
  99794. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Bytes=%lu",
  99795. + Hardware, Logical, Bytes);
  99796. +
  99797. + /* Verify the arguments. */
  99798. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99799. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  99800. +
  99801. +#ifdef __QNXNTO__
  99802. + if (PhysicalAddresses && (Hardware->mmuVersion == 0))
  99803. + {
  99804. + /* Convert physical into hardware specific address. */
  99805. + gcmkONERROR(
  99806. + gckHARDWARE_ConvertPhysical(Hardware, Physical, &address));
  99807. + }
  99808. + else
  99809. + {
  99810. +#endif
  99811. + /* Convert logical into hardware specific address. */
  99812. + gcmkONERROR(
  99813. + gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
  99814. +#ifdef __QNXNTO__
  99815. + }
  99816. +#endif
  99817. +
  99818. + /* Enable all events. */
  99819. + gcmkONERROR(
  99820. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U));
  99821. +
  99822. + /* Write address register. */
  99823. + gcmkONERROR(
  99824. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, address));
  99825. +
  99826. + /* Build control register. */
  99827. + 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)))
  99828. + | ((((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)));
  99829. +
  99830. + /* Set big endian */
  99831. + if (Hardware->bigEndian)
  99832. + {
  99833. + 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)));
  99834. + }
  99835. +
  99836. + /* Write control register. */
  99837. + gcmkONERROR(
  99838. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
  99839. +
  99840. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  99841. + "Started command buffer @ 0x%08x",
  99842. + address);
  99843. +
  99844. + /* Success. */
  99845. + gcmkFOOTER_NO();
  99846. + return gcvSTATUS_OK;
  99847. +
  99848. +OnError:
  99849. + /* Return the status. */
  99850. + gcmkFOOTER();
  99851. + return status;
  99852. +}
  99853. +
  99854. +/*******************************************************************************
  99855. +**
  99856. +** gckHARDWARE_WaitLink
  99857. +**
  99858. +** Append a WAIT/LINK command sequence at the specified location in the command
  99859. +** queue.
  99860. +**
  99861. +** INPUT:
  99862. +**
  99863. +** gckHARDWARE Hardware
  99864. +** Pointer to an gckHARDWARE object.
  99865. +**
  99866. +** gctPOINTER Logical
  99867. +** Pointer to the current location inside the command queue to append
  99868. +** WAIT/LINK command sequence at or gcvNULL just to query the size of the
  99869. +** WAIT/LINK command sequence.
  99870. +**
  99871. +** gctUINT32 Offset
  99872. +** Offset into command buffer required for alignment.
  99873. +**
  99874. +** gctSIZE_T * Bytes
  99875. +** Pointer to the number of bytes available for the WAIT/LINK command
  99876. +** sequence. If 'Logical' is gcvNULL, this argument will be ignored.
  99877. +**
  99878. +** OUTPUT:
  99879. +**
  99880. +** gctSIZE_T * Bytes
  99881. +** Pointer to a variable that will receive the number of bytes required
  99882. +** by the WAIT/LINK command sequence. If 'Bytes' is gcvNULL, nothing will
  99883. +** be returned.
  99884. +**
  99885. +** gctUINT32 * WaitOffset
  99886. +** Pointer to a variable that will receive the offset of the WAIT command
  99887. +** from the specified logcial pointer.
  99888. +** If 'WaitOffset' is gcvNULL nothing will be returned.
  99889. +**
  99890. +** gctSIZE_T * WaitSize
  99891. +** Pointer to a variable that will receive the number of bytes used by
  99892. +** the WAIT command. If 'LinkSize' is gcvNULL nothing will be returned.
  99893. +*/
  99894. +gceSTATUS
  99895. +gckHARDWARE_WaitLink(
  99896. + IN gckHARDWARE Hardware,
  99897. + IN gctPOINTER Logical,
  99898. + IN gctUINT32 Offset,
  99899. + IN OUT gctSIZE_T * Bytes,
  99900. + OUT gctUINT32 * WaitOffset,
  99901. + OUT gctSIZE_T * WaitSize
  99902. + )
  99903. +{
  99904. + static const gctUINT waitCount = 200;
  99905. +
  99906. + gceSTATUS status;
  99907. + gctUINT32 address;
  99908. + gctUINT32_PTR logical;
  99909. + gctSIZE_T bytes;
  99910. +
  99911. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x *Bytes=%lu",
  99912. + Hardware, Logical, Offset, gcmOPT_VALUE(Bytes));
  99913. +
  99914. + /* Verify the arguments. */
  99915. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  99916. + gcmkVERIFY_ARGUMENT((Logical != gcvNULL) || (Bytes != gcvNULL));
  99917. +
  99918. + /* Compute number of bytes required. */
  99919. +#if gcd6000_SUPPORT
  99920. + bytes = gcmALIGN(Offset + 96, 8) - Offset;
  99921. +#else
  99922. + bytes = gcmALIGN(Offset + 16, 8) - Offset;
  99923. +#endif
  99924. +
  99925. + /* Cast the input pointer. */
  99926. + logical = (gctUINT32_PTR) Logical;
  99927. +
  99928. + if (logical != gcvNULL)
  99929. + {
  99930. + /* Not enough space? */
  99931. + if (*Bytes < bytes)
  99932. + {
  99933. + /* Command queue too small. */
  99934. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  99935. + }
  99936. +
  99937. + /* Convert logical into hardware specific address. */
  99938. + gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, &address));
  99939. +
  99940. + /* Store the WAIT/LINK address. */
  99941. + Hardware->lastWaitLink = address;
  99942. +
  99943. + /* Append WAIT(count). */
  99944. + logical[0]
  99945. + = ((((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)))
  99946. + | ((((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)));
  99947. +
  99948. +#if gcd6000_SUPPORT
  99949. + /* Send FE-PE sempahore token. */
  99950. + logical[2]
  99951. + = ((((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)))
  99952. + | ((((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)))
  99953. + | ((((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)));
  99954. +
  99955. + logical[3]
  99956. + = ((((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)))
  99957. + | ((((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)));
  99958. +
  99959. + /* Send FE-PE stall token. */
  99960. + logical[4]
  99961. + = ((((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)));
  99962. +
  99963. + logical[5]
  99964. + = ((((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)))
  99965. + | ((((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)));
  99966. +
  99967. + /*************************************************************/
  99968. + /* Enable chip ID 0. */
  99969. + logical[6] =
  99970. + ((((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)))
  99971. + | (1 << 0);
  99972. +
  99973. + /* Send semaphore from FE to ChipID 1. */
  99974. + logical[8] =
  99975. + ((((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)))
  99976. + | ((((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)))
  99977. + | ((((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)));
  99978. +
  99979. + logical[9] =
  99980. + ((((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)))
  99981. + | ((((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)))
  99982. + | ((((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)));
  99983. +
  99984. + /* Send semaphore from FE to ChipID 1. */
  99985. + logical[10] =
  99986. + ((((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)));
  99987. +
  99988. + logical[11] =
  99989. + ((((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)))
  99990. + | ((((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)))
  99991. + | ((((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)));
  99992. +
  99993. + /*************************************************************/
  99994. + /* Enable chip ID 1. */
  99995. + logical[12] =
  99996. + ((((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)))
  99997. + | (1 << 1);
  99998. +
  99999. + /* Send semaphore from FE to ChipID 1. */
  100000. + logical[14] =
  100001. + ((((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)))
  100002. + | ((((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)))
  100003. + | ((((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)));
  100004. +
  100005. + logical[15] =
  100006. + ((((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)))
  100007. + | ((((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)))
  100008. + | ((((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)));
  100009. +
  100010. + /* Wait for semaphore from ChipID 0. */
  100011. + logical[16] =
  100012. + ((((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)));
  100013. +
  100014. + logical[17] =
  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) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
  100017. + | ((((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)));
  100018. +
  100019. + /*************************************************************/
  100020. + /* Enable all chips. */
  100021. + logical[18] =
  100022. + ((((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)))
  100023. + | (0xFFFF);
  100024. +
  100025. + /* LoadState(AQFlush, 1), flush. */
  100026. + logical[20]
  100027. + = ((((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)))
  100028. + | ((((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)))
  100029. + | ((((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)));
  100030. +
  100031. + logical[21]
  100032. + = ((((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)));
  100033. +
  100034. + /* Append LINK(2, address). */
  100035. + logical[22]
  100036. + = ((((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)))
  100037. + | ((((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)));
  100038. +
  100039. + logical[23] = address;
  100040. +#else
  100041. + /* Append LINK(2, address). */
  100042. + logical[2]
  100043. + = ((((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)))
  100044. + | ((((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)));
  100045. +
  100046. + logical[3] = address;
  100047. +
  100048. + gcmkTRACE_ZONE(
  100049. + gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100050. + "0x%08x: WAIT %u", address, waitCount
  100051. + );
  100052. +
  100053. + gcmkTRACE_ZONE(
  100054. + gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100055. + "0x%08x: LINK 0x%08x, #%lu",
  100056. + address + 8, address, bytes
  100057. + );
  100058. +#endif
  100059. +
  100060. + if (WaitOffset != gcvNULL)
  100061. + {
  100062. + /* Return the offset pointer to WAIT command. */
  100063. + *WaitOffset = 0;
  100064. + }
  100065. +
  100066. + if (WaitSize != gcvNULL)
  100067. + {
  100068. + /* Return number of bytes used by the WAIT command. */
  100069. + *WaitSize = 8;
  100070. + }
  100071. + }
  100072. +
  100073. + if (Bytes != gcvNULL)
  100074. + {
  100075. + /* Return number of bytes required by the WAIT/LINK command
  100076. + ** sequence. */
  100077. + *Bytes = bytes;
  100078. + }
  100079. +
  100080. + /* Success. */
  100081. + gcmkFOOTER_ARG("*Bytes=%lu *WaitOffset=0x%x *WaitSize=%lu",
  100082. + gcmOPT_VALUE(Bytes), gcmOPT_VALUE(WaitOffset),
  100083. + gcmOPT_VALUE(WaitSize));
  100084. + return gcvSTATUS_OK;
  100085. +
  100086. +OnError:
  100087. + /* Return the status. */
  100088. + gcmkFOOTER();
  100089. + return status;
  100090. +}
  100091. +
  100092. +/*******************************************************************************
  100093. +**
  100094. +** gckHARDWARE_End
  100095. +**
  100096. +** Append an END command at the specified location in the command queue.
  100097. +**
  100098. +** INPUT:
  100099. +**
  100100. +** gckHARDWARE Hardware
  100101. +** Pointer to an gckHARDWARE object.
  100102. +**
  100103. +** gctPOINTER Logical
  100104. +** Pointer to the current location inside the command queue to append
  100105. +** END command at or gcvNULL just to query the size of the END command.
  100106. +**
  100107. +** gctSIZE_T * Bytes
  100108. +** Pointer to the number of bytes available for the END command. If
  100109. +** 'Logical' is gcvNULL, this argument will be ignored.
  100110. +**
  100111. +** OUTPUT:
  100112. +**
  100113. +** gctSIZE_T * Bytes
  100114. +** Pointer to a variable that will receive the number of bytes required
  100115. +** for the END command. If 'Bytes' is gcvNULL, nothing will be returned.
  100116. +*/
  100117. +gceSTATUS
  100118. +gckHARDWARE_End(
  100119. + IN gckHARDWARE Hardware,
  100120. + IN gctPOINTER Logical,
  100121. + IN OUT gctSIZE_T * Bytes
  100122. + )
  100123. +{
  100124. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  100125. + gceSTATUS status;
  100126. +
  100127. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
  100128. + Hardware, Logical, gcmOPT_VALUE(Bytes));
  100129. +
  100130. + /* Verify the arguments. */
  100131. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100132. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100133. +
  100134. + if (Logical != gcvNULL)
  100135. + {
  100136. + if (*Bytes < 8)
  100137. + {
  100138. + /* Command queue too small. */
  100139. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100140. + }
  100141. +
  100142. + /* Append END. */
  100143. + logical[0] =
  100144. + ((((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)));
  100145. +
  100146. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: END", Logical);
  100147. +
  100148. + /* Make sure the CPU writes out the data to memory. */
  100149. + gcmkONERROR(
  100150. + gckOS_MemoryBarrier(Hardware->os, Logical));
  100151. + }
  100152. +
  100153. + if (Bytes != gcvNULL)
  100154. + {
  100155. + /* Return number of bytes required by the END command. */
  100156. + *Bytes = 8;
  100157. + }
  100158. +
  100159. + /* Success. */
  100160. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100161. + return gcvSTATUS_OK;
  100162. +
  100163. +OnError:
  100164. + /* Return the status. */
  100165. + gcmkFOOTER();
  100166. + return status;
  100167. +}
  100168. +
  100169. +/*******************************************************************************
  100170. +**
  100171. +** gckHARDWARE_Nop
  100172. +**
  100173. +** Append a NOP command at the specified location in the command queue.
  100174. +**
  100175. +** INPUT:
  100176. +**
  100177. +** gckHARDWARE Hardware
  100178. +** Pointer to an gckHARDWARE object.
  100179. +**
  100180. +** gctPOINTER Logical
  100181. +** Pointer to the current location inside the command queue to append
  100182. +** NOP command at or gcvNULL just to query the size of the NOP command.
  100183. +**
  100184. +** gctSIZE_T * Bytes
  100185. +** Pointer to the number of bytes available for the NOP command. If
  100186. +** 'Logical' is gcvNULL, this argument will be ignored.
  100187. +**
  100188. +** OUTPUT:
  100189. +**
  100190. +** gctSIZE_T * Bytes
  100191. +** Pointer to a variable that will receive the number of bytes required
  100192. +** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned.
  100193. +*/
  100194. +gceSTATUS
  100195. +gckHARDWARE_Nop(
  100196. + IN gckHARDWARE Hardware,
  100197. + IN gctPOINTER Logical,
  100198. + IN OUT gctSIZE_T * Bytes
  100199. + )
  100200. +{
  100201. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  100202. + gceSTATUS status;
  100203. +
  100204. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
  100205. + Hardware, Logical, gcmOPT_VALUE(Bytes));
  100206. +
  100207. + /* Verify the arguments. */
  100208. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100209. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100210. +
  100211. + if (Logical != gcvNULL)
  100212. + {
  100213. + if (*Bytes < 8)
  100214. + {
  100215. + /* Command queue too small. */
  100216. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100217. + }
  100218. +
  100219. + /* Append NOP. */
  100220. + 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)));
  100221. +
  100222. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical);
  100223. + }
  100224. +
  100225. + if (Bytes != gcvNULL)
  100226. + {
  100227. + /* Return number of bytes required by the NOP command. */
  100228. + *Bytes = 8;
  100229. + }
  100230. +
  100231. + /* Success. */
  100232. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100233. + return gcvSTATUS_OK;
  100234. +
  100235. +OnError:
  100236. + /* Return the status. */
  100237. + gcmkFOOTER();
  100238. + return status;
  100239. +}
  100240. +
  100241. +/*******************************************************************************
  100242. +**
  100243. +** gckHARDWARE_Wait
  100244. +**
  100245. +** Append a WAIT command at the specified location in the command queue.
  100246. +**
  100247. +** INPUT:
  100248. +**
  100249. +** gckHARDWARE Hardware
  100250. +** Pointer to an gckHARDWARE object.
  100251. +**
  100252. +** gctPOINTER Logical
  100253. +** Pointer to the current location inside the command queue to append
  100254. +** WAIT command at or gcvNULL just to query the size of the WAIT command.
  100255. +**
  100256. +** gctUINT32 Count
  100257. +** Number of cycles to wait.
  100258. +**
  100259. +** gctSIZE_T * Bytes
  100260. +** Pointer to the number of bytes available for the WAIT command. If
  100261. +** 'Logical' is gcvNULL, this argument will be ignored.
  100262. +**
  100263. +** OUTPUT:
  100264. +**
  100265. +** gctSIZE_T * Bytes
  100266. +** Pointer to a variable that will receive the number of bytes required
  100267. +** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned.
  100268. +*/
  100269. +gceSTATUS
  100270. +gckHARDWARE_Wait(
  100271. + IN gckHARDWARE Hardware,
  100272. + IN gctPOINTER Logical,
  100273. + IN gctUINT32 Count,
  100274. + IN OUT gctSIZE_T * Bytes
  100275. + )
  100276. +{
  100277. + gceSTATUS status;
  100278. + gctUINT32_PTR logical;
  100279. +
  100280. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Count=%u *Bytes=%lu",
  100281. + Hardware, Logical, Count, gcmOPT_VALUE(Bytes));
  100282. +
  100283. + /* Verify the arguments. */
  100284. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100285. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100286. +
  100287. + /* Cast the input pointer. */
  100288. + logical = (gctUINT32_PTR) Logical;
  100289. +
  100290. + if (Logical != gcvNULL)
  100291. + {
  100292. + if (*Bytes < 8)
  100293. + {
  100294. + /* Command queue too small. */
  100295. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100296. + }
  100297. +
  100298. + /* Append WAIT. */
  100299. + 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)))
  100300. + | ((((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)));
  100301. +
  100302. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  100303. + {
  100304. + gctUINT32 address;
  100305. +
  100306. + /* Convert logical into hardware specific address. */
  100307. + gcmkONERROR(gckHARDWARE_ConvertLogical(
  100308. + Hardware, logical, &address
  100309. + ));
  100310. +
  100311. + gcmkTRACE_ZONE(
  100312. + gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100313. + "0x%08x: WAIT %u", address, Count
  100314. + );
  100315. + }
  100316. +#endif
  100317. + }
  100318. +
  100319. + if (Bytes != gcvNULL)
  100320. + {
  100321. + /* Return number of bytes required by the WAIT command. */
  100322. + *Bytes = 8;
  100323. + }
  100324. +
  100325. + /* Success. */
  100326. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100327. + return gcvSTATUS_OK;
  100328. +
  100329. +OnError:
  100330. + /* Return the status. */
  100331. + gcmkFOOTER();
  100332. + return status;
  100333. +}
  100334. +
  100335. +/*******************************************************************************
  100336. +**
  100337. +** gckHARDWARE_Event
  100338. +**
  100339. +** Append an EVENT command at the specified location in the command queue.
  100340. +**
  100341. +** INPUT:
  100342. +**
  100343. +** gckHARDWARE Hardware
  100344. +** Pointer to an gckHARDWARE object.
  100345. +**
  100346. +** gctPOINTER Logical
  100347. +** Pointer to the current location inside the command queue to append
  100348. +** the EVENT command at or gcvNULL just to query the size of the EVENT
  100349. +** command.
  100350. +**
  100351. +** gctUINT8 Event
  100352. +** Event ID to program.
  100353. +**
  100354. +** gceKERNEL_WHERE FromWhere
  100355. +** Location of the pipe to send the event.
  100356. +**
  100357. +** gctSIZE_T * Bytes
  100358. +** Pointer to the number of bytes available for the EVENT command. If
  100359. +** 'Logical' is gcvNULL, this argument will be ignored.
  100360. +**
  100361. +** OUTPUT:
  100362. +**
  100363. +** gctSIZE_T * Bytes
  100364. +** Pointer to a variable that will receive the number of bytes required
  100365. +** for the EVENT command. If 'Bytes' is gcvNULL, nothing will be
  100366. +** returned.
  100367. +*/
  100368. +gceSTATUS
  100369. +gckHARDWARE_Event(
  100370. + IN gckHARDWARE Hardware,
  100371. + IN gctPOINTER Logical,
  100372. + IN gctUINT8 Event,
  100373. + IN gceKERNEL_WHERE FromWhere,
  100374. + IN OUT gctSIZE_T * Bytes
  100375. + )
  100376. +{
  100377. + gctUINT size;
  100378. + gctUINT32 destination = 0;
  100379. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  100380. + gceSTATUS status;
  100381. +
  100382. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Event=%u FromWhere=%d *Bytes=%lu",
  100383. + Hardware, Logical, Event, FromWhere, gcmOPT_VALUE(Bytes));
  100384. +
  100385. + /* Verify the arguments. */
  100386. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100387. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100388. + gcmkVERIFY_ARGUMENT(Event < 32);
  100389. +
  100390. + /* Determine the size of the command. */
  100391. +
  100392. + size = (Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL))
  100393. + ? gcmALIGN(8 + (1 + 5) * 4, 8) /* EVENT + 5 STATES */
  100394. + : 8;
  100395. +
  100396. + if (Logical != gcvNULL)
  100397. + {
  100398. + if (*Bytes < size)
  100399. + {
  100400. + /* Command queue too small. */
  100401. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100402. + }
  100403. +
  100404. + switch (FromWhere)
  100405. + {
  100406. + case gcvKERNEL_COMMAND:
  100407. + /* From command processor. */
  100408. + 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)));
  100409. + break;
  100410. +
  100411. + case gcvKERNEL_PIXEL:
  100412. + /* From pixel engine. */
  100413. + 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)));
  100414. + break;
  100415. +
  100416. + default:
  100417. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  100418. + }
  100419. +
  100420. + /* Append EVENT(Event, destiantion). */
  100421. + 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)))
  100422. + | ((((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)))
  100423. + | ((((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)));
  100424. +
  100425. + 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)));
  100426. +
  100427. + /* Make sure the event ID gets written out before GPU can access it. */
  100428. + gcmkONERROR(
  100429. + gckOS_MemoryBarrier(Hardware->os, logical + 1));
  100430. +
  100431. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  100432. + {
  100433. + gctUINT32 phys;
  100434. + gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys);
  100435. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100436. + "0x%08x: EVENT %d", phys, Event);
  100437. + }
  100438. +#endif
  100439. +
  100440. + /* Append the extra states. These are needed for the chips that do not
  100441. + ** support back-to-back events due to the async interface. The extra
  100442. + ** states add the necessary delay to ensure that event IDs do not
  100443. + ** collide. */
  100444. + if (size > 8)
  100445. + {
  100446. + 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)))
  100447. + | ((((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)))
  100448. + | ((((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)));
  100449. + logical[3] = 0;
  100450. + logical[4] = 0;
  100451. + logical[5] = 0;
  100452. + logical[6] = 0;
  100453. + logical[7] = 0;
  100454. + }
  100455. + }
  100456. +
  100457. + if (Bytes != gcvNULL)
  100458. + {
  100459. + /* Return number of bytes required by the EVENT command. */
  100460. + *Bytes = size;
  100461. + }
  100462. +
  100463. + /* Success. */
  100464. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100465. + return gcvSTATUS_OK;
  100466. +
  100467. +OnError:
  100468. + /* Return the status. */
  100469. + gcmkFOOTER();
  100470. + return status;
  100471. +}
  100472. +
  100473. +/*******************************************************************************
  100474. +**
  100475. +** gckHARDWARE_PipeSelect
  100476. +**
  100477. +** Append a PIPESELECT command at the specified location in the command queue.
  100478. +**
  100479. +** INPUT:
  100480. +**
  100481. +** gckHARDWARE Hardware
  100482. +** Pointer to an gckHARDWARE object.
  100483. +**
  100484. +** gctPOINTER Logical
  100485. +** Pointer to the current location inside the command queue to append
  100486. +** the PIPESELECT command at or gcvNULL just to query the size of the
  100487. +** PIPESELECT command.
  100488. +**
  100489. +** gcePIPE_SELECT Pipe
  100490. +** Pipe value to select.
  100491. +**
  100492. +** gctSIZE_T * Bytes
  100493. +** Pointer to the number of bytes available for the PIPESELECT command.
  100494. +** If 'Logical' is gcvNULL, this argument will be ignored.
  100495. +**
  100496. +** OUTPUT:
  100497. +**
  100498. +** gctSIZE_T * Bytes
  100499. +** Pointer to a variable that will receive the number of bytes required
  100500. +** for the PIPESELECT command. If 'Bytes' is gcvNULL, nothing will be
  100501. +** returned.
  100502. +*/
  100503. +gceSTATUS
  100504. +gckHARDWARE_PipeSelect(
  100505. + IN gckHARDWARE Hardware,
  100506. + IN gctPOINTER Logical,
  100507. + IN gcePIPE_SELECT Pipe,
  100508. + IN OUT gctSIZE_T * Bytes
  100509. + )
  100510. +{
  100511. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  100512. + gceSTATUS status;
  100513. +
  100514. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Pipe=%d *Bytes=%lu",
  100515. + Hardware, Logical, Pipe, gcmOPT_VALUE(Bytes));
  100516. +
  100517. + /* Verify the arguments. */
  100518. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100519. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100520. +
  100521. + /* Append a PipeSelect. */
  100522. + if (Logical != gcvNULL)
  100523. + {
  100524. + gctUINT32 flush, stall;
  100525. +
  100526. + if (*Bytes < 32)
  100527. + {
  100528. + /* Command queue too small. */
  100529. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100530. + }
  100531. +
  100532. + flush = (Pipe == gcvPIPE_2D)
  100533. + ? ((((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)))
  100534. + | ((((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)))
  100535. + : ((((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)));
  100536. +
  100537. + 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)))
  100538. + | ((((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)));
  100539. +
  100540. + /* LoadState(AQFlush, 1), flush. */
  100541. + logical[0]
  100542. + = ((((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)))
  100543. + | ((((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)))
  100544. + | ((((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)));
  100545. +
  100546. + logical[1]
  100547. + = flush;
  100548. +
  100549. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100550. + "0x%x: FLUSH 0x%x", logical, flush);
  100551. +
  100552. + /* LoadState(AQSempahore, 1), stall. */
  100553. + logical[2]
  100554. + = ((((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)))
  100555. + | ((((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)))
  100556. + | ((((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)));
  100557. +
  100558. + logical[3]
  100559. + = stall;
  100560. +
  100561. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100562. + "0x%x: SEMAPHORE 0x%x", logical + 2, stall);
  100563. +
  100564. + /* Stall, stall. */
  100565. + 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)));
  100566. + logical[5] = stall;
  100567. +
  100568. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100569. + "0x%x: STALL 0x%x", logical + 4, stall);
  100570. +
  100571. + /* LoadState(AQPipeSelect, 1), pipe. */
  100572. + logical[6]
  100573. + = ((((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)))
  100574. + | ((((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)))
  100575. + | ((((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)));
  100576. +
  100577. + logical[7] = (Pipe == gcvPIPE_2D)
  100578. + ? 0x1
  100579. + : 0x0;
  100580. +
  100581. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100582. + "0x%x: PIPE %d", logical + 6, Pipe);
  100583. + }
  100584. +
  100585. + if (Bytes != gcvNULL)
  100586. + {
  100587. + /* Return number of bytes required by the PIPESELECT command. */
  100588. + *Bytes = 32;
  100589. + }
  100590. +
  100591. + /* Success. */
  100592. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100593. + return gcvSTATUS_OK;
  100594. +
  100595. +OnError:
  100596. + /* Return the status. */
  100597. + gcmkFOOTER();
  100598. + return status;
  100599. +}
  100600. +
  100601. +/*******************************************************************************
  100602. +**
  100603. +** gckHARDWARE_Link
  100604. +**
  100605. +** Append a LINK command at the specified location in the command queue.
  100606. +**
  100607. +** INPUT:
  100608. +**
  100609. +** gckHARDWARE Hardware
  100610. +** Pointer to an gckHARDWARE object.
  100611. +**
  100612. +** gctPOINTER Logical
  100613. +** Pointer to the current location inside the command queue to append
  100614. +** the LINK command at or gcvNULL just to query the size of the LINK
  100615. +** command.
  100616. +**
  100617. +** gctPOINTER FetchAddress
  100618. +** Logical address of destination of LINK.
  100619. +**
  100620. +** gctSIZE_T FetchSize
  100621. +** Number of bytes in destination of LINK.
  100622. +**
  100623. +** gctSIZE_T * Bytes
  100624. +** Pointer to the number of bytes available for the LINK command. If
  100625. +** 'Logical' is gcvNULL, this argument will be ignored.
  100626. +**
  100627. +** OUTPUT:
  100628. +**
  100629. +** gctSIZE_T * Bytes
  100630. +** Pointer to a variable that will receive the number of bytes required
  100631. +** for the LINK command. If 'Bytes' is gcvNULL, nothing will be returned.
  100632. +*/
  100633. +gceSTATUS
  100634. +gckHARDWARE_Link(
  100635. + IN gckHARDWARE Hardware,
  100636. + IN gctPOINTER Logical,
  100637. + IN gctPOINTER FetchAddress,
  100638. + IN gctSIZE_T FetchSize,
  100639. + IN OUT gctSIZE_T * Bytes
  100640. + )
  100641. +{
  100642. + gceSTATUS status;
  100643. + gctSIZE_T bytes;
  100644. + gctUINT32 address;
  100645. + gctUINT32 link;
  100646. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  100647. +
  100648. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x FetchAddress=0x%x FetchSize=%lu "
  100649. + "*Bytes=%lu",
  100650. + Hardware, Logical, FetchAddress, FetchSize,
  100651. + gcmOPT_VALUE(Bytes));
  100652. +
  100653. + /* Verify the arguments. */
  100654. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100655. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  100656. +
  100657. + if (Logical != gcvNULL)
  100658. + {
  100659. + if (*Bytes < 8)
  100660. + {
  100661. + /* Command queue too small. */
  100662. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  100663. + }
  100664. +
  100665. + /* Convert logical address to hardware address. */
  100666. + gcmkONERROR(
  100667. + gckHARDWARE_ConvertLogical(Hardware, FetchAddress, &address));
  100668. +
  100669. + gcmkONERROR(
  100670. + gckOS_WriteMemory(Hardware->os, logical + 1, address));
  100671. +
  100672. + /* Make sure the address got written before the LINK command. */
  100673. + gcmkONERROR(
  100674. + gckOS_MemoryBarrier(Hardware->os, logical + 1));
  100675. +
  100676. + /* Compute number of 64-byte aligned bytes to fetch. */
  100677. + bytes = gcmALIGN(address + FetchSize, 8) - address;
  100678. +
  100679. + /* Append LINK(bytes / 8), FetchAddress. */
  100680. + 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)))
  100681. + | ((((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)));
  100682. +
  100683. + gcmkONERROR(
  100684. + gckOS_WriteMemory(Hardware->os, logical, link));
  100685. +
  100686. + /* Memory barrier. */
  100687. + gcmkONERROR(
  100688. + gckOS_MemoryBarrier(Hardware->os, logical));
  100689. +
  100690. +#if gcdLINK_QUEUE_SIZE && gcdVIRTUAL_COMMAND_BUFFER
  100691. + if (address >= 0x80000000)
  100692. + {
  100693. + gckLINKQUEUE_Enqueue(&Hardware->linkQueue, address, address + bytes);
  100694. + }
  100695. +#endif
  100696. + }
  100697. +
  100698. + if (Bytes != gcvNULL)
  100699. + {
  100700. + /* Return number of bytes required by the LINK command. */
  100701. + *Bytes = 8;
  100702. + }
  100703. +
  100704. + /* Success. */
  100705. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  100706. + return gcvSTATUS_OK;
  100707. +
  100708. +OnError:
  100709. + /* Return the status. */
  100710. + gcmkFOOTER();
  100711. + return status;
  100712. +}
  100713. +
  100714. +/*******************************************************************************
  100715. +**
  100716. +** gckHARDWARE_UpdateQueueTail
  100717. +**
  100718. +** Update the tail of the command queue.
  100719. +**
  100720. +** INPUT:
  100721. +**
  100722. +** gckHARDWARE Hardware
  100723. +** Pointer to an gckHARDWARE object.
  100724. +**
  100725. +** gctPOINTER Logical
  100726. +** Logical address of the start of the command queue.
  100727. +**
  100728. +** gctUINT32 Offset
  100729. +** Offset into the command queue of the tail (last command).
  100730. +**
  100731. +** OUTPUT:
  100732. +**
  100733. +** Nothing.
  100734. +*/
  100735. +gceSTATUS
  100736. +gckHARDWARE_UpdateQueueTail(
  100737. + IN gckHARDWARE Hardware,
  100738. + IN gctPOINTER Logical,
  100739. + IN gctUINT32 Offset
  100740. + )
  100741. +{
  100742. + gceSTATUS status;
  100743. +
  100744. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x",
  100745. + Hardware, Logical, Offset);
  100746. +
  100747. + /* Verify the hardware. */
  100748. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100749. +
  100750. + /* Force a barrier. */
  100751. + gcmkONERROR(
  100752. + gckOS_MemoryBarrier(Hardware->os, Logical));
  100753. +
  100754. + /* Notify gckKERNEL object of change. */
  100755. + gcmkONERROR(
  100756. + gckKERNEL_Notify(Hardware->kernel,
  100757. + gcvNOTIFY_COMMAND_QUEUE,
  100758. + gcvFALSE));
  100759. +
  100760. + if (status == gcvSTATUS_CHIP_NOT_READY)
  100761. + {
  100762. + gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
  100763. + }
  100764. +
  100765. + /* Success. */
  100766. + gcmkFOOTER_NO();
  100767. + return gcvSTATUS_OK;
  100768. +
  100769. +OnError:
  100770. + /* Return the status. */
  100771. + gcmkFOOTER();
  100772. + return status;
  100773. +}
  100774. +
  100775. +/*******************************************************************************
  100776. +**
  100777. +** gckHARDWARE_ConvertLogical
  100778. +**
  100779. +** Convert a logical system address into a hardware specific address.
  100780. +**
  100781. +** INPUT:
  100782. +**
  100783. +** gckHARDWARE Hardware
  100784. +** Pointer to an gckHARDWARE object.
  100785. +**
  100786. +** gctPOINTER Logical
  100787. +** Logical address to convert.
  100788. +**
  100789. +** gctUINT32* Address
  100790. +** Return hardware specific address.
  100791. +**
  100792. +** OUTPUT:
  100793. +**
  100794. +** Nothing.
  100795. +*/
  100796. +gceSTATUS
  100797. +gckHARDWARE_ConvertLogical(
  100798. + IN gckHARDWARE Hardware,
  100799. + IN gctPOINTER Logical,
  100800. + OUT gctUINT32 * Address
  100801. + )
  100802. +{
  100803. + gctUINT32 address;
  100804. + gceSTATUS status;
  100805. + gctUINT32 baseAddress;
  100806. +
  100807. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
  100808. +
  100809. + /* Verify the arguments. */
  100810. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100811. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  100812. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  100813. +
  100814. +#if gcdVIRTUAL_COMMAND_BUFFER
  100815. + status = gckKERNEL_GetGPUAddress(Hardware->kernel, Logical, Address);
  100816. +
  100817. + if (status == gcvSTATUS_INVALID_ADDRESS)
  100818. +#endif
  100819. + {
  100820. + /* Convert logical address into a physical address. */
  100821. + gcmkONERROR(
  100822. + gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
  100823. +
  100824. + /* For old MMU, get GPU address according to baseAddress. */
  100825. + if (Hardware->mmuVersion == 0)
  100826. + {
  100827. + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  100828. +
  100829. + /* Subtract base address to get a GPU address. */
  100830. + gcmkASSERT(address >= baseAddress);
  100831. + address -= baseAddress;
  100832. + }
  100833. +
  100834. + /* Return hardware specific address. */
  100835. + *Address = (Hardware->mmuVersion == 0)
  100836. + ? ((((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)))
  100837. + | ((((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)))
  100838. + : address;
  100839. + }
  100840. +
  100841. + /* Success. */
  100842. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  100843. + return gcvSTATUS_OK;
  100844. +
  100845. +OnError:
  100846. + /* Return the status. */
  100847. + gcmkFOOTER();
  100848. + return status;
  100849. +}
  100850. +
  100851. +/*******************************************************************************
  100852. +**
  100853. +** gckHARDWARE_ConvertPhysical
  100854. +**
  100855. +** Convert a physical address into a hardware specific address.
  100856. +**
  100857. +** INPUT:
  100858. +**
  100859. +** gckHARDWARE Hardware
  100860. +** Pointer to an gckHARDWARE object.
  100861. +**
  100862. +** gctPHYS_ADDR Physical
  100863. +** Physical address to convert.
  100864. +**
  100865. +** gctUINT32* Address
  100866. +** Return hardware specific address.
  100867. +**
  100868. +** OUTPUT:
  100869. +**
  100870. +** Nothing.
  100871. +*/
  100872. +gceSTATUS
  100873. +gckHARDWARE_ConvertPhysical(
  100874. + IN gckHARDWARE Hardware,
  100875. + IN gctPHYS_ADDR Physical,
  100876. + OUT gctUINT32 * Address
  100877. + )
  100878. +{
  100879. + gctUINT32 address;
  100880. + gctUINT32 baseAddress;
  100881. +
  100882. + gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x", Hardware, Physical);
  100883. +
  100884. + /* Verify the arguments. */
  100885. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100886. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  100887. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  100888. +
  100889. + address = gcmPTR2INT(Physical);
  100890. +
  100891. + /* For old MMU, get GPU address according to baseAddress. */
  100892. + if (Hardware->mmuVersion == 0)
  100893. + {
  100894. + gcmkVERIFY_OK(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  100895. +
  100896. + /* Subtract base address to get a GPU address. */
  100897. + gcmkASSERT(address >= baseAddress);
  100898. + address -= baseAddress;
  100899. + }
  100900. +
  100901. + /* Return hardware specific address. */
  100902. + *Address = (Hardware->mmuVersion == 0)
  100903. + ? ((((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)))
  100904. + | ((((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)))
  100905. + : address;
  100906. +
  100907. + /* Return the status. */
  100908. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  100909. + return gcvSTATUS_OK;
  100910. +}
  100911. +
  100912. +/*******************************************************************************
  100913. +**
  100914. +** gckHARDWARE_Interrupt
  100915. +**
  100916. +** Process an interrupt.
  100917. +**
  100918. +** INPUT:
  100919. +**
  100920. +** gckHARDWARE Hardware
  100921. +** Pointer to an gckHARDWARE object.
  100922. +**
  100923. +** gctBOOL InterruptValid
  100924. +** If gcvTRUE, this function will read the interrupt acknowledge
  100925. +** register, stores the data, and return whether or not the interrupt
  100926. +** is ours or not. If gcvFALSE, this functions will read the interrupt
  100927. +** acknowledge register and combine it with any stored value to handle
  100928. +** the event notifications.
  100929. +**
  100930. +** OUTPUT:
  100931. +**
  100932. +** Nothing.
  100933. +*/
  100934. +gceSTATUS
  100935. +gckHARDWARE_Interrupt(
  100936. + IN gckHARDWARE Hardware,
  100937. + IN gctBOOL InterruptValid
  100938. + )
  100939. +{
  100940. + gckEVENT eventObj;
  100941. + gctUINT32 data;
  100942. + gceSTATUS status;
  100943. +
  100944. + gcmkHEADER_ARG("Hardware=0x%x InterruptValid=%d", Hardware, InterruptValid);
  100945. +
  100946. + /* Verify the arguments. */
  100947. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  100948. +
  100949. + /* Extract gckEVENT object. */
  100950. + eventObj = Hardware->kernel->eventObj;
  100951. + gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
  100952. +
  100953. + if (InterruptValid)
  100954. + {
  100955. + /* Read AQIntrAcknowledge register. */
  100956. + gcmkONERROR(
  100957. + gckOS_ReadRegisterEx(Hardware->os,
  100958. + Hardware->core,
  100959. + 0x00010,
  100960. + &data));
  100961. +
  100962. + if (data == 0)
  100963. + {
  100964. + /* Not our interrupt. */
  100965. + status = gcvSTATUS_NOT_OUR_INTERRUPT;
  100966. + }
  100967. + else
  100968. + {
  100969. + /* Inform gckEVENT of the interrupt. */
  100970. + status = gckEVENT_Interrupt(eventObj, data);
  100971. + }
  100972. + }
  100973. + else
  100974. + {
  100975. + /* Handle events. */
  100976. + status = gckEVENT_Notify(eventObj, 0);
  100977. + }
  100978. +
  100979. +OnError:
  100980. + /* Return the status. */
  100981. + gcmkFOOTER();
  100982. + return status;
  100983. +}
  100984. +
  100985. +/*******************************************************************************
  100986. +**
  100987. +** gckHARDWARE_QueryCommandBuffer
  100988. +**
  100989. +** Query the command buffer alignment and number of reserved bytes.
  100990. +**
  100991. +** INPUT:
  100992. +**
  100993. +** gckHARDWARE Harwdare
  100994. +** Pointer to an gckHARDWARE object.
  100995. +**
  100996. +** OUTPUT:
  100997. +**
  100998. +** gctSIZE_T * Alignment
  100999. +** Pointer to a variable receiving the alignment for each command.
  101000. +**
  101001. +** gctSIZE_T * ReservedHead
  101002. +** Pointer to a variable receiving the number of reserved bytes at the
  101003. +** head of each command buffer.
  101004. +**
  101005. +** gctSIZE_T * ReservedTail
  101006. +** Pointer to a variable receiving the number of bytes reserved at the
  101007. +** tail of each command buffer.
  101008. +*/
  101009. +gceSTATUS
  101010. +gckHARDWARE_QueryCommandBuffer(
  101011. + IN gckHARDWARE Hardware,
  101012. + OUT gctSIZE_T * Alignment,
  101013. + OUT gctSIZE_T * ReservedHead,
  101014. + OUT gctSIZE_T * ReservedTail
  101015. + )
  101016. +{
  101017. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101018. +
  101019. + /* Verify the arguments. */
  101020. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101021. +
  101022. + if (Alignment != gcvNULL)
  101023. + {
  101024. + /* Align every 8 bytes. */
  101025. + *Alignment = 8;
  101026. + }
  101027. +
  101028. + if (ReservedHead != gcvNULL)
  101029. + {
  101030. + /* Reserve space for SelectPipe(). */
  101031. + *ReservedHead = 32;
  101032. + }
  101033. +
  101034. + if (ReservedTail != gcvNULL)
  101035. + {
  101036. + /* Reserve space for Link(). */
  101037. + *ReservedTail = 8;
  101038. + }
  101039. +
  101040. + /* Success. */
  101041. + gcmkFOOTER_ARG("*Alignment=%lu *ReservedHead=%lu *ReservedTail=%lu",
  101042. + gcmOPT_VALUE(Alignment), gcmOPT_VALUE(ReservedHead),
  101043. + gcmOPT_VALUE(ReservedTail));
  101044. + return gcvSTATUS_OK;
  101045. +}
  101046. +
  101047. +/*******************************************************************************
  101048. +**
  101049. +** gckHARDWARE_QuerySystemMemory
  101050. +**
  101051. +** Query the command buffer alignment and number of reserved bytes.
  101052. +**
  101053. +** INPUT:
  101054. +**
  101055. +** gckHARDWARE Harwdare
  101056. +** Pointer to an gckHARDWARE object.
  101057. +**
  101058. +** OUTPUT:
  101059. +**
  101060. +** gctSIZE_T * SystemSize
  101061. +** Pointer to a variable that receives the maximum size of the system
  101062. +** memory.
  101063. +**
  101064. +** gctUINT32 * SystemBaseAddress
  101065. +** Poinetr to a variable that receives the base address for system
  101066. +** memory.
  101067. +*/
  101068. +gceSTATUS
  101069. +gckHARDWARE_QuerySystemMemory(
  101070. + IN gckHARDWARE Hardware,
  101071. + OUT gctSIZE_T * SystemSize,
  101072. + OUT gctUINT32 * SystemBaseAddress
  101073. + )
  101074. +{
  101075. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101076. +
  101077. + /* Verify the arguments. */
  101078. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101079. +
  101080. + if (SystemSize != gcvNULL)
  101081. + {
  101082. + /* Maximum system memory can be 2GB. */
  101083. + *SystemSize = 1U << 31;
  101084. + }
  101085. +
  101086. + if (SystemBaseAddress != gcvNULL)
  101087. + {
  101088. + /* Set system memory base address. */
  101089. + *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)));
  101090. + }
  101091. +
  101092. + /* Success. */
  101093. + gcmkFOOTER_ARG("*SystemSize=%lu *SystemBaseAddress=%lu",
  101094. + gcmOPT_VALUE(SystemSize), gcmOPT_VALUE(SystemBaseAddress));
  101095. + return gcvSTATUS_OK;
  101096. +}
  101097. +
  101098. +#ifndef VIVANTE_NO_3D
  101099. +/*******************************************************************************
  101100. +**
  101101. +** gckHARDWARE_QueryShaderCaps
  101102. +**
  101103. +** Query the shader capabilities.
  101104. +**
  101105. +** INPUT:
  101106. +**
  101107. +** Nothing.
  101108. +**
  101109. +** OUTPUT:
  101110. +**
  101111. +** gctUINT * VertexUniforms
  101112. +** Pointer to a variable receiving the number of uniforms in the vertex
  101113. +** shader.
  101114. +**
  101115. +** gctUINT * FragmentUniforms
  101116. +** Pointer to a variable receiving the number of uniforms in the
  101117. +** fragment shader.
  101118. +**
  101119. +** gctUINT * Varyings
  101120. +** Pointer to a variable receiving the maimum number of varyings.
  101121. +*/
  101122. +gceSTATUS
  101123. +gckHARDWARE_QueryShaderCaps(
  101124. + IN gckHARDWARE Hardware,
  101125. + OUT gctUINT * VertexUniforms,
  101126. + OUT gctUINT * FragmentUniforms,
  101127. + OUT gctUINT * Varyings
  101128. + )
  101129. +{
  101130. + gctUINT32 vsConstMax;
  101131. + gctUINT32 psConstMax;
  101132. +
  101133. + gcmkHEADER_ARG("Hardware=0x%x VertexUniforms=0x%x "
  101134. + "FragmentUniforms=0x%x Varyings=0x%x",
  101135. + Hardware, VertexUniforms,
  101136. + FragmentUniforms, Varyings);
  101137. +
  101138. + if ((Hardware->identity.chipModel == gcv2000)
  101139. + && (Hardware->identity.chipRevision == 0x5118))
  101140. + {
  101141. + vsConstMax = 256;
  101142. + psConstMax = 64;
  101143. + }
  101144. + else if (Hardware->identity.numConstants > 256)
  101145. + {
  101146. + vsConstMax = 256;
  101147. + psConstMax = 256;
  101148. + }
  101149. + else if (Hardware->identity.numConstants == 256)
  101150. + {
  101151. + vsConstMax = 256;
  101152. + psConstMax = 256;
  101153. + }
  101154. + else
  101155. + {
  101156. + vsConstMax = 168;
  101157. + psConstMax = 64;
  101158. + }
  101159. +
  101160. + if (VertexUniforms != gcvNULL)
  101161. + {
  101162. + *VertexUniforms = vsConstMax;
  101163. + }
  101164. +
  101165. + if (FragmentUniforms != gcvNULL)
  101166. + {
  101167. + *FragmentUniforms = psConstMax;
  101168. + }
  101169. +
  101170. + if (Varyings != gcvNULL)
  101171. + {
  101172. + /* Return the shader varyings count. */
  101173. + *Varyings = Hardware->identity.varyingsCount;
  101174. + }
  101175. +
  101176. + /* Success. */
  101177. + gcmkFOOTER_NO();
  101178. + return gcvSTATUS_OK;
  101179. +}
  101180. +#endif
  101181. +
  101182. +/*******************************************************************************
  101183. +**
  101184. +** gckHARDWARE_SetMMU
  101185. +**
  101186. +** Set the page table base address.
  101187. +**
  101188. +** INPUT:
  101189. +**
  101190. +** gckHARDWARE Harwdare
  101191. +** Pointer to an gckHARDWARE object.
  101192. +**
  101193. +** gctPOINTER Logical
  101194. +** Logical address of the page table.
  101195. +**
  101196. +** OUTPUT:
  101197. +**
  101198. +** Nothing.
  101199. +*/
  101200. +gceSTATUS
  101201. +gckHARDWARE_SetMMU(
  101202. + IN gckHARDWARE Hardware,
  101203. + IN gctPOINTER Logical
  101204. + )
  101205. +{
  101206. + gceSTATUS status;
  101207. + gctUINT32 address = 0;
  101208. + gctUINT32 baseAddress;
  101209. +
  101210. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
  101211. +
  101212. + /* Verify the arguments. */
  101213. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101214. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  101215. +
  101216. + /* Convert the logical address into an hardware address. */
  101217. + gcmkONERROR(
  101218. + gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
  101219. +
  101220. + /* Also get the base address - we need a real physical address. */
  101221. + gcmkONERROR(
  101222. + gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  101223. +
  101224. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101225. + "Setting page table to 0x%08X",
  101226. + address + baseAddress);
  101227. +
  101228. + /* Write the AQMemoryFePageTable register. */
  101229. + gcmkONERROR(
  101230. + gckOS_WriteRegisterEx(Hardware->os,
  101231. + Hardware->core,
  101232. + 0x00400,
  101233. + address + baseAddress));
  101234. +
  101235. + /* Write the AQMemoryRaPageTable register. */
  101236. + gcmkONERROR(
  101237. + gckOS_WriteRegisterEx(Hardware->os,
  101238. + Hardware->core,
  101239. + 0x00410,
  101240. + address + baseAddress));
  101241. +
  101242. + /* Write the AQMemoryTxPageTable register. */
  101243. + gcmkONERROR(
  101244. + gckOS_WriteRegisterEx(Hardware->os,
  101245. + Hardware->core,
  101246. + 0x00404,
  101247. + address + baseAddress));
  101248. +
  101249. +
  101250. + /* Write the AQMemoryPePageTable register. */
  101251. + gcmkONERROR(
  101252. + gckOS_WriteRegisterEx(Hardware->os,
  101253. + Hardware->core,
  101254. + 0x00408,
  101255. + address + baseAddress));
  101256. +
  101257. + /* Write the AQMemoryPezPageTable register. */
  101258. + gcmkONERROR(
  101259. + gckOS_WriteRegisterEx(Hardware->os,
  101260. + Hardware->core,
  101261. + 0x0040C,
  101262. + address + baseAddress));
  101263. +
  101264. + /* Return the status. */
  101265. + gcmkFOOTER_NO();
  101266. + return status;
  101267. +
  101268. +OnError:
  101269. + /* Return the status. */
  101270. + gcmkFOOTER();
  101271. + return status;
  101272. +}
  101273. +
  101274. +/*******************************************************************************
  101275. +**
  101276. +** gckHARDWARE_FlushMMU
  101277. +**
  101278. +** Flush the page table.
  101279. +**
  101280. +** INPUT:
  101281. +**
  101282. +** gckHARDWARE Harwdare
  101283. +** Pointer to an gckHARDWARE object.
  101284. +**
  101285. +** OUTPUT:
  101286. +**
  101287. +** Nothing.
  101288. +*/
  101289. +gceSTATUS
  101290. +gckHARDWARE_FlushMMU(
  101291. + IN gckHARDWARE Hardware
  101292. + )
  101293. +{
  101294. + gceSTATUS status;
  101295. + gckCOMMAND command;
  101296. + gctUINT32_PTR buffer;
  101297. + gctSIZE_T bufferSize;
  101298. + gctBOOL commitEntered = gcvFALSE;
  101299. + gctPOINTER pointer = gcvNULL;
  101300. + gctUINT32 flushSize;
  101301. + gctUINT32 count;
  101302. + gctUINT32 physical;
  101303. +
  101304. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101305. +
  101306. + /* Verify the arguments. */
  101307. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101308. +
  101309. + /* Verify the gckCOMMAND object pointer. */
  101310. + command = Hardware->kernel->command;
  101311. +
  101312. + /* Acquire the command queue. */
  101313. + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
  101314. + commitEntered = gcvTRUE;
  101315. +
  101316. + /* Flush the memory controller. */
  101317. + if (Hardware->mmuVersion == 0)
  101318. + {
  101319. + gcmkONERROR(gckCOMMAND_Reserve(
  101320. + command, 8, &pointer, &bufferSize
  101321. + ));
  101322. +
  101323. + buffer = (gctUINT32_PTR) pointer;
  101324. +
  101325. + buffer[0]
  101326. + = ((((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)))
  101327. + | ((((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)))
  101328. + | ((((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)));
  101329. +
  101330. + buffer[1]
  101331. + = ((((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)))
  101332. + | ((((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)))
  101333. + | ((((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)))
  101334. + | ((((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)))
  101335. + | ((((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)));
  101336. +
  101337. + gcmkONERROR(gckCOMMAND_Execute(command, 8));
  101338. + }
  101339. + else
  101340. + {
  101341. + flushSize = 16 * 4;
  101342. +
  101343. + gcmkONERROR(gckCOMMAND_Reserve(
  101344. + command, flushSize, &pointer, &bufferSize
  101345. + ));
  101346. +
  101347. + buffer = (gctUINT32_PTR) pointer;
  101348. +
  101349. + count = (bufferSize - flushSize + 7) >> 3;
  101350. +
  101351. + gcmkONERROR(gckOS_GetPhysicalAddress(command->os, buffer, &physical));
  101352. +
  101353. + /* Flush cache. */
  101354. + buffer[0]
  101355. + = ((((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)))
  101356. + | ((((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)))
  101357. + | ((((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)));
  101358. +
  101359. + buffer[1]
  101360. + = ((((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)))
  101361. + | ((((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)))
  101362. + | ((((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)))
  101363. + | ((((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)))
  101364. + | ((((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)))
  101365. + | ((((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)));
  101366. +
  101367. + /* Arm the PE-FE Semaphore. */
  101368. + buffer[2]
  101369. + = ((((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)))
  101370. + | ((((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)))
  101371. + | ((((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)));
  101372. +
  101373. + buffer[3]
  101374. + = ((((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)))
  101375. + | ((((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)));
  101376. +
  101377. + /* STALL FE until PE is done flushing. */
  101378. + buffer[4]
  101379. + = ((((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)));
  101380. +
  101381. + buffer[5]
  101382. + = ((((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)))
  101383. + | ((((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)));
  101384. +
  101385. + /* LINK to next slot to flush FE FIFO. */
  101386. + buffer[6]
  101387. + = ((((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)))
  101388. + | ((((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)));
  101389. +
  101390. + buffer[7]
  101391. + = physical + 8 * gcmSIZEOF(gctUINT32);
  101392. +
  101393. + /* Flush MMU cache. */
  101394. + buffer[8]
  101395. + = ((((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)))
  101396. + | ((((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)))
  101397. + | ((((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)));
  101398. +
  101399. + buffer[9]
  101400. + = (((((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))));
  101401. +
  101402. + /* Arm the PE-FE Semaphore. */
  101403. + buffer[10]
  101404. + = ((((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)))
  101405. + | ((((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)))
  101406. + | ((((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)));
  101407. +
  101408. + buffer[11]
  101409. + = ((((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)))
  101410. + | ((((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)));
  101411. +
  101412. + /* STALL FE until PE is done flushing. */
  101413. + buffer[12]
  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) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
  101415. +
  101416. + buffer[13]
  101417. + = ((((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)))
  101418. + | ((((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)));
  101419. +
  101420. + /* LINK to next slot to flush FE FIFO. */
  101421. + buffer[14]
  101422. + = ((((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)))
  101423. + | ((((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)));
  101424. +
  101425. + buffer[15]
  101426. + = physical + flushSize;
  101427. +
  101428. + gcmkONERROR(gckCOMMAND_Execute(command, flushSize));
  101429. + }
  101430. +
  101431. + /* Release the command queue. */
  101432. + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
  101433. + commitEntered = gcvFALSE;
  101434. +
  101435. + /* Success. */
  101436. + gcmkFOOTER_NO();
  101437. + return gcvSTATUS_OK;
  101438. +
  101439. +OnError:
  101440. + if (commitEntered)
  101441. + {
  101442. + /* Release the command queue mutex. */
  101443. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
  101444. + gcvFALSE));
  101445. + }
  101446. +
  101447. + /* Return the status. */
  101448. + gcmkFOOTER();
  101449. + return status;
  101450. +}
  101451. +
  101452. +/*******************************************************************************
  101453. +**
  101454. +** gckHARDWARE_SetMMUv2
  101455. +**
  101456. +** Set the page table base address.
  101457. +**
  101458. +** INPUT:
  101459. +**
  101460. +** gckHARDWARE Harwdare
  101461. +** Pointer to an gckHARDWARE object.
  101462. +**
  101463. +** OUTPUT:
  101464. +**
  101465. +** Nothing.
  101466. +*/
  101467. +gceSTATUS
  101468. +gckHARDWARE_SetMMUv2(
  101469. + IN gckHARDWARE Hardware,
  101470. + IN gctBOOL Enable,
  101471. + IN gctPOINTER MtlbAddress,
  101472. + IN gceMMU_MODE Mode,
  101473. + IN gctPOINTER SafeAddress,
  101474. + IN gctBOOL FromPower
  101475. + )
  101476. +{
  101477. + gceSTATUS status;
  101478. + gctUINT32 config, address;
  101479. + gckCOMMAND command;
  101480. + gctUINT32_PTR buffer;
  101481. + gctSIZE_T bufferSize;
  101482. + gctBOOL commitEntered = gcvFALSE;
  101483. + gctPOINTER pointer = gcvNULL;
  101484. + gctBOOL acquired = gcvFALSE;
  101485. + gctBOOL config2D;
  101486. + gctSIZE_T configSize;
  101487. +
  101488. + gcmkHEADER_ARG("Hardware=0x%x Enable=%d", Hardware, Enable);
  101489. +
  101490. + /* Verify the arguments. */
  101491. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101492. +
  101493. + config2D = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D)
  101494. + && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_2D);
  101495. +
  101496. + configSize = 4 * 4;
  101497. +
  101498. + if (config2D)
  101499. + {
  101500. + configSize +=
  101501. + /* Pipe Select. */
  101502. + 4 * 4
  101503. + /* Configure MMU States. */
  101504. + + 4 * 4;
  101505. + }
  101506. +
  101507. + /* Convert logical address into physical address. */
  101508. + gcmkONERROR(
  101509. + gckOS_GetPhysicalAddress(Hardware->os, MtlbAddress, &config));
  101510. +
  101511. + gcmkONERROR(
  101512. + gckOS_GetPhysicalAddress(Hardware->os, SafeAddress, &address));
  101513. +
  101514. + if (address & 0x3F)
  101515. + {
  101516. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  101517. + }
  101518. +
  101519. + switch (Mode)
  101520. + {
  101521. + case gcvMMU_MODE_1K:
  101522. + if (config & 0x3FF)
  101523. + {
  101524. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  101525. + }
  101526. +
  101527. + 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)));
  101528. +
  101529. + break;
  101530. +
  101531. + case gcvMMU_MODE_4K:
  101532. + if (config & 0xFFF)
  101533. + {
  101534. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  101535. + }
  101536. +
  101537. + 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)));
  101538. +
  101539. + break;
  101540. +
  101541. + default:
  101542. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  101543. + }
  101544. +
  101545. + /* Verify the gckCOMMAND object pointer. */
  101546. + command = Hardware->kernel->command;
  101547. +
  101548. + /* Acquire the command queue. */
  101549. + gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
  101550. + commitEntered = gcvTRUE;
  101551. +
  101552. + gcmkONERROR(gckCOMMAND_Reserve(
  101553. + command, configSize, &pointer, &bufferSize
  101554. + ));
  101555. +
  101556. + buffer = pointer;
  101557. +
  101558. + buffer[0]
  101559. + = ((((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)))
  101560. + | ((((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)))
  101561. + | ((((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)));
  101562. +
  101563. + buffer[1] = config;
  101564. +
  101565. + buffer[2]
  101566. + = ((((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)))
  101567. + | ((((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)))
  101568. + | ((((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)));
  101569. +
  101570. + buffer[3] = address;
  101571. +
  101572. + if (config2D)
  101573. + {
  101574. + /* LoadState(AQPipeSelect, 1), pipe. */
  101575. + buffer[4]
  101576. + = ((((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)))
  101577. + | ((((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)))
  101578. + | ((((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)));
  101579. +
  101580. + buffer[5] = 0x1;
  101581. +
  101582. + buffer[6]
  101583. + = ((((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)))
  101584. + | ((((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)))
  101585. + | ((((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)));
  101586. +
  101587. + buffer[7] = config;
  101588. +
  101589. + buffer[8]
  101590. + = ((((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)))
  101591. + | ((((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)))
  101592. + | ((((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)));
  101593. +
  101594. + buffer[9] = address;
  101595. +
  101596. + /* LoadState(AQPipeSelect, 1), pipe. */
  101597. + buffer[10]
  101598. + = ((((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)))
  101599. + | ((((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)))
  101600. + | ((((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)));
  101601. +
  101602. + buffer[11] = 0x0;
  101603. + }
  101604. +
  101605. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101606. + "Setup MMU: config=%08x, Safe Address=%08x\n.", config, address);
  101607. +
  101608. + gcmkONERROR(gckCOMMAND_Execute(command, configSize));
  101609. +
  101610. + if (FromPower == gcvFALSE)
  101611. + {
  101612. + /* Acquire global semaphore to suspend power management until MMU
  101613. + ** is enabled. And acquired it before gckCOMMAND_ExitCommit to
  101614. + ** make sure GPU keeps ON. */
  101615. + gcmkONERROR(
  101616. + gckOS_AcquireSemaphore(Hardware->os, Hardware->globalSemaphore));
  101617. +
  101618. + acquired = gcvTRUE;
  101619. + }
  101620. +
  101621. + /* Release the command queue. */
  101622. + gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
  101623. + commitEntered = gcvFALSE;
  101624. +
  101625. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101626. + "call gckCOMMAND_Stall to make sure the config is done.\n ");
  101627. +
  101628. + gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
  101629. +
  101630. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101631. + "Enable MMU through GCREG_MMU_CONTROL.");
  101632. +
  101633. + /* Enable MMU. */
  101634. + gcmkONERROR(
  101635. + gckOS_WriteRegisterEx(Hardware->os,
  101636. + Hardware->core,
  101637. + 0x0018C,
  101638. + ((((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)))));
  101639. +
  101640. + if (FromPower == gcvFALSE)
  101641. + {
  101642. + /* Relase global semaphore. */
  101643. + gcmkVERIFY_OK(
  101644. + gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
  101645. +
  101646. + acquired = gcvFALSE;
  101647. + }
  101648. +
  101649. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101650. + "call gckCOMMAND_Stall to check MMU available.\n");
  101651. +
  101652. + gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
  101653. +
  101654. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101655. + "The MMU is available.\n");
  101656. +
  101657. + /* Return the status. */
  101658. + gcmkFOOTER_NO();
  101659. + return status;
  101660. +
  101661. +OnError:
  101662. + if (commitEntered)
  101663. + {
  101664. + /* Release the command queue mutex. */
  101665. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
  101666. + FromPower));
  101667. + }
  101668. +
  101669. + if (acquired)
  101670. + {
  101671. + gcmkVERIFY_OK(
  101672. + gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
  101673. + }
  101674. +
  101675. + /* Return the status. */
  101676. + gcmkFOOTER();
  101677. + return status;
  101678. +}
  101679. +
  101680. +/*******************************************************************************
  101681. +**
  101682. +** gckHARDWARE_BuildVirtualAddress
  101683. +**
  101684. +** Build a virtual address.
  101685. +**
  101686. +** INPUT:
  101687. +**
  101688. +** gckHARDWARE Harwdare
  101689. +** Pointer to an gckHARDWARE object.
  101690. +**
  101691. +** gctUINT32 Index
  101692. +** Index into page table.
  101693. +**
  101694. +** gctUINT32 Offset
  101695. +** Offset into page.
  101696. +**
  101697. +** OUTPUT:
  101698. +**
  101699. +** gctUINT32 * Address
  101700. +** Pointer to a variable receiving te hardware address.
  101701. +*/
  101702. +gceSTATUS
  101703. +gckHARDWARE_BuildVirtualAddress(
  101704. + IN gckHARDWARE Hardware,
  101705. + IN gctUINT32 Index,
  101706. + IN gctUINT32 Offset,
  101707. + OUT gctUINT32 * Address
  101708. + )
  101709. +{
  101710. + gcmkHEADER_ARG("Hardware=0x%x Index=%u Offset=%u", Hardware, Index, Offset);
  101711. +
  101712. + /* Verify the arguments. */
  101713. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101714. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  101715. +
  101716. + /* Build virtual address. */
  101717. + *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)))
  101718. + | ((((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)));
  101719. +
  101720. + /* Success. */
  101721. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  101722. + return gcvSTATUS_OK;
  101723. +}
  101724. +
  101725. +gceSTATUS
  101726. +gckHARDWARE_GetIdle(
  101727. + IN gckHARDWARE Hardware,
  101728. + IN gctBOOL Wait,
  101729. + OUT gctUINT32 * Data
  101730. + )
  101731. +{
  101732. + gceSTATUS status;
  101733. + gctUINT32 idle = 0;
  101734. + gctINT retry, poll, pollCount;
  101735. +
  101736. + gcmkHEADER_ARG("Hardware=0x%x Wait=%d", Hardware, Wait);
  101737. +
  101738. + /* Verify the arguments. */
  101739. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101740. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  101741. +
  101742. +
  101743. + /* If we have to wait, try 100 polls per millisecond. */
  101744. + pollCount = Wait ? 100 : 1;
  101745. +
  101746. + /* At most, try for 1 second. */
  101747. + for (retry = 0; retry < 1000; ++retry)
  101748. + {
  101749. + /* If we have to wait, try 100 polls per millisecond. */
  101750. + for (poll = pollCount; poll > 0; --poll)
  101751. + {
  101752. + /* Read register. */
  101753. + gcmkONERROR(
  101754. + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
  101755. +
  101756. + /* See if we have to wait for FE idle. */
  101757. + if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  101758. + {
  101759. + /* FE is idle. */
  101760. + break;
  101761. + }
  101762. + }
  101763. +
  101764. + /* Check if we need to wait for FE and FE is busy. */
  101765. + 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)))))) ))
  101766. + {
  101767. + /* Wait a little. */
  101768. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101769. + "%s: Waiting for idle: 0x%08X",
  101770. + __FUNCTION__, idle);
  101771. +
  101772. + gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
  101773. + }
  101774. + else
  101775. + {
  101776. + break;
  101777. + }
  101778. + }
  101779. +
  101780. + /* Return idle to caller. */
  101781. + *Data = idle;
  101782. +
  101783. + /* Success. */
  101784. + gcmkFOOTER_ARG("*Data=0x%08x", *Data);
  101785. + return gcvSTATUS_OK;
  101786. +
  101787. +OnError:
  101788. + /* Return the status. */
  101789. + gcmkFOOTER();
  101790. + return status;
  101791. +}
  101792. +
  101793. +/* Flush the caches. */
  101794. +gceSTATUS
  101795. +gckHARDWARE_Flush(
  101796. + IN gckHARDWARE Hardware,
  101797. + IN gceKERNEL_FLUSH Flush,
  101798. + IN gctPOINTER Logical,
  101799. + IN OUT gctSIZE_T * Bytes
  101800. + )
  101801. +{
  101802. + gctUINT32 pipe;
  101803. + gctUINT32 flush = 0;
  101804. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  101805. + gceSTATUS status;
  101806. + gctBOOL fcFlushStall;
  101807. + gctUINT32 reserveBytes = 8;
  101808. +
  101809. + gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu",
  101810. + Hardware, Flush, Logical, gcmOPT_VALUE(Bytes));
  101811. +
  101812. + /* Verify the arguments. */
  101813. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101814. +
  101815. + /* Get current pipe. */
  101816. + pipe = Hardware->kernel->command->pipeSelect;
  101817. +
  101818. + fcFlushStall
  101819. + = ((((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)))))))
  101820. + && (Flush == gcvFLUSH_ALL)
  101821. + ;
  101822. +
  101823. + if (fcFlushStall)
  101824. + {
  101825. + reserveBytes += 8;
  101826. + }
  101827. +
  101828. + /* Flush 3D color cache. */
  101829. + if ((Flush & gcvFLUSH_COLOR) && (pipe == 0x0))
  101830. + {
  101831. + 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)));
  101832. + }
  101833. +
  101834. + /* Flush 3D depth cache. */
  101835. + if ((Flush & gcvFLUSH_DEPTH) && (pipe == 0x0))
  101836. + {
  101837. + 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)));
  101838. + }
  101839. +
  101840. + /* Flush 3D texture cache. */
  101841. + if ((Flush & gcvFLUSH_TEXTURE) && (pipe == 0x0))
  101842. + {
  101843. + 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)));
  101844. + 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)));
  101845. + }
  101846. +
  101847. + /* Flush 2D cache. */
  101848. + if ((Flush & gcvFLUSH_2D) && (pipe == 0x1))
  101849. + {
  101850. + 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)));
  101851. + }
  101852. +
  101853. + /* See if there is a valid flush. */
  101854. + if (flush == 0)
  101855. + {
  101856. + if (Bytes != gcvNULL)
  101857. + {
  101858. + /* No bytes required. */
  101859. + *Bytes = 0;
  101860. + }
  101861. + }
  101862. +
  101863. + else
  101864. + {
  101865. + /* Copy to command queue. */
  101866. + if (Logical != gcvNULL)
  101867. + {
  101868. + if (*Bytes < reserveBytes)
  101869. + {
  101870. + /* Command queue too small. */
  101871. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  101872. + }
  101873. +
  101874. + /* Append LOAD_STATE to AQFlush. */
  101875. + 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)))
  101876. + | ((((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)))
  101877. + | ((((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)));
  101878. +
  101879. + logical[1] = flush;
  101880. +
  101881. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101882. + "0x%x: FLUSH 0x%x", logical, flush);
  101883. +
  101884. + if (fcFlushStall)
  101885. + {
  101886. + 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)))
  101887. + | ((((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)))
  101888. + | ((((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)));
  101889. +
  101890. + 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)));
  101891. +
  101892. +
  101893. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101894. + "0x%x: FLUSH 0x%x", logical + 3, logical[3]);
  101895. + }
  101896. +
  101897. + }
  101898. +
  101899. + if (Bytes != gcvNULL)
  101900. + {
  101901. + /* bytes required. */
  101902. + *Bytes = reserveBytes;
  101903. + }
  101904. + }
  101905. +
  101906. + /* Success. */
  101907. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  101908. + return gcvSTATUS_OK;
  101909. +
  101910. +OnError:
  101911. + /* Return the status. */
  101912. + gcmkFOOTER();
  101913. + return status;
  101914. +}
  101915. +
  101916. +gceSTATUS
  101917. +gckHARDWARE_SetFastClear(
  101918. + IN gckHARDWARE Hardware,
  101919. + IN gctINT Enable,
  101920. + IN gctINT Compression
  101921. + )
  101922. +{
  101923. +#ifndef VIVANTE_NO_3D
  101924. + gctUINT32 debug;
  101925. + gceSTATUS status;
  101926. +
  101927. + gcmkHEADER_ARG("Hardware=0x%x Enable=%d Compression=%d",
  101928. + Hardware, Enable, Compression);
  101929. +
  101930. + /* Only process if fast clear is available. */
  101931. + 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)))))) ))
  101932. + {
  101933. + if (Enable == -1)
  101934. + {
  101935. + /* Determine automatic value for fast clear. */
  101936. + Enable = ((Hardware->identity.chipModel != gcv500)
  101937. + || (Hardware->identity.chipRevision >= 3)
  101938. + ) ? 1 : 0;
  101939. + }
  101940. +
  101941. + if (Compression == -1)
  101942. + {
  101943. + /* Determine automatic value for compression. */
  101944. + Compression = Enable
  101945. + & (((((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)))))) );
  101946. + }
  101947. +
  101948. + /* Read AQMemoryDebug register. */
  101949. + gcmkONERROR(
  101950. + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &debug));
  101951. +
  101952. + /* Set fast clear bypass. */
  101953. + 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)));
  101954. +
  101955. + if (
  101956. + ((((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))))))) ||
  101957. + (Hardware->identity.chipModel >= gcv4000))
  101958. + {
  101959. + /* Set compression bypass. */
  101960. + 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)));
  101961. + }
  101962. +
  101963. + /* Write back AQMemoryDebug register. */
  101964. + gcmkONERROR(
  101965. + gckOS_WriteRegisterEx(Hardware->os,
  101966. + Hardware->core,
  101967. + 0x00414,
  101968. + debug));
  101969. +
  101970. + /* Store fast clear and comprersison flags. */
  101971. + Hardware->allowFastClear = Enable;
  101972. + Hardware->allowCompression = Compression;
  101973. +
  101974. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101975. + "FastClear=%d Compression=%d", Enable, Compression);
  101976. + }
  101977. +
  101978. + /* Success. */
  101979. + gcmkFOOTER_NO();
  101980. + return gcvSTATUS_OK;
  101981. +
  101982. +OnError:
  101983. + /* Return the status. */
  101984. + gcmkFOOTER();
  101985. + return status;
  101986. +#else
  101987. + return gcvSTATUS_OK;
  101988. +#endif
  101989. +}
  101990. +
  101991. +typedef enum
  101992. +{
  101993. + gcvPOWER_FLAG_INITIALIZE = 1 << 0,
  101994. + gcvPOWER_FLAG_STALL = 1 << 1,
  101995. + gcvPOWER_FLAG_STOP = 1 << 2,
  101996. + gcvPOWER_FLAG_START = 1 << 3,
  101997. + gcvPOWER_FLAG_RELEASE = 1 << 4,
  101998. + gcvPOWER_FLAG_DELAY = 1 << 5,
  101999. + gcvPOWER_FLAG_SAVE = 1 << 6,
  102000. + gcvPOWER_FLAG_ACQUIRE = 1 << 7,
  102001. + gcvPOWER_FLAG_POWER_OFF = 1 << 8,
  102002. + gcvPOWER_FLAG_CLOCK_OFF = 1 << 9,
  102003. + gcvPOWER_FLAG_CLOCK_ON = 1 << 10,
  102004. +}
  102005. +gcePOWER_FLAGS;
  102006. +
  102007. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  102008. +static gctCONST_STRING
  102009. +_PowerEnum(gceCHIPPOWERSTATE State)
  102010. +{
  102011. + const gctCONST_STRING states[] =
  102012. + {
  102013. + gcmSTRING(gcvPOWER_ON),
  102014. + gcmSTRING(gcvPOWER_OFF),
  102015. + gcmSTRING(gcvPOWER_IDLE),
  102016. + gcmSTRING(gcvPOWER_SUSPEND),
  102017. + gcmSTRING(gcvPOWER_SUSPEND_ATPOWERON),
  102018. + gcmSTRING(gcvPOWER_OFF_ATPOWERON),
  102019. + gcmSTRING(gcvPOWER_IDLE_BROADCAST),
  102020. + gcmSTRING(gcvPOWER_SUSPEND_BROADCAST),
  102021. + gcmSTRING(gcvPOWER_OFF_BROADCAST),
  102022. + gcmSTRING(gcvPOWER_OFF_RECOVERY),
  102023. + gcmSTRING(gcvPOWER_ON_AUTO)
  102024. + };
  102025. +
  102026. + if ((State >= gcvPOWER_ON) && (State <= gcvPOWER_ON_AUTO))
  102027. + {
  102028. + return states[State - gcvPOWER_ON];
  102029. + }
  102030. +
  102031. + return "unknown";
  102032. +}
  102033. +#endif
  102034. +
  102035. +/*******************************************************************************
  102036. +**
  102037. +** gckHARDWARE_SetPowerManagementState
  102038. +**
  102039. +** Set GPU to a specified power state.
  102040. +**
  102041. +** INPUT:
  102042. +**
  102043. +** gckHARDWARE Harwdare
  102044. +** Pointer to an gckHARDWARE object.
  102045. +**
  102046. +** gceCHIPPOWERSTATE State
  102047. +** Power State.
  102048. +**
  102049. +*/
  102050. +gceSTATUS
  102051. +gckHARDWARE_SetPowerManagementState(
  102052. + IN gckHARDWARE Hardware,
  102053. + IN gceCHIPPOWERSTATE State
  102054. + )
  102055. +{
  102056. + gceSTATUS status;
  102057. + gckCOMMAND command = gcvNULL;
  102058. + gckOS os;
  102059. + gctUINT flag, clock;
  102060. + gctPOINTER buffer;
  102061. + gctSIZE_T bytes, requested;
  102062. + gctBOOL acquired = gcvFALSE;
  102063. + gctBOOL mutexAcquired = gcvFALSE;
  102064. + gctBOOL stall = gcvTRUE;
  102065. + gctBOOL broadcast = gcvFALSE;
  102066. +#if gcdPOWEROFF_TIMEOUT
  102067. + gctBOOL timeout = gcvFALSE;
  102068. + gctBOOL isAfter = gcvFALSE;
  102069. + gctUINT32 currentTime;
  102070. +#endif
  102071. + gctUINT32 process, thread;
  102072. + gctBOOL commitEntered = gcvFALSE;
  102073. + gctBOOL commandStarted = gcvFALSE;
  102074. + gctBOOL isrStarted = gcvFALSE;
  102075. +
  102076. +#if gcdENABLE_PROFILING
  102077. + gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
  102078. + initTime, offTime, startTime, totalTime;
  102079. +#endif
  102080. + gctBOOL global = gcvFALSE;
  102081. + gctBOOL globalAcquired = gcvFALSE;
  102082. + gctBOOL configMmu = gcvFALSE;
  102083. +
  102084. + /* State transition flags. */
  102085. + static const gctUINT flags[4][4] =
  102086. + {
  102087. + /* gcvPOWER_ON */
  102088. + { /* ON */ 0,
  102089. + /* OFF */ gcvPOWER_FLAG_ACQUIRE |
  102090. + gcvPOWER_FLAG_STALL |
  102091. + gcvPOWER_FLAG_STOP |
  102092. + gcvPOWER_FLAG_POWER_OFF |
  102093. + gcvPOWER_FLAG_CLOCK_OFF,
  102094. + /* IDLE */ gcvPOWER_FLAG_ACQUIRE |
  102095. + gcvPOWER_FLAG_STALL,
  102096. + /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
  102097. + gcvPOWER_FLAG_STALL |
  102098. + gcvPOWER_FLAG_STOP |
  102099. + gcvPOWER_FLAG_CLOCK_OFF,
  102100. + },
  102101. +
  102102. + /* gcvPOWER_OFF */
  102103. + { /* ON */ gcvPOWER_FLAG_INITIALIZE |
  102104. + gcvPOWER_FLAG_START |
  102105. + gcvPOWER_FLAG_RELEASE |
  102106. + gcvPOWER_FLAG_DELAY,
  102107. + /* OFF */ 0,
  102108. + /* IDLE */ gcvPOWER_FLAG_INITIALIZE |
  102109. + gcvPOWER_FLAG_START |
  102110. + gcvPOWER_FLAG_DELAY,
  102111. + /* SUSPEND */ gcvPOWER_FLAG_INITIALIZE |
  102112. + gcvPOWER_FLAG_CLOCK_OFF,
  102113. + },
  102114. +
  102115. + /* gcvPOWER_IDLE */
  102116. + { /* ON */ gcvPOWER_FLAG_RELEASE,
  102117. + /* OFF */ gcvPOWER_FLAG_STOP |
  102118. + gcvPOWER_FLAG_POWER_OFF |
  102119. + gcvPOWER_FLAG_CLOCK_OFF,
  102120. + /* IDLE */ 0,
  102121. + /* SUSPEND */ gcvPOWER_FLAG_STOP |
  102122. + gcvPOWER_FLAG_CLOCK_OFF,
  102123. + },
  102124. +
  102125. + /* gcvPOWER_SUSPEND */
  102126. + { /* ON */ gcvPOWER_FLAG_START |
  102127. + gcvPOWER_FLAG_RELEASE |
  102128. + gcvPOWER_FLAG_DELAY |
  102129. + gcvPOWER_FLAG_CLOCK_ON,
  102130. + /* OFF */ gcvPOWER_FLAG_SAVE |
  102131. + gcvPOWER_FLAG_POWER_OFF |
  102132. + gcvPOWER_FLAG_CLOCK_OFF,
  102133. + /* IDLE */ gcvPOWER_FLAG_START |
  102134. + gcvPOWER_FLAG_DELAY |
  102135. + gcvPOWER_FLAG_CLOCK_ON,
  102136. + /* SUSPEND */ 0,
  102137. + },
  102138. + };
  102139. +
  102140. + /* Clocks. */
  102141. + static const gctUINT clocks[4] =
  102142. + {
  102143. + /* gcvPOWER_ON */
  102144. + ((((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))) |
  102145. + ((((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))) |
  102146. + ((((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))) |
  102147. + ((((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))),
  102148. +
  102149. + /* gcvPOWER_OFF */
  102150. + ((((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))) |
  102151. + ((((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))) |
  102152. + ((((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))) |
  102153. + ((((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))),
  102154. +
  102155. + /* gcvPOWER_IDLE */
  102156. + ((((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))) |
  102157. + ((((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))) |
  102158. + ((((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))) |
  102159. + ((((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))),
  102160. +
  102161. + /* gcvPOWER_SUSPEND */
  102162. + ((((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))) |
  102163. + ((((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))) |
  102164. + ((((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))) |
  102165. + ((((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))),
  102166. + };
  102167. +
  102168. + gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
  102169. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  102170. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102171. + "Switching to power state %d(%s)",
  102172. + State, _PowerEnum(State));
  102173. +#endif
  102174. +
  102175. + /* Verify the arguments. */
  102176. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102177. +
  102178. + /* Get the gckOS object pointer. */
  102179. + os = Hardware->os;
  102180. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  102181. +
  102182. + /* Get the gckCOMMAND object pointer. */
  102183. + gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
  102184. + command = Hardware->kernel->command;
  102185. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  102186. +
  102187. + if (Hardware->powerManagement == gcvFALSE)
  102188. + {
  102189. + gcmkFOOTER_NO();
  102190. + return gcvSTATUS_OK;
  102191. + }
  102192. +
  102193. + /* Start profiler. */
  102194. + gcmkPROFILE_INIT(freq, time);
  102195. +
  102196. + /* Convert the broadcast power state. */
  102197. + switch (State)
  102198. + {
  102199. + case gcvPOWER_SUSPEND_ATPOWERON:
  102200. + /* Convert to SUSPEND and don't wait for STALL. */
  102201. + State = gcvPOWER_SUSPEND;
  102202. + stall = gcvFALSE;
  102203. + break;
  102204. +
  102205. + case gcvPOWER_OFF_ATPOWERON:
  102206. + /* Convert to OFF and don't wait for STALL. */
  102207. + State = gcvPOWER_OFF;
  102208. + stall = gcvFALSE;
  102209. + break;
  102210. +
  102211. + case gcvPOWER_IDLE_BROADCAST:
  102212. + /* Convert to IDLE and note we are inside broadcast. */
  102213. + State = gcvPOWER_IDLE;
  102214. + broadcast = gcvTRUE;
  102215. + break;
  102216. +
  102217. + case gcvPOWER_SUSPEND_BROADCAST:
  102218. + /* Convert to SUSPEND and note we are inside broadcast. */
  102219. + State = gcvPOWER_SUSPEND;
  102220. + broadcast = gcvTRUE;
  102221. + break;
  102222. +
  102223. + case gcvPOWER_OFF_BROADCAST:
  102224. + /* Convert to OFF and note we are inside broadcast. */
  102225. + State = gcvPOWER_OFF;
  102226. + broadcast = gcvTRUE;
  102227. + break;
  102228. +
  102229. + case gcvPOWER_OFF_RECOVERY:
  102230. + /* Convert to OFF and note we are inside recovery. */
  102231. + State = gcvPOWER_OFF;
  102232. + stall = gcvFALSE;
  102233. + broadcast = gcvTRUE;
  102234. + break;
  102235. +
  102236. + case gcvPOWER_ON_AUTO:
  102237. + /* Convert to ON and note we are inside recovery. */
  102238. + State = gcvPOWER_ON;
  102239. + break;
  102240. +
  102241. + case gcvPOWER_ON:
  102242. + case gcvPOWER_IDLE:
  102243. + case gcvPOWER_SUSPEND:
  102244. + case gcvPOWER_OFF:
  102245. + /* Mark as global power management. */
  102246. + global = gcvTRUE;
  102247. + break;
  102248. +
  102249. +#if gcdPOWEROFF_TIMEOUT
  102250. + case gcvPOWER_OFF_TIMEOUT:
  102251. + /* Convert to OFF and note we are inside broadcast. */
  102252. + State = gcvPOWER_OFF;
  102253. + broadcast = gcvTRUE;
  102254. + /* Check time out */
  102255. + timeout = gcvTRUE;
  102256. + break;
  102257. +#endif
  102258. +
  102259. + default:
  102260. + break;
  102261. + }
  102262. +
  102263. + /* Get current process and thread IDs. */
  102264. + gcmkONERROR(gckOS_GetProcessID(&process));
  102265. + gcmkONERROR(gckOS_GetThreadID(&thread));
  102266. +
  102267. + /* Before we grab locks see if this is actually a needed change */
  102268. + if (State == Hardware->chipPowerState)
  102269. + return gcvSTATUS_OK;
  102270. +
  102271. + if (broadcast)
  102272. + {
  102273. + /* Try to acquire the power mutex. */
  102274. + status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
  102275. +
  102276. + if (status == gcvSTATUS_TIMEOUT)
  102277. + {
  102278. + /* Check if we already own this mutex. */
  102279. + if ((Hardware->powerProcess == process)
  102280. + && (Hardware->powerThread == thread)
  102281. + )
  102282. + {
  102283. + /* Bail out on recursive power management. */
  102284. + gcmkFOOTER_NO();
  102285. + return gcvSTATUS_OK;
  102286. + }
  102287. + else if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
  102288. + {
  102289. + /* Called from IST,
  102290. + ** so waiting here will cause deadlock,
  102291. + ** if lock holder call gckCOMMAND_Stall() */
  102292. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  102293. + }
  102294. +#if gcdPOWEROFF_TIMEOUT
  102295. + else if(State == gcvPOWER_OFF && timeout == gcvTRUE)
  102296. + {
  102297. + /*
  102298. + ** try to aqcuire the mutex with more milliseconds,
  102299. + ** flush_delayed_work should be running with timeout,
  102300. + ** so waiting here will cause deadlock */
  102301. + status = gckOS_AcquireMutex(os, Hardware->powerMutex, gcdPOWEROFF_TIMEOUT);
  102302. +
  102303. + if (status == gcvSTATUS_TIMEOUT)
  102304. + {
  102305. + gckOS_Print("GPU Timer deadlock, exit by timeout!!!!\n");
  102306. +
  102307. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  102308. + }
  102309. + }
  102310. +#endif
  102311. + else
  102312. + {
  102313. + /* Acquire the power mutex. */
  102314. + gcmkONERROR(gckOS_AcquireMutex(os,
  102315. + Hardware->powerMutex,
  102316. + gcvINFINITE));
  102317. + }
  102318. + }
  102319. + }
  102320. + else
  102321. + {
  102322. + /* Acquire the power mutex. */
  102323. + gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
  102324. + }
  102325. +
  102326. + /* Get time until mtuex acquired. */
  102327. + gcmkPROFILE_QUERY(time, mutexTime);
  102328. +
  102329. + Hardware->powerProcess = process;
  102330. + Hardware->powerThread = thread;
  102331. + mutexAcquired = gcvTRUE;
  102332. +
  102333. + /* Grab control flags and clock. */
  102334. + flag = flags[Hardware->chipPowerState][State];
  102335. + clock = clocks[State];
  102336. +
  102337. +#if gcdENABLE_FSCALE_VAL_ADJUST
  102338. + if (State == gcvPOWER_ON)
  102339. + {
  102340. + 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)));
  102341. + }
  102342. +#endif
  102343. +
  102344. + if (State == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF && broadcast)
  102345. + {
  102346. +#if gcdPOWER_SUSNPEND_WHEN_IDLE
  102347. + /* Do nothing */
  102348. +
  102349. + /* Release the power mutex. */
  102350. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102351. +
  102352. + gcmkFOOTER_NO();
  102353. + return gcvSTATUS_OK;
  102354. +#else
  102355. + /* Clock should be on when switch power from off to suspend */
  102356. + 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))) |
  102357. + ((((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))) |
  102358. + ((((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))) |
  102359. + ((((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))) ;
  102360. +#endif
  102361. + }
  102362. +
  102363. +#if gcdPOWEROFF_TIMEOUT
  102364. + if (timeout)
  102365. + {
  102366. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  102367. +
  102368. + gcmkONERROR(
  102369. + gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
  102370. +
  102371. + /* powerOffTime is pushed forward, give up.*/
  102372. + if (isAfter
  102373. + /* Expect a transition start from IDLE or SUSPEND. */
  102374. + || (Hardware->chipPowerState == gcvPOWER_ON)
  102375. + || (Hardware->chipPowerState == gcvPOWER_OFF)
  102376. + )
  102377. + {
  102378. + /* Release the power mutex. */
  102379. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102380. +
  102381. + /* No need to do anything. */
  102382. + gcmkFOOTER_NO();
  102383. + return gcvSTATUS_OK;
  102384. + }
  102385. +
  102386. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102387. + "Power Off GPU[%d] at %u [supposed to be at %u]",
  102388. + Hardware->core, currentTime, Hardware->powerOffTime);
  102389. + }
  102390. +
  102391. + if (State == gcvPOWER_ON || State == gcvPOWER_OFF)
  102392. + {
  102393. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
  102394. +
  102395. + /* Cancel running timer when GPU enters ON or OFF. */
  102396. + gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
  102397. + }
  102398. +#endif
  102399. +
  102400. + if (flag == 0)
  102401. + {
  102402. + /* Release the power mutex. */
  102403. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102404. +
  102405. + /* No need to do anything. */
  102406. + gcmkFOOTER_NO();
  102407. + return gcvSTATUS_OK;
  102408. + }
  102409. +
  102410. + /* If this is an internal power management, we have to check if we can grab
  102411. + ** the global power semaphore. If we cannot, we have to wait until the
  102412. + ** external world changes power management. */
  102413. + if (!global)
  102414. + {
  102415. + /* Try to acquire the global semaphore. */
  102416. + status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
  102417. + if (status == gcvSTATUS_TIMEOUT)
  102418. + {
  102419. + if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
  102420. + {
  102421. + /* Called from thread routine which should NEVER sleep.*/
  102422. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  102423. + }
  102424. +
  102425. + /* Release the power mutex. */
  102426. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102427. + "Releasing the power mutex.");
  102428. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102429. + mutexAcquired = gcvFALSE;
  102430. +
  102431. + /* Wait for the semaphore. */
  102432. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102433. + "Waiting for global semaphore.");
  102434. + gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore));
  102435. + globalAcquired = gcvTRUE;
  102436. +
  102437. + /* Acquire the power mutex. */
  102438. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102439. + "Reacquiring the power mutex.");
  102440. + gcmkONERROR(gckOS_AcquireMutex(os,
  102441. + Hardware->powerMutex,
  102442. + gcvINFINITE));
  102443. + mutexAcquired = gcvTRUE;
  102444. +
  102445. + /* chipPowerState may be changed by external world during the time
  102446. + ** we give up powerMutex, so updating flag now is necessary. */
  102447. + flag = flags[Hardware->chipPowerState][State];
  102448. +
  102449. + if (flag == 0)
  102450. + {
  102451. + gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
  102452. + globalAcquired = gcvFALSE;
  102453. +
  102454. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102455. + mutexAcquired = gcvFALSE;
  102456. +
  102457. + gcmkFOOTER_NO();
  102458. + return gcvSTATUS_OK;
  102459. + }
  102460. + }
  102461. + else
  102462. + {
  102463. + /* Error. */
  102464. + gcmkONERROR(status);
  102465. + }
  102466. +
  102467. + /* Release the global semaphore again. */
  102468. + gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
  102469. + globalAcquired = gcvFALSE;
  102470. + }
  102471. + else
  102472. + {
  102473. + if (State == gcvPOWER_OFF || State == gcvPOWER_SUSPEND || State == gcvPOWER_IDLE)
  102474. + {
  102475. + /* Acquire the global semaphore if it has not been acquired. */
  102476. + status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
  102477. + if (status == gcvSTATUS_OK)
  102478. + {
  102479. + globalAcquired = gcvTRUE;
  102480. + }
  102481. + else if (status != gcvSTATUS_TIMEOUT)
  102482. + {
  102483. + /* Other errors. */
  102484. + gcmkONERROR(status);
  102485. + }
  102486. + /* Ignore gcvSTATUS_TIMEOUT and leave globalAcquired as gcvFALSE.
  102487. + ** gcvSTATUS_TIMEOUT means global semaphore has already
  102488. + ** been acquired before this operation, so even if we fail,
  102489. + ** we should not release it in our error handling. It should be
  102490. + ** released by the next successful global gcvPOWER_ON. */
  102491. + }
  102492. +
  102493. + /* Global power management can't be aborted, so sync with
  102494. + ** proceeding last commit. */
  102495. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  102496. + {
  102497. + /* Acquire the power management semaphore. */
  102498. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  102499. + acquired = gcvTRUE;
  102500. +
  102501. + /* avoid acquiring again. */
  102502. + flag &= ~gcvPOWER_FLAG_ACQUIRE;
  102503. + }
  102504. + }
  102505. +
  102506. + if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
  102507. + {
  102508. + /* Turn on the power. */
  102509. + gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
  102510. +
  102511. + /* Mark clock and power as enabled. */
  102512. + Hardware->clockState = gcvTRUE;
  102513. + Hardware->powerState = gcvTRUE;
  102514. +
  102515. + for (;;)
  102516. + {
  102517. + /* Check if GPU is present and awake. */
  102518. + status = _IsGPUPresent(Hardware);
  102519. +
  102520. + /* Check if the GPU is not responding. */
  102521. + if (status == gcvSTATUS_GPU_NOT_RESPONDING)
  102522. + {
  102523. + /* Turn off the power and clock. */
  102524. + gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvFALSE, gcvFALSE));
  102525. +
  102526. + Hardware->clockState = gcvFALSE;
  102527. + Hardware->powerState = gcvFALSE;
  102528. +
  102529. + /* Wait a little. */
  102530. + gckOS_Delay(os, 1);
  102531. +
  102532. + /* Turn on the power and clock. */
  102533. + gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
  102534. +
  102535. + Hardware->clockState = gcvTRUE;
  102536. + Hardware->powerState = gcvTRUE;
  102537. +
  102538. + /* We need to initialize the hardware and start the command
  102539. + * processor. */
  102540. + flag |= gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_START;
  102541. + }
  102542. + else
  102543. + {
  102544. + /* Test for error. */
  102545. + gcmkONERROR(status);
  102546. +
  102547. + /* Break out of loop. */
  102548. + break;
  102549. + }
  102550. + }
  102551. + }
  102552. +
  102553. + /* Get time until powered on. */
  102554. + gcmkPROFILE_QUERY(time, onTime);
  102555. +
  102556. + if ((flag & gcvPOWER_FLAG_STALL) && stall)
  102557. + {
  102558. + gctBOOL idle;
  102559. + gctINT32 atomValue;
  102560. +
  102561. + /* For global operation, all pending commits have already been
  102562. + ** blocked by globalSemaphore or powerSemaphore.*/
  102563. + if (!global)
  102564. + {
  102565. + /* Check commit atom. */
  102566. + gcmkONERROR(gckOS_AtomGet(os, command->atomCommit, &atomValue));
  102567. +
  102568. + if (atomValue > 0)
  102569. + {
  102570. + /* Commits are pending - abort power management. */
  102571. + status = broadcast ? gcvSTATUS_CHIP_NOT_READY
  102572. + : gcvSTATUS_MORE_DATA;
  102573. + goto OnError;
  102574. + }
  102575. + }
  102576. +
  102577. + if (broadcast)
  102578. + {
  102579. + /* Check for idle. */
  102580. + gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
  102581. +
  102582. + if (!idle)
  102583. + {
  102584. + status = gcvSTATUS_CHIP_NOT_READY;
  102585. + goto OnError;
  102586. + }
  102587. + }
  102588. +
  102589. + else
  102590. + {
  102591. + /* Acquire the command queue. */
  102592. + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvTRUE));
  102593. + commitEntered = gcvTRUE;
  102594. +
  102595. + /* Get the size of the flush command. */
  102596. + gcmkONERROR(gckHARDWARE_Flush(Hardware,
  102597. + gcvFLUSH_ALL,
  102598. + gcvNULL,
  102599. + &requested));
  102600. +
  102601. + /* Reserve space in the command queue. */
  102602. + gcmkONERROR(gckCOMMAND_Reserve(command,
  102603. + requested,
  102604. + &buffer,
  102605. + &bytes));
  102606. +
  102607. + /* Append a flush. */
  102608. + gcmkONERROR(gckHARDWARE_Flush(
  102609. + Hardware, gcvFLUSH_ALL, buffer, &bytes
  102610. + ));
  102611. +
  102612. + /* Execute the command queue. */
  102613. + gcmkONERROR(gckCOMMAND_Execute(command, requested));
  102614. +
  102615. + /* Release the command queue. */
  102616. + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvTRUE));
  102617. + commitEntered = gcvFALSE;
  102618. +
  102619. + /* Wait to finish all commands. */
  102620. + gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE));
  102621. + }
  102622. + }
  102623. +
  102624. + /* Get time until stalled. */
  102625. + gcmkPROFILE_QUERY(time, stallTime);
  102626. +
  102627. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  102628. + {
  102629. + /* Acquire the power management semaphore. */
  102630. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  102631. + acquired = gcvTRUE;
  102632. + }
  102633. +
  102634. + if (flag & gcvPOWER_FLAG_STOP)
  102635. + {
  102636. + /* Stop the command parser. */
  102637. + gcmkONERROR(gckCOMMAND_Stop(command, gcvFALSE));
  102638. +
  102639. + /* Stop the Isr. */
  102640. + if (Hardware->stopIsr)
  102641. + {
  102642. + gcmkONERROR(Hardware->stopIsr(Hardware->isrContext, Hardware->core));
  102643. + }
  102644. + }
  102645. +
  102646. + /* Flush Cache before Power Off. */
  102647. + if (flag & gcvPOWER_FLAG_POWER_OFF)
  102648. + {
  102649. + if (Hardware->clockState == gcvFALSE)
  102650. + {
  102651. + /* Turn off the GPU power. */
  102652. + gcmkONERROR(
  102653. + gckOS_SetGPUPower(os,
  102654. + Hardware->core,
  102655. + gcvTRUE,
  102656. + gcvTRUE));
  102657. +
  102658. + Hardware->clockState = gcvTRUE;
  102659. +
  102660. + if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE)
  102661. + {
  102662. + /* Write the clock control register. */
  102663. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  102664. + Hardware->core,
  102665. + 0x00000,
  102666. + clocks[0]));
  102667. +
  102668. + /* Done loading the frequency scaler. */
  102669. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  102670. + Hardware->core,
  102671. + 0x00000,
  102672. + ((((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)))));
  102673. + }
  102674. + }
  102675. +
  102676. + gcmkONERROR(gckCOMMAND_Start(command));
  102677. +
  102678. + gcmkONERROR(_FlushCache(Hardware, command));
  102679. +
  102680. + gckOS_Delay(gcvNULL, 1);
  102681. +
  102682. + /* Stop the command parser. */
  102683. + gcmkONERROR(gckCOMMAND_Stop(command, gcvFALSE));
  102684. +
  102685. + flag |= gcvPOWER_FLAG_CLOCK_OFF;
  102686. + }
  102687. +
  102688. + /* Get time until stopped. */
  102689. + gcmkPROFILE_QUERY(time, stopTime);
  102690. +
  102691. + /* Only process this when hardware is enabled. */
  102692. + if (Hardware->clockState && Hardware->powerState
  102693. + /* Don't touch clock control if dynamic frequency scaling is available. */
  102694. + && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE
  102695. + )
  102696. + {
  102697. + if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
  102698. + {
  102699. + if (Hardware->identity.chipModel == gcv4000
  102700. + && Hardware->identity.chipRevision == 0x5208)
  102701. + {
  102702. + clock &= ~2U;
  102703. + }
  102704. + }
  102705. +
  102706. + /* Write the clock control register. */
  102707. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  102708. + Hardware->core,
  102709. + 0x00000,
  102710. + clock));
  102711. +
  102712. + /* Done loading the frequency scaler. */
  102713. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  102714. + Hardware->core,
  102715. + 0x00000,
  102716. + ((((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)))));
  102717. + }
  102718. +
  102719. + if (flag & gcvPOWER_FLAG_DELAY)
  102720. + {
  102721. + /* Wait for the specified amount of time to settle coming back from
  102722. + ** power-off or suspend state. */
  102723. + gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
  102724. + }
  102725. +
  102726. + /* Get time until delayed. */
  102727. + gcmkPROFILE_QUERY(time, delayTime);
  102728. +
  102729. + if (flag & gcvPOWER_FLAG_INITIALIZE)
  102730. + {
  102731. + /* Initialize hardware. */
  102732. + gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
  102733. +
  102734. + gcmkONERROR(gckHARDWARE_SetFastClear(Hardware,
  102735. + Hardware->allowFastClear,
  102736. + Hardware->allowCompression));
  102737. +
  102738. + /* Force the command queue to reload the next context. */
  102739. + command->currContext = gcvNULL;
  102740. +
  102741. + /* Need to config mmu after command start. */
  102742. + configMmu = gcvTRUE;
  102743. + }
  102744. +
  102745. + /* Get time until initialized. */
  102746. + gcmkPROFILE_QUERY(time, initTime);
  102747. +
  102748. + if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
  102749. + {
  102750. + /* Turn off the GPU power. */
  102751. + gcmkONERROR(
  102752. + gckOS_SetGPUPower(os,
  102753. + Hardware->core,
  102754. + (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  102755. + : gcvTRUE,
  102756. + (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  102757. + : gcvTRUE));
  102758. +
  102759. + /* Save current hardware power and clock states. */
  102760. + Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  102761. + : gcvTRUE;
  102762. + Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  102763. + : gcvTRUE;
  102764. + }
  102765. +
  102766. + /* Get time until off. */
  102767. + gcmkPROFILE_QUERY(time, offTime);
  102768. +
  102769. + if (flag & gcvPOWER_FLAG_START)
  102770. + {
  102771. + /* Start the command processor. */
  102772. + gcmkONERROR(gckCOMMAND_Start(command));
  102773. + commandStarted = gcvTRUE;
  102774. +
  102775. + if (Hardware->startIsr)
  102776. + {
  102777. + /* Start the Isr. */
  102778. + gcmkONERROR(Hardware->startIsr(Hardware->isrContext, Hardware->core));
  102779. + isrStarted = gcvTRUE;
  102780. + }
  102781. +
  102782. + /* Set NEW MMU. */
  102783. + if (Hardware->mmuVersion != 0 && configMmu)
  102784. + {
  102785. + gcmkONERROR(
  102786. + gckHARDWARE_SetMMUv2(
  102787. + Hardware,
  102788. + gcvTRUE,
  102789. + Hardware->kernel->mmu->mtlbLogical,
  102790. + gcvMMU_MODE_4K,
  102791. + (gctUINT8_PTR)Hardware->kernel->mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
  102792. + gcvTRUE
  102793. + ));
  102794. + }
  102795. + }
  102796. +
  102797. + /* Get time until started. */
  102798. + gcmkPROFILE_QUERY(time, startTime);
  102799. +
  102800. + if (flag & gcvPOWER_FLAG_RELEASE)
  102801. + {
  102802. + /* Release the power management semaphore. */
  102803. + gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
  102804. + acquired = gcvFALSE;
  102805. +
  102806. + if (global)
  102807. + {
  102808. + /* Verify global semaphore has been acquired already before
  102809. + ** we release it.
  102810. + ** If it was acquired, gckOS_TryAcquireSemaphore will return
  102811. + ** gcvSTATUS_TIMEOUT and we release it. Otherwise, global
  102812. + ** semaphore will be acquried now, but it still is released
  102813. + ** immediately. */
  102814. + status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
  102815. + if (status != gcvSTATUS_TIMEOUT)
  102816. + {
  102817. + gcmkONERROR(status);
  102818. + }
  102819. +
  102820. + /* Release the global semaphore. */
  102821. + gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
  102822. + globalAcquired = gcvFALSE;
  102823. + }
  102824. + }
  102825. +
  102826. + /* Save the new power state. */
  102827. + Hardware->chipPowerState = State;
  102828. +
  102829. +#if gcdDVFS
  102830. + if (State == gcvPOWER_ON && Hardware->kernel->dvfs)
  102831. + {
  102832. + gckDVFS_Start(Hardware->kernel->dvfs);
  102833. + }
  102834. +#endif
  102835. +
  102836. +#if gcdPOWEROFF_TIMEOUT
  102837. + if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
  102838. + {
  102839. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  102840. +
  102841. + Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
  102842. + /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
  102843. + gcmkVERIFY_OK(gckOS_StartTimer(os,
  102844. + Hardware->powerOffTimer,
  102845. + Hardware->powerOffTimeout));
  102846. + }
  102847. +#endif
  102848. +
  102849. + /* Release the power mutex. */
  102850. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  102851. +
  102852. + /* Get total time. */
  102853. + gcmkPROFILE_QUERY(time, totalTime);
  102854. +#if gcdENABLE_PROFILING
  102855. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102856. + "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
  102857. + freq, mutexTime, onTime, stallTime, stopTime);
  102858. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102859. + " delay:%llu init:%llu off:%llu start:%llu total:%llu",
  102860. + delayTime, initTime, offTime, startTime, totalTime);
  102861. +#endif
  102862. +
  102863. + /* Success. */
  102864. + gcmkFOOTER_NO();
  102865. + return gcvSTATUS_OK;
  102866. +
  102867. +OnError:
  102868. + if (commandStarted)
  102869. + {
  102870. + gcmkVERIFY_OK(gckCOMMAND_Stop(command, gcvFALSE));
  102871. + }
  102872. +
  102873. + if (isrStarted)
  102874. + {
  102875. + gcmkVERIFY_OK(Hardware->stopIsr(Hardware->isrContext, Hardware->core));
  102876. + }
  102877. +
  102878. + if (commitEntered)
  102879. + {
  102880. + /* Release the command queue mutex. */
  102881. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, gcvTRUE));
  102882. + }
  102883. +
  102884. + if (acquired)
  102885. + {
  102886. + /* Release semaphore. */
  102887. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
  102888. + command->powerSemaphore));
  102889. + }
  102890. +
  102891. + if (globalAcquired)
  102892. + {
  102893. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
  102894. + Hardware->globalSemaphore));
  102895. + }
  102896. +
  102897. + if (mutexAcquired)
  102898. + {
  102899. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  102900. + }
  102901. +
  102902. + /* Return the status. */
  102903. + gcmkFOOTER();
  102904. + return status;
  102905. +}
  102906. +
  102907. +/*******************************************************************************
  102908. +**
  102909. +** gckHARDWARE_QueryPowerManagementState
  102910. +**
  102911. +** Get GPU power state.
  102912. +**
  102913. +** INPUT:
  102914. +**
  102915. +** gckHARDWARE Harwdare
  102916. +** Pointer to an gckHARDWARE object.
  102917. +**
  102918. +** gceCHIPPOWERSTATE* State
  102919. +** Power State.
  102920. +**
  102921. +*/
  102922. +gceSTATUS
  102923. +gckHARDWARE_QueryPowerManagementState(
  102924. + IN gckHARDWARE Hardware,
  102925. + OUT gceCHIPPOWERSTATE* State
  102926. + )
  102927. +{
  102928. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  102929. +
  102930. + /* Verify the arguments. */
  102931. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102932. + gcmkVERIFY_ARGUMENT(State != gcvNULL);
  102933. +
  102934. + /* Return the statue. */
  102935. + *State = Hardware->chipPowerState;
  102936. +
  102937. + /* Success. */
  102938. + gcmkFOOTER_ARG("*State=%d", *State);
  102939. + return gcvSTATUS_OK;
  102940. +}
  102941. +
  102942. +/*******************************************************************************
  102943. +**
  102944. +** gckHARDWARE_SetPowerManagement
  102945. +**
  102946. +** Configure GPU power management function.
  102947. +** Only used in driver initialization stage.
  102948. +**
  102949. +** INPUT:
  102950. +**
  102951. +** gckHARDWARE Harwdare
  102952. +** Pointer to an gckHARDWARE object.
  102953. +**
  102954. +** gctBOOL PowerManagement
  102955. +** Power Mangement State.
  102956. +**
  102957. +*/
  102958. +gceSTATUS
  102959. +gckHARDWARE_SetPowerManagement(
  102960. + IN gckHARDWARE Hardware,
  102961. + IN gctBOOL PowerManagement
  102962. + )
  102963. +{
  102964. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  102965. +
  102966. + /* Verify the arguments. */
  102967. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102968. +
  102969. + Hardware->powerManagement = PowerManagement;
  102970. +
  102971. + /* Success. */
  102972. + gcmkFOOTER_NO();
  102973. + return gcvSTATUS_OK;
  102974. +}
  102975. +
  102976. +/*******************************************************************************
  102977. +**
  102978. +** gckHARDWARE_SetGpuProfiler
  102979. +**
  102980. +** Configure GPU profiler function.
  102981. +** Only used in driver initialization stage.
  102982. +**
  102983. +** INPUT:
  102984. +**
  102985. +** gckHARDWARE Harwdare
  102986. +** Pointer to an gckHARDWARE object.
  102987. +**
  102988. +** gctBOOL GpuProfiler
  102989. +** GOU Profiler State.
  102990. +**
  102991. +*/
  102992. +gceSTATUS
  102993. +gckHARDWARE_SetGpuProfiler(
  102994. + IN gckHARDWARE Hardware,
  102995. + IN gctBOOL GpuProfiler
  102996. + )
  102997. +{
  102998. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  102999. +
  103000. + /* Verify the arguments. */
  103001. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103002. +
  103003. + Hardware->gpuProfiler = GpuProfiler;
  103004. +
  103005. + /* Success. */
  103006. + gcmkFOOTER_NO();
  103007. + return gcvSTATUS_OK;
  103008. +}
  103009. +
  103010. +#if gcdENABLE_FSCALE_VAL_ADJUST
  103011. +gceSTATUS
  103012. +gckHARDWARE_SetFscaleValue(
  103013. + IN gckHARDWARE Hardware,
  103014. + IN gctUINT32 FscaleValue
  103015. + )
  103016. +{
  103017. + gceSTATUS status;
  103018. + gctUINT32 clock;
  103019. + gctBOOL acquired = gcvFALSE;
  103020. +
  103021. + gcmkHEADER_ARG("Hardware=0x%x FscaleValue=%d", Hardware, FscaleValue);
  103022. +
  103023. + gcmkVERIFY_ARGUMENT(FscaleValue > 0 && FscaleValue <= 64);
  103024. +
  103025. + gcmkONERROR(
  103026. + gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
  103027. + acquired = gcvTRUE;
  103028. +
  103029. + Hardware->powerOnFscaleVal = FscaleValue;
  103030. +
  103031. + if (Hardware->chipPowerState == gcvPOWER_ON)
  103032. + {
  103033. + gctUINT32 data;
  103034. +
  103035. + gcmkONERROR(
  103036. + gckOS_ReadRegisterEx(Hardware->os,
  103037. + Hardware->core,
  103038. + Hardware->powerBaseAddress
  103039. + + 0x00104,
  103040. + &data));
  103041. +
  103042. + /* Disable all clock gating. */
  103043. + gcmkONERROR(
  103044. + gckOS_WriteRegisterEx(Hardware->os,
  103045. + Hardware->core,
  103046. + Hardware->powerBaseAddress
  103047. + + 0x00104,
  103048. + ((((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)))
  103049. + | ((((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)))
  103050. + | ((((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)))
  103051. + | ((((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)))
  103052. + | ((((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)))
  103053. + | ((((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)))
  103054. + | ((((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)))
  103055. + | ((((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)))
  103056. + | ((((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)))
  103057. + | ((((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)))
  103058. + | ((((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)))));
  103059. +
  103060. + 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)))
  103061. + | ((((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)))
  103062. + | ((((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)))
  103063. + | ((((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)));
  103064. +
  103065. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103066. + Hardware->core,
  103067. + 0x00000,
  103068. + clock));
  103069. +
  103070. + /* Done loading the frequency scaler. */
  103071. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103072. + Hardware->core,
  103073. + 0x00000,
  103074. + ((((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)))));
  103075. +
  103076. + /* Restore all clock gating. */
  103077. + gcmkONERROR(
  103078. + gckOS_WriteRegisterEx(Hardware->os,
  103079. + Hardware->core,
  103080. + Hardware->powerBaseAddress
  103081. + + 0x00104,
  103082. + data));
  103083. + }
  103084. +
  103085. + gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  103086. +
  103087. + gcmkFOOTER_NO();
  103088. + return gcvSTATUS_OK;
  103089. +
  103090. +OnError:
  103091. + if (acquired)
  103092. + {
  103093. + gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  103094. + }
  103095. +
  103096. + gcmkFOOTER();
  103097. + return status;
  103098. +}
  103099. +
  103100. +gceSTATUS
  103101. +gckHARDWARE_GetFscaleValue(
  103102. + IN gckHARDWARE Hardware,
  103103. + IN gctUINT * FscaleValue,
  103104. + IN gctUINT * MinFscaleValue,
  103105. + IN gctUINT * MaxFscaleValue
  103106. + )
  103107. +{
  103108. + *FscaleValue = Hardware->powerOnFscaleVal;
  103109. + if ((gpu3DMinClock > 0) && (gpu3DMinClock <= 64) && (Hardware->core == gcvCORE_MAJOR))
  103110. + *MinFscaleValue = gpu3DMinClock;
  103111. + else
  103112. + *MinFscaleValue = 1;
  103113. + *MaxFscaleValue = 64;
  103114. +
  103115. + return gcvSTATUS_OK;
  103116. +}
  103117. +
  103118. +#endif
  103119. +
  103120. +#if gcdPOWEROFF_TIMEOUT
  103121. +gceSTATUS
  103122. +gckHARDWARE_SetPowerOffTimeout(
  103123. + IN gckHARDWARE Hardware,
  103124. + IN gctUINT32 Timeout
  103125. +)
  103126. +{
  103127. + gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
  103128. +
  103129. + Hardware->powerOffTimeout = Timeout;
  103130. +
  103131. + gcmkFOOTER_NO();
  103132. + return gcvSTATUS_OK;
  103133. +}
  103134. +
  103135. +
  103136. +gceSTATUS
  103137. +gckHARDWARE_QueryPowerOffTimeout(
  103138. + IN gckHARDWARE Hardware,
  103139. + OUT gctUINT32* Timeout
  103140. +)
  103141. +{
  103142. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  103143. +
  103144. + *Timeout = Hardware->powerOffTimeout;
  103145. +
  103146. + gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
  103147. + return gcvSTATUS_OK;
  103148. +}
  103149. +#endif
  103150. +
  103151. +gceSTATUS
  103152. +gckHARDWARE_QueryIdle(
  103153. + IN gckHARDWARE Hardware,
  103154. + OUT gctBOOL_PTR IsIdle
  103155. + )
  103156. +{
  103157. + gceSTATUS status;
  103158. + gctUINT32 idle, address;
  103159. +
  103160. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  103161. +
  103162. + /* Verify the arguments. */
  103163. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103164. + gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL);
  103165. +
  103166. + /* We are idle when the power is not ON. */
  103167. + if (Hardware->chipPowerState != gcvPOWER_ON)
  103168. + {
  103169. + *IsIdle = gcvTRUE;
  103170. + }
  103171. +
  103172. + else
  103173. + {
  103174. + /* Read idle register. */
  103175. + gcmkONERROR(
  103176. + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
  103177. +
  103178. + /* Pipe must be idle. */
  103179. + 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)
  103180. + || ((((((gctUINT32) (idle)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) ) != 1)
  103181. + || ((((((gctUINT32) (idle)) >> (0 ? 4:4)) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1)))))) ) != 1)
  103182. + || ((((((gctUINT32) (idle)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ) != 1)
  103183. + || ((((((gctUINT32) (idle)) >> (0 ? 6:6)) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1)))))) ) != 1)
  103184. + || ((((((gctUINT32) (idle)) >> (0 ? 7:7)) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1)))))) ) != 1)
  103185. + || ((((((gctUINT32) (idle)) >> (0 ? 2:2)) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) ) != 1)
  103186. + )
  103187. + {
  103188. + /* Something is busy. */
  103189. + *IsIdle = gcvFALSE;
  103190. + }
  103191. +
  103192. + else
  103193. + {
  103194. + /* Read the current FE address. */
  103195. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  103196. + Hardware->core,
  103197. + 0x00664,
  103198. + &address));
  103199. +
  103200. + /* Test if address is inside the last WAIT/LINK sequence. */
  103201. + if ((address >= Hardware->lastWaitLink)
  103202. + && (address <= Hardware->lastWaitLink + 16)
  103203. + )
  103204. + {
  103205. + /* FE is in last WAIT/LINK and the pipe is idle. */
  103206. + *IsIdle = gcvTRUE;
  103207. + }
  103208. + else
  103209. + {
  103210. + /* FE is not in WAIT/LINK yet. */
  103211. + *IsIdle = gcvFALSE;
  103212. + }
  103213. + }
  103214. + }
  103215. +
  103216. + /* Success. */
  103217. + gcmkFOOTER_NO();
  103218. + return gcvSTATUS_OK;
  103219. +
  103220. +OnError:
  103221. + /* Return the status. */
  103222. + gcmkFOOTER();
  103223. + return status;
  103224. +}
  103225. +
  103226. +/*******************************************************************************
  103227. +** Handy macros that will help in reading those debug registers.
  103228. +*/
  103229. +
  103230. +#define gcmkREAD_DEBUG_REGISTER(control, block, index, data) \
  103231. + gcmkONERROR(\
  103232. + gckOS_WriteRegisterEx(Hardware->os, \
  103233. + Hardware->core, \
  103234. + GC_DEBUG_CONTROL##control##_Address, \
  103235. + gcmSETFIELD(0, \
  103236. + GC_DEBUG_CONTROL##control, \
  103237. + block, \
  103238. + index))); \
  103239. + gcmkONERROR(\
  103240. + gckOS_ReadRegisterEx(Hardware->os, \
  103241. + Hardware->core, \
  103242. + GC_DEBUG_SIGNALS_##block##_Address, \
  103243. + &profiler->data))
  103244. +
  103245. +#define gcmkREAD_DEBUG_REGISTER_N(control, block, index, data) \
  103246. + gcmkONERROR(\
  103247. + gckOS_WriteRegisterEx(Hardware->os, \
  103248. + Hardware->core, \
  103249. + GC_DEBUG_CONTROL##control##_Address, \
  103250. + gcmSETFIELD(0, \
  103251. + GC_DEBUG_CONTROL##control, \
  103252. + block, \
  103253. + index))); \
  103254. + gcmkONERROR(\
  103255. + gckOS_ReadRegisterEx(Hardware->os, \
  103256. + Hardware->core, \
  103257. + GC_DEBUG_SIGNALS_##block##_Address, \
  103258. + &data))
  103259. +
  103260. +#define gcmkRESET_DEBUG_REGISTER(control, block) \
  103261. + gcmkONERROR(\
  103262. + gckOS_WriteRegisterEx(Hardware->os, \
  103263. + Hardware->core, \
  103264. + GC_DEBUG_CONTROL##control##_Address, \
  103265. + gcmSETFIELD(0, \
  103266. + GC_DEBUG_CONTROL##control, \
  103267. + block, \
  103268. + 15))); \
  103269. + gcmkONERROR(\
  103270. + gckOS_WriteRegisterEx(Hardware->os, \
  103271. + Hardware->core, \
  103272. + GC_DEBUG_CONTROL##control##_Address, \
  103273. + gcmSETFIELD(0, \
  103274. + GC_DEBUG_CONTROL##control, \
  103275. + block, \
  103276. + 0)))
  103277. +
  103278. +/*******************************************************************************
  103279. +**
  103280. +** gckHARDWARE_ProfileEngine2D
  103281. +**
  103282. +** Read the profile registers available in the 2D engine and sets them in the
  103283. +** profile. The function will also reset the pixelsRendered counter every time.
  103284. +**
  103285. +** INPUT:
  103286. +**
  103287. +** gckHARDWARE Hardware
  103288. +** Pointer to an gckHARDWARE object.
  103289. +**
  103290. +** OPTIONAL gcs2D_PROFILE_PTR Profile
  103291. +** Pointer to a gcs2D_Profile structure.
  103292. +**
  103293. +** OUTPUT:
  103294. +**
  103295. +** Nothing.
  103296. +*/
  103297. +gceSTATUS
  103298. +gckHARDWARE_ProfileEngine2D(
  103299. + IN gckHARDWARE Hardware,
  103300. + OPTIONAL gcs2D_PROFILE_PTR Profile
  103301. + )
  103302. +{
  103303. + gceSTATUS status;
  103304. + gcs2D_PROFILE_PTR profiler = Profile;
  103305. +
  103306. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  103307. +
  103308. + /* Verify the arguments. */
  103309. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103310. +
  103311. + if (Profile != gcvNULL)
  103312. + {
  103313. + /* Read the cycle count. */
  103314. + gcmkONERROR(
  103315. + gckOS_ReadRegisterEx(Hardware->os,
  103316. + Hardware->core,
  103317. + 0x00438,
  103318. + &Profile->cycleCount));
  103319. +
  103320. + /* Read pixels rendered by 2D engine. */
  103321. + 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))) ));
  103322. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pixelsRendered));
  103323. +
  103324. + /* Reset counter. */
  103325. + 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))) ));
  103326. +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)))
  103327. +));
  103328. + }
  103329. +
  103330. + /* Success. */
  103331. + gcmkFOOTER_NO();
  103332. + return gcvSTATUS_OK;
  103333. +
  103334. +OnError:
  103335. + /* Return the status. */
  103336. + gcmkFOOTER();
  103337. + return status;
  103338. +}
  103339. +
  103340. +#if VIVANTE_PROFILER
  103341. +gceSTATUS
  103342. +gckHARDWARE_QueryProfileRegisters(
  103343. + IN gckHARDWARE Hardware,
  103344. + IN gctBOOL Reset,
  103345. + OUT gcsPROFILER_COUNTERS * Counters
  103346. + )
  103347. +{
  103348. + gceSTATUS status;
  103349. + gcsPROFILER_COUNTERS * profiler = Counters;
  103350. + gctUINT i, clock;
  103351. + gctUINT32 colorKilled, colorDrawn, depthKilled, depthDrawn;
  103352. + gctUINT32 totalRead, totalWrite;
  103353. +
  103354. + gcmkHEADER_ARG("Hardware=0x%x Counters=0x%x", Hardware, Counters);
  103355. +
  103356. + /* Verify the arguments. */
  103357. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103358. +
  103359. + /* Read the counters. */
  103360. + gcmkONERROR(
  103361. + gckOS_ReadRegisterEx(Hardware->os,
  103362. + Hardware->core,
  103363. + 0x00438,
  103364. + &profiler->gpuCyclesCounter));
  103365. +
  103366. + gcmkONERROR(
  103367. + gckOS_ReadRegisterEx(Hardware->os,
  103368. + Hardware->core,
  103369. + 0x00078,
  103370. + &profiler->gpuTotalCyclesCounter));
  103371. +
  103372. + gcmkONERROR(
  103373. + gckOS_ReadRegisterEx(Hardware->os,
  103374. + Hardware->core,
  103375. + 0x0007C,
  103376. + &profiler->gpuIdleCyclesCounter));
  103377. +
  103378. +
  103379. + /* Read clock control register. */
  103380. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  103381. + Hardware->core,
  103382. + 0x00000,
  103383. + &clock));
  103384. +
  103385. + profiler->gpuTotalRead64BytesPerFrame = 0;
  103386. + profiler->gpuTotalWrite64BytesPerFrame = 0;
  103387. + profiler->pe_pixel_count_killed_by_color_pipe = 0;
  103388. + profiler->pe_pixel_count_killed_by_depth_pipe = 0;
  103389. + profiler->pe_pixel_count_drawn_by_color_pipe = 0;
  103390. + profiler->pe_pixel_count_drawn_by_depth_pipe = 0;
  103391. +
  103392. + /* Walk through all avaiable pixel pipes. */
  103393. + for (i = 0; i < Hardware->identity.pixelPipes; ++i)
  103394. + {
  103395. + /* Select proper pipe. */
  103396. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103397. + Hardware->core,
  103398. + 0x00000,
  103399. + ((((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)))));
  103400. +
  103401. + /* BW */
  103402. + gcmkONERROR(
  103403. + gckOS_ReadRegisterEx(Hardware->os,
  103404. + Hardware->core,
  103405. + 0x00040,
  103406. + &totalRead));
  103407. + gcmkONERROR(
  103408. + gckOS_ReadRegisterEx(Hardware->os,
  103409. + Hardware->core,
  103410. + 0x00044,
  103411. + &totalWrite));
  103412. +
  103413. + profiler->gpuTotalRead64BytesPerFrame += totalRead;
  103414. + profiler->gpuTotalWrite64BytesPerFrame += totalWrite;
  103415. +
  103416. + /* PE */
  103417. + 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));
  103418. + 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));
  103419. + 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));
  103420. + 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));
  103421. +
  103422. + profiler->pe_pixel_count_killed_by_color_pipe += colorKilled;
  103423. + profiler->pe_pixel_count_killed_by_depth_pipe += depthKilled;
  103424. + profiler->pe_pixel_count_drawn_by_color_pipe += colorDrawn;
  103425. + profiler->pe_pixel_count_drawn_by_depth_pipe += depthDrawn;
  103426. + }
  103427. +
  103428. + /* Reset clock control register. */
  103429. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103430. + Hardware->core,
  103431. + 0x00000,
  103432. + clock));
  103433. +
  103434. + if(Reset){
  103435. + /* Reset counters. */
  103436. + gcmkONERROR(
  103437. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
  103438. + gcmkONERROR(
  103439. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
  103440. + gcmkONERROR(
  103441. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
  103442. + gcmkONERROR(
  103443. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
  103444. + 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))) ));
  103445. +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)))
  103446. +));
  103447. + }
  103448. +
  103449. + /* SH */
  103450. + 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))) ));
  103451. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->ps_inst_counter));
  103452. + 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))) ));
  103453. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_pixel_counter));
  103454. + 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))) ));
  103455. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vs_inst_counter));
  103456. + 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))) ));
  103457. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_vertice_counter));
  103458. + 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))) ));
  103459. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_branch_inst_counter));
  103460. + 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))) ));
  103461. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_texld_inst_counter));
  103462. + 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))) ));
  103463. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter));
  103464. + 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))) ));
  103465. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter));
  103466. + 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))) ));
  103467. +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)))
  103468. +));}
  103469. +
  103470. + /* PA */
  103471. + 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))) ));
  103472. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_vtx_counter));
  103473. + 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))) ));
  103474. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_prim_counter));
  103475. + 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))) ));
  103476. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_output_prim_counter));
  103477. + 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))) ));
  103478. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_depth_clipped_counter));
  103479. + 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))) ));
  103480. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter));
  103481. + 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))) ));
  103482. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter));
  103483. + 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))) ));
  103484. +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)))
  103485. +));}
  103486. +
  103487. + /* SE */
  103488. + 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))) ));
  103489. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count));
  103490. + 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))) ));
  103491. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count));
  103492. + 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))) ));
  103493. +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)))
  103494. +));}
  103495. +
  103496. + /* RA */
  103497. + 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))) ));
  103498. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_pixel_count));
  103499. + 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))) ));
  103500. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_quad_count));
  103501. + 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))) ));
  103502. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_quad_count_after_early_z));
  103503. + 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))) ));
  103504. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_primitive_count));
  103505. + 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))) ));
  103506. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter));
  103507. + 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))) ));
  103508. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter));
  103509. + 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))) ));
  103510. +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)))
  103511. +));}
  103512. +
  103513. + /* TX */
  103514. + 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))) ));
  103515. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_bilinear_requests));
  103516. + 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))) ));
  103517. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_trilinear_requests));
  103518. + 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))) ));
  103519. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_discarded_texture_requests));
  103520. + 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))) ));
  103521. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_texture_requests));
  103522. + 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))) ));
  103523. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_count));
  103524. + 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))) ));
  103525. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_in_8B_count));
  103526. + 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))) ));
  103527. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_count));
  103528. + 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))) ));
  103529. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count));
  103530. + 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))) ));
  103531. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count));
  103532. + 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))) ));
  103533. +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)))
  103534. +));}
  103535. +
  103536. + /* MC */
  103537. + 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))) ));
  103538. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_pipeline));
  103539. + 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))) ));
  103540. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP));
  103541. + 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))) ));
  103542. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline));
  103543. + 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))) ));
  103544. +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)))
  103545. +));}
  103546. +
  103547. + /* HI */
  103548. + 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))) ));
  103549. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_read_request_stalled));
  103550. + 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))) ));
  103551. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled));
  103552. + 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))) ));
  103553. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled));
  103554. + 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))) ));
  103555. +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)))
  103556. +));}
  103557. +
  103558. + /* Success. */
  103559. + gcmkFOOTER_NO();
  103560. + return gcvSTATUS_OK;
  103561. +
  103562. +OnError:
  103563. + /* Return the status. */
  103564. + gcmkFOOTER();
  103565. + return status;
  103566. +}
  103567. +#endif
  103568. +
  103569. +#if VIVANTE_PROFILER_CONTEXT
  103570. +#define gcmkUPDATE_PROFILE_DATA(data) \
  103571. + profilerHistroy->data += profiler->data
  103572. +
  103573. +gceSTATUS
  103574. +gckHARDWARE_QueryContextProfile(
  103575. + IN gckHARDWARE Hardware,
  103576. + IN gctBOOL Reset,
  103577. + IN gckCONTEXT Context,
  103578. + OUT gcsPROFILER_COUNTERS * Counters
  103579. + )
  103580. +{
  103581. + gceSTATUS status;
  103582. + gckCOMMAND command = Hardware->kernel->command;
  103583. + gcsPROFILER_COUNTERS * profiler = Counters;
  103584. +
  103585. + gcmkHEADER_ARG("Hardware=0x%x Counters=0x%x", Hardware, Counters);
  103586. +
  103587. + /* Verify the arguments. */
  103588. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103589. +
  103590. + /* Acquire the context sequnence mutex. */
  103591. + gcmkONERROR(gckOS_AcquireMutex(
  103592. + command->os, command->mutexContextSeq, gcvINFINITE
  103593. + ));
  103594. +
  103595. + /* Read the counters. */
  103596. + gcmkVERIFY_OK(gckOS_MemCopy(
  103597. + profiler, &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS)
  103598. + ));
  103599. +
  103600. + if (Reset)
  103601. + {
  103602. + /* Reset counters. */
  103603. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  103604. + &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS)
  103605. + ));
  103606. + }
  103607. +
  103608. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  103609. + command->os, command->mutexContextSeq
  103610. + ));
  103611. +
  103612. + /* Success. */
  103613. + gcmkFOOTER_NO();
  103614. + return gcvSTATUS_OK;
  103615. +
  103616. +OnError:
  103617. + /* Return the status. */
  103618. + gcmkFOOTER();
  103619. + return status;
  103620. +}
  103621. +
  103622. +
  103623. +gceSTATUS
  103624. +gckHARDWARE_UpdateContextProfile(
  103625. + IN gckHARDWARE Hardware,
  103626. + IN gckCONTEXT Context
  103627. + )
  103628. +{
  103629. + gceSTATUS status;
  103630. + gcsPROFILER_COUNTERS * profiler = &Context->latestProfiler;
  103631. + gcsPROFILER_COUNTERS * profilerHistroy = &Context->histroyProfiler;
  103632. + gctUINT i, clock;
  103633. + gctUINT32 colorKilled, colorDrawn, depthKilled, depthDrawn;
  103634. + gctUINT32 totalRead, totalWrite;
  103635. + gceCHIPMODEL chipModel;
  103636. + gctUINT32 chipRevision;
  103637. + gctUINT32 temp;
  103638. + gctBOOL needResetShader = gcvFALSE;
  103639. +
  103640. + gcmkHEADER_ARG("Hardware=0x%x Context=0x%x", Hardware, Context);
  103641. +
  103642. + /* Verify the arguments. */
  103643. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103644. + gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
  103645. +
  103646. + chipModel = Hardware->identity.chipModel;
  103647. + chipRevision = Hardware->identity.chipRevision;
  103648. + if (chipModel == gcv2000 || (chipModel == gcv2100 && chipRevision == 0x5118))
  103649. + {
  103650. + needResetShader = gcvTRUE;
  103651. + }
  103652. +
  103653. + /* Read the counters. */
  103654. + gcmkONERROR(
  103655. + gckOS_ReadRegisterEx(Hardware->os,
  103656. + Hardware->core,
  103657. + 0x00438,
  103658. + &profiler->gpuCyclesCounter));
  103659. + gcmkUPDATE_PROFILE_DATA(gpuCyclesCounter);
  103660. +
  103661. + gcmkONERROR(
  103662. + gckOS_ReadRegisterEx(Hardware->os,
  103663. + Hardware->core,
  103664. + 0x00078,
  103665. + &profiler->gpuTotalCyclesCounter));
  103666. + gcmkUPDATE_PROFILE_DATA(gpuTotalCyclesCounter);
  103667. +
  103668. + gcmkONERROR(
  103669. + gckOS_ReadRegisterEx(Hardware->os,
  103670. + Hardware->core,
  103671. + 0x0007C,
  103672. + &profiler->gpuIdleCyclesCounter));
  103673. + gcmkUPDATE_PROFILE_DATA(gpuIdleCyclesCounter);
  103674. +
  103675. + /* Read clock control register. */
  103676. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  103677. + Hardware->core,
  103678. + 0x00000,
  103679. + &clock));
  103680. +
  103681. + profiler->gpuTotalRead64BytesPerFrame = 0;
  103682. + profiler->gpuTotalWrite64BytesPerFrame = 0;
  103683. + profiler->pe_pixel_count_killed_by_color_pipe = 0;
  103684. + profiler->pe_pixel_count_killed_by_depth_pipe = 0;
  103685. + profiler->pe_pixel_count_drawn_by_color_pipe = 0;
  103686. + profiler->pe_pixel_count_drawn_by_depth_pipe = 0;
  103687. +
  103688. + /* Walk through all avaiable pixel pipes. */
  103689. + for (i = 0; i < Hardware->identity.pixelPipes; ++i)
  103690. + {
  103691. + /* Select proper pipe. */
  103692. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103693. + Hardware->core,
  103694. + 0x00000,
  103695. + ((((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)))));
  103696. +
  103697. + /* BW */
  103698. + gcmkONERROR(
  103699. + gckOS_ReadRegisterEx(Hardware->os,
  103700. + Hardware->core,
  103701. + 0x00040,
  103702. + &totalRead));
  103703. + gcmkONERROR(
  103704. + gckOS_ReadRegisterEx(Hardware->os,
  103705. + Hardware->core,
  103706. + 0x00044,
  103707. + &totalWrite));
  103708. +
  103709. + profiler->gpuTotalRead64BytesPerFrame += totalRead;
  103710. + profiler->gpuTotalWrite64BytesPerFrame += totalWrite;
  103711. + gcmkUPDATE_PROFILE_DATA(gpuTotalRead64BytesPerFrame);
  103712. + gcmkUPDATE_PROFILE_DATA(gpuTotalWrite64BytesPerFrame);
  103713. +
  103714. + /* PE */
  103715. + 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));
  103716. + 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));
  103717. + 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));
  103718. + 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));
  103719. +
  103720. + profiler->pe_pixel_count_killed_by_color_pipe += colorKilled;
  103721. + profiler->pe_pixel_count_killed_by_depth_pipe += depthKilled;
  103722. + profiler->pe_pixel_count_drawn_by_color_pipe += colorDrawn;
  103723. + profiler->pe_pixel_count_drawn_by_depth_pipe += depthDrawn;
  103724. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_killed_by_color_pipe);
  103725. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_killed_by_depth_pipe);
  103726. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_drawn_by_color_pipe);
  103727. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_drawn_by_depth_pipe);
  103728. + }
  103729. +
  103730. + /* Reset clock control register. */
  103731. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  103732. + Hardware->core,
  103733. + 0x00000,
  103734. + clock));
  103735. +
  103736. +
  103737. +
  103738. +
  103739. + /* Reset counters. */
  103740. + gcmkONERROR(
  103741. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
  103742. + gcmkONERROR(
  103743. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
  103744. + gcmkONERROR(
  103745. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
  103746. + gcmkONERROR(
  103747. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
  103748. + 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))) ));
  103749. +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)))
  103750. +));
  103751. +
  103752. + /* SH */
  103753. + 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))) ));
  103754. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->ps_inst_counter));
  103755. + if (needResetShader)
  103756. + {
  103757. + temp = profiler->ps_inst_counter;
  103758. + profiler->ps_inst_counter -= Context->prevPSInstCount;
  103759. + Context->prevPSInstCount = temp;
  103760. + }
  103761. + gcmkUPDATE_PROFILE_DATA(ps_inst_counter);
  103762. +
  103763. + 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))) ));
  103764. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_pixel_counter));
  103765. + if (needResetShader)
  103766. + {
  103767. + temp = profiler->rendered_pixel_counter;
  103768. + profiler->rendered_pixel_counter -= Context->prevPSPixelCount;
  103769. + Context->prevPSPixelCount = temp;
  103770. + }
  103771. + gcmkUPDATE_PROFILE_DATA(rendered_pixel_counter);
  103772. +
  103773. + 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))) ));
  103774. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vs_inst_counter));
  103775. + if (needResetShader)
  103776. + {
  103777. + temp = profiler->vs_inst_counter;
  103778. + profiler->vs_inst_counter -= Context->prevVSInstCount;
  103779. + Context->prevVSInstCount = temp;
  103780. + }
  103781. + gcmkUPDATE_PROFILE_DATA(vs_inst_counter);
  103782. +
  103783. + 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))) ));
  103784. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_vertice_counter));
  103785. + if (needResetShader)
  103786. + {
  103787. + temp = profiler->rendered_vertice_counter;
  103788. + profiler->rendered_vertice_counter -= Context->prevVSVertexCount;
  103789. + Context->prevVSVertexCount = temp;
  103790. + }
  103791. + gcmkUPDATE_PROFILE_DATA(rendered_vertice_counter);
  103792. +
  103793. + 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))) ));
  103794. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_branch_inst_counter));
  103795. + if (needResetShader)
  103796. + {
  103797. + temp = profiler->vtx_branch_inst_counter;
  103798. + profiler->vtx_branch_inst_counter -= Context->prevVSBranchInstCount;
  103799. + Context->prevVSBranchInstCount = temp;
  103800. + }
  103801. + gcmkUPDATE_PROFILE_DATA(vtx_branch_inst_counter);
  103802. +
  103803. + 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))) ));
  103804. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_texld_inst_counter));
  103805. + if (needResetShader)
  103806. + {
  103807. + temp = profiler->vtx_texld_inst_counter;
  103808. + profiler->vtx_texld_inst_counter -= Context->prevVSTexInstCount;
  103809. + Context->prevVSTexInstCount = temp;
  103810. + }
  103811. + gcmkUPDATE_PROFILE_DATA(vtx_texld_inst_counter);
  103812. +
  103813. + 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))) ));
  103814. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter));
  103815. + if (needResetShader)
  103816. + {
  103817. + temp = profiler->pxl_branch_inst_counter;
  103818. + profiler->pxl_branch_inst_counter -= Context->prevPSBranchInstCount;
  103819. + Context->prevPSBranchInstCount = temp;
  103820. + }
  103821. + gcmkUPDATE_PROFILE_DATA(pxl_branch_inst_counter);
  103822. +
  103823. + 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))) ));
  103824. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter));
  103825. + if (needResetShader)
  103826. + {
  103827. + temp = profiler->pxl_texld_inst_counter;
  103828. + profiler->pxl_texld_inst_counter -= Context->prevPSTexInstCount;
  103829. + Context->prevPSTexInstCount = temp;
  103830. + }
  103831. + gcmkUPDATE_PROFILE_DATA(pxl_texld_inst_counter);
  103832. +
  103833. + 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))) ));
  103834. +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)))
  103835. +));
  103836. +
  103837. + /* PA */
  103838. + 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))) ));
  103839. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_vtx_counter));
  103840. + gcmkUPDATE_PROFILE_DATA(pa_input_vtx_counter);
  103841. + 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))) ));
  103842. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_prim_counter));
  103843. + gcmkUPDATE_PROFILE_DATA(pa_input_prim_counter);
  103844. + 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))) ));
  103845. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_output_prim_counter));
  103846. + gcmkUPDATE_PROFILE_DATA(pa_output_prim_counter);
  103847. + 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))) ));
  103848. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_depth_clipped_counter));
  103849. + gcmkUPDATE_PROFILE_DATA(pa_depth_clipped_counter);
  103850. + 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))) ));
  103851. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter));
  103852. + gcmkUPDATE_PROFILE_DATA(pa_trivial_rejected_counter);
  103853. + 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))) ));
  103854. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter));
  103855. + gcmkUPDATE_PROFILE_DATA(pa_culled_counter);
  103856. + 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))) ));
  103857. +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)))
  103858. +));
  103859. +
  103860. + /* SE */
  103861. + 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))) ));
  103862. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count));
  103863. + gcmkUPDATE_PROFILE_DATA(se_culled_triangle_count);
  103864. + 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))) ));
  103865. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count));
  103866. + gcmkUPDATE_PROFILE_DATA(se_culled_lines_count);
  103867. + 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))) ));
  103868. +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)))
  103869. +));
  103870. +
  103871. + /* RA */
  103872. + 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))) ));
  103873. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_pixel_count));
  103874. + gcmkUPDATE_PROFILE_DATA(ra_valid_pixel_count);
  103875. + 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))) ));
  103876. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_quad_count));
  103877. + gcmkUPDATE_PROFILE_DATA(ra_total_quad_count);
  103878. + 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))) ));
  103879. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_quad_count_after_early_z));
  103880. + gcmkUPDATE_PROFILE_DATA(ra_valid_quad_count_after_early_z);
  103881. + 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))) ));
  103882. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_primitive_count));
  103883. + gcmkUPDATE_PROFILE_DATA(ra_total_primitive_count);
  103884. + 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))) ));
  103885. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter));
  103886. + gcmkUPDATE_PROFILE_DATA(ra_pipe_cache_miss_counter);
  103887. + 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))) ));
  103888. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter));
  103889. + gcmkUPDATE_PROFILE_DATA(ra_prefetch_cache_miss_counter);
  103890. + 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))) ));
  103891. +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)))
  103892. +));
  103893. +
  103894. + /* TX */
  103895. + 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))) ));
  103896. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_bilinear_requests));
  103897. + gcmkUPDATE_PROFILE_DATA(tx_total_bilinear_requests);
  103898. + 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))) ));
  103899. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_trilinear_requests));
  103900. + gcmkUPDATE_PROFILE_DATA(tx_total_trilinear_requests);
  103901. + 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))) ));
  103902. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_discarded_texture_requests));
  103903. + gcmkUPDATE_PROFILE_DATA(tx_total_discarded_texture_requests);
  103904. + 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))) ));
  103905. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_texture_requests));
  103906. + gcmkUPDATE_PROFILE_DATA(tx_total_texture_requests);
  103907. + 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))) ));
  103908. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_count));
  103909. + gcmkUPDATE_PROFILE_DATA(tx_mem_read_count);
  103910. + 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))) ));
  103911. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_in_8B_count));
  103912. + gcmkUPDATE_PROFILE_DATA(tx_mem_read_in_8B_count);
  103913. + 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))) ));
  103914. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_count));
  103915. + gcmkUPDATE_PROFILE_DATA(tx_cache_miss_count);
  103916. + 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))) ));
  103917. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count));
  103918. + gcmkUPDATE_PROFILE_DATA(tx_cache_hit_texel_count);
  103919. + 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))) ));
  103920. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count));
  103921. + gcmkUPDATE_PROFILE_DATA(tx_cache_miss_texel_count);
  103922. + 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))) ));
  103923. +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)))
  103924. +));
  103925. +
  103926. + /* MC */
  103927. + 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))) ));
  103928. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_pipeline));
  103929. + gcmkUPDATE_PROFILE_DATA(mc_total_read_req_8B_from_pipeline);
  103930. + 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))) ));
  103931. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP));
  103932. + gcmkUPDATE_PROFILE_DATA(mc_total_read_req_8B_from_IP);
  103933. + 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))) ));
  103934. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline));
  103935. + gcmkUPDATE_PROFILE_DATA(mc_total_write_req_8B_from_pipeline);
  103936. + 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))) ));
  103937. +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)))
  103938. +));
  103939. +
  103940. + /* HI */
  103941. + 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))) ));
  103942. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_read_request_stalled));
  103943. + gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_read_request_stalled);
  103944. + 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))) ));
  103945. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled));
  103946. + gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_write_request_stalled);
  103947. + 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))) ));
  103948. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled));
  103949. + gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_write_data_stalled);
  103950. + 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))) ));
  103951. +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)))
  103952. +));
  103953. +
  103954. + /* Success. */
  103955. + gcmkFOOTER_NO();
  103956. + return gcvSTATUS_OK;
  103957. +
  103958. +OnError:
  103959. + /* Return the status. */
  103960. + gcmkFOOTER();
  103961. + return status;
  103962. +}
  103963. +#endif
  103964. +
  103965. +static gceSTATUS
  103966. +_ResetGPU(
  103967. + IN gckHARDWARE Hardware,
  103968. + IN gckOS Os,
  103969. + IN gceCORE Core
  103970. + )
  103971. +{
  103972. + gctUINT32 control, idle;
  103973. + gceSTATUS status;
  103974. +
  103975. + for (;;)
  103976. + {
  103977. + /* Disable clock gating. */
  103978. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  103979. + Core,
  103980. + Hardware->powerBaseAddress +
  103981. + 0x00104,
  103982. + 0x00000000));
  103983. +
  103984. + 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)));
  103985. +
  103986. + /* Disable pulse-eater. */
  103987. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  103988. + Core,
  103989. + 0x0010C,
  103990. + control));
  103991. +
  103992. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  103993. + Core,
  103994. + 0x0010C,
  103995. + ((((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)))));
  103996. +
  103997. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  103998. + Core,
  103999. + 0x0010C,
  104000. + control));
  104001. +
  104002. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104003. + Core,
  104004. + 0x00000,
  104005. + ((((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)))));
  104006. +
  104007. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104008. + Core,
  104009. + 0x00000,
  104010. + 0x00000900));
  104011. +
  104012. + /* Wait for clock being stable. */
  104013. + gcmkONERROR(gckOS_Delay(Os, 1));
  104014. +
  104015. + /* Isolate the GPU. */
  104016. + 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)));
  104017. +
  104018. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104019. + Core,
  104020. + 0x00000,
  104021. + control));
  104022. +
  104023. + /* Set soft reset. */
  104024. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104025. + Core,
  104026. + 0x00000,
  104027. + ((((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)))));
  104028. +
  104029. + /* Wait for reset. */
  104030. + gcmkONERROR(gckOS_Delay(Os, 1));
  104031. +
  104032. + /* Reset soft reset bit. */
  104033. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104034. + Core,
  104035. + 0x00000,
  104036. + ((((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)))));
  104037. +
  104038. + /* Reset GPU isolation. */
  104039. + 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)));
  104040. +
  104041. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  104042. + Core,
  104043. + 0x00000,
  104044. + control));
  104045. +
  104046. + /* Read idle register. */
  104047. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  104048. + Core,
  104049. + 0x00004,
  104050. + &idle));
  104051. +
  104052. + 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)
  104053. + {
  104054. + continue;
  104055. + }
  104056. +
  104057. + /* Read reset register. */
  104058. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  104059. + Core,
  104060. + 0x00000,
  104061. + &control));
  104062. +
  104063. + 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)
  104064. + || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
  104065. + )
  104066. + {
  104067. + continue;
  104068. + }
  104069. +
  104070. + /* GPU is idle. */
  104071. + break;
  104072. + }
  104073. +
  104074. + /* Success. */
  104075. + return gcvSTATUS_OK;
  104076. +
  104077. +OnError:
  104078. +
  104079. + /* Return the error. */
  104080. + return status;
  104081. +}
  104082. +
  104083. +gceSTATUS
  104084. +gckHARDWARE_Reset(
  104085. + IN gckHARDWARE Hardware
  104086. + )
  104087. +{
  104088. + gceSTATUS status;
  104089. + gckCOMMAND command;
  104090. + gctBOOL acquired = gcvFALSE;
  104091. + gctBOOL mutexAcquired = gcvFALSE;
  104092. + gctUINT32 process, thread;
  104093. +
  104094. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  104095. +
  104096. + /* Verify the arguments. */
  104097. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104098. + gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
  104099. + command = Hardware->kernel->command;
  104100. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  104101. +
  104102. + if (Hardware->identity.chipRevision < 0x4600)
  104103. + {
  104104. + /* Not supported - we need the isolation bit. */
  104105. + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
  104106. + }
  104107. +
  104108. + status = gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, 0);
  104109. + if (status == gcvSTATUS_TIMEOUT)
  104110. + {
  104111. + gcmkONERROR(gckOS_GetProcessID(&process));
  104112. + gcmkONERROR(gckOS_GetThreadID(&thread));
  104113. +
  104114. + if ((Hardware->powerProcess == process)
  104115. + && (Hardware->powerThread == thread))
  104116. + {
  104117. + /* No way to recovery from a error in power management. */
  104118. + gcmkFOOTER_NO();
  104119. + return gcvSTATUS_OK;
  104120. + }
  104121. + }
  104122. + else
  104123. + {
  104124. + mutexAcquired = gcvTRUE;
  104125. + }
  104126. +
  104127. + if (Hardware->chipPowerState == gcvPOWER_ON)
  104128. + {
  104129. + /* Acquire the power management semaphore. */
  104130. + gcmkONERROR(
  104131. + gckOS_AcquireSemaphore(Hardware->os, command->powerSemaphore));
  104132. + acquired = gcvTRUE;
  104133. + }
  104134. +
  104135. + if ((Hardware->chipPowerState == gcvPOWER_ON)
  104136. + || (Hardware->chipPowerState == gcvPOWER_IDLE)
  104137. + )
  104138. + {
  104139. + /* Stop the command processor. */
  104140. + gcmkONERROR(gckCOMMAND_Stop(command, gcvTRUE));
  104141. + }
  104142. +
  104143. + /* Stop isr, we will start it again when power on GPU. */
  104144. + if (Hardware->stopIsr)
  104145. + {
  104146. + gcmkONERROR(Hardware->stopIsr(Hardware->isrContext, Hardware->core));
  104147. + }
  104148. +
  104149. + /* Hardware reset. */
  104150. + status = gckOS_ResetGPU(Hardware->os, Hardware->core);
  104151. +
  104152. + if (gcmIS_ERROR(status))
  104153. + {
  104154. + /* Soft reset. */
  104155. + gcmkONERROR(_ResetGPU(Hardware, Hardware->os, Hardware->core));
  104156. + }
  104157. +
  104158. + /* Force an OFF to ON power switch. */
  104159. + Hardware->chipPowerState = gcvPOWER_OFF;
  104160. +
  104161. + gcmkONERROR(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  104162. + mutexAcquired = gcvFALSE;
  104163. +
  104164. + /* Success. */
  104165. + gcmkFOOTER_NO();
  104166. + return gcvSTATUS_OK;
  104167. +
  104168. +OnError:
  104169. + if (acquired)
  104170. + {
  104171. + /* Release the power management semaphore. */
  104172. + gcmkVERIFY_OK(
  104173. + gckOS_ReleaseSemaphore(Hardware->os, command->powerSemaphore));
  104174. + }
  104175. +
  104176. + if (mutexAcquired)
  104177. + {
  104178. + gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
  104179. + }
  104180. +
  104181. + /* Return the error. */
  104182. + gcmkFOOTER();
  104183. + return status;
  104184. +}
  104185. +
  104186. +gceSTATUS
  104187. +gckHARDWARE_GetBaseAddress(
  104188. + IN gckHARDWARE Hardware,
  104189. + OUT gctUINT32_PTR BaseAddress
  104190. + )
  104191. +{
  104192. + gceSTATUS status;
  104193. +
  104194. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  104195. +
  104196. + /* Verify the arguments. */
  104197. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104198. + gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL);
  104199. +
  104200. + /* Test if we have a new Memory Controller. */
  104201. + 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))))))))
  104202. + {
  104203. + /* No base address required. */
  104204. + *BaseAddress = 0;
  104205. + }
  104206. + else
  104207. + {
  104208. + /* Get the base address from the OS. */
  104209. + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, BaseAddress));
  104210. + }
  104211. +
  104212. + /* Success. */
  104213. + gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
  104214. + return gcvSTATUS_OK;
  104215. +
  104216. +OnError:
  104217. + /* Return the status. */
  104218. + gcmkFOOTER();
  104219. + return status;
  104220. +}
  104221. +
  104222. +gceSTATUS
  104223. +gckHARDWARE_NeedBaseAddress(
  104224. + IN gckHARDWARE Hardware,
  104225. + IN gctUINT32 State,
  104226. + OUT gctBOOL_PTR NeedBase
  104227. + )
  104228. +{
  104229. + gctBOOL need = gcvFALSE;
  104230. +
  104231. + gcmkHEADER_ARG("Hardware=0x%x State=0x%08x", Hardware, State);
  104232. +
  104233. + /* Verify the arguments. */
  104234. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104235. + gcmkVERIFY_ARGUMENT(NeedBase != gcvNULL);
  104236. +
  104237. + /* Make sure this is a load state. */
  104238. + 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))))))))
  104239. + {
  104240. +#ifndef VIVANTE_NO_3D
  104241. + /* Get the state address. */
  104242. + switch ((((((gctUINT32) (State)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) ))
  104243. + {
  104244. + case 0x0596:
  104245. + case 0x0597:
  104246. + case 0x0599:
  104247. + case 0x059A:
  104248. + case 0x05A9:
  104249. + /* These states need a TRUE physical address. */
  104250. + need = gcvTRUE;
  104251. + break;
  104252. + }
  104253. +#else
  104254. + /* 2D addresses don't need a base address. */
  104255. +#endif
  104256. + }
  104257. +
  104258. + /* Return the flag. */
  104259. + *NeedBase = need;
  104260. +
  104261. + /* Success. */
  104262. + gcmkFOOTER_ARG("*NeedBase=%d", *NeedBase);
  104263. + return gcvSTATUS_OK;
  104264. +}
  104265. +
  104266. +gceSTATUS
  104267. +gckHARDWARE_SetIsrManager(
  104268. + IN gckHARDWARE Hardware,
  104269. + IN gctISRMANAGERFUNC StartIsr,
  104270. + IN gctISRMANAGERFUNC StopIsr,
  104271. + IN gctPOINTER Context
  104272. + )
  104273. +{
  104274. + gceSTATUS status = gcvSTATUS_OK;
  104275. +
  104276. + gcmkHEADER_ARG("Hardware=0x%x, StartIsr=0x%x, StopIsr=0x%x, Context=0x%x",
  104277. + Hardware, StartIsr, StopIsr, Context);
  104278. +
  104279. + /* Verify the arguments. */
  104280. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104281. +
  104282. + if (StartIsr == gcvNULL ||
  104283. + StopIsr == gcvNULL ||
  104284. + Context == gcvNULL)
  104285. + {
  104286. + status = gcvSTATUS_INVALID_ARGUMENT;
  104287. +
  104288. + gcmkFOOTER();
  104289. + return status;
  104290. + }
  104291. +
  104292. + Hardware->startIsr = StartIsr;
  104293. + Hardware->stopIsr = StopIsr;
  104294. + Hardware->isrContext = Context;
  104295. +
  104296. + /* Success. */
  104297. + gcmkFOOTER();
  104298. +
  104299. + return status;
  104300. +}
  104301. +
  104302. +/*******************************************************************************
  104303. +**
  104304. +** gckHARDWARE_Compose
  104305. +**
  104306. +** Start a composition.
  104307. +**
  104308. +** INPUT:
  104309. +**
  104310. +** gckHARDWARE Hardware
  104311. +** Pointer to the gckHARDWARE object.
  104312. +**
  104313. +** OUTPUT:
  104314. +**
  104315. +** Nothing.
  104316. +*/
  104317. +gceSTATUS
  104318. +gckHARDWARE_Compose(
  104319. + IN gckHARDWARE Hardware,
  104320. + IN gctUINT32 ProcessID,
  104321. + IN gctPHYS_ADDR Physical,
  104322. + IN gctPOINTER Logical,
  104323. + IN gctSIZE_T Offset,
  104324. + IN gctSIZE_T Size,
  104325. + IN gctUINT8 EventID
  104326. + )
  104327. +{
  104328. +#ifndef VIVANTE_NO_3D
  104329. + gceSTATUS status;
  104330. + gctUINT32_PTR triggerState;
  104331. +
  104332. + gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x Logical=0x%x"
  104333. + " Offset=%d Size=%d EventID=%d",
  104334. + Hardware, Physical, Logical, Offset, Size, EventID);
  104335. +
  104336. + /* Verify the arguments. */
  104337. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104338. + gcmkVERIFY_ARGUMENT(((Size + 8) & 63) == 0);
  104339. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  104340. +
  104341. + /* Program the trigger state. */
  104342. + triggerState = (gctUINT32_PTR) ((gctUINT8_PTR) Logical + Offset + Size);
  104343. + triggerState[0] = 0x0C03;
  104344. + triggerState[1]
  104345. + = ((((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)))
  104346. + | ((((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)))
  104347. + | ((((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)))
  104348. + | ((((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)))
  104349. + | ((((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)))
  104350. + | ((((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)))
  104351. + ;
  104352. +
  104353. +#if gcdNONPAGED_MEMORY_CACHEABLE
  104354. + /* Flush the cache for the wait/link. */
  104355. + gcmkONERROR(gckOS_CacheClean(
  104356. + Hardware->os, ProcessID, gcvNULL,
  104357. + Physical, Logical, Offset + Size
  104358. + ));
  104359. +#endif
  104360. +
  104361. + /* Start composition. */
  104362. + gcmkONERROR(gckOS_WriteRegisterEx(
  104363. + Hardware->os, Hardware->core, 0x00554,
  104364. + ((((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)))
  104365. + ));
  104366. +
  104367. + /* Success. */
  104368. + gcmkFOOTER_NO();
  104369. + return gcvSTATUS_OK;
  104370. +
  104371. +OnError:
  104372. + /* Return the status. */
  104373. + gcmkFOOTER();
  104374. + return status;
  104375. +#else
  104376. + /* Return the status. */
  104377. + return gcvSTATUS_NOT_SUPPORTED;
  104378. +#endif
  104379. +}
  104380. +
  104381. +/*******************************************************************************
  104382. +**
  104383. +** gckHARDWARE_IsFeatureAvailable
  104384. +**
  104385. +** Verifies whether the specified feature is available in hardware.
  104386. +**
  104387. +** INPUT:
  104388. +**
  104389. +** gckHARDWARE Hardware
  104390. +** Pointer to an gckHARDWARE object.
  104391. +**
  104392. +** gceFEATURE Feature
  104393. +** Feature to be verified.
  104394. +*/
  104395. +gceSTATUS
  104396. +gckHARDWARE_IsFeatureAvailable(
  104397. + IN gckHARDWARE Hardware,
  104398. + IN gceFEATURE Feature
  104399. + )
  104400. +{
  104401. + gctBOOL available;
  104402. +
  104403. + gcmkHEADER_ARG("Hardware=0x%x Feature=%d", Hardware, Feature);
  104404. +
  104405. + /* Verify the arguments. */
  104406. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104407. +
  104408. + /* Only features needed by common kernel logic added here. */
  104409. + switch (Feature)
  104410. + {
  104411. + case gcvFEATURE_END_EVENT:
  104412. + /*available = gcmVERIFYFIELDVALUE(Hardware->identity.chipMinorFeatures2,
  104413. + GC_MINOR_FEATURES2, END_EVENT, AVAILABLE
  104414. + );*/
  104415. + available = gcvFALSE;
  104416. + break;
  104417. + case gcvFEATURE_MC20:
  104418. + 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)))))));
  104419. + break;
  104420. + case gcvFEATURE_DYNAMIC_FREQUENCY_SCALING:
  104421. + /* This feature doesn't apply for 2D cores. */
  104422. + 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)))))))
  104423. + && ((((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)))))));
  104424. + break;
  104425. +
  104426. + case gcvFEATURE_PIPE_2D:
  104427. + 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)))))));
  104428. + break;
  104429. +
  104430. + case gcvFEATURE_PIPE_3D:
  104431. +#ifndef VIVANTE_NO_3D
  104432. + 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)))))));
  104433. +#else
  104434. + available = gcvFALSE;
  104435. +#endif
  104436. + break;
  104437. +
  104438. + case gcvFEATURE_HALTI2:
  104439. + 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)))))));
  104440. + break;
  104441. +
  104442. + default:
  104443. + gcmkFATAL("Invalid feature has been requested.");
  104444. + available = gcvFALSE;
  104445. + }
  104446. +
  104447. + /* Return result. */
  104448. + gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_OK);
  104449. + return available ? gcvSTATUS_TRUE : gcvSTATUS_OK;
  104450. +}
  104451. +
  104452. +/*******************************************************************************
  104453. +**
  104454. +** gckHARDWARE_DumpMMUException
  104455. +**
  104456. +** Dump the MMU debug info on an MMU exception.
  104457. +**
  104458. +** INPUT:
  104459. +**
  104460. +** gckHARDWARE Harwdare
  104461. +** Pointer to an gckHARDWARE object.
  104462. +**
  104463. +** OUTPUT:
  104464. +**
  104465. +** Nothing.
  104466. +*/
  104467. +gceSTATUS
  104468. +gckHARDWARE_DumpMMUException(
  104469. + IN gckHARDWARE Hardware
  104470. + )
  104471. +{
  104472. +#if !gcdPOWER_SUSNPEND_WHEN_IDLE && !gcdPOWEROFF_TIMEOUT
  104473. + gctUINT32 mmu, mmuStatus, address, i;
  104474. +#if gcdDEBUG
  104475. + gctUINT32 mtlb, stlb, offset;
  104476. +#endif
  104477. +
  104478. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  104479. +
  104480. + /* Verify the arguments. */
  104481. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104482. +
  104483. + gcmkPRINT("GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
  104484. + Hardware->core,
  104485. + Hardware->identity.chipModel,
  104486. + Hardware->identity.chipRevision);
  104487. +
  104488. + gcmkPRINT("**************************\n");
  104489. + gcmkPRINT("*** MMU ERROR DUMP ***\n");
  104490. + gcmkPRINT("**************************\n");
  104491. +
  104492. + gcmkVERIFY_OK(
  104493. + gckOS_ReadRegisterEx(Hardware->os,
  104494. + Hardware->core,
  104495. + 0x00188,
  104496. + &mmuStatus));
  104497. +
  104498. + gcmkPRINT(" MMU status = 0x%08X\n", mmuStatus);
  104499. +
  104500. + for (i = 0; i < 4; i += 1)
  104501. + {
  104502. + mmu = mmuStatus & 0xF;
  104503. + mmuStatus >>= 4;
  104504. +
  104505. + if (mmu == 0)
  104506. + {
  104507. + continue;
  104508. + }
  104509. +
  104510. + switch (mmu)
  104511. + {
  104512. + case 1:
  104513. + gcmkPRINT(" MMU%d: slave not present\n", i);
  104514. + break;
  104515. +
  104516. + case 2:
  104517. + gcmkPRINT(" MMU%d: page not present\n", i);
  104518. + break;
  104519. +
  104520. + case 3:
  104521. + gcmkPRINT(" MMU%d: write violation\n", i);
  104522. + break;
  104523. +
  104524. + default:
  104525. + gcmkPRINT(" MMU%d: unknown state\n", i);
  104526. + }
  104527. +
  104528. + gcmkVERIFY_OK(
  104529. + gckOS_ReadRegisterEx(Hardware->os,
  104530. + Hardware->core,
  104531. + 0x00190 + i * 4,
  104532. + &address));
  104533. +
  104534. + mtlb = (address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
  104535. + stlb = (address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
  104536. + offset = address & gcdMMU_OFFSET_4K_MASK;
  104537. +
  104538. + gcmkPRINT(" MMU%d: exception address = 0x%08X\n", i, address);
  104539. +
  104540. + gcmkPRINT(" MTLB entry = %d\n", mtlb);
  104541. +
  104542. + gcmkPRINT(" STLB entry = %d\n", stlb);
  104543. +
  104544. + gcmkPRINT(" Offset = 0x%08X (%d)\n", offset, offset);
  104545. +
  104546. + gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, address);
  104547. +
  104548. + }
  104549. +
  104550. + gcmkFOOTER_NO();
  104551. +#else
  104552. + /* If clock could be off automatically, we can't read mmu debug
  104553. + ** register here; build driver with gcdPOWER_SUSPEND_WHEN_IDLE = 0
  104554. + ** and gcdPOWEROFF_TIMEOUT = 0 to make it safe to read mmu register. */
  104555. + gcmkPRINT("[galcore] %s(%d): MMU Exception!", __FUNCTION__, __LINE__);
  104556. +#endif
  104557. +
  104558. + return gcvSTATUS_OK;
  104559. +}
  104560. +
  104561. +/*******************************************************************************
  104562. +**
  104563. +** gckHARDWARE_DumpGPUState
  104564. +**
  104565. +** Dump the GPU debug registers.
  104566. +**
  104567. +** INPUT:
  104568. +**
  104569. +** gckHARDWARE Harwdare
  104570. +** Pointer to an gckHARDWARE object.
  104571. +**
  104572. +** OUTPUT:
  104573. +**
  104574. +** Nothing.
  104575. +*/
  104576. +gceSTATUS
  104577. +gckHARDWARE_DumpGPUState(
  104578. + IN gckHARDWARE Hardware
  104579. + )
  104580. +{
  104581. + static gctCONST_STRING _cmdState[] =
  104582. + {
  104583. + "PAR_IDLE_ST", "PAR_DEC_ST", "PAR_ADR0_ST", "PAR_LOAD0_ST",
  104584. + "PAR_ADR1_ST", "PAR_LOAD1_ST", "PAR_3DADR_ST", "PAR_3DCMD_ST",
  104585. + "PAR_3DCNTL_ST", "PAR_3DIDXCNTL_ST", "PAR_INITREQDMA_ST",
  104586. + "PAR_DRAWIDX_ST", "PAR_DRAW_ST", "PAR_2DRECT0_ST", "PAR_2DRECT1_ST",
  104587. + "PAR_2DDATA0_ST", "PAR_2DDATA1_ST", "PAR_WAITFIFO_ST", "PAR_WAIT_ST",
  104588. + "PAR_LINK_ST", "PAR_END_ST", "PAR_STALL_ST"
  104589. + };
  104590. +
  104591. + static gctCONST_STRING _cmdDmaState[] =
  104592. + {
  104593. + "CMD_IDLE_ST", "CMD_START_ST", "CMD_REQ_ST", "CMD_END_ST"
  104594. + };
  104595. +
  104596. + static gctCONST_STRING _cmdFetState[] =
  104597. + {
  104598. + "FET_IDLE_ST", "FET_RAMVALID_ST", "FET_VALID_ST"
  104599. + };
  104600. +
  104601. + static gctCONST_STRING _reqDmaState[] =
  104602. + {
  104603. + "REQ_IDLE_ST", "REQ_WAITIDX_ST", "REQ_CAL_ST"
  104604. + };
  104605. +
  104606. + static gctCONST_STRING _calState[] =
  104607. + {
  104608. + "CAL_IDLE_ST", "CAL_LDADR_ST", "CAL_IDXCALC_ST"
  104609. + };
  104610. +
  104611. + static gctCONST_STRING _veReqState[] =
  104612. + {
  104613. + "VER_IDLE_ST", "VER_CKCACHE_ST", "VER_MISS_ST"
  104614. + };
  104615. +
  104616. + static gcsiDEBUG_REGISTERS _dbgRegs[] =
  104617. + {
  104618. + { "RA", 0x474, 16, 0x448, 16, 0x12344321 },
  104619. + { "TX", 0x474, 24, 0x44C, 16, 0x12211221 },
  104620. + { "FE", 0x470, 0, 0x450, 16, 0xBABEF00D },
  104621. + { "PE", 0x470, 16, 0x454, 16, 0xBABEF00D },
  104622. + { "DE", 0x470, 8, 0x458, 16, 0xBABEF00D },
  104623. + { "SH", 0x470, 24, 0x45C, 16, 0xDEADBEEF },
  104624. + { "PA", 0x474, 0, 0x460, 16, 0x0000AAAA },
  104625. + { "SE", 0x474, 8, 0x464, 16, 0x5E5E5E5E },
  104626. + { "MC", 0x478, 0, 0x468, 16, 0x12345678 },
  104627. + { "HI", 0x478, 8, 0x46C, 16, 0xAAAAAAAA }
  104628. + };
  104629. +
  104630. + static gctUINT32 _otherRegs[] =
  104631. + {
  104632. + 0x040, 0x044, 0x04C, 0x050, 0x054, 0x058, 0x05C, 0x060,
  104633. + 0x43c, 0x440, 0x444, 0x414,
  104634. + };
  104635. +
  104636. + gceSTATUS status;
  104637. + gckKERNEL kernel;
  104638. + gctUINT32 idle, axi;
  104639. + gctUINT32 dmaAddress1, dmaAddress2;
  104640. + gctUINT32 dmaState1, dmaState2;
  104641. + gctUINT32 dmaLow, dmaHigh;
  104642. + gctUINT32 cmdState, cmdDmaState, cmdFetState;
  104643. + gctUINT32 dmaReqState, calState, veReqState;
  104644. + gctUINT i;
  104645. + gctUINT pipe, pixelPipes;
  104646. + gctUINT32 control, oldControl;
  104647. + gckOS os = Hardware->os;
  104648. + gceCORE core = Hardware->core;
  104649. +
  104650. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  104651. +
  104652. + kernel = Hardware->kernel;
  104653. +
  104654. + gcmkPRINT_N(12, "GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
  104655. + core,
  104656. + Hardware->identity.chipModel,
  104657. + Hardware->identity.chipRevision);
  104658. +
  104659. + pixelPipes = Hardware->identity.pixelPipes
  104660. + ? Hardware->identity.pixelPipes
  104661. + : 1;
  104662. +
  104663. + /* Reset register values. */
  104664. + idle = axi =
  104665. + dmaState1 = dmaState2 =
  104666. + dmaAddress1 = dmaAddress2 =
  104667. + dmaLow = dmaHigh = 0;
  104668. +
  104669. + /* Verify whether DMA is running. */
  104670. + gcmkONERROR(_VerifyDMA(
  104671. + os, core, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
  104672. + ));
  104673. +
  104674. + cmdState = dmaState2 & 0x1F;
  104675. + cmdDmaState = (dmaState2 >> 8) & 0x03;
  104676. + cmdFetState = (dmaState2 >> 10) & 0x03;
  104677. + dmaReqState = (dmaState2 >> 12) & 0x03;
  104678. + calState = (dmaState2 >> 14) & 0x03;
  104679. + veReqState = (dmaState2 >> 16) & 0x03;
  104680. +
  104681. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x004, &idle));
  104682. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x00C, &axi));
  104683. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x668, &dmaLow));
  104684. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x66C, &dmaHigh));
  104685. +
  104686. + gcmkPRINT_N(0, "**************************\n");
  104687. + gcmkPRINT_N(0, "*** GPU STATE DUMP ***\n");
  104688. + gcmkPRINT_N(0, "**************************\n");
  104689. +
  104690. + gcmkPRINT_N(4, " axi = 0x%08X\n", axi);
  104691. +
  104692. + gcmkPRINT_N(4, " idle = 0x%08X\n", idle);
  104693. + if ((idle & 0x00000001) == 0) gcmkPRINT_N(0, " FE not idle\n");
  104694. + if ((idle & 0x00000002) == 0) gcmkPRINT_N(0, " DE not idle\n");
  104695. + if ((idle & 0x00000004) == 0) gcmkPRINT_N(0, " PE not idle\n");
  104696. + if ((idle & 0x00000008) == 0) gcmkPRINT_N(0, " SH not idle\n");
  104697. + if ((idle & 0x00000010) == 0) gcmkPRINT_N(0, " PA not idle\n");
  104698. + if ((idle & 0x00000020) == 0) gcmkPRINT_N(0, " SE not idle\n");
  104699. + if ((idle & 0x00000040) == 0) gcmkPRINT_N(0, " RA not idle\n");
  104700. + if ((idle & 0x00000080) == 0) gcmkPRINT_N(0, " TX not idle\n");
  104701. + if ((idle & 0x00000100) == 0) gcmkPRINT_N(0, " VG not idle\n");
  104702. + if ((idle & 0x00000200) == 0) gcmkPRINT_N(0, " IM not idle\n");
  104703. + if ((idle & 0x00000400) == 0) gcmkPRINT_N(0, " FP not idle\n");
  104704. + if ((idle & 0x00000800) == 0) gcmkPRINT_N(0, " TS not idle\n");
  104705. + if ((idle & 0x80000000) != 0) gcmkPRINT_N(0, " AXI low power mode\n");
  104706. +
  104707. + if (
  104708. + (dmaAddress1 == dmaAddress2)
  104709. + && (dmaState1 == dmaState2)
  104710. + )
  104711. + {
  104712. + gcmkPRINT_N(0, " DMA appears to be stuck at this address:\n");
  104713. + gcmkPRINT_N(4, " 0x%08X\n", dmaAddress1);
  104714. + }
  104715. + else
  104716. + {
  104717. + if (dmaAddress1 == dmaAddress2)
  104718. + {
  104719. + gcmkPRINT_N(0, " DMA address is constant, but state is changing:\n");
  104720. + gcmkPRINT_N(4, " 0x%08X\n", dmaState1);
  104721. + gcmkPRINT_N(4, " 0x%08X\n", dmaState2);
  104722. + }
  104723. + else
  104724. + {
  104725. + gcmkPRINT_N(0, " DMA is running; known addresses are:\n");
  104726. + gcmkPRINT_N(4, " 0x%08X\n", dmaAddress1);
  104727. + gcmkPRINT_N(4, " 0x%08X\n", dmaAddress2);
  104728. + }
  104729. + }
  104730. + gcmkPRINT_N(4, " dmaLow = 0x%08X\n", dmaLow);
  104731. + gcmkPRINT_N(4, " dmaHigh = 0x%08X\n", dmaHigh);
  104732. + gcmkPRINT_N(4, " dmaState = 0x%08X\n", dmaState2);
  104733. + gcmkPRINT_N(8, " command state = %d (%s)\n", cmdState, _cmdState [cmdState]);
  104734. + gcmkPRINT_N(8, " command DMA state = %d (%s)\n", cmdDmaState, _cmdDmaState[cmdDmaState]);
  104735. + gcmkPRINT_N(8, " command fetch state = %d (%s)\n", cmdFetState, _cmdFetState[cmdFetState]);
  104736. + gcmkPRINT_N(8, " DMA request state = %d (%s)\n", dmaReqState, _reqDmaState[dmaReqState]);
  104737. + gcmkPRINT_N(8, " cal state = %d (%s)\n", calState, _calState [calState]);
  104738. + gcmkPRINT_N(8, " VE request state = %d (%s)\n", veReqState, _veReqState [veReqState]);
  104739. +
  104740. + /* Record control. */
  104741. + gckOS_ReadRegisterEx(os, core, 0x0, &oldControl);
  104742. +
  104743. + for (pipe = 0; pipe < pixelPipes; pipe++)
  104744. + {
  104745. + gcmkPRINT_N(4, " Debug registers of pipe[%d]:\n", pipe);
  104746. +
  104747. + /* Switch pipe. */
  104748. + gckOS_ReadRegisterEx(os, core, 0x0, &control);
  104749. + control &= ~(0xF << 20);
  104750. + control |= (pipe << 20);
  104751. + gckOS_WriteRegisterEx(os, core, 0x0, control);
  104752. +
  104753. + for (i = 0; i < gcmCOUNTOF(_dbgRegs); i += 1)
  104754. + {
  104755. + gcmkONERROR(_DumpDebugRegisters(os, core, &_dbgRegs[i]));
  104756. + }
  104757. +
  104758. + gcmkPRINT_N(0, " Other Registers:\n");
  104759. + for (i = 0; i < gcmCOUNTOF(_otherRegs); i += 1)
  104760. + {
  104761. + gctUINT32 read;
  104762. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, _otherRegs[i], &read));
  104763. + gcmkPRINT_N(12, " [0x%04X] 0x%08X\n", _otherRegs[i], read);
  104764. + }
  104765. + }
  104766. +
  104767. + if (kernel->hardware->identity.chipFeatures & (1 << 4))
  104768. + {
  104769. + gctUINT32 read0, read1, write;
  104770. +
  104771. + read0 = read1 = write = 0;
  104772. +
  104773. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x43C, &read0));
  104774. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x440, &read1));
  104775. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x444, &write));
  104776. +
  104777. + gcmkPRINT_N(4, " read0 = 0x%08X\n", read0);
  104778. + gcmkPRINT_N(4, " read1 = 0x%08X\n", read1);
  104779. + gcmkPRINT_N(4, " write = 0x%08X\n", write);
  104780. + }
  104781. +
  104782. + /* Restore control. */
  104783. + gckOS_WriteRegisterEx(os, core, 0x0, oldControl);
  104784. +
  104785. + /* dump stack. */
  104786. + gckOS_DumpCallStack(os);
  104787. +
  104788. +OnError:
  104789. +
  104790. + /* Return the error. */
  104791. + gcmkFOOTER();
  104792. + return status;
  104793. +}
  104794. +
  104795. +
  104796. +#if gcdFRAME_DB
  104797. +static gceSTATUS
  104798. +gckHARDWARE_ReadPerformanceRegister(
  104799. + IN gckHARDWARE Hardware,
  104800. + IN gctUINT PerformanceAddress,
  104801. + IN gctUINT IndexAddress,
  104802. + IN gctUINT IndexShift,
  104803. + IN gctUINT Index,
  104804. + OUT gctUINT32_PTR Value
  104805. + )
  104806. +{
  104807. + gceSTATUS status;
  104808. +
  104809. + gcmkHEADER_ARG("Hardware=0x%x PerformanceAddress=0x%x IndexAddress=0x%x "
  104810. + "IndexShift=%u Index=%u",
  104811. + Hardware, PerformanceAddress, IndexAddress, IndexShift,
  104812. + Index);
  104813. +
  104814. + /* Write the index. */
  104815. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  104816. + Hardware->core,
  104817. + IndexAddress,
  104818. + Index << IndexShift));
  104819. +
  104820. + /* Read the register. */
  104821. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  104822. + Hardware->core,
  104823. + PerformanceAddress,
  104824. + Value));
  104825. +
  104826. + /* Test for reset. */
  104827. + if (Index == 15)
  104828. + {
  104829. + /* Index another register to get out of reset. */
  104830. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, IndexAddress, 0));
  104831. + }
  104832. +
  104833. + /* Success. */
  104834. + gcmkFOOTER_ARG("*Value=0x%x", *Value);
  104835. + return gcvSTATUS_OK;
  104836. +
  104837. +OnError:
  104838. + /* Return the status. */
  104839. + gcmkFOOTER();
  104840. + return status;
  104841. +}
  104842. +
  104843. +gceSTATUS
  104844. +gckHARDWARE_GetFrameInfo(
  104845. + IN gckHARDWARE Hardware,
  104846. + OUT gcsHAL_FRAME_INFO * FrameInfo
  104847. + )
  104848. +{
  104849. + gceSTATUS status;
  104850. + gctUINT i, clock;
  104851. + gcsHAL_FRAME_INFO info;
  104852. +#if gcdFRAME_DB_RESET
  104853. + gctUINT reset;
  104854. +#endif
  104855. +
  104856. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  104857. +
  104858. + /* Get profile tick. */
  104859. + gcmkONERROR(gckOS_GetProfileTick(&info.ticks));
  104860. +
  104861. + /* Read SH counters and reset them. */
  104862. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104863. + Hardware,
  104864. + 0x0045C,
  104865. + 0x00470,
  104866. + 24,
  104867. + 4,
  104868. + &info.shaderCycles));
  104869. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104870. + Hardware,
  104871. + 0x0045C,
  104872. + 0x00470,
  104873. + 24,
  104874. + 9,
  104875. + &info.vsInstructionCount));
  104876. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104877. + Hardware,
  104878. + 0x0045C,
  104879. + 0x00470,
  104880. + 24,
  104881. + 12,
  104882. + &info.vsTextureCount));
  104883. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104884. + Hardware,
  104885. + 0x0045C,
  104886. + 0x00470,
  104887. + 24,
  104888. + 7,
  104889. + &info.psInstructionCount));
  104890. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104891. + Hardware,
  104892. + 0x0045C,
  104893. + 0x00470,
  104894. + 24,
  104895. + 14,
  104896. + &info.psTextureCount));
  104897. +#if gcdFRAME_DB_RESET
  104898. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104899. + Hardware,
  104900. + 0x0045C,
  104901. + 0x00470,
  104902. + 24,
  104903. + 15,
  104904. + &reset));
  104905. +#endif
  104906. +
  104907. + /* Read PA counters and reset them. */
  104908. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104909. + Hardware,
  104910. + 0x00460,
  104911. + 0x00474,
  104912. + 0,
  104913. + 3,
  104914. + &info.vertexCount));
  104915. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104916. + Hardware,
  104917. + 0x00460,
  104918. + 0x00474,
  104919. + 0,
  104920. + 4,
  104921. + &info.primitiveCount));
  104922. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104923. + Hardware,
  104924. + 0x00460,
  104925. + 0x00474,
  104926. + 0,
  104927. + 7,
  104928. + &info.rejectedPrimitives));
  104929. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104930. + Hardware,
  104931. + 0x00460,
  104932. + 0x00474,
  104933. + 0,
  104934. + 8,
  104935. + &info.culledPrimitives));
  104936. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104937. + Hardware,
  104938. + 0x00460,
  104939. + 0x00474,
  104940. + 0,
  104941. + 6,
  104942. + &info.clippedPrimitives));
  104943. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104944. + Hardware,
  104945. + 0x00460,
  104946. + 0x00474,
  104947. + 0,
  104948. + 5,
  104949. + &info.outPrimitives));
  104950. +#if gcdFRAME_DB_RESET
  104951. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104952. + Hardware,
  104953. + 0x00460,
  104954. + 0x00474,
  104955. + 0,
  104956. + 15,
  104957. + &reset));
  104958. +#endif
  104959. +
  104960. + /* Read RA counters and reset them. */
  104961. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104962. + Hardware,
  104963. + 0x00448,
  104964. + 0x00474,
  104965. + 16,
  104966. + 3,
  104967. + &info.inPrimitives));
  104968. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104969. + Hardware,
  104970. + 0x00448,
  104971. + 0x00474,
  104972. + 16,
  104973. + 11,
  104974. + &info.culledQuadCount));
  104975. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104976. + Hardware,
  104977. + 0x00448,
  104978. + 0x00474,
  104979. + 16,
  104980. + 1,
  104981. + &info.totalQuadCount));
  104982. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104983. + Hardware,
  104984. + 0x00448,
  104985. + 0x00474,
  104986. + 16,
  104987. + 2,
  104988. + &info.quadCount));
  104989. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104990. + Hardware,
  104991. + 0x00448,
  104992. + 0x00474,
  104993. + 16,
  104994. + 0,
  104995. + &info.totalPixelCount));
  104996. +#if gcdFRAME_DB_RESET
  104997. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  104998. + Hardware,
  104999. + 0x00448,
  105000. + 0x00474,
  105001. + 16,
  105002. + 15,
  105003. + &reset));
  105004. +#endif
  105005. +
  105006. + /* Read TX counters and reset them. */
  105007. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105008. + Hardware,
  105009. + 0x0044C,
  105010. + 0x00474,
  105011. + 24,
  105012. + 0,
  105013. + &info.bilinearRequests));
  105014. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105015. + Hardware,
  105016. + 0x0044C,
  105017. + 0x00474,
  105018. + 24,
  105019. + 1,
  105020. + &info.trilinearRequests));
  105021. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105022. + Hardware,
  105023. + 0x0044C,
  105024. + 0x00474,
  105025. + 24,
  105026. + 8,
  105027. + &info.txHitCount));
  105028. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105029. + Hardware,
  105030. + 0x0044C,
  105031. + 0x00474,
  105032. + 24,
  105033. + 9,
  105034. + &info.txMissCount));
  105035. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105036. + Hardware,
  105037. + 0x0044C,
  105038. + 0x00474,
  105039. + 24,
  105040. + 6,
  105041. + &info.txBytes8));
  105042. +#if gcdFRAME_DB_RESET
  105043. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105044. + Hardware,
  105045. + 0x0044C,
  105046. + 0x00474,
  105047. + 24,
  105048. + 15,
  105049. + &reset));
  105050. +#endif
  105051. +
  105052. + /* Read clock control register. */
  105053. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105054. + Hardware->core,
  105055. + 0x00000,
  105056. + &clock));
  105057. +
  105058. + /* Walk through all avaiable pixel pipes. */
  105059. + for (i = 0; i < Hardware->identity.pixelPipes; ++i)
  105060. + {
  105061. + /* Select proper pipe. */
  105062. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105063. + Hardware->core,
  105064. + 0x00000,
  105065. + ((((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)))));
  105066. +
  105067. + /* Read cycle registers. */
  105068. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105069. + Hardware->core,
  105070. + 0x00078,
  105071. + &info.cycles[i]));
  105072. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105073. + Hardware->core,
  105074. + 0x0007C,
  105075. + &info.idleCycles[i]));
  105076. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105077. + Hardware->core,
  105078. + 0x00438,
  105079. + &info.mcCycles[i]));
  105080. +
  105081. + /* Read bandwidth registers. */
  105082. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105083. + Hardware->core,
  105084. + 0x0005C,
  105085. + &info.readRequests[i]));
  105086. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105087. + Hardware->core,
  105088. + 0x00040,
  105089. + &info.readBytes8[i]));
  105090. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105091. + Hardware->core,
  105092. + 0x00050,
  105093. + &info.writeRequests[i]));
  105094. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105095. + Hardware->core,
  105096. + 0x00044,
  105097. + &info.writeBytes8[i]));
  105098. +
  105099. + /* Read PE counters. */
  105100. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105101. + Hardware,
  105102. + 0x00454,
  105103. + 0x00470,
  105104. + 16,
  105105. + 0,
  105106. + &info.colorKilled[i]));
  105107. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105108. + Hardware,
  105109. + 0x00454,
  105110. + 0x00470,
  105111. + 16,
  105112. + 2,
  105113. + &info.colorDrawn[i]));
  105114. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105115. + Hardware,
  105116. + 0x00454,
  105117. + 0x00470,
  105118. + 16,
  105119. + 1,
  105120. + &info.depthKilled[i]));
  105121. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105122. + Hardware,
  105123. + 0x00454,
  105124. + 0x00470,
  105125. + 16,
  105126. + 3,
  105127. + &info.depthDrawn[i]));
  105128. + }
  105129. +
  105130. + /* Zero out remaning reserved counters. */
  105131. + for (; i < 8; ++i)
  105132. + {
  105133. + info.readBytes8[i] = 0;
  105134. + info.writeBytes8[i] = 0;
  105135. + info.cycles[i] = 0;
  105136. + info.idleCycles[i] = 0;
  105137. + info.mcCycles[i] = 0;
  105138. + info.readRequests[i] = 0;
  105139. + info.writeRequests[i] = 0;
  105140. + info.colorKilled[i] = 0;
  105141. + info.colorDrawn[i] = 0;
  105142. + info.depthKilled[i] = 0;
  105143. + info.depthDrawn[i] = 0;
  105144. + }
  105145. +
  105146. + /* Reset clock control register. */
  105147. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105148. + Hardware->core,
  105149. + 0x00000,
  105150. + clock));
  105151. +
  105152. + /* Reset cycle and bandwidth counters. */
  105153. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105154. + Hardware->core,
  105155. + 0x0003C,
  105156. + 1));
  105157. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105158. + Hardware->core,
  105159. + 0x0003C,
  105160. + 0));
  105161. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105162. + Hardware->core,
  105163. + 0x00078,
  105164. + 0));
  105165. +
  105166. +#if gcdFRAME_DB_RESET
  105167. + /* Reset PE counters. */
  105168. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  105169. + Hardware,
  105170. + 0x00454,
  105171. + 0x00470,
  105172. + 16,
  105173. + 15,
  105174. + &reset));
  105175. +#endif
  105176. +
  105177. + /* Copy to user. */
  105178. + gcmkONERROR(gckOS_CopyToUserData(Hardware->os,
  105179. + &info,
  105180. + FrameInfo,
  105181. + gcmSIZEOF(info)));
  105182. +
  105183. + /* Success. */
  105184. + gcmkFOOTER_NO();
  105185. + return gcvSTATUS_OK;
  105186. +
  105187. +OnError:
  105188. + /* Return the status. */
  105189. + gcmkFOOTER();
  105190. + return status;
  105191. +}
  105192. +#endif
  105193. +
  105194. +#if gcdDVFS
  105195. +#define READ_FROM_EATER1 0
  105196. +
  105197. +gceSTATUS
  105198. +gckHARDWARE_QueryLoad(
  105199. + IN gckHARDWARE Hardware,
  105200. + OUT gctUINT32 * Load
  105201. + )
  105202. +{
  105203. + gctUINT32 debug1;
  105204. + gceSTATUS status;
  105205. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  105206. +
  105207. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105208. + gcmkVERIFY_ARGUMENT(Load != gcvNULL);
  105209. +
  105210. + gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
  105211. +
  105212. + if (Hardware->chipPowerState == gcvPOWER_ON)
  105213. + {
  105214. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105215. + Hardware->core,
  105216. + 0x00110,
  105217. + Load));
  105218. +#if READ_FROM_EATER1
  105219. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105220. + Hardware->core,
  105221. + 0x00134,
  105222. + Load));
  105223. +#endif
  105224. +
  105225. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105226. + Hardware->core,
  105227. + 0x00114,
  105228. + &debug1));
  105229. +
  105230. + /* Patch result of 0x110 with result of 0x114. */
  105231. + if ((debug1 & 0xFF) == 1)
  105232. + {
  105233. + *Load &= ~0xFF;
  105234. + *Load |= 1;
  105235. + }
  105236. +
  105237. + if (((debug1 & 0xFF00) >> 8) == 1)
  105238. + {
  105239. + *Load &= ~(0xFF << 8);
  105240. + *Load |= 1 << 8;
  105241. + }
  105242. +
  105243. + if (((debug1 & 0xFF0000) >> 16) == 1)
  105244. + {
  105245. + *Load &= ~(0xFF << 16);
  105246. + *Load |= 1 << 16;
  105247. + }
  105248. +
  105249. + if (((debug1 & 0xFF000000) >> 24) == 1)
  105250. + {
  105251. + *Load &= ~(0xFF << 24);
  105252. + *Load |= 1 << 24;
  105253. + }
  105254. + }
  105255. + else
  105256. + {
  105257. + status = gcvSTATUS_INVALID_REQUEST;
  105258. + }
  105259. +
  105260. +OnError:
  105261. +
  105262. + gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
  105263. +
  105264. + gcmkFOOTER();
  105265. + return status;
  105266. +}
  105267. +
  105268. +gceSTATUS
  105269. +gckHARDWARE_SetDVFSPeroid(
  105270. + IN gckHARDWARE Hardware,
  105271. + OUT gctUINT32 Frequency
  105272. + )
  105273. +{
  105274. + gceSTATUS status;
  105275. + gctUINT32 period;
  105276. + gctUINT32 eater;
  105277. +
  105278. +#if READ_FROM_EATER1
  105279. + gctUINT32 period1;
  105280. + gctUINT32 eater1;
  105281. +#endif
  105282. +
  105283. + gcmkHEADER_ARG("Hardware=0x%X Frequency=%d", Hardware, Frequency);
  105284. +
  105285. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105286. +
  105287. + period = 0;
  105288. +
  105289. + while((64 << period) < (gcdDVFS_ANAYLSE_WINDOW * Frequency * 1000) )
  105290. + {
  105291. + period++;
  105292. + }
  105293. +
  105294. +#if READ_FROM_EATER1
  105295. + /*
  105296. + * Peroid = F * 1000 * 1000 / (60 * 16 * 1024);
  105297. + */
  105298. + period1 = Frequency * 6250 / 6114;
  105299. +#endif
  105300. +
  105301. + gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
  105302. +
  105303. + if (Hardware->chipPowerState == gcvPOWER_ON)
  105304. + {
  105305. + /* Get current configure. */
  105306. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105307. + Hardware->core,
  105308. + 0x0010C,
  105309. + &eater));
  105310. +
  105311. + /* Change peroid. */
  105312. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105313. + Hardware->core,
  105314. + 0x0010C,
  105315. + ((((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)))));
  105316. +
  105317. +#if READ_FROM_EATER1
  105318. + /* Config eater1. */
  105319. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105320. + Hardware->core,
  105321. + 0x00130,
  105322. + &eater1));
  105323. +
  105324. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105325. + Hardware->core,
  105326. + 0x00130,
  105327. + ((((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)))));
  105328. +#endif
  105329. + }
  105330. + else
  105331. + {
  105332. + status = gcvSTATUS_INVALID_REQUEST;
  105333. + }
  105334. +
  105335. +OnError:
  105336. + gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
  105337. +
  105338. + gcmkFOOTER();
  105339. + return status;
  105340. +}
  105341. +
  105342. +gceSTATUS
  105343. +gckHARDWARE_InitDVFS(
  105344. + IN gckHARDWARE Hardware
  105345. + )
  105346. +{
  105347. + gceSTATUS status;
  105348. + gctUINT32 data;
  105349. +
  105350. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  105351. +
  105352. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105353. +
  105354. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105355. + Hardware->core,
  105356. + 0x0010C,
  105357. + &data));
  105358. +
  105359. + 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)));
  105360. + 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)));
  105361. + 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)));
  105362. + 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)));
  105363. + 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)));
  105364. + 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)));
  105365. +
  105366. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  105367. + "DVFS Configure=0x%X",
  105368. + data);
  105369. +
  105370. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105371. + Hardware->core,
  105372. + 0x0010C,
  105373. + data));
  105374. +
  105375. + gcmkFOOTER_NO();
  105376. + return gcvSTATUS_OK;
  105377. +
  105378. +OnError:
  105379. + gcmkFOOTER();
  105380. + return status;
  105381. +}
  105382. +#endif
  105383. +
  105384. +
  105385. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h
  105386. --- linux-3.14.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h 1969-12-31 18:00:00.000000000 -0600
  105387. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h 2014-12-08 00:31:53.464418001 -0600
  105388. @@ -0,0 +1,136 @@
  105389. +/****************************************************************************
  105390. +*
  105391. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  105392. +*
  105393. +* This program is free software; you can redistribute it and/or modify
  105394. +* it under the terms of the GNU General Public License as published by
  105395. +* the Free Software Foundation; either version 2 of the license, or
  105396. +* (at your option) any later version.
  105397. +*
  105398. +* This program is distributed in the hope that it will be useful,
  105399. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  105400. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  105401. +* GNU General Public License for more details.
  105402. +*
  105403. +* You should have received a copy of the GNU General Public License
  105404. +* along with this program; if not write to the Free Software
  105405. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  105406. +*
  105407. +*****************************************************************************/
  105408. +
  105409. +
  105410. +#ifndef __gc_hal_kernel_hardware_h_
  105411. +#define __gc_hal_kernel_hardware_h_
  105412. +
  105413. +#if gcdENABLE_VG
  105414. +#include "gc_hal_kernel_hardware_vg.h"
  105415. +#endif
  105416. +
  105417. +#ifdef __cplusplus
  105418. +extern "C" {
  105419. +#endif
  105420. +
  105421. +/* gckHARDWARE object. */
  105422. +struct _gckHARDWARE
  105423. +{
  105424. + /* Object. */
  105425. + gcsOBJECT object;
  105426. +
  105427. + /* Pointer to gctKERNEL object. */
  105428. + gckKERNEL kernel;
  105429. +
  105430. + /* Pointer to gctOS object. */
  105431. + gckOS os;
  105432. +
  105433. + /* Core */
  105434. + gceCORE core;
  105435. +
  105436. + /* Chip characteristics. */
  105437. + gcsHAL_QUERY_CHIP_IDENTITY identity;
  105438. + gctBOOL allowFastClear;
  105439. + gctBOOL allowCompression;
  105440. + gctUINT32 powerBaseAddress;
  105441. + gctBOOL extraEventStates;
  105442. +
  105443. + /* Big endian */
  105444. + gctBOOL bigEndian;
  105445. +
  105446. + /* Chip status */
  105447. + gctPOINTER powerMutex;
  105448. + gctUINT32 powerProcess;
  105449. + gctUINT32 powerThread;
  105450. + gceCHIPPOWERSTATE chipPowerState;
  105451. + gctUINT32 lastWaitLink;
  105452. + gctBOOL clockState;
  105453. + gctBOOL powerState;
  105454. + gctPOINTER globalSemaphore;
  105455. +
  105456. + gctISRMANAGERFUNC startIsr;
  105457. + gctISRMANAGERFUNC stopIsr;
  105458. + gctPOINTER isrContext;
  105459. +
  105460. + gctUINT32 mmuVersion;
  105461. +
  105462. + /* Type */
  105463. + gceHARDWARE_TYPE type;
  105464. +
  105465. +#if gcdPOWEROFF_TIMEOUT
  105466. + gctUINT32 powerOffTime;
  105467. + gctUINT32 powerOffTimeout;
  105468. + gctPOINTER powerOffTimer;
  105469. +#endif
  105470. +
  105471. + gctPOINTER pageTableDirty;
  105472. +
  105473. +#if gcdENABLE_FSCALE_VAL_ADJUST
  105474. + /* FSCALE_VAL when gcvPOWER_ON. */
  105475. + gctUINT32 powerOnFscaleVal;
  105476. +#endif
  105477. +
  105478. +#if gcdLINK_QUEUE_SIZE
  105479. + struct _gckLINKQUEUE linkQueue;
  105480. +#endif
  105481. +
  105482. + gctBOOL powerManagement;
  105483. + gctBOOL gpuProfiler;
  105484. +};
  105485. +
  105486. +gceSTATUS
  105487. +gckHARDWARE_GetBaseAddress(
  105488. + IN gckHARDWARE Hardware,
  105489. + OUT gctUINT32_PTR BaseAddress
  105490. + );
  105491. +
  105492. +gceSTATUS
  105493. +gckHARDWARE_NeedBaseAddress(
  105494. + IN gckHARDWARE Hardware,
  105495. + IN gctUINT32 State,
  105496. + OUT gctBOOL_PTR NeedBase
  105497. + );
  105498. +
  105499. +gceSTATUS
  105500. +gckHARDWARE_GetFrameInfo(
  105501. + IN gckHARDWARE Hardware,
  105502. + OUT gcsHAL_FRAME_INFO * FrameInfo
  105503. + );
  105504. +
  105505. +gceSTATUS
  105506. +gckHARDWARE_SetFscaleValue(
  105507. + IN gckHARDWARE Hardware,
  105508. + IN gctUINT32 FscaleValue
  105509. + );
  105510. +
  105511. +gceSTATUS
  105512. +gckHARDWARE_GetFscaleValue(
  105513. + IN gckHARDWARE Hardware,
  105514. + IN gctUINT * FscaleValue,
  105515. + IN gctUINT * MinFscaleValue,
  105516. + IN gctUINT * MaxFscaleValue
  105517. + );
  105518. +
  105519. +#ifdef __cplusplus
  105520. +}
  105521. +#endif
  105522. +
  105523. +#endif /* __gc_hal_kernel_hardware_h_ */
  105524. +
  105525. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/config linux-imx6-3.14/drivers/mxc/gpu-viv/config
  105526. --- linux-3.14.14/drivers/mxc/gpu-viv/config 1969-12-31 18:00:00.000000000 -0600
  105527. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/config 2014-12-08 00:31:53.464418001 -0600
  105528. @@ -0,0 +1,38 @@
  105529. +##############################################################################
  105530. +#
  105531. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  105532. +#
  105533. +# This program is free software; you can redistribute it and/or modify
  105534. +# it under the terms of the GNU General Public License as published by
  105535. +# the Free Software Foundation; either version 2 of the license, or
  105536. +# (at your option) any later version.
  105537. +#
  105538. +# This program is distributed in the hope that it will be useful,
  105539. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  105540. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  105541. +# GNU General Public License for more details.
  105542. +#
  105543. +# You should have received a copy of the GNU General Public License
  105544. +# along with this program; if not write to the Free Software
  105545. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  105546. +#
  105547. +##############################################################################
  105548. +
  105549. +
  105550. +ARCH_TYPE ?= arm
  105551. +SDK_DIR ?= $(AQROOT)/build/sdk
  105552. +USE_3D_VG ?= 1
  105553. +FORCE_ALL_VIDEO_MEMORY_CACHED ?= 0
  105554. +NONPAGED_MEMORY_CACHEABLE ?= 0
  105555. +NONPAGED_MEMORY_BUFFERABLE ?= 1
  105556. +CACHE_FUNCTION_UNIMPLEMENTED ?= 0
  105557. +VIVANTE_ENABLE_VG ?= 1
  105558. +NO_USER_DIRECT_ACCESS_FROM_KERNEL ?= 1
  105559. +VIVANTE_NO_3D ?= 0
  105560. +ENABLE_OUTER_CACHE_PATCH ?= 1
  105561. +USE_BANK_ALIGNMENT ?= 1
  105562. +BANK_BIT_START ?= 13
  105563. +BANK_BIT_END ?= 15
  105564. +BANK_CHANNEL_BIT ?= 12
  105565. +ENABLE_GPU_CLOCK_BY_DRIVER = 1
  105566. +
  105567. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
  105568. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c 1969-12-31 18:00:00.000000000 -0600
  105569. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c 2014-12-08 00:31:53.464418001 -0600
  105570. @@ -0,0 +1,3967 @@
  105571. +/****************************************************************************
  105572. +*
  105573. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  105574. +*
  105575. +* This program is free software; you can redistribute it and/or modify
  105576. +* it under the terms of the GNU General Public License as published by
  105577. +* the Free Software Foundation; either version 2 of the license, or
  105578. +* (at your option) any later version.
  105579. +*
  105580. +* This program is distributed in the hope that it will be useful,
  105581. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  105582. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  105583. +* GNU General Public License for more details.
  105584. +*
  105585. +* You should have received a copy of the GNU General Public License
  105586. +* along with this program; if not write to the Free Software
  105587. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  105588. +*
  105589. +*****************************************************************************/
  105590. +
  105591. +
  105592. +#include "gc_hal_kernel_precomp.h"
  105593. +
  105594. +#define _GC_OBJ_ZONE gcvZONE_KERNEL
  105595. +
  105596. +/*******************************************************************************
  105597. +***** Version Signature *******************************************************/
  105598. +
  105599. +#define _gcmTXT2STR(t) #t
  105600. +#define gcmTXT2STR(t) _gcmTXT2STR(t)
  105601. +const char * _VERSION = "\n\0$VERSION$"
  105602. + gcmTXT2STR(gcvVERSION_MAJOR) "."
  105603. + gcmTXT2STR(gcvVERSION_MINOR) "."
  105604. + gcmTXT2STR(gcvVERSION_PATCH) ":"
  105605. + gcmTXT2STR(gcvVERSION_BUILD) "$\n";
  105606. +
  105607. +/******************************************************************************\
  105608. +******************************* gckKERNEL API Code ******************************
  105609. +\******************************************************************************/
  105610. +
  105611. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  105612. +#define gcmDEFINE2TEXT(d) #d
  105613. +gctCONST_STRING _DispatchText[] =
  105614. +{
  105615. + gcmDEFINE2TEXT(gcvHAL_QUERY_VIDEO_MEMORY),
  105616. + gcmDEFINE2TEXT(gcvHAL_QUERY_CHIP_IDENTITY),
  105617. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_NON_PAGED_MEMORY),
  105618. + gcmDEFINE2TEXT(gcvHAL_FREE_NON_PAGED_MEMORY),
  105619. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY),
  105620. + gcmDEFINE2TEXT(gcvHAL_FREE_CONTIGUOUS_MEMORY),
  105621. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_VIDEO_MEMORY),
  105622. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY),
  105623. + gcmDEFINE2TEXT(gcvHAL_FREE_VIDEO_MEMORY),
  105624. + gcmDEFINE2TEXT(gcvHAL_MAP_MEMORY),
  105625. + gcmDEFINE2TEXT(gcvHAL_UNMAP_MEMORY),
  105626. + gcmDEFINE2TEXT(gcvHAL_MAP_USER_MEMORY),
  105627. + gcmDEFINE2TEXT(gcvHAL_UNMAP_USER_MEMORY),
  105628. + gcmDEFINE2TEXT(gcvHAL_LOCK_VIDEO_MEMORY),
  105629. + gcmDEFINE2TEXT(gcvHAL_UNLOCK_VIDEO_MEMORY),
  105630. + gcmDEFINE2TEXT(gcvHAL_EVENT_COMMIT),
  105631. + gcmDEFINE2TEXT(gcvHAL_USER_SIGNAL),
  105632. + gcmDEFINE2TEXT(gcvHAL_SIGNAL),
  105633. + gcmDEFINE2TEXT(gcvHAL_WRITE_DATA),
  105634. + gcmDEFINE2TEXT(gcvHAL_COMMIT),
  105635. + gcmDEFINE2TEXT(gcvHAL_STALL),
  105636. + gcmDEFINE2TEXT(gcvHAL_READ_REGISTER),
  105637. + gcmDEFINE2TEXT(gcvHAL_WRITE_REGISTER),
  105638. + gcmDEFINE2TEXT(gcvHAL_GET_PROFILE_SETTING),
  105639. + gcmDEFINE2TEXT(gcvHAL_SET_PROFILE_SETTING),
  105640. + gcmDEFINE2TEXT(gcvHAL_READ_ALL_PROFILE_REGISTERS),
  105641. +#if VIVANTE_PROFILER_PERDRAW
  105642. + gcmDEFINE2TEXT(gcvHAL_READ_PROFILER_REGISTER_SETTING),
  105643. +#endif
  105644. + gcmDEFINE2TEXT(gcvHAL_PROFILE_REGISTERS_2D),
  105645. + gcmDEFINE2TEXT(gcvHAL_SET_POWER_MANAGEMENT_STATE),
  105646. + gcmDEFINE2TEXT(gcvHAL_QUERY_POWER_MANAGEMENT_STATE),
  105647. + gcmDEFINE2TEXT(gcvHAL_GET_BASE_ADDRESS),
  105648. + gcmDEFINE2TEXT(gcvHAL_SET_IDLE),
  105649. + gcmDEFINE2TEXT(gcvHAL_QUERY_KERNEL_SETTINGS),
  105650. + gcmDEFINE2TEXT(gcvHAL_RESET),
  105651. + gcmDEFINE2TEXT(gcvHAL_MAP_PHYSICAL),
  105652. + gcmDEFINE2TEXT(gcvHAL_DEBUG),
  105653. + gcmDEFINE2TEXT(gcvHAL_CACHE),
  105654. + gcmDEFINE2TEXT(gcvHAL_TIMESTAMP),
  105655. + gcmDEFINE2TEXT(gcvHAL_DATABASE),
  105656. + gcmDEFINE2TEXT(gcvHAL_VERSION),
  105657. + gcmDEFINE2TEXT(gcvHAL_CHIP_INFO),
  105658. + gcmDEFINE2TEXT(gcvHAL_ATTACH),
  105659. + gcmDEFINE2TEXT(gcvHAL_DETACH)
  105660. +};
  105661. +#endif
  105662. +
  105663. +#if gcdENABLE_RECOVERY
  105664. +void
  105665. +_ResetFinishFunction(
  105666. + gctPOINTER Data
  105667. + )
  105668. +{
  105669. + gckKERNEL kernel = (gckKERNEL)Data;
  105670. +
  105671. + gckOS_AtomSet(kernel->os, kernel->resetAtom, 0);
  105672. +}
  105673. +#endif
  105674. +
  105675. +/*******************************************************************************
  105676. +**
  105677. +** gckKERNEL_Construct
  105678. +**
  105679. +** Construct a new gckKERNEL object.
  105680. +**
  105681. +** INPUT:
  105682. +**
  105683. +** gckOS Os
  105684. +** Pointer to an gckOS object.
  105685. +**
  105686. +** gceCORE Core
  105687. +** Specified core.
  105688. +**
  105689. +** IN gctPOINTER Context
  105690. +** Pointer to a driver defined context.
  105691. +**
  105692. +** IN gckDB SharedDB,
  105693. +** Pointer to a shared DB.
  105694. +**
  105695. +** OUTPUT:
  105696. +**
  105697. +** gckKERNEL * Kernel
  105698. +** Pointer to a variable that will hold the pointer to the gckKERNEL
  105699. +** object.
  105700. +*/
  105701. +
  105702. +gceSTATUS
  105703. +gckKERNEL_Construct(
  105704. + IN gckOS Os,
  105705. + IN gceCORE Core,
  105706. + IN gctPOINTER Context,
  105707. + IN gckDB SharedDB,
  105708. + OUT gckKERNEL * Kernel
  105709. + )
  105710. +{
  105711. + gckKERNEL kernel = gcvNULL;
  105712. + gceSTATUS status;
  105713. + gctSIZE_T i;
  105714. + gctPOINTER pointer = gcvNULL;
  105715. +
  105716. + gcmkHEADER_ARG("Os=0x%x Context=0x%x", Os, Context);
  105717. +
  105718. + /* Verify the arguments. */
  105719. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  105720. + gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
  105721. +
  105722. + /* Allocate the gckKERNEL object. */
  105723. + gcmkONERROR(gckOS_Allocate(Os,
  105724. + gcmSIZEOF(struct _gckKERNEL),
  105725. + &pointer));
  105726. +
  105727. + kernel = pointer;
  105728. +
  105729. + /* Zero the object pointers. */
  105730. + kernel->hardware = gcvNULL;
  105731. + kernel->command = gcvNULL;
  105732. + kernel->eventObj = gcvNULL;
  105733. + kernel->mmu = gcvNULL;
  105734. +#if gcdDVFS
  105735. + kernel->dvfs = gcvNULL;
  105736. +#endif
  105737. +
  105738. + /* Initialize the gckKERNEL object. */
  105739. + kernel->object.type = gcvOBJ_KERNEL;
  105740. + kernel->os = Os;
  105741. + kernel->core = Core;
  105742. +
  105743. +
  105744. + if (SharedDB == gcvNULL)
  105745. + {
  105746. + gcmkONERROR(gckOS_Allocate(Os,
  105747. + gcmSIZEOF(struct _gckDB),
  105748. + &pointer));
  105749. +
  105750. + kernel->db = pointer;
  105751. + kernel->dbCreated = gcvTRUE;
  105752. + kernel->db->freeDatabase = gcvNULL;
  105753. + kernel->db->freeRecord = gcvNULL;
  105754. + kernel->db->dbMutex = gcvNULL;
  105755. + kernel->db->lastDatabase = gcvNULL;
  105756. + kernel->db->idleTime = 0;
  105757. + kernel->db->lastIdle = 0;
  105758. + kernel->db->lastSlowdown = 0;
  105759. +
  105760. + for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
  105761. + {
  105762. + kernel->db->db[i] = gcvNULL;
  105763. + }
  105764. +
  105765. + /* Construct a database mutex. */
  105766. + gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->dbMutex));
  105767. +
  105768. + /* Construct a id-pointer database. */
  105769. + gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->pointerDatabase));
  105770. +
  105771. + /* Construct a id-pointer database mutex. */
  105772. + gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->pointerDatabaseMutex));
  105773. + }
  105774. + else
  105775. + {
  105776. + kernel->db = SharedDB;
  105777. + kernel->dbCreated = gcvFALSE;
  105778. + }
  105779. +
  105780. + for (i = 0; i < gcmCOUNTOF(kernel->timers); ++i)
  105781. + {
  105782. + kernel->timers[i].startTime = 0;
  105783. + kernel->timers[i].stopTime = 0;
  105784. + }
  105785. +
  105786. + kernel->timeOut = gcdGPU_TIMEOUT;
  105787. +
  105788. + /* Save context. */
  105789. + kernel->context = Context;
  105790. +
  105791. +#if gcdVIRTUAL_COMMAND_BUFFER
  105792. + kernel->virtualBufferHead =
  105793. + kernel->virtualBufferTail = gcvNULL;
  105794. +
  105795. + gcmkONERROR(
  105796. + gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock));
  105797. +#endif
  105798. +
  105799. + /* Construct atom holding number of clients. */
  105800. + kernel->atomClients = gcvNULL;
  105801. + gcmkONERROR(gckOS_AtomConstruct(Os, &kernel->atomClients));
  105802. +
  105803. +#if gcdENABLE_VG
  105804. + kernel->vg = gcvNULL;
  105805. +
  105806. + if (Core == gcvCORE_VG)
  105807. + {
  105808. + /* Construct the gckMMU object. */
  105809. + gcmkONERROR(
  105810. + gckVGKERNEL_Construct(Os, Context, kernel, &kernel->vg));
  105811. + }
  105812. + else
  105813. +#endif
  105814. + {
  105815. + /* Construct the gckHARDWARE object. */
  105816. + gcmkONERROR(
  105817. + gckHARDWARE_Construct(Os, kernel->core, &kernel->hardware));
  105818. +
  105819. + /* Set pointer to gckKERNEL object in gckHARDWARE object. */
  105820. + kernel->hardware->kernel = kernel;
  105821. +
  105822. + /* Initialize the hardware. */
  105823. + gcmkONERROR(
  105824. + gckHARDWARE_InitializeHardware(kernel->hardware));
  105825. +
  105826. + /* Construct the gckCOMMAND object. */
  105827. + gcmkONERROR(
  105828. + gckCOMMAND_Construct(kernel, &kernel->command));
  105829. +
  105830. + /* Construct the gckEVENT object. */
  105831. + gcmkONERROR(
  105832. + gckEVENT_Construct(kernel, &kernel->eventObj));
  105833. +
  105834. + /* Construct the gckMMU object. */
  105835. + gcmkONERROR(
  105836. + gckMMU_Construct(kernel, gcdMMU_SIZE, &kernel->mmu));
  105837. +
  105838. +#if gcdENABLE_RECOVERY
  105839. + gcmkONERROR(
  105840. + gckOS_AtomConstruct(Os, &kernel->resetAtom));
  105841. +
  105842. + gcmkVERIFY_OK(
  105843. + gckOS_CreateTimer(Os,
  105844. + (gctTIMERFUNCTION)_ResetFinishFunction,
  105845. + (gctPOINTER)kernel,
  105846. + &kernel->resetFlagClearTimer));
  105847. + kernel->resetTimeStamp = 0;
  105848. +#endif
  105849. +
  105850. +#if gcdDVFS
  105851. + if (gckHARDWARE_IsFeatureAvailable(kernel->hardware,
  105852. + gcvFEATURE_DYNAMIC_FREQUENCY_SCALING))
  105853. + {
  105854. + gcmkONERROR(gckDVFS_Construct(kernel->hardware, &kernel->dvfs));
  105855. + gcmkONERROR(gckDVFS_Start(kernel->dvfs));
  105856. + }
  105857. +#endif
  105858. + }
  105859. +
  105860. + spin_lock_init(&kernel->irq_lock);
  105861. +
  105862. +#if VIVANTE_PROFILER
  105863. + /* Initialize profile setting */
  105864. + kernel->profileEnable = gcvFALSE;
  105865. + kernel->profileCleanRegister = gcvTRUE;
  105866. +#endif
  105867. +
  105868. +#if gcdANDROID_NATIVE_FENCE_SYNC
  105869. + gcmkONERROR(gckOS_CreateSyncTimeline(Os, &kernel->timeline));
  105870. +#endif
  105871. +
  105872. + /* Return pointer to the gckKERNEL object. */
  105873. + *Kernel = kernel;
  105874. +
  105875. + /* Success. */
  105876. + gcmkFOOTER_ARG("*Kernel=0x%x", *Kernel);
  105877. + return gcvSTATUS_OK;
  105878. +
  105879. +OnError:
  105880. + if (kernel != gcvNULL)
  105881. + {
  105882. +#if gcdENABLE_VG
  105883. + if (Core != gcvCORE_VG)
  105884. +#endif
  105885. + {
  105886. + if (kernel->eventObj != gcvNULL)
  105887. + {
  105888. + gcmkVERIFY_OK(gckEVENT_Destroy(kernel->eventObj));
  105889. + }
  105890. +
  105891. + if (kernel->command != gcvNULL)
  105892. + {
  105893. + gcmkVERIFY_OK(gckCOMMAND_Destroy(kernel->command));
  105894. + }
  105895. +
  105896. + if (kernel->hardware != gcvNULL)
  105897. + {
  105898. + /* Turn off the power. */
  105899. + gcmkVERIFY_OK(gckOS_SetGPUPower(kernel->hardware->os,
  105900. + kernel->hardware->core,
  105901. + gcvFALSE,
  105902. + gcvFALSE));
  105903. + gcmkVERIFY_OK(gckHARDWARE_Destroy(kernel->hardware));
  105904. + }
  105905. + }
  105906. +
  105907. + if (kernel->atomClients != gcvNULL)
  105908. + {
  105909. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->atomClients));
  105910. + }
  105911. +
  105912. +#if gcdENABLE_RECOVERY
  105913. + if (kernel->resetAtom != gcvNULL)
  105914. + {
  105915. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->resetAtom));
  105916. + }
  105917. +
  105918. + if (kernel->resetFlagClearTimer)
  105919. + {
  105920. + gcmkVERIFY_OK(gckOS_StopTimer(Os, kernel->resetFlagClearTimer));
  105921. + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, kernel->resetFlagClearTimer));
  105922. + }
  105923. +#endif
  105924. +
  105925. + if (kernel->dbCreated && kernel->db != gcvNULL)
  105926. + {
  105927. + if (kernel->db->dbMutex != gcvNULL)
  105928. + {
  105929. + /* Destroy the database mutex. */
  105930. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, kernel->db->dbMutex));
  105931. + }
  105932. +
  105933. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel->db));
  105934. + }
  105935. +
  105936. +#if gcdVIRTUAL_COMMAND_BUFFER
  105937. + if (kernel->virtualBufferLock != gcvNULL)
  105938. + {
  105939. + /* Destroy the virtual command buffer mutex. */
  105940. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, kernel->virtualBufferLock));
  105941. + }
  105942. +#endif
  105943. +
  105944. +#if gcdDVFS
  105945. + if (kernel->dvfs)
  105946. + {
  105947. + gcmkVERIFY_OK(gckDVFS_Stop(kernel->dvfs));
  105948. + gcmkVERIFY_OK(gckDVFS_Destroy(kernel->dvfs));
  105949. + }
  105950. +#endif
  105951. +
  105952. +#if gcdANDROID_NATIVE_FENCE_SYNC
  105953. + if (kernel->timeline)
  105954. + {
  105955. + gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Os, kernel->timeline));
  105956. + }
  105957. +#endif
  105958. +
  105959. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel));
  105960. + }
  105961. +
  105962. + /* Return the error. */
  105963. + gcmkFOOTER();
  105964. + return status;
  105965. +}
  105966. +
  105967. +/*******************************************************************************
  105968. +**
  105969. +** gckKERNEL_Destroy
  105970. +**
  105971. +** Destroy an gckKERNEL object.
  105972. +**
  105973. +** INPUT:
  105974. +**
  105975. +** gckKERNEL Kernel
  105976. +** Pointer to an gckKERNEL object to destroy.
  105977. +**
  105978. +** OUTPUT:
  105979. +**
  105980. +** Nothing.
  105981. +*/
  105982. +gceSTATUS
  105983. +gckKERNEL_Destroy(
  105984. + IN gckKERNEL Kernel
  105985. + )
  105986. +{
  105987. + gctSIZE_T i;
  105988. + gcsDATABASE_PTR database, databaseNext;
  105989. + gcsDATABASE_RECORD_PTR record, recordNext;
  105990. +
  105991. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  105992. +
  105993. + /* Verify the arguments. */
  105994. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  105995. +#if QNX_SINGLE_THREADED_DEBUGGING
  105996. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->debugMutex));
  105997. +#endif
  105998. +
  105999. + /* Destroy the database. */
  106000. + if (Kernel->dbCreated)
  106001. + {
  106002. + for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
  106003. + {
  106004. + if (Kernel->db->db[i] != gcvNULL)
  106005. + {
  106006. + gcmkVERIFY_OK(
  106007. + gckKERNEL_DestroyProcessDB(Kernel, Kernel->db->db[i]->processID));
  106008. + }
  106009. + }
  106010. +
  106011. + /* Free all databases. */
  106012. + for (database = Kernel->db->freeDatabase;
  106013. + database != gcvNULL;
  106014. + database = databaseNext)
  106015. + {
  106016. + databaseNext = database->next;
  106017. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, database));
  106018. + }
  106019. +
  106020. + if (Kernel->db->lastDatabase != gcvNULL)
  106021. + {
  106022. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db->lastDatabase));
  106023. + }
  106024. +
  106025. + /* Free all database records. */
  106026. + for (record = Kernel->db->freeRecord; record != gcvNULL; record = recordNext)
  106027. + {
  106028. + recordNext = record->next;
  106029. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, record));
  106030. + }
  106031. +
  106032. + /* Destroy the database mutex. */
  106033. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->dbMutex));
  106034. +
  106035. +
  106036. + /* Destroy id-pointer database. */
  106037. + gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Kernel->db->pointerDatabase));
  106038. +
  106039. + /* Destroy id-pointer database mutex. */
  106040. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
  106041. + }
  106042. +
  106043. +#if gcdENABLE_VG
  106044. + if (Kernel->vg)
  106045. + {
  106046. + gcmkVERIFY_OK(gckVGKERNEL_Destroy(Kernel->vg));
  106047. + }
  106048. + else
  106049. +#endif
  106050. + {
  106051. + /* Destroy the gckMMU object. */
  106052. + gcmkVERIFY_OK(gckMMU_Destroy(Kernel->mmu));
  106053. +
  106054. + /* Destroy the gckCOMMNAND object. */
  106055. + gcmkVERIFY_OK(gckCOMMAND_Destroy(Kernel->command));
  106056. +
  106057. + /* Destroy the gckEVENT object. */
  106058. + gcmkVERIFY_OK(gckEVENT_Destroy(Kernel->eventObj));
  106059. +
  106060. + /* Destroy the gckHARDWARE object. */
  106061. + gcmkVERIFY_OK(gckHARDWARE_Destroy(Kernel->hardware));
  106062. +
  106063. +#if gcdENABLE_RECOVERY
  106064. + gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->resetAtom));
  106065. +
  106066. + if (Kernel->resetFlagClearTimer)
  106067. + {
  106068. + gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->resetFlagClearTimer));
  106069. + gcmkVERIFY_OK(gckOS_DestroyTimer(Kernel->os, Kernel->resetFlagClearTimer));
  106070. + }
  106071. +#endif
  106072. + }
  106073. +
  106074. + /* Detsroy the client atom. */
  106075. + gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->atomClients));
  106076. +
  106077. +#if gcdVIRTUAL_COMMAND_BUFFER
  106078. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->virtualBufferLock));
  106079. +#endif
  106080. +
  106081. +#if gcdDVFS
  106082. + if (Kernel->dvfs)
  106083. + {
  106084. + gcmkVERIFY_OK(gckDVFS_Stop(Kernel->dvfs));
  106085. + gcmkVERIFY_OK(gckDVFS_Destroy(Kernel->dvfs));
  106086. + }
  106087. +#endif
  106088. +
  106089. +#if gcdANDROID_NATIVE_FENCE_SYNC
  106090. + gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Kernel->os, Kernel->timeline));
  106091. +#endif
  106092. +
  106093. + /* Mark the gckKERNEL object as unknown. */
  106094. + Kernel->object.type = gcvOBJ_UNKNOWN;
  106095. +
  106096. + /* Free the gckKERNEL object. */
  106097. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel));
  106098. +
  106099. + /* Success. */
  106100. + gcmkFOOTER_NO();
  106101. + return gcvSTATUS_OK;
  106102. +}
  106103. +
  106104. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  106105. +#include <linux/kernel.h>
  106106. +#include <linux/mm.h>
  106107. +#include <linux/oom.h>
  106108. +#include <linux/sched.h>
  106109. +#include <linux/notifier.h>
  106110. +
  106111. +extern struct task_struct *lowmem_deathpending;
  106112. +static unsigned long lowmem_deathpending_timeout;
  106113. +
  106114. +static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel)
  106115. +{
  106116. + struct task_struct *p;
  106117. + struct task_struct *selected = NULL;
  106118. + int tasksize;
  106119. + int ret = -1;
  106120. + int min_adj = 0;
  106121. + int selected_tasksize = 0;
  106122. + int selected_oom_adj;
  106123. + /*
  106124. + * If we already have a death outstanding, then
  106125. + * bail out right away; indicating to vmscan
  106126. + * that we have nothing further to offer on
  106127. + * this pass.
  106128. + *
  106129. + */
  106130. + if (lowmem_deathpending &&
  106131. + time_before_eq(jiffies, lowmem_deathpending_timeout))
  106132. + return 0;
  106133. + selected_oom_adj = min_adj;
  106134. +
  106135. + read_lock(&tasklist_lock);
  106136. + for_each_process(p) {
  106137. + struct mm_struct *mm;
  106138. + struct signal_struct *sig;
  106139. + gcuDATABASE_INFO info;
  106140. + int oom_adj;
  106141. +
  106142. + task_lock(p);
  106143. + mm = p->mm;
  106144. + sig = p->signal;
  106145. + if (!mm || !sig) {
  106146. + task_unlock(p);
  106147. + continue;
  106148. + }
  106149. + oom_adj = sig->oom_adj;
  106150. + if (oom_adj < min_adj) {
  106151. + task_unlock(p);
  106152. + continue;
  106153. + }
  106154. +
  106155. + tasksize = 0;
  106156. + if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK){
  106157. + tasksize += info.counters.bytes / PAGE_SIZE;
  106158. + }
  106159. + if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_CONTIGUOUS, &info) == gcvSTATUS_OK){
  106160. + tasksize += info.counters.bytes / PAGE_SIZE;
  106161. + }
  106162. +
  106163. + task_unlock(p);
  106164. +
  106165. + if (tasksize <= 0)
  106166. + continue;
  106167. +
  106168. + gckOS_Print("<gpu> pid %d (%s), adj %d, size %d \n", p->pid, p->comm, oom_adj, tasksize);
  106169. +
  106170. + if (selected) {
  106171. + if (oom_adj < selected_oom_adj)
  106172. + continue;
  106173. + if (oom_adj == selected_oom_adj &&
  106174. + tasksize <= selected_tasksize)
  106175. + continue;
  106176. + }
  106177. + selected = p;
  106178. + selected_tasksize = tasksize;
  106179. + selected_oom_adj = oom_adj;
  106180. + }
  106181. + if (selected) {
  106182. + gckOS_Print("<gpu> send sigkill to %d (%s), adj %d, size %d\n",
  106183. + selected->pid, selected->comm,
  106184. + selected_oom_adj, selected_tasksize);
  106185. + lowmem_deathpending = selected;
  106186. + lowmem_deathpending_timeout = jiffies + HZ;
  106187. + force_sig(SIGKILL, selected);
  106188. + ret = 0;
  106189. + }
  106190. + read_unlock(&tasklist_lock);
  106191. + return ret;
  106192. +}
  106193. +
  106194. +#endif
  106195. +
  106196. +/*******************************************************************************
  106197. +**
  106198. +** _AllocateMemory
  106199. +**
  106200. +** Private function to walk all required memory pools to allocate the requested
  106201. +** amount of video memory.
  106202. +**
  106203. +** INPUT:
  106204. +**
  106205. +** gckKERNEL Kernel
  106206. +** Pointer to an gckKERNEL object.
  106207. +**
  106208. +** gcsHAL_INTERFACE * Interface
  106209. +** Pointer to a gcsHAL_INTERFACE structure that defines the command to
  106210. +** be dispatched.
  106211. +**
  106212. +** OUTPUT:
  106213. +**
  106214. +** gcsHAL_INTERFACE * Interface
  106215. +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
  106216. +** returned.
  106217. +*/
  106218. +static gceSTATUS
  106219. +_AllocateMemory(
  106220. + IN gckKERNEL Kernel,
  106221. + IN OUT gcePOOL * Pool,
  106222. + IN gctSIZE_T Bytes,
  106223. + IN gctSIZE_T Alignment,
  106224. + IN gceSURF_TYPE Type,
  106225. + OUT gcuVIDMEM_NODE_PTR * Node
  106226. + )
  106227. +{
  106228. + gcePOOL pool;
  106229. + gceSTATUS status;
  106230. + gckVIDMEM videoMemory;
  106231. + gctINT loopCount;
  106232. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  106233. + gctBOOL tileStatusInVirtual;
  106234. + gctBOOL forceContiguous = gcvFALSE;
  106235. +
  106236. + gcmkHEADER_ARG("Kernel=0x%x *Pool=%d Bytes=%lu Alignment=%lu Type=%d",
  106237. + Kernel, *Pool, Bytes, Alignment, Type);
  106238. +
  106239. + gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
  106240. + gcmkVERIFY_ARGUMENT(Bytes != 0);
  106241. +
  106242. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  106243. +_AllocateMemory_Retry:
  106244. +#endif
  106245. + /* Get initial pool. */
  106246. + switch (pool = *Pool)
  106247. + {
  106248. + case gcvPOOL_DEFAULT_FORCE_CONTIGUOUS:
  106249. + forceContiguous = gcvTRUE;
  106250. + case gcvPOOL_DEFAULT:
  106251. + case gcvPOOL_LOCAL:
  106252. + pool = gcvPOOL_LOCAL_INTERNAL;
  106253. + loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
  106254. + break;
  106255. +
  106256. + case gcvPOOL_UNIFIED:
  106257. + pool = gcvPOOL_SYSTEM;
  106258. + loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
  106259. + break;
  106260. +
  106261. + case gcvPOOL_CONTIGUOUS:
  106262. + loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
  106263. + break;
  106264. +
  106265. + case gcvPOOL_DEFAULT_FORCE_CONTIGUOUS_CACHEABLE:
  106266. + pool = gcvPOOL_CONTIGUOUS;
  106267. + loopCount = 1;
  106268. + forceContiguous = gcvTRUE;
  106269. + break;
  106270. +
  106271. + default:
  106272. + loopCount = 1;
  106273. + break;
  106274. + }
  106275. +
  106276. + while (loopCount-- > 0)
  106277. + {
  106278. + if (pool == gcvPOOL_VIRTUAL)
  106279. + {
  106280. + /* Create a gcuVIDMEM_NODE for virtual memory. */
  106281. + gcmkONERROR(
  106282. + gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, &node));
  106283. +
  106284. + /* Success. */
  106285. + break;
  106286. + }
  106287. +
  106288. + else
  106289. + if (pool == gcvPOOL_CONTIGUOUS)
  106290. + {
  106291. +#if gcdCONTIGUOUS_SIZE_LIMIT
  106292. + if (Bytes > gcdCONTIGUOUS_SIZE_LIMIT && forceContiguous == gcvFALSE)
  106293. + {
  106294. + status = gcvSTATUS_OUT_OF_MEMORY;
  106295. + }
  106296. + else
  106297. +#endif
  106298. + {
  106299. + /* Create a gcuVIDMEM_NODE from contiguous memory. */
  106300. + status = gckVIDMEM_ConstructVirtual(Kernel, gcvTRUE, Bytes, &node);
  106301. + }
  106302. +
  106303. + if (gcmIS_SUCCESS(status) || forceContiguous == gcvTRUE)
  106304. + {
  106305. + /* Memory allocated. */
  106306. + if(node && forceContiguous == gcvTRUE)
  106307. + {
  106308. + gctUINT32 physAddr=0;
  106309. + gctUINT32 baseAddress = 0;
  106310. +
  106311. + gcmkONERROR(
  106312. + gckOS_LockPages(Kernel->os,
  106313. + node->Virtual.physical,
  106314. + node->Virtual.bytes,
  106315. + gcvFALSE,
  106316. + &node->Virtual.logical,
  106317. + &node->Virtual.pageCount));
  106318. +
  106319. + /* Convert logical address into a physical address. */
  106320. + gcmkONERROR(
  106321. + gckOS_GetPhysicalAddress(Kernel->os,
  106322. + node->Virtual.logical,
  106323. + &physAddr));
  106324. +
  106325. + gcmkONERROR(
  106326. + gckOS_UnlockPages(Kernel->os,
  106327. + node->Virtual.physical,
  106328. + node->Virtual.bytes,
  106329. + node->Virtual.logical));
  106330. +
  106331. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  106332. +
  106333. + gcmkASSERT(physAddr >= baseAddress);
  106334. +
  106335. + /* Subtract baseAddress to get a GPU address used for programming. */
  106336. + physAddr -= baseAddress;
  106337. +
  106338. + if((physAddr & 0x80000000) || ((physAddr + Bytes) & 0x80000000))
  106339. + {
  106340. + gckOS_Print("gpu virtual memory 0x%x cannot be allocated in force contiguous request!\n", physAddr);
  106341. +
  106342. + gcmkONERROR(gckVIDMEM_Free(node));
  106343. +
  106344. + node = gcvNULL;
  106345. + }
  106346. + }
  106347. +
  106348. + break;
  106349. + }
  106350. + }
  106351. +
  106352. + else
  106353. + {
  106354. + /* Get pointer to gckVIDMEM object for pool. */
  106355. +#if gcdUSE_VIDMEM_PER_PID
  106356. + gctUINT32 pid;
  106357. + gckOS_GetProcessID(&pid);
  106358. +
  106359. + status = gckKERNEL_GetVideoMemoryPoolPid(Kernel, pool, pid, &videoMemory);
  106360. + if (status == gcvSTATUS_NOT_FOUND)
  106361. + {
  106362. + /* Create VidMem pool for this process. */
  106363. + status = gckKERNEL_CreateVideoMemoryPoolPid(Kernel, pool, pid, &videoMemory);
  106364. + }
  106365. +#else
  106366. + status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory);
  106367. +#endif
  106368. +
  106369. + if (gcmIS_SUCCESS(status))
  106370. + {
  106371. + /* Allocate memory. */
  106372. + status = gckVIDMEM_AllocateLinear(videoMemory,
  106373. + Bytes,
  106374. + Alignment,
  106375. + Type,
  106376. + &node);
  106377. +
  106378. + if (gcmIS_SUCCESS(status))
  106379. + {
  106380. + /* Memory allocated. */
  106381. + node->VidMem.pool = pool;
  106382. + break;
  106383. + }
  106384. + }
  106385. + }
  106386. +
  106387. + if (pool == gcvPOOL_LOCAL_INTERNAL)
  106388. + {
  106389. + /* Advance to external memory. */
  106390. + pool = gcvPOOL_LOCAL_EXTERNAL;
  106391. + }
  106392. +
  106393. + else
  106394. + if (pool == gcvPOOL_LOCAL_EXTERNAL)
  106395. + {
  106396. + /* Advance to contiguous system memory. */
  106397. + pool = gcvPOOL_SYSTEM;
  106398. + }
  106399. +
  106400. + else
  106401. + if (pool == gcvPOOL_SYSTEM)
  106402. + {
  106403. + /* Advance to contiguous memory. */
  106404. + pool = gcvPOOL_CONTIGUOUS;
  106405. + }
  106406. +
  106407. + else
  106408. + if (pool == gcvPOOL_CONTIGUOUS)
  106409. + {
  106410. + tileStatusInVirtual =
  106411. + gckHARDWARE_IsFeatureAvailable(Kernel->hardware,
  106412. + gcvFEATURE_MC20);
  106413. +
  106414. + if (Type == gcvSURF_TILE_STATUS && tileStatusInVirtual != gcvTRUE)
  106415. + {
  106416. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  106417. + }
  106418. +
  106419. + /* Advance to virtual memory. */
  106420. + pool = gcvPOOL_VIRTUAL;
  106421. + }
  106422. +
  106423. + else
  106424. + {
  106425. + /* Out of pools. */
  106426. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  106427. + }
  106428. + }
  106429. +
  106430. + if (node == gcvNULL)
  106431. + {
  106432. +
  106433. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  106434. + if(forceContiguous == gcvTRUE)
  106435. + {
  106436. + if(force_contiguous_lowmem_shrink(Kernel) == 0)
  106437. + {
  106438. + /* Sleep 1 millisecond. */
  106439. + gckOS_Delay(gcvNULL, 1);
  106440. + goto _AllocateMemory_Retry;
  106441. + }
  106442. + }
  106443. +#endif
  106444. + /* Nothing allocated. */
  106445. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  106446. + }
  106447. +
  106448. + /* Return node and pool used for allocation. */
  106449. + *Node = node;
  106450. + *Pool = pool;
  106451. +
  106452. + /* Return status. */
  106453. + gcmkFOOTER_ARG("*Pool=%d *Node=0x%x", *Pool, *Node);
  106454. + return gcvSTATUS_OK;
  106455. +
  106456. +OnError:
  106457. + /* Return the status. */
  106458. + gcmkFOOTER();
  106459. + return status;
  106460. +}
  106461. +
  106462. +/*******************************************************************************
  106463. +**
  106464. +** gckKERNEL_Dispatch
  106465. +**
  106466. +** Dispatch a command received from the user HAL layer.
  106467. +**
  106468. +** INPUT:
  106469. +**
  106470. +** gckKERNEL Kernel
  106471. +** Pointer to an gckKERNEL object.
  106472. +**
  106473. +** gctBOOL FromUser
  106474. +** whether the call is from the user space.
  106475. +**
  106476. +** gcsHAL_INTERFACE * Interface
  106477. +** Pointer to a gcsHAL_INTERFACE structure that defines the command to
  106478. +** be dispatched.
  106479. +**
  106480. +** OUTPUT:
  106481. +**
  106482. +** gcsHAL_INTERFACE * Interface
  106483. +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
  106484. +** returned.
  106485. +*/
  106486. +
  106487. +gceSTATUS
  106488. +gckKERNEL_Dispatch(
  106489. + IN gckKERNEL Kernel,
  106490. + IN gctBOOL FromUser,
  106491. + IN OUT gcsHAL_INTERFACE * Interface
  106492. + )
  106493. +{
  106494. + gceSTATUS status = gcvSTATUS_OK;
  106495. + gctSIZE_T bytes;
  106496. + gcuVIDMEM_NODE_PTR node;
  106497. + gctBOOL locked = gcvFALSE;
  106498. + gctPHYS_ADDR physical = gcvNULL;
  106499. + gctPOINTER logical = gcvNULL;
  106500. + gctPOINTER info = gcvNULL;
  106501. + gckCONTEXT context = gcvNULL;
  106502. + gctUINT32 address;
  106503. + gctUINT32 processID;
  106504. + gckKERNEL kernel = Kernel;
  106505. +#if gcdSECURE_USER
  106506. + gcskSECURE_CACHE_PTR cache;
  106507. +#endif
  106508. + gctBOOL asynchronous;
  106509. + gctPOINTER paddr = gcvNULL;
  106510. +#if !USE_NEW_LINUX_SIGNAL
  106511. + gctSIGNAL signal;
  106512. +#endif
  106513. + gceSURF_TYPE type;
  106514. +
  106515. + gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x",
  106516. + Kernel, FromUser, Interface);
  106517. +
  106518. + /* Verify the arguments. */
  106519. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  106520. + gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
  106521. +
  106522. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  106523. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  106524. + "Dispatching command %d (%s)",
  106525. + Interface->command, _DispatchText[Interface->command]);
  106526. +#endif
  106527. +#if QNX_SINGLE_THREADED_DEBUGGING
  106528. + gckOS_AcquireMutex(Kernel->os, Kernel->debugMutex, gcvINFINITE);
  106529. +#endif
  106530. +
  106531. + /* Get the current process ID. */
  106532. + gcmkONERROR(gckOS_GetProcessID(&processID));
  106533. +
  106534. +#if gcdSECURE_USER
  106535. + gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
  106536. +#endif
  106537. +
  106538. + /* Dispatch on command. */
  106539. + switch (Interface->command)
  106540. + {
  106541. + case gcvHAL_GET_BASE_ADDRESS:
  106542. + /* Get base address. */
  106543. + gcmkONERROR(
  106544. + gckOS_GetBaseAddress(Kernel->os,
  106545. + &Interface->u.GetBaseAddress.baseAddress));
  106546. + break;
  106547. +
  106548. + case gcvHAL_QUERY_VIDEO_MEMORY:
  106549. + /* Query video memory size. */
  106550. + gcmkONERROR(gckKERNEL_QueryVideoMemory(Kernel, Interface));
  106551. + break;
  106552. +
  106553. + case gcvHAL_QUERY_CHIP_IDENTITY:
  106554. + /* Query chip identity. */
  106555. + gcmkONERROR(
  106556. + gckHARDWARE_QueryChipIdentity(
  106557. + Kernel->hardware,
  106558. + &Interface->u.QueryChipIdentity));
  106559. + break;
  106560. +
  106561. + case gcvHAL_MAP_MEMORY:
  106562. + physical = gcmINT2PTR(Interface->u.MapMemory.physical);
  106563. +
  106564. + /* Map memory. */
  106565. + gcmkONERROR(
  106566. + gckKERNEL_MapMemory(Kernel,
  106567. + physical,
  106568. + (gctSIZE_T) Interface->u.MapMemory.bytes,
  106569. + &logical));
  106570. +
  106571. + Interface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
  106572. +
  106573. + gcmkVERIFY_OK(
  106574. + gckKERNEL_AddProcessDB(Kernel,
  106575. + processID, gcvDB_MAP_MEMORY,
  106576. + logical,
  106577. + physical,
  106578. + (gctSIZE_T) Interface->u.MapMemory.bytes));
  106579. + break;
  106580. +
  106581. + case gcvHAL_UNMAP_MEMORY:
  106582. + physical = gcmINT2PTR(Interface->u.UnmapMemory.physical);
  106583. +
  106584. + /* Unmap memory. */
  106585. + gcmkONERROR(
  106586. + gckKERNEL_UnmapMemory(Kernel,
  106587. + physical,
  106588. + (gctSIZE_T) Interface->u.UnmapMemory.bytes,
  106589. + gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical)));
  106590. + gcmkVERIFY_OK(
  106591. + gckKERNEL_RemoveProcessDB(Kernel,
  106592. + processID, gcvDB_MAP_MEMORY,
  106593. + gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical)));
  106594. + break;
  106595. +
  106596. + case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
  106597. + bytes = (gctSIZE_T) Interface->u.AllocateNonPagedMemory.bytes;
  106598. +
  106599. + /* Allocate non-paged memory. */
  106600. + gcmkONERROR(
  106601. + gckOS_AllocateNonPagedMemory(
  106602. + Kernel->os,
  106603. + FromUser,
  106604. + &bytes,
  106605. + &physical,
  106606. + &logical));
  106607. +
  106608. + Interface->u.AllocateNonPagedMemory.bytes = bytes;
  106609. + Interface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
  106610. + Interface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
  106611. +
  106612. + gcmkVERIFY_OK(
  106613. + gckKERNEL_AddProcessDB(Kernel,
  106614. + processID, gcvDB_NON_PAGED,
  106615. + logical,
  106616. + gcmINT2PTR(Interface->u.AllocateNonPagedMemory.physical),
  106617. + bytes));
  106618. +
  106619. + break;
  106620. +
  106621. + case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER:
  106622. +#if gcdVIRTUAL_COMMAND_BUFFER
  106623. + bytes = (gctSIZE_T) Interface->u.AllocateVirtualCommandBuffer.bytes;
  106624. +
  106625. + gcmkONERROR(
  106626. + gckKERNEL_AllocateVirtualCommandBuffer(
  106627. + Kernel,
  106628. + FromUser,
  106629. + &bytes,
  106630. + &physical,
  106631. + &logical));
  106632. +
  106633. + Interface->u.AllocateVirtualCommandBuffer.bytes = bytes;
  106634. + Interface->u.AllocateVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(logical);
  106635. + Interface->u.AllocateVirtualCommandBuffer.physical = gcmPTR_TO_NAME(physical);
  106636. +
  106637. + gcmkVERIFY_OK(
  106638. + gckKERNEL_AddProcessDB(Kernel,
  106639. + processID, gcvDB_COMMAND_BUFFER,
  106640. + logical,
  106641. + gcmINT2PTR(Interface->u.AllocateVirtualCommandBuffer.physical),
  106642. + bytes));
  106643. +#else
  106644. + status = gcvSTATUS_NOT_SUPPORTED;
  106645. +#endif
  106646. + break;
  106647. +
  106648. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  106649. + physical = gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical);
  106650. +
  106651. + /* Unmap user logical out of physical memory first. */
  106652. + gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
  106653. + physical,
  106654. + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
  106655. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  106656. +
  106657. + /* Free non-paged memory. */
  106658. + gcmkONERROR(
  106659. + gckOS_FreeNonPagedMemory(Kernel->os,
  106660. + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
  106661. + physical,
  106662. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  106663. +
  106664. + gcmkVERIFY_OK(
  106665. + gckKERNEL_RemoveProcessDB(Kernel,
  106666. + processID, gcvDB_NON_PAGED,
  106667. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  106668. +
  106669. +#if gcdSECURE_USER
  106670. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  106671. + Kernel,
  106672. + cache,
  106673. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical),
  106674. + Interface->u.FreeNonPagedMemory.bytes));
  106675. +#endif
  106676. +
  106677. + gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physical);
  106678. +
  106679. + break;
  106680. +
  106681. + case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
  106682. + bytes = (gctSIZE_T) Interface->u.AllocateContiguousMemory.bytes;
  106683. +
  106684. + /* Allocate contiguous memory. */
  106685. + gcmkONERROR(gckOS_AllocateContiguous(
  106686. + Kernel->os,
  106687. + FromUser,
  106688. + &bytes,
  106689. + &physical,
  106690. + &logical));
  106691. +
  106692. + Interface->u.AllocateContiguousMemory.bytes = bytes;
  106693. + Interface->u.AllocateContiguousMemory.logical = gcmPTR_TO_UINT64(logical);
  106694. + Interface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical);
  106695. +
  106696. + gcmkONERROR(gckHARDWARE_ConvertLogical(
  106697. + Kernel->hardware,
  106698. + gcmUINT64_TO_PTR(Interface->u.AllocateContiguousMemory.logical),
  106699. + &Interface->u.AllocateContiguousMemory.address));
  106700. +
  106701. + gcmkVERIFY_OK(gckKERNEL_AddProcessDB(
  106702. + Kernel,
  106703. + processID, gcvDB_CONTIGUOUS,
  106704. + logical,
  106705. + gcmINT2PTR(Interface->u.AllocateContiguousMemory.physical),
  106706. + bytes));
  106707. +
  106708. + break;
  106709. +
  106710. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  106711. + physical = gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical);
  106712. +
  106713. + /* Unmap user logical out of physical memory first. */
  106714. + gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
  106715. + physical,
  106716. + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
  106717. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
  106718. +
  106719. + /* Free contiguous memory. */
  106720. + gcmkONERROR(
  106721. + gckOS_FreeContiguous(Kernel->os,
  106722. + physical,
  106723. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
  106724. + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes));
  106725. +
  106726. + gcmkVERIFY_OK(
  106727. + gckKERNEL_RemoveProcessDB(Kernel,
  106728. + processID, gcvDB_CONTIGUOUS,
  106729. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  106730. +
  106731. +#if gcdSECURE_USER
  106732. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  106733. + Kernel,
  106734. + cache,
  106735. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
  106736. + Interface->u.FreeContiguousMemory.bytes));
  106737. +#endif
  106738. +
  106739. + gcmRELEASE_NAME(Interface->u.FreeContiguousMemory.physical);
  106740. +
  106741. + break;
  106742. +
  106743. + case gcvHAL_ALLOCATE_VIDEO_MEMORY:
  106744. +
  106745. + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
  106746. +
  106747. + break;
  106748. +
  106749. + case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
  106750. + type = Interface->u.AllocateLinearVideoMemory.type;
  106751. +
  106752. + /* Allocate memory. */
  106753. + gcmkONERROR(
  106754. + _AllocateMemory(Kernel,
  106755. + &Interface->u.AllocateLinearVideoMemory.pool,
  106756. + Interface->u.AllocateLinearVideoMemory.bytes,
  106757. + Interface->u.AllocateLinearVideoMemory.alignment,
  106758. + Interface->u.AllocateLinearVideoMemory.type,
  106759. + &node));
  106760. +
  106761. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  106762. + {
  106763. + bytes = node->VidMem.bytes;
  106764. + node->VidMem.type = type;
  106765. +
  106766. + gcmkONERROR(
  106767. + gckKERNEL_AddProcessDB(Kernel,
  106768. + processID, gcvDB_VIDEO_MEMORY_RESERVED,
  106769. + node,
  106770. + gcvNULL,
  106771. + bytes));
  106772. + }
  106773. + else
  106774. + {
  106775. + bytes = node->Virtual.bytes;
  106776. + node->Virtual.type = type;
  106777. +
  106778. + if(node->Virtual.contiguous)
  106779. + {
  106780. + gcmkONERROR(
  106781. + gckKERNEL_AddProcessDB(Kernel,
  106782. + processID, gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  106783. + node,
  106784. + gcvNULL,
  106785. + bytes));
  106786. + }
  106787. + else
  106788. + {
  106789. + gcmkONERROR(
  106790. + gckKERNEL_AddProcessDB(Kernel,
  106791. + processID, gcvDB_VIDEO_MEMORY_VIRTUAL,
  106792. + node,
  106793. + gcvNULL,
  106794. + bytes));
  106795. + }
  106796. +
  106797. + }
  106798. +
  106799. + gcmkONERROR(
  106800. + gckKERNEL_AddProcessDB(Kernel,
  106801. + processID, gcvDB_VIDEO_MEMORY,
  106802. + node,
  106803. + gcvNULL,
  106804. + bytes));
  106805. +
  106806. + /* Get the node. */
  106807. + Interface->u.AllocateLinearVideoMemory.node = gcmPTR_TO_UINT64(node);
  106808. + break;
  106809. +
  106810. + case gcvHAL_FREE_VIDEO_MEMORY:
  106811. + node = gcmUINT64_TO_PTR(Interface->u.FreeVideoMemory.node);
  106812. +#ifdef __QNXNTO__
  106813. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM
  106814. + && node->VidMem.logical != gcvNULL)
  106815. + {
  106816. + gcmkONERROR(
  106817. + gckKERNEL_UnmapVideoMemory(Kernel,
  106818. + node->VidMem.logical,
  106819. + processID,
  106820. + node->VidMem.bytes));
  106821. + node->VidMem.logical = gcvNULL;
  106822. + }
  106823. +#endif
  106824. + /* Free video memory. */
  106825. + gcmkONERROR(
  106826. + gckVIDMEM_Free(node));
  106827. +
  106828. + gcmkONERROR(
  106829. + gckKERNEL_RemoveProcessDB(Kernel,
  106830. + processID, gcvDB_VIDEO_MEMORY,
  106831. + node));
  106832. +
  106833. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  106834. + {
  106835. + gcmkONERROR(
  106836. + gckKERNEL_RemoveProcessDB(Kernel,
  106837. + processID, gcvDB_VIDEO_MEMORY_RESERVED,
  106838. + node));
  106839. + }
  106840. + else if(node->Virtual.contiguous)
  106841. + {
  106842. + gcmkONERROR(
  106843. + gckKERNEL_RemoveProcessDB(Kernel,
  106844. + processID, gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  106845. + node));
  106846. + }
  106847. + else
  106848. + {
  106849. + gcmkONERROR(
  106850. + gckKERNEL_RemoveProcessDB(Kernel,
  106851. + processID, gcvDB_VIDEO_MEMORY_VIRTUAL,
  106852. + node));
  106853. + }
  106854. +
  106855. + break;
  106856. +
  106857. + case gcvHAL_LOCK_VIDEO_MEMORY:
  106858. + node = gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node);
  106859. +
  106860. + /* Lock video memory. */
  106861. + gcmkONERROR(
  106862. + gckVIDMEM_Lock(Kernel,
  106863. + node,
  106864. + Interface->u.LockVideoMemory.cacheable,
  106865. + &Interface->u.LockVideoMemory.address));
  106866. +
  106867. + locked = gcvTRUE;
  106868. +
  106869. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  106870. + {
  106871. + /* Map video memory address into user space. */
  106872. +#ifdef __QNXNTO__
  106873. + if (node->VidMem.logical == gcvNULL)
  106874. + {
  106875. + gcmkONERROR(
  106876. + gckKERNEL_MapVideoMemory(Kernel,
  106877. + FromUser,
  106878. + Interface->u.LockVideoMemory.address,
  106879. + processID,
  106880. + node->VidMem.bytes,
  106881. + &node->VidMem.logical));
  106882. + }
  106883. + gcmkASSERT(node->VidMem.logical != gcvNULL);
  106884. +
  106885. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical);
  106886. +#else
  106887. + gcmkONERROR(
  106888. + gckKERNEL_MapVideoMemory(Kernel,
  106889. + FromUser,
  106890. + Interface->u.LockVideoMemory.address,
  106891. + &logical));
  106892. +
  106893. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical);
  106894. +#endif
  106895. + }
  106896. + else
  106897. + {
  106898. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical);
  106899. +
  106900. + /* Success. */
  106901. + status = gcvSTATUS_OK;
  106902. + }
  106903. +
  106904. +#if gcdSECURE_USER
  106905. + /* Return logical address as physical address. */
  106906. + Interface->u.LockVideoMemory.address =
  106907. + Interface->u.LockVideoMemory.memory;
  106908. +#endif
  106909. + gcmkONERROR(
  106910. + gckKERNEL_AddProcessDB(Kernel,
  106911. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  106912. + node,
  106913. + gcvNULL,
  106914. + 0));
  106915. +
  106916. + break;
  106917. +
  106918. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  106919. + /* Unlock video memory. */
  106920. + node = gcmUINT64_TO_PTR(Interface->u.UnlockVideoMemory.node);
  106921. +
  106922. +#if gcdSECURE_USER
  106923. + /* Save node information before it disappears. */
  106924. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  106925. + {
  106926. + logical = gcvNULL;
  106927. + bytes = 0;
  106928. + }
  106929. + else
  106930. + {
  106931. + logical = node->Virtual.logical;
  106932. + bytes = node->Virtual.bytes;
  106933. + }
  106934. +#endif
  106935. +
  106936. + /* Unlock video memory. */
  106937. + gcmkONERROR(
  106938. + gckVIDMEM_Unlock(Kernel,
  106939. + node,
  106940. + Interface->u.UnlockVideoMemory.type,
  106941. + &Interface->u.UnlockVideoMemory.asynchroneous));
  106942. +
  106943. +#if gcdSECURE_USER
  106944. + /* Flush the translation cache for virtual surfaces. */
  106945. + if (logical != gcvNULL)
  106946. + {
  106947. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel,
  106948. + cache,
  106949. + logical,
  106950. + bytes));
  106951. + }
  106952. +#endif
  106953. + if (Interface->u.UnlockVideoMemory.asynchroneous == gcvFALSE)
  106954. + {
  106955. + /* There isn't a event to unlock this node, remove record now */
  106956. + gcmkONERROR(
  106957. + gckKERNEL_RemoveProcessDB(Kernel,
  106958. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  106959. + node));
  106960. + }
  106961. + break;
  106962. +
  106963. + case gcvHAL_EVENT_COMMIT:
  106964. + /* Commit an event queue. */
  106965. + gcmkONERROR(
  106966. + gckEVENT_Commit(Kernel->eventObj,
  106967. + gcmUINT64_TO_PTR(Interface->u.Event.queue)));
  106968. + break;
  106969. +
  106970. + case gcvHAL_COMMIT:
  106971. + /* Commit a command and context buffer. */
  106972. + gcmkONERROR(
  106973. + gckCOMMAND_Commit(Kernel->command,
  106974. + Interface->u.Commit.context ?
  106975. + gcmNAME_TO_PTR(Interface->u.Commit.context) : gcvNULL,
  106976. + gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffer),
  106977. + gcmUINT64_TO_PTR(Interface->u.Commit.delta),
  106978. + gcmUINT64_TO_PTR(Interface->u.Commit.queue),
  106979. + processID));
  106980. + break;
  106981. +
  106982. + case gcvHAL_STALL:
  106983. + /* Stall the command queue. */
  106984. + gcmkONERROR(gckCOMMAND_Stall(Kernel->command, gcvFALSE));
  106985. + break;
  106986. +
  106987. + case gcvHAL_MAP_USER_MEMORY:
  106988. + /* Map user memory to DMA. */
  106989. + gcmkONERROR(
  106990. + gckOS_MapUserMemory(Kernel->os,
  106991. + Kernel->core,
  106992. + gcmUINT64_TO_PTR(Interface->u.MapUserMemory.memory),
  106993. + Interface->u.MapUserMemory.physical,
  106994. + (gctSIZE_T) Interface->u.MapUserMemory.size,
  106995. + &info,
  106996. + &Interface->u.MapUserMemory.address));
  106997. +
  106998. + Interface->u.MapUserMemory.info = gcmPTR_TO_NAME(info);
  106999. +
  107000. + gcmkVERIFY_OK(
  107001. + gckKERNEL_AddProcessDB(Kernel,
  107002. + processID, gcvDB_MAP_USER_MEMORY,
  107003. + gcmINT2PTR(Interface->u.MapUserMemory.info),
  107004. + gcmUINT64_TO_PTR(Interface->u.MapUserMemory.memory),
  107005. + (gctSIZE_T) Interface->u.MapUserMemory.size));
  107006. + break;
  107007. +
  107008. + case gcvHAL_UNMAP_USER_MEMORY:
  107009. + address = Interface->u.UnmapUserMemory.address;
  107010. + info = gcmNAME_TO_PTR(Interface->u.UnmapUserMemory.info);
  107011. +
  107012. + /* Unmap user memory. */
  107013. + gcmkONERROR(
  107014. + gckOS_UnmapUserMemory(Kernel->os,
  107015. + Kernel->core,
  107016. + gcmUINT64_TO_PTR(Interface->u.UnmapUserMemory.memory),
  107017. + (gctSIZE_T) Interface->u.UnmapUserMemory.size,
  107018. + info,
  107019. + address));
  107020. +
  107021. +#if gcdSECURE_USER
  107022. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  107023. + Kernel,
  107024. + cache,
  107025. + gcmUINT64_TO_PTR(Interface->u.UnmapUserMemory.memory),
  107026. + Interface->u.UnmapUserMemory.size));
  107027. +#endif
  107028. + gcmkVERIFY_OK(
  107029. + gckKERNEL_RemoveProcessDB(Kernel,
  107030. + processID, gcvDB_MAP_USER_MEMORY,
  107031. + gcmINT2PTR(Interface->u.UnmapUserMemory.info)));
  107032. +
  107033. + gcmRELEASE_NAME(Interface->u.UnmapUserMemory.info);
  107034. +
  107035. + break;
  107036. +
  107037. +#if !USE_NEW_LINUX_SIGNAL
  107038. + case gcvHAL_USER_SIGNAL:
  107039. + /* Dispatch depends on the user signal subcommands. */
  107040. + switch(Interface->u.UserSignal.command)
  107041. + {
  107042. + case gcvUSER_SIGNAL_CREATE:
  107043. + /* Create a signal used in the user space. */
  107044. + gcmkONERROR(
  107045. + gckOS_CreateUserSignal(Kernel->os,
  107046. + Interface->u.UserSignal.manualReset,
  107047. + &Interface->u.UserSignal.id));
  107048. +
  107049. + gcmkVERIFY_OK(
  107050. + gckKERNEL_AddProcessDB(Kernel,
  107051. + processID, gcvDB_SIGNAL,
  107052. + gcmINT2PTR(Interface->u.UserSignal.id),
  107053. + gcvNULL,
  107054. + 0));
  107055. + break;
  107056. +
  107057. + case gcvUSER_SIGNAL_DESTROY:
  107058. + /* Destroy the signal. */
  107059. + gcmkONERROR(
  107060. + gckOS_DestroyUserSignal(Kernel->os,
  107061. + Interface->u.UserSignal.id));
  107062. +
  107063. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  107064. + Kernel,
  107065. + processID, gcvDB_SIGNAL,
  107066. + gcmINT2PTR(Interface->u.UserSignal.id)));
  107067. + break;
  107068. +
  107069. + case gcvUSER_SIGNAL_SIGNAL:
  107070. + /* Signal the signal. */
  107071. + gcmkONERROR(
  107072. + gckOS_SignalUserSignal(Kernel->os,
  107073. + Interface->u.UserSignal.id,
  107074. + Interface->u.UserSignal.state));
  107075. + break;
  107076. +
  107077. + case gcvUSER_SIGNAL_WAIT:
  107078. +#if gcdGPU_TIMEOUT
  107079. + if (Interface->u.UserSignal.wait == gcvINFINITE)
  107080. + {
  107081. + gckHARDWARE hardware;
  107082. + gctUINT32 timer = 0;
  107083. +
  107084. + for(;;)
  107085. + {
  107086. + /* Wait on the signal. */
  107087. + status = gckOS_WaitUserSignal(Kernel->os,
  107088. + Interface->u.UserSignal.id,
  107089. + gcdGPU_ADVANCETIMER);
  107090. +
  107091. + if (status == gcvSTATUS_TIMEOUT)
  107092. + {
  107093. + gcmkONERROR(
  107094. + gckOS_SignalQueryHardware(Kernel->os,
  107095. + (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id,
  107096. + &hardware));
  107097. +
  107098. + if (hardware)
  107099. + {
  107100. + /* This signal is bound to a hardware,
  107101. + ** so the timeout is limited by Kernel->timeOut.
  107102. + */
  107103. + timer += gcdGPU_ADVANCETIMER;
  107104. + }
  107105. +
  107106. + if (timer >= Kernel->timeOut)
  107107. + {
  107108. + gcmkONERROR(
  107109. + gckOS_Broadcast(Kernel->os,
  107110. + hardware,
  107111. + gcvBROADCAST_GPU_STUCK));
  107112. +
  107113. + timer = 0;
  107114. +
  107115. + /* If a few process try to reset GPU, only one
  107116. + ** of them can do the real reset, other processes
  107117. + ** still need to wait for this signal is triggered,
  107118. + ** which menas reset is finished.
  107119. + */
  107120. + continue;
  107121. + }
  107122. + }
  107123. + else
  107124. + {
  107125. + /* Bail out on other error. */
  107126. + gcmkONERROR(status);
  107127. +
  107128. + /* Wait for signal successfully. */
  107129. + break;
  107130. + }
  107131. + }
  107132. + }
  107133. + else
  107134. +#endif
  107135. + {
  107136. + /* Wait on the signal. */
  107137. + status = gckOS_WaitUserSignal(Kernel->os,
  107138. + Interface->u.UserSignal.id,
  107139. + Interface->u.UserSignal.wait);
  107140. + }
  107141. +
  107142. + break;
  107143. +
  107144. + case gcvUSER_SIGNAL_MAP:
  107145. + gcmkONERROR(
  107146. + gckOS_MapSignal(Kernel->os,
  107147. + (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id,
  107148. + (gctHANDLE)(gctUINTPTR_T)processID,
  107149. + &signal));
  107150. +
  107151. + gcmkVERIFY_OK(
  107152. + gckKERNEL_AddProcessDB(Kernel,
  107153. + processID, gcvDB_SIGNAL,
  107154. + gcmINT2PTR(Interface->u.UserSignal.id),
  107155. + gcvNULL,
  107156. + 0));
  107157. + break;
  107158. +
  107159. + case gcvUSER_SIGNAL_UNMAP:
  107160. + /* Destroy the signal. */
  107161. + gcmkONERROR(
  107162. + gckOS_DestroyUserSignal(Kernel->os,
  107163. + Interface->u.UserSignal.id));
  107164. +
  107165. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  107166. + Kernel,
  107167. + processID, gcvDB_SIGNAL,
  107168. + gcmINT2PTR(Interface->u.UserSignal.id)));
  107169. + break;
  107170. +
  107171. + default:
  107172. + /* Invalid user signal command. */
  107173. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107174. + }
  107175. + break;
  107176. +#endif
  107177. +
  107178. + case gcvHAL_SET_POWER_MANAGEMENT_STATE:
  107179. + /* Set the power management state. */
  107180. + gcmkONERROR(
  107181. + gckHARDWARE_SetPowerManagementState(
  107182. + Kernel->hardware,
  107183. + Interface->u.SetPowerManagement.state));
  107184. + break;
  107185. +
  107186. + case gcvHAL_QUERY_POWER_MANAGEMENT_STATE:
  107187. + /* Chip is not idle. */
  107188. + Interface->u.QueryPowerManagement.isIdle = gcvFALSE;
  107189. +
  107190. + /* Query the power management state. */
  107191. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
  107192. + Kernel->hardware,
  107193. + &Interface->u.QueryPowerManagement.state));
  107194. +
  107195. + /* Query the idle state. */
  107196. + gcmkONERROR(
  107197. + gckHARDWARE_QueryIdle(Kernel->hardware,
  107198. + &Interface->u.QueryPowerManagement.isIdle));
  107199. + break;
  107200. +
  107201. + case gcvHAL_READ_REGISTER:
  107202. +#if gcdREGISTER_ACCESS_FROM_USER
  107203. + {
  107204. + gceCHIPPOWERSTATE power;
  107205. +
  107206. + gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE);
  107207. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
  107208. + &power));
  107209. + if (power == gcvPOWER_ON)
  107210. + {
  107211. + /* Read a register. */
  107212. + gcmkONERROR(gckOS_ReadRegisterEx(
  107213. + Kernel->os,
  107214. + Kernel->core,
  107215. + Interface->u.ReadRegisterData.address,
  107216. + &Interface->u.ReadRegisterData.data));
  107217. + }
  107218. + else
  107219. + {
  107220. + /* Chip is in power-state. */
  107221. + Interface->u.ReadRegisterData.data = 0;
  107222. + status = gcvSTATUS_CHIP_NOT_READY;
  107223. + }
  107224. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
  107225. + }
  107226. +#else
  107227. + /* No access from user land to read registers. */
  107228. + Interface->u.ReadRegisterData.data = 0;
  107229. + status = gcvSTATUS_NOT_SUPPORTED;
  107230. +#endif
  107231. + break;
  107232. +
  107233. + case gcvHAL_WRITE_REGISTER:
  107234. +#if gcdREGISTER_ACCESS_FROM_USER
  107235. + {
  107236. + gceCHIPPOWERSTATE power;
  107237. +
  107238. + gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE);
  107239. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
  107240. + &power));
  107241. + if (power == gcvPOWER_ON)
  107242. + {
  107243. + /* Write a register. */
  107244. + gcmkONERROR(
  107245. + gckOS_WriteRegisterEx(Kernel->os,
  107246. + Kernel->core,
  107247. + Interface->u.WriteRegisterData.address,
  107248. + Interface->u.WriteRegisterData.data));
  107249. + }
  107250. + else
  107251. + {
  107252. + /* Chip is in power-state. */
  107253. + Interface->u.WriteRegisterData.data = 0;
  107254. + status = gcvSTATUS_CHIP_NOT_READY;
  107255. + }
  107256. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
  107257. + }
  107258. +#else
  107259. + /* No access from user land to write registers. */
  107260. + status = gcvSTATUS_NOT_SUPPORTED;
  107261. +#endif
  107262. + break;
  107263. +
  107264. + case gcvHAL_READ_ALL_PROFILE_REGISTERS:
  107265. +#if VIVANTE_PROFILER && VIVANTE_PROFILER_CONTEXT
  107266. + /* Read profile data according to the context. */
  107267. + gcmkONERROR(
  107268. + gckHARDWARE_QueryContextProfile(
  107269. + Kernel->hardware,
  107270. + Kernel->profileCleanRegister,
  107271. + gcmNAME_TO_PTR(Interface->u.RegisterProfileData.context),
  107272. + &Interface->u.RegisterProfileData.counters));
  107273. +#elif VIVANTE_PROFILER
  107274. + /* Read all 3D profile registers. */
  107275. + gcmkONERROR(
  107276. + gckHARDWARE_QueryProfileRegisters(
  107277. + Kernel->hardware,
  107278. + Kernel->profileCleanRegister,
  107279. + &Interface->u.RegisterProfileData.counters));
  107280. +#else
  107281. + status = gcvSTATUS_OK;
  107282. +#endif
  107283. + break;
  107284. +
  107285. + case gcvHAL_PROFILE_REGISTERS_2D:
  107286. +#if VIVANTE_PROFILER
  107287. + /* Read all 2D profile registers. */
  107288. + gcmkONERROR(
  107289. + gckHARDWARE_ProfileEngine2D(
  107290. + Kernel->hardware,
  107291. + gcmUINT64_TO_PTR(Interface->u.RegisterProfileData2D.hwProfile2D)));
  107292. +#else
  107293. + status = gcvSTATUS_OK;
  107294. +#endif
  107295. + break;
  107296. +
  107297. + case gcvHAL_GET_PROFILE_SETTING:
  107298. +#if VIVANTE_PROFILER
  107299. + /* Get profile setting */
  107300. + Interface->u.GetProfileSetting.enable = Kernel->profileEnable;
  107301. +#endif
  107302. +
  107303. + status = gcvSTATUS_OK;
  107304. + break;
  107305. + case gcvHAL_SET_PROFILE_SETTING:
  107306. +#if VIVANTE_PROFILER
  107307. + /* Set profile setting */
  107308. + if(Kernel->hardware->gpuProfiler)
  107309. + Kernel->profileEnable = Interface->u.SetProfileSetting.enable;
  107310. + else
  107311. + {
  107312. + status = gcvSTATUS_NOT_SUPPORTED;
  107313. + break;
  107314. + }
  107315. +#endif
  107316. +
  107317. + status = gcvSTATUS_OK;
  107318. + break;
  107319. +
  107320. +#if VIVANTE_PROFILER_PERDRAW
  107321. + case gcvHAL_READ_PROFILER_REGISTER_SETTING:
  107322. + #if VIVANTE_PROFILER
  107323. + Kernel->profileCleanRegister = Interface->u.SetProfilerRegisterClear.bclear;
  107324. + #endif
  107325. + status = gcvSTATUS_OK;
  107326. + break;
  107327. +#endif
  107328. +
  107329. + case gcvHAL_QUERY_KERNEL_SETTINGS:
  107330. + /* Get kernel settings. */
  107331. + gcmkONERROR(
  107332. + gckKERNEL_QuerySettings(Kernel,
  107333. + &Interface->u.QueryKernelSettings.settings));
  107334. + break;
  107335. +
  107336. + case gcvHAL_RESET:
  107337. + /* Reset the hardware. */
  107338. + gckKERNEL_Recovery(Kernel);
  107339. + break;
  107340. +
  107341. + case gcvHAL_DEBUG:
  107342. + /* Set debug level and zones. */
  107343. + if (Interface->u.Debug.set)
  107344. + {
  107345. + gckOS_SetDebugLevel(Interface->u.Debug.level);
  107346. + gckOS_SetDebugZones(Interface->u.Debug.zones,
  107347. + Interface->u.Debug.enable);
  107348. + }
  107349. +
  107350. + if (Interface->u.Debug.message[0] != '\0')
  107351. + {
  107352. + /* Print a message to the debugger. */
  107353. + if (Interface->u.Debug.type == gcvMESSAGE_TEXT)
  107354. + {
  107355. + gckOS_CopyPrint(Interface->u.Debug.message);
  107356. + }
  107357. + else
  107358. + {
  107359. + gckOS_DumpBuffer(Kernel->os,
  107360. + Interface->u.Debug.message,
  107361. + Interface->u.Debug.messageSize,
  107362. + gceDUMP_BUFFER_FROM_USER,
  107363. + gcvTRUE);
  107364. + }
  107365. + }
  107366. + status = gcvSTATUS_OK;
  107367. + break;
  107368. +
  107369. + case gcvHAL_DUMP_GPU_STATE:
  107370. + /* Dump GPU state */
  107371. + {
  107372. + gceCHIPPOWERSTATE power;
  107373. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
  107374. + &power));
  107375. + if (power == gcvPOWER_ON)
  107376. + {
  107377. + Interface->u.ReadRegisterData.data = 1;
  107378. + gcmkVERIFY_OK(
  107379. + gckHARDWARE_DumpGPUState(Kernel->hardware));
  107380. +#if gcdVIRTUAL_COMMAND_BUFFER
  107381. + gcmkVERIFY_OK(
  107382. + gckCOMMAND_DumpExecutingBuffer(Kernel->command));
  107383. +#endif
  107384. + }
  107385. + else
  107386. + {
  107387. + Interface->u.ReadRegisterData.data = 0;
  107388. + status = gcvSTATUS_CHIP_NOT_READY;
  107389. + }
  107390. + }
  107391. + break;
  107392. +
  107393. + case gcvHAL_DUMP_EVENT:
  107394. + /* Dump GPU event */
  107395. + gcmkVERIFY_OK(gckEVENT_Dump(Kernel->eventObj));
  107396. +
  107397. + /* Dump Process DB. */
  107398. + gcmkVERIFY_OK(gckKERNEL_DumpProcessDB(Kernel));
  107399. + break;
  107400. +
  107401. + case gcvHAL_CACHE:
  107402. + node = gcmUINT64_TO_PTR(Interface->u.Cache.node);
  107403. + if (node == gcvNULL)
  107404. + {
  107405. + /* FIXME Surface wrap some memory which is not allocated by us,
  107406. + ** So we don't have physical address to handle outer cache, ignore it*/
  107407. + status = gcvSTATUS_OK;
  107408. + break;
  107409. + }
  107410. + else if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  107411. + {
  107412. + /* Video memory has no physical handles. */
  107413. + physical = gcvNULL;
  107414. + }
  107415. + else
  107416. + {
  107417. + /* Grab physical handle. */
  107418. + physical = node->Virtual.physical;
  107419. + }
  107420. +
  107421. + logical = gcmUINT64_TO_PTR(Interface->u.Cache.logical);
  107422. + bytes = (gctSIZE_T) Interface->u.Cache.bytes;
  107423. + switch(Interface->u.Cache.operation)
  107424. + {
  107425. + case gcvCACHE_FLUSH:
  107426. + /* Clean and invalidate the cache. */
  107427. + status = gckOS_CacheFlush(Kernel->os,
  107428. + processID,
  107429. + physical,
  107430. + paddr,
  107431. + logical,
  107432. + bytes);
  107433. + break;
  107434. + case gcvCACHE_CLEAN:
  107435. + /* Clean the cache. */
  107436. + status = gckOS_CacheClean(Kernel->os,
  107437. + processID,
  107438. + physical,
  107439. + paddr,
  107440. + logical,
  107441. + bytes);
  107442. + break;
  107443. + case gcvCACHE_INVALIDATE:
  107444. + /* Invalidate the cache. */
  107445. + status = gckOS_CacheInvalidate(Kernel->os,
  107446. + processID,
  107447. + physical,
  107448. + paddr,
  107449. + logical,
  107450. + bytes);
  107451. + break;
  107452. +
  107453. + case gcvCACHE_MEMORY_BARRIER:
  107454. + status = gckOS_MemoryBarrier(Kernel->os,
  107455. + logical);
  107456. + break;
  107457. + default:
  107458. + status = gcvSTATUS_INVALID_ARGUMENT;
  107459. + break;
  107460. + }
  107461. + break;
  107462. +
  107463. + case gcvHAL_TIMESTAMP:
  107464. + /* Check for invalid timer. */
  107465. + if ((Interface->u.TimeStamp.timer >= gcmCOUNTOF(Kernel->timers))
  107466. + || (Interface->u.TimeStamp.request != 2))
  107467. + {
  107468. + Interface->u.TimeStamp.timeDelta = 0;
  107469. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107470. + }
  107471. +
  107472. + /* Return timer results and reset timer. */
  107473. + {
  107474. + gcsTIMER_PTR timer = &(Kernel->timers[Interface->u.TimeStamp.timer]);
  107475. + gctUINT64 timeDelta = 0;
  107476. +
  107477. + if (timer->stopTime < timer->startTime )
  107478. + {
  107479. + Interface->u.TimeStamp.timeDelta = 0;
  107480. + gcmkONERROR(gcvSTATUS_TIMER_OVERFLOW);
  107481. + }
  107482. +
  107483. + timeDelta = timer->stopTime - timer->startTime;
  107484. +
  107485. + /* Check truncation overflow. */
  107486. + Interface->u.TimeStamp.timeDelta = (gctINT32) timeDelta;
  107487. + /*bit0~bit30 is available*/
  107488. + if (timeDelta>>31)
  107489. + {
  107490. + Interface->u.TimeStamp.timeDelta = 0;
  107491. + gcmkONERROR(gcvSTATUS_TIMER_OVERFLOW);
  107492. + }
  107493. +
  107494. + status = gcvSTATUS_OK;
  107495. + }
  107496. + break;
  107497. +
  107498. + case gcvHAL_DATABASE:
  107499. + /* Query video memory. */
  107500. + gcmkONERROR(
  107501. + gckKERNEL_QueryProcessDB(Kernel,
  107502. + Interface->u.Database.processID,
  107503. + !Interface->u.Database.validProcessID,
  107504. + gcvDB_VIDEO_MEMORY,
  107505. + &Interface->u.Database.vidMem));
  107506. +
  107507. + /* Query non-paged memory. */
  107508. + gcmkONERROR(
  107509. + gckKERNEL_QueryProcessDB(Kernel,
  107510. + Interface->u.Database.processID,
  107511. + !Interface->u.Database.validProcessID,
  107512. + gcvDB_NON_PAGED,
  107513. + &Interface->u.Database.nonPaged));
  107514. +
  107515. + /* Query contiguous memory. */
  107516. + gcmkONERROR(
  107517. + gckKERNEL_QueryProcessDB(Kernel,
  107518. + Interface->u.Database.processID,
  107519. + !Interface->u.Database.validProcessID,
  107520. + gcvDB_CONTIGUOUS,
  107521. + &Interface->u.Database.contiguous));
  107522. +
  107523. + /* Query GPU idle time. */
  107524. + gcmkONERROR(
  107525. + gckKERNEL_QueryProcessDB(Kernel,
  107526. + Interface->u.Database.processID,
  107527. + !Interface->u.Database.validProcessID,
  107528. + gcvDB_IDLE,
  107529. + &Interface->u.Database.gpuIdle));
  107530. + break;
  107531. +
  107532. + case gcvHAL_VIDMEM_DATABASE:
  107533. + /* Query reserved video memory. */
  107534. + gcmkONERROR(
  107535. + gckKERNEL_QueryProcessDB(Kernel,
  107536. + Interface->u.VidMemDatabase.processID,
  107537. + !Interface->u.VidMemDatabase.validProcessID,
  107538. + gcvDB_VIDEO_MEMORY_RESERVED,
  107539. + &Interface->u.VidMemDatabase.vidMemResv));
  107540. +
  107541. + /* Query contiguous video memory. */
  107542. + gcmkONERROR(
  107543. + gckKERNEL_QueryProcessDB(Kernel,
  107544. + Interface->u.VidMemDatabase.processID,
  107545. + !Interface->u.VidMemDatabase.validProcessID,
  107546. + gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  107547. + &Interface->u.VidMemDatabase.vidMemCont));
  107548. +
  107549. + /* Query virtual video memory. */
  107550. + gcmkONERROR(
  107551. + gckKERNEL_QueryProcessDB(Kernel,
  107552. + Interface->u.VidMemDatabase.processID,
  107553. + !Interface->u.VidMemDatabase.validProcessID,
  107554. + gcvDB_VIDEO_MEMORY_VIRTUAL,
  107555. + &Interface->u.VidMemDatabase.vidMemVirt));
  107556. +
  107557. + break;
  107558. +
  107559. + case gcvHAL_VERSION:
  107560. + Interface->u.Version.major = gcvVERSION_MAJOR;
  107561. + Interface->u.Version.minor = gcvVERSION_MINOR;
  107562. + Interface->u.Version.patch = gcvVERSION_PATCH;
  107563. + Interface->u.Version.build = gcvVERSION_BUILD;
  107564. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  107565. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  107566. + "KERNEL version %d.%d.%d build %u %s %s",
  107567. + gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH,
  107568. + gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME);
  107569. +#endif
  107570. + break;
  107571. +
  107572. + case gcvHAL_CHIP_INFO:
  107573. + /* Only if not support multi-core */
  107574. + Interface->u.ChipInfo.count = 1;
  107575. + Interface->u.ChipInfo.types[0] = Kernel->hardware->type;
  107576. + break;
  107577. +
  107578. + case gcvHAL_ATTACH:
  107579. + /* Attach user process. */
  107580. + gcmkONERROR(
  107581. + gckCOMMAND_Attach(Kernel->command,
  107582. + &context,
  107583. + &bytes,
  107584. + processID));
  107585. +
  107586. + Interface->u.Attach.stateCount = bytes;
  107587. + Interface->u.Attach.context = gcmPTR_TO_NAME(context);
  107588. +
  107589. + gcmkVERIFY_OK(
  107590. + gckKERNEL_AddProcessDB(Kernel,
  107591. + processID, gcvDB_CONTEXT,
  107592. + gcmINT2PTR(Interface->u.Attach.context),
  107593. + gcvNULL,
  107594. + 0));
  107595. + break;
  107596. +
  107597. + case gcvHAL_DETACH:
  107598. + /* Detach user process. */
  107599. + gcmkONERROR(
  107600. + gckCOMMAND_Detach(Kernel->command,
  107601. + gcmNAME_TO_PTR(Interface->u.Detach.context)));
  107602. +
  107603. + gcmkVERIFY_OK(
  107604. + gckKERNEL_RemoveProcessDB(Kernel,
  107605. + processID, gcvDB_CONTEXT,
  107606. + gcmINT2PTR(Interface->u.Detach.context)));
  107607. +
  107608. + gcmRELEASE_NAME(Interface->u.Detach.context);
  107609. + break;
  107610. +
  107611. + case gcvHAL_COMPOSE:
  107612. + Interface->u.Compose.physical = gcmPTR_TO_UINT64(gcmNAME_TO_PTR(Interface->u.Compose.physical));
  107613. + /* Start composition. */
  107614. + gcmkONERROR(
  107615. + gckEVENT_Compose(Kernel->eventObj,
  107616. + &Interface->u.Compose));
  107617. + break;
  107618. +
  107619. + case gcvHAL_SET_TIMEOUT:
  107620. + /* set timeOut value from user */
  107621. + gckKERNEL_SetTimeOut(Kernel, Interface->u.SetTimeOut.timeOut);
  107622. + break;
  107623. +
  107624. +#if gcdFRAME_DB
  107625. + case gcvHAL_GET_FRAME_INFO:
  107626. + gcmkONERROR(gckHARDWARE_GetFrameInfo(
  107627. + Kernel->hardware,
  107628. + gcmUINT64_TO_PTR(Interface->u.GetFrameInfo.frameInfo)));
  107629. + break;
  107630. +#endif
  107631. +
  107632. + case gcvHAL_GET_SHARED_INFO:
  107633. + if (Interface->u.GetSharedInfo.data == gcvNULL)
  107634. + {
  107635. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107636. + }
  107637. + else
  107638. + {
  107639. + gctUINT32 pid = Interface->u.GetSharedInfo.pid;
  107640. + gctUINT32 dataId = Interface->u.GetSharedInfo.dataId;
  107641. + gctSIZE_T bytes = Interface->u.GetSharedInfo.bytes;
  107642. + gctPOINTER data = Interface->u.GetSharedInfo.data;
  107643. + gcsDATABASE_RECORD record;
  107644. +
  107645. + /* Find record. */
  107646. + gcmkONERROR(
  107647. + gckKERNEL_FindProcessDB(Kernel,
  107648. + pid,
  107649. + 0,
  107650. + gcvDB_SHARED_INFO,
  107651. + gcmINT2PTR(dataId),
  107652. + &record));
  107653. +
  107654. + /* Check memory size. */
  107655. + if (bytes < record.bytes)
  107656. + {
  107657. + /* Insufficient memory to hold shared data. */
  107658. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107659. + }
  107660. +
  107661. + /* Copy to user. */
  107662. + status = gckOS_CopyToUserData(Kernel->os,
  107663. + record.physical,
  107664. + data,
  107665. + record.bytes);
  107666. +
  107667. + /*
  107668. + * Remove from process db.
  107669. + * Every time when shared info is taken, the record is erased in
  107670. + * kernel side.
  107671. + */
  107672. + gcmkVERIFY_OK(
  107673. + gckKERNEL_RemoveProcessDB(Kernel,
  107674. + pid,
  107675. + gcvDB_SHARED_INFO,
  107676. + gcmINT2PTR(dataId)));
  107677. + /* Free existed data. */
  107678. + gcmkVERIFY_OK(
  107679. + gckOS_FreeMemory(Kernel->os, record.physical));
  107680. + }
  107681. + break;
  107682. +
  107683. + case gcvHAL_SET_SHARED_INFO:
  107684. + {
  107685. + gctUINT32 dataId = Interface->u.SetSharedInfo.dataId;
  107686. + gctPOINTER data = Interface->u.SetSharedInfo.data;
  107687. + gctUINT32 bytes = Interface->u.SetSharedInfo.bytes;
  107688. + gctPOINTER memory = gcvNULL;
  107689. + gcsDATABASE_RECORD record;
  107690. +
  107691. + if (gcmIS_SUCCESS(gckKERNEL_FindProcessDB(Kernel,
  107692. + processID,
  107693. + 0,
  107694. + gcvDB_SHARED_INFO,
  107695. + gcmINT2PTR(dataId),
  107696. + &record)))
  107697. + {
  107698. + /* Find a record with the same id. */
  107699. + if (bytes != record.bytes)
  107700. + {
  107701. + /* Remove from process db. */
  107702. + gcmkVERIFY_OK(
  107703. + gckKERNEL_RemoveProcessDB(Kernel,
  107704. + processID,
  107705. + gcvDB_SHARED_INFO,
  107706. + gcmINT2PTR(dataId)));
  107707. +
  107708. + /* Free existed data. */
  107709. + gcmkVERIFY_OK(
  107710. + gckOS_FreeMemory(Kernel->os, record.physical));
  107711. + }
  107712. + else
  107713. + {
  107714. + /* Re-use allocated memory. */
  107715. + memory = record.physical;
  107716. + }
  107717. + }
  107718. +
  107719. + if ((data == gcvNULL) || (bytes == 0))
  107720. + {
  107721. + /* Nothing to record. */
  107722. + break;
  107723. + }
  107724. +
  107725. + if (bytes > 1024)
  107726. + {
  107727. + /* Limite data size. */
  107728. + gcmkONERROR(gcvSTATUS_TOO_COMPLEX);
  107729. + }
  107730. +
  107731. + if (memory == gcvNULL)
  107732. + {
  107733. + /* Allocate memory for holding shared data. */
  107734. + gcmkONERROR(
  107735. + gckOS_AllocateMemory(Kernel->os, bytes, &memory));
  107736. +
  107737. + /* Add to process db. */
  107738. + status = gckKERNEL_AddProcessDB(Kernel,
  107739. + processID,
  107740. + gcvDB_SHARED_INFO,
  107741. + gcmINT2PTR(dataId),
  107742. + memory,
  107743. + bytes);
  107744. +
  107745. + if (gcmIS_ERROR(status))
  107746. + {
  107747. + /* Failed to add process db. Free allocated memory. */
  107748. + gcmkVERIFY_OK(gckOS_FreeMemory(Kernel->os, memory));
  107749. + break;
  107750. + }
  107751. + }
  107752. +
  107753. + /* Copy shared data to kernel memory. */
  107754. + gcmkONERROR(
  107755. + gckOS_CopyFromUserData(Kernel->os,
  107756. + memory,
  107757. + data,
  107758. + bytes));
  107759. + }
  107760. + break;
  107761. +
  107762. + case gcvHAL_SET_FSCALE_VALUE:
  107763. +#if gcdENABLE_FSCALE_VAL_ADJUST
  107764. + status = gckHARDWARE_SetFscaleValue(Kernel->hardware,
  107765. + Interface->u.SetFscaleValue.value);
  107766. +#else
  107767. + status = gcvSTATUS_NOT_SUPPORTED;
  107768. +#endif
  107769. + break;
  107770. + case gcvHAL_GET_FSCALE_VALUE:
  107771. +#if gcdENABLE_FSCALE_VAL_ADJUST
  107772. + status = gckHARDWARE_GetFscaleValue(Kernel->hardware,
  107773. + &Interface->u.GetFscaleValue.value,
  107774. + &Interface->u.GetFscaleValue.minValue,
  107775. + &Interface->u.GetFscaleValue.maxValue);
  107776. +#else
  107777. + status = gcvSTATUS_NOT_SUPPORTED;
  107778. +#endif
  107779. + break;
  107780. +
  107781. + case gcvHAL_QUERY_RESET_TIME_STAMP:
  107782. +#if gcdENABLE_RECOVERY
  107783. + Interface->u.QueryResetTimeStamp.timeStamp = Kernel->resetTimeStamp;
  107784. +#else
  107785. + Interface->u.QueryResetTimeStamp.timeStamp = 0;
  107786. +#endif
  107787. + break;
  107788. +
  107789. +#if gcdANDROID_NATIVE_FENCE_SYNC
  107790. + case gcvHAL_SYNC_POINT:
  107791. + {
  107792. + gctSYNC_POINT syncPoint;
  107793. +
  107794. + switch (Interface->u.SyncPoint.command)
  107795. + {
  107796. + case gcvSYNC_POINT_CREATE:
  107797. + gcmkONERROR(gckOS_CreateSyncPoint(Kernel->os, &syncPoint));
  107798. +
  107799. + Interface->u.SyncPoint.syncPoint = gcmPTR_TO_UINT64(syncPoint);
  107800. +
  107801. + gcmkVERIFY_OK(
  107802. + gckKERNEL_AddProcessDB(Kernel,
  107803. + processID, gcvDB_SYNC_POINT,
  107804. + syncPoint,
  107805. + gcvNULL,
  107806. + 0));
  107807. + break;
  107808. +
  107809. + case gcvSYNC_POINT_DESTROY:
  107810. + syncPoint = gcmUINT64_TO_PTR(Interface->u.SyncPoint.syncPoint);
  107811. +
  107812. + gcmkONERROR(gckOS_DestroySyncPoint(Kernel->os, syncPoint));
  107813. +
  107814. + gcmkVERIFY_OK(
  107815. + gckKERNEL_RemoveProcessDB(Kernel,
  107816. + processID, gcvDB_SYNC_POINT,
  107817. + syncPoint));
  107818. + break;
  107819. +
  107820. + default:
  107821. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107822. + break;
  107823. + }
  107824. + }
  107825. + break;
  107826. +
  107827. + case gcvHAL_CREATE_NATIVE_FENCE:
  107828. + {
  107829. + gctINT fenceFD;
  107830. + gctSYNC_POINT syncPoint =
  107831. + gcmUINT64_TO_PTR(Interface->u.CreateNativeFence.syncPoint);
  107832. +
  107833. + gcmkONERROR(
  107834. + gckOS_CreateNativeFence(Kernel->os,
  107835. + Kernel->timeline,
  107836. + syncPoint,
  107837. + &fenceFD));
  107838. +
  107839. + Interface->u.CreateNativeFence.fenceFD = fenceFD;
  107840. + }
  107841. + break;
  107842. +#endif
  107843. +
  107844. + default:
  107845. + /* Invalid command. */
  107846. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  107847. + }
  107848. +
  107849. +OnError:
  107850. + /* Save status. */
  107851. + Interface->status = status;
  107852. +
  107853. + if (gcmIS_ERROR(status))
  107854. + {
  107855. + if (locked)
  107856. + {
  107857. + /* Roll back the lock. */
  107858. + gcmkVERIFY_OK(
  107859. + gckVIDMEM_Unlock(Kernel,
  107860. + gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node),
  107861. + gcvSURF_TYPE_UNKNOWN,
  107862. + &asynchronous));
  107863. +
  107864. + if (gcvTRUE == asynchronous)
  107865. + {
  107866. + /* Bottom Half */
  107867. + gcmkVERIFY_OK(
  107868. + gckVIDMEM_Unlock(Kernel,
  107869. + gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node),
  107870. + gcvSURF_TYPE_UNKNOWN,
  107871. + gcvNULL));
  107872. + }
  107873. + }
  107874. + }
  107875. +
  107876. +#if QNX_SINGLE_THREADED_DEBUGGING
  107877. + gckOS_ReleaseMutex(Kernel->os, Kernel->debugMutex);
  107878. +#endif
  107879. +
  107880. + /* Return the status. */
  107881. + gcmkFOOTER();
  107882. + return status;
  107883. +}
  107884. +
  107885. +/*******************************************************************************
  107886. +** gckKERNEL_AttachProcess
  107887. +**
  107888. +** Attach or detach a process.
  107889. +**
  107890. +** INPUT:
  107891. +**
  107892. +** gckKERNEL Kernel
  107893. +** Pointer to an gckKERNEL object.
  107894. +**
  107895. +** gctBOOL Attach
  107896. +** gcvTRUE if a new process gets attached or gcFALSE when a process
  107897. +** gets detatched.
  107898. +**
  107899. +** OUTPUT:
  107900. +**
  107901. +** Nothing.
  107902. +*/
  107903. +gceSTATUS
  107904. +gckKERNEL_AttachProcess(
  107905. + IN gckKERNEL Kernel,
  107906. + IN gctBOOL Attach
  107907. + )
  107908. +{
  107909. + gceSTATUS status;
  107910. + gctUINT32 processID;
  107911. +
  107912. + gcmkHEADER_ARG("Kernel=0x%x Attach=%d", Kernel, Attach);
  107913. +
  107914. + /* Verify the arguments. */
  107915. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  107916. +
  107917. + /* Get current process ID. */
  107918. + gcmkONERROR(gckOS_GetProcessID(&processID));
  107919. +
  107920. + gcmkONERROR(gckKERNEL_AttachProcessEx(Kernel, Attach, processID));
  107921. +
  107922. + /* Success. */
  107923. + gcmkFOOTER_NO();
  107924. + return gcvSTATUS_OK;
  107925. +
  107926. +OnError:
  107927. + /* Return the status. */
  107928. + gcmkFOOTER();
  107929. + return status;
  107930. +}
  107931. +
  107932. +/*******************************************************************************
  107933. +** gckKERNEL_AttachProcessEx
  107934. +**
  107935. +** Attach or detach a process with the given PID. Can be paired with gckKERNEL_AttachProcess
  107936. +** provided the programmer is aware of the consequences.
  107937. +**
  107938. +** INPUT:
  107939. +**
  107940. +** gckKERNEL Kernel
  107941. +** Pointer to an gckKERNEL object.
  107942. +**
  107943. +** gctBOOL Attach
  107944. +** gcvTRUE if a new process gets attached or gcFALSE when a process
  107945. +** gets detatched.
  107946. +**
  107947. +** gctUINT32 PID
  107948. +** PID of the process to attach or detach.
  107949. +**
  107950. +** OUTPUT:
  107951. +**
  107952. +** Nothing.
  107953. +*/
  107954. +gceSTATUS
  107955. +gckKERNEL_AttachProcessEx(
  107956. + IN gckKERNEL Kernel,
  107957. + IN gctBOOL Attach,
  107958. + IN gctUINT32 PID
  107959. + )
  107960. +{
  107961. + gceSTATUS status;
  107962. + gctINT32 old;
  107963. +
  107964. + gcmkHEADER_ARG("Kernel=0x%x Attach=%d PID=%d", Kernel, Attach, PID);
  107965. +
  107966. + /* Verify the arguments. */
  107967. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  107968. +
  107969. + if (Attach)
  107970. + {
  107971. + /* Increment the number of clients attached. */
  107972. + gcmkONERROR(
  107973. + gckOS_AtomIncrement(Kernel->os, Kernel->atomClients, &old));
  107974. +
  107975. + if (old == 0)
  107976. + {
  107977. +#if gcdENABLE_VG
  107978. + if (Kernel->vg == gcvNULL)
  107979. +#endif
  107980. + {
  107981. + gcmkONERROR(gckOS_Broadcast(Kernel->os,
  107982. + Kernel->hardware,
  107983. + gcvBROADCAST_FIRST_PROCESS));
  107984. + }
  107985. + }
  107986. +
  107987. + if (Kernel->dbCreated)
  107988. + {
  107989. + /* Create the process database. */
  107990. + gcmkONERROR(gckKERNEL_CreateProcessDB(Kernel, PID));
  107991. + }
  107992. + }
  107993. + else
  107994. + {
  107995. + if (Kernel->dbCreated)
  107996. + {
  107997. + /* Clean up the process database. */
  107998. + gcmkONERROR(gckKERNEL_DestroyProcessDB(Kernel, PID));
  107999. +
  108000. + /* Save the last know process ID. */
  108001. + Kernel->db->lastProcessID = PID;
  108002. + }
  108003. +
  108004. +#if gcdENABLE_VG
  108005. + if (Kernel->vg == gcvNULL)
  108006. +#endif
  108007. + {
  108008. + status = gckEVENT_Submit(Kernel->eventObj, gcvTRUE, gcvFALSE);
  108009. +
  108010. + if (status == gcvSTATUS_INTERRUPTED && Kernel->eventObj->submitTimer)
  108011. + {
  108012. + gcmkONERROR(gckOS_StartTimer(Kernel->os,
  108013. + Kernel->eventObj->submitTimer,
  108014. + 1));
  108015. + }
  108016. + else
  108017. + {
  108018. + gcmkONERROR(status);
  108019. + }
  108020. + }
  108021. +
  108022. + /* Decrement the number of clients attached. */
  108023. + gcmkONERROR(
  108024. + gckOS_AtomDecrement(Kernel->os, Kernel->atomClients, &old));
  108025. +
  108026. + if (old == 1)
  108027. + {
  108028. +#if gcdENABLE_VG
  108029. + if (Kernel->vg == gcvNULL)
  108030. +#endif
  108031. + {
  108032. + /* Last client detached, switch to SUSPEND power state. */
  108033. + gcmkONERROR(gckOS_Broadcast(Kernel->os,
  108034. + Kernel->hardware,
  108035. + gcvBROADCAST_LAST_PROCESS));
  108036. + }
  108037. +
  108038. + /* Flush the debug cache. */
  108039. + gcmkDEBUGFLUSH(~0U);
  108040. + }
  108041. + }
  108042. +
  108043. + /* Success. */
  108044. + gcmkFOOTER_NO();
  108045. + return gcvSTATUS_OK;
  108046. +
  108047. +OnError:
  108048. + /* Return the status. */
  108049. + gcmkFOOTER();
  108050. + return status;
  108051. +}
  108052. +
  108053. +#if gcdSECURE_USER
  108054. +gceSTATUS
  108055. +gckKERNEL_MapLogicalToPhysical(
  108056. + IN gckKERNEL Kernel,
  108057. + IN gcskSECURE_CACHE_PTR Cache,
  108058. + IN OUT gctPOINTER * Data
  108059. + )
  108060. +{
  108061. + gceSTATUS status;
  108062. + static gctBOOL baseAddressValid = gcvFALSE;
  108063. + static gctUINT32 baseAddress;
  108064. + gctBOOL needBase;
  108065. + gcskLOGICAL_CACHE_PTR slot;
  108066. +
  108067. + gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x *Data=0x%x",
  108068. + Kernel, Cache, gcmOPT_POINTER(Data));
  108069. +
  108070. + /* Verify the arguments. */
  108071. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  108072. +
  108073. + if (!baseAddressValid)
  108074. + {
  108075. + /* Get base address. */
  108076. + gcmkONERROR(gckHARDWARE_GetBaseAddress(Kernel->hardware, &baseAddress));
  108077. +
  108078. + baseAddressValid = gcvTRUE;
  108079. + }
  108080. +
  108081. + /* Does this state load need a base address? */
  108082. + gcmkONERROR(gckHARDWARE_NeedBaseAddress(Kernel->hardware,
  108083. + ((gctUINT32_PTR) Data)[-1],
  108084. + &needBase));
  108085. +
  108086. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
  108087. + {
  108088. + gcskLOGICAL_CACHE_PTR next;
  108089. + gctINT i;
  108090. +
  108091. + /* Walk all used cache slots. */
  108092. + for (i = 1, slot = Cache->cache[0].next, next = gcvNULL;
  108093. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  108094. + ++i, slot = slot->next
  108095. + )
  108096. + {
  108097. + if (slot->logical == *Data)
  108098. + {
  108099. + /* Bail out. */
  108100. + next = slot;
  108101. + break;
  108102. + }
  108103. + }
  108104. +
  108105. + /* See if we had a miss. */
  108106. + if (next == gcvNULL)
  108107. + {
  108108. + /* Use the tail of the cache. */
  108109. + slot = Cache->cache[0].prev;
  108110. +
  108111. + /* Initialize the cache line. */
  108112. + slot->logical = *Data;
  108113. +
  108114. + /* Map the logical address to a DMA address. */
  108115. + gcmkONERROR(
  108116. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  108117. + }
  108118. +
  108119. + /* Move slot to head of list. */
  108120. + if (slot != Cache->cache[0].next)
  108121. + {
  108122. + /* Unlink. */
  108123. + slot->prev->next = slot->next;
  108124. + slot->next->prev = slot->prev;
  108125. +
  108126. + /* Move to head of chain. */
  108127. + slot->prev = &Cache->cache[0];
  108128. + slot->next = Cache->cache[0].next;
  108129. + slot->prev->next = slot;
  108130. + slot->next->prev = slot;
  108131. + }
  108132. + }
  108133. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
  108134. + {
  108135. + gctINT i;
  108136. + gcskLOGICAL_CACHE_PTR next = gcvNULL;
  108137. + gcskLOGICAL_CACHE_PTR oldestSlot = gcvNULL;
  108138. + slot = gcvNULL;
  108139. +
  108140. + if (Cache->cacheIndex != gcvNULL)
  108141. + {
  108142. + /* Walk the cache forwards. */
  108143. + for (i = 1, slot = Cache->cacheIndex;
  108144. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  108145. + ++i, slot = slot->next)
  108146. + {
  108147. + if (slot->logical == *Data)
  108148. + {
  108149. + /* Bail out. */
  108150. + next = slot;
  108151. + break;
  108152. + }
  108153. +
  108154. + /* Determine age of this slot. */
  108155. + if ((oldestSlot == gcvNULL)
  108156. + || (oldestSlot->stamp > slot->stamp)
  108157. + )
  108158. + {
  108159. + oldestSlot = slot;
  108160. + }
  108161. + }
  108162. +
  108163. + if (next == gcvNULL)
  108164. + {
  108165. + /* Walk the cache backwards. */
  108166. + for (slot = Cache->cacheIndex->prev;
  108167. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  108168. + ++i, slot = slot->prev)
  108169. + {
  108170. + if (slot->logical == *Data)
  108171. + {
  108172. + /* Bail out. */
  108173. + next = slot;
  108174. + break;
  108175. + }
  108176. +
  108177. + /* Determine age of this slot. */
  108178. + if ((oldestSlot == gcvNULL)
  108179. + || (oldestSlot->stamp > slot->stamp)
  108180. + )
  108181. + {
  108182. + oldestSlot = slot;
  108183. + }
  108184. + }
  108185. + }
  108186. + }
  108187. +
  108188. + /* See if we had a miss. */
  108189. + if (next == gcvNULL)
  108190. + {
  108191. + if (Cache->cacheFree != 0)
  108192. + {
  108193. + slot = &Cache->cache[Cache->cacheFree];
  108194. + gcmkASSERT(slot->logical == gcvNULL);
  108195. +
  108196. + ++ Cache->cacheFree;
  108197. + if (Cache->cacheFree >= gcmCOUNTOF(Cache->cache))
  108198. + {
  108199. + Cache->cacheFree = 0;
  108200. + }
  108201. + }
  108202. + else
  108203. + {
  108204. + /* Use the oldest cache slot. */
  108205. + gcmkASSERT(oldestSlot != gcvNULL);
  108206. + slot = oldestSlot;
  108207. +
  108208. + /* Unlink from the chain. */
  108209. + slot->prev->next = slot->next;
  108210. + slot->next->prev = slot->prev;
  108211. +
  108212. + /* Append to the end. */
  108213. + slot->prev = Cache->cache[0].prev;
  108214. + slot->next = &Cache->cache[0];
  108215. + slot->prev->next = slot;
  108216. + slot->next->prev = slot;
  108217. + }
  108218. +
  108219. + /* Initialize the cache line. */
  108220. + slot->logical = *Data;
  108221. +
  108222. + /* Map the logical address to a DMA address. */
  108223. + gcmkONERROR(
  108224. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  108225. + }
  108226. +
  108227. + /* Save time stamp. */
  108228. + slot->stamp = ++ Cache->cacheStamp;
  108229. +
  108230. + /* Save current slot for next lookup. */
  108231. + Cache->cacheIndex = slot;
  108232. + }
  108233. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  108234. + {
  108235. + gctINT i;
  108236. + gctUINT32 data = gcmPTR2INT(*Data);
  108237. + gctUINT32 key, index;
  108238. + gcskLOGICAL_CACHE_PTR hash;
  108239. +
  108240. + /* Generate a hash key. */
  108241. + key = (data >> 24) + (data >> 16) + (data >> 8) + data;
  108242. + index = key % gcmCOUNTOF(Cache->hash);
  108243. +
  108244. + /* Get the hash entry. */
  108245. + hash = &Cache->hash[index];
  108246. +
  108247. + for (slot = hash->nextHash, i = 0;
  108248. + (slot != gcvNULL) && (i < gcdSECURE_CACHE_SLOTS);
  108249. + slot = slot->nextHash, ++i
  108250. + )
  108251. + {
  108252. + if (slot->logical == (*Data))
  108253. + {
  108254. + break;
  108255. + }
  108256. + }
  108257. +
  108258. + if (slot == gcvNULL)
  108259. + {
  108260. + /* Grab from the tail of the cache. */
  108261. + slot = Cache->cache[0].prev;
  108262. +
  108263. + /* Unlink slot from any hash table it is part of. */
  108264. + if (slot->prevHash != gcvNULL)
  108265. + {
  108266. + slot->prevHash->nextHash = slot->nextHash;
  108267. + }
  108268. + if (slot->nextHash != gcvNULL)
  108269. + {
  108270. + slot->nextHash->prevHash = slot->prevHash;
  108271. + }
  108272. +
  108273. + /* Initialize the cache line. */
  108274. + slot->logical = *Data;
  108275. +
  108276. + /* Map the logical address to a DMA address. */
  108277. + gcmkONERROR(
  108278. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  108279. +
  108280. + if (hash->nextHash != gcvNULL)
  108281. + {
  108282. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  108283. + "Hash Collision: logical=0x%x key=0x%08x",
  108284. + *Data, key);
  108285. + }
  108286. +
  108287. + /* Insert the slot at the head of the hash list. */
  108288. + slot->nextHash = hash->nextHash;
  108289. + if (slot->nextHash != gcvNULL)
  108290. + {
  108291. + slot->nextHash->prevHash = slot;
  108292. + }
  108293. + slot->prevHash = hash;
  108294. + hash->nextHash = slot;
  108295. + }
  108296. +
  108297. + /* Move slot to head of list. */
  108298. + if (slot != Cache->cache[0].next)
  108299. + {
  108300. + /* Unlink. */
  108301. + slot->prev->next = slot->next;
  108302. + slot->next->prev = slot->prev;
  108303. +
  108304. + /* Move to head of chain. */
  108305. + slot->prev = &Cache->cache[0];
  108306. + slot->next = Cache->cache[0].next;
  108307. + slot->prev->next = slot;
  108308. + slot->next->prev = slot;
  108309. + }
  108310. + }
  108311. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
  108312. + {
  108313. + gctUINT32 index = (gcmPTR2INT(*Data) % gcdSECURE_CACHE_SLOTS) + 1;
  108314. +
  108315. + /* Get cache slot. */
  108316. + slot = &Cache->cache[index];
  108317. +
  108318. + /* Check for cache miss. */
  108319. + if (slot->logical != *Data)
  108320. + {
  108321. + /* Initialize the cache line. */
  108322. + slot->logical = *Data;
  108323. +
  108324. + /* Map the logical address to a DMA address. */
  108325. + gcmkONERROR(
  108326. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  108327. + }
  108328. + }
  108329. +#endif
  108330. +
  108331. + /* Return DMA address. */
  108332. + *Data = gcmINT2PTR(slot->dma + (needBase ? baseAddress : 0));
  108333. +
  108334. + /* Success. */
  108335. + gcmkFOOTER_ARG("*Data=0x%08x", *Data);
  108336. + return gcvSTATUS_OK;
  108337. +
  108338. +OnError:
  108339. + /* Return the status. */
  108340. + gcmkFOOTER();
  108341. + return status;
  108342. +}
  108343. +
  108344. +gceSTATUS
  108345. +gckKERNEL_FlushTranslationCache(
  108346. + IN gckKERNEL Kernel,
  108347. + IN gcskSECURE_CACHE_PTR Cache,
  108348. + IN gctPOINTER Logical,
  108349. + IN gctSIZE_T Bytes
  108350. + )
  108351. +{
  108352. + gctINT i;
  108353. + gcskLOGICAL_CACHE_PTR slot;
  108354. + gctUINT8_PTR ptr;
  108355. +
  108356. + gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x Logical=0x%x Bytes=%lu",
  108357. + Kernel, Cache, Logical, Bytes);
  108358. +
  108359. + /* Do we need to flush the entire cache? */
  108360. + if (Logical == gcvNULL)
  108361. + {
  108362. + /* Clear all cache slots. */
  108363. + for (i = 1; i <= gcdSECURE_CACHE_SLOTS; ++i)
  108364. + {
  108365. + Cache->cache[i].logical = gcvNULL;
  108366. +
  108367. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  108368. + Cache->cache[i].nextHash = gcvNULL;
  108369. + Cache->cache[i].prevHash = gcvNULL;
  108370. +#endif
  108371. +}
  108372. +
  108373. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  108374. + /* Zero the hash table. */
  108375. + for (i = 0; i < gcmCOUNTOF(Cache->hash); ++i)
  108376. + {
  108377. + Cache->hash[i].nextHash = gcvNULL;
  108378. + }
  108379. +#endif
  108380. +
  108381. + /* Reset the cache functionality. */
  108382. + Cache->cacheIndex = gcvNULL;
  108383. + Cache->cacheFree = 1;
  108384. + Cache->cacheStamp = 0;
  108385. + }
  108386. +
  108387. + else
  108388. + {
  108389. + gctUINT8_PTR low = (gctUINT8_PTR) Logical;
  108390. + gctUINT8_PTR high = low + Bytes;
  108391. +
  108392. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
  108393. + gcskLOGICAL_CACHE_PTR next;
  108394. +
  108395. + /* Walk all used cache slots. */
  108396. + for (i = 1, slot = Cache->cache[0].next;
  108397. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  108398. + ++i, slot = next
  108399. + )
  108400. + {
  108401. + /* Save pointer to next slot. */
  108402. + next = slot->next;
  108403. +
  108404. + /* Test if this slot falls within the range to flush. */
  108405. + ptr = (gctUINT8_PTR) slot->logical;
  108406. + if ((ptr >= low) && (ptr < high))
  108407. + {
  108408. + /* Unlink slot. */
  108409. + slot->prev->next = slot->next;
  108410. + slot->next->prev = slot->prev;
  108411. +
  108412. + /* Append slot to tail of cache. */
  108413. + slot->prev = Cache->cache[0].prev;
  108414. + slot->next = &Cache->cache[0];
  108415. + slot->prev->next = slot;
  108416. + slot->next->prev = slot;
  108417. +
  108418. + /* Mark slot as empty. */
  108419. + slot->logical = gcvNULL;
  108420. + }
  108421. + }
  108422. +
  108423. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
  108424. + gcskLOGICAL_CACHE_PTR next;
  108425. +
  108426. + for (i = 1, slot = Cache->cache[0].next;
  108427. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  108428. + ++i, slot = next)
  108429. + {
  108430. + /* Save pointer to next slot. */
  108431. + next = slot->next;
  108432. +
  108433. + /* Test if this slot falls within the range to flush. */
  108434. + ptr = (gctUINT8_PTR) slot->logical;
  108435. + if ((ptr >= low) && (ptr < high))
  108436. + {
  108437. + /* Test if this slot is the current slot. */
  108438. + if (slot == Cache->cacheIndex)
  108439. + {
  108440. + /* Move to next or previous slot. */
  108441. + Cache->cacheIndex = (slot->next->logical != gcvNULL)
  108442. + ? slot->next
  108443. + : (slot->prev->logical != gcvNULL)
  108444. + ? slot->prev
  108445. + : gcvNULL;
  108446. + }
  108447. +
  108448. + /* Unlink slot from cache. */
  108449. + slot->prev->next = slot->next;
  108450. + slot->next->prev = slot->prev;
  108451. +
  108452. + /* Insert slot to head of cache. */
  108453. + slot->prev = &Cache->cache[0];
  108454. + slot->next = Cache->cache[0].next;
  108455. + slot->prev->next = slot;
  108456. + slot->next->prev = slot;
  108457. +
  108458. + /* Mark slot as empty. */
  108459. + slot->logical = gcvNULL;
  108460. + slot->stamp = 0;
  108461. + }
  108462. + }
  108463. +
  108464. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  108465. + gctINT j;
  108466. + gcskLOGICAL_CACHE_PTR hash, next;
  108467. +
  108468. + /* Walk all hash tables. */
  108469. + for (i = 0, hash = Cache->hash;
  108470. + i < gcmCOUNTOF(Cache->hash);
  108471. + ++i, ++hash)
  108472. + {
  108473. + /* Walk all slots in the hash. */
  108474. + for (j = 0, slot = hash->nextHash;
  108475. + (j < gcdSECURE_CACHE_SLOTS) && (slot != gcvNULL);
  108476. + ++j, slot = next)
  108477. + {
  108478. + /* Save pointer to next slot. */
  108479. + next = slot->next;
  108480. +
  108481. + /* Test if this slot falls within the range to flush. */
  108482. + ptr = (gctUINT8_PTR) slot->logical;
  108483. + if ((ptr >= low) && (ptr < high))
  108484. + {
  108485. + /* Unlink slot from hash table. */
  108486. + if (slot->prevHash == hash)
  108487. + {
  108488. + hash->nextHash = slot->nextHash;
  108489. + }
  108490. + else
  108491. + {
  108492. + slot->prevHash->nextHash = slot->nextHash;
  108493. + }
  108494. +
  108495. + if (slot->nextHash != gcvNULL)
  108496. + {
  108497. + slot->nextHash->prevHash = slot->prevHash;
  108498. + }
  108499. +
  108500. + /* Unlink slot from cache. */
  108501. + slot->prev->next = slot->next;
  108502. + slot->next->prev = slot->prev;
  108503. +
  108504. + /* Append slot to tail of cache. */
  108505. + slot->prev = Cache->cache[0].prev;
  108506. + slot->next = &Cache->cache[0];
  108507. + slot->prev->next = slot;
  108508. + slot->next->prev = slot;
  108509. +
  108510. + /* Mark slot as empty. */
  108511. + slot->logical = gcvNULL;
  108512. + slot->prevHash = gcvNULL;
  108513. + slot->nextHash = gcvNULL;
  108514. + }
  108515. + }
  108516. + }
  108517. +
  108518. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
  108519. + gctUINT32 index;
  108520. +
  108521. + /* Loop while inside the range. */
  108522. + for (i = 1; (low < high) && (i <= gcdSECURE_CACHE_SLOTS); ++i)
  108523. + {
  108524. + /* Get index into cache for this range. */
  108525. + index = (gcmPTR2INT(low) % gcdSECURE_CACHE_SLOTS) + 1;
  108526. + slot = &Cache->cache[index];
  108527. +
  108528. + /* Test if this slot falls within the range to flush. */
  108529. + ptr = (gctUINT8_PTR) slot->logical;
  108530. + if ((ptr >= low) && (ptr < high))
  108531. + {
  108532. + /* Remove entry from cache. */
  108533. + slot->logical = gcvNULL;
  108534. + }
  108535. +
  108536. + /* Next block. */
  108537. + low += gcdSECURE_CACHE_SLOTS;
  108538. + }
  108539. +#endif
  108540. + }
  108541. +
  108542. + /* Success. */
  108543. + gcmkFOOTER_NO();
  108544. + return gcvSTATUS_OK;
  108545. +}
  108546. +#endif
  108547. +
  108548. +/*******************************************************************************
  108549. +**
  108550. +** gckKERNEL_Recovery
  108551. +**
  108552. +** Try to recover the GPU from a fatal error.
  108553. +**
  108554. +** INPUT:
  108555. +**
  108556. +** gckKERNEL Kernel
  108557. +** Pointer to an gckKERNEL object.
  108558. +**
  108559. +** OUTPUT:
  108560. +**
  108561. +** Nothing.
  108562. +*/
  108563. +gceSTATUS
  108564. +gckKERNEL_Recovery(
  108565. + IN gckKERNEL Kernel
  108566. + )
  108567. +{
  108568. +#if gcdENABLE_RECOVERY
  108569. +#define gcdEVENT_MASK 0x3FFFFFFF
  108570. + gceSTATUS status;
  108571. + gckEVENT eventObj;
  108572. + gckHARDWARE hardware;
  108573. +#if gcdSECURE_USER
  108574. + gctUINT32 processID;
  108575. + gcskSECURE_CACHE_PTR cache;
  108576. +#endif
  108577. + gctUINT32 oldValue;
  108578. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  108579. +
  108580. + /* Validate the arguemnts. */
  108581. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  108582. +
  108583. + /* Grab gckEVENT object. */
  108584. + eventObj = Kernel->eventObj;
  108585. + gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
  108586. +
  108587. + /* Grab gckHARDWARE object. */
  108588. + hardware = Kernel->hardware;
  108589. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  108590. +
  108591. +#if gcdSECURE_USER
  108592. + /* Flush the secure mapping cache. */
  108593. + gcmkONERROR(gckOS_GetProcessID(&processID));
  108594. + gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
  108595. + gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0));
  108596. +#endif
  108597. +
  108598. + gcmkONERROR(
  108599. + gckOS_AtomicExchange(Kernel->os, Kernel->resetAtom, 1, &oldValue));
  108600. +
  108601. + if (oldValue)
  108602. + {
  108603. + /* Some one else will recovery GPU. */
  108604. + return gcvSTATUS_OK;
  108605. + }
  108606. +
  108607. + gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core);
  108608. +
  108609. + /* Start a timer to clear reset flag, before timer is expired,
  108610. + ** other recovery request is ignored. */
  108611. + gcmkVERIFY_OK(
  108612. + gckOS_StartTimer(Kernel->os,
  108613. + Kernel->resetFlagClearTimer,
  108614. + gcdGPU_TIMEOUT - 500));
  108615. +
  108616. +
  108617. + /* Try issuing a soft reset for the GPU. */
  108618. + status = gckHARDWARE_Reset(hardware);
  108619. + if (status == gcvSTATUS_NOT_SUPPORTED)
  108620. + {
  108621. + /* Switch to OFF power. The next submit should return the GPU to ON
  108622. + ** state. */
  108623. + gcmkONERROR(
  108624. + gckHARDWARE_SetPowerManagementState(hardware,
  108625. + gcvPOWER_OFF_RECOVERY));
  108626. + }
  108627. + else
  108628. + {
  108629. + /* Bail out on reset error. */
  108630. + gcmkONERROR(status);
  108631. + }
  108632. +
  108633. + /* Handle all outstanding events now. */
  108634. +#if gcdSMP
  108635. + gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
  108636. +#else
  108637. + eventObj->pending = gcdEVENT_MASK;
  108638. +#endif
  108639. + gcmkONERROR(gckEVENT_Notify(eventObj, 1));
  108640. +
  108641. + /* Again in case more events got submitted. */
  108642. +#if gcdSMP
  108643. + gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
  108644. +#else
  108645. + eventObj->pending = gcdEVENT_MASK;
  108646. +#endif
  108647. + gcmkONERROR(gckEVENT_Notify(eventObj, 2));
  108648. +
  108649. + Kernel->resetTimeStamp++;
  108650. +
  108651. + /* Success. */
  108652. + gcmkFOOTER_NO();
  108653. + return gcvSTATUS_OK;
  108654. +
  108655. +OnError:
  108656. + /* Return the status. */
  108657. + gcmkFOOTER();
  108658. + return status;
  108659. +#else
  108660. + return gcvSTATUS_OK;
  108661. +#endif
  108662. +}
  108663. +
  108664. +/*******************************************************************************
  108665. +**
  108666. +** gckKERNEL_OpenUserData
  108667. +**
  108668. +** Get access to the user data.
  108669. +**
  108670. +** INPUT:
  108671. +**
  108672. +** gckKERNEL Kernel
  108673. +** Pointer to an gckKERNEL object.
  108674. +**
  108675. +** gctBOOL NeedCopy
  108676. +** The flag indicating whether or not the data should be copied.
  108677. +**
  108678. +** gctPOINTER StaticStorage
  108679. +** Pointer to the kernel storage where the data is to be copied if
  108680. +** NeedCopy is gcvTRUE.
  108681. +**
  108682. +** gctPOINTER UserPointer
  108683. +** User pointer to the data.
  108684. +**
  108685. +** gctSIZE_T Size
  108686. +** Size of the data.
  108687. +**
  108688. +** OUTPUT:
  108689. +**
  108690. +** gctPOINTER * KernelPointer
  108691. +** Pointer to the kernel pointer that will be pointing to the data.
  108692. +*/
  108693. +gceSTATUS
  108694. +gckKERNEL_OpenUserData(
  108695. + IN gckKERNEL Kernel,
  108696. + IN gctBOOL NeedCopy,
  108697. + IN gctPOINTER StaticStorage,
  108698. + IN gctPOINTER UserPointer,
  108699. + IN gctSIZE_T Size,
  108700. + OUT gctPOINTER * KernelPointer
  108701. + )
  108702. +{
  108703. + gceSTATUS status;
  108704. +
  108705. + gcmkHEADER_ARG(
  108706. + "Kernel=0x%08X NeedCopy=%d StaticStorage=0x%08X "
  108707. + "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
  108708. + Kernel, NeedCopy, StaticStorage, UserPointer, Size, KernelPointer
  108709. + );
  108710. +
  108711. + /* Validate the arguemnts. */
  108712. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  108713. + gcmkVERIFY_ARGUMENT(!NeedCopy || (StaticStorage != gcvNULL));
  108714. + gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
  108715. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  108716. + gcmkVERIFY_ARGUMENT(Size > 0);
  108717. +
  108718. + if (NeedCopy)
  108719. + {
  108720. + /* Copy the user data to the static storage. */
  108721. + gcmkONERROR(gckOS_CopyFromUserData(
  108722. + Kernel->os, StaticStorage, UserPointer, Size
  108723. + ));
  108724. +
  108725. + /* Set the kernel pointer. */
  108726. + * KernelPointer = StaticStorage;
  108727. + }
  108728. + else
  108729. + {
  108730. + gctPOINTER pointer = gcvNULL;
  108731. +
  108732. + /* Map the user pointer. */
  108733. + gcmkONERROR(gckOS_MapUserPointer(
  108734. + Kernel->os, UserPointer, Size, &pointer
  108735. + ));
  108736. +
  108737. + /* Set the kernel pointer. */
  108738. + * KernelPointer = pointer;
  108739. + }
  108740. +
  108741. +OnError:
  108742. + /* Return the status. */
  108743. + gcmkFOOTER();
  108744. + return status;
  108745. +}
  108746. +
  108747. +/*******************************************************************************
  108748. +**
  108749. +** gckKERNEL_CloseUserData
  108750. +**
  108751. +** Release resources associated with the user data connection opened by
  108752. +** gckKERNEL_OpenUserData.
  108753. +**
  108754. +** INPUT:
  108755. +**
  108756. +** gckKERNEL Kernel
  108757. +** Pointer to an gckKERNEL object.
  108758. +**
  108759. +** gctBOOL NeedCopy
  108760. +** The flag indicating whether or not the data should be copied.
  108761. +**
  108762. +** gctBOOL FlushData
  108763. +** If gcvTRUE, the data is written back to the user.
  108764. +**
  108765. +** gctPOINTER UserPointer
  108766. +** User pointer to the data.
  108767. +**
  108768. +** gctSIZE_T Size
  108769. +** Size of the data.
  108770. +**
  108771. +** OUTPUT:
  108772. +**
  108773. +** gctPOINTER * KernelPointer
  108774. +** Kernel pointer to the data.
  108775. +*/
  108776. +gceSTATUS
  108777. +gckKERNEL_CloseUserData(
  108778. + IN gckKERNEL Kernel,
  108779. + IN gctBOOL NeedCopy,
  108780. + IN gctBOOL FlushData,
  108781. + IN gctPOINTER UserPointer,
  108782. + IN gctSIZE_T Size,
  108783. + OUT gctPOINTER * KernelPointer
  108784. + )
  108785. +{
  108786. + gceSTATUS status = gcvSTATUS_OK;
  108787. + gctPOINTER pointer;
  108788. +
  108789. + gcmkHEADER_ARG(
  108790. + "Kernel=0x%08X NeedCopy=%d FlushData=%d "
  108791. + "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
  108792. + Kernel, NeedCopy, FlushData, UserPointer, Size, KernelPointer
  108793. + );
  108794. +
  108795. + /* Validate the arguemnts. */
  108796. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  108797. + gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
  108798. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  108799. + gcmkVERIFY_ARGUMENT(Size > 0);
  108800. +
  108801. + /* Get a shortcut to the kernel pointer. */
  108802. + pointer = * KernelPointer;
  108803. +
  108804. + if (pointer != gcvNULL)
  108805. + {
  108806. + if (NeedCopy)
  108807. + {
  108808. + if (FlushData)
  108809. + {
  108810. + gcmkONERROR(gckOS_CopyToUserData(
  108811. + Kernel->os, * KernelPointer, UserPointer, Size
  108812. + ));
  108813. + }
  108814. + }
  108815. + else
  108816. + {
  108817. + /* Unmap record from kernel memory. */
  108818. + gcmkONERROR(gckOS_UnmapUserPointer(
  108819. + Kernel->os,
  108820. + UserPointer,
  108821. + Size,
  108822. + * KernelPointer
  108823. + ));
  108824. + }
  108825. +
  108826. + /* Reset the kernel pointer. */
  108827. + * KernelPointer = gcvNULL;
  108828. + }
  108829. +
  108830. +OnError:
  108831. + /* Return the status. */
  108832. + gcmkFOOTER();
  108833. + return status;
  108834. +}
  108835. +
  108836. +void
  108837. +gckKERNEL_SetTimeOut(
  108838. + IN gckKERNEL Kernel,
  108839. + IN gctUINT32 timeOut
  108840. + )
  108841. +{
  108842. + gcmkHEADER_ARG("Kernel=0x%x timeOut=%d", Kernel, timeOut);
  108843. +#if gcdGPU_TIMEOUT
  108844. + Kernel->timeOut = timeOut;
  108845. +#endif
  108846. + gcmkFOOTER_NO();
  108847. +}
  108848. +
  108849. +#if gcdVIRTUAL_COMMAND_BUFFER
  108850. +gceSTATUS
  108851. +gckKERNEL_AllocateVirtualCommandBuffer(
  108852. + IN gckKERNEL Kernel,
  108853. + IN gctBOOL InUserSpace,
  108854. + IN OUT gctSIZE_T * Bytes,
  108855. + OUT gctPHYS_ADDR * Physical,
  108856. + OUT gctPOINTER * Logical
  108857. + )
  108858. +{
  108859. + gckOS os = Kernel->os;
  108860. + gceSTATUS status;
  108861. + gctPOINTER logical;
  108862. + gctSIZE_T pageCount;
  108863. + gctSIZE_T bytes = *Bytes;
  108864. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  108865. +
  108866. + gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
  108867. + os, InUserSpace, gcmOPT_VALUE(Bytes));
  108868. +
  108869. + /* Verify the arguments. */
  108870. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  108871. + gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
  108872. + gcmkVERIFY_ARGUMENT(*Bytes > 0);
  108873. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  108874. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  108875. +
  108876. + gcmkONERROR(gckOS_Allocate(os,
  108877. + sizeof(gckVIRTUAL_COMMAND_BUFFER),
  108878. + (gctPOINTER)&buffer));
  108879. +
  108880. + gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_COMMAND_BUFFER)));
  108881. +
  108882. + gcmkONERROR(gckOS_AllocatePagedMemoryEx(os,
  108883. + gcvFALSE,
  108884. + bytes,
  108885. + &buffer->physical));
  108886. +
  108887. + if (InUserSpace)
  108888. + {
  108889. + gcmkONERROR(gckOS_LockPages(os,
  108890. + buffer->physical,
  108891. + bytes,
  108892. + gcvFALSE,
  108893. + &logical,
  108894. + &pageCount));
  108895. +
  108896. + *Logical =
  108897. + buffer->userLogical = logical;
  108898. + }
  108899. + else
  108900. + {
  108901. + gcmkONERROR(
  108902. + gckOS_CreateKernelVirtualMapping(buffer->physical,
  108903. + &pageCount,
  108904. + &logical));
  108905. + *Logical =
  108906. + buffer->kernelLogical = logical;
  108907. + }
  108908. +
  108909. + buffer->pageCount = pageCount;
  108910. + buffer->kernel = Kernel;
  108911. +
  108912. + gcmkONERROR(gckOS_GetProcessID(&buffer->pid));
  108913. +
  108914. + gcmkONERROR(gckMMU_AllocatePages(Kernel->mmu,
  108915. + pageCount,
  108916. + &buffer->pageTable,
  108917. + &buffer->gpuAddress));
  108918. +
  108919. + gcmkONERROR(gckOS_MapPagesEx(os,
  108920. + Kernel->core,
  108921. + buffer->physical,
  108922. + pageCount,
  108923. + buffer->pageTable));
  108924. +
  108925. + gcmkONERROR(gckMMU_Flush(Kernel->mmu));
  108926. +
  108927. + *Physical = buffer;
  108928. +
  108929. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  108930. + "gpuAddress = %x pageCount = %d kernelLogical = %x userLogical=%x",
  108931. + buffer->gpuAddress, buffer->pageCount,
  108932. + buffer->kernelLogical, buffer->userLogical);
  108933. +
  108934. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, Kernel->virtualBufferLock, gcvINFINITE));
  108935. +
  108936. + if (Kernel->virtualBufferHead == gcvNULL)
  108937. + {
  108938. + Kernel->virtualBufferHead =
  108939. + Kernel->virtualBufferTail = buffer;
  108940. + }
  108941. + else
  108942. + {
  108943. + buffer->prev = Kernel->virtualBufferTail;
  108944. + Kernel->virtualBufferTail->next = buffer;
  108945. + Kernel->virtualBufferTail = buffer;
  108946. + }
  108947. +
  108948. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Kernel->virtualBufferLock));
  108949. +
  108950. + gcmkFOOTER_NO();
  108951. + return gcvSTATUS_OK;
  108952. +
  108953. +OnError:
  108954. + if (buffer->gpuAddress)
  108955. + {
  108956. + gcmkVERIFY_OK(
  108957. + gckMMU_FreePages(Kernel->mmu, buffer->pageTable, buffer->pageCount));
  108958. + }
  108959. +
  108960. + if (buffer->userLogical)
  108961. + {
  108962. + gcmkVERIFY_OK(
  108963. + gckOS_UnlockPages(os, buffer->physical, bytes, buffer->userLogical));
  108964. + }
  108965. +
  108966. + if (buffer->kernelLogical)
  108967. + {
  108968. + gcmkVERIFY_OK(
  108969. + gckOS_DestroyKernelVirtualMapping(buffer->kernelLogical));
  108970. + }
  108971. +
  108972. + if (buffer->physical)
  108973. + {
  108974. + gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, bytes));
  108975. + }
  108976. +
  108977. + gcmkVERIFY_OK(gckOS_Free(os, buffer));
  108978. +
  108979. + /* Return the status. */
  108980. + gcmkFOOTER();
  108981. + return status;
  108982. +}
  108983. +
  108984. +gceSTATUS
  108985. +gckKERNEL_DestroyVirtualCommandBuffer(
  108986. + IN gckKERNEL Kernel,
  108987. + IN gctSIZE_T Bytes,
  108988. + IN gctPHYS_ADDR Physical,
  108989. + IN gctPOINTER Logical
  108990. + )
  108991. +{
  108992. + gckOS os;
  108993. + gckKERNEL kernel;
  108994. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)Physical;
  108995. +
  108996. + gcmkHEADER();
  108997. + gcmkVERIFY_ARGUMENT(buffer != gcvNULL);
  108998. +
  108999. + kernel = buffer->kernel;
  109000. + os = kernel->os;
  109001. +
  109002. + if (buffer->userLogical)
  109003. + {
  109004. + gcmkVERIFY_OK(gckOS_UnlockPages(os, buffer->physical, Bytes, Logical));
  109005. + }
  109006. + else
  109007. + {
  109008. + gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(Logical));
  109009. + }
  109010. +
  109011. + gcmkVERIFY_OK(
  109012. + gckMMU_FreePages(kernel->mmu, buffer->pageTable, buffer->pageCount));
  109013. +
  109014. + gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, Bytes));
  109015. +
  109016. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE));
  109017. +
  109018. + if (buffer == kernel->virtualBufferHead)
  109019. + {
  109020. + if ((kernel->virtualBufferHead = buffer->next) == gcvNULL)
  109021. + {
  109022. + kernel->virtualBufferTail = gcvNULL;
  109023. + }
  109024. + }
  109025. + else
  109026. + {
  109027. + buffer->prev->next = buffer->next;
  109028. +
  109029. + if (buffer == kernel->virtualBufferTail)
  109030. + {
  109031. + kernel->virtualBufferTail = buffer->prev;
  109032. + }
  109033. + else
  109034. + {
  109035. + buffer->next->prev = buffer->prev;
  109036. + }
  109037. + }
  109038. +
  109039. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->virtualBufferLock));
  109040. +
  109041. + gcmkVERIFY_OK(gckOS_Free(os, buffer));
  109042. +
  109043. + gcmkFOOTER_NO();
  109044. + return gcvSTATUS_OK;
  109045. +}
  109046. +
  109047. +gceSTATUS
  109048. +gckKERNEL_GetGPUAddress(
  109049. + IN gckKERNEL Kernel,
  109050. + IN gctPOINTER Logical,
  109051. + OUT gctUINT32 * Address
  109052. + )
  109053. +{
  109054. + gceSTATUS status;
  109055. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  109056. + gctPOINTER start;
  109057. + gctINT pid;
  109058. +
  109059. + gcmkHEADER_ARG("Logical = %x", Logical);
  109060. +
  109061. + gckOS_GetProcessID(&pid);
  109062. +
  109063. + status = gcvSTATUS_INVALID_ADDRESS;
  109064. +
  109065. + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
  109066. +
  109067. + /* Walk all command buffer. */
  109068. + for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
  109069. + {
  109070. + if (buffer->userLogical)
  109071. + {
  109072. + start = buffer->userLogical;
  109073. + }
  109074. + else
  109075. + {
  109076. + start = buffer->kernelLogical;
  109077. + }
  109078. +
  109079. + if (Logical >= start
  109080. + && (Logical < (start + buffer->pageCount * 4096))
  109081. + && pid == buffer->pid
  109082. + )
  109083. + {
  109084. + * Address = buffer->gpuAddress + (Logical - start);
  109085. + status = gcvSTATUS_OK;
  109086. + break;
  109087. + }
  109088. + }
  109089. +
  109090. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
  109091. +
  109092. + gcmkFOOTER_NO();
  109093. + return status;
  109094. +}
  109095. +
  109096. +gceSTATUS
  109097. +gckKERNEL_QueryGPUAddress(
  109098. + IN gckKERNEL Kernel,
  109099. + IN gctUINT32 GpuAddress,
  109100. + OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
  109101. + )
  109102. +{
  109103. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  109104. + gctUINT32 start;
  109105. + gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
  109106. +
  109107. + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
  109108. +
  109109. + /* Walk all command buffers. */
  109110. + for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
  109111. + {
  109112. + start = (gctUINT32)buffer->gpuAddress;
  109113. +
  109114. + if (GpuAddress >= start && GpuAddress < (start + buffer->pageCount * 4096))
  109115. + {
  109116. + /* Find a range matched. */
  109117. + *Buffer = buffer;
  109118. + status = gcvSTATUS_OK;
  109119. + break;
  109120. + }
  109121. + }
  109122. +
  109123. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
  109124. +
  109125. + return status;
  109126. +}
  109127. +#endif
  109128. +
  109129. +#if gcdLINK_QUEUE_SIZE
  109130. +static void
  109131. +gckLINKQUEUE_Dequeue(
  109132. + IN gckLINKQUEUE LinkQueue
  109133. + )
  109134. +{
  109135. + gcmkASSERT(LinkQueue->count == gcdLINK_QUEUE_SIZE);
  109136. +
  109137. + LinkQueue->count--;
  109138. + LinkQueue->front = (LinkQueue->front + 1) % gcdLINK_QUEUE_SIZE;
  109139. +}
  109140. +
  109141. +void
  109142. +gckLINKQUEUE_Enqueue(
  109143. + IN gckLINKQUEUE LinkQueue,
  109144. + IN gctUINT32 start,
  109145. + IN gctUINT32 end
  109146. + )
  109147. +{
  109148. + if (LinkQueue->count == gcdLINK_QUEUE_SIZE)
  109149. + {
  109150. + gckLINKQUEUE_Dequeue(LinkQueue);
  109151. + }
  109152. +
  109153. + gcmkASSERT(LinkQueue->count < gcdLINK_QUEUE_SIZE);
  109154. +
  109155. + LinkQueue->count++;
  109156. +
  109157. + LinkQueue->data[LinkQueue->rear].start = start;
  109158. + LinkQueue->data[LinkQueue->rear].end = end;
  109159. +
  109160. + gcmkVERIFY_OK(
  109161. + gckOS_GetProcessID(&LinkQueue->data[LinkQueue->rear].pid));
  109162. +
  109163. + LinkQueue->rear = (LinkQueue->rear + 1) % gcdLINK_QUEUE_SIZE;
  109164. +}
  109165. +
  109166. +void
  109167. +gckLINKQUEUE_GetData(
  109168. + IN gckLINKQUEUE LinkQueue,
  109169. + IN gctUINT32 Index,
  109170. + OUT gckLINKDATA * Data
  109171. + )
  109172. +{
  109173. + gcmkASSERT(Index >= 0 && Index < gcdLINK_QUEUE_SIZE);
  109174. +
  109175. + *Data = &LinkQueue->data[(Index + LinkQueue->front) % gcdLINK_QUEUE_SIZE];
  109176. +}
  109177. +#endif
  109178. +
  109179. +/******************************************************************************\
  109180. +*************************** Pointer - ID translation ***************************
  109181. +\******************************************************************************/
  109182. +#define gcdID_TABLE_LENGTH 1024
  109183. +typedef struct _gcsINTEGERDB * gckINTEGERDB;
  109184. +typedef struct _gcsINTEGERDB
  109185. +{
  109186. + gckOS os;
  109187. + gctPOINTER* table;
  109188. + gctPOINTER mutex;
  109189. + gctUINT32 tableLen;
  109190. + gctUINT32 currentID;
  109191. + gctUINT32 unused;
  109192. +}
  109193. +gcsINTEGERDB;
  109194. +
  109195. +gceSTATUS
  109196. +gckKERNEL_CreateIntegerDatabase(
  109197. + IN gckKERNEL Kernel,
  109198. + OUT gctPOINTER * Database
  109199. + )
  109200. +{
  109201. + gceSTATUS status;
  109202. + gckINTEGERDB database = gcvNULL;
  109203. +
  109204. + gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
  109205. +
  109206. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  109207. + gcmkVERIFY_ARGUMENT(Database != gcvNULL);
  109208. +
  109209. + /* Allocate a database. */
  109210. + gcmkONERROR(gckOS_Allocate(
  109211. + Kernel->os, gcmSIZEOF(gcsINTEGERDB), (gctPOINTER *)&database));
  109212. +
  109213. + gckOS_ZeroMemory(database, gcmSIZEOF(gcsINTEGERDB));
  109214. +
  109215. + /* Allocate a pointer table. */
  109216. + gcmkONERROR(gckOS_Allocate(
  109217. + Kernel->os, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH, (gctPOINTER *)&database->table));
  109218. +
  109219. + gckOS_ZeroMemory(database->table, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH);
  109220. +
  109221. + /* Allocate a database mutex. */
  109222. + gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->mutex));
  109223. +
  109224. + /* Initialize. */
  109225. + database->currentID = 0;
  109226. + database->unused = gcdID_TABLE_LENGTH;
  109227. + database->os = Kernel->os;
  109228. + database->tableLen = gcdID_TABLE_LENGTH;
  109229. +
  109230. + *Database = database;
  109231. +
  109232. + gcmkFOOTER_ARG("*Database=0x%08X", *Database);
  109233. + return gcvSTATUS_OK;
  109234. +
  109235. +OnError:
  109236. + /* Rollback. */
  109237. + if (database)
  109238. + {
  109239. + if (database->table)
  109240. + {
  109241. + gcmkOS_SAFE_FREE(Kernel->os, database->table);
  109242. + }
  109243. +
  109244. + gcmkOS_SAFE_FREE(Kernel->os, database);
  109245. + }
  109246. +
  109247. + gcmkFOOTER();
  109248. + return status;
  109249. +}
  109250. +
  109251. +gceSTATUS
  109252. +gckKERNEL_DestroyIntegerDatabase(
  109253. + IN gckKERNEL Kernel,
  109254. + IN gctPOINTER Database
  109255. + )
  109256. +{
  109257. + gckINTEGERDB database = Database;
  109258. +
  109259. + gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
  109260. +
  109261. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  109262. + gcmkVERIFY_ARGUMENT(Database != gcvNULL);
  109263. +
  109264. + /* Destroy pointer table. */
  109265. + gcmkOS_SAFE_FREE(Kernel->os, database->table);
  109266. +
  109267. + /* Destroy database mutex. */
  109268. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->mutex));
  109269. +
  109270. + /* Destroy database. */
  109271. + gcmkOS_SAFE_FREE(Kernel->os, database);
  109272. +
  109273. + gcmkFOOTER_NO();
  109274. + return gcvSTATUS_OK;
  109275. +}
  109276. +
  109277. +gceSTATUS
  109278. +gckKERNEL_AllocateIntegerId(
  109279. + IN gctPOINTER Database,
  109280. + IN gctPOINTER Pointer,
  109281. + OUT gctUINT32 * Id
  109282. + )
  109283. +{
  109284. + gceSTATUS status;
  109285. + gckINTEGERDB database = Database;
  109286. + gctUINT32 i, unused, currentID, tableLen;
  109287. + gctPOINTER * table;
  109288. + gckOS os = database->os;
  109289. + gctBOOL acquired = gcvFALSE;
  109290. +
  109291. + gcmkHEADER_ARG("Database=0x%08X Pointer=0x%08X", Database, Pointer);
  109292. +
  109293. + gcmkVERIFY_ARGUMENT(Id != gcvNULL);
  109294. +
  109295. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
  109296. + acquired = gcvTRUE;
  109297. +
  109298. + if (database->unused < 1)
  109299. + {
  109300. + /* Extend table. */
  109301. + gcmkONERROR(
  109302. + gckOS_Allocate(os,
  109303. + gcmSIZEOF(gctPOINTER) * (database->tableLen + gcdID_TABLE_LENGTH),
  109304. + (gctPOINTER *)&table));
  109305. +
  109306. + gckOS_ZeroMemory(table + database->tableLen,
  109307. + gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH);
  109308. +
  109309. + /* Copy data from old table. */
  109310. + gckOS_MemCopy(table,
  109311. + database->table,
  109312. + database->tableLen * gcmSIZEOF(gctPOINTER));
  109313. +
  109314. + gcmkOS_SAFE_FREE(os, database->table);
  109315. +
  109316. + /* Update databse with new allocated table. */
  109317. + database->table = table;
  109318. + database->currentID = database->tableLen;
  109319. + database->tableLen += gcdID_TABLE_LENGTH;
  109320. + database->unused += gcdID_TABLE_LENGTH;
  109321. + }
  109322. +
  109323. + table = database->table;
  109324. + currentID = database->currentID;
  109325. + tableLen = database->tableLen;
  109326. + unused = database->unused;
  109327. +
  109328. + /* Connect id with pointer. */
  109329. + table[currentID] = Pointer;
  109330. +
  109331. + *Id = currentID + 1;
  109332. +
  109333. + /* Update the currentID. */
  109334. + if (--unused > 0)
  109335. + {
  109336. + for (i = 0; i < tableLen; i++)
  109337. + {
  109338. + if (++currentID >= tableLen)
  109339. + {
  109340. + /* Wrap to the begin. */
  109341. + currentID = 0;
  109342. + }
  109343. +
  109344. + if (table[currentID] == gcvNULL)
  109345. + {
  109346. + break;
  109347. + }
  109348. + }
  109349. + }
  109350. +
  109351. + database->table = table;
  109352. + database->currentID = currentID;
  109353. + database->tableLen = tableLen;
  109354. + database->unused = unused;
  109355. +
  109356. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109357. + acquired = gcvFALSE;
  109358. +
  109359. + gcmkFOOTER_ARG("*Id=%d", *Id);
  109360. + return gcvSTATUS_OK;
  109361. +
  109362. +OnError:
  109363. + if (acquired)
  109364. + {
  109365. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109366. + }
  109367. +
  109368. + gcmkFOOTER();
  109369. + return status;
  109370. +}
  109371. +
  109372. +gceSTATUS
  109373. +gckKERNEL_FreeIntegerId(
  109374. + IN gctPOINTER Database,
  109375. + IN gctUINT32 Id
  109376. + )
  109377. +{
  109378. + gceSTATUS status;
  109379. + gckINTEGERDB database = Database;
  109380. + gckOS os = database->os;
  109381. + gctBOOL acquired = gcvFALSE;
  109382. +
  109383. + gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
  109384. +
  109385. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
  109386. + acquired = gcvTRUE;
  109387. +
  109388. + if (!(Id > 0 && Id <= database->tableLen))
  109389. + {
  109390. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  109391. + }
  109392. +
  109393. + Id -= 1;
  109394. +
  109395. + database->table[Id] = gcvNULL;
  109396. +
  109397. + if (database->unused++ == 0)
  109398. + {
  109399. + database->currentID = Id;
  109400. + }
  109401. +
  109402. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109403. + acquired = gcvFALSE;
  109404. +
  109405. + gcmkFOOTER_NO();
  109406. + return gcvSTATUS_OK;
  109407. +
  109408. +OnError:
  109409. + if (acquired)
  109410. + {
  109411. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109412. + }
  109413. +
  109414. + gcmkFOOTER();
  109415. + return status;
  109416. +}
  109417. +
  109418. +gceSTATUS
  109419. +gckKERNEL_QueryIntegerId(
  109420. + IN gctPOINTER Database,
  109421. + IN gctUINT32 Id,
  109422. + OUT gctPOINTER * Pointer
  109423. + )
  109424. +{
  109425. + gceSTATUS status;
  109426. + gckINTEGERDB database = Database;
  109427. + gctPOINTER pointer;
  109428. + gckOS os = database->os;
  109429. + gctBOOL acquired = gcvFALSE;
  109430. +
  109431. + gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
  109432. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  109433. +
  109434. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
  109435. + acquired = gcvTRUE;
  109436. +
  109437. + if (!(Id > 0 && Id <= database->tableLen))
  109438. + {
  109439. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  109440. + }
  109441. +
  109442. + Id -= 1;
  109443. +
  109444. + pointer = database->table[Id];
  109445. +
  109446. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109447. + acquired = gcvFALSE;
  109448. +
  109449. + if (pointer)
  109450. + {
  109451. + *Pointer = pointer;
  109452. + }
  109453. + else
  109454. + {
  109455. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  109456. + }
  109457. +
  109458. + gcmkFOOTER_ARG("*Pointer=0x%08X", *Pointer);
  109459. + return gcvSTATUS_OK;
  109460. +
  109461. +OnError:
  109462. + if (acquired)
  109463. + {
  109464. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  109465. + }
  109466. +
  109467. + gcmkFOOTER();
  109468. + return status;
  109469. +}
  109470. +
  109471. +
  109472. +gctUINT32
  109473. +gckKERNEL_AllocateNameFromPointer(
  109474. + IN gckKERNEL Kernel,
  109475. + IN gctPOINTER Pointer
  109476. + )
  109477. +{
  109478. + gceSTATUS status;
  109479. + gctUINT32 name;
  109480. + gctPOINTER database = Kernel->db->pointerDatabase;
  109481. +
  109482. + gcmkHEADER_ARG("Kernel=0x%X Pointer=0x%X", Kernel, Pointer);
  109483. +
  109484. + gcmkONERROR(
  109485. + gckKERNEL_AllocateIntegerId(database, Pointer, &name));
  109486. +
  109487. + gcmkFOOTER_ARG("name=%d", name);
  109488. + return name;
  109489. +
  109490. +OnError:
  109491. + gcmkFOOTER();
  109492. + return 0;
  109493. +}
  109494. +
  109495. +gctPOINTER
  109496. +gckKERNEL_QueryPointerFromName(
  109497. + IN gckKERNEL Kernel,
  109498. + IN gctUINT32 Name
  109499. + )
  109500. +{
  109501. + gceSTATUS status;
  109502. + gctPOINTER pointer = gcvNULL;
  109503. + gctPOINTER database = Kernel->db->pointerDatabase;
  109504. +
  109505. + gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name);
  109506. +
  109507. + /* Lookup in database to get pointer. */
  109508. + gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, &pointer));
  109509. +
  109510. + gcmkFOOTER_ARG("pointer=0x%X", pointer);
  109511. + return pointer;
  109512. +
  109513. +OnError:
  109514. + gcmkFOOTER();
  109515. + return gcvNULL;
  109516. +}
  109517. +
  109518. +gceSTATUS
  109519. +gckKERNEL_DeleteName(
  109520. + IN gckKERNEL Kernel,
  109521. + IN gctUINT32 Name
  109522. + )
  109523. +{
  109524. + gctPOINTER database = Kernel->db->pointerDatabase;
  109525. +
  109526. + gcmkHEADER_ARG("Kernel=0x%X Name=0x%X", Kernel, Name);
  109527. +
  109528. + /* Free name if exists. */
  109529. + gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Name));
  109530. +
  109531. + gcmkFOOTER_NO();
  109532. + return gcvSTATUS_OK;
  109533. +}
  109534. +/*******************************************************************************
  109535. +***** Test Code ****************************************************************
  109536. +*******************************************************************************/
  109537. +
  109538. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
  109539. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c 1969-12-31 18:00:00.000000000 -0600
  109540. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c 2014-12-08 00:31:53.464418001 -0600
  109541. @@ -0,0 +1,3042 @@
  109542. +/****************************************************************************
  109543. +*
  109544. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  109545. +*
  109546. +* This program is free software; you can redistribute it and/or modify
  109547. +* it under the terms of the GNU General Public License as published by
  109548. +* the Free Software Foundation; either version 2 of the license, or
  109549. +* (at your option) any later version.
  109550. +*
  109551. +* This program is distributed in the hope that it will be useful,
  109552. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  109553. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  109554. +* GNU General Public License for more details.
  109555. +*
  109556. +* You should have received a copy of the GNU General Public License
  109557. +* along with this program; if not write to the Free Software
  109558. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  109559. +*
  109560. +*****************************************************************************/
  109561. +
  109562. +
  109563. +#include "gc_hal_kernel_precomp.h"
  109564. +#include "gc_hal_kernel_context.h"
  109565. +
  109566. +#ifdef __QNXNTO__
  109567. +#include <sys/slog.h>
  109568. +#endif
  109569. +
  109570. +#define _GC_OBJ_ZONE gcvZONE_COMMAND
  109571. +
  109572. +/******************************************************************************\
  109573. +********************************* Support Code *********************************
  109574. +\******************************************************************************/
  109575. +
  109576. +/*******************************************************************************
  109577. +**
  109578. +** _NewQueue
  109579. +**
  109580. +** Allocate a new command queue.
  109581. +**
  109582. +** INPUT:
  109583. +**
  109584. +** gckCOMMAND Command
  109585. +** Pointer to an gckCOMMAND object.
  109586. +**
  109587. +** OUTPUT:
  109588. +**
  109589. +** gckCOMMAND Command
  109590. +** gckCOMMAND object has been updated with a new command queue.
  109591. +*/
  109592. +static gceSTATUS
  109593. +_NewQueue(
  109594. + IN OUT gckCOMMAND Command
  109595. + )
  109596. +{
  109597. + gceSTATUS status;
  109598. + gctINT currentIndex, newIndex;
  109599. +
  109600. + gcmkHEADER_ARG("Command=0x%x", Command);
  109601. +
  109602. + /* Switch to the next command buffer. */
  109603. + currentIndex = Command->index;
  109604. + newIndex = (currentIndex + 1) % gcdCOMMAND_QUEUES;
  109605. +
  109606. + /* Wait for availability. */
  109607. +#if gcdDUMP_COMMAND
  109608. + gcmkPRINT("@[kernel.waitsignal]");
  109609. +#endif
  109610. +
  109611. + gcmkONERROR(gckOS_WaitSignal(
  109612. + Command->os,
  109613. + Command->queues[newIndex].signal,
  109614. + gcvINFINITE
  109615. + ));
  109616. +
  109617. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  109618. + if (newIndex < currentIndex)
  109619. + {
  109620. + Command->wrapCount += 1;
  109621. +
  109622. + gcmkTRACE_ZONE_N(
  109623. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  109624. + 2 * 4,
  109625. + "%s(%d): queue array wrapped around.\n",
  109626. + __FUNCTION__, __LINE__
  109627. + );
  109628. + }
  109629. +
  109630. + gcmkTRACE_ZONE_N(
  109631. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  109632. + 3 * 4,
  109633. + "%s(%d): total queue wrap arounds %d.\n",
  109634. + __FUNCTION__, __LINE__, Command->wrapCount
  109635. + );
  109636. +
  109637. + gcmkTRACE_ZONE_N(
  109638. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  109639. + 3 * 4,
  109640. + "%s(%d): switched to queue %d.\n",
  109641. + __FUNCTION__, __LINE__, newIndex
  109642. + );
  109643. +#endif
  109644. +
  109645. + /* Update gckCOMMAND object with new command queue. */
  109646. + Command->index = newIndex;
  109647. + Command->newQueue = gcvTRUE;
  109648. + Command->logical = Command->queues[newIndex].logical;
  109649. + Command->offset = 0;
  109650. +
  109651. + gcmkONERROR(
  109652. + gckOS_GetPhysicalAddress(
  109653. + Command->os,
  109654. + Command->logical,
  109655. + (gctUINT32 *) &Command->physical
  109656. + ));
  109657. +
  109658. + if (currentIndex != -1)
  109659. + {
  109660. + /* Mark the command queue as available. */
  109661. + gcmkONERROR(gckEVENT_Signal(
  109662. + Command->kernel->eventObj,
  109663. + Command->queues[currentIndex].signal,
  109664. + gcvKERNEL_COMMAND
  109665. + ));
  109666. + }
  109667. +
  109668. + /* Success. */
  109669. + gcmkFOOTER_ARG("Command->index=%d", Command->index);
  109670. + return gcvSTATUS_OK;
  109671. +
  109672. +OnError:
  109673. + /* Return the status. */
  109674. + gcmkFOOTER();
  109675. + return status;
  109676. +}
  109677. +
  109678. +static gceSTATUS
  109679. +_IncrementCommitAtom(
  109680. + IN gckCOMMAND Command,
  109681. + IN gctBOOL Increment
  109682. + )
  109683. +{
  109684. + gceSTATUS status;
  109685. + gckHARDWARE hardware;
  109686. + gctINT32 atomValue;
  109687. + gctBOOL powerAcquired = gcvFALSE;
  109688. +
  109689. + gcmkHEADER_ARG("Command=0x%x", Command);
  109690. +
  109691. + /* Extract the gckHARDWARE and gckEVENT objects. */
  109692. + hardware = Command->kernel->hardware;
  109693. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  109694. +
  109695. + /* Grab the power mutex. */
  109696. + gcmkONERROR(gckOS_AcquireMutex(
  109697. + Command->os, hardware->powerMutex, gcvINFINITE
  109698. + ));
  109699. + powerAcquired = gcvTRUE;
  109700. +
  109701. + /* Increment the commit atom. */
  109702. + if (Increment)
  109703. + {
  109704. + gcmkONERROR(gckOS_AtomIncrement(
  109705. + Command->os, Command->atomCommit, &atomValue
  109706. + ));
  109707. + }
  109708. + else
  109709. + {
  109710. + gcmkONERROR(gckOS_AtomDecrement(
  109711. + Command->os, Command->atomCommit, &atomValue
  109712. + ));
  109713. + }
  109714. +
  109715. + /* Release the power mutex. */
  109716. + gcmkONERROR(gckOS_ReleaseMutex(
  109717. + Command->os, hardware->powerMutex
  109718. + ));
  109719. + powerAcquired = gcvFALSE;
  109720. +
  109721. + /* Success. */
  109722. + gcmkFOOTER();
  109723. + return gcvSTATUS_OK;
  109724. +
  109725. +OnError:
  109726. + if (powerAcquired)
  109727. + {
  109728. + /* Release the power mutex. */
  109729. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  109730. + Command->os, hardware->powerMutex
  109731. + ));
  109732. + }
  109733. +
  109734. + /* Return the status. */
  109735. + gcmkFOOTER();
  109736. + return status;
  109737. +}
  109738. +
  109739. +#if gcdSECURE_USER
  109740. +static gceSTATUS
  109741. +_ProcessHints(
  109742. + IN gckCOMMAND Command,
  109743. + IN gctUINT32 ProcessID,
  109744. + IN gcoCMDBUF CommandBuffer
  109745. + )
  109746. +{
  109747. + gceSTATUS status = gcvSTATUS_OK;
  109748. + gckKERNEL kernel;
  109749. + gctBOOL needCopy = gcvFALSE;
  109750. + gcskSECURE_CACHE_PTR cache;
  109751. + gctUINT8_PTR commandBufferLogical;
  109752. + gctUINT8_PTR hintedData;
  109753. + gctUINT32_PTR hintArray;
  109754. + gctUINT i, hintCount;
  109755. +
  109756. + gcmkHEADER_ARG(
  109757. + "Command=0x%08X ProcessID=%d CommandBuffer=0x%08X",
  109758. + Command, ProcessID, CommandBuffer
  109759. + );
  109760. +
  109761. + /* Verify the arguments. */
  109762. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  109763. +
  109764. + /* Reset state array pointer. */
  109765. + hintArray = gcvNULL;
  109766. +
  109767. + /* Get the kernel object. */
  109768. + kernel = Command->kernel;
  109769. +
  109770. + /* Get the cache form the database. */
  109771. + gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
  109772. +
  109773. + /* Determine the start of the command buffer. */
  109774. + commandBufferLogical
  109775. + = (gctUINT8_PTR) CommandBuffer->logical
  109776. + + CommandBuffer->startOffset;
  109777. +
  109778. + /* Determine the number of records in the state array. */
  109779. + hintCount = CommandBuffer->hintArrayTail - CommandBuffer->hintArray;
  109780. +
  109781. + /* Check wehther we need to copy the structures or not. */
  109782. + gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
  109783. +
  109784. + /* Get access to the state array. */
  109785. + if (needCopy)
  109786. + {
  109787. + gctUINT copySize;
  109788. +
  109789. + if (Command->hintArrayAllocated &&
  109790. + (Command->hintArraySize < CommandBuffer->hintArraySize))
  109791. + {
  109792. + gcmkONERROR(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
  109793. + Command->hintArraySize = gcvFALSE;
  109794. + }
  109795. +
  109796. + if (!Command->hintArrayAllocated)
  109797. + {
  109798. + gctPOINTER pointer = gcvNULL;
  109799. +
  109800. + gcmkONERROR(gckOS_Allocate(
  109801. + Command->os,
  109802. + CommandBuffer->hintArraySize,
  109803. + &pointer
  109804. + ));
  109805. +
  109806. + Command->hintArray = gcmPTR_TO_UINT64(pointer);
  109807. + Command->hintArrayAllocated = gcvTRUE;
  109808. + Command->hintArraySize = CommandBuffer->hintArraySize;
  109809. + }
  109810. +
  109811. + hintArray = gcmUINT64_TO_PTR(Command->hintArray);
  109812. + copySize = hintCount * gcmSIZEOF(gctUINT32);
  109813. +
  109814. + gcmkONERROR(gckOS_CopyFromUserData(
  109815. + Command->os,
  109816. + hintArray,
  109817. + gcmUINT64_TO_PTR(CommandBuffer->hintArray),
  109818. + copySize
  109819. + ));
  109820. + }
  109821. + else
  109822. + {
  109823. + gctPOINTER pointer = gcvNULL;
  109824. +
  109825. + gcmkONERROR(gckOS_MapUserPointer(
  109826. + Command->os,
  109827. + gcmUINT64_TO_PTR(CommandBuffer->hintArray),
  109828. + CommandBuffer->hintArraySize,
  109829. + &pointer
  109830. + ));
  109831. +
  109832. + hintArray = pointer;
  109833. + }
  109834. +
  109835. + /* Scan through the buffer. */
  109836. + for (i = 0; i < hintCount; i += 1)
  109837. + {
  109838. + /* Determine the location of the hinted data. */
  109839. + hintedData = commandBufferLogical + hintArray[i];
  109840. +
  109841. + /* Map handle into physical address. */
  109842. + gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
  109843. + kernel, cache, (gctPOINTER) hintedData
  109844. + ));
  109845. + }
  109846. +
  109847. +OnError:
  109848. + /* Get access to the state array. */
  109849. + if (!needCopy && (hintArray != gcvNULL))
  109850. + {
  109851. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(
  109852. + Command->os,
  109853. + gcmUINT64_TO_PTR(CommandBuffer->hintArray),
  109854. + CommandBuffer->hintArraySize,
  109855. + hintArray
  109856. + ));
  109857. + }
  109858. +
  109859. + /* Return the status. */
  109860. + gcmkFOOTER();
  109861. + return status;
  109862. +}
  109863. +#endif
  109864. +
  109865. +static gceSTATUS
  109866. +_FlushMMU(
  109867. + IN gckCOMMAND Command
  109868. + )
  109869. +{
  109870. + gceSTATUS status;
  109871. + gctUINT32 oldValue;
  109872. + gckHARDWARE hardware = Command->kernel->hardware;
  109873. +
  109874. + gcmkONERROR(gckOS_AtomicExchange(Command->os,
  109875. + hardware->pageTableDirty,
  109876. + 0,
  109877. + &oldValue));
  109878. +
  109879. + if (oldValue)
  109880. + {
  109881. + /* Page Table is upated, flush mmu before commit. */
  109882. + gcmkONERROR(gckHARDWARE_FlushMMU(hardware));
  109883. + }
  109884. +
  109885. + return gcvSTATUS_OK;
  109886. +OnError:
  109887. + return status;
  109888. +}
  109889. +
  109890. +#if gcdVIRTUAL_COMMAND_BUFFER
  109891. +static void
  109892. +_DumpBuffer(
  109893. + IN gctPOINTER Buffer,
  109894. + IN gctUINT32 GpuAddress,
  109895. + IN gctSIZE_T Size
  109896. + )
  109897. +{
  109898. + gctINT i, line, left;
  109899. + gctUINT32_PTR data = Buffer;
  109900. +
  109901. + line = Size / 32;
  109902. + left = Size % 32;
  109903. +
  109904. +
  109905. + for (i = 0; i < line; i++)
  109906. + {
  109907. + gcmkPRINT("%X : %08X %08X %08X %08X %08X %08X %08X %08X ",
  109908. + GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
  109909. + data += 8;
  109910. + GpuAddress += 8 * 4;
  109911. + }
  109912. +
  109913. + switch(left)
  109914. + {
  109915. + case 28:
  109916. + gcmkPRINT("%X : %08X %08X %08X %08X %08X %08X %08X ",
  109917. + GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
  109918. + break;
  109919. + case 24:
  109920. + gcmkPRINT("%X : %08X %08X %08X %08X %08X %08X ",
  109921. + GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5]);
  109922. + break;
  109923. + case 20:
  109924. + gcmkPRINT("%X : %08X %08X %08X %08X %08X ",
  109925. + GpuAddress, data[0], data[1], data[2], data[3], data[4]);
  109926. + break;
  109927. + case 16:
  109928. + gcmkPRINT("%X : %08X %08X %08X %08X ",
  109929. + GpuAddress, data[0], data[1], data[2], data[3]);
  109930. + break;
  109931. + case 12:
  109932. + gcmkPRINT("%X : %08X %08X %08X ",
  109933. + GpuAddress, data[0], data[1], data[2]);
  109934. + break;
  109935. + case 8:
  109936. + gcmkPRINT("%X : %08X %08X ",
  109937. + GpuAddress, data[0], data[1]);
  109938. + break;
  109939. + case 4:
  109940. + gcmkPRINT("%X : %08X ",
  109941. + GpuAddress, data[0]);
  109942. + break;
  109943. + default:
  109944. + break;
  109945. + }
  109946. +}
  109947. +
  109948. +static void
  109949. +_DumpKernelCommandBuffer(
  109950. + IN gckCOMMAND Command
  109951. +)
  109952. +{
  109953. + gctINT i;
  109954. + gctUINT32 physical;
  109955. + gctPOINTER entry;
  109956. +
  109957. + for (i = 0; i < gcdCOMMAND_QUEUES; i++)
  109958. + {
  109959. + entry = Command->queues[i].logical;
  109960. +
  109961. + gckOS_GetPhysicalAddress(Command->os, entry, &physical);
  109962. +
  109963. + gcmkPRINT("Kernel command buffer %d\n", i);
  109964. +
  109965. + _DumpBuffer(entry, physical, Command->pageSize);
  109966. + }
  109967. +}
  109968. +#endif
  109969. +
  109970. +/******************************************************************************\
  109971. +****************************** gckCOMMAND API Code ******************************
  109972. +\******************************************************************************/
  109973. +
  109974. +/*******************************************************************************
  109975. +**
  109976. +** gckCOMMAND_Construct
  109977. +**
  109978. +** Construct a new gckCOMMAND object.
  109979. +**
  109980. +** INPUT:
  109981. +**
  109982. +** gckKERNEL Kernel
  109983. +** Pointer to an gckKERNEL object.
  109984. +**
  109985. +** OUTPUT:
  109986. +**
  109987. +** gckCOMMAND * Command
  109988. +** Pointer to a variable that will hold the pointer to the gckCOMMAND
  109989. +** object.
  109990. +*/
  109991. +gceSTATUS
  109992. +gckCOMMAND_Construct(
  109993. + IN gckKERNEL Kernel,
  109994. + OUT gckCOMMAND * Command
  109995. + )
  109996. +{
  109997. + gckOS os;
  109998. + gckCOMMAND command = gcvNULL;
  109999. + gceSTATUS status;
  110000. + gctINT i;
  110001. + gctPOINTER pointer = gcvNULL;
  110002. +
  110003. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  110004. +
  110005. + /* Verify the arguments. */
  110006. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  110007. + gcmkVERIFY_ARGUMENT(Command != gcvNULL);
  110008. +
  110009. + /* Extract the gckOS object. */
  110010. + os = Kernel->os;
  110011. +
  110012. + /* Allocate the gckCOMMAND structure. */
  110013. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckCOMMAND), &pointer));
  110014. + command = pointer;
  110015. +
  110016. + /* Reset the entire object. */
  110017. + gcmkONERROR(gckOS_ZeroMemory(command, gcmSIZEOF(struct _gckCOMMAND)));
  110018. +
  110019. + /* Initialize the gckCOMMAND object.*/
  110020. + command->object.type = gcvOBJ_COMMAND;
  110021. + command->kernel = Kernel;
  110022. + command->os = os;
  110023. +
  110024. + /* Get the command buffer requirements. */
  110025. + gcmkONERROR(gckHARDWARE_QueryCommandBuffer(
  110026. + Kernel->hardware,
  110027. + &command->alignment,
  110028. + &command->reservedHead,
  110029. + &command->reservedTail
  110030. + ));
  110031. +
  110032. + /* Create the command queue mutex. */
  110033. + gcmkONERROR(gckOS_CreateMutex(os, &command->mutexQueue));
  110034. +
  110035. + /* Create the context switching mutex. */
  110036. + gcmkONERROR(gckOS_CreateMutex(os, &command->mutexContext));
  110037. +
  110038. +#if VIVANTE_PROFILER_CONTEXT
  110039. + /* Create the context switching mutex. */
  110040. + gcmkONERROR(gckOS_CreateMutex(os, &command->mutexContextSeq));
  110041. +#endif
  110042. +
  110043. + /* Create the power management semaphore. */
  110044. + gcmkONERROR(gckOS_CreateSemaphore(os, &command->powerSemaphore));
  110045. +
  110046. + /* Create the commit atom. */
  110047. + gcmkONERROR(gckOS_AtomConstruct(os, &command->atomCommit));
  110048. +
  110049. + /* Get the page size from teh OS. */
  110050. + gcmkONERROR(gckOS_GetPageSize(os, &command->pageSize));
  110051. +
  110052. + /* Get process ID. */
  110053. + gcmkONERROR(gckOS_GetProcessID(&command->kernelProcessID));
  110054. +
  110055. + /* Set hardware to pipe 0. */
  110056. + command->pipeSelect = gcvPIPE_INVALID;
  110057. +
  110058. + /* Pre-allocate the command queues. */
  110059. + for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
  110060. + {
  110061. + gcmkONERROR(gckOS_AllocateNonPagedMemory(
  110062. + os,
  110063. + gcvFALSE,
  110064. + &command->pageSize,
  110065. + &command->queues[i].physical,
  110066. + &command->queues[i].logical
  110067. + ));
  110068. +
  110069. + gcmkONERROR(gckOS_CreateSignal(
  110070. + os, gcvFALSE, &command->queues[i].signal
  110071. + ));
  110072. +
  110073. + gcmkONERROR(gckOS_Signal(
  110074. + os, command->queues[i].signal, gcvTRUE
  110075. + ));
  110076. + }
  110077. +
  110078. + /* No command queue in use yet. */
  110079. + command->index = -1;
  110080. + command->logical = gcvNULL;
  110081. + command->newQueue = gcvFALSE;
  110082. +
  110083. + /* Command is not yet running. */
  110084. + command->running = gcvFALSE;
  110085. +
  110086. + /* Command queue is idle. */
  110087. + command->idle = gcvTRUE;
  110088. +
  110089. + /* Commit stamp is zero. */
  110090. + command->commitStamp = 0;
  110091. +
  110092. + /* END event signal not created. */
  110093. + command->endEventSignal = gcvNULL;
  110094. +
  110095. + /* Return pointer to the gckCOMMAND object. */
  110096. + *Command = command;
  110097. +
  110098. + /* Success. */
  110099. + gcmkFOOTER_ARG("*Command=0x%x", *Command);
  110100. + return gcvSTATUS_OK;
  110101. +
  110102. +OnError:
  110103. + /* Roll back. */
  110104. + if (command != gcvNULL)
  110105. + {
  110106. + if (command->atomCommit != gcvNULL)
  110107. + {
  110108. + gcmkVERIFY_OK(gckOS_AtomDestroy(os, command->atomCommit));
  110109. + }
  110110. +
  110111. + if (command->powerSemaphore != gcvNULL)
  110112. + {
  110113. + gcmkVERIFY_OK(gckOS_DestroySemaphore(os, command->powerSemaphore));
  110114. + }
  110115. +
  110116. + if (command->mutexContext != gcvNULL)
  110117. + {
  110118. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, command->mutexContext));
  110119. + }
  110120. +
  110121. +#if VIVANTE_PROFILER_CONTEXT
  110122. + if (command->mutexContextSeq != gcvNULL)
  110123. + {
  110124. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, command->mutexContextSeq));
  110125. + }
  110126. +#endif
  110127. +
  110128. + if (command->mutexQueue != gcvNULL)
  110129. + {
  110130. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, command->mutexQueue));
  110131. + }
  110132. +
  110133. + for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
  110134. + {
  110135. + if (command->queues[i].signal != gcvNULL)
  110136. + {
  110137. + gcmkVERIFY_OK(gckOS_DestroySignal(
  110138. + os, command->queues[i].signal
  110139. + ));
  110140. + }
  110141. +
  110142. + if (command->queues[i].logical != gcvNULL)
  110143. + {
  110144. + gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
  110145. + os,
  110146. + command->pageSize,
  110147. + command->queues[i].physical,
  110148. + command->queues[i].logical
  110149. + ));
  110150. + }
  110151. + }
  110152. +
  110153. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, command));
  110154. + }
  110155. +
  110156. + /* Return the status. */
  110157. + gcmkFOOTER();
  110158. + return status;
  110159. +}
  110160. +
  110161. +/*******************************************************************************
  110162. +**
  110163. +** gckCOMMAND_Destroy
  110164. +**
  110165. +** Destroy an gckCOMMAND object.
  110166. +**
  110167. +** INPUT:
  110168. +**
  110169. +** gckCOMMAND Command
  110170. +** Pointer to an gckCOMMAND object to destroy.
  110171. +**
  110172. +** OUTPUT:
  110173. +**
  110174. +** Nothing.
  110175. +*/
  110176. +gceSTATUS
  110177. +gckCOMMAND_Destroy(
  110178. + IN gckCOMMAND Command
  110179. + )
  110180. +{
  110181. + gctINT i;
  110182. +
  110183. + gcmkHEADER_ARG("Command=0x%x", Command);
  110184. +
  110185. + /* Verify the arguments. */
  110186. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  110187. +
  110188. + /* Stop the command queue. */
  110189. + gcmkVERIFY_OK(gckCOMMAND_Stop(Command, gcvFALSE));
  110190. +
  110191. + for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
  110192. + {
  110193. + gcmkASSERT(Command->queues[i].signal != gcvNULL);
  110194. + gcmkVERIFY_OK(gckOS_DestroySignal(
  110195. + Command->os, Command->queues[i].signal
  110196. + ));
  110197. +
  110198. + gcmkASSERT(Command->queues[i].logical != gcvNULL);
  110199. + gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
  110200. + Command->os,
  110201. + Command->pageSize,
  110202. + Command->queues[i].physical,
  110203. + Command->queues[i].logical
  110204. + ));
  110205. + }
  110206. +
  110207. + /* END event signal. */
  110208. + if (Command->endEventSignal != gcvNULL)
  110209. + {
  110210. + gcmkVERIFY_OK(gckOS_DestroySignal(
  110211. + Command->os, Command->endEventSignal
  110212. + ));
  110213. + }
  110214. +
  110215. + /* Delete the context switching mutex. */
  110216. + gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexContext));
  110217. +
  110218. +#if VIVANTE_PROFILER_CONTEXT
  110219. + if (Command->mutexContextSeq != gcvNULL)
  110220. + gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexContextSeq));
  110221. +#endif
  110222. +
  110223. + /* Delete the command queue mutex. */
  110224. + gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexQueue));
  110225. +
  110226. + /* Destroy the power management semaphore. */
  110227. + gcmkVERIFY_OK(gckOS_DestroySemaphore(Command->os, Command->powerSemaphore));
  110228. +
  110229. + /* Destroy the commit atom. */
  110230. + gcmkVERIFY_OK(gckOS_AtomDestroy(Command->os, Command->atomCommit));
  110231. +
  110232. +#if gcdSECURE_USER
  110233. + /* Free state array. */
  110234. + if (Command->hintArrayAllocated)
  110235. + {
  110236. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
  110237. + Command->hintArrayAllocated = gcvFALSE;
  110238. + }
  110239. +#endif
  110240. +
  110241. + /* Mark object as unknown. */
  110242. + Command->object.type = gcvOBJ_UNKNOWN;
  110243. +
  110244. + /* Free the gckCOMMAND object. */
  110245. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Command->os, Command));
  110246. +
  110247. + /* Success. */
  110248. + gcmkFOOTER_NO();
  110249. + return gcvSTATUS_OK;
  110250. +}
  110251. +
  110252. +/*******************************************************************************
  110253. +**
  110254. +** gckCOMMAND_EnterCommit
  110255. +**
  110256. +** Acquire command queue synchronization objects.
  110257. +**
  110258. +** INPUT:
  110259. +**
  110260. +** gckCOMMAND Command
  110261. +** Pointer to an gckCOMMAND object to destroy.
  110262. +**
  110263. +** gctBOOL FromPower
  110264. +** Determines whether the call originates from inside the power
  110265. +** management or not.
  110266. +**
  110267. +** OUTPUT:
  110268. +**
  110269. +** Nothing.
  110270. +*/
  110271. +gceSTATUS
  110272. +gckCOMMAND_EnterCommit(
  110273. + IN gckCOMMAND Command,
  110274. + IN gctBOOL FromPower
  110275. + )
  110276. +{
  110277. + gceSTATUS status;
  110278. + gckHARDWARE hardware;
  110279. + gctBOOL atomIncremented = gcvFALSE;
  110280. + gctBOOL semaAcquired = gcvFALSE;
  110281. +
  110282. + gcmkHEADER_ARG("Command=0x%x", Command);
  110283. +
  110284. + /* Extract the gckHARDWARE and gckEVENT objects. */
  110285. + hardware = Command->kernel->hardware;
  110286. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  110287. +
  110288. + if (!FromPower)
  110289. + {
  110290. + /* Increment COMMIT atom to let power management know that a commit is
  110291. + ** in progress. */
  110292. + gcmkONERROR(_IncrementCommitAtom(Command, gcvTRUE));
  110293. + atomIncremented = gcvTRUE;
  110294. +
  110295. + /* Notify the system the GPU has a commit. */
  110296. + gcmkONERROR(gckOS_Broadcast(Command->os,
  110297. + hardware,
  110298. + gcvBROADCAST_GPU_COMMIT));
  110299. +
  110300. + /* Acquire the power management semaphore. */
  110301. + gcmkONERROR(gckOS_AcquireSemaphore(Command->os,
  110302. + Command->powerSemaphore));
  110303. + semaAcquired = gcvTRUE;
  110304. + }
  110305. +
  110306. + /* Grab the conmmand queue mutex. */
  110307. + gcmkONERROR(gckOS_AcquireMutex(Command->os,
  110308. + Command->mutexQueue,
  110309. + gcvINFINITE));
  110310. +
  110311. + /* Success. */
  110312. + gcmkFOOTER();
  110313. + return gcvSTATUS_OK;
  110314. +
  110315. +OnError:
  110316. + if (semaAcquired)
  110317. + {
  110318. + /* Release the power management semaphore. */
  110319. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
  110320. + Command->os, Command->powerSemaphore
  110321. + ));
  110322. + }
  110323. +
  110324. + if (atomIncremented)
  110325. + {
  110326. + /* Decrement the commit atom. */
  110327. + gcmkVERIFY_OK(_IncrementCommitAtom(
  110328. + Command, gcvFALSE
  110329. + ));
  110330. + }
  110331. +
  110332. + /* Return the status. */
  110333. + gcmkFOOTER();
  110334. + return status;
  110335. +}
  110336. +
  110337. +/*******************************************************************************
  110338. +**
  110339. +** gckCOMMAND_ExitCommit
  110340. +**
  110341. +** Release command queue synchronization objects.
  110342. +**
  110343. +** INPUT:
  110344. +**
  110345. +** gckCOMMAND Command
  110346. +** Pointer to an gckCOMMAND object to destroy.
  110347. +**
  110348. +** gctBOOL FromPower
  110349. +** Determines whether the call originates from inside the power
  110350. +** management or not.
  110351. +**
  110352. +** OUTPUT:
  110353. +**
  110354. +** Nothing.
  110355. +*/
  110356. +gceSTATUS
  110357. +gckCOMMAND_ExitCommit(
  110358. + IN gckCOMMAND Command,
  110359. + IN gctBOOL FromPower
  110360. + )
  110361. +{
  110362. + gceSTATUS status;
  110363. +
  110364. + gcmkHEADER_ARG("Command=0x%x", Command);
  110365. +
  110366. + /* Release the power mutex. */
  110367. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexQueue));
  110368. +
  110369. + if (!FromPower)
  110370. + {
  110371. + /* Release the power management semaphore. */
  110372. + gcmkONERROR(gckOS_ReleaseSemaphore(Command->os,
  110373. + Command->powerSemaphore));
  110374. +
  110375. + /* Decrement the commit atom. */
  110376. + gcmkONERROR(_IncrementCommitAtom(Command, gcvFALSE));
  110377. + }
  110378. +
  110379. + /* Success. */
  110380. + gcmkFOOTER();
  110381. + return gcvSTATUS_OK;
  110382. +
  110383. +OnError:
  110384. + /* Return the status. */
  110385. + gcmkFOOTER();
  110386. + return status;
  110387. +}
  110388. +
  110389. +/*******************************************************************************
  110390. +**
  110391. +** gckCOMMAND_Start
  110392. +**
  110393. +** Start up the command queue.
  110394. +**
  110395. +** INPUT:
  110396. +**
  110397. +** gckCOMMAND Command
  110398. +** Pointer to an gckCOMMAND object to start.
  110399. +**
  110400. +** OUTPUT:
  110401. +**
  110402. +** Nothing.
  110403. +*/
  110404. +gceSTATUS
  110405. +gckCOMMAND_Start(
  110406. + IN gckCOMMAND Command
  110407. + )
  110408. +{
  110409. + gceSTATUS status;
  110410. + gckHARDWARE hardware;
  110411. + gctUINT32 waitOffset;
  110412. + gctSIZE_T waitLinkBytes;
  110413. +
  110414. + gcmkHEADER_ARG("Command=0x%x", Command);
  110415. +
  110416. + /* Verify the arguments. */
  110417. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  110418. +
  110419. + if (Command->running)
  110420. + {
  110421. + /* Command queue already running. */
  110422. + gcmkFOOTER_NO();
  110423. + return gcvSTATUS_OK;
  110424. + }
  110425. +
  110426. + /* Extract the gckHARDWARE object. */
  110427. + hardware = Command->kernel->hardware;
  110428. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  110429. +
  110430. + if (Command->logical == gcvNULL)
  110431. + {
  110432. + /* Start at beginning of a new queue. */
  110433. + gcmkONERROR(_NewQueue(Command));
  110434. + }
  110435. +
  110436. + /* Start at beginning of page. */
  110437. + Command->offset = 0;
  110438. +
  110439. + /* Set abvailable number of bytes for WAIT/LINK command sequence. */
  110440. + waitLinkBytes = Command->pageSize;
  110441. +
  110442. + /* Append WAIT/LINK. */
  110443. + gcmkONERROR(gckHARDWARE_WaitLink(
  110444. + hardware,
  110445. + Command->logical,
  110446. + 0,
  110447. + &waitLinkBytes,
  110448. + &waitOffset,
  110449. + &Command->waitSize
  110450. + ));
  110451. +
  110452. + Command->waitLogical = (gctUINT8_PTR) Command->logical + waitOffset;
  110453. + Command->waitPhysical = (gctUINT8_PTR) Command->physical + waitOffset;
  110454. +
  110455. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110456. + /* Flush the cache for the wait/link. */
  110457. + gcmkONERROR(gckOS_CacheClean(
  110458. + Command->os,
  110459. + Command->kernelProcessID,
  110460. + gcvNULL,
  110461. + Command->physical,
  110462. + Command->logical,
  110463. + waitLinkBytes
  110464. + ));
  110465. +#endif
  110466. +
  110467. + /* Adjust offset. */
  110468. + Command->offset = waitLinkBytes;
  110469. + Command->newQueue = gcvFALSE;
  110470. +
  110471. + /* Enable command processor. */
  110472. +#ifdef __QNXNTO__
  110473. + gcmkONERROR(gckHARDWARE_Execute(
  110474. + hardware,
  110475. + Command->logical,
  110476. + Command->physical,
  110477. + gcvTRUE,
  110478. + waitLinkBytes
  110479. + ));
  110480. +#else
  110481. + gcmkONERROR(gckHARDWARE_Execute(
  110482. + hardware,
  110483. + Command->logical,
  110484. + waitLinkBytes
  110485. + ));
  110486. +#endif
  110487. +
  110488. + /* Command queue is running. */
  110489. + Command->running = gcvTRUE;
  110490. +
  110491. + /* Success. */
  110492. + gcmkFOOTER_NO();
  110493. + return gcvSTATUS_OK;
  110494. +
  110495. +OnError:
  110496. + /* Return the status. */
  110497. + gcmkFOOTER();
  110498. + return status;
  110499. +}
  110500. +
  110501. +/*******************************************************************************
  110502. +**
  110503. +** gckCOMMAND_Stop
  110504. +**
  110505. +** Stop the command queue.
  110506. +**
  110507. +** INPUT:
  110508. +**
  110509. +** gckCOMMAND Command
  110510. +** Pointer to an gckCOMMAND object to stop.
  110511. +**
  110512. +** OUTPUT:
  110513. +**
  110514. +** Nothing.
  110515. +*/
  110516. +gceSTATUS
  110517. +gckCOMMAND_Stop(
  110518. + IN gckCOMMAND Command,
  110519. + IN gctBOOL FromRecovery
  110520. + )
  110521. +{
  110522. + gckHARDWARE hardware;
  110523. + gceSTATUS status;
  110524. + gctUINT32 idle;
  110525. +
  110526. + gcmkHEADER_ARG("Command=0x%x", Command);
  110527. +
  110528. + /* Verify the arguments. */
  110529. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  110530. +
  110531. + if (!Command->running)
  110532. + {
  110533. + /* Command queue is not running. */
  110534. + gcmkFOOTER_NO();
  110535. + return gcvSTATUS_OK;
  110536. + }
  110537. +
  110538. + /* Extract the gckHARDWARE object. */
  110539. + hardware = Command->kernel->hardware;
  110540. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  110541. +
  110542. + if (gckHARDWARE_IsFeatureAvailable(hardware,
  110543. + gcvFEATURE_END_EVENT) == gcvSTATUS_TRUE)
  110544. + {
  110545. + /* Allocate the signal. */
  110546. + if (Command->endEventSignal == gcvNULL)
  110547. + {
  110548. + gcmkONERROR(gckOS_CreateSignal(Command->os,
  110549. + gcvTRUE,
  110550. + &Command->endEventSignal));
  110551. + }
  110552. +
  110553. + /* Append the END EVENT command to trigger the signal. */
  110554. + gcmkONERROR(gckEVENT_Stop(Command->kernel->eventObj,
  110555. + Command->kernelProcessID,
  110556. + Command->waitPhysical,
  110557. + Command->waitLogical,
  110558. + Command->endEventSignal,
  110559. + &Command->waitSize));
  110560. + }
  110561. + else
  110562. + {
  110563. + /* Replace last WAIT with END. */
  110564. + gcmkONERROR(gckHARDWARE_End(
  110565. + hardware, Command->waitLogical, &Command->waitSize
  110566. + ));
  110567. +
  110568. + /* Update queue tail pointer. */
  110569. + gcmkONERROR(gckHARDWARE_UpdateQueueTail(Command->kernel->hardware,
  110570. + Command->logical,
  110571. + Command->offset));
  110572. +
  110573. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110574. + /* Flush the cache for the END. */
  110575. + gcmkONERROR(gckOS_CacheClean(
  110576. + Command->os,
  110577. + Command->kernelProcessID,
  110578. + gcvNULL,
  110579. + Command->waitPhysical,
  110580. + Command->waitLogical,
  110581. + Command->waitSize
  110582. + ));
  110583. +#endif
  110584. +
  110585. + /* Wait for idle. */
  110586. + gcmkONERROR(gckHARDWARE_GetIdle(hardware, !FromRecovery, &idle));
  110587. + }
  110588. +
  110589. + /* Command queue is no longer running. */
  110590. + Command->running = gcvFALSE;
  110591. +
  110592. + /* Success. */
  110593. + gcmkFOOTER_NO();
  110594. + return gcvSTATUS_OK;
  110595. +
  110596. +OnError:
  110597. + /* Return the status. */
  110598. + gcmkFOOTER();
  110599. + return status;
  110600. +}
  110601. +
  110602. +/*******************************************************************************
  110603. +**
  110604. +** gckCOMMAND_Commit
  110605. +**
  110606. +** Commit a command buffer to the command queue.
  110607. +**
  110608. +** INPUT:
  110609. +**
  110610. +** gckCOMMAND Command
  110611. +** Pointer to a gckCOMMAND object.
  110612. +**
  110613. +** gckCONTEXT Context
  110614. +** Pointer to a gckCONTEXT object.
  110615. +**
  110616. +** gcoCMDBUF CommandBuffer
  110617. +** Pointer to a gcoCMDBUF object.
  110618. +**
  110619. +** gcsSTATE_DELTA_PTR StateDelta
  110620. +** Pointer to the state delta.
  110621. +**
  110622. +** gctUINT32 ProcessID
  110623. +** Current process ID.
  110624. +**
  110625. +** OUTPUT:
  110626. +**
  110627. +** Nothing.
  110628. +*/
  110629. +gceSTATUS
  110630. +gckCOMMAND_Commit(
  110631. + IN gckCOMMAND Command,
  110632. + IN gckCONTEXT Context,
  110633. + IN gcoCMDBUF CommandBuffer,
  110634. + IN gcsSTATE_DELTA_PTR StateDelta,
  110635. + IN gcsQUEUE_PTR EventQueue,
  110636. + IN gctUINT32 ProcessID
  110637. + )
  110638. +{
  110639. + gceSTATUS status;
  110640. + gctBOOL commitEntered = gcvFALSE;
  110641. + gctBOOL contextAcquired = gcvFALSE;
  110642. + gckHARDWARE hardware;
  110643. + gctBOOL needCopy = gcvFALSE;
  110644. + gcsQUEUE_PTR eventRecord = gcvNULL;
  110645. + gcsQUEUE _eventRecord;
  110646. + gcsQUEUE_PTR nextEventRecord;
  110647. + gctBOOL commandBufferMapped = gcvFALSE;
  110648. + gcoCMDBUF commandBufferObject = gcvNULL;
  110649. +
  110650. +#if !gcdNULL_DRIVER
  110651. + gcsCONTEXT_PTR contextBuffer;
  110652. + struct _gcoCMDBUF _commandBufferObject;
  110653. + gctPHYS_ADDR commandBufferPhysical;
  110654. + gctUINT8_PTR commandBufferLogical;
  110655. + gctUINT8_PTR commandBufferLink;
  110656. + gctUINT commandBufferSize;
  110657. + gctSIZE_T nopBytes;
  110658. + gctSIZE_T pipeBytes;
  110659. + gctSIZE_T linkBytes;
  110660. + gctSIZE_T bytes;
  110661. + gctUINT32 offset;
  110662. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110663. + gctPHYS_ADDR entryPhysical;
  110664. +#endif
  110665. + gctPOINTER entryLogical;
  110666. + gctSIZE_T entryBytes;
  110667. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110668. + gctPHYS_ADDR exitPhysical;
  110669. +#endif
  110670. + gctPOINTER exitLogical;
  110671. + gctSIZE_T exitBytes;
  110672. + gctPHYS_ADDR waitLinkPhysical;
  110673. + gctPOINTER waitLinkLogical;
  110674. + gctSIZE_T waitLinkBytes;
  110675. + gctPHYS_ADDR waitPhysical;
  110676. + gctPOINTER waitLogical;
  110677. + gctUINT32 waitOffset;
  110678. + gctSIZE_T waitSize;
  110679. +
  110680. +#if gcdDUMP_COMMAND
  110681. + gctPOINTER contextDumpLogical = gcvNULL;
  110682. + gctSIZE_T contextDumpBytes = 0;
  110683. + gctPOINTER bufferDumpLogical = gcvNULL;
  110684. + gctSIZE_T bufferDumpBytes = 0;
  110685. +# endif
  110686. +#endif
  110687. +
  110688. +#if VIVANTE_PROFILER_CONTEXT
  110689. + gctBOOL sequenceAcquired = gcvFALSE;
  110690. +#endif
  110691. +
  110692. + gctPOINTER pointer = gcvNULL;
  110693. +
  110694. + gcmkHEADER_ARG(
  110695. + "Command=0x%x CommandBuffer=0x%x ProcessID=%d",
  110696. + Command, CommandBuffer, ProcessID
  110697. + );
  110698. +
  110699. + /* Verify the arguments. */
  110700. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  110701. +
  110702. + if (Command->kernel->core == gcvCORE_2D)
  110703. + {
  110704. + /* There is no context for 2D. */
  110705. + Context = gcvNULL;
  110706. + }
  110707. +
  110708. + gcmkONERROR(_FlushMMU(Command));
  110709. +
  110710. +#if VIVANTE_PROFILER_CONTEXT
  110711. + if((Command->kernel->hardware->gpuProfiler) && (Command->kernel->profileEnable))
  110712. + {
  110713. + /* Acquire the context sequnence mutex. */
  110714. + gcmkONERROR(gckOS_AcquireMutex(
  110715. + Command->os, Command->mutexContextSeq, gcvINFINITE
  110716. + ));
  110717. + sequenceAcquired = gcvTRUE;
  110718. + }
  110719. +#endif
  110720. +
  110721. + /* Acquire the command queue. */
  110722. + gcmkONERROR(gckCOMMAND_EnterCommit(Command, gcvFALSE));
  110723. + commitEntered = gcvTRUE;
  110724. +
  110725. + /* Acquire the context switching mutex. */
  110726. + gcmkONERROR(gckOS_AcquireMutex(
  110727. + Command->os, Command->mutexContext, gcvINFINITE
  110728. + ));
  110729. + contextAcquired = gcvTRUE;
  110730. +
  110731. + /* Extract the gckHARDWARE and gckEVENT objects. */
  110732. + hardware = Command->kernel->hardware;
  110733. +
  110734. + /* Check wehther we need to copy the structures or not. */
  110735. + gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
  110736. +
  110737. +#if gcdNULL_DRIVER
  110738. + /* Context switch required? */
  110739. + if ((Context != gcvNULL) && (Command->currContext != Context))
  110740. + {
  110741. + /* Yes, merge in the deltas. */
  110742. + gckCONTEXT_Update(Context, ProcessID, StateDelta);
  110743. +
  110744. + /* Update the current context. */
  110745. + Command->currContext = Context;
  110746. + }
  110747. +#else
  110748. + if (needCopy)
  110749. + {
  110750. + commandBufferObject = &_commandBufferObject;
  110751. +
  110752. + gcmkONERROR(gckOS_CopyFromUserData(
  110753. + Command->os,
  110754. + commandBufferObject,
  110755. + CommandBuffer,
  110756. + gcmSIZEOF(struct _gcoCMDBUF)
  110757. + ));
  110758. +
  110759. + gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
  110760. + }
  110761. + else
  110762. + {
  110763. + gcmkONERROR(gckOS_MapUserPointer(
  110764. + Command->os,
  110765. + CommandBuffer,
  110766. + gcmSIZEOF(struct _gcoCMDBUF),
  110767. + &pointer
  110768. + ));
  110769. +
  110770. + commandBufferObject = pointer;
  110771. +
  110772. + gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
  110773. + commandBufferMapped = gcvTRUE;
  110774. + }
  110775. +
  110776. + /* Query the size of NOP command. */
  110777. + gcmkONERROR(gckHARDWARE_Nop(
  110778. + hardware, gcvNULL, &nopBytes
  110779. + ));
  110780. +
  110781. + /* Query the size of pipe select command sequence. */
  110782. + gcmkONERROR(gckHARDWARE_PipeSelect(
  110783. + hardware, gcvNULL, gcvPIPE_3D, &pipeBytes
  110784. + ));
  110785. +
  110786. + /* Query the size of LINK command. */
  110787. + gcmkONERROR(gckHARDWARE_Link(
  110788. + hardware, gcvNULL, gcvNULL, 0, &linkBytes
  110789. + ));
  110790. +
  110791. + /* Compute the command buffer entry and the size. */
  110792. + commandBufferLogical
  110793. + = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
  110794. + + commandBufferObject->startOffset;
  110795. +
  110796. + gcmkONERROR(gckOS_GetPhysicalAddress(
  110797. + Command->os,
  110798. + commandBufferLogical,
  110799. + (gctUINT32_PTR)&commandBufferPhysical
  110800. + ));
  110801. +
  110802. + commandBufferSize
  110803. + = commandBufferObject->offset
  110804. + + Command->reservedTail
  110805. + - commandBufferObject->startOffset;
  110806. +
  110807. + /* Get the current offset. */
  110808. + offset = Command->offset;
  110809. +
  110810. + /* Compute number of bytes left in current kernel command queue. */
  110811. + bytes = Command->pageSize - offset;
  110812. +
  110813. + /* Query the size of WAIT/LINK command sequence. */
  110814. + gcmkONERROR(gckHARDWARE_WaitLink(
  110815. + hardware,
  110816. + gcvNULL,
  110817. + offset,
  110818. + &waitLinkBytes,
  110819. + gcvNULL,
  110820. + gcvNULL
  110821. + ));
  110822. +
  110823. + /* Is there enough space in the current command queue? */
  110824. + if (bytes < waitLinkBytes)
  110825. + {
  110826. + /* No, create a new one. */
  110827. + gcmkONERROR(_NewQueue(Command));
  110828. +
  110829. + /* Get the new current offset. */
  110830. + offset = Command->offset;
  110831. +
  110832. + /* Recompute the number of bytes in the new kernel command queue. */
  110833. + bytes = Command->pageSize - offset;
  110834. + gcmkASSERT(bytes >= waitLinkBytes);
  110835. + }
  110836. +
  110837. + /* Compute the location if WAIT/LINK command sequence. */
  110838. + waitLinkPhysical = (gctUINT8_PTR) Command->physical + offset;
  110839. + waitLinkLogical = (gctUINT8_PTR) Command->logical + offset;
  110840. +
  110841. + /* Context switch required? */
  110842. + if (Context == gcvNULL)
  110843. + {
  110844. + /* See if we have to switch pipes for the command buffer. */
  110845. + if (commandBufferObject->entryPipe == Command->pipeSelect)
  110846. + {
  110847. + /* Skip pipe switching sequence. */
  110848. + offset = pipeBytes;
  110849. + }
  110850. + else
  110851. + {
  110852. + /* The current hardware and the entry command buffer pipes
  110853. + ** are different, switch to the correct pipe. */
  110854. + gcmkONERROR(gckHARDWARE_PipeSelect(
  110855. + Command->kernel->hardware,
  110856. + commandBufferLogical,
  110857. + commandBufferObject->entryPipe,
  110858. + &pipeBytes
  110859. + ));
  110860. +
  110861. + /* Do not skip pipe switching sequence. */
  110862. + offset = 0;
  110863. + }
  110864. +
  110865. + /* Compute the entry. */
  110866. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110867. + entryPhysical = (gctUINT8_PTR) commandBufferPhysical + offset;
  110868. +#endif
  110869. + entryLogical = commandBufferLogical + offset;
  110870. + entryBytes = commandBufferSize - offset;
  110871. + }
  110872. + else if (Command->currContext != Context)
  110873. + {
  110874. + /* Temporary disable context length oprimization. */
  110875. + Context->dirty = gcvTRUE;
  110876. +
  110877. + /* Get the current context buffer. */
  110878. + contextBuffer = Context->buffer;
  110879. +
  110880. + /* Yes, merge in the deltas. */
  110881. + gcmkONERROR(gckCONTEXT_Update(Context, ProcessID, StateDelta));
  110882. +
  110883. + /* Determine context entry and exit points. */
  110884. + if (0)
  110885. + {
  110886. + /* Reset 2D dirty flag. */
  110887. + Context->dirty2D = gcvFALSE;
  110888. +
  110889. + if (Context->dirty || commandBufferObject->using3D)
  110890. + {
  110891. + /***************************************************************
  110892. + ** SWITCHING CONTEXT: 2D and 3D are used.
  110893. + */
  110894. +
  110895. + /* Reset 3D dirty flag. */
  110896. + Context->dirty3D = gcvFALSE;
  110897. +
  110898. + /* Compute the entry. */
  110899. + if (Command->pipeSelect == gcvPIPE_2D)
  110900. + {
  110901. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110902. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  110903. +#endif
  110904. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  110905. + entryBytes = Context->bufferSize - pipeBytes;
  110906. + }
  110907. + else
  110908. + {
  110909. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110910. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  110911. +#endif
  110912. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  110913. + entryBytes = Context->bufferSize;
  110914. + }
  110915. +
  110916. + /* See if we have to switch pipes between the context
  110917. + and command buffers. */
  110918. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  110919. + {
  110920. + /* Skip pipe switching sequence. */
  110921. + offset = pipeBytes;
  110922. + }
  110923. + else
  110924. + {
  110925. + /* The current hardware and the initial context pipes are
  110926. + different, switch to the correct pipe. */
  110927. + gcmkONERROR(gckHARDWARE_PipeSelect(
  110928. + Command->kernel->hardware,
  110929. + commandBufferLogical,
  110930. + commandBufferObject->entryPipe,
  110931. + &pipeBytes
  110932. + ));
  110933. +
  110934. + /* Do not skip pipe switching sequence. */
  110935. + offset = 0;
  110936. + }
  110937. +
  110938. + /* Ensure the NOP between 2D and 3D is in place so that the
  110939. + execution falls through from 2D to 3D. */
  110940. + gcmkONERROR(gckHARDWARE_Nop(
  110941. + hardware,
  110942. + contextBuffer->link2D,
  110943. + &nopBytes
  110944. + ));
  110945. +
  110946. + /* Generate a LINK from the context buffer to
  110947. + the command buffer. */
  110948. + gcmkONERROR(gckHARDWARE_Link(
  110949. + hardware,
  110950. + contextBuffer->link3D,
  110951. + commandBufferLogical + offset,
  110952. + commandBufferSize - offset,
  110953. + &linkBytes
  110954. + ));
  110955. +
  110956. + /* Mark context as not dirty. */
  110957. + Context->dirty = gcvFALSE;
  110958. + }
  110959. + else
  110960. + {
  110961. + /***************************************************************
  110962. + ** SWITCHING CONTEXT: 2D only command buffer.
  110963. + */
  110964. +
  110965. + /* Mark 3D as dirty. */
  110966. + Context->dirty3D = gcvTRUE;
  110967. +
  110968. + /* Compute the entry. */
  110969. + if (Command->pipeSelect == gcvPIPE_2D)
  110970. + {
  110971. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110972. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  110973. +#endif
  110974. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  110975. + entryBytes = Context->entryOffset3D - pipeBytes;
  110976. + }
  110977. + else
  110978. + {
  110979. +#if gcdNONPAGED_MEMORY_CACHEABLE
  110980. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  110981. +#endif
  110982. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  110983. + entryBytes = Context->entryOffset3D;
  110984. + }
  110985. +
  110986. + /* Store the current context buffer. */
  110987. + Context->dirtyBuffer = contextBuffer;
  110988. +
  110989. + /* See if we have to switch pipes between the context
  110990. + and command buffers. */
  110991. + if (commandBufferObject->entryPipe == gcvPIPE_2D)
  110992. + {
  110993. + /* Skip pipe switching sequence. */
  110994. + offset = pipeBytes;
  110995. + }
  110996. + else
  110997. + {
  110998. + /* The current hardware and the initial context pipes are
  110999. + different, switch to the correct pipe. */
  111000. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111001. + Command->kernel->hardware,
  111002. + commandBufferLogical,
  111003. + commandBufferObject->entryPipe,
  111004. + &pipeBytes
  111005. + ));
  111006. +
  111007. + /* Do not skip pipe switching sequence. */
  111008. + offset = 0;
  111009. + }
  111010. +
  111011. + /* 3D is not used, generate a LINK from the end of 2D part of
  111012. + the context buffer to the command buffer. */
  111013. + gcmkONERROR(gckHARDWARE_Link(
  111014. + hardware,
  111015. + contextBuffer->link2D,
  111016. + commandBufferLogical + offset,
  111017. + commandBufferSize - offset,
  111018. + &linkBytes
  111019. + ));
  111020. + }
  111021. + }
  111022. +
  111023. + /* Not using 2D. */
  111024. + else
  111025. + {
  111026. + /* Mark 2D as dirty. */
  111027. + Context->dirty2D = gcvTRUE;
  111028. +
  111029. + /* Store the current context buffer. */
  111030. + Context->dirtyBuffer = contextBuffer;
  111031. +
  111032. + if (Context->dirty || commandBufferObject->using3D)
  111033. + {
  111034. + /***************************************************************
  111035. + ** SWITCHING CONTEXT: 3D only command buffer.
  111036. + */
  111037. +
  111038. + /* Reset 3D dirty flag. */
  111039. + Context->dirty3D = gcvFALSE;
  111040. +
  111041. + /* Determine context buffer entry offset. */
  111042. + offset = (Command->pipeSelect == gcvPIPE_3D)
  111043. +
  111044. + /* Skip pipe switching sequence. */
  111045. + ? Context->entryOffset3D + pipeBytes
  111046. +
  111047. + /* Do not skip pipe switching sequence. */
  111048. + : Context->entryOffset3D;
  111049. +
  111050. + /* Compute the entry. */
  111051. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111052. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + offset;
  111053. +#endif
  111054. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + offset;
  111055. + entryBytes = Context->bufferSize - offset;
  111056. +
  111057. + /* See if we have to switch pipes between the context
  111058. + and command buffers. */
  111059. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  111060. + {
  111061. + /* Skip pipe switching sequence. */
  111062. + offset = pipeBytes;
  111063. + }
  111064. + else
  111065. + {
  111066. + /* The current hardware and the initial context pipes are
  111067. + different, switch to the correct pipe. */
  111068. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111069. + Command->kernel->hardware,
  111070. + commandBufferLogical,
  111071. + commandBufferObject->entryPipe,
  111072. + &pipeBytes
  111073. + ));
  111074. +
  111075. + /* Do not skip pipe switching sequence. */
  111076. + offset = 0;
  111077. + }
  111078. +
  111079. + /* Generate a LINK from the context buffer to
  111080. + the command buffer. */
  111081. + gcmkONERROR(gckHARDWARE_Link(
  111082. + hardware,
  111083. + contextBuffer->link3D,
  111084. + commandBufferLogical + offset,
  111085. + commandBufferSize - offset,
  111086. + &linkBytes
  111087. + ));
  111088. + }
  111089. + else
  111090. + {
  111091. + /***************************************************************
  111092. + ** SWITCHING CONTEXT: "XD" command buffer - neither 2D nor 3D.
  111093. + */
  111094. +
  111095. + /* Mark 3D as dirty. */
  111096. + Context->dirty3D = gcvTRUE;
  111097. +
  111098. + /* Compute the entry. */
  111099. + if (Command->pipeSelect == gcvPIPE_3D)
  111100. + {
  111101. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111102. + entryPhysical
  111103. + = (gctUINT8_PTR) contextBuffer->physical
  111104. + + Context->entryOffsetXDFrom3D;
  111105. +#endif
  111106. + entryLogical
  111107. + = (gctUINT8_PTR) contextBuffer->logical
  111108. + + Context->entryOffsetXDFrom3D;
  111109. +
  111110. + entryBytes
  111111. + = Context->bufferSize
  111112. + - Context->entryOffsetXDFrom3D;
  111113. + }
  111114. + else
  111115. + {
  111116. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111117. + entryPhysical
  111118. + = (gctUINT8_PTR) contextBuffer->physical
  111119. + + Context->entryOffsetXDFrom2D;
  111120. +#endif
  111121. + entryLogical
  111122. + = (gctUINT8_PTR) contextBuffer->logical
  111123. + + Context->entryOffsetXDFrom2D;
  111124. +
  111125. + entryBytes
  111126. + = Context->totalSize
  111127. + - Context->entryOffsetXDFrom2D;
  111128. + }
  111129. +
  111130. + /* See if we have to switch pipes between the context
  111131. + and command buffers. */
  111132. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  111133. + {
  111134. + /* Skip pipe switching sequence. */
  111135. + offset = pipeBytes;
  111136. + }
  111137. + else
  111138. + {
  111139. + /* The current hardware and the initial context pipes are
  111140. + different, switch to the correct pipe. */
  111141. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111142. + Command->kernel->hardware,
  111143. + commandBufferLogical,
  111144. + commandBufferObject->entryPipe,
  111145. + &pipeBytes
  111146. + ));
  111147. +
  111148. + /* Do not skip pipe switching sequence. */
  111149. + offset = 0;
  111150. + }
  111151. +
  111152. + /* Generate a LINK from the context buffer to
  111153. + the command buffer. */
  111154. + gcmkONERROR(gckHARDWARE_Link(
  111155. + hardware,
  111156. + contextBuffer->link3D,
  111157. + commandBufferLogical + offset,
  111158. + commandBufferSize - offset,
  111159. + &linkBytes
  111160. + ));
  111161. + }
  111162. + }
  111163. +
  111164. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111165. + /* Flush the context buffer cache. */
  111166. + gcmkONERROR(gckOS_CacheClean(
  111167. + Command->os,
  111168. + Command->kernelProcessID,
  111169. + gcvNULL,
  111170. + entryPhysical,
  111171. + entryLogical,
  111172. + entryBytes
  111173. + ));
  111174. +#endif
  111175. +
  111176. + /* Update the current context. */
  111177. + Command->currContext = Context;
  111178. +
  111179. +#if gcdDUMP_COMMAND
  111180. + contextDumpLogical = entryLogical;
  111181. + contextDumpBytes = entryBytes;
  111182. +#endif
  111183. + }
  111184. +
  111185. + /* Same context. */
  111186. + else
  111187. + {
  111188. + /* Determine context entry and exit points. */
  111189. + if (commandBufferObject->using2D && Context->dirty2D)
  111190. + {
  111191. + /* Reset 2D dirty flag. */
  111192. + Context->dirty2D = gcvFALSE;
  111193. +
  111194. + /* Get the "dirty" context buffer. */
  111195. + contextBuffer = Context->dirtyBuffer;
  111196. +
  111197. + if (commandBufferObject->using3D && Context->dirty3D)
  111198. + {
  111199. + /* Reset 3D dirty flag. */
  111200. + Context->dirty3D = gcvFALSE;
  111201. +
  111202. + /* Compute the entry. */
  111203. + if (Command->pipeSelect == gcvPIPE_2D)
  111204. + {
  111205. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111206. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  111207. +#endif
  111208. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  111209. + entryBytes = Context->bufferSize - pipeBytes;
  111210. + }
  111211. + else
  111212. + {
  111213. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111214. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  111215. +#endif
  111216. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  111217. + entryBytes = Context->bufferSize;
  111218. + }
  111219. +
  111220. + /* See if we have to switch pipes between the context
  111221. + and command buffers. */
  111222. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  111223. + {
  111224. + /* Skip pipe switching sequence. */
  111225. + offset = pipeBytes;
  111226. + }
  111227. + else
  111228. + {
  111229. + /* The current hardware and the initial context pipes are
  111230. + different, switch to the correct pipe. */
  111231. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111232. + Command->kernel->hardware,
  111233. + commandBufferLogical,
  111234. + commandBufferObject->entryPipe,
  111235. + &pipeBytes
  111236. + ));
  111237. +
  111238. + /* Do not skip pipe switching sequence. */
  111239. + offset = 0;
  111240. + }
  111241. +
  111242. + /* Ensure the NOP between 2D and 3D is in place so that the
  111243. + execution falls through from 2D to 3D. */
  111244. + gcmkONERROR(gckHARDWARE_Nop(
  111245. + hardware,
  111246. + contextBuffer->link2D,
  111247. + &nopBytes
  111248. + ));
  111249. +
  111250. + /* Generate a LINK from the context buffer to
  111251. + the command buffer. */
  111252. + gcmkONERROR(gckHARDWARE_Link(
  111253. + hardware,
  111254. + contextBuffer->link3D,
  111255. + commandBufferLogical + offset,
  111256. + commandBufferSize - offset,
  111257. + &linkBytes
  111258. + ));
  111259. + }
  111260. + else
  111261. + {
  111262. + /* Compute the entry. */
  111263. + if (Command->pipeSelect == gcvPIPE_2D)
  111264. + {
  111265. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111266. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  111267. +#endif
  111268. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  111269. + entryBytes = Context->entryOffset3D - pipeBytes;
  111270. + }
  111271. + else
  111272. + {
  111273. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111274. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  111275. +#endif
  111276. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  111277. + entryBytes = Context->entryOffset3D;
  111278. + }
  111279. +
  111280. + /* See if we have to switch pipes between the context
  111281. + and command buffers. */
  111282. + if (commandBufferObject->entryPipe == gcvPIPE_2D)
  111283. + {
  111284. + /* Skip pipe switching sequence. */
  111285. + offset = pipeBytes;
  111286. + }
  111287. + else
  111288. + {
  111289. + /* The current hardware and the initial context pipes are
  111290. + different, switch to the correct pipe. */
  111291. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111292. + Command->kernel->hardware,
  111293. + commandBufferLogical,
  111294. + commandBufferObject->entryPipe,
  111295. + &pipeBytes
  111296. + ));
  111297. +
  111298. + /* Do not skip pipe switching sequence. */
  111299. + offset = 0;
  111300. + }
  111301. +
  111302. + /* 3D is not used, generate a LINK from the end of 2D part of
  111303. + the context buffer to the command buffer. */
  111304. + gcmkONERROR(gckHARDWARE_Link(
  111305. + hardware,
  111306. + contextBuffer->link2D,
  111307. + commandBufferLogical + offset,
  111308. + commandBufferSize - offset,
  111309. + &linkBytes
  111310. + ));
  111311. + }
  111312. + }
  111313. + else
  111314. + {
  111315. + if (commandBufferObject->using3D && Context->dirty3D)
  111316. + {
  111317. + /* Reset 3D dirty flag. */
  111318. + Context->dirty3D = gcvFALSE;
  111319. +
  111320. + /* Get the "dirty" context buffer. */
  111321. + contextBuffer = Context->dirtyBuffer;
  111322. +
  111323. + /* Determine context buffer entry offset. */
  111324. + offset = (Command->pipeSelect == gcvPIPE_3D)
  111325. +
  111326. + /* Skip pipe switching sequence. */
  111327. + ? Context->entryOffset3D + pipeBytes
  111328. +
  111329. + /* Do not skip pipe switching sequence. */
  111330. + : Context->entryOffset3D;
  111331. +
  111332. + /* Compute the entry. */
  111333. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111334. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + offset;
  111335. +#endif
  111336. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + offset;
  111337. + entryBytes = Context->bufferSize - offset;
  111338. +
  111339. + /* See if we have to switch pipes between the context
  111340. + and command buffers. */
  111341. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  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. + /* Generate a LINK from the context buffer to
  111362. + the command buffer. */
  111363. + gcmkONERROR(gckHARDWARE_Link(
  111364. + hardware,
  111365. + contextBuffer->link3D,
  111366. + commandBufferLogical + offset,
  111367. + commandBufferSize - offset,
  111368. + &linkBytes
  111369. + ));
  111370. + }
  111371. + else
  111372. + {
  111373. + /* See if we have to switch pipes for the command buffer. */
  111374. + if (commandBufferObject->entryPipe == Command->pipeSelect)
  111375. + {
  111376. + /* Skip pipe switching sequence. */
  111377. + offset = pipeBytes;
  111378. + }
  111379. + else
  111380. + {
  111381. + /* The current hardware and the entry command buffer pipes
  111382. + ** are different, switch to the correct pipe. */
  111383. + gcmkONERROR(gckHARDWARE_PipeSelect(
  111384. + Command->kernel->hardware,
  111385. + commandBufferLogical,
  111386. + commandBufferObject->entryPipe,
  111387. + &pipeBytes
  111388. + ));
  111389. +
  111390. + /* Do not skip pipe switching sequence. */
  111391. + offset = 0;
  111392. + }
  111393. +
  111394. + /* Compute the entry. */
  111395. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111396. + entryPhysical = (gctUINT8_PTR) commandBufferPhysical + offset;
  111397. +#endif
  111398. + entryLogical = commandBufferLogical + offset;
  111399. + entryBytes = commandBufferSize - offset;
  111400. + }
  111401. + }
  111402. + }
  111403. +
  111404. +#if gcdDUMP_COMMAND
  111405. + bufferDumpLogical = commandBufferLogical + offset;
  111406. + bufferDumpBytes = commandBufferSize - offset;
  111407. +#endif
  111408. +
  111409. +#if gcdSECURE_USER
  111410. + /* Process user hints. */
  111411. + gcmkONERROR(_ProcessHints(Command, ProcessID, commandBufferObject));
  111412. +#endif
  111413. +
  111414. + /* Determine the location to jump to for the command buffer being
  111415. + ** scheduled. */
  111416. + if (Command->newQueue)
  111417. + {
  111418. + /* New command queue, jump to the beginning of it. */
  111419. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111420. + exitPhysical = Command->physical;
  111421. +#endif
  111422. + exitLogical = Command->logical;
  111423. + exitBytes = Command->offset + waitLinkBytes;
  111424. + }
  111425. + else
  111426. + {
  111427. + /* Still within the preexisting command queue, jump to the new
  111428. + WAIT/LINK command sequence. */
  111429. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111430. + exitPhysical = waitLinkPhysical;
  111431. +#endif
  111432. + exitLogical = waitLinkLogical;
  111433. + exitBytes = waitLinkBytes;
  111434. + }
  111435. +
  111436. + /* Add a new WAIT/LINK command sequence. When the command buffer which is
  111437. + currently being scheduled is fully executed by the GPU, the FE will
  111438. + jump to this WAIT/LINK sequence. */
  111439. + gcmkONERROR(gckHARDWARE_WaitLink(
  111440. + hardware,
  111441. + waitLinkLogical,
  111442. + offset,
  111443. + &waitLinkBytes,
  111444. + &waitOffset,
  111445. + &waitSize
  111446. + ));
  111447. +
  111448. + /* Compute the location if WAIT command. */
  111449. + waitPhysical = (gctUINT8_PTR) waitLinkPhysical + waitOffset;
  111450. + waitLogical = (gctUINT8_PTR) waitLinkLogical + waitOffset;
  111451. +
  111452. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111453. + /* Flush the command queue cache. */
  111454. + gcmkONERROR(gckOS_CacheClean(
  111455. + Command->os,
  111456. + Command->kernelProcessID,
  111457. + gcvNULL,
  111458. + exitPhysical,
  111459. + exitLogical,
  111460. + exitBytes
  111461. + ));
  111462. +#endif
  111463. +
  111464. + /* Determine the location of the LINK command in the command buffer. */
  111465. + commandBufferLink
  111466. + = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
  111467. + + commandBufferObject->offset;
  111468. +
  111469. + /* Generate a LINK from the end of the command buffer being scheduled
  111470. + back to the kernel command queue. */
  111471. + gcmkONERROR(gckHARDWARE_Link(
  111472. + hardware,
  111473. + commandBufferLink,
  111474. + exitLogical,
  111475. + exitBytes,
  111476. + &linkBytes
  111477. + ));
  111478. +
  111479. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111480. + /* Flush the command buffer cache. */
  111481. + gcmkONERROR(gckOS_CacheClean(
  111482. + Command->os,
  111483. + ProcessID,
  111484. + gcvNULL,
  111485. + commandBufferPhysical,
  111486. + commandBufferLogical,
  111487. + commandBufferSize
  111488. + ));
  111489. +#endif
  111490. +
  111491. + /* Generate a LINK from the previous WAIT/LINK command sequence to the
  111492. + entry determined above (either the context or the command buffer).
  111493. + This LINK replaces the WAIT instruction from the previous WAIT/LINK
  111494. + pair, therefore we use WAIT metrics for generation of this LINK.
  111495. + This action will execute the entire sequence. */
  111496. + gcmkONERROR(gckHARDWARE_Link(
  111497. + hardware,
  111498. + Command->waitLogical,
  111499. + entryLogical,
  111500. + entryBytes,
  111501. + &Command->waitSize
  111502. + ));
  111503. +
  111504. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111505. + /* Flush the cache for the link. */
  111506. + gcmkONERROR(gckOS_CacheClean(
  111507. + Command->os,
  111508. + Command->kernelProcessID,
  111509. + gcvNULL,
  111510. + Command->waitPhysical,
  111511. + Command->waitLogical,
  111512. + Command->waitSize
  111513. + ));
  111514. +#endif
  111515. +
  111516. + gcmkDUMPCOMMAND(
  111517. + Command->os,
  111518. + Command->waitLogical,
  111519. + Command->waitSize,
  111520. + gceDUMP_BUFFER_LINK,
  111521. + gcvFALSE
  111522. + );
  111523. +
  111524. + gcmkDUMPCOMMAND(
  111525. + Command->os,
  111526. + contextDumpLogical,
  111527. + contextDumpBytes,
  111528. + gceDUMP_BUFFER_CONTEXT,
  111529. + gcvFALSE
  111530. + );
  111531. +
  111532. + gcmkDUMPCOMMAND(
  111533. + Command->os,
  111534. + bufferDumpLogical,
  111535. + bufferDumpBytes,
  111536. + gceDUMP_BUFFER_USER,
  111537. + gcvFALSE
  111538. + );
  111539. +
  111540. + gcmkDUMPCOMMAND(
  111541. + Command->os,
  111542. + waitLinkLogical,
  111543. + waitLinkBytes,
  111544. + gceDUMP_BUFFER_WAITLINK,
  111545. + gcvFALSE
  111546. + );
  111547. +
  111548. + /* Update the current pipe. */
  111549. + Command->pipeSelect = commandBufferObject->exitPipe;
  111550. +
  111551. + /* Update command queue offset. */
  111552. + Command->offset += waitLinkBytes;
  111553. + Command->newQueue = gcvFALSE;
  111554. +
  111555. + /* Update address of last WAIT. */
  111556. + Command->waitPhysical = waitPhysical;
  111557. + Command->waitLogical = waitLogical;
  111558. + Command->waitSize = waitSize;
  111559. +
  111560. + /* Update queue tail pointer. */
  111561. + gcmkONERROR(gckHARDWARE_UpdateQueueTail(
  111562. + hardware, Command->logical, Command->offset
  111563. + ));
  111564. +
  111565. +#if gcdDUMP_COMMAND
  111566. + gcmkPRINT("@[kernel.commit]");
  111567. +#endif
  111568. +#endif /* gcdNULL_DRIVER */
  111569. +
  111570. + /* Release the context switching mutex. */
  111571. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  111572. + contextAcquired = gcvFALSE;
  111573. +
  111574. + /* Release the command queue. */
  111575. + gcmkONERROR(gckCOMMAND_ExitCommit(Command, gcvFALSE));
  111576. + commitEntered = gcvFALSE;
  111577. +
  111578. +#if VIVANTE_PROFILER_CONTEXT
  111579. + if(sequenceAcquired)
  111580. + {
  111581. + gcmkONERROR(gckCOMMAND_Stall(Command, gcvTRUE));
  111582. + if (Command->currContext)
  111583. + {
  111584. + gcmkONERROR(gckHARDWARE_UpdateContextProfile(
  111585. + hardware,
  111586. + Command->currContext));
  111587. + }
  111588. +
  111589. + /* Release the context switching mutex. */
  111590. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContextSeq));
  111591. + sequenceAcquired = gcvFALSE;
  111592. + }
  111593. +#endif
  111594. +
  111595. + /* Loop while there are records in the queue. */
  111596. + while (EventQueue != gcvNULL)
  111597. + {
  111598. + if (needCopy)
  111599. + {
  111600. + /* Point to stack record. */
  111601. + eventRecord = &_eventRecord;
  111602. +
  111603. + /* Copy the data from the client. */
  111604. + gcmkONERROR(gckOS_CopyFromUserData(
  111605. + Command->os, eventRecord, EventQueue, gcmSIZEOF(gcsQUEUE)
  111606. + ));
  111607. + }
  111608. + else
  111609. + {
  111610. + /* Map record into kernel memory. */
  111611. + gcmkONERROR(gckOS_MapUserPointer(Command->os,
  111612. + EventQueue,
  111613. + gcmSIZEOF(gcsQUEUE),
  111614. + &pointer));
  111615. +
  111616. + eventRecord = pointer;
  111617. + }
  111618. +
  111619. + /* Append event record to event queue. */
  111620. + gcmkONERROR(gckEVENT_AddList(
  111621. + Command->kernel->eventObj, &eventRecord->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE
  111622. + ));
  111623. +
  111624. + /* Next record in the queue. */
  111625. + nextEventRecord = gcmUINT64_TO_PTR(eventRecord->next);
  111626. +
  111627. + if (!needCopy)
  111628. + {
  111629. + /* Unmap record from kernel memory. */
  111630. + gcmkONERROR(gckOS_UnmapUserPointer(
  111631. + Command->os, EventQueue, gcmSIZEOF(gcsQUEUE), (gctPOINTER *) eventRecord
  111632. + ));
  111633. +
  111634. + eventRecord = gcvNULL;
  111635. + }
  111636. +
  111637. + EventQueue = nextEventRecord;
  111638. + }
  111639. +
  111640. + if (Command->kernel->eventObj->queueHead == gcvNULL
  111641. + && Command->kernel->hardware->powerManagement == gcvTRUE
  111642. + )
  111643. + {
  111644. + /* Commit done event by which work thread knows all jobs done. */
  111645. + gcmkVERIFY_OK(
  111646. + gckEVENT_CommitDone(Command->kernel->eventObj, gcvKERNEL_PIXEL));
  111647. + }
  111648. +
  111649. + /* Submit events. */
  111650. + status = gckEVENT_Submit(Command->kernel->eventObj, gcvTRUE, gcvFALSE);
  111651. +
  111652. + if (status == gcvSTATUS_INTERRUPTED)
  111653. + {
  111654. + gcmkTRACE(
  111655. + gcvLEVEL_INFO,
  111656. + "%s(%d): Intterupted in gckEVENT_Submit",
  111657. + __FUNCTION__, __LINE__
  111658. + );
  111659. + status = gcvSTATUS_OK;
  111660. + }
  111661. + else
  111662. + {
  111663. + gcmkONERROR(status);
  111664. + }
  111665. +
  111666. + /* Unmap the command buffer pointer. */
  111667. + if (commandBufferMapped)
  111668. + {
  111669. + gcmkONERROR(gckOS_UnmapUserPointer(
  111670. + Command->os,
  111671. + CommandBuffer,
  111672. + gcmSIZEOF(struct _gcoCMDBUF),
  111673. + commandBufferObject
  111674. + ));
  111675. +
  111676. + commandBufferMapped = gcvFALSE;
  111677. + }
  111678. +
  111679. + /* Return status. */
  111680. + gcmkFOOTER();
  111681. + return gcvSTATUS_OK;
  111682. +
  111683. +OnError:
  111684. + if ((eventRecord != gcvNULL) && !needCopy)
  111685. + {
  111686. + /* Roll back. */
  111687. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(
  111688. + Command->os,
  111689. + EventQueue,
  111690. + gcmSIZEOF(gcsQUEUE),
  111691. + (gctPOINTER *) eventRecord
  111692. + ));
  111693. + }
  111694. +
  111695. + if (contextAcquired)
  111696. + {
  111697. + /* Release the context switching mutex. */
  111698. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  111699. + }
  111700. +
  111701. + if (commitEntered)
  111702. + {
  111703. + /* Release the command queue mutex. */
  111704. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Command, gcvFALSE));
  111705. + }
  111706. +
  111707. +#if VIVANTE_PROFILER_CONTEXT
  111708. + if (sequenceAcquired)
  111709. + {
  111710. + /* Release the context sequence mutex. */
  111711. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContextSeq));
  111712. + }
  111713. +#endif
  111714. +
  111715. + /* Unmap the command buffer pointer. */
  111716. + if (commandBufferMapped)
  111717. + {
  111718. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(
  111719. + Command->os,
  111720. + CommandBuffer,
  111721. + gcmSIZEOF(struct _gcoCMDBUF),
  111722. + commandBufferObject
  111723. + ));
  111724. + }
  111725. +
  111726. + /* Return status. */
  111727. + gcmkFOOTER();
  111728. + return status;
  111729. +}
  111730. +
  111731. +/*******************************************************************************
  111732. +**
  111733. +** gckCOMMAND_Reserve
  111734. +**
  111735. +** Reserve space in the command queue. Also acquire the command queue mutex.
  111736. +**
  111737. +** INPUT:
  111738. +**
  111739. +** gckCOMMAND Command
  111740. +** Pointer to an gckCOMMAND object.
  111741. +**
  111742. +** gctSIZE_T RequestedBytes
  111743. +** Number of bytes previously reserved.
  111744. +**
  111745. +** OUTPUT:
  111746. +**
  111747. +** gctPOINTER * Buffer
  111748. +** Pointer to a variable that will receive the address of the reserved
  111749. +** space.
  111750. +**
  111751. +** gctSIZE_T * BufferSize
  111752. +** Pointer to a variable that will receive the number of bytes
  111753. +** available in the command queue.
  111754. +*/
  111755. +gceSTATUS
  111756. +gckCOMMAND_Reserve(
  111757. + IN gckCOMMAND Command,
  111758. + IN gctSIZE_T RequestedBytes,
  111759. + OUT gctPOINTER * Buffer,
  111760. + OUT gctSIZE_T * BufferSize
  111761. + )
  111762. +{
  111763. + gceSTATUS status;
  111764. + gctSIZE_T bytes;
  111765. + gctSIZE_T requiredBytes;
  111766. + gctUINT32 requestedAligned;
  111767. +
  111768. + gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
  111769. +
  111770. + /* Verify the arguments. */
  111771. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  111772. +
  111773. + /* Compute aligned number of reuested bytes. */
  111774. + requestedAligned = gcmALIGN(RequestedBytes, Command->alignment);
  111775. +
  111776. + /* Another WAIT/LINK command sequence will have to be appended after
  111777. + the requested area being reserved. Compute the number of bytes
  111778. + required for WAIT/LINK at the location after the reserved area. */
  111779. + gcmkONERROR(gckHARDWARE_WaitLink(
  111780. + Command->kernel->hardware,
  111781. + gcvNULL,
  111782. + Command->offset + requestedAligned,
  111783. + &requiredBytes,
  111784. + gcvNULL,
  111785. + gcvNULL
  111786. + ));
  111787. +
  111788. + /* Compute total number of bytes required. */
  111789. + requiredBytes += requestedAligned;
  111790. +
  111791. + /* Compute number of bytes available in command queue. */
  111792. + bytes = Command->pageSize - Command->offset;
  111793. +
  111794. + /* Is there enough space in the current command queue? */
  111795. + if (bytes < requiredBytes)
  111796. + {
  111797. + /* Create a new command queue. */
  111798. + gcmkONERROR(_NewQueue(Command));
  111799. +
  111800. + /* Recompute the number of bytes in the new kernel command queue. */
  111801. + bytes = Command->pageSize - Command->offset;
  111802. +
  111803. + /* Still not enough space? */
  111804. + if (bytes < requiredBytes)
  111805. + {
  111806. + /* Rare case, not enough room in command queue. */
  111807. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  111808. + }
  111809. + }
  111810. +
  111811. + /* Return pointer to empty slot command queue. */
  111812. + *Buffer = (gctUINT8 *) Command->logical + Command->offset;
  111813. +
  111814. + /* Return number of bytes left in command queue. */
  111815. + *BufferSize = bytes;
  111816. +
  111817. + /* Success. */
  111818. + gcmkFOOTER_ARG("*Buffer=0x%x *BufferSize=%lu", *Buffer, *BufferSize);
  111819. + return gcvSTATUS_OK;
  111820. +
  111821. +OnError:
  111822. + /* Return status. */
  111823. + gcmkFOOTER();
  111824. + return status;
  111825. +}
  111826. +
  111827. +/*******************************************************************************
  111828. +**
  111829. +** gckCOMMAND_Execute
  111830. +**
  111831. +** Execute a previously reserved command queue by appending a WAIT/LINK command
  111832. +** sequence after it and modifying the last WAIT into a LINK command. The
  111833. +** command FIFO mutex will be released whether this function succeeds or not.
  111834. +**
  111835. +** INPUT:
  111836. +**
  111837. +** gckCOMMAND Command
  111838. +** Pointer to an gckCOMMAND object.
  111839. +**
  111840. +** gctSIZE_T RequestedBytes
  111841. +** Number of bytes previously reserved.
  111842. +**
  111843. +** OUTPUT:
  111844. +**
  111845. +** Nothing.
  111846. +*/
  111847. +gceSTATUS
  111848. +gckCOMMAND_Execute(
  111849. + IN gckCOMMAND Command,
  111850. + IN gctSIZE_T RequestedBytes
  111851. + )
  111852. +{
  111853. + gceSTATUS status;
  111854. +
  111855. + gctPHYS_ADDR waitLinkPhysical;
  111856. + gctUINT8_PTR waitLinkLogical;
  111857. + gctUINT32 waitLinkOffset;
  111858. + gctSIZE_T waitLinkBytes;
  111859. +
  111860. + gctPHYS_ADDR waitPhysical;
  111861. + gctPOINTER waitLogical;
  111862. + gctUINT32 waitOffset;
  111863. + gctSIZE_T waitBytes;
  111864. +
  111865. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111866. + gctPHYS_ADDR execPhysical;
  111867. +#endif
  111868. + gctPOINTER execLogical;
  111869. + gctSIZE_T execBytes;
  111870. +
  111871. + gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
  111872. +
  111873. + /* Verify the arguments. */
  111874. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  111875. +
  111876. + /* Compute offset for WAIT/LINK. */
  111877. + waitLinkOffset = Command->offset + RequestedBytes;
  111878. +
  111879. + /* Compute number of bytes left in command queue. */
  111880. + waitLinkBytes = Command->pageSize - waitLinkOffset;
  111881. +
  111882. + /* Compute the location if WAIT/LINK command sequence. */
  111883. + waitLinkPhysical = (gctUINT8_PTR) Command->physical + waitLinkOffset;
  111884. + waitLinkLogical = (gctUINT8_PTR) Command->logical + waitLinkOffset;
  111885. +
  111886. + /* Append WAIT/LINK in command queue. */
  111887. + gcmkONERROR(gckHARDWARE_WaitLink(
  111888. + Command->kernel->hardware,
  111889. + waitLinkLogical,
  111890. + waitLinkOffset,
  111891. + &waitLinkBytes,
  111892. + &waitOffset,
  111893. + &waitBytes
  111894. + ));
  111895. +
  111896. + /* Compute the location if WAIT command. */
  111897. + waitPhysical = (gctUINT8_PTR) waitLinkPhysical + waitOffset;
  111898. + waitLogical = waitLinkLogical + waitOffset;
  111899. +
  111900. + /* Determine the location to jump to for the command buffer being
  111901. + ** scheduled. */
  111902. + if (Command->newQueue)
  111903. + {
  111904. + /* New command queue, jump to the beginning of it. */
  111905. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111906. + execPhysical = Command->physical;
  111907. +#endif
  111908. + execLogical = Command->logical;
  111909. + execBytes = waitLinkOffset + waitLinkBytes;
  111910. + }
  111911. + else
  111912. + {
  111913. + /* Still within the preexisting command queue, jump directly to the
  111914. + reserved area. */
  111915. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111916. + execPhysical = (gctUINT8 *) Command->physical + Command->offset;
  111917. +#endif
  111918. + execLogical = (gctUINT8 *) Command->logical + Command->offset;
  111919. + execBytes = RequestedBytes + waitLinkBytes;
  111920. + }
  111921. +
  111922. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111923. + /* Flush the cache. */
  111924. + gcmkONERROR(gckOS_CacheClean(
  111925. + Command->os,
  111926. + Command->kernelProcessID,
  111927. + gcvNULL,
  111928. + execPhysical,
  111929. + execLogical,
  111930. + execBytes
  111931. + ));
  111932. +#endif
  111933. +
  111934. + /* Convert the last WAIT into a LINK. */
  111935. + gcmkONERROR(gckHARDWARE_Link(
  111936. + Command->kernel->hardware,
  111937. + Command->waitLogical,
  111938. + execLogical,
  111939. + execBytes,
  111940. + &Command->waitSize
  111941. + ));
  111942. +
  111943. +#if gcdNONPAGED_MEMORY_CACHEABLE
  111944. + /* Flush the cache. */
  111945. + gcmkONERROR(gckOS_CacheClean(
  111946. + Command->os,
  111947. + Command->kernelProcessID,
  111948. + gcvNULL,
  111949. + Command->waitPhysical,
  111950. + Command->waitLogical,
  111951. + Command->waitSize
  111952. + ));
  111953. +#endif
  111954. +
  111955. + gcmkDUMPCOMMAND(
  111956. + Command->os,
  111957. + Command->waitLogical,
  111958. + Command->waitSize,
  111959. + gceDUMP_BUFFER_LINK,
  111960. + gcvFALSE
  111961. + );
  111962. +
  111963. + gcmkDUMPCOMMAND(
  111964. + Command->os,
  111965. + execLogical,
  111966. + execBytes,
  111967. + gceDUMP_BUFFER_KERNEL,
  111968. + gcvFALSE
  111969. + );
  111970. +
  111971. + /* Update the pointer to the last WAIT. */
  111972. + Command->waitPhysical = waitPhysical;
  111973. + Command->waitLogical = waitLogical;
  111974. + Command->waitSize = waitBytes;
  111975. +
  111976. + /* Update the command queue. */
  111977. + Command->offset += RequestedBytes + waitLinkBytes;
  111978. + Command->newQueue = gcvFALSE;
  111979. +
  111980. + /* Update queue tail pointer. */
  111981. + gcmkONERROR(gckHARDWARE_UpdateQueueTail(
  111982. + Command->kernel->hardware, Command->logical, Command->offset
  111983. + ));
  111984. +
  111985. +#if gcdDUMP_COMMAND
  111986. + gcmkPRINT("@[kernel.execute]");
  111987. +#endif
  111988. +
  111989. + /* Success. */
  111990. + gcmkFOOTER_NO();
  111991. + return gcvSTATUS_OK;
  111992. +
  111993. +OnError:
  111994. + /* Return the status. */
  111995. + gcmkFOOTER();
  111996. + return status;
  111997. +}
  111998. +
  111999. +/*******************************************************************************
  112000. +**
  112001. +** gckCOMMAND_Stall
  112002. +**
  112003. +** The calling thread will be suspended until the command queue has been
  112004. +** completed.
  112005. +**
  112006. +** INPUT:
  112007. +**
  112008. +** gckCOMMAND Command
  112009. +** Pointer to an gckCOMMAND object.
  112010. +**
  112011. +** gctBOOL FromPower
  112012. +** Determines whether the call originates from inside the power
  112013. +** management or not.
  112014. +**
  112015. +** OUTPUT:
  112016. +**
  112017. +** Nothing.
  112018. +*/
  112019. +gceSTATUS
  112020. +gckCOMMAND_Stall(
  112021. + IN gckCOMMAND Command,
  112022. + IN gctBOOL FromPower
  112023. + )
  112024. +{
  112025. +#if gcdNULL_DRIVER
  112026. + /* Do nothing with infinite hardware. */
  112027. + return gcvSTATUS_OK;
  112028. +#else
  112029. + gckOS os;
  112030. + gckHARDWARE hardware;
  112031. + gckEVENT eventObject;
  112032. + gceSTATUS status;
  112033. + gctSIGNAL signal = gcvNULL;
  112034. + gctUINT timer = 0;
  112035. +
  112036. + gcmkHEADER_ARG("Command=0x%x", Command);
  112037. +
  112038. + /* Verify the arguments. */
  112039. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  112040. +
  112041. + /* Extract the gckOS object pointer. */
  112042. + os = Command->os;
  112043. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  112044. +
  112045. + /* Extract the gckHARDWARE object pointer. */
  112046. + hardware = Command->kernel->hardware;
  112047. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  112048. +
  112049. + /* Extract the gckEVENT object pointer. */
  112050. + eventObject = Command->kernel->eventObj;
  112051. + gcmkVERIFY_OBJECT(eventObject, gcvOBJ_EVENT);
  112052. +
  112053. + /* Allocate the signal. */
  112054. + gcmkONERROR(gckOS_CreateSignal(os, gcvTRUE, &signal));
  112055. +
  112056. + /* Append the EVENT command to trigger the signal. */
  112057. + gcmkONERROR(gckEVENT_Signal(eventObject, signal, gcvKERNEL_PIXEL));
  112058. +
  112059. + /* Submit the event queue. */
  112060. + gcmkONERROR(gckEVENT_Submit(eventObject, gcvTRUE, FromPower));
  112061. +
  112062. +#if gcdDUMP_COMMAND
  112063. + gcmkPRINT("@[kernel.stall]");
  112064. +#endif
  112065. +
  112066. + if (status == gcvSTATUS_CHIP_NOT_READY)
  112067. + {
  112068. + /* Error. */
  112069. + goto OnError;
  112070. + }
  112071. +
  112072. + do
  112073. + {
  112074. + /* Wait for the signal. */
  112075. + status = gckOS_WaitSignal(os, signal, gcdGPU_ADVANCETIMER);
  112076. +
  112077. + if (status == gcvSTATUS_TIMEOUT)
  112078. + {
  112079. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  112080. + gctUINT32 idle;
  112081. +
  112082. + /* Read idle register. */
  112083. + gcmkVERIFY_OK(gckHARDWARE_GetIdle(
  112084. + hardware, gcvFALSE, &idle
  112085. + ));
  112086. +
  112087. + gcmkTRACE(
  112088. + gcvLEVEL_ERROR,
  112089. + "%s(%d): idle=%08x",
  112090. + __FUNCTION__, __LINE__, idle
  112091. + );
  112092. +
  112093. + gcmkONERROR(gckOS_MemoryBarrier(os, gcvNULL));
  112094. +
  112095. +#ifdef __QNXNTO__
  112096. + gctUINT32 reg_cmdbuf_fetch;
  112097. + gctUINT32 reg_intr;
  112098. +
  112099. + gcmkVERIFY_OK(gckOS_ReadRegisterEx(
  112100. + Command->kernel->hardware->os, Command->kernel->core, 0x0664, &reg_cmdbuf_fetch
  112101. + ));
  112102. +
  112103. + if (idle == 0x7FFFFFFE)
  112104. + {
  112105. + /*
  112106. + * GPU is idle so there should not be pending interrupts.
  112107. + * Just double check.
  112108. + *
  112109. + * Note that reading interrupt register clears it.
  112110. + * That's why we don't read it in all cases.
  112111. + */
  112112. + gcmkVERIFY_OK(gckOS_ReadRegisterEx(
  112113. + Command->kernel->hardware->os, Command->kernel->core, 0x10, &reg_intr
  112114. + ));
  112115. +
  112116. + slogf(
  112117. + _SLOG_SETCODE(1, 0),
  112118. + _SLOG_CRITICAL,
  112119. + "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X, interrupt = 0x%X)",
  112120. + idle, reg_cmdbuf_fetch, reg_intr
  112121. + );
  112122. + }
  112123. + else
  112124. + {
  112125. + slogf(
  112126. + _SLOG_SETCODE(1, 0),
  112127. + _SLOG_CRITICAL,
  112128. + "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X)",
  112129. + idle, reg_cmdbuf_fetch
  112130. + );
  112131. + }
  112132. +#endif
  112133. +#endif
  112134. + /* Advance timer. */
  112135. + timer += gcdGPU_ADVANCETIMER;
  112136. + }
  112137. + else if (status == gcvSTATUS_INTERRUPTED)
  112138. + {
  112139. + gcmkONERROR(gcvSTATUS_INTERRUPTED);
  112140. + }
  112141. +
  112142. + }
  112143. + while (gcmIS_ERROR(status)
  112144. +#if gcdGPU_TIMEOUT
  112145. + && (timer < Command->kernel->timeOut)
  112146. +#endif
  112147. + );
  112148. +
  112149. + /* Bail out on timeout. */
  112150. + if (gcmIS_ERROR(status))
  112151. + {
  112152. + /* Broadcast the stuck GPU. */
  112153. + gcmkONERROR(gckOS_Broadcast(
  112154. + os, hardware, gcvBROADCAST_GPU_STUCK
  112155. + ));
  112156. + }
  112157. +
  112158. + /* Delete the signal. */
  112159. + gcmkVERIFY_OK(gckOS_DestroySignal(os, signal));
  112160. +
  112161. + /* Success. */
  112162. + gcmkFOOTER_NO();
  112163. + return gcvSTATUS_OK;
  112164. +
  112165. +OnError:
  112166. + if (signal != gcvNULL)
  112167. + {
  112168. + /* Free the signal. */
  112169. + gcmkVERIFY_OK(gckOS_DestroySignal(os, signal));
  112170. + }
  112171. +
  112172. + /* Return the status. */
  112173. + gcmkFOOTER();
  112174. + return status;
  112175. +#endif
  112176. +}
  112177. +
  112178. +/*******************************************************************************
  112179. +**
  112180. +** gckCOMMAND_Attach
  112181. +**
  112182. +** Attach user process.
  112183. +**
  112184. +** INPUT:
  112185. +**
  112186. +** gckCOMMAND Command
  112187. +** Pointer to a gckCOMMAND object.
  112188. +**
  112189. +** gctUINT32 ProcessID
  112190. +** Current process ID.
  112191. +**
  112192. +** OUTPUT:
  112193. +**
  112194. +** gckCONTEXT * Context
  112195. +** Pointer to a variable that will receive a pointer to a new
  112196. +** gckCONTEXT object.
  112197. +**
  112198. +** gctSIZE_T * StateCount
  112199. +** Pointer to a variable that will receive the number of states
  112200. +** in the context buffer.
  112201. +*/
  112202. +gceSTATUS
  112203. +gckCOMMAND_Attach(
  112204. + IN gckCOMMAND Command,
  112205. + OUT gckCONTEXT * Context,
  112206. + OUT gctSIZE_T * StateCount,
  112207. + IN gctUINT32 ProcessID
  112208. + )
  112209. +{
  112210. + gceSTATUS status;
  112211. + gctBOOL acquired = gcvFALSE;
  112212. +
  112213. + gcmkHEADER_ARG("Command=0x%x", Command);
  112214. +
  112215. + /* Verify the arguments. */
  112216. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  112217. +
  112218. + /* Acquire the context switching mutex. */
  112219. + gcmkONERROR(gckOS_AcquireMutex(
  112220. + Command->os, Command->mutexContext, gcvINFINITE
  112221. + ));
  112222. + acquired = gcvTRUE;
  112223. +
  112224. + /* Construct a gckCONTEXT object. */
  112225. + gcmkONERROR(gckCONTEXT_Construct(
  112226. + Command->os,
  112227. + Command->kernel->hardware,
  112228. + ProcessID,
  112229. + Context
  112230. + ));
  112231. +
  112232. + /* Return the number of states in the context. */
  112233. + * StateCount = (* Context)->stateCount;
  112234. +
  112235. + /* Release the context switching mutex. */
  112236. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  112237. + acquired = gcvFALSE;
  112238. +
  112239. + /* Success. */
  112240. + gcmkFOOTER_ARG("*Context=0x%x", *Context);
  112241. + return gcvSTATUS_OK;
  112242. +
  112243. +OnError:
  112244. + /* Release mutex. */
  112245. + if (acquired)
  112246. + {
  112247. + /* Release the context switching mutex. */
  112248. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  112249. + acquired = gcvFALSE;
  112250. + }
  112251. +
  112252. + /* Return the status. */
  112253. + gcmkFOOTER();
  112254. + return status;
  112255. +}
  112256. +
  112257. +/*******************************************************************************
  112258. +**
  112259. +** gckCOMMAND_Detach
  112260. +**
  112261. +** Detach user process.
  112262. +**
  112263. +** INPUT:
  112264. +**
  112265. +** gckCOMMAND Command
  112266. +** Pointer to a gckCOMMAND object.
  112267. +**
  112268. +** gckCONTEXT Context
  112269. +** Pointer to a gckCONTEXT object to be destroyed.
  112270. +**
  112271. +** OUTPUT:
  112272. +**
  112273. +** Nothing.
  112274. +*/
  112275. +gceSTATUS
  112276. +gckCOMMAND_Detach(
  112277. + IN gckCOMMAND Command,
  112278. + IN gckCONTEXT Context
  112279. + )
  112280. +{
  112281. + gceSTATUS status;
  112282. + gctBOOL acquired = gcvFALSE;
  112283. +
  112284. + gcmkHEADER_ARG("Command=0x%x Context=0x%x", Command, Context);
  112285. +
  112286. + /* Verify the arguments. */
  112287. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  112288. +
  112289. + /* Acquire the context switching mutex. */
  112290. + gcmkONERROR(gckOS_AcquireMutex(
  112291. + Command->os, Command->mutexContext, gcvINFINITE
  112292. + ));
  112293. + acquired = gcvTRUE;
  112294. +
  112295. + /* Construct a gckCONTEXT object. */
  112296. + gcmkONERROR(gckCONTEXT_Destroy(Context));
  112297. +
  112298. + if (Command->currContext == Context)
  112299. + {
  112300. + /* Detach from gckCOMMAND object if the destoryed context is current context. */
  112301. + Command->currContext = gcvNULL;
  112302. + }
  112303. +
  112304. + /* Release the context switching mutex. */
  112305. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  112306. + acquired = gcvFALSE;
  112307. +
  112308. + /* Return the status. */
  112309. + gcmkFOOTER();
  112310. + return gcvSTATUS_OK;
  112311. +
  112312. +OnError:
  112313. + /* Release mutex. */
  112314. + if (acquired)
  112315. + {
  112316. + /* Release the context switching mutex. */
  112317. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  112318. + acquired = gcvFALSE;
  112319. + }
  112320. +
  112321. + /* Return the status. */
  112322. + gcmkFOOTER();
  112323. + return status;
  112324. +}
  112325. +
  112326. +#if gcdVIRTUAL_COMMAND_BUFFER
  112327. +/*******************************************************************************
  112328. +**
  112329. +** gckCOMMAND_DumpExecutingBuffer
  112330. +**
  112331. +** Dump the command buffer which GPU is executing.
  112332. +**
  112333. +** INPUT:
  112334. +**
  112335. +** gckCOMMAND Command
  112336. +** Pointer to a gckCOMMAND object.
  112337. +**
  112338. +** OUTPUT:
  112339. +**
  112340. +** Nothing.
  112341. +*/
  112342. +gceSTATUS
  112343. +gckCOMMAND_DumpExecutingBuffer(
  112344. + IN gckCOMMAND Command
  112345. + )
  112346. +{
  112347. + gceSTATUS status;
  112348. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  112349. + gctUINT32 gpuAddress;
  112350. + gctSIZE_T pageCount;
  112351. + gctPOINTER entry;
  112352. + gckOS os = Command->os;
  112353. + gckKERNEL kernel = Command->kernel;
  112354. +#if gcdLINK_QUEUE_SIZE
  112355. + gctINT pid;
  112356. + gctINT i, rear;
  112357. + gctUINT32 start, end;
  112358. + gctUINT32 dumpFront, dumpRear;
  112359. + gckLINKQUEUE queue = &kernel->hardware->linkQueue;
  112360. + gckLINKQUEUE queueMirror;
  112361. + gctUINT32 bytes;
  112362. + gckLINKDATA linkData;
  112363. +#endif
  112364. +
  112365. + gcmkPRINT("**************************\n");
  112366. + gcmkPRINT("**** COMMAND BUF DUMP ****\n");
  112367. + gcmkPRINT("**************************\n");
  112368. +
  112369. + gcmkVERIFY_OK(gckOS_ReadRegisterEx(os, kernel->core, 0x664, &gpuAddress));
  112370. +
  112371. + gcmkPRINT("DMA Address 0x%08X", gpuAddress);
  112372. +
  112373. +#if gcdLINK_QUEUE_SIZE
  112374. + /* Duplicate queue because it will be changed.*/
  112375. + gcmkONERROR(gckOS_AllocateMemory(os,
  112376. + sizeof(struct _gckLINKQUEUE),
  112377. + (gctPOINTER *)&queueMirror));
  112378. +
  112379. + gcmkONERROR(gckOS_MemCopy(queueMirror,
  112380. + queue,
  112381. + sizeof(struct _gckLINKQUEUE)));
  112382. +
  112383. + /* If kernel command buffer link to a context buffer, then link to a user command
  112384. + ** buffer, the second link will be in queue first, so we must fix this.
  112385. + ** In Queue: C1 U1 U2 C2 U3 U4 U5 C3
  112386. + ** Real: C1 X1 U1 C2 U2 U3 U4 C3 U5
  112387. + ** Command buffer X1 which is after C1 is out of queue, so C1 is meaningless.
  112388. + */
  112389. + for (i = 0; i < gcdLINK_QUEUE_SIZE; i++)
  112390. + {
  112391. + gckLINKQUEUE_GetData(queueMirror, i, &linkData);
  112392. +
  112393. + status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer);
  112394. +
  112395. + if (gcmIS_ERROR(status))
  112396. + {
  112397. + /* Can't find it in virtual command buffer list, ignore it. */
  112398. + continue;
  112399. + }
  112400. +
  112401. + if (buffer->kernelLogical)
  112402. + {
  112403. + /* It is a context buffer. */
  112404. + if (i == 0)
  112405. + {
  112406. + /* The real command buffer is out, so clear this slot. */
  112407. + linkData->start = 0;
  112408. + linkData->end = 0;
  112409. + linkData->pid = 0;
  112410. + }
  112411. + else
  112412. + {
  112413. + /* switch context buffer and command buffer. */
  112414. + struct _gckLINKDATA tmp = *linkData;
  112415. + gckLINKDATA linkDataPrevious;
  112416. +
  112417. + gckLINKQUEUE_GetData(queueMirror, i - 1, &linkDataPrevious);
  112418. + *linkData = *linkDataPrevious;
  112419. + *linkDataPrevious = tmp;
  112420. + }
  112421. + }
  112422. + }
  112423. +
  112424. + /* Clear search result. */
  112425. + dumpFront = dumpRear = gcvINFINITE;
  112426. +
  112427. + gcmkPRINT("Link Stack:");
  112428. +
  112429. + /* Search stuck address in link queue from rear. */
  112430. + rear = gcdLINK_QUEUE_SIZE - 1;
  112431. + for (i = 0; i < gcdLINK_QUEUE_SIZE; i++)
  112432. + {
  112433. + gckLINKQUEUE_GetData(queueMirror, rear, &linkData);
  112434. +
  112435. + start = linkData->start;
  112436. + end = linkData->end;
  112437. + pid = linkData->pid;
  112438. +
  112439. + if (gpuAddress >= start && gpuAddress < end)
  112440. + {
  112441. + /* Find latest matched command buffer. */
  112442. + gcmkPRINT(" %d, [%08X - %08X]", pid, start, end);
  112443. +
  112444. + /* Initiliaze dump information. */
  112445. + dumpFront = dumpRear = rear;
  112446. + }
  112447. +
  112448. + /* Advance to previous one. */
  112449. + rear--;
  112450. +
  112451. + if (dumpFront != gcvINFINITE)
  112452. + {
  112453. + break;
  112454. + }
  112455. + }
  112456. +
  112457. + if (dumpFront == gcvINFINITE)
  112458. + {
  112459. + /* Can't find matched record in link queue, dump kernel command buffer. */
  112460. + _DumpKernelCommandBuffer(Command);
  112461. +
  112462. + /* Free local copy. */
  112463. + gcmkOS_SAFE_FREE(os, queueMirror);
  112464. + return gcvSTATUS_OK;
  112465. + }
  112466. +
  112467. + /* Search the last context buffer linked. */
  112468. + while (rear >= 0)
  112469. + {
  112470. + gckLINKQUEUE_GetData(queueMirror, rear, &linkData);
  112471. +
  112472. + gcmkPRINT(" %d, [%08X - %08X]",
  112473. + linkData->pid,
  112474. + linkData->start,
  112475. + linkData->end);
  112476. +
  112477. + status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer);
  112478. +
  112479. + if (gcmIS_SUCCESS(status) && buffer->kernelLogical)
  112480. + {
  112481. + /* Find a context buffer. */
  112482. + dumpFront = rear;
  112483. + break;
  112484. + }
  112485. +
  112486. + rear--;
  112487. + }
  112488. +
  112489. + /* Dump from last context buffer to last command buffer where hang happens. */
  112490. + for (i = dumpFront; i <= dumpRear; i++)
  112491. + {
  112492. + gckLINKQUEUE_GetData(queueMirror, i, &linkData);
  112493. +
  112494. + /* Get gpu address of this command buffer. */
  112495. + gpuAddress = linkData->start;
  112496. + bytes = linkData->end - gpuAddress;
  112497. +
  112498. + /* Get the whole buffer. */
  112499. + status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer);
  112500. +
  112501. + if (gcmIS_ERROR(status))
  112502. + {
  112503. + gcmkPRINT("Buffer [%08X - %08X] is lost",
  112504. + linkData->start,
  112505. + linkData->end);
  112506. + continue;
  112507. + }
  112508. +
  112509. + /* Get kernel logical for dump. */
  112510. + if (buffer->kernelLogical)
  112511. + {
  112512. + /* Get kernel logical directly if it is a context buffer. */
  112513. + entry = buffer->kernelLogical;
  112514. + gcmkPRINT("Context Buffer:");
  112515. + }
  112516. + else
  112517. + {
  112518. + /* Make it accessiable by kernel if it is a user command buffer. */
  112519. + gcmkVERIFY_OK(
  112520. + gckOS_CreateKernelVirtualMapping(buffer->physical,
  112521. + &pageCount,
  112522. + &entry));
  112523. + gcmkPRINT("User Command Buffer:");
  112524. + }
  112525. +
  112526. + /* Dump from the entry. */
  112527. + _DumpBuffer(entry + (gpuAddress - buffer->gpuAddress), gpuAddress, bytes);
  112528. +
  112529. + /* Release kernel logical address if neccessary. */
  112530. + if (!buffer->kernelLogical)
  112531. + {
  112532. + gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(entry));
  112533. + }
  112534. + }
  112535. +
  112536. + /* Free local copy. */
  112537. + gcmkOS_SAFE_FREE(os, queueMirror);
  112538. + return gcvSTATUS_OK;
  112539. +OnError:
  112540. + return status;
  112541. +#else
  112542. + /* Without link queue information, we don't know the entry of last command
  112543. + ** buffer, just dump the page where GPU stuck. */
  112544. + status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer);
  112545. +
  112546. + if (gcmIS_SUCCESS(status))
  112547. + {
  112548. + gcmkVERIFY_OK(
  112549. + gckOS_CreateKernelVirtualMapping(buffer->physical, &pageCount, &entry));
  112550. +
  112551. + if (entry)
  112552. + {
  112553. + gctUINT32 offset = gpuAddress - buffer->gpuAddress;
  112554. + gctPOINTER entryDump = entry;
  112555. +
  112556. + /* Dump one pages. */
  112557. + gctUINT32 bytes = 4096;
  112558. +
  112559. + /* Align to page. */
  112560. + offset &= 0xfffff000;
  112561. +
  112562. + /* Kernel address of page where stall point stay. */
  112563. + entryDump += offset;
  112564. +
  112565. + /* Align to page. */
  112566. + gpuAddress &= 0xfffff000;
  112567. +
  112568. + gcmkPRINT("User Command Buffer:\n");
  112569. + _DumpBuffer(entryDump, gpuAddress, bytes);
  112570. + }
  112571. +
  112572. + gcmkVERIFY_OK(
  112573. + gckOS_DestroyKernelVirtualMapping(entry));
  112574. + }
  112575. + else
  112576. + {
  112577. + _DumpKernelCommandBuffer(Command);
  112578. + }
  112579. +
  112580. + return gcvSTATUS_OK;
  112581. +#endif
  112582. +}
  112583. +#endif
  112584. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
  112585. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c 1969-12-31 18:00:00.000000000 -0600
  112586. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c 2014-12-08 00:31:53.464418001 -0600
  112587. @@ -0,0 +1,3677 @@
  112588. +/****************************************************************************
  112589. +*
  112590. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  112591. +*
  112592. +* This program is free software; you can redistribute it and/or modify
  112593. +* it under the terms of the GNU General Public License as published by
  112594. +* the Free Software Foundation; either version 2 of the license, or
  112595. +* (at your option) any later version.
  112596. +*
  112597. +* This program is distributed in the hope that it will be useful,
  112598. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  112599. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  112600. +* GNU General Public License for more details.
  112601. +*
  112602. +* You should have received a copy of the GNU General Public License
  112603. +* along with this program; if not write to the Free Software
  112604. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  112605. +*
  112606. +*****************************************************************************/
  112607. +
  112608. +
  112609. +#include "gc_hal_kernel_precomp.h"
  112610. +
  112611. +#if gcdENABLE_VG
  112612. +
  112613. +#include "gc_hal_kernel_hardware_command_vg.h"
  112614. +
  112615. +#define _GC_OBJ_ZONE gcvZONE_COMMAND
  112616. +
  112617. +/******************************************************************************\
  112618. +*********************************** Debugging **********************************
  112619. +\******************************************************************************/
  112620. +
  112621. +#define gcvDISABLE_TIMEOUT 1
  112622. +#define gcvDUMP_COMMAND_BUFFER 0
  112623. +#define gcvDUMP_COMMAND_LINES 0
  112624. +
  112625. +
  112626. +#if gcvDEBUG || defined(EMULATOR) || gcvDISABLE_TIMEOUT
  112627. +# define gcvQUEUE_TIMEOUT ~0
  112628. +#else
  112629. +# define gcvQUEUE_TIMEOUT 10
  112630. +#endif
  112631. +
  112632. +
  112633. +/******************************************************************************\
  112634. +********************************** Definitions *********************************
  112635. +\******************************************************************************/
  112636. +
  112637. +/* Minimum buffer size. */
  112638. +#define gcvMINUMUM_BUFFER \
  112639. + gcmSIZEOF(gcsKERNEL_QUEUE_HEADER) + \
  112640. + gcmSIZEOF(gcsKERNEL_CMDQUEUE) * 2
  112641. +
  112642. +#define gcmDECLARE_INTERRUPT_HANDLER(Block, Number) \
  112643. + static gceSTATUS \
  112644. + _EventHandler_##Block##_##Number( \
  112645. + IN gckVGKERNEL Kernel \
  112646. + )
  112647. +
  112648. +#define gcmDEFINE_INTERRUPT_HANDLER(Block, Number) \
  112649. + gcmDECLARE_INTERRUPT_HANDLER(Block, Number) \
  112650. + { \
  112651. + return _EventHandler_Block( \
  112652. + Kernel, \
  112653. + &Kernel->command->taskTable[gcvBLOCK_##Block], \
  112654. + gcvFALSE \
  112655. + ); \
  112656. + }
  112657. +
  112658. +#define gcmDEFINE_INTERRUPT_HANDLER_ENTRY(Block, Number) \
  112659. + { gcvBLOCK_##Block, _EventHandler_##Block##_##Number }
  112660. +
  112661. +/* Block interrupt handling table entry. */
  112662. +typedef struct _gcsBLOCK_INTERRUPT_HANDLER * gcsBLOCK_INTERRUPT_HANDLER_PTR;
  112663. +typedef struct _gcsBLOCK_INTERRUPT_HANDLER
  112664. +{
  112665. + gceBLOCK block;
  112666. + gctINTERRUPT_HANDLER handler;
  112667. +}
  112668. +gcsBLOCK_INTERRUPT_HANDLER;
  112669. +
  112670. +/* Queue control functions. */
  112671. +typedef struct _gcsQUEUE_UPDATE_CONTROL * gcsQUEUE_UPDATE_CONTROL_PTR;
  112672. +typedef struct _gcsQUEUE_UPDATE_CONTROL
  112673. +{
  112674. + gctOBJECT_HANDLER execute;
  112675. + gctOBJECT_HANDLER update;
  112676. + gctOBJECT_HANDLER lastExecute;
  112677. + gctOBJECT_HANDLER lastUpdate;
  112678. +}
  112679. +gcsQUEUE_UPDATE_CONTROL;
  112680. +
  112681. +
  112682. +/******************************************************************************\
  112683. +********************************* Support Code *********************************
  112684. +\******************************************************************************/
  112685. +static gceSTATUS
  112686. +_FlushMMU(
  112687. + IN gckVGCOMMAND Command
  112688. + )
  112689. +{
  112690. + gceSTATUS status;
  112691. + gctUINT32 oldValue;
  112692. + gckVGHARDWARE hardware = Command->hardware;
  112693. +
  112694. + gcmkONERROR(gckOS_AtomicExchange(Command->os,
  112695. + hardware->pageTableDirty,
  112696. + 0,
  112697. + &oldValue));
  112698. +
  112699. + if (oldValue)
  112700. + {
  112701. + /* Page Table is upated, flush mmu before commit. */
  112702. + gcmkONERROR(gckVGHARDWARE_FlushMMU(hardware));
  112703. + }
  112704. +
  112705. + return gcvSTATUS_OK;
  112706. +OnError:
  112707. + return status;
  112708. +}
  112709. +
  112710. +static gceSTATUS
  112711. +_WaitForIdle(
  112712. + IN gckVGCOMMAND Command,
  112713. + IN gcsKERNEL_QUEUE_HEADER_PTR Queue
  112714. + )
  112715. +{
  112716. + gceSTATUS status = gcvSTATUS_OK;
  112717. + gctUINT32 idle;
  112718. + gctUINT timeout = 0;
  112719. +
  112720. + /* Loop while not idle. */
  112721. + while (Queue->pending)
  112722. + {
  112723. + /* Did we reach the timeout limit? */
  112724. + if (timeout == gcvQUEUE_TIMEOUT)
  112725. + {
  112726. + /* Hardware is probably dead... */
  112727. + return gcvSTATUS_TIMEOUT;
  112728. + }
  112729. +
  112730. + /* Sleep for 100ms. */
  112731. + gcmkERR_BREAK(gckOS_Delay(Command->os, 100));
  112732. +
  112733. + /* Not the first loop? */
  112734. + if (timeout > 0)
  112735. + {
  112736. + /* Read IDLE register. */
  112737. + gcmkVERIFY_OK(gckVGHARDWARE_GetIdle(Command->hardware, &idle));
  112738. +
  112739. + gcmkTRACE_ZONE(
  112740. + gcvLEVEL_ERROR, gcvZONE_COMMAND,
  112741. + "%s: timeout, IDLE=%08X\n",
  112742. + __FUNCTION__, idle
  112743. + );
  112744. + }
  112745. +
  112746. + /* Increment the timeout counter. */
  112747. + timeout += 1;
  112748. + }
  112749. +
  112750. + /* Return status. */
  112751. + return status;
  112752. +}
  112753. +
  112754. +static gctINT32
  112755. +_GetNextInterrupt(
  112756. + IN gckVGCOMMAND Command,
  112757. + IN gceBLOCK Block
  112758. + )
  112759. +{
  112760. + gctUINT index;
  112761. + gcsBLOCK_TASK_ENTRY_PTR entry;
  112762. + gctINT32 interrupt;
  112763. +
  112764. + /* Get the block entry. */
  112765. + entry = &Command->taskTable[Block];
  112766. +
  112767. + /* Make sure we have initialized interrupts. */
  112768. + gcmkASSERT(entry->interruptCount > 0);
  112769. +
  112770. + /* Decrement the interrupt usage semaphore. */
  112771. + gcmkVERIFY_OK(gckOS_DecrementSemaphore(
  112772. + Command->os, entry->interruptSemaphore
  112773. + ));
  112774. +
  112775. + /* Get the value index. */
  112776. + index = entry->interruptIndex;
  112777. +
  112778. + /* Get the interrupt value. */
  112779. + interrupt = entry->interruptArray[index];
  112780. +
  112781. + /* Must be a valid value. */
  112782. + gcmkASSERT((interrupt >= 0) && (interrupt <= 31));
  112783. +
  112784. + /* Advance the index to the next value. */
  112785. + index += 1;
  112786. +
  112787. + /* Set the new index. */
  112788. + entry->interruptIndex = (index == entry->interruptCount)
  112789. + ? 0
  112790. + : index;
  112791. +
  112792. + /* Return interrupt value. */
  112793. + return interrupt;
  112794. +}
  112795. +
  112796. +
  112797. +/******************************************************************************\
  112798. +***************************** Task Storage Management **************************
  112799. +\******************************************************************************/
  112800. +
  112801. +/* Minimum task buffer size. */
  112802. +#define gcvMIN_TASK_BUFFER \
  112803. +( \
  112804. + gcmSIZEOF(gcsTASK_CONTAINER) + 128 \
  112805. +)
  112806. +
  112807. +/* Free list terminator. */
  112808. +#define gcvFREE_TASK_TERMINATOR \
  112809. +( \
  112810. + (gcsTASK_CONTAINER_PTR) gcmINT2PTR(~0) \
  112811. +)
  112812. +
  112813. +
  112814. +/*----------------------------------------------------------------------------*/
  112815. +/*------------------- Allocated Task Buffer List Management ------------------*/
  112816. +
  112817. +static void
  112818. +_InsertTaskBuffer(
  112819. + IN gcsTASK_CONTAINER_PTR AddAfter,
  112820. + IN gcsTASK_CONTAINER_PTR Buffer
  112821. + )
  112822. +{
  112823. + gcsTASK_CONTAINER_PTR addBefore;
  112824. +
  112825. + /* Cannot add before the first buffer. */
  112826. + gcmkASSERT(AddAfter != gcvNULL);
  112827. +
  112828. + /* Create a shortcut to the next buffer. */
  112829. + addBefore = AddAfter->allocNext;
  112830. +
  112831. + /* Initialize the links. */
  112832. + Buffer->allocPrev = AddAfter;
  112833. + Buffer->allocNext = addBefore;
  112834. +
  112835. + /* Link to the previous buffer. */
  112836. + AddAfter->allocNext = Buffer;
  112837. +
  112838. + /* Link to the next buffer. */
  112839. + if (addBefore != gcvNULL)
  112840. + {
  112841. + addBefore->allocPrev = Buffer;
  112842. + }
  112843. +}
  112844. +
  112845. +static void
  112846. +_RemoveTaskBuffer(
  112847. + IN gcsTASK_CONTAINER_PTR Buffer
  112848. + )
  112849. +{
  112850. + gcsTASK_CONTAINER_PTR prev;
  112851. + gcsTASK_CONTAINER_PTR next;
  112852. +
  112853. + /* Cannot remove the first buffer. */
  112854. + gcmkASSERT(Buffer->allocPrev != gcvNULL);
  112855. +
  112856. + /* Create shortcuts to the previous and next buffers. */
  112857. + prev = Buffer->allocPrev;
  112858. + next = Buffer->allocNext;
  112859. +
  112860. + /* Tail buffer? */
  112861. + if (next == gcvNULL)
  112862. + {
  112863. + /* Remove from the list. */
  112864. + prev->allocNext = gcvNULL;
  112865. + }
  112866. +
  112867. + /* Buffer from the middle. */
  112868. + else
  112869. + {
  112870. + prev->allocNext = next;
  112871. + next->allocPrev = prev;
  112872. + }
  112873. +}
  112874. +
  112875. +
  112876. +/*----------------------------------------------------------------------------*/
  112877. +/*--------------------- Free Task Buffer List Management ---------------------*/
  112878. +
  112879. +static void
  112880. +_AppendToFreeList(
  112881. + IN gckVGCOMMAND Command,
  112882. + IN gcsTASK_CONTAINER_PTR Buffer
  112883. + )
  112884. +{
  112885. + /* Cannot be a part of the free list already. */
  112886. + gcmkASSERT(Buffer->freePrev == gcvNULL);
  112887. + gcmkASSERT(Buffer->freeNext == gcvNULL);
  112888. +
  112889. + /* First buffer to add? */
  112890. + if (Command->taskFreeHead == gcvNULL)
  112891. + {
  112892. + /* Terminate the links. */
  112893. + Buffer->freePrev = gcvFREE_TASK_TERMINATOR;
  112894. + Buffer->freeNext = gcvFREE_TASK_TERMINATOR;
  112895. +
  112896. + /* Initialize the list pointer. */
  112897. + Command->taskFreeHead = Command->taskFreeTail = Buffer;
  112898. + }
  112899. +
  112900. + /* Not the first, add after the tail. */
  112901. + else
  112902. + {
  112903. + /* Initialize the new tail buffer. */
  112904. + Buffer->freePrev = Command->taskFreeTail;
  112905. + Buffer->freeNext = gcvFREE_TASK_TERMINATOR;
  112906. +
  112907. + /* Add after the tail. */
  112908. + Command->taskFreeTail->freeNext = Buffer;
  112909. + Command->taskFreeTail = Buffer;
  112910. + }
  112911. +}
  112912. +
  112913. +static void
  112914. +_RemoveFromFreeList(
  112915. + IN gckVGCOMMAND Command,
  112916. + IN gcsTASK_CONTAINER_PTR Buffer
  112917. + )
  112918. +{
  112919. + /* Has to be a part of the free list. */
  112920. + gcmkASSERT(Buffer->freePrev != gcvNULL);
  112921. + gcmkASSERT(Buffer->freeNext != gcvNULL);
  112922. +
  112923. + /* Head buffer? */
  112924. + if (Buffer->freePrev == gcvFREE_TASK_TERMINATOR)
  112925. + {
  112926. + /* Tail buffer as well? */
  112927. + if (Buffer->freeNext == gcvFREE_TASK_TERMINATOR)
  112928. + {
  112929. + /* Reset the list pointer. */
  112930. + Command->taskFreeHead = Command->taskFreeTail = gcvNULL;
  112931. + }
  112932. +
  112933. + /* No, just the head. */
  112934. + else
  112935. + {
  112936. + /* Update the head. */
  112937. + Command->taskFreeHead = Buffer->freeNext;
  112938. +
  112939. + /* Terminate the next buffer. */
  112940. + Command->taskFreeHead->freePrev = gcvFREE_TASK_TERMINATOR;
  112941. + }
  112942. + }
  112943. +
  112944. + /* Not the head. */
  112945. + else
  112946. + {
  112947. + /* Tail buffer? */
  112948. + if (Buffer->freeNext == gcvFREE_TASK_TERMINATOR)
  112949. + {
  112950. + /* Update the tail. */
  112951. + Command->taskFreeTail = Buffer->freePrev;
  112952. +
  112953. + /* Terminate the previous buffer. */
  112954. + Command->taskFreeTail->freeNext = gcvFREE_TASK_TERMINATOR;
  112955. + }
  112956. +
  112957. + /* A buffer in the middle. */
  112958. + else
  112959. + {
  112960. + /* Remove the buffer from the list. */
  112961. + Buffer->freePrev->freeNext = Buffer->freeNext;
  112962. + Buffer->freeNext->freePrev = Buffer->freePrev;
  112963. + }
  112964. + }
  112965. +
  112966. + /* Reset free list pointers. */
  112967. + Buffer->freePrev = gcvNULL;
  112968. + Buffer->freeNext = gcvNULL;
  112969. +}
  112970. +
  112971. +
  112972. +/*----------------------------------------------------------------------------*/
  112973. +/*-------------------------- Task Buffer Allocation --------------------------*/
  112974. +
  112975. +static void
  112976. +_SplitTaskBuffer(
  112977. + IN gckVGCOMMAND Command,
  112978. + IN gcsTASK_CONTAINER_PTR Buffer,
  112979. + IN gctUINT Size
  112980. + )
  112981. +{
  112982. + /* Determine the size of the new buffer. */
  112983. + gctINT splitBufferSize = Buffer->size - Size;
  112984. + gcmkASSERT(splitBufferSize >= 0);
  112985. +
  112986. + /* Is the split buffer big enough to become a separate buffer? */
  112987. + if (splitBufferSize >= gcvMIN_TASK_BUFFER)
  112988. + {
  112989. + /* Place the new path data. */
  112990. + gcsTASK_CONTAINER_PTR splitBuffer = (gcsTASK_CONTAINER_PTR)
  112991. + (
  112992. + (gctUINT8_PTR) Buffer + Size
  112993. + );
  112994. +
  112995. + /* Set the trimmed buffer size. */
  112996. + Buffer->size = Size;
  112997. +
  112998. + /* Initialize the split buffer. */
  112999. + splitBuffer->referenceCount = 0;
  113000. + splitBuffer->size = splitBufferSize;
  113001. + splitBuffer->freePrev = gcvNULL;
  113002. + splitBuffer->freeNext = gcvNULL;
  113003. +
  113004. + /* Link in. */
  113005. + _InsertTaskBuffer(Buffer, splitBuffer);
  113006. + _AppendToFreeList(Command, splitBuffer);
  113007. + }
  113008. +}
  113009. +
  113010. +static gceSTATUS
  113011. +_AllocateTaskContainer(
  113012. + IN gckVGCOMMAND Command,
  113013. + IN gctUINT Size,
  113014. + OUT gcsTASK_CONTAINER_PTR * Buffer
  113015. + )
  113016. +{
  113017. + gceSTATUS status;
  113018. +
  113019. + gcmkHEADER_ARG("Command=0x%x Size=0x%x, Buffer ==0x%x", Command, Size, Buffer);
  113020. +
  113021. + /* Verify arguments. */
  113022. + gcmkVERIFY_ARGUMENT(Buffer != gcvNULL);
  113023. +
  113024. + do
  113025. + {
  113026. + gcsTASK_STORAGE_PTR storage;
  113027. + gcsTASK_CONTAINER_PTR buffer;
  113028. +
  113029. + /* Adjust the size. */
  113030. + Size += gcmSIZEOF(gcsTASK_CONTAINER);
  113031. +
  113032. + /* Adjust the allocation size if not big enough. */
  113033. + if (Size > Command->taskStorageUsable)
  113034. + {
  113035. + Command->taskStorageGranularity
  113036. + = gcmALIGN(Size + gcmSIZEOF(gcsTASK_STORAGE), 1024);
  113037. +
  113038. + Command->taskStorageUsable
  113039. + = Command->taskStorageGranularity - gcmSIZEOF(gcsTASK_STORAGE);
  113040. + }
  113041. +
  113042. + /* Is there a free buffer available? */
  113043. + else if (Command->taskFreeHead != gcvNULL)
  113044. + {
  113045. + /* Set the initial free buffer. */
  113046. + gcsTASK_CONTAINER_PTR buffer = Command->taskFreeHead;
  113047. +
  113048. + do
  113049. + {
  113050. + /* Is the buffer big enough? */
  113051. + if (buffer->size >= Size)
  113052. + {
  113053. + /* Remove the buffer from the free list. */
  113054. + _RemoveFromFreeList(Command, buffer);
  113055. +
  113056. + /* Split the buffer. */
  113057. + _SplitTaskBuffer(Command, buffer, Size);
  113058. +
  113059. + /* Set the result. */
  113060. + * Buffer = buffer;
  113061. +
  113062. + gcmkFOOTER_ARG("*Buffer=0x%x",*Buffer);
  113063. + /* Success. */
  113064. + return gcvSTATUS_OK;
  113065. + }
  113066. +
  113067. + /* Get the next free buffer. */
  113068. + buffer = buffer->freeNext;
  113069. + }
  113070. + while (buffer != gcvFREE_TASK_TERMINATOR);
  113071. + }
  113072. +
  113073. + /* Allocate a container. */
  113074. + gcmkERR_BREAK(gckOS_Allocate(
  113075. + Command->os,
  113076. + Command->taskStorageGranularity,
  113077. + (gctPOINTER *) &storage
  113078. + ));
  113079. +
  113080. + /* Link in the storage buffer. */
  113081. + storage->next = Command->taskStorage;
  113082. + Command->taskStorage = storage;
  113083. +
  113084. + /* Place the task buffer. */
  113085. + buffer = (gcsTASK_CONTAINER_PTR) (storage + 1);
  113086. +
  113087. + /* Determine the size of the buffer. */
  113088. + buffer->size
  113089. + = Command->taskStorageGranularity
  113090. + - gcmSIZEOF(gcsTASK_STORAGE);
  113091. +
  113092. + /* Initialize the task buffer. */
  113093. + buffer->referenceCount = 0;
  113094. + buffer->allocPrev = gcvNULL;
  113095. + buffer->allocNext = gcvNULL;
  113096. + buffer->freePrev = gcvNULL;
  113097. + buffer->freeNext = gcvNULL;
  113098. +
  113099. + /* Split the buffer. */
  113100. + _SplitTaskBuffer(Command, buffer, Size);
  113101. +
  113102. + /* Set the result. */
  113103. + * Buffer = buffer;
  113104. +
  113105. + gcmkFOOTER_ARG("*Buffer=0x%x",*Buffer);
  113106. + /* Success. */
  113107. + return gcvSTATUS_OK;
  113108. + }
  113109. + while (gcvFALSE);
  113110. +
  113111. + gcmkFOOTER();
  113112. + /* Return status. */
  113113. + return status;
  113114. +}
  113115. +
  113116. +static void
  113117. +_FreeTaskContainer(
  113118. + IN gckVGCOMMAND Command,
  113119. + IN gcsTASK_CONTAINER_PTR Buffer
  113120. + )
  113121. +{
  113122. + gcsTASK_CONTAINER_PTR prev;
  113123. + gcsTASK_CONTAINER_PTR next;
  113124. + gcsTASK_CONTAINER_PTR merged;
  113125. +
  113126. + gctSIZE_T mergedSize;
  113127. +
  113128. + /* Verify arguments. */
  113129. + gcmkASSERT(Buffer != gcvNULL);
  113130. + gcmkASSERT(Buffer->freePrev == gcvNULL);
  113131. + gcmkASSERT(Buffer->freeNext == gcvNULL);
  113132. +
  113133. + /* Get shortcuts to the previous and next path data buffers. */
  113134. + prev = Buffer->allocPrev;
  113135. + next = Buffer->allocNext;
  113136. +
  113137. + /* Is the previous path data buffer already free? */
  113138. + if (prev && prev->freeNext)
  113139. + {
  113140. + /* The previous path data buffer is the one that remains. */
  113141. + merged = prev;
  113142. +
  113143. + /* Is the next path data buffer already free? */
  113144. + if (next && next->freeNext)
  113145. + {
  113146. + /* Merge all three path data buffers into the previous. */
  113147. + mergedSize = prev->size + Buffer->size + next->size;
  113148. +
  113149. + /* Remove the next path data buffer. */
  113150. + _RemoveFromFreeList(Command, next);
  113151. + _RemoveTaskBuffer(next);
  113152. + }
  113153. + else
  113154. + {
  113155. + /* Merge the current path data buffer into the previous. */
  113156. + mergedSize = prev->size + Buffer->size;
  113157. + }
  113158. +
  113159. + /* Delete the current path data buffer. */
  113160. + _RemoveTaskBuffer(Buffer);
  113161. +
  113162. + /* Set new size. */
  113163. + merged->size = mergedSize;
  113164. + }
  113165. + else
  113166. + {
  113167. + /* The current path data buffer is the one that remains. */
  113168. + merged = Buffer;
  113169. +
  113170. + /* Is the next buffer already free? */
  113171. + if (next && next->freeNext)
  113172. + {
  113173. + /* Merge the next into the current. */
  113174. + mergedSize = Buffer->size + next->size;
  113175. +
  113176. + /* Remove the next buffer. */
  113177. + _RemoveFromFreeList(Command, next);
  113178. + _RemoveTaskBuffer(next);
  113179. +
  113180. + /* Set new size. */
  113181. + merged->size = mergedSize;
  113182. + }
  113183. +
  113184. + /* Add the current buffer into the free list. */
  113185. + _AppendToFreeList(Command, merged);
  113186. + }
  113187. +}
  113188. +
  113189. +gceSTATUS
  113190. +_RemoveRecordFromProcesDB(
  113191. + IN gckVGCOMMAND Command,
  113192. + IN gcsTASK_HEADER_PTR Task
  113193. + )
  113194. +{
  113195. + gcsTASK_PTR task = (gcsTASK_PTR)((gctUINT8_PTR)Task - sizeof(gcsTASK));
  113196. + gcsTASK_FREE_VIDEO_MEMORY_PTR freeVideoMemory;
  113197. + gcsTASK_UNLOCK_VIDEO_MEMORY_PTR unlockVideoMemory;
  113198. + gctINT pid;
  113199. + gctUINT32 size;
  113200. +
  113201. + /* Get the total size of all tasks. */
  113202. + size = task->size;
  113203. +
  113204. + gcmkVERIFY_OK(gckOS_GetProcessID((gctUINT32_PTR)&pid));
  113205. +
  113206. + do
  113207. + {
  113208. + switch (Task->id)
  113209. + {
  113210. + case gcvTASK_FREE_VIDEO_MEMORY:
  113211. + freeVideoMemory = (gcsTASK_FREE_VIDEO_MEMORY_PTR)Task;
  113212. +
  113213. + /* Remove record from process db. */
  113214. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  113215. + Command->kernel->kernel,
  113216. + pid,
  113217. + gcvDB_VIDEO_MEMORY,
  113218. + gcmUINT64_TO_PTR(freeVideoMemory->node)));
  113219. +
  113220. + /* Advance to next task. */
  113221. + size -= sizeof(gcsTASK_FREE_VIDEO_MEMORY);
  113222. + Task = (gcsTASK_HEADER_PTR)(freeVideoMemory + 1);
  113223. +
  113224. + break;
  113225. + case gcvTASK_UNLOCK_VIDEO_MEMORY:
  113226. + unlockVideoMemory = (gcsTASK_UNLOCK_VIDEO_MEMORY_PTR)Task;
  113227. +
  113228. + /* Remove record from process db. */
  113229. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  113230. + Command->kernel->kernel,
  113231. + pid,
  113232. + gcvDB_VIDEO_MEMORY_LOCKED,
  113233. + gcmUINT64_TO_PTR(unlockVideoMemory->node)));
  113234. +
  113235. + /* Advance to next task. */
  113236. + size -= sizeof(gcsTASK_UNLOCK_VIDEO_MEMORY);
  113237. + Task = (gcsTASK_HEADER_PTR)(unlockVideoMemory + 1);
  113238. +
  113239. + break;
  113240. + default:
  113241. + /* Skip the whole task. */
  113242. + size = 0;
  113243. + break;
  113244. + }
  113245. + }
  113246. + while(size);
  113247. +
  113248. + return gcvSTATUS_OK;
  113249. +}
  113250. +
  113251. +/******************************************************************************\
  113252. +********************************* Task Scheduling ******************************
  113253. +\******************************************************************************/
  113254. +
  113255. +static gceSTATUS
  113256. +_ScheduleTasks(
  113257. + IN gckVGCOMMAND Command,
  113258. + IN gcsTASK_MASTER_TABLE_PTR TaskTable,
  113259. + IN gctUINT8_PTR PreviousEnd
  113260. + )
  113261. +{
  113262. + gceSTATUS status;
  113263. +
  113264. + do
  113265. + {
  113266. + gctINT block;
  113267. + gcsTASK_CONTAINER_PTR container;
  113268. + gcsTASK_MASTER_ENTRY_PTR userTaskEntry;
  113269. + gcsBLOCK_TASK_ENTRY_PTR kernelTaskEntry;
  113270. + gcsTASK_PTR userTask;
  113271. + gctUINT8_PTR kernelTask;
  113272. + gctINT32 interrupt;
  113273. + gctUINT8_PTR eventCommand;
  113274. +
  113275. + /* Nothing to schedule? */
  113276. + if (TaskTable->size == 0)
  113277. + {
  113278. + status = gcvSTATUS_OK;
  113279. + break;
  113280. + }
  113281. +
  113282. + /* Acquire the mutex. */
  113283. + gcmkERR_BREAK(gckOS_AcquireMutex(
  113284. + Command->os,
  113285. + Command->taskMutex,
  113286. + gcvINFINITE
  113287. + ));
  113288. +
  113289. + gcmkTRACE_ZONE(
  113290. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113291. + "%s(%d)\n",
  113292. + __FUNCTION__, __LINE__
  113293. + );
  113294. +
  113295. + do
  113296. + {
  113297. + gcmkTRACE_ZONE(
  113298. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113299. + " number of tasks scheduled = %d\n"
  113300. + " size of event data in bytes = %d\n",
  113301. + TaskTable->count,
  113302. + TaskTable->size
  113303. + );
  113304. +
  113305. + /* Allocate task buffer. */
  113306. + gcmkERR_BREAK(_AllocateTaskContainer(
  113307. + Command,
  113308. + TaskTable->size,
  113309. + &container
  113310. + ));
  113311. +
  113312. + /* Determine the task data pointer. */
  113313. + kernelTask = (gctUINT8_PTR) (container + 1);
  113314. +
  113315. + /* Initialize the reference count. */
  113316. + container->referenceCount = TaskTable->count;
  113317. +
  113318. + /* Process tasks. */
  113319. + for (block = gcvBLOCK_COUNT - 1; block >= 0; block -= 1)
  113320. + {
  113321. + /* Get the current user table entry. */
  113322. + userTaskEntry = &TaskTable->table[block];
  113323. +
  113324. + /* Are there tasks scheduled? */
  113325. + if (userTaskEntry->head == gcvNULL)
  113326. + {
  113327. + /* No, skip to the next block. */
  113328. + continue;
  113329. + }
  113330. +
  113331. + gcmkTRACE_ZONE(
  113332. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113333. + " processing tasks for block %d\n",
  113334. + block
  113335. + );
  113336. +
  113337. + /* Get the current kernel table entry. */
  113338. + kernelTaskEntry = &Command->taskTable[block];
  113339. +
  113340. + /* Are there tasks for the current block scheduled? */
  113341. + if (kernelTaskEntry->container == gcvNULL)
  113342. + {
  113343. + gcmkTRACE_ZONE(
  113344. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113345. + " first task container for the block added\n",
  113346. + block
  113347. + );
  113348. +
  113349. + /* Nothing yet, set the container buffer pointer. */
  113350. + kernelTaskEntry->container = container;
  113351. + kernelTaskEntry->task = (gcsTASK_HEADER_PTR) kernelTask;
  113352. + }
  113353. +
  113354. + /* Yes, append to the end. */
  113355. + else
  113356. + {
  113357. + kernelTaskEntry->link->cotainer = container;
  113358. + kernelTaskEntry->link->task = (gcsTASK_HEADER_PTR) kernelTask;
  113359. + }
  113360. +
  113361. + /* Set initial task. */
  113362. + userTask = userTaskEntry->head;
  113363. +
  113364. + gcmkTRACE_ZONE(
  113365. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113366. + " copying user tasks over to the kernel\n"
  113367. + );
  113368. +
  113369. + /* Copy tasks. */
  113370. + do
  113371. + {
  113372. + gcsTASK_HEADER_PTR taskHeader = (gcsTASK_HEADER_PTR) (userTask + 1);
  113373. +
  113374. + gcmkVERIFY_OK(_RemoveRecordFromProcesDB(Command, taskHeader));
  113375. +
  113376. + gcmkTRACE_ZONE(
  113377. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113378. + " task ID = %d, size = %d\n",
  113379. + ((gcsTASK_HEADER_PTR) (userTask + 1))->id,
  113380. + userTask->size
  113381. + );
  113382. +
  113383. +#ifdef __QNXNTO__
  113384. + if (taskHeader->id == gcvTASK_SIGNAL)
  113385. + {
  113386. + ((gcsTASK_SIGNAL_PTR)taskHeader)->coid = TaskTable->coid;
  113387. + ((gcsTASK_SIGNAL_PTR)taskHeader)->rcvid = TaskTable->rcvid;
  113388. + }
  113389. +#endif /* __QNXNTO__ */
  113390. + /* Copy the task data. */
  113391. + gcmkVERIFY_OK(gckOS_MemCopy(
  113392. + kernelTask, taskHeader, userTask->size
  113393. + ));
  113394. +
  113395. + /* Advance to the next task. */
  113396. + kernelTask += userTask->size;
  113397. + userTask = userTask->next;
  113398. + }
  113399. + while (userTask != gcvNULL);
  113400. +
  113401. + /* Update link pointer in the header. */
  113402. + kernelTaskEntry->link = (gcsTASK_LINK_PTR) kernelTask;
  113403. +
  113404. + /* Initialize link task. */
  113405. + kernelTaskEntry->link->id = gcvTASK_LINK;
  113406. + kernelTaskEntry->link->cotainer = gcvNULL;
  113407. + kernelTaskEntry->link->task = gcvNULL;
  113408. +
  113409. + /* Advance the task data pointer. */
  113410. + kernelTask += gcmSIZEOF(gcsTASK_LINK);
  113411. + }
  113412. + }
  113413. + while (gcvFALSE);
  113414. +
  113415. + /* Release the mutex. */
  113416. + gcmkERR_BREAK(gckOS_ReleaseMutex(
  113417. + Command->os,
  113418. + Command->taskMutex
  113419. + ));
  113420. +
  113421. + /* Assign interrupts to the blocks. */
  113422. + eventCommand = PreviousEnd;
  113423. +
  113424. + for (block = gcvBLOCK_COUNT - 1; block >= 0; block -= 1)
  113425. + {
  113426. + /* Get the current user table entry. */
  113427. + userTaskEntry = &TaskTable->table[block];
  113428. +
  113429. + /* Are there tasks scheduled? */
  113430. + if (userTaskEntry->head == gcvNULL)
  113431. + {
  113432. + /* No, skip to the next block. */
  113433. + continue;
  113434. + }
  113435. +
  113436. + /* Get the interrupt number. */
  113437. + interrupt = _GetNextInterrupt(Command, block);
  113438. +
  113439. + gcmkTRACE_ZONE(
  113440. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  113441. + "%s(%d): block = %d interrupt = %d\n",
  113442. + __FUNCTION__, __LINE__,
  113443. + block, interrupt
  113444. + );
  113445. +
  113446. + /* Determine the command position. */
  113447. + eventCommand -= Command->info.eventCommandSize;
  113448. +
  113449. + /* Append an EVENT command. */
  113450. + gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
  113451. + Command, eventCommand, block, interrupt, gcvNULL
  113452. + ));
  113453. + }
  113454. + }
  113455. + while (gcvFALSE);
  113456. +
  113457. + /* Return status. */
  113458. + return status;
  113459. +}
  113460. +
  113461. +
  113462. +/******************************************************************************\
  113463. +******************************** Memory Management *****************************
  113464. +\******************************************************************************/
  113465. +
  113466. +static gceSTATUS
  113467. +_HardwareToKernel(
  113468. + IN gckOS Os,
  113469. + IN gcuVIDMEM_NODE_PTR Node,
  113470. + IN gctUINT32 Address,
  113471. + OUT gctPOINTER * KernelPointer
  113472. + )
  113473. +{
  113474. + gceSTATUS status;
  113475. + gckVIDMEM memory;
  113476. + gctUINT32 offset;
  113477. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY
  113478. + gctUINT32 nodePhysical;
  113479. +#endif
  113480. + status = gcvSTATUS_OK;
  113481. + /* Assume a non-virtual node and get the pool manager object. */
  113482. + memory = Node->VidMem.memory;
  113483. +
  113484. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY
  113485. + nodePhysical = memory->baseAddress
  113486. + + Node->VidMem.offset
  113487. + + Node->VidMem.alignment;
  113488. +
  113489. + if (Node->VidMem.kernelVirtual == gcvNULL)
  113490. + {
  113491. + status = gckOS_MapPhysical(Os,
  113492. + nodePhysical,
  113493. + Node->VidMem.bytes,
  113494. + (gctPOINTER *)&Node->VidMem.kernelVirtual);
  113495. +
  113496. + if (gcmkIS_ERROR(status))
  113497. + {
  113498. + return status;
  113499. + }
  113500. + }
  113501. +
  113502. + offset = Address - nodePhysical;
  113503. + *KernelPointer = (gctPOINTER)((gctUINT8_PTR)Node->VidMem.kernelVirtual + offset);
  113504. +#else
  113505. + /* Determine the header offset within the pool it is allocated in. */
  113506. + offset = Address - memory->baseAddress;
  113507. +
  113508. + /* Translate the offset into the kernel side pointer. */
  113509. + status = gckOS_GetKernelLogicalEx(
  113510. + Os,
  113511. + gcvCORE_VG,
  113512. + offset,
  113513. + KernelPointer
  113514. + );
  113515. +#endif
  113516. +
  113517. + /* Return status. */
  113518. + return status;
  113519. +}
  113520. +
  113521. +static gceSTATUS
  113522. +_ConvertUserCommandBufferPointer(
  113523. + IN gckVGCOMMAND Command,
  113524. + IN gcsCMDBUFFER_PTR UserCommandBuffer,
  113525. + OUT gcsCMDBUFFER_PTR * KernelCommandBuffer
  113526. + )
  113527. +{
  113528. + gceSTATUS status, last;
  113529. + gcsCMDBUFFER_PTR mappedUserCommandBuffer = gcvNULL;
  113530. +
  113531. + do
  113532. + {
  113533. + gctUINT32 headerAddress;
  113534. +
  113535. + /* Map the command buffer structure into the kernel space. */
  113536. + gcmkERR_BREAK(gckOS_MapUserPointer(
  113537. + Command->os,
  113538. + UserCommandBuffer,
  113539. + gcmSIZEOF(gcsCMDBUFFER),
  113540. + (gctPOINTER *) &mappedUserCommandBuffer
  113541. + ));
  113542. +
  113543. + /* Determine the address of the header. */
  113544. + headerAddress
  113545. + = mappedUserCommandBuffer->address
  113546. + - mappedUserCommandBuffer->bufferOffset;
  113547. +
  113548. + /* Translate the logical address to the kernel space. */
  113549. + gcmkERR_BREAK(_HardwareToKernel(
  113550. + Command->os,
  113551. + gcmUINT64_TO_PTR(mappedUserCommandBuffer->node),
  113552. + headerAddress,
  113553. + (gctPOINTER *) KernelCommandBuffer
  113554. + ));
  113555. + }
  113556. + while (gcvFALSE);
  113557. +
  113558. + /* Unmap the user command buffer. */
  113559. + if (mappedUserCommandBuffer != gcvNULL)
  113560. + {
  113561. + gcmkCHECK_STATUS(gckOS_UnmapUserPointer(
  113562. + Command->os,
  113563. + UserCommandBuffer,
  113564. + gcmSIZEOF(gcsCMDBUFFER),
  113565. + mappedUserCommandBuffer
  113566. + ));
  113567. + }
  113568. +
  113569. + /* Return status. */
  113570. + return status;
  113571. +}
  113572. +
  113573. +static gceSTATUS
  113574. +_AllocateLinear(
  113575. + IN gckVGCOMMAND Command,
  113576. + IN gctUINT Size,
  113577. + IN gctUINT Alignment,
  113578. + OUT gcuVIDMEM_NODE_PTR * Node,
  113579. + OUT gctUINT32 * Address,
  113580. + OUT gctPOINTER * Logical
  113581. + )
  113582. +{
  113583. + gceSTATUS status, last;
  113584. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  113585. + gctUINT32 address = (gctUINT32)~0;
  113586. +
  113587. + do
  113588. + {
  113589. + gcePOOL pool;
  113590. + gctPOINTER logical;
  113591. +
  113592. + /* Allocate from the system pool. */
  113593. + pool = gcvPOOL_SYSTEM;
  113594. +
  113595. + /* Allocate memory. */
  113596. + gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
  113597. + Command->kernel->kernel, &pool,
  113598. + Size, Alignment,
  113599. + gcvSURF_TYPE_UNKNOWN,
  113600. + &node
  113601. + ));
  113602. +
  113603. + /* Do not accept virtual pools for now because we don't handle the
  113604. + kernel pointer translation at the moment. */
  113605. + if (pool == gcvPOOL_VIRTUAL)
  113606. + {
  113607. + status = gcvSTATUS_OUT_OF_MEMORY;
  113608. + break;
  113609. + }
  113610. +
  113611. + /* Lock the command buffer. */
  113612. + gcmkERR_BREAK(gckVIDMEM_Lock(
  113613. + Command->kernel->kernel,
  113614. + node,
  113615. + gcvFALSE,
  113616. + &address
  113617. + ));
  113618. +
  113619. + /* Translate the logical address to the kernel space. */
  113620. + gcmkERR_BREAK(_HardwareToKernel(
  113621. + Command->os,
  113622. + node,
  113623. + address,
  113624. + &logical
  113625. + ));
  113626. +
  113627. + /* Set return values. */
  113628. + * Node = node;
  113629. + * Address = address;
  113630. + * Logical = logical;
  113631. +
  113632. + /* Success. */
  113633. + return gcvSTATUS_OK;
  113634. + }
  113635. + while (gcvFALSE);
  113636. +
  113637. + /* Roll back. */
  113638. + if (node != gcvNULL)
  113639. + {
  113640. + /* Unlock the command buffer. */
  113641. + if (address != ~0)
  113642. + {
  113643. + gcmkCHECK_STATUS(gckVIDMEM_Unlock(
  113644. + Command->kernel->kernel, node, gcvSURF_TYPE_UNKNOWN, gcvNULL
  113645. + ));
  113646. + }
  113647. +
  113648. + /* Free the command buffer. */
  113649. + gcmkCHECK_STATUS(gckVIDMEM_Free(
  113650. + node
  113651. + ));
  113652. + }
  113653. +
  113654. + /* Return status. */
  113655. + return status;
  113656. +}
  113657. +
  113658. +static gceSTATUS
  113659. +_FreeLinear(
  113660. + IN gckVGKERNEL Kernel,
  113661. + IN gcuVIDMEM_NODE_PTR Node
  113662. + )
  113663. +{
  113664. + gceSTATUS status;
  113665. +
  113666. + do
  113667. + {
  113668. + /* Unlock the linear buffer. */
  113669. + gcmkERR_BREAK(gckVIDMEM_Unlock(Kernel->kernel, Node, gcvSURF_TYPE_UNKNOWN, gcvNULL));
  113670. +
  113671. + /* Free the linear buffer. */
  113672. + gcmkERR_BREAK(gckVIDMEM_Free(Node));
  113673. + }
  113674. + while (gcvFALSE);
  113675. +
  113676. + /* Return status. */
  113677. + return status;
  113678. +}
  113679. +
  113680. +gceSTATUS
  113681. +_AllocateCommandBuffer(
  113682. + IN gckVGCOMMAND Command,
  113683. + IN gctSIZE_T Size,
  113684. + OUT gcsCMDBUFFER_PTR * CommandBuffer
  113685. + )
  113686. +{
  113687. + gceSTATUS status, last;
  113688. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  113689. +
  113690. + do
  113691. + {
  113692. + gctUINT alignedHeaderSize;
  113693. + gctUINT requestedSize;
  113694. + gctUINT allocationSize;
  113695. + gctUINT32 address = 0;
  113696. + gcsCMDBUFFER_PTR commandBuffer;
  113697. + gctUINT8_PTR endCommand;
  113698. +
  113699. + /* Determine the aligned header size. */
  113700. + alignedHeaderSize
  113701. + = gcmALIGN(gcmSIZEOF(gcsCMDBUFFER), Command->info.addressAlignment);
  113702. +
  113703. + /* Align the requested size. */
  113704. + requestedSize
  113705. + = gcmALIGN(Size, Command->info.commandAlignment);
  113706. +
  113707. + /* Determine the size of the buffer to allocate. */
  113708. + allocationSize
  113709. + = alignedHeaderSize
  113710. + + requestedSize
  113711. + + Command->info.staticTailSize;
  113712. +
  113713. + /* Allocate the command buffer. */
  113714. + gcmkERR_BREAK(_AllocateLinear(
  113715. + Command,
  113716. + allocationSize,
  113717. + Command->info.addressAlignment,
  113718. + &node,
  113719. + &address,
  113720. + (gctPOINTER *) &commandBuffer
  113721. + ));
  113722. +
  113723. + /* Initialize the structure. */
  113724. + commandBuffer->completion = gcvVACANT_BUFFER;
  113725. + commandBuffer->node = gcmPTR_TO_UINT64(node);
  113726. + commandBuffer->address = address + alignedHeaderSize;
  113727. + commandBuffer->bufferOffset = alignedHeaderSize;
  113728. + commandBuffer->size = requestedSize;
  113729. + commandBuffer->offset = requestedSize;
  113730. + commandBuffer->nextAllocated = gcvNULL;
  113731. + commandBuffer->nextSubBuffer = gcvNULL;
  113732. +
  113733. + /* Determine the data count. */
  113734. + commandBuffer->dataCount
  113735. + = (requestedSize + Command->info.staticTailSize)
  113736. + / Command->info.commandAlignment;
  113737. +
  113738. + /* Determine the location of the END command. */
  113739. + endCommand
  113740. + = (gctUINT8_PTR) commandBuffer
  113741. + + alignedHeaderSize
  113742. + + requestedSize;
  113743. +
  113744. + /* Append an END command. */
  113745. + gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
  113746. + Command,
  113747. + endCommand,
  113748. + Command->info.feBufferInt,
  113749. + gcvNULL
  113750. + ));
  113751. +
  113752. + /* Set the return pointer. */
  113753. + * CommandBuffer = commandBuffer;
  113754. +
  113755. + /* Success. */
  113756. + return gcvSTATUS_OK;
  113757. + }
  113758. + while (gcvFALSE);
  113759. +
  113760. + /* Roll back. */
  113761. + if (node != gcvNULL)
  113762. + {
  113763. + /* Free the command buffer. */
  113764. + gcmkCHECK_STATUS(_FreeLinear(Command->kernel, node));
  113765. + }
  113766. +
  113767. + /* Return status. */
  113768. + return status;
  113769. +}
  113770. +
  113771. +static gceSTATUS
  113772. +_FreeCommandBuffer(
  113773. + IN gckVGKERNEL Kernel,
  113774. + IN gcsCMDBUFFER_PTR CommandBuffer
  113775. + )
  113776. +{
  113777. + gceSTATUS status;
  113778. +
  113779. + /* Free the buffer. */
  113780. + status = _FreeLinear(Kernel, gcmUINT64_TO_PTR(CommandBuffer->node));
  113781. +
  113782. + /* Return status. */
  113783. + return status;
  113784. +}
  113785. +
  113786. +
  113787. +/******************************************************************************\
  113788. +****************************** TS Overflow Handler *****************************
  113789. +\******************************************************************************/
  113790. +
  113791. +static gceSTATUS
  113792. +_EventHandler_TSOverflow(
  113793. + IN gckVGKERNEL Kernel
  113794. + )
  113795. +{
  113796. + gcmkTRACE(
  113797. + gcvLEVEL_ERROR,
  113798. + "%s(%d): **** TS OVERFLOW ENCOUNTERED ****\n",
  113799. + __FUNCTION__, __LINE__
  113800. + );
  113801. +
  113802. + return gcvSTATUS_OK;
  113803. +}
  113804. +
  113805. +
  113806. +/******************************************************************************\
  113807. +****************************** Bus Error Handler *******************************
  113808. +\******************************************************************************/
  113809. +
  113810. +static gceSTATUS
  113811. +_EventHandler_BusError(
  113812. + IN gckVGKERNEL Kernel
  113813. + )
  113814. +{
  113815. + gcmkTRACE(
  113816. + gcvLEVEL_ERROR,
  113817. + "%s(%d): **** BUS ERROR ENCOUNTERED ****\n",
  113818. + __FUNCTION__, __LINE__
  113819. + );
  113820. +
  113821. + return gcvSTATUS_OK;
  113822. +}
  113823. +
  113824. +/******************************************************************************\
  113825. +****************************** Power Stall Handler *******************************
  113826. +\******************************************************************************/
  113827. +
  113828. +static gceSTATUS
  113829. +_EventHandler_PowerStall(
  113830. + IN gckVGKERNEL Kernel
  113831. + )
  113832. +{
  113833. + /* Signal. */
  113834. + return gckOS_Signal(
  113835. + Kernel->os,
  113836. + Kernel->command->powerStallSignal,
  113837. + gcvTRUE);
  113838. +}
  113839. +
  113840. +/******************************************************************************\
  113841. +******************************** Task Routines *********************************
  113842. +\******************************************************************************/
  113843. +
  113844. +typedef gceSTATUS (* gctTASKROUTINE) (
  113845. + gckVGCOMMAND Command,
  113846. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113847. + );
  113848. +
  113849. +static gceSTATUS
  113850. +_TaskLink(
  113851. + gckVGCOMMAND Command,
  113852. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113853. + );
  113854. +
  113855. +static gceSTATUS
  113856. +_TaskCluster(
  113857. + gckVGCOMMAND Command,
  113858. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113859. + );
  113860. +
  113861. +static gceSTATUS
  113862. +_TaskIncrement(
  113863. + gckVGCOMMAND Command,
  113864. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113865. + );
  113866. +
  113867. +static gceSTATUS
  113868. +_TaskDecrement(
  113869. + gckVGCOMMAND Command,
  113870. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113871. + );
  113872. +
  113873. +static gceSTATUS
  113874. +_TaskSignal(
  113875. + gckVGCOMMAND Command,
  113876. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113877. + );
  113878. +
  113879. +static gceSTATUS
  113880. +_TaskLockdown(
  113881. + gckVGCOMMAND Command,
  113882. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113883. + );
  113884. +
  113885. +static gceSTATUS
  113886. +_TaskUnlockVideoMemory(
  113887. + gckVGCOMMAND Command,
  113888. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113889. + );
  113890. +
  113891. +static gceSTATUS
  113892. +_TaskFreeVideoMemory(
  113893. + gckVGCOMMAND Command,
  113894. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113895. + );
  113896. +
  113897. +static gceSTATUS
  113898. +_TaskFreeContiguousMemory(
  113899. + gckVGCOMMAND Command,
  113900. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113901. + );
  113902. +
  113903. +static gceSTATUS
  113904. +_TaskUnmapUserMemory(
  113905. + gckVGCOMMAND Command,
  113906. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113907. + );
  113908. +
  113909. +static gctTASKROUTINE _taskRoutine[] =
  113910. +{
  113911. + _TaskLink, /* gcvTASK_LINK */
  113912. + _TaskCluster, /* gcvTASK_CLUSTER */
  113913. + _TaskIncrement, /* gcvTASK_INCREMENT */
  113914. + _TaskDecrement, /* gcvTASK_DECREMENT */
  113915. + _TaskSignal, /* gcvTASK_SIGNAL */
  113916. + _TaskLockdown, /* gcvTASK_LOCKDOWN */
  113917. + _TaskUnlockVideoMemory, /* gcvTASK_UNLOCK_VIDEO_MEMORY */
  113918. + _TaskFreeVideoMemory, /* gcvTASK_FREE_VIDEO_MEMORY */
  113919. + _TaskFreeContiguousMemory, /* gcvTASK_FREE_CONTIGUOUS_MEMORY */
  113920. + _TaskUnmapUserMemory, /* gcvTASK_UNMAP_USER_MEMORY */
  113921. +};
  113922. +
  113923. +static gceSTATUS
  113924. +_TaskLink(
  113925. + gckVGCOMMAND Command,
  113926. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113927. + )
  113928. +{
  113929. + /* Cast the task pointer. */
  113930. + gcsTASK_LINK_PTR task = (gcsTASK_LINK_PTR) TaskHeader->task;
  113931. +
  113932. + /* Save the pointer to the container. */
  113933. + gcsTASK_CONTAINER_PTR container = TaskHeader->container;
  113934. +
  113935. + /* No more tasks in the list? */
  113936. + if (task->task == gcvNULL)
  113937. + {
  113938. + /* Reset the entry. */
  113939. + TaskHeader->container = gcvNULL;
  113940. + TaskHeader->task = gcvNULL;
  113941. + TaskHeader->link = gcvNULL;
  113942. + }
  113943. + else
  113944. + {
  113945. + /* Update the entry. */
  113946. + TaskHeader->container = task->cotainer;
  113947. + TaskHeader->task = task->task;
  113948. + }
  113949. +
  113950. + /* Decrement the task buffer reference. */
  113951. + gcmkASSERT(container->referenceCount >= 0);
  113952. + if (container->referenceCount == 0)
  113953. + {
  113954. + /* Free the container. */
  113955. + _FreeTaskContainer(Command, container);
  113956. + }
  113957. +
  113958. + /* Success. */
  113959. + return gcvSTATUS_OK;
  113960. +}
  113961. +
  113962. +static gceSTATUS
  113963. +_TaskCluster(
  113964. + gckVGCOMMAND Command,
  113965. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  113966. + )
  113967. +{
  113968. + gceSTATUS status = gcvSTATUS_OK;
  113969. +
  113970. + /* Cast the task pointer. */
  113971. + gcsTASK_CLUSTER_PTR cluster = (gcsTASK_CLUSTER_PTR) TaskHeader->task;
  113972. +
  113973. + /* Get the number of tasks. */
  113974. + gctUINT taskCount = cluster->taskCount;
  113975. +
  113976. + /* Advance to the next task. */
  113977. + TaskHeader->task = (gcsTASK_HEADER_PTR) (cluster + 1);
  113978. +
  113979. + /* Perform all tasks in the cluster. */
  113980. + while (taskCount)
  113981. + {
  113982. + /* Perform the current task. */
  113983. + gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
  113984. + Command,
  113985. + TaskHeader
  113986. + ));
  113987. +
  113988. + /* Update the task count. */
  113989. + taskCount -= 1;
  113990. + }
  113991. +
  113992. + /* Return status. */
  113993. + return status;
  113994. +}
  113995. +
  113996. +static gceSTATUS
  113997. +_TaskIncrement(
  113998. + gckVGCOMMAND Command,
  113999. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114000. + )
  114001. +{
  114002. + gceSTATUS status;
  114003. +
  114004. + do
  114005. + {
  114006. + /* Cast the task pointer. */
  114007. + gcsTASK_INCREMENT_PTR task = (gcsTASK_INCREMENT_PTR) TaskHeader->task;
  114008. +
  114009. + /* Convert physical into logical address. */
  114010. + gctUINT32_PTR logical;
  114011. + gcmkERR_BREAK(gckOS_MapPhysical(
  114012. + Command->os,
  114013. + task->address,
  114014. + gcmSIZEOF(gctUINT32),
  114015. + (gctPOINTER *) &logical
  114016. + ));
  114017. +
  114018. + /* Increment data. */
  114019. + (* logical) += 1;
  114020. +
  114021. + /* Unmap the physical memory. */
  114022. + gcmkERR_BREAK(gckOS_UnmapPhysical(
  114023. + Command->os,
  114024. + logical,
  114025. + gcmSIZEOF(gctUINT32)
  114026. + ));
  114027. +
  114028. + /* Update the reference counter. */
  114029. + TaskHeader->container->referenceCount -= 1;
  114030. +
  114031. + /* Update the task pointer. */
  114032. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114033. + }
  114034. + while (gcvFALSE);
  114035. +
  114036. + /* Return status. */
  114037. + return status;
  114038. +}
  114039. +
  114040. +static gceSTATUS
  114041. +_TaskDecrement(
  114042. + gckVGCOMMAND Command,
  114043. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114044. + )
  114045. +{
  114046. + gceSTATUS status;
  114047. +
  114048. + do
  114049. + {
  114050. + /* Cast the task pointer. */
  114051. + gcsTASK_DECREMENT_PTR task = (gcsTASK_DECREMENT_PTR) TaskHeader->task;
  114052. +
  114053. + /* Convert physical into logical address. */
  114054. + gctUINT32_PTR logical;
  114055. + gcmkERR_BREAK(gckOS_MapPhysical(
  114056. + Command->os,
  114057. + task->address,
  114058. + gcmSIZEOF(gctUINT32),
  114059. + (gctPOINTER *) &logical
  114060. + ));
  114061. +
  114062. + /* Decrement data. */
  114063. + (* logical) -= 1;
  114064. +
  114065. + /* Unmap the physical memory. */
  114066. + gcmkERR_BREAK(gckOS_UnmapPhysical(
  114067. + Command->os,
  114068. + logical,
  114069. + gcmSIZEOF(gctUINT32)
  114070. + ));
  114071. +
  114072. + /* Update the reference counter. */
  114073. + TaskHeader->container->referenceCount -= 1;
  114074. +
  114075. + /* Update the task pointer. */
  114076. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114077. + }
  114078. + while (gcvFALSE);
  114079. +
  114080. + /* Return status. */
  114081. + return status;
  114082. +}
  114083. +
  114084. +static gceSTATUS
  114085. +_TaskSignal(
  114086. + gckVGCOMMAND Command,
  114087. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114088. + )
  114089. +{
  114090. + gceSTATUS status;
  114091. +
  114092. + do
  114093. + {
  114094. + /* Cast the task pointer. */
  114095. + gcsTASK_SIGNAL_PTR task = (gcsTASK_SIGNAL_PTR) TaskHeader->task;
  114096. +
  114097. +
  114098. + /* Map the signal into kernel space. */
  114099. +#ifdef __QNXNTO__
  114100. + gcmkERR_BREAK(gckOS_UserSignal(
  114101. + Command->os, task->signal, task->rcvid, task->coid
  114102. + ));
  114103. +#else
  114104. + gcmkERR_BREAK(gckOS_UserSignal(
  114105. + Command->os, task->signal, task->process
  114106. + ));
  114107. +#endif /* __QNXNTO__ */
  114108. +
  114109. + /* Update the reference counter. */
  114110. + TaskHeader->container->referenceCount -= 1;
  114111. +
  114112. + /* Update the task pointer. */
  114113. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114114. + }
  114115. + while (gcvFALSE);
  114116. +
  114117. + /* Return status. */
  114118. + return status;
  114119. +}
  114120. +
  114121. +static gceSTATUS
  114122. +_TaskLockdown(
  114123. + gckVGCOMMAND Command,
  114124. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114125. + )
  114126. +{
  114127. + gceSTATUS status;
  114128. + gctUINT32_PTR userCounter = gcvNULL;
  114129. + gctUINT32_PTR kernelCounter = gcvNULL;
  114130. + gctSIGNAL signal = gcvNULL;
  114131. +
  114132. + do
  114133. + {
  114134. + /* Cast the task pointer. */
  114135. + gcsTASK_LOCKDOWN_PTR task = (gcsTASK_LOCKDOWN_PTR) TaskHeader->task;
  114136. +
  114137. + /* Convert physical addresses into logical. */
  114138. + gcmkERR_BREAK(gckOS_MapPhysical(
  114139. + Command->os,
  114140. + task->userCounter,
  114141. + gcmSIZEOF(gctUINT32),
  114142. + (gctPOINTER *) &userCounter
  114143. + ));
  114144. +
  114145. + gcmkERR_BREAK(gckOS_MapPhysical(
  114146. + Command->os,
  114147. + task->kernelCounter,
  114148. + gcmSIZEOF(gctUINT32),
  114149. + (gctPOINTER *) &kernelCounter
  114150. + ));
  114151. +
  114152. + /* Update the kernel counter. */
  114153. + (* kernelCounter) += 1;
  114154. +
  114155. + /* Are the counters equal? */
  114156. + if ((* userCounter) == (* kernelCounter))
  114157. + {
  114158. + /* Map the signal into kernel space. */
  114159. + gcmkERR_BREAK(gckOS_MapSignal(
  114160. + Command->os, task->signal, task->process, &signal
  114161. + ));
  114162. +
  114163. + if (signal == gcvNULL)
  114164. + {
  114165. + /* Signal. */
  114166. + gcmkERR_BREAK(gckOS_Signal(
  114167. + Command->os, task->signal, gcvTRUE
  114168. + ));
  114169. + }
  114170. + else
  114171. + {
  114172. + /* Signal. */
  114173. + gcmkERR_BREAK(gckOS_Signal(
  114174. + Command->os, signal, gcvTRUE
  114175. + ));
  114176. + }
  114177. + }
  114178. +
  114179. + /* Update the reference counter. */
  114180. + TaskHeader->container->referenceCount -= 1;
  114181. +
  114182. + /* Update the task pointer. */
  114183. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114184. + }
  114185. + while (gcvFALSE);
  114186. +
  114187. + /* Destroy the mapped signal. */
  114188. + if (signal != gcvNULL)
  114189. + {
  114190. + gcmkVERIFY_OK(gckOS_DestroySignal(
  114191. + Command->os, signal
  114192. + ));
  114193. + }
  114194. +
  114195. + /* Unmap the physical memory. */
  114196. + if (kernelCounter != gcvNULL)
  114197. + {
  114198. + gcmkVERIFY_OK(gckOS_UnmapPhysical(
  114199. + Command->os,
  114200. + kernelCounter,
  114201. + gcmSIZEOF(gctUINT32)
  114202. + ));
  114203. + }
  114204. +
  114205. + if (userCounter != gcvNULL)
  114206. + {
  114207. + gcmkVERIFY_OK(gckOS_UnmapPhysical(
  114208. + Command->os,
  114209. + userCounter,
  114210. + gcmSIZEOF(gctUINT32)
  114211. + ));
  114212. + }
  114213. +
  114214. + /* Return status. */
  114215. + return status;
  114216. +}
  114217. +
  114218. +static gceSTATUS
  114219. +_TaskUnlockVideoMemory(
  114220. + gckVGCOMMAND Command,
  114221. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114222. + )
  114223. +{
  114224. + gceSTATUS status;
  114225. +
  114226. + do
  114227. + {
  114228. + /* Cast the task pointer. */
  114229. + gcsTASK_UNLOCK_VIDEO_MEMORY_PTR task
  114230. + = (gcsTASK_UNLOCK_VIDEO_MEMORY_PTR) TaskHeader->task;
  114231. +
  114232. + /* Unlock video memory. */
  114233. + gcmkERR_BREAK(gckVIDMEM_Unlock(
  114234. + Command->kernel->kernel,
  114235. + gcmUINT64_TO_PTR(task->node),
  114236. + gcvSURF_TYPE_UNKNOWN,
  114237. + gcvNULL));
  114238. +
  114239. + /* Update the reference counter. */
  114240. + TaskHeader->container->referenceCount -= 1;
  114241. +
  114242. + /* Update the task pointer. */
  114243. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114244. + }
  114245. + while (gcvFALSE);
  114246. +
  114247. + /* Return status. */
  114248. + return status;
  114249. +}
  114250. +
  114251. +static gceSTATUS
  114252. +_TaskFreeVideoMemory(
  114253. + gckVGCOMMAND Command,
  114254. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114255. + )
  114256. +{
  114257. + gceSTATUS status;
  114258. +
  114259. + do
  114260. + {
  114261. + /* Cast the task pointer. */
  114262. + gcsTASK_FREE_VIDEO_MEMORY_PTR task
  114263. + = (gcsTASK_FREE_VIDEO_MEMORY_PTR) TaskHeader->task;
  114264. +
  114265. + /* Free video memory. */
  114266. + gcmkERR_BREAK(gckVIDMEM_Free(gcmUINT64_TO_PTR(task->node)));
  114267. +
  114268. + /* Update the reference counter. */
  114269. + TaskHeader->container->referenceCount -= 1;
  114270. +
  114271. + /* Update the task pointer. */
  114272. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114273. + }
  114274. + while (gcvFALSE);
  114275. +
  114276. + /* Return status. */
  114277. + return status;
  114278. +}
  114279. +
  114280. +static gceSTATUS
  114281. +_TaskFreeContiguousMemory(
  114282. + gckVGCOMMAND Command,
  114283. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114284. + )
  114285. +{
  114286. + gceSTATUS status;
  114287. +
  114288. + do
  114289. + {
  114290. + /* Cast the task pointer. */
  114291. + gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR task
  114292. + = (gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR) TaskHeader->task;
  114293. +
  114294. + /* Free contiguous memory. */
  114295. + gcmkERR_BREAK(gckOS_FreeContiguous(
  114296. + Command->os, task->physical, task->logical, task->bytes
  114297. + ));
  114298. +
  114299. + /* Update the reference counter. */
  114300. + TaskHeader->container->referenceCount -= 1;
  114301. +
  114302. + /* Update the task pointer. */
  114303. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114304. + }
  114305. + while (gcvFALSE);
  114306. +
  114307. + /* Return status. */
  114308. + return status;
  114309. +}
  114310. +
  114311. +static gceSTATUS
  114312. +_TaskUnmapUserMemory(
  114313. + gckVGCOMMAND Command,
  114314. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  114315. + )
  114316. +{
  114317. + gceSTATUS status;
  114318. +
  114319. + do
  114320. + {
  114321. + /* Cast the task pointer. */
  114322. + gcsTASK_UNMAP_USER_MEMORY_PTR task
  114323. + = (gcsTASK_UNMAP_USER_MEMORY_PTR) TaskHeader->task;
  114324. +
  114325. + /* Unmap the user memory. */
  114326. + gcmkERR_BREAK(gckOS_UnmapUserMemory(
  114327. + Command->os, gcvCORE_VG, task->memory, task->size, task->info, task->address
  114328. + ));
  114329. +
  114330. + /* Update the reference counter. */
  114331. + TaskHeader->container->referenceCount -= 1;
  114332. +
  114333. + /* Update the task pointer. */
  114334. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  114335. + }
  114336. + while (gcvFALSE);
  114337. +
  114338. + /* Return status. */
  114339. + return status;
  114340. +}
  114341. +
  114342. +/******************************************************************************\
  114343. +************ Hardware Block Interrupt Handlers For Scheduled Events ************
  114344. +\******************************************************************************/
  114345. +
  114346. +static gceSTATUS
  114347. +_EventHandler_Block(
  114348. + IN gckVGKERNEL Kernel,
  114349. + IN gcsBLOCK_TASK_ENTRY_PTR TaskHeader,
  114350. + IN gctBOOL ProcessAll
  114351. + )
  114352. +{
  114353. + gceSTATUS status, last;
  114354. +
  114355. + gcmkHEADER_ARG("Kernel=0x%x TaskHeader=0x%x ProcessAll=0x%x", Kernel, TaskHeader, ProcessAll);
  114356. + /* Verify the arguments. */
  114357. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  114358. +
  114359. + do
  114360. + {
  114361. + gckVGCOMMAND command;
  114362. +
  114363. + /* Get the command buffer object. */
  114364. + command = Kernel->command;
  114365. +
  114366. + /* Increment the interrupt usage semaphore. */
  114367. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  114368. + command->os, TaskHeader->interruptSemaphore
  114369. + ));
  114370. +
  114371. + /* Acquire the mutex. */
  114372. + gcmkERR_BREAK(gckOS_AcquireMutex(
  114373. + command->os,
  114374. + command->taskMutex,
  114375. + gcvINFINITE
  114376. + ));
  114377. +
  114378. + /* Verify inputs. */
  114379. + gcmkASSERT(TaskHeader != gcvNULL);
  114380. + gcmkASSERT(TaskHeader->container != gcvNULL);
  114381. + gcmkASSERT(TaskHeader->task != gcvNULL);
  114382. + gcmkASSERT(TaskHeader->link != gcvNULL);
  114383. +
  114384. + /* Process tasks. */
  114385. + do
  114386. + {
  114387. + /* Process the current task. */
  114388. + gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
  114389. + command,
  114390. + TaskHeader
  114391. + ));
  114392. +
  114393. + /* Is the next task is LINK? */
  114394. + if (TaskHeader->task->id == gcvTASK_LINK)
  114395. + {
  114396. + gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
  114397. + command,
  114398. + TaskHeader
  114399. + ));
  114400. +
  114401. + /* Done. */
  114402. + break;
  114403. + }
  114404. + }
  114405. + while (ProcessAll);
  114406. +
  114407. + /* Release the mutex. */
  114408. + gcmkCHECK_STATUS(gckOS_ReleaseMutex(
  114409. + command->os,
  114410. + command->taskMutex
  114411. + ));
  114412. + }
  114413. + while (gcvFALSE);
  114414. +
  114415. + gcmkFOOTER();
  114416. + /* Return status. */
  114417. + return status;
  114418. +}
  114419. +
  114420. +gcmDECLARE_INTERRUPT_HANDLER(COMMAND, 0)
  114421. +{
  114422. + gceSTATUS status, last;
  114423. +
  114424. + gcmkHEADER_ARG("Kernel=0x%x ", Kernel);
  114425. +
  114426. + /* Verify the arguments. */
  114427. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  114428. +
  114429. +
  114430. + do
  114431. + {
  114432. + gckVGCOMMAND command;
  114433. + gcsKERNEL_QUEUE_HEADER_PTR mergeQueue;
  114434. + gcsKERNEL_QUEUE_HEADER_PTR queueTail;
  114435. + gcsKERNEL_CMDQUEUE_PTR entry;
  114436. + gctUINT entryCount;
  114437. +
  114438. + /* Get the command buffer object. */
  114439. + command = Kernel->command;
  114440. +
  114441. + /* Acquire the mutex. */
  114442. + gcmkERR_BREAK(gckOS_AcquireMutex(
  114443. + command->os,
  114444. + command->queueMutex,
  114445. + gcvINFINITE
  114446. + ));
  114447. +
  114448. + /* Get the current queue. */
  114449. + queueTail = command->queueTail;
  114450. +
  114451. + /* Get the current queue entry. */
  114452. + entry = queueTail->currentEntry;
  114453. +
  114454. + /* Get the number of entries in the queue. */
  114455. + entryCount = queueTail->pending;
  114456. +
  114457. + /* Process all entries. */
  114458. + while (gcvTRUE)
  114459. + {
  114460. + /* Call post-execution function. */
  114461. + status = entry->handler(Kernel, entry);
  114462. +
  114463. + /* Failed? */
  114464. + if (gcmkIS_ERROR(status))
  114465. + {
  114466. + gcmkTRACE_ZONE(
  114467. + gcvLEVEL_ERROR,
  114468. + gcvZONE_COMMAND,
  114469. + "[%s] line %d: post action failed.\n",
  114470. + __FUNCTION__, __LINE__
  114471. + );
  114472. + }
  114473. +
  114474. + /* Executed the next buffer? */
  114475. + if (status == gcvSTATUS_EXECUTED)
  114476. + {
  114477. + /* Update the queue. */
  114478. + queueTail->pending = entryCount;
  114479. + queueTail->currentEntry = entry;
  114480. +
  114481. + /* Success. */
  114482. + status = gcvSTATUS_OK;
  114483. +
  114484. + /* Break out of the loop. */
  114485. + break;
  114486. + }
  114487. +
  114488. + /* Advance to the next entry. */
  114489. + entry += 1;
  114490. + entryCount -= 1;
  114491. +
  114492. + /* Last entry? */
  114493. + if (entryCount == 0)
  114494. + {
  114495. + /* Reset the queue to idle. */
  114496. + queueTail->pending = 0;
  114497. +
  114498. + /* Get a shortcut to the queue to merge with. */
  114499. + mergeQueue = command->mergeQueue;
  114500. +
  114501. + /* Merge the queues if necessary. */
  114502. + if (mergeQueue != queueTail)
  114503. + {
  114504. + gcmkASSERT(mergeQueue < queueTail);
  114505. + gcmkASSERT(mergeQueue->next == queueTail);
  114506. +
  114507. + mergeQueue->size
  114508. + += gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
  114509. + + queueTail->size;
  114510. +
  114511. + mergeQueue->next = queueTail->next;
  114512. + }
  114513. +
  114514. + /* Advance to the next queue. */
  114515. + queueTail = queueTail->next;
  114516. +
  114517. + /* Did it wrap around? */
  114518. + if (command->queue == queueTail)
  114519. + {
  114520. + /* Reset merge queue. */
  114521. + command->mergeQueue = queueTail;
  114522. + }
  114523. +
  114524. + /* Set new queue. */
  114525. + command->queueTail = queueTail;
  114526. +
  114527. + /* Is the next queue scheduled? */
  114528. + if (queueTail->pending > 0)
  114529. + {
  114530. + gcsCMDBUFFER_PTR commandBuffer;
  114531. +
  114532. + /* The first entry must be a command buffer. */
  114533. + commandBuffer = queueTail->currentEntry->commandBuffer;
  114534. +
  114535. + /* Start the command processor. */
  114536. + status = gckVGHARDWARE_Execute(
  114537. + command->hardware,
  114538. + commandBuffer->address,
  114539. + commandBuffer->dataCount
  114540. + );
  114541. +
  114542. + /* Failed? */
  114543. + if (gcmkIS_ERROR(status))
  114544. + {
  114545. + gcmkTRACE_ZONE(
  114546. + gcvLEVEL_ERROR,
  114547. + gcvZONE_COMMAND,
  114548. + "[%s] line %d: failed to start the next queue.\n",
  114549. + __FUNCTION__, __LINE__
  114550. + );
  114551. + }
  114552. + }
  114553. + else
  114554. + {
  114555. + status = gckVGHARDWARE_SetPowerManagementState(
  114556. + Kernel->command->hardware, gcvPOWER_IDLE_BROADCAST
  114557. + );
  114558. + }
  114559. +
  114560. + /* Break out of the loop. */
  114561. + break;
  114562. + }
  114563. + }
  114564. +
  114565. + /* Release the mutex. */
  114566. + gcmkCHECK_STATUS(gckOS_ReleaseMutex(
  114567. + command->os,
  114568. + command->queueMutex
  114569. + ));
  114570. + }
  114571. + while (gcvFALSE);
  114572. +
  114573. +
  114574. + gcmkFOOTER();
  114575. + /* Return status. */
  114576. + return status;
  114577. +}
  114578. +
  114579. +/* Define standard block interrupt handlers. */
  114580. +gcmDEFINE_INTERRUPT_HANDLER(TESSELLATOR, 0)
  114581. +gcmDEFINE_INTERRUPT_HANDLER(VG, 0)
  114582. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 0)
  114583. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 1)
  114584. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 2)
  114585. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 3)
  114586. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 4)
  114587. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 5)
  114588. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 6)
  114589. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 7)
  114590. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 8)
  114591. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 9)
  114592. +
  114593. +/* The entries in the array are arranged by event priority. */
  114594. +static gcsBLOCK_INTERRUPT_HANDLER _blockHandlers[] =
  114595. +{
  114596. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(TESSELLATOR, 0),
  114597. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(VG, 0),
  114598. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 0),
  114599. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 1),
  114600. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 2),
  114601. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 3),
  114602. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 4),
  114603. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 5),
  114604. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 6),
  114605. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 7),
  114606. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 8),
  114607. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 9),
  114608. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(COMMAND, 0),
  114609. +};
  114610. +
  114611. +
  114612. +/******************************************************************************\
  114613. +************************* Static Command Buffer Handlers ***********************
  114614. +\******************************************************************************/
  114615. +
  114616. +static gceSTATUS
  114617. +_UpdateStaticCommandBuffer(
  114618. + IN gckVGKERNEL Kernel,
  114619. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114620. + )
  114621. +{
  114622. + gcmkTRACE_ZONE(
  114623. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114624. + "%s(%d)\n",
  114625. + __FUNCTION__, __LINE__
  114626. + );
  114627. +
  114628. + /* Success. */
  114629. + return gcvSTATUS_OK;
  114630. +}
  114631. +
  114632. +static gceSTATUS
  114633. +_ExecuteStaticCommandBuffer(
  114634. + IN gckVGKERNEL Kernel,
  114635. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114636. + )
  114637. +{
  114638. + gceSTATUS status;
  114639. +
  114640. + do
  114641. + {
  114642. + gcsCMDBUFFER_PTR commandBuffer;
  114643. +
  114644. + /* Cast the command buffer header. */
  114645. + commandBuffer = Entry->commandBuffer;
  114646. +
  114647. + /* Set to update the command buffer next time. */
  114648. + Entry->handler = _UpdateStaticCommandBuffer;
  114649. +
  114650. + gcmkTRACE_ZONE(
  114651. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114652. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  114653. + __FUNCTION__, __LINE__,
  114654. + commandBuffer->address,
  114655. + commandBuffer->dataCount
  114656. + );
  114657. +
  114658. + /* Start the command processor. */
  114659. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  114660. + Kernel->hardware,
  114661. + commandBuffer->address,
  114662. + commandBuffer->dataCount
  114663. + ));
  114664. +
  114665. + /* Success. */
  114666. + return gcvSTATUS_EXECUTED;
  114667. + }
  114668. + while (gcvFALSE);
  114669. +
  114670. + /* Return status. */
  114671. + return status;
  114672. +}
  114673. +
  114674. +static gceSTATUS
  114675. +_UpdateLastStaticCommandBuffer(
  114676. + IN gckVGKERNEL Kernel,
  114677. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114678. + )
  114679. +{
  114680. +#if gcvDEBUG || gcdFORCE_MESSAGES
  114681. + /* Get the command buffer header. */
  114682. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  114683. +
  114684. + /* Validate the command buffer. */
  114685. + gcmkASSERT(commandBuffer->completion != gcvNULL);
  114686. + gcmkASSERT(commandBuffer->completion != gcvVACANT_BUFFER);
  114687. +
  114688. +#endif
  114689. +
  114690. + gcmkTRACE_ZONE(
  114691. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114692. + "%s(%d): processing all tasks scheduled for FE.\n",
  114693. + __FUNCTION__, __LINE__
  114694. + );
  114695. +
  114696. + /* Perform scheduled tasks. */
  114697. + return _EventHandler_Block(
  114698. + Kernel,
  114699. + &Kernel->command->taskTable[gcvBLOCK_COMMAND],
  114700. + gcvTRUE
  114701. + );
  114702. +}
  114703. +
  114704. +static gceSTATUS
  114705. +_ExecuteLastStaticCommandBuffer(
  114706. + IN gckVGKERNEL Kernel,
  114707. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114708. + )
  114709. +{
  114710. + gceSTATUS status;
  114711. +
  114712. + do
  114713. + {
  114714. + /* Cast the command buffer header. */
  114715. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  114716. +
  114717. + /* Set to update the command buffer next time. */
  114718. + Entry->handler = _UpdateLastStaticCommandBuffer;
  114719. +
  114720. + gcmkTRACE_ZONE(
  114721. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114722. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  114723. + __FUNCTION__, __LINE__,
  114724. + commandBuffer->address,
  114725. + commandBuffer->dataCount
  114726. + );
  114727. +
  114728. + /* Start the command processor. */
  114729. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  114730. + Kernel->hardware,
  114731. + commandBuffer->address,
  114732. + commandBuffer->dataCount
  114733. + ));
  114734. +
  114735. + /* Success. */
  114736. + return gcvSTATUS_EXECUTED;
  114737. + }
  114738. + while (gcvFALSE);
  114739. +
  114740. + /* Return status. */
  114741. + return status;
  114742. +}
  114743. +
  114744. +
  114745. +/******************************************************************************\
  114746. +************************* Dynamic Command Buffer Handlers **********************
  114747. +\******************************************************************************/
  114748. +
  114749. +static gceSTATUS
  114750. +_UpdateDynamicCommandBuffer(
  114751. + IN gckVGKERNEL Kernel,
  114752. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114753. + )
  114754. +{
  114755. + gcmkTRACE_ZONE(
  114756. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114757. + "%s(%d)\n",
  114758. + __FUNCTION__, __LINE__
  114759. + );
  114760. +
  114761. + /* Success. */
  114762. + return gcvSTATUS_OK;
  114763. +}
  114764. +
  114765. +static gceSTATUS
  114766. +_ExecuteDynamicCommandBuffer(
  114767. + IN gckVGKERNEL Kernel,
  114768. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114769. + )
  114770. +{
  114771. + gceSTATUS status;
  114772. +
  114773. + do
  114774. + {
  114775. + /* Cast the command buffer header. */
  114776. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  114777. +
  114778. + /* Set to update the command buffer next time. */
  114779. + Entry->handler = _UpdateDynamicCommandBuffer;
  114780. +
  114781. + gcmkTRACE_ZONE(
  114782. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114783. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  114784. + __FUNCTION__, __LINE__,
  114785. + commandBuffer->address,
  114786. + commandBuffer->dataCount
  114787. + );
  114788. +
  114789. + /* Start the command processor. */
  114790. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  114791. + Kernel->hardware,
  114792. + commandBuffer->address,
  114793. + commandBuffer->dataCount
  114794. + ));
  114795. +
  114796. + /* Success. */
  114797. + return gcvSTATUS_EXECUTED;
  114798. + }
  114799. + while (gcvFALSE);
  114800. +
  114801. + /* Return status. */
  114802. + return status;
  114803. +}
  114804. +
  114805. +static gceSTATUS
  114806. +_UpdateLastDynamicCommandBuffer(
  114807. + IN gckVGKERNEL Kernel,
  114808. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114809. + )
  114810. +{
  114811. +#if gcvDEBUG || gcdFORCE_MESSAGES
  114812. + /* Get the command buffer header. */
  114813. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  114814. +
  114815. + /* Validate the command buffer. */
  114816. + gcmkASSERT(commandBuffer->completion != gcvNULL);
  114817. + gcmkASSERT(commandBuffer->completion != gcvVACANT_BUFFER);
  114818. +
  114819. +#endif
  114820. +
  114821. + gcmkTRACE_ZONE(
  114822. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114823. + "%s(%d): processing all tasks scheduled for FE.\n",
  114824. + __FUNCTION__, __LINE__
  114825. + );
  114826. +
  114827. + /* Perform scheduled tasks. */
  114828. + return _EventHandler_Block(
  114829. + Kernel,
  114830. + &Kernel->command->taskTable[gcvBLOCK_COMMAND],
  114831. + gcvTRUE
  114832. + );
  114833. +}
  114834. +
  114835. +static gceSTATUS
  114836. +_ExecuteLastDynamicCommandBuffer(
  114837. + IN gckVGKERNEL Kernel,
  114838. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114839. + )
  114840. +{
  114841. + gceSTATUS status;
  114842. +
  114843. + do
  114844. + {
  114845. + /* Cast the command buffer header. */
  114846. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  114847. +
  114848. + /* Set to update the command buffer next time. */
  114849. + Entry->handler = _UpdateLastDynamicCommandBuffer;
  114850. +
  114851. + gcmkTRACE_ZONE(
  114852. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  114853. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  114854. + __FUNCTION__, __LINE__,
  114855. + commandBuffer->address,
  114856. + commandBuffer->dataCount
  114857. + );
  114858. +
  114859. + /* Start the command processor. */
  114860. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  114861. + Kernel->hardware,
  114862. + commandBuffer->address,
  114863. + commandBuffer->dataCount
  114864. + ));
  114865. +
  114866. + /* Success. */
  114867. + return gcvSTATUS_EXECUTED;
  114868. + }
  114869. + while (gcvFALSE);
  114870. +
  114871. + /* Return status. */
  114872. + return status;
  114873. +}
  114874. +
  114875. +
  114876. +/******************************************************************************\
  114877. +********************************* Other Handlers *******************************
  114878. +\******************************************************************************/
  114879. +
  114880. +static gceSTATUS
  114881. +_FreeKernelCommandBuffer(
  114882. + IN gckVGKERNEL Kernel,
  114883. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  114884. + )
  114885. +{
  114886. + gceSTATUS status;
  114887. +
  114888. + /* Free the command buffer. */
  114889. + status = _FreeCommandBuffer(Kernel, Entry->commandBuffer);
  114890. +
  114891. + /* Return status. */
  114892. + return status;
  114893. +}
  114894. +
  114895. +
  114896. +/******************************************************************************\
  114897. +******************************* Queue Management *******************************
  114898. +\******************************************************************************/
  114899. +
  114900. +#if gcvDUMP_COMMAND_BUFFER
  114901. +static void
  114902. +_DumpCommandQueue(
  114903. + IN gckVGCOMMAND Command,
  114904. + IN gcsKERNEL_QUEUE_HEADER_PTR QueueHeader,
  114905. + IN gctUINT EntryCount
  114906. + )
  114907. +{
  114908. + gcsKERNEL_CMDQUEUE_PTR entry;
  114909. + gctUINT queueIndex;
  114910. +
  114911. +#if defined(gcvCOMMAND_BUFFER_NAME)
  114912. + static gctUINT arrayCount = 0;
  114913. +#endif
  114914. +
  114915. + /* Is dumpinng enabled? */
  114916. + if (!Commad->enableDumping)
  114917. + {
  114918. + return;
  114919. + }
  114920. +
  114921. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  114922. + gcmkTRACE_ZONE(
  114923. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  114924. + "COMMAND QUEUE DUMP: %d entries\n", EntryCount
  114925. + );
  114926. +#endif
  114927. +
  114928. + /* Get the pointer to the first entry. */
  114929. + entry = QueueHeader->currentEntry;
  114930. +
  114931. + /* Iterate through the queue. */
  114932. + for (queueIndex = 0; queueIndex < EntryCount; queueIndex += 1)
  114933. + {
  114934. + gcsCMDBUFFER_PTR buffer;
  114935. + gctUINT bufferCount;
  114936. + gctUINT bufferIndex;
  114937. + gctUINT i, count;
  114938. + gctUINT size;
  114939. + gctUINT32_PTR data;
  114940. +
  114941. +#if gcvDUMP_COMMAND_LINES
  114942. + gctUINT lineNumber;
  114943. +#endif
  114944. +
  114945. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  114946. + gcmkTRACE_ZONE(
  114947. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  114948. + "ENTRY %d\n", queueIndex
  114949. + );
  114950. +#endif
  114951. +
  114952. + /* Reset the count. */
  114953. + bufferCount = 0;
  114954. +
  114955. + /* Set the initial buffer. */
  114956. + buffer = entry->commandBuffer;
  114957. +
  114958. + /* Loop through all subbuffers. */
  114959. + while (buffer)
  114960. + {
  114961. + /* Update the count. */
  114962. + bufferCount += 1;
  114963. +
  114964. + /* Advance to the next subbuffer. */
  114965. + buffer = buffer->nextSubBuffer;
  114966. + }
  114967. +
  114968. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  114969. + if (bufferCount > 1)
  114970. + {
  114971. + gcmkTRACE_ZONE(
  114972. + gcvLEVEL_INFO,
  114973. + gcvZONE_COMMAND,
  114974. + " COMMAND BUFFER SET: %d buffers.\n",
  114975. + bufferCount
  114976. + );
  114977. + }
  114978. +#endif
  114979. +
  114980. + /* Reset the buffer index. */
  114981. + bufferIndex = 0;
  114982. +
  114983. + /* Set the initial buffer. */
  114984. + buffer = entry->commandBuffer;
  114985. +
  114986. + /* Loop through all subbuffers. */
  114987. + while (buffer)
  114988. + {
  114989. + /* Determine the size of the buffer. */
  114990. + size = buffer->dataCount * Command->info.commandAlignment;
  114991. +
  114992. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  114993. + /* A single buffer? */
  114994. + if (bufferCount == 1)
  114995. + {
  114996. + gcmkTRACE_ZONE(
  114997. + gcvLEVEL_INFO,
  114998. + gcvZONE_COMMAND,
  114999. + " COMMAND BUFFER: count=%d (0x%X), size=%d bytes @ %08X.\n",
  115000. + buffer->dataCount,
  115001. + buffer->dataCount,
  115002. + size,
  115003. + buffer->address
  115004. + );
  115005. + }
  115006. + else
  115007. + {
  115008. + gcmkTRACE_ZONE(
  115009. + gcvLEVEL_INFO,
  115010. + gcvZONE_COMMAND,
  115011. + " COMMAND BUFFER %d: count=%d (0x%X), size=%d bytes @ %08X\n",
  115012. + bufferIndex,
  115013. + buffer->dataCount,
  115014. + buffer->dataCount,
  115015. + size,
  115016. + buffer->address
  115017. + );
  115018. + }
  115019. +#endif
  115020. +
  115021. + /* Determine the number of double words to print. */
  115022. + count = size / 4;
  115023. +
  115024. + /* Determine the buffer location. */
  115025. + data = (gctUINT32_PTR)
  115026. + (
  115027. + (gctUINT8_PTR) buffer + buffer->bufferOffset
  115028. + );
  115029. +
  115030. +#if defined(gcvCOMMAND_BUFFER_NAME)
  115031. + gcmkTRACE_ZONE(
  115032. + gcvLEVEL_INFO,
  115033. + gcvZONE_COMMAND,
  115034. + "unsigned int _" gcvCOMMAND_BUFFER_NAME "_%d[] =\n",
  115035. + arrayCount
  115036. + );
  115037. +
  115038. + gcmkTRACE_ZONE(
  115039. + gcvLEVEL_INFO,
  115040. + gcvZONE_COMMAND,
  115041. + "{\n"
  115042. + );
  115043. +
  115044. + arrayCount += 1;
  115045. +#endif
  115046. +
  115047. +#if gcvDUMP_COMMAND_LINES
  115048. + /* Reset the line number. */
  115049. + lineNumber = 0;
  115050. +#endif
  115051. +
  115052. +#if defined(gcvCOMMAND_BUFFER_NAME)
  115053. + count -= 2;
  115054. +#endif
  115055. +
  115056. + for (i = 0; i < count; i += 1)
  115057. + {
  115058. + if ((i % 8) == 0)
  115059. + {
  115060. +#if defined(gcvCOMMAND_BUFFER_NAME)
  115061. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "\t");
  115062. +#else
  115063. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, " ");
  115064. +#endif
  115065. + }
  115066. +
  115067. +#if gcvDUMP_COMMAND_LINES
  115068. + if (lineNumber == gcvDUMP_COMMAND_LINES)
  115069. + {
  115070. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, " . . . . . . . . .\n");
  115071. + break;
  115072. + }
  115073. +#endif
  115074. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "0x%08X", data[i]);
  115075. +
  115076. + if (i + 1 == count)
  115077. + {
  115078. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "\n");
  115079. +
  115080. +#if gcvDUMP_COMMAND_LINES
  115081. + lineNumber += 1;
  115082. +#endif
  115083. + }
  115084. + else
  115085. + {
  115086. + if (((i + 1) % 8) == 0)
  115087. + {
  115088. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, ",\n");
  115089. +
  115090. +#if gcvDUMP_COMMAND_LINES
  115091. + lineNumber += 1;
  115092. +#endif
  115093. + }
  115094. + else
  115095. + {
  115096. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, ", ");
  115097. + }
  115098. + }
  115099. + }
  115100. +
  115101. +#if defined(gcvCOMMAND_BUFFER_NAME)
  115102. + gcmkTRACE_ZONE(
  115103. + gcvLEVEL_INFO,
  115104. + gcvZONE_COMMAND,
  115105. + "};\n\n"
  115106. + );
  115107. +#endif
  115108. +
  115109. + /* Advance to the next subbuffer. */
  115110. + buffer = buffer->nextSubBuffer;
  115111. + bufferIndex += 1;
  115112. + }
  115113. +
  115114. + /* Advance to the next entry. */
  115115. + entry += 1;
  115116. + }
  115117. +}
  115118. +#endif
  115119. +
  115120. +static gceSTATUS
  115121. +_LockCurrentQueue(
  115122. + IN gckVGCOMMAND Command,
  115123. + OUT gcsKERNEL_CMDQUEUE_PTR * Entries,
  115124. + OUT gctUINT_PTR EntryCount
  115125. + )
  115126. +{
  115127. + gceSTATUS status;
  115128. +
  115129. + do
  115130. + {
  115131. + gcsKERNEL_QUEUE_HEADER_PTR queueHead;
  115132. +
  115133. + /* Get a shortcut to the head of the queue. */
  115134. + queueHead = Command->queueHead;
  115135. +
  115136. + /* Is the head buffer still being worked on? */
  115137. + if (queueHead->pending)
  115138. + {
  115139. + /* Increment overflow count. */
  115140. + Command->queueOverflow += 1;
  115141. +
  115142. + /* Wait until the head becomes idle. */
  115143. + gcmkERR_BREAK(_WaitForIdle(Command, queueHead));
  115144. + }
  115145. +
  115146. + /* Acquire the mutex. */
  115147. + gcmkERR_BREAK(gckOS_AcquireMutex(
  115148. + Command->os,
  115149. + Command->queueMutex,
  115150. + gcvINFINITE
  115151. + ));
  115152. +
  115153. + /* Determine the first queue entry. */
  115154. + queueHead->currentEntry = (gcsKERNEL_CMDQUEUE_PTR)
  115155. + (
  115156. + (gctUINT8_PTR) queueHead + gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
  115157. + );
  115158. +
  115159. + /* Set the pointer to the first entry. */
  115160. + * Entries = queueHead->currentEntry;
  115161. +
  115162. + /* Determine the number of available entries. */
  115163. + * EntryCount = queueHead->size / gcmSIZEOF(gcsKERNEL_CMDQUEUE);
  115164. +
  115165. + /* Success. */
  115166. + return gcvSTATUS_OK;
  115167. + }
  115168. + while (gcvFALSE);
  115169. +
  115170. + /* Return status. */
  115171. + return status;
  115172. +}
  115173. +
  115174. +static gceSTATUS
  115175. +_UnlockCurrentQueue(
  115176. + IN gckVGCOMMAND Command,
  115177. + IN gctUINT EntryCount
  115178. + )
  115179. +{
  115180. + gceSTATUS status;
  115181. +
  115182. + do
  115183. + {
  115184. +#if !gcdENABLE_INFINITE_SPEED_HW
  115185. + gcsKERNEL_QUEUE_HEADER_PTR queueTail;
  115186. + gcsKERNEL_QUEUE_HEADER_PTR queueHead;
  115187. + gcsKERNEL_QUEUE_HEADER_PTR queueNext;
  115188. + gctUINT queueSize;
  115189. + gctUINT newSize;
  115190. + gctUINT unusedSize;
  115191. +
  115192. + /* Get shortcut to the head and to the tail of the queue. */
  115193. + queueTail = Command->queueTail;
  115194. + queueHead = Command->queueHead;
  115195. +
  115196. + /* Dump the command buffer. */
  115197. +#if gcvDUMP_COMMAND_BUFFER
  115198. + _DumpCommandQueue(Command, queueHead, EntryCount);
  115199. +#endif
  115200. +
  115201. + /* Get a shortcut to the current queue size. */
  115202. + queueSize = queueHead->size;
  115203. +
  115204. + /* Determine the new queue size. */
  115205. + newSize = EntryCount * gcmSIZEOF(gcsKERNEL_CMDQUEUE);
  115206. + gcmkASSERT(newSize <= queueSize);
  115207. +
  115208. + /* Determine the size of the unused area. */
  115209. + unusedSize = queueSize - newSize;
  115210. +
  115211. + /* Is the unused area big enough to become a buffer? */
  115212. + if (unusedSize >= gcvMINUMUM_BUFFER)
  115213. + {
  115214. + gcsKERNEL_QUEUE_HEADER_PTR nextHead;
  115215. +
  115216. + /* Place the new header. */
  115217. + nextHead = (gcsKERNEL_QUEUE_HEADER_PTR)
  115218. + (
  115219. + (gctUINT8_PTR) queueHead
  115220. + + gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
  115221. + + newSize
  115222. + );
  115223. +
  115224. + /* Initialize the buffer. */
  115225. + nextHead->size = unusedSize - gcmSIZEOF(gcsKERNEL_QUEUE_HEADER);
  115226. + nextHead->pending = 0;
  115227. +
  115228. + /* Link the buffer in. */
  115229. + nextHead->next = queueHead->next;
  115230. + queueHead->next = nextHead;
  115231. + queueNext = nextHead;
  115232. +
  115233. + /* Update the size of the current buffer. */
  115234. + queueHead->size = newSize;
  115235. + }
  115236. +
  115237. + /* Not big enough. */
  115238. + else
  115239. + {
  115240. + /* Determine the next queue. */
  115241. + queueNext = queueHead->next;
  115242. + }
  115243. +
  115244. + /* Mark the buffer as busy. */
  115245. + queueHead->pending = EntryCount;
  115246. +
  115247. + /* Advance to the next buffer. */
  115248. + Command->queueHead = queueNext;
  115249. +
  115250. + /* Start the command processor if the queue was empty. */
  115251. + if (queueTail == queueHead)
  115252. + {
  115253. + gcsCMDBUFFER_PTR commandBuffer;
  115254. +
  115255. + /* The first entry must be a command buffer. */
  115256. + commandBuffer = queueTail->currentEntry->commandBuffer;
  115257. +
  115258. + /* Start the command processor. */
  115259. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  115260. + Command->hardware,
  115261. + commandBuffer->address,
  115262. + commandBuffer->dataCount
  115263. + ));
  115264. + }
  115265. +
  115266. + /* The queue was not empty. */
  115267. + else
  115268. + {
  115269. + /* Advance the merge buffer if needed. */
  115270. + if (queueHead == Command->mergeQueue)
  115271. + {
  115272. + Command->mergeQueue = queueNext;
  115273. + }
  115274. + }
  115275. +#endif
  115276. +
  115277. + /* Release the mutex. */
  115278. + gcmkERR_BREAK(gckOS_ReleaseMutex(
  115279. + Command->os,
  115280. + Command->queueMutex
  115281. + ));
  115282. +
  115283. + /* Success. */
  115284. + return gcvSTATUS_OK;
  115285. + }
  115286. + while (gcvFALSE);
  115287. +
  115288. + /* Return status. */
  115289. + return status;
  115290. +}
  115291. +
  115292. +
  115293. +
  115294. +/******************************************************************************\
  115295. +****************************** gckVGCOMMAND API Code *****************************
  115296. +\******************************************************************************/
  115297. +gceSTATUS
  115298. +gckVGCOMMAND_Construct(
  115299. + IN gckVGKERNEL Kernel,
  115300. + IN gctUINT TaskGranularity,
  115301. + IN gctUINT QueueSize,
  115302. + OUT gckVGCOMMAND * Command
  115303. + )
  115304. +{
  115305. + gceSTATUS status, last;
  115306. + gckVGCOMMAND command = gcvNULL;
  115307. + gcsKERNEL_QUEUE_HEADER_PTR queue;
  115308. + gctUINT i, j;
  115309. +
  115310. + gcmkHEADER_ARG("Kernel=0x%x TaskGranularity=0x%x QueueSize=0x%x Command=0x%x",
  115311. + Kernel, TaskGranularity, QueueSize, Command);
  115312. + /* Verify the arguments. */
  115313. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  115314. + gcmkVERIFY_ARGUMENT(QueueSize >= gcvMINUMUM_BUFFER);
  115315. + gcmkVERIFY_ARGUMENT(Command != gcvNULL);
  115316. +
  115317. + do
  115318. + {
  115319. + /***********************************************************************
  115320. + ** Generic object initialization.
  115321. + */
  115322. +
  115323. + /* Allocate the gckVGCOMMAND structure. */
  115324. + gcmkERR_BREAK(gckOS_Allocate(
  115325. + Kernel->os,
  115326. + gcmSIZEOF(struct _gckVGCOMMAND),
  115327. + (gctPOINTER *) &command
  115328. + ));
  115329. +
  115330. + /* Initialize the object. */
  115331. + command->object.type = gcvOBJ_COMMAND;
  115332. +
  115333. + /* Set the object pointers. */
  115334. + command->kernel = Kernel;
  115335. + command->os = Kernel->os;
  115336. + command->hardware = Kernel->hardware;
  115337. +
  115338. + /* Reset pointers. */
  115339. + command->queue = gcvNULL;
  115340. + command->queueMutex = gcvNULL;
  115341. + command->taskMutex = gcvNULL;
  115342. + command->commitMutex = gcvNULL;
  115343. +
  115344. + command->powerStallBuffer = gcvNULL;
  115345. + command->powerStallSignal = gcvNULL;
  115346. + command->powerSemaphore = gcvNULL;
  115347. +
  115348. + /* Reset context states. */
  115349. + command->contextCounter = 0;
  115350. + command->currentContext = 0;
  115351. +
  115352. + /* Enable command buffer dumping. */
  115353. + command->enableDumping = gcvTRUE;
  115354. +
  115355. + /* Set features. */
  115356. + command->fe20 = Kernel->hardware->fe20;
  115357. + command->vg20 = Kernel->hardware->vg20;
  115358. + command->vg21 = Kernel->hardware->vg21;
  115359. +
  115360. + /* Reset task table .*/
  115361. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  115362. + command->taskTable, gcmSIZEOF(command->taskTable)
  115363. + ));
  115364. +
  115365. + /* Query command buffer attributes. */
  115366. + gcmkERR_BREAK(gckVGCOMMAND_InitializeInfo(command));
  115367. +
  115368. + /* Create the control mutexes. */
  115369. + gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->queueMutex));
  115370. + gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->taskMutex));
  115371. + gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->commitMutex));
  115372. +
  115373. + /* Create the power management semaphore. */
  115374. + gcmkERR_BREAK(gckOS_CreateSemaphore(Kernel->os,
  115375. + &command->powerSemaphore));
  115376. +
  115377. + gcmkERR_BREAK(gckOS_CreateSignal(Kernel->os,
  115378. + gcvFALSE, &command->powerStallSignal));
  115379. +
  115380. + /***********************************************************************
  115381. + ** Command queue initialization.
  115382. + */
  115383. +
  115384. + /* Allocate the command queue. */
  115385. + gcmkERR_BREAK(gckOS_Allocate(
  115386. + Kernel->os,
  115387. + QueueSize,
  115388. + (gctPOINTER *) &command->queue
  115389. + ));
  115390. +
  115391. + /* Initialize the command queue. */
  115392. + queue = command->queue;
  115393. +
  115394. + queue->size = QueueSize - gcmSIZEOF(gcsKERNEL_QUEUE_HEADER);
  115395. + queue->pending = 0;
  115396. + queue->next = queue;
  115397. +
  115398. + command->queueHead =
  115399. + command->queueTail =
  115400. + command->mergeQueue = command->queue;
  115401. +
  115402. + command->queueOverflow = 0;
  115403. +
  115404. +
  115405. + /***********************************************************************
  115406. + ** Enable TS overflow interrupt.
  115407. + */
  115408. +
  115409. + command->info.tsOverflowInt = 0;
  115410. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  115411. + Kernel->interrupt,
  115412. + &command->info.tsOverflowInt,
  115413. + _EventHandler_TSOverflow
  115414. + ));
  115415. +
  115416. + /* Mask out the interrupt. */
  115417. + Kernel->hardware->eventMask &= ~(1 << command->info.tsOverflowInt);
  115418. +
  115419. +
  115420. + /***********************************************************************
  115421. + ** Enable Bus Error interrupt.
  115422. + */
  115423. +
  115424. + /* Hardwired to bit 31. */
  115425. + command->busErrorInt = 31;
  115426. +
  115427. + /* Enable the interrupt. */
  115428. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  115429. + Kernel->interrupt,
  115430. + &command->busErrorInt,
  115431. + _EventHandler_BusError
  115432. + ));
  115433. +
  115434. +
  115435. + command->powerStallInt = 30;
  115436. + /* Enable the interrupt. */
  115437. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  115438. + Kernel->interrupt,
  115439. + &command->powerStallInt,
  115440. + _EventHandler_PowerStall
  115441. + ));
  115442. +
  115443. + /***********************************************************************
  115444. + ** Task management initialization.
  115445. + */
  115446. +
  115447. + command->taskStorage = gcvNULL;
  115448. + command->taskStorageGranularity = TaskGranularity;
  115449. + command->taskStorageUsable = TaskGranularity - gcmSIZEOF(gcsTASK_STORAGE);
  115450. +
  115451. + command->taskFreeHead = gcvNULL;
  115452. + command->taskFreeTail = gcvNULL;
  115453. +
  115454. + /* Enable block handlers. */
  115455. + for (i = 0; i < gcmCOUNTOF(_blockHandlers); i += 1)
  115456. + {
  115457. + /* Get the target hardware block. */
  115458. + gceBLOCK block = _blockHandlers[i].block;
  115459. +
  115460. + /* Get the interrupt array entry. */
  115461. + gcsBLOCK_TASK_ENTRY_PTR entry = &command->taskTable[block];
  115462. +
  115463. + /* Determine the interrupt value index. */
  115464. + gctUINT index = entry->interruptCount;
  115465. +
  115466. + /* Create the block semaphore. */
  115467. + if (entry->interruptSemaphore == gcvNULL)
  115468. + {
  115469. + gcmkERR_BREAK(gckOS_CreateSemaphoreVG(
  115470. + command->os, &entry->interruptSemaphore
  115471. + ));
  115472. + }
  115473. +
  115474. + /* Enable auto-detection. */
  115475. + entry->interruptArray[index] = -1;
  115476. +
  115477. + /* Enable interrupt for the block. */
  115478. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  115479. + Kernel->interrupt,
  115480. + &entry->interruptArray[index],
  115481. + _blockHandlers[i].handler
  115482. + ));
  115483. +
  115484. + /* Update the number of registered interrupts. */
  115485. + entry->interruptCount += 1;
  115486. +
  115487. + /* Inrement the semaphore to allow the usage of the registered
  115488. + interrupt. */
  115489. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  115490. + command->os, entry->interruptSemaphore
  115491. + ));
  115492. +
  115493. + }
  115494. +
  115495. + /* Error? */
  115496. + if (gcmkIS_ERROR(status))
  115497. + {
  115498. + break;
  115499. + }
  115500. +
  115501. + /* Get the FE interrupt. */
  115502. + command->info.feBufferInt
  115503. + = command->taskTable[gcvBLOCK_COMMAND].interruptArray[0];
  115504. +
  115505. + /* Return gckVGCOMMAND object pointer. */
  115506. + *Command = command;
  115507. +
  115508. + gcmkFOOTER_ARG("*Command=0x%x",*Command);
  115509. + /* Success. */
  115510. + return gcvSTATUS_OK;
  115511. + }
  115512. + while (gcvFALSE);
  115513. +
  115514. + /* Roll back. */
  115515. + if (command != gcvNULL)
  115516. + {
  115517. + /* Disable block handlers. */
  115518. + for (i = 0; i < gcvBLOCK_COUNT; i += 1)
  115519. + {
  115520. + /* Get the task table entry. */
  115521. + gcsBLOCK_TASK_ENTRY_PTR entry = &command->taskTable[i];
  115522. +
  115523. + /* Destroy the semaphore. */
  115524. + if (entry->interruptSemaphore != gcvNULL)
  115525. + {
  115526. + gcmkCHECK_STATUS(gckOS_DestroySemaphore(
  115527. + command->os, entry->interruptSemaphore
  115528. + ));
  115529. + }
  115530. +
  115531. + /* Disable all enabled interrupts. */
  115532. + for (j = 0; j < entry->interruptCount; j += 1)
  115533. + {
  115534. + /* Must be a valid value. */
  115535. + gcmkASSERT(entry->interruptArray[j] >= 0);
  115536. + gcmkASSERT(entry->interruptArray[j] <= 31);
  115537. +
  115538. + /* Disable the interrupt. */
  115539. + gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
  115540. + Kernel->interrupt,
  115541. + entry->interruptArray[j]
  115542. + ));
  115543. + }
  115544. + }
  115545. +
  115546. + /* Disable the bus error interrupt. */
  115547. + gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
  115548. + Kernel->interrupt,
  115549. + command->busErrorInt
  115550. + ));
  115551. +
  115552. + /* Disable TS overflow interrupt. */
  115553. + if (command->info.tsOverflowInt != -1)
  115554. + {
  115555. + gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
  115556. + Kernel->interrupt,
  115557. + command->info.tsOverflowInt
  115558. + ));
  115559. + }
  115560. +
  115561. + /* Delete the commit mutex. */
  115562. + if (command->commitMutex != gcvNULL)
  115563. + {
  115564. + gcmkCHECK_STATUS(gckOS_DeleteMutex(
  115565. + Kernel->os, command->commitMutex
  115566. + ));
  115567. + }
  115568. +
  115569. + /* Delete the command queue mutex. */
  115570. + if (command->taskMutex != gcvNULL)
  115571. + {
  115572. + gcmkCHECK_STATUS(gckOS_DeleteMutex(
  115573. + Kernel->os, command->taskMutex
  115574. + ));
  115575. + }
  115576. +
  115577. + /* Delete the command queue mutex. */
  115578. + if (command->queueMutex != gcvNULL)
  115579. + {
  115580. + gcmkCHECK_STATUS(gckOS_DeleteMutex(
  115581. + Kernel->os, command->queueMutex
  115582. + ));
  115583. + }
  115584. +
  115585. + /* Delete the command queue. */
  115586. + if (command->queue != gcvNULL)
  115587. + {
  115588. + gcmkCHECK_STATUS(gckOS_Free(
  115589. + Kernel->os, command->queue
  115590. + ));
  115591. + }
  115592. +
  115593. + if (command->powerSemaphore != gcvNULL)
  115594. + {
  115595. + gcmkVERIFY_OK(gckOS_DestroySemaphore(
  115596. + Kernel->os, command->powerSemaphore));
  115597. + }
  115598. +
  115599. + if (command->powerStallSignal != gcvNULL)
  115600. + {
  115601. + /* Create the power management semaphore. */
  115602. + gcmkVERIFY_OK(gckOS_DestroySignal(
  115603. + Kernel->os,
  115604. + command->powerStallSignal));
  115605. + }
  115606. +
  115607. + /* Free the gckVGCOMMAND structure. */
  115608. + gcmkCHECK_STATUS(gckOS_Free(
  115609. + Kernel->os, command
  115610. + ));
  115611. + }
  115612. +
  115613. + gcmkFOOTER();
  115614. + /* Return the error. */
  115615. + return status;
  115616. +}
  115617. +
  115618. +gceSTATUS
  115619. +gckVGCOMMAND_Destroy(
  115620. + OUT gckVGCOMMAND Command
  115621. + )
  115622. +{
  115623. + gceSTATUS status = gcvSTATUS_OK;
  115624. +
  115625. + gcmkHEADER_ARG("Command=0x%x", Command);
  115626. +
  115627. + /* Verify the arguments. */
  115628. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  115629. +
  115630. + do
  115631. + {
  115632. + gctUINT i;
  115633. + gcsTASK_STORAGE_PTR nextStorage;
  115634. +
  115635. + if (Command->queueHead != gcvNULL)
  115636. + {
  115637. + /* Wait until the head becomes idle. */
  115638. + gcmkERR_BREAK(_WaitForIdle(Command, Command->queueHead));
  115639. + }
  115640. +
  115641. + /* Disable block handlers. */
  115642. + for (i = 0; i < gcvBLOCK_COUNT; i += 1)
  115643. + {
  115644. + /* Get the interrupt array entry. */
  115645. + gcsBLOCK_TASK_ENTRY_PTR entry = &Command->taskTable[i];
  115646. +
  115647. + /* Determine the index of the last interrupt in the array. */
  115648. + gctINT index = entry->interruptCount - 1;
  115649. +
  115650. + /* Destroy the semaphore. */
  115651. + if (entry->interruptSemaphore != gcvNULL)
  115652. + {
  115653. + gcmkERR_BREAK(gckOS_DestroySemaphore(
  115654. + Command->os, entry->interruptSemaphore
  115655. + ));
  115656. + }
  115657. +
  115658. + /* Disable all enabled interrupts. */
  115659. + while (index >= 0)
  115660. + {
  115661. + /* Must be a valid value. */
  115662. + gcmkASSERT(entry->interruptArray[index] >= 0);
  115663. + gcmkASSERT(entry->interruptArray[index] <= 31);
  115664. +
  115665. + /* Disable the interrupt. */
  115666. + gcmkERR_BREAK(gckVGINTERRUPT_Disable(
  115667. + Command->kernel->interrupt,
  115668. + entry->interruptArray[index]
  115669. + ));
  115670. +
  115671. + /* Update to the next interrupt. */
  115672. + index -= 1;
  115673. + entry->interruptCount -= 1;
  115674. + }
  115675. +
  115676. + /* Error? */
  115677. + if (gcmkIS_ERROR(status))
  115678. + {
  115679. + break;
  115680. + }
  115681. + }
  115682. +
  115683. + /* Error? */
  115684. + if (gcmkIS_ERROR(status))
  115685. + {
  115686. + break;
  115687. + }
  115688. +
  115689. + /* Disable the bus error interrupt. */
  115690. + gcmkERR_BREAK(gckVGINTERRUPT_Disable(
  115691. + Command->kernel->interrupt,
  115692. + Command->busErrorInt
  115693. + ));
  115694. +
  115695. + /* Disable TS overflow interrupt. */
  115696. + if (Command->info.tsOverflowInt != -1)
  115697. + {
  115698. + gcmkERR_BREAK(gckVGINTERRUPT_Disable(
  115699. + Command->kernel->interrupt,
  115700. + Command->info.tsOverflowInt
  115701. + ));
  115702. +
  115703. + Command->info.tsOverflowInt = -1;
  115704. + }
  115705. +
  115706. + /* Delete the commit mutex. */
  115707. + if (Command->commitMutex != gcvNULL)
  115708. + {
  115709. + gcmkERR_BREAK(gckOS_DeleteMutex(
  115710. + Command->os, Command->commitMutex
  115711. + ));
  115712. +
  115713. + Command->commitMutex = gcvNULL;
  115714. + }
  115715. +
  115716. + /* Delete the command queue mutex. */
  115717. + if (Command->taskMutex != gcvNULL)
  115718. + {
  115719. + gcmkERR_BREAK(gckOS_DeleteMutex(
  115720. + Command->os, Command->taskMutex
  115721. + ));
  115722. +
  115723. + Command->taskMutex = gcvNULL;
  115724. + }
  115725. +
  115726. + /* Delete the command queue mutex. */
  115727. + if (Command->queueMutex != gcvNULL)
  115728. + {
  115729. + gcmkERR_BREAK(gckOS_DeleteMutex(
  115730. + Command->os, Command->queueMutex
  115731. + ));
  115732. +
  115733. + Command->queueMutex = gcvNULL;
  115734. + }
  115735. +
  115736. + if (Command->powerSemaphore != gcvNULL)
  115737. + {
  115738. + /* Destroy the power management semaphore. */
  115739. + gcmkERR_BREAK(gckOS_DestroySemaphore(
  115740. + Command->os, Command->powerSemaphore));
  115741. + }
  115742. +
  115743. + if (Command->powerStallSignal != gcvNULL)
  115744. + {
  115745. + /* Create the power management semaphore. */
  115746. + gcmkERR_BREAK(gckOS_DestroySignal(
  115747. + Command->os,
  115748. + Command->powerStallSignal));
  115749. + }
  115750. +
  115751. + if (Command->queue != gcvNULL)
  115752. + {
  115753. + /* Delete the command queue. */
  115754. + gcmkERR_BREAK(gckOS_Free(
  115755. + Command->os, Command->queue
  115756. + ));
  115757. + }
  115758. +
  115759. + /* Destroy all allocated buffers. */
  115760. + while (Command->taskStorage)
  115761. + {
  115762. + /* Copy the buffer pointer. */
  115763. + nextStorage = Command->taskStorage->next;
  115764. +
  115765. + /* Free the current container. */
  115766. + gcmkERR_BREAK(gckOS_Free(
  115767. + Command->os, Command->taskStorage
  115768. + ));
  115769. +
  115770. + /* Advance to the next one. */
  115771. + Command->taskStorage = nextStorage;
  115772. + }
  115773. +
  115774. + /* Error? */
  115775. + if (gcmkIS_ERROR(status))
  115776. + {
  115777. + break;
  115778. + }
  115779. +
  115780. + /* Mark the object as unknown. */
  115781. + Command->object.type = gcvOBJ_UNKNOWN;
  115782. +
  115783. + /* Free the gckVGCOMMAND structure. */
  115784. + gcmkERR_BREAK(gckOS_Free(Command->os, Command));
  115785. +
  115786. + gcmkFOOTER_NO();
  115787. + /* Success. */
  115788. + return gcvSTATUS_OK;
  115789. + }
  115790. + while (gcvFALSE);
  115791. +
  115792. + /* Restore the object type if failed. */
  115793. + Command->object.type = gcvOBJ_COMMAND;
  115794. +
  115795. + gcmkFOOTER();
  115796. + /* Return the error. */
  115797. + return status;
  115798. +}
  115799. +
  115800. +gceSTATUS
  115801. +gckVGCOMMAND_QueryCommandBuffer(
  115802. + IN gckVGCOMMAND Command,
  115803. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  115804. + )
  115805. +{
  115806. + gcmkHEADER_ARG("Command=0x%x Information=0x%x", Command, Information);
  115807. + /* Verify the arguments. */
  115808. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  115809. + gcmkVERIFY_ARGUMENT(Information != gcvNULL);
  115810. +
  115811. + /* Copy the information. */
  115812. + gcmkVERIFY_OK(gckOS_MemCopy(
  115813. + Information, &Command->info, sizeof(gcsCOMMAND_BUFFER_INFO)
  115814. + ));
  115815. +
  115816. + gcmkFOOTER_NO();
  115817. + /* Success. */
  115818. + return gcvSTATUS_OK;
  115819. +}
  115820. +
  115821. +gceSTATUS
  115822. +gckVGCOMMAND_Allocate(
  115823. + IN gckVGCOMMAND Command,
  115824. + IN gctSIZE_T Size,
  115825. + OUT gcsCMDBUFFER_PTR * CommandBuffer,
  115826. + OUT gctPOINTER * Data
  115827. + )
  115828. +{
  115829. + gceSTATUS status;
  115830. +
  115831. + gcmkHEADER_ARG("Command=0x%x Size=0x%x CommandBuffer=0x%x Data=0x%x",
  115832. + Command, Size, CommandBuffer, Data);
  115833. +
  115834. + /* Verify the arguments. */
  115835. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  115836. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  115837. +
  115838. + do
  115839. + {
  115840. + /* Allocate the buffer. */
  115841. + gcmkERR_BREAK(_AllocateCommandBuffer(Command, Size, CommandBuffer));
  115842. +
  115843. + /* Determine the data pointer. */
  115844. + * Data = (gctUINT8_PTR) (*CommandBuffer) + (* CommandBuffer)->bufferOffset;
  115845. + }
  115846. + while (gcvFALSE);
  115847. +
  115848. + gcmkFOOTER();
  115849. + /* Return status. */
  115850. + return status;
  115851. +}
  115852. +
  115853. +gceSTATUS
  115854. +gckVGCOMMAND_Free(
  115855. + IN gckVGCOMMAND Command,
  115856. + IN gcsCMDBUFFER_PTR CommandBuffer
  115857. + )
  115858. +{
  115859. + gceSTATUS status;
  115860. +
  115861. + gcmkHEADER_ARG("Command=0x%x CommandBuffer=0x%x",
  115862. + Command, CommandBuffer);
  115863. +
  115864. + /* Verify the arguments. */
  115865. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  115866. + gcmkVERIFY_ARGUMENT(CommandBuffer != gcvNULL);
  115867. +
  115868. + /* Free command buffer. */
  115869. + status = _FreeCommandBuffer(Command->kernel, CommandBuffer);
  115870. +
  115871. + gcmkFOOTER();
  115872. + /* Return status. */
  115873. + return status;
  115874. +}
  115875. +
  115876. +gceSTATUS
  115877. +gckVGCOMMAND_Execute(
  115878. + IN gckVGCOMMAND Command,
  115879. + IN gcsCMDBUFFER_PTR CommandBuffer
  115880. + )
  115881. +{
  115882. + gceSTATUS status;
  115883. +
  115884. + gcmkHEADER_ARG("Command=0x%x CommandBuffer=0x%x",
  115885. + Command, CommandBuffer);
  115886. +
  115887. + /* Verify the arguments. */
  115888. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  115889. + gcmkVERIFY_ARGUMENT(CommandBuffer != gcvNULL);
  115890. +
  115891. + do
  115892. + {
  115893. + gctUINT queueLength;
  115894. + gcsKERNEL_CMDQUEUE_PTR kernelEntry;
  115895. +
  115896. + /* Lock the current queue. */
  115897. + gcmkERR_BREAK(_LockCurrentQueue(
  115898. + Command, &kernelEntry, &queueLength
  115899. + ));
  115900. +
  115901. + /* Set the buffer. */
  115902. + kernelEntry->commandBuffer = CommandBuffer;
  115903. + kernelEntry->handler = _FreeKernelCommandBuffer;
  115904. +
  115905. + /* Lock the current queue. */
  115906. + gcmkERR_BREAK(_UnlockCurrentQueue(
  115907. + Command, 1
  115908. + ));
  115909. + }
  115910. + while (gcvFALSE);
  115911. +
  115912. + gcmkFOOTER();
  115913. + /* Return status. */
  115914. + return status;
  115915. +}
  115916. +
  115917. +gceSTATUS
  115918. +gckVGCOMMAND_Commit(
  115919. + IN gckVGCOMMAND Command,
  115920. + IN gcsVGCONTEXT_PTR Context,
  115921. + IN gcsVGCMDQUEUE_PTR Queue,
  115922. + IN gctUINT EntryCount,
  115923. + IN gcsTASK_MASTER_TABLE_PTR TaskTable
  115924. + )
  115925. +{
  115926. + /*
  115927. + The first buffer is executed through a direct gckVGHARDWARE_Execute call,
  115928. + therefore only an update is needed after the execution is over. All
  115929. + consequent buffers need to be executed upon the first update call from
  115930. + the FE interrupt handler.
  115931. + */
  115932. +
  115933. + static gcsQUEUE_UPDATE_CONTROL _dynamicBuffer[] =
  115934. + {
  115935. + {
  115936. + _UpdateDynamicCommandBuffer,
  115937. + _UpdateDynamicCommandBuffer,
  115938. + _UpdateLastDynamicCommandBuffer,
  115939. + _UpdateLastDynamicCommandBuffer
  115940. + },
  115941. + {
  115942. + _ExecuteDynamicCommandBuffer,
  115943. + _UpdateDynamicCommandBuffer,
  115944. + _ExecuteLastDynamicCommandBuffer,
  115945. + _UpdateLastDynamicCommandBuffer
  115946. + }
  115947. + };
  115948. +
  115949. + static gcsQUEUE_UPDATE_CONTROL _staticBuffer[] =
  115950. + {
  115951. + {
  115952. + _UpdateStaticCommandBuffer,
  115953. + _UpdateStaticCommandBuffer,
  115954. + _UpdateLastStaticCommandBuffer,
  115955. + _UpdateLastStaticCommandBuffer
  115956. + },
  115957. + {
  115958. + _ExecuteStaticCommandBuffer,
  115959. + _UpdateStaticCommandBuffer,
  115960. + _ExecuteLastStaticCommandBuffer,
  115961. + _UpdateLastStaticCommandBuffer
  115962. + }
  115963. + };
  115964. +
  115965. + gceSTATUS status, last;
  115966. +
  115967. + gcmkHEADER_ARG("Command=0x%x Context=0x%x Queue=0x%x EntryCount=0x%x TaskTable=0x%x",
  115968. + Command, Context, Queue, EntryCount, TaskTable);
  115969. +
  115970. + /* Verify the arguments. */
  115971. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  115972. + gcmkVERIFY_ARGUMENT(Context != gcvNULL);
  115973. + gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
  115974. + gcmkVERIFY_ARGUMENT(EntryCount > 1);
  115975. +
  115976. +#ifdef __QNXNTO__
  115977. + TaskTable->coid = Context->coid;
  115978. + TaskTable->rcvid = Context->rcvid;
  115979. +#endif /* __QNXNTO__ */
  115980. +
  115981. + do
  115982. + {
  115983. + gctBOOL haveFETasks;
  115984. + gctUINT queueSize;
  115985. + gcsVGCMDQUEUE_PTR mappedQueue;
  115986. + gcsVGCMDQUEUE_PTR userEntry;
  115987. + gcsKERNEL_CMDQUEUE_PTR kernelEntry;
  115988. + gcsQUEUE_UPDATE_CONTROL_PTR queueControl;
  115989. + gctUINT currentLength;
  115990. + gctUINT queueLength;
  115991. + gctUINT entriesQueued;
  115992. + gctUINT8_PTR previousEnd;
  115993. + gctBOOL previousDynamic;
  115994. + gctBOOL previousExecuted;
  115995. + gctUINT controlIndex;
  115996. +
  115997. + gcmkERR_BREAK(gckVGHARDWARE_SetPowerManagementState(
  115998. + Command->hardware, gcvPOWER_ON_AUTO
  115999. + ));
  116000. +
  116001. + /* Acquire the power semaphore. */
  116002. + gcmkERR_BREAK(gckOS_AcquireSemaphore(
  116003. + Command->os, Command->powerSemaphore
  116004. + ));
  116005. +
  116006. + /* Acquire the mutex. */
  116007. + status = gckOS_AcquireMutex(
  116008. + Command->os,
  116009. + Command->commitMutex,
  116010. + gcvINFINITE
  116011. + );
  116012. +
  116013. + if (gcmIS_ERROR(status))
  116014. + {
  116015. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
  116016. + Command->os, Command->powerSemaphore));
  116017. + break;
  116018. + }
  116019. +
  116020. + do
  116021. + {
  116022. + gcmkERR_BREAK(_FlushMMU(Command));
  116023. +
  116024. + /* Assign a context ID if not yet assigned. */
  116025. + if (Context->id == 0)
  116026. + {
  116027. + /* Assign the next context number. */
  116028. + Context->id = ++ Command->contextCounter;
  116029. +
  116030. + /* See if we overflowed. */
  116031. + if (Command->contextCounter == 0)
  116032. + {
  116033. + /* We actually did overflow, wow... */
  116034. + status = gcvSTATUS_OUT_OF_RESOURCES;
  116035. + break;
  116036. + }
  116037. + }
  116038. +
  116039. + /* The first entry in the queue is always the context buffer.
  116040. + Verify whether the user context is the same as the current
  116041. + context and if that's the case, skip the first entry. */
  116042. + if (Context->id == Command->currentContext)
  116043. + {
  116044. + /* Same context as before, skip the first entry. */
  116045. + EntryCount -= 1;
  116046. + Queue += 1;
  116047. +
  116048. + /* Set the signal to avoid user waiting. */
  116049. +#ifdef __QNXNTO__
  116050. + gcmkERR_BREAK(gckOS_UserSignal(
  116051. + Command->os, Context->signal, Context->rcvid, Context->coid
  116052. + ));
  116053. +#else
  116054. + gcmkERR_BREAK(gckOS_UserSignal(
  116055. + Command->os, Context->signal, Context->process
  116056. + ));
  116057. +
  116058. +#endif /* __QNXNTO__ */
  116059. +
  116060. + }
  116061. + else
  116062. + {
  116063. + /* Different user context - keep the first entry.
  116064. + Set the user context as the current one. */
  116065. + Command->currentContext = Context->id;
  116066. + }
  116067. +
  116068. + /* Reset pointers. */
  116069. + queueControl = gcvNULL;
  116070. + previousEnd = gcvNULL;
  116071. +
  116072. + /* Determine whether there are FE tasks to be performed. */
  116073. + haveFETasks = (TaskTable->table[gcvBLOCK_COMMAND].head != gcvNULL);
  116074. +
  116075. + /* Determine the size of the queue. */
  116076. + queueSize = EntryCount * gcmSIZEOF(gcsVGCMDQUEUE);
  116077. +
  116078. + /* Map the command queue into the kernel space. */
  116079. + gcmkERR_BREAK(gckOS_MapUserPointer(
  116080. + Command->os,
  116081. + Queue,
  116082. + queueSize,
  116083. + (gctPOINTER *) &mappedQueue
  116084. + ));
  116085. +
  116086. + /* Set the first entry. */
  116087. + userEntry = mappedQueue;
  116088. +
  116089. + /* Process the command queue. */
  116090. + while (EntryCount)
  116091. + {
  116092. + /* Lock the current queue. */
  116093. + gcmkERR_BREAK(_LockCurrentQueue(
  116094. + Command, &kernelEntry, &queueLength
  116095. + ));
  116096. +
  116097. + /* Determine the number of entries to process. */
  116098. + currentLength = (queueLength < EntryCount)
  116099. + ? queueLength
  116100. + : EntryCount;
  116101. +
  116102. + /* Update the number of the entries left to process. */
  116103. + EntryCount -= currentLength;
  116104. +
  116105. + /* Reset previous flags. */
  116106. + previousDynamic = gcvFALSE;
  116107. + previousExecuted = gcvFALSE;
  116108. +
  116109. + /* Set the initial control index. */
  116110. + controlIndex = 0;
  116111. +
  116112. + /* Process entries. */
  116113. + for (entriesQueued = 0; entriesQueued < currentLength; entriesQueued += 1)
  116114. + {
  116115. + /* Get the kernel pointer to the command buffer header. */
  116116. + gcsCMDBUFFER_PTR commandBuffer = gcvNULL;
  116117. + gcmkERR_BREAK(_ConvertUserCommandBufferPointer(
  116118. + Command,
  116119. + userEntry->commandBuffer,
  116120. + &commandBuffer
  116121. + ));
  116122. +
  116123. + /* Is it a dynamic command buffer? */
  116124. + if (userEntry->dynamic)
  116125. + {
  116126. + /* Select dynamic buffer control functions. */
  116127. + queueControl = &_dynamicBuffer[controlIndex];
  116128. + }
  116129. +
  116130. + /* No, a static command buffer. */
  116131. + else
  116132. + {
  116133. + /* Select static buffer control functions. */
  116134. + queueControl = &_staticBuffer[controlIndex];
  116135. + }
  116136. +
  116137. + /* Set the command buffer pointer to the entry. */
  116138. + kernelEntry->commandBuffer = commandBuffer;
  116139. +
  116140. + /* If the previous entry was a dynamic command buffer,
  116141. + link it to the current. */
  116142. + if (previousDynamic)
  116143. + {
  116144. + gcmkERR_BREAK(gckVGCOMMAND_FetchCommand(
  116145. + Command,
  116146. + previousEnd,
  116147. + commandBuffer->address,
  116148. + commandBuffer->dataCount,
  116149. + gcvNULL
  116150. + ));
  116151. +
  116152. + /* The buffer will be auto-executed, only need to
  116153. + update it after it has been executed. */
  116154. + kernelEntry->handler = queueControl->update;
  116155. +
  116156. + /* The buffer is only being updated. */
  116157. + previousExecuted = gcvFALSE;
  116158. + }
  116159. + else
  116160. + {
  116161. + /* Set the buffer up for execution. */
  116162. + kernelEntry->handler = queueControl->execute;
  116163. +
  116164. + /* The buffer is being updated. */
  116165. + previousExecuted = gcvTRUE;
  116166. + }
  116167. +
  116168. + /* The current buffer's END command becomes the last END. */
  116169. + previousEnd
  116170. + = ((gctUINT8_PTR) commandBuffer)
  116171. + + commandBuffer->bufferOffset
  116172. + + commandBuffer->dataCount * Command->info.commandAlignment
  116173. + - Command->info.staticTailSize;
  116174. +
  116175. + /* Update the last entry info. */
  116176. + previousDynamic = userEntry->dynamic;
  116177. +
  116178. + /* Advance entries. */
  116179. + userEntry += 1;
  116180. + kernelEntry += 1;
  116181. +
  116182. + /* Update the control index. */
  116183. + controlIndex = 1;
  116184. + }
  116185. +
  116186. + /* If the previous entry was a dynamic command buffer,
  116187. + terminate it with an END. */
  116188. + if (previousDynamic)
  116189. + {
  116190. + gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
  116191. + Command,
  116192. + previousEnd,
  116193. + Command->info.feBufferInt,
  116194. + gcvNULL
  116195. + ));
  116196. + }
  116197. +
  116198. + /* Last buffer? */
  116199. + if (EntryCount == 0)
  116200. + {
  116201. + /* Modify the last command buffer's routines to handle
  116202. + tasks if any.*/
  116203. + if (haveFETasks)
  116204. + {
  116205. + if (previousExecuted)
  116206. + {
  116207. + kernelEntry[-1].handler = queueControl->lastExecute;
  116208. + }
  116209. + else
  116210. + {
  116211. + kernelEntry[-1].handler = queueControl->lastUpdate;
  116212. + }
  116213. + }
  116214. +
  116215. + /* Release the mutex. */
  116216. + gcmkERR_BREAK(gckOS_ReleaseMutex(
  116217. + Command->os,
  116218. + Command->queueMutex
  116219. + ));
  116220. + /* Schedule tasks. */
  116221. + gcmkERR_BREAK(_ScheduleTasks(Command, TaskTable, previousEnd));
  116222. +
  116223. + /* Acquire the mutex. */
  116224. + gcmkERR_BREAK(gckOS_AcquireMutex(
  116225. + Command->os,
  116226. + Command->queueMutex,
  116227. + gcvINFINITE
  116228. + ));
  116229. + }
  116230. +
  116231. + /* Unkock and schedule the current queue for execution. */
  116232. + gcmkERR_BREAK(_UnlockCurrentQueue(
  116233. + Command, currentLength
  116234. + ));
  116235. + }
  116236. +
  116237. +
  116238. + /* Unmap the user command buffer. */
  116239. + gcmkERR_BREAK(gckOS_UnmapUserPointer(
  116240. + Command->os,
  116241. + Queue,
  116242. + queueSize,
  116243. + mappedQueue
  116244. + ));
  116245. + }
  116246. + while (gcvFALSE);
  116247. +
  116248. + /* Release the mutex. */
  116249. + gcmkCHECK_STATUS(gckOS_ReleaseMutex(
  116250. + Command->os,
  116251. + Command->commitMutex
  116252. + ));
  116253. +
  116254. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
  116255. + Command->os, Command->powerSemaphore));
  116256. + }
  116257. + while (gcvFALSE);
  116258. +
  116259. + gcmkFOOTER();
  116260. + /* Return status. */
  116261. + return status;
  116262. +}
  116263. +
  116264. +#endif /* gcdENABLE_VG */
  116265. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
  116266. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c 1969-12-31 18:00:00.000000000 -0600
  116267. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c 2014-12-08 00:31:53.464418001 -0600
  116268. @@ -0,0 +1,1604 @@
  116269. +/****************************************************************************
  116270. +*
  116271. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  116272. +*
  116273. +* This program is free software; you can redistribute it and/or modify
  116274. +* it under the terms of the GNU General Public License as published by
  116275. +* the Free Software Foundation; either version 2 of the license, or
  116276. +* (at your option) any later version.
  116277. +*
  116278. +* This program is distributed in the hope that it will be useful,
  116279. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  116280. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  116281. +* GNU General Public License for more details.
  116282. +*
  116283. +* You should have received a copy of the GNU General Public License
  116284. +* along with this program; if not write to the Free Software
  116285. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  116286. +*
  116287. +*****************************************************************************/
  116288. +
  116289. +
  116290. +#include "gc_hal_kernel_precomp.h"
  116291. +
  116292. +#define _GC_OBJ_ZONE gcvZONE_DATABASE
  116293. +
  116294. +/*******************************************************************************
  116295. +***** Private fuctions ********************************************************/
  116296. +
  116297. +#define _GetSlot(database, x) \
  116298. + (gctUINT32)(((gcmPTR_TO_UINT64(x) >> 7) % gcmCOUNTOF(database->list)))
  116299. +
  116300. +/*******************************************************************************
  116301. +** gckKERNEL_NewDatabase
  116302. +**
  116303. +** Create a new database structure and insert it to the head of the hash list.
  116304. +**
  116305. +** INPUT:
  116306. +**
  116307. +** gckKERNEL Kernel
  116308. +** Pointer to a gckKERNEL object.
  116309. +**
  116310. +** gctUINT32 ProcessID
  116311. +** ProcessID that identifies the database.
  116312. +**
  116313. +** OUTPUT:
  116314. +**
  116315. +** gcsDATABASE_PTR * Database
  116316. +** Pointer to a variable receiving the database structure pointer on
  116317. +** success.
  116318. +*/
  116319. +static gceSTATUS
  116320. +gckKERNEL_NewDatabase(
  116321. + IN gckKERNEL Kernel,
  116322. + IN gctUINT32 ProcessID,
  116323. + OUT gcsDATABASE_PTR * Database
  116324. + )
  116325. +{
  116326. + gceSTATUS status;
  116327. + gcsDATABASE_PTR database;
  116328. + gctBOOL acquired = gcvFALSE;
  116329. + gctSIZE_T slot;
  116330. + gcsDATABASE_PTR existingDatabase;
  116331. +
  116332. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  116333. +
  116334. + /* Acquire the database mutex. */
  116335. + gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116336. + acquired = gcvTRUE;
  116337. +
  116338. + /* Compute the hash for the database. */
  116339. + slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
  116340. +
  116341. + /* Walk the hash list. */
  116342. + for (existingDatabase = Kernel->db->db[slot];
  116343. + existingDatabase != gcvNULL;
  116344. + existingDatabase = existingDatabase->next)
  116345. + {
  116346. + if (existingDatabase->processID == ProcessID)
  116347. + {
  116348. + /* One process can't be added twice. */
  116349. + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
  116350. + }
  116351. + }
  116352. +
  116353. + if (Kernel->db->freeDatabase != gcvNULL)
  116354. + {
  116355. + /* Allocate a database from the free list. */
  116356. + database = Kernel->db->freeDatabase;
  116357. + Kernel->db->freeDatabase = database->next;
  116358. + }
  116359. + else
  116360. + {
  116361. + gctPOINTER pointer = gcvNULL;
  116362. +
  116363. + /* Allocate a new database from the heap. */
  116364. + gcmkONERROR(gckOS_Allocate(Kernel->os,
  116365. + gcmSIZEOF(gcsDATABASE),
  116366. + &pointer));
  116367. +
  116368. + database = pointer;
  116369. + }
  116370. +
  116371. + /* Insert the database into the hash. */
  116372. + database->next = Kernel->db->db[slot];
  116373. + Kernel->db->db[slot] = database;
  116374. +
  116375. + /* Save the hash slot. */
  116376. + database->slot = slot;
  116377. +
  116378. + /* Release the database mutex. */
  116379. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116380. +
  116381. + /* Return the database. */
  116382. + *Database = database;
  116383. +
  116384. + /* Success. */
  116385. + gcmkFOOTER_ARG("*Database=0x%x", *Database);
  116386. + return gcvSTATUS_OK;
  116387. +
  116388. +OnError:
  116389. + if (acquired)
  116390. + {
  116391. + /* Release the database mutex. */
  116392. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116393. + }
  116394. +
  116395. + /* Return the status. */
  116396. + gcmkFOOTER();
  116397. + return status;
  116398. +}
  116399. +
  116400. +/*******************************************************************************
  116401. +** gckKERNEL_FindDatabase
  116402. +**
  116403. +** Find a database identified by a process ID and move it to the head of the
  116404. +** hash list.
  116405. +**
  116406. +** INPUT:
  116407. +**
  116408. +** gckKERNEL Kernel
  116409. +** Pointer to a gckKERNEL object.
  116410. +**
  116411. +** gctUINT32 ProcessID
  116412. +** ProcessID that identifies the database.
  116413. +**
  116414. +** gctBOOL LastProcessID
  116415. +** gcvTRUE if searching for the last known process ID. gcvFALSE if
  116416. +** we need to search for the process ID specified by the ProcessID
  116417. +** argument.
  116418. +**
  116419. +** OUTPUT:
  116420. +**
  116421. +** gcsDATABASE_PTR * Database
  116422. +** Pointer to a variable receiving the database structure pointer on
  116423. +** success.
  116424. +*/
  116425. +static gceSTATUS
  116426. +gckKERNEL_FindDatabase(
  116427. + IN gckKERNEL Kernel,
  116428. + IN gctUINT32 ProcessID,
  116429. + IN gctBOOL LastProcessID,
  116430. + OUT gcsDATABASE_PTR * Database
  116431. + )
  116432. +{
  116433. + gceSTATUS status;
  116434. + gcsDATABASE_PTR database, previous;
  116435. + gctSIZE_T slot;
  116436. + gctBOOL acquired = gcvFALSE;
  116437. +
  116438. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d LastProcessID=%d",
  116439. + Kernel, ProcessID, LastProcessID);
  116440. +
  116441. + /* Compute the hash for the database. */
  116442. + slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
  116443. +
  116444. + /* Acquire the database mutex. */
  116445. + gcmkONERROR(
  116446. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116447. + acquired = gcvTRUE;
  116448. +
  116449. + /* Check whether we are getting the last known database. */
  116450. + if (LastProcessID)
  116451. + {
  116452. + /* Use last database. */
  116453. + database = Kernel->db->lastDatabase;
  116454. +
  116455. + if (database == gcvNULL)
  116456. + {
  116457. + /* Database not found. */
  116458. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  116459. + }
  116460. + }
  116461. + else
  116462. + {
  116463. + /* Walk the hash list. */
  116464. + for (previous = gcvNULL, database = Kernel->db->db[slot];
  116465. + database != gcvNULL;
  116466. + database = database->next)
  116467. + {
  116468. + if (database->processID == ProcessID)
  116469. + {
  116470. + /* Found it! */
  116471. + break;
  116472. + }
  116473. +
  116474. + previous = database;
  116475. + }
  116476. +
  116477. + if (database == gcvNULL)
  116478. + {
  116479. + /* Database not found. */
  116480. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  116481. + }
  116482. +
  116483. + if (previous != gcvNULL)
  116484. + {
  116485. + /* Move database to the head of the hash list. */
  116486. + previous->next = database->next;
  116487. + database->next = Kernel->db->db[slot];
  116488. + Kernel->db->db[slot] = database;
  116489. + }
  116490. + }
  116491. +
  116492. + /* Release the database mutex. */
  116493. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116494. +
  116495. + /* Return the database. */
  116496. + *Database = database;
  116497. +
  116498. + /* Success. */
  116499. + gcmkFOOTER_ARG("*Database=0x%x", *Database);
  116500. + return gcvSTATUS_OK;
  116501. +
  116502. +OnError:
  116503. + if (acquired)
  116504. + {
  116505. + /* Release the database mutex. */
  116506. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116507. + }
  116508. +
  116509. + /* Return the status. */
  116510. + gcmkFOOTER();
  116511. + return status;
  116512. +}
  116513. +
  116514. +/*******************************************************************************
  116515. +** gckKERNEL_DeleteDatabase
  116516. +**
  116517. +** Remove a database from the hash list and delete its structure.
  116518. +**
  116519. +** INPUT:
  116520. +**
  116521. +** gckKERNEL Kernel
  116522. +** Pointer to a gckKERNEL object.
  116523. +**
  116524. +** gcsDATABASE_PTR Database
  116525. +** Pointer to the database structure to remove.
  116526. +**
  116527. +** OUTPUT:
  116528. +**
  116529. +** Nothing.
  116530. +*/
  116531. +static gceSTATUS
  116532. +gckKERNEL_DeleteDatabase(
  116533. + IN gckKERNEL Kernel,
  116534. + IN gcsDATABASE_PTR Database
  116535. + )
  116536. +{
  116537. + gceSTATUS status;
  116538. + gctBOOL acquired = gcvFALSE;
  116539. + gcsDATABASE_PTR database;
  116540. +
  116541. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
  116542. +
  116543. + /* Acquire the database mutex. */
  116544. + gcmkONERROR(
  116545. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116546. + acquired = gcvTRUE;
  116547. +
  116548. + /* Check slot value. */
  116549. + gcmkVERIFY_ARGUMENT(Database->slot < gcmCOUNTOF(Kernel->db->db));
  116550. +
  116551. + if (Database->slot < gcmCOUNTOF(Kernel->db->db))
  116552. + {
  116553. + /* Check if database if the head of the hash list. */
  116554. + if (Kernel->db->db[Database->slot] == Database)
  116555. + {
  116556. + /* Remove the database from the hash list. */
  116557. + Kernel->db->db[Database->slot] = Database->next;
  116558. + }
  116559. + else
  116560. + {
  116561. + /* Walk the has list to find the database. */
  116562. + for (database = Kernel->db->db[Database->slot];
  116563. + database != gcvNULL;
  116564. + database = database->next
  116565. + )
  116566. + {
  116567. + /* Check if the next list entry is this database. */
  116568. + if (database->next == Database)
  116569. + {
  116570. + /* Remove the database from the hash list. */
  116571. + database->next = Database->next;
  116572. + break;
  116573. + }
  116574. + }
  116575. +
  116576. + if (database == gcvNULL)
  116577. + {
  116578. + /* Ouch! Something got corrupted. */
  116579. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  116580. + }
  116581. + }
  116582. + }
  116583. +
  116584. + if (Kernel->db->lastDatabase != gcvNULL)
  116585. + {
  116586. + /* Insert database to the free list. */
  116587. + Kernel->db->lastDatabase->next = Kernel->db->freeDatabase;
  116588. + Kernel->db->freeDatabase = Kernel->db->lastDatabase;
  116589. + }
  116590. +
  116591. + /* Keep database as the last database. */
  116592. + Kernel->db->lastDatabase = Database;
  116593. +
  116594. + /* Release the database mutex. */
  116595. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116596. +
  116597. + /* Success. */
  116598. + gcmkFOOTER_NO();
  116599. + return gcvSTATUS_OK;
  116600. +
  116601. +OnError:
  116602. + if (acquired)
  116603. + {
  116604. + /* Release the database mutex. */
  116605. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116606. + }
  116607. +
  116608. + /* Return the status. */
  116609. + gcmkFOOTER();
  116610. + return status;
  116611. +}
  116612. +
  116613. +/*******************************************************************************
  116614. +** gckKERNEL_NewRecord
  116615. +**
  116616. +** Create a new database record structure and insert it to the head of the
  116617. +** database.
  116618. +**
  116619. +** INPUT:
  116620. +**
  116621. +** gckKERNEL Kernel
  116622. +** Pointer to a gckKERNEL object.
  116623. +**
  116624. +** gcsDATABASE_PTR Database
  116625. +** Pointer to a database structure.
  116626. +**
  116627. +** OUTPUT:
  116628. +**
  116629. +** gcsDATABASE_RECORD_PTR * Record
  116630. +** Pointer to a variable receiving the database record structure
  116631. +** pointer on success.
  116632. +*/
  116633. +static gceSTATUS
  116634. +gckKERNEL_NewRecord(
  116635. + IN gckKERNEL Kernel,
  116636. + IN gcsDATABASE_PTR Database,
  116637. + IN gctUINT32 Slot,
  116638. + OUT gcsDATABASE_RECORD_PTR * Record
  116639. + )
  116640. +{
  116641. + gceSTATUS status;
  116642. + gctBOOL acquired = gcvFALSE;
  116643. + gcsDATABASE_RECORD_PTR record = gcvNULL;
  116644. +
  116645. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
  116646. +
  116647. + /* Acquire the database mutex. */
  116648. + gcmkONERROR(
  116649. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116650. + acquired = gcvTRUE;
  116651. +
  116652. + if (Kernel->db->freeRecord != gcvNULL)
  116653. + {
  116654. + /* Allocate the record from the free list. */
  116655. + record = Kernel->db->freeRecord;
  116656. + Kernel->db->freeRecord = record->next;
  116657. + }
  116658. + else
  116659. + {
  116660. + gctPOINTER pointer = gcvNULL;
  116661. +
  116662. + /* Allocate the record from the heap. */
  116663. + gcmkONERROR(gckOS_Allocate(Kernel->os,
  116664. + gcmSIZEOF(gcsDATABASE_RECORD),
  116665. + &pointer));
  116666. +
  116667. + record = pointer;
  116668. + }
  116669. +
  116670. + /* Insert the record in the database. */
  116671. + record->next = Database->list[Slot];
  116672. + Database->list[Slot] = record;
  116673. +
  116674. + /* Release the database mutex. */
  116675. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116676. +
  116677. + /* Return the record. */
  116678. + *Record = record;
  116679. +
  116680. + /* Success. */
  116681. + gcmkFOOTER_ARG("*Record=0x%x", *Record);
  116682. + return gcvSTATUS_OK;
  116683. +
  116684. +OnError:
  116685. + if (acquired)
  116686. + {
  116687. + /* Release the database mutex. */
  116688. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116689. + }
  116690. + if (record != gcvNULL)
  116691. + {
  116692. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, record));
  116693. + }
  116694. +
  116695. + /* Return the status. */
  116696. + gcmkFOOTER();
  116697. + return status;
  116698. +}
  116699. +
  116700. +/*******************************************************************************
  116701. +** gckKERNEL_DeleteRecord
  116702. +**
  116703. +** Remove a database record from the database and delete its structure.
  116704. +**
  116705. +** INPUT:
  116706. +**
  116707. +** gckKERNEL Kernel
  116708. +** Pointer to a gckKERNEL object.
  116709. +**
  116710. +** gcsDATABASE_PTR Database
  116711. +** Pointer to a database structure.
  116712. +**
  116713. +** gceDATABASE_TYPE Type
  116714. +** Type of the record to remove.
  116715. +**
  116716. +** gctPOINTER Data
  116717. +** Data of the record to remove.
  116718. +**
  116719. +** OUTPUT:
  116720. +**
  116721. +** gctSIZE_T_PTR Bytes
  116722. +** Pointer to a variable that receives the size of the record deleted.
  116723. +** Can be gcvNULL if the size is not required.
  116724. +*/
  116725. +static gceSTATUS
  116726. +gckKERNEL_DeleteRecord(
  116727. + IN gckKERNEL Kernel,
  116728. + IN gcsDATABASE_PTR Database,
  116729. + IN gceDATABASE_TYPE Type,
  116730. + IN gctPOINTER Data,
  116731. + OUT gctSIZE_T_PTR Bytes OPTIONAL
  116732. + )
  116733. +{
  116734. + gceSTATUS status;
  116735. + gctBOOL acquired = gcvFALSE;
  116736. + gcsDATABASE_RECORD_PTR record, previous;
  116737. + gctUINT32 slot = _GetSlot(Database, Data);
  116738. +
  116739. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
  116740. + Kernel, Database, Type, Data);
  116741. +
  116742. + /* Acquire the database mutex. */
  116743. + gcmkONERROR(
  116744. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116745. + acquired = gcvTRUE;
  116746. +
  116747. +
  116748. + /* Scan the database for this record. */
  116749. + for (record = Database->list[slot], previous = gcvNULL;
  116750. + record != gcvNULL;
  116751. + record = record->next
  116752. + )
  116753. + {
  116754. + if ((record->type == Type)
  116755. + && (record->data == Data)
  116756. + )
  116757. + {
  116758. + /* Found it! */
  116759. + break;
  116760. + }
  116761. +
  116762. + previous = record;
  116763. + }
  116764. +
  116765. + if (record == gcvNULL)
  116766. + {
  116767. + /* Ouch! This record is not found? */
  116768. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  116769. + }
  116770. +
  116771. + if (Bytes != gcvNULL)
  116772. + {
  116773. + /* Return size of record. */
  116774. + *Bytes = record->bytes;
  116775. + }
  116776. +
  116777. + /* Remove record from database. */
  116778. + if (previous == gcvNULL)
  116779. + {
  116780. + Database->list[slot] = record->next;
  116781. + }
  116782. + else
  116783. + {
  116784. + previous->next = record->next;
  116785. + }
  116786. +
  116787. + /* Insert record in free list. */
  116788. + record->next = Kernel->db->freeRecord;
  116789. + Kernel->db->freeRecord = record;
  116790. +
  116791. + /* Release the database mutex. */
  116792. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116793. +
  116794. + /* Success. */
  116795. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  116796. + return gcvSTATUS_OK;
  116797. +
  116798. +OnError:
  116799. + if (acquired)
  116800. + {
  116801. + /* Release the database mutex. */
  116802. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116803. + }
  116804. +
  116805. + /* Return the status. */
  116806. + gcmkFOOTER();
  116807. + return status;
  116808. +}
  116809. +
  116810. +/*******************************************************************************
  116811. +** gckKERNEL_FindRecord
  116812. +**
  116813. +** Find a database record from the database.
  116814. +**
  116815. +** INPUT:
  116816. +**
  116817. +** gckKERNEL Kernel
  116818. +** Pointer to a gckKERNEL object.
  116819. +**
  116820. +** gcsDATABASE_PTR Database
  116821. +** Pointer to a database structure.
  116822. +**
  116823. +** gceDATABASE_TYPE Type
  116824. +** Type of the record to remove.
  116825. +**
  116826. +** gctPOINTER Data
  116827. +** Data of the record to remove.
  116828. +**
  116829. +** OUTPUT:
  116830. +**
  116831. +** gctSIZE_T_PTR Bytes
  116832. +** Pointer to a variable that receives the size of the record deleted.
  116833. +** Can be gcvNULL if the size is not required.
  116834. +*/
  116835. +static gceSTATUS
  116836. +gckKERNEL_FindRecord(
  116837. + IN gckKERNEL Kernel,
  116838. + IN gcsDATABASE_PTR Database,
  116839. + IN gceDATABASE_TYPE Type,
  116840. + IN gctPOINTER Data,
  116841. + OUT gcsDATABASE_RECORD_PTR Record
  116842. + )
  116843. +{
  116844. + gceSTATUS status;
  116845. + gctBOOL acquired = gcvFALSE;
  116846. + gcsDATABASE_RECORD_PTR record;
  116847. + gctUINT32 slot = _GetSlot(Database, Data);
  116848. +
  116849. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
  116850. + Kernel, Database, Type, Data);
  116851. +
  116852. + /* Acquire the database mutex. */
  116853. + gcmkONERROR(
  116854. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  116855. + acquired = gcvTRUE;
  116856. +
  116857. + /* Scan the database for this record. */
  116858. + for (record = Database->list[slot];
  116859. + record != gcvNULL;
  116860. + record = record->next
  116861. + )
  116862. + {
  116863. + if ((record->type == Type)
  116864. + && (record->data == Data)
  116865. + )
  116866. + {
  116867. + /* Found it! */
  116868. + break;
  116869. + }
  116870. + }
  116871. +
  116872. + if (record == gcvNULL)
  116873. + {
  116874. + /* Ouch! This record is not found? */
  116875. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  116876. + }
  116877. +
  116878. + if (Record != gcvNULL)
  116879. + {
  116880. + /* Return information of record. */
  116881. + gcmkONERROR(
  116882. + gckOS_MemCopy(Record, record, sizeof(gcsDATABASE_RECORD)));
  116883. + }
  116884. +
  116885. + /* Release the database mutex. */
  116886. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116887. +
  116888. + /* Success. */
  116889. + gcmkFOOTER_ARG("Record=0x%x", Record);
  116890. + return gcvSTATUS_OK;
  116891. +
  116892. +OnError:
  116893. + if (acquired)
  116894. + {
  116895. + /* Release the database mutex. */
  116896. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  116897. + }
  116898. +
  116899. + /* Return the status. */
  116900. + gcmkFOOTER();
  116901. + return status;
  116902. +}
  116903. +
  116904. +
  116905. +/*******************************************************************************
  116906. +***** Public API **************************************************************/
  116907. +
  116908. +/*******************************************************************************
  116909. +** gckKERNEL_CreateProcessDB
  116910. +**
  116911. +** Create a new process database.
  116912. +**
  116913. +** INPUT:
  116914. +**
  116915. +** gckKERNEL Kernel
  116916. +** Pointer to a gckKERNEL object.
  116917. +**
  116918. +** gctUINT32 ProcessID
  116919. +** Process ID used to identify the database.
  116920. +**
  116921. +** OUTPUT:
  116922. +**
  116923. +** Nothing.
  116924. +*/
  116925. +gceSTATUS
  116926. +gckKERNEL_CreateProcessDB(
  116927. + IN gckKERNEL Kernel,
  116928. + IN gctUINT32 ProcessID
  116929. + )
  116930. +{
  116931. + gceSTATUS status;
  116932. + gcsDATABASE_PTR database = gcvNULL;
  116933. + gctUINT32 i;
  116934. +
  116935. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  116936. +
  116937. + /* Verify the arguments. */
  116938. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  116939. +
  116940. + /* Create a new database. */
  116941. + gcmkONERROR(gckKERNEL_NewDatabase(Kernel, ProcessID, &database));
  116942. +
  116943. + /* Initialize the database. */
  116944. + database->processID = ProcessID;
  116945. + database->vidMem.bytes = 0;
  116946. + database->vidMem.maxBytes = 0;
  116947. + database->vidMem.totalBytes = 0;
  116948. + database->nonPaged.bytes = 0;
  116949. + database->nonPaged.maxBytes = 0;
  116950. + database->nonPaged.totalBytes = 0;
  116951. + database->contiguous.bytes = 0;
  116952. + database->contiguous.maxBytes = 0;
  116953. + database->contiguous.totalBytes = 0;
  116954. + database->mapMemory.bytes = 0;
  116955. + database->mapMemory.maxBytes = 0;
  116956. + database->mapMemory.totalBytes = 0;
  116957. + database->mapUserMemory.bytes = 0;
  116958. + database->mapUserMemory.maxBytes = 0;
  116959. + database->mapUserMemory.totalBytes = 0;
  116960. + database->vidMemResv.bytes = 0;
  116961. + database->vidMemResv.maxBytes = 0;
  116962. + database->vidMemResv.totalBytes = 0;
  116963. + database->vidMemCont.bytes = 0;
  116964. + database->vidMemCont.maxBytes = 0;
  116965. + database->vidMemCont.totalBytes = 0;
  116966. + database->vidMemVirt.bytes = 0;
  116967. + database->vidMemVirt.maxBytes = 0;
  116968. + database->vidMemVirt.totalBytes = 0;
  116969. +
  116970. + for (i = 0; i < gcmCOUNTOF(database->list); i++)
  116971. + {
  116972. + database->list[i] = gcvNULL;
  116973. + }
  116974. +
  116975. +#if gcdSECURE_USER
  116976. + {
  116977. + gctINT slot;
  116978. + gcskSECURE_CACHE * cache = &database->cache;
  116979. +
  116980. + /* Setup the linked list of cache nodes. */
  116981. + for (slot = 1; slot <= gcdSECURE_CACHE_SLOTS; ++slot)
  116982. + {
  116983. + cache->cache[slot].logical = gcvNULL;
  116984. +
  116985. +#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
  116986. + cache->cache[slot].prev = &cache->cache[slot - 1];
  116987. + cache->cache[slot].next = &cache->cache[slot + 1];
  116988. +# endif
  116989. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  116990. + cache->cache[slot].nextHash = gcvNULL;
  116991. + cache->cache[slot].prevHash = gcvNULL;
  116992. +# endif
  116993. + }
  116994. +
  116995. +#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
  116996. + /* Setup the head and tail of the cache. */
  116997. + cache->cache[0].next = &cache->cache[1];
  116998. + cache->cache[0].prev = &cache->cache[gcdSECURE_CACHE_SLOTS];
  116999. + cache->cache[0].logical = gcvNULL;
  117000. +
  117001. + /* Fix up the head and tail pointers. */
  117002. + cache->cache[0].next->prev = &cache->cache[0];
  117003. + cache->cache[0].prev->next = &cache->cache[0];
  117004. +# endif
  117005. +
  117006. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  117007. + /* Zero out the hash table. */
  117008. + for (slot = 0; slot < gcmCOUNTOF(cache->hash); ++slot)
  117009. + {
  117010. + cache->hash[slot].logical = gcvNULL;
  117011. + cache->hash[slot].nextHash = gcvNULL;
  117012. + }
  117013. +# endif
  117014. +
  117015. + /* Initialize cache index. */
  117016. + cache->cacheIndex = gcvNULL;
  117017. + cache->cacheFree = 1;
  117018. + cache->cacheStamp = 0;
  117019. + }
  117020. +#endif
  117021. +
  117022. + /* Reset idle timer. */
  117023. + Kernel->db->lastIdle = 0;
  117024. +
  117025. + /* Success. */
  117026. + gcmkFOOTER_NO();
  117027. + return gcvSTATUS_OK;
  117028. +
  117029. +OnError:
  117030. + /* Return the status. */
  117031. + gcmkFOOTER();
  117032. + return status;
  117033. +}
  117034. +
  117035. +/*******************************************************************************
  117036. +** gckKERNEL_AddProcessDB
  117037. +**
  117038. +** Add a record to a process database.
  117039. +**
  117040. +** INPUT:
  117041. +**
  117042. +** gckKERNEL Kernel
  117043. +** Pointer to a gckKERNEL object.
  117044. +**
  117045. +** gctUINT32 ProcessID
  117046. +** Process ID used to identify the database.
  117047. +**
  117048. +** gceDATABASE_TYPE TYPE
  117049. +** Type of the record to add.
  117050. +**
  117051. +** gctPOINTER Pointer
  117052. +** Data of the record to add.
  117053. +**
  117054. +** gctPHYS_ADDR Physical
  117055. +** Physical address of the record to add.
  117056. +**
  117057. +** gctSIZE_T Size
  117058. +** Size of the record to add.
  117059. +**
  117060. +** OUTPUT:
  117061. +**
  117062. +** Nothing.
  117063. +*/
  117064. +gceSTATUS
  117065. +gckKERNEL_AddProcessDB(
  117066. + IN gckKERNEL Kernel,
  117067. + IN gctUINT32 ProcessID,
  117068. + IN gceDATABASE_TYPE Type,
  117069. + IN gctPOINTER Pointer,
  117070. + IN gctPHYS_ADDR Physical,
  117071. + IN gctSIZE_T Size
  117072. + )
  117073. +{
  117074. + gceSTATUS status;
  117075. + gcsDATABASE_PTR database;
  117076. + gcsDATABASE_RECORD_PTR record = gcvNULL;
  117077. + gcsDATABASE_COUNTERS * count;
  117078. +
  117079. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x "
  117080. + "Physical=0x%x Size=%lu",
  117081. + Kernel, ProcessID, Type, Pointer, Physical, Size);
  117082. +
  117083. + /* Verify the arguments. */
  117084. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117085. +
  117086. + /* Special case the idle record. */
  117087. + if (Type == gcvDB_IDLE)
  117088. + {
  117089. + gctUINT64 time;
  117090. +
  117091. + /* Get the current profile time. */
  117092. + gcmkONERROR(gckOS_GetProfileTick(&time));
  117093. +
  117094. + if ((ProcessID == 0) && (Kernel->db->lastIdle != 0))
  117095. + {
  117096. + /* Out of idle, adjust time it was idle. */
  117097. + Kernel->db->idleTime += time - Kernel->db->lastIdle;
  117098. + Kernel->db->lastIdle = 0;
  117099. + }
  117100. + else if (ProcessID == 1)
  117101. + {
  117102. + /* Save current idle time. */
  117103. + Kernel->db->lastIdle = time;
  117104. + }
  117105. +
  117106. +#if gcdDYNAMIC_SPEED
  117107. + {
  117108. + /* Test for first call. */
  117109. + if (Kernel->db->lastSlowdown == 0)
  117110. + {
  117111. + /* Save milliseconds. */
  117112. + Kernel->db->lastSlowdown = time;
  117113. + Kernel->db->lastSlowdownIdle = Kernel->db->idleTime;
  117114. + }
  117115. + else
  117116. + {
  117117. + /* Compute ellapsed time in milliseconds. */
  117118. + gctUINT delta = gckOS_ProfileToMS(time - Kernel->db->lastSlowdown);
  117119. +
  117120. + /* Test for end of period. */
  117121. + if (delta >= gcdDYNAMIC_SPEED)
  117122. + {
  117123. + /* Compute number of idle milliseconds. */
  117124. + gctUINT idle = gckOS_ProfileToMS(
  117125. + Kernel->db->idleTime - Kernel->db->lastSlowdownIdle);
  117126. +
  117127. + /* Broadcast to slow down the GPU. */
  117128. + gcmkONERROR(gckOS_BroadcastCalibrateSpeed(Kernel->os,
  117129. + Kernel->hardware,
  117130. + idle,
  117131. + delta));
  117132. +
  117133. + /* Save current time. */
  117134. + Kernel->db->lastSlowdown = time;
  117135. + Kernel->db->lastSlowdownIdle = Kernel->db->idleTime;
  117136. + }
  117137. + }
  117138. + }
  117139. +#endif
  117140. +
  117141. + /* Success. */
  117142. + gcmkFOOTER_NO();
  117143. + return gcvSTATUS_OK;
  117144. + }
  117145. +
  117146. + /* Verify the arguments. */
  117147. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  117148. +
  117149. + /* Find the database. */
  117150. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  117151. +
  117152. + /* Create a new record in the database. */
  117153. + gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, _GetSlot(database, Pointer), &record));
  117154. +
  117155. + /* Initialize the record. */
  117156. + record->kernel = Kernel;
  117157. + record->type = Type;
  117158. + record->data = Pointer;
  117159. + record->physical = Physical;
  117160. + record->bytes = Size;
  117161. +
  117162. + /* Get pointer to counters. */
  117163. + switch (Type)
  117164. + {
  117165. + case gcvDB_VIDEO_MEMORY:
  117166. + count = &database->vidMem;
  117167. + break;
  117168. +
  117169. + case gcvDB_NON_PAGED:
  117170. + count = &database->nonPaged;
  117171. + break;
  117172. +
  117173. + case gcvDB_CONTIGUOUS:
  117174. + count = &database->contiguous;
  117175. + break;
  117176. +
  117177. + case gcvDB_MAP_MEMORY:
  117178. + count = &database->mapMemory;
  117179. + break;
  117180. +
  117181. + case gcvDB_MAP_USER_MEMORY:
  117182. + count = &database->mapUserMemory;
  117183. + break;
  117184. +
  117185. + case gcvDB_VIDEO_MEMORY_RESERVED:
  117186. + count = &database->vidMemResv;
  117187. + break;
  117188. +
  117189. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  117190. + count = &database->vidMemCont;
  117191. + break;
  117192. +
  117193. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  117194. + count = &database->vidMemVirt;
  117195. + break;
  117196. +
  117197. + default:
  117198. + count = gcvNULL;
  117199. + break;
  117200. + }
  117201. +
  117202. + if (count != gcvNULL)
  117203. + {
  117204. + /* Adjust counters. */
  117205. + count->totalBytes += Size;
  117206. + count->bytes += Size;
  117207. +
  117208. + if (count->bytes > count->maxBytes)
  117209. + {
  117210. + count->maxBytes = count->bytes;
  117211. + }
  117212. + }
  117213. +
  117214. + /* Success. */
  117215. + gcmkFOOTER_NO();
  117216. + return gcvSTATUS_OK;
  117217. +
  117218. +OnError:
  117219. + /* Return the status. */
  117220. + gcmkFOOTER();
  117221. + return status;
  117222. +}
  117223. +
  117224. +/*******************************************************************************
  117225. +** gckKERNEL_RemoveProcessDB
  117226. +**
  117227. +** Remove a record from a process database.
  117228. +**
  117229. +** INPUT:
  117230. +**
  117231. +** gckKERNEL Kernel
  117232. +** Pointer to a gckKERNEL object.
  117233. +**
  117234. +** gctUINT32 ProcessID
  117235. +** Process ID used to identify the database.
  117236. +**
  117237. +** gceDATABASE_TYPE TYPE
  117238. +** Type of the record to remove.
  117239. +**
  117240. +** gctPOINTER Pointer
  117241. +** Data of the record to remove.
  117242. +**
  117243. +** OUTPUT:
  117244. +**
  117245. +** Nothing.
  117246. +*/
  117247. +gceSTATUS
  117248. +gckKERNEL_RemoveProcessDB(
  117249. + IN gckKERNEL Kernel,
  117250. + IN gctUINT32 ProcessID,
  117251. + IN gceDATABASE_TYPE Type,
  117252. + IN gctPOINTER Pointer
  117253. + )
  117254. +{
  117255. + gceSTATUS status;
  117256. + gcsDATABASE_PTR database;
  117257. + gctSIZE_T bytes = 0;
  117258. +
  117259. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
  117260. + Kernel, ProcessID, Type, Pointer);
  117261. +
  117262. + /* Verify the arguments. */
  117263. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117264. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  117265. +
  117266. + /* Find the database. */
  117267. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  117268. +
  117269. + /* Delete the record. */
  117270. + gcmkONERROR(
  117271. + gckKERNEL_DeleteRecord(Kernel, database, Type, Pointer, &bytes));
  117272. +
  117273. + /* Update counters. */
  117274. + switch (Type)
  117275. + {
  117276. + case gcvDB_VIDEO_MEMORY:
  117277. + database->vidMem.bytes -= bytes;
  117278. + break;
  117279. +
  117280. + case gcvDB_NON_PAGED:
  117281. + database->nonPaged.bytes -= bytes;
  117282. + break;
  117283. +
  117284. + case gcvDB_CONTIGUOUS:
  117285. + database->contiguous.bytes -= bytes;
  117286. + break;
  117287. +
  117288. + case gcvDB_MAP_MEMORY:
  117289. + database->mapMemory.bytes -= bytes;
  117290. + break;
  117291. +
  117292. + case gcvDB_MAP_USER_MEMORY:
  117293. + database->mapUserMemory.bytes -= bytes;
  117294. + break;
  117295. +
  117296. + case gcvDB_VIDEO_MEMORY_RESERVED:
  117297. + database->vidMemResv.bytes -= bytes;
  117298. + break;
  117299. +
  117300. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  117301. + database->vidMemCont.bytes -= bytes;
  117302. + break;
  117303. +
  117304. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  117305. + database->vidMemVirt.bytes -= bytes;
  117306. + break;
  117307. +
  117308. + default:
  117309. + break;
  117310. + }
  117311. +
  117312. + /* Success. */
  117313. + gcmkFOOTER_NO();
  117314. + return gcvSTATUS_OK;
  117315. +
  117316. +OnError:
  117317. + /* Return the status. */
  117318. + gcmkFOOTER();
  117319. + return status;
  117320. +}
  117321. +
  117322. +/*******************************************************************************
  117323. +** gckKERNEL_FindProcessDB
  117324. +**
  117325. +** Find a record from a process database.
  117326. +**
  117327. +** INPUT:
  117328. +**
  117329. +** gckKERNEL Kernel
  117330. +** Pointer to a gckKERNEL object.
  117331. +**
  117332. +** gctUINT32 ProcessID
  117333. +** Process ID used to identify the database.
  117334. +**
  117335. +** gceDATABASE_TYPE TYPE
  117336. +** Type of the record to remove.
  117337. +**
  117338. +** gctPOINTER Pointer
  117339. +** Data of the record to remove.
  117340. +**
  117341. +** OUTPUT:
  117342. +**
  117343. +** gcsDATABASE_RECORD_PTR Record
  117344. +** Copy of record.
  117345. +*/
  117346. +gceSTATUS
  117347. +gckKERNEL_FindProcessDB(
  117348. + IN gckKERNEL Kernel,
  117349. + IN gctUINT32 ProcessID,
  117350. + IN gctUINT32 ThreadID,
  117351. + IN gceDATABASE_TYPE Type,
  117352. + IN gctPOINTER Pointer,
  117353. + OUT gcsDATABASE_RECORD_PTR Record
  117354. + )
  117355. +{
  117356. + gceSTATUS status;
  117357. + gcsDATABASE_PTR database;
  117358. +
  117359. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
  117360. + Kernel, ProcessID, ThreadID, Type, Pointer);
  117361. +
  117362. + /* Verify the arguments. */
  117363. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117364. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  117365. +
  117366. + /* Find the database. */
  117367. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  117368. +
  117369. + /* Find the record. */
  117370. + gcmkONERROR(
  117371. + gckKERNEL_FindRecord(Kernel, database, Type, Pointer, Record));
  117372. +
  117373. + /* Success. */
  117374. + gcmkFOOTER_NO();
  117375. + return gcvSTATUS_OK;
  117376. +
  117377. +OnError:
  117378. + /* Return the status. */
  117379. + gcmkFOOTER();
  117380. + return status;
  117381. +}
  117382. +
  117383. +/*******************************************************************************
  117384. +** gckKERNEL_DestroyProcessDB
  117385. +**
  117386. +** Destroy a process database. If the database contains any records, the data
  117387. +** inside those records will be deleted as well. This aids in the cleanup if
  117388. +** a process has died unexpectedly or has memory leaks.
  117389. +**
  117390. +** INPUT:
  117391. +**
  117392. +** gckKERNEL Kernel
  117393. +** Pointer to a gckKERNEL object.
  117394. +**
  117395. +** gctUINT32 ProcessID
  117396. +** Process ID used to identify the database.
  117397. +**
  117398. +** OUTPUT:
  117399. +**
  117400. +** Nothing.
  117401. +*/
  117402. +gceSTATUS
  117403. +gckKERNEL_DestroyProcessDB(
  117404. + IN gckKERNEL Kernel,
  117405. + IN gctUINT32 ProcessID
  117406. + )
  117407. +{
  117408. + gceSTATUS status;
  117409. + gcsDATABASE_PTR database;
  117410. + gcsDATABASE_RECORD_PTR record, next;
  117411. + gctBOOL asynchronous;
  117412. + gctPHYS_ADDR physical;
  117413. + gcuVIDMEM_NODE_PTR node;
  117414. + gckKERNEL kernel = Kernel;
  117415. + gctUINT32 i;
  117416. +
  117417. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  117418. +
  117419. + /* Verify the arguments. */
  117420. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117421. +
  117422. + /* Find the database. */
  117423. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  117424. +
  117425. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117426. + "DB(%d): VidMem: total=%lu max=%lu",
  117427. + ProcessID, database->vidMem.totalBytes,
  117428. + database->vidMem.maxBytes);
  117429. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117430. + "DB(%d): NonPaged: total=%lu max=%lu",
  117431. + ProcessID, database->nonPaged.totalBytes,
  117432. + database->nonPaged.maxBytes);
  117433. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117434. + "DB(%d): Contiguous: total=%lu max=%lu",
  117435. + ProcessID, database->contiguous.totalBytes,
  117436. + database->contiguous.maxBytes);
  117437. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117438. + "DB(%d): Idle time=%llu",
  117439. + ProcessID, Kernel->db->idleTime);
  117440. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117441. + "DB(%d): Map: total=%lu max=%lu",
  117442. + ProcessID, database->mapMemory.totalBytes,
  117443. + database->mapMemory.maxBytes);
  117444. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  117445. + "DB(%d): Map: total=%lu max=%lu",
  117446. + ProcessID, database->mapUserMemory.totalBytes,
  117447. + database->mapUserMemory.maxBytes);
  117448. +
  117449. + if (database->list != gcvNULL)
  117450. + {
  117451. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117452. + "Process %d has entries in its database:",
  117453. + ProcessID);
  117454. + }
  117455. +
  117456. + for(i = 0; i < gcmCOUNTOF(database->list); i++)
  117457. + {
  117458. +
  117459. + /* Walk all records. */
  117460. + for (record = database->list[i]; record != gcvNULL; record = next)
  117461. + {
  117462. + /* Next next record. */
  117463. + next = record->next;
  117464. +
  117465. + /* Dispatch on record type. */
  117466. + switch (record->type)
  117467. + {
  117468. + case gcvDB_VIDEO_MEMORY:
  117469. + /* Free the video memory. */
  117470. + status = gckVIDMEM_Free(gcmUINT64_TO_PTR(record->data));
  117471. +
  117472. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117473. + "DB: VIDEO_MEMORY 0x%x (status=%d)",
  117474. + record->data, status);
  117475. + break;
  117476. +
  117477. + case gcvDB_NON_PAGED:
  117478. + physical = gcmNAME_TO_PTR(record->physical);
  117479. + /* Unmap user logical memory first. */
  117480. + status = gckOS_UnmapUserLogical(Kernel->os,
  117481. + physical,
  117482. + record->bytes,
  117483. + record->data);
  117484. +
  117485. + /* Free the non paged memory. */
  117486. + status = gckOS_FreeNonPagedMemory(Kernel->os,
  117487. + record->bytes,
  117488. + physical,
  117489. + record->data);
  117490. + gcmRELEASE_NAME(record->physical);
  117491. +
  117492. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117493. + "DB: NON_PAGED 0x%x, bytes=%lu (status=%d)",
  117494. + record->data, record->bytes, status);
  117495. + break;
  117496. +
  117497. +#if gcdVIRTUAL_COMMAND_BUFFER
  117498. + case gcvDB_COMMAND_BUFFER:
  117499. + /* Free the command buffer. */
  117500. + status = gckEVENT_DestroyVirtualCommandBuffer(record->kernel->eventObj,
  117501. + record->bytes,
  117502. + gcmNAME_TO_PTR(record->physical),
  117503. + record->data,
  117504. + gcvKERNEL_PIXEL);
  117505. + gcmRELEASE_NAME(record->physical);
  117506. +
  117507. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117508. + "DB: COMMAND_BUFFER 0x%x, bytes=%lu (status=%d)",
  117509. + record->data, record->bytes, status);
  117510. + break;
  117511. +#endif
  117512. +
  117513. + case gcvDB_CONTIGUOUS:
  117514. + physical = gcmNAME_TO_PTR(record->physical);
  117515. + /* Unmap user logical memory first. */
  117516. + status = gckOS_UnmapUserLogical(Kernel->os,
  117517. + physical,
  117518. + record->bytes,
  117519. + record->data);
  117520. +
  117521. + /* Free the contiguous memory. */
  117522. + status = gckEVENT_FreeContiguousMemory(Kernel->eventObj,
  117523. + record->bytes,
  117524. + physical,
  117525. + record->data,
  117526. + gcvKERNEL_PIXEL);
  117527. + gcmRELEASE_NAME(record->physical);
  117528. +
  117529. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117530. + "DB: CONTIGUOUS 0x%x bytes=%lu (status=%d)",
  117531. + record->data, record->bytes, status);
  117532. + break;
  117533. +
  117534. + case gcvDB_SIGNAL:
  117535. +#if USE_NEW_LINUX_SIGNAL
  117536. + status = gcvSTATUS_NOT_SUPPORTED;
  117537. +#else
  117538. + /* Free the user signal. */
  117539. + status = gckOS_DestroyUserSignal(Kernel->os,
  117540. + gcmPTR2INT(record->data));
  117541. +#endif /* USE_NEW_LINUX_SIGNAL */
  117542. +
  117543. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117544. + "DB: SIGNAL %d (status=%d)",
  117545. + (gctINT)(gctUINTPTR_T)record->data, status);
  117546. + break;
  117547. +
  117548. + case gcvDB_VIDEO_MEMORY_LOCKED:
  117549. + node = gcmUINT64_TO_PTR(record->data);
  117550. + /* Unlock what we still locked */
  117551. + status = gckVIDMEM_Unlock(record->kernel,
  117552. + node,
  117553. + gcvSURF_TYPE_UNKNOWN,
  117554. + &asynchronous);
  117555. +
  117556. + if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous))
  117557. + {
  117558. + /* TODO: we maybe need to schedule a event here */
  117559. + status = gckVIDMEM_Unlock(record->kernel,
  117560. + node,
  117561. + gcvSURF_TYPE_UNKNOWN,
  117562. + gcvNULL);
  117563. + }
  117564. +
  117565. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117566. + "DB: VIDEO_MEMORY_LOCKED 0x%x (status=%d)",
  117567. + node, status);
  117568. + break;
  117569. +
  117570. + case gcvDB_CONTEXT:
  117571. + /* TODO: Free the context */
  117572. + status = gckCOMMAND_Detach(Kernel->command, gcmNAME_TO_PTR(record->data));
  117573. + gcmRELEASE_NAME(record->data);
  117574. +
  117575. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117576. + "DB: CONTEXT 0x%x (status=%d)",
  117577. + record->data, status);
  117578. + break;
  117579. +
  117580. + case gcvDB_MAP_MEMORY:
  117581. + /* Unmap memory. */
  117582. + status = gckKERNEL_UnmapMemory(Kernel,
  117583. + record->physical,
  117584. + record->bytes,
  117585. + record->data);
  117586. +
  117587. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117588. + "DB: MAP MEMORY %d (status=%d)",
  117589. + gcmPTR2INT(record->data), status);
  117590. + break;
  117591. +
  117592. + case gcvDB_MAP_USER_MEMORY:
  117593. + /* TODO: Unmap user memory. */
  117594. + status = gckOS_UnmapUserMemory(Kernel->os,
  117595. + Kernel->core,
  117596. + record->physical,
  117597. + record->bytes,
  117598. + gcmNAME_TO_PTR(record->data),
  117599. + 0);
  117600. + gcmRELEASE_NAME(record->data);
  117601. +
  117602. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117603. + "DB: MAP USER MEMORY %d (status=%d)",
  117604. + gcmPTR2INT(record->data), status);
  117605. + break;
  117606. +
  117607. + case gcvDB_SHARED_INFO:
  117608. + status = gckOS_FreeMemory(Kernel->os, record->physical);
  117609. + break;
  117610. +
  117611. +#if gcdANDROID_NATIVE_FENCE_SYNC
  117612. + case gcvDB_SYNC_POINT:
  117613. + /* Free the user signal. */
  117614. + status = gckOS_DestroySyncPoint(Kernel->os,
  117615. + (gctSYNC_POINT) record->data);
  117616. +
  117617. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  117618. + "DB: SYNC POINT %d (status=%d)",
  117619. + (gctINT)(gctUINTPTR_T)record->data, status);
  117620. + break;
  117621. +#endif
  117622. +
  117623. + case gcvDB_VIDEO_MEMORY_RESERVED:
  117624. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  117625. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  117626. + break;//Nothing to do
  117627. +
  117628. + default:
  117629. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DATABASE,
  117630. + "DB: Correcupted record=0x%08x type=%d",
  117631. + record, record->type);
  117632. + break;
  117633. + }
  117634. +
  117635. + /* Delete the record. */
  117636. + gcmkONERROR(gckKERNEL_DeleteRecord(Kernel,
  117637. + database,
  117638. + record->type,
  117639. + record->data,
  117640. + gcvNULL));
  117641. + }
  117642. +
  117643. + }
  117644. +
  117645. + /* Delete the database. */
  117646. + gcmkONERROR(gckKERNEL_DeleteDatabase(Kernel, database));
  117647. +
  117648. + /* Success. */
  117649. + gcmkFOOTER_NO();
  117650. + return gcvSTATUS_OK;
  117651. +
  117652. +OnError:
  117653. + /* Return the status. */
  117654. + gcmkFOOTER();
  117655. + return status;
  117656. +}
  117657. +
  117658. +/*******************************************************************************
  117659. +** gckKERNEL_QueryProcessDB
  117660. +**
  117661. +** Query a process database for the current usage of a particular record type.
  117662. +**
  117663. +** INPUT:
  117664. +**
  117665. +** gckKERNEL Kernel
  117666. +** Pointer to a gckKERNEL object.
  117667. +**
  117668. +** gctUINT32 ProcessID
  117669. +** Process ID used to identify the database.
  117670. +**
  117671. +** gctBOOL LastProcessID
  117672. +** gcvTRUE if searching for the last known process ID. gcvFALSE if
  117673. +** we need to search for the process ID specified by the ProcessID
  117674. +** argument.
  117675. +**
  117676. +** gceDATABASE_TYPE Type
  117677. +** Type of the record to query.
  117678. +**
  117679. +** OUTPUT:
  117680. +**
  117681. +** gcuDATABASE_INFO * Info
  117682. +** Pointer to a variable that receives the requested information.
  117683. +*/
  117684. +gceSTATUS
  117685. +gckKERNEL_QueryProcessDB(
  117686. + IN gckKERNEL Kernel,
  117687. + IN gctUINT32 ProcessID,
  117688. + IN gctBOOL LastProcessID,
  117689. + IN gceDATABASE_TYPE Type,
  117690. + OUT gcuDATABASE_INFO * Info
  117691. + )
  117692. +{
  117693. + gceSTATUS status;
  117694. + gcsDATABASE_PTR database;
  117695. +
  117696. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Info=0x%x",
  117697. + Kernel, ProcessID, Type, Info);
  117698. +
  117699. + /* Verify the arguments. */
  117700. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117701. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  117702. +
  117703. + /* Find the database. */
  117704. + gcmkONERROR(
  117705. + gckKERNEL_FindDatabase(Kernel, ProcessID, LastProcessID, &database));
  117706. +
  117707. + /* Get pointer to counters. */
  117708. + switch (Type)
  117709. + {
  117710. + case gcvDB_VIDEO_MEMORY:
  117711. + gckOS_MemCopy(&Info->counters,
  117712. + &database->vidMem,
  117713. + gcmSIZEOF(database->vidMem));
  117714. + break;
  117715. +
  117716. + case gcvDB_NON_PAGED:
  117717. + gckOS_MemCopy(&Info->counters,
  117718. + &database->nonPaged,
  117719. + gcmSIZEOF(database->vidMem));
  117720. + break;
  117721. +
  117722. + case gcvDB_CONTIGUOUS:
  117723. + gckOS_MemCopy(&Info->counters,
  117724. + &database->contiguous,
  117725. + gcmSIZEOF(database->vidMem));
  117726. + break;
  117727. +
  117728. + case gcvDB_IDLE:
  117729. + Info->time = Kernel->db->idleTime;
  117730. + Kernel->db->idleTime = 0;
  117731. + break;
  117732. +
  117733. + case gcvDB_MAP_MEMORY:
  117734. + gckOS_MemCopy(&Info->counters,
  117735. + &database->mapMemory,
  117736. + gcmSIZEOF(database->mapMemory));
  117737. + break;
  117738. +
  117739. + case gcvDB_MAP_USER_MEMORY:
  117740. + gckOS_MemCopy(&Info->counters,
  117741. + &database->mapUserMemory,
  117742. + gcmSIZEOF(database->mapUserMemory));
  117743. + break;
  117744. +
  117745. + case gcvDB_VIDEO_MEMORY_RESERVED:
  117746. + gckOS_MemCopy(&Info->counters,
  117747. + &database->vidMemResv,
  117748. + gcmSIZEOF(database->vidMemResv));
  117749. + break;
  117750. +
  117751. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  117752. + gckOS_MemCopy(&Info->counters,
  117753. + &database->vidMemCont,
  117754. + gcmSIZEOF(database->vidMemCont));
  117755. + break;
  117756. +
  117757. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  117758. + gckOS_MemCopy(&Info->counters,
  117759. + &database->vidMemVirt,
  117760. + gcmSIZEOF(database->vidMemVirt));
  117761. + break;
  117762. +
  117763. + default:
  117764. + break;
  117765. + }
  117766. +
  117767. + /* Success. */
  117768. + gcmkFOOTER_NO();
  117769. + return gcvSTATUS_OK;
  117770. +
  117771. +OnError:
  117772. + /* Return the status. */
  117773. + gcmkFOOTER();
  117774. + return status;
  117775. +}
  117776. +
  117777. +#if gcdSECURE_USER
  117778. +/*******************************************************************************
  117779. +** gckKERNEL_GetProcessDBCache
  117780. +**
  117781. +** Get teh secure cache from a process database.
  117782. +**
  117783. +** INPUT:
  117784. +**
  117785. +** gckKERNEL Kernel
  117786. +** Pointer to a gckKERNEL object.
  117787. +**
  117788. +** gctUINT32 ProcessID
  117789. +** Process ID used to identify the database.
  117790. +**
  117791. +** OUTPUT:
  117792. +**
  117793. +** gcskSECURE_CACHE_PTR * Cache
  117794. +** Pointer to a variable that receives the secure cache pointer.
  117795. +*/
  117796. +gceSTATUS
  117797. +gckKERNEL_GetProcessDBCache(
  117798. + IN gckKERNEL Kernel,
  117799. + IN gctUINT32 ProcessID,
  117800. + OUT gcskSECURE_CACHE_PTR * Cache
  117801. + )
  117802. +{
  117803. + gceSTATUS status;
  117804. + gcsDATABASE_PTR database;
  117805. +
  117806. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  117807. +
  117808. + /* Verify the arguments. */
  117809. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117810. + gcmkVERIFY_ARGUMENT(Cache != gcvNULL);
  117811. +
  117812. + /* Find the database. */
  117813. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  117814. +
  117815. + /* Return the pointer to the cache. */
  117816. + *Cache = &database->cache;
  117817. +
  117818. + /* Success. */
  117819. + gcmkFOOTER_ARG("*Cache=0x%x", *Cache);
  117820. + return gcvSTATUS_OK;
  117821. +
  117822. +OnError:
  117823. + /* Return the status. */
  117824. + gcmkFOOTER();
  117825. + return status;
  117826. +}
  117827. +#endif
  117828. +
  117829. +gceSTATUS
  117830. +gckKERNEL_DumpProcessDB(
  117831. + IN gckKERNEL Kernel
  117832. + )
  117833. +{
  117834. + gcsDATABASE_PTR database;
  117835. + gctINT i, pid;
  117836. + gctUINT8 name[24];
  117837. +
  117838. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  117839. +
  117840. + /* Acquire the database mutex. */
  117841. + gcmkVERIFY_OK(
  117842. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  117843. +
  117844. + gcmkPRINT("**************************\n");
  117845. + gcmkPRINT("*** PROCESS DB DUMP ***\n");
  117846. + gcmkPRINT("**************************\n");
  117847. +
  117848. + gcmkPRINT_N(8, "%-8s%s\n", "PID", "NAME");
  117849. + /* Walk the databases. */
  117850. + for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
  117851. + {
  117852. + for (database = Kernel->db->db[i];
  117853. + database != gcvNULL;
  117854. + database = database->next)
  117855. + {
  117856. + pid = database->processID;
  117857. +
  117858. + gcmkVERIFY_OK(gckOS_ZeroMemory(name, gcmSIZEOF(name)));
  117859. +
  117860. + gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));
  117861. +
  117862. + gcmkPRINT_N(8, "%-8d%s\n", pid, name);
  117863. + }
  117864. + }
  117865. +
  117866. + /* Release the database mutex. */
  117867. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  117868. +
  117869. + /* Success. */
  117870. + gcmkFOOTER_NO();
  117871. + return gcvSTATUS_OK;
  117872. +}
  117873. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c
  117874. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c 1969-12-31 18:00:00.000000000 -0600
  117875. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c 2014-12-08 00:31:53.464418001 -0600
  117876. @@ -0,0 +1,2559 @@
  117877. +/****************************************************************************
  117878. +*
  117879. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  117880. +*
  117881. +* This program is free software; you can redistribute it and/or modify
  117882. +* it under the terms of the GNU General Public License as published by
  117883. +* the Free Software Foundation; either version 2 of the license, or
  117884. +* (at your option) any later version.
  117885. +*
  117886. +* This program is distributed in the hope that it will be useful,
  117887. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  117888. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  117889. +* GNU General Public License for more details.
  117890. +*
  117891. +* You should have received a copy of the GNU General Public License
  117892. +* along with this program; if not write to the Free Software
  117893. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  117894. +*
  117895. +*****************************************************************************/
  117896. +
  117897. +
  117898. +#include "gc_hal_kernel_precomp.h"
  117899. +#include <gc_hal_kernel_debug.h>
  117900. +
  117901. +/******************************************************************************\
  117902. +******************************** Debug Variables *******************************
  117903. +\******************************************************************************/
  117904. +
  117905. +static gceSTATUS _lastError = gcvSTATUS_OK;
  117906. +static gctUINT32 _debugLevel = gcvLEVEL_ERROR;
  117907. +/*
  117908. +_debugZones config value
  117909. +Please Reference define in gc_hal_base.h
  117910. +*/
  117911. +static gctUINT32 _debugZones = gcvZONE_NONE;
  117912. +
  117913. +/******************************************************************************\
  117914. +********************************* Debug Switches *******************************
  117915. +\******************************************************************************/
  117916. +
  117917. +/*
  117918. + gcdBUFFERED_OUTPUT
  117919. +
  117920. + When set to non-zero, all output is collected into a buffer with the
  117921. + specified size. Once the buffer gets full, the debug buffer will be
  117922. + printed to the console. gcdBUFFERED_SIZE determines the size of the buffer.
  117923. +*/
  117924. +#define gcdBUFFERED_OUTPUT 0
  117925. +
  117926. +/*
  117927. + gcdBUFFERED_SIZE
  117928. +
  117929. + When set to non-zero, all output is collected into a buffer with the
  117930. + specified size. Once the buffer gets full, the debug buffer will be
  117931. + printed to the console.
  117932. +*/
  117933. +#define gcdBUFFERED_SIZE (1024 * 1024 * 2)
  117934. +
  117935. +/*
  117936. + gcdDMA_BUFFER_COUNT
  117937. +
  117938. + If greater then zero, the debugger will attempt to find the command buffer
  117939. + where DMA is currently executing and then print this buffer and
  117940. + (gcdDMA_BUFFER_COUNT - 1) buffers before the current one. If set to zero
  117941. + or the current buffer is not found, all buffers are printed.
  117942. +*/
  117943. +#define gcdDMA_BUFFER_COUNT 0
  117944. +
  117945. +/*
  117946. + gcdTHREAD_BUFFERS
  117947. +
  117948. + When greater then one, will accumulate messages from the specified number
  117949. + of threads in separate output buffers.
  117950. +*/
  117951. +#define gcdTHREAD_BUFFERS 1
  117952. +
  117953. +/*
  117954. + gcdENABLE_OVERFLOW
  117955. +
  117956. + When set to non-zero, and the output buffer gets full, instead of being
  117957. + printed, it will be allowed to overflow removing the oldest messages.
  117958. +*/
  117959. +#define gcdENABLE_OVERFLOW 1
  117960. +
  117961. +/*
  117962. + gcdSHOW_LINE_NUMBER
  117963. +
  117964. + When enabledm each print statement will be preceeded with the current
  117965. + line number.
  117966. +*/
  117967. +#define gcdSHOW_LINE_NUMBER 0
  117968. +
  117969. +/*
  117970. + gcdSHOW_PROCESS_ID
  117971. +
  117972. + When enabledm each print statement will be preceeded with the current
  117973. + process ID.
  117974. +*/
  117975. +#define gcdSHOW_PROCESS_ID 0
  117976. +
  117977. +/*
  117978. + gcdSHOW_THREAD_ID
  117979. +
  117980. + When enabledm each print statement will be preceeded with the current
  117981. + thread ID.
  117982. +*/
  117983. +#define gcdSHOW_THREAD_ID 0
  117984. +
  117985. +/*
  117986. + gcdSHOW_TIME
  117987. +
  117988. + When enabled each print statement will be preceeded with the current
  117989. + high-resolution time.
  117990. +*/
  117991. +#define gcdSHOW_TIME 0
  117992. +
  117993. +
  117994. +/******************************************************************************\
  117995. +****************************** Miscellaneous Macros ****************************
  117996. +\******************************************************************************/
  117997. +
  117998. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  117999. +# define gcmDBGASSERT(Expression, Format, Value) \
  118000. + if (!(Expression)) \
  118001. + { \
  118002. + _DirectPrint( \
  118003. + "*** gcmDBGASSERT ***************************\n" \
  118004. + " function : %s\n" \
  118005. + " line : %d\n" \
  118006. + " expression : " #Expression "\n" \
  118007. + " actual value : " Format "\n", \
  118008. + __FUNCTION__, __LINE__, Value \
  118009. + ); \
  118010. + }
  118011. +#else
  118012. +# define gcmDBGASSERT(Expression, Format, Value)
  118013. +#endif
  118014. +
  118015. +#define gcmPTRALIGNMENT(Pointer, Alignemnt) \
  118016. +( \
  118017. + gcmALIGN(gcmPTR2INT(Pointer), Alignemnt) - gcmPTR2INT(Pointer) \
  118018. +)
  118019. +
  118020. +#if gcdALIGNBYSIZE
  118021. +# define gcmISALIGNED(Offset, Alignment) \
  118022. + (((Offset) & ((Alignment) - 1)) == 0)
  118023. +
  118024. +# define gcmkALIGNPTR(Type, Pointer, Alignment) \
  118025. + Pointer = (Type) gcmINT2PTR(gcmALIGN(gcmPTR2INT(Pointer), Alignment))
  118026. +#else
  118027. +# define gcmISALIGNED(Offset, Alignment) \
  118028. + gcvTRUE
  118029. +
  118030. +# define gcmkALIGNPTR(Type, Pointer, Alignment)
  118031. +#endif
  118032. +
  118033. +#define gcmALIGNSIZE(Offset, Size) \
  118034. + ((Size - Offset) + Size)
  118035. +
  118036. +#define gcdHAVEPREFIX \
  118037. +( \
  118038. + gcdSHOW_TIME \
  118039. + || gcdSHOW_LINE_NUMBER \
  118040. + || gcdSHOW_PROCESS_ID \
  118041. + || gcdSHOW_THREAD_ID \
  118042. +)
  118043. +
  118044. +#if gcdHAVEPREFIX
  118045. +
  118046. +# define gcdOFFSET 0
  118047. +
  118048. +#if gcdSHOW_TIME
  118049. +#if gcmISALIGNED(gcdOFFSET, 8)
  118050. +# define gcdTIMESIZE gcmSIZEOF(gctUINT64)
  118051. +# elif gcdOFFSET == 4
  118052. +# define gcdTIMESIZE gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
  118053. +# else
  118054. +# error "Unexpected offset value."
  118055. +# endif
  118056. +# undef gcdOFFSET
  118057. +# define gcdOFFSET 8
  118058. +#if !defined(gcdPREFIX_LEADER)
  118059. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT64)
  118060. +# define gcdTIMEFORMAT "0x%016llX"
  118061. +# else
  118062. +# define gcdTIMEFORMAT ", 0x%016llX"
  118063. +# endif
  118064. +# else
  118065. +# define gcdTIMESIZE 0
  118066. +# define gcdTIMEFORMAT
  118067. +# endif
  118068. +
  118069. +#if gcdSHOW_LINE_NUMBER
  118070. +#if gcmISALIGNED(gcdOFFSET, 8)
  118071. +# define gcdNUMSIZE gcmSIZEOF(gctUINT64)
  118072. +# elif gcdOFFSET == 4
  118073. +# define gcdNUMSIZE gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
  118074. +# else
  118075. +# error "Unexpected offset value."
  118076. +# endif
  118077. +# undef gcdOFFSET
  118078. +# define gcdOFFSET 8
  118079. +#if !defined(gcdPREFIX_LEADER)
  118080. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT64)
  118081. +# define gcdNUMFORMAT "%8llu"
  118082. +# else
  118083. +# define gcdNUMFORMAT ", %8llu"
  118084. +# endif
  118085. +# else
  118086. +# define gcdNUMSIZE 0
  118087. +# define gcdNUMFORMAT
  118088. +# endif
  118089. +
  118090. +#if gcdSHOW_PROCESS_ID
  118091. +#if gcmISALIGNED(gcdOFFSET, 4)
  118092. +# define gcdPIDSIZE gcmSIZEOF(gctUINT32)
  118093. +# else
  118094. +# error "Unexpected offset value."
  118095. +# endif
  118096. +# undef gcdOFFSET
  118097. +# define gcdOFFSET 4
  118098. +#if !defined(gcdPREFIX_LEADER)
  118099. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
  118100. +# define gcdPIDFORMAT "pid=%5d"
  118101. +# else
  118102. +# define gcdPIDFORMAT ", pid=%5d"
  118103. +# endif
  118104. +# else
  118105. +# define gcdPIDSIZE 0
  118106. +# define gcdPIDFORMAT
  118107. +# endif
  118108. +
  118109. +#if gcdSHOW_THREAD_ID
  118110. +#if gcmISALIGNED(gcdOFFSET, 4)
  118111. +# define gcdTIDSIZE gcmSIZEOF(gctUINT32)
  118112. +# else
  118113. +# error "Unexpected offset value."
  118114. +# endif
  118115. +# undef gcdOFFSET
  118116. +# define gcdOFFSET 4
  118117. +#if !defined(gcdPREFIX_LEADER)
  118118. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
  118119. +# define gcdTIDFORMAT "tid=%5d"
  118120. +# else
  118121. +# define gcdTIDFORMAT ", tid=%5d"
  118122. +# endif
  118123. +# else
  118124. +# define gcdTIDSIZE 0
  118125. +# define gcdTIDFORMAT
  118126. +# endif
  118127. +
  118128. +# define gcdPREFIX_SIZE \
  118129. + ( \
  118130. + gcdTIMESIZE \
  118131. + + gcdNUMSIZE \
  118132. + + gcdPIDSIZE \
  118133. + + gcdTIDSIZE \
  118134. + )
  118135. +
  118136. + static const char * _prefixFormat =
  118137. + "["
  118138. + gcdTIMEFORMAT
  118139. + gcdNUMFORMAT
  118140. + gcdPIDFORMAT
  118141. + gcdTIDFORMAT
  118142. + "] ";
  118143. +
  118144. +#else
  118145. +
  118146. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
  118147. +# define gcdPREFIX_SIZE 0
  118148. +
  118149. +#endif
  118150. +
  118151. +/* Assumed largest variable argument leader size. */
  118152. +#define gcdVARARG_LEADER gcmSIZEOF(gctUINT64)
  118153. +
  118154. +/* Alignnments. */
  118155. +#if gcdALIGNBYSIZE
  118156. +# define gcdPREFIX_ALIGNMENT gcdPREFIX_LEADER
  118157. +# define gcdVARARG_ALIGNMENT gcdVARARG_LEADER
  118158. +#else
  118159. +# define gcdPREFIX_ALIGNMENT 0
  118160. +# define gcdVARARG_ALIGNMENT 0
  118161. +#endif
  118162. +
  118163. +#if gcdBUFFERED_OUTPUT
  118164. +# define gcdOUTPUTPREFIX _AppendPrefix
  118165. +# define gcdOUTPUTSTRING _AppendString
  118166. +# define gcdOUTPUTCOPY _AppendCopy
  118167. +# define gcdOUTPUTBUFFER _AppendBuffer
  118168. +#else
  118169. +# define gcdOUTPUTPREFIX _PrintPrefix
  118170. +# define gcdOUTPUTSTRING _PrintString
  118171. +# define gcdOUTPUTCOPY _PrintString
  118172. +# define gcdOUTPUTBUFFER _PrintBuffer
  118173. +#endif
  118174. +
  118175. +/******************************************************************************\
  118176. +****************************** Private Structures ******************************
  118177. +\******************************************************************************/
  118178. +
  118179. +typedef enum _gceBUFITEM
  118180. +{
  118181. + gceBUFITEM_NONE,
  118182. + gcvBUFITEM_PREFIX,
  118183. + gcvBUFITEM_STRING,
  118184. + gcvBUFITEM_COPY,
  118185. + gcvBUFITEM_BUFFER
  118186. +}
  118187. +gceBUFITEM;
  118188. +
  118189. +/* Common item head/buffer terminator. */
  118190. +typedef struct _gcsBUFITEM_HEAD * gcsBUFITEM_HEAD_PTR;
  118191. +typedef struct _gcsBUFITEM_HEAD
  118192. +{
  118193. + gceBUFITEM type;
  118194. +}
  118195. +gcsBUFITEM_HEAD;
  118196. +
  118197. +/* String prefix (for ex. [ 1,tid=0x019A]) */
  118198. +typedef struct _gcsBUFITEM_PREFIX * gcsBUFITEM_PREFIX_PTR;
  118199. +typedef struct _gcsBUFITEM_PREFIX
  118200. +{
  118201. + gceBUFITEM type;
  118202. +#if gcdHAVEPREFIX
  118203. + gctPOINTER prefixData;
  118204. +#endif
  118205. +}
  118206. +gcsBUFITEM_PREFIX;
  118207. +
  118208. +/* Buffered string. */
  118209. +typedef struct _gcsBUFITEM_STRING * gcsBUFITEM_STRING_PTR;
  118210. +typedef struct _gcsBUFITEM_STRING
  118211. +{
  118212. + gceBUFITEM type;
  118213. + gctINT indent;
  118214. + gctCONST_STRING message;
  118215. + gctPOINTER messageData;
  118216. + gctUINT messageDataSize;
  118217. +}
  118218. +gcsBUFITEM_STRING;
  118219. +
  118220. +/* Buffered string (copy of the string is included with the record). */
  118221. +typedef struct _gcsBUFITEM_COPY * gcsBUFITEM_COPY_PTR;
  118222. +typedef struct _gcsBUFITEM_COPY
  118223. +{
  118224. + gceBUFITEM type;
  118225. + gctINT indent;
  118226. + gctPOINTER messageData;
  118227. + gctUINT messageDataSize;
  118228. +}
  118229. +gcsBUFITEM_COPY;
  118230. +
  118231. +/* Memory buffer. */
  118232. +typedef struct _gcsBUFITEM_BUFFER * gcsBUFITEM_BUFFER_PTR;
  118233. +typedef struct _gcsBUFITEM_BUFFER
  118234. +{
  118235. + gceBUFITEM type;
  118236. + gctINT indent;
  118237. + gceDUMP_BUFFER bufferType;
  118238. +
  118239. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  118240. + gctUINT32 dmaAddress;
  118241. +#endif
  118242. +
  118243. + gctUINT dataSize;
  118244. + gctUINT32 address;
  118245. +#if gcdHAVEPREFIX
  118246. + gctPOINTER prefixData;
  118247. +#endif
  118248. +}
  118249. +gcsBUFITEM_BUFFER;
  118250. +
  118251. +typedef struct _gcsBUFFERED_OUTPUT * gcsBUFFERED_OUTPUT_PTR;
  118252. +typedef struct _gcsBUFFERED_OUTPUT
  118253. +{
  118254. +#if gcdTHREAD_BUFFERS > 1
  118255. + gctUINT32 threadID;
  118256. +#endif
  118257. +
  118258. +#if gcdSHOW_LINE_NUMBER
  118259. + gctUINT64 lineNumber;
  118260. +#endif
  118261. +
  118262. + gctINT indent;
  118263. +
  118264. +#if gcdBUFFERED_OUTPUT
  118265. + gctINT start;
  118266. + gctINT index;
  118267. + gctINT count;
  118268. + gctUINT8 buffer[gcdBUFFERED_SIZE];
  118269. +#endif
  118270. +
  118271. + gcsBUFFERED_OUTPUT_PTR prev;
  118272. + gcsBUFFERED_OUTPUT_PTR next;
  118273. +}
  118274. +gcsBUFFERED_OUTPUT;
  118275. +
  118276. +typedef gctUINT (* gcfPRINTSTRING) (
  118277. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118278. + IN gcsBUFITEM_HEAD_PTR Item
  118279. + );
  118280. +
  118281. +typedef gctINT (* gcfGETITEMSIZE) (
  118282. + IN gcsBUFITEM_HEAD_PTR Item
  118283. + );
  118284. +
  118285. +/******************************************************************************\
  118286. +******************************* Private Variables ******************************
  118287. +\******************************************************************************/
  118288. +
  118289. +static gcsBUFFERED_OUTPUT _outputBuffer[gcdTHREAD_BUFFERS];
  118290. +static gcsBUFFERED_OUTPUT_PTR _outputBufferHead = gcvNULL;
  118291. +static gcsBUFFERED_OUTPUT_PTR _outputBufferTail = gcvNULL;
  118292. +
  118293. +/******************************************************************************\
  118294. +****************************** Item Size Functions *****************************
  118295. +\******************************************************************************/
  118296. +
  118297. +#if gcdBUFFERED_OUTPUT
  118298. +static gctINT
  118299. +_GetTerminatorItemSize(
  118300. + IN gcsBUFITEM_HEAD_PTR Item
  118301. + )
  118302. +{
  118303. + return gcmSIZEOF(gcsBUFITEM_HEAD);
  118304. +}
  118305. +
  118306. +static gctINT
  118307. +_GetPrefixItemSize(
  118308. + IN gcsBUFITEM_HEAD_PTR Item
  118309. + )
  118310. +{
  118311. +#if gcdHAVEPREFIX
  118312. + gcsBUFITEM_PREFIX_PTR item = (gcsBUFITEM_PREFIX_PTR) Item;
  118313. + gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  118314. + return vlen + gcdPREFIX_SIZE;
  118315. +#else
  118316. + return gcmSIZEOF(gcsBUFITEM_PREFIX);
  118317. +#endif
  118318. +}
  118319. +
  118320. +static gctINT
  118321. +_GetStringItemSize(
  118322. + IN gcsBUFITEM_HEAD_PTR Item
  118323. + )
  118324. +{
  118325. + gcsBUFITEM_STRING_PTR item = (gcsBUFITEM_STRING_PTR) Item;
  118326. + gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  118327. + return vlen + item->messageDataSize;
  118328. +}
  118329. +
  118330. +static gctINT
  118331. +_GetCopyItemSize(
  118332. + IN gcsBUFITEM_HEAD_PTR Item
  118333. + )
  118334. +{
  118335. + gcsBUFITEM_COPY_PTR item = (gcsBUFITEM_COPY_PTR) Item;
  118336. + gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  118337. + return vlen + item->messageDataSize;
  118338. +}
  118339. +
  118340. +static gctINT
  118341. +_GetBufferItemSize(
  118342. + IN gcsBUFITEM_HEAD_PTR Item
  118343. + )
  118344. +{
  118345. +#if gcdHAVEPREFIX
  118346. + gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
  118347. + gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  118348. + return vlen + gcdPREFIX_SIZE + item->dataSize;
  118349. +#else
  118350. + gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
  118351. + return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
  118352. +#endif
  118353. +}
  118354. +
  118355. +static gcfGETITEMSIZE _itemSize[] =
  118356. +{
  118357. + _GetTerminatorItemSize,
  118358. + _GetPrefixItemSize,
  118359. + _GetStringItemSize,
  118360. + _GetCopyItemSize,
  118361. + _GetBufferItemSize
  118362. +};
  118363. +#endif
  118364. +
  118365. +/******************************************************************************\
  118366. +******************************* Printing Functions *****************************
  118367. +\******************************************************************************/
  118368. +
  118369. +#if gcdDEBUG || gcdBUFFERED_OUTPUT
  118370. +static void
  118371. +_DirectPrint(
  118372. + gctCONST_STRING Message,
  118373. + ...
  118374. + )
  118375. +{
  118376. + gctINT len;
  118377. + char buffer[768];
  118378. + gctARGUMENTS arguments;
  118379. +
  118380. + gcmkARGUMENTS_START(arguments, Message);
  118381. + len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), Message, arguments);
  118382. + gcmkARGUMENTS_END(arguments);
  118383. +
  118384. + buffer[len] = '\0';
  118385. + gcmkOUTPUT_STRING(buffer);
  118386. +}
  118387. +#endif
  118388. +
  118389. +static int
  118390. +_AppendIndent(
  118391. + IN gctINT Indent,
  118392. + IN char * Buffer,
  118393. + IN int BufferSize
  118394. + )
  118395. +{
  118396. + gctINT i;
  118397. +
  118398. + gctINT len = 0;
  118399. + gctINT indent = Indent % 40;
  118400. +
  118401. + for (i = 0; i < indent; i += 1)
  118402. + {
  118403. + Buffer[len++] = ' ';
  118404. + }
  118405. +
  118406. + if (indent != Indent)
  118407. + {
  118408. + len += gcmkSPRINTF(
  118409. + Buffer + len, BufferSize - len, " <%d> ", Indent
  118410. + );
  118411. +
  118412. + Buffer[len] = '\0';
  118413. + }
  118414. +
  118415. + return len;
  118416. +}
  118417. +
  118418. +#if gcdHAVEPREFIX
  118419. +static void
  118420. +_PrintPrefix(
  118421. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118422. + IN gctPOINTER Data
  118423. + )
  118424. +{
  118425. + char buffer[768];
  118426. + gctINT len;
  118427. +
  118428. + /* Format the string. */
  118429. + len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, Data);
  118430. + buffer[len] = '\0';
  118431. +
  118432. + /* Print the string. */
  118433. + gcmkOUTPUT_STRING(buffer);
  118434. +}
  118435. +#endif
  118436. +
  118437. +static void
  118438. +_PrintString(
  118439. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118440. + IN gctINT Indent,
  118441. + IN gctCONST_STRING Message,
  118442. + IN gctUINT ArgumentSize,
  118443. + IN gctPOINTER Data
  118444. + )
  118445. +{
  118446. + char buffer[768];
  118447. + gctINT len;
  118448. +
  118449. + /* Append the indent string. */
  118450. + len = _AppendIndent(Indent, buffer, gcmSIZEOF(buffer));
  118451. +
  118452. + /* Format the string. */
  118453. + len += gcmkVSPRINTF(buffer + len, gcmSIZEOF(buffer) - len, Message, Data);
  118454. + buffer[len] = '\0';
  118455. +
  118456. + /* Add end-of-line if missing. */
  118457. + if (buffer[len - 1] != '\n')
  118458. + {
  118459. + buffer[len++] = '\n';
  118460. + buffer[len] = '\0';
  118461. + }
  118462. +
  118463. + /* Print the string. */
  118464. + gcmkOUTPUT_STRING(buffer);
  118465. +}
  118466. +
  118467. +static void
  118468. +_PrintBuffer(
  118469. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118470. + IN gctINT Indent,
  118471. + IN gctPOINTER PrefixData,
  118472. + IN gctPOINTER Data,
  118473. + IN gctUINT Address,
  118474. + IN gctUINT DataSize,
  118475. + IN gceDUMP_BUFFER Type,
  118476. + IN gctUINT32 DmaAddress
  118477. + )
  118478. +{
  118479. + static gctCONST_STRING _titleString[] =
  118480. + {
  118481. + "CONTEXT BUFFER",
  118482. + "USER COMMAND BUFFER",
  118483. + "KERNEL COMMAND BUFFER",
  118484. + "LINK BUFFER",
  118485. + "WAIT LINK BUFFER",
  118486. + ""
  118487. + };
  118488. +
  118489. + static const gctINT COLUMN_COUNT = 8;
  118490. +
  118491. + gctUINT i, count, column, address;
  118492. + gctUINT32_PTR data;
  118493. + gctCHAR buffer[768];
  118494. + gctUINT indent, len;
  118495. + gctBOOL command;
  118496. +
  118497. + /* Append space for the prefix. */
  118498. +#if gcdHAVEPREFIX
  118499. + indent = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, PrefixData);
  118500. + buffer[indent] = '\0';
  118501. +#else
  118502. + indent = 0;
  118503. +#endif
  118504. +
  118505. + /* Append the indent string. */
  118506. + indent += _AppendIndent(
  118507. + Indent, buffer + indent, gcmSIZEOF(buffer) - indent
  118508. + );
  118509. +
  118510. + switch (Type)
  118511. + {
  118512. + case gceDUMP_BUFFER_CONTEXT:
  118513. + case gceDUMP_BUFFER_USER:
  118514. + case gceDUMP_BUFFER_KERNEL:
  118515. + case gceDUMP_BUFFER_LINK:
  118516. + case gceDUMP_BUFFER_WAITLINK:
  118517. + /* Form and print the title string. */
  118518. + gcmkSPRINTF2(
  118519. + buffer + indent, gcmSIZEOF(buffer) - indent,
  118520. + "%s%s\n", _titleString[Type],
  118521. + ((DmaAddress >= Address) && (DmaAddress < Address + DataSize))
  118522. + ? " (CURRENT)" : ""
  118523. + );
  118524. +
  118525. + gcmkOUTPUT_STRING(buffer);
  118526. +
  118527. + /* Terminate the string. */
  118528. + buffer[indent] = '\0';
  118529. +
  118530. + /* This is a command buffer. */
  118531. + command = gcvTRUE;
  118532. + break;
  118533. +
  118534. + case gceDUMP_BUFFER_FROM_USER:
  118535. + /* This is not a command buffer. */
  118536. + command = gcvFALSE;
  118537. +
  118538. + /* No title. */
  118539. + break;
  118540. +
  118541. + default:
  118542. + gcmDBGASSERT(gcvFALSE, "%s", "invalid buffer type");
  118543. +
  118544. + /* This is not a command buffer. */
  118545. + command = gcvFALSE;
  118546. + }
  118547. +
  118548. + /* Overwrite the prefix with spaces. */
  118549. + for (i = 0; i < indent; i += 1)
  118550. + {
  118551. + buffer[i] = ' ';
  118552. + }
  118553. +
  118554. + /* Form and print the opening string. */
  118555. + if (command)
  118556. + {
  118557. + gcmkSPRINTF2(
  118558. + buffer + indent, gcmSIZEOF(buffer) - indent,
  118559. + "@[kernel.command %08X %08X\n", Address, DataSize
  118560. + );
  118561. +
  118562. + gcmkOUTPUT_STRING(buffer);
  118563. +
  118564. + /* Terminate the string. */
  118565. + buffer[indent] = '\0';
  118566. + }
  118567. +
  118568. + /* Get initial address. */
  118569. + address = Address;
  118570. +
  118571. + /* Cast the data pointer. */
  118572. + data = (gctUINT32_PTR) Data;
  118573. +
  118574. + /* Compute the number of double words. */
  118575. + count = DataSize / gcmSIZEOF(gctUINT32);
  118576. +
  118577. + /* Print the buffer. */
  118578. + for (i = 0, len = indent, column = 0; i < count; i += 1)
  118579. + {
  118580. + /* Append the address. */
  118581. + if (column == 0)
  118582. + {
  118583. + len += gcmkSPRINTF(
  118584. + buffer + len, gcmSIZEOF(buffer) - len, "0x%08X:", address
  118585. + );
  118586. + }
  118587. +
  118588. + /* Append the data value. */
  118589. + len += gcmkSPRINTF2(
  118590. + buffer + len, gcmSIZEOF(buffer) - len, "%c%08X",
  118591. + (address == DmaAddress)? '>' : ' ', data[i]
  118592. + );
  118593. +
  118594. + buffer[len] = '\0';
  118595. +
  118596. + /* Update the address. */
  118597. + address += gcmSIZEOF(gctUINT32);
  118598. +
  118599. + /* Advance column count. */
  118600. + column += 1;
  118601. +
  118602. + /* End of line? */
  118603. + if ((column % COLUMN_COUNT) == 0)
  118604. + {
  118605. + /* Append EOL. */
  118606. + gcmkSTRCAT(buffer + len, gcmSIZEOF(buffer) - len, "\n");
  118607. +
  118608. + /* Print the string. */
  118609. + gcmkOUTPUT_STRING(buffer);
  118610. +
  118611. + /* Reset. */
  118612. + len = indent;
  118613. + column = 0;
  118614. + }
  118615. + }
  118616. +
  118617. + /* Print the last partial string. */
  118618. + if (column != 0)
  118619. + {
  118620. + /* Append EOL. */
  118621. + gcmkSTRCAT(buffer + len, gcmSIZEOF(buffer) - len, "\n");
  118622. +
  118623. + /* Print the string. */
  118624. + gcmkOUTPUT_STRING(buffer);
  118625. + }
  118626. +
  118627. + /* Form and print the opening string. */
  118628. + if (command)
  118629. + {
  118630. + buffer[indent] = '\0';
  118631. + gcmkSTRCAT(buffer, gcmSIZEOF(buffer), "] -- command\n");
  118632. + gcmkOUTPUT_STRING(buffer);
  118633. + }
  118634. +}
  118635. +
  118636. +#if gcdBUFFERED_OUTPUT
  118637. +static gctUINT
  118638. +_PrintNone(
  118639. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118640. + IN gcsBUFITEM_HEAD_PTR Item
  118641. + )
  118642. +{
  118643. + /* Return the size of the node. */
  118644. + return gcmSIZEOF(gcsBUFITEM_HEAD);
  118645. +}
  118646. +
  118647. +static gctUINT
  118648. +_PrintPrefixWrapper(
  118649. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118650. + IN gcsBUFITEM_HEAD_PTR Item
  118651. + )
  118652. +{
  118653. +#if gcdHAVEPREFIX
  118654. + gcsBUFITEM_PREFIX_PTR item;
  118655. + gctUINT vlen;
  118656. +
  118657. + /* Get access to the data. */
  118658. + item = (gcsBUFITEM_PREFIX_PTR) Item;
  118659. +
  118660. + /* Print the message. */
  118661. + _PrintPrefix(OutputBuffer, item->prefixData);
  118662. +
  118663. + /* Compute the size of the variable portion of the structure. */
  118664. + vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  118665. +
  118666. + /* Return the size of the node. */
  118667. + return vlen + gcdPREFIX_SIZE;
  118668. +#else
  118669. + return gcmSIZEOF(gcsBUFITEM_PREFIX);
  118670. +#endif
  118671. +}
  118672. +
  118673. +static gctUINT
  118674. +_PrintStringWrapper(
  118675. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118676. + IN gcsBUFITEM_HEAD_PTR Item
  118677. + )
  118678. +{
  118679. + gcsBUFITEM_STRING_PTR item;
  118680. + gctUINT vlen;
  118681. +
  118682. + /* Get access to the data. */
  118683. + item = (gcsBUFITEM_STRING_PTR) Item;
  118684. +
  118685. + /* Print the message. */
  118686. + _PrintString(
  118687. + OutputBuffer,
  118688. + item->indent, item->message, item->messageDataSize, item->messageData
  118689. + );
  118690. +
  118691. + /* Compute the size of the variable portion of the structure. */
  118692. + vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  118693. +
  118694. + /* Return the size of the node. */
  118695. + return vlen + item->messageDataSize;
  118696. +}
  118697. +
  118698. +static gctUINT
  118699. +_PrintCopyWrapper(
  118700. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118701. + IN gcsBUFITEM_HEAD_PTR Item
  118702. + )
  118703. +{
  118704. + gcsBUFITEM_COPY_PTR item;
  118705. + gctCONST_STRING message;
  118706. + gctUINT vlen;
  118707. +
  118708. + /* Get access to the data. */
  118709. + item = (gcsBUFITEM_COPY_PTR) Item;
  118710. +
  118711. + /* Determine the string pointer. */
  118712. + message = (gctCONST_STRING) (item + 1);
  118713. +
  118714. + /* Print the message. */
  118715. + _PrintString(
  118716. + OutputBuffer,
  118717. + item->indent, message, item->messageDataSize, item->messageData
  118718. + );
  118719. +
  118720. + /* Compute the size of the variable portion of the structure. */
  118721. + vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  118722. +
  118723. + /* Return the size of the node. */
  118724. + return vlen + item->messageDataSize;
  118725. +}
  118726. +
  118727. +static gctUINT
  118728. +_PrintBufferWrapper(
  118729. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  118730. + IN gcsBUFITEM_HEAD_PTR Item
  118731. + )
  118732. +{
  118733. +#if gcdHAVEPREFIX
  118734. + gctUINT32 dmaAddress;
  118735. + gcsBUFITEM_BUFFER_PTR item;
  118736. + gctPOINTER data;
  118737. + gctUINT vlen;
  118738. +
  118739. + /* Get access to the data. */
  118740. + item = (gcsBUFITEM_BUFFER_PTR) Item;
  118741. +
  118742. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  118743. + dmaAddress = item->dmaAddress;
  118744. +#else
  118745. + dmaAddress = 0xFFFFFFFF;
  118746. +#endif
  118747. +
  118748. + if (dmaAddress != 0)
  118749. + {
  118750. + /* Compute the data address. */
  118751. + data = ((gctUINT8_PTR) item->prefixData) + gcdPREFIX_SIZE;
  118752. +
  118753. + /* Print buffer. */
  118754. + _PrintBuffer(
  118755. + OutputBuffer,
  118756. + item->indent, item->prefixData,
  118757. + data, item->address, item->dataSize,
  118758. + item->bufferType, dmaAddress
  118759. + );
  118760. + }
  118761. +
  118762. + /* Compute the size of the variable portion of the structure. */
  118763. + vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  118764. +
  118765. + /* Return the size of the node. */
  118766. + return vlen + gcdPREFIX_SIZE + item->dataSize;
  118767. +#else
  118768. + gctUINT32 dmaAddress;
  118769. + gcsBUFITEM_BUFFER_PTR item;
  118770. +
  118771. + /* Get access to the data. */
  118772. + item = (gcsBUFITEM_BUFFER_PTR) Item;
  118773. +
  118774. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  118775. + dmaAddress = item->dmaAddress;
  118776. +#else
  118777. + dmaAddress = 0xFFFFFFFF;
  118778. +#endif
  118779. +
  118780. + if (dmaAddress != 0)
  118781. + {
  118782. + /* Print buffer. */
  118783. + _PrintBuffer(
  118784. + OutputBuffer,
  118785. + item->indent, gcvNULL,
  118786. + item + 1, item->address, item->dataSize,
  118787. + item->bufferType, dmaAddress
  118788. + );
  118789. + }
  118790. +
  118791. + /* Return the size of the node. */
  118792. + return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
  118793. +#endif
  118794. +}
  118795. +
  118796. +static gcfPRINTSTRING _printArray[] =
  118797. +{
  118798. + _PrintNone,
  118799. + _PrintPrefixWrapper,
  118800. + _PrintStringWrapper,
  118801. + _PrintCopyWrapper,
  118802. + _PrintBufferWrapper
  118803. +};
  118804. +#endif
  118805. +
  118806. +/******************************************************************************\
  118807. +******************************* Private Functions ******************************
  118808. +\******************************************************************************/
  118809. +
  118810. +#if gcdBUFFERED_OUTPUT
  118811. +
  118812. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  118813. +static gcsBUFITEM_BUFFER_PTR
  118814. +_FindCurrentDMABuffer(
  118815. + gctUINT32 DmaAddress
  118816. + )
  118817. +{
  118818. + gctINT i, skip;
  118819. + gcsBUFITEM_HEAD_PTR item;
  118820. + gcsBUFITEM_BUFFER_PTR dmaCurrent;
  118821. +
  118822. + /* Reset the current buffer. */
  118823. + dmaCurrent = gcvNULL;
  118824. +
  118825. + /* Get the first stored item. */
  118826. + item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
  118827. +
  118828. + /* Run through all items. */
  118829. + for (i = 0; i < _outputBufferHead->count; i += 1)
  118830. + {
  118831. + /* Buffer item? */
  118832. + if (item->type == gcvBUFITEM_BUFFER)
  118833. + {
  118834. + gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
  118835. +
  118836. + if ((DmaAddress >= buffer->address) &&
  118837. + (DmaAddress < buffer->address + buffer->dataSize))
  118838. + {
  118839. + dmaCurrent = buffer;
  118840. + }
  118841. + }
  118842. +
  118843. + /* Get the item size and skip it. */
  118844. + skip = (* _itemSize[item->type]) (item);
  118845. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  118846. +
  118847. + /* End of the buffer? Wrap around. */
  118848. + if (item->type == gceBUFITEM_NONE)
  118849. + {
  118850. + item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
  118851. + }
  118852. + }
  118853. +
  118854. + /* Return result. */
  118855. + return dmaCurrent;
  118856. +}
  118857. +
  118858. +static void
  118859. +_EnableAllDMABuffers(
  118860. + void
  118861. + )
  118862. +{
  118863. + gctINT i, skip;
  118864. + gcsBUFITEM_HEAD_PTR item;
  118865. +
  118866. + /* Get the first stored item. */
  118867. + item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
  118868. +
  118869. + /* Run through all items. */
  118870. + for (i = 0; i < _outputBufferHead->count; i += 1)
  118871. + {
  118872. + /* Buffer item? */
  118873. + if (item->type == gcvBUFITEM_BUFFER)
  118874. + {
  118875. + gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
  118876. +
  118877. + /* Enable the buffer. */
  118878. + buffer->dmaAddress = ~0U;
  118879. + }
  118880. +
  118881. + /* Get the item size and skip it. */
  118882. + skip = (* _itemSize[item->type]) (item);
  118883. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  118884. +
  118885. + /* End of the buffer? Wrap around. */
  118886. + if (item->type == gceBUFITEM_NONE)
  118887. + {
  118888. + item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
  118889. + }
  118890. + }
  118891. +}
  118892. +
  118893. +static void
  118894. +_EnableDMABuffers(
  118895. + gctUINT32 DmaAddress,
  118896. + gcsBUFITEM_BUFFER_PTR CurrentDMABuffer
  118897. + )
  118898. +{
  118899. + gctINT i, skip, index;
  118900. + gcsBUFITEM_HEAD_PTR item;
  118901. + gcsBUFITEM_BUFFER_PTR buffers[gcdDMA_BUFFER_COUNT];
  118902. +
  118903. + /* Reset buffer pointers. */
  118904. + gckOS_ZeroMemory(buffers, gcmSIZEOF(buffers));
  118905. +
  118906. + /* Set the current buffer index. */
  118907. + index = -1;
  118908. +
  118909. + /* Get the first stored item. */
  118910. + item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
  118911. +
  118912. + /* Run through all items until the current DMA buffer is found. */
  118913. + for (i = 0; i < _outputBufferHead->count; i += 1)
  118914. + {
  118915. + /* Buffer item? */
  118916. + if (item->type == gcvBUFITEM_BUFFER)
  118917. + {
  118918. + /* Advance the index. */
  118919. + index = (index + 1) % gcdDMA_BUFFER_COUNT;
  118920. +
  118921. + /* Add to the buffer array. */
  118922. + buffers[index] = (gcsBUFITEM_BUFFER_PTR) item;
  118923. +
  118924. + /* Stop if this is the current DMA buffer. */
  118925. + if ((gcsBUFITEM_BUFFER_PTR) item == CurrentDMABuffer)
  118926. + {
  118927. + break;
  118928. + }
  118929. + }
  118930. +
  118931. + /* Get the item size and skip it. */
  118932. + skip = (* _itemSize[item->type]) (item);
  118933. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  118934. +
  118935. + /* End of the buffer? Wrap around. */
  118936. + if (item->type == gceBUFITEM_NONE)
  118937. + {
  118938. + item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
  118939. + }
  118940. + }
  118941. +
  118942. + /* Enable the found buffers. */
  118943. + gcmDBGASSERT(index != -1, "%d", index);
  118944. +
  118945. + for (i = 0; i < gcdDMA_BUFFER_COUNT; i += 1)
  118946. + {
  118947. + if (buffers[index] == gcvNULL)
  118948. + {
  118949. + break;
  118950. + }
  118951. +
  118952. + buffers[index]->dmaAddress = DmaAddress;
  118953. +
  118954. + index -= 1;
  118955. +
  118956. + if (index == -1)
  118957. + {
  118958. + index = gcdDMA_BUFFER_COUNT - 1;
  118959. + }
  118960. + }
  118961. +}
  118962. +#endif
  118963. +
  118964. +static void
  118965. +_Flush(
  118966. + gctUINT32 DmaAddress
  118967. + )
  118968. +{
  118969. + gctINT i, skip;
  118970. + gcsBUFITEM_HEAD_PTR item;
  118971. +
  118972. + gcsBUFFERED_OUTPUT_PTR outputBuffer = _outputBufferHead;
  118973. +
  118974. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  118975. + if ((outputBuffer != gcvNULL) && (outputBuffer->count != 0))
  118976. + {
  118977. + /* Find the current DMA buffer. */
  118978. + gcsBUFITEM_BUFFER_PTR dmaCurrent = _FindCurrentDMABuffer(DmaAddress);
  118979. +
  118980. + /* Was the current buffer found? */
  118981. + if (dmaCurrent == gcvNULL)
  118982. + {
  118983. + /* No, print all buffers. */
  118984. + _EnableAllDMABuffers();
  118985. + }
  118986. + else
  118987. + {
  118988. + /* Yes, enable only specified number of buffers. */
  118989. + _EnableDMABuffers(DmaAddress, dmaCurrent);
  118990. + }
  118991. + }
  118992. +#endif
  118993. +
  118994. + while (outputBuffer != gcvNULL)
  118995. + {
  118996. + if (outputBuffer->count != 0)
  118997. + {
  118998. + _DirectPrint("********************************************************************************\n");
  118999. + _DirectPrint("FLUSHING DEBUG OUTPUT BUFFER (%d elements).\n", outputBuffer->count);
  119000. + _DirectPrint("********************************************************************************\n");
  119001. +
  119002. + item = (gcsBUFITEM_HEAD_PTR) &outputBuffer->buffer[outputBuffer->start];
  119003. +
  119004. + for (i = 0; i < outputBuffer->count; i += 1)
  119005. + {
  119006. + skip = (* _printArray[item->type]) (outputBuffer, item);
  119007. +
  119008. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  119009. +
  119010. + if (item->type == gceBUFITEM_NONE)
  119011. + {
  119012. + item = (gcsBUFITEM_HEAD_PTR) outputBuffer->buffer;
  119013. + }
  119014. + }
  119015. +
  119016. + outputBuffer->start = 0;
  119017. + outputBuffer->index = 0;
  119018. + outputBuffer->count = 0;
  119019. + }
  119020. +
  119021. + outputBuffer = outputBuffer->next;
  119022. + }
  119023. +}
  119024. +
  119025. +static gcsBUFITEM_HEAD_PTR
  119026. +_AllocateItem(
  119027. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119028. + IN gctINT Size
  119029. + )
  119030. +{
  119031. + gctINT skip;
  119032. + gcsBUFITEM_HEAD_PTR item, next;
  119033. +
  119034. +#if gcdENABLE_OVERFLOW
  119035. + if (
  119036. + (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
  119037. + ||
  119038. + (
  119039. + (OutputBuffer->index < OutputBuffer->start) &&
  119040. + (OutputBuffer->index + Size >= OutputBuffer->start)
  119041. + )
  119042. + )
  119043. + {
  119044. + if (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
  119045. + {
  119046. + if (OutputBuffer->index < OutputBuffer->start)
  119047. + {
  119048. + item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
  119049. +
  119050. + while (item->type != gceBUFITEM_NONE)
  119051. + {
  119052. + skip = (* _itemSize[item->type]) (item);
  119053. +
  119054. + OutputBuffer->start += skip;
  119055. + OutputBuffer->count -= 1;
  119056. +
  119057. + item->type = gceBUFITEM_NONE;
  119058. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  119059. + }
  119060. +
  119061. + OutputBuffer->start = 0;
  119062. + }
  119063. +
  119064. + OutputBuffer->index = 0;
  119065. + }
  119066. +
  119067. + item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
  119068. +
  119069. + while (OutputBuffer->start - OutputBuffer->index <= Size)
  119070. + {
  119071. + skip = (* _itemSize[item->type]) (item);
  119072. +
  119073. + OutputBuffer->start += skip;
  119074. + OutputBuffer->count -= 1;
  119075. +
  119076. + item->type = gceBUFITEM_NONE;
  119077. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  119078. +
  119079. + if (item->type == gceBUFITEM_NONE)
  119080. + {
  119081. + OutputBuffer->start = 0;
  119082. + break;
  119083. + }
  119084. + }
  119085. + }
  119086. +#else
  119087. + if (OutputBuffer->index + Size > gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
  119088. + {
  119089. + _DirectPrint("\nMessage buffer full; forcing message flush.\n\n");
  119090. + _Flush(~0U);
  119091. + }
  119092. +#endif
  119093. +
  119094. + item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->index];
  119095. +
  119096. + OutputBuffer->index += Size;
  119097. + OutputBuffer->count += 1;
  119098. +
  119099. + next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + Size);
  119100. + next->type = gceBUFITEM_NONE;
  119101. +
  119102. + return item;
  119103. +}
  119104. +
  119105. +#if gcdALIGNBYSIZE
  119106. +static void
  119107. +_FreeExtraSpace(
  119108. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119109. + IN gctPOINTER Item,
  119110. + IN gctINT ItemSize,
  119111. + IN gctINT FreeSize
  119112. + )
  119113. +{
  119114. + gcsBUFITEM_HEAD_PTR next;
  119115. +
  119116. + OutputBuffer->index -= FreeSize;
  119117. +
  119118. + next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) Item + ItemSize);
  119119. + next->type = gceBUFITEM_NONE;
  119120. +}
  119121. +#endif
  119122. +
  119123. +#if gcdHAVEPREFIX
  119124. +static void
  119125. +_AppendPrefix(
  119126. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119127. + IN gctPOINTER Data
  119128. + )
  119129. +{
  119130. + gctUINT8_PTR prefixData;
  119131. + gcsBUFITEM_PREFIX_PTR item;
  119132. + gctINT allocSize;
  119133. +
  119134. +#if gcdALIGNBYSIZE
  119135. + gctUINT alignment;
  119136. + gctINT size, freeSize;
  119137. +#endif
  119138. +
  119139. + gcmDBGASSERT(Data != gcvNULL, "%p", Data);
  119140. +
  119141. + /* Determine the maximum item size. */
  119142. + allocSize
  119143. + = gcmSIZEOF(gcsBUFITEM_PREFIX)
  119144. + + gcdPREFIX_SIZE
  119145. + + gcdPREFIX_ALIGNMENT;
  119146. +
  119147. + /* Allocate prefix item. */
  119148. + item = (gcsBUFITEM_PREFIX_PTR) _AllocateItem(OutputBuffer, allocSize);
  119149. +
  119150. + /* Compute the initial prefix data pointer. */
  119151. + prefixData = (gctUINT8_PTR) (item + 1);
  119152. +
  119153. + /* Align the data pointer as necessary. */
  119154. +#if gcdALIGNBYSIZE
  119155. + alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
  119156. + prefixData += alignment;
  119157. +#endif
  119158. +
  119159. + /* Set item data. */
  119160. + item->type = gcvBUFITEM_PREFIX;
  119161. + item->prefixData = prefixData;
  119162. +
  119163. + /* Copy argument value. */
  119164. + memcpy(prefixData, Data, gcdPREFIX_SIZE);
  119165. +
  119166. +#if gcdALIGNBYSIZE
  119167. + /* Compute the actual node size. */
  119168. + size = gcmSIZEOF(gcsBUFITEM_PREFIX) + gcdPREFIX_SIZE + alignment;
  119169. +
  119170. + /* Free extra memory if any. */
  119171. + freeSize = allocSize - size;
  119172. + if (freeSize != 0)
  119173. + {
  119174. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  119175. + }
  119176. +#endif
  119177. +}
  119178. +#endif
  119179. +
  119180. +static void
  119181. +_AppendString(
  119182. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119183. + IN gctINT Indent,
  119184. + IN gctCONST_STRING Message,
  119185. + IN gctUINT ArgumentSize,
  119186. + IN gctPOINTER Data
  119187. + )
  119188. +{
  119189. + gctUINT8_PTR messageData;
  119190. + gcsBUFITEM_STRING_PTR item;
  119191. + gctINT allocSize;
  119192. +
  119193. +#if gcdALIGNBYSIZE
  119194. + gctUINT alignment;
  119195. + gctINT size, freeSize;
  119196. +#endif
  119197. +
  119198. + /* Determine the maximum item size. */
  119199. + allocSize
  119200. + = gcmSIZEOF(gcsBUFITEM_STRING)
  119201. + + ArgumentSize
  119202. + + gcdVARARG_ALIGNMENT;
  119203. +
  119204. + /* Allocate prefix item. */
  119205. + item = (gcsBUFITEM_STRING_PTR) _AllocateItem(OutputBuffer, allocSize);
  119206. +
  119207. + /* Compute the initial message data pointer. */
  119208. + messageData = (gctUINT8_PTR) (item + 1);
  119209. +
  119210. + /* Align the data pointer as necessary. */
  119211. +#if gcdALIGNBYSIZE
  119212. + alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
  119213. + messageData += alignment;
  119214. +#endif
  119215. +
  119216. + /* Set item data. */
  119217. + item->type = gcvBUFITEM_STRING;
  119218. + item->indent = Indent;
  119219. + item->message = Message;
  119220. + item->messageData = messageData;
  119221. + item->messageDataSize = ArgumentSize;
  119222. +
  119223. + /* Copy argument value. */
  119224. + if (ArgumentSize != 0)
  119225. + {
  119226. + memcpy(messageData, Data, ArgumentSize);
  119227. + }
  119228. +
  119229. +#if gcdALIGNBYSIZE
  119230. + /* Compute the actual node size. */
  119231. + size = gcmSIZEOF(gcsBUFITEM_STRING) + ArgumentSize + alignment;
  119232. +
  119233. + /* Free extra memory if any. */
  119234. + freeSize = allocSize - size;
  119235. + if (freeSize != 0)
  119236. + {
  119237. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  119238. + }
  119239. +#endif
  119240. +}
  119241. +
  119242. +static void
  119243. +_AppendCopy(
  119244. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119245. + IN gctINT Indent,
  119246. + IN gctCONST_STRING Message,
  119247. + IN gctUINT ArgumentSize,
  119248. + IN gctPOINTER Data
  119249. + )
  119250. +{
  119251. + gctUINT8_PTR messageData;
  119252. + gcsBUFITEM_COPY_PTR item;
  119253. + gctINT allocSize;
  119254. + gctINT messageLength;
  119255. + gctCONST_STRING message;
  119256. +
  119257. +#if gcdALIGNBYSIZE
  119258. + gctUINT alignment;
  119259. + gctINT size, freeSize;
  119260. +#endif
  119261. +
  119262. + /* Get the length of the string. */
  119263. + messageLength = strlen(Message) + 1;
  119264. +
  119265. + /* Determine the maximum item size. */
  119266. + allocSize
  119267. + = gcmSIZEOF(gcsBUFITEM_COPY)
  119268. + + messageLength
  119269. + + ArgumentSize
  119270. + + gcdVARARG_ALIGNMENT;
  119271. +
  119272. + /* Allocate prefix item. */
  119273. + item = (gcsBUFITEM_COPY_PTR) _AllocateItem(OutputBuffer, allocSize);
  119274. +
  119275. + /* Determine the message placement. */
  119276. + message = (gctCONST_STRING) (item + 1);
  119277. +
  119278. + /* Compute the initial message data pointer. */
  119279. + messageData = (gctUINT8_PTR) message + messageLength;
  119280. +
  119281. + /* Align the data pointer as necessary. */
  119282. +#if gcdALIGNBYSIZE
  119283. + if (ArgumentSize == 0)
  119284. + {
  119285. + alignment = 0;
  119286. + }
  119287. + else
  119288. + {
  119289. + alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
  119290. + messageData += alignment;
  119291. + }
  119292. +#endif
  119293. +
  119294. + /* Set item data. */
  119295. + item->type = gcvBUFITEM_COPY;
  119296. + item->indent = Indent;
  119297. + item->messageData = messageData;
  119298. + item->messageDataSize = ArgumentSize;
  119299. +
  119300. + /* Copy the message. */
  119301. + memcpy((gctPOINTER) message, Message, messageLength);
  119302. +
  119303. + /* Copy argument value. */
  119304. + if (ArgumentSize != 0)
  119305. + {
  119306. + memcpy(messageData, Data, ArgumentSize);
  119307. + }
  119308. +
  119309. +#if gcdALIGNBYSIZE
  119310. + /* Compute the actual node size. */
  119311. + size
  119312. + = gcmSIZEOF(gcsBUFITEM_COPY)
  119313. + + messageLength
  119314. + + ArgumentSize
  119315. + + alignment;
  119316. +
  119317. + /* Free extra memory if any. */
  119318. + freeSize = allocSize - size;
  119319. + if (freeSize != 0)
  119320. + {
  119321. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  119322. + }
  119323. +#endif
  119324. +}
  119325. +
  119326. +static void
  119327. +_AppendBuffer(
  119328. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119329. + IN gctINT Indent,
  119330. + IN gctPOINTER PrefixData,
  119331. + IN gctPOINTER Data,
  119332. + IN gctUINT Address,
  119333. + IN gctUINT DataSize,
  119334. + IN gceDUMP_BUFFER Type,
  119335. + IN gctUINT32 DmaAddress
  119336. + )
  119337. +{
  119338. +#if gcdHAVEPREFIX
  119339. + gctUINT8_PTR prefixData;
  119340. + gcsBUFITEM_BUFFER_PTR item;
  119341. + gctINT allocSize;
  119342. + gctPOINTER data;
  119343. +
  119344. +#if gcdALIGNBYSIZE
  119345. + gctUINT alignment;
  119346. + gctINT size, freeSize;
  119347. +#endif
  119348. +
  119349. + gcmDBGASSERT(DataSize != 0, "%d", DataSize);
  119350. + gcmDBGASSERT(Data != gcvNULL, "%p", Data);
  119351. +
  119352. + /* Determine the maximum item size. */
  119353. + allocSize
  119354. + = gcmSIZEOF(gcsBUFITEM_BUFFER)
  119355. + + gcdPREFIX_SIZE
  119356. + + gcdPREFIX_ALIGNMENT
  119357. + + DataSize;
  119358. +
  119359. + /* Allocate prefix item. */
  119360. + item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, allocSize);
  119361. +
  119362. + /* Compute the initial prefix data pointer. */
  119363. + prefixData = (gctUINT8_PTR) (item + 1);
  119364. +
  119365. +#if gcdALIGNBYSIZE
  119366. + /* Align the data pointer as necessary. */
  119367. + alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
  119368. + prefixData += alignment;
  119369. +#endif
  119370. +
  119371. + /* Set item data. */
  119372. + item->type = gcvBUFITEM_BUFFER;
  119373. + item->indent = Indent;
  119374. + item->bufferType = Type;
  119375. + item->dataSize = DataSize;
  119376. + item->address = Address;
  119377. + item->prefixData = prefixData;
  119378. +
  119379. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  119380. + item->dmaAddress = DmaAddress;
  119381. +#endif
  119382. +
  119383. + /* Copy prefix data. */
  119384. + memcpy(prefixData, PrefixData, gcdPREFIX_SIZE);
  119385. +
  119386. + /* Compute the data pointer. */
  119387. + data = prefixData + gcdPREFIX_SIZE;
  119388. +
  119389. + /* Copy argument value. */
  119390. + memcpy(data, Data, DataSize);
  119391. +
  119392. +#if gcdALIGNBYSIZE
  119393. + /* Compute the actual node size. */
  119394. + size
  119395. + = gcmSIZEOF(gcsBUFITEM_BUFFER)
  119396. + + gcdPREFIX_SIZE
  119397. + + alignment
  119398. + + DataSize;
  119399. +
  119400. + /* Free extra memory if any. */
  119401. + freeSize = allocSize - size;
  119402. + if (freeSize != 0)
  119403. + {
  119404. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  119405. + }
  119406. +#endif
  119407. +#else
  119408. + gcsBUFITEM_BUFFER_PTR item;
  119409. + gctINT size;
  119410. +
  119411. + gcmDBGASSERT(DataSize != 0, "%d", DataSize);
  119412. + gcmDBGASSERT(Data != gcvNULL, "%p", Data);
  119413. +
  119414. + /* Determine the maximum item size. */
  119415. + size = gcmSIZEOF(gcsBUFITEM_BUFFER) + DataSize;
  119416. +
  119417. + /* Allocate prefix item. */
  119418. + item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, size);
  119419. +
  119420. + /* Set item data. */
  119421. + item->type = gcvBUFITEM_BUFFER;
  119422. + item->indent = Indent;
  119423. + item->dataSize = DataSize;
  119424. + item->address = Address;
  119425. +
  119426. + /* Copy argument value. */
  119427. + memcpy(item + 1, Data, DataSize);
  119428. +#endif
  119429. +}
  119430. +#endif
  119431. +
  119432. +static gcmINLINE void
  119433. +_InitBuffers(
  119434. + void
  119435. + )
  119436. +{
  119437. + int i;
  119438. +
  119439. + if (_outputBufferHead == gcvNULL)
  119440. + {
  119441. + for (i = 0; i < gcdTHREAD_BUFFERS; i += 1)
  119442. + {
  119443. + if (_outputBufferTail == gcvNULL)
  119444. + {
  119445. + _outputBufferHead = &_outputBuffer[i];
  119446. + }
  119447. + else
  119448. + {
  119449. + _outputBufferTail->next = &_outputBuffer[i];
  119450. + }
  119451. +
  119452. +#if gcdTHREAD_BUFFERS > 1
  119453. + _outputBuffer[i].threadID = ~0U;
  119454. +#endif
  119455. +
  119456. + _outputBuffer[i].prev = _outputBufferTail;
  119457. + _outputBuffer[i].next = gcvNULL;
  119458. +
  119459. + _outputBufferTail = &_outputBuffer[i];
  119460. + }
  119461. + }
  119462. +}
  119463. +
  119464. +static gcmINLINE gcsBUFFERED_OUTPUT_PTR
  119465. +_GetOutputBuffer(
  119466. + void
  119467. + )
  119468. +{
  119469. + gcsBUFFERED_OUTPUT_PTR outputBuffer;
  119470. +
  119471. +#if gcdTHREAD_BUFFERS > 1
  119472. + /* Get the current thread ID. */
  119473. + gctUINT32 ThreadID = gcmkGETTHREADID();
  119474. +
  119475. + /* Locate the output buffer for the thread. */
  119476. + outputBuffer = _outputBufferHead;
  119477. +
  119478. + while (outputBuffer != gcvNULL)
  119479. + {
  119480. + if (outputBuffer->threadID == ThreadID)
  119481. + {
  119482. + break;
  119483. + }
  119484. +
  119485. + outputBuffer = outputBuffer->next;
  119486. + }
  119487. +
  119488. + /* No matching buffer found? */
  119489. + if (outputBuffer == gcvNULL)
  119490. + {
  119491. + /* Get the tail for the buffer. */
  119492. + outputBuffer = _outputBufferTail;
  119493. +
  119494. + /* Move it to the head. */
  119495. + _outputBufferTail = _outputBufferTail->prev;
  119496. + _outputBufferTail->next = gcvNULL;
  119497. +
  119498. + outputBuffer->prev = gcvNULL;
  119499. + outputBuffer->next = _outputBufferHead;
  119500. +
  119501. + _outputBufferHead->prev = outputBuffer;
  119502. + _outputBufferHead = outputBuffer;
  119503. +
  119504. + /* Reset the buffer. */
  119505. + outputBuffer->threadID = ThreadID;
  119506. +#if gcdBUFFERED_OUTPUT
  119507. + outputBuffer->start = 0;
  119508. + outputBuffer->index = 0;
  119509. + outputBuffer->count = 0;
  119510. +#endif
  119511. +#if gcdSHOW_LINE_NUMBER
  119512. + outputBuffer->lineNumber = 0;
  119513. +#endif
  119514. + }
  119515. +#else
  119516. + outputBuffer = _outputBufferHead;
  119517. +#endif
  119518. +
  119519. + return outputBuffer;
  119520. +}
  119521. +
  119522. +static gcmINLINE int _GetArgumentSize(
  119523. + IN gctCONST_STRING Message
  119524. + )
  119525. +{
  119526. + int i, count;
  119527. +
  119528. + gcmDBGASSERT(Message != gcvNULL, "%p", Message);
  119529. +
  119530. + for (i = 0, count = 0; Message[i]; i += 1)
  119531. + {
  119532. + if (Message[i] == '%')
  119533. + {
  119534. + count += 1;
  119535. + }
  119536. + }
  119537. +
  119538. + return count * gcmSIZEOF(gctUINT32);
  119539. +}
  119540. +
  119541. +#if gcdHAVEPREFIX
  119542. +static void
  119543. +_InitPrefixData(
  119544. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  119545. + IN gctPOINTER Data
  119546. + )
  119547. +{
  119548. + gctUINT8_PTR data = (gctUINT8_PTR) Data;
  119549. +
  119550. +#if gcdSHOW_TIME
  119551. + {
  119552. + gctUINT64 time;
  119553. + gckOS_GetProfileTick(&time);
  119554. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
  119555. + * ((gctUINT64_PTR) data) = time;
  119556. + data += gcmSIZEOF(gctUINT64);
  119557. + }
  119558. +#endif
  119559. +
  119560. +#if gcdSHOW_LINE_NUMBER
  119561. + {
  119562. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
  119563. + * ((gctUINT64_PTR) data) = OutputBuffer->lineNumber;
  119564. + data += gcmSIZEOF(gctUINT64);
  119565. + }
  119566. +#endif
  119567. +
  119568. +#if gcdSHOW_PROCESS_ID
  119569. + {
  119570. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
  119571. + * ((gctUINT32_PTR) data) = gcmkGETPROCESSID();
  119572. + data += gcmSIZEOF(gctUINT32);
  119573. + }
  119574. +#endif
  119575. +
  119576. +#if gcdSHOW_THREAD_ID
  119577. + {
  119578. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
  119579. + * ((gctUINT32_PTR) data) = gcmkGETTHREADID();
  119580. + }
  119581. +#endif
  119582. +}
  119583. +#endif
  119584. +
  119585. +static void
  119586. +_Print(
  119587. + IN gctUINT ArgumentSize,
  119588. + IN gctBOOL CopyMessage,
  119589. + IN gctCONST_STRING Message,
  119590. + IN gctARGUMENTS Arguments
  119591. + )
  119592. +{
  119593. + gcsBUFFERED_OUTPUT_PTR outputBuffer;
  119594. + gcmkDECLARE_LOCK(lockHandle);
  119595. +
  119596. + gcmkLOCKSECTION(lockHandle);
  119597. +
  119598. + /* Initialize output buffer list. */
  119599. + _InitBuffers();
  119600. +
  119601. + /* Locate the proper output buffer. */
  119602. + outputBuffer = _GetOutputBuffer();
  119603. +
  119604. + /* Update the line number. */
  119605. +#if gcdSHOW_LINE_NUMBER
  119606. + outputBuffer->lineNumber += 1;
  119607. +#endif
  119608. +
  119609. + /* Print prefix. */
  119610. +#if gcdHAVEPREFIX
  119611. + {
  119612. + gctUINT8_PTR alignedPrefixData;
  119613. + gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
  119614. +
  119615. + /* Compute aligned pointer. */
  119616. + alignedPrefixData = prefixData;
  119617. + gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
  119618. +
  119619. + /* Initialize the prefix data. */
  119620. + _InitPrefixData(outputBuffer, alignedPrefixData);
  119621. +
  119622. + /* Print the prefix. */
  119623. + gcdOUTPUTPREFIX(outputBuffer, alignedPrefixData);
  119624. + }
  119625. +#endif
  119626. +
  119627. + /* Form the indent string. */
  119628. + if (strncmp(Message, "--", 2) == 0)
  119629. + {
  119630. + outputBuffer->indent -= 2;
  119631. + }
  119632. +
  119633. + /* Print the message. */
  119634. + if (CopyMessage)
  119635. + {
  119636. + gcdOUTPUTCOPY(
  119637. + outputBuffer, outputBuffer->indent,
  119638. + Message, ArgumentSize, * (gctPOINTER *) &Arguments
  119639. + );
  119640. + }
  119641. + else
  119642. + {
  119643. + gcdOUTPUTSTRING(
  119644. + outputBuffer, outputBuffer->indent,
  119645. + Message, ArgumentSize, * (gctPOINTER *) &Arguments
  119646. + );
  119647. + }
  119648. +
  119649. + /* Check increasing indent. */
  119650. + if (strncmp(Message, "++", 2) == 0)
  119651. + {
  119652. + outputBuffer->indent += 2;
  119653. + }
  119654. +
  119655. + gcmkUNLOCKSECTION(lockHandle);
  119656. +}
  119657. +
  119658. +
  119659. +/******************************************************************************\
  119660. +********************************* Debug Macros *********************************
  119661. +\******************************************************************************/
  119662. +
  119663. +#ifdef __QNXNTO__
  119664. +
  119665. +extern volatile unsigned g_nQnxInIsrs;
  119666. +
  119667. +#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
  119668. +{ \
  119669. + if (atomic_add_value(&g_nQnxInIsrs, 1) == 0) \
  119670. + { \
  119671. + gctARGUMENTS __arguments__; \
  119672. + gcmkARGUMENTS_START(__arguments__, Message); \
  119673. + _Print(ArgumentSize, CopyMessage, Message, __arguments__); \
  119674. + gcmkARGUMENTS_END(__arguments__); \
  119675. + } \
  119676. + atomic_sub(&g_nQnxInIsrs, 1); \
  119677. +}
  119678. +
  119679. +#else
  119680. +
  119681. +#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
  119682. +{ \
  119683. + gctARGUMENTS __arguments__; \
  119684. + gcmkARGUMENTS_START(__arguments__, Message); \
  119685. + _Print(ArgumentSize, CopyMessage, Message, __arguments__); \
  119686. + gcmkARGUMENTS_END(__arguments__); \
  119687. +}
  119688. +
  119689. +#endif
  119690. +
  119691. +/******************************************************************************\
  119692. +********************************** Debug Code **********************************
  119693. +\******************************************************************************/
  119694. +
  119695. +/*******************************************************************************
  119696. +**
  119697. +** gckOS_Print
  119698. +**
  119699. +** Send a message to the debugger.
  119700. +**
  119701. +** INPUT:
  119702. +**
  119703. +** gctCONST_STRING Message
  119704. +** Pointer to message.
  119705. +**
  119706. +** ...
  119707. +** Optional arguments.
  119708. +**
  119709. +** OUTPUT:
  119710. +**
  119711. +** Nothing.
  119712. +*/
  119713. +
  119714. +void
  119715. +gckOS_Print(
  119716. + IN gctCONST_STRING Message,
  119717. + ...
  119718. + )
  119719. +{
  119720. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  119721. +}
  119722. +
  119723. +/*******************************************************************************
  119724. +**
  119725. +** gckOS_PrintN
  119726. +**
  119727. +** Send a message to the debugger.
  119728. +**
  119729. +** INPUT:
  119730. +**
  119731. +** gctUINT ArgumentSize
  119732. +** The size of the optional arguments in bytes.
  119733. +**
  119734. +** gctCONST_STRING Message
  119735. +** Pointer to message.
  119736. +**
  119737. +** ...
  119738. +** Optional arguments.
  119739. +**
  119740. +** OUTPUT:
  119741. +**
  119742. +** Nothing.
  119743. +*/
  119744. +
  119745. +void
  119746. +gckOS_PrintN(
  119747. + IN gctUINT ArgumentSize,
  119748. + IN gctCONST_STRING Message,
  119749. + ...
  119750. + )
  119751. +{
  119752. + gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
  119753. +}
  119754. +
  119755. +/*******************************************************************************
  119756. +**
  119757. +** gckOS_CopyPrint
  119758. +**
  119759. +** Send a message to the debugger. If in buffered output mode, the entire
  119760. +** message will be copied into the buffer instead of using the pointer to
  119761. +** the string.
  119762. +**
  119763. +** INPUT:
  119764. +**
  119765. +** gctCONST_STRING Message
  119766. +** Pointer to message.
  119767. +**
  119768. +** ...
  119769. +** Optional arguments.
  119770. +**
  119771. +** OUTPUT:
  119772. +**
  119773. +** Nothing.
  119774. +*/
  119775. +
  119776. +void
  119777. +gckOS_CopyPrint(
  119778. + IN gctCONST_STRING Message,
  119779. + ...
  119780. + )
  119781. +{
  119782. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvTRUE, Message);
  119783. +}
  119784. +
  119785. +/*******************************************************************************
  119786. +**
  119787. +** gckOS_DumpBuffer
  119788. +**
  119789. +** Print the contents of the specified buffer.
  119790. +**
  119791. +** INPUT:
  119792. +**
  119793. +** gckOS Os
  119794. +** Pointer to gckOS object.
  119795. +**
  119796. +** gctPOINTER Buffer
  119797. +** Pointer to the buffer to print.
  119798. +**
  119799. +** gctUINT Size
  119800. +** Size of the buffer.
  119801. +**
  119802. +** gceDUMP_BUFFER Type
  119803. +** Buffer type.
  119804. +**
  119805. +** OUTPUT:
  119806. +**
  119807. +** Nothing.
  119808. +*/
  119809. +
  119810. +void
  119811. +gckOS_DumpBuffer(
  119812. + IN gckOS Os,
  119813. + IN gctPOINTER Buffer,
  119814. + IN gctUINT Size,
  119815. + IN gceDUMP_BUFFER Type,
  119816. + IN gctBOOL CopyMessage
  119817. + )
  119818. +{
  119819. + gctUINT32 address;
  119820. + gcsBUFFERED_OUTPUT_PTR outputBuffer;
  119821. + static gctBOOL userLocked;
  119822. + gctCHAR *buffer = (gctCHAR*)Buffer;
  119823. +
  119824. + gcmkDECLARE_LOCK(lockHandle);
  119825. +
  119826. + /* Request lock when not coming from user,
  119827. + or coming from user and not yet locked
  119828. + and message is starting with @[. */
  119829. + if (Type == gceDUMP_BUFFER_FROM_USER)
  119830. + {
  119831. + if ((Size > 2)
  119832. + && (buffer[0] == '@')
  119833. + && (buffer[1] == '['))
  119834. + {
  119835. + /* Beginning of a user dump. */
  119836. + gcmkLOCKSECTION(lockHandle);
  119837. + userLocked = gcvTRUE;
  119838. + }
  119839. + /* Else, let it pass through. */
  119840. + }
  119841. + else
  119842. + {
  119843. + gcmkLOCKSECTION(lockHandle);
  119844. + userLocked = gcvFALSE;
  119845. + }
  119846. +
  119847. + if (Buffer != gcvNULL)
  119848. + {
  119849. + /* Initialize output buffer list. */
  119850. + _InitBuffers();
  119851. +
  119852. + /* Locate the proper output buffer. */
  119853. + outputBuffer = _GetOutputBuffer();
  119854. +
  119855. + /* Update the line number. */
  119856. +#if gcdSHOW_LINE_NUMBER
  119857. + outputBuffer->lineNumber += 1;
  119858. +#endif
  119859. +
  119860. + /* Get the physical address of the buffer. */
  119861. + if (Type != gceDUMP_BUFFER_FROM_USER)
  119862. + {
  119863. + gcmkVERIFY_OK(gckOS_GetPhysicalAddress(Os, Buffer, &address));
  119864. + }
  119865. + else
  119866. + {
  119867. + address = 0;
  119868. + }
  119869. +
  119870. +#if gcdHAVEPREFIX
  119871. + {
  119872. + gctUINT8_PTR alignedPrefixData;
  119873. + gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
  119874. +
  119875. + /* Compute aligned pointer. */
  119876. + alignedPrefixData = prefixData;
  119877. + gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
  119878. +
  119879. + /* Initialize the prefix data. */
  119880. + _InitPrefixData(outputBuffer, alignedPrefixData);
  119881. +
  119882. + /* Print/schedule the buffer. */
  119883. + gcdOUTPUTBUFFER(
  119884. + outputBuffer, outputBuffer->indent,
  119885. + alignedPrefixData, Buffer, address, Size, Type, 0
  119886. + );
  119887. + }
  119888. +#else
  119889. + /* Print/schedule the buffer. */
  119890. + if (Type == gceDUMP_BUFFER_FROM_USER)
  119891. + {
  119892. + gcdOUTPUTSTRING(
  119893. + outputBuffer, outputBuffer->indent,
  119894. + Buffer, 0, gcvNULL
  119895. + );
  119896. + }
  119897. + else
  119898. + {
  119899. + gcdOUTPUTBUFFER(
  119900. + outputBuffer, outputBuffer->indent,
  119901. + gcvNULL, Buffer, address, Size, Type, 0
  119902. + );
  119903. + }
  119904. +#endif
  119905. + }
  119906. +
  119907. + /* Unlock when not coming from user,
  119908. + or coming from user and not yet locked. */
  119909. + if (userLocked)
  119910. + {
  119911. + if ((Size > 4)
  119912. + && (buffer[0] == ']')
  119913. + && (buffer[1] == ' ')
  119914. + && (buffer[2] == '-')
  119915. + && (buffer[3] == '-'))
  119916. + {
  119917. + /* End of a user dump. */
  119918. + gcmkUNLOCKSECTION(lockHandle);
  119919. + userLocked = gcvFALSE;
  119920. + }
  119921. + /* Else, let it pass through, don't unlock. */
  119922. + }
  119923. + else
  119924. + {
  119925. + gcmkUNLOCKSECTION(lockHandle);
  119926. + }
  119927. +}
  119928. +
  119929. +/*******************************************************************************
  119930. +**
  119931. +** gckOS_DebugTrace
  119932. +**
  119933. +** Send a leveled message to the debugger.
  119934. +**
  119935. +** INPUT:
  119936. +**
  119937. +** gctUINT32 Level
  119938. +** Debug level of message.
  119939. +**
  119940. +** gctCONST_STRING Message
  119941. +** Pointer to message.
  119942. +**
  119943. +** ...
  119944. +** Optional arguments.
  119945. +**
  119946. +** OUTPUT:
  119947. +**
  119948. +** Nothing.
  119949. +*/
  119950. +
  119951. +void
  119952. +gckOS_DebugTrace(
  119953. + IN gctUINT32 Level,
  119954. + IN gctCONST_STRING Message,
  119955. + ...
  119956. + )
  119957. +{
  119958. + if (Level > _debugLevel)
  119959. + {
  119960. + return;
  119961. + }
  119962. +
  119963. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  119964. +}
  119965. +
  119966. +/*******************************************************************************
  119967. +**
  119968. +** gckOS_DebugTraceN
  119969. +**
  119970. +** Send a leveled message to the debugger.
  119971. +**
  119972. +** INPUT:
  119973. +**
  119974. +** gctUINT32 Level
  119975. +** Debug level of message.
  119976. +**
  119977. +** gctUINT ArgumentSize
  119978. +** The size of the optional arguments in bytes.
  119979. +**
  119980. +** gctCONST_STRING Message
  119981. +** Pointer to message.
  119982. +**
  119983. +** ...
  119984. +** Optional arguments.
  119985. +**
  119986. +** OUTPUT:
  119987. +**
  119988. +** Nothing.
  119989. +*/
  119990. +
  119991. +void
  119992. +gckOS_DebugTraceN(
  119993. + IN gctUINT32 Level,
  119994. + IN gctUINT ArgumentSize,
  119995. + IN gctCONST_STRING Message,
  119996. + ...
  119997. + )
  119998. +{
  119999. + if (Level > _debugLevel)
  120000. + {
  120001. + return;
  120002. + }
  120003. +
  120004. + gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
  120005. +}
  120006. +
  120007. +/*******************************************************************************
  120008. +**
  120009. +** gckOS_DebugTraceZone
  120010. +**
  120011. +** Send a leveled and zoned message to the debugger.
  120012. +**
  120013. +** INPUT:
  120014. +**
  120015. +** gctUINT32 Level
  120016. +** Debug level for message.
  120017. +**
  120018. +** gctUINT32 Zone
  120019. +** Debug zone for message.
  120020. +**
  120021. +** gctCONST_STRING Message
  120022. +** Pointer to message.
  120023. +**
  120024. +** ...
  120025. +** Optional arguments.
  120026. +**
  120027. +** OUTPUT:
  120028. +**
  120029. +** Nothing.
  120030. +*/
  120031. +
  120032. +void
  120033. +gckOS_DebugTraceZone(
  120034. + IN gctUINT32 Level,
  120035. + IN gctUINT32 Zone,
  120036. + IN gctCONST_STRING Message,
  120037. + ...
  120038. + )
  120039. +{
  120040. + if ((Level > _debugLevel) || !(Zone & _debugZones))
  120041. + {
  120042. + return;
  120043. + }
  120044. +
  120045. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  120046. +}
  120047. +
  120048. +/*******************************************************************************
  120049. +**
  120050. +** gckOS_DebugTraceZoneN
  120051. +**
  120052. +** Send a leveled and zoned message to the debugger.
  120053. +**
  120054. +** INPUT:
  120055. +**
  120056. +** gctUINT32 Level
  120057. +** Debug level for message.
  120058. +**
  120059. +** gctUINT32 Zone
  120060. +** Debug zone for message.
  120061. +**
  120062. +** gctUINT ArgumentSize
  120063. +** The size of the optional arguments in bytes.
  120064. +**
  120065. +** gctCONST_STRING Message
  120066. +** Pointer to message.
  120067. +**
  120068. +** ...
  120069. +** Optional arguments.
  120070. +**
  120071. +** OUTPUT:
  120072. +**
  120073. +** Nothing.
  120074. +*/
  120075. +
  120076. +void
  120077. +gckOS_DebugTraceZoneN(
  120078. + IN gctUINT32 Level,
  120079. + IN gctUINT32 Zone,
  120080. + IN gctUINT ArgumentSize,
  120081. + IN gctCONST_STRING Message,
  120082. + ...
  120083. + )
  120084. +{
  120085. + if ((Level > _debugLevel) || !(Zone & _debugZones))
  120086. + {
  120087. + return;
  120088. + }
  120089. +
  120090. + gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
  120091. +}
  120092. +
  120093. +/*******************************************************************************
  120094. +**
  120095. +** gckOS_DebugBreak
  120096. +**
  120097. +** Break into the debugger.
  120098. +**
  120099. +** INPUT:
  120100. +**
  120101. +** Nothing.
  120102. +**
  120103. +** OUTPUT:
  120104. +**
  120105. +** Nothing.
  120106. +*/
  120107. +void
  120108. +gckOS_DebugBreak(
  120109. + void
  120110. + )
  120111. +{
  120112. + gckOS_DebugTrace(gcvLEVEL_ERROR, "%s(%d)", __FUNCTION__, __LINE__);
  120113. +}
  120114. +
  120115. +/*******************************************************************************
  120116. +**
  120117. +** gckOS_DebugFatal
  120118. +**
  120119. +** Send a message to the debugger and break into the debugger.
  120120. +**
  120121. +** INPUT:
  120122. +**
  120123. +** gctCONST_STRING Message
  120124. +** Pointer to message.
  120125. +**
  120126. +** ...
  120127. +** Optional arguments.
  120128. +**
  120129. +** OUTPUT:
  120130. +**
  120131. +** Nothing.
  120132. +*/
  120133. +void
  120134. +gckOS_DebugFatal(
  120135. + IN gctCONST_STRING Message,
  120136. + ...
  120137. + )
  120138. +{
  120139. + gcmkPRINT_VERSION();
  120140. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  120141. +
  120142. + /* Break into the debugger. */
  120143. + gckOS_DebugBreak();
  120144. +}
  120145. +
  120146. +/*******************************************************************************
  120147. +**
  120148. +** gckOS_SetDebugLevel
  120149. +**
  120150. +** Set the debug level.
  120151. +**
  120152. +** INPUT:
  120153. +**
  120154. +** gctUINT32 Level
  120155. +** New debug level.
  120156. +**
  120157. +** OUTPUT:
  120158. +**
  120159. +** Nothing.
  120160. +*/
  120161. +
  120162. +void
  120163. +gckOS_SetDebugLevel(
  120164. + IN gctUINT32 Level
  120165. + )
  120166. +{
  120167. + _debugLevel = Level;
  120168. +}
  120169. +
  120170. +/*******************************************************************************
  120171. +**
  120172. +** gckOS_SetDebugZone
  120173. +**
  120174. +** Set the debug zone.
  120175. +**
  120176. +** INPUT:
  120177. +**
  120178. +** gctUINT32 Zone
  120179. +** New debug zone.
  120180. +**
  120181. +** OUTPUT:
  120182. +**
  120183. +** Nothing.
  120184. +*/
  120185. +void
  120186. +gckOS_SetDebugZone(
  120187. + IN gctUINT32 Zone
  120188. + )
  120189. +{
  120190. + _debugZones = Zone;
  120191. +}
  120192. +
  120193. +/*******************************************************************************
  120194. +**
  120195. +** gckOS_SetDebugLevelZone
  120196. +**
  120197. +** Set the debug level and zone.
  120198. +**
  120199. +** INPUT:
  120200. +**
  120201. +** gctUINT32 Level
  120202. +** New debug level.
  120203. +**
  120204. +** gctUINT32 Zone
  120205. +** New debug zone.
  120206. +**
  120207. +** OUTPUT:
  120208. +**
  120209. +** Nothing.
  120210. +*/
  120211. +
  120212. +void
  120213. +gckOS_SetDebugLevelZone(
  120214. + IN gctUINT32 Level,
  120215. + IN gctUINT32 Zone
  120216. + )
  120217. +{
  120218. + _debugLevel = Level;
  120219. + _debugZones = Zone;
  120220. +}
  120221. +
  120222. +/*******************************************************************************
  120223. +**
  120224. +** gckOS_SetDebugZones
  120225. +**
  120226. +** Enable or disable debug zones.
  120227. +**
  120228. +** INPUT:
  120229. +**
  120230. +** gctUINT32 Zones
  120231. +** Debug zones to enable or disable.
  120232. +**
  120233. +** gctBOOL Enable
  120234. +** Set to gcvTRUE to enable the zones (or the Zones with the current
  120235. +** zones) or gcvFALSE to disable the specified Zones.
  120236. +**
  120237. +** OUTPUT:
  120238. +**
  120239. +** Nothing.
  120240. +*/
  120241. +
  120242. +void
  120243. +gckOS_SetDebugZones(
  120244. + IN gctUINT32 Zones,
  120245. + IN gctBOOL Enable
  120246. + )
  120247. +{
  120248. + if (Enable)
  120249. + {
  120250. + /* Enable the zones. */
  120251. + _debugZones |= Zones;
  120252. + }
  120253. + else
  120254. + {
  120255. + /* Disable the zones. */
  120256. + _debugZones &= ~Zones;
  120257. + }
  120258. +}
  120259. +
  120260. +/*******************************************************************************
  120261. +**
  120262. +** gckOS_Verify
  120263. +**
  120264. +** Called to verify the result of a function call.
  120265. +**
  120266. +** INPUT:
  120267. +**
  120268. +** gceSTATUS Status
  120269. +** Function call result.
  120270. +**
  120271. +** OUTPUT:
  120272. +**
  120273. +** Nothing.
  120274. +*/
  120275. +
  120276. +void
  120277. +gckOS_Verify(
  120278. + IN gceSTATUS status
  120279. + )
  120280. +{
  120281. + _lastError = status;
  120282. +}
  120283. +
  120284. +/*******************************************************************************
  120285. +**
  120286. +** gckOS_DebugFlush
  120287. +**
  120288. +** Force messages to be flushed out.
  120289. +**
  120290. +** INPUT:
  120291. +**
  120292. +** gctCONST_STRING CallerName
  120293. +** Name of the caller function.
  120294. +**
  120295. +** gctUINT LineNumber
  120296. +** Line number of the caller.
  120297. +**
  120298. +** gctUINT32 DmaAddress
  120299. +** The current DMA address or ~0U to ignore.
  120300. +**
  120301. +** OUTPUT:
  120302. +**
  120303. +** Nothing.
  120304. +*/
  120305. +
  120306. +void
  120307. +gckOS_DebugFlush(
  120308. + gctCONST_STRING CallerName,
  120309. + gctUINT LineNumber,
  120310. + gctUINT32 DmaAddress
  120311. + )
  120312. +{
  120313. +#if gcdBUFFERED_OUTPUT
  120314. + _DirectPrint("\nFlush requested by %s(%d).\n\n", CallerName, LineNumber);
  120315. + _Flush(DmaAddress);
  120316. +#endif
  120317. +}
  120318. +gctCONST_STRING
  120319. +gckOS_DebugStatus2Name(
  120320. + gceSTATUS status
  120321. + )
  120322. +{
  120323. + switch (status)
  120324. + {
  120325. + case gcvSTATUS_OK:
  120326. + return "gcvSTATUS_OK";
  120327. + case gcvSTATUS_TRUE:
  120328. + return "gcvSTATUS_TRUE";
  120329. + case gcvSTATUS_NO_MORE_DATA:
  120330. + return "gcvSTATUS_NO_MORE_DATA";
  120331. + case gcvSTATUS_CACHED:
  120332. + return "gcvSTATUS_CACHED";
  120333. + case gcvSTATUS_MIPMAP_TOO_LARGE:
  120334. + return "gcvSTATUS_MIPMAP_TOO_LARGE";
  120335. + case gcvSTATUS_NAME_NOT_FOUND:
  120336. + return "gcvSTATUS_NAME_NOT_FOUND";
  120337. + case gcvSTATUS_NOT_OUR_INTERRUPT:
  120338. + return "gcvSTATUS_NOT_OUR_INTERRUPT";
  120339. + case gcvSTATUS_MISMATCH:
  120340. + return "gcvSTATUS_MISMATCH";
  120341. + case gcvSTATUS_MIPMAP_TOO_SMALL:
  120342. + return "gcvSTATUS_MIPMAP_TOO_SMALL";
  120343. + case gcvSTATUS_LARGER:
  120344. + return "gcvSTATUS_LARGER";
  120345. + case gcvSTATUS_SMALLER:
  120346. + return "gcvSTATUS_SMALLER";
  120347. + case gcvSTATUS_CHIP_NOT_READY:
  120348. + return "gcvSTATUS_CHIP_NOT_READY";
  120349. + case gcvSTATUS_NEED_CONVERSION:
  120350. + return "gcvSTATUS_NEED_CONVERSION";
  120351. + case gcvSTATUS_SKIP:
  120352. + return "gcvSTATUS_SKIP";
  120353. + case gcvSTATUS_DATA_TOO_LARGE:
  120354. + return "gcvSTATUS_DATA_TOO_LARGE";
  120355. + case gcvSTATUS_INVALID_CONFIG:
  120356. + return "gcvSTATUS_INVALID_CONFIG";
  120357. + case gcvSTATUS_CHANGED:
  120358. + return "gcvSTATUS_CHANGED";
  120359. + case gcvSTATUS_NOT_SUPPORT_DITHER:
  120360. + return "gcvSTATUS_NOT_SUPPORT_DITHER";
  120361. +
  120362. + case gcvSTATUS_INVALID_ARGUMENT:
  120363. + return "gcvSTATUS_INVALID_ARGUMENT";
  120364. + case gcvSTATUS_INVALID_OBJECT:
  120365. + return "gcvSTATUS_INVALID_OBJECT";
  120366. + case gcvSTATUS_OUT_OF_MEMORY:
  120367. + return "gcvSTATUS_OUT_OF_MEMORY";
  120368. + case gcvSTATUS_MEMORY_LOCKED:
  120369. + return "gcvSTATUS_MEMORY_LOCKED";
  120370. + case gcvSTATUS_MEMORY_UNLOCKED:
  120371. + return "gcvSTATUS_MEMORY_UNLOCKED";
  120372. + case gcvSTATUS_HEAP_CORRUPTED:
  120373. + return "gcvSTATUS_HEAP_CORRUPTED";
  120374. + case gcvSTATUS_GENERIC_IO:
  120375. + return "gcvSTATUS_GENERIC_IO";
  120376. + case gcvSTATUS_INVALID_ADDRESS:
  120377. + return "gcvSTATUS_INVALID_ADDRESS";
  120378. + case gcvSTATUS_CONTEXT_LOSSED:
  120379. + return "gcvSTATUS_CONTEXT_LOSSED";
  120380. + case gcvSTATUS_TOO_COMPLEX:
  120381. + return "gcvSTATUS_TOO_COMPLEX";
  120382. + case gcvSTATUS_BUFFER_TOO_SMALL:
  120383. + return "gcvSTATUS_BUFFER_TOO_SMALL";
  120384. + case gcvSTATUS_INTERFACE_ERROR:
  120385. + return "gcvSTATUS_INTERFACE_ERROR";
  120386. + case gcvSTATUS_NOT_SUPPORTED:
  120387. + return "gcvSTATUS_NOT_SUPPORTED";
  120388. + case gcvSTATUS_MORE_DATA:
  120389. + return "gcvSTATUS_MORE_DATA";
  120390. + case gcvSTATUS_TIMEOUT:
  120391. + return "gcvSTATUS_TIMEOUT";
  120392. + case gcvSTATUS_OUT_OF_RESOURCES:
  120393. + return "gcvSTATUS_OUT_OF_RESOURCES";
  120394. + case gcvSTATUS_INVALID_DATA:
  120395. + return "gcvSTATUS_INVALID_DATA";
  120396. + case gcvSTATUS_INVALID_MIPMAP:
  120397. + return "gcvSTATUS_INVALID_MIPMAP";
  120398. + case gcvSTATUS_NOT_FOUND:
  120399. + return "gcvSTATUS_NOT_FOUND";
  120400. + case gcvSTATUS_NOT_ALIGNED:
  120401. + return "gcvSTATUS_NOT_ALIGNED";
  120402. + case gcvSTATUS_INVALID_REQUEST:
  120403. + return "gcvSTATUS_INVALID_REQUEST";
  120404. + case gcvSTATUS_GPU_NOT_RESPONDING:
  120405. + return "gcvSTATUS_GPU_NOT_RESPONDING";
  120406. + case gcvSTATUS_TIMER_OVERFLOW:
  120407. + return "gcvSTATUS_TIMER_OVERFLOW";
  120408. + case gcvSTATUS_VERSION_MISMATCH:
  120409. + return "gcvSTATUS_VERSION_MISMATCH";
  120410. + case gcvSTATUS_LOCKED:
  120411. + return "gcvSTATUS_LOCKED";
  120412. +
  120413. + /* Linker errors. */
  120414. + case gcvSTATUS_GLOBAL_TYPE_MISMATCH:
  120415. + return "gcvSTATUS_GLOBAL_TYPE_MISMATCH";
  120416. + case gcvSTATUS_TOO_MANY_ATTRIBUTES:
  120417. + return "gcvSTATUS_TOO_MANY_ATTRIBUTES";
  120418. + case gcvSTATUS_TOO_MANY_UNIFORMS:
  120419. + return "gcvSTATUS_TOO_MANY_UNIFORMS";
  120420. + case gcvSTATUS_TOO_MANY_VARYINGS:
  120421. + return "gcvSTATUS_TOO_MANY_VARYINGS";
  120422. + case gcvSTATUS_UNDECLARED_VARYING:
  120423. + return "gcvSTATUS_UNDECLARED_VARYING";
  120424. + case gcvSTATUS_VARYING_TYPE_MISMATCH:
  120425. + return "gcvSTATUS_VARYING_TYPE_MISMATCH";
  120426. + case gcvSTATUS_MISSING_MAIN:
  120427. + return "gcvSTATUS_MISSING_MAIN";
  120428. + case gcvSTATUS_NAME_MISMATCH:
  120429. + return "gcvSTATUS_NAME_MISMATCH";
  120430. + case gcvSTATUS_INVALID_INDEX:
  120431. + return "gcvSTATUS_INVALID_INDEX";
  120432. + default:
  120433. + return "nil";
  120434. + }
  120435. +}
  120436. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
  120437. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c 1969-12-31 18:00:00.000000000 -0600
  120438. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c 2014-12-08 00:31:53.464418001 -0600
  120439. @@ -0,0 +1,2898 @@
  120440. +/****************************************************************************
  120441. +*
  120442. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  120443. +*
  120444. +* This program is free software; you can redistribute it and/or modify
  120445. +* it under the terms of the GNU General Public License as published by
  120446. +* the Free Software Foundation; either version 2 of the license, or
  120447. +* (at your option) any later version.
  120448. +*
  120449. +* This program is distributed in the hope that it will be useful,
  120450. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  120451. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  120452. +* GNU General Public License for more details.
  120453. +*
  120454. +* You should have received a copy of the GNU General Public License
  120455. +* along with this program; if not write to the Free Software
  120456. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  120457. +*
  120458. +*****************************************************************************/
  120459. +
  120460. +
  120461. +#include "gc_hal_kernel_precomp.h"
  120462. +#include "gc_hal_kernel_buffer.h"
  120463. +
  120464. +#ifdef __QNXNTO__
  120465. +#include <atomic.h>
  120466. +#include "gc_hal_kernel_qnx.h"
  120467. +#endif
  120468. +
  120469. +#define _GC_OBJ_ZONE gcvZONE_EVENT
  120470. +
  120471. +#define gcdEVENT_ALLOCATION_COUNT (4096 / gcmSIZEOF(gcsHAL_INTERFACE))
  120472. +#define gcdEVENT_MIN_THRESHOLD 4
  120473. +
  120474. +/******************************************************************************\
  120475. +********************************* Support Code *********************************
  120476. +\******************************************************************************/
  120477. +
  120478. +static gceSTATUS
  120479. +gckEVENT_AllocateQueue(
  120480. + IN gckEVENT Event,
  120481. + OUT gcsEVENT_QUEUE_PTR * Queue
  120482. + )
  120483. +{
  120484. + gceSTATUS status;
  120485. +
  120486. + gcmkHEADER_ARG("Event=0x%x", Event);
  120487. +
  120488. + /* Verify the arguments. */
  120489. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  120490. + gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
  120491. +
  120492. + /* Do we have free queues? */
  120493. + if (Event->freeList == gcvNULL)
  120494. + {
  120495. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  120496. + }
  120497. +
  120498. + /* Move one free queue from the free list. */
  120499. + * Queue = Event->freeList;
  120500. + Event->freeList = Event->freeList->next;
  120501. +
  120502. + /* Success. */
  120503. + gcmkFOOTER_ARG("*Queue=0x%x", gcmOPT_POINTER(Queue));
  120504. + return gcvSTATUS_OK;
  120505. +
  120506. +OnError:
  120507. + /* Return the status. */
  120508. + gcmkFOOTER();
  120509. + return status;
  120510. +}
  120511. +
  120512. +static gceSTATUS
  120513. +gckEVENT_FreeQueue(
  120514. + IN gckEVENT Event,
  120515. + OUT gcsEVENT_QUEUE_PTR Queue
  120516. + )
  120517. +{
  120518. + gceSTATUS status = gcvSTATUS_OK;
  120519. +
  120520. + gcmkHEADER_ARG("Event=0x%x", Event);
  120521. +
  120522. + /* Verify the arguments. */
  120523. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  120524. + gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
  120525. +
  120526. + /* Move one free queue from the free list. */
  120527. + Queue->next = Event->freeList;
  120528. + Event->freeList = Queue;
  120529. +
  120530. + /* Success. */
  120531. + gcmkFOOTER();
  120532. + return status;
  120533. +}
  120534. +
  120535. +static gceSTATUS
  120536. +gckEVENT_FreeRecord(
  120537. + IN gckEVENT Event,
  120538. + IN gcsEVENT_PTR Record
  120539. + )
  120540. +{
  120541. + gceSTATUS status;
  120542. + gctBOOL acquired = gcvFALSE;
  120543. +
  120544. + gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
  120545. +
  120546. + /* Verify the arguments. */
  120547. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  120548. + gcmkVERIFY_ARGUMENT(Record != gcvNULL);
  120549. +
  120550. + /* Acquire the mutex. */
  120551. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  120552. + Event->freeEventMutex,
  120553. + gcvINFINITE));
  120554. + acquired = gcvTRUE;
  120555. +
  120556. + /* Push the record on the free list. */
  120557. + Record->next = Event->freeEventList;
  120558. + Event->freeEventList = Record;
  120559. + Event->freeEventCount += 1;
  120560. +
  120561. + /* Release the mutex. */
  120562. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  120563. +
  120564. + /* Success. */
  120565. + gcmkFOOTER_NO();
  120566. + return gcvSTATUS_OK;
  120567. +
  120568. +OnError:
  120569. + /* Roll back. */
  120570. + if (acquired)
  120571. + {
  120572. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  120573. + }
  120574. +
  120575. + /* Return the status. */
  120576. + gcmkFOOTER();
  120577. + return gcvSTATUS_OK;
  120578. +}
  120579. +
  120580. +static gceSTATUS
  120581. +gckEVENT_IsEmpty(
  120582. + IN gckEVENT Event,
  120583. + OUT gctBOOL_PTR IsEmpty
  120584. + )
  120585. +{
  120586. + gceSTATUS status;
  120587. + gctSIZE_T i;
  120588. +
  120589. + gcmkHEADER_ARG("Event=0x%x", Event);
  120590. +
  120591. + /* Verify the arguments. */
  120592. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  120593. + gcmkVERIFY_ARGUMENT(IsEmpty != gcvNULL);
  120594. +
  120595. + /* Assume the event queue is empty. */
  120596. + *IsEmpty = gcvTRUE;
  120597. +
  120598. + /* Try acquiring the mutex. */
  120599. + status = gckOS_AcquireMutex(Event->os, Event->eventQueueMutex, 0);
  120600. + if (status == gcvSTATUS_TIMEOUT)
  120601. + {
  120602. + /* Timeout - queue is no longer empty. */
  120603. + *IsEmpty = gcvFALSE;
  120604. + }
  120605. + else
  120606. + {
  120607. + /* Bail out on error. */
  120608. + gcmkONERROR(status);
  120609. +
  120610. + /* Walk the event queue. */
  120611. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  120612. + {
  120613. + /* Check whether this event is in use. */
  120614. + if (Event->queues[i].head != gcvNULL)
  120615. + {
  120616. + /* The event is in use, hence the queue is not empty. */
  120617. + *IsEmpty = gcvFALSE;
  120618. + break;
  120619. + }
  120620. + }
  120621. +
  120622. + /* Release the mutex. */
  120623. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  120624. + }
  120625. +
  120626. + /* Success. */
  120627. + gcmkFOOTER_ARG("*IsEmpty=%d", gcmOPT_VALUE(IsEmpty));
  120628. + return gcvSTATUS_OK;
  120629. +
  120630. +OnError:
  120631. + /* Return the status. */
  120632. + gcmkFOOTER();
  120633. + return status;
  120634. +}
  120635. +
  120636. +static gceSTATUS
  120637. +_TryToIdleGPU(
  120638. + IN gckEVENT Event
  120639. +)
  120640. +{
  120641. + gceSTATUS status;
  120642. + gctBOOL empty = gcvFALSE, idle = gcvFALSE;
  120643. + gctBOOL powerLocked = gcvFALSE;
  120644. + gckHARDWARE hardware;
  120645. +
  120646. + gcmkHEADER_ARG("Event=0x%x", Event);
  120647. +
  120648. + /* Verify the arguments. */
  120649. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  120650. +
  120651. + /* Grab gckHARDWARE object. */
  120652. + hardware = Event->kernel->hardware;
  120653. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  120654. +
  120655. + /* Check whether the event queue is empty. */
  120656. + gcmkONERROR(gckEVENT_IsEmpty(Event, &empty));
  120657. +
  120658. + if (empty)
  120659. + {
  120660. + status = gckOS_AcquireMutex(hardware->os, hardware->powerMutex, 0);
  120661. + if (status == gcvSTATUS_TIMEOUT)
  120662. + {
  120663. + gcmkFOOTER_NO();
  120664. + return gcvSTATUS_OK;
  120665. + }
  120666. +
  120667. + powerLocked = gcvTRUE;
  120668. +
  120669. + /* Query whether the hardware is idle. */
  120670. + gcmkONERROR(gckHARDWARE_QueryIdle(Event->kernel->hardware, &idle));
  120671. +
  120672. + gcmkONERROR(gckOS_ReleaseMutex(hardware->os, hardware->powerMutex));
  120673. + powerLocked = gcvFALSE;
  120674. +
  120675. + if (idle)
  120676. + {
  120677. + /* Inform the system of idle GPU. */
  120678. + gcmkONERROR(gckOS_Broadcast(Event->os,
  120679. + Event->kernel->hardware,
  120680. + gcvBROADCAST_GPU_IDLE));
  120681. + }
  120682. + }
  120683. +
  120684. + gcmkFOOTER_NO();
  120685. + return gcvSTATUS_OK;
  120686. +
  120687. +OnError:
  120688. + if (powerLocked)
  120689. + {
  120690. + gcmkONERROR(gckOS_ReleaseMutex(hardware->os, hardware->powerMutex));
  120691. + powerLocked = gcvFALSE;
  120692. + }
  120693. +
  120694. + gcmkFOOTER();
  120695. + return status;
  120696. +}
  120697. +
  120698. +static gceSTATUS
  120699. +__RemoveRecordFromProcessDB(
  120700. + IN gckEVENT Event,
  120701. + IN gcsEVENT_PTR Record
  120702. + )
  120703. +{
  120704. + gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
  120705. + gcmkVERIFY_ARGUMENT(Record != gcvNULL);
  120706. +
  120707. + while (Record != gcvNULL)
  120708. + {
  120709. + if (Record->info.command == gcvHAL_SIGNAL)
  120710. + {
  120711. + /* TODO: Find a better place to bind signal to hardware.*/
  120712. + gcmkVERIFY_OK(gckOS_SignalSetHardware(Event->os,
  120713. + gcmUINT64_TO_PTR(Record->info.u.Signal.signal),
  120714. + Event->kernel->hardware));
  120715. + }
  120716. +
  120717. + if (Record->fromKernel)
  120718. + {
  120719. + /* No need to check db if event is from kernel. */
  120720. + Record = Record->next;
  120721. + continue;
  120722. + }
  120723. +
  120724. + switch (Record->info.command)
  120725. + {
  120726. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  120727. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120728. + Event->kernel,
  120729. + Record->processID,
  120730. + gcvDB_NON_PAGED,
  120731. + gcmUINT64_TO_PTR(Record->info.u.FreeNonPagedMemory.logical)));
  120732. + break;
  120733. +
  120734. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  120735. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120736. + Event->kernel,
  120737. + Record->processID,
  120738. + gcvDB_CONTIGUOUS,
  120739. + gcmUINT64_TO_PTR(Record->info.u.FreeContiguousMemory.logical)));
  120740. + break;
  120741. +
  120742. + case gcvHAL_FREE_VIDEO_MEMORY:
  120743. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120744. + Event->kernel,
  120745. + Record->processID,
  120746. + gcvDB_VIDEO_MEMORY,
  120747. + gcmUINT64_TO_PTR(Record->info.u.FreeVideoMemory.node)));
  120748. +
  120749. + {
  120750. + gcuVIDMEM_NODE_PTR node = (gcuVIDMEM_NODE_PTR)(gcmUINT64_TO_PTR(Record->info.u.FreeVideoMemory.node));
  120751. +
  120752. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  120753. + {
  120754. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
  120755. + Record->processID,
  120756. + gcvDB_VIDEO_MEMORY_RESERVED,
  120757. + node));
  120758. + }
  120759. + else if(node->Virtual.contiguous)
  120760. + {
  120761. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
  120762. + Record->processID,
  120763. + gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  120764. + node));
  120765. + }
  120766. + else
  120767. + {
  120768. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
  120769. + Record->processID,
  120770. + gcvDB_VIDEO_MEMORY_VIRTUAL,
  120771. + node));
  120772. + }
  120773. + }
  120774. +
  120775. + break;
  120776. +
  120777. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  120778. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120779. + Event->kernel,
  120780. + Record->processID,
  120781. + gcvDB_VIDEO_MEMORY_LOCKED,
  120782. + gcmUINT64_TO_PTR(Record->info.u.UnlockVideoMemory.node)));
  120783. + break;
  120784. +
  120785. + case gcvHAL_UNMAP_USER_MEMORY:
  120786. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120787. + Event->kernel,
  120788. + Record->processID,
  120789. + gcvDB_MAP_USER_MEMORY,
  120790. + gcmINT2PTR(Record->info.u.UnmapUserMemory.info)));
  120791. + break;
  120792. +
  120793. + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
  120794. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  120795. + Event->kernel,
  120796. + Record->processID,
  120797. + gcvDB_COMMAND_BUFFER,
  120798. + gcmUINT64_TO_PTR(Record->info.u.FreeVirtualCommandBuffer.logical)));
  120799. + break;
  120800. +
  120801. + default:
  120802. + break;
  120803. + }
  120804. +
  120805. + Record = Record->next;
  120806. + }
  120807. + gcmkFOOTER_NO();
  120808. + return gcvSTATUS_OK;
  120809. +}
  120810. +
  120811. +void
  120812. +_SubmitTimerFunction(
  120813. + gctPOINTER Data
  120814. + )
  120815. +{
  120816. + gckEVENT event = (gckEVENT)Data;
  120817. + gcmkVERIFY_OK(gckEVENT_Submit(event, gcvTRUE, gcvFALSE));
  120818. +}
  120819. +
  120820. +/******************************************************************************\
  120821. +******************************* gckEVENT API Code *******************************
  120822. +\******************************************************************************/
  120823. +
  120824. +/*******************************************************************************
  120825. +**
  120826. +** gckEVENT_Construct
  120827. +**
  120828. +** Construct a new gckEVENT object.
  120829. +**
  120830. +** INPUT:
  120831. +**
  120832. +** gckKERNEL Kernel
  120833. +** Pointer to an gckKERNEL object.
  120834. +**
  120835. +** OUTPUT:
  120836. +**
  120837. +** gckEVENT * Event
  120838. +** Pointer to a variable that receives the gckEVENT object pointer.
  120839. +*/
  120840. +gceSTATUS
  120841. +gckEVENT_Construct(
  120842. + IN gckKERNEL Kernel,
  120843. + OUT gckEVENT * Event
  120844. + )
  120845. +{
  120846. + gckOS os;
  120847. + gceSTATUS status;
  120848. + gckEVENT eventObj = gcvNULL;
  120849. + int i;
  120850. + gcsEVENT_PTR record;
  120851. + gctPOINTER pointer = gcvNULL;
  120852. +
  120853. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  120854. +
  120855. + /* Verify the arguments. */
  120856. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  120857. + gcmkVERIFY_ARGUMENT(Event != gcvNULL);
  120858. +
  120859. + /* Extract the pointer to the gckOS object. */
  120860. + os = Kernel->os;
  120861. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  120862. +
  120863. + /* Allocate the gckEVENT object. */
  120864. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckEVENT), &pointer));
  120865. +
  120866. + eventObj = pointer;
  120867. +
  120868. + /* Reset the object. */
  120869. + gcmkVERIFY_OK(gckOS_ZeroMemory(eventObj, gcmSIZEOF(struct _gckEVENT)));
  120870. +
  120871. + /* Initialize the gckEVENT object. */
  120872. + eventObj->object.type = gcvOBJ_EVENT;
  120873. + eventObj->kernel = Kernel;
  120874. + eventObj->os = os;
  120875. +
  120876. + /* Create the mutexes. */
  120877. + gcmkONERROR(gckOS_CreateMutex(os, &eventObj->eventQueueMutex));
  120878. + gcmkONERROR(gckOS_CreateMutex(os, &eventObj->freeEventMutex));
  120879. + gcmkONERROR(gckOS_CreateMutex(os, &eventObj->eventListMutex));
  120880. +
  120881. + /* Create a bunch of event reccords. */
  120882. + for (i = 0; i < gcdEVENT_ALLOCATION_COUNT; i += 1)
  120883. + {
  120884. + /* Allocate an event record. */
  120885. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsEVENT), &pointer));
  120886. +
  120887. + record = pointer;
  120888. +
  120889. + /* Push it on the free list. */
  120890. + record->next = eventObj->freeEventList;
  120891. + eventObj->freeEventList = record;
  120892. + eventObj->freeEventCount += 1;
  120893. + }
  120894. +
  120895. + /* Initialize the free list of event queues. */
  120896. + for (i = 0; i < gcdREPO_LIST_COUNT; i += 1)
  120897. + {
  120898. + eventObj->repoList[i].next = eventObj->freeList;
  120899. + eventObj->freeList = &eventObj->repoList[i];
  120900. + }
  120901. +
  120902. + /* Construct the atom. */
  120903. + gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->freeAtom));
  120904. + gcmkONERROR(gckOS_AtomSet(os,
  120905. + eventObj->freeAtom,
  120906. + gcmCOUNTOF(eventObj->queues)));
  120907. +
  120908. +#if gcdSMP
  120909. + gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pending));
  120910. +#endif
  120911. +
  120912. + gcmkVERIFY_OK(gckOS_CreateTimer(os,
  120913. + _SubmitTimerFunction,
  120914. + (gctPOINTER)eventObj,
  120915. + &eventObj->submitTimer));
  120916. +
  120917. + /* Return pointer to the gckEVENT object. */
  120918. + *Event = eventObj;
  120919. +
  120920. + /* Success. */
  120921. + gcmkFOOTER_ARG("*Event=0x%x", *Event);
  120922. + return gcvSTATUS_OK;
  120923. +
  120924. +OnError:
  120925. + /* Roll back. */
  120926. + if (eventObj != gcvNULL)
  120927. + {
  120928. + if (eventObj->eventQueueMutex != gcvNULL)
  120929. + {
  120930. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->eventQueueMutex));
  120931. + }
  120932. +
  120933. + if (eventObj->freeEventMutex != gcvNULL)
  120934. + {
  120935. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->freeEventMutex));
  120936. + }
  120937. +
  120938. + if (eventObj->eventListMutex != gcvNULL)
  120939. + {
  120940. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->eventListMutex));
  120941. + }
  120942. +
  120943. + while (eventObj->freeEventList != gcvNULL)
  120944. + {
  120945. + record = eventObj->freeEventList;
  120946. + eventObj->freeEventList = record->next;
  120947. +
  120948. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, record));
  120949. + }
  120950. +
  120951. + if (eventObj->freeAtom != gcvNULL)
  120952. + {
  120953. + gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->freeAtom));
  120954. + }
  120955. +
  120956. +#if gcdSMP
  120957. + if (eventObj->pending != gcvNULL)
  120958. + {
  120959. + gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->pending));
  120960. + }
  120961. +#endif
  120962. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, eventObj));
  120963. + }
  120964. +
  120965. + /* Return the status. */
  120966. + gcmkFOOTER();
  120967. + return status;
  120968. +}
  120969. +
  120970. +/*******************************************************************************
  120971. +**
  120972. +** gckEVENT_Destroy
  120973. +**
  120974. +** Destroy an gckEVENT object.
  120975. +**
  120976. +** INPUT:
  120977. +**
  120978. +** gckEVENT Event
  120979. +** Pointer to an gckEVENT object.
  120980. +**
  120981. +** OUTPUT:
  120982. +**
  120983. +** Nothing.
  120984. +*/
  120985. +gceSTATUS
  120986. +gckEVENT_Destroy(
  120987. + IN gckEVENT Event
  120988. + )
  120989. +{
  120990. + gcsEVENT_PTR record;
  120991. + gcsEVENT_QUEUE_PTR queue;
  120992. +
  120993. + gcmkHEADER_ARG("Event=0x%x", Event);
  120994. +
  120995. + /* Verify the arguments. */
  120996. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  120997. +
  120998. + if (Event->submitTimer != gcvNULL)
  120999. + {
  121000. + gcmkVERIFY_OK(gckOS_StopTimer(Event->os, Event->submitTimer));
  121001. + gcmkVERIFY_OK(gckOS_DestroyTimer(Event->os, Event->submitTimer));
  121002. + }
  121003. +
  121004. + /* Delete the queue mutex. */
  121005. + gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->eventQueueMutex));
  121006. +
  121007. + /* Free all free events. */
  121008. + while (Event->freeEventList != gcvNULL)
  121009. + {
  121010. + record = Event->freeEventList;
  121011. + Event->freeEventList = record->next;
  121012. +
  121013. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, record));
  121014. + }
  121015. +
  121016. + /* Delete the free mutex. */
  121017. + gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->freeEventMutex));
  121018. +
  121019. + /* Free all pending queues. */
  121020. + while (Event->queueHead != gcvNULL)
  121021. + {
  121022. + /* Get the current queue. */
  121023. + queue = Event->queueHead;
  121024. +
  121025. + /* Free all pending events. */
  121026. + while (queue->head != gcvNULL)
  121027. + {
  121028. + record = queue->head;
  121029. + queue->head = record->next;
  121030. +
  121031. + gcmkTRACE_ZONE_N(
  121032. + gcvLEVEL_WARNING, gcvZONE_EVENT,
  121033. + gcmSIZEOF(record) + gcmSIZEOF(queue->source),
  121034. + "Event record 0x%x is still pending for %d.",
  121035. + record, queue->source
  121036. + );
  121037. +
  121038. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, record));
  121039. + }
  121040. +
  121041. + /* Remove the top queue from the list. */
  121042. + if (Event->queueHead == Event->queueTail)
  121043. + {
  121044. + Event->queueHead =
  121045. + Event->queueTail = gcvNULL;
  121046. + }
  121047. + else
  121048. + {
  121049. + Event->queueHead = Event->queueHead->next;
  121050. + }
  121051. +
  121052. + /* Free the queue. */
  121053. + gcmkVERIFY_OK(gckEVENT_FreeQueue(Event, queue));
  121054. + }
  121055. +
  121056. + /* Delete the list mutex. */
  121057. + gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->eventListMutex));
  121058. +
  121059. + /* Delete the atom. */
  121060. + gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->freeAtom));
  121061. +
  121062. +#if gcdSMP
  121063. + gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->pending));
  121064. +#endif
  121065. +
  121066. + /* Mark the gckEVENT object as unknown. */
  121067. + Event->object.type = gcvOBJ_UNKNOWN;
  121068. +
  121069. + /* Free the gckEVENT object. */
  121070. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, Event));
  121071. +
  121072. + /* Success. */
  121073. + gcmkFOOTER_NO();
  121074. + return gcvSTATUS_OK;
  121075. +}
  121076. +
  121077. +/*******************************************************************************
  121078. +**
  121079. +** gckEVENT_GetEvent
  121080. +**
  121081. +** Reserve the next available hardware event.
  121082. +**
  121083. +** INPUT:
  121084. +**
  121085. +** gckEVENT Event
  121086. +** Pointer to an gckEVENT object.
  121087. +**
  121088. +** gctBOOL Wait
  121089. +** Set to gcvTRUE to force the function to wait if no events are
  121090. +** immediately available.
  121091. +**
  121092. +** gceKERNEL_WHERE Source
  121093. +** Source of the event.
  121094. +**
  121095. +** OUTPUT:
  121096. +**
  121097. +** gctUINT8 * EventID
  121098. +** Reserved event ID.
  121099. +*/
  121100. +static gceSTATUS
  121101. +gckEVENT_GetEvent(
  121102. + IN gckEVENT Event,
  121103. + IN gctBOOL Wait,
  121104. + OUT gctUINT8 * EventID,
  121105. + IN gcsEVENT_PTR Head,
  121106. + IN gceKERNEL_WHERE Source
  121107. + )
  121108. +{
  121109. + gctINT i, id;
  121110. + gceSTATUS status;
  121111. + gctBOOL acquired = gcvFALSE;
  121112. + gctINT32 free;
  121113. +
  121114. +#if gcdGPU_TIMEOUT
  121115. + gctUINT32 timer = 0;
  121116. +#endif
  121117. +
  121118. + gcmkHEADER_ARG("Event=0x%x Head=%p Source=%d", Event, Head, Source);
  121119. +
  121120. + while (gcvTRUE)
  121121. + {
  121122. + /* Grab the queue mutex. */
  121123. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  121124. + Event->eventQueueMutex,
  121125. + gcvINFINITE));
  121126. + acquired = gcvTRUE;
  121127. +
  121128. + /* Walk through all events. */
  121129. + id = Event->lastID;
  121130. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  121131. + {
  121132. + gctINT nextID = gckMATH_ModuloInt((id + 1),
  121133. + gcmCOUNTOF(Event->queues));
  121134. +
  121135. + if (Event->queues[id].head == gcvNULL)
  121136. + {
  121137. + *EventID = (gctUINT8) id;
  121138. +
  121139. + Event->lastID = (gctUINT8) nextID;
  121140. +
  121141. + /* Save time stamp of event. */
  121142. + Event->queues[id].stamp = ++(Event->stamp);
  121143. + Event->queues[id].head = Head;
  121144. + Event->queues[id].source = Source;
  121145. +
  121146. + gcmkONERROR(gckOS_AtomDecrement(Event->os,
  121147. + Event->freeAtom,
  121148. + &free));
  121149. +#if gcdDYNAMIC_SPEED
  121150. + if (free <= gcdDYNAMIC_EVENT_THRESHOLD)
  121151. + {
  121152. + gcmkONERROR(gckOS_BroadcastHurry(
  121153. + Event->os,
  121154. + Event->kernel->hardware,
  121155. + gcdDYNAMIC_EVENT_THRESHOLD - free));
  121156. + }
  121157. +#endif
  121158. +
  121159. + /* Release the queue mutex. */
  121160. + gcmkONERROR(gckOS_ReleaseMutex(Event->os,
  121161. + Event->eventQueueMutex));
  121162. +
  121163. + /* Success. */
  121164. + gcmkTRACE_ZONE_N(
  121165. + gcvLEVEL_INFO, gcvZONE_EVENT,
  121166. + gcmSIZEOF(id),
  121167. + "Using id=%d",
  121168. + id
  121169. + );
  121170. +
  121171. + gcmkFOOTER_ARG("*EventID=%u", *EventID);
  121172. + return gcvSTATUS_OK;
  121173. + }
  121174. +
  121175. + id = nextID;
  121176. + }
  121177. +
  121178. +#if gcdDYNAMIC_SPEED
  121179. + /* No free events, speed up the GPU right now! */
  121180. + gcmkONERROR(gckOS_BroadcastHurry(Event->os,
  121181. + Event->kernel->hardware,
  121182. + gcdDYNAMIC_EVENT_THRESHOLD));
  121183. +#endif
  121184. +
  121185. + /* Release the queue mutex. */
  121186. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  121187. + acquired = gcvFALSE;
  121188. +
  121189. + /* Fail if wait is not requested. */
  121190. + if (!Wait)
  121191. + {
  121192. + /* Out of resources. */
  121193. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  121194. + }
  121195. +
  121196. + /* Delay a while. */
  121197. + gcmkONERROR(gckOS_Delay(Event->os, 1));
  121198. +
  121199. +#if gcdGPU_TIMEOUT
  121200. + /* Increment the wait timer. */
  121201. + timer += 1;
  121202. +
  121203. + if (timer == Event->kernel->timeOut)
  121204. + {
  121205. + /* Try to call any outstanding events. */
  121206. + gcmkONERROR(gckHARDWARE_Interrupt(Event->kernel->hardware,
  121207. + gcvTRUE));
  121208. + }
  121209. + else if (timer > Event->kernel->timeOut)
  121210. + {
  121211. + gcmkTRACE_N(
  121212. + gcvLEVEL_ERROR,
  121213. + gcmSIZEOF(gctCONST_STRING) + gcmSIZEOF(gctINT),
  121214. + "%s(%d): no available events\n",
  121215. + __FUNCTION__, __LINE__
  121216. + );
  121217. +
  121218. + /* Bail out. */
  121219. + gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
  121220. + }
  121221. +#endif
  121222. + }
  121223. +
  121224. +OnError:
  121225. + if (acquired)
  121226. + {
  121227. + /* Release the queue mutex. */
  121228. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  121229. + }
  121230. +
  121231. + /* Return the status. */
  121232. + gcmkFOOTER();
  121233. + return status;
  121234. +}
  121235. +
  121236. +/*******************************************************************************
  121237. +**
  121238. +** gckEVENT_AllocateRecord
  121239. +**
  121240. +** Allocate a record for the new event.
  121241. +**
  121242. +** INPUT:
  121243. +**
  121244. +** gckEVENT Event
  121245. +** Pointer to an gckEVENT object.
  121246. +**
  121247. +** gctBOOL AllocateAllowed
  121248. +** State for allocation if out of free events.
  121249. +**
  121250. +** OUTPUT:
  121251. +**
  121252. +** gcsEVENT_PTR * Record
  121253. +** Allocated event record.
  121254. +*/
  121255. +gceSTATUS
  121256. +gckEVENT_AllocateRecord(
  121257. + IN gckEVENT Event,
  121258. + IN gctBOOL AllocateAllowed,
  121259. + OUT gcsEVENT_PTR * Record
  121260. + )
  121261. +{
  121262. + gceSTATUS status;
  121263. + gctBOOL acquired = gcvFALSE;
  121264. + gctINT i;
  121265. + gcsEVENT_PTR record;
  121266. + gctPOINTER pointer = gcvNULL;
  121267. +
  121268. + gcmkHEADER_ARG("Event=0x%x AllocateAllowed=%d", Event, AllocateAllowed);
  121269. +
  121270. + /* Verify the arguments. */
  121271. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121272. + gcmkVERIFY_ARGUMENT(Record != gcvNULL);
  121273. +
  121274. + /* Acquire the mutex. */
  121275. + gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->freeEventMutex, gcvINFINITE));
  121276. + acquired = gcvTRUE;
  121277. +
  121278. + /* Test if we are below the allocation threshold. */
  121279. + if ( (AllocateAllowed && (Event->freeEventCount < gcdEVENT_MIN_THRESHOLD)) ||
  121280. + (Event->freeEventCount == 0) )
  121281. + {
  121282. + /* Allocate a bunch of records. */
  121283. + for (i = 0; i < gcdEVENT_ALLOCATION_COUNT; i += 1)
  121284. + {
  121285. + /* Allocate an event record. */
  121286. + gcmkONERROR(gckOS_Allocate(Event->os,
  121287. + gcmSIZEOF(gcsEVENT),
  121288. + &pointer));
  121289. +
  121290. + record = pointer;
  121291. +
  121292. + /* Push it on the free list. */
  121293. + record->next = Event->freeEventList;
  121294. + Event->freeEventList = record;
  121295. + Event->freeEventCount += 1;
  121296. + }
  121297. + }
  121298. +
  121299. + *Record = Event->freeEventList;
  121300. + Event->freeEventList = Event->freeEventList->next;
  121301. + Event->freeEventCount -= 1;
  121302. +
  121303. + /* Release the mutex. */
  121304. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  121305. + acquired = gcvFALSE;
  121306. +
  121307. + /* Success. */
  121308. + gcmkFOOTER_ARG("*Record=0x%x", gcmOPT_POINTER(Record));
  121309. + return gcvSTATUS_OK;
  121310. +
  121311. +OnError:
  121312. + /* Roll back. */
  121313. + if (acquired)
  121314. + {
  121315. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  121316. + }
  121317. +
  121318. + /* Return the status. */
  121319. + gcmkFOOTER();
  121320. + return status;
  121321. +}
  121322. +
  121323. +/*******************************************************************************
  121324. +**
  121325. +** gckEVENT_AddList
  121326. +**
  121327. +** Add a new event to the list of events.
  121328. +**
  121329. +** INPUT:
  121330. +**
  121331. +** gckEVENT Event
  121332. +** Pointer to an gckEVENT object.
  121333. +**
  121334. +** gcsHAL_INTERFACE_PTR Interface
  121335. +** Pointer to the interface for the event to be added.
  121336. +**
  121337. +** gceKERNEL_WHERE FromWhere
  121338. +** Place in the pipe where the event needs to be generated.
  121339. +**
  121340. +** gctBOOL AllocateAllowed
  121341. +** State for allocation if out of free events.
  121342. +**
  121343. +** OUTPUT:
  121344. +**
  121345. +** Nothing.
  121346. +*/
  121347. +gceSTATUS
  121348. +gckEVENT_AddList(
  121349. + IN gckEVENT Event,
  121350. + IN gcsHAL_INTERFACE_PTR Interface,
  121351. + IN gceKERNEL_WHERE FromWhere,
  121352. + IN gctBOOL AllocateAllowed,
  121353. + IN gctBOOL FromKernel
  121354. + )
  121355. +{
  121356. + gceSTATUS status;
  121357. + gctBOOL acquired = gcvFALSE;
  121358. + gcsEVENT_PTR record = gcvNULL;
  121359. + gcsEVENT_QUEUE_PTR queue;
  121360. + gckKERNEL kernel = Event->kernel;
  121361. +
  121362. + gcmkHEADER_ARG("Event=0x%x Interface=0x%x",
  121363. + Event, Interface);
  121364. +
  121365. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, _GC_OBJ_ZONE,
  121366. + "FromWhere=%d AllocateAllowed=%d",
  121367. + FromWhere, AllocateAllowed);
  121368. +
  121369. + /* Verify the arguments. */
  121370. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121371. + gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
  121372. +
  121373. + /* Verify the event command. */
  121374. + gcmkASSERT
  121375. + ( (Interface->command == gcvHAL_FREE_NON_PAGED_MEMORY)
  121376. + || (Interface->command == gcvHAL_FREE_CONTIGUOUS_MEMORY)
  121377. + || (Interface->command == gcvHAL_FREE_VIDEO_MEMORY)
  121378. + || (Interface->command == gcvHAL_WRITE_DATA)
  121379. + || (Interface->command == gcvHAL_UNLOCK_VIDEO_MEMORY)
  121380. + || (Interface->command == gcvHAL_SIGNAL)
  121381. + || (Interface->command == gcvHAL_UNMAP_USER_MEMORY)
  121382. + || (Interface->command == gcvHAL_TIMESTAMP)
  121383. + || (Interface->command == gcvHAL_COMMIT_DONE)
  121384. + || (Interface->command == gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER)
  121385. + || (Interface->command == gcvHAL_SYNC_POINT)
  121386. + );
  121387. +
  121388. + /* Validate the source. */
  121389. + if ((FromWhere != gcvKERNEL_COMMAND) && (FromWhere != gcvKERNEL_PIXEL))
  121390. + {
  121391. + /* Invalid argument. */
  121392. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  121393. + }
  121394. +
  121395. + /* Allocate a free record. */
  121396. + gcmkONERROR(gckEVENT_AllocateRecord(Event, AllocateAllowed, &record));
  121397. +
  121398. + /* Termninate the record. */
  121399. + record->next = gcvNULL;
  121400. +
  121401. + /* Record the committer. */
  121402. + record->fromKernel = FromKernel;
  121403. +
  121404. + /* Copy the event interface into the record. */
  121405. + gckOS_MemCopy(&record->info, Interface, gcmSIZEOF(record->info));
  121406. +
  121407. + /* Get process ID. */
  121408. + gcmkONERROR(gckOS_GetProcessID(&record->processID));
  121409. +
  121410. +#ifdef __QNXNTO__
  121411. + record->kernel = Event->kernel;
  121412. +#endif
  121413. +
  121414. + gcmkONERROR(__RemoveRecordFromProcessDB(Event, record));
  121415. +
  121416. + /* Acquire the mutex. */
  121417. + gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->eventListMutex, gcvINFINITE));
  121418. + acquired = gcvTRUE;
  121419. +
  121420. + /* Do we need to allocate a new queue? */
  121421. + if ((Event->queueTail == gcvNULL) || (Event->queueTail->source < FromWhere))
  121422. + {
  121423. + /* Allocate a new queue. */
  121424. + gcmkONERROR(gckEVENT_AllocateQueue(Event, &queue));
  121425. +
  121426. + /* Initialize the queue. */
  121427. + queue->source = FromWhere;
  121428. + queue->head = gcvNULL;
  121429. + queue->next = gcvNULL;
  121430. +
  121431. + /* Attach it to the list of allocated queues. */
  121432. + if (Event->queueTail == gcvNULL)
  121433. + {
  121434. + Event->queueHead =
  121435. + Event->queueTail = queue;
  121436. + }
  121437. + else
  121438. + {
  121439. + Event->queueTail->next = queue;
  121440. + Event->queueTail = queue;
  121441. + }
  121442. + }
  121443. + else
  121444. + {
  121445. + queue = Event->queueTail;
  121446. + }
  121447. +
  121448. + /* Attach the record to the queue. */
  121449. + if (queue->head == gcvNULL)
  121450. + {
  121451. + queue->head = record;
  121452. + queue->tail = record;
  121453. + }
  121454. + else
  121455. + {
  121456. + queue->tail->next = record;
  121457. + queue->tail = record;
  121458. + }
  121459. +
  121460. + /* Unmap user space logical address.
  121461. + * Linux kernel does not support unmap the memory of other process any more since 3.5.
  121462. + * Let's unmap memory of self process before submit the event to gpu.
  121463. + * */
  121464. + switch(Interface->command)
  121465. + {
  121466. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  121467. + gcmkONERROR(gckOS_UnmapUserLogical(
  121468. + Event->os,
  121469. + gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical),
  121470. + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
  121471. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  121472. + break;
  121473. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  121474. + gcmkONERROR(gckOS_UnmapUserLogical(
  121475. + Event->os,
  121476. + gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical),
  121477. + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
  121478. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
  121479. + break;
  121480. + default:
  121481. + break;
  121482. + }
  121483. +
  121484. +
  121485. + /* Release the mutex. */
  121486. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  121487. +
  121488. + /* Success. */
  121489. + gcmkFOOTER_NO();
  121490. + return gcvSTATUS_OK;
  121491. +
  121492. +OnError:
  121493. + /* Roll back. */
  121494. + if (acquired)
  121495. + {
  121496. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  121497. + }
  121498. +
  121499. + if (record != gcvNULL)
  121500. + {
  121501. + gcmkVERIFY_OK(gckEVENT_FreeRecord(Event, record));
  121502. + }
  121503. +
  121504. + /* Return the status. */
  121505. + gcmkFOOTER();
  121506. + return status;
  121507. +}
  121508. +
  121509. +/*******************************************************************************
  121510. +**
  121511. +** gckEVENT_Unlock
  121512. +**
  121513. +** Schedule an event to unlock virtual memory.
  121514. +**
  121515. +** INPUT:
  121516. +**
  121517. +** gckEVENT Event
  121518. +** Pointer to an gckEVENT object.
  121519. +**
  121520. +** gceKERNEL_WHERE FromWhere
  121521. +** Place in the pipe where the event needs to be generated.
  121522. +**
  121523. +** gcuVIDMEM_NODE_PTR Node
  121524. +** Pointer to a gcuVIDMEM_NODE union that specifies the virtual memory
  121525. +** to unlock.
  121526. +**
  121527. +** gceSURF_TYPE Type
  121528. +** Type of surface to unlock.
  121529. +**
  121530. +** OUTPUT:
  121531. +**
  121532. +** Nothing.
  121533. +*/
  121534. +gceSTATUS
  121535. +gckEVENT_Unlock(
  121536. + IN gckEVENT Event,
  121537. + IN gceKERNEL_WHERE FromWhere,
  121538. + IN gcuVIDMEM_NODE_PTR Node,
  121539. + IN gceSURF_TYPE Type
  121540. + )
  121541. +{
  121542. + gceSTATUS status;
  121543. + gcsHAL_INTERFACE iface;
  121544. +
  121545. + gcmkHEADER_ARG("Event=0x%x FromWhere=%d Node=0x%x Type=%d",
  121546. + Event, FromWhere, Node, Type);
  121547. +
  121548. + /* Verify the arguments. */
  121549. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121550. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  121551. +
  121552. + /* Mark the event as an unlock. */
  121553. + iface.command = gcvHAL_UNLOCK_VIDEO_MEMORY;
  121554. + iface.u.UnlockVideoMemory.node = gcmPTR_TO_UINT64(Node);
  121555. + iface.u.UnlockVideoMemory.type = Type;
  121556. + iface.u.UnlockVideoMemory.asynchroneous = 0;
  121557. +
  121558. + /* Append it to the queue. */
  121559. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121560. +
  121561. + /* Success. */
  121562. + gcmkFOOTER_NO();
  121563. + return gcvSTATUS_OK;
  121564. +
  121565. +OnError:
  121566. + /* Return the status. */
  121567. + gcmkFOOTER();
  121568. + return status;
  121569. +}
  121570. +
  121571. +/*******************************************************************************
  121572. +**
  121573. +** gckEVENT_FreeVideoMemory
  121574. +**
  121575. +** Schedule an event to free video memory.
  121576. +**
  121577. +** INPUT:
  121578. +**
  121579. +** gckEVENT Event
  121580. +** Pointer to an gckEVENT object.
  121581. +**
  121582. +** gcuVIDMEM_NODE_PTR VideoMemory
  121583. +** Pointer to a gcuVIDMEM_NODE object to free.
  121584. +**
  121585. +** gceKERNEL_WHERE FromWhere
  121586. +** Place in the pipe where the event needs to be generated.
  121587. +**
  121588. +** OUTPUT:
  121589. +**
  121590. +** Nothing.
  121591. +*/
  121592. +gceSTATUS
  121593. +gckEVENT_FreeVideoMemory(
  121594. + IN gckEVENT Event,
  121595. + IN gcuVIDMEM_NODE_PTR VideoMemory,
  121596. + IN gceKERNEL_WHERE FromWhere
  121597. + )
  121598. +{
  121599. + gceSTATUS status;
  121600. + gcsHAL_INTERFACE iface;
  121601. +
  121602. + gcmkHEADER_ARG("Event=0x%x VideoMemory=0x%x FromWhere=%d",
  121603. + Event, VideoMemory, FromWhere);
  121604. +
  121605. + /* Verify the arguments. */
  121606. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121607. + gcmkVERIFY_ARGUMENT(VideoMemory != gcvNULL);
  121608. +
  121609. + /* Create an event. */
  121610. + iface.command = gcvHAL_FREE_VIDEO_MEMORY;
  121611. + iface.u.FreeVideoMemory.node = gcmPTR_TO_UINT64(VideoMemory);
  121612. +
  121613. + /* Append it to the queue. */
  121614. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121615. +
  121616. + /* Success. */
  121617. + gcmkFOOTER_NO();
  121618. + return gcvSTATUS_OK;
  121619. +
  121620. +OnError:
  121621. + /* Return the status. */
  121622. + gcmkFOOTER();
  121623. + return status;
  121624. +}
  121625. +
  121626. +/*******************************************************************************
  121627. +**
  121628. +** gckEVENT_FreeNonPagedMemory
  121629. +**
  121630. +** Schedule an event to free non-paged memory.
  121631. +**
  121632. +** INPUT:
  121633. +**
  121634. +** gckEVENT Event
  121635. +** Pointer to an gckEVENT object.
  121636. +**
  121637. +** gctSIZE_T Bytes
  121638. +** Number of bytes of non-paged memory to free.
  121639. +**
  121640. +** gctPHYS_ADDR Physical
  121641. +** Physical address of non-paged memory to free.
  121642. +**
  121643. +** gctPOINTER Logical
  121644. +** Logical address of non-paged memory to free.
  121645. +**
  121646. +** gceKERNEL_WHERE FromWhere
  121647. +** Place in the pipe where the event needs to be generated.
  121648. +*/
  121649. +gceSTATUS
  121650. +gckEVENT_FreeNonPagedMemory(
  121651. + IN gckEVENT Event,
  121652. + IN gctSIZE_T Bytes,
  121653. + IN gctPHYS_ADDR Physical,
  121654. + IN gctPOINTER Logical,
  121655. + IN gceKERNEL_WHERE FromWhere
  121656. + )
  121657. +{
  121658. + gceSTATUS status;
  121659. + gcsHAL_INTERFACE iface;
  121660. + gckKERNEL kernel = Event->kernel;
  121661. +
  121662. + gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
  121663. + "FromWhere=%d",
  121664. + Event, Bytes, Physical, Logical, FromWhere);
  121665. +
  121666. + /* Verify the arguments. */
  121667. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121668. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  121669. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  121670. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  121671. +
  121672. + /* Create an event. */
  121673. + iface.command = gcvHAL_FREE_NON_PAGED_MEMORY;
  121674. + iface.u.FreeNonPagedMemory.bytes = Bytes;
  121675. + iface.u.FreeNonPagedMemory.physical = gcmPTR_TO_NAME(Physical);
  121676. + iface.u.FreeNonPagedMemory.logical = gcmPTR_TO_UINT64(Logical);
  121677. +
  121678. + /* Append it to the queue. */
  121679. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121680. +
  121681. + /* Success. */
  121682. + gcmkFOOTER_NO();
  121683. + return gcvSTATUS_OK;
  121684. +
  121685. +OnError:
  121686. + /* Return the status. */
  121687. + gcmkFOOTER();
  121688. + return status;
  121689. +}
  121690. +
  121691. +gceSTATUS
  121692. +gckEVENT_DestroyVirtualCommandBuffer(
  121693. + IN gckEVENT Event,
  121694. + IN gctSIZE_T Bytes,
  121695. + IN gctPHYS_ADDR Physical,
  121696. + IN gctPOINTER Logical,
  121697. + IN gceKERNEL_WHERE FromWhere
  121698. + )
  121699. +{
  121700. + gceSTATUS status;
  121701. + gcsHAL_INTERFACE iface;
  121702. + gckKERNEL kernel = Event->kernel;
  121703. +
  121704. + gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
  121705. + "FromWhere=%d",
  121706. + Event, Bytes, Physical, Logical, FromWhere);
  121707. +
  121708. + /* Verify the arguments. */
  121709. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121710. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  121711. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  121712. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  121713. +
  121714. + /* Create an event. */
  121715. + iface.command = gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER;
  121716. + iface.u.FreeVirtualCommandBuffer.bytes = Bytes;
  121717. + iface.u.FreeVirtualCommandBuffer.physical = gcmPTR_TO_NAME(Physical);
  121718. + iface.u.FreeVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(Logical);
  121719. +
  121720. + /* Append it to the queue. */
  121721. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121722. +
  121723. + /* Success. */
  121724. + gcmkFOOTER_NO();
  121725. + return gcvSTATUS_OK;
  121726. +
  121727. +OnError:
  121728. + /* Return the status. */
  121729. + gcmkFOOTER();
  121730. + return status;
  121731. +}
  121732. +
  121733. +/*******************************************************************************
  121734. +**
  121735. +** gckEVENT_FreeContigiuousMemory
  121736. +**
  121737. +** Schedule an event to free contiguous memory.
  121738. +**
  121739. +** INPUT:
  121740. +**
  121741. +** gckEVENT Event
  121742. +** Pointer to an gckEVENT object.
  121743. +**
  121744. +** gctSIZE_T Bytes
  121745. +** Number of bytes of contiguous memory to free.
  121746. +**
  121747. +** gctPHYS_ADDR Physical
  121748. +** Physical address of contiguous memory to free.
  121749. +**
  121750. +** gctPOINTER Logical
  121751. +** Logical address of contiguous memory to free.
  121752. +**
  121753. +** gceKERNEL_WHERE FromWhere
  121754. +** Place in the pipe where the event needs to be generated.
  121755. +*/
  121756. +gceSTATUS
  121757. +gckEVENT_FreeContiguousMemory(
  121758. + IN gckEVENT Event,
  121759. + IN gctSIZE_T Bytes,
  121760. + IN gctPHYS_ADDR Physical,
  121761. + IN gctPOINTER Logical,
  121762. + IN gceKERNEL_WHERE FromWhere
  121763. + )
  121764. +{
  121765. + gceSTATUS status;
  121766. + gcsHAL_INTERFACE iface;
  121767. + gckKERNEL kernel = Event->kernel;
  121768. +
  121769. + gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
  121770. + "FromWhere=%d",
  121771. + Event, Bytes, Physical, Logical, FromWhere);
  121772. +
  121773. + /* Verify the arguments. */
  121774. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121775. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  121776. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  121777. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  121778. +
  121779. + /* Create an event. */
  121780. + iface.command = gcvHAL_FREE_CONTIGUOUS_MEMORY;
  121781. + iface.u.FreeContiguousMemory.bytes = Bytes;
  121782. + iface.u.FreeContiguousMemory.physical = gcmPTR_TO_NAME(Physical);
  121783. + iface.u.FreeContiguousMemory.logical = gcmPTR_TO_UINT64(Logical);
  121784. +
  121785. + /* Append it to the queue. */
  121786. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121787. +
  121788. + /* Success. */
  121789. + gcmkFOOTER_NO();
  121790. + return gcvSTATUS_OK;
  121791. +
  121792. +OnError:
  121793. + /* Return the status. */
  121794. + gcmkFOOTER();
  121795. + return status;
  121796. +}
  121797. +
  121798. +/*******************************************************************************
  121799. +**
  121800. +** gckEVENT_Signal
  121801. +**
  121802. +** Schedule an event to trigger a signal.
  121803. +**
  121804. +** INPUT:
  121805. +**
  121806. +** gckEVENT Event
  121807. +** Pointer to an gckEVENT object.
  121808. +**
  121809. +** gctSIGNAL Signal
  121810. +** Pointer to the signal to trigger.
  121811. +**
  121812. +** gceKERNEL_WHERE FromWhere
  121813. +** Place in the pipe where the event needs to be generated.
  121814. +**
  121815. +** OUTPUT:
  121816. +**
  121817. +** Nothing.
  121818. +*/
  121819. +gceSTATUS
  121820. +gckEVENT_Signal(
  121821. + IN gckEVENT Event,
  121822. + IN gctSIGNAL Signal,
  121823. + IN gceKERNEL_WHERE FromWhere
  121824. + )
  121825. +{
  121826. + gceSTATUS status;
  121827. + gcsHAL_INTERFACE iface;
  121828. +
  121829. + gcmkHEADER_ARG("Event=0x%x Signal=0x%x FromWhere=%d",
  121830. + Event, Signal, FromWhere);
  121831. +
  121832. + /* Verify the arguments. */
  121833. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121834. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  121835. +
  121836. + /* Mark the event as a signal. */
  121837. + iface.command = gcvHAL_SIGNAL;
  121838. + iface.u.Signal.signal = gcmPTR_TO_UINT64(Signal);
  121839. +#ifdef __QNXNTO__
  121840. + iface.u.Signal.coid = 0;
  121841. + iface.u.Signal.rcvid = 0;
  121842. +#endif
  121843. + iface.u.Signal.auxSignal = 0;
  121844. + iface.u.Signal.process = 0;
  121845. +
  121846. + /* Append it to the queue. */
  121847. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121848. +
  121849. + /* Success. */
  121850. + gcmkFOOTER_NO();
  121851. + return gcvSTATUS_OK;
  121852. +
  121853. +OnError:
  121854. + /* Return the status. */
  121855. + gcmkFOOTER();
  121856. + return status;
  121857. +}
  121858. +
  121859. +/*******************************************************************************
  121860. +**
  121861. +** gckEVENT_CommitDone
  121862. +**
  121863. +** Schedule an event to wake up work thread when commit is done by GPU.
  121864. +**
  121865. +** INPUT:
  121866. +**
  121867. +** gckEVENT Event
  121868. +** Pointer to an gckEVENT object.
  121869. +**
  121870. +** gceKERNEL_WHERE FromWhere
  121871. +** Place in the pipe where the event needs to be generated.
  121872. +**
  121873. +** OUTPUT:
  121874. +**
  121875. +** Nothing.
  121876. +*/
  121877. +gceSTATUS
  121878. +gckEVENT_CommitDone(
  121879. + IN gckEVENT Event,
  121880. + IN gceKERNEL_WHERE FromWhere
  121881. + )
  121882. +{
  121883. + gceSTATUS status;
  121884. + gcsHAL_INTERFACE iface;
  121885. +
  121886. + gcmkHEADER_ARG("Event=0x%x FromWhere=%d", Event, FromWhere);
  121887. +
  121888. + /* Verify the arguments. */
  121889. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  121890. +
  121891. + iface.command = gcvHAL_COMMIT_DONE;
  121892. +
  121893. + /* Append it to the queue. */
  121894. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  121895. +
  121896. + /* Success. */
  121897. + gcmkFOOTER_NO();
  121898. + return gcvSTATUS_OK;
  121899. +
  121900. +OnError:
  121901. + /* Return the status. */
  121902. + gcmkFOOTER();
  121903. + return status;
  121904. +}
  121905. +/*******************************************************************************
  121906. +**
  121907. +** gckEVENT_Submit
  121908. +**
  121909. +** Submit the current event queue to the GPU.
  121910. +**
  121911. +** INPUT:
  121912. +**
  121913. +** gckEVENT Event
  121914. +** Pointer to an gckEVENT object.
  121915. +**
  121916. +** gctBOOL Wait
  121917. +** Submit requires one vacant event; if Wait is set to not zero,
  121918. +** and there are no vacant events at this time, the function will
  121919. +** wait until an event becomes vacant so that submission of the
  121920. +** queue is successful.
  121921. +**
  121922. +** gctBOOL FromPower
  121923. +** Determines whether the call originates from inside the power
  121924. +** management or not.
  121925. +**
  121926. +** OUTPUT:
  121927. +**
  121928. +** Nothing.
  121929. +*/
  121930. +gceSTATUS
  121931. +gckEVENT_Submit(
  121932. + IN gckEVENT Event,
  121933. + IN gctBOOL Wait,
  121934. + IN gctBOOL FromPower
  121935. + )
  121936. +{
  121937. + gceSTATUS status;
  121938. + gctUINT8 id = 0xFF;
  121939. + gcsEVENT_QUEUE_PTR queue;
  121940. + gctBOOL acquired = gcvFALSE;
  121941. + gckCOMMAND command = gcvNULL;
  121942. + gctBOOL commitEntered = gcvFALSE;
  121943. +#if !gcdNULL_DRIVER
  121944. + gctSIZE_T bytes;
  121945. + gctPOINTER buffer;
  121946. +#endif
  121947. +
  121948. + gcmkHEADER_ARG("Event=0x%x Wait=%d", Event, Wait);
  121949. +
  121950. + /* Get gckCOMMAND object. */
  121951. + command = Event->kernel->command;
  121952. +
  121953. + /* Are there event queues? */
  121954. + if (Event->queueHead != gcvNULL)
  121955. + {
  121956. + /* Acquire the command queue. */
  121957. + gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
  121958. + commitEntered = gcvTRUE;
  121959. +
  121960. + /* Process all queues. */
  121961. + while (Event->queueHead != gcvNULL)
  121962. + {
  121963. + /* Acquire the list mutex. */
  121964. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  121965. + Event->eventListMutex,
  121966. + gcvINFINITE));
  121967. + acquired = gcvTRUE;
  121968. +
  121969. + /* Get the current queue. */
  121970. + queue = Event->queueHead;
  121971. +
  121972. + /* Allocate an event ID. */
  121973. + gcmkONERROR(gckEVENT_GetEvent(Event, Wait, &id, queue->head, queue->source));
  121974. +
  121975. + /* Copy event list to event ID queue. */
  121976. + Event->queues[id].head = queue->head;
  121977. +
  121978. + /* Remove the top queue from the list. */
  121979. + if (Event->queueHead == Event->queueTail)
  121980. + {
  121981. + Event->queueHead = gcvNULL;
  121982. + Event->queueTail = gcvNULL;
  121983. + }
  121984. + else
  121985. + {
  121986. + Event->queueHead = Event->queueHead->next;
  121987. + }
  121988. +
  121989. + /* Free the queue. */
  121990. + gcmkONERROR(gckEVENT_FreeQueue(Event, queue));
  121991. +
  121992. + /* Release the list mutex. */
  121993. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  121994. + acquired = gcvFALSE;
  121995. +
  121996. +#if gcdNULL_DRIVER
  121997. + /* Notify immediately on infinite hardware. */
  121998. + gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id));
  121999. +
  122000. + gcmkONERROR(gckEVENT_Notify(Event, 0));
  122001. +#else
  122002. + /* Get the size of the hardware event. */
  122003. + gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware,
  122004. + gcvNULL,
  122005. + id,
  122006. + Event->queues[id].source,
  122007. + &bytes));
  122008. +
  122009. + /* Reserve space in the command queue. */
  122010. + gcmkONERROR(gckCOMMAND_Reserve(command,
  122011. + bytes,
  122012. + &buffer,
  122013. + &bytes));
  122014. +
  122015. + /* Set the hardware event in the command queue. */
  122016. + gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware,
  122017. + buffer,
  122018. + id,
  122019. + Event->queues[id].source,
  122020. + &bytes));
  122021. +
  122022. + /* Execute the hardware event. */
  122023. + gcmkONERROR(gckCOMMAND_Execute(command, bytes));
  122024. +#endif
  122025. + }
  122026. +
  122027. + /* Release the command queue. */
  122028. + gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
  122029. + commitEntered = gcvFALSE;
  122030. + }
  122031. +
  122032. + /* Success. */
  122033. + gcmkFOOTER_NO();
  122034. + return gcvSTATUS_OK;
  122035. +
  122036. +OnError:
  122037. + if (commitEntered)
  122038. + {
  122039. + /* Release the command queue mutex. */
  122040. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, FromPower));
  122041. + }
  122042. +
  122043. + if (acquired)
  122044. + {
  122045. + /* Need to unroll the mutex acquire. */
  122046. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  122047. + }
  122048. +
  122049. + if (id != 0xFF)
  122050. + {
  122051. + /* Need to unroll the event allocation. */
  122052. + Event->queues[id].head = gcvNULL;
  122053. + }
  122054. +
  122055. + if (status == gcvSTATUS_GPU_NOT_RESPONDING)
  122056. + {
  122057. + /* Broadcast GPU stuck. */
  122058. + status = gckOS_Broadcast(Event->os,
  122059. + Event->kernel->hardware,
  122060. + gcvBROADCAST_GPU_STUCK);
  122061. + }
  122062. +
  122063. + /* Return the status. */
  122064. + gcmkFOOTER();
  122065. + return status;
  122066. +}
  122067. +
  122068. +/*******************************************************************************
  122069. +**
  122070. +** gckEVENT_Commit
  122071. +**
  122072. +** Commit an event queue from the user.
  122073. +**
  122074. +** INPUT:
  122075. +**
  122076. +** gckEVENT Event
  122077. +** Pointer to an gckEVENT object.
  122078. +**
  122079. +** gcsQUEUE_PTR Queue
  122080. +** User event queue.
  122081. +**
  122082. +** OUTPUT:
  122083. +**
  122084. +** Nothing.
  122085. +*/
  122086. +gceSTATUS
  122087. +gckEVENT_Commit(
  122088. + IN gckEVENT Event,
  122089. + IN gcsQUEUE_PTR Queue
  122090. + )
  122091. +{
  122092. + gceSTATUS status;
  122093. + gcsQUEUE_PTR record = gcvNULL, next;
  122094. + gctUINT32 processID;
  122095. + gctBOOL needCopy = gcvFALSE;
  122096. +
  122097. + gcmkHEADER_ARG("Event=0x%x Queue=0x%x", Event, Queue);
  122098. +
  122099. + /* Verify the arguments. */
  122100. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122101. +
  122102. + /* Get the current process ID. */
  122103. + gcmkONERROR(gckOS_GetProcessID(&processID));
  122104. +
  122105. + /* Query if we need to copy the client data. */
  122106. + gcmkONERROR(gckOS_QueryNeedCopy(Event->os, processID, &needCopy));
  122107. +
  122108. + /* Loop while there are records in the queue. */
  122109. + while (Queue != gcvNULL)
  122110. + {
  122111. + gcsQUEUE queue;
  122112. +
  122113. + if (needCopy)
  122114. + {
  122115. + /* Point to stack record. */
  122116. + record = &queue;
  122117. +
  122118. + /* Copy the data from the client. */
  122119. + gcmkONERROR(gckOS_CopyFromUserData(Event->os,
  122120. + record,
  122121. + Queue,
  122122. + gcmSIZEOF(gcsQUEUE)));
  122123. + }
  122124. + else
  122125. + {
  122126. + gctPOINTER pointer = gcvNULL;
  122127. +
  122128. + /* Map record into kernel memory. */
  122129. + gcmkONERROR(gckOS_MapUserPointer(Event->os,
  122130. + Queue,
  122131. + gcmSIZEOF(gcsQUEUE),
  122132. + &pointer));
  122133. +
  122134. + record = pointer;
  122135. + }
  122136. +
  122137. + /* Append event record to event queue. */
  122138. + gcmkONERROR(
  122139. + gckEVENT_AddList(Event, &record->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE));
  122140. +
  122141. + /* Next record in the queue. */
  122142. + next = gcmUINT64_TO_PTR(record->next);
  122143. +
  122144. + if (!needCopy)
  122145. + {
  122146. + /* Unmap record from kernel memory. */
  122147. + gcmkONERROR(
  122148. + gckOS_UnmapUserPointer(Event->os,
  122149. + Queue,
  122150. + gcmSIZEOF(gcsQUEUE),
  122151. + (gctPOINTER *) record));
  122152. + record = gcvNULL;
  122153. + }
  122154. +
  122155. + Queue = next;
  122156. + }
  122157. +
  122158. + /* Submit the event list. */
  122159. + gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE));
  122160. +
  122161. + /* Success */
  122162. + gcmkFOOTER_NO();
  122163. + return gcvSTATUS_OK;
  122164. +
  122165. +OnError:
  122166. + if ((record != gcvNULL) && !needCopy)
  122167. + {
  122168. + /* Roll back. */
  122169. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(Event->os,
  122170. + Queue,
  122171. + gcmSIZEOF(gcsQUEUE),
  122172. + (gctPOINTER *) record));
  122173. + }
  122174. +
  122175. + /* Return the status. */
  122176. + gcmkFOOTER();
  122177. + return status;
  122178. +}
  122179. +
  122180. +/*******************************************************************************
  122181. +**
  122182. +** gckEVENT_Compose
  122183. +**
  122184. +** Schedule a composition event and start a composition.
  122185. +**
  122186. +** INPUT:
  122187. +**
  122188. +** gckEVENT Event
  122189. +** Pointer to an gckEVENT object.
  122190. +**
  122191. +** gcsHAL_COMPOSE_PTR Info
  122192. +** Pointer to the composition structure.
  122193. +**
  122194. +** OUTPUT:
  122195. +**
  122196. +** Nothing.
  122197. +*/
  122198. +gceSTATUS
  122199. +gckEVENT_Compose(
  122200. + IN gckEVENT Event,
  122201. + IN gcsHAL_COMPOSE_PTR Info
  122202. + )
  122203. +{
  122204. + gceSTATUS status;
  122205. + gcsEVENT_PTR headRecord;
  122206. + gcsEVENT_PTR tailRecord;
  122207. + gcsEVENT_PTR tempRecord;
  122208. + gctUINT8 id = 0xFF;
  122209. + gctUINT32 processID;
  122210. +
  122211. + gcmkHEADER_ARG("Event=0x%x Info=0x%x", Event, Info);
  122212. +
  122213. + /* Verify the arguments. */
  122214. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122215. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  122216. +
  122217. + /* Get process ID. */
  122218. + gcmkONERROR(gckOS_GetProcessID(&processID));
  122219. +
  122220. + /* Allocate a record. */
  122221. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &tempRecord));
  122222. + headRecord = tailRecord = tempRecord;
  122223. +
  122224. + /* Initialize the record. */
  122225. + tempRecord->info.command = gcvHAL_SIGNAL;
  122226. + tempRecord->info.u.Signal.process = Info->process;
  122227. +#ifdef __QNXNTO__
  122228. + tempRecord->info.u.Signal.coid = Info->coid;
  122229. + tempRecord->info.u.Signal.rcvid = Info->rcvid;
  122230. +#endif
  122231. + tempRecord->info.u.Signal.signal = Info->signal;
  122232. + tempRecord->info.u.Signal.auxSignal = 0;
  122233. + tempRecord->next = gcvNULL;
  122234. + tempRecord->processID = processID;
  122235. +
  122236. + /* Allocate another record for user signal #1. */
  122237. + if (gcmUINT64_TO_PTR(Info->userSignal1) != gcvNULL)
  122238. + {
  122239. + /* Allocate a record. */
  122240. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &tempRecord));
  122241. + tailRecord->next = tempRecord;
  122242. + tailRecord = tempRecord;
  122243. +
  122244. + /* Initialize the record. */
  122245. + tempRecord->info.command = gcvHAL_SIGNAL;
  122246. + tempRecord->info.u.Signal.process = Info->userProcess;
  122247. +#ifdef __QNXNTO__
  122248. + tempRecord->info.u.Signal.coid = Info->coid;
  122249. + tempRecord->info.u.Signal.rcvid = Info->rcvid;
  122250. +#endif
  122251. + tempRecord->info.u.Signal.signal = Info->userSignal1;
  122252. + tempRecord->info.u.Signal.auxSignal = 0;
  122253. + tempRecord->next = gcvNULL;
  122254. + tempRecord->processID = processID;
  122255. + }
  122256. +
  122257. + /* Allocate another record for user signal #2. */
  122258. + if (gcmUINT64_TO_PTR(Info->userSignal2) != gcvNULL)
  122259. + {
  122260. + /* Allocate a record. */
  122261. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &tempRecord));
  122262. + tailRecord->next = tempRecord;
  122263. + tailRecord = tempRecord;
  122264. +
  122265. + /* Initialize the record. */
  122266. + tempRecord->info.command = gcvHAL_SIGNAL;
  122267. + tempRecord->info.u.Signal.process = Info->userProcess;
  122268. +#ifdef __QNXNTO__
  122269. + tempRecord->info.u.Signal.coid = Info->coid;
  122270. + tempRecord->info.u.Signal.rcvid = Info->rcvid;
  122271. +#endif
  122272. + tempRecord->info.u.Signal.signal = Info->userSignal2;
  122273. + tempRecord->info.u.Signal.auxSignal = 0;
  122274. + tempRecord->next = gcvNULL;
  122275. + tempRecord->processID = processID;
  122276. + }
  122277. +
  122278. + /* Allocate an event ID. */
  122279. + gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, headRecord, gcvKERNEL_PIXEL));
  122280. +
  122281. + /* Start composition. */
  122282. + gcmkONERROR(gckHARDWARE_Compose(
  122283. + Event->kernel->hardware, processID,
  122284. + gcmUINT64_TO_PTR(Info->physical), gcmUINT64_TO_PTR(Info->logical), Info->offset, Info->size, id
  122285. + ));
  122286. +
  122287. + /* Success. */
  122288. + gcmkFOOTER_NO();
  122289. + return gcvSTATUS_OK;
  122290. +
  122291. +OnError:
  122292. + /* Return the status. */
  122293. + gcmkFOOTER();
  122294. + return status;
  122295. +}
  122296. +
  122297. +/*******************************************************************************
  122298. +**
  122299. +** gckEVENT_Interrupt
  122300. +**
  122301. +** Called by the interrupt service routine to store the triggered interrupt
  122302. +** mask to be later processed by gckEVENT_Notify.
  122303. +**
  122304. +** INPUT:
  122305. +**
  122306. +** gckEVENT Event
  122307. +** Pointer to an gckEVENT object.
  122308. +**
  122309. +** gctUINT32 Data
  122310. +** Mask for the 32 interrupts.
  122311. +**
  122312. +** OUTPUT:
  122313. +**
  122314. +** Nothing.
  122315. +*/
  122316. +gceSTATUS
  122317. +gckEVENT_Interrupt(
  122318. + IN gckEVENT Event,
  122319. + IN gctUINT32 Data
  122320. + )
  122321. +{
  122322. + unsigned long flags;
  122323. + gcmkHEADER_ARG("Event=0x%x Data=0x%x", Event, Data);
  122324. +
  122325. + /* Verify the arguments. */
  122326. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122327. +
  122328. + /* Combine current interrupt status with pending flags. */
  122329. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  122330. +#if gcdSMP
  122331. + gckOS_AtomSetMask(Event->pending, Data);
  122332. +#elif defined(__QNXNTO__)
  122333. + atomic_set(&Event->pending, Data);
  122334. +#else
  122335. + Event->pending |= Data;
  122336. +#endif
  122337. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  122338. +
  122339. + /* Success. */
  122340. + gcmkFOOTER_NO();
  122341. + return gcvSTATUS_OK;
  122342. +}
  122343. +
  122344. +/*******************************************************************************
  122345. +**
  122346. +** gckEVENT_Notify
  122347. +**
  122348. +** Process all triggered interrupts.
  122349. +**
  122350. +** INPUT:
  122351. +**
  122352. +** gckEVENT Event
  122353. +** Pointer to an gckEVENT object.
  122354. +**
  122355. +** OUTPUT:
  122356. +**
  122357. +** Nothing.
  122358. +*/
  122359. +gceSTATUS
  122360. +gckEVENT_Notify(
  122361. + IN gckEVENT Event,
  122362. + IN gctUINT32 IDs
  122363. + )
  122364. +{
  122365. + gceSTATUS status = gcvSTATUS_OK;
  122366. + gctINT i;
  122367. + gcsEVENT_QUEUE * queue;
  122368. + gctUINT mask = 0;
  122369. + gctBOOL acquired = gcvFALSE;
  122370. + gcuVIDMEM_NODE_PTR node;
  122371. + gctPOINTER info;
  122372. + gctSIGNAL signal;
  122373. + gctUINT pending;
  122374. + gckKERNEL kernel = Event->kernel;
  122375. +#if !gcdSMP
  122376. + gctBOOL suspended = gcvFALSE;
  122377. +#endif
  122378. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  122379. + gctINT eventNumber = 0;
  122380. +#endif
  122381. + gctINT32 free;
  122382. +#if gcdSECURE_USER
  122383. + gcskSECURE_CACHE_PTR cache;
  122384. +#endif
  122385. + unsigned long flags;
  122386. +
  122387. + gcmkHEADER_ARG("Event=0x%x IDs=0x%x", Event, IDs);
  122388. +
  122389. + /* Verify the arguments. */
  122390. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122391. +
  122392. + gcmDEBUG_ONLY(
  122393. + if (IDs != 0)
  122394. + {
  122395. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  122396. + {
  122397. + if (Event->queues[i].head != gcvNULL)
  122398. + {
  122399. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122400. + "Queue(%d): stamp=%llu source=%d",
  122401. + i,
  122402. + Event->queues[i].stamp,
  122403. + Event->queues[i].source);
  122404. + }
  122405. + }
  122406. + }
  122407. + );
  122408. +
  122409. + for (;;)
  122410. + {
  122411. + gcsEVENT_PTR record;
  122412. +
  122413. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  122414. +#if gcdSMP
  122415. + /* Get current interrupts. */
  122416. + gckOS_AtomGet(Event->os, Event->pending, (gctINT32_PTR)&pending);
  122417. +#else
  122418. + /* Get current interrupts. */
  122419. + pending = Event->pending;
  122420. +#endif
  122421. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  122422. +
  122423. + if (pending & 0x80000000)
  122424. + {
  122425. + //gckOS_Print("!!!!!!!!!!!!! AXI BUS ERROR !!!!!!!!!!!!!\n");
  122426. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_EVENT, "AXI BUS ERROR");
  122427. + pending &= 0x7FFFFFFF;
  122428. + }
  122429. +
  122430. + if (pending & 0x40000000)
  122431. + {
  122432. + gckHARDWARE_DumpMMUException(Event->kernel->hardware);
  122433. +
  122434. + pending &= 0x3FFFFFFF;
  122435. + }
  122436. +
  122437. + gcmkTRACE_ZONE_N(
  122438. + gcvLEVEL_INFO, gcvZONE_EVENT,
  122439. + gcmSIZEOF(pending),
  122440. + "Pending interrupts 0x%x",
  122441. + pending
  122442. + );
  122443. +
  122444. + if (pending == 0)
  122445. + {
  122446. + /* No more pending interrupts - done. */
  122447. + break;
  122448. + }
  122449. +
  122450. + queue = gcvNULL;
  122451. +
  122452. + /* Grab the mutex queue. */
  122453. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  122454. + Event->eventQueueMutex,
  122455. + gcvINFINITE));
  122456. + acquired = gcvTRUE;
  122457. +
  122458. + gcmDEBUG_ONLY(
  122459. + if (IDs == 0)
  122460. + {
  122461. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  122462. + {
  122463. + if (Event->queues[i].head != gcvNULL)
  122464. + {
  122465. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122466. + "Queue(%d): stamp=%llu source=%d",
  122467. + i,
  122468. + Event->queues[i].stamp,
  122469. + Event->queues[i].source);
  122470. + }
  122471. + }
  122472. + }
  122473. + );
  122474. +
  122475. + /* Find the oldest pending interrupt. */
  122476. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  122477. + {
  122478. + if ((Event->queues[i].head != gcvNULL)
  122479. + && (pending & (1 << i))
  122480. + )
  122481. + {
  122482. + if ((queue == gcvNULL)
  122483. + || (Event->queues[i].stamp < queue->stamp)
  122484. + )
  122485. + {
  122486. + queue = &Event->queues[i];
  122487. + mask = 1 << i;
  122488. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  122489. + eventNumber = i;
  122490. +#endif
  122491. + }
  122492. + }
  122493. + }
  122494. +
  122495. + if (queue == gcvNULL)
  122496. + {
  122497. + gcmkTRACE_ZONE_N(
  122498. + gcvLEVEL_ERROR, gcvZONE_EVENT,
  122499. + gcmSIZEOF(pending),
  122500. + "Interrupts 0x%x are not pending.",
  122501. + pending
  122502. + );
  122503. +
  122504. + /* Release the mutex queue. */
  122505. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  122506. + acquired = gcvFALSE;
  122507. +
  122508. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  122509. +#if gcdSMP
  122510. + /* Mark pending interrupts as handled. */
  122511. + gckOS_AtomClearMask(Event->pending, pending);
  122512. +#elif defined(__QNXNTO__)
  122513. + /* Mark pending interrupts as handled. */
  122514. + atomic_clr((gctUINT32_PTR)&Event->pending, pending);
  122515. +#else
  122516. + /* Mark pending interrupts as handled. */
  122517. + Event->pending &= ~pending;
  122518. +#endif
  122519. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  122520. + break;
  122521. + }
  122522. +
  122523. + /* Check whether there is a missed interrupt. */
  122524. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  122525. + {
  122526. + if ((Event->queues[i].head != gcvNULL)
  122527. + && (Event->queues[i].stamp < queue->stamp)
  122528. + && (Event->queues[i].source <= queue->source)
  122529. + )
  122530. + {
  122531. + gcmkTRACE_N(
  122532. + gcvLEVEL_ERROR,
  122533. + gcmSIZEOF(i) + gcmSIZEOF(Event->queues[i].stamp),
  122534. + "Event %d lost (stamp %llu)",
  122535. + i, Event->queues[i].stamp
  122536. + );
  122537. +
  122538. + /* Use this event instead. */
  122539. + queue = &Event->queues[i];
  122540. + mask = 0;
  122541. + }
  122542. + }
  122543. +
  122544. + if (mask != 0)
  122545. + {
  122546. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  122547. + gcmkTRACE_ZONE_N(
  122548. + gcvLEVEL_INFO, gcvZONE_EVENT,
  122549. + gcmSIZEOF(eventNumber),
  122550. + "Processing interrupt %d",
  122551. + eventNumber
  122552. + );
  122553. +#endif
  122554. + }
  122555. +
  122556. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  122557. +#if gcdSMP
  122558. + /* Mark pending interrupt as handled. */
  122559. + gckOS_AtomClearMask(Event->pending, mask);
  122560. +#elif defined(__QNXNTO__)
  122561. + /* Mark pending interrupt as handled. */
  122562. + atomic_clr(&Event->pending, mask);
  122563. +#else
  122564. + /* Mark pending interrupt as handled. */
  122565. + Event->pending &= ~mask;
  122566. +#endif
  122567. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  122568. +
  122569. + /* We are in the notify loop. */
  122570. + Event->inNotify = gcvTRUE;
  122571. +
  122572. + /* We are in the notify loop. */
  122573. + Event->inNotify = gcvTRUE;
  122574. +
  122575. + /* Grab the event head. */
  122576. + record = queue->head;
  122577. +
  122578. + /* Now quickly clear its event list. */
  122579. + queue->head = gcvNULL;
  122580. +
  122581. + /* Release the mutex queue. */
  122582. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  122583. + acquired = gcvFALSE;
  122584. +
  122585. + /* Increase the number of free events. */
  122586. + gcmkONERROR(gckOS_AtomIncrement(Event->os, Event->freeAtom, &free));
  122587. +
  122588. + /* Walk all events for this interrupt. */
  122589. + while (record != gcvNULL)
  122590. + {
  122591. + gcsEVENT_PTR recordNext;
  122592. +#ifndef __QNXNTO__
  122593. + gctPOINTER logical;
  122594. +#endif
  122595. +#if gcdSECURE_USER
  122596. + gctSIZE_T bytes;
  122597. +#endif
  122598. +
  122599. + /* Grab next record. */
  122600. + recordNext = record->next;
  122601. +
  122602. +#ifdef __QNXNTO__
  122603. + /* Assign record->processID as the pid for this galcore thread.
  122604. + * Used in OS calls like gckOS_UnlockMemory() which do not take a pid.
  122605. + */
  122606. + drv_thread_specific_key_assign(record->processID, 0, Event->kernel->core);
  122607. +#endif
  122608. +
  122609. +#if gcdSECURE_USER
  122610. + /* Get the cache that belongs to this process. */
  122611. + gcmkONERROR(gckKERNEL_GetProcessDBCache(Event->kernel,
  122612. + record->processID,
  122613. + &cache));
  122614. +#endif
  122615. +
  122616. + gcmkTRACE_ZONE_N(
  122617. + gcvLEVEL_INFO, gcvZONE_EVENT,
  122618. + gcmSIZEOF(record->info.command),
  122619. + "Processing event type: %d",
  122620. + record->info.command
  122621. + );
  122622. +
  122623. + switch (record->info.command)
  122624. + {
  122625. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  122626. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122627. + "gcvHAL_FREE_NON_PAGED_MEMORY: 0x%x",
  122628. + gcmNAME_TO_PTR(record->info.u.FreeNonPagedMemory.physical));
  122629. +
  122630. + /* Free non-paged memory. */
  122631. + status = gckOS_FreeNonPagedMemory(
  122632. + Event->os,
  122633. + (gctSIZE_T) record->info.u.FreeNonPagedMemory.bytes,
  122634. + gcmNAME_TO_PTR(record->info.u.FreeNonPagedMemory.physical),
  122635. + gcmUINT64_TO_PTR(record->info.u.FreeNonPagedMemory.logical));
  122636. +
  122637. + if (gcmIS_SUCCESS(status))
  122638. + {
  122639. +#if gcdSECURE_USER
  122640. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  122641. + Event->kernel,
  122642. + cache,
  122643. + gcmUINT64_TO_PTR(record->record.u.FreeNonPagedMemory.logical),
  122644. + (gctSIZE_T) record->record.u.FreeNonPagedMemory.bytes));
  122645. +#endif
  122646. + }
  122647. + gcmRELEASE_NAME(record->info.u.FreeNonPagedMemory.physical);
  122648. + break;
  122649. +
  122650. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  122651. + gcmkTRACE_ZONE(
  122652. + gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122653. + "gcvHAL_FREE_CONTIGUOUS_MEMORY: 0x%x",
  122654. + gcmNAME_TO_PTR(record->info.u.FreeContiguousMemory.physical));
  122655. +
  122656. + /* Unmap the user memory. */
  122657. + status = gckOS_FreeContiguous(
  122658. + Event->os,
  122659. + gcmNAME_TO_PTR(record->info.u.FreeContiguousMemory.physical),
  122660. + gcmUINT64_TO_PTR(record->info.u.FreeContiguousMemory.logical),
  122661. + (gctSIZE_T) record->info.u.FreeContiguousMemory.bytes);
  122662. +
  122663. + if (gcmIS_SUCCESS(status))
  122664. + {
  122665. +#if gcdSECURE_USER
  122666. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  122667. + Event->kernel,
  122668. + cache,
  122669. + gcmUINT64_TO_PTR(record->record.u.FreeContiguousMemory.logical),
  122670. + (gctSIZE_T) record->record.u.FreeContiguousMemory.bytes));
  122671. +#endif
  122672. + }
  122673. + gcmRELEASE_NAME(record->info.u.FreeContiguousMemory.physical);
  122674. + break;
  122675. +
  122676. + case gcvHAL_FREE_VIDEO_MEMORY:
  122677. + node = gcmUINT64_TO_PTR(record->info.u.FreeVideoMemory.node);
  122678. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122679. + "gcvHAL_FREE_VIDEO_MEMORY: 0x%x",
  122680. + node);
  122681. +#ifdef __QNXNTO__
  122682. +#if gcdUSE_VIDMEM_PER_PID
  122683. + /* Check if the VidMem object still exists. */
  122684. + if (gckKERNEL_GetVideoMemoryPoolPid(record->kernel,
  122685. + gcvPOOL_SYSTEM,
  122686. + record->processID,
  122687. + gcvNULL) == gcvSTATUS_NOT_FOUND)
  122688. + {
  122689. + /*printf("Vidmem not found for process:%d\n", queue->processID);*/
  122690. + status = gcvSTATUS_OK;
  122691. + break;
  122692. + }
  122693. +#else
  122694. + if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  122695. + && (node->VidMem.logical != gcvNULL)
  122696. + )
  122697. + {
  122698. + gcmkERR_BREAK(
  122699. + gckKERNEL_UnmapVideoMemory(record->kernel,
  122700. + node->VidMem.logical,
  122701. + record->processID,
  122702. + node->VidMem.bytes));
  122703. + node->VidMem.logical = gcvNULL;
  122704. + }
  122705. +#endif
  122706. +#endif
  122707. +
  122708. + /* Free video memory. */
  122709. + status =
  122710. + gckVIDMEM_Free(node);
  122711. +
  122712. + break;
  122713. +
  122714. + case gcvHAL_WRITE_DATA:
  122715. +#ifndef __QNXNTO__
  122716. + /* Convert physical into logical address. */
  122717. + gcmkERR_BREAK(
  122718. + gckOS_MapPhysical(Event->os,
  122719. + record->info.u.WriteData.address,
  122720. + gcmSIZEOF(gctUINT32),
  122721. + &logical));
  122722. +
  122723. + /* Write data. */
  122724. + gcmkERR_BREAK(
  122725. + gckOS_WriteMemory(Event->os,
  122726. + logical,
  122727. + record->info.u.WriteData.data));
  122728. +
  122729. + /* Unmap the physical memory. */
  122730. + gcmkERR_BREAK(
  122731. + gckOS_UnmapPhysical(Event->os,
  122732. + logical,
  122733. + gcmSIZEOF(gctUINT32)));
  122734. +#else
  122735. + /* Write data. */
  122736. + gcmkERR_BREAK(
  122737. + gckOS_WriteMemory(Event->os,
  122738. + (gctPOINTER)
  122739. + record->info.u.WriteData.address,
  122740. + record->info.u.WriteData.data));
  122741. +#endif
  122742. + break;
  122743. +
  122744. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  122745. + node = gcmUINT64_TO_PTR(record->info.u.UnlockVideoMemory.node);
  122746. +
  122747. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122748. + "gcvHAL_UNLOCK_VIDEO_MEMORY: 0x%x",
  122749. + node);
  122750. +
  122751. + /* Save node information before it disappears. */
  122752. +#if gcdSECURE_USER
  122753. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  122754. + {
  122755. + logical = gcvNULL;
  122756. + bytes = 0;
  122757. + }
  122758. + else
  122759. + {
  122760. + logical = node->Virtual.logical;
  122761. + bytes = node->Virtual.bytes;
  122762. + }
  122763. +#endif
  122764. +
  122765. + /* Unlock. */
  122766. + status = gckVIDMEM_Unlock(
  122767. + Event->kernel,
  122768. + node,
  122769. + record->info.u.UnlockVideoMemory.type,
  122770. + gcvNULL);
  122771. +
  122772. +#if gcdSECURE_USER
  122773. + if (gcmIS_SUCCESS(status) && (logical != gcvNULL))
  122774. + {
  122775. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  122776. + Event->kernel,
  122777. + cache,
  122778. + logical,
  122779. + bytes));
  122780. + }
  122781. +#endif
  122782. + break;
  122783. +
  122784. + case gcvHAL_SIGNAL:
  122785. + signal = gcmUINT64_TO_PTR(record->info.u.Signal.signal);
  122786. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122787. + "gcvHAL_SIGNAL: 0x%x",
  122788. + signal);
  122789. +
  122790. +#ifdef __QNXNTO__
  122791. + if ((record->info.u.Signal.coid == 0)
  122792. + && (record->info.u.Signal.rcvid == 0)
  122793. + )
  122794. + {
  122795. + /* Kernel signal. */
  122796. + gcmkERR_BREAK(
  122797. + gckOS_Signal(Event->os,
  122798. + signal,
  122799. + gcvTRUE));
  122800. + }
  122801. + else
  122802. + {
  122803. + /* User signal. */
  122804. + gcmkERR_BREAK(
  122805. + gckOS_UserSignal(Event->os,
  122806. + signal,
  122807. + record->info.u.Signal.rcvid,
  122808. + record->info.u.Signal.coid));
  122809. + }
  122810. +#else
  122811. + /* Set signal. */
  122812. + if (gcmUINT64_TO_PTR(record->info.u.Signal.process) == gcvNULL)
  122813. + {
  122814. + /* Kernel signal. */
  122815. + gcmkERR_BREAK(
  122816. + gckOS_Signal(Event->os,
  122817. + signal,
  122818. + gcvTRUE));
  122819. + }
  122820. + else
  122821. + {
  122822. + /* User signal. */
  122823. + gcmkERR_BREAK(
  122824. + gckOS_UserSignal(Event->os,
  122825. + signal,
  122826. + gcmUINT64_TO_PTR(record->info.u.Signal.process)));
  122827. + }
  122828. +
  122829. + gcmkASSERT(record->info.u.Signal.auxSignal == 0);
  122830. +#endif
  122831. + break;
  122832. +
  122833. + case gcvHAL_UNMAP_USER_MEMORY:
  122834. + info = gcmNAME_TO_PTR(record->info.u.UnmapUserMemory.info);
  122835. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122836. + "gcvHAL_UNMAP_USER_MEMORY: 0x%x",
  122837. + info);
  122838. +
  122839. + /* Unmap the user memory. */
  122840. + status = gckOS_UnmapUserMemory(
  122841. + Event->os,
  122842. + Event->kernel->core,
  122843. + gcmUINT64_TO_PTR(record->info.u.UnmapUserMemory.memory),
  122844. + (gctSIZE_T) record->info.u.UnmapUserMemory.size,
  122845. + info,
  122846. + record->info.u.UnmapUserMemory.address);
  122847. +
  122848. +#if gcdSECURE_USER
  122849. + if (gcmIS_SUCCESS(status))
  122850. + {
  122851. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  122852. + Event->kernel,
  122853. + cache,
  122854. + gcmUINT64_TO_PTR(record->info.u.UnmapUserMemory.memory),
  122855. + (gctSIZE_T) record->info.u.UnmapUserMemory.size));
  122856. + }
  122857. +#endif
  122858. + gcmRELEASE_NAME(record->info.u.UnmapUserMemory.info);
  122859. + break;
  122860. +
  122861. + case gcvHAL_TIMESTAMP:
  122862. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122863. + "gcvHAL_TIMESTAMP: %d %d",
  122864. + record->info.u.TimeStamp.timer,
  122865. + record->info.u.TimeStamp.request);
  122866. +
  122867. + /* Process the timestamp. */
  122868. + switch (record->info.u.TimeStamp.request)
  122869. + {
  122870. + case 0:
  122871. + status = gckOS_GetTime(&Event->kernel->timers[
  122872. + record->info.u.TimeStamp.timer].
  122873. + stopTime);
  122874. + break;
  122875. +
  122876. + case 1:
  122877. + status = gckOS_GetTime(&Event->kernel->timers[
  122878. + record->info.u.TimeStamp.timer].
  122879. + startTime);
  122880. + break;
  122881. +
  122882. + default:
  122883. + gcmkTRACE_ZONE_N(
  122884. + gcvLEVEL_ERROR, gcvZONE_EVENT,
  122885. + gcmSIZEOF(record->info.u.TimeStamp.request),
  122886. + "Invalid timestamp request: %d",
  122887. + record->info.u.TimeStamp.request
  122888. + );
  122889. +
  122890. + status = gcvSTATUS_INVALID_ARGUMENT;
  122891. + break;
  122892. + }
  122893. + break;
  122894. +
  122895. +#if gcdVIRTUAL_COMMAND_BUFFER
  122896. + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
  122897. + gcmkVERIFY_OK(
  122898. + gckKERNEL_DestroyVirtualCommandBuffer(Event->kernel,
  122899. + (gctSIZE_T) record->info.u.FreeVirtualCommandBuffer.bytes,
  122900. + gcmNAME_TO_PTR(record->info.u.FreeVirtualCommandBuffer.physical),
  122901. + gcmUINT64_TO_PTR(record->info.u.FreeVirtualCommandBuffer.logical)
  122902. + ));
  122903. + gcmRELEASE_NAME(record->info.u.FreeVirtualCommandBuffer.physical);
  122904. + break;
  122905. +#endif
  122906. +
  122907. +#if gcdANDROID_NATIVE_FENCE_SYNC
  122908. + case gcvHAL_SYNC_POINT:
  122909. + {
  122910. + gctSYNC_POINT syncPoint;
  122911. +
  122912. + syncPoint = gcmUINT64_TO_PTR(record->info.u.SyncPoint.syncPoint);
  122913. + status = gckOS_SignalSyncPoint(Event->os, syncPoint);
  122914. + }
  122915. + break;
  122916. +#endif
  122917. +
  122918. + case gcvHAL_COMMIT_DONE:
  122919. + break;
  122920. +
  122921. + default:
  122922. + /* Invalid argument. */
  122923. + gcmkTRACE_ZONE_N(
  122924. + gcvLEVEL_ERROR, gcvZONE_EVENT,
  122925. + gcmSIZEOF(record->info.command),
  122926. + "Unknown event type: %d",
  122927. + record->info.command
  122928. + );
  122929. +
  122930. + status = gcvSTATUS_INVALID_ARGUMENT;
  122931. + break;
  122932. + }
  122933. +
  122934. + /* Make sure there are no errors generated. */
  122935. + if (gcmIS_ERROR(status))
  122936. + {
  122937. + gcmkTRACE_ZONE_N(
  122938. + gcvLEVEL_WARNING, gcvZONE_EVENT,
  122939. + gcmSIZEOF(status),
  122940. + "Event produced status: %d(%s)",
  122941. + status, gckOS_DebugStatus2Name(status));
  122942. + }
  122943. +
  122944. + /* Free the event. */
  122945. + gcmkVERIFY_OK(gckEVENT_FreeRecord(Event, record));
  122946. +
  122947. + /* Advance to next record. */
  122948. + record = recordNext;
  122949. + }
  122950. +
  122951. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  122952. + "Handled interrupt 0x%x", mask);
  122953. + }
  122954. +
  122955. + if (IDs == 0)
  122956. + {
  122957. + gcmkONERROR(_TryToIdleGPU(Event));
  122958. + }
  122959. +
  122960. + /* We are out the notify loop. */
  122961. + Event->inNotify = gcvFALSE;
  122962. +
  122963. + /* Success. */
  122964. + gcmkFOOTER_NO();
  122965. + return gcvSTATUS_OK;
  122966. +
  122967. +OnError:
  122968. + if (acquired)
  122969. + {
  122970. + /* Release mutex. */
  122971. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  122972. + }
  122973. +
  122974. +#if !gcdSMP
  122975. + if (suspended)
  122976. + {
  122977. + /* Resume interrupts. */
  122978. + gcmkVERIFY_OK(gckOS_ResumeInterruptEx(Event->os, Event->kernel->core));
  122979. + }
  122980. +#endif
  122981. +
  122982. + /* We are out the notify loop. */
  122983. + Event->inNotify = gcvFALSE;
  122984. +
  122985. + /* Return the status. */
  122986. + gcmkFOOTER();
  122987. + return status;
  122988. +}
  122989. +
  122990. +/*******************************************************************************
  122991. +** gckEVENT_FreeProcess
  122992. +**
  122993. +** Free all events owned by a particular process ID.
  122994. +**
  122995. +** INPUT:
  122996. +**
  122997. +** gckEVENT Event
  122998. +** Pointer to an gckEVENT object.
  122999. +**
  123000. +** gctUINT32 ProcessID
  123001. +** Process ID of the process to be freed up.
  123002. +**
  123003. +** OUTPUT:
  123004. +**
  123005. +** Nothing.
  123006. +*/
  123007. +gceSTATUS
  123008. +gckEVENT_FreeProcess(
  123009. + IN gckEVENT Event,
  123010. + IN gctUINT32 ProcessID
  123011. + )
  123012. +{
  123013. + gctSIZE_T i;
  123014. + gctBOOL acquired = gcvFALSE;
  123015. + gcsEVENT_PTR record, next;
  123016. + gceSTATUS status;
  123017. + gcsEVENT_PTR deleteHead, deleteTail;
  123018. +
  123019. + gcmkHEADER_ARG("Event=0x%x ProcessID=%d", Event, ProcessID);
  123020. +
  123021. + /* Verify the arguments. */
  123022. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  123023. +
  123024. + /* Walk through all queues. */
  123025. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  123026. + {
  123027. + if (Event->queues[i].head != gcvNULL)
  123028. + {
  123029. + /* Grab the event queue mutex. */
  123030. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  123031. + Event->eventQueueMutex,
  123032. + gcvINFINITE));
  123033. + acquired = gcvTRUE;
  123034. +
  123035. + /* Grab the mutex head. */
  123036. + record = Event->queues[i].head;
  123037. + Event->queues[i].head = gcvNULL;
  123038. + Event->queues[i].tail = gcvNULL;
  123039. + deleteHead = gcvNULL;
  123040. + deleteTail = gcvNULL;
  123041. +
  123042. + while (record != gcvNULL)
  123043. + {
  123044. + next = record->next;
  123045. + if (record->processID == ProcessID)
  123046. + {
  123047. + if (deleteHead == gcvNULL)
  123048. + {
  123049. + deleteHead = record;
  123050. + }
  123051. + else
  123052. + {
  123053. + deleteTail->next = record;
  123054. + }
  123055. +
  123056. + deleteTail = record;
  123057. + }
  123058. + else
  123059. + {
  123060. + if (Event->queues[i].head == gcvNULL)
  123061. + {
  123062. + Event->queues[i].head = record;
  123063. + }
  123064. + else
  123065. + {
  123066. + Event->queues[i].tail->next = record;
  123067. + }
  123068. +
  123069. + Event->queues[i].tail = record;
  123070. + }
  123071. +
  123072. + record->next = gcvNULL;
  123073. + record = next;
  123074. + }
  123075. +
  123076. + /* Release the mutex queue. */
  123077. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  123078. + acquired = gcvFALSE;
  123079. +
  123080. + /* Loop through the entire list of events. */
  123081. + for (record = deleteHead; record != gcvNULL; record = next)
  123082. + {
  123083. + /* Get the next event record. */
  123084. + next = record->next;
  123085. +
  123086. + /* Free the event record. */
  123087. + gcmkONERROR(gckEVENT_FreeRecord(Event, record));
  123088. + }
  123089. + }
  123090. + }
  123091. +
  123092. + gcmkONERROR(_TryToIdleGPU(Event));
  123093. +
  123094. + /* Success. */
  123095. + gcmkFOOTER_NO();
  123096. + return gcvSTATUS_OK;
  123097. +
  123098. +OnError:
  123099. + /* Release the event queue mutex. */
  123100. + if (acquired)
  123101. + {
  123102. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  123103. + }
  123104. +
  123105. + /* Return the status. */
  123106. + gcmkFOOTER();
  123107. + return status;
  123108. +}
  123109. +
  123110. +/*******************************************************************************
  123111. +** gckEVENT_Stop
  123112. +**
  123113. +** Stop the hardware using the End event mechanism.
  123114. +**
  123115. +** INPUT:
  123116. +**
  123117. +** gckEVENT Event
  123118. +** Pointer to an gckEVENT object.
  123119. +**
  123120. +** gctUINT32 ProcessID
  123121. +** Process ID Logical belongs.
  123122. +**
  123123. +** gctPHYS_ADDR Handle
  123124. +** Physical address handle. If gcvNULL it is video memory.
  123125. +**
  123126. +** gctPOINTER Logical
  123127. +** Logical address to flush.
  123128. +**
  123129. +** gctSIGNAL Signal
  123130. +** Pointer to the signal to trigger.
  123131. +**
  123132. +** OUTPUT:
  123133. +**
  123134. +** Nothing.
  123135. +*/
  123136. +gceSTATUS
  123137. +gckEVENT_Stop(
  123138. + IN gckEVENT Event,
  123139. + IN gctUINT32 ProcessID,
  123140. + IN gctPHYS_ADDR Handle,
  123141. + IN gctPOINTER Logical,
  123142. + IN gctSIGNAL Signal,
  123143. + IN OUT gctSIZE_T * waitSize
  123144. + )
  123145. +{
  123146. + gceSTATUS status;
  123147. + /* gctSIZE_T waitSize;*/
  123148. + gcsEVENT_PTR record;
  123149. + gctUINT8 id = 0xFF;
  123150. +
  123151. + gcmkHEADER_ARG("Event=0x%x ProcessID=%u Handle=0x%x Logical=0x%x "
  123152. + "Signal=0x%x",
  123153. + Event, ProcessID, Handle, Logical, Signal);
  123154. +
  123155. + /* Verify the arguments. */
  123156. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  123157. +
  123158. + /* Submit the current event queue. */
  123159. + gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE));
  123160. +
  123161. + /* Allocate a record. */
  123162. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &record));
  123163. +
  123164. + /* Initialize the record. */
  123165. + record->next = gcvNULL;
  123166. + record->processID = ProcessID;
  123167. + record->info.command = gcvHAL_SIGNAL;
  123168. + record->info.u.Signal.signal = gcmPTR_TO_UINT64(Signal);
  123169. +#ifdef __QNXNTO__
  123170. + record->info.u.Signal.coid = 0;
  123171. + record->info.u.Signal.rcvid = 0;
  123172. +#endif
  123173. + record->info.u.Signal.auxSignal = 0;
  123174. + record->info.u.Signal.process = 0;
  123175. +
  123176. +
  123177. + gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, record, gcvKERNEL_PIXEL));
  123178. +
  123179. + /* Replace last WAIT with END. */
  123180. + gcmkONERROR(gckHARDWARE_End(
  123181. + Event->kernel->hardware, Logical, waitSize
  123182. + ));
  123183. +
  123184. +#if gcdNONPAGED_MEMORY_CACHEABLE
  123185. + /* Flush the cache for the END. */
  123186. + gcmkONERROR(gckOS_CacheClean(
  123187. + Event->os,
  123188. + ProcessID,
  123189. + gcvNULL,
  123190. + Handle,
  123191. + Logical,
  123192. + *waitSize
  123193. + ));
  123194. +#endif
  123195. +
  123196. + /* Wait for the signal. */
  123197. + gcmkONERROR(gckOS_WaitSignal(Event->os, Signal, gcvINFINITE));
  123198. +
  123199. + /* Success. */
  123200. + gcmkFOOTER_NO();
  123201. + return gcvSTATUS_OK;
  123202. +
  123203. +OnError:
  123204. +
  123205. + /* Return the status. */
  123206. + gcmkFOOTER();
  123207. + return status;
  123208. +}
  123209. +
  123210. +static void
  123211. +_PrintRecord(
  123212. + gcsEVENT_PTR record
  123213. + )
  123214. +{
  123215. + switch (record->info.command)
  123216. + {
  123217. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  123218. + gcmkPRINT(" gcvHAL_FREE_NON_PAGED_MEMORY");
  123219. + break;
  123220. +
  123221. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  123222. + gcmkPRINT(" gcvHAL_FREE_CONTIGUOUS_MEMORY");
  123223. + break;
  123224. +
  123225. + case gcvHAL_FREE_VIDEO_MEMORY:
  123226. + gcmkPRINT(" gcvHAL_FREE_VIDEO_MEMORY");
  123227. + break;
  123228. +
  123229. + case gcvHAL_WRITE_DATA:
  123230. + gcmkPRINT(" gcvHAL_WRITE_DATA");
  123231. + break;
  123232. +
  123233. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  123234. + gcmkPRINT(" gcvHAL_UNLOCK_VIDEO_MEMORY");
  123235. + break;
  123236. +
  123237. + case gcvHAL_SIGNAL:
  123238. + gcmkPRINT(" gcvHAL_SIGNAL process=%d signal=0x%x",
  123239. + record->info.u.Signal.process,
  123240. + record->info.u.Signal.signal);
  123241. + break;
  123242. +
  123243. + case gcvHAL_UNMAP_USER_MEMORY:
  123244. + gcmkPRINT(" gcvHAL_UNMAP_USER_MEMORY");
  123245. + break;
  123246. +
  123247. + case gcvHAL_TIMESTAMP:
  123248. + gcmkPRINT(" gcvHAL_TIMESTAMP");
  123249. + break;
  123250. +
  123251. + case gcvHAL_COMMIT_DONE:
  123252. + gcmkPRINT(" gcvHAL_COMMIT_DONE");
  123253. + break;
  123254. +
  123255. + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
  123256. + gcmkPRINT(" gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER logical=0x%08x",
  123257. + record->info.u.FreeVirtualCommandBuffer.logical);
  123258. + break;
  123259. +
  123260. + default:
  123261. + gcmkPRINT(" Illegal Event %d", record->info.command);
  123262. + break;
  123263. + }
  123264. +}
  123265. +
  123266. +/*******************************************************************************
  123267. +** gckEVENT_Dump
  123268. +**
  123269. +** Dump record in event queue when stuck happens.
  123270. +** No protection for the event queue.
  123271. +**/
  123272. +gceSTATUS
  123273. +gckEVENT_Dump(
  123274. + IN gckEVENT Event
  123275. + )
  123276. +{
  123277. + gcsEVENT_QUEUE_PTR queueHead = Event->queueHead;
  123278. + gcsEVENT_QUEUE_PTR queue;
  123279. + gcsEVENT_PTR record = gcvNULL;
  123280. + gctINT i;
  123281. +
  123282. + gcmkHEADER_ARG("Event=0x%x", Event);
  123283. +
  123284. + gcmkPRINT("**************************\n");
  123285. + gcmkPRINT("*** EVENT STATE DUMP ***\n");
  123286. + gcmkPRINT("**************************\n");
  123287. +
  123288. +
  123289. + gcmkPRINT(" Unsumbitted Event:");
  123290. + while(queueHead)
  123291. + {
  123292. + queue = queueHead;
  123293. + record = queueHead->head;
  123294. +
  123295. + gcmkPRINT(" [%x]:", queue);
  123296. + while(record)
  123297. + {
  123298. + _PrintRecord(record);
  123299. + record = record->next;
  123300. + }
  123301. +
  123302. + if (queueHead == Event->queueTail)
  123303. + {
  123304. + queueHead = gcvNULL;
  123305. + }
  123306. + else
  123307. + {
  123308. + queueHead = queueHead->next;
  123309. + }
  123310. + }
  123311. +
  123312. + gcmkPRINT(" Untriggered Event:");
  123313. + for (i = 0; i < 30; i++)
  123314. + {
  123315. + queue = &Event->queues[i];
  123316. + record = queue->head;
  123317. +
  123318. + gcmkPRINT(" [%d]:", i);
  123319. + while(record)
  123320. + {
  123321. + _PrintRecord(record);
  123322. + record = record->next;
  123323. + }
  123324. + }
  123325. +
  123326. + gcmkFOOTER_NO();
  123327. + return gcvSTATUS_OK;
  123328. +}
  123329. +
  123330. +gceSTATUS gckEVENT_WaitEmpty(gckEVENT Event)
  123331. +{
  123332. + gctBOOL isEmpty;
  123333. +
  123334. + while (Event->inNotify || (gcmIS_SUCCESS(gckEVENT_IsEmpty(Event, &isEmpty)) && !isEmpty)) ;
  123335. +
  123336. + return gcvSTATUS_OK;
  123337. +}
  123338. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
  123339. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h 1969-12-31 18:00:00.000000000 -0600
  123340. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h 2014-12-08 00:31:53.464418001 -0600
  123341. @@ -0,0 +1,1011 @@
  123342. +/****************************************************************************
  123343. +*
  123344. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  123345. +*
  123346. +* This program is free software; you can redistribute it and/or modify
  123347. +* it under the terms of the GNU General Public License as published by
  123348. +* the Free Software Foundation; either version 2 of the license, or
  123349. +* (at your option) any later version.
  123350. +*
  123351. +* This program is distributed in the hope that it will be useful,
  123352. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  123353. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  123354. +* GNU General Public License for more details.
  123355. +*
  123356. +* You should have received a copy of the GNU General Public License
  123357. +* along with this program; if not write to the Free Software
  123358. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  123359. +*
  123360. +*****************************************************************************/
  123361. +
  123362. +
  123363. +#ifndef __gc_hal_kernel_h_
  123364. +#define __gc_hal_kernel_h_
  123365. +
  123366. +#include <linux/spinlock.h>
  123367. +
  123368. +#include "gc_hal.h"
  123369. +#include "gc_hal_kernel_hardware.h"
  123370. +#include "gc_hal_driver.h"
  123371. +
  123372. +#if gcdENABLE_VG
  123373. +#include "gc_hal_kernel_vg.h"
  123374. +#endif
  123375. +
  123376. +#ifdef __cplusplus
  123377. +extern "C" {
  123378. +#endif
  123379. +
  123380. +
  123381. +/*******************************************************************************
  123382. +***** New MMU Defination *******************************************************/
  123383. +#define gcdMMU_MTLB_SHIFT 22
  123384. +#define gcdMMU_STLB_4K_SHIFT 12
  123385. +#define gcdMMU_STLB_64K_SHIFT 16
  123386. +
  123387. +#define gcdMMU_MTLB_BITS (32 - gcdMMU_MTLB_SHIFT)
  123388. +#define gcdMMU_PAGE_4K_BITS gcdMMU_STLB_4K_SHIFT
  123389. +#define gcdMMU_STLB_4K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_4K_BITS)
  123390. +#define gcdMMU_PAGE_64K_BITS gcdMMU_STLB_64K_SHIFT
  123391. +#define gcdMMU_STLB_64K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_64K_BITS)
  123392. +
  123393. +#define gcdMMU_MTLB_ENTRY_NUM (1 << gcdMMU_MTLB_BITS)
  123394. +#define gcdMMU_MTLB_SIZE (gcdMMU_MTLB_ENTRY_NUM << 2)
  123395. +#define gcdMMU_STLB_4K_ENTRY_NUM (1 << gcdMMU_STLB_4K_BITS)
  123396. +#define gcdMMU_STLB_4K_SIZE (gcdMMU_STLB_4K_ENTRY_NUM << 2)
  123397. +#define gcdMMU_PAGE_4K_SIZE (1 << gcdMMU_STLB_4K_SHIFT)
  123398. +#define gcdMMU_STLB_64K_ENTRY_NUM (1 << gcdMMU_STLB_64K_BITS)
  123399. +#define gcdMMU_STLB_64K_SIZE (gcdMMU_STLB_64K_ENTRY_NUM << 2)
  123400. +#define gcdMMU_PAGE_64K_SIZE (1 << gcdMMU_STLB_64K_SHIFT)
  123401. +
  123402. +#define gcdMMU_MTLB_MASK (~((1U << gcdMMU_MTLB_SHIFT)-1))
  123403. +#define gcdMMU_STLB_4K_MASK ((~0U << gcdMMU_STLB_4K_SHIFT) ^ gcdMMU_MTLB_MASK)
  123404. +#define gcdMMU_PAGE_4K_MASK (gcdMMU_PAGE_4K_SIZE - 1)
  123405. +#define gcdMMU_STLB_64K_MASK ((~((1U << gcdMMU_STLB_64K_SHIFT)-1)) ^ gcdMMU_MTLB_MASK)
  123406. +#define gcdMMU_PAGE_64K_MASK (gcdMMU_PAGE_64K_SIZE - 1)
  123407. +
  123408. +/* Page offset definitions. */
  123409. +#define gcdMMU_OFFSET_4K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_4K_BITS)
  123410. +#define gcdMMU_OFFSET_4K_MASK ((1U << gcdMMU_OFFSET_4K_BITS) - 1)
  123411. +#define gcdMMU_OFFSET_16K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_16K_BITS)
  123412. +#define gcdMMU_OFFSET_16K_MASK ((1U << gcdMMU_OFFSET_16K_BITS) - 1)
  123413. +
  123414. +/*******************************************************************************
  123415. +***** Process Secure Cache ****************************************************/
  123416. +
  123417. +#define gcdSECURE_CACHE_LRU 1
  123418. +#define gcdSECURE_CACHE_LINEAR 2
  123419. +#define gcdSECURE_CACHE_HASH 3
  123420. +#define gcdSECURE_CACHE_TABLE 4
  123421. +
  123422. +typedef struct _gcskLOGICAL_CACHE * gcskLOGICAL_CACHE_PTR;
  123423. +typedef struct _gcskLOGICAL_CACHE gcskLOGICAL_CACHE;
  123424. +struct _gcskLOGICAL_CACHE
  123425. +{
  123426. + /* Logical address. */
  123427. + gctPOINTER logical;
  123428. +
  123429. + /* DMAable address. */
  123430. + gctUINT32 dma;
  123431. +
  123432. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  123433. + /* Pointer to the previous and next hash tables. */
  123434. + gcskLOGICAL_CACHE_PTR nextHash;
  123435. + gcskLOGICAL_CACHE_PTR prevHash;
  123436. +#endif
  123437. +
  123438. +#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
  123439. + /* Pointer to the previous and next slot. */
  123440. + gcskLOGICAL_CACHE_PTR next;
  123441. + gcskLOGICAL_CACHE_PTR prev;
  123442. +#endif
  123443. +
  123444. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
  123445. + /* Time stamp. */
  123446. + gctUINT64 stamp;
  123447. +#endif
  123448. +};
  123449. +
  123450. +typedef struct _gcskSECURE_CACHE * gcskSECURE_CACHE_PTR;
  123451. +typedef struct _gcskSECURE_CACHE
  123452. +{
  123453. + /* Cache memory. */
  123454. + gcskLOGICAL_CACHE cache[1 + gcdSECURE_CACHE_SLOTS];
  123455. +
  123456. + /* Last known index for LINEAR mode. */
  123457. + gcskLOGICAL_CACHE_PTR cacheIndex;
  123458. +
  123459. + /* Current free slot for LINEAR mode. */
  123460. + gctUINT32 cacheFree;
  123461. +
  123462. + /* Time stamp for LINEAR mode. */
  123463. + gctUINT64 cacheStamp;
  123464. +
  123465. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  123466. + /* Hash table for HASH mode. */
  123467. + gcskLOGICAL_CACHE hash[256];
  123468. +#endif
  123469. +}
  123470. +gcskSECURE_CACHE;
  123471. +
  123472. +/*******************************************************************************
  123473. +***** Process Database Management *********************************************/
  123474. +
  123475. +typedef enum _gceDATABASE_TYPE
  123476. +{
  123477. + gcvDB_VIDEO_MEMORY = 1, /* Video memory created. */
  123478. + gcvDB_COMMAND_BUFFER, /* Command Buffer. */
  123479. + gcvDB_NON_PAGED, /* Non paged memory. */
  123480. + gcvDB_CONTIGUOUS, /* Contiguous memory. */
  123481. + gcvDB_SIGNAL, /* Signal. */
  123482. + gcvDB_VIDEO_MEMORY_LOCKED, /* Video memory locked. */
  123483. + gcvDB_CONTEXT, /* Context */
  123484. + gcvDB_IDLE, /* GPU idle. */
  123485. + gcvDB_MAP_MEMORY, /* Map memory */
  123486. + gcvDB_SHARED_INFO, /* Private data */
  123487. + gcvDB_MAP_USER_MEMORY, /* Map user memory */
  123488. + gcvDB_SYNC_POINT, /* Sync point. */
  123489. + gcvDB_VIDEO_MEMORY_RESERVED, /* Reserved video memory */
  123490. + gcvDB_VIDEO_MEMORY_CONTIGUOUS, /* Contiguous video memory */
  123491. + gcvDB_VIDEO_MEMORY_VIRTUAL, /* Virtual video memory */
  123492. +}
  123493. +gceDATABASE_TYPE;
  123494. +
  123495. +typedef struct _gcsDATABASE_RECORD * gcsDATABASE_RECORD_PTR;
  123496. +typedef struct _gcsDATABASE_RECORD
  123497. +{
  123498. + /* Pointer to kernel. */
  123499. + gckKERNEL kernel;
  123500. +
  123501. + /* Pointer to next database record. */
  123502. + gcsDATABASE_RECORD_PTR next;
  123503. +
  123504. + /* Type of record. */
  123505. + gceDATABASE_TYPE type;
  123506. +
  123507. + /* Data for record. */
  123508. + gctPOINTER data;
  123509. + gctPHYS_ADDR physical;
  123510. + gctSIZE_T bytes;
  123511. +}
  123512. +gcsDATABASE_RECORD;
  123513. +
  123514. +typedef struct _gcsDATABASE * gcsDATABASE_PTR;
  123515. +typedef struct _gcsDATABASE
  123516. +{
  123517. + /* Pointer to next entry is hash list. */
  123518. + gcsDATABASE_PTR next;
  123519. + gctSIZE_T slot;
  123520. +
  123521. + /* Process ID. */
  123522. + gctUINT32 processID;
  123523. +
  123524. + /* Sizes to query. */
  123525. + gcsDATABASE_COUNTERS vidMem;
  123526. + gcsDATABASE_COUNTERS nonPaged;
  123527. + gcsDATABASE_COUNTERS contiguous;
  123528. + gcsDATABASE_COUNTERS mapUserMemory;
  123529. + gcsDATABASE_COUNTERS mapMemory;
  123530. + gcsDATABASE_COUNTERS vidMemResv;
  123531. + gcsDATABASE_COUNTERS vidMemCont;
  123532. + gcsDATABASE_COUNTERS vidMemVirt;
  123533. +
  123534. + /* Idle time management. */
  123535. + gctUINT64 lastIdle;
  123536. + gctUINT64 idle;
  123537. +
  123538. + /* Pointer to database. */
  123539. + gcsDATABASE_RECORD_PTR list[48];
  123540. +
  123541. +#if gcdSECURE_USER
  123542. + /* Secure cache. */
  123543. + gcskSECURE_CACHE cache;
  123544. +#endif
  123545. +
  123546. + gctPOINTER handleDatabase;
  123547. + gctPOINTER handleDatabaseMutex;
  123548. +}
  123549. +gcsDATABASE;
  123550. +
  123551. +/* Create a process database that will contain all its allocations. */
  123552. +gceSTATUS
  123553. +gckKERNEL_CreateProcessDB(
  123554. + IN gckKERNEL Kernel,
  123555. + IN gctUINT32 ProcessID
  123556. + );
  123557. +
  123558. +/* Add a record to the process database. */
  123559. +gceSTATUS
  123560. +gckKERNEL_AddProcessDB(
  123561. + IN gckKERNEL Kernel,
  123562. + IN gctUINT32 ProcessID,
  123563. + IN gceDATABASE_TYPE Type,
  123564. + IN gctPOINTER Pointer,
  123565. + IN gctPHYS_ADDR Physical,
  123566. + IN gctSIZE_T Size
  123567. + );
  123568. +
  123569. +/* Remove a record to the process database. */
  123570. +gceSTATUS
  123571. +gckKERNEL_RemoveProcessDB(
  123572. + IN gckKERNEL Kernel,
  123573. + IN gctUINT32 ProcessID,
  123574. + IN gceDATABASE_TYPE Type,
  123575. + IN gctPOINTER Pointer
  123576. + );
  123577. +
  123578. +/* Destroy the process database. */
  123579. +gceSTATUS
  123580. +gckKERNEL_DestroyProcessDB(
  123581. + IN gckKERNEL Kernel,
  123582. + IN gctUINT32 ProcessID
  123583. + );
  123584. +
  123585. +/* Find a record to the process database. */
  123586. +gceSTATUS
  123587. +gckKERNEL_FindProcessDB(
  123588. + IN gckKERNEL Kernel,
  123589. + IN gctUINT32 ProcessID,
  123590. + IN gctUINT32 ThreadID,
  123591. + IN gceDATABASE_TYPE Type,
  123592. + IN gctPOINTER Pointer,
  123593. + OUT gcsDATABASE_RECORD_PTR Record
  123594. + );
  123595. +
  123596. +/* Query the process database. */
  123597. +gceSTATUS
  123598. +gckKERNEL_QueryProcessDB(
  123599. + IN gckKERNEL Kernel,
  123600. + IN gctUINT32 ProcessID,
  123601. + IN gctBOOL LastProcessID,
  123602. + IN gceDATABASE_TYPE Type,
  123603. + OUT gcuDATABASE_INFO * Info
  123604. + );
  123605. +
  123606. +/* Dump the process database. */
  123607. +gceSTATUS
  123608. +gckKERNEL_DumpProcessDB(
  123609. + IN gckKERNEL Kernel
  123610. + );
  123611. +
  123612. +/* ID database */
  123613. +gceSTATUS
  123614. +gckKERNEL_CreateIntegerDatabase(
  123615. + IN gckKERNEL Kernel,
  123616. + OUT gctPOINTER * Database
  123617. + );
  123618. +
  123619. +gceSTATUS
  123620. +gckKERNEL_DestroyIntegerDatabase(
  123621. + IN gckKERNEL Kernel,
  123622. + IN gctPOINTER Database
  123623. + );
  123624. +
  123625. +gceSTATUS
  123626. +gckKERNEL_AllocateIntegerId(
  123627. + IN gctPOINTER Database,
  123628. + IN gctPOINTER Pointer,
  123629. + OUT gctUINT32 * Id
  123630. + );
  123631. +
  123632. +gceSTATUS
  123633. +gckKERNEL_FreeIntegerId(
  123634. + IN gctPOINTER Database,
  123635. + IN gctUINT32 Id
  123636. + );
  123637. +
  123638. +gceSTATUS
  123639. +gckKERNEL_QueryIntegerId(
  123640. + IN gctPOINTER Database,
  123641. + IN gctUINT32 Id,
  123642. + OUT gctPOINTER * Pointer
  123643. + );
  123644. +
  123645. +gctUINT32
  123646. +gckKERNEL_AllocateNameFromPointer(
  123647. + IN gckKERNEL Kernel,
  123648. + IN gctPOINTER Pointer
  123649. + );
  123650. +
  123651. +gctPOINTER
  123652. +gckKERNEL_QueryPointerFromName(
  123653. + IN gckKERNEL Kernel,
  123654. + IN gctUINT32 Name
  123655. + );
  123656. +
  123657. +gceSTATUS
  123658. +gckKERNEL_DeleteName(
  123659. + IN gckKERNEL Kernel,
  123660. + IN gctUINT32 Name
  123661. + );
  123662. +
  123663. +#if gcdSECURE_USER
  123664. +/* Get secure cache from the process database. */
  123665. +gceSTATUS
  123666. +gckKERNEL_GetProcessDBCache(
  123667. + IN gckKERNEL Kernel,
  123668. + IN gctUINT32 ProcessID,
  123669. + OUT gcskSECURE_CACHE_PTR * Cache
  123670. + );
  123671. +#endif
  123672. +
  123673. +/*******************************************************************************
  123674. +********* Timer Management ****************************************************/
  123675. +typedef struct _gcsTIMER * gcsTIMER_PTR;
  123676. +typedef struct _gcsTIMER
  123677. +{
  123678. + /* Start and Stop time holders. */
  123679. + gctUINT64 startTime;
  123680. + gctUINT64 stopTime;
  123681. +}
  123682. +gcsTIMER;
  123683. +
  123684. +/******************************************************************************\
  123685. +********************************** Structures **********************************
  123686. +\******************************************************************************/
  123687. +
  123688. +/* gckDB object. */
  123689. +struct _gckDB
  123690. +{
  123691. + /* Database management. */
  123692. + gcsDATABASE_PTR db[16];
  123693. + gctPOINTER dbMutex;
  123694. + gcsDATABASE_PTR freeDatabase;
  123695. + gcsDATABASE_RECORD_PTR freeRecord;
  123696. + gcsDATABASE_PTR lastDatabase;
  123697. + gctUINT32 lastProcessID;
  123698. + gctUINT64 lastIdle;
  123699. + gctUINT64 idleTime;
  123700. + gctUINT64 lastSlowdown;
  123701. + gctUINT64 lastSlowdownIdle;
  123702. + /* ID - Pointer database*/
  123703. + gctPOINTER pointerDatabase;
  123704. + gctPOINTER pointerDatabaseMutex;
  123705. +};
  123706. +
  123707. +#if gcdVIRTUAL_COMMAND_BUFFER
  123708. +typedef struct _gckVIRTUAL_COMMAND_BUFFER * gckVIRTUAL_COMMAND_BUFFER_PTR;
  123709. +typedef struct _gckVIRTUAL_COMMAND_BUFFER
  123710. +{
  123711. + gctPHYS_ADDR physical;
  123712. + gctPOINTER userLogical;
  123713. + gctPOINTER kernelLogical;
  123714. + gctSIZE_T pageCount;
  123715. + gctPOINTER pageTable;
  123716. + gctUINT32 gpuAddress;
  123717. + gctUINT pid;
  123718. + gckVIRTUAL_COMMAND_BUFFER_PTR next;
  123719. + gckVIRTUAL_COMMAND_BUFFER_PTR prev;
  123720. + gckKERNEL kernel;
  123721. +}
  123722. +gckVIRTUAL_COMMAND_BUFFER;
  123723. +#endif
  123724. +
  123725. +/* gckKERNEL object. */
  123726. +struct _gckKERNEL
  123727. +{
  123728. + /* Object. */
  123729. + gcsOBJECT object;
  123730. +
  123731. + /* Pointer to gckOS object. */
  123732. + gckOS os;
  123733. +
  123734. + /* Core */
  123735. + gceCORE core;
  123736. +
  123737. + /* Pointer to gckHARDWARE object. */
  123738. + gckHARDWARE hardware;
  123739. +
  123740. + /* Pointer to gckCOMMAND object. */
  123741. + gckCOMMAND command;
  123742. +
  123743. + /* Pointer to gckEVENT object. */
  123744. + gckEVENT eventObj;
  123745. +
  123746. + /* Pointer to context. */
  123747. + gctPOINTER context;
  123748. +
  123749. + /* Pointer to gckMMU object. */
  123750. + gckMMU mmu;
  123751. +
  123752. + /* Arom holding number of clients. */
  123753. + gctPOINTER atomClients;
  123754. +
  123755. +#if VIVANTE_PROFILER
  123756. + /* Enable profiling */
  123757. + gctBOOL profileEnable;
  123758. +
  123759. + /* Clear profile register or not*/
  123760. + gctBOOL profileCleanRegister;
  123761. +
  123762. +#endif
  123763. +
  123764. +#ifdef QNX_SINGLE_THREADED_DEBUGGING
  123765. + gctPOINTER debugMutex;
  123766. +#endif
  123767. +
  123768. + /* Database management. */
  123769. + gckDB db;
  123770. + gctBOOL dbCreated;
  123771. +
  123772. +#if gcdENABLE_RECOVERY
  123773. + gctPOINTER resetFlagClearTimer;
  123774. + gctPOINTER resetAtom;
  123775. + gctUINT64 resetTimeStamp;
  123776. +#endif
  123777. +
  123778. + /* Pointer to gckEVENT object. */
  123779. + gcsTIMER timers[8];
  123780. + gctUINT32 timeOut;
  123781. +
  123782. +#if gcdENABLE_VG
  123783. + gckVGKERNEL vg;
  123784. +#endif
  123785. +
  123786. +#if gcdVIRTUAL_COMMAND_BUFFER
  123787. + gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferHead;
  123788. + gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferTail;
  123789. + gctPOINTER virtualBufferLock;
  123790. +#endif
  123791. +
  123792. +#if gcdDVFS
  123793. + gckDVFS dvfs;
  123794. +#endif
  123795. +
  123796. +#if gcdANDROID_NATIVE_FENCE_SYNC
  123797. + gctHANDLE timeline;
  123798. +#endif
  123799. +
  123800. + spinlock_t irq_lock;
  123801. +};
  123802. +
  123803. +struct _FrequencyHistory
  123804. +{
  123805. + gctUINT32 frequency;
  123806. + gctUINT32 count;
  123807. +};
  123808. +
  123809. +/* gckDVFS object. */
  123810. +struct _gckDVFS
  123811. +{
  123812. + gckOS os;
  123813. + gckHARDWARE hardware;
  123814. + gctPOINTER timer;
  123815. + gctUINT32 pollingTime;
  123816. + gctBOOL stop;
  123817. + gctUINT32 totalConfig;
  123818. + gctUINT32 loads[8];
  123819. + gctUINT8 currentScale;
  123820. + struct _FrequencyHistory frequencyHistory[16];
  123821. +};
  123822. +
  123823. +/* gckCOMMAND object. */
  123824. +struct _gckCOMMAND
  123825. +{
  123826. + /* Object. */
  123827. + gcsOBJECT object;
  123828. +
  123829. + /* Pointer to required object. */
  123830. + gckKERNEL kernel;
  123831. + gckOS os;
  123832. +
  123833. + /* Number of bytes per page. */
  123834. + gctSIZE_T pageSize;
  123835. +
  123836. + /* Current pipe select. */
  123837. + gcePIPE_SELECT pipeSelect;
  123838. +
  123839. + /* Command queue running flag. */
  123840. + gctBOOL running;
  123841. +
  123842. + /* Idle flag and commit stamp. */
  123843. + gctBOOL idle;
  123844. + gctUINT64 commitStamp;
  123845. +
  123846. + /* Command queue mutex. */
  123847. + gctPOINTER mutexQueue;
  123848. +
  123849. + /* Context switching mutex. */
  123850. + gctPOINTER mutexContext;
  123851. +
  123852. +#if VIVANTE_PROFILER_CONTEXT
  123853. + /* Context sequence mutex. */
  123854. + gctPOINTER mutexContextSeq;
  123855. +#endif
  123856. +
  123857. + /* Command queue power semaphore. */
  123858. + gctPOINTER powerSemaphore;
  123859. +
  123860. + /* Current command queue. */
  123861. + struct _gcskCOMMAND_QUEUE
  123862. + {
  123863. + gctSIGNAL signal;
  123864. + gctPHYS_ADDR physical;
  123865. + gctPOINTER logical;
  123866. + }
  123867. + queues[gcdCOMMAND_QUEUES];
  123868. +
  123869. + gctPHYS_ADDR physical;
  123870. + gctPOINTER logical;
  123871. + gctUINT32 offset;
  123872. + gctINT index;
  123873. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  123874. + gctUINT wrapCount;
  123875. +#endif
  123876. +
  123877. + /* The command queue is new. */
  123878. + gctBOOL newQueue;
  123879. +
  123880. + /* Context management. */
  123881. + gckCONTEXT currContext;
  123882. +
  123883. + /* Pointer to last WAIT command. */
  123884. + gctPHYS_ADDR waitPhysical;
  123885. + gctPOINTER waitLogical;
  123886. + gctSIZE_T waitSize;
  123887. +
  123888. + /* Command buffer alignment. */
  123889. + gctSIZE_T alignment;
  123890. + gctSIZE_T reservedHead;
  123891. + gctSIZE_T reservedTail;
  123892. +
  123893. + /* Commit counter. */
  123894. + gctPOINTER atomCommit;
  123895. +
  123896. + /* Kernel process ID. */
  123897. + gctUINT32 kernelProcessID;
  123898. +
  123899. + /* End Event signal. */
  123900. + gctSIGNAL endEventSignal;
  123901. +
  123902. +#if gcdSECURE_USER
  123903. + /* Hint array copy buffer. */
  123904. + gctBOOL hintArrayAllocated;
  123905. + gctUINT hintArraySize;
  123906. + gctUINT32_PTR hintArray;
  123907. +#endif
  123908. +};
  123909. +
  123910. +typedef struct _gcsEVENT * gcsEVENT_PTR;
  123911. +
  123912. +/* Structure holding one event to be processed. */
  123913. +typedef struct _gcsEVENT
  123914. +{
  123915. + /* Pointer to next event in queue. */
  123916. + gcsEVENT_PTR next;
  123917. +
  123918. + /* Event information. */
  123919. + gcsHAL_INTERFACE info;
  123920. +
  123921. + /* Process ID owning the event. */
  123922. + gctUINT32 processID;
  123923. +
  123924. +#ifdef __QNXNTO__
  123925. + /* Kernel. */
  123926. + gckKERNEL kernel;
  123927. +#endif
  123928. +
  123929. + gctBOOL fromKernel;
  123930. +}
  123931. +gcsEVENT;
  123932. +
  123933. +/* Structure holding a list of events to be processed by an interrupt. */
  123934. +typedef struct _gcsEVENT_QUEUE * gcsEVENT_QUEUE_PTR;
  123935. +typedef struct _gcsEVENT_QUEUE
  123936. +{
  123937. + /* Time stamp. */
  123938. + gctUINT64 stamp;
  123939. +
  123940. + /* Source of the event. */
  123941. + gceKERNEL_WHERE source;
  123942. +
  123943. + /* Pointer to head of event queue. */
  123944. + gcsEVENT_PTR head;
  123945. +
  123946. + /* Pointer to tail of event queue. */
  123947. + gcsEVENT_PTR tail;
  123948. +
  123949. + /* Next list of events. */
  123950. + gcsEVENT_QUEUE_PTR next;
  123951. +}
  123952. +gcsEVENT_QUEUE;
  123953. +
  123954. +/*
  123955. + gcdREPO_LIST_COUNT defines the maximum number of event queues with different
  123956. + hardware module sources that may coexist at the same time. Only two sources
  123957. + are supported - gcvKERNEL_COMMAND and gcvKERNEL_PIXEL. gcvKERNEL_COMMAND
  123958. + source is used only for managing the kernel command queue and is only issued
  123959. + when the current command queue gets full. Since we commit event queues every
  123960. + time we commit command buffers, in the worst case we can have up to three
  123961. + pending event queues:
  123962. + - gcvKERNEL_PIXEL
  123963. + - gcvKERNEL_COMMAND (queue overflow)
  123964. + - gcvKERNEL_PIXEL
  123965. +*/
  123966. +#define gcdREPO_LIST_COUNT 3
  123967. +
  123968. +/* gckEVENT object. */
  123969. +struct _gckEVENT
  123970. +{
  123971. + /* The object. */
  123972. + gcsOBJECT object;
  123973. +
  123974. + /* Pointer to required objects. */
  123975. + gckOS os;
  123976. + gckKERNEL kernel;
  123977. +
  123978. + /* Time stamp. */
  123979. + gctUINT64 stamp;
  123980. + gctUINT64 lastCommitStamp;
  123981. +
  123982. + /* Queue mutex. */
  123983. + gctPOINTER eventQueueMutex;
  123984. +
  123985. + /* Array of event queues. */
  123986. + gcsEVENT_QUEUE queues[30];
  123987. + gctUINT8 lastID;
  123988. + gctPOINTER freeAtom;
  123989. +
  123990. + /* Pending events. */
  123991. +#if gcdSMP
  123992. + gctPOINTER pending;
  123993. +#else
  123994. + volatile gctUINT pending;
  123995. +#endif
  123996. +
  123997. + /* List of free event structures and its mutex. */
  123998. + gcsEVENT_PTR freeEventList;
  123999. + gctSIZE_T freeEventCount;
  124000. + gctPOINTER freeEventMutex;
  124001. +
  124002. + /* Event queues. */
  124003. + gcsEVENT_QUEUE_PTR queueHead;
  124004. + gcsEVENT_QUEUE_PTR queueTail;
  124005. + gcsEVENT_QUEUE_PTR freeList;
  124006. + gcsEVENT_QUEUE repoList[gcdREPO_LIST_COUNT];
  124007. + gctPOINTER eventListMutex;
  124008. +
  124009. + gctPOINTER submitTimer;
  124010. +
  124011. + volatile gctBOOL inNotify;
  124012. +};
  124013. +
  124014. +/* Free all events belonging to a process. */
  124015. +gceSTATUS
  124016. +gckEVENT_FreeProcess(
  124017. + IN gckEVENT Event,
  124018. + IN gctUINT32 ProcessID
  124019. + );
  124020. +
  124021. +gceSTATUS
  124022. +gckEVENT_Stop(
  124023. + IN gckEVENT Event,
  124024. + IN gctUINT32 ProcessID,
  124025. + IN gctPHYS_ADDR Handle,
  124026. + IN gctPOINTER Logical,
  124027. + IN gctSIGNAL Signal,
  124028. + IN OUT gctSIZE_T * waitSize
  124029. + );
  124030. +
  124031. +gceSTATUS
  124032. +gckEVENT_WaitEmpty(
  124033. + IN gckEVENT Event
  124034. + );
  124035. +
  124036. +/* gcuVIDMEM_NODE structure. */
  124037. +typedef union _gcuVIDMEM_NODE
  124038. +{
  124039. + /* Allocated from gckVIDMEM. */
  124040. + struct _gcsVIDMEM_NODE_VIDMEM
  124041. + {
  124042. + /* Owner of this node. */
  124043. + gckVIDMEM memory;
  124044. +
  124045. + /* Dual-linked list of nodes. */
  124046. + gcuVIDMEM_NODE_PTR next;
  124047. + gcuVIDMEM_NODE_PTR prev;
  124048. +
  124049. + /* Dual linked list of free nodes. */
  124050. + gcuVIDMEM_NODE_PTR nextFree;
  124051. + gcuVIDMEM_NODE_PTR prevFree;
  124052. +
  124053. + /* Information for this node. */
  124054. + gctUINT32 offset;
  124055. + gctSIZE_T bytes;
  124056. + gctUINT32 alignment;
  124057. +
  124058. +#ifdef __QNXNTO__
  124059. + /* Client/server vaddr (mapped using mmap_join). */
  124060. + gctPOINTER logical;
  124061. +#endif
  124062. +
  124063. + /* Locked counter. */
  124064. + gctINT32 locked;
  124065. +
  124066. + /* Memory pool. */
  124067. + gcePOOL pool;
  124068. + gctUINT32 physical;
  124069. +
  124070. + /* Process ID owning this memory. */
  124071. + gctUINT32 processID;
  124072. +
  124073. + /* Prevent compositor from freeing until client unlocks. */
  124074. + gctBOOL freePending;
  124075. +
  124076. + /* */
  124077. + gcsVIDMEM_NODE_SHARED_INFO sharedInfo;
  124078. +
  124079. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  124080. + gctPOINTER kernelVirtual;
  124081. +#endif
  124082. +
  124083. + /* Surface type. */
  124084. + gceSURF_TYPE type;
  124085. + }
  124086. + VidMem;
  124087. +
  124088. + /* Allocated from gckOS. */
  124089. + struct _gcsVIDMEM_NODE_VIRTUAL
  124090. + {
  124091. + /* Pointer to gckKERNEL object. */
  124092. + gckKERNEL kernel;
  124093. +
  124094. + /* Information for this node. */
  124095. + /* Contiguously allocated? */
  124096. + gctBOOL contiguous;
  124097. + /* mdl record pointer... a kmalloc address. Process agnostic. */
  124098. + gctPHYS_ADDR physical;
  124099. + gctSIZE_T bytes;
  124100. + /* do_mmap_pgoff address... mapped per-process. */
  124101. + gctPOINTER logical;
  124102. +
  124103. + /* Page table information. */
  124104. + /* Used only when node is not contiguous */
  124105. + gctSIZE_T pageCount;
  124106. +
  124107. + /* Used only when node is not contiguous */
  124108. + gctPOINTER pageTables[gcdMAX_GPU_COUNT];
  124109. + /* Pointer to gckKERNEL object who lock this. */
  124110. + gckKERNEL lockKernels[gcdMAX_GPU_COUNT];
  124111. + /* Actual physical address */
  124112. + gctUINT32 addresses[gcdMAX_GPU_COUNT];
  124113. +
  124114. + /* Mutex. */
  124115. + gctPOINTER mutex;
  124116. +
  124117. + /* Locked counter. */
  124118. + gctINT32 lockeds[gcdMAX_GPU_COUNT];
  124119. +
  124120. +#ifdef __QNXNTO__
  124121. + /* Single linked list of nodes. */
  124122. + gcuVIDMEM_NODE_PTR next;
  124123. +
  124124. + /* Unlock pending flag. */
  124125. + gctBOOL unlockPendings[gcdMAX_GPU_COUNT];
  124126. +
  124127. + /* Free pending flag. */
  124128. + gctBOOL freePending;
  124129. +#endif
  124130. +
  124131. + /* Process ID owning this memory. */
  124132. + gctUINT32 processID;
  124133. +
  124134. + /* Owner process sets freed to true
  124135. + * when it trys to free a locked
  124136. + * node */
  124137. + gctBOOL freed;
  124138. +
  124139. + /* */
  124140. + gcsVIDMEM_NODE_SHARED_INFO sharedInfo;
  124141. +
  124142. + /* Surface type. */
  124143. + gceSURF_TYPE type;
  124144. + }
  124145. + Virtual;
  124146. +}
  124147. +gcuVIDMEM_NODE;
  124148. +
  124149. +/* gckVIDMEM object. */
  124150. +struct _gckVIDMEM
  124151. +{
  124152. + /* Object. */
  124153. + gcsOBJECT object;
  124154. +
  124155. + /* Pointer to gckOS object. */
  124156. + gckOS os;
  124157. +
  124158. + /* Information for this video memory heap. */
  124159. + gctUINT32 baseAddress;
  124160. + gctSIZE_T bytes;
  124161. + gctSIZE_T freeBytes;
  124162. +
  124163. + /* Mapping for each type of surface. */
  124164. + gctINT mapping[gcvSURF_NUM_TYPES];
  124165. +
  124166. + /* Sentinel nodes for up to 8 banks. */
  124167. + gcuVIDMEM_NODE sentinel[8];
  124168. +
  124169. + /* Allocation threshold. */
  124170. + gctSIZE_T threshold;
  124171. +
  124172. + /* The heap mutex. */
  124173. + gctPOINTER mutex;
  124174. +
  124175. +#if gcdUSE_VIDMEM_PER_PID
  124176. + /* The Pid this VidMem belongs to. */
  124177. + gctUINT32 pid;
  124178. +
  124179. + struct _gckVIDMEM* next;
  124180. +#endif
  124181. +};
  124182. +
  124183. +/* gckMMU object. */
  124184. +struct _gckMMU
  124185. +{
  124186. + /* The object. */
  124187. + gcsOBJECT object;
  124188. +
  124189. + /* Pointer to gckOS object. */
  124190. + gckOS os;
  124191. +
  124192. + /* Pointer to gckHARDWARE object. */
  124193. + gckHARDWARE hardware;
  124194. +
  124195. + /* The page table mutex. */
  124196. + gctPOINTER pageTableMutex;
  124197. +
  124198. + /* Page table information. */
  124199. + gctSIZE_T pageTableSize;
  124200. + gctPHYS_ADDR pageTablePhysical;
  124201. + gctUINT32_PTR pageTableLogical;
  124202. + gctUINT32 pageTableEntries;
  124203. +
  124204. + /* Master TLB information. */
  124205. + gctSIZE_T mtlbSize;
  124206. + gctPHYS_ADDR mtlbPhysical;
  124207. + gctUINT32_PTR mtlbLogical;
  124208. + gctUINT32 mtlbEntries;
  124209. +
  124210. + /* Free entries. */
  124211. + gctUINT32 heapList;
  124212. + gctBOOL freeNodes;
  124213. +
  124214. + gctPOINTER staticSTLB;
  124215. + gctBOOL enabled;
  124216. +
  124217. + gctUINT32 dynamicMappingStart;
  124218. +
  124219. +#ifdef __QNXNTO__
  124220. + /* Single linked list of all allocated nodes. */
  124221. + gctPOINTER nodeMutex;
  124222. + gcuVIDMEM_NODE_PTR nodeList;
  124223. +#endif
  124224. +};
  124225. +
  124226. +#if gcdVIRTUAL_COMMAND_BUFFER
  124227. +gceSTATUS
  124228. +gckOS_CreateKernelVirtualMapping(
  124229. + IN gctPHYS_ADDR Physical,
  124230. + OUT gctSIZE_T * PageCount,
  124231. + OUT gctPOINTER * Logical
  124232. + );
  124233. +
  124234. +gceSTATUS
  124235. +gckOS_DestroyKernelVirtualMapping(
  124236. + IN gctPOINTER Logical
  124237. + );
  124238. +
  124239. +gceSTATUS
  124240. +gckKERNEL_AllocateVirtualCommandBuffer(
  124241. + IN gckKERNEL Kernel,
  124242. + IN gctBOOL InUserSpace,
  124243. + IN OUT gctSIZE_T * Bytes,
  124244. + OUT gctPHYS_ADDR * Physical,
  124245. + OUT gctPOINTER * Logical
  124246. + );
  124247. +
  124248. +gceSTATUS
  124249. +gckKERNEL_DestroyVirtualCommandBuffer(
  124250. + IN gckKERNEL Kernel,
  124251. + IN gctSIZE_T Bytes,
  124252. + IN gctPHYS_ADDR Physical,
  124253. + IN gctPOINTER Logical
  124254. + );
  124255. +
  124256. +gceSTATUS
  124257. +gckKERNEL_GetGPUAddress(
  124258. + IN gckKERNEL Kernel,
  124259. + IN gctPOINTER Logical,
  124260. + OUT gctUINT32 * Address
  124261. + );
  124262. +
  124263. +gceSTATUS
  124264. +gckKERNEL_QueryGPUAddress(
  124265. + IN gckKERNEL Kernel,
  124266. + IN gctUINT32 GpuAddress,
  124267. + OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
  124268. + );
  124269. +#endif
  124270. +
  124271. +gceSTATUS
  124272. +gckKERNEL_AttachProcess(
  124273. + IN gckKERNEL Kernel,
  124274. + IN gctBOOL Attach
  124275. + );
  124276. +
  124277. +gceSTATUS
  124278. +gckKERNEL_AttachProcessEx(
  124279. + IN gckKERNEL Kernel,
  124280. + IN gctBOOL Attach,
  124281. + IN gctUINT32 PID
  124282. + );
  124283. +
  124284. +#if gcdSECURE_USER
  124285. +gceSTATUS
  124286. +gckKERNEL_MapLogicalToPhysical(
  124287. + IN gckKERNEL Kernel,
  124288. + IN gcskSECURE_CACHE_PTR Cache,
  124289. + IN OUT gctPOINTER * Data
  124290. + );
  124291. +
  124292. +gceSTATUS
  124293. +gckKERNEL_FlushTranslationCache(
  124294. + IN gckKERNEL Kernel,
  124295. + IN gcskSECURE_CACHE_PTR Cache,
  124296. + IN gctPOINTER Logical,
  124297. + IN gctSIZE_T Bytes
  124298. + );
  124299. +#endif
  124300. +
  124301. +gceSTATUS
  124302. +gckHARDWARE_QueryIdle(
  124303. + IN gckHARDWARE Hardware,
  124304. + OUT gctBOOL_PTR IsIdle
  124305. + );
  124306. +
  124307. +/******************************************************************************\
  124308. +******************************* gckCONTEXT Object *******************************
  124309. +\******************************************************************************/
  124310. +
  124311. +gceSTATUS
  124312. +gckCONTEXT_Construct(
  124313. + IN gckOS Os,
  124314. + IN gckHARDWARE Hardware,
  124315. + IN gctUINT32 ProcessID,
  124316. + OUT gckCONTEXT * Context
  124317. + );
  124318. +
  124319. +gceSTATUS
  124320. +gckCONTEXT_Destroy(
  124321. + IN gckCONTEXT Context
  124322. + );
  124323. +
  124324. +gceSTATUS
  124325. +gckCONTEXT_Update(
  124326. + IN gckCONTEXT Context,
  124327. + IN gctUINT32 ProcessID,
  124328. + IN gcsSTATE_DELTA_PTR StateDelta
  124329. + );
  124330. +
  124331. +#if gcdLINK_QUEUE_SIZE
  124332. +void
  124333. +gckLINKQUEUE_Enqueue(
  124334. + IN gckLINKQUEUE LinkQueue,
  124335. + IN gctUINT32 start,
  124336. + IN gctUINT32 end
  124337. + );
  124338. +
  124339. +void
  124340. +gckLINKQUEUE_GetData(
  124341. + IN gckLINKQUEUE LinkQueue,
  124342. + IN gctUINT32 Index,
  124343. + OUT gckLINKDATA * Data
  124344. + );
  124345. +#endif
  124346. +
  124347. +
  124348. +#ifdef __cplusplus
  124349. +}
  124350. +#endif
  124351. +
  124352. +#endif /* __gc_hal_kernel_h_ */
  124353. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c
  124354. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c 1969-12-31 18:00:00.000000000 -0600
  124355. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c 2014-12-08 00:31:53.464418001 -0600
  124356. @@ -0,0 +1,859 @@
  124357. +/****************************************************************************
  124358. +*
  124359. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  124360. +*
  124361. +* This program is free software; you can redistribute it and/or modify
  124362. +* it under the terms of the GNU General Public License as published by
  124363. +* the Free Software Foundation; either version 2 of the license, or
  124364. +* (at your option) any later version.
  124365. +*
  124366. +* This program is distributed in the hope that it will be useful,
  124367. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  124368. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  124369. +* GNU General Public License for more details.
  124370. +*
  124371. +* You should have received a copy of the GNU General Public License
  124372. +* along with this program; if not write to the Free Software
  124373. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  124374. +*
  124375. +*****************************************************************************/
  124376. +
  124377. +
  124378. +/**
  124379. +** @file
  124380. +** gckHEAP object for kernel HAL layer. The heap implemented here is an arena-
  124381. +** based memory allocation. An arena-based memory heap allocates data quickly
  124382. +** from specified arenas and reduces memory fragmentation.
  124383. +**
  124384. +*/
  124385. +#include "gc_hal_kernel_precomp.h"
  124386. +
  124387. +#define _GC_OBJ_ZONE gcvZONE_HEAP
  124388. +
  124389. +/*******************************************************************************
  124390. +***** Structures ***************************************************************
  124391. +*******************************************************************************/
  124392. +
  124393. +#define gcdIN_USE ((gcskNODE_PTR) ~0)
  124394. +
  124395. +typedef struct _gcskNODE * gcskNODE_PTR;
  124396. +typedef struct _gcskNODE
  124397. +{
  124398. + /* Number of byets in node. */
  124399. + gctSIZE_T bytes;
  124400. +
  124401. + /* Pointer to next free node, or gcvNULL to mark the node as freed, or
  124402. + ** gcdIN_USE to mark the node as used. */
  124403. + gcskNODE_PTR next;
  124404. +
  124405. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124406. + /* Time stamp of allocation. */
  124407. + gctUINT64 timeStamp;
  124408. +#endif
  124409. +}
  124410. +gcskNODE;
  124411. +
  124412. +typedef struct _gcskHEAP * gcskHEAP_PTR;
  124413. +typedef struct _gcskHEAP
  124414. +{
  124415. + /* Linked list. */
  124416. + gcskHEAP_PTR next;
  124417. + gcskHEAP_PTR prev;
  124418. +
  124419. + /* Heap size. */
  124420. + gctSIZE_T size;
  124421. +
  124422. + /* Free list. */
  124423. + gcskNODE_PTR freeList;
  124424. +}
  124425. +gcskHEAP;
  124426. +
  124427. +struct _gckHEAP
  124428. +{
  124429. + /* Object. */
  124430. + gcsOBJECT object;
  124431. +
  124432. + /* Pointer to a gckOS object. */
  124433. + gckOS os;
  124434. +
  124435. + /* Locking mutex. */
  124436. + gctPOINTER mutex;
  124437. +
  124438. + /* Allocation parameters. */
  124439. + gctSIZE_T allocationSize;
  124440. +
  124441. + /* Heap list. */
  124442. + gcskHEAP_PTR heap;
  124443. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124444. + gctUINT64 timeStamp;
  124445. +#endif
  124446. +
  124447. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  124448. + /* Profile information. */
  124449. + gctUINT32 allocCount;
  124450. + gctUINT64 allocBytes;
  124451. + gctUINT64 allocBytesMax;
  124452. + gctUINT64 allocBytesTotal;
  124453. + gctUINT32 heapCount;
  124454. + gctUINT32 heapCountMax;
  124455. + gctUINT64 heapMemory;
  124456. + gctUINT64 heapMemoryMax;
  124457. +#endif
  124458. +};
  124459. +
  124460. +/*******************************************************************************
  124461. +***** Static Support Functions *************************************************
  124462. +*******************************************************************************/
  124463. +
  124464. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124465. +static gctSIZE_T
  124466. +_DumpHeap(
  124467. + IN gcskHEAP_PTR Heap
  124468. + )
  124469. +{
  124470. + gctPOINTER p;
  124471. + gctSIZE_T leaked = 0;
  124472. +
  124473. + /* Start at first node. */
  124474. + for (p = Heap + 1;;)
  124475. + {
  124476. + /* Convert the pointer. */
  124477. + gcskNODE_PTR node = (gcskNODE_PTR) p;
  124478. +
  124479. + /* Check if this is a used node. */
  124480. + if (node->next == gcdIN_USE)
  124481. + {
  124482. + /* Print the leaking node. */
  124483. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_HEAP,
  124484. + "Detected leaking: node=0x%x bytes=%lu timeStamp=%llu "
  124485. + "(%08X %c%c%c%c)",
  124486. + node, node->bytes, node->timeStamp,
  124487. + ((gctUINT32_PTR) (node + 1))[0],
  124488. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[0]),
  124489. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[1]),
  124490. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[2]),
  124491. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[3]));
  124492. +
  124493. + /* Add leaking byte count. */
  124494. + leaked += node->bytes;
  124495. + }
  124496. +
  124497. + /* Test for end of heap. */
  124498. + if (node->bytes == 0)
  124499. + {
  124500. + break;
  124501. + }
  124502. +
  124503. + else
  124504. + {
  124505. + /* Move to next node. */
  124506. + p = (gctUINT8_PTR) node + node->bytes;
  124507. + }
  124508. + }
  124509. +
  124510. + /* Return the number of leaked bytes. */
  124511. + return leaked;
  124512. +}
  124513. +#endif
  124514. +
  124515. +static gceSTATUS
  124516. +_CompactKernelHeap(
  124517. + IN gckHEAP Heap
  124518. + )
  124519. +{
  124520. + gcskHEAP_PTR heap, next;
  124521. + gctPOINTER p;
  124522. + gcskHEAP_PTR freeList = gcvNULL;
  124523. +
  124524. + gcmkHEADER_ARG("Heap=0x%x", Heap);
  124525. +
  124526. + /* Walk all the heaps. */
  124527. + for (heap = Heap->heap; heap != gcvNULL; heap = next)
  124528. + {
  124529. + gcskNODE_PTR lastFree = gcvNULL;
  124530. +
  124531. + /* Zero out the free list. */
  124532. + heap->freeList = gcvNULL;
  124533. +
  124534. + /* Start at the first node. */
  124535. + for (p = (gctUINT8_PTR) (heap + 1);;)
  124536. + {
  124537. + /* Convert the pointer. */
  124538. + gcskNODE_PTR node = (gcskNODE_PTR) p;
  124539. +
  124540. + gcmkASSERT(p <= (gctPOINTER) ((gctUINT8_PTR) (heap + 1) + heap->size));
  124541. +
  124542. + /* Test if this node not used. */
  124543. + if (node->next != gcdIN_USE)
  124544. + {
  124545. + /* Test if this is the end of the heap. */
  124546. + if (node->bytes == 0)
  124547. + {
  124548. + break;
  124549. + }
  124550. +
  124551. + /* Test of this is the first free node. */
  124552. + else if (lastFree == gcvNULL)
  124553. + {
  124554. + /* Initialzie the free list. */
  124555. + heap->freeList = node;
  124556. + lastFree = node;
  124557. + }
  124558. +
  124559. + else
  124560. + {
  124561. + /* Test if this free node is contiguous with the previous
  124562. + ** free node. */
  124563. + if ((gctUINT8_PTR) lastFree + lastFree->bytes == p)
  124564. + {
  124565. + /* Just increase the size of the previous free node. */
  124566. + lastFree->bytes += node->bytes;
  124567. + }
  124568. + else
  124569. + {
  124570. + /* Add to linked list. */
  124571. + lastFree->next = node;
  124572. + lastFree = node;
  124573. + }
  124574. + }
  124575. + }
  124576. +
  124577. + /* Move to next node. */
  124578. + p = (gctUINT8_PTR) node + node->bytes;
  124579. + }
  124580. +
  124581. + /* Mark the end of the chain. */
  124582. + if (lastFree != gcvNULL)
  124583. + {
  124584. + lastFree->next = gcvNULL;
  124585. + }
  124586. +
  124587. + /* Get next heap. */
  124588. + next = heap->next;
  124589. +
  124590. + /* Check if the entire heap is free. */
  124591. + if ((heap->freeList != gcvNULL)
  124592. + && (heap->freeList->bytes == heap->size - gcmSIZEOF(gcskNODE))
  124593. + )
  124594. + {
  124595. + /* Remove the heap from the linked list. */
  124596. + if (heap->prev == gcvNULL)
  124597. + {
  124598. + Heap->heap = next;
  124599. + }
  124600. + else
  124601. + {
  124602. + heap->prev->next = next;
  124603. + }
  124604. +
  124605. + if (heap->next != gcvNULL)
  124606. + {
  124607. + heap->next->prev = heap->prev;
  124608. + }
  124609. +
  124610. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  124611. + /* Update profiling. */
  124612. + Heap->heapCount -= 1;
  124613. + Heap->heapMemory -= heap->size + gcmSIZEOF(gcskHEAP);
  124614. +#endif
  124615. +
  124616. + /* Add this heap to the list of heaps that need to be freed. */
  124617. + heap->next = freeList;
  124618. + freeList = heap;
  124619. + }
  124620. + }
  124621. +
  124622. + if (freeList != gcvNULL)
  124623. + {
  124624. + /* Release the mutex, remove any chance for a dead lock. */
  124625. + gcmkVERIFY_OK(
  124626. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  124627. +
  124628. + /* Free all heaps in the free list. */
  124629. + for (heap = freeList; heap != gcvNULL; heap = next)
  124630. + {
  124631. + /* Get pointer to the next heap. */
  124632. + next = heap->next;
  124633. +
  124634. + /* Free the heap. */
  124635. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HEAP,
  124636. + "Freeing heap 0x%x (%lu bytes)",
  124637. + heap, heap->size + gcmSIZEOF(gcskHEAP));
  124638. + gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, heap));
  124639. + }
  124640. +
  124641. + /* Acquire the mutex again. */
  124642. + gcmkVERIFY_OK(
  124643. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  124644. + }
  124645. +
  124646. + /* Success. */
  124647. + gcmkFOOTER_NO();
  124648. + return gcvSTATUS_OK;
  124649. +}
  124650. +
  124651. +/*******************************************************************************
  124652. +***** gckHEAP API Code *********************************************************
  124653. +*******************************************************************************/
  124654. +
  124655. +/*******************************************************************************
  124656. +**
  124657. +** gckHEAP_Construct
  124658. +**
  124659. +** Construct a new gckHEAP object.
  124660. +**
  124661. +** INPUT:
  124662. +**
  124663. +** gckOS Os
  124664. +** Pointer to a gckOS object.
  124665. +**
  124666. +** gctSIZE_T AllocationSize
  124667. +** Minimum size per arena.
  124668. +**
  124669. +** OUTPUT:
  124670. +**
  124671. +** gckHEAP * Heap
  124672. +** Pointer to a variable that will hold the pointer to the gckHEAP
  124673. +** object.
  124674. +*/
  124675. +gceSTATUS
  124676. +gckHEAP_Construct(
  124677. + IN gckOS Os,
  124678. + IN gctSIZE_T AllocationSize,
  124679. + OUT gckHEAP * Heap
  124680. + )
  124681. +{
  124682. + gceSTATUS status;
  124683. + gckHEAP heap = gcvNULL;
  124684. + gctPOINTER pointer = gcvNULL;
  124685. +
  124686. + gcmkHEADER_ARG("Os=0x%x AllocationSize=%lu", Os, AllocationSize);
  124687. +
  124688. + /* Verify the arguments. */
  124689. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  124690. + gcmkVERIFY_ARGUMENT(Heap != gcvNULL);
  124691. +
  124692. + /* Allocate the gckHEAP object. */
  124693. + gcmkONERROR(gckOS_AllocateMemory(Os,
  124694. + gcmSIZEOF(struct _gckHEAP),
  124695. + &pointer));
  124696. +
  124697. + heap = pointer;
  124698. +
  124699. + /* Initialize the gckHEAP object. */
  124700. + heap->object.type = gcvOBJ_HEAP;
  124701. + heap->os = Os;
  124702. + heap->allocationSize = AllocationSize;
  124703. + heap->heap = gcvNULL;
  124704. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124705. + heap->timeStamp = 0;
  124706. +#endif
  124707. +
  124708. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  124709. + /* Zero the counters. */
  124710. + heap->allocCount = 0;
  124711. + heap->allocBytes = 0;
  124712. + heap->allocBytesMax = 0;
  124713. + heap->allocBytesTotal = 0;
  124714. + heap->heapCount = 0;
  124715. + heap->heapCountMax = 0;
  124716. + heap->heapMemory = 0;
  124717. + heap->heapMemoryMax = 0;
  124718. +#endif
  124719. +
  124720. + /* Create the mutex. */
  124721. + gcmkONERROR(gckOS_CreateMutex(Os, &heap->mutex));
  124722. +
  124723. + /* Return the pointer to the gckHEAP object. */
  124724. + *Heap = heap;
  124725. +
  124726. + /* Success. */
  124727. + gcmkFOOTER_ARG("*Heap=0x%x", *Heap);
  124728. + return gcvSTATUS_OK;
  124729. +
  124730. +OnError:
  124731. + /* Roll back. */
  124732. + if (heap != gcvNULL)
  124733. + {
  124734. + /* Free the heap structure. */
  124735. + gcmkVERIFY_OK(gckOS_FreeMemory(Os, heap));
  124736. + }
  124737. +
  124738. + /* Return the status. */
  124739. + gcmkFOOTER();
  124740. + return status;
  124741. +}
  124742. +
  124743. +/*******************************************************************************
  124744. +**
  124745. +** gckHEAP_Destroy
  124746. +**
  124747. +** Destroy a gckHEAP object.
  124748. +**
  124749. +** INPUT:
  124750. +**
  124751. +** gckHEAP Heap
  124752. +** Pointer to a gckHEAP object to destroy.
  124753. +**
  124754. +** OUTPUT:
  124755. +**
  124756. +** Nothing.
  124757. +*/
  124758. +gceSTATUS
  124759. +gckHEAP_Destroy(
  124760. + IN gckHEAP Heap
  124761. + )
  124762. +{
  124763. + gcskHEAP_PTR heap;
  124764. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124765. + gctSIZE_T leaked = 0;
  124766. +#endif
  124767. +
  124768. + gcmkHEADER_ARG("Heap=0x%x", Heap);
  124769. +
  124770. + for (heap = Heap->heap; heap != gcvNULL; heap = Heap->heap)
  124771. + {
  124772. + /* Unlink heap from linked list. */
  124773. + Heap->heap = heap->next;
  124774. +
  124775. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124776. + /* Check for leaked memory. */
  124777. + leaked += _DumpHeap(heap);
  124778. +#endif
  124779. +
  124780. + /* Free the heap. */
  124781. + gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, heap));
  124782. + }
  124783. +
  124784. + /* Free the mutex. */
  124785. + gcmkVERIFY_OK(gckOS_DeleteMutex(Heap->os, Heap->mutex));
  124786. +
  124787. + /* Free the heap structure. */
  124788. + gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, Heap));
  124789. +
  124790. + /* Success. */
  124791. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124792. + gcmkFOOTER_ARG("leaked=%lu", leaked);
  124793. +#else
  124794. + gcmkFOOTER_NO();
  124795. +#endif
  124796. + return gcvSTATUS_OK;
  124797. +}
  124798. +
  124799. +/*******************************************************************************
  124800. +**
  124801. +** gckHEAP_Allocate
  124802. +**
  124803. +** Allocate data from the heap.
  124804. +**
  124805. +** INPUT:
  124806. +**
  124807. +** gckHEAP Heap
  124808. +** Pointer to a gckHEAP object.
  124809. +**
  124810. +** IN gctSIZE_T Bytes
  124811. +** Number of byte to allocate.
  124812. +**
  124813. +** OUTPUT:
  124814. +**
  124815. +** gctPOINTER * Memory
  124816. +** Pointer to a variable that will hold the address of the allocated
  124817. +** memory.
  124818. +*/
  124819. +gceSTATUS
  124820. +gckHEAP_Allocate(
  124821. + IN gckHEAP Heap,
  124822. + IN gctSIZE_T Bytes,
  124823. + OUT gctPOINTER * Memory
  124824. + )
  124825. +{
  124826. + gctBOOL acquired = gcvFALSE;
  124827. + gcskHEAP_PTR heap;
  124828. + gceSTATUS status;
  124829. + gctSIZE_T bytes;
  124830. + gcskNODE_PTR node, used, prevFree = gcvNULL;
  124831. + gctPOINTER memory = gcvNULL;
  124832. +
  124833. + gcmkHEADER_ARG("Heap=0x%x Bytes=%lu", Heap, Bytes);
  124834. +
  124835. + /* Verify the arguments. */
  124836. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  124837. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  124838. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  124839. +
  124840. + /* Determine number of bytes required for a node. */
  124841. + bytes = gcmALIGN(Bytes + gcmSIZEOF(gcskNODE), 8);
  124842. +
  124843. + /* Acquire the mutex. */
  124844. + gcmkONERROR(
  124845. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  124846. +
  124847. + acquired = gcvTRUE;
  124848. +
  124849. + /* Check if this allocation is bigger than the default allocation size. */
  124850. + if (bytes > Heap->allocationSize - gcmSIZEOF(gcskHEAP) - gcmSIZEOF(gcskNODE))
  124851. + {
  124852. + /* Adjust allocation size. */
  124853. + Heap->allocationSize = bytes * 2;
  124854. + }
  124855. +
  124856. + else if (Heap->heap != gcvNULL)
  124857. + {
  124858. + gctINT i;
  124859. +
  124860. + /* 2 retries, since we might need to compact. */
  124861. + for (i = 0; i < 2; ++i)
  124862. + {
  124863. + /* Walk all the heaps. */
  124864. + for (heap = Heap->heap; heap != gcvNULL; heap = heap->next)
  124865. + {
  124866. + /* Check if this heap has enough bytes to hold the request. */
  124867. + if (bytes <= heap->size - gcmSIZEOF(gcskNODE))
  124868. + {
  124869. + prevFree = gcvNULL;
  124870. +
  124871. + /* Walk the chain of free nodes. */
  124872. + for (node = heap->freeList;
  124873. + node != gcvNULL;
  124874. + node = node->next
  124875. + )
  124876. + {
  124877. + gcmkASSERT(node->next != gcdIN_USE);
  124878. +
  124879. + /* Check if this free node has enough bytes. */
  124880. + if (node->bytes >= bytes)
  124881. + {
  124882. + /* Use the node. */
  124883. + goto UseNode;
  124884. + }
  124885. +
  124886. + /* Save current free node for linked list management. */
  124887. + prevFree = node;
  124888. + }
  124889. + }
  124890. + }
  124891. +
  124892. + if (i == 0)
  124893. + {
  124894. + /* Compact the heap. */
  124895. + gcmkVERIFY_OK(_CompactKernelHeap(Heap));
  124896. +
  124897. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  124898. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124899. + "===== KERNEL HEAP =====");
  124900. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124901. + "Number of allocations : %12u",
  124902. + Heap->allocCount);
  124903. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124904. + "Number of bytes allocated : %12llu",
  124905. + Heap->allocBytes);
  124906. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124907. + "Maximum allocation size : %12llu",
  124908. + Heap->allocBytesMax);
  124909. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124910. + "Total number of bytes allocated : %12llu",
  124911. + Heap->allocBytesTotal);
  124912. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124913. + "Number of heaps : %12u",
  124914. + Heap->heapCount);
  124915. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124916. + "Heap memory in bytes : %12llu",
  124917. + Heap->heapMemory);
  124918. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124919. + "Maximum number of heaps : %12u",
  124920. + Heap->heapCountMax);
  124921. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  124922. + "Maximum heap memory in bytes : %12llu",
  124923. + Heap->heapMemoryMax);
  124924. +#endif
  124925. + }
  124926. + }
  124927. + }
  124928. +
  124929. + /* Release the mutex. */
  124930. + gcmkONERROR(
  124931. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  124932. +
  124933. + acquired = gcvFALSE;
  124934. +
  124935. + /* Allocate a new heap. */
  124936. + gcmkONERROR(
  124937. + gckOS_AllocateMemory(Heap->os,
  124938. + Heap->allocationSize,
  124939. + &memory));
  124940. +
  124941. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HEAP,
  124942. + "Allocated heap 0x%x (%lu bytes)",
  124943. + memory, Heap->allocationSize);
  124944. +
  124945. + /* Acquire the mutex. */
  124946. + gcmkONERROR(
  124947. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  124948. +
  124949. + acquired = gcvTRUE;
  124950. +
  124951. + /* Use the allocated memory as the heap. */
  124952. + heap = (gcskHEAP_PTR) memory;
  124953. +
  124954. + /* Insert this heap to the head of the chain. */
  124955. + heap->next = Heap->heap;
  124956. + heap->prev = gcvNULL;
  124957. + heap->size = Heap->allocationSize - gcmSIZEOF(gcskHEAP);
  124958. +
  124959. + if (heap->next != gcvNULL)
  124960. + {
  124961. + heap->next->prev = heap;
  124962. + }
  124963. + Heap->heap = heap;
  124964. +
  124965. + /* Mark the end of the heap. */
  124966. + node = (gcskNODE_PTR) ( (gctUINT8_PTR) heap
  124967. + + Heap->allocationSize
  124968. + - gcmSIZEOF(gcskNODE)
  124969. + );
  124970. + node->bytes = 0;
  124971. + node->next = gcvNULL;
  124972. +
  124973. + /* Create a free list. */
  124974. + node = (gcskNODE_PTR) (heap + 1);
  124975. + heap->freeList = node;
  124976. +
  124977. + /* Initialize the free list. */
  124978. + node->bytes = heap->size - gcmSIZEOF(gcskNODE);
  124979. + node->next = gcvNULL;
  124980. +
  124981. + /* No previous free. */
  124982. + prevFree = gcvNULL;
  124983. +
  124984. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  124985. + /* Update profiling. */
  124986. + Heap->heapCount += 1;
  124987. + Heap->heapMemory += Heap->allocationSize;
  124988. +
  124989. + if (Heap->heapCount > Heap->heapCountMax)
  124990. + {
  124991. + Heap->heapCountMax = Heap->heapCount;
  124992. + }
  124993. + if (Heap->heapMemory > Heap->heapMemoryMax)
  124994. + {
  124995. + Heap->heapMemoryMax = Heap->heapMemory;
  124996. + }
  124997. +#endif
  124998. +
  124999. +UseNode:
  125000. + /* Verify some stuff. */
  125001. + gcmkASSERT(heap != gcvNULL);
  125002. + gcmkASSERT(node != gcvNULL);
  125003. + gcmkASSERT(node->bytes >= bytes);
  125004. +
  125005. + if (heap->prev != gcvNULL)
  125006. + {
  125007. + /* Unlink the heap from the linked list. */
  125008. + heap->prev->next = heap->next;
  125009. + if (heap->next != gcvNULL)
  125010. + {
  125011. + heap->next->prev = heap->prev;
  125012. + }
  125013. +
  125014. + /* Move the heap to the front of the list. */
  125015. + heap->next = Heap->heap;
  125016. + heap->prev = gcvNULL;
  125017. + Heap->heap = heap;
  125018. + heap->next->prev = heap;
  125019. + }
  125020. +
  125021. + /* Check if there is enough free space left after usage for another free
  125022. + ** node. */
  125023. + if (node->bytes - bytes >= gcmSIZEOF(gcskNODE))
  125024. + {
  125025. + /* Allocated used space from the back of the free list. */
  125026. + used = (gcskNODE_PTR) ((gctUINT8_PTR) node + node->bytes - bytes);
  125027. +
  125028. + /* Adjust the number of free bytes. */
  125029. + node->bytes -= bytes;
  125030. + gcmkASSERT(node->bytes >= gcmSIZEOF(gcskNODE));
  125031. + }
  125032. + else
  125033. + {
  125034. + /* Remove this free list from the chain. */
  125035. + if (prevFree == gcvNULL)
  125036. + {
  125037. + heap->freeList = node->next;
  125038. + }
  125039. + else
  125040. + {
  125041. + prevFree->next = node->next;
  125042. + }
  125043. +
  125044. + /* Consume the entire free node. */
  125045. + used = (gcskNODE_PTR) node;
  125046. + bytes = node->bytes;
  125047. + }
  125048. +
  125049. + /* Mark node as used. */
  125050. + used->bytes = bytes;
  125051. + used->next = gcdIN_USE;
  125052. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  125053. + used->timeStamp = ++Heap->timeStamp;
  125054. +#endif
  125055. +
  125056. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  125057. + /* Update profile counters. */
  125058. + Heap->allocCount += 1;
  125059. + Heap->allocBytes += bytes;
  125060. + Heap->allocBytesMax = gcmMAX(Heap->allocBytes, Heap->allocBytesMax);
  125061. + Heap->allocBytesTotal += bytes;
  125062. +#endif
  125063. +
  125064. + /* Release the mutex. */
  125065. + gcmkVERIFY_OK(
  125066. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  125067. +
  125068. + /* Return pointer to memory. */
  125069. + *Memory = used + 1;
  125070. +
  125071. + /* Success. */
  125072. + gcmkFOOTER_ARG("*Memory=0x%x", *Memory);
  125073. + return gcvSTATUS_OK;
  125074. +
  125075. +OnError:
  125076. + if (acquired)
  125077. + {
  125078. + /* Release the mutex. */
  125079. + gcmkVERIFY_OK(
  125080. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  125081. + }
  125082. +
  125083. + if (memory != gcvNULL)
  125084. + {
  125085. + /* Free the heap memory. */
  125086. + gckOS_FreeMemory(Heap->os, memory);
  125087. + }
  125088. +
  125089. + /* Return the status. */
  125090. + gcmkFOOTER();
  125091. + return status;
  125092. +}
  125093. +
  125094. +/*******************************************************************************
  125095. +**
  125096. +** gckHEAP_Free
  125097. +**
  125098. +** Free allocated memory from the heap.
  125099. +**
  125100. +** INPUT:
  125101. +**
  125102. +** gckHEAP Heap
  125103. +** Pointer to a gckHEAP object.
  125104. +**
  125105. +** IN gctPOINTER Memory
  125106. +** Pointer to memory to free.
  125107. +**
  125108. +** OUTPUT:
  125109. +**
  125110. +** NOTHING.
  125111. +*/
  125112. +gceSTATUS
  125113. +gckHEAP_Free(
  125114. + IN gckHEAP Heap,
  125115. + IN gctPOINTER Memory
  125116. + )
  125117. +{
  125118. + gcskNODE_PTR node;
  125119. + gceSTATUS status;
  125120. +
  125121. + gcmkHEADER_ARG("Heap=0x%x Memory=0x%x", Heap, Memory);
  125122. +
  125123. + /* Verify the arguments. */
  125124. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  125125. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  125126. +
  125127. + /* Acquire the mutex. */
  125128. + gcmkONERROR(
  125129. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  125130. +
  125131. + /* Pointer to structure. */
  125132. + node = (gcskNODE_PTR) Memory - 1;
  125133. +
  125134. + /* Mark the node as freed. */
  125135. + node->next = gcvNULL;
  125136. +
  125137. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  125138. + /* Update profile counters. */
  125139. + Heap->allocBytes -= node->bytes;
  125140. +#endif
  125141. +
  125142. + /* Release the mutex. */
  125143. + gcmkVERIFY_OK(
  125144. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  125145. +
  125146. + /* Success. */
  125147. + gcmkFOOTER_NO();
  125148. + return gcvSTATUS_OK;
  125149. +
  125150. +OnError:
  125151. + /* Return the status. */
  125152. + gcmkFOOTER();
  125153. + return status;
  125154. +}
  125155. +
  125156. +#if VIVANTE_PROFILER
  125157. +gceSTATUS
  125158. +gckHEAP_ProfileStart(
  125159. + IN gckHEAP Heap
  125160. + )
  125161. +{
  125162. + gcmkHEADER_ARG("Heap=0x%x", Heap);
  125163. +
  125164. + /* Verify the arguments. */
  125165. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  125166. +
  125167. + /* Zero the counters. */
  125168. + Heap->allocCount = 0;
  125169. + Heap->allocBytes = 0;
  125170. + Heap->allocBytesMax = 0;
  125171. + Heap->allocBytesTotal = 0;
  125172. + Heap->heapCount = 0;
  125173. + Heap->heapCountMax = 0;
  125174. + Heap->heapMemory = 0;
  125175. + Heap->heapMemoryMax = 0;
  125176. +
  125177. + /* Success. */
  125178. + gcmkFOOTER_NO();
  125179. + return gcvSTATUS_OK;
  125180. +}
  125181. +
  125182. +gceSTATUS
  125183. +gckHEAP_ProfileEnd(
  125184. + IN gckHEAP Heap,
  125185. + IN gctCONST_STRING Title
  125186. + )
  125187. +{
  125188. + gcmkHEADER_ARG("Heap=0x%x Title=0x%x", Heap, Title);
  125189. +
  125190. + /* Verify the arguments. */
  125191. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  125192. + gcmkVERIFY_ARGUMENT(Title != gcvNULL);
  125193. +
  125194. + gcmkPRINT("");
  125195. + gcmkPRINT("=====[ HEAP - %s ]=====", Title);
  125196. + gcmkPRINT("Number of allocations : %12u", Heap->allocCount);
  125197. + gcmkPRINT("Number of bytes allocated : %12llu", Heap->allocBytes);
  125198. + gcmkPRINT("Maximum allocation size : %12llu", Heap->allocBytesMax);
  125199. + gcmkPRINT("Total number of bytes allocated : %12llu", Heap->allocBytesTotal);
  125200. + gcmkPRINT("Number of heaps : %12u", Heap->heapCount);
  125201. + gcmkPRINT("Heap memory in bytes : %12llu", Heap->heapMemory);
  125202. + gcmkPRINT("Maximum number of heaps : %12u", Heap->heapCountMax);
  125203. + gcmkPRINT("Maximum heap memory in bytes : %12llu", Heap->heapMemoryMax);
  125204. + gcmkPRINT("==============================================");
  125205. +
  125206. + /* Success. */
  125207. + gcmkFOOTER_NO();
  125208. + return gcvSTATUS_OK;
  125209. +}
  125210. +#endif /* VIVANTE_PROFILER */
  125211. +
  125212. +/*******************************************************************************
  125213. +***** Test Code ****************************************************************
  125214. +*******************************************************************************/
  125215. +
  125216. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c
  125217. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c 1969-12-31 18:00:00.000000000 -0600
  125218. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c 2014-12-08 00:31:53.464418001 -0600
  125219. @@ -0,0 +1,877 @@
  125220. +/****************************************************************************
  125221. +*
  125222. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  125223. +*
  125224. +* This program is free software; you can redistribute it and/or modify
  125225. +* it under the terms of the GNU General Public License as published by
  125226. +* the Free Software Foundation; either version 2 of the license, or
  125227. +* (at your option) any later version.
  125228. +*
  125229. +* This program is distributed in the hope that it will be useful,
  125230. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  125231. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  125232. +* GNU General Public License for more details.
  125233. +*
  125234. +* You should have received a copy of the GNU General Public License
  125235. +* along with this program; if not write to the Free Software
  125236. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  125237. +*
  125238. +*****************************************************************************/
  125239. +
  125240. +
  125241. +#include "gc_hal_kernel_precomp.h"
  125242. +
  125243. +#if gcdENABLE_VG
  125244. +
  125245. +/******************************************************************************\
  125246. +*********************** Support Functions and Definitions **********************
  125247. +\******************************************************************************/
  125248. +
  125249. +/* Interruot statistics will be accumulated if not zero. */
  125250. +#define gcmENABLE_INTERRUPT_STATISTICS 0
  125251. +
  125252. +#define _GC_OBJ_ZONE gcvZONE_INTERRUPT
  125253. +
  125254. +/* Object structure. */
  125255. +struct _gckVGINTERRUPT
  125256. +{
  125257. + /* Object. */
  125258. + gcsOBJECT object;
  125259. +
  125260. + /* gckVGKERNEL pointer. */
  125261. + gckVGKERNEL kernel;
  125262. +
  125263. + /* gckOS pointer. */
  125264. + gckOS os;
  125265. +
  125266. + /* Interrupt handlers. */
  125267. + gctINTERRUPT_HANDLER handlers[32];
  125268. +
  125269. + /* Main interrupt handler thread. */
  125270. + gctTHREAD handler;
  125271. + gctBOOL terminate;
  125272. +
  125273. + /* Interrupt FIFO. */
  125274. + gctSEMAPHORE fifoValid;
  125275. + gctUINT32 fifo[256];
  125276. + gctUINT fifoItems;
  125277. + gctUINT8 head;
  125278. + gctUINT8 tail;
  125279. +
  125280. + /* Interrupt statistics. */
  125281. +#if gcmENABLE_INTERRUPT_STATISTICS
  125282. + gctUINT maxFifoItems;
  125283. + gctUINT fifoOverflow;
  125284. + gctUINT maxSimultaneous;
  125285. + gctUINT multipleCount;
  125286. +#endif
  125287. +};
  125288. +
  125289. +
  125290. +/*******************************************************************************
  125291. +**
  125292. +** _ProcessInterrupt
  125293. +**
  125294. +** The interrupt processor.
  125295. +**
  125296. +** INPUT:
  125297. +**
  125298. +** ThreadParameter
  125299. +** Pointer to the gckVGINTERRUPT object.
  125300. +**
  125301. +** OUTPUT:
  125302. +**
  125303. +** Nothing.
  125304. +*/
  125305. +
  125306. +#if gcmENABLE_INTERRUPT_STATISTICS
  125307. +static void
  125308. +_ProcessInterrupt(
  125309. + gckVGINTERRUPT Interrupt,
  125310. + gctUINT_PTR TriggeredCount
  125311. + )
  125312. +#else
  125313. +static void
  125314. +_ProcessInterrupt(
  125315. + gckVGINTERRUPT Interrupt
  125316. + )
  125317. +#endif
  125318. +{
  125319. + gceSTATUS status;
  125320. + gctUINT32 triggered;
  125321. + gctUINT i;
  125322. +
  125323. + /* Advance to the next entry. */
  125324. + Interrupt->tail += 1;
  125325. + Interrupt->fifoItems -= 1;
  125326. +
  125327. + /* Get the interrupt value. */
  125328. + triggered = Interrupt->fifo[Interrupt->tail];
  125329. + gcmkASSERT(triggered != 0);
  125330. +
  125331. + gcmkTRACE_ZONE(
  125332. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125333. + "%s: triggered=0x%08X\n",
  125334. + __FUNCTION__,
  125335. + triggered
  125336. + );
  125337. +
  125338. + /* Walk through all possible interrupts. */
  125339. + for (i = 0; i < gcmSIZEOF(Interrupt->handlers); i += 1)
  125340. + {
  125341. + /* Test if interrupt happened. */
  125342. + if ((triggered & 1) == 1)
  125343. + {
  125344. +#if gcmENABLE_INTERRUPT_STATISTICS
  125345. + if (TriggeredCount != gcvNULL)
  125346. + {
  125347. + (* TriggeredCount) += 1;
  125348. + }
  125349. +#endif
  125350. +
  125351. + /* Make sure we have valid handler. */
  125352. + if (Interrupt->handlers[i] == gcvNULL)
  125353. + {
  125354. + gcmkTRACE(
  125355. + gcvLEVEL_ERROR,
  125356. + "%s: Interrupt %d isn't registered.\n",
  125357. + __FUNCTION__, i
  125358. + );
  125359. + }
  125360. + else
  125361. + {
  125362. + gcmkTRACE_ZONE(
  125363. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125364. + "%s: interrupt=%d\n",
  125365. + __FUNCTION__,
  125366. + i
  125367. + );
  125368. +
  125369. + /* Call the handler. */
  125370. + status = Interrupt->handlers[i] (Interrupt->kernel);
  125371. +
  125372. + if (gcmkIS_ERROR(status))
  125373. + {
  125374. + /* Failed to signal the semaphore. */
  125375. + gcmkTRACE(
  125376. + gcvLEVEL_ERROR,
  125377. + "%s: Error %d incrementing the semaphore #%d.\n",
  125378. + __FUNCTION__, status, i
  125379. + );
  125380. + }
  125381. + }
  125382. + }
  125383. +
  125384. + /* Next interrupt. */
  125385. + triggered >>= 1;
  125386. +
  125387. + /* No more interrupts to handle? */
  125388. + if (triggered == 0)
  125389. + {
  125390. + break;
  125391. + }
  125392. + }
  125393. +}
  125394. +
  125395. +
  125396. +/*******************************************************************************
  125397. +**
  125398. +** _MainInterruptHandler
  125399. +**
  125400. +** The main interrupt thread serves the interrupt FIFO and calls registered
  125401. +** handlers for the interrupts that occured. The handlers are called in the
  125402. +** sequence interrupts occured with the exception when multiple interrupts
  125403. +** occured at the same time. In that case the handler calls are "sorted" by
  125404. +** the interrupt number therefore giving the interrupts with lower numbers
  125405. +** higher priority.
  125406. +**
  125407. +** INPUT:
  125408. +**
  125409. +** ThreadParameter
  125410. +** Pointer to the gckVGINTERRUPT object.
  125411. +**
  125412. +** OUTPUT:
  125413. +**
  125414. +** Nothing.
  125415. +*/
  125416. +
  125417. +static gctTHREADFUNCRESULT gctTHREADFUNCTYPE
  125418. +_MainInterruptHandler(
  125419. + gctTHREADFUNCPARAMETER ThreadParameter
  125420. + )
  125421. +{
  125422. + gceSTATUS status;
  125423. + gckVGINTERRUPT interrupt;
  125424. +
  125425. +#if gcmENABLE_INTERRUPT_STATISTICS
  125426. + gctUINT count;
  125427. +#endif
  125428. +
  125429. + /* Cast the object. */
  125430. + interrupt = (gckVGINTERRUPT) ThreadParameter;
  125431. +
  125432. + /* Enter the loop. */
  125433. + while (gcvTRUE)
  125434. + {
  125435. + /* Wait for an interrupt. */
  125436. + status = gckOS_DecrementSemaphore(interrupt->os, interrupt->fifoValid);
  125437. +
  125438. + /* Error? */
  125439. + if (gcmkIS_ERROR(status))
  125440. + {
  125441. + break;
  125442. + }
  125443. +
  125444. + /* System termination request? */
  125445. + if (status == gcvSTATUS_TERMINATE)
  125446. + {
  125447. + break;
  125448. + }
  125449. +
  125450. + /* Driver is shutting down? */
  125451. + if (interrupt->terminate)
  125452. + {
  125453. + break;
  125454. + }
  125455. +
  125456. +#if gcmENABLE_INTERRUPT_STATISTICS
  125457. + /* Reset triggered count. */
  125458. + count = 0;
  125459. +
  125460. + /* Process the interrupt. */
  125461. + _ProcessInterrupt(interrupt, &count);
  125462. +
  125463. + /* Update conters. */
  125464. + if (count > interrupt->maxSimultaneous)
  125465. + {
  125466. + interrupt->maxSimultaneous = count;
  125467. + }
  125468. +
  125469. + if (count > 1)
  125470. + {
  125471. + interrupt->multipleCount += 1;
  125472. + }
  125473. +#else
  125474. + /* Process the interrupt. */
  125475. + _ProcessInterrupt(interrupt);
  125476. +#endif
  125477. + }
  125478. +
  125479. + return 0;
  125480. +}
  125481. +
  125482. +
  125483. +/*******************************************************************************
  125484. +**
  125485. +** _StartInterruptHandler / _StopInterruptHandler
  125486. +**
  125487. +** Main interrupt handler routine control.
  125488. +**
  125489. +** INPUT:
  125490. +**
  125491. +** ThreadParameter
  125492. +** Pointer to the gckVGINTERRUPT object.
  125493. +**
  125494. +** OUTPUT:
  125495. +**
  125496. +** Nothing.
  125497. +*/
  125498. +
  125499. +static gceSTATUS
  125500. +_StartInterruptHandler(
  125501. + gckVGINTERRUPT Interrupt
  125502. + )
  125503. +{
  125504. + gceSTATUS status, last;
  125505. +
  125506. + do
  125507. + {
  125508. + /* Objects must not be already created. */
  125509. + gcmkASSERT(Interrupt->fifoValid == gcvNULL);
  125510. + gcmkASSERT(Interrupt->handler == gcvNULL);
  125511. +
  125512. + /* Reset the termination request. */
  125513. + Interrupt->terminate = gcvFALSE;
  125514. +
  125515. +#if !gcdENABLE_INFINITE_SPEED_HW
  125516. + /* Construct the fifo semaphore. */
  125517. + gcmkERR_BREAK(gckOS_CreateSemaphoreVG(
  125518. + Interrupt->os, &Interrupt->fifoValid
  125519. + ));
  125520. +
  125521. + /* Start the interrupt handler thread. */
  125522. + gcmkERR_BREAK(gckOS_StartThread(
  125523. + Interrupt->os,
  125524. + _MainInterruptHandler,
  125525. + Interrupt,
  125526. + &Interrupt->handler
  125527. + ));
  125528. +#endif
  125529. +
  125530. + /* Success. */
  125531. + return gcvSTATUS_OK;
  125532. + }
  125533. + while (gcvFALSE);
  125534. +
  125535. + /* Roll back. */
  125536. + if (Interrupt->fifoValid != gcvNULL)
  125537. + {
  125538. + gcmkCHECK_STATUS(gckOS_DestroySemaphore(
  125539. + Interrupt->os, Interrupt->fifoValid
  125540. + ));
  125541. +
  125542. + Interrupt->fifoValid = gcvNULL;
  125543. + }
  125544. +
  125545. + /* Return the status. */
  125546. + return status;
  125547. +}
  125548. +
  125549. +static gceSTATUS
  125550. +_StopInterruptHandler(
  125551. + gckVGINTERRUPT Interrupt
  125552. + )
  125553. +{
  125554. + gceSTATUS status;
  125555. +
  125556. + do
  125557. + {
  125558. + /* Does the thread exist? */
  125559. + if (Interrupt->handler == gcvNULL)
  125560. + {
  125561. + /* The semaphore must be NULL as well. */
  125562. + gcmkASSERT(Interrupt->fifoValid == gcvNULL);
  125563. +
  125564. + /* Success. */
  125565. + status = gcvSTATUS_OK;
  125566. + break;
  125567. + }
  125568. +
  125569. + /* The semaphore must exist as well. */
  125570. + gcmkASSERT(Interrupt->fifoValid != gcvNULL);
  125571. +
  125572. + /* Set the termination request. */
  125573. + Interrupt->terminate = gcvTRUE;
  125574. +
  125575. + /* Unlock the thread. */
  125576. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  125577. + Interrupt->os, Interrupt->fifoValid
  125578. + ));
  125579. +
  125580. + /* Wait until the thread quits. */
  125581. + gcmkERR_BREAK(gckOS_StopThread(
  125582. + Interrupt->os,
  125583. + Interrupt->handler
  125584. + ));
  125585. +
  125586. + /* Destroy the semaphore. */
  125587. + gcmkERR_BREAK(gckOS_DestroySemaphore(
  125588. + Interrupt->os, Interrupt->fifoValid
  125589. + ));
  125590. +
  125591. + /* Reset handles. */
  125592. + Interrupt->handler = gcvNULL;
  125593. + Interrupt->fifoValid = gcvNULL;
  125594. + }
  125595. + while (gcvFALSE);
  125596. +
  125597. + /* Return the status. */
  125598. + return status;
  125599. +}
  125600. +
  125601. +
  125602. +/******************************************************************************\
  125603. +***************************** Interrupt Object API *****************************
  125604. +\******************************************************************************/
  125605. +
  125606. +/*******************************************************************************
  125607. +**
  125608. +** gckVGINTERRUPT_Construct
  125609. +**
  125610. +** Construct an interrupt object.
  125611. +**
  125612. +** INPUT:
  125613. +**
  125614. +** Kernel
  125615. +** Pointer to the gckVGKERNEL object.
  125616. +**
  125617. +** OUTPUT:
  125618. +**
  125619. +** Interrupt
  125620. +** Pointer to the new gckVGINTERRUPT object.
  125621. +*/
  125622. +
  125623. +gceSTATUS
  125624. +gckVGINTERRUPT_Construct(
  125625. + IN gckVGKERNEL Kernel,
  125626. + OUT gckVGINTERRUPT * Interrupt
  125627. + )
  125628. +{
  125629. + gceSTATUS status;
  125630. + gckVGINTERRUPT interrupt = gcvNULL;
  125631. +
  125632. + gcmkHEADER_ARG("Kernel=0x%x Interrupt=0x%x", Kernel, Interrupt);
  125633. +
  125634. + /* Verify argeuments. */
  125635. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  125636. + gcmkVERIFY_ARGUMENT(Interrupt != gcvNULL);
  125637. +
  125638. + do
  125639. + {
  125640. + /* Allocate the gckVGINTERRUPT structure. */
  125641. + gcmkERR_BREAK(gckOS_Allocate(
  125642. + Kernel->os,
  125643. + gcmSIZEOF(struct _gckVGINTERRUPT),
  125644. + (gctPOINTER *) &interrupt
  125645. + ));
  125646. +
  125647. + /* Reset the object data. */
  125648. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  125649. + interrupt, gcmSIZEOF(struct _gckVGINTERRUPT)
  125650. + ));
  125651. +
  125652. + /* Initialize the object. */
  125653. + interrupt->object.type = gcvOBJ_INTERRUPT;
  125654. +
  125655. + /* Initialize the object pointers. */
  125656. + interrupt->kernel = Kernel;
  125657. + interrupt->os = Kernel->os;
  125658. +
  125659. + /* Initialize the current FIFO position. */
  125660. + interrupt->head = (gctUINT8)~0;
  125661. + interrupt->tail = (gctUINT8)~0;
  125662. +
  125663. + /* Start the thread. */
  125664. + gcmkERR_BREAK(_StartInterruptHandler(interrupt));
  125665. +
  125666. + /* Return interrupt object. */
  125667. + *Interrupt = interrupt;
  125668. +
  125669. + gcmkFOOTER_ARG("*Interrup=0x%x", *Interrupt);
  125670. + /* Success. */
  125671. + return gcvSTATUS_OK;
  125672. + }
  125673. + while (gcvFALSE);
  125674. +
  125675. + /* Roll back. */
  125676. + if (interrupt != gcvNULL)
  125677. + {
  125678. + /* Free the gckVGINTERRUPT structure. */
  125679. + gcmkVERIFY_OK(gckOS_Free(interrupt->os, interrupt));
  125680. + }
  125681. +
  125682. + gcmkFOOTER();
  125683. +
  125684. + /* Return the status. */
  125685. + return status;
  125686. +}
  125687. +
  125688. +
  125689. +/*******************************************************************************
  125690. +**
  125691. +** gckVGINTERRUPT_Destroy
  125692. +**
  125693. +** Destroy an interrupt object.
  125694. +**
  125695. +** INPUT:
  125696. +**
  125697. +** Interrupt
  125698. +** Pointer to the gckVGINTERRUPT object to destroy.
  125699. +**
  125700. +** OUTPUT:
  125701. +**
  125702. +** Nothing.
  125703. +*/
  125704. +
  125705. +gceSTATUS
  125706. +gckVGINTERRUPT_Destroy(
  125707. + IN gckVGINTERRUPT Interrupt
  125708. + )
  125709. +{
  125710. + gceSTATUS status;
  125711. +
  125712. + gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
  125713. +
  125714. + /* Verify the arguments. */
  125715. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  125716. +
  125717. + do
  125718. + {
  125719. + /* Stop the interrupt thread. */
  125720. + gcmkERR_BREAK(_StopInterruptHandler(Interrupt));
  125721. +
  125722. + /* Mark the object as unknown. */
  125723. + Interrupt->object.type = gcvOBJ_UNKNOWN;
  125724. +
  125725. + /* Free the gckVGINTERRUPT structure. */
  125726. + gcmkERR_BREAK(gckOS_Free(Interrupt->os, Interrupt));
  125727. + }
  125728. + while (gcvFALSE);
  125729. +
  125730. + gcmkFOOTER();
  125731. +
  125732. + /* Return the status. */
  125733. + return status;
  125734. +}
  125735. +
  125736. +
  125737. +/*******************************************************************************
  125738. +**
  125739. +** gckVGINTERRUPT_DumpState
  125740. +**
  125741. +** Print the current state of the interrupt manager.
  125742. +**
  125743. +** INPUT:
  125744. +**
  125745. +** Interrupt
  125746. +** Pointer to a gckVGINTERRUPT object.
  125747. +**
  125748. +** OUTPUT:
  125749. +**
  125750. +** Nothing.
  125751. +*/
  125752. +
  125753. +#if gcvDEBUG
  125754. +gceSTATUS
  125755. +gckVGINTERRUPT_DumpState(
  125756. + IN gckVGINTERRUPT Interrupt
  125757. + )
  125758. +{
  125759. + gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
  125760. + /* Verify the arguments. */
  125761. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  125762. +
  125763. + /* Print the header. */
  125764. + gcmkTRACE_ZONE(
  125765. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125766. + "%s: INTERRUPT OBJECT STATUS\n",
  125767. + __FUNCTION__
  125768. + );
  125769. +
  125770. + /* Print statistics. */
  125771. +#if gcmENABLE_INTERRUPT_STATISTICS
  125772. + gcmkTRACE_ZONE(
  125773. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125774. + " Maximum number of FIFO items accumulated at a single time: %d\n",
  125775. + Interrupt->maxFifoItems
  125776. + );
  125777. +
  125778. + gcmkTRACE_ZONE(
  125779. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125780. + " Interrupt FIFO overflow happened times: %d\n",
  125781. + Interrupt->fifoOverflow
  125782. + );
  125783. +
  125784. + gcmkTRACE_ZONE(
  125785. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125786. + " Maximum number of interrupts simultaneously generated: %d\n",
  125787. + Interrupt->maxSimultaneous
  125788. + );
  125789. +
  125790. + gcmkTRACE_ZONE(
  125791. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125792. + " Number of times when there were multiple interrupts generated: %d\n",
  125793. + Interrupt->multipleCount
  125794. + );
  125795. +#endif
  125796. +
  125797. + gcmkTRACE_ZONE(
  125798. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125799. + " The current number of entries in the FIFO: %d\n",
  125800. + Interrupt->fifoItems
  125801. + );
  125802. +
  125803. + /* Print the FIFO contents. */
  125804. + if (Interrupt->fifoItems != 0)
  125805. + {
  125806. + gctUINT8 index;
  125807. + gctUINT8 last;
  125808. +
  125809. + gcmkTRACE_ZONE(
  125810. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125811. + " FIFO current contents:\n"
  125812. + );
  125813. +
  125814. + /* Get the current pointers. */
  125815. + index = Interrupt->tail;
  125816. + last = Interrupt->head;
  125817. +
  125818. + while (index != last)
  125819. + {
  125820. + /* Advance to the next entry. */
  125821. + index += 1;
  125822. +
  125823. + gcmkTRACE_ZONE(
  125824. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  125825. + " %d: 0x%08X\n",
  125826. + index, Interrupt->fifo[index]
  125827. + );
  125828. + }
  125829. + }
  125830. +
  125831. + gcmkFOOTER_NO();
  125832. + /* Success. */
  125833. + return gcvSTATUS_OK;
  125834. +}
  125835. +#endif
  125836. +
  125837. +
  125838. +/*******************************************************************************
  125839. +**
  125840. +** gckVGINTERRUPT_Enable
  125841. +**
  125842. +** Enable the specified interrupt.
  125843. +**
  125844. +** INPUT:
  125845. +**
  125846. +** Interrupt
  125847. +** Pointer to a gckVGINTERRUPT object.
  125848. +**
  125849. +** Id
  125850. +** Pointer to the variable that holds the interrupt number to be
  125851. +** registered in range 0..31.
  125852. +** If the value is less then 0, gckVGINTERRUPT_Enable will attempt
  125853. +** to find an unused interrupt. If such interrupt is found, the number
  125854. +** will be assigned to the variable if the functuion call succeedes.
  125855. +**
  125856. +** Handler
  125857. +** Pointer to the handler to register for the interrupt.
  125858. +**
  125859. +** OUTPUT:
  125860. +**
  125861. +** Nothing.
  125862. +*/
  125863. +
  125864. +gceSTATUS
  125865. +gckVGINTERRUPT_Enable(
  125866. + IN gckVGINTERRUPT Interrupt,
  125867. + IN OUT gctINT32_PTR Id,
  125868. + IN gctINTERRUPT_HANDLER Handler
  125869. + )
  125870. +{
  125871. + gceSTATUS status;
  125872. + gctINT32 i;
  125873. +
  125874. + gcmkHEADER_ARG("Interrupt=0x%x Id=0x%x Handler=0x%x", Interrupt, Id, Handler);
  125875. +
  125876. + /* Verify the arguments. */
  125877. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  125878. + gcmkVERIFY_ARGUMENT(Id != gcvNULL);
  125879. + gcmkVERIFY_ARGUMENT(Handler != gcvNULL);
  125880. +
  125881. + do
  125882. + {
  125883. + /* See if we need to allocate an ID. */
  125884. + if (*Id < 0)
  125885. + {
  125886. + /* Find the first unused interrupt handler. */
  125887. + for (i = 0; i < gcmCOUNTOF(Interrupt->handlers); ++i)
  125888. + {
  125889. + if (Interrupt->handlers[i] == gcvNULL)
  125890. + {
  125891. + break;
  125892. + }
  125893. + }
  125894. +
  125895. + /* No unused innterrupts? */
  125896. + if (i == gcmCOUNTOF(Interrupt->handlers))
  125897. + {
  125898. + status = gcvSTATUS_OUT_OF_RESOURCES;
  125899. + break;
  125900. + }
  125901. +
  125902. + /* Update the interrupt ID. */
  125903. + *Id = i;
  125904. + }
  125905. +
  125906. + /* Make sure the ID is in range. */
  125907. + else if (*Id >= gcmCOUNTOF(Interrupt->handlers))
  125908. + {
  125909. + status = gcvSTATUS_INVALID_ARGUMENT;
  125910. + break;
  125911. + }
  125912. +
  125913. + /* Set interrupt handler. */
  125914. + Interrupt->handlers[*Id] = Handler;
  125915. +
  125916. + /* Success. */
  125917. + status = gcvSTATUS_OK;
  125918. + }
  125919. + while (gcvFALSE);
  125920. +
  125921. + gcmkFOOTER();
  125922. + /* Return the status. */
  125923. + return status;
  125924. +}
  125925. +
  125926. +
  125927. +/*******************************************************************************
  125928. +**
  125929. +** gckVGINTERRUPT_Disable
  125930. +**
  125931. +** Disable the specified interrupt.
  125932. +**
  125933. +** INPUT:
  125934. +**
  125935. +** Interrupt
  125936. +** Pointer to a gckVGINTERRUPT object.
  125937. +**
  125938. +** Id
  125939. +** Interrupt number to be disabled in range 0..31.
  125940. +**
  125941. +** OUTPUT:
  125942. +**
  125943. +** Nothing.
  125944. +*/
  125945. +
  125946. +gceSTATUS
  125947. +gckVGINTERRUPT_Disable(
  125948. + IN gckVGINTERRUPT Interrupt,
  125949. + IN gctINT32 Id
  125950. + )
  125951. +{
  125952. + gcmkHEADER_ARG("Interrupt=0x%x Id=0x%x", Interrupt, Id);
  125953. + /* Verify the arguments. */
  125954. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  125955. + gcmkVERIFY_ARGUMENT((Id >= 0) && (Id < gcmCOUNTOF(Interrupt->handlers)));
  125956. +
  125957. + /* Reset interrupt handler. */
  125958. + Interrupt->handlers[Id] = gcvNULL;
  125959. +
  125960. + gcmkFOOTER_NO();
  125961. + /* Success. */
  125962. + return gcvSTATUS_OK;
  125963. +}
  125964. +
  125965. +
  125966. +/*******************************************************************************
  125967. +**
  125968. +** gckVGINTERRUPT_Enque
  125969. +**
  125970. +** Read the interrupt status register and put the value in the interrupt FIFO.
  125971. +**
  125972. +** INPUT:
  125973. +**
  125974. +** Interrupt
  125975. +** Pointer to a gckVGINTERRUPT object.
  125976. +**
  125977. +** OUTPUT:
  125978. +**
  125979. +** Nothing.
  125980. +*/
  125981. +
  125982. +#ifndef __QNXNTO__
  125983. +gceSTATUS
  125984. +gckVGINTERRUPT_Enque(
  125985. + IN gckVGINTERRUPT Interrupt
  125986. + )
  125987. +#else
  125988. +gceSTATUS
  125989. +gckVGINTERRUPT_Enque(
  125990. + IN gckVGINTERRUPT Interrupt,
  125991. + OUT gckOS *Os,
  125992. + OUT gctSEMAPHORE *Semaphore
  125993. + )
  125994. +#endif
  125995. +{
  125996. + gceSTATUS status;
  125997. + gctUINT32 triggered;
  125998. +
  125999. + gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
  126000. +
  126001. + /* Verify the arguments. */
  126002. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  126003. +
  126004. +#ifdef __QNXNTO__
  126005. + *Os = gcvNULL;
  126006. + *Semaphore = gcvNULL;
  126007. +#endif
  126008. +
  126009. + do
  126010. + {
  126011. + /* Read interrupt status register. */
  126012. + gcmkERR_BREAK(gckVGHARDWARE_ReadInterrupt(
  126013. + Interrupt->kernel->hardware, &triggered
  126014. + ));
  126015. +
  126016. + /* Mask out TS overflow interrupt */
  126017. + triggered &= 0xfffffffe;
  126018. +
  126019. + /* No interrupts to process? */
  126020. + if (triggered == 0)
  126021. + {
  126022. + status = gcvSTATUS_NOT_OUR_INTERRUPT;
  126023. + break;
  126024. + }
  126025. +
  126026. + /* FIFO overflow? */
  126027. + if (Interrupt->fifoItems == gcmCOUNTOF(Interrupt->fifo))
  126028. + {
  126029. +#if gcmENABLE_INTERRUPT_STATISTICS
  126030. + Interrupt->fifoOverflow += 1;
  126031. +#endif
  126032. +
  126033. + /* OR the interrupt with the last value in the FIFO. */
  126034. + Interrupt->fifo[Interrupt->head] |= triggered;
  126035. +
  126036. + /* Success (kind of). */
  126037. + status = gcvSTATUS_OK;
  126038. + }
  126039. + else
  126040. + {
  126041. + /* Advance to the next entry. */
  126042. + Interrupt->head += 1;
  126043. + Interrupt->fifoItems += 1;
  126044. +
  126045. +#if gcmENABLE_INTERRUPT_STATISTICS
  126046. + if (Interrupt->fifoItems > Interrupt->maxFifoItems)
  126047. + {
  126048. + Interrupt->maxFifoItems = Interrupt->fifoItems;
  126049. + }
  126050. +#endif
  126051. +
  126052. + /* Set the new value. */
  126053. + Interrupt->fifo[Interrupt->head] = triggered;
  126054. +
  126055. +#ifndef __QNXNTO__
  126056. + /* Increment the FIFO semaphore. */
  126057. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  126058. + Interrupt->os, Interrupt->fifoValid
  126059. + ));
  126060. +#else
  126061. + *Os = Interrupt->os;
  126062. + *Semaphore = Interrupt->fifoValid;
  126063. +#endif
  126064. +
  126065. + /* Windows kills our threads prematurely when the application
  126066. + exists. Verify here that the thread is still alive. */
  126067. + status = gckOS_VerifyThread(Interrupt->os, Interrupt->handler);
  126068. +
  126069. + /* Has the thread been prematurely terminated? */
  126070. + if (status != gcvSTATUS_OK)
  126071. + {
  126072. + /* Process all accumulated interrupts. */
  126073. + while (Interrupt->head != Interrupt->tail)
  126074. + {
  126075. +#if gcmENABLE_INTERRUPT_STATISTICS
  126076. + /* Process the interrupt. */
  126077. + _ProcessInterrupt(Interrupt, gcvNULL);
  126078. +#else
  126079. + /* Process the interrupt. */
  126080. + _ProcessInterrupt(Interrupt);
  126081. +#endif
  126082. + }
  126083. +
  126084. + /* Set success. */
  126085. + status = gcvSTATUS_OK;
  126086. + }
  126087. + }
  126088. + }
  126089. + while (gcvFALSE);
  126090. +
  126091. + gcmkFOOTER();
  126092. + /* Return status. */
  126093. + return status;
  126094. +}
  126095. +
  126096. +#endif /* gcdENABLE_VG */
  126097. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
  126098. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c 1969-12-31 18:00:00.000000000 -0600
  126099. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c 2014-12-08 00:31:53.468418001 -0600
  126100. @@ -0,0 +1,1982 @@
  126101. +/****************************************************************************
  126102. +*
  126103. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  126104. +*
  126105. +* This program is free software; you can redistribute it and/or modify
  126106. +* it under the terms of the GNU General Public License as published by
  126107. +* the Free Software Foundation; either version 2 of the license, or
  126108. +* (at your option) any later version.
  126109. +*
  126110. +* This program is distributed in the hope that it will be useful,
  126111. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  126112. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  126113. +* GNU General Public License for more details.
  126114. +*
  126115. +* You should have received a copy of the GNU General Public License
  126116. +* along with this program; if not write to the Free Software
  126117. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  126118. +*
  126119. +*****************************************************************************/
  126120. +
  126121. +
  126122. +#include "gc_hal_kernel_precomp.h"
  126123. +
  126124. +#define _GC_OBJ_ZONE gcvZONE_MMU
  126125. +
  126126. +typedef enum _gceMMU_TYPE
  126127. +{
  126128. + gcvMMU_USED = (0 << 4),
  126129. + gcvMMU_SINGLE = (1 << 4),
  126130. + gcvMMU_FREE = (2 << 4),
  126131. +}
  126132. +gceMMU_TYPE;
  126133. +
  126134. +#define gcmENTRY_TYPE(x) (x & 0xF0)
  126135. +
  126136. +#define gcdMMU_TABLE_DUMP 0
  126137. +
  126138. +#define gcdUSE_MMU_EXCEPTION 0
  126139. +
  126140. +/*
  126141. + gcdMMU_CLEAR_VALUE
  126142. +
  126143. + The clear value for the entry of the old MMU.
  126144. +*/
  126145. +#ifndef gcdMMU_CLEAR_VALUE
  126146. +# define gcdMMU_CLEAR_VALUE 0x00000ABC
  126147. +#endif
  126148. +
  126149. +/* VIV: Start GPU address for gcvSURF_VERTEX. */
  126150. +#define gcdVERTEX_START (128 << 10)
  126151. +
  126152. +typedef struct _gcsMMU_STLB *gcsMMU_STLB_PTR;
  126153. +
  126154. +typedef struct _gcsMMU_STLB
  126155. +{
  126156. + gctPHYS_ADDR physical;
  126157. + gctUINT32_PTR logical;
  126158. + gctSIZE_T size;
  126159. + gctUINT32 physBase;
  126160. + gctSIZE_T pageCount;
  126161. + gctUINT32 mtlbIndex;
  126162. + gctUINT32 mtlbEntryNum;
  126163. + gcsMMU_STLB_PTR next;
  126164. +} gcsMMU_STLB;
  126165. +
  126166. +#if gcdSHARED_PAGETABLE
  126167. +typedef struct _gcsSharedPageTable * gcsSharedPageTable_PTR;
  126168. +typedef struct _gcsSharedPageTable
  126169. +{
  126170. + /* Shared gckMMU object. */
  126171. + gckMMU mmu;
  126172. +
  126173. + /* Hardwares which use this shared pagetable. */
  126174. + gckHARDWARE hardwares[gcdMAX_GPU_COUNT];
  126175. +
  126176. + /* Number of cores use this shared pagetable. */
  126177. + gctUINT32 reference;
  126178. +}
  126179. +gcsSharedPageTable;
  126180. +
  126181. +static gcsSharedPageTable_PTR sharedPageTable = gcvNULL;
  126182. +#endif
  126183. +
  126184. +#if gcdMIRROR_PAGETABLE
  126185. +typedef struct _gcsMirrorPageTable * gcsMirrorPageTable_PTR;
  126186. +typedef struct _gcsMirrorPageTable
  126187. +{
  126188. + /* gckMMU objects. */
  126189. + gckMMU mmus[gcdMAX_GPU_COUNT];
  126190. +
  126191. + /* Hardwares which use this shared pagetable. */
  126192. + gckHARDWARE hardwares[gcdMAX_GPU_COUNT];
  126193. +
  126194. + /* Number of cores use this shared pagetable. */
  126195. + gctUINT32 reference;
  126196. +}
  126197. +gcsMirrorPageTable;
  126198. +
  126199. +static gcsMirrorPageTable_PTR mirrorPageTable = gcvNULL;
  126200. +static gctPOINTER mirrorPageTableMutex = gcvNULL;
  126201. +#endif
  126202. +
  126203. +typedef struct _gcsDynamicSpaceNode * gcsDynamicSpaceNode_PTR;
  126204. +typedef struct _gcsDynamicSpaceNode
  126205. +{
  126206. + gctUINT32 start;
  126207. + gctINT32 entries;
  126208. +}
  126209. +gcsDynamicSpaceNode;
  126210. +
  126211. +static void
  126212. +_WritePageEntry(
  126213. + IN gctUINT32_PTR PageEntry,
  126214. + IN gctUINT32 EntryValue
  126215. + )
  126216. +{
  126217. + static gctUINT16 data = 0xff00;
  126218. +
  126219. + if (*(gctUINT8 *)&data == 0xff)
  126220. + {
  126221. + *PageEntry = gcmSWAB32(EntryValue);
  126222. + }
  126223. + else
  126224. + {
  126225. + *PageEntry = EntryValue;
  126226. + }
  126227. +}
  126228. +
  126229. +static gctUINT32
  126230. +_ReadPageEntry(
  126231. + IN gctUINT32_PTR PageEntry
  126232. + )
  126233. +{
  126234. + static gctUINT16 data = 0xff00;
  126235. + gctUINT32 entryValue;
  126236. +
  126237. + if (*(gctUINT8 *)&data == 0xff)
  126238. + {
  126239. + entryValue = *PageEntry;
  126240. + return gcmSWAB32(entryValue);
  126241. + }
  126242. + else
  126243. + {
  126244. + return *PageEntry;
  126245. + }
  126246. +}
  126247. +
  126248. +static gceSTATUS
  126249. +_FillPageTable(
  126250. + IN gctUINT32_PTR PageTable,
  126251. + IN gctUINT32 PageCount,
  126252. + IN gctUINT32 EntryValue
  126253. +)
  126254. +{
  126255. + gctUINT i;
  126256. +
  126257. + for (i = 0; i < PageCount; i++)
  126258. + {
  126259. + _WritePageEntry(PageTable + i, EntryValue);
  126260. + }
  126261. +
  126262. + return gcvSTATUS_OK;
  126263. +}
  126264. +
  126265. +static gceSTATUS
  126266. +_Link(
  126267. + IN gckMMU Mmu,
  126268. + IN gctUINT32 Index,
  126269. + IN gctUINT32 Next
  126270. + )
  126271. +{
  126272. + if (Index >= Mmu->pageTableEntries)
  126273. + {
  126274. + /* Just move heap pointer. */
  126275. + Mmu->heapList = Next;
  126276. + }
  126277. + else
  126278. + {
  126279. + /* Address page table. */
  126280. + gctUINT32_PTR pageTable = Mmu->pageTableLogical;
  126281. +
  126282. + /* Dispatch on node type. */
  126283. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[Index])))
  126284. + {
  126285. + case gcvMMU_SINGLE:
  126286. + /* Set single index. */
  126287. + _WritePageEntry(&pageTable[Index], (Next << 8) | gcvMMU_SINGLE);
  126288. + break;
  126289. +
  126290. + case gcvMMU_FREE:
  126291. + /* Set index. */
  126292. + _WritePageEntry(&pageTable[Index + 1], Next);
  126293. + break;
  126294. +
  126295. + default:
  126296. + gcmkFATAL("MMU table correcupted at index %u!", Index);
  126297. + return gcvSTATUS_HEAP_CORRUPTED;
  126298. + }
  126299. + }
  126300. +
  126301. + /* Success. */
  126302. + return gcvSTATUS_OK;
  126303. +}
  126304. +
  126305. +static gceSTATUS
  126306. +_AddFree(
  126307. + IN gckMMU Mmu,
  126308. + IN gctUINT32 Index,
  126309. + IN gctUINT32 Node,
  126310. + IN gctUINT32 Count
  126311. + )
  126312. +{
  126313. + gctUINT32_PTR pageTable = Mmu->pageTableLogical;
  126314. +
  126315. + if (Count == 1)
  126316. + {
  126317. + /* Initialize a single page node. */
  126318. + _WritePageEntry(pageTable + Node, (~((1U<<8)-1)) | gcvMMU_SINGLE);
  126319. + }
  126320. + else
  126321. + {
  126322. + /* Initialize the node. */
  126323. + _WritePageEntry(pageTable + Node + 0, (Count << 8) | gcvMMU_FREE);
  126324. + _WritePageEntry(pageTable + Node + 1, ~0U);
  126325. + }
  126326. +
  126327. + /* Append the node. */
  126328. + return _Link(Mmu, Index, Node);
  126329. +}
  126330. +
  126331. +static gceSTATUS
  126332. +_Collect(
  126333. + IN gckMMU Mmu
  126334. + )
  126335. +{
  126336. + gctUINT32_PTR pageTable = Mmu->pageTableLogical;
  126337. + gceSTATUS status;
  126338. + gctUINT32 i, previous, start = 0, count = 0;
  126339. +
  126340. + previous = Mmu->heapList = ~0U;
  126341. + Mmu->freeNodes = gcvFALSE;
  126342. +
  126343. + /* Walk the entire page table. */
  126344. + for (i = 0; i < Mmu->pageTableEntries; ++i)
  126345. + {
  126346. + /* Dispatch based on type of page. */
  126347. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[i])))
  126348. + {
  126349. + case gcvMMU_USED:
  126350. + /* Used page, so close any open node. */
  126351. + if (count > 0)
  126352. + {
  126353. + /* Add the node. */
  126354. + gcmkONERROR(_AddFree(Mmu, previous, start, count));
  126355. +
  126356. + /* Reset the node. */
  126357. + previous = start;
  126358. + count = 0;
  126359. + }
  126360. + break;
  126361. +
  126362. + case gcvMMU_SINGLE:
  126363. + /* Single free node. */
  126364. + if (count++ == 0)
  126365. + {
  126366. + /* Start a new node. */
  126367. + start = i;
  126368. + }
  126369. + break;
  126370. +
  126371. + case gcvMMU_FREE:
  126372. + /* A free node. */
  126373. + if (count == 0)
  126374. + {
  126375. + /* Start a new node. */
  126376. + start = i;
  126377. + }
  126378. +
  126379. + /* Advance the count. */
  126380. + count += _ReadPageEntry(&pageTable[i]) >> 8;
  126381. +
  126382. + /* Advance the index into the page table. */
  126383. + i += (_ReadPageEntry(&pageTable[i]) >> 8) - 1;
  126384. + break;
  126385. +
  126386. + default:
  126387. + gcmkFATAL("MMU page table correcupted at index %u!", i);
  126388. + return gcvSTATUS_HEAP_CORRUPTED;
  126389. + }
  126390. + }
  126391. +
  126392. + /* See if we have an open node left. */
  126393. + if (count > 0)
  126394. + {
  126395. + /* Add the node to the list. */
  126396. + gcmkONERROR(_AddFree(Mmu, previous, start, count));
  126397. + }
  126398. +
  126399. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_MMU,
  126400. + "Performed a garbage collection of the MMU heap.");
  126401. +
  126402. + /* Success. */
  126403. + return gcvSTATUS_OK;
  126404. +
  126405. +OnError:
  126406. + /* Return the staus. */
  126407. + return status;
  126408. +}
  126409. +
  126410. +static gctUINT32
  126411. +_SetPage(gctUINT32 PageAddress)
  126412. +{
  126413. + return PageAddress
  126414. + /* writable */
  126415. + | (1 << 2)
  126416. + /* Ignore exception */
  126417. + | (0 << 1)
  126418. + /* Present */
  126419. + | (1 << 0);
  126420. +}
  126421. +
  126422. +static gceSTATUS
  126423. +_FillFlatMapping(
  126424. + IN gckMMU Mmu,
  126425. + IN gctUINT32 PhysBase,
  126426. + OUT gctSIZE_T Size
  126427. + )
  126428. +{
  126429. + gceSTATUS status;
  126430. + gctBOOL mutex = gcvFALSE;
  126431. + gcsMMU_STLB_PTR head = gcvNULL, pre = gcvNULL;
  126432. + gctUINT32 start = PhysBase & (~gcdMMU_PAGE_64K_MASK);
  126433. + gctUINT32 end = (PhysBase + Size - 1) & (~gcdMMU_PAGE_64K_MASK);
  126434. + gctUINT32 mStart = start >> gcdMMU_MTLB_SHIFT;
  126435. + gctUINT32 mEnd = end >> gcdMMU_MTLB_SHIFT;
  126436. + gctUINT32 sStart = (start & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
  126437. + gctUINT32 sEnd = (end & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
  126438. +
  126439. + /* Grab the mutex. */
  126440. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  126441. + mutex = gcvTRUE;
  126442. +
  126443. + while (mStart <= mEnd)
  126444. + {
  126445. + gcmkASSERT(mStart < gcdMMU_MTLB_ENTRY_NUM);
  126446. + if (*(Mmu->mtlbLogical + mStart) == 0)
  126447. + {
  126448. + gcsMMU_STLB_PTR stlb;
  126449. + gctPOINTER pointer = gcvNULL;
  126450. + gctUINT32 last = (mStart == mEnd) ? sEnd : (gcdMMU_STLB_64K_ENTRY_NUM - 1);
  126451. +
  126452. + gcmkONERROR(gckOS_Allocate(Mmu->os, sizeof(struct _gcsMMU_STLB), &pointer));
  126453. + stlb = pointer;
  126454. +
  126455. + stlb->mtlbEntryNum = 0;
  126456. + stlb->next = gcvNULL;
  126457. + stlb->physical = gcvNULL;
  126458. + stlb->logical = gcvNULL;
  126459. + stlb->size = gcdMMU_STLB_64K_SIZE;
  126460. + stlb->pageCount = 0;
  126461. +
  126462. + if (pre == gcvNULL)
  126463. + {
  126464. + pre = head = stlb;
  126465. + }
  126466. + else
  126467. + {
  126468. + gcmkASSERT(pre->next == gcvNULL);
  126469. + pre->next = stlb;
  126470. + pre = stlb;
  126471. + }
  126472. +
  126473. + gcmkONERROR(
  126474. + gckOS_AllocateContiguous(Mmu->os,
  126475. + gcvFALSE,
  126476. + &stlb->size,
  126477. + &stlb->physical,
  126478. + (gctPOINTER)&stlb->logical));
  126479. +
  126480. + gcmkONERROR(gckOS_ZeroMemory(stlb->logical, stlb->size));
  126481. +
  126482. + gcmkONERROR(gckOS_GetPhysicalAddress(
  126483. + Mmu->os,
  126484. + stlb->logical,
  126485. + &stlb->physBase));
  126486. +
  126487. + if (stlb->physBase & (gcdMMU_STLB_64K_SIZE - 1))
  126488. + {
  126489. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  126490. + }
  126491. +
  126492. + _WritePageEntry(Mmu->mtlbLogical + mStart,
  126493. + stlb->physBase
  126494. + /* 64KB page size */
  126495. + | (1 << 2)
  126496. + /* Ignore exception */
  126497. + | (0 << 1)
  126498. + /* Present */
  126499. + | (1 << 0)
  126500. + );
  126501. +#if gcdMMU_TABLE_DUMP
  126502. + gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
  126503. + __FUNCTION__, __LINE__,
  126504. + mStart,
  126505. + _ReadPageEntry(Mmu->mtlbLogical + mStart));
  126506. +#endif
  126507. +
  126508. + stlb->mtlbIndex = mStart;
  126509. + stlb->mtlbEntryNum = 1;
  126510. +#if gcdMMU_TABLE_DUMP
  126511. + gckOS_Print("%s(%d): STLB: logical:%08x -> physical:%08x\n",
  126512. + __FUNCTION__, __LINE__,
  126513. + stlb->logical,
  126514. + stlb->physBase);
  126515. +#endif
  126516. +
  126517. + while (sStart <= last)
  126518. + {
  126519. + gcmkASSERT(!(start & gcdMMU_PAGE_64K_MASK));
  126520. + _WritePageEntry(stlb->logical + sStart, _SetPage(start));
  126521. +#if gcdMMU_TABLE_DUMP
  126522. + gckOS_Print("%s(%d): insert STLB[%d]: %08x\n",
  126523. + __FUNCTION__, __LINE__,
  126524. + sStart,
  126525. + _ReadPageEntry(stlb->logical + sStart));
  126526. +#endif
  126527. + /* next page. */
  126528. + start += gcdMMU_PAGE_64K_SIZE;
  126529. + sStart++;
  126530. + stlb->pageCount++;
  126531. + }
  126532. +
  126533. + sStart = 0;
  126534. + ++mStart;
  126535. + }
  126536. + else
  126537. + {
  126538. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  126539. + }
  126540. + }
  126541. +
  126542. + /* Insert the stlb into staticSTLB. */
  126543. + if (Mmu->staticSTLB == gcvNULL)
  126544. + {
  126545. + Mmu->staticSTLB = head;
  126546. + }
  126547. + else
  126548. + {
  126549. + gcmkASSERT(pre == gcvNULL);
  126550. + gcmkASSERT(pre->next == gcvNULL);
  126551. + pre->next = Mmu->staticSTLB;
  126552. + Mmu->staticSTLB = head;
  126553. + }
  126554. +
  126555. + /* Release the mutex. */
  126556. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  126557. +
  126558. + return gcvSTATUS_OK;
  126559. +
  126560. +OnError:
  126561. +
  126562. + /* Roll back. */
  126563. + while (head != gcvNULL)
  126564. + {
  126565. + pre = head;
  126566. + head = head->next;
  126567. +
  126568. + if (pre->physical != gcvNULL)
  126569. + {
  126570. + gcmkVERIFY_OK(
  126571. + gckOS_FreeContiguous(Mmu->os,
  126572. + pre->physical,
  126573. + pre->logical,
  126574. + pre->size));
  126575. + }
  126576. +
  126577. + if (pre->mtlbEntryNum != 0)
  126578. + {
  126579. + gcmkASSERT(pre->mtlbEntryNum == 1);
  126580. + _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex, 0);
  126581. + }
  126582. +
  126583. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
  126584. + }
  126585. +
  126586. + if (mutex)
  126587. + {
  126588. + /* Release the mutex. */
  126589. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  126590. + }
  126591. +
  126592. + return status;
  126593. +}
  126594. +
  126595. +static gceSTATUS
  126596. +_FindDynamicSpace(
  126597. + IN gckMMU Mmu,
  126598. + OUT gcsDynamicSpaceNode_PTR *Array,
  126599. + OUT gctINT * Size
  126600. + )
  126601. +{
  126602. + gceSTATUS status = gcvSTATUS_OK;
  126603. + gctPOINTER pointer = gcvNULL;
  126604. + gcsDynamicSpaceNode_PTR array = gcvNULL;
  126605. + gctINT size = 0;
  126606. + gctINT i = 0, nodeStart = -1, nodeEntries = 0;
  126607. +
  126608. + /* Allocate memory for the array. */
  126609. + gcmkONERROR(gckOS_Allocate(Mmu->os,
  126610. + gcmSIZEOF(*array) * (gcdMMU_MTLB_ENTRY_NUM / 2),
  126611. + &pointer));
  126612. +
  126613. + array = (gcsDynamicSpaceNode_PTR)pointer;
  126614. +
  126615. + /* Loop all the entries. */
  126616. + while (i < gcdMMU_MTLB_ENTRY_NUM)
  126617. + {
  126618. + if (!Mmu->mtlbLogical[i])
  126619. + {
  126620. + if (nodeStart < 0)
  126621. + {
  126622. + /* This is the first entry of the dynamic space. */
  126623. + nodeStart = i;
  126624. + nodeEntries = 1;
  126625. + }
  126626. + else
  126627. + {
  126628. + /* Other entries of the dynamic space. */
  126629. + nodeEntries++;
  126630. + }
  126631. + }
  126632. + else if (nodeStart >= 0)
  126633. + {
  126634. + /* Save the previous node. */
  126635. + array[size].start = nodeStart;
  126636. + array[size].entries = nodeEntries;
  126637. + size++;
  126638. +
  126639. + /* Reset the start. */
  126640. + nodeStart = -1;
  126641. + nodeEntries = 0;
  126642. + }
  126643. +
  126644. + i++;
  126645. + }
  126646. +
  126647. + /* Save the previous node. */
  126648. + if (nodeStart >= 0)
  126649. + {
  126650. + array[size].start = nodeStart;
  126651. + array[size].entries = nodeEntries;
  126652. + size++;
  126653. + }
  126654. +
  126655. +#if gcdMMU_TABLE_DUMP
  126656. + for (i = 0; i < size; i++)
  126657. + {
  126658. + gckOS_Print("%s(%d): [%d]: start=%d, entries=%d.\n",
  126659. + __FUNCTION__, __LINE__,
  126660. + i,
  126661. + array[i].start,
  126662. + array[i].entries);
  126663. + }
  126664. +#endif
  126665. +
  126666. + *Array = array;
  126667. + *Size = size;
  126668. +
  126669. + return gcvSTATUS_OK;
  126670. +
  126671. +OnError:
  126672. + if (pointer != gcvNULL)
  126673. + {
  126674. + gckOS_Free(Mmu->os, pointer);
  126675. + }
  126676. +
  126677. + return status;
  126678. +}
  126679. +
  126680. +static gceSTATUS
  126681. +_SetupDynamicSpace(
  126682. + IN gckMMU Mmu
  126683. + )
  126684. +{
  126685. + gceSTATUS status;
  126686. + gcsDynamicSpaceNode_PTR nodeArray = gcvNULL;
  126687. + gctINT i, nodeArraySize = 0;
  126688. + gctUINT32 physical;
  126689. + gctINT numEntries = 0;
  126690. + gctUINT32_PTR pageTable;
  126691. + gctBOOL acquired = gcvFALSE;
  126692. +
  126693. + /* Find all the dynamic address space. */
  126694. + gcmkONERROR(_FindDynamicSpace(Mmu, &nodeArray, &nodeArraySize));
  126695. +
  126696. + /* TODO: We only use the largest one for now. */
  126697. + for (i = 0; i < nodeArraySize; i++)
  126698. + {
  126699. + if (nodeArray[i].entries > numEntries)
  126700. + {
  126701. + Mmu->dynamicMappingStart = nodeArray[i].start;
  126702. + numEntries = nodeArray[i].entries;
  126703. + }
  126704. + }
  126705. +
  126706. + gckOS_Free(Mmu->os, (gctPOINTER)nodeArray);
  126707. +
  126708. + Mmu->pageTableSize = numEntries * 4096;
  126709. +
  126710. + Mmu->pageTableEntries = Mmu->pageTableSize / gcmSIZEOF(gctUINT32);
  126711. +
  126712. + /* Construct Slave TLB. */
  126713. + gcmkONERROR(gckOS_AllocateContiguous(Mmu->os,
  126714. + gcvFALSE,
  126715. + &Mmu->pageTableSize,
  126716. + &Mmu->pageTablePhysical,
  126717. + (gctPOINTER)&Mmu->pageTableLogical));
  126718. +
  126719. +#if gcdUSE_MMU_EXCEPTION
  126720. + gcmkONERROR(_FillPageTable(Mmu->pageTableLogical,
  126721. + Mmu->pageTableEntries,
  126722. + /* Enable exception */
  126723. + 1 << 1));
  126724. +#else
  126725. + /* Invalidate all entries. */
  126726. + gcmkONERROR(gckOS_ZeroMemory(Mmu->pageTableLogical,
  126727. + Mmu->pageTableSize));
  126728. +#endif
  126729. +
  126730. + /* Initilization. */
  126731. + pageTable = Mmu->pageTableLogical;
  126732. + _WritePageEntry(pageTable, (Mmu->pageTableEntries << 8) | gcvMMU_FREE);
  126733. + _WritePageEntry(pageTable + 1, ~0U);
  126734. + Mmu->heapList = 0;
  126735. + Mmu->freeNodes = gcvFALSE;
  126736. +
  126737. + gcmkONERROR(gckOS_GetPhysicalAddress(Mmu->os,
  126738. + Mmu->pageTableLogical,
  126739. + &physical));
  126740. +
  126741. + /* Grab the mutex. */
  126742. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  126743. + acquired = gcvTRUE;
  126744. +
  126745. + /* Map to Master TLB. */
  126746. + for (i = (gctINT)Mmu->dynamicMappingStart;
  126747. + i < (gctINT)Mmu->dynamicMappingStart + numEntries;
  126748. + i++)
  126749. + {
  126750. + _WritePageEntry(Mmu->mtlbLogical + i,
  126751. + physical
  126752. + /* 4KB page size */
  126753. + | (0 << 2)
  126754. + /* Ignore exception */
  126755. + | (0 << 1)
  126756. + /* Present */
  126757. + | (1 << 0)
  126758. + );
  126759. +#if gcdMMU_TABLE_DUMP
  126760. + gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
  126761. + __FUNCTION__, __LINE__,
  126762. + i,
  126763. + _ReadPageEntry(Mmu->mtlbLogical + i));
  126764. +#endif
  126765. + physical += gcdMMU_STLB_4K_SIZE;
  126766. + }
  126767. +
  126768. + /* Release the mutex. */
  126769. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  126770. +
  126771. + return gcvSTATUS_OK;
  126772. +
  126773. +OnError:
  126774. + if (Mmu->pageTableLogical)
  126775. + {
  126776. + /* Free the page table. */
  126777. + gcmkVERIFY_OK(
  126778. + gckOS_FreeContiguous(Mmu->os,
  126779. + Mmu->pageTablePhysical,
  126780. + (gctPOINTER) Mmu->pageTableLogical,
  126781. + Mmu->pageTableSize));
  126782. + }
  126783. +
  126784. + if (acquired)
  126785. + {
  126786. + /* Release the mutex. */
  126787. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  126788. + }
  126789. +
  126790. + return status;
  126791. +}
  126792. +
  126793. +/*******************************************************************************
  126794. +**
  126795. +** _Construct
  126796. +**
  126797. +** Construct a new gckMMU object.
  126798. +**
  126799. +** INPUT:
  126800. +**
  126801. +** gckKERNEL Kernel
  126802. +** Pointer to an gckKERNEL object.
  126803. +**
  126804. +** gctSIZE_T MmuSize
  126805. +** Number of bytes for the page table.
  126806. +**
  126807. +** OUTPUT:
  126808. +**
  126809. +** gckMMU * Mmu
  126810. +** Pointer to a variable that receives the gckMMU object pointer.
  126811. +*/
  126812. +gceSTATUS
  126813. +_Construct(
  126814. + IN gckKERNEL Kernel,
  126815. + IN gctSIZE_T MmuSize,
  126816. + OUT gckMMU * Mmu
  126817. + )
  126818. +{
  126819. + gckOS os;
  126820. + gckHARDWARE hardware;
  126821. + gceSTATUS status;
  126822. + gckMMU mmu = gcvNULL;
  126823. + gctUINT32_PTR pageTable;
  126824. + gctPOINTER pointer = gcvNULL;
  126825. +
  126826. + gcmkHEADER_ARG("Kernel=0x%x MmuSize=%lu", Kernel, MmuSize);
  126827. +
  126828. + /* Verify the arguments. */
  126829. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  126830. + gcmkVERIFY_ARGUMENT(MmuSize > 0);
  126831. + gcmkVERIFY_ARGUMENT(Mmu != gcvNULL);
  126832. +
  126833. + /* Extract the gckOS object pointer. */
  126834. + os = Kernel->os;
  126835. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  126836. +
  126837. + /* Extract the gckHARDWARE object pointer. */
  126838. + hardware = Kernel->hardware;
  126839. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  126840. +
  126841. + /* Allocate memory for the gckMMU object. */
  126842. + gcmkONERROR(gckOS_Allocate(os, sizeof(struct _gckMMU), &pointer));
  126843. +
  126844. + mmu = pointer;
  126845. +
  126846. + /* Initialize the gckMMU object. */
  126847. + mmu->object.type = gcvOBJ_MMU;
  126848. + mmu->os = os;
  126849. + mmu->hardware = hardware;
  126850. + mmu->pageTableMutex = gcvNULL;
  126851. + mmu->pageTableLogical = gcvNULL;
  126852. + mmu->mtlbLogical = gcvNULL;
  126853. + mmu->staticSTLB = gcvNULL;
  126854. + mmu->enabled = gcvFALSE;
  126855. +#ifdef __QNXNTO__
  126856. + mmu->nodeList = gcvNULL;
  126857. + mmu->nodeMutex = gcvNULL;
  126858. +#endif
  126859. +
  126860. + /* Create the page table mutex. */
  126861. + gcmkONERROR(gckOS_CreateMutex(os, &mmu->pageTableMutex));
  126862. +
  126863. +#ifdef __QNXNTO__
  126864. + /* Create the node list mutex. */
  126865. + gcmkONERROR(gckOS_CreateMutex(os, &mmu->nodeMutex));
  126866. +#endif
  126867. +
  126868. + if (hardware->mmuVersion == 0)
  126869. + {
  126870. + mmu->pageTableSize = MmuSize;
  126871. +
  126872. + gcmkONERROR(
  126873. + gckOS_AllocateContiguous(os,
  126874. + gcvFALSE,
  126875. + &mmu->pageTableSize,
  126876. + &mmu->pageTablePhysical,
  126877. + &pointer));
  126878. +
  126879. + mmu->pageTableLogical = pointer;
  126880. +
  126881. + /* Compute number of entries in page table. */
  126882. + mmu->pageTableEntries = mmu->pageTableSize / sizeof(gctUINT32);
  126883. +
  126884. + /* Mark all pages as free. */
  126885. + pageTable = mmu->pageTableLogical;
  126886. +
  126887. +#if gcdMMU_CLEAR_VALUE
  126888. + _FillPageTable(pageTable, mmu->pageTableEntries, gcdMMU_CLEAR_VALUE);
  126889. +#endif
  126890. +
  126891. + _WritePageEntry(pageTable, (mmu->pageTableEntries << 8) | gcvMMU_FREE);
  126892. + _WritePageEntry(pageTable + 1, ~0U);
  126893. + mmu->heapList = 0;
  126894. + mmu->freeNodes = gcvFALSE;
  126895. +
  126896. + /* Set page table address. */
  126897. + gcmkONERROR(
  126898. + gckHARDWARE_SetMMU(hardware, (gctPOINTER) mmu->pageTableLogical));
  126899. + }
  126900. + else
  126901. + {
  126902. + /* Allocate the 4K mode MTLB table. */
  126903. + mmu->mtlbSize = gcdMMU_MTLB_SIZE + 64;
  126904. +
  126905. + gcmkONERROR(
  126906. + gckOS_AllocateContiguous(os,
  126907. + gcvFALSE,
  126908. + &mmu->mtlbSize,
  126909. + &mmu->mtlbPhysical,
  126910. + &pointer));
  126911. +
  126912. + mmu->mtlbLogical = pointer;
  126913. +
  126914. + /* Invalid all the entries. */
  126915. + gcmkONERROR(
  126916. + gckOS_ZeroMemory(pointer, mmu->mtlbSize));
  126917. + }
  126918. +
  126919. + /* Return the gckMMU object pointer. */
  126920. + *Mmu = mmu;
  126921. +
  126922. + /* Success. */
  126923. + gcmkFOOTER_ARG("*Mmu=0x%x", *Mmu);
  126924. + return gcvSTATUS_OK;
  126925. +
  126926. +OnError:
  126927. + /* Roll back. */
  126928. + if (mmu != gcvNULL)
  126929. + {
  126930. + if (mmu->pageTableLogical != gcvNULL)
  126931. + {
  126932. + /* Free the page table. */
  126933. + gcmkVERIFY_OK(
  126934. + gckOS_FreeContiguous(os,
  126935. + mmu->pageTablePhysical,
  126936. + (gctPOINTER) mmu->pageTableLogical,
  126937. + mmu->pageTableSize));
  126938. +
  126939. + }
  126940. +
  126941. + if (mmu->mtlbLogical != gcvNULL)
  126942. + {
  126943. + gcmkVERIFY_OK(
  126944. + gckOS_FreeContiguous(os,
  126945. + mmu->mtlbPhysical,
  126946. + (gctPOINTER) mmu->mtlbLogical,
  126947. + mmu->mtlbSize));
  126948. + }
  126949. +
  126950. + if (mmu->pageTableMutex != gcvNULL)
  126951. + {
  126952. + /* Delete the mutex. */
  126953. + gcmkVERIFY_OK(
  126954. + gckOS_DeleteMutex(os, mmu->pageTableMutex));
  126955. + }
  126956. +
  126957. +#ifdef __QNXNTO__
  126958. + if (mmu->nodeMutex != gcvNULL)
  126959. + {
  126960. + /* Delete the mutex. */
  126961. + gcmkVERIFY_OK(
  126962. + gckOS_DeleteMutex(os, mmu->nodeMutex));
  126963. + }
  126964. +#endif
  126965. +
  126966. + /* Mark the gckMMU object as unknown. */
  126967. + mmu->object.type = gcvOBJ_UNKNOWN;
  126968. +
  126969. + /* Free the allocates memory. */
  126970. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, mmu));
  126971. + }
  126972. +
  126973. + /* Return the status. */
  126974. + gcmkFOOTER();
  126975. + return status;
  126976. +}
  126977. +
  126978. +/*******************************************************************************
  126979. +**
  126980. +** _Destroy
  126981. +**
  126982. +** Destroy a gckMMU object.
  126983. +**
  126984. +** INPUT:
  126985. +**
  126986. +** gckMMU Mmu
  126987. +** Pointer to an gckMMU object.
  126988. +**
  126989. +** OUTPUT:
  126990. +**
  126991. +** Nothing.
  126992. +*/
  126993. +gceSTATUS
  126994. +_Destroy(
  126995. + IN gckMMU Mmu
  126996. + )
  126997. +{
  126998. +#ifdef __QNXNTO__
  126999. + gcuVIDMEM_NODE_PTR node, next;
  127000. +#endif
  127001. +
  127002. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  127003. +
  127004. + /* Verify the arguments. */
  127005. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127006. +
  127007. +#ifdef __QNXNTO__
  127008. + /* Free all associated virtual memory. */
  127009. + for (node = Mmu->nodeList; node != gcvNULL; node = next)
  127010. + {
  127011. + next = node->Virtual.next;
  127012. + gcmkVERIFY_OK(gckVIDMEM_Free(node));
  127013. + }
  127014. +#endif
  127015. +
  127016. + while (Mmu->staticSTLB != gcvNULL)
  127017. + {
  127018. + gcsMMU_STLB_PTR pre = Mmu->staticSTLB;
  127019. + Mmu->staticSTLB = pre->next;
  127020. +
  127021. + if (pre->physical != gcvNULL)
  127022. + {
  127023. + gcmkVERIFY_OK(
  127024. + gckOS_FreeContiguous(Mmu->os,
  127025. + pre->physical,
  127026. + pre->logical,
  127027. + pre->size));
  127028. + }
  127029. +
  127030. + if (pre->mtlbEntryNum != 0)
  127031. + {
  127032. + gcmkASSERT(pre->mtlbEntryNum == 1);
  127033. + _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex, 0);
  127034. +#if gcdMMU_TABLE_DUMP
  127035. + gckOS_Print("%s(%d): clean MTLB[%d]\n",
  127036. + __FUNCTION__, __LINE__,
  127037. + pre->mtlbIndex);
  127038. +#endif
  127039. + }
  127040. +
  127041. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
  127042. + }
  127043. +
  127044. + if (Mmu->hardware->mmuVersion != 0)
  127045. + {
  127046. + gcmkVERIFY_OK(
  127047. + gckOS_FreeContiguous(Mmu->os,
  127048. + Mmu->mtlbPhysical,
  127049. + (gctPOINTER) Mmu->mtlbLogical,
  127050. + Mmu->mtlbSize));
  127051. + }
  127052. +
  127053. + /* Free the page table. */
  127054. + gcmkVERIFY_OK(
  127055. + gckOS_FreeContiguous(Mmu->os,
  127056. + Mmu->pageTablePhysical,
  127057. + (gctPOINTER) Mmu->pageTableLogical,
  127058. + Mmu->pageTableSize));
  127059. +
  127060. +#ifdef __QNXNTO__
  127061. + /* Delete the node list mutex. */
  127062. + gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->nodeMutex));
  127063. +#endif
  127064. +
  127065. + /* Delete the page table mutex. */
  127066. + gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->pageTableMutex));
  127067. +
  127068. + /* Mark the gckMMU object as unknown. */
  127069. + Mmu->object.type = gcvOBJ_UNKNOWN;
  127070. +
  127071. + /* Free the gckMMU object. */
  127072. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, Mmu));
  127073. +
  127074. + /* Success. */
  127075. + gcmkFOOTER_NO();
  127076. + return gcvSTATUS_OK;
  127077. +}
  127078. +
  127079. +/*******************************************************************************
  127080. +** _AdjstIndex
  127081. +**
  127082. +** Adjust the index from which we search for a usable node to make sure
  127083. +** index allocated is greater than Start.
  127084. +*/
  127085. +gceSTATUS
  127086. +_AdjustIndex(
  127087. + IN gckMMU Mmu,
  127088. + IN gctUINT32 Index,
  127089. + IN gctUINT32 PageCount,
  127090. + IN gctUINT32 Start,
  127091. + OUT gctUINT32 * IndexAdjusted
  127092. + )
  127093. +{
  127094. + gceSTATUS status;
  127095. + gctUINT32 index = Index;
  127096. + gctUINT32_PTR map = Mmu->pageTableLogical;
  127097. +
  127098. + gcmkHEADER();
  127099. +
  127100. + for (; index < Mmu->pageTableEntries;)
  127101. + {
  127102. + gctUINT32 result = 0;
  127103. + gctUINT32 nodeSize = 0;
  127104. +
  127105. + if (index >= Start)
  127106. + {
  127107. + break;
  127108. + }
  127109. +
  127110. + switch (gcmENTRY_TYPE(map[index]))
  127111. + {
  127112. + case gcvMMU_SINGLE:
  127113. + nodeSize = 1;
  127114. + break;
  127115. +
  127116. + case gcvMMU_FREE:
  127117. + nodeSize = map[index] >> 8;
  127118. + break;
  127119. +
  127120. + default:
  127121. + gcmkFATAL("MMU table correcupted at index %u!", index);
  127122. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  127123. + }
  127124. +
  127125. + if (nodeSize > PageCount)
  127126. + {
  127127. + result = index + (nodeSize - PageCount);
  127128. +
  127129. + if (result >= Start)
  127130. + {
  127131. + break;
  127132. + }
  127133. + }
  127134. +
  127135. + switch (gcmENTRY_TYPE(map[index]))
  127136. + {
  127137. + case gcvMMU_SINGLE:
  127138. + index = map[index] >> 8;
  127139. + break;
  127140. +
  127141. + case gcvMMU_FREE:
  127142. + index = map[index + 1];
  127143. + break;
  127144. +
  127145. + default:
  127146. + gcmkFATAL("MMU table correcupted at index %u!", index);
  127147. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  127148. + }
  127149. + }
  127150. +
  127151. + *IndexAdjusted = index;
  127152. +
  127153. + gcmkFOOTER_NO();
  127154. + return gcvSTATUS_OK;
  127155. +
  127156. +OnError:
  127157. + gcmkFOOTER();
  127158. + return status;
  127159. +}
  127160. +
  127161. +gceSTATUS
  127162. +gckMMU_Construct(
  127163. + IN gckKERNEL Kernel,
  127164. + IN gctSIZE_T MmuSize,
  127165. + OUT gckMMU * Mmu
  127166. + )
  127167. +{
  127168. +#if gcdSHARED_PAGETABLE
  127169. + gceSTATUS status;
  127170. + gctPOINTER pointer;
  127171. +
  127172. + gcmkHEADER_ARG("Kernel=0x%08x", Kernel);
  127173. +
  127174. + if (sharedPageTable == gcvNULL)
  127175. + {
  127176. + gcmkONERROR(
  127177. + gckOS_Allocate(Kernel->os,
  127178. + sizeof(struct _gcsSharedPageTable),
  127179. + &pointer));
  127180. + sharedPageTable = pointer;
  127181. +
  127182. + gcmkONERROR(
  127183. + gckOS_ZeroMemory(sharedPageTable,
  127184. + sizeof(struct _gcsSharedPageTable)));
  127185. +
  127186. + gcmkONERROR(_Construct(Kernel, MmuSize, &sharedPageTable->mmu));
  127187. + }
  127188. + else if (Kernel->hardware->mmuVersion == 0)
  127189. + {
  127190. + /* Set page table address. */
  127191. + gcmkONERROR(
  127192. + gckHARDWARE_SetMMU(Kernel->hardware, (gctPOINTER) sharedPageTable->mmu->pageTableLogical));
  127193. + }
  127194. +
  127195. + *Mmu = sharedPageTable->mmu;
  127196. +
  127197. + sharedPageTable->hardwares[sharedPageTable->reference] = Kernel->hardware;
  127198. +
  127199. + sharedPageTable->reference++;
  127200. +
  127201. + gcmkFOOTER_ARG("sharedPageTable->reference=%lu", sharedPageTable->reference);
  127202. + return gcvSTATUS_OK;
  127203. +
  127204. +OnError:
  127205. + if (sharedPageTable)
  127206. + {
  127207. + if (sharedPageTable->mmu)
  127208. + {
  127209. + gcmkVERIFY_OK(gckMMU_Destroy(sharedPageTable->mmu));
  127210. + }
  127211. +
  127212. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, sharedPageTable));
  127213. + }
  127214. +
  127215. + gcmkFOOTER();
  127216. + return status;
  127217. +#elif gcdMIRROR_PAGETABLE
  127218. + gceSTATUS status;
  127219. + gctPOINTER pointer;
  127220. +
  127221. + gcmkHEADER_ARG("Kernel=0x%08x", Kernel);
  127222. +
  127223. + if (mirrorPageTable == gcvNULL)
  127224. + {
  127225. + gcmkONERROR(
  127226. + gckOS_Allocate(Kernel->os,
  127227. + sizeof(struct _gcsMirrorPageTable),
  127228. + &pointer));
  127229. + mirrorPageTable = pointer;
  127230. +
  127231. + gcmkONERROR(
  127232. + gckOS_ZeroMemory(mirrorPageTable,
  127233. + sizeof(struct _gcsMirrorPageTable)));
  127234. +
  127235. + gcmkONERROR(
  127236. + gckOS_CreateMutex(Kernel->os, &mirrorPageTableMutex));
  127237. + }
  127238. +
  127239. + gcmkONERROR(_Construct(Kernel, MmuSize, Mmu));
  127240. +
  127241. + mirrorPageTable->mmus[mirrorPageTable->reference] = *Mmu;
  127242. +
  127243. + mirrorPageTable->hardwares[mirrorPageTable->reference] = Kernel->hardware;
  127244. +
  127245. + mirrorPageTable->reference++;
  127246. +
  127247. + gcmkFOOTER_ARG("mirrorPageTable->reference=%lu", mirrorPageTable->reference);
  127248. + return gcvSTATUS_OK;
  127249. +
  127250. +OnError:
  127251. + if (mirrorPageTable && mirrorPageTable->reference == 0)
  127252. + {
  127253. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, mirrorPageTable));
  127254. + }
  127255. +
  127256. + gcmkFOOTER();
  127257. + return status;
  127258. +#else
  127259. + return _Construct(Kernel, MmuSize, Mmu);
  127260. +#endif
  127261. +}
  127262. +
  127263. +gceSTATUS
  127264. +gckMMU_Destroy(
  127265. + IN gckMMU Mmu
  127266. + )
  127267. +{
  127268. +#if gcdSHARED_PAGETABLE
  127269. + sharedPageTable->reference--;
  127270. +
  127271. + if (sharedPageTable->reference == 0)
  127272. + {
  127273. + if (sharedPageTable->mmu)
  127274. + {
  127275. + gcmkVERIFY_OK(_Destroy(Mmu));
  127276. + }
  127277. +
  127278. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, sharedPageTable));
  127279. + }
  127280. +
  127281. + return gcvSTATUS_OK;
  127282. +#elif gcdMIRROR_PAGETABLE
  127283. + mirrorPageTable->reference--;
  127284. +
  127285. + if (mirrorPageTable->reference == 0)
  127286. + {
  127287. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTable));
  127288. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTableMutex));
  127289. + }
  127290. +
  127291. + return _Destroy(Mmu);
  127292. +#else
  127293. + return _Destroy(Mmu);
  127294. +#endif
  127295. +}
  127296. +
  127297. +/*******************************************************************************
  127298. +**
  127299. +** gckMMU_AllocatePages
  127300. +**
  127301. +** Allocate pages inside the page table.
  127302. +**
  127303. +** INPUT:
  127304. +**
  127305. +** gckMMU Mmu
  127306. +** Pointer to an gckMMU object.
  127307. +**
  127308. +** gctSIZE_T PageCount
  127309. +** Number of pages to allocate.
  127310. +**
  127311. +** OUTPUT:
  127312. +**
  127313. +** gctPOINTER * PageTable
  127314. +** Pointer to a variable that receives the base address of the page
  127315. +** table.
  127316. +**
  127317. +** gctUINT32 * Address
  127318. +** Pointer to a variable that receives the hardware specific address.
  127319. +*/
  127320. +gceSTATUS
  127321. +_AllocatePages(
  127322. + IN gckMMU Mmu,
  127323. + IN gctSIZE_T PageCount,
  127324. + IN gceSURF_TYPE Type,
  127325. + OUT gctPOINTER * PageTable,
  127326. + OUT gctUINT32 * Address
  127327. + )
  127328. +{
  127329. + gceSTATUS status;
  127330. + gctBOOL mutex = gcvFALSE;
  127331. + gctUINT32 index = 0, previous = ~0U, left;
  127332. + gctUINT32_PTR pageTable;
  127333. + gctBOOL gotIt;
  127334. + gctUINT32 address;
  127335. +
  127336. + gcmkHEADER_ARG("Mmu=0x%x PageCount=%lu", Mmu, PageCount);
  127337. +
  127338. + /* Verify the arguments. */
  127339. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127340. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  127341. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  127342. +
  127343. + if (PageCount > Mmu->pageTableEntries)
  127344. + {
  127345. + gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
  127346. + __FUNCTION__, __LINE__);
  127347. +
  127348. + /* Not enough pages avaiable. */
  127349. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  127350. + }
  127351. +
  127352. + /* Grab the mutex. */
  127353. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  127354. + mutex = gcvTRUE;
  127355. +
  127356. + /* Cast pointer to page table. */
  127357. + for (pageTable = Mmu->pageTableLogical, gotIt = gcvFALSE; !gotIt;)
  127358. + {
  127359. + index = Mmu->heapList;
  127360. +
  127361. + if ((Mmu->hardware->mmuVersion == 0) && (Type == gcvSURF_VERTEX))
  127362. + {
  127363. + gcmkONERROR(_AdjustIndex(
  127364. + Mmu,
  127365. + index,
  127366. + PageCount,
  127367. + gcdVERTEX_START / gcmSIZEOF(gctUINT32),
  127368. + &index
  127369. + ));
  127370. + }
  127371. +
  127372. + /* Walk the heap list. */
  127373. + for (; !gotIt && (index < Mmu->pageTableEntries);)
  127374. + {
  127375. + /* Check the node type. */
  127376. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
  127377. + {
  127378. + case gcvMMU_SINGLE:
  127379. + /* Single odes are valid if we only need 1 page. */
  127380. + if (PageCount == 1)
  127381. + {
  127382. + gotIt = gcvTRUE;
  127383. + }
  127384. + else
  127385. + {
  127386. + /* Move to next node. */
  127387. + previous = index;
  127388. + index = _ReadPageEntry(&pageTable[index]) >> 8;
  127389. + }
  127390. + break;
  127391. +
  127392. + case gcvMMU_FREE:
  127393. + /* Test if the node has enough space. */
  127394. + if (PageCount <= (_ReadPageEntry(&pageTable[index]) >> 8))
  127395. + {
  127396. + gotIt = gcvTRUE;
  127397. + }
  127398. + else
  127399. + {
  127400. + /* Move to next node. */
  127401. + previous = index;
  127402. + index = _ReadPageEntry(&pageTable[index + 1]);
  127403. + }
  127404. + break;
  127405. +
  127406. + default:
  127407. + gcmkFATAL("MMU table correcupted at index %u!", index);
  127408. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  127409. + }
  127410. + }
  127411. +
  127412. + /* Test if we are out of memory. */
  127413. + if (index >= Mmu->pageTableEntries)
  127414. + {
  127415. + if (Mmu->freeNodes)
  127416. + {
  127417. + /* Time to move out the trash! */
  127418. + gcmkONERROR(_Collect(Mmu));
  127419. + }
  127420. + else
  127421. + {
  127422. + gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
  127423. + __FUNCTION__, __LINE__);
  127424. +
  127425. + /* Out of resources. */
  127426. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  127427. + }
  127428. + }
  127429. + }
  127430. +
  127431. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
  127432. + {
  127433. + case gcvMMU_SINGLE:
  127434. + /* Unlink single node from free list. */
  127435. + gcmkONERROR(
  127436. + _Link(Mmu, previous, _ReadPageEntry(&pageTable[index]) >> 8));
  127437. + break;
  127438. +
  127439. + case gcvMMU_FREE:
  127440. + /* Check how many pages will be left. */
  127441. + left = (_ReadPageEntry(&pageTable[index]) >> 8) - PageCount;
  127442. + switch (left)
  127443. + {
  127444. + case 0:
  127445. + /* The entire node is consumed, just unlink it. */
  127446. + gcmkONERROR(
  127447. + _Link(Mmu, previous, _ReadPageEntry(&pageTable[index + 1])));
  127448. + break;
  127449. +
  127450. + case 1:
  127451. + /* One page will remain. Convert the node to a single node and
  127452. + ** advance the index. */
  127453. + _WritePageEntry(&pageTable[index], (_ReadPageEntry(&pageTable[index + 1]) << 8) | gcvMMU_SINGLE);
  127454. + index ++;
  127455. + break;
  127456. +
  127457. + default:
  127458. + /* Enough pages remain for a new node. However, we will just adjust
  127459. + ** the size of the current node and advance the index. */
  127460. + _WritePageEntry(&pageTable[index], (left << 8) | gcvMMU_FREE);
  127461. + index += left;
  127462. + break;
  127463. + }
  127464. + break;
  127465. + }
  127466. +
  127467. + /* Mark node as used. */
  127468. + gcmkONERROR(_FillPageTable(&pageTable[index], PageCount, gcvMMU_USED));
  127469. +
  127470. + /* Return pointer to page table. */
  127471. + *PageTable = &pageTable[index];
  127472. +
  127473. + /* Build virtual address. */
  127474. + if (Mmu->hardware->mmuVersion == 0)
  127475. + {
  127476. + gcmkONERROR(
  127477. + gckHARDWARE_BuildVirtualAddress(Mmu->hardware, index, 0, &address));
  127478. + }
  127479. + else
  127480. + {
  127481. + gctUINT32 masterOffset = index / gcdMMU_STLB_4K_ENTRY_NUM
  127482. + + Mmu->dynamicMappingStart;
  127483. + gctUINT32 slaveOffset = index % gcdMMU_STLB_4K_ENTRY_NUM;
  127484. +
  127485. + address = (masterOffset << gcdMMU_MTLB_SHIFT)
  127486. + | (slaveOffset << gcdMMU_STLB_4K_SHIFT);
  127487. + }
  127488. +
  127489. + if (Address != gcvNULL)
  127490. + {
  127491. + *Address = address;
  127492. + }
  127493. +
  127494. + /* Release the mutex. */
  127495. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  127496. +
  127497. + /* Success. */
  127498. + gcmkFOOTER_ARG("*PageTable=0x%x *Address=%08x",
  127499. + *PageTable, gcmOPT_VALUE(Address));
  127500. + return gcvSTATUS_OK;
  127501. +
  127502. +OnError:
  127503. +
  127504. + if (mutex)
  127505. + {
  127506. + /* Release the mutex. */
  127507. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  127508. + }
  127509. +
  127510. + /* Return the status. */
  127511. + gcmkFOOTER();
  127512. + return status;
  127513. +}
  127514. +
  127515. +/*******************************************************************************
  127516. +**
  127517. +** gckMMU_FreePages
  127518. +**
  127519. +** Free pages inside the page table.
  127520. +**
  127521. +** INPUT:
  127522. +**
  127523. +** gckMMU Mmu
  127524. +** Pointer to an gckMMU object.
  127525. +**
  127526. +** gctPOINTER PageTable
  127527. +** Base address of the page table to free.
  127528. +**
  127529. +** gctSIZE_T PageCount
  127530. +** Number of pages to free.
  127531. +**
  127532. +** OUTPUT:
  127533. +**
  127534. +** Nothing.
  127535. +*/
  127536. +gceSTATUS
  127537. +_FreePages(
  127538. + IN gckMMU Mmu,
  127539. + IN gctPOINTER PageTable,
  127540. + IN gctSIZE_T PageCount
  127541. + )
  127542. +{
  127543. + gctUINT32_PTR pageTable;
  127544. + gceSTATUS status;
  127545. + gctBOOL acquired = gcvFALSE;
  127546. +
  127547. + gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=%lu",
  127548. + Mmu, PageTable, PageCount);
  127549. +
  127550. + /* Verify the arguments. */
  127551. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127552. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  127553. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  127554. +
  127555. + /* Convert the pointer. */
  127556. + pageTable = (gctUINT32_PTR) PageTable;
  127557. +
  127558. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  127559. + acquired = gcvTRUE;
  127560. +
  127561. +#if gcdMMU_CLEAR_VALUE
  127562. + if (Mmu->hardware->mmuVersion == 0)
  127563. + {
  127564. + _FillPageTable(pageTable, PageCount, gcdMMU_CLEAR_VALUE);
  127565. + }
  127566. +#endif
  127567. +
  127568. + if (PageCount == 1)
  127569. + {
  127570. + /* Single page node. */
  127571. + _WritePageEntry(pageTable,
  127572. + (~((1U<<8)-1)) | gcvMMU_SINGLE
  127573. +#if gcdUSE_MMU_EXCEPTION
  127574. + /* Enable exception */
  127575. + | 1 << 1
  127576. +#endif
  127577. + );
  127578. + }
  127579. + else
  127580. + {
  127581. + /* Mark the node as free. */
  127582. + _WritePageEntry(pageTable,
  127583. + (PageCount << 8) | gcvMMU_FREE
  127584. +#if gcdUSE_MMU_EXCEPTION
  127585. + /* Enable exception */
  127586. + | 1 << 1
  127587. +#endif
  127588. + );
  127589. + _WritePageEntry(pageTable + 1, ~0U);
  127590. +
  127591. +#if gcdUSE_MMU_EXCEPTION
  127592. + /* Enable exception */
  127593. + gcmkVERIFY_OK(_FillPageTable(pageTable + 2, PageCount - 2, 1 << 1));
  127594. +#endif
  127595. + }
  127596. +
  127597. + /* We have free nodes. */
  127598. + Mmu->freeNodes = gcvTRUE;
  127599. +
  127600. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  127601. + acquired = gcvFALSE;
  127602. +
  127603. + /* Success. */
  127604. + gcmkFOOTER_NO();
  127605. + return gcvSTATUS_OK;
  127606. +
  127607. +OnError:
  127608. + if (acquired)
  127609. + {
  127610. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  127611. + }
  127612. +
  127613. + gcmkFOOTER();
  127614. + return status;
  127615. +}
  127616. +
  127617. +gceSTATUS
  127618. +gckMMU_AllocatePages(
  127619. + IN gckMMU Mmu,
  127620. + IN gctSIZE_T PageCount,
  127621. + OUT gctPOINTER * PageTable,
  127622. + OUT gctUINT32 * Address
  127623. + )
  127624. +{
  127625. + return gckMMU_AllocatePagesEx(
  127626. + Mmu, PageCount, gcvSURF_UNKNOWN, PageTable, Address);
  127627. +}
  127628. +
  127629. +gceSTATUS
  127630. +gckMMU_AllocatePagesEx(
  127631. + IN gckMMU Mmu,
  127632. + IN gctSIZE_T PageCount,
  127633. + IN gceSURF_TYPE Type,
  127634. + OUT gctPOINTER * PageTable,
  127635. + OUT gctUINT32 * Address
  127636. + )
  127637. +{
  127638. +#if gcdMIRROR_PAGETABLE
  127639. + gceSTATUS status;
  127640. + gctPOINTER pageTable;
  127641. + gctUINT32 address;
  127642. + gctINT i;
  127643. + gckMMU mmu;
  127644. + gctBOOL acquired = gcvFALSE;
  127645. + gctBOOL allocated = gcvFALSE;
  127646. +
  127647. + gckOS_AcquireMutex(Mmu->os, mirrorPageTableMutex, gcvINFINITE);
  127648. + acquired = gcvTRUE;
  127649. +
  127650. + /* Allocate page table for current MMU. */
  127651. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  127652. + {
  127653. + if (Mmu == mirrorPageTable->mmus[i])
  127654. + {
  127655. + gcmkONERROR(_AllocatePages(Mmu, PageCount, Type, PageTable, Address));
  127656. + allocated = gcvTRUE;
  127657. + }
  127658. + }
  127659. +
  127660. + /* Allocate page table for other MMUs. */
  127661. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  127662. + {
  127663. + mmu = mirrorPageTable->mmus[i];
  127664. +
  127665. + if (Mmu != mmu)
  127666. + {
  127667. + gcmkONERROR(_AllocatePages(mmu, PageCount, Type, &pageTable, &address));
  127668. + gcmkASSERT(address == *Address);
  127669. + }
  127670. + }
  127671. +
  127672. + gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex);
  127673. + acquired = gcvFALSE;
  127674. +
  127675. + return gcvSTATUS_OK;
  127676. +OnError:
  127677. +
  127678. + if (allocated)
  127679. + {
  127680. + /* Page tables for multiple GPU always keep the same. So it is impossible
  127681. + * the fist one allocates successfully but others fail.
  127682. + */
  127683. + gcmkASSERT(0);
  127684. + }
  127685. +
  127686. + if (acquired)
  127687. + {
  127688. + gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex);
  127689. + }
  127690. +
  127691. + return status;
  127692. +#else
  127693. + return _AllocatePages(Mmu, PageCount, Type, PageTable, Address);
  127694. +#endif
  127695. +}
  127696. +
  127697. +gceSTATUS
  127698. +gckMMU_FreePages(
  127699. + IN gckMMU Mmu,
  127700. + IN gctPOINTER PageTable,
  127701. + IN gctSIZE_T PageCount
  127702. + )
  127703. +{
  127704. +#if gcdMIRROR_PAGETABLE
  127705. + gctINT i;
  127706. + gctUINT32 offset;
  127707. + gckMMU mmu;
  127708. +
  127709. + gckOS_AcquireMutex(Mmu->os, mirrorPageTableMutex, gcvINFINITE);
  127710. +
  127711. + gcmkVERIFY_OK(_FreePages(Mmu, PageTable, PageCount));
  127712. +
  127713. + offset = (gctUINT32)PageTable - (gctUINT32)Mmu->pageTableLogical;
  127714. +
  127715. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  127716. + {
  127717. + mmu = mirrorPageTable->mmus[i];
  127718. +
  127719. + if (mmu != Mmu)
  127720. + {
  127721. + gcmkVERIFY_OK(_FreePages(mmu, mmu->pageTableLogical + offset/4, PageCount));
  127722. + }
  127723. + }
  127724. +
  127725. + gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex);
  127726. +
  127727. + return gcvSTATUS_OK;
  127728. +#else
  127729. + return _FreePages(Mmu, PageTable, PageCount);
  127730. +#endif
  127731. +}
  127732. +
  127733. +gceSTATUS
  127734. +gckMMU_Enable(
  127735. + IN gckMMU Mmu,
  127736. + IN gctUINT32 PhysBaseAddr,
  127737. + IN gctUINT32 PhysSize
  127738. + )
  127739. +{
  127740. + gceSTATUS status;
  127741. +#if gcdSHARED_PAGETABLE
  127742. + gckHARDWARE hardware;
  127743. + gctINT i;
  127744. +#endif
  127745. +
  127746. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  127747. +
  127748. + /* Verify the arguments. */
  127749. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127750. +
  127751. +#if gcdSHARED_PAGETABLE
  127752. + if (Mmu->enabled)
  127753. + {
  127754. + gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP);
  127755. + return gcvSTATUS_SKIP;
  127756. + }
  127757. +#endif
  127758. +
  127759. + if (Mmu->hardware->mmuVersion == 0)
  127760. + {
  127761. + /* Success. */
  127762. + gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP);
  127763. + return gcvSTATUS_SKIP;
  127764. + }
  127765. + else
  127766. + {
  127767. + if (PhysSize != 0)
  127768. + {
  127769. + gcmkONERROR(_FillFlatMapping(
  127770. + Mmu,
  127771. + PhysBaseAddr,
  127772. + PhysSize
  127773. + ));
  127774. + }
  127775. +
  127776. + gcmkONERROR(_SetupDynamicSpace(Mmu));
  127777. +
  127778. +#if gcdSHARED_PAGETABLE
  127779. + for(i = 0; i < gcdMAX_GPU_COUNT; i++)
  127780. + {
  127781. + hardware = sharedPageTable->hardwares[i];
  127782. + if (hardware != gcvNULL)
  127783. + {
  127784. + gcmkONERROR(
  127785. + gckHARDWARE_SetMMUv2(
  127786. + hardware,
  127787. + gcvTRUE,
  127788. + Mmu->mtlbLogical,
  127789. + gcvMMU_MODE_4K,
  127790. + (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
  127791. + gcvFALSE
  127792. + ));
  127793. + }
  127794. + }
  127795. +#else
  127796. + gcmkONERROR(
  127797. + gckHARDWARE_SetMMUv2(
  127798. + Mmu->hardware,
  127799. + gcvTRUE,
  127800. + Mmu->mtlbLogical,
  127801. + gcvMMU_MODE_4K,
  127802. + (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
  127803. + gcvFALSE
  127804. + ));
  127805. +#endif
  127806. +
  127807. + Mmu->enabled = gcvTRUE;
  127808. +
  127809. + /* Success. */
  127810. + gcmkFOOTER_NO();
  127811. + return gcvSTATUS_OK;
  127812. + }
  127813. +
  127814. +OnError:
  127815. + /* Return the status. */
  127816. + gcmkFOOTER();
  127817. + return status;
  127818. +}
  127819. +
  127820. +gceSTATUS
  127821. +gckMMU_SetPage(
  127822. + IN gckMMU Mmu,
  127823. + IN gctUINT32 PageAddress,
  127824. + IN gctUINT32 *PageEntry
  127825. + )
  127826. +{
  127827. +#if gcdMIRROR_PAGETABLE
  127828. + gctUINT32_PTR pageEntry;
  127829. + gctINT i;
  127830. + gckMMU mmu;
  127831. + gctUINT32 offset = (gctUINT32)PageEntry - (gctUINT32)Mmu->pageTableLogical;
  127832. +#endif
  127833. +
  127834. + gctUINT32 data;
  127835. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  127836. +
  127837. + /* Verify the arguments. */
  127838. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127839. + gcmkVERIFY_ARGUMENT(PageEntry != gcvNULL);
  127840. + gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
  127841. +
  127842. + if (Mmu->hardware->mmuVersion == 0)
  127843. + {
  127844. + data = PageAddress;
  127845. + }
  127846. + else
  127847. + {
  127848. + data = _SetPage(PageAddress);
  127849. + }
  127850. +
  127851. + _WritePageEntry(PageEntry, data);
  127852. +
  127853. +#if gcdMIRROR_PAGETABLE
  127854. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  127855. + {
  127856. + mmu = mirrorPageTable->mmus[i];
  127857. +
  127858. + if (mmu != Mmu)
  127859. + {
  127860. + pageEntry = mmu->pageTableLogical + offset / 4;
  127861. +
  127862. + if (mmu->hardware->mmuVersion == 0)
  127863. + {
  127864. + _WritePageEntry(pageEntry, PageAddress);
  127865. + }
  127866. + else
  127867. + {
  127868. + _WritePageEntry(pageEntry, _SetPage(PageAddress));
  127869. + }
  127870. + }
  127871. +
  127872. + }
  127873. +#endif
  127874. + /* Success. */
  127875. + gcmkFOOTER_NO();
  127876. + return gcvSTATUS_OK;
  127877. +}
  127878. +
  127879. +#ifdef __QNXNTO__
  127880. +gceSTATUS
  127881. +gckMMU_InsertNode(
  127882. + IN gckMMU Mmu,
  127883. + IN gcuVIDMEM_NODE_PTR Node)
  127884. +{
  127885. + gceSTATUS status;
  127886. + gctBOOL mutex = gcvFALSE;
  127887. +
  127888. + gcmkHEADER_ARG("Mmu=0x%x Node=0x%x", Mmu, Node);
  127889. +
  127890. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127891. +
  127892. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
  127893. + mutex = gcvTRUE;
  127894. +
  127895. + Node->Virtual.next = Mmu->nodeList;
  127896. + Mmu->nodeList = Node;
  127897. +
  127898. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  127899. +
  127900. + gcmkFOOTER();
  127901. + return gcvSTATUS_OK;
  127902. +
  127903. +OnError:
  127904. + if (mutex)
  127905. + {
  127906. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  127907. + }
  127908. +
  127909. + gcmkFOOTER();
  127910. + return status;
  127911. +}
  127912. +
  127913. +gceSTATUS
  127914. +gckMMU_RemoveNode(
  127915. + IN gckMMU Mmu,
  127916. + IN gcuVIDMEM_NODE_PTR Node)
  127917. +{
  127918. + gceSTATUS status;
  127919. + gctBOOL mutex = gcvFALSE;
  127920. + gcuVIDMEM_NODE_PTR *iter;
  127921. +
  127922. + gcmkHEADER_ARG("Mmu=0x%x Node=0x%x", Mmu, Node);
  127923. +
  127924. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127925. +
  127926. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
  127927. + mutex = gcvTRUE;
  127928. +
  127929. + for (iter = &Mmu->nodeList; *iter; iter = &(*iter)->Virtual.next)
  127930. + {
  127931. + if (*iter == Node)
  127932. + {
  127933. + *iter = Node->Virtual.next;
  127934. + break;
  127935. + }
  127936. + }
  127937. +
  127938. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  127939. +
  127940. + gcmkFOOTER();
  127941. + return gcvSTATUS_OK;
  127942. +
  127943. +OnError:
  127944. + if (mutex)
  127945. + {
  127946. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  127947. + }
  127948. +
  127949. + gcmkFOOTER();
  127950. + return status;
  127951. +}
  127952. +
  127953. +gceSTATUS
  127954. +gckMMU_FreeHandleMemory(
  127955. + IN gckKERNEL Kernel,
  127956. + IN gckMMU Mmu,
  127957. + IN gctUINT32 Pid
  127958. + )
  127959. +{
  127960. + gceSTATUS status;
  127961. + gctBOOL acquired = gcvFALSE;
  127962. + gcuVIDMEM_NODE_PTR curr, next;
  127963. +
  127964. + gcmkHEADER_ARG("Kernel=0x%x, Mmu=0x%x Pid=%u", Kernel, Mmu, Pid);
  127965. +
  127966. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  127967. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  127968. +
  127969. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
  127970. + acquired = gcvTRUE;
  127971. +
  127972. + for (curr = Mmu->nodeList; curr != gcvNULL; curr = next)
  127973. + {
  127974. + next = curr->Virtual.next;
  127975. +
  127976. + if (curr->Virtual.processID == Pid)
  127977. + {
  127978. + while (curr->Virtual.unlockPendings[Kernel->core] == 0 && curr->Virtual.lockeds[Kernel->core] > 0)
  127979. + {
  127980. + gcmkONERROR(gckVIDMEM_Unlock(Kernel, curr, gcvSURF_TYPE_UNKNOWN, gcvNULL));
  127981. + }
  127982. +
  127983. + gcmkVERIFY_OK(gckVIDMEM_Free(curr));
  127984. + }
  127985. + }
  127986. +
  127987. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  127988. +
  127989. + gcmkFOOTER();
  127990. + return gcvSTATUS_OK;
  127991. +
  127992. +OnError:
  127993. + if (acquired)
  127994. + {
  127995. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  127996. + }
  127997. +
  127998. + gcmkFOOTER();
  127999. + return status;
  128000. +}
  128001. +#endif
  128002. +
  128003. +gceSTATUS
  128004. +gckMMU_Flush(
  128005. + IN gckMMU Mmu
  128006. + )
  128007. +{
  128008. + gckHARDWARE hardware;
  128009. +#if gcdSHARED_PAGETABLE
  128010. + gctINT i;
  128011. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  128012. + {
  128013. +#if gcdENABLE_VG
  128014. + if (i == gcvCORE_VG)
  128015. + {
  128016. + continue;
  128017. + }
  128018. +#endif
  128019. + hardware = sharedPageTable->hardwares[i];
  128020. + if (hardware)
  128021. + {
  128022. + /* Notify cores who use this page table. */
  128023. + gcmkVERIFY_OK(
  128024. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  128025. + }
  128026. + }
  128027. +#elif gcdMIRROR_PAGETABLE
  128028. + gctINT i;
  128029. + for (i = 0; i < mirrorPageTable->reference; i++)
  128030. + {
  128031. + hardware = mirrorPageTable->hardwares[i];
  128032. +
  128033. + /* Notify cores who use this page table. */
  128034. + gcmkVERIFY_OK(
  128035. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  128036. + }
  128037. +#else
  128038. + hardware = Mmu->hardware;
  128039. + gcmkVERIFY_OK(
  128040. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  128041. +#endif
  128042. +
  128043. + return gcvSTATUS_OK;
  128044. +}
  128045. +
  128046. +gceSTATUS
  128047. +gckMMU_DumpPageTableEntry(
  128048. + IN gckMMU Mmu,
  128049. + IN gctUINT32 Address
  128050. + )
  128051. +{
  128052. + gctUINT32_PTR pageTable;
  128053. + gctUINT32 index;
  128054. + gctUINT32 mtlb, stlb;
  128055. +
  128056. + gcmkHEADER_ARG("Mmu=0x%08X Address=0x%08X", Mmu, Address);
  128057. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  128058. +
  128059. + gcmkASSERT(Mmu->hardware->mmuVersion > 0);
  128060. +
  128061. + mtlb = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
  128062. + stlb = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
  128063. +
  128064. + if (Address >= 0x80000000)
  128065. + {
  128066. + pageTable = Mmu->pageTableLogical;
  128067. +
  128068. + index = (mtlb - Mmu->dynamicMappingStart)
  128069. + * gcdMMU_STLB_4K_ENTRY_NUM
  128070. + + stlb;
  128071. +
  128072. + gcmkPRINT(" Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
  128073. + }
  128074. +
  128075. + gcmkFOOTER_NO();
  128076. + return gcvSTATUS_OK;
  128077. +}
  128078. +
  128079. +/******************************************************************************
  128080. +****************************** T E S T C O D E ******************************
  128081. +******************************************************************************/
  128082. +
  128083. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c
  128084. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c 1969-12-31 18:00:00.000000000 -0600
  128085. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c 2014-12-08 00:31:53.468418001 -0600
  128086. @@ -0,0 +1,522 @@
  128087. +/****************************************************************************
  128088. +*
  128089. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  128090. +*
  128091. +* This program is free software; you can redistribute it and/or modify
  128092. +* it under the terms of the GNU General Public License as published by
  128093. +* the Free Software Foundation; either version 2 of the license, or
  128094. +* (at your option) any later version.
  128095. +*
  128096. +* This program is distributed in the hope that it will be useful,
  128097. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  128098. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  128099. +* GNU General Public License for more details.
  128100. +*
  128101. +* You should have received a copy of the GNU General Public License
  128102. +* along with this program; if not write to the Free Software
  128103. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  128104. +*
  128105. +*****************************************************************************/
  128106. +
  128107. +
  128108. +#include "gc_hal_kernel_precomp.h"
  128109. +
  128110. +#if gcdENABLE_VG
  128111. +
  128112. +#define _GC_OBJ_ZONE gcvZONE_MMU
  128113. +
  128114. +/*******************************************************************************
  128115. +**
  128116. +** gckVGMMU_Construct
  128117. +**
  128118. +** Construct a new gckVGMMU object.
  128119. +**
  128120. +** INPUT:
  128121. +**
  128122. +** gckVGKERNEL Kernel
  128123. +** Pointer to an gckVGKERNEL object.
  128124. +**
  128125. +** gctSIZE_T MmuSize
  128126. +** Number of bytes for the page table.
  128127. +**
  128128. +** OUTPUT:
  128129. +**
  128130. +** gckVGMMU * Mmu
  128131. +** Pointer to a variable that receives the gckVGMMU object pointer.
  128132. +*/
  128133. +gceSTATUS gckVGMMU_Construct(
  128134. + IN gckVGKERNEL Kernel,
  128135. + IN gctSIZE_T MmuSize,
  128136. + OUT gckVGMMU * Mmu
  128137. + )
  128138. +{
  128139. + gckOS os;
  128140. + gckVGHARDWARE hardware;
  128141. + gceSTATUS status;
  128142. + gckVGMMU mmu;
  128143. + gctUINT32 * pageTable;
  128144. + gctUINT32 i;
  128145. +
  128146. + gcmkHEADER_ARG("Kernel=0x%x MmuSize=0x%x Mmu=0x%x", Kernel, MmuSize, Mmu);
  128147. +
  128148. + /* Verify the arguments. */
  128149. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  128150. + gcmkVERIFY_ARGUMENT(MmuSize > 0);
  128151. + gcmkVERIFY_ARGUMENT(Mmu != gcvNULL);
  128152. +
  128153. + /* Extract the gckOS object pointer. */
  128154. + os = Kernel->os;
  128155. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  128156. +
  128157. + /* Extract the gckVGHARDWARE object pointer. */
  128158. + hardware = Kernel->hardware;
  128159. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  128160. +
  128161. + /* Allocate memory for the gckVGMMU object. */
  128162. + status = gckOS_Allocate(os, sizeof(struct _gckVGMMU), (gctPOINTER *) &mmu);
  128163. +
  128164. + if (status < 0)
  128165. + {
  128166. + /* Error. */
  128167. + gcmkFATAL(
  128168. + "%s(%d): could not allocate gckVGMMU object.",
  128169. + __FUNCTION__, __LINE__
  128170. + );
  128171. +
  128172. + gcmkFOOTER();
  128173. + return status;
  128174. + }
  128175. +
  128176. + /* Initialize the gckVGMMU object. */
  128177. + mmu->object.type = gcvOBJ_MMU;
  128178. + mmu->os = os;
  128179. + mmu->hardware = hardware;
  128180. +
  128181. + /* Create the mutex. */
  128182. + status = gckOS_CreateMutex(os, &mmu->mutex);
  128183. +
  128184. + if (status < 0)
  128185. + {
  128186. + /* Roll back. */
  128187. + mmu->object.type = gcvOBJ_UNKNOWN;
  128188. + gcmkVERIFY_OK(gckOS_Free(os, mmu));
  128189. +
  128190. + gcmkFOOTER();
  128191. + /* Error. */
  128192. + return status;
  128193. + }
  128194. +
  128195. + /* Allocate the page table. */
  128196. + mmu->pageTableSize = MmuSize;
  128197. + status = gckOS_AllocateContiguous(os,
  128198. + gcvFALSE,
  128199. + &mmu->pageTableSize,
  128200. + &mmu->pageTablePhysical,
  128201. + &mmu->pageTableLogical);
  128202. +
  128203. + if (status < 0)
  128204. + {
  128205. + /* Roll back. */
  128206. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, mmu->mutex));
  128207. +
  128208. + mmu->object.type = gcvOBJ_UNKNOWN;
  128209. + gcmkVERIFY_OK(gckOS_Free(os, mmu));
  128210. +
  128211. + /* Error. */
  128212. + gcmkFATAL(
  128213. + "%s(%d): could not allocate page table.",
  128214. + __FUNCTION__, __LINE__
  128215. + );
  128216. +
  128217. + gcmkFOOTER();
  128218. + return status;
  128219. + }
  128220. +
  128221. + /* Compute number of entries in page table. */
  128222. + mmu->entryCount = mmu->pageTableSize / sizeof(gctUINT32);
  128223. + mmu->entry = 0;
  128224. +
  128225. + /* Mark the entire page table as available. */
  128226. + pageTable = (gctUINT32 *) mmu->pageTableLogical;
  128227. + for (i = 0; i < mmu->entryCount; i++)
  128228. + {
  128229. + pageTable[i] = (gctUINT32)~0;
  128230. + }
  128231. +
  128232. + /* Set page table address. */
  128233. + status = gckVGHARDWARE_SetMMU(hardware, mmu->pageTableLogical);
  128234. +
  128235. + if (status < 0)
  128236. + {
  128237. + /* Free the page table. */
  128238. + gcmkVERIFY_OK(gckOS_FreeContiguous(mmu->os,
  128239. + mmu->pageTablePhysical,
  128240. + mmu->pageTableLogical,
  128241. + mmu->pageTableSize));
  128242. +
  128243. + /* Roll back. */
  128244. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, mmu->mutex));
  128245. +
  128246. + mmu->object.type = gcvOBJ_UNKNOWN;
  128247. + gcmkVERIFY_OK(gckOS_Free(os, mmu));
  128248. +
  128249. + /* Error. */
  128250. + gcmkFATAL(
  128251. + "%s(%d): could not program page table.",
  128252. + __FUNCTION__, __LINE__
  128253. + );
  128254. +
  128255. + gcmkFOOTER();
  128256. + return status;
  128257. + }
  128258. +
  128259. + /* Return the gckVGMMU object pointer. */
  128260. + *Mmu = mmu;
  128261. +
  128262. + gcmkTRACE_ZONE(
  128263. + gcvLEVEL_INFO, gcvZONE_MMU,
  128264. + "%s(%d): %u entries at %p.(0x%08X)\n",
  128265. + __FUNCTION__, __LINE__,
  128266. + mmu->entryCount,
  128267. + mmu->pageTableLogical,
  128268. + mmu->pageTablePhysical
  128269. + );
  128270. +
  128271. + gcmkFOOTER_NO();
  128272. + /* Success. */
  128273. + return gcvSTATUS_OK;
  128274. +}
  128275. +
  128276. +/*******************************************************************************
  128277. +**
  128278. +** gckVGMMU_Destroy
  128279. +**
  128280. +** Destroy a nAQMMU object.
  128281. +**
  128282. +** INPUT:
  128283. +**
  128284. +** gckVGMMU Mmu
  128285. +** Pointer to an gckVGMMU object.
  128286. +**
  128287. +** OUTPUT:
  128288. +**
  128289. +** Nothing.
  128290. +*/
  128291. +gceSTATUS gckVGMMU_Destroy(
  128292. + IN gckVGMMU Mmu
  128293. + )
  128294. +{
  128295. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  128296. +
  128297. + /* Verify the arguments. */
  128298. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  128299. +
  128300. + /* Free the page table. */
  128301. + gcmkVERIFY_OK(gckOS_FreeContiguous(Mmu->os,
  128302. + Mmu->pageTablePhysical,
  128303. + Mmu->pageTableLogical,
  128304. + Mmu->pageTableSize));
  128305. +
  128306. + /* Roll back. */
  128307. + gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->mutex));
  128308. +
  128309. + /* Mark the gckVGMMU object as unknown. */
  128310. + Mmu->object.type = gcvOBJ_UNKNOWN;
  128311. +
  128312. + /* Free the gckVGMMU object. */
  128313. + gcmkVERIFY_OK(gckOS_Free(Mmu->os, Mmu));
  128314. +
  128315. + gcmkFOOTER_NO();
  128316. + /* Success. */
  128317. + return gcvSTATUS_OK;
  128318. +}
  128319. +
  128320. +/*******************************************************************************
  128321. +**
  128322. +** gckVGMMU_AllocatePages
  128323. +**
  128324. +** Allocate pages inside the page table.
  128325. +**
  128326. +** INPUT:
  128327. +**
  128328. +** gckVGMMU Mmu
  128329. +** Pointer to an gckVGMMU object.
  128330. +**
  128331. +** gctSIZE_T PageCount
  128332. +** Number of pages to allocate.
  128333. +**
  128334. +** OUTPUT:
  128335. +**
  128336. +** gctPOINTER * PageTable
  128337. +** Pointer to a variable that receives the base address of the page
  128338. +** table.
  128339. +**
  128340. +** gctUINT32 * Address
  128341. +** Pointer to a variable that receives the hardware specific address.
  128342. +*/
  128343. +gceSTATUS gckVGMMU_AllocatePages(
  128344. + IN gckVGMMU Mmu,
  128345. + IN gctSIZE_T PageCount,
  128346. + OUT gctPOINTER * PageTable,
  128347. + OUT gctUINT32 * Address
  128348. + )
  128349. +{
  128350. + gceSTATUS status;
  128351. + gctUINT32 tail, index, i;
  128352. + gctUINT32 * table;
  128353. + gctBOOL allocated = gcvFALSE;
  128354. +
  128355. + gcmkHEADER_ARG("Mmu=0x%x PageCount=0x%x PageTable=0x%x Address=0x%x",
  128356. + Mmu, PageCount, PageTable, Address);
  128357. +
  128358. + /* Verify the arguments. */
  128359. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  128360. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  128361. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  128362. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  128363. +
  128364. + gcmkTRACE_ZONE(
  128365. + gcvLEVEL_INFO, gcvZONE_MMU,
  128366. + "%s(%d): %u pages.\n",
  128367. + __FUNCTION__, __LINE__,
  128368. + PageCount
  128369. + );
  128370. +
  128371. + if (PageCount > Mmu->entryCount)
  128372. + {
  128373. + gcmkTRACE_ZONE(
  128374. + gcvLEVEL_ERROR, gcvZONE_MMU,
  128375. + "%s(%d): page table too small for %u pages.\n",
  128376. + __FUNCTION__, __LINE__,
  128377. + PageCount
  128378. + );
  128379. +
  128380. + gcmkFOOTER_NO();
  128381. + /* Not enough pages avaiable. */
  128382. + return gcvSTATUS_OUT_OF_RESOURCES;
  128383. + }
  128384. +
  128385. + /* Grab the mutex. */
  128386. + status = gckOS_AcquireMutex(Mmu->os, Mmu->mutex, gcvINFINITE);
  128387. +
  128388. + if (status < 0)
  128389. + {
  128390. + gcmkTRACE_ZONE(
  128391. + gcvLEVEL_ERROR, gcvZONE_MMU,
  128392. + "%s(%d): could not acquire mutex.\n"
  128393. + ,__FUNCTION__, __LINE__
  128394. + );
  128395. +
  128396. + gcmkFOOTER();
  128397. + /* Error. */
  128398. + return status;
  128399. + }
  128400. +
  128401. + /* Compute the tail for this allocation. */
  128402. + tail = Mmu->entryCount - PageCount;
  128403. +
  128404. + /* Walk all entries until we find enough slots. */
  128405. + for (index = Mmu->entry; index <= tail;)
  128406. + {
  128407. + /* Access page table. */
  128408. + table = (gctUINT32 *) Mmu->pageTableLogical + index;
  128409. +
  128410. + /* See if all slots are available. */
  128411. + for (i = 0; i < PageCount; i++, table++)
  128412. + {
  128413. + if (*table != ~0)
  128414. + {
  128415. + /* Start from next slot. */
  128416. + index += i + 1;
  128417. + break;
  128418. + }
  128419. + }
  128420. +
  128421. + if (i == PageCount)
  128422. + {
  128423. + /* Bail out if we have enough page entries. */
  128424. + allocated = gcvTRUE;
  128425. + break;
  128426. + }
  128427. + }
  128428. +
  128429. + if (!allocated)
  128430. + {
  128431. + if (status >= 0)
  128432. + {
  128433. + /* Walk all entries until we find enough slots. */
  128434. + for (index = 0; index <= tail;)
  128435. + {
  128436. + /* Access page table. */
  128437. + table = (gctUINT32 *) Mmu->pageTableLogical + index;
  128438. +
  128439. + /* See if all slots are available. */
  128440. + for (i = 0; i < PageCount; i++, table++)
  128441. + {
  128442. + if (*table != ~0)
  128443. + {
  128444. + /* Start from next slot. */
  128445. + index += i + 1;
  128446. + break;
  128447. + }
  128448. + }
  128449. +
  128450. + if (i == PageCount)
  128451. + {
  128452. + /* Bail out if we have enough page entries. */
  128453. + allocated = gcvTRUE;
  128454. + break;
  128455. + }
  128456. + }
  128457. + }
  128458. + }
  128459. +
  128460. + if (!allocated && (status >= 0))
  128461. + {
  128462. + gcmkTRACE_ZONE(
  128463. + gcvLEVEL_ERROR, gcvZONE_MMU,
  128464. + "%s(%d): not enough free pages for %u pages.\n",
  128465. + __FUNCTION__, __LINE__,
  128466. + PageCount
  128467. + );
  128468. +
  128469. + /* Not enough empty slots available. */
  128470. + status = gcvSTATUS_OUT_OF_RESOURCES;
  128471. + }
  128472. +
  128473. + if (status >= 0)
  128474. + {
  128475. + /* Build virtual address. */
  128476. + status = gckVGHARDWARE_BuildVirtualAddress(Mmu->hardware,
  128477. + index,
  128478. + 0,
  128479. + Address);
  128480. +
  128481. + if (status >= 0)
  128482. + {
  128483. + /* Update current entry into page table. */
  128484. + Mmu->entry = index + PageCount;
  128485. +
  128486. + /* Return pointer to page table. */
  128487. + *PageTable = (gctUINT32 *) Mmu->pageTableLogical + index;
  128488. +
  128489. + gcmkTRACE_ZONE(
  128490. + gcvLEVEL_INFO, gcvZONE_MMU,
  128491. + "%s(%d): allocated %u pages at index %u (0x%08X) @ %p.\n",
  128492. + __FUNCTION__, __LINE__,
  128493. + PageCount,
  128494. + index,
  128495. + *Address,
  128496. + *PageTable
  128497. + );
  128498. + }
  128499. + }
  128500. +
  128501. + /* Release the mutex. */
  128502. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->mutex));
  128503. + gcmkFOOTER();
  128504. +
  128505. + /* Return status. */
  128506. + return status;
  128507. +}
  128508. +
  128509. +/*******************************************************************************
  128510. +**
  128511. +** gckVGMMU_FreePages
  128512. +**
  128513. +** Free pages inside the page table.
  128514. +**
  128515. +** INPUT:
  128516. +**
  128517. +** gckVGMMU Mmu
  128518. +** Pointer to an gckVGMMU object.
  128519. +**
  128520. +** gctPOINTER PageTable
  128521. +** Base address of the page table to free.
  128522. +**
  128523. +** gctSIZE_T PageCount
  128524. +** Number of pages to free.
  128525. +**
  128526. +** OUTPUT:
  128527. +**
  128528. +** Nothing.
  128529. +*/
  128530. +gceSTATUS gckVGMMU_FreePages(
  128531. + IN gckVGMMU Mmu,
  128532. + IN gctPOINTER PageTable,
  128533. + IN gctSIZE_T PageCount
  128534. + )
  128535. +{
  128536. + gctUINT32 * table;
  128537. +
  128538. + gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=0x%x",
  128539. + Mmu, PageTable, PageCount);
  128540. +
  128541. + /* Verify the arguments. */
  128542. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  128543. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  128544. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  128545. +
  128546. + gcmkTRACE_ZONE(
  128547. + gcvLEVEL_INFO, gcvZONE_MMU,
  128548. + "%s(%d): freeing %u pages at index %u @ %p.\n",
  128549. + __FUNCTION__, __LINE__,
  128550. + PageCount,
  128551. + ((gctUINT32 *) PageTable - (gctUINT32 *) Mmu->pageTableLogical),
  128552. + PageTable
  128553. + );
  128554. +
  128555. + /* Convert pointer. */
  128556. + table = (gctUINT32 *) PageTable;
  128557. +
  128558. + /* Mark the page table entries as available. */
  128559. + while (PageCount-- > 0)
  128560. + {
  128561. + *table++ = (gctUINT32)~0;
  128562. + }
  128563. +
  128564. + gcmkFOOTER_NO();
  128565. + /* Success. */
  128566. + return gcvSTATUS_OK;
  128567. +}
  128568. +
  128569. +gceSTATUS
  128570. +gckVGMMU_SetPage(
  128571. + IN gckVGMMU Mmu,
  128572. + IN gctUINT32 PageAddress,
  128573. + IN gctUINT32 *PageEntry
  128574. + )
  128575. +{
  128576. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  128577. +
  128578. + /* Verify the arguments. */
  128579. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  128580. + gcmkVERIFY_ARGUMENT(PageEntry != gcvNULL);
  128581. + gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
  128582. +
  128583. + *PageEntry = PageAddress;
  128584. +
  128585. + /* Success. */
  128586. + gcmkFOOTER_NO();
  128587. + return gcvSTATUS_OK;
  128588. +}
  128589. +
  128590. +gceSTATUS
  128591. +gckVGMMU_Flush(
  128592. + IN gckVGMMU Mmu
  128593. + )
  128594. +{
  128595. + gckVGHARDWARE hardware;
  128596. +
  128597. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  128598. +
  128599. + hardware = Mmu->hardware;
  128600. + gcmkVERIFY_OK(
  128601. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  128602. +
  128603. + /* Success. */
  128604. + gcmkFOOTER_NO();
  128605. + return gcvSTATUS_OK;
  128606. +}
  128607. +
  128608. +#endif /* gcdENABLE_VG */
  128609. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c
  128610. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c 1969-12-31 18:00:00.000000000 -0600
  128611. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c 2014-12-08 00:31:53.468418001 -0600
  128612. @@ -0,0 +1,347 @@
  128613. +/****************************************************************************
  128614. +*
  128615. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  128616. +*
  128617. +* This program is free software; you can redistribute it and/or modify
  128618. +* it under the terms of the GNU General Public License as published by
  128619. +* the Free Software Foundation; either version 2 of the license, or
  128620. +* (at your option) any later version.
  128621. +*
  128622. +* This program is distributed in the hope that it will be useful,
  128623. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  128624. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  128625. +* GNU General Public License for more details.
  128626. +*
  128627. +* You should have received a copy of the GNU General Public License
  128628. +* along with this program; if not write to the Free Software
  128629. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  128630. +*
  128631. +*****************************************************************************/
  128632. +
  128633. +
  128634. +#include "gc_hal_kernel_precomp.h"
  128635. +
  128636. +#define _GC_OBJ_ZONE gcvZONE_POWER
  128637. +
  128638. +/******************************************************************************\
  128639. +************************ Dynamic Voltage Frequency Setting *********************
  128640. +\******************************************************************************/
  128641. +#if gcdDVFS
  128642. +static gctUINT32
  128643. +_GetLoadHistory(
  128644. + IN gckDVFS Dvfs,
  128645. + IN gctUINT32 Select,
  128646. + IN gctUINT32 Index
  128647. +)
  128648. +{
  128649. + return Dvfs->loads[Index];
  128650. +}
  128651. +
  128652. +static void
  128653. +_IncreaseScale(
  128654. + IN gckDVFS Dvfs,
  128655. + IN gctUINT32 Load,
  128656. + OUT gctUINT8 *Scale
  128657. + )
  128658. +{
  128659. + if (Dvfs->currentScale < 32)
  128660. + {
  128661. + *Scale = Dvfs->currentScale + 8;
  128662. + }
  128663. + else
  128664. + {
  128665. + *Scale = Dvfs->currentScale + 8;
  128666. + *Scale = gcmMIN(64, *Scale);
  128667. + }
  128668. +}
  128669. +
  128670. +static void
  128671. +_RecordFrequencyHistory(
  128672. + gckDVFS Dvfs,
  128673. + gctUINT32 Frequency
  128674. + )
  128675. +{
  128676. + gctUINT32 i = 0;
  128677. +
  128678. + struct _FrequencyHistory *history = Dvfs->frequencyHistory;
  128679. +
  128680. + for (i = 0; i < 16; i++)
  128681. + {
  128682. + if (history->frequency == Frequency)
  128683. + {
  128684. + break;
  128685. + }
  128686. +
  128687. + if (history->frequency == 0)
  128688. + {
  128689. + history->frequency = Frequency;
  128690. + break;
  128691. + }
  128692. +
  128693. + history++;
  128694. + }
  128695. +
  128696. + if (i < 16)
  128697. + {
  128698. + history->count++;
  128699. + }
  128700. +}
  128701. +
  128702. +static gctUINT32
  128703. +_GetFrequencyHistory(
  128704. + gckDVFS Dvfs,
  128705. + gctUINT32 Frequency
  128706. + )
  128707. +{
  128708. + gctUINT32 i = 0;
  128709. +
  128710. + struct _FrequencyHistory * history = Dvfs->frequencyHistory;
  128711. +
  128712. + for (i = 0; i < 16; i++)
  128713. + {
  128714. + if (history->frequency == Frequency)
  128715. + {
  128716. + break;
  128717. + }
  128718. +
  128719. + history++;
  128720. + }
  128721. +
  128722. + if (i < 16)
  128723. + {
  128724. + return history->count;
  128725. + }
  128726. +
  128727. + return 0;
  128728. +}
  128729. +
  128730. +static void
  128731. +_Policy(
  128732. + IN gckDVFS Dvfs,
  128733. + IN gctUINT32 Load,
  128734. + OUT gctUINT8 *Scale
  128735. + )
  128736. +{
  128737. + gctUINT8 load[4], nextLoad;
  128738. + gctUINT8 scale;
  128739. +
  128740. + /* Last 4 history. */
  128741. + load[0] = (Load & 0xFF);
  128742. + load[1] = (Load & 0xFF00) >> 8;
  128743. + load[2] = (Load & 0xFF0000) >> 16;
  128744. + load[3] = (Load & 0xFF000000) >> 24;
  128745. +
  128746. + /* Determine target scale. */
  128747. + if (load[0] > 54)
  128748. + {
  128749. + _IncreaseScale(Dvfs, Load, &scale);
  128750. + }
  128751. + else
  128752. + {
  128753. + nextLoad = (load[0] + load[1] + load[2] + load[3])/4;
  128754. +
  128755. + scale = Dvfs->currentScale * (nextLoad) / 54;
  128756. +
  128757. + scale = gcmMAX(1, scale);
  128758. + scale = gcmMIN(64, scale);
  128759. + }
  128760. +
  128761. + Dvfs->totalConfig++;
  128762. +
  128763. + Dvfs->loads[(load[0]-1)/8]++;
  128764. +
  128765. + *Scale = scale;
  128766. +
  128767. +
  128768. + if (Dvfs->totalConfig % 100 == 0)
  128769. + {
  128770. + gcmkPRINT("=======================================================");
  128771. + gcmkPRINT("GPU Load: %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
  128772. + 8, 16, 24, 32, 40, 48, 56, 64);
  128773. + gcmkPRINT(" %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
  128774. + _GetLoadHistory(Dvfs,2, 0),
  128775. + _GetLoadHistory(Dvfs,2, 1),
  128776. + _GetLoadHistory(Dvfs,2, 2),
  128777. + _GetLoadHistory(Dvfs,2, 3),
  128778. + _GetLoadHistory(Dvfs,2, 4),
  128779. + _GetLoadHistory(Dvfs,2, 5),
  128780. + _GetLoadHistory(Dvfs,2, 6),
  128781. + _GetLoadHistory(Dvfs,2, 7)
  128782. + );
  128783. +
  128784. + gcmkPRINT("Frequency(MHz) %-8d %-8d %-8d %-8d %-8d",
  128785. + 58, 120, 240, 360, 480);
  128786. + gcmkPRINT(" %-8d %-8d %-8d %-8d %-8d",
  128787. + _GetFrequencyHistory(Dvfs, 58),
  128788. + _GetFrequencyHistory(Dvfs,120),
  128789. + _GetFrequencyHistory(Dvfs,240),
  128790. + _GetFrequencyHistory(Dvfs,360),
  128791. + _GetFrequencyHistory(Dvfs,480)
  128792. + );
  128793. + }
  128794. +}
  128795. +
  128796. +static void
  128797. +_TimerFunction(
  128798. + gctPOINTER Data
  128799. + )
  128800. +{
  128801. + gceSTATUS status;
  128802. + gckDVFS dvfs = (gckDVFS) Data;
  128803. + gckHARDWARE hardware = dvfs->hardware;
  128804. + gctUINT32 value;
  128805. + gctUINT32 frequency;
  128806. + gctUINT8 scale;
  128807. + gctUINT32 t1, t2, consumed;
  128808. +
  128809. + gckOS_GetTicks(&t1);
  128810. +
  128811. + gcmkONERROR(gckHARDWARE_QueryLoad(hardware, &value));
  128812. +
  128813. + /* determine target sacle. */
  128814. + _Policy(dvfs, value, &scale);
  128815. +
  128816. + /* Set frequency and voltage. */
  128817. + gcmkONERROR(gckOS_SetGPUFrequency(hardware->os, hardware->core, scale));
  128818. +
  128819. + /* Query real frequency. */
  128820. + gcmkONERROR(
  128821. + gckOS_QueryGPUFrequency(hardware->os,
  128822. + hardware->core,
  128823. + &frequency,
  128824. + &dvfs->currentScale));
  128825. +
  128826. + _RecordFrequencyHistory(dvfs, frequency);
  128827. +
  128828. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_POWER,
  128829. + "Current frequency = %d",
  128830. + frequency);
  128831. +
  128832. + /* Set period. */
  128833. + gcmkONERROR(gckHARDWARE_SetDVFSPeroid(hardware, frequency));
  128834. +
  128835. +OnError:
  128836. + /* Determine next querying time. */
  128837. + gckOS_GetTicks(&t2);
  128838. +
  128839. + consumed = gcmMIN(((long)t2 - (long)t1), 5);
  128840. +
  128841. + if (dvfs->stop == gcvFALSE)
  128842. + {
  128843. + gcmkVERIFY_OK(gckOS_StartTimer(hardware->os,
  128844. + dvfs->timer,
  128845. + dvfs->pollingTime - consumed));
  128846. + }
  128847. +
  128848. + return;
  128849. +}
  128850. +
  128851. +gceSTATUS
  128852. +gckDVFS_Construct(
  128853. + IN gckHARDWARE Hardware,
  128854. + OUT gckDVFS * Dvfs
  128855. + )
  128856. +{
  128857. + gceSTATUS status;
  128858. + gctPOINTER pointer;
  128859. + gckDVFS dvfs = gcvNULL;
  128860. + gckOS os = Hardware->os;
  128861. +
  128862. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  128863. +
  128864. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  128865. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  128866. +
  128867. + /* Allocate a gckDVFS manager. */
  128868. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckDVFS), &pointer));
  128869. +
  128870. + gckOS_ZeroMemory(pointer, gcmSIZEOF(struct _gckDVFS));
  128871. +
  128872. + dvfs = pointer;
  128873. +
  128874. + /* Initialization. */
  128875. + dvfs->hardware = Hardware;
  128876. + dvfs->pollingTime = gcdDVFS_POLLING_TIME;
  128877. + dvfs->os = Hardware->os;
  128878. + dvfs->currentScale = 64;
  128879. +
  128880. + /* Create a polling timer. */
  128881. + gcmkONERROR(gckOS_CreateTimer(os, _TimerFunction, pointer, &dvfs->timer));
  128882. +
  128883. + /* Initialize frequency and voltage adjustment helper. */
  128884. + gcmkONERROR(gckOS_PrepareGPUFrequency(os, Hardware->core));
  128885. +
  128886. + /* Return result. */
  128887. + *Dvfs = dvfs;
  128888. +
  128889. + gcmkFOOTER_NO();
  128890. + return gcvSTATUS_OK;
  128891. +
  128892. +OnError:
  128893. + /* Roll back. */
  128894. + if (dvfs)
  128895. + {
  128896. + if (dvfs->timer)
  128897. + {
  128898. + gcmkVERIFY_OK(gckOS_DestroyTimer(os, dvfs->timer));
  128899. + }
  128900. +
  128901. + gcmkOS_SAFE_FREE(os, dvfs);
  128902. + }
  128903. +
  128904. + gcmkFOOTER();
  128905. + return status;
  128906. +}
  128907. +
  128908. +gceSTATUS
  128909. +gckDVFS_Destroy(
  128910. + IN gckDVFS Dvfs
  128911. + )
  128912. +{
  128913. + gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
  128914. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  128915. +
  128916. + /* Deinitialize helper fuunction. */
  128917. + gcmkVERIFY_OK(gckOS_FinishGPUFrequency(Dvfs->os, Dvfs->hardware->core));
  128918. +
  128919. + /* DestroyTimer. */
  128920. + gcmkVERIFY_OK(gckOS_DestroyTimer(Dvfs->os, Dvfs->timer));
  128921. +
  128922. + gcmkOS_SAFE_FREE(Dvfs->os, Dvfs);
  128923. +
  128924. + gcmkFOOTER_NO();
  128925. + return gcvSTATUS_OK;
  128926. +}
  128927. +
  128928. +gceSTATUS
  128929. +gckDVFS_Start(
  128930. + IN gckDVFS Dvfs
  128931. + )
  128932. +{
  128933. + gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
  128934. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  128935. +
  128936. + gckHARDWARE_InitDVFS(Dvfs->hardware);
  128937. +
  128938. + Dvfs->stop = gcvFALSE;
  128939. +
  128940. + gckOS_StartTimer(Dvfs->os, Dvfs->timer, Dvfs->pollingTime);
  128941. +
  128942. + gcmkFOOTER_NO();
  128943. + return gcvSTATUS_OK;
  128944. +}
  128945. +
  128946. +gceSTATUS
  128947. +gckDVFS_Stop(
  128948. + IN gckDVFS Dvfs
  128949. + )
  128950. +{
  128951. + gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
  128952. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  128953. +
  128954. + Dvfs->stop = gcvTRUE;
  128955. +
  128956. + gcmkFOOTER_NO();
  128957. + return gcvSTATUS_OK;
  128958. +}
  128959. +#endif
  128960. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h
  128961. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h 1969-12-31 18:00:00.000000000 -0600
  128962. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h 2014-12-08 00:31:53.468418001 -0600
  128963. @@ -0,0 +1,29 @@
  128964. +/****************************************************************************
  128965. +*
  128966. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  128967. +*
  128968. +* This program is free software; you can redistribute it and/or modify
  128969. +* it under the terms of the GNU General Public License as published by
  128970. +* the Free Software Foundation; either version 2 of the license, or
  128971. +* (at your option) any later version.
  128972. +*
  128973. +* This program is distributed in the hope that it will be useful,
  128974. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  128975. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  128976. +* GNU General Public License for more details.
  128977. +*
  128978. +* You should have received a copy of the GNU General Public License
  128979. +* along with this program; if not write to the Free Software
  128980. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  128981. +*
  128982. +*****************************************************************************/
  128983. +
  128984. +
  128985. +#ifndef __gc_hal_kernel_precomp_h_
  128986. +#define __gc_hal_kernel_precomp_h_
  128987. +
  128988. +#include "gc_hal.h"
  128989. +#include "gc_hal_driver.h"
  128990. +#include "gc_hal_kernel.h"
  128991. +
  128992. +#endif /* __gc_hal_kernel_precomp_h_ */
  128993. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
  128994. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c 1969-12-31 18:00:00.000000000 -0600
  128995. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c 2014-12-08 00:31:53.468418001 -0600
  128996. @@ -0,0 +1,895 @@
  128997. +/****************************************************************************
  128998. +*
  128999. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  129000. +*
  129001. +* This program is free software; you can redistribute it and/or modify
  129002. +* it under the terms of the GNU General Public License as published by
  129003. +* the Free Software Foundation; either version 2 of the license, or
  129004. +* (at your option) any later version.
  129005. +*
  129006. +* This program is distributed in the hope that it will be useful,
  129007. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  129008. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  129009. +* GNU General Public License for more details.
  129010. +*
  129011. +* You should have received a copy of the GNU General Public License
  129012. +* along with this program; if not write to the Free Software
  129013. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  129014. +*
  129015. +*****************************************************************************/
  129016. +
  129017. +
  129018. +#include "gc_hal_kernel_precomp.h"
  129019. +
  129020. +#if gcdENABLE_VG
  129021. +
  129022. +#define ENABLE_VG_TRY_VIRTUAL_MEMORY 0
  129023. +
  129024. +#define _GC_OBJ_ZONE gcvZONE_VG
  129025. +
  129026. +/******************************************************************************\
  129027. +******************************* gckKERNEL API Code ******************************
  129028. +\******************************************************************************/
  129029. +
  129030. +/*******************************************************************************
  129031. +**
  129032. +** gckKERNEL_Construct
  129033. +**
  129034. +** Construct a new gckKERNEL object.
  129035. +**
  129036. +** INPUT:
  129037. +**
  129038. +** gckOS Os
  129039. +** Pointer to an gckOS object.
  129040. +**
  129041. +** IN gctPOINTER Context
  129042. +** Pointer to a driver defined context.
  129043. +**
  129044. +** OUTPUT:
  129045. +**
  129046. +** gckKERNEL * Kernel
  129047. +** Pointer to a variable that will hold the pointer to the gckKERNEL
  129048. +** object.
  129049. +*/
  129050. +gceSTATUS gckVGKERNEL_Construct(
  129051. + IN gckOS Os,
  129052. + IN gctPOINTER Context,
  129053. + IN gckKERNEL inKernel,
  129054. + OUT gckVGKERNEL * Kernel
  129055. + )
  129056. +{
  129057. + gceSTATUS status;
  129058. + gckVGKERNEL kernel = gcvNULL;
  129059. +
  129060. + gcmkHEADER_ARG("Os=0x%x Context=0x%x", Os, Context);
  129061. + /* Verify the arguments. */
  129062. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  129063. + gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
  129064. +
  129065. + do
  129066. + {
  129067. + /* Allocate the gckKERNEL object. */
  129068. + gcmkERR_BREAK(gckOS_Allocate(
  129069. + Os,
  129070. + sizeof(struct _gckVGKERNEL),
  129071. + (gctPOINTER *) &kernel
  129072. + ));
  129073. +
  129074. + /* Initialize the gckKERNEL object. */
  129075. + kernel->object.type = gcvOBJ_KERNEL;
  129076. + kernel->os = Os;
  129077. + kernel->context = Context;
  129078. + kernel->hardware = gcvNULL;
  129079. + kernel->interrupt = gcvNULL;
  129080. + kernel->command = gcvNULL;
  129081. + kernel->mmu = gcvNULL;
  129082. + kernel->kernel = inKernel;
  129083. +
  129084. + /* Construct the gckVGHARDWARE object. */
  129085. + gcmkERR_BREAK(gckVGHARDWARE_Construct(
  129086. + Os, &kernel->hardware
  129087. + ));
  129088. +
  129089. + /* Set pointer to gckKERNEL object in gckVGHARDWARE object. */
  129090. + kernel->hardware->kernel = kernel;
  129091. +
  129092. + /* Construct the gckVGINTERRUPT object. */
  129093. + gcmkERR_BREAK(gckVGINTERRUPT_Construct(
  129094. + kernel, &kernel->interrupt
  129095. + ));
  129096. +
  129097. + /* Construct the gckVGCOMMAND object. */
  129098. + gcmkERR_BREAK(gckVGCOMMAND_Construct(
  129099. + kernel, gcmKB2BYTES(8), gcmKB2BYTES(2), &kernel->command
  129100. + ));
  129101. +
  129102. + /* Construct the gckVGMMU object. */
  129103. + gcmkERR_BREAK(gckVGMMU_Construct(
  129104. + kernel, gcmKB2BYTES(32), &kernel->mmu
  129105. + ));
  129106. +
  129107. + /* Return pointer to the gckKERNEL object. */
  129108. + *Kernel = kernel;
  129109. +
  129110. + gcmkFOOTER_ARG("*Kernel=0x%x", *Kernel);
  129111. + /* Success. */
  129112. + return gcvSTATUS_OK;
  129113. + }
  129114. + while (gcvFALSE);
  129115. +
  129116. + /* Roll back. */
  129117. + if (kernel != gcvNULL)
  129118. + {
  129119. + if (kernel->mmu != gcvNULL)
  129120. + {
  129121. + gcmkVERIFY_OK(gckVGMMU_Destroy(kernel->mmu));
  129122. + }
  129123. +
  129124. + if (kernel->command != gcvNULL)
  129125. + {
  129126. + gcmkVERIFY_OK(gckVGCOMMAND_Destroy(kernel->command));
  129127. + }
  129128. +
  129129. + if (kernel->interrupt != gcvNULL)
  129130. + {
  129131. + gcmkVERIFY_OK(gckVGINTERRUPT_Destroy(kernel->interrupt));
  129132. + }
  129133. +
  129134. + if (kernel->hardware != gcvNULL)
  129135. + {
  129136. + gcmkVERIFY_OK(gckVGHARDWARE_Destroy(kernel->hardware));
  129137. + }
  129138. +
  129139. + gcmkVERIFY_OK(gckOS_Free(Os, kernel));
  129140. + }
  129141. +
  129142. + gcmkFOOTER();
  129143. + /* Return status. */
  129144. + return status;
  129145. +}
  129146. +
  129147. +/*******************************************************************************
  129148. +**
  129149. +** gckKERNEL_Destroy
  129150. +**
  129151. +** Destroy an gckKERNEL object.
  129152. +**
  129153. +** INPUT:
  129154. +**
  129155. +** gckKERNEL Kernel
  129156. +** Pointer to an gckKERNEL object to destroy.
  129157. +**
  129158. +** OUTPUT:
  129159. +**
  129160. +** Nothing.
  129161. +*/
  129162. +gceSTATUS gckVGKERNEL_Destroy(
  129163. + IN gckVGKERNEL Kernel
  129164. + )
  129165. +{
  129166. + gceSTATUS status;
  129167. +
  129168. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  129169. +
  129170. + /* Verify the arguments. */
  129171. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  129172. +
  129173. + do
  129174. + {
  129175. + /* Destroy the gckVGMMU object. */
  129176. + if (Kernel->mmu != gcvNULL)
  129177. + {
  129178. + gcmkERR_BREAK(gckVGMMU_Destroy(Kernel->mmu));
  129179. + Kernel->mmu = gcvNULL;
  129180. + }
  129181. +
  129182. + /* Destroy the gckVGCOMMAND object. */
  129183. + if (Kernel->command != gcvNULL)
  129184. + {
  129185. + gcmkERR_BREAK(gckVGCOMMAND_Destroy(Kernel->command));
  129186. + Kernel->command = gcvNULL;
  129187. + }
  129188. +
  129189. + /* Destroy the gckVGINTERRUPT object. */
  129190. + if (Kernel->interrupt != gcvNULL)
  129191. + {
  129192. + gcmkERR_BREAK(gckVGINTERRUPT_Destroy(Kernel->interrupt));
  129193. + Kernel->interrupt = gcvNULL;
  129194. + }
  129195. +
  129196. + /* Destroy the gckVGHARDWARE object. */
  129197. + if (Kernel->hardware != gcvNULL)
  129198. + {
  129199. + gcmkERR_BREAK(gckVGHARDWARE_Destroy(Kernel->hardware));
  129200. + Kernel->hardware = gcvNULL;
  129201. + }
  129202. +
  129203. + /* Mark the gckKERNEL object as unknown. */
  129204. + Kernel->object.type = gcvOBJ_UNKNOWN;
  129205. +
  129206. + /* Free the gckKERNEL object. */
  129207. + gcmkERR_BREAK(gckOS_Free(Kernel->os, Kernel));
  129208. + }
  129209. + while (gcvFALSE);
  129210. +
  129211. + gcmkFOOTER();
  129212. +
  129213. + /* Return status. */
  129214. + return status;
  129215. +}
  129216. +
  129217. +/*******************************************************************************
  129218. +**
  129219. +** gckKERNEL_AllocateLinearMemory
  129220. +**
  129221. +** Function walks all required memory pools and allocates the requested
  129222. +** amount of video memory.
  129223. +**
  129224. +** INPUT:
  129225. +**
  129226. +** gckKERNEL Kernel
  129227. +** Pointer to an gckKERNEL object.
  129228. +**
  129229. +** gcePOOL * Pool
  129230. +** Pointer the desired memory pool.
  129231. +**
  129232. +** gctSIZE_T Bytes
  129233. +** Number of bytes to allocate.
  129234. +**
  129235. +** gctSIZE_T Alignment
  129236. +** Required buffer alignment.
  129237. +**
  129238. +** gceSURF_TYPE Type
  129239. +** Surface type.
  129240. +**
  129241. +** OUTPUT:
  129242. +**
  129243. +** gcePOOL * Pool
  129244. +** Pointer to the actual pool where the memory was allocated.
  129245. +**
  129246. +** gcuVIDMEM_NODE_PTR * Node
  129247. +** Allocated node.
  129248. +*/
  129249. +gceSTATUS
  129250. +gckKERNEL_AllocateLinearMemory(
  129251. + IN gckKERNEL Kernel,
  129252. + IN OUT gcePOOL * Pool,
  129253. + IN gctSIZE_T Bytes,
  129254. + IN gctSIZE_T Alignment,
  129255. + IN gceSURF_TYPE Type,
  129256. + OUT gcuVIDMEM_NODE_PTR * Node
  129257. + )
  129258. +{
  129259. + gcePOOL pool;
  129260. + gceSTATUS status;
  129261. + gckVIDMEM videoMemory;
  129262. +
  129263. + /* Get initial pool. */
  129264. + switch (pool = *Pool)
  129265. + {
  129266. + case gcvPOOL_DEFAULT:
  129267. + case gcvPOOL_LOCAL:
  129268. + pool = gcvPOOL_LOCAL_INTERNAL;
  129269. + break;
  129270. +
  129271. + case gcvPOOL_UNIFIED:
  129272. + pool = gcvPOOL_SYSTEM;
  129273. + break;
  129274. +
  129275. + default:
  129276. + break;
  129277. + }
  129278. +
  129279. + do
  129280. + {
  129281. + /* Verify the number of bytes to allocate. */
  129282. + if (Bytes == 0)
  129283. + {
  129284. + status = gcvSTATUS_INVALID_ARGUMENT;
  129285. + break;
  129286. + }
  129287. +
  129288. + if (pool == gcvPOOL_VIRTUAL)
  129289. + {
  129290. + /* Create a gcuVIDMEM_NODE for virtual memory. */
  129291. + gcmkERR_BREAK(gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, Node));
  129292. +
  129293. + /* Success. */
  129294. + break;
  129295. + }
  129296. +
  129297. + else
  129298. + {
  129299. + /* Get pointer to gckVIDMEM object for pool. */
  129300. + status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory);
  129301. +
  129302. + if (status == gcvSTATUS_OK)
  129303. + {
  129304. + if(*Pool == gcvPOOL_SYSTEM)
  129305. + Type |= gcvSURF_VG;
  129306. + /* Allocate memory. */
  129307. + status = gckVIDMEM_AllocateLinear(videoMemory,
  129308. + Bytes,
  129309. + Alignment,
  129310. + Type,
  129311. + Node);
  129312. +
  129313. + if (status == gcvSTATUS_OK)
  129314. + {
  129315. + /* Memory allocated. */
  129316. + break;
  129317. + }
  129318. + }
  129319. + }
  129320. +
  129321. + if (pool == gcvPOOL_LOCAL_INTERNAL)
  129322. + {
  129323. + /* Advance to external memory. */
  129324. + pool = gcvPOOL_LOCAL_EXTERNAL;
  129325. + }
  129326. + else if (pool == gcvPOOL_LOCAL_EXTERNAL)
  129327. + {
  129328. + /* Advance to contiguous system memory. */
  129329. + pool = gcvPOOL_SYSTEM;
  129330. + }
  129331. + else if (pool == gcvPOOL_SYSTEM)
  129332. + {
  129333. + /* Advance to virtual memory. */
  129334. +#if ENABLE_VG_TRY_VIRTUAL_MEMORY
  129335. + pool = gcvPOOL_VIRTUAL;
  129336. +#else
  129337. + /*VG non-contiguous memory support is not ready yet, disable it temporary*/
  129338. + status = gcvSTATUS_OUT_OF_MEMORY;
  129339. + break;
  129340. +#endif
  129341. + }
  129342. + else
  129343. + {
  129344. + /* Out of pools. */
  129345. + status = gcvSTATUS_OUT_OF_MEMORY;
  129346. + break;
  129347. + }
  129348. + }
  129349. + /* Loop only for multiple selection pools. */
  129350. + while ((*Pool == gcvPOOL_DEFAULT)
  129351. + || (*Pool == gcvPOOL_LOCAL)
  129352. + || (*Pool == gcvPOOL_UNIFIED)
  129353. + );
  129354. +
  129355. + if (gcmIS_SUCCESS(status))
  129356. + {
  129357. + /* Return pool used for allocation. */
  129358. + *Pool = pool;
  129359. + }
  129360. +
  129361. + /* Return status. */
  129362. + return status;
  129363. +}
  129364. +
  129365. +/*******************************************************************************
  129366. +**
  129367. +** gckKERNEL_Dispatch
  129368. +**
  129369. +** Dispatch a command received from the user HAL layer.
  129370. +**
  129371. +** INPUT:
  129372. +**
  129373. +** gckKERNEL Kernel
  129374. +** Pointer to an gckKERNEL object.
  129375. +**
  129376. +** gcsHAL_INTERFACE * Interface
  129377. +** Pointer to a gcsHAL_INTERFACE structure that defines the command to
  129378. +** be dispatched.
  129379. +**
  129380. +** OUTPUT:
  129381. +**
  129382. +** gcsHAL_INTERFACE * Interface
  129383. +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
  129384. +** returned.
  129385. +*/
  129386. +gceSTATUS gckVGKERNEL_Dispatch(
  129387. + IN gckKERNEL Kernel,
  129388. + IN gctBOOL FromUser,
  129389. + IN OUT gcsHAL_INTERFACE * Interface
  129390. + )
  129391. +{
  129392. + gceSTATUS status;
  129393. + gcsHAL_INTERFACE * kernelInterface = Interface;
  129394. + gcuVIDMEM_NODE_PTR node;
  129395. + gctUINT32 processID;
  129396. + gckKERNEL kernel = Kernel;
  129397. + gctPOINTER info = gcvNULL;
  129398. + gctPHYS_ADDR physical = gcvNULL;
  129399. + gctPOINTER logical = gcvNULL;
  129400. + gctSIZE_T bytes = 0;
  129401. +
  129402. + gcmkHEADER_ARG("Kernel=0x%x Interface=0x%x ", Kernel, Interface);
  129403. +
  129404. + /* Verify the arguments. */
  129405. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  129406. + gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
  129407. +
  129408. + gcmkONERROR(gckOS_GetProcessID(&processID));
  129409. +
  129410. + /* Dispatch on command. */
  129411. + switch (Interface->command)
  129412. + {
  129413. + case gcvHAL_QUERY_VIDEO_MEMORY:
  129414. + /* Query video memory size. */
  129415. + gcmkERR_BREAK(gckKERNEL_QueryVideoMemory(
  129416. + Kernel, kernelInterface
  129417. + ));
  129418. + break;
  129419. +
  129420. + case gcvHAL_QUERY_CHIP_IDENTITY:
  129421. + /* Query chip identity. */
  129422. + gcmkERR_BREAK(gckVGHARDWARE_QueryChipIdentity(
  129423. + Kernel->vg->hardware,
  129424. + &kernelInterface->u.QueryChipIdentity.chipModel,
  129425. + &kernelInterface->u.QueryChipIdentity.chipRevision,
  129426. + &kernelInterface->u.QueryChipIdentity.chipFeatures,
  129427. + &kernelInterface->u.QueryChipIdentity.chipMinorFeatures,
  129428. + &kernelInterface->u.QueryChipIdentity.chipMinorFeatures2
  129429. + ));
  129430. + break;
  129431. +
  129432. + case gcvHAL_QUERY_COMMAND_BUFFER:
  129433. + /* Query command buffer information. */
  129434. + gcmkERR_BREAK(gckKERNEL_QueryCommandBuffer(
  129435. + Kernel,
  129436. + &kernelInterface->u.QueryCommandBuffer.information
  129437. + ));
  129438. + break;
  129439. + case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
  129440. + bytes = (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes;
  129441. + /* Allocate non-paged memory. */
  129442. + gcmkERR_BREAK(gckOS_AllocateContiguous(
  129443. + Kernel->os,
  129444. + gcvTRUE,
  129445. + &bytes,
  129446. + &physical,
  129447. + &logical
  129448. + ));
  129449. +
  129450. + kernelInterface->u.AllocateNonPagedMemory.bytes = bytes;
  129451. + kernelInterface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
  129452. + kernelInterface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
  129453. + break;
  129454. +
  129455. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  129456. + physical = gcmNAME_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.physical);
  129457. +
  129458. + /* Unmap user logical out of physical memory first. */
  129459. + gcmkERR_BREAK(gckOS_UnmapUserLogical(
  129460. + Kernel->os,
  129461. + physical,
  129462. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes,
  129463. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical)
  129464. + ));
  129465. +
  129466. + /* Free non-paged memory. */
  129467. + gcmkERR_BREAK(gckOS_FreeNonPagedMemory(
  129468. + Kernel->os,
  129469. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes,
  129470. + physical,
  129471. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical)
  129472. + ));
  129473. +
  129474. + gcmRELEASE_NAME(kernelInterface->u.AllocateNonPagedMemory.physical);
  129475. + break;
  129476. +
  129477. + case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
  129478. + bytes = (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes;
  129479. + /* Allocate contiguous memory. */
  129480. + gcmkERR_BREAK(gckOS_AllocateContiguous(
  129481. + Kernel->os,
  129482. + gcvTRUE,
  129483. + &bytes,
  129484. + &physical,
  129485. + &logical
  129486. + ));
  129487. +
  129488. + kernelInterface->u.AllocateNonPagedMemory.bytes = bytes;
  129489. + kernelInterface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
  129490. + kernelInterface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
  129491. + break;
  129492. +
  129493. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  129494. + physical = gcmNAME_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.physical);
  129495. + /* Unmap user logical out of physical memory first. */
  129496. + gcmkERR_BREAK(gckOS_UnmapUserLogical(
  129497. + Kernel->os,
  129498. + physical,
  129499. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes,
  129500. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical)
  129501. + ));
  129502. +
  129503. + /* Free contiguous memory. */
  129504. + gcmkERR_BREAK(gckOS_FreeContiguous(
  129505. + Kernel->os,
  129506. + physical,
  129507. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical),
  129508. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes
  129509. + ));
  129510. +
  129511. + gcmRELEASE_NAME(kernelInterface->u.AllocateNonPagedMemory.physical);
  129512. + break;
  129513. +
  129514. + case gcvHAL_ALLOCATE_VIDEO_MEMORY:
  129515. + {
  129516. + gctSIZE_T bytes;
  129517. + gctUINT32 bitsPerPixel;
  129518. + gctUINT32 bits;
  129519. +
  129520. + /* Align width and height to tiles. */
  129521. + gcmkERR_BREAK(gckVGHARDWARE_AlignToTile(
  129522. + Kernel->vg->hardware,
  129523. + kernelInterface->u.AllocateVideoMemory.type,
  129524. + &kernelInterface->u.AllocateVideoMemory.width,
  129525. + &kernelInterface->u.AllocateVideoMemory.height
  129526. + ));
  129527. +
  129528. + /* Convert format into bytes per pixel and bytes per tile. */
  129529. + gcmkERR_BREAK(gckVGHARDWARE_ConvertFormat(
  129530. + Kernel->vg->hardware,
  129531. + kernelInterface->u.AllocateVideoMemory.format,
  129532. + &bitsPerPixel,
  129533. + gcvNULL
  129534. + ));
  129535. +
  129536. + /* Compute number of bits for the allocation. */
  129537. + bits
  129538. + = kernelInterface->u.AllocateVideoMemory.width
  129539. + * kernelInterface->u.AllocateVideoMemory.height
  129540. + * kernelInterface->u.AllocateVideoMemory.depth
  129541. + * bitsPerPixel;
  129542. +
  129543. + /* Compute number of bytes for the allocation. */
  129544. + bytes = gcmALIGN(bits, 8) / 8;
  129545. +
  129546. + /* Allocate memory. */
  129547. + gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
  129548. + Kernel,
  129549. + &kernelInterface->u.AllocateVideoMemory.pool,
  129550. + bytes,
  129551. + 64,
  129552. + kernelInterface->u.AllocateVideoMemory.type,
  129553. + &node
  129554. + ));
  129555. +
  129556. + kernelInterface->u.AllocateVideoMemory.node = gcmPTR_TO_UINT64(node);
  129557. + }
  129558. + break;
  129559. +
  129560. + case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
  129561. + /* Allocate memory. */
  129562. + gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
  129563. + Kernel,
  129564. + &kernelInterface->u.AllocateLinearVideoMemory.pool,
  129565. + kernelInterface->u.AllocateLinearVideoMemory.bytes,
  129566. + kernelInterface->u.AllocateLinearVideoMemory.alignment,
  129567. + kernelInterface->u.AllocateLinearVideoMemory.type,
  129568. + &node
  129569. + ));
  129570. +
  129571. + gcmkERR_BREAK(gckKERNEL_AddProcessDB(Kernel,
  129572. + processID, gcvDB_VIDEO_MEMORY,
  129573. + node,
  129574. + gcvNULL,
  129575. + kernelInterface->u.AllocateLinearVideoMemory.bytes
  129576. + ));
  129577. +
  129578. + kernelInterface->u.AllocateLinearVideoMemory.node = gcmPTR_TO_UINT64(node);
  129579. + break;
  129580. +
  129581. + case gcvHAL_FREE_VIDEO_MEMORY:
  129582. + node = gcmUINT64_TO_PTR(Interface->u.FreeVideoMemory.node);
  129583. +#ifdef __QNXNTO__
  129584. + /* Unmap the video memory */
  129585. +
  129586. + if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM) &&
  129587. + (node->VidMem.logical != gcvNULL))
  129588. + {
  129589. + gckKERNEL_UnmapVideoMemory(Kernel,
  129590. + node->VidMem.logical,
  129591. + processID,
  129592. + node->VidMem.bytes);
  129593. + node->VidMem.logical = gcvNULL;
  129594. + }
  129595. +#endif /* __QNXNTO__ */
  129596. +
  129597. + /* Free video memory. */
  129598. + gcmkERR_BREAK(gckVIDMEM_Free(
  129599. + node
  129600. + ));
  129601. +
  129602. + gcmkERR_BREAK(gckKERNEL_RemoveProcessDB(
  129603. + Kernel,
  129604. + processID, gcvDB_VIDEO_MEMORY,
  129605. + node
  129606. + ));
  129607. +
  129608. + break;
  129609. +
  129610. + case gcvHAL_MAP_MEMORY:
  129611. + /* Map memory. */
  129612. + gcmkERR_BREAK(gckKERNEL_MapMemory(
  129613. + Kernel,
  129614. + gcmINT2PTR(kernelInterface->u.MapMemory.physical),
  129615. + (gctSIZE_T) kernelInterface->u.MapMemory.bytes,
  129616. + &logical
  129617. + ));
  129618. + kernelInterface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
  129619. + break;
  129620. +
  129621. + case gcvHAL_UNMAP_MEMORY:
  129622. + /* Unmap memory. */
  129623. + gcmkERR_BREAK(gckKERNEL_UnmapMemory(
  129624. + Kernel,
  129625. + gcmINT2PTR(kernelInterface->u.MapMemory.physical),
  129626. + (gctSIZE_T) kernelInterface->u.MapMemory.bytes,
  129627. + gcmUINT64_TO_PTR(kernelInterface->u.MapMemory.logical)
  129628. + ));
  129629. + break;
  129630. +
  129631. + case gcvHAL_MAP_USER_MEMORY:
  129632. + /* Map user memory to DMA. */
  129633. + gcmkERR_BREAK(gckOS_MapUserMemory(
  129634. + Kernel->os,
  129635. + gcvCORE_VG,
  129636. + gcmUINT64_TO_PTR(kernelInterface->u.MapUserMemory.memory),
  129637. + kernelInterface->u.MapUserMemory.physical,
  129638. + (gctSIZE_T) kernelInterface->u.MapUserMemory.size,
  129639. + &info,
  129640. + &kernelInterface->u.MapUserMemory.address
  129641. + ));
  129642. +
  129643. + kernelInterface->u.MapUserMemory.info = gcmPTR_TO_NAME(info);
  129644. + break;
  129645. +
  129646. + case gcvHAL_UNMAP_USER_MEMORY:
  129647. + /* Unmap user memory. */
  129648. + gcmkERR_BREAK(gckOS_UnmapUserMemory(
  129649. + Kernel->os,
  129650. + gcvCORE_VG,
  129651. + gcmUINT64_TO_PTR(kernelInterface->u.UnmapUserMemory.memory),
  129652. + (gctSIZE_T) kernelInterface->u.UnmapUserMemory.size,
  129653. + gcmNAME_TO_PTR(kernelInterface->u.UnmapUserMemory.info),
  129654. + kernelInterface->u.UnmapUserMemory.address
  129655. + ));
  129656. + gcmRELEASE_NAME(kernelInterface->u.UnmapUserMemory.info);
  129657. + break;
  129658. + case gcvHAL_LOCK_VIDEO_MEMORY:
  129659. + node = gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node);
  129660. +
  129661. + /* Lock video memory. */
  129662. + gcmkERR_BREAK(
  129663. + gckVIDMEM_Lock(Kernel,
  129664. + node,
  129665. + gcvFALSE,
  129666. + &Interface->u.LockVideoMemory.address));
  129667. +
  129668. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  129669. + {
  129670. + /* Map video memory address into user space. */
  129671. +#ifdef __QNXNTO__
  129672. + if (node->VidMem.logical == gcvNULL)
  129673. + {
  129674. + gcmkONERROR(
  129675. + gckKERNEL_MapVideoMemory(Kernel,
  129676. + FromUser,
  129677. + Interface->u.LockVideoMemory.address,
  129678. + processID,
  129679. + node->VidMem.bytes,
  129680. + &node->VidMem.logical));
  129681. + }
  129682. +
  129683. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical);
  129684. +#else
  129685. + gcmkERR_BREAK(
  129686. + gckKERNEL_MapVideoMemoryEx(Kernel,
  129687. + gcvCORE_VG,
  129688. + FromUser,
  129689. + Interface->u.LockVideoMemory.address,
  129690. + &logical));
  129691. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical);
  129692. +#endif
  129693. + }
  129694. + else
  129695. + {
  129696. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical);
  129697. +
  129698. + /* Success. */
  129699. + status = gcvSTATUS_OK;
  129700. + }
  129701. +
  129702. +#if gcdSECURE_USER
  129703. + /* Return logical address as physical address. */
  129704. + Interface->u.LockVideoMemory.address =
  129705. + (gctUINT32)(Interface->u.LockVideoMemory.memory);
  129706. +#endif
  129707. + gcmkERR_BREAK(
  129708. + gckKERNEL_AddProcessDB(Kernel,
  129709. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  129710. + node,
  129711. + gcvNULL,
  129712. + 0));
  129713. + break;
  129714. +
  129715. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  129716. + /* Unlock video memory. */
  129717. + node = gcmUINT64_TO_PTR(Interface->u.UnlockVideoMemory.node);
  129718. +
  129719. +#if gcdSECURE_USER
  129720. + /* Save node information before it disappears. */
  129721. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  129722. + {
  129723. + logical = gcvNULL;
  129724. + bytes = 0;
  129725. + }
  129726. + else
  129727. + {
  129728. + logical = node->Virtual.logical;
  129729. + bytes = node->Virtual.bytes;
  129730. + }
  129731. +#endif
  129732. +
  129733. + /* Unlock video memory. */
  129734. + gcmkERR_BREAK(
  129735. + gckVIDMEM_Unlock(Kernel,
  129736. + node,
  129737. + Interface->u.UnlockVideoMemory.type,
  129738. + &Interface->u.UnlockVideoMemory.asynchroneous));
  129739. +
  129740. +#if gcdSECURE_USER
  129741. + /* Flush the translation cache for virtual surfaces. */
  129742. + if (logical != gcvNULL)
  129743. + {
  129744. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel,
  129745. + cache,
  129746. + logical,
  129747. + bytes));
  129748. + }
  129749. +#endif
  129750. +
  129751. + if (Interface->u.UnlockVideoMemory.asynchroneous == gcvFALSE)
  129752. + {
  129753. + /* There isn't a event to unlock this node, remove record now */
  129754. + gcmkERR_BREAK(
  129755. + gckKERNEL_RemoveProcessDB(Kernel,
  129756. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  129757. + node));
  129758. + }
  129759. +
  129760. + break;
  129761. + case gcvHAL_USER_SIGNAL:
  129762. +#if !USE_NEW_LINUX_SIGNAL
  129763. + /* Dispatch depends on the user signal subcommands. */
  129764. + switch(Interface->u.UserSignal.command)
  129765. + {
  129766. + case gcvUSER_SIGNAL_CREATE:
  129767. + /* Create a signal used in the user space. */
  129768. + gcmkERR_BREAK(
  129769. + gckOS_CreateUserSignal(Kernel->os,
  129770. + Interface->u.UserSignal.manualReset,
  129771. + &Interface->u.UserSignal.id));
  129772. +
  129773. + gcmkVERIFY_OK(
  129774. + gckKERNEL_AddProcessDB(Kernel,
  129775. + processID, gcvDB_SIGNAL,
  129776. + gcmINT2PTR(Interface->u.UserSignal.id),
  129777. + gcvNULL,
  129778. + 0));
  129779. + break;
  129780. +
  129781. + case gcvUSER_SIGNAL_DESTROY:
  129782. + /* Destroy the signal. */
  129783. + gcmkERR_BREAK(
  129784. + gckOS_DestroyUserSignal(Kernel->os,
  129785. + Interface->u.UserSignal.id));
  129786. +
  129787. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  129788. + Kernel,
  129789. + processID, gcvDB_SIGNAL,
  129790. + gcmINT2PTR(Interface->u.UserSignal.id)));
  129791. + break;
  129792. +
  129793. + case gcvUSER_SIGNAL_SIGNAL:
  129794. + /* Signal the signal. */
  129795. + gcmkERR_BREAK(
  129796. + gckOS_SignalUserSignal(Kernel->os,
  129797. + Interface->u.UserSignal.id,
  129798. + Interface->u.UserSignal.state));
  129799. + break;
  129800. +
  129801. + case gcvUSER_SIGNAL_WAIT:
  129802. + /* Wait on the signal. */
  129803. + status = gckOS_WaitUserSignal(Kernel->os,
  129804. + Interface->u.UserSignal.id,
  129805. + Interface->u.UserSignal.wait);
  129806. + break;
  129807. +
  129808. + default:
  129809. + /* Invalid user signal command. */
  129810. + gcmkERR_BREAK(gcvSTATUS_INVALID_ARGUMENT);
  129811. + }
  129812. +#endif
  129813. + break;
  129814. +
  129815. + case gcvHAL_COMMIT:
  129816. + /* Commit a command and context buffer. */
  129817. + gcmkERR_BREAK(gckVGCOMMAND_Commit(
  129818. + Kernel->vg->command,
  129819. + gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.context),
  129820. + gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.queue),
  129821. + kernelInterface->u.VGCommit.entryCount,
  129822. + gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.taskTable)
  129823. + ));
  129824. + break;
  129825. + case gcvHAL_VERSION:
  129826. + kernelInterface->u.Version.major = gcvVERSION_MAJOR;
  129827. + kernelInterface->u.Version.minor = gcvVERSION_MINOR;
  129828. + kernelInterface->u.Version.patch = gcvVERSION_PATCH;
  129829. + kernelInterface->u.Version.build = gcvVERSION_BUILD;
  129830. + status = gcvSTATUS_OK;
  129831. + break;
  129832. +
  129833. + case gcvHAL_GET_BASE_ADDRESS:
  129834. + /* Get base address. */
  129835. + gcmkERR_BREAK(
  129836. + gckOS_GetBaseAddress(Kernel->os,
  129837. + &kernelInterface->u.GetBaseAddress.baseAddress));
  129838. + break;
  129839. + default:
  129840. + /* Invalid command. */
  129841. + status = gcvSTATUS_INVALID_ARGUMENT;
  129842. + }
  129843. +
  129844. +OnError:
  129845. + /* Save status. */
  129846. + kernelInterface->status = status;
  129847. +
  129848. + gcmkFOOTER();
  129849. +
  129850. + /* Return the status. */
  129851. + return status;
  129852. +}
  129853. +
  129854. +/*******************************************************************************
  129855. +**
  129856. +** gckKERNEL_QueryCommandBuffer
  129857. +**
  129858. +** Query command buffer attributes.
  129859. +**
  129860. +** INPUT:
  129861. +**
  129862. +** gckKERNEL Kernel
  129863. +** Pointer to an gckVGHARDWARE object.
  129864. +**
  129865. +** OUTPUT:
  129866. +**
  129867. +** gcsCOMMAND_BUFFER_INFO_PTR Information
  129868. +** Pointer to the information structure to receive buffer attributes.
  129869. +*/
  129870. +gceSTATUS
  129871. +gckKERNEL_QueryCommandBuffer(
  129872. + IN gckKERNEL Kernel,
  129873. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  129874. + )
  129875. +{
  129876. + gceSTATUS status;
  129877. +
  129878. + gcmkHEADER_ARG("Kernel=0x%x *Pool=0x%x",
  129879. + Kernel, Information);
  129880. + /* Verify the arguments. */
  129881. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  129882. +
  129883. + /* Get the information. */
  129884. + status = gckVGCOMMAND_QueryCommandBuffer(Kernel->vg->command, Information);
  129885. +
  129886. + gcmkFOOTER();
  129887. + /* Return status. */
  129888. + return status;
  129889. +}
  129890. +
  129891. +#endif /* gcdENABLE_VG */
  129892. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h
  129893. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h 1969-12-31 18:00:00.000000000 -0600
  129894. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h 2014-12-08 00:31:53.468418001 -0600
  129895. @@ -0,0 +1,85 @@
  129896. +/****************************************************************************
  129897. +*
  129898. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  129899. +*
  129900. +* This program is free software; you can redistribute it and/or modify
  129901. +* it under the terms of the GNU General Public License as published by
  129902. +* the Free Software Foundation; either version 2 of the license, or
  129903. +* (at your option) any later version.
  129904. +*
  129905. +* This program is distributed in the hope that it will be useful,
  129906. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  129907. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  129908. +* GNU General Public License for more details.
  129909. +*
  129910. +* You should have received a copy of the GNU General Public License
  129911. +* along with this program; if not write to the Free Software
  129912. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  129913. +*
  129914. +*****************************************************************************/
  129915. +
  129916. +
  129917. +#ifndef __gc_hal_kernel_vg_h_
  129918. +#define __gc_hal_kernel_vg_h_
  129919. +
  129920. +#include "gc_hal.h"
  129921. +#include "gc_hal_driver.h"
  129922. +#include "gc_hal_kernel_hardware.h"
  129923. +
  129924. +/******************************************************************************\
  129925. +********************************** Structures **********************************
  129926. +\******************************************************************************/
  129927. +
  129928. +/* gckKERNEL object. */
  129929. +struct _gckVGKERNEL
  129930. +{
  129931. + /* Object. */
  129932. + gcsOBJECT object;
  129933. +
  129934. + /* Pointer to gckOS object. */
  129935. + gckOS os;
  129936. +
  129937. + /* Pointer to gckHARDWARE object. */
  129938. + gckVGHARDWARE hardware;
  129939. +
  129940. + /* Pointer to gckINTERRUPT object. */
  129941. + gckVGINTERRUPT interrupt;
  129942. +
  129943. + /* Pointer to gckCOMMAND object. */
  129944. + gckVGCOMMAND command;
  129945. +
  129946. + /* Pointer to context. */
  129947. + gctPOINTER context;
  129948. +
  129949. + /* Pointer to gckMMU object. */
  129950. + gckVGMMU mmu;
  129951. +
  129952. + gckKERNEL kernel;
  129953. +};
  129954. +
  129955. +/* gckMMU object. */
  129956. +struct _gckVGMMU
  129957. +{
  129958. + /* The object. */
  129959. + gcsOBJECT object;
  129960. +
  129961. + /* Pointer to gckOS object. */
  129962. + gckOS os;
  129963. +
  129964. + /* Pointer to gckHARDWARE object. */
  129965. + gckVGHARDWARE hardware;
  129966. +
  129967. + /* The page table mutex. */
  129968. + gctPOINTER mutex;
  129969. +
  129970. + /* Page table information. */
  129971. + gctSIZE_T pageTableSize;
  129972. + gctPHYS_ADDR pageTablePhysical;
  129973. + gctPOINTER pageTableLogical;
  129974. +
  129975. + /* Allocation index. */
  129976. + gctUINT32 entryCount;
  129977. + gctUINT32 entry;
  129978. +};
  129979. +
  129980. +#endif /* __gc_hal_kernel_h_ */
  129981. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
  129982. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c 1969-12-31 18:00:00.000000000 -0600
  129983. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c 2014-12-08 00:31:53.468418001 -0600
  129984. @@ -0,0 +1,2264 @@
  129985. +/****************************************************************************
  129986. +*
  129987. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  129988. +*
  129989. +* This program is free software; you can redistribute it and/or modify
  129990. +* it under the terms of the GNU General Public License as published by
  129991. +* the Free Software Foundation; either version 2 of the license, or
  129992. +* (at your option) any later version.
  129993. +*
  129994. +* This program is distributed in the hope that it will be useful,
  129995. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  129996. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  129997. +* GNU General Public License for more details.
  129998. +*
  129999. +* You should have received a copy of the GNU General Public License
  130000. +* along with this program; if not write to the Free Software
  130001. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  130002. +*
  130003. +*****************************************************************************/
  130004. +
  130005. +
  130006. +#include "gc_hal_kernel_precomp.h"
  130007. +
  130008. +#define _GC_OBJ_ZONE gcvZONE_VIDMEM
  130009. +
  130010. +/******************************************************************************\
  130011. +******************************* Private Functions ******************************
  130012. +\******************************************************************************/
  130013. +
  130014. +/*******************************************************************************
  130015. +**
  130016. +** _Split
  130017. +**
  130018. +** Split a node on the required byte boundary.
  130019. +**
  130020. +** INPUT:
  130021. +**
  130022. +** gckOS Os
  130023. +** Pointer to an gckOS object.
  130024. +**
  130025. +** gcuVIDMEM_NODE_PTR Node
  130026. +** Pointer to the node to split.
  130027. +**
  130028. +** gctSIZE_T Bytes
  130029. +** Number of bytes to keep in the node.
  130030. +**
  130031. +** OUTPUT:
  130032. +**
  130033. +** Nothing.
  130034. +**
  130035. +** RETURNS:
  130036. +**
  130037. +** gctBOOL
  130038. +** gcvTRUE if the node was split successfully, or gcvFALSE if there is an
  130039. +** error.
  130040. +**
  130041. +*/
  130042. +static gctBOOL
  130043. +_Split(
  130044. + IN gckOS Os,
  130045. + IN gcuVIDMEM_NODE_PTR Node,
  130046. + IN gctSIZE_T Bytes
  130047. + )
  130048. +{
  130049. + gcuVIDMEM_NODE_PTR node;
  130050. + gctPOINTER pointer = gcvNULL;
  130051. +
  130052. + /* Make sure the byte boundary makes sense. */
  130053. + if ((Bytes <= 0) || (Bytes > Node->VidMem.bytes))
  130054. + {
  130055. + return gcvFALSE;
  130056. + }
  130057. +
  130058. + /* Allocate a new gcuVIDMEM_NODE object. */
  130059. + if (gcmIS_ERROR(gckOS_Allocate(Os,
  130060. + gcmSIZEOF(gcuVIDMEM_NODE),
  130061. + &pointer)))
  130062. + {
  130063. + /* Error. */
  130064. + return gcvFALSE;
  130065. + }
  130066. +
  130067. + node = pointer;
  130068. +
  130069. + /* Initialize gcuVIDMEM_NODE structure. */
  130070. + node->VidMem.offset = Node->VidMem.offset + Bytes;
  130071. + node->VidMem.bytes = Node->VidMem.bytes - Bytes;
  130072. + node->VidMem.alignment = 0;
  130073. + node->VidMem.locked = 0;
  130074. + node->VidMem.memory = Node->VidMem.memory;
  130075. + node->VidMem.pool = Node->VidMem.pool;
  130076. + node->VidMem.physical = Node->VidMem.physical;
  130077. +#ifdef __QNXNTO__
  130078. +#if gcdUSE_VIDMEM_PER_PID
  130079. + gcmkASSERT(Node->VidMem.physical != 0);
  130080. + gcmkASSERT(Node->VidMem.logical != gcvNULL);
  130081. + node->VidMem.processID = Node->VidMem.processID;
  130082. + node->VidMem.physical = Node->VidMem.physical + Bytes;
  130083. + node->VidMem.logical = Node->VidMem.logical + Bytes;
  130084. +#else
  130085. + node->VidMem.processID = 0;
  130086. + node->VidMem.logical = gcvNULL;
  130087. +#endif
  130088. +#endif
  130089. +
  130090. + /* Insert node behind specified node. */
  130091. + node->VidMem.next = Node->VidMem.next;
  130092. + node->VidMem.prev = Node;
  130093. + Node->VidMem.next = node->VidMem.next->VidMem.prev = node;
  130094. +
  130095. + /* Insert free node behind specified node. */
  130096. + node->VidMem.nextFree = Node->VidMem.nextFree;
  130097. + node->VidMem.prevFree = Node;
  130098. + Node->VidMem.nextFree = node->VidMem.nextFree->VidMem.prevFree = node;
  130099. +
  130100. + /* Adjust size of specified node. */
  130101. + Node->VidMem.bytes = Bytes;
  130102. +
  130103. + /* Success. */
  130104. + return gcvTRUE;
  130105. +}
  130106. +
  130107. +/*******************************************************************************
  130108. +**
  130109. +** _Merge
  130110. +**
  130111. +** Merge two adjacent nodes together.
  130112. +**
  130113. +** INPUT:
  130114. +**
  130115. +** gckOS Os
  130116. +** Pointer to an gckOS object.
  130117. +**
  130118. +** gcuVIDMEM_NODE_PTR Node
  130119. +** Pointer to the first of the two nodes to merge.
  130120. +**
  130121. +** OUTPUT:
  130122. +**
  130123. +** Nothing.
  130124. +**
  130125. +*/
  130126. +static gceSTATUS
  130127. +_Merge(
  130128. + IN gckOS Os,
  130129. + IN gcuVIDMEM_NODE_PTR Node
  130130. + )
  130131. +{
  130132. + gcuVIDMEM_NODE_PTR node;
  130133. + gceSTATUS status;
  130134. +
  130135. + /* Save pointer to next node. */
  130136. + node = Node->VidMem.next;
  130137. +#if gcdUSE_VIDMEM_PER_PID
  130138. + /* Check if the nodes are adjacent physically. */
  130139. + if ( ((Node->VidMem.physical + Node->VidMem.bytes) != node->VidMem.physical) ||
  130140. + ((Node->VidMem.logical + Node->VidMem.bytes) != node->VidMem.logical) )
  130141. + {
  130142. + /* Can't merge. */
  130143. + return gcvSTATUS_OK;
  130144. + }
  130145. +#else
  130146. +
  130147. + /* This is a good time to make sure the heap is not corrupted. */
  130148. + if (Node->VidMem.offset + Node->VidMem.bytes != node->VidMem.offset)
  130149. + {
  130150. + /* Corrupted heap. */
  130151. + gcmkASSERT(
  130152. + Node->VidMem.offset + Node->VidMem.bytes == node->VidMem.offset);
  130153. + return gcvSTATUS_HEAP_CORRUPTED;
  130154. + }
  130155. +#endif
  130156. +
  130157. + /* Adjust byte count. */
  130158. + Node->VidMem.bytes += node->VidMem.bytes;
  130159. +
  130160. + /* Unlink next node from linked list. */
  130161. + Node->VidMem.next = node->VidMem.next;
  130162. + Node->VidMem.nextFree = node->VidMem.nextFree;
  130163. +
  130164. + Node->VidMem.next->VidMem.prev =
  130165. + Node->VidMem.nextFree->VidMem.prevFree = Node;
  130166. +
  130167. + /* Free next node. */
  130168. + status = gcmkOS_SAFE_FREE(Os, node);
  130169. + return status;
  130170. +}
  130171. +
  130172. +/******************************************************************************\
  130173. +******************************* gckVIDMEM API Code ******************************
  130174. +\******************************************************************************/
  130175. +
  130176. +/*******************************************************************************
  130177. +**
  130178. +** gckVIDMEM_ConstructVirtual
  130179. +**
  130180. +** Construct a new gcuVIDMEM_NODE union for virtual memory.
  130181. +**
  130182. +** INPUT:
  130183. +**
  130184. +** gckKERNEL Kernel
  130185. +** Pointer to an gckKERNEL object.
  130186. +**
  130187. +** gctSIZE_T Bytes
  130188. +** Number of byte to allocate.
  130189. +**
  130190. +** OUTPUT:
  130191. +**
  130192. +** gcuVIDMEM_NODE_PTR * Node
  130193. +** Pointer to a variable that receives the gcuVIDMEM_NODE union pointer.
  130194. +*/
  130195. +gceSTATUS
  130196. +gckVIDMEM_ConstructVirtual(
  130197. + IN gckKERNEL Kernel,
  130198. + IN gctBOOL Contiguous,
  130199. + IN gctSIZE_T Bytes,
  130200. + OUT gcuVIDMEM_NODE_PTR * Node
  130201. + )
  130202. +{
  130203. + gckOS os;
  130204. + gceSTATUS status;
  130205. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  130206. + gctPOINTER pointer = gcvNULL;
  130207. + gctINT i;
  130208. +
  130209. + gcmkHEADER_ARG("Kernel=0x%x Contiguous=%d Bytes=%lu", Kernel, Contiguous, Bytes);
  130210. +
  130211. + /* Verify the arguments. */
  130212. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  130213. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  130214. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  130215. +
  130216. + /* Extract the gckOS object pointer. */
  130217. + os = Kernel->os;
  130218. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  130219. +
  130220. + /* Allocate an gcuVIDMEM_NODE union. */
  130221. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
  130222. +
  130223. + node = pointer;
  130224. +
  130225. + /* Initialize gcuVIDMEM_NODE union for virtual memory. */
  130226. + node->Virtual.kernel = Kernel;
  130227. + node->Virtual.contiguous = Contiguous;
  130228. + node->Virtual.logical = gcvNULL;
  130229. +
  130230. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  130231. + {
  130232. + node->Virtual.lockeds[i] = 0;
  130233. + node->Virtual.pageTables[i] = gcvNULL;
  130234. + node->Virtual.lockKernels[i] = gcvNULL;
  130235. + }
  130236. +
  130237. + node->Virtual.mutex = gcvNULL;
  130238. +
  130239. + gcmkONERROR(gckOS_GetProcessID(&node->Virtual.processID));
  130240. +
  130241. +#ifdef __QNXNTO__
  130242. + node->Virtual.next = gcvNULL;
  130243. + node->Virtual.freePending = gcvFALSE;
  130244. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  130245. + {
  130246. + node->Virtual.unlockPendings[i] = gcvFALSE;
  130247. + }
  130248. +#endif
  130249. +
  130250. + node->Virtual.freed = gcvFALSE;
  130251. +
  130252. + gcmkONERROR(gckOS_ZeroMemory(&node->Virtual.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)));
  130253. +
  130254. + /* Create the mutex. */
  130255. + gcmkONERROR(
  130256. + gckOS_CreateMutex(os, &node->Virtual.mutex));
  130257. +
  130258. + /* Allocate the virtual memory. */
  130259. + gcmkONERROR(
  130260. + gckOS_AllocatePagedMemoryEx(os,
  130261. + node->Virtual.contiguous,
  130262. + node->Virtual.bytes = Bytes,
  130263. + &node->Virtual.physical));
  130264. +
  130265. +#ifdef __QNXNTO__
  130266. + /* Register. */
  130267. +#if gcdENABLE_VG
  130268. + if (Kernel->core != gcvCORE_VG)
  130269. +#endif
  130270. + {
  130271. + gckMMU_InsertNode(Kernel->mmu, node);
  130272. + }
  130273. +#endif
  130274. +
  130275. + /* Return pointer to the gcuVIDMEM_NODE union. */
  130276. + *Node = node;
  130277. +
  130278. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130279. + "Created virtual node 0x%x for %u bytes @ 0x%x",
  130280. + node, Bytes, node->Virtual.physical);
  130281. +
  130282. + /* Success. */
  130283. + gcmkFOOTER_ARG("*Node=0x%x", *Node);
  130284. + return gcvSTATUS_OK;
  130285. +
  130286. +OnError:
  130287. + /* Roll back. */
  130288. + if (node != gcvNULL)
  130289. + {
  130290. + if (node->Virtual.mutex != gcvNULL)
  130291. + {
  130292. + /* Destroy the mutex. */
  130293. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->Virtual.mutex));
  130294. + }
  130295. +
  130296. + /* Free the structure. */
  130297. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
  130298. + }
  130299. +
  130300. + /* Return the status. */
  130301. + gcmkFOOTER();
  130302. + return status;
  130303. +}
  130304. +
  130305. +/*******************************************************************************
  130306. +**
  130307. +** gckVIDMEM_DestroyVirtual
  130308. +**
  130309. +** Destroy an gcuVIDMEM_NODE union for virtual memory.
  130310. +**
  130311. +** INPUT:
  130312. +**
  130313. +** gcuVIDMEM_NODE_PTR Node
  130314. +** Pointer to a gcuVIDMEM_NODE union.
  130315. +**
  130316. +** OUTPUT:
  130317. +**
  130318. +** Nothing.
  130319. +*/
  130320. +gceSTATUS
  130321. +gckVIDMEM_DestroyVirtual(
  130322. + IN gcuVIDMEM_NODE_PTR Node
  130323. + )
  130324. +{
  130325. + gckOS os;
  130326. + gctINT i;
  130327. +
  130328. + gcmkHEADER_ARG("Node=0x%x", Node);
  130329. +
  130330. + /* Verify the arguments. */
  130331. + gcmkVERIFY_OBJECT(Node->Virtual.kernel, gcvOBJ_KERNEL);
  130332. +
  130333. + /* Extact the gckOS object pointer. */
  130334. + os = Node->Virtual.kernel->os;
  130335. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  130336. +
  130337. +#ifdef __QNXNTO__
  130338. + /* Unregister. */
  130339. +#if gcdENABLE_VG
  130340. + if (Node->Virtual.kernel->core != gcvCORE_VG)
  130341. +#endif
  130342. + {
  130343. + gcmkVERIFY_OK(
  130344. + gckMMU_RemoveNode(Node->Virtual.kernel->mmu, Node));
  130345. + }
  130346. +#endif
  130347. +
  130348. + /* Delete the mutex. */
  130349. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, Node->Virtual.mutex));
  130350. +
  130351. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  130352. + {
  130353. + if (Node->Virtual.pageTables[i] != gcvNULL)
  130354. + {
  130355. +#if gcdENABLE_VG
  130356. + if (i == gcvCORE_VG)
  130357. + {
  130358. + /* Free the pages. */
  130359. + gcmkVERIFY_OK(gckVGMMU_FreePages(Node->Virtual.lockKernels[i]->vg->mmu,
  130360. + Node->Virtual.pageTables[i],
  130361. + Node->Virtual.pageCount));
  130362. + }
  130363. + else
  130364. +#endif
  130365. + {
  130366. + /* Free the pages. */
  130367. + gcmkVERIFY_OK(gckMMU_FreePages(Node->Virtual.lockKernels[i]->mmu,
  130368. + Node->Virtual.pageTables[i],
  130369. + Node->Virtual.pageCount));
  130370. + }
  130371. + }
  130372. + }
  130373. +
  130374. + /* Delete the gcuVIDMEM_NODE union. */
  130375. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, Node));
  130376. +
  130377. + /* Success. */
  130378. + gcmkFOOTER_NO();
  130379. + return gcvSTATUS_OK;
  130380. +}
  130381. +
  130382. +/*******************************************************************************
  130383. +**
  130384. +** gckVIDMEM_Construct
  130385. +**
  130386. +** Construct a new gckVIDMEM object.
  130387. +**
  130388. +** INPUT:
  130389. +**
  130390. +** gckOS Os
  130391. +** Pointer to an gckOS object.
  130392. +**
  130393. +** gctUINT32 BaseAddress
  130394. +** Base address for the video memory heap.
  130395. +**
  130396. +** gctSIZE_T Bytes
  130397. +** Number of bytes in the video memory heap.
  130398. +**
  130399. +** gctSIZE_T Threshold
  130400. +** Minimum number of bytes beyond am allocation before the node is
  130401. +** split. Can be used as a minimum alignment requirement.
  130402. +**
  130403. +** gctSIZE_T BankSize
  130404. +** Number of bytes per physical memory bank. Used by bank
  130405. +** optimization.
  130406. +**
  130407. +** OUTPUT:
  130408. +**
  130409. +** gckVIDMEM * Memory
  130410. +** Pointer to a variable that will hold the pointer to the gckVIDMEM
  130411. +** object.
  130412. +*/
  130413. +gceSTATUS
  130414. +gckVIDMEM_Construct(
  130415. + IN gckOS Os,
  130416. + IN gctUINT32 BaseAddress,
  130417. + IN gctSIZE_T Bytes,
  130418. + IN gctSIZE_T Threshold,
  130419. + IN gctSIZE_T BankSize,
  130420. + OUT gckVIDMEM * Memory
  130421. + )
  130422. +{
  130423. + gckVIDMEM memory = gcvNULL;
  130424. + gceSTATUS status;
  130425. + gcuVIDMEM_NODE_PTR node;
  130426. + gctINT i, banks = 0;
  130427. + gctPOINTER pointer = gcvNULL;
  130428. +
  130429. + gcmkHEADER_ARG("Os=0x%x BaseAddress=%08x Bytes=%lu Threshold=%lu "
  130430. + "BankSize=%lu",
  130431. + Os, BaseAddress, Bytes, Threshold, BankSize);
  130432. +
  130433. + /* Verify the arguments. */
  130434. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  130435. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  130436. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  130437. +
  130438. + /* Allocate the gckVIDMEM object. */
  130439. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(struct _gckVIDMEM), &pointer));
  130440. +
  130441. + memory = pointer;
  130442. +
  130443. + /* Initialize the gckVIDMEM object. */
  130444. + memory->object.type = gcvOBJ_VIDMEM;
  130445. + memory->os = Os;
  130446. +
  130447. + /* Set video memory heap information. */
  130448. + memory->baseAddress = BaseAddress;
  130449. + memory->bytes = Bytes;
  130450. + memory->freeBytes = Bytes;
  130451. + memory->threshold = Threshold;
  130452. + memory->mutex = gcvNULL;
  130453. +#if gcdUSE_VIDMEM_PER_PID
  130454. + gcmkONERROR(gckOS_GetProcessID(&memory->pid));
  130455. +#endif
  130456. +
  130457. + BaseAddress = 0;
  130458. +
  130459. + /* Walk all possible banks. */
  130460. + for (i = 0; i < gcmCOUNTOF(memory->sentinel); ++i)
  130461. + {
  130462. + gctSIZE_T bytes;
  130463. +
  130464. + if (BankSize == 0)
  130465. + {
  130466. + /* Use all bytes for the first bank. */
  130467. + bytes = Bytes;
  130468. + }
  130469. + else
  130470. + {
  130471. + /* Compute number of bytes for this bank. */
  130472. + bytes = gcmALIGN(BaseAddress + 1, BankSize) - BaseAddress;
  130473. +
  130474. + if (bytes > Bytes)
  130475. + {
  130476. + /* Make sure we don't exceed the total number of bytes. */
  130477. + bytes = Bytes;
  130478. + }
  130479. + }
  130480. +
  130481. + if (bytes == 0)
  130482. + {
  130483. + /* Mark heap is not used. */
  130484. + memory->sentinel[i].VidMem.next =
  130485. + memory->sentinel[i].VidMem.prev =
  130486. + memory->sentinel[i].VidMem.nextFree =
  130487. + memory->sentinel[i].VidMem.prevFree = gcvNULL;
  130488. + continue;
  130489. + }
  130490. +
  130491. + /* Allocate one gcuVIDMEM_NODE union. */
  130492. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
  130493. +
  130494. + node = pointer;
  130495. +
  130496. + /* Initialize gcuVIDMEM_NODE union. */
  130497. + node->VidMem.memory = memory;
  130498. +
  130499. + node->VidMem.next =
  130500. + node->VidMem.prev =
  130501. + node->VidMem.nextFree =
  130502. + node->VidMem.prevFree = &memory->sentinel[i];
  130503. +
  130504. + node->VidMem.offset = BaseAddress;
  130505. + node->VidMem.bytes = bytes;
  130506. + node->VidMem.alignment = 0;
  130507. + node->VidMem.physical = 0;
  130508. + node->VidMem.pool = gcvPOOL_UNKNOWN;
  130509. +
  130510. + node->VidMem.locked = 0;
  130511. +
  130512. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  130513. + node->VidMem.kernelVirtual = gcvNULL;
  130514. +#endif
  130515. +
  130516. + gcmkONERROR(gckOS_ZeroMemory(&node->VidMem.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)));
  130517. +
  130518. +#ifdef __QNXNTO__
  130519. +#if gcdUSE_VIDMEM_PER_PID
  130520. + node->VidMem.processID = memory->pid;
  130521. + node->VidMem.physical = memory->baseAddress + BaseAddress;
  130522. + gcmkONERROR(gckOS_GetLogicalAddressProcess(Os,
  130523. + node->VidMem.processID,
  130524. + node->VidMem.physical,
  130525. + &node->VidMem.logical));
  130526. +#else
  130527. + node->VidMem.processID = 0;
  130528. + node->VidMem.logical = gcvNULL;
  130529. +#endif
  130530. +#endif
  130531. +
  130532. + /* Initialize the linked list of nodes. */
  130533. + memory->sentinel[i].VidMem.next =
  130534. + memory->sentinel[i].VidMem.prev =
  130535. + memory->sentinel[i].VidMem.nextFree =
  130536. + memory->sentinel[i].VidMem.prevFree = node;
  130537. +
  130538. + /* Mark sentinel. */
  130539. + memory->sentinel[i].VidMem.bytes = 0;
  130540. +
  130541. + /* Adjust address for next bank. */
  130542. + BaseAddress += bytes;
  130543. + Bytes -= bytes;
  130544. + banks ++;
  130545. + }
  130546. +
  130547. + /* Assign all the bank mappings. */
  130548. + memory->mapping[gcvSURF_RENDER_TARGET] = banks - 1;
  130549. + memory->mapping[gcvSURF_BITMAP] = banks - 1;
  130550. + if (banks > 1) --banks;
  130551. + memory->mapping[gcvSURF_DEPTH] = banks - 1;
  130552. + memory->mapping[gcvSURF_HIERARCHICAL_DEPTH] = banks - 1;
  130553. + if (banks > 1) --banks;
  130554. + memory->mapping[gcvSURF_TEXTURE] = banks - 1;
  130555. + if (banks > 1) --banks;
  130556. + memory->mapping[gcvSURF_VERTEX] = banks - 1;
  130557. + if (banks > 1) --banks;
  130558. + memory->mapping[gcvSURF_INDEX] = banks - 1;
  130559. + if (banks > 1) --banks;
  130560. + memory->mapping[gcvSURF_TILE_STATUS] = banks - 1;
  130561. + if (banks > 1) --banks;
  130562. + memory->mapping[gcvSURF_TYPE_UNKNOWN] = 0;
  130563. +
  130564. +#if gcdENABLE_VG
  130565. + memory->mapping[gcvSURF_IMAGE] = 0;
  130566. + memory->mapping[gcvSURF_MASK] = 0;
  130567. + memory->mapping[gcvSURF_SCISSOR] = 0;
  130568. +#endif
  130569. +
  130570. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130571. + "[GALCORE] INDEX: bank %d",
  130572. + memory->mapping[gcvSURF_INDEX]);
  130573. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130574. + "[GALCORE] VERTEX: bank %d",
  130575. + memory->mapping[gcvSURF_VERTEX]);
  130576. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130577. + "[GALCORE] TEXTURE: bank %d",
  130578. + memory->mapping[gcvSURF_TEXTURE]);
  130579. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130580. + "[GALCORE] RENDER_TARGET: bank %d",
  130581. + memory->mapping[gcvSURF_RENDER_TARGET]);
  130582. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130583. + "[GALCORE] DEPTH: bank %d",
  130584. + memory->mapping[gcvSURF_DEPTH]);
  130585. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  130586. + "[GALCORE] TILE_STATUS: bank %d",
  130587. + memory->mapping[gcvSURF_TILE_STATUS]);
  130588. +
  130589. + /* Allocate the mutex. */
  130590. + gcmkONERROR(gckOS_CreateMutex(Os, &memory->mutex));
  130591. +
  130592. + /* Return pointer to the gckVIDMEM object. */
  130593. + *Memory = memory;
  130594. +
  130595. + /* Success. */
  130596. + gcmkFOOTER_ARG("*Memory=0x%x", *Memory);
  130597. + return gcvSTATUS_OK;
  130598. +
  130599. +OnError:
  130600. + /* Roll back. */
  130601. + if (memory != gcvNULL)
  130602. + {
  130603. + if (memory->mutex != gcvNULL)
  130604. + {
  130605. + /* Delete the mutex. */
  130606. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, memory->mutex));
  130607. + }
  130608. +
  130609. + for (i = 0; i < banks; ++i)
  130610. + {
  130611. + /* Free the heap. */
  130612. + gcmkASSERT(memory->sentinel[i].VidMem.next != gcvNULL);
  130613. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, memory->sentinel[i].VidMem.next));
  130614. + }
  130615. +
  130616. + /* Free the object. */
  130617. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, memory));
  130618. + }
  130619. +
  130620. + /* Return the status. */
  130621. + gcmkFOOTER();
  130622. + return status;
  130623. +}
  130624. +
  130625. +/*******************************************************************************
  130626. +**
  130627. +** gckVIDMEM_Destroy
  130628. +**
  130629. +** Destroy an gckVIDMEM object.
  130630. +**
  130631. +** INPUT:
  130632. +**
  130633. +** gckVIDMEM Memory
  130634. +** Pointer to an gckVIDMEM object to destroy.
  130635. +**
  130636. +** OUTPUT:
  130637. +**
  130638. +** Nothing.
  130639. +*/
  130640. +gceSTATUS
  130641. +gckVIDMEM_Destroy(
  130642. + IN gckVIDMEM Memory
  130643. + )
  130644. +{
  130645. + gcuVIDMEM_NODE_PTR node, next;
  130646. + gctINT i;
  130647. +
  130648. + gcmkHEADER_ARG("Memory=0x%x", Memory);
  130649. +
  130650. + /* Verify the arguments. */
  130651. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  130652. +
  130653. + /* Walk all sentinels. */
  130654. + for (i = 0; i < gcmCOUNTOF(Memory->sentinel); ++i)
  130655. + {
  130656. + /* Bail out of the heap is not used. */
  130657. + if (Memory->sentinel[i].VidMem.next == gcvNULL)
  130658. + {
  130659. + break;
  130660. + }
  130661. +
  130662. + /* Walk all the nodes until we reach the sentinel. */
  130663. + for (node = Memory->sentinel[i].VidMem.next;
  130664. + node->VidMem.bytes != 0;
  130665. + node = next)
  130666. + {
  130667. + /* Save pointer to the next node. */
  130668. + next = node->VidMem.next;
  130669. +
  130670. + /* Free the node. */
  130671. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Memory->os, node));
  130672. + }
  130673. + }
  130674. +
  130675. + /* Free the mutex. */
  130676. + gcmkVERIFY_OK(gckOS_DeleteMutex(Memory->os, Memory->mutex));
  130677. +
  130678. + /* Mark the object as unknown. */
  130679. + Memory->object.type = gcvOBJ_UNKNOWN;
  130680. +
  130681. + /* Free the gckVIDMEM object. */
  130682. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Memory->os, Memory));
  130683. +
  130684. + /* Success. */
  130685. + gcmkFOOTER_NO();
  130686. + return gcvSTATUS_OK;
  130687. +}
  130688. +
  130689. +/*******************************************************************************
  130690. +**
  130691. +** gckVIDMEM_Allocate
  130692. +**
  130693. +** Allocate rectangular memory from the gckVIDMEM object.
  130694. +**
  130695. +** INPUT:
  130696. +**
  130697. +** gckVIDMEM Memory
  130698. +** Pointer to an gckVIDMEM object.
  130699. +**
  130700. +** gctUINT Width
  130701. +** Width of rectangle to allocate. Make sure the width is properly
  130702. +** aligned.
  130703. +**
  130704. +** gctUINT Height
  130705. +** Height of rectangle to allocate. Make sure the height is properly
  130706. +** aligned.
  130707. +**
  130708. +** gctUINT Depth
  130709. +** Depth of rectangle to allocate. This equals to the number of
  130710. +** rectangles to allocate contiguously (i.e., for cubic maps and volume
  130711. +** textures).
  130712. +**
  130713. +** gctUINT BytesPerPixel
  130714. +** Number of bytes per pixel.
  130715. +**
  130716. +** gctUINT32 Alignment
  130717. +** Byte alignment for allocation.
  130718. +**
  130719. +** gceSURF_TYPE Type
  130720. +** Type of surface to allocate (use by bank optimization).
  130721. +**
  130722. +** OUTPUT:
  130723. +**
  130724. +** gcuVIDMEM_NODE_PTR * Node
  130725. +** Pointer to a variable that will hold the allocated memory node.
  130726. +*/
  130727. +gceSTATUS
  130728. +gckVIDMEM_Allocate(
  130729. + IN gckVIDMEM Memory,
  130730. + IN gctUINT Width,
  130731. + IN gctUINT Height,
  130732. + IN gctUINT Depth,
  130733. + IN gctUINT BytesPerPixel,
  130734. + IN gctUINT32 Alignment,
  130735. + IN gceSURF_TYPE Type,
  130736. + OUT gcuVIDMEM_NODE_PTR * Node
  130737. + )
  130738. +{
  130739. + gctSIZE_T bytes;
  130740. + gceSTATUS status;
  130741. +
  130742. + gcmkHEADER_ARG("Memory=0x%x Width=%u Height=%u Depth=%u BytesPerPixel=%u "
  130743. + "Alignment=%u Type=%d",
  130744. + Memory, Width, Height, Depth, BytesPerPixel, Alignment,
  130745. + Type);
  130746. +
  130747. + /* Verify the arguments. */
  130748. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  130749. + gcmkVERIFY_ARGUMENT(Width > 0);
  130750. + gcmkVERIFY_ARGUMENT(Height > 0);
  130751. + gcmkVERIFY_ARGUMENT(Depth > 0);
  130752. + gcmkVERIFY_ARGUMENT(BytesPerPixel > 0);
  130753. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  130754. +
  130755. + /* Compute linear size. */
  130756. + bytes = Width * Height * Depth * BytesPerPixel;
  130757. +
  130758. + /* Allocate through linear function. */
  130759. + gcmkONERROR(
  130760. + gckVIDMEM_AllocateLinear(Memory, bytes, Alignment, Type, Node));
  130761. +
  130762. + /* Success. */
  130763. + gcmkFOOTER_ARG("*Node=0x%x", *Node);
  130764. + return gcvSTATUS_OK;
  130765. +
  130766. +OnError:
  130767. + /* Return the status. */
  130768. + gcmkFOOTER();
  130769. + return status;
  130770. +}
  130771. +
  130772. +#if gcdENABLE_BANK_ALIGNMENT
  130773. +
  130774. +#if !gcdBANK_BIT_START
  130775. +#error gcdBANK_BIT_START not defined.
  130776. +#endif
  130777. +
  130778. +#if !gcdBANK_BIT_END
  130779. +#error gcdBANK_BIT_END not defined.
  130780. +#endif
  130781. +/*******************************************************************************
  130782. +** _GetSurfaceBankAlignment
  130783. +**
  130784. +** Return the required offset alignment required to the make BaseAddress
  130785. +** aligned properly.
  130786. +**
  130787. +** INPUT:
  130788. +**
  130789. +** gckOS Os
  130790. +** Pointer to gcoOS object.
  130791. +**
  130792. +** gceSURF_TYPE Type
  130793. +** Type of allocation.
  130794. +**
  130795. +** gctUINT32 BaseAddress
  130796. +** Base address of current video memory node.
  130797. +**
  130798. +** OUTPUT:
  130799. +**
  130800. +** gctUINT32_PTR AlignmentOffset
  130801. +** Pointer to a variable that will hold the number of bytes to skip in
  130802. +** the current video memory node in order to make the alignment bank
  130803. +** aligned.
  130804. +*/
  130805. +static gceSTATUS
  130806. +_GetSurfaceBankAlignment(
  130807. + IN gceSURF_TYPE Type,
  130808. + IN gctUINT32 BaseAddress,
  130809. + OUT gctUINT32_PTR AlignmentOffset
  130810. + )
  130811. +{
  130812. + gctUINT32 bank;
  130813. + /* To retrieve the bank. */
  130814. + static const gctUINT32 bankMask = (0xFFFFFFFF << gcdBANK_BIT_START)
  130815. + ^ (0xFFFFFFFF << (gcdBANK_BIT_END + 1));
  130816. +
  130817. + /* To retrieve the bank and all the lower bytes. */
  130818. + static const gctUINT32 byteMask = ~(0xFFFFFFFF << (gcdBANK_BIT_END + 1));
  130819. +
  130820. + gcmkHEADER_ARG("Type=%d BaseAddress=0x%x ", Type, BaseAddress);
  130821. +
  130822. + /* Verify the arguments. */
  130823. + gcmkVERIFY_ARGUMENT(AlignmentOffset != gcvNULL);
  130824. +
  130825. + switch (Type)
  130826. + {
  130827. + case gcvSURF_RENDER_TARGET:
  130828. + bank = (BaseAddress & bankMask) >> (gcdBANK_BIT_START);
  130829. +
  130830. + /* Align to the first bank. */
  130831. + *AlignmentOffset = (bank == 0) ?
  130832. + 0 :
  130833. + ((1 << (gcdBANK_BIT_END + 1)) + 0) - (BaseAddress & byteMask);
  130834. + break;
  130835. +
  130836. + case gcvSURF_DEPTH:
  130837. + bank = (BaseAddress & bankMask) >> (gcdBANK_BIT_START);
  130838. +
  130839. + /* Align to the third bank. */
  130840. + *AlignmentOffset = (bank == 2) ?
  130841. + 0 :
  130842. + ((1 << (gcdBANK_BIT_END + 1)) + (2 << gcdBANK_BIT_START)) - (BaseAddress & byteMask);
  130843. +
  130844. + /* Add a channel offset at the channel bit. */
  130845. + *AlignmentOffset += (1 << gcdBANK_CHANNEL_BIT);
  130846. + break;
  130847. +
  130848. + default:
  130849. + /* no alignment needed. */
  130850. + *AlignmentOffset = 0;
  130851. + }
  130852. +
  130853. + /* Return the status. */
  130854. + gcmkFOOTER_ARG("*AlignmentOffset=%u", *AlignmentOffset);
  130855. + return gcvSTATUS_OK;
  130856. +}
  130857. +#endif
  130858. +
  130859. +static gcuVIDMEM_NODE_PTR
  130860. +_FindNode(
  130861. + IN gckVIDMEM Memory,
  130862. + IN gctINT Bank,
  130863. + IN gctSIZE_T Bytes,
  130864. + IN gceSURF_TYPE Type,
  130865. + IN OUT gctUINT32_PTR Alignment
  130866. + )
  130867. +{
  130868. + gcuVIDMEM_NODE_PTR node;
  130869. + gctUINT32 alignment;
  130870. +
  130871. +#if gcdENABLE_BANK_ALIGNMENT
  130872. + gctUINT32 bankAlignment;
  130873. + gceSTATUS status;
  130874. +#endif
  130875. +
  130876. + if (Memory->sentinel[Bank].VidMem.nextFree == gcvNULL)
  130877. + {
  130878. + /* No free nodes left. */
  130879. + return gcvNULL;
  130880. + }
  130881. +
  130882. +#if gcdENABLE_BANK_ALIGNMENT
  130883. + /* Walk all free nodes until we have one that is big enough or we have
  130884. + ** reached the sentinel. */
  130885. + for (node = Memory->sentinel[Bank].VidMem.nextFree;
  130886. + node->VidMem.bytes != 0;
  130887. + node = node->VidMem.nextFree)
  130888. + {
  130889. + gcmkONERROR(_GetSurfaceBankAlignment(
  130890. + Type,
  130891. + node->VidMem.memory->baseAddress + node->VidMem.offset,
  130892. + &bankAlignment));
  130893. +
  130894. + bankAlignment = gcmALIGN(bankAlignment, *Alignment);
  130895. +
  130896. + /* Compute number of bytes to skip for alignment. */
  130897. + alignment = (*Alignment == 0)
  130898. + ? 0
  130899. + : (*Alignment - (node->VidMem.offset % *Alignment));
  130900. +
  130901. + if (alignment == *Alignment)
  130902. + {
  130903. + /* Node is already aligned. */
  130904. + alignment = 0;
  130905. + }
  130906. +
  130907. + if (node->VidMem.bytes >= Bytes + alignment + bankAlignment)
  130908. + {
  130909. + /* This node is big enough. */
  130910. + *Alignment = alignment + bankAlignment;
  130911. + return node;
  130912. + }
  130913. + }
  130914. +#endif
  130915. +
  130916. + /* Walk all free nodes until we have one that is big enough or we have
  130917. + reached the sentinel. */
  130918. + for (node = Memory->sentinel[Bank].VidMem.nextFree;
  130919. + node->VidMem.bytes != 0;
  130920. + node = node->VidMem.nextFree)
  130921. + {
  130922. +
  130923. + gctINT modulo = gckMATH_ModuloInt(node->VidMem.offset, *Alignment);
  130924. +
  130925. + /* Compute number of bytes to skip for alignment. */
  130926. + alignment = (*Alignment == 0) ? 0 : (*Alignment - modulo);
  130927. +
  130928. + if (alignment == *Alignment)
  130929. + {
  130930. + /* Node is already aligned. */
  130931. + alignment = 0;
  130932. + }
  130933. +
  130934. + if (node->VidMem.bytes >= Bytes + alignment)
  130935. + {
  130936. + /* This node is big enough. */
  130937. + *Alignment = alignment;
  130938. + return node;
  130939. + }
  130940. + }
  130941. +
  130942. +#if gcdENABLE_BANK_ALIGNMENT
  130943. +OnError:
  130944. +#endif
  130945. + /* Not enough memory. */
  130946. + return gcvNULL;
  130947. +}
  130948. +
  130949. +/*******************************************************************************
  130950. +**
  130951. +** gckVIDMEM_AllocateLinear
  130952. +**
  130953. +** Allocate linear memory from the gckVIDMEM object.
  130954. +**
  130955. +** INPUT:
  130956. +**
  130957. +** gckVIDMEM Memory
  130958. +** Pointer to an gckVIDMEM object.
  130959. +**
  130960. +** gctSIZE_T Bytes
  130961. +** Number of bytes to allocate.
  130962. +**
  130963. +** gctUINT32 Alignment
  130964. +** Byte alignment for allocation.
  130965. +**
  130966. +** gceSURF_TYPE Type
  130967. +** Type of surface to allocate (use by bank optimization).
  130968. +**
  130969. +** OUTPUT:
  130970. +**
  130971. +** gcuVIDMEM_NODE_PTR * Node
  130972. +** Pointer to a variable that will hold the allocated memory node.
  130973. +*/
  130974. +gceSTATUS
  130975. +gckVIDMEM_AllocateLinear(
  130976. + IN gckVIDMEM Memory,
  130977. + IN gctSIZE_T Bytes,
  130978. + IN gctUINT32 Alignment,
  130979. + IN gceSURF_TYPE Type,
  130980. + OUT gcuVIDMEM_NODE_PTR * Node
  130981. + )
  130982. +{
  130983. + gceSTATUS status;
  130984. + gcuVIDMEM_NODE_PTR node;
  130985. + gctUINT32 alignment;
  130986. + gctINT bank, i;
  130987. + gctBOOL acquired = gcvFALSE;
  130988. +#if gcdSMALL_BLOCK_SIZE
  130989. + gctBOOL force_allocate = (Type == gcvSURF_TILE_STATUS) || (Type & gcvSURF_VG);
  130990. +#endif
  130991. +
  130992. + gcmkHEADER_ARG("Memory=0x%x Bytes=%lu Alignment=%u Type=%d",
  130993. + Memory, Bytes, Alignment, Type);
  130994. +
  130995. + Type &= ~gcvSURF_VG;
  130996. + /* Verify the arguments. */
  130997. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  130998. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  130999. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  131000. + gcmkVERIFY_ARGUMENT(Type < gcvSURF_NUM_TYPES);
  131001. +
  131002. + /* Acquire the mutex. */
  131003. + gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
  131004. +
  131005. + acquired = gcvTRUE;
  131006. +#if !gcdUSE_VIDMEM_PER_PID
  131007. +
  131008. + if (Bytes > Memory->freeBytes)
  131009. + {
  131010. + /* Not enough memory. */
  131011. + status = gcvSTATUS_OUT_OF_MEMORY;
  131012. + goto OnError;
  131013. + }
  131014. +#endif
  131015. +
  131016. +#if gcdSMALL_BLOCK_SIZE
  131017. + if ((!force_allocate) && (Memory->freeBytes < (Memory->bytes/gcdRATIO_FOR_SMALL_MEMORY))
  131018. + && (Bytes >= gcdSMALL_BLOCK_SIZE)
  131019. + )
  131020. + {
  131021. + /* The left memory is for small memory.*/
  131022. + status = gcvSTATUS_OUT_OF_MEMORY;
  131023. + goto OnError;
  131024. + }
  131025. +#endif
  131026. +
  131027. + /* Find the default bank for this surface type. */
  131028. + gcmkASSERT((gctINT) Type < gcmCOUNTOF(Memory->mapping));
  131029. + bank = Memory->mapping[Type];
  131030. + alignment = Alignment;
  131031. +
  131032. +#if gcdUSE_VIDMEM_PER_PID
  131033. + if (Bytes <= Memory->freeBytes)
  131034. + {
  131035. +#endif
  131036. + /* Find a free node in the default bank. */
  131037. + node = _FindNode(Memory, bank, Bytes, Type, &alignment);
  131038. +
  131039. + /* Out of memory? */
  131040. + if (node == gcvNULL)
  131041. + {
  131042. + /* Walk all lower banks. */
  131043. + for (i = bank - 1; i >= 0; --i)
  131044. + {
  131045. + /* Find a free node inside the current bank. */
  131046. + node = _FindNode(Memory, i, Bytes, Type, &alignment);
  131047. + if (node != gcvNULL)
  131048. + {
  131049. + break;
  131050. + }
  131051. + }
  131052. + }
  131053. +
  131054. + if (node == gcvNULL)
  131055. + {
  131056. + /* Walk all upper banks. */
  131057. + for (i = bank + 1; i < gcmCOUNTOF(Memory->sentinel); ++i)
  131058. + {
  131059. + if (Memory->sentinel[i].VidMem.nextFree == gcvNULL)
  131060. + {
  131061. + /* Abort when we reach unused banks. */
  131062. + break;
  131063. + }
  131064. +
  131065. + /* Find a free node inside the current bank. */
  131066. + node = _FindNode(Memory, i, Bytes, Type, &alignment);
  131067. + if (node != gcvNULL)
  131068. + {
  131069. + break;
  131070. + }
  131071. + }
  131072. + }
  131073. +#if gcdUSE_VIDMEM_PER_PID
  131074. + }
  131075. +#endif
  131076. +
  131077. + if (node == gcvNULL)
  131078. + {
  131079. + /* Out of memory. */
  131080. +#if gcdUSE_VIDMEM_PER_PID
  131081. + /* Allocate more memory from shared pool. */
  131082. + gctSIZE_T bytes;
  131083. + gctPHYS_ADDR physical_temp;
  131084. + gctUINT32 physical;
  131085. + gctPOINTER logical;
  131086. +
  131087. + bytes = gcmALIGN(Bytes, gcdUSE_VIDMEM_PER_PID_SIZE);
  131088. +
  131089. + gcmkONERROR(gckOS_AllocateContiguous(Memory->os,
  131090. + gcvTRUE,
  131091. + &bytes,
  131092. + &physical_temp,
  131093. + &logical));
  131094. +
  131095. + /* physical address is returned as 0 for user space. workaround. */
  131096. + if (physical_temp == gcvNULL)
  131097. + {
  131098. + gcmkONERROR(gckOS_GetPhysicalAddress(Memory->os, logical, &physical));
  131099. + }
  131100. +
  131101. + /* Allocate one gcuVIDMEM_NODE union. */
  131102. + gcmkONERROR(
  131103. + gckOS_Allocate(Memory->os,
  131104. + gcmSIZEOF(gcuVIDMEM_NODE),
  131105. + (gctPOINTER *) &node));
  131106. +
  131107. + /* Initialize gcuVIDMEM_NODE union. */
  131108. + node->VidMem.memory = Memory;
  131109. +
  131110. + node->VidMem.offset = 0;
  131111. + node->VidMem.bytes = bytes;
  131112. + node->VidMem.alignment = 0;
  131113. + node->VidMem.physical = physical;
  131114. + node->VidMem.pool = gcvPOOL_UNKNOWN;
  131115. +
  131116. + node->VidMem.locked = 0;
  131117. +
  131118. +#ifdef __QNXNTO__
  131119. + gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID));
  131120. + node->VidMem.logical = logical;
  131121. + gcmkASSERT(logical != gcvNULL);
  131122. +#endif
  131123. +
  131124. + /* Insert node behind sentinel node. */
  131125. + node->VidMem.next = Memory->sentinel[bank].VidMem.next;
  131126. + node->VidMem.prev = &Memory->sentinel[bank];
  131127. + Memory->sentinel[bank].VidMem.next = node->VidMem.next->VidMem.prev = node;
  131128. +
  131129. + /* Insert free node behind sentinel node. */
  131130. + node->VidMem.nextFree = Memory->sentinel[bank].VidMem.nextFree;
  131131. + node->VidMem.prevFree = &Memory->sentinel[bank];
  131132. + Memory->sentinel[bank].VidMem.nextFree = node->VidMem.nextFree->VidMem.prevFree = node;
  131133. +
  131134. + Memory->freeBytes += bytes;
  131135. +#else
  131136. + status = gcvSTATUS_OUT_OF_MEMORY;
  131137. + goto OnError;
  131138. +#endif
  131139. + }
  131140. +
  131141. + /* Do we have an alignment? */
  131142. + if (alignment > 0)
  131143. + {
  131144. + /* Split the node so it is aligned. */
  131145. + if (_Split(Memory->os, node, alignment))
  131146. + {
  131147. + /* Successful split, move to aligned node. */
  131148. + node = node->VidMem.next;
  131149. +
  131150. + /* Remove alignment. */
  131151. + alignment = 0;
  131152. + }
  131153. + }
  131154. +
  131155. + /* Do we have enough memory after the allocation to split it? */
  131156. + if (node->VidMem.bytes - Bytes > Memory->threshold)
  131157. + {
  131158. + /* Adjust the node size. */
  131159. + _Split(Memory->os, node, Bytes);
  131160. + }
  131161. +
  131162. + /* Remove the node from the free list. */
  131163. + node->VidMem.prevFree->VidMem.nextFree = node->VidMem.nextFree;
  131164. + node->VidMem.nextFree->VidMem.prevFree = node->VidMem.prevFree;
  131165. + node->VidMem.nextFree =
  131166. + node->VidMem.prevFree = gcvNULL;
  131167. +
  131168. + /* Fill in the information. */
  131169. + node->VidMem.alignment = alignment;
  131170. + node->VidMem.memory = Memory;
  131171. +#ifdef __QNXNTO__
  131172. +#if !gcdUSE_VIDMEM_PER_PID
  131173. + node->VidMem.logical = gcvNULL;
  131174. + gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID));
  131175. +#else
  131176. + gcmkASSERT(node->VidMem.logical != gcvNULL);
  131177. +#endif
  131178. +#endif
  131179. +
  131180. + /* Adjust the number of free bytes. */
  131181. + Memory->freeBytes -= node->VidMem.bytes;
  131182. +
  131183. + node->VidMem.freePending = gcvFALSE;
  131184. +
  131185. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  131186. + node->VidMem.kernelVirtual = gcvNULL;
  131187. +#endif
  131188. +
  131189. + /* Release the mutex. */
  131190. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  131191. +
  131192. + /* Return the pointer to the node. */
  131193. + *Node = node;
  131194. +
  131195. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131196. + "Allocated %u bytes @ 0x%x [0x%08X]",
  131197. + node->VidMem.bytes, node, node->VidMem.offset);
  131198. +
  131199. + /* Success. */
  131200. + gcmkFOOTER_ARG("*Node=0x%x", *Node);
  131201. + return gcvSTATUS_OK;
  131202. +
  131203. +OnError:
  131204. + if (acquired)
  131205. + {
  131206. + /* Release the mutex. */
  131207. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  131208. + }
  131209. +
  131210. + /* Return the status. */
  131211. + gcmkFOOTER();
  131212. + return status;
  131213. +}
  131214. +
  131215. +/*******************************************************************************
  131216. +**
  131217. +** gckVIDMEM_Free
  131218. +**
  131219. +** Free an allocated video memory node.
  131220. +**
  131221. +** INPUT:
  131222. +**
  131223. +** gcuVIDMEM_NODE_PTR Node
  131224. +** Pointer to a gcuVIDMEM_NODE object.
  131225. +**
  131226. +** OUTPUT:
  131227. +**
  131228. +** Nothing.
  131229. +*/
  131230. +gceSTATUS
  131231. +gckVIDMEM_Free(
  131232. + IN gcuVIDMEM_NODE_PTR Node
  131233. + )
  131234. +{
  131235. + gceSTATUS status;
  131236. + gckKERNEL kernel = gcvNULL;
  131237. + gckVIDMEM memory = gcvNULL;
  131238. + gcuVIDMEM_NODE_PTR node;
  131239. + gctBOOL mutexAcquired = gcvFALSE;
  131240. + gckOS os = gcvNULL;
  131241. + gctBOOL acquired = gcvFALSE;
  131242. + gctINT32 i, totalLocked;
  131243. +
  131244. + gcmkHEADER_ARG("Node=0x%x", Node);
  131245. +
  131246. + /* Verify the arguments. */
  131247. + if ((Node == gcvNULL)
  131248. + || (Node->VidMem.memory == gcvNULL)
  131249. + )
  131250. + {
  131251. + /* Invalid object. */
  131252. + gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
  131253. + }
  131254. +
  131255. + /**************************** Video Memory ********************************/
  131256. +
  131257. + if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  131258. + {
  131259. + if (Node->VidMem.locked > 0)
  131260. + {
  131261. + /* Client still has a lock, defer free op 'till when lock reaches 0. */
  131262. + Node->VidMem.freePending = gcvTRUE;
  131263. +
  131264. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131265. + "Node 0x%x is locked (%d)... deferring free.",
  131266. + Node, Node->VidMem.locked);
  131267. +
  131268. + gcmkFOOTER_NO();
  131269. + return gcvSTATUS_OK;
  131270. + }
  131271. +
  131272. + /* Extract pointer to gckVIDMEM object owning the node. */
  131273. + memory = Node->VidMem.memory;
  131274. +
  131275. + /* Acquire the mutex. */
  131276. + gcmkONERROR(
  131277. + gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
  131278. +
  131279. + mutexAcquired = gcvTRUE;
  131280. +
  131281. +#ifdef __QNXNTO__
  131282. +#if !gcdUSE_VIDMEM_PER_PID
  131283. + /* Reset. */
  131284. + Node->VidMem.processID = 0;
  131285. + Node->VidMem.logical = gcvNULL;
  131286. +#endif
  131287. +
  131288. + /* Don't try to re-free an already freed node. */
  131289. + if ((Node->VidMem.nextFree == gcvNULL)
  131290. + && (Node->VidMem.prevFree == gcvNULL)
  131291. + )
  131292. +#endif
  131293. + {
  131294. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  131295. + if (Node->VidMem.kernelVirtual)
  131296. + {
  131297. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131298. + "%s(%d) Unmap %x from kernel space.",
  131299. + __FUNCTION__, __LINE__,
  131300. + Node->VidMem.kernelVirtual);
  131301. +
  131302. + gcmkVERIFY_OK(
  131303. + gckOS_UnmapPhysical(memory->os,
  131304. + Node->VidMem.kernelVirtual,
  131305. + Node->VidMem.bytes));
  131306. +
  131307. + Node->VidMem.kernelVirtual = gcvNULL;
  131308. + }
  131309. +#endif
  131310. +
  131311. + /* Check if Node is already freed. */
  131312. + if (Node->VidMem.nextFree)
  131313. + {
  131314. + /* Node is alread freed. */
  131315. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  131316. + }
  131317. +
  131318. + /* Update the number of free bytes. */
  131319. + memory->freeBytes += Node->VidMem.bytes;
  131320. +
  131321. + /* Find the next free node. */
  131322. + for (node = Node->VidMem.next;
  131323. + node != gcvNULL && node->VidMem.nextFree == gcvNULL;
  131324. + node = node->VidMem.next) ;
  131325. +
  131326. + /* Insert this node in the free list. */
  131327. + Node->VidMem.nextFree = node;
  131328. + Node->VidMem.prevFree = node->VidMem.prevFree;
  131329. +
  131330. + Node->VidMem.prevFree->VidMem.nextFree =
  131331. + node->VidMem.prevFree = Node;
  131332. +
  131333. + /* Is the next node a free node and not the sentinel? */
  131334. + if ((Node->VidMem.next == Node->VidMem.nextFree)
  131335. + && (Node->VidMem.next->VidMem.bytes != 0)
  131336. + )
  131337. + {
  131338. + /* Merge this node with the next node. */
  131339. + gcmkONERROR(_Merge(memory->os, node = Node));
  131340. + gcmkASSERT(node->VidMem.nextFree != node);
  131341. + gcmkASSERT(node->VidMem.prevFree != node);
  131342. + }
  131343. +
  131344. + /* Is the previous node a free node and not the sentinel? */
  131345. + if ((Node->VidMem.prev == Node->VidMem.prevFree)
  131346. + && (Node->VidMem.prev->VidMem.bytes != 0)
  131347. + )
  131348. + {
  131349. + /* Merge this node with the previous node. */
  131350. + gcmkONERROR(_Merge(memory->os, node = Node->VidMem.prev));
  131351. + gcmkASSERT(node->VidMem.nextFree != node);
  131352. + gcmkASSERT(node->VidMem.prevFree != node);
  131353. + }
  131354. + }
  131355. +
  131356. + /* Release the mutex. */
  131357. + gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
  131358. +
  131359. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131360. + "Node 0x%x is freed.",
  131361. + Node);
  131362. +
  131363. + /* Success. */
  131364. + gcmkFOOTER_NO();
  131365. + return gcvSTATUS_OK;
  131366. + }
  131367. +
  131368. + /*************************** Virtual Memory *******************************/
  131369. +
  131370. + /* Get gckKERNEL object. */
  131371. + kernel = Node->Virtual.kernel;
  131372. +
  131373. + /* Verify the gckKERNEL object pointer. */
  131374. + gcmkVERIFY_OBJECT(kernel, gcvOBJ_KERNEL);
  131375. +
  131376. + /* Get the gckOS object pointer. */
  131377. + os = kernel->os;
  131378. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  131379. +
  131380. + /* Grab the mutex. */
  131381. + gcmkONERROR(
  131382. + gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
  131383. +
  131384. + acquired = gcvTRUE;
  131385. +
  131386. + for (i = 0, totalLocked = 0; i < gcdMAX_GPU_COUNT; i++)
  131387. + {
  131388. + totalLocked += Node->Virtual.lockeds[i];
  131389. + }
  131390. +
  131391. + if (totalLocked > 0)
  131392. + {
  131393. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_VIDMEM,
  131394. + "gckVIDMEM_Free: Virtual node 0x%x is locked (%d)",
  131395. + Node, totalLocked);
  131396. +
  131397. + /* Set Flag */
  131398. + Node->Virtual.freed = gcvTRUE;
  131399. +
  131400. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  131401. + }
  131402. + else
  131403. + {
  131404. + /* Free the virtual memory. */
  131405. + gcmkVERIFY_OK(gckOS_FreePagedMemory(kernel->os,
  131406. + Node->Virtual.physical,
  131407. + Node->Virtual.bytes));
  131408. +
  131409. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  131410. +
  131411. + /* Destroy the gcuVIDMEM_NODE union. */
  131412. + gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
  131413. + }
  131414. +
  131415. + /* Success. */
  131416. + gcmkFOOTER_NO();
  131417. + return gcvSTATUS_OK;
  131418. +
  131419. +OnError:
  131420. + if (mutexAcquired)
  131421. + {
  131422. + /* Release the mutex. */
  131423. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  131424. + memory->os, memory->mutex
  131425. + ));
  131426. + }
  131427. +
  131428. + if (acquired)
  131429. + {
  131430. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  131431. + }
  131432. +
  131433. + /* Return the status. */
  131434. + gcmkFOOTER();
  131435. + return status;
  131436. +}
  131437. +
  131438. +
  131439. +#ifdef __QNXNTO__
  131440. +/*******************************************************************************
  131441. +**
  131442. +** gcoVIDMEM_FreeHandleMemory
  131443. +**
  131444. +** Free all allocated video memory nodes for a handle.
  131445. +**
  131446. +** INPUT:
  131447. +**
  131448. +** gcoVIDMEM Memory
  131449. +** Pointer to an gcoVIDMEM object..
  131450. +**
  131451. +** OUTPUT:
  131452. +**
  131453. +** Nothing.
  131454. +*/
  131455. +gceSTATUS
  131456. +gckVIDMEM_FreeHandleMemory(
  131457. + IN gckKERNEL Kernel,
  131458. + IN gckVIDMEM Memory,
  131459. + IN gctUINT32 Pid
  131460. + )
  131461. +{
  131462. + gceSTATUS status;
  131463. + gctBOOL mutex = gcvFALSE;
  131464. + gcuVIDMEM_NODE_PTR node;
  131465. + gctINT i;
  131466. + gctUINT32 nodeCount = 0, byteCount = 0;
  131467. + gctBOOL again;
  131468. +
  131469. + gcmkHEADER_ARG("Kernel=0x%x, Memory=0x%x Pid=0x%u", Kernel, Memory, Pid);
  131470. +
  131471. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  131472. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  131473. +
  131474. + gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
  131475. + mutex = gcvTRUE;
  131476. +
  131477. + /* Walk all sentinels. */
  131478. + for (i = 0; i < gcmCOUNTOF(Memory->sentinel); ++i)
  131479. + {
  131480. + /* Bail out of the heap if it is not used. */
  131481. + if (Memory->sentinel[i].VidMem.next == gcvNULL)
  131482. + {
  131483. + break;
  131484. + }
  131485. +
  131486. + do
  131487. + {
  131488. + again = gcvFALSE;
  131489. +
  131490. + /* Walk all the nodes until we reach the sentinel. */
  131491. + for (node = Memory->sentinel[i].VidMem.next;
  131492. + node->VidMem.bytes != 0;
  131493. + node = node->VidMem.next)
  131494. + {
  131495. + /* Free the node if it was allocated by Handle. */
  131496. + if (node->VidMem.processID == Pid)
  131497. + {
  131498. + /* Unlock video memory. */
  131499. + while (node->VidMem.locked > 0)
  131500. + {
  131501. + gckVIDMEM_Unlock(Kernel, node, gcvSURF_TYPE_UNKNOWN, gcvNULL);
  131502. + }
  131503. +
  131504. + nodeCount++;
  131505. + byteCount += node->VidMem.bytes;
  131506. +
  131507. + /* Free video memory. */
  131508. + gcmkVERIFY_OK(gckVIDMEM_Free(node));
  131509. +
  131510. + /*
  131511. + * Freeing may cause a merge which will invalidate our iteration.
  131512. + * Don't be clever, just restart.
  131513. + */
  131514. + again = gcvTRUE;
  131515. +
  131516. + break;
  131517. + }
  131518. +#if gcdUSE_VIDMEM_PER_PID
  131519. + else
  131520. + {
  131521. + gcmkASSERT(node->VidMem.processID == Pid);
  131522. + }
  131523. +#endif
  131524. + }
  131525. + }
  131526. + while (again);
  131527. + }
  131528. +
  131529. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  131530. + gcmkFOOTER();
  131531. + return gcvSTATUS_OK;
  131532. +
  131533. +OnError:
  131534. + if (mutex)
  131535. + {
  131536. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  131537. + }
  131538. +
  131539. + gcmkFOOTER();
  131540. + return status;
  131541. +}
  131542. +#endif
  131543. +
  131544. +/*******************************************************************************
  131545. +**
  131546. +** _NeedVirtualMapping
  131547. +**
  131548. +** Whether setup GPU page table for video node.
  131549. +**
  131550. +** INPUT:
  131551. +** gckKERNEL Kernel
  131552. +** Pointer to an gckKERNEL object.
  131553. +**
  131554. +** gcuVIDMEM_NODE_PTR Node
  131555. +** Pointer to a gcuVIDMEM_NODE union.
  131556. +**
  131557. +** gceCORE Core
  131558. +** Id of current GPU.
  131559. +**
  131560. +** OUTPUT:
  131561. +** gctBOOL * NeedMapping
  131562. +** A pointer hold the result whether Node should be mapping.
  131563. +*/
  131564. +static gceSTATUS
  131565. +_NeedVirtualMapping(
  131566. + IN gckKERNEL Kernel,
  131567. + IN gceCORE Core,
  131568. + IN gcuVIDMEM_NODE_PTR Node,
  131569. + OUT gctBOOL * NeedMapping
  131570. +)
  131571. +{
  131572. + gceSTATUS status;
  131573. + gctUINT32 phys;
  131574. + gctUINT32 end;
  131575. + gcePOOL pool;
  131576. + gctUINT32 offset;
  131577. + gctUINT32 baseAddress;
  131578. +
  131579. + gcmkHEADER_ARG("Node=0x%X", Node);
  131580. +
  131581. + /* Verify the arguments. */
  131582. + gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
  131583. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  131584. + gcmkVERIFY_ARGUMENT(NeedMapping != gcvNULL);
  131585. + gcmkVERIFY_ARGUMENT(Core < gcdMAX_GPU_COUNT);
  131586. +
  131587. + if (Node->Virtual.contiguous)
  131588. + {
  131589. +#if gcdENABLE_VG
  131590. + if (Core == gcvCORE_VG)
  131591. + {
  131592. + *NeedMapping = gcvFALSE;
  131593. + }
  131594. + else
  131595. +#endif
  131596. + {
  131597. + /* Convert logical address into a physical address. */
  131598. + gcmkONERROR(
  131599. + gckOS_GetPhysicalAddress(Kernel->os, Node->Virtual.logical, &phys));
  131600. +
  131601. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  131602. +
  131603. + gcmkASSERT(phys >= baseAddress);
  131604. +
  131605. + /* Subtract baseAddress to get a GPU address used for programming. */
  131606. + phys -= baseAddress;
  131607. +
  131608. + /* If part of region is belong to gcvPOOL_VIRTUAL,
  131609. + ** whole region has to be mapped. */
  131610. + end = phys + Node->Virtual.bytes - 1;
  131611. +
  131612. + gcmkONERROR(gckHARDWARE_SplitMemory(
  131613. + Kernel->hardware, end, &pool, &offset
  131614. + ));
  131615. +
  131616. + *NeedMapping = (pool == gcvPOOL_VIRTUAL);
  131617. + }
  131618. + }
  131619. + else
  131620. + {
  131621. + *NeedMapping = gcvTRUE;
  131622. + }
  131623. +
  131624. + gcmkFOOTER_ARG("*NeedMapping=%d", *NeedMapping);
  131625. + return gcvSTATUS_OK;
  131626. +
  131627. +OnError:
  131628. + gcmkFOOTER();
  131629. + return status;
  131630. +}
  131631. +
  131632. +/*******************************************************************************
  131633. +**
  131634. +** gckVIDMEM_Lock
  131635. +**
  131636. +** Lock a video memory node and return its hardware specific address.
  131637. +**
  131638. +** INPUT:
  131639. +**
  131640. +** gckKERNEL Kernel
  131641. +** Pointer to an gckKERNEL object.
  131642. +**
  131643. +** gcuVIDMEM_NODE_PTR Node
  131644. +** Pointer to a gcuVIDMEM_NODE union.
  131645. +**
  131646. +** OUTPUT:
  131647. +**
  131648. +** gctUINT32 * Address
  131649. +** Pointer to a variable that will hold the hardware specific address.
  131650. +*/
  131651. +gceSTATUS
  131652. +gckVIDMEM_Lock(
  131653. + IN gckKERNEL Kernel,
  131654. + IN gcuVIDMEM_NODE_PTR Node,
  131655. + IN gctBOOL Cacheable,
  131656. + OUT gctUINT32 * Address
  131657. + )
  131658. +{
  131659. + gceSTATUS status;
  131660. + gctBOOL acquired = gcvFALSE;
  131661. + gctBOOL locked = gcvFALSE;
  131662. + gckOS os = gcvNULL;
  131663. + gctBOOL needMapping;
  131664. + gctUINT32 baseAddress;
  131665. +
  131666. + gcmkHEADER_ARG("Node=0x%x", Node);
  131667. +
  131668. + /* Verify the arguments. */
  131669. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  131670. +
  131671. + if ((Node == gcvNULL)
  131672. + || (Node->VidMem.memory == gcvNULL)
  131673. + )
  131674. + {
  131675. + /* Invalid object. */
  131676. + gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
  131677. + }
  131678. +
  131679. + /**************************** Video Memory ********************************/
  131680. +
  131681. + if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  131682. + {
  131683. + if (Cacheable == gcvTRUE)
  131684. + {
  131685. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  131686. + }
  131687. +
  131688. + /* Increment the lock count. */
  131689. + Node->VidMem.locked ++;
  131690. +
  131691. + /* Return the physical address of the node. */
  131692. +#if !gcdUSE_VIDMEM_PER_PID
  131693. + *Address = Node->VidMem.memory->baseAddress
  131694. + + Node->VidMem.offset
  131695. + + Node->VidMem.alignment;
  131696. +#else
  131697. + *Address = Node->VidMem.physical;
  131698. +#endif
  131699. +
  131700. + /* Get hardware specific address. */
  131701. +#if gcdENABLE_VG
  131702. + if (Kernel->vg == gcvNULL)
  131703. +#endif
  131704. + {
  131705. + if (Kernel->hardware->mmuVersion == 0)
  131706. + {
  131707. + /* Convert physical to GPU address for old mmu. */
  131708. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  131709. + gcmkASSERT(*Address > baseAddress);
  131710. + *Address -= baseAddress;
  131711. + }
  131712. + }
  131713. +
  131714. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131715. + "Locked node 0x%x (%d) @ 0x%08X",
  131716. + Node,
  131717. + Node->VidMem.locked,
  131718. + *Address);
  131719. + }
  131720. +
  131721. + /*************************** Virtual Memory *******************************/
  131722. +
  131723. + else
  131724. + {
  131725. + /* Verify the gckKERNEL object pointer. */
  131726. + gcmkVERIFY_OBJECT(Node->Virtual.kernel, gcvOBJ_KERNEL);
  131727. +
  131728. + /* Extract the gckOS object pointer. */
  131729. + os = Node->Virtual.kernel->os;
  131730. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  131731. +
  131732. + /* Grab the mutex. */
  131733. + gcmkONERROR(gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
  131734. + acquired = gcvTRUE;
  131735. +
  131736. +#if gcdPAGED_MEMORY_CACHEABLE
  131737. + /* Force video memory cacheable. */
  131738. + Cacheable = gcvTRUE;
  131739. +#endif
  131740. +
  131741. + gcmkONERROR(
  131742. + gckOS_LockPages(os,
  131743. + Node->Virtual.physical,
  131744. + Node->Virtual.bytes,
  131745. + Cacheable,
  131746. + &Node->Virtual.logical,
  131747. + &Node->Virtual.pageCount));
  131748. +
  131749. + /* Increment the lock count. */
  131750. + if (Node->Virtual.lockeds[Kernel->core] ++ == 0)
  131751. + {
  131752. + /* Is this node pending for a final unlock? */
  131753. +#ifdef __QNXNTO__
  131754. + if (!Node->Virtual.contiguous && Node->Virtual.unlockPendings[Kernel->core])
  131755. + {
  131756. + /* Make sure we have a page table. */
  131757. + gcmkASSERT(Node->Virtual.pageTables[Kernel->core] != gcvNULL);
  131758. +
  131759. + /* Remove pending unlock. */
  131760. + Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
  131761. + }
  131762. +
  131763. + /* First lock - create a page table. */
  131764. + gcmkASSERT(Node->Virtual.pageTables[Kernel->core] == gcvNULL);
  131765. +
  131766. + /* Make sure we mark our node as not flushed. */
  131767. + Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
  131768. +#endif
  131769. +
  131770. + locked = gcvTRUE;
  131771. +
  131772. + gcmkONERROR(_NeedVirtualMapping(Kernel, Kernel->core, Node, &needMapping));
  131773. +
  131774. + if (needMapping == gcvFALSE)
  131775. + {
  131776. + /* Get hardware specific address. */
  131777. +#if gcdENABLE_VG
  131778. + if (Kernel->vg != gcvNULL)
  131779. + {
  131780. + gcmkONERROR(gckVGHARDWARE_ConvertLogical(Kernel->vg->hardware,
  131781. + Node->Virtual.logical,
  131782. + &Node->Virtual.addresses[Kernel->core]));
  131783. + }
  131784. + else
  131785. +#endif
  131786. + {
  131787. + gcmkONERROR(gckHARDWARE_ConvertLogical(Kernel->hardware,
  131788. + Node->Virtual.logical,
  131789. + &Node->Virtual.addresses[Kernel->core]));
  131790. + }
  131791. + }
  131792. + else
  131793. + {
  131794. +#if gcdENABLE_VG
  131795. + if (Kernel->vg != gcvNULL)
  131796. + {
  131797. + /* Allocate pages inside the MMU. */
  131798. + gcmkONERROR(
  131799. + gckVGMMU_AllocatePages(Kernel->vg->mmu,
  131800. + Node->Virtual.pageCount,
  131801. + &Node->Virtual.pageTables[Kernel->core],
  131802. + &Node->Virtual.addresses[Kernel->core]));
  131803. + }
  131804. + else
  131805. +#endif
  131806. + {
  131807. + /* Allocate pages inside the MMU. */
  131808. + gcmkONERROR(
  131809. + gckMMU_AllocatePagesEx(Kernel->mmu,
  131810. + Node->Virtual.pageCount,
  131811. + Node->Virtual.type,
  131812. + &Node->Virtual.pageTables[Kernel->core],
  131813. + &Node->Virtual.addresses[Kernel->core]));
  131814. + }
  131815. +
  131816. + Node->Virtual.lockKernels[Kernel->core] = Kernel;
  131817. +
  131818. + /* Map the pages. */
  131819. +#ifdef __QNXNTO__
  131820. + gcmkONERROR(
  131821. + gckOS_MapPagesEx(os,
  131822. + Kernel->core,
  131823. + Node->Virtual.physical,
  131824. + Node->Virtual.logical,
  131825. + Node->Virtual.pageCount,
  131826. + Node->Virtual.pageTables[Kernel->core]));
  131827. +#else
  131828. + gcmkONERROR(
  131829. + gckOS_MapPagesEx(os,
  131830. + Kernel->core,
  131831. + Node->Virtual.physical,
  131832. + Node->Virtual.pageCount,
  131833. + Node->Virtual.pageTables[Kernel->core]));
  131834. +#endif
  131835. +
  131836. +#if gcdENABLE_VG
  131837. + if (Kernel->core == gcvCORE_VG)
  131838. + {
  131839. + gcmkONERROR(gckVGMMU_Flush(Kernel->vg->mmu));
  131840. + }
  131841. + else
  131842. +#endif
  131843. + {
  131844. + gcmkONERROR(gckMMU_Flush(Kernel->mmu));
  131845. + }
  131846. + }
  131847. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131848. + "Mapped virtual node 0x%x to 0x%08X",
  131849. + Node,
  131850. + Node->Virtual.addresses[Kernel->core]);
  131851. + }
  131852. +
  131853. + /* Return hardware address. */
  131854. + *Address = Node->Virtual.addresses[Kernel->core];
  131855. +
  131856. + /* Release the mutex. */
  131857. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  131858. + }
  131859. +
  131860. + /* Success. */
  131861. + gcmkFOOTER_ARG("*Address=%08x", *Address);
  131862. + return gcvSTATUS_OK;
  131863. +
  131864. +OnError:
  131865. + if (locked)
  131866. + {
  131867. + if (Node->Virtual.pageTables[Kernel->core] != gcvNULL)
  131868. + {
  131869. +#if gcdENABLE_VG
  131870. + if (Kernel->vg != gcvNULL)
  131871. + {
  131872. + /* Free the pages from the MMU. */
  131873. + gcmkVERIFY_OK(
  131874. + gckVGMMU_FreePages(Kernel->vg->mmu,
  131875. + Node->Virtual.pageTables[Kernel->core],
  131876. + Node->Virtual.pageCount));
  131877. + }
  131878. + else
  131879. +#endif
  131880. + {
  131881. + /* Free the pages from the MMU. */
  131882. + gcmkVERIFY_OK(
  131883. + gckMMU_FreePages(Kernel->mmu,
  131884. + Node->Virtual.pageTables[Kernel->core],
  131885. + Node->Virtual.pageCount));
  131886. + }
  131887. + Node->Virtual.pageTables[Kernel->core] = gcvNULL;
  131888. + Node->Virtual.lockKernels[Kernel->core] = gcvNULL;
  131889. + }
  131890. +
  131891. + /* Unlock the pages. */
  131892. + gcmkVERIFY_OK(
  131893. + gckOS_UnlockPages(os,
  131894. + Node->Virtual.physical,
  131895. + Node->Virtual.bytes,
  131896. + Node->Virtual.logical
  131897. + ));
  131898. +
  131899. + Node->Virtual.lockeds[Kernel->core]--;
  131900. + }
  131901. +
  131902. + if (acquired)
  131903. + {
  131904. + /* Release the mutex. */
  131905. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  131906. + }
  131907. +
  131908. + /* Return the status. */
  131909. + gcmkFOOTER();
  131910. + return status;
  131911. +}
  131912. +
  131913. +/*******************************************************************************
  131914. +**
  131915. +** gckVIDMEM_Unlock
  131916. +**
  131917. +** Unlock a video memory node.
  131918. +**
  131919. +** INPUT:
  131920. +**
  131921. +** gckKERNEL Kernel
  131922. +** Pointer to an gckKERNEL object.
  131923. +**
  131924. +** gcuVIDMEM_NODE_PTR Node
  131925. +** Pointer to a locked gcuVIDMEM_NODE union.
  131926. +**
  131927. +** gceSURF_TYPE Type
  131928. +** Type of surface to unlock.
  131929. +**
  131930. +** gctBOOL * Asynchroneous
  131931. +** Pointer to a variable specifying whether the surface should be
  131932. +** unlocked asynchroneously or not.
  131933. +**
  131934. +** OUTPUT:
  131935. +**
  131936. +** gctBOOL * Asynchroneous
  131937. +** Pointer to a variable receiving the number of bytes used in the
  131938. +** command buffer specified by 'Commands'. If gcvNULL, there is no
  131939. +** command buffer.
  131940. +*/
  131941. +gceSTATUS
  131942. +gckVIDMEM_Unlock(
  131943. + IN gckKERNEL Kernel,
  131944. + IN gcuVIDMEM_NODE_PTR Node,
  131945. + IN gceSURF_TYPE Type,
  131946. + IN OUT gctBOOL * Asynchroneous
  131947. + )
  131948. +{
  131949. + gceSTATUS status;
  131950. + gckHARDWARE hardware;
  131951. + gctPOINTER buffer;
  131952. + gctSIZE_T requested, bufferSize;
  131953. + gckCOMMAND command = gcvNULL;
  131954. + gceKERNEL_FLUSH flush;
  131955. + gckOS os = gcvNULL;
  131956. + gctBOOL acquired = gcvFALSE;
  131957. + gctBOOL commitEntered = gcvFALSE;
  131958. + gctINT32 i, totalLocked;
  131959. +
  131960. + gcmkHEADER_ARG("Node=0x%x Type=%d *Asynchroneous=%d",
  131961. + Node, Type, gcmOPT_VALUE(Asynchroneous));
  131962. +
  131963. + /* Verify the arguments. */
  131964. + if ((Node == gcvNULL)
  131965. + || (Node->VidMem.memory == gcvNULL)
  131966. + )
  131967. + {
  131968. + /* Invalid object. */
  131969. + gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
  131970. + }
  131971. +
  131972. + /**************************** Video Memory ********************************/
  131973. +
  131974. + if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  131975. + {
  131976. + if (Node->VidMem.locked <= 0)
  131977. + {
  131978. + /* The surface was not locked. */
  131979. + status = gcvSTATUS_MEMORY_UNLOCKED;
  131980. + goto OnError;
  131981. + }
  131982. +
  131983. + /* Decrement the lock count. */
  131984. + Node->VidMem.locked --;
  131985. +
  131986. + if (Asynchroneous != gcvNULL)
  131987. + {
  131988. + /* No need for any events. */
  131989. + *Asynchroneous = gcvFALSE;
  131990. + }
  131991. +
  131992. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  131993. + "Unlocked node 0x%x (%d)",
  131994. + Node,
  131995. + Node->VidMem.locked);
  131996. +
  131997. +#ifdef __QNXNTO__
  131998. + /* Unmap the video memory */
  131999. + if ((Node->VidMem.locked == 0) && (Node->VidMem.logical != gcvNULL))
  132000. + {
  132001. + if (Kernel->core == gcvCORE_VG)
  132002. + {
  132003. + gckKERNEL_UnmapVideoMemory(Kernel,
  132004. + Node->VidMem.logical,
  132005. + Node->VidMem.processID,
  132006. + Node->VidMem.bytes);
  132007. + Node->VidMem.logical = gcvNULL;
  132008. + }
  132009. + }
  132010. +#endif /* __QNXNTO__ */
  132011. +
  132012. + if (Node->VidMem.freePending && (Node->VidMem.locked == 0))
  132013. + {
  132014. + /* Client has unlocked node previously attempted to be freed by compositor. Free now. */
  132015. + Node->VidMem.freePending = gcvFALSE;
  132016. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132017. + "Deferred-freeing Node 0x%x.",
  132018. + Node);
  132019. + gcmkONERROR(gckVIDMEM_Free(Node));
  132020. + }
  132021. + }
  132022. +
  132023. + /*************************** Virtual Memory *******************************/
  132024. +
  132025. + else
  132026. + {
  132027. + /* Verify the gckHARDWARE object pointer. */
  132028. + hardware = Kernel->hardware;
  132029. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  132030. +
  132031. + /* Verify the gckCOMMAND object pointer. */
  132032. + command = Kernel->command;
  132033. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  132034. +
  132035. + /* Get the gckOS object pointer. */
  132036. + os = Kernel->os;
  132037. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  132038. +
  132039. + /* Grab the mutex. */
  132040. + gcmkONERROR(
  132041. + gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
  132042. +
  132043. + acquired = gcvTRUE;
  132044. +
  132045. + if (Asynchroneous == gcvNULL)
  132046. + {
  132047. + if (Node->Virtual.lockeds[Kernel->core] == 0)
  132048. + {
  132049. + status = gcvSTATUS_MEMORY_UNLOCKED;
  132050. + goto OnError;
  132051. + }
  132052. +
  132053. + /* Decrement lock count. */
  132054. + -- Node->Virtual.lockeds[Kernel->core];
  132055. +
  132056. + /* See if we can unlock the resources. */
  132057. + if (Node->Virtual.lockeds[Kernel->core] == 0)
  132058. + {
  132059. + /* Free the page table. */
  132060. + if (Node->Virtual.pageTables[Kernel->core] != gcvNULL)
  132061. + {
  132062. +#if gcdENABLE_VG
  132063. + if (Kernel->vg != gcvNULL)
  132064. + {
  132065. + gcmkONERROR(
  132066. + gckVGMMU_FreePages(Kernel->vg->mmu,
  132067. + Node->Virtual.pageTables[Kernel->core],
  132068. + Node->Virtual.pageCount));
  132069. + }
  132070. + else
  132071. +#endif
  132072. + {
  132073. + gcmkONERROR(
  132074. + gckMMU_FreePages(Kernel->mmu,
  132075. + Node->Virtual.pageTables[Kernel->core],
  132076. + Node->Virtual.pageCount));
  132077. + }
  132078. + /* Mark page table as freed. */
  132079. + Node->Virtual.pageTables[Kernel->core] = gcvNULL;
  132080. + Node->Virtual.lockKernels[Kernel->core] = gcvNULL;
  132081. + }
  132082. +
  132083. +#ifdef __QNXNTO__
  132084. + /* Mark node as unlocked. */
  132085. + Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
  132086. +#endif
  132087. + }
  132088. +
  132089. + for (i = 0, totalLocked = 0; i < gcdMAX_GPU_COUNT; i++)
  132090. + {
  132091. + totalLocked += Node->Virtual.lockeds[i];
  132092. + }
  132093. +
  132094. + if (totalLocked == 0)
  132095. + {
  132096. + /* Owner have already freed this node
  132097. + ** and we are the last one to unlock, do
  132098. + ** real free */
  132099. + if (Node->Virtual.freed)
  132100. + {
  132101. + /* Free the virtual memory. */
  132102. + gcmkVERIFY_OK(gckOS_FreePagedMemory(Kernel->os,
  132103. + Node->Virtual.physical,
  132104. + Node->Virtual.bytes));
  132105. +
  132106. + /* Release mutex before node is destroyed */
  132107. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  132108. +
  132109. + acquired = gcvFALSE;
  132110. +
  132111. + /* Destroy the gcuVIDMEM_NODE union. */
  132112. + gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
  132113. +
  132114. + /* Node has been destroyed, so we should not touch it any more */
  132115. + gcmkFOOTER();
  132116. + return gcvSTATUS_OK;
  132117. + }
  132118. + }
  132119. +
  132120. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132121. + "Unmapped virtual node 0x%x from 0x%08X",
  132122. + Node, Node->Virtual.addresses[Kernel->core]);
  132123. +
  132124. + }
  132125. +
  132126. + else
  132127. + {
  132128. + /* If we need to unlock a node from virtual memory we have to be
  132129. + ** very carefull. If the node is still inside the caches we
  132130. + ** might get a bus error later if the cache line needs to be
  132131. + ** replaced. So - we have to flush the caches before we do
  132132. + ** anything. */
  132133. +
  132134. + /* gckCommand_EnterCommit() can't be called in interrupt handler because
  132135. + ** of a dead lock situation:
  132136. + ** process call Command_Commit(), and acquire Command->mutexQueue in
  132137. + ** gckCOMMAND_EnterCommit(). Then it will wait for a signal which depends
  132138. + ** on interrupt handler to generate, if interrupt handler enter
  132139. + ** gckCommand_EnterCommit(), process will never get the signal. */
  132140. +
  132141. + /* So, flush cache when we still in process context, and then ask caller to
  132142. + ** schedule a event. */
  132143. +
  132144. + gcmkONERROR(
  132145. + gckOS_UnlockPages(os,
  132146. + Node->Virtual.physical,
  132147. + Node->Virtual.bytes,
  132148. + Node->Virtual.logical));
  132149. +
  132150. + if (!Node->Virtual.contiguous
  132151. + && (Node->Virtual.lockeds[Kernel->core] == 1)
  132152. +#if gcdENABLE_VG
  132153. + && (Kernel->vg == gcvNULL)
  132154. +#endif
  132155. + )
  132156. + {
  132157. + if (Type == gcvSURF_BITMAP)
  132158. + {
  132159. + /* Flush 2D cache. */
  132160. + flush = gcvFLUSH_2D;
  132161. + }
  132162. + else if (Type == gcvSURF_RENDER_TARGET)
  132163. + {
  132164. + /* Flush color cache. */
  132165. + flush = gcvFLUSH_COLOR;
  132166. + }
  132167. + else if (Type == gcvSURF_DEPTH)
  132168. + {
  132169. + /* Flush depth cache. */
  132170. + flush = gcvFLUSH_DEPTH;
  132171. + }
  132172. + else
  132173. + {
  132174. + /* No flush required. */
  132175. + flush = (gceKERNEL_FLUSH) 0;
  132176. + }
  132177. + if(hardware)
  132178. + {
  132179. + gcmkONERROR(
  132180. + gckHARDWARE_Flush(hardware, flush, gcvNULL, &requested));
  132181. +
  132182. + if (requested != 0)
  132183. + {
  132184. + /* Acquire the command queue. */
  132185. + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
  132186. + commitEntered = gcvTRUE;
  132187. +
  132188. + gcmkONERROR(gckCOMMAND_Reserve(
  132189. + command, requested, &buffer, &bufferSize
  132190. + ));
  132191. +
  132192. + gcmkONERROR(gckHARDWARE_Flush(
  132193. + hardware, flush, buffer, &bufferSize
  132194. + ));
  132195. +
  132196. + /* Mark node as pending. */
  132197. +#ifdef __QNXNTO__
  132198. + Node->Virtual.unlockPendings[Kernel->core] = gcvTRUE;
  132199. +#endif
  132200. +
  132201. + gcmkONERROR(gckCOMMAND_Execute(command, requested));
  132202. +
  132203. + /* Release the command queue. */
  132204. + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
  132205. + commitEntered = gcvFALSE;
  132206. + }
  132207. + }
  132208. + else
  132209. + {
  132210. + gckOS_Print("Hardware already is freed.\n");
  132211. + }
  132212. + }
  132213. +
  132214. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132215. + "Scheduled unlock for virtual node 0x%x",
  132216. + Node);
  132217. +
  132218. + /* Schedule the surface to be unlocked. */
  132219. + *Asynchroneous = gcvTRUE;
  132220. + }
  132221. +
  132222. + /* Release the mutex. */
  132223. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  132224. +
  132225. + acquired = gcvFALSE;
  132226. + }
  132227. +
  132228. + /* Success. */
  132229. + gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous));
  132230. + return gcvSTATUS_OK;
  132231. +
  132232. +OnError:
  132233. + if (commitEntered)
  132234. + {
  132235. + /* Release the command queue mutex. */
  132236. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, gcvFALSE));
  132237. + }
  132238. +
  132239. + if (acquired)
  132240. + {
  132241. + /* Release the mutex. */
  132242. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  132243. + }
  132244. +
  132245. + /* Return the status. */
  132246. + gcmkFOOTER();
  132247. + return status;
  132248. +}
  132249. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
  132250. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h 1969-12-31 18:00:00.000000000 -0600
  132251. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h 2014-12-08 00:31:53.468418001 -0600
  132252. @@ -0,0 +1,3896 @@
  132253. +/****************************************************************************
  132254. +*
  132255. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  132256. +*
  132257. +* This program is free software; you can redistribute it and/or modify
  132258. +* it under the terms of the GNU General Public License as published by
  132259. +* the Free Software Foundation; either version 2 of the license, or
  132260. +* (at your option) any later version.
  132261. +*
  132262. +* This program is distributed in the hope that it will be useful,
  132263. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  132264. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  132265. +* GNU General Public License for more details.
  132266. +*
  132267. +* You should have received a copy of the GNU General Public License
  132268. +* along with this program; if not write to the Free Software
  132269. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  132270. +*
  132271. +*****************************************************************************/
  132272. +
  132273. +
  132274. +#ifndef __gc_hal_base_h_
  132275. +#define __gc_hal_base_h_
  132276. +
  132277. +#include "gc_hal_enum.h"
  132278. +#include "gc_hal_types.h"
  132279. +
  132280. +#include "gc_hal_dump.h"
  132281. +
  132282. +#ifdef __cplusplus
  132283. +extern "C" {
  132284. +#endif
  132285. +
  132286. +/******************************************************************************\
  132287. +****************************** Object Declarations *****************************
  132288. +\******************************************************************************/
  132289. +
  132290. +typedef struct _gckOS * gckOS;
  132291. +typedef struct _gcoHAL * gcoHAL;
  132292. +typedef struct _gcoOS * gcoOS;
  132293. +typedef struct _gco2D * gco2D;
  132294. +
  132295. +#ifndef VIVANTE_NO_3D
  132296. +typedef struct _gco3D * gco3D;
  132297. +#endif
  132298. +
  132299. +typedef struct _gcoSURF * gcoSURF;
  132300. +typedef struct _gcsSURF_INFO * gcsSURF_INFO_PTR;
  132301. +typedef struct _gcsSURF_NODE * gcsSURF_NODE_PTR;
  132302. +typedef struct _gcsSURF_FORMAT_INFO * gcsSURF_FORMAT_INFO_PTR;
  132303. +typedef struct _gcsPOINT * gcsPOINT_PTR;
  132304. +typedef struct _gcsSIZE * gcsSIZE_PTR;
  132305. +typedef struct _gcsRECT * gcsRECT_PTR;
  132306. +typedef struct _gcsBOUNDARY * gcsBOUNDARY_PTR;
  132307. +typedef struct _gcoDUMP * gcoDUMP;
  132308. +typedef struct _gcoHARDWARE * gcoHARDWARE;
  132309. +typedef union _gcuVIDMEM_NODE * gcuVIDMEM_NODE_PTR;
  132310. +
  132311. +typedef struct gcsATOM * gcsATOM_PTR;
  132312. +
  132313. +#if gcdENABLE_VG
  132314. +typedef struct _gcoVG * gcoVG;
  132315. +typedef struct _gcsCOMPLETION_SIGNAL * gcsCOMPLETION_SIGNAL_PTR;
  132316. +typedef struct _gcsCONTEXT_MAP * gcsCONTEXT_MAP_PTR;
  132317. +#else
  132318. +typedef void * gcoVG;
  132319. +#endif
  132320. +
  132321. +#if gcdSYNC
  132322. +typedef struct _gcoFENCE * gcoFENCE;
  132323. +typedef struct _gcsSYNC_CONTEXT * gcsSYNC_CONTEXT_PTR;
  132324. +#endif
  132325. +
  132326. +typedef struct _gcoOS_SymbolsList gcoOS_SymbolsList;
  132327. +
  132328. +/******************************************************************************\
  132329. +******************************* Process local storage *************************
  132330. +\******************************************************************************/
  132331. +typedef struct _gcsPLS * gcsPLS_PTR;
  132332. +
  132333. +typedef void (* gctPLS_DESTRUCTOR) (
  132334. + gcsPLS_PTR
  132335. + );
  132336. +
  132337. +typedef struct _gcsPLS
  132338. +{
  132339. + /* Global objects. */
  132340. + gcoOS os;
  132341. + gcoHAL hal;
  132342. +
  132343. + /* Internal memory pool. */
  132344. + gctSIZE_T internalSize;
  132345. + gctPHYS_ADDR internalPhysical;
  132346. + gctPOINTER internalLogical;
  132347. +
  132348. + /* External memory pool. */
  132349. + gctSIZE_T externalSize;
  132350. + gctPHYS_ADDR externalPhysical;
  132351. + gctPOINTER externalLogical;
  132352. +
  132353. + /* Contiguous memory pool. */
  132354. + gctSIZE_T contiguousSize;
  132355. + gctPHYS_ADDR contiguousPhysical;
  132356. + gctPOINTER contiguousLogical;
  132357. +
  132358. + /* EGL-specific process-wide objects. */
  132359. + gctPOINTER eglDisplayInfo;
  132360. + gctPOINTER eglSurfaceInfo;
  132361. + gceSURF_FORMAT eglConfigFormat;
  132362. +
  132363. + /* PorcessID of the constrcutor process */
  132364. + gctUINT32 processID;
  132365. +#if gcdFORCE_GAL_LOAD_TWICE
  132366. + /* ThreadID of the constrcutor process. */
  132367. + gctSIZE_T threadID;
  132368. + /* Flag for calling module destructor. */
  132369. + gctBOOL exiting;
  132370. +#endif
  132371. +
  132372. + /* Reference count for destructor. */
  132373. + gcsATOM_PTR reference;
  132374. + gctBOOL bKFS;
  132375. +#if gcdUSE_NPOT_PATCH
  132376. + gctBOOL bNeedSupportNP2Texture;
  132377. +#endif
  132378. +
  132379. + /* Destructor for eglDisplayInfo. */
  132380. + gctPLS_DESTRUCTOR destructor;
  132381. +}
  132382. +gcsPLS;
  132383. +
  132384. +extern gcsPLS gcPLS;
  132385. +
  132386. +/******************************************************************************\
  132387. +******************************* Thread local storage *************************
  132388. +\******************************************************************************/
  132389. +
  132390. +typedef struct _gcsTLS * gcsTLS_PTR;
  132391. +
  132392. +typedef void (* gctTLS_DESTRUCTOR) (
  132393. + gcsTLS_PTR
  132394. + );
  132395. +
  132396. +typedef struct _gcsTLS
  132397. +{
  132398. + gceHARDWARE_TYPE currentType;
  132399. + gcoHARDWARE hardware;
  132400. + /* Only for separated 3D and 2D */
  132401. + gcoHARDWARE hardware2D;
  132402. +#if gcdENABLE_VG
  132403. + gcoVGHARDWARE vg;
  132404. + gcoVG engineVG;
  132405. +#endif /* gcdENABLE_VG */
  132406. + gctPOINTER context;
  132407. + gctTLS_DESTRUCTOR destructor;
  132408. + gctBOOL ProcessExiting;
  132409. +
  132410. +#ifndef VIVANTE_NO_3D
  132411. + gco3D engine3D;
  132412. +#endif
  132413. +#if gcdSYNC
  132414. + gctBOOL fenceEnable;
  132415. +#endif
  132416. + gco2D engine2D;
  132417. + gctBOOL copied;
  132418. +
  132419. +#if gcdFORCE_GAL_LOAD_TWICE
  132420. + /* libGAL.so handle */
  132421. + gctHANDLE handle;
  132422. +#endif
  132423. +}
  132424. +gcsTLS;
  132425. +
  132426. +/******************************************************************************\
  132427. +********************************* Enumerations *********************************
  132428. +\******************************************************************************/
  132429. +
  132430. +typedef enum _gcePLS_VALUE
  132431. +{
  132432. + gcePLS_VALUE_EGL_DISPLAY_INFO,
  132433. + gcePLS_VALUE_EGL_SURFACE_INFO,
  132434. + gcePLS_VALUE_EGL_CONFIG_FORMAT_INFO,
  132435. + gcePLS_VALUE_EGL_DESTRUCTOR_INFO,
  132436. +}
  132437. +gcePLS_VALUE;
  132438. +
  132439. +/* Video memory pool type. */
  132440. +typedef enum _gcePOOL
  132441. +{
  132442. + gcvPOOL_UNKNOWN = 0,
  132443. + gcvPOOL_DEFAULT,
  132444. + gcvPOOL_LOCAL,
  132445. + gcvPOOL_LOCAL_INTERNAL,
  132446. + gcvPOOL_LOCAL_EXTERNAL,
  132447. + gcvPOOL_UNIFIED,
  132448. + gcvPOOL_SYSTEM,
  132449. + gcvPOOL_VIRTUAL,
  132450. + gcvPOOL_USER,
  132451. + gcvPOOL_CONTIGUOUS,
  132452. + gcvPOOL_DEFAULT_FORCE_CONTIGUOUS,
  132453. + gcvPOOL_DEFAULT_FORCE_CONTIGUOUS_CACHEABLE,
  132454. +
  132455. + gcvPOOL_NUMBER_OF_POOLS
  132456. +}
  132457. +gcePOOL;
  132458. +
  132459. +#ifndef VIVANTE_NO_3D
  132460. +/* Blending functions. */
  132461. +typedef enum _gceBLEND_FUNCTION
  132462. +{
  132463. + gcvBLEND_ZERO,
  132464. + gcvBLEND_ONE,
  132465. + gcvBLEND_SOURCE_COLOR,
  132466. + gcvBLEND_INV_SOURCE_COLOR,
  132467. + gcvBLEND_SOURCE_ALPHA,
  132468. + gcvBLEND_INV_SOURCE_ALPHA,
  132469. + gcvBLEND_TARGET_COLOR,
  132470. + gcvBLEND_INV_TARGET_COLOR,
  132471. + gcvBLEND_TARGET_ALPHA,
  132472. + gcvBLEND_INV_TARGET_ALPHA,
  132473. + gcvBLEND_SOURCE_ALPHA_SATURATE,
  132474. + gcvBLEND_CONST_COLOR,
  132475. + gcvBLEND_INV_CONST_COLOR,
  132476. + gcvBLEND_CONST_ALPHA,
  132477. + gcvBLEND_INV_CONST_ALPHA,
  132478. +}
  132479. +gceBLEND_FUNCTION;
  132480. +
  132481. +/* Blending modes. */
  132482. +typedef enum _gceBLEND_MODE
  132483. +{
  132484. + gcvBLEND_ADD,
  132485. + gcvBLEND_SUBTRACT,
  132486. + gcvBLEND_REVERSE_SUBTRACT,
  132487. + gcvBLEND_MIN,
  132488. + gcvBLEND_MAX,
  132489. +}
  132490. +gceBLEND_MODE;
  132491. +
  132492. +/* API flags. */
  132493. +typedef enum _gceAPI
  132494. +{
  132495. + gcvAPI_D3D = 0x1,
  132496. + gcvAPI_OPENGL = 0x2,
  132497. + gcvAPI_OPENVG = 0x3,
  132498. + gcvAPI_OPENCL = 0x4,
  132499. +}
  132500. +gceAPI;
  132501. +
  132502. +/* Depth modes. */
  132503. +typedef enum _gceDEPTH_MODE
  132504. +{
  132505. + gcvDEPTH_NONE,
  132506. + gcvDEPTH_Z,
  132507. + gcvDEPTH_W,
  132508. +}
  132509. +gceDEPTH_MODE;
  132510. +#endif /* VIVANTE_NO_3D */
  132511. +
  132512. +typedef enum _gceWHERE
  132513. +{
  132514. + gcvWHERE_COMMAND,
  132515. + gcvWHERE_RASTER,
  132516. + gcvWHERE_PIXEL,
  132517. +}
  132518. +gceWHERE;
  132519. +
  132520. +typedef enum _gceHOW
  132521. +{
  132522. + gcvHOW_SEMAPHORE = 0x1,
  132523. + gcvHOW_STALL = 0x2,
  132524. + gcvHOW_SEMAPHORE_STALL = 0x3,
  132525. +}
  132526. +gceHOW;
  132527. +
  132528. +typedef enum _gceSignalHandlerType
  132529. +{
  132530. + gcvHANDLE_SIGFPE_WHEN_SIGNAL_CODE_IS_0 = 0x1,
  132531. +}
  132532. +gceSignalHandlerType;
  132533. +
  132534. +
  132535. +#if gcdENABLE_VG
  132536. +/* gcsHAL_Limits*/
  132537. +typedef struct _gcsHAL_LIMITS
  132538. +{
  132539. + /* chip info */
  132540. + gceCHIPMODEL chipModel;
  132541. + gctUINT32 chipRevision;
  132542. + gctUINT32 featureCount;
  132543. + gctUINT32 *chipFeatures;
  132544. +
  132545. + /* target caps */
  132546. + gctUINT32 maxWidth;
  132547. + gctUINT32 maxHeight;
  132548. + gctUINT32 multiTargetCount;
  132549. + gctUINT32 maxSamples;
  132550. +
  132551. +}gcsHAL_LIMITS;
  132552. +#endif
  132553. +
  132554. +/******************************************************************************\
  132555. +*********** Generic Memory Allocation Optimization Using Containers ************
  132556. +\******************************************************************************/
  132557. +
  132558. +/* Generic container definition. */
  132559. +typedef struct _gcsCONTAINER_LINK * gcsCONTAINER_LINK_PTR;
  132560. +typedef struct _gcsCONTAINER_LINK
  132561. +{
  132562. + /* Points to the next container. */
  132563. + gcsCONTAINER_LINK_PTR next;
  132564. +}
  132565. +gcsCONTAINER_LINK;
  132566. +
  132567. +typedef struct _gcsCONTAINER_RECORD * gcsCONTAINER_RECORD_PTR;
  132568. +typedef struct _gcsCONTAINER_RECORD
  132569. +{
  132570. + gcsCONTAINER_RECORD_PTR prev;
  132571. + gcsCONTAINER_RECORD_PTR next;
  132572. +}
  132573. +gcsCONTAINER_RECORD;
  132574. +
  132575. +typedef struct _gcsCONTAINER * gcsCONTAINER_PTR;
  132576. +typedef struct _gcsCONTAINER
  132577. +{
  132578. + gctUINT containerSize;
  132579. + gctUINT recordSize;
  132580. + gctUINT recordCount;
  132581. + gcsCONTAINER_LINK_PTR containers;
  132582. + gcsCONTAINER_RECORD freeList;
  132583. + gcsCONTAINER_RECORD allocList;
  132584. +}
  132585. +gcsCONTAINER;
  132586. +
  132587. +gceSTATUS
  132588. +gcsCONTAINER_Construct(
  132589. + IN gcsCONTAINER_PTR Container,
  132590. + gctUINT RecordsPerContainer,
  132591. + gctUINT RecordSize
  132592. + );
  132593. +
  132594. +gceSTATUS
  132595. +gcsCONTAINER_Destroy(
  132596. + IN gcsCONTAINER_PTR Container
  132597. + );
  132598. +
  132599. +gceSTATUS
  132600. +gcsCONTAINER_AllocateRecord(
  132601. + IN gcsCONTAINER_PTR Container,
  132602. + OUT gctPOINTER * Record
  132603. + );
  132604. +
  132605. +gceSTATUS
  132606. +gcsCONTAINER_FreeRecord(
  132607. + IN gcsCONTAINER_PTR Container,
  132608. + IN gctPOINTER Record
  132609. + );
  132610. +
  132611. +gceSTATUS
  132612. +gcsCONTAINER_FreeAll(
  132613. + IN gcsCONTAINER_PTR Container
  132614. + );
  132615. +
  132616. +/******************************************************************************\
  132617. +********************************* gcoHAL Object *********************************
  132618. +\******************************************************************************/
  132619. +
  132620. +/* Construct a new gcoHAL object. */
  132621. +gceSTATUS
  132622. +gcoHAL_Construct(
  132623. + IN gctPOINTER Context,
  132624. + IN gcoOS Os,
  132625. + OUT gcoHAL * Hal
  132626. + );
  132627. +
  132628. +/* Destroy an gcoHAL object. */
  132629. +gceSTATUS
  132630. +gcoHAL_Destroy(
  132631. + IN gcoHAL Hal
  132632. + );
  132633. +
  132634. +/* Get pointer to gco2D object. */
  132635. +gceSTATUS
  132636. +gcoHAL_Get2DEngine(
  132637. + IN gcoHAL Hal,
  132638. + OUT gco2D * Engine
  132639. + );
  132640. +
  132641. +gceSTATUS
  132642. +gcoHAL_SetFscaleValue(
  132643. + IN gctUINT FscaleValue
  132644. + );
  132645. +
  132646. +gceSTATUS
  132647. +gcoHAL_GetFscaleValue(
  132648. + OUT gctUINT * FscaleValue,
  132649. + OUT gctUINT * MinFscaleValue,
  132650. + OUT gctUINT * MaxFscaleValue
  132651. + );
  132652. +
  132653. +gceSTATUS
  132654. +gcoHAL_SetBltNP2Texture(
  132655. + gctBOOL enable
  132656. + );
  132657. +
  132658. +#ifndef VIVANTE_NO_3D
  132659. +/* Get pointer to gco3D object. */
  132660. +gceSTATUS
  132661. +gcoHAL_Get3DEngine(
  132662. + IN gcoHAL Hal,
  132663. + OUT gco3D * Engine
  132664. + );
  132665. +
  132666. +gceSTATUS
  132667. +gcoHAL_Query3DEngine(
  132668. + IN gcoHAL Hal,
  132669. + OUT gco3D * Engine
  132670. + );
  132671. +
  132672. +gceSTATUS
  132673. +gcoHAL_Set3DEngine(
  132674. + IN gcoHAL Hal,
  132675. + IN gco3D Engine
  132676. + );
  132677. +
  132678. +gceSTATUS
  132679. +gcoHAL_Get3DHardware(
  132680. + IN gcoHAL Hal,
  132681. + OUT gcoHARDWARE * Hardware
  132682. + );
  132683. +
  132684. +gceSTATUS
  132685. +gcoHAL_Set3DHardware(
  132686. + IN gcoHAL Hal,
  132687. + IN gcoHARDWARE Hardware
  132688. + );
  132689. +
  132690. +
  132691. +#endif /* VIVANTE_NO_3D */
  132692. +
  132693. +/* Verify whether the specified feature is available in hardware. */
  132694. +gceSTATUS
  132695. +gcoHAL_IsFeatureAvailable(
  132696. + IN gcoHAL Hal,
  132697. + IN gceFEATURE Feature
  132698. + );
  132699. +
  132700. +/* Query the identity of the hardware. */
  132701. +gceSTATUS
  132702. +gcoHAL_QueryChipIdentity(
  132703. + IN gcoHAL Hal,
  132704. + OUT gceCHIPMODEL* ChipModel,
  132705. + OUT gctUINT32* ChipRevision,
  132706. + OUT gctUINT32* ChipFeatures,
  132707. + OUT gctUINT32* ChipMinorFeatures
  132708. + );
  132709. +
  132710. +/* Query the minor features of the hardware. */
  132711. +gceSTATUS gcoHAL_QueryChipMinorFeatures(
  132712. + IN gcoHAL Hal,
  132713. + OUT gctUINT32* NumFeatures,
  132714. + OUT gctUINT32* ChipMinorFeatures
  132715. + );
  132716. +
  132717. +/* Query the amount of video memory. */
  132718. +gceSTATUS
  132719. +gcoHAL_QueryVideoMemory(
  132720. + IN gcoHAL Hal,
  132721. + OUT gctPHYS_ADDR * InternalAddress,
  132722. + OUT gctSIZE_T * InternalSize,
  132723. + OUT gctPHYS_ADDR * ExternalAddress,
  132724. + OUT gctSIZE_T * ExternalSize,
  132725. + OUT gctPHYS_ADDR * ContiguousAddress,
  132726. + OUT gctSIZE_T * ContiguousSize
  132727. + );
  132728. +
  132729. +/* Map video memory. */
  132730. +gceSTATUS
  132731. +gcoHAL_MapMemory(
  132732. + IN gcoHAL Hal,
  132733. + IN gctPHYS_ADDR Physical,
  132734. + IN gctSIZE_T NumberOfBytes,
  132735. + OUT gctPOINTER * Logical
  132736. + );
  132737. +
  132738. +/* Unmap video memory. */
  132739. +gceSTATUS
  132740. +gcoHAL_UnmapMemory(
  132741. + IN gcoHAL Hal,
  132742. + IN gctPHYS_ADDR Physical,
  132743. + IN gctSIZE_T NumberOfBytes,
  132744. + IN gctPOINTER Logical
  132745. + );
  132746. +
  132747. +/* Schedule an unmap of a buffer mapped through its physical address. */
  132748. +gceSTATUS
  132749. +gcoHAL_ScheduleUnmapMemory(
  132750. + IN gcoHAL Hal,
  132751. + IN gctPHYS_ADDR Physical,
  132752. + IN gctSIZE_T NumberOfBytes,
  132753. + IN gctPOINTER Logical
  132754. + );
  132755. +
  132756. +/* Map user memory. */
  132757. +gceSTATUS
  132758. +gcoHAL_MapUserMemory(
  132759. + IN gctPOINTER Logical,
  132760. + IN gctUINT32 Physical,
  132761. + IN gctSIZE_T Size,
  132762. + OUT gctPOINTER * Info,
  132763. + OUT gctUINT32_PTR GPUAddress
  132764. + );
  132765. +
  132766. +/* Unmap user memory. */
  132767. +gceSTATUS
  132768. +gcoHAL_UnmapUserMemory(
  132769. + IN gctPOINTER Logical,
  132770. + IN gctSIZE_T Size,
  132771. + IN gctPOINTER Info,
  132772. + IN gctUINT32 GPUAddress
  132773. + );
  132774. +
  132775. +/* Schedule an unmap of a user buffer using event mechanism. */
  132776. +gceSTATUS
  132777. +gcoHAL_ScheduleUnmapUserMemory(
  132778. + IN gcoHAL Hal,
  132779. + IN gctPOINTER Info,
  132780. + IN gctSIZE_T Size,
  132781. + IN gctUINT32 Address,
  132782. + IN gctPOINTER Memory
  132783. + );
  132784. +
  132785. +/* Commit the current command buffer. */
  132786. +gceSTATUS
  132787. +gcoHAL_Commit(
  132788. + IN gcoHAL Hal,
  132789. + IN gctBOOL Stall
  132790. + );
  132791. +
  132792. +/* Query the tile capabilities. */
  132793. +gceSTATUS
  132794. +gcoHAL_QueryTiled(
  132795. + IN gcoHAL Hal,
  132796. + OUT gctINT32 * TileWidth2D,
  132797. + OUT gctINT32 * TileHeight2D,
  132798. + OUT gctINT32 * TileWidth3D,
  132799. + OUT gctINT32 * TileHeight3D
  132800. + );
  132801. +
  132802. +gceSTATUS
  132803. +gcoHAL_Compact(
  132804. + IN gcoHAL Hal
  132805. + );
  132806. +
  132807. +#if VIVANTE_PROFILER
  132808. +gceSTATUS
  132809. +gcoHAL_ProfileStart(
  132810. + IN gcoHAL Hal
  132811. + );
  132812. +
  132813. +gceSTATUS
  132814. +gcoHAL_ProfileEnd(
  132815. + IN gcoHAL Hal,
  132816. + IN gctCONST_STRING Title
  132817. + );
  132818. +#endif
  132819. +
  132820. +/* Power Management */
  132821. +gceSTATUS
  132822. +gcoHAL_SetPowerManagementState(
  132823. + IN gcoHAL Hal,
  132824. + IN gceCHIPPOWERSTATE State
  132825. + );
  132826. +
  132827. +gceSTATUS
  132828. +gcoHAL_QueryPowerManagementState(
  132829. + IN gcoHAL Hal,
  132830. + OUT gceCHIPPOWERSTATE *State
  132831. + );
  132832. +
  132833. +/* Set the filter type for filter blit. */
  132834. +gceSTATUS
  132835. +gcoHAL_SetFilterType(
  132836. + IN gcoHAL Hal,
  132837. + IN gceFILTER_TYPE FilterType
  132838. + );
  132839. +
  132840. +gceSTATUS
  132841. +gcoHAL_GetDump(
  132842. + IN gcoHAL Hal,
  132843. + OUT gcoDUMP * Dump
  132844. + );
  132845. +
  132846. +/* Call the kernel HAL layer. */
  132847. +gceSTATUS
  132848. +gcoHAL_Call(
  132849. + IN gcoHAL Hal,
  132850. + IN OUT gcsHAL_INTERFACE_PTR Interface
  132851. + );
  132852. +
  132853. +gceSTATUS
  132854. +gcoHAL_GetPatchID(
  132855. + IN gcoHAL Hal,
  132856. + OUT gcePATCH_ID * PatchID
  132857. + );
  132858. +
  132859. +/* Schedule an event. */
  132860. +gceSTATUS
  132861. +gcoHAL_ScheduleEvent(
  132862. + IN gcoHAL Hal,
  132863. + IN OUT gcsHAL_INTERFACE_PTR Interface
  132864. + );
  132865. +
  132866. +/* Destroy a surface. */
  132867. +gceSTATUS
  132868. +gcoHAL_DestroySurface(
  132869. + IN gcoHAL Hal,
  132870. + IN gcoSURF Surface
  132871. + );
  132872. +
  132873. +/* Request a start/stop timestamp. */
  132874. +gceSTATUS
  132875. +gcoHAL_SetTimer(
  132876. + IN gcoHAL Hal,
  132877. + IN gctUINT32 Index,
  132878. + IN gctBOOL Start
  132879. + );
  132880. +
  132881. +/* Get Time delta from a Timer in microseconds. */
  132882. +gceSTATUS
  132883. +gcoHAL_GetTimerTime(
  132884. + IN gcoHAL Hal,
  132885. + IN gctUINT32 Timer,
  132886. + OUT gctINT32_PTR TimeDelta
  132887. + );
  132888. +
  132889. +/* set timeout value. */
  132890. +gceSTATUS
  132891. +gcoHAL_SetTimeOut(
  132892. + IN gcoHAL Hal,
  132893. + IN gctUINT32 timeOut
  132894. + );
  132895. +
  132896. +gceSTATUS
  132897. +gcoHAL_SetHardwareType(
  132898. + IN gcoHAL Hal,
  132899. + IN gceHARDWARE_TYPE HardwardType
  132900. + );
  132901. +
  132902. +gceSTATUS
  132903. +gcoHAL_GetHardwareType(
  132904. + IN gcoHAL Hal,
  132905. + OUT gceHARDWARE_TYPE * HardwardType
  132906. + );
  132907. +
  132908. +gceSTATUS
  132909. +gcoHAL_QueryChipCount(
  132910. + IN gcoHAL Hal,
  132911. + OUT gctINT32 * Count
  132912. + );
  132913. +
  132914. +gceSTATUS
  132915. +gcoHAL_QuerySeparated3D2D(
  132916. + IN gcoHAL Hal
  132917. + );
  132918. +
  132919. +gceSTATUS
  132920. +gcoHAL_QuerySpecialHint(
  132921. + IN gceSPECIAL_HINT Hint
  132922. + );
  132923. +
  132924. +gceSTATUS
  132925. +gcoHAL_SetSpecialHintData(
  132926. + IN gcoHARDWARE Hardware
  132927. + );
  132928. +
  132929. +/* Get pointer to gcoVG object. */
  132930. +gceSTATUS
  132931. +gcoHAL_GetVGEngine(
  132932. + IN gcoHAL Hal,
  132933. + OUT gcoVG * Engine
  132934. + );
  132935. +
  132936. +#if gcdENABLE_VG
  132937. +gceSTATUS
  132938. +gcoHAL_QueryChipLimits(
  132939. + IN gcoHAL Hal,
  132940. + IN gctINT32 Chip,
  132941. + OUT gcsHAL_LIMITS *Limits);
  132942. +
  132943. +gceSTATUS
  132944. +gcoHAL_QueryChipFeature(
  132945. + IN gcoHAL Hal,
  132946. + IN gctINT32 Chip,
  132947. + IN gceFEATURE Feature);
  132948. +
  132949. +#endif
  132950. +/******************************************************************************\
  132951. +********************************** gcoOS Object *********************************
  132952. +\******************************************************************************/
  132953. +
  132954. +/* Get PLS value for given key */
  132955. +gctPOINTER
  132956. +gcoOS_GetPLSValue(
  132957. + IN gcePLS_VALUE key
  132958. + );
  132959. +
  132960. +/* Set PLS value of a given key */
  132961. +void
  132962. +gcoOS_SetPLSValue(
  132963. + IN gcePLS_VALUE key,
  132964. + OUT gctPOINTER value
  132965. + );
  132966. +
  132967. +/* Get access to the thread local storage. */
  132968. +gceSTATUS
  132969. +gcoOS_GetTLS(
  132970. + OUT gcsTLS_PTR * TLS
  132971. + );
  132972. +
  132973. + /* Copy the TLS from a source thread. */
  132974. + gceSTATUS gcoOS_CopyTLS(IN gcsTLS_PTR Source);
  132975. +
  132976. +/* Destroy the objects associated with the current thread. */
  132977. +void
  132978. +gcoOS_FreeThreadData(
  132979. + IN gctBOOL ProcessExiting
  132980. + );
  132981. +
  132982. +/* Construct a new gcoOS object. */
  132983. +gceSTATUS
  132984. +gcoOS_Construct(
  132985. + IN gctPOINTER Context,
  132986. + OUT gcoOS * Os
  132987. + );
  132988. +
  132989. +/* Destroy an gcoOS object. */
  132990. +gceSTATUS
  132991. +gcoOS_Destroy(
  132992. + IN gcoOS Os
  132993. + );
  132994. +
  132995. +/* Get the base address for the physical memory. */
  132996. +gceSTATUS
  132997. +gcoOS_GetBaseAddress(
  132998. + IN gcoOS Os,
  132999. + OUT gctUINT32_PTR BaseAddress
  133000. + );
  133001. +
  133002. +/* Allocate memory from the heap. */
  133003. +gceSTATUS
  133004. +gcoOS_Allocate(
  133005. + IN gcoOS Os,
  133006. + IN gctSIZE_T Bytes,
  133007. + OUT gctPOINTER * Memory
  133008. + );
  133009. +
  133010. +/* Get allocated memory size. */
  133011. +gceSTATUS
  133012. +gcoOS_GetMemorySize(
  133013. + IN gcoOS Os,
  133014. + IN gctPOINTER Memory,
  133015. + OUT gctSIZE_T_PTR MemorySize
  133016. + );
  133017. +
  133018. +/* Free allocated memory. */
  133019. +gceSTATUS
  133020. +gcoOS_Free(
  133021. + IN gcoOS Os,
  133022. + IN gctPOINTER Memory
  133023. + );
  133024. +
  133025. +/* Allocate memory. */
  133026. +gceSTATUS
  133027. +gcoOS_AllocateMemory(
  133028. + IN gcoOS Os,
  133029. + IN gctSIZE_T Bytes,
  133030. + OUT gctPOINTER * Memory
  133031. + );
  133032. +
  133033. +/* Free memory. */
  133034. +gceSTATUS
  133035. +gcoOS_FreeMemory(
  133036. + IN gcoOS Os,
  133037. + IN gctPOINTER Memory
  133038. + );
  133039. +
  133040. +/* Allocate contiguous memory. */
  133041. +gceSTATUS
  133042. +gcoOS_AllocateContiguous(
  133043. + IN gcoOS Os,
  133044. + IN gctBOOL InUserSpace,
  133045. + IN OUT gctSIZE_T * Bytes,
  133046. + OUT gctPHYS_ADDR * Physical,
  133047. + OUT gctPOINTER * Logical
  133048. + );
  133049. +
  133050. +/* Free contiguous memory. */
  133051. +gceSTATUS
  133052. +gcoOS_FreeContiguous(
  133053. + IN gcoOS Os,
  133054. + IN gctPHYS_ADDR Physical,
  133055. + IN gctPOINTER Logical,
  133056. + IN gctSIZE_T Bytes
  133057. + );
  133058. +
  133059. +/* Allocate video memory. */
  133060. +gceSTATUS
  133061. +gcoOS_AllocateVideoMemory(
  133062. + IN gcoOS Os,
  133063. + IN gctBOOL InUserSpace,
  133064. + IN gctBOOL InCacheable,
  133065. + IN OUT gctSIZE_T * Bytes,
  133066. + OUT gctUINT32 * Physical,
  133067. + OUT gctPOINTER * Logical,
  133068. + OUT gctPOINTER * Handle
  133069. + );
  133070. +
  133071. +/* Free video memory. */
  133072. +gceSTATUS
  133073. +gcoOS_FreeVideoMemory(
  133074. + IN gcoOS Os,
  133075. + IN gctPOINTER Handle
  133076. + );
  133077. +
  133078. +gceSTATUS
  133079. +gcoSURF_GetBankOffsetBytes(
  133080. + IN gcoSURF Surfce,
  133081. + IN gceSURF_TYPE Type,
  133082. + IN gctUINT32 Stride,
  133083. + IN gctUINT32_PTR Bytes
  133084. + );
  133085. +
  133086. +/* Map user memory. */
  133087. +gceSTATUS
  133088. +gcoOS_MapUserMemory(
  133089. + IN gcoOS Os,
  133090. + IN gctPOINTER Memory,
  133091. + IN gctSIZE_T Size,
  133092. + OUT gctPOINTER * Info,
  133093. + OUT gctUINT32_PTR Address
  133094. + );
  133095. +
  133096. +/* Map user memory. */
  133097. +gceSTATUS
  133098. +gcoOS_MapUserMemoryEx(
  133099. + IN gcoOS Os,
  133100. + IN gctPOINTER Memory,
  133101. + IN gctUINT32 Physical,
  133102. + IN gctSIZE_T Size,
  133103. + OUT gctPOINTER * Info,
  133104. + OUT gctUINT32_PTR Address
  133105. + );
  133106. +
  133107. +/* Unmap user memory. */
  133108. +gceSTATUS
  133109. +gcoOS_UnmapUserMemory(
  133110. + IN gcoOS Os,
  133111. + IN gctPOINTER Memory,
  133112. + IN gctSIZE_T Size,
  133113. + IN gctPOINTER Info,
  133114. + IN gctUINT32 Address
  133115. + );
  133116. +
  133117. +/* Device I/O Control call to the kernel HAL layer. */
  133118. +gceSTATUS
  133119. +gcoOS_DeviceControl(
  133120. + IN gcoOS Os,
  133121. + IN gctUINT32 IoControlCode,
  133122. + IN gctPOINTER InputBuffer,
  133123. + IN gctSIZE_T InputBufferSize,
  133124. + IN gctPOINTER OutputBuffer,
  133125. + IN gctSIZE_T OutputBufferSize
  133126. + );
  133127. +
  133128. +/* Allocate non paged memory. */
  133129. +gceSTATUS
  133130. +gcoOS_AllocateNonPagedMemory(
  133131. + IN gcoOS Os,
  133132. + IN gctBOOL InUserSpace,
  133133. + IN OUT gctSIZE_T * Bytes,
  133134. + OUT gctPHYS_ADDR * Physical,
  133135. + OUT gctPOINTER * Logical
  133136. + );
  133137. +
  133138. +/* Free non paged memory. */
  133139. +gceSTATUS
  133140. +gcoOS_FreeNonPagedMemory(
  133141. + IN gcoOS Os,
  133142. + IN gctSIZE_T Bytes,
  133143. + IN gctPHYS_ADDR Physical,
  133144. + IN gctPOINTER Logical
  133145. + );
  133146. +
  133147. +#define gcmOS_SAFE_FREE(os, mem) \
  133148. + gcoOS_Free(os, mem); \
  133149. + mem = gcvNULL
  133150. +
  133151. +#define gcmkOS_SAFE_FREE(os, mem) \
  133152. + gckOS_Free(os, mem); \
  133153. + mem = gcvNULL
  133154. +
  133155. +typedef enum _gceFILE_MODE
  133156. +{
  133157. + gcvFILE_CREATE = 0,
  133158. + gcvFILE_APPEND,
  133159. + gcvFILE_READ,
  133160. + gcvFILE_CREATETEXT,
  133161. + gcvFILE_APPENDTEXT,
  133162. + gcvFILE_READTEXT,
  133163. +}
  133164. +gceFILE_MODE;
  133165. +
  133166. +/* Open a file. */
  133167. +gceSTATUS
  133168. +gcoOS_Open(
  133169. + IN gcoOS Os,
  133170. + IN gctCONST_STRING FileName,
  133171. + IN gceFILE_MODE Mode,
  133172. + OUT gctFILE * File
  133173. + );
  133174. +
  133175. +/* Close a file. */
  133176. +gceSTATUS
  133177. +gcoOS_Close(
  133178. + IN gcoOS Os,
  133179. + IN gctFILE File
  133180. + );
  133181. +
  133182. +/* Read data from a file. */
  133183. +gceSTATUS
  133184. +gcoOS_Read(
  133185. + IN gcoOS Os,
  133186. + IN gctFILE File,
  133187. + IN gctSIZE_T ByteCount,
  133188. + IN gctPOINTER Data,
  133189. + OUT gctSIZE_T * ByteRead
  133190. + );
  133191. +
  133192. +/* Write data to a file. */
  133193. +gceSTATUS
  133194. +gcoOS_Write(
  133195. + IN gcoOS Os,
  133196. + IN gctFILE File,
  133197. + IN gctSIZE_T ByteCount,
  133198. + IN gctCONST_POINTER Data
  133199. + );
  133200. +
  133201. +/* Flush data to a file. */
  133202. +gceSTATUS
  133203. +gcoOS_Flush(
  133204. + IN gcoOS Os,
  133205. + IN gctFILE File
  133206. + );
  133207. +
  133208. +/* Close a file descriptor. */
  133209. +gceSTATUS
  133210. +gcoOS_CloseFD(
  133211. + IN gcoOS Os,
  133212. + IN gctINT FD
  133213. + );
  133214. +
  133215. +/* Dup file descriptor to another. */
  133216. +gceSTATUS
  133217. +gcoOS_DupFD(
  133218. + IN gcoOS Os,
  133219. + IN gctINT FD,
  133220. + OUT gctINT * FD2
  133221. + );
  133222. +
  133223. +/* Create an endpoint for communication. */
  133224. +gceSTATUS
  133225. +gcoOS_Socket(
  133226. + IN gcoOS Os,
  133227. + IN gctINT Domain,
  133228. + IN gctINT Type,
  133229. + IN gctINT Protocol,
  133230. + OUT gctINT *SockFd
  133231. + );
  133232. +
  133233. +/* Close a socket. */
  133234. +gceSTATUS
  133235. +gcoOS_CloseSocket(
  133236. + IN gcoOS Os,
  133237. + IN gctINT SockFd
  133238. + );
  133239. +
  133240. +/* Initiate a connection on a socket. */
  133241. +gceSTATUS
  133242. +gcoOS_Connect(
  133243. + IN gcoOS Os,
  133244. + IN gctINT SockFd,
  133245. + IN gctCONST_POINTER HostName,
  133246. + IN gctUINT Port);
  133247. +
  133248. +/* Shut down part of connection on a socket. */
  133249. +gceSTATUS
  133250. +gcoOS_Shutdown(
  133251. + IN gcoOS Os,
  133252. + IN gctINT SockFd,
  133253. + IN gctINT How
  133254. + );
  133255. +
  133256. +/* Send a message on a socket. */
  133257. +gceSTATUS
  133258. +gcoOS_Send(
  133259. + IN gcoOS Os,
  133260. + IN gctINT SockFd,
  133261. + IN gctSIZE_T ByteCount,
  133262. + IN gctCONST_POINTER Data,
  133263. + IN gctINT Flags
  133264. + );
  133265. +
  133266. +/* Initiate a connection on a socket. */
  133267. +gceSTATUS
  133268. +gcoOS_WaitForSend(
  133269. + IN gcoOS Os,
  133270. + IN gctINT SockFd,
  133271. + IN gctINT Seconds,
  133272. + IN gctINT MicroSeconds);
  133273. +
  133274. +/* Get environment variable value. */
  133275. +gceSTATUS
  133276. +gcoOS_GetEnv(
  133277. + IN gcoOS Os,
  133278. + IN gctCONST_STRING VarName,
  133279. + OUT gctSTRING * Value
  133280. + );
  133281. +
  133282. +/* Set environment variable value. */
  133283. +gceSTATUS
  133284. +gcoOS_SetEnv(
  133285. + IN gcoOS Os,
  133286. + IN gctCONST_STRING VarName,
  133287. + IN gctSTRING Value
  133288. + );
  133289. +
  133290. +/* Get current working directory. */
  133291. +gceSTATUS
  133292. +gcoOS_GetCwd(
  133293. + IN gcoOS Os,
  133294. + IN gctINT SizeInBytes,
  133295. + OUT gctSTRING Buffer
  133296. + );
  133297. +
  133298. +/* Get file status info. */
  133299. +gceSTATUS
  133300. +gcoOS_Stat(
  133301. + IN gcoOS Os,
  133302. + IN gctCONST_STRING FileName,
  133303. + OUT gctPOINTER Buffer
  133304. + );
  133305. +
  133306. +typedef enum _gceFILE_WHENCE
  133307. +{
  133308. + gcvFILE_SEEK_SET,
  133309. + gcvFILE_SEEK_CUR,
  133310. + gcvFILE_SEEK_END
  133311. +}
  133312. +gceFILE_WHENCE;
  133313. +
  133314. +/* Set the current position of a file. */
  133315. +gceSTATUS
  133316. +gcoOS_Seek(
  133317. + IN gcoOS Os,
  133318. + IN gctFILE File,
  133319. + IN gctUINT32 Offset,
  133320. + IN gceFILE_WHENCE Whence
  133321. + );
  133322. +
  133323. +/* Set the current position of a file. */
  133324. +gceSTATUS
  133325. +gcoOS_SetPos(
  133326. + IN gcoOS Os,
  133327. + IN gctFILE File,
  133328. + IN gctUINT32 Position
  133329. + );
  133330. +
  133331. +/* Get the current position of a file. */
  133332. +gceSTATUS
  133333. +gcoOS_GetPos(
  133334. + IN gcoOS Os,
  133335. + IN gctFILE File,
  133336. + OUT gctUINT32 * Position
  133337. + );
  133338. +
  133339. +/* Same as strstr. */
  133340. +gceSTATUS
  133341. +gcoOS_StrStr(
  133342. + IN gctCONST_STRING String,
  133343. + IN gctCONST_STRING SubString,
  133344. + OUT gctSTRING * Output
  133345. + );
  133346. +
  133347. +/* Find the last occurance of a character inside a string. */
  133348. +gceSTATUS
  133349. +gcoOS_StrFindReverse(
  133350. + IN gctCONST_STRING String,
  133351. + IN gctINT8 Character,
  133352. + OUT gctSTRING * Output
  133353. + );
  133354. +
  133355. +gceSTATUS
  133356. +gcoOS_StrDup(
  133357. + IN gcoOS Os,
  133358. + IN gctCONST_STRING String,
  133359. + OUT gctSTRING * Target
  133360. + );
  133361. +
  133362. +/* Copy a string. */
  133363. +gceSTATUS
  133364. +gcoOS_StrCopySafe(
  133365. + IN gctSTRING Destination,
  133366. + IN gctSIZE_T DestinationSize,
  133367. + IN gctCONST_STRING Source
  133368. + );
  133369. +
  133370. +/* Append a string. */
  133371. +gceSTATUS
  133372. +gcoOS_StrCatSafe(
  133373. + IN gctSTRING Destination,
  133374. + IN gctSIZE_T DestinationSize,
  133375. + IN gctCONST_STRING Source
  133376. + );
  133377. +
  133378. +/* Compare two strings. */
  133379. +gceSTATUS
  133380. +gcoOS_StrCmp(
  133381. + IN gctCONST_STRING String1,
  133382. + IN gctCONST_STRING String2
  133383. + );
  133384. +
  133385. +/* Compare characters of two strings. */
  133386. +gceSTATUS
  133387. +gcoOS_StrNCmp(
  133388. + IN gctCONST_STRING String1,
  133389. + IN gctCONST_STRING String2,
  133390. + IN gctSIZE_T Count
  133391. + );
  133392. +
  133393. +/* Convert string to float. */
  133394. +gceSTATUS
  133395. +gcoOS_StrToFloat(
  133396. + IN gctCONST_STRING String,
  133397. + OUT gctFLOAT * Float
  133398. + );
  133399. +
  133400. +/* Convert hex string to integer. */
  133401. +gceSTATUS
  133402. +gcoOS_HexStrToInt(
  133403. + IN gctCONST_STRING String,
  133404. + OUT gctINT * Int
  133405. + );
  133406. +
  133407. +/* Convert hex string to float. */
  133408. +gceSTATUS
  133409. +gcoOS_HexStrToFloat(
  133410. + IN gctCONST_STRING String,
  133411. + OUT gctFLOAT * Float
  133412. + );
  133413. +
  133414. +/* Convert string to integer. */
  133415. +gceSTATUS
  133416. +gcoOS_StrToInt(
  133417. + IN gctCONST_STRING String,
  133418. + OUT gctINT * Int
  133419. + );
  133420. +
  133421. +gceSTATUS
  133422. +gcoOS_MemCmp(
  133423. + IN gctCONST_POINTER Memory1,
  133424. + IN gctCONST_POINTER Memory2,
  133425. + IN gctSIZE_T Bytes
  133426. + );
  133427. +
  133428. +gceSTATUS
  133429. +gcoOS_PrintStrSafe(
  133430. + OUT gctSTRING String,
  133431. + IN gctSIZE_T StringSize,
  133432. + IN OUT gctUINT * Offset,
  133433. + IN gctCONST_STRING Format,
  133434. + ...
  133435. + );
  133436. +
  133437. +gceSTATUS
  133438. +gcoOS_LoadLibrary(
  133439. + IN gcoOS Os,
  133440. + IN gctCONST_STRING Library,
  133441. + OUT gctHANDLE * Handle
  133442. + );
  133443. +
  133444. +gceSTATUS
  133445. +gcoOS_FreeLibrary(
  133446. + IN gcoOS Os,
  133447. + IN gctHANDLE Handle
  133448. + );
  133449. +
  133450. +gceSTATUS
  133451. +gcoOS_GetProcAddress(
  133452. + IN gcoOS Os,
  133453. + IN gctHANDLE Handle,
  133454. + IN gctCONST_STRING Name,
  133455. + OUT gctPOINTER * Function
  133456. + );
  133457. +
  133458. +gceSTATUS
  133459. +gcoOS_Compact(
  133460. + IN gcoOS Os
  133461. + );
  133462. +
  133463. +gceSTATUS
  133464. +gcoOS_AddSignalHandler (
  133465. + IN gceSignalHandlerType SignalHandlerType
  133466. + );
  133467. +
  133468. +#if VIVANTE_PROFILER
  133469. +gceSTATUS
  133470. +gcoOS_ProfileStart(
  133471. + IN gcoOS Os
  133472. + );
  133473. +
  133474. +gceSTATUS
  133475. +gcoOS_ProfileEnd(
  133476. + IN gcoOS Os,
  133477. + IN gctCONST_STRING Title
  133478. + );
  133479. +
  133480. +gceSTATUS
  133481. +gcoOS_SetProfileSetting(
  133482. + IN gcoOS Os,
  133483. + IN gctBOOL Enable,
  133484. + IN gctCONST_STRING FileName
  133485. + );
  133486. +#endif
  133487. +
  133488. +gctBOOL
  133489. +gcoOS_IsNeededSupportNP2Texture(
  133490. + IN gctCHAR* ProcName
  133491. + );
  133492. +
  133493. +/* Query the video memory. */
  133494. +gceSTATUS
  133495. +gcoOS_QueryVideoMemory(
  133496. + IN gcoOS Os,
  133497. + OUT gctPHYS_ADDR * InternalAddress,
  133498. + OUT gctSIZE_T * InternalSize,
  133499. + OUT gctPHYS_ADDR * ExternalAddress,
  133500. + OUT gctSIZE_T * ExternalSize,
  133501. + OUT gctPHYS_ADDR * ContiguousAddress,
  133502. + OUT gctSIZE_T * ContiguousSize
  133503. + );
  133504. +
  133505. +/* Detect if the process is the executable specified. */
  133506. +gceSTATUS
  133507. +gcoOS_DetectProcessByNamePid(
  133508. + IN gctCONST_STRING Name,
  133509. + IN gctHANDLE Pid
  133510. + );
  133511. +
  133512. +/* Detect if the current process is the executable specified. */
  133513. +gceSTATUS
  133514. +gcoOS_DetectProcessByName(
  133515. + IN gctCONST_STRING Name
  133516. + );
  133517. +
  133518. +gceSTATUS
  133519. +gcoOS_DetectProcessByEncryptedName(
  133520. + IN gctCONST_STRING Name
  133521. + );
  133522. +
  133523. +#if defined(ANDROID)
  133524. +gceSTATUS
  133525. +gcoOS_DetectProgrameByEncryptedSymbols(
  133526. + IN gcoOS_SymbolsList Symbols
  133527. + );
  133528. +#endif
  133529. +
  133530. +/*----------------------------------------------------------------------------*/
  133531. +/*----- Atoms ----------------------------------------------------------------*/
  133532. +
  133533. +/* Construct an atom. */
  133534. +gceSTATUS
  133535. +gcoOS_AtomConstruct(
  133536. + IN gcoOS Os,
  133537. + OUT gcsATOM_PTR * Atom
  133538. + );
  133539. +
  133540. +/* Destroy an atom. */
  133541. +gceSTATUS
  133542. +gcoOS_AtomDestroy(
  133543. + IN gcoOS Os,
  133544. + IN gcsATOM_PTR Atom
  133545. + );
  133546. +
  133547. +/* Increment an atom. */
  133548. +gceSTATUS
  133549. +gcoOS_AtomIncrement(
  133550. + IN gcoOS Os,
  133551. + IN gcsATOM_PTR Atom,
  133552. + OUT gctINT32_PTR OldValue
  133553. + );
  133554. +
  133555. +/* Decrement an atom. */
  133556. +gceSTATUS
  133557. +gcoOS_AtomDecrement(
  133558. + IN gcoOS Os,
  133559. + IN gcsATOM_PTR Atom,
  133560. + OUT gctINT32_PTR OldValue
  133561. + );
  133562. +
  133563. +gctHANDLE
  133564. +gcoOS_GetCurrentProcessID(
  133565. + void
  133566. + );
  133567. +
  133568. +gctHANDLE
  133569. +gcoOS_GetCurrentThreadID(
  133570. + void
  133571. + );
  133572. +
  133573. +/*----------------------------------------------------------------------------*/
  133574. +/*----- Time -----------------------------------------------------------------*/
  133575. +
  133576. +/* Get the number of milliseconds since the system started. */
  133577. +gctUINT32
  133578. +gcoOS_GetTicks(
  133579. + void
  133580. + );
  133581. +
  133582. +/* Get time in microseconds. */
  133583. +gceSTATUS
  133584. +gcoOS_GetTime(
  133585. + gctUINT64_PTR Time
  133586. + );
  133587. +
  133588. +/* Get CPU usage in microseconds. */
  133589. +gceSTATUS
  133590. +gcoOS_GetCPUTime(
  133591. + gctUINT64_PTR CPUTime
  133592. + );
  133593. +
  133594. +/* Get memory usage. */
  133595. +gceSTATUS
  133596. +gcoOS_GetMemoryUsage(
  133597. + gctUINT32_PTR MaxRSS,
  133598. + gctUINT32_PTR IxRSS,
  133599. + gctUINT32_PTR IdRSS,
  133600. + gctUINT32_PTR IsRSS
  133601. + );
  133602. +
  133603. +/* Delay a number of microseconds. */
  133604. +gceSTATUS
  133605. +gcoOS_Delay(
  133606. + IN gcoOS Os,
  133607. + IN gctUINT32 Delay
  133608. + );
  133609. +
  133610. +/*----------------------------------------------------------------------------*/
  133611. +/*----- Threads --------------------------------------------------------------*/
  133612. +
  133613. +#ifdef _WIN32
  133614. +/* Cannot include windows.h here becuase "near" and "far"
  133615. + * which are used in gcsDEPTH_INFO, are defined to nothing in WinDef.h.
  133616. + * So, use the real value of DWORD and WINAPI, instead.
  133617. + * DWORD is unsigned long, and WINAPI is __stdcall.
  133618. + * If these two are change in WinDef.h, the following two typdefs
  133619. + * need to be changed, too.
  133620. + */
  133621. +typedef unsigned long gctTHREAD_RETURN;
  133622. +typedef unsigned long (__stdcall * gcTHREAD_ROUTINE)(void * Argument);
  133623. +#else
  133624. +typedef void * gctTHREAD_RETURN;
  133625. +typedef void * (* gcTHREAD_ROUTINE)(void *);
  133626. +#endif
  133627. +
  133628. +/* Create a new thread. */
  133629. +gceSTATUS
  133630. +gcoOS_CreateThread(
  133631. + IN gcoOS Os,
  133632. + IN gcTHREAD_ROUTINE Worker,
  133633. + IN gctPOINTER Argument,
  133634. + OUT gctPOINTER * Thread
  133635. + );
  133636. +
  133637. +/* Close a thread. */
  133638. +gceSTATUS
  133639. +gcoOS_CloseThread(
  133640. + IN gcoOS Os,
  133641. + IN gctPOINTER Thread
  133642. + );
  133643. +
  133644. +/*----------------------------------------------------------------------------*/
  133645. +/*----- Mutexes --------------------------------------------------------------*/
  133646. +
  133647. +/* Create a new mutex. */
  133648. +gceSTATUS
  133649. +gcoOS_CreateMutex(
  133650. + IN gcoOS Os,
  133651. + OUT gctPOINTER * Mutex
  133652. + );
  133653. +
  133654. +/* Delete a mutex. */
  133655. +gceSTATUS
  133656. +gcoOS_DeleteMutex(
  133657. + IN gcoOS Os,
  133658. + IN gctPOINTER Mutex
  133659. + );
  133660. +
  133661. +/* Acquire a mutex. */
  133662. +gceSTATUS
  133663. +gcoOS_AcquireMutex(
  133664. + IN gcoOS Os,
  133665. + IN gctPOINTER Mutex,
  133666. + IN gctUINT32 Timeout
  133667. + );
  133668. +
  133669. +/* Release a mutex. */
  133670. +gceSTATUS
  133671. +gcoOS_ReleaseMutex(
  133672. + IN gcoOS Os,
  133673. + IN gctPOINTER Mutex
  133674. + );
  133675. +
  133676. +/*----------------------------------------------------------------------------*/
  133677. +/*----- Signals --------------------------------------------------------------*/
  133678. +
  133679. +/* Create a signal. */
  133680. +gceSTATUS
  133681. +gcoOS_CreateSignal(
  133682. + IN gcoOS Os,
  133683. + IN gctBOOL ManualReset,
  133684. + OUT gctSIGNAL * Signal
  133685. + );
  133686. +
  133687. +/* Destroy a signal. */
  133688. +gceSTATUS
  133689. +gcoOS_DestroySignal(
  133690. + IN gcoOS Os,
  133691. + IN gctSIGNAL Signal
  133692. + );
  133693. +
  133694. +/* Signal a signal. */
  133695. +gceSTATUS
  133696. +gcoOS_Signal(
  133697. + IN gcoOS Os,
  133698. + IN gctSIGNAL Signal,
  133699. + IN gctBOOL State
  133700. + );
  133701. +
  133702. +/* Wait for a signal. */
  133703. +gceSTATUS
  133704. +gcoOS_WaitSignal(
  133705. + IN gcoOS Os,
  133706. + IN gctSIGNAL Signal,
  133707. + IN gctUINT32 Wait
  133708. + );
  133709. +
  133710. +/* Map a signal from another process */
  133711. +gceSTATUS
  133712. +gcoOS_MapSignal(
  133713. + IN gctSIGNAL RemoteSignal,
  133714. + OUT gctSIGNAL * LocalSignal
  133715. + );
  133716. +
  133717. +/* Unmap a signal mapped from another process */
  133718. +gceSTATUS
  133719. +gcoOS_UnmapSignal(
  133720. + IN gctSIGNAL Signal
  133721. + );
  133722. +
  133723. +/*----------------------------------------------------------------------------*/
  133724. +/*----- Android Native Fence -------------------------------------------------*/
  133725. +
  133726. +/* Create sync point. */
  133727. +gceSTATUS
  133728. +gcoOS_CreateSyncPoint(
  133729. + IN gcoOS Os,
  133730. + OUT gctSYNC_POINT * SyncPoint
  133731. + );
  133732. +
  133733. +/* Destroy sync point. */
  133734. +gceSTATUS
  133735. +gcoOS_DestroySyncPoint(
  133736. + IN gcoOS Os,
  133737. + IN gctSYNC_POINT SyncPoint
  133738. + );
  133739. +
  133740. +/* Create native fence. */
  133741. +gceSTATUS
  133742. +gcoOS_CreateNativeFence(
  133743. + IN gcoOS Os,
  133744. + IN gctSYNC_POINT SyncPoint,
  133745. + OUT gctINT * FenceFD
  133746. + );
  133747. +
  133748. +/* Wait on native fence. */
  133749. +gceSTATUS
  133750. +gcoOS_WaitNativeFence(
  133751. + IN gcoOS Os,
  133752. + IN gctINT FenceFD,
  133753. + IN gctUINT32 Timeout
  133754. + );
  133755. +
  133756. +/*----------------------------------------------------------------------------*/
  133757. +/*----- Memory Access and Cache ----------------------------------------------*/
  133758. +
  133759. +/* Write a register. */
  133760. +gceSTATUS
  133761. +gcoOS_WriteRegister(
  133762. + IN gcoOS Os,
  133763. + IN gctUINT32 Address,
  133764. + IN gctUINT32 Data
  133765. + );
  133766. +
  133767. +/* Read a register. */
  133768. +gceSTATUS
  133769. +gcoOS_ReadRegister(
  133770. + IN gcoOS Os,
  133771. + IN gctUINT32 Address,
  133772. + OUT gctUINT32 * Data
  133773. + );
  133774. +
  133775. +gceSTATUS
  133776. +gcoOS_CacheClean(
  133777. + IN gcoOS Os,
  133778. + IN gctUINT64 Node,
  133779. + IN gctPOINTER Logical,
  133780. + IN gctSIZE_T Bytes
  133781. + );
  133782. +
  133783. +gceSTATUS
  133784. +gcoOS_CacheFlush(
  133785. + IN gcoOS Os,
  133786. + IN gctUINT64 Node,
  133787. + IN gctPOINTER Logical,
  133788. + IN gctSIZE_T Bytes
  133789. + );
  133790. +
  133791. +gceSTATUS
  133792. +gcoOS_CacheInvalidate(
  133793. + IN gcoOS Os,
  133794. + IN gctUINT64 Node,
  133795. + IN gctPOINTER Logical,
  133796. + IN gctSIZE_T Bytes
  133797. + );
  133798. +
  133799. +gceSTATUS
  133800. +gcoOS_MemoryBarrier(
  133801. + IN gcoOS Os,
  133802. + IN gctPOINTER Logical
  133803. + );
  133804. +
  133805. +
  133806. +/*----------------------------------------------------------------------------*/
  133807. +/*----- Profile --------------------------------------------------------------*/
  133808. +
  133809. +gceSTATUS
  133810. +gckOS_GetProfileTick(
  133811. + OUT gctUINT64_PTR Tick
  133812. + );
  133813. +
  133814. +gceSTATUS
  133815. +gckOS_QueryProfileTickRate(
  133816. + OUT gctUINT64_PTR TickRate
  133817. + );
  133818. +
  133819. +gctUINT32
  133820. +gckOS_ProfileToMS(
  133821. + IN gctUINT64 Ticks
  133822. + );
  133823. +
  133824. +gceSTATUS
  133825. +gcoOS_GetProfileTick(
  133826. + OUT gctUINT64_PTR Tick
  133827. + );
  133828. +
  133829. +gceSTATUS
  133830. +gcoOS_QueryProfileTickRate(
  133831. + OUT gctUINT64_PTR TickRate
  133832. + );
  133833. +
  133834. +#define _gcmPROFILE_INIT(prefix, freq, start) \
  133835. + do { \
  133836. + prefix ## OS_QueryProfileTickRate(&(freq)); \
  133837. + prefix ## OS_GetProfileTick(&(start)); \
  133838. + } while (gcvFALSE)
  133839. +
  133840. +#define _gcmPROFILE_QUERY(prefix, start, ticks) \
  133841. + do { \
  133842. + prefix ## OS_GetProfileTick(&(ticks)); \
  133843. + (ticks) = ((ticks) > (start)) ? ((ticks) - (start)) \
  133844. + : (~0ull - (start) + (ticks) + 1); \
  133845. + } while (gcvFALSE)
  133846. +
  133847. +#if gcdENABLE_PROFILING
  133848. +# define gcmkPROFILE_INIT(freq, start) _gcmPROFILE_INIT(gck, freq, start)
  133849. +# define gcmkPROFILE_QUERY(start, ticks) _gcmPROFILE_QUERY(gck, start, ticks)
  133850. +# define gcmPROFILE_INIT(freq, start) _gcmPROFILE_INIT(gco, freq, start)
  133851. +# define gcmPROFILE_QUERY(start, ticks) _gcmPROFILE_QUERY(gco, start, ticks)
  133852. +# define gcmPROFILE_ONLY(x) x
  133853. +# define gcmPROFILE_ELSE(x) do { } while (gcvFALSE)
  133854. +# define gcmPROFILE_DECLARE_ONLY(x) x
  133855. +# define gcmPROFILE_DECLARE_ELSE(x) typedef x
  133856. +#else
  133857. +# define gcmkPROFILE_INIT(start, freq) do { } while (gcvFALSE)
  133858. +# define gcmkPROFILE_QUERY(start, ticks) do { } while (gcvFALSE)
  133859. +# define gcmPROFILE_INIT(start, freq) do { } while (gcvFALSE)
  133860. +# define gcmPROFILE_QUERY(start, ticks) do { } while (gcvFALSE)
  133861. +# define gcmPROFILE_ONLY(x) do { } while (gcvFALSE)
  133862. +# define gcmPROFILE_ELSE(x) x
  133863. +# define gcmPROFILE_DECLARE_ONLY(x) do { } while (gcvFALSE)
  133864. +# define gcmPROFILE_DECLARE_ELSE(x) x
  133865. +#endif
  133866. +
  133867. +/*******************************************************************************
  133868. +** gcoMATH object
  133869. +*/
  133870. +
  133871. +#define gcdPI 3.14159265358979323846f
  133872. +
  133873. +/* Kernel. */
  133874. +gctINT
  133875. +gckMATH_ModuloInt(
  133876. + IN gctINT X,
  133877. + IN gctINT Y
  133878. + );
  133879. +
  133880. +/* User. */
  133881. +gctUINT32
  133882. +gcoMATH_Log2in5dot5(
  133883. + IN gctINT X
  133884. + );
  133885. +
  133886. +
  133887. +gctFLOAT
  133888. +gcoMATH_UIntAsFloat(
  133889. + IN gctUINT32 X
  133890. + );
  133891. +
  133892. +gctUINT32
  133893. +gcoMATH_FloatAsUInt(
  133894. + IN gctFLOAT X
  133895. + );
  133896. +
  133897. +gctBOOL
  133898. +gcoMATH_CompareEqualF(
  133899. + IN gctFLOAT X,
  133900. + IN gctFLOAT Y
  133901. + );
  133902. +
  133903. +gctUINT16
  133904. +gcoMATH_UInt8AsFloat16(
  133905. + IN gctUINT8 X
  133906. + );
  133907. +
  133908. +/******************************************************************************\
  133909. +**************************** Coordinate Structures *****************************
  133910. +\******************************************************************************/
  133911. +
  133912. +typedef struct _gcsPOINT
  133913. +{
  133914. + gctINT32 x;
  133915. + gctINT32 y;
  133916. +}
  133917. +gcsPOINT;
  133918. +
  133919. +typedef struct _gcsSIZE
  133920. +{
  133921. + gctINT32 width;
  133922. + gctINT32 height;
  133923. +}
  133924. +gcsSIZE;
  133925. +
  133926. +typedef struct _gcsRECT
  133927. +{
  133928. + gctINT32 left;
  133929. + gctINT32 top;
  133930. + gctINT32 right;
  133931. + gctINT32 bottom;
  133932. +}
  133933. +gcsRECT;
  133934. +
  133935. +typedef union _gcsPIXEL
  133936. +{
  133937. + struct
  133938. + {
  133939. + gctFLOAT r, g, b, a;
  133940. + gctFLOAT d, s;
  133941. + } pf;
  133942. +
  133943. + struct
  133944. + {
  133945. + gctINT32 r, g, b, a;
  133946. + gctINT32 d, s;
  133947. + } pi;
  133948. +
  133949. + struct
  133950. + {
  133951. + gctUINT32 r, g, b, a;
  133952. + gctUINT32 d, s;
  133953. + } pui;
  133954. +
  133955. +} gcsPIXEL;
  133956. +
  133957. +
  133958. +/******************************************************************************\
  133959. +********************************* gcoSURF Object ********************************
  133960. +\******************************************************************************/
  133961. +
  133962. +/*----------------------------------------------------------------------------*/
  133963. +/*------------------------------- gcoSURF Common ------------------------------*/
  133964. +
  133965. +/* Color format classes. */
  133966. +typedef enum _gceFORMAT_CLASS
  133967. +{
  133968. + gcvFORMAT_CLASS_RGBA = 4500,
  133969. + gcvFORMAT_CLASS_YUV,
  133970. + gcvFORMAT_CLASS_INDEX,
  133971. + gcvFORMAT_CLASS_LUMINANCE,
  133972. + gcvFORMAT_CLASS_BUMP,
  133973. + gcvFORMAT_CLASS_DEPTH,
  133974. +}
  133975. +gceFORMAT_CLASS;
  133976. +
  133977. +/* Special enums for width field in gcsFORMAT_COMPONENT. */
  133978. +typedef enum _gceCOMPONENT_CONTROL
  133979. +{
  133980. + gcvCOMPONENT_NOTPRESENT = 0x00,
  133981. + gcvCOMPONENT_DONTCARE = 0x80,
  133982. + gcvCOMPONENT_WIDTHMASK = 0x7F,
  133983. + gcvCOMPONENT_ODD = 0x80
  133984. +}
  133985. +gceCOMPONENT_CONTROL;
  133986. +
  133987. +/* Color format component parameters. */
  133988. +typedef struct _gcsFORMAT_COMPONENT
  133989. +{
  133990. + gctUINT8 start;
  133991. + gctUINT8 width;
  133992. +}
  133993. +gcsFORMAT_COMPONENT;
  133994. +
  133995. +/* RGBA color format class. */
  133996. +typedef struct _gcsFORMAT_CLASS_TYPE_RGBA
  133997. +{
  133998. + gcsFORMAT_COMPONENT alpha;
  133999. + gcsFORMAT_COMPONENT red;
  134000. + gcsFORMAT_COMPONENT green;
  134001. + gcsFORMAT_COMPONENT blue;
  134002. +}
  134003. +gcsFORMAT_CLASS_TYPE_RGBA;
  134004. +
  134005. +/* YUV color format class. */
  134006. +typedef struct _gcsFORMAT_CLASS_TYPE_YUV
  134007. +{
  134008. + gcsFORMAT_COMPONENT y;
  134009. + gcsFORMAT_COMPONENT u;
  134010. + gcsFORMAT_COMPONENT v;
  134011. +}
  134012. +gcsFORMAT_CLASS_TYPE_YUV;
  134013. +
  134014. +/* Index color format class. */
  134015. +typedef struct _gcsFORMAT_CLASS_TYPE_INDEX
  134016. +{
  134017. + gcsFORMAT_COMPONENT value;
  134018. +}
  134019. +gcsFORMAT_CLASS_TYPE_INDEX;
  134020. +
  134021. +/* Luminance color format class. */
  134022. +typedef struct _gcsFORMAT_CLASS_TYPE_LUMINANCE
  134023. +{
  134024. + gcsFORMAT_COMPONENT alpha;
  134025. + gcsFORMAT_COMPONENT value;
  134026. +}
  134027. +gcsFORMAT_CLASS_TYPE_LUMINANCE;
  134028. +
  134029. +/* Bump map color format class. */
  134030. +typedef struct _gcsFORMAT_CLASS_TYPE_BUMP
  134031. +{
  134032. + gcsFORMAT_COMPONENT alpha;
  134033. + gcsFORMAT_COMPONENT l;
  134034. + gcsFORMAT_COMPONENT v;
  134035. + gcsFORMAT_COMPONENT u;
  134036. + gcsFORMAT_COMPONENT q;
  134037. + gcsFORMAT_COMPONENT w;
  134038. +}
  134039. +gcsFORMAT_CLASS_TYPE_BUMP;
  134040. +
  134041. +/* Depth and stencil format class. */
  134042. +typedef struct _gcsFORMAT_CLASS_TYPE_DEPTH
  134043. +{
  134044. + gcsFORMAT_COMPONENT depth;
  134045. + gcsFORMAT_COMPONENT stencil;
  134046. +}
  134047. +gcsFORMAT_CLASS_TYPE_DEPTH;
  134048. +
  134049. +/* Format parameters. */
  134050. +typedef struct _gcsSURF_FORMAT_INFO
  134051. +{
  134052. + /* Format code and class. */
  134053. + gceSURF_FORMAT format;
  134054. + gceFORMAT_CLASS fmtClass;
  134055. +
  134056. + /* The size of one pixel in bits. */
  134057. + gctUINT8 bitsPerPixel;
  134058. +
  134059. + /* Component swizzle. */
  134060. + gceSURF_SWIZZLE swizzle;
  134061. +
  134062. + /* Some formats have two neighbour pixels interleaved together. */
  134063. + /* To describe such format, set the flag to 1 and add another */
  134064. + /* like this one describing the odd pixel format. */
  134065. + gctUINT8 interleaved;
  134066. +
  134067. + /* Format components. */
  134068. + union
  134069. + {
  134070. + gcsFORMAT_CLASS_TYPE_BUMP bump;
  134071. + gcsFORMAT_CLASS_TYPE_RGBA rgba;
  134072. + gcsFORMAT_CLASS_TYPE_YUV yuv;
  134073. + gcsFORMAT_CLASS_TYPE_LUMINANCE lum;
  134074. + gcsFORMAT_CLASS_TYPE_INDEX index;
  134075. + gcsFORMAT_CLASS_TYPE_DEPTH depth;
  134076. + } u;
  134077. +}
  134078. +gcsSURF_FORMAT_INFO;
  134079. +
  134080. +/* Frame buffer information. */
  134081. +typedef struct _gcsSURF_FRAMEBUFFER
  134082. +{
  134083. + gctPOINTER logical;
  134084. + gctUINT width, height;
  134085. + gctINT stride;
  134086. + gceSURF_FORMAT format;
  134087. +}
  134088. +gcsSURF_FRAMEBUFFER;
  134089. +
  134090. +typedef struct _gcsVIDMEM_NODE_SHARED_INFO
  134091. +{
  134092. + gctBOOL tileStatusDisabled;
  134093. + gcsPOINT SrcOrigin;
  134094. + gcsPOINT DestOrigin;
  134095. + gcsSIZE RectSize;
  134096. + gctUINT32 clearValue;
  134097. +}
  134098. +gcsVIDMEM_NODE_SHARED_INFO;
  134099. +
  134100. +/* Generic pixel component descriptors. */
  134101. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XXX8;
  134102. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XX8X;
  134103. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_X8XX;
  134104. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_8XXX;
  134105. +
  134106. +typedef enum _gceORIENTATION
  134107. +{
  134108. + gcvORIENTATION_TOP_BOTTOM,
  134109. + gcvORIENTATION_BOTTOM_TOP,
  134110. +}
  134111. +gceORIENTATION;
  134112. +
  134113. +
  134114. +/* Construct a new gcoSURF object. */
  134115. +gceSTATUS
  134116. +gcoSURF_Construct(
  134117. + IN gcoHAL Hal,
  134118. + IN gctUINT Width,
  134119. + IN gctUINT Height,
  134120. + IN gctUINT Depth,
  134121. + IN gceSURF_TYPE Type,
  134122. + IN gceSURF_FORMAT Format,
  134123. + IN gcePOOL Pool,
  134124. + OUT gcoSURF * Surface
  134125. + );
  134126. +
  134127. +/* Destroy an gcoSURF object. */
  134128. +gceSTATUS
  134129. +gcoSURF_Destroy(
  134130. + IN gcoSURF Surface
  134131. + );
  134132. +
  134133. +/* Map user-allocated surface. */
  134134. +gceSTATUS
  134135. +gcoSURF_MapUserSurface(
  134136. + IN gcoSURF Surface,
  134137. + IN gctUINT Alignment,
  134138. + IN gctPOINTER Logical,
  134139. + IN gctUINT32 Physical
  134140. + );
  134141. +
  134142. +/* Query vid mem node info. */
  134143. +gceSTATUS
  134144. +gcoSURF_QueryVidMemNode(
  134145. + IN gcoSURF Surface,
  134146. + OUT gctUINT64 * Node,
  134147. + OUT gcePOOL * Pool,
  134148. + OUT gctUINT_PTR Bytes
  134149. + );
  134150. +
  134151. +/* Set the color type of the surface. */
  134152. +gceSTATUS
  134153. +gcoSURF_SetColorType(
  134154. + IN gcoSURF Surface,
  134155. + IN gceSURF_COLOR_TYPE ColorType
  134156. + );
  134157. +
  134158. +/* Get the color type of the surface. */
  134159. +gceSTATUS
  134160. +gcoSURF_GetColorType(
  134161. + IN gcoSURF Surface,
  134162. + OUT gceSURF_COLOR_TYPE *ColorType
  134163. + );
  134164. +
  134165. +/* Set the surface ration angle. */
  134166. +gceSTATUS
  134167. +gcoSURF_SetRotation(
  134168. + IN gcoSURF Surface,
  134169. + IN gceSURF_ROTATION Rotation
  134170. + );
  134171. +
  134172. +gceSTATUS
  134173. +gcoSURF_SetPreRotation(
  134174. + IN gcoSURF Surface,
  134175. + IN gceSURF_ROTATION Rotation
  134176. + );
  134177. +
  134178. +gceSTATUS
  134179. +gcoSURF_GetPreRotation(
  134180. + IN gcoSURF Surface,
  134181. + IN gceSURF_ROTATION *Rotation
  134182. + );
  134183. +
  134184. +gceSTATUS
  134185. +gcoSURF_IsValid(
  134186. + IN gcoSURF Surface
  134187. + );
  134188. +
  134189. +#ifndef VIVANTE_NO_3D
  134190. +/* Verify and return the state of the tile status mechanism. */
  134191. +gceSTATUS
  134192. +gcoSURF_IsTileStatusSupported(
  134193. + IN gcoSURF Surface
  134194. + );
  134195. +
  134196. +/* Process tile status for the specified surface. */
  134197. +gceSTATUS
  134198. +gcoSURF_SetTileStatus(
  134199. + IN gcoSURF Surface
  134200. + );
  134201. +
  134202. +/* Enable tile status for the specified surface. */
  134203. +gceSTATUS
  134204. +gcoSURF_EnableTileStatus(
  134205. + IN gcoSURF Surface
  134206. + );
  134207. +
  134208. +/* Disable tile status for the specified surface. */
  134209. +gceSTATUS
  134210. +gcoSURF_DisableTileStatus(
  134211. + IN gcoSURF Surface,
  134212. + IN gctBOOL Decompress
  134213. + );
  134214. +
  134215. +gceSTATUS
  134216. +gcoSURF_AlignResolveRect(
  134217. + IN gcoSURF Surf,
  134218. + IN gcsPOINT_PTR RectOrigin,
  134219. + IN gcsPOINT_PTR RectSize,
  134220. + OUT gcsPOINT_PTR AlignedOrigin,
  134221. + OUT gcsPOINT_PTR AlignedSize
  134222. + );
  134223. +#endif /* VIVANTE_NO_3D */
  134224. +
  134225. +/* Get surface size. */
  134226. +gceSTATUS
  134227. +gcoSURF_GetSize(
  134228. + IN gcoSURF Surface,
  134229. + OUT gctUINT * Width,
  134230. + OUT gctUINT * Height,
  134231. + OUT gctUINT * Depth
  134232. + );
  134233. +
  134234. +/* Get surface aligned sizes. */
  134235. +gceSTATUS
  134236. +gcoSURF_GetAlignedSize(
  134237. + IN gcoSURF Surface,
  134238. + OUT gctUINT * Width,
  134239. + OUT gctUINT * Height,
  134240. + OUT gctINT * Stride
  134241. + );
  134242. +
  134243. +/* Get alignments. */
  134244. +gceSTATUS
  134245. +gcoSURF_GetAlignment(
  134246. + IN gceSURF_TYPE Type,
  134247. + IN gceSURF_FORMAT Format,
  134248. + OUT gctUINT * AddressAlignment,
  134249. + OUT gctUINT * XAlignment,
  134250. + OUT gctUINT * YAlignment
  134251. + );
  134252. +
  134253. +/* Get surface type and format. */
  134254. +gceSTATUS
  134255. +gcoSURF_GetFormat(
  134256. + IN gcoSURF Surface,
  134257. + OUT gceSURF_TYPE * Type,
  134258. + OUT gceSURF_FORMAT * Format
  134259. + );
  134260. +
  134261. +/* Get surface tiling. */
  134262. +gceSTATUS
  134263. +gcoSURF_GetTiling(
  134264. + IN gcoSURF Surface,
  134265. + OUT gceTILING * Tiling
  134266. + );
  134267. +
  134268. +/* Lock the surface. */
  134269. +gceSTATUS
  134270. +gcoSURF_Lock(
  134271. + IN gcoSURF Surface,
  134272. + IN OUT gctUINT32 * Address,
  134273. + IN OUT gctPOINTER * Memory
  134274. + );
  134275. +
  134276. +/* Unlock the surface. */
  134277. +gceSTATUS
  134278. +gcoSURF_Unlock(
  134279. + IN gcoSURF Surface,
  134280. + IN gctPOINTER Memory
  134281. + );
  134282. +
  134283. +/* Return pixel format parameters. */
  134284. +gceSTATUS
  134285. +gcoSURF_QueryFormat(
  134286. + IN gceSURF_FORMAT Format,
  134287. + OUT gcsSURF_FORMAT_INFO_PTR * Info
  134288. + );
  134289. +
  134290. +/* Compute the color pixel mask. */
  134291. +gceSTATUS
  134292. +gcoSURF_ComputeColorMask(
  134293. + IN gcsSURF_FORMAT_INFO_PTR Format,
  134294. + OUT gctUINT32_PTR ColorMask
  134295. + );
  134296. +
  134297. +/* Flush the surface. */
  134298. +gceSTATUS
  134299. +gcoSURF_Flush(
  134300. + IN gcoSURF Surface
  134301. + );
  134302. +
  134303. +/* Fill surface from it's tile status buffer. */
  134304. +gceSTATUS
  134305. +gcoSURF_FillFromTile(
  134306. + IN gcoSURF Surface
  134307. + );
  134308. +
  134309. +/* Check if surface needs a filler. */
  134310. +gceSTATUS gcoSURF_NeedFiller(IN gcoSURF Surface);
  134311. +
  134312. +/* Fill surface with a value. */
  134313. +gceSTATUS
  134314. +gcoSURF_Fill(
  134315. + IN gcoSURF Surface,
  134316. + IN gcsPOINT_PTR Origin,
  134317. + IN gcsSIZE_PTR Size,
  134318. + IN gctUINT32 Value,
  134319. + IN gctUINT32 Mask
  134320. + );
  134321. +
  134322. +/* Alpha blend two surfaces together. */
  134323. +gceSTATUS
  134324. +gcoSURF_Blend(
  134325. + IN gcoSURF SrcSurface,
  134326. + IN gcoSURF DestSurface,
  134327. + IN gcsPOINT_PTR SrcOrig,
  134328. + IN gcsPOINT_PTR DestOrigin,
  134329. + IN gcsSIZE_PTR Size,
  134330. + IN gceSURF_BLEND_MODE Mode
  134331. + );
  134332. +
  134333. +/* Create a new gcoSURF wrapper object. */
  134334. +gceSTATUS
  134335. +gcoSURF_ConstructWrapper(
  134336. + IN gcoHAL Hal,
  134337. + OUT gcoSURF * Surface
  134338. + );
  134339. +
  134340. +/* Set the underlying buffer for the surface wrapper. */
  134341. +gceSTATUS
  134342. +gcoSURF_SetBuffer(
  134343. + IN gcoSURF Surface,
  134344. + IN gceSURF_TYPE Type,
  134345. + IN gceSURF_FORMAT Format,
  134346. + IN gctUINT Stride,
  134347. + IN gctPOINTER Logical,
  134348. + IN gctUINT32 Physical
  134349. + );
  134350. +
  134351. +/* Set the underlying video buffer for the surface wrapper. */
  134352. +gceSTATUS
  134353. +gcoSURF_SetVideoBuffer(
  134354. + IN gcoSURF Surface,
  134355. + IN gceSURF_TYPE Type,
  134356. + IN gceSURF_FORMAT Format,
  134357. + IN gctUINT Width,
  134358. + IN gctUINT Height,
  134359. + IN gctUINT Stride,
  134360. + IN gctPOINTER *LogicalPlane1,
  134361. + IN gctUINT32 *PhysicalPlane1
  134362. + );
  134363. +
  134364. +/* Set the size of the surface in pixels and map the underlying buffer. */
  134365. +gceSTATUS
  134366. +gcoSURF_SetWindow(
  134367. + IN gcoSURF Surface,
  134368. + IN gctUINT X,
  134369. + IN gctUINT Y,
  134370. + IN gctUINT Width,
  134371. + IN gctUINT Height
  134372. + );
  134373. +
  134374. +/* Set width/height alignment of the surface directly and calculate stride/size. This is only for dri backend now. Please be careful before use. */
  134375. +gceSTATUS
  134376. +gcoSURF_SetAlignment(
  134377. + IN gcoSURF Surface,
  134378. + IN gctUINT Width,
  134379. + IN gctUINT Height
  134380. + );
  134381. +
  134382. +/* Increase reference count of the surface. */
  134383. +gceSTATUS
  134384. +gcoSURF_ReferenceSurface(
  134385. + IN gcoSURF Surface
  134386. + );
  134387. +
  134388. +/* Get surface reference count. */
  134389. +gceSTATUS
  134390. +gcoSURF_QueryReferenceCount(
  134391. + IN gcoSURF Surface,
  134392. + OUT gctINT32 * ReferenceCount
  134393. + );
  134394. +
  134395. +/* Set surface orientation. */
  134396. +gceSTATUS
  134397. +gcoSURF_SetOrientation(
  134398. + IN gcoSURF Surface,
  134399. + IN gceORIENTATION Orientation
  134400. + );
  134401. +
  134402. +/* Query surface orientation. */
  134403. +gceSTATUS
  134404. +gcoSURF_QueryOrientation(
  134405. + IN gcoSURF Surface,
  134406. + OUT gceORIENTATION * Orientation
  134407. + );
  134408. +
  134409. +gceSTATUS
  134410. +gcoSURF_SetOffset(
  134411. + IN gcoSURF Surface,
  134412. + IN gctUINT Offset
  134413. + );
  134414. +
  134415. +gceSTATUS
  134416. +gcoSURF_GetOffset(
  134417. + IN gcoSURF Surface,
  134418. + OUT gctUINT *Offset
  134419. + );
  134420. +
  134421. +gceSTATUS
  134422. +gcoSURF_NODE_Cache(
  134423. + IN gcsSURF_NODE_PTR Node,
  134424. + IN gctPOINTER Logical,
  134425. + IN gctSIZE_T Bytes,
  134426. + IN gceCACHEOPERATION Operation
  134427. + );
  134428. +
  134429. +/* Perform CPU cache operation on surface */
  134430. +gceSTATUS
  134431. +gcoSURF_CPUCacheOperation(
  134432. + IN gcoSURF Surface,
  134433. + IN gceCACHEOPERATION Operation
  134434. + );
  134435. +
  134436. +
  134437. +gceSTATUS
  134438. +gcoSURF_SetLinearResolveAddress(
  134439. + IN gcoSURF Surface,
  134440. + IN gctUINT32 Address,
  134441. + IN gctPOINTER Memory
  134442. + );
  134443. +
  134444. + gceSTATUS
  134445. + gcoSURF_Swap(IN gcoSURF Surface1, IN gcoSURF Surface2);
  134446. +
  134447. +/******************************************************************************\
  134448. +********************************* gcoDUMP Object ********************************
  134449. +\******************************************************************************/
  134450. +
  134451. +/* Construct a new gcoDUMP object. */
  134452. +gceSTATUS
  134453. +gcoDUMP_Construct(
  134454. + IN gcoOS Os,
  134455. + IN gcoHAL Hal,
  134456. + OUT gcoDUMP * Dump
  134457. + );
  134458. +
  134459. +/* Destroy a gcoDUMP object. */
  134460. +gceSTATUS
  134461. +gcoDUMP_Destroy(
  134462. + IN gcoDUMP Dump
  134463. + );
  134464. +
  134465. +/* Enable/disable dumping. */
  134466. +gceSTATUS
  134467. +gcoDUMP_Control(
  134468. + IN gcoDUMP Dump,
  134469. + IN gctSTRING FileName
  134470. + );
  134471. +
  134472. +gceSTATUS
  134473. +gcoDUMP_IsEnabled(
  134474. + IN gcoDUMP Dump,
  134475. + OUT gctBOOL * Enabled
  134476. + );
  134477. +
  134478. +/* Add surface. */
  134479. +gceSTATUS
  134480. +gcoDUMP_AddSurface(
  134481. + IN gcoDUMP Dump,
  134482. + IN gctINT32 Width,
  134483. + IN gctINT32 Height,
  134484. + IN gceSURF_FORMAT PixelFormat,
  134485. + IN gctUINT32 Address,
  134486. + IN gctSIZE_T ByteCount
  134487. + );
  134488. +
  134489. +/* Mark the beginning of a frame. */
  134490. +gceSTATUS
  134491. +gcoDUMP_FrameBegin(
  134492. + IN gcoDUMP Dump
  134493. + );
  134494. +
  134495. +/* Mark the end of a frame. */
  134496. +gceSTATUS
  134497. +gcoDUMP_FrameEnd(
  134498. + IN gcoDUMP Dump
  134499. + );
  134500. +
  134501. +/* Dump data. */
  134502. +gceSTATUS
  134503. +gcoDUMP_DumpData(
  134504. + IN gcoDUMP Dump,
  134505. + IN gceDUMP_TAG Type,
  134506. + IN gctUINT32 Address,
  134507. + IN gctSIZE_T ByteCount,
  134508. + IN gctCONST_POINTER Data
  134509. + );
  134510. +
  134511. +/* Delete an address. */
  134512. +gceSTATUS
  134513. +gcoDUMP_Delete(
  134514. + IN gcoDUMP Dump,
  134515. + IN gctUINT32 Address
  134516. + );
  134517. +
  134518. +/* Enable dump or not. */
  134519. +gceSTATUS
  134520. +gcoDUMP_SetDumpFlag(
  134521. + IN gctBOOL DumpState
  134522. + );
  134523. +
  134524. +/******************************************************************************\
  134525. +******************************* gcsRECT Structure ******************************
  134526. +\******************************************************************************/
  134527. +
  134528. +/* Initialize rectangle structure. */
  134529. +gceSTATUS
  134530. +gcsRECT_Set(
  134531. + OUT gcsRECT_PTR Rect,
  134532. + IN gctINT32 Left,
  134533. + IN gctINT32 Top,
  134534. + IN gctINT32 Right,
  134535. + IN gctINT32 Bottom
  134536. + );
  134537. +
  134538. +/* Return the width of the rectangle. */
  134539. +gceSTATUS
  134540. +gcsRECT_Width(
  134541. + IN gcsRECT_PTR Rect,
  134542. + OUT gctINT32 * Width
  134543. + );
  134544. +
  134545. +/* Return the height of the rectangle. */
  134546. +gceSTATUS
  134547. +gcsRECT_Height(
  134548. + IN gcsRECT_PTR Rect,
  134549. + OUT gctINT32 * Height
  134550. + );
  134551. +
  134552. +/* Ensure that top left corner is to the left and above the right bottom. */
  134553. +gceSTATUS
  134554. +gcsRECT_Normalize(
  134555. + IN OUT gcsRECT_PTR Rect
  134556. + );
  134557. +
  134558. +/* Compare two rectangles. */
  134559. +gceSTATUS
  134560. +gcsRECT_IsEqual(
  134561. + IN gcsRECT_PTR Rect1,
  134562. + IN gcsRECT_PTR Rect2,
  134563. + OUT gctBOOL * Equal
  134564. + );
  134565. +
  134566. +/* Compare the sizes of two rectangles. */
  134567. +gceSTATUS
  134568. +gcsRECT_IsOfEqualSize(
  134569. + IN gcsRECT_PTR Rect1,
  134570. + IN gcsRECT_PTR Rect2,
  134571. + OUT gctBOOL * EqualSize
  134572. + );
  134573. +
  134574. +gceSTATUS
  134575. +gcsRECT_RelativeRotation(
  134576. + IN gceSURF_ROTATION Orientation,
  134577. + IN OUT gceSURF_ROTATION *Relation);
  134578. +
  134579. +gceSTATUS
  134580. +
  134581. +gcsRECT_Rotate(
  134582. +
  134583. + IN OUT gcsRECT_PTR Rect,
  134584. +
  134585. + IN gceSURF_ROTATION Rotation,
  134586. +
  134587. + IN gceSURF_ROTATION toRotation,
  134588. +
  134589. + IN gctINT32 SurfaceWidth,
  134590. +
  134591. + IN gctINT32 SurfaceHeight
  134592. +
  134593. + );
  134594. +
  134595. +/******************************************************************************\
  134596. +**************************** gcsBOUNDARY Structure *****************************
  134597. +\******************************************************************************/
  134598. +
  134599. +typedef struct _gcsBOUNDARY
  134600. +{
  134601. + gctINT x;
  134602. + gctINT y;
  134603. + gctINT width;
  134604. + gctINT height;
  134605. +}
  134606. +gcsBOUNDARY;
  134607. +
  134608. +/******************************************************************************\
  134609. +********************************* gcoHEAP Object ********************************
  134610. +\******************************************************************************/
  134611. +
  134612. +typedef struct _gcoHEAP * gcoHEAP;
  134613. +
  134614. +/* Construct a new gcoHEAP object. */
  134615. +gceSTATUS
  134616. +gcoHEAP_Construct(
  134617. + IN gcoOS Os,
  134618. + IN gctSIZE_T AllocationSize,
  134619. + OUT gcoHEAP * Heap
  134620. + );
  134621. +
  134622. +/* Destroy an gcoHEAP object. */
  134623. +gceSTATUS
  134624. +gcoHEAP_Destroy(
  134625. + IN gcoHEAP Heap
  134626. + );
  134627. +
  134628. +/* Allocate memory. */
  134629. +gceSTATUS
  134630. +gcoHEAP_Allocate(
  134631. + IN gcoHEAP Heap,
  134632. + IN gctSIZE_T Bytes,
  134633. + OUT gctPOINTER * Node
  134634. + );
  134635. +
  134636. +gceSTATUS
  134637. +gcoHEAP_GetMemorySize(
  134638. + IN gcoHEAP Heap,
  134639. + IN gctPOINTER Memory,
  134640. + OUT gctSIZE_T_PTR MemorySize
  134641. + );
  134642. +
  134643. +/* Free memory. */
  134644. +gceSTATUS
  134645. +gcoHEAP_Free(
  134646. + IN gcoHEAP Heap,
  134647. + IN gctPOINTER Node
  134648. + );
  134649. +
  134650. +#if (VIVANTE_PROFILER || gcdDEBUG)
  134651. +/* Profile the heap. */
  134652. +gceSTATUS
  134653. +gcoHEAP_ProfileStart(
  134654. + IN gcoHEAP Heap
  134655. + );
  134656. +
  134657. +gceSTATUS
  134658. +gcoHEAP_ProfileEnd(
  134659. + IN gcoHEAP Heap,
  134660. + IN gctCONST_STRING Title
  134661. + );
  134662. +#endif
  134663. +
  134664. +
  134665. +/******************************************************************************\
  134666. +******************************* Debugging Macros *******************************
  134667. +\******************************************************************************/
  134668. +
  134669. +void
  134670. +gcoOS_SetDebugLevel(
  134671. + IN gctUINT32 Level
  134672. + );
  134673. +
  134674. +void
  134675. +gcoOS_GetDebugLevel(
  134676. + OUT gctUINT32_PTR DebugLevel
  134677. + );
  134678. +
  134679. +void
  134680. +gcoOS_SetDebugZone(
  134681. + IN gctUINT32 Zone
  134682. + );
  134683. +
  134684. +void
  134685. +gcoOS_GetDebugZone(
  134686. + IN gctUINT32 Zone,
  134687. + OUT gctUINT32_PTR DebugZone
  134688. + );
  134689. +
  134690. +void
  134691. +gcoOS_SetDebugLevelZone(
  134692. + IN gctUINT32 Level,
  134693. + IN gctUINT32 Zone
  134694. + );
  134695. +
  134696. +void
  134697. +gcoOS_SetDebugZones(
  134698. + IN gctUINT32 Zones,
  134699. + IN gctBOOL Enable
  134700. + );
  134701. +
  134702. +void
  134703. +gcoOS_SetDebugFile(
  134704. + IN gctCONST_STRING FileName
  134705. + );
  134706. +
  134707. +gctFILE
  134708. +gcoOS_ReplaceDebugFile(
  134709. + IN gctFILE fp
  134710. + );
  134711. +
  134712. +/*******************************************************************************
  134713. +**
  134714. +** gcmFATAL
  134715. +**
  134716. +** Print a message to the debugger and execute a break point.
  134717. +**
  134718. +** ARGUMENTS:
  134719. +**
  134720. +** message Message.
  134721. +** ... Optional arguments.
  134722. +*/
  134723. +
  134724. +void
  134725. +gckOS_DebugFatal(
  134726. + IN gctCONST_STRING Message,
  134727. + ...
  134728. + );
  134729. +
  134730. +void
  134731. +gcoOS_DebugFatal(
  134732. + IN gctCONST_STRING Message,
  134733. + ...
  134734. + );
  134735. +
  134736. +#if gcmIS_DEBUG(gcdDEBUG_FATAL)
  134737. +# define gcmFATAL gcoOS_DebugFatal
  134738. +# define gcmkFATAL gckOS_DebugFatal
  134739. +#elif gcdHAS_ELLIPSES
  134740. +# define gcmFATAL(...)
  134741. +# define gcmkFATAL(...)
  134742. +#else
  134743. + gcmINLINE static void
  134744. + __dummy_fatal(
  134745. + IN gctCONST_STRING Message,
  134746. + ...
  134747. + )
  134748. + {
  134749. + }
  134750. +# define gcmFATAL __dummy_fatal
  134751. +# define gcmkFATAL __dummy_fatal
  134752. +#endif
  134753. +
  134754. +#define gcmENUM2TEXT(e) case e: return #e
  134755. +
  134756. +/*******************************************************************************
  134757. +**
  134758. +** gcmTRACE
  134759. +**
  134760. +** Print a message to the debugfer if the correct level has been set. In
  134761. +** retail mode this macro does nothing.
  134762. +**
  134763. +** ARGUMENTS:
  134764. +**
  134765. +** level Level of message.
  134766. +** message Message.
  134767. +** ... Optional arguments.
  134768. +*/
  134769. +#define gcvLEVEL_NONE -1
  134770. +#define gcvLEVEL_ERROR 0
  134771. +#define gcvLEVEL_WARNING 1
  134772. +#define gcvLEVEL_INFO 2
  134773. +#define gcvLEVEL_VERBOSE 3
  134774. +
  134775. +void
  134776. +gckOS_DebugTrace(
  134777. + IN gctUINT32 Level,
  134778. + IN gctCONST_STRING Message,
  134779. + ...
  134780. + );
  134781. +
  134782. +void
  134783. +gckOS_DebugTraceN(
  134784. + IN gctUINT32 Level,
  134785. + IN gctUINT ArgumentSize,
  134786. + IN gctCONST_STRING Message,
  134787. + ...
  134788. + );
  134789. +
  134790. +void
  134791. +gcoOS_DebugTrace(
  134792. + IN gctUINT32 Level,
  134793. + IN gctCONST_STRING Message,
  134794. + ...
  134795. + );
  134796. +
  134797. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  134798. +# define gcmTRACE gcoOS_DebugTrace
  134799. +# define gcmkTRACE gckOS_DebugTrace
  134800. +# define gcmkTRACE_N gckOS_DebugTraceN
  134801. +#elif gcdHAS_ELLIPSES
  134802. +# define gcmTRACE(...)
  134803. +# define gcmkTRACE(...)
  134804. +# define gcmkTRACE_N(...)
  134805. +#else
  134806. + gcmINLINE static void
  134807. + __dummy_trace(
  134808. + IN gctUINT32 Level,
  134809. + IN gctCONST_STRING Message,
  134810. + ...
  134811. + )
  134812. + {
  134813. + }
  134814. +
  134815. + gcmINLINE static void
  134816. + __dummy_trace_n(
  134817. + IN gctUINT32 Level,
  134818. + IN gctUINT ArgumentSize,
  134819. + IN gctCONST_STRING Message,
  134820. + ...
  134821. + )
  134822. + {
  134823. + }
  134824. +
  134825. +# define gcmTRACE __dummy_trace
  134826. +# define gcmkTRACE __dummy_trace
  134827. +# define gcmkTRACE_N __dummy_trace_n
  134828. +#endif
  134829. +
  134830. +/* Zones common for kernel and user. */
  134831. +#define gcvZONE_OS (1 << 0)
  134832. +#define gcvZONE_HARDWARE (1 << 1)
  134833. +#define gcvZONE_HEAP (1 << 2)
  134834. +#define gcvZONE_SIGNAL (1 << 27)
  134835. +
  134836. +/* Kernel zones. */
  134837. +#define gcvZONE_KERNEL (1 << 3)
  134838. +#define gcvZONE_VIDMEM (1 << 4)
  134839. +#define gcvZONE_COMMAND (1 << 5)
  134840. +#define gcvZONE_DRIVER (1 << 6)
  134841. +#define gcvZONE_CMODEL (1 << 7)
  134842. +#define gcvZONE_MMU (1 << 8)
  134843. +#define gcvZONE_EVENT (1 << 9)
  134844. +#define gcvZONE_DEVICE (1 << 10)
  134845. +#define gcvZONE_DATABASE (1 << 11)
  134846. +#define gcvZONE_INTERRUPT (1 << 12)
  134847. +#define gcvZONE_POWER (1 << 13)
  134848. +
  134849. +/* User zones. */
  134850. +#define gcvZONE_HAL (1 << 3)
  134851. +#define gcvZONE_BUFFER (1 << 4)
  134852. +#define gcvZONE_CONTEXT (1 << 5)
  134853. +#define gcvZONE_SURFACE (1 << 6)
  134854. +#define gcvZONE_INDEX (1 << 7)
  134855. +#define gcvZONE_STREAM (1 << 8)
  134856. +#define gcvZONE_TEXTURE (1 << 9)
  134857. +#define gcvZONE_2D (1 << 10)
  134858. +#define gcvZONE_3D (1 << 11)
  134859. +#define gcvZONE_COMPILER (1 << 12)
  134860. +#define gcvZONE_MEMORY (1 << 13)
  134861. +#define gcvZONE_STATE (1 << 14)
  134862. +#define gcvZONE_AUX (1 << 15)
  134863. +#define gcvZONE_VERTEX (1 << 16)
  134864. +#define gcvZONE_CL (1 << 17)
  134865. +#define gcvZONE_COMPOSITION (1 << 17)
  134866. +#define gcvZONE_VG (1 << 18)
  134867. +#define gcvZONE_IMAGE (1 << 19)
  134868. +#define gcvZONE_UTILITY (1 << 20)
  134869. +#define gcvZONE_PARAMETERS (1 << 21)
  134870. +
  134871. +/* API definitions. */
  134872. +#define gcvZONE_API_HAL (1 << 28)
  134873. +#define gcvZONE_API_EGL (2 << 28)
  134874. +#define gcvZONE_API_ES11 (3 << 28)
  134875. +#define gcvZONE_API_ES20 (4 << 28)
  134876. +#define gcvZONE_API_VG11 (5 << 28)
  134877. +#define gcvZONE_API_GL (6 << 28)
  134878. +#define gcvZONE_API_DFB (7 << 28)
  134879. +#define gcvZONE_API_GDI (8 << 28)
  134880. +#define gcvZONE_API_D3D (9 << 28)
  134881. +#define gcvZONE_API_ES30 (10 << 28)
  134882. +
  134883. +
  134884. +#define gcmZONE_GET_API(zone) ((zone) >> 28)
  134885. +/*Set gcdZONE_MASE like 0x0 | gcvZONE_API_EGL
  134886. +will enable print EGL module debug info*/
  134887. +#define gcdZONE_MASK 0x0FFFFFFF
  134888. +
  134889. +/* Handy zones. */
  134890. +#define gcvZONE_NONE 0
  134891. +#define gcvZONE_ALL 0x0FFFFFFF
  134892. +
  134893. +/*Dump API depth set 1 for API, 2 for API and API behavior*/
  134894. +#define gcvDUMP_API_DEPTH 1
  134895. +
  134896. +/*******************************************************************************
  134897. +**
  134898. +** gcmTRACE_ZONE
  134899. +**
  134900. +** Print a message to the debugger if the correct level and zone has been
  134901. +** set. In retail mode this macro does nothing.
  134902. +**
  134903. +** ARGUMENTS:
  134904. +**
  134905. +** Level Level of message.
  134906. +** Zone Zone of message.
  134907. +** Message Message.
  134908. +** ... Optional arguments.
  134909. +*/
  134910. +
  134911. +void
  134912. +gckOS_DebugTraceZone(
  134913. + IN gctUINT32 Level,
  134914. + IN gctUINT32 Zone,
  134915. + IN gctCONST_STRING Message,
  134916. + ...
  134917. + );
  134918. +
  134919. +void
  134920. +gckOS_DebugTraceZoneN(
  134921. + IN gctUINT32 Level,
  134922. + IN gctUINT32 Zone,
  134923. + IN gctUINT ArgumentSize,
  134924. + IN gctCONST_STRING Message,
  134925. + ...
  134926. + );
  134927. +
  134928. +void
  134929. +gcoOS_DebugTraceZone(
  134930. + IN gctUINT32 Level,
  134931. + IN gctUINT32 Zone,
  134932. + IN gctCONST_STRING Message,
  134933. + ...
  134934. + );
  134935. +
  134936. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  134937. +# define gcmTRACE_ZONE gcoOS_DebugTraceZone
  134938. +# define gcmkTRACE_ZONE gckOS_DebugTraceZone
  134939. +# define gcmkTRACE_ZONE_N gckOS_DebugTraceZoneN
  134940. +#elif gcdHAS_ELLIPSES
  134941. +# define gcmTRACE_ZONE(...)
  134942. +# define gcmkTRACE_ZONE(...)
  134943. +# define gcmkTRACE_ZONE_N(...)
  134944. +#else
  134945. + gcmINLINE static void
  134946. + __dummy_trace_zone(
  134947. + IN gctUINT32 Level,
  134948. + IN gctUINT32 Zone,
  134949. + IN gctCONST_STRING Message,
  134950. + ...
  134951. + )
  134952. + {
  134953. + }
  134954. +
  134955. + gcmINLINE static void
  134956. + __dummy_trace_zone_n(
  134957. + IN gctUINT32 Level,
  134958. + IN gctUINT32 Zone,
  134959. + IN gctUINT ArgumentSize,
  134960. + IN gctCONST_STRING Message,
  134961. + ...
  134962. + )
  134963. + {
  134964. + }
  134965. +
  134966. +# define gcmTRACE_ZONE __dummy_trace_zone
  134967. +# define gcmkTRACE_ZONE __dummy_trace_zone
  134968. +# define gcmkTRACE_ZONE_N __dummy_trace_zone_n
  134969. +#endif
  134970. +
  134971. +/*******************************************************************************
  134972. +**
  134973. +** gcmDEBUG_ONLY
  134974. +**
  134975. +** Execute a statement or function only in DEBUG mode.
  134976. +**
  134977. +** ARGUMENTS:
  134978. +**
  134979. +** f Statement or function to execute.
  134980. +*/
  134981. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  134982. +# define gcmDEBUG_ONLY(f) f
  134983. +#else
  134984. +# define gcmDEBUG_ONLY(f)
  134985. +#endif
  134986. +
  134987. +/*******************************************************************************
  134988. +**
  134989. +** gcmSTACK_PUSH
  134990. +** gcmSTACK_POP
  134991. +** gcmSTACK_DUMP
  134992. +**
  134993. +** Push or pop a function with entry arguments on the trace stack.
  134994. +**
  134995. +** ARGUMENTS:
  134996. +**
  134997. +** Function Name of function.
  134998. +** Line Line number.
  134999. +** Text Optional text.
  135000. +** ... Optional arguments for text.
  135001. +*/
  135002. +#if gcmIS_DEBUG(gcdDEBUG_STACK)
  135003. + void
  135004. + gcoOS_StackPush(
  135005. + IN gctCONST_STRING Function,
  135006. + IN gctINT Line,
  135007. + IN gctCONST_STRING Text,
  135008. + ...
  135009. + );
  135010. + void
  135011. + gcoOS_StackPop(
  135012. + IN gctCONST_STRING Function
  135013. + );
  135014. + void
  135015. + gcoOS_StackDump(
  135016. + void
  135017. + );
  135018. +# define gcmSTACK_PUSH gcoOS_StackPush
  135019. +# define gcmSTACK_POP gcoOS_StackPop
  135020. +# define gcmSTACK_DUMP gcoOS_StackDump
  135021. +#elif gcdHAS_ELLIPSES
  135022. +# define gcmSTACK_PUSH(...) do { } while (0)
  135023. +# define gcmSTACK_POP(Function) do { } while (0)
  135024. +# define gcmSTACK_DUMP() do { } while (0)
  135025. +#else
  135026. + gcmINLINE static void
  135027. + __dummy_stack_push(
  135028. + IN gctCONST_STRING Function,
  135029. + IN gctINT Line,
  135030. + IN gctCONST_STRING Text, ...
  135031. + )
  135032. + {
  135033. + }
  135034. +# define gcmSTACK_PUSH __dummy_stack_push
  135035. +# define gcmSTACK_POP(Function) do { } while (0)
  135036. +# define gcmSTACK_DUMP() do { } while (0)
  135037. +#endif
  135038. +
  135039. +/******************************************************************************\
  135040. +******************************** Logging Macros ********************************
  135041. +\******************************************************************************/
  135042. +
  135043. +#define gcdHEADER_LEVEL gcvLEVEL_VERBOSE
  135044. +
  135045. +
  135046. +#if gcdENABLE_PROFILING
  135047. +void
  135048. +gcoOS_ProfileDB(
  135049. + IN gctCONST_STRING Function,
  135050. + IN OUT gctBOOL_PTR Initialized
  135051. + );
  135052. +
  135053. +#define gcmHEADER() \
  135054. + static gctBOOL __profile__initialized__ = gcvFALSE; \
  135055. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
  135056. + gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__)
  135057. +#define gcmHEADER_ARG(...) \
  135058. + static gctBOOL __profile__initialized__ = gcvFALSE; \
  135059. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
  135060. + gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__)
  135061. +#define gcmFOOTER() \
  135062. + gcmSTACK_POP(__FUNCTION__); \
  135063. + gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
  135064. +#define gcmFOOTER_NO() \
  135065. + gcmSTACK_POP(__FUNCTION__); \
  135066. + gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
  135067. +#define gcmFOOTER_ARG(...) \
  135068. + gcmSTACK_POP(__FUNCTION__); \
  135069. + gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
  135070. +#define gcmFOOTER_KILL() \
  135071. + gcmSTACK_POP(__FUNCTION__); \
  135072. + gcoOS_ProfileDB(gcvNULL, gcvNULL)
  135073. +
  135074. +#else /* gcdENABLE_PROFILING */
  135075. +
  135076. +#if gcdHAS_ELLIPSES
  135077. +#define gcmHEADER() \
  135078. + gctINT8 __user__ = 1; \
  135079. + gctINT8_PTR __user_ptr__ = &__user__; \
  135080. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
  135081. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135082. + "++%s(%d)", __FUNCTION__, __LINE__)
  135083. +#else
  135084. + gcmINLINE static void
  135085. + __dummy_header(void)
  135086. + {
  135087. + }
  135088. +# define gcmHEADER __dummy_header
  135089. +#endif
  135090. +
  135091. +#if gcdHAS_ELLIPSES
  135092. +# define gcmHEADER_ARG(Text, ...) \
  135093. + gctINT8 __user__ = 1; \
  135094. + gctINT8_PTR __user_ptr__ = &__user__; \
  135095. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
  135096. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135097. + "++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__)
  135098. +#else
  135099. + gcmINLINE static void
  135100. + __dummy_header_arg(
  135101. + IN gctCONST_STRING Text,
  135102. + ...
  135103. + )
  135104. + {
  135105. + }
  135106. +# define gcmHEADER_ARG __dummy_header_arg
  135107. +#endif
  135108. +
  135109. +#if gcdHAS_ELLIPSES
  135110. +# define gcmFOOTER() \
  135111. + gcmSTACK_POP(__FUNCTION__); \
  135112. + gcmPROFILE_ONLY(gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135113. + "--%s(%d) [%llu,%llu]: status=%d(%s)", \
  135114. + __FUNCTION__, __LINE__, \
  135115. + __ticks__, __total__, \
  135116. + status, gcoOS_DebugStatus2Name(status))); \
  135117. + gcmPROFILE_ELSE(gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135118. + "--%s(%d): status=%d(%s)", \
  135119. + __FUNCTION__, __LINE__, \
  135120. + status, gcoOS_DebugStatus2Name(status))); \
  135121. + *__user_ptr__ -= 1
  135122. +#else
  135123. + gcmINLINE static void
  135124. + __dummy_footer(void)
  135125. + {
  135126. + }
  135127. +# define gcmFOOTER __dummy_footer
  135128. +#endif
  135129. +
  135130. +#if gcdHAS_ELLIPSES
  135131. +#define gcmFOOTER_NO() \
  135132. + gcmSTACK_POP(__FUNCTION__); \
  135133. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135134. + "--%s(%d)", __FUNCTION__, __LINE__); \
  135135. + *__user_ptr__ -= 1
  135136. +#else
  135137. + gcmINLINE static void
  135138. + __dummy_footer_no(void)
  135139. + {
  135140. + }
  135141. +# define gcmFOOTER_NO __dummy_footer_no
  135142. +#endif
  135143. +
  135144. +#if gcdHAS_ELLIPSES
  135145. +#define gcmFOOTER_KILL() \
  135146. + gcmSTACK_POP(__FUNCTION__); \
  135147. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135148. + "--%s(%d)", __FUNCTION__, __LINE__); \
  135149. + *__user_ptr__ -= 1
  135150. +#else
  135151. + gcmINLINE static void
  135152. + __dummy_footer_kill(void)
  135153. + {
  135154. + }
  135155. +# define gcmFOOTER_KILL __dummy_footer_kill
  135156. +#endif
  135157. +
  135158. +#if gcdHAS_ELLIPSES
  135159. +# define gcmFOOTER_ARG(Text, ...) \
  135160. + gcmSTACK_POP(__FUNCTION__); \
  135161. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135162. + "--%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__); \
  135163. + *__user_ptr__ -= 1
  135164. +#else
  135165. + gcmINLINE static void
  135166. + __dummy_footer_arg(
  135167. + IN gctCONST_STRING Text,
  135168. + ...
  135169. + )
  135170. + {
  135171. + }
  135172. +# define gcmFOOTER_ARG __dummy_footer_arg
  135173. +#endif
  135174. +
  135175. +#endif /* gcdENABLE_PROFILING */
  135176. +
  135177. +#if gcdHAS_ELLIPSES
  135178. +#define gcmkHEADER() \
  135179. + gctINT8 __kernel__ = 1; \
  135180. + gctINT8_PTR __kernel_ptr__ = &__kernel__; \
  135181. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135182. + "++%s(%d)", __FUNCTION__, __LINE__)
  135183. +#else
  135184. + gcmINLINE static void
  135185. + __dummy_kheader(void)
  135186. + {
  135187. + }
  135188. +# define gcmkHEADER __dummy_kheader
  135189. +#endif
  135190. +
  135191. +#if gcdHAS_ELLIPSES
  135192. +# define gcmkHEADER_ARG(Text, ...) \
  135193. + gctINT8 __kernel__ = 1; \
  135194. + gctINT8_PTR __kernel_ptr__ = &__kernel__; \
  135195. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135196. + "++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__)
  135197. +#else
  135198. + gcmINLINE static void
  135199. + __dummy_kheader_arg(
  135200. + IN gctCONST_STRING Text,
  135201. + ...
  135202. + )
  135203. + {
  135204. + }
  135205. +# define gcmkHEADER_ARG __dummy_kheader_arg
  135206. +#endif
  135207. +
  135208. +#if gcdHAS_ELLIPSES
  135209. +#define gcmkFOOTER() \
  135210. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135211. + "--%s(%d): status=%d(%s)", \
  135212. + __FUNCTION__, __LINE__, status, gckOS_DebugStatus2Name(status)); \
  135213. + *__kernel_ptr__ -= 1
  135214. +#else
  135215. + gcmINLINE static void
  135216. + __dummy_kfooter(void)
  135217. + {
  135218. + }
  135219. +# define gcmkFOOTER __dummy_kfooter
  135220. +#endif
  135221. +
  135222. +#if gcdHAS_ELLIPSES
  135223. +#define gcmkFOOTER_NO() \
  135224. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135225. + "--%s(%d)", __FUNCTION__, __LINE__); \
  135226. + *__kernel_ptr__ -= 1
  135227. +#else
  135228. + gcmINLINE static void
  135229. + __dummy_kfooter_no(void)
  135230. + {
  135231. + }
  135232. +# define gcmkFOOTER_NO __dummy_kfooter_no
  135233. +#endif
  135234. +
  135235. +#if gcdHAS_ELLIPSES
  135236. +# define gcmkFOOTER_ARG(Text, ...) \
  135237. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  135238. + "--%s(%d): " Text, \
  135239. + __FUNCTION__, __LINE__, __VA_ARGS__); \
  135240. + *__kernel_ptr__ -= 1
  135241. +#else
  135242. + gcmINLINE static void
  135243. + __dummy_kfooter_arg(
  135244. + IN gctCONST_STRING Text,
  135245. + ...
  135246. + )
  135247. + {
  135248. + }
  135249. +# define gcmkFOOTER_ARG __dummy_kfooter_arg
  135250. +#endif
  135251. +
  135252. +#define gcmOPT_VALUE(ptr) (((ptr) == gcvNULL) ? 0 : *(ptr))
  135253. +#define gcmOPT_VALUE_INDEX(ptr, index) (((ptr) == gcvNULL) ? 0 : ptr[index])
  135254. +#define gcmOPT_POINTER(ptr) (((ptr) == gcvNULL) ? gcvNULL : *(ptr))
  135255. +#define gcmOPT_STRING(ptr) (((ptr) == gcvNULL) ? "(nil)" : (ptr))
  135256. +
  135257. +void
  135258. +gckOS_Print(
  135259. + IN gctCONST_STRING Message,
  135260. + ...
  135261. + );
  135262. +
  135263. +void
  135264. +gckOS_PrintN(
  135265. + IN gctUINT ArgumentSize,
  135266. + IN gctCONST_STRING Message,
  135267. + ...
  135268. + );
  135269. +
  135270. +void
  135271. +gckOS_CopyPrint(
  135272. + IN gctCONST_STRING Message,
  135273. + ...
  135274. + );
  135275. +
  135276. +void
  135277. +gcoOS_Print(
  135278. + IN gctCONST_STRING Message,
  135279. + ...
  135280. + );
  135281. +
  135282. +#define gcmPRINT gcoOS_Print
  135283. +#define gcmkPRINT gckOS_Print
  135284. +#define gcmkPRINT_N gckOS_PrintN
  135285. +
  135286. +#if gcdPRINT_VERSION
  135287. +# define gcmPRINT_VERSION() do { \
  135288. + _gcmPRINT_VERSION(gcm); \
  135289. + gcmSTACK_DUMP(); \
  135290. + } while (0)
  135291. +# define gcmkPRINT_VERSION() _gcmPRINT_VERSION(gcmk)
  135292. +# define _gcmPRINT_VERSION(prefix) \
  135293. + prefix##TRACE(gcvLEVEL_ERROR, \
  135294. + "Vivante HAL version %d.%d.%d build %d %s %s", \
  135295. + gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, \
  135296. + gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME )
  135297. +#else
  135298. +# define gcmPRINT_VERSION() do { gcmSTACK_DUMP(); } while (gcvFALSE)
  135299. +# define gcmkPRINT_VERSION() do { } while (gcvFALSE)
  135300. +#endif
  135301. +
  135302. +typedef enum _gceDUMP_BUFFER
  135303. +{
  135304. + gceDUMP_BUFFER_CONTEXT,
  135305. + gceDUMP_BUFFER_USER,
  135306. + gceDUMP_BUFFER_KERNEL,
  135307. + gceDUMP_BUFFER_LINK,
  135308. + gceDUMP_BUFFER_WAITLINK,
  135309. + gceDUMP_BUFFER_FROM_USER,
  135310. +}
  135311. +gceDUMP_BUFFER;
  135312. +
  135313. +void
  135314. +gckOS_DumpBuffer(
  135315. + IN gckOS Os,
  135316. + IN gctPOINTER Buffer,
  135317. + IN gctUINT Size,
  135318. + IN gceDUMP_BUFFER Type,
  135319. + IN gctBOOL CopyMessage
  135320. + );
  135321. +
  135322. +#define gcmkDUMPBUFFER gckOS_DumpBuffer
  135323. +
  135324. +#if gcdDUMP_COMMAND
  135325. +# define gcmkDUMPCOMMAND(Os, Buffer, Size, Type, CopyMessage) \
  135326. + gcmkDUMPBUFFER(Os, Buffer, Size, Type, CopyMessage)
  135327. +#else
  135328. +# define gcmkDUMPCOMMAND(Os, Buffer, Size, Type, CopyMessage)
  135329. +#endif
  135330. +
  135331. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  135332. +
  135333. +void
  135334. +gckOS_DebugFlush(
  135335. + gctCONST_STRING CallerName,
  135336. + gctUINT LineNumber,
  135337. + gctUINT32 DmaAddress
  135338. + );
  135339. +
  135340. +# define gcmkDEBUGFLUSH(DmaAddress) \
  135341. + gckOS_DebugFlush(__FUNCTION__, __LINE__, DmaAddress)
  135342. +#else
  135343. +# define gcmkDEBUGFLUSH(DmaAddress)
  135344. +#endif
  135345. +
  135346. +/*******************************************************************************
  135347. +**
  135348. +** gcmDUMP_FRAMERATE
  135349. +**
  135350. +** Print average frame rate
  135351. +**
  135352. +*/
  135353. +#if gcdDUMP_FRAMERATE
  135354. + gceSTATUS
  135355. + gcfDumpFrameRate(
  135356. + void
  135357. + );
  135358. +# define gcmDUMP_FRAMERATE gcfDumpFrameRate
  135359. +#elif gcdHAS_ELLIPSES
  135360. +# define gcmDUMP_FRAMERATE(...)
  135361. +#else
  135362. + gcmINLINE static void
  135363. + __dummy_dump_frame_rate(
  135364. + void
  135365. + )
  135366. + {
  135367. + }
  135368. +# define gcmDUMP_FRAMERATE __dummy_dump_frame_rate
  135369. +#endif
  135370. +
  135371. +
  135372. +/*******************************************************************************
  135373. +**
  135374. +** gcmDUMP
  135375. +**
  135376. +** Print a dump message.
  135377. +**
  135378. +** ARGUMENTS:
  135379. +**
  135380. +** gctSTRING Message.
  135381. +**
  135382. +** ... Optional arguments.
  135383. +*/
  135384. +#if gcdDUMP
  135385. + gceSTATUS
  135386. + gcfDump(
  135387. + IN gcoOS Os,
  135388. + IN gctCONST_STRING String,
  135389. + ...
  135390. + );
  135391. +# define gcmDUMP gcfDump
  135392. +#elif gcdHAS_ELLIPSES
  135393. +# define gcmDUMP(...)
  135394. +#else
  135395. + gcmINLINE static void
  135396. + __dummy_dump(
  135397. + IN gcoOS Os,
  135398. + IN gctCONST_STRING Message,
  135399. + ...
  135400. + )
  135401. + {
  135402. + }
  135403. +# define gcmDUMP __dummy_dump
  135404. +#endif
  135405. +
  135406. +/*******************************************************************************
  135407. +**
  135408. +** gcmDUMP_DATA
  135409. +**
  135410. +** Add data to the dump.
  135411. +**
  135412. +** ARGUMENTS:
  135413. +**
  135414. +** gctSTRING Tag
  135415. +** Tag for dump.
  135416. +**
  135417. +** gctPOINTER Logical
  135418. +** Logical address of buffer.
  135419. +**
  135420. +** gctSIZE_T Bytes
  135421. +** Number of bytes.
  135422. +*/
  135423. +
  135424. +#if gcdDUMP || gcdDUMP_COMMAND
  135425. + gceSTATUS
  135426. + gcfDumpData(
  135427. + IN gcoOS Os,
  135428. + IN gctSTRING Tag,
  135429. + IN gctPOINTER Logical,
  135430. + IN gctSIZE_T Bytes
  135431. + );
  135432. +# define gcmDUMP_DATA gcfDumpData
  135433. +#elif gcdHAS_ELLIPSES
  135434. +# define gcmDUMP_DATA(...)
  135435. +#else
  135436. + gcmINLINE static void
  135437. + __dummy_dump_data(
  135438. + IN gcoOS Os,
  135439. + IN gctSTRING Tag,
  135440. + IN gctPOINTER Logical,
  135441. + IN gctSIZE_T Bytes
  135442. + )
  135443. + {
  135444. + }
  135445. +# define gcmDUMP_DATA __dummy_dump_data
  135446. +#endif
  135447. +
  135448. +/*******************************************************************************
  135449. +**
  135450. +** gcmDUMP_BUFFER
  135451. +**
  135452. +** Print a buffer to the dump.
  135453. +**
  135454. +** ARGUMENTS:
  135455. +**
  135456. +** gctSTRING Tag
  135457. +** Tag for dump.
  135458. +**
  135459. +** gctUINT32 Physical
  135460. +** Physical address of buffer.
  135461. +**
  135462. +** gctPOINTER Logical
  135463. +** Logical address of buffer.
  135464. +**
  135465. +** gctUINT32 Offset
  135466. +** Offset into buffer.
  135467. +**
  135468. +** gctSIZE_T Bytes
  135469. +** Number of bytes.
  135470. +*/
  135471. +
  135472. +#if gcdDUMP || gcdDUMP_COMMAND
  135473. +gceSTATUS
  135474. +gcfDumpBuffer(
  135475. + IN gcoOS Os,
  135476. + IN gctSTRING Tag,
  135477. + IN gctUINT32 Physical,
  135478. + IN gctPOINTER Logical,
  135479. + IN gctUINT32 Offset,
  135480. + IN gctSIZE_T Bytes
  135481. + );
  135482. +# define gcmDUMP_BUFFER gcfDumpBuffer
  135483. +#elif gcdHAS_ELLIPSES
  135484. +# define gcmDUMP_BUFFER(...)
  135485. +#else
  135486. + gcmINLINE static void
  135487. + __dummy_dump_buffer(
  135488. + IN gcoOS Os,
  135489. + IN gctSTRING Tag,
  135490. + IN gctUINT32 Physical,
  135491. + IN gctPOINTER Logical,
  135492. + IN gctUINT32 Offset,
  135493. + IN gctSIZE_T Bytes
  135494. + )
  135495. + {
  135496. + }
  135497. +# define gcmDUMP_BUFFER __dummy_dump_buffer
  135498. +#endif
  135499. +
  135500. +/*******************************************************************************
  135501. +**
  135502. +** gcmDUMP_API
  135503. +**
  135504. +** Print a dump message for a high level API prefixed by the function name.
  135505. +**
  135506. +** ARGUMENTS:
  135507. +**
  135508. +** gctSTRING Message.
  135509. +**
  135510. +** ... Optional arguments.
  135511. +*/
  135512. +gceSTATUS gcfDumpApi(IN gctCONST_STRING String, ...);
  135513. +#if gcdDUMP_API
  135514. +# define gcmDUMP_API gcfDumpApi
  135515. +#elif gcdHAS_ELLIPSES
  135516. +# define gcmDUMP_API(...)
  135517. +#else
  135518. + gcmINLINE static void
  135519. + __dummy_dump_api(
  135520. + IN gctCONST_STRING Message,
  135521. + ...
  135522. + )
  135523. + {
  135524. + }
  135525. +# define gcmDUMP_API __dummy_dump_api
  135526. +#endif
  135527. +
  135528. +/*******************************************************************************
  135529. +**
  135530. +** gcmDUMP_API_ARRAY
  135531. +**
  135532. +** Print an array of data.
  135533. +**
  135534. +** ARGUMENTS:
  135535. +**
  135536. +** gctUINT32_PTR Pointer to array.
  135537. +** gctUINT32 Size.
  135538. +*/
  135539. +gceSTATUS gcfDumpArray(IN gctCONST_POINTER Data, IN gctUINT32 Size);
  135540. +#if gcdDUMP_API
  135541. +# define gcmDUMP_API_ARRAY gcfDumpArray
  135542. +#elif gcdHAS_ELLIPSES
  135543. +# define gcmDUMP_API_ARRAY(...)
  135544. +#else
  135545. + gcmINLINE static void
  135546. + __dummy_dump_api_array(
  135547. + IN gctCONST_POINTER Data,
  135548. + IN gctUINT32 Size
  135549. + )
  135550. + {
  135551. + }
  135552. +# define gcmDUMP_API_ARRAY __dummy_dump_api_array
  135553. +#endif
  135554. +
  135555. +/*******************************************************************************
  135556. +**
  135557. +** gcmDUMP_API_ARRAY_TOKEN
  135558. +**
  135559. +** Print an array of data terminated by a token.
  135560. +**
  135561. +** ARGUMENTS:
  135562. +**
  135563. +** gctUINT32_PTR Pointer to array.
  135564. +** gctUINT32 Termination.
  135565. +*/
  135566. +gceSTATUS gcfDumpArrayToken(IN gctCONST_POINTER Data, IN gctUINT32 Termination);
  135567. +#if gcdDUMP_API
  135568. +# define gcmDUMP_API_ARRAY_TOKEN gcfDumpArrayToken
  135569. +#elif gcdHAS_ELLIPSES
  135570. +# define gcmDUMP_API_ARRAY_TOKEN(...)
  135571. +#else
  135572. + gcmINLINE static void
  135573. + __dummy_dump_api_array_token(
  135574. + IN gctCONST_POINTER Data,
  135575. + IN gctUINT32 Termination
  135576. + )
  135577. + {
  135578. + }
  135579. +# define gcmDUMP_API_ARRAY_TOKEN __dummy_dump_api_array_token
  135580. +#endif
  135581. +
  135582. +/*******************************************************************************
  135583. +**
  135584. +** gcmDUMP_API_DATA
  135585. +**
  135586. +** Print an array of bytes.
  135587. +**
  135588. +** ARGUMENTS:
  135589. +**
  135590. +** gctCONST_POINTER Pointer to array.
  135591. +** gctSIZE_T Size.
  135592. +*/
  135593. +gceSTATUS gcfDumpApiData(IN gctCONST_POINTER Data, IN gctSIZE_T Size);
  135594. +#if gcdDUMP_API
  135595. +# define gcmDUMP_API_DATA gcfDumpApiData
  135596. +#elif gcdHAS_ELLIPSES
  135597. +# define gcmDUMP_API_DATA(...)
  135598. +#else
  135599. + gcmINLINE static void
  135600. + __dummy_dump_api_data(
  135601. + IN gctCONST_POINTER Data,
  135602. + IN gctSIZE_T Size
  135603. + )
  135604. + {
  135605. + }
  135606. +# define gcmDUMP_API_DATA __dummy_dump_api_data
  135607. +#endif
  135608. +
  135609. +/*******************************************************************************
  135610. +**
  135611. +** gcmTRACE_RELEASE
  135612. +**
  135613. +** Print a message to the shader debugger.
  135614. +**
  135615. +** ARGUMENTS:
  135616. +**
  135617. +** message Message.
  135618. +** ... Optional arguments.
  135619. +*/
  135620. +
  135621. +#define gcmTRACE_RELEASE gcoOS_DebugShaderTrace
  135622. +
  135623. +void
  135624. +gcoOS_DebugShaderTrace(
  135625. + IN gctCONST_STRING Message,
  135626. + ...
  135627. + );
  135628. +
  135629. +void
  135630. +gcoOS_SetDebugShaderFiles(
  135631. + IN gctCONST_STRING VSFileName,
  135632. + IN gctCONST_STRING FSFileName
  135633. + );
  135634. +
  135635. +void
  135636. +gcoOS_SetDebugShaderFileType(
  135637. + IN gctUINT32 ShaderType
  135638. + );
  135639. +
  135640. +void
  135641. +gcoOS_EnableDebugBuffer(
  135642. + IN gctBOOL Enable
  135643. + );
  135644. +
  135645. +/*******************************************************************************
  135646. +**
  135647. +** gcmBREAK
  135648. +**
  135649. +** Break into the debugger. In retail mode this macro does nothing.
  135650. +**
  135651. +** ARGUMENTS:
  135652. +**
  135653. +** None.
  135654. +*/
  135655. +
  135656. +void
  135657. +gcoOS_DebugBreak(
  135658. + void
  135659. + );
  135660. +
  135661. +void
  135662. +gckOS_DebugBreak(
  135663. + void
  135664. + );
  135665. +
  135666. +#if gcmIS_DEBUG(gcdDEBUG_BREAK)
  135667. +# define gcmBREAK gcoOS_DebugBreak
  135668. +# define gcmkBREAK gckOS_DebugBreak
  135669. +#else
  135670. +# define gcmBREAK()
  135671. +# define gcmkBREAK()
  135672. +#endif
  135673. +
  135674. +/*******************************************************************************
  135675. +**
  135676. +** gcmASSERT
  135677. +**
  135678. +** Evaluate an expression and break into the debugger if the expression
  135679. +** evaluates to false. In retail mode this macro does nothing.
  135680. +**
  135681. +** ARGUMENTS:
  135682. +**
  135683. +** exp Expression to evaluate.
  135684. +*/
  135685. +#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
  135686. +# define _gcmASSERT(prefix, exp) \
  135687. + do \
  135688. + { \
  135689. + if (!(exp)) \
  135690. + { \
  135691. + prefix##TRACE(gcvLEVEL_ERROR, \
  135692. + #prefix "ASSERT at %s(%d)", \
  135693. + __FUNCTION__, __LINE__); \
  135694. + prefix##TRACE(gcvLEVEL_ERROR, \
  135695. + "(%s)", #exp); \
  135696. + prefix##BREAK(); \
  135697. + } \
  135698. + } \
  135699. + while (gcvFALSE)
  135700. +# define gcmASSERT(exp) _gcmASSERT(gcm, exp)
  135701. +# define gcmkASSERT(exp) _gcmASSERT(gcmk, exp)
  135702. +#else
  135703. +# define gcmASSERT(exp)
  135704. +# define gcmkASSERT(exp)
  135705. +#endif
  135706. +
  135707. +/*******************************************************************************
  135708. +**
  135709. +** gcmVERIFY
  135710. +**
  135711. +** Verify if an expression returns true. If the expression does not
  135712. +** evaluates to true, an assertion will happen in debug mode.
  135713. +**
  135714. +** ARGUMENTS:
  135715. +**
  135716. +** exp Expression to evaluate.
  135717. +*/
  135718. +#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
  135719. +# define gcmVERIFY(exp) gcmASSERT(exp)
  135720. +# define gcmkVERIFY(exp) gcmkASSERT(exp)
  135721. +#else
  135722. +# define gcmVERIFY(exp) exp
  135723. +# define gcmkVERIFY(exp) exp
  135724. +#endif
  135725. +
  135726. +/*******************************************************************************
  135727. +**
  135728. +** gcmVERIFY_OK
  135729. +**
  135730. +** Verify a fucntion returns gcvSTATUS_OK. If the function does not return
  135731. +** gcvSTATUS_OK, an assertion will happen in debug mode.
  135732. +**
  135733. +** ARGUMENTS:
  135734. +**
  135735. +** func Function to evaluate.
  135736. +*/
  135737. +
  135738. +void
  135739. +gcoOS_Verify(
  135740. + IN gceSTATUS status
  135741. + );
  135742. +
  135743. +void
  135744. +gckOS_Verify(
  135745. + IN gceSTATUS status
  135746. + );
  135747. +
  135748. +#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
  135749. +# define gcmVERIFY_OK(func) \
  135750. + do \
  135751. + { \
  135752. + gceSTATUS verifyStatus = func; \
  135753. + gcoOS_Verify(verifyStatus); \
  135754. + if (verifyStatus != gcvSTATUS_OK) \
  135755. + { \
  135756. + gcmTRACE( \
  135757. + gcvLEVEL_ERROR, \
  135758. + "gcmVERIFY_OK(%d): function returned %d", \
  135759. + __LINE__, verifyStatus \
  135760. + ); \
  135761. + } \
  135762. + gcmASSERT(verifyStatus == gcvSTATUS_OK); \
  135763. + } \
  135764. + while (gcvFALSE)
  135765. +# define gcmkVERIFY_OK(func) \
  135766. + do \
  135767. + { \
  135768. + gceSTATUS verifyStatus = func; \
  135769. + if (verifyStatus != gcvSTATUS_OK) \
  135770. + { \
  135771. + gcmkTRACE( \
  135772. + gcvLEVEL_ERROR, \
  135773. + "gcmkVERIFY_OK(%d): function returned %d", \
  135774. + __LINE__, verifyStatus \
  135775. + ); \
  135776. + } \
  135777. + gckOS_Verify(verifyStatus); \
  135778. + gcmkASSERT(verifyStatus == gcvSTATUS_OK); \
  135779. + } \
  135780. + while (gcvFALSE)
  135781. +#else
  135782. +# define gcmVERIFY_OK(func) func
  135783. +# define gcmkVERIFY_OK(func) func
  135784. +#endif
  135785. +
  135786. +gctCONST_STRING
  135787. +gcoOS_DebugStatus2Name(
  135788. + gceSTATUS status
  135789. + );
  135790. +
  135791. +gctCONST_STRING
  135792. +gckOS_DebugStatus2Name(
  135793. + gceSTATUS status
  135794. + );
  135795. +
  135796. +/*******************************************************************************
  135797. +**
  135798. +** gcmERR_BREAK
  135799. +**
  135800. +** Executes a break statement on error.
  135801. +**
  135802. +** ASSUMPTIONS:
  135803. +**
  135804. +** 'status' variable of gceSTATUS type must be defined.
  135805. +**
  135806. +** ARGUMENTS:
  135807. +**
  135808. +** func Function to evaluate.
  135809. +*/
  135810. +#define _gcmERR_BREAK(prefix, func) \
  135811. + status = func; \
  135812. + if (gcmIS_ERROR(status)) \
  135813. + { \
  135814. + prefix##PRINT_VERSION(); \
  135815. + prefix##TRACE(gcvLEVEL_ERROR, \
  135816. + #prefix "ERR_BREAK: status=%d(%s) @ %s(%d)", \
  135817. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135818. + break; \
  135819. + } \
  135820. + do { } while (gcvFALSE)
  135821. +#define _gcmkERR_BREAK(prefix, func) \
  135822. + status = func; \
  135823. + if (gcmIS_ERROR(status)) \
  135824. + { \
  135825. + prefix##PRINT_VERSION(); \
  135826. + prefix##TRACE(gcvLEVEL_ERROR, \
  135827. + #prefix "ERR_BREAK: status=%d(%s) @ %s(%d)", \
  135828. + status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135829. + break; \
  135830. + } \
  135831. + do { } while (gcvFALSE)
  135832. +#define gcmERR_BREAK(func) _gcmERR_BREAK(gcm, func)
  135833. +#define gcmkERR_BREAK(func) _gcmkERR_BREAK(gcmk, func)
  135834. +
  135835. +/*******************************************************************************
  135836. +**
  135837. +** gcmERR_RETURN
  135838. +**
  135839. +** Executes a return on error.
  135840. +**
  135841. +** ASSUMPTIONS:
  135842. +**
  135843. +** 'status' variable of gceSTATUS type must be defined.
  135844. +**
  135845. +** ARGUMENTS:
  135846. +**
  135847. +** func Function to evaluate.
  135848. +*/
  135849. +#define _gcmERR_RETURN(prefix, func) \
  135850. + status = func; \
  135851. + if (gcmIS_ERROR(status)) \
  135852. + { \
  135853. + prefix##PRINT_VERSION(); \
  135854. + prefix##TRACE(gcvLEVEL_ERROR, \
  135855. + #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
  135856. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135857. + prefix##FOOTER(); \
  135858. + return status; \
  135859. + } \
  135860. + do { } while (gcvFALSE)
  135861. +#define _gcmkERR_RETURN(prefix, func) \
  135862. + status = func; \
  135863. + if (gcmIS_ERROR(status)) \
  135864. + { \
  135865. + prefix##PRINT_VERSION(); \
  135866. + prefix##TRACE(gcvLEVEL_ERROR, \
  135867. + #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
  135868. + status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135869. + prefix##FOOTER(); \
  135870. + return status; \
  135871. + } \
  135872. + do { } while (gcvFALSE)
  135873. +#define gcmERR_RETURN(func) _gcmERR_RETURN(gcm, func)
  135874. +#define gcmkERR_RETURN(func) _gcmkERR_RETURN(gcmk, func)
  135875. +
  135876. +
  135877. +/*******************************************************************************
  135878. +**
  135879. +** gcmONERROR
  135880. +**
  135881. +** Jump to the error handler in case there is an error.
  135882. +**
  135883. +** ASSUMPTIONS:
  135884. +**
  135885. +** 'status' variable of gceSTATUS type must be defined.
  135886. +**
  135887. +** ARGUMENTS:
  135888. +**
  135889. +** func Function to evaluate.
  135890. +*/
  135891. +#define _gcmONERROR(prefix, func) \
  135892. + do \
  135893. + { \
  135894. + status = func; \
  135895. + if (gcmIS_ERROR(status)) \
  135896. + { \
  135897. + prefix##PRINT_VERSION(); \
  135898. + prefix##TRACE(gcvLEVEL_ERROR, \
  135899. + #prefix "ONERROR: status=%d(%s) @ %s(%d)", \
  135900. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135901. + goto OnError; \
  135902. + } \
  135903. + } \
  135904. + while (gcvFALSE)
  135905. +#define _gcmkONERROR(prefix, func) \
  135906. + do \
  135907. + { \
  135908. + status = func; \
  135909. + if (gcmIS_ERROR(status)) \
  135910. + { \
  135911. + prefix##PRINT_VERSION(); \
  135912. + prefix##TRACE(gcvLEVEL_ERROR, \
  135913. + #prefix "ONERROR: status=%d(%s) @ %s(%d)", \
  135914. + status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  135915. + goto OnError; \
  135916. + } \
  135917. + } \
  135918. + while (gcvFALSE)
  135919. +#define gcmONERROR(func) _gcmONERROR(gcm, func)
  135920. +#define gcmkONERROR(func) _gcmkONERROR(gcmk, func)
  135921. +
  135922. +/*******************************************************************************
  135923. +**
  135924. +** gcmVERIFY_LOCK
  135925. +**
  135926. +** Verifies whether the surface is locked.
  135927. +**
  135928. +** ARGUMENTS:
  135929. +**
  135930. +** surfaceInfo Pointer to the surface iniformational structure.
  135931. +*/
  135932. +#define gcmVERIFY_LOCK(surfaceInfo) \
  135933. + if (!surfaceInfo->node.valid) \
  135934. + { \
  135935. + gcmONERROR(gcvSTATUS_MEMORY_UNLOCKED); \
  135936. + } \
  135937. +
  135938. +/*******************************************************************************
  135939. +**
  135940. +** gcmVERIFY_NODE_LOCK
  135941. +**
  135942. +** Verifies whether the surface node is locked.
  135943. +**
  135944. +** ARGUMENTS:
  135945. +**
  135946. +** surfaceInfo Pointer to the surface iniformational structure.
  135947. +*/
  135948. +#define gcmVERIFY_NODE_LOCK(surfaceNode) \
  135949. + if (!(surfaceNode)->valid) \
  135950. + { \
  135951. + status = gcvSTATUS_MEMORY_UNLOCKED; \
  135952. + break; \
  135953. + } \
  135954. + do { } while (gcvFALSE)
  135955. +
  135956. +/*******************************************************************************
  135957. +**
  135958. +** gcmBADOBJECT_BREAK
  135959. +**
  135960. +** Executes a break statement on bad object.
  135961. +**
  135962. +** ARGUMENTS:
  135963. +**
  135964. +** obj Object to test.
  135965. +** t Expected type of the object.
  135966. +*/
  135967. +#define gcmBADOBJECT_BREAK(obj, t) \
  135968. + if ((obj == gcvNULL) \
  135969. + || (((gcsOBJECT *)(obj))->type != t) \
  135970. + ) \
  135971. + { \
  135972. + status = gcvSTATUS_INVALID_OBJECT; \
  135973. + break; \
  135974. + } \
  135975. + do { } while (gcvFALSE)
  135976. +
  135977. +/*******************************************************************************
  135978. +**
  135979. +** gcmCHECK_STATUS
  135980. +**
  135981. +** Executes a break statement on error.
  135982. +**
  135983. +** ASSUMPTIONS:
  135984. +**
  135985. +** 'status' variable of gceSTATUS type must be defined.
  135986. +**
  135987. +** ARGUMENTS:
  135988. +**
  135989. +** func Function to evaluate.
  135990. +*/
  135991. +#define _gcmCHECK_STATUS(prefix, func) \
  135992. + do \
  135993. + { \
  135994. + last = func; \
  135995. + if (gcmIS_ERROR(last)) \
  135996. + { \
  135997. + prefix##TRACE(gcvLEVEL_ERROR, \
  135998. + #prefix "CHECK_STATUS: status=%d(%s) @ %s(%d)", \
  135999. + last, gcoOS_DebugStatus2Name(last), __FUNCTION__, __LINE__); \
  136000. + status = last; \
  136001. + } \
  136002. + } \
  136003. + while (gcvFALSE)
  136004. +#define _gcmkCHECK_STATUS(prefix, func) \
  136005. + do \
  136006. + { \
  136007. + last = func; \
  136008. + if (gcmIS_ERROR(last)) \
  136009. + { \
  136010. + prefix##TRACE(gcvLEVEL_ERROR, \
  136011. + #prefix "CHECK_STATUS: status=%d(%s) @ %s(%d)", \
  136012. + last, gckOS_DebugStatus2Name(last), __FUNCTION__, __LINE__); \
  136013. + status = last; \
  136014. + } \
  136015. + } \
  136016. + while (gcvFALSE)
  136017. +#define gcmCHECK_STATUS(func) _gcmCHECK_STATUS(gcm, func)
  136018. +#define gcmkCHECK_STATUS(func) _gcmkCHECK_STATUS(gcmk, func)
  136019. +
  136020. +/*******************************************************************************
  136021. +**
  136022. +** gcmVERIFY_ARGUMENT
  136023. +**
  136024. +** Assert if an argument does not apply to the specified expression. If
  136025. +** the argument evaluates to false, gcvSTATUS_INVALID_ARGUMENT will be
  136026. +** returned from the current function. In retail mode this macro does
  136027. +** nothing.
  136028. +**
  136029. +** ARGUMENTS:
  136030. +**
  136031. +** arg Argument to evaluate.
  136032. +*/
  136033. +# define _gcmVERIFY_ARGUMENT(prefix, arg) \
  136034. + do \
  136035. + { \
  136036. + if (!(arg)) \
  136037. + { \
  136038. + prefix##TRACE(gcvLEVEL_ERROR, #prefix "VERIFY_ARGUMENT failed:"); \
  136039. + prefix##ASSERT(arg); \
  136040. + prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT); \
  136041. + return gcvSTATUS_INVALID_ARGUMENT; \
  136042. + } \
  136043. + } \
  136044. + while (gcvFALSE)
  136045. +# define gcmVERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcm, arg)
  136046. +# define gcmkVERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcmk, arg)
  136047. +
  136048. +/*******************************************************************************
  136049. +**
  136050. +** gcmDEBUG_VERIFY_ARGUMENT
  136051. +**
  136052. +** Works just like gcmVERIFY_ARGUMENT, but is only valid in debug mode.
  136053. +** Use this to verify arguments inside non-public API functions.
  136054. +*/
  136055. +#if gcdDEBUG
  136056. +# define gcmDEBUG_VERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcm, arg)
  136057. +# define gcmkDEBUG_VERIFY_ARGUMENT(arg) _gcmkVERIFY_ARGUMENT(gcm, arg)
  136058. +#else
  136059. +# define gcmDEBUG_VERIFY_ARGUMENT(arg)
  136060. +# define gcmkDEBUG_VERIFY_ARGUMENT(arg)
  136061. +#endif
  136062. +
  136063. +/*******************************************************************************
  136064. +**
  136065. +** gcmVERIFY_ARGUMENT_RETURN
  136066. +**
  136067. +** Assert if an argument does not apply to the specified expression. If
  136068. +** the argument evaluates to false, gcvSTATUS_INVALID_ARGUMENT will be
  136069. +** returned from the current function. In retail mode this macro does
  136070. +** nothing.
  136071. +**
  136072. +** ARGUMENTS:
  136073. +**
  136074. +** arg Argument to evaluate.
  136075. +*/
  136076. +# define _gcmVERIFY_ARGUMENT_RETURN(prefix, arg, value) \
  136077. + do \
  136078. + { \
  136079. + if (!(arg)) \
  136080. + { \
  136081. + prefix##TRACE(gcvLEVEL_ERROR, \
  136082. + #prefix "gcmVERIFY_ARGUMENT_RETURN failed:"); \
  136083. + prefix##ASSERT(arg); \
  136084. + prefix##FOOTER_ARG("value=%d", value); \
  136085. + return value; \
  136086. + } \
  136087. + } \
  136088. + while (gcvFALSE)
  136089. +# define gcmVERIFY_ARGUMENT_RETURN(arg, value) \
  136090. + _gcmVERIFY_ARGUMENT_RETURN(gcm, arg, value)
  136091. +# define gcmkVERIFY_ARGUMENT_RETURN(arg, value) \
  136092. + _gcmVERIFY_ARGUMENT_RETURN(gcmk, arg, value)
  136093. +
  136094. +#define MAX_LOOP_COUNT 0x7FFFFFFF
  136095. +
  136096. +/******************************************************************************\
  136097. +****************************** User Debug Option ******************************
  136098. +\******************************************************************************/
  136099. +
  136100. +/* User option. */
  136101. +typedef enum _gceDEBUG_MSG
  136102. +{
  136103. + gcvDEBUG_MSG_NONE,
  136104. + gcvDEBUG_MSG_ERROR,
  136105. + gcvDEBUG_MSG_WARNING
  136106. +}
  136107. +gceDEBUG_MSG;
  136108. +
  136109. +typedef struct _gcsUSER_DEBUG_OPTION
  136110. +{
  136111. + gceDEBUG_MSG debugMsg;
  136112. +}
  136113. +gcsUSER_DEBUG_OPTION;
  136114. +
  136115. +gcsUSER_DEBUG_OPTION *
  136116. +gcGetUserDebugOption(
  136117. + void
  136118. + );
  136119. +
  136120. +struct _gcoOS_SymbolsList
  136121. +{
  136122. + gcePATCH_ID patchId;
  136123. + const char * symList[10];
  136124. +};
  136125. +
  136126. +#if gcdHAS_ELLIPSES
  136127. +#define gcmUSER_DEBUG_MSG(level, ...) \
  136128. + do \
  136129. + { \
  136130. + if (level <= gcGetUserDebugOption()->debugMsg) \
  136131. + { \
  136132. + gcoOS_Print(__VA_ARGS__); \
  136133. + } \
  136134. + } while (gcvFALSE)
  136135. +
  136136. +#define gcmUSER_DEBUG_ERROR_MSG(...) gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_ERROR, "Error: " __VA_ARGS__)
  136137. +#define gcmUSER_DEBUG_WARNING_MSG(...) gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_WARNING, "Warring: " __VA_ARGS__)
  136138. +#else
  136139. +#define gcmUSER_DEBUG_MSG
  136140. +#define gcmUSER_DEBUG_ERROR_MSG
  136141. +#define gcmUSER_DEBUG_WARNING_MSG
  136142. +#endif
  136143. +
  136144. +#ifdef __cplusplus
  136145. +}
  136146. +#endif
  136147. +
  136148. +#endif /* __gc_hal_base_h_ */
  136149. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
  136150. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h 1969-12-31 18:00:00.000000000 -0600
  136151. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h 2014-12-08 00:31:53.468418001 -0600
  136152. @@ -0,0 +1,4298 @@
  136153. +/****************************************************************************
  136154. +*
  136155. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  136156. +*
  136157. +* This program is free software; you can redistribute it and/or modify
  136158. +* it under the terms of the GNU General Public License as published by
  136159. +* the Free Software Foundation; either version 2 of the license, or
  136160. +* (at your option) any later version.
  136161. +*
  136162. +* This program is distributed in the hope that it will be useful,
  136163. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  136164. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  136165. +* GNU General Public License for more details.
  136166. +*
  136167. +* You should have received a copy of the GNU General Public License
  136168. +* along with this program; if not write to the Free Software
  136169. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  136170. +*
  136171. +*****************************************************************************/
  136172. +
  136173. +/*
  136174. +** Include file the defines the front- and back-end compilers, as well as the
  136175. +** objects they use.
  136176. +*/
  136177. +
  136178. +#ifndef __gc_hal_compiler_h_
  136179. +#define __gc_hal_compiler_h_
  136180. +
  136181. +#ifndef VIVANTE_NO_3D
  136182. +#include "gc_hal_types.h"
  136183. +#include "gc_hal_engine.h"
  136184. +
  136185. +#ifdef __cplusplus
  136186. +extern "C" {
  136187. +#endif
  136188. +
  136189. +#ifndef GC_ENABLE_LOADTIME_OPT
  136190. +#define GC_ENABLE_LOADTIME_OPT 1
  136191. +#endif
  136192. +
  136193. +#define TEMP_OPT_CONSTANT_TEXLD_COORD 0
  136194. +
  136195. +#define TEMP_SHADER_PATCH 1
  136196. +
  136197. +#define TEMP_INLINE_ALL_EXPANSION 1
  136198. +/******************************* IR VERSION ******************/
  136199. +#define gcdSL_IR_VERSION gcmCC('\0','\0','\0','\1')
  136200. +
  136201. +/******************************************************************************\
  136202. +|******************************* SHADER LANGUAGE ******************************|
  136203. +\******************************************************************************/
  136204. +
  136205. + /* allocator/deallocator function pointer */
  136206. +typedef gceSTATUS (*gctAllocatorFunc)(
  136207. + IN gctSIZE_T Bytes,
  136208. + OUT gctPOINTER * Memory
  136209. + );
  136210. +
  136211. +typedef gceSTATUS (*gctDeallocatorFunc)(
  136212. + IN gctPOINTER Memory
  136213. + );
  136214. +
  136215. +typedef gctBOOL (*compareFunc) (
  136216. + IN void * data,
  136217. + IN void * key
  136218. + );
  136219. +
  136220. +typedef struct _gcsListNode gcsListNode;
  136221. +struct _gcsListNode
  136222. +{
  136223. + gcsListNode * next;
  136224. + void * data;
  136225. +};
  136226. +
  136227. +typedef struct _gcsAllocator
  136228. +{
  136229. + gctAllocatorFunc allocate;
  136230. + gctDeallocatorFunc deallocate;
  136231. +} gcsAllocator;
  136232. +
  136233. +/* simple map structure */
  136234. +typedef struct _SimpleMap SimpleMap;
  136235. +struct _SimpleMap
  136236. +{
  136237. + gctUINT32 key;
  136238. + gctUINT32 val;
  136239. + SimpleMap *next;
  136240. + gcsAllocator *allocator;
  136241. +
  136242. +};
  136243. +
  136244. +/* SimpleMap Operations */
  136245. +/* return -1 if not found, otherwise return the mapped value */
  136246. +gctUINT32
  136247. +gcSimpleMap_Find(
  136248. + IN SimpleMap *Map,
  136249. + IN gctUINT32 Key
  136250. + );
  136251. +
  136252. +gceSTATUS
  136253. +gcSimpleMap_Destory(
  136254. + IN SimpleMap * Map,
  136255. + IN gcsAllocator * Allocator
  136256. + );
  136257. +
  136258. +/* Add a pair <Key, Val> to the Map head, the user should be aware that the
  136259. + * map pointer is always changed when adding a new node :
  136260. + *
  136261. + * gcSimpleMap_AddNode(&theMap, key, val, allocator);
  136262. + *
  136263. + */
  136264. +gceSTATUS
  136265. +gcSimpleMap_AddNode(
  136266. + IN SimpleMap ** Map,
  136267. + IN gctUINT32 Key,
  136268. + IN gctUINT32 Val,
  136269. + IN gcsAllocator * Allocator
  136270. + );
  136271. +
  136272. +/* gcsList data structure and related operations */
  136273. +typedef struct _gcsList
  136274. +{
  136275. + gcsListNode *head;
  136276. + gcsListNode *tail;
  136277. + gctINT count;
  136278. + gcsAllocator *allocator;
  136279. +} gcsList;
  136280. +
  136281. +/* List operations */
  136282. +void
  136283. +gcList_Init(
  136284. + IN gcsList *list,
  136285. + IN gcsAllocator *allocator
  136286. + );
  136287. +
  136288. +gceSTATUS
  136289. +gcList_CreateNode(
  136290. + IN void * Data,
  136291. + IN gctAllocatorFunc Allocator,
  136292. + OUT gcsListNode ** ListNode
  136293. + );
  136294. +
  136295. +gceSTATUS
  136296. +gcList_Clean(
  136297. + IN gcsList * List,
  136298. + IN gctBOOL FreeData
  136299. + );
  136300. +
  136301. +gcsListNode *
  136302. +gcList_FindNode(
  136303. + IN gcsList * List,
  136304. + IN void * Key,
  136305. + IN compareFunc compare
  136306. + );
  136307. +
  136308. +gceSTATUS
  136309. +gcList_AddNode(
  136310. + IN gcsList * List,
  136311. + IN void * Data
  136312. + );
  136313. +
  136314. +gceSTATUS
  136315. +gcList_RemoveNode(
  136316. + IN gcsList * List,
  136317. + IN gcsListNode * Node
  136318. + );
  136319. +
  136320. +/* link list structure for code list */
  136321. +typedef gcsList gcsCodeList;
  136322. +typedef gcsCodeList * gctCodeList;
  136323. +typedef gcsListNode gcsCodeListNode;
  136324. +
  136325. +/* Possible shader language opcodes. */
  136326. +typedef enum _gcSL_OPCODE
  136327. +{
  136328. + gcSL_NOP, /* 0x00 */
  136329. + gcSL_MOV, /* 0x01 */
  136330. + gcSL_SAT, /* 0x02 */
  136331. + gcSL_DP3, /* 0x03 */
  136332. + gcSL_DP4, /* 0x04 */
  136333. + gcSL_ABS, /* 0x05 */
  136334. + gcSL_JMP, /* 0x06 */
  136335. + gcSL_ADD, /* 0x07 */
  136336. + gcSL_MUL, /* 0x08 */
  136337. + gcSL_RCP, /* 0x09 */
  136338. + gcSL_SUB, /* 0x0A */
  136339. + gcSL_KILL, /* 0x0B */
  136340. + gcSL_TEXLD, /* 0x0C */
  136341. + gcSL_CALL, /* 0x0D */
  136342. + gcSL_RET, /* 0x0E */
  136343. + gcSL_NORM, /* 0x0F */
  136344. + gcSL_MAX, /* 0x10 */
  136345. + gcSL_MIN, /* 0x11 */
  136346. + gcSL_POW, /* 0x12 */
  136347. + gcSL_RSQ, /* 0x13 */
  136348. + gcSL_LOG, /* 0x14 */
  136349. + gcSL_FRAC, /* 0x15 */
  136350. + gcSL_FLOOR, /* 0x16 */
  136351. + gcSL_CEIL, /* 0x17 */
  136352. + gcSL_CROSS, /* 0x18 */
  136353. + gcSL_TEXLDP, /* 0x19 */
  136354. + gcSL_TEXBIAS, /* 0x1A */
  136355. + gcSL_TEXGRAD, /* 0x1B */
  136356. + gcSL_TEXLOD, /* 0x1C */
  136357. + gcSL_SIN, /* 0x1D */
  136358. + gcSL_COS, /* 0x1E */
  136359. + gcSL_TAN, /* 0x1F */
  136360. + gcSL_EXP, /* 0x20 */
  136361. + gcSL_SIGN, /* 0x21 */
  136362. + gcSL_STEP, /* 0x22 */
  136363. + gcSL_SQRT, /* 0x23 */
  136364. + gcSL_ACOS, /* 0x24 */
  136365. + gcSL_ASIN, /* 0x25 */
  136366. + gcSL_ATAN, /* 0x26 */
  136367. + gcSL_SET, /* 0x27 */
  136368. + gcSL_DSX, /* 0x28 */
  136369. + gcSL_DSY, /* 0x29 */
  136370. + gcSL_FWIDTH, /* 0x2A */
  136371. + gcSL_DIV, /* 0x2B */
  136372. + gcSL_MOD, /* 0x2C */
  136373. + gcSL_AND_BITWISE, /* 0x2D */
  136374. + gcSL_OR_BITWISE, /* 0x2E */
  136375. + gcSL_XOR_BITWISE, /* 0x2F */
  136376. + gcSL_NOT_BITWISE, /* 0x30 */
  136377. + gcSL_LSHIFT, /* 0x31 */
  136378. + gcSL_RSHIFT, /* 0x32 */
  136379. + gcSL_ROTATE, /* 0x33 */
  136380. + gcSL_BITSEL, /* 0x34 */
  136381. + gcSL_LEADZERO, /* 0x35 */
  136382. + gcSL_LOAD, /* 0x36 */
  136383. + gcSL_STORE, /* 0x37 */
  136384. + gcSL_BARRIER, /* 0x38 */
  136385. + gcSL_STORE1, /* 0x39 */
  136386. + gcSL_ATOMADD, /* 0x3A */
  136387. + gcSL_ATOMSUB, /* 0x3B */
  136388. + gcSL_ATOMXCHG, /* 0x3C */
  136389. + gcSL_ATOMCMPXCHG, /* 0x3D */
  136390. + gcSL_ATOMMIN, /* 0x3E */
  136391. + gcSL_ATOMMAX, /* 0x3F */
  136392. + gcSL_ATOMOR, /* 0x40 */
  136393. + gcSL_ATOMAND, /* 0x41 */
  136394. + gcSL_ATOMXOR, /* 0x42 */
  136395. + /*gcSL_UNUSED, 0x43 */
  136396. + /*gcSL_UNUSED, 0x44 */
  136397. + /*gcSL_UNUSED, 0x45 */
  136398. + /*gcSL_UNUSED, 0x46 */
  136399. + /*gcSL_UNUSED, 0x47 */
  136400. + /*gcSL_UNUSED, 0x48 */
  136401. + /*gcSL_UNUSED, 0x49 */
  136402. + /*gcSL_UNUSED, 0x4A */
  136403. + /*gcSL_UNUSED, 0x4B */
  136404. + /*gcSL_UNUSED, 0x4C */
  136405. + /*gcSL_UNUSED, 0x4D */
  136406. + /*gcSL_UNUSED, 0x4E */
  136407. + /*gcSL_UNUSED, 0x4F */
  136408. + /*gcSL_UNUSED, 0x50 */
  136409. + /*gcSL_UNUSED, 0x51 */
  136410. + /*gcSL_UNUSED, 0x52 */
  136411. + gcSL_ADDLO = 0x53, /* 0x53 */ /* Float only. */
  136412. + gcSL_MULLO, /* 0x54 */ /* Float only. */
  136413. + gcSL_CONV, /* 0x55 */
  136414. + gcSL_GETEXP, /* 0x56 */
  136415. + gcSL_GETMANT, /* 0x57 */
  136416. + gcSL_MULHI, /* 0x58 */ /* Integer only. */
  136417. + gcSL_CMP, /* 0x59 */
  136418. + gcSL_I2F, /* 0x5A */
  136419. + gcSL_F2I, /* 0x5B */
  136420. + gcSL_ADDSAT, /* 0x5C */ /* Integer only. */
  136421. + gcSL_SUBSAT, /* 0x5D */ /* Integer only. */
  136422. + gcSL_MULSAT, /* 0x5E */ /* Integer only. */
  136423. + gcSL_DP2, /* 0x5F */
  136424. + gcSL_MAXOPCODE
  136425. +}
  136426. +gcSL_OPCODE;
  136427. +
  136428. +typedef enum _gcSL_FORMAT
  136429. +{
  136430. + gcSL_FLOAT = 0, /* 0 */
  136431. + gcSL_INTEGER = 1, /* 1 */
  136432. + gcSL_INT32 = 1, /* 1 */
  136433. + gcSL_BOOLEAN = 2, /* 2 */
  136434. + gcSL_UINT32 = 3, /* 3 */
  136435. + gcSL_INT8, /* 4 */
  136436. + gcSL_UINT8, /* 5 */
  136437. + gcSL_INT16, /* 6 */
  136438. + gcSL_UINT16, /* 7 */
  136439. + gcSL_INT64, /* 8 */ /* Reserved for future enhancement. */
  136440. + gcSL_UINT64, /* 9 */ /* Reserved for future enhancement. */
  136441. + gcSL_INT128, /* 10 */ /* Reserved for future enhancement. */
  136442. + gcSL_UINT128, /* 11 */ /* Reserved for future enhancement. */
  136443. + gcSL_FLOAT16, /* 12 */
  136444. + gcSL_FLOAT64, /* 13 */ /* Reserved for future enhancement. */
  136445. + gcSL_FLOAT128, /* 14 */ /* Reserved for future enhancement. */
  136446. +}
  136447. +gcSL_FORMAT;
  136448. +
  136449. +/* Destination write enable bits. */
  136450. +typedef enum _gcSL_ENABLE
  136451. +{
  136452. + gcSL_ENABLE_NONE = 0x0, /* none is enabled, error/uninitialized state */
  136453. + gcSL_ENABLE_X = 0x1,
  136454. + gcSL_ENABLE_Y = 0x2,
  136455. + gcSL_ENABLE_Z = 0x4,
  136456. + gcSL_ENABLE_W = 0x8,
  136457. + /* Combinations. */
  136458. + gcSL_ENABLE_XY = gcSL_ENABLE_X | gcSL_ENABLE_Y,
  136459. + gcSL_ENABLE_XYZ = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z,
  136460. + gcSL_ENABLE_XYZW = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W,
  136461. + gcSL_ENABLE_XYW = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_W,
  136462. + gcSL_ENABLE_XZ = gcSL_ENABLE_X | gcSL_ENABLE_Z,
  136463. + gcSL_ENABLE_XZW = gcSL_ENABLE_X | gcSL_ENABLE_Z | gcSL_ENABLE_W,
  136464. + gcSL_ENABLE_XW = gcSL_ENABLE_X | gcSL_ENABLE_W,
  136465. + gcSL_ENABLE_YZ = gcSL_ENABLE_Y | gcSL_ENABLE_Z,
  136466. + gcSL_ENABLE_YZW = gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W,
  136467. + gcSL_ENABLE_YW = gcSL_ENABLE_Y | gcSL_ENABLE_W,
  136468. + gcSL_ENABLE_ZW = gcSL_ENABLE_Z | gcSL_ENABLE_W,
  136469. +}
  136470. +gcSL_ENABLE;
  136471. +
  136472. +/* Possible indices. */
  136473. +typedef enum _gcSL_INDEXED
  136474. +{
  136475. + gcSL_NOT_INDEXED, /* 0 */
  136476. + gcSL_INDEXED_X, /* 1 */
  136477. + gcSL_INDEXED_Y, /* 2 */
  136478. + gcSL_INDEXED_Z, /* 3 */
  136479. + gcSL_INDEXED_W, /* 4 */
  136480. +}
  136481. +gcSL_INDEXED;
  136482. +
  136483. +/* Opcode conditions. */
  136484. +typedef enum _gcSL_CONDITION
  136485. +{
  136486. + gcSL_ALWAYS, /* 0x0 */
  136487. + gcSL_NOT_EQUAL, /* 0x1 */
  136488. + gcSL_LESS_OR_EQUAL, /* 0x2 */
  136489. + gcSL_LESS, /* 0x3 */
  136490. + gcSL_EQUAL, /* 0x4 */
  136491. + gcSL_GREATER, /* 0x5 */
  136492. + gcSL_GREATER_OR_EQUAL, /* 0x6 */
  136493. + gcSL_AND, /* 0x7 */
  136494. + gcSL_OR, /* 0x8 */
  136495. + gcSL_XOR, /* 0x9 */
  136496. + gcSL_NOT_ZERO, /* 0xA */
  136497. +}
  136498. +gcSL_CONDITION;
  136499. +
  136500. +/* Possible source operand types. */
  136501. +typedef enum _gcSL_TYPE
  136502. +{
  136503. + gcSL_NONE, /* 0x0 */
  136504. + gcSL_TEMP, /* 0x1 */
  136505. + gcSL_ATTRIBUTE, /* 0x2 */
  136506. + gcSL_UNIFORM, /* 0x3 */
  136507. + gcSL_SAMPLER, /* 0x4 */
  136508. + gcSL_CONSTANT, /* 0x5 */
  136509. + gcSL_OUTPUT, /* 0x6 */
  136510. + gcSL_PHYSICAL, /* 0x7 */
  136511. +}
  136512. +gcSL_TYPE;
  136513. +
  136514. +/* Swizzle generator macro. */
  136515. +#define gcmSWIZZLE(Component1, Component2, Component3, Component4) \
  136516. +( \
  136517. + (gcSL_SWIZZLE_ ## Component1 << 0) | \
  136518. + (gcSL_SWIZZLE_ ## Component2 << 2) | \
  136519. + (gcSL_SWIZZLE_ ## Component3 << 4) | \
  136520. + (gcSL_SWIZZLE_ ## Component4 << 6) \
  136521. +)
  136522. +
  136523. +#define gcmExtractSwizzle(Swizzle, Index) \
  136524. + ((gcSL_SWIZZLE) ((((Swizzle) >> (Index * 2)) & 0x3)))
  136525. +
  136526. +#define gcmComposeSwizzle(SwizzleX, SwizzleY, SwizzleZ, SwizzleW) \
  136527. +( \
  136528. + ((SwizzleX) << 0) | \
  136529. + ((SwizzleY) << 2) | \
  136530. + ((SwizzleZ) << 4) | \
  136531. + ((SwizzleW) << 6) \
  136532. +)
  136533. +
  136534. +/* Possible swizzle values. */
  136535. +typedef enum _gcSL_SWIZZLE
  136536. +{
  136537. + gcSL_SWIZZLE_X, /* 0x0 */
  136538. + gcSL_SWIZZLE_Y, /* 0x1 */
  136539. + gcSL_SWIZZLE_Z, /* 0x2 */
  136540. + gcSL_SWIZZLE_W, /* 0x3 */
  136541. + /* Combinations. */
  136542. + gcSL_SWIZZLE_XXXX = gcmSWIZZLE(X, X, X, X),
  136543. + gcSL_SWIZZLE_YYYY = gcmSWIZZLE(Y, Y, Y, Y),
  136544. + gcSL_SWIZZLE_ZZZZ = gcmSWIZZLE(Z, Z, Z, Z),
  136545. + gcSL_SWIZZLE_WWWW = gcmSWIZZLE(W, W, W, W),
  136546. + gcSL_SWIZZLE_XYYY = gcmSWIZZLE(X, Y, Y, Y),
  136547. + gcSL_SWIZZLE_XZZZ = gcmSWIZZLE(X, Z, Z, Z),
  136548. + gcSL_SWIZZLE_XWWW = gcmSWIZZLE(X, W, W, W),
  136549. + gcSL_SWIZZLE_YZZZ = gcmSWIZZLE(Y, Z, Z, Z),
  136550. + gcSL_SWIZZLE_YWWW = gcmSWIZZLE(Y, W, W, W),
  136551. + gcSL_SWIZZLE_ZWWW = gcmSWIZZLE(Z, W, W, W),
  136552. + gcSL_SWIZZLE_XYZZ = gcmSWIZZLE(X, Y, Z, Z),
  136553. + gcSL_SWIZZLE_XYWW = gcmSWIZZLE(X, Y, W, W),
  136554. + gcSL_SWIZZLE_XZWW = gcmSWIZZLE(X, Z, W, W),
  136555. + gcSL_SWIZZLE_YZWW = gcmSWIZZLE(Y, Z, W, W),
  136556. + gcSL_SWIZZLE_XXYZ = gcmSWIZZLE(X, X, Y, Z),
  136557. + gcSL_SWIZZLE_XYZW = gcmSWIZZLE(X, Y, Z, W),
  136558. + gcSL_SWIZZLE_XYXY = gcmSWIZZLE(X, Y, X, Y),
  136559. + gcSL_SWIZZLE_YYZZ = gcmSWIZZLE(Y, Y, Z, Z),
  136560. + gcSL_SWIZZLE_YYWW = gcmSWIZZLE(Y, Y, W, W),
  136561. + gcSL_SWIZZLE_ZZZW = gcmSWIZZLE(Z, Z, Z, W),
  136562. + gcSL_SWIZZLE_XZZW = gcmSWIZZLE(X, Z, Z, W),
  136563. + gcSL_SWIZZLE_YYZW = gcmSWIZZLE(Y, Y, Z, W),
  136564. +
  136565. + gcSL_SWIZZLE_INVALID = 0x7FFFFFFF
  136566. +}
  136567. +gcSL_SWIZZLE;
  136568. +
  136569. +typedef enum _gcSL_COMPONENT
  136570. +{
  136571. + gcSL_COMPONENT_X, /* 0x0 */
  136572. + gcSL_COMPONENT_Y, /* 0x1 */
  136573. + gcSL_COMPONENT_Z, /* 0x2 */
  136574. + gcSL_COMPONENT_W, /* 0x3 */
  136575. + gcSL_COMPONENT_COUNT /* 0x4 */
  136576. +} gcSL_COMPONENT;
  136577. +
  136578. +#define gcmIsComponentEnabled(Enable, Component) (((Enable) & (1 << (Component))) != 0)
  136579. +
  136580. +/******************************************************************************\
  136581. +|*********************************** SHADERS **********************************|
  136582. +\******************************************************************************/
  136583. +
  136584. +/* Shader types. */
  136585. +typedef enum _gcSHADER_KIND {
  136586. + gcSHADER_TYPE_UNKNOWN = 0,
  136587. + gcSHADER_TYPE_VERTEX,
  136588. + gcSHADER_TYPE_FRAGMENT,
  136589. + gcSHADER_TYPE_CL,
  136590. + gcSHADER_TYPE_PRECOMPILED,
  136591. + gcSHADER_KIND_COUNT
  136592. +} gcSHADER_KIND;
  136593. +
  136594. +typedef enum _gcGL_DRIVER_VERSION {
  136595. + gcGL_DRIVER_ES11, /* OpenGL ES 1.1 */
  136596. + gcGL_DRIVER_ES20, /* OpenGL ES 2.0 */
  136597. + gcGL_DRIVER_ES30 /* OpenGL ES 3.0 */
  136598. +} gcGL_DRIVER_VERSION;
  136599. +
  136600. +/* gcSHADER objects. */
  136601. +typedef struct _gcSHADER * gcSHADER;
  136602. +typedef struct _gcATTRIBUTE * gcATTRIBUTE;
  136603. +typedef struct _gcUNIFORM * gcUNIFORM;
  136604. +typedef struct _gcOUTPUT * gcOUTPUT;
  136605. +typedef struct _gcsFUNCTION * gcFUNCTION;
  136606. +typedef struct _gcsKERNEL_FUNCTION * gcKERNEL_FUNCTION;
  136607. +typedef struct _gcsHINT * gcsHINT_PTR;
  136608. +typedef struct _gcSHADER_PROFILER * gcSHADER_PROFILER;
  136609. +typedef struct _gcVARIABLE * gcVARIABLE;
  136610. +
  136611. +struct _gcsHINT
  136612. +{
  136613. + /* Numbr of data transfers for Vertex Shader output. */
  136614. + gctUINT32 vsOutputCount;
  136615. +
  136616. + /* Flag whether the VS has point size or not. */
  136617. + gctBOOL vsHasPointSize;
  136618. +
  136619. +#if gcdUSE_WCLIP_PATCH
  136620. + /* Flag whether the VS gl_position.z depends on gl_position.w
  136621. + it's a hint for wclipping */
  136622. + gctBOOL vsPositionZDependsOnW;
  136623. +#endif
  136624. +
  136625. + gctBOOL clipW;
  136626. +
  136627. + /* Flag whether or not the shader has a KILL instruction. */
  136628. + gctBOOL hasKill;
  136629. +
  136630. + /* Element count. */
  136631. + gctUINT32 elementCount;
  136632. +
  136633. + /* Component count. */
  136634. + gctUINT32 componentCount;
  136635. +
  136636. + /* Number of data transfers for Fragment Shader input. */
  136637. + gctUINT32 fsInputCount;
  136638. +
  136639. + /* Maximum number of temporary registers used in FS. */
  136640. + gctUINT32 fsMaxTemp;
  136641. +
  136642. + /* Maximum number of temporary registers used in VS. */
  136643. + gctUINT32 vsMaxTemp;
  136644. +
  136645. + /* Balance minimum. */
  136646. + gctUINT32 balanceMin;
  136647. +
  136648. + /* Balance maximum. */
  136649. + gctUINT32 balanceMax;
  136650. +
  136651. + /* Auto-shift balancing. */
  136652. + gctBOOL autoShift;
  136653. +
  136654. + /* Flag whether the PS outputs the depth value or not. */
  136655. + gctBOOL psHasFragDepthOut;
  136656. +
  136657. + /* Flag whether the ThreadWalker is in PS. */
  136658. + gctBOOL threadWalkerInPS;
  136659. +
  136660. + /* HW reg number for position of VS */
  136661. + gctUINT32 hwRegNoOfSIVPos;
  136662. +
  136663. +#if gcdALPHA_KILL_IN_SHADER
  136664. + /* States to set when alpha kill is enabled. */
  136665. + gctUINT32 killStateAddress;
  136666. + gctUINT32 alphaKillStateValue;
  136667. + gctUINT32 colorKillStateValue;
  136668. +
  136669. + /* Shader instructiuon. */
  136670. + gctUINT32 killInstructionAddress;
  136671. + gctUINT32 alphaKillInstruction[3];
  136672. + gctUINT32 colorKillInstruction[3];
  136673. +#endif
  136674. +
  136675. +#if TEMP_SHADER_PATCH
  136676. + gctUINT32 pachedShaderIdentifier;
  136677. +#endif
  136678. +};
  136679. +
  136680. +#if TEMP_SHADER_PATCH
  136681. +#define INVALID_SHADER_IDENTIFIER 0xFFFFFFFF
  136682. +#endif
  136683. +
  136684. +/* gcSHADER_TYPE enumeration. */
  136685. +typedef enum _gcSHADER_TYPE
  136686. +{
  136687. + gcSHADER_FLOAT_X1 = 0, /* 0x00 */
  136688. + gcSHADER_FLOAT_X2, /* 0x01 */
  136689. + gcSHADER_FLOAT_X3, /* 0x02 */
  136690. + gcSHADER_FLOAT_X4, /* 0x03 */
  136691. + gcSHADER_FLOAT_2X2, /* 0x04 */
  136692. + gcSHADER_FLOAT_3X3, /* 0x05 */
  136693. + gcSHADER_FLOAT_4X4, /* 0x06 */
  136694. + gcSHADER_BOOLEAN_X1, /* 0x07 */
  136695. + gcSHADER_BOOLEAN_X2, /* 0x08 */
  136696. + gcSHADER_BOOLEAN_X3, /* 0x09 */
  136697. + gcSHADER_BOOLEAN_X4, /* 0x0A */
  136698. + gcSHADER_INTEGER_X1, /* 0x0B */
  136699. + gcSHADER_INTEGER_X2, /* 0x0C */
  136700. + gcSHADER_INTEGER_X3, /* 0x0D */
  136701. + gcSHADER_INTEGER_X4, /* 0x0E */
  136702. + gcSHADER_SAMPLER_1D, /* 0x0F */
  136703. + gcSHADER_SAMPLER_2D, /* 0x10 */
  136704. + gcSHADER_SAMPLER_3D, /* 0x11 */
  136705. + gcSHADER_SAMPLER_CUBIC, /* 0x12 */
  136706. + gcSHADER_FIXED_X1, /* 0x13 */
  136707. + gcSHADER_FIXED_X2, /* 0x14 */
  136708. + gcSHADER_FIXED_X3, /* 0x15 */
  136709. + gcSHADER_FIXED_X4, /* 0x16 */
  136710. + gcSHADER_IMAGE_2D, /* 0x17 */ /* For OCL. */
  136711. + gcSHADER_IMAGE_3D, /* 0x18 */ /* For OCL. */
  136712. + gcSHADER_SAMPLER, /* 0x19 */ /* For OCL. */
  136713. + gcSHADER_FLOAT_2X3, /* 0x1A */
  136714. + gcSHADER_FLOAT_2X4, /* 0x1B */
  136715. + gcSHADER_FLOAT_3X2, /* 0x1C */
  136716. + gcSHADER_FLOAT_3X4, /* 0x1D */
  136717. + gcSHADER_FLOAT_4X2, /* 0x1E */
  136718. + gcSHADER_FLOAT_4X3, /* 0x1F */
  136719. + gcSHADER_ISAMPLER_2D, /* 0x20 */
  136720. + gcSHADER_ISAMPLER_3D, /* 0x21 */
  136721. + gcSHADER_ISAMPLER_CUBIC, /* 0x22 */
  136722. + gcSHADER_USAMPLER_2D, /* 0x23 */
  136723. + gcSHADER_USAMPLER_3D, /* 0x24 */
  136724. + gcSHADER_USAMPLER_CUBIC, /* 0x25 */
  136725. + gcSHADER_SAMPLER_EXTERNAL_OES, /* 0x26 */
  136726. +
  136727. + gcSHADER_UINT_X1, /* 0x27 */
  136728. + gcSHADER_UINT_X2, /* 0x28 */
  136729. + gcSHADER_UINT_X3, /* 0x29 */
  136730. + gcSHADER_UINT_X4, /* 0x2A */
  136731. +
  136732. + gcSHADER_UNKONWN_TYPE, /* do not add type after this */
  136733. + gcSHADER_TYPE_COUNT /* must to change gcvShaderTypeInfo at the
  136734. + * same time if you add any new type! */}
  136735. +gcSHADER_TYPE;
  136736. +
  136737. +typedef enum _gcSHADER_TYPE_KIND
  136738. +{
  136739. + gceTK_UNKOWN,
  136740. + gceTK_FLOAT,
  136741. + gceTK_INT,
  136742. + gceTK_UINT,
  136743. + gceTK_BOOL,
  136744. + gceTK_FIXED,
  136745. + gceTK_SAMPLER,
  136746. + gceTK_IMAGE,
  136747. + gceTK_OTHER
  136748. +} gcSHADER_TYPE_KIND;
  136749. +
  136750. +typedef struct _gcSHADER_TYPEINFO
  136751. +{
  136752. + gcSHADER_TYPE type; /* e.g. gcSHADER_FLOAT_2X4 */
  136753. + gctINT components; /* e.g. 4 components */
  136754. + gctINT rows; /* e.g. 2 rows */
  136755. + gcSHADER_TYPE componentType; /* e.g. gcSHADER_FLOAT_X4 */
  136756. + gcSHADER_TYPE_KIND kind; /* e.g. gceTK_FLOAT */
  136757. + gctCONST_STRING name; /* e.g. "FLOAT_2X4" */
  136758. +} gcSHADER_TYPEINFO;
  136759. +
  136760. +extern gcSHADER_TYPEINFO gcvShaderTypeInfo[];
  136761. +
  136762. +#define gcmType_Comonents(Type) (gcvShaderTypeInfo[Type].components)
  136763. +#define gcmType_Rows(Type) (gcvShaderTypeInfo[Type].rows)
  136764. +#define gcmType_ComonentType(Type) (gcvShaderTypeInfo[Type].componentType)
  136765. +#define gcmType_Kind(Type) (gcvShaderTypeInfo[Type].kind)
  136766. +#define gcmType_Name(Type) (gcvShaderTypeInfo[Type].name)
  136767. +
  136768. +#define gcmType_isMatrix(type) (gcmType_Rows(type) > 1)
  136769. +
  136770. +typedef enum _gcSHADER_VAR_CATEGORY
  136771. +{
  136772. + gcSHADER_VAR_CATEGORY_NORMAL = 0, /* primitive type and its array */
  136773. + gcSHADER_VAR_CATEGORY_STRUCT = 1 /* structure */
  136774. +}
  136775. +gcSHADER_VAR_CATEGORY;
  136776. +
  136777. +typedef enum _gceTYPE_QUALIFIER
  136778. +{
  136779. + gcvTYPE_QUALIFIER_NONE = 0x0, /* unqualified */
  136780. + gcvTYPE_QUALIFIER_VOLATILE = 0x1, /* volatile */
  136781. +}gceTYPE_QUALIFIER;
  136782. +
  136783. +typedef gctUINT16 gctTYPE_QUALIFIER;
  136784. +
  136785. +#if GC_ENABLE_LOADTIME_OPT
  136786. +typedef struct _gcSHADER_TYPE_INFO
  136787. +{
  136788. + gcSHADER_TYPE type; /* eg. gcSHADER_FLOAT_2X3 is the type */
  136789. + gctCONST_STRING name; /* the name of the type: "gcSHADER_FLOAT_2X3" */
  136790. + gcSHADER_TYPE baseType; /* its base type is gcSHADER_FLOAT_2 */
  136791. + gctINT components; /* it has 2 components */
  136792. + gctINT rows; /* and 3 rows */
  136793. + gctINT size; /* the size in byte */
  136794. +} gcSHADER_TYPE_INFO;
  136795. +
  136796. +extern gcSHADER_TYPE_INFO shader_type_info[];
  136797. +
  136798. +enum gceLTCDumpOption {
  136799. + gceLTC_DUMP_UNIFORM = 0x0001,
  136800. + gceLTC_DUMP_EVALUATION = 0x0002,
  136801. + gceLTC_DUMP_EXPESSION = 0x0004,
  136802. + gceLTC_DUMP_COLLECTING = 0x0008,
  136803. +};
  136804. +
  136805. +gctBOOL gcDumpOption(gctINT Opt);
  136806. +
  136807. +#endif /* GC_ENABLE_LOADTIME_OPT */
  136808. +
  136809. +#define IS_MATRIX_TYPE(type) \
  136810. + (((type >= gcSHADER_FLOAT_2X2) && (type <= gcSHADER_FLOAT_4X4)) || \
  136811. + ((type >= gcSHADER_FLOAT_2X3) && (type <= gcSHADER_FLOAT_4X3)))
  136812. +
  136813. +/* gcSHADER_PRECISION enumeration. */
  136814. +typedef enum _gcSHADER_PRECISION
  136815. +{
  136816. + gcSHADER_PRECISION_DEFAULT, /* 0x00 */
  136817. + gcSHADER_PRECISION_HIGH, /* 0x01 */
  136818. + gcSHADER_PRECISION_MEDIUM, /* 0x02 */
  136819. + gcSHADER_PRECISION_LOW, /* 0x03 */
  136820. +}
  136821. +gcSHADER_PRECISION;
  136822. +
  136823. +/* Shader flags. */
  136824. +typedef enum _gceSHADER_FLAGS
  136825. +{
  136826. + gcvSHADER_NO_OPTIMIZATION = 0x00,
  136827. + gcvSHADER_DEAD_CODE = 0x01,
  136828. + gcvSHADER_RESOURCE_USAGE = 0x02,
  136829. + gcvSHADER_OPTIMIZER = 0x04,
  136830. + gcvSHADER_USE_GL_Z = 0x08,
  136831. + /*
  136832. + The GC family of GPU cores model GC860 and under require the Z
  136833. + to be from 0 <= z <= w.
  136834. + However, OpenGL specifies the Z to be from -w <= z <= w. So we
  136835. + have to a conversion here:
  136836. +
  136837. + z = (z + w) / 2.
  136838. +
  136839. + So here we append two instructions to the vertex shader.
  136840. + */
  136841. + gcvSHADER_USE_GL_POSITION = 0x10,
  136842. + gcvSHADER_USE_GL_FACE = 0x20,
  136843. + gcvSHADER_USE_GL_POINT_COORD = 0x40,
  136844. + gcvSHADER_LOADTIME_OPTIMIZER = 0x80,
  136845. +#if gcdALPHA_KILL_IN_SHADER
  136846. + gcvSHADER_USE_ALPHA_KILL = 0x100,
  136847. +#endif
  136848. +
  136849. +#if gcdPRE_ROTATION && (ANDROID_SDK_VERSION >= 14)
  136850. + gcvSHADER_VS_PRE_ROTATION = 0x200,
  136851. +#endif
  136852. +
  136853. +#if TEMP_INLINE_ALL_EXPANSION
  136854. + gcvSHADER_INLINE_ALL_EXPANSION = 0x400,
  136855. +#endif
  136856. +}
  136857. +gceSHADER_FLAGS;
  136858. +
  136859. +gceSTATUS
  136860. +gcSHADER_CheckClipW(
  136861. + IN gctCONST_STRING VertexSource,
  136862. + IN gctCONST_STRING FragmentSource,
  136863. + OUT gctBOOL * clipW);
  136864. +
  136865. +/*******************************************************************************
  136866. +** gcSHADER_GetUniformVectorCount
  136867. +**
  136868. +** Get the number of vectors used by uniforms for this shader.
  136869. +**
  136870. +** INPUT:
  136871. +**
  136872. +** gcSHADER Shader
  136873. +** Pointer to a gcSHADER object.
  136874. +**
  136875. +** OUTPUT:
  136876. +**
  136877. +** gctSIZE_T * Count
  136878. +** Pointer to a variable receiving the number of vectors.
  136879. +*/
  136880. +gceSTATUS
  136881. +gcSHADER_GetUniformVectorCount(
  136882. + IN gcSHADER Shader,
  136883. + OUT gctSIZE_T * Count
  136884. + );
  136885. +
  136886. +/*******************************************************************************
  136887. +** gcOptimizer Data Structures
  136888. +*******************************************************************************/
  136889. +typedef enum _gceSHADER_OPTIMIZATION
  136890. +{
  136891. + /* No optimization. */
  136892. + gcvOPTIMIZATION_NONE,
  136893. +
  136894. + /* Flow graph construction. */
  136895. + gcvOPTIMIZATION_CONSTRUCTION = 1 << 0,
  136896. +
  136897. + /* Dead code elimination. */
  136898. + gcvOPTIMIZATION_DEAD_CODE = 1 << 1,
  136899. +
  136900. + /* Redundant move instruction elimination. */
  136901. + gcvOPTIMIZATION_REDUNDANT_MOVE = 1 << 2,
  136902. +
  136903. + /* Inline expansion. */
  136904. + gcvOPTIMIZATION_INLINE_EXPANSION = 1 << 3,
  136905. +
  136906. + /* Constant propagation. */
  136907. + gcvOPTIMIZATION_CONSTANT_PROPAGATION = 1 << 4,
  136908. +
  136909. + /* Redundant bounds/checking elimination. */
  136910. + gcvOPTIMIZATION_REDUNDANT_CHECKING = 1 << 5,
  136911. +
  136912. + /* Loop invariant movement. */
  136913. + gcvOPTIMIZATION_LOOP_INVARIANT = 1 << 6,
  136914. +
  136915. + /* Induction variable removal. */
  136916. + gcvOPTIMIZATION_INDUCTION_VARIABLE = 1 << 7,
  136917. +
  136918. + /* Common subexpression elimination. */
  136919. + gcvOPTIMIZATION_COMMON_SUBEXPRESSION = 1 << 8,
  136920. +
  136921. + /* Control flow/banch optimization. */
  136922. + gcvOPTIMIZATION_CONTROL_FLOW = 1 << 9,
  136923. +
  136924. + /* Vector component operation merge. */
  136925. + gcvOPTIMIZATION_VECTOR_INSTRUCTION_MERGE = 1 << 10,
  136926. +
  136927. + /* Algebra simplificaton. */
  136928. + gcvOPTIMIZATION_ALGEBRAIC_SIMPLIFICATION = 1 << 11,
  136929. +
  136930. + /* Pattern matching and replacing. */
  136931. + gcvOPTIMIZATION_PATTERN_MATCHING = 1 << 12,
  136932. +
  136933. + /* Interprocedural constant propagation. */
  136934. + gcvOPTIMIZATION_IP_CONSTANT_PROPAGATION = 1 << 13,
  136935. +
  136936. + /* Interprecedural register optimization. */
  136937. + gcvOPTIMIZATION_IP_REGISTRATION = 1 << 14,
  136938. +
  136939. + /* Optimization option number. */
  136940. + gcvOPTIMIZATION_OPTION_NUMBER = 1 << 15,
  136941. +
  136942. + /* Loadtime constant. */
  136943. + gcvOPTIMIZATION_LOADTIME_CONSTANT = 1 << 16,
  136944. +
  136945. + /* MAD instruction optimization. */
  136946. + gcvOPTIMIZATION_MAD_INSTRUCTION = 1 << 17,
  136947. +
  136948. + /* Special optimization for LOAD SW workaround. */
  136949. + gcvOPTIMIZATION_LOAD_SW_WORKAROUND = 1 << 18,
  136950. +
  136951. + /* move code into conditional block if possile */
  136952. + gcvOPTIMIZATION_CONDITIONALIZE = 1 << 19,
  136953. +
  136954. + /* expriemental: power optimization mode
  136955. + 1. add extra dummy texld to tune performance
  136956. + 2. insert NOP after high power instrucitons
  136957. + 3. split high power vec3/vec4 instruciton to vec2/vec1 operation
  136958. + 4. ...
  136959. + */
  136960. + gcvOPTIMIZATION_POWER_OPTIMIZATION = 1 << 20,
  136961. +
  136962. + /* optimize varying packing */
  136963. + gcvOPTIMIZATION_VARYINGPACKING = 1 << 22,
  136964. +
  136965. +#if TEMP_INLINE_ALL_EXPANSION
  136966. + gcvOPTIMIZATION_INLINE_ALL_EXPANSION = 1 << 23,
  136967. +#endif
  136968. +
  136969. + /* Full optimization. */
  136970. + /* Note that gcvOPTIMIZATION_LOAD_SW_WORKAROUND is off. */
  136971. + gcvOPTIMIZATION_FULL = 0x7FFFFFFF &
  136972. + ~gcvOPTIMIZATION_LOAD_SW_WORKAROUND &
  136973. + ~gcvOPTIMIZATION_INLINE_ALL_EXPANSION &
  136974. + ~gcvOPTIMIZATION_POWER_OPTIMIZATION,
  136975. +
  136976. + /* Optimization Unit Test flag. */
  136977. + gcvOPTIMIZATION_UNIT_TEST = 1 << 31
  136978. +}
  136979. +gceSHADER_OPTIMIZATION;
  136980. +
  136981. +typedef enum _gceOPTIMIZATION_VaryingPaking
  136982. +{
  136983. + gcvOPTIMIZATION_VARYINGPACKING_NONE = 0,
  136984. + gcvOPTIMIZATION_VARYINGPACKING_NOSPLIT,
  136985. + gcvOPTIMIZATION_VARYINGPACKING_SPLIT
  136986. +} gceOPTIMIZATION_VaryingPaking;
  136987. +
  136988. +typedef struct _gcOPTIMIZER_OPTION
  136989. +{
  136990. + gceSHADER_OPTIMIZATION optFlags;
  136991. +
  136992. + /* debug & dump options:
  136993. +
  136994. + VC_OPTION=-DUMP:SRC:OPT|:OPTV|:CG|:CGV:|ALL|ALLV
  136995. +
  136996. + SRC: dump shader source code
  136997. + OPT: dump incoming and final IR
  136998. + OPTV: dump result IR in each optimization phase
  136999. + CG: dump generated machine code
  137000. + CGV: dump BE tree and optimization detail
  137001. +
  137002. + ALL = SRC|OPT|CG
  137003. + ALLV = SRC|OPT|OPTV|CG|CGV
  137004. + */
  137005. + gctBOOL dumpShaderSource; /* dump shader source code */
  137006. + gctBOOL dumpOptimizer; /* dump incoming and final IR */
  137007. + gctBOOL dumpOptimizerVerbose; /* dump result IR in each optimization phase */
  137008. + gctBOOL dumpBEGenertedCode; /* dump generated machine code */
  137009. + gctBOOL dumpBEVerbose; /* dump BE tree and optimization detail */
  137010. + gctBOOL dumpBEFinalIR; /* dump BE final IR */
  137011. +
  137012. + /* Code generation */
  137013. +
  137014. + /* Varying Packing:
  137015. +
  137016. + VC_OPTION=-PACKVARYING:[0-2]|:T[-]m[,n]|:LshaderIdx,min,max
  137017. +
  137018. + 0: turn off varying packing
  137019. + 1: pack varyings, donot split any varying
  137020. + 2: pack varyings, may split to make fully packed output
  137021. +
  137022. + Tm: only packing shader pair which vertex shader id is m
  137023. + Tm,n: only packing shader pair which vertex shader id
  137024. + is in range of [m, n]
  137025. + T-m: do not packing shader pair which vertex shader id is m
  137026. + T-m,n: do not packing shader pair which vertex shader id
  137027. + is in range of [m, n]
  137028. +
  137029. + LshaderIdx,min,max : set load balance (min, max) for shaderIdx
  137030. + if shaderIdx is -1, all shaders are impacted
  137031. + newMin = origMin * (min/100.);
  137032. + newMax = origMax * (max/100.);
  137033. + */
  137034. + gceOPTIMIZATION_VaryingPaking packVarying;
  137035. + gctINT _triageStart;
  137036. + gctINT _triageEnd;
  137037. + gctINT _loadBalanceShaderIdx;
  137038. + gctINT _loadBalanceMin;
  137039. + gctINT _loadBalanceMax;
  137040. +
  137041. + /* Do not generate immdeiate
  137042. +
  137043. + VC_OPTION=-NOIMM
  137044. +
  137045. + Force generate immediate even the machine model don't support it,
  137046. + for testing purpose only
  137047. +
  137048. + VC_OPTION=-FORCEIMM
  137049. + */
  137050. + gctBOOL noImmediate;
  137051. + gctBOOL forceImmediate;
  137052. +
  137053. + /* Power reduction mode options */
  137054. + gctBOOL needPowerOptimization;
  137055. +
  137056. + /* Patch TEXLD instruction by adding dummy texld
  137057. + (can be used to tune GPU power usage):
  137058. + for every TEXLD we seen, add n dummy TEXLD
  137059. +
  137060. + it can be enabled by environment variable:
  137061. +
  137062. + VC_OPTION=-PATCH_TEXLD:M:N
  137063. +
  137064. + (for each M texld, add N dummy texld)
  137065. + */
  137066. + gctINT patchEveryTEXLDs;
  137067. + gctINT patchDummyTEXLDs;
  137068. +
  137069. + /* Insert NOP after high power consumption instructions
  137070. +
  137071. + VC_OPTION="-INSERTNOP:MUL:MULLO:DP3:DP4:SEENTEXLD"
  137072. + */
  137073. + gctBOOL insertNOP;
  137074. + gctBOOL insertNOPAfterMUL;
  137075. + gctBOOL insertNOPAfterMULLO;
  137076. + gctBOOL insertNOPAfterDP3;
  137077. + gctBOOL insertNOPAfterDP4;
  137078. + gctBOOL insertNOPOnlyWhenTexldSeen;
  137079. +
  137080. + /* split MAD to MUL and ADD:
  137081. +
  137082. + VC_OPTION=-SPLITMAD
  137083. + */
  137084. + gctBOOL splitMAD;
  137085. +
  137086. + /* Convert vect3/vec4 operations to multiple vec2/vec1 operations
  137087. +
  137088. + VC_OPTION=-SPLITVEC:MUL:MULLO:DP3:DP4
  137089. + */
  137090. + gctBOOL splitVec;
  137091. + gctBOOL splitVec4MUL;
  137092. + gctBOOL splitVec4MULLO;
  137093. + gctBOOL splitVec4DP3;
  137094. + gctBOOL splitVec4DP4;
  137095. +
  137096. + /* turn/off features:
  137097. +
  137098. + VC_OPTION=-F:n,[0|1]
  137099. + Note: n must be decimal number
  137100. + */
  137101. + gctUINT featureBits;
  137102. +
  137103. + /* inline level (default 2 at O1):
  137104. +
  137105. + VC_OPTION=-INLINELEVEL:[0-3]
  137106. + 0: no inline
  137107. + 1: only inline the function only called once or small function
  137108. + 2: inline functions be called less than 5 times or medium size function
  137109. + 3: inline everything possible
  137110. + */
  137111. + gctUINT inlineLevel;
  137112. +} gcOPTIMIZER_OPTION;
  137113. +
  137114. +extern gcOPTIMIZER_OPTION theOptimizerOption;
  137115. +#define gcmGetOptimizerOption() gcGetOptimizerOption()
  137116. +
  137117. +#define gcmOPT_DUMP_SHADER_SRC() \
  137118. + (gcmGetOptimizerOption()->dumpShaderSource != 0)
  137119. +#define gcmOPT_DUMP_OPTIMIZER() \
  137120. + (gcmGetOptimizerOption()->dumpOptimizer != 0 || \
  137121. + gcmOPT_DUMP_OPTIMIZER_VERBOSE() )
  137122. +#define gcmOPT_DUMP_OPTIMIZER_VERBOSE() \
  137123. + (gcmGetOptimizerOption()->dumpOptimizerVerbose != 0)
  137124. +#define gcmOPT_DUMP_CODEGEN() \
  137125. + (gcmGetOptimizerOption()->dumpBEGenertedCode != 0 || \
  137126. + gcmOPT_DUMP_CODEGEN_VERBOSE() )
  137127. +#define gcmOPT_DUMP_CODEGEN_VERBOSE() \
  137128. + (gcmGetOptimizerOption()->dumpBEVerbose != 0)
  137129. +#define gcmOPT_DUMP_FINAL_IR() \
  137130. + (gcmGetOptimizerOption()->dumpBEFinalIR != 0)
  137131. +
  137132. +#define gcmOPT_SET_DUMP_SHADER_SRC(v) \
  137133. + gcmGetOptimizerOption()->dumpShaderSource = (v)
  137134. +
  137135. +#define gcmOPT_PATCH_TEXLD() (gcmGetOptimizerOption()->patchDummyTEXLDs != 0)
  137136. +#define gcmOPT_INSERT_NOP() (gcmGetOptimizerOption()->insertNOP == gcvTRUE)
  137137. +#define gcmOPT_SPLITMAD() (gcmGetOptimizerOption()->splitMAD == gcvTRUE)
  137138. +#define gcmOPT_SPLITVEC() (gcmGetOptimizerOption()->splitVec == gcvTRUE)
  137139. +
  137140. +#define gcmOPT_NOIMMEDIATE() (gcmGetOptimizerOption()->noImmediate == gcvTRUE)
  137141. +#define gcmOPT_FORCEIMMEDIATE() (gcmGetOptimizerOption()->forceImmediate == gcvTRUE)
  137142. +
  137143. +#define gcmOPT_PACKVARYING() (gcmGetOptimizerOption()->packVarying)
  137144. +#define gcmOPT_PACKVARYING_triageStart() (gcmGetOptimizerOption()->_triageStart)
  137145. +#define gcmOPT_PACKVARYING_triageEnd() (gcmGetOptimizerOption()->_triageEnd)
  137146. +
  137147. +#define gcmOPT_INLINELEVEL() (gcmGetOptimizerOption()->inlineLevel)
  137148. +
  137149. +/* Setters */
  137150. +#define gcmOPT_SetPatchTexld(m,n) (gcmGetOptimizerOption()->patchEveryTEXLDs = (m),\
  137151. + gcmGetOptimizerOption()->patchDummyTEXLDs = (n))
  137152. +#define gcmOPT_SetSplitVecMUL() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  137153. + gcmGetOptimizerOption()->splitVec4MUL = gcvTRUE)
  137154. +#define gcmOPT_SetSplitVecMULLO() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  137155. + gcmGetOptimizerOption()->splitVec4MULLO = gcvTRUE)
  137156. +#define gcmOPT_SetSplitVecDP3() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  137157. + gcmGetOptimizerOption()->splitVec4DP3 = gcvTRUE)
  137158. +#define gcmOPT_SetSplitVecDP4() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  137159. + gcmGetOptimizerOption()->splitVec4DP4 = gcvTRUE)
  137160. +
  137161. +#define gcmOPT_SetPackVarying(v) (gcmGetOptimizerOption()->packVarying = v)
  137162. +
  137163. +#define FB_LIVERANGE_FIX1 0x0001
  137164. +
  137165. +
  137166. +#define PredefinedDummySamplerId 8
  137167. +
  137168. +/* Function argument qualifier */
  137169. +typedef enum _gceINPUT_OUTPUT
  137170. +{
  137171. + gcvFUNCTION_INPUT,
  137172. + gcvFUNCTION_OUTPUT,
  137173. + gcvFUNCTION_INOUT
  137174. +}
  137175. +gceINPUT_OUTPUT;
  137176. +
  137177. +/* Kernel function property flags. */
  137178. +typedef enum _gcePROPERTY_FLAGS
  137179. +{
  137180. + gcvPROPERTY_REQD_WORK_GRP_SIZE = 0x01
  137181. +}
  137182. +gceKERNEL_FUNCTION_PROPERTY_FLAGS;
  137183. +
  137184. +/* Uniform flags. */
  137185. +typedef enum _gceUNIFORM_FLAGS
  137186. +{
  137187. + gcvUNIFORM_KERNEL_ARG = 0x01,
  137188. + gcvUNIFORM_KERNEL_ARG_LOCAL = 0x02,
  137189. + gcvUNIFORM_KERNEL_ARG_SAMPLER = 0x04,
  137190. + gcvUNIFORM_LOCAL_ADDRESS_SPACE = 0x08,
  137191. + gcvUNIFORM_PRIVATE_ADDRESS_SPACE = 0x10,
  137192. + gcvUNIFORM_CONSTANT_ADDRESS_SPACE = 0x20,
  137193. + gcvUNIFORM_GLOBAL_SIZE = 0x40,
  137194. + gcvUNIFORM_LOCAL_SIZE = 0x80,
  137195. + gcvUNIFORM_NUM_GROUPS = 0x100,
  137196. + gcvUNIFORM_GLOBAL_OFFSET = 0x200,
  137197. + gcvUNIFORM_WORK_DIM = 0x400,
  137198. + gcvUNIFORM_KERNEL_ARG_CONSTANT = 0x800,
  137199. + gcvUNIFORM_KERNEL_ARG_LOCAL_MEM_SIZE = 0x1000,
  137200. + gcvUNIFORM_KERNEL_ARG_PRIVATE = 0x2000,
  137201. + gcvUNIFORM_LOADTIME_CONSTANT = 0x4000,
  137202. + gcvUNIFORM_IS_ARRAY = 0x8000,
  137203. +}
  137204. +gceUNIFORM_FLAGS;
  137205. +
  137206. +#define gcdUNIFORM_KERNEL_ARG_MASK (gcvUNIFORM_KERNEL_ARG | \
  137207. + gcvUNIFORM_KERNEL_ARG_LOCAL | \
  137208. + gcvUNIFORM_KERNEL_ARG_SAMPLER | \
  137209. + gcvUNIFORM_KERNEL_ARG_PRIVATE | \
  137210. + gcvUNIFORM_KERNEL_ARG_CONSTANT)
  137211. +
  137212. +typedef enum _gceVARIABLE_UPDATE_FLAGS
  137213. +{
  137214. + gcvVARIABLE_UPDATE_NOUPDATE = 0,
  137215. + gcvVARIABLE_UPDATE_TEMPREG,
  137216. + gcvVARIABLE_UPDATE_TYPE_QUALIFIER,
  137217. +}gceVARIABLE_UPDATE_FLAGS;
  137218. +
  137219. +typedef struct _gcMACHINE_INST
  137220. +{
  137221. + gctUINT state0;
  137222. + gctUINT state1;
  137223. + gctUINT state2;
  137224. + gctUINT state3;
  137225. +}gcMACHINE_INST, *gcMACHINE_INST_PTR;
  137226. +
  137227. +typedef struct _gcMACHINECODE
  137228. +{
  137229. + gcMACHINE_INST_PTR pCode; /* machine code */
  137230. + gctUINT instCount; /* 128-bit count */
  137231. + gctUINT maxConstRegNo;
  137232. + gctUINT maxTempRegNo;
  137233. + gctUINT endPCOfMainRoutine;
  137234. +}gcMACHINECODE, *gcMACHINECODE_PTR;
  137235. +
  137236. +typedef enum NP2_ADDRESS_MODE
  137237. +{
  137238. + NP2_ADDRESS_MODE_CLAMP = 0,
  137239. + NP2_ADDRESS_MODE_REPEAT = 1,
  137240. + NP2_ADDRESS_MODE_MIRROR = 2
  137241. +}NP2_ADDRESS_MODE;
  137242. +
  137243. +typedef struct _gcNPOT_PATCH_PARAM
  137244. +{
  137245. + gctINT samplerSlot;
  137246. + NP2_ADDRESS_MODE addressMode[3];
  137247. + gctINT texDimension; /* 2 or 3 */
  137248. +}gcNPOT_PATCH_PARAM, *gcNPOT_PATCH_PARAM_PTR;
  137249. +
  137250. +typedef struct _gcZBIAS_PATCH_PARAM
  137251. +{
  137252. + /* Driver uses this to program uniform that designating zbias */
  137253. + gctINT uniformAddr;
  137254. + gctINT channel;
  137255. +}gcZBIAS_PATCH_PARAM, *gcZBIAS_PATCH_PARAM_PTR;
  137256. +
  137257. +void
  137258. +gcGetOptionFromEnv(
  137259. + IN OUT gcOPTIMIZER_OPTION * Option
  137260. + );
  137261. +
  137262. +void
  137263. +gcSetOptimizerOption(
  137264. + IN gceSHADER_FLAGS Flags
  137265. + );
  137266. +
  137267. +gcOPTIMIZER_OPTION *
  137268. +gcGetOptimizerOption();
  137269. +
  137270. +/*******************************************************************************
  137271. +** gcSHADER_SetCompilerVersion
  137272. +**
  137273. +** Set the compiler version of a gcSHADER object.
  137274. +**
  137275. +** INPUT:
  137276. +**
  137277. +** gcSHADER Shader
  137278. +** Pointer to gcSHADER object
  137279. +**
  137280. +** gctINT *Version
  137281. +** Pointer to a two word version
  137282. +*/
  137283. +gceSTATUS
  137284. +gcSHADER_SetCompilerVersion(
  137285. + IN gcSHADER Shader,
  137286. + IN gctUINT32 *Version
  137287. + );
  137288. +
  137289. +/*******************************************************************************
  137290. +** gcSHADER_GetCompilerVersion
  137291. +**
  137292. +** Get the compiler version of a gcSHADER object.
  137293. +**
  137294. +** INPUT:
  137295. +**
  137296. +** gcSHADER Shader
  137297. +** Pointer to a gcSHADER object.
  137298. +**
  137299. +** OUTPUT:
  137300. +**
  137301. +** gctUINT32_PTR *CompilerVersion.
  137302. +** Pointer to holder of returned compilerVersion pointer
  137303. +*/
  137304. +gceSTATUS
  137305. +gcSHADER_GetCompilerVersion(
  137306. + IN gcSHADER Shader,
  137307. + OUT gctUINT32_PTR *CompilerVersion
  137308. + );
  137309. +
  137310. +/*******************************************************************************
  137311. +** gcSHADER_GetType
  137312. +**
  137313. +** Get the gcSHADER object's type.
  137314. +**
  137315. +** INPUT:
  137316. +**
  137317. +** gcSHADER Shader
  137318. +** Pointer to a gcSHADER object.
  137319. +**
  137320. +** OUTPUT:
  137321. +**
  137322. +** gctINT *Type.
  137323. +** Pointer to return shader type.
  137324. +*/
  137325. +gceSTATUS
  137326. +gcSHADER_GetType(
  137327. + IN gcSHADER Shader,
  137328. + OUT gctINT *Type
  137329. + );
  137330. +
  137331. +gctUINT
  137332. +gcSHADER_NextId();
  137333. +/*******************************************************************************
  137334. +** gcSHADER_Construct
  137335. +********************************************************************************
  137336. +**
  137337. +** Construct a new gcSHADER object.
  137338. +**
  137339. +** INPUT:
  137340. +**
  137341. +** gcoOS Hal
  137342. +** Pointer to an gcoHAL object.
  137343. +**
  137344. +** gctINT ShaderType
  137345. +** Type of gcSHADER object to cerate. 'ShaderType' can be one of the
  137346. +** following:
  137347. +**
  137348. +** gcSHADER_TYPE_VERTEX Vertex shader.
  137349. +** gcSHADER_TYPE_FRAGMENT Fragment shader.
  137350. +**
  137351. +** OUTPUT:
  137352. +**
  137353. +** gcSHADER * Shader
  137354. +** Pointer to a variable receiving the gcSHADER object pointer.
  137355. +*/
  137356. +gceSTATUS
  137357. +gcSHADER_Construct(
  137358. + IN gcoHAL Hal,
  137359. + IN gctINT ShaderType,
  137360. + OUT gcSHADER * Shader
  137361. + );
  137362. +
  137363. +/*******************************************************************************
  137364. +** gcSHADER_Destroy
  137365. +********************************************************************************
  137366. +**
  137367. +** Destroy a gcSHADER object.
  137368. +**
  137369. +** INPUT:
  137370. +**
  137371. +** gcSHADER Shader
  137372. +** Pointer to a gcSHADER object.
  137373. +**
  137374. +** OUTPUT:
  137375. +**
  137376. +** Nothing.
  137377. +*/
  137378. +gceSTATUS
  137379. +gcSHADER_Destroy(
  137380. + IN gcSHADER Shader
  137381. + );
  137382. +
  137383. +/*******************************************************************************
  137384. +** gcSHADER_Copy
  137385. +********************************************************************************
  137386. +**
  137387. +** Copy a gcSHADER object.
  137388. +**
  137389. +** INPUT:
  137390. +**
  137391. +** gcSHADER Shader
  137392. +** Pointer to a gcSHADER object.
  137393. +**
  137394. +** gcSHADER Source
  137395. +** Pointer to a gcSHADER object that will be copied.
  137396. +**
  137397. +** OUTPUT:
  137398. +**
  137399. +** Nothing.
  137400. +*/
  137401. +gceSTATUS
  137402. +gcSHADER_Copy(
  137403. + IN gcSHADER Shader,
  137404. + IN gcSHADER Source
  137405. + );
  137406. +
  137407. +/*******************************************************************************
  137408. +** gcSHADER_LoadHeader
  137409. +**
  137410. +** Load a gcSHADER object from a binary buffer. The binary buffer is layed out
  137411. +** as follows:
  137412. +** // Six word header
  137413. +** // Signature, must be 'S','H','D','R'.
  137414. +** gctINT8 signature[4];
  137415. +** gctUINT32 binFileVersion;
  137416. +** gctUINT32 compilerVersion[2];
  137417. +** gctUINT32 gcSLVersion;
  137418. +** gctUINT32 binarySize;
  137419. +**
  137420. +** INPUT:
  137421. +**
  137422. +** gcSHADER Shader
  137423. +** Pointer to a gcSHADER object.
  137424. +** Shader type will be returned if type in shader object is not gcSHADER_TYPE_PRECOMPILED
  137425. +**
  137426. +** gctPOINTER Buffer
  137427. +** Pointer to a binary buffer containing the shader data to load.
  137428. +**
  137429. +** gctSIZE_T BufferSize
  137430. +** Number of bytes inside the binary buffer pointed to by 'Buffer'.
  137431. +**
  137432. +** OUTPUT:
  137433. +** nothing
  137434. +**
  137435. +*/
  137436. +gceSTATUS
  137437. +gcSHADER_LoadHeader(
  137438. + IN gcSHADER Shader,
  137439. + IN gctPOINTER Buffer,
  137440. + IN gctSIZE_T BufferSize,
  137441. + OUT gctUINT32 * ShaderVersion
  137442. + );
  137443. +
  137444. +/*******************************************************************************
  137445. +** gcSHADER_LoadKernel
  137446. +**
  137447. +** Load a kernel function given by name into gcSHADER object
  137448. +**
  137449. +** INPUT:
  137450. +**
  137451. +** gcSHADER Shader
  137452. +** Pointer to a gcSHADER object.
  137453. +**
  137454. +** gctSTRING KernelName
  137455. +** Pointer to a kernel function name
  137456. +**
  137457. +** OUTPUT:
  137458. +** nothing
  137459. +**
  137460. +*/
  137461. +gceSTATUS
  137462. +gcSHADER_LoadKernel(
  137463. + IN gcSHADER Shader,
  137464. + IN gctSTRING KernelName
  137465. + );
  137466. +
  137467. +/*******************************************************************************
  137468. +** gcSHADER_Load
  137469. +********************************************************************************
  137470. +**
  137471. +** Load a gcSHADER object from a binary buffer.
  137472. +**
  137473. +** INPUT:
  137474. +**
  137475. +** gcSHADER Shader
  137476. +** Pointer to a gcSHADER object.
  137477. +**
  137478. +** gctPOINTER Buffer
  137479. +** Pointer to a binary buffer containg the shader data to load.
  137480. +**
  137481. +** gctSIZE_T BufferSize
  137482. +** Number of bytes inside the binary buffer pointed to by 'Buffer'.
  137483. +**
  137484. +** OUTPUT:
  137485. +**
  137486. +** Nothing.
  137487. +*/
  137488. +gceSTATUS
  137489. +gcSHADER_Load(
  137490. + IN gcSHADER Shader,
  137491. + IN gctPOINTER Buffer,
  137492. + IN gctSIZE_T BufferSize
  137493. + );
  137494. +
  137495. +/*******************************************************************************
  137496. +** gcSHADER_Save
  137497. +********************************************************************************
  137498. +**
  137499. +** Save a gcSHADER object to a binary buffer.
  137500. +**
  137501. +** INPUT:
  137502. +**
  137503. +** gcSHADER Shader
  137504. +** Pointer to a gcSHADER object.
  137505. +**
  137506. +** gctPOINTER Buffer
  137507. +** Pointer to a binary buffer to be used as storage for the gcSHADER
  137508. +** object. If 'Buffer' is gcvNULL, the gcSHADER object will not be saved,
  137509. +** but the number of bytes required to hold the binary output for the
  137510. +** gcSHADER object will be returned.
  137511. +**
  137512. +** gctSIZE_T * BufferSize
  137513. +** Pointer to a variable holding the number of bytes allocated in
  137514. +** 'Buffer'. Only valid if 'Buffer' is not gcvNULL.
  137515. +**
  137516. +** OUTPUT:
  137517. +**
  137518. +** gctSIZE_T * BufferSize
  137519. +** Pointer to a variable receiving the number of bytes required to hold
  137520. +** the binary form of the gcSHADER object.
  137521. +*/
  137522. +gceSTATUS
  137523. +gcSHADER_Save(
  137524. + IN gcSHADER Shader,
  137525. + IN gctPOINTER Buffer,
  137526. + IN OUT gctSIZE_T * BufferSize
  137527. + );
  137528. +
  137529. +/*******************************************************************************
  137530. +** gcSHADER_LoadEx
  137531. +********************************************************************************
  137532. +**
  137533. +** Load a gcSHADER object from a binary buffer.
  137534. +**
  137535. +** INPUT:
  137536. +**
  137537. +** gcSHADER Shader
  137538. +** Pointer to a gcSHADER object.
  137539. +**
  137540. +** gctPOINTER Buffer
  137541. +** Pointer to a binary buffer containg the shader data to load.
  137542. +**
  137543. +** gctSIZE_T BufferSize
  137544. +** Number of bytes inside the binary buffer pointed to by 'Buffer'.
  137545. +**
  137546. +** OUTPUT:
  137547. +**
  137548. +** Nothing.
  137549. +*/
  137550. +gceSTATUS
  137551. +gcSHADER_LoadEx(
  137552. + IN gcSHADER Shader,
  137553. + IN gctPOINTER Buffer,
  137554. + IN gctSIZE_T BufferSize
  137555. + );
  137556. +
  137557. +/*******************************************************************************
  137558. +** gcSHADER_SaveEx
  137559. +********************************************************************************
  137560. +**
  137561. +** Save a gcSHADER object to a binary buffer.
  137562. +**
  137563. +** INPUT:
  137564. +**
  137565. +** gcSHADER Shader
  137566. +** Pointer to a gcSHADER object.
  137567. +**
  137568. +** gctPOINTER Buffer
  137569. +** Pointer to a binary buffer to be used as storage for the gcSHADER
  137570. +** object. If 'Buffer' is gcvNULL, the gcSHADER object will not be saved,
  137571. +** but the number of bytes required to hold the binary output for the
  137572. +** gcSHADER object will be returned.
  137573. +**
  137574. +** gctSIZE_T * BufferSize
  137575. +** Pointer to a variable holding the number of bytes allocated in
  137576. +** 'Buffer'. Only valid if 'Buffer' is not gcvNULL.
  137577. +**
  137578. +** OUTPUT:
  137579. +**
  137580. +** gctSIZE_T * BufferSize
  137581. +** Pointer to a variable receiving the number of bytes required to hold
  137582. +** the binary form of the gcSHADER object.
  137583. +*/
  137584. +gceSTATUS
  137585. +gcSHADER_SaveEx(
  137586. + IN gcSHADER Shader,
  137587. + IN gctPOINTER Buffer,
  137588. + IN OUT gctSIZE_T * BufferSize
  137589. + );
  137590. +
  137591. +/*******************************************************************************
  137592. +** gcSHADER_ReallocateAttributes
  137593. +**
  137594. +** Reallocate an array of pointers to gcATTRIBUTE objects.
  137595. +**
  137596. +** INPUT:
  137597. +**
  137598. +** gcSHADER Shader
  137599. +** Pointer to a gcSHADER object.
  137600. +**
  137601. +** gctSIZE_T Count
  137602. +** Array count to reallocate. 'Count' must be at least 1.
  137603. +*/
  137604. +gceSTATUS
  137605. +gcSHADER_ReallocateAttributes(
  137606. + IN gcSHADER Shader,
  137607. + IN gctSIZE_T Count
  137608. + );
  137609. +
  137610. +/*******************************************************************************
  137611. +** gcSHADER_AddAttribute
  137612. +********************************************************************************
  137613. +**
  137614. +** Add an attribute to a gcSHADER object.
  137615. +**
  137616. +** INPUT:
  137617. +**
  137618. +** gcSHADER Shader
  137619. +** Pointer to a gcSHADER object.
  137620. +**
  137621. +** gctCONST_STRING Name
  137622. +** Name of the attribute to add.
  137623. +**
  137624. +** gcSHADER_TYPE Type
  137625. +** Type of the attribute to add.
  137626. +**
  137627. +** gctSIZE_T Length
  137628. +** Array length of the attribute to add. 'Length' must be at least 1.
  137629. +**
  137630. +** gctBOOL IsTexture
  137631. +** gcvTRUE if the attribute is used as a texture coordinate, gcvFALSE if not.
  137632. +**
  137633. +** OUTPUT:
  137634. +**
  137635. +** gcATTRIBUTE * Attribute
  137636. +** Pointer to a variable receiving the gcATTRIBUTE object pointer.
  137637. +*/
  137638. +gceSTATUS
  137639. +gcSHADER_AddAttribute(
  137640. + IN gcSHADER Shader,
  137641. + IN gctCONST_STRING Name,
  137642. + IN gcSHADER_TYPE Type,
  137643. + IN gctSIZE_T Length,
  137644. + IN gctBOOL IsTexture,
  137645. + OUT gcATTRIBUTE * Attribute
  137646. + );
  137647. +
  137648. +/*******************************************************************************
  137649. +** gcSHADER_GetAttributeCount
  137650. +********************************************************************************
  137651. +**
  137652. +** Get the number of attributes for this shader.
  137653. +**
  137654. +** INPUT:
  137655. +**
  137656. +** gcSHADER Shader
  137657. +** Pointer to a gcSHADER object.
  137658. +**
  137659. +** OUTPUT:
  137660. +**
  137661. +** gctSIZE_T * Count
  137662. +** Pointer to a variable receiving the number of attributes.
  137663. +*/
  137664. +gceSTATUS
  137665. +gcSHADER_GetAttributeCount(
  137666. + IN gcSHADER Shader,
  137667. + OUT gctSIZE_T * Count
  137668. + );
  137669. +
  137670. +/*******************************************************************************
  137671. +** gcSHADER_GetAttribute
  137672. +********************************************************************************
  137673. +**
  137674. +** Get the gcATTRIBUTE object poniter for an indexed attribute for this shader.
  137675. +**
  137676. +** INPUT:
  137677. +**
  137678. +** gcSHADER Shader
  137679. +** Pointer to a gcSHADER object.
  137680. +**
  137681. +** gctUINT Index
  137682. +** Index of the attribute to retrieve.
  137683. +**
  137684. +** OUTPUT:
  137685. +**
  137686. +** gcATTRIBUTE * Attribute
  137687. +** Pointer to a variable receiving the gcATTRIBUTE object pointer.
  137688. +*/
  137689. +gceSTATUS
  137690. +gcSHADER_GetAttribute(
  137691. + IN gcSHADER Shader,
  137692. + IN gctUINT Index,
  137693. + OUT gcATTRIBUTE * Attribute
  137694. + );
  137695. +
  137696. +/*******************************************************************************
  137697. +** gcSHADER_ReallocateUniforms
  137698. +**
  137699. +** Reallocate an array of pointers to gcUNIFORM objects.
  137700. +**
  137701. +** INPUT:
  137702. +**
  137703. +** gcSHADER Shader
  137704. +** Pointer to a gcSHADER object.
  137705. +**
  137706. +** gctSIZE_T Count
  137707. +** Array count to reallocate. 'Count' must be at least 1.
  137708. +*/
  137709. +gceSTATUS
  137710. +gcSHADER_ReallocateUniforms(
  137711. + IN gcSHADER Shader,
  137712. + IN gctSIZE_T Count
  137713. + );
  137714. +
  137715. +/*******************************************************************************
  137716. +** gcSHADER_AddUniform
  137717. +********************************************************************************
  137718. +**
  137719. +** Add an uniform to a gcSHADER object.
  137720. +**
  137721. +** INPUT:
  137722. +**
  137723. +** gcSHADER Shader
  137724. +** Pointer to a gcSHADER object.
  137725. +**
  137726. +** gctCONST_STRING Name
  137727. +** Name of the uniform to add.
  137728. +**
  137729. +** gcSHADER_TYPE Type
  137730. +** Type of the uniform to add.
  137731. +**
  137732. +** gctSIZE_T Length
  137733. +** Array length of the uniform to add. 'Length' must be at least 1.
  137734. +**
  137735. +** OUTPUT:
  137736. +**
  137737. +** gcUNIFORM * Uniform
  137738. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  137739. +*/
  137740. +gceSTATUS
  137741. +gcSHADER_AddUniform(
  137742. + IN gcSHADER Shader,
  137743. + IN gctCONST_STRING Name,
  137744. + IN gcSHADER_TYPE Type,
  137745. + IN gctSIZE_T Length,
  137746. + OUT gcUNIFORM * Uniform
  137747. + );
  137748. +
  137749. +/*******************************************************************************
  137750. +** gcSHADER_AddPreRotationUniform
  137751. +********************************************************************************
  137752. +**
  137753. +** Add an uniform to a gcSHADER object.
  137754. +**
  137755. +** INPUT:
  137756. +**
  137757. +** gcSHADER Shader
  137758. +** Pointer to a gcSHADER object.
  137759. +**
  137760. +** gctCONST_STRING Name
  137761. +** Name of the uniform to add.
  137762. +**
  137763. +** gcSHADER_TYPE Type
  137764. +** Type of the uniform to add.
  137765. +**
  137766. +** gctSIZE_T Length
  137767. +** Array length of the uniform to add. 'Length' must be at least 1.
  137768. +**
  137769. +** gctINT col
  137770. +** Which uniform.
  137771. +**
  137772. +** OUTPUT:
  137773. +**
  137774. +** gcUNIFORM * Uniform
  137775. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  137776. +*/
  137777. +gceSTATUS
  137778. +gcSHADER_AddPreRotationUniform(
  137779. + IN gcSHADER Shader,
  137780. + IN gctCONST_STRING Name,
  137781. + IN gcSHADER_TYPE Type,
  137782. + IN gctSIZE_T Length,
  137783. + IN gctINT col,
  137784. + OUT gcUNIFORM * Uniform
  137785. + );
  137786. +
  137787. +/*******************************************************************************
  137788. +** gcSHADER_AddUniformEx
  137789. +********************************************************************************
  137790. +**
  137791. +** Add an uniform to a gcSHADER object.
  137792. +**
  137793. +** INPUT:
  137794. +**
  137795. +** gcSHADER Shader
  137796. +** Pointer to a gcSHADER object.
  137797. +**
  137798. +** gctCONST_STRING Name
  137799. +** Name of the uniform to add.
  137800. +**
  137801. +** gcSHADER_TYPE Type
  137802. +** Type of the uniform to add.
  137803. +**
  137804. +** gcSHADER_PRECISION precision
  137805. +** Precision of the uniform to add.
  137806. +**
  137807. +** gctSIZE_T Length
  137808. +** Array length of the uniform to add. 'Length' must be at least 1.
  137809. +**
  137810. +** OUTPUT:
  137811. +**
  137812. +** gcUNIFORM * Uniform
  137813. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  137814. +*/
  137815. +gceSTATUS
  137816. +gcSHADER_AddUniformEx(
  137817. + IN gcSHADER Shader,
  137818. + IN gctCONST_STRING Name,
  137819. + IN gcSHADER_TYPE Type,
  137820. + IN gcSHADER_PRECISION precision,
  137821. + IN gctSIZE_T Length,
  137822. + OUT gcUNIFORM * Uniform
  137823. + );
  137824. +
  137825. +/*******************************************************************************
  137826. +** gcSHADER_AddUniformEx1
  137827. +********************************************************************************
  137828. +**
  137829. +** Add an uniform to a gcSHADER object.
  137830. +**
  137831. +** INPUT:
  137832. +**
  137833. +** gcSHADER Shader
  137834. +** Pointer to a gcSHADER object.
  137835. +**
  137836. +** gctCONST_STRING Name
  137837. +** Name of the uniform to add.
  137838. +**
  137839. +** gcSHADER_TYPE Type
  137840. +** Type of the uniform to add.
  137841. +**
  137842. +** gcSHADER_PRECISION precision
  137843. +** Precision of the uniform to add.
  137844. +**
  137845. +** gctSIZE_T Length
  137846. +** Array length of the uniform to add. 'Length' must be at least 1.
  137847. +**
  137848. +** gcSHADER_VAR_CATEGORY varCategory
  137849. +** Variable category, normal or struct.
  137850. +**
  137851. +** gctUINT16 numStructureElement
  137852. +** If struct, its element number.
  137853. +**
  137854. +** gctINT16 parent
  137855. +** If struct, parent index in gcSHADER.variables.
  137856. +**
  137857. +** gctINT16 prevSibling
  137858. +** If struct, previous sibling index in gcSHADER.variables.
  137859. +**
  137860. +** OUTPUT:
  137861. +**
  137862. +** gcUNIFORM * Uniform
  137863. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  137864. +**
  137865. +** gctINT16* ThisUniformIndex
  137866. +** Returned value about uniform index in gcSHADER.
  137867. +*/
  137868. +gceSTATUS
  137869. +gcSHADER_AddUniformEx1(
  137870. + IN gcSHADER Shader,
  137871. + IN gctCONST_STRING Name,
  137872. + IN gcSHADER_TYPE Type,
  137873. + IN gcSHADER_PRECISION precision,
  137874. + IN gctSIZE_T Length,
  137875. + IN gctINT IsArray,
  137876. + IN gcSHADER_VAR_CATEGORY varCategory,
  137877. + IN gctUINT16 numStructureElement,
  137878. + IN gctINT16 parent,
  137879. + IN gctINT16 prevSibling,
  137880. + OUT gctINT16* ThisUniformIndex,
  137881. + OUT gcUNIFORM * Uniform
  137882. + );
  137883. +
  137884. +/*******************************************************************************
  137885. +** gcSHADER_GetUniformCount
  137886. +********************************************************************************
  137887. +**
  137888. +** Get the number of uniforms for this shader.
  137889. +**
  137890. +** INPUT:
  137891. +**
  137892. +** gcSHADER Shader
  137893. +** Pointer to a gcSHADER object.
  137894. +**
  137895. +** OUTPUT:
  137896. +**
  137897. +** gctSIZE_T * Count
  137898. +** Pointer to a variable receiving the number of uniforms.
  137899. +*/
  137900. +gceSTATUS
  137901. +gcSHADER_GetUniformCount(
  137902. + IN gcSHADER Shader,
  137903. + OUT gctSIZE_T * Count
  137904. + );
  137905. +
  137906. +/*******************************************************************************
  137907. +** gcSHADER_GetPreRotationUniform
  137908. +********************************************************************************
  137909. +**
  137910. +** Get the preRotate Uniform.
  137911. +**
  137912. +** INPUT:
  137913. +**
  137914. +** gcSHADER Shader
  137915. +** Pointer to a gcSHADER object.
  137916. +**
  137917. +** OUTPUT:
  137918. +**
  137919. +** gcUNIFORM ** pUniform
  137920. +** Pointer to a preRotation uniforms array.
  137921. +*/
  137922. +gceSTATUS
  137923. +gcSHADER_GetPreRotationUniform(
  137924. + IN gcSHADER Shader,
  137925. + OUT gcUNIFORM ** pUniform
  137926. + );
  137927. +
  137928. +/*******************************************************************************
  137929. +** gcSHADER_GetUniform
  137930. +********************************************************************************
  137931. +**
  137932. +** Get the gcUNIFORM object pointer for an indexed uniform for this shader.
  137933. +**
  137934. +** INPUT:
  137935. +**
  137936. +** gcSHADER Shader
  137937. +** Pointer to a gcSHADER object.
  137938. +**
  137939. +** gctUINT Index
  137940. +** Index of the uniform to retrieve.
  137941. +**
  137942. +** OUTPUT:
  137943. +**
  137944. +** gcUNIFORM * Uniform
  137945. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  137946. +*/
  137947. +gceSTATUS
  137948. +gcSHADER_GetUniform(
  137949. + IN gcSHADER Shader,
  137950. + IN gctUINT Index,
  137951. + OUT gcUNIFORM * Uniform
  137952. + );
  137953. +
  137954. +
  137955. +/*******************************************************************************
  137956. +** gcSHADER_GetUniformIndexingRange
  137957. +********************************************************************************
  137958. +**
  137959. +** Get the gcUNIFORM object pointer for an indexed uniform for this shader.
  137960. +**
  137961. +** INPUT:
  137962. +**
  137963. +** gcSHADER Shader
  137964. +** Pointer to a gcSHADER object.
  137965. +**
  137966. +** gctINT uniformIndex
  137967. +** Index of the start uniform.
  137968. +**
  137969. +** gctINT offset
  137970. +** Offset to indexing.
  137971. +**
  137972. +** OUTPUT:
  137973. +**
  137974. +** gctINT * LastUniformIndex
  137975. +** Pointer to index of last uniform in indexing range.
  137976. +**
  137977. +** gctINT * OffsetUniformIndex
  137978. +** Pointer to index of uniform that indexing at offset.
  137979. +**
  137980. +** gctINT * DeviationInOffsetUniform
  137981. +** Pointer to offset in uniform picked up.
  137982. +*/
  137983. +gceSTATUS
  137984. +gcSHADER_GetUniformIndexingRange(
  137985. + IN gcSHADER Shader,
  137986. + IN gctINT uniformIndex,
  137987. + IN gctINT offset,
  137988. + OUT gctINT * LastUniformIndex,
  137989. + OUT gctINT * OffsetUniformIndex,
  137990. + OUT gctINT * DeviationInOffsetUniform
  137991. + );
  137992. +
  137993. +/*******************************************************************************
  137994. +** gcSHADER_GetKernelFucntion
  137995. +**
  137996. +** Get the gcKERNEL_FUNCTION object pointer for an indexed kernel function for this shader.
  137997. +**
  137998. +** INPUT:
  137999. +**
  138000. +** gcSHADER Shader
  138001. +** Pointer to a gcSHADER object.
  138002. +**
  138003. +** gctUINT Index
  138004. +** Index of kernel function to retreive the name for.
  138005. +**
  138006. +** OUTPUT:
  138007. +**
  138008. +** gcKERNEL_FUNCTION * KernelFunction
  138009. +** Pointer to a variable receiving the gcKERNEL_FUNCTION object pointer.
  138010. +*/
  138011. +gceSTATUS
  138012. +gcSHADER_GetKernelFunction(
  138013. + IN gcSHADER Shader,
  138014. + IN gctUINT Index,
  138015. + OUT gcKERNEL_FUNCTION * KernelFunction
  138016. + );
  138017. +
  138018. +gceSTATUS
  138019. +gcSHADER_GetKernelFunctionByName(
  138020. + IN gcSHADER Shader,
  138021. + IN gctSTRING KernelName,
  138022. + OUT gcKERNEL_FUNCTION * KernelFunction
  138023. + );
  138024. +/*******************************************************************************
  138025. +** gcSHADER_GetKernelFunctionCount
  138026. +**
  138027. +** Get the number of kernel functions for this shader.
  138028. +**
  138029. +** INPUT:
  138030. +**
  138031. +** gcSHADER Shader
  138032. +** Pointer to a gcSHADER object.
  138033. +**
  138034. +** OUTPUT:
  138035. +**
  138036. +** gctSIZE_T * Count
  138037. +** Pointer to a variable receiving the number of kernel functions.
  138038. +*/
  138039. +gceSTATUS
  138040. +gcSHADER_GetKernelFunctionCount(
  138041. + IN gcSHADER Shader,
  138042. + OUT gctSIZE_T * Count
  138043. + );
  138044. +
  138045. +/*******************************************************************************
  138046. +** gcSHADER_ReallocateOutputs
  138047. +**
  138048. +** Reallocate an array of pointers to gcOUTPUT objects.
  138049. +**
  138050. +** INPUT:
  138051. +**
  138052. +** gcSHADER Shader
  138053. +** Pointer to a gcSHADER object.
  138054. +**
  138055. +** gctSIZE_T Count
  138056. +** Array count to reallocate. 'Count' must be at least 1.
  138057. +*/
  138058. +gceSTATUS
  138059. +gcSHADER_ReallocateOutputs(
  138060. + IN gcSHADER Shader,
  138061. + IN gctSIZE_T Count
  138062. + );
  138063. +
  138064. +/*******************************************************************************
  138065. +** gcSHADER_AddOutput
  138066. +********************************************************************************
  138067. +**
  138068. +** Add an output to a gcSHADER object.
  138069. +**
  138070. +** INPUT:
  138071. +**
  138072. +** gcSHADER Shader
  138073. +** Pointer to a gcSHADER object.
  138074. +**
  138075. +** gctCONST_STRING Name
  138076. +** Name of the output to add.
  138077. +**
  138078. +** gcSHADER_TYPE Type
  138079. +** Type of the output to add.
  138080. +**
  138081. +** gctSIZE_T Length
  138082. +** Array length of the output to add. 'Length' must be at least 1.
  138083. +**
  138084. +** gctUINT16 TempRegister
  138085. +** Temporary register index that holds the output value.
  138086. +**
  138087. +** OUTPUT:
  138088. +**
  138089. +** Nothing.
  138090. +*/
  138091. +gceSTATUS
  138092. +gcSHADER_AddOutput(
  138093. + IN gcSHADER Shader,
  138094. + IN gctCONST_STRING Name,
  138095. + IN gcSHADER_TYPE Type,
  138096. + IN gctSIZE_T Length,
  138097. + IN gctUINT16 TempRegister
  138098. + );
  138099. +
  138100. +gceSTATUS
  138101. +gcSHADER_AddOutputIndexed(
  138102. + IN gcSHADER Shader,
  138103. + IN gctCONST_STRING Name,
  138104. + IN gctSIZE_T Index,
  138105. + IN gctUINT16 TempIndex
  138106. + );
  138107. +
  138108. +/*******************************************************************************
  138109. +** gcSHADER_GetOutputCount
  138110. +********************************************************************************
  138111. +**
  138112. +** Get the number of outputs for this shader.
  138113. +**
  138114. +** INPUT:
  138115. +**
  138116. +** gcSHADER Shader
  138117. +** Pointer to a gcSHADER object.
  138118. +**
  138119. +** OUTPUT:
  138120. +**
  138121. +** gctSIZE_T * Count
  138122. +** Pointer to a variable receiving the number of outputs.
  138123. +*/
  138124. +gceSTATUS
  138125. +gcSHADER_GetOutputCount(
  138126. + IN gcSHADER Shader,
  138127. + OUT gctSIZE_T * Count
  138128. + );
  138129. +
  138130. +/*******************************************************************************
  138131. +** gcSHADER_GetOutput
  138132. +********************************************************************************
  138133. +**
  138134. +** Get the gcOUTPUT object pointer for an indexed output for this shader.
  138135. +**
  138136. +** INPUT:
  138137. +**
  138138. +** gcSHADER Shader
  138139. +** Pointer to a gcSHADER object.
  138140. +**
  138141. +** gctUINT Index
  138142. +** Index of output to retrieve.
  138143. +**
  138144. +** OUTPUT:
  138145. +**
  138146. +** gcOUTPUT * Output
  138147. +** Pointer to a variable receiving the gcOUTPUT object pointer.
  138148. +*/
  138149. +gceSTATUS
  138150. +gcSHADER_GetOutput(
  138151. + IN gcSHADER Shader,
  138152. + IN gctUINT Index,
  138153. + OUT gcOUTPUT * Output
  138154. + );
  138155. +
  138156. +
  138157. +/*******************************************************************************
  138158. +** gcSHADER_GetOutputByName
  138159. +********************************************************************************
  138160. +**
  138161. +** Get the gcOUTPUT object pointer for this shader by output name.
  138162. +**
  138163. +** INPUT:
  138164. +**
  138165. +** gcSHADER Shader
  138166. +** Pointer to a gcSHADER object.
  138167. +**
  138168. +** gctSTRING name
  138169. +** Name of output to retrieve.
  138170. +**
  138171. +** gctSIZE_T nameLength
  138172. +** Length of name to retrieve
  138173. +**
  138174. +** OUTPUT:
  138175. +**
  138176. +** gcOUTPUT * Output
  138177. +** Pointer to a variable receiving the gcOUTPUT object pointer.
  138178. +*/
  138179. +gceSTATUS
  138180. +gcSHADER_GetOutputByName(
  138181. + IN gcSHADER Shader,
  138182. + IN gctSTRING name,
  138183. + IN gctSIZE_T nameLength,
  138184. + OUT gcOUTPUT * Output
  138185. + );
  138186. +
  138187. +/*******************************************************************************
  138188. +** gcSHADER_ReallocateVariables
  138189. +**
  138190. +** Reallocate an array of pointers to gcVARIABLE objects.
  138191. +**
  138192. +** INPUT:
  138193. +**
  138194. +** gcSHADER Shader
  138195. +** Pointer to a gcSHADER object.
  138196. +**
  138197. +** gctSIZE_T Count
  138198. +** Array count to reallocate. 'Count' must be at least 1.
  138199. +*/
  138200. +gceSTATUS
  138201. +gcSHADER_ReallocateVariables(
  138202. + IN gcSHADER Shader,
  138203. + IN gctSIZE_T Count
  138204. + );
  138205. +
  138206. +/*******************************************************************************
  138207. +** gcSHADER_AddVariable
  138208. +********************************************************************************
  138209. +**
  138210. +** Add a variable to a gcSHADER object.
  138211. +**
  138212. +** INPUT:
  138213. +**
  138214. +** gcSHADER Shader
  138215. +** Pointer to a gcSHADER object.
  138216. +**
  138217. +** gctCONST_STRING Name
  138218. +** Name of the variable to add.
  138219. +**
  138220. +** gcSHADER_TYPE Type
  138221. +** Type of the variable to add.
  138222. +**
  138223. +** gctSIZE_T Length
  138224. +** Array length of the variable to add. 'Length' must be at least 1.
  138225. +**
  138226. +** gctUINT16 TempRegister
  138227. +** Temporary register index that holds the variable value.
  138228. +**
  138229. +** OUTPUT:
  138230. +**
  138231. +** Nothing.
  138232. +*/
  138233. +gceSTATUS
  138234. +gcSHADER_AddVariable(
  138235. + IN gcSHADER Shader,
  138236. + IN gctCONST_STRING Name,
  138237. + IN gcSHADER_TYPE Type,
  138238. + IN gctSIZE_T Length,
  138239. + IN gctUINT16 TempRegister
  138240. + );
  138241. +
  138242. +
  138243. +/*******************************************************************************
  138244. +** gcSHADER_AddVariableEx
  138245. +********************************************************************************
  138246. +**
  138247. +** Add a variable to a gcSHADER object.
  138248. +**
  138249. +** INPUT:
  138250. +**
  138251. +** gcSHADER Shader
  138252. +** Pointer to a gcSHADER object.
  138253. +**
  138254. +** gctCONST_STRING Name
  138255. +** Name of the variable to add.
  138256. +**
  138257. +** gcSHADER_TYPE Type
  138258. +** Type of the variable to add.
  138259. +**
  138260. +** gctSIZE_T Length
  138261. +** Array length of the variable to add. 'Length' must be at least 1.
  138262. +**
  138263. +** gctUINT16 TempRegister
  138264. +** Temporary register index that holds the variable value.
  138265. +**
  138266. +** gcSHADER_VAR_CATEGORY varCategory
  138267. +** Variable category, normal or struct.
  138268. +**
  138269. +** gctUINT16 numStructureElement
  138270. +** If struct, its element number.
  138271. +**
  138272. +** gctINT16 parent
  138273. +** If struct, parent index in gcSHADER.variables.
  138274. +**
  138275. +** gctINT16 prevSibling
  138276. +** If struct, previous sibling index in gcSHADER.variables.
  138277. +**
  138278. +** OUTPUT:
  138279. +**
  138280. +** gctINT16* ThisVarIndex
  138281. +** Returned value about variable index in gcSHADER.
  138282. +*/
  138283. +gceSTATUS
  138284. +gcSHADER_AddVariableEx(
  138285. + IN gcSHADER Shader,
  138286. + IN gctCONST_STRING Name,
  138287. + IN gcSHADER_TYPE Type,
  138288. + IN gctSIZE_T Length,
  138289. + IN gctUINT16 TempRegister,
  138290. + IN gcSHADER_VAR_CATEGORY varCategory,
  138291. + IN gctUINT16 numStructureElement,
  138292. + IN gctINT16 parent,
  138293. + IN gctINT16 prevSibling,
  138294. + OUT gctINT16* ThisVarIndex
  138295. + );
  138296. +
  138297. +/*******************************************************************************
  138298. +** gcSHADER_UpdateVariable
  138299. +********************************************************************************
  138300. +**
  138301. +** Update a variable to a gcSHADER object.
  138302. +**
  138303. +** INPUT:
  138304. +**
  138305. +** gcSHADER Shader
  138306. +** Pointer to a gcSHADER object.
  138307. +**
  138308. +** gctUINT Index
  138309. +** Index of variable to retrieve.
  138310. +**
  138311. +** gceVARIABLE_UPDATE_FLAGS flag
  138312. +** Flag which property of variable will be updated.
  138313. +**
  138314. +** gctUINT newValue
  138315. +** New value to update.
  138316. +**
  138317. +** OUTPUT:
  138318. +**
  138319. +** Nothing.
  138320. +*/
  138321. +gceSTATUS
  138322. +gcSHADER_UpdateVariable(
  138323. + IN gcSHADER Shader,
  138324. + IN gctUINT Index,
  138325. + IN gceVARIABLE_UPDATE_FLAGS flag,
  138326. + IN gctUINT newValue
  138327. + );
  138328. +
  138329. +/*******************************************************************************
  138330. +** gcSHADER_GetVariableCount
  138331. +********************************************************************************
  138332. +**
  138333. +** Get the number of variables for this shader.
  138334. +**
  138335. +** INPUT:
  138336. +**
  138337. +** gcSHADER Shader
  138338. +** Pointer to a gcSHADER object.
  138339. +**
  138340. +** OUTPUT:
  138341. +**
  138342. +** gctSIZE_T * Count
  138343. +** Pointer to a variable receiving the number of variables.
  138344. +*/
  138345. +gceSTATUS
  138346. +gcSHADER_GetVariableCount(
  138347. + IN gcSHADER Shader,
  138348. + OUT gctSIZE_T * Count
  138349. + );
  138350. +
  138351. +/*******************************************************************************
  138352. +** gcSHADER_GetVariable
  138353. +********************************************************************************
  138354. +**
  138355. +** Get the gcVARIABLE object pointer for an indexed variable for this shader.
  138356. +**
  138357. +** INPUT:
  138358. +**
  138359. +** gcSHADER Shader
  138360. +** Pointer to a gcSHADER object.
  138361. +**
  138362. +** gctUINT Index
  138363. +** Index of variable to retrieve.
  138364. +**
  138365. +** OUTPUT:
  138366. +**
  138367. +** gcVARIABLE * Variable
  138368. +** Pointer to a variable receiving the gcVARIABLE object pointer.
  138369. +*/
  138370. +gceSTATUS
  138371. +gcSHADER_GetVariable(
  138372. + IN gcSHADER Shader,
  138373. + IN gctUINT Index,
  138374. + OUT gcVARIABLE * Variable
  138375. + );
  138376. +
  138377. +/*******************************************************************************
  138378. +** gcSHADER_GetVariableIndexingRange
  138379. +********************************************************************************
  138380. +**
  138381. +** Get the gcVARIABLE indexing range.
  138382. +**
  138383. +** INPUT:
  138384. +**
  138385. +** gcSHADER Shader
  138386. +** Pointer to a gcSHADER object.
  138387. +**
  138388. +** gcVARIABLE variable
  138389. +** Start variable.
  138390. +**
  138391. +** gctBOOL whole
  138392. +** Indicate whether maximum indexing range is queried
  138393. +**
  138394. +** OUTPUT:
  138395. +**
  138396. +** gctUINT *Start
  138397. +** Pointer to range start (temp register index).
  138398. +**
  138399. +** gctUINT *End
  138400. +** Pointer to range end (temp register index).
  138401. +*/
  138402. +gceSTATUS
  138403. +gcSHADER_GetVariableIndexingRange(
  138404. + IN gcSHADER Shader,
  138405. + IN gcVARIABLE variable,
  138406. + IN gctBOOL whole,
  138407. + OUT gctUINT *Start,
  138408. + OUT gctUINT *End
  138409. + );
  138410. +
  138411. +/*******************************************************************************
  138412. +** gcSHADER_AddOpcode
  138413. +********************************************************************************
  138414. +**
  138415. +** Add an opcode to a gcSHADER object.
  138416. +**
  138417. +** INPUT:
  138418. +**
  138419. +** gcSHADER Shader
  138420. +** Pointer to a gcSHADER object.
  138421. +**
  138422. +** gcSL_OPCODE Opcode
  138423. +** Opcode to add.
  138424. +**
  138425. +** gctUINT16 TempRegister
  138426. +** Temporary register index that acts as the target of the opcode.
  138427. +**
  138428. +** gctUINT8 Enable
  138429. +** Write enable bits for the temporary register that acts as the target
  138430. +** of the opcode.
  138431. +**
  138432. +** gcSL_FORMAT Format
  138433. +** Format of the temporary register.
  138434. +**
  138435. +** OUTPUT:
  138436. +**
  138437. +** Nothing.
  138438. +*/
  138439. +gceSTATUS
  138440. +gcSHADER_AddOpcode(
  138441. + IN gcSHADER Shader,
  138442. + IN gcSL_OPCODE Opcode,
  138443. + IN gctUINT16 TempRegister,
  138444. + IN gctUINT8 Enable,
  138445. + IN gcSL_FORMAT Format
  138446. + );
  138447. +
  138448. +gceSTATUS
  138449. +gcSHADER_AddOpcode2(
  138450. + IN gcSHADER Shader,
  138451. + IN gcSL_OPCODE Opcode,
  138452. + IN gcSL_CONDITION Condition,
  138453. + IN gctUINT16 TempRegister,
  138454. + IN gctUINT8 Enable,
  138455. + IN gcSL_FORMAT Format
  138456. + );
  138457. +
  138458. +/*******************************************************************************
  138459. +** gcSHADER_AddOpcodeIndexed
  138460. +********************************************************************************
  138461. +**
  138462. +** Add an opcode to a gcSHADER object that writes to an dynamically indexed
  138463. +** target.
  138464. +**
  138465. +** INPUT:
  138466. +**
  138467. +** gcSHADER Shader
  138468. +** Pointer to a gcSHADER object.
  138469. +**
  138470. +** gcSL_OPCODE Opcode
  138471. +** Opcode to add.
  138472. +**
  138473. +** gctUINT16 TempRegister
  138474. +** Temporary register index that acts as the target of the opcode.
  138475. +**
  138476. +** gctUINT8 Enable
  138477. +** Write enable bits for the temporary register that acts as the
  138478. +** target of the opcode.
  138479. +**
  138480. +** gcSL_INDEXED Mode
  138481. +** Location of the dynamic index inside the temporary register. Valid
  138482. +** values can be:
  138483. +**
  138484. +** gcSL_INDEXED_X - Use x component of the temporary register.
  138485. +** gcSL_INDEXED_Y - Use y component of the temporary register.
  138486. +** gcSL_INDEXED_Z - Use z component of the temporary register.
  138487. +** gcSL_INDEXED_W - Use w component of the temporary register.
  138488. +**
  138489. +** gctUINT16 IndexRegister
  138490. +** Temporary register index that holds the dynamic index.
  138491. +**
  138492. +** gcSL_FORMAT Format
  138493. +** Format of the temporary register.
  138494. +**
  138495. +** OUTPUT:
  138496. +**
  138497. +** Nothing.
  138498. +*/
  138499. +gceSTATUS
  138500. +gcSHADER_AddOpcodeIndexed(
  138501. + IN gcSHADER Shader,
  138502. + IN gcSL_OPCODE Opcode,
  138503. + IN gctUINT16 TempRegister,
  138504. + IN gctUINT8 Enable,
  138505. + IN gcSL_INDEXED Mode,
  138506. + IN gctUINT16 IndexRegister,
  138507. + IN gcSL_FORMAT Format
  138508. + );
  138509. +
  138510. +/*******************************************************************************
  138511. +** gcSHADER_AddOpcodeConditionIndexed
  138512. +**
  138513. +** Add an opcode to a gcSHADER object that writes to an dynamically indexed
  138514. +** target.
  138515. +**
  138516. +** INPUT:
  138517. +**
  138518. +** gcSHADER Shader
  138519. +** Pointer to a gcSHADER object.
  138520. +**
  138521. +** gcSL_OPCODE Opcode
  138522. +** Opcode to add.
  138523. +**
  138524. +** gcSL_CONDITION Condition
  138525. +** Condition to check.
  138526. +**
  138527. +** gctUINT16 TempRegister
  138528. +** Temporary register index that acts as the target of the opcode.
  138529. +**
  138530. +** gctUINT8 Enable
  138531. +** Write enable bits for the temporary register that acts as the
  138532. +** target of the opcode.
  138533. +**
  138534. +** gcSL_INDEXED Indexed
  138535. +** Location of the dynamic index inside the temporary register. Valid
  138536. +** values can be:
  138537. +**
  138538. +** gcSL_INDEXED_X - Use x component of the temporary register.
  138539. +** gcSL_INDEXED_Y - Use y component of the temporary register.
  138540. +** gcSL_INDEXED_Z - Use z component of the temporary register.
  138541. +** gcSL_INDEXED_W - Use w component of the temporary register.
  138542. +**
  138543. +** gctUINT16 IndexRegister
  138544. +** Temporary register index that holds the dynamic index.
  138545. +**
  138546. +** OUTPUT:
  138547. +**
  138548. +** Nothing.
  138549. +*/
  138550. +gceSTATUS
  138551. +gcSHADER_AddOpcodeConditionIndexed(
  138552. + IN gcSHADER Shader,
  138553. + IN gcSL_OPCODE Opcode,
  138554. + IN gcSL_CONDITION Condition,
  138555. + IN gctUINT16 TempRegister,
  138556. + IN gctUINT8 Enable,
  138557. + IN gcSL_INDEXED Indexed,
  138558. + IN gctUINT16 IndexRegister,
  138559. + IN gcSL_FORMAT Format
  138560. + );
  138561. +
  138562. +/*******************************************************************************
  138563. +** gcSHADER_AddOpcodeConditional
  138564. +********************************************************************************
  138565. +**
  138566. +** Add an conditional opcode to a gcSHADER object.
  138567. +**
  138568. +** INPUT:
  138569. +**
  138570. +** gcSHADER Shader
  138571. +** Pointer to a gcSHADER object.
  138572. +**
  138573. +** gcSL_OPCODE Opcode
  138574. +** Opcode to add.
  138575. +**
  138576. +** gcSL_CONDITION Condition
  138577. +** Condition that needs to evaluate to gcvTRUE in order for the opcode to
  138578. +** execute.
  138579. +**
  138580. +** gctUINT Label
  138581. +** Target label if 'Condition' evaluates to gcvTRUE.
  138582. +**
  138583. +** OUTPUT:
  138584. +**
  138585. +** Nothing.
  138586. +*/
  138587. +gceSTATUS
  138588. +gcSHADER_AddOpcodeConditional(
  138589. + IN gcSHADER Shader,
  138590. + IN gcSL_OPCODE Opcode,
  138591. + IN gcSL_CONDITION Condition,
  138592. + IN gctUINT Label
  138593. + );
  138594. +
  138595. +/*******************************************************************************
  138596. +** gcSHADER_AddOpcodeConditionalFormatted
  138597. +**
  138598. +** Add an conditional jump or call opcode to a gcSHADER object.
  138599. +**
  138600. +** INPUT:
  138601. +**
  138602. +** gcSHADER Shader
  138603. +** Pointer to a gcSHADER object.
  138604. +**
  138605. +** gcSL_OPCODE Opcode
  138606. +** Opcode to add.
  138607. +**
  138608. +** gcSL_CONDITION Condition
  138609. +** Condition that needs to evaluate to gcvTRUE in order for the opcode to
  138610. +** execute.
  138611. +**
  138612. +** gcSL_FORMAT Format
  138613. +** Format of conditional operands
  138614. +**
  138615. +** gctUINT Label
  138616. +** Target label if 'Condition' evaluates to gcvTRUE.
  138617. +**
  138618. +** OUTPUT:
  138619. +**
  138620. +** Nothing.
  138621. +*/
  138622. +gceSTATUS
  138623. +gcSHADER_AddOpcodeConditionalFormatted(
  138624. + IN gcSHADER Shader,
  138625. + IN gcSL_OPCODE Opcode,
  138626. + IN gcSL_CONDITION Condition,
  138627. + IN gcSL_FORMAT Format,
  138628. + IN gctUINT Label
  138629. + );
  138630. +
  138631. +/*******************************************************************************
  138632. +** gcSHADER_AddOpcodeConditionalFormattedEnable
  138633. +**
  138634. +** Add an conditional jump or call opcode to a gcSHADER object.
  138635. +**
  138636. +** INPUT:
  138637. +**
  138638. +** gcSHADER Shader
  138639. +** Pointer to a gcSHADER object.
  138640. +**
  138641. +** gcSL_OPCODE Opcode
  138642. +** Opcode to add.
  138643. +**
  138644. +** gcSL_CONDITION Condition
  138645. +** Condition that needs to evaluate to gcvTRUE in order for the opcode to
  138646. +** execute.
  138647. +**
  138648. +** gcSL_FORMAT Format
  138649. +** Format of conditional operands
  138650. +**
  138651. +** gctUINT8 Enable
  138652. +** Write enable value for the target of the opcode.
  138653. +**
  138654. +** gctUINT Label
  138655. +** Target label if 'Condition' evaluates to gcvTRUE.
  138656. +**
  138657. +** OUTPUT:
  138658. +**
  138659. +** Nothing.
  138660. +*/
  138661. +gceSTATUS
  138662. +gcSHADER_AddOpcodeConditionalFormattedEnable(
  138663. + IN gcSHADER Shader,
  138664. + IN gcSL_OPCODE Opcode,
  138665. + IN gcSL_CONDITION Condition,
  138666. + IN gcSL_FORMAT Format,
  138667. + IN gctUINT8 Enable,
  138668. + IN gctUINT Label
  138669. + );
  138670. +
  138671. +/*******************************************************************************
  138672. +** gcSHADER_AddLabel
  138673. +********************************************************************************
  138674. +**
  138675. +** Define a label at the current instruction of a gcSHADER object.
  138676. +**
  138677. +** INPUT:
  138678. +**
  138679. +** gcSHADER Shader
  138680. +** Pointer to a gcSHADER object.
  138681. +**
  138682. +** gctUINT Label
  138683. +** Label to define.
  138684. +**
  138685. +** OUTPUT:
  138686. +**
  138687. +** Nothing.
  138688. +*/
  138689. +gceSTATUS
  138690. +gcSHADER_AddLabel(
  138691. + IN gcSHADER Shader,
  138692. + IN gctUINT Label
  138693. + );
  138694. +
  138695. +/*******************************************************************************
  138696. +** gcSHADER_AddSource
  138697. +********************************************************************************
  138698. +**
  138699. +** Add a source operand to a gcSHADER object.
  138700. +**
  138701. +** INPUT:
  138702. +**
  138703. +** gcSHADER Shader
  138704. +** Pointer to a gcSHADER object.
  138705. +**
  138706. +** gcSL_TYPE Type
  138707. +** Type of the source operand.
  138708. +**
  138709. +** gctUINT16 SourceIndex
  138710. +** Index of the source operand.
  138711. +**
  138712. +** gctUINT8 Swizzle
  138713. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138714. +**
  138715. +** gcSL_FORMAT Format
  138716. +** Format of the source operand.
  138717. +**
  138718. +** OUTPUT:
  138719. +**
  138720. +** Nothing.
  138721. +*/
  138722. +gceSTATUS
  138723. +gcSHADER_AddSource(
  138724. + IN gcSHADER Shader,
  138725. + IN gcSL_TYPE Type,
  138726. + IN gctUINT16 SourceIndex,
  138727. + IN gctUINT8 Swizzle,
  138728. + IN gcSL_FORMAT Format
  138729. + );
  138730. +
  138731. +/*******************************************************************************
  138732. +** gcSHADER_AddSourceIndexed
  138733. +********************************************************************************
  138734. +**
  138735. +** Add a dynamically indexed source operand to a gcSHADER object.
  138736. +**
  138737. +** INPUT:
  138738. +**
  138739. +** gcSHADER Shader
  138740. +** Pointer to a gcSHADER object.
  138741. +**
  138742. +** gcSL_TYPE Type
  138743. +** Type of the source operand.
  138744. +**
  138745. +** gctUINT16 SourceIndex
  138746. +** Index of the source operand.
  138747. +**
  138748. +** gctUINT8 Swizzle
  138749. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138750. +**
  138751. +** gcSL_INDEXED Mode
  138752. +** Addressing mode for the index.
  138753. +**
  138754. +** gctUINT16 IndexRegister
  138755. +** Temporary register index that holds the dynamic index.
  138756. +**
  138757. +** gcSL_FORMAT Format
  138758. +** Format of the source operand.
  138759. +**
  138760. +** OUTPUT:
  138761. +**
  138762. +** Nothing.
  138763. +*/
  138764. +gceSTATUS
  138765. +gcSHADER_AddSourceIndexed(
  138766. + IN gcSHADER Shader,
  138767. + IN gcSL_TYPE Type,
  138768. + IN gctUINT16 SourceIndex,
  138769. + IN gctUINT8 Swizzle,
  138770. + IN gcSL_INDEXED Mode,
  138771. + IN gctUINT16 IndexRegister,
  138772. + IN gcSL_FORMAT Format
  138773. + );
  138774. +
  138775. +/*******************************************************************************
  138776. +** gcSHADER_AddSourceAttribute
  138777. +********************************************************************************
  138778. +**
  138779. +** Add an attribute as a source operand to a gcSHADER object.
  138780. +**
  138781. +** INPUT:
  138782. +**
  138783. +** gcSHADER Shader
  138784. +** Pointer to a gcSHADER object.
  138785. +**
  138786. +** gcATTRIBUTE Attribute
  138787. +** Pointer to a gcATTRIBUTE object.
  138788. +**
  138789. +** gctUINT8 Swizzle
  138790. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138791. +**
  138792. +** gctINT Index
  138793. +** Static index into the attribute in case the attribute is a matrix
  138794. +** or array.
  138795. +**
  138796. +** OUTPUT:
  138797. +**
  138798. +** Nothing.
  138799. +*/
  138800. +gceSTATUS
  138801. +gcSHADER_AddSourceAttribute(
  138802. + IN gcSHADER Shader,
  138803. + IN gcATTRIBUTE Attribute,
  138804. + IN gctUINT8 Swizzle,
  138805. + IN gctINT Index
  138806. + );
  138807. +
  138808. +/*******************************************************************************
  138809. +** gcSHADER_AddSourceAttributeIndexed
  138810. +********************************************************************************
  138811. +**
  138812. +** Add an indexed attribute as a source operand to a gcSHADER object.
  138813. +**
  138814. +** INPUT:
  138815. +**
  138816. +** gcSHADER Shader
  138817. +** Pointer to a gcSHADER object.
  138818. +**
  138819. +** gcATTRIBUTE Attribute
  138820. +** Pointer to a gcATTRIBUTE object.
  138821. +**
  138822. +** gctUINT8 Swizzle
  138823. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138824. +**
  138825. +** gctINT Index
  138826. +** Static index into the attribute in case the attribute is a matrix
  138827. +** or array.
  138828. +**
  138829. +** gcSL_INDEXED Mode
  138830. +** Addressing mode of the dynamic index.
  138831. +**
  138832. +** gctUINT16 IndexRegister
  138833. +** Temporary register index that holds the dynamic index.
  138834. +**
  138835. +** OUTPUT:
  138836. +**
  138837. +** Nothing.
  138838. +*/
  138839. +gceSTATUS
  138840. +gcSHADER_AddSourceAttributeIndexed(
  138841. + IN gcSHADER Shader,
  138842. + IN gcATTRIBUTE Attribute,
  138843. + IN gctUINT8 Swizzle,
  138844. + IN gctINT Index,
  138845. + IN gcSL_INDEXED Mode,
  138846. + IN gctUINT16 IndexRegister
  138847. + );
  138848. +
  138849. +/*******************************************************************************
  138850. +** gcSHADER_AddSourceUniform
  138851. +********************************************************************************
  138852. +**
  138853. +** Add a uniform as a source operand to a gcSHADER object.
  138854. +**
  138855. +** INPUT:
  138856. +**
  138857. +** gcSHADER Shader
  138858. +** Pointer to a gcSHADER object.
  138859. +**
  138860. +** gcUNIFORM Uniform
  138861. +** Pointer to a gcUNIFORM object.
  138862. +**
  138863. +** gctUINT8 Swizzle
  138864. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138865. +**
  138866. +** gctINT Index
  138867. +** Static index into the uniform in case the uniform is a matrix or
  138868. +** array.
  138869. +**
  138870. +** OUTPUT:
  138871. +**
  138872. +** Nothing.
  138873. +*/
  138874. +gceSTATUS
  138875. +gcSHADER_AddSourceUniform(
  138876. + IN gcSHADER Shader,
  138877. + IN gcUNIFORM Uniform,
  138878. + IN gctUINT8 Swizzle,
  138879. + IN gctINT Index
  138880. + );
  138881. +
  138882. +/*******************************************************************************
  138883. +** gcSHADER_AddSourceUniformIndexed
  138884. +********************************************************************************
  138885. +**
  138886. +** Add an indexed uniform as a source operand to a gcSHADER object.
  138887. +**
  138888. +** INPUT:
  138889. +**
  138890. +** gcSHADER Shader
  138891. +** Pointer to a gcSHADER object.
  138892. +**
  138893. +** gcUNIFORM Uniform
  138894. +** Pointer to a gcUNIFORM object.
  138895. +**
  138896. +** gctUINT8 Swizzle
  138897. +** x, y, z, and w swizzle values packed into one 8-bit value.
  138898. +**
  138899. +** gctINT Index
  138900. +** Static index into the uniform in case the uniform is a matrix or
  138901. +** array.
  138902. +**
  138903. +** gcSL_INDEXED Mode
  138904. +** Addressing mode of the dynamic index.
  138905. +**
  138906. +** gctUINT16 IndexRegister
  138907. +** Temporary register index that holds the dynamic index.
  138908. +**
  138909. +** OUTPUT:
  138910. +**
  138911. +** Nothing.
  138912. +*/
  138913. +gceSTATUS
  138914. +gcSHADER_AddSourceUniformIndexed(
  138915. + IN gcSHADER Shader,
  138916. + IN gcUNIFORM Uniform,
  138917. + IN gctUINT8 Swizzle,
  138918. + IN gctINT Index,
  138919. + IN gcSL_INDEXED Mode,
  138920. + IN gctUINT16 IndexRegister
  138921. + );
  138922. +
  138923. +gceSTATUS
  138924. +gcSHADER_AddSourceSamplerIndexed(
  138925. + IN gcSHADER Shader,
  138926. + IN gctUINT8 Swizzle,
  138927. + IN gcSL_INDEXED Mode,
  138928. + IN gctUINT16 IndexRegister
  138929. + );
  138930. +
  138931. +gceSTATUS
  138932. +gcSHADER_AddSourceAttributeFormatted(
  138933. + IN gcSHADER Shader,
  138934. + IN gcATTRIBUTE Attribute,
  138935. + IN gctUINT8 Swizzle,
  138936. + IN gctINT Index,
  138937. + IN gcSL_FORMAT Format
  138938. + );
  138939. +
  138940. +gceSTATUS
  138941. +gcSHADER_AddSourceAttributeIndexedFormatted(
  138942. + IN gcSHADER Shader,
  138943. + IN gcATTRIBUTE Attribute,
  138944. + IN gctUINT8 Swizzle,
  138945. + IN gctINT Index,
  138946. + IN gcSL_INDEXED Mode,
  138947. + IN gctUINT16 IndexRegister,
  138948. + IN gcSL_FORMAT Format
  138949. + );
  138950. +
  138951. +gceSTATUS
  138952. +gcSHADER_AddSourceUniformFormatted(
  138953. + IN gcSHADER Shader,
  138954. + IN gcUNIFORM Uniform,
  138955. + IN gctUINT8 Swizzle,
  138956. + IN gctINT Index,
  138957. + IN gcSL_FORMAT Format
  138958. + );
  138959. +
  138960. +gceSTATUS
  138961. +gcSHADER_AddSourceUniformIndexedFormatted(
  138962. + IN gcSHADER Shader,
  138963. + IN gcUNIFORM Uniform,
  138964. + IN gctUINT8 Swizzle,
  138965. + IN gctINT Index,
  138966. + IN gcSL_INDEXED Mode,
  138967. + IN gctUINT16 IndexRegister,
  138968. + IN gcSL_FORMAT Format
  138969. + );
  138970. +
  138971. +gceSTATUS
  138972. +gcSHADER_AddSourceSamplerIndexedFormatted(
  138973. + IN gcSHADER Shader,
  138974. + IN gctUINT8 Swizzle,
  138975. + IN gcSL_INDEXED Mode,
  138976. + IN gctUINT16 IndexRegister,
  138977. + IN gcSL_FORMAT Format
  138978. + );
  138979. +
  138980. +/*******************************************************************************
  138981. +** gcSHADER_AddSourceConstant
  138982. +********************************************************************************
  138983. +**
  138984. +** Add a constant floating point value as a source operand to a gcSHADER
  138985. +** object.
  138986. +**
  138987. +** INPUT:
  138988. +**
  138989. +** gcSHADER Shader
  138990. +** Pointer to a gcSHADER object.
  138991. +**
  138992. +** gctFLOAT Constant
  138993. +** Floating point constant.
  138994. +**
  138995. +** OUTPUT:
  138996. +**
  138997. +** Nothing.
  138998. +*/
  138999. +gceSTATUS
  139000. +gcSHADER_AddSourceConstant(
  139001. + IN gcSHADER Shader,
  139002. + IN gctFLOAT Constant
  139003. + );
  139004. +
  139005. +/*******************************************************************************
  139006. +** gcSHADER_AddSourceConstantFormatted
  139007. +********************************************************************************
  139008. +**
  139009. +** Add a constant value as a source operand to a gcSHADER
  139010. +** object.
  139011. +**
  139012. +** INPUT:
  139013. +**
  139014. +** gcSHADER Shader
  139015. +** Pointer to a gcSHADER object.
  139016. +**
  139017. +** void * Constant
  139018. +** Pointer to constant.
  139019. +**
  139020. +** gcSL_FORMAT Format
  139021. +**
  139022. +** OUTPUT:
  139023. +**
  139024. +** Nothing.
  139025. +*/
  139026. +gceSTATUS
  139027. +gcSHADER_AddSourceConstantFormatted(
  139028. + IN gcSHADER Shader,
  139029. + IN void *Constant,
  139030. + IN gcSL_FORMAT Format
  139031. + );
  139032. +
  139033. +/*******************************************************************************
  139034. +** gcSHADER_Pack
  139035. +********************************************************************************
  139036. +**
  139037. +** Pack a dynamically created gcSHADER object by trimming the allocated arrays
  139038. +** and resolving all the labeling.
  139039. +**
  139040. +** INPUT:
  139041. +**
  139042. +** gcSHADER Shader
  139043. +** Pointer to a gcSHADER object.
  139044. +**
  139045. +** OUTPUT:
  139046. +**
  139047. +** Nothing.
  139048. +*/
  139049. +gceSTATUS
  139050. +gcSHADER_Pack(
  139051. + IN gcSHADER Shader
  139052. + );
  139053. +
  139054. +/*******************************************************************************
  139055. +** gcSHADER_SetOptimizationOption
  139056. +********************************************************************************
  139057. +**
  139058. +** Set optimization option of a gcSHADER object.
  139059. +**
  139060. +** INPUT:
  139061. +**
  139062. +** gcSHADER Shader
  139063. +** Pointer to a gcSHADER object.
  139064. +**
  139065. +** gctUINT OptimizationOption
  139066. +** Optimization option. Can be one of the following:
  139067. +**
  139068. +** 0 - No optimization.
  139069. +** 1 - Full optimization.
  139070. +** Other value - For optimizer testing.
  139071. +**
  139072. +** OUTPUT:
  139073. +**
  139074. +** Nothing.
  139075. +*/
  139076. +gceSTATUS
  139077. +gcSHADER_SetOptimizationOption(
  139078. + IN gcSHADER Shader,
  139079. + IN gctUINT OptimizationOption
  139080. + );
  139081. +
  139082. +/*******************************************************************************
  139083. +** gcSHADER_ReallocateFunctions
  139084. +**
  139085. +** Reallocate an array of pointers to gcFUNCTION objects.
  139086. +**
  139087. +** INPUT:
  139088. +**
  139089. +** gcSHADER Shader
  139090. +** Pointer to a gcSHADER object.
  139091. +**
  139092. +** gctSIZE_T Count
  139093. +** Array count to reallocate. 'Count' must be at least 1.
  139094. +*/
  139095. +gceSTATUS
  139096. +gcSHADER_ReallocateFunctions(
  139097. + IN gcSHADER Shader,
  139098. + IN gctSIZE_T Count
  139099. + );
  139100. +
  139101. +gceSTATUS
  139102. +gcSHADER_AddFunction(
  139103. + IN gcSHADER Shader,
  139104. + IN gctCONST_STRING Name,
  139105. + OUT gcFUNCTION * Function
  139106. + );
  139107. +
  139108. +gceSTATUS
  139109. +gcSHADER_ReallocateKernelFunctions(
  139110. + IN gcSHADER Shader,
  139111. + IN gctSIZE_T Count
  139112. + );
  139113. +
  139114. +gceSTATUS
  139115. +gcSHADER_AddKernelFunction(
  139116. + IN gcSHADER Shader,
  139117. + IN gctCONST_STRING Name,
  139118. + OUT gcKERNEL_FUNCTION * KernelFunction
  139119. + );
  139120. +
  139121. +gceSTATUS
  139122. +gcSHADER_BeginFunction(
  139123. + IN gcSHADER Shader,
  139124. + IN gcFUNCTION Function
  139125. + );
  139126. +
  139127. +gceSTATUS
  139128. +gcSHADER_EndFunction(
  139129. + IN gcSHADER Shader,
  139130. + IN gcFUNCTION Function
  139131. + );
  139132. +
  139133. +gceSTATUS
  139134. +gcSHADER_BeginKernelFunction(
  139135. + IN gcSHADER Shader,
  139136. + IN gcKERNEL_FUNCTION KernelFunction
  139137. + );
  139138. +
  139139. +gceSTATUS
  139140. +gcSHADER_EndKernelFunction(
  139141. + IN gcSHADER Shader,
  139142. + IN gcKERNEL_FUNCTION KernelFunction,
  139143. + IN gctSIZE_T LocalMemorySize
  139144. + );
  139145. +
  139146. +gceSTATUS
  139147. +gcSHADER_SetMaxKernelFunctionArgs(
  139148. + IN gcSHADER Shader,
  139149. + IN gctUINT32 MaxKernelFunctionArgs
  139150. + );
  139151. +
  139152. +/*******************************************************************************
  139153. +** gcSHADER_SetConstantMemorySize
  139154. +**
  139155. +** Set the constant memory address space size of a gcSHADER object.
  139156. +**
  139157. +** INPUT:
  139158. +**
  139159. +** gcSHADER Shader
  139160. +** Pointer to a gcSHADER object.
  139161. +**
  139162. +** gctSIZE_T ConstantMemorySize
  139163. +** Constant memory size in bytes
  139164. +**
  139165. +** gctCHAR *ConstantMemoryBuffer
  139166. +** Constant memory buffer
  139167. +*/
  139168. +gceSTATUS
  139169. +gcSHADER_SetConstantMemorySize(
  139170. + IN gcSHADER Shader,
  139171. + IN gctSIZE_T ConstantMemorySize,
  139172. + IN gctCHAR * ConstantMemoryBuffer
  139173. + );
  139174. +
  139175. +/*******************************************************************************
  139176. +** gcSHADER_GetConstantMemorySize
  139177. +**
  139178. +** Set the constant memory address space size of a gcSHADER object.
  139179. +**
  139180. +** INPUT:
  139181. +**
  139182. +** gcSHADER Shader
  139183. +** Pointer to a gcSHADER object.
  139184. +**
  139185. +** OUTPUT:
  139186. +**
  139187. +** gctSIZE_T * ConstantMemorySize
  139188. +** Pointer to a variable receiving constant memory size in bytes
  139189. +**
  139190. +** gctCHAR **ConstantMemoryBuffer.
  139191. +** Pointer to a variable for returned shader constant memory buffer.
  139192. +*/
  139193. +gceSTATUS
  139194. +gcSHADER_GetConstantMemorySize(
  139195. + IN gcSHADER Shader,
  139196. + OUT gctSIZE_T * ConstantMemorySize,
  139197. + OUT gctCHAR ** ConstantMemoryBuffer
  139198. + );
  139199. +
  139200. +/*******************************************************************************
  139201. +** gcSHADER_SetPrivateMemorySize
  139202. +**
  139203. +** Set the private memory address space size of a gcSHADER object.
  139204. +**
  139205. +** INPUT:
  139206. +**
  139207. +** gcSHADER Shader
  139208. +** Pointer to a gcSHADER object.
  139209. +**
  139210. +** gctSIZE_T PrivateMemorySize
  139211. +** Private memory size in bytes
  139212. +*/
  139213. +gceSTATUS
  139214. +gcSHADER_SetPrivateMemorySize(
  139215. + IN gcSHADER Shader,
  139216. + IN gctSIZE_T PrivateMemorySize
  139217. + );
  139218. +
  139219. +/*******************************************************************************
  139220. +** gcSHADER_GetPrivateMemorySize
  139221. +**
  139222. +** Set the private memory address space size of a gcSHADER object.
  139223. +**
  139224. +** INPUT:
  139225. +**
  139226. +** gcSHADER Shader
  139227. +** Pointer to a gcSHADER object.
  139228. +**
  139229. +** OUTPUT:
  139230. +**
  139231. +** gctSIZE_T * PrivateMemorySize
  139232. +** Pointer to a variable receiving private memory size in bytes
  139233. +*/
  139234. +gceSTATUS
  139235. +gcSHADER_GetPrivateMemorySize(
  139236. + IN gcSHADER Shader,
  139237. + OUT gctSIZE_T * PrivateMemorySize
  139238. + );
  139239. +
  139240. +/*******************************************************************************
  139241. +** gcSHADER_SetLocalMemorySize
  139242. +**
  139243. +** Set the local memory address space size of a gcSHADER object.
  139244. +**
  139245. +** INPUT:
  139246. +**
  139247. +** gcSHADER Shader
  139248. +** Pointer to a gcSHADER object.
  139249. +**
  139250. +** gctSIZE_T LocalMemorySize
  139251. +** Local memory size in bytes
  139252. +*/
  139253. +gceSTATUS
  139254. +gcSHADER_SetLocalMemorySize(
  139255. + IN gcSHADER Shader,
  139256. + IN gctSIZE_T LocalMemorySize
  139257. + );
  139258. +
  139259. +/*******************************************************************************
  139260. +** gcSHADER_GetLocalMemorySize
  139261. +**
  139262. +** Set the local memory address space size of a gcSHADER object.
  139263. +**
  139264. +** INPUT:
  139265. +**
  139266. +** gcSHADER Shader
  139267. +** Pointer to a gcSHADER object.
  139268. +**
  139269. +** OUTPUT:
  139270. +**
  139271. +** gctSIZE_T * LocalMemorySize
  139272. +** Pointer to a variable receiving lcoal memory size in bytes
  139273. +*/
  139274. +gceSTATUS
  139275. +gcSHADER_GetLocalMemorySize(
  139276. + IN gcSHADER Shader,
  139277. + OUT gctSIZE_T * LocalMemorySize
  139278. + );
  139279. +
  139280. +
  139281. +/*******************************************************************************
  139282. +** gcSHADER_CheckValidity
  139283. +**
  139284. +** Check validity for a gcSHADER object.
  139285. +**
  139286. +** INPUT:
  139287. +**
  139288. +** gcSHADER Shader
  139289. +** Pointer to a gcSHADER object.
  139290. +**
  139291. +*/
  139292. +gceSTATUS
  139293. +gcSHADER_CheckValidity(
  139294. + IN gcSHADER Shader
  139295. + );
  139296. +
  139297. +#if gcdUSE_WCLIP_PATCH
  139298. +gceSTATUS
  139299. +gcATTRIBUTE_IsPosition(
  139300. + IN gcATTRIBUTE Attribute,
  139301. + OUT gctBOOL * IsPosition
  139302. + );
  139303. +#endif
  139304. +
  139305. +/*******************************************************************************
  139306. +** gcATTRIBUTE_GetType
  139307. +********************************************************************************
  139308. +**
  139309. +** Get the type and array length of a gcATTRIBUTE object.
  139310. +**
  139311. +** INPUT:
  139312. +**
  139313. +** gcATTRIBUTE Attribute
  139314. +** Pointer to a gcATTRIBUTE object.
  139315. +**
  139316. +** OUTPUT:
  139317. +**
  139318. +** gcSHADER_TYPE * Type
  139319. +** Pointer to a variable receiving the type of the attribute. 'Type'
  139320. +** can be gcvNULL, in which case no type will be returned.
  139321. +**
  139322. +** gctSIZE_T * ArrayLength
  139323. +** Pointer to a variable receiving the length of the array if the
  139324. +** attribute was declared as an array. If the attribute was not
  139325. +** declared as an array, the array length will be 1. 'ArrayLength' can
  139326. +** be gcvNULL, in which case no array length will be returned.
  139327. +*/
  139328. +gceSTATUS
  139329. +gcATTRIBUTE_GetType(
  139330. + IN gcATTRIBUTE Attribute,
  139331. + OUT gcSHADER_TYPE * Type,
  139332. + OUT gctSIZE_T * ArrayLength
  139333. + );
  139334. +
  139335. +/*******************************************************************************
  139336. +** gcATTRIBUTE_GetName
  139337. +********************************************************************************
  139338. +**
  139339. +** Get the name of a gcATTRIBUTE object.
  139340. +**
  139341. +** INPUT:
  139342. +**
  139343. +** gcATTRIBUTE Attribute
  139344. +** Pointer to a gcATTRIBUTE object.
  139345. +**
  139346. +** OUTPUT:
  139347. +**
  139348. +** gctSIZE_T * Length
  139349. +** Pointer to a variable receiving the length of the attribute name.
  139350. +** 'Length' can be gcvNULL, in which case no length will be returned.
  139351. +**
  139352. +** gctCONST_STRING * Name
  139353. +** Pointer to a variable receiving the pointer to the attribute name.
  139354. +** 'Name' can be gcvNULL, in which case no name will be returned.
  139355. +*/
  139356. +gceSTATUS
  139357. +gcATTRIBUTE_GetName(
  139358. + IN gcATTRIBUTE Attribute,
  139359. + OUT gctSIZE_T * Length,
  139360. + OUT gctCONST_STRING * Name
  139361. + );
  139362. +
  139363. +/*******************************************************************************
  139364. +** gcATTRIBUTE_IsEnabled
  139365. +********************************************************************************
  139366. +**
  139367. +** Query the enabled state of a gcATTRIBUTE object.
  139368. +**
  139369. +** INPUT:
  139370. +**
  139371. +** gcATTRIBUTE Attribute
  139372. +** Pointer to a gcATTRIBUTE object.
  139373. +**
  139374. +** OUTPUT:
  139375. +**
  139376. +** gctBOOL * Enabled
  139377. +** Pointer to a variable receiving the enabled state of the attribute.
  139378. +*/
  139379. +gceSTATUS
  139380. +gcATTRIBUTE_IsEnabled(
  139381. + IN gcATTRIBUTE Attribute,
  139382. + OUT gctBOOL * Enabled
  139383. + );
  139384. +
  139385. +/*******************************************************************************
  139386. +** gcUNIFORM_GetType
  139387. +********************************************************************************
  139388. +**
  139389. +** Get the type and array length of a gcUNIFORM object.
  139390. +**
  139391. +** INPUT:
  139392. +**
  139393. +** gcUNIFORM Uniform
  139394. +** Pointer to a gcUNIFORM object.
  139395. +**
  139396. +** OUTPUT:
  139397. +**
  139398. +** gcSHADER_TYPE * Type
  139399. +** Pointer to a variable receiving the type of the uniform. 'Type' can
  139400. +** be gcvNULL, in which case no type will be returned.
  139401. +**
  139402. +** gctSIZE_T * ArrayLength
  139403. +** Pointer to a variable receiving the length of the array if the
  139404. +** uniform was declared as an array. If the uniform was not declared
  139405. +** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
  139406. +** in which case no array length will be returned.
  139407. +*/
  139408. +gceSTATUS
  139409. +gcUNIFORM_GetType(
  139410. + IN gcUNIFORM Uniform,
  139411. + OUT gcSHADER_TYPE * Type,
  139412. + OUT gctSIZE_T * ArrayLength
  139413. + );
  139414. +
  139415. +/*******************************************************************************
  139416. +** gcUNIFORM_GetTypeEx
  139417. +********************************************************************************
  139418. +**
  139419. +** Get the type and array length of a gcUNIFORM object.
  139420. +**
  139421. +** INPUT:
  139422. +**
  139423. +** gcUNIFORM Uniform
  139424. +** Pointer to a gcUNIFORM object.
  139425. +**
  139426. +** OUTPUT:
  139427. +**
  139428. +** gcSHADER_TYPE * Type
  139429. +** Pointer to a variable receiving the type of the uniform. 'Type' can
  139430. +** be gcvNULL, in which case no type will be returned.
  139431. +**
  139432. +** gcSHADER_PRECISION * Precision
  139433. +** Pointer to a variable receiving the precision of the uniform. 'Precision' can
  139434. +** be gcvNULL, in which case no type will be returned.
  139435. +**
  139436. +** gctSIZE_T * ArrayLength
  139437. +** Pointer to a variable receiving the length of the array if the
  139438. +** uniform was declared as an array. If the uniform was not declared
  139439. +** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
  139440. +** in which case no array length will be returned.
  139441. +*/
  139442. +gceSTATUS
  139443. +gcUNIFORM_GetTypeEx(
  139444. + IN gcUNIFORM Uniform,
  139445. + OUT gcSHADER_TYPE * Type,
  139446. + OUT gcSHADER_PRECISION * Precision,
  139447. + OUT gctSIZE_T * ArrayLength
  139448. + );
  139449. +
  139450. +/*******************************************************************************
  139451. +** gcUNIFORM_GetFlags
  139452. +********************************************************************************
  139453. +**
  139454. +** Get the flags of a gcUNIFORM object.
  139455. +**
  139456. +** INPUT:
  139457. +**
  139458. +** gcUNIFORM Uniform
  139459. +** Pointer to a gcUNIFORM object.
  139460. +**
  139461. +** OUTPUT:
  139462. +**
  139463. +** gceUNIFORM_FLAGS * Flags
  139464. +** Pointer to a variable receiving the flags of the uniform.
  139465. +**
  139466. +*/
  139467. +gceSTATUS
  139468. +gcUNIFORM_GetFlags(
  139469. + IN gcUNIFORM Uniform,
  139470. + OUT gceUNIFORM_FLAGS * Flags
  139471. + );
  139472. +
  139473. +/*******************************************************************************
  139474. +** gcUNIFORM_SetFlags
  139475. +********************************************************************************
  139476. +**
  139477. +** Set the flags of a gcUNIFORM object.
  139478. +**
  139479. +** INPUT:
  139480. +**
  139481. +** gcUNIFORM Uniform
  139482. +** Pointer to a gcUNIFORM object.
  139483. +**
  139484. +** gceUNIFORM_FLAGS Flags
  139485. +** Flags of the uniform to be set.
  139486. +**
  139487. +** OUTPUT:
  139488. +** Nothing.
  139489. +**
  139490. +*/
  139491. +gceSTATUS
  139492. +gcUNIFORM_SetFlags(
  139493. + IN gcUNIFORM Uniform,
  139494. + IN gceUNIFORM_FLAGS Flags
  139495. + );
  139496. +
  139497. +/*******************************************************************************
  139498. +** gcUNIFORM_GetName
  139499. +********************************************************************************
  139500. +**
  139501. +** Get the name of a gcUNIFORM object.
  139502. +**
  139503. +** INPUT:
  139504. +**
  139505. +** gcUNIFORM Uniform
  139506. +** Pointer to a gcUNIFORM object.
  139507. +**
  139508. +** OUTPUT:
  139509. +**
  139510. +** gctSIZE_T * Length
  139511. +** Pointer to a variable receiving the length of the uniform name.
  139512. +** 'Length' can be gcvNULL, in which case no length will be returned.
  139513. +**
  139514. +** gctCONST_STRING * Name
  139515. +** Pointer to a variable receiving the pointer to the uniform name.
  139516. +** 'Name' can be gcvNULL, in which case no name will be returned.
  139517. +*/
  139518. +gceSTATUS
  139519. +gcUNIFORM_GetName(
  139520. + IN gcUNIFORM Uniform,
  139521. + OUT gctSIZE_T * Length,
  139522. + OUT gctCONST_STRING * Name
  139523. + );
  139524. +
  139525. +/*******************************************************************************
  139526. +** gcUNIFORM_GetSampler
  139527. +********************************************************************************
  139528. +**
  139529. +** Get the physical sampler number for a sampler gcUNIFORM object.
  139530. +**
  139531. +** INPUT:
  139532. +**
  139533. +** gcUNIFORM Uniform
  139534. +** Pointer to a gcUNIFORM object.
  139535. +**
  139536. +** OUTPUT:
  139537. +**
  139538. +** gctUINT32 * Sampler
  139539. +** Pointer to a variable receiving the physical sampler.
  139540. +*/
  139541. +gceSTATUS
  139542. +gcUNIFORM_GetSampler(
  139543. + IN gcUNIFORM Uniform,
  139544. + OUT gctUINT32 * Sampler
  139545. + );
  139546. +
  139547. +/*******************************************************************************
  139548. +** gcUNIFORM_GetFormat
  139549. +**
  139550. +** Get the type and array length of a gcUNIFORM object.
  139551. +**
  139552. +** INPUT:
  139553. +**
  139554. +** gcUNIFORM Uniform
  139555. +** Pointer to a gcUNIFORM object.
  139556. +**
  139557. +** OUTPUT:
  139558. +**
  139559. +** gcSL_FORMAT * Format
  139560. +** Pointer to a variable receiving the format of element of the uniform.
  139561. +** 'Type' can be gcvNULL, in which case no type will be returned.
  139562. +**
  139563. +** gctBOOL * IsPointer
  139564. +** Pointer to a variable receiving the state wheter the uniform is a pointer.
  139565. +** 'IsPointer' can be gcvNULL, in which case no array length will be returned.
  139566. +*/
  139567. +gceSTATUS
  139568. +gcUNIFORM_GetFormat(
  139569. + IN gcUNIFORM Uniform,
  139570. + OUT gcSL_FORMAT * Format,
  139571. + OUT gctBOOL * IsPointer
  139572. + );
  139573. +
  139574. +/*******************************************************************************
  139575. +** gcUNIFORM_SetFormat
  139576. +**
  139577. +** Set the format and isPointer of a uniform.
  139578. +**
  139579. +** INPUT:
  139580. +**
  139581. +** gcUNIFORM Uniform
  139582. +** Pointer to a gcUNIFORM object.
  139583. +**
  139584. +** gcSL_FORMAT Format
  139585. +** Format of element of the uniform shaderType.
  139586. +**
  139587. +** gctBOOL IsPointer
  139588. +** Wheter the uniform is a pointer.
  139589. +**
  139590. +** OUTPUT:
  139591. +**
  139592. +** Nothing.
  139593. +*/
  139594. +gceSTATUS
  139595. +gcUNIFORM_SetFormat(
  139596. + IN gcUNIFORM Uniform,
  139597. + IN gcSL_FORMAT Format,
  139598. + IN gctBOOL IsPointer
  139599. + );
  139600. +
  139601. +/*******************************************************************************
  139602. +** gcUNIFORM_SetValue
  139603. +********************************************************************************
  139604. +**
  139605. +** Set the value of a uniform in integer.
  139606. +**
  139607. +** INPUT:
  139608. +**
  139609. +** gcUNIFORM Uniform
  139610. +** Pointer to a gcUNIFORM object.
  139611. +**
  139612. +** gctSIZE_T Count
  139613. +** Number of entries to program if the uniform has been declared as an
  139614. +** array.
  139615. +**
  139616. +** const gctINT * Value
  139617. +** Pointer to a buffer holding the integer values for the uniform.
  139618. +**
  139619. +** OUTPUT:
  139620. +**
  139621. +** Nothing.
  139622. +*/
  139623. +gceSTATUS
  139624. +gcUNIFORM_SetValue(
  139625. + IN gcUNIFORM Uniform,
  139626. + IN gctSIZE_T Count,
  139627. + IN const gctINT * Value
  139628. + );
  139629. +
  139630. +/*******************************************************************************
  139631. +** gcUNIFORM_SetValueX
  139632. +********************************************************************************
  139633. +**
  139634. +** Set the value of a uniform in fixed point.
  139635. +**
  139636. +** INPUT:
  139637. +**
  139638. +** gcUNIFORM Uniform
  139639. +** Pointer to a gcUNIFORM object.
  139640. +**
  139641. +** gctSIZE_T Count
  139642. +** Number of entries to program if the uniform has been declared as an
  139643. +** array.
  139644. +**
  139645. +** const gctFIXED_POINT * Value
  139646. +** Pointer to a buffer holding the fixed point values for the uniform.
  139647. +**
  139648. +** OUTPUT:
  139649. +**
  139650. +** Nothing.
  139651. +*/
  139652. +gceSTATUS
  139653. +gcUNIFORM_SetValueX(
  139654. + IN gcUNIFORM Uniform,
  139655. + IN gctSIZE_T Count,
  139656. + IN gctFIXED_POINT * Value
  139657. + );
  139658. +
  139659. +/*******************************************************************************
  139660. +** gcUNIFORM_SetValueF
  139661. +********************************************************************************
  139662. +**
  139663. +** Set the value of a uniform in floating point.
  139664. +**
  139665. +** INPUT:
  139666. +**
  139667. +** gcUNIFORM Uniform
  139668. +** Pointer to a gcUNIFORM object.
  139669. +**
  139670. +** gctSIZE_T Count
  139671. +** Number of entries to program if the uniform has been declared as an
  139672. +** array.
  139673. +**
  139674. +** const gctFLOAT * Value
  139675. +** Pointer to a buffer holding the floating point values for the
  139676. +** uniform.
  139677. +**
  139678. +** OUTPUT:
  139679. +**
  139680. +** Nothing.
  139681. +*/
  139682. +gceSTATUS
  139683. +gcUNIFORM_SetValueF(
  139684. + IN gcUNIFORM Uniform,
  139685. + IN gctSIZE_T Count,
  139686. + IN const gctFLOAT * Value
  139687. + );
  139688. +
  139689. +/*******************************************************************************
  139690. +** gcUNIFORM_ProgramF
  139691. +**
  139692. +** Set the value of a uniform in floating point.
  139693. +**
  139694. +** INPUT:
  139695. +**
  139696. +** gctUINT32 Address
  139697. +** Address of Uniform.
  139698. +**
  139699. +** gctSIZE_T Row/Col
  139700. +**
  139701. +** const gctFLOAT * Value
  139702. +** Pointer to a buffer holding the floating point values for the
  139703. +** uniform.
  139704. +**
  139705. +** OUTPUT:
  139706. +**
  139707. +** Nothing.
  139708. +*/
  139709. +gceSTATUS
  139710. +gcUNIFORM_ProgramF(
  139711. + IN gctUINT32 Address,
  139712. + IN gctSIZE_T Row,
  139713. + IN gctSIZE_T Col,
  139714. + IN const gctFLOAT * Value
  139715. + );
  139716. +
  139717. +/*******************************************************************************
  139718. +** gcUNIFORM_GetModelViewProjMatrix
  139719. +********************************************************************************
  139720. +**
  139721. +** Get the value of uniform modelViewProjMatrix ID if present.
  139722. +**
  139723. +** INPUT:
  139724. +**
  139725. +** gcUNIFORM Uniform
  139726. +** Pointer to a gcUNIFORM object.
  139727. +**
  139728. +** OUTPUT:
  139729. +**
  139730. +** Nothing.
  139731. +*/
  139732. +gctUINT
  139733. +gcUNIFORM_GetModelViewProjMatrix(
  139734. + IN gcUNIFORM Uniform
  139735. + );
  139736. +
  139737. +/*******************************************************************************
  139738. +** gcOUTPUT_GetType
  139739. +********************************************************************************
  139740. +**
  139741. +** Get the type and array length of a gcOUTPUT object.
  139742. +**
  139743. +** INPUT:
  139744. +**
  139745. +** gcOUTPUT Output
  139746. +** Pointer to a gcOUTPUT object.
  139747. +**
  139748. +** OUTPUT:
  139749. +**
  139750. +** gcSHADER_TYPE * Type
  139751. +** Pointer to a variable receiving the type of the output. 'Type' can
  139752. +** be gcvNULL, in which case no type will be returned.
  139753. +**
  139754. +** gctSIZE_T * ArrayLength
  139755. +** Pointer to a variable receiving the length of the array if the
  139756. +** output was declared as an array. If the output was not declared
  139757. +** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
  139758. +** in which case no array length will be returned.
  139759. +*/
  139760. +gceSTATUS
  139761. +gcOUTPUT_GetType(
  139762. + IN gcOUTPUT Output,
  139763. + OUT gcSHADER_TYPE * Type,
  139764. + OUT gctSIZE_T * ArrayLength
  139765. + );
  139766. +
  139767. +/*******************************************************************************
  139768. +** gcOUTPUT_GetIndex
  139769. +********************************************************************************
  139770. +**
  139771. +** Get the index of a gcOUTPUT object.
  139772. +**
  139773. +** INPUT:
  139774. +**
  139775. +** gcOUTPUT Output
  139776. +** Pointer to a gcOUTPUT object.
  139777. +**
  139778. +** OUTPUT:
  139779. +**
  139780. +** gctUINT * Index
  139781. +** Pointer to a variable receiving the temporary register index of the
  139782. +** output. 'Index' can be gcvNULL,. in which case no index will be
  139783. +** returned.
  139784. +*/
  139785. +gceSTATUS
  139786. +gcOUTPUT_GetIndex(
  139787. + IN gcOUTPUT Output,
  139788. + OUT gctUINT * Index
  139789. + );
  139790. +
  139791. +/*******************************************************************************
  139792. +** gcOUTPUT_GetName
  139793. +********************************************************************************
  139794. +**
  139795. +** Get the name of a gcOUTPUT object.
  139796. +**
  139797. +** INPUT:
  139798. +**
  139799. +** gcOUTPUT Output
  139800. +** Pointer to a gcOUTPUT object.
  139801. +**
  139802. +** OUTPUT:
  139803. +**
  139804. +** gctSIZE_T * Length
  139805. +** Pointer to a variable receiving the length of the output name.
  139806. +** 'Length' can be gcvNULL, in which case no length will be returned.
  139807. +**
  139808. +** gctCONST_STRING * Name
  139809. +** Pointer to a variable receiving the pointer to the output name.
  139810. +** 'Name' can be gcvNULL, in which case no name will be returned.
  139811. +*/
  139812. +gceSTATUS
  139813. +gcOUTPUT_GetName(
  139814. + IN gcOUTPUT Output,
  139815. + OUT gctSIZE_T * Length,
  139816. + OUT gctCONST_STRING * Name
  139817. + );
  139818. +
  139819. +/*******************************************************************************
  139820. +*********************************************************** F U N C T I O N S **
  139821. +*******************************************************************************/
  139822. +
  139823. +/*******************************************************************************
  139824. +** gcFUNCTION_ReallocateArguments
  139825. +**
  139826. +** Reallocate an array of gcsFUNCTION_ARGUMENT objects.
  139827. +**
  139828. +** INPUT:
  139829. +**
  139830. +** gcFUNCTION Function
  139831. +** Pointer to a gcFUNCTION object.
  139832. +**
  139833. +** gctSIZE_T Count
  139834. +** Array count to reallocate. 'Count' must be at least 1.
  139835. +*/
  139836. +gceSTATUS
  139837. +gcFUNCTION_ReallocateArguments(
  139838. + IN gcFUNCTION Function,
  139839. + IN gctSIZE_T Count
  139840. + );
  139841. +
  139842. +gceSTATUS
  139843. +gcFUNCTION_AddArgument(
  139844. + IN gcFUNCTION Function,
  139845. + IN gctUINT16 TempIndex,
  139846. + IN gctUINT8 Enable,
  139847. + IN gctUINT8 Qualifier
  139848. + );
  139849. +
  139850. +gceSTATUS
  139851. +gcFUNCTION_GetArgument(
  139852. + IN gcFUNCTION Function,
  139853. + IN gctUINT16 Index,
  139854. + OUT gctUINT16_PTR Temp,
  139855. + OUT gctUINT8_PTR Enable,
  139856. + OUT gctUINT8_PTR Swizzle
  139857. + );
  139858. +
  139859. +gceSTATUS
  139860. +gcFUNCTION_GetLabel(
  139861. + IN gcFUNCTION Function,
  139862. + OUT gctUINT_PTR Label
  139863. + );
  139864. +
  139865. +/*******************************************************************************
  139866. +************************* K E R N E L P R O P E R T Y F U N C T I O N S **
  139867. +*******************************************************************************/
  139868. +/*******************************************************************************/
  139869. +gceSTATUS
  139870. +gcKERNEL_FUNCTION_AddKernelFunctionProperties(
  139871. + IN gcKERNEL_FUNCTION KernelFunction,
  139872. + IN gctINT propertyType,
  139873. + IN gctSIZE_T propertySize,
  139874. + IN gctINT * values
  139875. + );
  139876. +
  139877. +gceSTATUS
  139878. +gcKERNEL_FUNCTION_GetPropertyCount(
  139879. + IN gcKERNEL_FUNCTION KernelFunction,
  139880. + OUT gctSIZE_T * Count
  139881. + );
  139882. +
  139883. +gceSTATUS
  139884. +gcKERNEL_FUNCTION_GetProperty(
  139885. + IN gcKERNEL_FUNCTION KernelFunction,
  139886. + IN gctUINT Index,
  139887. + OUT gctSIZE_T * propertySize,
  139888. + OUT gctINT * propertyType,
  139889. + OUT gctINT * propertyValues
  139890. + );
  139891. +
  139892. +
  139893. +/*******************************************************************************
  139894. +*******************************I M A G E S A M P L E R F U N C T I O N S **
  139895. +*******************************************************************************/
  139896. +/*******************************************************************************
  139897. +** gcKERNEL_FUNCTION_ReallocateImageSamplers
  139898. +**
  139899. +** Reallocate an array of pointers to image sampler pair.
  139900. +**
  139901. +** INPUT:
  139902. +**
  139903. +** gcKERNEL_FUNCTION KernelFunction
  139904. +** Pointer to a gcKERNEL_FUNCTION object.
  139905. +**
  139906. +** gctSIZE_T Count
  139907. +** Array count to reallocate. 'Count' must be at least 1.
  139908. +*/
  139909. +gceSTATUS
  139910. +gcKERNEL_FUNCTION_ReallocateImageSamplers(
  139911. + IN gcKERNEL_FUNCTION KernelFunction,
  139912. + IN gctSIZE_T Count
  139913. + );
  139914. +
  139915. +gceSTATUS
  139916. +gcKERNEL_FUNCTION_AddImageSampler(
  139917. + IN gcKERNEL_FUNCTION KernelFunction,
  139918. + IN gctUINT8 ImageNum,
  139919. + IN gctBOOL IsConstantSamplerType,
  139920. + IN gctUINT32 SamplerType
  139921. + );
  139922. +
  139923. +gceSTATUS
  139924. +gcKERNEL_FUNCTION_GetImageSamplerCount(
  139925. + IN gcKERNEL_FUNCTION KernelFunction,
  139926. + OUT gctSIZE_T * Count
  139927. + );
  139928. +
  139929. +gceSTATUS
  139930. +gcKERNEL_FUNCTION_GetImageSampler(
  139931. + IN gcKERNEL_FUNCTION KernelFunction,
  139932. + IN gctUINT Index,
  139933. + OUT gctUINT8 *ImageNum,
  139934. + OUT gctBOOL *IsConstantSamplerType,
  139935. + OUT gctUINT32 *SamplerType
  139936. + );
  139937. +
  139938. +/*******************************************************************************
  139939. +*********************************************K E R N E L F U N C T I O N S **
  139940. +*******************************************************************************/
  139941. +
  139942. +/*******************************************************************************
  139943. +** gcKERNEL_FUNCTION_ReallocateArguments
  139944. +**
  139945. +** Reallocate an array of gcsFUNCTION_ARGUMENT objects.
  139946. +**
  139947. +** INPUT:
  139948. +**
  139949. +** gcKERNEL_FUNCTION Function
  139950. +** Pointer to a gcKERNEL_FUNCTION object.
  139951. +**
  139952. +** gctSIZE_T Count
  139953. +** Array count to reallocate. 'Count' must be at least 1.
  139954. +*/
  139955. +gceSTATUS
  139956. +gcKERNEL_FUNCTION_ReallocateArguments(
  139957. + IN gcKERNEL_FUNCTION Function,
  139958. + IN gctSIZE_T Count
  139959. + );
  139960. +
  139961. +gceSTATUS
  139962. +gcKERNEL_FUNCTION_AddArgument(
  139963. + IN gcKERNEL_FUNCTION Function,
  139964. + IN gctUINT16 TempIndex,
  139965. + IN gctUINT8 Enable,
  139966. + IN gctUINT8 Qualifier
  139967. + );
  139968. +
  139969. +gceSTATUS
  139970. +gcKERNEL_FUNCTION_GetArgument(
  139971. + IN gcKERNEL_FUNCTION Function,
  139972. + IN gctUINT16 Index,
  139973. + OUT gctUINT16_PTR Temp,
  139974. + OUT gctUINT8_PTR Enable,
  139975. + OUT gctUINT8_PTR Swizzle
  139976. + );
  139977. +
  139978. +gceSTATUS
  139979. +gcKERNEL_FUNCTION_GetLabel(
  139980. + IN gcKERNEL_FUNCTION Function,
  139981. + OUT gctUINT_PTR Label
  139982. + );
  139983. +
  139984. +gceSTATUS
  139985. +gcKERNEL_FUNCTION_GetName(
  139986. + IN gcKERNEL_FUNCTION KernelFunction,
  139987. + OUT gctSIZE_T * Length,
  139988. + OUT gctCONST_STRING * Name
  139989. + );
  139990. +
  139991. +gceSTATUS
  139992. +gcKERNEL_FUNCTION_ReallocateUniformArguments(
  139993. + IN gcKERNEL_FUNCTION KernelFunction,
  139994. + IN gctSIZE_T Count
  139995. + );
  139996. +
  139997. +gceSTATUS
  139998. +gcKERNEL_FUNCTION_AddUniformArgument(
  139999. + IN gcKERNEL_FUNCTION KernelFunction,
  140000. + IN gctCONST_STRING Name,
  140001. + IN gcSHADER_TYPE Type,
  140002. + IN gctSIZE_T Length,
  140003. + OUT gcUNIFORM * UniformArgument
  140004. + );
  140005. +
  140006. +gceSTATUS
  140007. +gcKERNEL_FUNCTION_GetUniformArgumentCount(
  140008. + IN gcKERNEL_FUNCTION KernelFunction,
  140009. + OUT gctSIZE_T * Count
  140010. + );
  140011. +
  140012. +gceSTATUS
  140013. +gcKERNEL_FUNCTION_GetUniformArgument(
  140014. + IN gcKERNEL_FUNCTION KernelFunction,
  140015. + IN gctUINT Index,
  140016. + OUT gcUNIFORM * UniformArgument
  140017. + );
  140018. +
  140019. +gceSTATUS
  140020. +gcKERNEL_FUNCTION_SetCodeEnd(
  140021. + IN gcKERNEL_FUNCTION KernelFunction
  140022. + );
  140023. +
  140024. +/*******************************************************************************
  140025. +** gcCompileShader
  140026. +********************************************************************************
  140027. +**
  140028. +** Compile a shader.
  140029. +**
  140030. +** INPUT:
  140031. +**
  140032. +** gcoOS Hal
  140033. +** Pointer to an gcoHAL object.
  140034. +**
  140035. +** gctINT ShaderType
  140036. +** Shader type to compile. Can be one of the following values:
  140037. +**
  140038. +** gcSHADER_TYPE_VERTEX
  140039. +** Compile a vertex shader.
  140040. +**
  140041. +** gcSHADER_TYPE_FRAGMENT
  140042. +** Compile a fragment shader.
  140043. +**
  140044. +** gctSIZE_T SourceSize
  140045. +** Size of the source buffer in bytes.
  140046. +**
  140047. +** gctCONST_STRING Source
  140048. +** Pointer to the buffer containing the shader source code.
  140049. +**
  140050. +** OUTPUT:
  140051. +**
  140052. +** gcSHADER * Binary
  140053. +** Pointer to a variable receiving the pointer to a gcSHADER object
  140054. +** containg the compiled shader code.
  140055. +**
  140056. +** gctSTRING * Log
  140057. +** Pointer to a variable receiving a string pointer containging the
  140058. +** compile log.
  140059. +*/
  140060. +gceSTATUS
  140061. +gcCompileShader(
  140062. + IN gcoHAL Hal,
  140063. + IN gctINT ShaderType,
  140064. + IN gctSIZE_T SourceSize,
  140065. + IN gctCONST_STRING Source,
  140066. + OUT gcSHADER * Binary,
  140067. + OUT gctSTRING * Log
  140068. + );
  140069. +
  140070. +/*******************************************************************************
  140071. +** gcOptimizeShader
  140072. +********************************************************************************
  140073. +**
  140074. +** Optimize a shader.
  140075. +**
  140076. +** INPUT:
  140077. +**
  140078. +** gcSHADER Shader
  140079. +** Pointer to a gcSHADER object holding information about the compiled
  140080. +** shader.
  140081. +**
  140082. +** gctFILE LogFile
  140083. +** Pointer to an open FILE object.
  140084. +*/
  140085. +gceSTATUS
  140086. +gcOptimizeShader(
  140087. + IN gcSHADER Shader,
  140088. + IN gctFILE LogFile
  140089. + );
  140090. +
  140091. +/*******************************************************************************
  140092. +** gcLinkShaders
  140093. +********************************************************************************
  140094. +**
  140095. +** Link two shaders and generate a harwdare specific state buffer by compiling
  140096. +** the compiler generated code through the resource allocator and code
  140097. +** generator.
  140098. +**
  140099. +** INPUT:
  140100. +**
  140101. +** gcSHADER VertexShader
  140102. +** Pointer to a gcSHADER object holding information about the compiled
  140103. +** vertex shader.
  140104. +**
  140105. +** gcSHADER FragmentShader
  140106. +** Pointer to a gcSHADER object holding information about the compiled
  140107. +** fragment shader.
  140108. +**
  140109. +** gceSHADER_FLAGS Flags
  140110. +** Compiler flags. Can be any of the following:
  140111. +**
  140112. +** gcvSHADER_DEAD_CODE - Dead code elimination.
  140113. +** gcvSHADER_RESOURCE_USAGE - Resource usage optimizaion.
  140114. +** gcvSHADER_OPTIMIZER - Full optimization.
  140115. +** gcvSHADER_USE_GL_Z - Use OpenGL ES Z coordinate.
  140116. +** gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position.
  140117. +** gcvSHADER_USE_GL_FACE - Use OpenGL ES gl_FaceForward.
  140118. +**
  140119. +** OUTPUT:
  140120. +**
  140121. +** gctSIZE_T * StateBufferSize
  140122. +** Pointer to a variable receicing the number of bytes in the buffer
  140123. +** returned in 'StateBuffer'.
  140124. +**
  140125. +** gctPOINTER * StateBuffer
  140126. +** Pointer to a variable receiving a buffer pointer that contains the
  140127. +** states required to download the shaders into the hardware.
  140128. +**
  140129. +** gcsHINT_PTR * Hints
  140130. +** Pointer to a variable receiving a gcsHINT structure pointer that
  140131. +** contains information required when loading the shader states.
  140132. +*/
  140133. +gceSTATUS
  140134. +gcLinkShaders(
  140135. + IN gcSHADER VertexShader,
  140136. + IN gcSHADER FragmentShader,
  140137. + IN gceSHADER_FLAGS Flags,
  140138. + OUT gctSIZE_T * StateBufferSize,
  140139. + OUT gctPOINTER * StateBuffer,
  140140. + OUT gcsHINT_PTR * Hints,
  140141. + OUT gcMACHINECODE_PTR *ppVsMachineCode,
  140142. + OUT gcMACHINECODE_PTR *ppFsMachineCode
  140143. + );
  140144. +
  140145. +/*******************************************************************************
  140146. +** gcLoadShaders
  140147. +********************************************************************************
  140148. +**
  140149. +** Load a pre-compiled and pre-linked shader program into the hardware.
  140150. +**
  140151. +** INPUT:
  140152. +**
  140153. +** gcoHAL Hal
  140154. +** Pointer to a gcoHAL object.
  140155. +**
  140156. +** gctSIZE_T StateBufferSize
  140157. +** The number of bytes in the 'StateBuffer'.
  140158. +**
  140159. +** gctPOINTER StateBuffer
  140160. +** Pointer to the states that make up the shader program.
  140161. +**
  140162. +** gcsHINT_PTR Hints
  140163. +** Pointer to a gcsHINT structure that contains information required
  140164. +** when loading the shader states.
  140165. +*/
  140166. +gceSTATUS
  140167. +gcLoadShaders(
  140168. + IN gcoHAL Hal,
  140169. + IN gctSIZE_T StateBufferSize,
  140170. + IN gctPOINTER StateBuffer,
  140171. + IN gcsHINT_PTR Hints
  140172. + );
  140173. +
  140174. +gceSTATUS
  140175. +gcRecompileShaders(
  140176. + IN gcoHAL Hal,
  140177. + IN gcMACHINECODE_PTR pVsMachineCode,
  140178. + IN gcMACHINECODE_PTR pPsMachineCode,
  140179. + /*Recompile variables*/
  140180. + IN OUT gctPOINTER *ppRecompileStateBuffer,
  140181. + IN OUT gctSIZE_T *pRecompileStateBufferSize,
  140182. + IN OUT gcsHINT_PTR *ppRecompileHints,
  140183. + /* natvie state*/
  140184. + IN gctPOINTER pNativeStateBuffer,
  140185. + IN gctSIZE_T nativeStateBufferSize,
  140186. + IN gcsHINT_PTR pNativeHints,
  140187. + /* npt info */
  140188. + IN gctUINT32 Samplers,
  140189. + IN gctUINT32 *SamplerWrapS,
  140190. + IN gctUINT32 *SamplerWrapT
  140191. + );
  140192. +
  140193. +gceSTATUS
  140194. +gcRecompileDepthBias(
  140195. + IN gcoHAL Hal,
  140196. + IN gcMACHINECODE_PTR pVsMachineCode,
  140197. + /*Recompile variables*/
  140198. + IN OUT gctPOINTER *ppRecompileStateBuffer,
  140199. + IN OUT gctSIZE_T *pRecompileStateBufferSize,
  140200. + IN OUT gcsHINT_PTR *ppRecompileHints,
  140201. + /* natvie state*/
  140202. + IN gctPOINTER pNativeStateBuffer,
  140203. + IN gctSIZE_T nativeStateBufferSize,
  140204. + IN gcsHINT_PTR pNativeHints,
  140205. + OUT gctINT * uniformAddr,
  140206. + OUT gctINT * uniformChannel
  140207. + );
  140208. +
  140209. +/*******************************************************************************
  140210. +** gcSaveProgram
  140211. +********************************************************************************
  140212. +**
  140213. +** Save pre-compiled shaders and pre-linked programs to a binary file.
  140214. +**
  140215. +** INPUT:
  140216. +**
  140217. +** gcSHADER VertexShader
  140218. +** Pointer to vertex shader object.
  140219. +**
  140220. +** gcSHADER FragmentShader
  140221. +** Pointer to fragment shader object.
  140222. +**
  140223. +** gctSIZE_T ProgramBufferSize
  140224. +** Number of bytes in 'ProgramBuffer'.
  140225. +**
  140226. +** gctPOINTER ProgramBuffer
  140227. +** Pointer to buffer containing the program states.
  140228. +**
  140229. +** gcsHINT_PTR Hints
  140230. +** Pointer to HINTS structure for program states.
  140231. +**
  140232. +** OUTPUT:
  140233. +**
  140234. +** gctPOINTER * Binary
  140235. +** Pointer to a variable receiving the binary data to be saved.
  140236. +**
  140237. +** gctSIZE_T * BinarySize
  140238. +** Pointer to a variable receiving the number of bytes inside 'Binary'.
  140239. +*/
  140240. +gceSTATUS
  140241. +gcSaveProgram(
  140242. + IN gcSHADER VertexShader,
  140243. + IN gcSHADER FragmentShader,
  140244. + IN gctSIZE_T ProgramBufferSize,
  140245. + IN gctPOINTER ProgramBuffer,
  140246. + IN gcsHINT_PTR Hints,
  140247. + OUT gctPOINTER * Binary,
  140248. + OUT gctSIZE_T * BinarySize
  140249. + );
  140250. +
  140251. +/*******************************************************************************
  140252. +** gcLoadProgram
  140253. +********************************************************************************
  140254. +**
  140255. +** Load pre-compiled shaders and pre-linked programs from a binary file.
  140256. +**
  140257. +** INPUT:
  140258. +**
  140259. +** gctPOINTER Binary
  140260. +** Pointer to the binary data loaded.
  140261. +**
  140262. +** gctSIZE_T BinarySize
  140263. +** Number of bytes in 'Binary'.
  140264. +**
  140265. +** OUTPUT:
  140266. +**
  140267. +** gcSHADER VertexShader
  140268. +** Pointer to a vertex shader object.
  140269. +**
  140270. +** gcSHADER FragmentShader
  140271. +** Pointer to a fragment shader object.
  140272. +**
  140273. +** gctSIZE_T * ProgramBufferSize
  140274. +** Pointer to a variable receicing the number of bytes in the buffer
  140275. +** returned in 'ProgramBuffer'.
  140276. +**
  140277. +** gctPOINTER * ProgramBuffer
  140278. +** Pointer to a variable receiving a buffer pointer that contains the
  140279. +** states required to download the shaders into the hardware.
  140280. +**
  140281. +** gcsHINT_PTR * Hints
  140282. +** Pointer to a variable receiving a gcsHINT structure pointer that
  140283. +** contains information required when loading the shader states.
  140284. +*/
  140285. +gceSTATUS
  140286. +gcLoadProgram(
  140287. + IN gctPOINTER Binary,
  140288. + IN gctSIZE_T BinarySize,
  140289. + OUT gcSHADER VertexShader,
  140290. + OUT gcSHADER FragmentShader,
  140291. + OUT gctSIZE_T * ProgramBufferSize,
  140292. + OUT gctPOINTER * ProgramBuffer,
  140293. + OUT gcsHINT_PTR * Hints
  140294. + );
  140295. +
  140296. +/*******************************************************************************
  140297. +** gcCompileKernel
  140298. +********************************************************************************
  140299. +**
  140300. +** Compile a OpenCL kernel shader.
  140301. +**
  140302. +** INPUT:
  140303. +**
  140304. +** gcoOS Hal
  140305. +** Pointer to an gcoHAL object.
  140306. +**
  140307. +** gctSIZE_T SourceSize
  140308. +** Size of the source buffer in bytes.
  140309. +**
  140310. +** gctCONST_STRING Source
  140311. +** Pointer to the buffer containing the shader source code.
  140312. +**
  140313. +** OUTPUT:
  140314. +**
  140315. +** gcSHADER * Binary
  140316. +** Pointer to a variable receiving the pointer to a gcSHADER object
  140317. +** containg the compiled shader code.
  140318. +**
  140319. +** gctSTRING * Log
  140320. +** Pointer to a variable receiving a string pointer containging the
  140321. +** compile log.
  140322. +*/
  140323. +gceSTATUS
  140324. +gcCompileKernel(
  140325. + IN gcoHAL Hal,
  140326. + IN gctSIZE_T SourceSize,
  140327. + IN gctCONST_STRING Source,
  140328. + IN gctCONST_STRING Options,
  140329. + OUT gcSHADER * Binary,
  140330. + OUT gctSTRING * Log
  140331. + );
  140332. +
  140333. +/*******************************************************************************
  140334. +** gcLinkKernel
  140335. +********************************************************************************
  140336. +**
  140337. +** Link OpenCL kernel and generate a harwdare specific state buffer by compiling
  140338. +** the compiler generated code through the resource allocator and code
  140339. +** generator.
  140340. +**
  140341. +** INPUT:
  140342. +**
  140343. +** gcSHADER Kernel
  140344. +** Pointer to a gcSHADER object holding information about the compiled
  140345. +** OpenCL kernel.
  140346. +**
  140347. +** gceSHADER_FLAGS Flags
  140348. +** Compiler flags. Can be any of the following:
  140349. +**
  140350. +** gcvSHADER_DEAD_CODE - Dead code elimination.
  140351. +** gcvSHADER_RESOURCE_USAGE - Resource usage optimizaion.
  140352. +** gcvSHADER_OPTIMIZER - Full optimization.
  140353. +** gcvSHADER_USE_GL_Z - Use OpenGL ES Z coordinate.
  140354. +** gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position.
  140355. +** gcvSHADER_USE_GL_FACE - Use OpenGL ES gl_FaceForward.
  140356. +**
  140357. +** OUTPUT:
  140358. +**
  140359. +** gctSIZE_T * StateBufferSize
  140360. +** Pointer to a variable receiving the number of bytes in the buffer
  140361. +** returned in 'StateBuffer'.
  140362. +**
  140363. +** gctPOINTER * StateBuffer
  140364. +** Pointer to a variable receiving a buffer pointer that contains the
  140365. +** states required to download the shaders into the hardware.
  140366. +**
  140367. +** gcsHINT_PTR * Hints
  140368. +** Pointer to a variable receiving a gcsHINT structure pointer that
  140369. +** contains information required when loading the shader states.
  140370. +*/
  140371. +gceSTATUS
  140372. +gcLinkKernel(
  140373. + IN gcSHADER Kernel,
  140374. + IN gceSHADER_FLAGS Flags,
  140375. + OUT gctSIZE_T * StateBufferSize,
  140376. + OUT gctPOINTER * StateBuffer,
  140377. + OUT gcsHINT_PTR * Hints
  140378. + );
  140379. +
  140380. +/*******************************************************************************
  140381. +** gcLoadKernel
  140382. +********************************************************************************
  140383. +**
  140384. +** Load a pre-compiled and pre-linked kernel program into the hardware.
  140385. +**
  140386. +** INPUT:
  140387. +**
  140388. +** gctSIZE_T StateBufferSize
  140389. +** The number of bytes in the 'StateBuffer'.
  140390. +**
  140391. +** gctPOINTER StateBuffer
  140392. +** Pointer to the states that make up the shader program.
  140393. +**
  140394. +** gcsHINT_PTR Hints
  140395. +** Pointer to a gcsHINT structure that contains information required
  140396. +** when loading the shader states.
  140397. +*/
  140398. +gceSTATUS
  140399. +gcLoadKernel(
  140400. + IN gctSIZE_T StateBufferSize,
  140401. + IN gctPOINTER StateBuffer,
  140402. + IN gcsHINT_PTR Hints
  140403. + );
  140404. +
  140405. +gceSTATUS
  140406. +gcInvokeThreadWalker(
  140407. + IN gcsTHREAD_WALKER_INFO_PTR Info
  140408. + );
  140409. +
  140410. +void
  140411. +gcTYPE_GetTypeInfo(
  140412. + IN gcSHADER_TYPE Type,
  140413. + OUT gctINT * Components,
  140414. + OUT gctINT * Rows,
  140415. + OUT gctCONST_STRING * Name
  140416. + );
  140417. +
  140418. +gctBOOL
  140419. +gcOPT_doVaryingPackingForShader(
  140420. + IN gcSHADER Shader
  140421. + );
  140422. +
  140423. +gceSTATUS
  140424. +gcSHADER_PatchNPOTForMachineCode(
  140425. + IN gcSHADER_KIND shaderType,
  140426. + IN gcMACHINECODE_PTR pMachineCode,
  140427. + IN gcNPOT_PATCH_PARAM_PTR pPatchParam,
  140428. + IN gctUINT countOfPatchParam,
  140429. + IN gctUINT hwSupportedInstCount,
  140430. + OUT gctPOINTER* ppCmdBuffer,
  140431. + OUT gctUINT32* pByteSizeOfCmdBuffer,
  140432. + IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */
  140433. + );
  140434. +
  140435. +gceSTATUS
  140436. +gcSHADER_PatchZBiasForMachineCodeVS(
  140437. + IN gcMACHINECODE_PTR pMachineCode,
  140438. + IN OUT gcZBIAS_PATCH_PARAM_PTR pPatchParam,
  140439. + IN gctUINT hwSupportedInstCount,
  140440. + OUT gctPOINTER* ppCmdBuffer,
  140441. + OUT gctUINT32* pByteSizeOfCmdBuffer,
  140442. + IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */
  140443. + );
  140444. +
  140445. +#ifdef __cplusplus
  140446. +}
  140447. +#endif
  140448. +
  140449. +#endif /* VIVANTE_NO_3D */
  140450. +#endif /* __gc_hal_compiler_h_ */
  140451. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
  140452. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h 1969-12-31 18:00:00.000000000 -0600
  140453. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h 2014-12-08 00:31:53.468418001 -0600
  140454. @@ -0,0 +1,1051 @@
  140455. +/****************************************************************************
  140456. +*
  140457. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  140458. +*
  140459. +* This program is free software; you can redistribute it and/or modify
  140460. +* it under the terms of the GNU General Public License as published by
  140461. +* the Free Software Foundation; either version 2 of the license, or
  140462. +* (at your option) any later version.
  140463. +*
  140464. +* This program is distributed in the hope that it will be useful,
  140465. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  140466. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  140467. +* GNU General Public License for more details.
  140468. +*
  140469. +* You should have received a copy of the GNU General Public License
  140470. +* along with this program; if not write to the Free Software
  140471. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  140472. +*
  140473. +*****************************************************************************/
  140474. +
  140475. +
  140476. +#ifndef __gc_hal_driver_h_
  140477. +#define __gc_hal_driver_h_
  140478. +
  140479. +#include "gc_hal_enum.h"
  140480. +#include "gc_hal_types.h"
  140481. +
  140482. +#if gcdENABLE_VG
  140483. +#include "gc_hal_driver_vg.h"
  140484. +#endif
  140485. +
  140486. +#ifdef __cplusplus
  140487. +extern "C" {
  140488. +#endif
  140489. +
  140490. +/******************************************************************************\
  140491. +******************************* I/O Control Codes ******************************
  140492. +\******************************************************************************/
  140493. +
  140494. +#define gcvHAL_CLASS "galcore"
  140495. +#define IOCTL_GCHAL_INTERFACE 30000
  140496. +#define IOCTL_GCHAL_KERNEL_INTERFACE 30001
  140497. +#define IOCTL_GCHAL_TERMINATE 30002
  140498. +
  140499. +/******************************************************************************\
  140500. +********************************* Command Codes ********************************
  140501. +\******************************************************************************/
  140502. +
  140503. +typedef enum _gceHAL_COMMAND_CODES
  140504. +{
  140505. + /* Generic query. */
  140506. + gcvHAL_QUERY_VIDEO_MEMORY,
  140507. + gcvHAL_QUERY_CHIP_IDENTITY,
  140508. +
  140509. + /* Contiguous memory. */
  140510. + gcvHAL_ALLOCATE_NON_PAGED_MEMORY,
  140511. + gcvHAL_FREE_NON_PAGED_MEMORY,
  140512. + gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY,
  140513. + gcvHAL_FREE_CONTIGUOUS_MEMORY,
  140514. +
  140515. + /* Video memory allocation. */
  140516. + gcvHAL_ALLOCATE_VIDEO_MEMORY, /* Enforced alignment. */
  140517. + gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY, /* No alignment. */
  140518. + gcvHAL_FREE_VIDEO_MEMORY,
  140519. +
  140520. + /* Physical-to-logical mapping. */
  140521. + gcvHAL_MAP_MEMORY,
  140522. + gcvHAL_UNMAP_MEMORY,
  140523. +
  140524. + /* Logical-to-physical mapping. */
  140525. + gcvHAL_MAP_USER_MEMORY,
  140526. + gcvHAL_UNMAP_USER_MEMORY,
  140527. +
  140528. + /* Surface lock/unlock. */
  140529. + gcvHAL_LOCK_VIDEO_MEMORY,
  140530. + gcvHAL_UNLOCK_VIDEO_MEMORY,
  140531. +
  140532. + /* Event queue. */
  140533. + gcvHAL_EVENT_COMMIT,
  140534. +
  140535. + gcvHAL_USER_SIGNAL,
  140536. + gcvHAL_SIGNAL,
  140537. + gcvHAL_WRITE_DATA,
  140538. +
  140539. + gcvHAL_COMMIT,
  140540. + gcvHAL_STALL,
  140541. +
  140542. + gcvHAL_READ_REGISTER,
  140543. + gcvHAL_WRITE_REGISTER,
  140544. +
  140545. + gcvHAL_GET_PROFILE_SETTING,
  140546. + gcvHAL_SET_PROFILE_SETTING,
  140547. +
  140548. + gcvHAL_READ_ALL_PROFILE_REGISTERS,
  140549. + gcvHAL_PROFILE_REGISTERS_2D,
  140550. +#if VIVANTE_PROFILER_PERDRAW
  140551. + gcvHAL_READ_PROFILER_REGISTER_SETTING,
  140552. +#endif
  140553. +
  140554. + /* Power management. */
  140555. + gcvHAL_SET_POWER_MANAGEMENT_STATE,
  140556. + gcvHAL_QUERY_POWER_MANAGEMENT_STATE,
  140557. +
  140558. + gcvHAL_GET_BASE_ADDRESS,
  140559. +
  140560. + gcvHAL_SET_IDLE, /* reserved */
  140561. +
  140562. + /* Queries. */
  140563. + gcvHAL_QUERY_KERNEL_SETTINGS,
  140564. +
  140565. + /* Reset. */
  140566. + gcvHAL_RESET,
  140567. +
  140568. + /* Map physical address into handle. */
  140569. + gcvHAL_MAP_PHYSICAL,
  140570. +
  140571. + /* Debugger stuff. */
  140572. + gcvHAL_DEBUG,
  140573. +
  140574. + /* Cache stuff. */
  140575. + gcvHAL_CACHE,
  140576. +
  140577. + /* TimeStamp */
  140578. + gcvHAL_TIMESTAMP,
  140579. +
  140580. + /* Database. */
  140581. + gcvHAL_DATABASE,
  140582. +
  140583. + /* Version. */
  140584. + gcvHAL_VERSION,
  140585. +
  140586. + /* Chip info */
  140587. + gcvHAL_CHIP_INFO,
  140588. +
  140589. + /* Process attaching/detaching. */
  140590. + gcvHAL_ATTACH,
  140591. + gcvHAL_DETACH,
  140592. +
  140593. + /* Composition. */
  140594. + gcvHAL_COMPOSE,
  140595. +
  140596. + /* Set timeOut value */
  140597. + gcvHAL_SET_TIMEOUT,
  140598. +
  140599. + /* Frame database. */
  140600. + gcvHAL_GET_FRAME_INFO,
  140601. +
  140602. + /* Shared info for each process */
  140603. + gcvHAL_GET_SHARED_INFO,
  140604. + gcvHAL_SET_SHARED_INFO,
  140605. + gcvHAL_QUERY_COMMAND_BUFFER,
  140606. +
  140607. + gcvHAL_COMMIT_DONE,
  140608. +
  140609. + /* GPU and event dump */
  140610. + gcvHAL_DUMP_GPU_STATE,
  140611. + gcvHAL_DUMP_EVENT,
  140612. +
  140613. + /* Virtual command buffer. */
  140614. + gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER,
  140615. + gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER,
  140616. +
  140617. + /* FSCALE_VAL. */
  140618. + gcvHAL_SET_FSCALE_VALUE,
  140619. + gcvHAL_GET_FSCALE_VALUE,
  140620. +
  140621. + /* Reset time stamp. */
  140622. + gcvHAL_QUERY_RESET_TIME_STAMP,
  140623. +
  140624. + /* Sync point operations. */
  140625. + gcvHAL_SYNC_POINT,
  140626. +
  140627. + /* Create native fence and return its fd. */
  140628. + gcvHAL_CREATE_NATIVE_FENCE,
  140629. +
  140630. + /* Video memory database */
  140631. + gcvHAL_VIDMEM_DATABASE,
  140632. +}
  140633. +gceHAL_COMMAND_CODES;
  140634. +
  140635. +/******************************************************************************\
  140636. +****************************** Interface Structure *****************************
  140637. +\******************************************************************************/
  140638. +
  140639. +#define gcdMAX_PROFILE_FILE_NAME 128
  140640. +
  140641. +/* Kernel settings. */
  140642. +typedef struct _gcsKERNEL_SETTINGS
  140643. +{
  140644. + /* Used RealTime signal between kernel and user. */
  140645. + gctINT signal;
  140646. +}
  140647. +gcsKERNEL_SETTINGS;
  140648. +
  140649. +
  140650. +/* gcvHAL_QUERY_CHIP_IDENTITY */
  140651. +typedef struct _gcsHAL_QUERY_CHIP_IDENTITY * gcsHAL_QUERY_CHIP_IDENTITY_PTR;
  140652. +typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
  140653. +{
  140654. +
  140655. + /* Chip model. */
  140656. + gceCHIPMODEL chipModel;
  140657. +
  140658. + /* Revision value.*/
  140659. + gctUINT32 chipRevision;
  140660. +
  140661. + /* Supported feature fields. */
  140662. + gctUINT32 chipFeatures;
  140663. +
  140664. + /* Supported minor feature fields. */
  140665. + gctUINT32 chipMinorFeatures;
  140666. +
  140667. + /* Supported minor feature 1 fields. */
  140668. + gctUINT32 chipMinorFeatures1;
  140669. +
  140670. + /* Supported minor feature 2 fields. */
  140671. + gctUINT32 chipMinorFeatures2;
  140672. +
  140673. + /* Supported minor feature 3 fields. */
  140674. + gctUINT32 chipMinorFeatures3;
  140675. +
  140676. + /* Supported minor feature 4 fields. */
  140677. + gctUINT32 chipMinorFeatures4;
  140678. +
  140679. + /* Number of streams supported. */
  140680. + gctUINT32 streamCount;
  140681. +
  140682. + /* Total number of temporary registers per thread. */
  140683. + gctUINT32 registerMax;
  140684. +
  140685. + /* Maximum number of threads. */
  140686. + gctUINT32 threadCount;
  140687. +
  140688. + /* Number of shader cores. */
  140689. + gctUINT32 shaderCoreCount;
  140690. +
  140691. + /* Size of the vertex cache. */
  140692. + gctUINT32 vertexCacheSize;
  140693. +
  140694. + /* Number of entries in the vertex output buffer. */
  140695. + gctUINT32 vertexOutputBufferSize;
  140696. +
  140697. + /* Number of pixel pipes. */
  140698. + gctUINT32 pixelPipes;
  140699. +
  140700. + /* Number of instructions. */
  140701. + gctUINT32 instructionCount;
  140702. +
  140703. + /* Number of constants. */
  140704. + gctUINT32 numConstants;
  140705. +
  140706. + /* Buffer size */
  140707. + gctUINT32 bufferSize;
  140708. +
  140709. + /* Number of varyings */
  140710. + gctUINT32 varyingsCount;
  140711. +
  140712. + /* Supertile layout style in hardware */
  140713. + gctUINT32 superTileMode;
  140714. +
  140715. + /* Special control bits for 2D chip. */
  140716. + gctUINT32 chip2DControl;
  140717. +}
  140718. +gcsHAL_QUERY_CHIP_IDENTITY;
  140719. +
  140720. +/* gcvHAL_COMPOSE. */
  140721. +typedef struct _gcsHAL_COMPOSE * gcsHAL_COMPOSE_PTR;
  140722. +typedef struct _gcsHAL_COMPOSE
  140723. +{
  140724. + /* Composition state buffer. */
  140725. + gctUINT64 physical;
  140726. + gctUINT64 logical;
  140727. + gctUINT offset;
  140728. + gctUINT size;
  140729. +
  140730. + /* Composition end signal. */
  140731. + gctUINT64 process;
  140732. + gctUINT64 signal;
  140733. +
  140734. + /* User signals. */
  140735. + gctUINT64 userProcess;
  140736. + gctUINT64 userSignal1;
  140737. + gctUINT64 userSignal2;
  140738. +
  140739. +#if defined(__QNXNTO__)
  140740. + /* Client pulse side-channel connection ID. */
  140741. + gctINT32 coid;
  140742. +
  140743. + /* Set by server. */
  140744. + gctINT32 rcvid;
  140745. +#endif
  140746. +}
  140747. +gcsHAL_COMPOSE;
  140748. +
  140749. +
  140750. +typedef struct _gcsHAL_INTERFACE
  140751. +{
  140752. + /* Command code. */
  140753. + gceHAL_COMMAND_CODES command;
  140754. +
  140755. + /* Hardware type. */
  140756. + gceHARDWARE_TYPE hardwareType;
  140757. +
  140758. + /* Status value. */
  140759. + gceSTATUS status;
  140760. +
  140761. + /* Handle to this interface channel. */
  140762. + gctUINT64 handle;
  140763. +
  140764. + /* Pid of the client. */
  140765. + gctUINT32 pid;
  140766. +
  140767. + /* Union of command structures. */
  140768. + union _u
  140769. + {
  140770. + /* gcvHAL_GET_BASE_ADDRESS */
  140771. + struct _gcsHAL_GET_BASE_ADDRESS
  140772. + {
  140773. + /* Physical memory address of internal memory. */
  140774. + OUT gctUINT32 baseAddress;
  140775. + }
  140776. + GetBaseAddress;
  140777. +
  140778. + /* gcvHAL_QUERY_VIDEO_MEMORY */
  140779. + struct _gcsHAL_QUERY_VIDEO_MEMORY
  140780. + {
  140781. + /* Physical memory address of internal memory. Just a name. */
  140782. + OUT gctUINT32 internalPhysical;
  140783. +
  140784. + /* Size in bytes of internal memory. */
  140785. + OUT gctUINT64 internalSize;
  140786. +
  140787. + /* Physical memory address of external memory. Just a name. */
  140788. + OUT gctUINT32 externalPhysical;
  140789. +
  140790. + /* Size in bytes of external memory.*/
  140791. + OUT gctUINT64 externalSize;
  140792. +
  140793. + /* Physical memory address of contiguous memory. Just a name. */
  140794. + OUT gctUINT32 contiguousPhysical;
  140795. +
  140796. + /* Size in bytes of contiguous memory.*/
  140797. + OUT gctUINT64 contiguousSize;
  140798. + }
  140799. + QueryVideoMemory;
  140800. +
  140801. + /* gcvHAL_QUERY_CHIP_IDENTITY */
  140802. + gcsHAL_QUERY_CHIP_IDENTITY QueryChipIdentity;
  140803. +
  140804. + /* gcvHAL_MAP_MEMORY */
  140805. + struct _gcsHAL_MAP_MEMORY
  140806. + {
  140807. + /* Physical memory address to map. Just a name on Linux/Qnx. */
  140808. + IN gctUINT32 physical;
  140809. +
  140810. + /* Number of bytes in physical memory to map. */
  140811. + IN gctUINT64 bytes;
  140812. +
  140813. + /* Address of mapped memory. */
  140814. + OUT gctUINT64 logical;
  140815. + }
  140816. + MapMemory;
  140817. +
  140818. + /* gcvHAL_UNMAP_MEMORY */
  140819. + struct _gcsHAL_UNMAP_MEMORY
  140820. + {
  140821. + /* Physical memory address to unmap. Just a name on Linux/Qnx. */
  140822. + IN gctUINT32 physical;
  140823. +
  140824. + /* Number of bytes in physical memory to unmap. */
  140825. + IN gctUINT64 bytes;
  140826. +
  140827. + /* Address of mapped memory to unmap. */
  140828. + IN gctUINT64 logical;
  140829. + }
  140830. + UnmapMemory;
  140831. +
  140832. + /* gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY */
  140833. + struct _gcsHAL_ALLOCATE_LINEAR_VIDEO_MEMORY
  140834. + {
  140835. + /* Number of bytes to allocate. */
  140836. + IN OUT gctUINT bytes;
  140837. +
  140838. + /* Buffer alignment. */
  140839. + IN gctUINT alignment;
  140840. +
  140841. + /* Type of allocation. */
  140842. + IN gceSURF_TYPE type;
  140843. +
  140844. + /* Memory pool to allocate from. */
  140845. + IN OUT gcePOOL pool;
  140846. +
  140847. + /* Allocated video memory in gcuVIDMEM_NODE. */
  140848. + OUT gctUINT64 node;
  140849. + }
  140850. + AllocateLinearVideoMemory;
  140851. +
  140852. + /* gcvHAL_ALLOCATE_VIDEO_MEMORY */
  140853. + struct _gcsHAL_ALLOCATE_VIDEO_MEMORY
  140854. + {
  140855. + /* Width of rectangle to allocate. */
  140856. + IN OUT gctUINT width;
  140857. +
  140858. + /* Height of rectangle to allocate. */
  140859. + IN OUT gctUINT height;
  140860. +
  140861. + /* Depth of rectangle to allocate. */
  140862. + IN gctUINT depth;
  140863. +
  140864. + /* Format rectangle to allocate in gceSURF_FORMAT. */
  140865. + IN gceSURF_FORMAT format;
  140866. +
  140867. + /* Type of allocation. */
  140868. + IN gceSURF_TYPE type;
  140869. +
  140870. + /* Memory pool to allocate from. */
  140871. + IN OUT gcePOOL pool;
  140872. +
  140873. + /* Allocated video memory in gcuVIDMEM_NODE. */
  140874. + OUT gctUINT64 node;
  140875. + }
  140876. + AllocateVideoMemory;
  140877. +
  140878. + /* gcvHAL_FREE_VIDEO_MEMORY */
  140879. + struct _gcsHAL_FREE_VIDEO_MEMORY
  140880. + {
  140881. + /* Allocated video memory in gcuVIDMEM_NODE. */
  140882. + IN gctUINT64 node;
  140883. +
  140884. +#ifdef __QNXNTO__
  140885. +/* TODO: This is part of the unlock - why is it here? */
  140886. + /* Mapped logical address to unmap in user space. */
  140887. + OUT gctUINT64 memory;
  140888. +
  140889. + /* Number of bytes to allocated. */
  140890. + OUT gctUINT64 bytes;
  140891. +#endif
  140892. + }
  140893. + FreeVideoMemory;
  140894. +
  140895. + /* gcvHAL_LOCK_VIDEO_MEMORY */
  140896. + struct _gcsHAL_LOCK_VIDEO_MEMORY
  140897. + {
  140898. + /* Allocated video memory gcuVIDMEM_NODE gcuVIDMEM_NODE. */
  140899. + IN gctUINT64 node;
  140900. +
  140901. + /* Cache configuration. */
  140902. + /* Only gcvPOOL_CONTIGUOUS and gcvPOOL_VIRUTAL
  140903. + ** can be configured */
  140904. + IN gctBOOL cacheable;
  140905. +
  140906. + /* Hardware specific address. */
  140907. + OUT gctUINT32 address;
  140908. +
  140909. + /* Mapped logical address. */
  140910. + OUT gctUINT64 memory;
  140911. + }
  140912. + LockVideoMemory;
  140913. +
  140914. + /* gcvHAL_UNLOCK_VIDEO_MEMORY */
  140915. + struct _gcsHAL_UNLOCK_VIDEO_MEMORY
  140916. + {
  140917. + /* Allocated video memory in gcuVIDMEM_NODE. */
  140918. + IN gctUINT64 node;
  140919. +
  140920. + /* Type of surface. */
  140921. + IN gceSURF_TYPE type;
  140922. +
  140923. + /* Flag to unlock surface asynchroneously. */
  140924. + IN OUT gctBOOL asynchroneous;
  140925. + }
  140926. + UnlockVideoMemory;
  140927. +
  140928. + /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
  140929. + struct _gcsHAL_ALLOCATE_NON_PAGED_MEMORY
  140930. + {
  140931. + /* Number of bytes to allocate. */
  140932. + IN OUT gctUINT64 bytes;
  140933. +
  140934. + /* Physical address of allocation. Just a name. */
  140935. + OUT gctUINT32 physical;
  140936. +
  140937. + /* Logical address of allocation. */
  140938. + OUT gctUINT64 logical;
  140939. + }
  140940. + AllocateNonPagedMemory;
  140941. +
  140942. + /* gcvHAL_FREE_NON_PAGED_MEMORY */
  140943. + struct _gcsHAL_FREE_NON_PAGED_MEMORY
  140944. + {
  140945. + /* Number of bytes allocated. */
  140946. + IN gctUINT64 bytes;
  140947. +
  140948. + /* Physical address of allocation. Just a name. */
  140949. + IN gctUINT32 physical;
  140950. +
  140951. + /* Logical address of allocation. */
  140952. + IN gctUINT64 logical;
  140953. + }
  140954. + FreeNonPagedMemory;
  140955. +
  140956. + /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
  140957. + struct _gcsHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER
  140958. + {
  140959. + /* Number of bytes to allocate. */
  140960. + IN OUT gctUINT64 bytes;
  140961. +
  140962. + /* Physical address of allocation. Just a name. */
  140963. + OUT gctUINT32 physical;
  140964. +
  140965. + /* Logical address of allocation. */
  140966. + OUT gctUINT64 logical;
  140967. + }
  140968. + AllocateVirtualCommandBuffer;
  140969. +
  140970. + /* gcvHAL_FREE_NON_PAGED_MEMORY */
  140971. + struct _gcsHAL_FREE_VIRTUAL_COMMAND_BUFFER
  140972. + {
  140973. + /* Number of bytes allocated. */
  140974. + IN gctUINT64 bytes;
  140975. +
  140976. + /* Physical address of allocation. Just a name. */
  140977. + IN gctUINT32 physical;
  140978. +
  140979. + /* Logical address of allocation. */
  140980. + IN gctUINT64 logical;
  140981. + }
  140982. + FreeVirtualCommandBuffer;
  140983. +
  140984. + /* gcvHAL_EVENT_COMMIT. */
  140985. + struct _gcsHAL_EVENT_COMMIT
  140986. + {
  140987. + /* Event queue in gcsQUEUE. */
  140988. + IN gctUINT64 queue;
  140989. + }
  140990. + Event;
  140991. +
  140992. + /* gcvHAL_COMMIT */
  140993. + struct _gcsHAL_COMMIT
  140994. + {
  140995. + /* Context buffer object gckCONTEXT. */
  140996. + IN gctUINT64 context;
  140997. +
  140998. + /* Command buffer gcoCMDBUF. */
  140999. + IN gctUINT64 commandBuffer;
  141000. +
  141001. + /* State delta buffer in gcsSTATE_DELTA. */
  141002. + gctUINT64 delta;
  141003. +
  141004. + /* Event queue in gcsQUEUE. */
  141005. + IN gctUINT64 queue;
  141006. + }
  141007. + Commit;
  141008. +
  141009. + /* gcvHAL_MAP_USER_MEMORY */
  141010. + struct _gcsHAL_MAP_USER_MEMORY
  141011. + {
  141012. + /* Base address of user memory to map. */
  141013. + IN gctUINT64 memory;
  141014. +
  141015. + /* Physical address of user memory to map. */
  141016. + IN gctUINT32 physical;
  141017. +
  141018. + /* Size of user memory in bytes to map. */
  141019. + IN gctUINT64 size;
  141020. +
  141021. + /* Info record required by gcvHAL_UNMAP_USER_MEMORY. Just a name. */
  141022. + OUT gctUINT32 info;
  141023. +
  141024. + /* Physical address of mapped memory. */
  141025. + OUT gctUINT32 address;
  141026. + }
  141027. + MapUserMemory;
  141028. +
  141029. + /* gcvHAL_UNMAP_USER_MEMORY */
  141030. + struct _gcsHAL_UNMAP_USER_MEMORY
  141031. + {
  141032. + /* Base address of user memory to unmap. */
  141033. + IN gctUINT64 memory;
  141034. +
  141035. + /* Size of user memory in bytes to unmap. */
  141036. + IN gctUINT64 size;
  141037. +
  141038. + /* Info record returned by gcvHAL_MAP_USER_MEMORY. Just a name. */
  141039. + IN gctUINT32 info;
  141040. +
  141041. + /* Physical address of mapped memory as returned by
  141042. + gcvHAL_MAP_USER_MEMORY. */
  141043. + IN gctUINT32 address;
  141044. + }
  141045. + UnmapUserMemory;
  141046. +#if !USE_NEW_LINUX_SIGNAL
  141047. + /* gcsHAL_USER_SIGNAL */
  141048. + struct _gcsHAL_USER_SIGNAL
  141049. + {
  141050. + /* Command. */
  141051. + gceUSER_SIGNAL_COMMAND_CODES command;
  141052. +
  141053. + /* Signal ID. */
  141054. + IN OUT gctINT id;
  141055. +
  141056. + /* Reset mode. */
  141057. + IN gctBOOL manualReset;
  141058. +
  141059. + /* Wait timedout. */
  141060. + IN gctUINT32 wait;
  141061. +
  141062. + /* State. */
  141063. + IN gctBOOL state;
  141064. + }
  141065. + UserSignal;
  141066. +#endif
  141067. +
  141068. + /* gcvHAL_SIGNAL. */
  141069. + struct _gcsHAL_SIGNAL
  141070. + {
  141071. + /* Signal handle to signal gctSIGNAL. */
  141072. + IN gctUINT64 signal;
  141073. +
  141074. + /* Reserved gctSIGNAL. */
  141075. + IN gctUINT64 auxSignal;
  141076. +
  141077. + /* Process owning the signal gctHANDLE. */
  141078. + IN gctUINT64 process;
  141079. +
  141080. +#if defined(__QNXNTO__)
  141081. + /* Client pulse side-channel connection ID. Set by client in gcoOS_CreateSignal. */
  141082. + IN gctINT32 coid;
  141083. +
  141084. + /* Set by server. */
  141085. + IN gctINT32 rcvid;
  141086. +#endif
  141087. + /* Event generated from where of pipeline */
  141088. + IN gceKERNEL_WHERE fromWhere;
  141089. + }
  141090. + Signal;
  141091. +
  141092. + /* gcvHAL_WRITE_DATA. */
  141093. + struct _gcsHAL_WRITE_DATA
  141094. + {
  141095. + /* Address to write data to. */
  141096. + IN gctUINT32 address;
  141097. +
  141098. + /* Data to write. */
  141099. + IN gctUINT32 data;
  141100. + }
  141101. + WriteData;
  141102. +
  141103. + /* gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY */
  141104. + struct _gcsHAL_ALLOCATE_CONTIGUOUS_MEMORY
  141105. + {
  141106. + /* Number of bytes to allocate. */
  141107. + IN OUT gctUINT64 bytes;
  141108. +
  141109. + /* Hardware address of allocation. */
  141110. + OUT gctUINT32 address;
  141111. +
  141112. + /* Physical address of allocation. Just a name. */
  141113. + OUT gctUINT32 physical;
  141114. +
  141115. + /* Logical address of allocation. */
  141116. + OUT gctUINT64 logical;
  141117. + }
  141118. + AllocateContiguousMemory;
  141119. +
  141120. + /* gcvHAL_FREE_CONTIGUOUS_MEMORY */
  141121. + struct _gcsHAL_FREE_CONTIGUOUS_MEMORY
  141122. + {
  141123. + /* Number of bytes allocated. */
  141124. + IN gctUINT64 bytes;
  141125. +
  141126. + /* Physical address of allocation. Just a name. */
  141127. + IN gctUINT32 physical;
  141128. +
  141129. + /* Logical address of allocation. */
  141130. + IN gctUINT64 logical;
  141131. + }
  141132. + FreeContiguousMemory;
  141133. +
  141134. + /* gcvHAL_READ_REGISTER */
  141135. + struct _gcsHAL_READ_REGISTER
  141136. + {
  141137. + /* Logical address of memory to write data to. */
  141138. + IN gctUINT32 address;
  141139. +
  141140. + /* Data read. */
  141141. + OUT gctUINT32 data;
  141142. + }
  141143. + ReadRegisterData;
  141144. +
  141145. + /* gcvHAL_WRITE_REGISTER */
  141146. + struct _gcsHAL_WRITE_REGISTER
  141147. + {
  141148. + /* Logical address of memory to write data to. */
  141149. + IN gctUINT32 address;
  141150. +
  141151. + /* Data read. */
  141152. + IN gctUINT32 data;
  141153. + }
  141154. + WriteRegisterData;
  141155. +
  141156. +#if VIVANTE_PROFILER
  141157. + /* gcvHAL_GET_PROFILE_SETTING */
  141158. + struct _gcsHAL_GET_PROFILE_SETTING
  141159. + {
  141160. + /* Enable profiling */
  141161. + OUT gctBOOL enable;
  141162. +
  141163. + /* The profile file name */
  141164. + OUT gctCHAR fileName[gcdMAX_PROFILE_FILE_NAME];
  141165. + }
  141166. + GetProfileSetting;
  141167. +
  141168. + /* gcvHAL_SET_PROFILE_SETTING */
  141169. + struct _gcsHAL_SET_PROFILE_SETTING
  141170. + {
  141171. + /* Enable profiling */
  141172. + IN gctBOOL enable;
  141173. +
  141174. + /* The profile file name */
  141175. + IN gctCHAR fileName[gcdMAX_PROFILE_FILE_NAME];
  141176. + }
  141177. + SetProfileSetting;
  141178. +
  141179. +#if VIVANTE_PROFILER_PERDRAW
  141180. + /* gcvHAL_READ_PROFILER_REGISTER_SETTING */
  141181. + struct _gcsHAL_READ_PROFILER_REGISTER_SETTING
  141182. + {
  141183. + /*Should Clear Register*/
  141184. + IN gctBOOL bclear;
  141185. + }
  141186. + SetProfilerRegisterClear;
  141187. +#endif
  141188. +
  141189. + /* gcvHAL_READ_ALL_PROFILE_REGISTERS */
  141190. + struct _gcsHAL_READ_ALL_PROFILE_REGISTERS
  141191. + {
  141192. +#if VIVANTE_PROFILER_CONTEXT
  141193. + /* Context buffer object gckCONTEXT. Just a name. */
  141194. + IN gctUINT32 context;
  141195. +#endif
  141196. + /* Data read. */
  141197. + OUT gcsPROFILER_COUNTERS counters;
  141198. + }
  141199. + RegisterProfileData;
  141200. +
  141201. + /* gcvHAL_PROFILE_REGISTERS_2D */
  141202. + struct _gcsHAL_PROFILE_REGISTERS_2D
  141203. + {
  141204. + /* Data read in gcs2D_PROFILE. */
  141205. + OUT gctUINT64 hwProfile2D;
  141206. + }
  141207. + RegisterProfileData2D;
  141208. +#endif
  141209. + /* Power management. */
  141210. + /* gcvHAL_SET_POWER_MANAGEMENT_STATE */
  141211. + struct _gcsHAL_SET_POWER_MANAGEMENT
  141212. + {
  141213. + /* Data read. */
  141214. + IN gceCHIPPOWERSTATE state;
  141215. + }
  141216. + SetPowerManagement;
  141217. +
  141218. + /* gcvHAL_QUERY_POWER_MANAGEMENT_STATE */
  141219. + struct _gcsHAL_QUERY_POWER_MANAGEMENT
  141220. + {
  141221. + /* Data read. */
  141222. + OUT gceCHIPPOWERSTATE state;
  141223. +
  141224. + /* Idle query. */
  141225. + OUT gctBOOL isIdle;
  141226. + }
  141227. + QueryPowerManagement;
  141228. +
  141229. + /* gcvHAL_QUERY_KERNEL_SETTINGS */
  141230. + struct _gcsHAL_QUERY_KERNEL_SETTINGS
  141231. + {
  141232. + /* Settings.*/
  141233. + OUT gcsKERNEL_SETTINGS settings;
  141234. + }
  141235. + QueryKernelSettings;
  141236. +
  141237. + /* gcvHAL_MAP_PHYSICAL */
  141238. + struct _gcsHAL_MAP_PHYSICAL
  141239. + {
  141240. + /* gcvTRUE to map, gcvFALSE to unmap. */
  141241. + IN gctBOOL map;
  141242. +
  141243. + /* Physical address. */
  141244. + IN OUT gctUINT64 physical;
  141245. + }
  141246. + MapPhysical;
  141247. +
  141248. + /* gcvHAL_DEBUG */
  141249. + struct _gcsHAL_DEBUG
  141250. + {
  141251. + /* If gcvTRUE, set the debug information. */
  141252. + IN gctBOOL set;
  141253. + IN gctUINT32 level;
  141254. + IN gctUINT32 zones;
  141255. + IN gctBOOL enable;
  141256. +
  141257. + IN gceDEBUG_MESSAGE_TYPE type;
  141258. + IN gctUINT32 messageSize;
  141259. +
  141260. + /* Message to print if not empty. */
  141261. + IN gctCHAR message[80];
  141262. + }
  141263. + Debug;
  141264. +
  141265. + /* gcvHAL_CACHE */
  141266. + struct _gcsHAL_CACHE
  141267. + {
  141268. + IN gceCACHEOPERATION operation;
  141269. + /* gctHANDLE */
  141270. + IN gctUINT64 process;
  141271. + IN gctUINT64 logical;
  141272. + IN gctUINT64 bytes;
  141273. + /* gcuVIDMEM_NODE_PTR */
  141274. + IN gctUINT64 node;
  141275. + }
  141276. + Cache;
  141277. +
  141278. + /* gcvHAL_TIMESTAMP */
  141279. + struct _gcsHAL_TIMESTAMP
  141280. + {
  141281. + /* Timer select. */
  141282. + IN gctUINT32 timer;
  141283. +
  141284. + /* Timer request type (0-stop, 1-start, 2-send delta). */
  141285. + IN gctUINT32 request;
  141286. +
  141287. + /* Result of delta time in microseconds. */
  141288. + OUT gctINT32 timeDelta;
  141289. + }
  141290. + TimeStamp;
  141291. +
  141292. + /* gcvHAL_DATABASE */
  141293. + struct _gcsHAL_DATABASE
  141294. + {
  141295. + /* Set to gcvTRUE if you want to query a particular process ID.
  141296. + ** Set to gcvFALSE to query the last detached process. */
  141297. + IN gctBOOL validProcessID;
  141298. +
  141299. + /* Process ID to query. */
  141300. + IN gctUINT32 processID;
  141301. +
  141302. + /* Information. */
  141303. + OUT gcuDATABASE_INFO vidMem;
  141304. + OUT gcuDATABASE_INFO nonPaged;
  141305. + OUT gcuDATABASE_INFO contiguous;
  141306. + OUT gcuDATABASE_INFO gpuIdle;
  141307. + }
  141308. + Database;
  141309. +
  141310. + /* gcvHAL_VIDMEM_DATABASE */
  141311. + struct _gcsHAL_VIDMEM_DATABASE
  141312. + {
  141313. + /* Set to gcvTRUE if you want to query a particular process ID.
  141314. + ** Set to gcvFALSE to query the last detached process. */
  141315. + IN gctBOOL validProcessID;
  141316. +
  141317. + /* Process ID to query. */
  141318. + IN gctUINT32 processID;
  141319. +
  141320. + /* Information. */
  141321. + OUT gcuDATABASE_INFO vidMemResv;
  141322. + OUT gcuDATABASE_INFO vidMemCont;
  141323. + OUT gcuDATABASE_INFO vidMemVirt;
  141324. + }
  141325. + VidMemDatabase;
  141326. +
  141327. + /* gcvHAL_VERSION */
  141328. + struct _gcsHAL_VERSION
  141329. + {
  141330. + /* Major version: N.n.n. */
  141331. + OUT gctINT32 major;
  141332. +
  141333. + /* Minor version: n.N.n. */
  141334. + OUT gctINT32 minor;
  141335. +
  141336. + /* Patch version: n.n.N. */
  141337. + OUT gctINT32 patch;
  141338. +
  141339. + /* Build version. */
  141340. + OUT gctUINT32 build;
  141341. + }
  141342. + Version;
  141343. +
  141344. + /* gcvHAL_CHIP_INFO */
  141345. + struct _gcsHAL_CHIP_INFO
  141346. + {
  141347. + /* Chip count. */
  141348. + OUT gctINT32 count;
  141349. +
  141350. + /* Chip types. */
  141351. + OUT gceHARDWARE_TYPE types[gcdCHIP_COUNT];
  141352. + }
  141353. + ChipInfo;
  141354. +
  141355. + /* gcvHAL_ATTACH */
  141356. + struct _gcsHAL_ATTACH
  141357. + {
  141358. + /* Context buffer object gckCONTEXT. Just a name. */
  141359. + OUT gctUINT32 context;
  141360. +
  141361. + /* Number of states in the buffer. */
  141362. + OUT gctUINT64 stateCount;
  141363. + }
  141364. + Attach;
  141365. +
  141366. + /* gcvHAL_DETACH */
  141367. + struct _gcsHAL_DETACH
  141368. + {
  141369. + /* Context buffer object gckCONTEXT. Just a name. */
  141370. + IN gctUINT32 context;
  141371. + }
  141372. + Detach;
  141373. +
  141374. + /* gcvHAL_COMPOSE. */
  141375. + gcsHAL_COMPOSE Compose;
  141376. +
  141377. + /* gcvHAL_GET_FRAME_INFO. */
  141378. + struct _gcsHAL_GET_FRAME_INFO
  141379. + {
  141380. + /* gcsHAL_FRAME_INFO* */
  141381. + OUT gctUINT64 frameInfo;
  141382. + }
  141383. + GetFrameInfo;
  141384. +
  141385. + /* gcvHAL_SET_TIME_OUT. */
  141386. + struct _gcsHAL_SET_TIMEOUT
  141387. + {
  141388. + gctUINT32 timeOut;
  141389. + }
  141390. + SetTimeOut;
  141391. +
  141392. +#if gcdENABLE_VG
  141393. + /* gcvHAL_COMMIT */
  141394. + struct _gcsHAL_VGCOMMIT
  141395. + {
  141396. + /* Context buffer in gcsVGCONTEXT. */
  141397. + IN gctUINT64 context;
  141398. +
  141399. + /* Command queue in gcsVGCMDQUEUE. */
  141400. + IN gctUINT64 queue;
  141401. +
  141402. + /* Number of entries in the queue. */
  141403. + IN gctUINT entryCount;
  141404. +
  141405. + /* Task table in gcsTASK_MASTER_TABLE. */
  141406. + IN gctUINT64 taskTable;
  141407. + }
  141408. + VGCommit;
  141409. +
  141410. + /* gcvHAL_QUERY_COMMAND_BUFFER */
  141411. + struct _gcsHAL_QUERY_COMMAND_BUFFER
  141412. + {
  141413. + /* Command buffer attributes. */
  141414. + OUT gcsCOMMAND_BUFFER_INFO information;
  141415. + }
  141416. + QueryCommandBuffer;
  141417. +
  141418. +#endif
  141419. +
  141420. + struct _gcsHAL_GET_SHARED_INFO
  141421. + {
  141422. + /* Process id. */
  141423. + IN gctUINT32 pid;
  141424. +
  141425. + /* Data id. */
  141426. + IN gctUINT32 dataId;
  141427. +
  141428. + /* Data size. */
  141429. + IN gctSIZE_T bytes;
  141430. +
  141431. + /* Pointer to save the shared data. */
  141432. + OUT gctPOINTER data;
  141433. + }
  141434. + GetSharedInfo;
  141435. +
  141436. + struct _gcsHAL_SET_SHARED_INFO
  141437. + {
  141438. + /* Data id. */
  141439. + IN gctUINT32 dataId;
  141440. +
  141441. + /* Data to be shared. */
  141442. + IN gctPOINTER data;
  141443. +
  141444. + /* Data size. */
  141445. + IN gctSIZE_T bytes;
  141446. + }
  141447. + SetSharedInfo;
  141448. +
  141449. + struct _gcsHAL_SET_FSCALE_VALUE
  141450. + {
  141451. + IN gctUINT value;
  141452. + }
  141453. + SetFscaleValue;
  141454. +
  141455. + struct _gcsHAL_GET_FSCALE_VALUE
  141456. + {
  141457. + OUT gctUINT value;
  141458. + OUT gctUINT minValue;
  141459. + OUT gctUINT maxValue;
  141460. + }
  141461. + GetFscaleValue;
  141462. +
  141463. + struct _gcsHAL_QUERY_RESET_TIME_STAMP
  141464. + {
  141465. + OUT gctUINT64 timeStamp;
  141466. + }
  141467. + QueryResetTimeStamp;
  141468. +
  141469. + struct _gcsHAL_SYNC_POINT
  141470. + {
  141471. + /* Command. */
  141472. + gceSYNC_POINT_COMMAND_CODES command;
  141473. +
  141474. + /* Sync point. */
  141475. + IN OUT gctUINT64 syncPoint;
  141476. +
  141477. + /* From where. */
  141478. + IN gceKERNEL_WHERE fromWhere;
  141479. +
  141480. + /* Signaled state. */
  141481. + OUT gctBOOL state;
  141482. + }
  141483. + SyncPoint;
  141484. +
  141485. + struct _gcsHAL_CREATE_NATIVE_FENCE
  141486. + {
  141487. + /* Signal id to dup. */
  141488. + IN gctUINT64 syncPoint;
  141489. +
  141490. + /* Native fence file descriptor. */
  141491. + OUT gctINT fenceFD;
  141492. +
  141493. + }
  141494. + CreateNativeFence;
  141495. + }
  141496. + u;
  141497. +}
  141498. +gcsHAL_INTERFACE;
  141499. +
  141500. +
  141501. +#ifdef __cplusplus
  141502. +}
  141503. +#endif
  141504. +
  141505. +#endif /* __gc_hal_driver_h_ */
  141506. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h
  141507. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h 1969-12-31 18:00:00.000000000 -0600
  141508. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h 2014-12-08 00:31:53.468418001 -0600
  141509. @@ -0,0 +1,270 @@
  141510. +/****************************************************************************
  141511. +*
  141512. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  141513. +*
  141514. +* This program is free software; you can redistribute it and/or modify
  141515. +* it under the terms of the GNU General Public License as published by
  141516. +* the Free Software Foundation; either version 2 of the license, or
  141517. +* (at your option) any later version.
  141518. +*
  141519. +* This program is distributed in the hope that it will be useful,
  141520. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  141521. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  141522. +* GNU General Public License for more details.
  141523. +*
  141524. +* You should have received a copy of the GNU General Public License
  141525. +* along with this program; if not write to the Free Software
  141526. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  141527. +*
  141528. +*****************************************************************************/
  141529. +
  141530. +
  141531. +#ifndef __gc_hal_driver_vg_h_
  141532. +#define __gc_hal_driver_vg_h_
  141533. +
  141534. +
  141535. +
  141536. +#include "gc_hal_types.h"
  141537. +
  141538. +#ifdef __cplusplus
  141539. +extern "C" {
  141540. +#endif
  141541. +
  141542. +/******************************************************************************\
  141543. +******************************* I/O Control Codes ******************************
  141544. +\******************************************************************************/
  141545. +
  141546. +#define gcvHAL_CLASS "galcore"
  141547. +#define IOCTL_GCHAL_INTERFACE 30000
  141548. +
  141549. +/******************************************************************************\
  141550. +********************************* Command Codes ********************************
  141551. +\******************************************************************************/
  141552. +
  141553. +/******************************************************************************\
  141554. +********************* Command buffer information structure. ********************
  141555. +\******************************************************************************/
  141556. +
  141557. +typedef struct _gcsCOMMAND_BUFFER_INFO * gcsCOMMAND_BUFFER_INFO_PTR;
  141558. +typedef struct _gcsCOMMAND_BUFFER_INFO
  141559. +{
  141560. + /* FE command buffer interrupt ID. */
  141561. + gctINT32 feBufferInt;
  141562. +
  141563. + /* TS overflow interrupt ID. */
  141564. + gctINT32 tsOverflowInt;
  141565. +
  141566. + /* Alignment and mask for the buffer address. */
  141567. + gctUINT addressMask;
  141568. + gctSIZE_T addressAlignment;
  141569. +
  141570. + /* Alignment for each command. */
  141571. + gctSIZE_T commandAlignment;
  141572. +
  141573. + /* Number of bytes required by the STATE command. */
  141574. + gctSIZE_T stateCommandSize;
  141575. +
  141576. + /* Number of bytes required by the RESTART command. */
  141577. + gctSIZE_T restartCommandSize;
  141578. +
  141579. + /* Number of bytes required by the FETCH command. */
  141580. + gctSIZE_T fetchCommandSize;
  141581. +
  141582. + /* Number of bytes required by the CALL command. */
  141583. + gctSIZE_T callCommandSize;
  141584. +
  141585. + /* Number of bytes required by the RETURN command. */
  141586. + gctSIZE_T returnCommandSize;
  141587. +
  141588. + /* Number of bytes required by the EVENT command. */
  141589. + gctSIZE_T eventCommandSize;
  141590. +
  141591. + /* Number of bytes required by the END command. */
  141592. + gctSIZE_T endCommandSize;
  141593. +
  141594. + /* Number of bytes reserved at the tail of a static command buffer. */
  141595. + gctSIZE_T staticTailSize;
  141596. +
  141597. + /* Number of bytes reserved at the tail of a dynamic command buffer. */
  141598. + gctSIZE_T dynamicTailSize;
  141599. +}
  141600. +gcsCOMMAND_BUFFER_INFO;
  141601. +
  141602. +/******************************************************************************\
  141603. +******************************** Task Structures *******************************
  141604. +\******************************************************************************/
  141605. +
  141606. +typedef enum _gceTASK
  141607. +{
  141608. + gcvTASK_LINK,
  141609. + gcvTASK_CLUSTER,
  141610. + gcvTASK_INCREMENT,
  141611. + gcvTASK_DECREMENT,
  141612. + gcvTASK_SIGNAL,
  141613. + gcvTASK_LOCKDOWN,
  141614. + gcvTASK_UNLOCK_VIDEO_MEMORY,
  141615. + gcvTASK_FREE_VIDEO_MEMORY,
  141616. + gcvTASK_FREE_CONTIGUOUS_MEMORY,
  141617. + gcvTASK_UNMAP_USER_MEMORY
  141618. +}
  141619. +gceTASK;
  141620. +
  141621. +typedef struct _gcsTASK_HEADER * gcsTASK_HEADER_PTR;
  141622. +typedef struct _gcsTASK_HEADER
  141623. +{
  141624. + /* Task ID. */
  141625. + IN gceTASK id;
  141626. +}
  141627. +gcsTASK_HEADER;
  141628. +
  141629. +typedef struct _gcsTASK_LINK * gcsTASK_LINK_PTR;
  141630. +typedef struct _gcsTASK_LINK
  141631. +{
  141632. + /* Task ID (gcvTASK_LINK). */
  141633. + IN gceTASK id;
  141634. +
  141635. + /* Pointer to the next task container. */
  141636. + IN gctPOINTER cotainer;
  141637. +
  141638. + /* Pointer to the next task from the next task container. */
  141639. + IN gcsTASK_HEADER_PTR task;
  141640. +}
  141641. +gcsTASK_LINK;
  141642. +
  141643. +typedef struct _gcsTASK_CLUSTER * gcsTASK_CLUSTER_PTR;
  141644. +typedef struct _gcsTASK_CLUSTER
  141645. +{
  141646. + /* Task ID (gcvTASK_CLUSTER). */
  141647. + IN gceTASK id;
  141648. +
  141649. + /* Number of tasks in the cluster. */
  141650. + IN gctUINT taskCount;
  141651. +}
  141652. +gcsTASK_CLUSTER;
  141653. +
  141654. +typedef struct _gcsTASK_INCREMENT * gcsTASK_INCREMENT_PTR;
  141655. +typedef struct _gcsTASK_INCREMENT
  141656. +{
  141657. + /* Task ID (gcvTASK_INCREMENT). */
  141658. + IN gceTASK id;
  141659. +
  141660. + /* Address of the variable to increment. */
  141661. + IN gctUINT32 address;
  141662. +}
  141663. +gcsTASK_INCREMENT;
  141664. +
  141665. +typedef struct _gcsTASK_DECREMENT * gcsTASK_DECREMENT_PTR;
  141666. +typedef struct _gcsTASK_DECREMENT
  141667. +{
  141668. + /* Task ID (gcvTASK_DECREMENT). */
  141669. + IN gceTASK id;
  141670. +
  141671. + /* Address of the variable to decrement. */
  141672. + IN gctUINT32 address;
  141673. +}
  141674. +gcsTASK_DECREMENT;
  141675. +
  141676. +typedef struct _gcsTASK_SIGNAL * gcsTASK_SIGNAL_PTR;
  141677. +typedef struct _gcsTASK_SIGNAL
  141678. +{
  141679. + /* Task ID (gcvTASK_SIGNAL). */
  141680. + IN gceTASK id;
  141681. +
  141682. + /* Process owning the signal. */
  141683. + IN gctHANDLE process;
  141684. +
  141685. + /* Signal handle to signal. */
  141686. + IN gctSIGNAL signal;
  141687. +
  141688. +#if defined(__QNXNTO__)
  141689. + IN gctINT32 coid;
  141690. + IN gctINT32 rcvid;
  141691. +#endif
  141692. +}
  141693. +gcsTASK_SIGNAL;
  141694. +
  141695. +typedef struct _gcsTASK_LOCKDOWN * gcsTASK_LOCKDOWN_PTR;
  141696. +typedef struct _gcsTASK_LOCKDOWN
  141697. +{
  141698. + /* Task ID (gcvTASK_LOCKDOWN). */
  141699. + IN gceTASK id;
  141700. +
  141701. + /* Address of the user space counter. */
  141702. + IN gctUINT32 userCounter;
  141703. +
  141704. + /* Address of the kernel space counter. */
  141705. + IN gctUINT32 kernelCounter;
  141706. +
  141707. + /* Process owning the signal. */
  141708. + IN gctHANDLE process;
  141709. +
  141710. + /* Signal handle to signal. */
  141711. + IN gctSIGNAL signal;
  141712. +}
  141713. +gcsTASK_LOCKDOWN;
  141714. +
  141715. +typedef struct _gcsTASK_UNLOCK_VIDEO_MEMORY * gcsTASK_UNLOCK_VIDEO_MEMORY_PTR;
  141716. +typedef struct _gcsTASK_UNLOCK_VIDEO_MEMORY
  141717. +{
  141718. + /* Task ID (gcvTASK_UNLOCK_VIDEO_MEMORY). */
  141719. + IN gceTASK id;
  141720. +
  141721. + /* Allocated video memory. */
  141722. + IN gctUINT64 node;
  141723. +}
  141724. +gcsTASK_UNLOCK_VIDEO_MEMORY;
  141725. +
  141726. +typedef struct _gcsTASK_FREE_VIDEO_MEMORY * gcsTASK_FREE_VIDEO_MEMORY_PTR;
  141727. +typedef struct _gcsTASK_FREE_VIDEO_MEMORY
  141728. +{
  141729. + /* Task ID (gcvTASK_FREE_VIDEO_MEMORY). */
  141730. + IN gceTASK id;
  141731. +
  141732. + /* Allocated video memory. */
  141733. + IN gctUINT64 node;
  141734. +}
  141735. +gcsTASK_FREE_VIDEO_MEMORY;
  141736. +
  141737. +typedef struct _gcsTASK_FREE_CONTIGUOUS_MEMORY * gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR;
  141738. +typedef struct _gcsTASK_FREE_CONTIGUOUS_MEMORY
  141739. +{
  141740. + /* Task ID (gcvTASK_FREE_CONTIGUOUS_MEMORY). */
  141741. + IN gceTASK id;
  141742. +
  141743. + /* Number of bytes allocated. */
  141744. + IN gctSIZE_T bytes;
  141745. +
  141746. + /* Physical address of allocation. */
  141747. + IN gctPHYS_ADDR physical;
  141748. +
  141749. + /* Logical address of allocation. */
  141750. + IN gctPOINTER logical;
  141751. +}
  141752. +gcsTASK_FREE_CONTIGUOUS_MEMORY;
  141753. +
  141754. +typedef struct _gcsTASK_UNMAP_USER_MEMORY * gcsTASK_UNMAP_USER_MEMORY_PTR;
  141755. +typedef struct _gcsTASK_UNMAP_USER_MEMORY
  141756. +{
  141757. + /* Task ID (gcvTASK_UNMAP_USER_MEMORY). */
  141758. + IN gceTASK id;
  141759. +
  141760. + /* Base address of user memory to unmap. */
  141761. + IN gctPOINTER memory;
  141762. +
  141763. + /* Size of user memory in bytes to unmap. */
  141764. + IN gctSIZE_T size;
  141765. +
  141766. + /* Info record returned by gcvHAL_MAP_USER_MEMORY. */
  141767. + IN gctPOINTER info;
  141768. +
  141769. + /* Physical address of mapped memory as returned by
  141770. + gcvHAL_MAP_USER_MEMORY. */
  141771. + IN gctUINT32 address;
  141772. +}
  141773. +gcsTASK_UNMAP_USER_MEMORY;
  141774. +
  141775. +#ifdef __cplusplus
  141776. +}
  141777. +#endif
  141778. +
  141779. +#endif /* __gc_hal_driver_h_ */
  141780. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h
  141781. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h 1969-12-31 18:00:00.000000000 -0600
  141782. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h 2014-12-08 00:31:53.468418001 -0600
  141783. @@ -0,0 +1,88 @@
  141784. +/****************************************************************************
  141785. +*
  141786. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  141787. +*
  141788. +* This program is free software; you can redistribute it and/or modify
  141789. +* it under the terms of the GNU General Public License as published by
  141790. +* the Free Software Foundation; either version 2 of the license, or
  141791. +* (at your option) any later version.
  141792. +*
  141793. +* This program is distributed in the hope that it will be useful,
  141794. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  141795. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  141796. +* GNU General Public License for more details.
  141797. +*
  141798. +* You should have received a copy of the GNU General Public License
  141799. +* along with this program; if not write to the Free Software
  141800. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  141801. +*
  141802. +*****************************************************************************/
  141803. +
  141804. +
  141805. +#ifndef __gc_hal_dump_h_
  141806. +#define __gc_hal_dump_h_
  141807. +
  141808. +#ifdef __cplusplus
  141809. +extern "C" {
  141810. +#endif
  141811. +
  141812. +/*
  141813. +** FILE LAYOUT:
  141814. +**
  141815. +** gcsDUMP_FILE structure
  141816. +**
  141817. +** gcsDUMP_DATA frame
  141818. +** gcsDUMP_DATA or gcDUMP_DATA_SIZE records rendingring the frame
  141819. +** gctUINT8 data[length]
  141820. +*/
  141821. +
  141822. +#define gcvDUMP_FILE_SIGNATURE gcmCC('g','c','D','B')
  141823. +
  141824. +typedef struct _gcsDUMP_FILE
  141825. +{
  141826. + gctUINT32 signature; /* File signature */
  141827. + gctSIZE_T length; /* Length of file */
  141828. + gctUINT32 frames; /* Number of frames in file */
  141829. +}
  141830. +gcsDUMP_FILE;
  141831. +
  141832. +typedef enum _gceDUMP_TAG
  141833. +{
  141834. + gcvTAG_SURFACE = gcmCC('s','u','r','f'),
  141835. + gcvTAG_FRAME = gcmCC('f','r','m',' '),
  141836. + gcvTAG_COMMAND = gcmCC('c','m','d',' '),
  141837. + gcvTAG_INDEX = gcmCC('i','n','d','x'),
  141838. + gcvTAG_STREAM = gcmCC('s','t','r','m'),
  141839. + gcvTAG_TEXTURE = gcmCC('t','e','x','t'),
  141840. + gcvTAG_RENDER_TARGET = gcmCC('r','n','d','r'),
  141841. + gcvTAG_DEPTH = gcmCC('z','b','u','f'),
  141842. + gcvTAG_RESOLVE = gcmCC('r','s','l','v'),
  141843. + gcvTAG_DELETE = gcmCC('d','e','l',' '),
  141844. +}
  141845. +gceDUMP_TAG;
  141846. +
  141847. +typedef struct _gcsDUMP_SURFACE
  141848. +{
  141849. + gceDUMP_TAG type; /* Type of record. */
  141850. + gctUINT32 address; /* Address of the surface. */
  141851. + gctINT16 width; /* Width of surface. */
  141852. + gctINT16 height; /* Height of surface. */
  141853. + gceSURF_FORMAT format; /* Surface pixel format. */
  141854. + gctSIZE_T length; /* Number of bytes inside the surface. */
  141855. +}
  141856. +gcsDUMP_SURFACE;
  141857. +
  141858. +typedef struct _gcsDUMP_DATA
  141859. +{
  141860. + gceDUMP_TAG type; /* Type of record. */
  141861. + gctSIZE_T length; /* Number of bytes of data. */
  141862. + gctUINT32 address; /* Address for the data. */
  141863. +}
  141864. +gcsDUMP_DATA;
  141865. +
  141866. +#ifdef __cplusplus
  141867. +}
  141868. +#endif
  141869. +
  141870. +#endif /* __gc_hal_dump_h_ */
  141871. +
  141872. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
  141873. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h 1969-12-31 18:00:00.000000000 -0600
  141874. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h 2014-12-08 00:31:53.468418001 -0600
  141875. @@ -0,0 +1,627 @@
  141876. +/****************************************************************************
  141877. +*
  141878. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  141879. +*
  141880. +* This program is free software; you can redistribute it and/or modify
  141881. +* it under the terms of the GNU General Public License as published by
  141882. +* the Free Software Foundation; either version 2 of the license, or
  141883. +* (at your option) any later version.
  141884. +*
  141885. +* This program is distributed in the hope that it will be useful,
  141886. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  141887. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  141888. +* GNU General Public License for more details.
  141889. +*
  141890. +* You should have received a copy of the GNU General Public License
  141891. +* along with this program; if not write to the Free Software
  141892. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  141893. +*
  141894. +*****************************************************************************/
  141895. +
  141896. +#ifndef __gc_hal_eglplatform_h_
  141897. +#define __gc_hal_eglplatform_h_
  141898. +
  141899. +/* Include VDK types. */
  141900. +#include "gc_hal_types.h"
  141901. +#include "gc_hal_base.h"
  141902. +#include "gc_hal_eglplatform_type.h"
  141903. +#ifdef __cplusplus
  141904. +extern "C" {
  141905. +#endif
  141906. +
  141907. +
  141908. +#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
  141909. +/* Win32 and Windows CE platforms. */
  141910. +#include <windows.h>
  141911. +typedef HDC HALNativeDisplayType;
  141912. +typedef HWND HALNativeWindowType;
  141913. +typedef HBITMAP HALNativePixmapType;
  141914. +
  141915. +typedef struct __BITFIELDINFO{
  141916. + BITMAPINFO bmi;
  141917. + RGBQUAD bmiColors[2];
  141918. +} BITFIELDINFO;
  141919. +
  141920. +#elif defined(LINUX) && defined(EGL_API_DFB) && !defined(__APPLE__)
  141921. +#include <directfb.h>
  141922. +typedef struct _DFBDisplay * HALNativeDisplayType;
  141923. +typedef struct _DFBWindow * HALNativeWindowType;
  141924. +typedef struct _DFBPixmap * HALNativePixmapType;
  141925. +
  141926. +#elif defined(LINUX) && defined(EGL_API_FB) && !defined(__APPLE__)
  141927. +
  141928. +#if defined(EGL_API_WL)
  141929. +/* Wayland platform. */
  141930. +#include "wayland-server.h"
  141931. +#include <wayland-egl.h>
  141932. +
  141933. +#define WL_EGL_NUM_BACKBUFFERS 3
  141934. +
  141935. +typedef struct _gcsWL_VIV_BUFFER
  141936. +{
  141937. + struct wl_resource *wl_buffer;
  141938. + gcoSURF surface;
  141939. + gctINT32 width, height;
  141940. +} gcsWL_VIV_BUFFER;
  141941. +
  141942. +typedef struct _gcsWL_EGL_DISPLAY
  141943. +{
  141944. + struct wl_display* wl_display;
  141945. + struct wl_viv* wl_viv;
  141946. + struct wl_registry *registry;
  141947. + struct wl_event_queue *wl_queue;
  141948. +} gcsWL_EGL_DISPLAY;
  141949. +
  141950. +typedef struct _gcsWL_EGL_BUFFER_INFO
  141951. +{
  141952. + gctINT32 width;
  141953. + gctINT32 height;
  141954. + gctINT32 stride;
  141955. + gceSURF_FORMAT format;
  141956. + gcuVIDMEM_NODE_PTR node;
  141957. + gcePOOL pool;
  141958. + gctUINT bytes;
  141959. + gcoSURF surface;
  141960. + gcoSURF attached_surface;
  141961. + gctINT32 invalidate;
  141962. + gctBOOL locked;
  141963. +} gcsWL_EGL_BUFFER_INFO;
  141964. +
  141965. +typedef struct _gcsWL_EGL_BUFFER
  141966. +{
  141967. + struct wl_buffer* wl_buffer;
  141968. + gcsWL_EGL_BUFFER_INFO info;
  141969. +} gcsWL_EGL_BUFFER;
  141970. +
  141971. +typedef struct _gcsWL_EGL_WINDOW_INFO
  141972. +{
  141973. + gctINT32 dx;
  141974. + gctINT32 dy;
  141975. + gctUINT width;
  141976. + gctUINT height;
  141977. + gctINT32 attached_width;
  141978. + gctINT32 attached_height;
  141979. + gceSURF_FORMAT format;
  141980. + gctUINT bpp;
  141981. +} gcsWL_EGL_WINDOW_INFO;
  141982. +
  141983. +struct wl_egl_window
  141984. +{
  141985. + gcsWL_EGL_DISPLAY* display;
  141986. + gcsWL_EGL_BUFFER backbuffers[WL_EGL_NUM_BACKBUFFERS];
  141987. + gcsWL_EGL_WINDOW_INFO info;
  141988. + gctUINT current;
  141989. + struct wl_surface* surface;
  141990. + struct wl_callback* frame_callback;
  141991. +};
  141992. +
  141993. +typedef void* HALNativeDisplayType;
  141994. +typedef void* HALNativeWindowType;
  141995. +typedef void* HALNativePixmapType;
  141996. +#else
  141997. +/* Linux platform for FBDEV. */
  141998. +typedef struct _FBDisplay * HALNativeDisplayType;
  141999. +typedef struct _FBWindow * HALNativeWindowType;
  142000. +typedef struct _FBPixmap * HALNativePixmapType;
  142001. +#endif
  142002. +#elif defined(__ANDROID__) || defined(ANDROID)
  142003. +
  142004. +struct egl_native_pixmap_t;
  142005. +
  142006. +#if ANDROID_SDK_VERSION >= 9
  142007. + #include <android/native_window.h>
  142008. +
  142009. + typedef struct ANativeWindow* HALNativeWindowType;
  142010. + typedef struct egl_native_pixmap_t* HALNativePixmapType;
  142011. + typedef void* HALNativeDisplayType;
  142012. +#else
  142013. + struct android_native_window_t;
  142014. + typedef struct android_native_window_t* HALNativeWindowType;
  142015. + typedef struct egl_native_pixmap_t * HALNativePixmapType;
  142016. + typedef void* HALNativeDisplayType;
  142017. +#endif
  142018. +
  142019. +#elif defined(LINUX) || defined(__APPLE__)
  142020. +/* X11 platform. */
  142021. +#include <X11/Xlib.h>
  142022. +#include <X11/Xutil.h>
  142023. +
  142024. +typedef Display * HALNativeDisplayType;
  142025. +typedef Window HALNativeWindowType;
  142026. +
  142027. +#ifdef CUSTOM_PIXMAP
  142028. +typedef void * HALNativePixmapType;
  142029. +#else
  142030. +typedef Pixmap HALNativePixmapType;
  142031. +#endif /* CUSTOM_PIXMAP */
  142032. +
  142033. +/* Rename some badly named X defines. */
  142034. +#ifdef Status
  142035. +# define XStatus int
  142036. +# undef Status
  142037. +#endif
  142038. +#ifdef Always
  142039. +# define XAlways 2
  142040. +# undef Always
  142041. +#endif
  142042. +#ifdef CurrentTime
  142043. +# undef CurrentTime
  142044. +# define XCurrentTime 0
  142045. +#endif
  142046. +
  142047. +#elif defined(__QNXNTO__)
  142048. +#include <screen/screen.h>
  142049. +
  142050. +/* VOID */
  142051. +typedef int HALNativeDisplayType;
  142052. +typedef screen_window_t HALNativeWindowType;
  142053. +typedef screen_pixmap_t HALNativePixmapType;
  142054. +
  142055. +#else
  142056. +
  142057. +#error "Platform not recognized"
  142058. +
  142059. +/* VOID */
  142060. +typedef void * HALNativeDisplayType;
  142061. +typedef void * HALNativeWindowType;
  142062. +typedef void * HALNativePixmapType;
  142063. +
  142064. +#endif
  142065. +
  142066. +/* define DUMMY according to the system */
  142067. +#if defined(EGL_API_WL)
  142068. +# define WL_DUMMY (31415926)
  142069. +# define EGL_DUMMY WL_DUMMY
  142070. +#elif defined(__ANDROID__) || defined(ANDROID)
  142071. +# define ANDROID_DUMMY (31415926)
  142072. +# define EGL_DUMMY ANDROID_DUMMY
  142073. +#else
  142074. +# define EGL_DUMMY (31415926)
  142075. +#endif
  142076. +
  142077. +/*******************************************************************************
  142078. +** Display. ********************************************************************
  142079. +*/
  142080. +
  142081. +gceSTATUS
  142082. +gcoOS_GetDisplay(
  142083. + OUT HALNativeDisplayType * Display,
  142084. + IN gctPOINTER Context
  142085. + );
  142086. +
  142087. +gceSTATUS
  142088. +gcoOS_GetDisplayByIndex(
  142089. + IN gctINT DisplayIndex,
  142090. + OUT HALNativeDisplayType * Display,
  142091. + IN gctPOINTER Context
  142092. + );
  142093. +
  142094. +gceSTATUS
  142095. +gcoOS_GetDisplayInfo(
  142096. + IN HALNativeDisplayType Display,
  142097. + OUT gctINT * Width,
  142098. + OUT gctINT * Height,
  142099. + OUT gctSIZE_T * Physical,
  142100. + OUT gctINT * Stride,
  142101. + OUT gctINT * BitsPerPixel
  142102. + );
  142103. +
  142104. +
  142105. +
  142106. +gceSTATUS
  142107. +gcoOS_GetDisplayInfoEx(
  142108. + IN HALNativeDisplayType Display,
  142109. + IN HALNativeWindowType Window,
  142110. + IN gctUINT DisplayInfoSize,
  142111. + OUT halDISPLAY_INFO * DisplayInfo
  142112. + );
  142113. +
  142114. +gceSTATUS
  142115. +gcoOS_GetNextDisplayInfoExByIndex(
  142116. + IN gctINT Index,
  142117. + IN HALNativeDisplayType Display,
  142118. + IN HALNativeWindowType Window,
  142119. + IN gctUINT DisplayInfoSize,
  142120. + OUT halDISPLAY_INFO * DisplayInfo
  142121. + );
  142122. +
  142123. +gceSTATUS
  142124. +gcoOS_GetDisplayVirtual(
  142125. + IN HALNativeDisplayType Display,
  142126. + OUT gctINT * Width,
  142127. + OUT gctINT * Height
  142128. + );
  142129. +
  142130. +gceSTATUS
  142131. +gcoOS_GetDisplayBackbuffer(
  142132. + IN HALNativeDisplayType Display,
  142133. + IN HALNativeWindowType Window,
  142134. + OUT gctPOINTER * context,
  142135. + OUT gcoSURF * surface,
  142136. + OUT gctUINT * Offset,
  142137. + OUT gctINT * X,
  142138. + OUT gctINT * Y
  142139. + );
  142140. +
  142141. +gceSTATUS
  142142. +gcoOS_SetDisplayVirtual(
  142143. + IN HALNativeDisplayType Display,
  142144. + IN HALNativeWindowType Window,
  142145. + IN gctUINT Offset,
  142146. + IN gctINT X,
  142147. + IN gctINT Y
  142148. + );
  142149. +
  142150. +gceSTATUS
  142151. +gcoOS_SetDisplayVirtualEx(
  142152. + IN HALNativeDisplayType Display,
  142153. + IN HALNativeWindowType Window,
  142154. + IN gctPOINTER Context,
  142155. + IN gcoSURF Surface,
  142156. + IN gctUINT Offset,
  142157. + IN gctINT X,
  142158. + IN gctINT Y
  142159. + );
  142160. +
  142161. +gceSTATUS
  142162. +gcoOS_SetSwapInterval(
  142163. + IN HALNativeDisplayType Display,
  142164. + IN gctINT Interval
  142165. +);
  142166. +
  142167. +gceSTATUS
  142168. +gcoOS_GetSwapInterval(
  142169. + IN HALNativeDisplayType Display,
  142170. + IN gctINT_PTR Min,
  142171. + IN gctINT_PTR Max
  142172. +);
  142173. +
  142174. +gceSTATUS
  142175. +gcoOS_DisplayBufferRegions(
  142176. + IN HALNativeDisplayType Display,
  142177. + IN HALNativeWindowType Window,
  142178. + IN gctINT NumRects,
  142179. + IN gctINT_PTR Rects
  142180. + );
  142181. +
  142182. +gceSTATUS
  142183. +gcoOS_DestroyDisplay(
  142184. + IN HALNativeDisplayType Display
  142185. + );
  142186. +
  142187. +gceSTATUS
  142188. +gcoOS_InitLocalDisplayInfo(
  142189. + IN HALNativeDisplayType Display,
  142190. + IN OUT gctPOINTER * localDisplay
  142191. + );
  142192. +
  142193. +gceSTATUS
  142194. +gcoOS_DeinitLocalDisplayInfo(
  142195. + IN HALNativeDisplayType Display,
  142196. + IN OUT gctPOINTER * localDisplay
  142197. + );
  142198. +
  142199. +gceSTATUS
  142200. +gcoOS_GetDisplayInfoEx2(
  142201. + IN HALNativeDisplayType Display,
  142202. + IN HALNativeWindowType Window,
  142203. + IN gctPOINTER localDisplay,
  142204. + IN gctUINT DisplayInfoSize,
  142205. + OUT halDISPLAY_INFO * DisplayInfo
  142206. + );
  142207. +
  142208. +gceSTATUS
  142209. +gcoOS_GetDisplayBackbufferEx(
  142210. + IN HALNativeDisplayType Display,
  142211. + IN HALNativeWindowType Window,
  142212. + IN gctPOINTER localDisplay,
  142213. + OUT gctPOINTER * context,
  142214. + OUT gcoSURF * surface,
  142215. + OUT gctUINT * Offset,
  142216. + OUT gctINT * X,
  142217. + OUT gctINT * Y
  142218. + );
  142219. +
  142220. +gceSTATUS
  142221. +gcoOS_IsValidDisplay(
  142222. + IN HALNativeDisplayType Display
  142223. + );
  142224. +
  142225. +gceSTATUS
  142226. +gcoOS_GetNativeVisualId(
  142227. + IN HALNativeDisplayType Display,
  142228. + OUT gctINT* nativeVisualId
  142229. + );
  142230. +
  142231. +gctBOOL
  142232. +gcoOS_SynchronousFlip(
  142233. + IN HALNativeDisplayType Display
  142234. + );
  142235. +
  142236. +/*******************************************************************************
  142237. +** Windows. ********************************************************************
  142238. +*/
  142239. +
  142240. +gceSTATUS
  142241. +gcoOS_CreateWindow(
  142242. + IN HALNativeDisplayType Display,
  142243. + IN gctINT X,
  142244. + IN gctINT Y,
  142245. + IN gctINT Width,
  142246. + IN gctINT Height,
  142247. + OUT HALNativeWindowType * Window
  142248. + );
  142249. +
  142250. +gceSTATUS
  142251. +gcoOS_GetWindowInfo(
  142252. + IN HALNativeDisplayType Display,
  142253. + IN HALNativeWindowType Window,
  142254. + OUT gctINT * X,
  142255. + OUT gctINT * Y,
  142256. + OUT gctINT * Width,
  142257. + OUT gctINT * Height,
  142258. + OUT gctINT * BitsPerPixel,
  142259. + OUT gctUINT * Offset
  142260. + );
  142261. +
  142262. +gceSTATUS
  142263. +gcoOS_DestroyWindow(
  142264. + IN HALNativeDisplayType Display,
  142265. + IN HALNativeWindowType Window
  142266. + );
  142267. +
  142268. +gceSTATUS
  142269. +gcoOS_DrawImage(
  142270. + IN HALNativeDisplayType Display,
  142271. + IN HALNativeWindowType Window,
  142272. + IN gctINT Left,
  142273. + IN gctINT Top,
  142274. + IN gctINT Right,
  142275. + IN gctINT Bottom,
  142276. + IN gctINT Width,
  142277. + IN gctINT Height,
  142278. + IN gctINT BitsPerPixel,
  142279. + IN gctPOINTER Bits
  142280. + );
  142281. +
  142282. +gceSTATUS
  142283. +gcoOS_GetImage(
  142284. + IN HALNativeWindowType Window,
  142285. + IN gctINT Left,
  142286. + IN gctINT Top,
  142287. + IN gctINT Right,
  142288. + IN gctINT Bottom,
  142289. + OUT gctINT * BitsPerPixel,
  142290. + OUT gctPOINTER * Bits
  142291. + );
  142292. +
  142293. +gceSTATUS
  142294. +gcoOS_GetWindowInfoEx(
  142295. + IN HALNativeDisplayType Display,
  142296. + IN HALNativeWindowType Window,
  142297. + OUT gctINT * X,
  142298. + OUT gctINT * Y,
  142299. + OUT gctINT * Width,
  142300. + OUT gctINT * Height,
  142301. + OUT gctINT * BitsPerPixel,
  142302. + OUT gctUINT * Offset,
  142303. + OUT gceSURF_FORMAT * Format
  142304. + );
  142305. +
  142306. +gceSTATUS
  142307. +gcoOS_DrawImageEx(
  142308. + IN HALNativeDisplayType Display,
  142309. + IN HALNativeWindowType Window,
  142310. + IN gctINT Left,
  142311. + IN gctINT Top,
  142312. + IN gctINT Right,
  142313. + IN gctINT Bottom,
  142314. + IN gctINT Width,
  142315. + IN gctINT Height,
  142316. + IN gctINT BitsPerPixel,
  142317. + IN gctPOINTER Bits,
  142318. + IN gceSURF_FORMAT Format
  142319. + );
  142320. +
  142321. +/*******************************************************************************
  142322. +** Pixmaps. ********************************************************************
  142323. +*/
  142324. +
  142325. +gceSTATUS
  142326. +gcoOS_CreatePixmap(
  142327. + IN HALNativeDisplayType Display,
  142328. + IN gctINT Width,
  142329. + IN gctINT Height,
  142330. + IN gctINT BitsPerPixel,
  142331. + OUT HALNativePixmapType * Pixmap
  142332. + );
  142333. +
  142334. +gceSTATUS
  142335. +gcoOS_GetPixmapInfo(
  142336. + IN HALNativeDisplayType Display,
  142337. + IN HALNativePixmapType Pixmap,
  142338. + OUT gctINT * Width,
  142339. + OUT gctINT * Height,
  142340. + OUT gctINT * BitsPerPixel,
  142341. + OUT gctINT * Stride,
  142342. + OUT gctPOINTER * Bits
  142343. + );
  142344. +
  142345. +gceSTATUS
  142346. +gcoOS_DrawPixmap(
  142347. + IN HALNativeDisplayType Display,
  142348. + IN HALNativePixmapType Pixmap,
  142349. + IN gctINT Left,
  142350. + IN gctINT Top,
  142351. + IN gctINT Right,
  142352. + IN gctINT Bottom,
  142353. + IN gctINT Width,
  142354. + IN gctINT Height,
  142355. + IN gctINT BitsPerPixel,
  142356. + IN gctPOINTER Bits
  142357. + );
  142358. +
  142359. +gceSTATUS
  142360. +gcoOS_DestroyPixmap(
  142361. + IN HALNativeDisplayType Display,
  142362. + IN HALNativePixmapType Pixmap
  142363. + );
  142364. +
  142365. +gceSTATUS
  142366. +gcoOS_GetPixmapInfoEx(
  142367. + IN HALNativeDisplayType Display,
  142368. + IN HALNativePixmapType Pixmap,
  142369. + OUT gctINT * Width,
  142370. + OUT gctINT * Height,
  142371. + OUT gctINT * BitsPerPixel,
  142372. + OUT gctINT * Stride,
  142373. + OUT gctPOINTER * Bits,
  142374. + OUT gceSURF_FORMAT * Format
  142375. + );
  142376. +
  142377. +gceSTATUS
  142378. +gcoOS_CopyPixmapBits(
  142379. + IN HALNativeDisplayType Display,
  142380. + IN HALNativePixmapType Pixmap,
  142381. + IN gctUINT DstWidth,
  142382. + IN gctUINT DstHeight,
  142383. + IN gctINT DstStride,
  142384. + IN gceSURF_FORMAT DstFormat,
  142385. + OUT gctPOINTER DstBits
  142386. + );
  142387. +
  142388. +/*******************************************************************************
  142389. +** OS relative. ****************************************************************
  142390. +*/
  142391. +gceSTATUS
  142392. +gcoOS_LoadEGLLibrary(
  142393. + OUT gctHANDLE * Handle
  142394. + );
  142395. +
  142396. +gceSTATUS
  142397. +gcoOS_FreeEGLLibrary(
  142398. + IN gctHANDLE Handle
  142399. + );
  142400. +
  142401. +gceSTATUS
  142402. +gcoOS_ShowWindow(
  142403. + IN HALNativeDisplayType Display,
  142404. + IN HALNativeWindowType Window
  142405. + );
  142406. +
  142407. +gceSTATUS
  142408. +gcoOS_HideWindow(
  142409. + IN HALNativeDisplayType Display,
  142410. + IN HALNativeWindowType Window
  142411. + );
  142412. +
  142413. +gceSTATUS
  142414. +gcoOS_SetWindowTitle(
  142415. + IN HALNativeDisplayType Display,
  142416. + IN HALNativeWindowType Window,
  142417. + IN gctCONST_STRING Title
  142418. + );
  142419. +
  142420. +gceSTATUS
  142421. +gcoOS_CapturePointer(
  142422. + IN HALNativeDisplayType Display,
  142423. + IN HALNativeWindowType Window
  142424. + );
  142425. +
  142426. +gceSTATUS
  142427. +gcoOS_GetEvent(
  142428. + IN HALNativeDisplayType Display,
  142429. + IN HALNativeWindowType Window,
  142430. + OUT halEvent * Event
  142431. + );
  142432. +
  142433. +gceSTATUS
  142434. +gcoOS_CreateClientBuffer(
  142435. + IN gctINT Width,
  142436. + IN gctINT Height,
  142437. + IN gctINT Format,
  142438. + IN gctINT Type,
  142439. + OUT gctPOINTER * ClientBuffer
  142440. + );
  142441. +
  142442. +gceSTATUS
  142443. +gcoOS_GetClientBufferInfo(
  142444. + IN gctPOINTER ClientBuffer,
  142445. + OUT gctINT * Width,
  142446. + OUT gctINT * Height,
  142447. + OUT gctINT * Stride,
  142448. + OUT gctPOINTER * Bits
  142449. + );
  142450. +
  142451. +gceSTATUS
  142452. +gcoOS_DestroyClientBuffer(
  142453. + IN gctPOINTER ClientBuffer
  142454. + );
  142455. +
  142456. +gceSTATUS
  142457. +gcoOS_DestroyContext(
  142458. + IN gctPOINTER Display,
  142459. + IN gctPOINTER Context
  142460. + );
  142461. +
  142462. +gceSTATUS
  142463. +gcoOS_CreateContext(
  142464. + IN gctPOINTER LocalDisplay,
  142465. + IN gctPOINTER Context
  142466. + );
  142467. +
  142468. +gceSTATUS
  142469. +gcoOS_MakeCurrent(
  142470. + IN gctPOINTER LocalDisplay,
  142471. + IN HALNativeWindowType DrawDrawable,
  142472. + IN HALNativeWindowType ReadDrawable,
  142473. + IN gctPOINTER Context,
  142474. + IN gcoSURF ResolveTarget
  142475. + );
  142476. +
  142477. +gceSTATUS
  142478. +gcoOS_CreateDrawable(
  142479. + IN gctPOINTER LocalDisplay,
  142480. + IN HALNativeWindowType Drawable
  142481. + );
  142482. +
  142483. +gceSTATUS
  142484. +gcoOS_DestroyDrawable(
  142485. + IN gctPOINTER LocalDisplay,
  142486. + IN HALNativeWindowType Drawable
  142487. + );
  142488. +gceSTATUS
  142489. +gcoOS_SwapBuffers(
  142490. + IN gctPOINTER LocalDisplay,
  142491. + IN HALNativeWindowType Drawable,
  142492. + IN gcoSURF RenderTarget,
  142493. + IN gcoSURF ResolveTarget,
  142494. + IN gctPOINTER ResolveBits,
  142495. + OUT gctUINT *Width,
  142496. + OUT gctUINT *Height
  142497. + );
  142498. +#ifdef __cplusplus
  142499. +}
  142500. +#endif
  142501. +
  142502. +#endif /* __gc_hal_eglplatform_h_ */
  142503. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h
  142504. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h 1969-12-31 18:00:00.000000000 -0600
  142505. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h 2014-12-08 00:31:53.468418001 -0600
  142506. @@ -0,0 +1,286 @@
  142507. +/****************************************************************************
  142508. +*
  142509. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  142510. +*
  142511. +* This program is free software; you can redistribute it and/or modify
  142512. +* it under the terms of the GNU General Public License as published by
  142513. +* the Free Software Foundation; either version 2 of the license, or
  142514. +* (at your option) any later version.
  142515. +*
  142516. +* This program is distributed in the hope that it will be useful,
  142517. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  142518. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  142519. +* GNU General Public License for more details.
  142520. +*
  142521. +* You should have received a copy of the GNU General Public License
  142522. +* along with this program; if not write to the Free Software
  142523. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  142524. +*
  142525. +*****************************************************************************/
  142526. +
  142527. +
  142528. +#ifndef __gc_hal_eglplatform_type_h_
  142529. +#define __gc_hal_eglplatform_type_h_
  142530. +
  142531. +#ifdef __cplusplus
  142532. +extern "C" {
  142533. +#endif
  142534. +
  142535. +/*******************************************************************************
  142536. +** Events. *********************************************************************
  142537. +*/
  142538. +
  142539. +typedef enum _halEventType
  142540. +{
  142541. + /* Keyboard event. */
  142542. + HAL_KEYBOARD,
  142543. +
  142544. + /* Mouse move event. */
  142545. + HAL_POINTER,
  142546. +
  142547. + /* Mouse button event. */
  142548. + HAL_BUTTON,
  142549. +
  142550. + /* Application close event. */
  142551. + HAL_CLOSE,
  142552. +
  142553. + /* Application window has been updated. */
  142554. + HAL_WINDOW_UPDATE
  142555. +}
  142556. +halEventType;
  142557. +
  142558. +/* Scancodes for keyboard. */
  142559. +typedef enum _halKeys
  142560. +{
  142561. + HAL_UNKNOWN = -1,
  142562. +
  142563. + HAL_BACKSPACE = 0x08,
  142564. + HAL_TAB,
  142565. + HAL_ENTER = 0x0D,
  142566. + HAL_ESCAPE = 0x1B,
  142567. +
  142568. + HAL_SPACE = 0x20,
  142569. + HAL_SINGLEQUOTE = 0x27,
  142570. + HAL_PAD_ASTERISK = 0x2A,
  142571. + HAL_COMMA = 0x2C,
  142572. + HAL_HYPHEN,
  142573. + HAL_PERIOD,
  142574. + HAL_SLASH,
  142575. + HAL_0,
  142576. + HAL_1,
  142577. + HAL_2,
  142578. + HAL_3,
  142579. + HAL_4,
  142580. + HAL_5,
  142581. + HAL_6,
  142582. + HAL_7,
  142583. + HAL_8,
  142584. + HAL_9,
  142585. + HAL_SEMICOLON = 0x3B,
  142586. + HAL_EQUAL = 0x3D,
  142587. + HAL_A = 0x41,
  142588. + HAL_B,
  142589. + HAL_C,
  142590. + HAL_D,
  142591. + HAL_E,
  142592. + HAL_F,
  142593. + HAL_G,
  142594. + HAL_H,
  142595. + HAL_I,
  142596. + HAL_J,
  142597. + HAL_K,
  142598. + HAL_L,
  142599. + HAL_M,
  142600. + HAL_N,
  142601. + HAL_O,
  142602. + HAL_P,
  142603. + HAL_Q,
  142604. + HAL_R,
  142605. + HAL_S,
  142606. + HAL_T,
  142607. + HAL_U,
  142608. + HAL_V,
  142609. + HAL_W,
  142610. + HAL_X,
  142611. + HAL_Y,
  142612. + HAL_Z,
  142613. + HAL_LBRACKET,
  142614. + HAL_BACKSLASH,
  142615. + HAL_RBRACKET,
  142616. + HAL_BACKQUOTE = 0x60,
  142617. +
  142618. + HAL_F1 = 0x80,
  142619. + HAL_F2,
  142620. + HAL_F3,
  142621. + HAL_F4,
  142622. + HAL_F5,
  142623. + HAL_F6,
  142624. + HAL_F7,
  142625. + HAL_F8,
  142626. + HAL_F9,
  142627. + HAL_F10,
  142628. + HAL_F11,
  142629. + HAL_F12,
  142630. +
  142631. + HAL_LCTRL,
  142632. + HAL_RCTRL,
  142633. + HAL_LSHIFT,
  142634. + HAL_RSHIFT,
  142635. + HAL_LALT,
  142636. + HAL_RALT,
  142637. + HAL_CAPSLOCK,
  142638. + HAL_NUMLOCK,
  142639. + HAL_SCROLLLOCK,
  142640. + HAL_PAD_0,
  142641. + HAL_PAD_1,
  142642. + HAL_PAD_2,
  142643. + HAL_PAD_3,
  142644. + HAL_PAD_4,
  142645. + HAL_PAD_5,
  142646. + HAL_PAD_6,
  142647. + HAL_PAD_7,
  142648. + HAL_PAD_8,
  142649. + HAL_PAD_9,
  142650. + HAL_PAD_HYPHEN,
  142651. + HAL_PAD_PLUS,
  142652. + HAL_PAD_SLASH,
  142653. + HAL_PAD_PERIOD,
  142654. + HAL_PAD_ENTER,
  142655. + HAL_SYSRQ,
  142656. + HAL_PRNTSCRN,
  142657. + HAL_BREAK,
  142658. + HAL_UP,
  142659. + HAL_LEFT,
  142660. + HAL_RIGHT,
  142661. + HAL_DOWN,
  142662. + HAL_HOME,
  142663. + HAL_END,
  142664. + HAL_PGUP,
  142665. + HAL_PGDN,
  142666. + HAL_INSERT,
  142667. + HAL_DELETE,
  142668. + HAL_LWINDOW,
  142669. + HAL_RWINDOW,
  142670. + HAL_MENU,
  142671. + HAL_POWER,
  142672. + HAL_SLEEP,
  142673. + HAL_WAKE
  142674. +}
  142675. +halKeys;
  142676. +
  142677. +/* Structure that defined keyboard mapping. */
  142678. +typedef struct _halKeyMap
  142679. +{
  142680. + /* Normal key. */
  142681. + halKeys normal;
  142682. +
  142683. + /* Extended key. */
  142684. + halKeys extended;
  142685. +}
  142686. +halKeyMap;
  142687. +
  142688. +/* Event structure. */
  142689. +typedef struct _halEvent
  142690. +{
  142691. + /* Event type. */
  142692. + halEventType type;
  142693. +
  142694. + /* Event data union. */
  142695. + union _halEventData
  142696. + {
  142697. + /* Event data for keyboard. */
  142698. + struct _halKeyboard
  142699. + {
  142700. + /* Scancode. */
  142701. + halKeys scancode;
  142702. +
  142703. + /* ASCII characte of the key pressed. */
  142704. + char key;
  142705. +
  142706. + /* Flag whether the key was pressed (1) or released (0). */
  142707. + char pressed;
  142708. + }
  142709. + keyboard;
  142710. +
  142711. + /* Event data for pointer. */
  142712. + struct _halPointer
  142713. + {
  142714. + /* Current pointer coordinate. */
  142715. + int x;
  142716. + int y;
  142717. + }
  142718. + pointer;
  142719. +
  142720. + /* Event data for mouse buttons. */
  142721. + struct _halButton
  142722. + {
  142723. + /* Left button state. */
  142724. + int left;
  142725. +
  142726. + /* Middle button state. */
  142727. + int middle;
  142728. +
  142729. + /* Right button state. */
  142730. + int right;
  142731. +
  142732. + /* Current pointer coordinate. */
  142733. + int x;
  142734. + int y;
  142735. + }
  142736. + button;
  142737. + }
  142738. + data;
  142739. +}
  142740. +halEvent;
  142741. +
  142742. +/* VFK_DISPLAY_INFO structure defining information returned by
  142743. + vdkGetDisplayInfoEx. */
  142744. +typedef struct _halDISPLAY_INFO
  142745. +{
  142746. + /* The size of the display in pixels. */
  142747. + int width;
  142748. + int height;
  142749. +
  142750. + /* The stride of the dispay. -1 is returned if the stride is not known
  142751. + ** for the specified display.*/
  142752. + int stride;
  142753. +
  142754. + /* The color depth of the display in bits per pixel. */
  142755. + int bitsPerPixel;
  142756. +
  142757. + /* The logical pointer to the display memory buffer. NULL is returned
  142758. + ** if the pointer is not known for the specified display. */
  142759. + void * logical;
  142760. +
  142761. + /* The physical address of the display memory buffer. ~0 is returned
  142762. + ** if the address is not known for the specified display. */
  142763. + unsigned long physical;
  142764. +
  142765. + int wrapFB; /* true if compositor, false otherwise. */
  142766. +
  142767. +#ifndef __QNXNTO__
  142768. + /* 355_FB_MULTI_BUFFER */
  142769. + int multiBuffer;
  142770. + int backBufferY;
  142771. +#endif
  142772. +
  142773. + /* The color info of the display. */
  142774. + unsigned int alphaLength;
  142775. + unsigned int alphaOffset;
  142776. + unsigned int redLength;
  142777. + unsigned int redOffset;
  142778. + unsigned int greenLength;
  142779. + unsigned int greenOffset;
  142780. + unsigned int blueLength;
  142781. + unsigned int blueOffset;
  142782. +
  142783. + /* Display flip support. */
  142784. + int flip;
  142785. +}
  142786. +halDISPLAY_INFO;
  142787. +
  142788. +#ifdef __cplusplus
  142789. +}
  142790. +#endif
  142791. +
  142792. +#endif /* __gc_hal_eglplatform_type_h_ */
  142793. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
  142794. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h 1969-12-31 18:00:00.000000000 -0600
  142795. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h 2014-12-08 00:31:53.468418001 -0600
  142796. @@ -0,0 +1,2053 @@
  142797. +/****************************************************************************
  142798. +*
  142799. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  142800. +*
  142801. +* This program is free software; you can redistribute it and/or modify
  142802. +* it under the terms of the GNU General Public License as published by
  142803. +* the Free Software Foundation; either version 2 of the license, or
  142804. +* (at your option) any later version.
  142805. +*
  142806. +* This program is distributed in the hope that it will be useful,
  142807. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  142808. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  142809. +* GNU General Public License for more details.
  142810. +*
  142811. +* You should have received a copy of the GNU General Public License
  142812. +* along with this program; if not write to the Free Software
  142813. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  142814. +*
  142815. +*****************************************************************************/
  142816. +
  142817. +
  142818. +#ifndef __gc_hal_engine_h_
  142819. +#define __gc_hal_engine_h_
  142820. +
  142821. +#ifndef VIVANTE_NO_3D
  142822. +#include "gc_hal_types.h"
  142823. +#include "gc_hal_enum.h"
  142824. +
  142825. +#if gcdENABLE_VG
  142826. +#include "gc_hal_engine_vg.h"
  142827. +#endif
  142828. +
  142829. +#ifdef __cplusplus
  142830. +extern "C" {
  142831. +#endif
  142832. +
  142833. +/******************************************************************************\
  142834. +****************************** Object Declarations *****************************
  142835. +\******************************************************************************/
  142836. +
  142837. +typedef struct _gcoSTREAM * gcoSTREAM;
  142838. +typedef struct _gcoVERTEX * gcoVERTEX;
  142839. +typedef struct _gcoTEXTURE * gcoTEXTURE;
  142840. +typedef struct _gcoINDEX * gcoINDEX;
  142841. +typedef struct _gcsVERTEX_ATTRIBUTES * gcsVERTEX_ATTRIBUTES_PTR;
  142842. +typedef struct _gcoVERTEXARRAY * gcoVERTEXARRAY;
  142843. +
  142844. +#define gcdATTRIBUTE_COUNT 16
  142845. +
  142846. +/******************************************************************************\
  142847. +********************************* Enumerations *********************************
  142848. +\******************************************************************************/
  142849. +
  142850. +/* Shading format. */
  142851. +typedef enum _gceSHADING
  142852. +{
  142853. + gcvSHADING_SMOOTH,
  142854. + gcvSHADING_FLAT_D3D,
  142855. + gcvSHADING_FLAT_OPENGL,
  142856. +}
  142857. +gceSHADING;
  142858. +
  142859. +/* Culling modes. */
  142860. +typedef enum _gceCULL
  142861. +{
  142862. + gcvCULL_NONE,
  142863. + gcvCULL_CCW,
  142864. + gcvCULL_CW,
  142865. +}
  142866. +gceCULL;
  142867. +
  142868. +/* Fill modes. */
  142869. +typedef enum _gceFILL
  142870. +{
  142871. + gcvFILL_POINT,
  142872. + gcvFILL_WIRE_FRAME,
  142873. + gcvFILL_SOLID,
  142874. +}
  142875. +gceFILL;
  142876. +
  142877. +/* Compare modes. */
  142878. +typedef enum _gceCOMPARE
  142879. +{
  142880. + gcvCOMPARE_NEVER,
  142881. + gcvCOMPARE_NOT_EQUAL,
  142882. + gcvCOMPARE_LESS,
  142883. + gcvCOMPARE_LESS_OR_EQUAL,
  142884. + gcvCOMPARE_EQUAL,
  142885. + gcvCOMPARE_GREATER,
  142886. + gcvCOMPARE_GREATER_OR_EQUAL,
  142887. + gcvCOMPARE_ALWAYS,
  142888. + gcvCOMPARE_INVALID = -1
  142889. +}
  142890. +gceCOMPARE;
  142891. +
  142892. +/* Stencil modes. */
  142893. +typedef enum _gceSTENCIL_MODE
  142894. +{
  142895. + gcvSTENCIL_NONE,
  142896. + gcvSTENCIL_SINGLE_SIDED,
  142897. + gcvSTENCIL_DOUBLE_SIDED,
  142898. +}
  142899. +gceSTENCIL_MODE;
  142900. +
  142901. +/* Stencil operations. */
  142902. +typedef enum _gceSTENCIL_OPERATION
  142903. +{
  142904. + gcvSTENCIL_KEEP,
  142905. + gcvSTENCIL_REPLACE,
  142906. + gcvSTENCIL_ZERO,
  142907. + gcvSTENCIL_INVERT,
  142908. + gcvSTENCIL_INCREMENT,
  142909. + gcvSTENCIL_DECREMENT,
  142910. + gcvSTENCIL_INCREMENT_SATURATE,
  142911. + gcvSTENCIL_DECREMENT_SATURATE,
  142912. + gcvSTENCIL_OPERATION_INVALID = -1
  142913. +}
  142914. +gceSTENCIL_OPERATION;
  142915. +
  142916. +/* Stencil selection. */
  142917. +typedef enum _gceSTENCIL_WHERE
  142918. +{
  142919. + gcvSTENCIL_FRONT,
  142920. + gcvSTENCIL_BACK,
  142921. +}
  142922. +gceSTENCIL_WHERE;
  142923. +
  142924. +/* Texture addressing selection. */
  142925. +typedef enum _gceTEXTURE_WHICH
  142926. +{
  142927. + gcvTEXTURE_S,
  142928. + gcvTEXTURE_T,
  142929. + gcvTEXTURE_R,
  142930. +}
  142931. +gceTEXTURE_WHICH;
  142932. +
  142933. +/* Texture addressing modes. */
  142934. +typedef enum _gceTEXTURE_ADDRESSING
  142935. +{
  142936. + gcvTEXTURE_WRAP,
  142937. + gcvTEXTURE_CLAMP,
  142938. + gcvTEXTURE_BORDER,
  142939. + gcvTEXTURE_MIRROR,
  142940. + gcvTEXTURE_MIRROR_ONCE,
  142941. +}
  142942. +gceTEXTURE_ADDRESSING;
  142943. +
  142944. +/* Texture filters. */
  142945. +typedef enum _gceTEXTURE_FILTER
  142946. +{
  142947. + gcvTEXTURE_NONE,
  142948. + gcvTEXTURE_POINT,
  142949. + gcvTEXTURE_LINEAR,
  142950. + gcvTEXTURE_ANISOTROPIC,
  142951. +}
  142952. +gceTEXTURE_FILTER;
  142953. +
  142954. +/* Primitive types. */
  142955. +typedef enum _gcePRIMITIVE
  142956. +{
  142957. + gcvPRIMITIVE_POINT_LIST,
  142958. + gcvPRIMITIVE_LINE_LIST,
  142959. + gcvPRIMITIVE_LINE_STRIP,
  142960. + gcvPRIMITIVE_LINE_LOOP,
  142961. + gcvPRIMITIVE_TRIANGLE_LIST,
  142962. + gcvPRIMITIVE_TRIANGLE_STRIP,
  142963. + gcvPRIMITIVE_TRIANGLE_FAN,
  142964. + gcvPRIMITIVE_RECTANGLE,
  142965. +}
  142966. +gcePRIMITIVE;
  142967. +
  142968. +/* Index types. */
  142969. +typedef enum _gceINDEX_TYPE
  142970. +{
  142971. + gcvINDEX_8,
  142972. + gcvINDEX_16,
  142973. + gcvINDEX_32,
  142974. +}
  142975. +gceINDEX_TYPE;
  142976. +
  142977. +/******************************************************************************\
  142978. +********************************* gcoHAL Object *********************************
  142979. +\******************************************************************************/
  142980. +
  142981. +/* Query the target capabilities. */
  142982. +gceSTATUS
  142983. +gcoHAL_QueryTargetCaps(
  142984. + IN gcoHAL Hal,
  142985. + OUT gctUINT * MaxWidth,
  142986. + OUT gctUINT * MaxHeight,
  142987. + OUT gctUINT * MultiTargetCount,
  142988. + OUT gctUINT * MaxSamples
  142989. + );
  142990. +
  142991. +gceSTATUS
  142992. +gcoHAL_SetDepthOnly(
  142993. + IN gcoHAL Hal,
  142994. + IN gctBOOL Enable
  142995. + );
  142996. +
  142997. +gceSTATUS
  142998. +gcoHAL_QueryShaderCaps(
  142999. + IN gcoHAL Hal,
  143000. + OUT gctUINT * VertexUniforms,
  143001. + OUT gctUINT * FragmentUniforms,
  143002. + OUT gctUINT * Varyings
  143003. + );
  143004. +
  143005. +gceSTATUS
  143006. +gcoHAL_QueryTextureCaps(
  143007. + IN gcoHAL Hal,
  143008. + OUT gctUINT * MaxWidth,
  143009. + OUT gctUINT * MaxHeight,
  143010. + OUT gctUINT * MaxDepth,
  143011. + OUT gctBOOL * Cubic,
  143012. + OUT gctBOOL * NonPowerOfTwo,
  143013. + OUT gctUINT * VertexSamplers,
  143014. + OUT gctUINT * PixelSamplers
  143015. + );
  143016. +
  143017. +gceSTATUS
  143018. +gcoHAL_QueryTextureMaxAniso(
  143019. + IN gcoHAL Hal,
  143020. + OUT gctUINT * MaxAnisoValue
  143021. + );
  143022. +
  143023. +gceSTATUS
  143024. +gcoHAL_QueryStreamCaps(
  143025. + IN gcoHAL Hal,
  143026. + OUT gctUINT32 * MaxAttributes,
  143027. + OUT gctUINT32 * MaxStreamSize,
  143028. + OUT gctUINT32 * NumberOfStreams,
  143029. + OUT gctUINT32 * Alignment
  143030. + );
  143031. +
  143032. +/******************************************************************************\
  143033. +********************************* gcoSURF Object ********************************
  143034. +\******************************************************************************/
  143035. +
  143036. +/*----------------------------------------------------------------------------*/
  143037. +/*--------------------------------- gcoSURF 3D --------------------------------*/
  143038. +
  143039. +/* Copy surface. */
  143040. +gceSTATUS
  143041. +gcoSURF_Copy(
  143042. + IN gcoSURF Surface,
  143043. + IN gcoSURF Source
  143044. + );
  143045. +
  143046. +/* Clear surface. */
  143047. +gceSTATUS
  143048. +gcoSURF_Clear(
  143049. + IN gcoSURF Surface,
  143050. + IN gctUINT Flags
  143051. + );
  143052. +
  143053. +/* Set number of samples for a gcoSURF object. */
  143054. +gceSTATUS
  143055. +gcoSURF_SetSamples(
  143056. + IN gcoSURF Surface,
  143057. + IN gctUINT Samples
  143058. + );
  143059. +
  143060. +/* Get the number of samples per pixel. */
  143061. +gceSTATUS
  143062. +gcoSURF_GetSamples(
  143063. + IN gcoSURF Surface,
  143064. + OUT gctUINT_PTR Samples
  143065. + );
  143066. +
  143067. +/* Clear rectangular surface. */
  143068. +gceSTATUS
  143069. +gcoSURF_ClearRect(
  143070. + IN gcoSURF Surface,
  143071. + IN gctINT Left,
  143072. + IN gctINT Top,
  143073. + IN gctINT Right,
  143074. + IN gctINT Bottom,
  143075. + IN gctUINT Flags
  143076. + );
  143077. +
  143078. +/* TO BE REMOVED */
  143079. + gceSTATUS
  143080. + depr_gcoSURF_Resolve(
  143081. + IN gcoSURF SrcSurface,
  143082. + IN gcoSURF DestSurface,
  143083. + IN gctUINT32 DestAddress,
  143084. + IN gctPOINTER DestBits,
  143085. + IN gctINT DestStride,
  143086. + IN gceSURF_TYPE DestType,
  143087. + IN gceSURF_FORMAT DestFormat,
  143088. + IN gctUINT DestWidth,
  143089. + IN gctUINT DestHeight
  143090. + );
  143091. +
  143092. + gceSTATUS
  143093. + depr_gcoSURF_ResolveRect(
  143094. + IN gcoSURF SrcSurface,
  143095. + IN gcoSURF DestSurface,
  143096. + IN gctUINT32 DestAddress,
  143097. + IN gctPOINTER DestBits,
  143098. + IN gctINT DestStride,
  143099. + IN gceSURF_TYPE DestType,
  143100. + IN gceSURF_FORMAT DestFormat,
  143101. + IN gctUINT DestWidth,
  143102. + IN gctUINT DestHeight,
  143103. + IN gcsPOINT_PTR SrcOrigin,
  143104. + IN gcsPOINT_PTR DestOrigin,
  143105. + IN gcsPOINT_PTR RectSize
  143106. + );
  143107. +
  143108. +/* Resample surface. */
  143109. +gceSTATUS
  143110. +gcoSURF_Resample(
  143111. + IN gcoSURF SrcSurface,
  143112. + IN gcoSURF DestSurface
  143113. + );
  143114. +
  143115. +/* Resolve surface. */
  143116. +gceSTATUS
  143117. +gcoSURF_Resolve(
  143118. + IN gcoSURF SrcSurface,
  143119. + IN gcoSURF DestSurface
  143120. + );
  143121. +
  143122. +gceSTATUS
  143123. +gcoSURF_IsHWResolveable(
  143124. + IN gcoSURF SrcSurface,
  143125. + IN gcoSURF DestSurface,
  143126. + IN gcsPOINT_PTR SrcOrigin,
  143127. + IN gcsPOINT_PTR DestOrigin,
  143128. + IN gcsPOINT_PTR RectSize
  143129. + );
  143130. +
  143131. +/* Resolve rectangular area of a surface. */
  143132. +gceSTATUS
  143133. +gcoSURF_ResolveRect(
  143134. + IN gcoSURF SrcSurface,
  143135. + IN gcoSURF DestSurface,
  143136. + IN gcsPOINT_PTR SrcOrigin,
  143137. + IN gcsPOINT_PTR DestOrigin,
  143138. + IN gcsPOINT_PTR RectSize
  143139. + );
  143140. +
  143141. +/* Set surface resolvability. */
  143142. +gceSTATUS
  143143. +gcoSURF_SetResolvability(
  143144. + IN gcoSURF Surface,
  143145. + IN gctBOOL Resolvable
  143146. + );
  143147. +
  143148. +gceSTATUS
  143149. +gcoSURF_IsRenderable(
  143150. + IN gcoSURF Surface
  143151. + );
  143152. +
  143153. +gceSTATUS
  143154. +gcoSURF_IsFormatRenderableAsRT(
  143155. + IN gcoSURF Surface
  143156. + );
  143157. +
  143158. +#if gcdSYNC
  143159. +gceSTATUS
  143160. +gcoSURF_GetFence(
  143161. + IN gcoSURF Surface
  143162. + );
  143163. +gceSTATUS
  143164. +gcoSURF_WaitFence(
  143165. + IN gcoSURF Surface
  143166. + );
  143167. +
  143168. +gceSTATUS
  143169. +gcoSTREAM_GetFence(
  143170. + IN gcoSTREAM stream
  143171. + );
  143172. +
  143173. +gceSTATUS
  143174. +gcoSTREAM_WaitFence(
  143175. + IN gcoSTREAM stream
  143176. + );
  143177. +
  143178. +gceSTATUS
  143179. +gcoINDEX_GetFence(
  143180. + IN gcoINDEX index
  143181. + );
  143182. +
  143183. +gceSTATUS
  143184. +gcoINDEX_WaitFence(
  143185. + IN gcoINDEX index
  143186. + );
  143187. +#endif
  143188. +
  143189. +/******************************************************************************\
  143190. +******************************** gcoINDEX Object *******************************
  143191. +\******************************************************************************/
  143192. +
  143193. +/* Construct a new gcoINDEX object. */
  143194. +gceSTATUS
  143195. +gcoINDEX_Construct(
  143196. + IN gcoHAL Hal,
  143197. + OUT gcoINDEX * Index
  143198. + );
  143199. +
  143200. +/* Destroy a gcoINDEX object. */
  143201. +gceSTATUS
  143202. +gcoINDEX_Destroy(
  143203. + IN gcoINDEX Index
  143204. + );
  143205. +
  143206. +/* Lock index in memory. */
  143207. +gceSTATUS
  143208. +gcoINDEX_Lock(
  143209. + IN gcoINDEX Index,
  143210. + OUT gctUINT32 * Address,
  143211. + OUT gctPOINTER * Memory
  143212. + );
  143213. +
  143214. +/* Unlock index that was previously locked with gcoINDEX_Lock. */
  143215. +gceSTATUS
  143216. +gcoINDEX_Unlock(
  143217. + IN gcoINDEX Index
  143218. + );
  143219. +
  143220. +/* Upload index data into the memory. */
  143221. +gceSTATUS
  143222. +gcoINDEX_Load(
  143223. + IN gcoINDEX Index,
  143224. + IN gceINDEX_TYPE IndexType,
  143225. + IN gctUINT32 IndexCount,
  143226. + IN gctPOINTER IndexBuffer
  143227. + );
  143228. +
  143229. +/* Bind an index object to the hardware. */
  143230. +gceSTATUS
  143231. +gcoINDEX_Bind(
  143232. + IN gcoINDEX Index,
  143233. + IN gceINDEX_TYPE Type
  143234. + );
  143235. +
  143236. +/* Bind an index object to the hardware. */
  143237. +gceSTATUS
  143238. +gcoINDEX_BindOffset(
  143239. + IN gcoINDEX Index,
  143240. + IN gceINDEX_TYPE Type,
  143241. + IN gctUINT32 Offset
  143242. + );
  143243. +
  143244. +/* Free existing index buffer. */
  143245. +gceSTATUS
  143246. +gcoINDEX_Free(
  143247. + IN gcoINDEX Index
  143248. + );
  143249. +
  143250. +/* Upload data into an index buffer. */
  143251. +gceSTATUS
  143252. +gcoINDEX_Upload(
  143253. + IN gcoINDEX Index,
  143254. + IN gctCONST_POINTER Buffer,
  143255. + IN gctSIZE_T Bytes
  143256. + );
  143257. +
  143258. +/* Upload data into an index buffer starting at an offset. */
  143259. +gceSTATUS
  143260. +gcoINDEX_UploadOffset(
  143261. + IN gcoINDEX Index,
  143262. + IN gctUINT32 Offset,
  143263. + IN gctCONST_POINTER Buffer,
  143264. + IN gctSIZE_T Bytes
  143265. + );
  143266. +
  143267. +/*Merge index2 to index1 from 0, index2 must subset of inex1*/
  143268. +gceSTATUS
  143269. +gcoINDEX_Merge(
  143270. + IN gcoINDEX Index1,
  143271. + IN gcoINDEX Index2
  143272. + );
  143273. +
  143274. +/*check if index buffer is enough for this draw*/
  143275. +gctBOOL
  143276. +gcoINDEX_CheckRange(
  143277. + IN gcoINDEX Index,
  143278. + IN gceINDEX_TYPE Type,
  143279. + IN gctINT Count,
  143280. + IN gctUINT32 Indices
  143281. + );
  143282. +
  143283. +/* Query the index capabilities. */
  143284. +gceSTATUS
  143285. +gcoINDEX_QueryCaps(
  143286. + OUT gctBOOL * Index8,
  143287. + OUT gctBOOL * Index16,
  143288. + OUT gctBOOL * Index32,
  143289. + OUT gctUINT * MaxIndex
  143290. + );
  143291. +
  143292. +/* Determine the index range in the current index buffer. */
  143293. +gceSTATUS
  143294. +gcoINDEX_GetIndexRange(
  143295. + IN gcoINDEX Index,
  143296. + IN gceINDEX_TYPE Type,
  143297. + IN gctUINT32 Offset,
  143298. + IN gctUINT32 Count,
  143299. + OUT gctUINT32 * MinimumIndex,
  143300. + OUT gctUINT32 * MaximumIndex
  143301. + );
  143302. +
  143303. +/* Dynamic buffer management. */
  143304. +gceSTATUS
  143305. +gcoINDEX_SetDynamic(
  143306. + IN gcoINDEX Index,
  143307. + IN gctSIZE_T Bytes,
  143308. + IN gctUINT Buffers
  143309. + );
  143310. +
  143311. +gceSTATUS
  143312. +gcoINDEX_UploadDynamic(
  143313. + IN gcoINDEX Index,
  143314. + IN gctCONST_POINTER Data,
  143315. + IN gctSIZE_T Bytes
  143316. + );
  143317. +
  143318. +/******************************************************************************\
  143319. +********************************** gco3D Object *********************************
  143320. +\******************************************************************************/
  143321. +
  143322. +/* Clear flags. */
  143323. +typedef enum _gceCLEAR
  143324. +{
  143325. + gcvCLEAR_COLOR = 0x1,
  143326. + gcvCLEAR_DEPTH = 0x2,
  143327. + gcvCLEAR_STENCIL = 0x4,
  143328. + gcvCLEAR_HZ = 0x8,
  143329. + gcvCLEAR_HAS_VAA = 0x10,
  143330. +}
  143331. +gceCLEAR;
  143332. +
  143333. +/* Blending targets. */
  143334. +typedef enum _gceBLEND_UNIT
  143335. +{
  143336. + gcvBLEND_SOURCE,
  143337. + gcvBLEND_TARGET,
  143338. +}
  143339. +gceBLEND_UNIT;
  143340. +
  143341. +/* Construct a new gco3D object. */
  143342. +gceSTATUS
  143343. +gco3D_Construct(
  143344. + IN gcoHAL Hal,
  143345. + OUT gco3D * Engine
  143346. + );
  143347. +
  143348. +/* Destroy an gco3D object. */
  143349. +gceSTATUS
  143350. +gco3D_Destroy(
  143351. + IN gco3D Engine
  143352. + );
  143353. +
  143354. +/* Set 3D API type. */
  143355. +gceSTATUS
  143356. +gco3D_SetAPI(
  143357. + IN gco3D Engine,
  143358. + IN gceAPI ApiType
  143359. + );
  143360. +
  143361. +/* Set render target. */
  143362. +gceSTATUS
  143363. +gco3D_SetTarget(
  143364. + IN gco3D Engine,
  143365. + IN gcoSURF Surface
  143366. + );
  143367. +
  143368. +/* Unset render target. */
  143369. +gceSTATUS
  143370. +gco3D_UnsetTarget(
  143371. + IN gco3D Engine,
  143372. + IN gcoSURF Surface
  143373. + );
  143374. +
  143375. +/* Set depth buffer. */
  143376. +gceSTATUS
  143377. +gco3D_SetDepth(
  143378. + IN gco3D Engine,
  143379. + IN gcoSURF Surface
  143380. + );
  143381. +
  143382. +/* Unset depth buffer. */
  143383. +gceSTATUS
  143384. +gco3D_UnsetDepth(
  143385. + IN gco3D Engine,
  143386. + IN gcoSURF Surface
  143387. + );
  143388. +
  143389. +/* Set viewport. */
  143390. +gceSTATUS
  143391. +gco3D_SetViewport(
  143392. + IN gco3D Engine,
  143393. + IN gctINT32 Left,
  143394. + IN gctINT32 Top,
  143395. + IN gctINT32 Right,
  143396. + IN gctINT32 Bottom
  143397. + );
  143398. +
  143399. +/* Set scissors. */
  143400. +gceSTATUS
  143401. +gco3D_SetScissors(
  143402. + IN gco3D Engine,
  143403. + IN gctINT32 Left,
  143404. + IN gctINT32 Top,
  143405. + IN gctINT32 Right,
  143406. + IN gctINT32 Bottom
  143407. + );
  143408. +
  143409. +/* Set clear color. */
  143410. +gceSTATUS
  143411. +gco3D_SetClearColor(
  143412. + IN gco3D Engine,
  143413. + IN gctUINT8 Red,
  143414. + IN gctUINT8 Green,
  143415. + IN gctUINT8 Blue,
  143416. + IN gctUINT8 Alpha
  143417. + );
  143418. +
  143419. +/* Set fixed point clear color. */
  143420. +gceSTATUS
  143421. +gco3D_SetClearColorX(
  143422. + IN gco3D Engine,
  143423. + IN gctFIXED_POINT Red,
  143424. + IN gctFIXED_POINT Green,
  143425. + IN gctFIXED_POINT Blue,
  143426. + IN gctFIXED_POINT Alpha
  143427. + );
  143428. +
  143429. +/* Set floating point clear color. */
  143430. +gceSTATUS
  143431. +gco3D_SetClearColorF(
  143432. + IN gco3D Engine,
  143433. + IN gctFLOAT Red,
  143434. + IN gctFLOAT Green,
  143435. + IN gctFLOAT Blue,
  143436. + IN gctFLOAT Alpha
  143437. + );
  143438. +
  143439. +/* Set fixed point clear depth. */
  143440. +gceSTATUS
  143441. +gco3D_SetClearDepthX(
  143442. + IN gco3D Engine,
  143443. + IN gctFIXED_POINT Depth
  143444. + );
  143445. +
  143446. +/* Set floating point clear depth. */
  143447. +gceSTATUS
  143448. +gco3D_SetClearDepthF(
  143449. + IN gco3D Engine,
  143450. + IN gctFLOAT Depth
  143451. + );
  143452. +
  143453. +/* Set clear stencil. */
  143454. +gceSTATUS
  143455. +gco3D_SetClearStencil(
  143456. + IN gco3D Engine,
  143457. + IN gctUINT32 Stencil
  143458. + );
  143459. +
  143460. +/* Clear a Rect sub-surface. */
  143461. +gceSTATUS
  143462. +gco3D_ClearRect(
  143463. + IN gco3D Engine,
  143464. + IN gctUINT32 Address,
  143465. + IN gctPOINTER Memory,
  143466. + IN gctUINT32 Stride,
  143467. + IN gceSURF_FORMAT Format,
  143468. + IN gctINT32 Left,
  143469. + IN gctINT32 Top,
  143470. + IN gctINT32 Right,
  143471. + IN gctINT32 Bottom,
  143472. + IN gctUINT32 Width,
  143473. + IN gctUINT32 Height,
  143474. + IN gctUINT32 Flags
  143475. + );
  143476. +
  143477. +/* Clear surface. */
  143478. +gceSTATUS
  143479. +gco3D_Clear(
  143480. + IN gco3D Engine,
  143481. + IN gctUINT32 Address,
  143482. + IN gctUINT32 Stride,
  143483. + IN gceSURF_FORMAT Format,
  143484. + IN gctUINT32 Width,
  143485. + IN gctUINT32 Height,
  143486. + IN gctUINT32 Flags
  143487. + );
  143488. +
  143489. +
  143490. +/* Clear tile status. */
  143491. +gceSTATUS
  143492. +gco3D_ClearTileStatus(
  143493. + IN gco3D Engine,
  143494. + IN gcsSURF_INFO_PTR Surface,
  143495. + IN gctUINT32 TileStatusAddress,
  143496. + IN gctUINT32 Flags
  143497. + );
  143498. +
  143499. +/* Set shading mode. */
  143500. +gceSTATUS
  143501. +gco3D_SetShading(
  143502. + IN gco3D Engine,
  143503. + IN gceSHADING Shading
  143504. + );
  143505. +
  143506. +/* Set blending mode. */
  143507. +gceSTATUS
  143508. +gco3D_EnableBlending(
  143509. + IN gco3D Engine,
  143510. + IN gctBOOL Enable
  143511. + );
  143512. +
  143513. +/* Set blending function. */
  143514. +gceSTATUS
  143515. +gco3D_SetBlendFunction(
  143516. + IN gco3D Engine,
  143517. + IN gceBLEND_UNIT Unit,
  143518. + IN gceBLEND_FUNCTION FunctionRGB,
  143519. + IN gceBLEND_FUNCTION FunctionAlpha
  143520. + );
  143521. +
  143522. +/* Set blending mode. */
  143523. +gceSTATUS
  143524. +gco3D_SetBlendMode(
  143525. + IN gco3D Engine,
  143526. + IN gceBLEND_MODE ModeRGB,
  143527. + IN gceBLEND_MODE ModeAlpha
  143528. + );
  143529. +
  143530. +/* Set blending color. */
  143531. +gceSTATUS
  143532. +gco3D_SetBlendColor(
  143533. + IN gco3D Engine,
  143534. + IN gctUINT Red,
  143535. + IN gctUINT Green,
  143536. + IN gctUINT Blue,
  143537. + IN gctUINT Alpha
  143538. + );
  143539. +
  143540. +/* Set fixed point blending color. */
  143541. +gceSTATUS
  143542. +gco3D_SetBlendColorX(
  143543. + IN gco3D Engine,
  143544. + IN gctFIXED_POINT Red,
  143545. + IN gctFIXED_POINT Green,
  143546. + IN gctFIXED_POINT Blue,
  143547. + IN gctFIXED_POINT Alpha
  143548. + );
  143549. +
  143550. +/* Set floating point blending color. */
  143551. +gceSTATUS
  143552. +gco3D_SetBlendColorF(
  143553. + IN gco3D Engine,
  143554. + IN gctFLOAT Red,
  143555. + IN gctFLOAT Green,
  143556. + IN gctFLOAT Blue,
  143557. + IN gctFLOAT Alpha
  143558. + );
  143559. +
  143560. +/* Set culling mode. */
  143561. +gceSTATUS
  143562. +gco3D_SetCulling(
  143563. + IN gco3D Engine,
  143564. + IN gceCULL Mode
  143565. + );
  143566. +
  143567. +/* Enable point size */
  143568. +gceSTATUS
  143569. +gco3D_SetPointSizeEnable(
  143570. + IN gco3D Engine,
  143571. + IN gctBOOL Enable
  143572. + );
  143573. +
  143574. +/* Set point sprite */
  143575. +gceSTATUS
  143576. +gco3D_SetPointSprite(
  143577. + IN gco3D Engine,
  143578. + IN gctBOOL Enable
  143579. + );
  143580. +
  143581. +/* Set fill mode. */
  143582. +gceSTATUS
  143583. +gco3D_SetFill(
  143584. + IN gco3D Engine,
  143585. + IN gceFILL Mode
  143586. + );
  143587. +
  143588. +/* Set depth compare mode. */
  143589. +gceSTATUS
  143590. +gco3D_SetDepthCompare(
  143591. + IN gco3D Engine,
  143592. + IN gceCOMPARE Compare
  143593. + );
  143594. +
  143595. +/* Enable depth writing. */
  143596. +gceSTATUS
  143597. +gco3D_EnableDepthWrite(
  143598. + IN gco3D Engine,
  143599. + IN gctBOOL Enable
  143600. + );
  143601. +
  143602. +/* Set depth mode. */
  143603. +gceSTATUS
  143604. +gco3D_SetDepthMode(
  143605. + IN gco3D Engine,
  143606. + IN gceDEPTH_MODE Mode
  143607. + );
  143608. +
  143609. +/* Set depth range. */
  143610. +gceSTATUS
  143611. +gco3D_SetDepthRangeX(
  143612. + IN gco3D Engine,
  143613. + IN gceDEPTH_MODE Mode,
  143614. + IN gctFIXED_POINT Near,
  143615. + IN gctFIXED_POINT Far
  143616. + );
  143617. +
  143618. +/* Set depth range. */
  143619. +gceSTATUS
  143620. +gco3D_SetDepthRangeF(
  143621. + IN gco3D Engine,
  143622. + IN gceDEPTH_MODE Mode,
  143623. + IN gctFLOAT Near,
  143624. + IN gctFLOAT Far
  143625. + );
  143626. +
  143627. +/* Set last pixel enable */
  143628. +gceSTATUS
  143629. +gco3D_SetLastPixelEnable(
  143630. + IN gco3D Engine,
  143631. + IN gctBOOL Enable
  143632. + );
  143633. +
  143634. +/* Set depth Bias and Scale */
  143635. +gceSTATUS
  143636. +gco3D_SetDepthScaleBiasX(
  143637. + IN gco3D Engine,
  143638. + IN gctFIXED_POINT DepthScale,
  143639. + IN gctFIXED_POINT DepthBias
  143640. + );
  143641. +
  143642. +gceSTATUS
  143643. +gco3D_SetDepthScaleBiasF(
  143644. + IN gco3D Engine,
  143645. + IN gctFLOAT DepthScale,
  143646. + IN gctFLOAT DepthBias
  143647. + );
  143648. +
  143649. +/* Set depth near and far clipping plane. */
  143650. +gceSTATUS
  143651. +gco3D_SetDepthPlaneF(
  143652. + IN gco3D Engine,
  143653. + IN gctFLOAT Near,
  143654. + IN gctFLOAT Far
  143655. + );
  143656. +
  143657. +/* Enable or disable dithering. */
  143658. +gceSTATUS
  143659. +gco3D_EnableDither(
  143660. + IN gco3D Engine,
  143661. + IN gctBOOL Enable
  143662. + );
  143663. +
  143664. +/* Set color write enable bits. */
  143665. +gceSTATUS
  143666. +gco3D_SetColorWrite(
  143667. + IN gco3D Engine,
  143668. + IN gctUINT8 Enable
  143669. + );
  143670. +
  143671. +/* Enable or disable early depth. */
  143672. +gceSTATUS
  143673. +gco3D_SetEarlyDepth(
  143674. + IN gco3D Engine,
  143675. + IN gctBOOL Enable
  143676. + );
  143677. +
  143678. +/* Enable or disable all early depth operations. */
  143679. +gceSTATUS
  143680. +gco3D_SetAllEarlyDepthModes(
  143681. + IN gco3D Engine,
  143682. + IN gctBOOL Disable
  143683. + );
  143684. +
  143685. +/* Switch dynamic early mode */
  143686. +gceSTATUS
  143687. +gco3D_SwitchDynamicEarlyDepthMode(
  143688. + IN gco3D Engine
  143689. + );
  143690. +
  143691. +/* Set dynamic early mode */
  143692. +gceSTATUS
  143693. +gco3D_DisableDynamicEarlyDepthMode(
  143694. + IN gco3D Engine,
  143695. + IN gctBOOL Disable
  143696. + );
  143697. +
  143698. +/* Enable or disable depth-only mode. */
  143699. +gceSTATUS
  143700. +gco3D_SetDepthOnly(
  143701. + IN gco3D Engine,
  143702. + IN gctBOOL Enable
  143703. + );
  143704. +
  143705. +typedef struct _gcsSTENCIL_INFO * gcsSTENCIL_INFO_PTR;
  143706. +typedef struct _gcsSTENCIL_INFO
  143707. +{
  143708. + gceSTENCIL_MODE mode;
  143709. +
  143710. + gctUINT8 maskFront;
  143711. + gctUINT8 maskBack;
  143712. + gctUINT8 writeMaskFront;
  143713. + gctUINT8 writeMaskBack;
  143714. +
  143715. + gctUINT8 referenceFront;
  143716. +
  143717. + gceCOMPARE compareFront;
  143718. + gceSTENCIL_OPERATION passFront;
  143719. + gceSTENCIL_OPERATION failFront;
  143720. + gceSTENCIL_OPERATION depthFailFront;
  143721. +
  143722. + gctUINT8 referenceBack;
  143723. + gceCOMPARE compareBack;
  143724. + gceSTENCIL_OPERATION passBack;
  143725. + gceSTENCIL_OPERATION failBack;
  143726. + gceSTENCIL_OPERATION depthFailBack;
  143727. +}
  143728. +gcsSTENCIL_INFO;
  143729. +
  143730. +/* Set stencil mode. */
  143731. +gceSTATUS
  143732. +gco3D_SetStencilMode(
  143733. + IN gco3D Engine,
  143734. + IN gceSTENCIL_MODE Mode
  143735. + );
  143736. +
  143737. +/* Set stencil mask. */
  143738. +gceSTATUS
  143739. +gco3D_SetStencilMask(
  143740. + IN gco3D Engine,
  143741. + IN gctUINT8 Mask
  143742. + );
  143743. +
  143744. +/* Set stencil back mask. */
  143745. +gceSTATUS
  143746. +gco3D_SetStencilMaskBack(
  143747. + IN gco3D Engine,
  143748. + IN gctUINT8 Mask
  143749. + );
  143750. +
  143751. +/* Set stencil write mask. */
  143752. +gceSTATUS
  143753. +gco3D_SetStencilWriteMask(
  143754. + IN gco3D Engine,
  143755. + IN gctUINT8 Mask
  143756. + );
  143757. +
  143758. +/* Set stencil back write mask. */
  143759. +gceSTATUS
  143760. +gco3D_SetStencilWriteMaskBack(
  143761. + IN gco3D Engine,
  143762. + IN gctUINT8 Mask
  143763. + );
  143764. +
  143765. +/* Set stencil reference. */
  143766. +gceSTATUS
  143767. +gco3D_SetStencilReference(
  143768. + IN gco3D Engine,
  143769. + IN gctUINT8 Reference,
  143770. + IN gctBOOL Front
  143771. + );
  143772. +
  143773. +/* Set stencil compare. */
  143774. +gceSTATUS
  143775. +gco3D_SetStencilCompare(
  143776. + IN gco3D Engine,
  143777. + IN gceSTENCIL_WHERE Where,
  143778. + IN gceCOMPARE Compare
  143779. + );
  143780. +
  143781. +/* Set stencil operation on pass. */
  143782. +gceSTATUS
  143783. +gco3D_SetStencilPass(
  143784. + IN gco3D Engine,
  143785. + IN gceSTENCIL_WHERE Where,
  143786. + IN gceSTENCIL_OPERATION Operation
  143787. + );
  143788. +
  143789. +/* Set stencil operation on fail. */
  143790. +gceSTATUS
  143791. +gco3D_SetStencilFail(
  143792. + IN gco3D Engine,
  143793. + IN gceSTENCIL_WHERE Where,
  143794. + IN gceSTENCIL_OPERATION Operation
  143795. + );
  143796. +
  143797. +/* Set stencil operation on depth fail. */
  143798. +gceSTATUS
  143799. +gco3D_SetStencilDepthFail(
  143800. + IN gco3D Engine,
  143801. + IN gceSTENCIL_WHERE Where,
  143802. + IN gceSTENCIL_OPERATION Operation
  143803. + );
  143804. +
  143805. +/* Set all stencil states in one blow. */
  143806. +gceSTATUS
  143807. +gco3D_SetStencilAll(
  143808. + IN gco3D Engine,
  143809. + IN gcsSTENCIL_INFO_PTR Info
  143810. + );
  143811. +
  143812. +typedef struct _gcsALPHA_INFO * gcsALPHA_INFO_PTR;
  143813. +typedef struct _gcsALPHA_INFO
  143814. +{
  143815. + /* Alpha test states. */
  143816. + gctBOOL test;
  143817. + gceCOMPARE compare;
  143818. + gctUINT8 reference;
  143819. + gctFLOAT floatReference;
  143820. +
  143821. + /* Alpha blending states. */
  143822. + gctBOOL blend;
  143823. +
  143824. + gceBLEND_FUNCTION srcFuncColor;
  143825. + gceBLEND_FUNCTION srcFuncAlpha;
  143826. + gceBLEND_FUNCTION trgFuncColor;
  143827. + gceBLEND_FUNCTION trgFuncAlpha;
  143828. +
  143829. + gceBLEND_MODE modeColor;
  143830. + gceBLEND_MODE modeAlpha;
  143831. +
  143832. + gctUINT32 color;
  143833. +}
  143834. +gcsALPHA_INFO;
  143835. +
  143836. +/* Enable or disable alpha test. */
  143837. +gceSTATUS
  143838. +gco3D_SetAlphaTest(
  143839. + IN gco3D Engine,
  143840. + IN gctBOOL Enable
  143841. + );
  143842. +
  143843. +/* Set alpha test compare. */
  143844. +gceSTATUS
  143845. +gco3D_SetAlphaCompare(
  143846. + IN gco3D Engine,
  143847. + IN gceCOMPARE Compare
  143848. + );
  143849. +
  143850. +/* Set alpha test reference in unsigned integer. */
  143851. +gceSTATUS
  143852. +gco3D_SetAlphaReference(
  143853. + IN gco3D Engine,
  143854. + IN gctUINT8 Reference,
  143855. + IN gctFLOAT FloatReference
  143856. + );
  143857. +
  143858. +/* Set alpha test reference in fixed point. */
  143859. +gceSTATUS
  143860. +gco3D_SetAlphaReferenceX(
  143861. + IN gco3D Engine,
  143862. + IN gctFIXED_POINT Reference
  143863. + );
  143864. +
  143865. +/* Set alpha test reference in floating point. */
  143866. +gceSTATUS
  143867. +gco3D_SetAlphaReferenceF(
  143868. + IN gco3D Engine,
  143869. + IN gctFLOAT Reference
  143870. + );
  143871. +
  143872. +/* Enable/Disable anti-alias line. */
  143873. +gceSTATUS
  143874. +gco3D_SetAntiAliasLine(
  143875. + IN gco3D Engine,
  143876. + IN gctBOOL Enable
  143877. + );
  143878. +
  143879. +/* Set texture slot for anti-alias line. */
  143880. +gceSTATUS
  143881. +gco3D_SetAALineTexSlot(
  143882. + IN gco3D Engine,
  143883. + IN gctUINT TexSlot
  143884. + );
  143885. +
  143886. +/* Set anti-alias line width scale. */
  143887. +gceSTATUS
  143888. +gco3D_SetAALineWidth(
  143889. + IN gco3D Engine,
  143890. + IN gctFLOAT Width
  143891. + );
  143892. +
  143893. +/* Draw a number of primitives. */
  143894. +gceSTATUS
  143895. +gco3D_DrawPrimitives(
  143896. + IN gco3D Engine,
  143897. + IN gcePRIMITIVE Type,
  143898. + IN gctINT StartVertex,
  143899. + IN gctSIZE_T PrimitiveCount
  143900. + );
  143901. +
  143902. +gceSTATUS
  143903. +gco3D_DrawPrimitivesCount(
  143904. + IN gco3D Engine,
  143905. + IN gcePRIMITIVE Type,
  143906. + IN gctINT* StartVertex,
  143907. + IN gctSIZE_T* VertexCount,
  143908. + IN gctSIZE_T PrimitiveCount
  143909. + );
  143910. +
  143911. +
  143912. +/* Draw a number of primitives using offsets. */
  143913. +gceSTATUS
  143914. +gco3D_DrawPrimitivesOffset(
  143915. + IN gco3D Engine,
  143916. + IN gcePRIMITIVE Type,
  143917. + IN gctINT32 StartOffset,
  143918. + IN gctSIZE_T PrimitiveCount
  143919. + );
  143920. +
  143921. +/* Draw a number of indexed primitives. */
  143922. +gceSTATUS
  143923. +gco3D_DrawIndexedPrimitives(
  143924. + IN gco3D Engine,
  143925. + IN gcePRIMITIVE Type,
  143926. + IN gctINT BaseVertex,
  143927. + IN gctINT StartIndex,
  143928. + IN gctSIZE_T PrimitiveCount
  143929. + );
  143930. +
  143931. +/* Draw a number of indexed primitives using offsets. */
  143932. +gceSTATUS
  143933. +gco3D_DrawIndexedPrimitivesOffset(
  143934. + IN gco3D Engine,
  143935. + IN gcePRIMITIVE Type,
  143936. + IN gctINT32 BaseOffset,
  143937. + IN gctINT32 StartOffset,
  143938. + IN gctSIZE_T PrimitiveCount
  143939. + );
  143940. +
  143941. +/* Enable or disable anti-aliasing. */
  143942. +gceSTATUS
  143943. +gco3D_SetAntiAlias(
  143944. + IN gco3D Engine,
  143945. + IN gctBOOL Enable
  143946. + );
  143947. +
  143948. +/* Write data into the command buffer. */
  143949. +gceSTATUS
  143950. +gco3D_WriteBuffer(
  143951. + IN gco3D Engine,
  143952. + IN gctCONST_POINTER Data,
  143953. + IN gctSIZE_T Bytes,
  143954. + IN gctBOOL Aligned
  143955. + );
  143956. +
  143957. +/* Send sempahore and stall until sempahore is signalled. */
  143958. +gceSTATUS
  143959. +gco3D_Semaphore(
  143960. + IN gco3D Engine,
  143961. + IN gceWHERE From,
  143962. + IN gceWHERE To,
  143963. + IN gceHOW How);
  143964. +
  143965. +/* Set the subpixels center. */
  143966. +gceSTATUS
  143967. +gco3D_SetCentroids(
  143968. + IN gco3D Engine,
  143969. + IN gctUINT32 Index,
  143970. + IN gctPOINTER Centroids
  143971. + );
  143972. +
  143973. +gceSTATUS
  143974. +gco3D_SetLogicOp(
  143975. + IN gco3D Engine,
  143976. + IN gctUINT8 Rop
  143977. + );
  143978. +
  143979. +/* OCL thread walker information. */
  143980. +typedef struct _gcsTHREAD_WALKER_INFO * gcsTHREAD_WALKER_INFO_PTR;
  143981. +typedef struct _gcsTHREAD_WALKER_INFO
  143982. +{
  143983. + gctUINT32 dimensions;
  143984. + gctUINT32 traverseOrder;
  143985. + gctUINT32 enableSwathX;
  143986. + gctUINT32 enableSwathY;
  143987. + gctUINT32 enableSwathZ;
  143988. + gctUINT32 swathSizeX;
  143989. + gctUINT32 swathSizeY;
  143990. + gctUINT32 swathSizeZ;
  143991. + gctUINT32 valueOrder;
  143992. +
  143993. + gctUINT32 globalSizeX;
  143994. + gctUINT32 globalOffsetX;
  143995. + gctUINT32 globalSizeY;
  143996. + gctUINT32 globalOffsetY;
  143997. + gctUINT32 globalSizeZ;
  143998. + gctUINT32 globalOffsetZ;
  143999. +
  144000. + gctUINT32 workGroupSizeX;
  144001. + gctUINT32 workGroupCountX;
  144002. + gctUINT32 workGroupSizeY;
  144003. + gctUINT32 workGroupCountY;
  144004. + gctUINT32 workGroupSizeZ;
  144005. + gctUINT32 workGroupCountZ;
  144006. +
  144007. + gctUINT32 threadAllocation;
  144008. +}
  144009. +gcsTHREAD_WALKER_INFO;
  144010. +
  144011. +/* Start OCL thread walker. */
  144012. +gceSTATUS
  144013. +gco3D_InvokeThreadWalker(
  144014. + IN gco3D Engine,
  144015. + IN gcsTHREAD_WALKER_INFO_PTR Info
  144016. + );
  144017. +
  144018. +/* Set w clip and w plane limit value. */
  144019. +gceSTATUS
  144020. +gco3D_SetWClipEnable(
  144021. + IN gco3D Engine,
  144022. + IN gctBOOL Enable
  144023. + );
  144024. +
  144025. +gceSTATUS
  144026. +gco3D_GetWClipEnable(
  144027. + IN gco3D Engine,
  144028. + OUT gctBOOL * Enable
  144029. + );
  144030. +
  144031. +gceSTATUS
  144032. +gco3D_SetWPlaneLimitF(
  144033. + IN gco3D Engine,
  144034. + IN gctFLOAT Value
  144035. + );
  144036. +
  144037. +gceSTATUS
  144038. +gco3D_SetWPlaneLimitX(
  144039. + IN gco3D Engine,
  144040. + IN gctFIXED_POINT Value
  144041. + );
  144042. +
  144043. +
  144044. +gceSTATUS
  144045. +gco3D_SetWPlaneLimit(
  144046. + IN gco3D Engine,
  144047. + IN gctFLOAT Value
  144048. + );
  144049. +
  144050. +/*----------------------------------------------------------------------------*/
  144051. +/*-------------------------- gco3D Fragment Processor ------------------------*/
  144052. +
  144053. +/* Set the fragment processor configuration. */
  144054. +gceSTATUS
  144055. +gco3D_SetFragmentConfiguration(
  144056. + IN gco3D Engine,
  144057. + IN gctBOOL ColorFromStream,
  144058. + IN gctBOOL EnableFog,
  144059. + IN gctBOOL EnableSmoothPoint,
  144060. + IN gctUINT32 ClipPlanes
  144061. + );
  144062. +
  144063. +/* Enable/disable texture stage operation. */
  144064. +gceSTATUS
  144065. +gco3D_EnableTextureStage(
  144066. + IN gco3D Engine,
  144067. + IN gctINT Stage,
  144068. + IN gctBOOL Enable
  144069. + );
  144070. +
  144071. +/* Program the channel enable masks for the color texture function. */
  144072. +gceSTATUS
  144073. +gco3D_SetTextureColorMask(
  144074. + IN gco3D Engine,
  144075. + IN gctINT Stage,
  144076. + IN gctBOOL ColorEnabled,
  144077. + IN gctBOOL AlphaEnabled
  144078. + );
  144079. +
  144080. +/* Program the channel enable masks for the alpha texture function. */
  144081. +gceSTATUS
  144082. +gco3D_SetTextureAlphaMask(
  144083. + IN gco3D Engine,
  144084. + IN gctINT Stage,
  144085. + IN gctBOOL ColorEnabled,
  144086. + IN gctBOOL AlphaEnabled
  144087. + );
  144088. +
  144089. +/* Program the constant fragment color. */
  144090. +gceSTATUS
  144091. +gco3D_SetFragmentColorX(
  144092. + IN gco3D Engine,
  144093. + IN gctFIXED_POINT Red,
  144094. + IN gctFIXED_POINT Green,
  144095. + IN gctFIXED_POINT Blue,
  144096. + IN gctFIXED_POINT Alpha
  144097. + );
  144098. +
  144099. +gceSTATUS
  144100. +gco3D_SetFragmentColorF(
  144101. + IN gco3D Engine,
  144102. + IN gctFLOAT Red,
  144103. + IN gctFLOAT Green,
  144104. + IN gctFLOAT Blue,
  144105. + IN gctFLOAT Alpha
  144106. + );
  144107. +
  144108. +/* Program the constant fog color. */
  144109. +gceSTATUS
  144110. +gco3D_SetFogColorX(
  144111. + IN gco3D Engine,
  144112. + IN gctFIXED_POINT Red,
  144113. + IN gctFIXED_POINT Green,
  144114. + IN gctFIXED_POINT Blue,
  144115. + IN gctFIXED_POINT Alpha
  144116. + );
  144117. +
  144118. +gceSTATUS
  144119. +gco3D_SetFogColorF(
  144120. + IN gco3D Engine,
  144121. + IN gctFLOAT Red,
  144122. + IN gctFLOAT Green,
  144123. + IN gctFLOAT Blue,
  144124. + IN gctFLOAT Alpha
  144125. + );
  144126. +
  144127. +/* Program the constant texture color. */
  144128. +gceSTATUS
  144129. +gco3D_SetTetxureColorX(
  144130. + IN gco3D Engine,
  144131. + IN gctINT Stage,
  144132. + IN gctFIXED_POINT Red,
  144133. + IN gctFIXED_POINT Green,
  144134. + IN gctFIXED_POINT Blue,
  144135. + IN gctFIXED_POINT Alpha
  144136. + );
  144137. +
  144138. +gceSTATUS
  144139. +gco3D_SetTetxureColorF(
  144140. + IN gco3D Engine,
  144141. + IN gctINT Stage,
  144142. + IN gctFLOAT Red,
  144143. + IN gctFLOAT Green,
  144144. + IN gctFLOAT Blue,
  144145. + IN gctFLOAT Alpha
  144146. + );
  144147. +
  144148. +/* Configure color texture function. */
  144149. +gceSTATUS
  144150. +gco3D_SetColorTextureFunction(
  144151. + IN gco3D Engine,
  144152. + IN gctINT Stage,
  144153. + IN gceTEXTURE_FUNCTION Function,
  144154. + IN gceTEXTURE_SOURCE Source0,
  144155. + IN gceTEXTURE_CHANNEL Channel0,
  144156. + IN gceTEXTURE_SOURCE Source1,
  144157. + IN gceTEXTURE_CHANNEL Channel1,
  144158. + IN gceTEXTURE_SOURCE Source2,
  144159. + IN gceTEXTURE_CHANNEL Channel2,
  144160. + IN gctINT Scale
  144161. + );
  144162. +
  144163. +/* Configure alpha texture function. */
  144164. +gceSTATUS
  144165. +gco3D_SetAlphaTextureFunction(
  144166. + IN gco3D Engine,
  144167. + IN gctINT Stage,
  144168. + IN gceTEXTURE_FUNCTION Function,
  144169. + IN gceTEXTURE_SOURCE Source0,
  144170. + IN gceTEXTURE_CHANNEL Channel0,
  144171. + IN gceTEXTURE_SOURCE Source1,
  144172. + IN gceTEXTURE_CHANNEL Channel1,
  144173. + IN gceTEXTURE_SOURCE Source2,
  144174. + IN gceTEXTURE_CHANNEL Channel2,
  144175. + IN gctINT Scale
  144176. + );
  144177. +
  144178. +/* Invoke OCL thread walker. */
  144179. +gceSTATUS
  144180. +gcoHARDWARE_InvokeThreadWalker(
  144181. + IN gcsTHREAD_WALKER_INFO_PTR Info
  144182. + );
  144183. +
  144184. +/******************************************************************************\
  144185. +******************************* gcoTEXTURE Object *******************************
  144186. +\******************************************************************************/
  144187. +
  144188. +/* Cube faces. */
  144189. +typedef enum _gceTEXTURE_FACE
  144190. +{
  144191. + gcvFACE_NONE,
  144192. + gcvFACE_POSITIVE_X,
  144193. + gcvFACE_NEGATIVE_X,
  144194. + gcvFACE_POSITIVE_Y,
  144195. + gcvFACE_NEGATIVE_Y,
  144196. + gcvFACE_POSITIVE_Z,
  144197. + gcvFACE_NEGATIVE_Z,
  144198. +}
  144199. +gceTEXTURE_FACE;
  144200. +
  144201. +#if gcdFORCE_MIPMAP
  144202. +typedef enum
  144203. +{
  144204. + gcvForceMipDisabled = 0,
  144205. + gcvForceMipEnable = 1,
  144206. + gcvForceMipGenerated = 2,
  144207. + gcvForceMipNever = 3,
  144208. +}gceFORCE_MIPMAP;
  144209. +#endif
  144210. +
  144211. +typedef struct _gcsTEXTURE
  144212. +{
  144213. + /* Addressing modes. */
  144214. + gceTEXTURE_ADDRESSING s;
  144215. + gceTEXTURE_ADDRESSING t;
  144216. + gceTEXTURE_ADDRESSING r;
  144217. +
  144218. + /* Border color. */
  144219. + gctUINT8 border[4];
  144220. +
  144221. + /* Filters. */
  144222. + gceTEXTURE_FILTER minFilter;
  144223. + gceTEXTURE_FILTER magFilter;
  144224. + gceTEXTURE_FILTER mipFilter;
  144225. + gctUINT anisoFilter;
  144226. + gctBOOL forceTopLevel;
  144227. + gctBOOL autoMipmap;
  144228. +#if gcdFORCE_MIPMAP
  144229. + gceFORCE_MIPMAP forceMipmap;
  144230. +#endif
  144231. + /* Level of detail. */
  144232. + gctFIXED_POINT lodBias;
  144233. + gctFIXED_POINT lodMin;
  144234. + gctFIXED_POINT lodMax;
  144235. +}
  144236. +gcsTEXTURE, * gcsTEXTURE_PTR;
  144237. +
  144238. +/* Construct a new gcoTEXTURE object. */
  144239. +gceSTATUS
  144240. +gcoTEXTURE_Construct(
  144241. + IN gcoHAL Hal,
  144242. + OUT gcoTEXTURE * Texture
  144243. + );
  144244. +
  144245. +/* Construct a new sized gcoTEXTURE object. */
  144246. +gceSTATUS
  144247. +gcoTEXTURE_ConstructSized(
  144248. + IN gcoHAL Hal,
  144249. + IN gceSURF_FORMAT Format,
  144250. + IN gctUINT Width,
  144251. + IN gctUINT Height,
  144252. + IN gctUINT Depth,
  144253. + IN gctUINT Faces,
  144254. + IN gctUINT MipMapCount,
  144255. + IN gcePOOL Pool,
  144256. + OUT gcoTEXTURE * Texture
  144257. + );
  144258. +
  144259. +/* Destroy an gcoTEXTURE object. */
  144260. +gceSTATUS
  144261. +gcoTEXTURE_Destroy(
  144262. + IN gcoTEXTURE Texture
  144263. + );
  144264. +#if gcdFORCE_MIPMAP
  144265. +gceSTATUS
  144266. +gcoTEXTURE_DestroyForceMipmap(
  144267. + IN gcoTEXTURE Texture
  144268. + );
  144269. +
  144270. +gceSTATUS
  144271. +gcoTEXTURE_GetMipLevels(
  144272. + IN gcoTEXTURE Texture,
  144273. + OUT gctINT * levels
  144274. + );
  144275. +#endif
  144276. +/* Replace a mipmap in gcoTEXTURE object. */
  144277. +gceSTATUS
  144278. +gcoTEXTURE_ReplaceMipMap(
  144279. + IN gcoTEXTURE Texture,
  144280. + IN gctUINT Level,
  144281. + IN gctUINT Width,
  144282. + IN gctUINT Height,
  144283. + IN gctINT imageFormat,
  144284. + IN gceSURF_FORMAT Format,
  144285. + IN gctUINT Depth,
  144286. + IN gctUINT Faces,
  144287. + IN gcePOOL Pool
  144288. + );
  144289. +
  144290. +/* Upload data to an gcoTEXTURE object. */
  144291. +gceSTATUS
  144292. +gcoTEXTURE_Upload(
  144293. + IN gcoTEXTURE Texture,
  144294. + IN gceTEXTURE_FACE Face,
  144295. + IN gctUINT Width,
  144296. + IN gctUINT Height,
  144297. + IN gctUINT Slice,
  144298. + IN gctCONST_POINTER Memory,
  144299. + IN gctINT Stride,
  144300. + IN gceSURF_FORMAT Format
  144301. + );
  144302. +
  144303. +/* Upload data to an gcoTEXTURE object. */
  144304. +gceSTATUS
  144305. +gcoTEXTURE_UploadSub(
  144306. + IN gcoTEXTURE Texture,
  144307. + IN gctUINT MipMap,
  144308. + IN gceTEXTURE_FACE Face,
  144309. + IN gctUINT X,
  144310. + IN gctUINT Y,
  144311. + IN gctUINT Width,
  144312. + IN gctUINT Height,
  144313. + IN gctUINT Slice,
  144314. + IN gctCONST_POINTER Memory,
  144315. + IN gctINT Stride,
  144316. + IN gceSURF_FORMAT Format
  144317. + );
  144318. +
  144319. +/* Upload YUV data to an gcoTEXTURE object. */
  144320. +gceSTATUS
  144321. +gcoTEXTURE_UploadYUV(
  144322. + IN gcoTEXTURE Texture,
  144323. + IN gceTEXTURE_FACE Face,
  144324. + IN gctUINT Width,
  144325. + IN gctUINT Height,
  144326. + IN gctUINT Slice,
  144327. + IN gctPOINTER Memory[3],
  144328. + IN gctINT Stride[3],
  144329. + IN gceSURF_FORMAT Format
  144330. + );
  144331. +
  144332. +/* Upload compressed data to an gcoTEXTURE object. */
  144333. +gceSTATUS
  144334. +gcoTEXTURE_UploadCompressed(
  144335. + IN gcoTEXTURE Texture,
  144336. + IN gceTEXTURE_FACE Face,
  144337. + IN gctUINT Width,
  144338. + IN gctUINT Height,
  144339. + IN gctUINT Slice,
  144340. + IN gctCONST_POINTER Memory,
  144341. + IN gctSIZE_T Bytes
  144342. + );
  144343. +
  144344. +/* Upload compressed sub data to an gcoTEXTURE object. */
  144345. +gceSTATUS
  144346. +gcoTEXTURE_UploadCompressedSub(
  144347. + IN gcoTEXTURE Texture,
  144348. + IN gctUINT MipMap,
  144349. + IN gceTEXTURE_FACE Face,
  144350. + IN gctUINT XOffset,
  144351. + IN gctUINT YOffset,
  144352. + IN gctUINT Width,
  144353. + IN gctUINT Height,
  144354. + IN gctUINT Slice,
  144355. + IN gctCONST_POINTER Memory,
  144356. + IN gctSIZE_T Size
  144357. + );
  144358. +
  144359. +/* GetImageFormat of texture. */
  144360. +gceSTATUS
  144361. +gcoTEXTURE_GetImageFormat(
  144362. + IN gcoTEXTURE Texture,
  144363. + IN gctUINT MipMap,
  144364. + OUT gctINT * ImageFormat
  144365. + );
  144366. +
  144367. +/* Get gcoSURF object for a mipmap level. */
  144368. +gceSTATUS
  144369. +gcoTEXTURE_GetMipMap(
  144370. + IN gcoTEXTURE Texture,
  144371. + IN gctUINT MipMap,
  144372. + OUT gcoSURF * Surface
  144373. + );
  144374. +
  144375. +/* Get gcoSURF object for a mipmap level and face offset. */
  144376. +gceSTATUS
  144377. +gcoTEXTURE_GetMipMapFace(
  144378. + IN gcoTEXTURE Texture,
  144379. + IN gctUINT MipMap,
  144380. + IN gceTEXTURE_FACE Face,
  144381. + OUT gcoSURF * Surface,
  144382. + OUT gctUINT32_PTR Offset
  144383. + );
  144384. +
  144385. +gceSTATUS
  144386. +gcoTEXTURE_AddMipMap(
  144387. + IN gcoTEXTURE Texture,
  144388. + IN gctINT Level,
  144389. + IN gctINT imageFormat,
  144390. + IN gceSURF_FORMAT Format,
  144391. + IN gctUINT Width,
  144392. + IN gctUINT Height,
  144393. + IN gctUINT Depth,
  144394. + IN gctUINT Faces,
  144395. + IN gcePOOL Pool,
  144396. + OUT gcoSURF * Surface
  144397. + );
  144398. +
  144399. +gceSTATUS
  144400. +gcoTEXTURE_AddMipMapFromClient(
  144401. + IN gcoTEXTURE Texture,
  144402. + IN gctINT Level,
  144403. + IN gcoSURF Surface
  144404. + );
  144405. +
  144406. +gceSTATUS
  144407. +gcoTEXTURE_AddMipMapFromSurface(
  144408. + IN gcoTEXTURE Texture,
  144409. + IN gctINT Level,
  144410. + IN gcoSURF Surface
  144411. + );
  144412. +
  144413. +gceSTATUS
  144414. +gcoTEXTURE_SetMaxLevel(
  144415. + IN gcoTEXTURE Texture,
  144416. + IN gctUINT Levels
  144417. + );
  144418. +
  144419. +gceSTATUS
  144420. +gcoTEXTURE_SetEndianHint(
  144421. + IN gcoTEXTURE Texture,
  144422. + IN gceENDIAN_HINT EndianHint
  144423. + );
  144424. +
  144425. +gceSTATUS
  144426. +gcoTEXTURE_Disable(
  144427. + IN gcoHAL Hal,
  144428. + IN gctINT Sampler
  144429. + );
  144430. +
  144431. +gceSTATUS
  144432. +gcoTEXTURE_Flush(
  144433. + IN gcoTEXTURE Texture
  144434. + );
  144435. +
  144436. +gceSTATUS
  144437. +gcoTEXTURE_QueryCaps(
  144438. + IN gcoHAL Hal,
  144439. + OUT gctUINT * MaxWidth,
  144440. + OUT gctUINT * MaxHeight,
  144441. + OUT gctUINT * MaxDepth,
  144442. + OUT gctBOOL * Cubic,
  144443. + OUT gctBOOL * NonPowerOfTwo,
  144444. + OUT gctUINT * VertexSamplers,
  144445. + OUT gctUINT * PixelSamplers
  144446. + );
  144447. +
  144448. +gceSTATUS
  144449. +gcoTEXTURE_GetTiling(
  144450. + IN gcoTEXTURE Texture,
  144451. + IN gctINT preferLevel,
  144452. + OUT gceTILING * Tiling
  144453. + );
  144454. +
  144455. +gceSTATUS
  144456. +gcoTEXTURE_GetClosestFormat(
  144457. + IN gcoHAL Hal,
  144458. + IN gceSURF_FORMAT InFormat,
  144459. + OUT gceSURF_FORMAT* OutFormat
  144460. + );
  144461. +
  144462. +gceSTATUS
  144463. +gcoTEXTURE_RenderIntoMipMap(
  144464. + IN gcoTEXTURE Texture,
  144465. + IN gctINT Level
  144466. + );
  144467. +
  144468. +gceSTATUS
  144469. +gcoTEXTURE_IsRenderable(
  144470. + IN gcoTEXTURE Texture,
  144471. + IN gctUINT Level
  144472. + );
  144473. +
  144474. +gceSTATUS
  144475. +gcoTEXTURE_IsRenderableEx(
  144476. + IN gcoTEXTURE Texture,
  144477. + IN gctUINT Level
  144478. + );
  144479. +
  144480. +gceSTATUS
  144481. +gcoTEXTURE_IsComplete(
  144482. + IN gcoTEXTURE Texture,
  144483. + IN gctINT MaxLevel
  144484. + );
  144485. +
  144486. +gceSTATUS
  144487. +gcoTEXTURE_BindTexture(
  144488. + IN gcoTEXTURE Texture,
  144489. + IN gctINT Target,
  144490. + IN gctINT Sampler,
  144491. + IN gcsTEXTURE_PTR Info
  144492. + );
  144493. +
  144494. +/******************************************************************************\
  144495. +******************************* gcoSTREAM Object ******************************
  144496. +\******************************************************************************/
  144497. +
  144498. +typedef enum _gceVERTEX_FORMAT
  144499. +{
  144500. + gcvVERTEX_BYTE,
  144501. + gcvVERTEX_UNSIGNED_BYTE,
  144502. + gcvVERTEX_SHORT,
  144503. + gcvVERTEX_UNSIGNED_SHORT,
  144504. + gcvVERTEX_INT,
  144505. + gcvVERTEX_UNSIGNED_INT,
  144506. + gcvVERTEX_FIXED,
  144507. + gcvVERTEX_HALF,
  144508. + gcvVERTEX_FLOAT,
  144509. + gcvVERTEX_UNSIGNED_INT_10_10_10_2,
  144510. + gcvVERTEX_INT_10_10_10_2,
  144511. +}
  144512. +gceVERTEX_FORMAT;
  144513. +
  144514. +gceSTATUS
  144515. +gcoSTREAM_Construct(
  144516. + IN gcoHAL Hal,
  144517. + OUT gcoSTREAM * Stream
  144518. + );
  144519. +
  144520. +gceSTATUS
  144521. +gcoSTREAM_Destroy(
  144522. + IN gcoSTREAM Stream
  144523. + );
  144524. +
  144525. +gceSTATUS
  144526. +gcoSTREAM_Upload(
  144527. + IN gcoSTREAM Stream,
  144528. + IN gctCONST_POINTER Buffer,
  144529. + IN gctUINT32 Offset,
  144530. + IN gctSIZE_T Bytes,
  144531. + IN gctBOOL Dynamic
  144532. + );
  144533. +
  144534. +gceSTATUS
  144535. +gcoSTREAM_SetStride(
  144536. + IN gcoSTREAM Stream,
  144537. + IN gctUINT32 Stride
  144538. + );
  144539. +
  144540. +gceSTATUS
  144541. +gcoSTREAM_Lock(
  144542. + IN gcoSTREAM Stream,
  144543. + OUT gctPOINTER * Logical,
  144544. + OUT gctUINT32 * Physical
  144545. + );
  144546. +
  144547. +gceSTATUS
  144548. +gcoSTREAM_Unlock(
  144549. + IN gcoSTREAM Stream
  144550. + );
  144551. +
  144552. +gceSTATUS
  144553. +gcoSTREAM_Reserve(
  144554. + IN gcoSTREAM Stream,
  144555. + IN gctSIZE_T Bytes
  144556. + );
  144557. +
  144558. +gceSTATUS
  144559. +gcoSTREAM_Flush(
  144560. + IN gcoSTREAM Stream
  144561. + );
  144562. +
  144563. +/* Dynamic buffer API. */
  144564. +gceSTATUS
  144565. +gcoSTREAM_SetDynamic(
  144566. + IN gcoSTREAM Stream,
  144567. + IN gctSIZE_T Bytes,
  144568. + IN gctUINT Buffers
  144569. + );
  144570. +
  144571. +typedef struct _gcsSTREAM_INFO
  144572. +{
  144573. + gctUINT index;
  144574. + gceVERTEX_FORMAT format;
  144575. + gctBOOL normalized;
  144576. + gctUINT components;
  144577. + gctSIZE_T size;
  144578. + gctCONST_POINTER data;
  144579. + gctUINT stride;
  144580. +}
  144581. +gcsSTREAM_INFO, * gcsSTREAM_INFO_PTR;
  144582. +
  144583. +gceSTATUS
  144584. +gcoSTREAM_UploadDynamic(
  144585. + IN gcoSTREAM Stream,
  144586. + IN gctUINT VertexCount,
  144587. + IN gctUINT InfoCount,
  144588. + IN gcsSTREAM_INFO_PTR Info,
  144589. + IN gcoVERTEX Vertex
  144590. + );
  144591. +
  144592. +gceSTATUS
  144593. +gcoSTREAM_CPUCacheOperation(
  144594. + IN gcoSTREAM Stream,
  144595. + IN gceCACHEOPERATION Operation
  144596. + );
  144597. +
  144598. +/******************************************************************************\
  144599. +******************************** gcoVERTEX Object ******************************
  144600. +\******************************************************************************/
  144601. +
  144602. +typedef struct _gcsVERTEX_ATTRIBUTES
  144603. +{
  144604. + gceVERTEX_FORMAT format;
  144605. + gctBOOL normalized;
  144606. + gctUINT32 components;
  144607. + gctSIZE_T size;
  144608. + gctUINT32 stream;
  144609. + gctUINT32 offset;
  144610. + gctUINT32 stride;
  144611. +}
  144612. +gcsVERTEX_ATTRIBUTES;
  144613. +
  144614. +gceSTATUS
  144615. +gcoVERTEX_Construct(
  144616. + IN gcoHAL Hal,
  144617. + OUT gcoVERTEX * Vertex
  144618. + );
  144619. +
  144620. +gceSTATUS
  144621. +gcoVERTEX_Destroy(
  144622. + IN gcoVERTEX Vertex
  144623. + );
  144624. +
  144625. +gceSTATUS
  144626. +gcoVERTEX_Reset(
  144627. + IN gcoVERTEX Vertex
  144628. + );
  144629. +
  144630. +gceSTATUS
  144631. +gcoVERTEX_EnableAttribute(
  144632. + IN gcoVERTEX Vertex,
  144633. + IN gctUINT32 Index,
  144634. + IN gceVERTEX_FORMAT Format,
  144635. + IN gctBOOL Normalized,
  144636. + IN gctUINT32 Components,
  144637. + IN gcoSTREAM Stream,
  144638. + IN gctUINT32 Offset,
  144639. + IN gctUINT32 Stride
  144640. + );
  144641. +
  144642. +gceSTATUS
  144643. +gcoVERTEX_DisableAttribute(
  144644. + IN gcoVERTEX Vertex,
  144645. + IN gctUINT32 Index
  144646. + );
  144647. +
  144648. +gceSTATUS
  144649. +gcoVERTEX_Bind(
  144650. + IN gcoVERTEX Vertex
  144651. + );
  144652. +
  144653. +/*******************************************************************************
  144654. +***** gcoVERTEXARRAY Object ***************************************************/
  144655. +
  144656. +typedef struct _gcsVERTEXARRAY
  144657. +{
  144658. + /* Enabled. */
  144659. + gctBOOL enable;
  144660. +
  144661. + /* Number of components. */
  144662. + gctINT size;
  144663. +
  144664. + /* Attribute format. */
  144665. + gceVERTEX_FORMAT format;
  144666. +
  144667. + /* Flag whether the attribute is normalized or not. */
  144668. + gctBOOL normalized;
  144669. +
  144670. + /* Stride of the component. */
  144671. + gctUINT stride;
  144672. +
  144673. + /* Pointer to the attribute data. */
  144674. + gctCONST_POINTER pointer;
  144675. +
  144676. + /* Stream object owning the attribute data. */
  144677. + gcoSTREAM stream;
  144678. +
  144679. + /* Generic values for attribute. */
  144680. + gctFLOAT genericValue[4];
  144681. +
  144682. + /* Generic size for attribute. */
  144683. + gctINT genericSize;
  144684. +
  144685. + /* Vertex shader linkage. */
  144686. + gctUINT linkage;
  144687. +
  144688. +#if gcdUSE_WCLIP_PATCH
  144689. + gctBOOL isPosition;
  144690. +#endif
  144691. +}
  144692. +gcsVERTEXARRAY,
  144693. +* gcsVERTEXARRAY_PTR;
  144694. +
  144695. +gceSTATUS
  144696. +gcoVERTEXARRAY_Construct(
  144697. + IN gcoHAL Hal,
  144698. + OUT gcoVERTEXARRAY * Vertex
  144699. + );
  144700. +
  144701. +gceSTATUS
  144702. +gcoVERTEXARRAY_Destroy(
  144703. + IN gcoVERTEXARRAY Vertex
  144704. + );
  144705. +
  144706. +gceSTATUS
  144707. +gcoVERTEXARRAY_Bind(
  144708. + IN gcoVERTEXARRAY Vertex,
  144709. + IN gctUINT32 EnableBits,
  144710. + IN gcsVERTEXARRAY_PTR VertexArray,
  144711. + IN gctUINT First,
  144712. + IN gctSIZE_T Count,
  144713. + IN gceINDEX_TYPE IndexType,
  144714. + IN gcoINDEX IndexObject,
  144715. + IN gctPOINTER IndexMemory,
  144716. + IN OUT gcePRIMITIVE * PrimitiveType,
  144717. +#if gcdUSE_WCLIP_PATCH
  144718. + IN OUT gctUINT * PrimitiveCount,
  144719. + IN OUT gctFLOAT * wLimitRms,
  144720. + IN OUT gctBOOL * wLimitDirty
  144721. +#else
  144722. + IN OUT gctUINT * PrimitiveCount
  144723. +#endif
  144724. + );
  144725. +
  144726. +gctUINT
  144727. +gcoVERTEXARRAY_GetMaxStream(
  144728. + IN gcoVERTEXARRAY Vertex
  144729. +);
  144730. +
  144731. +gceSTATUS
  144732. +gcoVERTEXARRAY_SetMaxStream(
  144733. + IN gcoVERTEXARRAY Vertex,
  144734. + gctUINT maxStreams
  144735. +);
  144736. +/*******************************************************************************
  144737. +***** Composition *************************************************************/
  144738. +
  144739. +typedef enum _gceCOMPOSITION
  144740. +{
  144741. + gcvCOMPOSE_CLEAR = 1,
  144742. + gcvCOMPOSE_BLUR,
  144743. + gcvCOMPOSE_DIM,
  144744. + gcvCOMPOSE_LAYER
  144745. +}
  144746. +gceCOMPOSITION;
  144747. +
  144748. +typedef struct _gcsCOMPOSITION * gcsCOMPOSITION_PTR;
  144749. +typedef struct _gcsCOMPOSITION
  144750. +{
  144751. + /* Structure size. */
  144752. + gctUINT structSize;
  144753. +
  144754. + /* Composition operation. */
  144755. + gceCOMPOSITION operation;
  144756. +
  144757. + /* Layer to be composed. */
  144758. + gcoSURF layer;
  144759. +
  144760. + /* Source and target coordinates. */
  144761. + gcsRECT srcRect;
  144762. + gcsRECT trgRect;
  144763. +
  144764. + /* Target rectangle */
  144765. + gcsPOINT v0;
  144766. + gcsPOINT v1;
  144767. + gcsPOINT v2;
  144768. +
  144769. + /* Blending parameters. */
  144770. + gctBOOL enableBlending;
  144771. + gctBOOL premultiplied;
  144772. + gctUINT8 alphaValue;
  144773. +
  144774. + /* Clear color. */
  144775. + gctFLOAT r;
  144776. + gctFLOAT g;
  144777. + gctFLOAT b;
  144778. + gctFLOAT a;
  144779. +}
  144780. +gcsCOMPOSITION;
  144781. +
  144782. +gceSTATUS
  144783. +gco3D_ProbeComposition(
  144784. + gctBOOL ResetIfEmpty
  144785. + );
  144786. +
  144787. +gceSTATUS
  144788. +gco3D_CompositionBegin(
  144789. + void
  144790. + );
  144791. +
  144792. +gceSTATUS
  144793. +gco3D_ComposeLayer(
  144794. + IN gcsCOMPOSITION_PTR Layer
  144795. + );
  144796. +
  144797. +gceSTATUS
  144798. +gco3D_CompositionSignals(
  144799. + IN gctHANDLE Process,
  144800. + IN gctSIGNAL Signal1,
  144801. + IN gctSIGNAL Signal2
  144802. + );
  144803. +
  144804. +gceSTATUS
  144805. +gco3D_CompositionEnd(
  144806. + IN gcoSURF Target,
  144807. + IN gctBOOL Synchronous
  144808. + );
  144809. +
  144810. +/* Frame Database */
  144811. +gceSTATUS
  144812. +gcoHAL_AddFrameDB(
  144813. + void
  144814. + );
  144815. +
  144816. +gceSTATUS
  144817. +gcoHAL_DumpFrameDB(
  144818. + gctCONST_STRING Filename OPTIONAL
  144819. + );
  144820. +
  144821. +gceSTATUS
  144822. +gcoHAL_GetSharedInfo(
  144823. + IN gctUINT32 Pid,
  144824. + IN gctUINT32 DataId,
  144825. + IN gctSIZE_T Bytes,
  144826. + OUT gctPOINTER Data
  144827. + );
  144828. +
  144829. +gceSTATUS
  144830. +gcoHAL_SetSharedInfo(
  144831. + IN gctUINT32 DataId,
  144832. + IN gctPOINTER Data,
  144833. + IN gctSIZE_T Bytes
  144834. + );
  144835. +
  144836. +#if VIVANTE_PROFILER_CONTEXT
  144837. +gceSTATUS
  144838. +gcoHARDWARE_GetContext(
  144839. + IN gcoHARDWARE Hardware,
  144840. + OUT gctUINT32 * Context
  144841. + );
  144842. +#endif
  144843. +
  144844. +#ifdef __cplusplus
  144845. +}
  144846. +#endif
  144847. +
  144848. +#endif /* VIVANTE_NO_3D */
  144849. +#endif /* __gc_hal_engine_h_ */
  144850. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h
  144851. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h 1969-12-31 18:00:00.000000000 -0600
  144852. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h 2014-12-08 00:31:53.468418001 -0600
  144853. @@ -0,0 +1,904 @@
  144854. +/****************************************************************************
  144855. +*
  144856. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  144857. +*
  144858. +* This program is free software; you can redistribute it and/or modify
  144859. +* it under the terms of the GNU General Public License as published by
  144860. +* the Free Software Foundation; either version 2 of the license, or
  144861. +* (at your option) any later version.
  144862. +*
  144863. +* This program is distributed in the hope that it will be useful,
  144864. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  144865. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  144866. +* GNU General Public License for more details.
  144867. +*
  144868. +* You should have received a copy of the GNU General Public License
  144869. +* along with this program; if not write to the Free Software
  144870. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  144871. +*
  144872. +*****************************************************************************/
  144873. +
  144874. +
  144875. +#ifndef __gc_hal_engine_vg_h_
  144876. +#define __gc_hal_engine_vg_h_
  144877. +
  144878. +#ifdef __cplusplus
  144879. +extern "C" {
  144880. +#endif
  144881. +
  144882. +#include "gc_hal_types.h"
  144883. +
  144884. +/******************************************************************************\
  144885. +******************************** VG Enumerations *******************************
  144886. +\******************************************************************************/
  144887. +
  144888. +/**
  144889. +** @ingroup gcoVG
  144890. +**
  144891. +** @brief Tiling mode for painting and imagig.
  144892. +**
  144893. +** This enumeration defines the tiling modes supported by the HAL. This is
  144894. +** in fact a one-to-one mapping of the OpenVG 1.1 tile modes.
  144895. +*/
  144896. +typedef enum _gceTILE_MODE
  144897. +{
  144898. + gcvTILE_FILL,
  144899. + gcvTILE_PAD,
  144900. + gcvTILE_REPEAT,
  144901. + gcvTILE_REFLECT
  144902. +}
  144903. +gceTILE_MODE;
  144904. +
  144905. +/******************************************************************************/
  144906. +/** @ingroup gcoVG
  144907. +**
  144908. +** @brief The different paint modes.
  144909. +**
  144910. +** This enumeration lists the available paint modes.
  144911. +*/
  144912. +typedef enum _gcePAINT_TYPE
  144913. +{
  144914. + /** Solid color. */
  144915. + gcvPAINT_MODE_SOLID,
  144916. +
  144917. + /** Linear gradient. */
  144918. + gcvPAINT_MODE_LINEAR,
  144919. +
  144920. + /** Radial gradient. */
  144921. + gcvPAINT_MODE_RADIAL,
  144922. +
  144923. + /** Pattern. */
  144924. + gcvPAINT_MODE_PATTERN,
  144925. +
  144926. + /** Mode count. */
  144927. + gcvPAINT_MODE_COUNT
  144928. +}
  144929. +gcePAINT_TYPE;
  144930. +
  144931. +/**
  144932. +** @ingroup gcoVG
  144933. +**
  144934. +** @brief Types of path data supported by HAL.
  144935. +**
  144936. +** This enumeration defines the types of path data supported by the HAL.
  144937. +** This is in fact a one-to-one mapping of the OpenVG 1.1 path types.
  144938. +*/
  144939. +typedef enum _gcePATHTYPE
  144940. +{
  144941. + gcePATHTYPE_UNKNOWN = -1,
  144942. + gcePATHTYPE_INT8,
  144943. + gcePATHTYPE_INT16,
  144944. + gcePATHTYPE_INT32,
  144945. + gcePATHTYPE_FLOAT
  144946. +}
  144947. +gcePATHTYPE;
  144948. +
  144949. +/**
  144950. +** @ingroup gcoVG
  144951. +**
  144952. +** @brief Supported path segment commands.
  144953. +**
  144954. +** This enumeration defines the path segment commands supported by the HAL.
  144955. +*/
  144956. +typedef enum _gceVGCMD
  144957. +{
  144958. + gcvVGCMD_END, /* 0: GCCMD_TS_OPCODE_END */
  144959. + gcvVGCMD_CLOSE, /* 1: GCCMD_TS_OPCODE_CLOSE */
  144960. + gcvVGCMD_MOVE, /* 2: GCCMD_TS_OPCODE_MOVE */
  144961. + gcvVGCMD_MOVE_REL, /* 3: GCCMD_TS_OPCODE_MOVE_REL */
  144962. + gcvVGCMD_LINE, /* 4: GCCMD_TS_OPCODE_LINE */
  144963. + gcvVGCMD_LINE_REL, /* 5: GCCMD_TS_OPCODE_LINE_REL */
  144964. + gcvVGCMD_QUAD, /* 6: GCCMD_TS_OPCODE_QUADRATIC */
  144965. + gcvVGCMD_QUAD_REL, /* 7: GCCMD_TS_OPCODE_QUADRATIC_REL */
  144966. + gcvVGCMD_CUBIC, /* 8: GCCMD_TS_OPCODE_CUBIC */
  144967. + gcvVGCMD_CUBIC_REL, /* 9: GCCMD_TS_OPCODE_CUBIC_REL */
  144968. + gcvVGCMD_BREAK, /* 10: GCCMD_TS_OPCODE_BREAK */
  144969. + gcvVGCMD_HLINE, /* 11: ******* R E S E R V E D *******/
  144970. + gcvVGCMD_HLINE_REL, /* 12: ******* R E S E R V E D *******/
  144971. + gcvVGCMD_VLINE, /* 13: ******* R E S E R V E D *******/
  144972. + gcvVGCMD_VLINE_REL, /* 14: ******* R E S E R V E D *******/
  144973. + gcvVGCMD_SQUAD, /* 15: ******* R E S E R V E D *******/
  144974. + gcvVGCMD_SQUAD_REL, /* 16: ******* R E S E R V E D *******/
  144975. + gcvVGCMD_SCUBIC, /* 17: ******* R E S E R V E D *******/
  144976. + gcvVGCMD_SCUBIC_REL, /* 18: ******* R E S E R V E D *******/
  144977. + gcvVGCMD_SCCWARC, /* 19: ******* R E S E R V E D *******/
  144978. + gcvVGCMD_SCCWARC_REL, /* 20: ******* R E S E R V E D *******/
  144979. + gcvVGCMD_SCWARC, /* 21: ******* R E S E R V E D *******/
  144980. + gcvVGCMD_SCWARC_REL, /* 22: ******* R E S E R V E D *******/
  144981. + gcvVGCMD_LCCWARC, /* 23: ******* R E S E R V E D *******/
  144982. + gcvVGCMD_LCCWARC_REL, /* 24: ******* R E S E R V E D *******/
  144983. + gcvVGCMD_LCWARC, /* 25: ******* R E S E R V E D *******/
  144984. + gcvVGCMD_LCWARC_REL, /* 26: ******* R E S E R V E D *******/
  144985. +
  144986. + /* The width of the command recognized by the hardware on bits. */
  144987. + gcvVGCMD_WIDTH = 5,
  144988. +
  144989. + /* Hardware command mask. */
  144990. + gcvVGCMD_MASK = (1 << gcvVGCMD_WIDTH) - 1,
  144991. +
  144992. + /* Command modifiers. */
  144993. + gcvVGCMD_H_MOD = 1 << gcvVGCMD_WIDTH, /* = 32 */
  144994. + gcvVGCMD_V_MOD = 2 << gcvVGCMD_WIDTH, /* = 64 */
  144995. + gcvVGCMD_S_MOD = 3 << gcvVGCMD_WIDTH, /* = 96 */
  144996. + gcvVGCMD_ARC_MOD = 4 << gcvVGCMD_WIDTH, /* = 128 */
  144997. +
  144998. + /* Emulated LINE commands. */
  144999. + gcvVGCMD_HLINE_EMUL = gcvVGCMD_H_MOD | gcvVGCMD_LINE, /* = 36 */
  145000. + gcvVGCMD_HLINE_EMUL_REL = gcvVGCMD_H_MOD | gcvVGCMD_LINE_REL, /* = 37 */
  145001. + gcvVGCMD_VLINE_EMUL = gcvVGCMD_V_MOD | gcvVGCMD_LINE, /* = 68 */
  145002. + gcvVGCMD_VLINE_EMUL_REL = gcvVGCMD_V_MOD | gcvVGCMD_LINE_REL, /* = 69 */
  145003. +
  145004. + /* Emulated SMOOTH commands. */
  145005. + gcvVGCMD_SQUAD_EMUL = gcvVGCMD_S_MOD | gcvVGCMD_QUAD, /* = 102 */
  145006. + gcvVGCMD_SQUAD_EMUL_REL = gcvVGCMD_S_MOD | gcvVGCMD_QUAD_REL, /* = 103 */
  145007. + gcvVGCMD_SCUBIC_EMUL = gcvVGCMD_S_MOD | gcvVGCMD_CUBIC, /* = 104 */
  145008. + gcvVGCMD_SCUBIC_EMUL_REL = gcvVGCMD_S_MOD | gcvVGCMD_CUBIC_REL, /* = 105 */
  145009. +
  145010. + /* Emulation ARC commands. */
  145011. + gcvVGCMD_ARC_LINE = gcvVGCMD_ARC_MOD | gcvVGCMD_LINE, /* = 132 */
  145012. + gcvVGCMD_ARC_LINE_REL = gcvVGCMD_ARC_MOD | gcvVGCMD_LINE_REL, /* = 133 */
  145013. + gcvVGCMD_ARC_QUAD = gcvVGCMD_ARC_MOD | gcvVGCMD_QUAD, /* = 134 */
  145014. + gcvVGCMD_ARC_QUAD_REL = gcvVGCMD_ARC_MOD | gcvVGCMD_QUAD_REL /* = 135 */
  145015. +}
  145016. +gceVGCMD;
  145017. +typedef enum _gceVGCMD * gceVGCMD_PTR;
  145018. +
  145019. +/**
  145020. +** @ingroup gcoVG
  145021. +**
  145022. +** @brief Blending modes supported by the HAL.
  145023. +**
  145024. +** This enumeration defines the blending modes supported by the HAL. This is
  145025. +** in fact a one-to-one mapping of the OpenVG 1.1 blending modes.
  145026. +*/
  145027. +typedef enum _gceVG_BLEND
  145028. +{
  145029. + gcvVG_BLEND_SRC,
  145030. + gcvVG_BLEND_SRC_OVER,
  145031. + gcvVG_BLEND_DST_OVER,
  145032. + gcvVG_BLEND_SRC_IN,
  145033. + gcvVG_BLEND_DST_IN,
  145034. + gcvVG_BLEND_MULTIPLY,
  145035. + gcvVG_BLEND_SCREEN,
  145036. + gcvVG_BLEND_DARKEN,
  145037. + gcvVG_BLEND_LIGHTEN,
  145038. + gcvVG_BLEND_ADDITIVE,
  145039. + gcvVG_BLEND_SUBTRACT,
  145040. + gcvVG_BLEND_FILTER
  145041. +}
  145042. +gceVG_BLEND;
  145043. +
  145044. +/**
  145045. +** @ingroup gcoVG
  145046. +**
  145047. +** @brief Image modes supported by the HAL.
  145048. +**
  145049. +** This enumeration defines the image modes supported by the HAL. This is
  145050. +** in fact a one-to-one mapping of the OpenVG 1.1 image modes with the addition
  145051. +** of NO IMAGE.
  145052. +*/
  145053. +typedef enum _gceVG_IMAGE
  145054. +{
  145055. + gcvVG_IMAGE_NONE,
  145056. + gcvVG_IMAGE_NORMAL,
  145057. + gcvVG_IMAGE_MULTIPLY,
  145058. + gcvVG_IMAGE_STENCIL,
  145059. + gcvVG_IMAGE_FILTER
  145060. +}
  145061. +gceVG_IMAGE;
  145062. +
  145063. +/**
  145064. +** @ingroup gcoVG
  145065. +**
  145066. +** @brief Filter mode patterns and imaging.
  145067. +**
  145068. +** This enumeration defines the filter modes supported by the HAL.
  145069. +*/
  145070. +typedef enum _gceIMAGE_FILTER
  145071. +{
  145072. + gcvFILTER_POINT,
  145073. + gcvFILTER_LINEAR,
  145074. + gcvFILTER_BI_LINEAR
  145075. +}
  145076. +gceIMAGE_FILTER;
  145077. +
  145078. +/**
  145079. +** @ingroup gcoVG
  145080. +**
  145081. +** @brief Primitive modes supported by the HAL.
  145082. +**
  145083. +** This enumeration defines the primitive modes supported by the HAL.
  145084. +*/
  145085. +typedef enum _gceVG_PRIMITIVE
  145086. +{
  145087. + gcvVG_SCANLINE,
  145088. + gcvVG_RECTANGLE,
  145089. + gcvVG_TESSELLATED,
  145090. + gcvVG_TESSELLATED_TILED
  145091. +}
  145092. +gceVG_PRIMITIVE;
  145093. +
  145094. +/**
  145095. +** @ingroup gcoVG
  145096. +**
  145097. +** @brief Rendering quality modes supported by the HAL.
  145098. +**
  145099. +** This enumeration defines the rendering quality modes supported by the HAL.
  145100. +*/
  145101. +typedef enum _gceRENDER_QUALITY
  145102. +{
  145103. + gcvVG_NONANTIALIASED,
  145104. + gcvVG_2X2_MSAA,
  145105. + gcvVG_2X4_MSAA,
  145106. + gcvVG_4X4_MSAA
  145107. +}
  145108. +gceRENDER_QUALITY;
  145109. +
  145110. +/**
  145111. +** @ingroup gcoVG
  145112. +**
  145113. +** @brief Fill rules supported by the HAL.
  145114. +**
  145115. +** This enumeration defines the fill rules supported by the HAL.
  145116. +*/
  145117. +typedef enum _gceFILL_RULE
  145118. +{
  145119. + gcvVG_EVEN_ODD,
  145120. + gcvVG_NON_ZERO
  145121. +}
  145122. +gceFILL_RULE;
  145123. +
  145124. +/**
  145125. +** @ingroup gcoVG
  145126. +**
  145127. +** @brief Cap styles supported by the HAL.
  145128. +**
  145129. +** This enumeration defines the cap styles supported by the HAL.
  145130. +*/
  145131. +typedef enum _gceCAP_STYLE
  145132. +{
  145133. + gcvCAP_BUTT,
  145134. + gcvCAP_ROUND,
  145135. + gcvCAP_SQUARE
  145136. +}
  145137. +gceCAP_STYLE;
  145138. +
  145139. +/**
  145140. +** @ingroup gcoVG
  145141. +**
  145142. +** @brief Join styles supported by the HAL.
  145143. +**
  145144. +** This enumeration defines the join styles supported by the HAL.
  145145. +*/
  145146. +typedef enum _gceJOIN_STYLE
  145147. +{
  145148. + gcvJOIN_MITER,
  145149. + gcvJOIN_ROUND,
  145150. + gcvJOIN_BEVEL
  145151. +}
  145152. +gceJOIN_STYLE;
  145153. +
  145154. +/**
  145155. +** @ingroup gcoVG
  145156. +**
  145157. +** @brief Channel mask values.
  145158. +**
  145159. +** This enumeration defines the values for channel mask used in image
  145160. +** filtering.
  145161. +*/
  145162. +
  145163. +/* Base values for channel mask definitions. */
  145164. +#define gcvCHANNEL_X (0)
  145165. +#define gcvCHANNEL_R (1 << 0)
  145166. +#define gcvCHANNEL_G (1 << 1)
  145167. +#define gcvCHANNEL_B (1 << 2)
  145168. +#define gcvCHANNEL_A (1 << 3)
  145169. +
  145170. +typedef enum _gceCHANNEL
  145171. +{
  145172. + gcvCHANNEL_XXXX = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X),
  145173. + gcvCHANNEL_XXXA = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_A),
  145174. + gcvCHANNEL_XXBX = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_X),
  145175. + gcvCHANNEL_XXBA = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_A),
  145176. +
  145177. + gcvCHANNEL_XGXX = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_X),
  145178. + gcvCHANNEL_XGXA = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_A),
  145179. + gcvCHANNEL_XGBX = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_X),
  145180. + gcvCHANNEL_XGBA = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_A),
  145181. +
  145182. + gcvCHANNEL_RXXX = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X),
  145183. + gcvCHANNEL_RXXA = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_A),
  145184. + gcvCHANNEL_RXBX = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_X),
  145185. + gcvCHANNEL_RXBA = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_A),
  145186. +
  145187. + gcvCHANNEL_RGXX = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_X),
  145188. + gcvCHANNEL_RGXA = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_A),
  145189. + gcvCHANNEL_RGBX = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_X),
  145190. + gcvCHANNEL_RGBA = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_A),
  145191. +}
  145192. +gceCHANNEL;
  145193. +
  145194. +/******************************************************************************\
  145195. +******************************** VG Structures *******************************
  145196. +\******************************************************************************/
  145197. +
  145198. +/**
  145199. +** @ingroup gcoVG
  145200. +**
  145201. +** @brief Definition of the color ramp used by the gradient paints.
  145202. +**
  145203. +** The gcsCOLOR_RAMP structure defines the layout of one single color inside
  145204. +** a color ramp which is used by gradient paints.
  145205. +*/
  145206. +typedef struct _gcsCOLOR_RAMP
  145207. +{
  145208. + /** Value for the color stop. */
  145209. + gctFLOAT stop;
  145210. +
  145211. + /** Red color channel value for the color stop. */
  145212. + gctFLOAT red;
  145213. +
  145214. + /** Green color channel value for the color stop. */
  145215. + gctFLOAT green;
  145216. +
  145217. + /** Blue color channel value for the color stop. */
  145218. + gctFLOAT blue;
  145219. +
  145220. + /** Alpha color channel value for the color stop. */
  145221. + gctFLOAT alpha;
  145222. +}
  145223. +gcsCOLOR_RAMP, * gcsCOLOR_RAMP_PTR;
  145224. +
  145225. +/**
  145226. +** @ingroup gcoVG
  145227. +**
  145228. +** @brief Definition of the color ramp used by the gradient paints in fixed form.
  145229. +**
  145230. +** The gcsCOLOR_RAMP structure defines the layout of one single color inside
  145231. +** a color ramp which is used by gradient paints.
  145232. +*/
  145233. +typedef struct _gcsFIXED_COLOR_RAMP
  145234. +{
  145235. + /** Value for the color stop. */
  145236. + gctFIXED_POINT stop;
  145237. +
  145238. + /** Red color channel value for the color stop. */
  145239. + gctFIXED_POINT red;
  145240. +
  145241. + /** Green color channel value for the color stop. */
  145242. + gctFIXED_POINT green;
  145243. +
  145244. + /** Blue color channel value for the color stop. */
  145245. + gctFIXED_POINT blue;
  145246. +
  145247. + /** Alpha color channel value for the color stop. */
  145248. + gctFIXED_POINT alpha;
  145249. +}
  145250. +gcsFIXED_COLOR_RAMP, * gcsFIXED_COLOR_RAMP_PTR;
  145251. +
  145252. +
  145253. +/**
  145254. +** @ingroup gcoVG
  145255. +**
  145256. +** @brief Rectangle structure used by the gcoVG object.
  145257. +**
  145258. +** This structure defines the layout of a rectangle. Make sure width and
  145259. +** height are larger than 0.
  145260. +*/
  145261. +typedef struct _gcsVG_RECT * gcsVG_RECT_PTR;
  145262. +typedef struct _gcsVG_RECT
  145263. +{
  145264. + /** Left location of the rectangle. */
  145265. + gctINT x;
  145266. +
  145267. + /** Top location of the rectangle. */
  145268. + gctINT y;
  145269. +
  145270. + /** Width of the rectangle. */
  145271. + gctINT width;
  145272. +
  145273. + /** Height of the rectangle. */
  145274. + gctINT height;
  145275. +}
  145276. +gcsVG_RECT;
  145277. +
  145278. +/**
  145279. +** @ingroup gcoVG
  145280. +**
  145281. +** @brief Path command buffer attribute structure.
  145282. +**
  145283. +** The gcsPATH_BUFFER_INFO structure contains the specifics about
  145284. +** the layout of the path data command buffer.
  145285. +*/
  145286. +typedef struct _gcsPATH_BUFFER_INFO * gcsPATH_BUFFER_INFO_PTR;
  145287. +typedef struct _gcsPATH_BUFFER_INFO
  145288. +{
  145289. + gctUINT reservedForHead;
  145290. + gctUINT reservedForTail;
  145291. +}
  145292. +gcsPATH_BUFFER_INFO;
  145293. +
  145294. +/**
  145295. +** @ingroup gcoVG
  145296. +**
  145297. +** @brief Definition of the path data container structure.
  145298. +**
  145299. +** The gcsPATH structure defines the layout of the path data container.
  145300. +*/
  145301. +typedef struct _gcsPATH_DATA * gcsPATH_DATA_PTR;
  145302. +typedef struct _gcsPATH_DATA
  145303. +{
  145304. + /* Data container in command buffer format. */
  145305. + gcsCMDBUFFER data;
  145306. +
  145307. + /* Path data type. */
  145308. + gcePATHTYPE dataType;
  145309. +}
  145310. +gcsPATH_DATA;
  145311. +
  145312. +
  145313. +/******************************************************************************\
  145314. +********************************* gcoHAL Object ********************************
  145315. +\******************************************************************************/
  145316. +
  145317. +/* Query path data storage attributes. */
  145318. +gceSTATUS
  145319. +gcoHAL_QueryPathStorage(
  145320. + IN gcoHAL Hal,
  145321. + OUT gcsPATH_BUFFER_INFO_PTR Information
  145322. + );
  145323. +
  145324. +/* Associate a completion signal with the command buffer. */
  145325. +gceSTATUS
  145326. +gcoHAL_AssociateCompletion(
  145327. + IN gcoHAL Hal,
  145328. + IN gcsPATH_DATA_PTR PathData
  145329. + );
  145330. +
  145331. +/* Release the current command buffer completion signal. */
  145332. +gceSTATUS
  145333. +gcoHAL_DeassociateCompletion(
  145334. + IN gcoHAL Hal,
  145335. + IN gcsPATH_DATA_PTR PathData
  145336. + );
  145337. +
  145338. +/* Verify whether the command buffer is still in use. */
  145339. +gceSTATUS
  145340. +gcoHAL_CheckCompletion(
  145341. + IN gcoHAL Hal,
  145342. + IN gcsPATH_DATA_PTR PathData
  145343. + );
  145344. +
  145345. +/* Wait until the command buffer is no longer in use. */
  145346. +gceSTATUS
  145347. +gcoHAL_WaitCompletion(
  145348. + IN gcoHAL Hal,
  145349. + IN gcsPATH_DATA_PTR PathData
  145350. + );
  145351. +
  145352. +/* Flush the pixel cache. */
  145353. +gceSTATUS
  145354. +gcoHAL_Flush(
  145355. + IN gcoHAL Hal
  145356. + );
  145357. +
  145358. +/* Split a harwdare address into pool and offset. */
  145359. +gceSTATUS
  145360. +gcoHAL_SplitAddress(
  145361. + IN gcoHAL Hal,
  145362. + IN gctUINT32 Address,
  145363. + OUT gcePOOL * Pool,
  145364. + OUT gctUINT32 * Offset
  145365. + );
  145366. +
  145367. +/* Combine pool and offset into a harwdare address. */
  145368. +gceSTATUS
  145369. +gcoHAL_CombineAddress(
  145370. + IN gcoHAL Hal,
  145371. + IN gcePOOL Pool,
  145372. + IN gctUINT32 Offset,
  145373. + OUT gctUINT32 * Address
  145374. + );
  145375. +
  145376. +/* Schedule to free linear video memory allocated. */
  145377. +gceSTATUS
  145378. +gcoHAL_ScheduleVideoMemory(
  145379. + IN gcoHAL Hal,
  145380. + IN gctUINT64 Node
  145381. + );
  145382. +
  145383. +/* Free linear video memory allocated with gcoHAL_AllocateLinearVideoMemory. */
  145384. +gceSTATUS
  145385. +gcoHAL_FreeVideoMemory(
  145386. + IN gcoHAL Hal,
  145387. + IN gctUINT64 Node
  145388. + );
  145389. +
  145390. +/* Query command buffer attributes. */
  145391. +gceSTATUS
  145392. +gcoHAL_QueryCommandBuffer(
  145393. + IN gcoHAL Hal,
  145394. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  145395. + );
  145396. +/* Allocate and lock linear video memory. */
  145397. +gceSTATUS
  145398. +gcoHAL_AllocateLinearVideoMemory(
  145399. + IN gcoHAL Hal,
  145400. + IN gctUINT Size,
  145401. + IN gctUINT Alignment,
  145402. + IN gcePOOL Pool,
  145403. + OUT gctUINT64 * Node,
  145404. + OUT gctUINT32 * Address,
  145405. + OUT gctPOINTER * Memory
  145406. + );
  145407. +
  145408. +/* Align the specified size accordingly to the hardware requirements. */
  145409. +gceSTATUS
  145410. +gcoHAL_GetAlignedSurfaceSize(
  145411. + IN gcoHAL Hal,
  145412. + IN gceSURF_TYPE Type,
  145413. + IN OUT gctUINT32_PTR Width,
  145414. + IN OUT gctUINT32_PTR Height
  145415. + );
  145416. +
  145417. +gceSTATUS
  145418. +gcoHAL_ReserveTask(
  145419. + IN gcoHAL Hal,
  145420. + IN gceBLOCK Block,
  145421. + IN gctUINT TaskCount,
  145422. + IN gctSIZE_T Bytes,
  145423. + OUT gctPOINTER * Memory
  145424. + );
  145425. +/******************************************************************************\
  145426. +********************************** gcoVG Object ********************************
  145427. +\******************************************************************************/
  145428. +
  145429. +/** @defgroup gcoVG gcoVG
  145430. +**
  145431. +** The gcoVG object abstracts the VG hardware pipe.
  145432. +*/
  145433. +
  145434. +gctBOOL
  145435. +gcoVG_IsMaskSupported(
  145436. + IN gceSURF_FORMAT Format
  145437. + );
  145438. +
  145439. +gctBOOL
  145440. +gcoVG_IsTargetSupported(
  145441. + IN gceSURF_FORMAT Format
  145442. + );
  145443. +
  145444. +gctBOOL
  145445. +gcoVG_IsImageSupported(
  145446. + IN gceSURF_FORMAT Format
  145447. + );
  145448. +
  145449. +gctUINT8 gcoVG_PackColorComponent(
  145450. + gctFLOAT Value
  145451. + );
  145452. +
  145453. +gceSTATUS
  145454. +gcoVG_Construct(
  145455. + IN gcoHAL Hal,
  145456. + OUT gcoVG * Vg
  145457. + );
  145458. +
  145459. +gceSTATUS
  145460. +gcoVG_Destroy(
  145461. + IN gcoVG Vg
  145462. + );
  145463. +
  145464. +gceSTATUS
  145465. +gcoVG_SetTarget(
  145466. + IN gcoVG Vg,
  145467. + IN gcoSURF Target
  145468. + );
  145469. +
  145470. +gceSTATUS
  145471. +gcoVG_UnsetTarget(
  145472. + IN gcoVG Vg,
  145473. + IN gcoSURF Surface
  145474. + );
  145475. +
  145476. +gceSTATUS
  145477. +gcoVG_SetUserToSurface(
  145478. + IN gcoVG Vg,
  145479. + IN gctFLOAT UserToSurface[9]
  145480. + );
  145481. +
  145482. +gceSTATUS
  145483. +gcoVG_SetSurfaceToImage(
  145484. + IN gcoVG Vg,
  145485. + IN gctFLOAT SurfaceToImage[9]
  145486. + );
  145487. +
  145488. +gceSTATUS
  145489. +gcoVG_EnableMask(
  145490. + IN gcoVG Vg,
  145491. + IN gctBOOL Enable
  145492. + );
  145493. +
  145494. +gceSTATUS
  145495. +gcoVG_SetMask(
  145496. + IN gcoVG Vg,
  145497. + IN gcoSURF Mask
  145498. + );
  145499. +
  145500. +gceSTATUS
  145501. +gcoVG_UnsetMask(
  145502. + IN gcoVG Vg,
  145503. + IN gcoSURF Surface
  145504. + );
  145505. +
  145506. +gceSTATUS
  145507. +gcoVG_FlushMask(
  145508. + IN gcoVG Vg
  145509. + );
  145510. +
  145511. +gceSTATUS
  145512. +gcoVG_EnableScissor(
  145513. + IN gcoVG Vg,
  145514. + IN gctBOOL Enable
  145515. + );
  145516. +
  145517. +gceSTATUS
  145518. +gcoVG_SetScissor(
  145519. + IN gcoVG Vg,
  145520. + IN gctSIZE_T RectangleCount,
  145521. + IN gcsVG_RECT_PTR Rectangles
  145522. + );
  145523. +
  145524. +gceSTATUS
  145525. +gcoVG_EnableColorTransform(
  145526. + IN gcoVG Vg,
  145527. + IN gctBOOL Enable
  145528. + );
  145529. +
  145530. +gceSTATUS
  145531. +gcoVG_SetColorTransform(
  145532. + IN gcoVG Vg,
  145533. + IN gctFLOAT ColorTransform[8]
  145534. + );
  145535. +
  145536. +gceSTATUS
  145537. +gcoVG_SetTileFillColor(
  145538. + IN gcoVG Vg,
  145539. + IN gctFLOAT Red,
  145540. + IN gctFLOAT Green,
  145541. + IN gctFLOAT Blue,
  145542. + IN gctFLOAT Alpha
  145543. + );
  145544. +
  145545. +gceSTATUS
  145546. +gcoVG_SetSolidPaint(
  145547. + IN gcoVG Vg,
  145548. + IN gctUINT8 Red,
  145549. + IN gctUINT8 Green,
  145550. + IN gctUINT8 Blue,
  145551. + IN gctUINT8 Alpha
  145552. + );
  145553. +
  145554. +gceSTATUS
  145555. +gcoVG_SetLinearPaint(
  145556. + IN gcoVG Vg,
  145557. + IN gctFLOAT Constant,
  145558. + IN gctFLOAT StepX,
  145559. + IN gctFLOAT StepY
  145560. + );
  145561. +
  145562. +gceSTATUS
  145563. +gcoVG_SetRadialPaint(
  145564. + IN gcoVG Vg,
  145565. + IN gctFLOAT LinConstant,
  145566. + IN gctFLOAT LinStepX,
  145567. + IN gctFLOAT LinStepY,
  145568. + IN gctFLOAT RadConstant,
  145569. + IN gctFLOAT RadStepX,
  145570. + IN gctFLOAT RadStepY,
  145571. + IN gctFLOAT RadStepXX,
  145572. + IN gctFLOAT RadStepYY,
  145573. + IN gctFLOAT RadStepXY
  145574. + );
  145575. +
  145576. +gceSTATUS
  145577. +gcoVG_SetPatternPaint(
  145578. + IN gcoVG Vg,
  145579. + IN gctFLOAT UConstant,
  145580. + IN gctFLOAT UStepX,
  145581. + IN gctFLOAT UStepY,
  145582. + IN gctFLOAT VConstant,
  145583. + IN gctFLOAT VStepX,
  145584. + IN gctFLOAT VStepY,
  145585. + IN gctBOOL Linear
  145586. + );
  145587. +
  145588. +gceSTATUS
  145589. +gcoVG_SetColorRamp(
  145590. + IN gcoVG Vg,
  145591. + IN gcoSURF ColorRamp,
  145592. + IN gceTILE_MODE ColorRampSpreadMode
  145593. + );
  145594. +
  145595. +gceSTATUS
  145596. +gcoVG_SetPattern(
  145597. + IN gcoVG Vg,
  145598. + IN gcoSURF Pattern,
  145599. + IN gceTILE_MODE TileMode,
  145600. + IN gceIMAGE_FILTER Filter
  145601. + );
  145602. +
  145603. +gceSTATUS
  145604. +gcoVG_SetImageMode(
  145605. + IN gcoVG Vg,
  145606. + IN gceVG_IMAGE Mode
  145607. + );
  145608. +
  145609. +gceSTATUS
  145610. +gcoVG_SetBlendMode(
  145611. + IN gcoVG Vg,
  145612. + IN gceVG_BLEND Mode
  145613. + );
  145614. +
  145615. +gceSTATUS
  145616. +gcoVG_SetRenderingQuality(
  145617. + IN gcoVG Vg,
  145618. + IN gceRENDER_QUALITY Quality
  145619. + );
  145620. +
  145621. +gceSTATUS
  145622. +gcoVG_SetFillRule(
  145623. + IN gcoVG Vg,
  145624. + IN gceFILL_RULE FillRule
  145625. + );
  145626. +
  145627. +gceSTATUS
  145628. +gcoVG_FinalizePath(
  145629. + IN gcoVG Vg,
  145630. + IN gcsPATH_DATA_PTR PathData
  145631. + );
  145632. +
  145633. +gceSTATUS
  145634. +gcoVG_Clear(
  145635. + IN gcoVG Vg,
  145636. + IN gctINT X,
  145637. + IN gctINT Y,
  145638. + IN gctINT Width,
  145639. + IN gctINT Height
  145640. + );
  145641. +
  145642. +gceSTATUS
  145643. +gcoVG_DrawPath(
  145644. + IN gcoVG Vg,
  145645. + IN gcsPATH_DATA_PTR PathData,
  145646. + IN gctFLOAT Scale,
  145647. + IN gctFLOAT Bias,
  145648. + IN gctBOOL SoftwareTesselation
  145649. + );
  145650. +
  145651. +gceSTATUS
  145652. +gcoVG_DrawImage(
  145653. + IN gcoVG Vg,
  145654. + IN gcoSURF Source,
  145655. + IN gcsPOINT_PTR SourceOrigin,
  145656. + IN gcsPOINT_PTR TargetOrigin,
  145657. + IN gcsSIZE_PTR SourceSize,
  145658. + IN gctINT SourceX,
  145659. + IN gctINT SourceY,
  145660. + IN gctINT TargetX,
  145661. + IN gctINT TargetY,
  145662. + IN gctINT Width,
  145663. + IN gctINT Height,
  145664. + IN gctBOOL Mask
  145665. + );
  145666. +
  145667. +gceSTATUS
  145668. +gcoVG_TesselateImage(
  145669. + IN gcoVG Vg,
  145670. + IN gcoSURF Image,
  145671. + IN gcsVG_RECT_PTR Rectangle,
  145672. + IN gceIMAGE_FILTER Filter,
  145673. + IN gctBOOL Mask,
  145674. + IN gctBOOL SoftwareTesselation
  145675. + );
  145676. +
  145677. +gceSTATUS
  145678. +gcoVG_Blit(
  145679. + IN gcoVG Vg,
  145680. + IN gcoSURF Source,
  145681. + IN gcoSURF Target,
  145682. + IN gcsVG_RECT_PTR SrcRect,
  145683. + IN gcsVG_RECT_PTR TrgRect,
  145684. + IN gceIMAGE_FILTER Filter,
  145685. + IN gceVG_BLEND Mode
  145686. + );
  145687. +
  145688. +gceSTATUS
  145689. +gcoVG_ColorMatrix(
  145690. + IN gcoVG Vg,
  145691. + IN gcoSURF Source,
  145692. + IN gcoSURF Target,
  145693. + IN const gctFLOAT * Matrix,
  145694. + IN gceCHANNEL ColorChannels,
  145695. + IN gctBOOL FilterLinear,
  145696. + IN gctBOOL FilterPremultiplied,
  145697. + IN gcsPOINT_PTR SourceOrigin,
  145698. + IN gcsPOINT_PTR TargetOrigin,
  145699. + IN gctINT Width,
  145700. + IN gctINT Height
  145701. + );
  145702. +
  145703. +gceSTATUS
  145704. +gcoVG_SeparableConvolve(
  145705. + IN gcoVG Vg,
  145706. + IN gcoSURF Source,
  145707. + IN gcoSURF Target,
  145708. + IN gctINT KernelWidth,
  145709. + IN gctINT KernelHeight,
  145710. + IN gctINT ShiftX,
  145711. + IN gctINT ShiftY,
  145712. + IN const gctINT16 * KernelX,
  145713. + IN const gctINT16 * KernelY,
  145714. + IN gctFLOAT Scale,
  145715. + IN gctFLOAT Bias,
  145716. + IN gceTILE_MODE TilingMode,
  145717. + IN gctFLOAT_PTR FillColor,
  145718. + IN gceCHANNEL ColorChannels,
  145719. + IN gctBOOL FilterLinear,
  145720. + IN gctBOOL FilterPremultiplied,
  145721. + IN gcsPOINT_PTR SourceOrigin,
  145722. + IN gcsPOINT_PTR TargetOrigin,
  145723. + IN gcsSIZE_PTR SourceSize,
  145724. + IN gctINT Width,
  145725. + IN gctINT Height
  145726. + );
  145727. +
  145728. +gceSTATUS
  145729. +gcoVG_GaussianBlur(
  145730. + IN gcoVG Vg,
  145731. + IN gcoSURF Source,
  145732. + IN gcoSURF Target,
  145733. + IN gctFLOAT StdDeviationX,
  145734. + IN gctFLOAT StdDeviationY,
  145735. + IN gceTILE_MODE TilingMode,
  145736. + IN gctFLOAT_PTR FillColor,
  145737. + IN gceCHANNEL ColorChannels,
  145738. + IN gctBOOL FilterLinear,
  145739. + IN gctBOOL FilterPremultiplied,
  145740. + IN gcsPOINT_PTR SourceOrigin,
  145741. + IN gcsPOINT_PTR TargetOrigin,
  145742. + IN gcsSIZE_PTR SourceSize,
  145743. + IN gctINT Width,
  145744. + IN gctINT Height
  145745. + );
  145746. +
  145747. +gceSTATUS
  145748. +gcoVG_EnableDither(
  145749. + IN gcoVG Vg,
  145750. + IN gctBOOL Enable
  145751. + );
  145752. +
  145753. +#ifdef __cplusplus
  145754. +}
  145755. +#endif
  145756. +
  145757. +#endif /* __gc_hal_vg_h_ */
  145758. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
  145759. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h 1969-12-31 18:00:00.000000000 -0600
  145760. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h 2014-12-08 00:31:53.468418001 -0600
  145761. @@ -0,0 +1,965 @@
  145762. +/****************************************************************************
  145763. +*
  145764. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  145765. +*
  145766. +* This program is free software; you can redistribute it and/or modify
  145767. +* it under the terms of the GNU General Public License as published by
  145768. +* the Free Software Foundation; either version 2 of the license, or
  145769. +* (at your option) any later version.
  145770. +*
  145771. +* This program is distributed in the hope that it will be useful,
  145772. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  145773. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  145774. +* GNU General Public License for more details.
  145775. +*
  145776. +* You should have received a copy of the GNU General Public License
  145777. +* along with this program; if not write to the Free Software
  145778. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  145779. +*
  145780. +*****************************************************************************/
  145781. +
  145782. +
  145783. +#ifndef __gc_hal_enum_h_
  145784. +#define __gc_hal_enum_h_
  145785. +
  145786. +#ifdef __cplusplus
  145787. +extern "C" {
  145788. +#endif
  145789. +
  145790. +/* Chip models. */
  145791. +typedef enum _gceCHIPMODEL
  145792. +{
  145793. + gcv300 = 0x0300,
  145794. + gcv320 = 0x0320,
  145795. + gcv350 = 0x0350,
  145796. + gcv355 = 0x0355,
  145797. + gcv400 = 0x0400,
  145798. + gcv410 = 0x0410,
  145799. + gcv420 = 0x0420,
  145800. + gcv450 = 0x0450,
  145801. + gcv500 = 0x0500,
  145802. + gcv530 = 0x0530,
  145803. + gcv600 = 0x0600,
  145804. + gcv700 = 0x0700,
  145805. + gcv800 = 0x0800,
  145806. + gcv860 = 0x0860,
  145807. + gcv880 = 0x0880,
  145808. + gcv1000 = 0x1000,
  145809. + gcv2000 = 0x2000,
  145810. + gcv2100 = 0x2100,
  145811. + gcv4000 = 0x4000,
  145812. +}
  145813. +gceCHIPMODEL;
  145814. +
  145815. +/* Chip features. */
  145816. +typedef enum _gceFEATURE
  145817. +{
  145818. + gcvFEATURE_PIPE_2D = 0,
  145819. + gcvFEATURE_PIPE_3D,
  145820. + gcvFEATURE_PIPE_VG,
  145821. + gcvFEATURE_DC,
  145822. + gcvFEATURE_HIGH_DYNAMIC_RANGE,
  145823. + gcvFEATURE_MODULE_CG,
  145824. + gcvFEATURE_MIN_AREA,
  145825. + gcvFEATURE_BUFFER_INTERLEAVING,
  145826. + gcvFEATURE_BYTE_WRITE_2D,
  145827. + gcvFEATURE_ENDIANNESS_CONFIG,
  145828. + gcvFEATURE_DUAL_RETURN_BUS,
  145829. + gcvFEATURE_DEBUG_MODE,
  145830. + gcvFEATURE_YUY2_RENDER_TARGET,
  145831. + gcvFEATURE_FRAGMENT_PROCESSOR,
  145832. + gcvFEATURE_2DPE20,
  145833. + gcvFEATURE_FAST_CLEAR,
  145834. + gcvFEATURE_YUV420_TILER,
  145835. + gcvFEATURE_YUY2_AVERAGING,
  145836. + gcvFEATURE_FLIP_Y,
  145837. + gcvFEATURE_EARLY_Z,
  145838. + gcvFEATURE_Z_COMPRESSION,
  145839. + gcvFEATURE_MSAA,
  145840. + gcvFEATURE_SPECIAL_ANTI_ALIASING,
  145841. + gcvFEATURE_SPECIAL_MSAA_LOD,
  145842. + gcvFEATURE_422_TEXTURE_COMPRESSION,
  145843. + gcvFEATURE_DXT_TEXTURE_COMPRESSION,
  145844. + gcvFEATURE_ETC1_TEXTURE_COMPRESSION,
  145845. + gcvFEATURE_CORRECT_TEXTURE_CONVERTER,
  145846. + gcvFEATURE_TEXTURE_8K,
  145847. + gcvFEATURE_SCALER,
  145848. + gcvFEATURE_YUV420_SCALER,
  145849. + gcvFEATURE_SHADER_HAS_W,
  145850. + gcvFEATURE_SHADER_HAS_SIGN,
  145851. + gcvFEATURE_SHADER_HAS_FLOOR,
  145852. + gcvFEATURE_SHADER_HAS_CEIL,
  145853. + gcvFEATURE_SHADER_HAS_SQRT,
  145854. + gcvFEATURE_SHADER_HAS_TRIG,
  145855. + gcvFEATURE_VAA,
  145856. + gcvFEATURE_HZ,
  145857. + gcvFEATURE_CORRECT_STENCIL,
  145858. + gcvFEATURE_VG20,
  145859. + gcvFEATURE_VG_FILTER,
  145860. + gcvFEATURE_VG21,
  145861. + gcvFEATURE_VG_DOUBLE_BUFFER,
  145862. + gcvFEATURE_MC20,
  145863. + gcvFEATURE_SUPER_TILED,
  145864. + gcvFEATURE_2D_FILTERBLIT_PLUS_ALPHABLEND,
  145865. + gcvFEATURE_2D_DITHER,
  145866. + gcvFEATURE_2D_A8_TARGET,
  145867. + gcvFEATURE_2D_FILTERBLIT_FULLROTATION,
  145868. + gcvFEATURE_2D_BITBLIT_FULLROTATION,
  145869. + gcvFEATURE_WIDE_LINE,
  145870. + gcvFEATURE_FC_FLUSH_STALL,
  145871. + gcvFEATURE_FULL_DIRECTFB,
  145872. + gcvFEATURE_HALF_FLOAT_PIPE,
  145873. + gcvFEATURE_LINE_LOOP,
  145874. + gcvFEATURE_2D_YUV_BLIT,
  145875. + gcvFEATURE_2D_TILING,
  145876. + gcvFEATURE_NON_POWER_OF_TWO,
  145877. + gcvFEATURE_3D_TEXTURE,
  145878. + gcvFEATURE_TEXTURE_ARRAY,
  145879. + gcvFEATURE_TILE_FILLER,
  145880. + gcvFEATURE_LOGIC_OP,
  145881. + gcvFEATURE_COMPOSITION,
  145882. + gcvFEATURE_MIXED_STREAMS,
  145883. + gcvFEATURE_2D_MULTI_SOURCE_BLT,
  145884. + gcvFEATURE_END_EVENT,
  145885. + gcvFEATURE_VERTEX_10_10_10_2,
  145886. + gcvFEATURE_TEXTURE_10_10_10_2,
  145887. + gcvFEATURE_TEXTURE_ANISOTROPIC_FILTERING,
  145888. + gcvFEATURE_TEXTURE_FLOAT_HALF_FLOAT,
  145889. + gcvFEATURE_2D_ROTATION_STALL_FIX,
  145890. + gcvFEATURE_2D_MULTI_SOURCE_BLT_EX,
  145891. + gcvFEATURE_BUG_FIXES10,
  145892. + gcvFEATURE_2D_MINOR_TILING,
  145893. + /* Supertiled compressed textures are supported. */
  145894. + gcvFEATURE_TEX_COMPRRESSION_SUPERTILED,
  145895. + gcvFEATURE_FAST_MSAA,
  145896. + gcvFEATURE_BUG_FIXED_INDEXED_TRIANGLE_STRIP,
  145897. + gcvFEATURE_TEXTURE_TILED_READ,
  145898. + gcvFEATURE_DEPTH_BIAS_FIX,
  145899. + gcvFEATURE_RECT_PRIMITIVE,
  145900. + gcvFEATURE_BUG_FIXES11,
  145901. + gcvFEATURE_SUPERTILED_TEXTURE,
  145902. + gcvFEATURE_2D_NO_COLORBRUSH_INDEX8,
  145903. + gcvFEATURE_RS_YUV_TARGET,
  145904. + gcvFEATURE_2D_FC_SOURCE,
  145905. + gcvFEATURE_PE_DITHER_FIX,
  145906. + gcvFEATURE_2D_YUV_SEPARATE_STRIDE,
  145907. + gcvFEATURE_FRUSTUM_CLIP_FIX,
  145908. + gcvFEATURE_TEXTURE_LINEAR,
  145909. + gcvFEATURE_TEXTURE_YUV_ASSEMBLER,
  145910. + gcvFEATURE_SHADER_HAS_INSTRUCTION_CACHE,
  145911. + gcvFEATURE_DYNAMIC_FREQUENCY_SCALING,
  145912. + gcvFEATURE_BUGFIX15,
  145913. + gcvFEATURE_2D_GAMMA,
  145914. + gcvFEATURE_2D_COLOR_SPACE_CONVERSION,
  145915. + gcvFEATURE_2D_SUPER_TILE_VERSION,
  145916. + gcvFEATURE_2D_MIRROR_EXTENSION,
  145917. + gcvFEATURE_2D_SUPER_TILE_V1,
  145918. + gcvFEATURE_2D_SUPER_TILE_V2,
  145919. + gcvFEATURE_2D_SUPER_TILE_V3,
  145920. + gcvFEATURE_2D_MULTI_SOURCE_BLT_EX2,
  145921. + gcvFEATURE_ELEMENT_INDEX_UINT,
  145922. + gcvFEATURE_2D_COMPRESSION,
  145923. + gcvFEATURE_2D_OPF_YUV_OUTPUT,
  145924. + gcvFEATURE_2D_MULTI_SRC_BLT_TO_UNIFIED_DST_RECT,
  145925. + gcvFEATURE_2D_YUV_MODE,
  145926. + gcvFEATURE_DECOMPRESS_Z16,
  145927. + gcvFEATURE_LINEAR_RENDER_TARGET,
  145928. + gcvFEATURE_BUG_FIXES8,
  145929. + gcvFEATURE_HALTI2,
  145930. + gcvFEATURE_MMU,
  145931. +}
  145932. +gceFEATURE;
  145933. +
  145934. +/* Chip Power Status. */
  145935. +typedef enum _gceCHIPPOWERSTATE
  145936. +{
  145937. + gcvPOWER_ON = 0,
  145938. + gcvPOWER_OFF,
  145939. + gcvPOWER_IDLE,
  145940. + gcvPOWER_SUSPEND,
  145941. + gcvPOWER_SUSPEND_ATPOWERON,
  145942. + gcvPOWER_OFF_ATPOWERON,
  145943. + gcvPOWER_IDLE_BROADCAST,
  145944. + gcvPOWER_SUSPEND_BROADCAST,
  145945. + gcvPOWER_OFF_BROADCAST,
  145946. + gcvPOWER_OFF_RECOVERY,
  145947. + gcvPOWER_OFF_TIMEOUT,
  145948. + gcvPOWER_ON_AUTO
  145949. +}
  145950. +gceCHIPPOWERSTATE;
  145951. +
  145952. +/* CPU cache operations */
  145953. +typedef enum _gceCACHEOPERATION
  145954. +{
  145955. + gcvCACHE_CLEAN = 0x01,
  145956. + gcvCACHE_INVALIDATE = 0x02,
  145957. + gcvCACHE_FLUSH = gcvCACHE_CLEAN | gcvCACHE_INVALIDATE,
  145958. + gcvCACHE_MEMORY_BARRIER = 0x04
  145959. +}
  145960. +gceCACHEOPERATION;
  145961. +
  145962. +/* Surface types. */
  145963. +typedef enum _gceSURF_TYPE
  145964. +{
  145965. + gcvSURF_TYPE_UNKNOWN = 0,
  145966. + gcvSURF_INDEX,
  145967. + gcvSURF_VERTEX,
  145968. + gcvSURF_TEXTURE,
  145969. + gcvSURF_RENDER_TARGET,
  145970. + gcvSURF_DEPTH,
  145971. + gcvSURF_BITMAP,
  145972. + gcvSURF_TILE_STATUS,
  145973. + gcvSURF_IMAGE,
  145974. + gcvSURF_MASK,
  145975. + gcvSURF_SCISSOR,
  145976. + gcvSURF_HIERARCHICAL_DEPTH,
  145977. + gcvSURF_NUM_TYPES, /* Make sure this is the last one! */
  145978. +
  145979. + /* Combinations. */
  145980. + gcvSURF_NO_TILE_STATUS = 0x100,
  145981. + gcvSURF_NO_VIDMEM = 0x200, /* Used to allocate surfaces with no underlying vidmem node.
  145982. + In Android, vidmem node is allocated by another process. */
  145983. + gcvSURF_CACHEABLE = 0x400, /* Used to allocate a cacheable surface */
  145984. + gcvSURF_FLIP = 0x800, /* The Resolve Target the will been flip resolve from RT */
  145985. + gcvSURF_TILE_STATUS_DIRTY = 0x1000, /* Init tile status to all dirty */
  145986. +
  145987. + gcvSURF_LINEAR = 0x2000,
  145988. + gcvSURF_VG = 0x4000,
  145989. +
  145990. + gcvSURF_TEXTURE_LINEAR = gcvSURF_TEXTURE
  145991. + | gcvSURF_LINEAR,
  145992. +
  145993. + gcvSURF_RENDER_TARGET_NO_TILE_STATUS = gcvSURF_RENDER_TARGET
  145994. + | gcvSURF_NO_TILE_STATUS,
  145995. +
  145996. + gcvSURF_RENDER_TARGET_TS_DIRTY = gcvSURF_RENDER_TARGET
  145997. + | gcvSURF_TILE_STATUS_DIRTY,
  145998. +
  145999. + gcvSURF_DEPTH_NO_TILE_STATUS = gcvSURF_DEPTH
  146000. + | gcvSURF_NO_TILE_STATUS,
  146001. +
  146002. + gcvSURF_DEPTH_TS_DIRTY = gcvSURF_DEPTH
  146003. + | gcvSURF_TILE_STATUS_DIRTY,
  146004. +
  146005. + /* Supported surface types with no vidmem node. */
  146006. + gcvSURF_BITMAP_NO_VIDMEM = gcvSURF_BITMAP
  146007. + | gcvSURF_NO_VIDMEM,
  146008. +
  146009. + gcvSURF_TEXTURE_NO_VIDMEM = gcvSURF_TEXTURE
  146010. + | gcvSURF_NO_VIDMEM,
  146011. +
  146012. + /* Cacheable surface types with no vidmem node. */
  146013. + gcvSURF_CACHEABLE_BITMAP_NO_VIDMEM = gcvSURF_BITMAP_NO_VIDMEM
  146014. + | gcvSURF_CACHEABLE,
  146015. +
  146016. + gcvSURF_CACHEABLE_BITMAP = gcvSURF_BITMAP
  146017. + | gcvSURF_CACHEABLE,
  146018. +
  146019. + gcvSURF_FLIP_BITMAP = gcvSURF_BITMAP
  146020. + | gcvSURF_FLIP,
  146021. +}
  146022. +gceSURF_TYPE;
  146023. +
  146024. +typedef enum _gceSURF_USAGE
  146025. +{
  146026. + gcvSURF_USAGE_UNKNOWN,
  146027. + gcvSURF_USAGE_RESOLVE_AFTER_CPU,
  146028. + gcvSURF_USAGE_RESOLVE_AFTER_3D
  146029. +}
  146030. +gceSURF_USAGE;
  146031. +
  146032. +typedef enum _gceSURF_COLOR_TYPE
  146033. +{
  146034. + gcvSURF_COLOR_UNKNOWN = 0,
  146035. + gcvSURF_COLOR_LINEAR = 0x01,
  146036. + gcvSURF_COLOR_ALPHA_PRE = 0x02,
  146037. +}
  146038. +gceSURF_COLOR_TYPE;
  146039. +
  146040. +/* Rotation. */
  146041. +typedef enum _gceSURF_ROTATION
  146042. +{
  146043. + gcvSURF_0_DEGREE = 0,
  146044. + gcvSURF_90_DEGREE,
  146045. + gcvSURF_180_DEGREE,
  146046. + gcvSURF_270_DEGREE,
  146047. + gcvSURF_FLIP_X,
  146048. + gcvSURF_FLIP_Y,
  146049. +
  146050. + gcvSURF_POST_FLIP_X = 0x40000000,
  146051. + gcvSURF_POST_FLIP_Y = 0x80000000,
  146052. +}
  146053. +gceSURF_ROTATION;
  146054. +
  146055. +typedef enum _gceMIPMAP_IMAGE_FORMAT
  146056. +{
  146057. + gcvUNKNOWN_MIPMAP_IMAGE_FORMAT = -2
  146058. +}
  146059. +gceMIPMAP_IMAGE_FORMAT;
  146060. +
  146061. +
  146062. +/* Surface formats. */
  146063. +typedef enum _gceSURF_FORMAT
  146064. +{
  146065. + /* Unknown format. */
  146066. + gcvSURF_UNKNOWN = 0,
  146067. +
  146068. + /* Palettized formats. */
  146069. + gcvSURF_INDEX1 = 100,
  146070. + gcvSURF_INDEX4,
  146071. + gcvSURF_INDEX8,
  146072. +
  146073. + /* RGB formats. */
  146074. + gcvSURF_A2R2G2B2 = 200,
  146075. + gcvSURF_R3G3B2,
  146076. + gcvSURF_A8R3G3B2,
  146077. + gcvSURF_X4R4G4B4,
  146078. + gcvSURF_A4R4G4B4,
  146079. + gcvSURF_R4G4B4A4,
  146080. + gcvSURF_X1R5G5B5,
  146081. + gcvSURF_A1R5G5B5,
  146082. + gcvSURF_R5G5B5A1,
  146083. + gcvSURF_R5G6B5,
  146084. + gcvSURF_R8G8B8,
  146085. + gcvSURF_X8R8G8B8,
  146086. + gcvSURF_A8R8G8B8,
  146087. + gcvSURF_R8G8B8A8,
  146088. + gcvSURF_G8R8G8B8,
  146089. + gcvSURF_R8G8B8G8,
  146090. + gcvSURF_X2R10G10B10,
  146091. + gcvSURF_A2R10G10B10,
  146092. + gcvSURF_X12R12G12B12,
  146093. + gcvSURF_A12R12G12B12,
  146094. + gcvSURF_X16R16G16B16,
  146095. + gcvSURF_A16R16G16B16,
  146096. + gcvSURF_A32R32G32B32,
  146097. + gcvSURF_R8G8B8X8,
  146098. + gcvSURF_R5G5B5X1,
  146099. + gcvSURF_R4G4B4X4,
  146100. +
  146101. + /* BGR formats. */
  146102. + gcvSURF_A4B4G4R4 = 300,
  146103. + gcvSURF_A1B5G5R5,
  146104. + gcvSURF_B5G6R5,
  146105. + gcvSURF_B8G8R8,
  146106. + gcvSURF_B16G16R16,
  146107. + gcvSURF_X8B8G8R8,
  146108. + gcvSURF_A8B8G8R8,
  146109. + gcvSURF_A2B10G10R10,
  146110. + gcvSURF_X16B16G16R16,
  146111. + gcvSURF_A16B16G16R16,
  146112. + gcvSURF_B32G32R32,
  146113. + gcvSURF_X32B32G32R32,
  146114. + gcvSURF_A32B32G32R32,
  146115. + gcvSURF_B4G4R4A4,
  146116. + gcvSURF_B5G5R5A1,
  146117. + gcvSURF_B8G8R8X8,
  146118. + gcvSURF_B8G8R8A8,
  146119. + gcvSURF_X4B4G4R4,
  146120. + gcvSURF_X1B5G5R5,
  146121. + gcvSURF_B4G4R4X4,
  146122. + gcvSURF_B5G5R5X1,
  146123. + gcvSURF_X2B10G10R10,
  146124. +
  146125. + /* Compressed formats. */
  146126. + gcvSURF_DXT1 = 400,
  146127. + gcvSURF_DXT2,
  146128. + gcvSURF_DXT3,
  146129. + gcvSURF_DXT4,
  146130. + gcvSURF_DXT5,
  146131. + gcvSURF_CXV8U8,
  146132. + gcvSURF_ETC1,
  146133. + gcvSURF_R11_EAC,
  146134. + gcvSURF_SIGNED_R11_EAC,
  146135. + gcvSURF_RG11_EAC,
  146136. + gcvSURF_SIGNED_RG11_EAC,
  146137. + gcvSURF_RGB8_ETC2,
  146138. + gcvSURF_SRGB8_ETC2,
  146139. + gcvSURF_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
  146140. + gcvSURF_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
  146141. + gcvSURF_RGBA8_ETC2_EAC,
  146142. + gcvSURF_SRGB8_ALPHA8_ETC2_EAC,
  146143. +
  146144. + /* YUV formats. */
  146145. + gcvSURF_YUY2 = 500,
  146146. + gcvSURF_UYVY,
  146147. + gcvSURF_YV12,
  146148. + gcvSURF_I420,
  146149. + gcvSURF_NV12,
  146150. + gcvSURF_NV21,
  146151. + gcvSURF_NV16,
  146152. + gcvSURF_NV61,
  146153. + gcvSURF_YVYU,
  146154. + gcvSURF_VYUY,
  146155. +
  146156. + /* Depth formats. */
  146157. + gcvSURF_D16 = 600,
  146158. + gcvSURF_D24S8,
  146159. + gcvSURF_D32,
  146160. + gcvSURF_D24X8,
  146161. +
  146162. + /* Alpha formats. */
  146163. + gcvSURF_A4 = 700,
  146164. + gcvSURF_A8,
  146165. + gcvSURF_A12,
  146166. + gcvSURF_A16,
  146167. + gcvSURF_A32,
  146168. + gcvSURF_A1,
  146169. +
  146170. + /* Luminance formats. */
  146171. + gcvSURF_L4 = 800,
  146172. + gcvSURF_L8,
  146173. + gcvSURF_L12,
  146174. + gcvSURF_L16,
  146175. + gcvSURF_L32,
  146176. + gcvSURF_L1,
  146177. +
  146178. + /* Alpha/Luminance formats. */
  146179. + gcvSURF_A4L4 = 900,
  146180. + gcvSURF_A2L6,
  146181. + gcvSURF_A8L8,
  146182. + gcvSURF_A4L12,
  146183. + gcvSURF_A12L12,
  146184. + gcvSURF_A16L16,
  146185. +
  146186. + /* Bump formats. */
  146187. + gcvSURF_L6V5U5 = 1000,
  146188. + gcvSURF_V8U8,
  146189. + gcvSURF_X8L8V8U8,
  146190. + gcvSURF_Q8W8V8U8,
  146191. + gcvSURF_A2W10V10U10,
  146192. + gcvSURF_V16U16,
  146193. + gcvSURF_Q16W16V16U16,
  146194. +
  146195. + /* R/RG/RA formats. */
  146196. + gcvSURF_R8 = 1100,
  146197. + gcvSURF_X8R8,
  146198. + gcvSURF_G8R8,
  146199. + gcvSURF_X8G8R8,
  146200. + gcvSURF_A8R8,
  146201. + gcvSURF_R16,
  146202. + gcvSURF_X16R16,
  146203. + gcvSURF_G16R16,
  146204. + gcvSURF_X16G16R16,
  146205. + gcvSURF_A16R16,
  146206. + gcvSURF_R32,
  146207. + gcvSURF_X32R32,
  146208. + gcvSURF_G32R32,
  146209. + gcvSURF_X32G32R32,
  146210. + gcvSURF_A32R32,
  146211. + gcvSURF_RG16,
  146212. +
  146213. + /* Floating point formats. */
  146214. + gcvSURF_R16F = 1200,
  146215. + gcvSURF_X16R16F,
  146216. + gcvSURF_G16R16F,
  146217. + gcvSURF_X16G16R16F,
  146218. + gcvSURF_B16G16R16F,
  146219. + gcvSURF_X16B16G16R16F,
  146220. + gcvSURF_A16B16G16R16F,
  146221. + gcvSURF_R32F,
  146222. + gcvSURF_X32R32F,
  146223. + gcvSURF_G32R32F,
  146224. + gcvSURF_X32G32R32F,
  146225. + gcvSURF_B32G32R32F,
  146226. + gcvSURF_X32B32G32R32F,
  146227. + gcvSURF_A32B32G32R32F,
  146228. + gcvSURF_A16F,
  146229. + gcvSURF_L16F,
  146230. + gcvSURF_A16L16F,
  146231. + gcvSURF_A16R16F,
  146232. + gcvSURF_A32F,
  146233. + gcvSURF_L32F,
  146234. + gcvSURF_A32L32F,
  146235. + gcvSURF_A32R32F,
  146236. +
  146237. +}
  146238. +gceSURF_FORMAT;
  146239. +
  146240. +/* Pixel swizzle modes. */
  146241. +typedef enum _gceSURF_SWIZZLE
  146242. +{
  146243. + gcvSURF_NOSWIZZLE = 0,
  146244. + gcvSURF_ARGB,
  146245. + gcvSURF_ABGR,
  146246. + gcvSURF_RGBA,
  146247. + gcvSURF_BGRA
  146248. +}
  146249. +gceSURF_SWIZZLE;
  146250. +
  146251. +/* Transparency modes. */
  146252. +typedef enum _gceSURF_TRANSPARENCY
  146253. +{
  146254. + /* Valid only for PE 1.0 */
  146255. + gcvSURF_OPAQUE = 0,
  146256. + gcvSURF_SOURCE_MATCH,
  146257. + gcvSURF_SOURCE_MASK,
  146258. + gcvSURF_PATTERN_MASK,
  146259. +}
  146260. +gceSURF_TRANSPARENCY;
  146261. +
  146262. +/* Surface Alignment. */
  146263. +typedef enum _gceSURF_ALIGNMENT
  146264. +{
  146265. + gcvSURF_FOUR = 0,
  146266. + gcvSURF_SIXTEEN,
  146267. + gcvSURF_SUPER_TILED,
  146268. + gcvSURF_SPLIT_TILED,
  146269. + gcvSURF_SPLIT_SUPER_TILED,
  146270. +}
  146271. +gceSURF_ALIGNMENT;
  146272. +
  146273. +
  146274. +/* Surface Addressing. */
  146275. +typedef enum _gceSURF_ADDRESSING
  146276. +{
  146277. + gcvSURF_NO_STRIDE_TILED = 0,
  146278. + gcvSURF_NO_STRIDE_LINEAR,
  146279. + gcvSURF_STRIDE_TILED,
  146280. + gcvSURF_STRIDE_LINEAR
  146281. +}
  146282. +gceSURF_ADDRESSING;
  146283. +
  146284. +/* Transparency modes. */
  146285. +typedef enum _gce2D_TRANSPARENCY
  146286. +{
  146287. + /* Valid only for PE 2.0 */
  146288. + gcv2D_OPAQUE = 0,
  146289. + gcv2D_KEYED,
  146290. + gcv2D_MASKED
  146291. +}
  146292. +gce2D_TRANSPARENCY;
  146293. +
  146294. +/* Mono packing modes. */
  146295. +typedef enum _gceSURF_MONOPACK
  146296. +{
  146297. + gcvSURF_PACKED8 = 0,
  146298. + gcvSURF_PACKED16,
  146299. + gcvSURF_PACKED32,
  146300. + gcvSURF_UNPACKED,
  146301. +}
  146302. +gceSURF_MONOPACK;
  146303. +
  146304. +/* Blending modes. */
  146305. +typedef enum _gceSURF_BLEND_MODE
  146306. +{
  146307. + /* Porter-Duff blending modes. */
  146308. + /* Fsrc Fdst */
  146309. + gcvBLEND_CLEAR = 0, /* 0 0 */
  146310. + gcvBLEND_SRC, /* 1 0 */
  146311. + gcvBLEND_DST, /* 0 1 */
  146312. + gcvBLEND_SRC_OVER_DST, /* 1 1 - Asrc */
  146313. + gcvBLEND_DST_OVER_SRC, /* 1 - Adst 1 */
  146314. + gcvBLEND_SRC_IN_DST, /* Adst 0 */
  146315. + gcvBLEND_DST_IN_SRC, /* 0 Asrc */
  146316. + gcvBLEND_SRC_OUT_DST, /* 1 - Adst 0 */
  146317. + gcvBLEND_DST_OUT_SRC, /* 0 1 - Asrc */
  146318. + gcvBLEND_SRC_ATOP_DST, /* Adst 1 - Asrc */
  146319. + gcvBLEND_DST_ATOP_SRC, /* 1 - Adst Asrc */
  146320. + gcvBLEND_SRC_XOR_DST, /* 1 - Adst 1 - Asrc */
  146321. +
  146322. + /* Special blending modes. */
  146323. + gcvBLEND_SET, /* DST = 1 */
  146324. + gcvBLEND_SUB /* DST = DST * (1 - SRC) */
  146325. +}
  146326. +gceSURF_BLEND_MODE;
  146327. +
  146328. +/* Per-pixel alpha modes. */
  146329. +typedef enum _gceSURF_PIXEL_ALPHA_MODE
  146330. +{
  146331. + gcvSURF_PIXEL_ALPHA_STRAIGHT = 0,
  146332. + gcvSURF_PIXEL_ALPHA_INVERSED
  146333. +}
  146334. +gceSURF_PIXEL_ALPHA_MODE;
  146335. +
  146336. +/* Global alpha modes. */
  146337. +typedef enum _gceSURF_GLOBAL_ALPHA_MODE
  146338. +{
  146339. + gcvSURF_GLOBAL_ALPHA_OFF = 0,
  146340. + gcvSURF_GLOBAL_ALPHA_ON,
  146341. + gcvSURF_GLOBAL_ALPHA_SCALE
  146342. +}
  146343. +gceSURF_GLOBAL_ALPHA_MODE;
  146344. +
  146345. +/* Color component modes for alpha blending. */
  146346. +typedef enum _gceSURF_PIXEL_COLOR_MODE
  146347. +{
  146348. + gcvSURF_COLOR_STRAIGHT = 0,
  146349. + gcvSURF_COLOR_MULTIPLY
  146350. +}
  146351. +gceSURF_PIXEL_COLOR_MODE;
  146352. +
  146353. +/* Color component modes for alpha blending. */
  146354. +typedef enum _gce2D_PIXEL_COLOR_MULTIPLY_MODE
  146355. +{
  146356. + gcv2D_COLOR_MULTIPLY_DISABLE = 0,
  146357. + gcv2D_COLOR_MULTIPLY_ENABLE
  146358. +}
  146359. +gce2D_PIXEL_COLOR_MULTIPLY_MODE;
  146360. +
  146361. +/* Color component modes for alpha blending. */
  146362. +typedef enum _gce2D_GLOBAL_COLOR_MULTIPLY_MODE
  146363. +{
  146364. + gcv2D_GLOBAL_COLOR_MULTIPLY_DISABLE = 0,
  146365. + gcv2D_GLOBAL_COLOR_MULTIPLY_ALPHA,
  146366. + gcv2D_GLOBAL_COLOR_MULTIPLY_COLOR
  146367. +}
  146368. +gce2D_GLOBAL_COLOR_MULTIPLY_MODE;
  146369. +
  146370. +/* Alpha blending factor modes. */
  146371. +typedef enum _gceSURF_BLEND_FACTOR_MODE
  146372. +{
  146373. + gcvSURF_BLEND_ZERO = 0,
  146374. + gcvSURF_BLEND_ONE,
  146375. + gcvSURF_BLEND_STRAIGHT,
  146376. + gcvSURF_BLEND_INVERSED,
  146377. + gcvSURF_BLEND_COLOR,
  146378. + gcvSURF_BLEND_COLOR_INVERSED,
  146379. + gcvSURF_BLEND_SRC_ALPHA_SATURATED,
  146380. + gcvSURF_BLEND_STRAIGHT_NO_CROSS,
  146381. + gcvSURF_BLEND_INVERSED_NO_CROSS,
  146382. + gcvSURF_BLEND_COLOR_NO_CROSS,
  146383. + gcvSURF_BLEND_COLOR_INVERSED_NO_CROSS,
  146384. + gcvSURF_BLEND_SRC_ALPHA_SATURATED_CROSS
  146385. +}
  146386. +gceSURF_BLEND_FACTOR_MODE;
  146387. +
  146388. +/* Alpha blending porter duff rules. */
  146389. +typedef enum _gce2D_PORTER_DUFF_RULE
  146390. +{
  146391. + gcvPD_CLEAR = 0,
  146392. + gcvPD_SRC,
  146393. + gcvPD_SRC_OVER,
  146394. + gcvPD_DST_OVER,
  146395. + gcvPD_SRC_IN,
  146396. + gcvPD_DST_IN,
  146397. + gcvPD_SRC_OUT,
  146398. + gcvPD_DST_OUT,
  146399. + gcvPD_SRC_ATOP,
  146400. + gcvPD_DST_ATOP,
  146401. + gcvPD_ADD,
  146402. + gcvPD_XOR,
  146403. + gcvPD_DST
  146404. +}
  146405. +gce2D_PORTER_DUFF_RULE;
  146406. +
  146407. +/* Alpha blending factor modes. */
  146408. +typedef enum _gce2D_YUV_COLOR_MODE
  146409. +{
  146410. + gcv2D_YUV_601= 0,
  146411. + gcv2D_YUV_709,
  146412. + gcv2D_YUV_USER_DEFINED,
  146413. + gcv2D_YUV_USER_DEFINED_CLAMP,
  146414. +
  146415. + /* Default setting is for src. gcv2D_YUV_DST
  146416. + can be ORed to set dst.
  146417. + */
  146418. + gcv2D_YUV_DST = 0x80000000,
  146419. +}
  146420. +gce2D_YUV_COLOR_MODE;
  146421. +
  146422. +typedef enum _gce2D_COMMAND
  146423. +{
  146424. + gcv2D_CLEAR = 0,
  146425. + gcv2D_LINE,
  146426. + gcv2D_BLT,
  146427. + gcv2D_STRETCH,
  146428. + gcv2D_HOR_FILTER,
  146429. + gcv2D_VER_FILTER,
  146430. + gcv2D_MULTI_SOURCE_BLT,
  146431. +}
  146432. +gce2D_COMMAND;
  146433. +
  146434. +typedef enum _gce2D_TILE_STATUS_CONFIG
  146435. +{
  146436. + gcv2D_TSC_DISABLE = 0,
  146437. + gcv2D_TSC_ENABLE = 0x00000001,
  146438. + gcv2D_TSC_COMPRESSED = 0x00000002,
  146439. + gcv2D_TSC_DOWN_SAMPLER = 0x00000004,
  146440. + gcv2D_TSC_2D_COMPRESSED = 0x00000008,
  146441. +}
  146442. +gce2D_TILE_STATUS_CONFIG;
  146443. +
  146444. +typedef enum _gce2D_QUERY
  146445. +{
  146446. + gcv2D_QUERY_RGB_ADDRESS_MIN_ALIGN = 0,
  146447. + gcv2D_QUERY_RGB_STRIDE_MIN_ALIGN,
  146448. + gcv2D_QUERY_YUV_ADDRESS_MIN_ALIGN,
  146449. + gcv2D_QUERY_YUV_STRIDE_MIN_ALIGN,
  146450. +}
  146451. +gce2D_QUERY;
  146452. +
  146453. +typedef enum _gce2D_SUPER_TILE_VERSION
  146454. +{
  146455. + gcv2D_SUPER_TILE_VERSION_V1 = 1,
  146456. + gcv2D_SUPER_TILE_VERSION_V2 = 2,
  146457. + gcv2D_SUPER_TILE_VERSION_V3 = 3,
  146458. +}
  146459. +gce2D_SUPER_TILE_VERSION;
  146460. +
  146461. +typedef enum _gce2D_STATE
  146462. +{
  146463. + gcv2D_STATE_SPECIAL_FILTER_MIRROR_MODE = 1,
  146464. + gcv2D_STATE_SUPER_TILE_VERSION,
  146465. + gcv2D_STATE_EN_GAMMA,
  146466. + gcv2D_STATE_DE_GAMMA,
  146467. + gcv2D_STATE_MULTI_SRC_BLIT_UNIFIED_DST_RECT,
  146468. + gcv2D_STATE_XRGB_ENABLE,
  146469. +
  146470. + gcv2D_STATE_ARRAY_EN_GAMMA = 0x10001,
  146471. + gcv2D_STATE_ARRAY_DE_GAMMA,
  146472. + gcv2D_STATE_ARRAY_CSC_YUV_TO_RGB,
  146473. + gcv2D_STATE_ARRAY_CSC_RGB_TO_YUV,
  146474. +}
  146475. +gce2D_STATE;
  146476. +
  146477. +#ifndef VIVANTE_NO_3D
  146478. +/* Texture functions. */
  146479. +typedef enum _gceTEXTURE_FUNCTION
  146480. +{
  146481. + gcvTEXTURE_DUMMY = 0,
  146482. + gcvTEXTURE_REPLACE = 0,
  146483. + gcvTEXTURE_MODULATE,
  146484. + gcvTEXTURE_ADD,
  146485. + gcvTEXTURE_ADD_SIGNED,
  146486. + gcvTEXTURE_INTERPOLATE,
  146487. + gcvTEXTURE_SUBTRACT,
  146488. + gcvTEXTURE_DOT3
  146489. +}
  146490. +gceTEXTURE_FUNCTION;
  146491. +
  146492. +/* Texture sources. */
  146493. +typedef enum _gceTEXTURE_SOURCE
  146494. +{
  146495. + gcvCOLOR_FROM_TEXTURE = 0,
  146496. + gcvCOLOR_FROM_CONSTANT_COLOR,
  146497. + gcvCOLOR_FROM_PRIMARY_COLOR,
  146498. + gcvCOLOR_FROM_PREVIOUS_COLOR
  146499. +}
  146500. +gceTEXTURE_SOURCE;
  146501. +
  146502. +/* Texture source channels. */
  146503. +typedef enum _gceTEXTURE_CHANNEL
  146504. +{
  146505. + gcvFROM_COLOR = 0,
  146506. + gcvFROM_ONE_MINUS_COLOR,
  146507. + gcvFROM_ALPHA,
  146508. + gcvFROM_ONE_MINUS_ALPHA
  146509. +}
  146510. +gceTEXTURE_CHANNEL;
  146511. +#endif /* VIVANTE_NO_3D */
  146512. +
  146513. +/* Filter types. */
  146514. +typedef enum _gceFILTER_TYPE
  146515. +{
  146516. + gcvFILTER_SYNC = 0,
  146517. + gcvFILTER_BLUR,
  146518. + gcvFILTER_USER
  146519. +}
  146520. +gceFILTER_TYPE;
  146521. +
  146522. +/* Filter pass types. */
  146523. +typedef enum _gceFILTER_PASS_TYPE
  146524. +{
  146525. + gcvFILTER_HOR_PASS = 0,
  146526. + gcvFILTER_VER_PASS
  146527. +}
  146528. +gceFILTER_PASS_TYPE;
  146529. +
  146530. +/* Endian hints. */
  146531. +typedef enum _gceENDIAN_HINT
  146532. +{
  146533. + gcvENDIAN_NO_SWAP = 0,
  146534. + gcvENDIAN_SWAP_WORD,
  146535. + gcvENDIAN_SWAP_DWORD
  146536. +}
  146537. +gceENDIAN_HINT;
  146538. +
  146539. +/* Tiling modes. */
  146540. +typedef enum _gceTILING
  146541. +{
  146542. + gcvLINEAR = 0,
  146543. + gcvTILED,
  146544. + gcvSUPERTILED,
  146545. + gcvMULTI_TILED,
  146546. + gcvMULTI_SUPERTILED,
  146547. + gcvMINORTILED,
  146548. +}
  146549. +gceTILING;
  146550. +
  146551. +/* 2D pattern type. */
  146552. +typedef enum _gce2D_PATTERN
  146553. +{
  146554. + gcv2D_PATTERN_SOLID = 0,
  146555. + gcv2D_PATTERN_MONO,
  146556. + gcv2D_PATTERN_COLOR,
  146557. + gcv2D_PATTERN_INVALID
  146558. +}
  146559. +gce2D_PATTERN;
  146560. +
  146561. +/* 2D source type. */
  146562. +typedef enum _gce2D_SOURCE
  146563. +{
  146564. + gcv2D_SOURCE_MASKED = 0,
  146565. + gcv2D_SOURCE_MONO,
  146566. + gcv2D_SOURCE_COLOR,
  146567. + gcv2D_SOURCE_INVALID
  146568. +}
  146569. +gce2D_SOURCE;
  146570. +
  146571. +/* Pipes. */
  146572. +typedef enum _gcePIPE_SELECT
  146573. +{
  146574. + gcvPIPE_INVALID = ~0,
  146575. + gcvPIPE_3D = 0,
  146576. + gcvPIPE_2D
  146577. +}
  146578. +gcePIPE_SELECT;
  146579. +
  146580. +/* Hardware type. */
  146581. +typedef enum _gceHARDWARE_TYPE
  146582. +{
  146583. + gcvHARDWARE_INVALID = 0x00,
  146584. + gcvHARDWARE_3D = 0x01,
  146585. + gcvHARDWARE_2D = 0x02,
  146586. + gcvHARDWARE_VG = 0x04,
  146587. +
  146588. + gcvHARDWARE_3D2D = gcvHARDWARE_3D | gcvHARDWARE_2D
  146589. +}
  146590. +gceHARDWARE_TYPE;
  146591. +
  146592. +#define gcdCHIP_COUNT 3
  146593. +
  146594. +typedef enum _gceMMU_MODE
  146595. +{
  146596. + gcvMMU_MODE_1K,
  146597. + gcvMMU_MODE_4K,
  146598. +} gceMMU_MODE;
  146599. +
  146600. +/* User signal command codes. */
  146601. +typedef enum _gceUSER_SIGNAL_COMMAND_CODES
  146602. +{
  146603. + gcvUSER_SIGNAL_CREATE,
  146604. + gcvUSER_SIGNAL_DESTROY,
  146605. + gcvUSER_SIGNAL_SIGNAL,
  146606. + gcvUSER_SIGNAL_WAIT,
  146607. + gcvUSER_SIGNAL_MAP,
  146608. + gcvUSER_SIGNAL_UNMAP,
  146609. +}
  146610. +gceUSER_SIGNAL_COMMAND_CODES;
  146611. +
  146612. +/* Sync point command codes. */
  146613. +typedef enum _gceSYNC_POINT_COMMAND_CODES
  146614. +{
  146615. + gcvSYNC_POINT_CREATE,
  146616. + gcvSYNC_POINT_DESTROY,
  146617. + gcvSYNC_POINT_SIGNAL,
  146618. +}
  146619. +gceSYNC_POINT_COMMAND_CODES;
  146620. +
  146621. +/* Event locations. */
  146622. +typedef enum _gceKERNEL_WHERE
  146623. +{
  146624. + gcvKERNEL_COMMAND,
  146625. + gcvKERNEL_VERTEX,
  146626. + gcvKERNEL_TRIANGLE,
  146627. + gcvKERNEL_TEXTURE,
  146628. + gcvKERNEL_PIXEL,
  146629. +}
  146630. +gceKERNEL_WHERE;
  146631. +
  146632. +#if gcdENABLE_VG
  146633. +/* Hardware blocks. */
  146634. +typedef enum _gceBLOCK
  146635. +{
  146636. + gcvBLOCK_COMMAND,
  146637. + gcvBLOCK_TESSELLATOR,
  146638. + gcvBLOCK_TESSELLATOR2,
  146639. + gcvBLOCK_TESSELLATOR3,
  146640. + gcvBLOCK_RASTER,
  146641. + gcvBLOCK_VG,
  146642. + gcvBLOCK_VG2,
  146643. + gcvBLOCK_VG3,
  146644. + gcvBLOCK_PIXEL,
  146645. +
  146646. + /* Number of defined blocks. */
  146647. + gcvBLOCK_COUNT
  146648. +}
  146649. +gceBLOCK;
  146650. +#endif
  146651. +
  146652. +/* gcdDUMP message type. */
  146653. +typedef enum _gceDEBUG_MESSAGE_TYPE
  146654. +{
  146655. + gcvMESSAGE_TEXT,
  146656. + gcvMESSAGE_DUMP
  146657. +}
  146658. +gceDEBUG_MESSAGE_TYPE;
  146659. +
  146660. +typedef enum _gceSPECIAL_HINT
  146661. +{
  146662. + gceSPECIAL_HINT0,
  146663. + gceSPECIAL_HINT1,
  146664. + gceSPECIAL_HINT2,
  146665. + gceSPECIAL_HINT3,
  146666. + /* For disable dynamic stream/index */
  146667. + gceSPECIAL_HINT4
  146668. +}
  146669. +gceSPECIAL_HINT;
  146670. +
  146671. +typedef enum _gceMACHINECODE
  146672. +{
  146673. + gcvMACHINECODE_HOVERJET0 = 0x0,
  146674. + gcvMACHINECODE_HOVERJET1 ,
  146675. +
  146676. + gcvMACHINECODE_TAIJI0 ,
  146677. + gcvMACHINECODE_TAIJI1 ,
  146678. + gcvMACHINECODE_TAIJI2 ,
  146679. +
  146680. + gcvMACHINECODE_ANTUTU0 ,
  146681. +
  146682. + gcvMACHINECODE_GLB27_RELEASE_0,
  146683. + gcvMACHINECODE_GLB27_RELEASE_1,
  146684. +
  146685. + gcvMACHINECODE_WAVESCAPE0 ,
  146686. + gcvMACHINECODE_WAVESCAPE1 ,
  146687. +
  146688. + gcvMACHINECODE_NENAMARKV2_4_0 ,
  146689. + gcvMACHINECODE_NENAMARKV2_4_1 ,
  146690. +
  146691. + gcvMACHINECODE_GLB25_RELEASE_0,
  146692. + gcvMACHINECODE_GLB25_RELEASE_1,
  146693. + gcvMACHINECODE_GLB25_RELEASE_2,
  146694. +}
  146695. +gceMACHINECODE;
  146696. +
  146697. +
  146698. +/******************************************************************************\
  146699. +****************************** Object Declarations *****************************
  146700. +\******************************************************************************/
  146701. +
  146702. +typedef struct _gckCONTEXT * gckCONTEXT;
  146703. +typedef struct _gcoCMDBUF * gcoCMDBUF;
  146704. +typedef struct _gcsSTATE_DELTA * gcsSTATE_DELTA_PTR;
  146705. +typedef struct _gcsQUEUE * gcsQUEUE_PTR;
  146706. +typedef struct _gcoQUEUE * gcoQUEUE;
  146707. +typedef struct _gcsHAL_INTERFACE * gcsHAL_INTERFACE_PTR;
  146708. +typedef struct _gcs2D_PROFILE * gcs2D_PROFILE_PTR;
  146709. +
  146710. +#if gcdENABLE_VG
  146711. +typedef struct _gcoVGHARDWARE * gcoVGHARDWARE;
  146712. +typedef struct _gcoVGBUFFER * gcoVGBUFFER;
  146713. +typedef struct _gckVGHARDWARE * gckVGHARDWARE;
  146714. +typedef struct _gcsVGCONTEXT * gcsVGCONTEXT_PTR;
  146715. +typedef struct _gcsVGCONTEXT_MAP * gcsVGCONTEXT_MAP_PTR;
  146716. +typedef struct _gcsVGCMDQUEUE * gcsVGCMDQUEUE_PTR;
  146717. +typedef struct _gcsTASK_MASTER_TABLE * gcsTASK_MASTER_TABLE_PTR;
  146718. +typedef struct _gckVGKERNEL * gckVGKERNEL;
  146719. +typedef void * gctTHREAD;
  146720. +#endif
  146721. +
  146722. +#ifdef __cplusplus
  146723. +}
  146724. +#endif
  146725. +
  146726. +#endif /* __gc_hal_enum_h_ */
  146727. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
  146728. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h 1969-12-31 18:00:00.000000000 -0600
  146729. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h 2014-12-08 00:31:53.468418001 -0600
  146730. @@ -0,0 +1,2661 @@
  146731. +/****************************************************************************
  146732. +*
  146733. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  146734. +*
  146735. +* This program is free software; you can redistribute it and/or modify
  146736. +* it under the terms of the GNU General Public License as published by
  146737. +* the Free Software Foundation; either version 2 of the license, or
  146738. +* (at your option) any later version.
  146739. +*
  146740. +* This program is distributed in the hope that it will be useful,
  146741. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  146742. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  146743. +* GNU General Public License for more details.
  146744. +*
  146745. +* You should have received a copy of the GNU General Public License
  146746. +* along with this program; if not write to the Free Software
  146747. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  146748. +*
  146749. +*****************************************************************************/
  146750. +
  146751. +
  146752. +#ifndef __gc_hal_h_
  146753. +#define __gc_hal_h_
  146754. +
  146755. +#include "gc_hal_rename.h"
  146756. +#include "gc_hal_types.h"
  146757. +#include "gc_hal_enum.h"
  146758. +#include "gc_hal_base.h"
  146759. +#include "gc_hal_profiler.h"
  146760. +#include "gc_hal_driver.h"
  146761. +#ifndef VIVANTE_NO_3D
  146762. +#include "gc_hal_statistics.h"
  146763. +#endif
  146764. +
  146765. +#ifdef __cplusplus
  146766. +extern "C" {
  146767. +#endif
  146768. +
  146769. +/******************************************************************************\
  146770. +******************************* Alignment Macros *******************************
  146771. +\******************************************************************************/
  146772. +
  146773. +#define gcmALIGN(n, align) \
  146774. +( \
  146775. + ((n) + ((align) - 1)) & ~((align) - 1) \
  146776. +)
  146777. +
  146778. +#define gcmALIGN_BASE(n, align) \
  146779. +( \
  146780. + ((n) & ~((align) - 1)) \
  146781. +)
  146782. +
  146783. +/******************************************************************************\
  146784. +***************************** Element Count Macro *****************************
  146785. +\******************************************************************************/
  146786. +
  146787. +#define gcmSIZEOF(a) \
  146788. +( \
  146789. + (gctSIZE_T) (sizeof(a)) \
  146790. +)
  146791. +
  146792. +#define gcmCOUNTOF(a) \
  146793. +( \
  146794. + sizeof(a) / sizeof(a[0]) \
  146795. +)
  146796. +
  146797. +/******************************************************************************\
  146798. +********************************* Cast Macro **********************************
  146799. +\******************************************************************************/
  146800. +#define gcmNAME_TO_PTR(na) \
  146801. + gckKERNEL_QueryPointerFromName(kernel, gcmALL_TO_UINT32(na))
  146802. +
  146803. +#define gcmPTR_TO_NAME(ptr) \
  146804. + gckKERNEL_AllocateNameFromPointer(kernel, ptr)
  146805. +
  146806. +#define gcmRELEASE_NAME(na) \
  146807. + gckKERNEL_DeleteName(kernel, gcmALL_TO_UINT32(na))
  146808. +
  146809. +#ifdef __LP64__
  146810. +
  146811. +#define gcmALL_TO_UINT32(t) \
  146812. +( \
  146813. + (gctUINT32) (gctUINTPTR_T) (t)\
  146814. +)
  146815. +
  146816. +#define gcmPTR_TO_UINT64(p) \
  146817. +( \
  146818. + (gctUINT64) (p)\
  146819. +)
  146820. +
  146821. +#define gcmUINT64_TO_PTR(u) \
  146822. +( \
  146823. + (gctPOINTER) (u)\
  146824. +)
  146825. +
  146826. +#else /* 32 bit */
  146827. +
  146828. +#define gcmALL_TO_UINT32(t) \
  146829. +( \
  146830. + (gctUINT32) (t)\
  146831. +)
  146832. +
  146833. +#define gcmPTR_TO_UINT64(p) \
  146834. +( \
  146835. + (gctUINT64) (gctUINTPTR_T) (p)\
  146836. +)
  146837. +
  146838. +#define gcmUINT64_TO_PTR(u) \
  146839. +( \
  146840. + (gctPOINTER) (gctUINTPTR_T) (u)\
  146841. +)
  146842. +
  146843. +#endif
  146844. +
  146845. +#define gcmUINT64_TO_TYPE(u, t) \
  146846. +( \
  146847. + (t) (gctUINTPTR_T) (u)\
  146848. +)
  146849. +
  146850. +/******************************************************************************\
  146851. +******************************** Useful Macro *********************************
  146852. +\******************************************************************************/
  146853. +
  146854. +#define gcvINVALID_ADDRESS ~0U
  146855. +
  146856. +#define gcmGET_PRE_ROTATION(rotate) \
  146857. + ((rotate) & (~(gcvSURF_POST_FLIP_X | gcvSURF_POST_FLIP_Y)))
  146858. +
  146859. +#define gcmGET_POST_ROTATION(rotate) \
  146860. + ((rotate) & (gcvSURF_POST_FLIP_X | gcvSURF_POST_FLIP_Y))
  146861. +
  146862. +/******************************************************************************\
  146863. +******************************** gcsOBJECT Object *******************************
  146864. +\******************************************************************************/
  146865. +
  146866. +/* Type of objects. */
  146867. +typedef enum _gceOBJECT_TYPE
  146868. +{
  146869. + gcvOBJ_UNKNOWN = 0,
  146870. + gcvOBJ_2D = gcmCC('2','D',' ',' '),
  146871. + gcvOBJ_3D = gcmCC('3','D',' ',' '),
  146872. + gcvOBJ_ATTRIBUTE = gcmCC('A','T','T','R'),
  146873. + gcvOBJ_BRUSHCACHE = gcmCC('B','R','U','$'),
  146874. + gcvOBJ_BRUSHNODE = gcmCC('B','R','U','n'),
  146875. + gcvOBJ_BRUSH = gcmCC('B','R','U','o'),
  146876. + gcvOBJ_BUFFER = gcmCC('B','U','F','R'),
  146877. + gcvOBJ_COMMAND = gcmCC('C','M','D',' '),
  146878. + gcvOBJ_COMMANDBUFFER = gcmCC('C','M','D','B'),
  146879. + gcvOBJ_CONTEXT = gcmCC('C','T','X','T'),
  146880. + gcvOBJ_DEVICE = gcmCC('D','E','V',' '),
  146881. + gcvOBJ_DUMP = gcmCC('D','U','M','P'),
  146882. + gcvOBJ_EVENT = gcmCC('E','V','N','T'),
  146883. + gcvOBJ_FUNCTION = gcmCC('F','U','N','C'),
  146884. + gcvOBJ_HAL = gcmCC('H','A','L',' '),
  146885. + gcvOBJ_HARDWARE = gcmCC('H','A','R','D'),
  146886. + gcvOBJ_HEAP = gcmCC('H','E','A','P'),
  146887. + gcvOBJ_INDEX = gcmCC('I','N','D','X'),
  146888. + gcvOBJ_INTERRUPT = gcmCC('I','N','T','R'),
  146889. + gcvOBJ_KERNEL = gcmCC('K','E','R','N'),
  146890. + gcvOBJ_KERNEL_FUNCTION = gcmCC('K','F','C','N'),
  146891. + gcvOBJ_MEMORYBUFFER = gcmCC('M','E','M','B'),
  146892. + gcvOBJ_MMU = gcmCC('M','M','U',' '),
  146893. + gcvOBJ_OS = gcmCC('O','S',' ',' '),
  146894. + gcvOBJ_OUTPUT = gcmCC('O','U','T','P'),
  146895. + gcvOBJ_PAINT = gcmCC('P','N','T',' '),
  146896. + gcvOBJ_PATH = gcmCC('P','A','T','H'),
  146897. + gcvOBJ_QUEUE = gcmCC('Q','U','E',' '),
  146898. + gcvOBJ_SAMPLER = gcmCC('S','A','M','P'),
  146899. + gcvOBJ_SHADER = gcmCC('S','H','D','R'),
  146900. + gcvOBJ_STREAM = gcmCC('S','T','R','M'),
  146901. + gcvOBJ_SURF = gcmCC('S','U','R','F'),
  146902. + gcvOBJ_TEXTURE = gcmCC('T','X','T','R'),
  146903. + gcvOBJ_UNIFORM = gcmCC('U','N','I','F'),
  146904. + gcvOBJ_VARIABLE = gcmCC('V','A','R','I'),
  146905. + gcvOBJ_VERTEX = gcmCC('V','R','T','X'),
  146906. + gcvOBJ_VIDMEM = gcmCC('V','M','E','M'),
  146907. + gcvOBJ_VG = gcmCC('V','G',' ',' '),
  146908. +}
  146909. +gceOBJECT_TYPE;
  146910. +
  146911. +/* gcsOBJECT object defintinon. */
  146912. +typedef struct _gcsOBJECT
  146913. +{
  146914. + /* Type of an object. */
  146915. + gceOBJECT_TYPE type;
  146916. +}
  146917. +gcsOBJECT;
  146918. +
  146919. +typedef struct _gckHARDWARE * gckHARDWARE;
  146920. +
  146921. +/* CORE flags. */
  146922. +typedef enum _gceCORE
  146923. +{
  146924. + gcvCORE_MAJOR = 0x0,
  146925. + gcvCORE_2D = 0x1,
  146926. + gcvCORE_VG = 0x2
  146927. +}
  146928. +gceCORE;
  146929. +
  146930. +#define gcdMAX_GPU_COUNT 3
  146931. +
  146932. +/*******************************************************************************
  146933. +**
  146934. +** gcmVERIFY_OBJECT
  146935. +**
  146936. +** Assert if an object is invalid or is not of the specified type. If the
  146937. +** object is invalid or not of the specified type, gcvSTATUS_INVALID_OBJECT
  146938. +** will be returned from the current function. In retail mode this macro
  146939. +** does nothing.
  146940. +**
  146941. +** ARGUMENTS:
  146942. +**
  146943. +** obj Object to test.
  146944. +** t Expected type of the object.
  146945. +*/
  146946. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  146947. +#define _gcmVERIFY_OBJECT(prefix, obj, t) \
  146948. + if ((obj) == gcvNULL) \
  146949. + { \
  146950. + prefix##TRACE(gcvLEVEL_ERROR, \
  146951. + #prefix "VERIFY_OBJECT failed: NULL"); \
  146952. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  146953. + gcmCC_PRINT(t)); \
  146954. + prefix##ASSERT((obj) != gcvNULL); \
  146955. + prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_OBJECT); \
  146956. + return gcvSTATUS_INVALID_OBJECT; \
  146957. + } \
  146958. + else if (((gcsOBJECT*) (obj))->type != t) \
  146959. + { \
  146960. + prefix##TRACE(gcvLEVEL_ERROR, \
  146961. + #prefix "VERIFY_OBJECT failed: %c%c%c%c", \
  146962. + gcmCC_PRINT(((gcsOBJECT*) (obj))->type)); \
  146963. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  146964. + gcmCC_PRINT(t)); \
  146965. + prefix##ASSERT(((gcsOBJECT*)(obj))->type == t); \
  146966. + prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_OBJECT); \
  146967. + return gcvSTATUS_INVALID_OBJECT; \
  146968. + }
  146969. +
  146970. +# define gcmVERIFY_OBJECT(obj, t) _gcmVERIFY_OBJECT(gcm, obj, t)
  146971. +# define gcmkVERIFY_OBJECT(obj, t) _gcmVERIFY_OBJECT(gcmk, obj, t)
  146972. +#else
  146973. +# define gcmVERIFY_OBJECT(obj, t) do {} while (gcvFALSE)
  146974. +# define gcmkVERIFY_OBJECT(obj, t) do {} while (gcvFALSE)
  146975. +#endif
  146976. +
  146977. +/******************************************************************************/
  146978. +/*VERIFY_OBJECT if special return expected*/
  146979. +/******************************************************************************/
  146980. +#ifndef EGL_API_ANDROID
  146981. +# define _gcmVERIFY_OBJECT_RETURN(prefix, obj, t, retVal) \
  146982. + do \
  146983. + { \
  146984. + if ((obj) == gcvNULL) \
  146985. + { \
  146986. + prefix##PRINT_VERSION(); \
  146987. + prefix##TRACE(gcvLEVEL_ERROR, \
  146988. + #prefix "VERIFY_OBJECT_RETURN failed: NULL"); \
  146989. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  146990. + gcmCC_PRINT(t)); \
  146991. + prefix##ASSERT((obj) != gcvNULL); \
  146992. + prefix##FOOTER_ARG("retVal=%d", retVal); \
  146993. + return retVal; \
  146994. + } \
  146995. + else if (((gcsOBJECT*) (obj))->type != t) \
  146996. + { \
  146997. + prefix##PRINT_VERSION(); \
  146998. + prefix##TRACE(gcvLEVEL_ERROR, \
  146999. + #prefix "VERIFY_OBJECT_RETURN failed: %c%c%c%c", \
  147000. + gcmCC_PRINT(((gcsOBJECT*) (obj))->type)); \
  147001. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  147002. + gcmCC_PRINT(t)); \
  147003. + prefix##ASSERT(((gcsOBJECT*)(obj))->type == t); \
  147004. + prefix##FOOTER_ARG("retVal=%d", retVal); \
  147005. + return retVal; \
  147006. + } \
  147007. + } \
  147008. + while (gcvFALSE)
  147009. +# define gcmVERIFY_OBJECT_RETURN(obj, t, retVal) \
  147010. + _gcmVERIFY_OBJECT_RETURN(gcm, obj, t, retVal)
  147011. +# define gcmkVERIFY_OBJECT_RETURN(obj, t, retVal) \
  147012. + _gcmVERIFY_OBJECT_RETURN(gcmk, obj, t, retVal)
  147013. +#else
  147014. +# define gcmVERIFY_OBJECT_RETURN(obj, t) do {} while (gcvFALSE)
  147015. +# define gcmVERIFY_OBJECT_RETURN(obj, t) do {} while (gcvFALSE)
  147016. +#endif
  147017. +
  147018. +/******************************************************************************\
  147019. +********************************** gckOS Object *********************************
  147020. +\******************************************************************************/
  147021. +
  147022. +/* Construct a new gckOS object. */
  147023. +gceSTATUS
  147024. +gckOS_Construct(
  147025. + IN gctPOINTER Context,
  147026. + OUT gckOS * Os
  147027. + );
  147028. +
  147029. +/* Destroy an gckOS object. */
  147030. +gceSTATUS
  147031. +gckOS_Destroy(
  147032. + IN gckOS Os
  147033. + );
  147034. +
  147035. +/* Query the video memory. */
  147036. +gceSTATUS
  147037. +gckOS_QueryVideoMemory(
  147038. + IN gckOS Os,
  147039. + OUT gctPHYS_ADDR * InternalAddress,
  147040. + OUT gctSIZE_T * InternalSize,
  147041. + OUT gctPHYS_ADDR * ExternalAddress,
  147042. + OUT gctSIZE_T * ExternalSize,
  147043. + OUT gctPHYS_ADDR * ContiguousAddress,
  147044. + OUT gctSIZE_T * ContiguousSize
  147045. + );
  147046. +
  147047. +/* Allocate memory from the heap. */
  147048. +gceSTATUS
  147049. +gckOS_Allocate(
  147050. + IN gckOS Os,
  147051. + IN gctSIZE_T Bytes,
  147052. + OUT gctPOINTER * Memory
  147053. + );
  147054. +
  147055. +/* Free allocated memory. */
  147056. +gceSTATUS
  147057. +gckOS_Free(
  147058. + IN gckOS Os,
  147059. + IN gctPOINTER Memory
  147060. + );
  147061. +
  147062. +/* Wrapper for allocation memory.. */
  147063. +gceSTATUS
  147064. +gckOS_AllocateMemory(
  147065. + IN gckOS Os,
  147066. + IN gctSIZE_T Bytes,
  147067. + OUT gctPOINTER * Memory
  147068. + );
  147069. +
  147070. +/* Wrapper for freeing memory. */
  147071. +gceSTATUS
  147072. +gckOS_FreeMemory(
  147073. + IN gckOS Os,
  147074. + IN gctPOINTER Memory
  147075. + );
  147076. +
  147077. +/* Allocate paged memory. */
  147078. +gceSTATUS
  147079. +gckOS_AllocatePagedMemory(
  147080. + IN gckOS Os,
  147081. + IN gctSIZE_T Bytes,
  147082. + OUT gctPHYS_ADDR * Physical
  147083. + );
  147084. +
  147085. +/* Allocate paged memory. */
  147086. +gceSTATUS
  147087. +gckOS_AllocatePagedMemoryEx(
  147088. + IN gckOS Os,
  147089. + IN gctBOOL Contiguous,
  147090. + IN gctSIZE_T Bytes,
  147091. + OUT gctPHYS_ADDR * Physical
  147092. + );
  147093. +
  147094. +/* Lock pages. */
  147095. +gceSTATUS
  147096. +gckOS_LockPages(
  147097. + IN gckOS Os,
  147098. + IN gctPHYS_ADDR Physical,
  147099. + IN gctSIZE_T Bytes,
  147100. + IN gctBOOL Cacheable,
  147101. + OUT gctPOINTER * Logical,
  147102. + OUT gctSIZE_T * PageCount
  147103. + );
  147104. +
  147105. +/* Map pages. */
  147106. +gceSTATUS
  147107. +gckOS_MapPages(
  147108. + IN gckOS Os,
  147109. + IN gctPHYS_ADDR Physical,
  147110. +#ifdef __QNXNTO__
  147111. + IN gctPOINTER Logical,
  147112. +#endif
  147113. + IN gctSIZE_T PageCount,
  147114. + IN gctPOINTER PageTable
  147115. + );
  147116. +
  147117. +/* Map pages. */
  147118. +gceSTATUS
  147119. +gckOS_MapPagesEx(
  147120. + IN gckOS Os,
  147121. + IN gceCORE Core,
  147122. + IN gctPHYS_ADDR Physical,
  147123. +#ifdef __QNXNTO__
  147124. + IN gctPOINTER Logical,
  147125. +#endif
  147126. + IN gctSIZE_T PageCount,
  147127. + IN gctPOINTER PageTable
  147128. + );
  147129. +
  147130. +/* Unlock pages. */
  147131. +gceSTATUS
  147132. +gckOS_UnlockPages(
  147133. + IN gckOS Os,
  147134. + IN gctPHYS_ADDR Physical,
  147135. + IN gctSIZE_T Bytes,
  147136. + IN gctPOINTER Logical
  147137. + );
  147138. +
  147139. +/* Free paged memory. */
  147140. +gceSTATUS
  147141. +gckOS_FreePagedMemory(
  147142. + IN gckOS Os,
  147143. + IN gctPHYS_ADDR Physical,
  147144. + IN gctSIZE_T Bytes
  147145. + );
  147146. +
  147147. +/* Allocate non-paged memory. */
  147148. +gceSTATUS
  147149. +gckOS_AllocateNonPagedMemory(
  147150. + IN gckOS Os,
  147151. + IN gctBOOL InUserSpace,
  147152. + IN OUT gctSIZE_T * Bytes,
  147153. + OUT gctPHYS_ADDR * Physical,
  147154. + OUT gctPOINTER * Logical
  147155. + );
  147156. +
  147157. +/* Free non-paged memory. */
  147158. +gceSTATUS
  147159. +gckOS_FreeNonPagedMemory(
  147160. + IN gckOS Os,
  147161. + IN gctSIZE_T Bytes,
  147162. + IN gctPHYS_ADDR Physical,
  147163. + IN gctPOINTER Logical
  147164. + );
  147165. +
  147166. +/* Allocate contiguous memory. */
  147167. +gceSTATUS
  147168. +gckOS_AllocateContiguous(
  147169. + IN gckOS Os,
  147170. + IN gctBOOL InUserSpace,
  147171. + IN OUT gctSIZE_T * Bytes,
  147172. + OUT gctPHYS_ADDR * Physical,
  147173. + OUT gctPOINTER * Logical
  147174. + );
  147175. +
  147176. +/* Free contiguous memory. */
  147177. +gceSTATUS
  147178. +gckOS_FreeContiguous(
  147179. + IN gckOS Os,
  147180. + IN gctPHYS_ADDR Physical,
  147181. + IN gctPOINTER Logical,
  147182. + IN gctSIZE_T Bytes
  147183. + );
  147184. +
  147185. +/* Get the number fo bytes per page. */
  147186. +gceSTATUS
  147187. +gckOS_GetPageSize(
  147188. + IN gckOS Os,
  147189. + OUT gctSIZE_T * PageSize
  147190. + );
  147191. +
  147192. +/* Get the physical address of a corresponding logical address. */
  147193. +gceSTATUS
  147194. +gckOS_GetPhysicalAddress(
  147195. + IN gckOS Os,
  147196. + IN gctPOINTER Logical,
  147197. + OUT gctUINT32 * Address
  147198. + );
  147199. +
  147200. +/* Get the physical address of a corresponding logical address. */
  147201. +gceSTATUS
  147202. +gckOS_GetPhysicalAddressProcess(
  147203. + IN gckOS Os,
  147204. + IN gctPOINTER Logical,
  147205. + IN gctUINT32 ProcessID,
  147206. + OUT gctUINT32 * Address
  147207. + );
  147208. +
  147209. +/* Map physical memory. */
  147210. +gceSTATUS
  147211. +gckOS_MapPhysical(
  147212. + IN gckOS Os,
  147213. + IN gctUINT32 Physical,
  147214. + IN gctSIZE_T Bytes,
  147215. + OUT gctPOINTER * Logical
  147216. + );
  147217. +
  147218. +/* Unmap previously mapped physical memory. */
  147219. +gceSTATUS
  147220. +gckOS_UnmapPhysical(
  147221. + IN gckOS Os,
  147222. + IN gctPOINTER Logical,
  147223. + IN gctSIZE_T Bytes
  147224. + );
  147225. +
  147226. +/* Read data from a hardware register. */
  147227. +gceSTATUS
  147228. +gckOS_ReadRegister(
  147229. + IN gckOS Os,
  147230. + IN gctUINT32 Address,
  147231. + OUT gctUINT32 * Data
  147232. + );
  147233. +
  147234. +/* Read data from a hardware register. */
  147235. +gceSTATUS
  147236. +gckOS_ReadRegisterEx(
  147237. + IN gckOS Os,
  147238. + IN gceCORE Core,
  147239. + IN gctUINT32 Address,
  147240. + OUT gctUINT32 * Data
  147241. + );
  147242. +
  147243. +/* Write data to a hardware register. */
  147244. +gceSTATUS
  147245. +gckOS_WriteRegister(
  147246. + IN gckOS Os,
  147247. + IN gctUINT32 Address,
  147248. + IN gctUINT32 Data
  147249. + );
  147250. +
  147251. +/* Write data to a hardware register. */
  147252. +gceSTATUS
  147253. +gckOS_WriteRegisterEx(
  147254. + IN gckOS Os,
  147255. + IN gceCORE Core,
  147256. + IN gctUINT32 Address,
  147257. + IN gctUINT32 Data
  147258. + );
  147259. +
  147260. +/* Write data to a 32-bit memory location. */
  147261. +gceSTATUS
  147262. +gckOS_WriteMemory(
  147263. + IN gckOS Os,
  147264. + IN gctPOINTER Address,
  147265. + IN gctUINT32 Data
  147266. + );
  147267. +
  147268. +/* Map physical memory into the process space. */
  147269. +gceSTATUS
  147270. +gckOS_MapMemory(
  147271. + IN gckOS Os,
  147272. + IN gctPHYS_ADDR Physical,
  147273. + IN gctSIZE_T Bytes,
  147274. + OUT gctPOINTER * Logical
  147275. + );
  147276. +
  147277. +/* Unmap physical memory from the specified process space. */
  147278. +gceSTATUS
  147279. +gckOS_UnmapMemoryEx(
  147280. + IN gckOS Os,
  147281. + IN gctPHYS_ADDR Physical,
  147282. + IN gctSIZE_T Bytes,
  147283. + IN gctPOINTER Logical,
  147284. + IN gctUINT32 PID
  147285. + );
  147286. +
  147287. +/* Unmap physical memory from the process space. */
  147288. +gceSTATUS
  147289. +gckOS_UnmapMemory(
  147290. + IN gckOS Os,
  147291. + IN gctPHYS_ADDR Physical,
  147292. + IN gctSIZE_T Bytes,
  147293. + IN gctPOINTER Logical
  147294. + );
  147295. +
  147296. +/* Unmap user logical memory out of physical memory.
  147297. + * This function is only supported in Linux currently.
  147298. + */
  147299. +gceSTATUS
  147300. +gckOS_UnmapUserLogical(
  147301. + IN gckOS Os,
  147302. + IN gctPHYS_ADDR Physical,
  147303. + IN gctSIZE_T Bytes,
  147304. + IN gctPOINTER Logical
  147305. + );
  147306. +
  147307. +/* Create a new mutex. */
  147308. +gceSTATUS
  147309. +gckOS_CreateMutex(
  147310. + IN gckOS Os,
  147311. + OUT gctPOINTER * Mutex
  147312. + );
  147313. +
  147314. +/* Delete a mutex. */
  147315. +gceSTATUS
  147316. +gckOS_DeleteMutex(
  147317. + IN gckOS Os,
  147318. + IN gctPOINTER Mutex
  147319. + );
  147320. +
  147321. +/* Acquire a mutex. */
  147322. +gceSTATUS
  147323. +gckOS_AcquireMutex(
  147324. + IN gckOS Os,
  147325. + IN gctPOINTER Mutex,
  147326. + IN gctUINT32 Timeout
  147327. + );
  147328. +
  147329. +/* Release a mutex. */
  147330. +gceSTATUS
  147331. +gckOS_ReleaseMutex(
  147332. + IN gckOS Os,
  147333. + IN gctPOINTER Mutex
  147334. + );
  147335. +
  147336. +/* Atomically exchange a pair of 32-bit values. */
  147337. +gceSTATUS
  147338. +gckOS_AtomicExchange(
  147339. + IN gckOS Os,
  147340. + IN OUT gctUINT32_PTR Target,
  147341. + IN gctUINT32 NewValue,
  147342. + OUT gctUINT32_PTR OldValue
  147343. + );
  147344. +
  147345. +/* Atomically exchange a pair of pointers. */
  147346. +gceSTATUS
  147347. +gckOS_AtomicExchangePtr(
  147348. + IN gckOS Os,
  147349. + IN OUT gctPOINTER * Target,
  147350. + IN gctPOINTER NewValue,
  147351. + OUT gctPOINTER * OldValue
  147352. + );
  147353. +
  147354. +#if gcdSMP
  147355. +gceSTATUS
  147356. +gckOS_AtomSetMask(
  147357. + IN gctPOINTER Atom,
  147358. + IN gctUINT32 Mask
  147359. + );
  147360. +
  147361. +gceSTATUS
  147362. +gckOS_AtomClearMask(
  147363. + IN gctPOINTER Atom,
  147364. + IN gctUINT32 Mask
  147365. + );
  147366. +#endif
  147367. +
  147368. +gceSTATUS
  147369. +gckOS_DumpCallStack(
  147370. + IN gckOS Os
  147371. + );
  147372. +
  147373. +gceSTATUS
  147374. +gckOS_GetProcessNameByPid(
  147375. + IN gctINT Pid,
  147376. + IN gctSIZE_T Length,
  147377. + OUT gctUINT8_PTR String
  147378. + );
  147379. +
  147380. +
  147381. +
  147382. +/*******************************************************************************
  147383. +**
  147384. +** gckOS_AtomConstruct
  147385. +**
  147386. +** Create an atom.
  147387. +**
  147388. +** INPUT:
  147389. +**
  147390. +** gckOS Os
  147391. +** Pointer to a gckOS object.
  147392. +**
  147393. +** OUTPUT:
  147394. +**
  147395. +** gctPOINTER * Atom
  147396. +** Pointer to a variable receiving the constructed atom.
  147397. +*/
  147398. +gceSTATUS
  147399. +gckOS_AtomConstruct(
  147400. + IN gckOS Os,
  147401. + OUT gctPOINTER * Atom
  147402. + );
  147403. +
  147404. +/*******************************************************************************
  147405. +**
  147406. +** gckOS_AtomDestroy
  147407. +**
  147408. +** Destroy an atom.
  147409. +**
  147410. +** INPUT:
  147411. +**
  147412. +** gckOS Os
  147413. +** Pointer to a gckOS object.
  147414. +**
  147415. +** gctPOINTER Atom
  147416. +** Pointer to the atom to destroy.
  147417. +**
  147418. +** OUTPUT:
  147419. +**
  147420. +** Nothing.
  147421. +*/
  147422. +gceSTATUS
  147423. +gckOS_AtomDestroy(
  147424. + IN gckOS Os,
  147425. + OUT gctPOINTER Atom
  147426. + );
  147427. +
  147428. +/*******************************************************************************
  147429. +**
  147430. +** gckOS_AtomGet
  147431. +**
  147432. +** Get the 32-bit value protected by an atom.
  147433. +**
  147434. +** INPUT:
  147435. +**
  147436. +** gckOS Os
  147437. +** Pointer to a gckOS object.
  147438. +**
  147439. +** gctPOINTER Atom
  147440. +** Pointer to the atom.
  147441. +**
  147442. +** OUTPUT:
  147443. +**
  147444. +** gctINT32_PTR Value
  147445. +** Pointer to a variable the receives the value of the atom.
  147446. +*/
  147447. +gceSTATUS
  147448. +gckOS_AtomGet(
  147449. + IN gckOS Os,
  147450. + IN gctPOINTER Atom,
  147451. + OUT gctINT32_PTR Value
  147452. + );
  147453. +
  147454. +/*******************************************************************************
  147455. +**
  147456. +** gckOS_AtomSet
  147457. +**
  147458. +** Set the 32-bit value protected by an atom.
  147459. +**
  147460. +** INPUT:
  147461. +**
  147462. +** gckOS Os
  147463. +** Pointer to a gckOS object.
  147464. +**
  147465. +** gctPOINTER Atom
  147466. +** Pointer to the atom.
  147467. +**
  147468. +** gctINT32 Value
  147469. +** The value of the atom.
  147470. +**
  147471. +** OUTPUT:
  147472. +**
  147473. +** Nothing.
  147474. +*/
  147475. +gceSTATUS
  147476. +gckOS_AtomSet(
  147477. + IN gckOS Os,
  147478. + IN gctPOINTER Atom,
  147479. + IN gctINT32 Value
  147480. + );
  147481. +
  147482. +/*******************************************************************************
  147483. +**
  147484. +** gckOS_AtomIncrement
  147485. +**
  147486. +** Atomically increment the 32-bit integer value inside an atom.
  147487. +**
  147488. +** INPUT:
  147489. +**
  147490. +** gckOS Os
  147491. +** Pointer to a gckOS object.
  147492. +**
  147493. +** gctPOINTER Atom
  147494. +** Pointer to the atom.
  147495. +**
  147496. +** OUTPUT:
  147497. +**
  147498. +** gctINT32_PTR Value
  147499. +** Pointer to a variable the receives the original value of the atom.
  147500. +*/
  147501. +gceSTATUS
  147502. +gckOS_AtomIncrement(
  147503. + IN gckOS Os,
  147504. + IN gctPOINTER Atom,
  147505. + OUT gctINT32_PTR Value
  147506. + );
  147507. +
  147508. +/*******************************************************************************
  147509. +**
  147510. +** gckOS_AtomDecrement
  147511. +**
  147512. +** Atomically decrement the 32-bit integer value inside an atom.
  147513. +**
  147514. +** INPUT:
  147515. +**
  147516. +** gckOS Os
  147517. +** Pointer to a gckOS object.
  147518. +**
  147519. +** gctPOINTER Atom
  147520. +** Pointer to the atom.
  147521. +**
  147522. +** OUTPUT:
  147523. +**
  147524. +** gctINT32_PTR Value
  147525. +** Pointer to a variable the receives the original value of the atom.
  147526. +*/
  147527. +gceSTATUS
  147528. +gckOS_AtomDecrement(
  147529. + IN gckOS Os,
  147530. + IN gctPOINTER Atom,
  147531. + OUT gctINT32_PTR Value
  147532. + );
  147533. +
  147534. +/* Delay a number of microseconds. */
  147535. +gceSTATUS
  147536. +gckOS_Delay(
  147537. + IN gckOS Os,
  147538. + IN gctUINT32 Delay
  147539. + );
  147540. +
  147541. +/* Get time in milliseconds. */
  147542. +gceSTATUS
  147543. +gckOS_GetTicks(
  147544. + OUT gctUINT32_PTR Time
  147545. + );
  147546. +
  147547. +/* Compare time value. */
  147548. +gceSTATUS
  147549. +gckOS_TicksAfter(
  147550. + IN gctUINT32 Time1,
  147551. + IN gctUINT32 Time2,
  147552. + OUT gctBOOL_PTR IsAfter
  147553. + );
  147554. +
  147555. +/* Get time in microseconds. */
  147556. +gceSTATUS
  147557. +gckOS_GetTime(
  147558. + OUT gctUINT64_PTR Time
  147559. + );
  147560. +
  147561. +/* Memory barrier. */
  147562. +gceSTATUS
  147563. +gckOS_MemoryBarrier(
  147564. + IN gckOS Os,
  147565. + IN gctPOINTER Address
  147566. + );
  147567. +
  147568. +/* Map user pointer. */
  147569. +gceSTATUS
  147570. +gckOS_MapUserPointer(
  147571. + IN gckOS Os,
  147572. + IN gctPOINTER Pointer,
  147573. + IN gctSIZE_T Size,
  147574. + OUT gctPOINTER * KernelPointer
  147575. + );
  147576. +
  147577. +/* Unmap user pointer. */
  147578. +gceSTATUS
  147579. +gckOS_UnmapUserPointer(
  147580. + IN gckOS Os,
  147581. + IN gctPOINTER Pointer,
  147582. + IN gctSIZE_T Size,
  147583. + IN gctPOINTER KernelPointer
  147584. + );
  147585. +
  147586. +/*******************************************************************************
  147587. +**
  147588. +** gckOS_QueryNeedCopy
  147589. +**
  147590. +** Query whether the memory can be accessed or mapped directly or it has to be
  147591. +** copied.
  147592. +**
  147593. +** INPUT:
  147594. +**
  147595. +** gckOS Os
  147596. +** Pointer to an gckOS object.
  147597. +**
  147598. +** gctUINT32 ProcessID
  147599. +** Process ID of the current process.
  147600. +**
  147601. +** OUTPUT:
  147602. +**
  147603. +** gctBOOL_PTR NeedCopy
  147604. +** Pointer to a boolean receiving gcvTRUE if the memory needs a copy or
  147605. +** gcvFALSE if the memory can be accessed or mapped dircetly.
  147606. +*/
  147607. +gceSTATUS
  147608. +gckOS_QueryNeedCopy(
  147609. + IN gckOS Os,
  147610. + IN gctUINT32 ProcessID,
  147611. + OUT gctBOOL_PTR NeedCopy
  147612. + );
  147613. +
  147614. +/*******************************************************************************
  147615. +**
  147616. +** gckOS_CopyFromUserData
  147617. +**
  147618. +** Copy data from user to kernel memory.
  147619. +**
  147620. +** INPUT:
  147621. +**
  147622. +** gckOS Os
  147623. +** Pointer to an gckOS object.
  147624. +**
  147625. +** gctPOINTER KernelPointer
  147626. +** Pointer to kernel memory.
  147627. +**
  147628. +** gctPOINTER Pointer
  147629. +** Pointer to user memory.
  147630. +**
  147631. +** gctSIZE_T Size
  147632. +** Number of bytes to copy.
  147633. +**
  147634. +** OUTPUT:
  147635. +**
  147636. +** Nothing.
  147637. +*/
  147638. +gceSTATUS
  147639. +gckOS_CopyFromUserData(
  147640. + IN gckOS Os,
  147641. + IN gctPOINTER KernelPointer,
  147642. + IN gctPOINTER Pointer,
  147643. + IN gctSIZE_T Size
  147644. + );
  147645. +
  147646. +/*******************************************************************************
  147647. +**
  147648. +** gckOS_CopyToUserData
  147649. +**
  147650. +** Copy data from kernel to user memory.
  147651. +**
  147652. +** INPUT:
  147653. +**
  147654. +** gckOS Os
  147655. +** Pointer to an gckOS object.
  147656. +**
  147657. +** gctPOINTER KernelPointer
  147658. +** Pointer to kernel memory.
  147659. +**
  147660. +** gctPOINTER Pointer
  147661. +** Pointer to user memory.
  147662. +**
  147663. +** gctSIZE_T Size
  147664. +** Number of bytes to copy.
  147665. +**
  147666. +** OUTPUT:
  147667. +**
  147668. +** Nothing.
  147669. +*/
  147670. +gceSTATUS
  147671. +gckOS_CopyToUserData(
  147672. + IN gckOS Os,
  147673. + IN gctPOINTER KernelPointer,
  147674. + IN gctPOINTER Pointer,
  147675. + IN gctSIZE_T Size
  147676. + );
  147677. +
  147678. +#ifdef __QNXNTO__
  147679. +/* Map user physical address. */
  147680. +gceSTATUS
  147681. +gckOS_MapUserPhysical(
  147682. + IN gckOS Os,
  147683. + IN gctPHYS_ADDR Phys,
  147684. + OUT gctPOINTER * KernelPointer
  147685. + );
  147686. +#endif
  147687. +
  147688. +gceSTATUS
  147689. +gckOS_SuspendInterrupt(
  147690. + IN gckOS Os
  147691. + );
  147692. +
  147693. +gceSTATUS
  147694. +gckOS_SuspendInterruptEx(
  147695. + IN gckOS Os,
  147696. + IN gceCORE Core
  147697. + );
  147698. +
  147699. +gceSTATUS
  147700. +gckOS_ResumeInterrupt(
  147701. + IN gckOS Os
  147702. + );
  147703. +
  147704. +gceSTATUS
  147705. +gckOS_ResumeInterruptEx(
  147706. + IN gckOS Os,
  147707. + IN gceCORE Core
  147708. + );
  147709. +
  147710. +/* Get the base address for the physical memory. */
  147711. +gceSTATUS
  147712. +gckOS_GetBaseAddress(
  147713. + IN gckOS Os,
  147714. + OUT gctUINT32_PTR BaseAddress
  147715. + );
  147716. +
  147717. +/* Perform a memory copy. */
  147718. +gceSTATUS
  147719. +gckOS_MemCopy(
  147720. + IN gctPOINTER Destination,
  147721. + IN gctCONST_POINTER Source,
  147722. + IN gctSIZE_T Bytes
  147723. + );
  147724. +
  147725. +/* Zero memory. */
  147726. +gceSTATUS
  147727. +gckOS_ZeroMemory(
  147728. + IN gctPOINTER Memory,
  147729. + IN gctSIZE_T Bytes
  147730. + );
  147731. +
  147732. +/* Device I/O control to the kernel HAL layer. */
  147733. +gceSTATUS
  147734. +gckOS_DeviceControl(
  147735. + IN gckOS Os,
  147736. + IN gctBOOL FromUser,
  147737. + IN gctUINT32 IoControlCode,
  147738. + IN gctPOINTER InputBuffer,
  147739. + IN gctSIZE_T InputBufferSize,
  147740. + OUT gctPOINTER OutputBuffer,
  147741. + IN gctSIZE_T OutputBufferSize
  147742. + );
  147743. +
  147744. +/*******************************************************************************
  147745. +**
  147746. +** gckOS_GetProcessID
  147747. +**
  147748. +** Get current process ID.
  147749. +**
  147750. +** INPUT:
  147751. +**
  147752. +** Nothing.
  147753. +**
  147754. +** OUTPUT:
  147755. +**
  147756. +** gctUINT32_PTR ProcessID
  147757. +** Pointer to the variable that receives the process ID.
  147758. +*/
  147759. +gceSTATUS
  147760. +gckOS_GetProcessID(
  147761. + OUT gctUINT32_PTR ProcessID
  147762. + );
  147763. +
  147764. +gceSTATUS
  147765. +gckOS_GetCurrentProcessID(
  147766. + OUT gctUINT32_PTR ProcessID
  147767. + );
  147768. +
  147769. +/*******************************************************************************
  147770. +**
  147771. +** gckOS_GetThreadID
  147772. +**
  147773. +** Get current thread ID.
  147774. +**
  147775. +** INPUT:
  147776. +**
  147777. +** Nothing.
  147778. +**
  147779. +** OUTPUT:
  147780. +**
  147781. +** gctUINT32_PTR ThreadID
  147782. +** Pointer to the variable that receives the thread ID.
  147783. +*/
  147784. +gceSTATUS
  147785. +gckOS_GetThreadID(
  147786. + OUT gctUINT32_PTR ThreadID
  147787. + );
  147788. +
  147789. +/******************************************************************************\
  147790. +********************************** Signal Object *********************************
  147791. +\******************************************************************************/
  147792. +
  147793. +/* Create a signal. */
  147794. +gceSTATUS
  147795. +gckOS_CreateSignal(
  147796. + IN gckOS Os,
  147797. + IN gctBOOL ManualReset,
  147798. + OUT gctSIGNAL * Signal
  147799. + );
  147800. +
  147801. +/* Destroy a signal. */
  147802. +gceSTATUS
  147803. +gckOS_DestroySignal(
  147804. + IN gckOS Os,
  147805. + IN gctSIGNAL Signal
  147806. + );
  147807. +
  147808. +/* Signal a signal. */
  147809. +gceSTATUS
  147810. +gckOS_Signal(
  147811. + IN gckOS Os,
  147812. + IN gctSIGNAL Signal,
  147813. + IN gctBOOL State
  147814. + );
  147815. +
  147816. +/* Wait for a signal. */
  147817. +gceSTATUS
  147818. +gckOS_WaitSignal(
  147819. + IN gckOS Os,
  147820. + IN gctSIGNAL Signal,
  147821. + IN gctUINT32 Wait
  147822. + );
  147823. +
  147824. +/* Map a user signal to the kernel space. */
  147825. +gceSTATUS
  147826. +gckOS_MapSignal(
  147827. + IN gckOS Os,
  147828. + IN gctSIGNAL Signal,
  147829. + IN gctHANDLE Process,
  147830. + OUT gctSIGNAL * MappedSignal
  147831. + );
  147832. +
  147833. +/* Unmap a user signal */
  147834. +gceSTATUS
  147835. +gckOS_UnmapSignal(
  147836. + IN gckOS Os,
  147837. + IN gctSIGNAL Signal
  147838. + );
  147839. +
  147840. +/* Map user memory. */
  147841. +gceSTATUS
  147842. +gckOS_MapUserMemory(
  147843. + IN gckOS Os,
  147844. + IN gceCORE Core,
  147845. + IN gctPOINTER Memory,
  147846. + IN gctUINT32 Physical,
  147847. + IN gctSIZE_T Size,
  147848. + OUT gctPOINTER * Info,
  147849. + OUT gctUINT32_PTR Address
  147850. + );
  147851. +
  147852. +/* Unmap user memory. */
  147853. +gceSTATUS
  147854. +gckOS_UnmapUserMemory(
  147855. + IN gckOS Os,
  147856. + IN gceCORE Core,
  147857. + IN gctPOINTER Memory,
  147858. + IN gctSIZE_T Size,
  147859. + IN gctPOINTER Info,
  147860. + IN gctUINT32 Address
  147861. + );
  147862. +
  147863. +/******************************************************************************\
  147864. +************************** Android Native Fence Sync ***************************
  147865. +\******************************************************************************/
  147866. +gceSTATUS
  147867. +gckOS_CreateSyncTimeline(
  147868. + IN gckOS Os,
  147869. + OUT gctHANDLE * Timeline
  147870. + );
  147871. +
  147872. +gceSTATUS
  147873. +gckOS_DestroySyncTimeline(
  147874. + IN gckOS Os,
  147875. + IN gctHANDLE Timeline
  147876. + );
  147877. +
  147878. +gceSTATUS
  147879. +gckOS_CreateSyncPoint(
  147880. + IN gckOS Os,
  147881. + OUT gctSYNC_POINT * SyncPoint
  147882. + );
  147883. +
  147884. +gceSTATUS
  147885. +gckOS_ReferenceSyncPoint(
  147886. + IN gckOS Os,
  147887. + IN gctSYNC_POINT SyncPoint
  147888. + );
  147889. +
  147890. +gceSTATUS
  147891. +gckOS_DestroySyncPoint(
  147892. + IN gckOS Os,
  147893. + IN gctSYNC_POINT SyncPoint
  147894. + );
  147895. +
  147896. +gceSTATUS
  147897. +gckOS_SignalSyncPoint(
  147898. + IN gckOS Os,
  147899. + IN gctSYNC_POINT SyncPoint
  147900. + );
  147901. +
  147902. +gceSTATUS
  147903. +gckOS_QuerySyncPoint(
  147904. + IN gckOS Os,
  147905. + IN gctSYNC_POINT SyncPoint,
  147906. + OUT gctBOOL_PTR State
  147907. + );
  147908. +
  147909. +gceSTATUS
  147910. +gckOS_CreateNativeFence(
  147911. + IN gckOS Os,
  147912. + IN gctHANDLE Timeline,
  147913. + IN gctSYNC_POINT SyncPoint,
  147914. + OUT gctINT * FenceFD
  147915. + );
  147916. +
  147917. +#if !USE_NEW_LINUX_SIGNAL
  147918. +/* Create signal to be used in the user space. */
  147919. +gceSTATUS
  147920. +gckOS_CreateUserSignal(
  147921. + IN gckOS Os,
  147922. + IN gctBOOL ManualReset,
  147923. + OUT gctINT * SignalID
  147924. + );
  147925. +
  147926. +/* Destroy signal used in the user space. */
  147927. +gceSTATUS
  147928. +gckOS_DestroyUserSignal(
  147929. + IN gckOS Os,
  147930. + IN gctINT SignalID
  147931. + );
  147932. +
  147933. +/* Wait for signal used in the user space. */
  147934. +gceSTATUS
  147935. +gckOS_WaitUserSignal(
  147936. + IN gckOS Os,
  147937. + IN gctINT SignalID,
  147938. + IN gctUINT32 Wait
  147939. + );
  147940. +
  147941. +/* Signal a signal used in the user space. */
  147942. +gceSTATUS
  147943. +gckOS_SignalUserSignal(
  147944. + IN gckOS Os,
  147945. + IN gctINT SignalID,
  147946. + IN gctBOOL State
  147947. + );
  147948. +#endif /* USE_NEW_LINUX_SIGNAL */
  147949. +
  147950. +/* Set a signal owned by a process. */
  147951. +#if defined(__QNXNTO__)
  147952. +gceSTATUS
  147953. +gckOS_UserSignal(
  147954. + IN gckOS Os,
  147955. + IN gctSIGNAL Signal,
  147956. + IN gctINT Recvid,
  147957. + IN gctINT Coid
  147958. + );
  147959. +#else
  147960. +gceSTATUS
  147961. +gckOS_UserSignal(
  147962. + IN gckOS Os,
  147963. + IN gctSIGNAL Signal,
  147964. + IN gctHANDLE Process
  147965. + );
  147966. +#endif
  147967. +
  147968. +/******************************************************************************\
  147969. +** Cache Support
  147970. +*/
  147971. +
  147972. +gceSTATUS
  147973. +gckOS_CacheClean(
  147974. + gckOS Os,
  147975. + gctUINT32 ProcessID,
  147976. + gctPHYS_ADDR Handle,
  147977. + gctPOINTER Physical,
  147978. + gctPOINTER Logical,
  147979. + gctSIZE_T Bytes
  147980. + );
  147981. +
  147982. +gceSTATUS
  147983. +gckOS_CacheFlush(
  147984. + gckOS Os,
  147985. + gctUINT32 ProcessID,
  147986. + gctPHYS_ADDR Handle,
  147987. + gctPOINTER Physical,
  147988. + gctPOINTER Logical,
  147989. + gctSIZE_T Bytes
  147990. + );
  147991. +
  147992. +gceSTATUS
  147993. +gckOS_CacheInvalidate(
  147994. + gckOS Os,
  147995. + gctUINT32 ProcessID,
  147996. + gctPHYS_ADDR Handle,
  147997. + gctPOINTER Physical,
  147998. + gctPOINTER Logical,
  147999. + gctSIZE_T Bytes
  148000. + );
  148001. +
  148002. +/******************************************************************************\
  148003. +** Debug Support
  148004. +*/
  148005. +
  148006. +void
  148007. +gckOS_SetDebugLevel(
  148008. + IN gctUINT32 Level
  148009. + );
  148010. +
  148011. +void
  148012. +gckOS_SetDebugZone(
  148013. + IN gctUINT32 Zone
  148014. + );
  148015. +
  148016. +void
  148017. +gckOS_SetDebugLevelZone(
  148018. + IN gctUINT32 Level,
  148019. + IN gctUINT32 Zone
  148020. + );
  148021. +
  148022. +void
  148023. +gckOS_SetDebugZones(
  148024. + IN gctUINT32 Zones,
  148025. + IN gctBOOL Enable
  148026. + );
  148027. +
  148028. +void
  148029. +gckOS_SetDebugFile(
  148030. + IN gctCONST_STRING FileName
  148031. + );
  148032. +
  148033. +/*******************************************************************************
  148034. +** Broadcast interface.
  148035. +*/
  148036. +
  148037. +typedef enum _gceBROADCAST
  148038. +{
  148039. + /* GPU might be idle. */
  148040. + gcvBROADCAST_GPU_IDLE,
  148041. +
  148042. + /* A commit is going to happen. */
  148043. + gcvBROADCAST_GPU_COMMIT,
  148044. +
  148045. + /* GPU seems to be stuck. */
  148046. + gcvBROADCAST_GPU_STUCK,
  148047. +
  148048. + /* First process gets attached. */
  148049. + gcvBROADCAST_FIRST_PROCESS,
  148050. +
  148051. + /* Last process gets detached. */
  148052. + gcvBROADCAST_LAST_PROCESS,
  148053. +
  148054. + /* AXI bus error. */
  148055. + gcvBROADCAST_AXI_BUS_ERROR,
  148056. +}
  148057. +gceBROADCAST;
  148058. +
  148059. +gceSTATUS
  148060. +gckOS_Broadcast(
  148061. + IN gckOS Os,
  148062. + IN gckHARDWARE Hardware,
  148063. + IN gceBROADCAST Reason
  148064. + );
  148065. +
  148066. +gceSTATUS
  148067. +gckOS_BroadcastHurry(
  148068. + IN gckOS Os,
  148069. + IN gckHARDWARE Hardware,
  148070. + IN gctUINT Urgency
  148071. + );
  148072. +
  148073. +gceSTATUS
  148074. +gckOS_BroadcastCalibrateSpeed(
  148075. + IN gckOS Os,
  148076. + IN gckHARDWARE Hardware,
  148077. + IN gctUINT Idle,
  148078. + IN gctUINT Time
  148079. + );
  148080. +
  148081. +/*******************************************************************************
  148082. +**
  148083. +** gckOS_SetGPUPower
  148084. +**
  148085. +** Set the power of the GPU on or off.
  148086. +**
  148087. +** INPUT:
  148088. +**
  148089. +** gckOS Os
  148090. +** Pointer to a gckOS object.ß
  148091. +**
  148092. +** gckCORE Core
  148093. +** GPU whose power is set.
  148094. +**
  148095. +** gctBOOL Clock
  148096. +** gcvTRUE to turn on the clock, or gcvFALSE to turn off the clock.
  148097. +**
  148098. +** gctBOOL Power
  148099. +** gcvTRUE to turn on the power, or gcvFALSE to turn off the power.
  148100. +**
  148101. +** OUTPUT:
  148102. +**
  148103. +** Nothing.
  148104. +*/
  148105. +gceSTATUS
  148106. +gckOS_SetGPUPower(
  148107. + IN gckOS Os,
  148108. + IN gceCORE Core,
  148109. + IN gctBOOL Clock,
  148110. + IN gctBOOL Power
  148111. + );
  148112. +
  148113. +gceSTATUS
  148114. +gckOS_ResetGPU(
  148115. + IN gckOS Os,
  148116. + IN gceCORE Core
  148117. + );
  148118. +
  148119. +gceSTATUS
  148120. +gckOS_PrepareGPUFrequency(
  148121. + IN gckOS Os,
  148122. + IN gceCORE Core
  148123. + );
  148124. +
  148125. +gceSTATUS
  148126. +gckOS_FinishGPUFrequency(
  148127. + IN gckOS Os,
  148128. + IN gceCORE Core
  148129. + );
  148130. +
  148131. +gceSTATUS
  148132. +gckOS_QueryGPUFrequency(
  148133. + IN gckOS Os,
  148134. + IN gceCORE Core,
  148135. + OUT gctUINT32 * Frequency,
  148136. + OUT gctUINT8 * Scale
  148137. + );
  148138. +
  148139. +gceSTATUS
  148140. +gckOS_SetGPUFrequency(
  148141. + IN gckOS Os,
  148142. + IN gceCORE Core,
  148143. + IN gctUINT8 Scale
  148144. + );
  148145. +
  148146. +/*******************************************************************************
  148147. +** Semaphores.
  148148. +*/
  148149. +
  148150. +/* Create a new semaphore. */
  148151. +gceSTATUS
  148152. +gckOS_CreateSemaphore(
  148153. + IN gckOS Os,
  148154. + OUT gctPOINTER * Semaphore
  148155. + );
  148156. +
  148157. +#if gcdENABLE_VG
  148158. +gceSTATUS
  148159. +gckOS_CreateSemaphoreVG(
  148160. + IN gckOS Os,
  148161. + OUT gctPOINTER * Semaphore
  148162. + );
  148163. +#endif
  148164. +
  148165. +/* Delete a semahore. */
  148166. +gceSTATUS
  148167. +gckOS_DestroySemaphore(
  148168. + IN gckOS Os,
  148169. + IN gctPOINTER Semaphore
  148170. + );
  148171. +
  148172. +/* Acquire a semahore. */
  148173. +gceSTATUS
  148174. +gckOS_AcquireSemaphore(
  148175. + IN gckOS Os,
  148176. + IN gctPOINTER Semaphore
  148177. + );
  148178. +
  148179. +/* Try to acquire a semahore. */
  148180. +gceSTATUS
  148181. +gckOS_TryAcquireSemaphore(
  148182. + IN gckOS Os,
  148183. + IN gctPOINTER Semaphore
  148184. + );
  148185. +
  148186. +/* Release a semahore. */
  148187. +gceSTATUS
  148188. +gckOS_ReleaseSemaphore(
  148189. + IN gckOS Os,
  148190. + IN gctPOINTER Semaphore
  148191. + );
  148192. +
  148193. +/*******************************************************************************
  148194. +** Timer API.
  148195. +*/
  148196. +
  148197. +typedef void (*gctTIMERFUNCTION)(gctPOINTER);
  148198. +
  148199. +/* Create a timer. */
  148200. +gceSTATUS
  148201. +gckOS_CreateTimer(
  148202. + IN gckOS Os,
  148203. + IN gctTIMERFUNCTION Function,
  148204. + IN gctPOINTER Data,
  148205. + OUT gctPOINTER * Timer
  148206. + );
  148207. +
  148208. +/* Destory a timer. */
  148209. +gceSTATUS
  148210. +gckOS_DestroyTimer(
  148211. + IN gckOS Os,
  148212. + IN gctPOINTER Timer
  148213. + );
  148214. +
  148215. +/* Start a timer. */
  148216. +gceSTATUS
  148217. +gckOS_StartTimer(
  148218. + IN gckOS Os,
  148219. + IN gctPOINTER Timer,
  148220. + IN gctUINT32 Delay
  148221. + );
  148222. +
  148223. +/* Stop a timer. */
  148224. +gceSTATUS
  148225. +gckOS_StopTimer(
  148226. + IN gckOS Os,
  148227. + IN gctPOINTER Timer
  148228. + );
  148229. +
  148230. +/******************************************************************************\
  148231. +********************************* gckHEAP Object ********************************
  148232. +\******************************************************************************/
  148233. +
  148234. +typedef struct _gckHEAP * gckHEAP;
  148235. +
  148236. +/* Construct a new gckHEAP object. */
  148237. +gceSTATUS
  148238. +gckHEAP_Construct(
  148239. + IN gckOS Os,
  148240. + IN gctSIZE_T AllocationSize,
  148241. + OUT gckHEAP * Heap
  148242. + );
  148243. +
  148244. +/* Destroy an gckHEAP object. */
  148245. +gceSTATUS
  148246. +gckHEAP_Destroy(
  148247. + IN gckHEAP Heap
  148248. + );
  148249. +
  148250. +/* Allocate memory. */
  148251. +gceSTATUS
  148252. +gckHEAP_Allocate(
  148253. + IN gckHEAP Heap,
  148254. + IN gctSIZE_T Bytes,
  148255. + OUT gctPOINTER * Node
  148256. + );
  148257. +
  148258. +/* Free memory. */
  148259. +gceSTATUS
  148260. +gckHEAP_Free(
  148261. + IN gckHEAP Heap,
  148262. + IN gctPOINTER Node
  148263. + );
  148264. +
  148265. +/* Profile the heap. */
  148266. +gceSTATUS
  148267. +gckHEAP_ProfileStart(
  148268. + IN gckHEAP Heap
  148269. + );
  148270. +
  148271. +gceSTATUS
  148272. +gckHEAP_ProfileEnd(
  148273. + IN gckHEAP Heap,
  148274. + IN gctCONST_STRING Title
  148275. + );
  148276. +
  148277. +
  148278. +/******************************************************************************\
  148279. +******************************** gckVIDMEM Object ******************************
  148280. +\******************************************************************************/
  148281. +
  148282. +typedef struct _gckVIDMEM * gckVIDMEM;
  148283. +typedef struct _gckKERNEL * gckKERNEL;
  148284. +typedef struct _gckDB * gckDB;
  148285. +typedef struct _gckDVFS * gckDVFS;
  148286. +
  148287. +/* Construct a new gckVIDMEM object. */
  148288. +gceSTATUS
  148289. +gckVIDMEM_Construct(
  148290. + IN gckOS Os,
  148291. + IN gctUINT32 BaseAddress,
  148292. + IN gctSIZE_T Bytes,
  148293. + IN gctSIZE_T Threshold,
  148294. + IN gctSIZE_T Banking,
  148295. + OUT gckVIDMEM * Memory
  148296. + );
  148297. +
  148298. +/* Destroy an gckVDIMEM object. */
  148299. +gceSTATUS
  148300. +gckVIDMEM_Destroy(
  148301. + IN gckVIDMEM Memory
  148302. + );
  148303. +
  148304. +/* Allocate rectangular memory. */
  148305. +gceSTATUS
  148306. +gckVIDMEM_Allocate(
  148307. + IN gckVIDMEM Memory,
  148308. + IN gctUINT Width,
  148309. + IN gctUINT Height,
  148310. + IN gctUINT Depth,
  148311. + IN gctUINT BytesPerPixel,
  148312. + IN gctUINT32 Alignment,
  148313. + IN gceSURF_TYPE Type,
  148314. + OUT gcuVIDMEM_NODE_PTR * Node
  148315. + );
  148316. +
  148317. +/* Allocate linear memory. */
  148318. +gceSTATUS
  148319. +gckVIDMEM_AllocateLinear(
  148320. + IN gckVIDMEM Memory,
  148321. + IN gctSIZE_T Bytes,
  148322. + IN gctUINT32 Alignment,
  148323. + IN gceSURF_TYPE Type,
  148324. + OUT gcuVIDMEM_NODE_PTR * Node
  148325. + );
  148326. +
  148327. +/* Free memory. */
  148328. +gceSTATUS
  148329. +gckVIDMEM_Free(
  148330. + IN gcuVIDMEM_NODE_PTR Node
  148331. + );
  148332. +
  148333. +/* Lock memory. */
  148334. +gceSTATUS
  148335. +gckVIDMEM_Lock(
  148336. + IN gckKERNEL Kernel,
  148337. + IN gcuVIDMEM_NODE_PTR Node,
  148338. + IN gctBOOL Cacheable,
  148339. + OUT gctUINT32 * Address
  148340. + );
  148341. +
  148342. +/* Unlock memory. */
  148343. +gceSTATUS
  148344. +gckVIDMEM_Unlock(
  148345. + IN gckKERNEL Kernel,
  148346. + IN gcuVIDMEM_NODE_PTR Node,
  148347. + IN gceSURF_TYPE Type,
  148348. + IN OUT gctBOOL * Asynchroneous
  148349. + );
  148350. +
  148351. +/* Construct a gcuVIDMEM_NODE union for virtual memory. */
  148352. +gceSTATUS
  148353. +gckVIDMEM_ConstructVirtual(
  148354. + IN gckKERNEL Kernel,
  148355. + IN gctBOOL Contiguous,
  148356. + IN gctSIZE_T Bytes,
  148357. + OUT gcuVIDMEM_NODE_PTR * Node
  148358. + );
  148359. +
  148360. +/* Destroy a gcuVIDMEM_NODE union for virtual memory. */
  148361. +gceSTATUS
  148362. +gckVIDMEM_DestroyVirtual(
  148363. + IN gcuVIDMEM_NODE_PTR Node
  148364. + );
  148365. +
  148366. +/******************************************************************************\
  148367. +******************************** gckKERNEL Object ******************************
  148368. +\******************************************************************************/
  148369. +
  148370. +struct _gcsHAL_INTERFACE;
  148371. +
  148372. +/* Notifications. */
  148373. +typedef enum _gceNOTIFY
  148374. +{
  148375. + gcvNOTIFY_INTERRUPT,
  148376. + gcvNOTIFY_COMMAND_QUEUE,
  148377. +}
  148378. +gceNOTIFY;
  148379. +
  148380. +/* Flush flags. */
  148381. +typedef enum _gceKERNEL_FLUSH
  148382. +{
  148383. + gcvFLUSH_COLOR = 0x01,
  148384. + gcvFLUSH_DEPTH = 0x02,
  148385. + gcvFLUSH_TEXTURE = 0x04,
  148386. + gcvFLUSH_2D = 0x08,
  148387. + gcvFLUSH_ALL = gcvFLUSH_COLOR
  148388. + | gcvFLUSH_DEPTH
  148389. + | gcvFLUSH_TEXTURE
  148390. + | gcvFLUSH_2D,
  148391. +}
  148392. +gceKERNEL_FLUSH;
  148393. +
  148394. +/* Construct a new gckKERNEL object. */
  148395. +gceSTATUS
  148396. +gckKERNEL_Construct(
  148397. + IN gckOS Os,
  148398. + IN gceCORE Core,
  148399. + IN gctPOINTER Context,
  148400. + IN gckDB SharedDB,
  148401. + OUT gckKERNEL * Kernel
  148402. + );
  148403. +
  148404. +/* Destroy an gckKERNEL object. */
  148405. +gceSTATUS
  148406. +gckKERNEL_Destroy(
  148407. + IN gckKERNEL Kernel
  148408. + );
  148409. +
  148410. +/* Dispatch a user-level command. */
  148411. +gceSTATUS
  148412. +gckKERNEL_Dispatch(
  148413. + IN gckKERNEL Kernel,
  148414. + IN gctBOOL FromUser,
  148415. + IN OUT struct _gcsHAL_INTERFACE * Interface
  148416. + );
  148417. +
  148418. +/* Query the video memory. */
  148419. +gceSTATUS
  148420. +gckKERNEL_QueryVideoMemory(
  148421. + IN gckKERNEL Kernel,
  148422. + OUT struct _gcsHAL_INTERFACE * Interface
  148423. + );
  148424. +
  148425. +/* Lookup the gckVIDMEM object for a pool. */
  148426. +gceSTATUS
  148427. +gckKERNEL_GetVideoMemoryPool(
  148428. + IN gckKERNEL Kernel,
  148429. + IN gcePOOL Pool,
  148430. + OUT gckVIDMEM * VideoMemory
  148431. + );
  148432. +
  148433. +#if gcdUSE_VIDMEM_PER_PID
  148434. +gceSTATUS
  148435. +gckKERNEL_GetVideoMemoryPoolPid(
  148436. + IN gckKERNEL Kernel,
  148437. + IN gcePOOL Pool,
  148438. + IN gctUINT32 Pid,
  148439. + OUT gckVIDMEM * VideoMemory
  148440. + );
  148441. +
  148442. +gceSTATUS
  148443. +gckKERNEL_CreateVideoMemoryPoolPid(
  148444. + IN gckKERNEL Kernel,
  148445. + IN gcePOOL Pool,
  148446. + IN gctUINT32 Pid,
  148447. + OUT gckVIDMEM * VideoMemory
  148448. + );
  148449. +
  148450. +gceSTATUS
  148451. +gckKERNEL_RemoveVideoMemoryPoolPid(
  148452. + IN gckKERNEL Kernel,
  148453. + IN gckVIDMEM VideoMemory
  148454. + );
  148455. +#endif
  148456. +
  148457. +/* Map video memory. */
  148458. +gceSTATUS
  148459. +gckKERNEL_MapVideoMemory(
  148460. + IN gckKERNEL Kernel,
  148461. + IN gctBOOL InUserSpace,
  148462. + IN gctUINT32 Address,
  148463. +#ifdef __QNXNTO__
  148464. + IN gctUINT32 Pid,
  148465. + IN gctUINT32 Bytes,
  148466. +#endif
  148467. + OUT gctPOINTER * Logical
  148468. + );
  148469. +
  148470. +/* Map video memory. */
  148471. +gceSTATUS
  148472. +gckKERNEL_MapVideoMemoryEx(
  148473. + IN gckKERNEL Kernel,
  148474. + IN gceCORE Core,
  148475. + IN gctBOOL InUserSpace,
  148476. + IN gctUINT32 Address,
  148477. +#ifdef __QNXNTO__
  148478. + IN gctUINT32 Pid,
  148479. + IN gctUINT32 Bytes,
  148480. +#endif
  148481. + OUT gctPOINTER * Logical
  148482. + );
  148483. +
  148484. +#ifdef __QNXNTO__
  148485. +/* Unmap video memory. */
  148486. +gceSTATUS
  148487. +gckKERNEL_UnmapVideoMemory(
  148488. + IN gckKERNEL Kernel,
  148489. + IN gctPOINTER Logical,
  148490. + IN gctUINT32 Pid,
  148491. + IN gctUINT32 Bytes
  148492. + );
  148493. +#endif
  148494. +
  148495. +/* Map memory. */
  148496. +gceSTATUS
  148497. +gckKERNEL_MapMemory(
  148498. + IN gckKERNEL Kernel,
  148499. + IN gctPHYS_ADDR Physical,
  148500. + IN gctSIZE_T Bytes,
  148501. + OUT gctPOINTER * Logical
  148502. + );
  148503. +
  148504. +/* Unmap memory. */
  148505. +gceSTATUS
  148506. +gckKERNEL_UnmapMemory(
  148507. + IN gckKERNEL Kernel,
  148508. + IN gctPHYS_ADDR Physical,
  148509. + IN gctSIZE_T Bytes,
  148510. + IN gctPOINTER Logical
  148511. + );
  148512. +
  148513. +/* Notification of events. */
  148514. +gceSTATUS
  148515. +gckKERNEL_Notify(
  148516. + IN gckKERNEL Kernel,
  148517. + IN gceNOTIFY Notifcation,
  148518. + IN gctBOOL Data
  148519. + );
  148520. +
  148521. +gceSTATUS
  148522. +gckKERNEL_QuerySettings(
  148523. + IN gckKERNEL Kernel,
  148524. + OUT gcsKERNEL_SETTINGS * Settings
  148525. + );
  148526. +
  148527. +/*******************************************************************************
  148528. +**
  148529. +** gckKERNEL_Recovery
  148530. +**
  148531. +** Try to recover the GPU from a fatal error.
  148532. +**
  148533. +** INPUT:
  148534. +**
  148535. +** gckKERNEL Kernel
  148536. +** Pointer to an gckKERNEL object.
  148537. +**
  148538. +** OUTPUT:
  148539. +**
  148540. +** Nothing.
  148541. +*/
  148542. +gceSTATUS
  148543. +gckKERNEL_Recovery(
  148544. + IN gckKERNEL Kernel
  148545. + );
  148546. +
  148547. +/* Set the value of timeout on HW operation. */
  148548. +void
  148549. +gckKERNEL_SetTimeOut(
  148550. + IN gckKERNEL Kernel,
  148551. + IN gctUINT32 timeOut
  148552. + );
  148553. +
  148554. +/* Get access to the user data. */
  148555. +gceSTATUS
  148556. +gckKERNEL_OpenUserData(
  148557. + IN gckKERNEL Kernel,
  148558. + IN gctBOOL NeedCopy,
  148559. + IN gctPOINTER StaticStorage,
  148560. + IN gctPOINTER UserPointer,
  148561. + IN gctSIZE_T Size,
  148562. + OUT gctPOINTER * KernelPointer
  148563. + );
  148564. +
  148565. +/* Release resources associated with the user data connection. */
  148566. +gceSTATUS
  148567. +gckKERNEL_CloseUserData(
  148568. + IN gckKERNEL Kernel,
  148569. + IN gctBOOL NeedCopy,
  148570. + IN gctBOOL FlushData,
  148571. + IN gctPOINTER UserPointer,
  148572. + IN gctSIZE_T Size,
  148573. + OUT gctPOINTER * KernelPointer
  148574. + );
  148575. +
  148576. +gceSTATUS
  148577. +gckDVFS_Construct(
  148578. + IN gckHARDWARE Hardware,
  148579. + OUT gckDVFS * Frequency
  148580. + );
  148581. +
  148582. +gceSTATUS
  148583. +gckDVFS_Destroy(
  148584. + IN gckDVFS Dvfs
  148585. + );
  148586. +
  148587. +gceSTATUS
  148588. +gckDVFS_Start(
  148589. + IN gckDVFS Dvfs
  148590. + );
  148591. +
  148592. +gceSTATUS
  148593. +gckDVFS_Stop(
  148594. + IN gckDVFS Dvfs
  148595. + );
  148596. +
  148597. +/******************************************************************************\
  148598. +******************************* gckHARDWARE Object *****************************
  148599. +\******************************************************************************/
  148600. +
  148601. +/* Construct a new gckHARDWARE object. */
  148602. +gceSTATUS
  148603. +gckHARDWARE_Construct(
  148604. + IN gckOS Os,
  148605. + IN gceCORE Core,
  148606. + OUT gckHARDWARE * Hardware
  148607. + );
  148608. +
  148609. +/* Destroy an gckHARDWARE object. */
  148610. +gceSTATUS
  148611. +gckHARDWARE_Destroy(
  148612. + IN gckHARDWARE Hardware
  148613. + );
  148614. +
  148615. +/* Get hardware type. */
  148616. +gceSTATUS
  148617. +gckHARDWARE_GetType(
  148618. + IN gckHARDWARE Hardware,
  148619. + OUT gceHARDWARE_TYPE * Type
  148620. + );
  148621. +
  148622. +/* Query system memory requirements. */
  148623. +gceSTATUS
  148624. +gckHARDWARE_QuerySystemMemory(
  148625. + IN gckHARDWARE Hardware,
  148626. + OUT gctSIZE_T * SystemSize,
  148627. + OUT gctUINT32 * SystemBaseAddress
  148628. + );
  148629. +
  148630. +/* Build virtual address. */
  148631. +gceSTATUS
  148632. +gckHARDWARE_BuildVirtualAddress(
  148633. + IN gckHARDWARE Hardware,
  148634. + IN gctUINT32 Index,
  148635. + IN gctUINT32 Offset,
  148636. + OUT gctUINT32 * Address
  148637. + );
  148638. +
  148639. +/* Query command buffer requirements. */
  148640. +gceSTATUS
  148641. +gckHARDWARE_QueryCommandBuffer(
  148642. + IN gckHARDWARE Hardware,
  148643. + OUT gctSIZE_T * Alignment,
  148644. + OUT gctSIZE_T * ReservedHead,
  148645. + OUT gctSIZE_T * ReservedTail
  148646. + );
  148647. +
  148648. +/* Add a WAIT/LINK pair in the command queue. */
  148649. +gceSTATUS
  148650. +gckHARDWARE_WaitLink(
  148651. + IN gckHARDWARE Hardware,
  148652. + IN gctPOINTER Logical,
  148653. + IN gctUINT32 Offset,
  148654. + IN OUT gctSIZE_T * Bytes,
  148655. + OUT gctUINT32 * WaitOffset,
  148656. + OUT gctSIZE_T * WaitBytes
  148657. + );
  148658. +
  148659. +/* Kickstart the command processor. */
  148660. +gceSTATUS
  148661. +gckHARDWARE_Execute(
  148662. + IN gckHARDWARE Hardware,
  148663. + IN gctPOINTER Logical,
  148664. +#ifdef __QNXNTO__
  148665. + IN gctPOINTER Physical,
  148666. + IN gctBOOL PhysicalAddresses,
  148667. +#endif
  148668. + IN gctSIZE_T Bytes
  148669. + );
  148670. +
  148671. +/* Add an END command in the command queue. */
  148672. +gceSTATUS
  148673. +gckHARDWARE_End(
  148674. + IN gckHARDWARE Hardware,
  148675. + IN gctPOINTER Logical,
  148676. + IN OUT gctSIZE_T * Bytes
  148677. + );
  148678. +
  148679. +/* Add a NOP command in the command queue. */
  148680. +gceSTATUS
  148681. +gckHARDWARE_Nop(
  148682. + IN gckHARDWARE Hardware,
  148683. + IN gctPOINTER Logical,
  148684. + IN OUT gctSIZE_T * Bytes
  148685. + );
  148686. +
  148687. +/* Add a WAIT command in the command queue. */
  148688. +gceSTATUS
  148689. +gckHARDWARE_Wait(
  148690. + IN gckHARDWARE Hardware,
  148691. + IN gctPOINTER Logical,
  148692. + IN gctUINT32 Count,
  148693. + IN OUT gctSIZE_T * Bytes
  148694. + );
  148695. +
  148696. +/* Add a PIPESELECT command in the command queue. */
  148697. +gceSTATUS
  148698. +gckHARDWARE_PipeSelect(
  148699. + IN gckHARDWARE Hardware,
  148700. + IN gctPOINTER Logical,
  148701. + IN gcePIPE_SELECT Pipe,
  148702. + IN OUT gctSIZE_T * Bytes
  148703. + );
  148704. +
  148705. +/* Add a LINK command in the command queue. */
  148706. +gceSTATUS
  148707. +gckHARDWARE_Link(
  148708. + IN gckHARDWARE Hardware,
  148709. + IN gctPOINTER Logical,
  148710. + IN gctPOINTER FetchAddress,
  148711. + IN gctSIZE_T FetchSize,
  148712. + IN OUT gctSIZE_T * Bytes
  148713. + );
  148714. +
  148715. +/* Add an EVENT command in the command queue. */
  148716. +gceSTATUS
  148717. +gckHARDWARE_Event(
  148718. + IN gckHARDWARE Hardware,
  148719. + IN gctPOINTER Logical,
  148720. + IN gctUINT8 Event,
  148721. + IN gceKERNEL_WHERE FromWhere,
  148722. + IN OUT gctSIZE_T * Bytes
  148723. + );
  148724. +
  148725. +/* Query the available memory. */
  148726. +gceSTATUS
  148727. +gckHARDWARE_QueryMemory(
  148728. + IN gckHARDWARE Hardware,
  148729. + OUT gctSIZE_T * InternalSize,
  148730. + OUT gctUINT32 * InternalBaseAddress,
  148731. + OUT gctUINT32 * InternalAlignment,
  148732. + OUT gctSIZE_T * ExternalSize,
  148733. + OUT gctUINT32 * ExternalBaseAddress,
  148734. + OUT gctUINT32 * ExternalAlignment,
  148735. + OUT gctUINT32 * HorizontalTileSize,
  148736. + OUT gctUINT32 * VerticalTileSize
  148737. + );
  148738. +
  148739. +/* Query the identity of the hardware. */
  148740. +gceSTATUS
  148741. +gckHARDWARE_QueryChipIdentity(
  148742. + IN gckHARDWARE Hardware,
  148743. + OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  148744. + );
  148745. +
  148746. +/* Query the shader support. */
  148747. +gceSTATUS
  148748. +gckHARDWARE_QueryShaderCaps(
  148749. + IN gckHARDWARE Hardware,
  148750. + OUT gctUINT * VertexUniforms,
  148751. + OUT gctUINT * FragmentUniforms,
  148752. + OUT gctUINT * Varyings
  148753. + );
  148754. +
  148755. +/* Split a harwdare specific address into API stuff. */
  148756. +gceSTATUS
  148757. +gckHARDWARE_SplitMemory(
  148758. + IN gckHARDWARE Hardware,
  148759. + IN gctUINT32 Address,
  148760. + OUT gcePOOL * Pool,
  148761. + OUT gctUINT32 * Offset
  148762. + );
  148763. +
  148764. +/* Update command queue tail pointer. */
  148765. +gceSTATUS
  148766. +gckHARDWARE_UpdateQueueTail(
  148767. + IN gckHARDWARE Hardware,
  148768. + IN gctPOINTER Logical,
  148769. + IN gctUINT32 Offset
  148770. + );
  148771. +
  148772. +/* Convert logical address to hardware specific address. */
  148773. +gceSTATUS
  148774. +gckHARDWARE_ConvertLogical(
  148775. + IN gckHARDWARE Hardware,
  148776. + IN gctPOINTER Logical,
  148777. + OUT gctUINT32 * Address
  148778. + );
  148779. +
  148780. +#ifdef __QNXNTO__
  148781. +/* Convert physical address to hardware specific address. */
  148782. +gceSTATUS
  148783. +gckHARDWARE_ConvertPhysical(
  148784. + IN gckHARDWARE Hardware,
  148785. + IN gctPHYS_ADDR Physical,
  148786. + OUT gctUINT32 * Address
  148787. + );
  148788. +#endif
  148789. +
  148790. +/* Interrupt manager. */
  148791. +gceSTATUS
  148792. +gckHARDWARE_Interrupt(
  148793. + IN gckHARDWARE Hardware,
  148794. + IN gctBOOL InterruptValid
  148795. + );
  148796. +
  148797. +/* Program MMU. */
  148798. +gceSTATUS
  148799. +gckHARDWARE_SetMMU(
  148800. + IN gckHARDWARE Hardware,
  148801. + IN gctPOINTER Logical
  148802. + );
  148803. +
  148804. +/* Flush the MMU. */
  148805. +gceSTATUS
  148806. +gckHARDWARE_FlushMMU(
  148807. + IN gckHARDWARE Hardware
  148808. + );
  148809. +
  148810. +/* Set the page table base address. */
  148811. +gceSTATUS
  148812. +gckHARDWARE_SetMMUv2(
  148813. + IN gckHARDWARE Hardware,
  148814. + IN gctBOOL Enable,
  148815. + IN gctPOINTER MtlbAddress,
  148816. + IN gceMMU_MODE Mode,
  148817. + IN gctPOINTER SafeAddress,
  148818. + IN gctBOOL FromPower
  148819. + );
  148820. +
  148821. +/* Get idle register. */
  148822. +gceSTATUS
  148823. +gckHARDWARE_GetIdle(
  148824. + IN gckHARDWARE Hardware,
  148825. + IN gctBOOL Wait,
  148826. + OUT gctUINT32 * Data
  148827. + );
  148828. +
  148829. +/* Flush the caches. */
  148830. +gceSTATUS
  148831. +gckHARDWARE_Flush(
  148832. + IN gckHARDWARE Hardware,
  148833. + IN gceKERNEL_FLUSH Flush,
  148834. + IN gctPOINTER Logical,
  148835. + IN OUT gctSIZE_T * Bytes
  148836. + );
  148837. +
  148838. +/* Enable/disable fast clear. */
  148839. +gceSTATUS
  148840. +gckHARDWARE_SetFastClear(
  148841. + IN gckHARDWARE Hardware,
  148842. + IN gctINT Enable,
  148843. + IN gctINT Compression
  148844. + );
  148845. +
  148846. +gceSTATUS
  148847. +gckHARDWARE_ReadInterrupt(
  148848. + IN gckHARDWARE Hardware,
  148849. + OUT gctUINT32_PTR IDs
  148850. + );
  148851. +
  148852. +/* Power management. */
  148853. +gceSTATUS
  148854. +gckHARDWARE_SetPowerManagementState(
  148855. + IN gckHARDWARE Hardware,
  148856. + IN gceCHIPPOWERSTATE State
  148857. + );
  148858. +
  148859. +gceSTATUS
  148860. +gckHARDWARE_QueryPowerManagementState(
  148861. + IN gckHARDWARE Hardware,
  148862. + OUT gceCHIPPOWERSTATE* State
  148863. + );
  148864. +
  148865. +gceSTATUS
  148866. +gckHARDWARE_SetPowerManagement(
  148867. + IN gckHARDWARE Hardware,
  148868. + IN gctBOOL PowerManagement
  148869. + );
  148870. +
  148871. +gceSTATUS
  148872. +gckHARDWARE_SetGpuProfiler(
  148873. + IN gckHARDWARE Hardware,
  148874. + IN gctBOOL GpuProfiler
  148875. + );
  148876. +
  148877. +#if gcdENABLE_FSCALE_VAL_ADJUST
  148878. +gceSTATUS
  148879. +gckHARDWARE_SetFscaleValue(
  148880. + IN gckHARDWARE Hardware,
  148881. + IN gctUINT32 FscaleValue
  148882. + );
  148883. +
  148884. +gceSTATUS
  148885. +gckHARDWARE_GetFscaleValue(
  148886. + IN gckHARDWARE Hardware,
  148887. + IN gctUINT * FscaleValue,
  148888. + IN gctUINT * MinFscaleValue,
  148889. + IN gctUINT * MaxFscaleValue
  148890. + );
  148891. +#endif
  148892. +
  148893. +#if gcdPOWEROFF_TIMEOUT
  148894. +gceSTATUS
  148895. +gckHARDWARE_SetPowerOffTimeout(
  148896. + IN gckHARDWARE Hardware,
  148897. + IN gctUINT32 Timeout
  148898. +);
  148899. +
  148900. +gceSTATUS
  148901. +gckHARDWARE_QueryPowerOffTimeout(
  148902. + IN gckHARDWARE Hardware,
  148903. + OUT gctUINT32* Timeout
  148904. +);
  148905. +#endif
  148906. +
  148907. +/* Profile 2D Engine. */
  148908. +gceSTATUS
  148909. +gckHARDWARE_ProfileEngine2D(
  148910. + IN gckHARDWARE Hardware,
  148911. + OUT gcs2D_PROFILE_PTR Profile
  148912. + );
  148913. +
  148914. +gceSTATUS
  148915. +gckHARDWARE_InitializeHardware(
  148916. + IN gckHARDWARE Hardware
  148917. + );
  148918. +
  148919. +gceSTATUS
  148920. +gckHARDWARE_Reset(
  148921. + IN gckHARDWARE Hardware
  148922. + );
  148923. +
  148924. +typedef gceSTATUS (*gctISRMANAGERFUNC)(gctPOINTER Context, gceCORE Core);
  148925. +
  148926. +gceSTATUS
  148927. +gckHARDWARE_SetIsrManager(
  148928. + IN gckHARDWARE Hardware,
  148929. + IN gctISRMANAGERFUNC StartIsr,
  148930. + IN gctISRMANAGERFUNC StopIsr,
  148931. + IN gctPOINTER Context
  148932. + );
  148933. +
  148934. +/* Start a composition. */
  148935. +gceSTATUS
  148936. +gckHARDWARE_Compose(
  148937. + IN gckHARDWARE Hardware,
  148938. + IN gctUINT32 ProcessID,
  148939. + IN gctPHYS_ADDR Physical,
  148940. + IN gctPOINTER Logical,
  148941. + IN gctSIZE_T Offset,
  148942. + IN gctSIZE_T Size,
  148943. + IN gctUINT8 EventID
  148944. + );
  148945. +
  148946. +/* Check for Hardware features. */
  148947. +gceSTATUS
  148948. +gckHARDWARE_IsFeatureAvailable(
  148949. + IN gckHARDWARE Hardware,
  148950. + IN gceFEATURE Feature
  148951. + );
  148952. +
  148953. +gceSTATUS
  148954. +gckHARDWARE_DumpMMUException(
  148955. + IN gckHARDWARE Hardware
  148956. + );
  148957. +
  148958. +gceSTATUS
  148959. +gckHARDWARE_DumpGPUState(
  148960. + IN gckHARDWARE Hardware
  148961. + );
  148962. +
  148963. +gceSTATUS
  148964. +gckHARDWARE_InitDVFS(
  148965. + IN gckHARDWARE Hardware
  148966. + );
  148967. +
  148968. +gceSTATUS
  148969. +gckHARDWARE_QueryLoad(
  148970. + IN gckHARDWARE Hardware,
  148971. + OUT gctUINT32 * Load
  148972. + );
  148973. +
  148974. +gceSTATUS
  148975. +gckHARDWARE_SetDVFSPeroid(
  148976. + IN gckHARDWARE Hardware,
  148977. + IN gctUINT32 Frequency
  148978. + );
  148979. +
  148980. +#if !gcdENABLE_VG
  148981. +/******************************************************************************\
  148982. +***************************** gckINTERRUPT Object ******************************
  148983. +\******************************************************************************/
  148984. +
  148985. +typedef struct _gckINTERRUPT * gckINTERRUPT;
  148986. +
  148987. +typedef gceSTATUS (* gctINTERRUPT_HANDLER)(
  148988. + IN gckKERNEL Kernel
  148989. + );
  148990. +
  148991. +gceSTATUS
  148992. +gckINTERRUPT_Construct(
  148993. + IN gckKERNEL Kernel,
  148994. + OUT gckINTERRUPT * Interrupt
  148995. + );
  148996. +
  148997. +gceSTATUS
  148998. +gckINTERRUPT_Destroy(
  148999. + IN gckINTERRUPT Interrupt
  149000. + );
  149001. +
  149002. +gceSTATUS
  149003. +gckINTERRUPT_SetHandler(
  149004. + IN gckINTERRUPT Interrupt,
  149005. + IN OUT gctINT32_PTR Id,
  149006. + IN gctINTERRUPT_HANDLER Handler
  149007. + );
  149008. +
  149009. +gceSTATUS
  149010. +gckINTERRUPT_Notify(
  149011. + IN gckINTERRUPT Interrupt,
  149012. + IN gctBOOL Valid
  149013. + );
  149014. +#endif
  149015. +/******************************************************************************\
  149016. +******************************** gckEVENT Object *******************************
  149017. +\******************************************************************************/
  149018. +
  149019. +typedef struct _gckEVENT * gckEVENT;
  149020. +
  149021. +/* Construct a new gckEVENT object. */
  149022. +gceSTATUS
  149023. +gckEVENT_Construct(
  149024. + IN gckKERNEL Kernel,
  149025. + OUT gckEVENT * Event
  149026. + );
  149027. +
  149028. +/* Destroy an gckEVENT object. */
  149029. +gceSTATUS
  149030. +gckEVENT_Destroy(
  149031. + IN gckEVENT Event
  149032. + );
  149033. +
  149034. +/* Add a new event to the list of events. */
  149035. +gceSTATUS
  149036. +gckEVENT_AddList(
  149037. + IN gckEVENT Event,
  149038. + IN gcsHAL_INTERFACE_PTR Interface,
  149039. + IN gceKERNEL_WHERE FromWhere,
  149040. + IN gctBOOL AllocateAllowed,
  149041. + IN gctBOOL FromKernel
  149042. + );
  149043. +
  149044. +/* Schedule a FreeNonPagedMemory event. */
  149045. +gceSTATUS
  149046. +gckEVENT_FreeNonPagedMemory(
  149047. + IN gckEVENT Event,
  149048. + IN gctSIZE_T Bytes,
  149049. + IN gctPHYS_ADDR Physical,
  149050. + IN gctPOINTER Logical,
  149051. + IN gceKERNEL_WHERE FromWhere
  149052. + );
  149053. +
  149054. +/* Schedule a FreeContiguousMemory event. */
  149055. +gceSTATUS
  149056. +gckEVENT_FreeContiguousMemory(
  149057. + IN gckEVENT Event,
  149058. + IN gctSIZE_T Bytes,
  149059. + IN gctPHYS_ADDR Physical,
  149060. + IN gctPOINTER Logical,
  149061. + IN gceKERNEL_WHERE FromWhere
  149062. + );
  149063. +
  149064. +/* Schedule a FreeVideoMemory event. */
  149065. +gceSTATUS
  149066. +gckEVENT_FreeVideoMemory(
  149067. + IN gckEVENT Event,
  149068. + IN gcuVIDMEM_NODE_PTR VideoMemory,
  149069. + IN gceKERNEL_WHERE FromWhere
  149070. + );
  149071. +
  149072. +/* Schedule a signal event. */
  149073. +gceSTATUS
  149074. +gckEVENT_Signal(
  149075. + IN gckEVENT Event,
  149076. + IN gctSIGNAL Signal,
  149077. + IN gceKERNEL_WHERE FromWhere
  149078. + );
  149079. +
  149080. +/* Schedule an Unlock event. */
  149081. +gceSTATUS
  149082. +gckEVENT_Unlock(
  149083. + IN gckEVENT Event,
  149084. + IN gceKERNEL_WHERE FromWhere,
  149085. + IN gcuVIDMEM_NODE_PTR Node,
  149086. + IN gceSURF_TYPE Type
  149087. + );
  149088. +
  149089. +gceSTATUS
  149090. +gckEVENT_CommitDone(
  149091. + IN gckEVENT Event,
  149092. + IN gceKERNEL_WHERE FromWhere
  149093. + );
  149094. +
  149095. +#if gcdVIRTUAL_COMMAND_BUFFER
  149096. +/* Schedule a FreeVirtualCommandBuffer event. */
  149097. +gceSTATUS
  149098. +gckEVENT_DestroyVirtualCommandBuffer(
  149099. + IN gckEVENT Event,
  149100. + IN gctSIZE_T Bytes,
  149101. + IN gctPHYS_ADDR Physical,
  149102. + IN gctPOINTER Logical,
  149103. + IN gceKERNEL_WHERE FromWhere
  149104. + );
  149105. +#endif
  149106. +
  149107. +gceSTATUS
  149108. +gckEVENT_Submit(
  149109. + IN gckEVENT Event,
  149110. + IN gctBOOL Wait,
  149111. + IN gctBOOL FromPower
  149112. + );
  149113. +
  149114. +/* Commit an event queue. */
  149115. +gceSTATUS
  149116. +gckEVENT_Commit(
  149117. + IN gckEVENT Event,
  149118. + IN gcsQUEUE_PTR Queue
  149119. + );
  149120. +
  149121. +/* Schedule a composition event. */
  149122. +gceSTATUS
  149123. +gckEVENT_Compose(
  149124. + IN gckEVENT Event,
  149125. + IN gcsHAL_COMPOSE_PTR Info
  149126. + );
  149127. +
  149128. +/* Event callback routine. */
  149129. +gceSTATUS
  149130. +gckEVENT_Notify(
  149131. + IN gckEVENT Event,
  149132. + IN gctUINT32 IDs
  149133. + );
  149134. +
  149135. +/* Event callback routine. */
  149136. +gceSTATUS
  149137. +gckEVENT_Interrupt(
  149138. + IN gckEVENT Event,
  149139. + IN gctUINT32 IDs
  149140. + );
  149141. +
  149142. +gceSTATUS
  149143. +gckEVENT_Dump(
  149144. + IN gckEVENT Event
  149145. + );
  149146. +/******************************************************************************\
  149147. +******************************* gckCOMMAND Object ******************************
  149148. +\******************************************************************************/
  149149. +
  149150. +typedef struct _gckCOMMAND * gckCOMMAND;
  149151. +
  149152. +/* Construct a new gckCOMMAND object. */
  149153. +gceSTATUS
  149154. +gckCOMMAND_Construct(
  149155. + IN gckKERNEL Kernel,
  149156. + OUT gckCOMMAND * Command
  149157. + );
  149158. +
  149159. +/* Destroy an gckCOMMAND object. */
  149160. +gceSTATUS
  149161. +gckCOMMAND_Destroy(
  149162. + IN gckCOMMAND Command
  149163. + );
  149164. +
  149165. +/* Acquire command queue synchronization objects. */
  149166. +gceSTATUS
  149167. +gckCOMMAND_EnterCommit(
  149168. + IN gckCOMMAND Command,
  149169. + IN gctBOOL FromPower
  149170. + );
  149171. +
  149172. +/* Release command queue synchronization objects. */
  149173. +gceSTATUS
  149174. +gckCOMMAND_ExitCommit(
  149175. + IN gckCOMMAND Command,
  149176. + IN gctBOOL FromPower
  149177. + );
  149178. +
  149179. +/* Start the command queue. */
  149180. +gceSTATUS
  149181. +gckCOMMAND_Start(
  149182. + IN gckCOMMAND Command
  149183. + );
  149184. +
  149185. +/* Stop the command queue. */
  149186. +gceSTATUS
  149187. +gckCOMMAND_Stop(
  149188. + IN gckCOMMAND Command,
  149189. + IN gctBOOL FromRecovery
  149190. + );
  149191. +
  149192. +/* Commit a buffer to the command queue. */
  149193. +gceSTATUS
  149194. +gckCOMMAND_Commit(
  149195. + IN gckCOMMAND Command,
  149196. + IN gckCONTEXT Context,
  149197. + IN gcoCMDBUF CommandBuffer,
  149198. + IN gcsSTATE_DELTA_PTR StateDelta,
  149199. + IN gcsQUEUE_PTR EventQueue,
  149200. + IN gctUINT32 ProcessID
  149201. + );
  149202. +
  149203. +/* Reserve space in the command buffer. */
  149204. +gceSTATUS
  149205. +gckCOMMAND_Reserve(
  149206. + IN gckCOMMAND Command,
  149207. + IN gctSIZE_T RequestedBytes,
  149208. + OUT gctPOINTER * Buffer,
  149209. + OUT gctSIZE_T * BufferSize
  149210. + );
  149211. +
  149212. +/* Execute reserved space in the command buffer. */
  149213. +gceSTATUS
  149214. +gckCOMMAND_Execute(
  149215. + IN gckCOMMAND Command,
  149216. + IN gctSIZE_T RequstedBytes
  149217. + );
  149218. +
  149219. +/* Stall the command queue. */
  149220. +gceSTATUS
  149221. +gckCOMMAND_Stall(
  149222. + IN gckCOMMAND Command,
  149223. + IN gctBOOL FromPower
  149224. + );
  149225. +
  149226. +/* Attach user process. */
  149227. +gceSTATUS
  149228. +gckCOMMAND_Attach(
  149229. + IN gckCOMMAND Command,
  149230. + OUT gckCONTEXT * Context,
  149231. + OUT gctSIZE_T * StateCount,
  149232. + IN gctUINT32 ProcessID
  149233. + );
  149234. +
  149235. +/* Detach user process. */
  149236. +gceSTATUS
  149237. +gckCOMMAND_Detach(
  149238. + IN gckCOMMAND Command,
  149239. + IN gckCONTEXT Context
  149240. + );
  149241. +
  149242. +#if gcdVIRTUAL_COMMAND_BUFFER
  149243. +gceSTATUS
  149244. +gckCOMMAND_DumpExecutingBuffer(
  149245. + IN gckCOMMAND Command
  149246. + );
  149247. +#endif
  149248. +
  149249. +/******************************************************************************\
  149250. +********************************* gckMMU Object ********************************
  149251. +\******************************************************************************/
  149252. +
  149253. +typedef struct _gckMMU * gckMMU;
  149254. +
  149255. +/* Construct a new gckMMU object. */
  149256. +gceSTATUS
  149257. +gckMMU_Construct(
  149258. + IN gckKERNEL Kernel,
  149259. + IN gctSIZE_T MmuSize,
  149260. + OUT gckMMU * Mmu
  149261. + );
  149262. +
  149263. +/* Destroy an gckMMU object. */
  149264. +gceSTATUS
  149265. +gckMMU_Destroy(
  149266. + IN gckMMU Mmu
  149267. + );
  149268. +
  149269. +/* Enable the MMU. */
  149270. +gceSTATUS
  149271. +gckMMU_Enable(
  149272. + IN gckMMU Mmu,
  149273. + IN gctUINT32 PhysBaseAddr,
  149274. + IN gctUINT32 PhysSize
  149275. + );
  149276. +
  149277. +/* Allocate pages inside the MMU. */
  149278. +gceSTATUS
  149279. +gckMMU_AllocatePages(
  149280. + IN gckMMU Mmu,
  149281. + IN gctSIZE_T PageCount,
  149282. + OUT gctPOINTER * PageTable,
  149283. + OUT gctUINT32 * Address
  149284. + );
  149285. +
  149286. +gceSTATUS
  149287. +gckMMU_AllocatePagesEx(
  149288. + IN gckMMU Mmu,
  149289. + IN gctSIZE_T PageCount,
  149290. + IN gceSURF_TYPE Type,
  149291. + OUT gctPOINTER * PageTable,
  149292. + OUT gctUINT32 * Address
  149293. + );
  149294. +
  149295. +/* Remove a page table from the MMU. */
  149296. +gceSTATUS
  149297. +gckMMU_FreePages(
  149298. + IN gckMMU Mmu,
  149299. + IN gctPOINTER PageTable,
  149300. + IN gctSIZE_T PageCount
  149301. + );
  149302. +
  149303. +/* Set the MMU page with info. */
  149304. +gceSTATUS
  149305. +gckMMU_SetPage(
  149306. + IN gckMMU Mmu,
  149307. + IN gctUINT32 PageAddress,
  149308. + IN gctUINT32 *PageEntry
  149309. + );
  149310. +
  149311. +#ifdef __QNXNTO__
  149312. +gceSTATUS
  149313. +gckMMU_InsertNode(
  149314. + IN gckMMU Mmu,
  149315. + IN gcuVIDMEM_NODE_PTR Node);
  149316. +
  149317. +gceSTATUS
  149318. +gckMMU_RemoveNode(
  149319. + IN gckMMU Mmu,
  149320. + IN gcuVIDMEM_NODE_PTR Node);
  149321. +#endif
  149322. +
  149323. +#ifdef __QNXNTO__
  149324. +gceSTATUS
  149325. +gckMMU_FreeHandleMemory(
  149326. + IN gckKERNEL Kernel,
  149327. + IN gckMMU Mmu,
  149328. + IN gctUINT32 Pid
  149329. + );
  149330. +#endif
  149331. +
  149332. +gceSTATUS
  149333. +gckMMU_Flush(
  149334. + IN gckMMU Mmu
  149335. + );
  149336. +
  149337. +gceSTATUS
  149338. +gckMMU_DumpPageTableEntry(
  149339. + IN gckMMU Mmu,
  149340. + IN gctUINT32 Address
  149341. + );
  149342. +
  149343. +
  149344. +#if VIVANTE_PROFILER
  149345. +gceSTATUS
  149346. +gckHARDWARE_QueryProfileRegisters(
  149347. + IN gckHARDWARE Hardware,
  149348. + IN gctBOOL Clear,
  149349. + OUT gcsPROFILER_COUNTERS * Counters
  149350. + );
  149351. +#endif
  149352. +
  149353. +#if VIVANTE_PROFILER_CONTEXT
  149354. +gceSTATUS
  149355. +gckHARDWARE_QueryContextProfile(
  149356. + IN gckHARDWARE Hardware,
  149357. + IN gctBOOL Clear,
  149358. + IN gckCONTEXT Context,
  149359. + OUT gcsPROFILER_COUNTERS * Counters
  149360. + );
  149361. +
  149362. +gceSTATUS
  149363. +gckHARDWARE_UpdateContextProfile(
  149364. + IN gckHARDWARE Hardware,
  149365. + IN gckCONTEXT Context
  149366. + );
  149367. +#endif
  149368. +
  149369. +gceSTATUS
  149370. +gckOS_SignalQueryHardware(
  149371. + IN gckOS Os,
  149372. + IN gctSIGNAL Signal,
  149373. + OUT gckHARDWARE * Hardware
  149374. + );
  149375. +
  149376. +gceSTATUS
  149377. +gckOS_SignalSetHardware(
  149378. + IN gckOS Os,
  149379. + IN gctSIGNAL Signal,
  149380. + gckHARDWARE Hardware
  149381. + );
  149382. +
  149383. +#ifdef __cplusplus
  149384. +}
  149385. +#endif
  149386. +
  149387. +#if gcdENABLE_VG
  149388. +#include "gc_hal_vg.h"
  149389. +#endif
  149390. +
  149391. +#endif /* __gc_hal_h_ */
  149392. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h
  149393. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h 1969-12-31 18:00:00.000000000 -0600
  149394. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h 2014-12-08 00:31:53.468418001 -0600
  149395. @@ -0,0 +1,185 @@
  149396. +/****************************************************************************
  149397. +*
  149398. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  149399. +*
  149400. +* This program is free software; you can redistribute it and/or modify
  149401. +* it under the terms of the GNU General Public License as published by
  149402. +* the Free Software Foundation; either version 2 of the license, or
  149403. +* (at your option) any later version.
  149404. +*
  149405. +* This program is distributed in the hope that it will be useful,
  149406. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  149407. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  149408. +* GNU General Public License for more details.
  149409. +*
  149410. +* You should have received a copy of the GNU General Public License
  149411. +* along with this program; if not write to the Free Software
  149412. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  149413. +*
  149414. +*****************************************************************************/
  149415. +
  149416. +
  149417. +#ifndef __gc_hal_kernel_buffer_h_
  149418. +#define __gc_hal_kernel_buffer_h_
  149419. +
  149420. +
  149421. +#ifdef __cplusplus
  149422. +extern "C" {
  149423. +#endif
  149424. +
  149425. +/******************************************************************************\
  149426. +************************ Command Buffer and Event Objects **********************
  149427. +\******************************************************************************/
  149428. +
  149429. +/* The number of context buffers per user. */
  149430. +#define gcdCONTEXT_BUFFER_COUNT 2
  149431. +
  149432. +/* State delta record. */
  149433. +typedef struct _gcsSTATE_DELTA_RECORD * gcsSTATE_DELTA_RECORD_PTR;
  149434. +typedef struct _gcsSTATE_DELTA_RECORD
  149435. +{
  149436. + /* State address. */
  149437. + gctUINT address;
  149438. +
  149439. + /* State mask. */
  149440. + gctUINT32 mask;
  149441. +
  149442. + /* State data. */
  149443. + gctUINT32 data;
  149444. +}
  149445. +gcsSTATE_DELTA_RECORD;
  149446. +
  149447. +/* State delta. */
  149448. +typedef struct _gcsSTATE_DELTA
  149449. +{
  149450. + /* For debugging: the number of delta in the order of creation. */
  149451. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  149452. + gctUINT num;
  149453. +#endif
  149454. +
  149455. + /* Main state delta ID. Every time state delta structure gets reinitialized,
  149456. + main ID is incremented. If main state ID overflows, all map entry IDs get
  149457. + reinitialized to make sure there is no potential erroneous match after
  149458. + the overflow.*/
  149459. + gctUINT id;
  149460. +
  149461. + /* The number of contexts pending modification by the delta. */
  149462. + gctINT refCount;
  149463. +
  149464. + /* Vertex element count for the delta buffer. */
  149465. + gctUINT elementCount;
  149466. +
  149467. + /* Number of states currently stored in the record array. */
  149468. + gctUINT recordCount;
  149469. +
  149470. + /* Record array; holds all modified states in gcsSTATE_DELTA_RECORD. */
  149471. + gctUINT64 recordArray;
  149472. +
  149473. + /* Map entry ID is used for map entry validation. If map entry ID does not
  149474. + match the main state delta ID, the entry and the corresponding state are
  149475. + considered not in use. */
  149476. + gctUINT64 mapEntryID;
  149477. + gctUINT mapEntryIDSize;
  149478. +
  149479. + /* If the map entry ID matches the main state delta ID, index points to
  149480. + the state record in the record array. */
  149481. + gctUINT64 mapEntryIndex;
  149482. +
  149483. + /* Previous and next state deltas in gcsSTATE_DELTA. */
  149484. + gctUINT64 prev;
  149485. + gctUINT64 next;
  149486. +}
  149487. +gcsSTATE_DELTA;
  149488. +
  149489. +/* Command buffer object. */
  149490. +struct _gcoCMDBUF
  149491. +{
  149492. + /* The object. */
  149493. + gcsOBJECT object;
  149494. +
  149495. + /* Command buffer entry and exit pipes. */
  149496. + gcePIPE_SELECT entryPipe;
  149497. + gcePIPE_SELECT exitPipe;
  149498. +
  149499. + /* Feature usage flags. */
  149500. + gctBOOL using2D;
  149501. + gctBOOL using3D;
  149502. + gctBOOL usingFilterBlit;
  149503. + gctBOOL usingPalette;
  149504. +
  149505. + /* Physical address of command buffer. Just a name. */
  149506. + gctUINT32 physical;
  149507. +
  149508. + /* Logical address of command buffer. */
  149509. + gctUINT64 logical;
  149510. +
  149511. + /* Number of bytes in command buffer. */
  149512. + gctUINT bytes;
  149513. +
  149514. + /* Start offset into the command buffer. */
  149515. + gctUINT startOffset;
  149516. +
  149517. + /* Current offset into the command buffer. */
  149518. + gctUINT offset;
  149519. +
  149520. + /* Number of free bytes in command buffer. */
  149521. + gctUINT free;
  149522. +
  149523. + /* Location of the last reserved area. */
  149524. + gctUINT64 lastReserve;
  149525. + gctUINT lastOffset;
  149526. +
  149527. +#if gcdSECURE_USER
  149528. + /* Hint array for the current command buffer. */
  149529. + gctUINT hintArraySize;
  149530. + gctUINT64 hintArray;
  149531. + gctUINT64 hintArrayTail;
  149532. +#endif
  149533. +
  149534. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  149535. + /* Last load state command location and hardware address. */
  149536. + gctUINT64 lastLoadStatePtr;
  149537. + gctUINT32 lastLoadStateAddress;
  149538. + gctUINT32 lastLoadStateCount;
  149539. +#endif
  149540. +};
  149541. +
  149542. +typedef struct _gcsQUEUE
  149543. +{
  149544. + /* Pointer to next gcsQUEUE structure in gcsQUEUE. */
  149545. + gctUINT64 next;
  149546. +
  149547. + /* Event information. */
  149548. + gcsHAL_INTERFACE iface;
  149549. +}
  149550. +gcsQUEUE;
  149551. +
  149552. +/* Event queue. */
  149553. +struct _gcoQUEUE
  149554. +{
  149555. + /* The object. */
  149556. + gcsOBJECT object;
  149557. +
  149558. + /* Pointer to current event queue. */
  149559. + gcsQUEUE_PTR head;
  149560. + gcsQUEUE_PTR tail;
  149561. +
  149562. +#ifdef __QNXNTO__
  149563. + /* Buffer for records. */
  149564. + gcsQUEUE_PTR records;
  149565. + gctUINT32 freeBytes;
  149566. + gctUINT32 offset;
  149567. +#else
  149568. + /* List of free records. */
  149569. + gcsQUEUE_PTR freeList;
  149570. +#endif
  149571. + #define gcdIN_QUEUE_RECORD_LIMIT 16
  149572. + /* Number of records currently in queue */
  149573. + gctUINT32 recordCount;
  149574. +};
  149575. +
  149576. +#ifdef __cplusplus
  149577. +}
  149578. +#endif
  149579. +
  149580. +#endif /* __gc_hal_kernel_buffer_h_ */
  149581. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h
  149582. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h 1969-12-31 18:00:00.000000000 -0600
  149583. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h 2014-12-08 00:31:53.468418001 -0600
  149584. @@ -0,0 +1,530 @@
  149585. +/****************************************************************************
  149586. +*
  149587. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  149588. +*
  149589. +* This program is free software; you can redistribute it and/or modify
  149590. +* it under the terms of the GNU General Public License as published by
  149591. +* the Free Software Foundation; either version 2 of the license, or
  149592. +* (at your option) any later version.
  149593. +*
  149594. +* This program is distributed in the hope that it will be useful,
  149595. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  149596. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  149597. +* GNU General Public License for more details.
  149598. +*
  149599. +* You should have received a copy of the GNU General Public License
  149600. +* along with this program; if not write to the Free Software
  149601. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  149602. +*
  149603. +*****************************************************************************/
  149604. +
  149605. +
  149606. +/*
  149607. +** Include file for the local memory management.
  149608. +*/
  149609. +
  149610. +#ifndef __gc_hal_mem_h_
  149611. +#define __gc_hal_mem_h_
  149612. +#ifndef VIVANTE_NO_3D
  149613. +
  149614. +#ifdef __cplusplus
  149615. +extern "C" {
  149616. +#endif
  149617. +
  149618. +/*******************************************************************************
  149619. +** Usage:
  149620. +
  149621. + The macros to declare MemPool type and functions are
  149622. + gcmMEM_DeclareFSMemPool (Type, TypeName, Prefix)
  149623. + gcmMEM_DeclareVSMemPool (Type, TypeName, Prefix)
  149624. + gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix)
  149625. +
  149626. + The data structures for MemPool are
  149627. + typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
  149628. + typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
  149629. + typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
  149630. +
  149631. + The MemPool constructor and destructor functions are
  149632. + gcfMEM_InitFSMemPool(gcsMEM_FS_MEM_POOL *, gcoOS, gctUINT, gctUINT);
  149633. + gcfMEM_FreeFSMemPool(gcsMEM_FS_MEM_POOL *);
  149634. + gcfMEM_InitVSMemPool(gcsMEM_VS_MEM_POOL *, gcoOS, gctUINT, gctBOOL);
  149635. + gcfMEM_FreeVSMemPool(gcsMEM_VS_MEM_POOL *);
  149636. + gcfMEM_InitAFSMemPool(gcsMEM_AFS_MEM_POOL *, gcoOS, gctUINT);
  149637. + gcfMEM_FreeAFSMemPool(gcsMEM_AFS_MEM_POOL *);
  149638. +
  149639. + FS: for Fixed-Size data structures
  149640. + VS: for Variable-size data structures
  149641. + AFS: for Array of Fixed-Size data structures
  149642. +
  149643. +
  149644. + // Example 1: For a fixed-size data structure, struct gcsNode.
  149645. + // It is used locally in a file, so the functions are static without prefix.
  149646. + // At top level, declear allocate and free functions.
  149647. + // The first argument is the data type.
  149648. + // The second armument is the short name used in the fuctions.
  149649. + gcmMEM_DeclareFSMemPool(struct gcsNode, Node, );
  149650. +
  149651. + // The previous macro creates two inline functions,
  149652. + // _AllocateNode and _FreeNode.
  149653. +
  149654. + // In function or struct
  149655. + gcsMEM_FS_MEM_POOL nodeMemPool;
  149656. +
  149657. + // In function,
  149658. + struct gcsNode * node;
  149659. + gceSTATUS status;
  149660. +
  149661. + // Before using the memory pool, initialize it.
  149662. + // The second argument is the gcoOS object.
  149663. + // The third argument is the number of data structures to allocate for each chunk.
  149664. + status = gcfMEM_InitFSMemPool(&nodeMemPool, os, 100, sizeof(struct gcsNode));
  149665. + ...
  149666. +
  149667. + // Allocate a node.
  149668. + status = _AllocateNode(nodeMemPool, &node);
  149669. + ...
  149670. + // Free a node.
  149671. + _FreeNode(nodeMemPool, node);
  149672. +
  149673. + // After using the memory pool, free it.
  149674. + gcfMEM_FreeFSMemPool(&nodeMemPool);
  149675. +
  149676. +
  149677. + // Example 2: For array of fixed-size data structures, struct gcsNode.
  149678. + // It is used in several files, so the functions are extern with prefix.
  149679. + // At top level, declear allocate and free functions.
  149680. + // The first argument is the data type, and the second one is the short name
  149681. + // used in the fuctions.
  149682. + gcmMEM_DeclareAFSMemPool(struct gcsNode, NodeArray, gcfOpt);
  149683. +
  149684. + // The previous macro creates two inline functions,
  149685. + // gcfOpt_AllocateNodeArray and gcfOpt_FreeNodeArray.
  149686. +
  149687. + // In function or struct
  149688. + gcsMEM_AFS_MEM_POOL nodeArrayMemPool;
  149689. +
  149690. + // In function,
  149691. + struct gcsNode * nodeArray;
  149692. + gceSTATUS status;
  149693. +
  149694. + // Before using the array memory pool, initialize it.
  149695. + // The second argument is the gcoOS object, the third is the number of data
  149696. + // structures to allocate for each chunk.
  149697. + status = gcfMEM_InitAFSMemPool(&nodeArrayMemPool, os, sizeof(struct gcsNode));
  149698. + ...
  149699. +
  149700. + // Allocate a node array of size 100.
  149701. + status = gcfOpt_AllocateNodeArray(nodeArrayMemPool, &nodeArray, 100);
  149702. + ...
  149703. + // Free a node array.
  149704. + gcfOpt_FreeNodeArray(&nodeArrayMemPool, nodeArray);
  149705. +
  149706. + // After using the array memory pool, free it.
  149707. + gcfMEM_FreeAFSMemPool(&nodeArrayMemPool);
  149708. +
  149709. +*******************************************************************************/
  149710. +
  149711. +/*******************************************************************************
  149712. +** To switch back to use gcoOS_Allocate and gcoOS_Free, add
  149713. +** #define USE_LOCAL_MEMORY_POOL 0
  149714. +** before including this file.
  149715. +*******************************************************************************/
  149716. +#ifndef USE_LOCAL_MEMORY_POOL
  149717. +/*
  149718. + USE_LOCAL_MEMORY_POOL
  149719. +
  149720. + This define enables the local memory management to improve performance.
  149721. +*/
  149722. +#define USE_LOCAL_MEMORY_POOL 1
  149723. +#endif
  149724. +
  149725. +/*******************************************************************************
  149726. +** Memory Pool Data Structures
  149727. +*******************************************************************************/
  149728. +#if USE_LOCAL_MEMORY_POOL
  149729. + typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
  149730. + typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
  149731. + typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
  149732. +#else
  149733. + typedef gcoOS gcsMEM_FS_MEM_POOL;
  149734. + typedef gcoOS gcsMEM_VS_MEM_POOL;
  149735. + typedef gcoOS gcsMEM_AFS_MEM_POOL;
  149736. +#endif
  149737. +
  149738. +/*******************************************************************************
  149739. +** Memory Pool Macros
  149740. +*******************************************************************************/
  149741. +#if USE_LOCAL_MEMORY_POOL
  149742. +#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
  149743. +gceSTATUS \
  149744. +Prefix##_Allocate##TypeName( \
  149745. + gcsMEM_FS_MEM_POOL MemPool, \
  149746. + Type ** Pointer \
  149747. + ) \
  149748. +{ \
  149749. + return(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
  149750. +} \
  149751. + \
  149752. +gceSTATUS \
  149753. +Prefix##_CAllocate##TypeName( \
  149754. + gcsMEM_FS_MEM_POOL MemPool, \
  149755. + Type ** Pointer \
  149756. + ) \
  149757. +{ \
  149758. + gceSTATUS status; \
  149759. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149760. + gcmERR_RETURN(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
  149761. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
  149762. + gcmFOOTER(); \
  149763. + return gcvSTATUS_OK; \
  149764. +} \
  149765. + \
  149766. +gceSTATUS \
  149767. +Prefix##_Free##TypeName( \
  149768. + gcsMEM_FS_MEM_POOL MemPool, \
  149769. + Type * Pointer \
  149770. + ) \
  149771. +{ \
  149772. + gceSTATUS status; \
  149773. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149774. + status = gcfMEM_FSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
  149775. + gcmFOOTER(); \
  149776. + return status; \
  149777. +} \
  149778. + \
  149779. +gceSTATUS \
  149780. +Prefix##_Free##TypeName##List( \
  149781. + gcsMEM_FS_MEM_POOL MemPool, \
  149782. + Type * FirstPointer, \
  149783. + Type * LastPointer \
  149784. + ) \
  149785. +{ \
  149786. + gceSTATUS status; \
  149787. + gcmHEADER_ARG("MemPool=0x%x FirstPointer=0x%x LastPointer=0x%x", MemPool, FirstPointer, LastPointer); \
  149788. + status = gcfMEM_FSMemPoolFreeAList(MemPool, (gctPOINTER) FirstPointer, (gctPOINTER) LastPointer); \
  149789. + gcmFOOTER(); \
  149790. + return status; \
  149791. +}
  149792. +
  149793. +#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
  149794. +gceSTATUS \
  149795. +Prefix##_Allocate##TypeName( \
  149796. + gcsMEM_FS_MEM_POOL MemPool, \
  149797. + Type ** Pointer, \
  149798. + gctUINT Size \
  149799. + ) \
  149800. +{ \
  149801. + gceSTATUS status;\
  149802. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  149803. + status = gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer); \
  149804. + gcmFOOTER(); \
  149805. + return status; \
  149806. +} \
  149807. + \
  149808. +gceSTATUS \
  149809. + Prefix##_CAllocate##TypeName( \
  149810. + gcsMEM_FS_MEM_POOL MemPool, \
  149811. + Type ** Pointer, \
  149812. + gctUINT Size \
  149813. + ) \
  149814. +{ \
  149815. + gceSTATUS status; \
  149816. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  149817. + gcmERR_RETURN(gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer)); \
  149818. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, size); \
  149819. + gcmFOOTER(); \
  149820. + return gcvSTATUS_OK; \
  149821. +} \
  149822. + \
  149823. +gceSTATUS \
  149824. +Prefix##_Free##TypeName( \
  149825. + gcsMEM_FS_MEM_POOL MemPool, \
  149826. + Type * Pointer \
  149827. + ) \
  149828. +{ \
  149829. + gceSTATUS status; \
  149830. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pinter); \
  149831. + status = gcfMEM_VSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
  149832. + gcmFOOTER(); \
  149833. + return status; \
  149834. +}
  149835. +
  149836. +#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
  149837. +gceSTATUS \
  149838. +Prefix##_Allocate##TypeName( \
  149839. + gcsMEM_AFS_MEM_POOL MemPool, \
  149840. + Type ** Pointer, \
  149841. + gctUINT Count \
  149842. + ) \
  149843. +{ \
  149844. + gceSTATUS status; \
  149845. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  149846. + status = gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer); \
  149847. + gcmFOOTER(); \
  149848. + return status; \
  149849. +} \
  149850. + \
  149851. +gceSTATUS \
  149852. +Prefix##_CAllocate##TypeName( \
  149853. + gcsMEM_AFS_MEM_POOL MemPool, \
  149854. + Type ** Pointer, \
  149855. + gctUINT Count \
  149856. + ) \
  149857. +{ \
  149858. + gceSTATUS status; \
  149859. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  149860. + gcmERR_RETURN(gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer)); \
  149861. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
  149862. + gcmFOOTER(); \
  149863. + return gcvSTATUS_OK; \
  149864. +} \
  149865. + \
  149866. +gceSTATUS \
  149867. +Prefix##_Free##TypeName( \
  149868. + gcsMEM_AFS_MEM_POOL MemPool, \
  149869. + Type * Pointer \
  149870. + ) \
  149871. +{ \
  149872. + gceSTATUS status; \
  149873. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149874. + status = gcfMEM_AFSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
  149875. + gcmFOOTER(); \
  149876. + return status; \
  149877. +}
  149878. +
  149879. +#else
  149880. +
  149881. +#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
  149882. +gceSTATUS \
  149883. +Prefix##_Allocate##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, Pointer); \
  149890. + status = gcoOS_Allocate(MemPool, \
  149891. + gcmSIZEOF(Type), \
  149892. + (gctPOINTER *) Pointer); \
  149893. + gcmFOOTER(); \
  149894. + return status; \
  149895. +} \
  149896. + \
  149897. +gceSTATUS \
  149898. +Prefix##_CAllocate##TypeName( \
  149899. + gcsMEM_FS_MEM_POOL MemPool, \
  149900. + Type ** Pointer \
  149901. + ) \
  149902. +{ \
  149903. + gceSTATUS status; \
  149904. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149905. + gcmERR_RETURN(gcoOS_Allocate(MemPool, \
  149906. + gcmSIZEOF(Type), \
  149907. + (gctPOINTER *) Pointer)); \
  149908. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
  149909. + gcmFOOTER(); \
  149910. + return gcvSTATUS_OK; \
  149911. +} \
  149912. + \
  149913. +gceSTATUS \
  149914. +Prefix##_Free##TypeName( \
  149915. + gcsMEM_FS_MEM_POOL MemPool, \
  149916. + Type * Pointer \
  149917. + ) \
  149918. +{ \
  149919. + gceSTATUS status; \
  149920. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149921. + status = gcmOS_SAFE_FREE(MemPool, Pointer); \
  149922. + gcmFOOTER(); \
  149923. + return status; \
  149924. +}
  149925. +
  149926. +#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
  149927. +gceSTATUS \
  149928. +Prefix##_Allocate##TypeName( \
  149929. + gcsMEM_VS_MEM_POOL MemPool, \
  149930. + Type ** Pointer, \
  149931. + gctUINT Size \
  149932. + ) \
  149933. +{ \
  149934. + gceSTATUS status; \
  149935. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  149936. + status = gcoOS_Allocate(MemPool, \
  149937. + Size, \
  149938. + (gctPOINTER *) Pointer); \
  149939. + gcmFOOTER(); \
  149940. + return status; \
  149941. +} \
  149942. + \
  149943. +gceSTATUS \
  149944. +Prefix##_CAllocate##TypeName( \
  149945. + gcsMEM_VS_MEM_POOL MemPool, \
  149946. + Type ** Pointer, \
  149947. + gctUINT Size \
  149948. + ) \
  149949. +{ \
  149950. + gceSTATUS status; \
  149951. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  149952. + gcmERR_RETURN(gcoOS_Allocate(MemPool, \
  149953. + Size, \
  149954. + (gctPOINTER *) Pointer)); \
  149955. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Size); \
  149956. + gcmFOOTER(); \
  149957. + return gcvSTATUS_OK; \
  149958. +} \
  149959. + \
  149960. +gceSTATUS \
  149961. +Prefix##_Free##TypeName( \
  149962. + gcsMEM_VS_MEM_POOL MemPool, \
  149963. + Type * Pointer \
  149964. + ) \
  149965. +{ \
  149966. + gceSTATUS status; \
  149967. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  149968. + status = gcmOS_SAFE_FREE(MemPool, Pointer); \
  149969. + gcmFOOTER(); \
  149970. + return status; \
  149971. +}
  149972. +
  149973. +#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
  149974. +gceSTATUS \
  149975. +Prefix##_Allocate##TypeName( \
  149976. + gcsMEM_AFS_MEM_POOL MemPool, \
  149977. + Type ** Pointer, \
  149978. + gctUINT Count \
  149979. + ) \
  149980. +{ \
  149981. + gceSTATUS status; \
  149982. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  149983. + status = gcoOS_Allocate(MemPool, \
  149984. + Count * gcmSIZEOF(Type), \
  149985. + (gctPOINTER *) Pointer); \
  149986. + gcmFOOTER(); \
  149987. + return status; \
  149988. +} \
  149989. + \
  149990. +gceSTATUS \
  149991. +Prefix##_CAllocate##TypeName( \
  149992. + gcsMEM_AFS_MEM_POOL MemPool, \
  149993. + Type ** Pointer, \
  149994. + gctUINT Count \
  149995. + ) \
  149996. +{ \
  149997. + gceSTATUS status; \
  149998. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  149999. + gcmERR_RETURN(gcoOS_Allocate(MemPool, \
  150000. + Count * gcmSIZEOF(Type), \
  150001. + (gctPOINTER *) Pointer)); \
  150002. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
  150003. + gcmFOOTER(); \
  150004. + return gcvSTATUS_OK; \
  150005. +} \
  150006. + \
  150007. +gceSTATUS \
  150008. +Prefix##_Free##TypeName( \
  150009. + gcsMEM_AFS_MEM_POOL MemPool, \
  150010. + Type * Pointer \
  150011. + ) \
  150012. +{ \
  150013. + gceSTATUS status; \
  150014. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  150015. + status = gcmOS_SAFE_FREE(MemPool, Pointer); \
  150016. + gcmFOOTER(); \
  150017. + return status; \
  150018. +}
  150019. +#endif
  150020. +
  150021. +/*******************************************************************************
  150022. +** Memory Pool Data Functions
  150023. +*******************************************************************************/
  150024. +gceSTATUS
  150025. +gcfMEM_InitFSMemPool(
  150026. + IN gcsMEM_FS_MEM_POOL * MemPool,
  150027. + IN gcoOS OS,
  150028. + IN gctUINT NodeCount,
  150029. + IN gctUINT NodeSize
  150030. + );
  150031. +
  150032. +gceSTATUS
  150033. +gcfMEM_FreeFSMemPool(
  150034. + IN gcsMEM_FS_MEM_POOL * MemPool
  150035. + );
  150036. +
  150037. +gceSTATUS
  150038. +gcfMEM_FSMemPoolGetANode(
  150039. + IN gcsMEM_FS_MEM_POOL MemPool,
  150040. + OUT gctPOINTER * Node
  150041. + );
  150042. +
  150043. +gceSTATUS
  150044. +gcfMEM_FSMemPoolFreeANode(
  150045. + IN gcsMEM_FS_MEM_POOL MemPool,
  150046. + IN gctPOINTER Node
  150047. + );
  150048. +
  150049. +gceSTATUS
  150050. +gcfMEM_FSMemPoolFreeAList(
  150051. + IN gcsMEM_FS_MEM_POOL MemPool,
  150052. + IN gctPOINTER FirstNode,
  150053. + IN gctPOINTER LastNode
  150054. + );
  150055. +
  150056. +gceSTATUS
  150057. +gcfMEM_InitVSMemPool(
  150058. + IN gcsMEM_VS_MEM_POOL * MemPool,
  150059. + IN gcoOS OS,
  150060. + IN gctUINT BlockSize,
  150061. + IN gctBOOL RecycleFreeNode
  150062. + );
  150063. +
  150064. +gceSTATUS
  150065. +gcfMEM_FreeVSMemPool(
  150066. + IN gcsMEM_VS_MEM_POOL * MemPool
  150067. + );
  150068. +
  150069. +gceSTATUS
  150070. +gcfMEM_VSMemPoolGetANode(
  150071. + IN gcsMEM_VS_MEM_POOL MemPool,
  150072. + IN gctUINT Size,
  150073. + IN gctUINT Alignment,
  150074. + OUT gctPOINTER * Node
  150075. + );
  150076. +
  150077. +gceSTATUS
  150078. +gcfMEM_VSMemPoolFreeANode(
  150079. + IN gcsMEM_VS_MEM_POOL MemPool,
  150080. + IN gctPOINTER Node
  150081. + );
  150082. +
  150083. +gceSTATUS
  150084. +gcfMEM_InitAFSMemPool(
  150085. + IN gcsMEM_AFS_MEM_POOL *MemPool,
  150086. + IN gcoOS OS,
  150087. + IN gctUINT NodeCount,
  150088. + IN gctUINT NodeSize
  150089. + );
  150090. +
  150091. +gceSTATUS
  150092. +gcfMEM_FreeAFSMemPool(
  150093. + IN gcsMEM_AFS_MEM_POOL *MemPool
  150094. + );
  150095. +
  150096. +gceSTATUS
  150097. +gcfMEM_AFSMemPoolGetANode(
  150098. + IN gcsMEM_AFS_MEM_POOL MemPool,
  150099. + IN gctUINT Count,
  150100. + OUT gctPOINTER * Node
  150101. + );
  150102. +
  150103. +gceSTATUS
  150104. +gcfMEM_AFSMemPoolFreeANode(
  150105. + IN gcsMEM_AFS_MEM_POOL MemPool,
  150106. + IN gctPOINTER Node
  150107. + );
  150108. +
  150109. +#ifdef __cplusplus
  150110. +}
  150111. +#endif
  150112. +
  150113. +#endif /* VIVANTE_NO_3D */
  150114. +#endif /* __gc_hal_mem_h_ */
  150115. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
  150116. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h 1969-12-31 18:00:00.000000000 -0600
  150117. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h 2014-12-08 00:31:53.468418001 -0600
  150118. @@ -0,0 +1,947 @@
  150119. +/****************************************************************************
  150120. +*
  150121. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  150122. +*
  150123. +* This program is free software; you can redistribute it and/or modify
  150124. +* it under the terms of the GNU General Public License as published by
  150125. +* the Free Software Foundation; either version 2 of the license, or
  150126. +* (at your option) any later version.
  150127. +*
  150128. +* This program is distributed in the hope that it will be useful,
  150129. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  150130. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  150131. +* GNU General Public License for more details.
  150132. +*
  150133. +* You should have received a copy of the GNU General Public License
  150134. +* along with this program; if not write to the Free Software
  150135. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  150136. +*
  150137. +*****************************************************************************/
  150138. +
  150139. +
  150140. +#ifndef __gc_hal_options_h_
  150141. +#define __gc_hal_options_h_
  150142. +
  150143. +/*
  150144. + gcdPRINT_VERSION
  150145. +
  150146. + Print HAL version.
  150147. +*/
  150148. +#ifndef gcdPRINT_VERSION
  150149. +# define gcdPRINT_VERSION 0
  150150. +#endif
  150151. +
  150152. +/*
  150153. + USE_NEW_LINUX_SIGNAL
  150154. +
  150155. + This define enables the Linux kernel signaling between kernel and user.
  150156. +*/
  150157. +#ifndef USE_NEW_LINUX_SIGNAL
  150158. +# define USE_NEW_LINUX_SIGNAL 0
  150159. +#endif
  150160. +
  150161. +/*
  150162. + VIVANTE_PROFILER
  150163. +
  150164. + This define enables the profiler.
  150165. +*/
  150166. +#ifndef VIVANTE_PROFILER
  150167. +# define VIVANTE_PROFILER 1
  150168. +#endif
  150169. +
  150170. +#ifndef VIVANTE_PROFILER_PERDRAW
  150171. +# define VIVANTE_PROFILER_PERDRAW 0
  150172. +#endif
  150173. +
  150174. +/*
  150175. + VIVANTE_PROFILER_CONTEXT
  150176. +
  150177. + This define enables the profiler according to each hw context.
  150178. +*/
  150179. +#ifndef VIVANTE_PROFILER_CONTEXT
  150180. +# define VIVANTE_PROFILER_CONTEXT 1
  150181. +#endif
  150182. +
  150183. +/*
  150184. + gcdUSE_VG
  150185. +
  150186. + Enable VG HAL layer (only for GC350).
  150187. +*/
  150188. +#ifndef gcdUSE_VG
  150189. +# define gcdUSE_VG 0
  150190. +#endif
  150191. +
  150192. +/*
  150193. + USE_SW_FB
  150194. +
  150195. + Set to 1 if the frame buffer memory cannot be accessed by the GPU.
  150196. +*/
  150197. +#ifndef USE_SW_FB
  150198. +# define USE_SW_FB 0
  150199. +#endif
  150200. +
  150201. +/*
  150202. + USE_SUPER_SAMPLING
  150203. +
  150204. + This define enables super-sampling support.
  150205. +*/
  150206. +#define USE_SUPER_SAMPLING 0
  150207. +
  150208. +/*
  150209. + PROFILE_HAL_COUNTERS
  150210. +
  150211. + This define enables HAL counter profiling support. HW and SHADER
  150212. + counter profiling depends on this.
  150213. +*/
  150214. +#ifndef PROFILE_HAL_COUNTERS
  150215. +# define PROFILE_HAL_COUNTERS 1
  150216. +#endif
  150217. +
  150218. +/*
  150219. + PROFILE_HW_COUNTERS
  150220. +
  150221. + This define enables HW counter profiling support.
  150222. +*/
  150223. +#ifndef PROFILE_HW_COUNTERS
  150224. +# define PROFILE_HW_COUNTERS 1
  150225. +#endif
  150226. +
  150227. +/*
  150228. + PROFILE_SHADER_COUNTERS
  150229. +
  150230. + This define enables SHADER counter profiling support.
  150231. +*/
  150232. +#ifndef PROFILE_SHADER_COUNTERS
  150233. +# define PROFILE_SHADER_COUNTERS 1
  150234. +#endif
  150235. +
  150236. +/*
  150237. + COMMAND_PROCESSOR_VERSION
  150238. +
  150239. + The version of the command buffer and task manager.
  150240. +*/
  150241. +#define COMMAND_PROCESSOR_VERSION 1
  150242. +
  150243. +/*
  150244. + gcdDUMP_KEY
  150245. +
  150246. + Set this to a string that appears in 'cat /proc/<pid>/cmdline'. E.g. 'camera'.
  150247. + HAL will create dumps for the processes matching this key.
  150248. +*/
  150249. +#ifndef gcdDUMP_KEY
  150250. +# define gcdDUMP_KEY "process"
  150251. +#endif
  150252. +
  150253. +/*
  150254. + gcdDUMP_PATH
  150255. +
  150256. + The dump file location. Some processes cannot write to the sdcard.
  150257. + Try apps' data dir, e.g. /data/data/com.android.launcher
  150258. +*/
  150259. +#ifndef gcdDUMP_PATH
  150260. +#if defined(ANDROID)
  150261. +# define gcdDUMP_PATH "/mnt/sdcard/"
  150262. +#else
  150263. +# define gcdDUMP_PATH "./"
  150264. +#endif
  150265. +#endif
  150266. +
  150267. +/*
  150268. + gcdDUMP
  150269. +
  150270. + When set to 1, a dump of all states and memory uploads, as well as other
  150271. + hardware related execution will be printed to the debug console. This
  150272. + data can be used for playing back applications.
  150273. +*/
  150274. +#ifndef gcdDUMP
  150275. +# define gcdDUMP 0
  150276. +#endif
  150277. +
  150278. +/*
  150279. + gcdDUMP_API
  150280. +
  150281. + When set to 1, a high level dump of the EGL and GL/VG APs's are
  150282. + captured.
  150283. +*/
  150284. +#ifndef gcdDUMP_API
  150285. +# define gcdDUMP_API 0
  150286. +#endif
  150287. +
  150288. +/*
  150289. + gcdDUMP_FRAMERATE
  150290. + When set to a value other than zero, averaqe frame rate will be dumped.
  150291. + The value set is the starting frame that the average will be calculated.
  150292. + This is needed because sometimes first few frames are too slow to be included
  150293. + in the average. Frame count starts from 1.
  150294. +*/
  150295. +#ifndef gcdDUMP_FRAMERATE
  150296. +# define gcdDUMP_FRAMERATE 0
  150297. +#endif
  150298. +
  150299. +/*
  150300. + gcdVIRTUAL_COMMAND_BUFFER
  150301. + When set to 1, user command buffer and context buffer will be allocated
  150302. + from gcvPOOL_VIRTUAL.
  150303. +*/
  150304. +#ifndef gcdVIRTUAL_COMMAND_BUFFER
  150305. +# define gcdVIRTUAL_COMMAND_BUFFER 0
  150306. +#endif
  150307. +
  150308. +/*
  150309. + gcdENABLE_FSCALE_VAL_ADJUST
  150310. + When non-zero, FSCALE_VAL when gcvPOWER_ON can be adjusted externally.
  150311. + */
  150312. +#ifndef gcdENABLE_FSCALE_VAL_ADJUST
  150313. +# define gcdENABLE_FSCALE_VAL_ADJUST 1
  150314. +#endif
  150315. +
  150316. +/*
  150317. + gcdDUMP_IN_KERNEL
  150318. +
  150319. + When set to 1, all dumps will happen in the kernel. This is handy if
  150320. + you want the kernel to dump its command buffers as well and the data
  150321. + needs to be in sync.
  150322. +*/
  150323. +#ifndef gcdDUMP_IN_KERNEL
  150324. +# define gcdDUMP_IN_KERNEL 0
  150325. +#endif
  150326. +
  150327. +/*
  150328. + gcdDUMP_COMMAND
  150329. +
  150330. + When set to non-zero, the command queue will dump all incoming command
  150331. + and context buffers as well as all other modifications to the command
  150332. + queue.
  150333. +*/
  150334. +#ifndef gcdDUMP_COMMAND
  150335. +# define gcdDUMP_COMMAND 0
  150336. +#endif
  150337. +
  150338. +/*
  150339. + gcdDUMP_FRAME_TGA
  150340. +
  150341. + When set to a value other than 0, a dump of the frame specified by the value,
  150342. + will be done into frame.tga. Frame count starts from 1.
  150343. + */
  150344. +#ifndef gcdDUMP_FRAME_TGA
  150345. +#define gcdDUMP_FRAME_TGA 0
  150346. +#endif
  150347. +/*
  150348. + gcdNULL_DRIVER
  150349. +
  150350. + Set to 1 for infinite speed hardware.
  150351. + Set to 2 for bypassing the HAL.
  150352. + Set to 3 for bypassing the drivers.
  150353. +*/
  150354. +#ifndef gcdNULL_DRIVER
  150355. +# define gcdNULL_DRIVER 0
  150356. +#endif
  150357. +
  150358. +/*
  150359. + gcdENABLE_TIMEOUT_DETECTION
  150360. +
  150361. + Enable timeout detection.
  150362. +*/
  150363. +#ifndef gcdENABLE_TIMEOUT_DETECTION
  150364. +# define gcdENABLE_TIMEOUT_DETECTION 0
  150365. +#endif
  150366. +
  150367. +/*
  150368. + gcdCMD_BUFFER_SIZE
  150369. +
  150370. + Number of bytes in a command buffer.
  150371. +*/
  150372. +#ifndef gcdCMD_BUFFER_SIZE
  150373. +# define gcdCMD_BUFFER_SIZE (128 << 10)
  150374. +#endif
  150375. +
  150376. +/*
  150377. + gcdCMD_BUFFERS
  150378. +
  150379. + Number of command buffers to use per client.
  150380. +*/
  150381. +#ifndef gcdCMD_BUFFERS
  150382. +# define gcdCMD_BUFFERS 2
  150383. +#endif
  150384. +
  150385. +/*
  150386. + gcdMAX_CMD_BUFFERS
  150387. +
  150388. + Maximum number of command buffers to use per client.
  150389. +*/
  150390. +#ifndef gcdMAX_CMD_BUFFERS
  150391. +# define gcdMAX_CMD_BUFFERS 8
  150392. +#endif
  150393. +
  150394. +/*
  150395. + gcdCOMMAND_QUEUES
  150396. +
  150397. + Number of command queues in the kernel.
  150398. +*/
  150399. +#ifndef gcdCOMMAND_QUEUES
  150400. +# define gcdCOMMAND_QUEUES 2
  150401. +#endif
  150402. +
  150403. +/*
  150404. + gcdPOWER_CONTROL_DELAY
  150405. +
  150406. + The delay in milliseconds required to wait until the GPU has woke up
  150407. + from a suspend or power-down state. This is system dependent because
  150408. + the bus clock also needs to stabalize.
  150409. +*/
  150410. +#ifndef gcdPOWER_CONTROL_DELAY
  150411. +# define gcdPOWER_CONTROL_DELAY 0
  150412. +#endif
  150413. +
  150414. +/*
  150415. + gcdMIRROR_PAGETABLE
  150416. +
  150417. + Enable it when GPUs with old MMU and new MMU exist at same SoC. It makes
  150418. + each GPU use same virtual address to access same physical memory.
  150419. +*/
  150420. +#ifndef gcdMIRROR_PAGETABLE
  150421. +# define gcdMIRROR_PAGETABLE 0
  150422. +#endif
  150423. +
  150424. +/*
  150425. + gcdMMU_SIZE
  150426. +
  150427. + Size of the MMU page table in bytes. Each 4 bytes can hold 4kB worth of
  150428. + virtual data.
  150429. +*/
  150430. +#ifndef gcdMMU_SIZE
  150431. +#if gcdMIRROR_PAGETABLE
  150432. +# define gcdMMU_SIZE 0x200000
  150433. +#else
  150434. +# define gcdMMU_SIZE (2048 << 10)
  150435. +#endif
  150436. +#endif
  150437. +
  150438. +/*
  150439. + gcdSECURE_USER
  150440. +
  150441. + Use logical addresses instead of physical addresses in user land. In
  150442. + this case a hint table is created for both command buffers and context
  150443. + buffers, and that hint table will be used to patch up those buffers in
  150444. + the kernel when they are ready to submit.
  150445. +*/
  150446. +#ifndef gcdSECURE_USER
  150447. +# define gcdSECURE_USER 0
  150448. +#endif
  150449. +
  150450. +/*
  150451. + gcdSECURE_CACHE_SLOTS
  150452. +
  150453. + Number of slots in the logical to DMA address cache table. Each time a
  150454. + logical address needs to be translated into a DMA address for the GPU,
  150455. + this cache will be walked. The replacement scheme is LRU.
  150456. +*/
  150457. +#ifndef gcdSECURE_CACHE_SLOTS
  150458. +# define gcdSECURE_CACHE_SLOTS 1024
  150459. +#endif
  150460. +
  150461. +/*
  150462. + gcdSECURE_CACHE_METHOD
  150463. +
  150464. + Replacement scheme used for Secure Cache. The following options are
  150465. + available:
  150466. +
  150467. + gcdSECURE_CACHE_LRU
  150468. + A standard LRU cache.
  150469. +
  150470. + gcdSECURE_CACHE_LINEAR
  150471. + A linear walker with the idea that an application will always
  150472. + render the scene in a similar way, so the next entry in the
  150473. + cache should be a hit most of the time.
  150474. +
  150475. + gcdSECURE_CACHE_HASH
  150476. + A 256-entry hash table.
  150477. +
  150478. + gcdSECURE_CACHE_TABLE
  150479. + A simple cache but with potential of a lot of cache replacement.
  150480. +*/
  150481. +#ifndef gcdSECURE_CACHE_METHOD
  150482. +# define gcdSECURE_CACHE_METHOD gcdSECURE_CACHE_HASH
  150483. +#endif
  150484. +
  150485. +/*
  150486. + gcdREGISTER_ACCESS_FROM_USER
  150487. +
  150488. + Set to 1 to allow IOCTL calls to get through from user land. This
  150489. + should only be in debug or development drops.
  150490. +*/
  150491. +#ifndef gcdREGISTER_ACCESS_FROM_USER
  150492. +# define gcdREGISTER_ACCESS_FROM_USER 1
  150493. +#endif
  150494. +
  150495. +/*
  150496. + gcdUSER_HEAP_ALLOCATOR
  150497. +
  150498. + Set to 1 to enable user mode heap allocator for fast memory allocation
  150499. + and destroying. Otherwise, memory allocation/destroying in user mode
  150500. + will be directly managed by system. Only for linux for now.
  150501. +*/
  150502. +#ifndef gcdUSER_HEAP_ALLOCATOR
  150503. +# define gcdUSER_HEAP_ALLOCATOR 1
  150504. +#endif
  150505. +
  150506. +/*
  150507. + gcdHEAP_SIZE
  150508. +
  150509. + Set the allocation size for the internal heaps. Each time a heap is
  150510. + full, a new heap will be allocated with this minmimum amount of bytes.
  150511. + The bigger this size, the fewer heaps there are to allocate, the better
  150512. + the performance. However, heaps won't be freed until they are
  150513. + completely free, so there might be some more memory waste if the size is
  150514. + too big.
  150515. +*/
  150516. +#ifndef gcdHEAP_SIZE
  150517. +# define gcdHEAP_SIZE (64 << 10)
  150518. +#endif
  150519. +
  150520. +/*
  150521. + gcdPOWER_SUSNPEND_WHEN_IDLE
  150522. +
  150523. + Set to 1 to make GPU enter gcvPOWER_SUSPEND when idle detected,
  150524. + otherwise GPU will enter gcvPOWER_IDLE.
  150525. +*/
  150526. +#ifndef gcdPOWER_SUSNPEND_WHEN_IDLE
  150527. +# define gcdPOWER_SUSNPEND_WHEN_IDLE 1
  150528. +#endif
  150529. +
  150530. +/*
  150531. + gcdFPGA_BUILD
  150532. +
  150533. + This define enables work arounds for FPGA images.
  150534. +*/
  150535. +#ifndef gcdFPGA_BUILD
  150536. +# define gcdFPGA_BUILD 0
  150537. +#endif
  150538. +
  150539. +/*
  150540. + gcdGPU_TIMEOUT
  150541. +
  150542. + This define specified the number of milliseconds the system will wait
  150543. + before it broadcasts the GPU is stuck. In other words, it will define
  150544. + the timeout of any operation that needs to wait for the GPU.
  150545. +
  150546. + If the value is 0, no timeout will be checked for.
  150547. +*/
  150548. +#ifndef gcdGPU_TIMEOUT
  150549. +#if gcdFPGA_BUILD
  150550. +# define gcdGPU_TIMEOUT 0
  150551. +# else
  150552. +# define gcdGPU_TIMEOUT 20000
  150553. +# endif
  150554. +#endif
  150555. +
  150556. +/*
  150557. + gcdGPU_ADVANCETIMER
  150558. +
  150559. + it is advance timer.
  150560. +*/
  150561. +#ifndef gcdGPU_ADVANCETIMER
  150562. +# define gcdGPU_ADVANCETIMER 250
  150563. +#endif
  150564. +
  150565. +/*
  150566. + gcdSTATIC_LINK
  150567. +
  150568. + This define disalbes static linking;
  150569. +*/
  150570. +#ifndef gcdSTATIC_LINK
  150571. +# define gcdSTATIC_LINK 0
  150572. +#endif
  150573. +
  150574. +/*
  150575. + gcdUSE_NEW_HEAP
  150576. +
  150577. + Setting this define to 1 enables new heap.
  150578. +*/
  150579. +#ifndef gcdUSE_NEW_HEAP
  150580. +# define gcdUSE_NEW_HEAP 0
  150581. +#endif
  150582. +
  150583. +/*
  150584. + gcdCMD_NO_2D_CONTEXT
  150585. +
  150586. + This define enables no-context 2D command buffer.
  150587. +*/
  150588. +#ifndef gcdCMD_NO_2D_CONTEXT
  150589. +# define gcdCMD_NO_2D_CONTEXT 1
  150590. +#endif
  150591. +
  150592. +/*
  150593. + gcdENABLE_BANK_ALIGNMENT
  150594. +
  150595. + When enabled, video memory is allocated bank aligned. The vendor can modify
  150596. + _GetSurfaceBankAlignment() and gcoSURF_GetBankOffsetBytes() to define how
  150597. + different types of allocations are bank and channel aligned.
  150598. + When disabled (default), no bank alignment is done.
  150599. +*/
  150600. +#ifndef gcdENABLE_BANK_ALIGNMENT
  150601. +# define gcdENABLE_BANK_ALIGNMENT 0
  150602. +#endif
  150603. +
  150604. +/*
  150605. + gcdBANK_BIT_START
  150606. +
  150607. + Specifies the start bit of the bank (inclusive).
  150608. +*/
  150609. +#ifndef gcdBANK_BIT_START
  150610. +# define gcdBANK_BIT_START 12
  150611. +#endif
  150612. +
  150613. +/*
  150614. + gcdBANK_BIT_END
  150615. +
  150616. + Specifies the end bit of the bank (inclusive).
  150617. +*/
  150618. +#ifndef gcdBANK_BIT_END
  150619. +# define gcdBANK_BIT_END 14
  150620. +#endif
  150621. +
  150622. +/*
  150623. + gcdBANK_CHANNEL_BIT
  150624. +
  150625. + When set, video memory when allocated bank aligned is allocated such that
  150626. + render and depth buffer addresses alternate on the channel bit specified.
  150627. + This option has an effect only when gcdENABLE_BANK_ALIGNMENT is enabled.
  150628. + When disabled (default), no alteration is done.
  150629. +*/
  150630. +#ifndef gcdBANK_CHANNEL_BIT
  150631. +# define gcdBANK_CHANNEL_BIT 7
  150632. +#endif
  150633. +
  150634. +/*
  150635. + gcdDYNAMIC_SPEED
  150636. +
  150637. + When non-zero, it informs the kernel driver to use the speed throttling
  150638. + broadcasting functions to inform the system the GPU should be spet up or
  150639. + slowed down. It will send a broadcast for slowdown each "interval"
  150640. + specified by this define in milliseconds
  150641. + (gckOS_BroadcastCalibrateSpeed).
  150642. +*/
  150643. +#ifndef gcdDYNAMIC_SPEED
  150644. +# define gcdDYNAMIC_SPEED 2000
  150645. +#endif
  150646. +
  150647. +/*
  150648. + gcdDYNAMIC_EVENT_THRESHOLD
  150649. +
  150650. + When non-zero, it specifies the maximum number of available events at
  150651. + which the kernel driver will issue a broadcast to speed up the GPU
  150652. + (gckOS_BroadcastHurry).
  150653. +*/
  150654. +#ifndef gcdDYNAMIC_EVENT_THRESHOLD
  150655. +# define gcdDYNAMIC_EVENT_THRESHOLD 5
  150656. +#endif
  150657. +
  150658. +/*
  150659. + gcdENABLE_PROFILING
  150660. +
  150661. + Enable profiling macros.
  150662. +*/
  150663. +#ifndef gcdENABLE_PROFILING
  150664. +# define gcdENABLE_PROFILING 0
  150665. +#endif
  150666. +
  150667. +/*
  150668. + gcdENABLE_128B_MERGE
  150669. +
  150670. + Enable 128B merge for the BUS control.
  150671. +*/
  150672. +#ifndef gcdENABLE_128B_MERGE
  150673. +# define gcdENABLE_128B_MERGE 0
  150674. +#endif
  150675. +
  150676. +/*
  150677. + gcdFRAME_DB
  150678. +
  150679. + When non-zero, it specified the number of frames inside the frame
  150680. + database. The frame DB will collect per-frame timestamps and hardware
  150681. + counters.
  150682. +*/
  150683. +#ifndef gcdFRAME_DB
  150684. +# define gcdFRAME_DB 0
  150685. +# define gcdFRAME_DB_RESET 0
  150686. +# define gcdFRAME_DB_NAME "/var/log/frameDB.log"
  150687. +#endif
  150688. +
  150689. +/*
  150690. + gcdENABLE_VG
  150691. + enable the 2D openVG
  150692. +*/
  150693. +
  150694. +#ifndef gcdENABLE_VG
  150695. +# define gcdENABLE_VG 0
  150696. +#endif
  150697. +
  150698. +/*
  150699. + gcdDYNAMIC_MAP_RESERVED_MEMORY
  150700. +
  150701. + When gcvPOOL_SYSTEM is constructed from RESERVED memory,
  150702. + driver can map the whole reserved memory to kernel space
  150703. + at the beginning, or just map a piece of memory when need
  150704. + to access.
  150705. +
  150706. + Notice:
  150707. + - It's only for the 2D openVG. For other cores, there is
  150708. + _NO_ need to map reserved memory to kernel.
  150709. + - It's meaningless when memory is allocated by
  150710. + gckOS_AllocateContiguous, in that case, memory is always
  150711. + mapped by system when allocated.
  150712. +*/
  150713. +#ifndef gcdDYNAMIC_MAP_RESERVED_MEMORY
  150714. +# define gcdDYNAMIC_MAP_RESERVED_MEMORY 1
  150715. +#endif
  150716. +
  150717. +/*
  150718. + gcdPAGED_MEMORY_CACHEABLE
  150719. +
  150720. + When non-zero, paged memory will be cacheable.
  150721. +
  150722. + Normally, driver will detemines whether a video memory
  150723. + is cacheable or not. When cacheable is not neccessary,
  150724. + it will be writecombine.
  150725. +
  150726. + This option is only for those SOC which can't enable
  150727. + writecombine without enabling cacheable.
  150728. +*/
  150729. +
  150730. +#ifndef gcdPAGED_MEMORY_CACHEABLE
  150731. +# define gcdPAGED_MEMORY_CACHEABLE 0
  150732. +#endif
  150733. +
  150734. +/*
  150735. + gcdNONPAGED_MEMORY_CACHEABLE
  150736. +
  150737. + When non-zero, non paged memory will be cacheable.
  150738. +*/
  150739. +
  150740. +#ifndef gcdNONPAGED_MEMORY_CACHEABLE
  150741. +# define gcdNONPAGED_MEMORY_CACHEABLE 0
  150742. +#endif
  150743. +
  150744. +/*
  150745. + gcdNONPAGED_MEMORY_BUFFERABLE
  150746. +
  150747. + When non-zero, non paged memory will be bufferable.
  150748. + gcdNONPAGED_MEMORY_BUFFERABLE and gcdNONPAGED_MEMORY_CACHEABLE
  150749. + can't be set 1 at same time
  150750. +*/
  150751. +
  150752. +#ifndef gcdNONPAGED_MEMORY_BUFFERABLE
  150753. +# define gcdNONPAGED_MEMORY_BUFFERABLE 1
  150754. +#endif
  150755. +
  150756. +/*
  150757. + gcdENABLE_INFINITE_SPEED_HW
  150758. + enable the Infinte HW , this is for 2D openVG
  150759. +*/
  150760. +
  150761. +#ifndef gcdENABLE_INFINITE_SPEED_HW
  150762. +# define gcdENABLE_INFINITE_SPEED_HW 0
  150763. +#endif
  150764. +
  150765. +/*
  150766. + gcdENABLE_TS_DOUBLE_BUFFER
  150767. + enable the TS double buffer, this is for 2D openVG
  150768. +*/
  150769. +
  150770. +#ifndef gcdENABLE_TS_DOUBLE_BUFFER
  150771. +# define gcdENABLE_TS_DOUBLE_BUFFER 1
  150772. +#endif
  150773. +
  150774. +/*
  150775. + gcd6000_SUPPORT
  150776. +
  150777. + Temporary define to enable/disable 6000 support.
  150778. + */
  150779. +#ifndef gcd6000_SUPPORT
  150780. +# define gcd6000_SUPPORT 0
  150781. +#endif
  150782. +
  150783. +/*
  150784. + gcdPOWEROFF_TIMEOUT
  150785. +
  150786. + When non-zero, GPU will power off automatically from
  150787. + idle state, and gcdPOWEROFF_TIMEOUT is also the default
  150788. + timeout in milliseconds.
  150789. + */
  150790. +
  150791. +#ifndef gcdPOWEROFF_TIMEOUT
  150792. +# define gcdPOWEROFF_TIMEOUT 300
  150793. +#endif
  150794. +
  150795. +/*
  150796. + gcdUSE_VIDMEM_PER_PID
  150797. +*/
  150798. +#ifndef gcdUSE_VIDMEM_PER_PID
  150799. +# define gcdUSE_VIDMEM_PER_PID 0
  150800. +#endif
  150801. +
  150802. +/*
  150803. + QNX_SINGLE_THREADED_DEBUGGING
  150804. +*/
  150805. +#ifndef QNX_SINGLE_THREADED_DEBUGGING
  150806. +# define QNX_SINGLE_THREADED_DEBUGGING 0
  150807. +#endif
  150808. +
  150809. +/*
  150810. + gcdENABLE_RECOVERY
  150811. +
  150812. + This define enables the recovery code.
  150813. +*/
  150814. +#ifndef gcdENABLE_RECOVERY
  150815. +# define gcdENABLE_RECOVERY 1
  150816. +#endif
  150817. +
  150818. +/*
  150819. + gcdRENDER_THREADS
  150820. +
  150821. + Number of render threads. Make it zero, and there will be no render
  150822. + threads.
  150823. +*/
  150824. +#ifndef gcdRENDER_THREADS
  150825. +# define gcdRENDER_THREADS 0
  150826. +#endif
  150827. +
  150828. +/*
  150829. + gcdSMP
  150830. +
  150831. + This define enables SMP support.
  150832. +
  150833. + Currently, it only works on Linux/Android,
  150834. + Kbuild will config it according to whether
  150835. + CONFIG_SMP is set.
  150836. +
  150837. +*/
  150838. +#ifndef gcdSMP
  150839. +# define gcdSMP 0
  150840. +#endif
  150841. +
  150842. +/*
  150843. + gcdSUPPORT_SWAP_RECTANGLE
  150844. +
  150845. + Support swap with a specific rectangle.
  150846. +
  150847. + Set the rectangle with eglSetSwapRectangleANDROID api.
  150848. +*/
  150849. +#ifndef gcdSUPPORT_SWAP_RECTANGLE
  150850. +# define gcdSUPPORT_SWAP_RECTANGLE 0
  150851. +#endif
  150852. +
  150853. +/*
  150854. + gcdGPU_LINEAR_BUFFER_ENABLED
  150855. +
  150856. + Use linear buffer for GPU apps so HWC can do 2D composition.
  150857. +*/
  150858. +#ifndef gcdGPU_LINEAR_BUFFER_ENABLED
  150859. +# define gcdGPU_LINEAR_BUFFER_ENABLED 1
  150860. +#endif
  150861. +
  150862. +/*
  150863. + gcdENABLE_RENDER_INTO_WINDOW
  150864. +
  150865. + Enable Render-Into-Window (ie, No-Resolve) feature on android.
  150866. + NOTE that even if enabled, it still depends on hardware feature and
  150867. + android application behavior. When hardware feature or application
  150868. + behavior can not support render into window mode, it will fail back
  150869. + to normal mode.
  150870. + When Render-Into-Window is finally used, window back buffer of android
  150871. + applications will be allocated matching render target tiling format.
  150872. + Otherwise buffer tiling is decided by the above option
  150873. + 'gcdGPU_LINEAR_BUFFER_ENABLED'.
  150874. +*/
  150875. +#ifndef gcdENABLE_RENDER_INTO_WINDOW
  150876. +# define gcdENABLE_RENDER_INTO_WINDOW 1
  150877. +#endif
  150878. +
  150879. +/*
  150880. + gcdSHARED_RESOLVE_BUFFER_ENABLED
  150881. +
  150882. + Use shared resolve buffer for all app buffers.
  150883. +*/
  150884. +#ifndef gcdSHARED_RESOLVE_BUFFER_ENABLED
  150885. +# define gcdSHARED_RESOLVE_BUFFER_ENABLED 0
  150886. +#endif
  150887. +
  150888. +/*
  150889. + gcdUSE_TRIANGLE_STRIP_PATCH
  150890. + */
  150891. +#ifndef gcdUSE_TRIANGLE_STRIP_PATCH
  150892. +# define gcdUSE_TRIANGLE_STRIP_PATCH 1
  150893. +#endif
  150894. +
  150895. +/*
  150896. + gcdENABLE_OUTER_CACHE_PATCH
  150897. +
  150898. + Enable the outer cache patch.
  150899. +*/
  150900. +#ifndef gcdENABLE_OUTER_CACHE_PATCH
  150901. +# define gcdENABLE_OUTER_CACHE_PATCH 0
  150902. +#endif
  150903. +
  150904. +#ifndef gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST
  150905. +# ifdef ANDROID
  150906. +# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 1
  150907. +# else
  150908. +# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 0
  150909. +# endif
  150910. +#endif
  150911. +
  150912. +#ifndef gcdENABLE_PE_DITHER_FIX
  150913. +# define gcdENABLE_PE_DITHER_FIX 1
  150914. +#endif
  150915. +
  150916. +#ifndef gcdSHARED_PAGETABLE
  150917. +# define gcdSHARED_PAGETABLE 1
  150918. +#endif
  150919. +#ifndef gcdUSE_PVR
  150920. +# define gcdUSE_PVR 1
  150921. +#endif
  150922. +
  150923. +/*
  150924. + gcdSMALL_BLOCK_SIZE
  150925. +
  150926. + When non-zero, a part of VIDMEM will be reserved for requests
  150927. + whose requesting size is less than gcdSMALL_BLOCK_SIZE.
  150928. +
  150929. + For Linux, it's the size of a page. If this requeset fallbacks
  150930. + to gcvPOOL_CONTIGUOUS or gcvPOOL_VIRTUAL, memory will be wasted
  150931. + because they allocate a page at least.
  150932. + */
  150933. +#ifndef gcdSMALL_BLOCK_SIZE
  150934. +# define gcdSMALL_BLOCK_SIZE 4096
  150935. +# define gcdRATIO_FOR_SMALL_MEMORY 32
  150936. +#endif
  150937. +
  150938. +/*
  150939. + gcdCONTIGUOUS_SIZE_LIMIT
  150940. + When non-zero, size of video node from gcvPOOL_CONTIGUOUS is
  150941. + limited by gcdCONTIGUOUS_SIZE_LIMIT.
  150942. + */
  150943. +#ifndef gcdCONTIGUOUS_SIZE_LIMIT
  150944. +# define gcdCONTIGUOUS_SIZE_LIMIT 0
  150945. +#endif
  150946. +
  150947. +#ifndef gcdDISALBE_EARLY_EARLY_Z
  150948. +# define gcdDISALBE_EARLY_EARLY_Z 1
  150949. +#endif
  150950. +
  150951. +#ifndef gcdSHADER_SRC_BY_MACHINECODE
  150952. +# define gcdSHADER_SRC_BY_MACHINECODE 1
  150953. +#endif
  150954. +
  150955. +/*
  150956. + gcdLINK_QUEUE_SIZE
  150957. +
  150958. + When non-zero, driver maintains a queue to record information of
  150959. + latest lined context buffer and command buffer. Data in this queue
  150960. + is be used to debug.
  150961. +*/
  150962. +#ifndef gcdLINK_QUEUE_SIZE
  150963. +# define gcdLINK_QUEUE_SIZE 0
  150964. +#endif
  150965. +
  150966. +/* gcdALPHA_KILL_IN_SHADER
  150967. + *
  150968. + * Enable alpha kill inside the shader. This will be set automatically by the
  150969. + * HAL if certain states match a criteria.
  150970. + */
  150971. +#ifndef gcdALPHA_KILL_IN_SHADER
  150972. +# define gcdALPHA_KILL_IN_SHADER 1
  150973. +#endif
  150974. +
  150975. +/* gcdHIGH_PRECISION_DELAY_ENABLE
  150976. + *
  150977. + * Enable high precision schedule delay with 1ms unit. otherwise schedule delay up to 10ms.
  150978. + * Browser app performance will have obvious drop without this enablement
  150979. + */
  150980. +#ifndef gcdHIGH_PRECISION_DELAY_ENABLE
  150981. +# define gcdHIGH_PRECISION_DELAY_ENABLE 1
  150982. +#endif
  150983. +
  150984. +#ifndef gcdUSE_WCLIP_PATCH
  150985. +# define gcdUSE_WCLIP_PATCH 1
  150986. +#endif
  150987. +
  150988. +#ifndef gcdHZ_L2_DISALBE
  150989. +# define gcdHZ_L2_DISALBE 1
  150990. +#endif
  150991. +
  150992. +#ifndef gcdBUGFIX15_DISABLE
  150993. +# define gcdBUGFIX15_DISABLE 1
  150994. +#endif
  150995. +
  150996. +#ifndef gcdDISABLE_HZ_FAST_CLEAR
  150997. +# define gcdDISABLE_HZ_FAST_CLEAR 1
  150998. +#endif
  150999. +
  151000. +#ifndef gcdUSE_NPOT_PATCH
  151001. +#define gcdUSE_NPOT_PATCH 1
  151002. +#endif
  151003. +
  151004. +#ifndef gcdSYNC
  151005. +# define gcdSYNC 1
  151006. +#endif
  151007. +
  151008. +#ifndef gcdENABLE_SPECIAL_HINT3
  151009. +# define gcdENABLE_SPECIAL_HINT3 1
  151010. +#endif
  151011. +
  151012. +#if defined(ANDROID)
  151013. +#ifndef gcdPRE_ROTATION
  151014. +# define gcdPRE_ROTATION 1
  151015. +#endif
  151016. +#endif
  151017. +
  151018. +/*
  151019. + gcdDVFS
  151020. +
  151021. + When non-zero, software will make use of dynamic voltage and
  151022. + frequency feature.
  151023. + */
  151024. +#ifndef gcdDVFS
  151025. +# define gcdDVFS 0
  151026. +# define gcdDVFS_ANAYLSE_WINDOW 4
  151027. +# define gcdDVFS_POLLING_TIME (gcdDVFS_ANAYLSE_WINDOW * 4)
  151028. +#endif
  151029. +
  151030. +/*
  151031. + gcdANDROID_NATIVE_FENCE_SYNC
  151032. +
  151033. + Enable android native fence sync. It is introduced since jellybean-4.2.
  151034. + Depends on linux kernel option: CONFIG_SYNC.
  151035. +
  151036. + 0: Disabled
  151037. + 1: Build framework for native fence sync feature, and EGL extension
  151038. + 2: Enable async swap buffers for client
  151039. + * Native fence sync for client 'queueBuffer' in EGL, which is
  151040. + 'acquireFenceFd' for layer in compositor side.
  151041. + 3. Enable async hwcomposer composition.
  151042. + * 'releaseFenceFd' for layer in compositor side, which is native
  151043. + fence sync when client 'dequeueBuffer'
  151044. + * Native fence sync for compositor 'queueBuffer' in EGL, which is
  151045. + 'acquireFenceFd' for framebuffer target for DC
  151046. + */
  151047. +#ifndef gcdANDROID_NATIVE_FENCE_SYNC
  151048. +# define gcdANDROID_NATIVE_FENCE_SYNC 0
  151049. +#endif
  151050. +
  151051. +#ifndef gcdFORCE_MIPMAP
  151052. +# define gcdFORCE_MIPMAP 0
  151053. +#endif
  151054. +
  151055. +/*
  151056. + gcdFORCE_GAL_LOAD_TWICE
  151057. +
  151058. + When non-zero, each thread except the main one will load libGAL.so twice to avoid potential segmetantion fault when app using dlopen/dlclose.
  151059. + If threads exit arbitrarily, libGAL.so may not unload until the process quit.
  151060. + */
  151061. +#ifndef gcdFORCE_GAL_LOAD_TWICE
  151062. +# define gcdFORCE_GAL_LOAD_TWICE 0
  151063. +#endif
  151064. +
  151065. +#endif /* __gc_hal_options_h_ */
  151066. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h
  151067. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h 1969-12-31 18:00:00.000000000 -0600
  151068. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h 2014-12-08 00:31:53.468418001 -0600
  151069. @@ -0,0 +1,584 @@
  151070. +/****************************************************************************
  151071. +*
  151072. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  151073. +*
  151074. +* This program is free software; you can redistribute it and/or modify
  151075. +* it under the terms of the GNU General Public License as published by
  151076. +* the Free Software Foundation; either version 2 of the license, or
  151077. +* (at your option) any later version.
  151078. +*
  151079. +* This program is distributed in the hope that it will be useful,
  151080. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  151081. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  151082. +* GNU General Public License for more details.
  151083. +*
  151084. +* You should have received a copy of the GNU General Public License
  151085. +* along with this program; if not write to the Free Software
  151086. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  151087. +*
  151088. +*****************************************************************************/
  151089. +
  151090. +
  151091. +#ifndef __gc_hal_profiler_h_
  151092. +#define __gc_hal_profiler_h_
  151093. +
  151094. +#ifdef __cplusplus
  151095. +extern "C" {
  151096. +#endif
  151097. +
  151098. +#define GLVERTEX_OBJECT 10
  151099. +#define GLVERTEX_OBJECT_BYTES 11
  151100. +
  151101. +#define GLINDEX_OBJECT 20
  151102. +#define GLINDEX_OBJECT_BYTES 21
  151103. +
  151104. +#define GLTEXTURE_OBJECT 30
  151105. +#define GLTEXTURE_OBJECT_BYTES 31
  151106. +
  151107. +#if VIVANTE_PROFILER
  151108. +#define gcmPROFILE_GC(Enum, Value) gcoPROFILER_Count(gcvNULL, Enum, Value)
  151109. +#else
  151110. +#define gcmPROFILE_GC(Enum, Value) do { } while (gcvFALSE)
  151111. +#endif
  151112. +
  151113. +#ifndef gcdNEW_PROFILER_FILE
  151114. +#define gcdNEW_PROFILER_FILE 1
  151115. +#endif
  151116. +
  151117. +#define ES11_CALLS 151
  151118. +#define ES11_DRAWCALLS (ES11_CALLS + 1)
  151119. +#define ES11_STATECHANGECALLS (ES11_DRAWCALLS + 1)
  151120. +#define ES11_POINTCOUNT (ES11_STATECHANGECALLS + 1)
  151121. +#define ES11_LINECOUNT (ES11_POINTCOUNT + 1)
  151122. +#define ES11_TRIANGLECOUNT (ES11_LINECOUNT + 1)
  151123. +
  151124. +#define ES20_CALLS 159
  151125. +#define ES20_DRAWCALLS (ES20_CALLS + 1)
  151126. +#define ES20_STATECHANGECALLS (ES20_DRAWCALLS + 1)
  151127. +#define ES20_POINTCOUNT (ES20_STATECHANGECALLS + 1)
  151128. +#define ES20_LINECOUNT (ES20_POINTCOUNT + 1)
  151129. +#define ES20_TRIANGLECOUNT (ES20_LINECOUNT + 1)
  151130. +
  151131. +#define VG11_CALLS 88
  151132. +#define VG11_DRAWCALLS (VG11_CALLS + 1)
  151133. +#define VG11_STATECHANGECALLS (VG11_DRAWCALLS + 1)
  151134. +#define VG11_FILLCOUNT (VG11_STATECHANGECALLS + 1)
  151135. +#define VG11_STROKECOUNT (VG11_FILLCOUNT + 1)
  151136. +/* End of Driver API ID Definitions. */
  151137. +
  151138. +/* HAL & MISC IDs. */
  151139. +#define HAL_VERTBUFNEWBYTEALLOC 1
  151140. +#define HAL_VERTBUFTOTALBYTEALLOC (HAL_VERTBUFNEWBYTEALLOC + 1)
  151141. +#define HAL_VERTBUFNEWOBJALLOC (HAL_VERTBUFTOTALBYTEALLOC + 1)
  151142. +#define HAL_VERTBUFTOTALOBJALLOC (HAL_VERTBUFNEWOBJALLOC + 1)
  151143. +#define HAL_INDBUFNEWBYTEALLOC (HAL_VERTBUFTOTALOBJALLOC + 1)
  151144. +#define HAL_INDBUFTOTALBYTEALLOC (HAL_INDBUFNEWBYTEALLOC + 1)
  151145. +#define HAL_INDBUFNEWOBJALLOC (HAL_INDBUFTOTALBYTEALLOC + 1)
  151146. +#define HAL_INDBUFTOTALOBJALLOC (HAL_INDBUFNEWOBJALLOC + 1)
  151147. +#define HAL_TEXBUFNEWBYTEALLOC (HAL_INDBUFTOTALOBJALLOC + 1)
  151148. +#define HAL_TEXBUFTOTALBYTEALLOC (HAL_TEXBUFNEWBYTEALLOC + 1)
  151149. +#define HAL_TEXBUFNEWOBJALLOC (HAL_TEXBUFTOTALBYTEALLOC + 1)
  151150. +#define HAL_TEXBUFTOTALOBJALLOC (HAL_TEXBUFNEWOBJALLOC + 1)
  151151. +
  151152. +#define GPU_CYCLES 1
  151153. +#define GPU_READ64BYTE (GPU_CYCLES + 1)
  151154. +#define GPU_WRITE64BYTE (GPU_READ64BYTE + 1)
  151155. +#define GPU_TOTALCYCLES (GPU_WRITE64BYTE + 1)
  151156. +#define GPU_IDLECYCLES (GPU_TOTALCYCLES + 1)
  151157. +
  151158. +#define VS_INSTCOUNT 1
  151159. +#define VS_BRANCHINSTCOUNT (VS_INSTCOUNT + 1)
  151160. +#define VS_TEXLDINSTCOUNT (VS_BRANCHINSTCOUNT + 1)
  151161. +#define VS_RENDEREDVERTCOUNT (VS_TEXLDINSTCOUNT + 1)
  151162. +#define VS_SOURCE (VS_RENDEREDVERTCOUNT + 1)
  151163. +
  151164. +#define PS_INSTCOUNT 1
  151165. +#define PS_BRANCHINSTCOUNT (PS_INSTCOUNT + 1)
  151166. +#define PS_TEXLDINSTCOUNT (PS_BRANCHINSTCOUNT + 1)
  151167. +#define PS_RENDEREDPIXCOUNT (PS_TEXLDINSTCOUNT + 1)
  151168. +#define PS_SOURCE (PS_RENDEREDPIXCOUNT + 1)
  151169. +
  151170. +#define PA_INVERTCOUNT 1
  151171. +#define PA_INPRIMCOUNT (PA_INVERTCOUNT + 1)
  151172. +#define PA_OUTPRIMCOUNT (PA_INPRIMCOUNT + 1)
  151173. +#define PA_DEPTHCLIPCOUNT (PA_OUTPRIMCOUNT + 1)
  151174. +#define PA_TRIVIALREJCOUNT (PA_DEPTHCLIPCOUNT + 1)
  151175. +#define PA_CULLCOUNT (PA_TRIVIALREJCOUNT + 1)
  151176. +
  151177. +#define SE_TRIANGLECOUNT 1
  151178. +#define SE_LINECOUNT (SE_TRIANGLECOUNT + 1)
  151179. +
  151180. +#define RA_VALIDPIXCOUNT 1
  151181. +#define RA_TOTALQUADCOUNT (RA_VALIDPIXCOUNT + 1)
  151182. +#define RA_VALIDQUADCOUNTEZ (RA_TOTALQUADCOUNT + 1)
  151183. +#define RA_TOTALPRIMCOUNT (RA_VALIDQUADCOUNTEZ + 1)
  151184. +#define RA_PIPECACHEMISSCOUNT (RA_TOTALPRIMCOUNT + 1)
  151185. +#define RA_PREFCACHEMISSCOUNT (RA_PIPECACHEMISSCOUNT + 1)
  151186. +#define RA_EEZCULLCOUNT (RA_PREFCACHEMISSCOUNT + 1)
  151187. +
  151188. +#define TX_TOTBILINEARREQ 1
  151189. +#define TX_TOTTRILINEARREQ (TX_TOTBILINEARREQ + 1)
  151190. +#define TX_TOTDISCARDTEXREQ (TX_TOTTRILINEARREQ + 1)
  151191. +#define TX_TOTTEXREQ (TX_TOTDISCARDTEXREQ + 1)
  151192. +#define TX_MEMREADCOUNT (TX_TOTTEXREQ + 1)
  151193. +#define TX_MEMREADIN8BCOUNT (TX_MEMREADCOUNT + 1)
  151194. +#define TX_CACHEMISSCOUNT (TX_MEMREADIN8BCOUNT + 1)
  151195. +#define TX_CACHEHITTEXELCOUNT (TX_CACHEMISSCOUNT + 1)
  151196. +#define TX_CACHEMISSTEXELCOUNT (TX_CACHEHITTEXELCOUNT + 1)
  151197. +
  151198. +#define PE_KILLEDBYCOLOR 1
  151199. +#define PE_KILLEDBYDEPTH (PE_KILLEDBYCOLOR + 1)
  151200. +#define PE_DRAWNBYCOLOR (PE_KILLEDBYDEPTH + 1)
  151201. +#define PE_DRAWNBYDEPTH (PE_DRAWNBYCOLOR + 1)
  151202. +
  151203. +#define MC_READREQ8BPIPE 1
  151204. +#define MC_READREQ8BIP (MC_READREQ8BPIPE + 1)
  151205. +#define MC_WRITEREQ8BPIPE (MC_READREQ8BIP + 1)
  151206. +
  151207. +#define AXI_READREQSTALLED 1
  151208. +#define AXI_WRITEREQSTALLED (AXI_READREQSTALLED + 1)
  151209. +#define AXI_WRITEDATASTALLED (AXI_WRITEREQSTALLED + 1)
  151210. +
  151211. +#define PVS_INSTRCOUNT 1
  151212. +#define PVS_ALUINSTRCOUNT (PVS_INSTRCOUNT + 1)
  151213. +#define PVS_TEXINSTRCOUNT (PVS_ALUINSTRCOUNT + 1)
  151214. +#define PVS_ATTRIBCOUNT (PVS_TEXINSTRCOUNT + 1)
  151215. +#define PVS_UNIFORMCOUNT (PVS_ATTRIBCOUNT + 1)
  151216. +#define PVS_FUNCTIONCOUNT (PVS_UNIFORMCOUNT + 1)
  151217. +#define PVS_SOURCE (PVS_FUNCTIONCOUNT + 1)
  151218. +
  151219. +#define PPS_INSTRCOUNT 1
  151220. +#define PPS_ALUINSTRCOUNT (PPS_INSTRCOUNT + 1)
  151221. +#define PPS_TEXINSTRCOUNT (PPS_ALUINSTRCOUNT + 1)
  151222. +#define PPS_ATTRIBCOUNT (PPS_TEXINSTRCOUNT + 1)
  151223. +#define PPS_UNIFORMCOUNT (PPS_ATTRIBCOUNT + 1)
  151224. +#define PPS_FUNCTIONCOUNT (PPS_UNIFORMCOUNT + 1)
  151225. +#define PPS_SOURCE (PPS_FUNCTIONCOUNT + 1)
  151226. +/* End of MISC Counter IDs. */
  151227. +
  151228. +#ifdef gcdNEW_PROFILER_FILE
  151229. +
  151230. +/* Category Constants. */
  151231. +#define VPHEADER 0x010000
  151232. +#define VPG_INFO 0x020000
  151233. +#define VPG_TIME 0x030000
  151234. +#define VPG_MEM 0x040000
  151235. +#define VPG_ES11 0x050000
  151236. +#define VPG_ES20 0x060000
  151237. +#define VPG_VG11 0x070000
  151238. +#define VPG_HAL 0x080000
  151239. +#define VPG_HW 0x090000
  151240. +#define VPG_GPU 0x0a0000
  151241. +#define VPG_VS 0x0b0000
  151242. +#define VPG_PS 0x0c0000
  151243. +#define VPG_PA 0x0d0000
  151244. +#define VPG_SETUP 0x0e0000
  151245. +#define VPG_RA 0x0f0000
  151246. +#define VPG_TX 0x100000
  151247. +#define VPG_PE 0x110000
  151248. +#define VPG_MC 0x120000
  151249. +#define VPG_AXI 0x130000
  151250. +#define VPG_PROG 0x140000
  151251. +#define VPG_PVS 0x150000
  151252. +#define VPG_PPS 0x160000
  151253. +#define VPG_ES11_TIME 0x170000
  151254. +#define VPG_ES20_TIME 0x180000
  151255. +#define VPG_FRAME 0x190000
  151256. +#define VPG_ES11_DRAW 0x200000
  151257. +#define VPG_ES20_DRAW 0x210000
  151258. +#define VPG_END 0xff0000
  151259. +
  151260. +/* Info. */
  151261. +#define VPC_INFOCOMPANY (VPG_INFO + 1)
  151262. +#define VPC_INFOVERSION (VPC_INFOCOMPANY + 1)
  151263. +#define VPC_INFORENDERER (VPC_INFOVERSION + 1)
  151264. +#define VPC_INFOREVISION (VPC_INFORENDERER + 1)
  151265. +#define VPC_INFODRIVER (VPC_INFOREVISION + 1)
  151266. +#define VPC_INFODRIVERMODE (VPC_INFODRIVER + 1)
  151267. +#define VPC_INFOSCREENSIZE (VPC_INFODRIVERMODE + 1)
  151268. +
  151269. +/* Counter Constants. */
  151270. +#define VPC_ELAPSETIME (VPG_TIME + 1)
  151271. +#define VPC_CPUTIME (VPC_ELAPSETIME + 1)
  151272. +
  151273. +#define VPC_MEMMAXRES (VPG_MEM + 1)
  151274. +#define VPC_MEMSHARED (VPC_MEMMAXRES + 1)
  151275. +#define VPC_MEMUNSHAREDDATA (VPC_MEMSHARED + 1)
  151276. +#define VPC_MEMUNSHAREDSTACK (VPC_MEMUNSHAREDDATA + 1)
  151277. +
  151278. +/* OpenGL ES11 Statics Counter IDs. */
  151279. +#define VPC_ES11CALLS (VPG_ES11 + ES11_CALLS)
  151280. +#define VPC_ES11DRAWCALLS (VPG_ES11 + ES11_DRAWCALLS)
  151281. +#define VPC_ES11STATECHANGECALLS (VPG_ES11 + ES11_STATECHANGECALLS)
  151282. +#define VPC_ES11POINTCOUNT (VPG_ES11 + ES11_POINTCOUNT)
  151283. +#define VPC_ES11LINECOUNT (VPG_ES11 + ES11_LINECOUNT)
  151284. +#define VPC_ES11TRIANGLECOUNT (VPG_ES11 + ES11_TRIANGLECOUNT)
  151285. +
  151286. +/* OpenGL ES20 Statistics Counter IDs. */
  151287. +#define VPC_ES20CALLS (VPG_ES20 + ES20_CALLS)
  151288. +#define VPC_ES20DRAWCALLS (VPG_ES20 + ES20_DRAWCALLS)
  151289. +#define VPC_ES20STATECHANGECALLS (VPG_ES20 + ES20_STATECHANGECALLS)
  151290. +#define VPC_ES20POINTCOUNT (VPG_ES20 + ES20_POINTCOUNT)
  151291. +#define VPC_ES20LINECOUNT (VPG_ES20 + ES20_LINECOUNT)
  151292. +#define VPC_ES20TRIANGLECOUNT (VPG_ES20 + ES20_TRIANGLECOUNT)
  151293. +
  151294. +/* OpenVG Statistics Counter IDs. */
  151295. +#define VPC_VG11CALLS (VPG_VG11 + VG11_CALLS)
  151296. +#define VPC_VG11DRAWCALLS (VPG_VG11 + VG11_DRAWCALLS)
  151297. +#define VPC_VG11STATECHANGECALLS (VPG_VG11 + VG11_STATECHANGECALLS)
  151298. +#define VPC_VG11FILLCOUNT (VPG_VG11 + VG11_FILLCOUNT)
  151299. +#define VPC_VG11STROKECOUNT (VPG_VG11 + VG11_STROKECOUNT)
  151300. +
  151301. +/* HAL Counters. */
  151302. +#define VPC_HALVERTBUFNEWBYTEALLOC (VPG_HAL + HAL_VERTBUFNEWBYTEALLOC)
  151303. +#define VPC_HALVERTBUFTOTALBYTEALLOC (VPG_HAL + HAL_VERTBUFTOTALBYTEALLOC)
  151304. +#define VPC_HALVERTBUFNEWOBJALLOC (VPG_HAL + HAL_VERTBUFNEWOBJALLOC)
  151305. +#define VPC_HALVERTBUFTOTALOBJALLOC (VPG_HAL + HAL_VERTBUFTOTALOBJALLOC)
  151306. +#define VPC_HALINDBUFNEWBYTEALLOC (VPG_HAL + HAL_INDBUFNEWBYTEALLOC)
  151307. +#define VPC_HALINDBUFTOTALBYTEALLOC (VPG_HAL + HAL_INDBUFTOTALBYTEALLOC)
  151308. +#define VPC_HALINDBUFNEWOBJALLOC (VPG_HAL + HAL_INDBUFNEWOBJALLOC)
  151309. +#define VPC_HALINDBUFTOTALOBJALLOC (VPG_HAL + HAL_INDBUFTOTALOBJALLOC)
  151310. +#define VPC_HALTEXBUFNEWBYTEALLOC (VPG_HAL + HAL_TEXBUFNEWBYTEALLOC)
  151311. +#define VPC_HALTEXBUFTOTALBYTEALLOC (VPG_HAL + HAL_TEXBUFTOTALBYTEALLOC)
  151312. +#define VPC_HALTEXBUFNEWOBJALLOC (VPG_HAL + HAL_TEXBUFNEWOBJALLOC)
  151313. +#define VPC_HALTEXBUFTOTALOBJALLOC (VPG_HAL + HAL_TEXBUFTOTALOBJALLOC)
  151314. +
  151315. +/* HW: GPU Counters. */
  151316. +#define VPC_GPUCYCLES (VPG_GPU + GPU_CYCLES)
  151317. +#define VPC_GPUREAD64BYTE (VPG_GPU + GPU_READ64BYTE)
  151318. +#define VPC_GPUWRITE64BYTE (VPG_GPU + GPU_WRITE64BYTE)
  151319. +#define VPC_GPUTOTALCYCLES (VPG_GPU + GPU_TOTALCYCLES)
  151320. +#define VPC_GPUIDLECYCLES (VPG_GPU + GPU_IDLECYCLES)
  151321. +
  151322. +/* HW: Shader Counters. */
  151323. +#define VPC_VSINSTCOUNT (VPG_VS + VS_INSTCOUNT)
  151324. +#define VPC_VSBRANCHINSTCOUNT (VPG_VS + VS_BRANCHINSTCOUNT)
  151325. +#define VPC_VSTEXLDINSTCOUNT (VPG_VS + VS_TEXLDINSTCOUNT)
  151326. +#define VPC_VSRENDEREDVERTCOUNT (VPG_VS + VS_RENDEREDVERTCOUNT)
  151327. +/* HW: PS Count. */
  151328. +#define VPC_PSINSTCOUNT (VPG_PS + PS_INSTCOUNT)
  151329. +#define VPC_PSBRANCHINSTCOUNT (VPG_PS + PS_BRANCHINSTCOUNT)
  151330. +#define VPC_PSTEXLDINSTCOUNT (VPG_PS + PS_TEXLDINSTCOUNT)
  151331. +#define VPC_PSRENDEREDPIXCOUNT (VPG_PS + PS_RENDEREDPIXCOUNT)
  151332. +
  151333. +
  151334. +/* HW: PA Counters. */
  151335. +#define VPC_PAINVERTCOUNT (VPG_PA + PA_INVERTCOUNT)
  151336. +#define VPC_PAINPRIMCOUNT (VPG_PA + PA_INPRIMCOUNT)
  151337. +#define VPC_PAOUTPRIMCOUNT (VPG_PA + PA_OUTPRIMCOUNT)
  151338. +#define VPC_PADEPTHCLIPCOUNT (VPG_PA + PA_DEPTHCLIPCOUNT)
  151339. +#define VPC_PATRIVIALREJCOUNT (VPG_PA + PA_TRIVIALREJCOUNT)
  151340. +#define VPC_PACULLCOUNT (VPG_PA + PA_CULLCOUNT)
  151341. +
  151342. +/* HW: Setup Counters. */
  151343. +#define VPC_SETRIANGLECOUNT (VPG_SETUP + SE_TRIANGLECOUNT)
  151344. +#define VPC_SELINECOUNT (VPG_SETUP + SE_LINECOUNT)
  151345. +
  151346. +/* HW: RA Counters. */
  151347. +#define VPC_RAVALIDPIXCOUNT (VPG_RA + RA_VALIDPIXCOUNT)
  151348. +#define VPC_RATOTALQUADCOUNT (VPG_RA + RA_TOTALQUADCOUNT)
  151349. +#define VPC_RAVALIDQUADCOUNTEZ (VPG_RA + RA_VALIDQUADCOUNTEZ)
  151350. +#define VPC_RATOTALPRIMCOUNT (VPG_RA + RA_TOTALPRIMCOUNT)
  151351. +#define VPC_RAPIPECACHEMISSCOUNT (VPG_RA + RA_PIPECACHEMISSCOUNT)
  151352. +#define VPC_RAPREFCACHEMISSCOUNT (VPG_RA + RA_PREFCACHEMISSCOUNT)
  151353. +#define VPC_RAEEZCULLCOUNT (VPG_RA + RA_EEZCULLCOUNT)
  151354. +
  151355. +/* HW: TEX Counters. */
  151356. +#define VPC_TXTOTBILINEARREQ (VPG_TX + TX_TOTBILINEARREQ)
  151357. +#define VPC_TXTOTTRILINEARREQ (VPG_TX + TX_TOTTRILINEARREQ)
  151358. +#define VPC_TXTOTDISCARDTEXREQ (VPG_TX + TX_TOTDISCARDTEXREQ)
  151359. +#define VPC_TXTOTTEXREQ (VPG_TX + TX_TOTTEXREQ)
  151360. +#define VPC_TXMEMREADCOUNT (VPG_TX + TX_MEMREADCOUNT)
  151361. +#define VPC_TXMEMREADIN8BCOUNT (VPG_TX + TX_MEMREADIN8BCOUNT)
  151362. +#define VPC_TXCACHEMISSCOUNT (VPG_TX + TX_CACHEMISSCOUNT)
  151363. +#define VPC_TXCACHEHITTEXELCOUNT (VPG_TX + TX_CACHEHITTEXELCOUNT)
  151364. +#define VPC_TXCACHEMISSTEXELCOUNT (VPG_TX + TX_CACHEMISSTEXELCOUNT)
  151365. +
  151366. +/* HW: PE Counters. */
  151367. +#define VPC_PEKILLEDBYCOLOR (VPG_PE + PE_KILLEDBYCOLOR)
  151368. +#define VPC_PEKILLEDBYDEPTH (VPG_PE + PE_KILLEDBYDEPTH)
  151369. +#define VPC_PEDRAWNBYCOLOR (VPG_PE + PE_DRAWNBYCOLOR)
  151370. +#define VPC_PEDRAWNBYDEPTH (VPG_PE + PE_DRAWNBYDEPTH)
  151371. +
  151372. +/* HW: MC Counters. */
  151373. +#define VPC_MCREADREQ8BPIPE (VPG_MC + MC_READREQ8BPIPE)
  151374. +#define VPC_MCREADREQ8BIP (VPG_MC + MC_READREQ8BIP)
  151375. +#define VPC_MCWRITEREQ8BPIPE (VPG_MC + MC_WRITEREQ8BPIPE)
  151376. +
  151377. +/* HW: AXI Counters. */
  151378. +#define VPC_AXIREADREQSTALLED (VPG_AXI + AXI_READREQSTALLED)
  151379. +#define VPC_AXIWRITEREQSTALLED (VPG_AXI + AXI_WRITEREQSTALLED)
  151380. +#define VPC_AXIWRITEDATASTALLED (VPG_AXI + AXI_WRITEDATASTALLED)
  151381. +
  151382. +/* PROGRAM: Shader program counters. */
  151383. +#define VPC_PVSINSTRCOUNT (VPG_PVS + PVS_INSTRCOUNT)
  151384. +#define VPC_PVSALUINSTRCOUNT (VPG_PVS + PVS_ALUINSTRCOUNT)
  151385. +#define VPC_PVSTEXINSTRCOUNT (VPG_PVS + PVS_TEXINSTRCOUNT)
  151386. +#define VPC_PVSATTRIBCOUNT (VPG_PVS + PVS_ATTRIBCOUNT)
  151387. +#define VPC_PVSUNIFORMCOUNT (VPG_PVS + PVS_UNIFORMCOUNT)
  151388. +#define VPC_PVSFUNCTIONCOUNT (VPG_PVS + PVS_FUNCTIONCOUNT)
  151389. +#define VPC_PVSSOURCE (VPG_PVS + PVS_SOURCE)
  151390. +
  151391. +#define VPC_PPSINSTRCOUNT (VPG_PPS + PPS_INSTRCOUNT)
  151392. +#define VPC_PPSALUINSTRCOUNT (VPG_PPS + PPS_ALUINSTRCOUNT)
  151393. +#define VPC_PPSTEXINSTRCOUNT (VPG_PPS + PPS_TEXINSTRCOUNT)
  151394. +#define VPC_PPSATTRIBCOUNT (VPG_PPS + PPS_ATTRIBCOUNT)
  151395. +#define VPC_PPSUNIFORMCOUNT (VPG_PPS + PPS_UNIFORMCOUNT)
  151396. +#define VPC_PPSFUNCTIONCOUNT (VPG_PPS + PPS_FUNCTIONCOUNT)
  151397. +#define VPC_PPSSOURCE (VPG_PPS + PPS_SOURCE)
  151398. +
  151399. +#define VPC_PROGRAMHANDLE (VPG_PROG + 1)
  151400. +
  151401. +#define VPG_ES20_DRAW_NO (VPG_ES20_DRAW + 1)
  151402. +#define VPG_ES11_DRAW_NO (VPG_ES11_DRAW + 1)
  151403. +
  151404. +#define VPG_FRAME_USEVBO (VPG_FRAME + 1)
  151405. +
  151406. +#endif
  151407. +
  151408. +
  151409. +/* HW profile information. */
  151410. +typedef struct _gcsPROFILER_COUNTERS
  151411. +{
  151412. + /* HW static counters. */
  151413. + gctUINT32 gpuClock;
  151414. + gctUINT32 axiClock;
  151415. + gctUINT32 shaderClock;
  151416. +
  151417. + /* HW vairable counters. */
  151418. + gctUINT32 gpuClockStart;
  151419. + gctUINT32 gpuClockEnd;
  151420. +
  151421. + /* HW vairable counters. */
  151422. + gctUINT32 gpuCyclesCounter;
  151423. + gctUINT32 gpuTotalCyclesCounter;
  151424. + gctUINT32 gpuIdleCyclesCounter;
  151425. + gctUINT32 gpuTotalRead64BytesPerFrame;
  151426. + gctUINT32 gpuTotalWrite64BytesPerFrame;
  151427. +
  151428. + /* PE */
  151429. + gctUINT32 pe_pixel_count_killed_by_color_pipe;
  151430. + gctUINT32 pe_pixel_count_killed_by_depth_pipe;
  151431. + gctUINT32 pe_pixel_count_drawn_by_color_pipe;
  151432. + gctUINT32 pe_pixel_count_drawn_by_depth_pipe;
  151433. +
  151434. + /* SH */
  151435. + gctUINT32 ps_inst_counter;
  151436. + gctUINT32 rendered_pixel_counter;
  151437. + gctUINT32 vs_inst_counter;
  151438. + gctUINT32 rendered_vertice_counter;
  151439. + gctUINT32 vtx_branch_inst_counter;
  151440. + gctUINT32 vtx_texld_inst_counter;
  151441. + gctUINT32 pxl_branch_inst_counter;
  151442. + gctUINT32 pxl_texld_inst_counter;
  151443. +
  151444. + /* PA */
  151445. + gctUINT32 pa_input_vtx_counter;
  151446. + gctUINT32 pa_input_prim_counter;
  151447. + gctUINT32 pa_output_prim_counter;
  151448. + gctUINT32 pa_depth_clipped_counter;
  151449. + gctUINT32 pa_trivial_rejected_counter;
  151450. + gctUINT32 pa_culled_counter;
  151451. +
  151452. + /* SE */
  151453. + gctUINT32 se_culled_triangle_count;
  151454. + gctUINT32 se_culled_lines_count;
  151455. +
  151456. + /* RA */
  151457. + gctUINT32 ra_valid_pixel_count;
  151458. + gctUINT32 ra_total_quad_count;
  151459. + gctUINT32 ra_valid_quad_count_after_early_z;
  151460. + gctUINT32 ra_total_primitive_count;
  151461. + gctUINT32 ra_pipe_cache_miss_counter;
  151462. + gctUINT32 ra_prefetch_cache_miss_counter;
  151463. + gctUINT32 ra_eez_culled_counter;
  151464. +
  151465. + /* TX */
  151466. + gctUINT32 tx_total_bilinear_requests;
  151467. + gctUINT32 tx_total_trilinear_requests;
  151468. + gctUINT32 tx_total_discarded_texture_requests;
  151469. + gctUINT32 tx_total_texture_requests;
  151470. + gctUINT32 tx_mem_read_count;
  151471. + gctUINT32 tx_mem_read_in_8B_count;
  151472. + gctUINT32 tx_cache_miss_count;
  151473. + gctUINT32 tx_cache_hit_texel_count;
  151474. + gctUINT32 tx_cache_miss_texel_count;
  151475. +
  151476. + /* MC */
  151477. + gctUINT32 mc_total_read_req_8B_from_pipeline;
  151478. + gctUINT32 mc_total_read_req_8B_from_IP;
  151479. + gctUINT32 mc_total_write_req_8B_from_pipeline;
  151480. +
  151481. + /* HI */
  151482. + gctUINT32 hi_axi_cycles_read_request_stalled;
  151483. + gctUINT32 hi_axi_cycles_write_request_stalled;
  151484. + gctUINT32 hi_axi_cycles_write_data_stalled;
  151485. +}
  151486. +gcsPROFILER_COUNTERS;
  151487. +
  151488. +/* HAL profile information. */
  151489. +typedef struct _gcsPROFILER
  151490. +{
  151491. + gctUINT32 enable;
  151492. + gctBOOL enableHal;
  151493. + gctBOOL enableHW;
  151494. + gctBOOL enableSH;
  151495. + gctBOOL isSyncMode;
  151496. +
  151497. + gctBOOL useSocket;
  151498. + gctINT sockFd;
  151499. +
  151500. + gctFILE file;
  151501. +
  151502. + /* Aggregate Information */
  151503. +
  151504. + /* Clock Info */
  151505. + gctUINT64 frameStart;
  151506. + gctUINT64 frameEnd;
  151507. +
  151508. + /* Current frame information */
  151509. + gctUINT32 frameNumber;
  151510. + gctUINT64 frameStartTimeusec;
  151511. + gctUINT64 frameEndTimeusec;
  151512. + gctUINT64 frameStartCPUTimeusec;
  151513. + gctUINT64 frameEndCPUTimeusec;
  151514. +
  151515. +#if PROFILE_HAL_COUNTERS
  151516. + gctUINT32 vertexBufferTotalBytesAlloc;
  151517. + gctUINT32 vertexBufferNewBytesAlloc;
  151518. + int vertexBufferTotalObjectsAlloc;
  151519. + int vertexBufferNewObjectsAlloc;
  151520. +
  151521. + gctUINT32 indexBufferTotalBytesAlloc;
  151522. + gctUINT32 indexBufferNewBytesAlloc;
  151523. + int indexBufferTotalObjectsAlloc;
  151524. + int indexBufferNewObjectsAlloc;
  151525. +
  151526. + gctUINT32 textureBufferTotalBytesAlloc;
  151527. + gctUINT32 textureBufferNewBytesAlloc;
  151528. + int textureBufferTotalObjectsAlloc;
  151529. + int textureBufferNewObjectsAlloc;
  151530. +
  151531. + gctUINT32 numCommits;
  151532. + gctUINT32 drawPointCount;
  151533. + gctUINT32 drawLineCount;
  151534. + gctUINT32 drawTriangleCount;
  151535. + gctUINT32 drawVertexCount;
  151536. + gctUINT32 redundantStateChangeCalls;
  151537. +#endif
  151538. +
  151539. + gctUINT32 prevVSInstCount;
  151540. + gctUINT32 prevVSBranchInstCount;
  151541. + gctUINT32 prevVSTexInstCount;
  151542. + gctUINT32 prevVSVertexCount;
  151543. + gctUINT32 prevPSInstCount;
  151544. + gctUINT32 prevPSBranchInstCount;
  151545. + gctUINT32 prevPSTexInstCount;
  151546. + gctUINT32 prevPSPixelCount;
  151547. +
  151548. + char* psSource;
  151549. + char* vsSource;
  151550. +
  151551. +}
  151552. +gcsPROFILER;
  151553. +
  151554. +/* Memory profile information. */
  151555. +struct _gcsMemProfile
  151556. +{
  151557. + /* Memory Usage */
  151558. + gctUINT32 videoMemUsed;
  151559. + gctUINT32 systemMemUsed;
  151560. + gctUINT32 commitBufferSize;
  151561. + gctUINT32 contextBufferCopyBytes;
  151562. +};
  151563. +
  151564. +/* Shader profile information. */
  151565. +struct _gcsSHADER_PROFILER
  151566. +{
  151567. + gctUINT32 shaderLength;
  151568. + gctUINT32 shaderALUCycles;
  151569. + gctUINT32 shaderTexLoadCycles;
  151570. + gctUINT32 shaderTempRegCount;
  151571. + gctUINT32 shaderSamplerRegCount;
  151572. + gctUINT32 shaderInputRegCount;
  151573. + gctUINT32 shaderOutputRegCount;
  151574. +};
  151575. +
  151576. +/* Initialize the gcsProfiler. */
  151577. +gceSTATUS
  151578. +gcoPROFILER_Initialize(
  151579. + IN gcoHAL Hal
  151580. + );
  151581. +
  151582. +/* Destroy the gcProfiler. */
  151583. +gceSTATUS
  151584. +gcoPROFILER_Destroy(
  151585. + IN gcoHAL Hal
  151586. + );
  151587. +
  151588. +/* Write data to profiler. */
  151589. +gceSTATUS
  151590. +gcoPROFILER_Write(
  151591. + IN gcoHAL Hal,
  151592. + IN gctSIZE_T ByteCount,
  151593. + IN gctCONST_POINTER Data
  151594. + );
  151595. +
  151596. +/* Flush data out. */
  151597. +gceSTATUS
  151598. +gcoPROFILER_Flush(
  151599. + IN gcoHAL Hal
  151600. + );
  151601. +
  151602. +/* Call to signal end of frame. */
  151603. +gceSTATUS
  151604. +gcoPROFILER_EndFrame(
  151605. + IN gcoHAL Hal
  151606. + );
  151607. +
  151608. +/* Call to signal end of draw. */
  151609. +gceSTATUS
  151610. +gcoPROFILER_EndDraw(
  151611. + IN gcoHAL Hal,
  151612. + IN gctBOOL FirstDraw
  151613. + );
  151614. +
  151615. +/* Increase profile counter Enum by Value. */
  151616. +gceSTATUS
  151617. +gcoPROFILER_Count(
  151618. + IN gcoHAL Hal,
  151619. + IN gctUINT32 Enum,
  151620. + IN gctINT Value
  151621. + );
  151622. +
  151623. +gceSTATUS
  151624. +gcoPROFILER_ShaderSourceFS(
  151625. + IN gcoHAL Hal,
  151626. + IN char* source
  151627. + );
  151628. +
  151629. +gceSTATUS
  151630. +gcoPROFILER_ShaderSourceVS(
  151631. + IN gcoHAL Hal,
  151632. + IN char* source
  151633. + );
  151634. +
  151635. +/* Profile input vertex shader. */
  151636. +gceSTATUS
  151637. +gcoPROFILER_ShaderVS(
  151638. + IN gcoHAL Hal,
  151639. + IN gctPOINTER Vs
  151640. + );
  151641. +
  151642. +/* Profile input fragment shader. */
  151643. +gceSTATUS
  151644. +gcoPROFILER_ShaderFS(
  151645. + IN gcoHAL Hal,
  151646. + IN gctPOINTER Fs
  151647. + );
  151648. +
  151649. +#ifdef __cplusplus
  151650. +}
  151651. +#endif
  151652. +
  151653. +#endif /* __gc_hal_profiler_h_ */
  151654. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
  151655. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h 1969-12-31 18:00:00.000000000 -0600
  151656. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h 2014-12-08 00:31:53.472418001 -0600
  151657. @@ -0,0 +1,1010 @@
  151658. +/****************************************************************************
  151659. +*
  151660. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  151661. +*
  151662. +* This program is free software; you can redistribute it and/or modify
  151663. +* it under the terms of the GNU General Public License as published by
  151664. +* the Free Software Foundation; either version 2 of the license, or
  151665. +* (at your option) any later version.
  151666. +*
  151667. +* This program is distributed in the hope that it will be useful,
  151668. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  151669. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  151670. +* GNU General Public License for more details.
  151671. +*
  151672. +* You should have received a copy of the GNU General Public License
  151673. +* along with this program; if not write to the Free Software
  151674. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  151675. +*
  151676. +*****************************************************************************/
  151677. +
  151678. +
  151679. +#ifndef __gc_hal_raster_h_
  151680. +#define __gc_hal_raster_h_
  151681. +
  151682. +#include "gc_hal_enum.h"
  151683. +#include "gc_hal_types.h"
  151684. +
  151685. +#ifdef __cplusplus
  151686. +extern "C" {
  151687. +#endif
  151688. +
  151689. +/******************************************************************************\
  151690. +****************************** Object Declarations *****************************
  151691. +\******************************************************************************/
  151692. +
  151693. +typedef struct _gcoBRUSH * gcoBRUSH;
  151694. +typedef struct _gcoBRUSH_CACHE * gcoBRUSH_CACHE;
  151695. +
  151696. +/******************************************************************************\
  151697. +******************************** gcoBRUSH Object *******************************
  151698. +\******************************************************************************/
  151699. +
  151700. +/* Create a new solid color gcoBRUSH object. */
  151701. +gceSTATUS
  151702. +gcoBRUSH_ConstructSingleColor(
  151703. + IN gcoHAL Hal,
  151704. + IN gctUINT32 ColorConvert,
  151705. + IN gctUINT32 Color,
  151706. + IN gctUINT64 Mask,
  151707. + gcoBRUSH * Brush
  151708. + );
  151709. +
  151710. +/* Create a new monochrome gcoBRUSH object. */
  151711. +gceSTATUS
  151712. +gcoBRUSH_ConstructMonochrome(
  151713. + IN gcoHAL Hal,
  151714. + IN gctUINT32 OriginX,
  151715. + IN gctUINT32 OriginY,
  151716. + IN gctUINT32 ColorConvert,
  151717. + IN gctUINT32 FgColor,
  151718. + IN gctUINT32 BgColor,
  151719. + IN gctUINT64 Bits,
  151720. + IN gctUINT64 Mask,
  151721. + gcoBRUSH * Brush
  151722. + );
  151723. +
  151724. +/* Create a color gcoBRUSH object. */
  151725. +gceSTATUS
  151726. +gcoBRUSH_ConstructColor(
  151727. + IN gcoHAL Hal,
  151728. + IN gctUINT32 OriginX,
  151729. + IN gctUINT32 OriginY,
  151730. + IN gctPOINTER Address,
  151731. + IN gceSURF_FORMAT Format,
  151732. + IN gctUINT64 Mask,
  151733. + gcoBRUSH * Brush
  151734. + );
  151735. +
  151736. +/* Destroy an gcoBRUSH object. */
  151737. +gceSTATUS
  151738. +gcoBRUSH_Destroy(
  151739. + IN gcoBRUSH Brush
  151740. + );
  151741. +
  151742. +/******************************************************************************\
  151743. +******************************** gcoSURF Object *******************************
  151744. +\******************************************************************************/
  151745. +
  151746. +/* Set cipping rectangle. */
  151747. +gceSTATUS
  151748. +gcoSURF_SetClipping(
  151749. + IN gcoSURF Surface
  151750. + );
  151751. +
  151752. +/* Clear one or more rectangular areas. */
  151753. +gceSTATUS
  151754. +gcoSURF_Clear2D(
  151755. + IN gcoSURF DestSurface,
  151756. + IN gctUINT32 RectCount,
  151757. + IN gcsRECT_PTR DestRect,
  151758. + IN gctUINT32 LoColor,
  151759. + IN gctUINT32 HiColor
  151760. + );
  151761. +
  151762. +/* Draw one or more Bresenham lines. */
  151763. +gceSTATUS
  151764. +gcoSURF_Line(
  151765. + IN gcoSURF Surface,
  151766. + IN gctUINT32 LineCount,
  151767. + IN gcsRECT_PTR Position,
  151768. + IN gcoBRUSH Brush,
  151769. + IN gctUINT8 FgRop,
  151770. + IN gctUINT8 BgRop
  151771. + );
  151772. +
  151773. +/* Generic rectangular blit. */
  151774. +gceSTATUS
  151775. +gcoSURF_Blit(
  151776. + IN OPTIONAL gcoSURF SrcSurface,
  151777. + IN gcoSURF DestSurface,
  151778. + IN gctUINT32 RectCount,
  151779. + IN OPTIONAL gcsRECT_PTR SrcRect,
  151780. + IN gcsRECT_PTR DestRect,
  151781. + IN OPTIONAL gcoBRUSH Brush,
  151782. + IN gctUINT8 FgRop,
  151783. + IN gctUINT8 BgRop,
  151784. + IN OPTIONAL gceSURF_TRANSPARENCY Transparency,
  151785. + IN OPTIONAL gctUINT32 TransparencyColor,
  151786. + IN OPTIONAL gctPOINTER Mask,
  151787. + IN OPTIONAL gceSURF_MONOPACK MaskPack
  151788. + );
  151789. +
  151790. +/* Monochrome blit. */
  151791. +gceSTATUS
  151792. +gcoSURF_MonoBlit(
  151793. + IN gcoSURF DestSurface,
  151794. + IN gctPOINTER Source,
  151795. + IN gceSURF_MONOPACK SourcePack,
  151796. + IN gcsPOINT_PTR SourceSize,
  151797. + IN gcsPOINT_PTR SourceOrigin,
  151798. + IN gcsRECT_PTR DestRect,
  151799. + IN OPTIONAL gcoBRUSH Brush,
  151800. + IN gctUINT8 FgRop,
  151801. + IN gctUINT8 BgRop,
  151802. + IN gctBOOL ColorConvert,
  151803. + IN gctUINT8 MonoTransparency,
  151804. + IN gceSURF_TRANSPARENCY Transparency,
  151805. + IN gctUINT32 FgColor,
  151806. + IN gctUINT32 BgColor
  151807. + );
  151808. +
  151809. +/* Filter blit. */
  151810. +gceSTATUS
  151811. +gcoSURF_FilterBlit(
  151812. + IN gcoSURF SrcSurface,
  151813. + IN gcoSURF DestSurface,
  151814. + IN gcsRECT_PTR SrcRect,
  151815. + IN gcsRECT_PTR DestRect,
  151816. + IN gcsRECT_PTR DestSubRect
  151817. + );
  151818. +
  151819. +/* Enable alpha blending engine in the hardware and disengage the ROP engine. */
  151820. +gceSTATUS
  151821. +gcoSURF_EnableAlphaBlend(
  151822. + IN gcoSURF Surface,
  151823. + IN gctUINT8 SrcGlobalAlphaValue,
  151824. + IN gctUINT8 DstGlobalAlphaValue,
  151825. + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
  151826. + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
  151827. + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
  151828. + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
  151829. + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
  151830. + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
  151831. + IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
  151832. + IN gceSURF_PIXEL_COLOR_MODE DstColorMode
  151833. + );
  151834. +
  151835. +/* Disable alpha blending engine in the hardware and engage the ROP engine. */
  151836. +gceSTATUS
  151837. +gcoSURF_DisableAlphaBlend(
  151838. + IN gcoSURF Surface
  151839. + );
  151840. +
  151841. +/* Copy a rectangular area with format conversion. */
  151842. +gceSTATUS
  151843. +gcoSURF_CopyPixels(
  151844. + IN gcoSURF Source,
  151845. + IN gcoSURF Target,
  151846. + IN gctINT SourceX,
  151847. + IN gctINT SourceY,
  151848. + IN gctINT TargetX,
  151849. + IN gctINT TargetY,
  151850. + IN gctINT Width,
  151851. + IN gctINT Height
  151852. + );
  151853. +
  151854. +/* Read surface pixel. */
  151855. +gceSTATUS
  151856. +gcoSURF_ReadPixel(
  151857. + IN gcoSURF Surface,
  151858. + IN gctPOINTER Memory,
  151859. + IN gctINT X,
  151860. + IN gctINT Y,
  151861. + IN gceSURF_FORMAT Format,
  151862. + OUT gctPOINTER PixelValue
  151863. + );
  151864. +
  151865. +/* Write surface pixel. */
  151866. +gceSTATUS
  151867. +gcoSURF_WritePixel(
  151868. + IN gcoSURF Surface,
  151869. + IN gctPOINTER Memory,
  151870. + IN gctINT X,
  151871. + IN gctINT Y,
  151872. + IN gceSURF_FORMAT Format,
  151873. + IN gctPOINTER PixelValue
  151874. + );
  151875. +
  151876. +gceSTATUS
  151877. +gcoSURF_SetDither(
  151878. + IN gcoSURF Surface,
  151879. + IN gctBOOL Dither
  151880. + );
  151881. +/******************************************************************************\
  151882. +********************************** gco2D Object *********************************
  151883. +\******************************************************************************/
  151884. +
  151885. +/* Construct a new gco2D object. */
  151886. +gceSTATUS
  151887. +gco2D_Construct(
  151888. + IN gcoHAL Hal,
  151889. + OUT gco2D * Hardware
  151890. + );
  151891. +
  151892. +/* Destroy an gco2D object. */
  151893. +gceSTATUS
  151894. +gco2D_Destroy(
  151895. + IN gco2D Hardware
  151896. + );
  151897. +
  151898. +/* Sets the maximum number of brushes in the brush cache. */
  151899. +gceSTATUS
  151900. +gco2D_SetBrushLimit(
  151901. + IN gco2D Hardware,
  151902. + IN gctUINT MaxCount
  151903. + );
  151904. +
  151905. +/* Flush the brush. */
  151906. +gceSTATUS
  151907. +gco2D_FlushBrush(
  151908. + IN gco2D Engine,
  151909. + IN gcoBRUSH Brush,
  151910. + IN gceSURF_FORMAT Format
  151911. + );
  151912. +
  151913. +/* Program the specified solid color brush. */
  151914. +gceSTATUS
  151915. +gco2D_LoadSolidBrush(
  151916. + IN gco2D Engine,
  151917. + IN gceSURF_FORMAT Format,
  151918. + IN gctUINT32 ColorConvert,
  151919. + IN gctUINT32 Color,
  151920. + IN gctUINT64 Mask
  151921. + );
  151922. +
  151923. +gceSTATUS
  151924. +gco2D_LoadMonochromeBrush(
  151925. + IN gco2D Engine,
  151926. + IN gctUINT32 OriginX,
  151927. + IN gctUINT32 OriginY,
  151928. + IN gctUINT32 ColorConvert,
  151929. + IN gctUINT32 FgColor,
  151930. + IN gctUINT32 BgColor,
  151931. + IN gctUINT64 Bits,
  151932. + IN gctUINT64 Mask
  151933. + );
  151934. +
  151935. +gceSTATUS
  151936. +gco2D_LoadColorBrush(
  151937. + IN gco2D Engine,
  151938. + IN gctUINT32 OriginX,
  151939. + IN gctUINT32 OriginY,
  151940. + IN gctUINT32 Address,
  151941. + IN gceSURF_FORMAT Format,
  151942. + IN gctUINT64 Mask
  151943. + );
  151944. +
  151945. +/* Configure monochrome source. */
  151946. +gceSTATUS
  151947. +gco2D_SetMonochromeSource(
  151948. + IN gco2D Engine,
  151949. + IN gctBOOL ColorConvert,
  151950. + IN gctUINT8 MonoTransparency,
  151951. + IN gceSURF_MONOPACK DataPack,
  151952. + IN gctBOOL CoordRelative,
  151953. + IN gceSURF_TRANSPARENCY Transparency,
  151954. + IN gctUINT32 FgColor,
  151955. + IN gctUINT32 BgColor
  151956. + );
  151957. +
  151958. +/* Configure color source. */
  151959. +gceSTATUS
  151960. +gco2D_SetColorSource(
  151961. + IN gco2D Engine,
  151962. + IN gctUINT32 Address,
  151963. + IN gctUINT32 Stride,
  151964. + IN gceSURF_FORMAT Format,
  151965. + IN gceSURF_ROTATION Rotation,
  151966. + IN gctUINT32 SurfaceWidth,
  151967. + IN gctBOOL CoordRelative,
  151968. + IN gceSURF_TRANSPARENCY Transparency,
  151969. + IN gctUINT32 TransparencyColor
  151970. + );
  151971. +
  151972. +/* Configure color source extension for full rotation. */
  151973. +gceSTATUS
  151974. +gco2D_SetColorSourceEx(
  151975. + IN gco2D Engine,
  151976. + IN gctUINT32 Address,
  151977. + IN gctUINT32 Stride,
  151978. + IN gceSURF_FORMAT Format,
  151979. + IN gceSURF_ROTATION Rotation,
  151980. + IN gctUINT32 SurfaceWidth,
  151981. + IN gctUINT32 SurfaceHeight,
  151982. + IN gctBOOL CoordRelative,
  151983. + IN gceSURF_TRANSPARENCY Transparency,
  151984. + IN gctUINT32 TransparencyColor
  151985. + );
  151986. +
  151987. +/* Configure color source. */
  151988. +gceSTATUS
  151989. +gco2D_SetColorSourceAdvanced(
  151990. + IN gco2D Engine,
  151991. + IN gctUINT32 Address,
  151992. + IN gctUINT32 Stride,
  151993. + IN gceSURF_FORMAT Format,
  151994. + IN gceSURF_ROTATION Rotation,
  151995. + IN gctUINT32 SurfaceWidth,
  151996. + IN gctUINT32 SurfaceHeight,
  151997. + IN gctBOOL CoordRelative
  151998. + );
  151999. +
  152000. +gceSTATUS
  152001. +gco2D_SetColorSourceN(
  152002. + IN gco2D Engine,
  152003. + IN gctUINT32 Address,
  152004. + IN gctUINT32 Stride,
  152005. + IN gceSURF_FORMAT Format,
  152006. + IN gceSURF_ROTATION Rotation,
  152007. + IN gctUINT32 SurfaceWidth,
  152008. + IN gctUINT32 SurfaceHeight,
  152009. + IN gctUINT32 SurfaceNumber
  152010. + );
  152011. +
  152012. +/* Configure masked color source. */
  152013. +gceSTATUS
  152014. +gco2D_SetMaskedSource(
  152015. + IN gco2D Engine,
  152016. + IN gctUINT32 Address,
  152017. + IN gctUINT32 Stride,
  152018. + IN gceSURF_FORMAT Format,
  152019. + IN gctBOOL CoordRelative,
  152020. + IN gceSURF_MONOPACK MaskPack
  152021. + );
  152022. +
  152023. +/* Configure masked color source extension for full rotation. */
  152024. +gceSTATUS
  152025. +gco2D_SetMaskedSourceEx(
  152026. + IN gco2D Engine,
  152027. + IN gctUINT32 Address,
  152028. + IN gctUINT32 Stride,
  152029. + IN gceSURF_FORMAT Format,
  152030. + IN gctBOOL CoordRelative,
  152031. + IN gceSURF_MONOPACK MaskPack,
  152032. + IN gceSURF_ROTATION Rotation,
  152033. + IN gctUINT32 SurfaceWidth,
  152034. + IN gctUINT32 SurfaceHeight
  152035. + );
  152036. +
  152037. +/* Setup the source rectangle. */
  152038. +gceSTATUS
  152039. +gco2D_SetSource(
  152040. + IN gco2D Engine,
  152041. + IN gcsRECT_PTR SrcRect
  152042. + );
  152043. +
  152044. +/* Set clipping rectangle. */
  152045. +gceSTATUS
  152046. +gco2D_SetClipping(
  152047. + IN gco2D Engine,
  152048. + IN gcsRECT_PTR Rect
  152049. + );
  152050. +
  152051. +/* Configure destination. */
  152052. +gceSTATUS
  152053. +gco2D_SetTarget(
  152054. + IN gco2D Engine,
  152055. + IN gctUINT32 Address,
  152056. + IN gctUINT32 Stride,
  152057. + IN gceSURF_ROTATION Rotation,
  152058. + IN gctUINT32 SurfaceWidth
  152059. + );
  152060. +
  152061. +/* Configure destination extension for full rotation. */
  152062. +gceSTATUS
  152063. +gco2D_SetTargetEx(
  152064. + IN gco2D Engine,
  152065. + IN gctUINT32 Address,
  152066. + IN gctUINT32 Stride,
  152067. + IN gceSURF_ROTATION Rotation,
  152068. + IN gctUINT32 SurfaceWidth,
  152069. + IN gctUINT32 SurfaceHeight
  152070. + );
  152071. +
  152072. +/* Calculate and program the stretch factors. */
  152073. +gceSTATUS
  152074. +gco2D_CalcStretchFactor(
  152075. + IN gco2D Engine,
  152076. + IN gctINT32 SrcSize,
  152077. + IN gctINT32 DestSize,
  152078. + OUT gctUINT32_PTR Factor
  152079. + );
  152080. +
  152081. +gceSTATUS
  152082. +gco2D_SetStretchFactors(
  152083. + IN gco2D Engine,
  152084. + IN gctUINT32 HorFactor,
  152085. + IN gctUINT32 VerFactor
  152086. + );
  152087. +
  152088. +/* Calculate and program the stretch factors based on the rectangles. */
  152089. +gceSTATUS
  152090. +gco2D_SetStretchRectFactors(
  152091. + IN gco2D Engine,
  152092. + IN gcsRECT_PTR SrcRect,
  152093. + IN gcsRECT_PTR DestRect
  152094. + );
  152095. +
  152096. +/* Create a new solid color gcoBRUSH object. */
  152097. +gceSTATUS
  152098. +gco2D_ConstructSingleColorBrush(
  152099. + IN gco2D Engine,
  152100. + IN gctUINT32 ColorConvert,
  152101. + IN gctUINT32 Color,
  152102. + IN gctUINT64 Mask,
  152103. + gcoBRUSH * Brush
  152104. + );
  152105. +
  152106. +/* Create a new monochrome gcoBRUSH object. */
  152107. +gceSTATUS
  152108. +gco2D_ConstructMonochromeBrush(
  152109. + IN gco2D Engine,
  152110. + IN gctUINT32 OriginX,
  152111. + IN gctUINT32 OriginY,
  152112. + IN gctUINT32 ColorConvert,
  152113. + IN gctUINT32 FgColor,
  152114. + IN gctUINT32 BgColor,
  152115. + IN gctUINT64 Bits,
  152116. + IN gctUINT64 Mask,
  152117. + gcoBRUSH * Brush
  152118. + );
  152119. +
  152120. +/* Create a color gcoBRUSH object. */
  152121. +gceSTATUS
  152122. +gco2D_ConstructColorBrush(
  152123. + IN gco2D Engine,
  152124. + IN gctUINT32 OriginX,
  152125. + IN gctUINT32 OriginY,
  152126. + IN gctPOINTER Address,
  152127. + IN gceSURF_FORMAT Format,
  152128. + IN gctUINT64 Mask,
  152129. + gcoBRUSH * Brush
  152130. + );
  152131. +
  152132. +/* Clear one or more rectangular areas. */
  152133. +gceSTATUS
  152134. +gco2D_Clear(
  152135. + IN gco2D Engine,
  152136. + IN gctUINT32 RectCount,
  152137. + IN gcsRECT_PTR Rect,
  152138. + IN gctUINT32 Color32,
  152139. + IN gctUINT8 FgRop,
  152140. + IN gctUINT8 BgRop,
  152141. + IN gceSURF_FORMAT DestFormat
  152142. + );
  152143. +
  152144. +/* Draw one or more Bresenham lines. */
  152145. +gceSTATUS
  152146. +gco2D_Line(
  152147. + IN gco2D Engine,
  152148. + IN gctUINT32 LineCount,
  152149. + IN gcsRECT_PTR Position,
  152150. + IN gcoBRUSH Brush,
  152151. + IN gctUINT8 FgRop,
  152152. + IN gctUINT8 BgRop,
  152153. + IN gceSURF_FORMAT DestFormat
  152154. + );
  152155. +
  152156. +/* Draw one or more Bresenham lines based on the 32-bit color. */
  152157. +gceSTATUS
  152158. +gco2D_ColorLine(
  152159. + IN gco2D Engine,
  152160. + IN gctUINT32 LineCount,
  152161. + IN gcsRECT_PTR Position,
  152162. + IN gctUINT32 Color32,
  152163. + IN gctUINT8 FgRop,
  152164. + IN gctUINT8 BgRop,
  152165. + IN gceSURF_FORMAT DestFormat
  152166. + );
  152167. +
  152168. +/* Generic blit. */
  152169. +gceSTATUS
  152170. +gco2D_Blit(
  152171. + IN gco2D Engine,
  152172. + IN gctUINT32 RectCount,
  152173. + IN gcsRECT_PTR Rect,
  152174. + IN gctUINT8 FgRop,
  152175. + IN gctUINT8 BgRop,
  152176. + IN gceSURF_FORMAT DestFormat
  152177. + );
  152178. +
  152179. +gceSTATUS
  152180. +gco2D_Blend(
  152181. + IN gco2D Engine,
  152182. + IN gctUINT32 SrcCount,
  152183. + IN gctUINT32 RectCount,
  152184. + IN gcsRECT_PTR Rect,
  152185. + IN gctUINT8 FgRop,
  152186. + IN gctUINT8 BgRop,
  152187. + IN gceSURF_FORMAT DestFormat
  152188. + );
  152189. +
  152190. +/* Batch blit. */
  152191. +gceSTATUS
  152192. +gco2D_BatchBlit(
  152193. + IN gco2D Engine,
  152194. + IN gctUINT32 RectCount,
  152195. + IN gcsRECT_PTR SrcRect,
  152196. + IN gcsRECT_PTR DestRect,
  152197. + IN gctUINT8 FgRop,
  152198. + IN gctUINT8 BgRop,
  152199. + IN gceSURF_FORMAT DestFormat
  152200. + );
  152201. +
  152202. +/* Stretch blit. */
  152203. +gceSTATUS
  152204. +gco2D_StretchBlit(
  152205. + IN gco2D Engine,
  152206. + IN gctUINT32 RectCount,
  152207. + IN gcsRECT_PTR Rect,
  152208. + IN gctUINT8 FgRop,
  152209. + IN gctUINT8 BgRop,
  152210. + IN gceSURF_FORMAT DestFormat
  152211. + );
  152212. +
  152213. +/* Monochrome blit. */
  152214. +gceSTATUS
  152215. +gco2D_MonoBlit(
  152216. + IN gco2D Engine,
  152217. + IN gctPOINTER StreamBits,
  152218. + IN gcsPOINT_PTR StreamSize,
  152219. + IN gcsRECT_PTR StreamRect,
  152220. + IN gceSURF_MONOPACK SrcStreamPack,
  152221. + IN gceSURF_MONOPACK DestStreamPack,
  152222. + IN gcsRECT_PTR DestRect,
  152223. + IN gctUINT32 FgRop,
  152224. + IN gctUINT32 BgRop,
  152225. + IN gceSURF_FORMAT DestFormat
  152226. + );
  152227. +
  152228. +gceSTATUS
  152229. +gco2D_MonoBlitEx(
  152230. + IN gco2D Engine,
  152231. + IN gctPOINTER StreamBits,
  152232. + IN gctINT32 StreamStride,
  152233. + IN gctINT32 StreamWidth,
  152234. + IN gctINT32 StreamHeight,
  152235. + IN gctINT32 StreamX,
  152236. + IN gctINT32 StreamY,
  152237. + IN gctUINT32 FgColor,
  152238. + IN gctUINT32 BgColor,
  152239. + IN gcsRECT_PTR SrcRect,
  152240. + IN gcsRECT_PTR DstRect,
  152241. + IN gctUINT8 FgRop,
  152242. + IN gctUINT8 BgRop
  152243. + );
  152244. +
  152245. +/* Set kernel size. */
  152246. +gceSTATUS
  152247. +gco2D_SetKernelSize(
  152248. + IN gco2D Engine,
  152249. + IN gctUINT8 HorKernelSize,
  152250. + IN gctUINT8 VerKernelSize
  152251. + );
  152252. +
  152253. +/* Set filter type. */
  152254. +gceSTATUS
  152255. +gco2D_SetFilterType(
  152256. + IN gco2D Engine,
  152257. + IN gceFILTER_TYPE FilterType
  152258. + );
  152259. +
  152260. +/* Set the filter kernel by user. */
  152261. +gceSTATUS
  152262. +gco2D_SetUserFilterKernel(
  152263. + IN gco2D Engine,
  152264. + IN gceFILTER_PASS_TYPE PassType,
  152265. + IN gctUINT16_PTR KernelArray
  152266. + );
  152267. +
  152268. +/* Select the pass(es) to be done for user defined filter. */
  152269. +gceSTATUS
  152270. +gco2D_EnableUserFilterPasses(
  152271. + IN gco2D Engine,
  152272. + IN gctBOOL HorPass,
  152273. + IN gctBOOL VerPass
  152274. + );
  152275. +
  152276. +/* Frees the temporary buffer allocated by filter blit operation. */
  152277. +gceSTATUS
  152278. +gco2D_FreeFilterBuffer(
  152279. + IN gco2D Engine
  152280. + );
  152281. +
  152282. +/* Filter blit. */
  152283. +gceSTATUS
  152284. +gco2D_FilterBlit(
  152285. + IN gco2D Engine,
  152286. + IN gctUINT32 SrcAddress,
  152287. + IN gctUINT SrcStride,
  152288. + IN gctUINT32 SrcUAddress,
  152289. + IN gctUINT SrcUStride,
  152290. + IN gctUINT32 SrcVAddress,
  152291. + IN gctUINT SrcVStride,
  152292. + IN gceSURF_FORMAT SrcFormat,
  152293. + IN gceSURF_ROTATION SrcRotation,
  152294. + IN gctUINT32 SrcSurfaceWidth,
  152295. + IN gcsRECT_PTR SrcRect,
  152296. + IN gctUINT32 DestAddress,
  152297. + IN gctUINT DestStride,
  152298. + IN gceSURF_FORMAT DestFormat,
  152299. + IN gceSURF_ROTATION DestRotation,
  152300. + IN gctUINT32 DestSurfaceWidth,
  152301. + IN gcsRECT_PTR DestRect,
  152302. + IN gcsRECT_PTR DestSubRect
  152303. + );
  152304. +
  152305. +/* Filter blit extension for full rotation. */
  152306. +gceSTATUS
  152307. +gco2D_FilterBlitEx(
  152308. + IN gco2D Engine,
  152309. + IN gctUINT32 SrcAddress,
  152310. + IN gctUINT SrcStride,
  152311. + IN gctUINT32 SrcUAddress,
  152312. + IN gctUINT SrcUStride,
  152313. + IN gctUINT32 SrcVAddress,
  152314. + IN gctUINT SrcVStride,
  152315. + IN gceSURF_FORMAT SrcFormat,
  152316. + IN gceSURF_ROTATION SrcRotation,
  152317. + IN gctUINT32 SrcSurfaceWidth,
  152318. + IN gctUINT32 SrcSurfaceHeight,
  152319. + IN gcsRECT_PTR SrcRect,
  152320. + IN gctUINT32 DestAddress,
  152321. + IN gctUINT DestStride,
  152322. + IN gceSURF_FORMAT DestFormat,
  152323. + IN gceSURF_ROTATION DestRotation,
  152324. + IN gctUINT32 DestSurfaceWidth,
  152325. + IN gctUINT32 DestSurfaceHeight,
  152326. + IN gcsRECT_PTR DestRect,
  152327. + IN gcsRECT_PTR DestSubRect
  152328. + );
  152329. +
  152330. +gceSTATUS
  152331. +gco2D_FilterBlitEx2(
  152332. + IN gco2D Engine,
  152333. + IN gctUINT32_PTR SrcAddresses,
  152334. + IN gctUINT32 SrcAddressNum,
  152335. + IN gctUINT32_PTR SrcStrides,
  152336. + IN gctUINT32 SrcStrideNum,
  152337. + IN gceTILING SrcTiling,
  152338. + IN gceSURF_FORMAT SrcFormat,
  152339. + IN gceSURF_ROTATION SrcRotation,
  152340. + IN gctUINT32 SrcSurfaceWidth,
  152341. + IN gctUINT32 SrcSurfaceHeight,
  152342. + IN gcsRECT_PTR SrcRect,
  152343. + IN gctUINT32_PTR DestAddresses,
  152344. + IN gctUINT32 DestAddressNum,
  152345. + IN gctUINT32_PTR DestStrides,
  152346. + IN gctUINT32 DestStrideNum,
  152347. + IN gceTILING DestTiling,
  152348. + IN gceSURF_FORMAT DestFormat,
  152349. + IN gceSURF_ROTATION DestRotation,
  152350. + IN gctUINT32 DestSurfaceWidth,
  152351. + IN gctUINT32 DestSurfaceHeight,
  152352. + IN gcsRECT_PTR DestRect,
  152353. + IN gcsRECT_PTR DestSubRect
  152354. + );
  152355. +
  152356. +/* Enable alpha blending engine in the hardware and disengage the ROP engine. */
  152357. +gceSTATUS
  152358. +gco2D_EnableAlphaBlend(
  152359. + IN gco2D Engine,
  152360. + IN gctUINT8 SrcGlobalAlphaValue,
  152361. + IN gctUINT8 DstGlobalAlphaValue,
  152362. + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
  152363. + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
  152364. + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
  152365. + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
  152366. + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
  152367. + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
  152368. + IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
  152369. + IN gceSURF_PIXEL_COLOR_MODE DstColorMode
  152370. + );
  152371. +
  152372. +/* Enable alpha blending engine in the hardware. */
  152373. +gceSTATUS
  152374. +gco2D_EnableAlphaBlendAdvanced(
  152375. + IN gco2D Engine,
  152376. + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
  152377. + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
  152378. + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
  152379. + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
  152380. + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
  152381. + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode
  152382. + );
  152383. +
  152384. +/* Enable alpha blending engine with Porter Duff rule. */
  152385. +gceSTATUS
  152386. +gco2D_SetPorterDuffBlending(
  152387. + IN gco2D Engine,
  152388. + IN gce2D_PORTER_DUFF_RULE Rule
  152389. + );
  152390. +
  152391. +/* Disable alpha blending engine in the hardware and engage the ROP engine. */
  152392. +gceSTATUS
  152393. +gco2D_DisableAlphaBlend(
  152394. + IN gco2D Engine
  152395. + );
  152396. +
  152397. +/* Retrieve the maximum number of 32-bit data chunks for a single DE command. */
  152398. +gctUINT32
  152399. +gco2D_GetMaximumDataCount(
  152400. + void
  152401. + );
  152402. +
  152403. +/* Retrieve the maximum number of rectangles, that can be passed in a single DE command. */
  152404. +gctUINT32
  152405. +gco2D_GetMaximumRectCount(
  152406. + void
  152407. + );
  152408. +
  152409. +/* Returns the pixel alignment of the surface. */
  152410. +gceSTATUS
  152411. +gco2D_GetPixelAlignment(
  152412. + gceSURF_FORMAT Format,
  152413. + gcsPOINT_PTR Alignment
  152414. + );
  152415. +
  152416. +/* Retrieve monochrome stream pack size. */
  152417. +gceSTATUS
  152418. +gco2D_GetPackSize(
  152419. + IN gceSURF_MONOPACK StreamPack,
  152420. + OUT gctUINT32 * PackWidth,
  152421. + OUT gctUINT32 * PackHeight
  152422. + );
  152423. +
  152424. +/* Flush the 2D pipeline. */
  152425. +gceSTATUS
  152426. +gco2D_Flush(
  152427. + IN gco2D Engine
  152428. + );
  152429. +
  152430. +/* Load 256-entry color table for INDEX8 source surfaces. */
  152431. +gceSTATUS
  152432. +gco2D_LoadPalette(
  152433. + IN gco2D Engine,
  152434. + IN gctUINT FirstIndex,
  152435. + IN gctUINT IndexCount,
  152436. + IN gctPOINTER ColorTable,
  152437. + IN gctBOOL ColorConvert
  152438. + );
  152439. +
  152440. +/* Enable/disable 2D BitBlt mirrorring. */
  152441. +gceSTATUS
  152442. +gco2D_SetBitBlitMirror(
  152443. + IN gco2D Engine,
  152444. + IN gctBOOL HorizontalMirror,
  152445. + IN gctBOOL VerticalMirror
  152446. + );
  152447. +
  152448. +/*
  152449. + * Set the transparency for source, destination and pattern.
  152450. + * It also enable or disable the DFB color key mode.
  152451. + */
  152452. +gceSTATUS
  152453. +gco2D_SetTransparencyAdvancedEx(
  152454. + IN gco2D Engine,
  152455. + IN gce2D_TRANSPARENCY SrcTransparency,
  152456. + IN gce2D_TRANSPARENCY DstTransparency,
  152457. + IN gce2D_TRANSPARENCY PatTransparency,
  152458. + IN gctBOOL EnableDFBColorKeyMode
  152459. + );
  152460. +
  152461. +/* Set the transparency for source, destination and pattern. */
  152462. +gceSTATUS
  152463. +gco2D_SetTransparencyAdvanced(
  152464. + IN gco2D Engine,
  152465. + IN gce2D_TRANSPARENCY SrcTransparency,
  152466. + IN gce2D_TRANSPARENCY DstTransparency,
  152467. + IN gce2D_TRANSPARENCY PatTransparency
  152468. + );
  152469. +
  152470. +/* Set the source color key. */
  152471. +gceSTATUS
  152472. +gco2D_SetSourceColorKeyAdvanced(
  152473. + IN gco2D Engine,
  152474. + IN gctUINT32 ColorKey
  152475. + );
  152476. +
  152477. +/* Set the source color key range. */
  152478. +gceSTATUS
  152479. +gco2D_SetSourceColorKeyRangeAdvanced(
  152480. + IN gco2D Engine,
  152481. + IN gctUINT32 ColorKeyLow,
  152482. + IN gctUINT32 ColorKeyHigh
  152483. + );
  152484. +
  152485. +/* Set the target color key. */
  152486. +gceSTATUS
  152487. +gco2D_SetTargetColorKeyAdvanced(
  152488. + IN gco2D Engine,
  152489. + IN gctUINT32 ColorKey
  152490. + );
  152491. +
  152492. +/* Set the target color key range. */
  152493. +gceSTATUS
  152494. +gco2D_SetTargetColorKeyRangeAdvanced(
  152495. + IN gco2D Engine,
  152496. + IN gctUINT32 ColorKeyLow,
  152497. + IN gctUINT32 ColorKeyHigh
  152498. + );
  152499. +
  152500. +/* Set the YUV color space mode. */
  152501. +gceSTATUS
  152502. +gco2D_SetYUVColorMode(
  152503. + IN gco2D Engine,
  152504. + IN gce2D_YUV_COLOR_MODE Mode
  152505. + );
  152506. +
  152507. +/* Setup the source global color value in ARGB8 format. */
  152508. +gceSTATUS gco2D_SetSourceGlobalColorAdvanced(
  152509. + IN gco2D Engine,
  152510. + IN gctUINT32 Color32
  152511. + );
  152512. +
  152513. +/* Setup the target global color value in ARGB8 format. */
  152514. +gceSTATUS gco2D_SetTargetGlobalColorAdvanced(
  152515. + IN gco2D Engine,
  152516. + IN gctUINT32 Color32
  152517. + );
  152518. +
  152519. +/* Setup the source and target pixel multiply modes. */
  152520. +gceSTATUS
  152521. +gco2D_SetPixelMultiplyModeAdvanced(
  152522. + IN gco2D Engine,
  152523. + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE SrcPremultiplySrcAlpha,
  152524. + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstPremultiplyDstAlpha,
  152525. + IN gce2D_GLOBAL_COLOR_MULTIPLY_MODE SrcPremultiplyGlobalMode,
  152526. + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstDemultiplyDstAlpha
  152527. + );
  152528. +
  152529. +/* Set the GPU clock cycles after which the idle engine will keep auto-flushing. */
  152530. +gceSTATUS
  152531. +gco2D_SetAutoFlushCycles(
  152532. + IN gco2D Engine,
  152533. + IN gctUINT32 Cycles
  152534. + );
  152535. +
  152536. +#if VIVANTE_PROFILER
  152537. +/* Read the profile registers available in the 2D engine and sets them in the profile.
  152538. + The function will also reset the pixelsRendered counter every time.
  152539. +*/
  152540. +gceSTATUS
  152541. +gco2D_ProfileEngine(
  152542. + IN gco2D Engine,
  152543. + OPTIONAL gcs2D_PROFILE_PTR Profile
  152544. + );
  152545. +#endif
  152546. +
  152547. +/* Enable or disable 2D dithering. */
  152548. +gceSTATUS
  152549. +gco2D_EnableDither(
  152550. + IN gco2D Engine,
  152551. + IN gctBOOL Enable
  152552. + );
  152553. +
  152554. +gceSTATUS
  152555. +gco2D_SetGenericSource(
  152556. + IN gco2D Engine,
  152557. + IN gctUINT32_PTR Addresses,
  152558. + IN gctUINT32 AddressNum,
  152559. + IN gctUINT32_PTR Strides,
  152560. + IN gctUINT32 StrideNum,
  152561. + IN gceTILING Tiling,
  152562. + IN gceSURF_FORMAT Format,
  152563. + IN gceSURF_ROTATION Rotation,
  152564. + IN gctUINT32 SurfaceWidth,
  152565. + IN gctUINT32 SurfaceHeight
  152566. +);
  152567. +
  152568. +gceSTATUS
  152569. +gco2D_SetGenericTarget(
  152570. + IN gco2D Engine,
  152571. + IN gctUINT32_PTR Addresses,
  152572. + IN gctUINT32 AddressNum,
  152573. + IN gctUINT32_PTR Strides,
  152574. + IN gctUINT32 StrideNum,
  152575. + IN gceTILING Tiling,
  152576. + IN gceSURF_FORMAT Format,
  152577. + IN gceSURF_ROTATION Rotation,
  152578. + IN gctUINT32 SurfaceWidth,
  152579. + IN gctUINT32 SurfaceHeight
  152580. +);
  152581. +
  152582. +gceSTATUS
  152583. +gco2D_SetCurrentSourceIndex(
  152584. + IN gco2D Engine,
  152585. + IN gctUINT32 SrcIndex
  152586. + );
  152587. +
  152588. +gceSTATUS
  152589. +gco2D_MultiSourceBlit(
  152590. + IN gco2D Engine,
  152591. + IN gctUINT32 SourceMask,
  152592. + IN gcsRECT_PTR DestRect,
  152593. + IN gctUINT32 RectCount
  152594. + );
  152595. +
  152596. +gceSTATUS
  152597. +gco2D_SetROP(
  152598. + IN gco2D Engine,
  152599. + IN gctUINT8 FgRop,
  152600. + IN gctUINT8 BgRop
  152601. + );
  152602. +
  152603. +gceSTATUS
  152604. +gco2D_SetGdiStretchMode(
  152605. + IN gco2D Engine,
  152606. + IN gctBOOL Enable
  152607. + );
  152608. +
  152609. +gceSTATUS
  152610. +gco2D_SetSourceTileStatus(
  152611. + IN gco2D Engine,
  152612. + IN gce2D_TILE_STATUS_CONFIG TSControl,
  152613. + IN gceSURF_FORMAT CompressedFormat,
  152614. + IN gctUINT32 ClearValue,
  152615. + IN gctUINT32 GpuAddress
  152616. + );
  152617. +
  152618. +gceSTATUS
  152619. +gco2D_SetTargetTileStatus(
  152620. + IN gco2D Engine,
  152621. + IN gce2D_TILE_STATUS_CONFIG TileStatusConfig,
  152622. + IN gceSURF_FORMAT CompressedFormat,
  152623. + IN gctUINT32 ClearValue,
  152624. + IN gctUINT32 GpuAddress
  152625. + );
  152626. +
  152627. +gceSTATUS
  152628. +gco2D_QueryU32(
  152629. + IN gco2D Engine,
  152630. + IN gce2D_QUERY Item,
  152631. + OUT gctUINT32_PTR Value
  152632. + );
  152633. +
  152634. +gceSTATUS
  152635. +gco2D_SetStateU32(
  152636. + IN gco2D Engine,
  152637. + IN gce2D_STATE State,
  152638. + IN gctUINT32 Value
  152639. + );
  152640. +
  152641. +gceSTATUS
  152642. +gco2D_SetStateArrayI32(
  152643. + IN gco2D Engine,
  152644. + IN gce2D_STATE State,
  152645. + IN gctINT32_PTR Array,
  152646. + IN gctINT32 ArraySize
  152647. + );
  152648. +
  152649. +gceSTATUS
  152650. +gco2D_SetStateArrayU32(
  152651. + IN gco2D Engine,
  152652. + IN gce2D_STATE State,
  152653. + IN gctUINT32_PTR Array,
  152654. + IN gctINT32 ArraySize
  152655. + );
  152656. +
  152657. +gceSTATUS
  152658. +gco2D_SetTargetRect(
  152659. + IN gco2D Engine,
  152660. + IN gcsRECT_PTR Rect
  152661. + );
  152662. +
  152663. +#ifdef __cplusplus
  152664. +}
  152665. +#endif
  152666. +
  152667. +#endif /* __gc_hal_raster_h_ */
  152668. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h
  152669. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h 1969-12-31 18:00:00.000000000 -0600
  152670. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h 2014-12-08 00:31:53.472418001 -0600
  152671. @@ -0,0 +1,248 @@
  152672. +/****************************************************************************
  152673. +*
  152674. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  152675. +*
  152676. +* This program is free software; you can redistribute it and/or modify
  152677. +* it under the terms of the GNU General Public License as published by
  152678. +* the Free Software Foundation; either version 2 of the license, or
  152679. +* (at your option) any later version.
  152680. +*
  152681. +* This program is distributed in the hope that it will be useful,
  152682. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  152683. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  152684. +* GNU General Public License for more details.
  152685. +*
  152686. +* You should have received a copy of the GNU General Public License
  152687. +* along with this program; if not write to the Free Software
  152688. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  152689. +*
  152690. +*****************************************************************************/
  152691. +
  152692. +
  152693. +#ifndef __gc_hal_rename_h_
  152694. +#define __gc_hal_rename_h_
  152695. +
  152696. +
  152697. +#if defined(_HAL2D_APPENDIX)
  152698. +
  152699. +#define _HAL2D_RENAME_2(api, appendix) api ## appendix
  152700. +#define _HAL2D_RENAME_1(api, appendix) _HAL2D_RENAME_2(api, appendix)
  152701. +#define gcmHAL2D(api) _HAL2D_RENAME_1(api, _HAL2D_APPENDIX)
  152702. +
  152703. +
  152704. +#define gckOS_Construct gcmHAL2D(gckOS_Construct)
  152705. +#define gckOS_Destroy gcmHAL2D(gckOS_Destroy)
  152706. +#define gckOS_QueryVideoMemory gcmHAL2D(gckOS_QueryVideoMemory)
  152707. +#define gckOS_Allocate gcmHAL2D(gckOS_Allocate)
  152708. +#define gckOS_Free gcmHAL2D(gckOS_Free)
  152709. +#define gckOS_AllocateMemory gcmHAL2D(gckOS_AllocateMemory)
  152710. +#define gckOS_FreeMemory gcmHAL2D(gckOS_FreeMemory)
  152711. +#define gckOS_AllocatePagedMemory gcmHAL2D(gckOS_AllocatePagedMemory)
  152712. +#define gckOS_AllocatePagedMemoryEx gcmHAL2D(gckOS_AllocatePagedMemoryEx)
  152713. +#define gckOS_LockPages gcmHAL2D(gckOS_LockPages)
  152714. +#define gckOS_MapPages gcmHAL2D(gckOS_MapPages)
  152715. +#define gckOS_UnlockPages gcmHAL2D(gckOS_UnlockPages)
  152716. +#define gckOS_FreePagedMemory gcmHAL2D(gckOS_FreePagedMemory)
  152717. +#define gckOS_AllocateNonPagedMemory gcmHAL2D(gckOS_AllocateNonPagedMemory)
  152718. +#define gckOS_FreeNonPagedMemory gcmHAL2D(gckOS_FreeNonPagedMemory)
  152719. +#define gckOS_AllocateContiguous gcmHAL2D(gckOS_AllocateContiguous)
  152720. +#define gckOS_FreeContiguous gcmHAL2D(gckOS_FreeContiguous)
  152721. +#define gckOS_GetPageSize gcmHAL2D(gckOS_GetPageSize)
  152722. +#define gckOS_GetPhysicalAddress gcmHAL2D(gckOS_GetPhysicalAddress)
  152723. +#define gckOS_GetPhysicalAddressProcess gcmHAL2D(gckOS_GetPhysicalAddressProcess)
  152724. +#define gckOS_MapPhysical gcmHAL2D(gckOS_MapPhysical)
  152725. +#define gckOS_UnmapPhysical gcmHAL2D(gckOS_UnmapPhysical)
  152726. +#define gckOS_ReadRegister gcmHAL2D(gckOS_ReadRegister)
  152727. +#define gckOS_WriteRegister gcmHAL2D(gckOS_WriteRegister)
  152728. +#define gckOS_WriteMemory gcmHAL2D(gckOS_WriteMemory)
  152729. +#define gckOS_MapMemory gcmHAL2D(gckOS_MapMemory)
  152730. +#define gckOS_UnmapMemory gcmHAL2D(gckOS_UnmapMemory)
  152731. +#define gckOS_UnmapMemoryEx gcmHAL2D(gckOS_UnmapMemoryEx)
  152732. +#define gckOS_CreateMutex gcmHAL2D(gckOS_CreateMutex)
  152733. +#define gckOS_DeleteMutex gcmHAL2D(gckOS_DeleteMutex)
  152734. +#define gckOS_AcquireMutex gcmHAL2D(gckOS_AcquireMutex)
  152735. +#define gckOS_ReleaseMutex gcmHAL2D(gckOS_ReleaseMutex)
  152736. +#define gckOS_AtomicExchange gcmHAL2D(gckOS_AtomicExchange)
  152737. +#define gckOS_AtomicExchangePtr gcmHAL2D(gckOS_AtomicExchangePtr)
  152738. +#define gckOS_AtomConstruct gcmHAL2D(gckOS_AtomConstruct)
  152739. +#define gckOS_AtomDestroy gcmHAL2D(gckOS_AtomDestroy)
  152740. +#define gckOS_AtomGet gcmHAL2D(gckOS_AtomGet)
  152741. +#define gckOS_AtomIncrement gcmHAL2D(gckOS_AtomIncrement)
  152742. +#define gckOS_AtomDecrement gcmHAL2D(gckOS_AtomDecrement)
  152743. +#define gckOS_Delay gcmHAL2D(gckOS_Delay)
  152744. +#define gckOS_GetTime gcmHAL2D(gckOS_GetTime)
  152745. +#define gckOS_MemoryBarrier gcmHAL2D(gckOS_MemoryBarrier)
  152746. +#define gckOS_MapUserPointer gcmHAL2D(gckOS_MapUserPointer)
  152747. +#define gckOS_UnmapUserPointer gcmHAL2D(gckOS_UnmapUserPointer)
  152748. +#define gckOS_QueryNeedCopy gcmHAL2D(gckOS_QueryNeedCopy)
  152749. +#define gckOS_CopyFromUserData gcmHAL2D(gckOS_CopyFromUserData)
  152750. +#define gckOS_CopyToUserData gcmHAL2D(gckOS_CopyToUserData)
  152751. +#define gckOS_MapUserPhysical gcmHAL2D(gckOS_MapUserPhysical)
  152752. +#define gckOS_SuspendInterrupt gcmHAL2D(gckOS_SuspendInterrupt)
  152753. +#define gckOS_ResumeInterrupt gcmHAL2D(gckOS_ResumeInterrupt)
  152754. +#define gckOS_GetBaseAddress gcmHAL2D(gckOS_GetBaseAddress)
  152755. +#define gckOS_MemCopy gcmHAL2D(gckOS_MemCopy)
  152756. +#define gckOS_ZeroMemory gcmHAL2D(gckOS_ZeroMemory)
  152757. +#define gckOS_DeviceControl gcmHAL2D(gckOS_DeviceControl)
  152758. +#define gckOS_GetProcessID gcmHAL2D(gckOS_GetProcessID)
  152759. +#define gckOS_GetThreadID gcmHAL2D(gckOS_GetThreadID)
  152760. +#define gckOS_CreateSignal gcmHAL2D(gckOS_CreateSignal)
  152761. +#define gckOS_DestroySignal gcmHAL2D(gckOS_DestroySignal)
  152762. +#define gckOS_Signal gcmHAL2D(gckOS_Signal)
  152763. +#define gckOS_WaitSignal gcmHAL2D(gckOS_WaitSignal)
  152764. +#define gckOS_MapSignal gcmHAL2D(gckOS_MapSignal)
  152765. +#define gckOS_MapUserMemory gcmHAL2D(gckOS_MapUserMemory)
  152766. +#define gckOS_UnmapUserMemory gcmHAL2D(gckOS_UnmapUserMemory)
  152767. +#define gckOS_CreateUserSignal gcmHAL2D(gckOS_CreateUserSignal)
  152768. +#define gckOS_DestroyUserSignal gcmHAL2D(gckOS_DestroyUserSignal)
  152769. +#define gckOS_WaitUserSignal gcmHAL2D(gckOS_WaitUserSignal)
  152770. +#define gckOS_SignalUserSignal gcmHAL2D(gckOS_SignalUserSignal)
  152771. +#define gckOS_UserSignal gcmHAL2D(gckOS_UserSignal)
  152772. +#define gckOS_UserSignal gcmHAL2D(gckOS_UserSignal)
  152773. +#define gckOS_CacheClean gcmHAL2D(gckOS_CacheClean)
  152774. +#define gckOS_CacheFlush gcmHAL2D(gckOS_CacheFlush)
  152775. +#define gckOS_SetDebugLevel gcmHAL2D(gckOS_SetDebugLevel)
  152776. +#define gckOS_SetDebugZone gcmHAL2D(gckOS_SetDebugZone)
  152777. +#define gckOS_SetDebugLevelZone gcmHAL2D(gckOS_SetDebugLevelZone)
  152778. +#define gckOS_SetDebugZones gcmHAL2D(gckOS_SetDebugZones)
  152779. +#define gckOS_SetDebugFile gcmHAL2D(gckOS_SetDebugFile)
  152780. +#define gckOS_Broadcast gcmHAL2D(gckOS_Broadcast)
  152781. +#define gckOS_SetGPUPower gcmHAL2D(gckOS_SetGPUPower)
  152782. +#define gckOS_CreateSemaphore gcmHAL2D(gckOS_CreateSemaphore)
  152783. +#define gckOS_DestroySemaphore gcmHAL2D(gckOS_DestroySemaphore)
  152784. +#define gckOS_AcquireSemaphore gcmHAL2D(gckOS_AcquireSemaphore)
  152785. +#define gckOS_ReleaseSemaphore gcmHAL2D(gckOS_ReleaseSemaphore)
  152786. +#define gckHEAP_Construct gcmHAL2D(gckHEAP_Construct)
  152787. +#define gckHEAP_Destroy gcmHAL2D(gckHEAP_Destroy)
  152788. +#define gckHEAP_Allocate gcmHAL2D(gckHEAP_Allocate)
  152789. +#define gckHEAP_Free gcmHAL2D(gckHEAP_Free)
  152790. +#define gckHEAP_ProfileStart gcmHAL2D(gckHEAP_ProfileStart)
  152791. +#define gckHEAP_ProfileEnd gcmHAL2D(gckHEAP_ProfileEnd)
  152792. +#define gckHEAP_Test gcmHAL2D(gckHEAP_Test)
  152793. +#define gckVIDMEM_Construct gcmHAL2D(gckVIDMEM_Construct)
  152794. +#define gckVIDMEM_Destroy gcmHAL2D(gckVIDMEM_Destroy)
  152795. +#define gckVIDMEM_Allocate gcmHAL2D(gckVIDMEM_Allocate)
  152796. +#define gckVIDMEM_AllocateLinear gcmHAL2D(gckVIDMEM_AllocateLinear)
  152797. +#define gckVIDMEM_Free gcmHAL2D(gckVIDMEM_Free)
  152798. +#define gckVIDMEM_Lock gcmHAL2D(gckVIDMEM_Lock)
  152799. +#define gckVIDMEM_Unlock gcmHAL2D(gckVIDMEM_Unlock)
  152800. +#define gckVIDMEM_ConstructVirtual gcmHAL2D(gckVIDMEM_ConstructVirtual)
  152801. +#define gckVIDMEM_DestroyVirtual gcmHAL2D(gckVIDMEM_DestroyVirtual)
  152802. +#define gckKERNEL_Construct gcmHAL2D(gckKERNEL_Construct)
  152803. +#define gckKERNEL_Destroy gcmHAL2D(gckKERNEL_Destroy)
  152804. +#define gckKERNEL_Dispatch gcmHAL2D(gckKERNEL_Dispatch)
  152805. +#define gckKERNEL_QueryVideoMemory gcmHAL2D(gckKERNEL_QueryVideoMemory)
  152806. +#define gckKERNEL_GetVideoMemoryPool gcmHAL2D(gckKERNEL_GetVideoMemoryPool)
  152807. +#define gckKERNEL_MapVideoMemory gcmHAL2D(gckKERNEL_MapVideoMemory)
  152808. +#define gckKERNEL_UnmapVideoMemory gcmHAL2D(gckKERNEL_UnmapVideoMemory)
  152809. +#define gckKERNEL_MapMemory gcmHAL2D(gckKERNEL_MapMemory)
  152810. +#define gckKERNEL_UnmapMemory gcmHAL2D(gckKERNEL_UnmapMemory)
  152811. +#define gckKERNEL_Notify gcmHAL2D(gckKERNEL_Notify)
  152812. +#define gckKERNEL_QuerySettings gcmHAL2D(gckKERNEL_QuerySettings)
  152813. +#define gckKERNEL_Recovery gcmHAL2D(gckKERNEL_Recovery)
  152814. +#define gckKERNEL_OpenUserData gcmHAL2D(gckKERNEL_OpenUserData)
  152815. +#define gckKERNEL_CloseUserData gcmHAL2D(gckKERNEL_CloseUserData)
  152816. +#define gckHARDWARE_Construct gcmHAL2D(gckHARDWARE_Construct)
  152817. +#define gckHARDWARE_Destroy gcmHAL2D(gckHARDWARE_Destroy)
  152818. +#define gckHARDWARE_QuerySystemMemory gcmHAL2D(gckHARDWARE_QuerySystemMemory)
  152819. +#define gckHARDWARE_BuildVirtualAddress gcmHAL2D(gckHARDWARE_BuildVirtualAddress)
  152820. +#define gckHARDWARE_QueryCommandBuffer gcmHAL2D(gckHARDWARE_QueryCommandBuffer)
  152821. +#define gckHARDWARE_WaitLink gcmHAL2D(gckHARDWARE_WaitLink)
  152822. +#define gckHARDWARE_Execute gcmHAL2D(gckHARDWARE_Execute)
  152823. +#define gckHARDWARE_End gcmHAL2D(gckHARDWARE_End)
  152824. +#define gckHARDWARE_Nop gcmHAL2D(gckHARDWARE_Nop)
  152825. +#define gckHARDWARE_Wait gcmHAL2D(gckHARDWARE_Wait)
  152826. +#define gckHARDWARE_PipeSelect gcmHAL2D(gckHARDWARE_PipeSelect)
  152827. +#define gckHARDWARE_Link gcmHAL2D(gckHARDWARE_Link)
  152828. +#define gckHARDWARE_Event gcmHAL2D(gckHARDWARE_Event)
  152829. +#define gckHARDWARE_QueryMemory gcmHAL2D(gckHARDWARE_QueryMemory)
  152830. +#define gckHARDWARE_QueryChipIdentity gcmHAL2D(gckHARDWARE_QueryChipIdentity)
  152831. +#define gckHARDWARE_QueryChipSpecs gcmHAL2D(gckHARDWARE_QueryChipSpecs)
  152832. +#define gckHARDWARE_QueryShaderCaps gcmHAL2D(gckHARDWARE_QueryShaderCaps)
  152833. +#define gckHARDWARE_ConvertFormat gcmHAL2D(gckHARDWARE_ConvertFormat)
  152834. +#define gckHARDWARE_SplitMemory gcmHAL2D(gckHARDWARE_SplitMemory)
  152835. +#define gckHARDWARE_AlignToTile gcmHAL2D(gckHARDWARE_AlignToTile)
  152836. +#define gckHARDWARE_UpdateQueueTail gcmHAL2D(gckHARDWARE_UpdateQueueTail)
  152837. +#define gckHARDWARE_ConvertLogical gcmHAL2D(gckHARDWARE_ConvertLogical)
  152838. +#define gckHARDWARE_ConvertPhysical gcmHAL2D(gckHARDWARE_ConvertPhysical)
  152839. +#define gckHARDWARE_Interrupt gcmHAL2D(gckHARDWARE_Interrupt)
  152840. +#define gckHARDWARE_SetMMU gcmHAL2D(gckHARDWARE_SetMMU)
  152841. +#define gckHARDWARE_FlushMMU gcmHAL2D(gckHARDWARE_FlushMMU)
  152842. +#define gckHARDWARE_GetIdle gcmHAL2D(gckHARDWARE_GetIdle)
  152843. +#define gckHARDWARE_Flush gcmHAL2D(gckHARDWARE_Flush)
  152844. +#define gckHARDWARE_SetFastClear gcmHAL2D(gckHARDWARE_SetFastClear)
  152845. +#define gckHARDWARE_ReadInterrupt gcmHAL2D(gckHARDWARE_ReadInterrupt)
  152846. +#define gckHARDWARE_SetPowerManagementState gcmHAL2D(gckHARDWARE_SetPowerManagementState)
  152847. +#define gckHARDWARE_QueryPowerManagementState gcmHAL2D(gckHARDWARE_QueryPowerManagementState)
  152848. +#define gckHARDWARE_ProfileEngine2D gcmHAL2D(gckHARDWARE_ProfileEngine2D)
  152849. +#define gckHARDWARE_InitializeHardware gcmHAL2D(gckHARDWARE_InitializeHardware)
  152850. +#define gckHARDWARE_Reset gcmHAL2D(gckHARDWARE_Reset)
  152851. +#define gckINTERRUPT_Construct gcmHAL2D(gckINTERRUPT_Construct)
  152852. +#define gckINTERRUPT_Destroy gcmHAL2D(gckINTERRUPT_Destroy)
  152853. +#define gckINTERRUPT_SetHandler gcmHAL2D(gckINTERRUPT_SetHandler)
  152854. +#define gckINTERRUPT_Notify gcmHAL2D(gckINTERRUPT_Notify)
  152855. +#define gckEVENT_Construct gcmHAL2D(gckEVENT_Construct)
  152856. +#define gckEVENT_Destroy gcmHAL2D(gckEVENT_Destroy)
  152857. +#define gckEVENT_AddList gcmHAL2D(gckEVENT_AddList)
  152858. +#define gckEVENT_FreeNonPagedMemory gcmHAL2D(gckEVENT_FreeNonPagedMemory)
  152859. +#define gckEVENT_FreeContiguousMemory gcmHAL2D(gckEVENT_FreeContiguousMemory)
  152860. +#define gckEVENT_FreeVideoMemory gcmHAL2D(gckEVENT_FreeVideoMemory)
  152861. +#define gckEVENT_Signal gcmHAL2D(gckEVENT_Signal)
  152862. +#define gckEVENT_Unlock gcmHAL2D(gckEVENT_Unlock)
  152863. +#define gckEVENT_Submit gcmHAL2D(gckEVENT_Submit)
  152864. +#define gckEVENT_Commit gcmHAL2D(gckEVENT_Commit)
  152865. +#define gckEVENT_Notify gcmHAL2D(gckEVENT_Notify)
  152866. +#define gckEVENT_Interrupt gcmHAL2D(gckEVENT_Interrupt)
  152867. +#define gckCOMMAND_Construct gcmHAL2D(gckCOMMAND_Construct)
  152868. +#define gckCOMMAND_Destroy gcmHAL2D(gckCOMMAND_Destroy)
  152869. +#define gckCOMMAND_EnterCommit gcmHAL2D(gckCOMMAND_EnterCommit)
  152870. +#define gckCOMMAND_ExitCommit gcmHAL2D(gckCOMMAND_ExitCommit)
  152871. +#define gckCOMMAND_Start gcmHAL2D(gckCOMMAND_Start)
  152872. +#define gckCOMMAND_Stop gcmHAL2D(gckCOMMAND_Stop)
  152873. +#define gckCOMMAND_Commit gcmHAL2D(gckCOMMAND_Commit)
  152874. +#define gckCOMMAND_Reserve gcmHAL2D(gckCOMMAND_Reserve)
  152875. +#define gckCOMMAND_Execute gcmHAL2D(gckCOMMAND_Execute)
  152876. +#define gckCOMMAND_Stall gcmHAL2D(gckCOMMAND_Stall)
  152877. +#define gckCOMMAND_Attach gcmHAL2D(gckCOMMAND_Attach)
  152878. +#define gckCOMMAND_Detach gcmHAL2D(gckCOMMAND_Detach)
  152879. +#define gckMMU_Construct gcmHAL2D(gckMMU_Construct)
  152880. +#define gckMMU_Destroy gcmHAL2D(gckMMU_Destroy)
  152881. +#define gckMMU_AllocatePages gcmHAL2D(gckMMU_AllocatePages)
  152882. +#define gckMMU_FreePages gcmHAL2D(gckMMU_FreePages)
  152883. +#define gckMMU_InsertNode gcmHAL2D(gckMMU_InsertNode)
  152884. +#define gckMMU_RemoveNode gcmHAL2D(gckMMU_RemoveNode)
  152885. +#define gckMMU_FreeHandleMemory gcmHAL2D(gckMMU_FreeHandleMemory)
  152886. +#define gckMMU_Test gcmHAL2D(gckMMU_Test)
  152887. +#define gckHARDWARE_QueryProfileRegisters gcmHAL2D(gckHARDWARE_QueryProfileRegisters)
  152888. +
  152889. +
  152890. +#define FindMdlMap gcmHAL2D(FindMdlMap)
  152891. +#define OnProcessExit gcmHAL2D(OnProcessExit)
  152892. +
  152893. +#define gckGALDEVICE_Destroy gcmHAL2D(gckGALDEVICE_Destroy)
  152894. +#define gckOS_Print gcmHAL2D(gckOS_Print)
  152895. +#define gckGALDEVICE_FreeMemory gcmHAL2D(gckGALDEVICE_FreeMemory)
  152896. +#define gckGALDEVICE_AllocateMemory gcmHAL2D(gckGALDEVICE_AllocateMemory)
  152897. +#define gckOS_DebugBreak gcmHAL2D(gckOS_DebugBreak)
  152898. +#define gckGALDEVICE_Release_ISR gcmHAL2D(gckGALDEVICE_Release_ISR)
  152899. +#define gckOS_Verify gcmHAL2D(gckOS_Verify)
  152900. +#define gckCOMMAND_Release gcmHAL2D(gckCOMMAND_Release)
  152901. +#define gckGALDEVICE_Stop gcmHAL2D(gckGALDEVICE_Stop)
  152902. +#define gckGALDEVICE_Construct gcmHAL2D(gckGALDEVICE_Construct)
  152903. +#define gckOS_DebugFatal gcmHAL2D(gckOS_DebugFatal)
  152904. +#define gckOS_DebugTrace gcmHAL2D(gckOS_DebugTrace)
  152905. +#define gckHARDWARE_GetBaseAddress gcmHAL2D(gckHARDWARE_GetBaseAddress)
  152906. +#define gckGALDEVICE_Setup_ISR gcmHAL2D(gckGALDEVICE_Setup_ISR)
  152907. +#define gckKERNEL_AttachProcess gcmHAL2D(gckKERNEL_AttachProcess)
  152908. +#define gckKERNEL_AttachProcessEx gcmHAL2D(gckKERNEL_AttachProcessEx)
  152909. +#define gckGALDEVICE_Start_Thread gcmHAL2D(gckGALDEVICE_Start_Thread)
  152910. +#define gckHARDWARE_QueryIdle gcmHAL2D(gckHARDWARE_QueryIdle)
  152911. +#define gckGALDEVICE_Start gcmHAL2D(gckGALDEVICE_Start)
  152912. +#define gckOS_GetKernelLogical gcmHAL2D(gckOS_GetKernelLogical)
  152913. +#define gckOS_DebugTraceZone gcmHAL2D(gckOS_DebugTraceZone)
  152914. +#define gckGALDEVICE_Stop_Thread gcmHAL2D(gckGALDEVICE_Stop_Thread)
  152915. +#define gckHARDWARE_NeedBaseAddress gcmHAL2D(gckHARDWARE_NeedBaseAddress)
  152916. +
  152917. +#endif
  152918. +
  152919. +#endif /* __gc_hal_rename_h_ */
  152920. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h
  152921. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h 1969-12-31 18:00:00.000000000 -0600
  152922. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h 2014-12-08 00:31:53.472418001 -0600
  152923. @@ -0,0 +1,115 @@
  152924. +/****************************************************************************
  152925. +*
  152926. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  152927. +*
  152928. +* This program is free software; you can redistribute it and/or modify
  152929. +* it under the terms of the GNU General Public License as published by
  152930. +* the Free Software Foundation; either version 2 of the license, or
  152931. +* (at your option) any later version.
  152932. +*
  152933. +* This program is distributed in the hope that it will be useful,
  152934. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  152935. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  152936. +* GNU General Public License for more details.
  152937. +*
  152938. +* You should have received a copy of the GNU General Public License
  152939. +* along with this program; if not write to the Free Software
  152940. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  152941. +*
  152942. +*****************************************************************************/
  152943. +
  152944. +
  152945. +#ifndef __gc_hal_statistics_h_
  152946. +#define __gc_hal_statistics_h_
  152947. +
  152948. +
  152949. +#define VIV_STAT_ENABLE_STATISTICS 0
  152950. +
  152951. +/* Toal number of frames for which the frame time is accounted. We have storage
  152952. + to keep frame times for last this many frames.
  152953. +*/
  152954. +#define VIV_STAT_FRAME_BUFFER_SIZE 30
  152955. +
  152956. +/*
  152957. + Total number of frames sampled for a mode. This means
  152958. +
  152959. + # of frames for HZ Current : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
  152960. + # of frames for HZ Switched : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
  152961. + +
  152962. + --------------------------------------------------------
  152963. + : (2 * VIV_STAT_EARLY_Z_SAMPLE_FRAMES) frames needed
  152964. +
  152965. + IMPORTANT: This total must be smaller than VIV_STAT_FRAME_BUFFER_SIZE
  152966. +*/
  152967. +#define VIV_STAT_EARLY_Z_SAMPLE_FRAMES 7
  152968. +#define VIV_STAT_EARLY_Z_LATENCY_FRAMES 2
  152969. +
  152970. +/* Multiplication factor for previous Hz off mode. Make it more than 1.0 to advertise HZ on.*/
  152971. +#define VIV_STAT_EARLY_Z_FACTOR (1.05f)
  152972. +
  152973. +/* Defines the statistical data keys monitored by the statistics module */
  152974. +typedef enum _gceSTATISTICS
  152975. +{
  152976. + gcvFRAME_FPS = 1,
  152977. +}
  152978. +gceSTATISTICS;
  152979. +
  152980. +/* HAL statistics information. */
  152981. +typedef struct _gcsSTATISTICS_EARLYZ
  152982. +{
  152983. + gctUINT switchBackCount;
  152984. + gctUINT nextCheckPoint;
  152985. + gctBOOL disabled;
  152986. +}
  152987. +gcsSTATISTICS_EARLYZ;
  152988. +
  152989. +
  152990. +/* Defines the statistical data keys monitored by the statistics module */
  152991. +typedef enum _gceSTATISTICS_Call
  152992. +{
  152993. + gcvSTAT_ES11_GLDRAWELEMENTS = 1,
  152994. +}
  152995. +gceSTATISTICS_Call;
  152996. +
  152997. +
  152998. +/* HAL statistics information. */
  152999. +typedef struct _gcsSTATISTICS
  153000. +{
  153001. + gctUINT64 frameTime[VIV_STAT_FRAME_BUFFER_SIZE];
  153002. + gctUINT64 previousFrameTime;
  153003. + gctUINT frame;
  153004. + gcsSTATISTICS_EARLYZ earlyZ;
  153005. + gctUINT ES11_drawElementsCount;
  153006. + gctBOOL applyRTestVAFix;
  153007. +}
  153008. +gcsSTATISTICS;
  153009. +
  153010. +
  153011. +/* Add a frame based data into current statistics. */
  153012. +void
  153013. +gcfSTATISTICS_AddData(
  153014. + IN gceSTATISTICS Key,
  153015. + IN gctUINT Value
  153016. + );
  153017. +
  153018. +/* Marks the frame end and triggers statistical calculations and decisions.*/
  153019. +void
  153020. +gcfSTATISTICS_MarkFrameEnd (
  153021. + void
  153022. + );
  153023. +
  153024. +/* Sets whether the dynmaic HZ is disabled or not .*/
  153025. +void
  153026. +gcfSTATISTICS_DisableDynamicEarlyZ (
  153027. + IN gctBOOL Disabled
  153028. + );
  153029. +
  153030. +/* Checks whether or not glDrawArray function call will be discarded */
  153031. +gctBOOL
  153032. +gcfSTATISTICS_DiscardCall(
  153033. + gceSTATISTICS_Call Function
  153034. + );
  153035. +
  153036. +
  153037. +#endif /*__gc_hal_statistics_h_ */
  153038. +
  153039. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
  153040. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h 1969-12-31 18:00:00.000000000 -0600
  153041. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h 2014-12-08 00:31:53.472418001 -0600
  153042. @@ -0,0 +1,1080 @@
  153043. +/****************************************************************************
  153044. +*
  153045. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  153046. +*
  153047. +* This program is free software; you can redistribute it and/or modify
  153048. +* it under the terms of the GNU General Public License as published by
  153049. +* the Free Software Foundation; either version 2 of the license, or
  153050. +* (at your option) any later version.
  153051. +*
  153052. +* This program is distributed in the hope that it will be useful,
  153053. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  153054. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  153055. +* GNU General Public License for more details.
  153056. +*
  153057. +* You should have received a copy of the GNU General Public License
  153058. +* along with this program; if not write to the Free Software
  153059. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  153060. +*
  153061. +*****************************************************************************/
  153062. +
  153063. +
  153064. +#ifndef __gc_hal_types_h_
  153065. +#define __gc_hal_types_h_
  153066. +
  153067. +#include "gc_hal_version.h"
  153068. +#include "gc_hal_options.h"
  153069. +
  153070. +#ifdef _WIN32
  153071. +#pragma warning(disable:4127) /* Conditional expression is constant (do { }
  153072. + ** while(0)). */
  153073. +#pragma warning(disable:4100) /* Unreferenced formal parameter. */
  153074. +#pragma warning(disable:4204) /* Non-constant aggregate initializer (C99). */
  153075. +#pragma warning(disable:4131) /* Uses old-style declarator (for Bison and
  153076. + ** Flex generated files). */
  153077. +#pragma warning(disable:4206) /* Translation unit is empty. */
  153078. +#endif
  153079. +
  153080. +#ifdef __cplusplus
  153081. +extern "C" {
  153082. +#endif
  153083. +
  153084. +/******************************************************************************\
  153085. +** Platform macros.
  153086. +*/
  153087. +
  153088. +#if defined(__GNUC__)
  153089. +# define gcdHAS_ELLIPSES 1 /* GCC always has it. */
  153090. +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
  153091. +# define gcdHAS_ELLIPSES 1 /* C99 has it. */
  153092. +#elif defined(_MSC_VER) && (_MSC_VER >= 1500)
  153093. +# define gcdHAS_ELLIPSES 1 /* MSVC 2007+ has it. */
  153094. +#elif defined(UNDER_CE)
  153095. +#if UNDER_CE >= 600
  153096. +# define gcdHAS_ELLIPSES 1
  153097. +# else
  153098. +# define gcdHAS_ELLIPSES 0
  153099. +# endif
  153100. +#else
  153101. +# error "gcdHAS_ELLIPSES: Platform could not be determined"
  153102. +#endif
  153103. +
  153104. +/******************************************************************************\
  153105. +************************************ Keyword ***********************************
  153106. +\******************************************************************************/
  153107. +
  153108. +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
  153109. +# define gcmINLINE inline /* C99 keyword. */
  153110. +#elif defined(__GNUC__)
  153111. +# define gcmINLINE __inline__ /* GNU keyword. */
  153112. +#elif defined(_MSC_VER) || defined(UNDER_CE)
  153113. +# define gcmINLINE __inline /* Internal keyword. */
  153114. +#else
  153115. +# error "gcmINLINE: Platform could not be determined"
  153116. +#endif
  153117. +
  153118. +/* Possible debug flags. */
  153119. +#define gcdDEBUG_NONE 0
  153120. +#define gcdDEBUG_ALL (1 << 0)
  153121. +#define gcdDEBUG_FATAL (1 << 1)
  153122. +#define gcdDEBUG_TRACE (1 << 2)
  153123. +#define gcdDEBUG_BREAK (1 << 3)
  153124. +#define gcdDEBUG_ASSERT (1 << 4)
  153125. +#define gcdDEBUG_CODE (1 << 5)
  153126. +#define gcdDEBUG_STACK (1 << 6)
  153127. +
  153128. +#define gcmIS_DEBUG(flag) ( gcdDEBUG & (flag | gcdDEBUG_ALL) )
  153129. +
  153130. +#ifndef gcdDEBUG
  153131. +#if (defined(DBG) && DBG) || defined(DEBUG) || defined(_DEBUG)
  153132. +# define gcdDEBUG gcdDEBUG_ALL
  153133. +# else
  153134. +# define gcdDEBUG gcdDEBUG_NONE
  153135. +# endif
  153136. +#endif
  153137. +
  153138. +#ifdef _USRDLL
  153139. +#ifdef _MSC_VER
  153140. +#ifdef HAL_EXPORTS
  153141. +# define HALAPI __declspec(dllexport)
  153142. +# else
  153143. +# define HALAPI __declspec(dllimport)
  153144. +# endif
  153145. +# define HALDECL __cdecl
  153146. +# else
  153147. +#ifdef HAL_EXPORTS
  153148. +# define HALAPI
  153149. +# else
  153150. +# define HALAPI extern
  153151. +# endif
  153152. +# endif
  153153. +#else
  153154. +# define HALAPI
  153155. +# define HALDECL
  153156. +#endif
  153157. +
  153158. +/******************************************************************************\
  153159. +********************************** Common Types ********************************
  153160. +\******************************************************************************/
  153161. +
  153162. +#define gcvFALSE 0
  153163. +#define gcvTRUE 1
  153164. +
  153165. +#define gcvINFINITE ((gctUINT32) ~0U)
  153166. +
  153167. +#define gcvINVALID_HANDLE ((gctHANDLE) ~0U)
  153168. +
  153169. +typedef int gctBOOL;
  153170. +typedef gctBOOL * gctBOOL_PTR;
  153171. +
  153172. +typedef int gctINT;
  153173. +typedef long gctLONG;
  153174. +typedef signed char gctINT8;
  153175. +typedef signed short gctINT16;
  153176. +typedef signed int gctINT32;
  153177. +typedef signed long long gctINT64;
  153178. +
  153179. +typedef gctINT * gctINT_PTR;
  153180. +typedef gctINT8 * gctINT8_PTR;
  153181. +typedef gctINT16 * gctINT16_PTR;
  153182. +typedef gctINT32 * gctINT32_PTR;
  153183. +typedef gctINT64 * gctINT64_PTR;
  153184. +
  153185. +typedef unsigned int gctUINT;
  153186. +typedef unsigned char gctUINT8;
  153187. +typedef unsigned short gctUINT16;
  153188. +typedef unsigned int gctUINT32;
  153189. +typedef unsigned long long gctUINT64;
  153190. +typedef unsigned long gctUINTPTR_T;
  153191. +
  153192. +typedef gctUINT * gctUINT_PTR;
  153193. +typedef gctUINT8 * gctUINT8_PTR;
  153194. +typedef gctUINT16 * gctUINT16_PTR;
  153195. +typedef gctUINT32 * gctUINT32_PTR;
  153196. +typedef gctUINT64 * gctUINT64_PTR;
  153197. +
  153198. +typedef unsigned long gctSIZE_T;
  153199. +typedef gctSIZE_T * gctSIZE_T_PTR;
  153200. +
  153201. +#ifdef __cplusplus
  153202. +# define gcvNULL 0
  153203. +#else
  153204. +# define gcvNULL ((void *) 0)
  153205. +#endif
  153206. +
  153207. +typedef float gctFLOAT;
  153208. +typedef signed int gctFIXED_POINT;
  153209. +typedef float * gctFLOAT_PTR;
  153210. +
  153211. +typedef void * gctPHYS_ADDR;
  153212. +typedef void * gctHANDLE;
  153213. +typedef void * gctFILE;
  153214. +typedef void * gctSIGNAL;
  153215. +typedef void * gctWINDOW;
  153216. +typedef void * gctIMAGE;
  153217. +typedef void * gctSYNC_POINT;
  153218. +
  153219. +typedef void * gctSEMAPHORE;
  153220. +
  153221. +typedef void * gctPOINTER;
  153222. +typedef const void * gctCONST_POINTER;
  153223. +
  153224. +typedef char gctCHAR;
  153225. +typedef char * gctSTRING;
  153226. +typedef const char * gctCONST_STRING;
  153227. +
  153228. +typedef struct _gcsCOUNT_STRING
  153229. +{
  153230. + gctSIZE_T Length;
  153231. + gctCONST_STRING String;
  153232. +}
  153233. +gcsCOUNT_STRING;
  153234. +
  153235. +typedef union _gcuFLOAT_UINT32
  153236. +{
  153237. + gctFLOAT f;
  153238. + gctUINT32 u;
  153239. +}
  153240. +gcuFLOAT_UINT32;
  153241. +
  153242. +/* Fixed point constants. */
  153243. +#define gcvZERO_X ((gctFIXED_POINT) 0x00000000)
  153244. +#define gcvHALF_X ((gctFIXED_POINT) 0x00008000)
  153245. +#define gcvONE_X ((gctFIXED_POINT) 0x00010000)
  153246. +#define gcvNEGONE_X ((gctFIXED_POINT) 0xFFFF0000)
  153247. +#define gcvTWO_X ((gctFIXED_POINT) 0x00020000)
  153248. +
  153249. +/* Stringizing macro. */
  153250. +#define gcmSTRING(Value) #Value
  153251. +
  153252. +/******************************************************************************\
  153253. +******************************* Fixed Point Math *******************************
  153254. +\******************************************************************************/
  153255. +
  153256. +#define gcmXMultiply(x1, x2) gcoMATH_MultiplyFixed(x1, x2)
  153257. +#define gcmXDivide(x1, x2) gcoMATH_DivideFixed(x1, x2)
  153258. +#define gcmXMultiplyDivide(x1, x2, x3) gcoMATH_MultiplyDivideFixed(x1, x2, x3)
  153259. +
  153260. +/* 2D Engine profile. */
  153261. +typedef struct _gcs2D_PROFILE
  153262. +{
  153263. + /* Cycle count.
  153264. + 32bit counter incremented every 2D clock cycle.
  153265. + Wraps back to 0 when the counter overflows.
  153266. + */
  153267. + gctUINT32 cycleCount;
  153268. +
  153269. + /* Pixels rendered by the 2D engine.
  153270. + Resets to 0 every time it is read. */
  153271. + gctUINT32 pixelsRendered;
  153272. +}
  153273. +gcs2D_PROFILE;
  153274. +
  153275. +/* Macro to combine four characters into a Charcater Code. */
  153276. +#define gcmCC(c1, c2, c3, c4) \
  153277. +( \
  153278. + (char) (c1) \
  153279. + | \
  153280. + ((char) (c2) << 8) \
  153281. + | \
  153282. + ((char) (c3) << 16) \
  153283. + | \
  153284. + ((char) (c4) << 24) \
  153285. +)
  153286. +
  153287. +#define gcmPRINTABLE(c) ((((c) >= ' ') && ((c) <= '}')) ? ((c) != '%' ? (c) : ' ') : ' ')
  153288. +
  153289. +#define gcmCC_PRINT(cc) \
  153290. + gcmPRINTABLE((char) ( (cc) & 0xFF)), \
  153291. + gcmPRINTABLE((char) (((cc) >> 8) & 0xFF)), \
  153292. + gcmPRINTABLE((char) (((cc) >> 16) & 0xFF)), \
  153293. + gcmPRINTABLE((char) (((cc) >> 24) & 0xFF))
  153294. +
  153295. +/******************************************************************************\
  153296. +****************************** Function Parameters *****************************
  153297. +\******************************************************************************/
  153298. +
  153299. +#define IN
  153300. +#define OUT
  153301. +#define OPTIONAL
  153302. +
  153303. +/******************************************************************************\
  153304. +********************************* Status Codes *********************************
  153305. +\******************************************************************************/
  153306. +
  153307. +typedef enum _gceSTATUS
  153308. +{
  153309. + gcvSTATUS_OK = 0,
  153310. + gcvSTATUS_FALSE = 0,
  153311. + gcvSTATUS_TRUE = 1,
  153312. + gcvSTATUS_NO_MORE_DATA = 2,
  153313. + gcvSTATUS_CACHED = 3,
  153314. + gcvSTATUS_MIPMAP_TOO_LARGE = 4,
  153315. + gcvSTATUS_NAME_NOT_FOUND = 5,
  153316. + gcvSTATUS_NOT_OUR_INTERRUPT = 6,
  153317. + gcvSTATUS_MISMATCH = 7,
  153318. + gcvSTATUS_MIPMAP_TOO_SMALL = 8,
  153319. + gcvSTATUS_LARGER = 9,
  153320. + gcvSTATUS_SMALLER = 10,
  153321. + gcvSTATUS_CHIP_NOT_READY = 11,
  153322. + gcvSTATUS_NEED_CONVERSION = 12,
  153323. + gcvSTATUS_SKIP = 13,
  153324. + gcvSTATUS_DATA_TOO_LARGE = 14,
  153325. + gcvSTATUS_INVALID_CONFIG = 15,
  153326. + gcvSTATUS_CHANGED = 16,
  153327. + gcvSTATUS_NOT_SUPPORT_DITHER = 17,
  153328. + gcvSTATUS_EXECUTED = 18,
  153329. + gcvSTATUS_TERMINATE = 19,
  153330. +
  153331. + gcvSTATUS_CONVERT_TO_SINGLE_STREAM = 20,
  153332. +
  153333. + gcvSTATUS_INVALID_ARGUMENT = -1,
  153334. + gcvSTATUS_INVALID_OBJECT = -2,
  153335. + gcvSTATUS_OUT_OF_MEMORY = -3,
  153336. + gcvSTATUS_MEMORY_LOCKED = -4,
  153337. + gcvSTATUS_MEMORY_UNLOCKED = -5,
  153338. + gcvSTATUS_HEAP_CORRUPTED = -6,
  153339. + gcvSTATUS_GENERIC_IO = -7,
  153340. + gcvSTATUS_INVALID_ADDRESS = -8,
  153341. + gcvSTATUS_CONTEXT_LOSSED = -9,
  153342. + gcvSTATUS_TOO_COMPLEX = -10,
  153343. + gcvSTATUS_BUFFER_TOO_SMALL = -11,
  153344. + gcvSTATUS_INTERFACE_ERROR = -12,
  153345. + gcvSTATUS_NOT_SUPPORTED = -13,
  153346. + gcvSTATUS_MORE_DATA = -14,
  153347. + gcvSTATUS_TIMEOUT = -15,
  153348. + gcvSTATUS_OUT_OF_RESOURCES = -16,
  153349. + gcvSTATUS_INVALID_DATA = -17,
  153350. + gcvSTATUS_INVALID_MIPMAP = -18,
  153351. + gcvSTATUS_NOT_FOUND = -19,
  153352. + gcvSTATUS_NOT_ALIGNED = -20,
  153353. + gcvSTATUS_INVALID_REQUEST = -21,
  153354. + gcvSTATUS_GPU_NOT_RESPONDING = -22,
  153355. + gcvSTATUS_TIMER_OVERFLOW = -23,
  153356. + gcvSTATUS_VERSION_MISMATCH = -24,
  153357. + gcvSTATUS_LOCKED = -25,
  153358. + gcvSTATUS_INTERRUPTED = -26,
  153359. + gcvSTATUS_DEVICE = -27,
  153360. + gcvSTATUS_NOT_MULTI_PIPE_ALIGNED = -28,
  153361. +
  153362. + /* Linker errors. */
  153363. + gcvSTATUS_GLOBAL_TYPE_MISMATCH = -1000,
  153364. + gcvSTATUS_TOO_MANY_ATTRIBUTES = -1001,
  153365. + gcvSTATUS_TOO_MANY_UNIFORMS = -1002,
  153366. + gcvSTATUS_TOO_MANY_VARYINGS = -1003,
  153367. + gcvSTATUS_UNDECLARED_VARYING = -1004,
  153368. + gcvSTATUS_VARYING_TYPE_MISMATCH = -1005,
  153369. + gcvSTATUS_MISSING_MAIN = -1006,
  153370. + gcvSTATUS_NAME_MISMATCH = -1007,
  153371. + gcvSTATUS_INVALID_INDEX = -1008,
  153372. + gcvSTATUS_UNIFORM_TYPE_MISMATCH = -1009,
  153373. +
  153374. + /* Compiler errors. */
  153375. + gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR = -2000,
  153376. + gcvSTATUS_COMPILER_FE_PARSER_ERROR = -2001,
  153377. +}
  153378. +gceSTATUS;
  153379. +
  153380. +/******************************************************************************\
  153381. +********************************* Status Macros ********************************
  153382. +\******************************************************************************/
  153383. +
  153384. +#define gcmIS_ERROR(status) (status < 0)
  153385. +#define gcmNO_ERROR(status) (status >= 0)
  153386. +#define gcmIS_SUCCESS(status) (status == gcvSTATUS_OK)
  153387. +
  153388. +/******************************************************************************\
  153389. +********************************* Field Macros *********************************
  153390. +\******************************************************************************/
  153391. +
  153392. +#define __gcmSTART(reg_field) \
  153393. + (0 ? reg_field)
  153394. +
  153395. +#define __gcmEND(reg_field) \
  153396. + (1 ? reg_field)
  153397. +
  153398. +#define __gcmGETSIZE(reg_field) \
  153399. + (__gcmEND(reg_field) - __gcmSTART(reg_field) + 1)
  153400. +
  153401. +#define __gcmALIGN(data, reg_field) \
  153402. + (((gctUINT32) (data)) << __gcmSTART(reg_field))
  153403. +
  153404. +#define __gcmMASK(reg_field) \
  153405. + ((gctUINT32) ((__gcmGETSIZE(reg_field) == 32) \
  153406. + ? ~0 \
  153407. + : (~(~0 << __gcmGETSIZE(reg_field)))))
  153408. +
  153409. +/*******************************************************************************
  153410. +**
  153411. +** gcmFIELDMASK
  153412. +**
  153413. +** Get aligned field mask.
  153414. +**
  153415. +** ARGUMENTS:
  153416. +**
  153417. +** reg Name of register.
  153418. +** field Name of field within register.
  153419. +*/
  153420. +#define gcmFIELDMASK(reg, field) \
  153421. +( \
  153422. + __gcmALIGN(__gcmMASK(reg##_##field), reg##_##field) \
  153423. +)
  153424. +
  153425. +/*******************************************************************************
  153426. +**
  153427. +** gcmGETFIELD
  153428. +**
  153429. +** Extract the value of a field from specified data.
  153430. +**
  153431. +** ARGUMENTS:
  153432. +**
  153433. +** data Data value.
  153434. +** reg Name of register.
  153435. +** field Name of field within register.
  153436. +*/
  153437. +#define gcmGETFIELD(data, reg, field) \
  153438. +( \
  153439. + ((((gctUINT32) (data)) >> __gcmSTART(reg##_##field)) \
  153440. + & __gcmMASK(reg##_##field)) \
  153441. +)
  153442. +
  153443. +/*******************************************************************************
  153444. +**
  153445. +** gcmSETFIELD
  153446. +**
  153447. +** Set the value of a field within specified data.
  153448. +**
  153449. +** ARGUMENTS:
  153450. +**
  153451. +** data Data value.
  153452. +** reg Name of register.
  153453. +** field Name of field within register.
  153454. +** value Value for field.
  153455. +*/
  153456. +#define gcmSETFIELD(data, reg, field, value) \
  153457. +( \
  153458. + (((gctUINT32) (data)) \
  153459. + & ~__gcmALIGN(__gcmMASK(reg##_##field), reg##_##field)) \
  153460. + | __gcmALIGN((gctUINT32) (value) \
  153461. + & __gcmMASK(reg##_##field), reg##_##field) \
  153462. +)
  153463. +
  153464. +/*******************************************************************************
  153465. +**
  153466. +** gcmSETFIELDVALUE
  153467. +**
  153468. +** Set the value of a field within specified data with a
  153469. +** predefined value.
  153470. +**
  153471. +** ARGUMENTS:
  153472. +**
  153473. +** data Data value.
  153474. +** reg Name of register.
  153475. +** field Name of field within register.
  153476. +** value Name of the value within the field.
  153477. +*/
  153478. +#define gcmSETFIELDVALUE(data, reg, field, value) \
  153479. +( \
  153480. + (((gctUINT32) (data)) \
  153481. + & ~__gcmALIGN(__gcmMASK(reg##_##field), reg##_##field)) \
  153482. + | __gcmALIGN(reg##_##field##_##value \
  153483. + & __gcmMASK(reg##_##field), reg##_##field) \
  153484. +)
  153485. +
  153486. +/*******************************************************************************
  153487. +**
  153488. +** gcmGETMASKEDFIELDMASK
  153489. +**
  153490. +** Determine field mask of a masked field.
  153491. +**
  153492. +** ARGUMENTS:
  153493. +**
  153494. +** reg Name of register.
  153495. +** field Name of field within register.
  153496. +*/
  153497. +#define gcmGETMASKEDFIELDMASK(reg, field) \
  153498. +( \
  153499. + gcmSETFIELD(0, reg, field, ~0) | \
  153500. + gcmSETFIELD(0, reg, MASK_ ## field, ~0) \
  153501. +)
  153502. +
  153503. +/*******************************************************************************
  153504. +**
  153505. +** gcmSETMASKEDFIELD
  153506. +**
  153507. +** Set the value of a masked field with specified data.
  153508. +**
  153509. +** ARGUMENTS:
  153510. +**
  153511. +** reg Name of register.
  153512. +** field Name of field within register.
  153513. +** value Value for field.
  153514. +*/
  153515. +#define gcmSETMASKEDFIELD(reg, field, value) \
  153516. +( \
  153517. + gcmSETFIELD (~0, reg, field, value) & \
  153518. + gcmSETFIELDVALUE(~0, reg, MASK_ ## field, ENABLED) \
  153519. +)
  153520. +
  153521. +/*******************************************************************************
  153522. +**
  153523. +** gcmSETMASKEDFIELDVALUE
  153524. +**
  153525. +** Set the value of a masked field with specified data.
  153526. +**
  153527. +** ARGUMENTS:
  153528. +**
  153529. +** reg Name of register.
  153530. +** field Name of field within register.
  153531. +** value Value for field.
  153532. +*/
  153533. +#define gcmSETMASKEDFIELDVALUE(reg, field, value) \
  153534. +( \
  153535. + gcmSETFIELDVALUE(~0, reg, field, value) & \
  153536. + gcmSETFIELDVALUE(~0, reg, MASK_ ## field, ENABLED) \
  153537. +)
  153538. +
  153539. +/*******************************************************************************
  153540. +**
  153541. +** gcmVERIFYFIELDVALUE
  153542. +**
  153543. +** Verify if the value of a field within specified data equals a
  153544. +** predefined value.
  153545. +**
  153546. +** ARGUMENTS:
  153547. +**
  153548. +** data Data value.
  153549. +** reg Name of register.
  153550. +** field Name of field within register.
  153551. +** value Name of the value within the field.
  153552. +*/
  153553. +#define gcmVERIFYFIELDVALUE(data, reg, field, value) \
  153554. +( \
  153555. + (((gctUINT32) (data)) >> __gcmSTART(reg##_##field) & \
  153556. + __gcmMASK(reg##_##field)) \
  153557. + == \
  153558. + (reg##_##field##_##value & __gcmMASK(reg##_##field)) \
  153559. +)
  153560. +
  153561. +/*******************************************************************************
  153562. +** Bit field macros.
  153563. +*/
  153564. +
  153565. +#define __gcmSTARTBIT(Field) \
  153566. + ( 1 ? Field )
  153567. +
  153568. +#define __gcmBITSIZE(Field) \
  153569. + ( 0 ? Field )
  153570. +
  153571. +#define __gcmBITMASK(Field) \
  153572. +( \
  153573. + (1 << __gcmBITSIZE(Field)) - 1 \
  153574. +)
  153575. +
  153576. +#define gcmGETBITS(Value, Type, Field) \
  153577. +( \
  153578. + ( ((Type) (Value)) >> __gcmSTARTBIT(Field) ) \
  153579. + & \
  153580. + __gcmBITMASK(Field) \
  153581. +)
  153582. +
  153583. +#define gcmSETBITS(Value, Type, Field, NewValue) \
  153584. +( \
  153585. + ( ((Type) (Value)) \
  153586. + & ~(__gcmBITMASK(Field) << __gcmSTARTBIT(Field)) \
  153587. + ) \
  153588. + | \
  153589. + ( ( ((Type) (NewValue)) \
  153590. + & __gcmBITMASK(Field) \
  153591. + ) << __gcmSTARTBIT(Field) \
  153592. + ) \
  153593. +)
  153594. +
  153595. +/*******************************************************************************
  153596. +**
  153597. +** gcmISINREGRANGE
  153598. +**
  153599. +** Verify whether the specified address is in the register range.
  153600. +**
  153601. +** ARGUMENTS:
  153602. +**
  153603. +** Address Address to be verified.
  153604. +** Name Name of a register.
  153605. +*/
  153606. +
  153607. +#define gcmISINREGRANGE(Address, Name) \
  153608. +( \
  153609. + ((Address & (~0U << Name ## _LSB)) == (Name ## _Address >> 2)) \
  153610. +)
  153611. +
  153612. +/*******************************************************************************
  153613. +**
  153614. +** A set of macros to aid state loading.
  153615. +**
  153616. +** ARGUMENTS:
  153617. +**
  153618. +** CommandBuffer Pointer to a gcoCMDBUF object.
  153619. +** StateDelta Pointer to a gcsSTATE_DELTA state delta structure.
  153620. +** Memory Destination memory pointer of gctUINT32_PTR type.
  153621. +** PartOfContext Whether or not the state is a part of the context.
  153622. +** FixedPoint Whether or not the state is of the fixed point format.
  153623. +** Count Number of consecutive states to be loaded.
  153624. +** Address State address.
  153625. +** Data Data to be set to the state.
  153626. +*/
  153627. +
  153628. +/*----------------------------------------------------------------------------*/
  153629. +
  153630. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  153631. +
  153632. +# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count) \
  153633. + CommandBuffer->lastLoadStatePtr = gcmPTR_TO_UINT64(Memory); \
  153634. + CommandBuffer->lastLoadStateAddress = Address; \
  153635. + CommandBuffer->lastLoadStateCount = Count
  153636. +
  153637. +# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address) \
  153638. + gcmASSERT( \
  153639. + (gctUINT) (Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastLoadStatePtr, gctUINT32_PTR) - 1) \
  153640. + == \
  153641. + (gctUINT) (Address - CommandBuffer->lastLoadStateAddress) \
  153642. + ); \
  153643. + \
  153644. + gcmASSERT(CommandBuffer->lastLoadStateCount > 0); \
  153645. + \
  153646. + CommandBuffer->lastLoadStateCount -= 1
  153647. +
  153648. +# define gcmVERIFYLOADSTATEDONE(CommandBuffer) \
  153649. + gcmASSERT(CommandBuffer->lastLoadStateCount == 0)
  153650. +
  153651. +#else
  153652. +
  153653. +# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count)
  153654. +# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address)
  153655. +# define gcmVERIFYLOADSTATEDONE(CommandBuffer)
  153656. +
  153657. +#endif
  153658. +
  153659. +#if gcdSECURE_USER
  153660. +
  153661. +# define gcmDEFINESECUREUSER() \
  153662. + gctUINT __secure_user_offset__; \
  153663. + gctUINT32_PTR __secure_user_hintArray__;
  153664. +
  153665. +# define gcmBEGINSECUREUSER() \
  153666. + __secure_user_offset__ = reserve->lastOffset; \
  153667. + \
  153668. + __secure_user_hintArray__ = gcmUINT64_TO_PTR(reserve->hintArrayTail)
  153669. +
  153670. +# define gcmENDSECUREUSER() \
  153671. + reserve->hintArrayTail = gcmPTR_TO_UINT64(__secure_user_hintArray__)
  153672. +
  153673. +# define gcmSKIPSECUREUSER() \
  153674. + __secure_user_offset__ += gcmSIZEOF(gctUINT32)
  153675. +
  153676. +# define gcmUPDATESECUREUSER() \
  153677. + *__secure_user_hintArray__ = __secure_user_offset__; \
  153678. + \
  153679. + __secure_user_offset__ += gcmSIZEOF(gctUINT32); \
  153680. + __secure_user_hintArray__ += 1
  153681. +
  153682. +#else
  153683. +
  153684. +# define gcmDEFINESECUREUSER()
  153685. +# define gcmBEGINSECUREUSER()
  153686. +# define gcmENDSECUREUSER()
  153687. +# define gcmSKIPSECUREUSER()
  153688. +# define gcmUPDATESECUREUSER()
  153689. +
  153690. +#endif
  153691. +
  153692. +/*----------------------------------------------------------------------------*/
  153693. +
  153694. +#if gcdDUMP
  153695. +# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data) \
  153696. + if (FixedPoint) \
  153697. + { \
  153698. + gcmDUMP(gcvNULL, "@[state.x 0x%04X 0x%08X]", \
  153699. + Address, Data \
  153700. + ); \
  153701. + } \
  153702. + else \
  153703. + { \
  153704. + gcmDUMP(gcvNULL, "@[state 0x%04X 0x%08X]", \
  153705. + Address, Data \
  153706. + ); \
  153707. + }
  153708. +#else
  153709. +# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data)
  153710. +#endif
  153711. +
  153712. +/*----------------------------------------------------------------------------*/
  153713. +
  153714. +#define gcmDEFINESTATEBUFFER(CommandBuffer, StateDelta, Memory, ReserveSize) \
  153715. + gcmDEFINESECUREUSER() \
  153716. + gctSIZE_T ReserveSize; \
  153717. + gcoCMDBUF CommandBuffer; \
  153718. + gctUINT32_PTR Memory; \
  153719. + gcsSTATE_DELTA_PTR StateDelta
  153720. +
  153721. +#define gcmBEGINSTATEBUFFER(Hardware, CommandBuffer, StateDelta, Memory, ReserveSize) \
  153722. +{ \
  153723. + gcmONERROR(gcoBUFFER_Reserve( \
  153724. + Hardware->buffer, ReserveSize, gcvTRUE, &CommandBuffer \
  153725. + )); \
  153726. + \
  153727. + Memory = gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \
  153728. + \
  153729. + StateDelta = Hardware->delta; \
  153730. + \
  153731. + gcmBEGINSECUREUSER(); \
  153732. +}
  153733. +
  153734. +#define gcmENDSTATEBUFFER(CommandBuffer, Memory, ReserveSize) \
  153735. +{ \
  153736. + gcmENDSECUREUSER(); \
  153737. + \
  153738. + gcmASSERT( \
  153739. + gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT8_PTR) + ReserveSize \
  153740. + == \
  153741. + (gctUINT8_PTR) Memory \
  153742. + ); \
  153743. +}
  153744. +
  153745. +/*----------------------------------------------------------------------------*/
  153746. +
  153747. +#define gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, Count) \
  153748. +{ \
  153749. + gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
  153750. + gcmASSERT((gctUINT32)Count <= 1024); \
  153751. + \
  153752. + gcmVERIFYLOADSTATEDONE(CommandBuffer); \
  153753. + \
  153754. + gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count); \
  153755. + \
  153756. + *Memory++ \
  153757. + = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \
  153758. + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
  153759. + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
  153760. + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
  153761. + \
  153762. + gcmSKIPSECUREUSER(); \
  153763. +}
  153764. +
  153765. +#define gcmENDSTATEBATCH(CommandBuffer, Memory) \
  153766. +{ \
  153767. + gcmVERIFYLOADSTATEDONE(CommandBuffer); \
  153768. + \
  153769. + gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
  153770. +}
  153771. +
  153772. +/*----------------------------------------------------------------------------*/
  153773. +
  153774. +#define gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
  153775. + Address, Data) \
  153776. +{ \
  153777. + gctUINT32 __temp_data32__; \
  153778. + \
  153779. + gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
  153780. + \
  153781. + __temp_data32__ = Data; \
  153782. + \
  153783. + *Memory++ = __temp_data32__; \
  153784. + \
  153785. + gcoHARDWARE_UpdateDelta( \
  153786. + StateDelta, FixedPoint, Address, 0, __temp_data32__ \
  153787. + ); \
  153788. + \
  153789. + gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
  153790. + \
  153791. + gcmUPDATESECUREUSER(); \
  153792. +}
  153793. +
  153794. +#define gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data) \
  153795. +{ \
  153796. + gctUINT32 __temp_data32__; \
  153797. + \
  153798. + gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
  153799. + \
  153800. + __temp_data32__ = Data; \
  153801. + \
  153802. + *Memory++ = __temp_data32__; \
  153803. + \
  153804. + gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
  153805. + \
  153806. + gcmSKIPSECUREUSER(); \
  153807. +}
  153808. +
  153809. +#define gcmSETFILLER(CommandBuffer, Memory) \
  153810. +{ \
  153811. + gcmVERIFYLOADSTATEDONE(CommandBuffer); \
  153812. + \
  153813. + Memory += 1; \
  153814. + \
  153815. + gcmSKIPSECUREUSER(); \
  153816. +}
  153817. +
  153818. +/*----------------------------------------------------------------------------*/
  153819. +
  153820. +#define gcmSETSINGLESTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
  153821. + Address, Data) \
  153822. +{ \
  153823. + gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
  153824. + gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
  153825. + Address, Data); \
  153826. + gcmENDSTATEBATCH(CommandBuffer, Memory); \
  153827. +}
  153828. +
  153829. +#define gcmSETSINGLECTRLSTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
  153830. + Address, Data) \
  153831. +{ \
  153832. + gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
  153833. + gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data); \
  153834. + gcmENDSTATEBATCH(CommandBuffer, Memory); \
  153835. +}
  153836. +
  153837. +
  153838. +/*******************************************************************************
  153839. +**
  153840. +** gcmSETSTARTDECOMMAND
  153841. +**
  153842. +** Form a START_DE command.
  153843. +**
  153844. +** ARGUMENTS:
  153845. +**
  153846. +** Memory Destination memory pointer of gctUINT32_PTR type.
  153847. +** Count Number of the rectangles.
  153848. +*/
  153849. +
  153850. +#define gcmSETSTARTDECOMMAND(Memory, Count) \
  153851. +{ \
  153852. + *Memory++ \
  153853. + = gcmSETFIELDVALUE(0, AQ_COMMAND_START_DE_COMMAND, OPCODE, START_DE) \
  153854. + | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, COUNT, Count) \
  153855. + | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, DATA_COUNT, 0); \
  153856. + \
  153857. + *Memory++ = 0xDEADDEED; \
  153858. +}
  153859. +
  153860. +/******************************************************************************\
  153861. +******************************** Ceiling Macro ********************************
  153862. +\******************************************************************************/
  153863. +#define gcmCEIL(x) ((x - (gctUINT32)x) == 0 ? (gctUINT32)x : (gctUINT32)x + 1)
  153864. +
  153865. +/******************************************************************************\
  153866. +******************************** Min/Max Macros ********************************
  153867. +\******************************************************************************/
  153868. +
  153869. +#define gcmMIN(x, y) (((x) <= (y)) ? (x) : (y))
  153870. +#define gcmMAX(x, y) (((x) >= (y)) ? (x) : (y))
  153871. +#define gcmCLAMP(x, min, max) (((x) < (min)) ? (min) : \
  153872. + ((x) > (max)) ? (max) : (x))
  153873. +#define gcmABS(x) (((x) < 0) ? -(x) : (x))
  153874. +#define gcmNEG(x) (((x) < 0) ? (x) : -(x))
  153875. +
  153876. +/*******************************************************************************
  153877. +**
  153878. +** gcmPTR2INT
  153879. +**
  153880. +** Convert a pointer to an integer value.
  153881. +**
  153882. +** ARGUMENTS:
  153883. +**
  153884. +** p Pointer value.
  153885. +*/
  153886. +#if defined(_WIN32) || (defined(__LP64__) && __LP64__)
  153887. +# define gcmPTR2INT(p) \
  153888. + ( \
  153889. + (gctUINT32) (gctUINT64) (p) \
  153890. + )
  153891. +#else
  153892. +# define gcmPTR2INT(p) \
  153893. + ( \
  153894. + (gctUINT32) (p) \
  153895. + )
  153896. +#endif
  153897. +
  153898. +/*******************************************************************************
  153899. +**
  153900. +** gcmINT2PTR
  153901. +**
  153902. +** Convert an integer value into a pointer.
  153903. +**
  153904. +** ARGUMENTS:
  153905. +**
  153906. +** v Integer value.
  153907. +*/
  153908. +#ifdef __LP64__
  153909. +# define gcmINT2PTR(i) \
  153910. + ( \
  153911. + (gctPOINTER) (gctINT64) (i) \
  153912. + )
  153913. +#else
  153914. +# define gcmINT2PTR(i) \
  153915. + ( \
  153916. + (gctPOINTER) (i) \
  153917. + )
  153918. +#endif
  153919. +
  153920. +/*******************************************************************************
  153921. +**
  153922. +** gcmOFFSETOF
  153923. +**
  153924. +** Compute the byte offset of a field inside a structure.
  153925. +**
  153926. +** ARGUMENTS:
  153927. +**
  153928. +** s Structure name.
  153929. +** field Field name.
  153930. +*/
  153931. +#define gcmOFFSETOF(s, field) \
  153932. +( \
  153933. + gcmPTR2INT(& (((struct s *) 0)->field)) \
  153934. +)
  153935. +
  153936. +#define gcmSWAB32(x) ((gctUINT32)( \
  153937. + (((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \
  153938. + (((gctUINT32)(x) & (gctUINT32)0x0000FF00UL) << 8) | \
  153939. + (((gctUINT32)(x) & (gctUINT32)0x00FF0000UL) >> 8) | \
  153940. + (((gctUINT32)(x) & (gctUINT32)0xFF000000UL) >> 24)))
  153941. +
  153942. +/*******************************************************************************
  153943. +***** Database ****************************************************************/
  153944. +
  153945. +typedef struct _gcsDATABASE_COUNTERS
  153946. +{
  153947. + /* Number of currently allocated bytes. */
  153948. + gctUINT64 bytes;
  153949. +
  153950. + /* Maximum number of bytes allocated (memory footprint). */
  153951. + gctUINT64 maxBytes;
  153952. +
  153953. + /* Total number of bytes allocated. */
  153954. + gctUINT64 totalBytes;
  153955. +}
  153956. +gcsDATABASE_COUNTERS;
  153957. +
  153958. +typedef struct _gcuDATABASE_INFO
  153959. +{
  153960. + /* Counters. */
  153961. + gcsDATABASE_COUNTERS counters;
  153962. +
  153963. + /* Time value. */
  153964. + gctUINT64 time;
  153965. +}
  153966. +gcuDATABASE_INFO;
  153967. +
  153968. +/*******************************************************************************
  153969. +***** Frame database **********************************************************/
  153970. +
  153971. +/* gcsHAL_FRAME_INFO */
  153972. +typedef struct _gcsHAL_FRAME_INFO
  153973. +{
  153974. + /* Current timer tick. */
  153975. + OUT gctUINT64 ticks;
  153976. +
  153977. + /* Bandwidth counters. */
  153978. + OUT gctUINT readBytes8[8];
  153979. + OUT gctUINT writeBytes8[8];
  153980. +
  153981. + /* Counters. */
  153982. + OUT gctUINT cycles[8];
  153983. + OUT gctUINT idleCycles[8];
  153984. + OUT gctUINT mcCycles[8];
  153985. + OUT gctUINT readRequests[8];
  153986. + OUT gctUINT writeRequests[8];
  153987. +
  153988. + /* FE counters. */
  153989. + OUT gctUINT drawCount;
  153990. + OUT gctUINT vertexOutCount;
  153991. + OUT gctUINT vertexMissCount;
  153992. +
  153993. + /* 3D counters. */
  153994. + OUT gctUINT vertexCount;
  153995. + OUT gctUINT primitiveCount;
  153996. + OUT gctUINT rejectedPrimitives;
  153997. + OUT gctUINT culledPrimitives;
  153998. + OUT gctUINT clippedPrimitives;
  153999. + OUT gctUINT droppedPrimitives;
  154000. + OUT gctUINT frustumClippedPrimitives;
  154001. + OUT gctUINT outPrimitives;
  154002. + OUT gctUINT inPrimitives;
  154003. + OUT gctUINT culledQuadCount;
  154004. + OUT gctUINT totalQuadCount;
  154005. + OUT gctUINT quadCount;
  154006. + OUT gctUINT totalPixelCount;
  154007. +
  154008. + /* PE counters. */
  154009. + OUT gctUINT colorKilled[8];
  154010. + OUT gctUINT colorDrawn[8];
  154011. + OUT gctUINT depthKilled[8];
  154012. + OUT gctUINT depthDrawn[8];
  154013. +
  154014. + /* Shader counters. */
  154015. + OUT gctUINT shaderCycles;
  154016. + OUT gctUINT vsInstructionCount;
  154017. + OUT gctUINT vsTextureCount;
  154018. + OUT gctUINT vsBranchCount;
  154019. + OUT gctUINT vsVertices;
  154020. + OUT gctUINT psInstructionCount;
  154021. + OUT gctUINT psTextureCount;
  154022. + OUT gctUINT psBranchCount;
  154023. + OUT gctUINT psPixels;
  154024. +
  154025. + /* Texture counters. */
  154026. + OUT gctUINT bilinearRequests;
  154027. + OUT gctUINT trilinearRequests;
  154028. + OUT gctUINT txBytes8[2];
  154029. + OUT gctUINT txHitCount;
  154030. + OUT gctUINT txMissCount;
  154031. +}
  154032. +gcsHAL_FRAME_INFO;
  154033. +
  154034. +typedef enum _gcePATCH_ID
  154035. +{
  154036. + gcePATCH_UNKNOWN = 0xFFFFFFFF,
  154037. +
  154038. + /* Benchmark list*/
  154039. + gcePATCH_GLB11 = 0x0,
  154040. + gcePATCH_GLB21,
  154041. + gcePATCH_GLB25,
  154042. + gcePATCH_GLB27,
  154043. +
  154044. + gcePATCH_BM21,
  154045. + gcePATCH_MM,
  154046. + gcePATCH_MM06,
  154047. + gcePATCH_MM07,
  154048. + gcePATCH_QUADRANT,
  154049. + gcePATCH_ANTUTU,
  154050. + gcePATCH_SMARTBENCH,
  154051. + gcePATCH_JPCT,
  154052. + gcePATCH_NENAMARK,
  154053. + gcePATCH_NENAMARK2,
  154054. + gcePATCH_NEOCORE,
  154055. + gcePATCH_GLB,
  154056. + gcePATCH_GB,
  154057. + gcePATCH_RTESTVA,
  154058. + gcePATCH_BMX,
  154059. + gcePATCH_BMGUI,
  154060. +
  154061. + /* Game list */
  154062. + gcePATCH_NBA2013,
  154063. + gcePATCH_BARDTALE,
  154064. + gcePATCH_BUSPARKING3D,
  154065. + gcePATCH_FISHBOODLE,
  154066. + gcePATCH_SUBWAYSURFER,
  154067. + gcePATCH_HIGHWAYDRIVER,
  154068. + gcePATCH_PREMIUM,
  154069. + gcePATCH_RACEILLEGAL,
  154070. + gcePATCH_BLABLA,
  154071. + gcePATCH_MEGARUN,
  154072. + gcePATCH_GALAXYONFIRE2,
  154073. + gcePATCH_GLOFTR3HM,
  154074. + gcePATCH_GLOFTSXHM,
  154075. + gcePATCH_GLOFTF3HM,
  154076. + gcePATCH_GLOFTGANG,
  154077. + gcePATCH_XRUNNER,
  154078. + gcePATCH_WP,
  154079. + gcePATCH_DEVIL,
  154080. + gcePATCH_HOLYARCH,
  154081. + gcePATCH_MUSE,
  154082. + gcePATCH_SG,
  154083. + gcePATCH_SIEGECRAFT,
  154084. + gcePATCH_CARCHALLENGE,
  154085. + gcePATCH_HEROESCALL,
  154086. + gcePATCH_MONOPOLY,
  154087. + gcePATCH_CTGL20,
  154088. + gcePATCH_FIREFOX,
  154089. + gcePATCH_CHORME,
  154090. + gcePATCH_DUOKANTV,
  154091. + gcePATCH_TESTAPP,
  154092. + gcePATCH_GOOGLEEARTH,
  154093. +
  154094. + /* Count enum*/
  154095. + gcePATCH_COUNT,
  154096. +}
  154097. +gcePATCH_ID;
  154098. +
  154099. +#if gcdLINK_QUEUE_SIZE
  154100. +typedef struct _gckLINKDATA * gckLINKDATA;
  154101. +struct _gckLINKDATA
  154102. +{
  154103. + gctUINT32 start;
  154104. + gctUINT32 end;
  154105. + gctINT pid;
  154106. +};
  154107. +
  154108. +typedef struct _gckLINKQUEUE * gckLINKQUEUE;
  154109. +struct _gckLINKQUEUE
  154110. +{
  154111. + struct _gckLINKDATA data[gcdLINK_QUEUE_SIZE];
  154112. + gctUINT32 rear;
  154113. + gctUINT32 front;
  154114. + gctUINT32 count;
  154115. +};
  154116. +#endif
  154117. +
  154118. +#ifdef __cplusplus
  154119. +}
  154120. +#endif
  154121. +
  154122. +#endif /* __gc_hal_types_h_ */
  154123. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
  154124. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h 1969-12-31 18:00:00.000000000 -0600
  154125. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h 2014-12-08 00:31:53.472418001 -0600
  154126. @@ -0,0 +1,37 @@
  154127. +/****************************************************************************
  154128. +*
  154129. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  154130. +*
  154131. +* This program is free software; you can redistribute it and/or modify
  154132. +* it under the terms of the GNU General Public License as published by
  154133. +* the Free Software Foundation; either version 2 of the license, or
  154134. +* (at your option) any later version.
  154135. +*
  154136. +* This program is distributed in the hope that it will be useful,
  154137. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  154138. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  154139. +* GNU General Public License for more details.
  154140. +*
  154141. +* You should have received a copy of the GNU General Public License
  154142. +* along with this program; if not write to the Free Software
  154143. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  154144. +*
  154145. +*****************************************************************************/
  154146. +
  154147. +
  154148. +#ifndef __gc_hal_version_h_
  154149. +#define __gc_hal_version_h_
  154150. +
  154151. +#define gcvVERSION_MAJOR 4
  154152. +
  154153. +#define gcvVERSION_MINOR 6
  154154. +
  154155. +#define gcvVERSION_PATCH 9
  154156. +
  154157. +#define gcvVERSION_BUILD 9754
  154158. +
  154159. +#define gcvVERSION_DATE __DATE__
  154160. +
  154161. +#define gcvVERSION_TIME __TIME__
  154162. +
  154163. +#endif /* __gc_hal_version_h_ */
  154164. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
  154165. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h 1969-12-31 18:00:00.000000000 -0600
  154166. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h 2014-12-08 00:31:53.472418001 -0600
  154167. @@ -0,0 +1,913 @@
  154168. +/****************************************************************************
  154169. +*
  154170. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  154171. +*
  154172. +* This program is free software; you can redistribute it and/or modify
  154173. +* it under the terms of the GNU General Public License as published by
  154174. +* the Free Software Foundation; either version 2 of the license, or
  154175. +* (at your option) any later version.
  154176. +*
  154177. +* This program is distributed in the hope that it will be useful,
  154178. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  154179. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  154180. +* GNU General Public License for more details.
  154181. +*
  154182. +* You should have received a copy of the GNU General Public License
  154183. +* along with this program; if not write to the Free Software
  154184. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  154185. +*
  154186. +*****************************************************************************/
  154187. +
  154188. +
  154189. +#ifndef __gc_hal_vg_h_
  154190. +#define __gc_hal_vg_h_
  154191. +
  154192. +#ifdef __cplusplus
  154193. +extern "C" {
  154194. +#endif
  154195. +
  154196. +
  154197. +#include "gc_hal_rename.h"
  154198. +#include "gc_hal_types.h"
  154199. +#include "gc_hal_enum.h"
  154200. +#include "gc_hal_base.h"
  154201. +
  154202. +#if gcdENABLE_VG
  154203. +
  154204. +/* Thread routine type. */
  154205. +#if defined(LINUX)
  154206. + typedef gctINT gctTHREADFUNCRESULT;
  154207. + typedef gctPOINTER gctTHREADFUNCPARAMETER;
  154208. +# define gctTHREADFUNCTYPE
  154209. +#elif defined(WIN32)
  154210. + typedef gctUINT gctTHREADFUNCRESULT;
  154211. + typedef gctPOINTER gctTHREADFUNCPARAMETER;
  154212. +# define gctTHREADFUNCTYPE __stdcall
  154213. +#elif defined(__QNXNTO__)
  154214. + typedef void * gctTHREADFUNCRESULT;
  154215. + typedef gctPOINTER gctTHREADFUNCPARAMETER;
  154216. +# define gctTHREADFUNCTYPE
  154217. +#endif
  154218. +
  154219. +typedef gctTHREADFUNCRESULT (gctTHREADFUNCTYPE * gctTHREADFUNC) (
  154220. + gctTHREADFUNCPARAMETER ThreadParameter
  154221. + );
  154222. +
  154223. +
  154224. +#if defined(gcvDEBUG)
  154225. +# undef gcvDEBUG
  154226. +#endif
  154227. +
  154228. +#define gcdFORCE_DEBUG 0
  154229. +#define gcdFORCE_MESSAGES 0
  154230. +
  154231. +
  154232. +#if DBG || defined(DEBUG) || defined(_DEBUG) || gcdFORCE_DEBUG
  154233. +# define gcvDEBUG 1
  154234. +#else
  154235. +# define gcvDEBUG 0
  154236. +#endif
  154237. +
  154238. +#define _gcmERROR_RETURN(prefix, func) \
  154239. + status = func; \
  154240. + if (gcmIS_ERROR(status)) \
  154241. + { \
  154242. + prefix##PRINT_VERSION(); \
  154243. + prefix##TRACE(gcvLEVEL_ERROR, \
  154244. + #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
  154245. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  154246. + return status; \
  154247. + } \
  154248. + do { } while (gcvFALSE)
  154249. +
  154250. +#define gcmERROR_RETURN(func) _gcmERROR_RETURN(gcm, func)
  154251. +
  154252. +#define gcmLOG_LOCATION()
  154253. +
  154254. +#define gcmkIS_ERROR(status) (status < 0)
  154255. +
  154256. +#define gcmALIGNDOWN(n, align) \
  154257. +( \
  154258. + (n) & ~((align) - 1) \
  154259. +)
  154260. +
  154261. +#define gcmIS_VALID_INDEX(Index, Array) \
  154262. + (((gctUINT) (Index)) < gcmCOUNTOF(Array))
  154263. +
  154264. +
  154265. +#define gcmIS_NAN(x) \
  154266. +( \
  154267. + ((* (gctUINT32_PTR) &(x)) & 0x7FFFFFFF) == 0x7FFFFFFF \
  154268. +)
  154269. +
  154270. +#define gcmLERP(v1, v2, w) \
  154271. + ((v1) * (w) + (v2) * (1.0f - (w)))
  154272. +
  154273. +#define gcmINTERSECT(Start1, Start2, Length) \
  154274. + (gcmABS((Start1) - (Start2)) < (Length))
  154275. +
  154276. +/*******************************************************************************
  154277. +**
  154278. +** gcmERR_GOTO
  154279. +**
  154280. +** Prints a message and terminates the current loop on error.
  154281. +**
  154282. +** ASSUMPTIONS:
  154283. +**
  154284. +** 'status' variable of gceSTATUS type must be defined.
  154285. +**
  154286. +** ARGUMENTS:
  154287. +**
  154288. +** Function
  154289. +** Function to evaluate.
  154290. +*/
  154291. +
  154292. +#define gcmERR_GOTO(Function) \
  154293. + status = Function; \
  154294. + if (gcmIS_ERROR(status)) \
  154295. + { \
  154296. + gcmTRACE( \
  154297. + gcvLEVEL_ERROR, \
  154298. + "gcmERR_GOTO: status=%d @ line=%d in function %s.\n", \
  154299. + status, __LINE__, __FUNCTION__ \
  154300. + ); \
  154301. + goto ErrorHandler; \
  154302. + }
  154303. +
  154304. +#if gcvDEBUG || gcdFORCE_MESSAGES
  154305. +# define gcmVERIFY_BOOLEAN(Expression) \
  154306. + gcmASSERT( \
  154307. + ( (Expression) == gcvFALSE ) || \
  154308. + ( (Expression) == gcvTRUE ) \
  154309. + )
  154310. +#else
  154311. +# define gcmVERIFY_BOOLEAN(Expression)
  154312. +#endif
  154313. +
  154314. +/*******************************************************************************
  154315. +**
  154316. +** gcmVERIFYFIELDFIT
  154317. +**
  154318. +** Verify whether the value fits in the field.
  154319. +**
  154320. +** ARGUMENTS:
  154321. +**
  154322. +** data Data value.
  154323. +** reg Name of register.
  154324. +** field Name of field within register.
  154325. +** value Value for field.
  154326. +*/
  154327. +#define gcmVERIFYFIELDFIT(reg, field, value) \
  154328. + gcmASSERT( \
  154329. + (value) <= gcmFIELDMAX(reg, field) \
  154330. + )
  154331. +/*******************************************************************************
  154332. +**
  154333. +** gcmFIELDMAX
  154334. +**
  154335. +** Get field maximum value.
  154336. +**
  154337. +** ARGUMENTS:
  154338. +**
  154339. +** reg Name of register.
  154340. +** field Name of field within register.
  154341. +*/
  154342. +#define gcmFIELDMAX(reg, field) \
  154343. +( \
  154344. + (gctUINT32) \
  154345. + ( \
  154346. + (__gcmGETSIZE(reg##_##field) == 32) \
  154347. + ? ~0 \
  154348. + : (~(~0 << __gcmGETSIZE(reg##_##field))) \
  154349. + ) \
  154350. +)
  154351. +
  154352. +
  154353. +/* ANSI C does not have the 'f' functions, define replacements here. */
  154354. +#define gcmSINF(x) ((gctFLOAT) sin(x))
  154355. +#define gcmCOSF(x) ((gctFLOAT) cos(x))
  154356. +#define gcmASINF(x) ((gctFLOAT) asin(x))
  154357. +#define gcmACOSF(x) ((gctFLOAT) acos(x))
  154358. +#define gcmSQRTF(x) ((gctFLOAT) sqrt(x))
  154359. +#define gcmFABSF(x) ((gctFLOAT) fabs(x))
  154360. +#define gcmFMODF(x, y) ((gctFLOAT) fmod((x), (y)))
  154361. +#define gcmCEILF(x) ((gctFLOAT) ceil(x))
  154362. +#define gcmFLOORF(x) ((gctFLOAT) floor(x))
  154363. +
  154364. +
  154365. +
  154366. +/* Fixed point constants. */
  154367. +#define gcvZERO_X ((gctFIXED_POINT) 0x00000000)
  154368. +#define gcvHALF_X ((gctFIXED_POINT) 0x00008000)
  154369. +#define gcvONE_X ((gctFIXED_POINT) 0x00010000)
  154370. +#define gcvNEGONE_X ((gctFIXED_POINT) 0xFFFF0000)
  154371. +#define gcvTWO_X ((gctFIXED_POINT) 0x00020000)
  154372. +
  154373. +/* Integer constants. */
  154374. +#define gcvMAX_POS_INT ((gctINT) 0x7FFFFFFF)
  154375. +#define gcvMAX_NEG_INT ((gctINT) 0x80000000)
  154376. +
  154377. +/* Float constants. */
  154378. +#define gcvMAX_POS_FLOAT ((gctFLOAT) 3.4028235e+038)
  154379. +#define gcvMAX_NEG_FLOAT ((gctFLOAT) -3.4028235e+038)
  154380. +
  154381. +/******************************************************************************\
  154382. +***************************** Miscellaneous Macro ******************************
  154383. +\******************************************************************************/
  154384. +
  154385. +#define gcmKB2BYTES(Kilobyte) \
  154386. +( \
  154387. + (Kilobyte) << 10 \
  154388. +)
  154389. +
  154390. +#define gcmMB2BYTES(Megabyte) \
  154391. +( \
  154392. + (Megabyte) << 20 \
  154393. +)
  154394. +
  154395. +#define gcmMAT(Matrix, Row, Column) \
  154396. +( \
  154397. + (Matrix) [(Row) * 3 + (Column)] \
  154398. +)
  154399. +
  154400. +#define gcmMAKE2CHAR(Char1, Char2) \
  154401. +( \
  154402. + ((gctUINT16) (gctUINT8) (Char1) << 0) | \
  154403. + ((gctUINT16) (gctUINT8) (Char2) << 8) \
  154404. +)
  154405. +
  154406. +#define gcmMAKE4CHAR(Char1, Char2, Char3, Char4) \
  154407. +( \
  154408. + ((gctUINT32)(gctUINT8) (Char1) << 0) | \
  154409. + ((gctUINT32)(gctUINT8) (Char2) << 8) | \
  154410. + ((gctUINT32)(gctUINT8) (Char3) << 16) | \
  154411. + ((gctUINT32)(gctUINT8) (Char4) << 24) \
  154412. +)
  154413. +
  154414. +/* some platforms need to fix the physical address for HW to access*/
  154415. +#define gcmFIXADDRESS(address) \
  154416. +(\
  154417. + (address)\
  154418. +)
  154419. +
  154420. +#define gcmkFIXADDRESS(address) \
  154421. +(\
  154422. + (address)\
  154423. +)
  154424. +
  154425. +/******************************************************************************\
  154426. +****************************** Kernel Debug Macro ******************************
  154427. +\******************************************************************************/
  154428. +
  154429. +/* Set signal to signaled state for specified process. */
  154430. +gceSTATUS
  154431. +gckOS_SetSignal(
  154432. + IN gckOS Os,
  154433. + IN gctHANDLE Process,
  154434. + IN gctSIGNAL Signal
  154435. + );
  154436. +
  154437. +/* Return the kernel logical pointer for the given physical one. */
  154438. +gceSTATUS
  154439. +gckOS_GetKernelLogical(
  154440. + IN gckOS Os,
  154441. + IN gctUINT32 Address,
  154442. + OUT gctPOINTER * KernelPointer
  154443. + );
  154444. +
  154445. +/* Return the kernel logical pointer for the given physical one. */
  154446. +gceSTATUS
  154447. +gckOS_GetKernelLogicalEx(
  154448. + IN gckOS Os,
  154449. + IN gceCORE Core,
  154450. + IN gctUINT32 Address,
  154451. + OUT gctPOINTER * KernelPointer
  154452. + );
  154453. +
  154454. +/*----------------------------------------------------------------------------*/
  154455. +/*----------------------------- Semaphore Object -----------------------------*/
  154456. +
  154457. +/* Increment the value of a semaphore. */
  154458. +gceSTATUS
  154459. +gckOS_IncrementSemaphore(
  154460. + IN gckOS Os,
  154461. + IN gctSEMAPHORE Semaphore
  154462. + );
  154463. +
  154464. +/* Decrement the value of a semaphore (waiting might occur). */
  154465. +gceSTATUS
  154466. +gckOS_DecrementSemaphore(
  154467. + IN gckOS Os,
  154468. + IN gctSEMAPHORE Semaphore
  154469. + );
  154470. +
  154471. +
  154472. +/*----------------------------------------------------------------------------*/
  154473. +/*------------------------------- Thread Object ------------------------------*/
  154474. +
  154475. +/* Start a thread. */
  154476. +gceSTATUS
  154477. +gckOS_StartThread(
  154478. + IN gckOS Os,
  154479. + IN gctTHREADFUNC ThreadFunction,
  154480. + IN gctPOINTER ThreadParameter,
  154481. + OUT gctTHREAD * Thread
  154482. + );
  154483. +
  154484. +/* Stop a thread. */
  154485. +gceSTATUS
  154486. +gckOS_StopThread(
  154487. + IN gckOS Os,
  154488. + IN gctTHREAD Thread
  154489. + );
  154490. +
  154491. +/* Verify whether the thread is still running. */
  154492. +gceSTATUS
  154493. +gckOS_VerifyThread(
  154494. + IN gckOS Os,
  154495. + IN gctTHREAD Thread
  154496. + );
  154497. +
  154498. +
  154499. +/* Construct a new gckVGKERNEL object. */
  154500. +gceSTATUS
  154501. +gckVGKERNEL_Construct(
  154502. + IN gckOS Os,
  154503. + IN gctPOINTER Context,
  154504. + IN gckKERNEL inKernel,
  154505. + OUT gckVGKERNEL * Kernel
  154506. + );
  154507. +
  154508. +/* Destroy an gckVGKERNEL object. */
  154509. +gceSTATUS
  154510. +gckVGKERNEL_Destroy(
  154511. + IN gckVGKERNEL Kernel
  154512. + );
  154513. +
  154514. +/* Allocate linear video memory. */
  154515. +gceSTATUS
  154516. +gckKERNEL_AllocateLinearMemory(
  154517. + IN gckKERNEL Kernel,
  154518. + IN OUT gcePOOL * Pool,
  154519. + IN gctSIZE_T Bytes,
  154520. + IN gctSIZE_T Alignment,
  154521. + IN gceSURF_TYPE Type,
  154522. + OUT gcuVIDMEM_NODE_PTR * Node
  154523. + );
  154524. +
  154525. +/* Unmap memory. */
  154526. +gceSTATUS
  154527. +gckKERNEL_UnmapMemory(
  154528. + IN gckKERNEL Kernel,
  154529. + IN gctPHYS_ADDR Physical,
  154530. + IN gctSIZE_T Bytes,
  154531. + IN gctPOINTER Logical
  154532. + );
  154533. +
  154534. +/* Dispatch a user-level command. */
  154535. +gceSTATUS
  154536. +gckVGKERNEL_Dispatch(
  154537. + IN gckKERNEL Kernel,
  154538. + IN gctBOOL FromUser,
  154539. + IN OUT struct _gcsHAL_INTERFACE * Interface
  154540. + );
  154541. +
  154542. +/* Query command buffer requirements. */
  154543. +gceSTATUS
  154544. +gckKERNEL_QueryCommandBuffer(
  154545. + IN gckKERNEL Kernel,
  154546. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  154547. + );
  154548. +
  154549. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY
  154550. +gceSTATUS
  154551. +gckOS_MapReservedMemoryToKernel(
  154552. + IN gckOS Os,
  154553. + IN gctUINT32 Physical,
  154554. + IN gctINT Bytes,
  154555. + IN OUT gctPOINTER *Virtual
  154556. + );
  154557. +
  154558. +gceSTATUS
  154559. +gckOS_UnmapReservedMemoryFromKernel(
  154560. + IN gctPOINTER Virtual
  154561. + );
  154562. +#endif
  154563. +
  154564. +/******************************************************************************\
  154565. +******************************* gckVGHARDWARE Object ******************************
  154566. +\******************************************************************************/
  154567. +
  154568. +/* Construct a new gckVGHARDWARE object. */
  154569. +gceSTATUS
  154570. +gckVGHARDWARE_Construct(
  154571. + IN gckOS Os,
  154572. + OUT gckVGHARDWARE * Hardware
  154573. + );
  154574. +
  154575. +/* Destroy an gckVGHARDWARE object. */
  154576. +gceSTATUS
  154577. +gckVGHARDWARE_Destroy(
  154578. + IN gckVGHARDWARE Hardware
  154579. + );
  154580. +
  154581. +/* Query system memory requirements. */
  154582. +gceSTATUS
  154583. +gckVGHARDWARE_QuerySystemMemory(
  154584. + IN gckVGHARDWARE Hardware,
  154585. + OUT gctSIZE_T * SystemSize,
  154586. + OUT gctUINT32 * SystemBaseAddress
  154587. + );
  154588. +
  154589. +/* Build virtual address. */
  154590. +gceSTATUS
  154591. +gckVGHARDWARE_BuildVirtualAddress(
  154592. + IN gckVGHARDWARE Hardware,
  154593. + IN gctUINT32 Index,
  154594. + IN gctUINT32 Offset,
  154595. + OUT gctUINT32 * Address
  154596. + );
  154597. +
  154598. +/* Kickstart the command processor. */
  154599. +gceSTATUS
  154600. +gckVGHARDWARE_Execute(
  154601. + IN gckVGHARDWARE Hardware,
  154602. + IN gctUINT32 Address,
  154603. + IN gctSIZE_T Count
  154604. + );
  154605. +
  154606. +/* Query the available memory. */
  154607. +gceSTATUS
  154608. +gckVGHARDWARE_QueryMemory(
  154609. + IN gckVGHARDWARE Hardware,
  154610. + OUT gctSIZE_T * InternalSize,
  154611. + OUT gctUINT32 * InternalBaseAddress,
  154612. + OUT gctUINT32 * InternalAlignment,
  154613. + OUT gctSIZE_T * ExternalSize,
  154614. + OUT gctUINT32 * ExternalBaseAddress,
  154615. + OUT gctUINT32 * ExternalAlignment,
  154616. + OUT gctUINT32 * HorizontalTileSize,
  154617. + OUT gctUINT32 * VerticalTileSize
  154618. + );
  154619. +
  154620. +/* Query the identity of the hardware. */
  154621. +gceSTATUS
  154622. +gckVGHARDWARE_QueryChipIdentity(
  154623. + IN gckVGHARDWARE Hardware,
  154624. + OUT gceCHIPMODEL* ChipModel,
  154625. + OUT gctUINT32* ChipRevision,
  154626. + OUT gctUINT32* ChipFeatures,
  154627. + OUT gctUINT32* ChipMinorFeatures,
  154628. + OUT gctUINT32* ChipMinorFeatures1
  154629. + );
  154630. +
  154631. +/* Convert an API format. */
  154632. +gceSTATUS
  154633. +gckVGHARDWARE_ConvertFormat(
  154634. + IN gckVGHARDWARE Hardware,
  154635. + IN gceSURF_FORMAT Format,
  154636. + OUT gctUINT32 * BitsPerPixel,
  154637. + OUT gctUINT32 * BytesPerTile
  154638. + );
  154639. +
  154640. +/* Split a harwdare specific address into API stuff. */
  154641. +gceSTATUS
  154642. +gckVGHARDWARE_SplitMemory(
  154643. + IN gckVGHARDWARE Hardware,
  154644. + IN gctUINT32 Address,
  154645. + OUT gcePOOL * Pool,
  154646. + OUT gctUINT32 * Offset
  154647. + );
  154648. +
  154649. +/* Align size to tile boundary. */
  154650. +gceSTATUS
  154651. +gckVGHARDWARE_AlignToTile(
  154652. + IN gckVGHARDWARE Hardware,
  154653. + IN gceSURF_TYPE Type,
  154654. + IN OUT gctUINT32_PTR Width,
  154655. + IN OUT gctUINT32_PTR Height
  154656. + );
  154657. +
  154658. +/* Convert logical address to hardware specific address. */
  154659. +gceSTATUS
  154660. +gckVGHARDWARE_ConvertLogical(
  154661. + IN gckVGHARDWARE Hardware,
  154662. + IN gctPOINTER Logical,
  154663. + OUT gctUINT32 * Address
  154664. + );
  154665. +
  154666. +/* Program MMU. */
  154667. +gceSTATUS
  154668. +gckVGHARDWARE_SetMMU(
  154669. + IN gckVGHARDWARE Hardware,
  154670. + IN gctPOINTER Logical
  154671. + );
  154672. +
  154673. +/* Flush the MMU. */
  154674. +gceSTATUS
  154675. +gckVGHARDWARE_FlushMMU(
  154676. + IN gckVGHARDWARE Hardware
  154677. + );
  154678. +
  154679. +/* Get idle register. */
  154680. +gceSTATUS
  154681. +gckVGHARDWARE_GetIdle(
  154682. + IN gckVGHARDWARE Hardware,
  154683. + OUT gctUINT32 * Data
  154684. + );
  154685. +
  154686. +/* Flush the caches. */
  154687. +gceSTATUS
  154688. +gckVGHARDWARE_Flush(
  154689. + IN gckVGHARDWARE Hardware,
  154690. + IN gceKERNEL_FLUSH Flush,
  154691. + IN gctPOINTER Logical,
  154692. + IN OUT gctSIZE_T * Bytes
  154693. + );
  154694. +
  154695. +/* Enable/disable fast clear. */
  154696. +gceSTATUS
  154697. +gckVGHARDWARE_SetFastClear(
  154698. + IN gckVGHARDWARE Hardware,
  154699. + IN gctINT Enable
  154700. + );
  154701. +
  154702. +gceSTATUS
  154703. +gckVGHARDWARE_ReadInterrupt(
  154704. + IN gckVGHARDWARE Hardware,
  154705. + OUT gctUINT32_PTR IDs
  154706. + );
  154707. +
  154708. +/* Power management. */
  154709. +gceSTATUS
  154710. +gckVGHARDWARE_SetPowerManagementState(
  154711. + IN gckVGHARDWARE Hardware,
  154712. + IN gceCHIPPOWERSTATE State
  154713. + );
  154714. +
  154715. +gceSTATUS
  154716. +gckVGHARDWARE_QueryPowerManagementState(
  154717. + IN gckVGHARDWARE Hardware,
  154718. + OUT gceCHIPPOWERSTATE* State
  154719. + );
  154720. +
  154721. +gceSTATUS
  154722. +gckVGHARDWARE_SetPowerManagement(
  154723. + IN gckVGHARDWARE Hardware,
  154724. + IN gctBOOL PowerManagement
  154725. + );
  154726. +
  154727. +gceSTATUS
  154728. +gckVGHARDWARE_SetPowerOffTimeout(
  154729. + IN gckVGHARDWARE Hardware,
  154730. + IN gctUINT32 Timeout
  154731. + );
  154732. +
  154733. +gceSTATUS
  154734. +gckVGHARDWARE_QueryPowerOffTimeout(
  154735. + IN gckVGHARDWARE Hardware,
  154736. + OUT gctUINT32* Timeout
  154737. + );
  154738. +
  154739. +gceSTATUS
  154740. +gckVGHARDWARE_QueryIdle(
  154741. + IN gckVGHARDWARE Hardware,
  154742. + OUT gctBOOL_PTR IsIdle
  154743. + );
  154744. +/******************************************************************************\
  154745. +*************************** Command Buffer Structures **************************
  154746. +\******************************************************************************/
  154747. +
  154748. +/* Vacant command buffer marker. */
  154749. +#define gcvVACANT_BUFFER ((gcsCOMPLETION_SIGNAL_PTR) (1))
  154750. +
  154751. +/* Command buffer header. */
  154752. +typedef struct _gcsCMDBUFFER * gcsCMDBUFFER_PTR;
  154753. +typedef struct _gcsCMDBUFFER
  154754. +{
  154755. + /* Pointer to the completion signal. */
  154756. + gcsCOMPLETION_SIGNAL_PTR completion;
  154757. +
  154758. + /* The user sets this to the node of the container buffer whitin which
  154759. + this particular command buffer resides. The kernel sets this to the
  154760. + node of the internally allocated buffer. */
  154761. + gctUINT64 node;
  154762. +
  154763. + /* Command buffer hardware address. */
  154764. + gctUINT32 address;
  154765. +
  154766. + /* The offset of the buffer from the beginning of the header. */
  154767. + gctUINT32 bufferOffset;
  154768. +
  154769. + /* Size of the area allocated for the data portion of this particular
  154770. + command buffer (headers and tail reserves are excluded). */
  154771. + gctSIZE_T size;
  154772. +
  154773. + /* Offset into the buffer [0..size]; reflects exactly how much data has
  154774. + been put into the command buffer. */
  154775. + gctUINT offset;
  154776. +
  154777. + /* The number of command units in the buffer for the hardware to
  154778. + execute. */
  154779. + gctSIZE_T dataCount;
  154780. +
  154781. + /* MANAGED BY : user HAL (gcoBUFFER object).
  154782. + USED BY : user HAL (gcoBUFFER object).
  154783. + Points to the immediate next allocated command buffer. */
  154784. + gcsCMDBUFFER_PTR nextAllocated;
  154785. +
  154786. + /* MANAGED BY : user layers (HAL and drivers).
  154787. + USED BY : kernel HAL (gcoBUFFER object).
  154788. + Points to the next subbuffer if any. A family of subbuffers are chained
  154789. + together and are meant to be executed inseparably as a unit. Meaning
  154790. + that context switching cannot occur while a chain of subbuffers is being
  154791. + executed. */
  154792. + gcsCMDBUFFER_PTR nextSubBuffer;
  154793. +}
  154794. +gcsCMDBUFFER;
  154795. +
  154796. +/* Command queue element. */
  154797. +typedef struct _gcsVGCMDQUEUE
  154798. +{
  154799. + /* Pointer to the command buffer header. */
  154800. + gcsCMDBUFFER_PTR commandBuffer;
  154801. +
  154802. + /* Dynamic vs. static command buffer state. */
  154803. + gctBOOL dynamic;
  154804. +}
  154805. +gcsVGCMDQUEUE;
  154806. +
  154807. +/* Context map entry. */
  154808. +typedef struct _gcsVGCONTEXT_MAP
  154809. +{
  154810. + /* State index. */
  154811. + gctUINT32 index;
  154812. +
  154813. + /* New state value. */
  154814. + gctUINT32 data;
  154815. +
  154816. + /* Points to the next entry in the mod list. */
  154817. + gcsVGCONTEXT_MAP_PTR next;
  154818. +}
  154819. +gcsVGCONTEXT_MAP;
  154820. +
  154821. +/* gcsVGCONTEXT structure that holds the current context. */
  154822. +typedef struct _gcsVGCONTEXT
  154823. +{
  154824. + /* Context ID. */
  154825. + gctUINT64 id;
  154826. +
  154827. + /* State caching ebable flag. */
  154828. + gctBOOL stateCachingEnabled;
  154829. +
  154830. + /* Current pipe. */
  154831. + gctUINT32 currentPipe;
  154832. +
  154833. + /* State map/mod buffer. */
  154834. + gctSIZE_T mapFirst;
  154835. + gctSIZE_T mapLast;
  154836. +#ifdef __QNXNTO__
  154837. + gctSIZE_T mapContainerSize;
  154838. +#endif
  154839. + gcsVGCONTEXT_MAP_PTR mapContainer;
  154840. + gcsVGCONTEXT_MAP_PTR mapPrev;
  154841. + gcsVGCONTEXT_MAP_PTR mapCurr;
  154842. + gcsVGCONTEXT_MAP_PTR firstPrevMap;
  154843. + gcsVGCONTEXT_MAP_PTR firstCurrMap;
  154844. +
  154845. + /* Main context buffer. */
  154846. + gcsCMDBUFFER_PTR header;
  154847. + gctUINT32_PTR buffer;
  154848. +
  154849. + /* Completion signal. */
  154850. + gctHANDLE process;
  154851. + gctSIGNAL signal;
  154852. +
  154853. +#if defined(__QNXNTO__)
  154854. + gctINT32 coid;
  154855. + gctINT32 rcvid;
  154856. +#endif
  154857. +}
  154858. +gcsVGCONTEXT;
  154859. +
  154860. +/* User space task header. */
  154861. +typedef struct _gcsTASK * gcsTASK_PTR;
  154862. +typedef struct _gcsTASK
  154863. +{
  154864. + /* Pointer to the next task for the same interrupt in user space. */
  154865. + gcsTASK_PTR next;
  154866. +
  154867. + /* Size of the task data that immediately follows the structure. */
  154868. + gctUINT size;
  154869. +
  154870. + /* Task data starts here. */
  154871. + /* ... */
  154872. +}
  154873. +gcsTASK;
  154874. +
  154875. +/* User space task master table entry. */
  154876. +typedef struct _gcsTASK_MASTER_ENTRY * gcsTASK_MASTER_ENTRY_PTR;
  154877. +typedef struct _gcsTASK_MASTER_ENTRY
  154878. +{
  154879. + /* Pointers to the head and to the tail of the task chain. */
  154880. + gcsTASK_PTR head;
  154881. + gcsTASK_PTR tail;
  154882. +}
  154883. +gcsTASK_MASTER_ENTRY;
  154884. +
  154885. +/* User space task master table entry. */
  154886. +typedef struct _gcsTASK_MASTER_TABLE
  154887. +{
  154888. + /* Table with one entry per block. */
  154889. + gcsTASK_MASTER_ENTRY table[gcvBLOCK_COUNT];
  154890. +
  154891. + /* The total number of tasks sckeduled. */
  154892. + gctUINT count;
  154893. +
  154894. + /* The total size of event data in bytes. */
  154895. + gctUINT size;
  154896. +
  154897. +#if defined(__QNXNTO__)
  154898. + gctINT32 coid;
  154899. + gctINT32 rcvid;
  154900. +#endif
  154901. +}
  154902. +gcsTASK_MASTER_TABLE;
  154903. +
  154904. +/******************************************************************************\
  154905. +***************************** gckVGINTERRUPT Object ******************************
  154906. +\******************************************************************************/
  154907. +
  154908. +typedef struct _gckVGINTERRUPT * gckVGINTERRUPT;
  154909. +
  154910. +typedef gceSTATUS (* gctINTERRUPT_HANDLER)(
  154911. + IN gckVGKERNEL Kernel
  154912. + );
  154913. +
  154914. +gceSTATUS
  154915. +gckVGINTERRUPT_Construct(
  154916. + IN gckVGKERNEL Kernel,
  154917. + OUT gckVGINTERRUPT * Interrupt
  154918. + );
  154919. +
  154920. +gceSTATUS
  154921. +gckVGINTERRUPT_Destroy(
  154922. + IN gckVGINTERRUPT Interrupt
  154923. + );
  154924. +
  154925. +gceSTATUS
  154926. +gckVGINTERRUPT_Enable(
  154927. + IN gckVGINTERRUPT Interrupt,
  154928. + IN OUT gctINT32_PTR Id,
  154929. + IN gctINTERRUPT_HANDLER Handler
  154930. + );
  154931. +
  154932. +gceSTATUS
  154933. +gckVGINTERRUPT_Disable(
  154934. + IN gckVGINTERRUPT Interrupt,
  154935. + IN gctINT32 Id
  154936. + );
  154937. +
  154938. +#ifndef __QNXNTO__
  154939. +
  154940. +gceSTATUS
  154941. +gckVGINTERRUPT_Enque(
  154942. + IN gckVGINTERRUPT Interrupt
  154943. + );
  154944. +
  154945. +#else
  154946. +
  154947. +gceSTATUS
  154948. +gckVGINTERRUPT_Enque(
  154949. + IN gckVGINTERRUPT Interrupt,
  154950. + OUT gckOS *Os,
  154951. + OUT gctSEMAPHORE *Semaphore
  154952. + );
  154953. +
  154954. +#endif
  154955. +
  154956. +gceSTATUS
  154957. +gckVGINTERRUPT_DumpState(
  154958. + IN gckVGINTERRUPT Interrupt
  154959. + );
  154960. +
  154961. +
  154962. +/******************************************************************************\
  154963. +******************************* gckVGCOMMAND Object *******************************
  154964. +\******************************************************************************/
  154965. +
  154966. +typedef struct _gckVGCOMMAND * gckVGCOMMAND;
  154967. +
  154968. +/* Construct a new gckVGCOMMAND object. */
  154969. +gceSTATUS
  154970. +gckVGCOMMAND_Construct(
  154971. + IN gckVGKERNEL Kernel,
  154972. + IN gctUINT TaskGranularity,
  154973. + IN gctUINT QueueSize,
  154974. + OUT gckVGCOMMAND * Command
  154975. + );
  154976. +
  154977. +/* Destroy an gckVGCOMMAND object. */
  154978. +gceSTATUS
  154979. +gckVGCOMMAND_Destroy(
  154980. + IN gckVGCOMMAND Command
  154981. + );
  154982. +
  154983. +/* Query command buffer attributes. */
  154984. +gceSTATUS
  154985. +gckVGCOMMAND_QueryCommandBuffer(
  154986. + IN gckVGCOMMAND Command,
  154987. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  154988. + );
  154989. +
  154990. +/* Allocate a command queue. */
  154991. +gceSTATUS
  154992. +gckVGCOMMAND_Allocate(
  154993. + IN gckVGCOMMAND Command,
  154994. + IN gctSIZE_T Size,
  154995. + OUT gcsCMDBUFFER_PTR * CommandBuffer,
  154996. + OUT gctPOINTER * Data
  154997. + );
  154998. +
  154999. +/* Release memory held by the command queue. */
  155000. +gceSTATUS
  155001. +gckVGCOMMAND_Free(
  155002. + IN gckVGCOMMAND Command,
  155003. + IN gcsCMDBUFFER_PTR CommandBuffer
  155004. + );
  155005. +
  155006. +/* Schedule the command queue for execution. */
  155007. +gceSTATUS
  155008. +gckVGCOMMAND_Execute(
  155009. + IN gckVGCOMMAND Command,
  155010. + IN gcsCMDBUFFER_PTR CommandBuffer
  155011. + );
  155012. +
  155013. +/* Commit a buffer to the command queue. */
  155014. +gceSTATUS
  155015. +gckVGCOMMAND_Commit(
  155016. + IN gckVGCOMMAND Command,
  155017. + IN gcsVGCONTEXT_PTR Context,
  155018. + IN gcsVGCMDQUEUE_PTR Queue,
  155019. + IN gctUINT EntryCount,
  155020. + IN gcsTASK_MASTER_TABLE_PTR TaskTable
  155021. + );
  155022. +
  155023. +/******************************************************************************\
  155024. +********************************* gckVGMMU Object ********************************
  155025. +\******************************************************************************/
  155026. +
  155027. +typedef struct _gckVGMMU * gckVGMMU;
  155028. +
  155029. +/* Construct a new gckVGMMU object. */
  155030. +gceSTATUS
  155031. +gckVGMMU_Construct(
  155032. + IN gckVGKERNEL Kernel,
  155033. + IN gctSIZE_T MmuSize,
  155034. + OUT gckVGMMU * Mmu
  155035. + );
  155036. +
  155037. +/* Destroy an gckVGMMU object. */
  155038. +gceSTATUS
  155039. +gckVGMMU_Destroy(
  155040. + IN gckVGMMU Mmu
  155041. + );
  155042. +
  155043. +/* Allocate pages inside the MMU. */
  155044. +gceSTATUS
  155045. +gckVGMMU_AllocatePages(
  155046. + IN gckVGMMU Mmu,
  155047. + IN gctSIZE_T PageCount,
  155048. + OUT gctPOINTER * PageTable,
  155049. + OUT gctUINT32 * Address
  155050. + );
  155051. +
  155052. +/* Remove a page table from the MMU. */
  155053. +gceSTATUS
  155054. +gckVGMMU_FreePages(
  155055. + IN gckVGMMU Mmu,
  155056. + IN gctPOINTER PageTable,
  155057. + IN gctSIZE_T PageCount
  155058. + );
  155059. +
  155060. +/* Set the MMU page with info. */
  155061. +gceSTATUS
  155062. +gckVGMMU_SetPage(
  155063. + IN gckVGMMU Mmu,
  155064. + IN gctUINT32 PageAddress,
  155065. + IN gctUINT32 *PageEntry
  155066. + );
  155067. +
  155068. +/* Flush MMU */
  155069. +gceSTATUS
  155070. +gckVGMMU_Flush(
  155071. + IN gckVGMMU Mmu
  155072. + );
  155073. +
  155074. +#endif /* gcdENABLE_VG */
  155075. +
  155076. +#ifdef __cplusplus
  155077. +} /* extern "C" */
  155078. +#endif
  155079. +
  155080. +#endif /* __gc_hal_h_ */
  155081. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
  155082. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c 1969-12-31 18:00:00.000000000 -0600
  155083. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c 2014-12-08 00:31:53.472418001 -0600
  155084. @@ -0,0 +1,795 @@
  155085. +/****************************************************************************
  155086. +*
  155087. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  155088. +*
  155089. +* This program is free software; you can redistribute it and/or modify
  155090. +* it under the terms of the GNU General Public License as published by
  155091. +* the Free Software Foundation; either version 2 of the license, or
  155092. +* (at your option) any later version.
  155093. +*
  155094. +* This program is distributed in the hope that it will be useful,
  155095. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  155096. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  155097. +* GNU General Public License for more details.
  155098. +*
  155099. +* You should have received a copy of the GNU General Public License
  155100. +* along with this program; if not write to the Free Software
  155101. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  155102. +*
  155103. +*****************************************************************************/
  155104. +
  155105. +
  155106. +#ifdef MODULE
  155107. +#include <linux/module.h>
  155108. +#endif
  155109. +#include <linux/init.h>
  155110. +#include <linux/debugfs.h>
  155111. +#include <linux/slab.h>
  155112. +#ifdef MODVERSIONS
  155113. +#include <linux/modversions.h>
  155114. +#endif
  155115. +#include <linux/stddef.h>
  155116. +#include <linux/sched.h>
  155117. +#include <linux/kernel.h>
  155118. +#include <linux/timer.h>
  155119. +#include <linux/delay.h>
  155120. +#include <linux/errno.h>
  155121. +#include <linux/mutex.h>
  155122. +#include <linux/vmalloc.h>
  155123. +#include <linux/types.h>
  155124. +#include <linux/fs.h>
  155125. +#include <linux/poll.h>
  155126. +#include <asm/uaccess.h>
  155127. +#include <linux/completion.h>
  155128. +#include "gc_hal_kernel_linux.h"
  155129. +
  155130. +/*
  155131. + Prequsite:
  155132. +
  155133. + 1) Debugfs feature must be enabled in the kernel.
  155134. + 1.a) You can enable this, in the compilation of the uImage, all you have to do is, In the "make menuconfig" part,
  155135. + you have to enable the debugfs in the kernel hacking part of the menu.
  155136. +
  155137. + HOW TO USE:
  155138. + 1) insert the driver with the following option logFileSize, Ex: insmod galcore.ko ...... logFileSize=10240
  155139. + This gives a circular buffer of 10 MB
  155140. +
  155141. + 2)Usually after inserting the driver, the debug file system is mounted under /sys/kernel/debug/
  155142. +
  155143. + 2.a)If the debugfs is not mounted, you must do "mount -t debugfs none /sys/kernel/debug"
  155144. +
  155145. + 3) To read what is being printed in the debugfs file system:
  155146. + Ex : cat /sys/kernel/debug/gpu/galcore_trace
  155147. +
  155148. + 4)To write into the debug file system from user side :
  155149. + Ex: echo "hello" > cat /sys/kernel/debug/gpu/galcore_trace
  155150. +
  155151. + 5)To write into debugfs from kernel side, Use the function called gckDebugFileSystemPrint
  155152. +
  155153. +
  155154. + USECASE Kernel Dump:
  155155. +
  155156. + 1) Go to /hal/inc/gc_hal_options.h, and enable the following flags:
  155157. + - # define gcdDUMP 1
  155158. + - # define gcdDUMP_IN_KERNEL 1
  155159. + - # define gcdDUMP_COMMAND 1
  155160. +
  155161. + 2) Go to /hal/kernel/gc_hal_kernel_command.c and disable the following flag
  155162. + -#define gcdSIMPLE_COMMAND_DUMP 0
  155163. +
  155164. + 3) Compile the driver
  155165. + 4) insmod it with the logFileSize option
  155166. + 5) Run an application
  155167. + 6) You can get the dump by cat /sys/kernel/debug/gpu/galcore_trace
  155168. +
  155169. + */
  155170. +
  155171. +/**/
  155172. +typedef va_list gctDBGARGS ;
  155173. +#define gcmkARGS_START(argument, pointer) va_start(argument, pointer)
  155174. +#define gcmkARGS_END(argument) va_end(argument)
  155175. +
  155176. +#define gcmkDBGFSPRINT(ArgumentSize, Message) \
  155177. + { \
  155178. + gctDBGARGS __arguments__; \
  155179. + gcmkARGS_START(__arguments__, Message); \
  155180. + _DebugFSPrint(ArgumentSize, Message, __arguments__);\
  155181. + gcmkARGS_END(__arguments__); \
  155182. + }
  155183. +
  155184. +/*Debug File System Node Struct*/
  155185. +struct _gcsDebugFileSystemNode
  155186. +{
  155187. + /*wait queues for read and write operations*/
  155188. +#if defined(DECLARE_WAIT_QUEUE_HEAD)
  155189. + wait_queue_head_t read_q , write_q ;
  155190. +#else
  155191. + struct wait_queue *read_q , *write_q ;
  155192. +#endif
  155193. + struct dentry *parent ; /*parent directory*/
  155194. + struct dentry *filen ; /*filename*/
  155195. + struct semaphore sem ; /* mutual exclusion semaphore */
  155196. + char *data ; /* The circular buffer data */
  155197. + int size ; /* Size of the buffer pointed to by 'data' */
  155198. + int refcount ; /* Files that have this buffer open */
  155199. + int read_point ; /* Offset in circ. buffer of oldest data */
  155200. + int write_point ; /* Offset in circ. buffer of newest data */
  155201. + int offset ; /* Byte number of read_point in the stream */
  155202. + struct _gcsDebugFileSystemNode *next ;
  155203. +} ;
  155204. +
  155205. +/* amount of data in the queue */
  155206. +#define gcmkNODE_QLEN(node) ( (node)->write_point >= (node)->read_point ? \
  155207. + (node)->write_point - (node)->read_point : \
  155208. + (node)->size - (node)->read_point + (node)->write_point)
  155209. +
  155210. +/* byte number of the last byte in the queue */
  155211. +#define gcmkNODE_FIRST_EMPTY_BYTE(node) ((node)->offset + gcmkNODE_QLEN(node))
  155212. +
  155213. +/*Synchronization primitives*/
  155214. +#define gcmkNODE_READQ(node) (&((node)->read_q))
  155215. +#define gcmkNODE_WRITEQ(node) (&((node)->write_q))
  155216. +#define gcmkNODE_SEM(node) (&((node)->sem))
  155217. +
  155218. +/*Utilities*/
  155219. +#define gcmkMIN(x, y) ((x) < (y) ? (x) : y)
  155220. +
  155221. +/*Debug File System Struct*/
  155222. +typedef struct _gcsDebugFileSystem
  155223. +{
  155224. + gcsDebugFileSystemNode* linkedlist ;
  155225. + gcsDebugFileSystemNode* currentNode ;
  155226. + int isInited ;
  155227. +} gcsDebugFileSystem ;
  155228. +
  155229. +
  155230. +/*debug file system*/
  155231. +static gcsDebugFileSystem gc_dbgfs ;
  155232. +
  155233. +
  155234. +
  155235. +/*******************************************************************************
  155236. + **
  155237. + ** READ & WRITE FUNCTIONS (START)
  155238. + **
  155239. + *******************************************************************************/
  155240. +
  155241. +/*******************************************************************************
  155242. + **
  155243. + ** _ReadFromNode
  155244. + **
  155245. + ** 1) reading bytes out of a circular buffer with wraparound.
  155246. + ** 2)returns caddr_t, pointer to data read, which the caller must free.
  155247. + ** 3) length is (a pointer to) the number of bytes to be read, which will be set by this function to
  155248. + ** be the number of bytes actually returned
  155249. + **
  155250. + *******************************************************************************/
  155251. +static caddr_t
  155252. +_ReadFromNode (
  155253. + gcsDebugFileSystemNode* Node ,
  155254. + size_t *Length ,
  155255. + loff_t *Offset
  155256. + )
  155257. +{
  155258. + caddr_t retval ;
  155259. + int bytes_copied = 0 , n , start_point , remaining ;
  155260. +
  155261. + /* is the user trying to read data that has already scrolled off? */
  155262. + if ( *Offset < Node->offset )
  155263. + {
  155264. + *Offset = Node->offset ;
  155265. + }
  155266. +
  155267. + /* is the user trying to read past EOF? */
  155268. + if ( *Offset >= gcmkNODE_FIRST_EMPTY_BYTE ( Node ) )
  155269. + {
  155270. + return NULL ;
  155271. + }
  155272. +
  155273. + /* find the smaller of the total bytes we have available and what
  155274. + * the user is asking for */
  155275. +
  155276. + *Length = gcmkMIN ( *Length , gcmkNODE_FIRST_EMPTY_BYTE ( Node ) - *Offset ) ;
  155277. +
  155278. + remaining = * Length ;
  155279. +
  155280. + /* figure out where to start based on user's Offset */
  155281. + start_point = Node->read_point + ( *Offset - Node->offset ) ;
  155282. +
  155283. + start_point = start_point % Node->size ;
  155284. +
  155285. + /* allocate memory to return */
  155286. + if ( ( retval = kmalloc ( sizeof (char ) * remaining , GFP_KERNEL ) ) == NULL )
  155287. + return NULL ;
  155288. +
  155289. + /* copy the (possibly noncontiguous) data to our buffer */
  155290. + while ( remaining )
  155291. + {
  155292. + n = gcmkMIN ( remaining , Node->size - start_point ) ;
  155293. + memcpy ( retval + bytes_copied , Node->data + start_point , n ) ;
  155294. + bytes_copied += n ;
  155295. + remaining -= n ;
  155296. + start_point = ( start_point + n ) % Node->size ;
  155297. + }
  155298. +
  155299. + /* advance user's file pointer */
  155300. + *Offset += * Length ;
  155301. +
  155302. + return retval ;
  155303. +}
  155304. +
  155305. +/*******************************************************************************
  155306. + **
  155307. + ** _WriteToNode
  155308. + **
  155309. + ** 1) writes to a circular buffer with wraparound.
  155310. + ** 2)in case of an overflow, it overwrites the oldest unread data.
  155311. + **
  155312. + *********************************************************************************/
  155313. +static void
  155314. +_WriteToNode (
  155315. + gcsDebugFileSystemNode* Node ,
  155316. + caddr_t Buf ,
  155317. + int Length
  155318. + )
  155319. +{
  155320. + int bytes_copied = 0 ;
  155321. + int overflow = 0 ;
  155322. + int n ;
  155323. +
  155324. + if ( Length + gcmkNODE_QLEN ( Node ) >= ( Node->size - 1 ) )
  155325. + {
  155326. + overflow = 1 ;
  155327. +
  155328. + /* in case of overflow, figure out where the new buffer will
  155329. + * begin. we start by figuring out where the current buffer ENDS:
  155330. + * node->parent->offset + gcmkNODE_QLEN. we then advance the end-offset
  155331. + * by the Length of the current write, and work backwards to
  155332. + * figure out what the oldest unoverwritten data will be (i.e.,
  155333. + * size of the buffer). */
  155334. + Node->offset = Node->offset + gcmkNODE_QLEN ( Node ) + Length
  155335. + - Node->size + 1 ;
  155336. + }
  155337. +
  155338. + while ( Length )
  155339. + {
  155340. + /* how many contiguous bytes are available from the write point to
  155341. + * the end of the circular buffer? */
  155342. + n = gcmkMIN ( Length , Node->size - Node->write_point ) ;
  155343. + memcpy ( Node->data + Node->write_point , Buf + bytes_copied , n ) ;
  155344. + bytes_copied += n ;
  155345. + Length -= n ;
  155346. + Node->write_point = ( Node->write_point + n ) % Node->size ;
  155347. + }
  155348. +
  155349. + /* if there is an overflow, reset the read point to read whatever is
  155350. + * the oldest data that we have, that has not yet been
  155351. + * overwritten. */
  155352. + if ( overflow )
  155353. + {
  155354. + Node->read_point = ( Node->write_point + 1 ) % Node->size ;
  155355. + }
  155356. +}
  155357. +
  155358. +
  155359. +/*******************************************************************************
  155360. + **
  155361. + ** PRINTING UTILITY (START)
  155362. + **
  155363. + *******************************************************************************/
  155364. +
  155365. +/*******************************************************************************
  155366. + **
  155367. + ** _GetArgumentSize
  155368. + **
  155369. + **
  155370. + *******************************************************************************/
  155371. +static gctINT
  155372. +_GetArgumentSize (
  155373. + IN gctCONST_STRING Message
  155374. + )
  155375. +{
  155376. + gctINT i , count ;
  155377. +
  155378. + for ( i = 0 , count = 0 ; Message[i] ; i += 1 )
  155379. + {
  155380. + if ( Message[i] == '%' )
  155381. + {
  155382. + count += 1 ;
  155383. + }
  155384. + }
  155385. + return count * sizeof (unsigned int ) ;
  155386. +}
  155387. +
  155388. +/*******************************************************************************
  155389. + **
  155390. + ** _AppendString
  155391. + **
  155392. + **
  155393. + *******************************************************************************/
  155394. +static ssize_t
  155395. +_AppendString (
  155396. + IN gcsDebugFileSystemNode* Node ,
  155397. + IN gctCONST_STRING String ,
  155398. + IN int Length
  155399. + )
  155400. +{
  155401. + caddr_t message = NULL ;
  155402. + int n ;
  155403. +
  155404. + /* if the message is longer than the buffer, just take the beginning
  155405. + * of it, in hopes that the reader (if any) will have time to read
  155406. + * before we wrap around and obliterate it */
  155407. + n = gcmkMIN ( Length , Node->size - 1 ) ;
  155408. +
  155409. + /* make sure we have the memory for it */
  155410. + if ( ( message = kmalloc ( n , GFP_KERNEL ) ) == NULL )
  155411. + return - ENOMEM ;
  155412. +
  155413. + /* copy into our temp buffer */
  155414. + memcpy ( message , String , n ) ;
  155415. +
  155416. + /* now copy it into the circular buffer and free our temp copy */
  155417. + _WriteToNode ( Node , message , n ) ;
  155418. + kfree ( message ) ;
  155419. + return n ;
  155420. +}
  155421. +
  155422. +/*******************************************************************************
  155423. + **
  155424. + ** _DebugFSPrint
  155425. + **
  155426. + **
  155427. + *******************************************************************************/
  155428. +static void
  155429. +_DebugFSPrint (
  155430. + IN unsigned int ArgumentSize ,
  155431. + IN const char* Message ,
  155432. + IN gctDBGARGS Arguments
  155433. +
  155434. + )
  155435. +{
  155436. + char buffer[MAX_LINE_SIZE] ;
  155437. + int len ;
  155438. + down ( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ;
  155439. + len = vsnprintf ( buffer , sizeof (buffer ) , Message , *( va_list * ) & Arguments ) ;
  155440. + buffer[len] = '\0' ;
  155441. +
  155442. + /* Add end-of-line if missing. */
  155443. + if ( buffer[len - 1] != '\n' )
  155444. + {
  155445. + buffer[len ++] = '\n' ;
  155446. + buffer[len] = '\0' ;
  155447. + }
  155448. + _AppendString ( gc_dbgfs.currentNode , buffer , len ) ;
  155449. + up ( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ;
  155450. + wake_up_interruptible ( gcmkNODE_READQ ( gc_dbgfs.currentNode ) ) ; /* blocked in read*/
  155451. +}
  155452. +
  155453. +/*******************************************************************************
  155454. + **
  155455. + ** LINUX SYSTEM FUNCTIONS (START)
  155456. + **
  155457. + *******************************************************************************/
  155458. +
  155459. +/*******************************************************************************
  155460. + **
  155461. + ** find the vivlog structure associated with an inode.
  155462. + ** returns a pointer to the structure if found, NULL if not found
  155463. + **
  155464. + *******************************************************************************/
  155465. +static gcsDebugFileSystemNode*
  155466. +_GetNodeInfo (
  155467. + IN struct inode *Inode
  155468. + )
  155469. +{
  155470. + gcsDebugFileSystemNode* node ;
  155471. +
  155472. + if ( Inode == NULL )
  155473. + return NULL ;
  155474. +
  155475. + for ( node = gc_dbgfs.linkedlist ; node != NULL ; node = node->next )
  155476. + if ( node->filen->d_inode->i_ino == Inode->i_ino )
  155477. + return node ;
  155478. +
  155479. + return NULL ;
  155480. +}
  155481. +
  155482. +/*******************************************************************************
  155483. + **
  155484. + ** _DebugFSRead
  155485. + **
  155486. + *******************************************************************************/
  155487. +static ssize_t
  155488. +_DebugFSRead (
  155489. + struct file *file ,
  155490. + char __user * buffer ,
  155491. + size_t length ,
  155492. + loff_t * offset
  155493. + )
  155494. +{
  155495. + int retval ;
  155496. + caddr_t data_to_return ;
  155497. + gcsDebugFileSystemNode* node ;
  155498. + /* get the metadata about this emlog */
  155499. + if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL )
  155500. + {
  155501. + printk ( "debugfs_read: record not found\n" ) ;
  155502. + return - EIO ;
  155503. + }
  155504. +
  155505. + if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
  155506. + {
  155507. + return - ERESTARTSYS ;
  155508. + }
  155509. +
  155510. + /* wait until there's data available (unless we do nonblocking reads) */
  155511. + while ( *offset >= gcmkNODE_FIRST_EMPTY_BYTE ( node ) )
  155512. + {
  155513. + up ( gcmkNODE_SEM ( node ) ) ;
  155514. + if ( file->f_flags & O_NONBLOCK )
  155515. + {
  155516. + return - EAGAIN ;
  155517. + }
  155518. + if ( wait_event_interruptible ( ( *( gcmkNODE_READQ ( node ) ) ) , ( *offset < gcmkNODE_FIRST_EMPTY_BYTE ( node ) ) ) )
  155519. + {
  155520. + return - ERESTARTSYS ; /* signal: tell the fs layer to handle it */
  155521. + }
  155522. + /* otherwise loop, but first reacquire the lock */
  155523. + if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
  155524. + {
  155525. + return - ERESTARTSYS ;
  155526. + }
  155527. + }
  155528. + data_to_return = _ReadFromNode ( node , &length , offset ) ;
  155529. + if ( data_to_return == NULL )
  155530. + {
  155531. + retval = 0 ;
  155532. + goto unlock ;
  155533. + }
  155534. + if ( copy_to_user ( buffer , data_to_return , length ) > 0 )
  155535. + {
  155536. + retval = - EFAULT ;
  155537. + }
  155538. + else
  155539. + {
  155540. + retval = length ;
  155541. + }
  155542. + kfree ( data_to_return ) ;
  155543. +unlock:
  155544. + up ( gcmkNODE_SEM ( node ) ) ;
  155545. + wake_up_interruptible ( gcmkNODE_WRITEQ ( node ) ) ;
  155546. + return retval ;
  155547. +}
  155548. +
  155549. +/*******************************************************************************
  155550. + **
  155551. + **_DebugFSWrite
  155552. + **
  155553. + *******************************************************************************/
  155554. +static ssize_t
  155555. +_DebugFSWrite (
  155556. + struct file *file ,
  155557. + const char __user * buffer ,
  155558. + size_t length ,
  155559. + loff_t * offset
  155560. + )
  155561. +{
  155562. + caddr_t message = NULL ;
  155563. + int n ;
  155564. + gcsDebugFileSystemNode*node ;
  155565. +
  155566. + /* get the metadata about this log */
  155567. + if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL )
  155568. + {
  155569. + return - EIO ;
  155570. + }
  155571. +
  155572. + if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
  155573. + {
  155574. + return - ERESTARTSYS ;
  155575. + }
  155576. +
  155577. + /* if the message is longer than the buffer, just take the beginning
  155578. + * of it, in hopes that the reader (if any) will have time to read
  155579. + * before we wrap around and obliterate it */
  155580. + n = gcmkMIN ( length , node->size - 1 ) ;
  155581. +
  155582. + /* make sure we have the memory for it */
  155583. + if ( ( message = kmalloc ( n , GFP_KERNEL ) ) == NULL )
  155584. + {
  155585. + up ( gcmkNODE_SEM ( node ) ) ;
  155586. + return - ENOMEM ;
  155587. + }
  155588. +
  155589. + /* copy into our temp buffer */
  155590. + if ( copy_from_user ( message , buffer , n ) > 0 )
  155591. + {
  155592. + up ( gcmkNODE_SEM ( node ) ) ;
  155593. + kfree ( message ) ;
  155594. + return - EFAULT ;
  155595. + }
  155596. +
  155597. + /* now copy it into the circular buffer and free our temp copy */
  155598. + _WriteToNode ( node , message , n ) ;
  155599. +
  155600. + kfree ( message ) ;
  155601. + up ( gcmkNODE_SEM ( node ) ) ;
  155602. +
  155603. + /* wake up any readers that might be waiting for the data. we call
  155604. + * schedule in the vague hope that a reader will run before the
  155605. + * writer's next write, to avoid losing data. */
  155606. + wake_up_interruptible ( gcmkNODE_READQ ( node ) ) ;
  155607. +
  155608. + return n ;
  155609. +}
  155610. +
  155611. +/*******************************************************************************
  155612. + **
  155613. + ** File Operations Table
  155614. + **
  155615. + *******************************************************************************/
  155616. +static const struct file_operations debugfs_operations = {
  155617. + .owner = THIS_MODULE ,
  155618. + .read = _DebugFSRead ,
  155619. + .write = _DebugFSWrite ,
  155620. +} ;
  155621. +
  155622. +/*******************************************************************************
  155623. + **
  155624. + ** INTERFACE FUNCTIONS (START)
  155625. + **
  155626. + *******************************************************************************/
  155627. +
  155628. +/*******************************************************************************
  155629. + **
  155630. + ** gckDebugFileSystemIsEnabled
  155631. + **
  155632. + **
  155633. + ** INPUT:
  155634. + **
  155635. + ** OUTPUT:
  155636. + **
  155637. + *******************************************************************************/
  155638. +
  155639. +
  155640. +gctINT
  155641. +gckDebugFileSystemIsEnabled ( void )
  155642. +{
  155643. + return gc_dbgfs.isInited ;
  155644. +}
  155645. +/*******************************************************************************
  155646. + **
  155647. + ** gckDebugFileSystemInitialize
  155648. + **
  155649. + **
  155650. + ** INPUT:
  155651. + **
  155652. + ** OUTPUT:
  155653. + **
  155654. + *******************************************************************************/
  155655. +
  155656. +gctINT
  155657. +gckDebugFileSystemInitialize ( void )
  155658. +{
  155659. + if ( ! gc_dbgfs.isInited )
  155660. + {
  155661. + gc_dbgfs.linkedlist = gcvNULL ;
  155662. + gc_dbgfs.currentNode = gcvNULL ;
  155663. + gc_dbgfs.isInited = 1 ;
  155664. + }
  155665. + return gc_dbgfs.isInited ;
  155666. +}
  155667. +/*******************************************************************************
  155668. + **
  155669. + ** gckDebugFileSystemTerminate
  155670. + **
  155671. + **
  155672. + ** INPUT:
  155673. + **
  155674. + ** OUTPUT:
  155675. + **
  155676. + *******************************************************************************/
  155677. +
  155678. +gctINT
  155679. +gckDebugFileSystemTerminate ( void )
  155680. +{
  155681. + gcsDebugFileSystemNode * next = gcvNULL ;
  155682. + gcsDebugFileSystemNode * temp = gcvNULL ;
  155683. + if ( gc_dbgfs.isInited )
  155684. + {
  155685. + temp = gc_dbgfs.linkedlist ;
  155686. + while ( temp != gcvNULL )
  155687. + {
  155688. + next = temp->next ;
  155689. + gckDebugFileSystemFreeNode ( temp ) ;
  155690. + kfree ( temp ) ;
  155691. + temp = next ;
  155692. + }
  155693. + gc_dbgfs.isInited = 0 ;
  155694. + }
  155695. + return 0 ;
  155696. +}
  155697. +
  155698. +
  155699. +/*******************************************************************************
  155700. + **
  155701. + ** gckDebugFileSystemCreateNode
  155702. + **
  155703. + **
  155704. + ** INPUT:
  155705. + **
  155706. + ** OUTPUT:
  155707. + **
  155708. + ** gckDebugFileSystemFreeNode * Device
  155709. + ** Pointer to a variable receiving the gcsDebugFileSystemNode object pointer on
  155710. + ** success.
  155711. + *********************************************************************************/
  155712. +
  155713. +gctINT
  155714. +gckDebugFileSystemCreateNode (
  155715. + IN gctINT SizeInKB ,
  155716. + IN gctCONST_STRING ParentName ,
  155717. + IN gctCONST_STRING NodeName ,
  155718. + OUT gcsDebugFileSystemNode **Node
  155719. + )
  155720. +{
  155721. + gcsDebugFileSystemNode*node ;
  155722. + /* allocate space for our metadata and initialize it */
  155723. + if ( ( node = kmalloc ( sizeof (gcsDebugFileSystemNode ) , GFP_KERNEL ) ) == NULL )
  155724. + goto struct_malloc_failed ;
  155725. +
  155726. + /*Zero it out*/
  155727. + memset ( node , 0 , sizeof (gcsDebugFileSystemNode ) ) ;
  155728. +
  155729. + /*Init the sync primitives*/
  155730. +#if defined(DECLARE_WAIT_QUEUE_HEAD)
  155731. + init_waitqueue_head ( gcmkNODE_READQ ( node ) ) ;
  155732. +#else
  155733. + init_waitqueue ( gcmkNODE_READQ ( node ) ) ;
  155734. +#endif
  155735. +
  155736. +#if defined(DECLARE_WAIT_QUEUE_HEAD)
  155737. + init_waitqueue_head ( gcmkNODE_WRITEQ ( node ) ) ;
  155738. +#else
  155739. + init_waitqueue ( gcmkNODE_WRITEQ ( node ) ) ;
  155740. +#endif
  155741. + sema_init ( gcmkNODE_SEM ( node ) , 1 ) ;
  155742. + /*End the sync primitives*/
  155743. +
  155744. +
  155745. + /* figure out how much of a buffer this should be and allocate the buffer */
  155746. + node->size = 1024 * SizeInKB ;
  155747. + if ( ( node->data = ( char * ) vmalloc ( sizeof (char ) * node->size ) ) == NULL )
  155748. + goto data_malloc_failed ;
  155749. +
  155750. + /*creating the debug file system*/
  155751. + node->parent = debugfs_create_dir ( ParentName , NULL ) ;
  155752. +
  155753. + /*creating the file*/
  155754. + node->filen = debugfs_create_file ( NodeName , S_IRUGO | S_IWUSR , node->parent , NULL ,
  155755. + &debugfs_operations ) ;
  155756. +
  155757. + /* add it to our linked list */
  155758. + node->next = gc_dbgfs.linkedlist ;
  155759. + gc_dbgfs.linkedlist = node ;
  155760. +
  155761. + /* pass the struct back */
  155762. + *Node = node ;
  155763. + return 0 ;
  155764. +
  155765. + vfree ( node->data ) ;
  155766. +data_malloc_failed:
  155767. + kfree ( node ) ;
  155768. +struct_malloc_failed:
  155769. + return - ENOMEM ;
  155770. +}
  155771. +
  155772. +/*******************************************************************************
  155773. + **
  155774. + ** gckDebugFileSystemFreeNode
  155775. + **
  155776. + **
  155777. + ** INPUT:
  155778. + **
  155779. + ** OUTPUT:
  155780. + **
  155781. + *******************************************************************************/
  155782. +void
  155783. +gckDebugFileSystemFreeNode (
  155784. + IN gcsDebugFileSystemNode * Node
  155785. + )
  155786. +{
  155787. +
  155788. + gcsDebugFileSystemNode **ptr ;
  155789. +
  155790. + if ( Node == NULL )
  155791. + {
  155792. + printk ( "null passed to free_vinfo\n" ) ;
  155793. + return ;
  155794. + }
  155795. +
  155796. + down ( gcmkNODE_SEM ( Node ) ) ;
  155797. + /*free data*/
  155798. + vfree ( Node->data ) ;
  155799. +
  155800. + /*Close Debug fs*/
  155801. + if ( Node->filen )
  155802. + {
  155803. + debugfs_remove ( Node->filen ) ;
  155804. + }
  155805. + if ( Node->parent )
  155806. + {
  155807. + debugfs_remove ( Node->parent ) ;
  155808. + }
  155809. +
  155810. + /* now delete the node from the linked list */
  155811. + ptr = & ( gc_dbgfs.linkedlist ) ;
  155812. + while ( *ptr != Node )
  155813. + {
  155814. + if ( ! *ptr )
  155815. + {
  155816. + printk ( "corrupt info list!\n" ) ;
  155817. + break ;
  155818. + }
  155819. + else
  155820. + ptr = & ( ( **ptr ).next ) ;
  155821. + }
  155822. + *ptr = Node->next ;
  155823. + up ( gcmkNODE_SEM ( Node ) ) ;
  155824. +}
  155825. +
  155826. +/*******************************************************************************
  155827. + **
  155828. + ** gckDebugFileSystemSetCurrentNode
  155829. + **
  155830. + **
  155831. + ** INPUT:
  155832. + **
  155833. + ** OUTPUT:
  155834. + **
  155835. + *******************************************************************************/
  155836. +void
  155837. +gckDebugFileSystemSetCurrentNode (
  155838. + IN gcsDebugFileSystemNode * Node
  155839. + )
  155840. +{
  155841. + gc_dbgfs.currentNode = Node ;
  155842. +}
  155843. +
  155844. +/*******************************************************************************
  155845. + **
  155846. + ** gckDebugFileSystemGetCurrentNode
  155847. + **
  155848. + **
  155849. + ** INPUT:
  155850. + **
  155851. + ** OUTPUT:
  155852. + **
  155853. + *******************************************************************************/
  155854. +void
  155855. +gckDebugFileSystemGetCurrentNode (
  155856. + OUT gcsDebugFileSystemNode ** Node
  155857. + )
  155858. +{
  155859. + *Node = gc_dbgfs.currentNode ;
  155860. +}
  155861. +
  155862. +/*******************************************************************************
  155863. + **
  155864. + ** gckDebugFileSystemPrint
  155865. + **
  155866. + **
  155867. + ** INPUT:
  155868. + **
  155869. + ** OUTPUT:
  155870. + **
  155871. + *******************************************************************************/
  155872. +void
  155873. +gckDebugFileSystemPrint (
  155874. + IN gctCONST_STRING Message ,
  155875. + ...
  155876. + )
  155877. +{
  155878. + gcmkDBGFSPRINT ( _GetArgumentSize ( Message ) , Message ) ;
  155879. +}
  155880. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h
  155881. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h 1969-12-31 18:00:00.000000000 -0600
  155882. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h 2014-12-08 00:31:53.472418001 -0600
  155883. @@ -0,0 +1,84 @@
  155884. +/****************************************************************************
  155885. +*
  155886. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  155887. +*
  155888. +* This program is free software; you can redistribute it and/or modify
  155889. +* it under the terms of the GNU General Public License as published by
  155890. +* the Free Software Foundation; either version 2 of the license, or
  155891. +* (at your option) any later version.
  155892. +*
  155893. +* This program is distributed in the hope that it will be useful,
  155894. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  155895. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  155896. +* GNU General Public License for more details.
  155897. +*
  155898. +* You should have received a copy of the GNU General Public License
  155899. +* along with this program; if not write to the Free Software
  155900. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  155901. +*
  155902. +*****************************************************************************/
  155903. +
  155904. +
  155905. +#include <stdarg.h>
  155906. +
  155907. +#ifndef __gc_hal_kernel_debugfs_h_
  155908. +#define __gc_hal_kernel_debugfs_h_
  155909. +
  155910. + #define MAX_LINE_SIZE 768 /* Max bytes for a line of debug info */
  155911. +
  155912. +
  155913. + typedef struct _gcsDebugFileSystemNode gcsDebugFileSystemNode ;
  155914. +
  155915. +
  155916. +/*******************************************************************************
  155917. + **
  155918. + ** System Related
  155919. + **
  155920. + *******************************************************************************/
  155921. +
  155922. +gctINT gckDebugFileSystemIsEnabled(void);
  155923. +
  155924. +gctINT gckDebugFileSystemInitialize(void);
  155925. +
  155926. +gctINT gckDebugFileSystemTerminate(void);
  155927. +
  155928. +
  155929. +/*******************************************************************************
  155930. + **
  155931. + ** Node Related
  155932. + **
  155933. + *******************************************************************************/
  155934. +
  155935. +gctINT gckDebugFileSystemCreateNode(
  155936. + IN gctINT SizeInKB,
  155937. + IN gctCONST_STRING ParentName ,
  155938. + IN gctCONST_STRING NodeName,
  155939. + OUT gcsDebugFileSystemNode **Node
  155940. + );
  155941. +
  155942. +
  155943. +void gckDebugFileSystemFreeNode(
  155944. + IN gcsDebugFileSystemNode * Node
  155945. + );
  155946. +
  155947. +
  155948. +
  155949. +void gckDebugFileSystemSetCurrentNode(
  155950. + IN gcsDebugFileSystemNode * Node
  155951. + );
  155952. +
  155953. +
  155954. +
  155955. +void gckDebugFileSystemGetCurrentNode(
  155956. + OUT gcsDebugFileSystemNode ** Node
  155957. + );
  155958. +
  155959. +
  155960. +void gckDebugFileSystemPrint(
  155961. + IN gctCONST_STRING Message,
  155962. + ...
  155963. + );
  155964. +
  155965. +#endif
  155966. +
  155967. +
  155968. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
  155969. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h 1969-12-31 18:00:00.000000000 -0600
  155970. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h 2014-12-08 00:31:53.472418001 -0600
  155971. @@ -0,0 +1,102 @@
  155972. +/****************************************************************************
  155973. +*
  155974. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  155975. +*
  155976. +* This program is free software; you can redistribute it and/or modify
  155977. +* it under the terms of the GNU General Public License as published by
  155978. +* the Free Software Foundation; either version 2 of the license, or
  155979. +* (at your option) any later version.
  155980. +*
  155981. +* This program is distributed in the hope that it will be useful,
  155982. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  155983. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  155984. +* GNU General Public License for more details.
  155985. +*
  155986. +* You should have received a copy of the GNU General Public License
  155987. +* along with this program; if not write to the Free Software
  155988. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  155989. +*
  155990. +*****************************************************************************/
  155991. +
  155992. +
  155993. +#ifndef __gc_hal_kernel_debug_h_
  155994. +#define __gc_hal_kernel_debug_h_
  155995. +
  155996. +#include <gc_hal_kernel_linux.h>
  155997. +#include <linux/spinlock.h>
  155998. +#include <linux/time.h>
  155999. +#include <stdarg.h>
  156000. +
  156001. +#ifdef __cplusplus
  156002. +extern "C" {
  156003. +#endif
  156004. +
  156005. +/******************************************************************************\
  156006. +****************************** OS-dependent Macros *****************************
  156007. +\******************************************************************************/
  156008. +
  156009. +typedef va_list gctARGUMENTS;
  156010. +
  156011. +#define gcmkARGUMENTS_START(Arguments, Pointer) \
  156012. + va_start(Arguments, Pointer)
  156013. +
  156014. +#define gcmkARGUMENTS_END(Arguments) \
  156015. + va_end(Arguments)
  156016. +
  156017. +#define gcmkDECLARE_LOCK(__spinLock__) \
  156018. + static DEFINE_SPINLOCK(__spinLock__);
  156019. +
  156020. +#define gcmkLOCKSECTION(__spinLock__) \
  156021. + spin_lock(&__spinLock__)
  156022. +
  156023. +#define gcmkUNLOCKSECTION(__spinLock__) \
  156024. + spin_unlock(&__spinLock__)
  156025. +
  156026. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  156027. +# define gcmkGETPROCESSID() \
  156028. + task_tgid_vnr(current)
  156029. +#else
  156030. +# define gcmkGETPROCESSID() \
  156031. + current->tgid
  156032. +#endif
  156033. +
  156034. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  156035. +# define gcmkGETTHREADID() \
  156036. + task_pid_vnr(current)
  156037. +#else
  156038. +# define gcmkGETTHREADID() \
  156039. + current->pid
  156040. +#endif
  156041. +
  156042. +#define gcmkOUTPUT_STRING(String) \
  156043. + if(gckDebugFileSystemIsEnabled()) \
  156044. + gckDebugFileSystemPrint(String);\
  156045. + else\
  156046. + printk(String); \
  156047. + touch_softlockup_watchdog()
  156048. +
  156049. +
  156050. +#define gcmkSPRINTF(Destination, Size, Message, Value) \
  156051. + snprintf(Destination, Size, Message, Value)
  156052. +
  156053. +#define gcmkSPRINTF2(Destination, Size, Message, Value1, Value2) \
  156054. + snprintf(Destination, Size, Message, Value1, Value2)
  156055. +
  156056. +#define gcmkSPRINTF3(Destination, Size, Message, Value1, Value2, Value3) \
  156057. + snprintf(Destination, Size, Message, Value1, Value2, Value3)
  156058. +
  156059. +#define gcmkVSPRINTF(Destination, Size, Message, Arguments) \
  156060. + vsnprintf(Destination, Size, Message, *(va_list *) &Arguments)
  156061. +
  156062. +#define gcmkSTRCAT(Destination, Size, String) \
  156063. + strncat(Destination, String, Size)
  156064. +
  156065. +/* If not zero, forces data alignment in the variable argument list
  156066. + by its individual size. */
  156067. +#define gcdALIGNBYSIZE 1
  156068. +
  156069. +#ifdef __cplusplus
  156070. +}
  156071. +#endif
  156072. +
  156073. +#endif /* __gc_hal_kernel_debug_h_ */
  156074. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
  156075. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c 1969-12-31 18:00:00.000000000 -0600
  156076. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c 2014-12-08 00:31:53.472418001 -0600
  156077. @@ -0,0 +1,1676 @@
  156078. +/****************************************************************************
  156079. +*
  156080. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  156081. +*
  156082. +* This program is free software; you can redistribute it and/or modify
  156083. +* it under the terms of the GNU General Public License as published by
  156084. +* the Free Software Foundation; either version 2 of the license, or
  156085. +* (at your option) any later version.
  156086. +*
  156087. +* This program is distributed in the hope that it will be useful,
  156088. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  156089. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  156090. +* GNU General Public License for more details.
  156091. +*
  156092. +* You should have received a copy of the GNU General Public License
  156093. +* along with this program; if not write to the Free Software
  156094. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  156095. +*
  156096. +*****************************************************************************/
  156097. +
  156098. +
  156099. +#include "gc_hal_kernel_linux.h"
  156100. +#include <linux/pagemap.h>
  156101. +#include <linux/seq_file.h>
  156102. +#include <linux/mm.h>
  156103. +#include <linux/mman.h>
  156104. +#include <linux/slab.h>
  156105. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
  156106. +#include <mach/hardware.h>
  156107. +#endif
  156108. +#include <linux/pm_runtime.h>
  156109. +
  156110. +#define _GC_OBJ_ZONE gcvZONE_DEVICE
  156111. +
  156112. +#define DEBUG_FILE "galcore_trace"
  156113. +#define PARENT_FILE "gpu"
  156114. +
  156115. +
  156116. +#ifdef FLAREON
  156117. + static struct dove_gpio_irq_handler gc500_handle;
  156118. +#endif
  156119. +
  156120. +#define gcmIS_CORE_PRESENT(Device, Core) (Device->irqLines[Core] > 0)
  156121. +
  156122. +/******************************************************************************\
  156123. +*************************** Memory Allocation Wrappers *************************
  156124. +\******************************************************************************/
  156125. +
  156126. +static gceSTATUS
  156127. +_AllocateMemory(
  156128. + IN gckGALDEVICE Device,
  156129. + IN gctSIZE_T Bytes,
  156130. + OUT gctPOINTER *Logical,
  156131. + OUT gctPHYS_ADDR *Physical,
  156132. + OUT gctUINT32 *PhysAddr
  156133. + )
  156134. +{
  156135. + gceSTATUS status;
  156136. +
  156137. + gcmkHEADER_ARG("Device=0x%x Bytes=%lu", Device, Bytes);
  156138. +
  156139. + gcmkVERIFY_ARGUMENT(Device != NULL);
  156140. + gcmkVERIFY_ARGUMENT(Logical != NULL);
  156141. + gcmkVERIFY_ARGUMENT(Physical != NULL);
  156142. + gcmkVERIFY_ARGUMENT(PhysAddr != NULL);
  156143. +
  156144. + gcmkONERROR(gckOS_AllocateContiguous(
  156145. + Device->os, gcvFALSE, &Bytes, Physical, Logical
  156146. + ));
  156147. +
  156148. + *PhysAddr = ((PLINUX_MDL)*Physical)->dmaHandle - Device->baseAddress;
  156149. +
  156150. + /* Success. */
  156151. + gcmkFOOTER_ARG(
  156152. + "*Logical=0x%x *Physical=0x%x *PhysAddr=0x%08x",
  156153. + *Logical, *Physical, *PhysAddr
  156154. + );
  156155. +
  156156. + return gcvSTATUS_OK;
  156157. +
  156158. +OnError:
  156159. + gcmkFOOTER();
  156160. + return status;
  156161. +}
  156162. +
  156163. +static gceSTATUS
  156164. +_FreeMemory(
  156165. + IN gckGALDEVICE Device,
  156166. + IN gctPOINTER Logical,
  156167. + IN gctPHYS_ADDR Physical)
  156168. +{
  156169. + gceSTATUS status;
  156170. +
  156171. + gcmkHEADER_ARG("Device=0x%x Logical=0x%x Physical=0x%x",
  156172. + Device, Logical, Physical);
  156173. +
  156174. + gcmkVERIFY_ARGUMENT(Device != NULL);
  156175. +
  156176. + status = gckOS_FreeContiguous(
  156177. + Device->os, Physical, Logical,
  156178. + ((PLINUX_MDL) Physical)->numPages * PAGE_SIZE
  156179. + );
  156180. +
  156181. + gcmkFOOTER();
  156182. + return status;
  156183. +}
  156184. +
  156185. +
  156186. +
  156187. +/******************************************************************************\
  156188. +******************************* Interrupt Handler ******************************
  156189. +\******************************************************************************/
  156190. +static irqreturn_t isrRoutine(int irq, void *ctxt)
  156191. +{
  156192. + gceSTATUS status;
  156193. + gckGALDEVICE device;
  156194. +
  156195. + device = (gckGALDEVICE) ctxt;
  156196. +
  156197. + /* Call kernel interrupt notification. */
  156198. + status = gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], gcvNOTIFY_INTERRUPT, gcvTRUE);
  156199. +
  156200. + if (gcmIS_SUCCESS(status))
  156201. + {
  156202. + device->dataReadys[gcvCORE_MAJOR] = gcvTRUE;
  156203. +
  156204. + up(&device->semas[gcvCORE_MAJOR]);
  156205. +
  156206. + return IRQ_HANDLED;
  156207. + }
  156208. +
  156209. + return IRQ_NONE;
  156210. +}
  156211. +
  156212. +static int threadRoutine(void *ctxt)
  156213. +{
  156214. + gckGALDEVICE device = (gckGALDEVICE) ctxt;
  156215. +
  156216. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  156217. + "Starting isr Thread with extension=%p",
  156218. + device);
  156219. +
  156220. + for (;;)
  156221. + {
  156222. + static int down;
  156223. +
  156224. + down = down_interruptible(&device->semas[gcvCORE_MAJOR]);
  156225. + if (down); /*To make gcc 4.6 happye*/
  156226. + device->dataReadys[gcvCORE_MAJOR] = gcvFALSE;
  156227. +
  156228. + if (device->killThread == gcvTRUE)
  156229. + {
  156230. + /* The daemon exits. */
  156231. + while (!kthread_should_stop())
  156232. + {
  156233. + gckOS_Delay(device->os, 1);
  156234. + }
  156235. +
  156236. + return 0;
  156237. + }
  156238. +
  156239. + gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], gcvNOTIFY_INTERRUPT, gcvFALSE);
  156240. + }
  156241. +}
  156242. +
  156243. +static irqreturn_t isrRoutine2D(int irq, void *ctxt)
  156244. +{
  156245. + gceSTATUS status;
  156246. + gckGALDEVICE device;
  156247. +
  156248. + device = (gckGALDEVICE) ctxt;
  156249. +
  156250. + /* Call kernel interrupt notification. */
  156251. + status = gckKERNEL_Notify(device->kernels[gcvCORE_2D], gcvNOTIFY_INTERRUPT, gcvTRUE);
  156252. +
  156253. + if (gcmIS_SUCCESS(status))
  156254. + {
  156255. + device->dataReadys[gcvCORE_2D] = gcvTRUE;
  156256. +
  156257. + up(&device->semas[gcvCORE_2D]);
  156258. +
  156259. + return IRQ_HANDLED;
  156260. + }
  156261. +
  156262. + return IRQ_NONE;
  156263. +}
  156264. +
  156265. +static int threadRoutine2D(void *ctxt)
  156266. +{
  156267. + gckGALDEVICE device = (gckGALDEVICE) ctxt;
  156268. +
  156269. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  156270. + "Starting isr Thread with extension=%p",
  156271. + device);
  156272. +
  156273. + for (;;)
  156274. + {
  156275. + static int down;
  156276. +
  156277. + down = down_interruptible(&device->semas[gcvCORE_2D]);
  156278. + if (down); /*To make gcc 4.6 happye*/
  156279. + device->dataReadys[gcvCORE_2D] = gcvFALSE;
  156280. +
  156281. + if (device->killThread == gcvTRUE)
  156282. + {
  156283. + /* The daemon exits. */
  156284. + while (!kthread_should_stop())
  156285. + {
  156286. + gckOS_Delay(device->os, 1);
  156287. + }
  156288. +
  156289. + return 0;
  156290. + }
  156291. +
  156292. + gckKERNEL_Notify(device->kernels[gcvCORE_2D], gcvNOTIFY_INTERRUPT, gcvFALSE);
  156293. + }
  156294. +}
  156295. +
  156296. +static irqreturn_t isrRoutineVG(int irq, void *ctxt)
  156297. +{
  156298. +#if gcdENABLE_VG
  156299. + gceSTATUS status;
  156300. + gckGALDEVICE device;
  156301. +
  156302. + device = (gckGALDEVICE) ctxt;
  156303. +
  156304. + /* Serve the interrupt. */
  156305. + status = gckVGINTERRUPT_Enque(device->kernels[gcvCORE_VG]->vg->interrupt);
  156306. +
  156307. + /* Determine the return value. */
  156308. + return (status == gcvSTATUS_NOT_OUR_INTERRUPT)
  156309. + ? IRQ_RETVAL(0)
  156310. + : IRQ_RETVAL(1);
  156311. +#else
  156312. + return IRQ_NONE;
  156313. +#endif
  156314. +}
  156315. +
  156316. +static int threadRoutineVG(void *ctxt)
  156317. +{
  156318. + gckGALDEVICE device = (gckGALDEVICE) ctxt;
  156319. +
  156320. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  156321. + "Starting isr Thread with extension=%p",
  156322. + device);
  156323. +
  156324. + for (;;)
  156325. + {
  156326. + static int down;
  156327. +
  156328. + down = down_interruptible(&device->semas[gcvCORE_VG]);
  156329. + if (down); /*To make gcc 4.6 happye*/
  156330. + device->dataReadys[gcvCORE_VG] = gcvFALSE;
  156331. +
  156332. + if (device->killThread == gcvTRUE)
  156333. + {
  156334. + /* The daemon exits. */
  156335. + while (!kthread_should_stop())
  156336. + {
  156337. + gckOS_Delay(device->os, 1);
  156338. + }
  156339. +
  156340. + return 0;
  156341. + }
  156342. +
  156343. + gckKERNEL_Notify(device->kernels[gcvCORE_VG], gcvNOTIFY_INTERRUPT, gcvFALSE);
  156344. + }
  156345. +}
  156346. +
  156347. +/******************************************************************************\
  156348. +******************************* gckGALDEVICE Code ******************************
  156349. +\******************************************************************************/
  156350. +
  156351. +/*******************************************************************************
  156352. +**
  156353. +** gckGALDEVICE_Construct
  156354. +**
  156355. +** Constructor.
  156356. +**
  156357. +** INPUT:
  156358. +**
  156359. +** OUTPUT:
  156360. +**
  156361. +** gckGALDEVICE * Device
  156362. +** Pointer to a variable receiving the gckGALDEVICE object pointer on
  156363. +** success.
  156364. +*/
  156365. +gceSTATUS
  156366. +gckGALDEVICE_Construct(
  156367. + IN gctINT IrqLine,
  156368. + IN gctUINT32 RegisterMemBase,
  156369. + IN gctSIZE_T RegisterMemSize,
  156370. + IN gctINT IrqLine2D,
  156371. + IN gctUINT32 RegisterMemBase2D,
  156372. + IN gctSIZE_T RegisterMemSize2D,
  156373. + IN gctINT IrqLineVG,
  156374. + IN gctUINT32 RegisterMemBaseVG,
  156375. + IN gctSIZE_T RegisterMemSizeVG,
  156376. + IN gctUINT32 ContiguousBase,
  156377. + IN gctSIZE_T ContiguousSize,
  156378. + IN gctSIZE_T BankSize,
  156379. + IN gctINT FastClear,
  156380. + IN gctINT Compression,
  156381. + IN gctUINT32 PhysBaseAddr,
  156382. + IN gctUINT32 PhysSize,
  156383. + IN gctINT Signal,
  156384. + IN gctUINT LogFileSize,
  156385. + IN struct device *pdev,
  156386. + IN gctINT PowerManagement,
  156387. + IN gctINT GpuProfiler,
  156388. + OUT gckGALDEVICE *Device
  156389. + )
  156390. +{
  156391. + gctUINT32 internalBaseAddress = 0, internalAlignment = 0;
  156392. + gctUINT32 externalBaseAddress = 0, externalAlignment = 0;
  156393. + gctUINT32 horizontalTileSize, verticalTileSize;
  156394. + struct resource* mem_region;
  156395. + gctUINT32 physAddr;
  156396. + gctUINT32 physical;
  156397. + gckGALDEVICE device;
  156398. + gceSTATUS status;
  156399. + gctINT32 i;
  156400. + gceHARDWARE_TYPE type;
  156401. + gckDB sharedDB = gcvNULL;
  156402. + gckKERNEL kernel = gcvNULL;
  156403. +
  156404. + gcmkHEADER_ARG("IrqLine=%d RegisterMemBase=0x%08x RegisterMemSize=%u "
  156405. + "IrqLine2D=%d RegisterMemBase2D=0x%08x RegisterMemSize2D=%u "
  156406. + "IrqLineVG=%d RegisterMemBaseVG=0x%08x RegisterMemSizeVG=%u "
  156407. + "ContiguousBase=0x%08x ContiguousSize=%lu BankSize=%lu "
  156408. + "FastClear=%d Compression=%d PhysBaseAddr=0x%x PhysSize=%d Signal=%d",
  156409. + IrqLine, RegisterMemBase, RegisterMemSize,
  156410. + IrqLine2D, RegisterMemBase2D, RegisterMemSize2D,
  156411. + IrqLineVG, RegisterMemBaseVG, RegisterMemSizeVG,
  156412. + ContiguousBase, ContiguousSize, BankSize, FastClear, Compression,
  156413. + PhysBaseAddr, PhysSize, Signal);
  156414. +
  156415. + /* Allocate device structure. */
  156416. + device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL);
  156417. +
  156418. + if (!device)
  156419. + {
  156420. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  156421. + }
  156422. +
  156423. + memset(device, 0, sizeof(struct _gckGALDEVICE));
  156424. +
  156425. + device->dbgnode = gcvNULL;
  156426. + if(LogFileSize != 0)
  156427. + {
  156428. + if(gckDebugFileSystemCreateNode(LogFileSize,PARENT_FILE,DEBUG_FILE,&(device->dbgnode)) != 0)
  156429. + {
  156430. + gcmkTRACE_ZONE(
  156431. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  156432. + "%s(%d): Failed to create the debug file system %s/%s \n",
  156433. + __FUNCTION__, __LINE__,
  156434. + PARENT_FILE, DEBUG_FILE
  156435. + );
  156436. + }
  156437. + else
  156438. + {
  156439. + /*Everything is OK*/
  156440. + gckDebugFileSystemSetCurrentNode(device->dbgnode);
  156441. + }
  156442. + }
  156443. +#ifdef CONFIG_PM
  156444. + /*Init runtime pm for gpu*/
  156445. + pm_runtime_enable(pdev);
  156446. + device->pmdev = pdev;
  156447. +#endif
  156448. +
  156449. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  156450. + /*get gpu regulator*/
  156451. + device->gpu_regulator = regulator_get(pdev, "cpu_vddgpu");
  156452. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  156453. + device->gpu_regulator = devm_regulator_get(pdev, "pu");
  156454. +#endif
  156455. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  156456. + if (IS_ERR(device->gpu_regulator)) {
  156457. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER,
  156458. + "%s(%d): Failed to get gpu regulator %s/%s \n",
  156459. + __FUNCTION__, __LINE__,
  156460. + PARENT_FILE, DEBUG_FILE);
  156461. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  156462. + }
  156463. +#endif
  156464. + /*Initialize the clock structure*/
  156465. + if (IrqLine != -1) {
  156466. + device->clk_3d_core = clk_get(pdev, "gpu3d_clk");
  156467. + if (!IS_ERR(device->clk_3d_core)) {
  156468. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  156469. + if (cpu_is_mx6q()) {
  156470. + device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk");
  156471. + if (IS_ERR(device->clk_3d_shader)) {
  156472. + IrqLine = -1;
  156473. + clk_put(device->clk_3d_core);
  156474. + device->clk_3d_core = NULL;
  156475. + device->clk_3d_shader = NULL;
  156476. + gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
  156477. + }
  156478. + }
  156479. +#else
  156480. + device->clk_3d_axi = clk_get(pdev, "gpu3d_axi_clk");
  156481. + device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk");
  156482. + if (IS_ERR(device->clk_3d_shader)) {
  156483. + IrqLine = -1;
  156484. + clk_put(device->clk_3d_core);
  156485. + device->clk_3d_core = NULL;
  156486. + device->clk_3d_shader = NULL;
  156487. + gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
  156488. + }
  156489. +#endif
  156490. + } else {
  156491. + IrqLine = -1;
  156492. + device->clk_3d_core = NULL;
  156493. + gckOS_Print("galcore: clk_get gpu3d_clk failed, disable 3d!\n");
  156494. + }
  156495. + }
  156496. + if ((IrqLine2D != -1) || (IrqLineVG != -1)) {
  156497. + device->clk_2d_core = clk_get(pdev, "gpu2d_clk");
  156498. + if (IS_ERR(device->clk_2d_core)) {
  156499. + IrqLine2D = -1;
  156500. + IrqLineVG = -1;
  156501. + device->clk_2d_core = NULL;
  156502. + gckOS_Print("galcore: clk_get 2d core clock failed, disable 2d/vg!\n");
  156503. + } else {
  156504. + if (IrqLine2D != -1) {
  156505. + device->clk_2d_axi = clk_get(pdev, "gpu2d_axi_clk");
  156506. + if (IS_ERR(device->clk_2d_axi)) {
  156507. + device->clk_2d_axi = NULL;
  156508. + IrqLine2D = -1;
  156509. + gckOS_Print("galcore: clk_get 2d axi clock failed, disable 2d\n");
  156510. + }
  156511. + }
  156512. + if (IrqLineVG != -1) {
  156513. + device->clk_vg_axi = clk_get(pdev, "openvg_axi_clk");
  156514. + if (IS_ERR(device->clk_vg_axi)) {
  156515. + IrqLineVG = -1;
  156516. + device->clk_vg_axi = NULL;
  156517. + gckOS_Print("galcore: clk_get vg clock failed, disable vg!\n");
  156518. + }
  156519. + }
  156520. + }
  156521. + }
  156522. +
  156523. + if (IrqLine != -1)
  156524. + {
  156525. + device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase;
  156526. + device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize;
  156527. + }
  156528. +
  156529. + if (IrqLine2D != -1)
  156530. + {
  156531. + device->requestedRegisterMemBases[gcvCORE_2D] = RegisterMemBase2D;
  156532. + device->requestedRegisterMemSizes[gcvCORE_2D] = RegisterMemSize2D;
  156533. + }
  156534. +
  156535. + if (IrqLineVG != -1)
  156536. + {
  156537. + device->requestedRegisterMemBases[gcvCORE_VG] = RegisterMemBaseVG;
  156538. + device->requestedRegisterMemSizes[gcvCORE_VG] = RegisterMemSizeVG;
  156539. + }
  156540. +
  156541. + device->requestedContiguousBase = 0;
  156542. + device->requestedContiguousSize = 0;
  156543. +
  156544. +
  156545. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  156546. + {
  156547. + physical = device->requestedRegisterMemBases[i];
  156548. +
  156549. + /* Set up register memory region. */
  156550. + if (physical != 0)
  156551. + {
  156552. + mem_region = request_mem_region(
  156553. + physical, device->requestedRegisterMemSizes[i], "galcore register region"
  156554. + );
  156555. +
  156556. + if (mem_region == gcvNULL)
  156557. + {
  156558. + gcmkTRACE_ZONE(
  156559. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  156560. + "%s(%d): Failed to claim %lu bytes @ 0x%08X\n",
  156561. + __FUNCTION__, __LINE__,
  156562. + physical, device->requestedRegisterMemSizes[i]
  156563. + );
  156564. +
  156565. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  156566. + }
  156567. +
  156568. + device->registerBases[i] = (gctPOINTER) ioremap_nocache(
  156569. + physical, device->requestedRegisterMemSizes[i]);
  156570. +
  156571. + if (device->registerBases[i] == gcvNULL)
  156572. + {
  156573. + gcmkTRACE_ZONE(
  156574. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  156575. + "%s(%d): Unable to map %ld bytes @ 0x%08X\n",
  156576. + __FUNCTION__, __LINE__,
  156577. + physical, device->requestedRegisterMemSizes[i]
  156578. + );
  156579. +
  156580. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  156581. + }
  156582. +
  156583. + physical += device->requestedRegisterMemSizes[i];
  156584. + }
  156585. + else
  156586. + {
  156587. + device->registerBases[i] = gcvNULL;
  156588. + }
  156589. + }
  156590. +
  156591. + /* Set the base address */
  156592. + device->baseAddress = PhysBaseAddr;
  156593. +
  156594. + /* Construct the gckOS object. */
  156595. + gcmkONERROR(gckOS_Construct(device, &device->os));
  156596. +
  156597. + if (IrqLine != -1)
  156598. + {
  156599. + /* Construct the gckKERNEL object. */
  156600. + gcmkONERROR(gckKERNEL_Construct(
  156601. + device->os, gcvCORE_MAJOR, device,
  156602. + gcvNULL, &device->kernels[gcvCORE_MAJOR]));
  156603. +
  156604. + sharedDB = device->kernels[gcvCORE_MAJOR]->db;
  156605. +
  156606. + /* Initialize core mapping */
  156607. + for (i = 0; i < 8; i++)
  156608. + {
  156609. + device->coreMapping[i] = gcvCORE_MAJOR;
  156610. + }
  156611. +
  156612. + /* Setup the ISR manager. */
  156613. + gcmkONERROR(gckHARDWARE_SetIsrManager(
  156614. + device->kernels[gcvCORE_MAJOR]->hardware,
  156615. + (gctISRMANAGERFUNC) gckGALDEVICE_Enable_ISR,
  156616. + (gctISRMANAGERFUNC) gckGALDEVICE_Disable_ISR,
  156617. + device
  156618. + ));
  156619. +
  156620. + gcmkONERROR(gckHARDWARE_SetFastClear(
  156621. + device->kernels[gcvCORE_MAJOR]->hardware, FastClear, Compression
  156622. + ));
  156623. +
  156624. + gcmkONERROR(gckHARDWARE_SetPowerManagement(
  156625. + device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement
  156626. + ));
  156627. +
  156628. + gcmkONERROR(gckHARDWARE_SetGpuProfiler(
  156629. + device->kernels[gcvCORE_MAJOR]->hardware, GpuProfiler
  156630. + ));
  156631. +
  156632. +#if COMMAND_PROCESSOR_VERSION == 1
  156633. + /* Start the command queue. */
  156634. + gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_MAJOR]->command));
  156635. +#endif
  156636. + }
  156637. + else
  156638. + {
  156639. + device->kernels[gcvCORE_MAJOR] = gcvNULL;
  156640. + }
  156641. +
  156642. + if (IrqLine2D != -1)
  156643. + {
  156644. + gcmkONERROR(gckKERNEL_Construct(
  156645. + device->os, gcvCORE_2D, device,
  156646. + sharedDB, &device->kernels[gcvCORE_2D]));
  156647. +
  156648. + if (sharedDB == gcvNULL) sharedDB = device->kernels[gcvCORE_2D]->db;
  156649. +
  156650. + /* Verify the hardware type */
  156651. + gcmkONERROR(gckHARDWARE_GetType(device->kernels[gcvCORE_2D]->hardware, &type));
  156652. +
  156653. + if (type != gcvHARDWARE_2D)
  156654. + {
  156655. + gcmkTRACE_ZONE(
  156656. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  156657. + "%s(%d): Unexpected hardware type: %d\n",
  156658. + __FUNCTION__, __LINE__,
  156659. + type
  156660. + );
  156661. +
  156662. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  156663. + }
  156664. +
  156665. + /* Initialize core mapping */
  156666. + if (device->kernels[gcvCORE_MAJOR] == gcvNULL)
  156667. + {
  156668. + for (i = 0; i < 8; i++)
  156669. + {
  156670. + device->coreMapping[i] = gcvCORE_2D;
  156671. + }
  156672. + }
  156673. + else
  156674. + {
  156675. + device->coreMapping[gcvHARDWARE_2D] = gcvCORE_2D;
  156676. + }
  156677. +
  156678. + /* Setup the ISR manager. */
  156679. + gcmkONERROR(gckHARDWARE_SetIsrManager(
  156680. + device->kernels[gcvCORE_2D]->hardware,
  156681. + (gctISRMANAGERFUNC) gckGALDEVICE_Enable_ISR,
  156682. + (gctISRMANAGERFUNC) gckGALDEVICE_Disable_ISR,
  156683. + device
  156684. + ));
  156685. +
  156686. + gcmkONERROR(gckHARDWARE_SetPowerManagement(
  156687. + device->kernels[gcvCORE_2D]->hardware, PowerManagement
  156688. + ));
  156689. +
  156690. +
  156691. +#if COMMAND_PROCESSOR_VERSION == 1
  156692. + /* Start the command queue. */
  156693. + gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_2D]->command));
  156694. +#endif
  156695. + }
  156696. + else
  156697. + {
  156698. + device->kernels[gcvCORE_2D] = gcvNULL;
  156699. + }
  156700. +
  156701. + if (IrqLineVG != -1)
  156702. + {
  156703. +#if gcdENABLE_VG
  156704. + gcmkONERROR(gckKERNEL_Construct(
  156705. + device->os, gcvCORE_VG, device,
  156706. + sharedDB, &device->kernels[gcvCORE_VG]));
  156707. + /* Initialize core mapping */
  156708. + if (device->kernels[gcvCORE_MAJOR] == gcvNULL
  156709. + && device->kernels[gcvCORE_2D] == gcvNULL
  156710. + )
  156711. + {
  156712. + for (i = 0; i < 8; i++)
  156713. + {
  156714. + device->coreMapping[i] = gcvCORE_VG;
  156715. + }
  156716. + }
  156717. + else
  156718. + {
  156719. + device->coreMapping[gcvHARDWARE_VG] = gcvCORE_VG;
  156720. + }
  156721. +
  156722. +
  156723. + gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
  156724. + device->kernels[gcvCORE_VG]->vg->hardware,
  156725. + PowerManagement
  156726. + ));
  156727. +
  156728. +#endif
  156729. + }
  156730. + else
  156731. + {
  156732. + device->kernels[gcvCORE_VG] = gcvNULL;
  156733. + }
  156734. +
  156735. + /* Initialize the ISR. */
  156736. + device->irqLines[gcvCORE_MAJOR] = IrqLine;
  156737. + device->irqLines[gcvCORE_2D] = IrqLine2D;
  156738. + device->irqLines[gcvCORE_VG] = IrqLineVG;
  156739. +
  156740. + /* Initialize the kernel thread semaphores. */
  156741. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  156742. + {
  156743. + if (device->irqLines[i] != -1) sema_init(&device->semas[i], 0);
  156744. + }
  156745. +
  156746. + device->signal = Signal;
  156747. +
  156748. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  156749. + {
  156750. + if (device->kernels[i] != gcvNULL) break;
  156751. + }
  156752. +
  156753. + if (i == gcdMAX_GPU_COUNT)
  156754. + {
  156755. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  156756. + }
  156757. +
  156758. +#if gcdENABLE_VG
  156759. + if (i == gcvCORE_VG)
  156760. + {
  156761. + /* Query the ceiling of the system memory. */
  156762. + gcmkONERROR(gckVGHARDWARE_QuerySystemMemory(
  156763. + device->kernels[i]->vg->hardware,
  156764. + &device->systemMemorySize,
  156765. + &device->systemMemoryBaseAddress
  156766. + ));
  156767. + /* query the amount of video memory */
  156768. + gcmkONERROR(gckVGHARDWARE_QueryMemory(
  156769. + device->kernels[i]->vg->hardware,
  156770. + &device->internalSize, &internalBaseAddress, &internalAlignment,
  156771. + &device->externalSize, &externalBaseAddress, &externalAlignment,
  156772. + &horizontalTileSize, &verticalTileSize
  156773. + ));
  156774. + }
  156775. + else
  156776. +#endif
  156777. + {
  156778. + /* Query the ceiling of the system memory. */
  156779. + gcmkONERROR(gckHARDWARE_QuerySystemMemory(
  156780. + device->kernels[i]->hardware,
  156781. + &device->systemMemorySize,
  156782. + &device->systemMemoryBaseAddress
  156783. + ));
  156784. +
  156785. + /* query the amount of video memory */
  156786. + gcmkONERROR(gckHARDWARE_QueryMemory(
  156787. + device->kernels[i]->hardware,
  156788. + &device->internalSize, &internalBaseAddress, &internalAlignment,
  156789. + &device->externalSize, &externalBaseAddress, &externalAlignment,
  156790. + &horizontalTileSize, &verticalTileSize
  156791. + ));
  156792. + }
  156793. +
  156794. +
  156795. + /* Grab the first availiable kernel */
  156796. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  156797. + {
  156798. + if (device->irqLines[i] != -1)
  156799. + {
  156800. + kernel = device->kernels[i];
  156801. + break;
  156802. + }
  156803. + }
  156804. +
  156805. + /* Set up the internal memory region. */
  156806. + if (device->internalSize > 0)
  156807. + {
  156808. + status = gckVIDMEM_Construct(
  156809. + device->os,
  156810. + internalBaseAddress, device->internalSize, internalAlignment,
  156811. + 0, &device->internalVidMem
  156812. + );
  156813. +
  156814. + if (gcmIS_ERROR(status))
  156815. + {
  156816. + /* Error, disable internal heap. */
  156817. + device->internalSize = 0;
  156818. + }
  156819. + else
  156820. + {
  156821. + /* Map internal memory. */
  156822. + device->internalLogical
  156823. + = (gctPOINTER) ioremap_nocache(physical, device->internalSize);
  156824. +
  156825. + if (device->internalLogical == gcvNULL)
  156826. + {
  156827. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  156828. + }
  156829. +
  156830. + device->internalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical;
  156831. + device->internalPhysicalName = gcmPTR_TO_NAME(device->internalPhysical);
  156832. + physical += device->internalSize;
  156833. + }
  156834. + }
  156835. +
  156836. + if (device->externalSize > 0)
  156837. + {
  156838. + /* create the external memory heap */
  156839. + status = gckVIDMEM_Construct(
  156840. + device->os,
  156841. + externalBaseAddress, device->externalSize, externalAlignment,
  156842. + 0, &device->externalVidMem
  156843. + );
  156844. +
  156845. + if (gcmIS_ERROR(status))
  156846. + {
  156847. + /* Error, disable internal heap. */
  156848. + device->externalSize = 0;
  156849. + }
  156850. + else
  156851. + {
  156852. + /* Map external memory. */
  156853. + device->externalLogical
  156854. + = (gctPOINTER) ioremap_nocache(physical, device->externalSize);
  156855. +
  156856. + if (device->externalLogical == gcvNULL)
  156857. + {
  156858. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  156859. + }
  156860. +
  156861. + device->externalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical;
  156862. + device->externalPhysicalName = gcmPTR_TO_NAME(device->externalPhysical);
  156863. + physical += device->externalSize;
  156864. + }
  156865. + }
  156866. +
  156867. + /* set up the contiguous memory */
  156868. + device->contiguousSize = ContiguousSize;
  156869. +
  156870. + if (ContiguousSize > 0)
  156871. + {
  156872. + if (ContiguousBase == 0)
  156873. + {
  156874. + while (device->contiguousSize > 0)
  156875. + {
  156876. + /* Allocate contiguous memory. */
  156877. + status = _AllocateMemory(
  156878. + device,
  156879. + device->contiguousSize,
  156880. + &device->contiguousBase,
  156881. + &device->contiguousPhysical,
  156882. + &physAddr
  156883. + );
  156884. +
  156885. + if (gcmIS_SUCCESS(status))
  156886. + {
  156887. + device->contiguousPhysicalName = gcmPTR_TO_NAME(device->contiguousPhysical);
  156888. + status = gckVIDMEM_Construct(
  156889. + device->os,
  156890. + physAddr | device->systemMemoryBaseAddress,
  156891. + device->contiguousSize,
  156892. + 64,
  156893. + BankSize,
  156894. + &device->contiguousVidMem
  156895. + );
  156896. +
  156897. + if (gcmIS_SUCCESS(status))
  156898. + {
  156899. + break;
  156900. + }
  156901. +
  156902. + gcmkONERROR(_FreeMemory(
  156903. + device,
  156904. + device->contiguousBase,
  156905. + device->contiguousPhysical
  156906. + ));
  156907. +
  156908. + gcmRELEASE_NAME(device->contiguousPhysicalName);
  156909. + device->contiguousBase = gcvNULL;
  156910. + device->contiguousPhysical = gcvNULL;
  156911. + }
  156912. +
  156913. + if (device->contiguousSize <= (4 << 20))
  156914. + {
  156915. + device->contiguousSize = 0;
  156916. + }
  156917. + else
  156918. + {
  156919. + device->contiguousSize -= (4 << 20);
  156920. + }
  156921. + }
  156922. + }
  156923. + else
  156924. + {
  156925. + /* Create the contiguous memory heap. */
  156926. + status = gckVIDMEM_Construct(
  156927. + device->os,
  156928. + ContiguousBase | device->systemMemoryBaseAddress,
  156929. + ContiguousSize,
  156930. + 64, BankSize,
  156931. + &device->contiguousVidMem
  156932. + );
  156933. +
  156934. + if (gcmIS_ERROR(status))
  156935. + {
  156936. + /* Error, disable contiguous memory pool. */
  156937. + device->contiguousVidMem = gcvNULL;
  156938. + device->contiguousSize = 0;
  156939. + }
  156940. + else
  156941. + {
  156942. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
  156943. + mem_region = request_mem_region(
  156944. + ContiguousBase, ContiguousSize, "galcore managed memory"
  156945. + );
  156946. +
  156947. + if (mem_region == gcvNULL)
  156948. + {
  156949. + gcmkTRACE_ZONE(
  156950. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  156951. + "%s(%d): Failed to claim %ld bytes @ 0x%08X\n",
  156952. + __FUNCTION__, __LINE__,
  156953. + ContiguousSize, ContiguousBase
  156954. + );
  156955. +
  156956. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  156957. + }
  156958. +#endif
  156959. +
  156960. + device->requestedContiguousBase = ContiguousBase;
  156961. + device->requestedContiguousSize = ContiguousSize;
  156962. +
  156963. +#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  156964. + if (gcmIS_CORE_PRESENT(device, gcvCORE_VG))
  156965. + {
  156966. + device->contiguousBase
  156967. +#if gcdPAGED_MEMORY_CACHEABLE
  156968. + = (gctPOINTER) ioremap_cached(ContiguousBase, ContiguousSize);
  156969. +#else
  156970. + = (gctPOINTER) ioremap_nocache(ContiguousBase, ContiguousSize);
  156971. +#endif
  156972. + if (device->contiguousBase == gcvNULL)
  156973. + {
  156974. + device->contiguousVidMem = gcvNULL;
  156975. + device->contiguousSize = 0;
  156976. +
  156977. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  156978. + }
  156979. + }
  156980. +#endif
  156981. +
  156982. + device->contiguousPhysical = gcvNULL;
  156983. + device->contiguousPhysicalName = 0;
  156984. + device->contiguousSize = ContiguousSize;
  156985. + device->contiguousMapped = gcvTRUE;
  156986. + }
  156987. + }
  156988. + }
  156989. +
  156990. + /* Return pointer to the device. */
  156991. + * Device = device;
  156992. +
  156993. + gcmkFOOTER_ARG("*Device=0x%x", * Device);
  156994. + return gcvSTATUS_OK;
  156995. +
  156996. +OnError:
  156997. + /* Roll back. */
  156998. + gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
  156999. +
  157000. + gcmkFOOTER();
  157001. + return status;
  157002. +}
  157003. +
  157004. +/*******************************************************************************
  157005. +**
  157006. +** gckGALDEVICE_Destroy
  157007. +**
  157008. +** Class destructor.
  157009. +**
  157010. +** INPUT:
  157011. +**
  157012. +** Nothing.
  157013. +**
  157014. +** OUTPUT:
  157015. +**
  157016. +** Nothing.
  157017. +**
  157018. +** RETURNS:
  157019. +**
  157020. +** Nothing.
  157021. +*/
  157022. +gceSTATUS
  157023. +gckGALDEVICE_Destroy(
  157024. + gckGALDEVICE Device)
  157025. +{
  157026. + gctINT i;
  157027. + gceSTATUS status = gcvSTATUS_OK;
  157028. + gckKERNEL kernel = gcvNULL;
  157029. +
  157030. + gcmkHEADER_ARG("Device=0x%x", Device);
  157031. +
  157032. + if (Device != gcvNULL)
  157033. + {
  157034. + /* Grab the first availiable kernel */
  157035. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  157036. + {
  157037. + if (Device->irqLines[i] != -1)
  157038. + {
  157039. + kernel = Device->kernels[i];
  157040. + break;
  157041. + }
  157042. + }
  157043. + if (Device->internalPhysicalName != 0)
  157044. + {
  157045. + gcmRELEASE_NAME(Device->internalPhysicalName);
  157046. + Device->internalPhysicalName = 0;
  157047. + }
  157048. + if (Device->externalPhysicalName != 0)
  157049. + {
  157050. + gcmRELEASE_NAME(Device->externalPhysicalName);
  157051. + Device->externalPhysicalName = 0;
  157052. + }
  157053. + if (Device->contiguousPhysicalName != 0)
  157054. + {
  157055. + gcmRELEASE_NAME(Device->contiguousPhysicalName);
  157056. + Device->contiguousPhysicalName = 0;
  157057. + }
  157058. +
  157059. +
  157060. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  157061. + {
  157062. + if (Device->kernels[i] != gcvNULL)
  157063. + {
  157064. + /* Destroy the gckKERNEL object. */
  157065. + gcmkVERIFY_OK(gckKERNEL_Destroy(Device->kernels[i]));
  157066. + Device->kernels[i] = gcvNULL;
  157067. + }
  157068. + }
  157069. +
  157070. + {
  157071. + if (Device->internalLogical != gcvNULL)
  157072. + {
  157073. + /* Unmap the internal memory. */
  157074. + iounmap(Device->internalLogical);
  157075. + Device->internalLogical = gcvNULL;
  157076. + }
  157077. +
  157078. + if (Device->internalVidMem != gcvNULL)
  157079. + {
  157080. + /* Destroy the internal heap. */
  157081. + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->internalVidMem));
  157082. + Device->internalVidMem = gcvNULL;
  157083. + }
  157084. + }
  157085. +
  157086. + {
  157087. + if (Device->externalLogical != gcvNULL)
  157088. + {
  157089. + /* Unmap the external memory. */
  157090. + iounmap(Device->externalLogical);
  157091. + Device->externalLogical = gcvNULL;
  157092. + }
  157093. +
  157094. + if (Device->externalVidMem != gcvNULL)
  157095. + {
  157096. + /* destroy the external heap */
  157097. + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->externalVidMem));
  157098. + Device->externalVidMem = gcvNULL;
  157099. + }
  157100. + }
  157101. +
  157102. + {
  157103. + if (Device->contiguousBase != gcvNULL)
  157104. + {
  157105. + if (Device->contiguousMapped)
  157106. + {
  157107. +#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  157108. + if (Device->contiguousBase)
  157109. + {
  157110. + /* Unmap the contiguous memory. */
  157111. + iounmap(Device->contiguousBase);
  157112. + }
  157113. +#endif
  157114. + }
  157115. + else
  157116. + {
  157117. + gcmkONERROR(_FreeMemory(
  157118. + Device,
  157119. + Device->contiguousBase,
  157120. + Device->contiguousPhysical
  157121. + ));
  157122. + }
  157123. +
  157124. + Device->contiguousBase = gcvNULL;
  157125. + Device->contiguousPhysical = gcvNULL;
  157126. + }
  157127. +
  157128. + if (Device->requestedContiguousBase != 0)
  157129. + {
  157130. + release_mem_region(Device->requestedContiguousBase, Device->requestedContiguousSize);
  157131. + Device->requestedContiguousBase = 0;
  157132. + Device->requestedContiguousSize = 0;
  157133. + }
  157134. +
  157135. + if (Device->contiguousVidMem != gcvNULL)
  157136. + {
  157137. + /* Destroy the contiguous heap. */
  157138. + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->contiguousVidMem));
  157139. + Device->contiguousVidMem = gcvNULL;
  157140. + }
  157141. + }
  157142. +
  157143. + {
  157144. + if(gckDebugFileSystemIsEnabled())
  157145. + {
  157146. + gckDebugFileSystemFreeNode(Device->dbgnode);
  157147. + kfree(Device->dbgnode);
  157148. + Device->dbgnode = gcvNULL;
  157149. + }
  157150. + }
  157151. +
  157152. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  157153. + {
  157154. + if (Device->registerBases[i] != gcvNULL)
  157155. + {
  157156. + /* Unmap register memory. */
  157157. + iounmap(Device->registerBases[i]);
  157158. + if (Device->requestedRegisterMemBases[i] != 0)
  157159. + {
  157160. + release_mem_region(Device->requestedRegisterMemBases[i], Device->requestedRegisterMemSizes[i]);
  157161. + }
  157162. +
  157163. + Device->registerBases[i] = gcvNULL;
  157164. + Device->requestedRegisterMemBases[i] = 0;
  157165. + Device->requestedRegisterMemSizes[i] = 0;
  157166. + }
  157167. + }
  157168. +
  157169. + /*Disable clock*/
  157170. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  157171. + if (Device->clk_3d_axi) {
  157172. + clk_put(Device->clk_3d_axi);
  157173. + Device->clk_3d_axi = NULL;
  157174. + }
  157175. +#endif
  157176. + if (Device->clk_3d_core) {
  157177. + clk_put(Device->clk_3d_core);
  157178. + Device->clk_3d_core = NULL;
  157179. + }
  157180. + if (Device->clk_3d_shader) {
  157181. + clk_put(Device->clk_3d_shader);
  157182. + Device->clk_3d_shader = NULL;
  157183. + }
  157184. + if (Device->clk_2d_core) {
  157185. + clk_put(Device->clk_2d_core);
  157186. + Device->clk_2d_core = NULL;
  157187. + }
  157188. + if (Device->clk_2d_axi) {
  157189. + clk_put(Device->clk_2d_axi);
  157190. + Device->clk_2d_axi = NULL;
  157191. + }
  157192. + if (Device->clk_vg_axi) {
  157193. + clk_put(Device->clk_vg_axi);
  157194. + Device->clk_vg_axi = NULL;
  157195. + }
  157196. +
  157197. +#ifdef CONFIG_PM
  157198. + if(Device->pmdev)
  157199. + pm_runtime_disable(Device->pmdev);
  157200. +#endif
  157201. +
  157202. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  157203. + if (Device->gpu_regulator) {
  157204. + regulator_put(Device->gpu_regulator);
  157205. + Device->gpu_regulator = NULL;
  157206. + }
  157207. +#endif
  157208. +
  157209. + /* Destroy the gckOS object. */
  157210. + if (Device->os != gcvNULL)
  157211. + {
  157212. + gcmkVERIFY_OK(gckOS_Destroy(Device->os));
  157213. + Device->os = gcvNULL;
  157214. + }
  157215. +
  157216. + /* Free the device. */
  157217. + kfree(Device);
  157218. + }
  157219. +
  157220. + gcmkFOOTER_NO();
  157221. + return gcvSTATUS_OK;
  157222. +
  157223. +OnError:
  157224. + gcmkFOOTER();
  157225. + return status;
  157226. +}
  157227. +
  157228. +/*******************************************************************************
  157229. +**
  157230. +** gckGALDEVICE_Setup_ISR
  157231. +**
  157232. +** Start the ISR routine.
  157233. +**
  157234. +** INPUT:
  157235. +**
  157236. +** gckGALDEVICE Device
  157237. +** Pointer to an gckGALDEVICE object.
  157238. +**
  157239. +** OUTPUT:
  157240. +**
  157241. +** Nothing.
  157242. +**
  157243. +** RETURNS:
  157244. +**
  157245. +** gcvSTATUS_OK
  157246. +** Setup successfully.
  157247. +** gcvSTATUS_GENERIC_IO
  157248. +** Setup failed.
  157249. +*/
  157250. +gceSTATUS
  157251. +gckGALDEVICE_Setup_ISR(
  157252. + IN gckGALDEVICE Device,
  157253. + IN gceCORE Core
  157254. + )
  157255. +{
  157256. + gceSTATUS status;
  157257. + gctINT ret = -1;
  157258. +
  157259. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  157260. +
  157261. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157262. +
  157263. + if (Device->irqLines[Core] < 0)
  157264. + {
  157265. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157266. + }
  157267. +
  157268. + /* Hook up the isr based on the irq line. */
  157269. +#ifdef FLAREON
  157270. + gc500_handle.dev_name = "galcore interrupt service";
  157271. + gc500_handle.dev_id = Device;
  157272. + switch (Core) {
  157273. + case gcvCORE_MAJOR:
  157274. + gc500_handle.handler = isrRoutine;
  157275. + break;
  157276. + case gcvCORE_2D:
  157277. + gc500_handle.handler = isrRoutine2D;
  157278. + break;
  157279. + case gcvCORE_VG:
  157280. + gc500_handle.handler = isrRoutineVG;
  157281. + break;
  157282. + default:
  157283. + break;
  157284. + }
  157285. + gc500_handle.intr_gen = GPIO_INTR_LEVEL_TRIGGER;
  157286. + gc500_handle.intr_trig = GPIO_TRIG_HIGH_LEVEL;
  157287. +
  157288. + ret = dove_gpio_request(
  157289. + DOVE_GPIO0_7, &gc500_handle
  157290. + );
  157291. +#else
  157292. + switch (Core) {
  157293. + case gcvCORE_MAJOR:
  157294. + ret = request_irq(
  157295. + Device->irqLines[Core], isrRoutine, IRQF_DISABLED,
  157296. + "galcore interrupt service", Device
  157297. + );
  157298. + break;
  157299. + case gcvCORE_2D:
  157300. + ret = request_irq(
  157301. + Device->irqLines[Core], isrRoutine2D, IRQF_DISABLED,
  157302. + "galcore 2D interrupt service", Device
  157303. + );
  157304. + break;
  157305. + case gcvCORE_VG:
  157306. + ret = request_irq(
  157307. + Device->irqLines[Core], isrRoutineVG, IRQF_DISABLED,
  157308. + "galcore VG interrupt service", Device
  157309. + );
  157310. + break;
  157311. + default:
  157312. + break;
  157313. + }
  157314. +#endif
  157315. +
  157316. + if (ret != 0)
  157317. + {
  157318. + gcmkTRACE_ZONE(
  157319. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  157320. + "%s(%d): Could not register irq line %d (error=%d)\n",
  157321. + __FUNCTION__, __LINE__,
  157322. + Device->irqLines[Core], ret
  157323. + );
  157324. +
  157325. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157326. + }
  157327. +
  157328. + Device->isrEnabled[Core] = 1;
  157329. +
  157330. + /* Mark ISR as initialized. */
  157331. + Device->isrInitializeds[Core] = gcvTRUE;
  157332. +
  157333. + gcmkFOOTER_NO();
  157334. + return gcvSTATUS_OK;
  157335. +
  157336. +OnError:
  157337. + gcmkFOOTER();
  157338. + return status;
  157339. +}
  157340. +
  157341. +gceSTATUS
  157342. +gckGALDEVICE_Enable_ISR(
  157343. + IN gckGALDEVICE Device,
  157344. + IN gceCORE Core
  157345. + )
  157346. +{
  157347. + gceSTATUS status;
  157348. +
  157349. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  157350. +
  157351. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157352. +
  157353. + if (Device->irqLines[Core] < 0)
  157354. + {
  157355. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157356. + }
  157357. +
  157358. + spin_lock(&Device->kernels[Core]->irq_lock);
  157359. + if (Device->isrEnabled[Core] == 0)
  157360. + {
  157361. + enable_irq(Device->irqLines[Core]);
  157362. + /* Mark ISR as initialized. */
  157363. + Device->isrEnabled[Core] = gcvTRUE;
  157364. + }
  157365. + Device->isrEnabled[Core]++;
  157366. + spin_unlock(&Device->kernels[Core]->irq_lock);
  157367. +
  157368. + gcmkFOOTER_NO();
  157369. + return gcvSTATUS_OK;
  157370. +
  157371. +OnError:
  157372. + gcmkFOOTER();
  157373. + return status;
  157374. +}
  157375. +
  157376. +/*******************************************************************************
  157377. +**
  157378. +** gckGALDEVICE_Release_ISR
  157379. +**
  157380. +** Release the irq line.
  157381. +**
  157382. +** INPUT:
  157383. +**
  157384. +** gckGALDEVICE Device
  157385. +** Pointer to an gckGALDEVICE object.
  157386. +**
  157387. +** OUTPUT:
  157388. +**
  157389. +** Nothing.
  157390. +**
  157391. +** RETURNS:
  157392. +**
  157393. +** Nothing.
  157394. +*/
  157395. +gceSTATUS
  157396. +gckGALDEVICE_Release_ISR(
  157397. + IN gckGALDEVICE Device,
  157398. + IN gceCORE Core
  157399. + )
  157400. +{
  157401. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  157402. +
  157403. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157404. +
  157405. + /* release the irq */
  157406. + if (Device->isrInitializeds[Core])
  157407. + {
  157408. +#ifdef FLAREON
  157409. + dove_gpio_free(DOVE_GPIO0_7, "galcore interrupt service");
  157410. +#else
  157411. + free_irq(Device->irqLines[Core], Device);
  157412. +#endif
  157413. +
  157414. + Device->isrInitializeds[Core] = gcvFALSE;
  157415. + }
  157416. +
  157417. + gcmkFOOTER_NO();
  157418. + return gcvSTATUS_OK;
  157419. +}
  157420. +
  157421. +gceSTATUS
  157422. +gckGALDEVICE_Disable_ISR(
  157423. + IN gckGALDEVICE Device,
  157424. + IN gceCORE Core
  157425. + )
  157426. +{
  157427. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  157428. +
  157429. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157430. +
  157431. + /* disable the irq */
  157432. + spin_lock(&Device->kernels[Core]->irq_lock);
  157433. + if (Device->isrEnabled[Core] > 0)
  157434. + {
  157435. + Device->isrEnabled[Core]--;
  157436. + if (Device->isrEnabled[Core] == 0)
  157437. + disable_irq(Device->irqLines[Core]);
  157438. + }
  157439. + spin_unlock(&Device->kernels[Core]->irq_lock);
  157440. +
  157441. + gcmkFOOTER_NO();
  157442. + return gcvSTATUS_OK;
  157443. +}
  157444. +
  157445. +/*******************************************************************************
  157446. +**
  157447. +** gckGALDEVICE_Start_Threads
  157448. +**
  157449. +** Start the daemon threads.
  157450. +**
  157451. +** INPUT:
  157452. +**
  157453. +** gckGALDEVICE Device
  157454. +** Pointer to an gckGALDEVICE object.
  157455. +**
  157456. +** OUTPUT:
  157457. +**
  157458. +** Nothing.
  157459. +**
  157460. +** RETURNS:
  157461. +**
  157462. +** gcvSTATUS_OK
  157463. +** Start successfully.
  157464. +** gcvSTATUS_GENERIC_IO
  157465. +** Start failed.
  157466. +*/
  157467. +gceSTATUS
  157468. +gckGALDEVICE_Start_Threads(
  157469. + IN gckGALDEVICE Device
  157470. + )
  157471. +{
  157472. + gceSTATUS status;
  157473. + struct task_struct * task;
  157474. +
  157475. + gcmkHEADER_ARG("Device=0x%x", Device);
  157476. +
  157477. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157478. +
  157479. + if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
  157480. + {
  157481. + /* Start the kernel thread. */
  157482. + task = kthread_run(threadRoutine, Device, "galcore daemon thread");
  157483. +
  157484. + if (IS_ERR(task))
  157485. + {
  157486. + gcmkTRACE_ZONE(
  157487. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  157488. + "%s(%d): Could not start the kernel thread.\n",
  157489. + __FUNCTION__, __LINE__
  157490. + );
  157491. +
  157492. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157493. + }
  157494. +
  157495. + Device->threadCtxts[gcvCORE_MAJOR] = task;
  157496. + Device->threadInitializeds[gcvCORE_MAJOR] = gcvTRUE;
  157497. + }
  157498. +
  157499. + if (Device->kernels[gcvCORE_2D] != gcvNULL)
  157500. + {
  157501. + /* Start the kernel thread. */
  157502. + task = kthread_run(threadRoutine2D, Device, "galcore daemon thread for 2D");
  157503. +
  157504. + if (IS_ERR(task))
  157505. + {
  157506. + gcmkTRACE_ZONE(
  157507. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  157508. + "%s(%d): Could not start the kernel thread.\n",
  157509. + __FUNCTION__, __LINE__
  157510. + );
  157511. +
  157512. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157513. + }
  157514. +
  157515. + Device->threadCtxts[gcvCORE_2D] = task;
  157516. + Device->threadInitializeds[gcvCORE_2D] = gcvTRUE;
  157517. + }
  157518. + else
  157519. + {
  157520. + Device->threadInitializeds[gcvCORE_2D] = gcvFALSE;
  157521. + }
  157522. +
  157523. + if (Device->kernels[gcvCORE_VG] != gcvNULL)
  157524. + {
  157525. + /* Start the kernel thread. */
  157526. + task = kthread_run(threadRoutineVG, Device, "galcore daemon thread for VG");
  157527. +
  157528. + if (IS_ERR(task))
  157529. + {
  157530. + gcmkTRACE_ZONE(
  157531. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  157532. + "%s(%d): Could not start the kernel thread.\n",
  157533. + __FUNCTION__, __LINE__
  157534. + );
  157535. +
  157536. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  157537. + }
  157538. +
  157539. + Device->threadCtxts[gcvCORE_VG] = task;
  157540. + Device->threadInitializeds[gcvCORE_VG] = gcvTRUE;
  157541. + }
  157542. + else
  157543. + {
  157544. + Device->threadInitializeds[gcvCORE_VG] = gcvFALSE;
  157545. + }
  157546. +
  157547. + gcmkFOOTER_NO();
  157548. + return gcvSTATUS_OK;
  157549. +
  157550. +OnError:
  157551. + gcmkFOOTER();
  157552. + return status;
  157553. +}
  157554. +
  157555. +/*******************************************************************************
  157556. +**
  157557. +** gckGALDEVICE_Stop_Threads
  157558. +**
  157559. +** Stop the gal device, including the following actions: stop the daemon
  157560. +** thread, release the irq.
  157561. +**
  157562. +** INPUT:
  157563. +**
  157564. +** gckGALDEVICE Device
  157565. +** Pointer to an gckGALDEVICE object.
  157566. +**
  157567. +** OUTPUT:
  157568. +**
  157569. +** Nothing.
  157570. +**
  157571. +** RETURNS:
  157572. +**
  157573. +** Nothing.
  157574. +*/
  157575. +gceSTATUS
  157576. +gckGALDEVICE_Stop_Threads(
  157577. + gckGALDEVICE Device
  157578. + )
  157579. +{
  157580. + gctINT i;
  157581. +
  157582. + gcmkHEADER_ARG("Device=0x%x", Device);
  157583. +
  157584. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157585. +
  157586. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  157587. + {
  157588. + /* Stop the kernel threads. */
  157589. + if (Device->threadInitializeds[i])
  157590. + {
  157591. + Device->killThread = gcvTRUE;
  157592. + up(&Device->semas[i]);
  157593. +
  157594. + kthread_stop(Device->threadCtxts[i]);
  157595. + Device->threadCtxts[i] = gcvNULL;
  157596. + Device->threadInitializeds[i] = gcvFALSE;
  157597. + }
  157598. + }
  157599. +
  157600. + gcmkFOOTER_NO();
  157601. + return gcvSTATUS_OK;
  157602. +}
  157603. +
  157604. +/*******************************************************************************
  157605. +**
  157606. +** gckGALDEVICE_Start
  157607. +**
  157608. +** Start the gal device, including the following actions: setup the isr routine
  157609. +** and start the daemoni thread.
  157610. +**
  157611. +** INPUT:
  157612. +**
  157613. +** gckGALDEVICE Device
  157614. +** Pointer to an gckGALDEVICE object.
  157615. +**
  157616. +** OUTPUT:
  157617. +**
  157618. +** Nothing.
  157619. +**
  157620. +** RETURNS:
  157621. +**
  157622. +** gcvSTATUS_OK
  157623. +** Start successfully.
  157624. +*/
  157625. +gceSTATUS
  157626. +gckGALDEVICE_Start(
  157627. + IN gckGALDEVICE Device
  157628. + )
  157629. +{
  157630. + gceSTATUS status;
  157631. +
  157632. + gcmkHEADER_ARG("Device=0x%x", Device);
  157633. +
  157634. + /* Start the kernel thread. */
  157635. + gcmkONERROR(gckGALDEVICE_Start_Threads(Device));
  157636. +
  157637. + if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
  157638. + {
  157639. + /* Setup the ISR routine. */
  157640. + gcmkONERROR(gckGALDEVICE_Setup_ISR(Device, gcvCORE_MAJOR));
  157641. +
  157642. + /* Switch to SUSPEND power state. */
  157643. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  157644. + Device->kernels[gcvCORE_MAJOR]->hardware, gcvPOWER_OFF_BROADCAST
  157645. + ));
  157646. + }
  157647. +
  157648. + if (Device->kernels[gcvCORE_2D] != gcvNULL)
  157649. + {
  157650. + /* Setup the ISR routine. */
  157651. + gcmkONERROR(gckGALDEVICE_Setup_ISR(Device, gcvCORE_2D));
  157652. +
  157653. + /* Switch to SUSPEND power state. */
  157654. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  157655. + Device->kernels[gcvCORE_2D]->hardware, gcvPOWER_OFF_BROADCAST
  157656. + ));
  157657. + }
  157658. +
  157659. + if (Device->kernels[gcvCORE_VG] != gcvNULL)
  157660. + {
  157661. + /* Setup the ISR routine. */
  157662. + gcmkONERROR(gckGALDEVICE_Setup_ISR(Device, gcvCORE_VG));
  157663. +
  157664. + /* Switch to SUSPEND power state. */
  157665. + gcmkONERROR(gckVGHARDWARE_SetPowerManagementState(
  157666. + Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF_BROADCAST
  157667. + ));
  157668. + }
  157669. +
  157670. + gcmkFOOTER_NO();
  157671. + return gcvSTATUS_OK;
  157672. +
  157673. +OnError:
  157674. + gcmkFOOTER();
  157675. + return status;
  157676. +}
  157677. +
  157678. +/*******************************************************************************
  157679. +**
  157680. +** gckGALDEVICE_Stop
  157681. +**
  157682. +** Stop the gal device, including the following actions: stop the daemon
  157683. +** thread, release the irq.
  157684. +**
  157685. +** INPUT:
  157686. +**
  157687. +** gckGALDEVICE Device
  157688. +** Pointer to an gckGALDEVICE object.
  157689. +**
  157690. +** OUTPUT:
  157691. +**
  157692. +** Nothing.
  157693. +**
  157694. +** RETURNS:
  157695. +**
  157696. +** Nothing.
  157697. +*/
  157698. +gceSTATUS
  157699. +gckGALDEVICE_Stop(
  157700. + gckGALDEVICE Device
  157701. + )
  157702. +{
  157703. + gceSTATUS status;
  157704. +
  157705. + gcmkHEADER_ARG("Device=0x%x", Device);
  157706. +
  157707. + gcmkVERIFY_ARGUMENT(Device != NULL);
  157708. +
  157709. + if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
  157710. + {
  157711. + /* Switch to OFF power state. */
  157712. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  157713. + Device->kernels[gcvCORE_MAJOR]->hardware, gcvPOWER_OFF
  157714. + ));
  157715. +
  157716. + /* Remove the ISR routine. */
  157717. + gcmkONERROR(gckGALDEVICE_Release_ISR(Device, gcvCORE_MAJOR));
  157718. + }
  157719. +
  157720. + if (Device->kernels[gcvCORE_2D] != gcvNULL)
  157721. + {
  157722. + /* Setup the ISR routine. */
  157723. + gcmkONERROR(gckGALDEVICE_Release_ISR(Device, gcvCORE_2D));
  157724. +
  157725. + /* Switch to OFF power state. */
  157726. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  157727. + Device->kernels[gcvCORE_2D]->hardware, gcvPOWER_OFF
  157728. + ));
  157729. + }
  157730. +
  157731. + if (Device->kernels[gcvCORE_VG] != gcvNULL)
  157732. + {
  157733. + /* Setup the ISR routine. */
  157734. + gcmkONERROR(gckGALDEVICE_Release_ISR(Device, gcvCORE_VG));
  157735. +
  157736. +#if gcdENABLE_VG
  157737. + /* Switch to OFF power state. */
  157738. + gcmkONERROR(gckVGHARDWARE_SetPowerManagementState(
  157739. + Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF
  157740. + ));
  157741. +#endif
  157742. + }
  157743. +
  157744. + /* Stop the kernel thread. */
  157745. + gcmkONERROR(gckGALDEVICE_Stop_Threads(Device));
  157746. +
  157747. + gcmkFOOTER_NO();
  157748. + return gcvSTATUS_OK;
  157749. +
  157750. +OnError:
  157751. + gcmkFOOTER();
  157752. + return status;
  157753. +}
  157754. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
  157755. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h 1969-12-31 18:00:00.000000000 -0600
  157756. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h 2014-12-08 00:31:53.472418001 -0600
  157757. @@ -0,0 +1,192 @@
  157758. +/****************************************************************************
  157759. +*
  157760. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  157761. +*
  157762. +* This program is free software; you can redistribute it and/or modify
  157763. +* it under the terms of the GNU General Public License as published by
  157764. +* the Free Software Foundation; either version 2 of the license, or
  157765. +* (at your option) any later version.
  157766. +*
  157767. +* This program is distributed in the hope that it will be useful,
  157768. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  157769. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  157770. +* GNU General Public License for more details.
  157771. +*
  157772. +* You should have received a copy of the GNU General Public License
  157773. +* along with this program; if not write to the Free Software
  157774. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  157775. +*
  157776. +*****************************************************************************/
  157777. +
  157778. +
  157779. +#ifndef __gc_hal_kernel_device_h_
  157780. +#define __gc_hal_kernel_device_h_
  157781. +
  157782. +/******************************************************************************\
  157783. +******************************* gckGALDEVICE Structure *******************************
  157784. +\******************************************************************************/
  157785. +
  157786. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  157787. +struct contiguous_mem_pool {
  157788. + struct dma_attrs attrs;
  157789. + dma_addr_t phys;
  157790. + void *virt;
  157791. + size_t size;
  157792. +};
  157793. +#endif
  157794. +
  157795. +typedef struct _gckGALDEVICE
  157796. +{
  157797. + /* Objects. */
  157798. + gckOS os;
  157799. + gckKERNEL kernels[gcdMAX_GPU_COUNT];
  157800. +
  157801. + /* Attributes. */
  157802. + gctSIZE_T internalSize;
  157803. + gctPHYS_ADDR internalPhysical;
  157804. + gctUINT32 internalPhysicalName;
  157805. + gctPOINTER internalLogical;
  157806. + gckVIDMEM internalVidMem;
  157807. + gctSIZE_T externalSize;
  157808. + gctPHYS_ADDR externalPhysical;
  157809. + gctUINT32 externalPhysicalName;
  157810. + gctPOINTER externalLogical;
  157811. + gckVIDMEM externalVidMem;
  157812. + gckVIDMEM contiguousVidMem;
  157813. + gctPOINTER contiguousBase;
  157814. + gctPHYS_ADDR contiguousPhysical;
  157815. + gctUINT32 contiguousPhysicalName;
  157816. + gctSIZE_T contiguousSize;
  157817. + gctBOOL contiguousMapped;
  157818. + gctPOINTER contiguousMappedUser;
  157819. + gctSIZE_T systemMemorySize;
  157820. + gctUINT32 systemMemoryBaseAddress;
  157821. + gctPOINTER registerBases[gcdMAX_GPU_COUNT];
  157822. + gctSIZE_T registerSizes[gcdMAX_GPU_COUNT];
  157823. + gctUINT32 baseAddress;
  157824. + gctUINT32 requestedRegisterMemBases[gcdMAX_GPU_COUNT];
  157825. + gctSIZE_T requestedRegisterMemSizes[gcdMAX_GPU_COUNT];
  157826. + gctUINT32 requestedContiguousBase;
  157827. + gctSIZE_T requestedContiguousSize;
  157828. +
  157829. + /* IRQ management. */
  157830. + gctINT irqLines[gcdMAX_GPU_COUNT];
  157831. + gctBOOL isrInitializeds[gcdMAX_GPU_COUNT];
  157832. + gctINT isrEnabled[gcdMAX_GPU_COUNT];
  157833. + gctBOOL dataReadys[gcdMAX_GPU_COUNT];
  157834. +
  157835. + /* Thread management. */
  157836. + struct task_struct *threadCtxts[gcdMAX_GPU_COUNT];
  157837. + struct semaphore semas[gcdMAX_GPU_COUNT];
  157838. + gctBOOL threadInitializeds[gcdMAX_GPU_COUNT];
  157839. + gctBOOL killThread;
  157840. +
  157841. + /* Signal management. */
  157842. + gctINT signal;
  157843. +
  157844. + /* Core mapping */
  157845. + gceCORE coreMapping[8];
  157846. +
  157847. + /* States before suspend. */
  157848. + gceCHIPPOWERSTATE statesStored[gcdMAX_GPU_COUNT];
  157849. +
  157850. + /*Device Debug File System Entry in Kernel*/
  157851. + struct _gcsDebugFileSystemNode * dbgnode;
  157852. +
  157853. + /* Clock management.*/
  157854. + struct clk *clk_3d_core;
  157855. + struct clk *clk_3d_shader;
  157856. + struct clk *clk_3d_axi;
  157857. + struct clk *clk_2d_core;
  157858. + struct clk *clk_2d_axi;
  157859. + struct clk *clk_vg_axi;
  157860. +
  157861. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  157862. + /*Power management.*/
  157863. + struct regulator *gpu_regulator;
  157864. +#endif
  157865. + /*Run time pm*/
  157866. + struct device *pmdev;
  157867. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  157868. + struct contiguous_mem_pool *pool;
  157869. + struct reset_control *rstc[gcdMAX_GPU_COUNT];
  157870. +#endif
  157871. +}
  157872. +* gckGALDEVICE;
  157873. +
  157874. +typedef struct _gcsHAL_PRIVATE_DATA
  157875. +{
  157876. + gckGALDEVICE device;
  157877. + gctPOINTER mappedMemory;
  157878. + gctPOINTER contiguousLogical;
  157879. + /* The process opening the device may not be the same as the one that closes it. */
  157880. + gctUINT32 pidOpen;
  157881. +}
  157882. +gcsHAL_PRIVATE_DATA, * gcsHAL_PRIVATE_DATA_PTR;
  157883. +
  157884. +gceSTATUS gckGALDEVICE_Enable_ISR(
  157885. + IN gckGALDEVICE Device,
  157886. + IN gceCORE Core
  157887. + );
  157888. +
  157889. +gceSTATUS gckGALDEVICE_Disable_ISR(
  157890. + IN gckGALDEVICE Device,
  157891. + IN gceCORE Core
  157892. + );
  157893. +
  157894. +gceSTATUS gckGALDEVICE_Setup_ISR(
  157895. + IN gckGALDEVICE Device,
  157896. + IN gceCORE Core
  157897. + );
  157898. +
  157899. +gceSTATUS gckGALDEVICE_Release_ISR(
  157900. + IN gckGALDEVICE Device,
  157901. + IN gceCORE Core
  157902. + );
  157903. +
  157904. +gceSTATUS gckGALDEVICE_Start_Threads(
  157905. + IN gckGALDEVICE Device
  157906. + );
  157907. +
  157908. +gceSTATUS gckGALDEVICE_Stop_Threads(
  157909. + gckGALDEVICE Device
  157910. + );
  157911. +
  157912. +gceSTATUS gckGALDEVICE_Start(
  157913. + IN gckGALDEVICE Device
  157914. + );
  157915. +
  157916. +gceSTATUS gckGALDEVICE_Stop(
  157917. + gckGALDEVICE Device
  157918. + );
  157919. +
  157920. +gceSTATUS gckGALDEVICE_Construct(
  157921. + IN gctINT IrqLine,
  157922. + IN gctUINT32 RegisterMemBase,
  157923. + IN gctSIZE_T RegisterMemSize,
  157924. + IN gctINT IrqLine2D,
  157925. + IN gctUINT32 RegisterMemBase2D,
  157926. + IN gctSIZE_T RegisterMemSize2D,
  157927. + IN gctINT IrqLineVG,
  157928. + IN gctUINT32 RegisterMemBaseVG,
  157929. + IN gctSIZE_T RegisterMemSizeVG,
  157930. + IN gctUINT32 ContiguousBase,
  157931. + IN gctSIZE_T ContiguousSize,
  157932. + IN gctSIZE_T BankSize,
  157933. + IN gctINT FastClear,
  157934. + IN gctINT Compression,
  157935. + IN gctUINT32 PhysBaseAddr,
  157936. + IN gctUINT32 PhysSize,
  157937. + IN gctINT Signal,
  157938. + IN gctUINT LogFileSize,
  157939. + IN struct device *pdev,
  157940. + IN gctINT PowerManagement,
  157941. + IN gctINT GpuProfiler,
  157942. + OUT gckGALDEVICE *Device
  157943. + );
  157944. +
  157945. +gceSTATUS gckGALDEVICE_Destroy(
  157946. + IN gckGALDEVICE Device
  157947. + );
  157948. +
  157949. +#endif /* __gc_hal_kernel_device_h_ */
  157950. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
  157951. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c 1969-12-31 18:00:00.000000000 -0600
  157952. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c 2014-12-08 00:31:53.472418001 -0600
  157953. @@ -0,0 +1,1471 @@
  157954. +/****************************************************************************
  157955. +*
  157956. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  157957. +* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  157958. +*
  157959. +* This program is free software; you can redistribute it and/or modify
  157960. +* it under the terms of the GNU General Public License as published by
  157961. +* the Free Software Foundation; either version 2 of the license, or
  157962. +* (at your option) any later version.
  157963. +*
  157964. +* This program is distributed in the hope that it will be useful,
  157965. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  157966. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  157967. +* GNU General Public License for more details.
  157968. +*
  157969. +* You should have received a copy of the GNU General Public License
  157970. +* along with this program; if not write to the Free Software
  157971. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  157972. +*
  157973. +*****************************************************************************/
  157974. +
  157975. +#include <linux/device.h>
  157976. +#include <linux/slab.h>
  157977. +#include <linux/notifier.h>
  157978. +#include "gc_hal_kernel_linux.h"
  157979. +#include "gc_hal_driver.h"
  157980. +
  157981. +#if USE_PLATFORM_DRIVER
  157982. +# include <linux/platform_device.h>
  157983. +#endif
  157984. +
  157985. +#ifdef CONFIG_PXA_DVFM
  157986. +# include <mach/dvfm.h>
  157987. +# include <mach/pxa3xx_dvfm.h>
  157988. +#endif
  157989. +
  157990. +
  157991. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  157992. +# include <linux/resmem_account.h>
  157993. +# include <linux/kernel.h>
  157994. +# include <linux/mm.h>
  157995. +# include <linux/oom.h>
  157996. +# include <linux/sched.h>
  157997. +# include <linux/notifier.h>
  157998. +
  157999. +struct task_struct *lowmem_deathpending;
  158000. +
  158001. +static int
  158002. +task_notify_func(struct notifier_block *self, unsigned long val, void *data);
  158003. +
  158004. +static struct notifier_block task_nb = {
  158005. + .notifier_call = task_notify_func,
  158006. +};
  158007. +
  158008. +static int
  158009. +task_notify_func(struct notifier_block *self, unsigned long val, void *data)
  158010. +{
  158011. + struct task_struct *task = data;
  158012. +
  158013. + if (task == lowmem_deathpending)
  158014. + lowmem_deathpending = NULL;
  158015. +
  158016. + return NOTIFY_OK;
  158017. +}
  158018. +#endif
  158019. +
  158020. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  158021. +#include <mach/viv_gpu.h>
  158022. +#else
  158023. +#include <linux/pm_runtime.h>
  158024. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
  158025. +#include <mach/busfreq.h>
  158026. +#else
  158027. +#include <linux/busfreq-imx6.h>
  158028. +#include <linux/reset.h>
  158029. +#endif
  158030. +#endif
  158031. +/* Zone used for header/footer. */
  158032. +#define _GC_OBJ_ZONE gcvZONE_DRIVER
  158033. +
  158034. +#if gcdENABLE_FSCALE_VAL_ADJUST
  158035. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  158036. +#include <linux/device_cooling.h>
  158037. +#define REG_THERMAL_NOTIFIER(a) register_devfreq_cooling_notifier(a);
  158038. +#define UNREG_THERMAL_NOTIFIER(a) unregister_devfreq_cooling_notifier(a);
  158039. +#else
  158040. +extern int register_thermal_notifier(struct notifier_block *nb);
  158041. +extern int unregister_thermal_notifier(struct notifier_block *nb);
  158042. +#define REG_THERMAL_NOTIFIER(a) register_thermal_notifier(a);
  158043. +#define UNREG_THERMAL_NOTIFIER(a) unregister_thermal_notifier(a);
  158044. +#endif
  158045. +#endif
  158046. +
  158047. +MODULE_DESCRIPTION("Vivante Graphics Driver");
  158048. +MODULE_LICENSE("GPL");
  158049. +
  158050. +static struct class* gpuClass;
  158051. +
  158052. +static gckGALDEVICE galDevice;
  158053. +
  158054. +static uint major = 199;
  158055. +module_param(major, uint, 0644);
  158056. +
  158057. +static int irqLine = -1;
  158058. +module_param(irqLine, int, 0644);
  158059. +
  158060. +static ulong registerMemBase = 0x80000000;
  158061. +module_param(registerMemBase, ulong, 0644);
  158062. +
  158063. +static ulong registerMemSize = 2 << 10;
  158064. +module_param(registerMemSize, ulong, 0644);
  158065. +
  158066. +static int irqLine2D = -1;
  158067. +module_param(irqLine2D, int, 0644);
  158068. +
  158069. +static ulong registerMemBase2D = 0x00000000;
  158070. +module_param(registerMemBase2D, ulong, 0644);
  158071. +
  158072. +static ulong registerMemSize2D = 2 << 10;
  158073. +module_param(registerMemSize2D, ulong, 0644);
  158074. +
  158075. +static int irqLineVG = -1;
  158076. +module_param(irqLineVG, int, 0644);
  158077. +
  158078. +static ulong registerMemBaseVG = 0x00000000;
  158079. +module_param(registerMemBaseVG, ulong, 0644);
  158080. +
  158081. +static ulong registerMemSizeVG = 2 << 10;
  158082. +module_param(registerMemSizeVG, ulong, 0644);
  158083. +
  158084. +#if gcdENABLE_FSCALE_VAL_ADJUST
  158085. +static ulong contiguousSize = 128 << 20;
  158086. +#else
  158087. +static ulong contiguousSize = 4 << 20;
  158088. +#endif
  158089. +module_param(contiguousSize, ulong, 0644);
  158090. +
  158091. +static ulong contiguousBase = 0;
  158092. +module_param(contiguousBase, ulong, 0644);
  158093. +
  158094. +static ulong bankSize = 0;
  158095. +module_param(bankSize, ulong, 0644);
  158096. +
  158097. +static int fastClear = -1;
  158098. +module_param(fastClear, int, 0644);
  158099. +
  158100. +static int compression = -1;
  158101. +module_param(compression, int, 0644);
  158102. +
  158103. +static int powerManagement = 1;
  158104. +module_param(powerManagement, int, 0644);
  158105. +
  158106. +static int gpuProfiler = 0;
  158107. +module_param(gpuProfiler, int, 0644);
  158108. +
  158109. +static int signal = 48;
  158110. +module_param(signal, int, 0644);
  158111. +
  158112. +static ulong baseAddress = 0;
  158113. +module_param(baseAddress, ulong, 0644);
  158114. +
  158115. +static ulong physSize = 0;
  158116. +module_param(physSize, ulong, 0644);
  158117. +
  158118. +static uint logFileSize=0;
  158119. +module_param(logFileSize,uint, 0644);
  158120. +
  158121. +static int showArgs = 0;
  158122. +module_param(showArgs, int, 0644);
  158123. +
  158124. +int gpu3DMinClock = 0;
  158125. +module_param(gpu3DMinClock, int, 0644);
  158126. +
  158127. +#if ENABLE_GPU_CLOCK_BY_DRIVER
  158128. + unsigned long coreClock = 156000000;
  158129. + module_param(coreClock, ulong, 0644);
  158130. +#endif
  158131. +
  158132. +static int drv_open(
  158133. + struct inode* inode,
  158134. + struct file* filp
  158135. + );
  158136. +
  158137. +static int drv_release(
  158138. + struct inode* inode,
  158139. + struct file* filp
  158140. + );
  158141. +
  158142. +static long drv_ioctl(
  158143. + struct file* filp,
  158144. + unsigned int ioctlCode,
  158145. + unsigned long arg
  158146. + );
  158147. +
  158148. +static int drv_mmap(
  158149. + struct file* filp,
  158150. + struct vm_area_struct* vma
  158151. + );
  158152. +
  158153. +static struct file_operations driver_fops =
  158154. +{
  158155. + .owner = THIS_MODULE,
  158156. + .open = drv_open,
  158157. + .release = drv_release,
  158158. + .unlocked_ioctl = drv_ioctl,
  158159. +#ifdef HAVE_COMPAT_IOCTL
  158160. + .compat_ioctl = drv_ioctl,
  158161. +#endif
  158162. + .mmap = drv_mmap,
  158163. +};
  158164. +
  158165. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  158166. +static size_t viv_gpu_resmem_query(struct task_struct *p, struct reserved_memory_account *m);
  158167. +static struct reserved_memory_account viv_gpu_resmem_handler = {
  158168. + .name = "viv_gpu",
  158169. + .get_page_used_by_process = viv_gpu_resmem_query,
  158170. +};
  158171. +
  158172. +size_t viv_gpu_resmem_query(struct task_struct *p, struct reserved_memory_account *m)
  158173. +{
  158174. + gcuDATABASE_INFO info;
  158175. + unsigned int processid = p->pid;
  158176. + gckKERNEL gpukernel = m->data;
  158177. +
  158178. + /* ignore error happens in this api. */
  158179. + if (gckKERNEL_QueryProcessDB(gpukernel, processid, false, gcvDB_VIDEO_MEMORY, &info) != gcvSTATUS_OK)
  158180. + return 0;
  158181. +
  158182. + /* we return pages. */
  158183. + if (info.counters.bytes > 0)
  158184. + return info.counters.bytes / PAGE_SIZE;
  158185. + return 0;
  158186. +}
  158187. +#endif
  158188. +
  158189. +int drv_open(
  158190. + struct inode* inode,
  158191. + struct file* filp
  158192. + )
  158193. +{
  158194. + gceSTATUS status;
  158195. + gctBOOL attached = gcvFALSE;
  158196. + gcsHAL_PRIVATE_DATA_PTR data = gcvNULL;
  158197. + gctINT i;
  158198. +
  158199. + gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp);
  158200. +
  158201. + if (filp == gcvNULL)
  158202. + {
  158203. + gcmkTRACE_ZONE(
  158204. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158205. + "%s(%d): filp is NULL\n",
  158206. + __FUNCTION__, __LINE__
  158207. + );
  158208. +
  158209. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158210. + }
  158211. +
  158212. + data = kmalloc(sizeof(gcsHAL_PRIVATE_DATA), GFP_KERNEL);
  158213. +
  158214. + if (data == gcvNULL)
  158215. + {
  158216. + gcmkTRACE_ZONE(
  158217. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158218. + "%s(%d): private_data is NULL\n",
  158219. + __FUNCTION__, __LINE__
  158220. + );
  158221. +
  158222. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  158223. + }
  158224. +
  158225. + data->device = galDevice;
  158226. + data->mappedMemory = gcvNULL;
  158227. + data->contiguousLogical = gcvNULL;
  158228. + gcmkONERROR(gckOS_GetProcessID(&data->pidOpen));
  158229. +
  158230. + /* Attached the process. */
  158231. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  158232. + {
  158233. + if (galDevice->kernels[i] != gcvNULL)
  158234. + {
  158235. + gcmkONERROR(gckKERNEL_AttachProcess(galDevice->kernels[i], gcvTRUE));
  158236. + }
  158237. + }
  158238. + attached = gcvTRUE;
  158239. +
  158240. + if (!galDevice->contiguousMapped)
  158241. + {
  158242. + gcmkONERROR(gckOS_MapMemory(
  158243. + galDevice->os,
  158244. + galDevice->contiguousPhysical,
  158245. + galDevice->contiguousSize,
  158246. + &data->contiguousLogical
  158247. + ));
  158248. + }
  158249. +
  158250. + filp->private_data = data;
  158251. +
  158252. + /* Success. */
  158253. + gcmkFOOTER_NO();
  158254. + return 0;
  158255. +
  158256. +OnError:
  158257. + if (data != gcvNULL)
  158258. + {
  158259. + if (data->contiguousLogical != gcvNULL)
  158260. + {
  158261. + gcmkVERIFY_OK(gckOS_UnmapMemory(
  158262. + galDevice->os,
  158263. + galDevice->contiguousPhysical,
  158264. + galDevice->contiguousSize,
  158265. + data->contiguousLogical
  158266. + ));
  158267. + }
  158268. +
  158269. + kfree(data);
  158270. + }
  158271. +
  158272. + if (attached)
  158273. + {
  158274. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  158275. + {
  158276. + if (galDevice->kernels[i] != gcvNULL)
  158277. + {
  158278. + gcmkVERIFY_OK(gckKERNEL_AttachProcess(galDevice->kernels[i], gcvFALSE));
  158279. + }
  158280. + }
  158281. + }
  158282. +
  158283. + gcmkFOOTER();
  158284. + return -ENOTTY;
  158285. +}
  158286. +
  158287. +int drv_release(
  158288. + struct inode* inode,
  158289. + struct file* filp
  158290. + )
  158291. +{
  158292. + gceSTATUS status;
  158293. + gcsHAL_PRIVATE_DATA_PTR data;
  158294. + gckGALDEVICE device;
  158295. + gctINT i;
  158296. +
  158297. + gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp);
  158298. +
  158299. + if (filp == gcvNULL)
  158300. + {
  158301. + gcmkTRACE_ZONE(
  158302. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158303. + "%s(%d): filp is NULL\n",
  158304. + __FUNCTION__, __LINE__
  158305. + );
  158306. +
  158307. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158308. + }
  158309. +
  158310. + data = filp->private_data;
  158311. +
  158312. + if (data == gcvNULL)
  158313. + {
  158314. + gcmkTRACE_ZONE(
  158315. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158316. + "%s(%d): private_data is NULL\n",
  158317. + __FUNCTION__, __LINE__
  158318. + );
  158319. +
  158320. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158321. + }
  158322. +
  158323. + device = data->device;
  158324. +
  158325. + if (device == gcvNULL)
  158326. + {
  158327. + gcmkTRACE_ZONE(
  158328. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158329. + "%s(%d): device is NULL\n",
  158330. + __FUNCTION__, __LINE__
  158331. + );
  158332. +
  158333. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158334. + }
  158335. +
  158336. + if (!device->contiguousMapped)
  158337. + {
  158338. + if (data->contiguousLogical != gcvNULL)
  158339. + {
  158340. + gcmkONERROR(gckOS_UnmapMemoryEx(
  158341. + galDevice->os,
  158342. + galDevice->contiguousPhysical,
  158343. + galDevice->contiguousSize,
  158344. + data->contiguousLogical,
  158345. + data->pidOpen
  158346. + ));
  158347. +
  158348. + data->contiguousLogical = gcvNULL;
  158349. + }
  158350. + }
  158351. +
  158352. + /* A process gets detached. */
  158353. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  158354. + {
  158355. + if (galDevice->kernels[i] != gcvNULL)
  158356. + {
  158357. + gcmkONERROR(gckKERNEL_AttachProcessEx(galDevice->kernels[i], gcvFALSE, data->pidOpen));
  158358. + }
  158359. + }
  158360. +
  158361. + kfree(data);
  158362. + filp->private_data = NULL;
  158363. +
  158364. + /* Success. */
  158365. + gcmkFOOTER_NO();
  158366. + return 0;
  158367. +
  158368. +OnError:
  158369. + gcmkFOOTER();
  158370. + return -ENOTTY;
  158371. +}
  158372. +
  158373. +long drv_ioctl(
  158374. + struct file* filp,
  158375. + unsigned int ioctlCode,
  158376. + unsigned long arg
  158377. + )
  158378. +{
  158379. + gceSTATUS status;
  158380. + gcsHAL_INTERFACE iface;
  158381. + gctUINT32 copyLen;
  158382. + DRIVER_ARGS drvArgs;
  158383. + gckGALDEVICE device;
  158384. + gcsHAL_PRIVATE_DATA_PTR data;
  158385. + gctINT32 i, count;
  158386. +
  158387. + gcmkHEADER_ARG(
  158388. + "filp=0x%08X ioctlCode=0x%08X arg=0x%08X",
  158389. + filp, ioctlCode, arg
  158390. + );
  158391. +
  158392. + if (filp == gcvNULL)
  158393. + {
  158394. + gcmkTRACE_ZONE(
  158395. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158396. + "%s(%d): filp is NULL\n",
  158397. + __FUNCTION__, __LINE__
  158398. + );
  158399. +
  158400. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158401. + }
  158402. +
  158403. + data = filp->private_data;
  158404. +
  158405. + if (data == gcvNULL)
  158406. + {
  158407. + gcmkTRACE_ZONE(
  158408. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158409. + "%s(%d): private_data is NULL\n",
  158410. + __FUNCTION__, __LINE__
  158411. + );
  158412. +
  158413. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158414. + }
  158415. +
  158416. + device = data->device;
  158417. +
  158418. + if (device == gcvNULL)
  158419. + {
  158420. + gcmkTRACE_ZONE(
  158421. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158422. + "%s(%d): device is NULL\n",
  158423. + __FUNCTION__, __LINE__
  158424. + );
  158425. +
  158426. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158427. + }
  158428. +
  158429. + if ((ioctlCode != IOCTL_GCHAL_INTERFACE)
  158430. + && (ioctlCode != IOCTL_GCHAL_KERNEL_INTERFACE)
  158431. + )
  158432. + {
  158433. + gcmkTRACE_ZONE(
  158434. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158435. + "%s(%d): unknown command %d\n",
  158436. + __FUNCTION__, __LINE__,
  158437. + ioctlCode
  158438. + );
  158439. +
  158440. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158441. + }
  158442. +
  158443. + /* Get the drvArgs. */
  158444. + copyLen = copy_from_user(
  158445. + &drvArgs, (void *) arg, sizeof(DRIVER_ARGS)
  158446. + );
  158447. +
  158448. + if (copyLen != 0)
  158449. + {
  158450. + gcmkTRACE_ZONE(
  158451. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158452. + "%s(%d): error copying of the input arguments.\n",
  158453. + __FUNCTION__, __LINE__
  158454. + );
  158455. +
  158456. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158457. + }
  158458. +
  158459. + /* Now bring in the gcsHAL_INTERFACE structure. */
  158460. + if ((drvArgs.InputBufferSize != sizeof(gcsHAL_INTERFACE))
  158461. + || (drvArgs.OutputBufferSize != sizeof(gcsHAL_INTERFACE))
  158462. + )
  158463. + {
  158464. + gcmkTRACE_ZONE(
  158465. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158466. + "%s(%d): input or/and output structures are invalid.\n",
  158467. + __FUNCTION__, __LINE__
  158468. + );
  158469. +
  158470. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158471. + }
  158472. +
  158473. + copyLen = copy_from_user(
  158474. + &iface, gcmUINT64_TO_PTR(drvArgs.InputBuffer), sizeof(gcsHAL_INTERFACE)
  158475. + );
  158476. +
  158477. + if (copyLen != 0)
  158478. + {
  158479. + gcmkTRACE_ZONE(
  158480. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158481. + "%s(%d): error copying of input HAL interface.\n",
  158482. + __FUNCTION__, __LINE__
  158483. + );
  158484. +
  158485. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158486. + }
  158487. +
  158488. + if (iface.command == gcvHAL_CHIP_INFO)
  158489. + {
  158490. + count = 0;
  158491. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  158492. + {
  158493. + if (device->kernels[i] != gcvNULL)
  158494. + {
  158495. +#if gcdENABLE_VG
  158496. + if (i == gcvCORE_VG)
  158497. + {
  158498. + iface.u.ChipInfo.types[count] = gcvHARDWARE_VG;
  158499. + }
  158500. + else
  158501. +#endif
  158502. + {
  158503. + gcmkVERIFY_OK(gckHARDWARE_GetType(device->kernels[i]->hardware,
  158504. + &iface.u.ChipInfo.types[count]));
  158505. + }
  158506. + count++;
  158507. + }
  158508. + }
  158509. +
  158510. + iface.u.ChipInfo.count = count;
  158511. + iface.status = status = gcvSTATUS_OK;
  158512. + }
  158513. + else
  158514. + {
  158515. + if (iface.hardwareType < 0 || iface.hardwareType > 7)
  158516. + {
  158517. + gcmkTRACE_ZONE(
  158518. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158519. + "%s(%d): unknown hardwareType %d\n",
  158520. + __FUNCTION__, __LINE__,
  158521. + iface.hardwareType
  158522. + );
  158523. +
  158524. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158525. + }
  158526. +
  158527. +#if gcdENABLE_VG
  158528. + if (device->coreMapping[iface.hardwareType] == gcvCORE_VG)
  158529. + {
  158530. + status = gckVGKERNEL_Dispatch(device->kernels[gcvCORE_VG],
  158531. + (ioctlCode == IOCTL_GCHAL_INTERFACE),
  158532. + &iface);
  158533. + }
  158534. + else
  158535. +#endif
  158536. + {
  158537. + status = gckKERNEL_Dispatch(device->kernels[device->coreMapping[iface.hardwareType]],
  158538. + (ioctlCode == IOCTL_GCHAL_INTERFACE),
  158539. + &iface);
  158540. + }
  158541. + }
  158542. +
  158543. + /* Redo system call after pending signal is handled. */
  158544. + if (status == gcvSTATUS_INTERRUPTED)
  158545. + {
  158546. + gcmkFOOTER();
  158547. + return -ERESTARTSYS;
  158548. + }
  158549. +
  158550. + if (gcmIS_SUCCESS(status) && (iface.command == gcvHAL_LOCK_VIDEO_MEMORY))
  158551. + {
  158552. + gcuVIDMEM_NODE_PTR node = gcmUINT64_TO_PTR(iface.u.LockVideoMemory.node);
  158553. + /* Special case for mapped memory. */
  158554. + if ((data->mappedMemory != gcvNULL)
  158555. + && (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  158556. + )
  158557. + {
  158558. + /* Compute offset into mapped memory. */
  158559. + gctUINT32 offset
  158560. + = (gctUINT8 *) gcmUINT64_TO_PTR(iface.u.LockVideoMemory.memory)
  158561. + - (gctUINT8 *) device->contiguousBase;
  158562. +
  158563. + /* Compute offset into user-mapped region. */
  158564. + iface.u.LockVideoMemory.memory =
  158565. + gcmPTR_TO_UINT64((gctUINT8 *) data->mappedMemory + offset);
  158566. + }
  158567. + }
  158568. +
  158569. + /* Copy data back to the user. */
  158570. + copyLen = copy_to_user(
  158571. + gcmUINT64_TO_PTR(drvArgs.OutputBuffer), &iface, sizeof(gcsHAL_INTERFACE)
  158572. + );
  158573. +
  158574. + if (copyLen != 0)
  158575. + {
  158576. + gcmkTRACE_ZONE(
  158577. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158578. + "%s(%d): error copying of output HAL interface.\n",
  158579. + __FUNCTION__, __LINE__
  158580. + );
  158581. +
  158582. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158583. + }
  158584. +
  158585. + /* Success. */
  158586. + gcmkFOOTER_NO();
  158587. + return 0;
  158588. +
  158589. +OnError:
  158590. + gcmkFOOTER();
  158591. + return -ENOTTY;
  158592. +}
  158593. +
  158594. +static int drv_mmap(
  158595. + struct file* filp,
  158596. + struct vm_area_struct* vma
  158597. + )
  158598. +{
  158599. + gceSTATUS status = gcvSTATUS_OK;
  158600. + gcsHAL_PRIVATE_DATA_PTR data;
  158601. + gckGALDEVICE device;
  158602. +
  158603. + gcmkHEADER_ARG("filp=0x%08X vma=0x%08X", filp, vma);
  158604. +
  158605. + if (filp == gcvNULL)
  158606. + {
  158607. + gcmkTRACE_ZONE(
  158608. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158609. + "%s(%d): filp is NULL\n",
  158610. + __FUNCTION__, __LINE__
  158611. + );
  158612. +
  158613. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158614. + }
  158615. +
  158616. + data = filp->private_data;
  158617. +
  158618. + if (data == gcvNULL)
  158619. + {
  158620. + gcmkTRACE_ZONE(
  158621. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158622. + "%s(%d): private_data is NULL\n",
  158623. + __FUNCTION__, __LINE__
  158624. + );
  158625. +
  158626. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158627. + }
  158628. +
  158629. + device = data->device;
  158630. +
  158631. + if (device == gcvNULL)
  158632. + {
  158633. + gcmkTRACE_ZONE(
  158634. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158635. + "%s(%d): device is NULL\n",
  158636. + __FUNCTION__, __LINE__
  158637. + );
  158638. +
  158639. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158640. + }
  158641. +
  158642. +#if !gcdPAGED_MEMORY_CACHEABLE
  158643. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  158644. + vma->vm_flags |= gcdVM_FLAGS;
  158645. +#endif
  158646. + vma->vm_pgoff = 0;
  158647. +
  158648. + if (device->contiguousMapped)
  158649. + {
  158650. + unsigned long size = vma->vm_end - vma->vm_start;
  158651. + int ret = 0;
  158652. +
  158653. + if (size > device->contiguousSize)
  158654. + {
  158655. + gcmkTRACE_ZONE(
  158656. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158657. + "%s(%d): Invalid mapping size.\n",
  158658. + __FUNCTION__, __LINE__
  158659. + );
  158660. +
  158661. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158662. + }
  158663. +
  158664. + ret = io_remap_pfn_range(
  158665. + vma,
  158666. + vma->vm_start,
  158667. + device->requestedContiguousBase >> PAGE_SHIFT,
  158668. + size,
  158669. + vma->vm_page_prot
  158670. + );
  158671. +
  158672. + if (ret != 0)
  158673. + {
  158674. + gcmkTRACE_ZONE(
  158675. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158676. + "%s(%d): io_remap_pfn_range failed %d\n",
  158677. + __FUNCTION__, __LINE__,
  158678. + ret
  158679. + );
  158680. +
  158681. + data->mappedMemory = gcvNULL;
  158682. +
  158683. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  158684. + }
  158685. +
  158686. + data->mappedMemory = (gctPOINTER) vma->vm_start;
  158687. +
  158688. + /* Success. */
  158689. + gcmkFOOTER_NO();
  158690. + return 0;
  158691. + }
  158692. +
  158693. +
  158694. +OnError:
  158695. + gcmkFOOTER();
  158696. + return -ENOTTY;
  158697. +}
  158698. +
  158699. +
  158700. +#if !USE_PLATFORM_DRIVER
  158701. +static int __init drv_init(void)
  158702. +#else
  158703. +static int drv_init(struct device *pdev)
  158704. +#endif
  158705. +{
  158706. + int ret;
  158707. + int result = -EINVAL;
  158708. + gceSTATUS status;
  158709. + gckGALDEVICE device = gcvNULL;
  158710. + struct class* device_class = gcvNULL;
  158711. +
  158712. + gcmkHEADER();
  158713. +
  158714. +#if ENABLE_GPU_CLOCK_BY_DRIVER && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
  158715. + {
  158716. +# if 0
  158717. + struct clk * clk;
  158718. +
  158719. + clk = clk_get(NULL, "GCCLK");
  158720. +
  158721. + if (IS_ERR(clk))
  158722. + {
  158723. + gcmkTRACE_ZONE(
  158724. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158725. + "%s(%d): clk get error: %d\n",
  158726. + __FUNCTION__, __LINE__,
  158727. + PTR_ERR(clk)
  158728. + );
  158729. +
  158730. + result = -ENODEV;
  158731. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  158732. + }
  158733. +
  158734. + /*
  158735. + * APMU_GC_156M, APMU_GC_312M, APMU_GC_PLL2, APMU_GC_PLL2_DIV2 currently.
  158736. + * Use the 2X clock.
  158737. + */
  158738. + if (clk_set_rate(clk, coreClock * 2))
  158739. + {
  158740. + gcmkTRACE_ZONE(
  158741. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158742. + "%s(%d): Failed to set core clock.\n",
  158743. + __FUNCTION__, __LINE__
  158744. + );
  158745. +
  158746. + result = -EAGAIN;
  158747. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  158748. + }
  158749. +
  158750. + clk_enable(clk);
  158751. +
  158752. +#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
  158753. + gc_pwr(1);
  158754. +# endif
  158755. +# endif
  158756. + }
  158757. +#endif
  158758. +
  158759. + printk(KERN_INFO "Galcore version %d.%d.%d.%d\n",
  158760. + gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD);
  158761. + /* when enable gpu profiler, we need to turn off gpu powerMangement */
  158762. + if(gpuProfiler)
  158763. + powerManagement = 0;
  158764. + if (showArgs)
  158765. + {
  158766. + printk("galcore options:\n");
  158767. + printk(" irqLine = %d\n", irqLine);
  158768. + printk(" registerMemBase = 0x%08lX\n", registerMemBase);
  158769. + printk(" registerMemSize = 0x%08lX\n", registerMemSize);
  158770. +
  158771. + if (irqLine2D != -1)
  158772. + {
  158773. + printk(" irqLine2D = %d\n", irqLine2D);
  158774. + printk(" registerMemBase2D = 0x%08lX\n", registerMemBase2D);
  158775. + printk(" registerMemSize2D = 0x%08lX\n", registerMemSize2D);
  158776. + }
  158777. +
  158778. + if (irqLineVG != -1)
  158779. + {
  158780. + printk(" irqLineVG = %d\n", irqLineVG);
  158781. + printk(" registerMemBaseVG = 0x%08lX\n", registerMemBaseVG);
  158782. + printk(" registerMemSizeVG = 0x%08lX\n", registerMemSizeVG);
  158783. + }
  158784. +
  158785. + printk(" contiguousSize = %ld\n", contiguousSize);
  158786. + printk(" contiguousBase = 0x%08lX\n", contiguousBase);
  158787. + printk(" bankSize = 0x%08lX\n", bankSize);
  158788. + printk(" fastClear = %d\n", fastClear);
  158789. + printk(" compression = %d\n", compression);
  158790. + printk(" signal = %d\n", signal);
  158791. + printk(" baseAddress = 0x%08lX\n", baseAddress);
  158792. + printk(" physSize = 0x%08lX\n", physSize);
  158793. + printk(" logFileSize = %d KB \n", logFileSize);
  158794. + printk(" powerManagement = %d\n", powerManagement);
  158795. + printk(" gpuProfiler = %d\n", gpuProfiler);
  158796. +#if ENABLE_GPU_CLOCK_BY_DRIVER
  158797. + printk(" coreClock = %lu\n", coreClock);
  158798. +#endif
  158799. + }
  158800. +
  158801. + if(logFileSize != 0)
  158802. + {
  158803. + gckDebugFileSystemInitialize();
  158804. + }
  158805. +
  158806. + /* Create the GAL device. */
  158807. + gcmkONERROR(gckGALDEVICE_Construct(
  158808. + irqLine,
  158809. + registerMemBase, registerMemSize,
  158810. + irqLine2D,
  158811. + registerMemBase2D, registerMemSize2D,
  158812. + irqLineVG,
  158813. + registerMemBaseVG, registerMemSizeVG,
  158814. + contiguousBase, contiguousSize,
  158815. + bankSize, fastClear, compression, baseAddress, physSize, signal,
  158816. + logFileSize,
  158817. + pdev,
  158818. + powerManagement,
  158819. + gpuProfiler,
  158820. + &device
  158821. + ));
  158822. +
  158823. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  158824. + device->pool = dev_get_drvdata(pdev);
  158825. +#endif
  158826. +
  158827. + /* Start the GAL device. */
  158828. + gcmkONERROR(gckGALDEVICE_Start(device));
  158829. +
  158830. + if ((physSize != 0)
  158831. + && (device->kernels[gcvCORE_MAJOR] != gcvNULL)
  158832. + && (device->kernels[gcvCORE_MAJOR]->hardware->mmuVersion != 0))
  158833. + {
  158834. + status = gckMMU_Enable(device->kernels[gcvCORE_MAJOR]->mmu, baseAddress, physSize);
  158835. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  158836. + "Enable new MMU: status=%d\n", status);
  158837. +
  158838. + if ((device->kernels[gcvCORE_2D] != gcvNULL)
  158839. + && (device->kernels[gcvCORE_2D]->hardware->mmuVersion != 0))
  158840. + {
  158841. + status = gckMMU_Enable(device->kernels[gcvCORE_2D]->mmu, baseAddress, physSize);
  158842. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  158843. + "Enable new MMU for 2D: status=%d\n", status);
  158844. + }
  158845. +
  158846. + /* Reset the base address */
  158847. + device->baseAddress = 0;
  158848. + }
  158849. +
  158850. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  158851. + task_free_register(&task_nb);
  158852. + viv_gpu_resmem_handler.data = device->kernels[gcvCORE_MAJOR];
  158853. + register_reserved_memory_account(&viv_gpu_resmem_handler);
  158854. +#endif
  158855. +
  158856. +
  158857. + /* Register the character device. */
  158858. + ret = register_chrdev(major, DRV_NAME, &driver_fops);
  158859. +
  158860. + if (ret < 0)
  158861. + {
  158862. + gcmkTRACE_ZONE(
  158863. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158864. + "%s(%d): Could not allocate major number for mmap.\n",
  158865. + __FUNCTION__, __LINE__
  158866. + );
  158867. +
  158868. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  158869. + }
  158870. +
  158871. + if (major == 0)
  158872. + {
  158873. + major = ret;
  158874. + }
  158875. +
  158876. + /* Create the device class. */
  158877. + device_class = class_create(THIS_MODULE, "graphics_class");
  158878. +
  158879. + if (IS_ERR(device_class))
  158880. + {
  158881. + gcmkTRACE_ZONE(
  158882. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158883. + "%s(%d): Failed to create the class.\n",
  158884. + __FUNCTION__, __LINE__
  158885. + );
  158886. +
  158887. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  158888. + }
  158889. +
  158890. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  158891. + device_create(device_class, NULL, MKDEV(major, 0), NULL, "galcore");
  158892. +#else
  158893. + device_create(device_class, NULL, MKDEV(major, 0), "galcore");
  158894. +#endif
  158895. +
  158896. + galDevice = device;
  158897. + gpuClass = device_class;
  158898. +
  158899. + gcmkTRACE_ZONE(
  158900. + gcvLEVEL_INFO, gcvZONE_DRIVER,
  158901. + "%s(%d): irqLine=%d, contiguousSize=%lu, memBase=0x%lX\n",
  158902. + __FUNCTION__, __LINE__,
  158903. + irqLine, contiguousSize, registerMemBase
  158904. + );
  158905. +
  158906. + /* Success. */
  158907. + gcmkFOOTER_NO();
  158908. + return 0;
  158909. +
  158910. +OnError:
  158911. + /* Roll back. */
  158912. + if (device_class != gcvNULL)
  158913. + {
  158914. + device_destroy(device_class, MKDEV(major, 0));
  158915. + class_destroy(device_class);
  158916. + }
  158917. +
  158918. + if (device != gcvNULL)
  158919. + {
  158920. + gcmkVERIFY_OK(gckGALDEVICE_Stop(device));
  158921. + gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
  158922. + }
  158923. +
  158924. + gcmkFOOTER();
  158925. + return result;
  158926. +}
  158927. +
  158928. +#if !USE_PLATFORM_DRIVER
  158929. +static void __exit drv_exit(void)
  158930. +#else
  158931. +static void drv_exit(void)
  158932. +#endif
  158933. +{
  158934. + gcmkHEADER();
  158935. +
  158936. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  158937. + task_free_unregister(&task_nb);
  158938. + unregister_reserved_memory_account(&viv_gpu_resmem_handler);
  158939. +#endif
  158940. +
  158941. + gcmkASSERT(gpuClass != gcvNULL);
  158942. + device_destroy(gpuClass, MKDEV(major, 0));
  158943. + class_destroy(gpuClass);
  158944. +
  158945. + unregister_chrdev(major, DRV_NAME);
  158946. +
  158947. + gcmkVERIFY_OK(gckGALDEVICE_Stop(galDevice));
  158948. + gcmkVERIFY_OK(gckGALDEVICE_Destroy(galDevice));
  158949. +
  158950. + if(gckDebugFileSystemIsEnabled())
  158951. + {
  158952. + gckDebugFileSystemTerminate();
  158953. + }
  158954. +
  158955. +#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
  158956. + {
  158957. +# if 0
  158958. + struct clk * clk = NULL;
  158959. +
  158960. +#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
  158961. + gc_pwr(0);
  158962. +#endif
  158963. + clk = clk_get(NULL, "GCCLK");
  158964. + clk_disable(clk);
  158965. +# endif
  158966. + }
  158967. +#endif
  158968. +
  158969. + gcmkFOOTER_NO();
  158970. +}
  158971. +
  158972. +#if !USE_PLATFORM_DRIVER
  158973. + module_init(drv_init);
  158974. + module_exit(drv_exit);
  158975. +#else
  158976. +
  158977. +#ifdef CONFIG_DOVE_GPU
  158978. +# define DEVICE_NAME "dove_gpu"
  158979. +#else
  158980. +# define DEVICE_NAME "galcore"
  158981. +#endif
  158982. +
  158983. +#if gcdENABLE_FSCALE_VAL_ADJUST
  158984. +static int thermal_hot_pm_notify(struct notifier_block *nb, unsigned long event,
  158985. + void *dummy)
  158986. +{
  158987. + static gctUINT orgFscale, minFscale, maxFscale;
  158988. + static gctBOOL bAlreadyTooHot = gcvFALSE;
  158989. + gckHARDWARE hardware = galDevice->kernels[gcvCORE_MAJOR]->hardware;
  158990. +
  158991. + if (event && !bAlreadyTooHot) {
  158992. + gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
  158993. + gckHARDWARE_SetFscaleValue(hardware, minFscale);
  158994. + bAlreadyTooHot = gcvTRUE;
  158995. + gckOS_Print("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale);
  158996. + } else if (!event && bAlreadyTooHot) {
  158997. + gckHARDWARE_SetFscaleValue(hardware, orgFscale);
  158998. + gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale);
  158999. + bAlreadyTooHot = gcvFALSE;
  159000. + }
  159001. + return NOTIFY_OK;
  159002. +}
  159003. +
  159004. +static struct notifier_block thermal_hot_pm_notifier = {
  159005. + .notifier_call = thermal_hot_pm_notify,
  159006. + };
  159007. +#endif
  159008. +
  159009. +
  159010. +
  159011. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
  159012. +static int gpu_probe(struct platform_device *pdev)
  159013. +#else
  159014. +static int __devinit gpu_probe(struct platform_device *pdev)
  159015. +#endif
  159016. +{
  159017. + int ret = -ENODEV;
  159018. + struct resource* res;
  159019. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159020. + struct contiguous_mem_pool *pool;
  159021. + struct reset_control *rstc;
  159022. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  159023. + struct device_node *dn =pdev->dev.of_node;
  159024. + const u32 *prop;
  159025. +#else
  159026. + struct viv_gpu_platform_data *pdata;
  159027. +#endif
  159028. + gcmkHEADER();
  159029. +
  159030. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phys_baseaddr");
  159031. + if (res)
  159032. + baseAddress = res->start;
  159033. +
  159034. + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_3d");
  159035. + if (res)
  159036. + irqLine = res->start;
  159037. +
  159038. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_3d");
  159039. + if (res)
  159040. + {
  159041. + registerMemBase = res->start;
  159042. + registerMemSize = res->end - res->start + 1;
  159043. + }
  159044. +
  159045. + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_2d");
  159046. + if (res)
  159047. + irqLine2D = res->start;
  159048. +
  159049. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_2d");
  159050. + if (res)
  159051. + {
  159052. + registerMemBase2D = res->start;
  159053. + registerMemSize2D = res->end - res->start + 1;
  159054. + }
  159055. +
  159056. + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_vg");
  159057. + if (res)
  159058. + irqLineVG = res->start;
  159059. +
  159060. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_vg");
  159061. + if (res)
  159062. + {
  159063. + registerMemBaseVG = res->start;
  159064. + registerMemSizeVG = res->end - res->start + 1;
  159065. + }
  159066. +
  159067. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159068. + pool = devm_kzalloc(&pdev->dev, sizeof(*pool), GFP_KERNEL);
  159069. + if (!pool)
  159070. + return -ENOMEM;
  159071. + pool->size = contiguousSize;
  159072. + init_dma_attrs(&pool->attrs);
  159073. + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &pool->attrs);
  159074. + pool->virt = dma_alloc_attrs(&pdev->dev, pool->size, &pool->phys,
  159075. + GFP_KERNEL, &pool->attrs);
  159076. + if (!pool->virt) {
  159077. + dev_err(&pdev->dev, "Failed to allocate contiguous memory\n");
  159078. + return -ENOMEM;
  159079. + }
  159080. + contiguousBase = pool->phys;
  159081. + dev_set_drvdata(&pdev->dev, pool);
  159082. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  159083. + prop = of_get_property(dn, "contiguousbase", NULL);
  159084. + if(prop)
  159085. + contiguousBase = *prop;
  159086. + of_property_read_u32(dn,"contiguoussize", (u32 *)&contiguousSize);
  159087. +#else
  159088. + pdata = pdev->dev.platform_data;
  159089. + if (pdata) {
  159090. + contiguousBase = pdata->reserved_mem_base;
  159091. + contiguousSize = pdata->reserved_mem_size;
  159092. + }
  159093. +#endif
  159094. + if (contiguousSize == 0)
  159095. + gckOS_Print("Warning: No contiguous memory is reserverd for gpu.!\n ");
  159096. + ret = drv_init(&pdev->dev);
  159097. +
  159098. + if (!ret)
  159099. + {
  159100. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159101. + rstc = devm_reset_control_get(&pdev->dev, "gpu3d");
  159102. + galDevice->rstc[gcvCORE_MAJOR] = IS_ERR(rstc) ? NULL : rstc;
  159103. +
  159104. + rstc = devm_reset_control_get(&pdev->dev, "gpu2d");
  159105. + galDevice->rstc[gcvCORE_2D] = IS_ERR(rstc) ? NULL : rstc;
  159106. +
  159107. + rstc = devm_reset_control_get(&pdev->dev, "gpuvg");
  159108. + galDevice->rstc[gcvCORE_VG] = IS_ERR(rstc) ? NULL : rstc;
  159109. +#endif
  159110. + platform_set_drvdata(pdev, galDevice);
  159111. +
  159112. +#if gcdENABLE_FSCALE_VAL_ADJUST
  159113. + if (galDevice->kernels[gcvCORE_MAJOR])
  159114. + REG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
  159115. +#endif
  159116. + gcmkFOOTER_NO();
  159117. + return ret;
  159118. + }
  159119. +#if gcdENABLE_FSCALE_VAL_ADJUST
  159120. + UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
  159121. +#endif
  159122. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159123. + dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
  159124. + &pool->attrs);
  159125. +#endif
  159126. + gcmkFOOTER_ARG(KERN_INFO "Failed to register gpu driver: %d\n", ret);
  159127. + return ret;
  159128. +}
  159129. +
  159130. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
  159131. +static int gpu_remove(struct platform_device *pdev)
  159132. +#else
  159133. +static int __devexit gpu_remove(struct platform_device *pdev)
  159134. +#endif
  159135. +{
  159136. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159137. + gckGALDEVICE device = platform_get_drvdata(pdev);
  159138. + struct contiguous_mem_pool *pool = device->pool;
  159139. +#endif
  159140. + gcmkHEADER();
  159141. +#if gcdENABLE_FSCALE_VAL_ADJUST
  159142. + if(galDevice->kernels[gcvCORE_MAJOR])
  159143. + UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
  159144. +#endif
  159145. + drv_exit();
  159146. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  159147. + dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
  159148. + &pool->attrs);
  159149. +#endif
  159150. + gcmkFOOTER_NO();
  159151. + return 0;
  159152. +}
  159153. +
  159154. +static int gpu_suspend(struct platform_device *dev, pm_message_t state)
  159155. +{
  159156. + gceSTATUS status;
  159157. + gckGALDEVICE device;
  159158. + gctINT i;
  159159. +
  159160. + device = platform_get_drvdata(dev);
  159161. +
  159162. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  159163. + {
  159164. + if (device->kernels[i] != gcvNULL)
  159165. + {
  159166. + /* Store states. */
  159167. +#if gcdENABLE_VG
  159168. + if (i == gcvCORE_VG)
  159169. + {
  159170. + status = gckVGHARDWARE_QueryPowerManagementState(device->kernels[i]->vg->hardware, &device->statesStored[i]);
  159171. + }
  159172. + else
  159173. +#endif
  159174. + {
  159175. + status = gckHARDWARE_QueryPowerManagementState(device->kernels[i]->hardware, &device->statesStored[i]);
  159176. + }
  159177. +
  159178. + if (gcmIS_ERROR(status))
  159179. + {
  159180. + return -1;
  159181. + }
  159182. +
  159183. +#if gcdENABLE_VG
  159184. + if (i == gcvCORE_VG)
  159185. + {
  159186. + status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_OFF);
  159187. + }
  159188. + else
  159189. +#endif
  159190. + {
  159191. + status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_OFF);
  159192. + }
  159193. + if (gcmIS_ERROR(status))
  159194. + {
  159195. + return -1;
  159196. + }
  159197. +
  159198. + }
  159199. + }
  159200. +
  159201. + return 0;
  159202. +}
  159203. +
  159204. +static int gpu_resume(struct platform_device *dev)
  159205. +{
  159206. + gceSTATUS status;
  159207. + gckGALDEVICE device;
  159208. + gctINT i;
  159209. + gceCHIPPOWERSTATE statesStored;
  159210. +
  159211. + device = platform_get_drvdata(dev);
  159212. +
  159213. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  159214. + {
  159215. + if (device->kernels[i] != gcvNULL)
  159216. + {
  159217. +#if gcdENABLE_VG
  159218. + if (i == gcvCORE_VG)
  159219. + {
  159220. + status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_ON);
  159221. + }
  159222. + else
  159223. +#endif
  159224. + {
  159225. + status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_ON);
  159226. + }
  159227. +
  159228. + if (gcmIS_ERROR(status))
  159229. + {
  159230. + return -1;
  159231. + }
  159232. +
  159233. + /* Convert global state to crossponding internal state. */
  159234. + switch(device->statesStored[i])
  159235. + {
  159236. + case gcvPOWER_OFF:
  159237. + statesStored = gcvPOWER_OFF_BROADCAST;
  159238. + break;
  159239. + case gcvPOWER_IDLE:
  159240. + statesStored = gcvPOWER_IDLE_BROADCAST;
  159241. + break;
  159242. + case gcvPOWER_SUSPEND:
  159243. + statesStored = gcvPOWER_SUSPEND_BROADCAST;
  159244. + break;
  159245. + case gcvPOWER_ON:
  159246. + statesStored = gcvPOWER_ON_AUTO;
  159247. + break;
  159248. + default:
  159249. + statesStored = device->statesStored[i];
  159250. + break;
  159251. + }
  159252. +
  159253. + /* Restore states. */
  159254. +#if gcdENABLE_VG
  159255. + if (i == gcvCORE_VG)
  159256. + {
  159257. + status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, statesStored);
  159258. + }
  159259. + else
  159260. +#endif
  159261. + {
  159262. + status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, statesStored);
  159263. + }
  159264. +
  159265. + if (gcmIS_ERROR(status))
  159266. + {
  159267. + return -1;
  159268. + }
  159269. + }
  159270. + }
  159271. +
  159272. + return 0;
  159273. +}
  159274. +
  159275. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  159276. +static const struct of_device_id mxs_gpu_dt_ids[] = {
  159277. + { .compatible = "fsl,imx6q-gpu", },
  159278. + {/* sentinel */}
  159279. +};
  159280. +MODULE_DEVICE_TABLE(of, mxs_gpu_dt_ids);
  159281. +
  159282. +#ifdef CONFIG_PM
  159283. +static int gpu_runtime_suspend(struct device *dev)
  159284. +{
  159285. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 7)
  159286. + release_bus_freq(BUS_FREQ_HIGH);
  159287. +#endif
  159288. + return 0;
  159289. +}
  159290. +
  159291. +static int gpu_runtime_resume(struct device *dev)
  159292. +{
  159293. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 7)
  159294. + request_bus_freq(BUS_FREQ_HIGH);
  159295. +#endif
  159296. + return 0;
  159297. +}
  159298. +
  159299. +static int gpu_system_suspend(struct device *dev)
  159300. +{
  159301. + pm_message_t state={0};
  159302. + return gpu_suspend(to_platform_device(dev), state);
  159303. +}
  159304. +
  159305. +static int gpu_system_resume(struct device *dev)
  159306. +{
  159307. + return gpu_resume(to_platform_device(dev));
  159308. +}
  159309. +
  159310. +static const struct dev_pm_ops gpu_pm_ops = {
  159311. + SET_RUNTIME_PM_OPS(gpu_runtime_suspend, gpu_runtime_resume, NULL)
  159312. + SET_SYSTEM_SLEEP_PM_OPS(gpu_system_suspend, gpu_system_resume)
  159313. +};
  159314. +#endif
  159315. +#endif
  159316. +
  159317. +static struct platform_driver gpu_driver = {
  159318. + .probe = gpu_probe,
  159319. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
  159320. + .remove = gpu_remove,
  159321. +#else
  159322. + .remove = __devexit_p(gpu_remove),
  159323. +#endif
  159324. +
  159325. + .suspend = gpu_suspend,
  159326. + .resume = gpu_resume,
  159327. +
  159328. + .driver = {
  159329. + .name = DEVICE_NAME,
  159330. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  159331. + .of_match_table = mxs_gpu_dt_ids,
  159332. +#if CONFIG_PM
  159333. + .pm = &gpu_pm_ops,
  159334. +#endif
  159335. +#endif
  159336. + }
  159337. +};
  159338. +
  159339. +#if 0 /*CONFIG_DOVE_GPU*/
  159340. +static struct resource gpu_resources[] = {
  159341. + {
  159342. + .name = "gpu_irq",
  159343. + .flags = IORESOURCE_IRQ,
  159344. + },
  159345. + {
  159346. + .name = "gpu_base",
  159347. + .flags = IORESOURCE_MEM,
  159348. + },
  159349. + {
  159350. + .name = "gpu_mem",
  159351. + .flags = IORESOURCE_MEM,
  159352. + },
  159353. +};
  159354. +
  159355. +static struct platform_device * gpu_device;
  159356. +#endif
  159357. +
  159358. +static int __init gpu_init(void)
  159359. +{
  159360. + int ret = 0;
  159361. +
  159362. +#if 0 /*ndef CONFIG_DOVE_GPU*/
  159363. + gpu_resources[0].start = gpu_resources[0].end = irqLine;
  159364. +
  159365. + gpu_resources[1].start = registerMemBase;
  159366. + gpu_resources[1].end = registerMemBase + registerMemSize - 1;
  159367. +
  159368. + gpu_resources[2].start = contiguousBase;
  159369. + gpu_resources[2].end = contiguousBase + contiguousSize - 1;
  159370. +
  159371. + /* Allocate device */
  159372. + gpu_device = platform_device_alloc(DEVICE_NAME, -1);
  159373. + if (!gpu_device)
  159374. + {
  159375. + printk(KERN_ERR "galcore: platform_device_alloc failed.\n");
  159376. + ret = -ENOMEM;
  159377. + goto out;
  159378. + }
  159379. +
  159380. + /* Insert resource */
  159381. + ret = platform_device_add_resources(gpu_device, gpu_resources, 3);
  159382. + if (ret)
  159383. + {
  159384. + printk(KERN_ERR "galcore: platform_device_add_resources failed.\n");
  159385. + goto put_dev;
  159386. + }
  159387. +
  159388. + /* Add device */
  159389. + ret = platform_device_add(gpu_device);
  159390. + if (ret)
  159391. + {
  159392. + printk(KERN_ERR "galcore: platform_device_add failed.\n");
  159393. + goto put_dev;
  159394. + }
  159395. +#endif
  159396. +
  159397. + ret = platform_driver_register(&gpu_driver);
  159398. + if (!ret)
  159399. + {
  159400. + goto out;
  159401. + }
  159402. +
  159403. +#if 0 /*ndef CONFIG_DOVE_GPU*/
  159404. + platform_device_del(gpu_device);
  159405. +put_dev:
  159406. + platform_device_put(gpu_device);
  159407. +#endif
  159408. +
  159409. +out:
  159410. + return ret;
  159411. +}
  159412. +
  159413. +static void __exit gpu_exit(void)
  159414. +{
  159415. + platform_driver_unregister(&gpu_driver);
  159416. +#if 0 /*ndef CONFIG_DOVE_GPU*/
  159417. + platform_device_unregister(gpu_device);
  159418. +#endif
  159419. +}
  159420. +
  159421. +module_init(gpu_init);
  159422. +module_exit(gpu_exit);
  159423. +
  159424. +#endif
  159425. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c
  159426. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c 1969-12-31 18:00:00.000000000 -0600
  159427. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c 2014-12-08 00:31:53.472418001 -0600
  159428. @@ -0,0 +1,481 @@
  159429. +/****************************************************************************
  159430. +*
  159431. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  159432. +*
  159433. +* This program is free software; you can redistribute it and/or modify
  159434. +* it under the terms of the GNU General Public License as published by
  159435. +* the Free Software Foundation; either version 2 of the license, or
  159436. +* (at your option) any later version.
  159437. +*
  159438. +* This program is distributed in the hope that it will be useful,
  159439. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  159440. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  159441. +* GNU General Public License for more details.
  159442. +*
  159443. +* You should have received a copy of the GNU General Public License
  159444. +* along with this program; if not write to the Free Software
  159445. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  159446. +*
  159447. +*****************************************************************************/
  159448. +
  159449. +
  159450. +#include "gc_hal_kernel_linux.h"
  159451. +
  159452. +#define _GC_OBJ_ZONE gcvZONE_KERNEL
  159453. +
  159454. +/******************************************************************************\
  159455. +******************************* gckKERNEL API Code ******************************
  159456. +\******************************************************************************/
  159457. +
  159458. +/*******************************************************************************
  159459. +**
  159460. +** gckKERNEL_QueryVideoMemory
  159461. +**
  159462. +** Query the amount of video memory.
  159463. +**
  159464. +** INPUT:
  159465. +**
  159466. +** gckKERNEL Kernel
  159467. +** Pointer to an gckKERNEL object.
  159468. +**
  159469. +** OUTPUT:
  159470. +**
  159471. +** gcsHAL_INTERFACE * Interface
  159472. +** Pointer to an gcsHAL_INTERFACE structure that will be filled in with
  159473. +** the memory information.
  159474. +*/
  159475. +gceSTATUS
  159476. +gckKERNEL_QueryVideoMemory(
  159477. + IN gckKERNEL Kernel,
  159478. + OUT gcsHAL_INTERFACE * Interface
  159479. + )
  159480. +{
  159481. + gckGALDEVICE device;
  159482. +
  159483. + gcmkHEADER_ARG("Kernel=%p", Kernel);
  159484. +
  159485. + /* Verify the arguments. */
  159486. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  159487. + gcmkVERIFY_ARGUMENT(Interface != NULL);
  159488. +
  159489. + /* Extract the pointer to the gckGALDEVICE class. */
  159490. + device = (gckGALDEVICE) Kernel->context;
  159491. +
  159492. + /* Get internal memory size and physical address. */
  159493. + Interface->u.QueryVideoMemory.internalSize = device->internalSize;
  159494. + Interface->u.QueryVideoMemory.internalPhysical = device->internalPhysicalName;
  159495. +
  159496. + /* Get external memory size and physical address. */
  159497. + Interface->u.QueryVideoMemory.externalSize = device->externalSize;
  159498. + Interface->u.QueryVideoMemory.externalPhysical = device->externalPhysicalName;
  159499. +
  159500. + /* Get contiguous memory size and physical address. */
  159501. + Interface->u.QueryVideoMemory.contiguousSize = device->contiguousSize;
  159502. + Interface->u.QueryVideoMemory.contiguousPhysical = device->contiguousPhysicalName;
  159503. +
  159504. + /* Success. */
  159505. + gcmkFOOTER_NO();
  159506. + return gcvSTATUS_OK;
  159507. +}
  159508. +
  159509. +/*******************************************************************************
  159510. +**
  159511. +** gckKERNEL_GetVideoMemoryPool
  159512. +**
  159513. +** Get the gckVIDMEM object belonging to the specified pool.
  159514. +**
  159515. +** INPUT:
  159516. +**
  159517. +** gckKERNEL Kernel
  159518. +** Pointer to an gckKERNEL object.
  159519. +**
  159520. +** gcePOOL Pool
  159521. +** Pool to query gckVIDMEM object for.
  159522. +**
  159523. +** OUTPUT:
  159524. +**
  159525. +** gckVIDMEM * VideoMemory
  159526. +** Pointer to a variable that will hold the pointer to the gckVIDMEM
  159527. +** object belonging to the requested pool.
  159528. +*/
  159529. +gceSTATUS
  159530. +gckKERNEL_GetVideoMemoryPool(
  159531. + IN gckKERNEL Kernel,
  159532. + IN gcePOOL Pool,
  159533. + OUT gckVIDMEM * VideoMemory
  159534. + )
  159535. +{
  159536. + gckGALDEVICE device;
  159537. + gckVIDMEM videoMemory;
  159538. +
  159539. + gcmkHEADER_ARG("Kernel=%p Pool=%d", Kernel, Pool);
  159540. +
  159541. + /* Verify the arguments. */
  159542. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  159543. + gcmkVERIFY_ARGUMENT(VideoMemory != NULL);
  159544. +
  159545. + /* Extract the pointer to the gckGALDEVICE class. */
  159546. + device = (gckGALDEVICE) Kernel->context;
  159547. +
  159548. + /* Dispatch on pool. */
  159549. + switch (Pool)
  159550. + {
  159551. + case gcvPOOL_LOCAL_INTERNAL:
  159552. + /* Internal memory. */
  159553. + videoMemory = device->internalVidMem;
  159554. + break;
  159555. +
  159556. + case gcvPOOL_LOCAL_EXTERNAL:
  159557. + /* External memory. */
  159558. + videoMemory = device->externalVidMem;
  159559. + break;
  159560. +
  159561. + case gcvPOOL_SYSTEM:
  159562. + /* System memory. */
  159563. + videoMemory = device->contiguousVidMem;
  159564. + break;
  159565. +
  159566. + default:
  159567. + /* Unknown pool. */
  159568. + videoMemory = NULL;
  159569. + }
  159570. +
  159571. + /* Return pointer to the gckVIDMEM object. */
  159572. + *VideoMemory = videoMemory;
  159573. +
  159574. + /* Return status. */
  159575. + gcmkFOOTER_ARG("*VideoMemory=%p", *VideoMemory);
  159576. + return (videoMemory == NULL) ? gcvSTATUS_OUT_OF_MEMORY : gcvSTATUS_OK;
  159577. +}
  159578. +
  159579. +/*******************************************************************************
  159580. +**
  159581. +** gckKERNEL_MapMemory
  159582. +**
  159583. +** Map video memory into the current process space.
  159584. +**
  159585. +** INPUT:
  159586. +**
  159587. +** gckKERNEL Kernel
  159588. +** Pointer to an gckKERNEL object.
  159589. +**
  159590. +** gctPHYS_ADDR Physical
  159591. +** Physical address of video memory to map.
  159592. +**
  159593. +** gctSIZE_T Bytes
  159594. +** Number of bytes to map.
  159595. +**
  159596. +** OUTPUT:
  159597. +**
  159598. +** gctPOINTER * Logical
  159599. +** Pointer to a variable that will hold the base address of the mapped
  159600. +** memory region.
  159601. +*/
  159602. +gceSTATUS
  159603. +gckKERNEL_MapMemory(
  159604. + IN gckKERNEL Kernel,
  159605. + IN gctPHYS_ADDR Physical,
  159606. + IN gctSIZE_T Bytes,
  159607. + OUT gctPOINTER * Logical
  159608. + )
  159609. +{
  159610. + gckKERNEL kernel = Kernel;
  159611. + gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
  159612. +
  159613. + return gckOS_MapMemory(Kernel->os, physical, Bytes, Logical);
  159614. +}
  159615. +
  159616. +/*******************************************************************************
  159617. +**
  159618. +** gckKERNEL_UnmapMemory
  159619. +**
  159620. +** Unmap video memory from the current process space.
  159621. +**
  159622. +** INPUT:
  159623. +**
  159624. +** gckKERNEL Kernel
  159625. +** Pointer to an gckKERNEL object.
  159626. +**
  159627. +** gctPHYS_ADDR Physical
  159628. +** Physical address of video memory to map.
  159629. +**
  159630. +** gctSIZE_T Bytes
  159631. +** Number of bytes to map.
  159632. +**
  159633. +** gctPOINTER Logical
  159634. +** Base address of the mapped memory region.
  159635. +**
  159636. +** OUTPUT:
  159637. +**
  159638. +** Nothing.
  159639. +*/
  159640. +gceSTATUS
  159641. +gckKERNEL_UnmapMemory(
  159642. + IN gckKERNEL Kernel,
  159643. + IN gctPHYS_ADDR Physical,
  159644. + IN gctSIZE_T Bytes,
  159645. + IN gctPOINTER Logical
  159646. + )
  159647. +{
  159648. + gckKERNEL kernel = Kernel;
  159649. + gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
  159650. +
  159651. + return gckOS_UnmapMemory(Kernel->os, physical, Bytes, Logical);
  159652. +}
  159653. +
  159654. +/*******************************************************************************
  159655. +**
  159656. +** gckKERNEL_MapVideoMemory
  159657. +**
  159658. +** Get the logical address for a hardware specific memory address for the
  159659. +** current process.
  159660. +**
  159661. +** INPUT:
  159662. +**
  159663. +** gckKERNEL Kernel
  159664. +** Pointer to an gckKERNEL object.
  159665. +**
  159666. +** gctBOOL InUserSpace
  159667. +** gcvTRUE to map the memory into the user space.
  159668. +**
  159669. +** gctUINT32 Address
  159670. +** Hardware specific memory address.
  159671. +**
  159672. +** OUTPUT:
  159673. +**
  159674. +** gctPOINTER * Logical
  159675. +** Pointer to a variable that will hold the logical address of the
  159676. +** specified memory address.
  159677. +*/
  159678. +gceSTATUS
  159679. +gckKERNEL_MapVideoMemoryEx(
  159680. + IN gckKERNEL Kernel,
  159681. + IN gceCORE Core,
  159682. + IN gctBOOL InUserSpace,
  159683. + IN gctUINT32 Address,
  159684. + OUT gctPOINTER * Logical
  159685. + )
  159686. +{
  159687. + gckGALDEVICE device;
  159688. + PLINUX_MDL mdl;
  159689. + PLINUX_MDL_MAP mdlMap;
  159690. + gcePOOL pool;
  159691. + gctUINT32 offset, base;
  159692. + gceSTATUS status;
  159693. + gctPOINTER logical;
  159694. +
  159695. + gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x",
  159696. + Kernel, InUserSpace, Address);
  159697. +
  159698. + /* Verify the arguments. */
  159699. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  159700. + gcmkVERIFY_ARGUMENT(Logical != NULL);
  159701. +
  159702. + /* Extract the pointer to the gckGALDEVICE class. */
  159703. + device = (gckGALDEVICE) Kernel->context;
  159704. +
  159705. +#if gcdENABLE_VG
  159706. + if (Core == gcvCORE_VG)
  159707. + {
  159708. + /* Split the memory address into a pool type and offset. */
  159709. + gcmkONERROR(
  159710. + gckVGHARDWARE_SplitMemory(Kernel->vg->hardware, Address, &pool, &offset));
  159711. + }
  159712. + else
  159713. +#endif
  159714. + {
  159715. + /* Split the memory address into a pool type and offset. */
  159716. + gcmkONERROR(
  159717. + gckHARDWARE_SplitMemory(Kernel->hardware, Address, &pool, &offset));
  159718. + }
  159719. +
  159720. + /* Dispatch on pool. */
  159721. + switch (pool)
  159722. + {
  159723. + case gcvPOOL_LOCAL_INTERNAL:
  159724. + /* Internal memory. */
  159725. + logical = device->internalLogical;
  159726. + break;
  159727. +
  159728. + case gcvPOOL_LOCAL_EXTERNAL:
  159729. + /* External memory. */
  159730. + logical = device->externalLogical;
  159731. + break;
  159732. +
  159733. + case gcvPOOL_SYSTEM:
  159734. + /* System memory. */
  159735. + if (device->contiguousMapped)
  159736. + {
  159737. + logical = device->contiguousBase;
  159738. + }
  159739. + else
  159740. + {
  159741. + gctINT processID;
  159742. + gckOS_GetProcessID(&processID);
  159743. +
  159744. + mdl = (PLINUX_MDL) device->contiguousPhysical;
  159745. +
  159746. + mdlMap = FindMdlMap(mdl, processID);
  159747. + gcmkASSERT(mdlMap);
  159748. +
  159749. + logical = (gctPOINTER) mdlMap->vmaAddr;
  159750. + }
  159751. +#if gcdENABLE_VG
  159752. + if (Core == gcvCORE_VG)
  159753. + {
  159754. + gcmkVERIFY_OK(
  159755. + gckVGHARDWARE_SplitMemory(Kernel->vg->hardware,
  159756. + device->contiguousVidMem->baseAddress,
  159757. + &pool,
  159758. + &base));
  159759. + }
  159760. + else
  159761. +#endif
  159762. + {
  159763. + gctUINT32 baseAddress = 0;
  159764. +
  159765. + if (Kernel->hardware->mmuVersion == 0)
  159766. + {
  159767. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  159768. + }
  159769. +
  159770. + gcmkVERIFY_OK(
  159771. + gckHARDWARE_SplitMemory(Kernel->hardware,
  159772. + device->contiguousVidMem->baseAddress - baseAddress,
  159773. + &pool,
  159774. + &base));
  159775. + }
  159776. + offset -= base;
  159777. + break;
  159778. +
  159779. + default:
  159780. + /* Invalid memory pool. */
  159781. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  159782. + }
  159783. +
  159784. + /* Build logical address of specified address. */
  159785. + *Logical = (gctPOINTER) ((gctUINT8_PTR) logical + offset);
  159786. +
  159787. + /* Success. */
  159788. + gcmkFOOTER_ARG("*Logical=%p", *Logical);
  159789. + return gcvSTATUS_OK;
  159790. +
  159791. +OnError:
  159792. + /* Retunn the status. */
  159793. + gcmkFOOTER();
  159794. + return status;
  159795. +}
  159796. +
  159797. +/*******************************************************************************
  159798. +**
  159799. +** gckKERNEL_MapVideoMemory
  159800. +**
  159801. +** Get the logical address for a hardware specific memory address for the
  159802. +** current process.
  159803. +**
  159804. +** INPUT:
  159805. +**
  159806. +** gckKERNEL Kernel
  159807. +** Pointer to an gckKERNEL object.
  159808. +**
  159809. +** gctBOOL InUserSpace
  159810. +** gcvTRUE to map the memory into the user space.
  159811. +**
  159812. +** gctUINT32 Address
  159813. +** Hardware specific memory address.
  159814. +**
  159815. +** OUTPUT:
  159816. +**
  159817. +** gctPOINTER * Logical
  159818. +** Pointer to a variable that will hold the logical address of the
  159819. +** specified memory address.
  159820. +*/
  159821. +gceSTATUS
  159822. +gckKERNEL_MapVideoMemory(
  159823. + IN gckKERNEL Kernel,
  159824. + IN gctBOOL InUserSpace,
  159825. + IN gctUINT32 Address,
  159826. + OUT gctPOINTER * Logical
  159827. + )
  159828. +{
  159829. + return gckKERNEL_MapVideoMemoryEx(Kernel, gcvCORE_MAJOR, InUserSpace, Address, Logical);
  159830. +}
  159831. +/*******************************************************************************
  159832. +**
  159833. +** gckKERNEL_Notify
  159834. +**
  159835. +** This function iscalled by clients to notify the gckKERNRL object of an event.
  159836. +**
  159837. +** INPUT:
  159838. +**
  159839. +** gckKERNEL Kernel
  159840. +** Pointer to an gckKERNEL object.
  159841. +**
  159842. +** gceNOTIFY Notification
  159843. +** Notification event.
  159844. +**
  159845. +** OUTPUT:
  159846. +**
  159847. +** Nothing.
  159848. +*/
  159849. +gceSTATUS
  159850. +gckKERNEL_Notify(
  159851. + IN gckKERNEL Kernel,
  159852. + IN gceNOTIFY Notification,
  159853. + IN gctBOOL Data
  159854. + )
  159855. +{
  159856. + gceSTATUS status;
  159857. +
  159858. + gcmkHEADER_ARG("Kernel=%p Notification=%d Data=%d",
  159859. + Kernel, Notification, Data);
  159860. +
  159861. + /* Verify the arguments. */
  159862. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  159863. +
  159864. + /* Dispatch on notifcation. */
  159865. + switch (Notification)
  159866. + {
  159867. + case gcvNOTIFY_INTERRUPT:
  159868. + /* Process the interrupt. */
  159869. +#if COMMAND_PROCESSOR_VERSION > 1
  159870. + status = gckINTERRUPT_Notify(Kernel->interrupt, Data);
  159871. +#else
  159872. + status = gckHARDWARE_Interrupt(Kernel->hardware, Data);
  159873. +#endif
  159874. + break;
  159875. +
  159876. + default:
  159877. + status = gcvSTATUS_OK;
  159878. + break;
  159879. + }
  159880. +
  159881. + /* Success. */
  159882. + gcmkFOOTER();
  159883. + return status;
  159884. +}
  159885. +
  159886. +gceSTATUS
  159887. +gckKERNEL_QuerySettings(
  159888. + IN gckKERNEL Kernel,
  159889. + OUT gcsKERNEL_SETTINGS * Settings
  159890. + )
  159891. +{
  159892. + gckGALDEVICE device;
  159893. +
  159894. + gcmkHEADER_ARG("Kernel=%p", Kernel);
  159895. +
  159896. + /* Verify the arguments. */
  159897. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  159898. + gcmkVERIFY_ARGUMENT(Settings != gcvNULL);
  159899. +
  159900. + /* Extract the pointer to the gckGALDEVICE class. */
  159901. + device = (gckGALDEVICE) Kernel->context;
  159902. +
  159903. + /* Fill in signal. */
  159904. + Settings->signal = device->signal;
  159905. +
  159906. + /* Success. */
  159907. + gcmkFOOTER_ARG("Settings->signal=%d", Settings->signal);
  159908. + return gcvSTATUS_OK;
  159909. +}
  159910. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
  159911. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h 1969-12-31 18:00:00.000000000 -0600
  159912. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h 2014-12-08 00:31:53.472418001 -0600
  159913. @@ -0,0 +1,94 @@
  159914. +/****************************************************************************
  159915. +*
  159916. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  159917. +*
  159918. +* This program is free software; you can redistribute it and/or modify
  159919. +* it under the terms of the GNU General Public License as published by
  159920. +* the Free Software Foundation; either version 2 of the license, or
  159921. +* (at your option) any later version.
  159922. +*
  159923. +* This program is distributed in the hope that it will be useful,
  159924. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  159925. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  159926. +* GNU General Public License for more details.
  159927. +*
  159928. +* You should have received a copy of the GNU General Public License
  159929. +* along with this program; if not write to the Free Software
  159930. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  159931. +*
  159932. +*****************************************************************************/
  159933. +
  159934. +
  159935. +#ifndef __gc_hal_kernel_linux_h_
  159936. +#define __gc_hal_kernel_linux_h_
  159937. +
  159938. +#include <linux/version.h>
  159939. +#include <linux/init.h>
  159940. +#include <linux/module.h>
  159941. +#include <linux/fs.h>
  159942. +#include <linux/mm.h>
  159943. +#include <linux/sched.h>
  159944. +#include <linux/signal.h>
  159945. +#ifdef FLAREON
  159946. +# include <asm/arch-realview/dove_gpio_irq.h>
  159947. +#endif
  159948. +#include <linux/interrupt.h>
  159949. +#include <linux/vmalloc.h>
  159950. +#include <linux/dma-mapping.h>
  159951. +#include <linux/kthread.h>
  159952. +
  159953. +#ifdef MODVERSIONS
  159954. +# include <linux/modversions.h>
  159955. +#endif
  159956. +#include <asm/io.h>
  159957. +#include <asm/uaccess.h>
  159958. +
  159959. +#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
  159960. +#include <linux/clk.h>
  159961. +#include <linux/regulator/consumer.h>
  159962. +#endif
  159963. +
  159964. +#define NTSTRSAFE_NO_CCH_FUNCTIONS
  159965. +#include "gc_hal.h"
  159966. +#include "gc_hal_driver.h"
  159967. +#include "gc_hal_kernel.h"
  159968. +#include "gc_hal_kernel_device.h"
  159969. +#include "gc_hal_kernel_os.h"
  159970. +#include "gc_hal_kernel_debugfs.h"
  159971. +
  159972. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
  159973. +#define FIND_TASK_BY_PID(x) pid_task(find_vpid(x), PIDTYPE_PID)
  159974. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  159975. +#define FIND_TASK_BY_PID(x) find_task_by_vpid(x)
  159976. +#else
  159977. +#define FIND_TASK_BY_PID(x) find_task_by_pid(x)
  159978. +#endif
  159979. +
  159980. +#define _WIDE(string) L##string
  159981. +#define WIDE(string) _WIDE(string)
  159982. +
  159983. +#define countof(a) (sizeof(a) / sizeof(a[0]))
  159984. +
  159985. +#define DRV_NAME "galcore"
  159986. +
  159987. +#define GetPageCount(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
  159988. +
  159989. +#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,7,0)
  159990. +#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP)
  159991. +#else
  159992. +#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED)
  159993. +#endif
  159994. +
  159995. +static inline gctINT
  159996. +GetOrder(
  159997. + IN gctINT numPages
  159998. + )
  159999. +{
  160000. + gctINT order = 0;
  160001. +
  160002. + while ((1 << order) < numPages) order++;
  160003. +
  160004. + return order;
  160005. +}
  160006. +
  160007. +#endif /* __gc_hal_kernel_linux_h_ */
  160008. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c
  160009. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c 1969-12-31 18:00:00.000000000 -0600
  160010. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c 2014-12-08 00:31:53.472418001 -0600
  160011. @@ -0,0 +1,32 @@
  160012. +/****************************************************************************
  160013. +*
  160014. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  160015. +*
  160016. +* This program is free software; you can redistribute it and/or modify
  160017. +* it under the terms of the GNU General Public License as published by
  160018. +* the Free Software Foundation; either version 2 of the license, or
  160019. +* (at your option) any later version.
  160020. +*
  160021. +* This program is distributed in the hope that it will be useful,
  160022. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  160023. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  160024. +* GNU General Public License for more details.
  160025. +*
  160026. +* You should have received a copy of the GNU General Public License
  160027. +* along with this program; if not write to the Free Software
  160028. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  160029. +*
  160030. +*****************************************************************************/
  160031. +
  160032. +
  160033. +#include "gc_hal_kernel_linux.h"
  160034. +
  160035. +gctINT
  160036. +gckMATH_ModuloInt(
  160037. + IN gctINT X,
  160038. + IN gctINT Y
  160039. + )
  160040. +{
  160041. + if(Y ==0) {return 0;}
  160042. + else {return X % Y;}
  160043. +}
  160044. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
  160045. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c 1969-12-31 18:00:00.000000000 -0600
  160046. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c 2014-12-08 00:31:53.472418001 -0600
  160047. @@ -0,0 +1,9019 @@
  160048. +/****************************************************************************
  160049. +*
  160050. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  160051. +*
  160052. +* This program is free software; you can redistribute it and/or modify
  160053. +* it under the terms of the GNU General Public License as published by
  160054. +* the Free Software Foundation; either version 2 of the license, or
  160055. +* (at your option) any later version.
  160056. +*
  160057. +* This program is distributed in the hope that it will be useful,
  160058. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  160059. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  160060. +* GNU General Public License for more details.
  160061. +*
  160062. +* You should have received a copy of the GNU General Public License
  160063. +* along with this program; if not write to the Free Software
  160064. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  160065. +*
  160066. +*****************************************************************************/
  160067. +
  160068. +
  160069. +#include "gc_hal_kernel_linux.h"
  160070. +
  160071. +#include <linux/pagemap.h>
  160072. +#include <linux/seq_file.h>
  160073. +#include <linux/mm.h>
  160074. +#include <linux/mman.h>
  160075. +#include <linux/sched.h>
  160076. +#include <asm/atomic.h>
  160077. +#include <linux/dma-mapping.h>
  160078. +#include <linux/slab.h>
  160079. +#include <linux/idr.h>
  160080. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
  160081. +#include <mach/hardware.h>
  160082. +#endif
  160083. +#include <linux/workqueue.h>
  160084. +#include <linux/idr.h>
  160085. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
  160086. +#include <linux/math64.h>
  160087. +#endif
  160088. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  160089. +#include <linux/reset.h>
  160090. +static inline void imx_gpc_power_up_pu(bool flag) {}
  160091. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  160092. +#include <mach/common.h>
  160093. +#endif
  160094. +#include <linux/delay.h>
  160095. +#include <linux/pm_runtime.h>
  160096. +
  160097. +
  160098. +#if gcdANDROID_NATIVE_FENCE_SYNC
  160099. +#include <linux/file.h>
  160100. +#include "gc_hal_kernel_sync.h"
  160101. +#endif
  160102. +
  160103. +
  160104. +#define _GC_OBJ_ZONE gcvZONE_OS
  160105. +
  160106. +/*******************************************************************************
  160107. +***** Version Signature *******************************************************/
  160108. +
  160109. +#ifdef ANDROID
  160110. +const char * _PLATFORM = "\n\0$PLATFORM$Android$\n";
  160111. +#else
  160112. +const char * _PLATFORM = "\n\0$PLATFORM$Linux$\n";
  160113. +#endif
  160114. +
  160115. +#define USER_SIGNAL_TABLE_LEN_INIT 64
  160116. +#define gcdSUPPRESS_OOM_MESSAGE 1
  160117. +
  160118. +#define MEMORY_LOCK(os) \
  160119. + gcmkVERIFY_OK(gckOS_AcquireMutex( \
  160120. + (os), \
  160121. + (os)->memoryLock, \
  160122. + gcvINFINITE))
  160123. +
  160124. +#define MEMORY_UNLOCK(os) \
  160125. + gcmkVERIFY_OK(gckOS_ReleaseMutex((os), (os)->memoryLock))
  160126. +
  160127. +#define MEMORY_MAP_LOCK(os) \
  160128. + gcmkVERIFY_OK(gckOS_AcquireMutex( \
  160129. + (os), \
  160130. + (os)->memoryMapLock, \
  160131. + gcvINFINITE))
  160132. +
  160133. +#define MEMORY_MAP_UNLOCK(os) \
  160134. + gcmkVERIFY_OK(gckOS_ReleaseMutex((os), (os)->memoryMapLock))
  160135. +
  160136. +/* Protection bit when mapping memroy to user sapce */
  160137. +#define gcmkPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
  160138. +
  160139. +#if gcdNONPAGED_MEMORY_BUFFERABLE
  160140. +#define gcmkIOREMAP ioremap_wc
  160141. +#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
  160142. +#elif !gcdNONPAGED_MEMORY_CACHEABLE
  160143. +#define gcmkIOREMAP ioremap_nocache
  160144. +#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_noncached(x)
  160145. +#endif
  160146. +
  160147. +#if gcdSUPPRESS_OOM_MESSAGE
  160148. +#define gcdNOWARN __GFP_NOWARN
  160149. +#else
  160150. +#define gcdNOWARN 0
  160151. +#endif
  160152. +
  160153. +#define gcdINFINITE_TIMEOUT (60 * 1000)
  160154. +#define gcdDETECT_TIMEOUT 0
  160155. +#define gcdDETECT_DMA_ADDRESS 1
  160156. +#define gcdDETECT_DMA_STATE 1
  160157. +
  160158. +#define gcdUSE_NON_PAGED_MEMORY_CACHE 10
  160159. +
  160160. +/******************************************************************************\
  160161. +********************************** Structures **********************************
  160162. +\******************************************************************************/
  160163. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  160164. +typedef struct _gcsNonPagedMemoryCache
  160165. +{
  160166. +#ifndef NO_DMA_COHERENT
  160167. + gctINT size;
  160168. + gctSTRING addr;
  160169. + dma_addr_t dmaHandle;
  160170. +#else
  160171. + long order;
  160172. + struct page * page;
  160173. +#endif
  160174. +
  160175. + struct _gcsNonPagedMemoryCache * prev;
  160176. + struct _gcsNonPagedMemoryCache * next;
  160177. +}
  160178. +gcsNonPagedMemoryCache;
  160179. +#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */
  160180. +
  160181. +typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR;
  160182. +typedef struct _gcsUSER_MAPPING
  160183. +{
  160184. + /* Pointer to next mapping structure. */
  160185. + gcsUSER_MAPPING_PTR next;
  160186. +
  160187. + /* Physical address of this mapping. */
  160188. + gctUINT32 physical;
  160189. +
  160190. + /* Logical address of this mapping. */
  160191. + gctPOINTER logical;
  160192. +
  160193. + /* Number of bytes of this mapping. */
  160194. + gctSIZE_T bytes;
  160195. +
  160196. + /* Starting address of this mapping. */
  160197. + gctINT8_PTR start;
  160198. +
  160199. + /* Ending address of this mapping. */
  160200. + gctINT8_PTR end;
  160201. +}
  160202. +gcsUSER_MAPPING;
  160203. +
  160204. +typedef struct _gcsINTEGER_DB * gcsINTEGER_DB_PTR;
  160205. +typedef struct _gcsINTEGER_DB
  160206. +{
  160207. + struct idr idr;
  160208. + spinlock_t lock;
  160209. + gctINT curr;
  160210. +}
  160211. +gcsINTEGER_DB;
  160212. +
  160213. +struct _gckOS
  160214. +{
  160215. + /* Object. */
  160216. + gcsOBJECT object;
  160217. +
  160218. + /* Heap. */
  160219. + gckHEAP heap;
  160220. +
  160221. + /* Pointer to device */
  160222. + gckGALDEVICE device;
  160223. +
  160224. + /* Memory management */
  160225. + gctPOINTER memoryLock;
  160226. + gctPOINTER memoryMapLock;
  160227. +
  160228. + struct _LINUX_MDL *mdlHead;
  160229. + struct _LINUX_MDL *mdlTail;
  160230. +
  160231. + /* Kernel process ID. */
  160232. + gctUINT32 kernelProcessID;
  160233. +
  160234. + /* Signal management. */
  160235. +
  160236. + /* Lock. */
  160237. + gctPOINTER signalMutex;
  160238. +
  160239. + /* signal id database. */
  160240. + gcsINTEGER_DB signalDB;
  160241. +
  160242. +#if gcdANDROID_NATIVE_FENCE_SYNC
  160243. + /* Lock. */
  160244. + gctPOINTER syncPointMutex;
  160245. +
  160246. + /* sync point id database. */
  160247. + gcsINTEGER_DB syncPointDB;
  160248. +#endif
  160249. +
  160250. + gcsUSER_MAPPING_PTR userMap;
  160251. + gctPOINTER debugLock;
  160252. +
  160253. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  160254. + gctUINT cacheSize;
  160255. + gcsNonPagedMemoryCache * cacheHead;
  160256. + gcsNonPagedMemoryCache * cacheTail;
  160257. +#endif
  160258. +
  160259. + /* workqueue for os timer. */
  160260. + struct workqueue_struct * workqueue;
  160261. +};
  160262. +
  160263. +typedef struct _gcsSIGNAL * gcsSIGNAL_PTR;
  160264. +typedef struct _gcsSIGNAL
  160265. +{
  160266. + /* Kernel sync primitive. */
  160267. + struct completion obj;
  160268. +
  160269. + /* Manual reset flag. */
  160270. + gctBOOL manualReset;
  160271. +
  160272. + /* The reference counter. */
  160273. + atomic_t ref;
  160274. +
  160275. + /* The owner of the signal. */
  160276. + gctHANDLE process;
  160277. +
  160278. + gckHARDWARE hardware;
  160279. +
  160280. + /* ID. */
  160281. + gctUINT32 id;
  160282. +}
  160283. +gcsSIGNAL;
  160284. +
  160285. +#if gcdANDROID_NATIVE_FENCE_SYNC
  160286. +typedef struct _gcsSYNC_POINT * gcsSYNC_POINT_PTR;
  160287. +typedef struct _gcsSYNC_POINT
  160288. +{
  160289. + /* The reference counter. */
  160290. + atomic_t ref;
  160291. +
  160292. + /* State. */
  160293. + atomic_t state;
  160294. +
  160295. + /* timeline. */
  160296. + struct sync_timeline * timeline;
  160297. +
  160298. + /* ID. */
  160299. + gctUINT32 id;
  160300. +}
  160301. +gcsSYNC_POINT;
  160302. +#endif
  160303. +
  160304. +typedef struct _gcsPageInfo * gcsPageInfo_PTR;
  160305. +typedef struct _gcsPageInfo
  160306. +{
  160307. + struct page **pages;
  160308. + gctUINT32_PTR pageTable;
  160309. +}
  160310. +gcsPageInfo;
  160311. +
  160312. +typedef struct _gcsOSTIMER * gcsOSTIMER_PTR;
  160313. +typedef struct _gcsOSTIMER
  160314. +{
  160315. + struct delayed_work work;
  160316. + gctTIMERFUNCTION function;
  160317. + gctPOINTER data;
  160318. +} gcsOSTIMER;
  160319. +
  160320. +/******************************************************************************\
  160321. +******************************* Private Functions ******************************
  160322. +\******************************************************************************/
  160323. +
  160324. +static gctINT
  160325. +_GetProcessID(
  160326. + void
  160327. + )
  160328. +{
  160329. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  160330. + return task_tgid_vnr(current);
  160331. +#else
  160332. + return current->tgid;
  160333. +#endif
  160334. +}
  160335. +
  160336. +static gctINT
  160337. +_GetThreadID(
  160338. + void
  160339. + )
  160340. +{
  160341. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  160342. + return task_pid_vnr(current);
  160343. +#else
  160344. + return current->pid;
  160345. +#endif
  160346. +}
  160347. +
  160348. +static PLINUX_MDL
  160349. +_CreateMdl(
  160350. + IN gctINT ProcessID
  160351. + )
  160352. +{
  160353. + PLINUX_MDL mdl;
  160354. +
  160355. + gcmkHEADER_ARG("ProcessID=%d", ProcessID);
  160356. +
  160357. + mdl = (PLINUX_MDL)kzalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | gcdNOWARN);
  160358. + if (mdl == gcvNULL)
  160359. + {
  160360. + gcmkFOOTER_NO();
  160361. + return gcvNULL;
  160362. + }
  160363. +
  160364. + mdl->pid = ProcessID;
  160365. + mdl->maps = gcvNULL;
  160366. + mdl->prev = gcvNULL;
  160367. + mdl->next = gcvNULL;
  160368. +
  160369. + gcmkFOOTER_ARG("0x%X", mdl);
  160370. + return mdl;
  160371. +}
  160372. +
  160373. +static gceSTATUS
  160374. +_DestroyMdlMap(
  160375. + IN PLINUX_MDL Mdl,
  160376. + IN PLINUX_MDL_MAP MdlMap
  160377. + );
  160378. +
  160379. +static gceSTATUS
  160380. +_DestroyMdl(
  160381. + IN PLINUX_MDL Mdl
  160382. + )
  160383. +{
  160384. + PLINUX_MDL_MAP mdlMap, next;
  160385. +
  160386. + gcmkHEADER_ARG("Mdl=0x%X", Mdl);
  160387. +
  160388. + /* Verify the arguments. */
  160389. + gcmkVERIFY_ARGUMENT(Mdl != gcvNULL);
  160390. +
  160391. + mdlMap = Mdl->maps;
  160392. +
  160393. + while (mdlMap != gcvNULL)
  160394. + {
  160395. + next = mdlMap->next;
  160396. +
  160397. + gcmkVERIFY_OK(_DestroyMdlMap(Mdl, mdlMap));
  160398. +
  160399. + mdlMap = next;
  160400. + }
  160401. +
  160402. + kfree(Mdl);
  160403. +
  160404. + gcmkFOOTER_NO();
  160405. + return gcvSTATUS_OK;
  160406. +}
  160407. +
  160408. +static PLINUX_MDL_MAP
  160409. +_CreateMdlMap(
  160410. + IN PLINUX_MDL Mdl,
  160411. + IN gctINT ProcessID
  160412. + )
  160413. +{
  160414. + PLINUX_MDL_MAP mdlMap;
  160415. +
  160416. + gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
  160417. +
  160418. + mdlMap = (PLINUX_MDL_MAP)kmalloc(sizeof(struct _LINUX_MDL_MAP), GFP_KERNEL | gcdNOWARN);
  160419. + if (mdlMap == gcvNULL)
  160420. + {
  160421. + gcmkFOOTER_NO();
  160422. + return gcvNULL;
  160423. + }
  160424. +
  160425. + mdlMap->pid = ProcessID;
  160426. + mdlMap->vmaAddr = gcvNULL;
  160427. + mdlMap->vma = gcvNULL;
  160428. + mdlMap->count = 0;
  160429. +
  160430. + mdlMap->next = Mdl->maps;
  160431. + Mdl->maps = mdlMap;
  160432. +
  160433. + gcmkFOOTER_ARG("0x%X", mdlMap);
  160434. + return mdlMap;
  160435. +}
  160436. +
  160437. +static gceSTATUS
  160438. +_DestroyMdlMap(
  160439. + IN PLINUX_MDL Mdl,
  160440. + IN PLINUX_MDL_MAP MdlMap
  160441. + )
  160442. +{
  160443. + PLINUX_MDL_MAP prevMdlMap;
  160444. +
  160445. + gcmkHEADER_ARG("Mdl=0x%X MdlMap=0x%X", Mdl, MdlMap);
  160446. +
  160447. + /* Verify the arguments. */
  160448. + gcmkVERIFY_ARGUMENT(MdlMap != gcvNULL);
  160449. + gcmkASSERT(Mdl->maps != gcvNULL);
  160450. +
  160451. + if (Mdl->maps == MdlMap)
  160452. + {
  160453. + Mdl->maps = MdlMap->next;
  160454. + }
  160455. + else
  160456. + {
  160457. + prevMdlMap = Mdl->maps;
  160458. +
  160459. + while (prevMdlMap->next != MdlMap)
  160460. + {
  160461. + prevMdlMap = prevMdlMap->next;
  160462. +
  160463. + gcmkASSERT(prevMdlMap != gcvNULL);
  160464. + }
  160465. +
  160466. + prevMdlMap->next = MdlMap->next;
  160467. + }
  160468. +
  160469. + kfree(MdlMap);
  160470. +
  160471. + gcmkFOOTER_NO();
  160472. + return gcvSTATUS_OK;
  160473. +}
  160474. +
  160475. +extern PLINUX_MDL_MAP
  160476. +FindMdlMap(
  160477. + IN PLINUX_MDL Mdl,
  160478. + IN gctINT ProcessID
  160479. + )
  160480. +{
  160481. + PLINUX_MDL_MAP mdlMap;
  160482. +
  160483. + gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
  160484. + if(Mdl == gcvNULL)
  160485. + {
  160486. + gcmkFOOTER_NO();
  160487. + return gcvNULL;
  160488. + }
  160489. + mdlMap = Mdl->maps;
  160490. +
  160491. + while (mdlMap != gcvNULL)
  160492. + {
  160493. + if (mdlMap->pid == ProcessID)
  160494. + {
  160495. + gcmkFOOTER_ARG("0x%X", mdlMap);
  160496. + return mdlMap;
  160497. + }
  160498. +
  160499. + mdlMap = mdlMap->next;
  160500. + }
  160501. +
  160502. + gcmkFOOTER_NO();
  160503. + return gcvNULL;
  160504. +}
  160505. +
  160506. +void
  160507. +OnProcessExit(
  160508. + IN gckOS Os,
  160509. + IN gckKERNEL Kernel
  160510. + )
  160511. +{
  160512. +}
  160513. +
  160514. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
  160515. +static inline int
  160516. +is_vmalloc_addr(
  160517. + void *Addr
  160518. + )
  160519. +{
  160520. + unsigned long addr = (unsigned long)Addr;
  160521. +
  160522. + return addr >= VMALLOC_START && addr < VMALLOC_END;
  160523. +}
  160524. +#endif
  160525. +
  160526. +static void
  160527. +_NonContiguousFree(
  160528. + IN struct page ** Pages,
  160529. + IN gctUINT32 NumPages
  160530. + )
  160531. +{
  160532. + gctINT i;
  160533. +
  160534. + gcmkHEADER_ARG("Pages=0x%X, NumPages=%d", Pages, NumPages);
  160535. +
  160536. + gcmkASSERT(Pages != gcvNULL);
  160537. +
  160538. + for (i = 0; i < NumPages; i++)
  160539. + {
  160540. + __free_page(Pages[i]);
  160541. + }
  160542. +
  160543. + if (is_vmalloc_addr(Pages))
  160544. + {
  160545. + vfree(Pages);
  160546. + }
  160547. + else
  160548. + {
  160549. + kfree(Pages);
  160550. + }
  160551. +
  160552. + gcmkFOOTER_NO();
  160553. +}
  160554. +
  160555. +static struct page **
  160556. +_NonContiguousAlloc(
  160557. + IN gctUINT32 NumPages
  160558. + )
  160559. +{
  160560. + struct page ** pages;
  160561. + struct page *p;
  160562. + gctINT i, size;
  160563. +
  160564. + gcmkHEADER_ARG("NumPages=%lu", NumPages);
  160565. +
  160566. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
  160567. + if (NumPages > totalram_pages)
  160568. +#else
  160569. + if (NumPages > num_physpages)
  160570. +#endif
  160571. + {
  160572. + gcmkFOOTER_NO();
  160573. + return gcvNULL;
  160574. + }
  160575. +
  160576. + size = NumPages * sizeof(struct page *);
  160577. +
  160578. + pages = kmalloc(size, GFP_KERNEL | gcdNOWARN);
  160579. +
  160580. + if (!pages)
  160581. + {
  160582. + pages = vmalloc(size);
  160583. +
  160584. + if (!pages)
  160585. + {
  160586. + gcmkFOOTER_NO();
  160587. + return gcvNULL;
  160588. + }
  160589. + }
  160590. +
  160591. + for (i = 0; i < NumPages; i++)
  160592. + {
  160593. + p = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN);
  160594. +
  160595. + if (!p)
  160596. + {
  160597. + _NonContiguousFree(pages, i);
  160598. + gcmkFOOTER_NO();
  160599. + return gcvNULL;
  160600. + }
  160601. +
  160602. + pages[i] = p;
  160603. + }
  160604. +
  160605. + gcmkFOOTER_ARG("pages=0x%X", pages);
  160606. + return pages;
  160607. +}
  160608. +
  160609. +static inline struct page *
  160610. +_NonContiguousToPage(
  160611. + IN struct page ** Pages,
  160612. + IN gctUINT32 Index
  160613. + )
  160614. +{
  160615. + gcmkASSERT(Pages != gcvNULL);
  160616. + return Pages[Index];
  160617. +}
  160618. +
  160619. +static inline unsigned long
  160620. +_NonContiguousToPfn(
  160621. + IN struct page ** Pages,
  160622. + IN gctUINT32 Index
  160623. + )
  160624. +{
  160625. + gcmkASSERT(Pages != gcvNULL);
  160626. + return page_to_pfn(_NonContiguousToPage(Pages, Index));
  160627. +}
  160628. +
  160629. +static inline unsigned long
  160630. +_NonContiguousToPhys(
  160631. + IN struct page ** Pages,
  160632. + IN gctUINT32 Index
  160633. + )
  160634. +{
  160635. + gcmkASSERT(Pages != gcvNULL);
  160636. + return page_to_phys(_NonContiguousToPage(Pages, Index));
  160637. +}
  160638. +
  160639. +
  160640. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  160641. +
  160642. +static gctBOOL
  160643. +_AddNonPagedMemoryCache(
  160644. + gckOS Os,
  160645. +#ifndef NO_DMA_COHERENT
  160646. + gctINT Size,
  160647. + gctSTRING Addr,
  160648. + dma_addr_t DmaHandle
  160649. +#else
  160650. + long Order,
  160651. + struct page * Page
  160652. +#endif
  160653. + )
  160654. +{
  160655. + gcsNonPagedMemoryCache *cache;
  160656. +
  160657. + if (Os->cacheSize >= gcdUSE_NON_PAGED_MEMORY_CACHE)
  160658. + {
  160659. + return gcvFALSE;
  160660. + }
  160661. +
  160662. + /* Allocate the cache record */
  160663. + cache = (gcsNonPagedMemoryCache *)kmalloc(sizeof(gcsNonPagedMemoryCache), GFP_ATOMIC);
  160664. +
  160665. + if (cache == gcvNULL) return gcvFALSE;
  160666. +
  160667. +#ifndef NO_DMA_COHERENT
  160668. + cache->size = Size;
  160669. + cache->addr = Addr;
  160670. + cache->dmaHandle = DmaHandle;
  160671. +#else
  160672. + cache->order = Order;
  160673. + cache->page = Page;
  160674. +#endif
  160675. +
  160676. + /* Add to list */
  160677. + if (Os->cacheHead == gcvNULL)
  160678. + {
  160679. + cache->prev = gcvNULL;
  160680. + cache->next = gcvNULL;
  160681. + Os->cacheHead =
  160682. + Os->cacheTail = cache;
  160683. + }
  160684. + else
  160685. + {
  160686. + /* Add to the tail. */
  160687. + cache->prev = Os->cacheTail;
  160688. + cache->next = gcvNULL;
  160689. + Os->cacheTail->next = cache;
  160690. + Os->cacheTail = cache;
  160691. + }
  160692. +
  160693. + Os->cacheSize++;
  160694. +
  160695. + return gcvTRUE;
  160696. +}
  160697. +
  160698. +#ifndef NO_DMA_COHERENT
  160699. +static gctSTRING
  160700. +_GetNonPagedMemoryCache(
  160701. + gckOS Os,
  160702. + gctINT Size,
  160703. + dma_addr_t * DmaHandle
  160704. + )
  160705. +#else
  160706. +static struct page *
  160707. +_GetNonPagedMemoryCache(
  160708. + gckOS Os,
  160709. + long Order
  160710. + )
  160711. +#endif
  160712. +{
  160713. + gcsNonPagedMemoryCache *cache;
  160714. +#ifndef NO_DMA_COHERENT
  160715. + gctSTRING addr;
  160716. +#else
  160717. + struct page * page;
  160718. +#endif
  160719. +
  160720. + if (Os->cacheHead == gcvNULL) return gcvNULL;
  160721. +
  160722. + /* Find the right cache */
  160723. + cache = Os->cacheHead;
  160724. +
  160725. + while (cache != gcvNULL)
  160726. + {
  160727. +#ifndef NO_DMA_COHERENT
  160728. + if (cache->size == Size) break;
  160729. +#else
  160730. + if (cache->order == Order) break;
  160731. +#endif
  160732. +
  160733. + cache = cache->next;
  160734. + }
  160735. +
  160736. + if (cache == gcvNULL) return gcvNULL;
  160737. +
  160738. + /* Remove the cache from list */
  160739. + if (cache == Os->cacheHead)
  160740. + {
  160741. + Os->cacheHead = cache->next;
  160742. +
  160743. + if (Os->cacheHead == gcvNULL)
  160744. + {
  160745. + Os->cacheTail = gcvNULL;
  160746. + }
  160747. + }
  160748. + else
  160749. + {
  160750. + cache->prev->next = cache->next;
  160751. +
  160752. + if (cache == Os->cacheTail)
  160753. + {
  160754. + Os->cacheTail = cache->prev;
  160755. + }
  160756. + else
  160757. + {
  160758. + cache->next->prev = cache->prev;
  160759. + }
  160760. + }
  160761. +
  160762. + /* Destroy cache */
  160763. +#ifndef NO_DMA_COHERENT
  160764. + addr = cache->addr;
  160765. + *DmaHandle = cache->dmaHandle;
  160766. +#else
  160767. + page = cache->page;
  160768. +#endif
  160769. +
  160770. + kfree(cache);
  160771. +
  160772. + Os->cacheSize--;
  160773. +
  160774. +#ifndef NO_DMA_COHERENT
  160775. + return addr;
  160776. +#else
  160777. + return page;
  160778. +#endif
  160779. +}
  160780. +
  160781. +static void
  160782. +_FreeAllNonPagedMemoryCache(
  160783. + gckOS Os
  160784. + )
  160785. +{
  160786. + gcsNonPagedMemoryCache *cache, *nextCache;
  160787. +
  160788. + MEMORY_LOCK(Os);
  160789. +
  160790. + cache = Os->cacheHead;
  160791. +
  160792. + while (cache != gcvNULL)
  160793. + {
  160794. + if (cache != Os->cacheTail)
  160795. + {
  160796. + nextCache = cache->next;
  160797. + }
  160798. + else
  160799. + {
  160800. + nextCache = gcvNULL;
  160801. + }
  160802. +
  160803. + /* Remove the cache from list */
  160804. + if (cache == Os->cacheHead)
  160805. + {
  160806. + Os->cacheHead = cache->next;
  160807. +
  160808. + if (Os->cacheHead == gcvNULL)
  160809. + {
  160810. + Os->cacheTail = gcvNULL;
  160811. + }
  160812. + }
  160813. + else
  160814. + {
  160815. + cache->prev->next = cache->next;
  160816. +
  160817. + if (cache == Os->cacheTail)
  160818. + {
  160819. + Os->cacheTail = cache->prev;
  160820. + }
  160821. + else
  160822. + {
  160823. + cache->next->prev = cache->prev;
  160824. + }
  160825. + }
  160826. +
  160827. +#ifndef NO_DMA_COHERENT
  160828. + dma_free_coherent(gcvNULL,
  160829. + cache->size,
  160830. + cache->addr,
  160831. + cache->dmaHandle);
  160832. +#else
  160833. + free_pages((unsigned long)page_address(cache->page), cache->order);
  160834. +#endif
  160835. +
  160836. + kfree(cache);
  160837. +
  160838. + cache = nextCache;
  160839. + }
  160840. +
  160841. + MEMORY_UNLOCK(Os);
  160842. +}
  160843. +
  160844. +#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */
  160845. +
  160846. +/*******************************************************************************
  160847. +** Integer Id Management.
  160848. +*/
  160849. +gceSTATUS
  160850. +_AllocateIntegerId(
  160851. + IN gcsINTEGER_DB_PTR Database,
  160852. + IN gctPOINTER KernelPointer,
  160853. + OUT gctUINT32 *Id
  160854. + )
  160855. +{
  160856. + int result;
  160857. + gctINT next;
  160858. +
  160859. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
  160860. + idr_preload(GFP_KERNEL | gcdNOWARN);
  160861. +
  160862. + spin_lock(&Database->lock);
  160863. +
  160864. + next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
  160865. + result = idr_alloc(&Database->idr, KernelPointer, next, 0, GFP_ATOMIC);
  160866. +
  160867. + if (!result)
  160868. + {
  160869. + Database->curr = *Id;
  160870. + }
  160871. +
  160872. + spin_unlock(&Database->lock);
  160873. +
  160874. + idr_preload_end();
  160875. +
  160876. + if (result < 0)
  160877. + {
  160878. + return gcvSTATUS_OUT_OF_RESOURCES;
  160879. + }
  160880. +
  160881. + *Id = result;
  160882. +#else
  160883. +again:
  160884. + if (idr_pre_get(&Database->idr, GFP_KERNEL | gcdNOWARN) == 0)
  160885. + {
  160886. + return gcvSTATUS_OUT_OF_MEMORY;
  160887. + }
  160888. +
  160889. + spin_lock(&Database->lock);
  160890. +
  160891. + next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
  160892. +
  160893. + /* Try to get a id greater than current id. */
  160894. + result = idr_get_new_above(&Database->idr, KernelPointer, next, Id);
  160895. +
  160896. + if (!result)
  160897. + {
  160898. + Database->curr = *Id;
  160899. + }
  160900. +
  160901. + spin_unlock(&Database->lock);
  160902. +
  160903. + if (result == -EAGAIN)
  160904. + {
  160905. + goto again;
  160906. + }
  160907. +
  160908. + if (result != 0)
  160909. + {
  160910. + return gcvSTATUS_OUT_OF_RESOURCES;
  160911. + }
  160912. +#endif
  160913. +
  160914. + return gcvSTATUS_OK;
  160915. +}
  160916. +
  160917. +gceSTATUS
  160918. +_QueryIntegerId(
  160919. + IN gcsINTEGER_DB_PTR Database,
  160920. + IN gctUINT32 Id,
  160921. + OUT gctPOINTER * KernelPointer
  160922. + )
  160923. +{
  160924. + gctPOINTER pointer;
  160925. +
  160926. + spin_lock(&Database->lock);
  160927. +
  160928. + pointer = idr_find(&Database->idr, Id);
  160929. +
  160930. + spin_unlock(&Database->lock);
  160931. +
  160932. + if(pointer)
  160933. + {
  160934. + *KernelPointer = pointer;
  160935. + return gcvSTATUS_OK;
  160936. + }
  160937. + else
  160938. + {
  160939. + gcmkTRACE_ZONE(
  160940. + gcvLEVEL_ERROR, gcvZONE_OS,
  160941. + "%s(%d) Id = %d is not found",
  160942. + __FUNCTION__, __LINE__, Id);
  160943. +
  160944. + return gcvSTATUS_NOT_FOUND;
  160945. + }
  160946. +}
  160947. +
  160948. +gceSTATUS
  160949. +_DestroyIntegerId(
  160950. + IN gcsINTEGER_DB_PTR Database,
  160951. + IN gctUINT32 Id
  160952. + )
  160953. +{
  160954. + spin_lock(&Database->lock);
  160955. +
  160956. + idr_remove(&Database->idr, Id);
  160957. +
  160958. + spin_unlock(&Database->lock);
  160959. +
  160960. + return gcvSTATUS_OK;
  160961. +}
  160962. +
  160963. +static void
  160964. +_UnmapUserLogical(
  160965. + IN gctINT Pid,
  160966. + IN gctPOINTER Logical,
  160967. + IN gctUINT32 Size
  160968. +)
  160969. +{
  160970. + if (unlikely(current->mm == gcvNULL))
  160971. + {
  160972. + /* Do nothing if process is exiting. */
  160973. + return;
  160974. + }
  160975. +
  160976. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  160977. + if (vm_munmap((unsigned long)Logical, Size) < 0)
  160978. + {
  160979. + gcmkTRACE_ZONE(
  160980. + gcvLEVEL_WARNING, gcvZONE_OS,
  160981. + "%s(%d): vm_munmap failed",
  160982. + __FUNCTION__, __LINE__
  160983. + );
  160984. + }
  160985. +#else
  160986. + down_write(&current->mm->mmap_sem);
  160987. + if (do_munmap(current->mm, (unsigned long)Logical, Size) < 0)
  160988. + {
  160989. + gcmkTRACE_ZONE(
  160990. + gcvLEVEL_WARNING, gcvZONE_OS,
  160991. + "%s(%d): do_munmap failed",
  160992. + __FUNCTION__, __LINE__
  160993. + );
  160994. + }
  160995. + up_write(&current->mm->mmap_sem);
  160996. +#endif
  160997. +}
  160998. +
  160999. +gceSTATUS
  161000. +_QueryProcessPageTable(
  161001. + IN gctPOINTER Logical,
  161002. + OUT gctUINT32 * Address
  161003. + )
  161004. +{
  161005. + spinlock_t *lock;
  161006. + gctUINTPTR_T logical = (gctUINTPTR_T)Logical;
  161007. + pgd_t *pgd;
  161008. + pud_t *pud;
  161009. + pmd_t *pmd;
  161010. + pte_t *pte;
  161011. +
  161012. + if (!current->mm)
  161013. + {
  161014. + return gcvSTATUS_NOT_FOUND;
  161015. + }
  161016. +
  161017. + pgd = pgd_offset(current->mm, logical);
  161018. + if (pgd_none(*pgd) || pgd_bad(*pgd))
  161019. + {
  161020. + return gcvSTATUS_NOT_FOUND;
  161021. + }
  161022. +
  161023. + pud = pud_offset(pgd, logical);
  161024. + if (pud_none(*pud) || pud_bad(*pud))
  161025. + {
  161026. + return gcvSTATUS_NOT_FOUND;
  161027. + }
  161028. +
  161029. + pmd = pmd_offset(pud, logical);
  161030. + if (pmd_none(*pmd) || pmd_bad(*pmd))
  161031. + {
  161032. + return gcvSTATUS_NOT_FOUND;
  161033. + }
  161034. +
  161035. + pte = pte_offset_map_lock(current->mm, pmd, logical, &lock);
  161036. + if (!pte)
  161037. + {
  161038. + return gcvSTATUS_NOT_FOUND;
  161039. + }
  161040. +
  161041. + if (!pte_present(*pte))
  161042. + {
  161043. + pte_unmap_unlock(pte, lock);
  161044. + return gcvSTATUS_NOT_FOUND;
  161045. + }
  161046. +
  161047. + *Address = (pte_pfn(*pte) << PAGE_SHIFT) | (logical & ~PAGE_MASK);
  161048. + pte_unmap_unlock(pte, lock);
  161049. +
  161050. + return gcvSTATUS_OK;
  161051. +}
  161052. +
  161053. +/*******************************************************************************
  161054. +**
  161055. +** gckOS_Construct
  161056. +**
  161057. +** Construct a new gckOS object.
  161058. +**
  161059. +** INPUT:
  161060. +**
  161061. +** gctPOINTER Context
  161062. +** Pointer to the gckGALDEVICE class.
  161063. +**
  161064. +** OUTPUT:
  161065. +**
  161066. +** gckOS * Os
  161067. +** Pointer to a variable that will hold the pointer to the gckOS object.
  161068. +*/
  161069. +gceSTATUS
  161070. +gckOS_Construct(
  161071. + IN gctPOINTER Context,
  161072. + OUT gckOS * Os
  161073. + )
  161074. +{
  161075. + gckOS os;
  161076. + gceSTATUS status;
  161077. +
  161078. + gcmkHEADER_ARG("Context=0x%X", Context);
  161079. +
  161080. + /* Verify the arguments. */
  161081. + gcmkVERIFY_ARGUMENT(Os != gcvNULL);
  161082. +
  161083. + /* Allocate the gckOS object. */
  161084. + os = (gckOS) kmalloc(gcmSIZEOF(struct _gckOS), GFP_KERNEL | gcdNOWARN);
  161085. +
  161086. + if (os == gcvNULL)
  161087. + {
  161088. + /* Out of memory. */
  161089. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
  161090. + return gcvSTATUS_OUT_OF_MEMORY;
  161091. + }
  161092. +
  161093. + /* Zero the memory. */
  161094. + gckOS_ZeroMemory(os, gcmSIZEOF(struct _gckOS));
  161095. +
  161096. + /* Initialize the gckOS object. */
  161097. + os->object.type = gcvOBJ_OS;
  161098. +
  161099. + /* Set device device. */
  161100. + os->device = Context;
  161101. +
  161102. + /* IMPORTANT! No heap yet. */
  161103. + os->heap = gcvNULL;
  161104. +
  161105. + /* Initialize the memory lock. */
  161106. + gcmkONERROR(gckOS_CreateMutex(os, &os->memoryLock));
  161107. + gcmkONERROR(gckOS_CreateMutex(os, &os->memoryMapLock));
  161108. +
  161109. + /* Create debug lock mutex. */
  161110. + gcmkONERROR(gckOS_CreateMutex(os, &os->debugLock));
  161111. +
  161112. +
  161113. + os->mdlHead = os->mdlTail = gcvNULL;
  161114. +
  161115. + /* Get the kernel process ID. */
  161116. + gcmkONERROR(gckOS_GetProcessID(&os->kernelProcessID));
  161117. +
  161118. + /*
  161119. + * Initialize the signal manager.
  161120. + */
  161121. +
  161122. + /* Initialize mutex. */
  161123. + gcmkONERROR(gckOS_CreateMutex(os, &os->signalMutex));
  161124. +
  161125. + /* Initialize signal id database lock. */
  161126. + spin_lock_init(&os->signalDB.lock);
  161127. +
  161128. + /* Initialize signal id database. */
  161129. + idr_init(&os->signalDB.idr);
  161130. +
  161131. +#if gcdANDROID_NATIVE_FENCE_SYNC
  161132. + /*
  161133. + * Initialize the sync point manager.
  161134. + */
  161135. +
  161136. + /* Initialize mutex. */
  161137. + gcmkONERROR(gckOS_CreateMutex(os, &os->syncPointMutex));
  161138. +
  161139. + /* Initialize sync point id database lock. */
  161140. + spin_lock_init(&os->syncPointDB.lock);
  161141. +
  161142. + /* Initialize sync point id database. */
  161143. + idr_init(&os->syncPointDB.idr);
  161144. +#endif
  161145. +
  161146. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  161147. + os->cacheSize = 0;
  161148. + os->cacheHead = gcvNULL;
  161149. + os->cacheTail = gcvNULL;
  161150. +#endif
  161151. +
  161152. + /* Create a workqueue for os timer. */
  161153. + os->workqueue = create_singlethread_workqueue("galcore workqueue");
  161154. +
  161155. + if (os->workqueue == gcvNULL)
  161156. + {
  161157. + /* Out of memory. */
  161158. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  161159. + }
  161160. +
  161161. + /* Return pointer to the gckOS object. */
  161162. + *Os = os;
  161163. +
  161164. + /* Success. */
  161165. + gcmkFOOTER_ARG("*Os=0x%X", *Os);
  161166. + return gcvSTATUS_OK;
  161167. +
  161168. +OnError:
  161169. +
  161170. +#if gcdANDROID_NATIVE_FENCE_SYNC
  161171. + if (os->syncPointMutex != gcvNULL)
  161172. + {
  161173. + gcmkVERIFY_OK(
  161174. + gckOS_DeleteMutex(os, os->syncPointMutex));
  161175. + }
  161176. +#endif
  161177. +
  161178. + if (os->signalMutex != gcvNULL)
  161179. + {
  161180. + gcmkVERIFY_OK(
  161181. + gckOS_DeleteMutex(os, os->signalMutex));
  161182. + }
  161183. +
  161184. + if (os->heap != gcvNULL)
  161185. + {
  161186. + gcmkVERIFY_OK(
  161187. + gckHEAP_Destroy(os->heap));
  161188. + }
  161189. +
  161190. + if (os->memoryMapLock != gcvNULL)
  161191. + {
  161192. + gcmkVERIFY_OK(
  161193. + gckOS_DeleteMutex(os, os->memoryMapLock));
  161194. + }
  161195. +
  161196. + if (os->memoryLock != gcvNULL)
  161197. + {
  161198. + gcmkVERIFY_OK(
  161199. + gckOS_DeleteMutex(os, os->memoryLock));
  161200. + }
  161201. +
  161202. + if (os->debugLock != gcvNULL)
  161203. + {
  161204. + gcmkVERIFY_OK(
  161205. + gckOS_DeleteMutex(os, os->debugLock));
  161206. + }
  161207. +
  161208. + if (os->workqueue != gcvNULL)
  161209. + {
  161210. + destroy_workqueue(os->workqueue);
  161211. + }
  161212. +
  161213. + kfree(os);
  161214. +
  161215. + /* Return the error. */
  161216. + gcmkFOOTER();
  161217. + return status;
  161218. +}
  161219. +
  161220. +/*******************************************************************************
  161221. +**
  161222. +** gckOS_Destroy
  161223. +**
  161224. +** Destroy an gckOS object.
  161225. +**
  161226. +** INPUT:
  161227. +**
  161228. +** gckOS Os
  161229. +** Pointer to an gckOS object that needs to be destroyed.
  161230. +**
  161231. +** OUTPUT:
  161232. +**
  161233. +** Nothing.
  161234. +*/
  161235. +gceSTATUS
  161236. +gckOS_Destroy(
  161237. + IN gckOS Os
  161238. + )
  161239. +{
  161240. + gckHEAP heap;
  161241. +
  161242. + gcmkHEADER_ARG("Os=0x%X", Os);
  161243. +
  161244. + /* Verify the arguments. */
  161245. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161246. +
  161247. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  161248. + _FreeAllNonPagedMemoryCache(Os);
  161249. +#endif
  161250. +
  161251. +#if gcdANDROID_NATIVE_FENCE_SYNC
  161252. + /*
  161253. + * Destroy the sync point manager.
  161254. + */
  161255. +
  161256. + /* Destroy the mutex. */
  161257. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->syncPointMutex));
  161258. +#endif
  161259. +
  161260. + /*
  161261. + * Destroy the signal manager.
  161262. + */
  161263. +
  161264. + /* Destroy the mutex. */
  161265. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->signalMutex));
  161266. +
  161267. + if (Os->heap != gcvNULL)
  161268. + {
  161269. + /* Mark gckHEAP as gone. */
  161270. + heap = Os->heap;
  161271. + Os->heap = gcvNULL;
  161272. +
  161273. + /* Destroy the gckHEAP object. */
  161274. + gcmkVERIFY_OK(gckHEAP_Destroy(heap));
  161275. + }
  161276. +
  161277. + /* Destroy the memory lock. */
  161278. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->memoryMapLock));
  161279. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->memoryLock));
  161280. +
  161281. + /* Destroy debug lock mutex. */
  161282. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->debugLock));
  161283. +
  161284. + /* Wait for all works done. */
  161285. + flush_workqueue(Os->workqueue);
  161286. +
  161287. + /* Destory work queue. */
  161288. + destroy_workqueue(Os->workqueue);
  161289. +
  161290. + /* Flush the debug cache. */
  161291. + gcmkDEBUGFLUSH(~0U);
  161292. +
  161293. + /* Mark the gckOS object as unknown. */
  161294. + Os->object.type = gcvOBJ_UNKNOWN;
  161295. +
  161296. + /* Free the gckOS object. */
  161297. + kfree(Os);
  161298. +
  161299. + /* Success. */
  161300. + gcmkFOOTER_NO();
  161301. + return gcvSTATUS_OK;
  161302. +}
  161303. +
  161304. +static gctSTRING
  161305. +_CreateKernelVirtualMapping(
  161306. + IN PLINUX_MDL Mdl
  161307. + )
  161308. +{
  161309. + gctSTRING addr = 0;
  161310. + gctINT numPages = Mdl->numPages;
  161311. +
  161312. +#if gcdNONPAGED_MEMORY_CACHEABLE
  161313. + if (Mdl->contiguous)
  161314. + {
  161315. + addr = page_address(Mdl->u.contiguousPages);
  161316. + }
  161317. + else
  161318. + {
  161319. + addr = vmap(Mdl->u.nonContiguousPages,
  161320. + numPages,
  161321. + 0,
  161322. + PAGE_KERNEL);
  161323. +
  161324. + /* Trigger a page fault. */
  161325. + memset(addr, 0, numPages * PAGE_SIZE);
  161326. + }
  161327. +#else
  161328. + struct page ** pages;
  161329. + gctBOOL free = gcvFALSE;
  161330. + gctINT i;
  161331. +
  161332. + if (Mdl->contiguous)
  161333. + {
  161334. + pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN);
  161335. +
  161336. + if (!pages)
  161337. + {
  161338. + return gcvNULL;
  161339. + }
  161340. +
  161341. + for (i = 0; i < numPages; i++)
  161342. + {
  161343. + pages[i] = nth_page(Mdl->u.contiguousPages, i);
  161344. + }
  161345. +
  161346. + free = gcvTRUE;
  161347. + }
  161348. + else
  161349. + {
  161350. + pages = Mdl->u.nonContiguousPages;
  161351. + }
  161352. +
  161353. + /* ioremap() can't work on system memory since 2.6.38. */
  161354. + addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
  161355. +
  161356. + /* Trigger a page fault. */
  161357. + memset(addr, 0, numPages * PAGE_SIZE);
  161358. +
  161359. + if (free)
  161360. + {
  161361. + kfree(pages);
  161362. + }
  161363. +
  161364. +#endif
  161365. +
  161366. + return addr;
  161367. +}
  161368. +
  161369. +static void
  161370. +_DestoryKernelVirtualMapping(
  161371. + IN gctSTRING Addr
  161372. + )
  161373. +{
  161374. +#if !gcdNONPAGED_MEMORY_CACHEABLE
  161375. + vunmap(Addr);
  161376. +#endif
  161377. +}
  161378. +
  161379. +gceSTATUS
  161380. +gckOS_CreateKernelVirtualMapping(
  161381. + IN gctPHYS_ADDR Physical,
  161382. + OUT gctSIZE_T * PageCount,
  161383. + OUT gctPOINTER * Logical
  161384. + )
  161385. +{
  161386. + *PageCount = ((PLINUX_MDL)Physical)->numPages;
  161387. + *Logical = _CreateKernelVirtualMapping((PLINUX_MDL)Physical);
  161388. +
  161389. + return gcvSTATUS_OK;
  161390. +}
  161391. +
  161392. +gceSTATUS
  161393. +gckOS_DestroyKernelVirtualMapping(
  161394. + IN gctPOINTER Logical
  161395. + )
  161396. +{
  161397. + _DestoryKernelVirtualMapping((gctSTRING)Logical);
  161398. + return gcvSTATUS_OK;
  161399. +}
  161400. +
  161401. +/*******************************************************************************
  161402. +**
  161403. +** gckOS_Allocate
  161404. +**
  161405. +** Allocate memory.
  161406. +**
  161407. +** INPUT:
  161408. +**
  161409. +** gckOS Os
  161410. +** Pointer to an gckOS object.
  161411. +**
  161412. +** gctSIZE_T Bytes
  161413. +** Number of bytes to allocate.
  161414. +**
  161415. +** OUTPUT:
  161416. +**
  161417. +** gctPOINTER * Memory
  161418. +** Pointer to a variable that will hold the allocated memory location.
  161419. +*/
  161420. +gceSTATUS
  161421. +gckOS_Allocate(
  161422. + IN gckOS Os,
  161423. + IN gctSIZE_T Bytes,
  161424. + OUT gctPOINTER * Memory
  161425. + )
  161426. +{
  161427. + gceSTATUS status;
  161428. +
  161429. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
  161430. +
  161431. + /* Verify the arguments. */
  161432. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161433. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  161434. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  161435. +
  161436. + /* Do we have a heap? */
  161437. + if (Os->heap != gcvNULL)
  161438. + {
  161439. + /* Allocate from the heap. */
  161440. + gcmkONERROR(gckHEAP_Allocate(Os->heap, Bytes, Memory));
  161441. + }
  161442. + else
  161443. + {
  161444. + gcmkONERROR(gckOS_AllocateMemory(Os, Bytes, Memory));
  161445. + }
  161446. +
  161447. + /* Success. */
  161448. + gcmkFOOTER_ARG("*Memory=0x%X", *Memory);
  161449. + return gcvSTATUS_OK;
  161450. +
  161451. +OnError:
  161452. + /* Return the status. */
  161453. + gcmkFOOTER();
  161454. + return status;
  161455. +}
  161456. +
  161457. +/*******************************************************************************
  161458. +**
  161459. +** gckOS_Free
  161460. +**
  161461. +** Free allocated memory.
  161462. +**
  161463. +** INPUT:
  161464. +**
  161465. +** gckOS Os
  161466. +** Pointer to an gckOS object.
  161467. +**
  161468. +** gctPOINTER Memory
  161469. +** Pointer to memory allocation to free.
  161470. +**
  161471. +** OUTPUT:
  161472. +**
  161473. +** Nothing.
  161474. +*/
  161475. +gceSTATUS
  161476. +gckOS_Free(
  161477. + IN gckOS Os,
  161478. + IN gctPOINTER Memory
  161479. + )
  161480. +{
  161481. + gceSTATUS status;
  161482. +
  161483. + gcmkHEADER_ARG("Os=0x%X Memory=0x%X", Os, Memory);
  161484. +
  161485. + /* Verify the arguments. */
  161486. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161487. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  161488. +
  161489. + /* Do we have a heap? */
  161490. + if (Os->heap != gcvNULL)
  161491. + {
  161492. + /* Free from the heap. */
  161493. + gcmkONERROR(gckHEAP_Free(Os->heap, Memory));
  161494. + }
  161495. + else
  161496. + {
  161497. + gcmkONERROR(gckOS_FreeMemory(Os, Memory));
  161498. + }
  161499. +
  161500. + /* Success. */
  161501. + gcmkFOOTER_NO();
  161502. + return gcvSTATUS_OK;
  161503. +
  161504. +OnError:
  161505. + /* Return the status. */
  161506. + gcmkFOOTER();
  161507. + return status;
  161508. +}
  161509. +
  161510. +/*******************************************************************************
  161511. +**
  161512. +** gckOS_AllocateMemory
  161513. +**
  161514. +** Allocate memory wrapper.
  161515. +**
  161516. +** INPUT:
  161517. +**
  161518. +** gctSIZE_T Bytes
  161519. +** Number of bytes to allocate.
  161520. +**
  161521. +** OUTPUT:
  161522. +**
  161523. +** gctPOINTER * Memory
  161524. +** Pointer to a variable that will hold the allocated memory location.
  161525. +*/
  161526. +gceSTATUS
  161527. +gckOS_AllocateMemory(
  161528. + IN gckOS Os,
  161529. + IN gctSIZE_T Bytes,
  161530. + OUT gctPOINTER * Memory
  161531. + )
  161532. +{
  161533. + gctPOINTER memory;
  161534. + gceSTATUS status;
  161535. +
  161536. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
  161537. +
  161538. + /* Verify the arguments. */
  161539. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  161540. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  161541. +
  161542. + if (Bytes > PAGE_SIZE)
  161543. + {
  161544. + memory = (gctPOINTER) vmalloc(Bytes);
  161545. + }
  161546. + else
  161547. + {
  161548. + memory = (gctPOINTER) kmalloc(Bytes, GFP_KERNEL | gcdNOWARN);
  161549. + }
  161550. +
  161551. + if (memory == gcvNULL)
  161552. + {
  161553. + /* Out of memory. */
  161554. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  161555. + }
  161556. +
  161557. + /* Return pointer to the memory allocation. */
  161558. + *Memory = memory;
  161559. +
  161560. + /* Success. */
  161561. + gcmkFOOTER_ARG("*Memory=0x%X", *Memory);
  161562. + return gcvSTATUS_OK;
  161563. +
  161564. +OnError:
  161565. + /* Return the status. */
  161566. + gcmkFOOTER();
  161567. + return status;
  161568. +}
  161569. +
  161570. +/*******************************************************************************
  161571. +**
  161572. +** gckOS_FreeMemory
  161573. +**
  161574. +** Free allocated memory wrapper.
  161575. +**
  161576. +** INPUT:
  161577. +**
  161578. +** gctPOINTER Memory
  161579. +** Pointer to memory allocation to free.
  161580. +**
  161581. +** OUTPUT:
  161582. +**
  161583. +** Nothing.
  161584. +*/
  161585. +gceSTATUS
  161586. +gckOS_FreeMemory(
  161587. + IN gckOS Os,
  161588. + IN gctPOINTER Memory
  161589. + )
  161590. +{
  161591. + gcmkHEADER_ARG("Memory=0x%X", Memory);
  161592. +
  161593. + /* Verify the arguments. */
  161594. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  161595. +
  161596. + /* Free the memory from the OS pool. */
  161597. + if (is_vmalloc_addr(Memory))
  161598. + {
  161599. + vfree(Memory);
  161600. + }
  161601. + else
  161602. + {
  161603. + kfree(Memory);
  161604. + }
  161605. +
  161606. + /* Success. */
  161607. + gcmkFOOTER_NO();
  161608. + return gcvSTATUS_OK;
  161609. +}
  161610. +
  161611. +/*******************************************************************************
  161612. +**
  161613. +** gckOS_MapMemory
  161614. +**
  161615. +** Map physical memory into the current process.
  161616. +**
  161617. +** INPUT:
  161618. +**
  161619. +** gckOS Os
  161620. +** Pointer to an gckOS object.
  161621. +**
  161622. +** gctPHYS_ADDR Physical
  161623. +** Start of physical address memory.
  161624. +**
  161625. +** gctSIZE_T Bytes
  161626. +** Number of bytes to map.
  161627. +**
  161628. +** OUTPUT:
  161629. +**
  161630. +** gctPOINTER * Memory
  161631. +** Pointer to a variable that will hold the logical address of the
  161632. +** mapped memory.
  161633. +*/
  161634. +gceSTATUS
  161635. +gckOS_MapMemory(
  161636. + IN gckOS Os,
  161637. + IN gctPHYS_ADDR Physical,
  161638. + IN gctSIZE_T Bytes,
  161639. + OUT gctPOINTER * Logical
  161640. + )
  161641. +{
  161642. + PLINUX_MDL_MAP mdlMap;
  161643. + PLINUX_MDL mdl = (PLINUX_MDL)Physical;
  161644. +
  161645. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
  161646. +
  161647. + /* Verify the arguments. */
  161648. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161649. + gcmkVERIFY_ARGUMENT(Physical != 0);
  161650. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  161651. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  161652. +
  161653. + MEMORY_LOCK(Os);
  161654. +
  161655. + mdlMap = FindMdlMap(mdl, _GetProcessID());
  161656. +
  161657. + if (mdlMap == gcvNULL)
  161658. + {
  161659. + mdlMap = _CreateMdlMap(mdl, _GetProcessID());
  161660. +
  161661. + if (mdlMap == gcvNULL)
  161662. + {
  161663. + MEMORY_UNLOCK(Os);
  161664. +
  161665. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
  161666. + return gcvSTATUS_OUT_OF_MEMORY;
  161667. + }
  161668. + }
  161669. +
  161670. + if (mdlMap->vmaAddr == gcvNULL)
  161671. + {
  161672. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
  161673. + mdlMap->vmaAddr = (char *)vm_mmap(gcvNULL,
  161674. + 0L,
  161675. + mdl->numPages * PAGE_SIZE,
  161676. + PROT_READ | PROT_WRITE,
  161677. + MAP_SHARED,
  161678. + 0);
  161679. +#else
  161680. + down_write(&current->mm->mmap_sem);
  161681. +
  161682. + mdlMap->vmaAddr = (char *)do_mmap_pgoff(gcvNULL,
  161683. + 0L,
  161684. + mdl->numPages * PAGE_SIZE,
  161685. + PROT_READ | PROT_WRITE,
  161686. + MAP_SHARED,
  161687. + 0);
  161688. +
  161689. + up_write(&current->mm->mmap_sem);
  161690. +#endif
  161691. +
  161692. + if (IS_ERR(mdlMap->vmaAddr))
  161693. + {
  161694. + gcmkTRACE(
  161695. + gcvLEVEL_ERROR,
  161696. + "%s(%d): do_mmap_pgoff error",
  161697. + __FUNCTION__, __LINE__
  161698. + );
  161699. +
  161700. + gcmkTRACE(
  161701. + gcvLEVEL_ERROR,
  161702. + "%s(%d): mdl->numPages: %d mdl->vmaAddr: 0x%X",
  161703. + __FUNCTION__, __LINE__,
  161704. + mdl->numPages,
  161705. + mdlMap->vmaAddr
  161706. + );
  161707. +
  161708. + mdlMap->vmaAddr = gcvNULL;
  161709. +
  161710. + MEMORY_UNLOCK(Os);
  161711. +
  161712. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
  161713. + return gcvSTATUS_OUT_OF_MEMORY;
  161714. + }
  161715. +
  161716. + down_write(&current->mm->mmap_sem);
  161717. +
  161718. + mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
  161719. +
  161720. + if (!mdlMap->vma)
  161721. + {
  161722. + gcmkTRACE(
  161723. + gcvLEVEL_ERROR,
  161724. + "%s(%d): find_vma error.",
  161725. + __FUNCTION__, __LINE__
  161726. + );
  161727. +
  161728. + mdlMap->vmaAddr = gcvNULL;
  161729. +
  161730. + up_write(&current->mm->mmap_sem);
  161731. +
  161732. + MEMORY_UNLOCK(Os);
  161733. +
  161734. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  161735. + return gcvSTATUS_OUT_OF_RESOURCES;
  161736. + }
  161737. +
  161738. +#ifndef NO_DMA_COHERENT
  161739. + if (dma_mmap_coherent(gcvNULL,
  161740. + mdlMap->vma,
  161741. + mdl->addr,
  161742. + mdl->dmaHandle,
  161743. + mdl->numPages * PAGE_SIZE) < 0)
  161744. + {
  161745. + up_write(&current->mm->mmap_sem);
  161746. +
  161747. + gcmkTRACE(
  161748. + gcvLEVEL_ERROR,
  161749. + "%s(%d): dma_mmap_coherent error.",
  161750. + __FUNCTION__, __LINE__
  161751. + );
  161752. +
  161753. + mdlMap->vmaAddr = gcvNULL;
  161754. +
  161755. + MEMORY_UNLOCK(Os);
  161756. +
  161757. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  161758. + return gcvSTATUS_OUT_OF_RESOURCES;
  161759. + }
  161760. +#else
  161761. +#if !gcdPAGED_MEMORY_CACHEABLE
  161762. + mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
  161763. + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
  161764. +# endif
  161765. + mdlMap->vma->vm_pgoff = 0;
  161766. +
  161767. + if (remap_pfn_range(mdlMap->vma,
  161768. + mdlMap->vma->vm_start,
  161769. + mdl->dmaHandle >> PAGE_SHIFT,
  161770. + mdl->numPages*PAGE_SIZE,
  161771. + mdlMap->vma->vm_page_prot) < 0)
  161772. + {
  161773. + up_write(&current->mm->mmap_sem);
  161774. +
  161775. + gcmkTRACE(
  161776. + gcvLEVEL_ERROR,
  161777. + "%s(%d): remap_pfn_range error.",
  161778. + __FUNCTION__, __LINE__
  161779. + );
  161780. +
  161781. + mdlMap->vmaAddr = gcvNULL;
  161782. +
  161783. + MEMORY_UNLOCK(Os);
  161784. +
  161785. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  161786. + return gcvSTATUS_OUT_OF_RESOURCES;
  161787. + }
  161788. +#endif
  161789. +
  161790. + up_write(&current->mm->mmap_sem);
  161791. + }
  161792. +
  161793. + MEMORY_UNLOCK(Os);
  161794. +
  161795. + *Logical = mdlMap->vmaAddr;
  161796. +
  161797. + gcmkFOOTER_ARG("*Logical=0x%X", *Logical);
  161798. + return gcvSTATUS_OK;
  161799. +}
  161800. +
  161801. +/*******************************************************************************
  161802. +**
  161803. +** gckOS_UnmapMemory
  161804. +**
  161805. +** Unmap physical memory out of the current process.
  161806. +**
  161807. +** INPUT:
  161808. +**
  161809. +** gckOS Os
  161810. +** Pointer to an gckOS object.
  161811. +**
  161812. +** gctPHYS_ADDR Physical
  161813. +** Start of physical address memory.
  161814. +**
  161815. +** gctSIZE_T Bytes
  161816. +** Number of bytes to unmap.
  161817. +**
  161818. +** gctPOINTER Memory
  161819. +** Pointer to a previously mapped memory region.
  161820. +**
  161821. +** OUTPUT:
  161822. +**
  161823. +** Nothing.
  161824. +*/
  161825. +gceSTATUS
  161826. +gckOS_UnmapMemory(
  161827. + IN gckOS Os,
  161828. + IN gctPHYS_ADDR Physical,
  161829. + IN gctSIZE_T Bytes,
  161830. + IN gctPOINTER Logical
  161831. + )
  161832. +{
  161833. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X",
  161834. + Os, Physical, Bytes, Logical);
  161835. +
  161836. + /* Verify the arguments. */
  161837. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161838. + gcmkVERIFY_ARGUMENT(Physical != 0);
  161839. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  161840. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  161841. +
  161842. + gckOS_UnmapMemoryEx(Os, Physical, Bytes, Logical, _GetProcessID());
  161843. +
  161844. + /* Success. */
  161845. + gcmkFOOTER_NO();
  161846. + return gcvSTATUS_OK;
  161847. +}
  161848. +
  161849. +
  161850. +/*******************************************************************************
  161851. +**
  161852. +** gckOS_UnmapMemoryEx
  161853. +**
  161854. +** Unmap physical memory in the specified process.
  161855. +**
  161856. +** INPUT:
  161857. +**
  161858. +** gckOS Os
  161859. +** Pointer to an gckOS object.
  161860. +**
  161861. +** gctPHYS_ADDR Physical
  161862. +** Start of physical address memory.
  161863. +**
  161864. +** gctSIZE_T Bytes
  161865. +** Number of bytes to unmap.
  161866. +**
  161867. +** gctPOINTER Memory
  161868. +** Pointer to a previously mapped memory region.
  161869. +**
  161870. +** gctUINT32 PID
  161871. +** Pid of the process that opened the device and mapped this memory.
  161872. +**
  161873. +** OUTPUT:
  161874. +**
  161875. +** Nothing.
  161876. +*/
  161877. +gceSTATUS
  161878. +gckOS_UnmapMemoryEx(
  161879. + IN gckOS Os,
  161880. + IN gctPHYS_ADDR Physical,
  161881. + IN gctSIZE_T Bytes,
  161882. + IN gctPOINTER Logical,
  161883. + IN gctUINT32 PID
  161884. + )
  161885. +{
  161886. + PLINUX_MDL_MAP mdlMap;
  161887. + PLINUX_MDL mdl = (PLINUX_MDL)Physical;
  161888. +
  161889. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X PID=%d",
  161890. + Os, Physical, Bytes, Logical, PID);
  161891. +
  161892. + /* Verify the arguments. */
  161893. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161894. + gcmkVERIFY_ARGUMENT(Physical != 0);
  161895. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  161896. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  161897. + gcmkVERIFY_ARGUMENT(PID != 0);
  161898. +
  161899. + MEMORY_LOCK(Os);
  161900. +
  161901. + if (Logical)
  161902. + {
  161903. + mdlMap = FindMdlMap(mdl, PID);
  161904. +
  161905. + if (mdlMap == gcvNULL || mdlMap->vmaAddr == gcvNULL)
  161906. + {
  161907. + MEMORY_UNLOCK(Os);
  161908. +
  161909. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  161910. + return gcvSTATUS_INVALID_ARGUMENT;
  161911. + }
  161912. +
  161913. + _UnmapUserLogical(PID, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
  161914. +
  161915. + gcmkVERIFY_OK(_DestroyMdlMap(mdl, mdlMap));
  161916. + }
  161917. +
  161918. + MEMORY_UNLOCK(Os);
  161919. +
  161920. + /* Success. */
  161921. + gcmkFOOTER_NO();
  161922. + return gcvSTATUS_OK;
  161923. +}
  161924. +
  161925. +/*******************************************************************************
  161926. +**
  161927. +** gckOS_UnmapUserLogical
  161928. +**
  161929. +** Unmap user logical memory out of physical memory.
  161930. +**
  161931. +** INPUT:
  161932. +**
  161933. +** gckOS Os
  161934. +** Pointer to an gckOS object.
  161935. +**
  161936. +** gctPHYS_ADDR Physical
  161937. +** Start of physical address memory.
  161938. +**
  161939. +** gctSIZE_T Bytes
  161940. +** Number of bytes to unmap.
  161941. +**
  161942. +** gctPOINTER Memory
  161943. +** Pointer to a previously mapped memory region.
  161944. +**
  161945. +** OUTPUT:
  161946. +**
  161947. +** Nothing.
  161948. +*/
  161949. +gceSTATUS
  161950. +gckOS_UnmapUserLogical(
  161951. + IN gckOS Os,
  161952. + IN gctPHYS_ADDR Physical,
  161953. + IN gctSIZE_T Bytes,
  161954. + IN gctPOINTER Logical
  161955. + )
  161956. +{
  161957. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X",
  161958. + Os, Physical, Bytes, Logical);
  161959. +
  161960. + /* Verify the arguments. */
  161961. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  161962. + gcmkVERIFY_ARGUMENT(Physical != 0);
  161963. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  161964. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  161965. +
  161966. + gckOS_UnmapMemory(Os, Physical, Bytes, Logical);
  161967. +
  161968. + /* Success. */
  161969. + gcmkFOOTER_NO();
  161970. + return gcvSTATUS_OK;
  161971. +
  161972. +}
  161973. +
  161974. +/*******************************************************************************
  161975. +**
  161976. +** gckOS_AllocateNonPagedMemory
  161977. +**
  161978. +** Allocate a number of pages from non-paged memory.
  161979. +**
  161980. +** INPUT:
  161981. +**
  161982. +** gckOS Os
  161983. +** Pointer to an gckOS object.
  161984. +**
  161985. +** gctBOOL InUserSpace
  161986. +** gcvTRUE if the pages need to be mapped into user space.
  161987. +**
  161988. +** gctSIZE_T * Bytes
  161989. +** Pointer to a variable that holds the number of bytes to allocate.
  161990. +**
  161991. +** OUTPUT:
  161992. +**
  161993. +** gctSIZE_T * Bytes
  161994. +** Pointer to a variable that hold the number of bytes allocated.
  161995. +**
  161996. +** gctPHYS_ADDR * Physical
  161997. +** Pointer to a variable that will hold the physical address of the
  161998. +** allocation.
  161999. +**
  162000. +** gctPOINTER * Logical
  162001. +** Pointer to a variable that will hold the logical address of the
  162002. +** allocation.
  162003. +*/
  162004. +gceSTATUS
  162005. +gckOS_AllocateNonPagedMemory(
  162006. + IN gckOS Os,
  162007. + IN gctBOOL InUserSpace,
  162008. + IN OUT gctSIZE_T * Bytes,
  162009. + OUT gctPHYS_ADDR * Physical,
  162010. + OUT gctPOINTER * Logical
  162011. + )
  162012. +{
  162013. + gctSIZE_T bytes;
  162014. + gctINT numPages;
  162015. + PLINUX_MDL mdl = gcvNULL;
  162016. + PLINUX_MDL_MAP mdlMap = gcvNULL;
  162017. + gctSTRING addr;
  162018. +#ifdef NO_DMA_COHERENT
  162019. + struct page * page;
  162020. + long size, order;
  162021. + gctPOINTER vaddr;
  162022. +#endif
  162023. + gctBOOL locked = gcvFALSE;
  162024. + gceSTATUS status;
  162025. +
  162026. + gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
  162027. + Os, InUserSpace, gcmOPT_VALUE(Bytes));
  162028. +
  162029. + /* Verify the arguments. */
  162030. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162031. + gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
  162032. + gcmkVERIFY_ARGUMENT(*Bytes > 0);
  162033. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  162034. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  162035. +
  162036. + /* Align number of bytes to page size. */
  162037. + bytes = gcmALIGN(*Bytes, PAGE_SIZE);
  162038. +
  162039. + /* Get total number of pages.. */
  162040. + numPages = GetPageCount(bytes, 0);
  162041. +
  162042. + /* Allocate mdl+vector structure */
  162043. + mdl = _CreateMdl(_GetProcessID());
  162044. + if (mdl == gcvNULL)
  162045. + {
  162046. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  162047. + }
  162048. +
  162049. + mdl->pagedMem = 0;
  162050. + mdl->numPages = numPages;
  162051. +
  162052. + MEMORY_LOCK(Os);
  162053. + locked = gcvTRUE;
  162054. +
  162055. +#ifndef NO_DMA_COHERENT
  162056. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162057. + addr = _GetNonPagedMemoryCache(Os,
  162058. + mdl->numPages * PAGE_SIZE,
  162059. + &mdl->dmaHandle);
  162060. +
  162061. + if (addr == gcvNULL)
  162062. +#endif
  162063. + {
  162064. + addr = dma_alloc_coherent(gcvNULL,
  162065. + mdl->numPages * PAGE_SIZE,
  162066. + &mdl->dmaHandle,
  162067. + GFP_KERNEL | gcdNOWARN);
  162068. + }
  162069. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162070. + if(addr == gcvNULL)
  162071. + {
  162072. + MEMORY_UNLOCK(Os);
  162073. + locked = gcvFALSE;
  162074. + /*Free all cache and try again*/
  162075. + _FreeAllNonPagedMemoryCache(Os);
  162076. + MEMORY_LOCK(Os);
  162077. + locked = gcvTRUE;
  162078. + addr = dma_alloc_coherent(gcvNULL,
  162079. + mdl->numPages * PAGE_SIZE,
  162080. + &mdl->dmaHandle,
  162081. + GFP_KERNEL | gcdNOWARN);
  162082. + }
  162083. +#endif
  162084. +#else
  162085. + size = mdl->numPages * PAGE_SIZE;
  162086. + order = get_order(size);
  162087. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162088. + page = _GetNonPagedMemoryCache(Os, order);
  162089. +
  162090. + if (page == gcvNULL)
  162091. +#endif
  162092. + {
  162093. + page = alloc_pages(GFP_KERNEL | gcdNOWARN, order);
  162094. + }
  162095. +
  162096. + if (page == gcvNULL)
  162097. + {
  162098. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  162099. + }
  162100. +
  162101. + vaddr = (gctPOINTER)page_address(page);
  162102. + mdl->contiguous = gcvTRUE;
  162103. + mdl->u.contiguousPages = page;
  162104. + addr = _CreateKernelVirtualMapping(mdl);
  162105. + mdl->dmaHandle = virt_to_phys(vaddr);
  162106. + mdl->kaddr = vaddr;
  162107. + mdl->u.contiguousPages = page;
  162108. +
  162109. +#if !defined(CONFIG_PPC)
  162110. + /* Cache invalidate. */
  162111. + dma_sync_single_for_device(
  162112. + gcvNULL,
  162113. + page_to_phys(page),
  162114. + bytes,
  162115. + DMA_FROM_DEVICE);
  162116. +#endif
  162117. +
  162118. + while (size > 0)
  162119. + {
  162120. + SetPageReserved(virt_to_page(vaddr));
  162121. +
  162122. + vaddr += PAGE_SIZE;
  162123. + size -= PAGE_SIZE;
  162124. + }
  162125. +#endif
  162126. +
  162127. + if (addr == gcvNULL)
  162128. + {
  162129. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  162130. + }
  162131. +
  162132. + mdl->addr = addr;
  162133. +
  162134. + /* Return allocated memory. */
  162135. + *Bytes = bytes;
  162136. + *Physical = (gctPHYS_ADDR) mdl;
  162137. +
  162138. + if (InUserSpace)
  162139. + {
  162140. + mdlMap = _CreateMdlMap(mdl, _GetProcessID());
  162141. +
  162142. + if (mdlMap == gcvNULL)
  162143. + {
  162144. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  162145. + }
  162146. +
  162147. + /* Only after mmap this will be valid. */
  162148. +
  162149. + /* We need to map this to user space. */
  162150. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
  162151. + mdlMap->vmaAddr = (gctSTRING) vm_mmap(gcvNULL,
  162152. + 0L,
  162153. + mdl->numPages * PAGE_SIZE,
  162154. + PROT_READ | PROT_WRITE,
  162155. + MAP_SHARED,
  162156. + 0);
  162157. +#else
  162158. + down_write(&current->mm->mmap_sem);
  162159. +
  162160. + mdlMap->vmaAddr = (gctSTRING) do_mmap_pgoff(gcvNULL,
  162161. + 0L,
  162162. + mdl->numPages * PAGE_SIZE,
  162163. + PROT_READ | PROT_WRITE,
  162164. + MAP_SHARED,
  162165. + 0);
  162166. +
  162167. + up_write(&current->mm->mmap_sem);
  162168. +#endif
  162169. +
  162170. + if (IS_ERR(mdlMap->vmaAddr))
  162171. + {
  162172. + gcmkTRACE_ZONE(
  162173. + gcvLEVEL_WARNING, gcvZONE_OS,
  162174. + "%s(%d): do_mmap_pgoff error",
  162175. + __FUNCTION__, __LINE__
  162176. + );
  162177. +
  162178. + mdlMap->vmaAddr = gcvNULL;
  162179. +
  162180. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  162181. + }
  162182. +
  162183. + down_write(&current->mm->mmap_sem);
  162184. +
  162185. + mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
  162186. +
  162187. + if (mdlMap->vma == gcvNULL)
  162188. + {
  162189. + gcmkTRACE_ZONE(
  162190. + gcvLEVEL_WARNING, gcvZONE_OS,
  162191. + "%s(%d): find_vma error",
  162192. + __FUNCTION__, __LINE__
  162193. + );
  162194. +
  162195. + up_write(&current->mm->mmap_sem);
  162196. +
  162197. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  162198. + }
  162199. +
  162200. +#ifndef NO_DMA_COHERENT
  162201. + if (dma_mmap_coherent(gcvNULL,
  162202. + mdlMap->vma,
  162203. + mdl->addr,
  162204. + mdl->dmaHandle,
  162205. + mdl->numPages * PAGE_SIZE) < 0)
  162206. + {
  162207. + gcmkTRACE_ZONE(
  162208. + gcvLEVEL_WARNING, gcvZONE_OS,
  162209. + "%s(%d): dma_mmap_coherent error",
  162210. + __FUNCTION__, __LINE__
  162211. + );
  162212. +
  162213. + up_write(&current->mm->mmap_sem);
  162214. +
  162215. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  162216. + }
  162217. +#else
  162218. + mdlMap->vma->vm_page_prot = gcmkNONPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
  162219. + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
  162220. + mdlMap->vma->vm_pgoff = 0;
  162221. +
  162222. + if (remap_pfn_range(mdlMap->vma,
  162223. + mdlMap->vma->vm_start,
  162224. + mdl->dmaHandle >> PAGE_SHIFT,
  162225. + mdl->numPages * PAGE_SIZE,
  162226. + mdlMap->vma->vm_page_prot))
  162227. + {
  162228. + gcmkTRACE_ZONE(
  162229. + gcvLEVEL_WARNING, gcvZONE_OS,
  162230. + "%s(%d): remap_pfn_range error",
  162231. + __FUNCTION__, __LINE__
  162232. + );
  162233. +
  162234. + up_write(&current->mm->mmap_sem);
  162235. +
  162236. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  162237. + }
  162238. +#endif /* NO_DMA_COHERENT */
  162239. +
  162240. + up_write(&current->mm->mmap_sem);
  162241. +
  162242. + *Logical = mdlMap->vmaAddr;
  162243. + }
  162244. + else
  162245. + {
  162246. + *Logical = (gctPOINTER)mdl->addr;
  162247. + }
  162248. +
  162249. + /*
  162250. + * Add this to a global list.
  162251. + * Will be used by get physical address
  162252. + * and mapuser pointer functions.
  162253. + */
  162254. +
  162255. + if (!Os->mdlHead)
  162256. + {
  162257. + /* Initialize the queue. */
  162258. + Os->mdlHead = Os->mdlTail = mdl;
  162259. + }
  162260. + else
  162261. + {
  162262. + /* Add to the tail. */
  162263. + mdl->prev = Os->mdlTail;
  162264. + Os->mdlTail->next = mdl;
  162265. + Os->mdlTail = mdl;
  162266. + }
  162267. +
  162268. + MEMORY_UNLOCK(Os);
  162269. +
  162270. + /* Success. */
  162271. + gcmkFOOTER_ARG("*Bytes=%lu *Physical=0x%X *Logical=0x%X",
  162272. + *Bytes, *Physical, *Logical);
  162273. + return gcvSTATUS_OK;
  162274. +
  162275. +OnError:
  162276. + if (mdlMap != gcvNULL)
  162277. + {
  162278. + /* Free LINUX_MDL_MAP. */
  162279. + gcmkVERIFY_OK(_DestroyMdlMap(mdl, mdlMap));
  162280. + }
  162281. +
  162282. + if (mdl != gcvNULL)
  162283. + {
  162284. + /* Free LINUX_MDL. */
  162285. + gcmkVERIFY_OK(_DestroyMdl(mdl));
  162286. + }
  162287. +
  162288. + if (locked)
  162289. + {
  162290. + /* Unlock memory. */
  162291. + MEMORY_UNLOCK(Os);
  162292. + }
  162293. +
  162294. + /* Return the status. */
  162295. + gcmkFOOTER();
  162296. + return status;
  162297. +}
  162298. +
  162299. +/*******************************************************************************
  162300. +**
  162301. +** gckOS_FreeNonPagedMemory
  162302. +**
  162303. +** Free previously allocated and mapped pages from non-paged memory.
  162304. +**
  162305. +** INPUT:
  162306. +**
  162307. +** gckOS Os
  162308. +** Pointer to an gckOS object.
  162309. +**
  162310. +** gctSIZE_T Bytes
  162311. +** Number of bytes allocated.
  162312. +**
  162313. +** gctPHYS_ADDR Physical
  162314. +** Physical address of the allocated memory.
  162315. +**
  162316. +** gctPOINTER Logical
  162317. +** Logical address of the allocated memory.
  162318. +**
  162319. +** OUTPUT:
  162320. +**
  162321. +** Nothing.
  162322. +*/
  162323. +gceSTATUS gckOS_FreeNonPagedMemory(
  162324. + IN gckOS Os,
  162325. + IN gctSIZE_T Bytes,
  162326. + IN gctPHYS_ADDR Physical,
  162327. + IN gctPOINTER Logical
  162328. + )
  162329. +{
  162330. + PLINUX_MDL mdl;
  162331. + PLINUX_MDL_MAP mdlMap;
  162332. +#ifdef NO_DMA_COHERENT
  162333. + unsigned size;
  162334. + gctPOINTER vaddr;
  162335. +#endif /* NO_DMA_COHERENT */
  162336. +
  162337. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu Physical=0x%X Logical=0x%X",
  162338. + Os, Bytes, Physical, Logical);
  162339. +
  162340. + /* Verify the arguments. */
  162341. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162342. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  162343. + gcmkVERIFY_ARGUMENT(Physical != 0);
  162344. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  162345. +
  162346. + /* Convert physical address into a pointer to a MDL. */
  162347. + mdl = (PLINUX_MDL) Physical;
  162348. +
  162349. + MEMORY_LOCK(Os);
  162350. +
  162351. +#ifndef NO_DMA_COHERENT
  162352. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162353. + if (!_AddNonPagedMemoryCache(Os,
  162354. + mdl->numPages * PAGE_SIZE,
  162355. + mdl->addr,
  162356. + mdl->dmaHandle))
  162357. +#endif
  162358. + {
  162359. + dma_free_coherent(gcvNULL,
  162360. + mdl->numPages * PAGE_SIZE,
  162361. + mdl->addr,
  162362. + mdl->dmaHandle);
  162363. + }
  162364. +#else
  162365. + size = mdl->numPages * PAGE_SIZE;
  162366. + vaddr = mdl->kaddr;
  162367. +
  162368. + while (size > 0)
  162369. + {
  162370. + ClearPageReserved(virt_to_page(vaddr));
  162371. +
  162372. + vaddr += PAGE_SIZE;
  162373. + size -= PAGE_SIZE;
  162374. + }
  162375. +
  162376. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162377. + if (!_AddNonPagedMemoryCache(Os,
  162378. + get_order(mdl->numPages * PAGE_SIZE),
  162379. + virt_to_page(mdl->kaddr)))
  162380. +#endif
  162381. + {
  162382. + free_pages((unsigned long)mdl->kaddr, get_order(mdl->numPages * PAGE_SIZE));
  162383. + }
  162384. +
  162385. + _DestoryKernelVirtualMapping(mdl->addr);
  162386. +#endif /* NO_DMA_COHERENT */
  162387. +
  162388. + mdlMap = mdl->maps;
  162389. +
  162390. + while (mdlMap != gcvNULL)
  162391. + {
  162392. + if (mdlMap->vmaAddr != gcvNULL)
  162393. + {
  162394. + /* No mapped memory exists when free nonpaged memory */
  162395. + gcmkASSERT(0);
  162396. + }
  162397. +
  162398. + mdlMap = mdlMap->next;
  162399. + }
  162400. +
  162401. + /* Remove the node from global list.. */
  162402. + if (mdl == Os->mdlHead)
  162403. + {
  162404. + if ((Os->mdlHead = mdl->next) == gcvNULL)
  162405. + {
  162406. + Os->mdlTail = gcvNULL;
  162407. + }
  162408. + }
  162409. + else
  162410. + {
  162411. + mdl->prev->next = mdl->next;
  162412. + if (mdl == Os->mdlTail)
  162413. + {
  162414. + Os->mdlTail = mdl->prev;
  162415. + }
  162416. + else
  162417. + {
  162418. + mdl->next->prev = mdl->prev;
  162419. + }
  162420. + }
  162421. +
  162422. + MEMORY_UNLOCK(Os);
  162423. +
  162424. + gcmkVERIFY_OK(_DestroyMdl(mdl));
  162425. +
  162426. + /* Success. */
  162427. + gcmkFOOTER_NO();
  162428. + return gcvSTATUS_OK;
  162429. +}
  162430. +
  162431. +/*******************************************************************************
  162432. +**
  162433. +** gckOS_ReadRegister
  162434. +**
  162435. +** Read data from a register.
  162436. +**
  162437. +** INPUT:
  162438. +**
  162439. +** gckOS Os
  162440. +** Pointer to an gckOS object.
  162441. +**
  162442. +** gctUINT32 Address
  162443. +** Address of register.
  162444. +**
  162445. +** OUTPUT:
  162446. +**
  162447. +** gctUINT32 * Data
  162448. +** Pointer to a variable that receives the data read from the register.
  162449. +*/
  162450. +gceSTATUS
  162451. +gckOS_ReadRegister(
  162452. + IN gckOS Os,
  162453. + IN gctUINT32 Address,
  162454. + OUT gctUINT32 * Data
  162455. + )
  162456. +{
  162457. + return gckOS_ReadRegisterEx(Os, gcvCORE_MAJOR, Address, Data);
  162458. +}
  162459. +
  162460. +gceSTATUS
  162461. +gckOS_ReadRegisterEx(
  162462. + IN gckOS Os,
  162463. + IN gceCORE Core,
  162464. + IN gctUINT32 Address,
  162465. + OUT gctUINT32 * Data
  162466. + )
  162467. +{
  162468. + gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%X", Os, Core, Address);
  162469. +
  162470. + /* Verify the arguments. */
  162471. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162472. + gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
  162473. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  162474. +
  162475. + *Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address);
  162476. +
  162477. + /* Success. */
  162478. + gcmkFOOTER_ARG("*Data=0x%08x", *Data);
  162479. + return gcvSTATUS_OK;
  162480. +}
  162481. +
  162482. +/*******************************************************************************
  162483. +**
  162484. +** gckOS_WriteRegister
  162485. +**
  162486. +** Write data to a register.
  162487. +**
  162488. +** INPUT:
  162489. +**
  162490. +** gckOS Os
  162491. +** Pointer to an gckOS object.
  162492. +**
  162493. +** gctUINT32 Address
  162494. +** Address of register.
  162495. +**
  162496. +** gctUINT32 Data
  162497. +** Data for register.
  162498. +**
  162499. +** OUTPUT:
  162500. +**
  162501. +** Nothing.
  162502. +*/
  162503. +gceSTATUS
  162504. +gckOS_WriteRegister(
  162505. + IN gckOS Os,
  162506. + IN gctUINT32 Address,
  162507. + IN gctUINT32 Data
  162508. + )
  162509. +{
  162510. + return gckOS_WriteRegisterEx(Os, gcvCORE_MAJOR, Address, Data);
  162511. +}
  162512. +
  162513. +gceSTATUS
  162514. +gckOS_WriteRegisterEx(
  162515. + IN gckOS Os,
  162516. + IN gceCORE Core,
  162517. + IN gctUINT32 Address,
  162518. + IN gctUINT32 Data
  162519. + )
  162520. +{
  162521. + gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%X Data=0x%08x", Os, Core, Address, Data);
  162522. +
  162523. + gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
  162524. +
  162525. + writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address);
  162526. +
  162527. + /* Success. */
  162528. + gcmkFOOTER_NO();
  162529. + return gcvSTATUS_OK;
  162530. +}
  162531. +
  162532. +/*******************************************************************************
  162533. +**
  162534. +** gckOS_GetPageSize
  162535. +**
  162536. +** Get the system's page size.
  162537. +**
  162538. +** INPUT:
  162539. +**
  162540. +** gckOS Os
  162541. +** Pointer to an gckOS object.
  162542. +**
  162543. +** OUTPUT:
  162544. +**
  162545. +** gctSIZE_T * PageSize
  162546. +** Pointer to a variable that will receive the system's page size.
  162547. +*/
  162548. +gceSTATUS gckOS_GetPageSize(
  162549. + IN gckOS Os,
  162550. + OUT gctSIZE_T * PageSize
  162551. + )
  162552. +{
  162553. + gcmkHEADER_ARG("Os=0x%X", Os);
  162554. +
  162555. + /* Verify the arguments. */
  162556. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162557. + gcmkVERIFY_ARGUMENT(PageSize != gcvNULL);
  162558. +
  162559. + /* Return the page size. */
  162560. + *PageSize = (gctSIZE_T) PAGE_SIZE;
  162561. +
  162562. + /* Success. */
  162563. + gcmkFOOTER_ARG("*PageSize", *PageSize);
  162564. + return gcvSTATUS_OK;
  162565. +}
  162566. +
  162567. +/*******************************************************************************
  162568. +**
  162569. +** gckOS_GetPhysicalAddress
  162570. +**
  162571. +** Get the physical system address of a corresponding virtual address.
  162572. +**
  162573. +** INPUT:
  162574. +**
  162575. +** gckOS Os
  162576. +** Pointer to an gckOS object.
  162577. +**
  162578. +** gctPOINTER Logical
  162579. +** Logical address.
  162580. +**
  162581. +** OUTPUT:
  162582. +**
  162583. +** gctUINT32 * Address
  162584. +** Poinetr to a variable that receives the 32-bit physical adress.
  162585. +*/
  162586. +gceSTATUS
  162587. +gckOS_GetPhysicalAddress(
  162588. + IN gckOS Os,
  162589. + IN gctPOINTER Logical,
  162590. + OUT gctUINT32 * Address
  162591. + )
  162592. +{
  162593. + gceSTATUS status;
  162594. + gctUINT32 processID;
  162595. +
  162596. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X", Os, Logical);
  162597. +
  162598. + /* Verify the arguments. */
  162599. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162600. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  162601. +
  162602. + /* Query page table of current process first. */
  162603. + status = _QueryProcessPageTable(Logical, Address);
  162604. +
  162605. + if (gcmIS_ERROR(status))
  162606. + {
  162607. + /* Get current process ID. */
  162608. + processID = _GetProcessID();
  162609. +
  162610. + /* Route through other function. */
  162611. + gcmkONERROR(
  162612. + gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
  162613. + }
  162614. +
  162615. + /* Success. */
  162616. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  162617. + return gcvSTATUS_OK;
  162618. +
  162619. +OnError:
  162620. + /* Return the status. */
  162621. + gcmkFOOTER();
  162622. + return status;
  162623. +}
  162624. +
  162625. +#if gcdSECURE_USER
  162626. +static gceSTATUS
  162627. +gckOS_AddMapping(
  162628. + IN gckOS Os,
  162629. + IN gctUINT32 Physical,
  162630. + IN gctPOINTER Logical,
  162631. + IN gctSIZE_T Bytes
  162632. + )
  162633. +{
  162634. + gceSTATUS status;
  162635. + gcsUSER_MAPPING_PTR map;
  162636. +
  162637. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Logical=0x%X Bytes=%lu",
  162638. + Os, Physical, Logical, Bytes);
  162639. +
  162640. + gcmkONERROR(gckOS_Allocate(Os,
  162641. + gcmSIZEOF(gcsUSER_MAPPING),
  162642. + (gctPOINTER *) &map));
  162643. +
  162644. + map->next = Os->userMap;
  162645. + map->physical = Physical - Os->device->baseAddress;
  162646. + map->logical = Logical;
  162647. + map->bytes = Bytes;
  162648. + map->start = (gctINT8_PTR) Logical;
  162649. + map->end = map->start + Bytes;
  162650. +
  162651. + Os->userMap = map;
  162652. +
  162653. + gcmkFOOTER_NO();
  162654. + return gcvSTATUS_OK;
  162655. +
  162656. +OnError:
  162657. + gcmkFOOTER();
  162658. + return status;
  162659. +}
  162660. +
  162661. +static gceSTATUS
  162662. +gckOS_RemoveMapping(
  162663. + IN gckOS Os,
  162664. + IN gctPOINTER Logical,
  162665. + IN gctSIZE_T Bytes
  162666. + )
  162667. +{
  162668. + gceSTATUS status;
  162669. + gcsUSER_MAPPING_PTR map, prev;
  162670. +
  162671. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu", Os, Logical, Bytes);
  162672. +
  162673. + for (map = Os->userMap, prev = gcvNULL; map != gcvNULL; map = map->next)
  162674. + {
  162675. + if ((map->logical == Logical)
  162676. + && (map->bytes == Bytes)
  162677. + )
  162678. + {
  162679. + break;
  162680. + }
  162681. +
  162682. + prev = map;
  162683. + }
  162684. +
  162685. + if (map == gcvNULL)
  162686. + {
  162687. + gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
  162688. + }
  162689. +
  162690. + if (prev == gcvNULL)
  162691. + {
  162692. + Os->userMap = map->next;
  162693. + }
  162694. + else
  162695. + {
  162696. + prev->next = map->next;
  162697. + }
  162698. +
  162699. + gcmkONERROR(gcmkOS_SAFE_FREE(Os, map));
  162700. +
  162701. + gcmkFOOTER_NO();
  162702. + return gcvSTATUS_OK;
  162703. +
  162704. +OnError:
  162705. + gcmkFOOTER();
  162706. + return status;
  162707. +}
  162708. +#endif
  162709. +
  162710. +static gceSTATUS
  162711. +_ConvertLogical2Physical(
  162712. + IN gckOS Os,
  162713. + IN gctPOINTER Logical,
  162714. + IN gctUINT32 ProcessID,
  162715. + IN PLINUX_MDL Mdl,
  162716. + OUT gctUINT32_PTR Physical
  162717. + )
  162718. +{
  162719. + gctINT8_PTR base, vBase;
  162720. + gctUINT32 offset;
  162721. + PLINUX_MDL_MAP map;
  162722. + gcsUSER_MAPPING_PTR userMap;
  162723. +
  162724. + base = (Mdl == gcvNULL) ? gcvNULL : (gctINT8_PTR) Mdl->addr;
  162725. +
  162726. + /* Check for the logical address match. */
  162727. + if ((base != gcvNULL)
  162728. + && ((gctINT8_PTR) Logical >= base)
  162729. + && ((gctINT8_PTR) Logical < base + Mdl->numPages * PAGE_SIZE)
  162730. + )
  162731. + {
  162732. + offset = (gctINT8_PTR) Logical - base;
  162733. +
  162734. + if (Mdl->dmaHandle != 0)
  162735. + {
  162736. + /* The memory was from coherent area. */
  162737. + *Physical = (gctUINT32) Mdl->dmaHandle + offset;
  162738. + }
  162739. + else if (Mdl->pagedMem && !Mdl->contiguous)
  162740. + {
  162741. + /* paged memory is not mapped to kernel space. */
  162742. + return gcvSTATUS_INVALID_ADDRESS;
  162743. + }
  162744. + else
  162745. + {
  162746. + *Physical = gcmPTR2INT(virt_to_phys(base)) + offset;
  162747. + }
  162748. +
  162749. + return gcvSTATUS_OK;
  162750. + }
  162751. +
  162752. + /* Walk user maps. */
  162753. + for (userMap = Os->userMap; userMap != gcvNULL; userMap = userMap->next)
  162754. + {
  162755. + if (((gctINT8_PTR) Logical >= userMap->start)
  162756. + && ((gctINT8_PTR) Logical < userMap->end)
  162757. + )
  162758. + {
  162759. + *Physical = userMap->physical
  162760. + + (gctUINT32) ((gctINT8_PTR) Logical - userMap->start);
  162761. +
  162762. + return gcvSTATUS_OK;
  162763. + }
  162764. + }
  162765. +
  162766. + if (ProcessID != Os->kernelProcessID)
  162767. + {
  162768. + map = FindMdlMap(Mdl, (gctINT) ProcessID);
  162769. + vBase = (map == gcvNULL) ? gcvNULL : (gctINT8_PTR) map->vmaAddr;
  162770. +
  162771. + /* Is the given address within that range. */
  162772. + if ((vBase != gcvNULL)
  162773. + && ((gctINT8_PTR) Logical >= vBase)
  162774. + && ((gctINT8_PTR) Logical < vBase + Mdl->numPages * PAGE_SIZE)
  162775. + )
  162776. + {
  162777. + offset = (gctINT8_PTR) Logical - vBase;
  162778. +
  162779. + if (Mdl->dmaHandle != 0)
  162780. + {
  162781. + /* The memory was from coherent area. */
  162782. + *Physical = (gctUINT32) Mdl->dmaHandle + offset;
  162783. + }
  162784. + else if (Mdl->pagedMem && !Mdl->contiguous)
  162785. + {
  162786. + *Physical = _NonContiguousToPhys(Mdl->u.nonContiguousPages, offset/PAGE_SIZE);
  162787. + }
  162788. + else
  162789. + {
  162790. + *Physical = page_to_phys(Mdl->u.contiguousPages) + offset;
  162791. + }
  162792. +
  162793. + return gcvSTATUS_OK;
  162794. + }
  162795. + }
  162796. +
  162797. + /* Address not yet found. */
  162798. + return gcvSTATUS_INVALID_ADDRESS;
  162799. +}
  162800. +
  162801. +/*******************************************************************************
  162802. +**
  162803. +** gckOS_GetPhysicalAddressProcess
  162804. +**
  162805. +** Get the physical system address of a corresponding virtual address for a
  162806. +** given process.
  162807. +**
  162808. +** INPUT:
  162809. +**
  162810. +** gckOS Os
  162811. +** Pointer to gckOS object.
  162812. +**
  162813. +** gctPOINTER Logical
  162814. +** Logical address.
  162815. +**
  162816. +** gctUINT32 ProcessID
  162817. +** Process ID.
  162818. +**
  162819. +** OUTPUT:
  162820. +**
  162821. +** gctUINT32 * Address
  162822. +** Poinetr to a variable that receives the 32-bit physical adress.
  162823. +*/
  162824. +gceSTATUS
  162825. +gckOS_GetPhysicalAddressProcess(
  162826. + IN gckOS Os,
  162827. + IN gctPOINTER Logical,
  162828. + IN gctUINT32 ProcessID,
  162829. + OUT gctUINT32 * Address
  162830. + )
  162831. +{
  162832. + PLINUX_MDL mdl;
  162833. + gctINT8_PTR base;
  162834. + gceSTATUS status = gcvSTATUS_INVALID_ADDRESS;
  162835. +
  162836. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X ProcessID=%d", Os, Logical, ProcessID);
  162837. +
  162838. + /* Verify the arguments. */
  162839. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162840. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  162841. +
  162842. + MEMORY_LOCK(Os);
  162843. +
  162844. + /* First try the contiguous memory pool. */
  162845. + if (Os->device->contiguousMapped)
  162846. + {
  162847. + base = (gctINT8_PTR) Os->device->contiguousBase;
  162848. +
  162849. + if (((gctINT8_PTR) Logical >= base)
  162850. + && ((gctINT8_PTR) Logical < base + Os->device->contiguousSize)
  162851. + )
  162852. + {
  162853. + /* Convert logical address into physical. */
  162854. + *Address = Os->device->contiguousVidMem->baseAddress
  162855. + + (gctINT8_PTR) Logical - base;
  162856. + status = gcvSTATUS_OK;
  162857. + }
  162858. + }
  162859. + else
  162860. + {
  162861. + /* Try the contiguous memory pool. */
  162862. + mdl = (PLINUX_MDL) Os->device->contiguousPhysical;
  162863. + status = _ConvertLogical2Physical(Os,
  162864. + Logical,
  162865. + ProcessID,
  162866. + mdl,
  162867. + Address);
  162868. + }
  162869. +
  162870. + if (gcmIS_ERROR(status))
  162871. + {
  162872. + /* Walk all MDLs. */
  162873. + for (mdl = Os->mdlHead; mdl != gcvNULL; mdl = mdl->next)
  162874. + {
  162875. + /* Try this MDL. */
  162876. + status = _ConvertLogical2Physical(Os,
  162877. + Logical,
  162878. + ProcessID,
  162879. + mdl,
  162880. + Address);
  162881. + if (gcmIS_SUCCESS(status))
  162882. + {
  162883. + break;
  162884. + }
  162885. + }
  162886. + }
  162887. +
  162888. + MEMORY_UNLOCK(Os);
  162889. +
  162890. + gcmkONERROR(status);
  162891. +
  162892. + /* Success. */
  162893. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  162894. + return gcvSTATUS_OK;
  162895. +
  162896. +OnError:
  162897. + /* Return the status. */
  162898. + gcmkFOOTER();
  162899. + return status;
  162900. +}
  162901. +
  162902. +/*******************************************************************************
  162903. +**
  162904. +** gckOS_MapPhysical
  162905. +**
  162906. +** Map a physical address into kernel space.
  162907. +**
  162908. +** INPUT:
  162909. +**
  162910. +** gckOS Os
  162911. +** Pointer to an gckOS object.
  162912. +**
  162913. +** gctUINT32 Physical
  162914. +** Physical address of the memory to map.
  162915. +**
  162916. +** gctSIZE_T Bytes
  162917. +** Number of bytes to map.
  162918. +**
  162919. +** OUTPUT:
  162920. +**
  162921. +** gctPOINTER * Logical
  162922. +** Pointer to a variable that receives the base address of the mapped
  162923. +** memory.
  162924. +*/
  162925. +gceSTATUS
  162926. +gckOS_MapPhysical(
  162927. + IN gckOS Os,
  162928. + IN gctUINT32 Physical,
  162929. + IN gctSIZE_T Bytes,
  162930. + OUT gctPOINTER * Logical
  162931. + )
  162932. +{
  162933. + gctPOINTER logical;
  162934. + PLINUX_MDL mdl;
  162935. + gctUINT32 physical = Physical;
  162936. +
  162937. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
  162938. +
  162939. + /* Verify the arguments. */
  162940. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  162941. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  162942. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  162943. +
  162944. + MEMORY_LOCK(Os);
  162945. +
  162946. + /* Go through our mapping to see if we know this physical address already. */
  162947. + mdl = Os->mdlHead;
  162948. +
  162949. + while (mdl != gcvNULL)
  162950. + {
  162951. + if (mdl->dmaHandle != 0)
  162952. + {
  162953. + if ((physical >= mdl->dmaHandle)
  162954. + && (physical < mdl->dmaHandle + mdl->numPages * PAGE_SIZE)
  162955. + )
  162956. + {
  162957. + *Logical = mdl->addr + (physical - mdl->dmaHandle);
  162958. + break;
  162959. + }
  162960. + }
  162961. +
  162962. + mdl = mdl->next;
  162963. + }
  162964. +
  162965. + if (mdl == gcvNULL)
  162966. + {
  162967. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  162968. + struct contiguous_mem_pool *pool = Os->device->pool;
  162969. +
  162970. + if (Physical >= pool->phys && Physical < pool->phys + pool->size)
  162971. + logical = (gctPOINTER)(Physical - pool->phys + pool->virt);
  162972. + else
  162973. + logical = gcvNULL;
  162974. +#else
  162975. + /* Map memory as cached memory. */
  162976. + request_mem_region(physical, Bytes, "MapRegion");
  162977. + logical = (gctPOINTER) ioremap_nocache(physical, Bytes);
  162978. +#endif
  162979. +
  162980. + if (logical == gcvNULL)
  162981. + {
  162982. + gcmkTRACE_ZONE(
  162983. + gcvLEVEL_INFO, gcvZONE_OS,
  162984. + "%s(%d): Failed to map physical address 0x%08x",
  162985. + __FUNCTION__, __LINE__, Physical
  162986. + );
  162987. +
  162988. + MEMORY_UNLOCK(Os);
  162989. +
  162990. + /* Out of resources. */
  162991. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  162992. + return gcvSTATUS_OUT_OF_RESOURCES;
  162993. + }
  162994. +
  162995. + /* Return pointer to mapped memory. */
  162996. + *Logical = logical;
  162997. + }
  162998. +
  162999. + MEMORY_UNLOCK(Os);
  163000. +
  163001. + /* Success. */
  163002. + gcmkFOOTER_ARG("*Logical=0x%X", *Logical);
  163003. + return gcvSTATUS_OK;
  163004. +}
  163005. +
  163006. +/*******************************************************************************
  163007. +**
  163008. +** gckOS_UnmapPhysical
  163009. +**
  163010. +** Unmap a previously mapped memory region from kernel memory.
  163011. +**
  163012. +** INPUT:
  163013. +**
  163014. +** gckOS Os
  163015. +** Pointer to an gckOS object.
  163016. +**
  163017. +** gctPOINTER Logical
  163018. +** Pointer to the base address of the memory to unmap.
  163019. +**
  163020. +** gctSIZE_T Bytes
  163021. +** Number of bytes to unmap.
  163022. +**
  163023. +** OUTPUT:
  163024. +**
  163025. +** Nothing.
  163026. +*/
  163027. +gceSTATUS
  163028. +gckOS_UnmapPhysical(
  163029. + IN gckOS Os,
  163030. + IN gctPOINTER Logical,
  163031. + IN gctSIZE_T Bytes
  163032. + )
  163033. +{
  163034. + PLINUX_MDL mdl;
  163035. +
  163036. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu", Os, Logical, Bytes);
  163037. +
  163038. + /* Verify the arguments. */
  163039. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163040. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  163041. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  163042. +
  163043. + MEMORY_LOCK(Os);
  163044. +
  163045. + mdl = Os->mdlHead;
  163046. +
  163047. + while (mdl != gcvNULL)
  163048. + {
  163049. + if (mdl->addr != gcvNULL)
  163050. + {
  163051. + if (Logical >= (gctPOINTER)mdl->addr
  163052. + && Logical < (gctPOINTER)((gctSTRING)mdl->addr + mdl->numPages * PAGE_SIZE))
  163053. + {
  163054. + break;
  163055. + }
  163056. + }
  163057. +
  163058. + mdl = mdl->next;
  163059. + }
  163060. +
  163061. + if (mdl == gcvNULL)
  163062. + {
  163063. + /* Unmap the memory. */
  163064. + iounmap(Logical);
  163065. + }
  163066. +
  163067. + MEMORY_UNLOCK(Os);
  163068. +
  163069. + /* Success. */
  163070. + gcmkFOOTER_NO();
  163071. + return gcvSTATUS_OK;
  163072. +}
  163073. +
  163074. +/*******************************************************************************
  163075. +**
  163076. +** gckOS_CreateMutex
  163077. +**
  163078. +** Create a new mutex.
  163079. +**
  163080. +** INPUT:
  163081. +**
  163082. +** gckOS Os
  163083. +** Pointer to an gckOS object.
  163084. +**
  163085. +** OUTPUT:
  163086. +**
  163087. +** gctPOINTER * Mutex
  163088. +** Pointer to a variable that will hold a pointer to the mutex.
  163089. +*/
  163090. +gceSTATUS
  163091. +gckOS_CreateMutex(
  163092. + IN gckOS Os,
  163093. + OUT gctPOINTER * Mutex
  163094. + )
  163095. +{
  163096. + gceSTATUS status;
  163097. +
  163098. + gcmkHEADER_ARG("Os=0x%X", Os);
  163099. +
  163100. + /* Validate the arguments. */
  163101. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163102. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  163103. +
  163104. + /* Allocate the mutex structure. */
  163105. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(struct mutex), Mutex));
  163106. +
  163107. + /* Initialize the mutex. */
  163108. + mutex_init(*Mutex);
  163109. +
  163110. + /* Return status. */
  163111. + gcmkFOOTER_ARG("*Mutex=0x%X", *Mutex);
  163112. + return gcvSTATUS_OK;
  163113. +
  163114. +OnError:
  163115. + /* Return status. */
  163116. + gcmkFOOTER();
  163117. + return status;
  163118. +}
  163119. +
  163120. +/*******************************************************************************
  163121. +**
  163122. +** gckOS_DeleteMutex
  163123. +**
  163124. +** Delete a mutex.
  163125. +**
  163126. +** INPUT:
  163127. +**
  163128. +** gckOS Os
  163129. +** Pointer to an gckOS object.
  163130. +**
  163131. +** gctPOINTER Mutex
  163132. +** Pointer to the mute to be deleted.
  163133. +**
  163134. +** OUTPUT:
  163135. +**
  163136. +** Nothing.
  163137. +*/
  163138. +gceSTATUS
  163139. +gckOS_DeleteMutex(
  163140. + IN gckOS Os,
  163141. + IN gctPOINTER Mutex
  163142. + )
  163143. +{
  163144. + gceSTATUS status;
  163145. +
  163146. + gcmkHEADER_ARG("Os=0x%X Mutex=0x%X", Os, Mutex);
  163147. +
  163148. + /* Validate the arguments. */
  163149. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163150. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  163151. +
  163152. + /* Destroy the mutex. */
  163153. + mutex_destroy(Mutex);
  163154. +
  163155. + /* Free the mutex structure. */
  163156. + gcmkONERROR(gckOS_Free(Os, Mutex));
  163157. +
  163158. + gcmkFOOTER_NO();
  163159. + return gcvSTATUS_OK;
  163160. +
  163161. +OnError:
  163162. + /* Return status. */
  163163. + gcmkFOOTER();
  163164. + return status;
  163165. +}
  163166. +
  163167. +/*******************************************************************************
  163168. +**
  163169. +** gckOS_AcquireMutex
  163170. +**
  163171. +** Acquire a mutex.
  163172. +**
  163173. +** INPUT:
  163174. +**
  163175. +** gckOS Os
  163176. +** Pointer to an gckOS object.
  163177. +**
  163178. +** gctPOINTER Mutex
  163179. +** Pointer to the mutex to be acquired.
  163180. +**
  163181. +** gctUINT32 Timeout
  163182. +** Timeout value specified in milliseconds.
  163183. +** Specify the value of gcvINFINITE to keep the thread suspended
  163184. +** until the mutex has been acquired.
  163185. +**
  163186. +** OUTPUT:
  163187. +**
  163188. +** Nothing.
  163189. +*/
  163190. +gceSTATUS
  163191. +gckOS_AcquireMutex(
  163192. + IN gckOS Os,
  163193. + IN gctPOINTER Mutex,
  163194. + IN gctUINT32 Timeout
  163195. + )
  163196. +{
  163197. +#if gcdDETECT_TIMEOUT
  163198. + gctUINT32 timeout;
  163199. +#endif
  163200. +
  163201. + gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x Timeout=%u", Os, Mutex, Timeout);
  163202. +
  163203. + /* Validate the arguments. */
  163204. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163205. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  163206. +
  163207. +#if gcdDETECT_TIMEOUT
  163208. + timeout = 0;
  163209. +
  163210. + for (;;)
  163211. + {
  163212. + /* Try to acquire the mutex. */
  163213. + if (mutex_trylock(Mutex))
  163214. + {
  163215. + /* Success. */
  163216. + gcmkFOOTER_NO();
  163217. + return gcvSTATUS_OK;
  163218. + }
  163219. +
  163220. + /* Advance the timeout. */
  163221. + timeout += 1;
  163222. +
  163223. + if (Timeout == gcvINFINITE)
  163224. + {
  163225. + if (timeout == gcdINFINITE_TIMEOUT)
  163226. + {
  163227. + gctUINT32 dmaAddress1, dmaAddress2;
  163228. + gctUINT32 dmaState1, dmaState2;
  163229. +
  163230. + dmaState1 = dmaState2 =
  163231. + dmaAddress1 = dmaAddress2 = 0;
  163232. +
  163233. + /* Verify whether DMA is running. */
  163234. + gcmkVERIFY_OK(_VerifyDMA(
  163235. + Os, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
  163236. + ));
  163237. +
  163238. +#if gcdDETECT_DMA_ADDRESS
  163239. + /* Dump only if DMA appears stuck. */
  163240. + if (
  163241. + (dmaAddress1 == dmaAddress2)
  163242. +#if gcdDETECT_DMA_STATE
  163243. + && (dmaState1 == dmaState2)
  163244. +# endif
  163245. + )
  163246. +# endif
  163247. + {
  163248. + gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR));
  163249. +
  163250. + gcmkPRINT(
  163251. + "%s(%d): mutex 0x%X; forced message flush.",
  163252. + __FUNCTION__, __LINE__, Mutex
  163253. + );
  163254. +
  163255. + /* Flush the debug cache. */
  163256. + gcmkDEBUGFLUSH(dmaAddress2);
  163257. + }
  163258. +
  163259. + timeout = 0;
  163260. + }
  163261. + }
  163262. + else
  163263. + {
  163264. + /* Timedout? */
  163265. + if (timeout >= Timeout)
  163266. + {
  163267. + break;
  163268. + }
  163269. + }
  163270. +
  163271. + /* Wait for 1 millisecond. */
  163272. + gcmkVERIFY_OK(gckOS_Delay(Os, 1));
  163273. + }
  163274. +#else
  163275. + if (Timeout == gcvINFINITE)
  163276. + {
  163277. + /* Lock the mutex. */
  163278. + mutex_lock(Mutex);
  163279. +
  163280. + /* Success. */
  163281. + gcmkFOOTER_NO();
  163282. + return gcvSTATUS_OK;
  163283. + }
  163284. +
  163285. + for (;;)
  163286. + {
  163287. + /* Try to acquire the mutex. */
  163288. + if (mutex_trylock(Mutex))
  163289. + {
  163290. + /* Success. */
  163291. + gcmkFOOTER_NO();
  163292. + return gcvSTATUS_OK;
  163293. + }
  163294. +
  163295. + if (Timeout-- == 0)
  163296. + {
  163297. + break;
  163298. + }
  163299. +
  163300. + /* Wait for 1 millisecond. */
  163301. + gcmkVERIFY_OK(gckOS_Delay(Os, 1));
  163302. + }
  163303. +#endif
  163304. +
  163305. + /* Timeout. */
  163306. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_TIMEOUT);
  163307. + return gcvSTATUS_TIMEOUT;
  163308. +}
  163309. +
  163310. +/*******************************************************************************
  163311. +**
  163312. +** gckOS_ReleaseMutex
  163313. +**
  163314. +** Release an acquired mutex.
  163315. +**
  163316. +** INPUT:
  163317. +**
  163318. +** gckOS Os
  163319. +** Pointer to an gckOS object.
  163320. +**
  163321. +** gctPOINTER Mutex
  163322. +** Pointer to the mutex to be released.
  163323. +**
  163324. +** OUTPUT:
  163325. +**
  163326. +** Nothing.
  163327. +*/
  163328. +gceSTATUS
  163329. +gckOS_ReleaseMutex(
  163330. + IN gckOS Os,
  163331. + IN gctPOINTER Mutex
  163332. + )
  163333. +{
  163334. + gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x", Os, Mutex);
  163335. +
  163336. + /* Validate the arguments. */
  163337. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163338. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  163339. +
  163340. + /* Release the mutex. */
  163341. + mutex_unlock(Mutex);
  163342. +
  163343. + /* Success. */
  163344. + gcmkFOOTER_NO();
  163345. + return gcvSTATUS_OK;
  163346. +}
  163347. +
  163348. +/*******************************************************************************
  163349. +**
  163350. +** gckOS_AtomicExchange
  163351. +**
  163352. +** Atomically exchange a pair of 32-bit values.
  163353. +**
  163354. +** INPUT:
  163355. +**
  163356. +** gckOS Os
  163357. +** Pointer to an gckOS object.
  163358. +**
  163359. +** IN OUT gctINT32_PTR Target
  163360. +** Pointer to the 32-bit value to exchange.
  163361. +**
  163362. +** IN gctINT32 NewValue
  163363. +** Specifies a new value for the 32-bit value pointed to by Target.
  163364. +**
  163365. +** OUT gctINT32_PTR OldValue
  163366. +** The old value of the 32-bit value pointed to by Target.
  163367. +**
  163368. +** OUTPUT:
  163369. +**
  163370. +** Nothing.
  163371. +*/
  163372. +gceSTATUS
  163373. +gckOS_AtomicExchange(
  163374. + IN gckOS Os,
  163375. + IN OUT gctUINT32_PTR Target,
  163376. + IN gctUINT32 NewValue,
  163377. + OUT gctUINT32_PTR OldValue
  163378. + )
  163379. +{
  163380. + gcmkHEADER_ARG("Os=0x%X Target=0x%X NewValue=%u", Os, Target, NewValue);
  163381. +
  163382. + /* Verify the arguments. */
  163383. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163384. +
  163385. + /* Exchange the pair of 32-bit values. */
  163386. + *OldValue = (gctUINT32) atomic_xchg((atomic_t *) Target, (int) NewValue);
  163387. +
  163388. + /* Success. */
  163389. + gcmkFOOTER_ARG("*OldValue=%u", *OldValue);
  163390. + return gcvSTATUS_OK;
  163391. +}
  163392. +
  163393. +/*******************************************************************************
  163394. +**
  163395. +** gckOS_AtomicExchangePtr
  163396. +**
  163397. +** Atomically exchange a pair of pointers.
  163398. +**
  163399. +** INPUT:
  163400. +**
  163401. +** gckOS Os
  163402. +** Pointer to an gckOS object.
  163403. +**
  163404. +** IN OUT gctPOINTER * Target
  163405. +** Pointer to the 32-bit value to exchange.
  163406. +**
  163407. +** IN gctPOINTER NewValue
  163408. +** Specifies a new value for the pointer pointed to by Target.
  163409. +**
  163410. +** OUT gctPOINTER * OldValue
  163411. +** The old value of the pointer pointed to by Target.
  163412. +**
  163413. +** OUTPUT:
  163414. +**
  163415. +** Nothing.
  163416. +*/
  163417. +gceSTATUS
  163418. +gckOS_AtomicExchangePtr(
  163419. + IN gckOS Os,
  163420. + IN OUT gctPOINTER * Target,
  163421. + IN gctPOINTER NewValue,
  163422. + OUT gctPOINTER * OldValue
  163423. + )
  163424. +{
  163425. + gcmkHEADER_ARG("Os=0x%X Target=0x%X NewValue=0x%X", Os, Target, NewValue);
  163426. +
  163427. + /* Verify the arguments. */
  163428. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163429. +
  163430. + /* Exchange the pair of pointers. */
  163431. + *OldValue = (gctPOINTER)(gctUINTPTR_T) atomic_xchg((atomic_t *) Target, (int)(gctUINTPTR_T) NewValue);
  163432. +
  163433. + /* Success. */
  163434. + gcmkFOOTER_ARG("*OldValue=0x%X", *OldValue);
  163435. + return gcvSTATUS_OK;
  163436. +}
  163437. +
  163438. +#if gcdSMP
  163439. +/*******************************************************************************
  163440. +**
  163441. +** gckOS_AtomicSetMask
  163442. +**
  163443. +** Atomically set mask to Atom
  163444. +**
  163445. +** INPUT:
  163446. +** IN OUT gctPOINTER Atom
  163447. +** Pointer to the atom to set.
  163448. +**
  163449. +** IN gctUINT32 Mask
  163450. +** Mask to set.
  163451. +**
  163452. +** OUTPUT:
  163453. +**
  163454. +** Nothing.
  163455. +*/
  163456. +gceSTATUS
  163457. +gckOS_AtomSetMask(
  163458. + IN gctPOINTER Atom,
  163459. + IN gctUINT32 Mask
  163460. + )
  163461. +{
  163462. + gctUINT32 oval, nval;
  163463. +
  163464. + gcmkHEADER_ARG("Atom=0x%0x", Atom);
  163465. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163466. +
  163467. + do
  163468. + {
  163469. + oval = atomic_read((atomic_t *) Atom);
  163470. + nval = oval | Mask;
  163471. + } while (atomic_cmpxchg((atomic_t *) Atom, oval, nval) != oval);
  163472. +
  163473. + gcmkFOOTER_NO();
  163474. + return gcvSTATUS_OK;
  163475. +}
  163476. +
  163477. +/*******************************************************************************
  163478. +**
  163479. +** gckOS_AtomClearMask
  163480. +**
  163481. +** Atomically clear mask from Atom
  163482. +**
  163483. +** INPUT:
  163484. +** IN OUT gctPOINTER Atom
  163485. +** Pointer to the atom to clear.
  163486. +**
  163487. +** IN gctUINT32 Mask
  163488. +** Mask to clear.
  163489. +**
  163490. +** OUTPUT:
  163491. +**
  163492. +** Nothing.
  163493. +*/
  163494. +gceSTATUS
  163495. +gckOS_AtomClearMask(
  163496. + IN gctPOINTER Atom,
  163497. + IN gctUINT32 Mask
  163498. + )
  163499. +{
  163500. + gctUINT32 oval, nval;
  163501. +
  163502. + gcmkHEADER_ARG("Atom=0x%0x", Atom);
  163503. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163504. +
  163505. + do
  163506. + {
  163507. + oval = atomic_read((atomic_t *) Atom);
  163508. + nval = oval & ~Mask;
  163509. + } while (atomic_cmpxchg((atomic_t *) Atom, oval, nval) != oval);
  163510. +
  163511. + gcmkFOOTER_NO();
  163512. + return gcvSTATUS_OK;
  163513. +}
  163514. +#endif
  163515. +
  163516. +/*******************************************************************************
  163517. +**
  163518. +** gckOS_AtomConstruct
  163519. +**
  163520. +** Create an atom.
  163521. +**
  163522. +** INPUT:
  163523. +**
  163524. +** gckOS Os
  163525. +** Pointer to a gckOS object.
  163526. +**
  163527. +** OUTPUT:
  163528. +**
  163529. +** gctPOINTER * Atom
  163530. +** Pointer to a variable receiving the constructed atom.
  163531. +*/
  163532. +gceSTATUS
  163533. +gckOS_AtomConstruct(
  163534. + IN gckOS Os,
  163535. + OUT gctPOINTER * Atom
  163536. + )
  163537. +{
  163538. + gceSTATUS status;
  163539. +
  163540. + gcmkHEADER_ARG("Os=0x%X", Os);
  163541. +
  163542. + /* Verify the arguments. */
  163543. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163544. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163545. +
  163546. + /* Allocate the atom. */
  163547. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(atomic_t), Atom));
  163548. +
  163549. + /* Initialize the atom. */
  163550. + atomic_set((atomic_t *) *Atom, 0);
  163551. +
  163552. + /* Success. */
  163553. + gcmkFOOTER_ARG("*Atom=0x%X", *Atom);
  163554. + return gcvSTATUS_OK;
  163555. +
  163556. +OnError:
  163557. + /* Return the status. */
  163558. + gcmkFOOTER();
  163559. + return status;
  163560. +}
  163561. +
  163562. +/*******************************************************************************
  163563. +**
  163564. +** gckOS_AtomDestroy
  163565. +**
  163566. +** Destroy an atom.
  163567. +**
  163568. +** INPUT:
  163569. +**
  163570. +** gckOS Os
  163571. +** Pointer to a gckOS object.
  163572. +**
  163573. +** gctPOINTER Atom
  163574. +** Pointer to the atom to destroy.
  163575. +**
  163576. +** OUTPUT:
  163577. +**
  163578. +** Nothing.
  163579. +*/
  163580. +gceSTATUS
  163581. +gckOS_AtomDestroy(
  163582. + IN gckOS Os,
  163583. + OUT gctPOINTER Atom
  163584. + )
  163585. +{
  163586. + gceSTATUS status;
  163587. +
  163588. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  163589. +
  163590. + /* Verify the arguments. */
  163591. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163592. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163593. +
  163594. + /* Free the atom. */
  163595. + gcmkONERROR(gcmkOS_SAFE_FREE(Os, Atom));
  163596. +
  163597. + /* Success. */
  163598. + gcmkFOOTER_NO();
  163599. + return gcvSTATUS_OK;
  163600. +
  163601. +OnError:
  163602. + /* Return the status. */
  163603. + gcmkFOOTER();
  163604. + return status;
  163605. +}
  163606. +
  163607. +/*******************************************************************************
  163608. +**
  163609. +** gckOS_AtomGet
  163610. +**
  163611. +** Get the 32-bit value protected by an atom.
  163612. +**
  163613. +** INPUT:
  163614. +**
  163615. +** gckOS Os
  163616. +** Pointer to a gckOS object.
  163617. +**
  163618. +** gctPOINTER Atom
  163619. +** Pointer to the atom.
  163620. +**
  163621. +** OUTPUT:
  163622. +**
  163623. +** gctINT32_PTR Value
  163624. +** Pointer to a variable the receives the value of the atom.
  163625. +*/
  163626. +gceSTATUS
  163627. +gckOS_AtomGet(
  163628. + IN gckOS Os,
  163629. + IN gctPOINTER Atom,
  163630. + OUT gctINT32_PTR Value
  163631. + )
  163632. +{
  163633. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  163634. +
  163635. + /* Verify the arguments. */
  163636. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163637. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163638. +
  163639. + /* Return the current value of atom. */
  163640. + *Value = atomic_read((atomic_t *) Atom);
  163641. +
  163642. + /* Success. */
  163643. + gcmkFOOTER_ARG("*Value=%d", *Value);
  163644. + return gcvSTATUS_OK;
  163645. +}
  163646. +
  163647. +/*******************************************************************************
  163648. +**
  163649. +** gckOS_AtomSet
  163650. +**
  163651. +** Set the 32-bit value protected by an atom.
  163652. +**
  163653. +** INPUT:
  163654. +**
  163655. +** gckOS Os
  163656. +** Pointer to a gckOS object.
  163657. +**
  163658. +** gctPOINTER Atom
  163659. +** Pointer to the atom.
  163660. +**
  163661. +** gctINT32 Value
  163662. +** The value of the atom.
  163663. +**
  163664. +** OUTPUT:
  163665. +**
  163666. +** Nothing.
  163667. +*/
  163668. +gceSTATUS
  163669. +gckOS_AtomSet(
  163670. + IN gckOS Os,
  163671. + IN gctPOINTER Atom,
  163672. + IN gctINT32 Value
  163673. + )
  163674. +{
  163675. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x Value=%d", Os, Atom);
  163676. +
  163677. + /* Verify the arguments. */
  163678. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163679. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163680. +
  163681. + /* Set the current value of atom. */
  163682. + atomic_set((atomic_t *) Atom, Value);
  163683. +
  163684. + /* Success. */
  163685. + gcmkFOOTER_NO();
  163686. + return gcvSTATUS_OK;
  163687. +}
  163688. +
  163689. +/*******************************************************************************
  163690. +**
  163691. +** gckOS_AtomIncrement
  163692. +**
  163693. +** Atomically increment the 32-bit integer value inside an atom.
  163694. +**
  163695. +** INPUT:
  163696. +**
  163697. +** gckOS Os
  163698. +** Pointer to a gckOS object.
  163699. +**
  163700. +** gctPOINTER Atom
  163701. +** Pointer to the atom.
  163702. +**
  163703. +** OUTPUT:
  163704. +**
  163705. +** gctINT32_PTR Value
  163706. +** Pointer to a variable that receives the original value of the atom.
  163707. +*/
  163708. +gceSTATUS
  163709. +gckOS_AtomIncrement(
  163710. + IN gckOS Os,
  163711. + IN gctPOINTER Atom,
  163712. + OUT gctINT32_PTR Value
  163713. + )
  163714. +{
  163715. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  163716. +
  163717. + /* Verify the arguments. */
  163718. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163719. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163720. +
  163721. + /* Increment the atom. */
  163722. + *Value = atomic_inc_return((atomic_t *) Atom) - 1;
  163723. +
  163724. + /* Success. */
  163725. + gcmkFOOTER_ARG("*Value=%d", *Value);
  163726. + return gcvSTATUS_OK;
  163727. +}
  163728. +
  163729. +/*******************************************************************************
  163730. +**
  163731. +** gckOS_AtomDecrement
  163732. +**
  163733. +** Atomically decrement the 32-bit integer value inside an atom.
  163734. +**
  163735. +** INPUT:
  163736. +**
  163737. +** gckOS Os
  163738. +** Pointer to a gckOS object.
  163739. +**
  163740. +** gctPOINTER Atom
  163741. +** Pointer to the atom.
  163742. +**
  163743. +** OUTPUT:
  163744. +**
  163745. +** gctINT32_PTR Value
  163746. +** Pointer to a variable that receives the original value of the atom.
  163747. +*/
  163748. +gceSTATUS
  163749. +gckOS_AtomDecrement(
  163750. + IN gckOS Os,
  163751. + IN gctPOINTER Atom,
  163752. + OUT gctINT32_PTR Value
  163753. + )
  163754. +{
  163755. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  163756. +
  163757. + /* Verify the arguments. */
  163758. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163759. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  163760. +
  163761. + /* Decrement the atom. */
  163762. + *Value = atomic_dec_return((atomic_t *) Atom) + 1;
  163763. +
  163764. + /* Success. */
  163765. + gcmkFOOTER_ARG("*Value=%d", *Value);
  163766. + return gcvSTATUS_OK;
  163767. +}
  163768. +
  163769. +/*******************************************************************************
  163770. +**
  163771. +** gckOS_Delay
  163772. +**
  163773. +** Delay execution of the current thread for a number of milliseconds.
  163774. +**
  163775. +** INPUT:
  163776. +**
  163777. +** gckOS Os
  163778. +** Pointer to an gckOS object.
  163779. +**
  163780. +** gctUINT32 Delay
  163781. +** Delay to sleep, specified in milliseconds.
  163782. +**
  163783. +** OUTPUT:
  163784. +**
  163785. +** Nothing.
  163786. +*/
  163787. +gceSTATUS
  163788. +gckOS_Delay(
  163789. + IN gckOS Os,
  163790. + IN gctUINT32 Delay
  163791. + )
  163792. +{
  163793. + gcmkHEADER_ARG("Os=0x%X Delay=%u", Os, Delay);
  163794. +
  163795. + if (Delay > 0)
  163796. + {
  163797. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
  163798. + ktime_t delay = ktime_set(Delay/1000, (Delay%1000) * NSEC_PER_MSEC);
  163799. + __set_current_state(TASK_UNINTERRUPTIBLE);
  163800. + schedule_hrtimeout(&delay, HRTIMER_MODE_REL);
  163801. +#else
  163802. + msleep(Delay);
  163803. +#endif
  163804. +
  163805. + }
  163806. +
  163807. + /* Success. */
  163808. + gcmkFOOTER_NO();
  163809. + return gcvSTATUS_OK;
  163810. +}
  163811. +
  163812. +/*******************************************************************************
  163813. +**
  163814. +** gckOS_GetTicks
  163815. +**
  163816. +** Get the number of milliseconds since the system started.
  163817. +**
  163818. +** INPUT:
  163819. +**
  163820. +** OUTPUT:
  163821. +**
  163822. +** gctUINT32_PTR Time
  163823. +** Pointer to a variable to get time.
  163824. +**
  163825. +*/
  163826. +gceSTATUS
  163827. +gckOS_GetTicks(
  163828. + OUT gctUINT32_PTR Time
  163829. + )
  163830. +{
  163831. + gcmkHEADER();
  163832. +
  163833. + *Time = jiffies_to_msecs(jiffies);
  163834. +
  163835. + gcmkFOOTER_NO();
  163836. + return gcvSTATUS_OK;
  163837. +}
  163838. +
  163839. +/*******************************************************************************
  163840. +**
  163841. +** gckOS_TicksAfter
  163842. +**
  163843. +** Compare time values got from gckOS_GetTicks.
  163844. +**
  163845. +** INPUT:
  163846. +** gctUINT32 Time1
  163847. +** First time value to be compared.
  163848. +**
  163849. +** gctUINT32 Time2
  163850. +** Second time value to be compared.
  163851. +**
  163852. +** OUTPUT:
  163853. +**
  163854. +** gctBOOL_PTR IsAfter
  163855. +** Pointer to a variable to result.
  163856. +**
  163857. +*/
  163858. +gceSTATUS
  163859. +gckOS_TicksAfter(
  163860. + IN gctUINT32 Time1,
  163861. + IN gctUINT32 Time2,
  163862. + OUT gctBOOL_PTR IsAfter
  163863. + )
  163864. +{
  163865. + gcmkHEADER();
  163866. +
  163867. + *IsAfter = time_after((unsigned long)Time1, (unsigned long)Time2);
  163868. +
  163869. + gcmkFOOTER_NO();
  163870. + return gcvSTATUS_OK;
  163871. +}
  163872. +
  163873. +/*******************************************************************************
  163874. +**
  163875. +** gckOS_GetTime
  163876. +**
  163877. +** Get the number of microseconds since the system started.
  163878. +**
  163879. +** INPUT:
  163880. +**
  163881. +** OUTPUT:
  163882. +**
  163883. +** gctUINT64_PTR Time
  163884. +** Pointer to a variable to get time.
  163885. +**
  163886. +*/
  163887. +gceSTATUS
  163888. +gckOS_GetTime(
  163889. + OUT gctUINT64_PTR Time
  163890. + )
  163891. +{
  163892. + gcmkHEADER();
  163893. +
  163894. + *Time = 0;
  163895. +
  163896. + gcmkFOOTER_NO();
  163897. + return gcvSTATUS_OK;
  163898. +}
  163899. +
  163900. +/*******************************************************************************
  163901. +**
  163902. +** gckOS_MemoryBarrier
  163903. +**
  163904. +** Make sure the CPU has executed everything up to this point and the data got
  163905. +** written to the specified pointer.
  163906. +**
  163907. +** INPUT:
  163908. +**
  163909. +** gckOS Os
  163910. +** Pointer to an gckOS object.
  163911. +**
  163912. +** gctPOINTER Address
  163913. +** Address of memory that needs to be barriered.
  163914. +**
  163915. +** OUTPUT:
  163916. +**
  163917. +** Nothing.
  163918. +*/
  163919. +gceSTATUS
  163920. +gckOS_MemoryBarrier(
  163921. + IN gckOS Os,
  163922. + IN gctPOINTER Address
  163923. + )
  163924. +{
  163925. + gcmkHEADER_ARG("Os=0x%X Address=0x%X", Os, Address);
  163926. +
  163927. + /* Verify the arguments. */
  163928. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163929. +
  163930. +#if gcdNONPAGED_MEMORY_BUFFERABLE \
  163931. + && defined (CONFIG_ARM) \
  163932. + && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
  163933. + /* drain write buffer */
  163934. + dsb();
  163935. +
  163936. + /* drain outer cache's write buffer? */
  163937. +#else
  163938. + mb();
  163939. +#endif
  163940. +
  163941. + /* Success. */
  163942. + gcmkFOOTER_NO();
  163943. + return gcvSTATUS_OK;
  163944. +}
  163945. +
  163946. +/*******************************************************************************
  163947. +**
  163948. +** gckOS_AllocatePagedMemory
  163949. +**
  163950. +** Allocate memory from the paged pool.
  163951. +**
  163952. +** INPUT:
  163953. +**
  163954. +** gckOS Os
  163955. +** Pointer to an gckOS object.
  163956. +**
  163957. +** gctSIZE_T Bytes
  163958. +** Number of bytes to allocate.
  163959. +**
  163960. +** OUTPUT:
  163961. +**
  163962. +** gctPHYS_ADDR * Physical
  163963. +** Pointer to a variable that receives the physical address of the
  163964. +** memory allocation.
  163965. +*/
  163966. +gceSTATUS
  163967. +gckOS_AllocatePagedMemory(
  163968. + IN gckOS Os,
  163969. + IN gctSIZE_T Bytes,
  163970. + OUT gctPHYS_ADDR * Physical
  163971. + )
  163972. +{
  163973. + gceSTATUS status;
  163974. +
  163975. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
  163976. +
  163977. + /* Verify the arguments. */
  163978. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163979. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  163980. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  163981. +
  163982. + /* Allocate the memory. */
  163983. + gcmkONERROR(gckOS_AllocatePagedMemoryEx(Os, gcvFALSE, Bytes, Physical));
  163984. +
  163985. + /* Success. */
  163986. + gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
  163987. + return gcvSTATUS_OK;
  163988. +
  163989. +OnError:
  163990. + /* Return the status. */
  163991. + gcmkFOOTER();
  163992. + return status;
  163993. +}
  163994. +
  163995. +/*******************************************************************************
  163996. +**
  163997. +** gckOS_AllocatePagedMemoryEx
  163998. +**
  163999. +** Allocate memory from the paged pool.
  164000. +**
  164001. +** INPUT:
  164002. +**
  164003. +** gckOS Os
  164004. +** Pointer to an gckOS object.
  164005. +**
  164006. +** gctBOOL Contiguous
  164007. +** Need contiguous memory or not.
  164008. +**
  164009. +** gctSIZE_T Bytes
  164010. +** Number of bytes to allocate.
  164011. +**
  164012. +** OUTPUT:
  164013. +**
  164014. +** gctPHYS_ADDR * Physical
  164015. +** Pointer to a variable that receives the physical address of the
  164016. +** memory allocation.
  164017. +*/
  164018. +gceSTATUS
  164019. +gckOS_AllocatePagedMemoryEx(
  164020. + IN gckOS Os,
  164021. + IN gctBOOL Contiguous,
  164022. + IN gctSIZE_T Bytes,
  164023. + OUT gctPHYS_ADDR * Physical
  164024. + )
  164025. +{
  164026. + gctINT numPages;
  164027. + gctINT i;
  164028. + PLINUX_MDL mdl = gcvNULL;
  164029. + gctSIZE_T bytes;
  164030. + gctBOOL locked = gcvFALSE;
  164031. + gceSTATUS status;
  164032. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  164033. + gctPOINTER addr = gcvNULL;
  164034. +#endif
  164035. +
  164036. + gcmkHEADER_ARG("Os=0x%X Contiguous=%d Bytes=%lu", Os, Contiguous, Bytes);
  164037. +
  164038. + /* Verify the arguments. */
  164039. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164040. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  164041. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164042. +
  164043. + bytes = gcmALIGN(Bytes, PAGE_SIZE);
  164044. +
  164045. + numPages = GetPageCount(bytes, 0);
  164046. +
  164047. + MEMORY_LOCK(Os);
  164048. + locked = gcvTRUE;
  164049. +
  164050. + mdl = _CreateMdl(_GetProcessID());
  164051. + if (mdl == gcvNULL)
  164052. + {
  164053. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  164054. + }
  164055. +
  164056. + if (Contiguous)
  164057. + {
  164058. + gctUINT32 order = get_order(bytes);
  164059. +
  164060. + if (order >= MAX_ORDER)
  164061. + {
  164062. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  164063. + }
  164064. +
  164065. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  164066. + addr =
  164067. + alloc_pages_exact(numPages * PAGE_SIZE, GFP_KERNEL | gcdNOWARN | __GFP_NORETRY);
  164068. +
  164069. + mdl->u.contiguousPages = addr
  164070. + ? virt_to_page(addr)
  164071. + : gcvNULL;
  164072. +
  164073. + mdl->exact = gcvTRUE;
  164074. +#else
  164075. + mdl->u.contiguousPages =
  164076. + alloc_pages(GFP_KERNEL | gcdNOWARN | __GFP_NORETRY, order);
  164077. +#endif
  164078. + if (mdl->u.contiguousPages == gcvNULL)
  164079. + {
  164080. + mdl->u.contiguousPages =
  164081. + alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN, order);
  164082. +
  164083. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  164084. + mdl->exact = gcvFALSE;
  164085. +#endif
  164086. + }
  164087. + }
  164088. + else
  164089. + {
  164090. + mdl->u.nonContiguousPages = _NonContiguousAlloc(numPages);
  164091. + }
  164092. +
  164093. + if (mdl->u.contiguousPages == gcvNULL && mdl->u.nonContiguousPages == gcvNULL)
  164094. + {
  164095. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  164096. + }
  164097. +
  164098. + mdl->dmaHandle = 0;
  164099. + mdl->addr = 0;
  164100. + mdl->numPages = numPages;
  164101. + mdl->pagedMem = 1;
  164102. + mdl->contiguous = Contiguous;
  164103. +
  164104. + for (i = 0; i < mdl->numPages; i++)
  164105. + {
  164106. + struct page *page;
  164107. +
  164108. + if (mdl->contiguous)
  164109. + {
  164110. + page = nth_page(mdl->u.contiguousPages, i);
  164111. + }
  164112. + else
  164113. + {
  164114. + page = _NonContiguousToPage(mdl->u.nonContiguousPages, i);
  164115. + }
  164116. +
  164117. + SetPageReserved(page);
  164118. +
  164119. + if (!PageHighMem(page) && page_to_phys(page))
  164120. + {
  164121. + gcmkVERIFY_OK(
  164122. + gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
  164123. + (gctPOINTER)(gctUINTPTR_T)page_to_phys(page),
  164124. + page_address(page),
  164125. + PAGE_SIZE));
  164126. + }
  164127. + }
  164128. +
  164129. + /* Return physical address. */
  164130. + *Physical = (gctPHYS_ADDR) mdl;
  164131. +
  164132. + /*
  164133. + * Add this to a global list.
  164134. + * Will be used by get physical address
  164135. + * and mapuser pointer functions.
  164136. + */
  164137. + if (!Os->mdlHead)
  164138. + {
  164139. + /* Initialize the queue. */
  164140. + Os->mdlHead = Os->mdlTail = mdl;
  164141. + }
  164142. + else
  164143. + {
  164144. + /* Add to tail. */
  164145. + mdl->prev = Os->mdlTail;
  164146. + Os->mdlTail->next = mdl;
  164147. + Os->mdlTail = mdl;
  164148. + }
  164149. +
  164150. + MEMORY_UNLOCK(Os);
  164151. +
  164152. + /* Success. */
  164153. + gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
  164154. + return gcvSTATUS_OK;
  164155. +
  164156. +OnError:
  164157. + if (mdl != gcvNULL)
  164158. + {
  164159. + /* Free the memory. */
  164160. + _DestroyMdl(mdl);
  164161. + }
  164162. +
  164163. + if (locked)
  164164. + {
  164165. + /* Unlock the memory. */
  164166. + MEMORY_UNLOCK(Os);
  164167. + }
  164168. +
  164169. + /* Return the status. */
  164170. + gcmkFOOTER();
  164171. + return status;
  164172. +}
  164173. +
  164174. +/*******************************************************************************
  164175. +**
  164176. +** gckOS_FreePagedMemory
  164177. +**
  164178. +** Free memory allocated from the paged pool.
  164179. +**
  164180. +** INPUT:
  164181. +**
  164182. +** gckOS Os
  164183. +** Pointer to an gckOS object.
  164184. +**
  164185. +** gctPHYS_ADDR Physical
  164186. +** Physical address of the allocation.
  164187. +**
  164188. +** gctSIZE_T Bytes
  164189. +** Number of bytes of the allocation.
  164190. +**
  164191. +** OUTPUT:
  164192. +**
  164193. +** Nothing.
  164194. +*/
  164195. +gceSTATUS
  164196. +gckOS_FreePagedMemory(
  164197. + IN gckOS Os,
  164198. + IN gctPHYS_ADDR Physical,
  164199. + IN gctSIZE_T Bytes
  164200. + )
  164201. +{
  164202. + PLINUX_MDL mdl = (PLINUX_MDL) Physical;
  164203. + gctINT i;
  164204. +
  164205. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
  164206. +
  164207. + /* Verify the arguments. */
  164208. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164209. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164210. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  164211. +
  164212. + /*addr = mdl->addr;*/
  164213. +
  164214. + MEMORY_LOCK(Os);
  164215. +
  164216. + for (i = 0; i < mdl->numPages; i++)
  164217. + {
  164218. + if (mdl->contiguous)
  164219. + {
  164220. + ClearPageReserved(nth_page(mdl->u.contiguousPages, i));
  164221. + }
  164222. + else
  164223. + {
  164224. + ClearPageReserved(_NonContiguousToPage(mdl->u.nonContiguousPages, i));
  164225. + }
  164226. + }
  164227. +
  164228. + if (mdl->contiguous)
  164229. + {
  164230. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  164231. + if (mdl->exact == gcvTRUE)
  164232. + {
  164233. + free_pages_exact(page_address(mdl->u.contiguousPages), mdl->numPages * PAGE_SIZE);
  164234. + }
  164235. + else
  164236. +#endif
  164237. + {
  164238. + __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages));
  164239. + }
  164240. + }
  164241. + else
  164242. + {
  164243. + _NonContiguousFree(mdl->u.nonContiguousPages, mdl->numPages);
  164244. + }
  164245. +
  164246. + /* Remove the node from global list. */
  164247. + if (mdl == Os->mdlHead)
  164248. + {
  164249. + if ((Os->mdlHead = mdl->next) == gcvNULL)
  164250. + {
  164251. + Os->mdlTail = gcvNULL;
  164252. + }
  164253. + }
  164254. + else
  164255. + {
  164256. + mdl->prev->next = mdl->next;
  164257. +
  164258. + if (mdl == Os->mdlTail)
  164259. + {
  164260. + Os->mdlTail = mdl->prev;
  164261. + }
  164262. + else
  164263. + {
  164264. + mdl->next->prev = mdl->prev;
  164265. + }
  164266. + }
  164267. +
  164268. + MEMORY_UNLOCK(Os);
  164269. +
  164270. + /* Free the structure... */
  164271. + gcmkVERIFY_OK(_DestroyMdl(mdl));
  164272. +
  164273. + /* Success. */
  164274. + gcmkFOOTER_NO();
  164275. + return gcvSTATUS_OK;
  164276. +}
  164277. +
  164278. +/*******************************************************************************
  164279. +**
  164280. +** gckOS_LockPages
  164281. +**
  164282. +** Lock memory allocated from the paged pool.
  164283. +**
  164284. +** INPUT:
  164285. +**
  164286. +** gckOS Os
  164287. +** Pointer to an gckOS object.
  164288. +**
  164289. +** gctPHYS_ADDR Physical
  164290. +** Physical address of the allocation.
  164291. +**
  164292. +** gctSIZE_T Bytes
  164293. +** Number of bytes of the allocation.
  164294. +**
  164295. +** gctBOOL Cacheable
  164296. +** Cache mode of mapping.
  164297. +**
  164298. +** OUTPUT:
  164299. +**
  164300. +** gctPOINTER * Logical
  164301. +** Pointer to a variable that receives the address of the mapped
  164302. +** memory.
  164303. +**
  164304. +** gctSIZE_T * PageCount
  164305. +** Pointer to a variable that receives the number of pages required for
  164306. +** the page table according to the GPU page size.
  164307. +*/
  164308. +gceSTATUS
  164309. +gckOS_LockPages(
  164310. + IN gckOS Os,
  164311. + IN gctPHYS_ADDR Physical,
  164312. + IN gctSIZE_T Bytes,
  164313. + IN gctBOOL Cacheable,
  164314. + OUT gctPOINTER * Logical,
  164315. + OUT gctSIZE_T * PageCount
  164316. + )
  164317. +{
  164318. + PLINUX_MDL mdl;
  164319. + PLINUX_MDL_MAP mdlMap;
  164320. + gctSTRING addr;
  164321. + unsigned long start;
  164322. + unsigned long pfn;
  164323. + gctINT i;
  164324. +
  164325. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Logical);
  164326. +
  164327. + /* Verify the arguments. */
  164328. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164329. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164330. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164331. + gcmkVERIFY_ARGUMENT(PageCount != gcvNULL);
  164332. +
  164333. + mdl = (PLINUX_MDL) Physical;
  164334. +
  164335. + MEMORY_LOCK(Os);
  164336. +
  164337. + mdlMap = FindMdlMap(mdl, _GetProcessID());
  164338. +
  164339. + if (mdlMap == gcvNULL)
  164340. + {
  164341. + mdlMap = _CreateMdlMap(mdl, _GetProcessID());
  164342. +
  164343. + if (mdlMap == gcvNULL)
  164344. + {
  164345. + MEMORY_UNLOCK(Os);
  164346. +
  164347. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  164348. + return gcvSTATUS_OUT_OF_MEMORY;
  164349. + }
  164350. + }
  164351. +
  164352. + if (mdlMap->vmaAddr == gcvNULL)
  164353. + {
  164354. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
  164355. + mdlMap->vmaAddr = (gctSTRING)vm_mmap(gcvNULL,
  164356. + 0L,
  164357. + mdl->numPages * PAGE_SIZE,
  164358. + PROT_READ | PROT_WRITE,
  164359. + MAP_SHARED,
  164360. + 0);
  164361. +#else
  164362. + down_write(&current->mm->mmap_sem);
  164363. +
  164364. + mdlMap->vmaAddr = (gctSTRING)do_mmap_pgoff(gcvNULL,
  164365. + 0L,
  164366. + mdl->numPages * PAGE_SIZE,
  164367. + PROT_READ | PROT_WRITE,
  164368. + MAP_SHARED,
  164369. + 0);
  164370. +
  164371. + up_write(&current->mm->mmap_sem);
  164372. +#endif
  164373. +
  164374. + gcmkTRACE_ZONE(
  164375. + gcvLEVEL_INFO, gcvZONE_OS,
  164376. + "%s(%d): vmaAddr->0x%X for phys_addr->0x%X",
  164377. + __FUNCTION__, __LINE__,
  164378. + (gctUINT32)(gctUINTPTR_T)mdlMap->vmaAddr,
  164379. + (gctUINT32)(gctUINTPTR_T)mdl
  164380. + );
  164381. +
  164382. + if (IS_ERR(mdlMap->vmaAddr))
  164383. + {
  164384. + gcmkTRACE_ZONE(
  164385. + gcvLEVEL_INFO, gcvZONE_OS,
  164386. + "%s(%d): do_mmap_pgoff error",
  164387. + __FUNCTION__, __LINE__
  164388. + );
  164389. +
  164390. + mdlMap->vmaAddr = gcvNULL;
  164391. +
  164392. + MEMORY_UNLOCK(Os);
  164393. +
  164394. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  164395. + return gcvSTATUS_OUT_OF_MEMORY;
  164396. + }
  164397. +
  164398. + down_write(&current->mm->mmap_sem);
  164399. +
  164400. + mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
  164401. +
  164402. + if (mdlMap->vma == gcvNULL)
  164403. + {
  164404. + up_write(&current->mm->mmap_sem);
  164405. +
  164406. + gcmkTRACE_ZONE(
  164407. + gcvLEVEL_INFO, gcvZONE_OS,
  164408. + "%s(%d): find_vma error",
  164409. + __FUNCTION__, __LINE__
  164410. + );
  164411. +
  164412. + mdlMap->vmaAddr = gcvNULL;
  164413. +
  164414. + MEMORY_UNLOCK(Os);
  164415. +
  164416. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  164417. + return gcvSTATUS_OUT_OF_RESOURCES;
  164418. + }
  164419. +
  164420. + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
  164421. +
  164422. + if (Cacheable == gcvFALSE)
  164423. + {
  164424. + /* Make this mapping non-cached. */
  164425. + mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
  164426. + }
  164427. +
  164428. + addr = mdl->addr;
  164429. +
  164430. + /* Now map all the vmalloc pages to this user address. */
  164431. + if (mdl->contiguous)
  164432. + {
  164433. + /* map kernel memory to user space.. */
  164434. + if (remap_pfn_range(mdlMap->vma,
  164435. + mdlMap->vma->vm_start,
  164436. + page_to_pfn(mdl->u.contiguousPages),
  164437. + mdlMap->vma->vm_end - mdlMap->vma->vm_start,
  164438. + mdlMap->vma->vm_page_prot) < 0)
  164439. + {
  164440. + up_write(&current->mm->mmap_sem);
  164441. +
  164442. + gcmkTRACE_ZONE(
  164443. + gcvLEVEL_INFO, gcvZONE_OS,
  164444. + "%s(%d): unable to mmap ret",
  164445. + __FUNCTION__, __LINE__
  164446. + );
  164447. +
  164448. + mdlMap->vmaAddr = gcvNULL;
  164449. +
  164450. + MEMORY_UNLOCK(Os);
  164451. +
  164452. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  164453. + return gcvSTATUS_OUT_OF_MEMORY;
  164454. + }
  164455. + }
  164456. + else
  164457. + {
  164458. + start = mdlMap->vma->vm_start;
  164459. +
  164460. + for (i = 0; i < mdl->numPages; i++)
  164461. + {
  164462. + pfn = _NonContiguousToPfn(mdl->u.nonContiguousPages, i);
  164463. +
  164464. + if (remap_pfn_range(mdlMap->vma,
  164465. + start,
  164466. + pfn,
  164467. + PAGE_SIZE,
  164468. + mdlMap->vma->vm_page_prot) < 0)
  164469. + {
  164470. + up_write(&current->mm->mmap_sem);
  164471. +
  164472. + gcmkTRACE_ZONE(
  164473. + gcvLEVEL_INFO, gcvZONE_OS,
  164474. + "%s(%d): gctPHYS_ADDR->0x%X Logical->0x%X Unable to map addr->0x%X to start->0x%X",
  164475. + __FUNCTION__, __LINE__,
  164476. + (gctUINT32)(gctUINTPTR_T)Physical,
  164477. + (gctUINT32)(gctUINTPTR_T)*Logical,
  164478. + (gctUINT32)(gctUINTPTR_T)addr,
  164479. + (gctUINT32)(gctUINTPTR_T)start
  164480. + );
  164481. +
  164482. + mdlMap->vmaAddr = gcvNULL;
  164483. +
  164484. + MEMORY_UNLOCK(Os);
  164485. +
  164486. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  164487. + return gcvSTATUS_OUT_OF_MEMORY;
  164488. + }
  164489. +
  164490. + start += PAGE_SIZE;
  164491. + addr += PAGE_SIZE;
  164492. + }
  164493. + }
  164494. +
  164495. + up_write(&current->mm->mmap_sem);
  164496. + }
  164497. +
  164498. + mdlMap->count++;
  164499. +
  164500. + /* Convert pointer to MDL. */
  164501. + *Logical = mdlMap->vmaAddr;
  164502. +
  164503. + /* Return the page number according to the GPU page size. */
  164504. + gcmkASSERT((PAGE_SIZE % 4096) == 0);
  164505. + gcmkASSERT((PAGE_SIZE / 4096) >= 1);
  164506. +
  164507. + *PageCount = mdl->numPages * (PAGE_SIZE / 4096);
  164508. +
  164509. + MEMORY_UNLOCK(Os);
  164510. +
  164511. + gcmkVERIFY_OK(gckOS_CacheFlush(
  164512. + Os,
  164513. + _GetProcessID(),
  164514. + Physical,
  164515. + gcvNULL,
  164516. + (gctPOINTER)mdlMap->vmaAddr,
  164517. + mdl->numPages * PAGE_SIZE
  164518. + ));
  164519. +
  164520. + /* Success. */
  164521. + gcmkFOOTER_ARG("*Logical=0x%X *PageCount=%lu", *Logical, *PageCount);
  164522. + return gcvSTATUS_OK;
  164523. +}
  164524. +
  164525. +/*******************************************************************************
  164526. +**
  164527. +** gckOS_MapPages
  164528. +**
  164529. +** Map paged memory into a page table.
  164530. +**
  164531. +** INPUT:
  164532. +**
  164533. +** gckOS Os
  164534. +** Pointer to an gckOS object.
  164535. +**
  164536. +** gctPHYS_ADDR Physical
  164537. +** Physical address of the allocation.
  164538. +**
  164539. +** gctSIZE_T PageCount
  164540. +** Number of pages required for the physical address.
  164541. +**
  164542. +** gctPOINTER PageTable
  164543. +** Pointer to the page table to fill in.
  164544. +**
  164545. +** OUTPUT:
  164546. +**
  164547. +** Nothing.
  164548. +*/
  164549. +gceSTATUS
  164550. +gckOS_MapPages(
  164551. + IN gckOS Os,
  164552. + IN gctPHYS_ADDR Physical,
  164553. + IN gctSIZE_T PageCount,
  164554. + IN gctPOINTER PageTable
  164555. + )
  164556. +{
  164557. + return gckOS_MapPagesEx(Os,
  164558. + gcvCORE_MAJOR,
  164559. + Physical,
  164560. + PageCount,
  164561. + PageTable);
  164562. +}
  164563. +
  164564. +gceSTATUS
  164565. +gckOS_MapPagesEx(
  164566. + IN gckOS Os,
  164567. + IN gceCORE Core,
  164568. + IN gctPHYS_ADDR Physical,
  164569. + IN gctSIZE_T PageCount,
  164570. + IN gctPOINTER PageTable
  164571. + )
  164572. +{
  164573. + gceSTATUS status = gcvSTATUS_OK;
  164574. + PLINUX_MDL mdl;
  164575. + gctUINT32* table;
  164576. + gctUINT32 offset;
  164577. +#if gcdNONPAGED_MEMORY_CACHEABLE
  164578. + gckMMU mmu;
  164579. + PLINUX_MDL mmuMdl;
  164580. + gctUINT32 bytes;
  164581. + gctPHYS_ADDR pageTablePhysical;
  164582. +#endif
  164583. +
  164584. + gcmkHEADER_ARG("Os=0x%X Core=%d Physical=0x%X PageCount=%u PageTable=0x%X",
  164585. + Os, Core, Physical, PageCount, PageTable);
  164586. +
  164587. + /* Verify the arguments. */
  164588. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164589. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164590. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  164591. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  164592. +
  164593. + /* Convert pointer to MDL. */
  164594. + mdl = (PLINUX_MDL)Physical;
  164595. +
  164596. + gcmkTRACE_ZONE(
  164597. + gcvLEVEL_INFO, gcvZONE_OS,
  164598. + "%s(%d): Physical->0x%X PageCount->0x%X PagedMemory->?%d",
  164599. + __FUNCTION__, __LINE__,
  164600. + (gctUINT32)(gctUINTPTR_T)Physical,
  164601. + (gctUINT32)(gctUINTPTR_T)PageCount,
  164602. + mdl->pagedMem
  164603. + );
  164604. +
  164605. + MEMORY_LOCK(Os);
  164606. +
  164607. + table = (gctUINT32 *)PageTable;
  164608. +#if gcdNONPAGED_MEMORY_CACHEABLE
  164609. + mmu = Os->device->kernels[Core]->mmu;
  164610. + bytes = PageCount * sizeof(*table);
  164611. + mmuMdl = (PLINUX_MDL)mmu->pageTablePhysical;
  164612. +#endif
  164613. +
  164614. + /* Get all the physical addresses and store them in the page table. */
  164615. +
  164616. + offset = 0;
  164617. +
  164618. + if (mdl->pagedMem)
  164619. + {
  164620. + /* Try to get the user pages so DMA can happen. */
  164621. + while (PageCount-- > 0)
  164622. + {
  164623. +#if gcdENABLE_VG
  164624. + if (Core == gcvCORE_VG)
  164625. + {
  164626. + if (mdl->contiguous)
  164627. + {
  164628. + gcmkONERROR(
  164629. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  164630. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  164631. + table));
  164632. + }
  164633. + else
  164634. + {
  164635. + gcmkONERROR(
  164636. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  164637. + _NonContiguousToPhys(mdl->u.nonContiguousPages, offset),
  164638. + table));
  164639. + }
  164640. + }
  164641. + else
  164642. +#endif
  164643. + {
  164644. + if (mdl->contiguous)
  164645. + {
  164646. + gcmkONERROR(
  164647. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  164648. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  164649. + table));
  164650. + }
  164651. + else
  164652. + {
  164653. + gcmkONERROR(
  164654. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  164655. + _NonContiguousToPhys(mdl->u.nonContiguousPages, offset),
  164656. + table));
  164657. + }
  164658. + }
  164659. +
  164660. + table++;
  164661. + offset += 1;
  164662. + }
  164663. + }
  164664. + else
  164665. + {
  164666. + gcmkTRACE_ZONE(
  164667. + gcvLEVEL_INFO, gcvZONE_OS,
  164668. + "%s(%d): we should not get this call for Non Paged Memory!",
  164669. + __FUNCTION__, __LINE__
  164670. + );
  164671. +
  164672. + while (PageCount-- > 0)
  164673. + {
  164674. +#if gcdENABLE_VG
  164675. + if (Core == gcvCORE_VG)
  164676. + {
  164677. + gcmkONERROR(
  164678. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  164679. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  164680. + table));
  164681. + }
  164682. + else
  164683. +#endif
  164684. + {
  164685. + gcmkONERROR(
  164686. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  164687. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  164688. + table));
  164689. + }
  164690. + table++;
  164691. + offset += 1;
  164692. + }
  164693. + }
  164694. +
  164695. +#if gcdNONPAGED_MEMORY_CACHEABLE
  164696. + /* Get physical address of pageTable */
  164697. + pageTablePhysical = (gctPHYS_ADDR)(mmuMdl->dmaHandle +
  164698. + ((gctUINT32 *)PageTable - mmu->pageTableLogical));
  164699. +
  164700. + /* Flush the mmu page table cache. */
  164701. + gcmkONERROR(gckOS_CacheClean(
  164702. + Os,
  164703. + _GetProcessID(),
  164704. + gcvNULL,
  164705. + pageTablePhysical,
  164706. + PageTable,
  164707. + bytes
  164708. + ));
  164709. +#endif
  164710. +
  164711. +OnError:
  164712. +
  164713. + MEMORY_UNLOCK(Os);
  164714. +
  164715. + /* Return the status. */
  164716. + gcmkFOOTER();
  164717. + return status;
  164718. +}
  164719. +
  164720. +/*******************************************************************************
  164721. +**
  164722. +** gckOS_UnlockPages
  164723. +**
  164724. +** Unlock memory allocated from the paged pool.
  164725. +**
  164726. +** INPUT:
  164727. +**
  164728. +** gckOS Os
  164729. +** Pointer to an gckOS object.
  164730. +**
  164731. +** gctPHYS_ADDR Physical
  164732. +** Physical address of the allocation.
  164733. +**
  164734. +** gctSIZE_T Bytes
  164735. +** Number of bytes of the allocation.
  164736. +**
  164737. +** gctPOINTER Logical
  164738. +** Address of the mapped memory.
  164739. +**
  164740. +** OUTPUT:
  164741. +**
  164742. +** Nothing.
  164743. +*/
  164744. +gceSTATUS
  164745. +gckOS_UnlockPages(
  164746. + IN gckOS Os,
  164747. + IN gctPHYS_ADDR Physical,
  164748. + IN gctSIZE_T Bytes,
  164749. + IN gctPOINTER Logical
  164750. + )
  164751. +{
  164752. + PLINUX_MDL_MAP mdlMap;
  164753. + PLINUX_MDL mdl = (PLINUX_MDL)Physical;
  164754. +
  164755. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%u Logical=0x%X",
  164756. + Os, Physical, Bytes, Logical);
  164757. +
  164758. + /* Verify the arguments. */
  164759. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164760. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164761. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164762. +
  164763. + /* Make sure there is already a mapping...*/
  164764. + gcmkVERIFY_ARGUMENT(mdl->u.nonContiguousPages != gcvNULL
  164765. + || mdl->u.contiguousPages != gcvNULL);
  164766. +
  164767. + MEMORY_LOCK(Os);
  164768. +
  164769. + mdlMap = mdl->maps;
  164770. +
  164771. + while (mdlMap != gcvNULL)
  164772. + {
  164773. + if ((mdlMap->vmaAddr != gcvNULL) && (_GetProcessID() == mdlMap->pid))
  164774. + {
  164775. + if (--mdlMap->count == 0)
  164776. + {
  164777. + _UnmapUserLogical(mdlMap->pid, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
  164778. + mdlMap->vmaAddr = gcvNULL;
  164779. + }
  164780. + }
  164781. +
  164782. + mdlMap = mdlMap->next;
  164783. + }
  164784. +
  164785. + MEMORY_UNLOCK(Os);
  164786. +
  164787. + /* Success. */
  164788. + gcmkFOOTER_NO();
  164789. + return gcvSTATUS_OK;
  164790. +}
  164791. +
  164792. +
  164793. +/*******************************************************************************
  164794. +**
  164795. +** gckOS_AllocateContiguous
  164796. +**
  164797. +** Allocate memory from the contiguous pool.
  164798. +**
  164799. +** INPUT:
  164800. +**
  164801. +** gckOS Os
  164802. +** Pointer to an gckOS object.
  164803. +**
  164804. +** gctBOOL InUserSpace
  164805. +** gcvTRUE if the pages need to be mapped into user space.
  164806. +**
  164807. +** gctSIZE_T * Bytes
  164808. +** Pointer to the number of bytes to allocate.
  164809. +**
  164810. +** OUTPUT:
  164811. +**
  164812. +** gctSIZE_T * Bytes
  164813. +** Pointer to a variable that receives the number of bytes allocated.
  164814. +**
  164815. +** gctPHYS_ADDR * Physical
  164816. +** Pointer to a variable that receives the physical address of the
  164817. +** memory allocation.
  164818. +**
  164819. +** gctPOINTER * Logical
  164820. +** Pointer to a variable that receives the logical address of the
  164821. +** memory allocation.
  164822. +*/
  164823. +gceSTATUS
  164824. +gckOS_AllocateContiguous(
  164825. + IN gckOS Os,
  164826. + IN gctBOOL InUserSpace,
  164827. + IN OUT gctSIZE_T * Bytes,
  164828. + OUT gctPHYS_ADDR * Physical,
  164829. + OUT gctPOINTER * Logical
  164830. + )
  164831. +{
  164832. + gceSTATUS status;
  164833. +
  164834. + gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
  164835. + Os, InUserSpace, gcmOPT_VALUE(Bytes));
  164836. +
  164837. + /* Verify the arguments. */
  164838. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164839. + gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
  164840. + gcmkVERIFY_ARGUMENT(*Bytes > 0);
  164841. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164842. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164843. +
  164844. + /* Same as non-paged memory for now. */
  164845. + gcmkONERROR(gckOS_AllocateNonPagedMemory(Os,
  164846. + InUserSpace,
  164847. + Bytes,
  164848. + Physical,
  164849. + Logical));
  164850. +
  164851. + /* Success. */
  164852. + gcmkFOOTER_ARG("*Bytes=%lu *Physical=0x%X *Logical=0x%X",
  164853. + *Bytes, *Physical, *Logical);
  164854. + return gcvSTATUS_OK;
  164855. +
  164856. +OnError:
  164857. + /* Return the status. */
  164858. + gcmkFOOTER();
  164859. + return status;
  164860. +}
  164861. +
  164862. +/*******************************************************************************
  164863. +**
  164864. +** gckOS_FreeContiguous
  164865. +**
  164866. +** Free memory allocated from the contiguous pool.
  164867. +**
  164868. +** INPUT:
  164869. +**
  164870. +** gckOS Os
  164871. +** Pointer to an gckOS object.
  164872. +**
  164873. +** gctPHYS_ADDR Physical
  164874. +** Physical address of the allocation.
  164875. +**
  164876. +** gctPOINTER Logical
  164877. +** Logicval address of the allocation.
  164878. +**
  164879. +** gctSIZE_T Bytes
  164880. +** Number of bytes of the allocation.
  164881. +**
  164882. +** OUTPUT:
  164883. +**
  164884. +** Nothing.
  164885. +*/
  164886. +gceSTATUS
  164887. +gckOS_FreeContiguous(
  164888. + IN gckOS Os,
  164889. + IN gctPHYS_ADDR Physical,
  164890. + IN gctPOINTER Logical,
  164891. + IN gctSIZE_T Bytes
  164892. + )
  164893. +{
  164894. + gceSTATUS status;
  164895. +
  164896. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Logical=0x%X Bytes=%lu",
  164897. + Os, Physical, Logical, Bytes);
  164898. +
  164899. + /* Verify the arguments. */
  164900. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164901. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164902. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164903. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  164904. +
  164905. + /* Same of non-paged memory for now. */
  164906. + gcmkONERROR(gckOS_FreeNonPagedMemory(Os, Bytes, Physical, Logical));
  164907. +
  164908. + /* Success. */
  164909. + gcmkFOOTER_NO();
  164910. + return gcvSTATUS_OK;
  164911. +
  164912. +OnError:
  164913. + /* Return the status. */
  164914. + gcmkFOOTER();
  164915. + return status;
  164916. +}
  164917. +
  164918. +#if gcdENABLE_VG
  164919. +/******************************************************************************
  164920. +**
  164921. +** gckOS_GetKernelLogical
  164922. +**
  164923. +** Return the kernel logical pointer that corresponods to the specified
  164924. +** hardware address.
  164925. +**
  164926. +** INPUT:
  164927. +**
  164928. +** gckOS Os
  164929. +** Pointer to an gckOS object.
  164930. +**
  164931. +** gctUINT32 Address
  164932. +** Hardware physical address.
  164933. +**
  164934. +** OUTPUT:
  164935. +**
  164936. +** gctPOINTER * KernelPointer
  164937. +** Pointer to a variable receiving the pointer in kernel address space.
  164938. +*/
  164939. +gceSTATUS
  164940. +gckOS_GetKernelLogical(
  164941. + IN gckOS Os,
  164942. + IN gctUINT32 Address,
  164943. + OUT gctPOINTER * KernelPointer
  164944. + )
  164945. +{
  164946. + return gckOS_GetKernelLogicalEx(Os, gcvCORE_MAJOR, Address, KernelPointer);
  164947. +}
  164948. +
  164949. +gceSTATUS
  164950. +gckOS_GetKernelLogicalEx(
  164951. + IN gckOS Os,
  164952. + IN gceCORE Core,
  164953. + IN gctUINT32 Address,
  164954. + OUT gctPOINTER * KernelPointer
  164955. + )
  164956. +{
  164957. + gceSTATUS status;
  164958. +
  164959. + gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%08x", Os, Core, Address);
  164960. +
  164961. + do
  164962. + {
  164963. + gckGALDEVICE device;
  164964. + gckKERNEL kernel;
  164965. + gcePOOL pool;
  164966. + gctUINT32 offset;
  164967. + gctPOINTER logical;
  164968. +
  164969. + /* Extract the pointer to the gckGALDEVICE class. */
  164970. + device = (gckGALDEVICE) Os->device;
  164971. +
  164972. + /* Kernel shortcut. */
  164973. + kernel = device->kernels[Core];
  164974. +#if gcdENABLE_VG
  164975. + if (Core == gcvCORE_VG)
  164976. + {
  164977. + gcmkERR_BREAK(gckVGHARDWARE_SplitMemory(
  164978. + kernel->vg->hardware, Address, &pool, &offset
  164979. + ));
  164980. + }
  164981. + else
  164982. +#endif
  164983. + {
  164984. + /* Split the memory address into a pool type and offset. */
  164985. + gcmkERR_BREAK(gckHARDWARE_SplitMemory(
  164986. + kernel->hardware, Address, &pool, &offset
  164987. + ));
  164988. + }
  164989. +
  164990. + /* Dispatch on pool. */
  164991. + switch (pool)
  164992. + {
  164993. + case gcvPOOL_LOCAL_INTERNAL:
  164994. + /* Internal memory. */
  164995. + logical = device->internalLogical;
  164996. + break;
  164997. +
  164998. + case gcvPOOL_LOCAL_EXTERNAL:
  164999. + /* External memory. */
  165000. + logical = device->externalLogical;
  165001. + break;
  165002. +
  165003. + case gcvPOOL_SYSTEM:
  165004. + /* System memory. */
  165005. + logical = device->contiguousBase;
  165006. + break;
  165007. +
  165008. + default:
  165009. + /* Invalid memory pool. */
  165010. + gcmkFOOTER();
  165011. + return gcvSTATUS_INVALID_ARGUMENT;
  165012. + }
  165013. +
  165014. + /* Build logical address of specified address. */
  165015. + * KernelPointer = ((gctUINT8_PTR) logical) + offset;
  165016. +
  165017. + /* Success. */
  165018. + gcmkFOOTER_ARG("*KernelPointer=0x%X", *KernelPointer);
  165019. + return gcvSTATUS_OK;
  165020. + }
  165021. + while (gcvFALSE);
  165022. +
  165023. + /* Return status. */
  165024. + gcmkFOOTER();
  165025. + return status;
  165026. +}
  165027. +#endif
  165028. +
  165029. +/*******************************************************************************
  165030. +**
  165031. +** gckOS_MapUserPointer
  165032. +**
  165033. +** Map a pointer from the user process into the kernel address space.
  165034. +**
  165035. +** INPUT:
  165036. +**
  165037. +** gckOS Os
  165038. +** Pointer to an gckOS object.
  165039. +**
  165040. +** gctPOINTER Pointer
  165041. +** Pointer in user process space that needs to be mapped.
  165042. +**
  165043. +** gctSIZE_T Size
  165044. +** Number of bytes that need to be mapped.
  165045. +**
  165046. +** OUTPUT:
  165047. +**
  165048. +** gctPOINTER * KernelPointer
  165049. +** Pointer to a variable receiving the mapped pointer in kernel address
  165050. +** space.
  165051. +*/
  165052. +gceSTATUS
  165053. +gckOS_MapUserPointer(
  165054. + IN gckOS Os,
  165055. + IN gctPOINTER Pointer,
  165056. + IN gctSIZE_T Size,
  165057. + OUT gctPOINTER * KernelPointer
  165058. + )
  165059. +{
  165060. + gctPOINTER buf = gcvNULL;
  165061. + gctUINT32 len;
  165062. +
  165063. + gcmkHEADER_ARG("Os=0x%X Pointer=0x%X Size=%lu", Os, Pointer, Size);
  165064. +
  165065. + /* Verify the arguments. */
  165066. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165067. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  165068. + gcmkVERIFY_ARGUMENT(Size > 0);
  165069. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  165070. +
  165071. + buf = kmalloc(Size, GFP_KERNEL | gcdNOWARN);
  165072. + if (buf == gcvNULL)
  165073. + {
  165074. + gcmkTRACE(
  165075. + gcvLEVEL_ERROR,
  165076. + "%s(%d): Failed to allocate memory.",
  165077. + __FUNCTION__, __LINE__
  165078. + );
  165079. +
  165080. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  165081. + return gcvSTATUS_OUT_OF_MEMORY;
  165082. + }
  165083. +
  165084. + len = copy_from_user(buf, Pointer, Size);
  165085. + if (len != 0)
  165086. + {
  165087. + gcmkTRACE(
  165088. + gcvLEVEL_ERROR,
  165089. + "%s(%d): Failed to copy data from user.",
  165090. + __FUNCTION__, __LINE__
  165091. + );
  165092. +
  165093. + if (buf != gcvNULL)
  165094. + {
  165095. + kfree(buf);
  165096. + }
  165097. +
  165098. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_GENERIC_IO);
  165099. + return gcvSTATUS_GENERIC_IO;
  165100. + }
  165101. +
  165102. + *KernelPointer = buf;
  165103. +
  165104. + gcmkFOOTER_ARG("*KernelPointer=0x%X", *KernelPointer);
  165105. + return gcvSTATUS_OK;
  165106. +}
  165107. +
  165108. +/*******************************************************************************
  165109. +**
  165110. +** gckOS_UnmapUserPointer
  165111. +**
  165112. +** Unmap a user process pointer from the kernel address space.
  165113. +**
  165114. +** INPUT:
  165115. +**
  165116. +** gckOS Os
  165117. +** Pointer to an gckOS object.
  165118. +**
  165119. +** gctPOINTER Pointer
  165120. +** Pointer in user process space that needs to be unmapped.
  165121. +**
  165122. +** gctSIZE_T Size
  165123. +** Number of bytes that need to be unmapped.
  165124. +**
  165125. +** gctPOINTER KernelPointer
  165126. +** Pointer in kernel address space that needs to be unmapped.
  165127. +**
  165128. +** OUTPUT:
  165129. +**
  165130. +** Nothing.
  165131. +*/
  165132. +gceSTATUS
  165133. +gckOS_UnmapUserPointer(
  165134. + IN gckOS Os,
  165135. + IN gctPOINTER Pointer,
  165136. + IN gctSIZE_T Size,
  165137. + IN gctPOINTER KernelPointer
  165138. + )
  165139. +{
  165140. + gctUINT32 len;
  165141. +
  165142. + gcmkHEADER_ARG("Os=0x%X Pointer=0x%X Size=%lu KernelPointer=0x%X",
  165143. + Os, Pointer, Size, KernelPointer);
  165144. +
  165145. +
  165146. + /* Verify the arguments. */
  165147. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165148. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  165149. + gcmkVERIFY_ARGUMENT(Size > 0);
  165150. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  165151. +
  165152. + len = copy_to_user(Pointer, KernelPointer, Size);
  165153. +
  165154. + kfree(KernelPointer);
  165155. +
  165156. + if (len != 0)
  165157. + {
  165158. + gcmkTRACE(
  165159. + gcvLEVEL_ERROR,
  165160. + "%s(%d): Failed to copy data to user.",
  165161. + __FUNCTION__, __LINE__
  165162. + );
  165163. +
  165164. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
  165165. + return gcvSTATUS_GENERIC_IO;
  165166. + }
  165167. +
  165168. + gcmkFOOTER_NO();
  165169. + return gcvSTATUS_OK;
  165170. +}
  165171. +
  165172. +/*******************************************************************************
  165173. +**
  165174. +** gckOS_QueryNeedCopy
  165175. +**
  165176. +** Query whether the memory can be accessed or mapped directly or it has to be
  165177. +** copied.
  165178. +**
  165179. +** INPUT:
  165180. +**
  165181. +** gckOS Os
  165182. +** Pointer to an gckOS object.
  165183. +**
  165184. +** gctUINT32 ProcessID
  165185. +** Process ID of the current process.
  165186. +**
  165187. +** OUTPUT:
  165188. +**
  165189. +** gctBOOL_PTR NeedCopy
  165190. +** Pointer to a boolean receiving gcvTRUE if the memory needs a copy or
  165191. +** gcvFALSE if the memory can be accessed or mapped dircetly.
  165192. +*/
  165193. +gceSTATUS
  165194. +gckOS_QueryNeedCopy(
  165195. + IN gckOS Os,
  165196. + IN gctUINT32 ProcessID,
  165197. + OUT gctBOOL_PTR NeedCopy
  165198. + )
  165199. +{
  165200. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d", Os, ProcessID);
  165201. +
  165202. + /* Verify the arguments. */
  165203. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165204. + gcmkVERIFY_ARGUMENT(NeedCopy != gcvNULL);
  165205. +
  165206. + /* We need to copy data. */
  165207. + *NeedCopy = gcvTRUE;
  165208. +
  165209. + /* Success. */
  165210. + gcmkFOOTER_ARG("*NeedCopy=%d", *NeedCopy);
  165211. + return gcvSTATUS_OK;
  165212. +}
  165213. +
  165214. +/*******************************************************************************
  165215. +**
  165216. +** gckOS_CopyFromUserData
  165217. +**
  165218. +** Copy data from user to kernel memory.
  165219. +**
  165220. +** INPUT:
  165221. +**
  165222. +** gckOS Os
  165223. +** Pointer to an gckOS object.
  165224. +**
  165225. +** gctPOINTER KernelPointer
  165226. +** Pointer to kernel memory.
  165227. +**
  165228. +** gctPOINTER Pointer
  165229. +** Pointer to user memory.
  165230. +**
  165231. +** gctSIZE_T Size
  165232. +** Number of bytes to copy.
  165233. +**
  165234. +** OUTPUT:
  165235. +**
  165236. +** Nothing.
  165237. +*/
  165238. +gceSTATUS
  165239. +gckOS_CopyFromUserData(
  165240. + IN gckOS Os,
  165241. + IN gctPOINTER KernelPointer,
  165242. + IN gctPOINTER Pointer,
  165243. + IN gctSIZE_T Size
  165244. + )
  165245. +{
  165246. + gceSTATUS status;
  165247. +
  165248. + gcmkHEADER_ARG("Os=0x%X KernelPointer=0x%X Pointer=0x%X Size=%lu",
  165249. + Os, KernelPointer, Pointer, Size);
  165250. +
  165251. + /* Verify the arguments. */
  165252. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165253. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  165254. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  165255. + gcmkVERIFY_ARGUMENT(Size > 0);
  165256. +
  165257. + /* Copy data from user. */
  165258. + if (copy_from_user(KernelPointer, Pointer, Size) != 0)
  165259. + {
  165260. + /* Could not copy all the bytes. */
  165261. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  165262. + }
  165263. +
  165264. + /* Success. */
  165265. + gcmkFOOTER_NO();
  165266. + return gcvSTATUS_OK;
  165267. +
  165268. +OnError:
  165269. + /* Return the status. */
  165270. + gcmkFOOTER();
  165271. + return status;
  165272. +}
  165273. +
  165274. +/*******************************************************************************
  165275. +**
  165276. +** gckOS_CopyToUserData
  165277. +**
  165278. +** Copy data from kernel to user memory.
  165279. +**
  165280. +** INPUT:
  165281. +**
  165282. +** gckOS Os
  165283. +** Pointer to an gckOS object.
  165284. +**
  165285. +** gctPOINTER KernelPointer
  165286. +** Pointer to kernel memory.
  165287. +**
  165288. +** gctPOINTER Pointer
  165289. +** Pointer to user memory.
  165290. +**
  165291. +** gctSIZE_T Size
  165292. +** Number of bytes to copy.
  165293. +**
  165294. +** OUTPUT:
  165295. +**
  165296. +** Nothing.
  165297. +*/
  165298. +gceSTATUS
  165299. +gckOS_CopyToUserData(
  165300. + IN gckOS Os,
  165301. + IN gctPOINTER KernelPointer,
  165302. + IN gctPOINTER Pointer,
  165303. + IN gctSIZE_T Size
  165304. + )
  165305. +{
  165306. + gceSTATUS status;
  165307. +
  165308. + gcmkHEADER_ARG("Os=0x%X KernelPointer=0x%X Pointer=0x%X Size=%lu",
  165309. + Os, KernelPointer, Pointer, Size);
  165310. +
  165311. + /* Verify the arguments. */
  165312. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165313. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  165314. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  165315. + gcmkVERIFY_ARGUMENT(Size > 0);
  165316. +
  165317. + /* Copy data to user. */
  165318. + if (copy_to_user(Pointer, KernelPointer, Size) != 0)
  165319. + {
  165320. + /* Could not copy all the bytes. */
  165321. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  165322. + }
  165323. +
  165324. + /* Success. */
  165325. + gcmkFOOTER_NO();
  165326. + return gcvSTATUS_OK;
  165327. +
  165328. +OnError:
  165329. + /* Return the status. */
  165330. + gcmkFOOTER();
  165331. + return status;
  165332. +}
  165333. +
  165334. +/*******************************************************************************
  165335. +**
  165336. +** gckOS_WriteMemory
  165337. +**
  165338. +** Write data to a memory.
  165339. +**
  165340. +** INPUT:
  165341. +**
  165342. +** gckOS Os
  165343. +** Pointer to an gckOS object.
  165344. +**
  165345. +** gctPOINTER Address
  165346. +** Address of the memory to write to.
  165347. +**
  165348. +** gctUINT32 Data
  165349. +** Data for register.
  165350. +**
  165351. +** OUTPUT:
  165352. +**
  165353. +** Nothing.
  165354. +*/
  165355. +gceSTATUS
  165356. +gckOS_WriteMemory(
  165357. + IN gckOS Os,
  165358. + IN gctPOINTER Address,
  165359. + IN gctUINT32 Data
  165360. + )
  165361. +{
  165362. + gceSTATUS status;
  165363. + gcmkHEADER_ARG("Os=0x%X Address=0x%X Data=%u", Os, Address, Data);
  165364. +
  165365. + /* Verify the arguments. */
  165366. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  165367. +
  165368. + /* Write memory. */
  165369. + if (access_ok(VERIFY_WRITE, Address, 4))
  165370. + {
  165371. + /* User address. */
  165372. + if(put_user(Data, (gctUINT32*)Address))
  165373. + {
  165374. + gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
  165375. + }
  165376. + }
  165377. + else
  165378. + {
  165379. + /* Kernel address. */
  165380. + *(gctUINT32 *)Address = Data;
  165381. + }
  165382. +
  165383. + /* Success. */
  165384. + gcmkFOOTER_NO();
  165385. + return gcvSTATUS_OK;
  165386. +
  165387. +OnError:
  165388. + gcmkFOOTER();
  165389. + return status;
  165390. +}
  165391. +
  165392. +/*******************************************************************************
  165393. +**
  165394. +** gckOS_MapUserMemory
  165395. +**
  165396. +** Lock down a user buffer and return an DMA'able address to be used by the
  165397. +** hardware to access it.
  165398. +**
  165399. +** INPUT:
  165400. +**
  165401. +** gctPOINTER Memory
  165402. +** Pointer to memory to lock down.
  165403. +**
  165404. +** gctSIZE_T Size
  165405. +** Size in bytes of the memory to lock down.
  165406. +**
  165407. +** OUTPUT:
  165408. +**
  165409. +** gctPOINTER * Info
  165410. +** Pointer to variable receiving the information record required by
  165411. +** gckOS_UnmapUserMemory.
  165412. +**
  165413. +** gctUINT32_PTR Address
  165414. +** Pointer to a variable that will receive the address DMA'able by the
  165415. +** hardware.
  165416. +*/
  165417. +gceSTATUS
  165418. +gckOS_MapUserMemory(
  165419. + IN gckOS Os,
  165420. + IN gceCORE Core,
  165421. + IN gctPOINTER Memory,
  165422. + IN gctUINT32 Physical,
  165423. + IN gctSIZE_T Size,
  165424. + OUT gctPOINTER * Info,
  165425. + OUT gctUINT32_PTR Address
  165426. + )
  165427. +{
  165428. + gceSTATUS status;
  165429. +
  165430. + gcmkHEADER_ARG("Os=0x%x Core=%d Memory=0x%x Size=%lu", Os, Core, Memory, Size);
  165431. +
  165432. +#if gcdSECURE_USER
  165433. + gcmkONERROR(gckOS_AddMapping(Os, *Address, Memory, Size));
  165434. +
  165435. + gcmkFOOTER_NO();
  165436. + return gcvSTATUS_OK;
  165437. +
  165438. +OnError:
  165439. + gcmkFOOTER();
  165440. + return status;
  165441. +#else
  165442. +{
  165443. + gctSIZE_T pageCount, i, j;
  165444. + gctUINT32_PTR pageTable;
  165445. + gctUINT32 address = 0, physical = ~0U;
  165446. + gctUINTPTR_T start, end, memory;
  165447. + gctUINT32 offset;
  165448. + gctINT result = 0;
  165449. +
  165450. + gcsPageInfo_PTR info = gcvNULL;
  165451. + struct page **pages = gcvNULL;
  165452. +
  165453. + /* Verify the arguments. */
  165454. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165455. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL || Physical != ~0U);
  165456. + gcmkVERIFY_ARGUMENT(Size > 0);
  165457. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  165458. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  165459. +
  165460. + do
  165461. + {
  165462. + memory = (gctUINTPTR_T) Memory;
  165463. +
  165464. + /* Get the number of required pages. */
  165465. + end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  165466. + start = memory >> PAGE_SHIFT;
  165467. + pageCount = end - start;
  165468. +
  165469. + gcmkTRACE_ZONE(
  165470. + gcvLEVEL_INFO, gcvZONE_OS,
  165471. + "%s(%d): pageCount: %d.",
  165472. + __FUNCTION__, __LINE__,
  165473. + pageCount
  165474. + );
  165475. +
  165476. + /* Overflow. */
  165477. + if ((memory + Size) < memory)
  165478. + {
  165479. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  165480. + return gcvSTATUS_INVALID_ARGUMENT;
  165481. + }
  165482. +
  165483. + MEMORY_MAP_LOCK(Os);
  165484. +
  165485. + /* Allocate the Info struct. */
  165486. + info = (gcsPageInfo_PTR)kmalloc(sizeof(gcsPageInfo), GFP_KERNEL | gcdNOWARN);
  165487. +
  165488. + if (info == gcvNULL)
  165489. + {
  165490. + status = gcvSTATUS_OUT_OF_MEMORY;
  165491. + break;
  165492. + }
  165493. +
  165494. + /* Allocate the array of page addresses. */
  165495. + pages = (struct page **)kmalloc(pageCount * sizeof(struct page *), GFP_KERNEL | gcdNOWARN);
  165496. +
  165497. + if (pages == gcvNULL)
  165498. + {
  165499. + status = gcvSTATUS_OUT_OF_MEMORY;
  165500. + break;
  165501. + }
  165502. +
  165503. + if (Physical != ~0U)
  165504. + {
  165505. + for (i = 0; i < pageCount; i++)
  165506. + {
  165507. + pages[i] = pfn_to_page((Physical >> PAGE_SHIFT) + i);
  165508. + get_page(pages[i]);
  165509. + }
  165510. + }
  165511. + else
  165512. + {
  165513. + /* Get the user pages. */
  165514. + down_read(&current->mm->mmap_sem);
  165515. +
  165516. + result = get_user_pages(current,
  165517. + current->mm,
  165518. + memory & PAGE_MASK,
  165519. + pageCount,
  165520. + 1,
  165521. + 0,
  165522. + pages,
  165523. + gcvNULL
  165524. + );
  165525. +
  165526. + up_read(&current->mm->mmap_sem);
  165527. +
  165528. + if (result <=0 || result < pageCount)
  165529. + {
  165530. + struct vm_area_struct *vma;
  165531. +
  165532. + /* Release the pages if any. */
  165533. + if (result > 0)
  165534. + {
  165535. + for (i = 0; i < result; i++)
  165536. + {
  165537. + if (pages[i] == gcvNULL)
  165538. + {
  165539. + break;
  165540. + }
  165541. +
  165542. + page_cache_release(pages[i]);
  165543. + pages[i] = gcvNULL;
  165544. + }
  165545. +
  165546. + result = 0;
  165547. + }
  165548. +
  165549. + vma = find_vma(current->mm, memory);
  165550. +
  165551. + if (vma && (vma->vm_flags & VM_PFNMAP))
  165552. + {
  165553. + pte_t * pte;
  165554. + spinlock_t * ptl;
  165555. + gctUINTPTR_T logical = memory;
  165556. +
  165557. + for (i = 0; i < pageCount; i++)
  165558. + {
  165559. + pgd_t * pgd = pgd_offset(current->mm, logical);
  165560. + pud_t * pud = pud_offset(pgd, logical);
  165561. +
  165562. + if (pud)
  165563. + {
  165564. + pmd_t * pmd = pmd_offset(pud, logical);
  165565. + pte = pte_offset_map_lock(current->mm, pmd, logical, &ptl);
  165566. + if (!pte)
  165567. + {
  165568. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  165569. + }
  165570. + }
  165571. + else
  165572. + {
  165573. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  165574. + }
  165575. +
  165576. + pages[i] = pte_page(*pte);
  165577. + pte_unmap_unlock(pte, ptl);
  165578. +
  165579. + /* Advance to next. */
  165580. + logical += PAGE_SIZE;
  165581. + }
  165582. + }
  165583. + else
  165584. + {
  165585. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  165586. + }
  165587. +
  165588. + /* Check if this memory is contiguous for old mmu. */
  165589. + if (Os->device->kernels[Core]->hardware->mmuVersion == 0)
  165590. + {
  165591. + for (i = 1; i < pageCount; i++)
  165592. + {
  165593. + if (pages[i] != nth_page(pages[0], i))
  165594. + {
  165595. + /* Non-contiguous. */
  165596. + break;
  165597. + }
  165598. + }
  165599. +
  165600. + if (i == pageCount)
  165601. + {
  165602. + /* Contiguous memory. */
  165603. + physical = page_to_phys(pages[0]) | (memory & ~PAGE_MASK);
  165604. +
  165605. + if (!((physical - Os->device->baseAddress) & 0x80000000))
  165606. + {
  165607. + kfree(pages);
  165608. + pages = gcvNULL;
  165609. +
  165610. + info->pages = gcvNULL;
  165611. + info->pageTable = gcvNULL;
  165612. +
  165613. + MEMORY_MAP_UNLOCK(Os);
  165614. +
  165615. + *Address = physical - Os->device->baseAddress;
  165616. + *Info = info;
  165617. +
  165618. + gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x",
  165619. + *Info, *Address);
  165620. +
  165621. + return gcvSTATUS_OK;
  165622. + }
  165623. + }
  165624. + }
  165625. +
  165626. + /* Reference pages. */
  165627. + for (i = 0; i < pageCount; i++)
  165628. + {
  165629. + get_page(pages[i]);
  165630. + }
  165631. + }
  165632. + }
  165633. +
  165634. + for (i = 0; i < pageCount; i++)
  165635. + {
  165636. +#ifdef CONFIG_ARM
  165637. + gctUINT32 data;
  165638. + get_user(data, (gctUINT32*)((memory & PAGE_MASK) + i * PAGE_SIZE));
  165639. +#endif
  165640. +
  165641. + /* Flush(clean) the data cache. */
  165642. + gcmkONERROR(gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
  165643. + (gctPOINTER)(gctUINTPTR_T)page_to_phys(pages[i]),
  165644. + (gctPOINTER)(memory & PAGE_MASK) + i*PAGE_SIZE,
  165645. + PAGE_SIZE));
  165646. + }
  165647. +
  165648. +#if gcdENABLE_VG
  165649. + if (Core == gcvCORE_VG)
  165650. + {
  165651. + /* Allocate pages inside the page table. */
  165652. + gcmkERR_BREAK(gckVGMMU_AllocatePages(Os->device->kernels[Core]->vg->mmu,
  165653. + pageCount * (PAGE_SIZE/4096),
  165654. + (gctPOINTER *) &pageTable,
  165655. + &address));
  165656. + }
  165657. + else
  165658. +#endif
  165659. + {
  165660. + /* Allocate pages inside the page table. */
  165661. + gcmkERR_BREAK(gckMMU_AllocatePages(Os->device->kernels[Core]->mmu,
  165662. + pageCount * (PAGE_SIZE/4096),
  165663. + (gctPOINTER *) &pageTable,
  165664. + &address));
  165665. + }
  165666. +
  165667. + /* Fill the page table. */
  165668. + for (i = 0; i < pageCount; i++)
  165669. + {
  165670. + gctUINT32 phys;
  165671. + gctUINT32_PTR tab = pageTable + i * (PAGE_SIZE/4096);
  165672. +
  165673. + phys = page_to_phys(pages[i]);
  165674. +
  165675. +#if gcdENABLE_VG
  165676. + if (Core == gcvCORE_VG)
  165677. + {
  165678. + /* Get the physical address from page struct. */
  165679. + gcmkONERROR(
  165680. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  165681. + phys,
  165682. + tab));
  165683. + }
  165684. + else
  165685. +#endif
  165686. + {
  165687. + /* Get the physical address from page struct. */
  165688. + gcmkONERROR(
  165689. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  165690. + phys,
  165691. + tab));
  165692. + }
  165693. +
  165694. + for (j = 1; j < (PAGE_SIZE/4096); j++)
  165695. + {
  165696. + pageTable[i * (PAGE_SIZE/4096) + j] = pageTable[i * (PAGE_SIZE/4096)] + 4096 * j;
  165697. + }
  165698. +
  165699. + gcmkTRACE_ZONE(
  165700. + gcvLEVEL_INFO, gcvZONE_OS,
  165701. + "%s(%d): pageTable[%d]: 0x%X 0x%X.",
  165702. + __FUNCTION__, __LINE__,
  165703. + i, phys, pageTable[i]);
  165704. + }
  165705. +
  165706. +#if gcdENABLE_VG
  165707. + if (Core == gcvCORE_VG)
  165708. + {
  165709. + gcmkONERROR(gckVGMMU_Flush(Os->device->kernels[Core]->vg->mmu));
  165710. + }
  165711. + else
  165712. +#endif
  165713. + {
  165714. + gcmkONERROR(gckMMU_Flush(Os->device->kernels[Core]->mmu));
  165715. + }
  165716. +
  165717. + /* Save pointer to page table. */
  165718. + info->pageTable = pageTable;
  165719. + info->pages = pages;
  165720. +
  165721. + *Info = (gctPOINTER) info;
  165722. +
  165723. + gcmkTRACE_ZONE(
  165724. + gcvLEVEL_INFO, gcvZONE_OS,
  165725. + "%s(%d): info->pages: 0x%X, info->pageTable: 0x%X, info: 0x%X.",
  165726. + __FUNCTION__, __LINE__,
  165727. + info->pages,
  165728. + info->pageTable,
  165729. + info
  165730. + );
  165731. +
  165732. + offset = (Physical != ~0U)
  165733. + ? (Physical & ~PAGE_MASK)
  165734. + : (memory & ~PAGE_MASK);
  165735. +
  165736. + /* Return address. */
  165737. + *Address = address + offset;
  165738. +
  165739. + gcmkTRACE_ZONE(
  165740. + gcvLEVEL_INFO, gcvZONE_OS,
  165741. + "%s(%d): Address: 0x%X.",
  165742. + __FUNCTION__, __LINE__,
  165743. + *Address
  165744. + );
  165745. +
  165746. + /* Success. */
  165747. + status = gcvSTATUS_OK;
  165748. + }
  165749. + while (gcvFALSE);
  165750. +
  165751. +OnError:
  165752. +
  165753. + if (gcmIS_ERROR(status))
  165754. + {
  165755. + gcmkTRACE(
  165756. + gcvLEVEL_ERROR,
  165757. + "%s(%d): error occured: %d.",
  165758. + __FUNCTION__, __LINE__,
  165759. + status
  165760. + );
  165761. +
  165762. + /* Release page array. */
  165763. + if (result > 0 && pages != gcvNULL)
  165764. + {
  165765. + gcmkTRACE(
  165766. + gcvLEVEL_ERROR,
  165767. + "%s(%d): error: page table is freed.",
  165768. + __FUNCTION__, __LINE__
  165769. + );
  165770. +
  165771. + for (i = 0; i < result; i++)
  165772. + {
  165773. + if (pages[i] == gcvNULL)
  165774. + {
  165775. + break;
  165776. + }
  165777. + page_cache_release(pages[i]);
  165778. + }
  165779. + }
  165780. +
  165781. + if (info!= gcvNULL && pages != gcvNULL)
  165782. + {
  165783. + gcmkTRACE(
  165784. + gcvLEVEL_ERROR,
  165785. + "%s(%d): error: pages is freed.",
  165786. + __FUNCTION__, __LINE__
  165787. + );
  165788. +
  165789. + /* Free the page table. */
  165790. + kfree(pages);
  165791. + info->pages = gcvNULL;
  165792. + }
  165793. +
  165794. + /* Release page info struct. */
  165795. + if (info != gcvNULL)
  165796. + {
  165797. + gcmkTRACE(
  165798. + gcvLEVEL_ERROR,
  165799. + "%s(%d): error: info is freed.",
  165800. + __FUNCTION__, __LINE__
  165801. + );
  165802. +
  165803. + /* Free the page info struct. */
  165804. + kfree(info);
  165805. + *Info = gcvNULL;
  165806. + }
  165807. + }
  165808. +
  165809. + MEMORY_MAP_UNLOCK(Os);
  165810. +
  165811. + /* Return the status. */
  165812. + if (gcmIS_SUCCESS(status))
  165813. + {
  165814. + gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x", *Info, *Address);
  165815. + }
  165816. + else
  165817. + {
  165818. + gcmkFOOTER();
  165819. + }
  165820. +
  165821. + return status;
  165822. +}
  165823. +#endif
  165824. +}
  165825. +
  165826. +/*******************************************************************************
  165827. +**
  165828. +** gckOS_UnmapUserMemory
  165829. +**
  165830. +** Unlock a user buffer and that was previously locked down by
  165831. +** gckOS_MapUserMemory.
  165832. +**
  165833. +** INPUT:
  165834. +**
  165835. +** gctPOINTER Memory
  165836. +** Pointer to memory to unlock.
  165837. +**
  165838. +** gctSIZE_T Size
  165839. +** Size in bytes of the memory to unlock.
  165840. +**
  165841. +** gctPOINTER Info
  165842. +** Information record returned by gckOS_MapUserMemory.
  165843. +**
  165844. +** gctUINT32_PTR Address
  165845. +** The address returned by gckOS_MapUserMemory.
  165846. +**
  165847. +** OUTPUT:
  165848. +**
  165849. +** Nothing.
  165850. +*/
  165851. +gceSTATUS
  165852. +gckOS_UnmapUserMemory(
  165853. + IN gckOS Os,
  165854. + IN gceCORE Core,
  165855. + IN gctPOINTER Memory,
  165856. + IN gctSIZE_T Size,
  165857. + IN gctPOINTER Info,
  165858. + IN gctUINT32 Address
  165859. + )
  165860. +{
  165861. + gceSTATUS status;
  165862. +
  165863. + gcmkHEADER_ARG("Os=0x%X Core=%d Memory=0x%X Size=%lu Info=0x%X Address0x%08x",
  165864. + Os, Core, Memory, Size, Info, Address);
  165865. +
  165866. +#if gcdSECURE_USER
  165867. + gcmkONERROR(gckOS_RemoveMapping(Os, Memory, Size));
  165868. +
  165869. + gcmkFOOTER_NO();
  165870. + return gcvSTATUS_OK;
  165871. +
  165872. +OnError:
  165873. + gcmkFOOTER();
  165874. + return status;
  165875. +#else
  165876. +{
  165877. + gctUINTPTR_T memory, start, end;
  165878. + gcsPageInfo_PTR info;
  165879. + gctSIZE_T pageCount, i;
  165880. + struct page **pages;
  165881. +
  165882. + /* Verify the arguments. */
  165883. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165884. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  165885. + gcmkVERIFY_ARGUMENT(Size > 0);
  165886. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  165887. +
  165888. + do
  165889. + {
  165890. + info = (gcsPageInfo_PTR) Info;
  165891. +
  165892. + pages = info->pages;
  165893. +
  165894. + gcmkTRACE_ZONE(
  165895. + gcvLEVEL_INFO, gcvZONE_OS,
  165896. + "%s(%d): info=0x%X, pages=0x%X.",
  165897. + __FUNCTION__, __LINE__,
  165898. + info, pages
  165899. + );
  165900. +
  165901. + /* Invalid page array. */
  165902. + if (pages == gcvNULL && info->pageTable == gcvNULL)
  165903. + {
  165904. + kfree(info);
  165905. +
  165906. + gcmkFOOTER_NO();
  165907. + return gcvSTATUS_OK;
  165908. + }
  165909. +
  165910. + memory = (gctUINTPTR_T)Memory;
  165911. + end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  165912. + start = memory >> PAGE_SHIFT;
  165913. + pageCount = end - start;
  165914. +
  165915. + /* Overflow. */
  165916. + if ((memory + Size) < memory)
  165917. + {
  165918. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  165919. + return gcvSTATUS_INVALID_ARGUMENT;
  165920. + }
  165921. +
  165922. + gcmkTRACE_ZONE(
  165923. + gcvLEVEL_INFO, gcvZONE_OS,
  165924. + "%s(%d): memory: 0x%X, pageCount: %d, pageTable: 0x%X.",
  165925. + __FUNCTION__, __LINE__,
  165926. + memory, pageCount, info->pageTable
  165927. + );
  165928. +
  165929. + MEMORY_MAP_LOCK(Os);
  165930. +
  165931. + gcmkASSERT(info->pageTable != gcvNULL);
  165932. +
  165933. +#if gcdENABLE_VG
  165934. + if (Core == gcvCORE_VG)
  165935. + {
  165936. + /* Free the pages from the MMU. */
  165937. + gcmkERR_BREAK(gckVGMMU_FreePages(Os->device->kernels[Core]->vg->mmu,
  165938. + info->pageTable,
  165939. + pageCount * (PAGE_SIZE/4096)
  165940. + ));
  165941. + }
  165942. + else
  165943. +#endif
  165944. + {
  165945. + /* Free the pages from the MMU. */
  165946. + gcmkERR_BREAK(gckMMU_FreePages(Os->device->kernels[Core]->mmu,
  165947. + info->pageTable,
  165948. + pageCount * (PAGE_SIZE/4096)
  165949. + ));
  165950. + }
  165951. +
  165952. + /* Release the page cache. */
  165953. + if (pages)
  165954. + {
  165955. + for (i = 0; i < pageCount; i++)
  165956. + {
  165957. + gcmkTRACE_ZONE(
  165958. + gcvLEVEL_INFO, gcvZONE_OS,
  165959. + "%s(%d): pages[%d]: 0x%X.",
  165960. + __FUNCTION__, __LINE__,
  165961. + i, pages[i]
  165962. + );
  165963. +
  165964. + if (!PageReserved(pages[i]))
  165965. + {
  165966. + SetPageDirty(pages[i]);
  165967. + }
  165968. +
  165969. + page_cache_release(pages[i]);
  165970. + }
  165971. + }
  165972. +
  165973. + /* Success. */
  165974. + status = gcvSTATUS_OK;
  165975. + }
  165976. + while (gcvFALSE);
  165977. +
  165978. + if (info != gcvNULL)
  165979. + {
  165980. + /* Free the page array. */
  165981. + if (info->pages != gcvNULL)
  165982. + {
  165983. + kfree(info->pages);
  165984. + }
  165985. +
  165986. + kfree(info);
  165987. + }
  165988. +
  165989. + MEMORY_MAP_UNLOCK(Os);
  165990. +
  165991. + /* Return the status. */
  165992. + gcmkFOOTER();
  165993. + return status;
  165994. +}
  165995. +#endif
  165996. +}
  165997. +
  165998. +/*******************************************************************************
  165999. +**
  166000. +** gckOS_GetBaseAddress
  166001. +**
  166002. +** Get the base address for the physical memory.
  166003. +**
  166004. +** INPUT:
  166005. +**
  166006. +** gckOS Os
  166007. +** Pointer to the gckOS object.
  166008. +**
  166009. +** OUTPUT:
  166010. +**
  166011. +** gctUINT32_PTR BaseAddress
  166012. +** Pointer to a variable that will receive the base address.
  166013. +*/
  166014. +gceSTATUS
  166015. +gckOS_GetBaseAddress(
  166016. + IN gckOS Os,
  166017. + OUT gctUINT32_PTR BaseAddress
  166018. + )
  166019. +{
  166020. + gcmkHEADER_ARG("Os=0x%X", Os);
  166021. +
  166022. + /* Verify the arguments. */
  166023. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166024. + gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL);
  166025. +
  166026. + /* Return base address. */
  166027. + *BaseAddress = Os->device->baseAddress;
  166028. +
  166029. + /* Success. */
  166030. + gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
  166031. + return gcvSTATUS_OK;
  166032. +}
  166033. +
  166034. +gceSTATUS
  166035. +gckOS_SuspendInterrupt(
  166036. + IN gckOS Os
  166037. + )
  166038. +{
  166039. + return gckOS_SuspendInterruptEx(Os, gcvCORE_MAJOR);
  166040. +}
  166041. +
  166042. +gceSTATUS
  166043. +gckOS_SuspendInterruptEx(
  166044. + IN gckOS Os,
  166045. + IN gceCORE Core
  166046. + )
  166047. +{
  166048. + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
  166049. +
  166050. + /* Verify the arguments. */
  166051. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166052. +
  166053. + disable_irq(Os->device->irqLines[Core]);
  166054. +
  166055. + gcmkFOOTER_NO();
  166056. + return gcvSTATUS_OK;
  166057. +}
  166058. +
  166059. +gceSTATUS
  166060. +gckOS_ResumeInterrupt(
  166061. + IN gckOS Os
  166062. + )
  166063. +{
  166064. + return gckOS_ResumeInterruptEx(Os, gcvCORE_MAJOR);
  166065. +}
  166066. +
  166067. +gceSTATUS
  166068. +gckOS_ResumeInterruptEx(
  166069. + IN gckOS Os,
  166070. + IN gceCORE Core
  166071. + )
  166072. +{
  166073. + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
  166074. +
  166075. + /* Verify the arguments. */
  166076. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166077. +
  166078. + enable_irq(Os->device->irqLines[Core]);
  166079. +
  166080. + gcmkFOOTER_NO();
  166081. + return gcvSTATUS_OK;
  166082. +}
  166083. +
  166084. +gceSTATUS
  166085. +gckOS_MemCopy(
  166086. + IN gctPOINTER Destination,
  166087. + IN gctCONST_POINTER Source,
  166088. + IN gctSIZE_T Bytes
  166089. + )
  166090. +{
  166091. + gcmkHEADER_ARG("Destination=0x%X Source=0x%X Bytes=%lu",
  166092. + Destination, Source, Bytes);
  166093. +
  166094. + gcmkVERIFY_ARGUMENT(Destination != gcvNULL);
  166095. + gcmkVERIFY_ARGUMENT(Source != gcvNULL);
  166096. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166097. +
  166098. + memcpy(Destination, Source, Bytes);
  166099. +
  166100. + gcmkFOOTER_NO();
  166101. + return gcvSTATUS_OK;
  166102. +}
  166103. +
  166104. +gceSTATUS
  166105. +gckOS_ZeroMemory(
  166106. + IN gctPOINTER Memory,
  166107. + IN gctSIZE_T Bytes
  166108. + )
  166109. +{
  166110. + gcmkHEADER_ARG("Memory=0x%X Bytes=%lu", Memory, Bytes);
  166111. +
  166112. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  166113. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166114. +
  166115. + memset(Memory, 0, Bytes);
  166116. +
  166117. + gcmkFOOTER_NO();
  166118. + return gcvSTATUS_OK;
  166119. +}
  166120. +
  166121. +/*******************************************************************************
  166122. +********************************* Cache Control ********************************
  166123. +*******************************************************************************/
  166124. +
  166125. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED && defined(CONFIG_OUTER_CACHE)
  166126. +static inline gceSTATUS
  166127. +outer_func(
  166128. + gceCACHEOPERATION Type,
  166129. + unsigned long Start,
  166130. + unsigned long End
  166131. + )
  166132. +{
  166133. + switch (Type)
  166134. + {
  166135. + case gcvCACHE_CLEAN:
  166136. + outer_clean_range(Start, End);
  166137. + break;
  166138. + case gcvCACHE_INVALIDATE:
  166139. + outer_inv_range(Start, End);
  166140. + break;
  166141. + case gcvCACHE_FLUSH:
  166142. + outer_flush_range(Start, End);
  166143. + break;
  166144. + default:
  166145. + return gcvSTATUS_INVALID_ARGUMENT;
  166146. + break;
  166147. + }
  166148. + return gcvSTATUS_OK;
  166149. +}
  166150. +
  166151. +#if gcdENABLE_OUTER_CACHE_PATCH
  166152. +/*******************************************************************************
  166153. +** _HandleOuterCache
  166154. +**
  166155. +** Handle the outer cache for the specified addresses.
  166156. +**
  166157. +** ARGUMENTS:
  166158. +**
  166159. +** gckOS Os
  166160. +** Pointer to gckOS object.
  166161. +**
  166162. +** gctUINT32 ProcessID
  166163. +** Process ID Logical belongs.
  166164. +**
  166165. +** gctPHYS_ADDR Handle
  166166. +** Physical address handle. If gcvNULL it is video memory.
  166167. +**
  166168. +** gctPOINTER Physical
  166169. +** Physical address to flush.
  166170. +**
  166171. +** gctPOINTER Logical
  166172. +** Logical address to flush.
  166173. +**
  166174. +** gctSIZE_T Bytes
  166175. +** Size of the address range in bytes to flush.
  166176. +**
  166177. +** gceOUTERCACHE_OPERATION Type
  166178. +** Operation need to be execute.
  166179. +*/
  166180. +static gceSTATUS
  166181. +_HandleOuterCache(
  166182. + IN gckOS Os,
  166183. + IN gctUINT32 ProcessID,
  166184. + IN gctPHYS_ADDR Handle,
  166185. + IN gctPOINTER Physical,
  166186. + IN gctPOINTER Logical,
  166187. + IN gctSIZE_T Bytes,
  166188. + IN gceCACHEOPERATION Type
  166189. + )
  166190. +{
  166191. + gceSTATUS status;
  166192. + gctUINT32 i, pageNum;
  166193. + unsigned long paddr;
  166194. + gctPOINTER vaddr;
  166195. +
  166196. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  166197. + Os, ProcessID, Handle, Logical, Bytes);
  166198. +
  166199. + if (Physical != gcvNULL)
  166200. + {
  166201. + /* Non paged memory or gcvPOOL_USER surface */
  166202. + paddr = (unsigned long) Physical;
  166203. + gcmkONERROR(outer_func(Type, paddr, paddr + Bytes));
  166204. + }
  166205. + else if ((Handle == gcvNULL)
  166206. + || (Handle != gcvNULL && ((PLINUX_MDL)Handle)->contiguous)
  166207. + )
  166208. + {
  166209. + /* Video Memory or contiguous virtual memory */
  166210. + gcmkONERROR(gckOS_GetPhysicalAddress(Os, Logical, (gctUINT32*)&paddr));
  166211. + gcmkONERROR(outer_func(Type, paddr, paddr + Bytes));
  166212. + }
  166213. + else
  166214. + {
  166215. + /* Non contiguous virtual memory */
  166216. + vaddr = (gctPOINTER)gcmALIGN_BASE((gctUINTPTR_T)Logical, PAGE_SIZE);
  166217. + pageNum = GetPageCount(Bytes, 0);
  166218. +
  166219. + for (i = 0; i < pageNum; i += 1)
  166220. + {
  166221. + gcmkONERROR(_ConvertLogical2Physical(
  166222. + Os,
  166223. + vaddr + PAGE_SIZE * i,
  166224. + ProcessID,
  166225. + (PLINUX_MDL)Handle,
  166226. + (gctUINT32*)&paddr
  166227. + ));
  166228. +
  166229. + gcmkONERROR(outer_func(Type, paddr, paddr + PAGE_SIZE));
  166230. + }
  166231. + }
  166232. +
  166233. + mb();
  166234. +
  166235. + /* Success. */
  166236. + gcmkFOOTER_NO();
  166237. + return gcvSTATUS_OK;
  166238. +
  166239. +OnError:
  166240. + /* Return the status. */
  166241. + gcmkFOOTER();
  166242. + return status;
  166243. +}
  166244. +#endif
  166245. +#endif
  166246. +
  166247. +/*******************************************************************************
  166248. +** gckOS_CacheClean
  166249. +**
  166250. +** Clean the cache for the specified addresses. The GPU is going to need the
  166251. +** data. If the system is allocating memory as non-cachable, this function can
  166252. +** be ignored.
  166253. +**
  166254. +** ARGUMENTS:
  166255. +**
  166256. +** gckOS Os
  166257. +** Pointer to gckOS object.
  166258. +**
  166259. +** gctUINT32 ProcessID
  166260. +** Process ID Logical belongs.
  166261. +**
  166262. +** gctPHYS_ADDR Handle
  166263. +** Physical address handle. If gcvNULL it is video memory.
  166264. +**
  166265. +** gctPOINTER Physical
  166266. +** Physical address to flush.
  166267. +**
  166268. +** gctPOINTER Logical
  166269. +** Logical address to flush.
  166270. +**
  166271. +** gctSIZE_T Bytes
  166272. +** Size of the address range in bytes to flush.
  166273. +*/
  166274. +gceSTATUS
  166275. +gckOS_CacheClean(
  166276. + IN gckOS Os,
  166277. + IN gctUINT32 ProcessID,
  166278. + IN gctPHYS_ADDR Handle,
  166279. + IN gctPOINTER Physical,
  166280. + IN gctPOINTER Logical,
  166281. + IN gctSIZE_T Bytes
  166282. + )
  166283. +{
  166284. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  166285. + Os, ProcessID, Handle, Logical, Bytes);
  166286. +
  166287. + /* Verify the arguments. */
  166288. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166289. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  166290. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166291. +
  166292. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
  166293. +#ifdef CONFIG_ARM
  166294. +
  166295. + /* Inner cache. */
  166296. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
  166297. + dmac_map_area(Logical, Bytes, DMA_TO_DEVICE);
  166298. +# else
  166299. + dmac_clean_range(Logical, Logical + Bytes);
  166300. +# endif
  166301. +
  166302. +#if defined(CONFIG_OUTER_CACHE)
  166303. + /* Outer cache. */
  166304. +#if gcdENABLE_OUTER_CACHE_PATCH
  166305. + _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_CLEAN);
  166306. +#else
  166307. + outer_clean_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
  166308. +#endif
  166309. +#endif
  166310. +
  166311. +#elif defined(CONFIG_MIPS)
  166312. +
  166313. + dma_cache_wback((unsigned long) Logical, Bytes);
  166314. +
  166315. +#elif defined(CONFIG_PPC)
  166316. +
  166317. + /* TODO */
  166318. +
  166319. +#else
  166320. + dma_sync_single_for_device(
  166321. + gcvNULL,
  166322. + (dma_addr_t)Physical,
  166323. + Bytes,
  166324. + DMA_TO_DEVICE);
  166325. +#endif
  166326. +#endif
  166327. +
  166328. + /* Success. */
  166329. + gcmkFOOTER_NO();
  166330. + return gcvSTATUS_OK;
  166331. +}
  166332. +
  166333. +/*******************************************************************************
  166334. +** gckOS_CacheInvalidate
  166335. +**
  166336. +** Invalidate the cache for the specified addresses. The GPU is going to need
  166337. +** data. If the system is allocating memory as non-cachable, this function can
  166338. +** be ignored.
  166339. +**
  166340. +** ARGUMENTS:
  166341. +**
  166342. +** gckOS Os
  166343. +** Pointer to gckOS object.
  166344. +**
  166345. +** gctUINT32 ProcessID
  166346. +** Process ID Logical belongs.
  166347. +**
  166348. +** gctPHYS_ADDR Handle
  166349. +** Physical address handle. If gcvNULL it is video memory.
  166350. +**
  166351. +** gctPOINTER Logical
  166352. +** Logical address to flush.
  166353. +**
  166354. +** gctSIZE_T Bytes
  166355. +** Size of the address range in bytes to flush.
  166356. +*/
  166357. +gceSTATUS
  166358. +gckOS_CacheInvalidate(
  166359. + IN gckOS Os,
  166360. + IN gctUINT32 ProcessID,
  166361. + IN gctPHYS_ADDR Handle,
  166362. + IN gctPOINTER Physical,
  166363. + IN gctPOINTER Logical,
  166364. + IN gctSIZE_T Bytes
  166365. + )
  166366. +{
  166367. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  166368. + Os, ProcessID, Handle, Logical, Bytes);
  166369. +
  166370. + /* Verify the arguments. */
  166371. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166372. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  166373. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166374. +
  166375. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
  166376. +#ifdef CONFIG_ARM
  166377. +
  166378. + /* Inner cache. */
  166379. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
  166380. + dmac_map_area(Logical, Bytes, DMA_FROM_DEVICE);
  166381. +# else
  166382. + dmac_inv_range(Logical, Logical + Bytes);
  166383. +# endif
  166384. +
  166385. +#if defined(CONFIG_OUTER_CACHE)
  166386. + /* Outer cache. */
  166387. +#if gcdENABLE_OUTER_CACHE_PATCH
  166388. + _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_INVALIDATE);
  166389. +#else
  166390. + outer_inv_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
  166391. +#endif
  166392. +#endif
  166393. +
  166394. +#elif defined(CONFIG_MIPS)
  166395. + dma_cache_inv((unsigned long) Logical, Bytes);
  166396. +#elif defined(CONFIG_PPC)
  166397. + /* TODO */
  166398. +#else
  166399. + dma_sync_single_for_device(
  166400. + gcvNULL,
  166401. + (dma_addr_t)Physical,
  166402. + Bytes,
  166403. + DMA_FROM_DEVICE);
  166404. +#endif
  166405. +#endif
  166406. +
  166407. + /* Success. */
  166408. + gcmkFOOTER_NO();
  166409. + return gcvSTATUS_OK;
  166410. +}
  166411. +
  166412. +/*******************************************************************************
  166413. +** gckOS_CacheFlush
  166414. +**
  166415. +** Clean the cache for the specified addresses and invalidate the lines as
  166416. +** well. The GPU is going to need and modify the data. If the system is
  166417. +** allocating memory as non-cachable, this function can be ignored.
  166418. +**
  166419. +** ARGUMENTS:
  166420. +**
  166421. +** gckOS Os
  166422. +** Pointer to gckOS object.
  166423. +**
  166424. +** gctUINT32 ProcessID
  166425. +** Process ID Logical belongs.
  166426. +**
  166427. +** gctPHYS_ADDR Handle
  166428. +** Physical address handle. If gcvNULL it is video memory.
  166429. +**
  166430. +** gctPOINTER Logical
  166431. +** Logical address to flush.
  166432. +**
  166433. +** gctSIZE_T Bytes
  166434. +** Size of the address range in bytes to flush.
  166435. +*/
  166436. +gceSTATUS
  166437. +gckOS_CacheFlush(
  166438. + IN gckOS Os,
  166439. + IN gctUINT32 ProcessID,
  166440. + IN gctPHYS_ADDR Handle,
  166441. + IN gctPOINTER Physical,
  166442. + IN gctPOINTER Logical,
  166443. + IN gctSIZE_T Bytes
  166444. + )
  166445. +{
  166446. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  166447. + Os, ProcessID, Handle, Logical, Bytes);
  166448. +
  166449. + /* Verify the arguments. */
  166450. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166451. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  166452. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166453. +
  166454. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
  166455. +#ifdef CONFIG_ARM
  166456. + /* Inner cache. */
  166457. + dmac_flush_range(Logical, Logical + Bytes);
  166458. +
  166459. +#if defined(CONFIG_OUTER_CACHE)
  166460. + /* Outer cache. */
  166461. +#if gcdENABLE_OUTER_CACHE_PATCH
  166462. + _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_FLUSH);
  166463. +#else
  166464. + outer_flush_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
  166465. +#endif
  166466. +#endif
  166467. +
  166468. +#elif defined(CONFIG_MIPS)
  166469. + dma_cache_wback_inv((unsigned long) Logical, Bytes);
  166470. +#elif defined(CONFIG_PPC)
  166471. + /* TODO */
  166472. +#else
  166473. + dma_sync_single_for_device(
  166474. + gcvNULL,
  166475. + (dma_addr_t)Physical,
  166476. + Bytes,
  166477. + DMA_BIDIRECTIONAL);
  166478. +#endif
  166479. +#endif
  166480. +
  166481. + /* Success. */
  166482. + gcmkFOOTER_NO();
  166483. + return gcvSTATUS_OK;
  166484. +}
  166485. +
  166486. +/*******************************************************************************
  166487. +********************************* Broadcasting *********************************
  166488. +*******************************************************************************/
  166489. +
  166490. +/*******************************************************************************
  166491. +**
  166492. +** gckOS_Broadcast
  166493. +**
  166494. +** System hook for broadcast events from the kernel driver.
  166495. +**
  166496. +** INPUT:
  166497. +**
  166498. +** gckOS Os
  166499. +** Pointer to the gckOS object.
  166500. +**
  166501. +** gckHARDWARE Hardware
  166502. +** Pointer to the gckHARDWARE object.
  166503. +**
  166504. +** gceBROADCAST Reason
  166505. +** Reason for the broadcast. Can be one of the following values:
  166506. +**
  166507. +** gcvBROADCAST_GPU_IDLE
  166508. +** Broadcasted when the kernel driver thinks the GPU might be
  166509. +** idle. This can be used to handle power management.
  166510. +**
  166511. +** gcvBROADCAST_GPU_COMMIT
  166512. +** Broadcasted when any client process commits a command
  166513. +** buffer. This can be used to handle power management.
  166514. +**
  166515. +** gcvBROADCAST_GPU_STUCK
  166516. +** Broadcasted when the kernel driver hits the timeout waiting
  166517. +** for the GPU.
  166518. +**
  166519. +** gcvBROADCAST_FIRST_PROCESS
  166520. +** First process is trying to connect to the kernel.
  166521. +**
  166522. +** gcvBROADCAST_LAST_PROCESS
  166523. +** Last process has detached from the kernel.
  166524. +**
  166525. +** OUTPUT:
  166526. +**
  166527. +** Nothing.
  166528. +*/
  166529. +gceSTATUS
  166530. +gckOS_Broadcast(
  166531. + IN gckOS Os,
  166532. + IN gckHARDWARE Hardware,
  166533. + IN gceBROADCAST Reason
  166534. + )
  166535. +{
  166536. + gceSTATUS status;
  166537. +
  166538. + gcmkHEADER_ARG("Os=0x%X Hardware=0x%X Reason=%d", Os, Hardware, Reason);
  166539. +
  166540. + /* Verify the arguments. */
  166541. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166542. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  166543. +
  166544. + switch (Reason)
  166545. + {
  166546. + case gcvBROADCAST_FIRST_PROCESS:
  166547. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "First process has attached");
  166548. + break;
  166549. +
  166550. + case gcvBROADCAST_LAST_PROCESS:
  166551. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "Last process has detached");
  166552. +
  166553. + /* Put GPU OFF. */
  166554. + gcmkONERROR(
  166555. + gckHARDWARE_SetPowerManagementState(Hardware,
  166556. + gcvPOWER_OFF_BROADCAST));
  166557. + break;
  166558. +
  166559. + case gcvBROADCAST_GPU_IDLE:
  166560. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "GPU idle.");
  166561. +
  166562. + /* Put GPU IDLE. */
  166563. + gcmkONERROR(
  166564. + gckHARDWARE_SetPowerManagementState(Hardware,
  166565. +#if gcdPOWER_SUSNPEND_WHEN_IDLE
  166566. + gcvPOWER_SUSPEND_BROADCAST));
  166567. +#else
  166568. + gcvPOWER_IDLE_BROADCAST));
  166569. +#endif
  166570. +
  166571. + /* Add idle process DB. */
  166572. + gcmkONERROR(gckKERNEL_AddProcessDB(Hardware->kernel,
  166573. + 1,
  166574. + gcvDB_IDLE,
  166575. + gcvNULL, gcvNULL, 0));
  166576. + break;
  166577. +
  166578. + case gcvBROADCAST_GPU_COMMIT:
  166579. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "COMMIT has arrived.");
  166580. +
  166581. + /* Add busy process DB. */
  166582. + gcmkONERROR(gckKERNEL_AddProcessDB(Hardware->kernel,
  166583. + 0,
  166584. + gcvDB_IDLE,
  166585. + gcvNULL, gcvNULL, 0));
  166586. +
  166587. + /* Put GPU ON. */
  166588. + gcmkONERROR(
  166589. + gckHARDWARE_SetPowerManagementState(Hardware, gcvPOWER_ON_AUTO));
  166590. + break;
  166591. +
  166592. + case gcvBROADCAST_GPU_STUCK:
  166593. + gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_GPU_STUCK\n");
  166594. +#if !gcdENABLE_RECOVERY
  166595. + gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware));
  166596. +#endif
  166597. + gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
  166598. + break;
  166599. +
  166600. + case gcvBROADCAST_AXI_BUS_ERROR:
  166601. + gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_AXI_BUS_ERROR\n");
  166602. + gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware));
  166603. + gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
  166604. + break;
  166605. + }
  166606. +
  166607. + /* Success. */
  166608. + gcmkFOOTER_NO();
  166609. + return gcvSTATUS_OK;
  166610. +
  166611. +OnError:
  166612. + /* Return the status. */
  166613. + gcmkFOOTER();
  166614. + return status;
  166615. +}
  166616. +
  166617. +/*******************************************************************************
  166618. +**
  166619. +** gckOS_BroadcastHurry
  166620. +**
  166621. +** The GPU is running too slow.
  166622. +**
  166623. +** INPUT:
  166624. +**
  166625. +** gckOS Os
  166626. +** Pointer to the gckOS object.
  166627. +**
  166628. +** gckHARDWARE Hardware
  166629. +** Pointer to the gckHARDWARE object.
  166630. +**
  166631. +** gctUINT Urgency
  166632. +** The higher the number, the higher the urgency to speed up the GPU.
  166633. +** The maximum value is defined by the gcdDYNAMIC_EVENT_THRESHOLD.
  166634. +**
  166635. +** OUTPUT:
  166636. +**
  166637. +** Nothing.
  166638. +*/
  166639. +gceSTATUS
  166640. +gckOS_BroadcastHurry(
  166641. + IN gckOS Os,
  166642. + IN gckHARDWARE Hardware,
  166643. + IN gctUINT Urgency
  166644. + )
  166645. +{
  166646. + gcmkHEADER_ARG("Os=0x%x Hardware=0x%x Urgency=%u", Os, Hardware, Urgency);
  166647. +
  166648. + /* Do whatever you need to do to speed up the GPU now. */
  166649. +
  166650. + /* Success. */
  166651. + gcmkFOOTER_NO();
  166652. + return gcvSTATUS_OK;
  166653. +}
  166654. +
  166655. +/*******************************************************************************
  166656. +**
  166657. +** gckOS_BroadcastCalibrateSpeed
  166658. +**
  166659. +** Calibrate the speed of the GPU.
  166660. +**
  166661. +** INPUT:
  166662. +**
  166663. +** gckOS Os
  166664. +** Pointer to the gckOS object.
  166665. +**
  166666. +** gckHARDWARE Hardware
  166667. +** Pointer to the gckHARDWARE object.
  166668. +**
  166669. +** gctUINT Idle, Time
  166670. +** Idle/Time will give the percentage the GPU is idle, so you can use
  166671. +** this to calibrate the working point of the GPU.
  166672. +**
  166673. +** OUTPUT:
  166674. +**
  166675. +** Nothing.
  166676. +*/
  166677. +gceSTATUS
  166678. +gckOS_BroadcastCalibrateSpeed(
  166679. + IN gckOS Os,
  166680. + IN gckHARDWARE Hardware,
  166681. + IN gctUINT Idle,
  166682. + IN gctUINT Time
  166683. + )
  166684. +{
  166685. + gcmkHEADER_ARG("Os=0x%x Hardware=0x%x Idle=%u Time=%u",
  166686. + Os, Hardware, Idle, Time);
  166687. +
  166688. + /* Do whatever you need to do to callibrate the GPU speed. */
  166689. +
  166690. + /* Success. */
  166691. + gcmkFOOTER_NO();
  166692. + return gcvSTATUS_OK;
  166693. +}
  166694. +
  166695. +/*******************************************************************************
  166696. +********************************** Semaphores **********************************
  166697. +*******************************************************************************/
  166698. +
  166699. +/*******************************************************************************
  166700. +**
  166701. +** gckOS_CreateSemaphore
  166702. +**
  166703. +** Create a semaphore.
  166704. +**
  166705. +** INPUT:
  166706. +**
  166707. +** gckOS Os
  166708. +** Pointer to the gckOS object.
  166709. +**
  166710. +** OUTPUT:
  166711. +**
  166712. +** gctPOINTER * Semaphore
  166713. +** Pointer to the variable that will receive the created semaphore.
  166714. +*/
  166715. +gceSTATUS
  166716. +gckOS_CreateSemaphore(
  166717. + IN gckOS Os,
  166718. + OUT gctPOINTER * Semaphore
  166719. + )
  166720. +{
  166721. + gceSTATUS status;
  166722. + struct semaphore *sem = gcvNULL;
  166723. +
  166724. + gcmkHEADER_ARG("Os=0x%X", Os);
  166725. +
  166726. + /* Verify the arguments. */
  166727. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166728. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  166729. +
  166730. + /* Allocate the semaphore structure. */
  166731. + sem = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
  166732. + if (sem == gcvNULL)
  166733. + {
  166734. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  166735. + }
  166736. +
  166737. + /* Initialize the semaphore. */
  166738. + sema_init(sem, 1);
  166739. +
  166740. + /* Return to caller. */
  166741. + *Semaphore = (gctPOINTER) sem;
  166742. +
  166743. + /* Success. */
  166744. + gcmkFOOTER_NO();
  166745. + return gcvSTATUS_OK;
  166746. +
  166747. +OnError:
  166748. + /* Return the status. */
  166749. + gcmkFOOTER();
  166750. + return status;
  166751. +}
  166752. +
  166753. +/*******************************************************************************
  166754. +**
  166755. +** gckOS_AcquireSemaphore
  166756. +**
  166757. +** Acquire a semaphore.
  166758. +**
  166759. +** INPUT:
  166760. +**
  166761. +** gckOS Os
  166762. +** Pointer to the gckOS object.
  166763. +**
  166764. +** gctPOINTER Semaphore
  166765. +** Pointer to the semaphore thet needs to be acquired.
  166766. +**
  166767. +** OUTPUT:
  166768. +**
  166769. +** Nothing.
  166770. +*/
  166771. +gceSTATUS
  166772. +gckOS_AcquireSemaphore(
  166773. + IN gckOS Os,
  166774. + IN gctPOINTER Semaphore
  166775. + )
  166776. +{
  166777. + gceSTATUS status;
  166778. +
  166779. + gcmkHEADER_ARG("Os=0x%08X Semaphore=0x%08X", Os, Semaphore);
  166780. +
  166781. + /* Verify the arguments. */
  166782. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166783. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  166784. +
  166785. + /* Acquire the semaphore. */
  166786. + if (down_interruptible((struct semaphore *) Semaphore))
  166787. + {
  166788. + gcmkONERROR(gcvSTATUS_INTERRUPTED);
  166789. + }
  166790. +
  166791. + /* Success. */
  166792. + gcmkFOOTER_NO();
  166793. + return gcvSTATUS_OK;
  166794. +
  166795. +OnError:
  166796. + /* Return the status. */
  166797. + gcmkFOOTER();
  166798. + return status;
  166799. +}
  166800. +
  166801. +/*******************************************************************************
  166802. +**
  166803. +** gckOS_TryAcquireSemaphore
  166804. +**
  166805. +** Try to acquire a semaphore.
  166806. +**
  166807. +** INPUT:
  166808. +**
  166809. +** gckOS Os
  166810. +** Pointer to the gckOS object.
  166811. +**
  166812. +** gctPOINTER Semaphore
  166813. +** Pointer to the semaphore thet needs to be acquired.
  166814. +**
  166815. +** OUTPUT:
  166816. +**
  166817. +** Nothing.
  166818. +*/
  166819. +gceSTATUS
  166820. +gckOS_TryAcquireSemaphore(
  166821. + IN gckOS Os,
  166822. + IN gctPOINTER Semaphore
  166823. + )
  166824. +{
  166825. + gceSTATUS status;
  166826. +
  166827. + gcmkHEADER_ARG("Os=0x%x", Os);
  166828. +
  166829. + /* Verify the arguments. */
  166830. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166831. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  166832. +
  166833. + /* Acquire the semaphore. */
  166834. + if (down_trylock((struct semaphore *) Semaphore))
  166835. + {
  166836. + /* Timeout. */
  166837. + status = gcvSTATUS_TIMEOUT;
  166838. + gcmkFOOTER();
  166839. + return status;
  166840. + }
  166841. +
  166842. + /* Success. */
  166843. + gcmkFOOTER_NO();
  166844. + return gcvSTATUS_OK;
  166845. +}
  166846. +
  166847. +/*******************************************************************************
  166848. +**
  166849. +** gckOS_ReleaseSemaphore
  166850. +**
  166851. +** Release a previously acquired semaphore.
  166852. +**
  166853. +** INPUT:
  166854. +**
  166855. +** gckOS Os
  166856. +** Pointer to the gckOS object.
  166857. +**
  166858. +** gctPOINTER Semaphore
  166859. +** Pointer to the semaphore thet needs to be released.
  166860. +**
  166861. +** OUTPUT:
  166862. +**
  166863. +** Nothing.
  166864. +*/
  166865. +gceSTATUS
  166866. +gckOS_ReleaseSemaphore(
  166867. + IN gckOS Os,
  166868. + IN gctPOINTER Semaphore
  166869. + )
  166870. +{
  166871. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%X", Os, Semaphore);
  166872. +
  166873. + /* Verify the arguments. */
  166874. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166875. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  166876. +
  166877. + /* Release the semaphore. */
  166878. + up((struct semaphore *) Semaphore);
  166879. +
  166880. + /* Success. */
  166881. + gcmkFOOTER_NO();
  166882. + return gcvSTATUS_OK;
  166883. +}
  166884. +
  166885. +/*******************************************************************************
  166886. +**
  166887. +** gckOS_DestroySemaphore
  166888. +**
  166889. +** Destroy a semaphore.
  166890. +**
  166891. +** INPUT:
  166892. +**
  166893. +** gckOS Os
  166894. +** Pointer to the gckOS object.
  166895. +**
  166896. +** gctPOINTER Semaphore
  166897. +** Pointer to the semaphore thet needs to be destroyed.
  166898. +**
  166899. +** OUTPUT:
  166900. +**
  166901. +** Nothing.
  166902. +*/
  166903. +gceSTATUS
  166904. +gckOS_DestroySemaphore(
  166905. + IN gckOS Os,
  166906. + IN gctPOINTER Semaphore
  166907. + )
  166908. +{
  166909. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%X", Os, Semaphore);
  166910. +
  166911. + /* Verify the arguments. */
  166912. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166913. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  166914. +
  166915. + /* Free the sempahore structure. */
  166916. + kfree(Semaphore);
  166917. +
  166918. + /* Success. */
  166919. + gcmkFOOTER_NO();
  166920. + return gcvSTATUS_OK;
  166921. +}
  166922. +
  166923. +/*******************************************************************************
  166924. +**
  166925. +** gckOS_GetProcessID
  166926. +**
  166927. +** Get current process ID.
  166928. +**
  166929. +** INPUT:
  166930. +**
  166931. +** Nothing.
  166932. +**
  166933. +** OUTPUT:
  166934. +**
  166935. +** gctUINT32_PTR ProcessID
  166936. +** Pointer to the variable that receives the process ID.
  166937. +*/
  166938. +gceSTATUS
  166939. +gckOS_GetProcessID(
  166940. + OUT gctUINT32_PTR ProcessID
  166941. + )
  166942. +{
  166943. + /* Get process ID. */
  166944. + if (ProcessID != gcvNULL)
  166945. + {
  166946. + *ProcessID = _GetProcessID();
  166947. + }
  166948. +
  166949. + /* Success. */
  166950. + return gcvSTATUS_OK;
  166951. +}
  166952. +
  166953. +/*******************************************************************************
  166954. +**
  166955. +** gckOS_GetThreadID
  166956. +**
  166957. +** Get current thread ID.
  166958. +**
  166959. +** INPUT:
  166960. +**
  166961. +** Nothing.
  166962. +**
  166963. +** OUTPUT:
  166964. +**
  166965. +** gctUINT32_PTR ThreadID
  166966. +** Pointer to the variable that receives the thread ID.
  166967. +*/
  166968. +gceSTATUS
  166969. +gckOS_GetThreadID(
  166970. + OUT gctUINT32_PTR ThreadID
  166971. + )
  166972. +{
  166973. + /* Get thread ID. */
  166974. + if (ThreadID != gcvNULL)
  166975. + {
  166976. + *ThreadID = _GetThreadID();
  166977. + }
  166978. +
  166979. + /* Success. */
  166980. + return gcvSTATUS_OK;
  166981. +}
  166982. +
  166983. +/*******************************************************************************
  166984. +**
  166985. +** gckOS_SetGPUPower
  166986. +**
  166987. +** Set the power of the GPU on or off.
  166988. +**
  166989. +** INPUT:
  166990. +**
  166991. +** gckOS Os
  166992. +** Pointer to a gckOS object.
  166993. +**
  166994. +** gckCORE Core
  166995. +** GPU whose power is set.
  166996. +**
  166997. +** gctBOOL Clock
  166998. +** gcvTRUE to turn on the clock, or gcvFALSE to turn off the clock.
  166999. +**
  167000. +** gctBOOL Power
  167001. +** gcvTRUE to turn on the power, or gcvFALSE to turn off the power.
  167002. +**
  167003. +** OUTPUT:
  167004. +**
  167005. +** Nothing.
  167006. +*/
  167007. +gceSTATUS
  167008. +gckOS_SetGPUPower(
  167009. + IN gckOS Os,
  167010. + IN gceCORE Core,
  167011. + IN gctBOOL Clock,
  167012. + IN gctBOOL Power
  167013. + )
  167014. +{
  167015. + struct clk *clk_3dcore = Os->device->clk_3d_core;
  167016. + struct clk *clk_3dshader = Os->device->clk_3d_shader;
  167017. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  167018. + struct clk *clk_3d_axi = Os->device->clk_3d_axi;
  167019. +#endif
  167020. + struct clk *clk_2dcore = Os->device->clk_2d_core;
  167021. + struct clk *clk_2d_axi = Os->device->clk_2d_axi;
  167022. + struct clk *clk_vg_axi = Os->device->clk_vg_axi;
  167023. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  167024. + int ret;
  167025. +#endif
  167026. +
  167027. + gctBOOL oldClockState = gcvFALSE;
  167028. + gctBOOL oldPowerState = gcvFALSE;
  167029. +
  167030. + gcmkHEADER_ARG("Os=0x%X Core=%d Clock=%d Power=%d", Os, Core, Clock, Power);
  167031. +
  167032. + if (Os->device->kernels[Core] != NULL)
  167033. + {
  167034. +#if gcdENABLE_VG
  167035. + if (Core == gcvCORE_VG)
  167036. + {
  167037. + oldClockState = Os->device->kernels[Core]->vg->hardware->clockState;
  167038. + oldPowerState = Os->device->kernels[Core]->vg->hardware->powerState;
  167039. + }
  167040. + else
  167041. + {
  167042. +#endif
  167043. + oldClockState = Os->device->kernels[Core]->hardware->clockState;
  167044. + oldPowerState = Os->device->kernels[Core]->hardware->powerState;
  167045. +#if gcdENABLE_VG
  167046. + }
  167047. +#endif
  167048. + }
  167049. + if((Power == gcvTRUE) && (oldPowerState == gcvFALSE))
  167050. + {
  167051. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  167052. + if(!IS_ERR(Os->device->gpu_regulator)) {
  167053. + ret = regulator_enable(Os->device->gpu_regulator);
  167054. + if (ret != 0)
  167055. + gckOS_Print("%s(%d): fail to enable pu regulator %d!\n",
  167056. + __FUNCTION__, __LINE__, ret);
  167057. + }
  167058. +#else
  167059. + imx_gpc_power_up_pu(true);
  167060. +#endif
  167061. +
  167062. +#ifdef CONFIG_PM
  167063. + pm_runtime_get_sync(Os->device->pmdev);
  167064. +#endif
  167065. + }
  167066. +
  167067. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  167068. + if (Clock == gcvTRUE) {
  167069. + if (oldClockState == gcvFALSE) {
  167070. + switch (Core) {
  167071. + case gcvCORE_MAJOR:
  167072. + clk_enable(clk_3dcore);
  167073. + if (cpu_is_mx6q())
  167074. + clk_enable(clk_3dshader);
  167075. + break;
  167076. + case gcvCORE_2D:
  167077. + clk_enable(clk_2dcore);
  167078. + clk_enable(clk_2d_axi);
  167079. + break;
  167080. + case gcvCORE_VG:
  167081. + clk_enable(clk_2dcore);
  167082. + clk_enable(clk_vg_axi);
  167083. + break;
  167084. + default:
  167085. + break;
  167086. + }
  167087. + }
  167088. + } else {
  167089. + if (oldClockState == gcvTRUE) {
  167090. + switch (Core) {
  167091. + case gcvCORE_MAJOR:
  167092. + if (cpu_is_mx6q())
  167093. + clk_disable(clk_3dshader);
  167094. + clk_disable(clk_3dcore);
  167095. + break;
  167096. + case gcvCORE_2D:
  167097. + clk_disable(clk_2dcore);
  167098. + clk_disable(clk_2d_axi);
  167099. + break;
  167100. + case gcvCORE_VG:
  167101. + clk_disable(clk_2dcore);
  167102. + clk_disable(clk_vg_axi);
  167103. + break;
  167104. + default:
  167105. + break;
  167106. + }
  167107. + }
  167108. + }
  167109. +#else
  167110. + if (Clock == gcvTRUE) {
  167111. + if (oldClockState == gcvFALSE) {
  167112. + switch (Core) {
  167113. + case gcvCORE_MAJOR:
  167114. + clk_prepare_enable(clk_3dcore);
  167115. + clk_prepare_enable(clk_3dshader);
  167116. + clk_prepare_enable(clk_3d_axi);
  167117. + break;
  167118. + case gcvCORE_2D:
  167119. + clk_prepare_enable(clk_2dcore);
  167120. + clk_prepare_enable(clk_2d_axi);
  167121. + break;
  167122. + case gcvCORE_VG:
  167123. + clk_prepare_enable(clk_2dcore);
  167124. + clk_prepare_enable(clk_vg_axi);
  167125. + break;
  167126. + default:
  167127. + break;
  167128. + }
  167129. + }
  167130. + } else {
  167131. + if (oldClockState == gcvTRUE) {
  167132. + switch (Core) {
  167133. + case gcvCORE_MAJOR:
  167134. + clk_disable_unprepare(clk_3d_axi);
  167135. + clk_disable_unprepare(clk_3dshader);
  167136. + clk_disable_unprepare(clk_3dcore);
  167137. + break;
  167138. + case gcvCORE_2D:
  167139. + clk_disable_unprepare(clk_2d_axi);
  167140. + clk_disable_unprepare(clk_2dcore);
  167141. + break;
  167142. + case gcvCORE_VG:
  167143. + clk_disable_unprepare(clk_vg_axi);
  167144. + clk_disable_unprepare(clk_2dcore);
  167145. + break;
  167146. + default:
  167147. + break;
  167148. + }
  167149. + }
  167150. + }
  167151. +#endif
  167152. + if((Power == gcvFALSE) && (oldPowerState == gcvTRUE))
  167153. + {
  167154. +#ifdef CONFIG_PM
  167155. + pm_runtime_put_sync(Os->device->pmdev);
  167156. +#endif
  167157. +
  167158. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  167159. + if(!IS_ERR(Os->device->gpu_regulator))
  167160. + regulator_disable(Os->device->gpu_regulator);
  167161. +#else
  167162. + imx_gpc_power_up_pu(false);
  167163. +#endif
  167164. +
  167165. + }
  167166. + /* TODO: Put your code here. */
  167167. + gcmkFOOTER_NO();
  167168. + return gcvSTATUS_OK;
  167169. +}
  167170. +
  167171. +/*******************************************************************************
  167172. +**
  167173. +** gckOS_ResetGPU
  167174. +**
  167175. +** Reset the GPU.
  167176. +**
  167177. +** INPUT:
  167178. +**
  167179. +** gckOS Os
  167180. +** Pointer to a gckOS object.
  167181. +**
  167182. +** gckCORE Core
  167183. +** GPU whose power is set.
  167184. +**
  167185. +** OUTPUT:
  167186. +**
  167187. +** Nothing.
  167188. +*/
  167189. +gceSTATUS
  167190. +gckOS_ResetGPU(
  167191. + IN gckOS Os,
  167192. + IN gceCORE Core
  167193. + )
  167194. +{
  167195. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  167196. +#define SRC_SCR_OFFSET 0
  167197. +#define BP_SRC_SCR_GPU3D_RST 1
  167198. +#define BP_SRC_SCR_GPU2D_RST 4
  167199. + void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR);
  167200. + gctUINT32 bit_offset,val;
  167201. +
  167202. + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
  167203. +
  167204. + if(Core == gcvCORE_MAJOR) {
  167205. + bit_offset = BP_SRC_SCR_GPU3D_RST;
  167206. + } else if((Core == gcvCORE_VG)
  167207. + ||(Core == gcvCORE_2D)) {
  167208. + bit_offset = BP_SRC_SCR_GPU2D_RST;
  167209. + } else {
  167210. + return gcvSTATUS_INVALID_CONFIG;
  167211. + }
  167212. + val = __raw_readl(src_base + SRC_SCR_OFFSET);
  167213. + val &= ~(1 << (bit_offset));
  167214. + val |= (1 << (bit_offset));
  167215. + __raw_writel(val, src_base + SRC_SCR_OFFSET);
  167216. +
  167217. + while ((__raw_readl(src_base + SRC_SCR_OFFSET) &
  167218. + (1 << (bit_offset))) != 0) {
  167219. + }
  167220. +
  167221. + gcmkFOOTER_NO();
  167222. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  167223. + struct reset_control *rstc = Os->device->rstc[Core];
  167224. + if (rstc)
  167225. + reset_control_reset(rstc);
  167226. +#else
  167227. + imx_src_reset_gpu((int)Core);
  167228. +#endif
  167229. + return gcvSTATUS_OK;
  167230. +}
  167231. +
  167232. +/*******************************************************************************
  167233. +**
  167234. +** gckOS_PrepareGPUFrequency
  167235. +**
  167236. +** Prepare to set GPU frequency and voltage.
  167237. +**
  167238. +** INPUT:
  167239. +**
  167240. +** gckOS Os
  167241. +** Pointer to a gckOS object.
  167242. +**
  167243. +** gckCORE Core
  167244. +** GPU whose frequency and voltage will be set.
  167245. +**
  167246. +** OUTPUT:
  167247. +**
  167248. +** Nothing.
  167249. +*/
  167250. +gceSTATUS
  167251. +gckOS_PrepareGPUFrequency(
  167252. + IN gckOS Os,
  167253. + IN gceCORE Core
  167254. + )
  167255. +{
  167256. + return gcvSTATUS_OK;
  167257. +}
  167258. +
  167259. +/*******************************************************************************
  167260. +**
  167261. +** gckOS_FinishGPUFrequency
  167262. +**
  167263. +** Finish GPU frequency setting.
  167264. +**
  167265. +** INPUT:
  167266. +**
  167267. +** gckOS Os
  167268. +** Pointer to a gckOS object.
  167269. +**
  167270. +** gckCORE Core
  167271. +** GPU whose frequency and voltage is set.
  167272. +**
  167273. +** OUTPUT:
  167274. +**
  167275. +** Nothing.
  167276. +*/
  167277. +gceSTATUS
  167278. +gckOS_FinishGPUFrequency(
  167279. + IN gckOS Os,
  167280. + IN gceCORE Core
  167281. + )
  167282. +{
  167283. + return gcvSTATUS_OK;
  167284. +}
  167285. +
  167286. +/*******************************************************************************
  167287. +**
  167288. +** gckOS_QueryGPUFrequency
  167289. +**
  167290. +** Query the current frequency of the GPU.
  167291. +**
  167292. +** INPUT:
  167293. +**
  167294. +** gckOS Os
  167295. +** Pointer to a gckOS object.
  167296. +**
  167297. +** gckCORE Core
  167298. +** GPU whose power is set.
  167299. +**
  167300. +** gctUINT32 * Frequency
  167301. +** Pointer to a gctUINT32 to obtain current frequency, in MHz.
  167302. +**
  167303. +** gctUINT8 * Scale
  167304. +** Pointer to a gctUINT8 to obtain current scale(1 - 64).
  167305. +**
  167306. +** OUTPUT:
  167307. +**
  167308. +** Nothing.
  167309. +*/
  167310. +gceSTATUS
  167311. +gckOS_QueryGPUFrequency(
  167312. + IN gckOS Os,
  167313. + IN gceCORE Core,
  167314. + OUT gctUINT32 * Frequency,
  167315. + OUT gctUINT8 * Scale
  167316. + )
  167317. +{
  167318. + return gcvSTATUS_OK;
  167319. +}
  167320. +
  167321. +/*******************************************************************************
  167322. +**
  167323. +** gckOS_SetGPUFrequency
  167324. +**
  167325. +** Set frequency and voltage of the GPU.
  167326. +**
  167327. +** 1. DVFS manager gives the target scale of full frequency, BSP must find
  167328. +** a real frequency according to this scale and board's configure.
  167329. +**
  167330. +** 2. BSP should find a suitable voltage for this frequency.
  167331. +**
  167332. +** 3. BSP must make sure setting take effect before this function returns.
  167333. +**
  167334. +** INPUT:
  167335. +**
  167336. +** gckOS Os
  167337. +** Pointer to a gckOS object.
  167338. +**
  167339. +** gckCORE Core
  167340. +** GPU whose power is set.
  167341. +**
  167342. +** gctUINT8 Scale
  167343. +** Target scale of full frequency, range is [1, 64]. 1 means 1/64 of
  167344. +** full frequency and 64 means 64/64 of full frequency.
  167345. +**
  167346. +** OUTPUT:
  167347. +**
  167348. +** Nothing.
  167349. +*/
  167350. +gceSTATUS
  167351. +gckOS_SetGPUFrequency(
  167352. + IN gckOS Os,
  167353. + IN gceCORE Core,
  167354. + IN gctUINT8 Scale
  167355. + )
  167356. +{
  167357. + return gcvSTATUS_OK;
  167358. +}
  167359. +
  167360. +/*----------------------------------------------------------------------------*/
  167361. +/*----- Profile --------------------------------------------------------------*/
  167362. +
  167363. +gceSTATUS
  167364. +gckOS_GetProfileTick(
  167365. + OUT gctUINT64_PTR Tick
  167366. + )
  167367. +{
  167368. + struct timespec time;
  167369. +
  167370. + ktime_get_ts(&time);
  167371. +
  167372. + *Tick = time.tv_nsec + time.tv_sec * 1000000000ULL;
  167373. +
  167374. + return gcvSTATUS_OK;
  167375. +}
  167376. +
  167377. +gceSTATUS
  167378. +gckOS_QueryProfileTickRate(
  167379. + OUT gctUINT64_PTR TickRate
  167380. + )
  167381. +{
  167382. + struct timespec res;
  167383. +
  167384. + hrtimer_get_res(CLOCK_MONOTONIC, &res);
  167385. +
  167386. + *TickRate = res.tv_nsec + res.tv_sec * 1000000000ULL;
  167387. +
  167388. + return gcvSTATUS_OK;
  167389. +}
  167390. +
  167391. +gctUINT32
  167392. +gckOS_ProfileToMS(
  167393. + IN gctUINT64 Ticks
  167394. + )
  167395. +{
  167396. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
  167397. + return div_u64(Ticks, 1000000);
  167398. +#else
  167399. + gctUINT64 rem = Ticks;
  167400. + gctUINT64 b = 1000000;
  167401. + gctUINT64 res, d = 1;
  167402. + gctUINT32 high = rem >> 32;
  167403. +
  167404. + /* Reduce the thing a bit first */
  167405. + res = 0;
  167406. + if (high >= 1000000)
  167407. + {
  167408. + high /= 1000000;
  167409. + res = (gctUINT64) high << 32;
  167410. + rem -= (gctUINT64) (high * 1000000) << 32;
  167411. + }
  167412. +
  167413. + while (((gctINT64) b > 0) && (b < rem))
  167414. + {
  167415. + b <<= 1;
  167416. + d <<= 1;
  167417. + }
  167418. +
  167419. + do
  167420. + {
  167421. + if (rem >= b)
  167422. + {
  167423. + rem -= b;
  167424. + res += d;
  167425. + }
  167426. +
  167427. + b >>= 1;
  167428. + d >>= 1;
  167429. + }
  167430. + while (d);
  167431. +
  167432. + return (gctUINT32) res;
  167433. +#endif
  167434. +}
  167435. +
  167436. +/******************************************************************************\
  167437. +******************************* Signal Management ******************************
  167438. +\******************************************************************************/
  167439. +
  167440. +#undef _GC_OBJ_ZONE
  167441. +#define _GC_OBJ_ZONE gcvZONE_SIGNAL
  167442. +
  167443. +/*******************************************************************************
  167444. +**
  167445. +** gckOS_CreateSignal
  167446. +**
  167447. +** Create a new signal.
  167448. +**
  167449. +** INPUT:
  167450. +**
  167451. +** gckOS Os
  167452. +** Pointer to an gckOS object.
  167453. +**
  167454. +** gctBOOL ManualReset
  167455. +** If set to gcvTRUE, gckOS_Signal with gcvFALSE must be called in
  167456. +** order to set the signal to nonsignaled state.
  167457. +** If set to gcvFALSE, the signal will automatically be set to
  167458. +** nonsignaled state by gckOS_WaitSignal function.
  167459. +**
  167460. +** OUTPUT:
  167461. +**
  167462. +** gctSIGNAL * Signal
  167463. +** Pointer to a variable receiving the created gctSIGNAL.
  167464. +*/
  167465. +gceSTATUS
  167466. +gckOS_CreateSignal(
  167467. + IN gckOS Os,
  167468. + IN gctBOOL ManualReset,
  167469. + OUT gctSIGNAL * Signal
  167470. + )
  167471. +{
  167472. + gceSTATUS status;
  167473. + gcsSIGNAL_PTR signal;
  167474. +
  167475. + gcmkHEADER_ARG("Os=0x%X ManualReset=%d", Os, ManualReset);
  167476. +
  167477. + /* Verify the arguments. */
  167478. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167479. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167480. +
  167481. + /* Create an event structure. */
  167482. + signal = (gcsSIGNAL_PTR) kmalloc(sizeof(gcsSIGNAL), GFP_KERNEL | gcdNOWARN);
  167483. +
  167484. + if (signal == gcvNULL)
  167485. + {
  167486. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  167487. + }
  167488. +
  167489. + /* Save the process ID. */
  167490. + signal->process = (gctHANDLE)(gctUINTPTR_T) _GetProcessID();
  167491. + signal->manualReset = ManualReset;
  167492. + signal->hardware = gcvNULL;
  167493. + init_completion(&signal->obj);
  167494. + atomic_set(&signal->ref, 1);
  167495. +
  167496. + gcmkONERROR(_AllocateIntegerId(&Os->signalDB, signal, &signal->id));
  167497. +
  167498. + *Signal = (gctSIGNAL)(gctUINTPTR_T)signal->id;
  167499. +
  167500. + gcmkFOOTER_ARG("*Signal=0x%X", *Signal);
  167501. + return gcvSTATUS_OK;
  167502. +
  167503. +OnError:
  167504. + if (signal != gcvNULL)
  167505. + {
  167506. + kfree(signal);
  167507. + }
  167508. +
  167509. + gcmkFOOTER_NO();
  167510. + return status;
  167511. +}
  167512. +
  167513. +gceSTATUS
  167514. +gckOS_SignalQueryHardware(
  167515. + IN gckOS Os,
  167516. + IN gctSIGNAL Signal,
  167517. + OUT gckHARDWARE * Hardware
  167518. + )
  167519. +{
  167520. + gceSTATUS status;
  167521. + gcsSIGNAL_PTR signal;
  167522. +
  167523. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Hardware=0x%X", Os, Signal, Hardware);
  167524. +
  167525. + /* Verify the arguments. */
  167526. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167527. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167528. + gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
  167529. +
  167530. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  167531. +
  167532. + *Hardware = signal->hardware;
  167533. +
  167534. + gcmkFOOTER_NO();
  167535. + return gcvSTATUS_OK;
  167536. +OnError:
  167537. + gcmkFOOTER();
  167538. + return status;
  167539. +}
  167540. +
  167541. +gceSTATUS
  167542. +gckOS_SignalSetHardware(
  167543. + IN gckOS Os,
  167544. + IN gctSIGNAL Signal,
  167545. + IN gckHARDWARE Hardware
  167546. + )
  167547. +{
  167548. + gceSTATUS status;
  167549. + gcsSIGNAL_PTR signal;
  167550. +
  167551. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Hardware=0x%X", Os, Signal, Hardware);
  167552. +
  167553. + /* Verify the arguments. */
  167554. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167555. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167556. +
  167557. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  167558. +
  167559. + signal->hardware = Hardware;
  167560. +
  167561. + gcmkFOOTER_NO();
  167562. + return gcvSTATUS_OK;
  167563. +OnError:
  167564. + gcmkFOOTER();
  167565. + return status;
  167566. +}
  167567. +
  167568. +/*******************************************************************************
  167569. +**
  167570. +** gckOS_DestroySignal
  167571. +**
  167572. +** Destroy a signal.
  167573. +**
  167574. +** INPUT:
  167575. +**
  167576. +** gckOS Os
  167577. +** Pointer to an gckOS object.
  167578. +**
  167579. +** gctSIGNAL Signal
  167580. +** Pointer to the gctSIGNAL.
  167581. +**
  167582. +** OUTPUT:
  167583. +**
  167584. +** Nothing.
  167585. +*/
  167586. +gceSTATUS
  167587. +gckOS_DestroySignal(
  167588. + IN gckOS Os,
  167589. + IN gctSIGNAL Signal
  167590. + )
  167591. +{
  167592. + gceSTATUS status;
  167593. + gcsSIGNAL_PTR signal;
  167594. + gctBOOL acquired = gcvFALSE;
  167595. +
  167596. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X", Os, Signal);
  167597. +
  167598. + /* Verify the arguments. */
  167599. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167600. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167601. +
  167602. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->signalMutex, gcvINFINITE));
  167603. + acquired = gcvTRUE;
  167604. +
  167605. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  167606. +
  167607. + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
  167608. +
  167609. + if (atomic_dec_and_test(&signal->ref))
  167610. + {
  167611. + gcmkVERIFY_OK(_DestroyIntegerId(&Os->signalDB, signal->id));
  167612. +
  167613. + /* Free the sgianl. */
  167614. + kfree(signal);
  167615. + }
  167616. +
  167617. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  167618. + acquired = gcvFALSE;
  167619. +
  167620. + /* Success. */
  167621. + gcmkFOOTER_NO();
  167622. + return gcvSTATUS_OK;
  167623. +
  167624. +OnError:
  167625. + if (acquired)
  167626. + {
  167627. + /* Release the mutex. */
  167628. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  167629. + }
  167630. +
  167631. + gcmkFOOTER();
  167632. + return status;
  167633. +}
  167634. +
  167635. +/*******************************************************************************
  167636. +**
  167637. +** gckOS_Signal
  167638. +**
  167639. +** Set a state of the specified signal.
  167640. +**
  167641. +** INPUT:
  167642. +**
  167643. +** gckOS Os
  167644. +** Pointer to an gckOS object.
  167645. +**
  167646. +** gctSIGNAL Signal
  167647. +** Pointer to the gctSIGNAL.
  167648. +**
  167649. +** gctBOOL State
  167650. +** If gcvTRUE, the signal will be set to signaled state.
  167651. +** If gcvFALSE, the signal will be set to nonsignaled state.
  167652. +**
  167653. +** OUTPUT:
  167654. +**
  167655. +** Nothing.
  167656. +*/
  167657. +gceSTATUS
  167658. +gckOS_Signal(
  167659. + IN gckOS Os,
  167660. + IN gctSIGNAL Signal,
  167661. + IN gctBOOL State
  167662. + )
  167663. +{
  167664. + gceSTATUS status;
  167665. + gcsSIGNAL_PTR signal;
  167666. + gctBOOL acquired = gcvFALSE;
  167667. +
  167668. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X State=%d", Os, Signal, State);
  167669. +
  167670. + /* Verify the arguments. */
  167671. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167672. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167673. +
  167674. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->signalMutex, gcvINFINITE));
  167675. + acquired = gcvTRUE;
  167676. +
  167677. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  167678. +
  167679. + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
  167680. +
  167681. + if (State)
  167682. + {
  167683. + /* unbind the signal from hardware. */
  167684. + signal->hardware = gcvNULL;
  167685. +
  167686. + /* Set the event to a signaled state. */
  167687. + complete(&signal->obj);
  167688. + }
  167689. + else
  167690. + {
  167691. + /* Set the event to an unsignaled state. */
  167692. + reinit_completion(&signal->obj);
  167693. + }
  167694. +
  167695. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  167696. + acquired = gcvFALSE;
  167697. +
  167698. + /* Success. */
  167699. + gcmkFOOTER_NO();
  167700. + return gcvSTATUS_OK;
  167701. +
  167702. +OnError:
  167703. + if (acquired)
  167704. + {
  167705. + /* Release the mutex. */
  167706. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  167707. + }
  167708. +
  167709. + gcmkFOOTER();
  167710. + return status;
  167711. +}
  167712. +
  167713. +#if gcdENABLE_VG
  167714. +gceSTATUS
  167715. +gckOS_SetSignalVG(
  167716. + IN gckOS Os,
  167717. + IN gctHANDLE Process,
  167718. + IN gctSIGNAL Signal
  167719. + )
  167720. +{
  167721. + gceSTATUS status;
  167722. + gctINT result;
  167723. + struct task_struct * userTask;
  167724. + struct siginfo info;
  167725. +
  167726. + userTask = FIND_TASK_BY_PID((pid_t)(gctUINTPTR_T) Process);
  167727. +
  167728. + if (userTask != gcvNULL)
  167729. + {
  167730. + info.si_signo = 48;
  167731. + info.si_code = __SI_CODE(__SI_RT, SI_KERNEL);
  167732. + info.si_pid = 0;
  167733. + info.si_uid = 0;
  167734. + info.si_ptr = (gctPOINTER) Signal;
  167735. +
  167736. + /* Signals with numbers between 32 and 63 are real-time,
  167737. + send a real-time signal to the user process. */
  167738. + result = send_sig_info(48, &info, userTask);
  167739. +
  167740. + printk("gckOS_SetSignalVG:0x%x\n", result);
  167741. + /* Error? */
  167742. + if (result < 0)
  167743. + {
  167744. + status = gcvSTATUS_GENERIC_IO;
  167745. +
  167746. + gcmkTRACE(
  167747. + gcvLEVEL_ERROR,
  167748. + "%s(%d): an error has occurred.\n",
  167749. + __FUNCTION__, __LINE__
  167750. + );
  167751. + }
  167752. + else
  167753. + {
  167754. + status = gcvSTATUS_OK;
  167755. + }
  167756. + }
  167757. + else
  167758. + {
  167759. + status = gcvSTATUS_GENERIC_IO;
  167760. +
  167761. + gcmkTRACE(
  167762. + gcvLEVEL_ERROR,
  167763. + "%s(%d): an error has occurred.\n",
  167764. + __FUNCTION__, __LINE__
  167765. + );
  167766. + }
  167767. +
  167768. + /* Return status. */
  167769. + return status;
  167770. +}
  167771. +#endif
  167772. +
  167773. +/*******************************************************************************
  167774. +**
  167775. +** gckOS_UserSignal
  167776. +**
  167777. +** Set the specified signal which is owned by a process to signaled state.
  167778. +**
  167779. +** INPUT:
  167780. +**
  167781. +** gckOS Os
  167782. +** Pointer to an gckOS object.
  167783. +**
  167784. +** gctSIGNAL Signal
  167785. +** Pointer to the gctSIGNAL.
  167786. +**
  167787. +** gctHANDLE Process
  167788. +** Handle of process owning the signal.
  167789. +**
  167790. +** OUTPUT:
  167791. +**
  167792. +** Nothing.
  167793. +*/
  167794. +gceSTATUS
  167795. +gckOS_UserSignal(
  167796. + IN gckOS Os,
  167797. + IN gctSIGNAL Signal,
  167798. + IN gctHANDLE Process
  167799. + )
  167800. +{
  167801. + gceSTATUS status;
  167802. + gctSIGNAL signal;
  167803. +
  167804. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=%d",
  167805. + Os, Signal, (gctINT32)(gctUINTPTR_T)Process);
  167806. +
  167807. + /* Map the signal into kernel space. */
  167808. + gcmkONERROR(gckOS_MapSignal(Os, Signal, Process, &signal));
  167809. +
  167810. + /* Signal. */
  167811. + status = gckOS_Signal(Os, signal, gcvTRUE);
  167812. +
  167813. + /* Unmap the signal */
  167814. + gcmkVERIFY_OK(gckOS_UnmapSignal(Os, Signal));
  167815. +
  167816. + gcmkFOOTER();
  167817. + return status;
  167818. +
  167819. +OnError:
  167820. + /* Return the status. */
  167821. + gcmkFOOTER();
  167822. + return status;
  167823. +}
  167824. +
  167825. +/*******************************************************************************
  167826. +**
  167827. +** gckOS_WaitSignal
  167828. +**
  167829. +** Wait for a signal to become signaled.
  167830. +**
  167831. +** INPUT:
  167832. +**
  167833. +** gckOS Os
  167834. +** Pointer to an gckOS object.
  167835. +**
  167836. +** gctSIGNAL Signal
  167837. +** Pointer to the gctSIGNAL.
  167838. +**
  167839. +** gctUINT32 Wait
  167840. +** Number of milliseconds to wait.
  167841. +** Pass the value of gcvINFINITE for an infinite wait.
  167842. +**
  167843. +** OUTPUT:
  167844. +**
  167845. +** Nothing.
  167846. +*/
  167847. +gceSTATUS
  167848. +gckOS_WaitSignal(
  167849. + IN gckOS Os,
  167850. + IN gctSIGNAL Signal,
  167851. + IN gctUINT32 Wait
  167852. + )
  167853. +{
  167854. + gceSTATUS status = gcvSTATUS_OK;
  167855. + gcsSIGNAL_PTR signal;
  167856. +
  167857. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Wait=0x%08X", Os, Signal, Wait);
  167858. +
  167859. + /* Verify the arguments. */
  167860. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167861. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  167862. +
  167863. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  167864. +
  167865. + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
  167866. +
  167867. + might_sleep();
  167868. +
  167869. + spin_lock_irq(&signal->obj.wait.lock);
  167870. +
  167871. + if (signal->obj.done)
  167872. + {
  167873. + if (!signal->manualReset)
  167874. + {
  167875. + signal->obj.done = 0;
  167876. + }
  167877. +
  167878. + status = gcvSTATUS_OK;
  167879. + }
  167880. + else if (Wait == 0)
  167881. + {
  167882. + status = gcvSTATUS_TIMEOUT;
  167883. + }
  167884. + else
  167885. + {
  167886. + /* Convert wait to milliseconds. */
  167887. +#if gcdDETECT_TIMEOUT
  167888. + gctINT timeout = (Wait == gcvINFINITE)
  167889. + ? gcdINFINITE_TIMEOUT * HZ / 1000
  167890. + : Wait * HZ / 1000;
  167891. +
  167892. + gctUINT complained = 0;
  167893. +#else
  167894. + gctINT timeout = (Wait == gcvINFINITE)
  167895. + ? MAX_SCHEDULE_TIMEOUT
  167896. + : Wait * HZ / 1000;
  167897. +#endif
  167898. +
  167899. + DECLARE_WAITQUEUE(wait, current);
  167900. + wait.flags |= WQ_FLAG_EXCLUSIVE;
  167901. + __add_wait_queue_tail(&signal->obj.wait, &wait);
  167902. +
  167903. + while (gcvTRUE)
  167904. + {
  167905. + if (signal_pending(current))
  167906. + {
  167907. + /* Interrupt received. */
  167908. + status = gcvSTATUS_INTERRUPTED;
  167909. + break;
  167910. + }
  167911. +
  167912. + __set_current_state(TASK_INTERRUPTIBLE);
  167913. + spin_unlock_irq(&signal->obj.wait.lock);
  167914. + timeout = schedule_timeout(timeout);
  167915. + spin_lock_irq(&signal->obj.wait.lock);
  167916. +
  167917. + if (signal->obj.done)
  167918. + {
  167919. + if (!signal->manualReset)
  167920. + {
  167921. + signal->obj.done = 0;
  167922. + }
  167923. +
  167924. + status = gcvSTATUS_OK;
  167925. + break;
  167926. + }
  167927. +
  167928. +#if gcdDETECT_TIMEOUT
  167929. + if ((Wait == gcvINFINITE) && (timeout == 0))
  167930. + {
  167931. + gctUINT32 dmaAddress1, dmaAddress2;
  167932. + gctUINT32 dmaState1, dmaState2;
  167933. +
  167934. + dmaState1 = dmaState2 =
  167935. + dmaAddress1 = dmaAddress2 = 0;
  167936. +
  167937. + /* Verify whether DMA is running. */
  167938. + gcmkVERIFY_OK(_VerifyDMA(
  167939. + Os, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
  167940. + ));
  167941. +
  167942. +#if gcdDETECT_DMA_ADDRESS
  167943. + /* Dump only if DMA appears stuck. */
  167944. + if (
  167945. + (dmaAddress1 == dmaAddress2)
  167946. +#if gcdDETECT_DMA_STATE
  167947. + && (dmaState1 == dmaState2)
  167948. +#endif
  167949. + )
  167950. +#endif
  167951. + {
  167952. + /* Increment complain count. */
  167953. + complained += 1;
  167954. +
  167955. + gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR));
  167956. +
  167957. + gcmkPRINT(
  167958. + "%s(%d): signal 0x%X; forced message flush (%d).",
  167959. + __FUNCTION__, __LINE__, Signal, complained
  167960. + );
  167961. +
  167962. + /* Flush the debug cache. */
  167963. + gcmkDEBUGFLUSH(dmaAddress2);
  167964. + }
  167965. +
  167966. + /* Reset timeout. */
  167967. + timeout = gcdINFINITE_TIMEOUT * HZ / 1000;
  167968. + }
  167969. +#endif
  167970. +
  167971. + if (timeout == 0)
  167972. + {
  167973. +
  167974. + status = gcvSTATUS_TIMEOUT;
  167975. + break;
  167976. + }
  167977. + }
  167978. +
  167979. + __remove_wait_queue(&signal->obj.wait, &wait);
  167980. +
  167981. +#if gcdDETECT_TIMEOUT
  167982. + if (complained)
  167983. + {
  167984. + gcmkPRINT(
  167985. + "%s(%d): signal=0x%X; waiting done; status=%d",
  167986. + __FUNCTION__, __LINE__, Signal, status
  167987. + );
  167988. + }
  167989. +#endif
  167990. + }
  167991. +
  167992. + spin_unlock_irq(&signal->obj.wait.lock);
  167993. +
  167994. +OnError:
  167995. + /* Return status. */
  167996. + gcmkFOOTER_ARG("Signal=0x%X status=%d", Signal, status);
  167997. + return status;
  167998. +}
  167999. +
  168000. +/*******************************************************************************
  168001. +**
  168002. +** gckOS_MapSignal
  168003. +**
  168004. +** Map a signal in to the current process space.
  168005. +**
  168006. +** INPUT:
  168007. +**
  168008. +** gckOS Os
  168009. +** Pointer to an gckOS object.
  168010. +**
  168011. +** gctSIGNAL Signal
  168012. +** Pointer to tha gctSIGNAL to map.
  168013. +**
  168014. +** gctHANDLE Process
  168015. +** Handle of process owning the signal.
  168016. +**
  168017. +** OUTPUT:
  168018. +**
  168019. +** gctSIGNAL * MappedSignal
  168020. +** Pointer to a variable receiving the mapped gctSIGNAL.
  168021. +*/
  168022. +gceSTATUS
  168023. +gckOS_MapSignal(
  168024. + IN gckOS Os,
  168025. + IN gctSIGNAL Signal,
  168026. + IN gctHANDLE Process,
  168027. + OUT gctSIGNAL * MappedSignal
  168028. + )
  168029. +{
  168030. + gceSTATUS status;
  168031. + gcsSIGNAL_PTR signal;
  168032. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=0x%X", Os, Signal, Process);
  168033. +
  168034. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  168035. + gcmkVERIFY_ARGUMENT(MappedSignal != gcvNULL);
  168036. +
  168037. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  168038. +
  168039. + if(atomic_inc_return(&signal->ref) <= 1)
  168040. + {
  168041. + /* The previous value is 0, it has been deleted. */
  168042. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  168043. + }
  168044. +
  168045. + *MappedSignal = (gctSIGNAL) Signal;
  168046. +
  168047. + /* Success. */
  168048. + gcmkFOOTER_ARG("*MappedSignal=0x%X", *MappedSignal);
  168049. + return gcvSTATUS_OK;
  168050. +
  168051. +OnError:
  168052. + gcmkFOOTER_NO();
  168053. + return status;
  168054. +}
  168055. +
  168056. +/*******************************************************************************
  168057. +**
  168058. +** gckOS_UnmapSignal
  168059. +**
  168060. +** Unmap a signal .
  168061. +**
  168062. +** INPUT:
  168063. +**
  168064. +** gckOS Os
  168065. +** Pointer to an gckOS object.
  168066. +**
  168067. +** gctSIGNAL Signal
  168068. +** Pointer to that gctSIGNAL mapped.
  168069. +*/
  168070. +gceSTATUS
  168071. +gckOS_UnmapSignal(
  168072. + IN gckOS Os,
  168073. + IN gctSIGNAL Signal
  168074. + )
  168075. +{
  168076. + return gckOS_DestroySignal(Os, Signal);
  168077. +}
  168078. +
  168079. +/*******************************************************************************
  168080. +**
  168081. +** gckOS_CreateUserSignal
  168082. +**
  168083. +** Create a new signal to be used in the user space.
  168084. +**
  168085. +** INPUT:
  168086. +**
  168087. +** gckOS Os
  168088. +** Pointer to an gckOS object.
  168089. +**
  168090. +** gctBOOL ManualReset
  168091. +** If set to gcvTRUE, gckOS_Signal with gcvFALSE must be called in
  168092. +** order to set the signal to nonsignaled state.
  168093. +** If set to gcvFALSE, the signal will automatically be set to
  168094. +** nonsignaled state by gckOS_WaitSignal function.
  168095. +**
  168096. +** OUTPUT:
  168097. +**
  168098. +** gctINT * SignalID
  168099. +** Pointer to a variable receiving the created signal's ID.
  168100. +*/
  168101. +gceSTATUS
  168102. +gckOS_CreateUserSignal(
  168103. + IN gckOS Os,
  168104. + IN gctBOOL ManualReset,
  168105. + OUT gctINT * SignalID
  168106. + )
  168107. +{
  168108. + gceSTATUS status;
  168109. + gctSIZE_T signal;
  168110. +
  168111. + /* Create a new signal. */
  168112. + status = gckOS_CreateSignal(Os, ManualReset, (gctSIGNAL *) &signal);
  168113. + *SignalID = (gctINT) signal;
  168114. +
  168115. + return status;
  168116. +}
  168117. +
  168118. +/*******************************************************************************
  168119. +**
  168120. +** gckOS_DestroyUserSignal
  168121. +**
  168122. +** Destroy a signal to be used in the user space.
  168123. +**
  168124. +** INPUT:
  168125. +**
  168126. +** gckOS Os
  168127. +** Pointer to an gckOS object.
  168128. +**
  168129. +** gctINT SignalID
  168130. +** The signal's ID.
  168131. +**
  168132. +** OUTPUT:
  168133. +**
  168134. +** Nothing.
  168135. +*/
  168136. +gceSTATUS
  168137. +gckOS_DestroyUserSignal(
  168138. + IN gckOS Os,
  168139. + IN gctINT SignalID
  168140. + )
  168141. +{
  168142. + return gckOS_DestroySignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID);
  168143. +}
  168144. +
  168145. +/*******************************************************************************
  168146. +**
  168147. +** gckOS_WaitUserSignal
  168148. +**
  168149. +** Wait for a signal used in the user mode to become signaled.
  168150. +**
  168151. +** INPUT:
  168152. +**
  168153. +** gckOS Os
  168154. +** Pointer to an gckOS object.
  168155. +**
  168156. +** gctINT SignalID
  168157. +** Signal ID.
  168158. +**
  168159. +** gctUINT32 Wait
  168160. +** Number of milliseconds to wait.
  168161. +** Pass the value of gcvINFINITE for an infinite wait.
  168162. +**
  168163. +** OUTPUT:
  168164. +**
  168165. +** Nothing.
  168166. +*/
  168167. +gceSTATUS
  168168. +gckOS_WaitUserSignal(
  168169. + IN gckOS Os,
  168170. + IN gctINT SignalID,
  168171. + IN gctUINT32 Wait
  168172. + )
  168173. +{
  168174. + return gckOS_WaitSignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, Wait);
  168175. +}
  168176. +
  168177. +/*******************************************************************************
  168178. +**
  168179. +** gckOS_SignalUserSignal
  168180. +**
  168181. +** Set a state of the specified 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. +** SignalID.
  168190. +**
  168191. +** gctBOOL State
  168192. +** If gcvTRUE, the signal will be set to signaled state.
  168193. +** If gcvFALSE, the signal will be set to nonsignaled state.
  168194. +**
  168195. +** OUTPUT:
  168196. +**
  168197. +** Nothing.
  168198. +*/
  168199. +gceSTATUS
  168200. +gckOS_SignalUserSignal(
  168201. + IN gckOS Os,
  168202. + IN gctINT SignalID,
  168203. + IN gctBOOL State
  168204. + )
  168205. +{
  168206. + return gckOS_Signal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, State);
  168207. +}
  168208. +
  168209. +#if gcdENABLE_VG
  168210. +gceSTATUS
  168211. +gckOS_CreateSemaphoreVG(
  168212. + IN gckOS Os,
  168213. + OUT gctSEMAPHORE * Semaphore
  168214. + )
  168215. +{
  168216. + gceSTATUS status;
  168217. + struct semaphore * newSemaphore;
  168218. +
  168219. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
  168220. + /* Verify the arguments. */
  168221. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168222. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  168223. +
  168224. + do
  168225. + {
  168226. + /* Allocate the semaphore structure. */
  168227. + newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
  168228. + if (newSemaphore == gcvNULL)
  168229. + {
  168230. + gcmkERR_BREAK(gcvSTATUS_OUT_OF_MEMORY);
  168231. + }
  168232. +
  168233. + /* Initialize the semaphore. */
  168234. + sema_init(newSemaphore, 0);
  168235. +
  168236. + /* Set the handle. */
  168237. + * Semaphore = (gctSEMAPHORE) newSemaphore;
  168238. +
  168239. + /* Success. */
  168240. + status = gcvSTATUS_OK;
  168241. + }
  168242. + while (gcvFALSE);
  168243. +
  168244. + gcmkFOOTER();
  168245. + /* Return the status. */
  168246. + return status;
  168247. +}
  168248. +
  168249. +
  168250. +gceSTATUS
  168251. +gckOS_IncrementSemaphore(
  168252. + IN gckOS Os,
  168253. + IN gctSEMAPHORE Semaphore
  168254. + )
  168255. +{
  168256. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
  168257. + /* Verify the arguments. */
  168258. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168259. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  168260. +
  168261. + /* Increment the semaphore's count. */
  168262. + up((struct semaphore *) Semaphore);
  168263. +
  168264. + gcmkFOOTER_NO();
  168265. + /* Success. */
  168266. + return gcvSTATUS_OK;
  168267. +}
  168268. +
  168269. +gceSTATUS
  168270. +gckOS_DecrementSemaphore(
  168271. + IN gckOS Os,
  168272. + IN gctSEMAPHORE Semaphore
  168273. + )
  168274. +{
  168275. + gceSTATUS status;
  168276. + gctINT result;
  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. + /* Decrement the semaphore's count. If the count is zero, wait
  168286. + until it gets incremented. */
  168287. + result = down_interruptible((struct semaphore *) Semaphore);
  168288. +
  168289. + /* Signal received? */
  168290. + if (result != 0)
  168291. + {
  168292. + status = gcvSTATUS_TERMINATE;
  168293. + break;
  168294. + }
  168295. +
  168296. + /* Success. */
  168297. + status = gcvSTATUS_OK;
  168298. + }
  168299. + while (gcvFALSE);
  168300. +
  168301. + gcmkFOOTER();
  168302. + /* Return the status. */
  168303. + return status;
  168304. +}
  168305. +
  168306. +/*******************************************************************************
  168307. +**
  168308. +** gckOS_SetSignal
  168309. +**
  168310. +** Set the specified signal to signaled state.
  168311. +**
  168312. +** INPUT:
  168313. +**
  168314. +** gckOS Os
  168315. +** Pointer to the gckOS object.
  168316. +**
  168317. +** gctHANDLE Process
  168318. +** Handle of process owning the signal.
  168319. +**
  168320. +** gctSIGNAL Signal
  168321. +** Pointer to the gctSIGNAL.
  168322. +**
  168323. +** OUTPUT:
  168324. +**
  168325. +** Nothing.
  168326. +*/
  168327. +gceSTATUS
  168328. +gckOS_SetSignal(
  168329. + IN gckOS Os,
  168330. + IN gctHANDLE Process,
  168331. + IN gctSIGNAL Signal
  168332. + )
  168333. +{
  168334. + gceSTATUS status;
  168335. + gctINT result;
  168336. + struct task_struct * userTask;
  168337. + struct siginfo info;
  168338. +
  168339. + userTask = FIND_TASK_BY_PID((pid_t)(gctUINTPTR_T) Process);
  168340. +
  168341. + if (userTask != gcvNULL)
  168342. + {
  168343. + info.si_signo = 48;
  168344. + info.si_code = __SI_CODE(__SI_RT, SI_KERNEL);
  168345. + info.si_pid = 0;
  168346. + info.si_uid = 0;
  168347. + info.si_ptr = (gctPOINTER) Signal;
  168348. +
  168349. + /* Signals with numbers between 32 and 63 are real-time,
  168350. + send a real-time signal to the user process. */
  168351. + result = send_sig_info(48, &info, userTask);
  168352. +
  168353. + /* Error? */
  168354. + if (result < 0)
  168355. + {
  168356. + status = gcvSTATUS_GENERIC_IO;
  168357. +
  168358. + gcmkTRACE(
  168359. + gcvLEVEL_ERROR,
  168360. + "%s(%d): an error has occurred.\n",
  168361. + __FUNCTION__, __LINE__
  168362. + );
  168363. + }
  168364. + else
  168365. + {
  168366. + status = gcvSTATUS_OK;
  168367. + }
  168368. + }
  168369. + else
  168370. + {
  168371. + status = gcvSTATUS_GENERIC_IO;
  168372. +
  168373. + gcmkTRACE(
  168374. + gcvLEVEL_ERROR,
  168375. + "%s(%d): an error has occurred.\n",
  168376. + __FUNCTION__, __LINE__
  168377. + );
  168378. + }
  168379. +
  168380. + /* Return status. */
  168381. + return status;
  168382. +}
  168383. +
  168384. +/******************************************************************************\
  168385. +******************************** Thread Object *********************************
  168386. +\******************************************************************************/
  168387. +
  168388. +gceSTATUS
  168389. +gckOS_StartThread(
  168390. + IN gckOS Os,
  168391. + IN gctTHREADFUNC ThreadFunction,
  168392. + IN gctPOINTER ThreadParameter,
  168393. + OUT gctTHREAD * Thread
  168394. + )
  168395. +{
  168396. + gceSTATUS status;
  168397. + struct task_struct * thread;
  168398. +
  168399. + gcmkHEADER_ARG("Os=0x%X ", Os);
  168400. + /* Verify the arguments. */
  168401. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168402. + gcmkVERIFY_ARGUMENT(ThreadFunction != gcvNULL);
  168403. + gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
  168404. +
  168405. + do
  168406. + {
  168407. + /* Create the thread. */
  168408. + thread = kthread_create(
  168409. + ThreadFunction,
  168410. + ThreadParameter,
  168411. + "Vivante Kernel Thread"
  168412. + );
  168413. +
  168414. + /* Failed? */
  168415. + if (IS_ERR(thread))
  168416. + {
  168417. + status = gcvSTATUS_GENERIC_IO;
  168418. + break;
  168419. + }
  168420. +
  168421. + /* Start the thread. */
  168422. + wake_up_process(thread);
  168423. +
  168424. + /* Set the thread handle. */
  168425. + * Thread = (gctTHREAD) thread;
  168426. +
  168427. + /* Success. */
  168428. + status = gcvSTATUS_OK;
  168429. + }
  168430. + while (gcvFALSE);
  168431. +
  168432. + gcmkFOOTER();
  168433. + /* Return the status. */
  168434. + return status;
  168435. +}
  168436. +
  168437. +gceSTATUS
  168438. +gckOS_StopThread(
  168439. + IN gckOS Os,
  168440. + IN gctTHREAD Thread
  168441. + )
  168442. +{
  168443. + gcmkHEADER_ARG("Os=0x%X Thread=0x%x", Os, Thread);
  168444. + /* Verify the arguments. */
  168445. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168446. + gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
  168447. +
  168448. + /* Thread should have already been enabled to terminate. */
  168449. + kthread_stop((struct task_struct *) Thread);
  168450. +
  168451. + gcmkFOOTER_NO();
  168452. + /* Success. */
  168453. + return gcvSTATUS_OK;
  168454. +}
  168455. +
  168456. +gceSTATUS
  168457. +gckOS_VerifyThread(
  168458. + IN gckOS Os,
  168459. + IN gctTHREAD Thread
  168460. + )
  168461. +{
  168462. + gcmkHEADER_ARG("Os=0x%X Thread=0x%x", Os, Thread);
  168463. + /* Verify the arguments. */
  168464. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168465. + gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
  168466. +
  168467. + gcmkFOOTER_NO();
  168468. + /* Success. */
  168469. + return gcvSTATUS_OK;
  168470. +}
  168471. +#endif
  168472. +
  168473. +/******************************************************************************\
  168474. +******************************** Software Timer ********************************
  168475. +\******************************************************************************/
  168476. +
  168477. +void
  168478. +_TimerFunction(
  168479. + struct work_struct * work
  168480. + )
  168481. +{
  168482. + gcsOSTIMER_PTR timer = (gcsOSTIMER_PTR)work;
  168483. +
  168484. + gctTIMERFUNCTION function = timer->function;
  168485. +
  168486. + function(timer->data);
  168487. +}
  168488. +
  168489. +/*******************************************************************************
  168490. +**
  168491. +** gckOS_CreateTimer
  168492. +**
  168493. +** Create a software timer.
  168494. +**
  168495. +** INPUT:
  168496. +**
  168497. +** gckOS Os
  168498. +** Pointer to the gckOS object.
  168499. +**
  168500. +** gctTIMERFUNCTION Function.
  168501. +** Pointer to a call back function which will be called when timer is
  168502. +** expired.
  168503. +**
  168504. +** gctPOINTER Data.
  168505. +** Private data which will be passed to call back function.
  168506. +**
  168507. +** OUTPUT:
  168508. +**
  168509. +** gctPOINTER * Timer
  168510. +** Pointer to a variable receiving the created timer.
  168511. +*/
  168512. +gceSTATUS
  168513. +gckOS_CreateTimer(
  168514. + IN gckOS Os,
  168515. + IN gctTIMERFUNCTION Function,
  168516. + IN gctPOINTER Data,
  168517. + OUT gctPOINTER * Timer
  168518. + )
  168519. +{
  168520. + gceSTATUS status;
  168521. + gcsOSTIMER_PTR pointer;
  168522. + gcmkHEADER_ARG("Os=0x%X Function=0x%X Data=0x%X", Os, Function, Data);
  168523. +
  168524. + /* Verify the arguments. */
  168525. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168526. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  168527. +
  168528. + gcmkONERROR(gckOS_Allocate(Os, sizeof(gcsOSTIMER), (gctPOINTER)&pointer));
  168529. +
  168530. + pointer->function = Function;
  168531. + pointer->data = Data;
  168532. +
  168533. + INIT_DELAYED_WORK(&pointer->work, _TimerFunction);
  168534. +
  168535. + *Timer = pointer;
  168536. +
  168537. + gcmkFOOTER_NO();
  168538. + return gcvSTATUS_OK;
  168539. +
  168540. +OnError:
  168541. + gcmkFOOTER();
  168542. + return status;
  168543. +}
  168544. +
  168545. +/*******************************************************************************
  168546. +**
  168547. +** gckOS_DestroyTimer
  168548. +**
  168549. +** Destory a software timer.
  168550. +**
  168551. +** INPUT:
  168552. +**
  168553. +** gckOS Os
  168554. +** Pointer to the gckOS object.
  168555. +**
  168556. +** gctPOINTER Timer
  168557. +** Pointer to the timer to be destoryed.
  168558. +**
  168559. +** OUTPUT:
  168560. +**
  168561. +** Nothing.
  168562. +*/
  168563. +gceSTATUS
  168564. +gckOS_DestroyTimer(
  168565. + IN gckOS Os,
  168566. + IN gctPOINTER Timer
  168567. + )
  168568. +{
  168569. + gcsOSTIMER_PTR timer;
  168570. + gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
  168571. +
  168572. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168573. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  168574. +
  168575. + timer = (gcsOSTIMER_PTR)Timer;
  168576. +
  168577. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
  168578. + cancel_delayed_work_sync(&timer->work);
  168579. +#else
  168580. + cancel_delayed_work(&timer->work);
  168581. + flush_workqueue(Os->workqueue);
  168582. +#endif
  168583. +
  168584. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, Timer));
  168585. +
  168586. + gcmkFOOTER_NO();
  168587. + return gcvSTATUS_OK;
  168588. +}
  168589. +
  168590. +/*******************************************************************************
  168591. +**
  168592. +** gckOS_StartTimer
  168593. +**
  168594. +** Schedule a software timer.
  168595. +**
  168596. +** INPUT:
  168597. +**
  168598. +** gckOS Os
  168599. +** Pointer to the gckOS object.
  168600. +**
  168601. +** gctPOINTER Timer
  168602. +** Pointer to the timer to be scheduled.
  168603. +**
  168604. +** gctUINT32 Delay
  168605. +** Delay in milliseconds.
  168606. +**
  168607. +** OUTPUT:
  168608. +**
  168609. +** Nothing.
  168610. +*/
  168611. +gceSTATUS
  168612. +gckOS_StartTimer(
  168613. + IN gckOS Os,
  168614. + IN gctPOINTER Timer,
  168615. + IN gctUINT32 Delay
  168616. + )
  168617. +{
  168618. + gcsOSTIMER_PTR timer;
  168619. +
  168620. + gcmkHEADER_ARG("Os=0x%X Timer=0x%X Delay=%u", Os, Timer, Delay);
  168621. +
  168622. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168623. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  168624. + gcmkVERIFY_ARGUMENT(Delay != 0);
  168625. +
  168626. + timer = (gcsOSTIMER_PTR)Timer;
  168627. +
  168628. + if (unlikely(delayed_work_pending(&timer->work)))
  168629. + {
  168630. + if (unlikely(!cancel_delayed_work(&timer->work)))
  168631. + {
  168632. + cancel_work_sync(&timer->work.work);
  168633. +
  168634. + if (unlikely(delayed_work_pending(&timer->work)))
  168635. + {
  168636. + gckOS_Print("gckOS_StartTimer error, the pending worker cannot complete!!!! \n");
  168637. +
  168638. + return gcvSTATUS_INVALID_REQUEST;
  168639. + }
  168640. + }
  168641. + }
  168642. +
  168643. + queue_delayed_work(Os->workqueue, &timer->work, msecs_to_jiffies(Delay));
  168644. +
  168645. + gcmkFOOTER_NO();
  168646. + return gcvSTATUS_OK;
  168647. +}
  168648. +
  168649. +/*******************************************************************************
  168650. +**
  168651. +** gckOS_StopTimer
  168652. +**
  168653. +** Cancel a unscheduled 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 cancel.
  168662. +**
  168663. +** OUTPUT:
  168664. +**
  168665. +** Nothing.
  168666. +*/
  168667. +gceSTATUS
  168668. +gckOS_StopTimer(
  168669. + IN gckOS Os,
  168670. + IN gctPOINTER Timer
  168671. + )
  168672. +{
  168673. + gcsOSTIMER_PTR timer;
  168674. + gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
  168675. +
  168676. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168677. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  168678. +
  168679. + timer = (gcsOSTIMER_PTR)Timer;
  168680. +
  168681. + cancel_delayed_work(&timer->work);
  168682. +
  168683. + gcmkFOOTER_NO();
  168684. + return gcvSTATUS_OK;
  168685. +}
  168686. +
  168687. +
  168688. +gceSTATUS
  168689. +gckOS_DumpCallStack(
  168690. + IN gckOS Os
  168691. + )
  168692. +{
  168693. + gcmkHEADER_ARG("Os=0x%X", Os);
  168694. +
  168695. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168696. +
  168697. + dump_stack();
  168698. +
  168699. + gcmkFOOTER_NO();
  168700. + return gcvSTATUS_OK;
  168701. +}
  168702. +
  168703. +
  168704. +gceSTATUS
  168705. +gckOS_GetProcessNameByPid(
  168706. + IN gctINT Pid,
  168707. + IN gctSIZE_T Length,
  168708. + OUT gctUINT8_PTR String
  168709. + )
  168710. +{
  168711. + struct task_struct *task;
  168712. +
  168713. + /* Get the task_struct of the task with pid. */
  168714. + rcu_read_lock();
  168715. +
  168716. + task = FIND_TASK_BY_PID(Pid);
  168717. +
  168718. + if (task == gcvNULL)
  168719. + {
  168720. + rcu_read_unlock();
  168721. + return gcvSTATUS_NOT_FOUND;
  168722. + }
  168723. +
  168724. + /* Get name of process. */
  168725. + strncpy(String, task->comm, Length);
  168726. +
  168727. + rcu_read_unlock();
  168728. +
  168729. + return gcvSTATUS_OK;
  168730. +}
  168731. +
  168732. +#if gcdANDROID_NATIVE_FENCE_SYNC
  168733. +
  168734. +gceSTATUS
  168735. +gckOS_CreateSyncPoint(
  168736. + IN gckOS Os,
  168737. + OUT gctSYNC_POINT * SyncPoint
  168738. + )
  168739. +{
  168740. + gceSTATUS status;
  168741. + gcsSYNC_POINT_PTR syncPoint;
  168742. +
  168743. + gcmkHEADER_ARG("Os=0x%X", Os);
  168744. +
  168745. + /* Verify the arguments. */
  168746. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168747. +
  168748. + /* Create an sync point structure. */
  168749. + syncPoint = (gcsSYNC_POINT_PTR) kmalloc(
  168750. + sizeof(gcsSYNC_POINT), GFP_KERNEL | gcdNOWARN);
  168751. +
  168752. + if (syncPoint == gcvNULL)
  168753. + {
  168754. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  168755. + }
  168756. +
  168757. + /* Initialize the sync point. */
  168758. + atomic_set(&syncPoint->ref, 1);
  168759. + atomic_set(&syncPoint->state, 0);
  168760. +
  168761. + gcmkONERROR(_AllocateIntegerId(&Os->syncPointDB, syncPoint, &syncPoint->id));
  168762. +
  168763. + *SyncPoint = (gctSYNC_POINT)(gctUINTPTR_T)syncPoint->id;
  168764. +
  168765. + gcmkFOOTER_ARG("*SyncPonint=%d", syncPoint->id);
  168766. + return gcvSTATUS_OK;
  168767. +
  168768. +OnError:
  168769. + if (syncPoint != gcvNULL)
  168770. + {
  168771. + kfree(syncPoint);
  168772. + }
  168773. +
  168774. + gcmkFOOTER();
  168775. + return status;
  168776. +}
  168777. +
  168778. +gceSTATUS
  168779. +gckOS_ReferenceSyncPoint(
  168780. + IN gckOS Os,
  168781. + IN gctSYNC_POINT SyncPoint
  168782. + )
  168783. +{
  168784. + gceSTATUS status;
  168785. + gcsSYNC_POINT_PTR syncPoint;
  168786. +
  168787. + gcmkHEADER_ARG("Os=0x%X", Os);
  168788. +
  168789. + /* Verify the arguments. */
  168790. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168791. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  168792. +
  168793. + gcmkONERROR(
  168794. + _QueryIntegerId(&Os->syncPointDB,
  168795. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  168796. + (gctPOINTER)&syncPoint));
  168797. +
  168798. + /* Initialize the sync point. */
  168799. + atomic_inc(&syncPoint->ref);
  168800. +
  168801. + gcmkFOOTER_NO();
  168802. + return gcvSTATUS_OK;
  168803. +
  168804. +OnError:
  168805. + gcmkFOOTER();
  168806. + return status;
  168807. +}
  168808. +
  168809. +gceSTATUS
  168810. +gckOS_DestroySyncPoint(
  168811. + IN gckOS Os,
  168812. + IN gctSYNC_POINT SyncPoint
  168813. + )
  168814. +{
  168815. + gceSTATUS status;
  168816. + gcsSYNC_POINT_PTR syncPoint;
  168817. + gctBOOL acquired = gcvFALSE;
  168818. +
  168819. + gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168820. +
  168821. + /* Verify the arguments. */
  168822. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168823. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  168824. +
  168825. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->syncPointMutex, gcvINFINITE));
  168826. + acquired = gcvTRUE;
  168827. +
  168828. + gcmkONERROR(
  168829. + _QueryIntegerId(&Os->syncPointDB,
  168830. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  168831. + (gctPOINTER)&syncPoint));
  168832. +
  168833. + gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168834. +
  168835. + if (atomic_dec_and_test(&syncPoint->ref))
  168836. + {
  168837. + gcmkVERIFY_OK(_DestroyIntegerId(&Os->syncPointDB, syncPoint->id));
  168838. +
  168839. + /* Free the sgianl. */
  168840. + syncPoint->timeline = gcvNULL;
  168841. + kfree(syncPoint);
  168842. + }
  168843. +
  168844. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  168845. + acquired = gcvFALSE;
  168846. +
  168847. + /* Success. */
  168848. + gcmkFOOTER_NO();
  168849. + return gcvSTATUS_OK;
  168850. +
  168851. +OnError:
  168852. + if (acquired)
  168853. + {
  168854. + /* Release the mutex. */
  168855. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  168856. + }
  168857. +
  168858. + gcmkFOOTER();
  168859. + return status;
  168860. +}
  168861. +
  168862. +gceSTATUS
  168863. +gckOS_SignalSyncPoint(
  168864. + IN gckOS Os,
  168865. + IN gctSYNC_POINT SyncPoint
  168866. + )
  168867. +{
  168868. + gceSTATUS status;
  168869. + gcsSYNC_POINT_PTR syncPoint;
  168870. + gctBOOL acquired = gcvFALSE;
  168871. +
  168872. + gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168873. +
  168874. + /* Verify the arguments. */
  168875. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168876. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  168877. +
  168878. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->syncPointMutex, gcvINFINITE));
  168879. + acquired = gcvTRUE;
  168880. +
  168881. + gcmkONERROR(
  168882. + _QueryIntegerId(&Os->syncPointDB,
  168883. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  168884. + (gctPOINTER)&syncPoint));
  168885. +
  168886. + gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168887. +
  168888. + /* Get state. */
  168889. + atomic_set(&syncPoint->state, gcvTRUE);
  168890. +
  168891. + /* Signal timeline. */
  168892. + if (syncPoint->timeline)
  168893. + {
  168894. + sync_timeline_signal(syncPoint->timeline);
  168895. + }
  168896. +
  168897. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  168898. + acquired = gcvFALSE;
  168899. +
  168900. + /* Success. */
  168901. + gcmkFOOTER_NO();
  168902. + return gcvSTATUS_OK;
  168903. +
  168904. +OnError:
  168905. + if (acquired)
  168906. + {
  168907. + /* Release the mutex. */
  168908. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  168909. + }
  168910. +
  168911. + gcmkFOOTER();
  168912. + return status;
  168913. +}
  168914. +
  168915. +gceSTATUS
  168916. +gckOS_QuerySyncPoint(
  168917. + IN gckOS Os,
  168918. + IN gctSYNC_POINT SyncPoint,
  168919. + OUT gctBOOL_PTR State
  168920. + )
  168921. +{
  168922. + gceSTATUS status;
  168923. + gcsSYNC_POINT_PTR syncPoint;
  168924. +
  168925. + gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168926. +
  168927. + /* Verify the arguments. */
  168928. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168929. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  168930. +
  168931. + gcmkONERROR(
  168932. + _QueryIntegerId(&Os->syncPointDB,
  168933. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  168934. + (gctPOINTER)&syncPoint));
  168935. +
  168936. + gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
  168937. +
  168938. + /* Get state. */
  168939. + *State = atomic_read(&syncPoint->state);
  168940. +
  168941. + /* Success. */
  168942. + gcmkFOOTER_ARG("*State=%d", *State);
  168943. + return gcvSTATUS_OK;
  168944. +
  168945. +OnError:
  168946. + gcmkFOOTER();
  168947. + return status;
  168948. +}
  168949. +
  168950. +gceSTATUS
  168951. +gckOS_CreateSyncTimeline(
  168952. + IN gckOS Os,
  168953. + OUT gctHANDLE * Timeline
  168954. + )
  168955. +{
  168956. + struct viv_sync_timeline * timeline;
  168957. +
  168958. + /* Create viv sync timeline. */
  168959. + timeline = viv_sync_timeline_create("viv timeline", Os);
  168960. +
  168961. + if (timeline == gcvNULL)
  168962. + {
  168963. + /* Out of memory. */
  168964. + return gcvSTATUS_OUT_OF_MEMORY;
  168965. + }
  168966. +
  168967. + *Timeline = (gctHANDLE) timeline;
  168968. + return gcvSTATUS_OK;
  168969. +}
  168970. +
  168971. +gceSTATUS
  168972. +gckOS_DestroySyncTimeline(
  168973. + IN gckOS Os,
  168974. + IN gctHANDLE Timeline
  168975. + )
  168976. +{
  168977. + struct viv_sync_timeline * timeline;
  168978. + gcmkASSERT(Timeline != gcvNULL);
  168979. +
  168980. + /* Destroy timeline. */
  168981. + timeline = (struct viv_sync_timeline *) Timeline;
  168982. + sync_timeline_destroy(&timeline->obj);
  168983. +
  168984. + return gcvSTATUS_OK;
  168985. +}
  168986. +
  168987. +gceSTATUS
  168988. +gckOS_CreateNativeFence(
  168989. + IN gckOS Os,
  168990. + IN gctHANDLE Timeline,
  168991. + IN gctSYNC_POINT SyncPoint,
  168992. + OUT gctINT * FenceFD
  168993. + )
  168994. +{
  168995. + int fd = -1;
  168996. + struct viv_sync_timeline *timeline;
  168997. + struct sync_pt * pt = gcvNULL;
  168998. + struct sync_fence * fence;
  168999. + char name[32];
  169000. + gcsSYNC_POINT_PTR syncPoint;
  169001. + gceSTATUS status;
  169002. +
  169003. + gcmkHEADER_ARG("Os=0x%X Timeline=0x%X SyncPoint=%d",
  169004. + Os, Timeline, (gctUINT)(gctUINTPTR_T)SyncPoint);
  169005. +
  169006. + gcmkONERROR(
  169007. + _QueryIntegerId(&Os->syncPointDB,
  169008. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  169009. + (gctPOINTER)&syncPoint));
  169010. +
  169011. + /* Cast timeline. */
  169012. + timeline = (struct viv_sync_timeline *) Timeline;
  169013. +
  169014. + fd = get_unused_fd();
  169015. +
  169016. + if (fd < 0)
  169017. + {
  169018. + /* Out of resources. */
  169019. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  169020. + }
  169021. +
  169022. + /* Create viv_sync_pt. */
  169023. + pt = viv_sync_pt_create(timeline, SyncPoint);
  169024. +
  169025. + if (pt == gcvNULL)
  169026. + {
  169027. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  169028. + }
  169029. +
  169030. + /* Reference sync_timeline. */
  169031. + syncPoint->timeline = &timeline->obj;
  169032. +
  169033. + /* Build fence name. */
  169034. + snprintf(name, 32, "viv sync_fence-%u", (gctUINT)(gctUINTPTR_T)SyncPoint);
  169035. +
  169036. + /* Create sync_fence. */
  169037. + fence = sync_fence_create(name, pt);
  169038. +
  169039. + if (fence == NULL)
  169040. + {
  169041. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  169042. + }
  169043. +
  169044. + /* Install fence to fd. */
  169045. + sync_fence_install(fence, fd);
  169046. +
  169047. + *FenceFD = fd;
  169048. + gcmkFOOTER_ARG("*FenceFD=%d", fd);
  169049. + return gcvSTATUS_OK;
  169050. +
  169051. +OnError:
  169052. + /* Error roll back. */
  169053. + if (pt)
  169054. + {
  169055. + sync_pt_free(pt);
  169056. + }
  169057. +
  169058. + if (fd > 0)
  169059. + {
  169060. + put_unused_fd(fd);
  169061. + }
  169062. +
  169063. + gcmkFOOTER();
  169064. + return status;
  169065. +}
  169066. +#endif
  169067. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
  169068. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h 1969-12-31 18:00:00.000000000 -0600
  169069. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h 2014-12-08 00:31:53.472418001 -0600
  169070. @@ -0,0 +1,83 @@
  169071. +/****************************************************************************
  169072. +*
  169073. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  169074. +*
  169075. +* This program is free software; you can redistribute it and/or modify
  169076. +* it under the terms of the GNU General Public License as published by
  169077. +* the Free Software Foundation; either version 2 of the license, or
  169078. +* (at your option) any later version.
  169079. +*
  169080. +* This program is distributed in the hope that it will be useful,
  169081. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  169082. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  169083. +* GNU General Public License for more details.
  169084. +*
  169085. +* You should have received a copy of the GNU General Public License
  169086. +* along with this program; if not write to the Free Software
  169087. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  169088. +*
  169089. +*****************************************************************************/
  169090. +
  169091. +
  169092. +#ifndef __gc_hal_kernel_os_h_
  169093. +#define __gc_hal_kernel_os_h_
  169094. +
  169095. +typedef struct _LINUX_MDL_MAP
  169096. +{
  169097. + gctINT pid;
  169098. + gctPOINTER vmaAddr;
  169099. + gctUINT32 count;
  169100. + struct vm_area_struct * vma;
  169101. + struct _LINUX_MDL_MAP * next;
  169102. +}
  169103. +LINUX_MDL_MAP;
  169104. +
  169105. +typedef struct _LINUX_MDL_MAP * PLINUX_MDL_MAP;
  169106. +
  169107. +typedef struct _LINUX_MDL
  169108. +{
  169109. + gctINT pid;
  169110. + char * addr;
  169111. +
  169112. + union _pages
  169113. + {
  169114. + /* Pointer to a array of pages. */
  169115. + struct page * contiguousPages;
  169116. + /* Pointer to a array of pointers to page. */
  169117. + struct page ** nonContiguousPages;
  169118. + }
  169119. + u;
  169120. +
  169121. +#ifdef NO_DMA_COHERENT
  169122. + gctPOINTER kaddr;
  169123. +#endif /* NO_DMA_COHERENT */
  169124. +
  169125. + gctINT numPages;
  169126. + gctINT pagedMem;
  169127. + gctBOOL contiguous;
  169128. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  169129. + gctBOOL exact;
  169130. +#endif
  169131. + dma_addr_t dmaHandle;
  169132. + PLINUX_MDL_MAP maps;
  169133. + struct _LINUX_MDL * prev;
  169134. + struct _LINUX_MDL * next;
  169135. +}
  169136. +LINUX_MDL, *PLINUX_MDL;
  169137. +
  169138. +extern PLINUX_MDL_MAP
  169139. +FindMdlMap(
  169140. + IN PLINUX_MDL Mdl,
  169141. + IN gctINT PID
  169142. + );
  169143. +
  169144. +typedef struct _DRIVER_ARGS
  169145. +{
  169146. + gctUINT64 InputBuffer;
  169147. + gctUINT64 InputBufferSize;
  169148. + gctUINT64 OutputBuffer;
  169149. + gctUINT64 OutputBufferSize;
  169150. +}
  169151. +DRIVER_ARGS;
  169152. +
  169153. +#endif /* __gc_hal_kernel_os_h_ */
  169154. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
  169155. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c 1969-12-31 18:00:00.000000000 -0600
  169156. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c 2014-12-08 00:31:53.472418001 -0600
  169157. @@ -0,0 +1,174 @@
  169158. +/****************************************************************************
  169159. +*
  169160. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  169161. +*
  169162. +* This program is free software; you can redistribute it and/or modify
  169163. +* it under the terms of the GNU General Public License as published by
  169164. +* the Free Software Foundation; either version 2 of the license, or
  169165. +* (at your option) any later version.
  169166. +*
  169167. +* This program is distributed in the hope that it will be useful,
  169168. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  169169. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  169170. +* GNU General Public License for more details.
  169171. +*
  169172. +* You should have received a copy of the GNU General Public License
  169173. +* along with this program; if not write to the Free Software
  169174. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  169175. +*
  169176. +*****************************************************************************/
  169177. +
  169178. +
  169179. +#include <linux/kernel.h>
  169180. +#include <linux/file.h>
  169181. +#include <linux/fs.h>
  169182. +#include <linux/miscdevice.h>
  169183. +#include <linux/module.h>
  169184. +#include <linux/syscalls.h>
  169185. +#include <linux/uaccess.h>
  169186. +
  169187. +#include "gc_hal_kernel_sync.h"
  169188. +
  169189. +#if gcdANDROID_NATIVE_FENCE_SYNC
  169190. +
  169191. +static struct sync_pt *
  169192. +viv_sync_pt_dup(
  169193. + struct sync_pt * sync_pt
  169194. + )
  169195. +{
  169196. + gceSTATUS status;
  169197. + struct viv_sync_pt *pt;
  169198. + struct viv_sync_pt *src;
  169199. + struct viv_sync_timeline *obj;
  169200. +
  169201. + src = (struct viv_sync_pt *) sync_pt;
  169202. + obj = (struct viv_sync_timeline *) sync_pt->parent;
  169203. +
  169204. + /* Create the new sync_pt. */
  169205. + pt = (struct viv_sync_pt *)
  169206. + sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt));
  169207. +
  169208. + pt->stamp = src->stamp;
  169209. + pt->sync = src->sync;
  169210. +
  169211. + /* Reference sync point. */
  169212. + status = gckOS_ReferenceSyncPoint(obj->os, pt->sync);
  169213. +
  169214. + if (gcmIS_ERROR(status))
  169215. + {
  169216. + sync_pt_free((struct sync_pt *)pt);
  169217. + return NULL;
  169218. + }
  169219. +
  169220. + return (struct sync_pt *)pt;
  169221. +}
  169222. +
  169223. +static int
  169224. +viv_sync_pt_has_signaled(
  169225. + struct sync_pt * sync_pt
  169226. + )
  169227. +{
  169228. + gceSTATUS status;
  169229. + gctBOOL state;
  169230. + struct viv_sync_pt * pt;
  169231. + struct viv_sync_timeline * obj;
  169232. +
  169233. + pt = (struct viv_sync_pt *)sync_pt;
  169234. + obj = (struct viv_sync_timeline *)sync_pt->parent;
  169235. +
  169236. + status = gckOS_QuerySyncPoint(obj->os, pt->sync, &state);
  169237. +
  169238. + if (gcmIS_ERROR(status))
  169239. + {
  169240. + /* Error. */
  169241. + return -1;
  169242. + }
  169243. +
  169244. + return state;
  169245. +}
  169246. +
  169247. +static int
  169248. +viv_sync_pt_compare(
  169249. + struct sync_pt * a,
  169250. + struct sync_pt * b
  169251. + )
  169252. +{
  169253. + int ret;
  169254. + struct viv_sync_pt * pt1 = (struct viv_sync_pt *) a;
  169255. + struct viv_sync_pt * pt2 = (struct viv_sync_pt *) b;
  169256. +
  169257. + ret = (pt1->stamp < pt2->stamp) ? -1
  169258. + : (pt1->stamp == pt2->stamp) ? 0
  169259. + : 1;
  169260. +
  169261. + return ret;
  169262. +}
  169263. +
  169264. +static void
  169265. +viv_sync_pt_free(
  169266. + struct sync_pt * sync_pt
  169267. + )
  169268. +{
  169269. + struct viv_sync_pt * pt;
  169270. + struct viv_sync_timeline * obj;
  169271. +
  169272. + pt = (struct viv_sync_pt *) sync_pt;
  169273. + obj = (struct viv_sync_timeline *) sync_pt->parent;
  169274. +
  169275. + gckOS_DestroySyncPoint(obj->os, pt->sync);
  169276. +}
  169277. +
  169278. +static struct sync_timeline_ops viv_timeline_ops =
  169279. +{
  169280. + .driver_name = "viv_sync",
  169281. + .dup = viv_sync_pt_dup,
  169282. + .has_signaled = viv_sync_pt_has_signaled,
  169283. + .compare = viv_sync_pt_compare,
  169284. + .free_pt = viv_sync_pt_free,
  169285. +};
  169286. +
  169287. +struct viv_sync_timeline *
  169288. +viv_sync_timeline_create(
  169289. + const char * name,
  169290. + gckOS os
  169291. + )
  169292. +{
  169293. + struct viv_sync_timeline * obj;
  169294. +
  169295. + obj = (struct viv_sync_timeline *)
  169296. + sync_timeline_create(&viv_timeline_ops, sizeof(struct viv_sync_timeline), name);
  169297. +
  169298. + obj->os = os;
  169299. + obj->stamp = 0;
  169300. +
  169301. + return obj;
  169302. +}
  169303. +
  169304. +struct sync_pt *
  169305. +viv_sync_pt_create(
  169306. + struct viv_sync_timeline * obj,
  169307. + gctSYNC_POINT SyncPoint
  169308. + )
  169309. +{
  169310. + gceSTATUS status;
  169311. + struct viv_sync_pt * pt;
  169312. +
  169313. + pt = (struct viv_sync_pt *)
  169314. + sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt));
  169315. +
  169316. + pt->stamp = obj->stamp++;
  169317. + pt->sync = SyncPoint;
  169318. +
  169319. + /* Dup signal. */
  169320. + status = gckOS_ReferenceSyncPoint(obj->os, SyncPoint);
  169321. +
  169322. + if (gcmIS_ERROR(status))
  169323. + {
  169324. + sync_pt_free((struct sync_pt *)pt);
  169325. + return NULL;
  169326. + }
  169327. +
  169328. + return (struct sync_pt *) pt;
  169329. +}
  169330. +
  169331. +#endif
  169332. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h
  169333. --- linux-3.14.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h 1969-12-31 18:00:00.000000000 -0600
  169334. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h 2014-12-08 00:31:53.472418001 -0600
  169335. @@ -0,0 +1,71 @@
  169336. +/****************************************************************************
  169337. +*
  169338. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  169339. +*
  169340. +* This program is free software; you can redistribute it and/or modify
  169341. +* it under the terms of the GNU General Public License as published by
  169342. +* the Free Software Foundation; either version 2 of the license, or
  169343. +* (at your option) any later version.
  169344. +*
  169345. +* This program is distributed in the hope that it will be useful,
  169346. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  169347. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  169348. +* GNU General Public License for more details.
  169349. +*
  169350. +* You should have received a copy of the GNU General Public License
  169351. +* along with this program; if not write to the Free Software
  169352. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  169353. +*
  169354. +*****************************************************************************/
  169355. +
  169356. +
  169357. +#ifndef __gc_hal_kernel_sync_h_
  169358. +#define __gc_hal_kernel_sync_h_
  169359. +
  169360. +#include <linux/types.h>
  169361. +
  169362. +#include <linux/sync.h>
  169363. +
  169364. +#include <gc_hal.h>
  169365. +#include <gc_hal_base.h>
  169366. +
  169367. +struct viv_sync_timeline
  169368. +{
  169369. + /* Parent object. */
  169370. + struct sync_timeline obj;
  169371. +
  169372. + /* Timestamp when sync_pt is created. */
  169373. + gctUINT stamp;
  169374. +
  169375. + /* Pointer to os struct. */
  169376. + gckOS os;
  169377. +};
  169378. +
  169379. +
  169380. +struct viv_sync_pt
  169381. +{
  169382. + /* Parent object. */
  169383. + struct sync_pt pt;
  169384. +
  169385. + /* Reference sync point*/
  169386. + gctSYNC_POINT sync;
  169387. +
  169388. + /* Timestamp when sync_pt is created. */
  169389. + gctUINT stamp;
  169390. +};
  169391. +
  169392. +/* Create viv_sync_timeline object. */
  169393. +struct viv_sync_timeline *
  169394. +viv_sync_timeline_create(
  169395. + const char * Name,
  169396. + gckOS Os
  169397. + );
  169398. +
  169399. +/* Create viv_sync_pt object. */
  169400. +struct sync_pt *
  169401. +viv_sync_pt_create(
  169402. + struct viv_sync_timeline * Obj,
  169403. + gctSYNC_POINT SyncPoint
  169404. + );
  169405. +
  169406. +#endif /* __gc_hal_kernel_sync_h_ */
  169407. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/Kbuild linux-imx6-3.14/drivers/mxc/gpu-viv/Kbuild
  169408. --- linux-3.14.14/drivers/mxc/gpu-viv/Kbuild 1969-12-31 18:00:00.000000000 -0600
  169409. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/Kbuild 2014-12-08 00:31:53.460418001 -0600
  169410. @@ -0,0 +1,236 @@
  169411. +##############################################################################
  169412. +#
  169413. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  169414. +#
  169415. +# This program is free software; you can redistribute it and/or modify
  169416. +# it under the terms of the GNU General Public License as published by
  169417. +# the Free Software Foundation; either version 2 of the license, or
  169418. +# (at your option) any later version.
  169419. +#
  169420. +# This program is distributed in the hope that it will be useful,
  169421. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  169422. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  169423. +# GNU General Public License for more details.
  169424. +#
  169425. +# You should have received a copy of the GNU General Public License
  169426. +# along with this program; if not write to the Free Software
  169427. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  169428. +#
  169429. +##############################################################################
  169430. +
  169431. +
  169432. +#
  169433. +# Linux build file for kernel HAL driver.
  169434. +#
  169435. +
  169436. +AQROOT := $(srctree)/drivers/mxc/gpu-viv
  169437. +AQARCH := $(AQROOT)/arch/XAQ2
  169438. +AQVGARCH := $(AQROOT)/arch/GC350
  169439. +
  169440. +include $(AQROOT)/config
  169441. +
  169442. +KERNEL_DIR ?= $(TOOL_DIR)/kernel
  169443. +
  169444. +OS_KERNEL_DIR := hal/os/linux/kernel
  169445. +ARCH_KERNEL_DIR := arch/$(notdir $(AQARCH))/hal/kernel
  169446. +ARCH_VG_KERNEL_DIR := arch/$(notdir $(AQVGARCH))/hal/kernel
  169447. +HAL_KERNEL_DIR := hal/kernel
  169448. +
  169449. +# EXTRA_CFLAGS += -Werror
  169450. +
  169451. +OBJS := $(OS_KERNEL_DIR)/gc_hal_kernel_device.o \
  169452. + $(OS_KERNEL_DIR)/gc_hal_kernel_driver.o \
  169453. + $(OS_KERNEL_DIR)/gc_hal_kernel_linux.o \
  169454. + $(OS_KERNEL_DIR)/gc_hal_kernel_math.o \
  169455. + $(OS_KERNEL_DIR)/gc_hal_kernel_os.o \
  169456. + $(OS_KERNEL_DIR)/gc_hal_kernel_debugfs.o
  169457. +
  169458. +OBJS += $(HAL_KERNEL_DIR)/gc_hal_kernel.o \
  169459. + $(HAL_KERNEL_DIR)/gc_hal_kernel_command.o \
  169460. + $(HAL_KERNEL_DIR)/gc_hal_kernel_db.o \
  169461. + $(HAL_KERNEL_DIR)/gc_hal_kernel_debug.o \
  169462. + $(HAL_KERNEL_DIR)/gc_hal_kernel_event.o \
  169463. + $(HAL_KERNEL_DIR)/gc_hal_kernel_heap.o \
  169464. + $(HAL_KERNEL_DIR)/gc_hal_kernel_mmu.o \
  169465. + $(HAL_KERNEL_DIR)/gc_hal_kernel_video_memory.o \
  169466. + $(HAL_KERNEL_DIR)/gc_hal_kernel_power.o
  169467. +
  169468. +OBJS += $(ARCH_KERNEL_DIR)/gc_hal_kernel_context.o \
  169469. + $(ARCH_KERNEL_DIR)/gc_hal_kernel_hardware.o
  169470. +
  169471. +ifeq ($(VIVANTE_ENABLE_VG), 1)
  169472. +OBJS +=\
  169473. + $(HAL_KERNEL_DIR)/gc_hal_kernel_vg.o\
  169474. + $(HAL_KERNEL_DIR)/gc_hal_kernel_command_vg.o\
  169475. + $(HAL_KERNEL_DIR)/gc_hal_kernel_interrupt_vg.o\
  169476. + $(HAL_KERNEL_DIR)/gc_hal_kernel_mmu_vg.o\
  169477. + $(ARCH_VG_KERNEL_DIR)/gc_hal_kernel_hardware_command_vg.o\
  169478. + $(ARCH_VG_KERNEL_DIR)/gc_hal_kernel_hardware_vg.o
  169479. +endif
  169480. +
  169481. +ifneq ($(CONFIG_SYNC),)
  169482. +OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_sync.o
  169483. +endif
  169484. +
  169485. +ifeq ($(KERNELRELEASE), )
  169486. +
  169487. +.PHONY: all clean install
  169488. +
  169489. +# Define targets.
  169490. +all:
  169491. + @make V=$(V) ARCH=$(ARCH_TYPE) -C $(KERNEL_DIR) SUBDIRS=`pwd` modules
  169492. +
  169493. +clean:
  169494. + @rm -rf $(OBJS)
  169495. + @rm -rf modules.order Module.symvers
  169496. + @find $(AQROOT) -name ".gc_*.cmd" | xargs rm -f
  169497. +
  169498. +install: all
  169499. + @mkdir -p $(SDK_DIR)/drivers
  169500. +
  169501. +else
  169502. +
  169503. +
  169504. +EXTRA_CFLAGS += -DLINUX -DDRIVER
  169505. +
  169506. +ifeq ($(ENUM_WORKAROUND), 1)
  169507. +EXTRA_CFLAGS += -DENUM_WORKAROUND=1
  169508. +else
  169509. +EXTRA_CFLAGS += -DENUM_WORKAROUND=0
  169510. +endif
  169511. +
  169512. +ifeq ($(FLAREON),1)
  169513. +EXTRA_CFLAGS += -DFLAREON
  169514. +endif
  169515. +
  169516. +ifeq ($(DEBUG), 1)
  169517. +EXTRA_CFLAGS += -DDBG=1 -DDEBUG -D_DEBUG
  169518. +else
  169519. +EXTRA_CFLAGS += -DDBG=0
  169520. +endif
  169521. +
  169522. +ifeq ($(NO_DMA_COHERENT), 1)
  169523. +EXTRA_CFLAGS += -DNO_DMA_COHERENT
  169524. +endif
  169525. +
  169526. +ifeq ($(CONFIG_DOVE_GPU), 1)
  169527. +EXTRA_CFLAGS += -DCONFIG_DOVE_GPU=1
  169528. +endif
  169529. +
  169530. +ifneq ($(USE_PLATFORM_DRIVER), 0)
  169531. +EXTRA_CFLAGS += -DUSE_PLATFORM_DRIVER=1
  169532. +else
  169533. +EXTRA_CFLAGS += -DUSE_PLATFORM_DRIVER=0
  169534. +endif
  169535. +
  169536. +
  169537. +EXTRA_CFLAGS += -DVIVANTE_PROFILER=1
  169538. +EXTRA_CFLAGS += -DVIVANTE_PROFILER_CONTEXT=1
  169539. +
  169540. +
  169541. +ifeq ($(ANDROID), 1)
  169542. +EXTRA_CFLAGS += -DANDROID=1
  169543. +endif
  169544. +
  169545. +ifeq ($(ENABLE_GPU_CLOCK_BY_DRIVER), 1)
  169546. +EXTRA_CFLAGS += -DENABLE_GPU_CLOCK_BY_DRIVER=1
  169547. +else
  169548. +EXTRA_CFLAGS += -DENABLE_GPU_CLOCK_BY_DRIVER=0
  169549. +endif
  169550. +
  169551. +ifeq ($(USE_NEW_LINUX_SIGNAL), 1)
  169552. +EXTRA_CFLAGS += -DUSE_NEW_LINUX_SIGNAL=1
  169553. +else
  169554. +EXTRA_CFLAGS += -DUSE_NEW_LINUX_SIGNAL=0
  169555. +endif
  169556. +
  169557. +ifeq ($(NO_USER_DIRECT_ACCESS_FROM_KERNEL), 1)
  169558. +EXTRA_CFLAGS += -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=1
  169559. +else
  169560. +EXTRA_CFLAGS += -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=0
  169561. +endif
  169562. +
  169563. +ifeq ($(FORCE_ALL_VIDEO_MEMORY_CACHED), 1)
  169564. +EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=1
  169565. +else
  169566. +EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=0
  169567. +endif
  169568. +
  169569. +ifeq ($(NONPAGED_MEMORY_CACHEABLE), 1)
  169570. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_CACHEABLE=1
  169571. +else
  169572. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_CACHEABLE=0
  169573. +endif
  169574. +
  169575. +ifeq ($(NONPAGED_MEMORY_BUFFERABLE), 1)
  169576. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_BUFFERABLE=1
  169577. +else
  169578. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_BUFFERABLE=0
  169579. +endif
  169580. +
  169581. +ifeq ($(CACHE_FUNCTION_UNIMPLEMENTED), 1)
  169582. +EXTRA_CFLAGS += -DgcdCACHE_FUNCTION_UNIMPLEMENTED=1
  169583. +else
  169584. +EXTRA_CFLAGS += -DgcdCACHE_FUNCTION_UNIMPLEMENTED=0
  169585. +endif
  169586. +
  169587. +ifeq ($(SUPPORT_SWAP_RECTANGLE), 1)
  169588. +EXTRA_CFLAGS += -DgcdSUPPORT_SWAP_RECTANGLE=1
  169589. +else
  169590. +EXTRA_CFLAGS += -DgcdSUPPORT_SWAP_RECTANGLE=0
  169591. +endif
  169592. +
  169593. +ifeq ($(VIVANTE_ENABLE_VG), 1)
  169594. +EXTRA_CFLAGS += -DgcdENABLE_VG=1
  169595. +else
  169596. +EXTRA_CFLAGS += -DgcdENABLE_VG=0
  169597. +endif
  169598. +
  169599. +ifeq ($(CONFIG_SMP), y)
  169600. +EXTRA_CFLAGS += -DgcdSMP=1
  169601. +else
  169602. +EXTRA_CFLAGS += -DgcdSMP=0
  169603. +endif
  169604. +
  169605. +ifeq ($(VIVANTE_NO_3D),1)
  169606. +EXTRA_CFLAGS += -DVIVANTE_NO_3D
  169607. +endif
  169608. +
  169609. +ifeq ($(ENABLE_OUTER_CACHE_PATCH), 1)
  169610. +EXTRA_CFLAGS += -DgcdENABLE_OUTER_CACHE_PATCH=1
  169611. +else
  169612. +EXTRA_CFLAGS += -DgcdENABLE_OUTER_CACHE_PATCH=0
  169613. +endif
  169614. +
  169615. +ifeq ($(USE_BANK_ALIGNMENT), 1)
  169616. + EXTRA_CFLAGS += -DgcdENABLE_BANK_ALIGNMENT=1
  169617. + ifneq ($(BANK_BIT_START), 0)
  169618. + ifneq ($(BANK_BIT_END), 0)
  169619. + EXTRA_CFLAGS += -DgcdBANK_BIT_START=$(BANK_BIT_START)
  169620. + EXTRA_CFLAGS += -DgcdBANK_BIT_END=$(BANK_BIT_END)
  169621. + endif
  169622. + endif
  169623. +
  169624. + ifneq ($(BANK_CHANNEL_BIT), 0)
  169625. + EXTRA_CFLAGS += -DgcdBANK_CHANNEL_BIT=$(BANK_CHANNEL_BIT)
  169626. + endif
  169627. +endif
  169628. +
  169629. +ifneq ($(CONFIG_SYNC),)
  169630. +EXTRA_CFLAGS += -DgcdANDROID_NATIVE_FENCE_SYNC=1
  169631. +endif
  169632. +
  169633. +EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/inc
  169634. +EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel
  169635. +EXTRA_CFLAGS += -I$(AQARCH)/hal/kernel
  169636. +EXTRA_CFLAGS += -I$(AQROOT)/hal/os/linux/kernel
  169637. +
  169638. +ifeq ($(VIVANTE_ENABLE_VG), 1)
  169639. +EXTRA_CFLAGS += -I$(AQVGARCH)/hal/kernel
  169640. +endif
  169641. +
  169642. +obj-$(CONFIG_MXC_GPU_VIV) += galcore.o
  169643. +
  169644. +galcore-objs := $(OBJS)
  169645. +
  169646. +endif
  169647. diff -Nur linux-3.14.14/drivers/mxc/gpu-viv/Kconfig linux-imx6-3.14/drivers/mxc/gpu-viv/Kconfig
  169648. --- linux-3.14.14/drivers/mxc/gpu-viv/Kconfig 1969-12-31 18:00:00.000000000 -0600
  169649. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/Kconfig 2014-12-08 00:31:53.460418001 -0600
  169650. @@ -0,0 +1,9 @@
  169651. +menu "MXC Vivante GPU support"
  169652. + depends on SOC_IMX6Q
  169653. +
  169654. +config MXC_GPU_VIV
  169655. + tristate "MXC Vivante GPU support"
  169656. + ---help---
  169657. + Say Y to get the GPU driver support.
  169658. +
  169659. +endmenu
  169660. diff -Nur linux-3.14.14/drivers/mxc/hdmi-cec/Kconfig linux-imx6-3.14/drivers/mxc/hdmi-cec/Kconfig
  169661. --- linux-3.14.14/drivers/mxc/hdmi-cec/Kconfig 1969-12-31 18:00:00.000000000 -0600
  169662. +++ linux-imx6-3.14/drivers/mxc/hdmi-cec/Kconfig 2014-12-08 00:31:53.472418001 -0600
  169663. @@ -0,0 +1,11 @@
  169664. +
  169665. +menu "MXC HDMI CEC (Consumer Electronics Control) support"
  169666. +
  169667. +config MXC_HDMI_CEC
  169668. + tristate "Support for MXC HDMI CEC (Consumer Electronics Control)"
  169669. + depends on MFD_MXC_HDMI
  169670. + depends on FB_MXC_HDMI
  169671. + help
  169672. + The HDMI CEC device implement low level protocol on i.MX6x platforms.
  169673. +
  169674. +endmenu
  169675. diff -Nur linux-3.14.14/drivers/mxc/hdmi-cec/Makefile linux-imx6-3.14/drivers/mxc/hdmi-cec/Makefile
  169676. --- linux-3.14.14/drivers/mxc/hdmi-cec/Makefile 1969-12-31 18:00:00.000000000 -0600
  169677. +++ linux-imx6-3.14/drivers/mxc/hdmi-cec/Makefile 2014-12-08 00:31:53.472418001 -0600
  169678. @@ -0,0 +1 @@
  169679. +obj-$(CONFIG_MXC_HDMI_CEC) += mxc_hdmi-cec.o
  169680. diff -Nur linux-3.14.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c linux-imx6-3.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
  169681. --- linux-3.14.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c 1969-12-31 18:00:00.000000000 -0600
  169682. +++ linux-imx6-3.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c 2014-12-08 00:31:53.472418001 -0600
  169683. @@ -0,0 +1,629 @@
  169684. +/*
  169685. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  169686. + */
  169687. +
  169688. +/*
  169689. + * The code contained herein is licensed under the GNU General Public
  169690. + * License. You may obtain a copy of the GNU General Public License
  169691. + * Version 2 or later at the following locations:
  169692. + *
  169693. + * http://www.opensource.org/licenses/gpl-license.html
  169694. + * http://www.gnu.org/copyleft/gpl.html
  169695. + */
  169696. +
  169697. +/*!
  169698. + * @file mxc_hdmi-cec.c
  169699. + *
  169700. + * @brief HDMI CEC system initialization and file operation implementation
  169701. + *
  169702. + * @ingroup HDMI
  169703. + */
  169704. +
  169705. +#include <linux/module.h>
  169706. +#include <linux/kernel.h>
  169707. +#include <linux/mm.h>
  169708. +#include <linux/fs.h>
  169709. +#include <linux/stat.h>
  169710. +#include <linux/platform_device.h>
  169711. +#include <linux/poll.h>
  169712. +#include <linux/wait.h>
  169713. +#include <linux/list.h>
  169714. +#include <linux/delay.h>
  169715. +#include <linux/fsl_devices.h>
  169716. +#include <linux/uaccess.h>
  169717. +#include <linux/io.h>
  169718. +#include <linux/slab.h>
  169719. +#include <linux/vmalloc.h>
  169720. +#include <linux/workqueue.h>
  169721. +#include <linux/sizes.h>
  169722. +
  169723. +#include <linux/console.h>
  169724. +#include <linux/types.h>
  169725. +#include <linux/mfd/mxc-hdmi-core.h>
  169726. +#include <linux/pinctrl/consumer.h>
  169727. +
  169728. +#include <video/mxc_hdmi.h>
  169729. +
  169730. +#include "mxc_hdmi-cec.h"
  169731. +
  169732. +
  169733. +#define MAX_MESSAGE_LEN 17
  169734. +
  169735. +#define MESSAGE_TYPE_RECEIVE_SUCCESS 1
  169736. +#define MESSAGE_TYPE_NOACK 2
  169737. +#define MESSAGE_TYPE_DISCONNECTED 3
  169738. +#define MESSAGE_TYPE_CONNECTED 4
  169739. +#define MESSAGE_TYPE_SEND_SUCCESS 5
  169740. +
  169741. +#define CEC_TX_INPROGRESS -1
  169742. +#define CEC_TX_AVAIL 0
  169743. +
  169744. +struct hdmi_cec_priv {
  169745. + int receive_error;
  169746. + int send_error;
  169747. + u8 Logical_address;
  169748. + bool cec_state;
  169749. + u8 last_msg[MAX_MESSAGE_LEN];
  169750. + u8 msg_len;
  169751. + int tx_answer;
  169752. + u16 latest_cec_stat;
  169753. + u8 link_status;
  169754. + spinlock_t irq_lock;
  169755. + struct delayed_work hdmi_cec_work;
  169756. + struct mutex lock;
  169757. +};
  169758. +
  169759. +struct hdmi_cec_event {
  169760. + int event_type;
  169761. + int msg_len;
  169762. + u8 msg[MAX_MESSAGE_LEN];
  169763. + struct list_head list;
  169764. +};
  169765. +
  169766. +
  169767. +static LIST_HEAD(head);
  169768. +
  169769. +static int hdmi_cec_ready = 0;
  169770. +static int hdmi_cec_started;
  169771. +static int hdmi_cec_major;
  169772. +static struct class *hdmi_cec_class;
  169773. +static struct hdmi_cec_priv hdmi_cec_data;
  169774. +static u8 open_count;
  169775. +
  169776. +static wait_queue_head_t hdmi_cec_queue;
  169777. +static wait_queue_head_t tx_cec_queue;
  169778. +
  169779. +static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
  169780. +{
  169781. + struct hdmi_cec_priv *hdmi_cec = data;
  169782. + u16 cec_stat = 0;
  169783. + unsigned long flags;
  169784. + u8 phy_stat0;
  169785. + irqreturn_t ret = IRQ_HANDLED;
  169786. +
  169787. + spin_lock_irqsave(&hdmi_cec->irq_lock, flags);
  169788. +
  169789. + hdmi_writeb(0x7f, HDMI_IH_MUTE_CEC_STAT0);
  169790. +
  169791. + cec_stat = hdmi_readb(HDMI_IH_CEC_STAT0);
  169792. + hdmi_writeb(cec_stat, HDMI_IH_CEC_STAT0);
  169793. + phy_stat0 = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
  169794. +
  169795. + if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \
  169796. + HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \
  169797. + HDMI_IH_CEC_STAT0_DONE)) == 0) {
  169798. + ret = IRQ_NONE;
  169799. + cec_stat = 0;
  169800. + }
  169801. + if (hdmi_cec->link_status ^ phy_stat0) {
  169802. + /* HPD value changed */
  169803. + hdmi_cec->link_status = phy_stat0;
  169804. + if (hdmi_cec->link_status)
  169805. + cec_stat |= 0x80; /* Connected */
  169806. + else
  169807. + cec_stat |= 0x100; /* Disconnected */
  169808. + }
  169809. + pr_debug("HDMI CEC interrupt received\n");
  169810. + hdmi_cec->latest_cec_stat = cec_stat ;
  169811. +
  169812. + schedule_delayed_work(&(hdmi_cec->hdmi_cec_work), msecs_to_jiffies(20));
  169813. +
  169814. + spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags);
  169815. +
  169816. + return ret;
  169817. +}
  169818. +
  169819. +void mxc_hdmi_cec_handle(u16 cec_stat)
  169820. +{
  169821. + u8 val = 0, i = 0;
  169822. + struct hdmi_cec_event *event = NULL;
  169823. + /*The current transmission is successful (for initiator only).*/
  169824. + if (!open_count)
  169825. + return;
  169826. +
  169827. + if (cec_stat & HDMI_IH_CEC_STAT0_DONE) {
  169828. + hdmi_cec_data.tx_answer = cec_stat;
  169829. + wake_up(&tx_cec_queue);
  169830. + }
  169831. + /*EOM is detected so that the received data is ready in the receiver data buffer*/
  169832. + if (cec_stat & HDMI_IH_CEC_STAT0_EOM) {
  169833. + hdmi_writeb(0x02, HDMI_IH_CEC_STAT0);
  169834. + event = vmalloc(sizeof(struct hdmi_cec_event));
  169835. + if (NULL == event) {
  169836. + pr_err("%s: Not enough memory!\n", __func__);
  169837. + return;
  169838. + }
  169839. + memset(event, 0, sizeof(struct hdmi_cec_event));
  169840. + event->msg_len = hdmi_readb(HDMI_CEC_RX_CNT);
  169841. + if (!event->msg_len) {
  169842. + pr_err("%s: Invalid CEC message length!\n", __func__);
  169843. + return;
  169844. + }
  169845. + event->event_type = MESSAGE_TYPE_RECEIVE_SUCCESS;
  169846. + for (i = 0; i < event->msg_len; i++)
  169847. + event->msg[i] = hdmi_readb(HDMI_CEC_RX_DATA0+i);
  169848. + hdmi_writeb(0x0, HDMI_CEC_LOCK);
  169849. + mutex_lock(&hdmi_cec_data.lock);
  169850. + list_add_tail(&event->list, &head);
  169851. + mutex_unlock(&hdmi_cec_data.lock);
  169852. + wake_up(&hdmi_cec_queue);
  169853. + }
  169854. + /*An error is detected on cec line (for initiator only). */
  169855. + if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_INIT) {
  169856. + mutex_lock(&hdmi_cec_data.lock);
  169857. + hdmi_cec_data.send_error++;
  169858. + if (hdmi_cec_data.send_error > 2) {
  169859. + pr_err("%s:Re-transmission is attempted more than 2 times!\n", __func__);
  169860. + hdmi_cec_data.send_error = 0;
  169861. + mutex_unlock(&hdmi_cec_data.lock);
  169862. + hdmi_cec_data.tx_answer = cec_stat;
  169863. + wake_up(&tx_cec_queue);
  169864. + return;
  169865. + }
  169866. + for (i = 0; i < hdmi_cec_data.msg_len; i++)
  169867. + hdmi_writeb(hdmi_cec_data.last_msg[i], HDMI_CEC_TX_DATA0+i);
  169868. + hdmi_writeb(hdmi_cec_data.msg_len, HDMI_CEC_TX_CNT);
  169869. + val = hdmi_readb(HDMI_CEC_CTRL);
  169870. + val |= 0x01;
  169871. + hdmi_writeb(val, HDMI_CEC_CTRL);
  169872. + mutex_unlock(&hdmi_cec_data.lock);
  169873. + }
  169874. + /*A frame is not acknowledged in a directly addressed message. Or a frame is negatively acknowledged in
  169875. + a broadcast message (for initiator only).*/
  169876. + if (cec_stat & HDMI_IH_CEC_STAT0_NACK) {
  169877. + hdmi_cec_data.tx_answer = cec_stat;
  169878. + wake_up(&tx_cec_queue);
  169879. + }
  169880. + /*An error is notified by a follower. Abnormal logic data bit error (for follower).*/
  169881. + if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_FOLL) {
  169882. + hdmi_cec_data.receive_error++;
  169883. + }
  169884. + /*HDMI cable connected*/
  169885. + if (cec_stat & 0x80) {
  169886. + pr_info("HDMI link connected\n");
  169887. + event = vmalloc(sizeof(struct hdmi_cec_event));
  169888. + if (NULL == event) {
  169889. + pr_err("%s: Not enough memory\n", __func__);
  169890. + return;
  169891. + }
  169892. + memset(event, 0, sizeof(struct hdmi_cec_event));
  169893. + event->event_type = MESSAGE_TYPE_CONNECTED;
  169894. + mutex_lock(&hdmi_cec_data.lock);
  169895. + list_add_tail(&event->list, &head);
  169896. + mutex_unlock(&hdmi_cec_data.lock);
  169897. + wake_up(&hdmi_cec_queue);
  169898. + }
  169899. + /*HDMI cable disconnected*/
  169900. + if (cec_stat & 0x100) {
  169901. + pr_info("HDMI link disconnected\n");
  169902. + event = vmalloc(sizeof(struct hdmi_cec_event));
  169903. + if (NULL == event) {
  169904. + pr_err("%s: Not enough memory!\n", __func__);
  169905. + return;
  169906. + }
  169907. + memset(event, 0, sizeof(struct hdmi_cec_event));
  169908. + event->event_type = MESSAGE_TYPE_DISCONNECTED;
  169909. + mutex_lock(&hdmi_cec_data.lock);
  169910. + list_add_tail(&event->list, &head);
  169911. + mutex_unlock(&hdmi_cec_data.lock);
  169912. + wake_up(&hdmi_cec_queue);
  169913. + }
  169914. + return;
  169915. +}
  169916. +EXPORT_SYMBOL(mxc_hdmi_cec_handle);
  169917. +static void mxc_hdmi_cec_worker(struct work_struct *work)
  169918. +{
  169919. + u8 val;
  169920. + mxc_hdmi_cec_handle(hdmi_cec_data.latest_cec_stat);
  169921. + val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST;
  169922. + hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
  169923. +}
  169924. +
  169925. +/*!
  169926. + * @brief open function for cec file operation
  169927. + *
  169928. + * @return 0 on success or negative error code on error
  169929. + */
  169930. +static int hdmi_cec_open(struct inode *inode, struct file *filp)
  169931. +{
  169932. + mutex_lock(&hdmi_cec_data.lock);
  169933. + if (open_count) {
  169934. + mutex_unlock(&hdmi_cec_data.lock);
  169935. + return -EBUSY;
  169936. + }
  169937. + open_count = 1;
  169938. + filp->private_data = (void *)(&hdmi_cec_data);
  169939. + hdmi_cec_data.Logical_address = 15;
  169940. + hdmi_cec_data.cec_state = false;
  169941. + mutex_unlock(&hdmi_cec_data.lock);
  169942. + return 0;
  169943. +}
  169944. +
  169945. +static ssize_t hdmi_cec_read(struct file *file, char __user *buf, size_t count,
  169946. + loff_t *ppos)
  169947. +{
  169948. + struct hdmi_cec_event *event = NULL;
  169949. + pr_debug("function : %s\n", __func__);
  169950. +
  169951. + if (!open_count)
  169952. + return -ENODEV;
  169953. + mutex_lock(&hdmi_cec_data.lock);
  169954. + if (false == hdmi_cec_data.cec_state) {
  169955. + mutex_unlock(&hdmi_cec_data.lock);
  169956. + return -EACCES;
  169957. + }
  169958. +
  169959. + if (list_empty(&head)) {
  169960. + if (file->f_flags & O_NONBLOCK) {
  169961. + mutex_unlock(&hdmi_cec_data.lock);
  169962. + return -EAGAIN;
  169963. + } else {
  169964. + do {
  169965. + mutex_unlock(&hdmi_cec_data.lock);
  169966. + if (wait_event_interruptible(hdmi_cec_queue, (!list_empty(&head))))
  169967. + return -ERESTARTSYS;
  169968. + mutex_lock(&hdmi_cec_data.lock);
  169969. + } while (list_empty(&head));
  169970. + }
  169971. + }
  169972. +
  169973. + event = list_first_entry(&head, struct hdmi_cec_event, list);
  169974. + list_del(&event->list);
  169975. + mutex_unlock(&hdmi_cec_data.lock);
  169976. + if (copy_to_user(buf, event,
  169977. + sizeof(struct hdmi_cec_event) - sizeof(struct list_head))) {
  169978. + vfree(event);
  169979. + return -EFAULT;
  169980. + }
  169981. + vfree(event);
  169982. + return (sizeof(struct hdmi_cec_event) - sizeof(struct list_head));
  169983. +}
  169984. +
  169985. +static ssize_t hdmi_cec_write(struct file *file, const char __user *buf,
  169986. + size_t count, loff_t *ppos)
  169987. +{
  169988. + int ret = 0 , i = 0;
  169989. + u8 msg[MAX_MESSAGE_LEN];
  169990. + u8 msg_len = 0, val = 0;
  169991. +
  169992. + pr_debug("function : %s\n", __func__);
  169993. +
  169994. + if (!open_count)
  169995. + return -ENODEV;
  169996. + mutex_lock(&hdmi_cec_data.lock);
  169997. + if (false == hdmi_cec_data.cec_state) {
  169998. + mutex_unlock(&hdmi_cec_data.lock);
  169999. + return -EACCES;
  170000. + }
  170001. + /* Ensure that there is only one writer who is the only listener of tx_cec_queue */
  170002. + if (hdmi_cec_data.tx_answer != CEC_TX_AVAIL) {
  170003. + mutex_unlock(&hdmi_cec_data.lock);
  170004. + return -EBUSY;
  170005. + }
  170006. + mutex_unlock(&hdmi_cec_data.lock);
  170007. + if (count > MAX_MESSAGE_LEN)
  170008. + return -EINVAL;
  170009. + memset(&msg, 0, MAX_MESSAGE_LEN);
  170010. + ret = copy_from_user(&msg, buf, count);
  170011. + if (ret)
  170012. + return -EACCES;
  170013. + mutex_lock(&hdmi_cec_data.lock);
  170014. + hdmi_cec_data.send_error = 0;
  170015. + hdmi_cec_data.tx_answer = CEC_TX_INPROGRESS;
  170016. + msg_len = count;
  170017. + hdmi_writeb(msg_len, HDMI_CEC_TX_CNT);
  170018. + for (i = 0; i < msg_len; i++)
  170019. + hdmi_writeb(msg[i], HDMI_CEC_TX_DATA0+i);
  170020. + val = hdmi_readb(HDMI_CEC_CTRL);
  170021. + val |= 0x01;
  170022. + hdmi_writeb(val, HDMI_CEC_CTRL);
  170023. + memcpy(hdmi_cec_data.last_msg, msg, msg_len);
  170024. + hdmi_cec_data.msg_len = msg_len;
  170025. + mutex_unlock(&hdmi_cec_data.lock);
  170026. +
  170027. + ret = wait_event_interruptible_timeout(tx_cec_queue, hdmi_cec_data.tx_answer != CEC_TX_INPROGRESS, HZ);
  170028. +
  170029. + if (ret < 0) {
  170030. + ret = -ERESTARTSYS;
  170031. + goto tx_out;
  170032. + }
  170033. +
  170034. + if (hdmi_cec_data.tx_answer & HDMI_IH_CEC_STAT0_DONE)
  170035. + /* msg correctly sent */
  170036. + ret = msg_len;
  170037. + else
  170038. + ret = -EIO;
  170039. +
  170040. + tx_out:
  170041. + hdmi_cec_data.tx_answer = CEC_TX_AVAIL;
  170042. + return ret;
  170043. +}
  170044. +
  170045. +void hdmi_cec_start_device(void)
  170046. +{
  170047. + u8 val;
  170048. +
  170049. + if (!hdmi_cec_ready || hdmi_cec_started)
  170050. + return;
  170051. +
  170052. + val = hdmi_readb(HDMI_MC_CLKDIS);
  170053. + val &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
  170054. + hdmi_writeb(val, HDMI_MC_CLKDIS);
  170055. + hdmi_writeb(0x02, HDMI_CEC_CTRL);
  170056. + /* Force read unlock */
  170057. + hdmi_writeb(0x0, HDMI_CEC_LOCK);
  170058. + val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
  170059. + hdmi_writeb(val, HDMI_CEC_POLARITY);
  170060. + val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST;
  170061. + hdmi_writeb(val, HDMI_CEC_MASK);
  170062. + hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
  170063. + hdmi_cec_data.link_status = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
  170064. + mutex_lock(&hdmi_cec_data.lock);
  170065. + hdmi_cec_data.cec_state = true;
  170066. + mutex_unlock(&hdmi_cec_data.lock);
  170067. +
  170068. + hdmi_cec_started = 1;
  170069. +}
  170070. +EXPORT_SYMBOL(hdmi_cec_start_device);
  170071. +
  170072. +void hdmi_cec_stop_device(void)
  170073. +{
  170074. + u8 val;
  170075. +
  170076. + if (!hdmi_cec_ready || !hdmi_cec_started)
  170077. + return;
  170078. +
  170079. + hdmi_writeb(0x10, HDMI_CEC_CTRL);
  170080. + val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_ARB_LOST | \
  170081. + HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
  170082. + hdmi_writeb(val, HDMI_CEC_MASK);
  170083. + hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
  170084. + hdmi_writeb(0x0, HDMI_CEC_POLARITY);
  170085. + val = hdmi_readb(HDMI_MC_CLKDIS);
  170086. + val |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
  170087. + hdmi_writeb(val, HDMI_MC_CLKDIS);
  170088. + mutex_lock(&hdmi_cec_data.lock);
  170089. + hdmi_cec_data.cec_state = false;
  170090. + mutex_unlock(&hdmi_cec_data.lock);
  170091. +
  170092. + hdmi_cec_started = 0;
  170093. +}
  170094. +EXPORT_SYMBOL(hdmi_cec_stop_device);
  170095. +
  170096. +/*!
  170097. + * @brief IO ctrl function for vpu file operation
  170098. + * @param cmd IO ctrl command
  170099. + * @return 0 on success or negative error code on error
  170100. + */
  170101. +static long hdmi_cec_ioctl(struct file *filp, u_int cmd,
  170102. + u_long arg)
  170103. +{
  170104. + int ret = 0, status = 0;
  170105. + u8 val = 0, msg = 0;
  170106. + struct mxc_edid_cfg hdmi_edid_cfg;
  170107. + pr_debug("function : %s\n", __func__);
  170108. + if (!open_count)
  170109. + return -ENODEV;
  170110. + switch (cmd) {
  170111. + case HDMICEC_IOC_SETLOGICALADDRESS:
  170112. + mutex_lock(&hdmi_cec_data.lock);
  170113. + if (false == hdmi_cec_data.cec_state) {
  170114. + mutex_unlock(&hdmi_cec_data.lock);
  170115. + pr_err("Trying to set logical address while not started\n");
  170116. + return -EACCES;
  170117. + }
  170118. + hdmi_cec_data.Logical_address = (u8)arg;
  170119. + if (hdmi_cec_data.Logical_address <= 7) {
  170120. + val = 1 << hdmi_cec_data.Logical_address;
  170121. + hdmi_writeb(val, HDMI_CEC_ADDR_L);
  170122. + hdmi_writeb(0, HDMI_CEC_ADDR_H);
  170123. + } else if (hdmi_cec_data.Logical_address > 7 && hdmi_cec_data.Logical_address <= 15) {
  170124. + val = 1 << (hdmi_cec_data.Logical_address - 8);
  170125. + hdmi_writeb(val, HDMI_CEC_ADDR_H);
  170126. + hdmi_writeb(0, HDMI_CEC_ADDR_L);
  170127. + } else
  170128. + ret = -EINVAL;
  170129. + /*Send Polling message with same source and destination address*/
  170130. + if (0 == ret && 15 != hdmi_cec_data.Logical_address) {
  170131. + msg = (hdmi_cec_data.Logical_address << 4)|hdmi_cec_data.Logical_address;
  170132. + hdmi_writeb(1, HDMI_CEC_TX_CNT);
  170133. + hdmi_writeb(msg, HDMI_CEC_TX_DATA0);
  170134. + val = hdmi_readb(HDMI_CEC_CTRL);
  170135. + val |= 0x01;
  170136. + hdmi_writeb(val, HDMI_CEC_CTRL);
  170137. + }
  170138. + mutex_unlock(&hdmi_cec_data.lock);
  170139. + break;
  170140. + case HDMICEC_IOC_STARTDEVICE:
  170141. + hdmi_cec_start_device();
  170142. + break;
  170143. + case HDMICEC_IOC_STOPDEVICE:
  170144. + hdmi_cec_stop_device();
  170145. + break;
  170146. + case HDMICEC_IOC_GETPHYADDRESS:
  170147. + hdmi_get_edid_cfg(&hdmi_edid_cfg);
  170148. + status = copy_to_user((void __user *)arg,
  170149. + &hdmi_edid_cfg.physical_address,
  170150. + 4*sizeof(u8));
  170151. + if (status)
  170152. + ret = -EFAULT;
  170153. + break;
  170154. + default:
  170155. + ret = -EINVAL;
  170156. + break;
  170157. + }
  170158. + return ret;
  170159. +}
  170160. +
  170161. +/*!
  170162. + * @brief Release function for vpu file operation
  170163. + * @return 0 on success or negative error code on error
  170164. + */
  170165. +static int hdmi_cec_release(struct inode *inode, struct file *filp)
  170166. +{
  170167. + mutex_lock(&hdmi_cec_data.lock);
  170168. + if (open_count) {
  170169. + open_count = 0;
  170170. + hdmi_cec_data.cec_state = false;
  170171. + hdmi_cec_data.Logical_address = 15;
  170172. + }
  170173. + mutex_unlock(&hdmi_cec_data.lock);
  170174. +
  170175. + return 0;
  170176. +}
  170177. +
  170178. +static unsigned int hdmi_cec_poll(struct file *file, poll_table *wait)
  170179. +{
  170180. + unsigned int mask = 0;
  170181. +
  170182. + pr_debug("function : %s\n", __func__);
  170183. +
  170184. + poll_wait(file, &hdmi_cec_queue, wait);
  170185. +
  170186. + mutex_lock(&hdmi_cec_data.lock);
  170187. + if (hdmi_cec_data.tx_answer == CEC_TX_AVAIL)
  170188. + mask = (POLLOUT | POLLWRNORM);
  170189. + if (!list_empty(&head))
  170190. + mask |= (POLLIN | POLLRDNORM);
  170191. + mutex_unlock(&hdmi_cec_data.lock);
  170192. + return mask;
  170193. +}
  170194. +
  170195. +
  170196. +const struct file_operations hdmi_cec_fops = {
  170197. + .owner = THIS_MODULE,
  170198. + .read = hdmi_cec_read,
  170199. + .write = hdmi_cec_write,
  170200. + .open = hdmi_cec_open,
  170201. + .unlocked_ioctl = hdmi_cec_ioctl,
  170202. + .release = hdmi_cec_release,
  170203. + .poll = hdmi_cec_poll,
  170204. +};
  170205. +
  170206. +static int hdmi_cec_dev_probe(struct platform_device *pdev)
  170207. +{
  170208. + int err = 0;
  170209. + struct device *temp_class;
  170210. + struct resource *res;
  170211. + struct pinctrl *pinctrl;
  170212. + int irq = platform_get_irq(pdev, 0);
  170213. +
  170214. + hdmi_cec_major = register_chrdev(hdmi_cec_major, "mxc_hdmi_cec", &hdmi_cec_fops);
  170215. + if (hdmi_cec_major < 0) {
  170216. + dev_err(&pdev->dev, "hdmi_cec: unable to get a major for HDMI CEC\n");
  170217. + err = -EBUSY;
  170218. + goto out;
  170219. + }
  170220. +
  170221. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  170222. + if (unlikely(res == NULL)) {
  170223. + dev_err(&pdev->dev, "hdmi_cec:No HDMI irq line provided\n");
  170224. + goto err_out_chrdev;
  170225. + }
  170226. + spin_lock_init(&hdmi_cec_data.irq_lock);
  170227. +
  170228. + err = devm_request_irq(&pdev->dev, irq, mxc_hdmi_cec_isr, IRQF_SHARED,
  170229. + dev_name(&pdev->dev), &hdmi_cec_data);
  170230. + if (err < 0) {
  170231. + dev_err(&pdev->dev, "hdmi_cec:Unable to request irq: %d\n", err);
  170232. + goto err_out_chrdev;
  170233. + }
  170234. +
  170235. + hdmi_cec_class = class_create(THIS_MODULE, "mxc_hdmi_cec");
  170236. + if (IS_ERR(hdmi_cec_class)) {
  170237. + err = PTR_ERR(hdmi_cec_class);
  170238. + goto err_out_chrdev;
  170239. + }
  170240. +
  170241. + temp_class = device_create(hdmi_cec_class, NULL, MKDEV(hdmi_cec_major, 0),
  170242. + NULL, "mxc_hdmi_cec");
  170243. + if (IS_ERR(temp_class)) {
  170244. + err = PTR_ERR(temp_class);
  170245. + goto err_out_class;
  170246. + }
  170247. +
  170248. + pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
  170249. + if (IS_ERR(pinctrl)) {
  170250. + dev_err(&pdev->dev, "can't get/select CEC pinctrl\n");
  170251. + goto err_out_class;
  170252. + }
  170253. +
  170254. + init_waitqueue_head(&hdmi_cec_queue);
  170255. + init_waitqueue_head(&tx_cec_queue);
  170256. +
  170257. + INIT_LIST_HEAD(&head);
  170258. +
  170259. + mutex_init(&hdmi_cec_data.lock);
  170260. + hdmi_cec_data.Logical_address = 15;
  170261. + hdmi_cec_data.tx_answer = CEC_TX_AVAIL;
  170262. + platform_set_drvdata(pdev, &hdmi_cec_data);
  170263. + INIT_DELAYED_WORK(&hdmi_cec_data.hdmi_cec_work, mxc_hdmi_cec_worker);
  170264. +
  170265. + dev_info(&pdev->dev, "HDMI CEC initialized\n");
  170266. + hdmi_cec_ready = 1;
  170267. + goto out;
  170268. +
  170269. +err_out_class:
  170270. + device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0));
  170271. + class_destroy(hdmi_cec_class);
  170272. +err_out_chrdev:
  170273. + unregister_chrdev(hdmi_cec_major, "mxc_hdmi_cec");
  170274. +out:
  170275. + return err;
  170276. +}
  170277. +
  170278. +static int hdmi_cec_dev_remove(struct platform_device *pdev)
  170279. +{
  170280. + if (hdmi_cec_data.cec_state)
  170281. + hdmi_cec_stop_device();
  170282. + if (hdmi_cec_major > 0) {
  170283. + device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0));
  170284. + class_destroy(hdmi_cec_class);
  170285. + unregister_chrdev(hdmi_cec_major, "mxc_hdmi_cec");
  170286. + hdmi_cec_major = 0;
  170287. +}
  170288. + return 0;
  170289. +}
  170290. +
  170291. +static const struct of_device_id imx_hdmi_cec_match[] = {
  170292. + { .compatible = "fsl,imx6q-hdmi-cec", },
  170293. + { .compatible = "fsl,imx6dl-hdmi-cec", },
  170294. + { /* sentinel */ }
  170295. +};
  170296. +
  170297. +static struct platform_driver mxc_hdmi_cec_driver = {
  170298. + .probe = hdmi_cec_dev_probe,
  170299. + .remove = hdmi_cec_dev_remove,
  170300. + .driver = {
  170301. + .name = "mxc_hdmi_cec",
  170302. + .of_match_table = imx_hdmi_cec_match,
  170303. + },
  170304. +};
  170305. +
  170306. +module_platform_driver(mxc_hdmi_cec_driver);
  170307. +
  170308. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  170309. +MODULE_DESCRIPTION("Linux HDMI CEC driver for Freescale i.MX/MXC");
  170310. +MODULE_LICENSE("GPL");
  170311. +MODULE_ALIAS("platform:mxc_hdmi_cec");
  170312. +
  170313. diff -Nur linux-3.14.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h linux-imx6-3.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h
  170314. --- linux-3.14.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h 1969-12-31 18:00:00.000000000 -0600
  170315. +++ linux-imx6-3.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h 2014-12-08 00:31:53.472418001 -0600
  170316. @@ -0,0 +1,38 @@
  170317. +/*
  170318. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  170319. + */
  170320. +
  170321. +/*
  170322. + * The code contained herein is licensed under the GNU General Public
  170323. + * License. You may obtain a copy of the GNU General Public License
  170324. + * Version 2 or later at the following locations:
  170325. + *
  170326. + * http://www.opensource.org/licenses/gpl-license.html
  170327. + * http://www.gnu.org/copyleft/gpl.html
  170328. + */
  170329. +#ifndef _HDMICEC_H_
  170330. +#define _HDMICEC_H_
  170331. +#include <linux/ioctl.h>
  170332. +
  170333. +/*
  170334. + * Ioctl definitions
  170335. + */
  170336. +
  170337. +/* Use 'k' as magic number */
  170338. +#define HDMICEC_IOC_MAGIC 'H'
  170339. +/*
  170340. + * S means "Set" through a ptr,
  170341. + * T means "Tell" directly with the argument value
  170342. + * G means "Get": reply by setting through a pointer
  170343. + * Q means "Query": response is on the return value
  170344. + * X means "eXchange": G and S atomically
  170345. + * H means "sHift": T and Q atomically
  170346. + */
  170347. +#define HDMICEC_IOC_SETLOGICALADDRESS \
  170348. + _IOW(HDMICEC_IOC_MAGIC, 1, unsigned char)
  170349. +#define HDMICEC_IOC_STARTDEVICE _IO(HDMICEC_IOC_MAGIC, 2)
  170350. +#define HDMICEC_IOC_STOPDEVICE _IO(HDMICEC_IOC_MAGIC, 3)
  170351. +#define HDMICEC_IOC_GETPHYADDRESS \
  170352. + _IOR(HDMICEC_IOC_MAGIC, 4, unsigned char[4])
  170353. +
  170354. +#endif /* !_HDMICEC_H_ */
  170355. diff -Nur linux-3.14.14/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
  170356. --- linux-3.14.14/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c 1969-12-31 18:00:00.000000000 -0600
  170357. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c 2014-12-08 00:31:53.472418001 -0600
  170358. @@ -0,0 +1,495 @@
  170359. +/*
  170360. + * Copyright 2009-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  170361. + */
  170362. +
  170363. +/*
  170364. + * The code contained herein is licensed under the GNU General Public
  170365. + * License. You may obtain a copy of the GNU General Public License
  170366. + * Version 2 or later at the following locations:
  170367. + *
  170368. + * http://www.opensource.org/licenses/gpl-license.html
  170369. + * http://www.gnu.org/copyleft/gpl.html
  170370. + */
  170371. +
  170372. +/*
  170373. + * @file ipu_calc_stripes_sizes.c
  170374. + *
  170375. + * @brief IPU IC functions
  170376. + *
  170377. + * @ingroup IPU
  170378. + */
  170379. +
  170380. +#include <linux/ipu-v3.h>
  170381. +#include <linux/module.h>
  170382. +#include <linux/math64.h>
  170383. +
  170384. +#define BPP_32 0
  170385. +#define BPP_16 3
  170386. +#define BPP_8 5
  170387. +#define BPP_24 1
  170388. +#define BPP_12 4
  170389. +#define BPP_18 2
  170390. +
  170391. +static u32 truncate(u32 up, /* 0: down; else: up */
  170392. + u64 a, /* must be non-negative */
  170393. + u32 b)
  170394. +{
  170395. + u32 d;
  170396. + u64 div;
  170397. + div = div_u64(a, b);
  170398. + d = b * (div >> 32);
  170399. + if (up && (a > (((u64)d) << 32)))
  170400. + return d+b;
  170401. + else
  170402. + return d;
  170403. +}
  170404. +
  170405. +static unsigned int f_calc(unsigned int pfs, unsigned int bpp, unsigned int *write)
  170406. +{/* return input_f */
  170407. + unsigned int f_calculated = 0;
  170408. + switch (pfs) {
  170409. + case IPU_PIX_FMT_YVU422P:
  170410. + case IPU_PIX_FMT_YUV422P:
  170411. + case IPU_PIX_FMT_YUV420P2:
  170412. + case IPU_PIX_FMT_YUV420P:
  170413. + case IPU_PIX_FMT_YVU420P:
  170414. + case IPU_PIX_FMT_YUV444P:
  170415. + f_calculated = 16;
  170416. + break;
  170417. +
  170418. + case IPU_PIX_FMT_RGB565:
  170419. + case IPU_PIX_FMT_YUYV:
  170420. + case IPU_PIX_FMT_UYVY:
  170421. + f_calculated = 8;
  170422. + break;
  170423. +
  170424. + case IPU_PIX_FMT_NV12:
  170425. + f_calculated = 8;
  170426. + break;
  170427. +
  170428. + default:
  170429. + f_calculated = 0;
  170430. + break;
  170431. +
  170432. + }
  170433. + if (!f_calculated) {
  170434. + switch (bpp) {
  170435. + case BPP_32:
  170436. + f_calculated = 2;
  170437. + break;
  170438. +
  170439. + case BPP_16:
  170440. + f_calculated = 4;
  170441. + break;
  170442. +
  170443. + case BPP_8:
  170444. + case BPP_24:
  170445. + f_calculated = 8;
  170446. + break;
  170447. +
  170448. + case BPP_12:
  170449. + f_calculated = 16;
  170450. + break;
  170451. +
  170452. + case BPP_18:
  170453. + f_calculated = 32;
  170454. + break;
  170455. +
  170456. + default:
  170457. + f_calculated = 0;
  170458. + break;
  170459. + }
  170460. + }
  170461. + return f_calculated;
  170462. +}
  170463. +
  170464. +
  170465. +static unsigned int m_calc(unsigned int pfs)
  170466. +{
  170467. + unsigned int m_calculated = 0;
  170468. + switch (pfs) {
  170469. + case IPU_PIX_FMT_YUV420P2:
  170470. + case IPU_PIX_FMT_YUV420P:
  170471. + case IPU_PIX_FMT_YVU422P:
  170472. + case IPU_PIX_FMT_YUV422P:
  170473. + case IPU_PIX_FMT_YVU420P:
  170474. + case IPU_PIX_FMT_YUV444P:
  170475. + m_calculated = 16;
  170476. + break;
  170477. +
  170478. + case IPU_PIX_FMT_NV12:
  170479. + case IPU_PIX_FMT_YUYV:
  170480. + case IPU_PIX_FMT_UYVY:
  170481. + m_calculated = 8;
  170482. + break;
  170483. +
  170484. + default:
  170485. + m_calculated = 8;
  170486. + break;
  170487. +
  170488. + }
  170489. + return m_calculated;
  170490. +}
  170491. +
  170492. +static int calc_split_resize_coeffs(unsigned int inSize, unsigned int outSize,
  170493. + unsigned int *resizeCoeff,
  170494. + unsigned int *downsizeCoeff)
  170495. +{
  170496. + uint32_t tempSize;
  170497. + uint32_t tempDownsize;
  170498. +
  170499. + if (inSize > 4096) {
  170500. + pr_debug("IC input size(%d) cannot exceed 4096\n",
  170501. + inSize);
  170502. + return -EINVAL;
  170503. + }
  170504. +
  170505. + if (outSize > 1024) {
  170506. + pr_debug("IC output size(%d) cannot exceed 1024\n",
  170507. + outSize);
  170508. + return -EINVAL;
  170509. + }
  170510. +
  170511. + if ((outSize << 3) < inSize) {
  170512. + pr_debug("IC cannot downsize more than 8:1\n");
  170513. + return -EINVAL;
  170514. + }
  170515. +
  170516. + /* Compute downsizing coefficient */
  170517. + /* Output of downsizing unit cannot be more than 1024 */
  170518. + tempDownsize = 0;
  170519. + tempSize = inSize;
  170520. + while (((tempSize > 1024) || (tempSize >= outSize * 2)) &&
  170521. + (tempDownsize < 2)) {
  170522. + tempSize >>= 1;
  170523. + tempDownsize++;
  170524. + }
  170525. + *downsizeCoeff = tempDownsize;
  170526. +
  170527. + /* compute resizing coefficient using the following equation:
  170528. + resizeCoeff = M*(SI -1)/(SO - 1)
  170529. + where M = 2^13, SI - input size, SO - output size */
  170530. + *resizeCoeff = (8192L * (tempSize - 1)) / (outSize - 1);
  170531. + if (*resizeCoeff >= 16384L) {
  170532. + pr_debug("Overflow on IC resize coefficient.\n");
  170533. + return -EINVAL;
  170534. + }
  170535. +
  170536. + pr_debug("resizing from %u -> %u pixels, "
  170537. + "downsize=%u, resize=%u.%lu (reg=%u)\n", inSize, outSize,
  170538. + *downsizeCoeff, (*resizeCoeff >= 8192L) ? 1 : 0,
  170539. + ((*resizeCoeff & 0x1FFF) * 10000L) / 8192L, *resizeCoeff);
  170540. +
  170541. + return 0;
  170542. +}
  170543. +
  170544. +/* Stripe parameters calculator */
  170545. +/**************************************************************************
  170546. +Notes:
  170547. +MSW = the maximal width allowed for a stripe
  170548. + i.MX31: 720, i.MX35: 800, i.MX37/51/53: 1024
  170549. +cirr = the maximal inverse resizing ratio for which overlap in the input
  170550. + is requested; typically cirr~2
  170551. +flags
  170552. + bit 0 - equal_stripes
  170553. + 0 each stripe is allowed to have independent parameters
  170554. + for maximal image quality
  170555. + 1 the stripes are requested to have identical parameters
  170556. + (except the base address), for maximal performance
  170557. + bit 1 - vertical/horizontal
  170558. + 0 horizontal
  170559. + 1 vertical
  170560. +
  170561. +If performance is the top priority (above image quality)
  170562. + Avoid overlap, by setting CIRR = 0
  170563. + This will also force effectively identical_stripes = 1
  170564. + Choose IF & OF that corresponds to the same IOX/SX for both stripes
  170565. + Choose IFW & OFW such that
  170566. + IFW/IM, IFW/IF, OFW/OM, OFW/OF are even integers
  170567. + The function returns an error status:
  170568. + 0: no error
  170569. + 1: invalid input parameters -> aborted without result
  170570. + Valid parameters should satisfy the following conditions
  170571. + IFW <= OFW, otherwise downsizing is required
  170572. + - which is not supported yet
  170573. + 4 <= IFW,OFW, so some interpolation may be needed even without overlap
  170574. + IM, OM, IF, OF should not vanish
  170575. + 2*IF <= IFW
  170576. + so the frame can be split to two equal stripes, even without overlap
  170577. + 2*(OF+IF/irr_opt) <= OFW
  170578. + so a valid positive INW exists even for equal stripes
  170579. + OF <= MSW, otherwise, the left stripe cannot be sufficiently large
  170580. + MSW < OFW, so splitting to stripes is required
  170581. + OFW <= 2*MSW, so two stripes are sufficient
  170582. + (this also implies that 2<=MSW)
  170583. + 2: OF is not a multiple of OM - not fully-supported yet
  170584. + Output is produced but OW is not guaranited to be a multiple of OM
  170585. + 4: OFW reduced to be a multiple of OM
  170586. + 8: CIRR > 1: truncated to 1
  170587. + Overlap is not supported (and not needed) y for upsizing)
  170588. +**************************************************************************/
  170589. +int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
  170590. + /* input frame width;>1 */
  170591. + unsigned int output_frame_width, /* output frame width; >1 */
  170592. + const unsigned int maximal_stripe_width,
  170593. + /* the maximal width allowed for a stripe */
  170594. + const unsigned long long cirr, /* see above */
  170595. + const unsigned int flags, /* see above */
  170596. + u32 input_pixelformat,/* pixel format after of read channel*/
  170597. + u32 output_pixelformat,/* pixel format after of write channel*/
  170598. + struct stripe_param *left,
  170599. + struct stripe_param *right)
  170600. +{
  170601. + const unsigned int irr_frac_bits = 13;
  170602. + const unsigned long irr_steps = 1 << irr_frac_bits;
  170603. + const u64 dirr = ((u64)1) << (32 - 2);
  170604. + /* The maximum relative difference allowed between the irrs */
  170605. + const u64 cr = ((u64)4) << 32;
  170606. + /* The importance ratio between the two terms in the cost function below */
  170607. +
  170608. + unsigned int status;
  170609. + unsigned int temp;
  170610. + unsigned int onw_min;
  170611. + unsigned int inw = 0, onw = 0, inw_best = 0;
  170612. + /* number of pixels in the left stripe NOT hidden by the right stripe */
  170613. + u64 irr_opt; /* the optimal inverse resizing ratio */
  170614. + u64 rr_opt; /* the optimal resizing ratio = 1/irr_opt*/
  170615. + u64 dinw; /* the misalignment between the stripes */
  170616. + /* (measured in units of input columns) */
  170617. + u64 difwl, difwr = 0;
  170618. + /* The number of input columns not reflected in the output */
  170619. + /* the resizing ratio used for the right stripe is */
  170620. + /* left->irr and right->irr respectively */
  170621. + u64 cost, cost_min;
  170622. + u64 div; /* result of division */
  170623. + bool equal_stripes = (flags & 0x1) != 0;
  170624. + bool vertical = (flags & 0x2) != 0;
  170625. +
  170626. + unsigned int input_m, input_f, output_m, output_f; /* parameters for upsizing by stripes */
  170627. + unsigned int resize_coeff;
  170628. + unsigned int downsize_coeff;
  170629. +
  170630. + status = 0;
  170631. +
  170632. + if (vertical) {
  170633. + input_f = 2;
  170634. + input_m = 8;
  170635. + output_f = 8;
  170636. + output_m = 2;
  170637. + } else {
  170638. + input_f = f_calc(input_pixelformat, 0, NULL);
  170639. + input_m = m_calc(input_pixelformat);
  170640. + output_f = input_m;
  170641. + output_m = m_calc(output_pixelformat);
  170642. + }
  170643. + if ((input_frame_width < 4) || (output_frame_width < 4))
  170644. + return 1;
  170645. +
  170646. + irr_opt = div_u64((((u64)(input_frame_width - 1)) << 32),
  170647. + (output_frame_width - 1));
  170648. + rr_opt = div_u64((((u64)(output_frame_width - 1)) << 32),
  170649. + (input_frame_width - 1));
  170650. +
  170651. + if ((input_m == 0) || (output_m == 0) || (input_f == 0) || (output_f == 0)
  170652. + || (input_frame_width < (2 * input_f))
  170653. + || ((((u64)output_frame_width) << 32) <
  170654. + (2 * ((((u64)output_f) << 32) + (input_f * rr_opt))))
  170655. + || (maximal_stripe_width < output_f)
  170656. + || ((output_frame_width <= maximal_stripe_width)
  170657. + && (equal_stripes == 0))
  170658. + || ((2 * maximal_stripe_width) < output_frame_width))
  170659. + return 1;
  170660. +
  170661. + if (output_f % output_m)
  170662. + status += 2;
  170663. +
  170664. + temp = truncate(0, (((u64)output_frame_width) << 32), output_m);
  170665. + if (temp < output_frame_width) {
  170666. + output_frame_width = temp;
  170667. + status += 4;
  170668. + }
  170669. +
  170670. + pr_debug("---------------->\n"
  170671. + "if = %d\n"
  170672. + "im = %d\n"
  170673. + "of = %d\n"
  170674. + "om = %d\n"
  170675. + "irr_opt = %llu\n"
  170676. + "rr_opt = %llu\n"
  170677. + "cirr = %llu\n"
  170678. + "pixel in = %08x\n"
  170679. + "pixel out = %08x\n"
  170680. + "ifw = %d\n"
  170681. + "ofwidth = %d\n",
  170682. + input_f,
  170683. + input_m,
  170684. + output_f,
  170685. + output_m,
  170686. + irr_opt,
  170687. + rr_opt,
  170688. + cirr,
  170689. + input_pixelformat,
  170690. + output_pixelformat,
  170691. + input_frame_width,
  170692. + output_frame_width
  170693. + );
  170694. +
  170695. + if (equal_stripes) {
  170696. + if ((irr_opt > cirr) /* overlap in the input is not requested */
  170697. + && ((input_frame_width % (input_m << 1)) == 0)
  170698. + && ((input_frame_width % (input_f << 1)) == 0)
  170699. + && ((output_frame_width % (output_m << 1)) == 0)
  170700. + && ((output_frame_width % (output_f << 1)) == 0)) {
  170701. + /* without overlap */
  170702. + left->input_width = right->input_width = right->input_column =
  170703. + input_frame_width >> 1;
  170704. + left->output_width = right->output_width = right->output_column =
  170705. + output_frame_width >> 1;
  170706. + left->input_column = 0;
  170707. + left->output_column = 0;
  170708. + div = div_u64(((((u64)irr_steps) << 32) *
  170709. + (right->input_width - 1)), (right->output_width - 1));
  170710. + left->irr = right->irr = truncate(0, div, 1);
  170711. + } else { /* with overlap */
  170712. + onw = truncate(0, (((u64)output_frame_width - 1) << 32) >> 1,
  170713. + output_f);
  170714. + inw = truncate(0, onw * irr_opt, input_f);
  170715. + /* this is the maximal inw which allows the same resizing ratio */
  170716. + /* in both stripes */
  170717. + onw = truncate(1, (inw * rr_opt), output_f);
  170718. + div = div_u64((((u64)(irr_steps * inw)) <<
  170719. + 32), onw);
  170720. + left->irr = right->irr = truncate(0, div, 1);
  170721. + left->output_width = right->output_width =
  170722. + output_frame_width - onw;
  170723. + /* These are valid assignments for output_width, */
  170724. + /* assuming output_f is a multiple of output_m */
  170725. + div = (((u64)(left->output_width-1) * (left->irr)) << 32);
  170726. + div = (((u64)1) << 32) + div_u64(div, irr_steps);
  170727. +
  170728. + left->input_width = right->input_width = truncate(1, div, input_m);
  170729. +
  170730. + div = div_u64((((u64)((right->output_width - 1) * right->irr)) <<
  170731. + 32), irr_steps);
  170732. + difwr = (((u64)(input_frame_width - 1 - inw)) << 32) - div;
  170733. + div = div_u64((difwr + (((u64)input_f) << 32)), 2);
  170734. + left->input_column = truncate(0, div, input_f);
  170735. +
  170736. +
  170737. + /* This splits the truncated input columns evenly */
  170738. + /* between the left and right margins */
  170739. + right->input_column = left->input_column + inw;
  170740. + left->output_column = 0;
  170741. + right->output_column = onw;
  170742. + }
  170743. + if (left->input_width > left->output_width) {
  170744. + if (calc_split_resize_coeffs(left->input_width,
  170745. + left->output_width,
  170746. + &resize_coeff,
  170747. + &downsize_coeff) < 0)
  170748. + return -EINVAL;
  170749. +
  170750. + if (downsize_coeff > 0) {
  170751. + left->irr = right->irr =
  170752. + (downsize_coeff << 14) | resize_coeff;
  170753. + }
  170754. + }
  170755. + pr_debug("inw %d, onw %d, ilw %d, ilc %d, olw %d,"
  170756. + " irw %d, irc %d, orw %d, orc %d, "
  170757. + "difwr %llu, lirr %u\n",
  170758. + inw, onw, left->input_width,
  170759. + left->input_column, left->output_width,
  170760. + right->input_width, right->input_column,
  170761. + right->output_width,
  170762. + right->output_column, difwr, left->irr);
  170763. + } else { /* independent stripes */
  170764. + onw_min = output_frame_width - maximal_stripe_width;
  170765. + /* onw is a multiple of output_f, in the range */
  170766. + /* [max(output_f,output_frame_width-maximal_stripe_width),*/
  170767. + /*min(output_frame_width-2,maximal_stripe_width)] */
  170768. + /* definitely beyond the cost of any valid setting */
  170769. + cost_min = (((u64)input_frame_width) << 32) + cr;
  170770. + onw = truncate(0, ((u64)maximal_stripe_width), output_f);
  170771. + if (output_frame_width - onw == 1)
  170772. + onw -= output_f; /* => onw and output_frame_width-1-onw are positive */
  170773. + inw = truncate(0, onw * irr_opt, input_f);
  170774. + /* this is the maximal inw which allows the same resizing ratio */
  170775. + /* in both stripes */
  170776. + onw = truncate(1, inw * rr_opt, output_f);
  170777. + do {
  170778. + div = div_u64((((u64)(irr_steps * inw)) << 32), onw);
  170779. + left->irr = truncate(0, div, 1);
  170780. + div = div_u64((((u64)(onw * left->irr)) << 32),
  170781. + irr_steps);
  170782. + dinw = (((u64)inw) << 32) - div;
  170783. +
  170784. + div = div_u64((((u64)((output_frame_width - 1 - onw) * left->irr)) <<
  170785. + 32), irr_steps);
  170786. +
  170787. + difwl = (((u64)(input_frame_width - 1 - inw)) << 32) - div;
  170788. +
  170789. + cost = difwl + (((u64)(cr * dinw)) >> 32);
  170790. +
  170791. + if (cost < cost_min) {
  170792. + inw_best = inw;
  170793. + cost_min = cost;
  170794. + }
  170795. +
  170796. + inw -= input_f;
  170797. + onw = truncate(1, inw * rr_opt, output_f);
  170798. + /* This is the minimal onw which allows the same resizing ratio */
  170799. + /* in both stripes */
  170800. + } while (onw >= onw_min);
  170801. +
  170802. + inw = inw_best;
  170803. + onw = truncate(1, inw * rr_opt, output_f);
  170804. + div = div_u64((((u64)(irr_steps * inw)) << 32), onw);
  170805. + left->irr = truncate(0, div, 1);
  170806. +
  170807. + left->output_width = onw;
  170808. + right->output_width = output_frame_width - onw;
  170809. + /* These are valid assignments for output_width, */
  170810. + /* assuming output_f is a multiple of output_m */
  170811. + left->input_width = truncate(1, ((u64)(inw + 1)) << 32, input_m);
  170812. + right->input_width = truncate(1, ((u64)(input_frame_width - inw)) <<
  170813. + 32, input_m);
  170814. +
  170815. + div = div_u64((((u64)(irr_steps * (input_frame_width - 1 - inw))) <<
  170816. + 32), (right->output_width - 1));
  170817. + right->irr = truncate(0, div, 1);
  170818. + temp = truncate(0, ((u64)left->irr) * ((((u64)1) << 32) + dirr), 1);
  170819. + if (temp < right->irr)
  170820. + right->irr = temp;
  170821. + div = div_u64(((u64)((right->output_width - 1) * right->irr) <<
  170822. + 32), irr_steps);
  170823. + difwr = (u64)(input_frame_width - 1 - inw) - div;
  170824. +
  170825. +
  170826. + div = div_u64((difwr + (((u64)input_f) << 32)), 2);
  170827. + left->input_column = truncate(0, div, input_f);
  170828. +
  170829. + /* This splits the truncated input columns evenly */
  170830. + /* between the left and right margins */
  170831. + right->input_column = left->input_column + inw;
  170832. + left->output_column = 0;
  170833. + right->output_column = onw;
  170834. + if (left->input_width > left->output_width) {
  170835. + if (calc_split_resize_coeffs(left->input_width,
  170836. + left->output_width,
  170837. + &resize_coeff,
  170838. + &downsize_coeff) < 0)
  170839. + return -EINVAL;
  170840. + left->irr = (downsize_coeff << 14) | resize_coeff;
  170841. + }
  170842. + if (right->input_width > right->output_width) {
  170843. + if (calc_split_resize_coeffs(right->input_width,
  170844. + right->output_width,
  170845. + &resize_coeff,
  170846. + &downsize_coeff) < 0)
  170847. + return -EINVAL;
  170848. + right->irr = (downsize_coeff << 14) | resize_coeff;
  170849. + }
  170850. + }
  170851. + return status;
  170852. +}
  170853. +EXPORT_SYMBOL(ipu_calc_stripes_sizes);
  170854. diff -Nur linux-3.14.14/drivers/mxc/ipu3/ipu_capture.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_capture.c
  170855. --- linux-3.14.14/drivers/mxc/ipu3/ipu_capture.c 1969-12-31 18:00:00.000000000 -0600
  170856. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_capture.c 2014-12-08 00:31:53.472418001 -0600
  170857. @@ -0,0 +1,816 @@
  170858. +/*
  170859. + * Copyright 2008-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  170860. + */
  170861. +
  170862. +/*
  170863. + * The code contained herein is licensed under the GNU General Public
  170864. + * License. You may obtain a copy of the GNU General Public License
  170865. + * Version 2 or later at the following locations:
  170866. + *
  170867. + * http://www.opensource.org/licenses/gpl-license.html
  170868. + * http://www.gnu.org/copyleft/gpl.html
  170869. + */
  170870. +
  170871. +/*!
  170872. + * @file ipu_capture.c
  170873. + *
  170874. + * @brief IPU capture dase functions
  170875. + *
  170876. + * @ingroup IPU
  170877. + */
  170878. +#include <linux/clk.h>
  170879. +#include <linux/delay.h>
  170880. +#include <linux/errno.h>
  170881. +#include <linux/init.h>
  170882. +#include <linux/io.h>
  170883. +#include <linux/ipu-v3.h>
  170884. +#include <linux/module.h>
  170885. +#include <linux/spinlock.h>
  170886. +#include <linux/types.h>
  170887. +
  170888. +#include "ipu_prv.h"
  170889. +#include "ipu_regs.h"
  170890. +
  170891. +/*!
  170892. + * _ipu_csi_mclk_set
  170893. + *
  170894. + * @param ipu ipu handler
  170895. + * @param pixel_clk desired pixel clock frequency in Hz
  170896. + * @param csi csi 0 or csi 1
  170897. + *
  170898. + * @return Returns 0 on success or negative error code on fail
  170899. + */
  170900. +int _ipu_csi_mclk_set(struct ipu_soc *ipu, uint32_t pixel_clk, uint32_t csi)
  170901. +{
  170902. + uint32_t temp;
  170903. + uint32_t div_ratio;
  170904. +
  170905. + div_ratio = (clk_get_rate(ipu->ipu_clk) / pixel_clk) - 1;
  170906. +
  170907. + if (div_ratio > 0xFF || div_ratio < 0) {
  170908. + dev_dbg(ipu->dev, "value of pixel_clk extends normal range\n");
  170909. + return -EINVAL;
  170910. + }
  170911. +
  170912. + temp = ipu_csi_read(ipu, csi, CSI_SENS_CONF);
  170913. + temp &= ~CSI_SENS_CONF_DIVRATIO_MASK;
  170914. + ipu_csi_write(ipu, csi, temp |
  170915. + (div_ratio << CSI_SENS_CONF_DIVRATIO_SHIFT),
  170916. + CSI_SENS_CONF);
  170917. +
  170918. + return 0;
  170919. +}
  170920. +
  170921. +/*!
  170922. + * ipu_csi_init_interface
  170923. + * Sets initial values for the CSI registers.
  170924. + * The width and height of the sensor and the actual frame size will be
  170925. + * set to the same values.
  170926. + * @param ipu ipu handler
  170927. + * @param width Sensor width
  170928. + * @param height Sensor height
  170929. + * @param pixel_fmt pixel format
  170930. + * @param cfg_param ipu_csi_signal_cfg_t structure
  170931. + * @param csi csi 0 or csi 1
  170932. + *
  170933. + * @return 0 for success, -EINVAL for error
  170934. + */
  170935. +int32_t
  170936. +ipu_csi_init_interface(struct ipu_soc *ipu, uint16_t width, uint16_t height,
  170937. + uint32_t pixel_fmt, ipu_csi_signal_cfg_t cfg_param)
  170938. +{
  170939. + uint32_t data = 0;
  170940. + uint32_t csi = cfg_param.csi;
  170941. +
  170942. + /* Set SENS_DATA_FORMAT bits (8, 9 and 10)
  170943. + RGB or YUV444 is 0 which is current value in data so not set
  170944. + explicitly
  170945. + This is also the default value if attempts are made to set it to
  170946. + something invalid. */
  170947. + switch (pixel_fmt) {
  170948. + case IPU_PIX_FMT_YUYV:
  170949. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV;
  170950. + break;
  170951. + case IPU_PIX_FMT_UYVY:
  170952. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY;
  170953. + break;
  170954. + case IPU_PIX_FMT_RGB24:
  170955. + case IPU_PIX_FMT_BGR24:
  170956. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB_YUV444;
  170957. + break;
  170958. + case IPU_PIX_FMT_GENERIC:
  170959. + case IPU_PIX_FMT_GENERIC_16:
  170960. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
  170961. + break;
  170962. + case IPU_PIX_FMT_RGB565:
  170963. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565;
  170964. + break;
  170965. + case IPU_PIX_FMT_RGB555:
  170966. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB555;
  170967. + break;
  170968. + default:
  170969. + return -EINVAL;
  170970. + }
  170971. +
  170972. + /* Set the CSI_SENS_CONF register remaining fields */
  170973. + data |= cfg_param.data_width << CSI_SENS_CONF_DATA_WIDTH_SHIFT |
  170974. + cfg_param.data_fmt << CSI_SENS_CONF_DATA_FMT_SHIFT |
  170975. + cfg_param.data_pol << CSI_SENS_CONF_DATA_POL_SHIFT |
  170976. + cfg_param.Vsync_pol << CSI_SENS_CONF_VSYNC_POL_SHIFT |
  170977. + cfg_param.Hsync_pol << CSI_SENS_CONF_HSYNC_POL_SHIFT |
  170978. + cfg_param.pixclk_pol << CSI_SENS_CONF_PIX_CLK_POL_SHIFT |
  170979. + cfg_param.ext_vsync << CSI_SENS_CONF_EXT_VSYNC_SHIFT |
  170980. + cfg_param.clk_mode << CSI_SENS_CONF_SENS_PRTCL_SHIFT |
  170981. + cfg_param.pack_tight << CSI_SENS_CONF_PACK_TIGHT_SHIFT |
  170982. + cfg_param.force_eof << CSI_SENS_CONF_FORCE_EOF_SHIFT |
  170983. + cfg_param.data_en_pol << CSI_SENS_CONF_DATA_EN_POL_SHIFT;
  170984. +
  170985. + _ipu_get(ipu);
  170986. +
  170987. + mutex_lock(&ipu->mutex_lock);
  170988. +
  170989. + ipu_csi_write(ipu, csi, data, CSI_SENS_CONF);
  170990. +
  170991. + /* Setup sensor frame size */
  170992. + ipu_csi_write(ipu, csi, (width - 1) | (height - 1) << 16, CSI_SENS_FRM_SIZE);
  170993. +
  170994. + /* Set CCIR registers */
  170995. + if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) {
  170996. + ipu_csi_write(ipu, csi, 0x40030, CSI_CCIR_CODE_1);
  170997. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  170998. + } else if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED) {
  170999. + if (width == 720 && height == 625) {
  171000. + /* PAL case */
  171001. + /*
  171002. + * Field0BlankEnd = 0x6, Field0BlankStart = 0x2,
  171003. + * Field0ActiveEnd = 0x4, Field0ActiveStart = 0
  171004. + */
  171005. + ipu_csi_write(ipu, csi, 0x40596, CSI_CCIR_CODE_1);
  171006. + /*
  171007. + * Field1BlankEnd = 0x7, Field1BlankStart = 0x3,
  171008. + * Field1ActiveEnd = 0x5, Field1ActiveStart = 0x1
  171009. + */
  171010. + ipu_csi_write(ipu, csi, 0xD07DF, CSI_CCIR_CODE_2);
  171011. +
  171012. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  171013. +
  171014. + } else if (width == 720 && height == 525) {
  171015. + /* NTSC case */
  171016. + /*
  171017. + * Field0BlankEnd = 0x7, Field0BlankStart = 0x3,
  171018. + * Field0ActiveEnd = 0x5, Field0ActiveStart = 0x1
  171019. + */
  171020. + ipu_csi_write(ipu, csi, 0xD07DF, CSI_CCIR_CODE_1);
  171021. + /*
  171022. + * Field1BlankEnd = 0x6, Field1BlankStart = 0x2,
  171023. + * Field1ActiveEnd = 0x4, Field1ActiveStart = 0
  171024. + */
  171025. + ipu_csi_write(ipu, csi, 0x40596, CSI_CCIR_CODE_2);
  171026. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  171027. + } else {
  171028. + dev_err(ipu->dev, "Unsupported CCIR656 interlaced "
  171029. + "video mode\n");
  171030. + mutex_unlock(&ipu->mutex_lock);
  171031. + _ipu_put(ipu);
  171032. + return -EINVAL;
  171033. + }
  171034. + _ipu_csi_ccir_err_detection_enable(ipu, csi);
  171035. + } else if ((cfg_param.clk_mode ==
  171036. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR) ||
  171037. + (cfg_param.clk_mode ==
  171038. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR) ||
  171039. + (cfg_param.clk_mode ==
  171040. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR) ||
  171041. + (cfg_param.clk_mode ==
  171042. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR)) {
  171043. + ipu_csi_write(ipu, csi, 0x40030, CSI_CCIR_CODE_1);
  171044. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  171045. + _ipu_csi_ccir_err_detection_enable(ipu, csi);
  171046. + } else if ((cfg_param.clk_mode == IPU_CSI_CLK_MODE_GATED_CLK) ||
  171047. + (cfg_param.clk_mode == IPU_CSI_CLK_MODE_NONGATED_CLK)) {
  171048. + _ipu_csi_ccir_err_detection_disable(ipu, csi);
  171049. + }
  171050. +
  171051. + dev_dbg(ipu->dev, "CSI_SENS_CONF = 0x%08X\n",
  171052. + ipu_csi_read(ipu, csi, CSI_SENS_CONF));
  171053. + dev_dbg(ipu->dev, "CSI_ACT_FRM_SIZE = 0x%08X\n",
  171054. + ipu_csi_read(ipu, csi, CSI_ACT_FRM_SIZE));
  171055. +
  171056. + mutex_unlock(&ipu->mutex_lock);
  171057. +
  171058. + _ipu_put(ipu);
  171059. +
  171060. + return 0;
  171061. +}
  171062. +EXPORT_SYMBOL(ipu_csi_init_interface);
  171063. +
  171064. +/*!
  171065. + * ipu_csi_get_sensor_protocol
  171066. + *
  171067. + * @param ipu ipu handler
  171068. + * @param csi csi 0 or csi 1
  171069. + *
  171070. + * @return Returns sensor protocol
  171071. + */
  171072. +int32_t ipu_csi_get_sensor_protocol(struct ipu_soc *ipu, uint32_t csi)
  171073. +{
  171074. + int ret;
  171075. + _ipu_get(ipu);
  171076. + ret = (ipu_csi_read(ipu, csi, CSI_SENS_CONF) &
  171077. + CSI_SENS_CONF_SENS_PRTCL_MASK) >>
  171078. + CSI_SENS_CONF_SENS_PRTCL_SHIFT;
  171079. + _ipu_put(ipu);
  171080. + return ret;
  171081. +}
  171082. +EXPORT_SYMBOL(ipu_csi_get_sensor_protocol);
  171083. +
  171084. +/*!
  171085. + * ipu_csi_enable_mclk
  171086. + *
  171087. + * @param ipu ipu handler
  171088. + * @param csi csi 0 or csi 1
  171089. + * @param flag true to enable mclk, false to disable mclk
  171090. + * @param wait true to wait 100ms make clock stable, false not wait
  171091. + *
  171092. + * @return Returns 0 on success
  171093. + */
  171094. +int ipu_csi_enable_mclk(struct ipu_soc *ipu, int csi, bool flag, bool wait)
  171095. +{
  171096. + /* Return immediately if there is no csi_clk to manage */
  171097. + if (ipu->csi_clk[csi] == NULL)
  171098. + return 0;
  171099. +
  171100. + if (flag) {
  171101. + clk_enable(ipu->csi_clk[csi]);
  171102. + if (wait == true)
  171103. + msleep(10);
  171104. + } else {
  171105. + clk_disable(ipu->csi_clk[csi]);
  171106. + }
  171107. +
  171108. + return 0;
  171109. +}
  171110. +EXPORT_SYMBOL(ipu_csi_enable_mclk);
  171111. +
  171112. +/*!
  171113. + * ipu_csi_get_window_size
  171114. + *
  171115. + * @param ipu ipu handler
  171116. + * @param width pointer to window width
  171117. + * @param height pointer to window height
  171118. + * @param csi csi 0 or csi 1
  171119. + */
  171120. +void ipu_csi_get_window_size(struct ipu_soc *ipu, uint32_t *width, uint32_t *height, uint32_t csi)
  171121. +{
  171122. + uint32_t reg;
  171123. +
  171124. + _ipu_get(ipu);
  171125. +
  171126. + mutex_lock(&ipu->mutex_lock);
  171127. +
  171128. + reg = ipu_csi_read(ipu, csi, CSI_ACT_FRM_SIZE);
  171129. + *width = (reg & 0xFFFF) + 1;
  171130. + *height = (reg >> 16 & 0xFFFF) + 1;
  171131. +
  171132. + mutex_unlock(&ipu->mutex_lock);
  171133. +
  171134. + _ipu_put(ipu);
  171135. +}
  171136. +EXPORT_SYMBOL(ipu_csi_get_window_size);
  171137. +
  171138. +/*!
  171139. + * ipu_csi_set_window_size
  171140. + *
  171141. + * @param ipu ipu handler
  171142. + * @param width window width
  171143. + * @param height window height
  171144. + * @param csi csi 0 or csi 1
  171145. + */
  171146. +void ipu_csi_set_window_size(struct ipu_soc *ipu, uint32_t width, uint32_t height, uint32_t csi)
  171147. +{
  171148. + _ipu_get(ipu);
  171149. +
  171150. + mutex_lock(&ipu->mutex_lock);
  171151. +
  171152. + ipu_csi_write(ipu, csi, (width - 1) | (height - 1) << 16, CSI_ACT_FRM_SIZE);
  171153. +
  171154. + mutex_unlock(&ipu->mutex_lock);
  171155. +
  171156. + _ipu_put(ipu);
  171157. +}
  171158. +EXPORT_SYMBOL(ipu_csi_set_window_size);
  171159. +
  171160. +/*!
  171161. + * ipu_csi_set_window_pos
  171162. + *
  171163. + * @param ipu ipu handler
  171164. + * @param left uint32 window x start
  171165. + * @param top uint32 window y start
  171166. + * @param csi csi 0 or csi 1
  171167. + */
  171168. +void ipu_csi_set_window_pos(struct ipu_soc *ipu, uint32_t left, uint32_t top, uint32_t csi)
  171169. +{
  171170. + uint32_t temp;
  171171. +
  171172. + _ipu_get(ipu);
  171173. +
  171174. + mutex_lock(&ipu->mutex_lock);
  171175. +
  171176. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  171177. + temp &= ~(CSI_HSC_MASK | CSI_VSC_MASK);
  171178. + temp |= ((top << CSI_VSC_SHIFT) | (left << CSI_HSC_SHIFT));
  171179. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  171180. +
  171181. + mutex_unlock(&ipu->mutex_lock);
  171182. +
  171183. + _ipu_put(ipu);
  171184. +}
  171185. +EXPORT_SYMBOL(ipu_csi_set_window_pos);
  171186. +
  171187. +/*!
  171188. + * _ipu_csi_horizontal_downsize_enable
  171189. + * Enable horizontal downsizing(decimation) by 2.
  171190. + *
  171191. + * @param ipu ipu handler
  171192. + * @param csi csi 0 or csi 1
  171193. + */
  171194. +void _ipu_csi_horizontal_downsize_enable(struct ipu_soc *ipu, uint32_t csi)
  171195. +{
  171196. + uint32_t temp;
  171197. +
  171198. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  171199. + temp |= CSI_HORI_DOWNSIZE_EN;
  171200. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  171201. +}
  171202. +
  171203. +/*!
  171204. + * _ipu_csi_horizontal_downsize_disable
  171205. + * Disable horizontal downsizing(decimation) by 2.
  171206. + *
  171207. + * @param ipu ipu handler
  171208. + * @param csi csi 0 or csi 1
  171209. + */
  171210. +void _ipu_csi_horizontal_downsize_disable(struct ipu_soc *ipu, uint32_t csi)
  171211. +{
  171212. + uint32_t temp;
  171213. +
  171214. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  171215. + temp &= ~CSI_HORI_DOWNSIZE_EN;
  171216. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  171217. +}
  171218. +
  171219. +/*!
  171220. + * _ipu_csi_vertical_downsize_enable
  171221. + * Enable vertical downsizing(decimation) by 2.
  171222. + *
  171223. + * @param ipu ipu handler
  171224. + * @param csi csi 0 or csi 1
  171225. + */
  171226. +void _ipu_csi_vertical_downsize_enable(struct ipu_soc *ipu, uint32_t csi)
  171227. +{
  171228. + uint32_t temp;
  171229. +
  171230. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  171231. + temp |= CSI_VERT_DOWNSIZE_EN;
  171232. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  171233. +}
  171234. +
  171235. +/*!
  171236. + * _ipu_csi_vertical_downsize_disable
  171237. + * Disable vertical downsizing(decimation) by 2.
  171238. + *
  171239. + * @param ipu ipu handler
  171240. + * @param csi csi 0 or csi 1
  171241. + */
  171242. +void _ipu_csi_vertical_downsize_disable(struct ipu_soc *ipu, uint32_t csi)
  171243. +{
  171244. + uint32_t temp;
  171245. +
  171246. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  171247. + temp &= ~CSI_VERT_DOWNSIZE_EN;
  171248. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  171249. +}
  171250. +
  171251. +/*!
  171252. + * _ipu_csi_set_test_generator
  171253. + *
  171254. + * @param ipu ipu handler
  171255. + * @param active 1 for active and 0 for inactive
  171256. + * @param r_value red value for the generated pattern of even pixel
  171257. + * @param g_value green value for the generated pattern of even
  171258. + * pixel
  171259. + * @param b_value blue value for the generated pattern of even pixel
  171260. + * @param pixel_clk desired pixel clock frequency in Hz
  171261. + * @param csi csi 0 or csi 1
  171262. + */
  171263. +void _ipu_csi_set_test_generator(struct ipu_soc *ipu, bool active, uint32_t r_value,
  171264. + uint32_t g_value, uint32_t b_value, uint32_t pix_clk, uint32_t csi)
  171265. +{
  171266. + uint32_t temp;
  171267. +
  171268. + temp = ipu_csi_read(ipu, csi, CSI_TST_CTRL);
  171269. +
  171270. + if (active == false) {
  171271. + temp &= ~CSI_TEST_GEN_MODE_EN;
  171272. + ipu_csi_write(ipu, csi, temp, CSI_TST_CTRL);
  171273. + } else {
  171274. + /* Set sensb_mclk div_ratio*/
  171275. + _ipu_csi_mclk_set(ipu, pix_clk, csi);
  171276. +
  171277. + temp &= ~(CSI_TEST_GEN_R_MASK | CSI_TEST_GEN_G_MASK |
  171278. + CSI_TEST_GEN_B_MASK);
  171279. + temp |= CSI_TEST_GEN_MODE_EN;
  171280. + temp |= (r_value << CSI_TEST_GEN_R_SHIFT) |
  171281. + (g_value << CSI_TEST_GEN_G_SHIFT) |
  171282. + (b_value << CSI_TEST_GEN_B_SHIFT);
  171283. + ipu_csi_write(ipu, csi, temp, CSI_TST_CTRL);
  171284. + }
  171285. +}
  171286. +
  171287. +/*!
  171288. + * _ipu_csi_ccir_err_detection_en
  171289. + * Enable error detection and correction for
  171290. + * CCIR interlaced mode with protection bit.
  171291. + *
  171292. + * @param ipu ipu handler
  171293. + * @param csi csi 0 or csi 1
  171294. + */
  171295. +void _ipu_csi_ccir_err_detection_enable(struct ipu_soc *ipu, uint32_t csi)
  171296. +{
  171297. + uint32_t temp;
  171298. +
  171299. + temp = ipu_csi_read(ipu, csi, CSI_CCIR_CODE_1);
  171300. + temp |= CSI_CCIR_ERR_DET_EN;
  171301. + ipu_csi_write(ipu, csi, temp, CSI_CCIR_CODE_1);
  171302. +
  171303. +}
  171304. +
  171305. +/*!
  171306. + * _ipu_csi_ccir_err_detection_disable
  171307. + * Disable error detection and correction for
  171308. + * CCIR interlaced mode with protection bit.
  171309. + *
  171310. + * @param ipu ipu handler
  171311. + * @param csi csi 0 or csi 1
  171312. + */
  171313. +void _ipu_csi_ccir_err_detection_disable(struct ipu_soc *ipu, uint32_t csi)
  171314. +{
  171315. + uint32_t temp;
  171316. +
  171317. + temp = ipu_csi_read(ipu, csi, CSI_CCIR_CODE_1);
  171318. + temp &= ~CSI_CCIR_ERR_DET_EN;
  171319. + ipu_csi_write(ipu, csi, temp, CSI_CCIR_CODE_1);
  171320. +
  171321. +}
  171322. +
  171323. +/*!
  171324. + * _ipu_csi_set_mipi_di
  171325. + *
  171326. + * @param ipu ipu handler
  171327. + * @param num MIPI data identifier 0-3 handled by CSI
  171328. + * @param di_val data identifier value
  171329. + * @param csi csi 0 or csi 1
  171330. + *
  171331. + * @return Returns 0 on success or negative error code on fail
  171332. + */
  171333. +int _ipu_csi_set_mipi_di(struct ipu_soc *ipu, uint32_t num, uint32_t di_val, uint32_t csi)
  171334. +{
  171335. + uint32_t temp;
  171336. + int retval = 0;
  171337. +
  171338. + if (di_val > 0xFFL) {
  171339. + retval = -EINVAL;
  171340. + goto err;
  171341. + }
  171342. +
  171343. + temp = ipu_csi_read(ipu, csi, CSI_MIPI_DI);
  171344. +
  171345. + switch (num) {
  171346. + case IPU_CSI_MIPI_DI0:
  171347. + temp &= ~CSI_MIPI_DI0_MASK;
  171348. + temp |= (di_val << CSI_MIPI_DI0_SHIFT);
  171349. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  171350. + break;
  171351. + case IPU_CSI_MIPI_DI1:
  171352. + temp &= ~CSI_MIPI_DI1_MASK;
  171353. + temp |= (di_val << CSI_MIPI_DI1_SHIFT);
  171354. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  171355. + break;
  171356. + case IPU_CSI_MIPI_DI2:
  171357. + temp &= ~CSI_MIPI_DI2_MASK;
  171358. + temp |= (di_val << CSI_MIPI_DI2_SHIFT);
  171359. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  171360. + break;
  171361. + case IPU_CSI_MIPI_DI3:
  171362. + temp &= ~CSI_MIPI_DI3_MASK;
  171363. + temp |= (di_val << CSI_MIPI_DI3_SHIFT);
  171364. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  171365. + break;
  171366. + default:
  171367. + retval = -EINVAL;
  171368. + }
  171369. +
  171370. +err:
  171371. + return retval;
  171372. +}
  171373. +
  171374. +/*!
  171375. + * _ipu_csi_set_skip_isp
  171376. + *
  171377. + * @param ipu ipu handler
  171378. + * @param skip select frames to be skipped and set the
  171379. + * correspond bits to 1
  171380. + * @param max_ratio number of frames in a skipping set and the
  171381. + * maximum value of max_ratio is 5
  171382. + * @param csi csi 0 or csi 1
  171383. + *
  171384. + * @return Returns 0 on success or negative error code on fail
  171385. + */
  171386. +int _ipu_csi_set_skip_isp(struct ipu_soc *ipu, uint32_t skip, uint32_t max_ratio, uint32_t csi)
  171387. +{
  171388. + uint32_t temp;
  171389. + int retval = 0;
  171390. +
  171391. + if (max_ratio > 5) {
  171392. + retval = -EINVAL;
  171393. + goto err;
  171394. + }
  171395. +
  171396. + temp = ipu_csi_read(ipu, csi, CSI_SKIP);
  171397. + temp &= ~(CSI_MAX_RATIO_SKIP_ISP_MASK | CSI_SKIP_ISP_MASK);
  171398. + temp |= (max_ratio << CSI_MAX_RATIO_SKIP_ISP_SHIFT) |
  171399. + (skip << CSI_SKIP_ISP_SHIFT);
  171400. + ipu_csi_write(ipu, csi, temp, CSI_SKIP);
  171401. +
  171402. +err:
  171403. + return retval;
  171404. +}
  171405. +
  171406. +/*!
  171407. + * _ipu_csi_set_skip_smfc
  171408. + *
  171409. + * @param ipu ipu handler
  171410. + * @param skip select frames to be skipped and set the
  171411. + * correspond bits to 1
  171412. + * @param max_ratio number of frames in a skipping set and the
  171413. + * maximum value of max_ratio is 5
  171414. + * @param id csi to smfc skipping id
  171415. + * @param csi csi 0 or csi 1
  171416. + *
  171417. + * @return Returns 0 on success or negative error code on fail
  171418. + */
  171419. +int _ipu_csi_set_skip_smfc(struct ipu_soc *ipu, uint32_t skip,
  171420. + uint32_t max_ratio, uint32_t id, uint32_t csi)
  171421. +{
  171422. + uint32_t temp;
  171423. + int retval = 0;
  171424. +
  171425. + if (max_ratio > 5 || id > 3) {
  171426. + retval = -EINVAL;
  171427. + goto err;
  171428. + }
  171429. +
  171430. + temp = ipu_csi_read(ipu, csi, CSI_SKIP);
  171431. + temp &= ~(CSI_MAX_RATIO_SKIP_SMFC_MASK | CSI_ID_2_SKIP_MASK |
  171432. + CSI_SKIP_SMFC_MASK);
  171433. + temp |= (max_ratio << CSI_MAX_RATIO_SKIP_SMFC_SHIFT) |
  171434. + (id << CSI_ID_2_SKIP_SHIFT) |
  171435. + (skip << CSI_SKIP_SMFC_SHIFT);
  171436. + ipu_csi_write(ipu, csi, temp, CSI_SKIP);
  171437. +
  171438. +err:
  171439. + return retval;
  171440. +}
  171441. +
  171442. +/*!
  171443. + * _ipu_smfc_init
  171444. + * Map CSI frames to IDMAC channels.
  171445. + *
  171446. + * @param ipu ipu handler
  171447. + * @param channel IDMAC channel 0-3
  171448. + * @param mipi_id mipi id number 0-3
  171449. + * @param csi csi0 or csi1
  171450. + */
  171451. +void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi)
  171452. +{
  171453. + uint32_t temp;
  171454. +
  171455. + temp = ipu_smfc_read(ipu, SMFC_MAP);
  171456. +
  171457. + switch (channel) {
  171458. + case CSI_MEM0:
  171459. + temp &= ~SMFC_MAP_CH0_MASK;
  171460. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH0_SHIFT;
  171461. + break;
  171462. + case CSI_MEM1:
  171463. + temp &= ~SMFC_MAP_CH1_MASK;
  171464. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH1_SHIFT;
  171465. + break;
  171466. + case CSI_MEM2:
  171467. + temp &= ~SMFC_MAP_CH2_MASK;
  171468. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH2_SHIFT;
  171469. + break;
  171470. + case CSI_MEM3:
  171471. + temp &= ~SMFC_MAP_CH3_MASK;
  171472. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH3_SHIFT;
  171473. + break;
  171474. + default:
  171475. + return;
  171476. + }
  171477. +
  171478. + ipu_smfc_write(ipu, temp, SMFC_MAP);
  171479. +}
  171480. +
  171481. +/*!
  171482. + * _ipu_smfc_set_wmc
  171483. + * Caution: The number of required channels, the enabled channels
  171484. + * and the FIFO size per channel are configured restrictedly.
  171485. + *
  171486. + * @param ipu ipu handler
  171487. + * @param channel IDMAC channel 0-3
  171488. + * @param set set 1 or clear 0
  171489. + * @param level water mark level when FIFO is on the
  171490. + * relative size
  171491. + */
  171492. +void _ipu_smfc_set_wmc(struct ipu_soc *ipu, ipu_channel_t channel, bool set, uint32_t level)
  171493. +{
  171494. + uint32_t temp;
  171495. +
  171496. + temp = ipu_smfc_read(ipu, SMFC_WMC);
  171497. +
  171498. + switch (channel) {
  171499. + case CSI_MEM0:
  171500. + if (set == true) {
  171501. + temp &= ~SMFC_WM0_SET_MASK;
  171502. + temp |= level << SMFC_WM0_SET_SHIFT;
  171503. + } else {
  171504. + temp &= ~SMFC_WM0_CLR_MASK;
  171505. + temp |= level << SMFC_WM0_CLR_SHIFT;
  171506. + }
  171507. + break;
  171508. + case CSI_MEM1:
  171509. + if (set == true) {
  171510. + temp &= ~SMFC_WM1_SET_MASK;
  171511. + temp |= level << SMFC_WM1_SET_SHIFT;
  171512. + } else {
  171513. + temp &= ~SMFC_WM1_CLR_MASK;
  171514. + temp |= level << SMFC_WM1_CLR_SHIFT;
  171515. + }
  171516. + break;
  171517. + case CSI_MEM2:
  171518. + if (set == true) {
  171519. + temp &= ~SMFC_WM2_SET_MASK;
  171520. + temp |= level << SMFC_WM2_SET_SHIFT;
  171521. + } else {
  171522. + temp &= ~SMFC_WM2_CLR_MASK;
  171523. + temp |= level << SMFC_WM2_CLR_SHIFT;
  171524. + }
  171525. + break;
  171526. + case CSI_MEM3:
  171527. + if (set == true) {
  171528. + temp &= ~SMFC_WM3_SET_MASK;
  171529. + temp |= level << SMFC_WM3_SET_SHIFT;
  171530. + } else {
  171531. + temp &= ~SMFC_WM3_CLR_MASK;
  171532. + temp |= level << SMFC_WM3_CLR_SHIFT;
  171533. + }
  171534. + break;
  171535. + default:
  171536. + return;
  171537. + }
  171538. +
  171539. + ipu_smfc_write(ipu, temp, SMFC_WMC);
  171540. +}
  171541. +
  171542. +/*!
  171543. + * _ipu_smfc_set_burst_size
  171544. + *
  171545. + * @param ipu ipu handler
  171546. + * @param channel IDMAC channel 0-3
  171547. + * @param bs burst size of IDMAC channel,
  171548. + * the value programmed here shoud be BURST_SIZE-1
  171549. + */
  171550. +void _ipu_smfc_set_burst_size(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t bs)
  171551. +{
  171552. + uint32_t temp;
  171553. +
  171554. + temp = ipu_smfc_read(ipu, SMFC_BS);
  171555. +
  171556. + switch (channel) {
  171557. + case CSI_MEM0:
  171558. + temp &= ~SMFC_BS0_MASK;
  171559. + temp |= bs << SMFC_BS0_SHIFT;
  171560. + break;
  171561. + case CSI_MEM1:
  171562. + temp &= ~SMFC_BS1_MASK;
  171563. + temp |= bs << SMFC_BS1_SHIFT;
  171564. + break;
  171565. + case CSI_MEM2:
  171566. + temp &= ~SMFC_BS2_MASK;
  171567. + temp |= bs << SMFC_BS2_SHIFT;
  171568. + break;
  171569. + case CSI_MEM3:
  171570. + temp &= ~SMFC_BS3_MASK;
  171571. + temp |= bs << SMFC_BS3_SHIFT;
  171572. + break;
  171573. + default:
  171574. + return;
  171575. + }
  171576. +
  171577. + ipu_smfc_write(ipu, temp, SMFC_BS);
  171578. +}
  171579. +
  171580. +/*!
  171581. + * _ipu_csi_init
  171582. + *
  171583. + * @param ipu ipu handler
  171584. + * @param channel IDMAC channel
  171585. + * @param csi csi 0 or csi 1
  171586. + *
  171587. + * @return Returns 0 on success or negative error code on fail
  171588. + */
  171589. +int _ipu_csi_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t csi)
  171590. +{
  171591. + uint32_t csi_sens_conf, csi_dest;
  171592. + int retval = 0;
  171593. +
  171594. + switch (channel) {
  171595. + case CSI_MEM0:
  171596. + case CSI_MEM1:
  171597. + case CSI_MEM2:
  171598. + case CSI_MEM3:
  171599. + csi_dest = CSI_DATA_DEST_IDMAC;
  171600. + break;
  171601. + case CSI_PRP_ENC_MEM:
  171602. + case CSI_PRP_VF_MEM:
  171603. + csi_dest = CSI_DATA_DEST_IC;
  171604. + break;
  171605. + default:
  171606. + retval = -EINVAL;
  171607. + goto err;
  171608. + }
  171609. +
  171610. + csi_sens_conf = ipu_csi_read(ipu, csi, CSI_SENS_CONF);
  171611. + csi_sens_conf &= ~CSI_SENS_CONF_DATA_DEST_MASK;
  171612. + ipu_csi_write(ipu, csi, csi_sens_conf | (csi_dest <<
  171613. + CSI_SENS_CONF_DATA_DEST_SHIFT), CSI_SENS_CONF);
  171614. +err:
  171615. + return retval;
  171616. +}
  171617. +
  171618. +/*!
  171619. + * csi_irq_handler
  171620. + *
  171621. + * @param irq interrupt id
  171622. + * @param dev_id pointer to ipu handler
  171623. + *
  171624. + * @return Returns if irq is handled
  171625. + */
  171626. +static irqreturn_t csi_irq_handler(int irq, void *dev_id)
  171627. +{
  171628. + struct ipu_soc *ipu = dev_id;
  171629. + struct completion *comp = &ipu->csi_comp;
  171630. +
  171631. + complete(comp);
  171632. + return IRQ_HANDLED;
  171633. +}
  171634. +
  171635. +/*!
  171636. + * _ipu_csi_wait4eof
  171637. + *
  171638. + * @param ipu ipu handler
  171639. + * @param channel IDMAC channel
  171640. + *
  171641. + */
  171642. +void _ipu_csi_wait4eof(struct ipu_soc *ipu, ipu_channel_t channel)
  171643. +{
  171644. + int ret;
  171645. + int irq = 0;
  171646. +
  171647. + if (channel == CSI_MEM0)
  171648. + irq = IPU_IRQ_CSI0_OUT_EOF;
  171649. + else if (channel == CSI_MEM1)
  171650. + irq = IPU_IRQ_CSI1_OUT_EOF;
  171651. + else if (channel == CSI_MEM2)
  171652. + irq = IPU_IRQ_CSI2_OUT_EOF;
  171653. + else if (channel == CSI_MEM3)
  171654. + irq = IPU_IRQ_CSI3_OUT_EOF;
  171655. + else if (channel == CSI_PRP_ENC_MEM)
  171656. + irq = IPU_IRQ_PRP_ENC_OUT_EOF;
  171657. + else if (channel == CSI_PRP_VF_MEM)
  171658. + irq = IPU_IRQ_PRP_VF_OUT_EOF;
  171659. + else{
  171660. + dev_err(ipu->dev, "Not a CSI channel\n");
  171661. + return;
  171662. + }
  171663. +
  171664. + init_completion(&ipu->csi_comp);
  171665. + ret = ipu_request_irq(ipu, irq, csi_irq_handler, 0, NULL, ipu);
  171666. + if (ret < 0) {
  171667. + dev_err(ipu->dev, "CSI irq %d in use\n", irq);
  171668. + return;
  171669. + }
  171670. + ret = wait_for_completion_timeout(&ipu->csi_comp, msecs_to_jiffies(500));
  171671. + ipu_free_irq(ipu, irq, ipu);
  171672. + dev_dbg(ipu->dev, "CSI stop timeout - %d * 10ms\n", 5 - ret);
  171673. +}
  171674. diff -Nur linux-3.14.14/drivers/mxc/ipu3/ipu_common.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_common.c
  171675. --- linux-3.14.14/drivers/mxc/ipu3/ipu_common.c 1969-12-31 18:00:00.000000000 -0600
  171676. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_common.c 2014-12-08 00:31:53.472418001 -0600
  171677. @@ -0,0 +1,3134 @@
  171678. +/*
  171679. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  171680. + */
  171681. +
  171682. +/*
  171683. + * The code contained herein is licensed under the GNU General Public
  171684. + * License. You may obtain a copy of the GNU General Public License
  171685. + * Version 2 or later at the following locations:
  171686. + *
  171687. + * http://www.opensource.org/licenses/gpl-license.html
  171688. + * http://www.gnu.org/copyleft/gpl.html
  171689. + */
  171690. +
  171691. +/*!
  171692. + * @file ipu_common.c
  171693. + *
  171694. + * @brief This file contains the IPU driver common API functions.
  171695. + *
  171696. + * @ingroup IPU
  171697. + */
  171698. +#include <linux/busfreq-imx6.h>
  171699. +#include <linux/clk.h>
  171700. +#include <linux/clk-provider.h>
  171701. +#include <linux/delay.h>
  171702. +#include <linux/err.h>
  171703. +#include <linux/init.h>
  171704. +#include <linux/interrupt.h>
  171705. +#include <linux/io.h>
  171706. +#include <linux/ipu-v3.h>
  171707. +#include <linux/irq.h>
  171708. +#include <linux/irqdesc.h>
  171709. +#include <linux/module.h>
  171710. +#include <linux/mod_devicetable.h>
  171711. +#include <linux/of_device.h>
  171712. +#include <linux/platform_device.h>
  171713. +#include <linux/pm_runtime.h>
  171714. +#include <linux/reset.h>
  171715. +#include <linux/spinlock.h>
  171716. +#include <linux/types.h>
  171717. +
  171718. +#include <asm/cacheflush.h>
  171719. +
  171720. +#include "ipu_param_mem.h"
  171721. +#include "ipu_regs.h"
  171722. +
  171723. +static struct ipu_soc ipu_array[MXC_IPU_MAX_NUM];
  171724. +int g_ipu_hw_rev;
  171725. +
  171726. +/* Static functions */
  171727. +static irqreturn_t ipu_sync_irq_handler(int irq, void *desc);
  171728. +static irqreturn_t ipu_err_irq_handler(int irq, void *desc);
  171729. +
  171730. +static inline uint32_t channel_2_dma(ipu_channel_t ch, ipu_buffer_t type)
  171731. +{
  171732. + return ((uint32_t) ch >> (6 * type)) & 0x3F;
  171733. +};
  171734. +
  171735. +static inline int _ipu_is_ic_chan(uint32_t dma_chan)
  171736. +{
  171737. + return (((dma_chan >= 11) && (dma_chan <= 22) && (dma_chan != 17) &&
  171738. + (dma_chan != 18)));
  171739. +}
  171740. +
  171741. +static inline int _ipu_is_vdi_out_chan(uint32_t dma_chan)
  171742. +{
  171743. + return (dma_chan == 5);
  171744. +}
  171745. +
  171746. +static inline int _ipu_is_ic_graphic_chan(uint32_t dma_chan)
  171747. +{
  171748. + return (dma_chan == 14 || dma_chan == 15);
  171749. +}
  171750. +
  171751. +/* Either DP BG or DP FG can be graphic window */
  171752. +static inline int _ipu_is_dp_graphic_chan(uint32_t dma_chan)
  171753. +{
  171754. + return (dma_chan == 23 || dma_chan == 27);
  171755. +}
  171756. +
  171757. +static inline int _ipu_is_irt_chan(uint32_t dma_chan)
  171758. +{
  171759. + return ((dma_chan >= 45) && (dma_chan <= 50));
  171760. +}
  171761. +
  171762. +static inline int _ipu_is_dmfc_chan(uint32_t dma_chan)
  171763. +{
  171764. + return ((dma_chan >= 23) && (dma_chan <= 29));
  171765. +}
  171766. +
  171767. +static inline int _ipu_is_smfc_chan(uint32_t dma_chan)
  171768. +{
  171769. + return ((dma_chan >= 0) && (dma_chan <= 3));
  171770. +}
  171771. +
  171772. +static inline int _ipu_is_trb_chan(uint32_t dma_chan)
  171773. +{
  171774. + return (((dma_chan == 8) || (dma_chan == 9) ||
  171775. + (dma_chan == 10) || (dma_chan == 13) ||
  171776. + (dma_chan == 21) || (dma_chan == 23) ||
  171777. + (dma_chan == 27) || (dma_chan == 28)) &&
  171778. + (g_ipu_hw_rev >= IPU_V3DEX));
  171779. +}
  171780. +
  171781. +/*
  171782. + * We usually use IDMAC 23 as full plane and IDMAC 27 as partial
  171783. + * plane.
  171784. + * IDMAC 23/24/28/41 can drive a display respectively - primary
  171785. + * IDMAC 27 depends on IDMAC 23 - nonprimary
  171786. + */
  171787. +static inline int _ipu_is_primary_disp_chan(uint32_t dma_chan)
  171788. +{
  171789. + return ((dma_chan == 23) || (dma_chan == 24) ||
  171790. + (dma_chan == 28) || (dma_chan == 41));
  171791. +}
  171792. +
  171793. +static inline int _ipu_is_sync_irq(uint32_t irq)
  171794. +{
  171795. + /* sync interrupt register number */
  171796. + int reg_num = irq / 32 + 1;
  171797. +
  171798. + return ((reg_num == 1) || (reg_num == 2) || (reg_num == 3) ||
  171799. + (reg_num == 4) || (reg_num == 7) || (reg_num == 8) ||
  171800. + (reg_num == 11) || (reg_num == 12) || (reg_num == 13) ||
  171801. + (reg_num == 14) || (reg_num == 15));
  171802. +}
  171803. +
  171804. +#define idma_is_valid(ch) (ch != NO_DMA)
  171805. +#define idma_mask(ch) (idma_is_valid(ch) ? (1UL << (ch & 0x1F)) : 0)
  171806. +#define idma_is_set(ipu, reg, dma) (ipu_idmac_read(ipu, reg(dma)) & idma_mask(dma))
  171807. +#define tri_cur_buf_mask(ch) (idma_mask(ch*2) * 3)
  171808. +#define tri_cur_buf_shift(ch) (ffs(idma_mask(ch*2)) - 1)
  171809. +
  171810. +static int ipu_clk_setup_enable(struct ipu_soc *ipu,
  171811. + struct ipu_pltfm_data *pdata)
  171812. +{
  171813. + char pixel_clk_0[] = "ipu1_pclk_0";
  171814. + char pixel_clk_1[] = "ipu1_pclk_1";
  171815. + char pixel_clk_0_sel[] = "ipu1_pclk0_sel";
  171816. + char pixel_clk_1_sel[] = "ipu1_pclk1_sel";
  171817. + char pixel_clk_0_div[] = "ipu1_pclk0_div";
  171818. + char pixel_clk_1_div[] = "ipu1_pclk1_div";
  171819. + char *ipu_pixel_clk_sel[] = { "ipu1", "ipu1_di0", "ipu1_di1", };
  171820. + char *pclk_sel;
  171821. + struct clk *clk;
  171822. + int ret;
  171823. + int i;
  171824. +
  171825. + pixel_clk_0[3] += pdata->id;
  171826. + pixel_clk_1[3] += pdata->id;
  171827. + pixel_clk_0_sel[3] += pdata->id;
  171828. + pixel_clk_1_sel[3] += pdata->id;
  171829. + pixel_clk_0_div[3] += pdata->id;
  171830. + pixel_clk_1_div[3] += pdata->id;
  171831. + for (i = 0; i < ARRAY_SIZE(ipu_pixel_clk_sel); i++) {
  171832. + pclk_sel = ipu_pixel_clk_sel[i];
  171833. + pclk_sel[3] += pdata->id;
  171834. + }
  171835. + dev_dbg(ipu->dev, "ipu_clk = %lu\n", clk_get_rate(ipu->ipu_clk));
  171836. +
  171837. + clk = clk_register_mux_pix_clk(ipu->dev, pixel_clk_0_sel,
  171838. + (const char **)ipu_pixel_clk_sel,
  171839. + ARRAY_SIZE(ipu_pixel_clk_sel),
  171840. + 0, pdata->id, 0, 0);
  171841. + if (IS_ERR(clk)) {
  171842. + dev_err(ipu->dev, "clk_register mux di0 failed");
  171843. + return PTR_ERR(clk);
  171844. + }
  171845. + ipu->pixel_clk_sel[0] = clk;
  171846. + clk = clk_register_mux_pix_clk(ipu->dev, pixel_clk_1_sel,
  171847. + (const char **)ipu_pixel_clk_sel,
  171848. + ARRAY_SIZE(ipu_pixel_clk_sel),
  171849. + 0, pdata->id, 1, 0);
  171850. + if (IS_ERR(clk)) {
  171851. + dev_err(ipu->dev, "clk_register mux di1 failed");
  171852. + return PTR_ERR(clk);
  171853. + }
  171854. + ipu->pixel_clk_sel[1] = clk;
  171855. +
  171856. + clk = clk_register_div_pix_clk(ipu->dev, pixel_clk_0_div,
  171857. + pixel_clk_0_sel, 0, pdata->id, 0, 0);
  171858. + if (IS_ERR(clk)) {
  171859. + dev_err(ipu->dev, "clk register di0 div failed");
  171860. + return PTR_ERR(clk);
  171861. + }
  171862. + clk = clk_register_div_pix_clk(ipu->dev, pixel_clk_1_div,
  171863. + pixel_clk_1_sel, CLK_SET_RATE_PARENT, pdata->id, 1, 0);
  171864. + if (IS_ERR(clk)) {
  171865. + dev_err(ipu->dev, "clk register di1 div failed");
  171866. + return PTR_ERR(clk);
  171867. + }
  171868. +
  171869. + ipu->pixel_clk[0] = clk_register_gate_pix_clk(ipu->dev, pixel_clk_0,
  171870. + pixel_clk_0_div, CLK_SET_RATE_PARENT,
  171871. + pdata->id, 0, 0);
  171872. + if (IS_ERR(ipu->pixel_clk[0])) {
  171873. + dev_err(ipu->dev, "clk register di0 gate failed");
  171874. + return PTR_ERR(ipu->pixel_clk[0]);
  171875. + }
  171876. + ipu->pixel_clk[1] = clk_register_gate_pix_clk(ipu->dev, pixel_clk_1,
  171877. + pixel_clk_1_div, CLK_SET_RATE_PARENT,
  171878. + pdata->id, 1, 0);
  171879. + if (IS_ERR(ipu->pixel_clk[1])) {
  171880. + dev_err(ipu->dev, "clk register di1 gate failed");
  171881. + return PTR_ERR(ipu->pixel_clk[1]);
  171882. + }
  171883. +
  171884. + ret = clk_set_parent(ipu->pixel_clk_sel[0], ipu->ipu_clk);
  171885. + if (ret) {
  171886. + dev_err(ipu->dev, "clk set parent failed");
  171887. + return ret;
  171888. + }
  171889. +
  171890. + ret = clk_set_parent(ipu->pixel_clk_sel[1], ipu->ipu_clk);
  171891. + if (ret) {
  171892. + dev_err(ipu->dev, "clk set parent failed");
  171893. + return ret;
  171894. + }
  171895. +
  171896. + ipu->di_clk[0] = devm_clk_get(ipu->dev, "di0");
  171897. + if (IS_ERR(ipu->di_clk[0])) {
  171898. + dev_err(ipu->dev, "clk_get di0 failed");
  171899. + return PTR_ERR(ipu->di_clk[0]);
  171900. + }
  171901. + ipu->di_clk[1] = devm_clk_get(ipu->dev, "di1");
  171902. + if (IS_ERR(ipu->di_clk[1])) {
  171903. + dev_err(ipu->dev, "clk_get di1 failed");
  171904. + return PTR_ERR(ipu->di_clk[1]);
  171905. + }
  171906. +
  171907. + ipu->di_clk_sel[0] = devm_clk_get(ipu->dev, "di0_sel");
  171908. + if (IS_ERR(ipu->di_clk_sel[0])) {
  171909. + dev_err(ipu->dev, "clk_get di0_sel failed");
  171910. + return PTR_ERR(ipu->di_clk_sel[0]);
  171911. + }
  171912. + ipu->di_clk_sel[1] = devm_clk_get(ipu->dev, "di1_sel");
  171913. + if (IS_ERR(ipu->di_clk_sel[1])) {
  171914. + dev_err(ipu->dev, "clk_get di1_sel failed");
  171915. + return PTR_ERR(ipu->di_clk_sel[1]);
  171916. + }
  171917. +
  171918. + return 0;
  171919. +}
  171920. +
  171921. +static int ipu_mem_reset(struct ipu_soc *ipu)
  171922. +{
  171923. + int timeout = 1000;
  171924. +
  171925. + ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST);
  171926. +
  171927. + while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) {
  171928. + if (!timeout--)
  171929. + return -ETIME;
  171930. + msleep(1);
  171931. + }
  171932. +
  171933. + return 0;
  171934. +}
  171935. +
  171936. +struct ipu_soc *ipu_get_soc(int id)
  171937. +{
  171938. + if (id >= MXC_IPU_MAX_NUM)
  171939. + return ERR_PTR(-ENODEV);
  171940. + else if (!ipu_array[id].online)
  171941. + return ERR_PTR(-ENODEV);
  171942. + else
  171943. + return &(ipu_array[id]);
  171944. +}
  171945. +EXPORT_SYMBOL_GPL(ipu_get_soc);
  171946. +
  171947. +void _ipu_get(struct ipu_soc *ipu)
  171948. +{
  171949. + int ret;
  171950. +
  171951. + ret = clk_enable(ipu->ipu_clk);
  171952. + if (ret < 0)
  171953. + BUG();
  171954. +}
  171955. +
  171956. +void _ipu_put(struct ipu_soc *ipu)
  171957. +{
  171958. + clk_disable(ipu->ipu_clk);
  171959. +}
  171960. +
  171961. +void ipu_disable_hsp_clk(struct ipu_soc *ipu)
  171962. +{
  171963. + _ipu_put(ipu);
  171964. +}
  171965. +EXPORT_SYMBOL(ipu_disable_hsp_clk);
  171966. +
  171967. +static struct platform_device_id imx_ipu_type[] = {
  171968. + {
  171969. + .name = "ipu-imx6q",
  171970. + .driver_data = IPU_V3H,
  171971. + }, {
  171972. + /* sentinel */
  171973. + }
  171974. +};
  171975. +MODULE_DEVICE_TABLE(platform, imx_ipu_type);
  171976. +
  171977. +static const struct of_device_id imx_ipuv3_dt_ids[] = {
  171978. + { .compatible = "fsl,imx6q-ipu", .data = &imx_ipu_type[IMX6Q_IPU], },
  171979. + { /* sentinel */ }
  171980. +};
  171981. +MODULE_DEVICE_TABLE(of, imx_ipuv3_dt_ids);
  171982. +
  171983. +/*!
  171984. + * This function is called by the driver framework to initialize the IPU
  171985. + * hardware.
  171986. + *
  171987. + * @param dev The device structure for the IPU passed in by the
  171988. + * driver framework.
  171989. + *
  171990. + * @return Returns 0 on success or negative error code on error
  171991. + */
  171992. +static int ipu_probe(struct platform_device *pdev)
  171993. +{
  171994. + struct ipu_soc *ipu;
  171995. + struct resource *res;
  171996. + unsigned long ipu_base;
  171997. + const struct of_device_id *of_id =
  171998. + of_match_device(imx_ipuv3_dt_ids, &pdev->dev);
  171999. + struct ipu_pltfm_data *pltfm_data;
  172000. + int ret = 0;
  172001. + u32 bypass_reset;
  172002. +
  172003. + dev_dbg(&pdev->dev, "<%s>\n", __func__);
  172004. +
  172005. + pltfm_data = devm_kzalloc(&pdev->dev, sizeof(struct ipu_pltfm_data),
  172006. + GFP_KERNEL);
  172007. + if (!pltfm_data)
  172008. + return -ENOMEM;
  172009. +
  172010. + ret = of_property_read_u32(pdev->dev.of_node,
  172011. + "bypass_reset", &bypass_reset);
  172012. + if (ret < 0) {
  172013. + dev_dbg(&pdev->dev, "can not get bypass_reset\n");
  172014. + return ret;
  172015. + }
  172016. + pltfm_data->bypass_reset = (bool)bypass_reset;
  172017. +
  172018. + pltfm_data->id = of_alias_get_id(pdev->dev.of_node, "ipu");
  172019. + if (pltfm_data->id < 0) {
  172020. + dev_dbg(&pdev->dev, "can not get alias id\n");
  172021. + return pltfm_data->id;
  172022. + }
  172023. +
  172024. + if (of_id)
  172025. + pdev->id_entry = of_id->data;
  172026. + pltfm_data->devtype = pdev->id_entry->driver_data;
  172027. + g_ipu_hw_rev = pltfm_data->devtype;
  172028. +
  172029. + ipu = &ipu_array[pltfm_data->id];
  172030. + memset(ipu, 0, sizeof(struct ipu_soc));
  172031. + ipu->dev = &pdev->dev;
  172032. + ipu->pdata = pltfm_data;
  172033. + dev_dbg(ipu->dev, "IPU rev:%d\n", g_ipu_hw_rev);
  172034. + spin_lock_init(&ipu->int_reg_spin_lock);
  172035. + spin_lock_init(&ipu->rdy_reg_spin_lock);
  172036. + mutex_init(&ipu->mutex_lock);
  172037. +
  172038. + ipu->irq_sync = platform_get_irq(pdev, 0);
  172039. + ipu->irq_err = platform_get_irq(pdev, 1);
  172040. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  172041. +
  172042. + if (!res || ipu->irq_sync < 0 || ipu->irq_err < 0) {
  172043. + dev_err(&pdev->dev, "can't get device resources\n");
  172044. + return -ENODEV;
  172045. + }
  172046. +
  172047. + if (!devm_request_mem_region(&pdev->dev, res->start,
  172048. + resource_size(res), pdev->name))
  172049. + return -EBUSY;
  172050. +
  172051. + ret = devm_request_irq(&pdev->dev, ipu->irq_sync,
  172052. + ipu_sync_irq_handler, 0, pdev->name, ipu);
  172053. + if (ret) {
  172054. + dev_err(ipu->dev, "request SYNC interrupt failed\n");
  172055. + return ret;
  172056. + }
  172057. + ret = devm_request_irq(&pdev->dev, ipu->irq_err,
  172058. + ipu_err_irq_handler, 0, pdev->name, ipu);
  172059. + if (ret) {
  172060. + dev_err(ipu->dev, "request ERR interrupt failed\n");
  172061. + return ret;
  172062. + }
  172063. +
  172064. + ipu_base = res->start;
  172065. + /* base fixup */
  172066. + if (g_ipu_hw_rev == IPU_V3H) /* IPUv3H */
  172067. + ipu_base += IPUV3H_REG_BASE;
  172068. + else if (g_ipu_hw_rev == IPU_V3M) /* IPUv3M */
  172069. + ipu_base += IPUV3M_REG_BASE;
  172070. + else /* IPUv3D, v3E, v3EX */
  172071. + ipu_base += IPUV3DEX_REG_BASE;
  172072. +
  172073. + ipu->cm_reg = devm_ioremap(&pdev->dev,
  172074. + ipu_base + IPU_CM_REG_BASE, PAGE_SIZE);
  172075. + ipu->ic_reg = devm_ioremap(&pdev->dev,
  172076. + ipu_base + IPU_IC_REG_BASE, PAGE_SIZE);
  172077. + ipu->idmac_reg = devm_ioremap(&pdev->dev,
  172078. + ipu_base + IPU_IDMAC_REG_BASE, PAGE_SIZE);
  172079. + /* DP Registers are accessed thru the SRM */
  172080. + ipu->dp_reg = devm_ioremap(&pdev->dev,
  172081. + ipu_base + IPU_SRM_REG_BASE, PAGE_SIZE);
  172082. + ipu->dc_reg = devm_ioremap(&pdev->dev,
  172083. + ipu_base + IPU_DC_REG_BASE, PAGE_SIZE);
  172084. + ipu->dmfc_reg = devm_ioremap(&pdev->dev,
  172085. + ipu_base + IPU_DMFC_REG_BASE, PAGE_SIZE);
  172086. + ipu->di_reg[0] = devm_ioremap(&pdev->dev,
  172087. + ipu_base + IPU_DI0_REG_BASE, PAGE_SIZE);
  172088. + ipu->di_reg[1] = devm_ioremap(&pdev->dev,
  172089. + ipu_base + IPU_DI1_REG_BASE, PAGE_SIZE);
  172090. + ipu->smfc_reg = devm_ioremap(&pdev->dev,
  172091. + ipu_base + IPU_SMFC_REG_BASE, PAGE_SIZE);
  172092. + ipu->csi_reg[0] = devm_ioremap(&pdev->dev,
  172093. + ipu_base + IPU_CSI0_REG_BASE, PAGE_SIZE);
  172094. + ipu->csi_reg[1] = devm_ioremap(&pdev->dev,
  172095. + ipu_base + IPU_CSI1_REG_BASE, PAGE_SIZE);
  172096. + ipu->cpmem_base = devm_ioremap(&pdev->dev,
  172097. + ipu_base + IPU_CPMEM_REG_BASE, SZ_128K);
  172098. + ipu->tpmem_base = devm_ioremap(&pdev->dev,
  172099. + ipu_base + IPU_TPM_REG_BASE, SZ_64K);
  172100. + ipu->dc_tmpl_reg = devm_ioremap(&pdev->dev,
  172101. + ipu_base + IPU_DC_TMPL_REG_BASE, SZ_128K);
  172102. + ipu->vdi_reg = devm_ioremap(&pdev->dev,
  172103. + ipu_base + IPU_VDI_REG_BASE, PAGE_SIZE);
  172104. + ipu->disp_base[1] = devm_ioremap(&pdev->dev,
  172105. + ipu_base + IPU_DISP1_BASE, SZ_4K);
  172106. + if (!ipu->cm_reg || !ipu->ic_reg || !ipu->idmac_reg ||
  172107. + !ipu->dp_reg || !ipu->dc_reg || !ipu->dmfc_reg ||
  172108. + !ipu->di_reg[0] || !ipu->di_reg[1] || !ipu->smfc_reg ||
  172109. + !ipu->csi_reg[0] || !ipu->csi_reg[1] || !ipu->cpmem_base ||
  172110. + !ipu->tpmem_base || !ipu->dc_tmpl_reg || !ipu->disp_base[1]
  172111. + || !ipu->vdi_reg)
  172112. + return -ENOMEM;
  172113. +
  172114. + dev_dbg(ipu->dev, "IPU CM Regs = %p\n", ipu->cm_reg);
  172115. + dev_dbg(ipu->dev, "IPU IC Regs = %p\n", ipu->ic_reg);
  172116. + dev_dbg(ipu->dev, "IPU IDMAC Regs = %p\n", ipu->idmac_reg);
  172117. + dev_dbg(ipu->dev, "IPU DP Regs = %p\n", ipu->dp_reg);
  172118. + dev_dbg(ipu->dev, "IPU DC Regs = %p\n", ipu->dc_reg);
  172119. + dev_dbg(ipu->dev, "IPU DMFC Regs = %p\n", ipu->dmfc_reg);
  172120. + dev_dbg(ipu->dev, "IPU DI0 Regs = %p\n", ipu->di_reg[0]);
  172121. + dev_dbg(ipu->dev, "IPU DI1 Regs = %p\n", ipu->di_reg[1]);
  172122. + dev_dbg(ipu->dev, "IPU SMFC Regs = %p\n", ipu->smfc_reg);
  172123. + dev_dbg(ipu->dev, "IPU CSI0 Regs = %p\n", ipu->csi_reg[0]);
  172124. + dev_dbg(ipu->dev, "IPU CSI1 Regs = %p\n", ipu->csi_reg[1]);
  172125. + dev_dbg(ipu->dev, "IPU CPMem = %p\n", ipu->cpmem_base);
  172126. + dev_dbg(ipu->dev, "IPU TPMem = %p\n", ipu->tpmem_base);
  172127. + dev_dbg(ipu->dev, "IPU DC Template Mem = %p\n", ipu->dc_tmpl_reg);
  172128. + dev_dbg(ipu->dev, "IPU Display Region 1 Mem = %p\n", ipu->disp_base[1]);
  172129. + dev_dbg(ipu->dev, "IPU VDI Regs = %p\n", ipu->vdi_reg);
  172130. +
  172131. + ipu->ipu_clk = devm_clk_get(ipu->dev, "bus");
  172132. + if (IS_ERR(ipu->ipu_clk)) {
  172133. + dev_err(ipu->dev, "clk_get ipu failed");
  172134. + return PTR_ERR(ipu->ipu_clk);
  172135. + }
  172136. +
  172137. + /* ipu_clk is always prepared */
  172138. + ret = clk_prepare_enable(ipu->ipu_clk);
  172139. + if (ret < 0) {
  172140. + dev_err(ipu->dev, "ipu clk enable failed\n");
  172141. + return ret;
  172142. + }
  172143. +
  172144. + ipu->online = true;
  172145. +
  172146. + platform_set_drvdata(pdev, ipu);
  172147. +
  172148. + if (!pltfm_data->bypass_reset) {
  172149. + ret = device_reset(&pdev->dev);
  172150. + if (ret) {
  172151. + dev_err(&pdev->dev, "failed to reset: %d\n", ret);
  172152. + return ret;
  172153. + }
  172154. +
  172155. + ipu_mem_reset(ipu);
  172156. +
  172157. + ipu_disp_init(ipu);
  172158. +
  172159. + /* Set MCU_T to divide MCU access window into 2 */
  172160. + ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18),
  172161. + IPU_DISP_GEN);
  172162. + }
  172163. +
  172164. + /* setup ipu clk tree after ipu reset */
  172165. + ret = ipu_clk_setup_enable(ipu, pltfm_data);
  172166. + if (ret < 0) {
  172167. + dev_err(ipu->dev, "ipu clk setup failed\n");
  172168. + ipu->online = false;
  172169. + return ret;
  172170. + }
  172171. +
  172172. + /* Set sync refresh channels and CSI->mem channel as high priority */
  172173. + ipu_idmac_write(ipu, 0x18800001L, IDMAC_CHA_PRI(0));
  172174. +
  172175. + /* Enable error interrupts by default */
  172176. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(5));
  172177. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(6));
  172178. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(9));
  172179. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(10));
  172180. +
  172181. + if (!pltfm_data->bypass_reset)
  172182. + clk_disable(ipu->ipu_clk);
  172183. +
  172184. + register_ipu_device(ipu, ipu->pdata->id);
  172185. +
  172186. + pm_runtime_enable(&pdev->dev);
  172187. +
  172188. + return ret;
  172189. +}
  172190. +
  172191. +int ipu_remove(struct platform_device *pdev)
  172192. +{
  172193. + struct ipu_soc *ipu = platform_get_drvdata(pdev);
  172194. +
  172195. + unregister_ipu_device(ipu, ipu->pdata->id);
  172196. +
  172197. + clk_put(ipu->ipu_clk);
  172198. +
  172199. + return 0;
  172200. +}
  172201. +
  172202. +void ipu_dump_registers(struct ipu_soc *ipu)
  172203. +{
  172204. + dev_dbg(ipu->dev, "IPU_CONF = \t0x%08X\n", ipu_cm_read(ipu, IPU_CONF));
  172205. + dev_dbg(ipu->dev, "IDMAC_CONF = \t0x%08X\n", ipu_idmac_read(ipu, IDMAC_CONF));
  172206. + dev_dbg(ipu->dev, "IDMAC_CHA_EN1 = \t0x%08X\n",
  172207. + ipu_idmac_read(ipu, IDMAC_CHA_EN(0)));
  172208. + dev_dbg(ipu->dev, "IDMAC_CHA_EN2 = \t0x%08X\n",
  172209. + ipu_idmac_read(ipu, IDMAC_CHA_EN(32)));
  172210. + dev_dbg(ipu->dev, "IDMAC_CHA_PRI1 = \t0x%08X\n",
  172211. + ipu_idmac_read(ipu, IDMAC_CHA_PRI(0)));
  172212. + dev_dbg(ipu->dev, "IDMAC_CHA_PRI2 = \t0x%08X\n",
  172213. + ipu_idmac_read(ipu, IDMAC_CHA_PRI(32)));
  172214. + dev_dbg(ipu->dev, "IDMAC_BAND_EN1 = \t0x%08X\n",
  172215. + ipu_idmac_read(ipu, IDMAC_BAND_EN(0)));
  172216. + dev_dbg(ipu->dev, "IDMAC_BAND_EN2 = \t0x%08X\n",
  172217. + ipu_idmac_read(ipu, IDMAC_BAND_EN(32)));
  172218. + dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n",
  172219. + ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(0)));
  172220. + dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n",
  172221. + ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(32)));
  172222. + if (g_ipu_hw_rev >= IPU_V3DEX) {
  172223. + dev_dbg(ipu->dev, "IPU_CHA_TRB_MODE_SEL0 = \t0x%08X\n",
  172224. + ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(0)));
  172225. + dev_dbg(ipu->dev, "IPU_CHA_TRB_MODE_SEL1 = \t0x%08X\n",
  172226. + ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(32)));
  172227. + }
  172228. + dev_dbg(ipu->dev, "DMFC_WR_CHAN = \t0x%08X\n",
  172229. + ipu_dmfc_read(ipu, DMFC_WR_CHAN));
  172230. + dev_dbg(ipu->dev, "DMFC_WR_CHAN_DEF = \t0x%08X\n",
  172231. + ipu_dmfc_read(ipu, DMFC_WR_CHAN_DEF));
  172232. + dev_dbg(ipu->dev, "DMFC_DP_CHAN = \t0x%08X\n",
  172233. + ipu_dmfc_read(ipu, DMFC_DP_CHAN));
  172234. + dev_dbg(ipu->dev, "DMFC_DP_CHAN_DEF = \t0x%08X\n",
  172235. + ipu_dmfc_read(ipu, DMFC_DP_CHAN_DEF));
  172236. + dev_dbg(ipu->dev, "DMFC_IC_CTRL = \t0x%08X\n",
  172237. + ipu_dmfc_read(ipu, DMFC_IC_CTRL));
  172238. + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW1 = \t0x%08X\n",
  172239. + ipu_cm_read(ipu, IPU_FS_PROC_FLOW1));
  172240. + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW2 = \t0x%08X\n",
  172241. + ipu_cm_read(ipu, IPU_FS_PROC_FLOW2));
  172242. + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW3 = \t0x%08X\n",
  172243. + ipu_cm_read(ipu, IPU_FS_PROC_FLOW3));
  172244. + dev_dbg(ipu->dev, "IPU_FS_DISP_FLOW1 = \t0x%08X\n",
  172245. + ipu_cm_read(ipu, IPU_FS_DISP_FLOW1));
  172246. + dev_dbg(ipu->dev, "IPU_VDIC_VDI_FSIZE = \t0x%08X\n",
  172247. + ipu_vdi_read(ipu, VDI_FSIZE));
  172248. + dev_dbg(ipu->dev, "IPU_VDIC_VDI_C = \t0x%08X\n",
  172249. + ipu_vdi_read(ipu, VDI_C));
  172250. + dev_dbg(ipu->dev, "IPU_IC_CONF = \t0x%08X\n",
  172251. + ipu_ic_read(ipu, IC_CONF));
  172252. +}
  172253. +
  172254. +/*!
  172255. + * This function is called to initialize a logical IPU channel.
  172256. + *
  172257. + * @param ipu ipu handler
  172258. + * @param channel Input parameter for the logical channel ID to init.
  172259. + *
  172260. + * @param params Input parameter containing union of channel
  172261. + * initialization parameters.
  172262. + *
  172263. + * @return Returns 0 on success or negative error code on fail
  172264. + */
  172265. +int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params)
  172266. +{
  172267. + int ret = 0;
  172268. + bool bad_pixfmt;
  172269. + uint32_t ipu_conf, reg, in_g_pixel_fmt, sec_dma;
  172270. +
  172271. + dev_dbg(ipu->dev, "init channel = %d\n", IPU_CHAN_ID(channel));
  172272. +
  172273. + ret = pm_runtime_get_sync(ipu->dev);
  172274. + if (ret < 0) {
  172275. + dev_err(ipu->dev, "ch = %d, pm_runtime_get failed:%d!\n",
  172276. + IPU_CHAN_ID(channel), ret);
  172277. + dump_stack();
  172278. + return ret;
  172279. + }
  172280. + /*
  172281. + * Here, ret could be 1 if the device's runtime PM status was
  172282. + * already 'active', so clear it to be 0.
  172283. + */
  172284. + ret = 0;
  172285. +
  172286. + _ipu_get(ipu);
  172287. +
  172288. + mutex_lock(&ipu->mutex_lock);
  172289. +
  172290. + /* Re-enable error interrupts every time a channel is initialized */
  172291. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(5));
  172292. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(6));
  172293. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(9));
  172294. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(10));
  172295. +
  172296. + if (ipu->channel_init_mask & (1L << IPU_CHAN_ID(channel))) {
  172297. + dev_warn(ipu->dev, "Warning: channel already initialized %d\n",
  172298. + IPU_CHAN_ID(channel));
  172299. + }
  172300. +
  172301. + ipu_conf = ipu_cm_read(ipu, IPU_CONF);
  172302. +
  172303. + switch (channel) {
  172304. + case CSI_MEM0:
  172305. + case CSI_MEM1:
  172306. + case CSI_MEM2:
  172307. + case CSI_MEM3:
  172308. + if (params->csi_mem.csi > 1) {
  172309. + ret = -EINVAL;
  172310. + goto err;
  172311. + }
  172312. +
  172313. + if (params->csi_mem.interlaced)
  172314. + ipu->chan_is_interlaced[channel_2_dma(channel,
  172315. + IPU_OUTPUT_BUFFER)] = true;
  172316. + else
  172317. + ipu->chan_is_interlaced[channel_2_dma(channel,
  172318. + IPU_OUTPUT_BUFFER)] = false;
  172319. +
  172320. + ipu->smfc_use_count++;
  172321. + ipu->csi_channel[params->csi_mem.csi] = channel;
  172322. +
  172323. + /*SMFC setting*/
  172324. + if (params->csi_mem.mipi_en) {
  172325. + ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172326. + params->csi_mem.csi));
  172327. + _ipu_smfc_init(ipu, channel, params->csi_mem.mipi_vc,
  172328. + params->csi_mem.csi);
  172329. + _ipu_csi_set_mipi_di(ipu, params->csi_mem.mipi_vc,
  172330. + params->csi_mem.mipi_id, params->csi_mem.csi);
  172331. + } else {
  172332. + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172333. + params->csi_mem.csi));
  172334. + _ipu_smfc_init(ipu, channel, 0, params->csi_mem.csi);
  172335. + }
  172336. +
  172337. + /*CSI data (include compander) dest*/
  172338. + _ipu_csi_init(ipu, channel, params->csi_mem.csi);
  172339. + break;
  172340. + case CSI_PRP_ENC_MEM:
  172341. + if (params->csi_prp_enc_mem.csi > 1) {
  172342. + ret = -EINVAL;
  172343. + goto err;
  172344. + }
  172345. + if ((ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
  172346. + (ipu->using_ic_dirct_ch == MEM_VDI_MEM)) {
  172347. + ret = -EINVAL;
  172348. + goto err;
  172349. + }
  172350. + ipu->using_ic_dirct_ch = CSI_PRP_ENC_MEM;
  172351. +
  172352. + ipu->ic_use_count++;
  172353. + ipu->csi_channel[params->csi_prp_enc_mem.csi] = channel;
  172354. +
  172355. + if (params->csi_prp_enc_mem.mipi_en) {
  172356. + ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172357. + params->csi_prp_enc_mem.csi));
  172358. + _ipu_csi_set_mipi_di(ipu,
  172359. + params->csi_prp_enc_mem.mipi_vc,
  172360. + params->csi_prp_enc_mem.mipi_id,
  172361. + params->csi_prp_enc_mem.csi);
  172362. + } else
  172363. + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172364. + params->csi_prp_enc_mem.csi));
  172365. +
  172366. + /*CSI0/1 feed into IC*/
  172367. + ipu_conf &= ~IPU_CONF_IC_INPUT;
  172368. + if (params->csi_prp_enc_mem.csi)
  172369. + ipu_conf |= IPU_CONF_CSI_SEL;
  172370. + else
  172371. + ipu_conf &= ~IPU_CONF_CSI_SEL;
  172372. +
  172373. + /*PRP skip buffer in memory, only valid when RWS_EN is true*/
  172374. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172375. + ipu_cm_write(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
  172376. +
  172377. + /*CSI data (include compander) dest*/
  172378. + _ipu_csi_init(ipu, channel, params->csi_prp_enc_mem.csi);
  172379. + _ipu_ic_init_prpenc(ipu, params, true);
  172380. + break;
  172381. + case CSI_PRP_VF_MEM:
  172382. + if (params->csi_prp_vf_mem.csi > 1) {
  172383. + ret = -EINVAL;
  172384. + goto err;
  172385. + }
  172386. + if ((ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
  172387. + (ipu->using_ic_dirct_ch == MEM_VDI_MEM)) {
  172388. + ret = -EINVAL;
  172389. + goto err;
  172390. + }
  172391. + ipu->using_ic_dirct_ch = CSI_PRP_VF_MEM;
  172392. +
  172393. + ipu->ic_use_count++;
  172394. + ipu->csi_channel[params->csi_prp_vf_mem.csi] = channel;
  172395. +
  172396. + if (params->csi_prp_vf_mem.mipi_en) {
  172397. + ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172398. + params->csi_prp_vf_mem.csi));
  172399. + _ipu_csi_set_mipi_di(ipu,
  172400. + params->csi_prp_vf_mem.mipi_vc,
  172401. + params->csi_prp_vf_mem.mipi_id,
  172402. + params->csi_prp_vf_mem.csi);
  172403. + } else
  172404. + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  172405. + params->csi_prp_vf_mem.csi));
  172406. +
  172407. + /*CSI0/1 feed into IC*/
  172408. + ipu_conf &= ~IPU_CONF_IC_INPUT;
  172409. + if (params->csi_prp_vf_mem.csi)
  172410. + ipu_conf |= IPU_CONF_CSI_SEL;
  172411. + else
  172412. + ipu_conf &= ~IPU_CONF_CSI_SEL;
  172413. +
  172414. + /*PRP skip buffer in memory, only valid when RWS_EN is true*/
  172415. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172416. + ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  172417. +
  172418. + /*CSI data (include compander) dest*/
  172419. + _ipu_csi_init(ipu, channel, params->csi_prp_vf_mem.csi);
  172420. + _ipu_ic_init_prpvf(ipu, params, true);
  172421. + break;
  172422. + case MEM_PRP_VF_MEM:
  172423. + if (params->mem_prp_vf_mem.graphics_combine_en) {
  172424. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  172425. + in_g_pixel_fmt = params->mem_prp_vf_mem.in_g_pixel_fmt;
  172426. + bad_pixfmt =
  172427. + _ipu_ch_param_bad_alpha_pos(in_g_pixel_fmt);
  172428. +
  172429. + if (params->mem_prp_vf_mem.alpha_chan_en) {
  172430. + if (bad_pixfmt) {
  172431. + dev_err(ipu->dev, "bad pixel format "
  172432. + "for graphics plane from "
  172433. + "ch%d\n", sec_dma);
  172434. + ret = -EINVAL;
  172435. + goto err;
  172436. + }
  172437. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  172438. + }
  172439. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
  172440. + }
  172441. +
  172442. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172443. + ipu_cm_write(ipu, reg | FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  172444. +
  172445. + _ipu_ic_init_prpvf(ipu, params, false);
  172446. + ipu->ic_use_count++;
  172447. + break;
  172448. + case MEM_VDI_PRP_VF_MEM:
  172449. + if ((ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM) ||
  172450. + (ipu->using_ic_dirct_ch == MEM_VDI_MEM) ||
  172451. + (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)) {
  172452. + ret = -EINVAL;
  172453. + goto err;
  172454. + }
  172455. + ipu->using_ic_dirct_ch = MEM_VDI_PRP_VF_MEM;
  172456. + ipu->ic_use_count++;
  172457. + ipu->vdi_use_count++;
  172458. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172459. + reg &= ~FS_VDI_SRC_SEL_MASK;
  172460. + ipu_cm_write(ipu, reg , IPU_FS_PROC_FLOW1);
  172461. +
  172462. + if (params->mem_prp_vf_mem.graphics_combine_en)
  172463. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
  172464. + _ipu_ic_init_prpvf(ipu, params, false);
  172465. + _ipu_vdi_init(ipu, channel, params);
  172466. + break;
  172467. + case MEM_VDI_PRP_VF_MEM_P:
  172468. + case MEM_VDI_PRP_VF_MEM_N:
  172469. + case MEM_VDI_MEM_P:
  172470. + case MEM_VDI_MEM_N:
  172471. + _ipu_vdi_init(ipu, channel, params);
  172472. + break;
  172473. + case MEM_VDI_MEM:
  172474. + if ((ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM) ||
  172475. + (ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
  172476. + (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)) {
  172477. + ret = -EINVAL;
  172478. + goto err;
  172479. + }
  172480. + ipu->using_ic_dirct_ch = MEM_VDI_MEM;
  172481. + ipu->ic_use_count++;
  172482. + ipu->vdi_use_count++;
  172483. + _ipu_vdi_init(ipu, channel, params);
  172484. + break;
  172485. + case MEM_ROT_VF_MEM:
  172486. + ipu->ic_use_count++;
  172487. + ipu->rot_use_count++;
  172488. + _ipu_ic_init_rotate_vf(ipu, params);
  172489. + break;
  172490. + case MEM_PRP_ENC_MEM:
  172491. + ipu->ic_use_count++;
  172492. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172493. + ipu_cm_write(ipu, reg | FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
  172494. + _ipu_ic_init_prpenc(ipu, params, false);
  172495. + break;
  172496. + case MEM_ROT_ENC_MEM:
  172497. + ipu->ic_use_count++;
  172498. + ipu->rot_use_count++;
  172499. + _ipu_ic_init_rotate_enc(ipu, params);
  172500. + break;
  172501. + case MEM_PP_MEM:
  172502. + if (params->mem_pp_mem.graphics_combine_en) {
  172503. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  172504. + in_g_pixel_fmt = params->mem_pp_mem.in_g_pixel_fmt;
  172505. + bad_pixfmt =
  172506. + _ipu_ch_param_bad_alpha_pos(in_g_pixel_fmt);
  172507. +
  172508. + if (params->mem_pp_mem.alpha_chan_en) {
  172509. + if (bad_pixfmt) {
  172510. + dev_err(ipu->dev, "bad pixel format "
  172511. + "for graphics plane from "
  172512. + "ch%d\n", sec_dma);
  172513. + ret = -EINVAL;
  172514. + goto err;
  172515. + }
  172516. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  172517. + }
  172518. +
  172519. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
  172520. + }
  172521. +
  172522. + _ipu_ic_init_pp(ipu, params);
  172523. + ipu->ic_use_count++;
  172524. + break;
  172525. + case MEM_ROT_PP_MEM:
  172526. + _ipu_ic_init_rotate_pp(ipu, params);
  172527. + ipu->ic_use_count++;
  172528. + ipu->rot_use_count++;
  172529. + break;
  172530. + case MEM_DC_SYNC:
  172531. + if (params->mem_dc_sync.di > 1) {
  172532. + ret = -EINVAL;
  172533. + goto err;
  172534. + }
  172535. +
  172536. + ipu->dc_di_assignment[1] = params->mem_dc_sync.di;
  172537. + _ipu_dc_init(ipu, 1, params->mem_dc_sync.di,
  172538. + params->mem_dc_sync.interlaced,
  172539. + params->mem_dc_sync.out_pixel_fmt);
  172540. + ipu->di_use_count[params->mem_dc_sync.di]++;
  172541. + ipu->dc_use_count++;
  172542. + ipu->dmfc_use_count++;
  172543. + break;
  172544. + case MEM_BG_SYNC:
  172545. + if (params->mem_dp_bg_sync.di > 1) {
  172546. + ret = -EINVAL;
  172547. + goto err;
  172548. + }
  172549. +
  172550. + if (params->mem_dp_bg_sync.alpha_chan_en)
  172551. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  172552. +
  172553. + ipu->dc_di_assignment[5] = params->mem_dp_bg_sync.di;
  172554. + _ipu_dp_init(ipu, channel, params->mem_dp_bg_sync.in_pixel_fmt,
  172555. + params->mem_dp_bg_sync.out_pixel_fmt);
  172556. + _ipu_dc_init(ipu, 5, params->mem_dp_bg_sync.di,
  172557. + params->mem_dp_bg_sync.interlaced,
  172558. + params->mem_dp_bg_sync.out_pixel_fmt);
  172559. + ipu->di_use_count[params->mem_dp_bg_sync.di]++;
  172560. + ipu->dc_use_count++;
  172561. + ipu->dp_use_count++;
  172562. + ipu->dmfc_use_count++;
  172563. + break;
  172564. + case MEM_FG_SYNC:
  172565. + _ipu_dp_init(ipu, channel, params->mem_dp_fg_sync.in_pixel_fmt,
  172566. + params->mem_dp_fg_sync.out_pixel_fmt);
  172567. +
  172568. + if (params->mem_dp_fg_sync.alpha_chan_en)
  172569. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  172570. +
  172571. + ipu->dc_use_count++;
  172572. + ipu->dp_use_count++;
  172573. + ipu->dmfc_use_count++;
  172574. + break;
  172575. + case DIRECT_ASYNC0:
  172576. + if (params->direct_async.di > 1) {
  172577. + ret = -EINVAL;
  172578. + goto err;
  172579. + }
  172580. +
  172581. + ipu->dc_di_assignment[8] = params->direct_async.di;
  172582. + _ipu_dc_init(ipu, 8, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
  172583. + ipu->di_use_count[params->direct_async.di]++;
  172584. + ipu->dc_use_count++;
  172585. + break;
  172586. + case DIRECT_ASYNC1:
  172587. + if (params->direct_async.di > 1) {
  172588. + ret = -EINVAL;
  172589. + goto err;
  172590. + }
  172591. +
  172592. + ipu->dc_di_assignment[9] = params->direct_async.di;
  172593. + _ipu_dc_init(ipu, 9, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
  172594. + ipu->di_use_count[params->direct_async.di]++;
  172595. + ipu->dc_use_count++;
  172596. + break;
  172597. + default:
  172598. + dev_err(ipu->dev, "Missing channel initialization\n");
  172599. + break;
  172600. + }
  172601. +
  172602. + ipu->channel_init_mask |= 1L << IPU_CHAN_ID(channel);
  172603. +
  172604. + ipu_cm_write(ipu, ipu_conf, IPU_CONF);
  172605. +
  172606. +err:
  172607. + mutex_unlock(&ipu->mutex_lock);
  172608. + return ret;
  172609. +}
  172610. +EXPORT_SYMBOL(ipu_init_channel);
  172611. +
  172612. +/*!
  172613. + * This function is called to uninitialize a logical IPU channel.
  172614. + *
  172615. + * @param ipu ipu handler
  172616. + * @param channel Input parameter for the logical channel ID to uninit.
  172617. + */
  172618. +void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel)
  172619. +{
  172620. + uint32_t reg;
  172621. + uint32_t in_dma, out_dma = 0;
  172622. + uint32_t ipu_conf;
  172623. + uint32_t dc_chan = 0;
  172624. + int ret;
  172625. +
  172626. + mutex_lock(&ipu->mutex_lock);
  172627. +
  172628. + if ((ipu->channel_init_mask & (1L << IPU_CHAN_ID(channel))) == 0) {
  172629. + dev_dbg(ipu->dev, "Channel already uninitialized %d\n",
  172630. + IPU_CHAN_ID(channel));
  172631. + mutex_unlock(&ipu->mutex_lock);
  172632. + return;
  172633. + }
  172634. +
  172635. + /* Make sure channel is disabled */
  172636. + /* Get input and output dma channels */
  172637. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  172638. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  172639. +
  172640. + if (idma_is_set(ipu, IDMAC_CHA_EN, in_dma) ||
  172641. + idma_is_set(ipu, IDMAC_CHA_EN, out_dma)) {
  172642. + dev_err(ipu->dev,
  172643. + "Channel %d is not disabled, disable first\n",
  172644. + IPU_CHAN_ID(channel));
  172645. + mutex_unlock(&ipu->mutex_lock);
  172646. + return;
  172647. + }
  172648. +
  172649. + ipu_conf = ipu_cm_read(ipu, IPU_CONF);
  172650. +
  172651. + /* Reset the double buffer */
  172652. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(in_dma));
  172653. + ipu_cm_write(ipu, reg & ~idma_mask(in_dma), IPU_CHA_DB_MODE_SEL(in_dma));
  172654. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(out_dma));
  172655. + ipu_cm_write(ipu, reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma));
  172656. +
  172657. + /* Reset the triple buffer */
  172658. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(in_dma));
  172659. + ipu_cm_write(ipu, reg & ~idma_mask(in_dma), IPU_CHA_TRB_MODE_SEL(in_dma));
  172660. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(out_dma));
  172661. + ipu_cm_write(ipu, reg & ~idma_mask(out_dma), IPU_CHA_TRB_MODE_SEL(out_dma));
  172662. +
  172663. + if (_ipu_is_ic_chan(in_dma) || _ipu_is_dp_graphic_chan(in_dma)) {
  172664. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = false;
  172665. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = false;
  172666. + }
  172667. +
  172668. + switch (channel) {
  172669. + case CSI_MEM0:
  172670. + case CSI_MEM1:
  172671. + case CSI_MEM2:
  172672. + case CSI_MEM3:
  172673. + ipu->smfc_use_count--;
  172674. + if (ipu->csi_channel[0] == channel) {
  172675. + ipu->csi_channel[0] = CHAN_NONE;
  172676. + } else if (ipu->csi_channel[1] == channel) {
  172677. + ipu->csi_channel[1] = CHAN_NONE;
  172678. + }
  172679. + break;
  172680. + case CSI_PRP_ENC_MEM:
  172681. + ipu->ic_use_count--;
  172682. + if (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)
  172683. + ipu->using_ic_dirct_ch = 0;
  172684. + _ipu_ic_uninit_prpenc(ipu);
  172685. + if (ipu->csi_channel[0] == channel) {
  172686. + ipu->csi_channel[0] = CHAN_NONE;
  172687. + } else if (ipu->csi_channel[1] == channel) {
  172688. + ipu->csi_channel[1] = CHAN_NONE;
  172689. + }
  172690. + break;
  172691. + case CSI_PRP_VF_MEM:
  172692. + ipu->ic_use_count--;
  172693. + if (ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM)
  172694. + ipu->using_ic_dirct_ch = 0;
  172695. + _ipu_ic_uninit_prpvf(ipu);
  172696. + if (ipu->csi_channel[0] == channel) {
  172697. + ipu->csi_channel[0] = CHAN_NONE;
  172698. + } else if (ipu->csi_channel[1] == channel) {
  172699. + ipu->csi_channel[1] = CHAN_NONE;
  172700. + }
  172701. + break;
  172702. + case MEM_PRP_VF_MEM:
  172703. + ipu->ic_use_count--;
  172704. + _ipu_ic_uninit_prpvf(ipu);
  172705. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172706. + ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  172707. + break;
  172708. + case MEM_VDI_PRP_VF_MEM:
  172709. + ipu->ic_use_count--;
  172710. + ipu->vdi_use_count--;
  172711. + if (ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM)
  172712. + ipu->using_ic_dirct_ch = 0;
  172713. + _ipu_ic_uninit_prpvf(ipu);
  172714. + _ipu_vdi_uninit(ipu);
  172715. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172716. + ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  172717. + break;
  172718. + case MEM_VDI_MEM:
  172719. + ipu->ic_use_count--;
  172720. + ipu->vdi_use_count--;
  172721. + if (ipu->using_ic_dirct_ch == MEM_VDI_MEM)
  172722. + ipu->using_ic_dirct_ch = 0;
  172723. + _ipu_vdi_uninit(ipu);
  172724. + break;
  172725. + case MEM_VDI_PRP_VF_MEM_P:
  172726. + case MEM_VDI_PRP_VF_MEM_N:
  172727. + case MEM_VDI_MEM_P:
  172728. + case MEM_VDI_MEM_N:
  172729. + break;
  172730. + case MEM_ROT_VF_MEM:
  172731. + ipu->rot_use_count--;
  172732. + ipu->ic_use_count--;
  172733. + _ipu_ic_uninit_rotate_vf(ipu);
  172734. + break;
  172735. + case MEM_PRP_ENC_MEM:
  172736. + ipu->ic_use_count--;
  172737. + _ipu_ic_uninit_prpenc(ipu);
  172738. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  172739. + ipu_cm_write(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
  172740. + break;
  172741. + case MEM_ROT_ENC_MEM:
  172742. + ipu->rot_use_count--;
  172743. + ipu->ic_use_count--;
  172744. + _ipu_ic_uninit_rotate_enc(ipu);
  172745. + break;
  172746. + case MEM_PP_MEM:
  172747. + ipu->ic_use_count--;
  172748. + _ipu_ic_uninit_pp(ipu);
  172749. + break;
  172750. + case MEM_ROT_PP_MEM:
  172751. + ipu->rot_use_count--;
  172752. + ipu->ic_use_count--;
  172753. + _ipu_ic_uninit_rotate_pp(ipu);
  172754. + break;
  172755. + case MEM_DC_SYNC:
  172756. + dc_chan = 1;
  172757. + _ipu_dc_uninit(ipu, 1);
  172758. + ipu->di_use_count[ipu->dc_di_assignment[1]]--;
  172759. + ipu->dc_use_count--;
  172760. + ipu->dmfc_use_count--;
  172761. + break;
  172762. + case MEM_BG_SYNC:
  172763. + dc_chan = 5;
  172764. + _ipu_dp_uninit(ipu, channel);
  172765. + _ipu_dc_uninit(ipu, 5);
  172766. + ipu->di_use_count[ipu->dc_di_assignment[5]]--;
  172767. + ipu->dc_use_count--;
  172768. + ipu->dp_use_count--;
  172769. + ipu->dmfc_use_count--;
  172770. + break;
  172771. + case MEM_FG_SYNC:
  172772. + _ipu_dp_uninit(ipu, channel);
  172773. + ipu->dc_use_count--;
  172774. + ipu->dp_use_count--;
  172775. + ipu->dmfc_use_count--;
  172776. + break;
  172777. + case DIRECT_ASYNC0:
  172778. + dc_chan = 8;
  172779. + _ipu_dc_uninit(ipu, 8);
  172780. + ipu->di_use_count[ipu->dc_di_assignment[8]]--;
  172781. + ipu->dc_use_count--;
  172782. + break;
  172783. + case DIRECT_ASYNC1:
  172784. + dc_chan = 9;
  172785. + _ipu_dc_uninit(ipu, 9);
  172786. + ipu->di_use_count[ipu->dc_di_assignment[9]]--;
  172787. + ipu->dc_use_count--;
  172788. + break;
  172789. + default:
  172790. + break;
  172791. + }
  172792. +
  172793. + if (ipu->ic_use_count == 0)
  172794. + ipu_conf &= ~IPU_CONF_IC_EN;
  172795. + if (ipu->vdi_use_count == 0) {
  172796. + ipu_conf &= ~IPU_CONF_ISP_EN;
  172797. + ipu_conf &= ~IPU_CONF_VDI_EN;
  172798. + ipu_conf &= ~IPU_CONF_IC_INPUT;
  172799. + }
  172800. + if (ipu->rot_use_count == 0)
  172801. + ipu_conf &= ~IPU_CONF_ROT_EN;
  172802. + if (ipu->dc_use_count == 0)
  172803. + ipu_conf &= ~IPU_CONF_DC_EN;
  172804. + if (ipu->dp_use_count == 0)
  172805. + ipu_conf &= ~IPU_CONF_DP_EN;
  172806. + if (ipu->dmfc_use_count == 0)
  172807. + ipu_conf &= ~IPU_CONF_DMFC_EN;
  172808. + if (ipu->di_use_count[0] == 0) {
  172809. + ipu_conf &= ~IPU_CONF_DI0_EN;
  172810. + }
  172811. + if (ipu->di_use_count[1] == 0) {
  172812. + ipu_conf &= ~IPU_CONF_DI1_EN;
  172813. + }
  172814. + if (ipu->smfc_use_count == 0)
  172815. + ipu_conf &= ~IPU_CONF_SMFC_EN;
  172816. +
  172817. + ipu_cm_write(ipu, ipu_conf, IPU_CONF);
  172818. +
  172819. + ipu->channel_init_mask &= ~(1L << IPU_CHAN_ID(channel));
  172820. +
  172821. + /*
  172822. + * Disable pixel clk and its parent clock(if the parent clock
  172823. + * usecount is 1) after clearing DC/DP/DI bits in IPU_CONF
  172824. + * register to prevent LVDS display channel starvation.
  172825. + */
  172826. + if (_ipu_is_primary_disp_chan(in_dma))
  172827. + clk_disable_unprepare(ipu->pixel_clk[ipu->dc_di_assignment[dc_chan]]);
  172828. +
  172829. + mutex_unlock(&ipu->mutex_lock);
  172830. +
  172831. + _ipu_put(ipu);
  172832. +
  172833. + ret = pm_runtime_put_sync_suspend(ipu->dev);
  172834. + if (ret < 0) {
  172835. + dev_err(ipu->dev, "ch = %d, pm_runtime_put failed:%d!\n",
  172836. + IPU_CHAN_ID(channel), ret);
  172837. + dump_stack();
  172838. + }
  172839. +
  172840. + WARN_ON(ipu->ic_use_count < 0);
  172841. + WARN_ON(ipu->vdi_use_count < 0);
  172842. + WARN_ON(ipu->rot_use_count < 0);
  172843. + WARN_ON(ipu->dc_use_count < 0);
  172844. + WARN_ON(ipu->dp_use_count < 0);
  172845. + WARN_ON(ipu->dmfc_use_count < 0);
  172846. + WARN_ON(ipu->smfc_use_count < 0);
  172847. +}
  172848. +EXPORT_SYMBOL(ipu_uninit_channel);
  172849. +
  172850. +/*!
  172851. + * This function is called to initialize buffer(s) for logical IPU channel.
  172852. + *
  172853. + * @param ipu ipu handler
  172854. + *
  172855. + * @param channel Input parameter for the logical channel ID.
  172856. + *
  172857. + * @param type Input parameter which buffer to initialize.
  172858. + *
  172859. + * @param pixel_fmt Input parameter for pixel format of buffer.
  172860. + * Pixel format is a FOURCC ASCII code.
  172861. + *
  172862. + * @param width Input parameter for width of buffer in pixels.
  172863. + *
  172864. + * @param height Input parameter for height of buffer in pixels.
  172865. + *
  172866. + * @param stride Input parameter for stride length of buffer
  172867. + * in pixels.
  172868. + *
  172869. + * @param rot_mode Input parameter for rotation setting of buffer.
  172870. + * A rotation setting other than
  172871. + * IPU_ROTATE_VERT_FLIP
  172872. + * should only be used for input buffers of
  172873. + * rotation channels.
  172874. + *
  172875. + * @param phyaddr_0 Input parameter buffer 0 physical address.
  172876. + *
  172877. + * @param phyaddr_1 Input parameter buffer 1 physical address.
  172878. + * Setting this to a value other than NULL enables
  172879. + * double buffering mode.
  172880. + *
  172881. + * @param phyaddr_2 Input parameter buffer 2 physical address.
  172882. + * Setting this to a value other than NULL enables
  172883. + * triple buffering mode, phyaddr_1 should not be
  172884. + * NULL then.
  172885. + *
  172886. + * @param u private u offset for additional cropping,
  172887. + * zero if not used.
  172888. + *
  172889. + * @param v private v offset for additional cropping,
  172890. + * zero if not used.
  172891. + *
  172892. + * @return Returns 0 on success or negative error code on fail
  172893. + */
  172894. +int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  172895. + ipu_buffer_t type,
  172896. + uint32_t pixel_fmt,
  172897. + uint16_t width, uint16_t height,
  172898. + uint32_t stride,
  172899. + ipu_rotate_mode_t rot_mode,
  172900. + dma_addr_t phyaddr_0, dma_addr_t phyaddr_1,
  172901. + dma_addr_t phyaddr_2,
  172902. + uint32_t u, uint32_t v)
  172903. +{
  172904. + uint32_t reg;
  172905. + uint32_t dma_chan;
  172906. + uint32_t burst_size;
  172907. +
  172908. + dma_chan = channel_2_dma(channel, type);
  172909. + if (!idma_is_valid(dma_chan))
  172910. + return -EINVAL;
  172911. +
  172912. + if (stride < width * bytes_per_pixel(pixel_fmt))
  172913. + stride = width * bytes_per_pixel(pixel_fmt);
  172914. +
  172915. + if (stride % 4) {
  172916. + dev_err(ipu->dev,
  172917. + "Stride not 32-bit aligned, stride = %d\n", stride);
  172918. + return -EINVAL;
  172919. + }
  172920. + /* IC & IRT channels' width must be multiple of 8 pixels */
  172921. + if ((_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan))
  172922. + && (width % 8)) {
  172923. + dev_err(ipu->dev, "Width must be 8 pixel multiple\n");
  172924. + return -EINVAL;
  172925. + }
  172926. +
  172927. + if (_ipu_is_vdi_out_chan(dma_chan) &&
  172928. + ((width < 16) || (height < 16) || (width % 2) || (height % 4))) {
  172929. + dev_err(ipu->dev, "vdi width/height limited err\n");
  172930. + return -EINVAL;
  172931. + }
  172932. +
  172933. + /* IPUv3EX and IPUv3M support triple buffer */
  172934. + if ((!_ipu_is_trb_chan(dma_chan)) && phyaddr_2) {
  172935. + dev_err(ipu->dev, "Chan%d doesn't support triple buffer "
  172936. + "mode\n", dma_chan);
  172937. + return -EINVAL;
  172938. + }
  172939. + if (!phyaddr_1 && phyaddr_2) {
  172940. + dev_err(ipu->dev, "Chan%d's buf1 physical addr is NULL for "
  172941. + "triple buffer mode\n", dma_chan);
  172942. + return -EINVAL;
  172943. + }
  172944. +
  172945. + mutex_lock(&ipu->mutex_lock);
  172946. +
  172947. + /* Build parameter memory data for DMA channel */
  172948. + _ipu_ch_param_init(ipu, dma_chan, pixel_fmt, width, height, stride, u, v, 0,
  172949. + phyaddr_0, phyaddr_1, phyaddr_2);
  172950. +
  172951. + /* Set correlative channel parameter of local alpha channel */
  172952. + if ((_ipu_is_ic_graphic_chan(dma_chan) ||
  172953. + _ipu_is_dp_graphic_chan(dma_chan)) &&
  172954. + (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] == true)) {
  172955. + _ipu_ch_param_set_alpha_use_separate_channel(ipu, dma_chan, true);
  172956. + _ipu_ch_param_set_alpha_buffer_memory(ipu, dma_chan);
  172957. + _ipu_ch_param_set_alpha_condition_read(ipu, dma_chan);
  172958. + /* fix alpha width as 8 and burst size as 16*/
  172959. + _ipu_ch_params_set_alpha_width(ipu, dma_chan, 8);
  172960. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 16);
  172961. + } else if (_ipu_is_ic_graphic_chan(dma_chan) &&
  172962. + ipu_pixel_format_has_alpha(pixel_fmt))
  172963. + _ipu_ch_param_set_alpha_use_separate_channel(ipu, dma_chan, false);
  172964. +
  172965. + if (rot_mode)
  172966. + _ipu_ch_param_set_rotation(ipu, dma_chan, rot_mode);
  172967. +
  172968. + /* IC and ROT channels have restriction of 8 or 16 pix burst length */
  172969. + if (_ipu_is_ic_chan(dma_chan) || _ipu_is_vdi_out_chan(dma_chan)) {
  172970. + if ((width % 16) == 0)
  172971. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 16);
  172972. + else
  172973. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 8);
  172974. + } else if (_ipu_is_irt_chan(dma_chan)) {
  172975. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 8);
  172976. + _ipu_ch_param_set_block_mode(ipu, dma_chan);
  172977. + } else if (_ipu_is_dmfc_chan(dma_chan)) {
  172978. + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
  172979. + _ipu_dmfc_set_wait4eot(ipu, dma_chan, width);
  172980. + _ipu_dmfc_set_burst_size(ipu, dma_chan, burst_size);
  172981. + }
  172982. +
  172983. + if (_ipu_disp_chan_is_interlaced(ipu, channel) ||
  172984. + ipu->chan_is_interlaced[dma_chan])
  172985. + _ipu_ch_param_set_interlaced_scan(ipu, dma_chan);
  172986. +
  172987. + if (_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan) ||
  172988. + _ipu_is_vdi_out_chan(dma_chan)) {
  172989. + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
  172990. + _ipu_ic_idma_init(ipu, dma_chan, width, height, burst_size,
  172991. + rot_mode);
  172992. + } else if (_ipu_is_smfc_chan(dma_chan)) {
  172993. + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
  172994. + /*
  172995. + * This is different from IPUv3 spec, but it is confirmed
  172996. + * in IPUforum that SMFC burst size should be NPB[6:3]
  172997. + * when IDMAC works in 16-bit generic data mode.
  172998. + */
  172999. + if (pixel_fmt == IPU_PIX_FMT_GENERIC)
  173000. + /* 8 bits per pixel */
  173001. + burst_size = burst_size >> 4;
  173002. + else if (pixel_fmt == IPU_PIX_FMT_GENERIC_16)
  173003. + /* 16 bits per pixel */
  173004. + burst_size = burst_size >> 3;
  173005. + else
  173006. + burst_size = burst_size >> 2;
  173007. + _ipu_smfc_set_burst_size(ipu, channel, burst_size-1);
  173008. + }
  173009. +
  173010. + /* AXI-id */
  173011. + if (idma_is_set(ipu, IDMAC_CHA_PRI, dma_chan)) {
  173012. + unsigned reg = IDMAC_CH_LOCK_EN_1;
  173013. + uint32_t value = 0;
  173014. + if (ipu->pdata->devtype == IPU_V3H) {
  173015. + _ipu_ch_param_set_axi_id(ipu, dma_chan, 0);
  173016. + switch (dma_chan) {
  173017. + case 5:
  173018. + value = 0x3;
  173019. + break;
  173020. + case 11:
  173021. + value = 0x3 << 2;
  173022. + break;
  173023. + case 12:
  173024. + value = 0x3 << 4;
  173025. + break;
  173026. + case 14:
  173027. + value = 0x3 << 6;
  173028. + break;
  173029. + case 15:
  173030. + value = 0x3 << 8;
  173031. + break;
  173032. + case 20:
  173033. + value = 0x3 << 10;
  173034. + break;
  173035. + case 21:
  173036. + value = 0x3 << 12;
  173037. + break;
  173038. + case 22:
  173039. + value = 0x3 << 14;
  173040. + break;
  173041. + case 23:
  173042. + value = 0x3 << 16;
  173043. + break;
  173044. + case 27:
  173045. + value = 0x3 << 18;
  173046. + break;
  173047. + case 28:
  173048. + value = 0x3 << 20;
  173049. + break;
  173050. + case 45:
  173051. + reg = IDMAC_CH_LOCK_EN_2;
  173052. + value = 0x3 << 0;
  173053. + break;
  173054. + case 46:
  173055. + reg = IDMAC_CH_LOCK_EN_2;
  173056. + value = 0x3 << 2;
  173057. + break;
  173058. + case 47:
  173059. + reg = IDMAC_CH_LOCK_EN_2;
  173060. + value = 0x3 << 4;
  173061. + break;
  173062. + case 48:
  173063. + reg = IDMAC_CH_LOCK_EN_2;
  173064. + value = 0x3 << 6;
  173065. + break;
  173066. + case 49:
  173067. + reg = IDMAC_CH_LOCK_EN_2;
  173068. + value = 0x3 << 8;
  173069. + break;
  173070. + case 50:
  173071. + reg = IDMAC_CH_LOCK_EN_2;
  173072. + value = 0x3 << 10;
  173073. + break;
  173074. + default:
  173075. + break;
  173076. + }
  173077. + value |= ipu_idmac_read(ipu, reg);
  173078. + ipu_idmac_write(ipu, value, reg);
  173079. + } else
  173080. + _ipu_ch_param_set_axi_id(ipu, dma_chan, 1);
  173081. + } else {
  173082. + if (ipu->pdata->devtype == IPU_V3H)
  173083. + _ipu_ch_param_set_axi_id(ipu, dma_chan, 1);
  173084. + }
  173085. +
  173086. + _ipu_ch_param_dump(ipu, dma_chan);
  173087. +
  173088. + if (phyaddr_2 && g_ipu_hw_rev >= IPU_V3DEX) {
  173089. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(dma_chan));
  173090. + reg &= ~idma_mask(dma_chan);
  173091. + ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(dma_chan));
  173092. +
  173093. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan));
  173094. + reg |= idma_mask(dma_chan);
  173095. + ipu_cm_write(ipu, reg, IPU_CHA_TRB_MODE_SEL(dma_chan));
  173096. +
  173097. + /* Set IDMAC third buffer's cpmem number */
  173098. + /* See __ipu_ch_get_third_buf_cpmem_num() for mapping */
  173099. + ipu_idmac_write(ipu, 0x00444047L, IDMAC_SUB_ADDR_4);
  173100. + ipu_idmac_write(ipu, 0x46004241L, IDMAC_SUB_ADDR_3);
  173101. + ipu_idmac_write(ipu, 0x00000045L, IDMAC_SUB_ADDR_1);
  173102. +
  173103. + /* Reset to buffer 0 */
  173104. + ipu_cm_write(ipu, tri_cur_buf_mask(dma_chan),
  173105. + IPU_CHA_TRIPLE_CUR_BUF(dma_chan));
  173106. + } else {
  173107. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan));
  173108. + reg &= ~idma_mask(dma_chan);
  173109. + ipu_cm_write(ipu, reg, IPU_CHA_TRB_MODE_SEL(dma_chan));
  173110. +
  173111. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(dma_chan));
  173112. + if (phyaddr_1)
  173113. + reg |= idma_mask(dma_chan);
  173114. + else
  173115. + reg &= ~idma_mask(dma_chan);
  173116. + ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(dma_chan));
  173117. +
  173118. + /* Reset to buffer 0 */
  173119. + ipu_cm_write(ipu, idma_mask(dma_chan),
  173120. + IPU_CHA_CUR_BUF(dma_chan));
  173121. +
  173122. + }
  173123. +
  173124. + mutex_unlock(&ipu->mutex_lock);
  173125. +
  173126. + return 0;
  173127. +}
  173128. +EXPORT_SYMBOL(ipu_init_channel_buffer);
  173129. +
  173130. +/*!
  173131. + * This function is called to update the physical address of a buffer for
  173132. + * a logical IPU channel.
  173133. + *
  173134. + * @param ipu ipu handler
  173135. + * @param channel Input parameter for the logical channel ID.
  173136. + *
  173137. + * @param type Input parameter which buffer to initialize.
  173138. + *
  173139. + * @param bufNum Input parameter for buffer number to update.
  173140. + * 0 or 1 are the only valid values.
  173141. + *
  173142. + * @param phyaddr Input parameter buffer physical address.
  173143. + *
  173144. + * @return This function returns 0 on success or negative error code on
  173145. + * fail. This function will fail if the buffer is set to ready.
  173146. + */
  173147. +int32_t ipu_update_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  173148. + ipu_buffer_t type, uint32_t bufNum, dma_addr_t phyaddr)
  173149. +{
  173150. + uint32_t reg;
  173151. + int ret = 0;
  173152. + uint32_t dma_chan = channel_2_dma(channel, type);
  173153. + unsigned long lock_flags;
  173154. +
  173155. + if (dma_chan == IDMA_CHAN_INVALID)
  173156. + return -EINVAL;
  173157. +
  173158. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173159. + if (bufNum == 0)
  173160. + reg = ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan));
  173161. + else if (bufNum == 1)
  173162. + reg = ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan));
  173163. + else
  173164. + reg = ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan));
  173165. +
  173166. + if ((reg & idma_mask(dma_chan)) == 0)
  173167. + _ipu_ch_param_set_buffer(ipu, dma_chan, bufNum, phyaddr);
  173168. + else
  173169. + ret = -EACCES;
  173170. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173171. +
  173172. + return ret;
  173173. +}
  173174. +EXPORT_SYMBOL(ipu_update_channel_buffer);
  173175. +
  173176. +/*!
  173177. + * This function is called to update the band mode setting for
  173178. + * a logical IPU channel.
  173179. + *
  173180. + * @param ipu ipu handler
  173181. + *
  173182. + * @param channel Input parameter for the logical channel ID.
  173183. + *
  173184. + * @param type Input parameter which buffer to initialize.
  173185. + *
  173186. + * @param band_height Input parameter for band lines:
  173187. + * shoule be log2(4/8/16/32/64/128/256).
  173188. + *
  173189. + * @return This function returns 0 on success or negative error code on
  173190. + * fail.
  173191. + */
  173192. +int32_t ipu_set_channel_bandmode(struct ipu_soc *ipu, ipu_channel_t channel,
  173193. + ipu_buffer_t type, uint32_t band_height)
  173194. +{
  173195. + uint32_t reg;
  173196. + int ret = 0;
  173197. + uint32_t dma_chan = channel_2_dma(channel, type);
  173198. +
  173199. + if ((2 > band_height) || (8 < band_height))
  173200. + return -EINVAL;
  173201. +
  173202. + mutex_lock(&ipu->mutex_lock);
  173203. +
  173204. + reg = ipu_idmac_read(ipu, IDMAC_BAND_EN(dma_chan));
  173205. + reg |= 1 << (dma_chan % 32);
  173206. + ipu_idmac_write(ipu, reg, IDMAC_BAND_EN(dma_chan));
  173207. +
  173208. + _ipu_ch_param_set_bandmode(ipu, dma_chan, band_height);
  173209. + dev_dbg(ipu->dev, "dma_chan:%d, band_height:%d.\n\n",
  173210. + dma_chan, 1 << band_height);
  173211. + mutex_unlock(&ipu->mutex_lock);
  173212. +
  173213. + return ret;
  173214. +}
  173215. +EXPORT_SYMBOL(ipu_set_channel_bandmode);
  173216. +
  173217. +/*!
  173218. + * This function is called to initialize a buffer for logical IPU channel.
  173219. + *
  173220. + * @param ipu ipu handler
  173221. + * @param channel Input parameter for the logical channel ID.
  173222. + *
  173223. + * @param type Input parameter which buffer to initialize.
  173224. + *
  173225. + * @param pixel_fmt Input parameter for pixel format of buffer.
  173226. + * Pixel format is a FOURCC ASCII code.
  173227. + *
  173228. + * @param width Input parameter for width of buffer in pixels.
  173229. + *
  173230. + * @param height Input parameter for height of buffer in pixels.
  173231. + *
  173232. + * @param stride Input parameter for stride length of buffer
  173233. + * in pixels.
  173234. + *
  173235. + * @param u predefined private u offset for additional cropping,
  173236. + * zero if not used.
  173237. + *
  173238. + * @param v predefined private v offset for additional cropping,
  173239. + * zero if not used.
  173240. + *
  173241. + * @param vertical_offset vertical offset for Y coordinate
  173242. + * in the existed frame
  173243. + *
  173244. + *
  173245. + * @param horizontal_offset horizontal offset for X coordinate
  173246. + * in the existed frame
  173247. + *
  173248. + *
  173249. + * @return Returns 0 on success or negative error code on fail
  173250. + * This function will fail if any buffer is set to ready.
  173251. + */
  173252. +
  173253. +int32_t ipu_update_channel_offset(struct ipu_soc *ipu,
  173254. + ipu_channel_t channel, ipu_buffer_t type,
  173255. + uint32_t pixel_fmt,
  173256. + uint16_t width, uint16_t height,
  173257. + uint32_t stride,
  173258. + uint32_t u, uint32_t v,
  173259. + uint32_t vertical_offset, uint32_t horizontal_offset)
  173260. +{
  173261. + int ret = 0;
  173262. + uint32_t dma_chan = channel_2_dma(channel, type);
  173263. + unsigned long lock_flags;
  173264. +
  173265. + if (dma_chan == IDMA_CHAN_INVALID)
  173266. + return -EINVAL;
  173267. +
  173268. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173269. + if ((ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan)) & idma_mask(dma_chan)) ||
  173270. + (ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan)) & idma_mask(dma_chan)) ||
  173271. + ((ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan)) & idma_mask(dma_chan)) &&
  173272. + (ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan)) & idma_mask(dma_chan)) &&
  173273. + _ipu_is_trb_chan(dma_chan)))
  173274. + ret = -EACCES;
  173275. + else
  173276. + _ipu_ch_offset_update(ipu, dma_chan, pixel_fmt, width, height, stride,
  173277. + u, v, 0, vertical_offset, horizontal_offset);
  173278. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173279. +
  173280. + return ret;
  173281. +}
  173282. +EXPORT_SYMBOL(ipu_update_channel_offset);
  173283. +
  173284. +
  173285. +/*!
  173286. + * This function is called to set a channel's buffer as ready.
  173287. + *
  173288. + * @param ipu ipu handler
  173289. + * @param channel Input parameter for the logical channel ID.
  173290. + *
  173291. + * @param type Input parameter which buffer to initialize.
  173292. + *
  173293. + * @param bufNum Input parameter for which buffer number set to
  173294. + * ready state.
  173295. + *
  173296. + * @return Returns 0 on success or negative error code on fail
  173297. + */
  173298. +int32_t ipu_select_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  173299. + ipu_buffer_t type, uint32_t bufNum)
  173300. +{
  173301. + uint32_t dma_chan = channel_2_dma(channel, type);
  173302. + unsigned long lock_flags;
  173303. +
  173304. + if (dma_chan == IDMA_CHAN_INVALID)
  173305. + return -EINVAL;
  173306. +
  173307. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173308. + /* Mark buffer to be ready. */
  173309. + if (bufNum == 0)
  173310. + ipu_cm_write(ipu, idma_mask(dma_chan),
  173311. + IPU_CHA_BUF0_RDY(dma_chan));
  173312. + else if (bufNum == 1)
  173313. + ipu_cm_write(ipu, idma_mask(dma_chan),
  173314. + IPU_CHA_BUF1_RDY(dma_chan));
  173315. + else
  173316. + ipu_cm_write(ipu, idma_mask(dma_chan),
  173317. + IPU_CHA_BUF2_RDY(dma_chan));
  173318. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173319. +
  173320. + return 0;
  173321. +}
  173322. +EXPORT_SYMBOL(ipu_select_buffer);
  173323. +
  173324. +/*!
  173325. + * This function is called to set a channel's buffer as ready.
  173326. + *
  173327. + * @param ipu ipu handler
  173328. + * @param bufNum Input parameter for which buffer number set to
  173329. + * ready state.
  173330. + *
  173331. + * @return Returns 0 on success or negative error code on fail
  173332. + */
  173333. +int32_t ipu_select_multi_vdi_buffer(struct ipu_soc *ipu, uint32_t bufNum)
  173334. +{
  173335. +
  173336. + uint32_t dma_chan = channel_2_dma(MEM_VDI_PRP_VF_MEM, IPU_INPUT_BUFFER);
  173337. + uint32_t mask_bit =
  173338. + idma_mask(channel_2_dma(MEM_VDI_PRP_VF_MEM_P, IPU_INPUT_BUFFER))|
  173339. + idma_mask(dma_chan)|
  173340. + idma_mask(channel_2_dma(MEM_VDI_PRP_VF_MEM_N, IPU_INPUT_BUFFER));
  173341. + unsigned long lock_flags;
  173342. +
  173343. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173344. + /* Mark buffers to be ready. */
  173345. + if (bufNum == 0)
  173346. + ipu_cm_write(ipu, mask_bit, IPU_CHA_BUF0_RDY(dma_chan));
  173347. + else
  173348. + ipu_cm_write(ipu, mask_bit, IPU_CHA_BUF1_RDY(dma_chan));
  173349. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173350. +
  173351. + return 0;
  173352. +}
  173353. +EXPORT_SYMBOL(ipu_select_multi_vdi_buffer);
  173354. +
  173355. +#define NA -1
  173356. +static int proc_dest_sel[] = {
  173357. + 0, 1, 1, 3, 5, 5, 4, 7, 8, 9, 10, 11, 12, 14, 15, 16,
  173358. + 0, 1, 1, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 14, 31 };
  173359. +static int proc_src_sel[] = { 0, 6, 7, 6, 7, 8, 5, NA, NA, NA,
  173360. + NA, NA, NA, NA, NA, 1, 2, 3, 4, 7, 8, NA, 8, NA };
  173361. +static int disp_src_sel[] = { 0, 6, 7, 8, 3, 4, 5, NA, NA, NA,
  173362. + NA, NA, NA, NA, NA, 1, NA, 2, NA, 3, 4, 4, 4, 4 };
  173363. +
  173364. +
  173365. +/*!
  173366. + * This function links 2 channels together for automatic frame
  173367. + * synchronization. The output of the source channel is linked to the input of
  173368. + * the destination channel.
  173369. + *
  173370. + * @param ipu ipu handler
  173371. + * @param src_ch Input parameter for the logical channel ID of
  173372. + * the source channel.
  173373. + *
  173374. + * @param dest_ch Input parameter for the logical channel ID of
  173375. + * the destination channel.
  173376. + *
  173377. + * @return This function returns 0 on success or negative error code on
  173378. + * fail.
  173379. + */
  173380. +int32_t ipu_link_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch)
  173381. +{
  173382. + int retval = 0;
  173383. + uint32_t fs_proc_flow1;
  173384. + uint32_t fs_proc_flow2;
  173385. + uint32_t fs_proc_flow3;
  173386. + uint32_t fs_disp_flow1;
  173387. +
  173388. + mutex_lock(&ipu->mutex_lock);
  173389. +
  173390. + fs_proc_flow1 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  173391. + fs_proc_flow2 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW2);
  173392. + fs_proc_flow3 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW3);
  173393. + fs_disp_flow1 = ipu_cm_read(ipu, IPU_FS_DISP_FLOW1);
  173394. +
  173395. + switch (src_ch) {
  173396. + case CSI_MEM0:
  173397. + fs_proc_flow3 &= ~FS_SMFC0_DEST_SEL_MASK;
  173398. + fs_proc_flow3 |=
  173399. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173400. + FS_SMFC0_DEST_SEL_OFFSET;
  173401. + break;
  173402. + case CSI_MEM1:
  173403. + fs_proc_flow3 &= ~FS_SMFC1_DEST_SEL_MASK;
  173404. + fs_proc_flow3 |=
  173405. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173406. + FS_SMFC1_DEST_SEL_OFFSET;
  173407. + break;
  173408. + case CSI_MEM2:
  173409. + fs_proc_flow3 &= ~FS_SMFC2_DEST_SEL_MASK;
  173410. + fs_proc_flow3 |=
  173411. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173412. + FS_SMFC2_DEST_SEL_OFFSET;
  173413. + break;
  173414. + case CSI_MEM3:
  173415. + fs_proc_flow3 &= ~FS_SMFC3_DEST_SEL_MASK;
  173416. + fs_proc_flow3 |=
  173417. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173418. + FS_SMFC3_DEST_SEL_OFFSET;
  173419. + break;
  173420. + case CSI_PRP_ENC_MEM:
  173421. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  173422. + fs_proc_flow2 |=
  173423. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173424. + FS_PRPENC_DEST_SEL_OFFSET;
  173425. + break;
  173426. + case CSI_PRP_VF_MEM:
  173427. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173428. + fs_proc_flow2 |=
  173429. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173430. + FS_PRPVF_DEST_SEL_OFFSET;
  173431. + break;
  173432. + case MEM_PP_MEM:
  173433. + fs_proc_flow2 &= ~FS_PP_DEST_SEL_MASK;
  173434. + fs_proc_flow2 |=
  173435. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173436. + FS_PP_DEST_SEL_OFFSET;
  173437. + break;
  173438. + case MEM_ROT_PP_MEM:
  173439. + fs_proc_flow2 &= ~FS_PP_ROT_DEST_SEL_MASK;
  173440. + fs_proc_flow2 |=
  173441. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173442. + FS_PP_ROT_DEST_SEL_OFFSET;
  173443. + break;
  173444. + case MEM_PRP_ENC_MEM:
  173445. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  173446. + fs_proc_flow2 |=
  173447. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173448. + FS_PRPENC_DEST_SEL_OFFSET;
  173449. + break;
  173450. + case MEM_ROT_ENC_MEM:
  173451. + fs_proc_flow2 &= ~FS_PRPENC_ROT_DEST_SEL_MASK;
  173452. + fs_proc_flow2 |=
  173453. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173454. + FS_PRPENC_ROT_DEST_SEL_OFFSET;
  173455. + break;
  173456. + case MEM_PRP_VF_MEM:
  173457. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173458. + fs_proc_flow2 |=
  173459. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173460. + FS_PRPVF_DEST_SEL_OFFSET;
  173461. + break;
  173462. + case MEM_VDI_PRP_VF_MEM:
  173463. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173464. + fs_proc_flow2 |=
  173465. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173466. + FS_PRPVF_DEST_SEL_OFFSET;
  173467. + break;
  173468. + case MEM_ROT_VF_MEM:
  173469. + fs_proc_flow2 &= ~FS_PRPVF_ROT_DEST_SEL_MASK;
  173470. + fs_proc_flow2 |=
  173471. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  173472. + FS_PRPVF_ROT_DEST_SEL_OFFSET;
  173473. + break;
  173474. + case MEM_VDOA_MEM:
  173475. + fs_proc_flow3 &= ~FS_VDOA_DEST_SEL_MASK;
  173476. + if (MEM_VDI_MEM == dest_ch)
  173477. + fs_proc_flow3 |= FS_VDOA_DEST_SEL_VDI;
  173478. + else if (MEM_PP_MEM == dest_ch)
  173479. + fs_proc_flow3 |= FS_VDOA_DEST_SEL_IC;
  173480. + else {
  173481. + retval = -EINVAL;
  173482. + goto err;
  173483. + }
  173484. + break;
  173485. + default:
  173486. + retval = -EINVAL;
  173487. + goto err;
  173488. + }
  173489. +
  173490. + switch (dest_ch) {
  173491. + case MEM_PP_MEM:
  173492. + fs_proc_flow1 &= ~FS_PP_SRC_SEL_MASK;
  173493. + if (MEM_VDOA_MEM == src_ch)
  173494. + fs_proc_flow1 |= FS_PP_SRC_SEL_VDOA;
  173495. + else
  173496. + fs_proc_flow1 |= proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  173497. + FS_PP_SRC_SEL_OFFSET;
  173498. + break;
  173499. + case MEM_ROT_PP_MEM:
  173500. + fs_proc_flow1 &= ~FS_PP_ROT_SRC_SEL_MASK;
  173501. + fs_proc_flow1 |=
  173502. + proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  173503. + FS_PP_ROT_SRC_SEL_OFFSET;
  173504. + break;
  173505. + case MEM_PRP_ENC_MEM:
  173506. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173507. + fs_proc_flow1 |=
  173508. + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
  173509. + break;
  173510. + case MEM_ROT_ENC_MEM:
  173511. + fs_proc_flow1 &= ~FS_PRPENC_ROT_SRC_SEL_MASK;
  173512. + fs_proc_flow1 |=
  173513. + proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  173514. + FS_PRPENC_ROT_SRC_SEL_OFFSET;
  173515. + break;
  173516. + case MEM_PRP_VF_MEM:
  173517. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173518. + fs_proc_flow1 |=
  173519. + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
  173520. + break;
  173521. + case MEM_VDI_PRP_VF_MEM:
  173522. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173523. + fs_proc_flow1 |=
  173524. + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
  173525. + break;
  173526. + case MEM_ROT_VF_MEM:
  173527. + fs_proc_flow1 &= ~FS_PRPVF_ROT_SRC_SEL_MASK;
  173528. + fs_proc_flow1 |=
  173529. + proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  173530. + FS_PRPVF_ROT_SRC_SEL_OFFSET;
  173531. + break;
  173532. + case MEM_DC_SYNC:
  173533. + fs_disp_flow1 &= ~FS_DC1_SRC_SEL_MASK;
  173534. + fs_disp_flow1 |=
  173535. + disp_src_sel[IPU_CHAN_ID(src_ch)] << FS_DC1_SRC_SEL_OFFSET;
  173536. + break;
  173537. + case MEM_BG_SYNC:
  173538. + fs_disp_flow1 &= ~FS_DP_SYNC0_SRC_SEL_MASK;
  173539. + fs_disp_flow1 |=
  173540. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  173541. + FS_DP_SYNC0_SRC_SEL_OFFSET;
  173542. + break;
  173543. + case MEM_FG_SYNC:
  173544. + fs_disp_flow1 &= ~FS_DP_SYNC1_SRC_SEL_MASK;
  173545. + fs_disp_flow1 |=
  173546. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  173547. + FS_DP_SYNC1_SRC_SEL_OFFSET;
  173548. + break;
  173549. + case MEM_DC_ASYNC:
  173550. + fs_disp_flow1 &= ~FS_DC2_SRC_SEL_MASK;
  173551. + fs_disp_flow1 |=
  173552. + disp_src_sel[IPU_CHAN_ID(src_ch)] << FS_DC2_SRC_SEL_OFFSET;
  173553. + break;
  173554. + case MEM_BG_ASYNC0:
  173555. + fs_disp_flow1 &= ~FS_DP_ASYNC0_SRC_SEL_MASK;
  173556. + fs_disp_flow1 |=
  173557. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  173558. + FS_DP_ASYNC0_SRC_SEL_OFFSET;
  173559. + break;
  173560. + case MEM_FG_ASYNC0:
  173561. + fs_disp_flow1 &= ~FS_DP_ASYNC1_SRC_SEL_MASK;
  173562. + fs_disp_flow1 |=
  173563. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  173564. + FS_DP_ASYNC1_SRC_SEL_OFFSET;
  173565. + break;
  173566. + case MEM_VDI_MEM:
  173567. + fs_proc_flow1 &= ~FS_VDI_SRC_SEL_MASK;
  173568. + if (MEM_VDOA_MEM == src_ch)
  173569. + fs_proc_flow1 |= FS_VDI_SRC_SEL_VDOA;
  173570. + else {
  173571. + retval = -EINVAL;
  173572. + goto err;
  173573. + }
  173574. + break;
  173575. + default:
  173576. + retval = -EINVAL;
  173577. + goto err;
  173578. + }
  173579. +
  173580. + ipu_cm_write(ipu, fs_proc_flow1, IPU_FS_PROC_FLOW1);
  173581. + ipu_cm_write(ipu, fs_proc_flow2, IPU_FS_PROC_FLOW2);
  173582. + ipu_cm_write(ipu, fs_proc_flow3, IPU_FS_PROC_FLOW3);
  173583. + ipu_cm_write(ipu, fs_disp_flow1, IPU_FS_DISP_FLOW1);
  173584. +
  173585. +err:
  173586. + mutex_unlock(&ipu->mutex_lock);
  173587. + return retval;
  173588. +}
  173589. +EXPORT_SYMBOL(ipu_link_channels);
  173590. +
  173591. +/*!
  173592. + * This function unlinks 2 channels and disables automatic frame
  173593. + * synchronization.
  173594. + *
  173595. + * @param ipu ipu handler
  173596. + * @param src_ch Input parameter for the logical channel ID of
  173597. + * the source channel.
  173598. + *
  173599. + * @param dest_ch Input parameter for the logical channel ID of
  173600. + * the destination channel.
  173601. + *
  173602. + * @return This function returns 0 on success or negative error code on
  173603. + * fail.
  173604. + */
  173605. +int32_t ipu_unlink_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch)
  173606. +{
  173607. + int retval = 0;
  173608. + uint32_t fs_proc_flow1;
  173609. + uint32_t fs_proc_flow2;
  173610. + uint32_t fs_proc_flow3;
  173611. + uint32_t fs_disp_flow1;
  173612. +
  173613. + mutex_lock(&ipu->mutex_lock);
  173614. +
  173615. + fs_proc_flow1 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  173616. + fs_proc_flow2 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW2);
  173617. + fs_proc_flow3 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW3);
  173618. + fs_disp_flow1 = ipu_cm_read(ipu, IPU_FS_DISP_FLOW1);
  173619. +
  173620. + switch (src_ch) {
  173621. + case CSI_MEM0:
  173622. + fs_proc_flow3 &= ~FS_SMFC0_DEST_SEL_MASK;
  173623. + break;
  173624. + case CSI_MEM1:
  173625. + fs_proc_flow3 &= ~FS_SMFC1_DEST_SEL_MASK;
  173626. + break;
  173627. + case CSI_MEM2:
  173628. + fs_proc_flow3 &= ~FS_SMFC2_DEST_SEL_MASK;
  173629. + break;
  173630. + case CSI_MEM3:
  173631. + fs_proc_flow3 &= ~FS_SMFC3_DEST_SEL_MASK;
  173632. + break;
  173633. + case CSI_PRP_ENC_MEM:
  173634. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  173635. + break;
  173636. + case CSI_PRP_VF_MEM:
  173637. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173638. + break;
  173639. + case MEM_PP_MEM:
  173640. + fs_proc_flow2 &= ~FS_PP_DEST_SEL_MASK;
  173641. + break;
  173642. + case MEM_ROT_PP_MEM:
  173643. + fs_proc_flow2 &= ~FS_PP_ROT_DEST_SEL_MASK;
  173644. + break;
  173645. + case MEM_PRP_ENC_MEM:
  173646. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  173647. + break;
  173648. + case MEM_ROT_ENC_MEM:
  173649. + fs_proc_flow2 &= ~FS_PRPENC_ROT_DEST_SEL_MASK;
  173650. + break;
  173651. + case MEM_PRP_VF_MEM:
  173652. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173653. + break;
  173654. + case MEM_VDI_PRP_VF_MEM:
  173655. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  173656. + break;
  173657. + case MEM_ROT_VF_MEM:
  173658. + fs_proc_flow2 &= ~FS_PRPVF_ROT_DEST_SEL_MASK;
  173659. + break;
  173660. + case MEM_VDOA_MEM:
  173661. + fs_proc_flow3 &= ~FS_VDOA_DEST_SEL_MASK;
  173662. + break;
  173663. + default:
  173664. + retval = -EINVAL;
  173665. + goto err;
  173666. + }
  173667. +
  173668. + switch (dest_ch) {
  173669. + case MEM_PP_MEM:
  173670. + fs_proc_flow1 &= ~FS_PP_SRC_SEL_MASK;
  173671. + break;
  173672. + case MEM_ROT_PP_MEM:
  173673. + fs_proc_flow1 &= ~FS_PP_ROT_SRC_SEL_MASK;
  173674. + break;
  173675. + case MEM_PRP_ENC_MEM:
  173676. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173677. + break;
  173678. + case MEM_ROT_ENC_MEM:
  173679. + fs_proc_flow1 &= ~FS_PRPENC_ROT_SRC_SEL_MASK;
  173680. + break;
  173681. + case MEM_PRP_VF_MEM:
  173682. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173683. + break;
  173684. + case MEM_VDI_PRP_VF_MEM:
  173685. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  173686. + break;
  173687. + case MEM_ROT_VF_MEM:
  173688. + fs_proc_flow1 &= ~FS_PRPVF_ROT_SRC_SEL_MASK;
  173689. + break;
  173690. + case MEM_DC_SYNC:
  173691. + fs_disp_flow1 &= ~FS_DC1_SRC_SEL_MASK;
  173692. + break;
  173693. + case MEM_BG_SYNC:
  173694. + fs_disp_flow1 &= ~FS_DP_SYNC0_SRC_SEL_MASK;
  173695. + break;
  173696. + case MEM_FG_SYNC:
  173697. + fs_disp_flow1 &= ~FS_DP_SYNC1_SRC_SEL_MASK;
  173698. + break;
  173699. + case MEM_DC_ASYNC:
  173700. + fs_disp_flow1 &= ~FS_DC2_SRC_SEL_MASK;
  173701. + break;
  173702. + case MEM_BG_ASYNC0:
  173703. + fs_disp_flow1 &= ~FS_DP_ASYNC0_SRC_SEL_MASK;
  173704. + break;
  173705. + case MEM_FG_ASYNC0:
  173706. + fs_disp_flow1 &= ~FS_DP_ASYNC1_SRC_SEL_MASK;
  173707. + break;
  173708. + case MEM_VDI_MEM:
  173709. + fs_proc_flow1 &= ~FS_VDI_SRC_SEL_MASK;
  173710. + break;
  173711. + default:
  173712. + retval = -EINVAL;
  173713. + goto err;
  173714. + }
  173715. +
  173716. + ipu_cm_write(ipu, fs_proc_flow1, IPU_FS_PROC_FLOW1);
  173717. + ipu_cm_write(ipu, fs_proc_flow2, IPU_FS_PROC_FLOW2);
  173718. + ipu_cm_write(ipu, fs_proc_flow3, IPU_FS_PROC_FLOW3);
  173719. + ipu_cm_write(ipu, fs_disp_flow1, IPU_FS_DISP_FLOW1);
  173720. +
  173721. +err:
  173722. + mutex_unlock(&ipu->mutex_lock);
  173723. + return retval;
  173724. +}
  173725. +EXPORT_SYMBOL(ipu_unlink_channels);
  173726. +
  173727. +/*!
  173728. + * This function check whether a logical channel was enabled.
  173729. + *
  173730. + * @param ipu ipu handler
  173731. + * @param channel Input parameter for the logical channel ID.
  173732. + *
  173733. + * @return This function returns 1 while request channel is enabled or
  173734. + * 0 for not enabled.
  173735. + */
  173736. +int32_t ipu_is_channel_busy(struct ipu_soc *ipu, ipu_channel_t channel)
  173737. +{
  173738. + uint32_t reg;
  173739. + uint32_t in_dma;
  173740. + uint32_t out_dma;
  173741. +
  173742. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  173743. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  173744. +
  173745. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
  173746. + if (reg & idma_mask(in_dma))
  173747. + return 1;
  173748. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
  173749. + if (reg & idma_mask(out_dma))
  173750. + return 1;
  173751. + return 0;
  173752. +}
  173753. +EXPORT_SYMBOL(ipu_is_channel_busy);
  173754. +
  173755. +/*!
  173756. + * This function enables a logical channel.
  173757. + *
  173758. + * @param ipu ipu handler
  173759. + * @param channel Input parameter for the logical channel ID.
  173760. + *
  173761. + * @return This function returns 0 on success or negative error code on
  173762. + * fail.
  173763. + */
  173764. +int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel)
  173765. +{
  173766. + uint32_t reg;
  173767. + uint32_t ipu_conf;
  173768. + uint32_t in_dma;
  173769. + uint32_t out_dma;
  173770. + uint32_t sec_dma;
  173771. + uint32_t thrd_dma;
  173772. +
  173773. + mutex_lock(&ipu->mutex_lock);
  173774. +
  173775. + if (ipu->channel_enable_mask & (1L << IPU_CHAN_ID(channel))) {
  173776. + dev_err(ipu->dev, "Warning: channel already enabled %d\n",
  173777. + IPU_CHAN_ID(channel));
  173778. + mutex_unlock(&ipu->mutex_lock);
  173779. + return -EACCES;
  173780. + }
  173781. +
  173782. + /* Get input and output dma channels */
  173783. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  173784. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  173785. +
  173786. + ipu_conf = ipu_cm_read(ipu, IPU_CONF);
  173787. + if (ipu->di_use_count[0] > 0) {
  173788. + ipu_conf |= IPU_CONF_DI0_EN;
  173789. + }
  173790. + if (ipu->di_use_count[1] > 0) {
  173791. + ipu_conf |= IPU_CONF_DI1_EN;
  173792. + }
  173793. + if (ipu->dp_use_count > 0)
  173794. + ipu_conf |= IPU_CONF_DP_EN;
  173795. + if (ipu->dc_use_count > 0)
  173796. + ipu_conf |= IPU_CONF_DC_EN;
  173797. + if (ipu->dmfc_use_count > 0)
  173798. + ipu_conf |= IPU_CONF_DMFC_EN;
  173799. + if (ipu->ic_use_count > 0)
  173800. + ipu_conf |= IPU_CONF_IC_EN;
  173801. + if (ipu->vdi_use_count > 0) {
  173802. + ipu_conf |= IPU_CONF_ISP_EN;
  173803. + ipu_conf |= IPU_CONF_VDI_EN;
  173804. + ipu_conf |= IPU_CONF_IC_INPUT;
  173805. + }
  173806. + if (ipu->rot_use_count > 0)
  173807. + ipu_conf |= IPU_CONF_ROT_EN;
  173808. + if (ipu->smfc_use_count > 0)
  173809. + ipu_conf |= IPU_CONF_SMFC_EN;
  173810. + ipu_cm_write(ipu, ipu_conf, IPU_CONF);
  173811. +
  173812. + if (idma_is_valid(in_dma)) {
  173813. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
  173814. + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
  173815. + }
  173816. + if (idma_is_valid(out_dma)) {
  173817. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
  173818. + ipu_idmac_write(ipu, reg | idma_mask(out_dma), IDMAC_CHA_EN(out_dma));
  173819. + }
  173820. +
  173821. + if ((ipu->sec_chan_en[IPU_CHAN_ID(channel)]) &&
  173822. + ((channel == MEM_PP_MEM) || (channel == MEM_PRP_VF_MEM) ||
  173823. + (channel == MEM_VDI_PRP_VF_MEM))) {
  173824. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  173825. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(sec_dma));
  173826. + ipu_idmac_write(ipu, reg | idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma));
  173827. + }
  173828. + if ((ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) &&
  173829. + ((channel == MEM_PP_MEM) || (channel == MEM_PRP_VF_MEM))) {
  173830. + thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
  173831. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
  173832. + ipu_idmac_write(ipu, reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
  173833. +
  173834. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  173835. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  173836. + ipu_idmac_write(ipu, reg | idma_mask(sec_dma), IDMAC_SEP_ALPHA);
  173837. + } else if ((ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) &&
  173838. + ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC))) {
  173839. + thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
  173840. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
  173841. + ipu_idmac_write(ipu, reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
  173842. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  173843. + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_SEP_ALPHA);
  173844. + }
  173845. +
  173846. + if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_SYNC) ||
  173847. + (channel == MEM_FG_SYNC)) {
  173848. + reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma));
  173849. + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_WM_EN(in_dma));
  173850. +
  173851. + _ipu_dp_dc_enable(ipu, channel);
  173852. + }
  173853. +
  173854. + if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
  173855. + _ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma) ||
  173856. + _ipu_is_vdi_out_chan(out_dma))
  173857. + _ipu_ic_enable_task(ipu, channel);
  173858. +
  173859. + ipu->channel_enable_mask |= 1L << IPU_CHAN_ID(channel);
  173860. +
  173861. + mutex_unlock(&ipu->mutex_lock);
  173862. +
  173863. + return 0;
  173864. +}
  173865. +EXPORT_SYMBOL(ipu_enable_channel);
  173866. +
  173867. +/*!
  173868. + * This function check buffer ready for a logical channel.
  173869. + *
  173870. + * @param ipu ipu handler
  173871. + * @param channel Input parameter for the logical channel ID.
  173872. + *
  173873. + * @param type Input parameter which buffer to clear.
  173874. + *
  173875. + * @param bufNum Input parameter for which buffer number clear
  173876. + * ready state.
  173877. + *
  173878. + */
  173879. +int32_t ipu_check_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  173880. + uint32_t bufNum)
  173881. +{
  173882. + uint32_t dma_chan = channel_2_dma(channel, type);
  173883. + uint32_t reg;
  173884. + unsigned long lock_flags;
  173885. +
  173886. + if (dma_chan == IDMA_CHAN_INVALID)
  173887. + return -EINVAL;
  173888. +
  173889. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173890. + if (bufNum == 0)
  173891. + reg = ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan));
  173892. + else if (bufNum == 1)
  173893. + reg = ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan));
  173894. + else
  173895. + reg = ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan));
  173896. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173897. +
  173898. + if (reg & idma_mask(dma_chan))
  173899. + return 1;
  173900. + else
  173901. + return 0;
  173902. +}
  173903. +EXPORT_SYMBOL(ipu_check_buffer_ready);
  173904. +
  173905. +/*!
  173906. + * This function clear 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. +void _ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  173918. + uint32_t bufNum)
  173919. +{
  173920. + uint32_t dma_ch = channel_2_dma(channel, type);
  173921. +
  173922. + if (!idma_is_valid(dma_ch))
  173923. + return;
  173924. +
  173925. + ipu_cm_write(ipu, 0xF0300000, IPU_GPR); /* write one to clear */
  173926. + if (bufNum == 0)
  173927. + ipu_cm_write(ipu, idma_mask(dma_ch),
  173928. + IPU_CHA_BUF0_RDY(dma_ch));
  173929. + else if (bufNum == 1)
  173930. + ipu_cm_write(ipu, idma_mask(dma_ch),
  173931. + IPU_CHA_BUF1_RDY(dma_ch));
  173932. + else
  173933. + ipu_cm_write(ipu, idma_mask(dma_ch),
  173934. + IPU_CHA_BUF2_RDY(dma_ch));
  173935. + ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
  173936. +}
  173937. +
  173938. +void ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  173939. + uint32_t bufNum)
  173940. +{
  173941. + unsigned long lock_flags;
  173942. +
  173943. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  173944. + _ipu_clear_buffer_ready(ipu, channel, type, bufNum);
  173945. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  173946. +}
  173947. +EXPORT_SYMBOL(ipu_clear_buffer_ready);
  173948. +
  173949. +/*!
  173950. + * This function disables a logical channel.
  173951. + *
  173952. + * @param ipu ipu handler
  173953. + * @param channel Input parameter for the logical channel ID.
  173954. + *
  173955. + * @param wait_for_stop Flag to set whether to wait for channel end
  173956. + * of frame or return immediately.
  173957. + *
  173958. + * @return This function returns 0 on success or negative error code on
  173959. + * fail.
  173960. + */
  173961. +int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wait_for_stop)
  173962. +{
  173963. + uint32_t reg;
  173964. + uint32_t in_dma;
  173965. + uint32_t out_dma;
  173966. + uint32_t sec_dma = NO_DMA;
  173967. + uint32_t thrd_dma = NO_DMA;
  173968. + uint16_t fg_pos_x, fg_pos_y;
  173969. + unsigned long lock_flags;
  173970. +
  173971. + mutex_lock(&ipu->mutex_lock);
  173972. +
  173973. + if ((ipu->channel_enable_mask & (1L << IPU_CHAN_ID(channel))) == 0) {
  173974. + dev_dbg(ipu->dev, "Channel already disabled %d\n",
  173975. + IPU_CHAN_ID(channel));
  173976. + mutex_unlock(&ipu->mutex_lock);
  173977. + return -EACCES;
  173978. + }
  173979. +
  173980. + /* Get input and output dma channels */
  173981. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  173982. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  173983. +
  173984. + if ((idma_is_valid(in_dma) &&
  173985. + !idma_is_set(ipu, IDMAC_CHA_EN, in_dma))
  173986. + && (idma_is_valid(out_dma) &&
  173987. + !idma_is_set(ipu, IDMAC_CHA_EN, out_dma))) {
  173988. + mutex_unlock(&ipu->mutex_lock);
  173989. + return -EINVAL;
  173990. + }
  173991. +
  173992. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)])
  173993. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  173994. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) {
  173995. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  173996. + thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
  173997. + }
  173998. +
  173999. + if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
  174000. + (channel == MEM_DC_SYNC)) {
  174001. + if (channel == MEM_FG_SYNC) {
  174002. + _ipu_disp_get_window_pos(ipu, channel, &fg_pos_x, &fg_pos_y);
  174003. + _ipu_disp_set_window_pos(ipu, channel, 0, 0);
  174004. + }
  174005. +
  174006. + _ipu_dp_dc_disable(ipu, channel, false);
  174007. +
  174008. + /*
  174009. + * wait for BG channel EOF then disable FG-IDMAC,
  174010. + * it avoid FG NFB4EOF error.
  174011. + */
  174012. + if ((channel == MEM_FG_SYNC) && (ipu_is_channel_busy(ipu, MEM_BG_SYNC))) {
  174013. + int timeout = 50;
  174014. +
  174015. + ipu_cm_write(ipu, IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF),
  174016. + IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF));
  174017. + while ((ipu_cm_read(ipu, IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF)) &
  174018. + IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF)) == 0) {
  174019. + msleep(10);
  174020. + timeout -= 10;
  174021. + if (timeout <= 0) {
  174022. + dev_err(ipu->dev, "warning: wait for bg sync eof timeout\n");
  174023. + break;
  174024. + }
  174025. + }
  174026. + }
  174027. + } else if (wait_for_stop && !_ipu_is_smfc_chan(out_dma) &&
  174028. + channel != CSI_PRP_VF_MEM && channel != CSI_PRP_ENC_MEM) {
  174029. + while (idma_is_set(ipu, IDMAC_CHA_BUSY, in_dma) ||
  174030. + idma_is_set(ipu, IDMAC_CHA_BUSY, out_dma) ||
  174031. + (ipu->sec_chan_en[IPU_CHAN_ID(channel)] &&
  174032. + idma_is_set(ipu, IDMAC_CHA_BUSY, sec_dma)) ||
  174033. + (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] &&
  174034. + idma_is_set(ipu, IDMAC_CHA_BUSY, thrd_dma))) {
  174035. + uint32_t irq = 0xffffffff;
  174036. + int timeout = 50000;
  174037. +
  174038. + if (idma_is_set(ipu, IDMAC_CHA_BUSY, out_dma))
  174039. + irq = out_dma;
  174040. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] &&
  174041. + idma_is_set(ipu, IDMAC_CHA_BUSY, sec_dma))
  174042. + irq = sec_dma;
  174043. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] &&
  174044. + idma_is_set(ipu, IDMAC_CHA_BUSY, thrd_dma))
  174045. + irq = thrd_dma;
  174046. + if (idma_is_set(ipu, IDMAC_CHA_BUSY, in_dma))
  174047. + irq = in_dma;
  174048. +
  174049. + if (irq == 0xffffffff) {
  174050. + dev_dbg(ipu->dev, "warning: no channel busy, break\n");
  174051. + break;
  174052. + }
  174053. +
  174054. + ipu_cm_write(ipu, IPUIRQ_2_MASK(irq),
  174055. + IPUIRQ_2_STATREG(irq));
  174056. +
  174057. + dev_dbg(ipu->dev, "warning: channel %d busy, need wait\n", irq);
  174058. +
  174059. + while (((ipu_cm_read(ipu, IPUIRQ_2_STATREG(irq))
  174060. + & IPUIRQ_2_MASK(irq)) == 0) &&
  174061. + (idma_is_set(ipu, IDMAC_CHA_BUSY, irq))) {
  174062. + udelay(10);
  174063. + timeout -= 10;
  174064. + if (timeout <= 0) {
  174065. + ipu_dump_registers(ipu);
  174066. + dev_err(ipu->dev, "warning: disable ipu dma channel %d during its busy state\n", irq);
  174067. + break;
  174068. + }
  174069. + }
  174070. + dev_dbg(ipu->dev, "wait_time:%d\n", 50000 - timeout);
  174071. +
  174072. + }
  174073. + }
  174074. +
  174075. + if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
  174076. + (channel == MEM_DC_SYNC)) {
  174077. + reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma));
  174078. + ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_WM_EN(in_dma));
  174079. + }
  174080. +
  174081. + /* Disable IC task */
  174082. + if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
  174083. + _ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma) ||
  174084. + _ipu_is_vdi_out_chan(out_dma))
  174085. + _ipu_ic_disable_task(ipu, channel);
  174086. +
  174087. + /* Disable DMA channel(s) */
  174088. + if (idma_is_valid(in_dma)) {
  174089. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
  174090. + ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
  174091. + ipu_cm_write(ipu, idma_mask(in_dma), IPU_CHA_CUR_BUF(in_dma));
  174092. + ipu_cm_write(ipu, tri_cur_buf_mask(in_dma),
  174093. + IPU_CHA_TRIPLE_CUR_BUF(in_dma));
  174094. + }
  174095. + if (idma_is_valid(out_dma)) {
  174096. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
  174097. + ipu_idmac_write(ipu, reg & ~idma_mask(out_dma), IDMAC_CHA_EN(out_dma));
  174098. + ipu_cm_write(ipu, idma_mask(out_dma), IPU_CHA_CUR_BUF(out_dma));
  174099. + ipu_cm_write(ipu, tri_cur_buf_mask(out_dma),
  174100. + IPU_CHA_TRIPLE_CUR_BUF(out_dma));
  174101. + }
  174102. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) {
  174103. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(sec_dma));
  174104. + ipu_idmac_write(ipu, reg & ~idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma));
  174105. + ipu_cm_write(ipu, idma_mask(sec_dma), IPU_CHA_CUR_BUF(sec_dma));
  174106. + }
  174107. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) {
  174108. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
  174109. + ipu_idmac_write(ipu, reg & ~idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
  174110. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC) {
  174111. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  174112. + ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_SEP_ALPHA);
  174113. + } else {
  174114. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  174115. + ipu_idmac_write(ipu, reg & ~idma_mask(sec_dma), IDMAC_SEP_ALPHA);
  174116. + }
  174117. + ipu_cm_write(ipu, idma_mask(thrd_dma), IPU_CHA_CUR_BUF(thrd_dma));
  174118. + }
  174119. +
  174120. + if (channel == MEM_FG_SYNC)
  174121. + _ipu_disp_set_window_pos(ipu, channel, fg_pos_x, fg_pos_y);
  174122. +
  174123. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  174124. + /* Set channel buffers NOT to be ready */
  174125. + if (idma_is_valid(in_dma)) {
  174126. + _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 0);
  174127. + _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 1);
  174128. + _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 2);
  174129. + }
  174130. + if (idma_is_valid(out_dma)) {
  174131. + _ipu_clear_buffer_ready(ipu, channel, IPU_OUTPUT_BUFFER, 0);
  174132. + _ipu_clear_buffer_ready(ipu, channel, IPU_OUTPUT_BUFFER, 1);
  174133. + }
  174134. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) {
  174135. + _ipu_clear_buffer_ready(ipu, channel, IPU_GRAPH_IN_BUFFER, 0);
  174136. + _ipu_clear_buffer_ready(ipu, channel, IPU_GRAPH_IN_BUFFER, 1);
  174137. + }
  174138. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) {
  174139. + _ipu_clear_buffer_ready(ipu, channel, IPU_ALPHA_IN_BUFFER, 0);
  174140. + _ipu_clear_buffer_ready(ipu, channel, IPU_ALPHA_IN_BUFFER, 1);
  174141. + }
  174142. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  174143. +
  174144. + ipu->channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel));
  174145. +
  174146. + mutex_unlock(&ipu->mutex_lock);
  174147. +
  174148. + return 0;
  174149. +}
  174150. +EXPORT_SYMBOL(ipu_disable_channel);
  174151. +
  174152. +/*!
  174153. + * This function enables CSI.
  174154. + *
  174155. + * @param ipu ipu handler
  174156. + * @param csi csi num 0 or 1
  174157. + *
  174158. + * @return This function returns 0 on success or negative error code on
  174159. + * fail.
  174160. + */
  174161. +int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi)
  174162. +{
  174163. + uint32_t reg;
  174164. +
  174165. + if (csi > 1) {
  174166. + dev_err(ipu->dev, "Wrong csi num_%d\n", csi);
  174167. + return -EINVAL;
  174168. + }
  174169. +
  174170. + _ipu_get(ipu);
  174171. + mutex_lock(&ipu->mutex_lock);
  174172. + ipu->csi_use_count[csi]++;
  174173. +
  174174. + if (ipu->csi_use_count[csi] == 1) {
  174175. + reg = ipu_cm_read(ipu, IPU_CONF);
  174176. + if (csi == 0)
  174177. + ipu_cm_write(ipu, reg | IPU_CONF_CSI0_EN, IPU_CONF);
  174178. + else
  174179. + ipu_cm_write(ipu, reg | IPU_CONF_CSI1_EN, IPU_CONF);
  174180. + }
  174181. + mutex_unlock(&ipu->mutex_lock);
  174182. + _ipu_put(ipu);
  174183. + return 0;
  174184. +}
  174185. +EXPORT_SYMBOL(ipu_enable_csi);
  174186. +
  174187. +/*!
  174188. + * This function disables CSI.
  174189. + *
  174190. + * @param ipu ipu handler
  174191. + * @param csi csi num 0 or 1
  174192. + *
  174193. + * @return This function returns 0 on success or negative error code on
  174194. + * fail.
  174195. + */
  174196. +int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi)
  174197. +{
  174198. + uint32_t reg;
  174199. +
  174200. + if (csi > 1) {
  174201. + dev_err(ipu->dev, "Wrong csi num_%d\n", csi);
  174202. + return -EINVAL;
  174203. + }
  174204. + _ipu_get(ipu);
  174205. + mutex_lock(&ipu->mutex_lock);
  174206. + ipu->csi_use_count[csi]--;
  174207. + if (ipu->csi_use_count[csi] == 0) {
  174208. + _ipu_csi_wait4eof(ipu, ipu->csi_channel[csi]);
  174209. + reg = ipu_cm_read(ipu, IPU_CONF);
  174210. + if (csi == 0)
  174211. + ipu_cm_write(ipu, reg & ~IPU_CONF_CSI0_EN, IPU_CONF);
  174212. + else
  174213. + ipu_cm_write(ipu, reg & ~IPU_CONF_CSI1_EN, IPU_CONF);
  174214. + }
  174215. + mutex_unlock(&ipu->mutex_lock);
  174216. + _ipu_put(ipu);
  174217. + return 0;
  174218. +}
  174219. +EXPORT_SYMBOL(ipu_disable_csi);
  174220. +
  174221. +static irqreturn_t ipu_sync_irq_handler(int irq, void *desc)
  174222. +{
  174223. + struct ipu_soc *ipu = desc;
  174224. + int i;
  174225. + uint32_t line, bit, int_stat, int_ctrl;
  174226. + irqreturn_t result = IRQ_NONE;
  174227. + const int int_reg[] = { 1, 2, 3, 4, 11, 12, 13, 14, 15, 0 };
  174228. +
  174229. + spin_lock(&ipu->int_reg_spin_lock);
  174230. +
  174231. + for (i = 0; int_reg[i] != 0; i++) {
  174232. + int_stat = ipu_cm_read(ipu, IPU_INT_STAT(int_reg[i]));
  174233. + int_ctrl = ipu_cm_read(ipu, IPU_INT_CTRL(int_reg[i]));
  174234. + int_stat &= int_ctrl;
  174235. + ipu_cm_write(ipu, int_stat, IPU_INT_STAT(int_reg[i]));
  174236. + while ((line = ffs(int_stat)) != 0) {
  174237. + bit = --line;
  174238. + int_stat &= ~(1UL << line);
  174239. + line += (int_reg[i] - 1) * 32;
  174240. + result |=
  174241. + ipu->irq_list[line].handler(line,
  174242. + ipu->irq_list[line].
  174243. + dev_id);
  174244. + if (ipu->irq_list[line].flags & IPU_IRQF_ONESHOT) {
  174245. + int_ctrl &= ~(1UL << bit);
  174246. + ipu_cm_write(ipu, int_ctrl,
  174247. + IPU_INT_CTRL(int_reg[i]));
  174248. + }
  174249. + }
  174250. + }
  174251. +
  174252. + spin_unlock(&ipu->int_reg_spin_lock);
  174253. +
  174254. + return result;
  174255. +}
  174256. +
  174257. +static irqreturn_t ipu_err_irq_handler(int irq, void *desc)
  174258. +{
  174259. + struct ipu_soc *ipu = desc;
  174260. + int i;
  174261. + uint32_t int_stat;
  174262. + const int err_reg[] = { 5, 6, 9, 10, 0 };
  174263. +
  174264. + spin_lock(&ipu->int_reg_spin_lock);
  174265. +
  174266. + for (i = 0; err_reg[i] != 0; i++) {
  174267. + int_stat = ipu_cm_read(ipu, IPU_INT_STAT(err_reg[i]));
  174268. + int_stat &= ipu_cm_read(ipu, IPU_INT_CTRL(err_reg[i]));
  174269. + if (int_stat) {
  174270. + ipu_cm_write(ipu, int_stat, IPU_INT_STAT(err_reg[i]));
  174271. + dev_warn(ipu->dev,
  174272. + "IPU Warning - IPU_INT_STAT_%d = 0x%08X\n",
  174273. + err_reg[i], int_stat);
  174274. + /* Disable interrupts so we only get error once */
  174275. + int_stat = ipu_cm_read(ipu, IPU_INT_CTRL(err_reg[i])) &
  174276. + ~int_stat;
  174277. + ipu_cm_write(ipu, int_stat, IPU_INT_CTRL(err_reg[i]));
  174278. + }
  174279. + }
  174280. +
  174281. + spin_unlock(&ipu->int_reg_spin_lock);
  174282. +
  174283. + return IRQ_HANDLED;
  174284. +}
  174285. +
  174286. +/*!
  174287. + * This function enables the interrupt for the specified interrupt line.
  174288. + * The interrupt lines are defined in \b ipu_irq_line enum.
  174289. + *
  174290. + * @param ipu ipu handler
  174291. + * @param irq Interrupt line to enable interrupt for.
  174292. + *
  174293. + * @return This function returns 0 on success or negative error code on
  174294. + * fail.
  174295. + */
  174296. +int ipu_enable_irq(struct ipu_soc *ipu, uint32_t irq)
  174297. +{
  174298. + uint32_t reg;
  174299. + unsigned long lock_flags;
  174300. + int ret = 0;
  174301. +
  174302. + _ipu_get(ipu);
  174303. +
  174304. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174305. +
  174306. + /*
  174307. + * Check sync interrupt handler only, since we do nothing for
  174308. + * error interrupts but than print out register values in the
  174309. + * error interrupt source handler.
  174310. + */
  174311. + if (_ipu_is_sync_irq(irq) && (ipu->irq_list[irq].handler == NULL)) {
  174312. + dev_err(ipu->dev, "handler hasn't been registered on sync "
  174313. + "irq %d\n", irq);
  174314. + ret = -EACCES;
  174315. + goto out;
  174316. + }
  174317. +
  174318. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  174319. + reg |= IPUIRQ_2_MASK(irq);
  174320. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  174321. +out:
  174322. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174323. +
  174324. + _ipu_put(ipu);
  174325. +
  174326. + return ret;
  174327. +}
  174328. +EXPORT_SYMBOL(ipu_enable_irq);
  174329. +
  174330. +/*!
  174331. + * This function disables the interrupt for the specified interrupt line.
  174332. + * The interrupt lines are defined in \b ipu_irq_line enum.
  174333. + *
  174334. + * @param ipu ipu handler
  174335. + * @param irq Interrupt line to disable interrupt for.
  174336. + *
  174337. + */
  174338. +void ipu_disable_irq(struct ipu_soc *ipu, uint32_t irq)
  174339. +{
  174340. + uint32_t reg;
  174341. + unsigned long lock_flags;
  174342. +
  174343. + _ipu_get(ipu);
  174344. +
  174345. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174346. +
  174347. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  174348. + reg &= ~IPUIRQ_2_MASK(irq);
  174349. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  174350. +
  174351. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174352. +
  174353. + _ipu_put(ipu);
  174354. +}
  174355. +EXPORT_SYMBOL(ipu_disable_irq);
  174356. +
  174357. +/*!
  174358. + * This function clears the interrupt for the specified interrupt line.
  174359. + * The interrupt lines are defined in \b ipu_irq_line enum.
  174360. + *
  174361. + * @param ipu ipu handler
  174362. + * @param irq Interrupt line to clear interrupt for.
  174363. + *
  174364. + */
  174365. +void ipu_clear_irq(struct ipu_soc *ipu, uint32_t irq)
  174366. +{
  174367. + unsigned long lock_flags;
  174368. +
  174369. + _ipu_get(ipu);
  174370. +
  174371. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174372. +
  174373. + ipu_cm_write(ipu, IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq));
  174374. +
  174375. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174376. +
  174377. + _ipu_put(ipu);
  174378. +}
  174379. +EXPORT_SYMBOL(ipu_clear_irq);
  174380. +
  174381. +/*!
  174382. + * This function returns the current interrupt status for the specified
  174383. + * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum.
  174384. + *
  174385. + * @param ipu ipu handler
  174386. + * @param irq Interrupt line to get status for.
  174387. + *
  174388. + * @return Returns true if the interrupt is pending/asserted or false if
  174389. + * the interrupt is not pending.
  174390. + */
  174391. +bool ipu_get_irq_status(struct ipu_soc *ipu, uint32_t irq)
  174392. +{
  174393. + uint32_t reg;
  174394. + unsigned long lock_flags;
  174395. +
  174396. + _ipu_get(ipu);
  174397. +
  174398. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174399. + reg = ipu_cm_read(ipu, IPUIRQ_2_STATREG(irq));
  174400. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174401. +
  174402. + _ipu_put(ipu);
  174403. +
  174404. + if (reg & IPUIRQ_2_MASK(irq))
  174405. + return true;
  174406. + else
  174407. + return false;
  174408. +}
  174409. +EXPORT_SYMBOL(ipu_get_irq_status);
  174410. +
  174411. +/*!
  174412. + * This function registers an interrupt handler function for the specified
  174413. + * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum.
  174414. + *
  174415. + * @param ipu ipu handler
  174416. + * @param irq Interrupt line to get status for.
  174417. + *
  174418. + * @param handler Input parameter for address of the handler
  174419. + * function.
  174420. + *
  174421. + * @param irq_flags Flags for interrupt mode. Currently not used.
  174422. + *
  174423. + * @param devname Input parameter for string name of driver
  174424. + * registering the handler.
  174425. + *
  174426. + * @param dev_id Input parameter for pointer of data to be
  174427. + * passed to the handler.
  174428. + *
  174429. + * @return This function returns 0 on success or negative error code on
  174430. + * fail.
  174431. + */
  174432. +int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
  174433. + irqreturn_t(*handler) (int, void *),
  174434. + uint32_t irq_flags, const char *devname, void *dev_id)
  174435. +{
  174436. + uint32_t reg;
  174437. + unsigned long lock_flags;
  174438. + int ret = 0;
  174439. +
  174440. + BUG_ON(irq >= IPU_IRQ_COUNT);
  174441. +
  174442. + _ipu_get(ipu);
  174443. +
  174444. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174445. +
  174446. + if (ipu->irq_list[irq].handler != NULL) {
  174447. + dev_err(ipu->dev,
  174448. + "handler already installed on irq %d\n", irq);
  174449. + ret = -EINVAL;
  174450. + goto out;
  174451. + }
  174452. +
  174453. + /*
  174454. + * Check sync interrupt handler only, since we do nothing for
  174455. + * error interrupts but than print out register values in the
  174456. + * error interrupt source handler.
  174457. + */
  174458. + if (_ipu_is_sync_irq(irq) && (handler == NULL)) {
  174459. + dev_err(ipu->dev, "handler is NULL for sync irq %d\n", irq);
  174460. + ret = -EINVAL;
  174461. + goto out;
  174462. + }
  174463. +
  174464. + ipu->irq_list[irq].handler = handler;
  174465. + ipu->irq_list[irq].flags = irq_flags;
  174466. + ipu->irq_list[irq].dev_id = dev_id;
  174467. + ipu->irq_list[irq].name = devname;
  174468. +
  174469. + /* clear irq stat for previous use */
  174470. + ipu_cm_write(ipu, IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq));
  174471. + /* enable the interrupt */
  174472. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  174473. + reg |= IPUIRQ_2_MASK(irq);
  174474. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  174475. +out:
  174476. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174477. +
  174478. + _ipu_put(ipu);
  174479. +
  174480. + return ret;
  174481. +}
  174482. +EXPORT_SYMBOL(ipu_request_irq);
  174483. +
  174484. +/*!
  174485. + * This function unregisters an interrupt handler for the specified interrupt
  174486. + * line. The interrupt lines are defined in \b ipu_irq_line enum.
  174487. + *
  174488. + * @param ipu ipu handler
  174489. + * @param irq Interrupt line to get status for.
  174490. + *
  174491. + * @param dev_id Input parameter for pointer of data to be passed
  174492. + * to the handler. This must match value passed to
  174493. + * ipu_request_irq().
  174494. + *
  174495. + */
  174496. +void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id)
  174497. +{
  174498. + uint32_t reg;
  174499. + unsigned long lock_flags;
  174500. +
  174501. + _ipu_get(ipu);
  174502. +
  174503. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  174504. +
  174505. + /* disable the interrupt */
  174506. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  174507. + reg &= ~IPUIRQ_2_MASK(irq);
  174508. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  174509. + if (ipu->irq_list[irq].dev_id == dev_id)
  174510. + memset(&ipu->irq_list[irq], 0, sizeof(ipu->irq_list[irq]));
  174511. +
  174512. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  174513. +
  174514. + _ipu_put(ipu);
  174515. +}
  174516. +EXPORT_SYMBOL(ipu_free_irq);
  174517. +
  174518. +uint32_t ipu_get_cur_buffer_idx(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type)
  174519. +{
  174520. + uint32_t reg, dma_chan;
  174521. +
  174522. + dma_chan = channel_2_dma(channel, type);
  174523. + if (!idma_is_valid(dma_chan))
  174524. + return -EINVAL;
  174525. +
  174526. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan));
  174527. + if ((reg & idma_mask(dma_chan)) && _ipu_is_trb_chan(dma_chan)) {
  174528. + reg = ipu_cm_read(ipu, IPU_CHA_TRIPLE_CUR_BUF(dma_chan));
  174529. + return (reg & tri_cur_buf_mask(dma_chan)) >>
  174530. + tri_cur_buf_shift(dma_chan);
  174531. + } else {
  174532. + reg = ipu_cm_read(ipu, IPU_CHA_CUR_BUF(dma_chan));
  174533. + if (reg & idma_mask(dma_chan))
  174534. + return 1;
  174535. + else
  174536. + return 0;
  174537. + }
  174538. +}
  174539. +EXPORT_SYMBOL(ipu_get_cur_buffer_idx);
  174540. +
  174541. +uint32_t _ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel)
  174542. +{
  174543. + uint32_t stat = 0;
  174544. + uint32_t task_stat_reg = ipu_cm_read(ipu, IPU_PROC_TASK_STAT);
  174545. +
  174546. + switch (channel) {
  174547. + case MEM_PRP_VF_MEM:
  174548. + stat = (task_stat_reg & TSTAT_VF_MASK) >> TSTAT_VF_OFFSET;
  174549. + break;
  174550. + case MEM_VDI_PRP_VF_MEM:
  174551. + stat = (task_stat_reg & TSTAT_VF_MASK) >> TSTAT_VF_OFFSET;
  174552. + break;
  174553. + case MEM_ROT_VF_MEM:
  174554. + stat =
  174555. + (task_stat_reg & TSTAT_VF_ROT_MASK) >> TSTAT_VF_ROT_OFFSET;
  174556. + break;
  174557. + case MEM_PRP_ENC_MEM:
  174558. + stat = (task_stat_reg & TSTAT_ENC_MASK) >> TSTAT_ENC_OFFSET;
  174559. + break;
  174560. + case MEM_ROT_ENC_MEM:
  174561. + stat =
  174562. + (task_stat_reg & TSTAT_ENC_ROT_MASK) >>
  174563. + TSTAT_ENC_ROT_OFFSET;
  174564. + break;
  174565. + case MEM_PP_MEM:
  174566. + stat = (task_stat_reg & TSTAT_PP_MASK) >> TSTAT_PP_OFFSET;
  174567. + break;
  174568. + case MEM_ROT_PP_MEM:
  174569. + stat =
  174570. + (task_stat_reg & TSTAT_PP_ROT_MASK) >> TSTAT_PP_ROT_OFFSET;
  174571. + break;
  174572. +
  174573. + default:
  174574. + stat = TASK_STAT_IDLE;
  174575. + break;
  174576. + }
  174577. + return stat;
  174578. +}
  174579. +
  174580. +/*!
  174581. + * This function check for a logical channel status
  174582. + *
  174583. + * @param ipu ipu handler
  174584. + * @param channel Input parameter for the logical channel ID.
  174585. + *
  174586. + * @return This function returns 0 on idle and 1 on busy.
  174587. + *
  174588. + */
  174589. +uint32_t ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel)
  174590. +{
  174591. + uint32_t dma_status;
  174592. +
  174593. + _ipu_get(ipu);
  174594. + mutex_lock(&ipu->mutex_lock);
  174595. + dma_status = ipu_is_channel_busy(ipu, channel);
  174596. + mutex_unlock(&ipu->mutex_lock);
  174597. + _ipu_put(ipu);
  174598. +
  174599. + dev_dbg(ipu->dev, "%s, dma_status:%d.\n", __func__, dma_status);
  174600. +
  174601. + return dma_status;
  174602. +}
  174603. +EXPORT_SYMBOL(ipu_channel_status);
  174604. +
  174605. +int32_t ipu_swap_channel(struct ipu_soc *ipu, ipu_channel_t from_ch, ipu_channel_t to_ch)
  174606. +{
  174607. + uint32_t reg;
  174608. + unsigned long lock_flags;
  174609. + int from_dma = channel_2_dma(from_ch, IPU_INPUT_BUFFER);
  174610. + int to_dma = channel_2_dma(to_ch, IPU_INPUT_BUFFER);
  174611. +
  174612. + mutex_lock(&ipu->mutex_lock);
  174613. +
  174614. + /* enable target channel */
  174615. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(to_dma));
  174616. + ipu_idmac_write(ipu, reg | idma_mask(to_dma), IDMAC_CHA_EN(to_dma));
  174617. +
  174618. + ipu->channel_enable_mask |= 1L << IPU_CHAN_ID(to_ch);
  174619. +
  174620. + /* switch dp dc */
  174621. + _ipu_dp_dc_disable(ipu, from_ch, true);
  174622. +
  174623. + /* disable source channel */
  174624. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(from_dma));
  174625. + ipu_idmac_write(ipu, reg & ~idma_mask(from_dma), IDMAC_CHA_EN(from_dma));
  174626. + ipu_cm_write(ipu, idma_mask(from_dma), IPU_CHA_CUR_BUF(from_dma));
  174627. + ipu_cm_write(ipu, tri_cur_buf_mask(from_dma),
  174628. + IPU_CHA_TRIPLE_CUR_BUF(from_dma));
  174629. +
  174630. + ipu->channel_enable_mask &= ~(1L << IPU_CHAN_ID(from_ch));
  174631. +
  174632. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  174633. + _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 0);
  174634. + _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 1);
  174635. + _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 2);
  174636. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  174637. +
  174638. + mutex_unlock(&ipu->mutex_lock);
  174639. +
  174640. + return 0;
  174641. +}
  174642. +EXPORT_SYMBOL(ipu_swap_channel);
  174643. +
  174644. +uint32_t bytes_per_pixel(uint32_t fmt)
  174645. +{
  174646. + switch (fmt) {
  174647. + case IPU_PIX_FMT_GENERIC: /*generic data */
  174648. + case IPU_PIX_FMT_RGB332:
  174649. + case IPU_PIX_FMT_YUV420P:
  174650. + case IPU_PIX_FMT_YVU420P:
  174651. + case IPU_PIX_FMT_YUV422P:
  174652. + case IPU_PIX_FMT_YUV444P:
  174653. + return 1;
  174654. + break;
  174655. + case IPU_PIX_FMT_GENERIC_16: /* generic data */
  174656. + case IPU_PIX_FMT_RGB565:
  174657. + case IPU_PIX_FMT_YUYV:
  174658. + case IPU_PIX_FMT_UYVY:
  174659. + return 2;
  174660. + break;
  174661. + case IPU_PIX_FMT_BGR24:
  174662. + case IPU_PIX_FMT_RGB24:
  174663. + case IPU_PIX_FMT_YUV444:
  174664. + return 3;
  174665. + break;
  174666. + case IPU_PIX_FMT_GENERIC_32: /*generic data */
  174667. + case IPU_PIX_FMT_BGR32:
  174668. + case IPU_PIX_FMT_BGRA32:
  174669. + case IPU_PIX_FMT_RGB32:
  174670. + case IPU_PIX_FMT_RGBA32:
  174671. + case IPU_PIX_FMT_ABGR32:
  174672. + return 4;
  174673. + break;
  174674. + default:
  174675. + return 1;
  174676. + break;
  174677. + }
  174678. + return 0;
  174679. +}
  174680. +EXPORT_SYMBOL(bytes_per_pixel);
  174681. +
  174682. +ipu_color_space_t format_to_colorspace(uint32_t fmt)
  174683. +{
  174684. + switch (fmt) {
  174685. + case IPU_PIX_FMT_RGB666:
  174686. + case IPU_PIX_FMT_RGB565:
  174687. + case IPU_PIX_FMT_BGR24:
  174688. + case IPU_PIX_FMT_RGB24:
  174689. + case IPU_PIX_FMT_GBR24:
  174690. + case IPU_PIX_FMT_BGR32:
  174691. + case IPU_PIX_FMT_BGRA32:
  174692. + case IPU_PIX_FMT_RGB32:
  174693. + case IPU_PIX_FMT_RGBA32:
  174694. + case IPU_PIX_FMT_ABGR32:
  174695. + case IPU_PIX_FMT_LVDS666:
  174696. + case IPU_PIX_FMT_LVDS888:
  174697. + return RGB;
  174698. + break;
  174699. +
  174700. + default:
  174701. + return YCbCr;
  174702. + break;
  174703. + }
  174704. + return RGB;
  174705. +}
  174706. +
  174707. +bool ipu_pixel_format_has_alpha(uint32_t fmt)
  174708. +{
  174709. + switch (fmt) {
  174710. + case IPU_PIX_FMT_RGBA32:
  174711. + case IPU_PIX_FMT_BGRA32:
  174712. + case IPU_PIX_FMT_ABGR32:
  174713. + return true;
  174714. + break;
  174715. + default:
  174716. + return false;
  174717. + break;
  174718. + }
  174719. + return false;
  174720. +}
  174721. +
  174722. +bool ipu_ch_param_bad_alpha_pos(uint32_t pixel_fmt)
  174723. +{
  174724. + return _ipu_ch_param_bad_alpha_pos(pixel_fmt);
  174725. +}
  174726. +EXPORT_SYMBOL(ipu_ch_param_bad_alpha_pos);
  174727. +
  174728. +#ifdef CONFIG_PM
  174729. +static int ipu_suspend(struct device *dev)
  174730. +{
  174731. + struct ipu_soc *ipu = dev_get_drvdata(dev);
  174732. +
  174733. + /* All IDMAC channel and IPU clock should be disabled.*/
  174734. + if (ipu->pdata->pg)
  174735. + ipu->pdata->pg(1);
  174736. +
  174737. + dev_dbg(dev, "ipu suspend.\n");
  174738. + return 0;
  174739. +}
  174740. +
  174741. +static int ipu_resume(struct device *dev)
  174742. +{
  174743. + struct ipu_soc *ipu = dev_get_drvdata(dev);
  174744. +
  174745. + if (ipu->pdata->pg) {
  174746. + ipu->pdata->pg(0);
  174747. +
  174748. + _ipu_get(ipu);
  174749. + _ipu_dmfc_init(ipu, dmfc_type_setup, 1);
  174750. + /* Set sync refresh channels as high priority */
  174751. + ipu_idmac_write(ipu, 0x18800001L, IDMAC_CHA_PRI(0));
  174752. + _ipu_put(ipu);
  174753. + }
  174754. + dev_dbg(dev, "ipu resume.\n");
  174755. + return 0;
  174756. +}
  174757. +
  174758. +int ipu_runtime_suspend(struct device *dev)
  174759. +{
  174760. + release_bus_freq(BUS_FREQ_HIGH);
  174761. + dev_dbg(dev, "ipu busfreq high release.\n");
  174762. +
  174763. + return 0;
  174764. +}
  174765. +
  174766. +int ipu_runtime_resume(struct device *dev)
  174767. +{
  174768. + request_bus_freq(BUS_FREQ_HIGH);
  174769. + dev_dbg(dev, "ipu busfreq high requst.\n");
  174770. +
  174771. + return 0;
  174772. +}
  174773. +
  174774. +static const struct dev_pm_ops ipu_pm_ops = {
  174775. + SET_RUNTIME_PM_OPS(ipu_runtime_suspend, ipu_runtime_resume, NULL)
  174776. + SET_SYSTEM_SLEEP_PM_OPS(ipu_suspend, ipu_resume)
  174777. +};
  174778. +#endif
  174779. +
  174780. +/*!
  174781. + * This structure contains pointers to the power management callback functions.
  174782. + */
  174783. +static struct platform_driver mxcipu_driver = {
  174784. + .driver = {
  174785. + .name = "imx-ipuv3",
  174786. + .of_match_table = imx_ipuv3_dt_ids,
  174787. + #ifdef CONFIG_PM
  174788. + .pm = &ipu_pm_ops,
  174789. + #endif
  174790. + },
  174791. + .probe = ipu_probe,
  174792. + .id_table = imx_ipu_type,
  174793. + .remove = ipu_remove,
  174794. +};
  174795. +
  174796. +int32_t __init ipu_gen_init(void)
  174797. +{
  174798. + int32_t ret;
  174799. +
  174800. + ret = platform_driver_register(&mxcipu_driver);
  174801. + return 0;
  174802. +}
  174803. +
  174804. +subsys_initcall(ipu_gen_init);
  174805. +
  174806. +static void __exit ipu_gen_uninit(void)
  174807. +{
  174808. + platform_driver_unregister(&mxcipu_driver);
  174809. +}
  174810. +
  174811. +module_exit(ipu_gen_uninit);
  174812. diff -Nur linux-3.14.14/drivers/mxc/ipu3/ipu_device.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_device.c
  174813. --- linux-3.14.14/drivers/mxc/ipu3/ipu_device.c 1969-12-31 18:00:00.000000000 -0600
  174814. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_device.c 2014-12-08 00:31:53.476418001 -0600
  174815. @@ -0,0 +1,3717 @@
  174816. +/*
  174817. + * Copyright 2005-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  174818. + */
  174819. +
  174820. +/*
  174821. + * The code contained herein is licensed under the GNU General Public
  174822. + * License. You may obtain a copy of the GNU General Public License
  174823. + * Version 2 or later at the following locations:
  174824. + *
  174825. + * http://www.opensource.org/licenses/gpl-license.html
  174826. + * http://www.gnu.org/copyleft/gpl.html
  174827. + */
  174828. +
  174829. +/*!
  174830. + * @file ipu_device.c
  174831. + *
  174832. + * @brief This file contains the IPUv3 driver device interface and fops functions.
  174833. + *
  174834. + * @ingroup IPU
  174835. + */
  174836. +#include <linux/clk.h>
  174837. +#include <linux/cpumask.h>
  174838. +#include <linux/delay.h>
  174839. +#include <linux/dma-mapping.h>
  174840. +#include <linux/err.h>
  174841. +#include <linux/init.h>
  174842. +#include <linux/io.h>
  174843. +#include <linux/ipu-v3.h>
  174844. +#include <linux/kernel.h>
  174845. +#include <linux/kthread.h>
  174846. +#include <linux/module.h>
  174847. +#include <linux/platform_device.h>
  174848. +#include <linux/poll.h>
  174849. +#include <linux/sched.h>
  174850. +#include <linux/sched/rt.h>
  174851. +#include <linux/slab.h>
  174852. +#include <linux/spinlock.h>
  174853. +#include <linux/time.h>
  174854. +#include <linux/types.h>
  174855. +#include <linux/vmalloc.h>
  174856. +#include <linux/wait.h>
  174857. +
  174858. +#include <asm/cacheflush.h>
  174859. +#include <asm/outercache.h>
  174860. +
  174861. +#include "ipu_param_mem.h"
  174862. +#include "ipu_regs.h"
  174863. +#include "vdoa.h"
  174864. +
  174865. +#define CHECK_RETCODE(cont, str, err, label, ret) \
  174866. +do { \
  174867. + if (cont) { \
  174868. + dev_err(t->dev, "ERR:[0x%p]-no:0x%x "#str" ret:%d," \
  174869. + "line:%d\n", t, t->task_no, ret, __LINE__);\
  174870. + if (ret != -EACCES) { \
  174871. + t->state = err; \
  174872. + goto label; \
  174873. + } \
  174874. + } \
  174875. +} while (0)
  174876. +
  174877. +#define CHECK_RETCODE_CONT(cont, str, err, ret) \
  174878. +do { \
  174879. + if (cont) { \
  174880. + dev_err(t->dev, "ERR:[0x%p]-no:0x%x"#str" ret:%d," \
  174881. + "line:%d\n", t, t->task_no, ret, __LINE__);\
  174882. + if (ret != -EACCES) { \
  174883. + if (t->state == STATE_OK) \
  174884. + t->state = err; \
  174885. + } \
  174886. + } \
  174887. +} while (0)
  174888. +
  174889. +#undef DBG_IPU_PERF
  174890. +#ifdef DBG_IPU_PERF
  174891. +#define CHECK_PERF(ts) \
  174892. +do { \
  174893. + getnstimeofday(ts); \
  174894. +} while (0)
  174895. +
  174896. +#define DECLARE_PERF_VAR \
  174897. + struct timespec ts_queue; \
  174898. + struct timespec ts_dotask; \
  174899. + struct timespec ts_waitirq; \
  174900. + struct timespec ts_sche; \
  174901. + struct timespec ts_rel; \
  174902. + struct timespec ts_frame
  174903. +
  174904. +#define PRINT_TASK_STATISTICS \
  174905. +do { \
  174906. + ts_queue = timespec_sub(tsk->ts_dotask, tsk->ts_queue); \
  174907. + ts_dotask = timespec_sub(tsk->ts_waitirq, tsk->ts_dotask); \
  174908. + ts_waitirq = timespec_sub(tsk->ts_inirq, tsk->ts_waitirq); \
  174909. + ts_sche = timespec_sub(tsk->ts_wakeup, tsk->ts_inirq); \
  174910. + ts_rel = timespec_sub(tsk->ts_rel, tsk->ts_wakeup); \
  174911. + ts_frame = timespec_sub(tsk->ts_rel, tsk->ts_queue); \
  174912. + dev_dbg(tsk->dev, "[0x%p] no-0x%x, ts_q:%ldus, ts_do:%ldus," \
  174913. + "ts_waitirq:%ldus,ts_sche:%ldus, ts_rel:%ldus," \
  174914. + "ts_frame: %ldus\n", tsk, tsk->task_no, \
  174915. + ts_queue.tv_nsec / NSEC_PER_USEC + ts_queue.tv_sec * USEC_PER_SEC,\
  174916. + ts_dotask.tv_nsec / NSEC_PER_USEC + ts_dotask.tv_sec * USEC_PER_SEC,\
  174917. + ts_waitirq.tv_nsec / NSEC_PER_USEC + ts_waitirq.tv_sec * USEC_PER_SEC,\
  174918. + ts_sche.tv_nsec / NSEC_PER_USEC + ts_sche.tv_sec * USEC_PER_SEC,\
  174919. + ts_rel.tv_nsec / NSEC_PER_USEC + ts_rel.tv_sec * USEC_PER_SEC,\
  174920. + ts_frame.tv_nsec / NSEC_PER_USEC + ts_frame.tv_sec * USEC_PER_SEC); \
  174921. + if ((ts_frame.tv_nsec/NSEC_PER_USEC + ts_frame.tv_sec*USEC_PER_SEC) > \
  174922. + 80000) \
  174923. + dev_dbg(tsk->dev, "ts_frame larger than 80ms [0x%p] no-0x%x.\n"\
  174924. + , tsk, tsk->task_no); \
  174925. +} while (0)
  174926. +#else
  174927. +#define CHECK_PERF(ts)
  174928. +#define DECLARE_PERF_VAR
  174929. +#define PRINT_TASK_STATISTICS
  174930. +#endif
  174931. +
  174932. +#define IPU_PP_CH_VF (IPU_TASK_ID_VF - 1)
  174933. +#define IPU_PP_CH_PP (IPU_TASK_ID_PP - 1)
  174934. +#define MAX_PP_CH (IPU_TASK_ID_MAX - 1)
  174935. +#define VDOA_DEF_TIMEOUT_MS (HZ/2)
  174936. +
  174937. +/* Strucutures and variables for exporting MXC IPU as device*/
  174938. +typedef enum {
  174939. + STATE_OK = 0,
  174940. + STATE_QUEUE,
  174941. + STATE_IN_PROGRESS,
  174942. + STATE_ERR,
  174943. + STATE_TIMEOUT,
  174944. + STATE_RES_TIMEOUT,
  174945. + STATE_NO_IPU,
  174946. + STATE_NO_IRQ,
  174947. + STATE_IPU_BUSY,
  174948. + STATE_IRQ_FAIL,
  174949. + STATE_IRQ_TIMEOUT,
  174950. + STATE_ENABLE_CHAN_FAIL,
  174951. + STATE_DISABLE_CHAN_FAIL,
  174952. + STATE_SEL_BUF_FAIL,
  174953. + STATE_INIT_CHAN_FAIL,
  174954. + STATE_LINK_CHAN_FAIL,
  174955. + STATE_UNLINK_CHAN_FAIL,
  174956. + STATE_INIT_CHAN_BUF_FAIL,
  174957. + STATE_INIT_CHAN_BAND_FAIL,
  174958. + STATE_SYS_NO_MEM,
  174959. + STATE_VDOA_IRQ_TIMEOUT,
  174960. + STATE_VDOA_IRQ_FAIL,
  174961. + STATE_VDOA_TASK_FAIL,
  174962. +} ipu_state_t;
  174963. +
  174964. +enum {
  174965. + INPUT_CHAN_VDI_P = 1,
  174966. + INPUT_CHAN,
  174967. + INPUT_CHAN_VDI_N,
  174968. +};
  174969. +
  174970. +struct ipu_state_msg {
  174971. + int state;
  174972. + char *msg;
  174973. +} state_msg[] = {
  174974. + {STATE_OK, "ok"},
  174975. + {STATE_QUEUE, "split queue"},
  174976. + {STATE_IN_PROGRESS, "split in progress"},
  174977. + {STATE_ERR, "error"},
  174978. + {STATE_TIMEOUT, "split task timeout"},
  174979. + {STATE_RES_TIMEOUT, "wait resource timeout"},
  174980. + {STATE_NO_IPU, "no ipu found"},
  174981. + {STATE_NO_IRQ, "no irq found for task"},
  174982. + {STATE_IPU_BUSY, "ipu busy"},
  174983. + {STATE_IRQ_FAIL, "request irq failed"},
  174984. + {STATE_IRQ_TIMEOUT, "wait for irq timeout"},
  174985. + {STATE_ENABLE_CHAN_FAIL, "ipu enable channel fail"},
  174986. + {STATE_DISABLE_CHAN_FAIL, "ipu disable channel fail"},
  174987. + {STATE_SEL_BUF_FAIL, "ipu select buf fail"},
  174988. + {STATE_INIT_CHAN_FAIL, "ipu init channel fail"},
  174989. + {STATE_LINK_CHAN_FAIL, "ipu link channel fail"},
  174990. + {STATE_UNLINK_CHAN_FAIL, "ipu unlink channel fail"},
  174991. + {STATE_INIT_CHAN_BUF_FAIL, "ipu init channel buffer fail"},
  174992. + {STATE_INIT_CHAN_BAND_FAIL, "ipu init channel band mode fail"},
  174993. + {STATE_SYS_NO_MEM, "sys no mem: -ENOMEM"},
  174994. + {STATE_VDOA_IRQ_TIMEOUT, "wait for vdoa irq timeout"},
  174995. + {STATE_VDOA_IRQ_FAIL, "vdoa irq fail"},
  174996. + {STATE_VDOA_TASK_FAIL, "vdoa task fail"},
  174997. +};
  174998. +
  174999. +struct stripe_setting {
  175000. + u32 iw;
  175001. + u32 ih;
  175002. + u32 ow;
  175003. + u32 oh;
  175004. + u32 outh_resize_ratio;
  175005. + u32 outv_resize_ratio;
  175006. + u32 i_left_pos;
  175007. + u32 i_right_pos;
  175008. + u32 i_top_pos;
  175009. + u32 i_bottom_pos;
  175010. + u32 o_left_pos;
  175011. + u32 o_right_pos;
  175012. + u32 o_top_pos;
  175013. + u32 o_bottom_pos;
  175014. + u32 rl_split_line;
  175015. + u32 ud_split_line;
  175016. +};
  175017. +
  175018. +struct task_set {
  175019. +#define NULL_MODE 0x0
  175020. +#define IC_MODE 0x1
  175021. +#define ROT_MODE 0x2
  175022. +#define VDI_MODE 0x4
  175023. +#define IPU_PREPROCESS_MODE_MASK (IC_MODE | ROT_MODE | VDI_MODE)
  175024. +/* VDOA_MODE means this task use vdoa, and VDOA has two modes:
  175025. + * BAND MODE and non-BAND MODE. Non-band mode will do transfer data
  175026. + * to memory. BAND mode needs hareware sync with IPU, it is used default
  175027. + * if connected to VDIC.
  175028. + */
  175029. +#define VDOA_MODE 0x8
  175030. +#define VDOA_BAND_MODE 0x10
  175031. + u8 mode;
  175032. +#define IC_VF 0x1
  175033. +#define IC_PP 0x2
  175034. +#define ROT_VF 0x4
  175035. +#define ROT_PP 0x8
  175036. +#define VDI_VF 0x10
  175037. +#define VDOA_ONLY 0x20
  175038. + u8 task;
  175039. +#define NO_SPLIT 0x0
  175040. +#define RL_SPLIT 0x1
  175041. +#define UD_SPLIT 0x2
  175042. +#define LEFT_STRIPE 0x1
  175043. +#define RIGHT_STRIPE 0x2
  175044. +#define UP_STRIPE 0x4
  175045. +#define DOWN_STRIPE 0x8
  175046. +#define SPLIT_MASK 0xF
  175047. + u8 split_mode;
  175048. + u8 band_lines;
  175049. + ipu_channel_t ic_chan;
  175050. + ipu_channel_t rot_chan;
  175051. + ipu_channel_t vdi_ic_p_chan;
  175052. + ipu_channel_t vdi_ic_n_chan;
  175053. +
  175054. + u32 i_off;
  175055. + u32 i_uoff;
  175056. + u32 i_voff;
  175057. + u32 istride;
  175058. +
  175059. + u32 ov_off;
  175060. + u32 ov_uoff;
  175061. + u32 ov_voff;
  175062. + u32 ovstride;
  175063. +
  175064. + u32 ov_alpha_off;
  175065. + u32 ov_alpha_stride;
  175066. +
  175067. + u32 o_off;
  175068. + u32 o_uoff;
  175069. + u32 o_voff;
  175070. + u32 ostride;
  175071. +
  175072. + u32 r_fmt;
  175073. + u32 r_width;
  175074. + u32 r_height;
  175075. + u32 r_stride;
  175076. + dma_addr_t r_paddr;
  175077. +
  175078. + struct stripe_setting sp_setting;
  175079. +};
  175080. +
  175081. +struct ipu_split_task {
  175082. + struct ipu_task task;
  175083. + struct ipu_task_entry *parent_task;
  175084. + struct ipu_task_entry *child_task;
  175085. + u32 task_no;
  175086. +};
  175087. +
  175088. +struct ipu_task_entry {
  175089. + struct ipu_input input;
  175090. + struct ipu_output output;
  175091. +
  175092. + bool overlay_en;
  175093. + struct ipu_overlay overlay;
  175094. +#define DEF_TIMEOUT_MS 1000
  175095. +#define DEF_DELAY_MS 20
  175096. + int timeout;
  175097. + int irq;
  175098. +
  175099. + u8 task_id;
  175100. + u8 ipu_id;
  175101. + u8 task_in_list;
  175102. + u8 split_done;
  175103. + struct mutex split_lock;
  175104. + struct mutex vdic_lock;
  175105. + wait_queue_head_t split_waitq;
  175106. +
  175107. + struct list_head node;
  175108. + struct list_head split_list;
  175109. + struct ipu_soc *ipu;
  175110. + struct device *dev;
  175111. + struct task_set set;
  175112. + wait_queue_head_t task_waitq;
  175113. + struct completion irq_comp;
  175114. + struct kref refcount;
  175115. + ipu_state_t state;
  175116. + u32 task_no;
  175117. + atomic_t done;
  175118. + atomic_t res_free;
  175119. + atomic_t res_get;
  175120. +
  175121. + struct ipu_task_entry *parent;
  175122. + char *vditmpbuf[2];
  175123. + u32 old_save_lines;
  175124. + u32 old_size;
  175125. + bool buf1filled;
  175126. + bool buf0filled;
  175127. +
  175128. + vdoa_handle_t vdoa_handle;
  175129. + struct vdoa_output_mem {
  175130. + void *vaddr;
  175131. + dma_addr_t paddr;
  175132. + int size;
  175133. + } vdoa_dma;
  175134. +
  175135. +#ifdef DBG_IPU_PERF
  175136. + struct timespec ts_queue;
  175137. + struct timespec ts_dotask;
  175138. + struct timespec ts_waitirq;
  175139. + struct timespec ts_inirq;
  175140. + struct timespec ts_wakeup;
  175141. + struct timespec ts_rel;
  175142. +#endif
  175143. +};
  175144. +
  175145. +struct ipu_channel_tabel {
  175146. + struct mutex lock;
  175147. + u8 used[MXC_IPU_MAX_NUM][MAX_PP_CH];
  175148. + u8 vdoa_used;
  175149. +};
  175150. +
  175151. +struct ipu_thread_data {
  175152. + struct ipu_soc *ipu;
  175153. + u32 id;
  175154. + u32 is_vdoa;
  175155. +};
  175156. +
  175157. +struct ipu_alloc_list {
  175158. + struct list_head list;
  175159. + dma_addr_t phy_addr;
  175160. + void *cpu_addr;
  175161. + u32 size;
  175162. + void *file_index;
  175163. +};
  175164. +
  175165. +static LIST_HEAD(ipu_alloc_list);
  175166. +static DEFINE_MUTEX(ipu_alloc_lock);
  175167. +static struct ipu_channel_tabel ipu_ch_tbl;
  175168. +static LIST_HEAD(ipu_task_list);
  175169. +static DEFINE_SPINLOCK(ipu_task_list_lock);
  175170. +static DECLARE_WAIT_QUEUE_HEAD(thread_waitq);
  175171. +static DECLARE_WAIT_QUEUE_HEAD(res_waitq);
  175172. +static atomic_t req_cnt;
  175173. +static atomic_t file_index = ATOMIC_INIT(1);
  175174. +static int major;
  175175. +static int max_ipu_no;
  175176. +static int thread_id;
  175177. +static atomic_t frame_no;
  175178. +static struct class *ipu_class;
  175179. +static struct device *ipu_dev;
  175180. +static int debug;
  175181. +module_param(debug, int, 0600);
  175182. +#ifdef DBG_IPU_PERF
  175183. +static struct timespec ts_frame_max;
  175184. +static u32 ts_frame_avg;
  175185. +static atomic_t frame_cnt;
  175186. +#endif
  175187. +
  175188. +static bool deinterlace_3_field(struct ipu_task_entry *t)
  175189. +{
  175190. + return ((t->set.mode & VDI_MODE) &&
  175191. + (t->input.deinterlace.motion != HIGH_MOTION));
  175192. +}
  175193. +
  175194. +static u32 tiled_filed_size(struct ipu_task_entry *t)
  175195. +{
  175196. + u32 field_size;
  175197. +
  175198. + /* note: page_align is required by VPU hw ouput buffer */
  175199. + field_size = TILED_NV12_FRAME_SIZE(t->input.width, t->input.height/2);
  175200. + return field_size;
  175201. +}
  175202. +
  175203. +static bool only_ic(u8 mode)
  175204. +{
  175205. + mode = mode & IPU_PREPROCESS_MODE_MASK;
  175206. + return ((mode == IC_MODE) || (mode == VDI_MODE));
  175207. +}
  175208. +
  175209. +static bool only_rot(u8 mode)
  175210. +{
  175211. + mode = mode & IPU_PREPROCESS_MODE_MASK;
  175212. + return (mode == ROT_MODE);
  175213. +}
  175214. +
  175215. +static bool ic_and_rot(u8 mode)
  175216. +{
  175217. + mode = mode & IPU_PREPROCESS_MODE_MASK;
  175218. + return ((mode == (IC_MODE | ROT_MODE)) ||
  175219. + (mode == (VDI_MODE | ROT_MODE)));
  175220. +}
  175221. +
  175222. +static bool need_split(struct ipu_task_entry *t)
  175223. +{
  175224. + return ((t->set.split_mode != NO_SPLIT) || (t->task_no & SPLIT_MASK));
  175225. +}
  175226. +
  175227. +unsigned int fmt_to_bpp(unsigned int pixelformat)
  175228. +{
  175229. + u32 bpp;
  175230. +
  175231. + switch (pixelformat) {
  175232. + case IPU_PIX_FMT_RGB565:
  175233. + /*interleaved 422*/
  175234. + case IPU_PIX_FMT_YUYV:
  175235. + case IPU_PIX_FMT_UYVY:
  175236. + /*non-interleaved 422*/
  175237. + case IPU_PIX_FMT_YUV422P:
  175238. + case IPU_PIX_FMT_YVU422P:
  175239. + bpp = 16;
  175240. + break;
  175241. + case IPU_PIX_FMT_BGR24:
  175242. + case IPU_PIX_FMT_RGB24:
  175243. + case IPU_PIX_FMT_YUV444:
  175244. + case IPU_PIX_FMT_YUV444P:
  175245. + bpp = 24;
  175246. + break;
  175247. + case IPU_PIX_FMT_BGR32:
  175248. + case IPU_PIX_FMT_BGRA32:
  175249. + case IPU_PIX_FMT_RGB32:
  175250. + case IPU_PIX_FMT_RGBA32:
  175251. + case IPU_PIX_FMT_ABGR32:
  175252. + bpp = 32;
  175253. + break;
  175254. + /*non-interleaved 420*/
  175255. + case IPU_PIX_FMT_YUV420P:
  175256. + case IPU_PIX_FMT_YVU420P:
  175257. + case IPU_PIX_FMT_YUV420P2:
  175258. + case IPU_PIX_FMT_NV12:
  175259. + bpp = 12;
  175260. + break;
  175261. + default:
  175262. + bpp = 8;
  175263. + break;
  175264. + }
  175265. + return bpp;
  175266. +}
  175267. +EXPORT_SYMBOL_GPL(fmt_to_bpp);
  175268. +
  175269. +cs_t colorspaceofpixel(int fmt)
  175270. +{
  175271. + switch (fmt) {
  175272. + case IPU_PIX_FMT_RGB565:
  175273. + case IPU_PIX_FMT_BGR24:
  175274. + case IPU_PIX_FMT_RGB24:
  175275. + case IPU_PIX_FMT_BGRA32:
  175276. + case IPU_PIX_FMT_BGR32:
  175277. + case IPU_PIX_FMT_RGBA32:
  175278. + case IPU_PIX_FMT_RGB32:
  175279. + case IPU_PIX_FMT_ABGR32:
  175280. + return RGB_CS;
  175281. + break;
  175282. + case IPU_PIX_FMT_UYVY:
  175283. + case IPU_PIX_FMT_YUYV:
  175284. + case IPU_PIX_FMT_YUV420P2:
  175285. + case IPU_PIX_FMT_YUV420P:
  175286. + case IPU_PIX_FMT_YVU420P:
  175287. + case IPU_PIX_FMT_YVU422P:
  175288. + case IPU_PIX_FMT_YUV422P:
  175289. + case IPU_PIX_FMT_YUV444:
  175290. + case IPU_PIX_FMT_YUV444P:
  175291. + case IPU_PIX_FMT_NV12:
  175292. + case IPU_PIX_FMT_TILED_NV12:
  175293. + case IPU_PIX_FMT_TILED_NV12F:
  175294. + return YUV_CS;
  175295. + break;
  175296. + default:
  175297. + return NULL_CS;
  175298. + }
  175299. +}
  175300. +EXPORT_SYMBOL_GPL(colorspaceofpixel);
  175301. +
  175302. +int need_csc(int ifmt, int ofmt)
  175303. +{
  175304. + cs_t ics, ocs;
  175305. +
  175306. + ics = colorspaceofpixel(ifmt);
  175307. + ocs = colorspaceofpixel(ofmt);
  175308. +
  175309. + if ((ics == NULL_CS) || (ocs == NULL_CS))
  175310. + return -1;
  175311. + else if (ics != ocs)
  175312. + return 1;
  175313. +
  175314. + return 0;
  175315. +}
  175316. +EXPORT_SYMBOL_GPL(need_csc);
  175317. +
  175318. +static int soc_max_in_width(u32 is_vdoa)
  175319. +{
  175320. + return is_vdoa ? 8192 : 4096;
  175321. +}
  175322. +
  175323. +static int soc_max_vdi_in_width(void)
  175324. +{
  175325. + return IPU_MAX_VDI_IN_WIDTH;
  175326. +}
  175327. +static int soc_max_in_height(void)
  175328. +{
  175329. + return 4096;
  175330. +}
  175331. +
  175332. +static int soc_max_out_width(void)
  175333. +{
  175334. + /* mx51/mx53/mx6q is 1024*/
  175335. + return 1024;
  175336. +}
  175337. +
  175338. +static int soc_max_out_height(void)
  175339. +{
  175340. + /* mx51/mx53/mx6q is 1024*/
  175341. + return 1024;
  175342. +}
  175343. +
  175344. +static void dump_task_info(struct ipu_task_entry *t)
  175345. +{
  175346. + if (!debug)
  175347. + return;
  175348. + dev_dbg(t->dev, "[0x%p]input:\n", (void *)t);
  175349. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->input.format);
  175350. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->input.width);
  175351. + dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->input.height);
  175352. + dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n", (void *)t, t->input.crop.w);
  175353. + dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n", (void *)t, t->input.crop.h);
  175354. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
  175355. + (void *)t, t->input.crop.pos.x);
  175356. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
  175357. + (void *)t, t->input.crop.pos.y);
  175358. + dev_dbg(t->dev, "[0x%p]input buffer:\n", (void *)t);
  175359. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->input.paddr);
  175360. + dev_dbg(t->dev, "[0x%p]\ti_off = 0x%x\n", (void *)t, t->set.i_off);
  175361. + dev_dbg(t->dev, "[0x%p]\ti_uoff = 0x%x\n", (void *)t, t->set.i_uoff);
  175362. + dev_dbg(t->dev, "[0x%p]\ti_voff = 0x%x\n", (void *)t, t->set.i_voff);
  175363. + dev_dbg(t->dev, "[0x%p]\tistride = %d\n", (void *)t, t->set.istride);
  175364. + if (t->input.deinterlace.enable) {
  175365. + dev_dbg(t->dev, "[0x%p]deinterlace enabled with:\n", (void *)t);
  175366. + if (t->input.deinterlace.motion != HIGH_MOTION) {
  175367. + dev_dbg(t->dev, "[0x%p]\tlow/medium motion\n", (void *)t);
  175368. + dev_dbg(t->dev, "[0x%p]\tpaddr_n = 0x%x\n",
  175369. + (void *)t, t->input.paddr_n);
  175370. + } else
  175371. + dev_dbg(t->dev, "[0x%p]\thigh motion\n", (void *)t);
  175372. + }
  175373. +
  175374. + dev_dbg(t->dev, "[0x%p]output:\n", (void *)t);
  175375. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->output.format);
  175376. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->output.width);
  175377. + dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->output.height);
  175378. + dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n", (void *)t, t->output.crop.w);
  175379. + dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n", (void *)t, t->output.crop.h);
  175380. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
  175381. + (void *)t, t->output.crop.pos.x);
  175382. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
  175383. + (void *)t, t->output.crop.pos.y);
  175384. + dev_dbg(t->dev, "[0x%p]\trotate = %d\n", (void *)t, t->output.rotate);
  175385. + dev_dbg(t->dev, "[0x%p]output buffer:\n", (void *)t);
  175386. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->output.paddr);
  175387. + dev_dbg(t->dev, "[0x%p]\to_off = 0x%x\n", (void *)t, t->set.o_off);
  175388. + dev_dbg(t->dev, "[0x%p]\to_uoff = 0x%x\n", (void *)t, t->set.o_uoff);
  175389. + dev_dbg(t->dev, "[0x%p]\to_voff = 0x%x\n", (void *)t, t->set.o_voff);
  175390. + dev_dbg(t->dev, "[0x%p]\tostride = %d\n", (void *)t, t->set.ostride);
  175391. +
  175392. + if (t->overlay_en) {
  175393. + dev_dbg(t->dev, "[0x%p]overlay:\n", (void *)t);
  175394. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n",
  175395. + (void *)t, t->overlay.format);
  175396. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n",
  175397. + (void *)t, t->overlay.width);
  175398. + dev_dbg(t->dev, "[0x%p]\theight = %d\n",
  175399. + (void *)t, t->overlay.height);
  175400. + dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n",
  175401. + (void *)t, t->overlay.crop.w);
  175402. + dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n",
  175403. + (void *)t, t->overlay.crop.h);
  175404. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
  175405. + (void *)t, t->overlay.crop.pos.x);
  175406. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
  175407. + (void *)t, t->overlay.crop.pos.y);
  175408. + dev_dbg(t->dev, "[0x%p]overlay buffer:\n", (void *)t);
  175409. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n",
  175410. + (void *)t, t->overlay.paddr);
  175411. + dev_dbg(t->dev, "[0x%p]\tov_off = 0x%x\n",
  175412. + (void *)t, t->set.ov_off);
  175413. + dev_dbg(t->dev, "[0x%p]\tov_uoff = 0x%x\n",
  175414. + (void *)t, t->set.ov_uoff);
  175415. + dev_dbg(t->dev, "[0x%p]\tov_voff = 0x%x\n",
  175416. + (void *)t, t->set.ov_voff);
  175417. + dev_dbg(t->dev, "[0x%p]\tovstride = %d\n",
  175418. + (void *)t, t->set.ovstride);
  175419. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  175420. + dev_dbg(t->dev, "[0x%p]local alpha enabled with:\n",
  175421. + (void *)t);
  175422. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n",
  175423. + (void *)t, t->overlay.alpha.loc_alp_paddr);
  175424. + dev_dbg(t->dev, "[0x%p]\tov_alpha_off = 0x%x\n",
  175425. + (void *)t, t->set.ov_alpha_off);
  175426. + dev_dbg(t->dev, "[0x%p]\tov_alpha_stride = %d\n",
  175427. + (void *)t, t->set.ov_alpha_stride);
  175428. + } else
  175429. + dev_dbg(t->dev, "[0x%p]globle alpha enabled with value 0x%x\n",
  175430. + (void *)t, t->overlay.alpha.gvalue);
  175431. + if (t->overlay.colorkey.enable)
  175432. + dev_dbg(t->dev, "[0x%p]colorkey enabled with value 0x%x\n",
  175433. + (void *)t, t->overlay.colorkey.value);
  175434. + }
  175435. +
  175436. + dev_dbg(t->dev, "[0x%p]want task_id = %d\n", (void *)t, t->task_id);
  175437. + dev_dbg(t->dev, "[0x%p]want task mode is 0x%x\n",
  175438. + (void *)t, t->set.mode);
  175439. + dev_dbg(t->dev, "[0x%p]\tIC_MODE = 0x%x\n", (void *)t, IC_MODE);
  175440. + dev_dbg(t->dev, "[0x%p]\tROT_MODE = 0x%x\n", (void *)t, ROT_MODE);
  175441. + dev_dbg(t->dev, "[0x%p]\tVDI_MODE = 0x%x\n", (void *)t, VDI_MODE);
  175442. + dev_dbg(t->dev, "[0x%p]\tTask_no = 0x%x\n\n\n", (void *)t, t->task_no);
  175443. +}
  175444. +
  175445. +static void dump_check_err(struct device *dev, int err)
  175446. +{
  175447. + switch (err) {
  175448. + case IPU_CHECK_ERR_INPUT_CROP:
  175449. + dev_err(dev, "input crop setting error\n");
  175450. + break;
  175451. + case IPU_CHECK_ERR_OUTPUT_CROP:
  175452. + dev_err(dev, "output crop setting error\n");
  175453. + break;
  175454. + case IPU_CHECK_ERR_OVERLAY_CROP:
  175455. + dev_err(dev, "overlay crop setting error\n");
  175456. + break;
  175457. + case IPU_CHECK_ERR_INPUT_OVER_LIMIT:
  175458. + dev_err(dev, "input over limitation\n");
  175459. + break;
  175460. + case IPU_CHECK_ERR_OVERLAY_WITH_VDI:
  175461. + dev_err(dev, "do not support overlay with deinterlace\n");
  175462. + break;
  175463. + case IPU_CHECK_ERR_OV_OUT_NO_FIT:
  175464. + dev_err(dev,
  175465. + "width/height of overlay and ic output should be same\n");
  175466. + break;
  175467. + case IPU_CHECK_ERR_PROC_NO_NEED:
  175468. + dev_err(dev, "no ipu processing need\n");
  175469. + break;
  175470. + case IPU_CHECK_ERR_SPLIT_INPUTW_OVER:
  175471. + dev_err(dev, "split mode input width overflow\n");
  175472. + break;
  175473. + case IPU_CHECK_ERR_SPLIT_INPUTH_OVER:
  175474. + dev_err(dev, "split mode input height overflow\n");
  175475. + break;
  175476. + case IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER:
  175477. + dev_err(dev, "split mode output width overflow\n");
  175478. + break;
  175479. + case IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER:
  175480. + dev_err(dev, "split mode output height overflow\n");
  175481. + break;
  175482. + case IPU_CHECK_ERR_SPLIT_WITH_ROT:
  175483. + dev_err(dev, "not support split mode with rotation\n");
  175484. + break;
  175485. + case IPU_CHECK_ERR_W_DOWNSIZE_OVER:
  175486. + dev_err(dev, "horizontal downsizing ratio overflow\n");
  175487. + break;
  175488. + case IPU_CHECK_ERR_H_DOWNSIZE_OVER:
  175489. + dev_err(dev, "vertical downsizing ratio overflow\n");
  175490. + break;
  175491. + default:
  175492. + break;
  175493. + }
  175494. +}
  175495. +
  175496. +static void dump_check_warn(struct device *dev, int warn)
  175497. +{
  175498. + if (warn & IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN)
  175499. + dev_warn(dev, "input u/v offset not 8 align\n");
  175500. + if (warn & IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN)
  175501. + dev_warn(dev, "output u/v offset not 8 align\n");
  175502. + if (warn & IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN)
  175503. + dev_warn(dev, "overlay u/v offset not 8 align\n");
  175504. +}
  175505. +
  175506. +static int set_crop(struct ipu_crop *crop, int width, int height, int fmt)
  175507. +{
  175508. + if ((width == 0) || (height == 0)) {
  175509. + pr_err("Invalid param: width=%d, height=%d\n", width, height);
  175510. + return -EINVAL;
  175511. + }
  175512. +
  175513. + if ((IPU_PIX_FMT_TILED_NV12 == fmt) ||
  175514. + (IPU_PIX_FMT_TILED_NV12F == fmt)) {
  175515. + if (crop->w || crop->h) {
  175516. + if (((crop->w + crop->pos.x) > width)
  175517. + || ((crop->h + crop->pos.y) > height)
  175518. + || (0 != (crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  175519. + || (0 != (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  175520. + || (0 != (crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  175521. + || (0 != (crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  175522. + ) {
  175523. + pr_err("set_crop error MB align.\n");
  175524. + return -EINVAL;
  175525. + }
  175526. + } else {
  175527. + crop->pos.x = 0;
  175528. + crop->pos.y = 0;
  175529. + crop->w = width;
  175530. + crop->h = height;
  175531. + if ((0 != (crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  175532. + || (0 != (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))) {
  175533. + pr_err("set_crop error w/h MB align.\n");
  175534. + return -EINVAL;
  175535. + }
  175536. + }
  175537. + } else {
  175538. + if (crop->w || crop->h) {
  175539. + if (((crop->w + crop->pos.x) > (width + 16))
  175540. + || ((crop->h + crop->pos.y) > height + 16)) {
  175541. + pr_err("set_crop error exceeds width/height.\n");
  175542. + return -EINVAL;
  175543. + }
  175544. + } else {
  175545. + crop->pos.x = 0;
  175546. + crop->pos.y = 0;
  175547. + crop->w = width;
  175548. + crop->h = height;
  175549. + }
  175550. + crop->w -= crop->w%8;
  175551. + crop->h -= crop->h%8;
  175552. + }
  175553. +
  175554. + if ((crop->w == 0) || (crop->h == 0)) {
  175555. + pr_err("Invalid crop param: crop.w=%d, crop.h=%d\n",
  175556. + crop->w, crop->h);
  175557. + return -EINVAL;
  175558. + }
  175559. +
  175560. + return 0;
  175561. +}
  175562. +
  175563. +static void update_offset(unsigned int fmt,
  175564. + unsigned int width, unsigned int height,
  175565. + unsigned int pos_x, unsigned int pos_y,
  175566. + int *off, int *uoff, int *voff, int *stride)
  175567. +{
  175568. + /* NOTE: u v offset should based on start point of off*/
  175569. + switch (fmt) {
  175570. + case IPU_PIX_FMT_YUV420P2:
  175571. + case IPU_PIX_FMT_YUV420P:
  175572. + *off = pos_y * width + pos_x;
  175573. + *uoff = (width * (height - pos_y) - pos_x)
  175574. + + (width/2) * (pos_y/2) + pos_x/2;
  175575. + /* In case height is odd, round up to even */
  175576. + *voff = *uoff + (width/2) * ((height+1)/2);
  175577. + break;
  175578. + case IPU_PIX_FMT_YVU420P:
  175579. + *off = pos_y * width + pos_x;
  175580. + *voff = (width * (height - pos_y) - pos_x)
  175581. + + (width/2) * (pos_y/2) + pos_x/2;
  175582. + /* In case height is odd, round up to even */
  175583. + *uoff = *voff + (width/2) * ((height+1)/2);
  175584. + break;
  175585. + case IPU_PIX_FMT_YVU422P:
  175586. + *off = pos_y * width + pos_x;
  175587. + *voff = (width * (height - pos_y) - pos_x)
  175588. + + (width/2) * pos_y + pos_x/2;
  175589. + *uoff = *voff + (width/2) * height;
  175590. + break;
  175591. + case IPU_PIX_FMT_YUV422P:
  175592. + *off = pos_y * width + pos_x;
  175593. + *uoff = (width * (height - pos_y) - pos_x)
  175594. + + (width/2) * pos_y + pos_x/2;
  175595. + *voff = *uoff + (width/2) * height;
  175596. + break;
  175597. + case IPU_PIX_FMT_YUV444P:
  175598. + *off = pos_y * width + pos_x;
  175599. + *uoff = width * height;
  175600. + *voff = width * height * 2;
  175601. + break;
  175602. + case IPU_PIX_FMT_NV12:
  175603. + *off = pos_y * width + pos_x;
  175604. + *uoff = (width * (height - pos_y) - pos_x)
  175605. + + width * (pos_y/2) + pos_x;
  175606. + break;
  175607. + case IPU_PIX_FMT_TILED_NV12:
  175608. + /*
  175609. + * tiled format, progressive:
  175610. + * assuming that line is aligned with MB height (aligned to 16)
  175611. + * offset = line * stride + (pixel / MB_width) * pixels_in_MB
  175612. + * = line * stride + (pixel / 16) * 256
  175613. + * = line * stride + pixel * 16
  175614. + */
  175615. + *off = pos_y * width + (pos_x << 4);
  175616. + *uoff = ALIGN(width * height, SZ_4K) + (*off >> 1) - *off;
  175617. + break;
  175618. + case IPU_PIX_FMT_TILED_NV12F:
  175619. + /*
  175620. + * tiled format, interlaced:
  175621. + * same as above, only number of pixels in MB is 128,
  175622. + * instead of 256
  175623. + */
  175624. + *off = (pos_y >> 1) * width + (pos_x << 3);
  175625. + *uoff = ALIGN(width * height/2, SZ_4K) + (*off >> 1) - *off;
  175626. + break;
  175627. + default:
  175628. + *off = (pos_y * width + pos_x) * fmt_to_bpp(fmt)/8;
  175629. + break;
  175630. + }
  175631. + *stride = width * bytes_per_pixel(fmt);
  175632. +}
  175633. +
  175634. +static int update_split_setting(struct ipu_task_entry *t, bool vdi_split)
  175635. +{
  175636. + struct stripe_param left_stripe;
  175637. + struct stripe_param right_stripe;
  175638. + struct stripe_param up_stripe;
  175639. + struct stripe_param down_stripe;
  175640. + u32 iw, ih, ow, oh;
  175641. + u32 max_width;
  175642. + int ret;
  175643. +
  175644. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT)
  175645. + return IPU_CHECK_ERR_SPLIT_WITH_ROT;
  175646. +
  175647. + iw = t->input.crop.w;
  175648. + ih = t->input.crop.h;
  175649. +
  175650. + ow = t->output.crop.w;
  175651. + oh = t->output.crop.h;
  175652. +
  175653. + memset(&left_stripe, 0, sizeof(left_stripe));
  175654. + memset(&right_stripe, 0, sizeof(right_stripe));
  175655. + memset(&up_stripe, 0, sizeof(up_stripe));
  175656. + memset(&down_stripe, 0, sizeof(down_stripe));
  175657. +
  175658. + if (t->set.split_mode & RL_SPLIT) {
  175659. + /*
  175660. + * We do want equal strips: initialize stripes in case
  175661. + * calc_stripes returns before actually doing the calculation
  175662. + */
  175663. + left_stripe.input_width = iw / 2;
  175664. + left_stripe.output_width = ow / 2;
  175665. + right_stripe.input_column = iw / 2;
  175666. + right_stripe.output_column = ow / 2;
  175667. +
  175668. + if (vdi_split)
  175669. + max_width = soc_max_vdi_in_width();
  175670. + else
  175671. + max_width = soc_max_out_width();
  175672. + ret = ipu_calc_stripes_sizes(iw,
  175673. + ow,
  175674. + max_width,
  175675. + (((unsigned long long)1) << 32), /* 32bit for fractional*/
  175676. + 1, /* equal stripes */
  175677. + t->input.format,
  175678. + t->output.format,
  175679. + &left_stripe,
  175680. + &right_stripe);
  175681. + if (ret < 0)
  175682. + return IPU_CHECK_ERR_W_DOWNSIZE_OVER;
  175683. + else if (ret)
  175684. + dev_dbg(t->dev, "Warn: no:0x%x,calc_stripes ret:%d\n",
  175685. + t->task_no, ret);
  175686. + t->set.sp_setting.iw = left_stripe.input_width;
  175687. + t->set.sp_setting.ow = left_stripe.output_width;
  175688. + t->set.sp_setting.outh_resize_ratio = left_stripe.irr;
  175689. + t->set.sp_setting.i_left_pos = left_stripe.input_column;
  175690. + t->set.sp_setting.o_left_pos = left_stripe.output_column;
  175691. + t->set.sp_setting.i_right_pos = right_stripe.input_column;
  175692. + t->set.sp_setting.o_right_pos = right_stripe.output_column;
  175693. + } else {
  175694. + t->set.sp_setting.iw = iw;
  175695. + t->set.sp_setting.ow = ow;
  175696. + t->set.sp_setting.outh_resize_ratio = 0;
  175697. + t->set.sp_setting.i_left_pos = 0;
  175698. + t->set.sp_setting.o_left_pos = 0;
  175699. + t->set.sp_setting.i_right_pos = 0;
  175700. + t->set.sp_setting.o_right_pos = 0;
  175701. + }
  175702. + if ((t->set.sp_setting.iw + t->set.sp_setting.i_right_pos) > (iw+16))
  175703. + return IPU_CHECK_ERR_SPLIT_INPUTW_OVER;
  175704. + if (((t->set.sp_setting.ow + t->set.sp_setting.o_right_pos) > ow)
  175705. + || (t->set.sp_setting.ow > soc_max_out_width()))
  175706. + return IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER;
  175707. + if (rounddown(t->set.sp_setting.ow, 8) * 8 <=
  175708. + rounddown(t->set.sp_setting.iw, 8))
  175709. + return IPU_CHECK_ERR_W_DOWNSIZE_OVER;
  175710. +
  175711. + if (t->set.split_mode & UD_SPLIT) {
  175712. + /*
  175713. + * We do want equal strips: initialize stripes in case
  175714. + * calc_stripes returns before actually doing the calculation
  175715. + */
  175716. + up_stripe.input_width = ih / 2;
  175717. + up_stripe.output_width = oh / 2;
  175718. + down_stripe.input_column = ih / 2;
  175719. + down_stripe.output_column = oh / 2;
  175720. + ret = ipu_calc_stripes_sizes(ih,
  175721. + oh,
  175722. + soc_max_out_height(),
  175723. + (((unsigned long long)1) << 32), /* 32bit for fractional*/
  175724. + 0x1 | 0x2, /* equal stripes and vertical */
  175725. + t->input.format,
  175726. + t->output.format,
  175727. + &up_stripe,
  175728. + &down_stripe);
  175729. + if (ret < 0)
  175730. + return IPU_CHECK_ERR_H_DOWNSIZE_OVER;
  175731. + else if (ret)
  175732. + dev_err(t->dev, "Warn: no:0x%x,calc_stripes ret:%d\n",
  175733. + t->task_no, ret);
  175734. + t->set.sp_setting.ih = up_stripe.input_width;
  175735. + t->set.sp_setting.oh = up_stripe.output_width;
  175736. + t->set.sp_setting.outv_resize_ratio = up_stripe.irr;
  175737. + t->set.sp_setting.i_top_pos = up_stripe.input_column;
  175738. + t->set.sp_setting.o_top_pos = up_stripe.output_column;
  175739. + t->set.sp_setting.i_bottom_pos = down_stripe.input_column;
  175740. + t->set.sp_setting.o_bottom_pos = down_stripe.output_column;
  175741. + } else {
  175742. + t->set.sp_setting.ih = ih;
  175743. + t->set.sp_setting.oh = oh;
  175744. + t->set.sp_setting.outv_resize_ratio = 0;
  175745. + t->set.sp_setting.i_top_pos = 0;
  175746. + t->set.sp_setting.o_top_pos = 0;
  175747. + t->set.sp_setting.i_bottom_pos = 0;
  175748. + t->set.sp_setting.o_bottom_pos = 0;
  175749. + }
  175750. +
  175751. + /* downscale case: enforce limits */
  175752. + if (((t->set.sp_setting.ih + t->set.sp_setting.i_bottom_pos) > (ih))
  175753. + && (t->set.sp_setting.ih >= t->set.sp_setting.oh))
  175754. + return IPU_CHECK_ERR_SPLIT_INPUTH_OVER;
  175755. + /* upscale case: relax limits because ipu_calc_stripes_sizes() may
  175756. + create input stripe that falls just outside of the input window */
  175757. + else if ((t->set.sp_setting.ih + t->set.sp_setting.i_bottom_pos)
  175758. + > (ih+16))
  175759. + return IPU_CHECK_ERR_SPLIT_INPUTH_OVER;
  175760. + if (((t->set.sp_setting.oh + t->set.sp_setting.o_bottom_pos) > oh)
  175761. + || (t->set.sp_setting.oh > soc_max_out_height()))
  175762. + return IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER;
  175763. + if (rounddown(t->set.sp_setting.oh, 8) * 8 <=
  175764. + rounddown(t->set.sp_setting.ih, 8))
  175765. + return IPU_CHECK_ERR_H_DOWNSIZE_OVER;
  175766. +
  175767. + return IPU_CHECK_OK;
  175768. +}
  175769. +
  175770. +static int check_task(struct ipu_task_entry *t)
  175771. +{
  175772. + int tmp;
  175773. + int ret = IPU_CHECK_OK;
  175774. + int timeout;
  175775. + bool vdi_split = false;
  175776. + int ocw, och;
  175777. +
  175778. + if ((IPU_PIX_FMT_TILED_NV12 == t->overlay.format) ||
  175779. + (IPU_PIX_FMT_TILED_NV12F == t->overlay.format) ||
  175780. + (IPU_PIX_FMT_TILED_NV12 == t->output.format) ||
  175781. + (IPU_PIX_FMT_TILED_NV12F == t->output.format) ||
  175782. + ((IPU_PIX_FMT_TILED_NV12F == t->input.format) &&
  175783. + !t->input.deinterlace.enable)) {
  175784. + ret = IPU_CHECK_ERR_NOT_SUPPORT;
  175785. + goto done;
  175786. + }
  175787. +
  175788. + /* check input */
  175789. + ret = set_crop(&t->input.crop, t->input.width, t->input.height,
  175790. + t->input.format);
  175791. + if (ret < 0) {
  175792. + ret = IPU_CHECK_ERR_INPUT_CROP;
  175793. + goto done;
  175794. + } else
  175795. + update_offset(t->input.format, t->input.width, t->input.height,
  175796. + t->input.crop.pos.x, t->input.crop.pos.y,
  175797. + &t->set.i_off, &t->set.i_uoff,
  175798. + &t->set.i_voff, &t->set.istride);
  175799. +
  175800. + /* check output */
  175801. + ret = set_crop(&t->output.crop, t->output.width, t->output.height,
  175802. + t->output.format);
  175803. + if (ret < 0) {
  175804. + ret = IPU_CHECK_ERR_OUTPUT_CROP;
  175805. + goto done;
  175806. + } else
  175807. + update_offset(t->output.format,
  175808. + t->output.width, t->output.height,
  175809. + t->output.crop.pos.x, t->output.crop.pos.y,
  175810. + &t->set.o_off, &t->set.o_uoff,
  175811. + &t->set.o_voff, &t->set.ostride);
  175812. +
  175813. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  175814. + /*
  175815. + * Cache output width and height and
  175816. + * swap them so that we may check
  175817. + * downsize overflow correctly.
  175818. + */
  175819. + ocw = t->output.crop.h;
  175820. + och = t->output.crop.w;
  175821. + } else {
  175822. + ocw = t->output.crop.w;
  175823. + och = t->output.crop.h;
  175824. + }
  175825. +
  175826. + if (ocw * 8 <= t->input.crop.w) {
  175827. + ret = IPU_CHECK_ERR_W_DOWNSIZE_OVER;
  175828. + goto done;
  175829. + }
  175830. +
  175831. + if (och * 8 <= t->input.crop.h) {
  175832. + ret = IPU_CHECK_ERR_H_DOWNSIZE_OVER;
  175833. + goto done;
  175834. + }
  175835. +
  175836. + if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  175837. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  175838. + if ((t->input.crop.w > soc_max_in_width(1)) ||
  175839. + (t->input.crop.h > soc_max_in_height())) {
  175840. + ret = IPU_CHECK_ERR_INPUT_OVER_LIMIT;
  175841. + goto done;
  175842. + }
  175843. + /* output fmt: NV12 and YUYV, now don't support resize */
  175844. + if (((IPU_PIX_FMT_NV12 != t->output.format) &&
  175845. + (IPU_PIX_FMT_YUYV != t->output.format)) ||
  175846. + (t->input.crop.w != t->output.crop.w) ||
  175847. + (t->input.crop.h != t->output.crop.h)) {
  175848. + ret = IPU_CHECK_ERR_NOT_SUPPORT;
  175849. + goto done;
  175850. + }
  175851. + }
  175852. +
  175853. + /* check overlay if there is */
  175854. + if (t->overlay_en) {
  175855. + if (t->input.deinterlace.enable) {
  175856. + ret = IPU_CHECK_ERR_OVERLAY_WITH_VDI;
  175857. + goto done;
  175858. + }
  175859. +
  175860. + ret = set_crop(&t->overlay.crop, t->overlay.width,
  175861. + t->overlay.height, t->overlay.format);
  175862. + if (ret < 0) {
  175863. + ret = IPU_CHECK_ERR_OVERLAY_CROP;
  175864. + goto done;
  175865. + } else {
  175866. + ocw = t->output.crop.w;
  175867. + och = t->output.crop.h;
  175868. +
  175869. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  175870. + ocw = t->output.crop.h;
  175871. + och = t->output.crop.w;
  175872. + }
  175873. + if ((t->overlay.crop.w != ocw) ||
  175874. + (t->overlay.crop.h != och)) {
  175875. + ret = IPU_CHECK_ERR_OV_OUT_NO_FIT;
  175876. + goto done;
  175877. + }
  175878. +
  175879. + update_offset(t->overlay.format,
  175880. + t->overlay.width, t->overlay.height,
  175881. + t->overlay.crop.pos.x, t->overlay.crop.pos.y,
  175882. + &t->set.ov_off, &t->set.ov_uoff,
  175883. + &t->set.ov_voff, &t->set.ovstride);
  175884. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  175885. + t->set.ov_alpha_stride = t->overlay.width;
  175886. + t->set.ov_alpha_off = t->overlay.crop.pos.y *
  175887. + t->overlay.width + t->overlay.crop.pos.x;
  175888. + }
  175889. + }
  175890. + }
  175891. +
  175892. + /* input overflow? */
  175893. + if (!((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  175894. + (IPU_PIX_FMT_TILED_NV12F == t->input.format))) {
  175895. + if ((t->input.crop.w > soc_max_in_width(0)) ||
  175896. + (t->input.crop.h > soc_max_in_height())) {
  175897. + ret = IPU_CHECK_ERR_INPUT_OVER_LIMIT;
  175898. + goto done;
  175899. + }
  175900. + }
  175901. +
  175902. + /* check task mode */
  175903. + t->set.mode = NULL_MODE;
  175904. + t->set.split_mode = NO_SPLIT;
  175905. +
  175906. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  175907. + /*output swap*/
  175908. + tmp = t->output.crop.w;
  175909. + t->output.crop.w = t->output.crop.h;
  175910. + t->output.crop.h = tmp;
  175911. + }
  175912. +
  175913. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT)
  175914. + t->set.mode |= ROT_MODE;
  175915. +
  175916. + /*need resize or CSC?*/
  175917. + if ((t->input.crop.w != t->output.crop.w) ||
  175918. + (t->input.crop.h != t->output.crop.h) ||
  175919. + need_csc(t->input.format, t->output.format))
  175920. + t->set.mode |= IC_MODE;
  175921. +
  175922. + /*need flip?*/
  175923. + if ((t->set.mode == NULL_MODE) && (t->output.rotate > IPU_ROTATE_NONE))
  175924. + t->set.mode |= IC_MODE;
  175925. +
  175926. + /*need IDMAC do format(same color space)?*/
  175927. + if ((t->set.mode == NULL_MODE) && (t->input.format != t->output.format))
  175928. + t->set.mode |= IC_MODE;
  175929. +
  175930. + /*overlay support*/
  175931. + if (t->overlay_en)
  175932. + t->set.mode |= IC_MODE;
  175933. +
  175934. + /*deinterlace*/
  175935. + if (t->input.deinterlace.enable) {
  175936. + t->set.mode &= ~IC_MODE;
  175937. + t->set.mode |= VDI_MODE;
  175938. + }
  175939. + if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  175940. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  175941. + if (t->set.mode & ROT_MODE) {
  175942. + ret = IPU_CHECK_ERR_NOT_SUPPORT;
  175943. + goto done;
  175944. + }
  175945. + t->set.mode |= VDOA_MODE;
  175946. + if (IPU_PIX_FMT_TILED_NV12F == t->input.format)
  175947. + t->set.mode |= VDOA_BAND_MODE;
  175948. + t->set.mode &= ~IC_MODE;
  175949. + }
  175950. +
  175951. + if ((t->set.mode & (IC_MODE | VDI_MODE)) &&
  175952. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  175953. + if (t->output.crop.w > soc_max_out_width())
  175954. + t->set.split_mode |= RL_SPLIT;
  175955. + if (t->output.crop.h > soc_max_out_height())
  175956. + t->set.split_mode |= UD_SPLIT;
  175957. + if (!t->set.split_mode && (t->set.mode & VDI_MODE) &&
  175958. + (t->input.crop.w > soc_max_vdi_in_width())) {
  175959. + t->set.split_mode |= RL_SPLIT;
  175960. + vdi_split = true;
  175961. + }
  175962. + if (t->set.split_mode) {
  175963. + if ((t->set.split_mode == RL_SPLIT) ||
  175964. + (t->set.split_mode == UD_SPLIT))
  175965. + timeout = DEF_TIMEOUT_MS * 2 + DEF_DELAY_MS;
  175966. + else
  175967. + timeout = DEF_TIMEOUT_MS * 4 + DEF_DELAY_MS;
  175968. + if (t->timeout < timeout)
  175969. + t->timeout = timeout;
  175970. +
  175971. + ret = update_split_setting(t, vdi_split);
  175972. + if (ret > IPU_CHECK_ERR_MIN)
  175973. + goto done;
  175974. + }
  175975. + }
  175976. +
  175977. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  175978. + /*output swap*/
  175979. + tmp = t->output.crop.w;
  175980. + t->output.crop.w = t->output.crop.h;
  175981. + t->output.crop.h = tmp;
  175982. + }
  175983. +
  175984. + if (t->set.mode == NULL_MODE) {
  175985. + ret = IPU_CHECK_ERR_PROC_NO_NEED;
  175986. + goto done;
  175987. + }
  175988. +
  175989. + if ((t->set.i_uoff % 8) || (t->set.i_voff % 8))
  175990. + ret |= IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN;
  175991. + if ((t->set.o_uoff % 8) || (t->set.o_voff % 8))
  175992. + ret |= IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN;
  175993. + if (t->overlay_en && ((t->set.ov_uoff % 8) || (t->set.ov_voff % 8)))
  175994. + ret |= IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN;
  175995. +
  175996. +done:
  175997. + /* dump msg */
  175998. + if (debug) {
  175999. + if (ret > IPU_CHECK_ERR_MIN)
  176000. + dump_check_err(t->dev, ret);
  176001. + else if (ret != IPU_CHECK_OK)
  176002. + dump_check_warn(t->dev, ret);
  176003. + }
  176004. +
  176005. + return ret;
  176006. +}
  176007. +
  176008. +static int prepare_task(struct ipu_task_entry *t)
  176009. +{
  176010. + int ret = 0;
  176011. +
  176012. + ret = check_task(t);
  176013. + if (ret > IPU_CHECK_ERR_MIN)
  176014. + return -EINVAL;
  176015. +
  176016. + if (t->set.mode & VDI_MODE) {
  176017. + t->task_id = IPU_TASK_ID_VF;
  176018. + t->set.task = VDI_VF;
  176019. + if (t->set.mode & ROT_MODE)
  176020. + t->set.task |= ROT_VF;
  176021. + }
  176022. +
  176023. + if (VDOA_MODE == t->set.mode) {
  176024. + if (t->set.task != 0) {
  176025. + dev_err(t->dev, "ERR: vdoa only task:0x%x, [0x%p].\n",
  176026. + t->set.task, t);
  176027. + return -EINVAL;
  176028. + }
  176029. + t->set.task |= VDOA_ONLY;
  176030. + }
  176031. +
  176032. + if (VDOA_BAND_MODE & t->set.mode) {
  176033. + /* to save band size: 1<<3 = 8 lines */
  176034. + t->set.band_lines = 3;
  176035. + }
  176036. +
  176037. + dump_task_info(t);
  176038. +
  176039. + return ret;
  176040. +}
  176041. +
  176042. +static uint32_t ic_vf_pp_is_busy(struct ipu_soc *ipu, bool is_vf)
  176043. +{
  176044. + uint32_t status;
  176045. + uint32_t status_vf;
  176046. + uint32_t status_rot;
  176047. +
  176048. + if (is_vf) {
  176049. + status = ipu_channel_status(ipu, MEM_VDI_PRP_VF_MEM);
  176050. + status_vf = ipu_channel_status(ipu, MEM_PRP_VF_MEM);
  176051. + status_rot = ipu_channel_status(ipu, MEM_ROT_VF_MEM);
  176052. + return status || status_vf || status_rot;
  176053. + } else {
  176054. + status = ipu_channel_status(ipu, MEM_PP_MEM);
  176055. + status_rot = ipu_channel_status(ipu, MEM_ROT_PP_MEM);
  176056. + return status || status_rot;
  176057. + }
  176058. +}
  176059. +
  176060. +static int _get_vdoa_ipu_res(struct ipu_task_entry *t)
  176061. +{
  176062. + int i;
  176063. + struct ipu_soc *ipu;
  176064. + u8 *used;
  176065. + uint32_t found_ipu = 0;
  176066. + uint32_t found_vdoa = 0;
  176067. + struct ipu_channel_tabel *tbl = &ipu_ch_tbl;
  176068. +
  176069. + mutex_lock(&tbl->lock);
  176070. + if (t->set.mode & VDOA_MODE) {
  176071. + if (NULL != t->vdoa_handle)
  176072. + found_vdoa = 1;
  176073. + else {
  176074. + found_vdoa = tbl->vdoa_used ? 0 : 1;
  176075. + if (found_vdoa) {
  176076. + tbl->vdoa_used = 1;
  176077. + vdoa_get_handle(&t->vdoa_handle);
  176078. + } else
  176079. + /* first get vdoa->ipu resource sequence */
  176080. + goto out;
  176081. + if (t->set.task & VDOA_ONLY)
  176082. + goto out;
  176083. + }
  176084. + }
  176085. +
  176086. + for (i = 0; i < max_ipu_no; i++) {
  176087. + ipu = ipu_get_soc(i);
  176088. + if (IS_ERR(ipu))
  176089. + dev_err(t->dev, "no:0x%x,found_vdoa:%d, ipu:%d\n",
  176090. + t->task_no, found_vdoa, i);
  176091. +
  176092. + used = &tbl->used[i][IPU_PP_CH_VF];
  176093. + if (t->set.mode & VDI_MODE) {
  176094. + if (0 == *used) {
  176095. + *used = 1;
  176096. + found_ipu = 1;
  176097. + break;
  176098. + }
  176099. + } else if ((t->set.mode & IC_MODE) || only_rot(t->set.mode)) {
  176100. + if (0 == *used) {
  176101. + t->task_id = IPU_TASK_ID_VF;
  176102. + if (t->set.mode & IC_MODE)
  176103. + t->set.task |= IC_VF;
  176104. + if (t->set.mode & ROT_MODE)
  176105. + t->set.task |= ROT_VF;
  176106. + *used = 1;
  176107. + found_ipu = 1;
  176108. + break;
  176109. + }
  176110. + } else
  176111. + dev_err(t->dev, "no:0x%x,found_vdoa:%d, mode:0x%x\n",
  176112. + t->task_no, found_vdoa, t->set.mode);
  176113. + }
  176114. + if (found_ipu)
  176115. + goto next;
  176116. +
  176117. + for (i = 0; i < max_ipu_no; i++) {
  176118. + ipu = ipu_get_soc(i);
  176119. + if (IS_ERR(ipu))
  176120. + dev_err(t->dev, "no:0x%x,found_vdoa:%d, ipu:%d\n",
  176121. + t->task_no, found_vdoa, i);
  176122. +
  176123. + if ((t->set.mode & IC_MODE) || only_rot(t->set.mode)) {
  176124. + used = &tbl->used[i][IPU_PP_CH_PP];
  176125. + if (0 == *used) {
  176126. + t->task_id = IPU_TASK_ID_PP;
  176127. + if (t->set.mode & IC_MODE)
  176128. + t->set.task |= IC_PP;
  176129. + if (t->set.mode & ROT_MODE)
  176130. + t->set.task |= ROT_PP;
  176131. + *used = 1;
  176132. + found_ipu = 1;
  176133. + break;
  176134. + }
  176135. + }
  176136. + }
  176137. +
  176138. +next:
  176139. + if (found_ipu) {
  176140. + t->ipu = ipu;
  176141. + t->ipu_id = i;
  176142. + t->dev = ipu->dev;
  176143. + if (atomic_inc_return(&t->res_get) == 2)
  176144. + dev_err(t->dev,
  176145. + "ERR no:0x%x,found_vdoa:%d,get ipu twice\n",
  176146. + t->task_no, found_vdoa);
  176147. + }
  176148. +out:
  176149. + dev_dbg(t->dev,
  176150. + "%s:no:0x%x,found_vdoa:%d, found_ipu:%d\n",
  176151. + __func__, t->task_no, found_vdoa, found_ipu);
  176152. + mutex_unlock(&tbl->lock);
  176153. + if (t->set.task & VDOA_ONLY)
  176154. + return found_vdoa;
  176155. + else if (t->set.mode & VDOA_MODE)
  176156. + return found_vdoa && found_ipu;
  176157. + else
  176158. + return found_ipu;
  176159. +}
  176160. +
  176161. +static void put_vdoa_ipu_res(struct ipu_task_entry *tsk, int vdoa_only)
  176162. +{
  176163. + int ret;
  176164. + int rel_vdoa = 0, rel_ipu = 0;
  176165. + struct ipu_channel_tabel *tbl = &ipu_ch_tbl;
  176166. +
  176167. + mutex_lock(&tbl->lock);
  176168. + if (tsk->set.mode & VDOA_MODE) {
  176169. + if (!tbl->vdoa_used && tsk->vdoa_handle)
  176170. + dev_err(tsk->dev,
  176171. + "ERR no:0x%x,vdoa not used,mode:0x%x\n",
  176172. + tsk->task_no, tsk->set.mode);
  176173. + if (tbl->vdoa_used && tsk->vdoa_handle) {
  176174. + tbl->vdoa_used = 0;
  176175. + vdoa_put_handle(&tsk->vdoa_handle);
  176176. + if (tsk->ipu)
  176177. + tsk->ipu->vdoa_en = 0;
  176178. + rel_vdoa = 1;
  176179. + if (vdoa_only || (tsk->set.task & VDOA_ONLY))
  176180. + goto out;
  176181. + }
  176182. + }
  176183. +
  176184. + tbl->used[tsk->ipu_id][tsk->task_id - 1] = 0;
  176185. + rel_ipu = 1;
  176186. + ret = atomic_inc_return(&tsk->res_free);
  176187. + if (ret == 2)
  176188. + dev_err(tsk->dev,
  176189. + "ERR no:0x%x,rel_vdoa:%d,put ipu twice\n",
  176190. + tsk->task_no, rel_vdoa);
  176191. +out:
  176192. + dev_dbg(tsk->dev,
  176193. + "%s:no:0x%x,rel_vdoa:%d, rel_ipu:%d\n",
  176194. + __func__, tsk->task_no, rel_vdoa, rel_ipu);
  176195. + mutex_unlock(&tbl->lock);
  176196. +}
  176197. +
  176198. +static int get_vdoa_ipu_res(struct ipu_task_entry *t)
  176199. +{
  176200. + int ret;
  176201. + uint32_t found = 0;
  176202. +
  176203. + found = _get_vdoa_ipu_res(t);
  176204. + if (!found) {
  176205. + t->ipu_id = -1;
  176206. + t->ipu = NULL;
  176207. + /* blocking to get resource */
  176208. + ret = atomic_inc_return(&req_cnt);
  176209. + dev_dbg(t->dev,
  176210. + "wait_res:no:0x%x,req_cnt:%d\n", t->task_no, ret);
  176211. + ret = wait_event_timeout(res_waitq, _get_vdoa_ipu_res(t),
  176212. + msecs_to_jiffies(t->timeout - DEF_DELAY_MS));
  176213. + if (ret == 0) {
  176214. + dev_err(t->dev, "ERR[0x%p,no-0x%x] wait_res timeout:%dms!\n",
  176215. + t, t->task_no, t->timeout - DEF_DELAY_MS);
  176216. + ret = -ETIMEDOUT;
  176217. + t->state = STATE_RES_TIMEOUT;
  176218. + goto out;
  176219. + } else {
  176220. + if (!(t->set.task & VDOA_ONLY) && (!t->ipu))
  176221. + dev_err(t->dev,
  176222. + "ERR[no-0x%x] can not get ipu!\n",
  176223. + t->task_no);
  176224. + ret = atomic_read(&req_cnt);
  176225. + if (ret > 0)
  176226. + ret = atomic_dec_return(&req_cnt);
  176227. + else
  176228. + dev_err(t->dev,
  176229. + "ERR[no-0x%x] req_cnt:%d mismatch!\n",
  176230. + t->task_no, ret);
  176231. + dev_dbg(t->dev, "no-0x%x,[0x%p],req_cnt:%d, got_res!\n",
  176232. + t->task_no, t, ret);
  176233. + found = 1;
  176234. + }
  176235. + }
  176236. +
  176237. +out:
  176238. + return found;
  176239. +}
  176240. +
  176241. +static struct ipu_task_entry *create_task_entry(struct ipu_task *task)
  176242. +{
  176243. + struct ipu_task_entry *tsk;
  176244. +
  176245. + tsk = kzalloc(sizeof(struct ipu_task_entry), GFP_KERNEL);
  176246. + if (!tsk)
  176247. + return ERR_PTR(-ENOMEM);
  176248. + kref_init(&tsk->refcount);
  176249. + tsk->state = -EINVAL;
  176250. + tsk->ipu_id = -1;
  176251. + tsk->dev = ipu_dev;
  176252. + tsk->input = task->input;
  176253. + tsk->output = task->output;
  176254. + tsk->overlay_en = task->overlay_en;
  176255. + if (tsk->overlay_en)
  176256. + tsk->overlay = task->overlay;
  176257. + if (task->timeout > DEF_TIMEOUT_MS)
  176258. + tsk->timeout = task->timeout;
  176259. + else
  176260. + tsk->timeout = DEF_TIMEOUT_MS;
  176261. +
  176262. + return tsk;
  176263. +}
  176264. +
  176265. +static void task_mem_free(struct kref *ref)
  176266. +{
  176267. + struct ipu_task_entry *tsk =
  176268. + container_of(ref, struct ipu_task_entry, refcount);
  176269. + kfree(tsk);
  176270. +}
  176271. +
  176272. +int create_split_child_task(struct ipu_split_task *sp_task)
  176273. +{
  176274. + int ret = 0;
  176275. + struct ipu_task_entry *tsk;
  176276. +
  176277. + tsk = create_task_entry(&sp_task->task);
  176278. + if (IS_ERR(tsk))
  176279. + return PTR_ERR(tsk);
  176280. +
  176281. + sp_task->child_task = tsk;
  176282. + tsk->task_no = sp_task->task_no;
  176283. +
  176284. + ret = prepare_task(tsk);
  176285. + if (ret < 0)
  176286. + goto err;
  176287. +
  176288. + tsk->parent = sp_task->parent_task;
  176289. + tsk->set.sp_setting = sp_task->parent_task->set.sp_setting;
  176290. +
  176291. + list_add(&tsk->node, &tsk->parent->split_list);
  176292. + dev_dbg(tsk->dev, "[0x%p] sp_tsk Q list,no-0x%x\n", tsk, tsk->task_no);
  176293. + tsk->state = STATE_QUEUE;
  176294. + CHECK_PERF(&tsk->ts_queue);
  176295. +err:
  176296. + return ret;
  176297. +}
  176298. +
  176299. +static inline int sp_task_check_done(struct ipu_split_task *sp_task,
  176300. + struct ipu_task_entry *parent, int num, int *idx)
  176301. +{
  176302. + int i;
  176303. + int ret = 0;
  176304. + struct ipu_task_entry *tsk;
  176305. + struct mutex *lock = &parent->split_lock;
  176306. +
  176307. + *idx = -EINVAL;
  176308. + mutex_lock(lock);
  176309. + for (i = 0; i < num; i++) {
  176310. + tsk = sp_task[i].child_task;
  176311. + if (tsk && tsk->split_done) {
  176312. + *idx = i;
  176313. + ret = 1;
  176314. + goto out;
  176315. + }
  176316. + }
  176317. +
  176318. +out:
  176319. + mutex_unlock(lock);
  176320. + return ret;
  176321. +}
  176322. +
  176323. +static int create_split_task(
  176324. + int stripe,
  176325. + struct ipu_split_task *sp_task)
  176326. +{
  176327. + struct ipu_task *task = &(sp_task->task);
  176328. + struct ipu_task_entry *t = sp_task->parent_task;
  176329. + int ret;
  176330. +
  176331. + sp_task->task_no |= stripe;
  176332. +
  176333. + task->input = t->input;
  176334. + task->output = t->output;
  176335. + task->overlay_en = t->overlay_en;
  176336. + if (task->overlay_en)
  176337. + task->overlay = t->overlay;
  176338. + task->task_id = t->task_id;
  176339. + if ((t->set.split_mode == RL_SPLIT) ||
  176340. + (t->set.split_mode == UD_SPLIT))
  176341. + task->timeout = t->timeout / 2;
  176342. + else
  176343. + task->timeout = t->timeout / 4;
  176344. +
  176345. + task->input.crop.w = t->set.sp_setting.iw;
  176346. + task->input.crop.h = t->set.sp_setting.ih;
  176347. + if (task->overlay_en) {
  176348. + task->overlay.crop.w = t->set.sp_setting.ow;
  176349. + task->overlay.crop.h = t->set.sp_setting.oh;
  176350. + }
  176351. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  176352. + task->output.crop.w = t->set.sp_setting.oh;
  176353. + task->output.crop.h = t->set.sp_setting.ow;
  176354. + t->set.sp_setting.rl_split_line = t->set.sp_setting.o_bottom_pos;
  176355. + t->set.sp_setting.ud_split_line = t->set.sp_setting.o_right_pos;
  176356. +
  176357. + } else {
  176358. + task->output.crop.w = t->set.sp_setting.ow;
  176359. + task->output.crop.h = t->set.sp_setting.oh;
  176360. + t->set.sp_setting.rl_split_line = t->set.sp_setting.o_right_pos;
  176361. + t->set.sp_setting.ud_split_line = t->set.sp_setting.o_bottom_pos;
  176362. + }
  176363. +
  176364. + if (stripe & LEFT_STRIPE)
  176365. + task->input.crop.pos.x += t->set.sp_setting.i_left_pos;
  176366. + else if (stripe & RIGHT_STRIPE)
  176367. + task->input.crop.pos.x += t->set.sp_setting.i_right_pos;
  176368. + if (stripe & UP_STRIPE)
  176369. + task->input.crop.pos.y += t->set.sp_setting.i_top_pos;
  176370. + else if (stripe & DOWN_STRIPE)
  176371. + task->input.crop.pos.y += t->set.sp_setting.i_bottom_pos;
  176372. +
  176373. + if (task->overlay_en) {
  176374. + if (stripe & LEFT_STRIPE)
  176375. + task->overlay.crop.pos.x += t->set.sp_setting.o_left_pos;
  176376. + else if (stripe & RIGHT_STRIPE)
  176377. + task->overlay.crop.pos.x += t->set.sp_setting.o_right_pos;
  176378. + if (stripe & UP_STRIPE)
  176379. + task->overlay.crop.pos.y += t->set.sp_setting.o_top_pos;
  176380. + else if (stripe & DOWN_STRIPE)
  176381. + task->overlay.crop.pos.y += t->set.sp_setting.o_bottom_pos;
  176382. + }
  176383. +
  176384. + switch (t->output.rotate) {
  176385. + case IPU_ROTATE_NONE:
  176386. + if (stripe & LEFT_STRIPE)
  176387. + task->output.crop.pos.x += t->set.sp_setting.o_left_pos;
  176388. + else if (stripe & RIGHT_STRIPE)
  176389. + task->output.crop.pos.x += t->set.sp_setting.o_right_pos;
  176390. + if (stripe & UP_STRIPE)
  176391. + task->output.crop.pos.y += t->set.sp_setting.o_top_pos;
  176392. + else if (stripe & DOWN_STRIPE)
  176393. + task->output.crop.pos.y += t->set.sp_setting.o_bottom_pos;
  176394. + break;
  176395. + case IPU_ROTATE_VERT_FLIP:
  176396. + if (stripe & LEFT_STRIPE)
  176397. + task->output.crop.pos.x += t->set.sp_setting.o_left_pos;
  176398. + else if (stripe & RIGHT_STRIPE)
  176399. + task->output.crop.pos.x += t->set.sp_setting.o_right_pos;
  176400. + if (stripe & UP_STRIPE)
  176401. + task->output.crop.pos.y =
  176402. + t->output.crop.pos.y + t->output.crop.h
  176403. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  176404. + else if (stripe & DOWN_STRIPE)
  176405. + task->output.crop.pos.y =
  176406. + t->output.crop.pos.y + t->output.crop.h
  176407. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  176408. + break;
  176409. + case IPU_ROTATE_HORIZ_FLIP:
  176410. + if (stripe & LEFT_STRIPE)
  176411. + task->output.crop.pos.x =
  176412. + t->output.crop.pos.x + t->output.crop.w
  176413. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  176414. + else if (stripe & RIGHT_STRIPE)
  176415. + task->output.crop.pos.x =
  176416. + t->output.crop.pos.x + t->output.crop.w
  176417. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  176418. + if (stripe & UP_STRIPE)
  176419. + task->output.crop.pos.y += t->set.sp_setting.o_top_pos;
  176420. + else if (stripe & DOWN_STRIPE)
  176421. + task->output.crop.pos.y += t->set.sp_setting.o_bottom_pos;
  176422. + break;
  176423. + case IPU_ROTATE_180:
  176424. + if (stripe & LEFT_STRIPE)
  176425. + task->output.crop.pos.x =
  176426. + t->output.crop.pos.x + t->output.crop.w
  176427. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  176428. + else if (stripe & RIGHT_STRIPE)
  176429. + task->output.crop.pos.x =
  176430. + t->output.crop.pos.x + t->output.crop.w
  176431. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  176432. + if (stripe & UP_STRIPE)
  176433. + task->output.crop.pos.y =
  176434. + t->output.crop.pos.y + t->output.crop.h
  176435. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  176436. + else if (stripe & DOWN_STRIPE)
  176437. + task->output.crop.pos.y =
  176438. + t->output.crop.pos.y + t->output.crop.h
  176439. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  176440. + break;
  176441. + case IPU_ROTATE_90_RIGHT:
  176442. + if (stripe & UP_STRIPE)
  176443. + task->output.crop.pos.x =
  176444. + t->output.crop.pos.x + t->output.crop.w
  176445. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  176446. + else if (stripe & DOWN_STRIPE)
  176447. + task->output.crop.pos.x =
  176448. + t->output.crop.pos.x + t->output.crop.w
  176449. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  176450. + if (stripe & LEFT_STRIPE)
  176451. + task->output.crop.pos.y += t->set.sp_setting.o_left_pos;
  176452. + else if (stripe & RIGHT_STRIPE)
  176453. + task->output.crop.pos.y += t->set.sp_setting.o_right_pos;
  176454. + break;
  176455. + case IPU_ROTATE_90_RIGHT_HFLIP:
  176456. + if (stripe & UP_STRIPE)
  176457. + task->output.crop.pos.x += t->set.sp_setting.o_top_pos;
  176458. + else if (stripe & DOWN_STRIPE)
  176459. + task->output.crop.pos.x += t->set.sp_setting.o_bottom_pos;
  176460. + if (stripe & LEFT_STRIPE)
  176461. + task->output.crop.pos.y += t->set.sp_setting.o_left_pos;
  176462. + else if (stripe & RIGHT_STRIPE)
  176463. + task->output.crop.pos.y += t->set.sp_setting.o_right_pos;
  176464. + break;
  176465. + case IPU_ROTATE_90_RIGHT_VFLIP:
  176466. + if (stripe & UP_STRIPE)
  176467. + task->output.crop.pos.x =
  176468. + t->output.crop.pos.x + t->output.crop.w
  176469. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  176470. + else if (stripe & DOWN_STRIPE)
  176471. + task->output.crop.pos.x =
  176472. + t->output.crop.pos.x + t->output.crop.w
  176473. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  176474. + if (stripe & LEFT_STRIPE)
  176475. + task->output.crop.pos.y =
  176476. + t->output.crop.pos.y + t->output.crop.h
  176477. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  176478. + else if (stripe & RIGHT_STRIPE)
  176479. + task->output.crop.pos.y =
  176480. + t->output.crop.pos.y + t->output.crop.h
  176481. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  176482. + break;
  176483. + case IPU_ROTATE_90_LEFT:
  176484. + if (stripe & UP_STRIPE)
  176485. + task->output.crop.pos.x += t->set.sp_setting.o_top_pos;
  176486. + else if (stripe & DOWN_STRIPE)
  176487. + task->output.crop.pos.x += t->set.sp_setting.o_bottom_pos;
  176488. + if (stripe & LEFT_STRIPE)
  176489. + task->output.crop.pos.y =
  176490. + t->output.crop.pos.y + t->output.crop.h
  176491. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  176492. + else if (stripe & RIGHT_STRIPE)
  176493. + task->output.crop.pos.y =
  176494. + t->output.crop.pos.y + t->output.crop.h
  176495. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  176496. + break;
  176497. + default:
  176498. + dev_err(t->dev, "ERR:should not be here\n");
  176499. + break;
  176500. + }
  176501. +
  176502. + ret = create_split_child_task(sp_task);
  176503. + if (ret < 0)
  176504. + dev_err(t->dev, "ERR:create_split_child_task() ret:%d\n", ret);
  176505. + return ret;
  176506. +}
  176507. +
  176508. +static int queue_split_task(struct ipu_task_entry *t,
  176509. + struct ipu_split_task *sp_task, uint32_t size)
  176510. +{
  176511. + int err[4];
  176512. + int ret = 0;
  176513. + int i, j;
  176514. + struct ipu_task_entry *tsk = NULL;
  176515. + struct mutex *lock = &t->split_lock;
  176516. + struct mutex *vdic_lock = &t->vdic_lock;
  176517. +
  176518. + dev_dbg(t->dev, "Split task 0x%p, no-0x%x, size:%d\n",
  176519. + t, t->task_no, size);
  176520. + mutex_init(lock);
  176521. + mutex_init(vdic_lock);
  176522. + init_waitqueue_head(&t->split_waitq);
  176523. + INIT_LIST_HEAD(&t->split_list);
  176524. + for (j = 0; j < size; j++) {
  176525. + memset(&sp_task[j], 0, sizeof(*sp_task));
  176526. + sp_task[j].parent_task = t;
  176527. + sp_task[j].task_no = t->task_no;
  176528. + }
  176529. +
  176530. + if (t->set.split_mode == RL_SPLIT) {
  176531. + i = 0;
  176532. + err[i] = create_split_task(RIGHT_STRIPE, &sp_task[i]);
  176533. + if (err[i] < 0)
  176534. + goto err_start;
  176535. + i = 1;
  176536. + err[i] = create_split_task(LEFT_STRIPE, &sp_task[i]);
  176537. + } else if (t->set.split_mode == UD_SPLIT) {
  176538. + i = 0;
  176539. + err[i] = create_split_task(DOWN_STRIPE, &sp_task[i]);
  176540. + if (err[i] < 0)
  176541. + goto err_start;
  176542. + i = 1;
  176543. + err[i] = create_split_task(UP_STRIPE, &sp_task[i]);
  176544. + } else {
  176545. + i = 0;
  176546. + err[i] = create_split_task(RIGHT_STRIPE | DOWN_STRIPE, &sp_task[i]);
  176547. + if (err[i] < 0)
  176548. + goto err_start;
  176549. + i = 1;
  176550. + err[i] = create_split_task(LEFT_STRIPE | DOWN_STRIPE, &sp_task[i]);
  176551. + if (err[i] < 0)
  176552. + goto err_start;
  176553. + i = 2;
  176554. + err[i] = create_split_task(RIGHT_STRIPE | UP_STRIPE, &sp_task[i]);
  176555. + if (err[i] < 0)
  176556. + goto err_start;
  176557. + i = 3;
  176558. + err[i] = create_split_task(LEFT_STRIPE | UP_STRIPE, &sp_task[i]);
  176559. + }
  176560. +
  176561. +err_start:
  176562. + for (j = 0; j < (i + 1); j++) {
  176563. + if (err[j] < 0) {
  176564. + if (sp_task[j].child_task)
  176565. + dev_err(t->dev,
  176566. + "sp_task[%d],no-0x%x fail state:%d, queue err:%d.\n",
  176567. + j, sp_task[j].child_task->task_no,
  176568. + sp_task[j].child_task->state, err[j]);
  176569. + goto err_exit;
  176570. + }
  176571. + dev_dbg(t->dev, "[0x%p] sp_task[%d], no-0x%x state:%s, queue ret:%d.\n",
  176572. + sp_task[j].child_task, j, sp_task[j].child_task->task_no,
  176573. + state_msg[sp_task[j].child_task->state].msg, err[j]);
  176574. + }
  176575. +
  176576. + return ret;
  176577. +
  176578. +err_exit:
  176579. + for (j = 0; j < (i + 1); j++) {
  176580. + if (err[j] < 0 && !ret)
  176581. + ret = err[j];
  176582. + tsk = sp_task[j].child_task;
  176583. + if (!tsk)
  176584. + continue;
  176585. + kfree(tsk);
  176586. + }
  176587. + t->state = STATE_ERR;
  176588. + return ret;
  176589. +
  176590. +}
  176591. +
  176592. +static int init_tiled_buf(struct ipu_soc *ipu, struct ipu_task_entry *t,
  176593. + ipu_channel_t channel, uint32_t ch_type)
  176594. +{
  176595. + int ret = 0;
  176596. + int i;
  176597. + uint32_t ipu_fmt;
  176598. + dma_addr_t inbuf_base = 0;
  176599. + u32 field_size;
  176600. + struct vdoa_params param;
  176601. + struct vdoa_ipu_buf buf;
  176602. + struct ipu_soc *ipu_idx;
  176603. + u32 ipu_stride, obuf_size;
  176604. + u32 height, width;
  176605. + ipu_buffer_t type;
  176606. +
  176607. + if ((IPU_PIX_FMT_YUYV != t->output.format) &&
  176608. + (IPU_PIX_FMT_NV12 != t->output.format)) {
  176609. + dev_err(t->dev, "ERR:[0x%d] output format\n", t->task_no);
  176610. + return -EINVAL;
  176611. + }
  176612. +
  176613. + memset(&param, 0, sizeof(param));
  176614. + /* init channel tiled bufs */
  176615. + if (deinterlace_3_field(t) &&
  176616. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  176617. + field_size = tiled_filed_size(t);
  176618. + if (INPUT_CHAN_VDI_P == ch_type) {
  176619. + inbuf_base = t->input.paddr + field_size;
  176620. + param.vfield_buf.prev_veba = inbuf_base + t->set.i_off;
  176621. + } else if (INPUT_CHAN == ch_type) {
  176622. + inbuf_base = t->input.paddr_n;
  176623. + param.vfield_buf.cur_veba = inbuf_base + t->set.i_off;
  176624. + } else if (INPUT_CHAN_VDI_N == ch_type) {
  176625. + inbuf_base = t->input.paddr_n + field_size;
  176626. + param.vfield_buf.next_veba = inbuf_base + t->set.i_off;
  176627. + } else
  176628. + return -EINVAL;
  176629. + height = t->input.crop.h >> 1; /* field format for vdoa */
  176630. + width = t->input.crop.w;
  176631. + param.vfield_buf.vubo = t->set.i_uoff;
  176632. + param.interlaced = 1;
  176633. + param.scan_order = 1;
  176634. + type = IPU_INPUT_BUFFER;
  176635. + } else if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) &&
  176636. + (INPUT_CHAN == ch_type)) {
  176637. + height = t->input.crop.h;
  176638. + width = t->input.crop.w;
  176639. + param.vframe_buf.veba = t->input.paddr + t->set.i_off;
  176640. + param.vframe_buf.vubo = t->set.i_uoff;
  176641. + type = IPU_INPUT_BUFFER;
  176642. + } else
  176643. + return -EINVAL;
  176644. +
  176645. + param.band_mode = (t->set.mode & VDOA_BAND_MODE) ? 1 : 0;
  176646. + if (param.band_mode && (t->set.band_lines != 3) &&
  176647. + (t->set.band_lines != 4) && (t->set.band_lines != 5))
  176648. + return -EINVAL;
  176649. + else if (param.band_mode)
  176650. + param.band_lines = (1 << t->set.band_lines);
  176651. + for (i = 0; i < max_ipu_no; i++) {
  176652. + ipu_idx = ipu_get_soc(i);
  176653. + if (!IS_ERR(ipu_idx) && ipu_idx == ipu)
  176654. + break;
  176655. + }
  176656. + if (t->set.task & VDOA_ONLY)
  176657. + /* dummy, didn't need ipu res */
  176658. + i = 0;
  176659. + if (max_ipu_no == i) {
  176660. + dev_err(t->dev, "ERR:[0x%p] get ipu num\n", t);
  176661. + return -EINVAL;
  176662. + }
  176663. +
  176664. + param.ipu_num = i;
  176665. + param.vpu_stride = t->input.width;
  176666. + param.height = height;
  176667. + param.width = width;
  176668. + if (IPU_PIX_FMT_NV12 == t->output.format)
  176669. + param.pfs = VDOA_PFS_NV12;
  176670. + else
  176671. + param.pfs = VDOA_PFS_YUYV;
  176672. + ipu_fmt = (param.pfs == VDOA_PFS_YUYV) ? IPU_PIX_FMT_YUYV :
  176673. + IPU_PIX_FMT_NV12;
  176674. + ipu_stride = param.width * bytes_per_pixel(ipu_fmt);
  176675. + obuf_size = PAGE_ALIGN(param.width * param.height *
  176676. + fmt_to_bpp(ipu_fmt)/8);
  176677. + dev_dbg(t->dev, "band_mode:%d, band_lines:%d\n",
  176678. + param.band_mode, param.band_lines);
  176679. + if (!param.band_mode) {
  176680. + /* note: if only for tiled -> raster convert and
  176681. + no other post-processing, we don't need alloc buf
  176682. + and use output buffer directly.
  176683. + */
  176684. + if (t->set.task & VDOA_ONLY)
  176685. + param.ieba0 = t->output.paddr;
  176686. + else {
  176687. + dev_err(t->dev, "ERR:[0x%d] vdoa task\n", t->task_no);
  176688. + return -EINVAL;
  176689. + }
  176690. + } else {
  176691. + if (IPU_PIX_FMT_TILED_NV12F != t->input.format) {
  176692. + dev_err(t->dev, "ERR [0x%d] vdoa task\n", t->task_no);
  176693. + return -EINVAL;
  176694. + }
  176695. + }
  176696. + ret = vdoa_setup(t->vdoa_handle, &param);
  176697. + if (ret)
  176698. + goto done;
  176699. + vdoa_get_output_buf(t->vdoa_handle, &buf);
  176700. + if (t->set.task & VDOA_ONLY)
  176701. + goto done;
  176702. +
  176703. + ret = ipu_init_channel_buffer(ipu,
  176704. + channel,
  176705. + type,
  176706. + ipu_fmt,
  176707. + width,
  176708. + height,
  176709. + ipu_stride,
  176710. + IPU_ROTATE_NONE,
  176711. + buf.ieba0,
  176712. + buf.ieba1,
  176713. + 0,
  176714. + buf.iubo,
  176715. + 0);
  176716. + if (ret < 0) {
  176717. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  176718. + goto done;
  176719. + }
  176720. +
  176721. + if (param.band_mode) {
  176722. + ret = ipu_set_channel_bandmode(ipu, channel,
  176723. + type, t->set.band_lines);
  176724. + if (ret < 0) {
  176725. + t->state = STATE_INIT_CHAN_BAND_FAIL;
  176726. + goto done;
  176727. + }
  176728. + }
  176729. +done:
  176730. + return ret;
  176731. +}
  176732. +
  176733. +static int init_tiled_ch_bufs(struct ipu_soc *ipu, struct ipu_task_entry *t)
  176734. +{
  176735. + int ret = 0;
  176736. +
  176737. + if (IPU_PIX_FMT_TILED_NV12 == t->input.format) {
  176738. + ret = init_tiled_buf(ipu, t, t->set.ic_chan, INPUT_CHAN);
  176739. + CHECK_RETCODE(ret < 0, "init tiled_ch", t->state, done, ret);
  176740. + } else if (IPU_PIX_FMT_TILED_NV12F == t->input.format) {
  176741. + ret = init_tiled_buf(ipu, t, t->set.ic_chan, INPUT_CHAN);
  176742. + CHECK_RETCODE(ret < 0, "init tiled_ch-c", t->state, done, ret);
  176743. + ret = init_tiled_buf(ipu, t, t->set.vdi_ic_p_chan,
  176744. + INPUT_CHAN_VDI_P);
  176745. + CHECK_RETCODE(ret < 0, "init tiled_ch-p", t->state, done, ret);
  176746. + ret = init_tiled_buf(ipu, t, t->set.vdi_ic_n_chan,
  176747. + INPUT_CHAN_VDI_N);
  176748. + CHECK_RETCODE(ret < 0, "init tiled_ch-n", t->state, done, ret);
  176749. + } else {
  176750. + ret = -EINVAL;
  176751. + dev_err(t->dev, "ERR[no-0x%x] invalid fmt:0x%x!\n",
  176752. + t->task_no, t->input.format);
  176753. + }
  176754. +
  176755. +done:
  176756. + return ret;
  176757. +}
  176758. +
  176759. +static int init_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
  176760. +{
  176761. + int ret = 0;
  176762. + ipu_channel_params_t params;
  176763. + dma_addr_t inbuf = 0, ovbuf = 0, ov_alp_buf = 0;
  176764. + dma_addr_t inbuf_p = 0, inbuf_n = 0;
  176765. + dma_addr_t outbuf = 0;
  176766. + int out_uoff = 0, out_voff = 0, out_rot;
  176767. + int out_w = 0, out_h = 0, out_stride;
  176768. + int out_fmt;
  176769. + u32 vdi_frame_idx = 0;
  176770. +
  176771. + memset(&params, 0, sizeof(params));
  176772. +
  176773. + /* is it need link a rot channel */
  176774. + if (ic_and_rot(t->set.mode)) {
  176775. + outbuf = t->set.r_paddr;
  176776. + out_w = t->set.r_width;
  176777. + out_h = t->set.r_height;
  176778. + out_stride = t->set.r_stride;
  176779. + out_fmt = t->set.r_fmt;
  176780. + out_uoff = 0;
  176781. + out_voff = 0;
  176782. + out_rot = IPU_ROTATE_NONE;
  176783. + } else {
  176784. + outbuf = t->output.paddr + t->set.o_off;
  176785. + out_w = t->output.crop.w;
  176786. + out_h = t->output.crop.h;
  176787. + out_stride = t->set.ostride;
  176788. + out_fmt = t->output.format;
  176789. + out_uoff = t->set.o_uoff;
  176790. + out_voff = t->set.o_voff;
  176791. + out_rot = t->output.rotate;
  176792. + }
  176793. +
  176794. + /* settings */
  176795. + params.mem_prp_vf_mem.in_width = t->input.crop.w;
  176796. + params.mem_prp_vf_mem.out_width = out_w;
  176797. + params.mem_prp_vf_mem.in_height = t->input.crop.h;
  176798. + params.mem_prp_vf_mem.out_height = out_h;
  176799. + params.mem_prp_vf_mem.in_pixel_fmt = t->input.format;
  176800. + params.mem_prp_vf_mem.out_pixel_fmt = out_fmt;
  176801. + params.mem_prp_vf_mem.motion_sel = t->input.deinterlace.motion;
  176802. +
  176803. + params.mem_prp_vf_mem.outh_resize_ratio =
  176804. + t->set.sp_setting.outh_resize_ratio;
  176805. + params.mem_prp_vf_mem.outv_resize_ratio =
  176806. + t->set.sp_setting.outv_resize_ratio;
  176807. +
  176808. + if (t->overlay_en) {
  176809. + params.mem_prp_vf_mem.in_g_pixel_fmt = t->overlay.format;
  176810. + params.mem_prp_vf_mem.graphics_combine_en = 1;
  176811. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_GLOBAL)
  176812. + params.mem_prp_vf_mem.global_alpha_en = 1;
  176813. + else if (t->overlay.alpha.loc_alp_paddr)
  176814. + params.mem_prp_vf_mem.alpha_chan_en = 1;
  176815. + /* otherwise, alpha bending per pixel is used. */
  176816. + params.mem_prp_vf_mem.alpha = t->overlay.alpha.gvalue;
  176817. + if (t->overlay.colorkey.enable) {
  176818. + params.mem_prp_vf_mem.key_color_en = 1;
  176819. + params.mem_prp_vf_mem.key_color = t->overlay.colorkey.value;
  176820. + }
  176821. + }
  176822. +
  176823. + if (t->input.deinterlace.enable) {
  176824. + if (t->input.deinterlace.field_fmt & IPU_DEINTERLACE_FIELD_MASK)
  176825. + params.mem_prp_vf_mem.field_fmt =
  176826. + IPU_DEINTERLACE_FIELD_BOTTOM;
  176827. + else
  176828. + params.mem_prp_vf_mem.field_fmt =
  176829. + IPU_DEINTERLACE_FIELD_TOP;
  176830. +
  176831. + if (t->input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN)
  176832. + vdi_frame_idx = t->input.deinterlace.field_fmt &
  176833. + IPU_DEINTERLACE_RATE_FRAME1;
  176834. + }
  176835. +
  176836. + if (t->set.mode & VDOA_MODE)
  176837. + ipu->vdoa_en = 1;
  176838. +
  176839. + /* init channels */
  176840. + if (!(t->set.task & VDOA_ONLY)) {
  176841. + ret = ipu_init_channel(ipu, t->set.ic_chan, &params);
  176842. + if (ret < 0) {
  176843. + t->state = STATE_INIT_CHAN_FAIL;
  176844. + goto done;
  176845. + }
  176846. + }
  176847. +
  176848. + if (deinterlace_3_field(t)) {
  176849. + ret = ipu_init_channel(ipu, t->set.vdi_ic_p_chan, &params);
  176850. + if (ret < 0) {
  176851. + t->state = STATE_INIT_CHAN_FAIL;
  176852. + goto done;
  176853. + }
  176854. + ret = ipu_init_channel(ipu, t->set.vdi_ic_n_chan, &params);
  176855. + if (ret < 0) {
  176856. + t->state = STATE_INIT_CHAN_FAIL;
  176857. + goto done;
  176858. + }
  176859. + }
  176860. +
  176861. + /* init channel bufs */
  176862. + if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  176863. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  176864. + ret = init_tiled_ch_bufs(ipu, t);
  176865. + if (ret < 0)
  176866. + goto done;
  176867. + } else {
  176868. + if ((deinterlace_3_field(t)) &&
  176869. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  176870. + if (params.mem_prp_vf_mem.field_fmt ==
  176871. + IPU_DEINTERLACE_FIELD_TOP) {
  176872. + if (vdi_frame_idx) {
  176873. + inbuf_p = t->input.paddr + t->set.istride +
  176874. + t->set.i_off;
  176875. + inbuf = t->input.paddr_n + t->set.i_off;
  176876. + inbuf_n = t->input.paddr_n + t->set.istride +
  176877. + t->set.i_off;
  176878. + params.mem_prp_vf_mem.field_fmt =
  176879. + IPU_DEINTERLACE_FIELD_BOTTOM;
  176880. + } else {
  176881. + inbuf_p = t->input.paddr + t->set.i_off;
  176882. + inbuf = t->input.paddr + t->set.istride + t->set.i_off;
  176883. + inbuf_n = t->input.paddr_n + t->set.i_off;
  176884. + }
  176885. + } else {
  176886. + if (vdi_frame_idx) {
  176887. + inbuf_p = t->input.paddr + t->set.i_off;
  176888. + inbuf = t->input.paddr_n + t->set.istride + t->set.i_off;
  176889. + inbuf_n = t->input.paddr_n + t->set.i_off;
  176890. + params.mem_prp_vf_mem.field_fmt =
  176891. + IPU_DEINTERLACE_FIELD_TOP;
  176892. + } else {
  176893. + inbuf_p = t->input.paddr + t->set.istride +
  176894. + t->set.i_off;
  176895. + inbuf = t->input.paddr + t->set.i_off;
  176896. + inbuf_n = t->input.paddr_n + t->set.istride +
  176897. + t->set.i_off;
  176898. + }
  176899. + }
  176900. + } else {
  176901. + if (t->input.deinterlace.enable) {
  176902. + if (params.mem_prp_vf_mem.field_fmt ==
  176903. + IPU_DEINTERLACE_FIELD_TOP) {
  176904. + if (vdi_frame_idx) {
  176905. + inbuf = t->input.paddr + t->set.istride + t->set.i_off;
  176906. + params.mem_prp_vf_mem.field_fmt =
  176907. + IPU_DEINTERLACE_FIELD_BOTTOM;
  176908. + } else
  176909. + inbuf = t->input.paddr + t->set.i_off;
  176910. + } else {
  176911. + if (vdi_frame_idx) {
  176912. + inbuf = t->input.paddr + t->set.i_off;
  176913. + params.mem_prp_vf_mem.field_fmt =
  176914. + IPU_DEINTERLACE_FIELD_TOP;
  176915. + } else
  176916. + inbuf = t->input.paddr + t->set.istride + t->set.i_off;
  176917. + }
  176918. + } else
  176919. + inbuf = t->input.paddr + t->set.i_off;
  176920. + }
  176921. +
  176922. + if (t->overlay_en)
  176923. + ovbuf = t->overlay.paddr + t->set.ov_off;
  176924. + }
  176925. + if (t->overlay_en && (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL))
  176926. + ov_alp_buf = t->overlay.alpha.loc_alp_paddr
  176927. + + t->set.ov_alpha_off;
  176928. +
  176929. + if ((IPU_PIX_FMT_TILED_NV12 != t->input.format) &&
  176930. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  176931. + ret = ipu_init_channel_buffer(ipu,
  176932. + t->set.ic_chan,
  176933. + IPU_INPUT_BUFFER,
  176934. + t->input.format,
  176935. + t->input.crop.w,
  176936. + t->input.crop.h,
  176937. + t->set.istride,
  176938. + IPU_ROTATE_NONE,
  176939. + inbuf,
  176940. + 0,
  176941. + 0,
  176942. + t->set.i_uoff,
  176943. + t->set.i_voff);
  176944. + if (ret < 0) {
  176945. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  176946. + goto done;
  176947. + }
  176948. + }
  176949. + if (deinterlace_3_field(t) &&
  176950. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  176951. + ret = ipu_init_channel_buffer(ipu,
  176952. + t->set.vdi_ic_p_chan,
  176953. + IPU_INPUT_BUFFER,
  176954. + t->input.format,
  176955. + t->input.crop.w,
  176956. + t->input.crop.h,
  176957. + t->set.istride,
  176958. + IPU_ROTATE_NONE,
  176959. + inbuf_p,
  176960. + 0,
  176961. + 0,
  176962. + t->set.i_uoff,
  176963. + t->set.i_voff);
  176964. + if (ret < 0) {
  176965. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  176966. + goto done;
  176967. + }
  176968. +
  176969. + ret = ipu_init_channel_buffer(ipu,
  176970. + t->set.vdi_ic_n_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_n,
  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. +
  176988. + if (t->overlay_en) {
  176989. + ret = ipu_init_channel_buffer(ipu,
  176990. + t->set.ic_chan,
  176991. + IPU_GRAPH_IN_BUFFER,
  176992. + t->overlay.format,
  176993. + t->overlay.crop.w,
  176994. + t->overlay.crop.h,
  176995. + t->set.ovstride,
  176996. + IPU_ROTATE_NONE,
  176997. + ovbuf,
  176998. + 0,
  176999. + 0,
  177000. + t->set.ov_uoff,
  177001. + t->set.ov_voff);
  177002. + if (ret < 0) {
  177003. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177004. + goto done;
  177005. + }
  177006. + }
  177007. +
  177008. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  177009. + ret = ipu_init_channel_buffer(ipu,
  177010. + t->set.ic_chan,
  177011. + IPU_ALPHA_IN_BUFFER,
  177012. + IPU_PIX_FMT_GENERIC,
  177013. + t->overlay.crop.w,
  177014. + t->overlay.crop.h,
  177015. + t->set.ov_alpha_stride,
  177016. + IPU_ROTATE_NONE,
  177017. + ov_alp_buf,
  177018. + 0,
  177019. + 0,
  177020. + 0, 0);
  177021. + if (ret < 0) {
  177022. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177023. + goto done;
  177024. + }
  177025. + }
  177026. +
  177027. + if (!(t->set.task & VDOA_ONLY)) {
  177028. + ret = ipu_init_channel_buffer(ipu,
  177029. + t->set.ic_chan,
  177030. + IPU_OUTPUT_BUFFER,
  177031. + out_fmt,
  177032. + out_w,
  177033. + out_h,
  177034. + out_stride,
  177035. + out_rot,
  177036. + outbuf,
  177037. + 0,
  177038. + 0,
  177039. + out_uoff,
  177040. + out_voff);
  177041. + if (ret < 0) {
  177042. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177043. + goto done;
  177044. + }
  177045. + }
  177046. +
  177047. + if ((t->set.mode & VDOA_BAND_MODE) && (t->set.task & VDI_VF)) {
  177048. + ret = ipu_link_channels(ipu, MEM_VDOA_MEM, t->set.ic_chan);
  177049. + CHECK_RETCODE(ret < 0, "ipu_link_ch vdoa_ic",
  177050. + STATE_LINK_CHAN_FAIL, done, ret);
  177051. + }
  177052. +
  177053. +done:
  177054. + return ret;
  177055. +}
  177056. +
  177057. +static void uninit_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
  177058. +{
  177059. + int ret;
  177060. +
  177061. + if ((t->set.mode & VDOA_BAND_MODE) && (t->set.task & VDI_VF)) {
  177062. + ret = ipu_unlink_channels(ipu, MEM_VDOA_MEM, t->set.ic_chan);
  177063. + CHECK_RETCODE_CONT(ret < 0, "ipu_unlink_ch vdoa_ic",
  177064. + STATE_UNLINK_CHAN_FAIL, ret);
  177065. + }
  177066. + ipu_uninit_channel(ipu, t->set.ic_chan);
  177067. + if (deinterlace_3_field(t)) {
  177068. + ipu_uninit_channel(ipu, t->set.vdi_ic_p_chan);
  177069. + ipu_uninit_channel(ipu, t->set.vdi_ic_n_chan);
  177070. + }
  177071. +}
  177072. +
  177073. +static int init_rot(struct ipu_soc *ipu, struct ipu_task_entry *t)
  177074. +{
  177075. + int ret = 0;
  177076. + dma_addr_t inbuf = 0, outbuf = 0;
  177077. + int in_uoff = 0, in_voff = 0;
  177078. + int in_fmt, in_width, in_height, in_stride;
  177079. +
  177080. + /* init channel */
  177081. + ret = ipu_init_channel(ipu, t->set.rot_chan, NULL);
  177082. + if (ret < 0) {
  177083. + t->state = STATE_INIT_CHAN_FAIL;
  177084. + goto done;
  177085. + }
  177086. +
  177087. + /* init channel buf */
  177088. + /* is it need link to a ic channel */
  177089. + if (ic_and_rot(t->set.mode)) {
  177090. + in_fmt = t->set.r_fmt;
  177091. + in_width = t->set.r_width;
  177092. + in_height = t->set.r_height;
  177093. + in_stride = t->set.r_stride;
  177094. + inbuf = t->set.r_paddr;
  177095. + in_uoff = 0;
  177096. + in_voff = 0;
  177097. + } else {
  177098. + in_fmt = t->input.format;
  177099. + in_width = t->input.crop.w;
  177100. + in_height = t->input.crop.h;
  177101. + in_stride = t->set.istride;
  177102. + inbuf = t->input.paddr + t->set.i_off;
  177103. + in_uoff = t->set.i_uoff;
  177104. + in_voff = t->set.i_voff;
  177105. + }
  177106. + outbuf = t->output.paddr + t->set.o_off;
  177107. +
  177108. + ret = ipu_init_channel_buffer(ipu,
  177109. + t->set.rot_chan,
  177110. + IPU_INPUT_BUFFER,
  177111. + in_fmt,
  177112. + in_width,
  177113. + in_height,
  177114. + in_stride,
  177115. + t->output.rotate,
  177116. + inbuf,
  177117. + 0,
  177118. + 0,
  177119. + in_uoff,
  177120. + in_voff);
  177121. + if (ret < 0) {
  177122. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177123. + goto done;
  177124. + }
  177125. +
  177126. + ret = ipu_init_channel_buffer(ipu,
  177127. + t->set.rot_chan,
  177128. + IPU_OUTPUT_BUFFER,
  177129. + t->output.format,
  177130. + t->output.crop.w,
  177131. + t->output.crop.h,
  177132. + t->set.ostride,
  177133. + IPU_ROTATE_NONE,
  177134. + outbuf,
  177135. + 0,
  177136. + 0,
  177137. + t->set.o_uoff,
  177138. + t->set.o_voff);
  177139. + if (ret < 0) {
  177140. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  177141. + goto done;
  177142. + }
  177143. +
  177144. +done:
  177145. + return ret;
  177146. +}
  177147. +
  177148. +static void uninit_rot(struct ipu_soc *ipu, struct ipu_task_entry *t)
  177149. +{
  177150. + ipu_uninit_channel(ipu, t->set.rot_chan);
  177151. +}
  177152. +
  177153. +static int get_irq(struct ipu_task_entry *t)
  177154. +{
  177155. + int irq;
  177156. + ipu_channel_t chan;
  177157. +
  177158. + if (only_ic(t->set.mode))
  177159. + chan = t->set.ic_chan;
  177160. + else
  177161. + chan = t->set.rot_chan;
  177162. +
  177163. + switch (chan) {
  177164. + case MEM_ROT_VF_MEM:
  177165. + irq = IPU_IRQ_PRP_VF_ROT_OUT_EOF;
  177166. + break;
  177167. + case MEM_ROT_PP_MEM:
  177168. + irq = IPU_IRQ_PP_ROT_OUT_EOF;
  177169. + break;
  177170. + case MEM_VDI_PRP_VF_MEM:
  177171. + case MEM_PRP_VF_MEM:
  177172. + irq = IPU_IRQ_PRP_VF_OUT_EOF;
  177173. + break;
  177174. + case MEM_PP_MEM:
  177175. + irq = IPU_IRQ_PP_OUT_EOF;
  177176. + break;
  177177. + case MEM_VDI_MEM:
  177178. + irq = IPU_IRQ_VDIC_OUT_EOF;
  177179. + break;
  177180. + default:
  177181. + irq = -EINVAL;
  177182. + }
  177183. +
  177184. + return irq;
  177185. +}
  177186. +
  177187. +static irqreturn_t task_irq_handler(int irq, void *dev_id)
  177188. +{
  177189. + struct ipu_task_entry *prev_tsk = dev_id;
  177190. +
  177191. + CHECK_PERF(&prev_tsk->ts_inirq);
  177192. + complete(&prev_tsk->irq_comp);
  177193. + dev_dbg(prev_tsk->dev, "[0x%p] no-0x%x in-irq!",
  177194. + prev_tsk, prev_tsk->task_no);
  177195. +
  177196. + return IRQ_HANDLED;
  177197. +}
  177198. +
  177199. +/* Fix deinterlace up&down split mode medium line */
  177200. +static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
  177201. +{
  177202. + u32 vdi_size;
  177203. + u32 vdi_save_lines;
  177204. + u32 stripe_mode;
  177205. + u32 task_no;
  177206. + u32 i, offset_addr;
  177207. + u32 line_size;
  177208. + unsigned char *base_off;
  177209. + struct ipu_task_entry *parent = t->parent;
  177210. + struct mutex *lock = &parent->vdic_lock;
  177211. +
  177212. + if (!parent) {
  177213. + dev_err(t->dev, "ERR[0x%x]invalid parent\n", t->task_no);
  177214. + return;
  177215. + }
  177216. + mutex_lock(lock);
  177217. + stripe_mode = t->task_no & 0xf;
  177218. + task_no = t->task_no >> 4;
  177219. +
  177220. + /* Save both luma and chroma part for interleaved YUV(e.g. YUYV).
  177221. + * Save luma part for non-interleaved and partial-interleaved
  177222. + * YUV format (e.g NV12 and YV12). */
  177223. + if (t->output.format == IPU_PIX_FMT_YUYV ||
  177224. + t->output.format == IPU_PIX_FMT_UYVY)
  177225. + line_size = t->output.crop.w * fmt_to_bpp(t->output.format)/8;
  177226. + else
  177227. + line_size = t->output.crop.w;
  177228. +
  177229. + vdi_save_lines = (t->output.crop.h - t->set.sp_setting.ud_split_line)/2;
  177230. + vdi_size = vdi_save_lines * line_size;
  177231. + if (vdi_save_lines <= 0) {
  177232. + dev_err(t->dev, "[0x%p] vdi_save_line error\n", (void *)t);
  177233. + mutex_unlock(lock);
  177234. + return;
  177235. + }
  177236. +
  177237. + /*check vditmpbuf buffer have alloced or buffer size is changed */
  177238. + if ((vdi_save_lines != parent->old_save_lines) ||
  177239. + (vdi_size != parent->old_size)) {
  177240. + if (parent->vditmpbuf[0] != NULL)
  177241. + kfree(parent->vditmpbuf[0]);
  177242. + if (parent->vditmpbuf[1] != NULL)
  177243. + kfree(parent->vditmpbuf[1]);
  177244. +
  177245. + parent->vditmpbuf[0] = kmalloc(vdi_size, GFP_KERNEL);
  177246. + if (parent->vditmpbuf[0] == NULL) {
  177247. + dev_err(t->dev,
  177248. + "[0x%p]Falied Alloc vditmpbuf[0]\n", (void *)t);
  177249. + mutex_unlock(lock);
  177250. + return;
  177251. + }
  177252. + memset(parent->vditmpbuf[0], 0, vdi_size);
  177253. +
  177254. + parent->vditmpbuf[1] = kmalloc(vdi_size, GFP_KERNEL);
  177255. + if (parent->vditmpbuf[1] == NULL) {
  177256. + dev_err(t->dev,
  177257. + "[0x%p]Falied Alloc vditmpbuf[1]\n", (void *)t);
  177258. + mutex_unlock(lock);
  177259. + return;
  177260. + }
  177261. + memset(parent->vditmpbuf[1], 0, vdi_size);
  177262. +
  177263. + parent->old_save_lines = vdi_save_lines;
  177264. + parent->old_size = vdi_size;
  177265. + }
  177266. +
  177267. + if (pfn_valid(t->output.paddr >> PAGE_SHIFT)) {
  177268. + base_off = page_address(pfn_to_page(t->output.paddr >> PAGE_SHIFT));
  177269. + base_off += t->output.paddr & ((1 << PAGE_SHIFT) - 1);
  177270. + } else {
  177271. + base_off = (char *)ioremap_nocache(t->output.paddr,
  177272. + t->output.width * t->output.height *
  177273. + fmt_to_bpp(t->output.format)/8);
  177274. + }
  177275. + if (base_off == NULL) {
  177276. + dev_err(t->dev, "ERR[0x%p]Failed get virtual address\n", t);
  177277. + mutex_unlock(lock);
  177278. + return;
  177279. + }
  177280. +
  177281. + /* UP stripe or UP&LEFT stripe */
  177282. + if ((stripe_mode == UP_STRIPE) ||
  177283. + (stripe_mode == (UP_STRIPE | LEFT_STRIPE))) {
  177284. + if (!parent->buf0filled) {
  177285. + offset_addr = t->set.o_off +
  177286. + t->set.sp_setting.ud_split_line*t->set.ostride;
  177287. + dmac_flush_range(base_off + offset_addr,
  177288. + base_off + offset_addr + vdi_size);
  177289. + outer_flush_range(t->output.paddr + offset_addr,
  177290. + t->output.paddr + offset_addr + vdi_size);
  177291. +
  177292. + for (i = 0; i < vdi_save_lines; i++)
  177293. + memcpy(parent->vditmpbuf[0] + i*line_size,
  177294. + base_off + offset_addr +
  177295. + i*t->set.ostride, line_size);
  177296. + parent->buf0filled = true;
  177297. + } else {
  177298. + offset_addr = t->set.o_off + (t->output.crop.h -
  177299. + vdi_save_lines) * t->set.ostride;
  177300. + for (i = 0; i < vdi_save_lines; i++)
  177301. + memcpy(base_off + offset_addr + i*t->set.ostride,
  177302. + parent->vditmpbuf[0] + i*line_size, line_size);
  177303. +
  177304. + dmac_flush_range(base_off + offset_addr,
  177305. + base_off + offset_addr + i*t->set.ostride);
  177306. + outer_flush_range(t->output.paddr + offset_addr,
  177307. + t->output.paddr + offset_addr + i*t->set.ostride);
  177308. + parent->buf0filled = false;
  177309. + }
  177310. + }
  177311. + /*Down stripe or Down&Left stripe*/
  177312. + else if ((stripe_mode == DOWN_STRIPE) ||
  177313. + (stripe_mode == (DOWN_STRIPE | LEFT_STRIPE))) {
  177314. + if (!parent->buf0filled) {
  177315. + offset_addr = t->set.o_off + vdi_save_lines*t->set.ostride;
  177316. + dmac_flush_range(base_off + offset_addr,
  177317. + base_off + offset_addr + vdi_size);
  177318. + outer_flush_range(t->output.paddr + offset_addr,
  177319. + t->output.paddr + offset_addr + vdi_size);
  177320. +
  177321. + for (i = 0; i < vdi_save_lines; i++)
  177322. + memcpy(parent->vditmpbuf[0] + i*line_size,
  177323. + base_off + offset_addr + i*t->set.ostride,
  177324. + line_size);
  177325. + parent->buf0filled = true;
  177326. + } else {
  177327. + offset_addr = t->set.o_off;
  177328. + for (i = 0; i < vdi_save_lines; i++)
  177329. + memcpy(base_off + offset_addr + i*t->set.ostride,
  177330. + parent->vditmpbuf[0] + i*line_size,
  177331. + line_size);
  177332. +
  177333. + dmac_flush_range(base_off + offset_addr,
  177334. + base_off + offset_addr + i*t->set.ostride);
  177335. + outer_flush_range(t->output.paddr + offset_addr,
  177336. + t->output.paddr + offset_addr + i*t->set.ostride);
  177337. + parent->buf0filled = false;
  177338. + }
  177339. + }
  177340. + /*Up&Right stripe*/
  177341. + else if (stripe_mode == (UP_STRIPE | RIGHT_STRIPE)) {
  177342. + if (!parent->buf1filled) {
  177343. + offset_addr = t->set.o_off +
  177344. + t->set.sp_setting.ud_split_line*t->set.ostride;
  177345. + dmac_flush_range(base_off + offset_addr,
  177346. + base_off + offset_addr + vdi_size);
  177347. + outer_flush_range(t->output.paddr + offset_addr,
  177348. + t->output.paddr + offset_addr + vdi_size);
  177349. +
  177350. + for (i = 0; i < vdi_save_lines; i++)
  177351. + memcpy(parent->vditmpbuf[1] + i*line_size,
  177352. + base_off + offset_addr + i*t->set.ostride,
  177353. + line_size);
  177354. + parent->buf1filled = true;
  177355. + } else {
  177356. + offset_addr = t->set.o_off +
  177357. + (t->output.crop.h - vdi_save_lines)*t->set.ostride;
  177358. + for (i = 0; i < vdi_save_lines; i++)
  177359. + memcpy(base_off + offset_addr + i*t->set.ostride,
  177360. + parent->vditmpbuf[1] + i*line_size,
  177361. + line_size);
  177362. +
  177363. + dmac_flush_range(base_off + offset_addr,
  177364. + base_off + offset_addr + i*t->set.ostride);
  177365. + outer_flush_range(t->output.paddr + offset_addr,
  177366. + t->output.paddr + offset_addr + i*t->set.ostride);
  177367. + parent->buf1filled = false;
  177368. + }
  177369. + }
  177370. + /*Down stripe or Down&Right stript*/
  177371. + else if (stripe_mode == (DOWN_STRIPE | RIGHT_STRIPE)) {
  177372. + if (!parent->buf1filled) {
  177373. + offset_addr = t->set.o_off + vdi_save_lines*t->set.ostride;
  177374. + dmac_flush_range(base_off + offset_addr,
  177375. + base_off + offset_addr + vdi_save_lines*t->set.ostride);
  177376. + outer_flush_range(t->output.paddr + offset_addr,
  177377. + t->output.paddr + offset_addr + vdi_save_lines*t->set.ostride);
  177378. +
  177379. + for (i = 0; i < vdi_save_lines; i++)
  177380. + memcpy(parent->vditmpbuf[1] + i*line_size,
  177381. + base_off + offset_addr + i*t->set.ostride,
  177382. + line_size);
  177383. + parent->buf1filled = true;
  177384. + } else {
  177385. + offset_addr = t->set.o_off;
  177386. + for (i = 0; i < vdi_save_lines; i++)
  177387. + memcpy(base_off + offset_addr + i*t->set.ostride,
  177388. + parent->vditmpbuf[1] + i*line_size,
  177389. + line_size);
  177390. +
  177391. + dmac_flush_range(base_off + offset_addr,
  177392. + base_off + offset_addr + vdi_save_lines*t->set.ostride);
  177393. + outer_flush_range(t->output.paddr + offset_addr,
  177394. + t->output.paddr + offset_addr + vdi_save_lines*t->set.ostride);
  177395. + parent->buf1filled = false;
  177396. + }
  177397. + }
  177398. + if (!pfn_valid(t->output.paddr >> PAGE_SHIFT))
  177399. + iounmap(base_off);
  177400. + mutex_unlock(lock);
  177401. +}
  177402. +
  177403. +static void do_task_release(struct ipu_task_entry *t, int fail)
  177404. +{
  177405. + int ret;
  177406. + struct ipu_soc *ipu = t->ipu;
  177407. +
  177408. + if (t->input.deinterlace.enable && !fail &&
  177409. + (t->task_no & (UP_STRIPE | DOWN_STRIPE)))
  177410. + vdi_split_process(ipu, t);
  177411. +
  177412. + ipu_free_irq(ipu, t->irq, t);
  177413. +
  177414. + if (t->vdoa_dma.vaddr)
  177415. + dma_free_coherent(t->dev,
  177416. + t->vdoa_dma.size,
  177417. + t->vdoa_dma.vaddr,
  177418. + t->vdoa_dma.paddr);
  177419. +
  177420. + if (only_ic(t->set.mode)) {
  177421. + ret = ipu_disable_channel(ipu, t->set.ic_chan, true);
  177422. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic",
  177423. + STATE_DISABLE_CHAN_FAIL, ret);
  177424. + if (deinterlace_3_field(t)) {
  177425. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_p_chan,
  177426. + true);
  177427. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic_p",
  177428. + STATE_DISABLE_CHAN_FAIL, ret);
  177429. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_n_chan,
  177430. + true);
  177431. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic_n",
  177432. + STATE_DISABLE_CHAN_FAIL, ret);
  177433. + }
  177434. + } else if (only_rot(t->set.mode)) {
  177435. + ret = ipu_disable_channel(ipu, t->set.rot_chan, true);
  177436. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_rot",
  177437. + STATE_DISABLE_CHAN_FAIL, ret);
  177438. + } else if (ic_and_rot(t->set.mode)) {
  177439. + ret = ipu_unlink_channels(ipu, t->set.ic_chan, t->set.rot_chan);
  177440. + CHECK_RETCODE_CONT(ret < 0, "ipu_unlink_ch",
  177441. + STATE_UNLINK_CHAN_FAIL, ret);
  177442. + ret = ipu_disable_channel(ipu, t->set.rot_chan, true);
  177443. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch ic_and_rot-rot",
  177444. + STATE_DISABLE_CHAN_FAIL, ret);
  177445. + ret = ipu_disable_channel(ipu, t->set.ic_chan, true);
  177446. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch ic_and_rot-ic",
  177447. + STATE_DISABLE_CHAN_FAIL, ret);
  177448. + if (deinterlace_3_field(t)) {
  177449. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_p_chan,
  177450. + true);
  177451. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch icrot-ic-p",
  177452. + STATE_DISABLE_CHAN_FAIL, ret);
  177453. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_n_chan,
  177454. + true);
  177455. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch icrot-ic-n",
  177456. + STATE_DISABLE_CHAN_FAIL, ret);
  177457. + }
  177458. + }
  177459. +
  177460. + if (only_ic(t->set.mode))
  177461. + uninit_ic(ipu, t);
  177462. + else if (only_rot(t->set.mode))
  177463. + uninit_rot(ipu, t);
  177464. + else if (ic_and_rot(t->set.mode)) {
  177465. + uninit_ic(ipu, t);
  177466. + uninit_rot(ipu, t);
  177467. + }
  177468. +
  177469. + t->state = STATE_OK;
  177470. + CHECK_PERF(&t->ts_rel);
  177471. + return;
  177472. +}
  177473. +
  177474. +static void do_task_vdoa_only(struct ipu_task_entry *t)
  177475. +{
  177476. + int ret;
  177477. +
  177478. + ret = init_tiled_ch_bufs(NULL, t);
  177479. + CHECK_RETCODE(ret < 0, "do_vdoa_only", STATE_ERR, out, ret);
  177480. + ret = vdoa_start(t->vdoa_handle, VDOA_DEF_TIMEOUT_MS);
  177481. + vdoa_stop(t->vdoa_handle);
  177482. + CHECK_RETCODE(ret < 0, "vdoa_wait4complete, do_vdoa_only",
  177483. + STATE_VDOA_IRQ_TIMEOUT, out, ret);
  177484. +
  177485. + t->state = STATE_OK;
  177486. +out:
  177487. + return;
  177488. +}
  177489. +
  177490. +static void do_task(struct ipu_task_entry *t)
  177491. +{
  177492. + int r_size;
  177493. + int irq;
  177494. + int ret;
  177495. + uint32_t busy;
  177496. + struct ipu_soc *ipu = t->ipu;
  177497. +
  177498. + CHECK_PERF(&t->ts_dotask);
  177499. +
  177500. + if (!ipu) {
  177501. + t->state = STATE_NO_IPU;
  177502. + return;
  177503. + }
  177504. +
  177505. + init_completion(&t->irq_comp);
  177506. + dev_dbg(ipu->dev, "[0x%p]Do task no:0x%x: id %d\n", (void *)t,
  177507. + t->task_no, t->task_id);
  177508. + dump_task_info(t);
  177509. +
  177510. + if (t->set.task & IC_PP) {
  177511. + t->set.ic_chan = MEM_PP_MEM;
  177512. + dev_dbg(ipu->dev, "[0x%p]ic channel MEM_PP_MEM\n", (void *)t);
  177513. + } else if (t->set.task & IC_VF) {
  177514. + t->set.ic_chan = MEM_PRP_VF_MEM;
  177515. + dev_dbg(ipu->dev, "[0x%p]ic channel MEM_PRP_VF_MEM\n", (void *)t);
  177516. + } else if (t->set.task & VDI_VF) {
  177517. + if (t->set.mode & VDOA_BAND_MODE) {
  177518. + t->set.ic_chan = MEM_VDI_MEM;
  177519. + if (deinterlace_3_field(t)) {
  177520. + t->set.vdi_ic_p_chan = MEM_VDI_MEM_P;
  177521. + t->set.vdi_ic_n_chan = MEM_VDI_MEM_N;
  177522. + }
  177523. + dev_dbg(ipu->dev, "[0x%p]ic ch MEM_VDI_MEM\n",
  177524. + (void *)t);
  177525. + } else {
  177526. + t->set.ic_chan = MEM_VDI_PRP_VF_MEM;
  177527. + if (deinterlace_3_field(t)) {
  177528. + t->set.vdi_ic_p_chan = MEM_VDI_PRP_VF_MEM_P;
  177529. + t->set.vdi_ic_n_chan = MEM_VDI_PRP_VF_MEM_N;
  177530. + }
  177531. + dev_dbg(ipu->dev,
  177532. + "[0x%p]ic ch MEM_VDI_PRP_VF_MEM\n", t);
  177533. + }
  177534. + }
  177535. +
  177536. + if (t->set.task & ROT_PP) {
  177537. + t->set.rot_chan = MEM_ROT_PP_MEM;
  177538. + dev_dbg(ipu->dev, "[0x%p]rot channel MEM_ROT_PP_MEM\n", (void *)t);
  177539. + } else if (t->set.task & ROT_VF) {
  177540. + t->set.rot_chan = MEM_ROT_VF_MEM;
  177541. + dev_dbg(ipu->dev, "[0x%p]rot channel MEM_ROT_VF_MEM\n", (void *)t);
  177542. + }
  177543. +
  177544. + if (t->task_id == IPU_TASK_ID_VF)
  177545. + busy = ic_vf_pp_is_busy(ipu, true);
  177546. + else if (t->task_id == IPU_TASK_ID_PP)
  177547. + busy = ic_vf_pp_is_busy(ipu, false);
  177548. + else {
  177549. + dev_err(ipu->dev, "ERR[no:0x%x]ipu task_id:%d invalid!\n",
  177550. + t->task_no, t->task_id);
  177551. + return;
  177552. + }
  177553. + if (busy) {
  177554. + dev_err(ipu->dev, "ERR[0x%p-no:0x%x]ipu task_id:%d busy!\n",
  177555. + (void *)t, t->task_no, t->task_id);
  177556. + t->state = STATE_IPU_BUSY;
  177557. + return;
  177558. + }
  177559. +
  177560. + irq = get_irq(t);
  177561. + if (irq < 0) {
  177562. + t->state = STATE_NO_IRQ;
  177563. + return;
  177564. + }
  177565. + t->irq = irq;
  177566. +
  177567. + /* channel setup */
  177568. + if (only_ic(t->set.mode)) {
  177569. + dev_dbg(t->dev, "[0x%p]only ic mode\n", (void *)t);
  177570. + ret = init_ic(ipu, t);
  177571. + CHECK_RETCODE(ret < 0, "init_ic only_ic",
  177572. + t->state, chan_setup, ret);
  177573. + } else if (only_rot(t->set.mode)) {
  177574. + dev_dbg(t->dev, "[0x%p]only rot mode\n", (void *)t);
  177575. + ret = init_rot(ipu, t);
  177576. + CHECK_RETCODE(ret < 0, "init_rot only_rot",
  177577. + t->state, chan_setup, ret);
  177578. + } else if (ic_and_rot(t->set.mode)) {
  177579. + int rot_idx = (t->task_id == IPU_TASK_ID_VF) ? 0 : 1;
  177580. +
  177581. + dev_dbg(t->dev, "[0x%p]ic + rot mode\n", (void *)t);
  177582. + t->set.r_fmt = t->output.format;
  177583. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  177584. + t->set.r_width = t->output.crop.h;
  177585. + t->set.r_height = t->output.crop.w;
  177586. + } else {
  177587. + t->set.r_width = t->output.crop.w;
  177588. + t->set.r_height = t->output.crop.h;
  177589. + }
  177590. + t->set.r_stride = t->set.r_width *
  177591. + bytes_per_pixel(t->set.r_fmt);
  177592. + r_size = PAGE_ALIGN(t->set.r_width * t->set.r_height
  177593. + * fmt_to_bpp(t->set.r_fmt)/8);
  177594. +
  177595. + if (r_size > ipu->rot_dma[rot_idx].size) {
  177596. + dev_dbg(t->dev, "[0x%p]realloc rot buffer\n", (void *)t);
  177597. +
  177598. + if (ipu->rot_dma[rot_idx].vaddr)
  177599. + dma_free_coherent(t->dev,
  177600. + ipu->rot_dma[rot_idx].size,
  177601. + ipu->rot_dma[rot_idx].vaddr,
  177602. + ipu->rot_dma[rot_idx].paddr);
  177603. +
  177604. + ipu->rot_dma[rot_idx].size = r_size;
  177605. + ipu->rot_dma[rot_idx].vaddr = dma_alloc_coherent(t->dev,
  177606. + r_size,
  177607. + &ipu->rot_dma[rot_idx].paddr,
  177608. + GFP_DMA | GFP_KERNEL);
  177609. + CHECK_RETCODE(ipu->rot_dma[rot_idx].vaddr == NULL,
  177610. + "ic_and_rot", STATE_SYS_NO_MEM,
  177611. + chan_setup, -ENOMEM);
  177612. + }
  177613. + t->set.r_paddr = ipu->rot_dma[rot_idx].paddr;
  177614. +
  177615. + dev_dbg(t->dev, "[0x%p]rotation:\n", (void *)t);
  177616. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->set.r_fmt);
  177617. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->set.r_width);
  177618. + dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->set.r_height);
  177619. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->set.r_paddr);
  177620. + dev_dbg(t->dev, "[0x%p]\trstride = %d\n", (void *)t, t->set.r_stride);
  177621. +
  177622. + ret = init_ic(ipu, t);
  177623. + CHECK_RETCODE(ret < 0, "init_ic ic_and_rot",
  177624. + t->state, chan_setup, ret);
  177625. + ret = init_rot(ipu, t);
  177626. + CHECK_RETCODE(ret < 0, "init_rot ic_and_rot",
  177627. + t->state, chan_setup, ret);
  177628. + ret = ipu_link_channels(ipu, t->set.ic_chan,
  177629. + t->set.rot_chan);
  177630. + CHECK_RETCODE(ret < 0, "ipu_link_ch ic_and_rot",
  177631. + STATE_LINK_CHAN_FAIL, chan_setup, ret);
  177632. + } else {
  177633. + dev_err(t->dev, "ERR [0x%p]do task: should not be here\n", t);
  177634. + t->state = STATE_ERR;
  177635. + return;
  177636. + }
  177637. +
  177638. + ret = ipu_request_irq(ipu, irq, task_irq_handler, 0, NULL, t);
  177639. + CHECK_RETCODE(ret < 0, "ipu_req_irq",
  177640. + STATE_IRQ_FAIL, chan_setup, ret);
  177641. +
  177642. + /* enable/start channel */
  177643. + if (only_ic(t->set.mode)) {
  177644. + ret = ipu_enable_channel(ipu, t->set.ic_chan);
  177645. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic",
  177646. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177647. + if (deinterlace_3_field(t)) {
  177648. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_p_chan);
  177649. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic_p",
  177650. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177651. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_n_chan);
  177652. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic_n",
  177653. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177654. + }
  177655. +
  177656. + ret = ipu_select_buffer(ipu, t->set.ic_chan, IPU_OUTPUT_BUFFER,
  177657. + 0);
  177658. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic",
  177659. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177660. + if (t->overlay_en) {
  177661. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177662. + IPU_GRAPH_IN_BUFFER, 0);
  177663. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_g",
  177664. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177665. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  177666. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177667. + IPU_ALPHA_IN_BUFFER, 0);
  177668. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_a",
  177669. + STATE_SEL_BUF_FAIL, chan_buf,
  177670. + ret);
  177671. + }
  177672. + }
  177673. + if (!(t->set.mode & VDOA_BAND_MODE)) {
  177674. + if (deinterlace_3_field(t))
  177675. + ipu_select_multi_vdi_buffer(ipu, 0);
  177676. + else {
  177677. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177678. + IPU_INPUT_BUFFER, 0);
  177679. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_i",
  177680. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177681. + }
  177682. + }
  177683. + } else if (only_rot(t->set.mode)) {
  177684. + ret = ipu_enable_channel(ipu, t->set.rot_chan);
  177685. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_rot",
  177686. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177687. + ret = ipu_select_buffer(ipu, t->set.rot_chan,
  177688. + IPU_OUTPUT_BUFFER, 0);
  177689. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_rot_o",
  177690. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177691. + ret = ipu_select_buffer(ipu, t->set.rot_chan,
  177692. + IPU_INPUT_BUFFER, 0);
  177693. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_rot_i",
  177694. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177695. + } else if (ic_and_rot(t->set.mode)) {
  177696. + ret = ipu_enable_channel(ipu, t->set.rot_chan);
  177697. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-rot",
  177698. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177699. + ret = ipu_enable_channel(ipu, t->set.ic_chan);
  177700. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-ic",
  177701. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177702. + if (deinterlace_3_field(t)) {
  177703. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_p_chan);
  177704. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-p",
  177705. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177706. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_n_chan);
  177707. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-n",
  177708. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  177709. + }
  177710. +
  177711. + ret = ipu_select_buffer(ipu, t->set.rot_chan,
  177712. + IPU_OUTPUT_BUFFER, 0);
  177713. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-rot-o",
  177714. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177715. + if (t->overlay_en) {
  177716. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177717. + IPU_GRAPH_IN_BUFFER, 0);
  177718. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-g",
  177719. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177720. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  177721. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177722. + IPU_ALPHA_IN_BUFFER, 0);
  177723. + CHECK_RETCODE(ret < 0, "ipu_sel_buf icrot-ic-a",
  177724. + STATE_SEL_BUF_FAIL,
  177725. + chan_buf, ret);
  177726. + }
  177727. + }
  177728. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177729. + IPU_OUTPUT_BUFFER, 0);
  177730. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-o",
  177731. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177732. + if (deinterlace_3_field(t))
  177733. + ipu_select_multi_vdi_buffer(ipu, 0);
  177734. + else {
  177735. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  177736. + IPU_INPUT_BUFFER, 0);
  177737. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-i",
  177738. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  177739. + }
  177740. + }
  177741. +
  177742. + if (need_split(t))
  177743. + t->state = STATE_IN_PROGRESS;
  177744. +
  177745. + if (t->set.mode & VDOA_BAND_MODE) {
  177746. + ret = vdoa_start(t->vdoa_handle, VDOA_DEF_TIMEOUT_MS);
  177747. + CHECK_RETCODE(ret < 0, "vdoa_wait4complete, do_vdoa_band",
  177748. + STATE_VDOA_IRQ_TIMEOUT, chan_rel, ret);
  177749. + }
  177750. +
  177751. + CHECK_PERF(&t->ts_waitirq);
  177752. + ret = wait_for_completion_timeout(&t->irq_comp,
  177753. + msecs_to_jiffies(t->timeout - DEF_DELAY_MS));
  177754. + CHECK_PERF(&t->ts_wakeup);
  177755. + CHECK_RETCODE(ret == 0, "wait_for_comp_timeout",
  177756. + STATE_IRQ_TIMEOUT, chan_rel, ret);
  177757. + dev_dbg(t->dev, "[0x%p] no-0x%x ipu irq done!", t, t->task_no);
  177758. +
  177759. +chan_rel:
  177760. +chan_buf:
  177761. +chan_en:
  177762. +chan_setup:
  177763. + if (t->set.mode & VDOA_BAND_MODE)
  177764. + vdoa_stop(t->vdoa_handle);
  177765. + do_task_release(t, t->state >= STATE_ERR);
  177766. + return;
  177767. +}
  177768. +
  177769. +static void do_task_vdoa_vdi(struct ipu_task_entry *t)
  177770. +{
  177771. + int i;
  177772. + int ret;
  177773. + u32 stripe_width;
  177774. +
  177775. + /* FIXME: crop mode not support now */
  177776. + stripe_width = t->input.width >> 1;
  177777. + t->input.crop.pos.x = 0;
  177778. + t->input.crop.pos.y = 0;
  177779. + t->input.crop.w = stripe_width;
  177780. + t->input.crop.h = t->input.height;
  177781. + t->output.crop.w = stripe_width;
  177782. + t->output.crop.h = t->input.height;
  177783. +
  177784. + for (i = 0; i < 2; i++) {
  177785. + t->input.crop.pos.x = t->input.crop.pos.x + i * stripe_width;
  177786. + t->output.crop.pos.x = t->output.crop.pos.x + i * stripe_width;
  177787. + /* check input */
  177788. + ret = set_crop(&t->input.crop, t->input.width, t->input.height,
  177789. + t->input.format);
  177790. + if (ret < 0) {
  177791. + ret = STATE_ERR;
  177792. + goto done;
  177793. + } else
  177794. + update_offset(t->input.format,
  177795. + t->input.width, t->input.height,
  177796. + t->input.crop.pos.x,
  177797. + t->input.crop.pos.y,
  177798. + &t->set.i_off, &t->set.i_uoff,
  177799. + &t->set.i_voff, &t->set.istride);
  177800. + dev_dbg(t->dev, "i_off:0x%x, i_uoff:0x%x, istride:%d.\n",
  177801. + t->set.i_off, t->set.i_uoff, t->set.istride);
  177802. + /* check output */
  177803. + ret = set_crop(&t->output.crop, t->input.width,
  177804. + t->output.height, t->output.format);
  177805. + if (ret < 0) {
  177806. + ret = STATE_ERR;
  177807. + goto done;
  177808. + } else
  177809. + update_offset(t->output.format,
  177810. + t->output.width, t->output.height,
  177811. + t->output.crop.pos.x,
  177812. + t->output.crop.pos.y,
  177813. + &t->set.o_off, &t->set.o_uoff,
  177814. + &t->set.o_voff, &t->set.ostride);
  177815. +
  177816. + dev_dbg(t->dev, "o_off:0x%x, o_uoff:0x%x, ostride:%d.\n",
  177817. + t->set.o_off, t->set.o_uoff, t->set.ostride);
  177818. +
  177819. + do_task(t);
  177820. + }
  177821. +
  177822. + return;
  177823. +done:
  177824. + dev_err(t->dev, "ERR %s set_crop.\n", __func__);
  177825. + t->state = ret;
  177826. + return;
  177827. +}
  177828. +
  177829. +static void get_res_do_task(struct ipu_task_entry *t)
  177830. +{
  177831. + uint32_t found;
  177832. + uint32_t split_child;
  177833. + struct mutex *lock;
  177834. +
  177835. + found = get_vdoa_ipu_res(t);
  177836. + if (!found) {
  177837. + dev_err(t->dev, "ERR:[0x%p] no-0x%x can not get res\n",
  177838. + t, t->task_no);
  177839. + return;
  177840. + } else {
  177841. + if (t->set.task & VDOA_ONLY)
  177842. + do_task_vdoa_only(t);
  177843. + else if ((IPU_PIX_FMT_TILED_NV12F == t->input.format) &&
  177844. + (t->set.mode & VDOA_BAND_MODE) &&
  177845. + (t->input.crop.w > soc_max_vdi_in_width()))
  177846. + do_task_vdoa_vdi(t);
  177847. + else
  177848. + do_task(t);
  177849. + put_vdoa_ipu_res(t, 0);
  177850. + }
  177851. + if (t->state != STATE_OK) {
  177852. + dev_err(t->dev, "ERR:[0x%p] no-0x%x state: %s\n",
  177853. + t, t->task_no, state_msg[t->state].msg);
  177854. + }
  177855. +
  177856. + split_child = need_split(t) && t->parent;
  177857. + if (split_child) {
  177858. + lock = &t->parent->split_lock;
  177859. + mutex_lock(lock);
  177860. + t->split_done = 1;
  177861. + mutex_unlock(lock);
  177862. + wake_up(&t->parent->split_waitq);
  177863. + }
  177864. +
  177865. + return;
  177866. +}
  177867. +
  177868. +static void wait_split_task_complete(struct ipu_task_entry *parent,
  177869. + struct ipu_split_task *sp_task, uint32_t size)
  177870. +{
  177871. + struct ipu_task_entry *tsk = NULL;
  177872. + int ret = 0, rc;
  177873. + int j, idx = -1;
  177874. + unsigned long flags;
  177875. + struct mutex *lock = &parent->split_lock;
  177876. + int k, busy_vf, busy_pp;
  177877. + struct ipu_soc *ipu;
  177878. + DECLARE_PERF_VAR;
  177879. +
  177880. + for (j = 0; j < size; j++) {
  177881. + rc = wait_event_timeout(
  177882. + parent->split_waitq,
  177883. + sp_task_check_done(sp_task, parent, size, &idx),
  177884. + msecs_to_jiffies(parent->timeout - DEF_DELAY_MS));
  177885. + if (!rc) {
  177886. + dev_err(parent->dev,
  177887. + "ERR:[0x%p] no-0x%x, split_task timeout,j:%d,"
  177888. + "size:%d.\n",
  177889. + parent, parent->task_no, j, size);
  177890. + ret = -ETIMEDOUT;
  177891. + goto out;
  177892. + } else {
  177893. + if (idx < 0) {
  177894. + dev_err(parent->dev,
  177895. + "ERR:[0x%p] no-0x%x, invalid task idx:%d\n",
  177896. + parent, parent->task_no, idx);
  177897. + continue;
  177898. + }
  177899. + tsk = sp_task[idx].child_task;
  177900. + mutex_lock(lock);
  177901. + if (!tsk->split_done || !tsk->ipu)
  177902. + dev_err(tsk->dev,
  177903. + "ERR:no-0x%x,split not done:%d/null ipu:0x%p\n",
  177904. + tsk->task_no, tsk->split_done, tsk->ipu);
  177905. + tsk->split_done = 0;
  177906. + mutex_unlock(lock);
  177907. +
  177908. + dev_dbg(tsk->dev,
  177909. + "[0x%p] no-0x%x sp_tsk[%d] done,state:%d.\n",
  177910. + tsk, tsk->task_no, idx, tsk->state);
  177911. + #ifdef DBG_IPU_PERF
  177912. + CHECK_PERF(&tsk->ts_rel);
  177913. + PRINT_TASK_STATISTICS;
  177914. + #endif
  177915. + }
  177916. + }
  177917. +
  177918. +out:
  177919. + if (ret == -ETIMEDOUT) {
  177920. + /* debug */
  177921. + for (k = 0; k < max_ipu_no; k++) {
  177922. + ipu = ipu_get_soc(k);
  177923. + if (IS_ERR(ipu)) {
  177924. + dev_err(parent->dev, "no:0x%x, null ipu:%d\n",
  177925. + parent->task_no, k);
  177926. + } else {
  177927. + busy_vf = ic_vf_pp_is_busy(ipu, true);
  177928. + busy_pp = ic_vf_pp_is_busy(ipu, false);
  177929. + dev_err(parent->dev,
  177930. + "ERR:ipu[%d] busy_vf:%d, busy_pp:%d.\n",
  177931. + k, busy_vf, busy_pp);
  177932. + }
  177933. + }
  177934. + for (k = 0; k < size; k++) {
  177935. + tsk = sp_task[k].child_task;
  177936. + if (!tsk)
  177937. + continue;
  177938. + dev_err(parent->dev,
  177939. + "ERR: sp_task[%d][0x%p] no-0x%x done:%d,"
  177940. + "state:%s,on_list:%d, ipu:0x%p,timeout!\n",
  177941. + k, tsk, tsk->task_no, tsk->split_done,
  177942. + state_msg[tsk->state].msg, tsk->task_in_list,
  177943. + tsk->ipu);
  177944. + }
  177945. + }
  177946. +
  177947. + for (j = 0; j < size; j++) {
  177948. + tsk = sp_task[j].child_task;
  177949. + if (!tsk)
  177950. + continue;
  177951. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  177952. + if (tsk->task_in_list) {
  177953. + list_del(&tsk->node);
  177954. + tsk->task_in_list = 0;
  177955. + dev_dbg(tsk->dev,
  177956. + "[0x%p] no-0x%x,id:%d sp_tsk timeout list_del.\n",
  177957. + tsk, tsk->task_no, tsk->task_id);
  177958. + }
  177959. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  177960. + if (!tsk->ipu)
  177961. + continue;
  177962. + if (tsk->state != STATE_OK) {
  177963. + dev_err(tsk->dev,
  177964. + "ERR:[0x%p] no-0x%x,id:%d, sp_tsk state: %s\n",
  177965. + tsk, tsk->task_no, tsk->task_id,
  177966. + state_msg[tsk->state].msg);
  177967. + }
  177968. + kref_put(&tsk->refcount, task_mem_free);
  177969. + }
  177970. +
  177971. + kfree(parent->vditmpbuf[0]);
  177972. + kfree(parent->vditmpbuf[1]);
  177973. +
  177974. + if (ret < 0)
  177975. + parent->state = STATE_TIMEOUT;
  177976. + else
  177977. + parent->state = STATE_OK;
  177978. + return;
  177979. +}
  177980. +
  177981. +static inline int find_task(struct ipu_task_entry **t, int thread_id)
  177982. +{
  177983. + int found;
  177984. + unsigned long flags;
  177985. + struct ipu_task_entry *tsk;
  177986. + struct list_head *task_list = &ipu_task_list;
  177987. +
  177988. + *t = NULL;
  177989. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  177990. + found = !list_empty(task_list);
  177991. + if (found) {
  177992. + tsk = list_first_entry(task_list, struct ipu_task_entry, node);
  177993. + if (tsk->task_in_list) {
  177994. + list_del(&tsk->node);
  177995. + tsk->task_in_list = 0;
  177996. + *t = tsk;
  177997. + kref_get(&tsk->refcount);
  177998. + dev_dbg(tsk->dev,
  177999. + "thread_id:%d,[0x%p] task_no:0x%x,mode:0x%x list_del\n",
  178000. + thread_id, tsk, tsk->task_no, tsk->set.mode);
  178001. + } else
  178002. + dev_err(tsk->dev,
  178003. + "thread_id:%d,task_no:0x%x,mode:0x%x not on list_del\n",
  178004. + thread_id, tsk->task_no, tsk->set.mode);
  178005. + }
  178006. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  178007. +
  178008. + return found;
  178009. +}
  178010. +
  178011. +static int ipu_task_thread(void *argv)
  178012. +{
  178013. + struct ipu_task_entry *tsk;
  178014. + struct ipu_task_entry *sp_tsk0;
  178015. + struct ipu_split_task sp_task[4];
  178016. + /* priority lower than irq_thread */
  178017. + const struct sched_param param = {
  178018. + .sched_priority = MAX_USER_RT_PRIO/2 - 1,
  178019. + };
  178020. + int ret;
  178021. + int curr_thread_id;
  178022. + uint32_t size;
  178023. + unsigned long flags;
  178024. + unsigned int cpu;
  178025. + struct cpumask cpu_mask;
  178026. + struct ipu_thread_data *data = (struct ipu_thread_data *)argv;
  178027. +
  178028. + thread_id++;
  178029. + curr_thread_id = thread_id;
  178030. + sched_setscheduler(current, SCHED_FIFO, &param);
  178031. +
  178032. + if (!data->is_vdoa) {
  178033. + cpu = cpumask_first(cpu_online_mask);
  178034. + cpumask_set_cpu(cpu, &cpu_mask);
  178035. + ret = sched_setaffinity(data->ipu->thread[data->id]->pid,
  178036. + &cpu_mask);
  178037. + if (ret < 0) {
  178038. + pr_err("%s: sched_setaffinity fail:%d.\n", __func__, ret);
  178039. + }
  178040. + pr_debug("%s: sched_setaffinity cpu:%d.\n", __func__, cpu);
  178041. + }
  178042. +
  178043. + while (!kthread_should_stop()) {
  178044. + int split_fail = 0;
  178045. + int split_parent;
  178046. + int split_child;
  178047. +
  178048. + wait_event_interruptible(thread_waitq, find_task(&tsk, curr_thread_id));
  178049. +
  178050. + if (!tsk) {
  178051. + pr_err("thread:%d can not find task.\n",
  178052. + curr_thread_id);
  178053. + continue;
  178054. + }
  178055. +
  178056. + /* note: other threads run split child task */
  178057. + split_parent = need_split(tsk) && !tsk->parent;
  178058. + split_child = need_split(tsk) && tsk->parent;
  178059. + if (split_parent) {
  178060. + if ((tsk->set.split_mode == RL_SPLIT) ||
  178061. + (tsk->set.split_mode == UD_SPLIT))
  178062. + size = 2;
  178063. + else
  178064. + size = 4;
  178065. + ret = queue_split_task(tsk, sp_task, size);
  178066. + if (ret < 0) {
  178067. + split_fail = 1;
  178068. + } else {
  178069. + struct list_head *pos;
  178070. +
  178071. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  178072. +
  178073. + sp_tsk0 = list_first_entry(&tsk->split_list,
  178074. + struct ipu_task_entry, node);
  178075. + list_del(&sp_tsk0->node);
  178076. +
  178077. + list_for_each(pos, &tsk->split_list) {
  178078. + struct ipu_task_entry *tmp;
  178079. +
  178080. + tmp = list_entry(pos,
  178081. + struct ipu_task_entry, node);
  178082. + tmp->task_in_list = 1;
  178083. + dev_dbg(tmp->dev,
  178084. + "[0x%p] no-0x%x,id:%d sp_tsk "
  178085. + "add_to_list.\n", tmp,
  178086. + tmp->task_no, tmp->task_id);
  178087. + }
  178088. + /* add to global list */
  178089. + list_splice(&tsk->split_list, &ipu_task_list);
  178090. +
  178091. + spin_unlock_irqrestore(&ipu_task_list_lock,
  178092. + flags);
  178093. + /* let the parent thread do the first sp_task */
  178094. + /* FIXME: ensure the correct sequence for split
  178095. + 4size: 5/6->9/a*/
  178096. + if (!sp_tsk0)
  178097. + dev_err(tsk->dev,
  178098. + "ERR: no-0x%x,can not get split_tsk0\n",
  178099. + tsk->task_no);
  178100. + wake_up_interruptible(&thread_waitq);
  178101. + get_res_do_task(sp_tsk0);
  178102. + dev_dbg(sp_tsk0->dev,
  178103. + "thread:%d complete tsk no:0x%x.\n",
  178104. + curr_thread_id, sp_tsk0->task_no);
  178105. + ret = atomic_read(&req_cnt);
  178106. + if (ret > 0) {
  178107. + wake_up(&res_waitq);
  178108. + dev_dbg(sp_tsk0->dev,
  178109. + "sp_tsk0 sche thread:%d no:0x%x,"
  178110. + "req_cnt:%d\n", curr_thread_id,
  178111. + sp_tsk0->task_no, ret);
  178112. + /* For other threads to get_res */
  178113. + schedule();
  178114. + }
  178115. + }
  178116. + } else
  178117. + get_res_do_task(tsk);
  178118. +
  178119. + /* wait for all 4 sp_task finished here or timeout
  178120. + and then release all resources */
  178121. + if (split_parent && !split_fail)
  178122. + wait_split_task_complete(tsk, sp_task, size);
  178123. +
  178124. + if (!split_child) {
  178125. + atomic_inc(&tsk->done);
  178126. + wake_up(&tsk->task_waitq);
  178127. + }
  178128. +
  178129. + dev_dbg(tsk->dev, "thread:%d complete tsk no:0x%x-[0x%p].\n",
  178130. + curr_thread_id, tsk->task_no, tsk);
  178131. + ret = atomic_read(&req_cnt);
  178132. + if (ret > 0) {
  178133. + wake_up(&res_waitq);
  178134. + dev_dbg(tsk->dev, "sche thread:%d no:0x%x,req_cnt:%d\n",
  178135. + curr_thread_id, tsk->task_no, ret);
  178136. + /* note: give cpu to other threads to get_res */
  178137. + schedule();
  178138. + }
  178139. +
  178140. + kref_put(&tsk->refcount, task_mem_free);
  178141. + }
  178142. +
  178143. + pr_info("ERR %s exit.\n", __func__);
  178144. + return 0;
  178145. +}
  178146. +
  178147. +int ipu_check_task(struct ipu_task *task)
  178148. +{
  178149. + struct ipu_task_entry *tsk;
  178150. + int ret = 0;
  178151. +
  178152. + tsk = create_task_entry(task);
  178153. + if (IS_ERR(tsk))
  178154. + return PTR_ERR(tsk);
  178155. +
  178156. + ret = check_task(tsk);
  178157. +
  178158. + task->input = tsk->input;
  178159. + task->output = tsk->output;
  178160. + task->overlay = tsk->overlay;
  178161. + dump_task_info(tsk);
  178162. +
  178163. + kref_put(&tsk->refcount, task_mem_free);
  178164. + if (ret != 0)
  178165. + pr_debug("%s ret:%d.\n", __func__, ret);
  178166. + return ret;
  178167. +}
  178168. +EXPORT_SYMBOL_GPL(ipu_check_task);
  178169. +
  178170. +int ipu_queue_task(struct ipu_task *task)
  178171. +{
  178172. + struct ipu_task_entry *tsk;
  178173. + unsigned long flags;
  178174. + int ret;
  178175. + u32 tmp_task_no;
  178176. + DECLARE_PERF_VAR;
  178177. +
  178178. + tsk = create_task_entry(task);
  178179. + if (IS_ERR(tsk))
  178180. + return PTR_ERR(tsk);
  178181. +
  178182. + CHECK_PERF(&tsk->ts_queue);
  178183. + ret = prepare_task(tsk);
  178184. + if (ret < 0)
  178185. + goto done;
  178186. +
  178187. + if (need_split(tsk)) {
  178188. + CHECK_PERF(&tsk->ts_dotask);
  178189. + CHECK_PERF(&tsk->ts_waitirq);
  178190. + CHECK_PERF(&tsk->ts_inirq);
  178191. + CHECK_PERF(&tsk->ts_wakeup);
  178192. + }
  178193. +
  178194. + /* task_no last four bits for split task type*/
  178195. + tmp_task_no = atomic_inc_return(&frame_no);
  178196. + tsk->task_no = tmp_task_no << 4;
  178197. + init_waitqueue_head(&tsk->task_waitq);
  178198. +
  178199. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  178200. + list_add_tail(&tsk->node, &ipu_task_list);
  178201. + tsk->task_in_list = 1;
  178202. + dev_dbg(tsk->dev, "[0x%p,no-0x%x] list_add_tail\n", tsk, tsk->task_no);
  178203. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  178204. + wake_up_interruptible(&thread_waitq);
  178205. +
  178206. + ret = wait_event_timeout(tsk->task_waitq, atomic_read(&tsk->done),
  178207. + msecs_to_jiffies(tsk->timeout));
  178208. + if (0 == ret) {
  178209. + /* note: the timeout should larger than the internal timeout!*/
  178210. + ret = -ETIMEDOUT;
  178211. + dev_err(tsk->dev, "ERR: [0x%p] no-0x%x, timeout:%dms!\n",
  178212. + tsk, tsk->task_no, tsk->timeout);
  178213. + } else {
  178214. + if (STATE_OK != tsk->state) {
  178215. + dev_err(tsk->dev, "ERR: [0x%p] no-0x%x,state %d: %s\n",
  178216. + tsk, tsk->task_no, tsk->state,
  178217. + state_msg[tsk->state].msg);
  178218. + ret = -ECANCELED;
  178219. + } else
  178220. + ret = 0;
  178221. + }
  178222. +
  178223. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  178224. + if (tsk->task_in_list) {
  178225. + list_del(&tsk->node);
  178226. + tsk->task_in_list = 0;
  178227. + dev_dbg(tsk->dev, "[0x%p] no:0x%x list_del\n",
  178228. + tsk, tsk->task_no);
  178229. + }
  178230. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  178231. +
  178232. +#ifdef DBG_IPU_PERF
  178233. + CHECK_PERF(&tsk->ts_rel);
  178234. + PRINT_TASK_STATISTICS;
  178235. + if (ts_frame_avg == 0)
  178236. + ts_frame_avg = ts_frame.tv_nsec / NSEC_PER_USEC +
  178237. + ts_frame.tv_sec * USEC_PER_SEC;
  178238. + else
  178239. + ts_frame_avg = (ts_frame_avg + ts_frame.tv_nsec / NSEC_PER_USEC
  178240. + + ts_frame.tv_sec * USEC_PER_SEC)/2;
  178241. + if (timespec_compare(&ts_frame, &ts_frame_max) > 0)
  178242. + ts_frame_max = ts_frame;
  178243. +
  178244. + atomic_inc(&frame_cnt);
  178245. +
  178246. + if ((atomic_read(&frame_cnt) % 1000) == 0)
  178247. + pr_debug("ipu_dev: max frame time:%ldus, avg frame time:%dus,"
  178248. + "frame_cnt:%d\n", ts_frame_max.tv_nsec / NSEC_PER_USEC
  178249. + + ts_frame_max.tv_sec * USEC_PER_SEC,
  178250. + ts_frame_avg, atomic_read(&frame_cnt));
  178251. +#endif
  178252. +done:
  178253. + if (ret < 0)
  178254. + dev_err(tsk->dev, "ERR: no-0x%x,ipu_queue_task err:%d\n",
  178255. + tsk->task_no, ret);
  178256. +
  178257. + kref_put(&tsk->refcount, task_mem_free);
  178258. +
  178259. + return ret;
  178260. +}
  178261. +EXPORT_SYMBOL_GPL(ipu_queue_task);
  178262. +
  178263. +static int mxc_ipu_open(struct inode *inode, struct file *file)
  178264. +{
  178265. + file->private_data = (void *)atomic_inc_return(&file_index);
  178266. + return 0;
  178267. +}
  178268. +
  178269. +static long mxc_ipu_ioctl(struct file *file,
  178270. + unsigned int cmd, unsigned long arg)
  178271. +{
  178272. + int __user *argp = (void __user *)arg;
  178273. + int ret = 0;
  178274. +
  178275. + switch (cmd) {
  178276. + case IPU_CHECK_TASK:
  178277. + {
  178278. + struct ipu_task task;
  178279. +
  178280. + if (copy_from_user
  178281. + (&task, (struct ipu_task *) arg,
  178282. + sizeof(struct ipu_task)))
  178283. + return -EFAULT;
  178284. + ret = ipu_check_task(&task);
  178285. + if (copy_to_user((struct ipu_task *) arg,
  178286. + &task, sizeof(struct ipu_task)))
  178287. + return -EFAULT;
  178288. + break;
  178289. + }
  178290. + case IPU_QUEUE_TASK:
  178291. + {
  178292. + struct ipu_task task;
  178293. +
  178294. + if (copy_from_user
  178295. + (&task, (struct ipu_task *) arg,
  178296. + sizeof(struct ipu_task)))
  178297. + return -EFAULT;
  178298. + ret = ipu_queue_task(&task);
  178299. + break;
  178300. + }
  178301. + case IPU_ALLOC:
  178302. + {
  178303. + int size;
  178304. + struct ipu_alloc_list *mem;
  178305. +
  178306. + mem = kzalloc(sizeof(*mem), GFP_KERNEL);
  178307. + if (mem == NULL)
  178308. + return -ENOMEM;
  178309. +
  178310. + if (get_user(size, argp))
  178311. + return -EFAULT;
  178312. +
  178313. + mem->size = PAGE_ALIGN(size);
  178314. +
  178315. + mem->cpu_addr = dma_alloc_coherent(ipu_dev, size,
  178316. + &mem->phy_addr,
  178317. + GFP_DMA | GFP_KERNEL);
  178318. + if (mem->cpu_addr == NULL) {
  178319. + kfree(mem);
  178320. + return -ENOMEM;
  178321. + }
  178322. + mem->file_index = file->private_data;
  178323. + mutex_lock(&ipu_alloc_lock);
  178324. + list_add(&mem->list, &ipu_alloc_list);
  178325. + mutex_unlock(&ipu_alloc_lock);
  178326. +
  178327. + dev_dbg(ipu_dev, "allocated %d bytes @ 0x%08X\n",
  178328. + mem->size, mem->phy_addr);
  178329. +
  178330. + if (put_user(mem->phy_addr, argp))
  178331. + return -EFAULT;
  178332. +
  178333. + break;
  178334. + }
  178335. + case IPU_FREE:
  178336. + {
  178337. + unsigned long offset;
  178338. + struct ipu_alloc_list *mem;
  178339. +
  178340. + if (get_user(offset, argp))
  178341. + return -EFAULT;
  178342. +
  178343. + ret = -EINVAL;
  178344. + mutex_lock(&ipu_alloc_lock);
  178345. + list_for_each_entry(mem, &ipu_alloc_list, list) {
  178346. + if (mem->phy_addr == offset) {
  178347. + list_del(&mem->list);
  178348. + dma_free_coherent(ipu_dev,
  178349. + mem->size,
  178350. + mem->cpu_addr,
  178351. + mem->phy_addr);
  178352. + kfree(mem);
  178353. + ret = 0;
  178354. + break;
  178355. + }
  178356. + }
  178357. + mutex_unlock(&ipu_alloc_lock);
  178358. + if (0 == ret)
  178359. + dev_dbg(ipu_dev, "free %d bytes @ 0x%08X\n",
  178360. + mem->size, mem->phy_addr);
  178361. +
  178362. + break;
  178363. + }
  178364. + default:
  178365. + break;
  178366. + }
  178367. + return ret;
  178368. +}
  178369. +
  178370. +static int mxc_ipu_mmap(struct file *file, struct vm_area_struct *vma)
  178371. +{
  178372. + bool found = false;
  178373. + u32 len;
  178374. + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  178375. + struct ipu_alloc_list *mem;
  178376. +
  178377. + mutex_lock(&ipu_alloc_lock);
  178378. + list_for_each_entry(mem, &ipu_alloc_list, list) {
  178379. + if (offset == mem->phy_addr) {
  178380. + found = true;
  178381. + len = mem->size;
  178382. + break;
  178383. + }
  178384. + }
  178385. + mutex_unlock(&ipu_alloc_lock);
  178386. + if (!found)
  178387. + return -EINVAL;
  178388. +
  178389. + if (vma->vm_end - vma->vm_start > len)
  178390. + return -EINVAL;
  178391. +
  178392. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  178393. +
  178394. + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  178395. + vma->vm_end - vma->vm_start,
  178396. + vma->vm_page_prot)) {
  178397. + printk(KERN_ERR
  178398. + "mmap failed!\n");
  178399. + return -ENOBUFS;
  178400. + }
  178401. + return 0;
  178402. +}
  178403. +
  178404. +static int mxc_ipu_release(struct inode *inode, struct file *file)
  178405. +{
  178406. + struct ipu_alloc_list *mem;
  178407. + struct ipu_alloc_list *n;
  178408. +
  178409. + mutex_lock(&ipu_alloc_lock);
  178410. + list_for_each_entry_safe(mem, n, &ipu_alloc_list, list) {
  178411. + if ((mem->cpu_addr != 0) &&
  178412. + (file->private_data == mem->file_index)) {
  178413. + list_del(&mem->list);
  178414. + dma_free_coherent(ipu_dev,
  178415. + mem->size,
  178416. + mem->cpu_addr,
  178417. + mem->phy_addr);
  178418. + dev_dbg(ipu_dev, "rel-free %d bytes @ 0x%08X\n",
  178419. + mem->size, mem->phy_addr);
  178420. + kfree(mem);
  178421. + }
  178422. + }
  178423. + mutex_unlock(&ipu_alloc_lock);
  178424. + atomic_dec(&file_index);
  178425. +
  178426. + return 0;
  178427. +}
  178428. +
  178429. +static struct file_operations mxc_ipu_fops = {
  178430. + .owner = THIS_MODULE,
  178431. + .open = mxc_ipu_open,
  178432. + .mmap = mxc_ipu_mmap,
  178433. + .release = mxc_ipu_release,
  178434. + .unlocked_ioctl = mxc_ipu_ioctl,
  178435. +};
  178436. +
  178437. +int register_ipu_device(struct ipu_soc *ipu, int id)
  178438. +{
  178439. + int ret = 0;
  178440. + static int idx;
  178441. + static struct ipu_thread_data thread_data[5];
  178442. +
  178443. + if (!major) {
  178444. + major = register_chrdev(0, "mxc_ipu", &mxc_ipu_fops);
  178445. + if (major < 0) {
  178446. + printk(KERN_ERR "Unable to register mxc_ipu as a char device\n");
  178447. + ret = major;
  178448. + goto register_cdev_fail;
  178449. + }
  178450. +
  178451. + ipu_class = class_create(THIS_MODULE, "mxc_ipu");
  178452. + if (IS_ERR(ipu_class)) {
  178453. + ret = PTR_ERR(ipu_class);
  178454. + goto ipu_class_fail;
  178455. + }
  178456. +
  178457. + ipu_dev = device_create(ipu_class, NULL, MKDEV(major, 0),
  178458. + NULL, "mxc_ipu");
  178459. + if (IS_ERR(ipu_dev)) {
  178460. + ret = PTR_ERR(ipu_dev);
  178461. + goto dev_create_fail;
  178462. + }
  178463. + ipu_dev->dma_mask = kmalloc(sizeof(*ipu_dev->dma_mask), GFP_KERNEL);
  178464. + *ipu_dev->dma_mask = DMA_BIT_MASK(32);
  178465. + ipu_dev->coherent_dma_mask = DMA_BIT_MASK(32);
  178466. +
  178467. + mutex_init(&ipu_ch_tbl.lock);
  178468. + }
  178469. + max_ipu_no = ++id;
  178470. + ipu->rot_dma[0].size = 0;
  178471. + ipu->rot_dma[1].size = 0;
  178472. +
  178473. + thread_data[idx].ipu = ipu;
  178474. + thread_data[idx].id = 0;
  178475. + thread_data[idx].is_vdoa = 0;
  178476. + ipu->thread[0] = kthread_run(ipu_task_thread, &thread_data[idx++],
  178477. + "ipu%d_task", id);
  178478. + if (IS_ERR(ipu->thread[0])) {
  178479. + ret = PTR_ERR(ipu->thread[0]);
  178480. + goto kthread0_fail;
  178481. + }
  178482. +
  178483. + thread_data[idx].ipu = ipu;
  178484. + thread_data[idx].id = 1;
  178485. + thread_data[idx].is_vdoa = 0;
  178486. + ipu->thread[1] = kthread_run(ipu_task_thread, &thread_data[idx++],
  178487. + "ipu%d_task", id);
  178488. + if (IS_ERR(ipu->thread[1])) {
  178489. + ret = PTR_ERR(ipu->thread[1]);
  178490. + goto kthread1_fail;
  178491. + }
  178492. +
  178493. +
  178494. + return ret;
  178495. +
  178496. +kthread1_fail:
  178497. + kthread_stop(ipu->thread[0]);
  178498. +kthread0_fail:
  178499. + if (id == 0)
  178500. + device_destroy(ipu_class, MKDEV(major, 0));
  178501. +dev_create_fail:
  178502. + if (id == 0) {
  178503. + class_destroy(ipu_class);
  178504. + }
  178505. +ipu_class_fail:
  178506. + if (id == 0)
  178507. + unregister_chrdev(major, "mxc_ipu");
  178508. +register_cdev_fail:
  178509. + return ret;
  178510. +}
  178511. +
  178512. +void unregister_ipu_device(struct ipu_soc *ipu, int id)
  178513. +{
  178514. + int i;
  178515. +
  178516. + kthread_stop(ipu->thread[0]);
  178517. + kthread_stop(ipu->thread[1]);
  178518. + for (i = 0; i < 2; i++) {
  178519. + if (ipu->rot_dma[i].vaddr)
  178520. + dma_free_coherent(ipu_dev,
  178521. + ipu->rot_dma[i].size,
  178522. + ipu->rot_dma[i].vaddr,
  178523. + ipu->rot_dma[i].paddr);
  178524. + }
  178525. +
  178526. + if (major) {
  178527. + device_destroy(ipu_class, MKDEV(major, 0));
  178528. + class_destroy(ipu_class);
  178529. + unregister_chrdev(major, "mxc_ipu");
  178530. + major = 0;
  178531. + }
  178532. +}
  178533. diff -Nur linux-3.14.14/drivers/mxc/ipu3/ipu_disp.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_disp.c
  178534. --- linux-3.14.14/drivers/mxc/ipu3/ipu_disp.c 1969-12-31 18:00:00.000000000 -0600
  178535. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_disp.c 2014-12-08 00:31:53.476418001 -0600
  178536. @@ -0,0 +1,1962 @@
  178537. +/*
  178538. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  178539. + */
  178540. +
  178541. +/*
  178542. + * The code contained herein is licensed under the GNU General Public
  178543. + * License. You may obtain a copy of the GNU General Public License
  178544. + * Version 2 or later at the following locations:
  178545. + *
  178546. + * http://www.opensource.org/licenses/gpl-license.html
  178547. + * http://www.gnu.org/copyleft/gpl.html
  178548. + */
  178549. +
  178550. +/*!
  178551. + * @file ipu_disp.c
  178552. + *
  178553. + * @brief IPU display submodule API functions
  178554. + *
  178555. + * @ingroup IPU
  178556. + */
  178557. +
  178558. +#include <linux/clk.h>
  178559. +#include <linux/clk-provider.h>
  178560. +#include <linux/delay.h>
  178561. +#include <linux/err.h>
  178562. +#include <linux/errno.h>
  178563. +#include <linux/io.h>
  178564. +#include <linux/ipu-v3.h>
  178565. +#include <linux/module.h>
  178566. +#include <linux/spinlock.h>
  178567. +#include <linux/types.h>
  178568. +
  178569. +#include <asm/atomic.h>
  178570. +
  178571. +#include "ipu_param_mem.h"
  178572. +#include "ipu_regs.h"
  178573. +
  178574. +struct dp_csc_param_t {
  178575. + int mode;
  178576. + void *coeff;
  178577. +};
  178578. +
  178579. +#define SYNC_WAVE 0
  178580. +#define NULL_WAVE (-1)
  178581. +#define ASYNC_SER_WAVE 6
  178582. +
  178583. +/* DC display ID assignments */
  178584. +#define DC_DISP_ID_SYNC(di) (di)
  178585. +#define DC_DISP_ID_SERIAL 2
  178586. +#define DC_DISP_ID_ASYNC 3
  178587. +
  178588. +int dmfc_type_setup;
  178589. +
  178590. +void _ipu_dmfc_init(struct ipu_soc *ipu, int dmfc_type, int first)
  178591. +{
  178592. + u32 dmfc_wr_chan, dmfc_dp_chan;
  178593. +
  178594. + if (first) {
  178595. + if (dmfc_type_setup > dmfc_type)
  178596. + dmfc_type = dmfc_type_setup;
  178597. + else
  178598. + dmfc_type_setup = dmfc_type;
  178599. +
  178600. + /* disable DMFC-IC channel*/
  178601. + ipu_dmfc_write(ipu, 0x2, DMFC_IC_CTRL);
  178602. + } else if (dmfc_type_setup >= DMFC_HIGH_RESOLUTION_DC) {
  178603. + dev_dbg(ipu->dev, "DMFC high resolution has set, will not change\n");
  178604. + return;
  178605. + } else
  178606. + dmfc_type_setup = dmfc_type;
  178607. +
  178608. + if (dmfc_type == DMFC_HIGH_RESOLUTION_DC) {
  178609. + /* 1 - segment 0~3;
  178610. + * 5B - segement 4, 5;
  178611. + * 5F - segement 6, 7;
  178612. + * 1C, 2C and 6B, 6F unused;
  178613. + */
  178614. + dev_info(ipu->dev, "IPU DMFC DC HIGH RESOLUTION: 1(0~3), 5B(4,5), 5F(6,7)\n");
  178615. + dmfc_wr_chan = 0x00000088;
  178616. + dmfc_dp_chan = 0x00009694;
  178617. + ipu->dmfc_size_28 = 256*4;
  178618. + ipu->dmfc_size_29 = 0;
  178619. + ipu->dmfc_size_24 = 0;
  178620. + ipu->dmfc_size_27 = 128*4;
  178621. + ipu->dmfc_size_23 = 128*4;
  178622. + } else if (dmfc_type == DMFC_HIGH_RESOLUTION_DP) {
  178623. + /* 1 - segment 0, 1;
  178624. + * 5B - segement 2~5;
  178625. + * 5F - segement 6,7;
  178626. + * 1C, 2C and 6B, 6F unused;
  178627. + */
  178628. + dev_info(ipu->dev, "IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)\n");
  178629. + dmfc_wr_chan = 0x00000090;
  178630. + dmfc_dp_chan = 0x0000968a;
  178631. + ipu->dmfc_size_28 = 128*4;
  178632. + ipu->dmfc_size_29 = 0;
  178633. + ipu->dmfc_size_24 = 0;
  178634. + ipu->dmfc_size_27 = 128*4;
  178635. + ipu->dmfc_size_23 = 256*4;
  178636. + } else if (dmfc_type == DMFC_HIGH_RESOLUTION_ONLY_DP) {
  178637. + /* 5B - segement 0~3;
  178638. + * 5F - segement 4~7;
  178639. + * 1, 1C, 2C and 6B, 6F unused;
  178640. + */
  178641. + dev_info(ipu->dev, "IPU DMFC ONLY-DP HIGH RESOLUTION: 5B(0~3), 5F(4~7)\n");
  178642. + dmfc_wr_chan = 0x00000000;
  178643. + dmfc_dp_chan = 0x00008c88;
  178644. + ipu->dmfc_size_28 = 0;
  178645. + ipu->dmfc_size_29 = 0;
  178646. + ipu->dmfc_size_24 = 0;
  178647. + ipu->dmfc_size_27 = 256*4;
  178648. + ipu->dmfc_size_23 = 256*4;
  178649. + } else {
  178650. + /* 1 - segment 0, 1;
  178651. + * 5B - segement 4, 5;
  178652. + * 5F - segement 6, 7;
  178653. + * 1C, 2C and 6B, 6F unused;
  178654. + */
  178655. + dev_info(ipu->dev, "IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)\n");
  178656. + dmfc_wr_chan = 0x00000090;
  178657. + dmfc_dp_chan = 0x00009694;
  178658. + ipu->dmfc_size_28 = 128*4;
  178659. + ipu->dmfc_size_29 = 0;
  178660. + ipu->dmfc_size_24 = 0;
  178661. + ipu->dmfc_size_27 = 128*4;
  178662. + ipu->dmfc_size_23 = 128*4;
  178663. + }
  178664. + ipu_dmfc_write(ipu, dmfc_wr_chan, DMFC_WR_CHAN);
  178665. + ipu_dmfc_write(ipu, 0x202020F6, DMFC_WR_CHAN_DEF);
  178666. + ipu_dmfc_write(ipu, dmfc_dp_chan, DMFC_DP_CHAN);
  178667. + /* Enable chan 5 watermark set at 5 bursts and clear at 7 bursts */
  178668. + ipu_dmfc_write(ipu, 0x2020F6F6, DMFC_DP_CHAN_DEF);
  178669. +}
  178670. +
  178671. +static int __init dmfc_setup(char *options)
  178672. +{
  178673. + get_option(&options, &dmfc_type_setup);
  178674. + if (dmfc_type_setup > DMFC_HIGH_RESOLUTION_ONLY_DP)
  178675. + dmfc_type_setup = DMFC_HIGH_RESOLUTION_ONLY_DP;
  178676. + return 1;
  178677. +}
  178678. +__setup("dmfc=", dmfc_setup);
  178679. +
  178680. +void _ipu_dmfc_set_wait4eot(struct ipu_soc *ipu, int dma_chan, int width)
  178681. +{
  178682. + u32 dmfc_gen1 = ipu_dmfc_read(ipu, DMFC_GENERAL1);
  178683. +
  178684. + if (width >= HIGH_RESOLUTION_WIDTH) {
  178685. + if (dma_chan == 23)
  178686. + _ipu_dmfc_init(ipu, DMFC_HIGH_RESOLUTION_DP, 0);
  178687. + else if (dma_chan == 28)
  178688. + _ipu_dmfc_init(ipu, DMFC_HIGH_RESOLUTION_DC, 0);
  178689. + }
  178690. +
  178691. + if (dma_chan == 23) { /*5B*/
  178692. + if (ipu->dmfc_size_23/width > 3)
  178693. + dmfc_gen1 |= 1UL << 20;
  178694. + else
  178695. + dmfc_gen1 &= ~(1UL << 20);
  178696. + } else if (dma_chan == 24) { /*6B*/
  178697. + if (ipu->dmfc_size_24/width > 1)
  178698. + dmfc_gen1 |= 1UL << 22;
  178699. + else
  178700. + dmfc_gen1 &= ~(1UL << 22);
  178701. + } else if (dma_chan == 27) { /*5F*/
  178702. + if (ipu->dmfc_size_27/width > 2)
  178703. + dmfc_gen1 |= 1UL << 21;
  178704. + else
  178705. + dmfc_gen1 &= ~(1UL << 21);
  178706. + } else if (dma_chan == 28) { /*1*/
  178707. + if (ipu->dmfc_size_28/width > 2)
  178708. + dmfc_gen1 |= 1UL << 16;
  178709. + else
  178710. + dmfc_gen1 &= ~(1UL << 16);
  178711. + } else if (dma_chan == 29) { /*6F*/
  178712. + if (ipu->dmfc_size_29/width > 1)
  178713. + dmfc_gen1 |= 1UL << 23;
  178714. + else
  178715. + dmfc_gen1 &= ~(1UL << 23);
  178716. + }
  178717. +
  178718. + ipu_dmfc_write(ipu, dmfc_gen1, DMFC_GENERAL1);
  178719. +}
  178720. +
  178721. +void _ipu_dmfc_set_burst_size(struct ipu_soc *ipu, int dma_chan, int burst_size)
  178722. +{
  178723. + u32 dmfc_wr_chan = ipu_dmfc_read(ipu, DMFC_WR_CHAN);
  178724. + u32 dmfc_dp_chan = ipu_dmfc_read(ipu, DMFC_DP_CHAN);
  178725. + int dmfc_bs = 0;
  178726. +
  178727. + switch (burst_size) {
  178728. + case 64:
  178729. + dmfc_bs = 0x40;
  178730. + break;
  178731. + case 32:
  178732. + case 20:
  178733. + dmfc_bs = 0x80;
  178734. + break;
  178735. + case 16:
  178736. + dmfc_bs = 0xc0;
  178737. + break;
  178738. + default:
  178739. + dev_err(ipu->dev, "Unsupported burst size %d\n",
  178740. + burst_size);
  178741. + return;
  178742. + }
  178743. +
  178744. + if (dma_chan == 23) { /*5B*/
  178745. + dmfc_dp_chan &= ~(0xc0);
  178746. + dmfc_dp_chan |= dmfc_bs;
  178747. + } else if (dma_chan == 27) { /*5F*/
  178748. + dmfc_dp_chan &= ~(0xc000);
  178749. + dmfc_dp_chan |= (dmfc_bs << 8);
  178750. + } else if (dma_chan == 28) { /*1*/
  178751. + dmfc_wr_chan &= ~(0xc0);
  178752. + dmfc_wr_chan |= dmfc_bs;
  178753. + }
  178754. +
  178755. + ipu_dmfc_write(ipu, dmfc_wr_chan, DMFC_WR_CHAN);
  178756. + ipu_dmfc_write(ipu, dmfc_dp_chan, DMFC_DP_CHAN);
  178757. +}
  178758. +
  178759. +static void _ipu_di_data_wave_config(struct ipu_soc *ipu,
  178760. + int di, int wave_gen,
  178761. + int access_size, int component_size)
  178762. +{
  178763. + u32 reg;
  178764. + reg = (access_size << DI_DW_GEN_ACCESS_SIZE_OFFSET) |
  178765. + (component_size << DI_DW_GEN_COMPONENT_SIZE_OFFSET);
  178766. + ipu_di_write(ipu, di, reg, DI_DW_GEN(wave_gen));
  178767. +}
  178768. +
  178769. +static void _ipu_di_data_pin_config(struct ipu_soc *ipu,
  178770. + int di, int wave_gen, int di_pin, int set,
  178771. + int up, int down)
  178772. +{
  178773. + u32 reg;
  178774. +
  178775. + reg = ipu_di_read(ipu, di, DI_DW_GEN(wave_gen));
  178776. + reg &= ~(0x3 << (di_pin * 2));
  178777. + reg |= set << (di_pin * 2);
  178778. + ipu_di_write(ipu, di, reg, DI_DW_GEN(wave_gen));
  178779. +
  178780. + ipu_di_write(ipu, di, (down << 16) | up, DI_DW_SET(wave_gen, set));
  178781. +}
  178782. +
  178783. +static void _ipu_di_sync_config(struct ipu_soc *ipu,
  178784. + int di, int wave_gen,
  178785. + int run_count, int run_src,
  178786. + int offset_count, int offset_src,
  178787. + int repeat_count, int cnt_clr_src,
  178788. + int cnt_polarity_gen_en,
  178789. + int cnt_polarity_clr_src,
  178790. + int cnt_polarity_trigger_src,
  178791. + int cnt_up, int cnt_down)
  178792. +{
  178793. + u32 reg;
  178794. +
  178795. + if ((run_count >= 0x1000) || (offset_count >= 0x1000) || (repeat_count >= 0x1000) ||
  178796. + (cnt_up >= 0x400) || (cnt_down >= 0x400)) {
  178797. + dev_err(ipu->dev, "DI%d counters out of range.\n", di);
  178798. + return;
  178799. + }
  178800. +
  178801. + reg = (run_count << 19) | (++run_src << 16) |
  178802. + (offset_count << 3) | ++offset_src;
  178803. + ipu_di_write(ipu, di, reg, DI_SW_GEN0(wave_gen));
  178804. + reg = (cnt_polarity_gen_en << 29) | (++cnt_clr_src << 25) |
  178805. + (++cnt_polarity_trigger_src << 12) | (++cnt_polarity_clr_src << 9);
  178806. + reg |= (cnt_down << 16) | cnt_up;
  178807. + if (repeat_count == 0) {
  178808. + /* Enable auto reload */
  178809. + reg |= 0x10000000;
  178810. + }
  178811. + ipu_di_write(ipu, di, reg, DI_SW_GEN1(wave_gen));
  178812. + reg = ipu_di_read(ipu, di, DI_STP_REP(wave_gen));
  178813. + reg &= ~(0xFFFF << (16 * ((wave_gen - 1) & 0x1)));
  178814. + reg |= repeat_count << (16 * ((wave_gen - 1) & 0x1));
  178815. + ipu_di_write(ipu, di, reg, DI_STP_REP(wave_gen));
  178816. +}
  178817. +
  178818. +static void _ipu_dc_map_link(struct ipu_soc *ipu,
  178819. + int current_map,
  178820. + int base_map_0, int buf_num_0,
  178821. + int base_map_1, int buf_num_1,
  178822. + int base_map_2, int buf_num_2)
  178823. +{
  178824. + int ptr_0 = base_map_0 * 3 + buf_num_0;
  178825. + int ptr_1 = base_map_1 * 3 + buf_num_1;
  178826. + int ptr_2 = base_map_2 * 3 + buf_num_2;
  178827. + int ptr;
  178828. + u32 reg;
  178829. + ptr = (ptr_2 << 10) + (ptr_1 << 5) + ptr_0;
  178830. +
  178831. + reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(current_map));
  178832. + reg &= ~(0x1F << ((16 * (current_map & 0x1))));
  178833. + reg |= ptr << ((16 * (current_map & 0x1)));
  178834. + ipu_dc_write(ipu, reg, DC_MAP_CONF_PTR(current_map));
  178835. +}
  178836. +
  178837. +static void _ipu_dc_map_config(struct ipu_soc *ipu,
  178838. + int map, int byte_num, int offset, int mask)
  178839. +{
  178840. + int ptr = map * 3 + byte_num;
  178841. + u32 reg;
  178842. +
  178843. + reg = ipu_dc_read(ipu, DC_MAP_CONF_VAL(ptr));
  178844. + reg &= ~(0xFFFF << (16 * (ptr & 0x1)));
  178845. + reg |= ((offset << 8) | mask) << (16 * (ptr & 0x1));
  178846. + ipu_dc_write(ipu, reg, DC_MAP_CONF_VAL(ptr));
  178847. +
  178848. + reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(map));
  178849. + reg &= ~(0x1F << ((16 * (map & 0x1)) + (5 * byte_num)));
  178850. + reg |= ptr << ((16 * (map & 0x1)) + (5 * byte_num));
  178851. + ipu_dc_write(ipu, reg, DC_MAP_CONF_PTR(map));
  178852. +}
  178853. +
  178854. +static void _ipu_dc_map_clear(struct ipu_soc *ipu, int map)
  178855. +{
  178856. + u32 reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(map));
  178857. + ipu_dc_write(ipu, reg & ~(0xFFFF << (16 * (map & 0x1))),
  178858. + DC_MAP_CONF_PTR(map));
  178859. +}
  178860. +
  178861. +static void _ipu_dc_write_tmpl(struct ipu_soc *ipu,
  178862. + int word, u32 opcode, u32 operand, int map,
  178863. + int wave, int glue, int sync, int stop)
  178864. +{
  178865. + u32 reg;
  178866. +
  178867. + if (opcode == WRG) {
  178868. + reg = sync;
  178869. + reg |= (glue << 4);
  178870. + reg |= (++wave << 11);
  178871. + reg |= ((operand & 0x1FFFF) << 15);
  178872. + ipu_dc_tmpl_write(ipu, reg, word * 8);
  178873. +
  178874. + reg = (operand >> 17);
  178875. + reg |= opcode << 7;
  178876. + reg |= (stop << 9);
  178877. + ipu_dc_tmpl_write(ipu, reg, word * 8 + 4);
  178878. + } else {
  178879. + reg = sync;
  178880. + reg |= (glue << 4);
  178881. + reg |= (++wave << 11);
  178882. + reg |= (++map << 15);
  178883. + reg |= (operand << 20) & 0xFFF00000;
  178884. + ipu_dc_tmpl_write(ipu, reg, word * 8);
  178885. +
  178886. + reg = (operand >> 12);
  178887. + reg |= opcode << 4;
  178888. + reg |= (stop << 9);
  178889. + ipu_dc_tmpl_write(ipu, reg, word * 8 + 4);
  178890. + }
  178891. +}
  178892. +
  178893. +static void _ipu_dc_link_event(struct ipu_soc *ipu,
  178894. + int chan, int event, int addr, int priority)
  178895. +{
  178896. + u32 reg;
  178897. + u32 address_shift;
  178898. + if (event < DC_EVEN_UGDE0) {
  178899. + reg = ipu_dc_read(ipu, DC_RL_CH(chan, event));
  178900. + reg &= ~(0xFFFF << (16 * (event & 0x1)));
  178901. + reg |= ((addr << 8) | priority) << (16 * (event & 0x1));
  178902. + ipu_dc_write(ipu, reg, DC_RL_CH(chan, event));
  178903. + } else {
  178904. + reg = ipu_dc_read(ipu, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
  178905. + if ((event - DC_EVEN_UGDE0) & 0x1) {
  178906. + reg &= ~(0x2FF << 16);
  178907. + reg |= (addr << 16);
  178908. + reg |= priority ? (2 << 24) : 0x0;
  178909. + } else {
  178910. + reg &= ~0xFC00FFFF;
  178911. + if (priority)
  178912. + chan = (chan >> 1) +
  178913. + ((((chan & 0x1) + ((chan & 0x2) >> 1))) | (chan >> 3));
  178914. + else
  178915. + chan = 0x7;
  178916. + address_shift = ((event - DC_EVEN_UGDE0) >> 1) ? 7 : 8;
  178917. + reg |= (addr << address_shift) | (priority << 3) | chan;
  178918. + }
  178919. + ipu_dc_write(ipu, reg, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
  178920. + }
  178921. +}
  178922. +
  178923. +/* Y = R * 1.200 + G * 2.343 + B * .453 + 0.250;
  178924. + U = R * -.672 + G * -1.328 + B * 2.000 + 512.250.;
  178925. + V = R * 2.000 + G * -1.672 + B * -.328 + 512.250.;*/
  178926. +static const int rgb2ycbcr_coeff[5][3] = {
  178927. + {0x4D, 0x96, 0x1D},
  178928. + {-0x2B, -0x55, 0x80},
  178929. + {0x80, -0x6B, -0x15},
  178930. + {0x0000, 0x0200, 0x0200}, /* B0, B1, B2 */
  178931. + {0x2, 0x2, 0x2}, /* S0, S1, S2 */
  178932. +};
  178933. +
  178934. +/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128));
  178935. + G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128));
  178936. + B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */
  178937. +static const int ycbcr2rgb_coeff[5][3] = {
  178938. + {0x095, 0x000, 0x0CC},
  178939. + {0x095, 0x3CE, 0x398},
  178940. + {0x095, 0x0FF, 0x000},
  178941. + {0x3E42, 0x010A, 0x3DD6}, /*B0,B1,B2 */
  178942. + {0x1, 0x1, 0x1}, /*S0,S1,S2 */
  178943. +};
  178944. +
  178945. +#define mask_a(a) ((u32)(a) & 0x3FF)
  178946. +#define mask_b(b) ((u32)(b) & 0x3FFF)
  178947. +
  178948. +/* Pls keep S0, S1 and S2 as 0x2 by using this convertion */
  178949. +static int _rgb_to_yuv(int n, int red, int green, int blue)
  178950. +{
  178951. + int c;
  178952. + c = red * rgb2ycbcr_coeff[n][0];
  178953. + c += green * rgb2ycbcr_coeff[n][1];
  178954. + c += blue * rgb2ycbcr_coeff[n][2];
  178955. + c /= 16;
  178956. + c += rgb2ycbcr_coeff[3][n] * 4;
  178957. + c += 8;
  178958. + c /= 16;
  178959. + if (c < 0)
  178960. + c = 0;
  178961. + if (c > 255)
  178962. + c = 255;
  178963. + return c;
  178964. +}
  178965. +
  178966. +/*
  178967. + * Row is for BG: RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE
  178968. + * Column is for FG: RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE
  178969. + */
  178970. +static struct dp_csc_param_t dp_csc_array[CSC_NUM][CSC_NUM] = {
  178971. +{{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} },
  178972. +{{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} },
  178973. +{{0, 0}, {DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff}, {0, 0}, {0, 0}, {0, 0} },
  178974. +{{DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff}, {0, 0}, {0, 0}, {0, 0}, {0, 0} },
  178975. +{{DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff}, {DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff}, {0, 0}, {0, 0}, {0, 0} }
  178976. +};
  178977. +
  178978. +void __ipu_dp_csc_setup(struct ipu_soc *ipu,
  178979. + int dp, struct dp_csc_param_t dp_csc_param,
  178980. + bool srm_mode_update)
  178981. +{
  178982. + u32 reg;
  178983. + const int (*coeff)[5][3];
  178984. +
  178985. + if (dp_csc_param.mode >= 0) {
  178986. + reg = ipu_dp_read(ipu, DP_COM_CONF(dp));
  178987. + reg &= ~DP_COM_CONF_CSC_DEF_MASK;
  178988. + reg |= dp_csc_param.mode;
  178989. + ipu_dp_write(ipu, reg, DP_COM_CONF(dp));
  178990. + }
  178991. +
  178992. + coeff = dp_csc_param.coeff;
  178993. +
  178994. + if (coeff) {
  178995. + ipu_dp_write(ipu, mask_a((*coeff)[0][0]) |
  178996. + (mask_a((*coeff)[0][1]) << 16), DP_CSC_A_0(dp));
  178997. + ipu_dp_write(ipu, mask_a((*coeff)[0][2]) |
  178998. + (mask_a((*coeff)[1][0]) << 16), DP_CSC_A_1(dp));
  178999. + ipu_dp_write(ipu, mask_a((*coeff)[1][1]) |
  179000. + (mask_a((*coeff)[1][2]) << 16), DP_CSC_A_2(dp));
  179001. + ipu_dp_write(ipu, mask_a((*coeff)[2][0]) |
  179002. + (mask_a((*coeff)[2][1]) << 16), DP_CSC_A_3(dp));
  179003. + ipu_dp_write(ipu, mask_a((*coeff)[2][2]) |
  179004. + (mask_b((*coeff)[3][0]) << 16) |
  179005. + ((*coeff)[4][0] << 30), DP_CSC_0(dp));
  179006. + ipu_dp_write(ipu, mask_b((*coeff)[3][1]) | ((*coeff)[4][1] << 14) |
  179007. + (mask_b((*coeff)[3][2]) << 16) |
  179008. + ((*coeff)[4][2] << 30), DP_CSC_1(dp));
  179009. + }
  179010. +
  179011. + if (srm_mode_update) {
  179012. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  179013. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  179014. + }
  179015. +}
  179016. +
  179017. +int _ipu_dp_init(struct ipu_soc *ipu,
  179018. + ipu_channel_t channel, uint32_t in_pixel_fmt,
  179019. + uint32_t out_pixel_fmt)
  179020. +{
  179021. + int in_fmt, out_fmt;
  179022. + int dp;
  179023. + int partial = false;
  179024. + uint32_t reg;
  179025. +
  179026. + if (channel == MEM_FG_SYNC) {
  179027. + dp = DP_SYNC;
  179028. + partial = true;
  179029. + } else if (channel == MEM_BG_SYNC) {
  179030. + dp = DP_SYNC;
  179031. + partial = false;
  179032. + } else if (channel == MEM_BG_ASYNC0) {
  179033. + dp = DP_ASYNC0;
  179034. + partial = false;
  179035. + } else {
  179036. + return -EINVAL;
  179037. + }
  179038. +
  179039. + in_fmt = format_to_colorspace(in_pixel_fmt);
  179040. + out_fmt = format_to_colorspace(out_pixel_fmt);
  179041. +
  179042. + if (partial) {
  179043. + if (in_fmt == RGB) {
  179044. + if (out_fmt == RGB)
  179045. + ipu->fg_csc_type = RGB2RGB;
  179046. + else
  179047. + ipu->fg_csc_type = RGB2YUV;
  179048. + } else {
  179049. + if (out_fmt == RGB)
  179050. + ipu->fg_csc_type = YUV2RGB;
  179051. + else
  179052. + ipu->fg_csc_type = YUV2YUV;
  179053. + }
  179054. + } else {
  179055. + if (in_fmt == RGB) {
  179056. + if (out_fmt == RGB)
  179057. + ipu->bg_csc_type = RGB2RGB;
  179058. + else
  179059. + ipu->bg_csc_type = RGB2YUV;
  179060. + } else {
  179061. + if (out_fmt == RGB)
  179062. + ipu->bg_csc_type = YUV2RGB;
  179063. + else
  179064. + ipu->bg_csc_type = YUV2YUV;
  179065. + }
  179066. + }
  179067. +
  179068. + /* Transform color key from rgb to yuv if CSC is enabled */
  179069. + reg = ipu_dp_read(ipu, DP_COM_CONF(dp));
  179070. + if (ipu->color_key_4rgb && (reg & DP_COM_CONF_GWCKE) &&
  179071. + (((ipu->fg_csc_type == RGB2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  179072. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == RGB2YUV)) ||
  179073. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  179074. + ((ipu->fg_csc_type == YUV2RGB) && (ipu->bg_csc_type == YUV2RGB)))) {
  179075. + int red, green, blue;
  179076. + int y, u, v;
  179077. + uint32_t color_key = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(dp)) & 0xFFFFFFL;
  179078. +
  179079. + dev_dbg(ipu->dev, "_ipu_dp_init color key 0x%x need change to yuv fmt!\n", color_key);
  179080. +
  179081. + red = (color_key >> 16) & 0xFF;
  179082. + green = (color_key >> 8) & 0xFF;
  179083. + blue = color_key & 0xFF;
  179084. +
  179085. + y = _rgb_to_yuv(0, red, green, blue);
  179086. + u = _rgb_to_yuv(1, red, green, blue);
  179087. + v = _rgb_to_yuv(2, red, green, blue);
  179088. + color_key = (y << 16) | (u << 8) | v;
  179089. +
  179090. + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(dp)) & 0xFF000000L;
  179091. + ipu_dp_write(ipu, reg | color_key, DP_GRAPH_WIND_CTRL(dp));
  179092. + ipu->color_key_4rgb = false;
  179093. +
  179094. + dev_dbg(ipu->dev, "_ipu_dp_init color key change to yuv fmt 0x%x!\n", color_key);
  179095. + }
  179096. +
  179097. + __ipu_dp_csc_setup(ipu, dp, dp_csc_array[ipu->bg_csc_type][ipu->fg_csc_type], true);
  179098. +
  179099. + return 0;
  179100. +}
  179101. +
  179102. +void _ipu_dp_uninit(struct ipu_soc *ipu, ipu_channel_t channel)
  179103. +{
  179104. + int dp;
  179105. + int partial = false;
  179106. +
  179107. + if (channel == MEM_FG_SYNC) {
  179108. + dp = DP_SYNC;
  179109. + partial = true;
  179110. + } else if (channel == MEM_BG_SYNC) {
  179111. + dp = DP_SYNC;
  179112. + partial = false;
  179113. + } else if (channel == MEM_BG_ASYNC0) {
  179114. + dp = DP_ASYNC0;
  179115. + partial = false;
  179116. + } else {
  179117. + return;
  179118. + }
  179119. +
  179120. + if (partial)
  179121. + ipu->fg_csc_type = CSC_NONE;
  179122. + else
  179123. + ipu->bg_csc_type = CSC_NONE;
  179124. +
  179125. + __ipu_dp_csc_setup(ipu, dp, dp_csc_array[ipu->bg_csc_type][ipu->fg_csc_type], false);
  179126. +}
  179127. +
  179128. +void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt)
  179129. +{
  179130. + u32 reg = 0;
  179131. +
  179132. + if ((dc_chan == 1) || (dc_chan == 5)) {
  179133. + if (interlaced) {
  179134. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 0, 3);
  179135. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 0, 2);
  179136. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 0, 1);
  179137. + } else {
  179138. + if (di) {
  179139. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 2, 3);
  179140. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 3, 2);
  179141. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 1, 1);
  179142. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  179143. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  179144. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  179145. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  179146. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE1, 9, 5);
  179147. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE1, 8, 5);
  179148. + }
  179149. + } else {
  179150. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 5, 3);
  179151. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 6, 2);
  179152. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 12, 1);
  179153. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  179154. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  179155. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  179156. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  179157. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE0, 10, 5);
  179158. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE0, 11, 5);
  179159. + }
  179160. + }
  179161. + }
  179162. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NF, 0, 0);
  179163. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NFIELD, 0, 0);
  179164. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOF, 0, 0);
  179165. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOFIELD, 0, 0);
  179166. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN, 0, 0);
  179167. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR, 0, 0);
  179168. +
  179169. + reg = 0x2;
  179170. + reg |= DC_DISP_ID_SYNC(di) << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET;
  179171. + reg |= di << 2;
  179172. + if (interlaced)
  179173. + reg |= DC_WR_CH_CONF_FIELD_MODE;
  179174. + } else if ((dc_chan == 8) || (dc_chan == 9)) {
  179175. + /* async channels */
  179176. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_0, 0x64, 1);
  179177. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_1, 0x64, 1);
  179178. +
  179179. + reg = 0x3;
  179180. + reg |= DC_DISP_ID_SERIAL << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET;
  179181. + }
  179182. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  179183. +
  179184. + ipu_dc_write(ipu, 0x00000000, DC_WR_CH_ADDR(dc_chan));
  179185. +
  179186. + ipu_dc_write(ipu, 0x00000084, DC_GEN);
  179187. +}
  179188. +
  179189. +void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan)
  179190. +{
  179191. + if ((dc_chan == 1) || (dc_chan == 5)) {
  179192. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 0, 0);
  179193. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 0, 0);
  179194. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 0, 0);
  179195. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NF, 0, 0);
  179196. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NFIELD, 0, 0);
  179197. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOF, 0, 0);
  179198. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOFIELD, 0, 0);
  179199. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN, 0, 0);
  179200. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR, 0, 0);
  179201. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE0, 0, 0);
  179202. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE0, 0, 0);
  179203. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE1, 0, 0);
  179204. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE1, 0, 0);
  179205. + } else if ((dc_chan == 8) || (dc_chan == 9)) {
  179206. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_W_0, 0, 0);
  179207. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_W_1, 0, 0);
  179208. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_W_0, 0, 0);
  179209. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_W_1, 0, 0);
  179210. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_0, 0, 0);
  179211. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_1, 0, 0);
  179212. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_R_0, 0, 0);
  179213. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_R_1, 0, 0);
  179214. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_R_0, 0, 0);
  179215. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_R_1, 0, 0);
  179216. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_R_0, 0, 0);
  179217. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_R_1, 0, 0);
  179218. + }
  179219. +}
  179220. +
  179221. +int _ipu_disp_chan_is_interlaced(struct ipu_soc *ipu, ipu_channel_t channel)
  179222. +{
  179223. + if (channel == MEM_DC_SYNC)
  179224. + return !!(ipu_dc_read(ipu, DC_WR_CH_CONF_1) &
  179225. + DC_WR_CH_CONF_FIELD_MODE);
  179226. + else if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC))
  179227. + return !!(ipu_dc_read(ipu, DC_WR_CH_CONF_5) &
  179228. + DC_WR_CH_CONF_FIELD_MODE);
  179229. + return 0;
  179230. +}
  179231. +
  179232. +void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel)
  179233. +{
  179234. + int di;
  179235. + uint32_t reg;
  179236. + uint32_t dc_chan;
  179237. + int irq = 0;
  179238. +
  179239. + if (channel == MEM_FG_SYNC)
  179240. + irq = IPU_IRQ_DP_SF_END;
  179241. + else if (channel == MEM_DC_SYNC)
  179242. + dc_chan = 1;
  179243. + else if (channel == MEM_BG_SYNC)
  179244. + dc_chan = 5;
  179245. + else
  179246. + return;
  179247. +
  179248. + if (channel == MEM_FG_SYNC) {
  179249. + /* Enable FG channel */
  179250. + reg = ipu_dp_read(ipu, DP_COM_CONF(DP_SYNC));
  179251. + ipu_dp_write(ipu, reg | DP_COM_CONF_FG_EN, DP_COM_CONF(DP_SYNC));
  179252. +
  179253. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  179254. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  179255. + return;
  179256. + } else if (channel == MEM_BG_SYNC) {
  179257. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  179258. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  179259. + }
  179260. +
  179261. + di = ipu->dc_di_assignment[dc_chan];
  179262. +
  179263. + /* Make sure other DC sync channel is not assigned same DI */
  179264. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(6 - dc_chan));
  179265. + if ((di << 2) == (reg & DC_WR_CH_CONF_PROG_DI_ID)) {
  179266. + reg &= ~DC_WR_CH_CONF_PROG_DI_ID;
  179267. + reg |= di ? 0 : DC_WR_CH_CONF_PROG_DI_ID;
  179268. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(6 - dc_chan));
  179269. + }
  179270. +
  179271. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
  179272. + reg |= 4 << DC_WR_CH_CONF_PROG_TYPE_OFFSET;
  179273. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  179274. +
  179275. + clk_prepare_enable(ipu->pixel_clk[di]);
  179276. +}
  179277. +
  179278. +static irqreturn_t dc_irq_handler(int irq, void *dev_id)
  179279. +{
  179280. + struct ipu_soc *ipu = dev_id;
  179281. + struct completion *comp = &ipu->dc_comp;
  179282. + uint32_t reg;
  179283. + uint32_t dc_chan;
  179284. +
  179285. + if (irq == IPU_IRQ_DC_FC_1)
  179286. + dc_chan = 1;
  179287. + else
  179288. + dc_chan = 5;
  179289. +
  179290. + if (!ipu->dc_swap) {
  179291. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
  179292. + reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
  179293. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  179294. +
  179295. + reg = ipu_cm_read(ipu, IPU_DISP_GEN);
  179296. + if (ipu->dc_di_assignment[dc_chan])
  179297. + reg &= ~DI1_COUNTER_RELEASE;
  179298. + else
  179299. + reg &= ~DI0_COUNTER_RELEASE;
  179300. + ipu_cm_write(ipu, reg, IPU_DISP_GEN);
  179301. + }
  179302. +
  179303. + complete(comp);
  179304. + return IRQ_HANDLED;
  179305. +}
  179306. +
  179307. +void _ipu_dp_dc_disable(struct ipu_soc *ipu, ipu_channel_t channel, bool swap)
  179308. +{
  179309. + int ret;
  179310. + uint32_t reg;
  179311. + uint32_t csc;
  179312. + uint32_t dc_chan;
  179313. + int irq = 0;
  179314. + int timeout = 50;
  179315. +
  179316. + ipu->dc_swap = swap;
  179317. +
  179318. + if (channel == MEM_DC_SYNC) {
  179319. + dc_chan = 1;
  179320. + irq = IPU_IRQ_DC_FC_1;
  179321. + } else if (channel == MEM_BG_SYNC) {
  179322. + dc_chan = 5;
  179323. + irq = IPU_IRQ_DP_SF_END;
  179324. + } else if (channel == MEM_FG_SYNC) {
  179325. + /* Disable FG channel */
  179326. + dc_chan = 5;
  179327. +
  179328. + reg = ipu_dp_read(ipu, DP_COM_CONF(DP_SYNC));
  179329. + csc = reg & DP_COM_CONF_CSC_DEF_MASK;
  179330. + if (csc == DP_COM_CONF_CSC_DEF_FG)
  179331. + reg &= ~DP_COM_CONF_CSC_DEF_MASK;
  179332. +
  179333. + reg &= ~DP_COM_CONF_FG_EN;
  179334. + ipu_dp_write(ipu, reg, DP_COM_CONF(DP_SYNC));
  179335. +
  179336. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  179337. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  179338. +
  179339. + if (ipu_is_channel_busy(ipu, MEM_BG_SYNC)) {
  179340. + ipu_cm_write(ipu, IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END),
  179341. + IPUIRQ_2_STATREG(IPU_IRQ_DP_SF_END));
  179342. + while ((ipu_cm_read(ipu, IPUIRQ_2_STATREG(IPU_IRQ_DP_SF_END)) &
  179343. + IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END)) == 0) {
  179344. + msleep(2);
  179345. + timeout -= 2;
  179346. + if (timeout <= 0)
  179347. + break;
  179348. + }
  179349. + }
  179350. + return;
  179351. + } else {
  179352. + return;
  179353. + }
  179354. +
  179355. + init_completion(&ipu->dc_comp);
  179356. + ret = ipu_request_irq(ipu, irq, dc_irq_handler, 0, NULL, ipu);
  179357. + if (ret < 0) {
  179358. + dev_err(ipu->dev, "DC irq %d in use\n", irq);
  179359. + return;
  179360. + }
  179361. + ret = wait_for_completion_timeout(&ipu->dc_comp, msecs_to_jiffies(50));
  179362. + ipu_free_irq(ipu, irq, ipu);
  179363. + dev_dbg(ipu->dev, "DC stop timeout - %d * 10ms\n", 5 - ret);
  179364. +
  179365. + if (ipu->dc_swap) {
  179366. + /* Swap DC channel 1 and 5 settings, and disable old dc chan */
  179367. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
  179368. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(6 - dc_chan));
  179369. + reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
  179370. + reg ^= DC_WR_CH_CONF_PROG_DI_ID;
  179371. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  179372. + }
  179373. +}
  179374. +
  179375. +void _ipu_init_dc_mappings(struct ipu_soc *ipu)
  179376. +{
  179377. + /* IPU_PIX_FMT_RGB24 */
  179378. + _ipu_dc_map_clear(ipu, 0);
  179379. + _ipu_dc_map_config(ipu, 0, 0, 7, 0xFF);
  179380. + _ipu_dc_map_config(ipu, 0, 1, 15, 0xFF);
  179381. + _ipu_dc_map_config(ipu, 0, 2, 23, 0xFF);
  179382. +
  179383. + /* IPU_PIX_FMT_RGB666 */
  179384. + _ipu_dc_map_clear(ipu, 1);
  179385. + _ipu_dc_map_config(ipu, 1, 0, 5, 0xFC);
  179386. + _ipu_dc_map_config(ipu, 1, 1, 11, 0xFC);
  179387. + _ipu_dc_map_config(ipu, 1, 2, 17, 0xFC);
  179388. +
  179389. + /* IPU_PIX_FMT_YUV444 */
  179390. + _ipu_dc_map_clear(ipu, 2);
  179391. + _ipu_dc_map_config(ipu, 2, 0, 15, 0xFF);
  179392. + _ipu_dc_map_config(ipu, 2, 1, 23, 0xFF);
  179393. + _ipu_dc_map_config(ipu, 2, 2, 7, 0xFF);
  179394. +
  179395. + /* IPU_PIX_FMT_RGB565 */
  179396. + _ipu_dc_map_clear(ipu, 3);
  179397. + _ipu_dc_map_config(ipu, 3, 0, 4, 0xF8);
  179398. + _ipu_dc_map_config(ipu, 3, 1, 10, 0xFC);
  179399. + _ipu_dc_map_config(ipu, 3, 2, 15, 0xF8);
  179400. +
  179401. + /* IPU_PIX_FMT_LVDS666 */
  179402. + _ipu_dc_map_clear(ipu, 4);
  179403. + _ipu_dc_map_config(ipu, 4, 0, 5, 0xFC);
  179404. + _ipu_dc_map_config(ipu, 4, 1, 13, 0xFC);
  179405. + _ipu_dc_map_config(ipu, 4, 2, 21, 0xFC);
  179406. +
  179407. + /* IPU_PIX_FMT_VYUY 16bit width */
  179408. + _ipu_dc_map_clear(ipu, 5);
  179409. + _ipu_dc_map_config(ipu, 5, 0, 7, 0xFF);
  179410. + _ipu_dc_map_config(ipu, 5, 1, 0, 0x0);
  179411. + _ipu_dc_map_config(ipu, 5, 2, 15, 0xFF);
  179412. + _ipu_dc_map_clear(ipu, 6);
  179413. + _ipu_dc_map_config(ipu, 6, 0, 0, 0x0);
  179414. + _ipu_dc_map_config(ipu, 6, 1, 7, 0xFF);
  179415. + _ipu_dc_map_config(ipu, 6, 2, 15, 0xFF);
  179416. +
  179417. + /* IPU_PIX_FMT_UYUV 16bit width */
  179418. + _ipu_dc_map_clear(ipu, 7);
  179419. + _ipu_dc_map_link(ipu, 7, 6, 0, 6, 1, 6, 2);
  179420. + _ipu_dc_map_clear(ipu, 8);
  179421. + _ipu_dc_map_link(ipu, 8, 5, 0, 5, 1, 5, 2);
  179422. +
  179423. + /* IPU_PIX_FMT_YUYV 16bit width */
  179424. + _ipu_dc_map_clear(ipu, 9);
  179425. + _ipu_dc_map_link(ipu, 9, 5, 2, 5, 1, 5, 0);
  179426. + _ipu_dc_map_clear(ipu, 10);
  179427. + _ipu_dc_map_link(ipu, 10, 5, 1, 5, 2, 5, 0);
  179428. +
  179429. + /* IPU_PIX_FMT_YVYU 16bit width */
  179430. + _ipu_dc_map_clear(ipu, 11);
  179431. + _ipu_dc_map_link(ipu, 11, 5, 1, 5, 2, 5, 0);
  179432. + _ipu_dc_map_clear(ipu, 12);
  179433. + _ipu_dc_map_link(ipu, 12, 5, 2, 5, 1, 5, 0);
  179434. +
  179435. + /* IPU_PIX_FMT_GBR24 */
  179436. + /* IPU_PIX_FMT_VYU444 */
  179437. + _ipu_dc_map_clear(ipu, 13);
  179438. + _ipu_dc_map_link(ipu, 13, 0, 2, 0, 0, 0, 1);
  179439. +
  179440. + /* IPU_PIX_FMT_BGR24 */
  179441. + _ipu_dc_map_clear(ipu, 14);
  179442. + _ipu_dc_map_link(ipu, 14, 0, 2, 0, 1, 0, 0);
  179443. +}
  179444. +
  179445. +int _ipu_pixfmt_to_map(uint32_t fmt)
  179446. +{
  179447. + switch (fmt) {
  179448. + case IPU_PIX_FMT_GENERIC:
  179449. + case IPU_PIX_FMT_RGB24:
  179450. + return 0;
  179451. + case IPU_PIX_FMT_RGB666:
  179452. + return 1;
  179453. + case IPU_PIX_FMT_YUV444:
  179454. + return 2;
  179455. + case IPU_PIX_FMT_RGB565:
  179456. + return 3;
  179457. + case IPU_PIX_FMT_LVDS666:
  179458. + return 4;
  179459. + case IPU_PIX_FMT_VYUY:
  179460. + return 6;
  179461. + case IPU_PIX_FMT_UYVY:
  179462. + return 8;
  179463. + case IPU_PIX_FMT_YUYV:
  179464. + return 10;
  179465. + case IPU_PIX_FMT_YVYU:
  179466. + return 12;
  179467. + case IPU_PIX_FMT_GBR24:
  179468. + case IPU_PIX_FMT_VYU444:
  179469. + return 13;
  179470. + case IPU_PIX_FMT_BGR24:
  179471. + return 14;
  179472. + }
  179473. +
  179474. + return -1;
  179475. +}
  179476. +
  179477. +/*!
  179478. + * This function sets the colorspace for of dp.
  179479. + * modes.
  179480. + *
  179481. + * @param ipu ipu handler
  179482. + * @param channel Input parameter for the logical channel ID.
  179483. + *
  179484. + * @param param If it's not NULL, update the csc table
  179485. + * with this parameter.
  179486. + *
  179487. + * @return N/A
  179488. + */
  179489. +void _ipu_dp_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3])
  179490. +{
  179491. + int dp;
  179492. + struct dp_csc_param_t dp_csc_param;
  179493. +
  179494. + if (channel == MEM_FG_SYNC)
  179495. + dp = DP_SYNC;
  179496. + else if (channel == MEM_BG_SYNC)
  179497. + dp = DP_SYNC;
  179498. + else if (channel == MEM_BG_ASYNC0)
  179499. + dp = DP_ASYNC0;
  179500. + else
  179501. + return;
  179502. +
  179503. + dp_csc_param.mode = -1;
  179504. + dp_csc_param.coeff = param;
  179505. + __ipu_dp_csc_setup(ipu, dp, dp_csc_param, true);
  179506. +}
  179507. +
  179508. +void ipu_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3])
  179509. +{
  179510. + _ipu_dp_set_csc_coefficients(ipu, channel, param);
  179511. +}
  179512. +EXPORT_SYMBOL(ipu_set_csc_coefficients);
  179513. +
  179514. +/*!
  179515. + * This function is called to adapt synchronous LCD panel to IPU restriction.
  179516. + *
  179517. + */
  179518. +void adapt_panel_to_ipu_restricitions(struct ipu_soc *ipu, uint16_t *v_start_width,
  179519. + uint16_t *v_sync_width,
  179520. + uint16_t *v_end_width)
  179521. +{
  179522. + if (*v_end_width < 2) {
  179523. + uint16_t diff = 2 - *v_end_width;
  179524. + if (*v_start_width >= diff) {
  179525. + *v_end_width = 2;
  179526. + *v_start_width = *v_start_width - diff;
  179527. + } else if (*v_sync_width > diff) {
  179528. + *v_end_width = 2;
  179529. + *v_sync_width = *v_sync_width - diff;
  179530. + } else
  179531. + dev_err(ipu->dev, "WARNING: try to adapt timming, but failed\n");
  179532. + dev_err(ipu->dev, "WARNING: adapt panel end blank lines\n");
  179533. + }
  179534. +}
  179535. +
  179536. +/*!
  179537. + * This function is called to initialize a synchronous LCD panel.
  179538. + *
  179539. + * @param ipu ipu handler
  179540. + * @param disp The DI the panel is attached to.
  179541. + *
  179542. + * @param pixel_clk Desired pixel clock frequency in Hz.
  179543. + *
  179544. + * @param pixel_fmt Input parameter for pixel format of buffer.
  179545. + * Pixel format is a FOURCC ASCII code.
  179546. + *
  179547. + * @param width The width of panel in pixels.
  179548. + *
  179549. + * @param height The height of panel in pixels.
  179550. + *
  179551. + * @param hStartWidth The number of pixel clocks between the HSYNC
  179552. + * signal pulse and the start of valid data.
  179553. + *
  179554. + * @param hSyncWidth The width of the HSYNC signal in units of pixel
  179555. + * clocks.
  179556. + *
  179557. + * @param hEndWidth The number of pixel clocks between the end of
  179558. + * valid data and the HSYNC signal for next line.
  179559. + *
  179560. + * @param vStartWidth The number of lines between the VSYNC
  179561. + * signal pulse and the start of valid data.
  179562. + *
  179563. + * @param vSyncWidth The width of the VSYNC signal in units of lines
  179564. + *
  179565. + * @param vEndWidth The number of lines between the end of valid
  179566. + * data and the VSYNC signal for next frame.
  179567. + *
  179568. + * @param sig Bitfield of signal polarities for LCD interface.
  179569. + *
  179570. + * @return This function returns 0 on success or negative error code on
  179571. + * fail.
  179572. + */
  179573. +int32_t ipu_init_sync_panel(struct ipu_soc *ipu, int disp, uint32_t pixel_clk,
  179574. + uint16_t width, uint16_t height,
  179575. + uint32_t pixel_fmt,
  179576. + uint16_t h_start_width, uint16_t h_sync_width,
  179577. + uint16_t h_end_width, uint16_t v_start_width,
  179578. + uint16_t v_sync_width, uint16_t v_end_width,
  179579. + uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig)
  179580. +{
  179581. + uint32_t field0_offset = 0;
  179582. + uint32_t field1_offset;
  179583. + uint32_t reg;
  179584. + uint32_t di_gen, vsync_cnt;
  179585. + uint32_t div, rounded_pixel_clk;
  179586. + uint32_t h_total, v_total;
  179587. + int map;
  179588. + int ret;
  179589. + struct clk *ldb_di0_clk, *ldb_di1_clk;
  179590. + struct clk *di_parent;
  179591. +
  179592. + dev_dbg(ipu->dev, "panel size = %d x %d\n", width, height);
  179593. +
  179594. + if ((v_sync_width == 0) || (h_sync_width == 0))
  179595. + return -EINVAL;
  179596. +
  179597. + adapt_panel_to_ipu_restricitions(ipu, &v_start_width, &v_sync_width, &v_end_width);
  179598. + h_total = width + h_sync_width + h_start_width + h_end_width;
  179599. + v_total = height + v_sync_width + v_start_width + v_end_width;
  179600. +
  179601. + /* Init clocking */
  179602. + dev_dbg(ipu->dev, "pixel clk = %d\n", pixel_clk);
  179603. +
  179604. + di_parent = clk_get_parent(ipu->di_clk_sel[disp]);
  179605. + if (!di_parent) {
  179606. + dev_err(ipu->dev, "get di clk parent fail\n");
  179607. + return -EINVAL;
  179608. + }
  179609. + ldb_di0_clk = clk_get(ipu->dev, "ldb_di0");
  179610. + if (IS_ERR(ldb_di0_clk)) {
  179611. + dev_err(ipu->dev, "clk_get di0 failed");
  179612. + return PTR_ERR(ldb_di0_clk);
  179613. + }
  179614. + ldb_di1_clk = clk_get(ipu->dev, "ldb_di1");
  179615. + if (IS_ERR(ldb_di1_clk)) {
  179616. + dev_err(ipu->dev, "clk_get di1 failed");
  179617. + return PTR_ERR(ldb_di1_clk);
  179618. + }
  179619. +
  179620. + if (ldb_di0_clk == di_parent || ldb_di1_clk == di_parent) {
  179621. + /* if di clk parent is tve/ldb, then keep it;*/
  179622. + dev_dbg(ipu->dev, "use special clk parent\n");
  179623. + ret = clk_set_parent(ipu->pixel_clk_sel[disp], ipu->di_clk[disp]);
  179624. + if (ret) {
  179625. + dev_err(ipu->dev, "set pixel clk error:%d\n", ret);
  179626. + return ret;
  179627. + }
  179628. + clk_put(ldb_di0_clk);
  179629. + clk_put(ldb_di1_clk);
  179630. + } else {
  179631. + /* try ipu clk first*/
  179632. + dev_dbg(ipu->dev, "try ipu internal clk\n");
  179633. + ret = clk_set_parent(ipu->pixel_clk_sel[disp], ipu->ipu_clk);
  179634. + if (ret) {
  179635. + dev_err(ipu->dev, "set pixel clk error:%d\n", ret);
  179636. + return ret;
  179637. + }
  179638. + rounded_pixel_clk = clk_round_rate(ipu->pixel_clk[disp], pixel_clk);
  179639. + dev_dbg(ipu->dev, "rounded pix clk:%d\n", rounded_pixel_clk);
  179640. + /*
  179641. + * we will only use 1/2 fraction for ipu clk,
  179642. + * so if the clk rate is not fit, try ext clk.
  179643. + */
  179644. + if (!sig.int_clk &&
  179645. + ((rounded_pixel_clk >= pixel_clk + pixel_clk/200) ||
  179646. + (rounded_pixel_clk <= pixel_clk - pixel_clk/200))) {
  179647. + dev_dbg(ipu->dev, "try ipu ext di clk\n");
  179648. +
  179649. + rounded_pixel_clk =
  179650. + clk_round_rate(ipu->di_clk[disp], pixel_clk);
  179651. + ret = clk_set_rate(ipu->di_clk[disp],
  179652. + rounded_pixel_clk);
  179653. + if (ret) {
  179654. + dev_err(ipu->dev,
  179655. + "set di clk rate error:%d\n", ret);
  179656. + return ret;
  179657. + }
  179658. + dev_dbg(ipu->dev, "di clk:%d\n", rounded_pixel_clk);
  179659. + ret = clk_set_parent(ipu->pixel_clk_sel[disp],
  179660. + ipu->di_clk[disp]);
  179661. + if (ret) {
  179662. + dev_err(ipu->dev,
  179663. + "set pixel clk parent error:%d\n", ret);
  179664. + return ret;
  179665. + }
  179666. + }
  179667. + }
  179668. + rounded_pixel_clk = clk_round_rate(ipu->pixel_clk[disp], pixel_clk);
  179669. + dev_dbg(ipu->dev, "round pixel clk:%d\n", rounded_pixel_clk);
  179670. + ret = clk_set_rate(ipu->pixel_clk[disp], rounded_pixel_clk);
  179671. + if (ret) {
  179672. + dev_err(ipu->dev, "set pixel clk rate error:%d\n", ret);
  179673. + return ret;
  179674. + }
  179675. + msleep(5);
  179676. + /* Get integer portion of divider */
  179677. + div = clk_get_rate(clk_get_parent(ipu->pixel_clk_sel[disp])) / rounded_pixel_clk;
  179678. + dev_dbg(ipu->dev, "div:%d\n", div);
  179679. + if (!div) {
  179680. + dev_err(ipu->dev, "invalid pixel clk div = 0\n");
  179681. + return -EINVAL;
  179682. + }
  179683. +
  179684. +
  179685. + mutex_lock(&ipu->mutex_lock);
  179686. +
  179687. + _ipu_di_data_wave_config(ipu, disp, SYNC_WAVE, div - 1, div - 1);
  179688. + _ipu_di_data_pin_config(ipu, disp, SYNC_WAVE, DI_PIN15, 3, 0, div * 2);
  179689. +
  179690. + map = _ipu_pixfmt_to_map(pixel_fmt);
  179691. + if (map < 0) {
  179692. + dev_dbg(ipu->dev, "IPU_DISP: No MAP\n");
  179693. + mutex_unlock(&ipu->mutex_lock);
  179694. + return -EINVAL;
  179695. + }
  179696. +
  179697. + /*clear DI*/
  179698. + di_gen = ipu_di_read(ipu, disp, DI_GENERAL);
  179699. + di_gen &= (0x3 << 20);
  179700. + ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
  179701. +
  179702. + if (sig.interlaced) {
  179703. + if (g_ipu_hw_rev >= IPU_V3DEX) {
  179704. + /* Setup internal HSYNC waveform */
  179705. + _ipu_di_sync_config(ipu,
  179706. + disp, /* display */
  179707. + 1, /* counter */
  179708. + h_total/2 - 1, /* run count */
  179709. + DI_SYNC_CLK, /* run_resolution */
  179710. + 0, /* offset */
  179711. + DI_SYNC_NONE, /* offset resolution */
  179712. + 0, /* repeat count */
  179713. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  179714. + 0, /* CNT_POLARITY_GEN_EN */
  179715. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179716. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179717. + 0, /* COUNT UP */
  179718. + 0 /* COUNT DOWN */
  179719. + );
  179720. +
  179721. + /* Field 1 VSYNC waveform */
  179722. + _ipu_di_sync_config(ipu,
  179723. + disp, /* display */
  179724. + 2, /* counter */
  179725. + h_total - 1, /* run count */
  179726. + DI_SYNC_CLK, /* run_resolution */
  179727. + 0, /* offset */
  179728. + DI_SYNC_NONE, /* offset resolution */
  179729. + 0, /* repeat count */
  179730. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  179731. + 0, /* CNT_POLARITY_GEN_EN */
  179732. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179733. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179734. + 0, /* COUNT UP */
  179735. + 2*div /* COUNT DOWN */
  179736. + );
  179737. +
  179738. + /* Setup internal HSYNC waveform */
  179739. + _ipu_di_sync_config(ipu,
  179740. + disp, /* display */
  179741. + 3, /* counter */
  179742. + v_total*2 - 1, /* run count */
  179743. + DI_SYNC_INT_HSYNC, /* run_resolution */
  179744. + 1, /* offset */
  179745. + DI_SYNC_INT_HSYNC, /* offset resolution */
  179746. + 0, /* repeat count */
  179747. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  179748. + 0, /* CNT_POLARITY_GEN_EN */
  179749. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179750. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179751. + 0, /* COUNT UP */
  179752. + 2*div /* COUNT DOWN */
  179753. + );
  179754. +
  179755. + /* Active Field ? */
  179756. + _ipu_di_sync_config(ipu,
  179757. + disp, /* display */
  179758. + 4, /* counter */
  179759. + v_total/2 - 1, /* run count */
  179760. + DI_SYNC_HSYNC, /* run_resolution */
  179761. + v_start_width, /* offset */
  179762. + DI_SYNC_HSYNC, /* offset resolution */
  179763. + 2, /* repeat count */
  179764. + DI_SYNC_VSYNC, /* CNT_CLR_SEL */
  179765. + 0, /* CNT_POLARITY_GEN_EN */
  179766. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179767. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179768. + 0, /* COUNT UP */
  179769. + 0 /* COUNT DOWN */
  179770. + );
  179771. +
  179772. + /* Active Line */
  179773. + _ipu_di_sync_config(ipu,
  179774. + disp, /* display */
  179775. + 5, /* counter */
  179776. + 0, /* run count */
  179777. + DI_SYNC_HSYNC, /* run_resolution */
  179778. + 0, /* offset */
  179779. + DI_SYNC_NONE, /* offset resolution */
  179780. + height/2, /* repeat count */
  179781. + 4, /* CNT_CLR_SEL */
  179782. + 0, /* CNT_POLARITY_GEN_EN */
  179783. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179784. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179785. + 0, /* COUNT UP */
  179786. + 0 /* COUNT DOWN */
  179787. + );
  179788. +
  179789. + /* Field 0 VSYNC waveform */
  179790. + _ipu_di_sync_config(ipu,
  179791. + disp, /* display */
  179792. + 6, /* counter */
  179793. + v_total - 1, /* run count */
  179794. + DI_SYNC_HSYNC, /* run_resolution */
  179795. + 0, /* offset */
  179796. + DI_SYNC_NONE, /* offset resolution */
  179797. + 0, /* repeat count */
  179798. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  179799. + 0, /* CNT_POLARITY_GEN_EN */
  179800. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179801. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179802. + 0, /* COUNT UP */
  179803. + 0 /* COUNT DOWN */
  179804. + );
  179805. +
  179806. + /* DC VSYNC waveform */
  179807. + vsync_cnt = 7;
  179808. + _ipu_di_sync_config(ipu,
  179809. + disp, /* display */
  179810. + 7, /* counter */
  179811. + v_total/2 - 1, /* run count */
  179812. + DI_SYNC_HSYNC, /* run_resolution */
  179813. + 9, /* offset */
  179814. + DI_SYNC_HSYNC, /* offset resolution */
  179815. + 2, /* repeat count */
  179816. + DI_SYNC_VSYNC, /* CNT_CLR_SEL */
  179817. + 0, /* CNT_POLARITY_GEN_EN */
  179818. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179819. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179820. + 0, /* COUNT UP */
  179821. + 0 /* COUNT DOWN */
  179822. + );
  179823. +
  179824. + /* active pixel waveform */
  179825. + _ipu_di_sync_config(ipu,
  179826. + disp, /* display */
  179827. + 8, /* counter */
  179828. + 0, /* run count */
  179829. + DI_SYNC_CLK, /* run_resolution */
  179830. + h_start_width, /* offset */
  179831. + DI_SYNC_CLK, /* offset resolution */
  179832. + width, /* repeat count */
  179833. + 5, /* CNT_CLR_SEL */
  179834. + 0, /* CNT_POLARITY_GEN_EN */
  179835. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179836. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179837. + 0, /* COUNT UP */
  179838. + 0 /* COUNT DOWN */
  179839. + );
  179840. +
  179841. + /* Second VSYNC */
  179842. + _ipu_di_sync_config(ipu,
  179843. + disp, /* display */
  179844. + 9, /* counter */
  179845. + v_total - 1, /* run count */
  179846. + DI_SYNC_INT_HSYNC, /* run_resolution */
  179847. + v_total/2, /* offset */
  179848. + DI_SYNC_INT_HSYNC, /* offset resolution */
  179849. + 0, /* repeat count */
  179850. + DI_SYNC_HSYNC, /* CNT_CLR_SEL */
  179851. + 0, /* CNT_POLARITY_GEN_EN */
  179852. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  179853. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  179854. + 0, /* COUNT UP */
  179855. + 2*div /* COUNT DOWN */
  179856. + );
  179857. +
  179858. + /* set gentime select and tag sel */
  179859. + reg = ipu_di_read(ipu, disp, DI_SW_GEN1(9));
  179860. + reg &= 0x1FFFFFFF;
  179861. + reg |= (3-1)<<29 | 0x00008000;
  179862. + ipu_di_write(ipu, disp, reg, DI_SW_GEN1(9));
  179863. +
  179864. + ipu_di_write(ipu, disp, v_total / 2 - 1, DI_SCR_CONF);
  179865. +
  179866. + /* set y_sel = 1 */
  179867. + di_gen |= 0x10000000;
  179868. + di_gen |= DI_GEN_POLARITY_5;
  179869. + di_gen |= DI_GEN_POLARITY_8;
  179870. + } else {
  179871. + /* Setup internal HSYNC waveform */
  179872. + _ipu_di_sync_config(ipu, disp, 1, h_total - 1, DI_SYNC_CLK,
  179873. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
  179874. + DI_SYNC_NONE, 0, 0);
  179875. +
  179876. + field1_offset = v_sync_width + v_start_width + height / 2 +
  179877. + v_end_width;
  179878. + if (sig.odd_field_first) {
  179879. + field0_offset = field1_offset - 1;
  179880. + field1_offset = 0;
  179881. + }
  179882. + v_total += v_start_width + v_end_width;
  179883. +
  179884. + /* Field 1 VSYNC waveform */
  179885. + _ipu_di_sync_config(ipu, disp, 2, v_total - 1, 1,
  179886. + field0_offset,
  179887. + field0_offset ? 1 : DI_SYNC_NONE,
  179888. + 0, DI_SYNC_NONE, 0,
  179889. + DI_SYNC_NONE, DI_SYNC_NONE, 0, 4);
  179890. +
  179891. + /* Setup internal HSYNC waveform */
  179892. + _ipu_di_sync_config(ipu, disp, 3, h_total - 1, DI_SYNC_CLK,
  179893. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0,
  179894. + DI_SYNC_NONE, DI_SYNC_NONE, 0, 4);
  179895. +
  179896. + /* Active Field ? */
  179897. + _ipu_di_sync_config(ipu, disp, 4,
  179898. + field0_offset ?
  179899. + field0_offset : field1_offset - 2,
  179900. + 1, v_start_width + v_sync_width, 1, 2, 2,
  179901. + 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0);
  179902. +
  179903. + /* Active Line */
  179904. + _ipu_di_sync_config(ipu, disp, 5, 0, 1,
  179905. + 0, DI_SYNC_NONE,
  179906. + height / 2, 4, 0, DI_SYNC_NONE,
  179907. + DI_SYNC_NONE, 0, 0);
  179908. +
  179909. + /* Field 0 VSYNC waveform */
  179910. + _ipu_di_sync_config(ipu, disp, 6, v_total - 1, 1,
  179911. + 0, DI_SYNC_NONE,
  179912. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
  179913. + DI_SYNC_NONE, 0, 0);
  179914. +
  179915. + /* DC VSYNC waveform */
  179916. + vsync_cnt = 7;
  179917. + _ipu_di_sync_config(ipu, disp, 7, 0, 1,
  179918. + field1_offset,
  179919. + field1_offset ? 1 : DI_SYNC_NONE,
  179920. + 1, 2, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0);
  179921. +
  179922. + /* active pixel waveform */
  179923. + _ipu_di_sync_config(ipu, disp, 8, 0, DI_SYNC_CLK,
  179924. + h_sync_width + h_start_width, DI_SYNC_CLK,
  179925. + width, 5, 0, DI_SYNC_NONE, DI_SYNC_NONE,
  179926. + 0, 0);
  179927. +
  179928. + /* ??? */
  179929. + _ipu_di_sync_config(ipu, disp, 9, v_total - 1, 2,
  179930. + 0, DI_SYNC_NONE,
  179931. + 0, DI_SYNC_NONE, 6, DI_SYNC_NONE,
  179932. + DI_SYNC_NONE, 0, 0);
  179933. +
  179934. + reg = ipu_di_read(ipu, disp, DI_SW_GEN1(9));
  179935. + reg |= 0x8000;
  179936. + ipu_di_write(ipu, disp, reg, DI_SW_GEN1(9));
  179937. +
  179938. + ipu_di_write(ipu, disp, v_sync_width + v_start_width +
  179939. + v_end_width + height / 2 - 1, DI_SCR_CONF);
  179940. + }
  179941. +
  179942. + /* Init template microcode */
  179943. + _ipu_dc_write_tmpl(ipu, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1);
  179944. +
  179945. + if (sig.Hsync_pol)
  179946. + di_gen |= DI_GEN_POLARITY_3;
  179947. + if (sig.Vsync_pol)
  179948. + di_gen |= DI_GEN_POLARITY_2;
  179949. + } else {
  179950. + /* Setup internal HSYNC waveform */
  179951. + _ipu_di_sync_config(ipu, disp, 1, h_total - 1, DI_SYNC_CLK,
  179952. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
  179953. + DI_SYNC_NONE, 0, 0);
  179954. +
  179955. + /* Setup external (delayed) HSYNC waveform */
  179956. + _ipu_di_sync_config(ipu, disp, DI_SYNC_HSYNC, h_total - 1,
  179957. + DI_SYNC_CLK, div * v_to_h_sync, DI_SYNC_CLK,
  179958. + 0, DI_SYNC_NONE, 1, DI_SYNC_NONE,
  179959. + DI_SYNC_CLK, 0, h_sync_width * 2);
  179960. + /* Setup VSYNC waveform */
  179961. + vsync_cnt = DI_SYNC_VSYNC;
  179962. + _ipu_di_sync_config(ipu, disp, DI_SYNC_VSYNC, v_total - 1,
  179963. + DI_SYNC_INT_HSYNC, 0, DI_SYNC_NONE, 0,
  179964. + DI_SYNC_NONE, 1, DI_SYNC_NONE,
  179965. + DI_SYNC_INT_HSYNC, 0, v_sync_width * 2);
  179966. + ipu_di_write(ipu, disp, v_total - 1, DI_SCR_CONF);
  179967. +
  179968. + /* Setup active data waveform to sync with DC */
  179969. + _ipu_di_sync_config(ipu, disp, 4, 0, DI_SYNC_HSYNC,
  179970. + v_sync_width + v_start_width, DI_SYNC_HSYNC, height,
  179971. + DI_SYNC_VSYNC, 0, DI_SYNC_NONE,
  179972. + DI_SYNC_NONE, 0, 0);
  179973. + _ipu_di_sync_config(ipu, disp, 5, 0, DI_SYNC_CLK,
  179974. + h_sync_width + h_start_width, DI_SYNC_CLK,
  179975. + width, 4, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0,
  179976. + 0);
  179977. +
  179978. + /* set VGA delayed hsync/vsync no matter VGA enabled */
  179979. + if (disp) {
  179980. + /* couter 7 for VGA delay HSYNC */
  179981. + _ipu_di_sync_config(ipu, disp, 7,
  179982. + h_total - 1, DI_SYNC_CLK,
  179983. + 18, DI_SYNC_CLK,
  179984. + 0, DI_SYNC_NONE,
  179985. + 1, DI_SYNC_NONE, DI_SYNC_CLK,
  179986. + 0, h_sync_width * 2);
  179987. +
  179988. + /* couter 8 for VGA delay VSYNC */
  179989. + _ipu_di_sync_config(ipu, disp, 8,
  179990. + v_total - 1, DI_SYNC_INT_HSYNC,
  179991. + 1, DI_SYNC_INT_HSYNC,
  179992. + 0, DI_SYNC_NONE,
  179993. + 1, DI_SYNC_NONE, DI_SYNC_INT_HSYNC,
  179994. + 0, v_sync_width * 2);
  179995. + }
  179996. +
  179997. + /* reset all unused counters */
  179998. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(6));
  179999. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(6));
  180000. + if (!disp) {
  180001. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(7));
  180002. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(7));
  180003. + ipu_di_write(ipu, disp, 0, DI_STP_REP(7));
  180004. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(8));
  180005. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(8));
  180006. + ipu_di_write(ipu, disp, 0, DI_STP_REP(8));
  180007. + }
  180008. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(9));
  180009. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(9));
  180010. + ipu_di_write(ipu, disp, 0, DI_STP_REP(9));
  180011. +
  180012. + reg = ipu_di_read(ipu, disp, DI_STP_REP(6));
  180013. + reg &= 0x0000FFFF;
  180014. + ipu_di_write(ipu, disp, reg, DI_STP_REP(6));
  180015. +
  180016. + /* Init template microcode */
  180017. + if (disp) {
  180018. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  180019. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  180020. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  180021. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  180022. + _ipu_dc_write_tmpl(ipu, 8, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
  180023. + _ipu_dc_write_tmpl(ipu, 9, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  180024. + /* configure user events according to DISP NUM */
  180025. + ipu_dc_write(ipu, (width - 1), DC_UGDE_3(disp));
  180026. + }
  180027. + _ipu_dc_write_tmpl(ipu, 2, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
  180028. + _ipu_dc_write_tmpl(ipu, 3, WROD(0), 0, map, SYNC_WAVE, 4, 5, 0);
  180029. + _ipu_dc_write_tmpl(ipu, 4, WRG, 0, map, NULL_WAVE, 0, 0, 1);
  180030. + _ipu_dc_write_tmpl(ipu, 1, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  180031. +
  180032. + } else {
  180033. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  180034. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  180035. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  180036. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  180037. + _ipu_dc_write_tmpl(ipu, 10, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
  180038. + _ipu_dc_write_tmpl(ipu, 11, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  180039. + /* configure user events according to DISP NUM */
  180040. + ipu_dc_write(ipu, width - 1, DC_UGDE_3(disp));
  180041. + }
  180042. + _ipu_dc_write_tmpl(ipu, 5, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
  180043. + _ipu_dc_write_tmpl(ipu, 6, WROD(0), 0, map, SYNC_WAVE, 4, 5, 0);
  180044. + _ipu_dc_write_tmpl(ipu, 7, WRG, 0, map, NULL_WAVE, 0, 0, 1);
  180045. + _ipu_dc_write_tmpl(ipu, 12, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  180046. + }
  180047. +
  180048. + if (sig.Hsync_pol) {
  180049. + di_gen |= DI_GEN_POLARITY_2;
  180050. + if (disp)
  180051. + di_gen |= DI_GEN_POLARITY_7;
  180052. + }
  180053. + if (sig.Vsync_pol) {
  180054. + di_gen |= DI_GEN_POLARITY_3;
  180055. + if (disp)
  180056. + di_gen |= DI_GEN_POLARITY_8;
  180057. + }
  180058. + }
  180059. + /* changinc DISP_CLK polarity: it can be wrong for some applications */
  180060. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  180061. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  180062. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  180063. + (pixel_fmt == IPU_PIX_FMT_VYUY))
  180064. + di_gen |= 0x00020000;
  180065. +
  180066. + if (!sig.clk_pol)
  180067. + di_gen |= DI_GEN_POLARITY_DISP_CLK;
  180068. +
  180069. + ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
  180070. +
  180071. + ipu_di_write(ipu, disp, (--vsync_cnt << DI_VSYNC_SEL_OFFSET) |
  180072. + 0x00000002, DI_SYNC_AS_GEN);
  180073. + reg = ipu_di_read(ipu, disp, DI_POL);
  180074. + reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15);
  180075. + if (sig.enable_pol)
  180076. + reg |= DI_POL_DRDY_POLARITY_15;
  180077. + if (sig.data_pol)
  180078. + reg |= DI_POL_DRDY_DATA_POLARITY;
  180079. + ipu_di_write(ipu, disp, reg, DI_POL);
  180080. +
  180081. + ipu_dc_write(ipu, width, DC_DISP_CONF2(DC_DISP_ID_SYNC(disp)));
  180082. +
  180083. + mutex_unlock(&ipu->mutex_lock);
  180084. +
  180085. + return 0;
  180086. +}
  180087. +EXPORT_SYMBOL(ipu_init_sync_panel);
  180088. +
  180089. +void ipu_uninit_sync_panel(struct ipu_soc *ipu, int disp)
  180090. +{
  180091. + uint32_t reg;
  180092. + uint32_t di_gen;
  180093. +
  180094. + if ((disp != 0) || (disp != 1))
  180095. + return;
  180096. +
  180097. + mutex_lock(&ipu->mutex_lock);
  180098. +
  180099. + di_gen = ipu_di_read(ipu, disp, DI_GENERAL);
  180100. + di_gen |= 0x3ff | DI_GEN_POLARITY_DISP_CLK;
  180101. + ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
  180102. +
  180103. + reg = ipu_di_read(ipu, disp, DI_POL);
  180104. + reg |= 0x3ffffff;
  180105. + ipu_di_write(ipu, disp, reg, DI_POL);
  180106. +
  180107. + mutex_unlock(&ipu->mutex_lock);
  180108. +}
  180109. +EXPORT_SYMBOL(ipu_uninit_sync_panel);
  180110. +
  180111. +int ipu_init_async_panel(struct ipu_soc *ipu, int disp, int type, uint32_t cycle_time,
  180112. + uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig)
  180113. +{
  180114. + int map;
  180115. + u32 ser_conf = 0;
  180116. + u32 div;
  180117. + u32 di_clk = clk_get_rate(ipu->ipu_clk);
  180118. +
  180119. + /* round up cycle_time, then calcalate the divider using scaled math */
  180120. + cycle_time += (1000000000UL / di_clk) - 1;
  180121. + div = (cycle_time * (di_clk / 256UL)) / (1000000000UL / 256UL);
  180122. +
  180123. + map = _ipu_pixfmt_to_map(pixel_fmt);
  180124. + if (map < 0)
  180125. + return -EINVAL;
  180126. +
  180127. + mutex_lock(&ipu->mutex_lock);
  180128. +
  180129. + if (type == IPU_PANEL_SERIAL) {
  180130. + ipu_di_write(ipu, disp, (div << 24) | ((sig.ifc_width - 1) << 4),
  180131. + DI_DW_GEN(ASYNC_SER_WAVE));
  180132. +
  180133. + _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_CS,
  180134. + 0, 0, (div * 2) + 1);
  180135. + _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_SER_CLK,
  180136. + 1, div, div * 2);
  180137. + _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_SER_RS,
  180138. + 2, 0, 0);
  180139. +
  180140. + _ipu_dc_write_tmpl(ipu, 0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0, 1);
  180141. +
  180142. + /* Configure DC for serial panel */
  180143. + ipu_dc_write(ipu, 0x14, DC_DISP_CONF1(DC_DISP_ID_SERIAL));
  180144. +
  180145. + if (sig.clk_pol)
  180146. + ser_conf |= DI_SER_CONF_SERIAL_CLK_POL;
  180147. + if (sig.data_pol)
  180148. + ser_conf |= DI_SER_CONF_SERIAL_DATA_POL;
  180149. + if (sig.rs_pol)
  180150. + ser_conf |= DI_SER_CONF_SERIAL_RS_POL;
  180151. + if (sig.cs_pol)
  180152. + ser_conf |= DI_SER_CONF_SERIAL_CS_POL;
  180153. + ipu_di_write(ipu, disp, ser_conf, DI_SER_CONF);
  180154. + }
  180155. +
  180156. + mutex_unlock(&ipu->mutex_lock);
  180157. + return 0;
  180158. +}
  180159. +EXPORT_SYMBOL(ipu_init_async_panel);
  180160. +
  180161. +/*!
  180162. + * This function sets the foreground and background plane global alpha blending
  180163. + * modes. This function also sets the DP graphic plane according to the
  180164. + * parameter of IPUv3 DP channel.
  180165. + *
  180166. + * @param ipu ipu handler
  180167. + * @param channel IPUv3 DP channel
  180168. + *
  180169. + * @param enable Boolean to enable or disable global alpha
  180170. + * blending. If disabled, local blending is used.
  180171. + *
  180172. + * @param alpha Global alpha value.
  180173. + *
  180174. + * @return Returns 0 on success or negative error code on fail
  180175. + */
  180176. +int32_t ipu_disp_set_global_alpha(struct ipu_soc *ipu, ipu_channel_t channel,
  180177. + bool enable, uint8_t alpha)
  180178. +{
  180179. + uint32_t reg;
  180180. + uint32_t flow;
  180181. + bool bg_chan;
  180182. +
  180183. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
  180184. + flow = DP_SYNC;
  180185. + else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
  180186. + flow = DP_ASYNC0;
  180187. + else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
  180188. + flow = DP_ASYNC1;
  180189. + else
  180190. + return -EINVAL;
  180191. +
  180192. + if (channel == MEM_BG_SYNC || channel == MEM_BG_ASYNC0 ||
  180193. + channel == MEM_BG_ASYNC1)
  180194. + bg_chan = true;
  180195. + else
  180196. + bg_chan = false;
  180197. +
  180198. + _ipu_get(ipu);
  180199. +
  180200. + mutex_lock(&ipu->mutex_lock);
  180201. +
  180202. + if (bg_chan) {
  180203. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180204. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWSEL, DP_COM_CONF(flow));
  180205. + } else {
  180206. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180207. + ipu_dp_write(ipu, reg | DP_COM_CONF_GWSEL, DP_COM_CONF(flow));
  180208. + }
  180209. +
  180210. + if (enable) {
  180211. + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(flow)) & 0x00FFFFFFL;
  180212. + ipu_dp_write(ipu, reg | ((uint32_t) alpha << 24),
  180213. + DP_GRAPH_WIND_CTRL(flow));
  180214. +
  180215. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180216. + ipu_dp_write(ipu, reg | DP_COM_CONF_GWAM, DP_COM_CONF(flow));
  180217. + } else {
  180218. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180219. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWAM, DP_COM_CONF(flow));
  180220. + }
  180221. +
  180222. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  180223. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  180224. +
  180225. + mutex_unlock(&ipu->mutex_lock);
  180226. +
  180227. + _ipu_put(ipu);
  180228. +
  180229. + return 0;
  180230. +}
  180231. +EXPORT_SYMBOL(ipu_disp_set_global_alpha);
  180232. +
  180233. +/*!
  180234. + * This function sets the transparent color key for SDC graphic plane.
  180235. + *
  180236. + * @param ipu ipu handler
  180237. + * @param channel Input parameter for the logical channel ID.
  180238. + *
  180239. + * @param enable Boolean to enable or disable color key
  180240. + *
  180241. + * @param colorKey 24-bit RGB color for transparent color key.
  180242. + *
  180243. + * @return Returns 0 on success or negative error code on fail
  180244. + */
  180245. +int32_t ipu_disp_set_color_key(struct ipu_soc *ipu, ipu_channel_t channel,
  180246. + bool enable, uint32_t color_key)
  180247. +{
  180248. + uint32_t reg, flow;
  180249. + int y, u, v;
  180250. + int red, green, blue;
  180251. +
  180252. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
  180253. + flow = DP_SYNC;
  180254. + else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
  180255. + flow = DP_ASYNC0;
  180256. + else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
  180257. + flow = DP_ASYNC1;
  180258. + else
  180259. + return -EINVAL;
  180260. +
  180261. + _ipu_get(ipu);
  180262. +
  180263. + mutex_lock(&ipu->mutex_lock);
  180264. +
  180265. + ipu->color_key_4rgb = true;
  180266. + /* Transform color key from rgb to yuv if CSC is enabled */
  180267. + if (((ipu->fg_csc_type == RGB2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  180268. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == RGB2YUV)) ||
  180269. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  180270. + ((ipu->fg_csc_type == YUV2RGB) && (ipu->bg_csc_type == YUV2RGB))) {
  180271. +
  180272. + dev_dbg(ipu->dev, "color key 0x%x need change to yuv fmt\n", color_key);
  180273. +
  180274. + red = (color_key >> 16) & 0xFF;
  180275. + green = (color_key >> 8) & 0xFF;
  180276. + blue = color_key & 0xFF;
  180277. +
  180278. + y = _rgb_to_yuv(0, red, green, blue);
  180279. + u = _rgb_to_yuv(1, red, green, blue);
  180280. + v = _rgb_to_yuv(2, red, green, blue);
  180281. + color_key = (y << 16) | (u << 8) | v;
  180282. +
  180283. + ipu->color_key_4rgb = false;
  180284. +
  180285. + dev_dbg(ipu->dev, "color key change to yuv fmt 0x%x\n", color_key);
  180286. + }
  180287. +
  180288. + if (enable) {
  180289. + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(flow)) & 0xFF000000L;
  180290. + ipu_dp_write(ipu, reg | color_key, DP_GRAPH_WIND_CTRL(flow));
  180291. +
  180292. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180293. + ipu_dp_write(ipu, reg | DP_COM_CONF_GWCKE, DP_COM_CONF(flow));
  180294. + } else {
  180295. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180296. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWCKE, DP_COM_CONF(flow));
  180297. + }
  180298. +
  180299. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  180300. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  180301. +
  180302. + mutex_unlock(&ipu->mutex_lock);
  180303. +
  180304. + _ipu_put(ipu);
  180305. +
  180306. + return 0;
  180307. +}
  180308. +EXPORT_SYMBOL(ipu_disp_set_color_key);
  180309. +
  180310. +/*!
  180311. + * This function sets the gamma correction for DP output.
  180312. + *
  180313. + * @param ipu ipu handler
  180314. + * @param channel Input parameter for the logical channel ID.
  180315. + *
  180316. + * @param enable Boolean to enable or disable gamma correction.
  180317. + *
  180318. + * @param constk Gamma piecewise linear approximation constk coeff.
  180319. + *
  180320. + * @param slopek Gamma piecewise linear approximation slopek coeff.
  180321. + *
  180322. + * @return Returns 0 on success or negative error code on fail
  180323. + */
  180324. +int32_t ipu_disp_set_gamma_correction(struct ipu_soc *ipu, ipu_channel_t channel, bool enable, int constk[], int slopek[])
  180325. +{
  180326. + uint32_t reg, flow, i;
  180327. +
  180328. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
  180329. + flow = DP_SYNC;
  180330. + else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
  180331. + flow = DP_ASYNC0;
  180332. + else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
  180333. + flow = DP_ASYNC1;
  180334. + else
  180335. + return -EINVAL;
  180336. +
  180337. + _ipu_get(ipu);
  180338. +
  180339. + mutex_lock(&ipu->mutex_lock);
  180340. +
  180341. + for (i = 0; i < 8; i++)
  180342. + ipu_dp_write(ipu, (constk[2*i] & 0x1ff) | ((constk[2*i+1] & 0x1ff) << 16), DP_GAMMA_C(flow, i));
  180343. + for (i = 0; i < 4; i++)
  180344. + ipu_dp_write(ipu, (slopek[4*i] & 0xff) | ((slopek[4*i+1] & 0xff) << 8) |
  180345. + ((slopek[4*i+2] & 0xff) << 16) | ((slopek[4*i+3] & 0xff) << 24), DP_GAMMA_S(flow, i));
  180346. +
  180347. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  180348. + if (enable) {
  180349. + if ((ipu->bg_csc_type == RGB2YUV) || (ipu->bg_csc_type == YUV2YUV))
  180350. + reg |= DP_COM_CONF_GAMMA_YUV_EN;
  180351. + else
  180352. + reg &= ~DP_COM_CONF_GAMMA_YUV_EN;
  180353. + ipu_dp_write(ipu, reg | DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow));
  180354. + } else
  180355. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow));
  180356. +
  180357. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  180358. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  180359. +
  180360. + mutex_unlock(&ipu->mutex_lock);
  180361. +
  180362. + _ipu_put(ipu);
  180363. +
  180364. + return 0;
  180365. +}
  180366. +EXPORT_SYMBOL(ipu_disp_set_gamma_correction);
  180367. +
  180368. +/*!
  180369. + * This function sets the window position of the foreground or background plane.
  180370. + * modes.
  180371. + *
  180372. + * @param ipu ipu handler
  180373. + * @param channel Input parameter for the logical channel ID.
  180374. + *
  180375. + * @param x_pos The X coordinate position to place window at.
  180376. + * The position is relative to the top left corner.
  180377. + *
  180378. + * @param y_pos The Y coordinate position to place window at.
  180379. + * The position is relative to the top left corner.
  180380. + *
  180381. + * @return Returns 0 on success or negative error code on fail
  180382. + */
  180383. +int32_t _ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  180384. + int16_t x_pos, int16_t y_pos)
  180385. +{
  180386. + u32 reg;
  180387. + uint32_t flow = 0;
  180388. + uint32_t dp_srm_shift;
  180389. +
  180390. + if ((channel == MEM_FG_SYNC) || (channel == MEM_BG_SYNC)) {
  180391. + flow = DP_SYNC;
  180392. + dp_srm_shift = 3;
  180393. + } else if (channel == MEM_FG_ASYNC0) {
  180394. + flow = DP_ASYNC0;
  180395. + dp_srm_shift = 5;
  180396. + } else if (channel == MEM_FG_ASYNC1) {
  180397. + flow = DP_ASYNC1;
  180398. + dp_srm_shift = 7;
  180399. + } else
  180400. + return -EINVAL;
  180401. +
  180402. + ipu_dp_write(ipu, (x_pos << 16) | y_pos, DP_FG_POS(flow));
  180403. +
  180404. + if (ipu_is_channel_busy(ipu, channel)) {
  180405. + /* controled by FSU if channel enabled */
  180406. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift));
  180407. + reg |= (0x1 << dp_srm_shift);
  180408. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  180409. + } else {
  180410. + /* disable auto swap, controled by MCU if channel disabled */
  180411. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift));
  180412. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  180413. + }
  180414. +
  180415. + return 0;
  180416. +}
  180417. +
  180418. +int32_t ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  180419. + int16_t x_pos, int16_t y_pos)
  180420. +{
  180421. + int ret;
  180422. +
  180423. + _ipu_get(ipu);
  180424. + mutex_lock(&ipu->mutex_lock);
  180425. + ret = _ipu_disp_set_window_pos(ipu, channel, x_pos, y_pos);
  180426. + mutex_unlock(&ipu->mutex_lock);
  180427. + _ipu_put(ipu);
  180428. + return ret;
  180429. +}
  180430. +EXPORT_SYMBOL(ipu_disp_set_window_pos);
  180431. +
  180432. +int32_t _ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  180433. + int16_t *x_pos, int16_t *y_pos)
  180434. +{
  180435. + u32 reg;
  180436. + uint32_t flow = 0;
  180437. +
  180438. + if (channel == MEM_FG_SYNC)
  180439. + flow = DP_SYNC;
  180440. + else if (channel == MEM_FG_ASYNC0)
  180441. + flow = DP_ASYNC0;
  180442. + else if (channel == MEM_FG_ASYNC1)
  180443. + flow = DP_ASYNC1;
  180444. + else
  180445. + return -EINVAL;
  180446. +
  180447. + reg = ipu_dp_read(ipu, DP_FG_POS(flow));
  180448. +
  180449. + *x_pos = (reg >> 16) & 0x7FF;
  180450. + *y_pos = reg & 0x7FF;
  180451. +
  180452. + return 0;
  180453. +}
  180454. +int32_t ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  180455. + int16_t *x_pos, int16_t *y_pos)
  180456. +{
  180457. + int ret;
  180458. +
  180459. + _ipu_get(ipu);
  180460. + mutex_lock(&ipu->mutex_lock);
  180461. + ret = _ipu_disp_get_window_pos(ipu, channel, x_pos, y_pos);
  180462. + mutex_unlock(&ipu->mutex_lock);
  180463. + _ipu_put(ipu);
  180464. + return ret;
  180465. +}
  180466. +EXPORT_SYMBOL(ipu_disp_get_window_pos);
  180467. +
  180468. +void ipu_disp_direct_write(struct ipu_soc *ipu, ipu_channel_t channel, u32 value, u32 offset)
  180469. +{
  180470. + if (channel == DIRECT_ASYNC0)
  180471. + writel(value, ipu->disp_base[0] + offset);
  180472. + else if (channel == DIRECT_ASYNC1)
  180473. + writel(value, ipu->disp_base[1] + offset);
  180474. +}
  180475. +EXPORT_SYMBOL(ipu_disp_direct_write);
  180476. +
  180477. +void ipu_reset_disp_panel(struct ipu_soc *ipu)
  180478. +{
  180479. + uint32_t tmp;
  180480. +
  180481. + tmp = ipu_di_read(ipu, 1, DI_GENERAL);
  180482. + ipu_di_write(ipu, 1, tmp | 0x08, DI_GENERAL);
  180483. + msleep(10); /* tRES >= 100us */
  180484. + tmp = ipu_di_read(ipu, 1, DI_GENERAL);
  180485. + ipu_di_write(ipu, 1, tmp & ~0x08, DI_GENERAL);
  180486. + msleep(60);
  180487. +
  180488. + return;
  180489. +}
  180490. +EXPORT_SYMBOL(ipu_reset_disp_panel);
  180491. +
  180492. +void ipu_disp_init(struct ipu_soc *ipu)
  180493. +{
  180494. + ipu->fg_csc_type = ipu->bg_csc_type = CSC_NONE;
  180495. + ipu->color_key_4rgb = true;
  180496. + _ipu_init_dc_mappings(ipu);
  180497. + _ipu_dmfc_init(ipu, DMFC_NORMAL, 1);
  180498. +}
  180499. diff -Nur linux-3.14.14/drivers/mxc/ipu3/ipu_ic.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_ic.c
  180500. --- linux-3.14.14/drivers/mxc/ipu3/ipu_ic.c 1969-12-31 18:00:00.000000000 -0600
  180501. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_ic.c 2014-12-08 00:31:53.476418001 -0600
  180502. @@ -0,0 +1,924 @@
  180503. +/*
  180504. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  180505. + */
  180506. +
  180507. +/*
  180508. + * The code contained herein is licensed under the GNU General Public
  180509. + * License. You may obtain a copy of the GNU General Public License
  180510. + * Version 2 or later at the following locations:
  180511. + *
  180512. + * http://www.opensource.org/licenses/gpl-license.html
  180513. + * http://www.gnu.org/copyleft/gpl.html
  180514. + */
  180515. +
  180516. +/*
  180517. + * @file ipu_ic.c
  180518. + *
  180519. + * @brief IPU IC functions
  180520. + *
  180521. + * @ingroup IPU
  180522. + */
  180523. +#include <linux/errno.h>
  180524. +#include <linux/init.h>
  180525. +#include <linux/io.h>
  180526. +#include <linux/ipu-v3.h>
  180527. +#include <linux/spinlock.h>
  180528. +#include <linux/types.h>
  180529. +#include <linux/videodev2.h>
  180530. +
  180531. +#include "ipu_param_mem.h"
  180532. +#include "ipu_regs.h"
  180533. +
  180534. +enum {
  180535. + IC_TASK_VIEWFINDER,
  180536. + IC_TASK_ENCODER,
  180537. + IC_TASK_POST_PROCESSOR
  180538. +};
  180539. +
  180540. +static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in_format,
  180541. + ipu_color_space_t out_format, int csc_index);
  180542. +
  180543. +static int _calc_resize_coeffs(struct ipu_soc *ipu,
  180544. + uint32_t inSize, uint32_t outSize,
  180545. + uint32_t *resizeCoeff,
  180546. + uint32_t *downsizeCoeff);
  180547. +
  180548. +void _ipu_vdi_set_top_field_man(struct ipu_soc *ipu, bool top_field_0)
  180549. +{
  180550. + uint32_t reg;
  180551. +
  180552. + reg = ipu_vdi_read(ipu, VDI_C);
  180553. + if (top_field_0)
  180554. + reg &= ~VDI_C_TOP_FIELD_MAN_1;
  180555. + else
  180556. + reg |= VDI_C_TOP_FIELD_MAN_1;
  180557. + ipu_vdi_write(ipu, reg, VDI_C);
  180558. +}
  180559. +
  180560. +void _ipu_vdi_set_motion(struct ipu_soc *ipu, ipu_motion_sel motion_sel)
  180561. +{
  180562. + uint32_t reg;
  180563. +
  180564. + reg = ipu_vdi_read(ipu, VDI_C);
  180565. + reg &= ~(VDI_C_MOT_SEL_FULL | VDI_C_MOT_SEL_MED | VDI_C_MOT_SEL_LOW);
  180566. + if (motion_sel == HIGH_MOTION)
  180567. + reg |= VDI_C_MOT_SEL_FULL;
  180568. + else if (motion_sel == MED_MOTION)
  180569. + reg |= VDI_C_MOT_SEL_MED;
  180570. + else
  180571. + reg |= VDI_C_MOT_SEL_LOW;
  180572. +
  180573. + ipu_vdi_write(ipu, reg, VDI_C);
  180574. + dev_dbg(ipu->dev, "VDI_C = \t0x%08X\n", reg);
  180575. +}
  180576. +
  180577. +void ic_dump_register(struct ipu_soc *ipu)
  180578. +{
  180579. + printk(KERN_DEBUG "IC_CONF = \t0x%08X\n", ipu_ic_read(ipu, IC_CONF));
  180580. + printk(KERN_DEBUG "IC_PRP_ENC_RSC = \t0x%08X\n",
  180581. + ipu_ic_read(ipu, IC_PRP_ENC_RSC));
  180582. + printk(KERN_DEBUG "IC_PRP_VF_RSC = \t0x%08X\n",
  180583. + ipu_ic_read(ipu, IC_PRP_VF_RSC));
  180584. + printk(KERN_DEBUG "IC_PP_RSC = \t0x%08X\n", ipu_ic_read(ipu, IC_PP_RSC));
  180585. + printk(KERN_DEBUG "IC_IDMAC_1 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_1));
  180586. + printk(KERN_DEBUG "IC_IDMAC_2 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_2));
  180587. + printk(KERN_DEBUG "IC_IDMAC_3 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_3));
  180588. +}
  180589. +
  180590. +void _ipu_ic_enable_task(struct ipu_soc *ipu, ipu_channel_t channel)
  180591. +{
  180592. + uint32_t ic_conf;
  180593. +
  180594. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  180595. + switch (channel) {
  180596. + case CSI_PRP_VF_MEM:
  180597. + case MEM_PRP_VF_MEM:
  180598. + ic_conf |= IC_CONF_PRPVF_EN;
  180599. + break;
  180600. + case MEM_VDI_PRP_VF_MEM:
  180601. + ic_conf |= IC_CONF_PRPVF_EN;
  180602. + break;
  180603. + case MEM_VDI_MEM:
  180604. + ic_conf |= IC_CONF_PRPVF_EN | IC_CONF_RWS_EN ;
  180605. + break;
  180606. + case MEM_ROT_VF_MEM:
  180607. + ic_conf |= IC_CONF_PRPVF_ROT_EN;
  180608. + break;
  180609. + case CSI_PRP_ENC_MEM:
  180610. + case MEM_PRP_ENC_MEM:
  180611. + ic_conf |= IC_CONF_PRPENC_EN;
  180612. + break;
  180613. + case MEM_ROT_ENC_MEM:
  180614. + ic_conf |= IC_CONF_PRPENC_ROT_EN;
  180615. + break;
  180616. + case MEM_PP_MEM:
  180617. + ic_conf |= IC_CONF_PP_EN;
  180618. + break;
  180619. + case MEM_ROT_PP_MEM:
  180620. + ic_conf |= IC_CONF_PP_ROT_EN;
  180621. + break;
  180622. + default:
  180623. + break;
  180624. + }
  180625. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  180626. +}
  180627. +
  180628. +void _ipu_ic_disable_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_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params)
  180667. +{
  180668. + uint32_t reg;
  180669. + uint32_t pixel_fmt;
  180670. + uint32_t pix_per_burst;
  180671. +
  180672. + reg = ((params->mem_prp_vf_mem.in_height-1) << 16) |
  180673. + (params->mem_prp_vf_mem.in_width-1);
  180674. + ipu_vdi_write(ipu, reg, VDI_FSIZE);
  180675. +
  180676. + /* Full motion, only vertical filter is used
  180677. + Burst size is 4 accesses */
  180678. + if (params->mem_prp_vf_mem.in_pixel_fmt ==
  180679. + IPU_PIX_FMT_UYVY ||
  180680. + params->mem_prp_vf_mem.in_pixel_fmt ==
  180681. + IPU_PIX_FMT_YUYV) {
  180682. + pixel_fmt = VDI_C_CH_422;
  180683. + pix_per_burst = 32;
  180684. + } else {
  180685. + pixel_fmt = VDI_C_CH_420;
  180686. + pix_per_burst = 64;
  180687. + }
  180688. +
  180689. + reg = ipu_vdi_read(ipu, VDI_C);
  180690. + reg |= pixel_fmt;
  180691. + switch (channel) {
  180692. + case MEM_VDI_PRP_VF_MEM:
  180693. + reg |= VDI_C_BURST_SIZE2_4;
  180694. + break;
  180695. + case MEM_VDI_PRP_VF_MEM_P:
  180696. + reg |= VDI_C_BURST_SIZE1_4 | VDI_C_VWM1_SET_1 | VDI_C_VWM1_CLR_2;
  180697. + break;
  180698. + case MEM_VDI_PRP_VF_MEM_N:
  180699. + reg |= VDI_C_BURST_SIZE3_4 | VDI_C_VWM3_SET_1 | VDI_C_VWM3_CLR_2;
  180700. + break;
  180701. +
  180702. + case MEM_VDI_MEM:
  180703. + reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
  180704. + << VDI_C_BURST_SIZE2_OFFSET;
  180705. + break;
  180706. + case MEM_VDI_MEM_P:
  180707. + reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
  180708. + << VDI_C_BURST_SIZE1_OFFSET;
  180709. + reg |= VDI_C_VWM1_SET_2 | VDI_C_VWM1_CLR_2;
  180710. + break;
  180711. + case MEM_VDI_MEM_N:
  180712. + reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
  180713. + << VDI_C_BURST_SIZE3_OFFSET;
  180714. + reg |= VDI_C_VWM3_SET_2 | VDI_C_VWM3_CLR_2;
  180715. + break;
  180716. + default:
  180717. + break;
  180718. + }
  180719. + ipu_vdi_write(ipu, reg, VDI_C);
  180720. +
  180721. + if (params->mem_prp_vf_mem.field_fmt == IPU_DEINTERLACE_FIELD_TOP)
  180722. + _ipu_vdi_set_top_field_man(ipu, true);
  180723. + else if (params->mem_prp_vf_mem.field_fmt == IPU_DEINTERLACE_FIELD_BOTTOM)
  180724. + _ipu_vdi_set_top_field_man(ipu, false);
  180725. +
  180726. + _ipu_vdi_set_motion(ipu, params->mem_prp_vf_mem.motion_sel);
  180727. +
  180728. + reg = ipu_ic_read(ipu, IC_CONF);
  180729. + reg &= ~IC_CONF_RWS_EN;
  180730. + ipu_ic_write(ipu, reg, IC_CONF);
  180731. +}
  180732. +
  180733. +void _ipu_vdi_uninit(struct ipu_soc *ipu)
  180734. +{
  180735. + ipu_vdi_write(ipu, 0, VDI_FSIZE);
  180736. + ipu_vdi_write(ipu, 0, VDI_C);
  180737. +}
  180738. +
  180739. +int _ipu_ic_init_prpvf(struct ipu_soc *ipu, ipu_channel_params_t *params,
  180740. + bool src_is_csi)
  180741. +{
  180742. + uint32_t reg, ic_conf;
  180743. + uint32_t downsizeCoeff, resizeCoeff;
  180744. + ipu_color_space_t in_fmt, out_fmt;
  180745. + int ret = 0;
  180746. +
  180747. + /* Setup vertical resizing */
  180748. + if (!params->mem_prp_vf_mem.outv_resize_ratio) {
  180749. + ret = _calc_resize_coeffs(ipu, params->mem_prp_vf_mem.in_height,
  180750. + params->mem_prp_vf_mem.out_height,
  180751. + &resizeCoeff, &downsizeCoeff);
  180752. + if (ret < 0) {
  180753. + dev_err(ipu->dev, "failed to calculate prpvf height "
  180754. + "scaling coefficients\n");
  180755. + return ret;
  180756. + }
  180757. +
  180758. + reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
  180759. + } else
  180760. + reg = (params->mem_prp_vf_mem.outv_resize_ratio) << 16;
  180761. +
  180762. + /* Setup horizontal resizing */
  180763. + if (!params->mem_prp_vf_mem.outh_resize_ratio) {
  180764. + ret = _calc_resize_coeffs(ipu, params->mem_prp_vf_mem.in_width,
  180765. + params->mem_prp_vf_mem.out_width,
  180766. + &resizeCoeff, &downsizeCoeff);
  180767. + if (ret < 0) {
  180768. + dev_err(ipu->dev, "failed to calculate prpvf width "
  180769. + "scaling coefficients\n");
  180770. + return ret;
  180771. + }
  180772. +
  180773. + reg |= (downsizeCoeff << 14) | resizeCoeff;
  180774. + } else
  180775. + reg |= params->mem_prp_vf_mem.outh_resize_ratio;
  180776. +
  180777. + ipu_ic_write(ipu, reg, IC_PRP_VF_RSC);
  180778. +
  180779. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  180780. +
  180781. + /* Setup color space conversion */
  180782. + in_fmt = format_to_colorspace(params->mem_prp_vf_mem.in_pixel_fmt);
  180783. + out_fmt = format_to_colorspace(params->mem_prp_vf_mem.out_pixel_fmt);
  180784. + if (in_fmt == RGB) {
  180785. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  180786. + /* Enable RGB->YCBCR CSC1 */
  180787. + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, out_fmt, 1);
  180788. + ic_conf |= IC_CONF_PRPVF_CSC1;
  180789. + }
  180790. + }
  180791. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  180792. + if (out_fmt == RGB) {
  180793. + /* Enable YCBCR->RGB CSC1 */
  180794. + _init_csc(ipu, IC_TASK_VIEWFINDER, YCbCr, RGB, 1);
  180795. + ic_conf |= IC_CONF_PRPVF_CSC1;
  180796. + } else {
  180797. + /* TODO: Support YUV<->YCbCr conversion? */
  180798. + }
  180799. + }
  180800. +
  180801. + if (params->mem_prp_vf_mem.graphics_combine_en) {
  180802. + ic_conf |= IC_CONF_PRPVF_CMB;
  180803. +
  180804. + if (!(ic_conf & IC_CONF_PRPVF_CSC1)) {
  180805. + /* need transparent CSC1 conversion */
  180806. + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, RGB, 1);
  180807. + ic_conf |= IC_CONF_PRPVF_CSC1; /* Enable RGB->RGB CSC */
  180808. + }
  180809. + in_fmt = format_to_colorspace(params->mem_prp_vf_mem.in_g_pixel_fmt);
  180810. + out_fmt = format_to_colorspace(params->mem_prp_vf_mem.out_pixel_fmt);
  180811. + if (in_fmt == RGB) {
  180812. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  180813. + /* Enable RGB->YCBCR CSC2 */
  180814. + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, out_fmt, 2);
  180815. + ic_conf |= IC_CONF_PRPVF_CSC2;
  180816. + }
  180817. + }
  180818. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  180819. + if (out_fmt == RGB) {
  180820. + /* Enable YCBCR->RGB CSC2 */
  180821. + _init_csc(ipu, IC_TASK_VIEWFINDER, YCbCr, RGB, 2);
  180822. + ic_conf |= IC_CONF_PRPVF_CSC2;
  180823. + } else {
  180824. + /* TODO: Support YUV<->YCbCr conversion? */
  180825. + }
  180826. + }
  180827. +
  180828. + if (params->mem_prp_vf_mem.global_alpha_en) {
  180829. + ic_conf |= IC_CONF_IC_GLB_LOC_A;
  180830. + reg = ipu_ic_read(ipu, IC_CMBP_1);
  180831. + reg &= ~(0xff);
  180832. + reg |= params->mem_prp_vf_mem.alpha;
  180833. + ipu_ic_write(ipu, reg, IC_CMBP_1);
  180834. + } else
  180835. + ic_conf &= ~IC_CONF_IC_GLB_LOC_A;
  180836. +
  180837. + if (params->mem_prp_vf_mem.key_color_en) {
  180838. + ic_conf |= IC_CONF_KEY_COLOR_EN;
  180839. + ipu_ic_write(ipu, params->mem_prp_vf_mem.key_color,
  180840. + IC_CMBP_2);
  180841. + } else
  180842. + ic_conf &= ~IC_CONF_KEY_COLOR_EN;
  180843. + } else {
  180844. + ic_conf &= ~IC_CONF_PRPVF_CMB;
  180845. + }
  180846. +
  180847. + if (src_is_csi)
  180848. + ic_conf &= ~IC_CONF_RWS_EN;
  180849. + else
  180850. + ic_conf |= IC_CONF_RWS_EN;
  180851. +
  180852. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  180853. +
  180854. + return ret;
  180855. +}
  180856. +
  180857. +void _ipu_ic_uninit_prpvf(struct ipu_soc *ipu)
  180858. +{
  180859. + uint32_t reg;
  180860. +
  180861. + reg = ipu_ic_read(ipu, IC_CONF);
  180862. + reg &= ~(IC_CONF_PRPVF_EN | IC_CONF_PRPVF_CMB |
  180863. + IC_CONF_PRPVF_CSC2 | IC_CONF_PRPVF_CSC1);
  180864. + ipu_ic_write(ipu, reg, IC_CONF);
  180865. +}
  180866. +
  180867. +void _ipu_ic_init_rotate_vf(struct ipu_soc *ipu, ipu_channel_params_t *params)
  180868. +{
  180869. +}
  180870. +
  180871. +void _ipu_ic_uninit_rotate_vf(struct ipu_soc *ipu)
  180872. +{
  180873. + uint32_t reg;
  180874. + reg = ipu_ic_read(ipu, IC_CONF);
  180875. + reg &= ~IC_CONF_PRPVF_ROT_EN;
  180876. + ipu_ic_write(ipu, reg, IC_CONF);
  180877. +}
  180878. +
  180879. +int _ipu_ic_init_prpenc(struct ipu_soc *ipu, ipu_channel_params_t *params,
  180880. + bool src_is_csi)
  180881. +{
  180882. + uint32_t reg, ic_conf;
  180883. + uint32_t downsizeCoeff, resizeCoeff;
  180884. + ipu_color_space_t in_fmt, out_fmt;
  180885. + int ret = 0;
  180886. +
  180887. + /* Setup vertical resizing */
  180888. + if (!params->mem_prp_enc_mem.outv_resize_ratio) {
  180889. + ret = _calc_resize_coeffs(ipu,
  180890. + params->mem_prp_enc_mem.in_height,
  180891. + params->mem_prp_enc_mem.out_height,
  180892. + &resizeCoeff, &downsizeCoeff);
  180893. + if (ret < 0) {
  180894. + dev_err(ipu->dev, "failed to calculate prpenc height "
  180895. + "scaling coefficients\n");
  180896. + return ret;
  180897. + }
  180898. +
  180899. + reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
  180900. + } else
  180901. + reg = (params->mem_prp_enc_mem.outv_resize_ratio) << 16;
  180902. +
  180903. + /* Setup horizontal resizing */
  180904. + if (!params->mem_prp_enc_mem.outh_resize_ratio) {
  180905. + ret = _calc_resize_coeffs(ipu, params->mem_prp_enc_mem.in_width,
  180906. + params->mem_prp_enc_mem.out_width,
  180907. + &resizeCoeff, &downsizeCoeff);
  180908. + if (ret < 0) {
  180909. + dev_err(ipu->dev, "failed to calculate prpenc width "
  180910. + "scaling coefficients\n");
  180911. + return ret;
  180912. + }
  180913. +
  180914. + reg |= (downsizeCoeff << 14) | resizeCoeff;
  180915. + } else
  180916. + reg |= params->mem_prp_enc_mem.outh_resize_ratio;
  180917. +
  180918. + ipu_ic_write(ipu, reg, IC_PRP_ENC_RSC);
  180919. +
  180920. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  180921. +
  180922. + /* Setup color space conversion */
  180923. + in_fmt = format_to_colorspace(params->mem_prp_enc_mem.in_pixel_fmt);
  180924. + out_fmt = format_to_colorspace(params->mem_prp_enc_mem.out_pixel_fmt);
  180925. + if (in_fmt == RGB) {
  180926. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  180927. + /* Enable RGB->YCBCR CSC1 */
  180928. + _init_csc(ipu, IC_TASK_ENCODER, RGB, out_fmt, 1);
  180929. + ic_conf |= IC_CONF_PRPENC_CSC1;
  180930. + }
  180931. + }
  180932. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  180933. + if (out_fmt == RGB) {
  180934. + /* Enable YCBCR->RGB CSC1 */
  180935. + _init_csc(ipu, IC_TASK_ENCODER, YCbCr, RGB, 1);
  180936. + ic_conf |= IC_CONF_PRPENC_CSC1;
  180937. + } else {
  180938. + /* TODO: Support YUV<->YCbCr conversion? */
  180939. + }
  180940. + }
  180941. +
  180942. + if (src_is_csi)
  180943. + ic_conf &= ~IC_CONF_RWS_EN;
  180944. + else
  180945. + ic_conf |= IC_CONF_RWS_EN;
  180946. +
  180947. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  180948. +
  180949. + return ret;
  180950. +}
  180951. +
  180952. +void _ipu_ic_uninit_prpenc(struct ipu_soc *ipu)
  180953. +{
  180954. + uint32_t reg;
  180955. +
  180956. + reg = ipu_ic_read(ipu, IC_CONF);
  180957. + reg &= ~(IC_CONF_PRPENC_EN | IC_CONF_PRPENC_CSC1);
  180958. + ipu_ic_write(ipu, reg, IC_CONF);
  180959. +}
  180960. +
  180961. +void _ipu_ic_init_rotate_enc(struct ipu_soc *ipu, ipu_channel_params_t *params)
  180962. +{
  180963. +}
  180964. +
  180965. +void _ipu_ic_uninit_rotate_enc(struct ipu_soc *ipu)
  180966. +{
  180967. + uint32_t reg;
  180968. +
  180969. + reg = ipu_ic_read(ipu, IC_CONF);
  180970. + reg &= ~(IC_CONF_PRPENC_ROT_EN);
  180971. + ipu_ic_write(ipu, reg, IC_CONF);
  180972. +}
  180973. +
  180974. +int _ipu_ic_init_pp(struct ipu_soc *ipu, ipu_channel_params_t *params)
  180975. +{
  180976. + uint32_t reg, ic_conf;
  180977. + uint32_t downsizeCoeff, resizeCoeff;
  180978. + ipu_color_space_t in_fmt, out_fmt;
  180979. + int ret = 0;
  180980. +
  180981. + /* Setup vertical resizing */
  180982. + if (!params->mem_pp_mem.outv_resize_ratio) {
  180983. + ret = _calc_resize_coeffs(ipu, params->mem_pp_mem.in_height,
  180984. + params->mem_pp_mem.out_height,
  180985. + &resizeCoeff, &downsizeCoeff);
  180986. + if (ret < 0) {
  180987. + dev_err(ipu->dev, "failed to calculate pp height "
  180988. + "scaling coefficients\n");
  180989. + return ret;
  180990. + }
  180991. +
  180992. + reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
  180993. + } else {
  180994. + reg = (params->mem_pp_mem.outv_resize_ratio) << 16;
  180995. + }
  180996. +
  180997. + /* Setup horizontal resizing */
  180998. + if (!params->mem_pp_mem.outh_resize_ratio) {
  180999. + ret = _calc_resize_coeffs(ipu, params->mem_pp_mem.in_width,
  181000. + params->mem_pp_mem.out_width,
  181001. + &resizeCoeff, &downsizeCoeff);
  181002. + if (ret < 0) {
  181003. + dev_err(ipu->dev, "failed to calculate pp width "
  181004. + "scaling coefficients\n");
  181005. + return ret;
  181006. + }
  181007. +
  181008. + reg |= (downsizeCoeff << 14) | resizeCoeff;
  181009. + } else {
  181010. + reg |= params->mem_pp_mem.outh_resize_ratio;
  181011. + }
  181012. +
  181013. + ipu_ic_write(ipu, reg, IC_PP_RSC);
  181014. +
  181015. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  181016. +
  181017. + /* Setup color space conversion */
  181018. + in_fmt = format_to_colorspace(params->mem_pp_mem.in_pixel_fmt);
  181019. + out_fmt = format_to_colorspace(params->mem_pp_mem.out_pixel_fmt);
  181020. + if (in_fmt == RGB) {
  181021. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  181022. + /* Enable RGB->YCBCR CSC1 */
  181023. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, out_fmt, 1);
  181024. + ic_conf |= IC_CONF_PP_CSC1;
  181025. + }
  181026. + }
  181027. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  181028. + if (out_fmt == RGB) {
  181029. + /* Enable YCBCR->RGB CSC1 */
  181030. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, YCbCr, RGB, 1);
  181031. + ic_conf |= IC_CONF_PP_CSC1;
  181032. + } else {
  181033. + /* TODO: Support YUV<->YCbCr conversion? */
  181034. + }
  181035. + }
  181036. +
  181037. + if (params->mem_pp_mem.graphics_combine_en) {
  181038. + ic_conf |= IC_CONF_PP_CMB;
  181039. +
  181040. + if (!(ic_conf & IC_CONF_PP_CSC1)) {
  181041. + /* need transparent CSC1 conversion */
  181042. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, RGB, 1);
  181043. + ic_conf |= IC_CONF_PP_CSC1; /* Enable RGB->RGB CSC */
  181044. + }
  181045. +
  181046. + in_fmt = format_to_colorspace(params->mem_pp_mem.in_g_pixel_fmt);
  181047. + out_fmt = format_to_colorspace(params->mem_pp_mem.out_pixel_fmt);
  181048. + if (in_fmt == RGB) {
  181049. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  181050. + /* Enable RGB->YCBCR CSC2 */
  181051. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, out_fmt, 2);
  181052. + ic_conf |= IC_CONF_PP_CSC2;
  181053. + }
  181054. + }
  181055. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  181056. + if (out_fmt == RGB) {
  181057. + /* Enable YCBCR->RGB CSC2 */
  181058. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, YCbCr, RGB, 2);
  181059. + ic_conf |= IC_CONF_PP_CSC2;
  181060. + } else {
  181061. + /* TODO: Support YUV<->YCbCr conversion? */
  181062. + }
  181063. + }
  181064. +
  181065. + if (params->mem_pp_mem.global_alpha_en) {
  181066. + ic_conf |= IC_CONF_IC_GLB_LOC_A;
  181067. + reg = ipu_ic_read(ipu, IC_CMBP_1);
  181068. + reg &= ~(0xff00);
  181069. + reg |= (params->mem_pp_mem.alpha << 8);
  181070. + ipu_ic_write(ipu, reg, IC_CMBP_1);
  181071. + } else
  181072. + ic_conf &= ~IC_CONF_IC_GLB_LOC_A;
  181073. +
  181074. + if (params->mem_pp_mem.key_color_en) {
  181075. + ic_conf |= IC_CONF_KEY_COLOR_EN;
  181076. + ipu_ic_write(ipu, params->mem_pp_mem.key_color,
  181077. + IC_CMBP_2);
  181078. + } else
  181079. + ic_conf &= ~IC_CONF_KEY_COLOR_EN;
  181080. + } else {
  181081. + ic_conf &= ~IC_CONF_PP_CMB;
  181082. + }
  181083. +
  181084. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  181085. +
  181086. + return ret;
  181087. +}
  181088. +
  181089. +void _ipu_ic_uninit_pp(struct ipu_soc *ipu)
  181090. +{
  181091. + uint32_t reg;
  181092. +
  181093. + reg = ipu_ic_read(ipu, IC_CONF);
  181094. + reg &= ~(IC_CONF_PP_EN | IC_CONF_PP_CSC1 | IC_CONF_PP_CSC2 |
  181095. + IC_CONF_PP_CMB);
  181096. + ipu_ic_write(ipu, reg, IC_CONF);
  181097. +}
  181098. +
  181099. +void _ipu_ic_init_rotate_pp(struct ipu_soc *ipu, ipu_channel_params_t *params)
  181100. +{
  181101. +}
  181102. +
  181103. +void _ipu_ic_uninit_rotate_pp(struct ipu_soc *ipu)
  181104. +{
  181105. + uint32_t reg;
  181106. + reg = ipu_ic_read(ipu, IC_CONF);
  181107. + reg &= ~IC_CONF_PP_ROT_EN;
  181108. + ipu_ic_write(ipu, reg, IC_CONF);
  181109. +}
  181110. +
  181111. +int _ipu_ic_idma_init(struct ipu_soc *ipu, int dma_chan,
  181112. + uint16_t width, uint16_t height,
  181113. + int burst_size, ipu_rotate_mode_t rot)
  181114. +{
  181115. + u32 ic_idmac_1, ic_idmac_2, ic_idmac_3;
  181116. + u32 temp_rot = bitrev8(rot) >> 5;
  181117. + bool need_hor_flip = false;
  181118. +
  181119. + if ((burst_size != 8) && (burst_size != 16)) {
  181120. + dev_dbg(ipu->dev, "Illegal burst length for IC\n");
  181121. + return -EINVAL;
  181122. + }
  181123. +
  181124. + width--;
  181125. + height--;
  181126. +
  181127. + if (temp_rot & 0x2) /* Need horizontal flip */
  181128. + need_hor_flip = true;
  181129. +
  181130. + ic_idmac_1 = ipu_ic_read(ipu, IC_IDMAC_1);
  181131. + ic_idmac_2 = ipu_ic_read(ipu, IC_IDMAC_2);
  181132. + ic_idmac_3 = ipu_ic_read(ipu, IC_IDMAC_3);
  181133. + if (dma_chan == 22) { /* PP output - CB2 */
  181134. + if (burst_size == 16)
  181135. + ic_idmac_1 |= IC_IDMAC_1_CB2_BURST_16;
  181136. + else
  181137. + ic_idmac_1 &= ~IC_IDMAC_1_CB2_BURST_16;
  181138. +
  181139. + if (need_hor_flip)
  181140. + ic_idmac_1 |= IC_IDMAC_1_PP_FLIP_RS;
  181141. + else
  181142. + ic_idmac_1 &= ~IC_IDMAC_1_PP_FLIP_RS;
  181143. +
  181144. + ic_idmac_2 &= ~IC_IDMAC_2_PP_HEIGHT_MASK;
  181145. + ic_idmac_2 |= height << IC_IDMAC_2_PP_HEIGHT_OFFSET;
  181146. +
  181147. + ic_idmac_3 &= ~IC_IDMAC_3_PP_WIDTH_MASK;
  181148. + ic_idmac_3 |= width << IC_IDMAC_3_PP_WIDTH_OFFSET;
  181149. + } else if (dma_chan == 11) { /* PP Input - CB5 */
  181150. + if (burst_size == 16)
  181151. + ic_idmac_1 |= IC_IDMAC_1_CB5_BURST_16;
  181152. + else
  181153. + ic_idmac_1 &= ~IC_IDMAC_1_CB5_BURST_16;
  181154. + } else if (dma_chan == 47) { /* PP Rot input */
  181155. + ic_idmac_1 &= ~IC_IDMAC_1_PP_ROT_MASK;
  181156. + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PP_ROT_OFFSET;
  181157. + }
  181158. +
  181159. + if (dma_chan == 12) { /* PRP Input - CB6 */
  181160. + if (burst_size == 16)
  181161. + ic_idmac_1 |= IC_IDMAC_1_CB6_BURST_16;
  181162. + else
  181163. + ic_idmac_1 &= ~IC_IDMAC_1_CB6_BURST_16;
  181164. + }
  181165. +
  181166. + if (dma_chan == 20) { /* PRP ENC output - CB0 */
  181167. + if (burst_size == 16)
  181168. + ic_idmac_1 |= IC_IDMAC_1_CB0_BURST_16;
  181169. + else
  181170. + ic_idmac_1 &= ~IC_IDMAC_1_CB0_BURST_16;
  181171. +
  181172. + if (need_hor_flip)
  181173. + ic_idmac_1 |= IC_IDMAC_1_PRPENC_FLIP_RS;
  181174. + else
  181175. + ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_FLIP_RS;
  181176. +
  181177. + ic_idmac_2 &= ~IC_IDMAC_2_PRPENC_HEIGHT_MASK;
  181178. + ic_idmac_2 |= height << IC_IDMAC_2_PRPENC_HEIGHT_OFFSET;
  181179. +
  181180. + ic_idmac_3 &= ~IC_IDMAC_3_PRPENC_WIDTH_MASK;
  181181. + ic_idmac_3 |= width << IC_IDMAC_3_PRPENC_WIDTH_OFFSET;
  181182. +
  181183. + } else if (dma_chan == 45) { /* PRP ENC Rot input */
  181184. + ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_ROT_MASK;
  181185. + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPENC_ROT_OFFSET;
  181186. + }
  181187. +
  181188. + if (dma_chan == 21) { /* PRP VF output - CB1 */
  181189. + if (burst_size == 16)
  181190. + ic_idmac_1 |= IC_IDMAC_1_CB1_BURST_16;
  181191. + else
  181192. + ic_idmac_1 &= ~IC_IDMAC_1_CB1_BURST_16;
  181193. +
  181194. + if (need_hor_flip)
  181195. + ic_idmac_1 |= IC_IDMAC_1_PRPVF_FLIP_RS;
  181196. + else
  181197. + ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_FLIP_RS;
  181198. +
  181199. + ic_idmac_2 &= ~IC_IDMAC_2_PRPVF_HEIGHT_MASK;
  181200. + ic_idmac_2 |= height << IC_IDMAC_2_PRPVF_HEIGHT_OFFSET;
  181201. +
  181202. + ic_idmac_3 &= ~IC_IDMAC_3_PRPVF_WIDTH_MASK;
  181203. + ic_idmac_3 |= width << IC_IDMAC_3_PRPVF_WIDTH_OFFSET;
  181204. +
  181205. + } else if (dma_chan == 46) { /* PRP VF Rot input */
  181206. + ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_ROT_MASK;
  181207. + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPVF_ROT_OFFSET;
  181208. + }
  181209. +
  181210. + if (dma_chan == 14) { /* PRP VF graphics combining input - CB3 */
  181211. + if (burst_size == 16)
  181212. + ic_idmac_1 |= IC_IDMAC_1_CB3_BURST_16;
  181213. + else
  181214. + ic_idmac_1 &= ~IC_IDMAC_1_CB3_BURST_16;
  181215. + } else if (dma_chan == 15) { /* PP graphics combining input - CB4 */
  181216. + if (burst_size == 16)
  181217. + ic_idmac_1 |= IC_IDMAC_1_CB4_BURST_16;
  181218. + else
  181219. + ic_idmac_1 &= ~IC_IDMAC_1_CB4_BURST_16;
  181220. + } else if (dma_chan == 5) { /* VDIC OUTPUT - CB7 */
  181221. + if (burst_size == 16)
  181222. + ic_idmac_1 |= IC_IDMAC_1_CB7_BURST_16;
  181223. + else
  181224. + ic_idmac_1 &= ~IC_IDMAC_1_CB7_BURST_16;
  181225. + }
  181226. +
  181227. + ipu_ic_write(ipu, ic_idmac_1, IC_IDMAC_1);
  181228. + ipu_ic_write(ipu, ic_idmac_2, IC_IDMAC_2);
  181229. + ipu_ic_write(ipu, ic_idmac_3, IC_IDMAC_3);
  181230. + return 0;
  181231. +}
  181232. +
  181233. +static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in_format,
  181234. + ipu_color_space_t out_format, int csc_index)
  181235. +{
  181236. + /*
  181237. + * Y = 0.257 * R + 0.504 * G + 0.098 * B + 16;
  181238. + * U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
  181239. + * V = 0.439 * R - 0.368 * G - 0.071 * B + 128;
  181240. + */
  181241. + static const uint32_t rgb2ycbcr_coeff[4][3] = {
  181242. + {0x0042, 0x0081, 0x0019},
  181243. + {0x01DA, 0x01B6, 0x0070},
  181244. + {0x0070, 0x01A2, 0x01EE},
  181245. + {0x0040, 0x0200, 0x0200}, /* A0, A1, A2 */
  181246. + };
  181247. +
  181248. + /* transparent RGB->RGB matrix for combining
  181249. + */
  181250. + static const uint32_t rgb2rgb_coeff[4][3] = {
  181251. + {0x0080, 0x0000, 0x0000},
  181252. + {0x0000, 0x0080, 0x0000},
  181253. + {0x0000, 0x0000, 0x0080},
  181254. + {0x0000, 0x0000, 0x0000}, /* A0, A1, A2 */
  181255. + };
  181256. +
  181257. +/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128));
  181258. + G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128));
  181259. + B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */
  181260. + static const uint32_t ycbcr2rgb_coeff[4][3] = {
  181261. + {149, 0, 204},
  181262. + {149, 462, 408},
  181263. + {149, 255, 0},
  181264. + {8192 - 446, 266, 8192 - 554}, /* A0, A1, A2 */
  181265. + };
  181266. +
  181267. + uint32_t param;
  181268. + uint32_t *base = NULL;
  181269. +
  181270. + if (ic_task == IC_TASK_ENCODER) {
  181271. + base = (uint32_t *)ipu->tpmem_base + 0x2008 / 4;
  181272. + } else if (ic_task == IC_TASK_VIEWFINDER) {
  181273. + if (csc_index == 1)
  181274. + base = (uint32_t *)ipu->tpmem_base + 0x4028 / 4;
  181275. + else
  181276. + base = (uint32_t *)ipu->tpmem_base + 0x4040 / 4;
  181277. + } else if (ic_task == IC_TASK_POST_PROCESSOR) {
  181278. + if (csc_index == 1)
  181279. + base = (uint32_t *)ipu->tpmem_base + 0x6060 / 4;
  181280. + else
  181281. + base = (uint32_t *)ipu->tpmem_base + 0x6078 / 4;
  181282. + } else {
  181283. + BUG();
  181284. + }
  181285. +
  181286. + if ((in_format == YCbCr) && (out_format == RGB)) {
  181287. + /* Init CSC (YCbCr->RGB) */
  181288. + param = (ycbcr2rgb_coeff[3][0] << 27) |
  181289. + (ycbcr2rgb_coeff[0][0] << 18) |
  181290. + (ycbcr2rgb_coeff[1][1] << 9) | ycbcr2rgb_coeff[2][2];
  181291. + writel(param, base++);
  181292. + /* scale = 2, sat = 0 */
  181293. + param = (ycbcr2rgb_coeff[3][0] >> 5) | (2L << (40 - 32));
  181294. + writel(param, base++);
  181295. +
  181296. + param = (ycbcr2rgb_coeff[3][1] << 27) |
  181297. + (ycbcr2rgb_coeff[0][1] << 18) |
  181298. + (ycbcr2rgb_coeff[1][0] << 9) | ycbcr2rgb_coeff[2][0];
  181299. + writel(param, base++);
  181300. + param = (ycbcr2rgb_coeff[3][1] >> 5);
  181301. + writel(param, base++);
  181302. +
  181303. + param = (ycbcr2rgb_coeff[3][2] << 27) |
  181304. + (ycbcr2rgb_coeff[0][2] << 18) |
  181305. + (ycbcr2rgb_coeff[1][2] << 9) | ycbcr2rgb_coeff[2][1];
  181306. + writel(param, base++);
  181307. + param = (ycbcr2rgb_coeff[3][2] >> 5);
  181308. + writel(param, base++);
  181309. + } else if ((in_format == RGB) && (out_format == YCbCr)) {
  181310. + /* Init CSC (RGB->YCbCr) */
  181311. + param = (rgb2ycbcr_coeff[3][0] << 27) |
  181312. + (rgb2ycbcr_coeff[0][0] << 18) |
  181313. + (rgb2ycbcr_coeff[1][1] << 9) | rgb2ycbcr_coeff[2][2];
  181314. + writel(param, base++);
  181315. + /* scale = 1, sat = 0 */
  181316. + param = (rgb2ycbcr_coeff[3][0] >> 5) | (1UL << 8);
  181317. + writel(param, base++);
  181318. +
  181319. + param = (rgb2ycbcr_coeff[3][1] << 27) |
  181320. + (rgb2ycbcr_coeff[0][1] << 18) |
  181321. + (rgb2ycbcr_coeff[1][0] << 9) | rgb2ycbcr_coeff[2][0];
  181322. + writel(param, base++);
  181323. + param = (rgb2ycbcr_coeff[3][1] >> 5);
  181324. + writel(param, base++);
  181325. +
  181326. + param = (rgb2ycbcr_coeff[3][2] << 27) |
  181327. + (rgb2ycbcr_coeff[0][2] << 18) |
  181328. + (rgb2ycbcr_coeff[1][2] << 9) | rgb2ycbcr_coeff[2][1];
  181329. + writel(param, base++);
  181330. + param = (rgb2ycbcr_coeff[3][2] >> 5);
  181331. + writel(param, base++);
  181332. + } else if ((in_format == RGB) && (out_format == RGB)) {
  181333. + /* Init CSC */
  181334. + param =
  181335. + (rgb2rgb_coeff[3][0] << 27) | (rgb2rgb_coeff[0][0] << 18) |
  181336. + (rgb2rgb_coeff[1][1] << 9) | rgb2rgb_coeff[2][2];
  181337. + writel(param, base++);
  181338. + /* scale = 2, sat = 0 */
  181339. + param = (rgb2rgb_coeff[3][0] >> 5) | (2UL << 8);
  181340. + writel(param, base++);
  181341. +
  181342. + param =
  181343. + (rgb2rgb_coeff[3][1] << 27) | (rgb2rgb_coeff[0][1] << 18) |
  181344. + (rgb2rgb_coeff[1][0] << 9) | rgb2rgb_coeff[2][0];
  181345. + writel(param, base++);
  181346. + param = (rgb2rgb_coeff[3][1] >> 5);
  181347. + writel(param, base++);
  181348. +
  181349. + param =
  181350. + (rgb2rgb_coeff[3][2] << 27) | (rgb2rgb_coeff[0][2] << 18) |
  181351. + (rgb2rgb_coeff[1][2] << 9) | rgb2rgb_coeff[2][1];
  181352. + writel(param, base++);
  181353. + param = (rgb2rgb_coeff[3][2] >> 5);
  181354. + writel(param, base++);
  181355. + } else {
  181356. + dev_err(ipu->dev, "Unsupported color space conversion\n");
  181357. + }
  181358. +}
  181359. +
  181360. +static int _calc_resize_coeffs(struct ipu_soc *ipu,
  181361. + uint32_t inSize, uint32_t outSize,
  181362. + uint32_t *resizeCoeff,
  181363. + uint32_t *downsizeCoeff)
  181364. +{
  181365. + uint32_t tempSize;
  181366. + uint32_t tempDownsize;
  181367. +
  181368. + if (inSize > 4096) {
  181369. + dev_err(ipu->dev, "IC input size(%d) cannot exceed 4096\n",
  181370. + inSize);
  181371. + return -EINVAL;
  181372. + }
  181373. +
  181374. + if (outSize > 1024) {
  181375. + dev_err(ipu->dev, "IC output size(%d) cannot exceed 1024\n",
  181376. + outSize);
  181377. + return -EINVAL;
  181378. + }
  181379. +
  181380. + if ((outSize << 3) < inSize) {
  181381. + dev_err(ipu->dev, "IC cannot downsize more than 8:1\n");
  181382. + return -EINVAL;
  181383. + }
  181384. +
  181385. + /* Compute downsizing coefficient */
  181386. + /* Output of downsizing unit cannot be more than 1024 */
  181387. + tempDownsize = 0;
  181388. + tempSize = inSize;
  181389. + while (((tempSize > 1024) || (tempSize >= outSize * 2)) &&
  181390. + (tempDownsize < 2)) {
  181391. + tempSize >>= 1;
  181392. + tempDownsize++;
  181393. + }
  181394. + *downsizeCoeff = tempDownsize;
  181395. +
  181396. + /* compute resizing coefficient using the following equation:
  181397. + resizeCoeff = M*(SI -1)/(SO - 1)
  181398. + where M = 2^13, SI - input size, SO - output size */
  181399. + *resizeCoeff = (8192L * (tempSize - 1)) / (outSize - 1);
  181400. + if (*resizeCoeff >= 16384L) {
  181401. + dev_err(ipu->dev, "Overflow on IC resize coefficient.\n");
  181402. + return -EINVAL;
  181403. + }
  181404. +
  181405. + dev_dbg(ipu->dev, "resizing from %u -> %u pixels, "
  181406. + "downsize=%u, resize=%u.%lu (reg=%u)\n", inSize, outSize,
  181407. + *downsizeCoeff, (*resizeCoeff >= 8192L) ? 1 : 0,
  181408. + ((*resizeCoeff & 0x1FFF) * 10000L) / 8192L, *resizeCoeff);
  181409. +
  181410. + return 0;
  181411. +}
  181412. +
  181413. +void _ipu_vdi_toggle_top_field_man(struct ipu_soc *ipu)
  181414. +{
  181415. + uint32_t reg;
  181416. + uint32_t mask_reg;
  181417. +
  181418. + reg = ipu_vdi_read(ipu, VDI_C);
  181419. + mask_reg = reg & VDI_C_TOP_FIELD_MAN_1;
  181420. + if (mask_reg == VDI_C_TOP_FIELD_MAN_1)
  181421. + reg &= ~VDI_C_TOP_FIELD_MAN_1;
  181422. + else
  181423. + reg |= VDI_C_TOP_FIELD_MAN_1;
  181424. +
  181425. + ipu_vdi_write(ipu, reg, VDI_C);
  181426. +}
  181427. diff -Nur linux-3.14.14/drivers/mxc/ipu3/ipu_param_mem.h linux-imx6-3.14/drivers/mxc/ipu3/ipu_param_mem.h
  181428. --- linux-3.14.14/drivers/mxc/ipu3/ipu_param_mem.h 1969-12-31 18:00:00.000000000 -0600
  181429. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_param_mem.h 2014-12-08 00:31:53.476418001 -0600
  181430. @@ -0,0 +1,921 @@
  181431. +/*
  181432. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  181433. + */
  181434. +
  181435. +/*
  181436. + * The code contained herein is licensed under the GNU General Public
  181437. + * License. You may obtain a copy of the GNU General Public License
  181438. + * Version 2 or later at the following locations:
  181439. + *
  181440. + * http://www.opensource.org/licenses/gpl-license.html
  181441. + * http://www.gnu.org/copyleft/gpl.html
  181442. + */
  181443. +#ifndef __INCLUDE_IPU_PARAM_MEM_H__
  181444. +#define __INCLUDE_IPU_PARAM_MEM_H__
  181445. +
  181446. +#include <linux/bitrev.h>
  181447. +#include <linux/types.h>
  181448. +
  181449. +#include "ipu_prv.h"
  181450. +
  181451. +extern u32 *ipu_cpmem_base;
  181452. +
  181453. +struct ipu_ch_param_word {
  181454. + uint32_t data[5];
  181455. + uint32_t res[3];
  181456. +};
  181457. +
  181458. +struct ipu_ch_param {
  181459. + struct ipu_ch_param_word word[2];
  181460. +};
  181461. +
  181462. +#define ipu_ch_param_addr(ipu, ch) (((struct ipu_ch_param *)ipu->cpmem_base) + (ch))
  181463. +
  181464. +#define _param_word(base, w) \
  181465. + (((struct ipu_ch_param *)(base))->word[(w)].data)
  181466. +
  181467. +#define ipu_ch_param_set_field(base, w, bit, size, v) { \
  181468. + int i = (bit) / 32; \
  181469. + int off = (bit) % 32; \
  181470. + _param_word(base, w)[i] |= (v) << off; \
  181471. + if (((bit)+(size)-1)/32 > i) { \
  181472. + _param_word(base, w)[i + 1] |= (v) >> (off ? (32 - off) : 0); \
  181473. + } \
  181474. +}
  181475. +
  181476. +#define ipu_ch_param_set_field_io(base, w, bit, size, v) { \
  181477. + int i = (bit) / 32; \
  181478. + int off = (bit) % 32; \
  181479. + unsigned reg_offset; \
  181480. + u32 temp; \
  181481. + reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
  181482. + reg_offset += i; \
  181483. + temp = readl((u32 *)base + reg_offset); \
  181484. + temp |= (v) << off; \
  181485. + writel(temp, (u32 *)base + reg_offset); \
  181486. + if (((bit)+(size)-1)/32 > i) { \
  181487. + reg_offset++; \
  181488. + temp = readl((u32 *)base + reg_offset); \
  181489. + temp |= (v) >> (off ? (32 - off) : 0); \
  181490. + writel(temp, (u32 *)base + reg_offset); \
  181491. + } \
  181492. +}
  181493. +
  181494. +#define ipu_ch_param_mod_field(base, w, bit, size, v) { \
  181495. + int i = (bit) / 32; \
  181496. + int off = (bit) % 32; \
  181497. + u32 mask = (1UL << size) - 1; \
  181498. + u32 temp = _param_word(base, w)[i]; \
  181499. + temp &= ~(mask << off); \
  181500. + _param_word(base, w)[i] = temp | (v) << off; \
  181501. + if (((bit)+(size)-1)/32 > i) { \
  181502. + temp = _param_word(base, w)[i + 1]; \
  181503. + temp &= ~(mask >> (32 - off)); \
  181504. + _param_word(base, w)[i + 1] = \
  181505. + temp | ((v) >> (off ? (32 - off) : 0)); \
  181506. + } \
  181507. +}
  181508. +
  181509. +#define ipu_ch_param_mod_field_io(base, w, bit, size, v) { \
  181510. + int i = (bit) / 32; \
  181511. + int off = (bit) % 32; \
  181512. + u32 mask = (1UL << size) - 1; \
  181513. + unsigned reg_offset; \
  181514. + u32 temp; \
  181515. + reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
  181516. + reg_offset += i; \
  181517. + temp = readl((u32 *)base + reg_offset); \
  181518. + temp &= ~(mask << off); \
  181519. + temp |= (v) << off; \
  181520. + writel(temp, (u32 *)base + reg_offset); \
  181521. + if (((bit)+(size)-1)/32 > i) { \
  181522. + reg_offset++; \
  181523. + temp = readl((u32 *)base + reg_offset); \
  181524. + temp &= ~(mask >> (32 - off)); \
  181525. + temp |= ((v) >> (off ? (32 - off) : 0)); \
  181526. + writel(temp, (u32 *)base + reg_offset); \
  181527. + } \
  181528. +}
  181529. +
  181530. +#define ipu_ch_param_read_field(base, w, bit, size) ({ \
  181531. + u32 temp2; \
  181532. + int i = (bit) / 32; \
  181533. + int off = (bit) % 32; \
  181534. + u32 mask = (1UL << size) - 1; \
  181535. + u32 temp1 = _param_word(base, w)[i]; \
  181536. + temp1 = mask & (temp1 >> off); \
  181537. + if (((bit)+(size)-1)/32 > i) { \
  181538. + temp2 = _param_word(base, w)[i + 1]; \
  181539. + temp2 &= mask >> (off ? (32 - off) : 0); \
  181540. + temp1 |= temp2 << (off ? (32 - off) : 0); \
  181541. + } \
  181542. + temp1; \
  181543. +})
  181544. +
  181545. +#define ipu_ch_param_read_field_io(base, w, bit, size) ({ \
  181546. + u32 temp1, temp2; \
  181547. + int i = (bit) / 32; \
  181548. + int off = (bit) % 32; \
  181549. + u32 mask = (1UL << size) - 1; \
  181550. + unsigned reg_offset; \
  181551. + reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
  181552. + reg_offset += i; \
  181553. + temp1 = readl((u32 *)base + reg_offset); \
  181554. + temp1 = mask & (temp1 >> off); \
  181555. + if (((bit)+(size)-1)/32 > i) { \
  181556. + reg_offset++; \
  181557. + temp2 = readl((u32 *)base + reg_offset); \
  181558. + temp2 &= mask >> (off ? (32 - off) : 0); \
  181559. + temp1 |= temp2 << (off ? (32 - off) : 0); \
  181560. + } \
  181561. + temp1; \
  181562. +})
  181563. +
  181564. +static inline int __ipu_ch_get_third_buf_cpmem_num(int ch)
  181565. +{
  181566. + switch (ch) {
  181567. + case 8:
  181568. + return 64;
  181569. + case 9:
  181570. + return 65;
  181571. + case 10:
  181572. + return 66;
  181573. + case 13:
  181574. + return 67;
  181575. + case 21:
  181576. + return 68;
  181577. + case 23:
  181578. + return 69;
  181579. + case 27:
  181580. + return 70;
  181581. + case 28:
  181582. + return 71;
  181583. + default:
  181584. + return -EINVAL;
  181585. + }
  181586. + return 0;
  181587. +}
  181588. +
  181589. +static inline void _ipu_ch_params_set_packing(struct ipu_ch_param *p,
  181590. + int red_width, int red_offset,
  181591. + int green_width, int green_offset,
  181592. + int blue_width, int blue_offset,
  181593. + int alpha_width, int alpha_offset)
  181594. +{
  181595. + /* Setup red width and offset */
  181596. + ipu_ch_param_set_field(p, 1, 116, 3, red_width - 1);
  181597. + ipu_ch_param_set_field(p, 1, 128, 5, red_offset);
  181598. + /* Setup green width and offset */
  181599. + ipu_ch_param_set_field(p, 1, 119, 3, green_width - 1);
  181600. + ipu_ch_param_set_field(p, 1, 133, 5, green_offset);
  181601. + /* Setup blue width and offset */
  181602. + ipu_ch_param_set_field(p, 1, 122, 3, blue_width - 1);
  181603. + ipu_ch_param_set_field(p, 1, 138, 5, blue_offset);
  181604. + /* Setup alpha width and offset */
  181605. + ipu_ch_param_set_field(p, 1, 125, 3, alpha_width - 1);
  181606. + ipu_ch_param_set_field(p, 1, 143, 5, alpha_offset);
  181607. +}
  181608. +
  181609. +static inline void _ipu_ch_param_dump(struct ipu_soc *ipu, int ch)
  181610. +{
  181611. + struct ipu_ch_param *p = ipu_ch_param_addr(ipu, ch);
  181612. + dev_dbg(ipu->dev, "ch %d word 0 - %08X %08X %08X %08X %08X\n", ch,
  181613. + p->word[0].data[0], p->word[0].data[1], p->word[0].data[2],
  181614. + p->word[0].data[3], p->word[0].data[4]);
  181615. + dev_dbg(ipu->dev, "ch %d word 1 - %08X %08X %08X %08X %08X\n", ch,
  181616. + p->word[1].data[0], p->word[1].data[1], p->word[1].data[2],
  181617. + p->word[1].data[3], p->word[1].data[4]);
  181618. + dev_dbg(ipu->dev, "PFS 0x%x, ",
  181619. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 85, 4));
  181620. + dev_dbg(ipu->dev, "BPP 0x%x, ",
  181621. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 107, 3));
  181622. + dev_dbg(ipu->dev, "NPB 0x%x\n",
  181623. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7));
  181624. +
  181625. + dev_dbg(ipu->dev, "FW %d, ",
  181626. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 125, 13));
  181627. + dev_dbg(ipu->dev, "FH %d, ",
  181628. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 138, 12));
  181629. + dev_dbg(ipu->dev, "EBA0 0x%x\n",
  181630. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 0, 29) << 3);
  181631. + dev_dbg(ipu->dev, "EBA1 0x%x\n",
  181632. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 29, 29) << 3);
  181633. + dev_dbg(ipu->dev, "Stride %d\n",
  181634. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14));
  181635. + dev_dbg(ipu->dev, "scan_order %d\n",
  181636. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 113, 1));
  181637. + dev_dbg(ipu->dev, "uv_stride %d\n",
  181638. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 128, 14));
  181639. + dev_dbg(ipu->dev, "u_offset 0x%x\n",
  181640. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22) << 3);
  181641. + dev_dbg(ipu->dev, "v_offset 0x%x\n",
  181642. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22) << 3);
  181643. +
  181644. + dev_dbg(ipu->dev, "Width0 %d+1, ",
  181645. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 116, 3));
  181646. + dev_dbg(ipu->dev, "Width1 %d+1, ",
  181647. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 119, 3));
  181648. + dev_dbg(ipu->dev, "Width2 %d+1, ",
  181649. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 122, 3));
  181650. + dev_dbg(ipu->dev, "Width3 %d+1, ",
  181651. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 125, 3));
  181652. + dev_dbg(ipu->dev, "Offset0 %d, ",
  181653. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 128, 5));
  181654. + dev_dbg(ipu->dev, "Offset1 %d, ",
  181655. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 133, 5));
  181656. + dev_dbg(ipu->dev, "Offset2 %d, ",
  181657. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 138, 5));
  181658. + dev_dbg(ipu->dev, "Offset3 %d\n",
  181659. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 143, 5));
  181660. +}
  181661. +
  181662. +static inline void fill_cpmem(struct ipu_soc *ipu, int ch, struct ipu_ch_param *params)
  181663. +{
  181664. + int i, w;
  181665. + void *addr = ipu_ch_param_addr(ipu, ch);
  181666. +
  181667. + /* 2 words, 5 valid data */
  181668. + for (w = 0; w < 2; w++) {
  181669. + for (i = 0; i < 5; i++) {
  181670. + writel(params->word[w].data[i], addr);
  181671. + addr += 4;
  181672. + }
  181673. + addr += 12;
  181674. + }
  181675. +}
  181676. +
  181677. +static inline void _ipu_ch_param_init(struct ipu_soc *ipu, int ch,
  181678. + uint32_t pixel_fmt, uint32_t width,
  181679. + uint32_t height, uint32_t stride,
  181680. + uint32_t u, uint32_t v,
  181681. + uint32_t uv_stride, dma_addr_t addr0,
  181682. + dma_addr_t addr1, dma_addr_t addr2)
  181683. +{
  181684. + uint32_t u_offset = 0;
  181685. + uint32_t v_offset = 0;
  181686. + int32_t sub_ch = 0;
  181687. + struct ipu_ch_param params;
  181688. +
  181689. + memset(&params, 0, sizeof(params));
  181690. +
  181691. + ipu_ch_param_set_field(&params, 0, 125, 13, width - 1);
  181692. +
  181693. + if (((ch == 8) || (ch == 9) || (ch == 10)) && !ipu->vdoa_en) {
  181694. + ipu_ch_param_set_field(&params, 0, 138, 12, (height / 2) - 1);
  181695. + ipu_ch_param_set_field(&params, 1, 102, 14, (stride * 2) - 1);
  181696. + } else {
  181697. + /* note: for vdoa+vdi- ch8/9/10, always use band mode */
  181698. + ipu_ch_param_set_field(&params, 0, 138, 12, height - 1);
  181699. + ipu_ch_param_set_field(&params, 1, 102, 14, stride - 1);
  181700. + }
  181701. +
  181702. + /* EBA is 8-byte aligned */
  181703. + ipu_ch_param_set_field(&params, 1, 0, 29, addr0 >> 3);
  181704. + ipu_ch_param_set_field(&params, 1, 29, 29, addr1 >> 3);
  181705. + if (addr0%8)
  181706. + dev_warn(ipu->dev,
  181707. + "IDMAC%d's EBA0 is not 8-byte aligned\n", ch);
  181708. + if (addr1%8)
  181709. + dev_warn(ipu->dev,
  181710. + "IDMAC%d's EBA1 is not 8-byte aligned\n", ch);
  181711. +
  181712. + switch (pixel_fmt) {
  181713. + case IPU_PIX_FMT_GENERIC:
  181714. + /*Represents 8-bit Generic data */
  181715. + ipu_ch_param_set_field(&params, 0, 107, 3, 5); /* bits/pixel */
  181716. + ipu_ch_param_set_field(&params, 1, 85, 4, 6); /* pix format */
  181717. + ipu_ch_param_set_field(&params, 1, 78, 7, 63); /* burst size */
  181718. +
  181719. + break;
  181720. + case IPU_PIX_FMT_GENERIC_16:
  181721. + /* Represents 16-bit generic data */
  181722. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  181723. + ipu_ch_param_set_field(&params, 1, 85, 4, 6); /* pix format */
  181724. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181725. +
  181726. + break;
  181727. + case IPU_PIX_FMT_GENERIC_32:
  181728. + /*Represents 32-bit Generic data */
  181729. + break;
  181730. + case IPU_PIX_FMT_RGB565:
  181731. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  181732. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181733. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181734. +
  181735. + _ipu_ch_params_set_packing(&params, 5, 0, 6, 5, 5, 11, 8, 16);
  181736. + break;
  181737. + case IPU_PIX_FMT_BGR24:
  181738. + ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
  181739. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181740. + ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
  181741. +
  181742. + _ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
  181743. + break;
  181744. + case IPU_PIX_FMT_RGB24:
  181745. + case IPU_PIX_FMT_YUV444:
  181746. + ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
  181747. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181748. + ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
  181749. +
  181750. + _ipu_ch_params_set_packing(&params, 8, 16, 8, 8, 8, 0, 8, 24);
  181751. + break;
  181752. + case IPU_PIX_FMT_VYU444:
  181753. + ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
  181754. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181755. + ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
  181756. +
  181757. + _ipu_ch_params_set_packing(&params, 8, 8, 8, 0, 8, 16, 8, 24);
  181758. + break;
  181759. + case IPU_PIX_FMT_BGRA32:
  181760. + case IPU_PIX_FMT_BGR32:
  181761. + ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
  181762. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  181763. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  181764. +
  181765. + _ipu_ch_params_set_packing(&params, 8, 8, 8, 16, 8, 24, 8, 0);
  181766. + break;
  181767. + case IPU_PIX_FMT_RGBA32:
  181768. + case IPU_PIX_FMT_RGB32:
  181769. + ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* 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, 15); /* burst size */
  181772. +
  181773. + _ipu_ch_params_set_packing(&params, 8, 24, 8, 16, 8, 8, 8, 0);
  181774. + break;
  181775. + case IPU_PIX_FMT_ABGR32:
  181776. + ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* 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, 15); /* 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_UYVY:
  181783. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  181784. + ipu_ch_param_set_field(&params, 1, 85, 4, 0xA); /* pix format */
  181785. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  181786. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  181787. + } else {
  181788. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181789. + }
  181790. + break;
  181791. + case IPU_PIX_FMT_YUYV:
  181792. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  181793. + ipu_ch_param_set_field(&params, 1, 85, 4, 0x8); /* pix format */
  181794. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  181795. + if (ipu->vdoa_en) {
  181796. + ipu_ch_param_set_field(&params, 1, 78, 7, 31);
  181797. + } else {
  181798. + ipu_ch_param_set_field(&params, 1, 78, 7, 15);
  181799. + }
  181800. + } else {
  181801. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181802. + }
  181803. + break;
  181804. + case IPU_PIX_FMT_YUV420P2:
  181805. + case IPU_PIX_FMT_YUV420P:
  181806. + ipu_ch_param_set_field(&params, 1, 85, 4, 2); /* pix format */
  181807. +
  181808. + if (uv_stride < stride / 2)
  181809. + uv_stride = stride / 2;
  181810. +
  181811. + u_offset = stride * height;
  181812. + v_offset = u_offset + (uv_stride * height / 2);
  181813. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  181814. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  181815. + uv_stride = uv_stride*2;
  181816. + } else {
  181817. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181818. + }
  181819. + break;
  181820. + case IPU_PIX_FMT_YVU420P:
  181821. + ipu_ch_param_set_field(&params, 1, 85, 4, 2); /* pix format */
  181822. +
  181823. + if (uv_stride < stride / 2)
  181824. + uv_stride = stride / 2;
  181825. +
  181826. + v_offset = stride * height;
  181827. + u_offset = v_offset + (uv_stride * height / 2);
  181828. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  181829. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  181830. + uv_stride = uv_stride*2;
  181831. + } else {
  181832. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181833. + }
  181834. + break;
  181835. + case IPU_PIX_FMT_YVU422P:
  181836. + /* BPP & pixel format */
  181837. + ipu_ch_param_set_field(&params, 1, 85, 4, 1); /* pix format */
  181838. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181839. +
  181840. + if (uv_stride < stride / 2)
  181841. + uv_stride = stride / 2;
  181842. +
  181843. + v_offset = (v == 0) ? stride * height : v;
  181844. + u_offset = (u == 0) ? v_offset + v_offset / 2 : u;
  181845. + break;
  181846. + case IPU_PIX_FMT_YUV422P:
  181847. + /* BPP & pixel format */
  181848. + ipu_ch_param_set_field(&params, 1, 85, 4, 1); /* pix format */
  181849. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181850. +
  181851. + if (uv_stride < stride / 2)
  181852. + uv_stride = stride / 2;
  181853. +
  181854. + u_offset = (u == 0) ? stride * height : u;
  181855. + v_offset = (v == 0) ? u_offset + u_offset / 2 : v;
  181856. + break;
  181857. + case IPU_PIX_FMT_YUV444P:
  181858. + /* BPP & pixel format */
  181859. + ipu_ch_param_set_field(&params, 1, 85, 4, 0); /* pix format */
  181860. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181861. + uv_stride = stride;
  181862. + u_offset = (u == 0) ? stride * height : u;
  181863. + v_offset = (v == 0) ? u_offset * 2 : v;
  181864. + break;
  181865. + case IPU_PIX_FMT_NV12:
  181866. + /* BPP & pixel format */
  181867. + ipu_ch_param_set_field(&params, 1, 85, 4, 4); /* pix format */
  181868. + uv_stride = stride;
  181869. + u_offset = (u == 0) ? stride * height : u;
  181870. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  181871. + if (ipu->vdoa_en) {
  181872. + /* one field buffer, memory width 64bits */
  181873. + ipu_ch_param_set_field(&params, 1, 78, 7, 63);
  181874. + } else {
  181875. + ipu_ch_param_set_field(&params, 1, 78, 7, 15);
  181876. + /* top/bottom field in one buffer*/
  181877. + uv_stride = uv_stride*2;
  181878. + }
  181879. + } else {
  181880. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  181881. + }
  181882. + break;
  181883. + default:
  181884. + dev_err(ipu->dev, "mxc ipu: unimplemented pixel format\n");
  181885. + break;
  181886. + }
  181887. + /*set burst size to 16*/
  181888. +
  181889. +
  181890. + if (uv_stride)
  181891. + ipu_ch_param_set_field(&params, 1, 128, 14, uv_stride - 1);
  181892. +
  181893. + /* Get the uv offset from user when need cropping */
  181894. + if (u || v) {
  181895. + u_offset = u;
  181896. + v_offset = v;
  181897. + }
  181898. +
  181899. + /* UBO and VBO are 22-bit and 8-byte aligned */
  181900. + if (u_offset/8 > 0x3fffff)
  181901. + dev_warn(ipu->dev,
  181902. + "IDMAC%d's U offset exceeds IPU limitation\n", ch);
  181903. + if (v_offset/8 > 0x3fffff)
  181904. + dev_warn(ipu->dev,
  181905. + "IDMAC%d's V offset exceeds IPU limitation\n", ch);
  181906. + if (u_offset%8)
  181907. + dev_warn(ipu->dev,
  181908. + "IDMAC%d's U offset is not 8-byte aligned\n", ch);
  181909. + if (v_offset%8)
  181910. + dev_warn(ipu->dev,
  181911. + "IDMAC%d's V offset is not 8-byte aligned\n", ch);
  181912. +
  181913. + ipu_ch_param_set_field(&params, 0, 46, 22, u_offset / 8);
  181914. + ipu_ch_param_set_field(&params, 0, 68, 22, v_offset / 8);
  181915. +
  181916. + dev_dbg(ipu->dev, "initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ipu, ch));
  181917. + fill_cpmem(ipu, ch, &params);
  181918. + if (addr2) {
  181919. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  181920. + if (sub_ch <= 0)
  181921. + return;
  181922. +
  181923. + ipu_ch_param_set_field(&params, 1, 0, 29, addr2 >> 3);
  181924. + ipu_ch_param_set_field(&params, 1, 29, 29, 0);
  181925. + if (addr2%8)
  181926. + dev_warn(ipu->dev,
  181927. + "IDMAC%d's sub-CPMEM entry%d EBA0 is not "
  181928. + "8-byte aligned\n", ch, sub_ch);
  181929. +
  181930. + dev_dbg(ipu->dev, "initializing idma ch %d @ %p sub cpmem\n", ch,
  181931. + ipu_ch_param_addr(ipu, sub_ch));
  181932. + fill_cpmem(ipu, sub_ch, &params);
  181933. + }
  181934. +};
  181935. +
  181936. +static inline void _ipu_ch_param_set_burst_size(struct ipu_soc *ipu,
  181937. + uint32_t ch,
  181938. + uint16_t burst_pixels)
  181939. +{
  181940. + int32_t sub_ch = 0;
  181941. +
  181942. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7,
  181943. + burst_pixels - 1);
  181944. +
  181945. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  181946. + if (sub_ch <= 0)
  181947. + return;
  181948. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 78, 7,
  181949. + burst_pixels - 1);
  181950. +};
  181951. +
  181952. +static inline int _ipu_ch_param_get_burst_size(struct ipu_soc *ipu, uint32_t ch)
  181953. +{
  181954. + return ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7) + 1;
  181955. +};
  181956. +
  181957. +static inline int _ipu_ch_param_get_bpp(struct ipu_soc *ipu, uint32_t ch)
  181958. +{
  181959. + return ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 107, 3);
  181960. +};
  181961. +
  181962. +static inline void _ipu_ch_param_set_buffer(struct ipu_soc *ipu, uint32_t ch,
  181963. + int bufNum, dma_addr_t phyaddr)
  181964. +{
  181965. + if (bufNum == 2) {
  181966. + ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  181967. + if (ch <= 0)
  181968. + return;
  181969. + bufNum = 0;
  181970. + }
  181971. +
  181972. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 29 * bufNum, 29,
  181973. + phyaddr / 8);
  181974. +};
  181975. +
  181976. +static inline void _ipu_ch_param_set_rotation(struct ipu_soc *ipu, uint32_t ch,
  181977. + ipu_rotate_mode_t rot)
  181978. +{
  181979. + u32 temp_rot = bitrev8(rot) >> 5;
  181980. + int32_t sub_ch = 0;
  181981. +
  181982. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 119, 3, temp_rot);
  181983. +
  181984. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  181985. + if (sub_ch <= 0)
  181986. + return;
  181987. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 119, 3, temp_rot);
  181988. +};
  181989. +
  181990. +static inline void _ipu_ch_param_set_block_mode(struct ipu_soc *ipu, uint32_t ch)
  181991. +{
  181992. + int32_t sub_ch = 0;
  181993. +
  181994. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 117, 2, 1);
  181995. +
  181996. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  181997. + if (sub_ch <= 0)
  181998. + return;
  181999. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 117, 2, 1);
  182000. +};
  182001. +
  182002. +static inline void _ipu_ch_param_set_alpha_use_separate_channel(struct ipu_soc *ipu,
  182003. + uint32_t ch,
  182004. + bool option)
  182005. +{
  182006. + int32_t sub_ch = 0;
  182007. +
  182008. + if (option) {
  182009. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 1);
  182010. + } else {
  182011. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 0);
  182012. + }
  182013. +
  182014. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182015. + if (sub_ch <= 0)
  182016. + return;
  182017. +
  182018. + if (option) {
  182019. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 1);
  182020. + } else {
  182021. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 0);
  182022. + }
  182023. +};
  182024. +
  182025. +static inline void _ipu_ch_param_set_alpha_condition_read(struct ipu_soc *ipu, uint32_t ch)
  182026. +{
  182027. + int32_t sub_ch = 0;
  182028. +
  182029. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 149, 1, 1);
  182030. +
  182031. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182032. + if (sub_ch <= 0)
  182033. + return;
  182034. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 149, 1, 1);
  182035. +};
  182036. +
  182037. +static inline void _ipu_ch_param_set_alpha_buffer_memory(struct ipu_soc *ipu, uint32_t ch)
  182038. +{
  182039. + int alp_mem_idx;
  182040. + int32_t sub_ch = 0;
  182041. +
  182042. + switch (ch) {
  182043. + case 14: /* PRP graphic */
  182044. + alp_mem_idx = 0;
  182045. + break;
  182046. + case 15: /* PP graphic */
  182047. + alp_mem_idx = 1;
  182048. + break;
  182049. + case 23: /* DP BG SYNC graphic */
  182050. + alp_mem_idx = 4;
  182051. + break;
  182052. + case 27: /* DP FG SYNC graphic */
  182053. + alp_mem_idx = 2;
  182054. + break;
  182055. + default:
  182056. + dev_err(ipu->dev, "unsupported correlative channel of local "
  182057. + "alpha channel\n");
  182058. + return;
  182059. + }
  182060. +
  182061. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 90, 3, alp_mem_idx);
  182062. +
  182063. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182064. + if (sub_ch <= 0)
  182065. + return;
  182066. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 90, 3, alp_mem_idx);
  182067. +};
  182068. +
  182069. +static inline void _ipu_ch_param_set_interlaced_scan(struct ipu_soc *ipu, uint32_t ch)
  182070. +{
  182071. + u32 stride;
  182072. + int32_t sub_ch = 0;
  182073. +
  182074. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182075. +
  182076. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch), 0, 113, 1, 1);
  182077. + if (sub_ch > 0)
  182078. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 113, 1, 1);
  182079. + stride = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14) + 1;
  182080. + /* ILO is 20-bit and 8-byte aligned */
  182081. + if (stride/8 > 0xfffff)
  182082. + dev_warn(ipu->dev,
  182083. + "IDMAC%d's ILO exceeds IPU limitation\n", ch);
  182084. + if (stride%8)
  182085. + dev_warn(ipu->dev,
  182086. + "IDMAC%d's ILO is not 8-byte aligned\n", ch);
  182087. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 58, 20, stride / 8);
  182088. + if (sub_ch > 0)
  182089. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 58, 20,
  182090. + stride / 8);
  182091. + stride *= 2;
  182092. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14, stride - 1);
  182093. + if (sub_ch > 0)
  182094. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 102, 14,
  182095. + stride - 1);
  182096. +};
  182097. +
  182098. +static inline void _ipu_ch_param_set_axi_id(struct ipu_soc *ipu, uint32_t ch, uint32_t id)
  182099. +{
  182100. + int32_t sub_ch = 0;
  182101. +
  182102. + id %= 4;
  182103. +
  182104. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 93, 2, id);
  182105. +
  182106. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182107. + if (sub_ch <= 0)
  182108. + return;
  182109. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 93, 2, id);
  182110. +};
  182111. +
  182112. +/* IDMAC U/V offset changing support */
  182113. +/* U and V input is not affected, */
  182114. +/* the update is done by new calculation according to */
  182115. +/* vertical_offset and horizontal_offset */
  182116. +static inline void _ipu_ch_offset_update(struct ipu_soc *ipu,
  182117. + int ch,
  182118. + uint32_t pixel_fmt,
  182119. + uint32_t width,
  182120. + uint32_t height,
  182121. + uint32_t stride,
  182122. + uint32_t u,
  182123. + uint32_t v,
  182124. + uint32_t uv_stride,
  182125. + uint32_t vertical_offset,
  182126. + uint32_t horizontal_offset)
  182127. +{
  182128. + uint32_t u_offset = 0;
  182129. + uint32_t v_offset = 0;
  182130. + uint32_t old_offset = 0;
  182131. + uint32_t u_fix = 0;
  182132. + uint32_t v_fix = 0;
  182133. + int32_t sub_ch = 0;
  182134. +
  182135. + switch (pixel_fmt) {
  182136. + case IPU_PIX_FMT_GENERIC:
  182137. + case IPU_PIX_FMT_GENERIC_16:
  182138. + case IPU_PIX_FMT_GENERIC_32:
  182139. + case IPU_PIX_FMT_RGB565:
  182140. + case IPU_PIX_FMT_BGR24:
  182141. + case IPU_PIX_FMT_RGB24:
  182142. + case IPU_PIX_FMT_YUV444:
  182143. + case IPU_PIX_FMT_BGRA32:
  182144. + case IPU_PIX_FMT_BGR32:
  182145. + case IPU_PIX_FMT_RGBA32:
  182146. + case IPU_PIX_FMT_RGB32:
  182147. + case IPU_PIX_FMT_ABGR32:
  182148. + case IPU_PIX_FMT_UYVY:
  182149. + case IPU_PIX_FMT_YUYV:
  182150. + break;
  182151. +
  182152. + case IPU_PIX_FMT_YUV420P2:
  182153. + case IPU_PIX_FMT_YUV420P:
  182154. + if (uv_stride < stride / 2)
  182155. + uv_stride = stride / 2;
  182156. +
  182157. + u_offset = stride * (height - vertical_offset - 1) +
  182158. + (stride - horizontal_offset) +
  182159. + (uv_stride * vertical_offset / 2) +
  182160. + horizontal_offset / 2;
  182161. + v_offset = u_offset + (uv_stride * height / 2);
  182162. + u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
  182163. + (horizontal_offset / 2) -
  182164. + (stride * vertical_offset) - (horizontal_offset)) :
  182165. + u_offset;
  182166. + v_fix = v ? (v + (uv_stride * vertical_offset / 2) +
  182167. + (horizontal_offset / 2) -
  182168. + (stride * vertical_offset) - (horizontal_offset)) :
  182169. + v_offset;
  182170. +
  182171. + break;
  182172. + case IPU_PIX_FMT_YVU420P:
  182173. + if (uv_stride < stride / 2)
  182174. + uv_stride = stride / 2;
  182175. +
  182176. + v_offset = stride * (height - vertical_offset - 1) +
  182177. + (stride - horizontal_offset) +
  182178. + (uv_stride * vertical_offset / 2) +
  182179. + horizontal_offset / 2;
  182180. + u_offset = v_offset + (uv_stride * height / 2);
  182181. + u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
  182182. + (horizontal_offset / 2) -
  182183. + (stride * vertical_offset) - (horizontal_offset)) :
  182184. + u_offset;
  182185. + v_fix = v ? (v + (uv_stride * vertical_offset / 2) +
  182186. + (horizontal_offset / 2) -
  182187. + (stride * vertical_offset) - (horizontal_offset)) :
  182188. + v_offset;
  182189. +
  182190. + break;
  182191. + case IPU_PIX_FMT_YVU422P:
  182192. + if (uv_stride < stride / 2)
  182193. + uv_stride = stride / 2;
  182194. +
  182195. + v_offset = stride * (height - vertical_offset - 1) +
  182196. + (stride - horizontal_offset) +
  182197. + (uv_stride * vertical_offset) +
  182198. + horizontal_offset / 2;
  182199. + u_offset = v_offset + uv_stride * height;
  182200. + u_fix = u ? (u + (uv_stride * vertical_offset) +
  182201. + horizontal_offset / 2 -
  182202. + (stride * vertical_offset) - (horizontal_offset)) :
  182203. + u_offset;
  182204. + v_fix = v ? (v + (uv_stride * vertical_offset) +
  182205. + horizontal_offset / 2 -
  182206. + (stride * vertical_offset) - (horizontal_offset)) :
  182207. + v_offset;
  182208. + break;
  182209. + case IPU_PIX_FMT_YUV422P:
  182210. + if (uv_stride < stride / 2)
  182211. + uv_stride = stride / 2;
  182212. +
  182213. + u_offset = stride * (height - vertical_offset - 1) +
  182214. + (stride - horizontal_offset) +
  182215. + (uv_stride * vertical_offset) +
  182216. + horizontal_offset / 2;
  182217. + v_offset = u_offset + uv_stride * height;
  182218. + u_fix = u ? (u + (uv_stride * vertical_offset) +
  182219. + horizontal_offset / 2 -
  182220. + (stride * vertical_offset) - (horizontal_offset)) :
  182221. + u_offset;
  182222. + v_fix = v ? (v + (uv_stride * vertical_offset) +
  182223. + horizontal_offset / 2 -
  182224. + (stride * vertical_offset) - (horizontal_offset)) :
  182225. + v_offset;
  182226. + break;
  182227. +
  182228. + case IPU_PIX_FMT_YUV444P:
  182229. + uv_stride = stride;
  182230. + u_offset = stride * (height - vertical_offset - 1) +
  182231. + (stride - horizontal_offset) +
  182232. + (uv_stride * vertical_offset) +
  182233. + horizontal_offset;
  182234. + v_offset = u_offset + uv_stride * height;
  182235. + u_fix = u ? (u + (uv_stride * vertical_offset) +
  182236. + horizontal_offset -
  182237. + (stride * vertical_offset) -
  182238. + (horizontal_offset)) :
  182239. + u_offset;
  182240. + v_fix = v ? (v + (uv_stride * vertical_offset) +
  182241. + horizontal_offset -
  182242. + (stride * vertical_offset) -
  182243. + (horizontal_offset)) :
  182244. + v_offset;
  182245. + break;
  182246. + case IPU_PIX_FMT_NV12:
  182247. + uv_stride = stride;
  182248. + u_offset = stride * (height - vertical_offset - 1) +
  182249. + (stride - horizontal_offset) +
  182250. + (uv_stride * vertical_offset / 2) +
  182251. + horizontal_offset;
  182252. + u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
  182253. + horizontal_offset -
  182254. + (stride * vertical_offset) - (horizontal_offset)) :
  182255. + u_offset;
  182256. +
  182257. + break;
  182258. + default:
  182259. + dev_err(ipu->dev, "mxc ipu: unimplemented pixel format\n");
  182260. + break;
  182261. + }
  182262. +
  182263. +
  182264. +
  182265. + if (u_fix > u_offset)
  182266. + u_offset = u_fix;
  182267. +
  182268. + if (v_fix > v_offset)
  182269. + v_offset = v_fix;
  182270. +
  182271. + /* UBO and VBO are 22-bit and 8-byte aligned */
  182272. + if (u_offset/8 > 0x3fffff)
  182273. + dev_warn(ipu->dev,
  182274. + "IDMAC%d's U offset exceeds IPU limitation\n", ch);
  182275. + if (v_offset/8 > 0x3fffff)
  182276. + dev_warn(ipu->dev,
  182277. + "IDMAC%d's V offset exceeds IPU limitation\n", ch);
  182278. + if (u_offset%8)
  182279. + dev_warn(ipu->dev,
  182280. + "IDMAC%d's U offset is not 8-byte aligned\n", ch);
  182281. + if (v_offset%8)
  182282. + dev_warn(ipu->dev,
  182283. + "IDMAC%d's V offset is not 8-byte aligned\n", ch);
  182284. +
  182285. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22);
  182286. + if (old_offset != u_offset / 8)
  182287. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22, u_offset / 8);
  182288. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22);
  182289. + if (old_offset != v_offset / 8)
  182290. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22, v_offset / 8);
  182291. +
  182292. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182293. + if (sub_ch <= 0)
  182294. + return;
  182295. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22);
  182296. + if (old_offset != u_offset / 8)
  182297. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22, u_offset / 8);
  182298. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22);
  182299. + if (old_offset != v_offset / 8)
  182300. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22, v_offset / 8);
  182301. +};
  182302. +
  182303. +static inline void _ipu_ch_params_set_alpha_width(struct ipu_soc *ipu, uint32_t ch, int alpha_width)
  182304. +{
  182305. + int32_t sub_ch = 0;
  182306. +
  182307. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch), 1, 125, 3, alpha_width - 1);
  182308. +
  182309. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182310. + if (sub_ch <= 0)
  182311. + return;
  182312. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 125, 3, alpha_width - 1);
  182313. +};
  182314. +
  182315. +static inline void _ipu_ch_param_set_bandmode(struct ipu_soc *ipu,
  182316. + uint32_t ch, uint32_t band_height)
  182317. +{
  182318. + int32_t sub_ch = 0;
  182319. +
  182320. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch),
  182321. + 0, 114, 3, band_height - 1);
  182322. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  182323. + if (sub_ch <= 0)
  182324. + return;
  182325. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch),
  182326. + 0, 114, 3, band_height - 1);
  182327. +
  182328. + dev_dbg(ipu->dev, "BNDM 0x%x, ",
  182329. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 114, 3));
  182330. +}
  182331. +
  182332. +/*
  182333. + * The IPUv3 IDMAC has a bug to read 32bpp pixels from a graphics plane
  182334. + * whose alpha component is at the most significant 8 bits. The bug only
  182335. + * impacts on cases in which the relevant separate alpha channel is enabled.
  182336. + *
  182337. + * Return true on bad alpha component position, otherwise, return false.
  182338. + */
  182339. +static inline bool _ipu_ch_param_bad_alpha_pos(uint32_t pixel_fmt)
  182340. +{
  182341. + switch (pixel_fmt) {
  182342. + case IPU_PIX_FMT_BGRA32:
  182343. + case IPU_PIX_FMT_BGR32:
  182344. + case IPU_PIX_FMT_RGBA32:
  182345. + case IPU_PIX_FMT_RGB32:
  182346. + return true;
  182347. + }
  182348. +
  182349. + return false;
  182350. +}
  182351. +#endif
  182352. diff -Nur linux-3.14.14/drivers/mxc/ipu3/ipu_pixel_clk.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_pixel_clk.c
  182353. --- linux-3.14.14/drivers/mxc/ipu3/ipu_pixel_clk.c 1969-12-31 18:00:00.000000000 -0600
  182354. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_pixel_clk.c 2014-12-08 00:31:53.476418001 -0600
  182355. @@ -0,0 +1,317 @@
  182356. +/*
  182357. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  182358. + */
  182359. +
  182360. +/*
  182361. + * The code contained herein is licensed under the GNU General Public
  182362. + * License. You may obtain a copy of the GNU General Public License
  182363. + * Version 2 or later at the following locations:
  182364. + *
  182365. + * http://www.opensource.org/licenses/gpl-license.html
  182366. + * http://www.gnu.org/copyleft/gpl.html
  182367. + */
  182368. +
  182369. +/*!
  182370. + * @file ipu_pixel_clk.c
  182371. + *
  182372. + * @brief IPU pixel clock implementation
  182373. + *
  182374. + * @ingroup IPU
  182375. + */
  182376. +
  182377. +#include <linux/clk-provider.h>
  182378. +#include <linux/err.h>
  182379. +#include <linux/io.h>
  182380. +#include <linux/ipu-v3.h>
  182381. +#include <linux/module.h>
  182382. +#include <linux/slab.h>
  182383. +#include <linux/string.h>
  182384. +
  182385. +#include "ipu_prv.h"
  182386. +#include "ipu_regs.h"
  182387. +
  182388. + /*
  182389. + * muxd clock implementation
  182390. + */
  182391. +struct clk_di_mux {
  182392. + struct clk_hw hw;
  182393. + u8 ipu_id;
  182394. + u8 di_id;
  182395. + u8 flags;
  182396. + u8 index;
  182397. +};
  182398. +#define to_clk_di_mux(_hw) container_of(_hw, struct clk_di_mux, hw)
  182399. +
  182400. +static int _ipu_pixel_clk_set_parent(struct clk_hw *hw, u8 index)
  182401. +{
  182402. + struct clk_di_mux *mux = to_clk_di_mux(hw);
  182403. + struct ipu_soc *ipu = ipu_get_soc(mux->ipu_id);
  182404. + u32 di_gen;
  182405. +
  182406. + di_gen = ipu_di_read(ipu, mux->di_id, DI_GENERAL);
  182407. + if (index == 0)
  182408. + /* ipu1_clk or ipu2_clk internal clk */
  182409. + di_gen &= ~DI_GEN_DI_CLK_EXT;
  182410. + else
  182411. + di_gen |= DI_GEN_DI_CLK_EXT;
  182412. +
  182413. + ipu_di_write(ipu, mux->di_id, di_gen, DI_GENERAL);
  182414. + mux->index = index;
  182415. + pr_debug("ipu_pixel_clk: di_clk_ext:0x%x, di_gen reg:0x%x.\n",
  182416. + !(di_gen & DI_GEN_DI_CLK_EXT), di_gen);
  182417. + return 0;
  182418. +}
  182419. +
  182420. +static u8 _ipu_pixel_clk_get_parent(struct clk_hw *hw)
  182421. +{
  182422. + struct clk_di_mux *mux = to_clk_di_mux(hw);
  182423. +
  182424. + return mux->index;
  182425. +}
  182426. +
  182427. +const struct clk_ops clk_mux_di_ops = {
  182428. + .get_parent = _ipu_pixel_clk_get_parent,
  182429. + .set_parent = _ipu_pixel_clk_set_parent,
  182430. +};
  182431. +
  182432. +struct clk *clk_register_mux_pix_clk(struct device *dev, const char *name,
  182433. + const char **parent_names, u8 num_parents, unsigned long flags,
  182434. + u8 ipu_id, u8 di_id, u8 clk_mux_flags)
  182435. +{
  182436. + struct clk_di_mux *mux;
  182437. + struct clk *clk;
  182438. + struct clk_init_data init;
  182439. +
  182440. + mux = kzalloc(sizeof(struct clk_di_mux), GFP_KERNEL);
  182441. + if (!mux)
  182442. + return ERR_PTR(-ENOMEM);
  182443. +
  182444. + init.name = name;
  182445. + init.ops = &clk_mux_di_ops;
  182446. + init.flags = flags;
  182447. + init.parent_names = parent_names;
  182448. + init.num_parents = num_parents;
  182449. +
  182450. + mux->ipu_id = ipu_id;
  182451. + mux->di_id = di_id;
  182452. + mux->flags = clk_mux_flags | CLK_SET_RATE_PARENT;
  182453. + mux->hw.init = &init;
  182454. +
  182455. + clk = clk_register(dev, &mux->hw);
  182456. + if (IS_ERR(clk))
  182457. + kfree(mux);
  182458. +
  182459. + return clk;
  182460. +}
  182461. +
  182462. +/*
  182463. + * Gated clock implementation
  182464. + */
  182465. +struct clk_di_div {
  182466. + struct clk_hw hw;
  182467. + u8 ipu_id;
  182468. + u8 di_id;
  182469. + u8 flags;
  182470. +};
  182471. +#define to_clk_di_div(_hw) container_of(_hw, struct clk_di_div, hw)
  182472. +
  182473. +static unsigned long _ipu_pixel_clk_div_recalc_rate(struct clk_hw *hw,
  182474. + unsigned long parent_rate)
  182475. +{
  182476. + struct clk_di_div *di_div = to_clk_di_div(hw);
  182477. + struct ipu_soc *ipu = ipu_get_soc(di_div->ipu_id);
  182478. + u32 div;
  182479. + u64 final_rate = (unsigned long long)parent_rate * 16;
  182480. +
  182481. + _ipu_get(ipu);
  182482. + div = ipu_di_read(ipu, di_div->di_id, DI_BS_CLKGEN0);
  182483. + _ipu_put(ipu);
  182484. + pr_debug("ipu_di%d read BS_CLKGEN0 div:%d, final_rate:%lld, prate:%ld\n",
  182485. + di_div->di_id, div, final_rate, parent_rate);
  182486. +
  182487. + if (div == 0)
  182488. + return 0;
  182489. + do_div(final_rate, div);
  182490. +
  182491. + return (unsigned long)final_rate;
  182492. +}
  182493. +
  182494. +static long _ipu_pixel_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
  182495. + unsigned long *parent_clk_rate)
  182496. +{
  182497. + u64 div, final_rate;
  182498. + u32 remainder;
  182499. + u64 parent_rate = (unsigned long long)(*parent_clk_rate) * 16;
  182500. +
  182501. + /*
  182502. + * Calculate divider
  182503. + * Fractional part is 4 bits,
  182504. + * so simply multiply by 2^4 to get fractional part.
  182505. + */
  182506. + div = parent_rate;
  182507. + remainder = do_div(div, rate);
  182508. + /* Round the divider value */
  182509. + if (remainder > (rate/2))
  182510. + div++;
  182511. + if (div < 0x10) /* Min DI disp clock divider is 1 */
  182512. + div = 0x10;
  182513. + if (div & ~0xFEF)
  182514. + div &= 0xFF8;
  182515. + else {
  182516. + /* Round up divider if it gets us closer to desired pix clk */
  182517. + if ((div & 0xC) == 0xC) {
  182518. + div += 0x10;
  182519. + div &= ~0xF;
  182520. + }
  182521. + }
  182522. + final_rate = parent_rate;
  182523. + do_div(final_rate, div);
  182524. +
  182525. + return final_rate;
  182526. +}
  182527. +
  182528. +static int _ipu_pixel_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
  182529. + unsigned long parent_clk_rate)
  182530. +{
  182531. + struct clk_di_div *di_div = to_clk_di_div(hw);
  182532. + struct ipu_soc *ipu = ipu_get_soc(di_div->ipu_id);
  182533. + u64 div, parent_rate;
  182534. + u32 remainder;
  182535. +
  182536. + parent_rate = (unsigned long long)parent_clk_rate * 16;
  182537. + div = parent_rate;
  182538. + remainder = do_div(div, rate);
  182539. + /* Round the divider value */
  182540. + if (remainder > (rate/2))
  182541. + div++;
  182542. +
  182543. + /* Round up divider if it gets us closer to desired pix clk */
  182544. + if ((div & 0xC) == 0xC) {
  182545. + div += 0x10;
  182546. + div &= ~0xF;
  182547. + }
  182548. + if (div > 0x1000)
  182549. + pr_err("Overflow, di:%d, DI_BS_CLKGEN0 div:0x%x\n",
  182550. + di_div->di_id, (u32)div);
  182551. + _ipu_get(ipu);
  182552. + ipu_di_write(ipu, di_div->di_id, (u32)div, DI_BS_CLKGEN0);
  182553. +
  182554. + /* Setup pixel clock timing */
  182555. + /* FIXME: needs to be more flexible */
  182556. + /* Down time is half of period */
  182557. + ipu_di_write(ipu, di_div->di_id, ((u32)div / 16) << 16, DI_BS_CLKGEN1);
  182558. + _ipu_put(ipu);
  182559. +
  182560. + return 0;
  182561. +}
  182562. +
  182563. +static struct clk_ops clk_div_ops = {
  182564. + .recalc_rate = _ipu_pixel_clk_div_recalc_rate,
  182565. + .round_rate = _ipu_pixel_clk_div_round_rate,
  182566. + .set_rate = _ipu_pixel_clk_div_set_rate,
  182567. +};
  182568. +
  182569. +struct clk *clk_register_div_pix_clk(struct device *dev, const char *name,
  182570. + const char *parent_name, unsigned long flags,
  182571. + u8 ipu_id, u8 di_id, u8 clk_div_flags)
  182572. +{
  182573. + struct clk_di_div *di_div;
  182574. + struct clk *clk;
  182575. + struct clk_init_data init;
  182576. +
  182577. + di_div = kzalloc(sizeof(struct clk_di_div), GFP_KERNEL);
  182578. + if (!di_div)
  182579. + return ERR_PTR(-ENOMEM);
  182580. +
  182581. + /* struct clk_di_div assignments */
  182582. + di_div->ipu_id = ipu_id;
  182583. + di_div->di_id = di_id;
  182584. + di_div->flags = clk_div_flags;
  182585. +
  182586. + init.name = name;
  182587. + init.ops = &clk_div_ops;
  182588. + init.flags = flags | CLK_SET_RATE_PARENT;
  182589. + init.parent_names = parent_name ? &parent_name : NULL;
  182590. + init.num_parents = parent_name ? 1 : 0;
  182591. +
  182592. + di_div->hw.init = &init;
  182593. +
  182594. + clk = clk_register(dev, &di_div->hw);
  182595. + if (IS_ERR(clk))
  182596. + kfree(clk);
  182597. +
  182598. + return clk;
  182599. +}
  182600. +
  182601. +/*
  182602. + * Gated clock implementation
  182603. + */
  182604. +struct clk_di_gate {
  182605. + struct clk_hw hw;
  182606. + u8 ipu_id;
  182607. + u8 di_id;
  182608. + u8 flags;
  182609. +};
  182610. +#define to_clk_di_gate(_hw) container_of(_hw, struct clk_di_gate, hw)
  182611. +
  182612. +static int _ipu_pixel_clk_enable(struct clk_hw *hw)
  182613. +{
  182614. + struct clk_di_gate *gate = to_clk_di_gate(hw);
  182615. + struct ipu_soc *ipu = ipu_get_soc(gate->ipu_id);
  182616. + u32 disp_gen;
  182617. +
  182618. + disp_gen = ipu_cm_read(ipu, IPU_DISP_GEN);
  182619. + disp_gen |= gate->di_id ? DI1_COUNTER_RELEASE : DI0_COUNTER_RELEASE;
  182620. + ipu_cm_write(ipu, disp_gen, IPU_DISP_GEN);
  182621. +
  182622. + return 0;
  182623. +}
  182624. +
  182625. +static void _ipu_pixel_clk_disable(struct clk_hw *hw)
  182626. +{
  182627. + struct clk_di_gate *gate = to_clk_di_gate(hw);
  182628. + struct ipu_soc *ipu = ipu_get_soc(gate->ipu_id);
  182629. + u32 disp_gen;
  182630. +
  182631. + disp_gen = ipu_cm_read(ipu, IPU_DISP_GEN);
  182632. + disp_gen &= gate->di_id ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE;
  182633. + ipu_cm_write(ipu, disp_gen, IPU_DISP_GEN);
  182634. +
  182635. +}
  182636. +
  182637. +
  182638. +static struct clk_ops clk_gate_di_ops = {
  182639. + .enable = _ipu_pixel_clk_enable,
  182640. + .disable = _ipu_pixel_clk_disable,
  182641. +};
  182642. +
  182643. +struct clk *clk_register_gate_pix_clk(struct device *dev, const char *name,
  182644. + const char *parent_name, unsigned long flags,
  182645. + u8 ipu_id, u8 di_id, u8 clk_gate_flags)
  182646. +{
  182647. + struct clk_di_gate *gate;
  182648. + struct clk *clk;
  182649. + struct clk_init_data init;
  182650. +
  182651. + gate = kzalloc(sizeof(struct clk_di_gate), GFP_KERNEL);
  182652. + if (!gate)
  182653. + return ERR_PTR(-ENOMEM);
  182654. +
  182655. + gate->ipu_id = ipu_id;
  182656. + gate->di_id = di_id;
  182657. + gate->flags = clk_gate_flags;
  182658. +
  182659. + init.name = name;
  182660. + init.ops = &clk_gate_di_ops;
  182661. + init.flags = flags | CLK_SET_RATE_PARENT;
  182662. + init.parent_names = parent_name ? &parent_name : NULL;
  182663. + init.num_parents = parent_name ? 1 : 0;
  182664. +
  182665. + gate->hw.init = &init;
  182666. +
  182667. + clk = clk_register(dev, &gate->hw);
  182668. + if (IS_ERR(clk))
  182669. + kfree(clk);
  182670. +
  182671. + return clk;
  182672. +}
  182673. diff -Nur linux-3.14.14/drivers/mxc/ipu3/ipu_prv.h linux-imx6-3.14/drivers/mxc/ipu3/ipu_prv.h
  182674. --- linux-3.14.14/drivers/mxc/ipu3/ipu_prv.h 1969-12-31 18:00:00.000000000 -0600
  182675. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_prv.h 2014-12-08 00:31:53.476418001 -0600
  182676. @@ -0,0 +1,356 @@
  182677. +/*
  182678. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  182679. + */
  182680. +
  182681. +/*
  182682. + * The code contained herein is licensed under the GNU General Public
  182683. + * License. You may obtain a copy of the GNU General Public License
  182684. + * Version 2 or later at the following locations:
  182685. + *
  182686. + * http://www.opensource.org/licenses/gpl-license.html
  182687. + * http://www.gnu.org/copyleft/gpl.html
  182688. + */
  182689. +#ifndef __INCLUDE_IPU_PRV_H__
  182690. +#define __INCLUDE_IPU_PRV_H__
  182691. +
  182692. +#include <linux/clkdev.h>
  182693. +#include <linux/device.h>
  182694. +#include <linux/fsl_devices.h>
  182695. +#include <linux/interrupt.h>
  182696. +#include <linux/types.h>
  182697. +
  182698. +#define MXC_IPU_MAX_NUM 2
  182699. +#define MXC_DI_NUM_PER_IPU 2
  182700. +
  182701. +/* Globals */
  182702. +extern int dmfc_type_setup;
  182703. +
  182704. +#define IDMA_CHAN_INVALID 0xFF
  182705. +#define HIGH_RESOLUTION_WIDTH 1024
  182706. +
  182707. +struct ipu_irq_node {
  182708. + irqreturn_t(*handler) (int, void *); /*!< the ISR */
  182709. + const char *name; /*!< device associated with the interrupt */
  182710. + void *dev_id; /*!< some unique information for the ISR */
  182711. + __u32 flags; /*!< not used */
  182712. +};
  182713. +
  182714. +enum csc_type_t {
  182715. + RGB2YUV = 0,
  182716. + YUV2RGB,
  182717. + RGB2RGB,
  182718. + YUV2YUV,
  182719. + CSC_NONE,
  182720. + CSC_NUM
  182721. +};
  182722. +
  182723. +enum imx_ipu_type {
  182724. + IMX6Q_IPU,
  182725. +};
  182726. +
  182727. +struct ipu_pltfm_data {
  182728. + u32 id;
  182729. + u32 devtype;
  182730. + int (*init) (int);
  182731. + void (*pg) (int);
  182732. +
  182733. + /*
  182734. + * Bypass reset to avoid display channel being
  182735. + * stopped by probe since it may starts to work
  182736. + * in bootloader.
  182737. + */
  182738. + bool bypass_reset;
  182739. +};
  182740. +
  182741. +struct ipu_soc {
  182742. + bool online;
  182743. + struct ipu_pltfm_data *pdata;
  182744. +
  182745. + /*clk*/
  182746. + struct clk *ipu_clk;
  182747. + struct clk *di_clk[2];
  182748. + struct clk *di_clk_sel[2];
  182749. + struct clk *pixel_clk[2];
  182750. + struct clk *pixel_clk_sel[2];
  182751. + struct clk *csi_clk[2];
  182752. +
  182753. + /*irq*/
  182754. + int irq_sync;
  182755. + int irq_err;
  182756. + struct ipu_irq_node irq_list[IPU_IRQ_COUNT];
  182757. +
  182758. + /*reg*/
  182759. + void __iomem *cm_reg;
  182760. + void __iomem *idmac_reg;
  182761. + void __iomem *dp_reg;
  182762. + void __iomem *ic_reg;
  182763. + void __iomem *dc_reg;
  182764. + void __iomem *dc_tmpl_reg;
  182765. + void __iomem *dmfc_reg;
  182766. + void __iomem *di_reg[2];
  182767. + void __iomem *smfc_reg;
  182768. + void __iomem *csi_reg[2];
  182769. + void __iomem *cpmem_base;
  182770. + void __iomem *tpmem_base;
  182771. + void __iomem *disp_base[2];
  182772. + void __iomem *vdi_reg;
  182773. +
  182774. + struct device *dev;
  182775. +
  182776. + ipu_channel_t csi_channel[2];
  182777. + ipu_channel_t using_ic_dirct_ch;
  182778. + unsigned char dc_di_assignment[10];
  182779. + bool sec_chan_en[24];
  182780. + bool thrd_chan_en[24];
  182781. + bool chan_is_interlaced[52];
  182782. + uint32_t channel_init_mask;
  182783. + uint32_t channel_enable_mask;
  182784. +
  182785. + /*use count*/
  182786. + int dc_use_count;
  182787. + int dp_use_count;
  182788. + int dmfc_use_count;
  182789. + int smfc_use_count;
  182790. + int ic_use_count;
  182791. + int rot_use_count;
  182792. + int vdi_use_count;
  182793. + int di_use_count[2];
  182794. + int csi_use_count[2];
  182795. +
  182796. + struct mutex mutex_lock;
  182797. + spinlock_t int_reg_spin_lock;
  182798. + spinlock_t rdy_reg_spin_lock;
  182799. +
  182800. + int dmfc_size_28;
  182801. + int dmfc_size_29;
  182802. + int dmfc_size_24;
  182803. + int dmfc_size_27;
  182804. + int dmfc_size_23;
  182805. +
  182806. + enum csc_type_t fg_csc_type;
  182807. + enum csc_type_t bg_csc_type;
  182808. + bool color_key_4rgb;
  182809. + bool dc_swap;
  182810. + struct completion dc_comp;
  182811. + struct completion csi_comp;
  182812. +
  182813. + struct rot_mem {
  182814. + void *vaddr;
  182815. + dma_addr_t paddr;
  182816. + int size;
  182817. + } rot_dma[2];
  182818. +
  182819. + int vdoa_en;
  182820. + struct task_struct *thread[2];
  182821. +
  182822. +};
  182823. +
  182824. +struct ipu_channel {
  182825. + u8 video_in_dma;
  182826. + u8 alpha_in_dma;
  182827. + u8 graph_in_dma;
  182828. + u8 out_dma;
  182829. +};
  182830. +
  182831. +enum ipu_dmfc_type {
  182832. + DMFC_NORMAL = 0,
  182833. + DMFC_HIGH_RESOLUTION_DC,
  182834. + DMFC_HIGH_RESOLUTION_DP,
  182835. + DMFC_HIGH_RESOLUTION_ONLY_DP,
  182836. +};
  182837. +
  182838. +static inline u32 ipu_cm_read(struct ipu_soc *ipu, unsigned offset)
  182839. +{
  182840. + return readl(ipu->cm_reg + offset);
  182841. +}
  182842. +
  182843. +static inline void ipu_cm_write(struct ipu_soc *ipu,
  182844. + u32 value, unsigned offset)
  182845. +{
  182846. + writel(value, ipu->cm_reg + offset);
  182847. +}
  182848. +
  182849. +static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset)
  182850. +{
  182851. + return readl(ipu->idmac_reg + offset);
  182852. +}
  182853. +
  182854. +static inline void ipu_idmac_write(struct ipu_soc *ipu,
  182855. + u32 value, unsigned offset)
  182856. +{
  182857. + writel(value, ipu->idmac_reg + offset);
  182858. +}
  182859. +
  182860. +static inline u32 ipu_dc_read(struct ipu_soc *ipu, unsigned offset)
  182861. +{
  182862. + return readl(ipu->dc_reg + offset);
  182863. +}
  182864. +
  182865. +static inline void ipu_dc_write(struct ipu_soc *ipu,
  182866. + u32 value, unsigned offset)
  182867. +{
  182868. + writel(value, ipu->dc_reg + offset);
  182869. +}
  182870. +
  182871. +static inline u32 ipu_dc_tmpl_read(struct ipu_soc *ipu, unsigned offset)
  182872. +{
  182873. + return readl(ipu->dc_tmpl_reg + offset);
  182874. +}
  182875. +
  182876. +static inline void ipu_dc_tmpl_write(struct ipu_soc *ipu,
  182877. + u32 value, unsigned offset)
  182878. +{
  182879. + writel(value, ipu->dc_tmpl_reg + offset);
  182880. +}
  182881. +
  182882. +static inline u32 ipu_dmfc_read(struct ipu_soc *ipu, unsigned offset)
  182883. +{
  182884. + return readl(ipu->dmfc_reg + offset);
  182885. +}
  182886. +
  182887. +static inline void ipu_dmfc_write(struct ipu_soc *ipu,
  182888. + u32 value, unsigned offset)
  182889. +{
  182890. + writel(value, ipu->dmfc_reg + offset);
  182891. +}
  182892. +
  182893. +static inline u32 ipu_dp_read(struct ipu_soc *ipu, unsigned offset)
  182894. +{
  182895. + return readl(ipu->dp_reg + offset);
  182896. +}
  182897. +
  182898. +static inline void ipu_dp_write(struct ipu_soc *ipu,
  182899. + u32 value, unsigned offset)
  182900. +{
  182901. + writel(value, ipu->dp_reg + offset);
  182902. +}
  182903. +
  182904. +static inline u32 ipu_di_read(struct ipu_soc *ipu, int di, unsigned offset)
  182905. +{
  182906. + return readl(ipu->di_reg[di] + offset);
  182907. +}
  182908. +
  182909. +static inline void ipu_di_write(struct ipu_soc *ipu, int di,
  182910. + u32 value, unsigned offset)
  182911. +{
  182912. + writel(value, ipu->di_reg[di] + offset);
  182913. +}
  182914. +
  182915. +static inline u32 ipu_csi_read(struct ipu_soc *ipu, int csi, unsigned offset)
  182916. +{
  182917. + return readl(ipu->csi_reg[csi] + offset);
  182918. +}
  182919. +
  182920. +static inline void ipu_csi_write(struct ipu_soc *ipu, int csi,
  182921. + u32 value, unsigned offset)
  182922. +{
  182923. + writel(value, ipu->csi_reg[csi] + offset);
  182924. +}
  182925. +
  182926. +static inline u32 ipu_smfc_read(struct ipu_soc *ipu, unsigned offset)
  182927. +{
  182928. + return readl(ipu->smfc_reg + offset);
  182929. +}
  182930. +
  182931. +static inline void ipu_smfc_write(struct ipu_soc *ipu,
  182932. + u32 value, unsigned offset)
  182933. +{
  182934. + writel(value, ipu->smfc_reg + offset);
  182935. +}
  182936. +
  182937. +static inline u32 ipu_vdi_read(struct ipu_soc *ipu, unsigned offset)
  182938. +{
  182939. + return readl(ipu->vdi_reg + offset);
  182940. +}
  182941. +
  182942. +static inline void ipu_vdi_write(struct ipu_soc *ipu,
  182943. + u32 value, unsigned offset)
  182944. +{
  182945. + writel(value, ipu->vdi_reg + offset);
  182946. +}
  182947. +
  182948. +static inline u32 ipu_ic_read(struct ipu_soc *ipu, unsigned offset)
  182949. +{
  182950. + return readl(ipu->ic_reg + offset);
  182951. +}
  182952. +
  182953. +static inline void ipu_ic_write(struct ipu_soc *ipu,
  182954. + u32 value, unsigned offset)
  182955. +{
  182956. + writel(value, ipu->ic_reg + offset);
  182957. +}
  182958. +
  182959. +int register_ipu_device(struct ipu_soc *ipu, int id);
  182960. +void unregister_ipu_device(struct ipu_soc *ipu, int id);
  182961. +ipu_color_space_t format_to_colorspace(uint32_t fmt);
  182962. +bool ipu_pixel_format_has_alpha(uint32_t fmt);
  182963. +
  182964. +void ipu_dump_registers(struct ipu_soc *ipu);
  182965. +
  182966. +uint32_t _ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel);
  182967. +
  182968. +void ipu_disp_init(struct ipu_soc *ipu);
  182969. +void _ipu_init_dc_mappings(struct ipu_soc *ipu);
  182970. +int _ipu_dp_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t in_pixel_fmt,
  182971. + uint32_t out_pixel_fmt);
  182972. +void _ipu_dp_uninit(struct ipu_soc *ipu, ipu_channel_t channel);
  182973. +void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt);
  182974. +void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan);
  182975. +void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel);
  182976. +void _ipu_dp_dc_disable(struct ipu_soc *ipu, ipu_channel_t channel, bool swap);
  182977. +void _ipu_dmfc_init(struct ipu_soc *ipu, int dmfc_type, int first);
  182978. +void _ipu_dmfc_set_wait4eot(struct ipu_soc *ipu, int dma_chan, int width);
  182979. +void _ipu_dmfc_set_burst_size(struct ipu_soc *ipu, int dma_chan, int burst_size);
  182980. +int _ipu_disp_chan_is_interlaced(struct ipu_soc *ipu, ipu_channel_t channel);
  182981. +
  182982. +void _ipu_ic_enable_task(struct ipu_soc *ipu, ipu_channel_t channel);
  182983. +void _ipu_ic_disable_task(struct ipu_soc *ipu, ipu_channel_t channel);
  182984. +int _ipu_ic_init_prpvf(struct ipu_soc *ipu, ipu_channel_params_t *params,
  182985. + bool src_is_csi);
  182986. +void _ipu_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params);
  182987. +void _ipu_vdi_uninit(struct ipu_soc *ipu);
  182988. +void _ipu_ic_uninit_prpvf(struct ipu_soc *ipu);
  182989. +void _ipu_ic_init_rotate_vf(struct ipu_soc *ipu, ipu_channel_params_t *params);
  182990. +void _ipu_ic_uninit_rotate_vf(struct ipu_soc *ipu);
  182991. +void _ipu_ic_init_csi(struct ipu_soc *ipu, ipu_channel_params_t *params);
  182992. +void _ipu_ic_uninit_csi(struct ipu_soc *ipu);
  182993. +int _ipu_ic_init_prpenc(struct ipu_soc *ipu, ipu_channel_params_t *params,
  182994. + bool src_is_csi);
  182995. +void _ipu_ic_uninit_prpenc(struct ipu_soc *ipu);
  182996. +void _ipu_ic_init_rotate_enc(struct ipu_soc *ipu, ipu_channel_params_t *params);
  182997. +void _ipu_ic_uninit_rotate_enc(struct ipu_soc *ipu);
  182998. +int _ipu_ic_init_pp(struct ipu_soc *ipu, ipu_channel_params_t *params);
  182999. +void _ipu_ic_uninit_pp(struct ipu_soc *ipu);
  183000. +void _ipu_ic_init_rotate_pp(struct ipu_soc *ipu, ipu_channel_params_t *params);
  183001. +void _ipu_ic_uninit_rotate_pp(struct ipu_soc *ipu);
  183002. +int _ipu_ic_idma_init(struct ipu_soc *ipu, int dma_chan, uint16_t width, uint16_t height,
  183003. + int burst_size, ipu_rotate_mode_t rot);
  183004. +void _ipu_vdi_toggle_top_field_man(struct ipu_soc *ipu);
  183005. +int _ipu_csi_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t csi);
  183006. +int _ipu_csi_set_mipi_di(struct ipu_soc *ipu, uint32_t num, uint32_t di_val, uint32_t csi);
  183007. +void ipu_csi_set_test_generator(struct ipu_soc *ipu, bool active, uint32_t r_value,
  183008. + uint32_t g_value, uint32_t b_value,
  183009. + uint32_t pix_clk, uint32_t csi);
  183010. +void _ipu_csi_ccir_err_detection_enable(struct ipu_soc *ipu, uint32_t csi);
  183011. +void _ipu_csi_ccir_err_detection_disable(struct ipu_soc *ipu, uint32_t csi);
  183012. +void _ipu_csi_wait4eof(struct ipu_soc *ipu, ipu_channel_t channel);
  183013. +void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi);
  183014. +void _ipu_smfc_set_burst_size(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t bs);
  183015. +void _ipu_dp_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]);
  183016. +int32_t _ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  183017. + int16_t x_pos, int16_t y_pos);
  183018. +int32_t _ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  183019. + int16_t *x_pos, int16_t *y_pos);
  183020. +void _ipu_get(struct ipu_soc *ipu);
  183021. +void _ipu_put(struct ipu_soc *ipu);
  183022. +
  183023. +struct clk *clk_register_mux_pix_clk(struct device *dev, const char *name,
  183024. + const char **parent_names, u8 num_parents, unsigned long flags,
  183025. + u8 ipu_id, u8 di_id, u8 clk_mux_flags);
  183026. +struct clk *clk_register_div_pix_clk(struct device *dev, const char *name,
  183027. + const char *parent_name, unsigned long flags,
  183028. + u8 ipu_id, u8 di_id, u8 clk_div_flags);
  183029. +struct clk *clk_register_gate_pix_clk(struct device *dev, const char *name,
  183030. + const char *parent_name, unsigned long flags,
  183031. + u8 ipu_id, u8 di_id, u8 clk_gate_flags);
  183032. +#endif /* __INCLUDE_IPU_PRV_H__ */
  183033. diff -Nur linux-3.14.14/drivers/mxc/ipu3/ipu_regs.h linux-imx6-3.14/drivers/mxc/ipu3/ipu_regs.h
  183034. --- linux-3.14.14/drivers/mxc/ipu3/ipu_regs.h 1969-12-31 18:00:00.000000000 -0600
  183035. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_regs.h 2014-12-08 00:31:53.476418001 -0600
  183036. @@ -0,0 +1,743 @@
  183037. +/*
  183038. + * Copyright (C) 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  183039. + */
  183040. +
  183041. +/*
  183042. + * The code contained herein is licensed under the GNU General Public
  183043. + * License. You may obtain a copy of the GNU General Public License
  183044. + * Version 2 or later at the following locations:
  183045. + *
  183046. + * http://www.opensource.org/licenses/gpl-license.html
  183047. + * http://www.gnu.org/copyleft/gpl.html
  183048. + */
  183049. +
  183050. +/*
  183051. + * @file ipu_regs.h
  183052. + *
  183053. + * @brief IPU Register definitions
  183054. + *
  183055. + * @ingroup IPU
  183056. + */
  183057. +#ifndef __IPU_REGS_INCLUDED__
  183058. +#define __IPU_REGS_INCLUDED__
  183059. +
  183060. +enum imx_ipu_rev {
  183061. + IPU_V3DEX = 2,
  183062. + IPU_V3M,
  183063. + IPU_V3H,
  183064. +};
  183065. +
  183066. +/*
  183067. + * hw_rev 2: IPUV3DEX
  183068. + * hw_rev 3: IPUV3M
  183069. + * hw_rev 4: IPUV3H
  183070. + */
  183071. +extern int g_ipu_hw_rev;
  183072. +
  183073. +#define IPU_MAX_VDI_IN_WIDTH ({g_ipu_hw_rev >= 3 ? \
  183074. + (968) : \
  183075. + (720); })
  183076. +#define IPU_DISP0_BASE 0x00000000
  183077. +#define IPU_MCU_T_DEFAULT 8
  183078. +#define IPU_DISP1_BASE ({g_ipu_hw_rev < 4 ? \
  183079. + (IPU_MCU_T_DEFAULT << 25) : \
  183080. + (0x00000000); })
  183081. +#define IPUV3DEX_REG_BASE 0x1E000000
  183082. +#define IPUV3M_REG_BASE 0x06000000
  183083. +#define IPUV3H_REG_BASE 0x00200000
  183084. +
  183085. +#define IPU_CM_REG_BASE 0x00000000
  183086. +#define IPU_IDMAC_REG_BASE 0x00008000
  183087. +#define IPU_ISP_REG_BASE 0x00010000
  183088. +#define IPU_DP_REG_BASE 0x00018000
  183089. +#define IPU_IC_REG_BASE 0x00020000
  183090. +#define IPU_IRT_REG_BASE 0x00028000
  183091. +#define IPU_CSI0_REG_BASE 0x00030000
  183092. +#define IPU_CSI1_REG_BASE 0x00038000
  183093. +#define IPU_DI0_REG_BASE 0x00040000
  183094. +#define IPU_DI1_REG_BASE 0x00048000
  183095. +#define IPU_SMFC_REG_BASE 0x00050000
  183096. +#define IPU_DC_REG_BASE 0x00058000
  183097. +#define IPU_DMFC_REG_BASE 0x00060000
  183098. +#define IPU_VDI_REG_BASE 0x00068000
  183099. +#define IPU_CPMEM_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  183100. + (0x00100000) : \
  183101. + (0x01000000); })
  183102. +#define IPU_LUT_REG_BASE 0x01020000
  183103. +#define IPU_SRM_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  183104. + (0x00140000) : \
  183105. + (0x01040000); })
  183106. +#define IPU_TPM_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  183107. + (0x00160000) : \
  183108. + (0x01060000); })
  183109. +#define IPU_DC_TMPL_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  183110. + (0x00180000) : \
  183111. + (0x01080000); })
  183112. +#define IPU_ISP_TBPR_REG_BASE 0x010C0000
  183113. +
  183114. +/* Register addresses */
  183115. +/* IPU Common registers */
  183116. +#define IPU_CM_REG(offset) (offset)
  183117. +
  183118. +#define IPU_CONF IPU_CM_REG(0)
  183119. +#define IPU_SRM_PRI1 IPU_CM_REG(0x00A0)
  183120. +#define IPU_SRM_PRI2 IPU_CM_REG(0x00A4)
  183121. +#define IPU_FS_PROC_FLOW1 IPU_CM_REG(0x00A8)
  183122. +#define IPU_FS_PROC_FLOW2 IPU_CM_REG(0x00AC)
  183123. +#define IPU_FS_PROC_FLOW3 IPU_CM_REG(0x00B0)
  183124. +#define IPU_FS_DISP_FLOW1 IPU_CM_REG(0x00B4)
  183125. +#define IPU_FS_DISP_FLOW2 IPU_CM_REG(0x00B8)
  183126. +#define IPU_SKIP IPU_CM_REG(0x00BC)
  183127. +#define IPU_DISP_ALT_CONF IPU_CM_REG(0x00C0)
  183128. +#define IPU_DISP_GEN IPU_CM_REG(0x00C4)
  183129. +#define IPU_DISP_ALT1 IPU_CM_REG(0x00C8)
  183130. +#define IPU_DISP_ALT2 IPU_CM_REG(0x00CC)
  183131. +#define IPU_DISP_ALT3 IPU_CM_REG(0x00D0)
  183132. +#define IPU_DISP_ALT4 IPU_CM_REG(0x00D4)
  183133. +#define IPU_SNOOP IPU_CM_REG(0x00D8)
  183134. +#define IPU_MEM_RST IPU_CM_REG(0x00DC)
  183135. +#define IPU_PM IPU_CM_REG(0x00E0)
  183136. +#define IPU_GPR IPU_CM_REG(0x00E4)
  183137. +#define IPU_CHA_DB_MODE_SEL(ch) IPU_CM_REG(0x0150 + 4 * ((ch) / 32))
  183138. +#define IPU_ALT_CHA_DB_MODE_SEL(ch) IPU_CM_REG(0x0168 + 4 * ((ch) / 32))
  183139. +/*
  183140. + * IPUv3D doesn't support triple buffer, so point
  183141. + * IPU_CHA_TRB_MODE_SEL, IPU_CHA_TRIPLE_CUR_BUF and
  183142. + * IPU_CHA_BUF2_RDY to readonly
  183143. + * IPU_ALT_CUR_BUF0 for IPUv3D.
  183144. + */
  183145. +#define IPU_CHA_TRB_MODE_SEL(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183146. + (0x0178 + 4 * ((ch) / 32)) : \
  183147. + (0x012C); })
  183148. +#define IPU_CHA_TRIPLE_CUR_BUF(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183149. + (0x0258 + \
  183150. + 4 * (((ch) * 2) / 32)) : \
  183151. + (0x012C); })
  183152. +#define IPU_CHA_BUF2_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183153. + (0x0288 + 4 * ((ch) / 32)) : \
  183154. + (0x012C); })
  183155. +#define IPU_CHA_CUR_BUF(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183156. + (0x023C + 4 * ((ch) / 32)) : \
  183157. + (0x0124 + 4 * ((ch) / 32)); })
  183158. +#define IPU_ALT_CUR_BUF0 IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183159. + (0x0244) : \
  183160. + (0x012C); })
  183161. +#define IPU_ALT_CUR_BUF1 IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183162. + (0x0248) : \
  183163. + (0x0130); })
  183164. +#define IPU_SRM_STAT IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183165. + (0x024C) : \
  183166. + (0x0134); })
  183167. +#define IPU_PROC_TASK_STAT IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183168. + (0x0250) : \
  183169. + (0x0138); })
  183170. +#define IPU_DISP_TASK_STAT IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183171. + (0x0254) : \
  183172. + (0x013C); })
  183173. +#define IPU_CHA_BUF0_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183174. + (0x0268 + 4 * ((ch) / 32)) : \
  183175. + (0x0140 + 4 * ((ch) / 32)); })
  183176. +#define IPU_CHA_BUF1_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183177. + (0x0270 + 4 * ((ch) / 32)) : \
  183178. + (0x0148 + 4 * ((ch) / 32)); })
  183179. +#define IPU_ALT_CHA_BUF0_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183180. + (0x0278 + 4 * ((ch) / 32)) : \
  183181. + (0x0158 + 4 * ((ch) / 32)); })
  183182. +#define IPU_ALT_CHA_BUF1_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183183. + (0x0280 + 4 * ((ch) / 32)) : \
  183184. + (0x0160 + 4 * ((ch) / 32)); })
  183185. +
  183186. +#define IPU_INT_CTRL(n) IPU_CM_REG(0x003C + 4 * ((n) - 1))
  183187. +#define IPU_INT_STAT(n) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  183188. + (0x0200 + 4 * ((n) - 1)) : \
  183189. + (0x00E8 + 4 * ((n) - 1)); })
  183190. +
  183191. +#define IPUIRQ_2_STATREG(irq) IPU_CM_REG(IPU_INT_STAT(1) + 4 * ((irq) / 32))
  183192. +#define IPUIRQ_2_CTRLREG(irq) IPU_CM_REG(IPU_INT_CTRL(1) + 4 * ((irq) / 32))
  183193. +#define IPUIRQ_2_MASK(irq) (1UL << ((irq) & 0x1F))
  183194. +
  183195. +/* IPU VDI registers */
  183196. +#define IPU_VDI_REG(offset) (offset)
  183197. +
  183198. +#define VDI_FSIZE IPU_VDI_REG(0)
  183199. +#define VDI_C IPU_VDI_REG(0x0004)
  183200. +
  183201. +/* IPU CSI Registers */
  183202. +#define IPU_CSI_REG(offset) (offset)
  183203. +
  183204. +#define CSI_SENS_CONF IPU_CSI_REG(0)
  183205. +#define CSI_SENS_FRM_SIZE IPU_CSI_REG(0x0004)
  183206. +#define CSI_ACT_FRM_SIZE IPU_CSI_REG(0x0008)
  183207. +#define CSI_OUT_FRM_CTRL IPU_CSI_REG(0x000C)
  183208. +#define CSI_TST_CTRL IPU_CSI_REG(0x0010)
  183209. +#define CSI_CCIR_CODE_1 IPU_CSI_REG(0x0014)
  183210. +#define CSI_CCIR_CODE_2 IPU_CSI_REG(0x0018)
  183211. +#define CSI_CCIR_CODE_3 IPU_CSI_REG(0x001C)
  183212. +#define CSI_MIPI_DI IPU_CSI_REG(0x0020)
  183213. +#define CSI_SKIP IPU_CSI_REG(0x0024)
  183214. +#define CSI_CPD_CTRL IPU_CSI_REG(0x0028)
  183215. +#define CSI_CPD_RC(n) IPU_CSI_REG(0x002C + 4 * (n))
  183216. +#define CSI_CPD_RS(n) IPU_CSI_REG(0x004C + 4 * (n))
  183217. +#define CSI_CPD_GRC(n) IPU_CSI_REG(0x005C + 4 * (n))
  183218. +#define CSI_CPD_GRS(n) IPU_CSI_REG(0x007C + 4 * (n))
  183219. +#define CSI_CPD_GBC(n) IPU_CSI_REG(0x008C + 4 * (n))
  183220. +#define CSI_CPD_GBS(n) IPU_CSI_REG(0x00AC + 4 * (n))
  183221. +#define CSI_CPD_BC(n) IPU_CSI_REG(0x00BC + 4 * (n))
  183222. +#define CSI_CPD_BS(n) IPU_CSI_REG(0x00DC + 4 * (n))
  183223. +#define CSI_CPD_OFFSET1 IPU_CSI_REG(0x00EC)
  183224. +#define CSI_CPD_OFFSET2 IPU_CSI_REG(0x00F0)
  183225. +
  183226. +/* IPU SMFC Registers */
  183227. +#define IPU_SMFC_REG(offset) (offset)
  183228. +
  183229. +#define SMFC_MAP IPU_SMFC_REG(0)
  183230. +#define SMFC_WMC IPU_SMFC_REG(0x0004)
  183231. +#define SMFC_BS IPU_SMFC_REG(0x0008)
  183232. +
  183233. +/* IPU IC Registers */
  183234. +#define IPU_IC_REG(offset) (offset)
  183235. +
  183236. +#define IC_CONF IPU_IC_REG(0)
  183237. +#define IC_PRP_ENC_RSC IPU_IC_REG(0x0004)
  183238. +#define IC_PRP_VF_RSC IPU_IC_REG(0x0008)
  183239. +#define IC_PP_RSC IPU_IC_REG(0x000C)
  183240. +#define IC_CMBP_1 IPU_IC_REG(0x0010)
  183241. +#define IC_CMBP_2 IPU_IC_REG(0x0014)
  183242. +#define IC_IDMAC_1 IPU_IC_REG(0x0018)
  183243. +#define IC_IDMAC_2 IPU_IC_REG(0x001C)
  183244. +#define IC_IDMAC_3 IPU_IC_REG(0x0020)
  183245. +#define IC_IDMAC_4 IPU_IC_REG(0x0024)
  183246. +
  183247. +/* IPU IDMAC Registers */
  183248. +#define IPU_IDMAC_REG(offset) (offset)
  183249. +
  183250. +#define IDMAC_CONF IPU_IDMAC_REG(0x0000)
  183251. +#define IDMAC_CHA_EN(ch) IPU_IDMAC_REG(0x0004 + 4 * ((ch) / 32))
  183252. +#define IDMAC_SEP_ALPHA IPU_IDMAC_REG(0x000C)
  183253. +#define IDMAC_ALT_SEP_ALPHA IPU_IDMAC_REG(0x0010)
  183254. +#define IDMAC_CHA_PRI(ch) IPU_IDMAC_REG(0x0014 + 4 * ((ch) / 32))
  183255. +#define IDMAC_WM_EN(ch) IPU_IDMAC_REG(0x001C + 4 * ((ch) / 32))
  183256. +#define IDMAC_CH_LOCK_EN_1 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183257. + (0x0024) : 0; })
  183258. +#define IDMAC_CH_LOCK_EN_2 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183259. + (0x0028) : \
  183260. + (0x0024); })
  183261. +#define IDMAC_SUB_ADDR_0 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183262. + (0x002C) : \
  183263. + (0x0028); })
  183264. +#define IDMAC_SUB_ADDR_1 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183265. + (0x0030) : \
  183266. + (0x002C); })
  183267. +#define IDMAC_SUB_ADDR_2 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183268. + (0x0034) : \
  183269. + (0x0030); })
  183270. +/*
  183271. + * IPUv3D doesn't support IDMAC_SUB_ADDR_3 and IDMAC_SUB_ADDR_4,
  183272. + * so point them to readonly IDMAC_CHA_BUSY1 for IPUv3D.
  183273. + */
  183274. +#define IDMAC_SUB_ADDR_3 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183275. + (0x0038) : \
  183276. + (0x0040); })
  183277. +#define IDMAC_SUB_ADDR_4 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183278. + (0x003C) : \
  183279. + (0x0040); })
  183280. +#define IDMAC_BAND_EN(ch) IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183281. + (0x0040 + 4 * ((ch) / 32)) : \
  183282. + (0x0034 + 4 * ((ch) / 32)); })
  183283. +#define IDMAC_CHA_BUSY(ch) IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  183284. + (0x0100 + 4 * ((ch) / 32)) : \
  183285. + (0x0040 + 4 * ((ch) / 32)); })
  183286. +
  183287. +/* IPU DI Registers */
  183288. +#define IPU_DI_REG(offset) (offset)
  183289. +
  183290. +#define DI_GENERAL IPU_DI_REG(0)
  183291. +#define DI_BS_CLKGEN0 IPU_DI_REG(0x0004)
  183292. +#define DI_BS_CLKGEN1 IPU_DI_REG(0x0008)
  183293. +#define DI_SW_GEN0(gen) IPU_DI_REG(0x000C + 4 * ((gen) - 1))
  183294. +#define DI_SW_GEN1(gen) IPU_DI_REG(0x0030 + 4 * ((gen) - 1))
  183295. +#define DI_STP_REP(gen) IPU_DI_REG(0x0148 + 4 * (((gen) - 1) / 2))
  183296. +#define DI_SYNC_AS_GEN IPU_DI_REG(0x0054)
  183297. +#define DI_DW_GEN(gen) IPU_DI_REG(0x0058 + 4 * (gen))
  183298. +#define DI_DW_SET(gen, set) IPU_DI_REG(0x0088 + 4 * ((gen) + 0xC * (set)))
  183299. +#define DI_SER_CONF IPU_DI_REG(0x015C)
  183300. +#define DI_SSC IPU_DI_REG(0x0160)
  183301. +#define DI_POL IPU_DI_REG(0x0164)
  183302. +#define DI_AW0 IPU_DI_REG(0x0168)
  183303. +#define DI_AW1 IPU_DI_REG(0x016C)
  183304. +#define DI_SCR_CONF IPU_DI_REG(0x0170)
  183305. +#define DI_STAT IPU_DI_REG(0x0174)
  183306. +
  183307. +/* IPU DMFC Registers */
  183308. +#define IPU_DMFC_REG(offset) (offset)
  183309. +
  183310. +#define DMFC_RD_CHAN IPU_DMFC_REG(0)
  183311. +#define DMFC_WR_CHAN IPU_DMFC_REG(0x0004)
  183312. +#define DMFC_WR_CHAN_DEF IPU_DMFC_REG(0x0008)
  183313. +#define DMFC_DP_CHAN IPU_DMFC_REG(0x000C)
  183314. +#define DMFC_DP_CHAN_DEF IPU_DMFC_REG(0x0010)
  183315. +#define DMFC_GENERAL1 IPU_DMFC_REG(0x0014)
  183316. +#define DMFC_GENERAL2 IPU_DMFC_REG(0x0018)
  183317. +#define DMFC_IC_CTRL IPU_DMFC_REG(0x001C)
  183318. +#define DMFC_STAT IPU_DMFC_REG(0x0020)
  183319. +
  183320. +/* IPU DC Registers */
  183321. +#define IPU_DC_REG(offset) (offset)
  183322. +
  183323. +#define DC_MAP_CONF_PTR(n) IPU_DC_REG(0x0108 + ((n) & ~0x1) * 2)
  183324. +#define DC_MAP_CONF_VAL(n) IPU_DC_REG(0x0144 + ((n) & ~0x1) * 2)
  183325. +
  183326. +#define _RL_CH_2_OFFSET(ch) (((ch) == 0) ? 8 : ( \
  183327. + ((ch) == 1) ? 0x24 : ( \
  183328. + ((ch) == 2) ? 0x40 : ( \
  183329. + ((ch) == 5) ? 0x64 : ( \
  183330. + ((ch) == 6) ? 0x80 : ( \
  183331. + ((ch) == 8) ? 0x9C : ( \
  183332. + ((ch) == 9) ? 0xBC : (-1))))))))
  183333. +#define DC_RL_CH(ch, evt) IPU_DC_REG(_RL_CH_2_OFFSET(ch) + \
  183334. + ((evt) & ~0x1) * 2)
  183335. +
  183336. +#define DC_EVT_NF 0
  183337. +#define DC_EVT_NL 1
  183338. +#define DC_EVT_EOF 2
  183339. +#define DC_EVT_NFIELD 3
  183340. +#define DC_EVT_EOL 4
  183341. +#define DC_EVT_EOFIELD 5
  183342. +#define DC_EVT_NEW_ADDR 6
  183343. +#define DC_EVT_NEW_CHAN 7
  183344. +#define DC_EVT_NEW_DATA 8
  183345. +
  183346. +#define DC_EVT_NEW_ADDR_W_0 0
  183347. +#define DC_EVT_NEW_ADDR_W_1 1
  183348. +#define DC_EVT_NEW_CHAN_W_0 2
  183349. +#define DC_EVT_NEW_CHAN_W_1 3
  183350. +#define DC_EVT_NEW_DATA_W_0 4
  183351. +#define DC_EVT_NEW_DATA_W_1 5
  183352. +#define DC_EVT_NEW_ADDR_R_0 6
  183353. +#define DC_EVT_NEW_ADDR_R_1 7
  183354. +#define DC_EVT_NEW_CHAN_R_0 8
  183355. +#define DC_EVT_NEW_CHAN_R_1 9
  183356. +#define DC_EVT_NEW_DATA_R_0 10
  183357. +#define DC_EVT_NEW_DATA_R_1 11
  183358. +#define DC_EVEN_UGDE0 12
  183359. +#define DC_ODD_UGDE0 13
  183360. +#define DC_EVEN_UGDE1 14
  183361. +#define DC_ODD_UGDE1 15
  183362. +#define DC_EVEN_UGDE2 16
  183363. +#define DC_ODD_UGDE2 17
  183364. +#define DC_EVEN_UGDE3 18
  183365. +#define DC_ODD_UGDE3 19
  183366. +
  183367. +#define dc_ch_offset(ch) \
  183368. +({ \
  183369. + const u8 _offset[] = { \
  183370. + 0, 0x1C, 0x38, 0x54, 0x58, 0x5C, 0x78, 0, 0x94, 0xB4}; \
  183371. + _offset[ch]; \
  183372. +})
  183373. +#define DC_WR_CH_CONF(ch) IPU_DC_REG(dc_ch_offset(ch))
  183374. +#define DC_WR_CH_ADDR(ch) IPU_DC_REG(dc_ch_offset(ch) + 4)
  183375. +
  183376. +#define DC_WR_CH_CONF_1 IPU_DC_REG(0x001C)
  183377. +#define DC_WR_CH_ADDR_1 IPU_DC_REG(0x0020)
  183378. +#define DC_WR_CH_CONF_5 IPU_DC_REG(0x005C)
  183379. +#define DC_WR_CH_ADDR_5 IPU_DC_REG(0x0060)
  183380. +#define DC_GEN IPU_DC_REG(0x00D4)
  183381. +#define DC_DISP_CONF1(disp) IPU_DC_REG(0x00D8 + 4 * (disp))
  183382. +#define DC_DISP_CONF2(disp) IPU_DC_REG(0x00E8 + 4 * (disp))
  183383. +#define DC_STAT IPU_DC_REG(0x01C8)
  183384. +#define DC_UGDE_0(evt) IPU_DC_REG(0x0174 + 16 * (evt))
  183385. +#define DC_UGDE_1(evt) IPU_DC_REG(0x0178 + 16 * (evt))
  183386. +#define DC_UGDE_2(evt) IPU_DC_REG(0x017C + 16 * (evt))
  183387. +#define DC_UGDE_3(evt) IPU_DC_REG(0x0180 + 16 * (evt))
  183388. +
  183389. +/* IPU DP Registers */
  183390. +#define IPU_DP_REG(offset) (offset)
  183391. +
  183392. +#define DP_SYNC 0
  183393. +#define DP_ASYNC0 0x60
  183394. +#define DP_ASYNC1 0xBC
  183395. +#define DP_COM_CONF(flow) IPU_DP_REG(flow)
  183396. +#define DP_GRAPH_WIND_CTRL(flow) IPU_DP_REG(0x0004 + (flow))
  183397. +#define DP_FG_POS(flow) IPU_DP_REG(0x0008 + (flow))
  183398. +#define DP_GAMMA_C(flow, i) IPU_DP_REG(0x0014 + (flow) + 4 * (i))
  183399. +#define DP_GAMMA_S(flow, i) IPU_DP_REG(0x0034 + (flow) + 4 * (i))
  183400. +#define DP_CSC_A_0(flow) IPU_DP_REG(0x0044 + (flow))
  183401. +#define DP_CSC_A_1(flow) IPU_DP_REG(0x0048 + (flow))
  183402. +#define DP_CSC_A_2(flow) IPU_DP_REG(0x004C + (flow))
  183403. +#define DP_CSC_A_3(flow) IPU_DP_REG(0x0050 + (flow))
  183404. +#define DP_CSC_0(flow) IPU_DP_REG(0x0054 + (flow))
  183405. +#define DP_CSC_1(flow) IPU_DP_REG(0x0058 + (flow))
  183406. +
  183407. +enum {
  183408. + IPU_CONF_CSI0_EN = 0x00000001,
  183409. + IPU_CONF_CSI1_EN = 0x00000002,
  183410. + IPU_CONF_IC_EN = 0x00000004,
  183411. + IPU_CONF_ROT_EN = 0x00000008,
  183412. + IPU_CONF_ISP_EN = 0x00000010,
  183413. + IPU_CONF_DP_EN = 0x00000020,
  183414. + IPU_CONF_DI0_EN = 0x00000040,
  183415. + IPU_CONF_DI1_EN = 0x00000080,
  183416. + IPU_CONF_DMFC_EN = 0x00000400,
  183417. + IPU_CONF_SMFC_EN = 0x00000100,
  183418. + IPU_CONF_DC_EN = 0x00000200,
  183419. + IPU_CONF_VDI_EN = 0x00001000,
  183420. + IPU_CONF_IDMAC_DIS = 0x00400000,
  183421. + IPU_CONF_IC_DMFC_SEL = 0x02000000,
  183422. + IPU_CONF_IC_DMFC_SYNC = 0x04000000,
  183423. + IPU_CONF_VDI_DMFC_SYNC = 0x08000000,
  183424. + IPU_CONF_CSI0_DATA_SOURCE = 0x10000000,
  183425. + IPU_CONF_CSI0_DATA_SOURCE_OFFSET = 28,
  183426. + IPU_CONF_CSI1_DATA_SOURCE = 0x20000000,
  183427. + IPU_CONF_IC_INPUT = 0x40000000,
  183428. + IPU_CONF_CSI_SEL = 0x80000000,
  183429. +
  183430. + DI0_COUNTER_RELEASE = 0x01000000,
  183431. + DI1_COUNTER_RELEASE = 0x02000000,
  183432. +
  183433. + FS_PRPVF_ROT_SRC_SEL_MASK = 0x00000F00,
  183434. + FS_PRPVF_ROT_SRC_SEL_OFFSET = 8,
  183435. + FS_PRPENC_ROT_SRC_SEL_MASK = 0x0000000F,
  183436. + FS_PRPENC_ROT_SRC_SEL_OFFSET = 0,
  183437. + FS_PP_ROT_SRC_SEL_MASK = 0x000F0000,
  183438. + FS_PP_ROT_SRC_SEL_OFFSET = 16,
  183439. + FS_PP_SRC_SEL_MASK = 0x0000F000,
  183440. + FS_PP_SRC_SEL_VDOA = 0x00008000,
  183441. + FS_PP_SRC_SEL_OFFSET = 12,
  183442. + FS_PRP_SRC_SEL_MASK = 0x0F000000,
  183443. + FS_PRP_SRC_SEL_OFFSET = 24,
  183444. + FS_VF_IN_VALID = 0x80000000,
  183445. + FS_ENC_IN_VALID = 0x40000000,
  183446. + FS_VDI_SRC_SEL_MASK = 0x30000000,
  183447. + FS_VDI_SRC_SEL_VDOA = 0x20000000,
  183448. + FS_VDOA_DEST_SEL_MASK = 0x00030000,
  183449. + FS_VDOA_DEST_SEL_VDI = 0x00020000,
  183450. + FS_VDOA_DEST_SEL_IC = 0x00010000,
  183451. + FS_VDI_SRC_SEL_OFFSET = 28,
  183452. +
  183453. +
  183454. + FS_PRPENC_DEST_SEL_MASK = 0x0000000F,
  183455. + FS_PRPENC_DEST_SEL_OFFSET = 0,
  183456. + FS_PRPVF_DEST_SEL_MASK = 0x000000F0,
  183457. + FS_PRPVF_DEST_SEL_OFFSET = 4,
  183458. + FS_PRPVF_ROT_DEST_SEL_MASK = 0x00000F00,
  183459. + FS_PRPVF_ROT_DEST_SEL_OFFSET = 8,
  183460. + FS_PP_DEST_SEL_MASK = 0x0000F000,
  183461. + FS_PP_DEST_SEL_OFFSET = 12,
  183462. + FS_PP_ROT_DEST_SEL_MASK = 0x000F0000,
  183463. + FS_PP_ROT_DEST_SEL_OFFSET = 16,
  183464. + FS_PRPENC_ROT_DEST_SEL_MASK = 0x00F00000,
  183465. + FS_PRPENC_ROT_DEST_SEL_OFFSET = 20,
  183466. +
  183467. + FS_SMFC0_DEST_SEL_MASK = 0x0000000F,
  183468. + FS_SMFC0_DEST_SEL_OFFSET = 0,
  183469. + FS_SMFC1_DEST_SEL_MASK = 0x00000070,
  183470. + FS_SMFC1_DEST_SEL_OFFSET = 4,
  183471. + FS_SMFC2_DEST_SEL_MASK = 0x00000780,
  183472. + FS_SMFC2_DEST_SEL_OFFSET = 7,
  183473. + FS_SMFC3_DEST_SEL_MASK = 0x00003800,
  183474. + FS_SMFC3_DEST_SEL_OFFSET = 11,
  183475. +
  183476. + FS_DC1_SRC_SEL_MASK = 0x00F00000,
  183477. + FS_DC1_SRC_SEL_OFFSET = 20,
  183478. + FS_DC2_SRC_SEL_MASK = 0x000F0000,
  183479. + FS_DC2_SRC_SEL_OFFSET = 16,
  183480. + FS_DP_SYNC0_SRC_SEL_MASK = 0x0000000F,
  183481. + FS_DP_SYNC0_SRC_SEL_OFFSET = 0,
  183482. + FS_DP_SYNC1_SRC_SEL_MASK = 0x000000F0,
  183483. + FS_DP_SYNC1_SRC_SEL_OFFSET = 4,
  183484. + FS_DP_ASYNC0_SRC_SEL_MASK = 0x00000F00,
  183485. + FS_DP_ASYNC0_SRC_SEL_OFFSET = 8,
  183486. + FS_DP_ASYNC1_SRC_SEL_MASK = 0x0000F000,
  183487. + FS_DP_ASYNC1_SRC_SEL_OFFSET = 12,
  183488. +
  183489. + FS_AUTO_REF_PER_MASK = 0,
  183490. + FS_AUTO_REF_PER_OFFSET = 16,
  183491. +
  183492. + TSTAT_VF_MASK = 0x0000000C,
  183493. + TSTAT_VF_OFFSET = 2,
  183494. + TSTAT_VF_ROT_MASK = 0x00000300,
  183495. + TSTAT_VF_ROT_OFFSET = 8,
  183496. + TSTAT_ENC_MASK = 0x00000003,
  183497. + TSTAT_ENC_OFFSET = 0,
  183498. + TSTAT_ENC_ROT_MASK = 0x000000C0,
  183499. + TSTAT_ENC_ROT_OFFSET = 6,
  183500. + TSTAT_PP_MASK = 0x00000030,
  183501. + TSTAT_PP_OFFSET = 4,
  183502. + TSTAT_PP_ROT_MASK = 0x00000C00,
  183503. + TSTAT_PP_ROT_OFFSET = 10,
  183504. +
  183505. + TASK_STAT_IDLE = 0,
  183506. + TASK_STAT_ACTIVE = 1,
  183507. + TASK_STAT_WAIT4READY = 2,
  183508. +
  183509. + /* Image Converter Register bits */
  183510. + IC_CONF_PRPENC_EN = 0x00000001,
  183511. + IC_CONF_PRPENC_CSC1 = 0x00000002,
  183512. + IC_CONF_PRPENC_ROT_EN = 0x00000004,
  183513. + IC_CONF_PRPVF_EN = 0x00000100,
  183514. + IC_CONF_PRPVF_CSC1 = 0x00000200,
  183515. + IC_CONF_PRPVF_CSC2 = 0x00000400,
  183516. + IC_CONF_PRPVF_CMB = 0x00000800,
  183517. + IC_CONF_PRPVF_ROT_EN = 0x00001000,
  183518. + IC_CONF_PP_EN = 0x00010000,
  183519. + IC_CONF_PP_CSC1 = 0x00020000,
  183520. + IC_CONF_PP_CSC2 = 0x00040000,
  183521. + IC_CONF_PP_CMB = 0x00080000,
  183522. + IC_CONF_PP_ROT_EN = 0x00100000,
  183523. + IC_CONF_IC_GLB_LOC_A = 0x10000000,
  183524. + IC_CONF_KEY_COLOR_EN = 0x20000000,
  183525. + IC_CONF_RWS_EN = 0x40000000,
  183526. + IC_CONF_CSI_MEM_WR_EN = 0x80000000,
  183527. +
  183528. + IC_RSZ_MAX_RESIZE_RATIO = 0x00004000,
  183529. +
  183530. + IC_IDMAC_1_CB0_BURST_16 = 0x00000001,
  183531. + IC_IDMAC_1_CB1_BURST_16 = 0x00000002,
  183532. + IC_IDMAC_1_CB2_BURST_16 = 0x00000004,
  183533. + IC_IDMAC_1_CB3_BURST_16 = 0x00000008,
  183534. + IC_IDMAC_1_CB4_BURST_16 = 0x00000010,
  183535. + IC_IDMAC_1_CB5_BURST_16 = 0x00000020,
  183536. + IC_IDMAC_1_CB6_BURST_16 = 0x00000040,
  183537. + IC_IDMAC_1_CB7_BURST_16 = 0x00000080,
  183538. + IC_IDMAC_1_PRPENC_ROT_MASK = 0x00003800,
  183539. + IC_IDMAC_1_PRPENC_ROT_OFFSET = 11,
  183540. + IC_IDMAC_1_PRPVF_ROT_MASK = 0x0001C000,
  183541. + IC_IDMAC_1_PRPVF_ROT_OFFSET = 14,
  183542. + IC_IDMAC_1_PP_ROT_MASK = 0x000E0000,
  183543. + IC_IDMAC_1_PP_ROT_OFFSET = 17,
  183544. + IC_IDMAC_1_PP_FLIP_RS = 0x00400000,
  183545. + IC_IDMAC_1_PRPVF_FLIP_RS = 0x00200000,
  183546. + IC_IDMAC_1_PRPENC_FLIP_RS = 0x00100000,
  183547. +
  183548. + IC_IDMAC_2_PRPENC_HEIGHT_MASK = 0x000003FF,
  183549. + IC_IDMAC_2_PRPENC_HEIGHT_OFFSET = 0,
  183550. + IC_IDMAC_2_PRPVF_HEIGHT_MASK = 0x000FFC00,
  183551. + IC_IDMAC_2_PRPVF_HEIGHT_OFFSET = 10,
  183552. + IC_IDMAC_2_PP_HEIGHT_MASK = 0x3FF00000,
  183553. + IC_IDMAC_2_PP_HEIGHT_OFFSET = 20,
  183554. +
  183555. + IC_IDMAC_3_PRPENC_WIDTH_MASK = 0x000003FF,
  183556. + IC_IDMAC_3_PRPENC_WIDTH_OFFSET = 0,
  183557. + IC_IDMAC_3_PRPVF_WIDTH_MASK = 0x000FFC00,
  183558. + IC_IDMAC_3_PRPVF_WIDTH_OFFSET = 10,
  183559. + IC_IDMAC_3_PP_WIDTH_MASK = 0x3FF00000,
  183560. + IC_IDMAC_3_PP_WIDTH_OFFSET = 20,
  183561. +
  183562. + CSI_SENS_CONF_DATA_FMT_SHIFT = 8,
  183563. + CSI_SENS_CONF_DATA_FMT_MASK = 0x00000700,
  183564. + CSI_SENS_CONF_DATA_FMT_RGB_YUV444 = 0L,
  183565. + CSI_SENS_CONF_DATA_FMT_YUV422_YUYV = 1L,
  183566. + CSI_SENS_CONF_DATA_FMT_YUV422_UYVY = 2L,
  183567. + CSI_SENS_CONF_DATA_FMT_BAYER = 3L,
  183568. + CSI_SENS_CONF_DATA_FMT_RGB565 = 4L,
  183569. + CSI_SENS_CONF_DATA_FMT_RGB555 = 5L,
  183570. + CSI_SENS_CONF_DATA_FMT_RGB444 = 6L,
  183571. + CSI_SENS_CONF_DATA_FMT_JPEG = 7L,
  183572. +
  183573. + CSI_SENS_CONF_VSYNC_POL_SHIFT = 0,
  183574. + CSI_SENS_CONF_HSYNC_POL_SHIFT = 1,
  183575. + CSI_SENS_CONF_DATA_POL_SHIFT = 2,
  183576. + CSI_SENS_CONF_PIX_CLK_POL_SHIFT = 3,
  183577. + CSI_SENS_CONF_SENS_PRTCL_MASK = 0x00000070L,
  183578. + CSI_SENS_CONF_SENS_PRTCL_SHIFT = 4,
  183579. + CSI_SENS_CONF_PACK_TIGHT_SHIFT = 7,
  183580. + CSI_SENS_CONF_DATA_WIDTH_SHIFT = 11,
  183581. + CSI_SENS_CONF_EXT_VSYNC_SHIFT = 15,
  183582. + CSI_SENS_CONF_DIVRATIO_SHIFT = 16,
  183583. +
  183584. + CSI_SENS_CONF_DIVRATIO_MASK = 0x00FF0000L,
  183585. + CSI_SENS_CONF_DATA_DEST_SHIFT = 24,
  183586. + CSI_SENS_CONF_DATA_DEST_MASK = 0x07000000L,
  183587. + CSI_SENS_CONF_JPEG8_EN_SHIFT = 27,
  183588. + CSI_SENS_CONF_JPEG_EN_SHIFT = 28,
  183589. + CSI_SENS_CONF_FORCE_EOF_SHIFT = 29,
  183590. + CSI_SENS_CONF_DATA_EN_POL_SHIFT = 31,
  183591. +
  183592. + CSI_DATA_DEST_ISP = 1L,
  183593. + CSI_DATA_DEST_IC = 2L,
  183594. + CSI_DATA_DEST_IDMAC = 4L,
  183595. +
  183596. + CSI_CCIR_ERR_DET_EN = 0x01000000L,
  183597. + CSI_HORI_DOWNSIZE_EN = 0x80000000L,
  183598. + CSI_VERT_DOWNSIZE_EN = 0x40000000L,
  183599. + CSI_TEST_GEN_MODE_EN = 0x01000000L,
  183600. +
  183601. + CSI_HSC_MASK = 0x1FFF0000,
  183602. + CSI_HSC_SHIFT = 16,
  183603. + CSI_VSC_MASK = 0x00000FFF,
  183604. + CSI_VSC_SHIFT = 0,
  183605. +
  183606. + CSI_TEST_GEN_R_MASK = 0x000000FFL,
  183607. + CSI_TEST_GEN_R_SHIFT = 0,
  183608. + CSI_TEST_GEN_G_MASK = 0x0000FF00L,
  183609. + CSI_TEST_GEN_G_SHIFT = 8,
  183610. + CSI_TEST_GEN_B_MASK = 0x00FF0000L,
  183611. + CSI_TEST_GEN_B_SHIFT = 16,
  183612. +
  183613. + CSI_MIPI_DI0_MASK = 0x000000FFL,
  183614. + CSI_MIPI_DI0_SHIFT = 0,
  183615. + CSI_MIPI_DI1_MASK = 0x0000FF00L,
  183616. + CSI_MIPI_DI1_SHIFT = 8,
  183617. + CSI_MIPI_DI2_MASK = 0x00FF0000L,
  183618. + CSI_MIPI_DI2_SHIFT = 16,
  183619. + CSI_MIPI_DI3_MASK = 0xFF000000L,
  183620. + CSI_MIPI_DI3_SHIFT = 24,
  183621. +
  183622. + CSI_MAX_RATIO_SKIP_ISP_MASK = 0x00070000L,
  183623. + CSI_MAX_RATIO_SKIP_ISP_SHIFT = 16,
  183624. + CSI_SKIP_ISP_MASK = 0x00F80000L,
  183625. + CSI_SKIP_ISP_SHIFT = 19,
  183626. + CSI_MAX_RATIO_SKIP_SMFC_MASK = 0x00000007L,
  183627. + CSI_MAX_RATIO_SKIP_SMFC_SHIFT = 0,
  183628. + CSI_SKIP_SMFC_MASK = 0x000000F8L,
  183629. + CSI_SKIP_SMFC_SHIFT = 3,
  183630. + CSI_ID_2_SKIP_MASK = 0x00000300L,
  183631. + CSI_ID_2_SKIP_SHIFT = 8,
  183632. +
  183633. + CSI_COLOR_FIRST_ROW_MASK = 0x00000002L,
  183634. + CSI_COLOR_FIRST_COMP_MASK = 0x00000001L,
  183635. +
  183636. + SMFC_MAP_CH0_MASK = 0x00000007L,
  183637. + SMFC_MAP_CH0_SHIFT = 0,
  183638. + SMFC_MAP_CH1_MASK = 0x00000038L,
  183639. + SMFC_MAP_CH1_SHIFT = 3,
  183640. + SMFC_MAP_CH2_MASK = 0x000001C0L,
  183641. + SMFC_MAP_CH2_SHIFT = 6,
  183642. + SMFC_MAP_CH3_MASK = 0x00000E00L,
  183643. + SMFC_MAP_CH3_SHIFT = 9,
  183644. +
  183645. + SMFC_WM0_SET_MASK = 0x00000007L,
  183646. + SMFC_WM0_SET_SHIFT = 0,
  183647. + SMFC_WM1_SET_MASK = 0x000001C0L,
  183648. + SMFC_WM1_SET_SHIFT = 6,
  183649. + SMFC_WM2_SET_MASK = 0x00070000L,
  183650. + SMFC_WM2_SET_SHIFT = 16,
  183651. + SMFC_WM3_SET_MASK = 0x01C00000L,
  183652. + SMFC_WM3_SET_SHIFT = 22,
  183653. +
  183654. + SMFC_WM0_CLR_MASK = 0x00000038L,
  183655. + SMFC_WM0_CLR_SHIFT = 3,
  183656. + SMFC_WM1_CLR_MASK = 0x00000E00L,
  183657. + SMFC_WM1_CLR_SHIFT = 9,
  183658. + SMFC_WM2_CLR_MASK = 0x00380000L,
  183659. + SMFC_WM2_CLR_SHIFT = 19,
  183660. + SMFC_WM3_CLR_MASK = 0x0E000000L,
  183661. + SMFC_WM3_CLR_SHIFT = 25,
  183662. +
  183663. + SMFC_BS0_MASK = 0x0000000FL,
  183664. + SMFC_BS0_SHIFT = 0,
  183665. + SMFC_BS1_MASK = 0x000000F0L,
  183666. + SMFC_BS1_SHIFT = 4,
  183667. + SMFC_BS2_MASK = 0x00000F00L,
  183668. + SMFC_BS2_SHIFT = 8,
  183669. + SMFC_BS3_MASK = 0x0000F000L,
  183670. + SMFC_BS3_SHIFT = 12,
  183671. +
  183672. + PF_CONF_TYPE_MASK = 0x00000007,
  183673. + PF_CONF_TYPE_SHIFT = 0,
  183674. + PF_CONF_PAUSE_EN = 0x00000010,
  183675. + PF_CONF_RESET = 0x00008000,
  183676. + PF_CONF_PAUSE_ROW_MASK = 0x00FF0000,
  183677. + PF_CONF_PAUSE_ROW_SHIFT = 16,
  183678. +
  183679. + DI_DW_GEN_ACCESS_SIZE_OFFSET = 24,
  183680. + DI_DW_GEN_COMPONENT_SIZE_OFFSET = 16,
  183681. +
  183682. + DI_GEN_DI_CLK_EXT = 0x100000,
  183683. + DI_GEN_POLARITY_DISP_CLK = 0x00020000,
  183684. + DI_GEN_POLARITY_1 = 0x00000001,
  183685. + DI_GEN_POLARITY_2 = 0x00000002,
  183686. + DI_GEN_POLARITY_3 = 0x00000004,
  183687. + DI_GEN_POLARITY_4 = 0x00000008,
  183688. + DI_GEN_POLARITY_5 = 0x00000010,
  183689. + DI_GEN_POLARITY_6 = 0x00000020,
  183690. + DI_GEN_POLARITY_7 = 0x00000040,
  183691. + DI_GEN_POLARITY_8 = 0x00000080,
  183692. +
  183693. + DI_POL_DRDY_DATA_POLARITY = 0x00000080,
  183694. + DI_POL_DRDY_POLARITY_15 = 0x00000010,
  183695. +
  183696. + DI_VSYNC_SEL_OFFSET = 13,
  183697. +
  183698. + DC_WR_CH_CONF_FIELD_MODE = 0x00000200,
  183699. + DC_WR_CH_CONF_PROG_TYPE_OFFSET = 5,
  183700. + DC_WR_CH_CONF_PROG_TYPE_MASK = 0x000000E0,
  183701. + DC_WR_CH_CONF_PROG_DI_ID = 0x00000004,
  183702. + DC_WR_CH_CONF_PROG_DISP_ID_OFFSET = 3,
  183703. + DC_WR_CH_CONF_PROG_DISP_ID_MASK = 0x00000018,
  183704. +
  183705. + DC_UGDE_0_ODD_EN = 0x02000000,
  183706. + DC_UGDE_0_ID_CODED_MASK = 0x00000007,
  183707. + DC_UGDE_0_ID_CODED_OFFSET = 0,
  183708. + DC_UGDE_0_EV_PRIORITY_MASK = 0x00000078,
  183709. + DC_UGDE_0_EV_PRIORITY_OFFSET = 3,
  183710. +
  183711. + DP_COM_CONF_FG_EN = 0x00000001,
  183712. + DP_COM_CONF_GWSEL = 0x00000002,
  183713. + DP_COM_CONF_GWAM = 0x00000004,
  183714. + DP_COM_CONF_GWCKE = 0x00000008,
  183715. + DP_COM_CONF_CSC_DEF_MASK = 0x00000300,
  183716. + DP_COM_CONF_CSC_DEF_OFFSET = 8,
  183717. + DP_COM_CONF_CSC_DEF_FG = 0x00000300,
  183718. + DP_COM_CONF_CSC_DEF_BG = 0x00000200,
  183719. + DP_COM_CONF_CSC_DEF_BOTH = 0x00000100,
  183720. + DP_COM_CONF_GAMMA_EN = 0x00001000,
  183721. + DP_COM_CONF_GAMMA_YUV_EN = 0x00002000,
  183722. +
  183723. + DI_SER_CONF_LLA_SER_ACCESS = 0x00000020,
  183724. + DI_SER_CONF_SERIAL_CLK_POL = 0x00000010,
  183725. + DI_SER_CONF_SERIAL_DATA_POL = 0x00000008,
  183726. + DI_SER_CONF_SERIAL_RS_POL = 0x00000004,
  183727. + DI_SER_CONF_SERIAL_CS_POL = 0x00000002,
  183728. + DI_SER_CONF_WAIT4SERIAL = 0x00000001,
  183729. +
  183730. + VDI_C_CH_420 = 0x00000000,
  183731. + VDI_C_CH_422 = 0x00000002,
  183732. + VDI_C_MOT_SEL_FULL = 0x00000008,
  183733. + VDI_C_MOT_SEL_LOW = 0x00000004,
  183734. + VDI_C_MOT_SEL_MED = 0x00000000,
  183735. + VDI_C_BURST_SIZE1_4 = 0x00000030,
  183736. + VDI_C_BURST_SIZE2_4 = 0x00000300,
  183737. + VDI_C_BURST_SIZE3_4 = 0x00003000,
  183738. + VDI_C_BURST_SIZE_MASK = 0xF,
  183739. + VDI_C_BURST_SIZE1_OFFSET = 4,
  183740. + VDI_C_BURST_SIZE2_OFFSET = 8,
  183741. + VDI_C_BURST_SIZE3_OFFSET = 12,
  183742. + VDI_C_VWM1_SET_1 = 0x00000000,
  183743. + VDI_C_VWM1_SET_2 = 0x00010000,
  183744. + VDI_C_VWM1_CLR_2 = 0x00080000,
  183745. + VDI_C_VWM3_SET_1 = 0x00000000,
  183746. + VDI_C_VWM3_SET_2 = 0x00400000,
  183747. + VDI_C_VWM3_CLR_2 = 0x02000000,
  183748. + VDI_C_TOP_FIELD_MAN_1 = 0x40000000,
  183749. + VDI_C_TOP_FIELD_AUTO_1 = 0x80000000,
  183750. +};
  183751. +
  183752. +enum di_pins {
  183753. + DI_PIN11 = 0,
  183754. + DI_PIN12 = 1,
  183755. + DI_PIN13 = 2,
  183756. + DI_PIN14 = 3,
  183757. + DI_PIN15 = 4,
  183758. + DI_PIN16 = 5,
  183759. + DI_PIN17 = 6,
  183760. + DI_PIN_CS = 7,
  183761. +
  183762. + DI_PIN_SER_CLK = 0,
  183763. + DI_PIN_SER_RS = 1,
  183764. +};
  183765. +
  183766. +enum di_sync_wave {
  183767. + DI_SYNC_NONE = -1,
  183768. + DI_SYNC_CLK = 0,
  183769. + DI_SYNC_INT_HSYNC = 1,
  183770. + DI_SYNC_HSYNC = 2,
  183771. + DI_SYNC_VSYNC = 3,
  183772. + DI_SYNC_DE = 5,
  183773. +};
  183774. +
  183775. +/* DC template opcodes */
  183776. +#define WROD(lf) (0x18 | (lf << 1))
  183777. +#define WRG (0x01)
  183778. +
  183779. +#endif
  183780. diff -Nur linux-3.14.14/drivers/mxc/ipu3/Kconfig linux-imx6-3.14/drivers/mxc/ipu3/Kconfig
  183781. --- linux-3.14.14/drivers/mxc/ipu3/Kconfig 1969-12-31 18:00:00.000000000 -0600
  183782. +++ linux-imx6-3.14/drivers/mxc/ipu3/Kconfig 2014-12-08 00:31:53.472418001 -0600
  183783. @@ -0,0 +1,2 @@
  183784. +config MXC_IPU_V3
  183785. + bool
  183786. diff -Nur linux-3.14.14/drivers/mxc/ipu3/Makefile linux-imx6-3.14/drivers/mxc/ipu3/Makefile
  183787. --- linux-3.14.14/drivers/mxc/ipu3/Makefile 1969-12-31 18:00:00.000000000 -0600
  183788. +++ linux-imx6-3.14/drivers/mxc/ipu3/Makefile 2014-12-08 00:31:53.472418001 -0600
  183789. @@ -0,0 +1,4 @@
  183790. +obj-$(CONFIG_MXC_IPU_V3) = mxc_ipu.o
  183791. +
  183792. +mxc_ipu-objs := ipu_common.o ipu_ic.o ipu_disp.o ipu_capture.o ipu_device.o \
  183793. + ipu_calc_stripes_sizes.o vdoa.o ipu_pixel_clk.o
  183794. diff -Nur linux-3.14.14/drivers/mxc/ipu3/vdoa.c linux-imx6-3.14/drivers/mxc/ipu3/vdoa.c
  183795. --- linux-3.14.14/drivers/mxc/ipu3/vdoa.c 1969-12-31 18:00:00.000000000 -0600
  183796. +++ linux-imx6-3.14/drivers/mxc/ipu3/vdoa.c 2014-12-08 00:31:53.476418001 -0600
  183797. @@ -0,0 +1,543 @@
  183798. +/*
  183799. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  183800. + *
  183801. + * This program is free software; you can redistribute it and/or modify
  183802. + * it under the terms of the GNU General Public License as published by
  183803. + * the Free Software Foundation; either version 2 of the License, or
  183804. + * (at your option) any later version.
  183805. +
  183806. + * This program is distributed in the hope that it will be useful,
  183807. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  183808. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  183809. + * GNU General Public License for more details.
  183810. +
  183811. + * You should have received a copy of the GNU General Public License along
  183812. + * with this program; if not, write to the Free Software Foundation, Inc.,
  183813. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  183814. + */
  183815. +#include <linux/clk.h>
  183816. +#include <linux/err.h>
  183817. +#include <linux/io.h>
  183818. +#include <linux/ipu.h>
  183819. +#include <linux/genalloc.h>
  183820. +#include <linux/module.h>
  183821. +#include <linux/platform_device.h>
  183822. +#include <linux/slab.h>
  183823. +#include <linux/types.h>
  183824. +
  183825. +#include "vdoa.h"
  183826. +/* 6band(3field* double buffer) * (width*2) * bandline(8)
  183827. + = 6x1024x2x8 = 96k or 72k(1.5byte) */
  183828. +#define MAX_VDOA_IRAM_SIZE (1024*96)
  183829. +#define VDOA_IRAM_SIZE (1024*72)
  183830. +
  183831. +#define VDOAC_BAND_HEIGHT_32LINES (32)
  183832. +#define VDOAC_BAND_HEIGHT_16LINES (16)
  183833. +#define VDOAC_BAND_HEIGHT_8LINES (8)
  183834. +#define VDOAC_THREE_FRAMES (0x1 << 2)
  183835. +#define VDOAC_SYNC_BAND_MODE (0x1 << 3)
  183836. +#define VDOAC_SCAN_ORDER_INTERLACED (0x1 << 4)
  183837. +#define VDOAC_PFS_YUYV (0x1 << 5)
  183838. +#define VDOAC_IPU_SEL_1 (0x1 << 6)
  183839. +#define VDOAFP_FH_MASK (0x1FFF)
  183840. +#define VDOAFP_FH_SHIFT (16)
  183841. +#define VDOAFP_FW_MASK (0x3FFF)
  183842. +#define VDOAFP_FW_SHIFT (0)
  183843. +#define VDOASL_VSLY_MASK (0x3FFF)
  183844. +#define VDOASL_VSLY_SHIFT (16)
  183845. +#define VDOASL_ISLY_MASK (0x7FFF)
  183846. +#define VDOASL_ISLY_SHIFT (0)
  183847. +#define VDOASRR_START_XFER (0x2)
  183848. +#define VDOASRR_SWRST (0x1)
  183849. +#define VDOAIEIST_TRANSFER_ERR (0x2)
  183850. +#define VDOAIEIST_TRANSFER_END (0x1)
  183851. +
  183852. +#define VDOAC (0x0) /* Control Register */
  183853. +#define VDOASRR (0x4) /* Start and Reset Register */
  183854. +#define VDOAIE (0x8) /* Interrupt Enable Register */
  183855. +#define VDOAIST (0xc) /* Interrupt Status Register */
  183856. +#define VDOAFP (0x10) /* Frame Parameters Register */
  183857. +#define VDOAIEBA00 (0x14) /* External Buffer n Frame m Address Register */
  183858. +#define VDOAIEBA01 (0x18) /* External Buffer n Frame m Address Register */
  183859. +#define VDOAIEBA02 (0x1c) /* External Buffer n Frame m Address Register */
  183860. +#define VDOAIEBA10 (0x20) /* External Buffer n Frame m Address Register */
  183861. +#define VDOAIEBA11 (0x24) /* External Buffer n Frame m Address Register */
  183862. +#define VDOAIEBA12 (0x28) /* External Buffer n Frame m Address Register */
  183863. +#define VDOASL (0x2c) /* IPU Stride Line Register */
  183864. +#define VDOAIUBO (0x30) /* IPU Chroma Buffer Offset Register */
  183865. +#define VDOAVEBA0 (0x34) /* External Buffer m Address Register */
  183866. +#define VDOAVEBA1 (0x38) /* External Buffer m Address Register */
  183867. +#define VDOAVEBA2 (0x3c) /* External Buffer m Address Register */
  183868. +#define VDOAVUBO (0x40) /* VPU Chroma Buffer Offset */
  183869. +#define VDOASR (0x44) /* Status Register */
  183870. +#define VDOATD (0x48) /* Test Debug Register */
  183871. +
  183872. +
  183873. +enum {
  183874. + VDOA_INIT = 0x1,
  183875. + VDOA_GET = 0x2,
  183876. + VDOA_SETUP = 0x4,
  183877. + VDOA_GET_OBUF = 0x8,
  183878. + VDOA_START = 0x10,
  183879. + VDOA_INIRQ = 0x20,
  183880. + VDOA_STOP = 0x40,
  183881. + VDOA_PUT = VDOA_INIT,
  183882. +};
  183883. +
  183884. +enum {
  183885. + VDOA_NULL = 0,
  183886. + VDOA_FRAME = 1,
  183887. + VDOA_PREV_FIELD = 2,
  183888. + VDOA_CURR_FIELD = 3,
  183889. + VDOA_NEXT_FIELD = 4,
  183890. +};
  183891. +
  183892. +#define CHECK_STATE(expect, retcode) \
  183893. +do { \
  183894. + if (!((expect) & vdoa->state)) { \
  183895. + dev_err(vdoa->dev, "ERR: %s state:0x%x, expect:0x%x.\n",\
  183896. + __func__, vdoa->state, (expect)); \
  183897. + retcode; \
  183898. + } \
  183899. +} while (0)
  183900. +
  183901. +#define CHECK_NULL_PTR(ptr) \
  183902. +do { \
  183903. + pr_debug("vdoa_ptr:0x%p in %s state:0x%x.\n", \
  183904. + vdoa, __func__, vdoa->state); \
  183905. + if (NULL == (ptr)) { \
  183906. + pr_err("ERR vdoa: %s state:0x%x null ptr.\n", \
  183907. + __func__, vdoa->state); \
  183908. + } \
  183909. +} while (0)
  183910. +
  183911. +struct vdoa_info {
  183912. + int state;
  183913. + struct device *dev;
  183914. + struct clk *vdoa_clk;
  183915. + void __iomem *reg_base;
  183916. + struct gen_pool *iram_pool;
  183917. + unsigned long iram_base;
  183918. + unsigned long iram_paddr;
  183919. + int irq;
  183920. + int field;
  183921. + struct completion comp;
  183922. +};
  183923. +
  183924. +static struct vdoa_info *g_vdoa;
  183925. +static unsigned long iram_size;
  183926. +static DEFINE_MUTEX(vdoa_lock);
  183927. +
  183928. +static inline void vdoa_read_register(struct vdoa_info *vdoa,
  183929. + u32 reg, u32 *val)
  183930. +{
  183931. + *val = ioread32(vdoa->reg_base + reg);
  183932. + dev_dbg(vdoa->dev, "read_reg:0x%02x, val:0x%08x.\n", reg, *val);
  183933. +}
  183934. +
  183935. +static inline void vdoa_write_register(struct vdoa_info *vdoa,
  183936. + u32 reg, u32 val)
  183937. +{
  183938. + iowrite32(val, vdoa->reg_base + reg);
  183939. + dev_dbg(vdoa->dev, "\t\twrite_reg:0x%02x, val:0x%08x.\n", reg, val);
  183940. +}
  183941. +
  183942. +static void dump_registers(struct vdoa_info *vdoa)
  183943. +{
  183944. + int i;
  183945. + u32 data;
  183946. +
  183947. + for (i = VDOAC; i < VDOATD; i += 4)
  183948. + vdoa_read_register(vdoa, i, &data);
  183949. +}
  183950. +
  183951. +int vdoa_setup(vdoa_handle_t handle, struct vdoa_params *params)
  183952. +{
  183953. + int band_size;
  183954. + int total_band_size = 0;
  183955. + int ipu_stride;
  183956. + u32 data;
  183957. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  183958. +
  183959. + CHECK_NULL_PTR(vdoa);
  183960. + CHECK_STATE(VDOA_GET | VDOA_GET_OBUF | VDOA_STOP, return -EINVAL);
  183961. + if (VDOA_GET == vdoa->state) {
  183962. + dev_dbg(vdoa->dev, "w:%d, h:%d.\n",
  183963. + params->width, params->height);
  183964. + data = (params->band_lines == VDOAC_BAND_HEIGHT_32LINES) ? 2 :
  183965. + ((params->band_lines == VDOAC_BAND_HEIGHT_16LINES) ?
  183966. + 1 : 0);
  183967. + data |= params->scan_order ? VDOAC_SCAN_ORDER_INTERLACED : 0;
  183968. + data |= params->band_mode ? VDOAC_SYNC_BAND_MODE : 0;
  183969. + data |= params->pfs ? VDOAC_PFS_YUYV : 0;
  183970. + data |= params->ipu_num ? VDOAC_IPU_SEL_1 : 0;
  183971. + vdoa_write_register(vdoa, VDOAC, data);
  183972. +
  183973. + data = ((params->width & VDOAFP_FW_MASK) << VDOAFP_FW_SHIFT) |
  183974. + ((params->height & VDOAFP_FH_MASK) << VDOAFP_FH_SHIFT);
  183975. + vdoa_write_register(vdoa, VDOAFP, data);
  183976. +
  183977. + ipu_stride = params->pfs ? params->width << 1 : params->width;
  183978. + data = ((params->vpu_stride & VDOASL_VSLY_MASK) <<
  183979. + VDOASL_VSLY_SHIFT) |
  183980. + ((ipu_stride & VDOASL_ISLY_MASK) << VDOASL_ISLY_SHIFT);
  183981. + vdoa_write_register(vdoa, VDOASL, data);
  183982. +
  183983. + dev_dbg(vdoa->dev, "band_mode:%d, band_line:%d, base:0x%lx.\n",
  183984. + params->band_mode, params->band_lines, vdoa->iram_paddr);
  183985. + }
  183986. + /*
  183987. + * band size = (luma_per_line + chroma_per_line) * bandLines
  183988. + * = width * (3/2 or 2) * bandLines
  183989. + * double buffer mode used.
  183990. + */
  183991. + if (params->pfs)
  183992. + band_size = (params->width << 1) * params->band_lines;
  183993. + else
  183994. + band_size = ((params->width * 3) >> 1) *
  183995. + params->band_lines;
  183996. + if (params->interlaced) {
  183997. + total_band_size = 6 * band_size; /* 3 frames*double buffer */
  183998. + if (iram_size < total_band_size) {
  183999. + dev_err(vdoa->dev, "iram_size:0x%lx is smaller than "
  184000. + "request:0x%x!\n", iram_size, total_band_size);
  184001. + return -EINVAL;
  184002. + }
  184003. + if (params->vfield_buf.prev_veba) {
  184004. + if (params->band_mode) {
  184005. + vdoa_write_register(vdoa, VDOAIEBA00,
  184006. + vdoa->iram_paddr);
  184007. + vdoa_write_register(vdoa, VDOAIEBA10,
  184008. + vdoa->iram_paddr + band_size);
  184009. + } else
  184010. + vdoa_write_register(vdoa, VDOAIEBA00,
  184011. + params->ieba0);
  184012. + vdoa_write_register(vdoa, VDOAVEBA0,
  184013. + params->vfield_buf.prev_veba);
  184014. + vdoa->field = VDOA_PREV_FIELD;
  184015. + }
  184016. + if (params->vfield_buf.cur_veba) {
  184017. + if (params->band_mode) {
  184018. + vdoa_write_register(vdoa, VDOAIEBA01,
  184019. + vdoa->iram_paddr + band_size * 2);
  184020. + vdoa_write_register(vdoa, VDOAIEBA11,
  184021. + vdoa->iram_paddr + band_size * 3);
  184022. + } else
  184023. + vdoa_write_register(vdoa, VDOAIEBA01,
  184024. + params->ieba1);
  184025. + vdoa_write_register(vdoa, VDOAVEBA1,
  184026. + params->vfield_buf.cur_veba);
  184027. + vdoa->field = VDOA_CURR_FIELD;
  184028. + }
  184029. + if (params->vfield_buf.next_veba) {
  184030. + if (params->band_mode) {
  184031. + vdoa_write_register(vdoa, VDOAIEBA02,
  184032. + vdoa->iram_paddr + band_size * 4);
  184033. + vdoa_write_register(vdoa, VDOAIEBA12,
  184034. + vdoa->iram_paddr + band_size * 5);
  184035. + } else
  184036. + vdoa_write_register(vdoa, VDOAIEBA02,
  184037. + params->ieba2);
  184038. + vdoa_write_register(vdoa, VDOAVEBA2,
  184039. + params->vfield_buf.next_veba);
  184040. + vdoa->field = VDOA_NEXT_FIELD;
  184041. + vdoa_read_register(vdoa, VDOAC, &data);
  184042. + data |= VDOAC_THREE_FRAMES;
  184043. + vdoa_write_register(vdoa, VDOAC, data);
  184044. + }
  184045. +
  184046. + if (!params->pfs)
  184047. + vdoa_write_register(vdoa, VDOAIUBO,
  184048. + params->width * params->band_lines);
  184049. + vdoa_write_register(vdoa, VDOAVUBO,
  184050. + params->vfield_buf.vubo);
  184051. + dev_dbg(vdoa->dev, "total band_size:0x%x.\n", band_size*6);
  184052. + } else if (params->band_mode) {
  184053. + /* used for progressive frame resize on PrP channel */
  184054. + BUG(); /* currently not support */
  184055. + /* progressvie frame: band mode */
  184056. + vdoa_write_register(vdoa, VDOAIEBA00, vdoa->iram_paddr);
  184057. + vdoa_write_register(vdoa, VDOAIEBA10,
  184058. + vdoa->iram_paddr + band_size);
  184059. + if (!params->pfs)
  184060. + vdoa_write_register(vdoa, VDOAIUBO,
  184061. + params->width * params->band_lines);
  184062. + dev_dbg(vdoa->dev, "total band_size:0x%x\n", band_size*2);
  184063. + } else {
  184064. + /* progressive frame: mem->mem, non-band mode */
  184065. + vdoa->field = VDOA_FRAME;
  184066. + vdoa_write_register(vdoa, VDOAVEBA0, params->vframe_buf.veba);
  184067. + vdoa_write_register(vdoa, VDOAVUBO, params->vframe_buf.vubo);
  184068. + vdoa_write_register(vdoa, VDOAIEBA00, params->ieba0);
  184069. + if (!params->pfs)
  184070. + /* note: iubo is relative value, based on ieba0 */
  184071. + vdoa_write_register(vdoa, VDOAIUBO,
  184072. + params->width * params->height);
  184073. + }
  184074. + vdoa->state = VDOA_SETUP;
  184075. + return 0;
  184076. +}
  184077. +
  184078. +void vdoa_get_output_buf(vdoa_handle_t handle, struct vdoa_ipu_buf *buf)
  184079. +{
  184080. + u32 data;
  184081. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  184082. +
  184083. + CHECK_NULL_PTR(vdoa);
  184084. + CHECK_STATE(VDOA_SETUP, return);
  184085. + vdoa->state = VDOA_GET_OBUF;
  184086. + memset(buf, 0, sizeof(*buf));
  184087. +
  184088. + vdoa_read_register(vdoa, VDOAC, &data);
  184089. + switch (vdoa->field) {
  184090. + case VDOA_FRAME:
  184091. + case VDOA_PREV_FIELD:
  184092. + vdoa_read_register(vdoa, VDOAIEBA00, &buf->ieba0);
  184093. + if (data & VDOAC_SYNC_BAND_MODE)
  184094. + vdoa_read_register(vdoa, VDOAIEBA10, &buf->ieba1);
  184095. + break;
  184096. + case VDOA_CURR_FIELD:
  184097. + vdoa_read_register(vdoa, VDOAIEBA01, &buf->ieba0);
  184098. + vdoa_read_register(vdoa, VDOAIEBA11, &buf->ieba1);
  184099. + break;
  184100. + case VDOA_NEXT_FIELD:
  184101. + vdoa_read_register(vdoa, VDOAIEBA02, &buf->ieba0);
  184102. + vdoa_read_register(vdoa, VDOAIEBA12, &buf->ieba1);
  184103. + break;
  184104. + default:
  184105. + BUG();
  184106. + break;
  184107. + }
  184108. + if (!(data & VDOAC_PFS_YUYV))
  184109. + vdoa_read_register(vdoa, VDOAIUBO, &buf->iubo);
  184110. +}
  184111. +
  184112. +int vdoa_start(vdoa_handle_t handle, int timeout_ms)
  184113. +{
  184114. + int ret;
  184115. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  184116. +
  184117. + CHECK_NULL_PTR(vdoa);
  184118. + CHECK_STATE(VDOA_GET_OBUF, return -EINVAL);
  184119. + vdoa->state = VDOA_START;
  184120. + init_completion(&vdoa->comp);
  184121. + vdoa_write_register(vdoa, VDOAIST,
  184122. + VDOAIEIST_TRANSFER_ERR | VDOAIEIST_TRANSFER_END);
  184123. + vdoa_write_register(vdoa, VDOAIE,
  184124. + VDOAIEIST_TRANSFER_ERR | VDOAIEIST_TRANSFER_END);
  184125. +
  184126. + enable_irq(vdoa->irq);
  184127. + vdoa_write_register(vdoa, VDOASRR, VDOASRR_START_XFER);
  184128. + dump_registers(vdoa);
  184129. +
  184130. + ret = wait_for_completion_timeout(&vdoa->comp,
  184131. + msecs_to_jiffies(timeout_ms));
  184132. +
  184133. + return ret > 0 ? 0 : -ETIMEDOUT;
  184134. +}
  184135. +
  184136. +void vdoa_stop(vdoa_handle_t handle)
  184137. +{
  184138. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  184139. +
  184140. + CHECK_NULL_PTR(vdoa);
  184141. + CHECK_STATE(VDOA_GET | VDOA_START | VDOA_INIRQ, return);
  184142. + vdoa->state = VDOA_STOP;
  184143. +
  184144. + disable_irq(vdoa->irq);
  184145. +
  184146. + vdoa_write_register(vdoa, VDOASRR, VDOASRR_SWRST);
  184147. +}
  184148. +
  184149. +void vdoa_get_handle(vdoa_handle_t *handle)
  184150. +{
  184151. + struct vdoa_info *vdoa = g_vdoa;
  184152. +
  184153. + CHECK_NULL_PTR(handle);
  184154. + *handle = (vdoa_handle_t *)NULL;
  184155. + CHECK_STATE(VDOA_INIT, return);
  184156. + mutex_lock(&vdoa_lock);
  184157. + clk_prepare_enable(vdoa->vdoa_clk);
  184158. + vdoa->state = VDOA_GET;
  184159. + vdoa->field = VDOA_NULL;
  184160. + vdoa_write_register(vdoa, VDOASRR, VDOASRR_SWRST);
  184161. +
  184162. + *handle = (vdoa_handle_t *)vdoa;
  184163. +}
  184164. +
  184165. +void vdoa_put_handle(vdoa_handle_t *handle)
  184166. +{
  184167. + struct vdoa_info *vdoa = (struct vdoa_info *)(*handle);
  184168. +
  184169. + CHECK_NULL_PTR(vdoa);
  184170. + CHECK_STATE(VDOA_STOP, return);
  184171. + if (vdoa != g_vdoa)
  184172. + BUG();
  184173. +
  184174. + clk_disable_unprepare(vdoa->vdoa_clk);
  184175. + vdoa->state = VDOA_PUT;
  184176. + *handle = (vdoa_handle_t *)NULL;
  184177. + mutex_unlock(&vdoa_lock);
  184178. +}
  184179. +
  184180. +static irqreturn_t vdoa_irq_handler(int irq, void *data)
  184181. +{
  184182. + u32 status, mask, val;
  184183. + struct vdoa_info *vdoa = data;
  184184. +
  184185. + CHECK_NULL_PTR(vdoa);
  184186. + CHECK_STATE(VDOA_START, return IRQ_HANDLED);
  184187. + vdoa->state = VDOA_INIRQ;
  184188. + vdoa_read_register(vdoa, VDOAIST, &status);
  184189. + vdoa_read_register(vdoa, VDOAIE, &mask);
  184190. + val = status & mask;
  184191. + vdoa_write_register(vdoa, VDOAIST, val);
  184192. + if (VDOAIEIST_TRANSFER_ERR & val)
  184193. + dev_err(vdoa->dev, "vdoa Transfer err irq!\n");
  184194. + if (VDOAIEIST_TRANSFER_END & val)
  184195. + dev_dbg(vdoa->dev, "vdoa Transfer end irq!\n");
  184196. + if (0 == val) {
  184197. + dev_err(vdoa->dev, "vdoa unknown irq!\n");
  184198. + BUG();
  184199. + }
  184200. +
  184201. + complete(&vdoa->comp);
  184202. + return IRQ_HANDLED;
  184203. +}
  184204. +
  184205. +/* IRAM Size in Kbytes, example:vdoa_iram_size=64, 64KBytes */
  184206. +static int __init vdoa_iram_size_setup(char *options)
  184207. +{
  184208. + int ret;
  184209. +
  184210. + ret = strict_strtoul(options, 0, &iram_size);
  184211. + if (ret)
  184212. + iram_size = 0;
  184213. + else
  184214. + iram_size *= SZ_1K;
  184215. +
  184216. + return 1;
  184217. +}
  184218. +__setup("vdoa_iram_size=", vdoa_iram_size_setup);
  184219. +
  184220. +static const struct of_device_id imx_vdoa_dt_ids[] = {
  184221. + { .compatible = "fsl,imx6q-vdoa", },
  184222. + { /* sentinel */ }
  184223. +};
  184224. +
  184225. +static int vdoa_probe(struct platform_device *pdev)
  184226. +{
  184227. + int ret;
  184228. + struct vdoa_info *vdoa;
  184229. + struct resource *res;
  184230. + struct resource *res_irq;
  184231. + struct device *dev = &pdev->dev;
  184232. + struct device_node *np = pdev->dev.of_node;
  184233. +
  184234. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  184235. + if (!res) {
  184236. + dev_err(dev, "can't get device resources\n");
  184237. + return -ENOENT;
  184238. + }
  184239. +
  184240. + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  184241. + if (!res_irq) {
  184242. + dev_err(dev, "failed to get irq resource\n");
  184243. + return -ENOENT;
  184244. + }
  184245. +
  184246. + vdoa = devm_kzalloc(dev, sizeof(struct vdoa_info), GFP_KERNEL);
  184247. + if (!vdoa)
  184248. + return -ENOMEM;
  184249. + vdoa->dev = dev;
  184250. +
  184251. + vdoa->reg_base = devm_request_and_ioremap(&pdev->dev, res);
  184252. + if (!vdoa->reg_base)
  184253. + return -EBUSY;
  184254. +
  184255. + vdoa->irq = res_irq->start;
  184256. + ret = devm_request_irq(dev, vdoa->irq, vdoa_irq_handler, 0,
  184257. + "vdoa", vdoa);
  184258. + if (ret) {
  184259. + dev_err(dev, "can't claim irq %d\n", vdoa->irq);
  184260. + return ret;
  184261. + }
  184262. + disable_irq(vdoa->irq);
  184263. +
  184264. + vdoa->vdoa_clk = devm_clk_get(dev, NULL);
  184265. + if (IS_ERR(vdoa->vdoa_clk)) {
  184266. + dev_err(dev, "failed to get vdoa_clk\n");
  184267. + return PTR_ERR(vdoa->vdoa_clk);
  184268. + }
  184269. +
  184270. + vdoa->iram_pool = of_get_named_gen_pool(np, "iram", 0);
  184271. + if (!vdoa->iram_pool) {
  184272. + dev_err(&pdev->dev, "iram pool not available\n");
  184273. + return -ENOMEM;
  184274. + }
  184275. +
  184276. + if ((iram_size == 0) || (iram_size > MAX_VDOA_IRAM_SIZE))
  184277. + iram_size = VDOA_IRAM_SIZE;
  184278. +
  184279. + vdoa->iram_base = gen_pool_alloc(vdoa->iram_pool, iram_size);
  184280. + if (!vdoa->iram_base) {
  184281. + dev_err(&pdev->dev, "unable to alloc iram\n");
  184282. + return -ENOMEM;
  184283. + }
  184284. +
  184285. + vdoa->iram_paddr = gen_pool_virt_to_phys(vdoa->iram_pool,
  184286. + vdoa->iram_base);
  184287. +
  184288. + dev_dbg(dev, "iram_base:0x%lx,iram_paddr:0x%lx,size:0x%lx\n",
  184289. + vdoa->iram_base, vdoa->iram_paddr, iram_size);
  184290. +
  184291. + vdoa->state = VDOA_INIT;
  184292. + dev_set_drvdata(dev, vdoa);
  184293. + g_vdoa = vdoa;
  184294. + dev_info(dev, "i.MX Video Data Order Adapter(VDOA) driver probed\n");
  184295. + return 0;
  184296. +}
  184297. +
  184298. +static int vdoa_remove(struct platform_device *pdev)
  184299. +{
  184300. + struct vdoa_info *vdoa = dev_get_drvdata(&pdev->dev);
  184301. +
  184302. + gen_pool_free(vdoa->iram_pool, vdoa->iram_base, iram_size);
  184303. + kfree(vdoa);
  184304. + dev_set_drvdata(&pdev->dev, NULL);
  184305. +
  184306. + return 0;
  184307. +}
  184308. +
  184309. +static struct platform_driver vdoa_driver = {
  184310. + .driver = {
  184311. + .name = "mxc_vdoa",
  184312. + .of_match_table = imx_vdoa_dt_ids,
  184313. + },
  184314. + .probe = vdoa_probe,
  184315. + .remove = vdoa_remove,
  184316. +};
  184317. +
  184318. +static int __init vdoa_init(void)
  184319. +{
  184320. + int err;
  184321. +
  184322. + err = platform_driver_register(&vdoa_driver);
  184323. + if (err) {
  184324. + pr_err("vdoa_driver register failed\n");
  184325. + return -ENODEV;
  184326. + }
  184327. + return 0;
  184328. +}
  184329. +
  184330. +static void __exit vdoa_cleanup(void)
  184331. +{
  184332. + platform_driver_unregister(&vdoa_driver);
  184333. +}
  184334. +
  184335. +module_init(vdoa_init);
  184336. +module_exit(vdoa_cleanup);
  184337. +
  184338. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  184339. +MODULE_DESCRIPTION("i.MX Video Data Order Adapter(VDOA) driver");
  184340. +MODULE_LICENSE("GPL");
  184341. diff -Nur linux-3.14.14/drivers/mxc/ipu3/vdoa.h linux-imx6-3.14/drivers/mxc/ipu3/vdoa.h
  184342. --- linux-3.14.14/drivers/mxc/ipu3/vdoa.h 1969-12-31 18:00:00.000000000 -0600
  184343. +++ linux-imx6-3.14/drivers/mxc/ipu3/vdoa.h 2014-12-08 00:31:53.476418001 -0600
  184344. @@ -0,0 +1,69 @@
  184345. +/*
  184346. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  184347. + *
  184348. + * This program is free software; you can redistribute it and/or modify
  184349. + * it under the terms of the GNU General Public License as published by
  184350. + * the Free Software Foundation; either version 2 of the License, or
  184351. + * (at your option) any later version.
  184352. +
  184353. + * This program is distributed in the hope that it will be useful,
  184354. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  184355. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  184356. + * GNU General Public License for more details.
  184357. +
  184358. + * You should have received a copy of the GNU General Public License along
  184359. + * with this program; if not, write to the Free Software Foundation, Inc.,
  184360. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  184361. + */
  184362. +
  184363. +#ifndef __VDOA_H__
  184364. +#define __VDOA_H__
  184365. +
  184366. +#define VDOA_PFS_YUYV (1)
  184367. +#define VDOA_PFS_NV12 (0)
  184368. +
  184369. +
  184370. +struct vfield_buf {
  184371. + u32 prev_veba;
  184372. + u32 cur_veba;
  184373. + u32 next_veba;
  184374. + u32 vubo;
  184375. +};
  184376. +
  184377. +struct vframe_buf {
  184378. + u32 veba;
  184379. + u32 vubo;
  184380. +};
  184381. +
  184382. +struct vdoa_params {
  184383. + u32 width;
  184384. + u32 height;
  184385. + int vpu_stride;
  184386. + int interlaced;
  184387. + int scan_order;
  184388. + int ipu_num;
  184389. + int band_lines;
  184390. + int band_mode;
  184391. + int pfs;
  184392. + u32 ieba0;
  184393. + u32 ieba1;
  184394. + u32 ieba2;
  184395. + struct vframe_buf vframe_buf;
  184396. + struct vfield_buf vfield_buf;
  184397. +};
  184398. +struct vdoa_ipu_buf {
  184399. + u32 ieba0;
  184400. + u32 ieba1;
  184401. + u32 iubo;
  184402. +};
  184403. +
  184404. +struct vdoa_info;
  184405. +typedef void *vdoa_handle_t;
  184406. +
  184407. +int vdoa_setup(vdoa_handle_t handle, struct vdoa_params *params);
  184408. +void vdoa_get_output_buf(vdoa_handle_t handle, struct vdoa_ipu_buf *buf);
  184409. +int vdoa_start(vdoa_handle_t handle, int timeout_ms);
  184410. +void vdoa_stop(vdoa_handle_t handle);
  184411. +void vdoa_get_handle(vdoa_handle_t *handle);
  184412. +void vdoa_put_handle(vdoa_handle_t *handle);
  184413. +#endif
  184414. diff -Nur linux-3.14.14/drivers/mxc/Kconfig linux-imx6-3.14/drivers/mxc/Kconfig
  184415. --- linux-3.14.14/drivers/mxc/Kconfig 1969-12-31 18:00:00.000000000 -0600
  184416. +++ linux-imx6-3.14/drivers/mxc/Kconfig 2014-12-08 00:31:53.460418001 -0600
  184417. @@ -0,0 +1,24 @@
  184418. +# drivers/mxc/Kconfig
  184419. +
  184420. +if ARCH_MXC
  184421. +
  184422. +menu "MXC support drivers"
  184423. +
  184424. +config MXC_IPU
  184425. + bool "Image Processing Unit Driver"
  184426. + select MXC_IPU_V3
  184427. + help
  184428. + If you plan to use the Image Processing unit, say
  184429. + Y here. IPU is needed by Framebuffer and V4L2 drivers.
  184430. +
  184431. +source "drivers/mxc/gpu-viv/Kconfig"
  184432. +source "drivers/mxc/ipu3/Kconfig"
  184433. +source "drivers/mxc/asrc/Kconfig"
  184434. +source "drivers/mxc/vpu/Kconfig"
  184435. +source "drivers/mxc/hdmi-cec/Kconfig"
  184436. +source "drivers/mxc/mipi/Kconfig"
  184437. +source "drivers/mxc/mlb/Kconfig"
  184438. +
  184439. +endmenu
  184440. +
  184441. +endif
  184442. diff -Nur linux-3.14.14/drivers/mxc/Makefile linux-imx6-3.14/drivers/mxc/Makefile
  184443. --- linux-3.14.14/drivers/mxc/Makefile 1969-12-31 18:00:00.000000000 -0600
  184444. +++ linux-imx6-3.14/drivers/mxc/Makefile 2014-12-08 00:31:53.460418001 -0600
  184445. @@ -0,0 +1,7 @@
  184446. +obj-$(CONFIG_MXC_GPU_VIV) += gpu-viv/
  184447. +obj-$(CONFIG_MXC_IPU_V3) += ipu3/
  184448. +obj-$(CONFIG_MXC_ASRC) += asrc/
  184449. +obj-$(CONFIG_MXC_VPU) += vpu/
  184450. +obj-$(CONFIG_MXC_HDMI_CEC) += hdmi-cec/
  184451. +obj-$(CONFIG_MXC_MIPI_CSI2) += mipi/
  184452. +obj-$(CONFIG_MXC_MLB) += mlb/
  184453. diff -Nur linux-3.14.14/drivers/mxc/mipi/Kconfig linux-imx6-3.14/drivers/mxc/mipi/Kconfig
  184454. --- linux-3.14.14/drivers/mxc/mipi/Kconfig 1969-12-31 18:00:00.000000000 -0600
  184455. +++ linux-imx6-3.14/drivers/mxc/mipi/Kconfig 2014-12-08 00:31:53.476418001 -0600
  184456. @@ -0,0 +1,14 @@
  184457. +#
  184458. +# MIPI configuration
  184459. +#
  184460. +
  184461. +menu "MXC MIPI Support"
  184462. +
  184463. +config MXC_MIPI_CSI2
  184464. + tristate "MIPI CSI2 support"
  184465. + depends on SOC_IMX6Q
  184466. + default n
  184467. + ---help---
  184468. + Say Y to get the MIPI CSI2 support.
  184469. +
  184470. +endmenu
  184471. diff -Nur linux-3.14.14/drivers/mxc/mipi/Makefile linux-imx6-3.14/drivers/mxc/mipi/Makefile
  184472. --- linux-3.14.14/drivers/mxc/mipi/Makefile 1969-12-31 18:00:00.000000000 -0600
  184473. +++ linux-imx6-3.14/drivers/mxc/mipi/Makefile 2014-12-08 00:31:53.476418001 -0600
  184474. @@ -0,0 +1,4 @@
  184475. +#
  184476. +# Makefile for the mipi interface driver
  184477. +#
  184478. +obj-$(CONFIG_MXC_MIPI_CSI2) += mxc_mipi_csi2.o
  184479. diff -Nur linux-3.14.14/drivers/mxc/mipi/mxc_mipi_csi2.c linux-imx6-3.14/drivers/mxc/mipi/mxc_mipi_csi2.c
  184480. --- linux-3.14.14/drivers/mxc/mipi/mxc_mipi_csi2.c 1969-12-31 18:00:00.000000000 -0600
  184481. +++ linux-imx6-3.14/drivers/mxc/mipi/mxc_mipi_csi2.c 2014-12-08 00:31:53.476418001 -0600
  184482. @@ -0,0 +1,540 @@
  184483. +/*
  184484. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  184485. + *
  184486. + * This program is free software; you can redistribute it and/or modify
  184487. + * it under the terms of the GNU General Public License as published by
  184488. + * the Free Software Foundation; either version 2 of the License, or
  184489. + * (at your option) any later version.
  184490. +
  184491. + * This program is distributed in the hope that it will be useful,
  184492. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  184493. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  184494. + * GNU General Public License for more details.
  184495. +
  184496. + * You should have received a copy of the GNU General Public License along
  184497. + * with this program; if not, write to the Free Software Foundation, Inc.,
  184498. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  184499. + */
  184500. +
  184501. +#include <linux/module.h>
  184502. +#include <linux/types.h>
  184503. +#include <linux/interrupt.h>
  184504. +#include <linux/irq.h>
  184505. +#include <linux/irqdesc.h>
  184506. +#include <linux/init.h>
  184507. +#include <linux/platform_device.h>
  184508. +#include <linux/err.h>
  184509. +#include <linux/clk.h>
  184510. +#include <linux/console.h>
  184511. +#include <linux/io.h>
  184512. +#include <linux/bitops.h>
  184513. +#include <linux/delay.h>
  184514. +#include <linux/fsl_devices.h>
  184515. +#include <linux/slab.h>
  184516. +#include <linux/of.h>
  184517. +
  184518. +#include <linux/mipi_csi2.h>
  184519. +
  184520. +#include "mxc_mipi_csi2.h"
  184521. +
  184522. +static struct mipi_csi2_info *gmipi_csi2;
  184523. +
  184524. +void _mipi_csi2_lock(struct mipi_csi2_info *info)
  184525. +{
  184526. + if (!in_irq() && !in_softirq())
  184527. + mutex_lock(&info->mutex_lock);
  184528. +}
  184529. +
  184530. +void _mipi_csi2_unlock(struct mipi_csi2_info *info)
  184531. +{
  184532. + if (!in_irq() && !in_softirq())
  184533. + mutex_unlock(&info->mutex_lock);
  184534. +}
  184535. +
  184536. +static inline void mipi_csi2_write(struct mipi_csi2_info *info,
  184537. + unsigned value, unsigned offset)
  184538. +{
  184539. + writel(value, info->mipi_csi2_base + offset);
  184540. +}
  184541. +
  184542. +static inline unsigned int mipi_csi2_read(struct mipi_csi2_info *info,
  184543. + unsigned offset)
  184544. +{
  184545. + return readl(info->mipi_csi2_base + offset);
  184546. +}
  184547. +
  184548. +/*!
  184549. + * This function is called to enable the mipi csi2 interface.
  184550. + *
  184551. + * @param info mipi csi2 hander
  184552. + * @return Returns setted value
  184553. + */
  184554. +bool mipi_csi2_enable(struct mipi_csi2_info *info)
  184555. +{
  184556. + bool status;
  184557. +
  184558. + _mipi_csi2_lock(info);
  184559. +
  184560. + if (!info->mipi_en) {
  184561. + info->mipi_en = true;
  184562. + clk_prepare_enable(info->cfg_clk);
  184563. + clk_prepare_enable(info->dphy_clk);
  184564. + } else
  184565. + mipi_dbg("mipi csi2 already enabled!\n");
  184566. +
  184567. + status = info->mipi_en;
  184568. +
  184569. + _mipi_csi2_unlock(info);
  184570. +
  184571. + return status;
  184572. +}
  184573. +EXPORT_SYMBOL(mipi_csi2_enable);
  184574. +
  184575. +/*!
  184576. + * This function is called to disable the mipi csi2 interface.
  184577. + *
  184578. + * @param info mipi csi2 hander
  184579. + * @return Returns setted value
  184580. + */
  184581. +bool mipi_csi2_disable(struct mipi_csi2_info *info)
  184582. +{
  184583. + bool status;
  184584. +
  184585. + _mipi_csi2_lock(info);
  184586. +
  184587. + if (info->mipi_en) {
  184588. + info->mipi_en = false;
  184589. + clk_disable_unprepare(info->dphy_clk);
  184590. + clk_disable_unprepare(info->cfg_clk);
  184591. + } else
  184592. + mipi_dbg("mipi csi2 already disabled!\n");
  184593. +
  184594. + status = info->mipi_en;
  184595. +
  184596. + _mipi_csi2_unlock(info);
  184597. +
  184598. + return status;
  184599. +}
  184600. +EXPORT_SYMBOL(mipi_csi2_disable);
  184601. +
  184602. +/*!
  184603. + * This function is called to get mipi csi2 disable/enable status.
  184604. + *
  184605. + * @param info mipi csi2 hander
  184606. + * @return Returns mipi csi2 status
  184607. + */
  184608. +bool mipi_csi2_get_status(struct mipi_csi2_info *info)
  184609. +{
  184610. + bool status;
  184611. +
  184612. + _mipi_csi2_lock(info);
  184613. + status = info->mipi_en;
  184614. + _mipi_csi2_unlock(info);
  184615. +
  184616. + return status;
  184617. +}
  184618. +EXPORT_SYMBOL(mipi_csi2_get_status);
  184619. +
  184620. +/*!
  184621. + * This function is called to set mipi lanes.
  184622. + *
  184623. + * @param info mipi csi2 hander
  184624. + * @return Returns setted value
  184625. + */
  184626. +unsigned int mipi_csi2_set_lanes(struct mipi_csi2_info *info)
  184627. +{
  184628. + unsigned int lanes;
  184629. +
  184630. + _mipi_csi2_lock(info);
  184631. + mipi_csi2_write(info, info->lanes - 1, MIPI_CSI2_N_LANES);
  184632. + lanes = mipi_csi2_read(info, MIPI_CSI2_N_LANES);
  184633. + _mipi_csi2_unlock(info);
  184634. +
  184635. + return lanes;
  184636. +}
  184637. +EXPORT_SYMBOL(mipi_csi2_set_lanes);
  184638. +
  184639. +/*!
  184640. + * This function is called to set mipi data type.
  184641. + *
  184642. + * @param info mipi csi2 hander
  184643. + * @return Returns setted value
  184644. + */
  184645. +unsigned int mipi_csi2_set_datatype(struct mipi_csi2_info *info,
  184646. + unsigned int datatype)
  184647. +{
  184648. + unsigned int dtype;
  184649. +
  184650. + _mipi_csi2_lock(info);
  184651. + info->datatype = datatype;
  184652. + dtype = info->datatype;
  184653. + _mipi_csi2_unlock(info);
  184654. +
  184655. + return dtype;
  184656. +}
  184657. +EXPORT_SYMBOL(mipi_csi2_set_datatype);
  184658. +
  184659. +/*!
  184660. + * This function is called to get mipi data type.
  184661. + *
  184662. + * @param info mipi csi2 hander
  184663. + * @return Returns mipi data type
  184664. + */
  184665. +unsigned int mipi_csi2_get_datatype(struct mipi_csi2_info *info)
  184666. +{
  184667. + unsigned int dtype;
  184668. +
  184669. + _mipi_csi2_lock(info);
  184670. + dtype = info->datatype;
  184671. + _mipi_csi2_unlock(info);
  184672. +
  184673. + return dtype;
  184674. +}
  184675. +EXPORT_SYMBOL(mipi_csi2_get_datatype);
  184676. +
  184677. +/*!
  184678. + * This function is called to get mipi csi2 dphy status.
  184679. + *
  184680. + * @param info mipi csi2 hander
  184681. + * @return Returns dphy status
  184682. + */
  184683. +unsigned int mipi_csi2_dphy_status(struct mipi_csi2_info *info)
  184684. +{
  184685. + unsigned int status;
  184686. +
  184687. + _mipi_csi2_lock(info);
  184688. + status = mipi_csi2_read(info, MIPI_CSI2_PHY_STATE);
  184689. + _mipi_csi2_unlock(info);
  184690. +
  184691. + return status;
  184692. +}
  184693. +EXPORT_SYMBOL(mipi_csi2_dphy_status);
  184694. +
  184695. +/*!
  184696. + * This function is called to get mipi csi2 error1 status.
  184697. + *
  184698. + * @param info mipi csi2 hander
  184699. + * @return Returns error1 value
  184700. + */
  184701. +unsigned int mipi_csi2_get_error1(struct mipi_csi2_info *info)
  184702. +{
  184703. + unsigned int err1;
  184704. +
  184705. + _mipi_csi2_lock(info);
  184706. + err1 = mipi_csi2_read(info, MIPI_CSI2_ERR1);
  184707. + _mipi_csi2_unlock(info);
  184708. +
  184709. + return err1;
  184710. +}
  184711. +EXPORT_SYMBOL(mipi_csi2_get_error1);
  184712. +
  184713. +/*!
  184714. + * This function is called to get mipi csi2 error1 status.
  184715. + *
  184716. + * @param info mipi csi2 hander
  184717. + * @return Returns error1 value
  184718. + */
  184719. +unsigned int mipi_csi2_get_error2(struct mipi_csi2_info *info)
  184720. +{
  184721. + unsigned int err2;
  184722. +
  184723. + _mipi_csi2_lock(info);
  184724. + err2 = mipi_csi2_read(info, MIPI_CSI2_ERR2);
  184725. + _mipi_csi2_unlock(info);
  184726. +
  184727. + return err2;
  184728. +}
  184729. +EXPORT_SYMBOL(mipi_csi2_get_error2);
  184730. +
  184731. +/*!
  184732. + * This function is called to enable mipi to ipu pixel clock.
  184733. + *
  184734. + * @param info mipi csi2 hander
  184735. + * @return Returns 0 on success or negative error code on fail
  184736. + */
  184737. +int mipi_csi2_pixelclk_enable(struct mipi_csi2_info *info)
  184738. +{
  184739. + return clk_prepare_enable(info->pixel_clk);
  184740. +}
  184741. +EXPORT_SYMBOL(mipi_csi2_pixelclk_enable);
  184742. +
  184743. +/*!
  184744. + * This function is called to disable mipi to ipu pixel clock.
  184745. + *
  184746. + * @param info mipi csi2 hander
  184747. + * @return Returns 0 on success or negative error code on fail
  184748. + */
  184749. +void mipi_csi2_pixelclk_disable(struct mipi_csi2_info *info)
  184750. +{
  184751. + clk_disable_unprepare(info->pixel_clk);
  184752. +}
  184753. +EXPORT_SYMBOL(mipi_csi2_pixelclk_disable);
  184754. +
  184755. +/*!
  184756. + * This function is called to power on mipi csi2.
  184757. + *
  184758. + * @param info mipi csi2 hander
  184759. + * @return Returns 0 on success or negative error code on fail
  184760. + */
  184761. +int mipi_csi2_reset(struct mipi_csi2_info *info)
  184762. +{
  184763. + _mipi_csi2_lock(info);
  184764. +
  184765. + mipi_csi2_write(info, 0x0, MIPI_CSI2_PHY_SHUTDOWNZ);
  184766. + mipi_csi2_write(info, 0x0, MIPI_CSI2_DPHY_RSTZ);
  184767. + mipi_csi2_write(info, 0x0, MIPI_CSI2_CSI2_RESETN);
  184768. +
  184769. + mipi_csi2_write(info, 0x00000001, MIPI_CSI2_PHY_TST_CTRL0);
  184770. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL1);
  184771. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
  184772. + mipi_csi2_write(info, 0x00000002, MIPI_CSI2_PHY_TST_CTRL0);
  184773. + mipi_csi2_write(info, 0x00010044, MIPI_CSI2_PHY_TST_CTRL1);
  184774. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
  184775. + mipi_csi2_write(info, 0x00000014, MIPI_CSI2_PHY_TST_CTRL1);
  184776. + mipi_csi2_write(info, 0x00000002, MIPI_CSI2_PHY_TST_CTRL0);
  184777. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
  184778. +
  184779. + mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_PHY_SHUTDOWNZ);
  184780. + mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_DPHY_RSTZ);
  184781. + mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_CSI2_RESETN);
  184782. +
  184783. + _mipi_csi2_unlock(info);
  184784. +
  184785. + return 0;
  184786. +}
  184787. +EXPORT_SYMBOL(mipi_csi2_reset);
  184788. +
  184789. +/*!
  184790. + * This function is called to get mipi csi2 info.
  184791. + *
  184792. + * @return Returns mipi csi2 info struct pointor
  184793. + */
  184794. +struct mipi_csi2_info *mipi_csi2_get_info(void)
  184795. +{
  184796. + return gmipi_csi2;
  184797. +}
  184798. +EXPORT_SYMBOL(mipi_csi2_get_info);
  184799. +
  184800. +/*!
  184801. + * This function is called to get mipi csi2 bind ipu num.
  184802. + *
  184803. + * @return Returns mipi csi2 bind ipu num
  184804. + */
  184805. +int mipi_csi2_get_bind_ipu(struct mipi_csi2_info *info)
  184806. +{
  184807. + int ipu_id;
  184808. +
  184809. + _mipi_csi2_lock(info);
  184810. + ipu_id = info->ipu_id;
  184811. + _mipi_csi2_unlock(info);
  184812. +
  184813. + return ipu_id;
  184814. +}
  184815. +EXPORT_SYMBOL(mipi_csi2_get_bind_ipu);
  184816. +
  184817. +/*!
  184818. + * This function is called to get mipi csi2 bind csi num.
  184819. + *
  184820. + * @return Returns mipi csi2 bind csi num
  184821. + */
  184822. +unsigned int mipi_csi2_get_bind_csi(struct mipi_csi2_info *info)
  184823. +{
  184824. + unsigned int csi_id;
  184825. +
  184826. + _mipi_csi2_lock(info);
  184827. + csi_id = info->csi_id;
  184828. + _mipi_csi2_unlock(info);
  184829. +
  184830. + return csi_id;
  184831. +}
  184832. +EXPORT_SYMBOL(mipi_csi2_get_bind_csi);
  184833. +
  184834. +/*!
  184835. + * This function is called to get mipi csi2 virtual channel.
  184836. + *
  184837. + * @return Returns mipi csi2 virtual channel num
  184838. + */
  184839. +unsigned int mipi_csi2_get_virtual_channel(struct mipi_csi2_info *info)
  184840. +{
  184841. + unsigned int v_channel;
  184842. +
  184843. + _mipi_csi2_lock(info);
  184844. + v_channel = info->v_channel;
  184845. + _mipi_csi2_unlock(info);
  184846. +
  184847. + return v_channel;
  184848. +}
  184849. +EXPORT_SYMBOL(mipi_csi2_get_virtual_channel);
  184850. +
  184851. +/**
  184852. + * This function is called by the driver framework to initialize the MIPI CSI2
  184853. + * device.
  184854. + *
  184855. + * @param pdev The device structure for the MIPI CSI2 passed in by the
  184856. + * driver framework.
  184857. + *
  184858. + * @return Returns 0 on success or negative error code on error
  184859. + */
  184860. +static int mipi_csi2_probe(struct platform_device *pdev)
  184861. +{
  184862. + struct device *dev = &pdev->dev;
  184863. + struct device_node *np = pdev->dev.of_node;
  184864. + struct resource *res;
  184865. + u32 mipi_csi2_dphy_ver;
  184866. + int ret;
  184867. +
  184868. + gmipi_csi2 = kmalloc(sizeof(struct mipi_csi2_info), GFP_KERNEL);
  184869. + if (!gmipi_csi2) {
  184870. + ret = -ENOMEM;
  184871. + goto alloc_failed;
  184872. + }
  184873. +
  184874. + ret = of_property_read_u32(np, "ipu_id", &(gmipi_csi2->ipu_id));
  184875. + if (ret) {
  184876. + dev_err(&pdev->dev, "ipu_id missing or invalid\n");
  184877. + goto err;
  184878. + }
  184879. +
  184880. + ret = of_property_read_u32(np, "csi_id", &(gmipi_csi2->csi_id));
  184881. + if (ret) {
  184882. + dev_err(&pdev->dev, "csi_id missing or invalid\n");
  184883. + goto err;
  184884. + }
  184885. +
  184886. + ret = of_property_read_u32(np, "v_channel", &(gmipi_csi2->v_channel));
  184887. + if (ret) {
  184888. + dev_err(&pdev->dev, "v_channel missing or invalid\n");
  184889. + goto err;
  184890. + }
  184891. +
  184892. + ret = of_property_read_u32(np, "lanes", &(gmipi_csi2->lanes));
  184893. + if (ret) {
  184894. + dev_err(&pdev->dev, "lanes missing or invalid\n");
  184895. + goto err;
  184896. + }
  184897. +
  184898. + if ((gmipi_csi2->ipu_id < 0) || (gmipi_csi2->ipu_id > 1) ||
  184899. + (gmipi_csi2->csi_id > 1) || (gmipi_csi2->v_channel > 3) ||
  184900. + (gmipi_csi2->lanes > 4)) {
  184901. + dev_err(&pdev->dev, "invalid param for mipi csi2!\n");
  184902. + ret = -EINVAL;
  184903. + goto err;
  184904. + }
  184905. +
  184906. + /* initialize mutex */
  184907. + mutex_init(&gmipi_csi2->mutex_lock);
  184908. +
  184909. + /* get mipi csi2 informaiton */
  184910. + gmipi_csi2->pdev = pdev;
  184911. + gmipi_csi2->mipi_en = false;
  184912. +
  184913. + gmipi_csi2->cfg_clk = devm_clk_get(dev, "cfg_clk");
  184914. + if (IS_ERR(gmipi_csi2->cfg_clk)) {
  184915. + dev_err(&pdev->dev, "failed to get cfg_clk\n");
  184916. + ret = PTR_ERR(gmipi_csi2->cfg_clk);
  184917. + goto err;
  184918. + }
  184919. +
  184920. + /* get mipi dphy clk */
  184921. + gmipi_csi2->dphy_clk = devm_clk_get(dev, "dphy_clk");
  184922. + if (IS_ERR(gmipi_csi2->dphy_clk)) {
  184923. + dev_err(&pdev->dev, "failed to get dphy pll_ref_clk\n");
  184924. + ret = PTR_ERR(gmipi_csi2->dphy_clk);
  184925. + goto err;
  184926. + }
  184927. +
  184928. + /* get mipi to ipu pixel clk */
  184929. + gmipi_csi2->pixel_clk = devm_clk_get(dev, "pixel_clk");
  184930. + if (IS_ERR(gmipi_csi2->pixel_clk)) {
  184931. + dev_err(&pdev->dev, "failed to get mipi pixel clk\n");
  184932. + ret = PTR_ERR(gmipi_csi2->pixel_clk);
  184933. + goto err;
  184934. + }
  184935. +
  184936. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  184937. + if (!res) {
  184938. + ret = -ENODEV;
  184939. + goto err;
  184940. + }
  184941. +
  184942. + /* mipi register mapping */
  184943. + gmipi_csi2->mipi_csi2_base = ioremap(res->start, PAGE_SIZE);
  184944. + if (!gmipi_csi2->mipi_csi2_base) {
  184945. + ret = -ENOMEM;
  184946. + goto err;
  184947. + }
  184948. +
  184949. + /* mipi dphy clk enable for register access */
  184950. + clk_prepare_enable(gmipi_csi2->dphy_clk);
  184951. + /* get mipi csi2 dphy version */
  184952. + mipi_csi2_dphy_ver = mipi_csi2_read(gmipi_csi2, MIPI_CSI2_VERSION);
  184953. +
  184954. + clk_disable_unprepare(gmipi_csi2->dphy_clk);
  184955. +
  184956. + platform_set_drvdata(pdev, gmipi_csi2);
  184957. +
  184958. + dev_info(&pdev->dev, "i.MX MIPI CSI2 driver probed\n");
  184959. + dev_info(&pdev->dev, "i.MX MIPI CSI2 dphy version is 0x%x\n",
  184960. + mipi_csi2_dphy_ver);
  184961. +
  184962. + return 0;
  184963. +
  184964. +err:
  184965. + kfree(gmipi_csi2);
  184966. +alloc_failed:
  184967. + dev_err(&pdev->dev, "i.MX MIPI CSI2 driver probed - error\n");
  184968. + return ret;
  184969. +}
  184970. +
  184971. +static int mipi_csi2_remove(struct platform_device *pdev)
  184972. +{
  184973. + /* unmapping mipi register */
  184974. + iounmap(gmipi_csi2->mipi_csi2_base);
  184975. +
  184976. + kfree(gmipi_csi2);
  184977. +
  184978. + dev_set_drvdata(&pdev->dev, NULL);
  184979. +
  184980. + return 0;
  184981. +}
  184982. +
  184983. +static const struct of_device_id imx_mipi_csi2_dt_ids[] = {
  184984. + { .compatible = "fsl,imx6q-mipi-csi2", },
  184985. + { /* sentinel */ }
  184986. +};
  184987. +
  184988. +static struct platform_driver mipi_csi2_driver = {
  184989. + .driver = {
  184990. + .name = "mxc_mipi_csi2",
  184991. + .of_match_table = imx_mipi_csi2_dt_ids,
  184992. + },
  184993. + .probe = mipi_csi2_probe,
  184994. + .remove = mipi_csi2_remove,
  184995. +};
  184996. +
  184997. +static int __init mipi_csi2_init(void)
  184998. +{
  184999. + int err;
  185000. +
  185001. + err = platform_driver_register(&mipi_csi2_driver);
  185002. + if (err) {
  185003. + pr_err("mipi_csi2_driver register failed\n");
  185004. + return -ENODEV;
  185005. + }
  185006. +
  185007. + pr_info("MIPI CSI2 driver module loaded\n");
  185008. +
  185009. + return 0;
  185010. +}
  185011. +
  185012. +static void __exit mipi_csi2_cleanup(void)
  185013. +{
  185014. + platform_driver_unregister(&mipi_csi2_driver);
  185015. +}
  185016. +
  185017. +subsys_initcall(mipi_csi2_init);
  185018. +module_exit(mipi_csi2_cleanup);
  185019. +
  185020. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  185021. +MODULE_DESCRIPTION("i.MX MIPI CSI2 driver");
  185022. +MODULE_LICENSE("GPL");
  185023. diff -Nur linux-3.14.14/drivers/mxc/mipi/mxc_mipi_csi2.h linux-imx6-3.14/drivers/mxc/mipi/mxc_mipi_csi2.h
  185024. --- linux-3.14.14/drivers/mxc/mipi/mxc_mipi_csi2.h 1969-12-31 18:00:00.000000000 -0600
  185025. +++ linux-imx6-3.14/drivers/mxc/mipi/mxc_mipi_csi2.h 2014-12-08 00:31:53.476418001 -0600
  185026. @@ -0,0 +1,46 @@
  185027. +/*
  185028. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  185029. + *
  185030. + * This program is free software; you can redistribute it and/or modify
  185031. + * it under the terms of the GNU General Public License as published by
  185032. + * the Free Software Foundation; either version 2 of the License, or
  185033. + * (at your option) any later version.
  185034. +
  185035. + * This program is distributed in the hope that it will be useful,
  185036. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  185037. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  185038. + * GNU General Public License for more details.
  185039. +
  185040. + * You should have received a copy of the GNU General Public License along
  185041. + * with this program; if not, write to the Free Software Foundation, Inc.,
  185042. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  185043. + */
  185044. +
  185045. +#ifndef __MXC_MIPI_CSI2_H__
  185046. +#define __MXC_MIPI_CSI2_H__
  185047. +
  185048. +#ifdef DEBUG
  185049. +#define mipi_dbg(fmt, ...) \
  185050. + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
  185051. +#else
  185052. +#define mipi_dbg(fmt, ...)
  185053. +#endif
  185054. +
  185055. +/* driver private data */
  185056. +struct mipi_csi2_info {
  185057. + bool mipi_en;
  185058. + int ipu_id;
  185059. + unsigned int csi_id;
  185060. + unsigned int v_channel;
  185061. + unsigned int lanes;
  185062. + unsigned int datatype;
  185063. + struct clk *cfg_clk;
  185064. + struct clk *dphy_clk;
  185065. + struct clk *pixel_clk;
  185066. + void __iomem *mipi_csi2_base;
  185067. + struct platform_device *pdev;
  185068. +
  185069. + struct mutex mutex_lock;
  185070. +};
  185071. +
  185072. +#endif
  185073. diff -Nur linux-3.14.14/drivers/mxc/mlb/Kconfig linux-imx6-3.14/drivers/mxc/mlb/Kconfig
  185074. --- linux-3.14.14/drivers/mxc/mlb/Kconfig 1969-12-31 18:00:00.000000000 -0600
  185075. +++ linux-imx6-3.14/drivers/mxc/mlb/Kconfig 2014-12-08 00:31:53.476418001 -0600
  185076. @@ -0,0 +1,17 @@
  185077. +#
  185078. +# MLB150 configuration
  185079. +#
  185080. +
  185081. +menu "MXC Media Local Bus Driver"
  185082. +
  185083. +config MXC_MLB
  185084. + boolean
  185085. +
  185086. +config MXC_MLB150
  185087. + tristate "MLB150 support"
  185088. + depends on SOC_IMX6Q
  185089. + select MXC_MLB
  185090. + ---help---
  185091. + Say Y to get the MLB150 support.
  185092. +
  185093. +endmenu
  185094. diff -Nur linux-3.14.14/drivers/mxc/mlb/Makefile linux-imx6-3.14/drivers/mxc/mlb/Makefile
  185095. --- linux-3.14.14/drivers/mxc/mlb/Makefile 1969-12-31 18:00:00.000000000 -0600
  185096. +++ linux-imx6-3.14/drivers/mxc/mlb/Makefile 2014-12-08 00:31:53.476418001 -0600
  185097. @@ -0,0 +1,5 @@
  185098. +#
  185099. +# Makefile for the i.MX6Q/DL MLB150 driver
  185100. +#
  185101. +
  185102. +obj-$(CONFIG_MXC_MLB150) += mxc_mlb150.o
  185103. diff -Nur linux-3.14.14/drivers/mxc/mlb/mxc_mlb150.c linux-imx6-3.14/drivers/mxc/mlb/mxc_mlb150.c
  185104. --- linux-3.14.14/drivers/mxc/mlb/mxc_mlb150.c 1969-12-31 18:00:00.000000000 -0600
  185105. +++ linux-imx6-3.14/drivers/mxc/mlb/mxc_mlb150.c 2014-12-08 00:31:53.476418001 -0600
  185106. @@ -0,0 +1,2778 @@
  185107. +/*
  185108. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  185109. + *
  185110. + * This program is free software; you can redistribute it and/or modify
  185111. + * it under the terms of the GNU General Public License as published by
  185112. + * the Free Software Foundation; either version 2 of the License, or
  185113. + * (at your option) any later version.
  185114. + *
  185115. + * This program is distributed in the hope that it will be useful,
  185116. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  185117. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  185118. + * GNU General Public License for more details.
  185119. + *
  185120. + * You should have received a copy of the GNU General Public License along
  185121. + * with this program; if not, write to the Free Software Foundation, Inc.,
  185122. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  185123. + */
  185124. +
  185125. +#include <linux/cdev.h>
  185126. +#include <linux/circ_buf.h>
  185127. +#include <linux/clk.h>
  185128. +#include <linux/delay.h>
  185129. +#include <linux/device.h>
  185130. +#include <linux/errno.h>
  185131. +#include <linux/fs.h>
  185132. +#include <linux/genalloc.h>
  185133. +#include <linux/init.h>
  185134. +#include <linux/interrupt.h>
  185135. +#include <linux/io.h>
  185136. +#include <linux/kernel.h>
  185137. +#include <linux/module.h>
  185138. +#include <linux/mxc_mlb.h>
  185139. +#include <linux/of.h>
  185140. +#include <linux/platform_device.h>
  185141. +#include <linux/poll.h>
  185142. +#include <linux/regulator/consumer.h>
  185143. +#include <linux/sched.h>
  185144. +#include <linux/slab.h>
  185145. +#include <linux/spinlock.h>
  185146. +#include <linux/uaccess.h>
  185147. +
  185148. +#define DRIVER_NAME "mxc_mlb150"
  185149. +
  185150. +/*
  185151. + * MLB module memory map registers define
  185152. + */
  185153. +#define REG_MLBC0 0x0
  185154. +#define MLBC0_MLBEN (0x1)
  185155. +#define MLBC0_MLBCLK_MASK (0x7 << 2)
  185156. +#define MLBC0_MLBCLK_SHIFT (2)
  185157. +#define MLBC0_MLBPEN (0x1 << 5)
  185158. +#define MLBC0_MLBLK (0x1 << 7)
  185159. +#define MLBC0_ASYRETRY (0x1 << 12)
  185160. +#define MLBC0_CTLRETRY (0x1 << 12)
  185161. +#define MLBC0_FCNT_MASK (0x7 << 15)
  185162. +#define MLBC0_FCNT_SHIFT (15)
  185163. +
  185164. +#define REG_MLBPC0 0x8
  185165. +#define MLBPC0_MCLKHYS (0x1 << 11)
  185166. +
  185167. +#define REG_MS0 0xC
  185168. +#define REG_MS1 0x14
  185169. +
  185170. +#define REG_MSS 0x20
  185171. +#define MSS_RSTSYSCMD (0x1)
  185172. +#define MSS_LKSYSCMD (0x1 << 1)
  185173. +#define MSS_ULKSYSCMD (0x1 << 2)
  185174. +#define MSS_CSSYSCMD (0x1 << 3)
  185175. +#define MSS_SWSYSCMD (0x1 << 4)
  185176. +#define MSS_SERVREQ (0x1 << 5)
  185177. +
  185178. +#define REG_MSD 0x24
  185179. +
  185180. +#define REG_MIEN 0x2C
  185181. +#define MIEN_ISOC_PE (0x1)
  185182. +#define MIEN_ISOC_BUFO (0x1 << 1)
  185183. +#define MIEN_SYNC_PE (0x1 << 16)
  185184. +#define MIEN_ARX_DONE (0x1 << 17)
  185185. +#define MIEN_ARX_PE (0x1 << 18)
  185186. +#define MIEN_ARX_BREAK (0x1 << 19)
  185187. +#define MIEN_ATX_DONE (0x1 << 20)
  185188. +#define MIEN_ATX_PE (0x1 << 21)
  185189. +#define MIEN_ATX_BREAK (0x1 << 22)
  185190. +#define MIEN_CRX_DONE (0x1 << 24)
  185191. +#define MIEN_CRX_PE (0x1 << 25)
  185192. +#define MIEN_CRX_BREAK (0x1 << 26)
  185193. +#define MIEN_CTX_DONE (0x1 << 27)
  185194. +#define MIEN_CTX_PE (0x1 << 28)
  185195. +#define MIEN_CTX_BREAK (0x1 << 29)
  185196. +
  185197. +#define REG_MLBPC2 0x34
  185198. +#define REG_MLBPC1 0x38
  185199. +#define MLBPC1_VAL (0x00000888)
  185200. +
  185201. +#define REG_MLBC1 0x3C
  185202. +#define MLBC1_LOCK (0x1 << 6)
  185203. +#define MLBC1_CLKM (0x1 << 7)
  185204. +#define MLBC1_NDA_MASK (0xFF << 8)
  185205. +#define MLBC1_NDA_SHIFT (8)
  185206. +
  185207. +#define REG_HCTL 0x80
  185208. +#define HCTL_RST0 (0x1)
  185209. +#define HCTL_RST1 (0x1 << 1)
  185210. +#define HCTL_EN (0x1 << 15)
  185211. +
  185212. +#define REG_HCMR0 0x88
  185213. +#define REG_HCMR1 0x8C
  185214. +#define REG_HCER0 0x90
  185215. +#define REG_HCER1 0x94
  185216. +#define REG_HCBR0 0x98
  185217. +#define REG_HCBR1 0x9C
  185218. +
  185219. +#define REG_MDAT0 0xC0
  185220. +#define REG_MDAT1 0xC4
  185221. +#define REG_MDAT2 0xC8
  185222. +#define REG_MDAT3 0xCC
  185223. +
  185224. +#define REG_MDWE0 0xD0
  185225. +#define REG_MDWE1 0xD4
  185226. +#define REG_MDWE2 0xD8
  185227. +#define REG_MDWE3 0xDC
  185228. +
  185229. +#define REG_MCTL 0xE0
  185230. +#define MCTL_XCMP (0x1)
  185231. +
  185232. +#define REG_MADR 0xE4
  185233. +#define MADR_WNR (0x1 << 31)
  185234. +#define MADR_TB (0x1 << 30)
  185235. +#define MADR_ADDR_MASK (0x7f << 8)
  185236. +#define MADR_ADDR_SHIFT (0)
  185237. +
  185238. +#define REG_ACTL 0x3C0
  185239. +#define ACTL_MPB (0x1 << 4)
  185240. +#define ACTL_DMAMODE (0x1 << 2)
  185241. +#define ACTL_SMX (0x1 << 1)
  185242. +#define ACTL_SCE (0x1)
  185243. +
  185244. +#define REG_ACSR0 0x3D0
  185245. +#define REG_ACSR1 0x3D4
  185246. +#define REG_ACMR0 0x3D8
  185247. +#define REG_ACMR1 0x3DC
  185248. +
  185249. +#define REG_CAT_MDATn(ch) (REG_MDAT0 + ((ch % 8) >> 1) * 4)
  185250. +#define REG_CAT_MDWEn(ch) (REG_MDWE0 + ((ch % 8) >> 1) * 4)
  185251. +
  185252. +#define INT_AHB0_CH_START (0)
  185253. +#define INT_AHB1_CH_START (32)
  185254. +
  185255. +#define LOGIC_CH_NUM (64)
  185256. +#define BUF_CDT_OFFSET (0x0)
  185257. +#define BUF_ADT_OFFSET (0x40)
  185258. +#define BUF_CAT_MLB_OFFSET (0x80)
  185259. +#define BUF_CAT_HBI_OFFSET (0x88)
  185260. +#define BUF_CTR_END_OFFSET (0x8F)
  185261. +
  185262. +#define CAT_MODE_RX (0x1 << 0)
  185263. +#define CAT_MODE_TX (0x1 << 1)
  185264. +#define CAT_MODE_INBOUND_DMA (0x1 << 8)
  185265. +#define CAT_MODE_OUTBOUND_DMA (0x1 << 9)
  185266. +
  185267. +#define CH_SYNC_DEFAULT_QUAD (1)
  185268. +#define CH_SYNC_MAX_QUAD (15)
  185269. +#define CH_SYNC_CDT_BUF_DEP (CH_SYNC_DEFAULT_QUAD * 4 * 4)
  185270. +#define CH_SYNC_ADT_BUF_MULTI (4)
  185271. +#define CH_SYNC_ADT_BUF_DEP (CH_SYNC_CDT_BUF_DEP * CH_SYNC_ADT_BUF_MULTI)
  185272. +#define CH_SYNC_BUF_SZ (CH_SYNC_MAX_QUAD * 4 * 4 * \
  185273. + CH_SYNC_ADT_BUF_MULTI)
  185274. +#define CH_CTRL_CDT_BUF_DEP (64)
  185275. +#define CH_CTRL_ADT_BUF_DEP (CH_CTRL_CDT_BUF_DEP)
  185276. +#define CH_CTRL_BUF_SZ (CH_CTRL_ADT_BUF_DEP)
  185277. +#define CH_ASYNC_MDP_PACKET_LEN (1024)
  185278. +#define CH_ASYNC_MEP_PACKET_LEN (1536)
  185279. +#define CH_ASYNC_CDT_BUF_DEP (CH_ASYNC_MEP_PACKET_LEN)
  185280. +#define CH_ASYNC_ADT_BUF_DEP (CH_ASYNC_CDT_BUF_DEP)
  185281. +#define CH_ASYNC_BUF_SZ (CH_ASYNC_ADT_BUF_DEP)
  185282. +#define CH_ISOC_BLK_SIZE_188 (188)
  185283. +#define CH_ISOC_BLK_SIZE_196 (196)
  185284. +#define CH_ISOC_BLK_SIZE (CH_ISOC_BLK_SIZE_188)
  185285. +#define CH_ISOC_BLK_NUM (1)
  185286. +#define CH_ISOC_CDT_BUF_DEP (CH_ISOC_BLK_SIZE * CH_ISOC_BLK_NUM)
  185287. +#define CH_ISOC_ADT_BUF_DEP (CH_ISOC_CDT_BUF_DEP)
  185288. +#define CH_ISOC_BUF_SZ (1024)
  185289. +
  185290. +#define CH_SYNC_DBR_BUF_OFFSET (0x0)
  185291. +#define CH_CTRL_DBR_BUF_OFFSET (CH_SYNC_DBR_BUF_OFFSET + \
  185292. + 2 * (CH_SYNC_MAX_QUAD * 4 * 4))
  185293. +#define CH_ASYNC_DBR_BUF_OFFSET (CH_CTRL_DBR_BUF_OFFSET + \
  185294. + 2 * CH_CTRL_CDT_BUF_DEP)
  185295. +#define CH_ISOC_DBR_BUF_OFFSET (CH_ASYNC_DBR_BUF_OFFSET + \
  185296. + 2 * CH_ASYNC_CDT_BUF_DEP)
  185297. +
  185298. +#define DBR_BUF_START 0x00000
  185299. +
  185300. +#define CDT_LEN (16)
  185301. +#define ADT_LEN (16)
  185302. +#define CAT_LEN (2)
  185303. +
  185304. +#define CDT_SZ (CDT_LEN * LOGIC_CH_NUM)
  185305. +#define ADT_SZ (ADT_LEN * LOGIC_CH_NUM)
  185306. +#define CAT_SZ (CAT_LEN * LOGIC_CH_NUM * 2)
  185307. +
  185308. +#define CDT_BASE(base) (base + BUF_CDT_OFFSET)
  185309. +#define ADT_BASE(base) (base + BUF_ADT_OFFSET)
  185310. +#define CAT_MLB_BASE(base) (base + BUF_CAT_MLB_OFFSET)
  185311. +#define CAT_HBI_BASE(base) (base + BUF_CAT_HBI_OFFSET)
  185312. +
  185313. +#define CDTn_ADDR(base, n) (base + BUF_CDT_OFFSET + n * CDT_LEN)
  185314. +#define ADTn_ADDR(base, n) (base + BUF_ADT_OFFSET + n * ADT_LEN)
  185315. +#define CATn_MLB_ADDR(base, n) (base + BUF_CAT_MLB_OFFSET + n * CAT_LEN)
  185316. +#define CATn_HBI_ADDR(base, n) (base + BUF_CAT_HBI_OFFSET + n * CAT_LEN)
  185317. +
  185318. +#define CAT_CL_SHIFT (0x0)
  185319. +#define CAT_CT_SHIFT (8)
  185320. +#define CAT_CE (0x1 << 11)
  185321. +#define CAT_RNW (0x1 << 12)
  185322. +#define CAT_MT (0x1 << 13)
  185323. +#define CAT_FCE (0x1 << 14)
  185324. +#define CAT_MFE (0x1 << 14)
  185325. +
  185326. +#define CDT_WSBC_SHIFT (14)
  185327. +#define CDT_WPC_SHIFT (11)
  185328. +#define CDT_RSBC_SHIFT (30)
  185329. +#define CDT_RPC_SHIFT (27)
  185330. +#define CDT_WPC_1_SHIFT (12)
  185331. +#define CDT_RPC_1_SHIFT (28)
  185332. +#define CDT_WPTR_SHIFT (0)
  185333. +#define CDT_SYNC_WSTS_MASK (0x0000f000)
  185334. +#define CDT_SYNC_WSTS_SHIFT (12)
  185335. +#define CDT_CTRL_ASYNC_WSTS_MASK (0x0000f000)
  185336. +#define CDT_CTRL_ASYNC_WSTS_SHIFT (12)
  185337. +#define CDT_ISOC_WSTS_MASK (0x0000e000)
  185338. +#define CDT_ISOC_WSTS_SHIFT (13)
  185339. +#define CDT_RPTR_SHIFT (16)
  185340. +#define CDT_SYNC_RSTS_MASK (0xf0000000)
  185341. +#define CDT_SYNC_RSTS_SHIFT (28)
  185342. +#define CDT_CTRL_ASYNC_RSTS_MASK (0xf0000000)
  185343. +#define CDT_CTRL_ASYNC_RSTS_SHIFT (28)
  185344. +#define CDT_ISOC_RSTS_MASK (0xe0000000)
  185345. +#define CDT_ISOC_RSTS_SHIFT (29)
  185346. +#define CDT_CTRL_ASYNC_WSTS_1 (0x1 << 14)
  185347. +#define CDT_CTRL_ASYNC_RSTS_1 (0x1 << 15)
  185348. +#define CDT_BD_SHIFT (0)
  185349. +#define CDT_BA_SHIFT (16)
  185350. +#define CDT_BS_SHIFT (0)
  185351. +#define CDT_BF_SHIFT (31)
  185352. +
  185353. +#define ADT_PG (0x1 << 13)
  185354. +#define ADT_LE (0x1 << 14)
  185355. +#define ADT_CE (0x1 << 15)
  185356. +#define ADT_BD1_SHIFT (0)
  185357. +#define ADT_ERR1 (0x1 << 13)
  185358. +#define ADT_DNE1 (0x1 << 14)
  185359. +#define ADT_RDY1 (0x1 << 15)
  185360. +#define ADT_BD2_SHIFT (16)
  185361. +#define ADT_ERR2 (0x1 << 29)
  185362. +#define ADT_DNE2 (0x1 << 30)
  185363. +#define ADT_RDY2 (0x1 << 31)
  185364. +#define ADT_BA1_SHIFT (0x0)
  185365. +#define ADT_BA2_SHIFT (0x0)
  185366. +#define ADT_PS1 (0x1 << 12)
  185367. +#define ADT_PS2 (0x1 << 28)
  185368. +#define ADT_MEP1 (0x1 << 11)
  185369. +#define ADT_MEP2 (0x1 << 27)
  185370. +
  185371. +#define MLB_MINOR_DEVICES 4
  185372. +#define MLB_CONTROL_DEV_NAME "ctrl"
  185373. +#define MLB_ASYNC_DEV_NAME "async"
  185374. +#define MLB_SYNC_DEV_NAME "sync"
  185375. +#define MLB_ISOC_DEV_NAME "isoc"
  185376. +
  185377. +#define TX_CHANNEL 0
  185378. +#define RX_CHANNEL 1
  185379. +
  185380. +#define TRANS_RING_NODES (1 << 3)
  185381. +
  185382. +enum MLB_CTYPE {
  185383. + MLB_CTYPE_SYNC,
  185384. + MLB_CTYPE_CTRL,
  185385. + MLB_CTYPE_ASYNC,
  185386. + MLB_CTYPE_ISOC,
  185387. +};
  185388. +
  185389. +enum CLK_SPEED {
  185390. + CLK_256FS,
  185391. + CLK_512FS,
  185392. + CLK_1024FS,
  185393. + CLK_2048FS,
  185394. + CLK_3072FS,
  185395. + CLK_4096FS,
  185396. + CLK_6144FS,
  185397. + CLK_8192FS,
  185398. +};
  185399. +
  185400. +struct mlb_ringbuf {
  185401. + s8 *virt_bufs[TRANS_RING_NODES];
  185402. + u32 phy_addrs[TRANS_RING_NODES];
  185403. + s32 head;
  185404. + s32 tail;
  185405. + s32 unit_size;
  185406. + s32 total_size;
  185407. + rwlock_t rb_lock ____cacheline_aligned; /* ring index lock */
  185408. +};
  185409. +
  185410. +struct mlb_channel_info {
  185411. + /* Input MLB channel address */
  185412. + u32 address;
  185413. + /* Internal AHB channel label */
  185414. + u32 cl;
  185415. + /* DBR buf head */
  185416. + u32 dbr_buf_head;
  185417. +};
  185418. +
  185419. +struct mlb_dev_info {
  185420. + /* device node name */
  185421. + const char dev_name[20];
  185422. + /* channel type */
  185423. + const unsigned int channel_type;
  185424. + /* ch fps */
  185425. + enum CLK_SPEED fps;
  185426. + /* channel info for tx/rx */
  185427. + struct mlb_channel_info channels[2];
  185428. + /* ring buffer */
  185429. + u8 *rbuf_base_virt;
  185430. + u32 rbuf_base_phy;
  185431. + struct mlb_ringbuf rx_rbuf;
  185432. + struct mlb_ringbuf tx_rbuf;
  185433. + /* exception event */
  185434. + unsigned long ex_event;
  185435. + /* tx busy indicator */
  185436. + unsigned long tx_busy;
  185437. + /* channel started up or not */
  185438. + atomic_t on;
  185439. + /* device open count */
  185440. + atomic_t opencnt;
  185441. + /* wait queue head for channel */
  185442. + wait_queue_head_t rx_wq;
  185443. + wait_queue_head_t tx_wq;
  185444. + /* TX OK */
  185445. + s32 tx_ok;
  185446. + /* spinlock for event access */
  185447. + spinlock_t event_lock;
  185448. + /*
  185449. + * Block size for isoc mode
  185450. + * This variable can be configured in ioctl
  185451. + */
  185452. + u32 isoc_blksz;
  185453. + /*
  185454. + * Quads number for sync mode
  185455. + * This variable can be confifured in ioctl
  185456. + */
  185457. + u32 sync_quad;
  185458. + /* Buffer depth in cdt */
  185459. + u32 cdt_buf_dep;
  185460. + /* Buffer depth in adt */
  185461. + u32 adt_buf_dep;
  185462. + /* Buffer size to hold data */
  185463. + u32 buf_size;
  185464. +};
  185465. +
  185466. +struct mlb_data {
  185467. + struct mlb_dev_info *devinfo;
  185468. + struct clk *clk_mlb3p;
  185469. + struct clk *clk_mlb6p;
  185470. + struct cdev cdev;
  185471. + struct class *class; /* device class */
  185472. + dev_t firstdev;
  185473. +#ifdef CONFIG_REGULATOR
  185474. + struct regulator *nvcc;
  185475. +#endif
  185476. + void __iomem *membase; /* mlb module base address */
  185477. + struct gen_pool *iram_pool;
  185478. + u32 iram_size;
  185479. + u32 irq_ahb0;
  185480. + u32 irq_ahb1;
  185481. + u32 irq_mlb;
  185482. +};
  185483. +
  185484. +/*
  185485. + * For optimization, we use fixed channel label for
  185486. + * input channels of each mode
  185487. + * SYNC: CL = 0 for RX, CL = 64 for TX
  185488. + * CTRL: CL = 1 for RX, CL = 65 for TX
  185489. + * ASYNC: CL = 2 for RX, CL = 66 for TX
  185490. + * ISOC: CL = 3 for RX, CL = 67 for TX
  185491. + */
  185492. +#define SYNC_RX_CL_AHB0 0
  185493. +#define CTRL_RX_CL_AHB0 1
  185494. +#define ASYNC_RX_CL_AHB0 2
  185495. +#define ISOC_RX_CL_AHB0 3
  185496. +#define SYNC_TX_CL_AHB0 4
  185497. +#define CTRL_TX_CL_AHB0 5
  185498. +#define ASYNC_TX_CL_AHB0 6
  185499. +#define ISOC_TX_CL_AHB0 7
  185500. +
  185501. +#define SYNC_RX_CL_AHB1 32
  185502. +#define CTRL_RX_CL_AHB1 33
  185503. +#define ASYNC_RX_CL_AHB1 34
  185504. +#define ISOC_RX_CL_AHB1 35
  185505. +#define SYNC_TX_CL_AHB1 36
  185506. +#define CTRL_TX_CL_AHB1 37
  185507. +#define ASYNC_TX_CL_AHB1 38
  185508. +#define ISOC_TX_CL_AHB1 39
  185509. +
  185510. +#define SYNC_RX_CL SYNC_RX_CL_AHB0
  185511. +#define CTRL_RX_CL CTRL_RX_CL_AHB0
  185512. +#define ASYNC_RX_CL ASYNC_RX_CL_AHB0
  185513. +#define ISOC_RX_CL ISOC_RX_CL_AHB0
  185514. +
  185515. +#define SYNC_TX_CL SYNC_TX_CL_AHB0
  185516. +#define CTRL_TX_CL CTRL_TX_CL_AHB0
  185517. +#define ASYNC_TX_CL ASYNC_TX_CL_AHB0
  185518. +#define ISOC_TX_CL ISOC_TX_CL_AHB0
  185519. +
  185520. +static struct mlb_dev_info mlb_devinfo[MLB_MINOR_DEVICES] = {
  185521. + {
  185522. + .dev_name = MLB_SYNC_DEV_NAME,
  185523. + .channel_type = MLB_CTYPE_SYNC,
  185524. + .channels = {
  185525. + [0] = {
  185526. + .cl = SYNC_TX_CL,
  185527. + .dbr_buf_head = CH_SYNC_DBR_BUF_OFFSET,
  185528. + },
  185529. + [1] = {
  185530. + .cl = SYNC_RX_CL,
  185531. + .dbr_buf_head = CH_SYNC_DBR_BUF_OFFSET
  185532. + + CH_SYNC_BUF_SZ,
  185533. + },
  185534. + },
  185535. + .rx_rbuf = {
  185536. + .unit_size = CH_SYNC_BUF_SZ,
  185537. + .rb_lock =
  185538. + __RW_LOCK_UNLOCKED(mlb_devinfo[0].rx_rbuf.rb_lock),
  185539. + },
  185540. + .tx_rbuf = {
  185541. + .unit_size = CH_SYNC_BUF_SZ,
  185542. + .rb_lock =
  185543. + __RW_LOCK_UNLOCKED(mlb_devinfo[0].tx_rbuf.rb_lock),
  185544. + },
  185545. + .cdt_buf_dep = CH_SYNC_CDT_BUF_DEP,
  185546. + .adt_buf_dep = CH_SYNC_ADT_BUF_DEP,
  185547. + .buf_size = CH_SYNC_BUF_SZ,
  185548. + .on = ATOMIC_INIT(0),
  185549. + .opencnt = ATOMIC_INIT(0),
  185550. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[0].event_lock),
  185551. + },
  185552. + {
  185553. + .dev_name = MLB_CONTROL_DEV_NAME,
  185554. + .channel_type = MLB_CTYPE_CTRL,
  185555. + .channels = {
  185556. + [0] = {
  185557. + .cl = CTRL_TX_CL,
  185558. + .dbr_buf_head = CH_CTRL_DBR_BUF_OFFSET,
  185559. + },
  185560. + [1] = {
  185561. + .cl = CTRL_RX_CL,
  185562. + .dbr_buf_head = CH_CTRL_DBR_BUF_OFFSET
  185563. + + CH_CTRL_BUF_SZ,
  185564. + },
  185565. + },
  185566. + .rx_rbuf = {
  185567. + .unit_size = CH_CTRL_BUF_SZ,
  185568. + .rb_lock =
  185569. + __RW_LOCK_UNLOCKED(mlb_devinfo[1].rx_rbuf.rb_lock),
  185570. + },
  185571. + .tx_rbuf = {
  185572. + .unit_size = CH_CTRL_BUF_SZ,
  185573. + .rb_lock =
  185574. + __RW_LOCK_UNLOCKED(mlb_devinfo[1].tx_rbuf.rb_lock),
  185575. + },
  185576. + .cdt_buf_dep = CH_CTRL_CDT_BUF_DEP,
  185577. + .adt_buf_dep = CH_CTRL_ADT_BUF_DEP,
  185578. + .buf_size = CH_CTRL_BUF_SZ,
  185579. + .on = ATOMIC_INIT(0),
  185580. + .opencnt = ATOMIC_INIT(0),
  185581. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[1].event_lock),
  185582. + },
  185583. + {
  185584. + .dev_name = MLB_ASYNC_DEV_NAME,
  185585. + .channel_type = MLB_CTYPE_ASYNC,
  185586. + .channels = {
  185587. + [0] = {
  185588. + .cl = ASYNC_TX_CL,
  185589. + .dbr_buf_head = CH_ASYNC_DBR_BUF_OFFSET,
  185590. + },
  185591. + [1] = {
  185592. + .cl = ASYNC_RX_CL,
  185593. + .dbr_buf_head = CH_ASYNC_DBR_BUF_OFFSET
  185594. + + CH_ASYNC_BUF_SZ,
  185595. + },
  185596. + },
  185597. + .rx_rbuf = {
  185598. + .unit_size = CH_ASYNC_BUF_SZ,
  185599. + .rb_lock =
  185600. + __RW_LOCK_UNLOCKED(mlb_devinfo[2].rx_rbuf.rb_lock),
  185601. + },
  185602. + .tx_rbuf = {
  185603. + .unit_size = CH_ASYNC_BUF_SZ,
  185604. + .rb_lock =
  185605. + __RW_LOCK_UNLOCKED(mlb_devinfo[2].tx_rbuf.rb_lock),
  185606. + },
  185607. + .cdt_buf_dep = CH_ASYNC_CDT_BUF_DEP,
  185608. + .adt_buf_dep = CH_ASYNC_ADT_BUF_DEP,
  185609. + .buf_size = CH_ASYNC_BUF_SZ,
  185610. + .on = ATOMIC_INIT(0),
  185611. + .opencnt = ATOMIC_INIT(0),
  185612. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[2].event_lock),
  185613. + },
  185614. + {
  185615. + .dev_name = MLB_ISOC_DEV_NAME,
  185616. + .channel_type = MLB_CTYPE_ISOC,
  185617. + .channels = {
  185618. + [0] = {
  185619. + .cl = ISOC_TX_CL,
  185620. + .dbr_buf_head = CH_ISOC_DBR_BUF_OFFSET,
  185621. + },
  185622. + [1] = {
  185623. + .cl = ISOC_RX_CL,
  185624. + .dbr_buf_head = CH_ISOC_DBR_BUF_OFFSET
  185625. + + CH_ISOC_BUF_SZ,
  185626. + },
  185627. + },
  185628. + .rx_rbuf = {
  185629. + .unit_size = CH_ISOC_BUF_SZ,
  185630. + .rb_lock =
  185631. + __RW_LOCK_UNLOCKED(mlb_devinfo[3].rx_rbuf.rb_lock),
  185632. + },
  185633. + .tx_rbuf = {
  185634. + .unit_size = CH_ISOC_BUF_SZ,
  185635. + .rb_lock =
  185636. + __RW_LOCK_UNLOCKED(mlb_devinfo[3].tx_rbuf.rb_lock),
  185637. + },
  185638. + .cdt_buf_dep = CH_ISOC_CDT_BUF_DEP,
  185639. + .adt_buf_dep = CH_ISOC_ADT_BUF_DEP,
  185640. + .buf_size = CH_ISOC_BUF_SZ,
  185641. + .on = ATOMIC_INIT(0),
  185642. + .opencnt = ATOMIC_INIT(0),
  185643. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[3].event_lock),
  185644. + .isoc_blksz = CH_ISOC_BLK_SIZE_188,
  185645. + },
  185646. +};
  185647. +
  185648. +static void __iomem *mlb_base;
  185649. +
  185650. +DEFINE_SPINLOCK(ctr_lock);
  185651. +
  185652. +#ifdef DEBUG
  185653. +#define DUMP_REG(reg) pr_debug(#reg": 0x%08x\n", __raw_readl(mlb_base + reg))
  185654. +
  185655. +static void mlb150_dev_dump_reg(void)
  185656. +{
  185657. + pr_debug("mxc_mlb150: Dump registers:\n");
  185658. + DUMP_REG(REG_MLBC0);
  185659. + DUMP_REG(REG_MLBPC0);
  185660. + DUMP_REG(REG_MS0);
  185661. + DUMP_REG(REG_MS1);
  185662. + DUMP_REG(REG_MSS);
  185663. + DUMP_REG(REG_MSD);
  185664. + DUMP_REG(REG_MIEN);
  185665. + DUMP_REG(REG_MLBPC2);
  185666. + DUMP_REG(REG_MLBPC1);
  185667. + DUMP_REG(REG_MLBC1);
  185668. + DUMP_REG(REG_HCTL);
  185669. + DUMP_REG(REG_HCMR0);
  185670. + DUMP_REG(REG_HCMR1);
  185671. + DUMP_REG(REG_HCER0);
  185672. + DUMP_REG(REG_HCER1);
  185673. + DUMP_REG(REG_HCBR0);
  185674. + DUMP_REG(REG_HCBR1);
  185675. + DUMP_REG(REG_MDAT0);
  185676. + DUMP_REG(REG_MDAT1);
  185677. + DUMP_REG(REG_MDAT2);
  185678. + DUMP_REG(REG_MDAT3);
  185679. + DUMP_REG(REG_MDWE0);
  185680. + DUMP_REG(REG_MDWE1);
  185681. + DUMP_REG(REG_MDWE2);
  185682. + DUMP_REG(REG_MDWE3);
  185683. + DUMP_REG(REG_MCTL);
  185684. + DUMP_REG(REG_MADR);
  185685. + DUMP_REG(REG_ACTL);
  185686. + DUMP_REG(REG_ACSR0);
  185687. + DUMP_REG(REG_ACSR1);
  185688. + DUMP_REG(REG_ACMR0);
  185689. + DUMP_REG(REG_ACMR1);
  185690. +}
  185691. +
  185692. +static void mlb150_dev_dump_hex(const u8 *buf, u32 len)
  185693. +{
  185694. + print_hex_dump(KERN_DEBUG, "CTR DUMP:",
  185695. + DUMP_PREFIX_OFFSET, 8, 1, buf, len, 0);
  185696. +}
  185697. +#endif
  185698. +
  185699. +static inline void mlb150_dev_enable_ctr_write(u32 mdat0_bits_en,
  185700. + u32 mdat1_bits_en, u32 mdat2_bits_en, u32 mdat3_bits_en)
  185701. +{
  185702. + __raw_writel(mdat0_bits_en, mlb_base + REG_MDWE0);
  185703. + __raw_writel(mdat1_bits_en, mlb_base + REG_MDWE1);
  185704. + __raw_writel(mdat2_bits_en, mlb_base + REG_MDWE2);
  185705. + __raw_writel(mdat3_bits_en, mlb_base + REG_MDWE3);
  185706. +}
  185707. +
  185708. +#ifdef DEBUG
  185709. +static inline u8 mlb150_dev_dbr_read(u32 dbr_addr)
  185710. +{
  185711. + s32 timeout = 1000;
  185712. + u8 dbr_val = 0;
  185713. + unsigned long flags;
  185714. +
  185715. + spin_lock_irqsave(&ctr_lock, flags);
  185716. + __raw_writel(MADR_TB | dbr_addr,
  185717. + mlb_base + REG_MADR);
  185718. +
  185719. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  185720. + & MCTL_XCMP)) &&
  185721. + timeout--)
  185722. + ;
  185723. +
  185724. + if (0 == timeout) {
  185725. + spin_unlock_irqrestore(&ctr_lock, flags);
  185726. + return -ETIME;
  185727. + }
  185728. +
  185729. + dbr_val = __raw_readl(mlb_base + REG_MDAT0) & 0x000000ff;
  185730. +
  185731. + __raw_writel(0, mlb_base + REG_MCTL);
  185732. + spin_unlock_irqrestore(&ctr_lock, flags);
  185733. +
  185734. + return dbr_val;
  185735. +}
  185736. +
  185737. +static inline s32 mlb150_dev_dbr_write(u32 dbr_addr, u8 dbr_val)
  185738. +{
  185739. + s32 timeout = 1000;
  185740. + u32 mdat0 = dbr_val & 0x000000ff;
  185741. + unsigned long flags;
  185742. +
  185743. + spin_lock_irqsave(&ctr_lock, flags);
  185744. + __raw_writel(mdat0, mlb_base + REG_MDAT0);
  185745. +
  185746. + __raw_writel(MADR_WNR | MADR_TB | dbr_addr,
  185747. + mlb_base + REG_MADR);
  185748. +
  185749. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  185750. + & MCTL_XCMP)) &&
  185751. + timeout--)
  185752. + ;
  185753. +
  185754. + if (timeout <= 0) {
  185755. + spin_unlock_irqrestore(&ctr_lock, flags);
  185756. + return -ETIME;
  185757. + }
  185758. +
  185759. + __raw_writel(0, mlb_base + REG_MCTL);
  185760. + spin_unlock_irqrestore(&ctr_lock, flags);
  185761. +
  185762. + return 0;
  185763. +}
  185764. +
  185765. +static inline s32 mlb150_dev_dbr_dump(u32 addr, u32 size)
  185766. +{
  185767. + u8 *dump_buf = NULL;
  185768. + u8 *buf_ptr = NULL;
  185769. + s32 i;
  185770. +
  185771. + dump_buf = kzalloc(size, GFP_KERNEL);
  185772. + if (!dump_buf) {
  185773. + pr_err("can't allocate enough memory\n");
  185774. + return -ENOMEM;
  185775. + }
  185776. +
  185777. + for (i = 0, buf_ptr = dump_buf;
  185778. + i < size; ++i, ++buf_ptr)
  185779. + *buf_ptr = mlb150_dev_dbr_read(addr + i);
  185780. +
  185781. + mlb150_dev_dump_hex(dump_buf, size);
  185782. +
  185783. + kfree(dump_buf);
  185784. +
  185785. + return 0;
  185786. +}
  185787. +#endif
  185788. +
  185789. +static s32 mlb150_dev_ctr_read(u32 ctr_offset, u32 *ctr_val)
  185790. +{
  185791. + s32 timeout = 1000;
  185792. + unsigned long flags;
  185793. +
  185794. + spin_lock_irqsave(&ctr_lock, flags);
  185795. + __raw_writel(ctr_offset, mlb_base + REG_MADR);
  185796. +
  185797. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  185798. + & MCTL_XCMP)) &&
  185799. + timeout--)
  185800. + ;
  185801. +
  185802. + if (timeout <= 0) {
  185803. + spin_unlock_irqrestore(&ctr_lock, flags);
  185804. + pr_debug("mxc_mlb150: Read CTR timeout\n");
  185805. + return -ETIME;
  185806. + }
  185807. +
  185808. + ctr_val[0] = __raw_readl(mlb_base + REG_MDAT0);
  185809. + ctr_val[1] = __raw_readl(mlb_base + REG_MDAT1);
  185810. + ctr_val[2] = __raw_readl(mlb_base + REG_MDAT2);
  185811. + ctr_val[3] = __raw_readl(mlb_base + REG_MDAT3);
  185812. +
  185813. + __raw_writel(0, mlb_base + REG_MCTL);
  185814. +
  185815. + spin_unlock_irqrestore(&ctr_lock, flags);
  185816. +
  185817. + return 0;
  185818. +}
  185819. +
  185820. +static s32 mlb150_dev_ctr_write(u32 ctr_offset, const u32 *ctr_val)
  185821. +{
  185822. + s32 timeout = 1000;
  185823. + unsigned long flags;
  185824. +
  185825. + spin_lock_irqsave(&ctr_lock, flags);
  185826. +
  185827. + __raw_writel(ctr_val[0], mlb_base + REG_MDAT0);
  185828. + __raw_writel(ctr_val[1], mlb_base + REG_MDAT1);
  185829. + __raw_writel(ctr_val[2], mlb_base + REG_MDAT2);
  185830. + __raw_writel(ctr_val[3], mlb_base + REG_MDAT3);
  185831. +
  185832. + __raw_writel(MADR_WNR | ctr_offset,
  185833. + 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: Write CTR timeout\n");
  185843. + return -ETIME;
  185844. + }
  185845. +
  185846. + __raw_writel(0, mlb_base + REG_MCTL);
  185847. +
  185848. + spin_unlock_irqrestore(&ctr_lock, flags);
  185849. +
  185850. +#ifdef DEBUG_CTR
  185851. + {
  185852. + u32 ctr_rd[4] = { 0 };
  185853. +
  185854. + if (!mlb150_dev_ctr_read(ctr_offset, ctr_rd)) {
  185855. + if (ctr_val[0] == ctr_rd[0] &&
  185856. + ctr_val[1] == ctr_rd[1] &&
  185857. + ctr_val[2] == ctr_rd[2] &&
  185858. + ctr_val[3] == ctr_rd[3])
  185859. + return 0;
  185860. + else {
  185861. + pr_debug("mxc_mlb150: ctr write failed\n");
  185862. + pr_debug("offset: 0x%x\n", ctr_offset);
  185863. + pr_debug("Write: 0x%x 0x%x 0x%x 0x%x\n",
  185864. + ctr_val[3], ctr_val[2],
  185865. + ctr_val[1], ctr_val[0]);
  185866. + pr_debug("Read: 0x%x 0x%x 0x%x 0x%x\n",
  185867. + ctr_rd[3], ctr_rd[2],
  185868. + ctr_rd[1], ctr_rd[0]);
  185869. + return -EBADE;
  185870. + }
  185871. + } else {
  185872. + pr_debug("mxc_mlb150: ctr read failed\n");
  185873. + return -EBADE;
  185874. + }
  185875. + }
  185876. +#endif
  185877. +
  185878. + return 0;
  185879. +}
  185880. +
  185881. +#ifdef DEBUG
  185882. +static s32 mlb150_dev_cat_read(u32 ctr_offset, u32 ch, u16 *cat_val)
  185883. +{
  185884. + u16 ctr_val[8] = { 0 };
  185885. +
  185886. + if (mlb150_dev_ctr_read(ctr_offset, (u32 *)ctr_val))
  185887. + return -ETIME;
  185888. +
  185889. + /*
  185890. + * Use u16 array to get u32 array value,
  185891. + * need to convert
  185892. + */
  185893. + cat_val = ctr_val[ch % 8];
  185894. +
  185895. + return 0;
  185896. +}
  185897. +#endif
  185898. +
  185899. +static s32 mlb150_dev_cat_write(u32 ctr_offset, u32 ch, const u16 cat_val)
  185900. +{
  185901. + u16 ctr_val[8] = { 0 };
  185902. +
  185903. + if (mlb150_dev_ctr_read(ctr_offset, (u32 *)ctr_val))
  185904. + return -ETIME;
  185905. +
  185906. + ctr_val[ch % 8] = cat_val;
  185907. + if (mlb150_dev_ctr_write(ctr_offset, (u32 *)ctr_val))
  185908. + return -ETIME;
  185909. +
  185910. + return 0;
  185911. +}
  185912. +
  185913. +#define mlb150_dev_cat_mlb_read(ch, cat_val) \
  185914. + mlb150_dev_cat_read(BUF_CAT_MLB_OFFSET + (ch >> 3), ch, cat_val)
  185915. +#define mlb150_dev_cat_mlb_write(ch, cat_val) \
  185916. + mlb150_dev_cat_write(BUF_CAT_MLB_OFFSET + (ch >> 3), ch, cat_val)
  185917. +#define mlb150_dev_cat_hbi_read(ch, cat_val) \
  185918. + mlb150_dev_cat_read(BUF_CAT_HBI_OFFSET + (ch >> 3), ch, cat_val)
  185919. +#define mlb150_dev_cat_hbi_write(ch, cat_val) \
  185920. + mlb150_dev_cat_write(BUF_CAT_HBI_OFFSET + (ch >> 3), ch, cat_val)
  185921. +
  185922. +#define mlb150_dev_cdt_read(ch, cdt_val) \
  185923. + mlb150_dev_ctr_read(BUF_CDT_OFFSET + ch, cdt_val)
  185924. +#define mlb150_dev_cdt_write(ch, cdt_val) \
  185925. + mlb150_dev_ctr_write(BUF_CDT_OFFSET + ch, cdt_val)
  185926. +#define mlb150_dev_adt_read(ch, adt_val) \
  185927. + mlb150_dev_ctr_read(BUF_ADT_OFFSET + ch, adt_val)
  185928. +#define mlb150_dev_adt_write(ch, adt_val) \
  185929. + mlb150_dev_ctr_write(BUF_ADT_OFFSET + ch, adt_val)
  185930. +
  185931. +static s32 mlb150_dev_get_adt_sts(u32 ch)
  185932. +{
  185933. + s32 timeout = 1000;
  185934. + unsigned long flags;
  185935. + u32 reg;
  185936. +
  185937. + spin_lock_irqsave(&ctr_lock, flags);
  185938. + __raw_writel(BUF_ADT_OFFSET + ch,
  185939. + mlb_base + REG_MADR);
  185940. +
  185941. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  185942. + & MCTL_XCMP)) &&
  185943. + timeout--)
  185944. + ;
  185945. +
  185946. + if (timeout <= 0) {
  185947. + spin_unlock_irqrestore(&ctr_lock, flags);
  185948. + pr_debug("mxc_mlb150: Read CTR timeout\n");
  185949. + return -ETIME;
  185950. + }
  185951. +
  185952. + reg = __raw_readl(mlb_base + REG_MDAT1);
  185953. +
  185954. + __raw_writel(0, mlb_base + REG_MCTL);
  185955. + spin_unlock_irqrestore(&ctr_lock, flags);
  185956. +
  185957. +#ifdef DEBUG_ADT
  185958. + pr_debug("mxc_mlb150: Get ch %d adt sts: 0x%08x\n", ch, reg);
  185959. +#endif
  185960. +
  185961. + return reg;
  185962. +}
  185963. +
  185964. +#ifdef DEBUG
  185965. +static void mlb150_dev_dump_ctr_tbl(u32 ch_start, u32 ch_end)
  185966. +{
  185967. + u32 i = 0;
  185968. + u32 ctr_val[4] = { 0 };
  185969. +
  185970. + pr_debug("mxc_mlb150: CDT Table");
  185971. + for (i = BUF_CDT_OFFSET + ch_start;
  185972. + i < BUF_CDT_OFFSET + ch_end;
  185973. + ++i) {
  185974. + mlb150_dev_ctr_read(i, ctr_val);
  185975. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  185976. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  185977. + }
  185978. +
  185979. + pr_debug("mxc_mlb150: ADT Table");
  185980. + for (i = BUF_ADT_OFFSET + ch_start;
  185981. + i < BUF_ADT_OFFSET + ch_end;
  185982. + ++i) {
  185983. + mlb150_dev_ctr_read(i, ctr_val);
  185984. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  185985. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  185986. + }
  185987. +
  185988. + pr_debug("mxc_mlb150: CAT MLB Table");
  185989. + for (i = BUF_CAT_MLB_OFFSET + (ch_start >> 3);
  185990. + i <= BUF_CAT_MLB_OFFSET + ((ch_end + 8) >> 3);
  185991. + ++i) {
  185992. + mlb150_dev_ctr_read(i, ctr_val);
  185993. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  185994. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  185995. + }
  185996. +
  185997. + pr_debug("mxc_mlb150: CAT HBI Table");
  185998. + for (i = BUF_CAT_HBI_OFFSET + (ch_start >> 3);
  185999. + i <= BUF_CAT_HBI_OFFSET + ((ch_end + 8) >> 3);
  186000. + ++i) {
  186001. + mlb150_dev_ctr_read(i, ctr_val);
  186002. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  186003. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  186004. + }
  186005. +}
  186006. +#endif
  186007. +
  186008. +/*
  186009. + * Initial the MLB module device
  186010. + */
  186011. +static inline void mlb150_dev_enable_dma_irq(u32 enable)
  186012. +{
  186013. + u32 ch_rx_mask = (1 << SYNC_RX_CL_AHB0) | (1 << CTRL_RX_CL_AHB0)
  186014. + | (1 << ASYNC_RX_CL_AHB0) | (1 << ISOC_RX_CL_AHB0)
  186015. + | (1 << SYNC_TX_CL_AHB0) | (1 << CTRL_TX_CL_AHB0)
  186016. + | (1 << ASYNC_TX_CL_AHB0) | (1 << ISOC_TX_CL_AHB0);
  186017. + u32 ch_tx_mask = (1 << (SYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186018. + (1 << (CTRL_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186019. + (1 << (ASYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186020. + (1 << (ISOC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186021. + (1 << (SYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186022. + (1 << (CTRL_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186023. + (1 << (ASYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186024. + (1 << (ISOC_TX_CL_AHB1 - INT_AHB1_CH_START));
  186025. +
  186026. + if (enable) {
  186027. + __raw_writel(ch_rx_mask, mlb_base + REG_ACMR0);
  186028. + __raw_writel(ch_tx_mask, mlb_base + REG_ACMR1);
  186029. + } else {
  186030. + __raw_writel(0x0, mlb_base + REG_ACMR0);
  186031. + __raw_writel(0x0, mlb_base + REG_ACMR1);
  186032. + }
  186033. +}
  186034. +
  186035. +
  186036. +static void mlb150_dev_init_ir_amba_ahb(void)
  186037. +{
  186038. + u32 reg = 0;
  186039. +
  186040. + /*
  186041. + * Step 1. Program the ACMRn registers to enable interrupts from all
  186042. + * active DMA channels
  186043. + */
  186044. + mlb150_dev_enable_dma_irq(1);
  186045. +
  186046. + /*
  186047. + * Step 2. Select the status clear method:
  186048. + * ACTL.SCE = 0, hardware clears on read
  186049. + * ACTL.SCE = 1, software writes a '1' to clear
  186050. + * We only support DMA MODE 1
  186051. + */
  186052. + reg = __raw_readl(mlb_base + REG_ACTL);
  186053. + reg |= ACTL_DMAMODE;
  186054. +#ifdef MULTIPLE_PACKAGE_MODE
  186055. + reg |= REG_ACTL_MPB;
  186056. +#endif
  186057. +
  186058. + /*
  186059. + * Step 3. Select 1 or 2 interrupt signals:
  186060. + * ACTL.SMX = 0: one interrupt for channels 0 - 31 on ahb_init[0]
  186061. + * and another interrupt for channels 32 - 63 on ahb_init[1]
  186062. + * ACTL.SMX = 1: singel interrupt all channels on ahb_init[0]
  186063. + */
  186064. + reg &= ~ACTL_SMX;
  186065. +
  186066. + __raw_writel(reg, mlb_base + REG_ACTL);
  186067. +}
  186068. +
  186069. +static inline void mlb150_dev_enable_ir_mlb(u32 enable)
  186070. +{
  186071. + /*
  186072. + * Step 1, Select the MSn to be cleared by software,
  186073. + * writing a '0' to the appropriate bits
  186074. + */
  186075. + __raw_writel(0, mlb_base + REG_MS0);
  186076. + __raw_writel(0, mlb_base + REG_MS1);
  186077. +
  186078. + /*
  186079. + * Step 1, Program MIEN to enable protocol error
  186080. + * interrupts for all active MLB channels
  186081. + */
  186082. + if (enable)
  186083. + __raw_writel(MIEN_CTX_PE |
  186084. + MIEN_CRX_PE | MIEN_ATX_PE |
  186085. + MIEN_ARX_PE | MIEN_SYNC_PE |
  186086. + MIEN_ISOC_PE,
  186087. + mlb_base + REG_MIEN);
  186088. + else
  186089. + __raw_writel(0, mlb_base + REG_MIEN);
  186090. +}
  186091. +
  186092. +static inline void mlb150_enable_pll(struct mlb_data *drvdata)
  186093. +{
  186094. + u32 c0_val;
  186095. +
  186096. + __raw_writel(MLBPC1_VAL,
  186097. + drvdata->membase + REG_MLBPC1);
  186098. +
  186099. + c0_val = __raw_readl(drvdata->membase + REG_MLBC0);
  186100. + if (c0_val & MLBC0_MLBPEN) {
  186101. + c0_val &= ~MLBC0_MLBPEN;
  186102. + __raw_writel(c0_val,
  186103. + drvdata->membase + REG_MLBC0);
  186104. + }
  186105. +
  186106. + clk_prepare_enable(drvdata->clk_mlb6p);
  186107. +
  186108. + c0_val |= (MLBC0_MLBPEN);
  186109. + __raw_writel(c0_val, drvdata->membase + REG_MLBC0);
  186110. +}
  186111. +
  186112. +static inline void mlb150_disable_pll(struct mlb_data *drvdata)
  186113. +{
  186114. + u32 c0_val;
  186115. +
  186116. + clk_disable_unprepare(drvdata->clk_mlb6p);
  186117. +
  186118. + c0_val = __raw_readl(drvdata->membase + REG_MLBC0);
  186119. +
  186120. + __raw_writel(0x0, drvdata->membase + REG_MLBPC1);
  186121. +
  186122. + c0_val &= ~MLBC0_MLBPEN;
  186123. + __raw_writel(c0_val, drvdata->membase + REG_MLBC0);
  186124. +}
  186125. +
  186126. +static void mlb150_dev_reset_cdt(void)
  186127. +{
  186128. + int i = 0;
  186129. + u32 ctr_val[4] = { 0 };
  186130. +
  186131. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  186132. + 0xffffffff, 0xffffffff);
  186133. +
  186134. + for (i = 0; i < (LOGIC_CH_NUM); ++i)
  186135. + mlb150_dev_ctr_write(BUF_CDT_OFFSET + i, ctr_val);
  186136. +}
  186137. +
  186138. +static s32 mlb150_dev_init_ch_cdt(struct mlb_dev_info *pdevinfo, u32 ch,
  186139. + enum MLB_CTYPE ctype, u32 ch_func)
  186140. +{
  186141. + u32 cdt_val[4] = { 0 };
  186142. +
  186143. + /* a. Set the 14-bit base address (BA) */
  186144. + pr_debug("mxc_mlb150: ctype: %d, ch: %d, dbr_buf_head: 0x%08x",
  186145. + ctype, ch, pdevinfo->channels[ch_func].dbr_buf_head);
  186146. + cdt_val[3] = (pdevinfo->channels[ch_func].dbr_buf_head)
  186147. + << CDT_BA_SHIFT;
  186148. + /*
  186149. + * b. Set the 12-bit or 13-bit buffer depth (BD)
  186150. + * BD = buffer depth in bytes - 1
  186151. + * For synchronous channels: (BD + 1) = 4 * m * bpf
  186152. + * For control channels: (BD + 1) >= max packet length (64)
  186153. + * For asynchronous channels: (BD + 1) >= max packet length
  186154. + * 1024 for a MOST Data packet (MDP);
  186155. + * 1536 for a MOST Ethernet Packet (MEP)
  186156. + * For isochronous channels: (BD + 1) mod (BS + 1) = 0
  186157. + * BS
  186158. + */
  186159. + if (MLB_CTYPE_ISOC == ctype)
  186160. + cdt_val[1] |= (pdevinfo->isoc_blksz - 1);
  186161. + /* BD */
  186162. + cdt_val[3] |= (pdevinfo->cdt_buf_dep - 1) << CDT_BD_SHIFT;
  186163. +
  186164. + pr_debug("mxc_mlb150: Set CDT val of channel %d, type: %d: "
  186165. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  186166. + ch, ctype, cdt_val[3], cdt_val[2], cdt_val[1], cdt_val[0]);
  186167. +
  186168. + if (mlb150_dev_cdt_write(ch, cdt_val))
  186169. + return -ETIME;
  186170. +
  186171. +#ifdef DEBUG_CTR
  186172. + {
  186173. + u32 cdt_rd[4] = { 0 };
  186174. + if (!mlb150_dev_cdt_read(ch, cdt_rd)) {
  186175. + pr_debug("mxc_mlb150: CDT val of channel %d: "
  186176. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  186177. + ch, cdt_rd[3], cdt_rd[2], cdt_rd[1], cdt_rd[0]);
  186178. + if (cdt_rd[3] == cdt_val[3] &&
  186179. + cdt_rd[2] == cdt_val[2] &&
  186180. + cdt_rd[1] == cdt_val[1] &&
  186181. + cdt_rd[0] == cdt_val[0]) {
  186182. + pr_debug("mxc_mlb150: set cdt succeed!\n");
  186183. + return 0;
  186184. + } else {
  186185. + pr_debug("mxc_mlb150: set cdt failed!\n");
  186186. + return -EBADE;
  186187. + }
  186188. + } else {
  186189. + pr_debug("mxc_mlb150: Read CDT val of channel %d failed\n",
  186190. + ch);
  186191. + return -EBADE;
  186192. + }
  186193. + }
  186194. +#endif
  186195. +
  186196. + return 0;
  186197. +}
  186198. +
  186199. +static s32 mlb150_dev_init_ch_cat(u32 ch, u32 cl,
  186200. + u32 cat_mode, enum MLB_CTYPE ctype)
  186201. +{
  186202. + u16 cat_val = 0;
  186203. +#ifdef DEBUG_CTR
  186204. + u16 cat_rd = 0;
  186205. +#endif
  186206. +
  186207. + cat_val = CAT_CE | (ctype << CAT_CT_SHIFT) | cl;
  186208. +
  186209. + if (cat_mode & CAT_MODE_OUTBOUND_DMA)
  186210. + cat_val |= CAT_RNW;
  186211. +
  186212. + if (MLB_CTYPE_SYNC == ctype)
  186213. + cat_val |= CAT_MT;
  186214. +
  186215. + switch (cat_mode) {
  186216. + case CAT_MODE_RX | CAT_MODE_INBOUND_DMA:
  186217. + case CAT_MODE_TX | CAT_MODE_OUTBOUND_DMA:
  186218. + pr_debug("mxc_mlb150: set CAT val of channel %d, type: %d: 0x%04x\n",
  186219. + ch, ctype, cat_val);
  186220. +
  186221. + if (mlb150_dev_cat_mlb_write(ch, cat_val))
  186222. + return -ETIME;
  186223. +#ifdef DEBUG_CTR
  186224. + if (!mlb150_dev_cat_mlb_read(ch, &cat_rd))
  186225. + pr_debug("mxc_mlb150: CAT val of mlb channel %d: 0x%04x",
  186226. + ch, cat_rd);
  186227. + else {
  186228. + pr_debug("mxc_mlb150: Read CAT of mlb channel %d failed\n",
  186229. + ch);
  186230. + return -EBADE;
  186231. + }
  186232. +#endif
  186233. + break;
  186234. + case CAT_MODE_TX | CAT_MODE_INBOUND_DMA:
  186235. + case CAT_MODE_RX | CAT_MODE_OUTBOUND_DMA:
  186236. + pr_debug("mxc_mlb150: set CAT val of channel %d, type: %d: 0x%04x\n",
  186237. + cl, ctype, cat_val);
  186238. +
  186239. + if (mlb150_dev_cat_hbi_write(cl, cat_val))
  186240. + return -ETIME;
  186241. +#ifdef DEBUG_CTR
  186242. + if (!mlb150_dev_cat_hbi_read(cl, &cat_rd))
  186243. + pr_debug("mxc_mlb150: CAT val of hbi channel %d: 0x%04x",
  186244. + cl, cat_rd);
  186245. + else {
  186246. + pr_debug("mxc_mlb150: Read CAT of hbi channel %d failed\n",
  186247. + cl);
  186248. + return -EBADE;
  186249. + }
  186250. +#endif
  186251. + break;
  186252. + default:
  186253. + return EBADRQC;
  186254. + }
  186255. +
  186256. +#ifdef DEBUG_CTR
  186257. + {
  186258. + if (cat_val == cat_rd) {
  186259. + pr_debug("mxc_mlb150: set cat succeed!\n");
  186260. + return 0;
  186261. + } else {
  186262. + pr_debug("mxc_mlb150: set cat failed!\n");
  186263. + return -EBADE;
  186264. + }
  186265. + }
  186266. +#endif
  186267. + return 0;
  186268. +}
  186269. +
  186270. +static void mlb150_dev_reset_cat(void)
  186271. +{
  186272. + int i = 0;
  186273. + u32 ctr_val[4] = { 0 };
  186274. +
  186275. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  186276. + 0xffffffff, 0xffffffff);
  186277. +
  186278. + for (i = 0; i < (LOGIC_CH_NUM >> 3); ++i) {
  186279. + mlb150_dev_ctr_write(BUF_CAT_MLB_OFFSET + i, ctr_val);
  186280. + mlb150_dev_ctr_write(BUF_CAT_HBI_OFFSET + i, ctr_val);
  186281. + }
  186282. +}
  186283. +
  186284. +static void mlb150_dev_init_rfb(struct mlb_dev_info *pdevinfo, u32 rx_ch,
  186285. + u32 tx_ch, enum MLB_CTYPE ctype)
  186286. +{
  186287. + u32 rx_cl = pdevinfo->channels[RX_CHANNEL].cl;
  186288. + u32 tx_cl = pdevinfo->channels[TX_CHANNEL].cl;
  186289. + /* Step 1, Initialize all bits of CAT to '0' */
  186290. + mlb150_dev_reset_cat();
  186291. + mlb150_dev_reset_cdt();
  186292. + /*
  186293. + * Step 2, Initialize logical channel
  186294. + * Step 3, Program the CDT for channel N
  186295. + */
  186296. + mlb150_dev_init_ch_cdt(pdevinfo, rx_cl, ctype, RX_CHANNEL);
  186297. + mlb150_dev_init_ch_cdt(pdevinfo, tx_cl, ctype, TX_CHANNEL);
  186298. +
  186299. + /* Step 4&5, Program the CAT for the inbound and outbound DMA */
  186300. + mlb150_dev_init_ch_cat(rx_ch, rx_cl,
  186301. + CAT_MODE_RX | CAT_MODE_INBOUND_DMA,
  186302. + ctype);
  186303. + mlb150_dev_init_ch_cat(rx_ch, rx_cl,
  186304. + CAT_MODE_RX | CAT_MODE_OUTBOUND_DMA,
  186305. + ctype);
  186306. + mlb150_dev_init_ch_cat(tx_ch, tx_cl,
  186307. + CAT_MODE_TX | CAT_MODE_INBOUND_DMA,
  186308. + ctype);
  186309. + mlb150_dev_init_ch_cat(tx_ch, tx_cl,
  186310. + CAT_MODE_TX | CAT_MODE_OUTBOUND_DMA,
  186311. + ctype);
  186312. +}
  186313. +
  186314. +static void mlb150_dev_reset_adt(void)
  186315. +{
  186316. + int i = 0;
  186317. + u32 ctr_val[4] = { 0 };
  186318. +
  186319. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  186320. + 0xffffffff, 0xffffffff);
  186321. +
  186322. + for (i = 0; i < (LOGIC_CH_NUM); ++i)
  186323. + mlb150_dev_ctr_write(BUF_ADT_OFFSET + i, ctr_val);
  186324. +}
  186325. +
  186326. +static void mlb150_dev_reset_whole_ctr(void)
  186327. +{
  186328. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  186329. + 0xffffffff, 0xffffffff);
  186330. + mlb150_dev_reset_cdt();
  186331. + mlb150_dev_reset_adt();
  186332. + mlb150_dev_reset_cat();
  186333. +}
  186334. +
  186335. +#define CLR_REG(reg) __raw_writel(0x0, mlb_base + reg)
  186336. +
  186337. +static void mlb150_dev_reset_all_regs(void)
  186338. +{
  186339. + CLR_REG(REG_MLBC0);
  186340. + CLR_REG(REG_MLBPC0);
  186341. + CLR_REG(REG_MS0);
  186342. + CLR_REG(REG_MS1);
  186343. + CLR_REG(REG_MSS);
  186344. + CLR_REG(REG_MSD);
  186345. + CLR_REG(REG_MIEN);
  186346. + CLR_REG(REG_MLBPC2);
  186347. + CLR_REG(REG_MLBPC1);
  186348. + CLR_REG(REG_MLBC1);
  186349. + CLR_REG(REG_HCTL);
  186350. + CLR_REG(REG_HCMR0);
  186351. + CLR_REG(REG_HCMR1);
  186352. + CLR_REG(REG_HCER0);
  186353. + CLR_REG(REG_HCER1);
  186354. + CLR_REG(REG_HCBR0);
  186355. + CLR_REG(REG_HCBR1);
  186356. + CLR_REG(REG_MDAT0);
  186357. + CLR_REG(REG_MDAT1);
  186358. + CLR_REG(REG_MDAT2);
  186359. + CLR_REG(REG_MDAT3);
  186360. + CLR_REG(REG_MDWE0);
  186361. + CLR_REG(REG_MDWE1);
  186362. + CLR_REG(REG_MDWE2);
  186363. + CLR_REG(REG_MDWE3);
  186364. + CLR_REG(REG_MCTL);
  186365. + CLR_REG(REG_MADR);
  186366. + CLR_REG(REG_ACTL);
  186367. + CLR_REG(REG_ACSR0);
  186368. + CLR_REG(REG_ACSR1);
  186369. + CLR_REG(REG_ACMR0);
  186370. + CLR_REG(REG_ACMR1);
  186371. +}
  186372. +
  186373. +static inline s32 mlb150_dev_pipo_start(struct mlb_ringbuf *rbuf,
  186374. + u32 ahb_ch, u32 buf_addr)
  186375. +{
  186376. + u32 ctr_val[4] = { 0 };
  186377. +
  186378. + ctr_val[1] |= ADT_RDY1;
  186379. + ctr_val[2] = buf_addr;
  186380. +
  186381. + if (mlb150_dev_adt_write(ahb_ch, ctr_val))
  186382. + return -ETIME;
  186383. +
  186384. + return 0;
  186385. +}
  186386. +
  186387. +static inline s32 mlb150_dev_pipo_next(u32 ahb_ch, enum MLB_CTYPE ctype,
  186388. + u32 dne_sts, u32 buf_addr)
  186389. +{
  186390. + u32 ctr_val[4] = { 0 };
  186391. +
  186392. + if (MLB_CTYPE_ASYNC == ctype ||
  186393. + MLB_CTYPE_CTRL == ctype) {
  186394. + ctr_val[1] |= ADT_PS1;
  186395. + ctr_val[1] |= ADT_PS2;
  186396. + }
  186397. +
  186398. + /*
  186399. + * Clear DNE1 and ERR1
  186400. + * Set the page ready bit (RDY1)
  186401. + */
  186402. + if (dne_sts & ADT_DNE1) {
  186403. + ctr_val[1] |= ADT_RDY2;
  186404. + ctr_val[3] = buf_addr;
  186405. + } else {
  186406. + ctr_val[1] |= ADT_RDY1;
  186407. + ctr_val[2] = buf_addr;
  186408. + }
  186409. +
  186410. + if (mlb150_dev_adt_write(ahb_ch, ctr_val))
  186411. + return -ETIME;
  186412. +
  186413. + return 0;
  186414. +}
  186415. +
  186416. +static inline s32 mlb150_dev_pipo_stop(struct mlb_ringbuf *rbuf, u32 ahb_ch)
  186417. +{
  186418. + u32 ctr_val[4] = { 0 };
  186419. + unsigned long flags;
  186420. +
  186421. + write_lock_irqsave(&rbuf->rb_lock, flags);
  186422. + rbuf->head = rbuf->tail = 0;
  186423. + write_unlock_irqrestore(&rbuf->rb_lock, flags);
  186424. +
  186425. + if (mlb150_dev_adt_write(ahb_ch, ctr_val))
  186426. + return -ETIME;
  186427. +
  186428. + return 0;
  186429. +}
  186430. +
  186431. +static s32 mlb150_dev_init_ch_amba_ahb(struct mlb_dev_info *pdevinfo,
  186432. + struct mlb_channel_info *chinfo,
  186433. + enum MLB_CTYPE ctype)
  186434. +{
  186435. + u32 ctr_val[4] = { 0 };
  186436. +
  186437. + /* a. Set the 32-bit base address (BA1) */
  186438. + ctr_val[3] = 0;
  186439. + ctr_val[2] = 0;
  186440. + ctr_val[1] = (pdevinfo->adt_buf_dep - 1) << ADT_BD1_SHIFT;
  186441. + ctr_val[1] |= (pdevinfo->adt_buf_dep - 1) << ADT_BD2_SHIFT;
  186442. + if (MLB_CTYPE_ASYNC == ctype ||
  186443. + MLB_CTYPE_CTRL == ctype) {
  186444. + ctr_val[1] |= ADT_PS1;
  186445. + ctr_val[1] |= ADT_PS2;
  186446. + }
  186447. +
  186448. + ctr_val[0] |= (ADT_LE | ADT_CE);
  186449. +
  186450. + pr_debug("mxc_mlb150: Set ADT val of channel %d, ctype: %d: "
  186451. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  186452. + chinfo->cl, ctype, ctr_val[3], ctr_val[2],
  186453. + ctr_val[1], ctr_val[0]);
  186454. +
  186455. + if (mlb150_dev_adt_write(chinfo->cl, ctr_val))
  186456. + return -ETIME;
  186457. +
  186458. +#ifdef DEBUG_CTR
  186459. + {
  186460. + u32 ctr_rd[4] = { 0 };
  186461. + if (!mlb150_dev_adt_read(chinfo->cl, ctr_rd)) {
  186462. + pr_debug("mxc_mlb150: ADT val of channel %d: "
  186463. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  186464. + chinfo->cl, ctr_rd[3], ctr_rd[2],
  186465. + ctr_rd[1], ctr_rd[0]);
  186466. + if (ctr_rd[3] == ctr_val[3] &&
  186467. + ctr_rd[2] == ctr_val[2] &&
  186468. + ctr_rd[1] == ctr_val[1] &&
  186469. + ctr_rd[0] == ctr_val[0]) {
  186470. + pr_debug("mxc_mlb150: set adt succeed!\n");
  186471. + return 0;
  186472. + } else {
  186473. + pr_debug("mxc_mlb150: set adt failed!\n");
  186474. + return -EBADE;
  186475. + }
  186476. + } else {
  186477. + pr_debug("mxc_mlb150: Read ADT val of channel %d failed\n",
  186478. + chinfo->cl);
  186479. + return -EBADE;
  186480. + }
  186481. + }
  186482. +#endif
  186483. +
  186484. + return 0;
  186485. +}
  186486. +
  186487. +static void mlb150_dev_init_amba_ahb(struct mlb_dev_info *pdevinfo,
  186488. + enum MLB_CTYPE ctype)
  186489. +{
  186490. + struct mlb_channel_info *tx_chinfo = &pdevinfo->channels[TX_CHANNEL];
  186491. + struct mlb_channel_info *rx_chinfo = &pdevinfo->channels[RX_CHANNEL];
  186492. +
  186493. + /* Step 1, Initialize all bits of the ADT to '0' */
  186494. + mlb150_dev_reset_adt();
  186495. +
  186496. + /*
  186497. + * Step 2, Select a logic channel
  186498. + * Step 3, Program the AMBA AHB block ping page for channel N
  186499. + * Step 4, Program the AMBA AHB block pong page for channel N
  186500. + */
  186501. + mlb150_dev_init_ch_amba_ahb(pdevinfo, rx_chinfo, ctype);
  186502. + mlb150_dev_init_ch_amba_ahb(pdevinfo, tx_chinfo, ctype);
  186503. +}
  186504. +
  186505. +static void mlb150_dev_exit(void)
  186506. +{
  186507. + u32 c0_val, hctl_val;
  186508. +
  186509. + /* Disable EN bits */
  186510. + c0_val = __raw_readl(mlb_base + REG_MLBC0);
  186511. + c0_val &= ~(MLBC0_MLBEN | MLBC0_MLBPEN);
  186512. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  186513. +
  186514. + hctl_val = __raw_readl(mlb_base + REG_HCTL);
  186515. + hctl_val &= ~HCTL_EN;
  186516. + __raw_writel(hctl_val, mlb_base + REG_HCTL);
  186517. +
  186518. + __raw_writel(0x0, mlb_base + REG_HCMR0);
  186519. + __raw_writel(0x0, mlb_base + REG_HCMR1);
  186520. +
  186521. + mlb150_dev_enable_dma_irq(0);
  186522. + mlb150_dev_enable_ir_mlb(0);
  186523. +}
  186524. +
  186525. +static void mlb150_dev_init(void)
  186526. +{
  186527. + u32 c0_val;
  186528. + u32 ch_rx_mask = (1 << SYNC_RX_CL_AHB0) | (1 << CTRL_RX_CL_AHB0)
  186529. + | (1 << ASYNC_RX_CL_AHB0) | (1 << ISOC_RX_CL_AHB0)
  186530. + | (1 << SYNC_TX_CL_AHB0) | (1 << CTRL_TX_CL_AHB0)
  186531. + | (1 << ASYNC_TX_CL_AHB0) | (1 << ISOC_TX_CL_AHB0);
  186532. + u32 ch_tx_mask = (1 << (SYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186533. + (1 << (CTRL_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186534. + (1 << (ASYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186535. + (1 << (ISOC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  186536. + (1 << (SYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186537. + (1 << (CTRL_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186538. + (1 << (ASYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  186539. + (1 << (ISOC_TX_CL_AHB1 - INT_AHB1_CH_START));
  186540. +
  186541. + /* Disable EN bits */
  186542. + mlb150_dev_exit();
  186543. +
  186544. + /*
  186545. + * Step 1. Initialize CTR and registers
  186546. + * a. Set all bit of the CTR (CAT, CDT, and ADT) to 0.
  186547. + */
  186548. + mlb150_dev_reset_whole_ctr();
  186549. +
  186550. + /* a. Set all bit of the CTR (CAT, CDT, and ADT) to 0. */
  186551. + mlb150_dev_reset_all_regs();
  186552. +
  186553. + /*
  186554. + * Step 2, Configure the MediaLB interface
  186555. + * Select pin mode and clock, 3-pin and 256fs
  186556. + */
  186557. + c0_val = __raw_readl(mlb_base + REG_MLBC0);
  186558. + c0_val &= ~(MLBC0_MLBPEN | MLBC0_MLBCLK_MASK);
  186559. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  186560. +
  186561. + c0_val |= MLBC0_MLBEN;
  186562. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  186563. +
  186564. + /* Step 3, Configure the HBI interface */
  186565. + __raw_writel(ch_rx_mask, mlb_base + REG_HCMR0);
  186566. + __raw_writel(ch_tx_mask, mlb_base + REG_HCMR1);
  186567. + __raw_writel(HCTL_EN, mlb_base + REG_HCTL);
  186568. +
  186569. + mlb150_dev_init_ir_amba_ahb();
  186570. +
  186571. + mlb150_dev_enable_ir_mlb(1);
  186572. +}
  186573. +
  186574. +static s32 mlb150_dev_unmute_syn_ch(u32 rx_ch, u32 rx_cl, u32 tx_ch, u32 tx_cl)
  186575. +{
  186576. + u32 timeout = 10000;
  186577. +
  186578. + /*
  186579. + * Check that MediaLB clock is running (MLBC1.CLKM = 0)
  186580. + * If MLBC1.CLKM = 1, clear the register bit, wait one
  186581. + * APB or I/O clock cycle and repeat the check
  186582. + */
  186583. + while ((__raw_readl(mlb_base + REG_MLBC1) & MLBC1_CLKM)
  186584. + && --timeout)
  186585. + __raw_writel(~MLBC1_CLKM, mlb_base + REG_MLBC1);
  186586. +
  186587. + if (0 == timeout)
  186588. + return -ETIME;
  186589. +
  186590. + timeout = 10000;
  186591. + /* Poll for MLB lock (MLBC0.MLBLK = 1) */
  186592. + while (!(__raw_readl(mlb_base + REG_MLBC0) & MLBC0_MLBLK)
  186593. + && --timeout)
  186594. + ;
  186595. +
  186596. + if (0 == timeout)
  186597. + return -ETIME;
  186598. +
  186599. + /* Unmute synchronous channel(s) */
  186600. + mlb150_dev_cat_mlb_write(rx_ch, CAT_CE | rx_cl);
  186601. + mlb150_dev_cat_mlb_write(tx_ch,
  186602. + CAT_CE | tx_cl | CAT_RNW);
  186603. + mlb150_dev_cat_hbi_write(rx_cl,
  186604. + CAT_CE | rx_cl | CAT_RNW);
  186605. + mlb150_dev_cat_hbi_write(tx_cl, CAT_CE | tx_cl);
  186606. +
  186607. + return 0;
  186608. +}
  186609. +
  186610. +/* In case the user calls channel shutdown, but rx or tx is not completed yet */
  186611. +static s32 mlb150_trans_complete_check(struct mlb_dev_info *pdevinfo)
  186612. +{
  186613. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  186614. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  186615. + s32 timeout = 1024;
  186616. +
  186617. + while (timeout--) {
  186618. + read_lock(&tx_rbuf->rb_lock);
  186619. + if (!CIRC_CNT(tx_rbuf->head, tx_rbuf->tail, TRANS_RING_NODES)) {
  186620. + read_unlock(&tx_rbuf->rb_lock);
  186621. + break;
  186622. + } else
  186623. + read_unlock(&tx_rbuf->rb_lock);
  186624. + }
  186625. +
  186626. + if (timeout <= 0) {
  186627. + pr_debug("TX complete check timeout!\n");
  186628. + return -ETIME;
  186629. + }
  186630. +
  186631. + timeout = 1024;
  186632. + while (timeout--) {
  186633. + read_lock(&rx_rbuf->rb_lock);
  186634. + if (!CIRC_CNT(rx_rbuf->head, rx_rbuf->tail, TRANS_RING_NODES)) {
  186635. + read_unlock(&rx_rbuf->rb_lock);
  186636. + break;
  186637. + } else
  186638. + read_unlock(&rx_rbuf->rb_lock);
  186639. + }
  186640. +
  186641. + if (timeout <= 0) {
  186642. + pr_debug("RX complete check timeout!\n");
  186643. + return -ETIME;
  186644. + }
  186645. +
  186646. + /*
  186647. + * Interrupt from TX can only inform that the data is sent
  186648. + * to AHB bus, not mean that it is sent to MITB. Thus we add
  186649. + * a delay here for data to be completed sent.
  186650. + */
  186651. + udelay(1000);
  186652. +
  186653. + return 0;
  186654. +}
  186655. +
  186656. +/*
  186657. + * Enable/Disable the MLB IRQ
  186658. + */
  186659. +static void mxc_mlb150_irq_enable(struct mlb_data *drvdata, u8 enable)
  186660. +{
  186661. + if (enable) {
  186662. + enable_irq(drvdata->irq_ahb0);
  186663. + enable_irq(drvdata->irq_ahb1);
  186664. + enable_irq(drvdata->irq_mlb);
  186665. + } else {
  186666. + disable_irq(drvdata->irq_ahb0);
  186667. + disable_irq(drvdata->irq_ahb1);
  186668. + disable_irq(drvdata->irq_mlb);
  186669. + }
  186670. +}
  186671. +
  186672. +/*
  186673. + * Enable the MLB channel
  186674. + */
  186675. +static s32 mlb_channel_enable(struct mlb_data *drvdata,
  186676. + int chan_dev_id, int on)
  186677. +{
  186678. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  186679. + struct mlb_channel_info *tx_chinfo = &pdevinfo->channels[TX_CHANNEL];
  186680. + struct mlb_channel_info *rx_chinfo = &pdevinfo->channels[RX_CHANNEL];
  186681. + u32 tx_ch = tx_chinfo->address;
  186682. + u32 rx_ch = rx_chinfo->address;
  186683. + u32 tx_cl = tx_chinfo->cl;
  186684. + u32 rx_cl = rx_chinfo->cl;
  186685. + s32 ret = 0;
  186686. +
  186687. + /*
  186688. + * setup the direction, enable, channel type,
  186689. + * mode select, channel address and mask buf start
  186690. + */
  186691. + if (on) {
  186692. + u32 ctype = pdevinfo->channel_type;
  186693. +
  186694. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  186695. + 0xffffffff, 0xffffffff);
  186696. + mlb150_dev_init_rfb(pdevinfo, rx_ch, tx_ch, ctype);
  186697. +
  186698. + mlb150_dev_init_amba_ahb(pdevinfo, ctype);
  186699. +
  186700. +#ifdef DEBUG
  186701. + mlb150_dev_dump_ctr_tbl(0, tx_chinfo->cl + 1);
  186702. +#endif
  186703. + /* Synchronize and unmute synchrouous channel */
  186704. + if (MLB_CTYPE_SYNC == ctype) {
  186705. + ret = mlb150_dev_unmute_syn_ch(rx_ch, rx_cl,
  186706. + tx_ch, tx_cl);
  186707. + if (ret)
  186708. + return ret;
  186709. + }
  186710. +
  186711. + mlb150_dev_enable_ctr_write(0x0, ADT_RDY1 | ADT_DNE1 |
  186712. + ADT_ERR1 | ADT_PS1 |
  186713. + ADT_RDY2 | ADT_DNE2 | ADT_ERR2 | ADT_PS2,
  186714. + 0xffffffff, 0xffffffff);
  186715. +
  186716. + if (pdevinfo->fps >= CLK_2048FS)
  186717. + mlb150_enable_pll(drvdata);
  186718. +
  186719. + atomic_set(&pdevinfo->on, 1);
  186720. +
  186721. +#ifdef DEBUG
  186722. + mlb150_dev_dump_reg();
  186723. + mlb150_dev_dump_ctr_tbl(0, tx_chinfo->cl + 1);
  186724. +#endif
  186725. + /* Init RX ADT */
  186726. + mlb150_dev_pipo_start(&pdevinfo->rx_rbuf, rx_cl,
  186727. + pdevinfo->rx_rbuf.phy_addrs[0]);
  186728. + } else {
  186729. + mlb150_dev_pipo_stop(&pdevinfo->rx_rbuf, rx_cl);
  186730. +
  186731. + mlb150_dev_enable_dma_irq(0);
  186732. + mlb150_dev_enable_ir_mlb(0);
  186733. +
  186734. + mlb150_dev_reset_cat();
  186735. +
  186736. + atomic_set(&pdevinfo->on, 0);
  186737. +
  186738. + if (pdevinfo->fps >= CLK_2048FS)
  186739. + mlb150_disable_pll(drvdata);
  186740. + }
  186741. +
  186742. + return 0;
  186743. +}
  186744. +
  186745. +/*
  186746. + * MLB interrupt handler
  186747. + */
  186748. +static void mlb_rx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
  186749. +{
  186750. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  186751. + s32 head, tail, adt_sts;
  186752. + u32 rx_buf_ptr;
  186753. +
  186754. +#ifdef DEBUG_RX
  186755. + pr_debug("mxc_mlb150: mlb_rx_isr\n");
  186756. +#endif
  186757. +
  186758. + read_lock(&rx_rbuf->rb_lock);
  186759. +
  186760. + head = (rx_rbuf->head + 1) & (TRANS_RING_NODES - 1);
  186761. + tail = ACCESS_ONCE(rx_rbuf->tail);
  186762. + read_unlock(&rx_rbuf->rb_lock);
  186763. +
  186764. + if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1) {
  186765. + rx_buf_ptr = rx_rbuf->phy_addrs[head];
  186766. +
  186767. + /* commit the item before incrementing the head */
  186768. + smp_wmb();
  186769. +
  186770. + write_lock(&rx_rbuf->rb_lock);
  186771. + rx_rbuf->head = head;
  186772. + write_unlock(&rx_rbuf->rb_lock);
  186773. +
  186774. + /* wake up the reader */
  186775. + wake_up_interruptible(&pdevinfo->rx_wq);
  186776. + } else {
  186777. + rx_buf_ptr = rx_rbuf->phy_addrs[head];
  186778. + pr_debug("drop RX package, due to no space, (%d,%d)\n",
  186779. + head, tail);
  186780. + }
  186781. +
  186782. + adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
  186783. + /* Set ADT for RX */
  186784. + mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, rx_buf_ptr);
  186785. +}
  186786. +
  186787. +static void mlb_tx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
  186788. +{
  186789. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  186790. + s32 head, tail, adt_sts;
  186791. + u32 tx_buf_ptr;
  186792. +
  186793. + read_lock(&tx_rbuf->rb_lock);
  186794. +
  186795. + head = ACCESS_ONCE(tx_rbuf->head);
  186796. + tail = (tx_rbuf->tail + 1) & (TRANS_RING_NODES - 1);
  186797. + read_unlock(&tx_rbuf->rb_lock);
  186798. +
  186799. + smp_mb();
  186800. + write_lock(&tx_rbuf->rb_lock);
  186801. + tx_rbuf->tail = tail;
  186802. + write_unlock(&tx_rbuf->rb_lock);
  186803. +
  186804. + /* check the current tx buffer is available or not */
  186805. + if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1) {
  186806. + /* read index before reading contents at that index */
  186807. + smp_read_barrier_depends();
  186808. +
  186809. + tx_buf_ptr = tx_rbuf->phy_addrs[tail];
  186810. +
  186811. + wake_up_interruptible(&pdevinfo->tx_wq);
  186812. +
  186813. + adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
  186814. + /* Set ADT for TX */
  186815. + mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
  186816. + }
  186817. +}
  186818. +
  186819. +static irqreturn_t mlb_ahb_isr(int irq, void *dev_id)
  186820. +{
  186821. + u32 acsr0, hcer0;
  186822. + u32 ch_mask = (1 << SYNC_RX_CL) | (1 << CTRL_RX_CL)
  186823. + | (1 << ASYNC_RX_CL) | (1 << ISOC_RX_CL)
  186824. + | (1 << SYNC_TX_CL) | (1 << CTRL_TX_CL)
  186825. + | (1 << ASYNC_TX_CL) | (1 << ISOC_TX_CL);
  186826. +
  186827. + /*
  186828. + * Step 5, Read the ACSRn registers to determine which channel or
  186829. + * channels are causing the interrupt
  186830. + */
  186831. + acsr0 = __raw_readl(mlb_base + REG_ACSR0);
  186832. +
  186833. + hcer0 = __raw_readl(mlb_base + REG_HCER0);
  186834. +
  186835. + /*
  186836. + * Step 6, If ACTL.SCE = 1, write the result of step 5 back to ACSR0
  186837. + * and ACSR1 to clear the interrupt
  186838. + * We'll not set ACTL_SCE
  186839. + */
  186840. +
  186841. + if (ch_mask & hcer0)
  186842. + pr_err("CH encounters an AHB error: 0x%x\n", hcer0);
  186843. +
  186844. + if ((1 << SYNC_RX_CL) & acsr0)
  186845. + mlb_rx_isr(MLB_CTYPE_SYNC, SYNC_RX_CL,
  186846. + &mlb_devinfo[MLB_CTYPE_SYNC]);
  186847. +
  186848. + if ((1 << CTRL_RX_CL) & acsr0)
  186849. + mlb_rx_isr(MLB_CTYPE_CTRL, CTRL_RX_CL,
  186850. + &mlb_devinfo[MLB_CTYPE_CTRL]);
  186851. +
  186852. + if ((1 << ASYNC_RX_CL) & acsr0)
  186853. + mlb_rx_isr(MLB_CTYPE_ASYNC, ASYNC_RX_CL,
  186854. + &mlb_devinfo[MLB_CTYPE_ASYNC]);
  186855. +
  186856. + if ((1 << ISOC_RX_CL) & acsr0)
  186857. + mlb_rx_isr(MLB_CTYPE_ISOC, ISOC_RX_CL,
  186858. + &mlb_devinfo[MLB_CTYPE_ISOC]);
  186859. +
  186860. + if ((1 << SYNC_TX_CL) & acsr0)
  186861. + mlb_tx_isr(MLB_CTYPE_SYNC, SYNC_TX_CL,
  186862. + &mlb_devinfo[MLB_CTYPE_SYNC]);
  186863. +
  186864. + if ((1 << CTRL_TX_CL) & acsr0)
  186865. + mlb_tx_isr(MLB_CTYPE_CTRL, CTRL_TX_CL,
  186866. + &mlb_devinfo[MLB_CTYPE_CTRL]);
  186867. +
  186868. + if ((1 << ASYNC_TX_CL) & acsr0)
  186869. + mlb_tx_isr(MLB_CTYPE_ASYNC, ASYNC_TX_CL,
  186870. + &mlb_devinfo[MLB_CTYPE_ASYNC]);
  186871. +
  186872. + if ((1 << ISOC_TX_CL) & acsr0)
  186873. + mlb_tx_isr(MLB_CTYPE_ASYNC, ISOC_TX_CL,
  186874. + &mlb_devinfo[MLB_CTYPE_ISOC]);
  186875. +
  186876. + return IRQ_HANDLED;
  186877. +}
  186878. +
  186879. +static irqreturn_t mlb_isr(int irq, void *dev_id)
  186880. +{
  186881. + u32 rx_int_sts, tx_int_sts, ms0,
  186882. + ms1, tx_cis, rx_cis, ctype;
  186883. + int minor;
  186884. + u32 cdt_val[4] = { 0 };
  186885. +
  186886. + /*
  186887. + * Step 4, Read the MSn register to determine which channel(s)
  186888. + * are causing the interrupt
  186889. + */
  186890. + ms0 = __raw_readl(mlb_base + REG_MS0);
  186891. + ms1 = __raw_readl(mlb_base + REG_MS1);
  186892. +
  186893. + /*
  186894. + * The MLB150_MS0, MLB150_MS1 registers need to be cleared. In
  186895. + * the spec description, the registers should be cleared when
  186896. + * enabling interrupt. In fact, we also should clear it in ISR.
  186897. + */
  186898. + __raw_writel(0, mlb_base + REG_MS0);
  186899. + __raw_writel(0, mlb_base + REG_MS1);
  186900. +
  186901. + pr_debug("mxc_mlb150: mlb interrupt:0x%08x 0x%08x\n",
  186902. + (u32)ms0, (u32)ms1);
  186903. +
  186904. + for (minor = 0; minor < MLB_MINOR_DEVICES; minor++) {
  186905. + struct mlb_dev_info *pdevinfo = &mlb_devinfo[minor];
  186906. + u32 rx_mlb_ch = pdevinfo->channels[RX_CHANNEL].address;
  186907. + u32 tx_mlb_ch = pdevinfo->channels[TX_CHANNEL].address;
  186908. + u32 rx_mlb_cl = pdevinfo->channels[RX_CHANNEL].cl;
  186909. + u32 tx_mlb_cl = pdevinfo->channels[TX_CHANNEL].cl;
  186910. +
  186911. + tx_cis = rx_cis = 0;
  186912. +
  186913. + ctype = pdevinfo->channel_type;
  186914. + rx_int_sts = (rx_mlb_ch < 31) ? ms0 : ms1;
  186915. + tx_int_sts = (tx_mlb_ch < 31) ? ms0 : ms1;
  186916. +
  186917. + pr_debug("mxc_mlb150: channel interrupt: "
  186918. + "tx %d: 0x%08x, rx %d: 0x%08x\n",
  186919. + tx_mlb_ch, (u32)tx_int_sts, rx_mlb_ch, (u32)rx_int_sts);
  186920. +
  186921. + /* Get tx channel interrupt status */
  186922. + if (tx_int_sts & (1 << (tx_mlb_ch % 32))) {
  186923. + mlb150_dev_cdt_read(tx_mlb_cl, cdt_val);
  186924. + pr_debug("mxc_mlb150: TX_CH: %d, cdt_val[3]: 0x%08x, "
  186925. + "cdt_val[2]: 0x%08x, "
  186926. + "cdt_val[1]: 0x%08x, "
  186927. + "cdt_val[0]: 0x%08x\n",
  186928. + tx_mlb_ch, cdt_val[3], cdt_val[2],
  186929. + cdt_val[1], cdt_val[0]);
  186930. + switch (ctype) {
  186931. + case MLB_CTYPE_SYNC:
  186932. + tx_cis = (cdt_val[2] & ~CDT_SYNC_WSTS_MASK)
  186933. + >> CDT_SYNC_WSTS_SHIFT;
  186934. + /*
  186935. + * Clear RSTS/WSTS errors to resume
  186936. + * channel operation
  186937. + * a. For synchronous channels: WSTS[3] = 0
  186938. + */
  186939. + cdt_val[2] &= ~(0x8 << CDT_SYNC_WSTS_SHIFT);
  186940. + break;
  186941. + case MLB_CTYPE_CTRL:
  186942. + case MLB_CTYPE_ASYNC:
  186943. + tx_cis = (cdt_val[2] &
  186944. + ~CDT_CTRL_ASYNC_WSTS_MASK)
  186945. + >> CDT_CTRL_ASYNC_WSTS_SHIFT;
  186946. + tx_cis = (cdt_val[3] & CDT_CTRL_ASYNC_WSTS_1) ?
  186947. + (tx_cis | (0x1 << 4)) : tx_cis;
  186948. + /*
  186949. + * b. For async and ctrl channels:
  186950. + * RSTS[4]/WSTS[4] = 0
  186951. + * and RSTS[2]/WSTS[2] = 0
  186952. + */
  186953. + cdt_val[3] &= ~CDT_CTRL_ASYNC_WSTS_1;
  186954. + cdt_val[2] &=
  186955. + ~(0x4 << CDT_CTRL_ASYNC_WSTS_SHIFT);
  186956. + break;
  186957. + case MLB_CTYPE_ISOC:
  186958. + tx_cis = (cdt_val[2] & ~CDT_ISOC_WSTS_MASK)
  186959. + >> CDT_ISOC_WSTS_SHIFT;
  186960. + /* c. For isoc channels: WSTS[2:1] = 0x00 */
  186961. + cdt_val[2] &= ~(0x6 << CDT_ISOC_WSTS_SHIFT);
  186962. + break;
  186963. + default:
  186964. + break;
  186965. + }
  186966. + mlb150_dev_cdt_write(tx_mlb_ch, cdt_val);
  186967. + }
  186968. +
  186969. + /* Get rx channel interrupt status */
  186970. + if (rx_int_sts & (1 << (rx_mlb_ch % 32))) {
  186971. + mlb150_dev_cdt_read(rx_mlb_cl, cdt_val);
  186972. + pr_debug("mxc_mlb150: RX_CH: %d, cdt_val[3]: 0x%08x, "
  186973. + "cdt_val[2]: 0x%08x, "
  186974. + "cdt_val[1]: 0x%08x, "
  186975. + "cdt_val[0]: 0x%08x\n",
  186976. + rx_mlb_ch, cdt_val[3], cdt_val[2],
  186977. + cdt_val[1], cdt_val[0]);
  186978. + switch (ctype) {
  186979. + case MLB_CTYPE_SYNC:
  186980. + tx_cis = (cdt_val[2] & ~CDT_SYNC_RSTS_MASK)
  186981. + >> CDT_SYNC_RSTS_SHIFT;
  186982. + cdt_val[2] &= ~(0x8 << CDT_SYNC_WSTS_SHIFT);
  186983. + break;
  186984. + case MLB_CTYPE_CTRL:
  186985. + case MLB_CTYPE_ASYNC:
  186986. + tx_cis =
  186987. + (cdt_val[2] & ~CDT_CTRL_ASYNC_RSTS_MASK)
  186988. + >> CDT_CTRL_ASYNC_RSTS_SHIFT;
  186989. + tx_cis = (cdt_val[3] & CDT_CTRL_ASYNC_RSTS_1) ?
  186990. + (tx_cis | (0x1 << 4)) : tx_cis;
  186991. + cdt_val[3] &= ~CDT_CTRL_ASYNC_RSTS_1;
  186992. + cdt_val[2] &=
  186993. + ~(0x4 << CDT_CTRL_ASYNC_RSTS_SHIFT);
  186994. + break;
  186995. + case MLB_CTYPE_ISOC:
  186996. + tx_cis = (cdt_val[2] & ~CDT_ISOC_RSTS_MASK)
  186997. + >> CDT_ISOC_RSTS_SHIFT;
  186998. + cdt_val[2] &= ~(0x6 << CDT_ISOC_WSTS_SHIFT);
  186999. + break;
  187000. + default:
  187001. + break;
  187002. + }
  187003. + mlb150_dev_cdt_write(rx_mlb_ch, cdt_val);
  187004. + }
  187005. +
  187006. + if (!tx_cis && !rx_cis)
  187007. + continue;
  187008. +
  187009. + /* fill exception event */
  187010. + spin_lock(&pdevinfo->event_lock);
  187011. + pdevinfo->ex_event |= (rx_cis << 16) | tx_cis;
  187012. + spin_unlock(&pdevinfo->event_lock);
  187013. + }
  187014. +
  187015. + return IRQ_HANDLED;
  187016. +}
  187017. +
  187018. +static int mxc_mlb150_open(struct inode *inode, struct file *filp)
  187019. +{
  187020. + int minor, ring_buf_size, buf_size, j, ret;
  187021. + void __iomem *buf_addr;
  187022. + ulong phy_addr;
  187023. + struct mlb_dev_info *pdevinfo = NULL;
  187024. + struct mlb_channel_info *pchinfo = NULL;
  187025. + struct mlb_data *drvdata;
  187026. +
  187027. + minor = MINOR(inode->i_rdev);
  187028. + drvdata = container_of(inode->i_cdev, struct mlb_data, cdev);
  187029. +
  187030. + if (minor < 0 || minor >= MLB_MINOR_DEVICES) {
  187031. + pr_err("no device\n");
  187032. + return -ENODEV;
  187033. + }
  187034. +
  187035. + /* open for each channel device */
  187036. + if (atomic_cmpxchg(&mlb_devinfo[minor].opencnt, 0, 1) != 0) {
  187037. + pr_err("busy\n");
  187038. + return -EBUSY;
  187039. + }
  187040. +
  187041. + clk_prepare_enable(drvdata->clk_mlb3p);
  187042. +
  187043. + /* initial MLB module */
  187044. + mlb150_dev_init();
  187045. +
  187046. + pdevinfo = &mlb_devinfo[minor];
  187047. + pchinfo = &pdevinfo->channels[TX_CHANNEL];
  187048. +
  187049. + ring_buf_size = pdevinfo->buf_size;
  187050. + buf_size = ring_buf_size * (TRANS_RING_NODES * 2);
  187051. + buf_addr = (void __iomem *)gen_pool_alloc(drvdata->iram_pool, buf_size);
  187052. + if (buf_addr == NULL) {
  187053. + ret = -ENOMEM;
  187054. + pr_err("can not alloc rx/tx buffers: %d\n", buf_size);
  187055. + return ret;
  187056. + }
  187057. + phy_addr = gen_pool_virt_to_phys(drvdata->iram_pool, (ulong)buf_addr);
  187058. + pr_debug("IRAM Range: Virt 0x%p - 0x%p, Phys 0x%x - 0x%x, size: 0x%x\n",
  187059. + buf_addr, (buf_addr + buf_size - 1), (u32)phy_addr,
  187060. + (u32)(phy_addr + buf_size - 1), buf_size);
  187061. + pdevinfo->rbuf_base_virt = buf_addr;
  187062. + pdevinfo->rbuf_base_phy = phy_addr;
  187063. + drvdata->iram_size = buf_size;
  187064. +
  187065. + memset(buf_addr, 0, buf_size);
  187066. +
  187067. + for (j = 0; j < (TRANS_RING_NODES);
  187068. + ++j, buf_addr += ring_buf_size, phy_addr += ring_buf_size) {
  187069. + pdevinfo->rx_rbuf.virt_bufs[j] = buf_addr;
  187070. + pdevinfo->rx_rbuf.phy_addrs[j] = phy_addr;
  187071. + pr_debug("RX Ringbuf[%d]: 0x%p 0x%x\n",
  187072. + j, buf_addr, (u32)phy_addr);
  187073. + }
  187074. + pdevinfo->rx_rbuf.unit_size = ring_buf_size;
  187075. + pdevinfo->rx_rbuf.total_size = buf_size;
  187076. + for (j = 0; j < (TRANS_RING_NODES);
  187077. + ++j, buf_addr += ring_buf_size, phy_addr += ring_buf_size) {
  187078. + pdevinfo->tx_rbuf.virt_bufs[j] = buf_addr;
  187079. + pdevinfo->tx_rbuf.phy_addrs[j] = phy_addr;
  187080. + pr_debug("TX Ringbuf[%d]: 0x%p 0x%x\n",
  187081. + j, buf_addr, (u32)phy_addr);
  187082. + }
  187083. +
  187084. + pdevinfo->tx_rbuf.unit_size = ring_buf_size;
  187085. + pdevinfo->tx_rbuf.total_size = buf_size;
  187086. +
  187087. + /* reset the buffer read/write ptr */
  187088. + pdevinfo->rx_rbuf.head = pdevinfo->rx_rbuf.tail = 0;
  187089. + pdevinfo->tx_rbuf.head = pdevinfo->tx_rbuf.tail = 0;
  187090. + pdevinfo->ex_event = 0;
  187091. + pdevinfo->tx_ok = 0;
  187092. +
  187093. + init_waitqueue_head(&pdevinfo->rx_wq);
  187094. + init_waitqueue_head(&pdevinfo->tx_wq);
  187095. +
  187096. + drvdata = container_of(inode->i_cdev, struct mlb_data, cdev);
  187097. + drvdata->devinfo = pdevinfo;
  187098. + mxc_mlb150_irq_enable(drvdata, 1);
  187099. + filp->private_data = drvdata;
  187100. +
  187101. + return 0;
  187102. +}
  187103. +
  187104. +static int mxc_mlb150_release(struct inode *inode, struct file *filp)
  187105. +{
  187106. + int minor;
  187107. + struct mlb_data *drvdata = filp->private_data;
  187108. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187109. +
  187110. + minor = MINOR(inode->i_rdev);
  187111. + mxc_mlb150_irq_enable(drvdata, 0);
  187112. +
  187113. +#ifdef DEBUG
  187114. + mlb150_dev_dump_reg();
  187115. + mlb150_dev_dump_ctr_tbl(0, pdevinfo->channels[TX_CHANNEL].cl + 1);
  187116. +#endif
  187117. +
  187118. + gen_pool_free(drvdata->iram_pool,
  187119. + (ulong)pdevinfo->rbuf_base_virt, drvdata->iram_size);
  187120. +
  187121. + mlb150_dev_exit();
  187122. +
  187123. + if (pdevinfo && atomic_read(&pdevinfo->on)
  187124. + && (pdevinfo->fps >= CLK_2048FS))
  187125. + clk_disable_unprepare(drvdata->clk_mlb6p);
  187126. +
  187127. + atomic_set(&pdevinfo->on, 0);
  187128. +
  187129. + clk_disable_unprepare(drvdata->clk_mlb3p);
  187130. + /* decrease the open count */
  187131. + atomic_set(&pdevinfo->opencnt, 0);
  187132. +
  187133. + drvdata->devinfo = NULL;
  187134. +
  187135. + return 0;
  187136. +}
  187137. +
  187138. +static long mxc_mlb150_ioctl(struct file *filp,
  187139. + unsigned int cmd, unsigned long arg)
  187140. +{
  187141. + struct inode *inode = filp->f_dentry->d_inode;
  187142. + struct mlb_data *drvdata = filp->private_data;
  187143. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187144. + void __user *argp = (void __user *)arg;
  187145. + unsigned long flags, event;
  187146. + int minor;
  187147. +
  187148. + minor = MINOR(inode->i_rdev);
  187149. +
  187150. + switch (cmd) {
  187151. + case MLB_CHAN_SETADDR:
  187152. + {
  187153. + unsigned int caddr;
  187154. + /* get channel address from user space */
  187155. + if (copy_from_user(&caddr, argp, sizeof(caddr))) {
  187156. + pr_err("mxc_mlb150: copy from user failed\n");
  187157. + return -EFAULT;
  187158. + }
  187159. + pdevinfo->channels[TX_CHANNEL].address =
  187160. + (caddr >> 16) & 0xFFFF;
  187161. + pdevinfo->channels[RX_CHANNEL].address = caddr & 0xFFFF;
  187162. + pr_debug("mxc_mlb150: set ch addr, tx: %d, rx: %d\n",
  187163. + pdevinfo->channels[TX_CHANNEL].address,
  187164. + pdevinfo->channels[RX_CHANNEL].address);
  187165. + break;
  187166. + }
  187167. +
  187168. + case MLB_CHAN_STARTUP:
  187169. + if (atomic_read(&pdevinfo->on)) {
  187170. + pr_debug("mxc_mlb150: channel alreadly startup\n");
  187171. + break;
  187172. + }
  187173. + if (mlb_channel_enable(drvdata, minor, 1))
  187174. + return -EFAULT;
  187175. + break;
  187176. + case MLB_CHAN_SHUTDOWN:
  187177. + if (atomic_read(&pdevinfo->on) == 0) {
  187178. + pr_debug("mxc_mlb150: channel areadly shutdown\n");
  187179. + break;
  187180. + }
  187181. + mlb150_trans_complete_check(pdevinfo);
  187182. + mlb_channel_enable(drvdata, minor, 0);
  187183. + break;
  187184. + case MLB_CHAN_GETEVENT:
  187185. + /* get and clear the ex_event */
  187186. + spin_lock_irqsave(&pdevinfo->event_lock, flags);
  187187. + event = pdevinfo->ex_event;
  187188. + pdevinfo->ex_event = 0;
  187189. + spin_unlock_irqrestore(&pdevinfo->event_lock, flags);
  187190. +
  187191. + if (event) {
  187192. + if (copy_to_user(argp, &event, sizeof(event))) {
  187193. + pr_err("mxc_mlb150: copy to user failed\n");
  187194. + return -EFAULT;
  187195. + }
  187196. + } else
  187197. + return -EAGAIN;
  187198. + break;
  187199. + case MLB_SET_ISOC_BLKSIZE_188:
  187200. + pdevinfo->isoc_blksz = 188;
  187201. + pdevinfo->cdt_buf_dep = pdevinfo->adt_buf_dep =
  187202. + pdevinfo->isoc_blksz * CH_ISOC_BLK_NUM;
  187203. + break;
  187204. + case MLB_SET_ISOC_BLKSIZE_196:
  187205. + pdevinfo->isoc_blksz = 196;
  187206. + pdevinfo->cdt_buf_dep = pdevinfo->adt_buf_dep =
  187207. + pdevinfo->isoc_blksz * CH_ISOC_BLK_NUM;
  187208. + break;
  187209. + case MLB_SET_SYNC_QUAD:
  187210. + {
  187211. + u32 quad;
  187212. +
  187213. + if (copy_from_user(&quad, argp, sizeof(quad))) {
  187214. + pr_err("mxc_mlb150: get quad number "
  187215. + "from user failed\n");
  187216. + return -EFAULT;
  187217. + }
  187218. + if (quad <= 0 || quad > 3) {
  187219. + pr_err("mxc_mlb150: Invalid Quadlets!"
  187220. + "Quadlets in Sync mode can "
  187221. + "only be 1, 2, 3\n");
  187222. + return -EINVAL;
  187223. + }
  187224. + pdevinfo->sync_quad = quad;
  187225. + /* Each quadlets is 4 bytes */
  187226. + pdevinfo->cdt_buf_dep = quad * 4 * 4;
  187227. + pdevinfo->adt_buf_dep =
  187228. + pdevinfo->cdt_buf_dep * CH_SYNC_ADT_BUF_MULTI;
  187229. + }
  187230. + break;
  187231. + case MLB_SET_FPS:
  187232. + {
  187233. + u32 fps, c0_val;
  187234. +
  187235. + /* get fps from user space */
  187236. + if (copy_from_user(&fps, argp, sizeof(fps))) {
  187237. + pr_err("mxc_mlb150: copy from user failed\n");
  187238. + return -EFAULT;
  187239. + }
  187240. +
  187241. + c0_val = __raw_readl(mlb_base + REG_MLBC0);
  187242. + c0_val &= ~MLBC0_MLBCLK_MASK;
  187243. +
  187244. + /* check fps value */
  187245. + switch (fps) {
  187246. + case 256:
  187247. + case 512:
  187248. + case 1024:
  187249. + pdevinfo->fps = fps >> 9;
  187250. + c0_val &= ~MLBC0_MLBPEN;
  187251. + c0_val |= (fps >> 9)
  187252. + << MLBC0_MLBCLK_SHIFT;
  187253. +
  187254. + if (1024 == fps) {
  187255. + /*
  187256. + * Invert output clock phase
  187257. + * in 1024 fps
  187258. + */
  187259. + __raw_writel(0x1,
  187260. + mlb_base + REG_MLBPC2);
  187261. + }
  187262. + break;
  187263. + case 2048:
  187264. + case 3072:
  187265. + case 4096:
  187266. + pdevinfo->fps = (fps >> 10) + 1;
  187267. + c0_val |= ((fps >> 10) + 1)
  187268. + << MLBC0_MLBCLK_SHIFT;
  187269. + break;
  187270. + case 6144:
  187271. + pdevinfo->fps = fps >> 10;
  187272. + c0_val |= ((fps >> 10) + 1)
  187273. + << MLBC0_MLBCLK_SHIFT;
  187274. + break;
  187275. + case 8192:
  187276. + pdevinfo->fps = (fps >> 10) - 1;
  187277. + c0_val |= ((fps >> 10) - 1)
  187278. + << MLBC0_MLBCLK_SHIFT;
  187279. + break;
  187280. + default:
  187281. + pr_debug("mxc_mlb150: invalid fps argument: %d\n",
  187282. + fps);
  187283. + return -EINVAL;
  187284. + }
  187285. +
  187286. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  187287. +
  187288. + pr_debug("mxc_mlb150: set fps to %d, MLBC0: 0x%08x\n",
  187289. + fps,
  187290. + (u32)__raw_readl(mlb_base + REG_MLBC0));
  187291. +
  187292. + break;
  187293. + }
  187294. +
  187295. + case MLB_GET_VER:
  187296. + {
  187297. + u32 version;
  187298. +
  187299. + /* get MLB device module version */
  187300. + version = 0x03030003;
  187301. +
  187302. + pr_debug("mxc_mlb150: get version: 0x%08x\n",
  187303. + version);
  187304. +
  187305. + if (copy_to_user(argp, &version, sizeof(version))) {
  187306. + pr_err("mxc_mlb150: copy to user failed\n");
  187307. + return -EFAULT;
  187308. + }
  187309. + break;
  187310. + }
  187311. +
  187312. + case MLB_SET_DEVADDR:
  187313. + {
  187314. + u32 c1_val;
  187315. + u8 devaddr;
  187316. +
  187317. + /* get MLB device address from user space */
  187318. + if (copy_from_user
  187319. + (&devaddr, argp, sizeof(unsigned char))) {
  187320. + pr_err("mxc_mlb150: copy from user failed\n");
  187321. + return -EFAULT;
  187322. + }
  187323. +
  187324. + c1_val = __raw_readl(mlb_base + REG_MLBC1);
  187325. + c1_val &= ~MLBC1_NDA_MASK;
  187326. + c1_val |= devaddr << MLBC1_NDA_SHIFT;
  187327. + __raw_writel(c1_val, mlb_base + REG_MLBC1);
  187328. + pr_debug("mxc_mlb150: set dev addr, dev addr: %d, "
  187329. + "MLBC1: 0x%08x\n", devaddr,
  187330. + (u32)__raw_readl(mlb_base + REG_MLBC1));
  187331. +
  187332. + break;
  187333. + }
  187334. +
  187335. + case MLB_IRQ_DISABLE:
  187336. + {
  187337. + disable_irq(drvdata->irq_mlb);
  187338. + break;
  187339. + }
  187340. +
  187341. + case MLB_IRQ_ENABLE:
  187342. + {
  187343. + enable_irq(drvdata->irq_mlb);
  187344. + break;
  187345. + }
  187346. + default:
  187347. + pr_info("mxc_mlb150: Invalid ioctl command\n");
  187348. + return -EINVAL;
  187349. + }
  187350. +
  187351. + return 0;
  187352. +}
  187353. +
  187354. +/*
  187355. + * MLB read routine
  187356. + * Read the current received data from queued buffer,
  187357. + * and free this buffer for hw to fill ingress data.
  187358. + */
  187359. +static ssize_t mxc_mlb150_read(struct file *filp, char __user *buf,
  187360. + size_t count, loff_t *f_pos)
  187361. +{
  187362. + int size;
  187363. + struct mlb_data *drvdata = filp->private_data;
  187364. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187365. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  187366. + int head, tail;
  187367. + unsigned long flags;
  187368. +
  187369. + read_lock_irqsave(&rx_rbuf->rb_lock, flags);
  187370. +
  187371. + head = ACCESS_ONCE(rx_rbuf->head);
  187372. + tail = rx_rbuf->tail;
  187373. +
  187374. + read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
  187375. +
  187376. + /* check the current rx buffer is available or not */
  187377. + if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
  187378. +
  187379. + if (filp->f_flags & O_NONBLOCK)
  187380. + return -EAGAIN;
  187381. +
  187382. + do {
  187383. + DEFINE_WAIT(__wait);
  187384. +
  187385. + for (;;) {
  187386. + prepare_to_wait(&pdevinfo->rx_wq,
  187387. + &__wait, TASK_INTERRUPTIBLE);
  187388. +
  187389. + read_lock_irqsave(&rx_rbuf->rb_lock, flags);
  187390. + if (CIRC_CNT(rx_rbuf->head, rx_rbuf->tail,
  187391. + TRANS_RING_NODES) > 0) {
  187392. + read_unlock_irqrestore(&rx_rbuf->rb_lock,
  187393. + flags);
  187394. + break;
  187395. + }
  187396. + read_unlock_irqrestore(&rx_rbuf->rb_lock,
  187397. + flags);
  187398. +
  187399. + if (!signal_pending(current)) {
  187400. + schedule();
  187401. + continue;
  187402. + }
  187403. + return -ERESTARTSYS;
  187404. + }
  187405. + finish_wait(&pdevinfo->rx_wq, &__wait);
  187406. + } while (0);
  187407. + }
  187408. +
  187409. + /* read index before reading contents at that index */
  187410. + smp_read_barrier_depends();
  187411. +
  187412. + size = pdevinfo->adt_buf_dep;
  187413. + if (size > count) {
  187414. + /* the user buffer is too small */
  187415. + pr_warning
  187416. + ("mxc_mlb150: received data size is bigger than "
  187417. + "size: %d, count: %d\n", size, count);
  187418. + return -EINVAL;
  187419. + }
  187420. +
  187421. + /* extract one item from the buffer */
  187422. + if (copy_to_user(buf, rx_rbuf->virt_bufs[tail], size)) {
  187423. + pr_err("mxc_mlb150: copy from user failed\n");
  187424. + return -EFAULT;
  187425. + }
  187426. +
  187427. + /* finish reading descriptor before incrementing tail */
  187428. + smp_mb();
  187429. +
  187430. + write_lock_irqsave(&rx_rbuf->rb_lock, flags);
  187431. + rx_rbuf->tail = (tail + 1) & (TRANS_RING_NODES - 1);
  187432. + write_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
  187433. +
  187434. + *f_pos = 0;
  187435. +
  187436. + return size;
  187437. +}
  187438. +
  187439. +/*
  187440. + * MLB write routine
  187441. + * Copy the user data to tx channel buffer,
  187442. + * and prepare the channel current/next buffer ptr.
  187443. + */
  187444. +static ssize_t mxc_mlb150_write(struct file *filp, const char __user *buf,
  187445. + size_t count, loff_t *f_pos)
  187446. +{
  187447. + s32 ret = 0;
  187448. + struct mlb_channel_info *pchinfo = NULL;
  187449. + struct mlb_data *drvdata = filp->private_data;
  187450. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187451. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  187452. + int head, tail;
  187453. + unsigned long flags;
  187454. +
  187455. + /*
  187456. + * minor = MINOR(filp->f_dentry->d_inode->i_rdev);
  187457. + */
  187458. + pchinfo = &pdevinfo->channels[TX_CHANNEL];
  187459. +
  187460. + if (count > pdevinfo->buf_size) {
  187461. + /* too many data to write */
  187462. + pr_warning("mxc_mlb150: overflow write data\n");
  187463. + return -EFBIG;
  187464. + }
  187465. +
  187466. + *f_pos = 0;
  187467. +
  187468. + read_lock_irqsave(&tx_rbuf->rb_lock, flags);
  187469. +
  187470. + head = tx_rbuf->head;
  187471. + tail = ACCESS_ONCE(tx_rbuf->tail);
  187472. + read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  187473. +
  187474. + if (0 == CIRC_SPACE(head, tail, TRANS_RING_NODES)) {
  187475. + if (filp->f_flags & O_NONBLOCK)
  187476. + return -EAGAIN;
  187477. + do {
  187478. + DEFINE_WAIT(__wait);
  187479. +
  187480. + for (;;) {
  187481. + prepare_to_wait(&pdevinfo->tx_wq,
  187482. + &__wait, TASK_INTERRUPTIBLE);
  187483. +
  187484. + read_lock_irqsave(&tx_rbuf->rb_lock, flags);
  187485. + if (CIRC_SPACE(tx_rbuf->head, tx_rbuf->tail,
  187486. + TRANS_RING_NODES) > 0) {
  187487. + read_unlock_irqrestore(&tx_rbuf->rb_lock,
  187488. + flags);
  187489. + break;
  187490. + }
  187491. + read_unlock_irqrestore(&tx_rbuf->rb_lock,
  187492. + flags);
  187493. +
  187494. + if (!signal_pending(current)) {
  187495. + schedule();
  187496. + continue;
  187497. + }
  187498. + return -ERESTARTSYS;
  187499. + }
  187500. + finish_wait(&pdevinfo->tx_wq, &__wait);
  187501. + } while (0);
  187502. + }
  187503. +
  187504. + if (copy_from_user((void *)tx_rbuf->virt_bufs[head], buf, count)) {
  187505. + read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  187506. + pr_err("mxc_mlb: copy from user failed\n");
  187507. + ret = -EFAULT;
  187508. + goto out;
  187509. + }
  187510. +
  187511. + write_lock_irqsave(&tx_rbuf->rb_lock, flags);
  187512. + smp_wmb();
  187513. + tx_rbuf->head = (head + 1) & (TRANS_RING_NODES - 1);
  187514. + write_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  187515. +
  187516. + if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
  187517. + u32 tx_buf_ptr, ahb_ch;
  187518. + s32 adt_sts;
  187519. + u32 ctype = pdevinfo->channel_type;
  187520. +
  187521. + /* read index before reading contents at that index */
  187522. + smp_read_barrier_depends();
  187523. +
  187524. + tx_buf_ptr = tx_rbuf->phy_addrs[tail];
  187525. +
  187526. + ahb_ch = pdevinfo->channels[TX_CHANNEL].cl;
  187527. + adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
  187528. +
  187529. + /* Set ADT for TX */
  187530. + mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
  187531. + }
  187532. +
  187533. + ret = count;
  187534. +out:
  187535. + return ret;
  187536. +}
  187537. +
  187538. +static unsigned int mxc_mlb150_poll(struct file *filp,
  187539. + struct poll_table_struct *wait)
  187540. +{
  187541. + int minor;
  187542. + unsigned int ret = 0;
  187543. + struct mlb_data *drvdata = filp->private_data;
  187544. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187545. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  187546. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  187547. + int head, tail;
  187548. + unsigned long flags;
  187549. +
  187550. +
  187551. + minor = MINOR(filp->f_dentry->d_inode->i_rdev);
  187552. +
  187553. + poll_wait(filp, &pdevinfo->rx_wq, wait);
  187554. + poll_wait(filp, &pdevinfo->tx_wq, wait);
  187555. +
  187556. + read_lock_irqsave(&tx_rbuf->rb_lock, flags);
  187557. + head = tx_rbuf->head;
  187558. + tail = tx_rbuf->tail;
  187559. + read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  187560. +
  187561. + /* check the tx buffer is avaiable or not */
  187562. + if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1)
  187563. + ret |= POLLOUT | POLLWRNORM;
  187564. +
  187565. + read_lock_irqsave(&rx_rbuf->rb_lock, flags);
  187566. + head = rx_rbuf->head;
  187567. + tail = rx_rbuf->tail;
  187568. + read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
  187569. +
  187570. + /* check the rx buffer filled or not */
  187571. + if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1)
  187572. + ret |= POLLIN | POLLRDNORM;
  187573. +
  187574. +
  187575. + /* check the exception event */
  187576. + if (pdevinfo->ex_event)
  187577. + ret |= POLLIN | POLLRDNORM;
  187578. +
  187579. + return ret;
  187580. +}
  187581. +
  187582. +/*
  187583. + * char dev file operations structure
  187584. + */
  187585. +static const struct file_operations mxc_mlb150_fops = {
  187586. +
  187587. + .owner = THIS_MODULE,
  187588. + .open = mxc_mlb150_open,
  187589. + .release = mxc_mlb150_release,
  187590. + .unlocked_ioctl = mxc_mlb150_ioctl,
  187591. + .poll = mxc_mlb150_poll,
  187592. + .read = mxc_mlb150_read,
  187593. + .write = mxc_mlb150_write,
  187594. +};
  187595. +
  187596. +static struct platform_device_id imx_mlb150_devtype[] = {
  187597. + {
  187598. + .name = "imx6q-mlb150",
  187599. + .driver_data = 0,
  187600. + }, {
  187601. + /* sentinel */
  187602. + }
  187603. +};
  187604. +MODULE_DEVICE_TABLE(platform, imx_mlb150_devtype);
  187605. +
  187606. +static const struct of_device_id mlb150_imx_dt_ids[] = {
  187607. + { .compatible = "fsl,imx6q-mlb150", .data = &imx_mlb150_devtype[0], },
  187608. + { /* sentinel */ }
  187609. +};
  187610. +
  187611. +/*
  187612. + * This function is called whenever the MLB device is detected.
  187613. + */
  187614. +static int mxc_mlb150_probe(struct platform_device *pdev)
  187615. +{
  187616. + int ret, mlb_major, i;
  187617. + struct mlb_data *drvdata;
  187618. + struct resource *res;
  187619. + struct device_node *np = pdev->dev.of_node;
  187620. +
  187621. + drvdata = devm_kzalloc(&pdev->dev, sizeof(struct mlb_data),
  187622. + GFP_KERNEL);
  187623. + if (!drvdata) {
  187624. + dev_err(&pdev->dev, "can't allocate enough memory\n");
  187625. + return -ENOMEM;
  187626. + }
  187627. +
  187628. + /*
  187629. + * Register MLB lld as four character devices
  187630. + */
  187631. + ret = alloc_chrdev_region(&drvdata->firstdev, 0,
  187632. + MLB_MINOR_DEVICES, "mxc_mlb150");
  187633. + if (ret < 0) {
  187634. + dev_err(&pdev->dev, "alloc region error\n");
  187635. + goto err_reg;
  187636. + }
  187637. + mlb_major = MAJOR(drvdata->firstdev);
  187638. + dev_dbg(&pdev->dev, "MLB device major: %d\n", mlb_major);
  187639. +
  187640. + cdev_init(&drvdata->cdev, &mxc_mlb150_fops);
  187641. + drvdata->cdev.owner = THIS_MODULE;
  187642. +
  187643. + ret = cdev_add(&drvdata->cdev, drvdata->firstdev, MLB_MINOR_DEVICES);
  187644. + if (ret) {
  187645. + dev_err(&pdev->dev, "can't add cdev\n");
  187646. + goto err_reg;
  187647. + }
  187648. +
  187649. + /* create class and device for udev information */
  187650. + drvdata->class = class_create(THIS_MODULE, "mlb150");
  187651. + if (IS_ERR(drvdata->class)) {
  187652. + dev_err(&pdev->dev, "failed to create device class\n");
  187653. + ret = -ENOMEM;
  187654. + goto err_class;
  187655. + }
  187656. +
  187657. + for (i = 0; i < MLB_MINOR_DEVICES; i++) {
  187658. + struct device *class_dev;
  187659. +
  187660. + class_dev = device_create(drvdata->class, NULL,
  187661. + MKDEV(mlb_major, i),
  187662. + NULL, mlb_devinfo[i].dev_name);
  187663. + if (IS_ERR(class_dev)) {
  187664. + dev_err(&pdev->dev, "failed to create mlb150 %s"
  187665. + " class device\n", mlb_devinfo[i].dev_name);
  187666. + ret = -ENOMEM;
  187667. + goto err_dev;
  187668. + }
  187669. + }
  187670. +
  187671. + /* ahb0 irq */
  187672. + drvdata->irq_ahb0 = platform_get_irq(pdev, 1);
  187673. + if (drvdata->irq_ahb0 < 0) {
  187674. + dev_err(&pdev->dev, "No ahb0 irq line provided\n");
  187675. + goto err_dev;
  187676. + }
  187677. + dev_dbg(&pdev->dev, "ahb0_irq: %d\n", drvdata->irq_ahb0);
  187678. + if (devm_request_irq(&pdev->dev, drvdata->irq_ahb0, mlb_ahb_isr,
  187679. + 0, "mlb_ahb0", NULL)) {
  187680. + dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_ahb0);
  187681. + goto err_dev;
  187682. + }
  187683. +
  187684. + /* ahb1 irq */
  187685. + drvdata->irq_ahb1 = platform_get_irq(pdev, 2);
  187686. + if (drvdata->irq_ahb1 < 0) {
  187687. + dev_err(&pdev->dev, "No ahb1 irq line provided\n");
  187688. + goto err_dev;
  187689. + }
  187690. + dev_dbg(&pdev->dev, "ahb1_irq: %d\n", drvdata->irq_ahb1);
  187691. + if (devm_request_irq(&pdev->dev, drvdata->irq_ahb1, mlb_ahb_isr,
  187692. + 0, "mlb_ahb1", NULL)) {
  187693. + dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_ahb1);
  187694. + goto err_dev;
  187695. + }
  187696. +
  187697. + /* mlb irq */
  187698. + drvdata->irq_mlb = platform_get_irq(pdev, 0);
  187699. + if (drvdata->irq_mlb < 0) {
  187700. + dev_err(&pdev->dev, "No mlb irq line provided\n");
  187701. + goto err_dev;
  187702. + }
  187703. + dev_dbg(&pdev->dev, "mlb_irq: %d\n", drvdata->irq_mlb);
  187704. + if (devm_request_irq(&pdev->dev, drvdata->irq_mlb, mlb_isr,
  187705. + 0, "mlb", NULL)) {
  187706. + dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_mlb);
  187707. + goto err_dev;
  187708. + }
  187709. +
  187710. + /* ioremap from phy mlb to kernel space */
  187711. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  187712. + if (!res) {
  187713. + dev_err(&pdev->dev, "can't get device resources\n");
  187714. + ret = -ENOENT;
  187715. + goto err_dev;
  187716. + }
  187717. + mlb_base = devm_request_and_ioremap(&pdev->dev, res);
  187718. + dev_dbg(&pdev->dev, "mapped base address: 0x%08x\n", (u32)mlb_base);
  187719. + if (IS_ERR(mlb_base)) {
  187720. + dev_err(&pdev->dev,
  187721. + "failed to get ioremap base\n");
  187722. + ret = PTR_ERR(mlb_base);
  187723. + goto err_dev;
  187724. + }
  187725. + drvdata->membase = mlb_base;
  187726. +
  187727. +#ifdef CONFIG_REGULATOR
  187728. + drvdata->nvcc = devm_regulator_get(&pdev->dev, "reg_nvcc");
  187729. + if (!IS_ERR(drvdata->nvcc)) {
  187730. + regulator_set_voltage(drvdata->nvcc, 2500000, 2500000);
  187731. + dev_err(&pdev->dev, "enalbe regulator\n");
  187732. + ret = regulator_enable(drvdata->nvcc);
  187733. + if (ret) {
  187734. + dev_err(&pdev->dev, "vdd set voltage error\n");
  187735. + goto err_dev;
  187736. + }
  187737. + }
  187738. +#endif
  187739. +
  187740. + /* enable clock */
  187741. + drvdata->clk_mlb3p = devm_clk_get(&pdev->dev, "mlb");
  187742. + if (IS_ERR(drvdata->clk_mlb3p)) {
  187743. + dev_err(&pdev->dev, "unable to get mlb clock\n");
  187744. + ret = PTR_ERR(drvdata->clk_mlb3p);
  187745. + goto err_dev;
  187746. + }
  187747. +
  187748. + drvdata->clk_mlb6p = devm_clk_get(&pdev->dev, "pll8_mlb");
  187749. + if (IS_ERR(drvdata->clk_mlb6p)) {
  187750. + dev_err(&pdev->dev, "unable to get mlb pll clock\n");
  187751. + ret = PTR_ERR(drvdata->clk_mlb6p);
  187752. + goto err_dev;
  187753. + }
  187754. +
  187755. +
  187756. + drvdata->iram_pool = of_get_named_gen_pool(np, "iram", 0);
  187757. + if (!drvdata->iram_pool) {
  187758. + dev_err(&pdev->dev, "iram pool not available\n");
  187759. + ret = -ENOMEM;
  187760. + goto err_dev;
  187761. + }
  187762. +
  187763. + drvdata->devinfo = NULL;
  187764. + mxc_mlb150_irq_enable(drvdata, 0);
  187765. + platform_set_drvdata(pdev, drvdata);
  187766. + return 0;
  187767. +
  187768. +err_dev:
  187769. + for (--i; i >= 0; i--)
  187770. + device_destroy(drvdata->class, MKDEV(mlb_major, i));
  187771. +
  187772. + class_destroy(drvdata->class);
  187773. +err_class:
  187774. + cdev_del(&drvdata->cdev);
  187775. +err_reg:
  187776. + unregister_chrdev_region(drvdata->firstdev, MLB_MINOR_DEVICES);
  187777. +
  187778. + return ret;
  187779. +}
  187780. +
  187781. +static int mxc_mlb150_remove(struct platform_device *pdev)
  187782. +{
  187783. + int i;
  187784. + struct mlb_data *drvdata = platform_get_drvdata(pdev);
  187785. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187786. +
  187787. + if (pdevinfo && atomic_read(&pdevinfo->on)
  187788. + && (pdevinfo->fps >= CLK_2048FS))
  187789. + clk_disable_unprepare(drvdata->clk_mlb6p);
  187790. +
  187791. + if (pdevinfo && atomic_read(&pdevinfo->opencnt))
  187792. + clk_disable_unprepare(drvdata->clk_mlb3p);
  187793. +
  187794. + /* disable mlb power */
  187795. +#ifdef CONFIG_REGULATOR
  187796. + if (!IS_ERR(drvdata->nvcc))
  187797. + regulator_disable(drvdata->nvcc);
  187798. +#endif
  187799. +
  187800. + /* destroy mlb device class */
  187801. + for (i = MLB_MINOR_DEVICES - 1; i >= 0; i--)
  187802. + device_destroy(drvdata->class,
  187803. + MKDEV(MAJOR(drvdata->firstdev), i));
  187804. + class_destroy(drvdata->class);
  187805. +
  187806. + cdev_del(&drvdata->cdev);
  187807. +
  187808. + /* Unregister the two MLB devices */
  187809. + unregister_chrdev_region(drvdata->firstdev, MLB_MINOR_DEVICES);
  187810. +
  187811. + return 0;
  187812. +}
  187813. +
  187814. +#ifdef CONFIG_PM
  187815. +static int mxc_mlb150_suspend(struct platform_device *pdev, pm_message_t state)
  187816. +{
  187817. + struct mlb_data *drvdata = platform_get_drvdata(pdev);
  187818. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187819. +
  187820. + if (pdevinfo && atomic_read(&pdevinfo->on)
  187821. + && (pdevinfo->fps >= CLK_2048FS))
  187822. + clk_disable_unprepare(drvdata->clk_mlb6p);
  187823. +
  187824. + if (pdevinfo && atomic_read(&pdevinfo->opencnt)) {
  187825. + mlb150_dev_exit();
  187826. + clk_disable_unprepare(drvdata->clk_mlb3p);
  187827. + }
  187828. +
  187829. + return 0;
  187830. +}
  187831. +
  187832. +static int mxc_mlb150_resume(struct platform_device *pdev)
  187833. +{
  187834. + struct mlb_data *drvdata = platform_get_drvdata(pdev);
  187835. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  187836. +
  187837. + if (pdevinfo && atomic_read(&pdevinfo->opencnt)) {
  187838. + clk_prepare_enable(drvdata->clk_mlb3p);
  187839. + mlb150_dev_init();
  187840. + }
  187841. +
  187842. + if (pdevinfo && atomic_read(&pdevinfo->on) &&
  187843. + (pdevinfo->fps >= CLK_2048FS))
  187844. + clk_prepare_enable(drvdata->clk_mlb6p);
  187845. +
  187846. + return 0;
  187847. +}
  187848. +#else
  187849. +#define mxc_mlb150_suspend NULL
  187850. +#define mxc_mlb150_resume NULL
  187851. +#endif
  187852. +
  187853. +/*
  187854. + * platform driver structure for MLB
  187855. + */
  187856. +static struct platform_driver mxc_mlb150_driver = {
  187857. + .driver = {
  187858. + .name = DRIVER_NAME,
  187859. + .owner = THIS_MODULE,
  187860. + .of_match_table = mlb150_imx_dt_ids,
  187861. + },
  187862. + .probe = mxc_mlb150_probe,
  187863. + .remove = mxc_mlb150_remove,
  187864. + .suspend = mxc_mlb150_suspend,
  187865. + .resume = mxc_mlb150_resume,
  187866. + .id_table = imx_mlb150_devtype,
  187867. +};
  187868. +
  187869. +static int __init mxc_mlb150_init(void)
  187870. +{
  187871. + return platform_driver_register(&mxc_mlb150_driver);
  187872. +}
  187873. +
  187874. +static void __exit mxc_mlb150_exit(void)
  187875. +{
  187876. + platform_driver_unregister(&mxc_mlb150_driver);
  187877. +}
  187878. +
  187879. +module_init(mxc_mlb150_init);
  187880. +module_exit(mxc_mlb150_exit);
  187881. +
  187882. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  187883. +MODULE_DESCRIPTION("MLB150 low level driver");
  187884. +MODULE_LICENSE("GPL");
  187885. diff -Nur linux-3.14.14/drivers/mxc/vpu/Kconfig linux-imx6-3.14/drivers/mxc/vpu/Kconfig
  187886. --- linux-3.14.14/drivers/mxc/vpu/Kconfig 1969-12-31 18:00:00.000000000 -0600
  187887. +++ linux-imx6-3.14/drivers/mxc/vpu/Kconfig 2014-12-08 00:31:53.476418001 -0600
  187888. @@ -0,0 +1,31 @@
  187889. +#
  187890. +# Codec configuration
  187891. +#
  187892. +
  187893. +menu "MXC VPU(Video Processing Unit) support"
  187894. +
  187895. +config MXC_VPU
  187896. + tristate "Support for MXC VPU(Video Processing Unit)"
  187897. + depends on (SOC_IMX27 || SOC_IMX5 || SOC_IMX6Q)
  187898. + default y
  187899. + ---help---
  187900. + The VPU codec device provides codec function for H.264/MPEG4/H.263,
  187901. + as well as MPEG2/VC-1/DivX on some platforms.
  187902. +
  187903. +config MXC_VPU_DEBUG
  187904. + bool "MXC VPU debugging"
  187905. + depends on MXC_VPU != n
  187906. + help
  187907. + This is an option for the developers; most people should
  187908. + say N here. This enables MXC VPU driver debugging.
  187909. +
  187910. +config MX6_VPU_352M
  187911. + bool "MX6 VPU 352M"
  187912. + depends on MXC_VPU
  187913. + default n
  187914. + help
  187915. + Increase VPU frequncy to 352M, the config will disable bus frequency
  187916. + adjust dynamic, and CPU lowest setpoint will be 352Mhz.
  187917. + This config is used for special VPU use case.
  187918. +
  187919. +endmenu
  187920. diff -Nur linux-3.14.14/drivers/mxc/vpu/Makefile linux-imx6-3.14/drivers/mxc/vpu/Makefile
  187921. --- linux-3.14.14/drivers/mxc/vpu/Makefile 1969-12-31 18:00:00.000000000 -0600
  187922. +++ linux-imx6-3.14/drivers/mxc/vpu/Makefile 2014-12-08 00:31:53.476418001 -0600
  187923. @@ -0,0 +1,9 @@
  187924. +#
  187925. +# Makefile for the VPU drivers.
  187926. +#
  187927. +
  187928. +obj-$(CONFIG_MXC_VPU) += mxc_vpu.o
  187929. +
  187930. +ifeq ($(CONFIG_MXC_VPU_DEBUG),y)
  187931. +EXTRA_CFLAGS += -DDEBUG
  187932. +endif
  187933. diff -Nur linux-3.14.14/drivers/mxc/vpu/mxc_vpu.c linux-imx6-3.14/drivers/mxc/vpu/mxc_vpu.c
  187934. --- linux-3.14.14/drivers/mxc/vpu/mxc_vpu.c 1969-12-31 18:00:00.000000000 -0600
  187935. +++ linux-imx6-3.14/drivers/mxc/vpu/mxc_vpu.c 2014-12-08 00:31:53.476418001 -0600
  187936. @@ -0,0 +1,1342 @@
  187937. +/*
  187938. + * Copyright 2006-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  187939. + */
  187940. +
  187941. +/*
  187942. + * The code contained herein is licensed under the GNU General Public
  187943. + * License. You may obtain a copy of the GNU General Public License
  187944. + * Version 2 or later at the following locations:
  187945. + *
  187946. + * http://www.opensource.org/licenses/gpl-license.html
  187947. + * http://www.gnu.org/copyleft/gpl.html
  187948. + */
  187949. +
  187950. +/*!
  187951. + * @file mxc_vpu.c
  187952. + *
  187953. + * @brief VPU system initialization and file operation implementation
  187954. + *
  187955. + * @ingroup VPU
  187956. + */
  187957. +
  187958. +#include <linux/kernel.h>
  187959. +#include <linux/mm.h>
  187960. +#include <linux/interrupt.h>
  187961. +#include <linux/ioport.h>
  187962. +#include <linux/stat.h>
  187963. +#include <linux/platform_device.h>
  187964. +#include <linux/kdev_t.h>
  187965. +#include <linux/dma-mapping.h>
  187966. +#include <linux/wait.h>
  187967. +#include <linux/list.h>
  187968. +#include <linux/clk.h>
  187969. +#include <linux/delay.h>
  187970. +#include <linux/fsl_devices.h>
  187971. +#include <linux/uaccess.h>
  187972. +#include <linux/io.h>
  187973. +#include <linux/slab.h>
  187974. +#include <linux/workqueue.h>
  187975. +#include <linux/sched.h>
  187976. +#include <linux/vmalloc.h>
  187977. +#include <linux/regulator/consumer.h>
  187978. +#include <linux/page-flags.h>
  187979. +#include <linux/mm_types.h>
  187980. +#include <linux/types.h>
  187981. +#include <linux/memblock.h>
  187982. +#include <linux/memory.h>
  187983. +#include <linux/version.h>
  187984. +#include <asm/page.h>
  187985. +
  187986. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  187987. +#include <linux/module.h>
  187988. +#include <linux/pm_runtime.h>
  187989. +#include <linux/sizes.h>
  187990. +#endif
  187991. +
  187992. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
  187993. +#include <linux/iram_alloc.h>
  187994. +#include <mach/clock.h>
  187995. +#include <mach/hardware.h>
  187996. +#include <mach/mxc_vpu.h>
  187997. +#endif
  187998. +
  187999. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188000. +#include <linux/busfreq-imx6.h>
  188001. +#include <linux/clk.h>
  188002. +#include <linux/genalloc.h>
  188003. +#include <linux/mxc_vpu.h>
  188004. +#include <linux/of.h>
  188005. +#include <linux/reset.h>
  188006. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188007. +#include <mach/busfreq.h>
  188008. +#include <mach/common.h>
  188009. +#else
  188010. +#include <asm/sizes.h>
  188011. +#endif
  188012. +
  188013. +/* Define one new pgprot which combined uncached and XN(never executable) */
  188014. +#define pgprot_noncachedxn(prot) \
  188015. + __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
  188016. +
  188017. +struct vpu_priv {
  188018. + struct fasync_struct *async_queue;
  188019. + struct work_struct work;
  188020. + struct workqueue_struct *workqueue;
  188021. + struct mutex lock;
  188022. +};
  188023. +
  188024. +/* To track the allocated memory buffer */
  188025. +struct memalloc_record {
  188026. + struct list_head list;
  188027. + struct vpu_mem_desc mem;
  188028. +};
  188029. +
  188030. +struct iram_setting {
  188031. + u32 start;
  188032. + u32 end;
  188033. +};
  188034. +
  188035. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188036. +static struct gen_pool *iram_pool;
  188037. +static u32 iram_base;
  188038. +#endif
  188039. +
  188040. +static LIST_HEAD(head);
  188041. +
  188042. +static int vpu_major;
  188043. +static int vpu_clk_usercount;
  188044. +static struct class *vpu_class;
  188045. +static struct vpu_priv vpu_data;
  188046. +static u8 open_count;
  188047. +static struct clk *vpu_clk;
  188048. +static struct vpu_mem_desc bitwork_mem = { 0 };
  188049. +static struct vpu_mem_desc pic_para_mem = { 0 };
  188050. +static struct vpu_mem_desc user_data_mem = { 0 };
  188051. +static struct vpu_mem_desc share_mem = { 0 };
  188052. +static struct vpu_mem_desc vshare_mem = { 0 };
  188053. +
  188054. +static void __iomem *vpu_base;
  188055. +static int vpu_ipi_irq;
  188056. +static u32 phy_vpu_base_addr;
  188057. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  188058. +static phys_addr_t top_address_DRAM;
  188059. +static struct mxc_vpu_platform_data *vpu_plat;
  188060. +#endif
  188061. +
  188062. +static struct device *vpu_dev;
  188063. +
  188064. +/* IRAM setting */
  188065. +static struct iram_setting iram;
  188066. +
  188067. +/* implement the blocking ioctl */
  188068. +static int irq_status;
  188069. +static int codec_done;
  188070. +static wait_queue_head_t vpu_queue;
  188071. +
  188072. +#ifdef CONFIG_SOC_IMX6Q
  188073. +#define MXC_VPU_HAS_JPU
  188074. +#endif
  188075. +
  188076. +#ifdef MXC_VPU_HAS_JPU
  188077. +static int vpu_jpu_irq;
  188078. +#endif
  188079. +
  188080. +#ifdef CONFIG_PM
  188081. +static unsigned int regBk[64];
  188082. +static unsigned int pc_before_suspend;
  188083. +#endif
  188084. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188085. +static struct regulator *vpu_regulator;
  188086. +#endif
  188087. +static atomic_t clk_cnt_from_ioc = ATOMIC_INIT(0);
  188088. +
  188089. +#define READ_REG(x) readl_relaxed(vpu_base + x)
  188090. +#define WRITE_REG(val, x) writel_relaxed(val, vpu_base + x)
  188091. +
  188092. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188093. +/* redirect to static functions */
  188094. +static int cpu_is_mx6dl(void)
  188095. +{
  188096. + int ret;
  188097. + ret = of_machine_is_compatible("fsl,imx6dl");
  188098. + return ret;
  188099. +}
  188100. +
  188101. +static int cpu_is_mx6q(void)
  188102. +{
  188103. + int ret;
  188104. + ret = of_machine_is_compatible("fsl,imx6q");
  188105. + return ret;
  188106. +}
  188107. +#endif
  188108. +
  188109. +static void vpu_reset(void)
  188110. +{
  188111. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188112. + device_reset(vpu_dev);
  188113. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188114. + imx_src_reset_vpu();
  188115. +#else
  188116. + if (vpu_plat->reset)
  188117. + vpu_plat->reset();
  188118. +#endif
  188119. +}
  188120. +
  188121. +static long vpu_power_get(bool on)
  188122. +{
  188123. + long ret = 0;
  188124. +
  188125. + if (on) {
  188126. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  188127. + vpu_regulator = regulator_get(NULL, "cpu_vddvpu");
  188128. + ret = IS_ERR(vpu_regulator);
  188129. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188130. + vpu_regulator = devm_regulator_get(vpu_dev, "pu");
  188131. + ret = IS_ERR(vpu_regulator);
  188132. +#endif
  188133. + } else {
  188134. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  188135. + if (!IS_ERR(vpu_regulator))
  188136. + regulator_put(vpu_regulator);
  188137. +#endif
  188138. + }
  188139. + return ret;
  188140. +}
  188141. +
  188142. +static void vpu_power_up(bool on)
  188143. +{
  188144. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188145. + int ret = 0;
  188146. +
  188147. + if (on) {
  188148. + if (!IS_ERR(vpu_regulator)) {
  188149. + ret = regulator_enable(vpu_regulator);
  188150. + if (ret)
  188151. + dev_err(vpu_dev, "failed to power up vpu\n");
  188152. + }
  188153. + } else {
  188154. + if (!IS_ERR(vpu_regulator)) {
  188155. + ret = regulator_disable(vpu_regulator);
  188156. + if (ret)
  188157. + dev_err(vpu_dev, "failed to power down vpu\n");
  188158. + }
  188159. + }
  188160. +#else
  188161. + imx_gpc_power_up_pu(on);
  188162. +#endif
  188163. +}
  188164. +
  188165. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188166. +static int cpu_is_mx53(void)
  188167. +{
  188168. + return 0;
  188169. +}
  188170. +
  188171. +static int cpu_is_mx51(void)
  188172. +{
  188173. + return 0;
  188174. +}
  188175. +
  188176. +#define VM_RESERVED 0
  188177. +#endif
  188178. +
  188179. +/*!
  188180. + * Private function to alloc dma buffer
  188181. + * @return status 0 success.
  188182. + */
  188183. +static int vpu_alloc_dma_buffer(struct vpu_mem_desc *mem)
  188184. +{
  188185. + mem->cpu_addr = (unsigned long)
  188186. + dma_alloc_coherent(NULL, PAGE_ALIGN(mem->size),
  188187. + (dma_addr_t *) (&mem->phy_addr),
  188188. + GFP_DMA | GFP_KERNEL);
  188189. + dev_dbg(vpu_dev, "[ALLOC] mem alloc cpu_addr = 0x%x\n", mem->cpu_addr);
  188190. + if ((void *)(mem->cpu_addr) == NULL) {
  188191. + dev_err(vpu_dev, "Physical memory allocation error!\n");
  188192. + return -1;
  188193. + }
  188194. + return 0;
  188195. +}
  188196. +
  188197. +/*!
  188198. + * Private function to free dma buffer
  188199. + */
  188200. +static void vpu_free_dma_buffer(struct vpu_mem_desc *mem)
  188201. +{
  188202. + if (mem->cpu_addr != 0) {
  188203. + dma_free_coherent(0, PAGE_ALIGN(mem->size),
  188204. + (void *)mem->cpu_addr, mem->phy_addr);
  188205. + }
  188206. +}
  188207. +
  188208. +/*!
  188209. + * Private function to free buffers
  188210. + * @return status 0 success.
  188211. + */
  188212. +static int vpu_free_buffers(void)
  188213. +{
  188214. + struct memalloc_record *rec, *n;
  188215. + struct vpu_mem_desc mem;
  188216. +
  188217. + list_for_each_entry_safe(rec, n, &head, list) {
  188218. + mem = rec->mem;
  188219. + if (mem.cpu_addr != 0) {
  188220. + vpu_free_dma_buffer(&mem);
  188221. + dev_dbg(vpu_dev, "[FREE] freed paddr=0x%08X\n", mem.phy_addr);
  188222. + /* delete from list */
  188223. + list_del(&rec->list);
  188224. + kfree(rec);
  188225. + }
  188226. + }
  188227. +
  188228. + return 0;
  188229. +}
  188230. +
  188231. +static inline void vpu_worker_callback(struct work_struct *w)
  188232. +{
  188233. + struct vpu_priv *dev = container_of(w, struct vpu_priv,
  188234. + work);
  188235. +
  188236. + if (dev->async_queue)
  188237. + kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
  188238. +
  188239. + irq_status = 1;
  188240. + /*
  188241. + * Clock is gated on when dec/enc started, gate it off when
  188242. + * codec is done.
  188243. + */
  188244. + if (codec_done)
  188245. + codec_done = 0;
  188246. +
  188247. + wake_up_interruptible(&vpu_queue);
  188248. +}
  188249. +
  188250. +/*!
  188251. + * @brief vpu interrupt handler
  188252. + */
  188253. +static irqreturn_t vpu_ipi_irq_handler(int irq, void *dev_id)
  188254. +{
  188255. + struct vpu_priv *dev = dev_id;
  188256. + unsigned long reg;
  188257. +
  188258. + reg = READ_REG(BIT_INT_REASON);
  188259. + if (reg & 0x8)
  188260. + codec_done = 1;
  188261. + WRITE_REG(0x1, BIT_INT_CLEAR);
  188262. +
  188263. + queue_work(dev->workqueue, &dev->work);
  188264. +
  188265. + return IRQ_HANDLED;
  188266. +}
  188267. +
  188268. +/*!
  188269. + * @brief vpu jpu interrupt handler
  188270. + */
  188271. +#ifdef MXC_VPU_HAS_JPU
  188272. +static irqreturn_t vpu_jpu_irq_handler(int irq, void *dev_id)
  188273. +{
  188274. + struct vpu_priv *dev = dev_id;
  188275. + unsigned long reg;
  188276. +
  188277. + reg = READ_REG(MJPEG_PIC_STATUS_REG);
  188278. + if (reg & 0x3)
  188279. + codec_done = 1;
  188280. +
  188281. + queue_work(dev->workqueue, &dev->work);
  188282. +
  188283. + return IRQ_HANDLED;
  188284. +}
  188285. +#endif
  188286. +
  188287. +/*!
  188288. + * @brief check phy memory prepare to pass to vpu is valid or not, we
  188289. + * already address some issue that if pass a wrong address to vpu
  188290. + * (like virtual address), system will hang.
  188291. + *
  188292. + * @return true return is a valid phy memory address, false return not.
  188293. + */
  188294. +bool vpu_is_valid_phy_memory(u32 paddr)
  188295. +{
  188296. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  188297. + if (paddr > top_address_DRAM)
  188298. + return false;
  188299. +#endif
  188300. +
  188301. + return true;
  188302. +}
  188303. +
  188304. +/*!
  188305. + * @brief open function for vpu file operation
  188306. + *
  188307. + * @return 0 on success or negative error code on error
  188308. + */
  188309. +static int vpu_open(struct inode *inode, struct file *filp)
  188310. +{
  188311. +
  188312. + mutex_lock(&vpu_data.lock);
  188313. +
  188314. + if (open_count++ == 0) {
  188315. +
  188316. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188317. + pm_runtime_get_sync(vpu_dev);
  188318. +#endif
  188319. + vpu_power_up(true);
  188320. +
  188321. +#ifdef CONFIG_SOC_IMX6Q
  188322. + clk_prepare(vpu_clk);
  188323. + clk_enable(vpu_clk);
  188324. + if (READ_REG(BIT_CUR_PC))
  188325. + dev_dbg(vpu_dev, "Not power off before vpu open!\n");
  188326. + clk_disable(vpu_clk);
  188327. + clk_unprepare(vpu_clk);
  188328. +#endif
  188329. + }
  188330. +
  188331. + filp->private_data = (void *)(&vpu_data);
  188332. + mutex_unlock(&vpu_data.lock);
  188333. + return 0;
  188334. +}
  188335. +
  188336. +/*!
  188337. + * @brief IO ctrl function for vpu file operation
  188338. + * @param cmd IO ctrl command
  188339. + * @return 0 on success or negative error code on error
  188340. + */
  188341. +static long vpu_ioctl(struct file *filp, u_int cmd,
  188342. + u_long arg)
  188343. +{
  188344. + int ret = 0;
  188345. +
  188346. + switch (cmd) {
  188347. + case VPU_IOC_PHYMEM_ALLOC:
  188348. + {
  188349. + struct memalloc_record *rec;
  188350. +
  188351. + rec = kzalloc(sizeof(*rec), GFP_KERNEL);
  188352. + if (!rec)
  188353. + return -ENOMEM;
  188354. +
  188355. + ret = copy_from_user(&(rec->mem),
  188356. + (struct vpu_mem_desc *)arg,
  188357. + sizeof(struct vpu_mem_desc));
  188358. + if (ret) {
  188359. + kfree(rec);
  188360. + return -EFAULT;
  188361. + }
  188362. +
  188363. + dev_dbg(vpu_dev, "[ALLOC] mem alloc size = 0x%x\n",
  188364. + rec->mem.size);
  188365. +
  188366. + ret = vpu_alloc_dma_buffer(&(rec->mem));
  188367. + if (ret == -1) {
  188368. + kfree(rec);
  188369. + dev_err(vpu_dev,
  188370. + "Physical memory allocation error!\n");
  188371. + break;
  188372. + }
  188373. + ret = copy_to_user((void __user *)arg, &(rec->mem),
  188374. + sizeof(struct vpu_mem_desc));
  188375. + if (ret) {
  188376. + kfree(rec);
  188377. + ret = -EFAULT;
  188378. + break;
  188379. + }
  188380. +
  188381. + mutex_lock(&vpu_data.lock);
  188382. + list_add(&rec->list, &head);
  188383. + mutex_unlock(&vpu_data.lock);
  188384. +
  188385. + break;
  188386. + }
  188387. + case VPU_IOC_PHYMEM_FREE:
  188388. + {
  188389. + struct memalloc_record *rec, *n;
  188390. + struct vpu_mem_desc vpu_mem;
  188391. +
  188392. + ret = copy_from_user(&vpu_mem,
  188393. + (struct vpu_mem_desc *)arg,
  188394. + sizeof(struct vpu_mem_desc));
  188395. + if (ret)
  188396. + return -EACCES;
  188397. +
  188398. + dev_dbg(vpu_dev, "[FREE] mem freed cpu_addr = 0x%x\n",
  188399. + vpu_mem.cpu_addr);
  188400. + if ((void *)vpu_mem.cpu_addr != NULL)
  188401. + vpu_free_dma_buffer(&vpu_mem);
  188402. +
  188403. + mutex_lock(&vpu_data.lock);
  188404. + list_for_each_entry_safe(rec, n, &head, list) {
  188405. + if (rec->mem.cpu_addr == vpu_mem.cpu_addr) {
  188406. + /* delete from list */
  188407. + list_del(&rec->list);
  188408. + kfree(rec);
  188409. + break;
  188410. + }
  188411. + }
  188412. + mutex_unlock(&vpu_data.lock);
  188413. +
  188414. + break;
  188415. + }
  188416. + case VPU_IOC_WAIT4INT:
  188417. + {
  188418. + u_long timeout = (u_long) arg;
  188419. + if (!wait_event_interruptible_timeout
  188420. + (vpu_queue, irq_status != 0,
  188421. + msecs_to_jiffies(timeout))) {
  188422. + dev_warn(vpu_dev, "VPU blocking: timeout.\n");
  188423. + ret = -ETIME;
  188424. + } else if (signal_pending(current)) {
  188425. + dev_warn(vpu_dev, "VPU interrupt received.\n");
  188426. + ret = -ERESTARTSYS;
  188427. + } else
  188428. + irq_status = 0;
  188429. + break;
  188430. + }
  188431. + case VPU_IOC_IRAM_SETTING:
  188432. + {
  188433. + ret = copy_to_user((void __user *)arg, &iram,
  188434. + sizeof(struct iram_setting));
  188435. + if (ret)
  188436. + ret = -EFAULT;
  188437. +
  188438. + break;
  188439. + }
  188440. + case VPU_IOC_CLKGATE_SETTING:
  188441. + {
  188442. + u32 clkgate_en;
  188443. +
  188444. + if (get_user(clkgate_en, (u32 __user *) arg))
  188445. + return -EFAULT;
  188446. +
  188447. + if (clkgate_en) {
  188448. + clk_prepare(vpu_clk);
  188449. + clk_enable(vpu_clk);
  188450. + atomic_inc(&clk_cnt_from_ioc);
  188451. + } else {
  188452. + clk_disable(vpu_clk);
  188453. + clk_unprepare(vpu_clk);
  188454. + atomic_dec(&clk_cnt_from_ioc);
  188455. + }
  188456. +
  188457. + break;
  188458. + }
  188459. + case VPU_IOC_GET_SHARE_MEM:
  188460. + {
  188461. + mutex_lock(&vpu_data.lock);
  188462. + if (share_mem.cpu_addr != 0) {
  188463. + ret = copy_to_user((void __user *)arg,
  188464. + &share_mem,
  188465. + sizeof(struct vpu_mem_desc));
  188466. + mutex_unlock(&vpu_data.lock);
  188467. + break;
  188468. + } else {
  188469. + if (copy_from_user(&share_mem,
  188470. + (struct vpu_mem_desc *)arg,
  188471. + sizeof(struct vpu_mem_desc))) {
  188472. + mutex_unlock(&vpu_data.lock);
  188473. + return -EFAULT;
  188474. + }
  188475. + if (vpu_alloc_dma_buffer(&share_mem) == -1)
  188476. + ret = -EFAULT;
  188477. + else {
  188478. + if (copy_to_user((void __user *)arg,
  188479. + &share_mem,
  188480. + sizeof(struct
  188481. + vpu_mem_desc)))
  188482. + ret = -EFAULT;
  188483. + }
  188484. + }
  188485. + mutex_unlock(&vpu_data.lock);
  188486. + break;
  188487. + }
  188488. + case VPU_IOC_REQ_VSHARE_MEM:
  188489. + {
  188490. + mutex_lock(&vpu_data.lock);
  188491. + if (vshare_mem.cpu_addr != 0) {
  188492. + ret = copy_to_user((void __user *)arg,
  188493. + &vshare_mem,
  188494. + sizeof(struct vpu_mem_desc));
  188495. + mutex_unlock(&vpu_data.lock);
  188496. + break;
  188497. + } else {
  188498. + if (copy_from_user(&vshare_mem,
  188499. + (struct vpu_mem_desc *)arg,
  188500. + sizeof(struct
  188501. + vpu_mem_desc))) {
  188502. + mutex_unlock(&vpu_data.lock);
  188503. + return -EFAULT;
  188504. + }
  188505. + /* vmalloc shared memory if not allocated */
  188506. + if (!vshare_mem.cpu_addr)
  188507. + vshare_mem.cpu_addr =
  188508. + (unsigned long)
  188509. + vmalloc_user(vshare_mem.size);
  188510. + if (copy_to_user
  188511. + ((void __user *)arg, &vshare_mem,
  188512. + sizeof(struct vpu_mem_desc)))
  188513. + ret = -EFAULT;
  188514. + }
  188515. + mutex_unlock(&vpu_data.lock);
  188516. + break;
  188517. + }
  188518. + case VPU_IOC_GET_WORK_ADDR:
  188519. + {
  188520. + if (bitwork_mem.cpu_addr != 0) {
  188521. + ret =
  188522. + copy_to_user((void __user *)arg,
  188523. + &bitwork_mem,
  188524. + sizeof(struct vpu_mem_desc));
  188525. + break;
  188526. + } else {
  188527. + if (copy_from_user(&bitwork_mem,
  188528. + (struct vpu_mem_desc *)arg,
  188529. + sizeof(struct vpu_mem_desc)))
  188530. + return -EFAULT;
  188531. +
  188532. + if (vpu_alloc_dma_buffer(&bitwork_mem) == -1)
  188533. + ret = -EFAULT;
  188534. + else if (copy_to_user((void __user *)arg,
  188535. + &bitwork_mem,
  188536. + sizeof(struct
  188537. + vpu_mem_desc)))
  188538. + ret = -EFAULT;
  188539. + }
  188540. + break;
  188541. + }
  188542. + /*
  188543. + * The following two ioctl is used when user allocates working buffer
  188544. + * and register it to vpu driver.
  188545. + */
  188546. + case VPU_IOC_QUERY_BITWORK_MEM:
  188547. + {
  188548. + if (copy_to_user((void __user *)arg,
  188549. + &bitwork_mem,
  188550. + sizeof(struct vpu_mem_desc)))
  188551. + ret = -EFAULT;
  188552. + break;
  188553. + }
  188554. + case VPU_IOC_SET_BITWORK_MEM:
  188555. + {
  188556. + if (copy_from_user(&bitwork_mem,
  188557. + (struct vpu_mem_desc *)arg,
  188558. + sizeof(struct vpu_mem_desc)))
  188559. + ret = -EFAULT;
  188560. + break;
  188561. + }
  188562. + case VPU_IOC_SYS_SW_RESET:
  188563. + {
  188564. + vpu_reset();
  188565. + break;
  188566. + }
  188567. + case VPU_IOC_REG_DUMP:
  188568. + break;
  188569. + case VPU_IOC_PHYMEM_DUMP:
  188570. + break;
  188571. + case VPU_IOC_PHYMEM_CHECK:
  188572. + {
  188573. + struct vpu_mem_desc check_memory;
  188574. + ret = copy_from_user(&check_memory,
  188575. + (void __user *)arg,
  188576. + sizeof(struct vpu_mem_desc));
  188577. + if (ret != 0) {
  188578. + dev_err(vpu_dev, "copy from user failure:%d\n", ret);
  188579. + ret = -EFAULT;
  188580. + break;
  188581. + }
  188582. + ret = vpu_is_valid_phy_memory((u32)check_memory.phy_addr);
  188583. +
  188584. + dev_dbg(vpu_dev, "vpu: memory phy:0x%x %s phy memory\n",
  188585. + check_memory.phy_addr, (ret ? "is" : "isn't"));
  188586. + /* borrow .size to pass back the result. */
  188587. + check_memory.size = ret;
  188588. + ret = copy_to_user((void __user *)arg, &check_memory,
  188589. + sizeof(struct vpu_mem_desc));
  188590. + if (ret) {
  188591. + ret = -EFAULT;
  188592. + break;
  188593. + }
  188594. + break;
  188595. + }
  188596. + case VPU_IOC_LOCK_DEV:
  188597. + {
  188598. + u32 lock_en;
  188599. +
  188600. + if (get_user(lock_en, (u32 __user *) arg))
  188601. + return -EFAULT;
  188602. +
  188603. + if (lock_en)
  188604. + mutex_lock(&vpu_data.lock);
  188605. + else
  188606. + mutex_unlock(&vpu_data.lock);
  188607. +
  188608. + break;
  188609. + }
  188610. + default:
  188611. + {
  188612. + dev_err(vpu_dev, "No such IOCTL, cmd is %d\n", cmd);
  188613. + ret = -EINVAL;
  188614. + break;
  188615. + }
  188616. + }
  188617. + return ret;
  188618. +}
  188619. +
  188620. +/*!
  188621. + * @brief Release function for vpu file operation
  188622. + * @return 0 on success or negative error code on error
  188623. + */
  188624. +static int vpu_release(struct inode *inode, struct file *filp)
  188625. +{
  188626. + int i;
  188627. + unsigned long timeout;
  188628. +
  188629. + mutex_lock(&vpu_data.lock);
  188630. +
  188631. + if (open_count > 0 && !(--open_count)) {
  188632. +
  188633. + /* Wait for vpu go to idle state */
  188634. + clk_prepare(vpu_clk);
  188635. + clk_enable(vpu_clk);
  188636. + if (READ_REG(BIT_CUR_PC)) {
  188637. +
  188638. + timeout = jiffies + HZ;
  188639. + while (READ_REG(BIT_BUSY_FLAG)) {
  188640. + msleep(1);
  188641. + if (time_after(jiffies, timeout)) {
  188642. + dev_warn(vpu_dev, "VPU timeout during release\n");
  188643. + break;
  188644. + }
  188645. + }
  188646. + clk_disable(vpu_clk);
  188647. + clk_unprepare(vpu_clk);
  188648. +
  188649. + /* Clean up interrupt */
  188650. + cancel_work_sync(&vpu_data.work);
  188651. + flush_workqueue(vpu_data.workqueue);
  188652. + irq_status = 0;
  188653. +
  188654. + clk_prepare(vpu_clk);
  188655. + clk_enable(vpu_clk);
  188656. + if (READ_REG(BIT_BUSY_FLAG)) {
  188657. +
  188658. + if (cpu_is_mx51() || cpu_is_mx53()) {
  188659. + dev_err(vpu_dev,
  188660. + "fatal error: can't gate/power off when VPU is busy\n");
  188661. + clk_disable(vpu_clk);
  188662. + clk_unprepare(vpu_clk);
  188663. + mutex_unlock(&vpu_data.lock);
  188664. + return -EFAULT;
  188665. + }
  188666. +
  188667. +#ifdef CONFIG_SOC_IMX6Q
  188668. + if (cpu_is_mx6dl() || cpu_is_mx6q()) {
  188669. + WRITE_REG(0x11, 0x10F0);
  188670. + timeout = jiffies + HZ;
  188671. + while (READ_REG(0x10F4) != 0x77) {
  188672. + msleep(1);
  188673. + if (time_after(jiffies, timeout))
  188674. + break;
  188675. + }
  188676. +
  188677. + if (READ_REG(0x10F4) != 0x77) {
  188678. + dev_err(vpu_dev,
  188679. + "fatal error: can't gate/power off when VPU is busy\n");
  188680. + WRITE_REG(0x0, 0x10F0);
  188681. + clk_disable(vpu_clk);
  188682. + clk_unprepare(vpu_clk);
  188683. + mutex_unlock(&vpu_data.lock);
  188684. + return -EFAULT;
  188685. + } else
  188686. + vpu_reset();
  188687. + }
  188688. +#endif
  188689. + }
  188690. + }
  188691. + clk_disable(vpu_clk);
  188692. + clk_unprepare(vpu_clk);
  188693. +
  188694. + vpu_free_buffers();
  188695. +
  188696. + /* Free shared memory when vpu device is idle */
  188697. + vpu_free_dma_buffer(&share_mem);
  188698. + share_mem.cpu_addr = 0;
  188699. + vfree((void *)vshare_mem.cpu_addr);
  188700. + vshare_mem.cpu_addr = 0;
  188701. +
  188702. + vpu_clk_usercount = atomic_read(&clk_cnt_from_ioc);
  188703. + for (i = 0; i < vpu_clk_usercount; i++) {
  188704. + clk_disable(vpu_clk);
  188705. + clk_unprepare(vpu_clk);
  188706. + atomic_dec(&clk_cnt_from_ioc);
  188707. + }
  188708. +
  188709. + vpu_power_up(false);
  188710. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188711. + pm_runtime_put_sync_suspend(vpu_dev);
  188712. +#endif
  188713. +
  188714. + }
  188715. + mutex_unlock(&vpu_data.lock);
  188716. +
  188717. + return 0;
  188718. +}
  188719. +
  188720. +/*!
  188721. + * @brief fasync function for vpu file operation
  188722. + * @return 0 on success or negative error code on error
  188723. + */
  188724. +static int vpu_fasync(int fd, struct file *filp, int mode)
  188725. +{
  188726. + struct vpu_priv *dev = (struct vpu_priv *)filp->private_data;
  188727. + return fasync_helper(fd, filp, mode, &dev->async_queue);
  188728. +}
  188729. +
  188730. +/*!
  188731. + * @brief memory map function of harware registers for vpu file operation
  188732. + * @return 0 on success or negative error code on error
  188733. + */
  188734. +static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm)
  188735. +{
  188736. + unsigned long pfn;
  188737. +
  188738. + vm->vm_flags |= VM_IO | VM_RESERVED;
  188739. + /*
  188740. + * Since vpu registers have been mapped with ioremap() at probe
  188741. + * which L_PTE_XN is 1, and the same physical address must be
  188742. + * mapped multiple times with same type, so set L_PTE_XN to 1 here.
  188743. + * Otherwise, there may be unexpected result in video codec.
  188744. + */
  188745. + vm->vm_page_prot = pgprot_noncachedxn(vm->vm_page_prot);
  188746. + pfn = phy_vpu_base_addr >> PAGE_SHIFT;
  188747. + dev_dbg(vpu_dev, "size=0x%x, page no.=0x%x\n",
  188748. + (int)(vm->vm_end - vm->vm_start), (int)pfn);
  188749. + return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end - vm->vm_start,
  188750. + vm->vm_page_prot) ? -EAGAIN : 0;
  188751. +}
  188752. +
  188753. +/*!
  188754. + * @brief memory map function of memory for vpu file operation
  188755. + * @return 0 on success or negative error code on error
  188756. + */
  188757. +static int vpu_map_dma_mem(struct file *fp, struct vm_area_struct *vm)
  188758. +{
  188759. + int request_size;
  188760. + request_size = vm->vm_end - vm->vm_start;
  188761. +
  188762. + dev_dbg(vpu_dev, "start=0x%x, pgoff=0x%x, size=0x%x\n",
  188763. + (unsigned int)(vm->vm_start), (unsigned int)(vm->vm_pgoff),
  188764. + request_size);
  188765. +
  188766. + vm->vm_flags |= VM_IO | VM_RESERVED;
  188767. + vm->vm_page_prot = pgprot_writecombine(vm->vm_page_prot);
  188768. +
  188769. + return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff,
  188770. + request_size, vm->vm_page_prot) ? -EAGAIN : 0;
  188771. +
  188772. +}
  188773. +
  188774. +/* !
  188775. + * @brief memory map function of vmalloced share memory
  188776. + * @return 0 on success or negative error code on error
  188777. + */
  188778. +static int vpu_map_vshare_mem(struct file *fp, struct vm_area_struct *vm)
  188779. +{
  188780. + int ret = -EINVAL;
  188781. +
  188782. + ret = remap_vmalloc_range(vm, (void *)(vm->vm_pgoff << PAGE_SHIFT), 0);
  188783. + vm->vm_flags |= VM_IO;
  188784. +
  188785. + return ret;
  188786. +}
  188787. +/*!
  188788. + * @brief memory map interface for vpu file operation
  188789. + * @return 0 on success or negative error code on error
  188790. + */
  188791. +static int vpu_mmap(struct file *fp, struct vm_area_struct *vm)
  188792. +{
  188793. + unsigned long offset;
  188794. +
  188795. + offset = vshare_mem.cpu_addr >> PAGE_SHIFT;
  188796. +
  188797. + if (vm->vm_pgoff && (vm->vm_pgoff == offset))
  188798. + return vpu_map_vshare_mem(fp, vm);
  188799. + else if (vm->vm_pgoff)
  188800. + return vpu_map_dma_mem(fp, vm);
  188801. + else
  188802. + return vpu_map_hwregs(fp, vm);
  188803. +}
  188804. +
  188805. +const struct file_operations vpu_fops = {
  188806. + .owner = THIS_MODULE,
  188807. + .open = vpu_open,
  188808. + .unlocked_ioctl = vpu_ioctl,
  188809. + .release = vpu_release,
  188810. + .fasync = vpu_fasync,
  188811. + .mmap = vpu_mmap,
  188812. +};
  188813. +
  188814. +/*!
  188815. + * This function is called by the driver framework to initialize the vpu device.
  188816. + * @param dev The device structure for the vpu passed in by the framework.
  188817. + * @return 0 on success or negative error code on error
  188818. + */
  188819. +static int vpu_dev_probe(struct platform_device *pdev)
  188820. +{
  188821. + int err = 0;
  188822. + struct device *temp_class;
  188823. + struct resource *res;
  188824. + unsigned long addr = 0;
  188825. +
  188826. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188827. + struct device_node *np = pdev->dev.of_node;
  188828. + u32 iramsize;
  188829. +
  188830. + err = of_property_read_u32(np, "iramsize", (u32 *)&iramsize);
  188831. + if (!err && iramsize)
  188832. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188833. + {
  188834. + iram_pool = of_get_named_gen_pool(np, "iram", 0);
  188835. + if (!iram_pool) {
  188836. + dev_err(&pdev->dev, "iram pool not available\n");
  188837. + return -ENOMEM;
  188838. + }
  188839. +
  188840. + iram_base = gen_pool_alloc(iram_pool, iramsize);
  188841. + if (!iram_base) {
  188842. + dev_err(&pdev->dev, "unable to alloc iram\n");
  188843. + return -ENOMEM;
  188844. + }
  188845. +
  188846. + addr = gen_pool_virt_to_phys(iram_pool, iram_base);
  188847. + }
  188848. +#else
  188849. + iram_alloc(iramsize, &addr);
  188850. +#endif
  188851. + if (addr == 0)
  188852. + iram.start = iram.end = 0;
  188853. + else {
  188854. + iram.start = addr;
  188855. + iram.end = addr + iramsize - 1;
  188856. + }
  188857. +#else
  188858. +
  188859. + vpu_plat = pdev->dev.platform_data;
  188860. +
  188861. + if (vpu_plat && vpu_plat->iram_enable && vpu_plat->iram_size)
  188862. + iram_alloc(vpu_plat->iram_size, &addr);
  188863. + if (addr == 0)
  188864. + iram.start = iram.end = 0;
  188865. + else {
  188866. + iram.start = addr;
  188867. + iram.end = addr + vpu_plat->iram_size - 1;
  188868. + }
  188869. +#endif
  188870. +
  188871. + vpu_dev = &pdev->dev;
  188872. +
  188873. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu_regs");
  188874. + if (!res) {
  188875. + dev_err(vpu_dev, "vpu: unable to get vpu base addr\n");
  188876. + return -ENODEV;
  188877. + }
  188878. + phy_vpu_base_addr = res->start;
  188879. + vpu_base = ioremap(res->start, res->end - res->start);
  188880. +
  188881. + vpu_major = register_chrdev(vpu_major, "mxc_vpu", &vpu_fops);
  188882. + if (vpu_major < 0) {
  188883. + dev_err(vpu_dev, "vpu: unable to get a major for VPU\n");
  188884. + err = -EBUSY;
  188885. + goto error;
  188886. + }
  188887. +
  188888. + vpu_class = class_create(THIS_MODULE, "mxc_vpu");
  188889. + if (IS_ERR(vpu_class)) {
  188890. + err = PTR_ERR(vpu_class);
  188891. + goto err_out_chrdev;
  188892. + }
  188893. +
  188894. + temp_class = device_create(vpu_class, NULL, MKDEV(vpu_major, 0),
  188895. + NULL, "mxc_vpu");
  188896. + if (IS_ERR(temp_class)) {
  188897. + err = PTR_ERR(temp_class);
  188898. + goto err_out_class;
  188899. + }
  188900. +
  188901. + vpu_clk = clk_get(&pdev->dev, "vpu_clk");
  188902. + if (IS_ERR(vpu_clk)) {
  188903. + err = -ENOENT;
  188904. + goto err_out_class;
  188905. + }
  188906. +
  188907. + vpu_ipi_irq = platform_get_irq_byname(pdev, "vpu_ipi_irq");
  188908. + if (vpu_ipi_irq < 0) {
  188909. + dev_err(vpu_dev, "vpu: unable to get vpu interrupt\n");
  188910. + err = -ENXIO;
  188911. + goto err_out_class;
  188912. + }
  188913. + err = request_irq(vpu_ipi_irq, vpu_ipi_irq_handler, 0, "VPU_CODEC_IRQ",
  188914. + (void *)(&vpu_data));
  188915. + if (err)
  188916. + goto err_out_class;
  188917. + if (vpu_power_get(true)) {
  188918. + if (!(cpu_is_mx51() || cpu_is_mx53())) {
  188919. + dev_err(vpu_dev, "failed to get vpu power\n");
  188920. + goto err_out_class;
  188921. + } else {
  188922. + /* regulator_get will return error on MX5x,
  188923. + * just igore it everywhere*/
  188924. + dev_warn(vpu_dev, "failed to get vpu power\n");
  188925. + }
  188926. + }
  188927. +
  188928. +#ifdef MXC_VPU_HAS_JPU
  188929. + vpu_jpu_irq = platform_get_irq_byname(pdev, "vpu_jpu_irq");
  188930. + if (vpu_jpu_irq < 0) {
  188931. + dev_err(vpu_dev, "vpu: unable to get vpu jpu interrupt\n");
  188932. + err = -ENXIO;
  188933. + free_irq(vpu_ipi_irq, &vpu_data);
  188934. + goto err_out_class;
  188935. + }
  188936. + err = request_irq(vpu_jpu_irq, vpu_jpu_irq_handler, IRQF_TRIGGER_RISING,
  188937. + "VPU_JPG_IRQ", (void *)(&vpu_data));
  188938. + if (err) {
  188939. + free_irq(vpu_ipi_irq, &vpu_data);
  188940. + goto err_out_class;
  188941. + }
  188942. +#endif
  188943. +
  188944. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188945. + pm_runtime_enable(&pdev->dev);
  188946. +#endif
  188947. +
  188948. + vpu_data.workqueue = create_workqueue("vpu_wq");
  188949. + INIT_WORK(&vpu_data.work, vpu_worker_callback);
  188950. + mutex_init(&vpu_data.lock);
  188951. + dev_info(vpu_dev, "VPU initialized\n");
  188952. + goto out;
  188953. +
  188954. +err_out_class:
  188955. + device_destroy(vpu_class, MKDEV(vpu_major, 0));
  188956. + class_destroy(vpu_class);
  188957. +err_out_chrdev:
  188958. + unregister_chrdev(vpu_major, "mxc_vpu");
  188959. +error:
  188960. + iounmap(vpu_base);
  188961. +out:
  188962. + return err;
  188963. +}
  188964. +
  188965. +static int vpu_dev_remove(struct platform_device *pdev)
  188966. +{
  188967. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188968. + pm_runtime_disable(&pdev->dev);
  188969. +#endif
  188970. + free_irq(vpu_ipi_irq, &vpu_data);
  188971. +#ifdef MXC_VPU_HAS_JPU
  188972. + free_irq(vpu_jpu_irq, &vpu_data);
  188973. +#endif
  188974. + cancel_work_sync(&vpu_data.work);
  188975. + flush_workqueue(vpu_data.workqueue);
  188976. + destroy_workqueue(vpu_data.workqueue);
  188977. +
  188978. + iounmap(vpu_base);
  188979. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188980. + if (iram.start)
  188981. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  188982. + gen_pool_free(iram_pool, iram_base, iram.end-iram.start+1);
  188983. +#else
  188984. + iram_free(iram.start, iram.end-iram.start+1);
  188985. +#endif
  188986. +#else
  188987. + if (vpu_plat && vpu_plat->iram_enable && vpu_plat->iram_size)
  188988. + iram_free(iram.start, vpu_plat->iram_size);
  188989. +#endif
  188990. +
  188991. + vpu_power_get(false);
  188992. + return 0;
  188993. +}
  188994. +
  188995. +#ifdef CONFIG_PM
  188996. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  188997. +static int vpu_suspend(struct device *dev)
  188998. +#else
  188999. +static int vpu_suspend(struct platform_device *pdev, pm_message_t state)
  189000. +#endif
  189001. +{
  189002. + int i;
  189003. + unsigned long timeout;
  189004. +
  189005. + mutex_lock(&vpu_data.lock);
  189006. + if (open_count == 0) {
  189007. + /* VPU is released (all instances are freed),
  189008. + * clock is already off, context is no longer needed,
  189009. + * power is already off on MX6,
  189010. + * gate power on MX51 */
  189011. + if (cpu_is_mx51()) {
  189012. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189013. + if (vpu_plat->pg)
  189014. + vpu_plat->pg(1);
  189015. +#endif
  189016. + }
  189017. + } else {
  189018. + /* Wait for vpu go to idle state, suspect vpu cannot be changed
  189019. + to idle state after about 1 sec */
  189020. + timeout = jiffies + HZ;
  189021. + clk_prepare(vpu_clk);
  189022. + clk_enable(vpu_clk);
  189023. + while (READ_REG(BIT_BUSY_FLAG)) {
  189024. + msleep(1);
  189025. + if (time_after(jiffies, timeout)) {
  189026. + clk_disable(vpu_clk);
  189027. + clk_unprepare(vpu_clk);
  189028. + mutex_unlock(&vpu_data.lock);
  189029. + return -EAGAIN;
  189030. + }
  189031. + }
  189032. + clk_disable(vpu_clk);
  189033. + clk_unprepare(vpu_clk);
  189034. +
  189035. + /* Make sure clock is disabled before suspend */
  189036. + vpu_clk_usercount = atomic_read(&clk_cnt_from_ioc);
  189037. + for (i = 0; i < vpu_clk_usercount; i++) {
  189038. + clk_disable(vpu_clk);
  189039. + clk_unprepare(vpu_clk);
  189040. + }
  189041. +
  189042. + if (cpu_is_mx53()) {
  189043. + mutex_unlock(&vpu_data.lock);
  189044. + return 0;
  189045. + }
  189046. +
  189047. + if (bitwork_mem.cpu_addr != 0) {
  189048. + clk_prepare(vpu_clk);
  189049. + clk_enable(vpu_clk);
  189050. + /* Save 64 registers from BIT_CODE_BUF_ADDR */
  189051. + for (i = 0; i < 64; i++)
  189052. + regBk[i] = READ_REG(BIT_CODE_BUF_ADDR + (i * 4));
  189053. + pc_before_suspend = READ_REG(BIT_CUR_PC);
  189054. + clk_disable(vpu_clk);
  189055. + clk_unprepare(vpu_clk);
  189056. + }
  189057. +
  189058. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189059. + if (vpu_plat->pg)
  189060. + vpu_plat->pg(1);
  189061. +#endif
  189062. +
  189063. + /* If VPU is working before suspend, disable
  189064. + * regulator to make usecount right. */
  189065. + vpu_power_up(false);
  189066. + }
  189067. +
  189068. + mutex_unlock(&vpu_data.lock);
  189069. + return 0;
  189070. +}
  189071. +
  189072. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  189073. +static int vpu_resume(struct device *dev)
  189074. +#else
  189075. +static int vpu_resume(struct platform_device *pdev)
  189076. +#endif
  189077. +{
  189078. + int i;
  189079. +
  189080. + mutex_lock(&vpu_data.lock);
  189081. + if (open_count == 0) {
  189082. + /* VPU is released (all instances are freed),
  189083. + * clock should be kept off, context is no longer needed,
  189084. + * power should be kept off on MX6,
  189085. + * disable power gating on MX51 */
  189086. + if (cpu_is_mx51()) {
  189087. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189088. + if (vpu_plat->pg)
  189089. + vpu_plat->pg(0);
  189090. +#endif
  189091. + }
  189092. + } else {
  189093. + if (cpu_is_mx53())
  189094. + goto recover_clk;
  189095. +
  189096. + /* If VPU is working before suspend, enable
  189097. + * regulator to make usecount right. */
  189098. + vpu_power_up(true);
  189099. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189100. + if (vpu_plat->pg)
  189101. + vpu_plat->pg(0);
  189102. +#endif
  189103. +
  189104. + if (bitwork_mem.cpu_addr != 0) {
  189105. + u32 *p = (u32 *) bitwork_mem.cpu_addr;
  189106. + u32 data, pc;
  189107. + u16 data_hi;
  189108. + u16 data_lo;
  189109. +
  189110. + clk_prepare(vpu_clk);
  189111. + clk_enable(vpu_clk);
  189112. +
  189113. + pc = READ_REG(BIT_CUR_PC);
  189114. + if (pc) {
  189115. + dev_warn(vpu_dev, "Not power off after suspend (PC=0x%x)\n", pc);
  189116. + clk_disable(vpu_clk);
  189117. + clk_unprepare(vpu_clk);
  189118. + goto recover_clk;
  189119. + }
  189120. +
  189121. + /* Restore registers */
  189122. + for (i = 0; i < 64; i++)
  189123. + WRITE_REG(regBk[i], BIT_CODE_BUF_ADDR + (i * 4));
  189124. +
  189125. + WRITE_REG(0x0, BIT_RESET_CTRL);
  189126. + WRITE_REG(0x0, BIT_CODE_RUN);
  189127. + /* MX6 RTL has a bug not to init MBC_SET_SUBBLK_EN on reset */
  189128. +#ifdef CONFIG_SOC_IMX6Q
  189129. + WRITE_REG(0x0, MBC_SET_SUBBLK_EN);
  189130. +#endif
  189131. +
  189132. + /*
  189133. + * Re-load boot code, from the codebuffer in external RAM.
  189134. + * Thankfully, we only need 4096 bytes, same for all platforms.
  189135. + */
  189136. + for (i = 0; i < 2048; i += 4) {
  189137. + data = p[(i / 2) + 1];
  189138. + data_hi = (data >> 16) & 0xFFFF;
  189139. + data_lo = data & 0xFFFF;
  189140. + WRITE_REG((i << 16) | data_hi, BIT_CODE_DOWN);
  189141. + WRITE_REG(((i + 1) << 16) | data_lo,
  189142. + BIT_CODE_DOWN);
  189143. +
  189144. + data = p[i / 2];
  189145. + data_hi = (data >> 16) & 0xFFFF;
  189146. + data_lo = data & 0xFFFF;
  189147. + WRITE_REG(((i + 2) << 16) | data_hi,
  189148. + BIT_CODE_DOWN);
  189149. + WRITE_REG(((i + 3) << 16) | data_lo,
  189150. + BIT_CODE_DOWN);
  189151. + }
  189152. +
  189153. + if (pc_before_suspend) {
  189154. + WRITE_REG(0x1, BIT_BUSY_FLAG);
  189155. + WRITE_REG(0x1, BIT_CODE_RUN);
  189156. + while (READ_REG(BIT_BUSY_FLAG))
  189157. + ;
  189158. + } else {
  189159. + dev_warn(vpu_dev, "PC=0 before suspend\n");
  189160. + }
  189161. + clk_disable(vpu_clk);
  189162. + clk_unprepare(vpu_clk);
  189163. + }
  189164. +
  189165. +recover_clk:
  189166. + /* Recover vpu clock */
  189167. + for (i = 0; i < vpu_clk_usercount; i++) {
  189168. + clk_prepare(vpu_clk);
  189169. + clk_enable(vpu_clk);
  189170. + }
  189171. + }
  189172. +
  189173. + mutex_unlock(&vpu_data.lock);
  189174. + return 0;
  189175. +}
  189176. +
  189177. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  189178. +static int vpu_runtime_suspend(struct device *dev)
  189179. +{
  189180. + release_bus_freq(BUS_FREQ_HIGH);
  189181. + return 0;
  189182. +}
  189183. +
  189184. +static int vpu_runtime_resume(struct device *dev)
  189185. +{
  189186. + request_bus_freq(BUS_FREQ_HIGH);
  189187. + return 0;
  189188. +}
  189189. +
  189190. +static const struct dev_pm_ops vpu_pm_ops = {
  189191. + SET_RUNTIME_PM_OPS(vpu_runtime_suspend, vpu_runtime_resume, NULL)
  189192. + SET_SYSTEM_SLEEP_PM_OPS(vpu_suspend, vpu_resume)
  189193. +};
  189194. +#endif
  189195. +
  189196. +#else
  189197. +#define vpu_suspend NULL
  189198. +#define vpu_resume NULL
  189199. +#endif /* !CONFIG_PM */
  189200. +
  189201. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  189202. +static const struct of_device_id vpu_of_match[] = {
  189203. + { .compatible = "fsl,imx6-vpu", },
  189204. + {/* sentinel */}
  189205. +};
  189206. +MODULE_DEVICE_TABLE(of, vpu_of_match);
  189207. +#endif
  189208. +
  189209. +/*! Driver definition
  189210. + *
  189211. + */
  189212. +static struct platform_driver mxcvpu_driver = {
  189213. + .driver = {
  189214. + .name = "mxc_vpu",
  189215. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  189216. + .of_match_table = vpu_of_match,
  189217. +#ifdef CONFIG_PM
  189218. + .pm = &vpu_pm_ops,
  189219. +#endif
  189220. +#endif
  189221. + },
  189222. + .probe = vpu_dev_probe,
  189223. + .remove = vpu_dev_remove,
  189224. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189225. + .suspend = vpu_suspend,
  189226. + .resume = vpu_resume,
  189227. +#endif
  189228. +};
  189229. +
  189230. +static int __init vpu_init(void)
  189231. +{
  189232. + int ret = platform_driver_register(&mxcvpu_driver);
  189233. +
  189234. + init_waitqueue_head(&vpu_queue);
  189235. +
  189236. +
  189237. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  189238. + memblock_analyze();
  189239. + top_address_DRAM = memblock_end_of_DRAM_with_reserved();
  189240. +#endif
  189241. +
  189242. + return ret;
  189243. +}
  189244. +
  189245. +static void __exit vpu_exit(void)
  189246. +{
  189247. + if (vpu_major > 0) {
  189248. + device_destroy(vpu_class, MKDEV(vpu_major, 0));
  189249. + class_destroy(vpu_class);
  189250. + unregister_chrdev(vpu_major, "mxc_vpu");
  189251. + vpu_major = 0;
  189252. + }
  189253. +
  189254. + vpu_free_dma_buffer(&bitwork_mem);
  189255. + vpu_free_dma_buffer(&pic_para_mem);
  189256. + vpu_free_dma_buffer(&user_data_mem);
  189257. +
  189258. + /* reset VPU state */
  189259. + vpu_power_up(true);
  189260. + clk_prepare(vpu_clk);
  189261. + clk_enable(vpu_clk);
  189262. + vpu_reset();
  189263. + clk_disable(vpu_clk);
  189264. + clk_unprepare(vpu_clk);
  189265. + vpu_power_up(false);
  189266. +
  189267. + clk_put(vpu_clk);
  189268. +
  189269. + platform_driver_unregister(&mxcvpu_driver);
  189270. + return;
  189271. +}
  189272. +
  189273. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  189274. +MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX/MXC");
  189275. +MODULE_LICENSE("GPL");
  189276. +
  189277. +module_init(vpu_init);
  189278. +module_exit(vpu_exit);
  189279. diff -Nur linux-3.14.14/drivers/net/bonding/bonding.h linux-imx6-3.14/drivers/net/bonding/bonding.h
  189280. --- linux-3.14.14/drivers/net/bonding/bonding.h 2014-07-28 10:07:25.000000000 -0500
  189281. +++ linux-imx6-3.14/drivers/net/bonding/bonding.h 2014-12-08 00:31:53.484418001 -0600
  189282. @@ -188,7 +188,8 @@
  189283. struct net_device *dev; /* first - useful for panic debug */
  189284. struct bonding *bond; /* our master */
  189285. int delay;
  189286. - unsigned long jiffies;
  189287. + /* all three in jiffies */
  189288. + unsigned long last_link_up;
  189289. unsigned long last_arp_rx;
  189290. unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS];
  189291. s8 link; /* one of BOND_LINK_XXXX */
  189292. diff -Nur linux-3.14.14/drivers/net/bonding/bond_main.c linux-imx6-3.14/drivers/net/bonding/bond_main.c
  189293. --- linux-3.14.14/drivers/net/bonding/bond_main.c 2014-07-28 10:07:25.000000000 -0500
  189294. +++ linux-imx6-3.14/drivers/net/bonding/bond_main.c 2014-12-08 00:31:53.480418001 -0600
  189295. @@ -798,7 +798,7 @@
  189296. return;
  189297. if (new_active) {
  189298. - new_active->jiffies = jiffies;
  189299. + new_active->last_link_up = jiffies;
  189300. if (new_active->link == BOND_LINK_BACK) {
  189301. if (USES_PRIMARY(bond->params.mode)) {
  189302. @@ -1457,7 +1457,7 @@
  189303. }
  189304. if (new_slave->link != BOND_LINK_DOWN)
  189305. - new_slave->jiffies = jiffies;
  189306. + new_slave->last_link_up = jiffies;
  189307. pr_debug("Initial state of slave_dev is BOND_LINK_%s\n",
  189308. new_slave->link == BOND_LINK_DOWN ? "DOWN" :
  189309. (new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
  189310. @@ -1908,7 +1908,7 @@
  189311. * recovered before downdelay expired
  189312. */
  189313. slave->link = BOND_LINK_UP;
  189314. - slave->jiffies = jiffies;
  189315. + slave->last_link_up = jiffies;
  189316. pr_info("%s: link status up again after %d ms for interface %s.\n",
  189317. bond->dev->name,
  189318. (bond->params.downdelay - slave->delay) *
  189319. @@ -1983,7 +1983,7 @@
  189320. case BOND_LINK_UP:
  189321. slave->link = BOND_LINK_UP;
  189322. - slave->jiffies = jiffies;
  189323. + slave->last_link_up = jiffies;
  189324. if (bond->params.mode == BOND_MODE_8023AD) {
  189325. /* prevent it from being the active one */
  189326. @@ -2268,6 +2268,7 @@
  189327. struct slave *slave)
  189328. {
  189329. struct arphdr *arp = (struct arphdr *)skb->data;
  189330. + struct slave *curr_active_slave;
  189331. unsigned char *arp_ptr;
  189332. __be32 sip, tip;
  189333. int alen;
  189334. @@ -2312,6 +2313,8 @@
  189335. bond->params.arp_validate, slave_do_arp_validate(bond, slave),
  189336. &sip, &tip);
  189337. + curr_active_slave = rcu_dereference(bond->curr_active_slave);
  189338. +
  189339. /*
  189340. * Backup slaves won't see the ARP reply, but do come through
  189341. * here for each ARP probe (so we swap the sip/tip to validate
  189342. @@ -2325,11 +2328,12 @@
  189343. * is done to avoid endless looping when we can't reach the
  189344. * arp_ip_target and fool ourselves with our own arp requests.
  189345. */
  189346. +
  189347. if (bond_is_active_slave(slave))
  189348. bond_validate_arp(bond, slave, sip, tip);
  189349. - else if (bond->curr_active_slave &&
  189350. - time_after(slave_last_rx(bond, bond->curr_active_slave),
  189351. - bond->curr_active_slave->jiffies))
  189352. + else if (curr_active_slave &&
  189353. + time_after(slave_last_rx(bond, curr_active_slave),
  189354. + curr_active_slave->last_link_up))
  189355. bond_validate_arp(bond, slave, tip, sip);
  189356. out_unlock:
  189357. @@ -2376,9 +2380,9 @@
  189358. oldcurrent = ACCESS_ONCE(bond->curr_active_slave);
  189359. /* see if any of the previous devices are up now (i.e. they have
  189360. * xmt and rcv traffic). the curr_active_slave does not come into
  189361. - * the picture unless it is null. also, slave->jiffies is not needed
  189362. - * here because we send an arp on each slave and give a slave as
  189363. - * long as it needs to get the tx/rx within the delta.
  189364. + * the picture unless it is null. also, slave->last_link_up is not
  189365. + * needed here because we send an arp on each slave and give a slave
  189366. + * as long as it needs to get the tx/rx within the delta.
  189367. * TODO: what about up/down delay in arp mode? it wasn't here before
  189368. * so it can wait
  189369. */
  189370. @@ -2505,7 +2509,7 @@
  189371. * active. This avoids bouncing, as the last receive
  189372. * times need a full ARP monitor cycle to be updated.
  189373. */
  189374. - if (bond_time_in_interval(bond, slave->jiffies, 2))
  189375. + if (bond_time_in_interval(bond, slave->last_link_up, 2))
  189376. continue;
  189377. /*
  189378. @@ -2698,7 +2702,7 @@
  189379. new_slave->link = BOND_LINK_BACK;
  189380. bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER);
  189381. bond_arp_send_all(bond, new_slave);
  189382. - new_slave->jiffies = jiffies;
  189383. + new_slave->last_link_up = jiffies;
  189384. rcu_assign_pointer(bond->current_arp_slave, new_slave);
  189385. check_state:
  189386. diff -Nur linux-3.14.14/drivers/net/can/flexcan.c linux-imx6-3.14/drivers/net/can/flexcan.c
  189387. --- linux-3.14.14/drivers/net/can/flexcan.c 2014-07-28 10:07:25.000000000 -0500
  189388. +++ linux-imx6-3.14/drivers/net/can/flexcan.c 2014-12-08 00:31:53.488418001 -0600
  189389. @@ -125,7 +125,8 @@
  189390. FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)
  189391. /* FLEXCAN interrupt flag register (IFLAG) bits */
  189392. -#define FLEXCAN_TX_BUF_ID 8
  189393. +#define FLEXCAN_RESERVED_BUF_ID 8
  189394. +#define FLEXCAN_TX_BUF_ID 13
  189395. #define FLEXCAN_IFLAG_BUF(x) BIT(x)
  189396. #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
  189397. #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
  189398. @@ -162,6 +163,7 @@
  189399. */
  189400. #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
  189401. #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */
  189402. +#define FLEXCAN_HAS_ERR005829 BIT(3) /* have errata ERR005829 */
  189403. /* Structure of the message buffer */
  189404. struct flexcan_mb {
  189405. @@ -221,7 +223,7 @@
  189406. };
  189407. static struct flexcan_devtype_data fsl_imx28_devtype_data;
  189408. static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
  189409. - .features = FLEXCAN_HAS_V10_FEATURES,
  189410. + .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_ERR005829,
  189411. };
  189412. static const struct can_bittiming_const flexcan_bittiming_const = {
  189413. @@ -428,6 +430,11 @@
  189414. flexcan_write(can_id, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
  189415. flexcan_write(ctrl, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
  189416. + if (priv->devtype_data->features & FLEXCAN_HAS_ERR005829) {
  189417. + writel(0x0, &regs->cantxfg[FLEXCAN_RESERVED_BUF_ID].can_ctrl);
  189418. + writel(0x0, &regs->cantxfg[FLEXCAN_RESERVED_BUF_ID].can_ctrl);
  189419. + }
  189420. +
  189421. return NETDEV_TX_OK;
  189422. }
  189423. diff -Nur linux-3.14.14/drivers/net/ethernet/adi/bfin_mac.c linux-imx6-3.14/drivers/net/ethernet/adi/bfin_mac.c
  189424. --- linux-3.14.14/drivers/net/ethernet/adi/bfin_mac.c 2014-07-28 10:07:25.000000000 -0500
  189425. +++ linux-imx6-3.14/drivers/net/ethernet/adi/bfin_mac.c 2014-12-08 00:31:53.500418001 -0600
  189426. @@ -1040,6 +1040,7 @@
  189427. .n_alarm = 0,
  189428. .n_ext_ts = 0,
  189429. .n_per_out = 0,
  189430. + .n_pins = 0,
  189431. .pps = 0,
  189432. .adjfreq = bfin_ptp_adjfreq,
  189433. .adjtime = bfin_ptp_adjtime,
  189434. diff -Nur linux-3.14.14/drivers/net/ethernet/broadcom/tg3.c linux-imx6-3.14/drivers/net/ethernet/broadcom/tg3.c
  189435. --- linux-3.14.14/drivers/net/ethernet/broadcom/tg3.c 2014-07-28 10:07:25.000000000 -0500
  189436. +++ linux-imx6-3.14/drivers/net/ethernet/broadcom/tg3.c 2014-12-08 00:31:53.540418001 -0600
  189437. @@ -6322,6 +6322,7 @@
  189438. .n_alarm = 0,
  189439. .n_ext_ts = 0,
  189440. .n_per_out = 1,
  189441. + .n_pins = 0,
  189442. .pps = 0,
  189443. .adjfreq = tg3_ptp_adjfreq,
  189444. .adjtime = tg3_ptp_adjtime,
  189445. diff -Nur linux-3.14.14/drivers/net/ethernet/cadence/macb.c linux-imx6-3.14/drivers/net/ethernet/cadence/macb.c
  189446. --- linux-3.14.14/drivers/net/ethernet/cadence/macb.c 2014-07-28 10:07:25.000000000 -0500
  189447. +++ linux-imx6-3.14/drivers/net/ethernet/cadence/macb.c 2014-12-08 00:31:53.548418001 -0600
  189448. @@ -605,25 +605,16 @@
  189449. {
  189450. unsigned int entry;
  189451. struct sk_buff *skb;
  189452. - struct macb_dma_desc *desc;
  189453. dma_addr_t paddr;
  189454. while (CIRC_SPACE(bp->rx_prepared_head, bp->rx_tail, RX_RING_SIZE) > 0) {
  189455. - u32 addr, ctrl;
  189456. -
  189457. entry = macb_rx_ring_wrap(bp->rx_prepared_head);
  189458. - desc = &bp->rx_ring[entry];
  189459. /* Make hw descriptor updates visible to CPU */
  189460. rmb();
  189461. - addr = desc->addr;
  189462. - ctrl = desc->ctrl;
  189463. bp->rx_prepared_head++;
  189464. - if ((addr & MACB_BIT(RX_USED)))
  189465. - continue;
  189466. -
  189467. if (bp->rx_skbuff[entry] == NULL) {
  189468. /* allocate sk_buff for this free entry in ring */
  189469. skb = netdev_alloc_skb(bp->dev, bp->rx_buffer_size);
  189470. @@ -704,7 +695,6 @@
  189471. if (!(addr & MACB_BIT(RX_USED)))
  189472. break;
  189473. - desc->addr &= ~MACB_BIT(RX_USED);
  189474. bp->rx_tail++;
  189475. count++;
  189476. diff -Nur linux-3.14.14/drivers/net/ethernet/chelsio/cxgb4vf/sge.c linux-imx6-3.14/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
  189477. --- linux-3.14.14/drivers/net/ethernet/chelsio/cxgb4vf/sge.c 2014-07-28 10:07:25.000000000 -0500
  189478. +++ linux-imx6-3.14/drivers/net/ethernet/chelsio/cxgb4vf/sge.c 2014-12-08 00:31:53.560418001 -0600
  189479. @@ -1510,7 +1510,8 @@
  189480. {
  189481. struct sk_buff *skb;
  189482. const struct cpl_rx_pkt *pkt = (void *)rsp;
  189483. - bool csum_ok = pkt->csum_calc && !pkt->err_vec;
  189484. + bool csum_ok = pkt->csum_calc && !pkt->err_vec &&
  189485. + (rspq->netdev->features & NETIF_F_RXCSUM);
  189486. struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq);
  189487. /*
  189488. @@ -1538,8 +1539,8 @@
  189489. skb_record_rx_queue(skb, rspq->idx);
  189490. rxq->stats.pkts++;
  189491. - if (csum_ok && (rspq->netdev->features & NETIF_F_RXCSUM) &&
  189492. - !pkt->err_vec && (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
  189493. + if (csum_ok && !pkt->err_vec &&
  189494. + (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
  189495. if (!pkt->ip_frag)
  189496. skb->ip_summed = CHECKSUM_UNNECESSARY;
  189497. else {
  189498. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/fec.h linux-imx6-3.14/drivers/net/ethernet/freescale/fec.h
  189499. --- linux-3.14.14/drivers/net/ethernet/freescale/fec.h 2014-07-28 10:07:25.000000000 -0500
  189500. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/fec.h 2014-12-08 00:31:53.592418001 -0600
  189501. @@ -221,7 +221,7 @@
  189502. #define BD_ENET_TX_RCMASK ((ushort)0x003c)
  189503. #define BD_ENET_TX_UN ((ushort)0x0002)
  189504. #define BD_ENET_TX_CSL ((ushort)0x0001)
  189505. -#define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */
  189506. +#define BD_ENET_TX_STATS ((ushort)0x0fff) /* All status bits */
  189507. /*enhanced buffer descriptor control/status used by Ethernet transmit*/
  189508. #define BD_ENET_TX_INT 0x40000000
  189509. @@ -246,8 +246,8 @@
  189510. #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
  189511. #define FEC_ENET_TX_FRSIZE 2048
  189512. #define FEC_ENET_TX_FRPPG (PAGE_SIZE / FEC_ENET_TX_FRSIZE)
  189513. -#define TX_RING_SIZE 16 /* Must be power of two */
  189514. -#define TX_RING_MOD_MASK 15 /* for this to work */
  189515. +#define TX_RING_SIZE 512 /* Must be power of two */
  189516. +#define TX_RING_MOD_MASK 511 /* for this to work */
  189517. #define BD_ENET_RX_INT 0x00800000
  189518. #define BD_ENET_RX_PTP ((ushort)0x0400)
  189519. @@ -256,12 +256,6 @@
  189520. #define FLAG_RX_CSUM_ENABLED (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
  189521. #define FLAG_RX_CSUM_ERROR (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
  189522. -struct fec_enet_delayed_work {
  189523. - struct delayed_work delay_work;
  189524. - bool timeout;
  189525. - bool trig_tx;
  189526. -};
  189527. -
  189528. /* The FEC buffer descriptors track the ring buffers. The rx_bd_base and
  189529. * tx_bd_base always point to the base of the buffer descriptors. The
  189530. * cur_rx and cur_tx point to the currently available buffer.
  189531. @@ -296,12 +290,18 @@
  189532. /* The ring entries to be free()ed */
  189533. struct bufdesc *dirty_tx;
  189534. + unsigned short bufdesc_size;
  189535. unsigned short tx_ring_size;
  189536. unsigned short rx_ring_size;
  189537. + unsigned short tx_stop_threshold;
  189538. + unsigned short tx_wake_threshold;
  189539. +
  189540. + /* Software TSO */
  189541. + char *tso_hdrs;
  189542. + dma_addr_t tso_hdrs_dma;
  189543. struct platform_device *pdev;
  189544. - int opened;
  189545. int dev_id;
  189546. /* Phylib and MDIO interface */
  189547. @@ -321,6 +321,8 @@
  189548. struct napi_struct napi;
  189549. int csum_flags;
  189550. + struct work_struct tx_timeout_work;
  189551. +
  189552. struct ptp_clock *ptp_clock;
  189553. struct ptp_clock_info ptp_caps;
  189554. unsigned long last_overflow_check;
  189555. @@ -333,7 +335,6 @@
  189556. int hwts_rx_en;
  189557. int hwts_tx_en;
  189558. struct timer_list time_keep;
  189559. - struct fec_enet_delayed_work delay_work;
  189560. struct regulator *reg_phy;
  189561. };
  189562. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/fec_main.c linux-imx6-3.14/drivers/net/ethernet/freescale/fec_main.c
  189563. --- linux-3.14.14/drivers/net/ethernet/freescale/fec_main.c 2014-07-28 10:07:25.000000000 -0500
  189564. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/fec_main.c 2014-12-08 00:31:53.592418001 -0600
  189565. @@ -36,6 +36,7 @@
  189566. #include <linux/in.h>
  189567. #include <linux/ip.h>
  189568. #include <net/ip.h>
  189569. +#include <net/tso.h>
  189570. #include <linux/tcp.h>
  189571. #include <linux/udp.h>
  189572. #include <linux/icmp.h>
  189573. @@ -54,6 +55,10 @@
  189574. #include <linux/of_net.h>
  189575. #include <linux/regulator/consumer.h>
  189576. #include <linux/if_vlan.h>
  189577. +#include <linux/pinctrl/consumer.h>
  189578. +#include <linux/busfreq-imx6.h>
  189579. +#include <linux/pm_runtime.h>
  189580. +#include <linux/pm_qos.h>
  189581. #include <asm/cacheflush.h>
  189582. @@ -91,6 +96,8 @@
  189583. #define FEC_QUIRK_HAS_CSUM (1 << 5)
  189584. /* Controller has hardware vlan support */
  189585. #define FEC_QUIRK_HAS_VLAN (1 << 6)
  189586. +/* Controller is FEC-MAC */
  189587. +#define FEC_QUIRK_FEC_MAC (1 << 7)
  189588. /* ENET IP errata ERR006358
  189589. *
  189590. * If the ready bit in the transmit buffer descriptor (TxBD[R]) is previously
  189591. @@ -100,7 +107,13 @@
  189592. * frames not being transmitted until there is a 0-to-1 transition on
  189593. * ENET_TDAR[TDAR].
  189594. */
  189595. -#define FEC_QUIRK_ERR006358 (1 << 7)
  189596. +#define FEC_QUIRK_ERR006358 (1 << 8)
  189597. +/*
  189598. + * i.MX6Q/DL ENET cannot wake up system in wait mode because ENET tx & rx
  189599. + * interrupt signal don't connect to GPC. So use pm qos to avoid cpu enter
  189600. + * to wait mode.
  189601. + */
  189602. +#define FEC_QUIRK_BUG_WAITMODE (1 << 9)
  189603. static struct platform_device_id fec_devtype[] = {
  189604. {
  189605. @@ -109,7 +122,7 @@
  189606. .driver_data = 0,
  189607. }, {
  189608. .name = "imx25-fec",
  189609. - .driver_data = FEC_QUIRK_USE_GASKET,
  189610. + .driver_data = FEC_QUIRK_USE_GASKET | FEC_QUIRK_FEC_MAC,
  189611. }, {
  189612. .name = "imx27-fec",
  189613. .driver_data = 0,
  189614. @@ -120,7 +133,8 @@
  189615. .name = "imx6q-fec",
  189616. .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
  189617. FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
  189618. - FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358,
  189619. + FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
  189620. + FEC_QUIRK_BUG_WAITMODE,
  189621. }, {
  189622. .name = "mvf600-fec",
  189623. .driver_data = FEC_QUIRK_ENET_MAC,
  189624. @@ -172,10 +186,6 @@
  189625. #endif
  189626. #endif /* CONFIG_M5272 */
  189627. -#if (((RX_RING_SIZE + TX_RING_SIZE) * 32) > PAGE_SIZE)
  189628. -#error "FEC: descriptor ring size constants too large"
  189629. -#endif
  189630. -
  189631. /* Interrupt events/masks. */
  189632. #define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
  189633. #define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
  189634. @@ -231,6 +241,15 @@
  189635. #define FEC_PAUSE_FLAG_AUTONEG 0x1
  189636. #define FEC_PAUSE_FLAG_ENABLE 0x2
  189637. +#define TSO_HEADER_SIZE 128
  189638. +/* Max number of allowed TCP segments for software TSO */
  189639. +#define FEC_MAX_TSO_SEGS 100
  189640. +#define FEC_MAX_SKB_DESCS (FEC_MAX_TSO_SEGS * 2 + MAX_SKB_FRAGS)
  189641. +
  189642. +#define IS_TSO_HEADER(txq, addr) \
  189643. + ((addr >= txq->tso_hdrs_dma) && \
  189644. + (addr < txq->tso_hdrs_dma + txq->tx_ring_size * TSO_HEADER_SIZE))
  189645. +
  189646. static int mii_cnt;
  189647. static inline
  189648. @@ -286,6 +305,22 @@
  189649. return (new_bd < base) ? (new_bd + ring_size) : new_bd;
  189650. }
  189651. +static int fec_enet_get_bd_index(struct bufdesc *base, struct bufdesc *bdp,
  189652. + struct fec_enet_private *fep)
  189653. +{
  189654. + return ((const char *)bdp - (const char *)base) / fep->bufdesc_size;
  189655. +}
  189656. +
  189657. +static int fec_enet_get_free_txdesc_num(struct fec_enet_private *fep)
  189658. +{
  189659. + int entries;
  189660. +
  189661. + entries = ((const char *)fep->dirty_tx -
  189662. + (const char *)fep->cur_tx) / fep->bufdesc_size - 1;
  189663. +
  189664. + return entries > 0 ? entries : entries + fep->tx_ring_size;
  189665. +}
  189666. +
  189667. static void *swap_buffer(void *bufaddr, int len)
  189668. {
  189669. int i;
  189670. @@ -297,6 +332,32 @@
  189671. return bufaddr;
  189672. }
  189673. +static void fec_dump(struct net_device *ndev)
  189674. +{
  189675. + struct fec_enet_private *fep = netdev_priv(ndev);
  189676. + struct bufdesc *bdp = fep->tx_bd_base;
  189677. + unsigned int index = 0;
  189678. +
  189679. + netdev_info(ndev, "TX ring dump\n");
  189680. + pr_info("Nr SC addr len SKB\n");
  189681. +
  189682. + do {
  189683. + pr_info("%3u %c%c 0x%04x 0x%08lx %4u %p\n",
  189684. + index,
  189685. + bdp == fep->cur_tx ? 'S' : ' ',
  189686. + bdp == fep->dirty_tx ? 'H' : ' ',
  189687. + bdp->cbd_sc, bdp->cbd_bufaddr, bdp->cbd_datlen,
  189688. + fep->tx_skbuff[index]);
  189689. + bdp = fec_enet_get_nextdesc(bdp, fep);
  189690. + index++;
  189691. + } while (bdp != fep->tx_bd_base);
  189692. +}
  189693. +
  189694. +static inline bool is_ipv4_pkt(struct sk_buff *skb)
  189695. +{
  189696. + return skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->version == 4;
  189697. +}
  189698. +
  189699. static int
  189700. fec_enet_clear_csum(struct sk_buff *skb, struct net_device *ndev)
  189701. {
  189702. @@ -307,137 +368,419 @@
  189703. if (unlikely(skb_cow_head(skb, 0)))
  189704. return -1;
  189705. + if (is_ipv4_pkt(skb))
  189706. + ip_hdr(skb)->check = 0;
  189707. *(__sum16 *)(skb->head + skb->csum_start + skb->csum_offset) = 0;
  189708. return 0;
  189709. }
  189710. -static netdev_tx_t
  189711. -fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
  189712. +static int
  189713. +fec_enet_txq_submit_frag_skb(struct sk_buff *skb, struct net_device *ndev)
  189714. {
  189715. struct fec_enet_private *fep = netdev_priv(ndev);
  189716. const struct platform_device_id *id_entry =
  189717. platform_get_device_id(fep->pdev);
  189718. - struct bufdesc *bdp, *bdp_pre;
  189719. - void *bufaddr;
  189720. - unsigned short status;
  189721. + struct bufdesc *bdp = fep->cur_tx;
  189722. + struct bufdesc_ex *ebdp;
  189723. + int nr_frags = skb_shinfo(skb)->nr_frags;
  189724. + int frag, frag_len;
  189725. + unsigned short status;
  189726. + unsigned int estatus = 0;
  189727. + skb_frag_t *this_frag;
  189728. unsigned int index;
  189729. + void *bufaddr;
  189730. + dma_addr_t addr;
  189731. + int i;
  189732. - /* Fill in a Tx ring entry */
  189733. + for (frag = 0; frag < nr_frags; frag++) {
  189734. + this_frag = &skb_shinfo(skb)->frags[frag];
  189735. + bdp = fec_enet_get_nextdesc(bdp, fep);
  189736. + ebdp = (struct bufdesc_ex *)bdp;
  189737. +
  189738. + status = bdp->cbd_sc;
  189739. + status &= ~BD_ENET_TX_STATS;
  189740. + status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
  189741. + frag_len = skb_shinfo(skb)->frags[frag].size;
  189742. +
  189743. + /* Handle the last BD specially */
  189744. + if (frag == nr_frags - 1) {
  189745. + status |= (BD_ENET_TX_INTR | BD_ENET_TX_LAST);
  189746. + if (fep->bufdesc_ex) {
  189747. + estatus |= BD_ENET_TX_INT;
  189748. + if (unlikely(skb_shinfo(skb)->tx_flags &
  189749. + SKBTX_HW_TSTAMP && fep->hwts_tx_en))
  189750. + estatus |= BD_ENET_TX_TS;
  189751. + }
  189752. + }
  189753. +
  189754. + if (fep->bufdesc_ex) {
  189755. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  189756. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  189757. + ebdp->cbd_bdu = 0;
  189758. + ebdp->cbd_esc = estatus;
  189759. + }
  189760. +
  189761. + bufaddr = page_address(this_frag->page.p) + this_frag->page_offset;
  189762. +
  189763. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  189764. + if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
  189765. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  189766. + memcpy(fep->tx_bounce[index], bufaddr, frag_len);
  189767. + bufaddr = fep->tx_bounce[index];
  189768. +
  189769. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  189770. + swap_buffer(bufaddr, frag_len);
  189771. + }
  189772. +
  189773. + addr = dma_map_single(&fep->pdev->dev, bufaddr, frag_len,
  189774. + DMA_TO_DEVICE);
  189775. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  189776. + dev_kfree_skb_any(skb);
  189777. + if (net_ratelimit())
  189778. + netdev_err(ndev, "Tx DMA memory map failed\n");
  189779. + goto dma_mapping_error;
  189780. + }
  189781. +
  189782. + bdp->cbd_bufaddr = addr;
  189783. + bdp->cbd_datlen = frag_len;
  189784. + bdp->cbd_sc = status;
  189785. + }
  189786. +
  189787. + fep->cur_tx = bdp;
  189788. +
  189789. + return 0;
  189790. +
  189791. +dma_mapping_error:
  189792. bdp = fep->cur_tx;
  189793. + for (i = 0; i < frag; i++) {
  189794. + bdp = fec_enet_get_nextdesc(bdp, fep);
  189795. + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
  189796. + bdp->cbd_datlen, DMA_TO_DEVICE);
  189797. + }
  189798. + return NETDEV_TX_OK;
  189799. +}
  189800. - status = bdp->cbd_sc;
  189801. +static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
  189802. +{
  189803. + struct fec_enet_private *fep = netdev_priv(ndev);
  189804. + const struct platform_device_id *id_entry =
  189805. + platform_get_device_id(fep->pdev);
  189806. + int nr_frags = skb_shinfo(skb)->nr_frags;
  189807. + struct bufdesc *bdp, *last_bdp;
  189808. + void *bufaddr;
  189809. + dma_addr_t addr;
  189810. + unsigned short status;
  189811. + unsigned short buflen;
  189812. + unsigned int estatus = 0;
  189813. + unsigned int index;
  189814. + int entries_free;
  189815. + int ret;
  189816. - if (status & BD_ENET_TX_READY) {
  189817. - /* Ooops. All transmit buffers are full. Bail out.
  189818. - * This should not happen, since ndev->tbusy should be set.
  189819. - */
  189820. - netdev_err(ndev, "tx queue full!\n");
  189821. - return NETDEV_TX_BUSY;
  189822. + entries_free = fec_enet_get_free_txdesc_num(fep);
  189823. + if (entries_free < MAX_SKB_FRAGS + 1) {
  189824. + dev_kfree_skb_any(skb);
  189825. + if (net_ratelimit())
  189826. + netdev_err(ndev, "NOT enough BD for SG!\n");
  189827. + return NETDEV_TX_OK;
  189828. }
  189829. /* Protocol checksum off-load for TCP and UDP. */
  189830. if (fec_enet_clear_csum(skb, ndev)) {
  189831. - kfree_skb(skb);
  189832. + dev_kfree_skb_any(skb);
  189833. return NETDEV_TX_OK;
  189834. }
  189835. - /* Clear all of the status flags */
  189836. + /* Fill in a Tx ring entry */
  189837. + bdp = fep->cur_tx;
  189838. + status = bdp->cbd_sc;
  189839. status &= ~BD_ENET_TX_STATS;
  189840. /* Set buffer length and buffer pointer */
  189841. bufaddr = skb->data;
  189842. - bdp->cbd_datlen = skb->len;
  189843. + buflen = skb_headlen(skb);
  189844. - /*
  189845. - * On some FEC implementations data must be aligned on
  189846. - * 4-byte boundaries. Use bounce buffers to copy data
  189847. - * and get it aligned. Ugh.
  189848. - */
  189849. - if (fep->bufdesc_ex)
  189850. - index = (struct bufdesc_ex *)bdp -
  189851. - (struct bufdesc_ex *)fep->tx_bd_base;
  189852. - else
  189853. - index = bdp - fep->tx_bd_base;
  189854. -
  189855. - if (((unsigned long) bufaddr) & FEC_ALIGNMENT) {
  189856. - memcpy(fep->tx_bounce[index], skb->data, skb->len);
  189857. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  189858. + if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
  189859. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  189860. + memcpy(fep->tx_bounce[index], skb->data, buflen);
  189861. bufaddr = fep->tx_bounce[index];
  189862. - }
  189863. -
  189864. - /*
  189865. - * Some design made an incorrect assumption on endian mode of
  189866. - * the system that it's running on. As the result, driver has to
  189867. - * swap every frame going to and coming from the controller.
  189868. - */
  189869. - if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  189870. - swap_buffer(bufaddr, skb->len);
  189871. - /* Save skb pointer */
  189872. - fep->tx_skbuff[index] = skb;
  189873. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  189874. + swap_buffer(bufaddr, buflen);
  189875. + }
  189876. - /* Push the data cache so the CPM does not get stale memory
  189877. - * data.
  189878. - */
  189879. - bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, bufaddr,
  189880. - skb->len, DMA_TO_DEVICE);
  189881. - if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
  189882. - bdp->cbd_bufaddr = 0;
  189883. - fep->tx_skbuff[index] = NULL;
  189884. + /* Push the data cache so the CPM does not get stale memory data. */
  189885. + addr = dma_map_single(&fep->pdev->dev, bufaddr, buflen, DMA_TO_DEVICE);
  189886. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  189887. dev_kfree_skb_any(skb);
  189888. if (net_ratelimit())
  189889. netdev_err(ndev, "Tx DMA memory map failed\n");
  189890. return NETDEV_TX_OK;
  189891. }
  189892. + if (nr_frags) {
  189893. + ret = fec_enet_txq_submit_frag_skb(skb, ndev);
  189894. + if (ret)
  189895. + return ret;
  189896. + } else {
  189897. + status |= (BD_ENET_TX_INTR | BD_ENET_TX_LAST);
  189898. + if (fep->bufdesc_ex) {
  189899. + estatus = BD_ENET_TX_INT;
  189900. + if (unlikely(skb_shinfo(skb)->tx_flags &
  189901. + SKBTX_HW_TSTAMP && fep->hwts_tx_en))
  189902. + estatus |= BD_ENET_TX_TS;
  189903. + }
  189904. + }
  189905. +
  189906. if (fep->bufdesc_ex) {
  189907. struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  189908. - ebdp->cbd_bdu = 0;
  189909. +
  189910. if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
  189911. - fep->hwts_tx_en)) {
  189912. - ebdp->cbd_esc = (BD_ENET_TX_TS | BD_ENET_TX_INT);
  189913. + fep->hwts_tx_en))
  189914. skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
  189915. - } else {
  189916. - ebdp->cbd_esc = BD_ENET_TX_INT;
  189917. - /* Enable protocol checksum flags
  189918. - * We do not bother with the IP Checksum bits as they
  189919. - * are done by the kernel
  189920. - */
  189921. - if (skb->ip_summed == CHECKSUM_PARTIAL)
  189922. - ebdp->cbd_esc |= BD_ENET_TX_PINS;
  189923. - }
  189924. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  189925. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  189926. +
  189927. + ebdp->cbd_bdu = 0;
  189928. + ebdp->cbd_esc = estatus;
  189929. }
  189930. + last_bdp = fep->cur_tx;
  189931. + index = fec_enet_get_bd_index(fep->tx_bd_base, last_bdp, fep);
  189932. + /* Save skb pointer */
  189933. + fep->tx_skbuff[index] = skb;
  189934. +
  189935. + bdp->cbd_datlen = buflen;
  189936. + bdp->cbd_bufaddr = addr;
  189937. +
  189938. /* Send it on its way. Tell FEC it's ready, interrupt when done,
  189939. * it's the last BD of the frame, and to put the CRC on the end.
  189940. */
  189941. - status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
  189942. - | BD_ENET_TX_LAST | BD_ENET_TX_TC);
  189943. + status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
  189944. bdp->cbd_sc = status;
  189945. - bdp_pre = fec_enet_get_prevdesc(bdp, fep);
  189946. - if ((id_entry->driver_data & FEC_QUIRK_ERR006358) &&
  189947. - !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) {
  189948. - fep->delay_work.trig_tx = true;
  189949. - schedule_delayed_work(&(fep->delay_work.delay_work),
  189950. - msecs_to_jiffies(1));
  189951. - }
  189952. -
  189953. /* If this was the last BD in the ring, start at the beginning again. */
  189954. - bdp = fec_enet_get_nextdesc(bdp, fep);
  189955. + bdp = fec_enet_get_nextdesc(last_bdp, fep);
  189956. skb_tx_timestamp(skb);
  189957. fep->cur_tx = bdp;
  189958. - if (fep->cur_tx == fep->dirty_tx)
  189959. - netif_stop_queue(ndev);
  189960. + /* Trigger transmission start */
  189961. + writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  189962. +
  189963. + return 0;
  189964. +}
  189965. +
  189966. +static int
  189967. +fec_enet_txq_put_data_tso(struct sk_buff *skb, struct net_device *ndev,
  189968. + struct bufdesc *bdp, int index, char *data,
  189969. + int size, bool last_tcp, bool is_last)
  189970. +{
  189971. + struct fec_enet_private *fep = netdev_priv(ndev);
  189972. + const struct platform_device_id *id_entry =
  189973. + platform_get_device_id(fep->pdev);
  189974. + struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  189975. + unsigned short status;
  189976. + unsigned int estatus = 0;
  189977. + dma_addr_t addr;
  189978. +
  189979. + status = bdp->cbd_sc;
  189980. + status &= ~BD_ENET_TX_STATS;
  189981. +
  189982. + status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
  189983. +
  189984. + if (((unsigned long) data) & FEC_ALIGNMENT ||
  189985. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  189986. + memcpy(fep->tx_bounce[index], data, size);
  189987. + data = fep->tx_bounce[index];
  189988. +
  189989. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  189990. + swap_buffer(data, size);
  189991. + }
  189992. +
  189993. + addr = dma_map_single(&fep->pdev->dev, data, size, DMA_TO_DEVICE);
  189994. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  189995. + dev_kfree_skb_any(skb);
  189996. + if (net_ratelimit())
  189997. + netdev_err(ndev, "Tx DMA memory map failed\n");
  189998. + return NETDEV_TX_BUSY;
  189999. + }
  190000. +
  190001. + bdp->cbd_datlen = size;
  190002. + bdp->cbd_bufaddr = addr;
  190003. +
  190004. + if (fep->bufdesc_ex) {
  190005. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  190006. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  190007. + ebdp->cbd_bdu = 0;
  190008. + ebdp->cbd_esc = estatus;
  190009. + }
  190010. +
  190011. + /* Handle the last BD specially */
  190012. + if (last_tcp)
  190013. + status |= (BD_ENET_TX_LAST | BD_ENET_TX_TC);
  190014. + if (is_last) {
  190015. + status |= BD_ENET_TX_INTR;
  190016. + if (fep->bufdesc_ex)
  190017. + ebdp->cbd_esc |= BD_ENET_TX_INT;
  190018. + }
  190019. +
  190020. + bdp->cbd_sc = status;
  190021. +
  190022. + return 0;
  190023. +}
  190024. +
  190025. +static int
  190026. +fec_enet_txq_put_hdr_tso(struct sk_buff *skb, struct net_device *ndev,
  190027. + struct bufdesc *bdp, int index)
  190028. +{
  190029. + struct fec_enet_private *fep = netdev_priv(ndev);
  190030. + const struct platform_device_id *id_entry =
  190031. + platform_get_device_id(fep->pdev);
  190032. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  190033. + struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  190034. + void *bufaddr;
  190035. + unsigned long dmabuf;
  190036. + unsigned short status;
  190037. + unsigned int estatus = 0;
  190038. +
  190039. + status = bdp->cbd_sc;
  190040. + status &= ~BD_ENET_TX_STATS;
  190041. + status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
  190042. +
  190043. + bufaddr = fep->tso_hdrs + index * TSO_HEADER_SIZE;
  190044. + dmabuf = fep->tso_hdrs_dma + index * TSO_HEADER_SIZE;
  190045. + if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
  190046. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  190047. + memcpy(fep->tx_bounce[index], skb->data, hdr_len);
  190048. + bufaddr = fep->tx_bounce[index];
  190049. +
  190050. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  190051. + swap_buffer(bufaddr, hdr_len);
  190052. +
  190053. + dmabuf = dma_map_single(&fep->pdev->dev, bufaddr,
  190054. + hdr_len, DMA_TO_DEVICE);
  190055. + if (dma_mapping_error(&fep->pdev->dev, dmabuf)) {
  190056. + dev_kfree_skb_any(skb);
  190057. + if (net_ratelimit())
  190058. + netdev_err(ndev, "Tx DMA memory map failed\n");
  190059. + return NETDEV_TX_BUSY;
  190060. + }
  190061. + }
  190062. +
  190063. + bdp->cbd_bufaddr = dmabuf;
  190064. + bdp->cbd_datlen = hdr_len;
  190065. +
  190066. + if (fep->bufdesc_ex) {
  190067. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  190068. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  190069. + ebdp->cbd_bdu = 0;
  190070. + ebdp->cbd_esc = estatus;
  190071. + }
  190072. +
  190073. + bdp->cbd_sc = status;
  190074. +
  190075. + return 0;
  190076. +}
  190077. +
  190078. +static int fec_enet_txq_submit_tso(struct sk_buff *skb, struct net_device *ndev)
  190079. +{
  190080. + struct fec_enet_private *fep = netdev_priv(ndev);
  190081. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  190082. + int total_len, data_left;
  190083. + struct bufdesc *bdp = fep->cur_tx;
  190084. + struct tso_t tso;
  190085. + unsigned int index = 0;
  190086. + int ret;
  190087. +
  190088. + if (tso_count_descs(skb) >= fec_enet_get_free_txdesc_num(fep)) {
  190089. + dev_kfree_skb_any(skb);
  190090. + if (net_ratelimit())
  190091. + netdev_err(ndev, "NOT enough BD for TSO!\n");
  190092. + return NETDEV_TX_OK;
  190093. + }
  190094. +
  190095. + /* Protocol checksum off-load for TCP and UDP. */
  190096. + if (fec_enet_clear_csum(skb, ndev)) {
  190097. + dev_kfree_skb_any(skb);
  190098. + return NETDEV_TX_OK;
  190099. + }
  190100. +
  190101. + /* Initialize the TSO handler, and prepare the first payload */
  190102. + tso_start(skb, &tso);
  190103. +
  190104. + total_len = skb->len - hdr_len;
  190105. + while (total_len > 0) {
  190106. + char *hdr;
  190107. +
  190108. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  190109. + data_left = min_t(int, skb_shinfo(skb)->gso_size, total_len);
  190110. + total_len -= data_left;
  190111. +
  190112. + /* prepare packet headers: MAC + IP + TCP */
  190113. + hdr = fep->tso_hdrs + index * TSO_HEADER_SIZE;
  190114. + tso_build_hdr(skb, hdr, &tso, data_left, total_len == 0);
  190115. + ret = fec_enet_txq_put_hdr_tso(skb, ndev, bdp, index);
  190116. + if (ret)
  190117. + goto err_release;
  190118. +
  190119. + while (data_left > 0) {
  190120. + int size;
  190121. +
  190122. + size = min_t(int, tso.size, data_left);
  190123. + bdp = fec_enet_get_nextdesc(bdp, fep);
  190124. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  190125. + ret = fec_enet_txq_put_data_tso(skb, ndev, bdp, index, tso.data,
  190126. + size, size == data_left,
  190127. + total_len == 0);
  190128. + if (ret)
  190129. + goto err_release;
  190130. +
  190131. + data_left -= size;
  190132. + tso_build_data(skb, &tso, size);
  190133. + }
  190134. +
  190135. + bdp = fec_enet_get_nextdesc(bdp, fep);
  190136. + }
  190137. +
  190138. + /* Save skb pointer */
  190139. + fep->tx_skbuff[index] = skb;
  190140. +
  190141. + skb_tx_timestamp(skb);
  190142. + fep->cur_tx = bdp;
  190143. /* Trigger transmission start */
  190144. writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  190145. + return 0;
  190146. +
  190147. +err_release:
  190148. + /* TODO: Release all used data descriptors for TSO */
  190149. + return ret;
  190150. +}
  190151. +
  190152. +static netdev_tx_t
  190153. +fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
  190154. +{
  190155. + struct fec_enet_private *fep = netdev_priv(ndev);
  190156. + int entries_free;
  190157. + int ret;
  190158. +
  190159. + if (skb_is_gso(skb))
  190160. + ret = fec_enet_txq_submit_tso(skb, ndev);
  190161. + else
  190162. + ret = fec_enet_txq_submit_skb(skb, ndev);
  190163. + if (ret)
  190164. + return ret;
  190165. +
  190166. + entries_free = fec_enet_get_free_txdesc_num(fep);
  190167. + if (entries_free <= fep->tx_stop_threshold)
  190168. + netif_stop_queue(ndev);
  190169. +
  190170. return NETDEV_TX_OK;
  190171. }
  190172. @@ -474,7 +817,7 @@
  190173. /* Initialize the BD for every fragment in the page. */
  190174. bdp->cbd_sc = 0;
  190175. - if (bdp->cbd_bufaddr && fep->tx_skbuff[i]) {
  190176. + if (fep->tx_skbuff[i]) {
  190177. dev_kfree_skb_any(fep->tx_skbuff[i]);
  190178. fep->tx_skbuff[i] = NULL;
  190179. }
  190180. @@ -488,12 +831,13 @@
  190181. fep->dirty_tx = bdp;
  190182. }
  190183. -/* This function is called to start or restart the FEC during a link
  190184. - * change. This only happens when switching between half and full
  190185. - * duplex.
  190186. +/*
  190187. + * This function is called to start or restart the FEC during a link
  190188. + * change, transmit timeout, or to reconfigure the FEC. The network
  190189. + * packet processing for this device must be stopped before this call.
  190190. */
  190191. static void
  190192. -fec_restart(struct net_device *ndev, int duplex)
  190193. +fec_restart(struct net_device *ndev)
  190194. {
  190195. struct fec_enet_private *fep = netdev_priv(ndev);
  190196. const struct platform_device_id *id_entry =
  190197. @@ -504,13 +848,6 @@
  190198. u32 rcntl = OPT_FRAME_SIZE | 0x04;
  190199. u32 ecntl = 0x2; /* ETHEREN */
  190200. - if (netif_running(ndev)) {
  190201. - netif_device_detach(ndev);
  190202. - napi_disable(&fep->napi);
  190203. - netif_stop_queue(ndev);
  190204. - netif_tx_lock_bh(ndev);
  190205. - }
  190206. -
  190207. /* Whack a reset. We should wait for this. */
  190208. writel(1, fep->hwp + FEC_ECNTRL);
  190209. udelay(10);
  190210. @@ -519,7 +856,8 @@
  190211. * enet-mac reset will reset mac address registers too,
  190212. * so need to reconfigure it.
  190213. */
  190214. - if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
  190215. + if (id_entry->driver_data & FEC_QUIRK_ENET_MAC ||
  190216. + id_entry->driver_data & FEC_QUIRK_FEC_MAC) {
  190217. memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN);
  190218. writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
  190219. writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
  190220. @@ -551,7 +889,7 @@
  190221. }
  190222. /* Enable MII mode */
  190223. - if (duplex) {
  190224. + if (fep->full_duplex == DUPLEX_FULL) {
  190225. /* FD enable */
  190226. writel(0x04, fep->hwp + FEC_X_CNTRL);
  190227. } else {
  190228. @@ -560,8 +898,6 @@
  190229. writel(0x0, fep->hwp + FEC_X_CNTRL);
  190230. }
  190231. - fep->full_duplex = duplex;
  190232. -
  190233. /* Set MII speed */
  190234. writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
  190235. @@ -679,13 +1015,6 @@
  190236. /* Enable interrupts we wish to service */
  190237. writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
  190238. -
  190239. - if (netif_running(ndev)) {
  190240. - netif_tx_unlock_bh(ndev);
  190241. - netif_wake_queue(ndev);
  190242. - napi_enable(&fep->napi);
  190243. - netif_device_attach(ndev);
  190244. - }
  190245. }
  190246. static void
  190247. @@ -723,29 +1052,44 @@
  190248. {
  190249. struct fec_enet_private *fep = netdev_priv(ndev);
  190250. + fec_dump(ndev);
  190251. +
  190252. ndev->stats.tx_errors++;
  190253. - fep->delay_work.timeout = true;
  190254. - schedule_delayed_work(&(fep->delay_work.delay_work), 0);
  190255. + schedule_work(&fep->tx_timeout_work);
  190256. }
  190257. -static void fec_enet_work(struct work_struct *work)
  190258. +static void fec_enet_timeout_work(struct work_struct *work)
  190259. {
  190260. struct fec_enet_private *fep =
  190261. - container_of(work,
  190262. - struct fec_enet_private,
  190263. - delay_work.delay_work.work);
  190264. -
  190265. - if (fep->delay_work.timeout) {
  190266. - fep->delay_work.timeout = false;
  190267. - fec_restart(fep->netdev, fep->full_duplex);
  190268. - netif_wake_queue(fep->netdev);
  190269. - }
  190270. + container_of(work, struct fec_enet_private, tx_timeout_work);
  190271. + struct net_device *ndev = fep->netdev;
  190272. - if (fep->delay_work.trig_tx) {
  190273. - fep->delay_work.trig_tx = false;
  190274. - writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  190275. + rtnl_lock();
  190276. + if (netif_device_present(ndev) || netif_running(ndev)) {
  190277. + napi_disable(&fep->napi);
  190278. + netif_tx_lock_bh(ndev);
  190279. + fec_restart(ndev);
  190280. + netif_wake_queue(ndev);
  190281. + netif_tx_unlock_bh(ndev);
  190282. + napi_enable(&fep->napi);
  190283. }
  190284. + rtnl_unlock();
  190285. +}
  190286. +
  190287. +static void
  190288. +fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts,
  190289. + struct skb_shared_hwtstamps *hwtstamps)
  190290. +{
  190291. + unsigned long flags;
  190292. + u64 ns;
  190293. +
  190294. + spin_lock_irqsave(&fep->tmreg_lock, flags);
  190295. + ns = timecounter_cyc2time(&fep->tc, ts);
  190296. + spin_unlock_irqrestore(&fep->tmreg_lock, flags);
  190297. +
  190298. + memset(hwtstamps, 0, sizeof(*hwtstamps));
  190299. + hwtstamps->hwtstamp = ns_to_ktime(ns);
  190300. }
  190301. static void
  190302. @@ -756,6 +1100,7 @@
  190303. unsigned short status;
  190304. struct sk_buff *skb;
  190305. int index = 0;
  190306. + int entries_free;
  190307. fep = netdev_priv(ndev);
  190308. bdp = fep->dirty_tx;
  190309. @@ -769,16 +1114,18 @@
  190310. if (bdp == fep->cur_tx)
  190311. break;
  190312. - if (fep->bufdesc_ex)
  190313. - index = (struct bufdesc_ex *)bdp -
  190314. - (struct bufdesc_ex *)fep->tx_bd_base;
  190315. - else
  190316. - index = bdp - fep->tx_bd_base;
  190317. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  190318. skb = fep->tx_skbuff[index];
  190319. - dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, skb->len,
  190320. - DMA_TO_DEVICE);
  190321. + fep->tx_skbuff[index] = NULL;
  190322. + if (!IS_TSO_HEADER(fep, bdp->cbd_bufaddr))
  190323. + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
  190324. + bdp->cbd_datlen, DMA_TO_DEVICE);
  190325. bdp->cbd_bufaddr = 0;
  190326. + if (!skb) {
  190327. + bdp = fec_enet_get_nextdesc(bdp, fep);
  190328. + continue;
  190329. + }
  190330. /* Check for errors. */
  190331. if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
  190332. @@ -797,26 +1144,18 @@
  190333. ndev->stats.tx_carrier_errors++;
  190334. } else {
  190335. ndev->stats.tx_packets++;
  190336. - ndev->stats.tx_bytes += bdp->cbd_datlen;
  190337. + ndev->stats.tx_bytes += skb->len;
  190338. }
  190339. if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) &&
  190340. fep->bufdesc_ex) {
  190341. struct skb_shared_hwtstamps shhwtstamps;
  190342. - unsigned long flags;
  190343. struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  190344. - memset(&shhwtstamps, 0, sizeof(shhwtstamps));
  190345. - spin_lock_irqsave(&fep->tmreg_lock, flags);
  190346. - shhwtstamps.hwtstamp = ns_to_ktime(
  190347. - timecounter_cyc2time(&fep->tc, ebdp->ts));
  190348. - spin_unlock_irqrestore(&fep->tmreg_lock, flags);
  190349. + fec_enet_hwtstamp(fep, ebdp->ts, &shhwtstamps);
  190350. skb_tstamp_tx(skb, &shhwtstamps);
  190351. }
  190352. - if (status & BD_ENET_TX_READY)
  190353. - netdev_err(ndev, "HEY! Enet xmit interrupt and TX_READY\n");
  190354. -
  190355. /* Deferred means some collisions occurred during transmit,
  190356. * but we eventually sent the packet OK.
  190357. */
  190358. @@ -825,7 +1164,6 @@
  190359. /* Free the sk buffer associated with this last transmit */
  190360. dev_kfree_skb_any(skb);
  190361. - fep->tx_skbuff[index] = NULL;
  190362. fep->dirty_tx = bdp;
  190363. @@ -834,14 +1172,17 @@
  190364. /* Since we have freed up a buffer, the ring is no longer full
  190365. */
  190366. - if (fep->dirty_tx != fep->cur_tx) {
  190367. - if (netif_queue_stopped(ndev))
  190368. + if (netif_queue_stopped(ndev)) {
  190369. + entries_free = fec_enet_get_free_txdesc_num(fep);
  190370. + if (entries_free >= fep->tx_wake_threshold)
  190371. netif_wake_queue(ndev);
  190372. }
  190373. }
  190374. - return;
  190375. -}
  190376. + /* ERR006538: Keep the transmitter going */
  190377. + if (bdp != fep->cur_tx && readl(fep->hwp + FEC_X_DES_ACTIVE) == 0)
  190378. + writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  190379. +}
  190380. /* During a receive, the cur_rx points to the current incoming buffer.
  190381. * When we update through the ring, if the next incoming buffer has
  190382. @@ -876,8 +1217,11 @@
  190383. while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
  190384. - if (pkt_received >= budget)
  190385. + if (pkt_received >= budget) {
  190386. + /* overwhelmed take a breath */
  190387. + udelay(210);
  190388. break;
  190389. + }
  190390. pkt_received++;
  190391. /* Since we have allocated space to hold a complete frame,
  190392. @@ -886,8 +1230,7 @@
  190393. if ((status & BD_ENET_RX_LAST) == 0)
  190394. netdev_err(ndev, "rcv is not +last\n");
  190395. - if (!fep->opened)
  190396. - goto rx_processing_done;
  190397. + writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
  190398. /* Check for errors. */
  190399. if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
  190400. @@ -920,11 +1263,7 @@
  190401. pkt_len = bdp->cbd_datlen;
  190402. ndev->stats.rx_bytes += pkt_len;
  190403. - if (fep->bufdesc_ex)
  190404. - index = (struct bufdesc_ex *)bdp -
  190405. - (struct bufdesc_ex *)fep->rx_bd_base;
  190406. - else
  190407. - index = bdp - fep->rx_bd_base;
  190408. + index = fec_enet_get_bd_index(fep->rx_bd_base, bdp, fep);
  190409. data = fep->rx_skbuff[index]->data;
  190410. dma_sync_single_for_cpu(&fep->pdev->dev, bdp->cbd_bufaddr,
  190411. FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
  190412. @@ -975,18 +1314,9 @@
  190413. skb->protocol = eth_type_trans(skb, ndev);
  190414. /* Get receive timestamp from the skb */
  190415. - if (fep->hwts_rx_en && fep->bufdesc_ex) {
  190416. - struct skb_shared_hwtstamps *shhwtstamps =
  190417. - skb_hwtstamps(skb);
  190418. - unsigned long flags;
  190419. -
  190420. - memset(shhwtstamps, 0, sizeof(*shhwtstamps));
  190421. -
  190422. - spin_lock_irqsave(&fep->tmreg_lock, flags);
  190423. - shhwtstamps->hwtstamp = ns_to_ktime(
  190424. - timecounter_cyc2time(&fep->tc, ebdp->ts));
  190425. - spin_unlock_irqrestore(&fep->tmreg_lock, flags);
  190426. - }
  190427. + if (fep->hwts_rx_en && fep->bufdesc_ex)
  190428. + fec_enet_hwtstamp(fep, ebdp->ts,
  190429. + skb_hwtstamps(skb));
  190430. if (fep->bufdesc_ex &&
  190431. (fep->csum_flags & FLAG_RX_CSUM_ENABLED)) {
  190432. @@ -1044,29 +1374,25 @@
  190433. {
  190434. struct net_device *ndev = dev_id;
  190435. struct fec_enet_private *fep = netdev_priv(ndev);
  190436. + const unsigned napi_mask = FEC_ENET_RXF | FEC_ENET_TXF;
  190437. uint int_events;
  190438. irqreturn_t ret = IRQ_NONE;
  190439. - do {
  190440. - int_events = readl(fep->hwp + FEC_IEVENT);
  190441. - writel(int_events, fep->hwp + FEC_IEVENT);
  190442. + int_events = readl(fep->hwp + FEC_IEVENT);
  190443. + writel(int_events & ~napi_mask, fep->hwp + FEC_IEVENT);
  190444. - if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) {
  190445. - ret = IRQ_HANDLED;
  190446. + if (int_events & napi_mask) {
  190447. + ret = IRQ_HANDLED;
  190448. - /* Disable the RX interrupt */
  190449. - if (napi_schedule_prep(&fep->napi)) {
  190450. - writel(FEC_RX_DISABLED_IMASK,
  190451. - fep->hwp + FEC_IMASK);
  190452. - __napi_schedule(&fep->napi);
  190453. - }
  190454. - }
  190455. + /* Disable the NAPI interrupts */
  190456. + writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
  190457. + napi_schedule(&fep->napi);
  190458. + }
  190459. - if (int_events & FEC_ENET_MII) {
  190460. - ret = IRQ_HANDLED;
  190461. - complete(&fep->mdio_done);
  190462. - }
  190463. - } while (int_events);
  190464. + if (int_events & FEC_ENET_MII) {
  190465. + ret = IRQ_HANDLED;
  190466. + complete(&fep->mdio_done);
  190467. + }
  190468. return ret;
  190469. }
  190470. @@ -1074,8 +1400,16 @@
  190471. static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
  190472. {
  190473. struct net_device *ndev = napi->dev;
  190474. - int pkts = fec_enet_rx(ndev, budget);
  190475. struct fec_enet_private *fep = netdev_priv(ndev);
  190476. + int pkts;
  190477. +
  190478. + /*
  190479. + * Clear any pending transmit or receive interrupts before
  190480. + * processing the rings to avoid racing with the hardware.
  190481. + */
  190482. + writel(FEC_ENET_RXF | FEC_ENET_TXF, fep->hwp + FEC_IEVENT);
  190483. +
  190484. + pkts = fec_enet_rx(ndev, budget);
  190485. fec_enet_tx(ndev);
  190486. @@ -1173,14 +1507,23 @@
  190487. return;
  190488. }
  190489. - if (phy_dev->link) {
  190490. + /*
  190491. + * If the netdev is down, or is going down, we're not interested
  190492. + * in link state events, so just mark our idea of the link as down
  190493. + * and ignore the event.
  190494. + */
  190495. + if (!netif_running(ndev) || !netif_device_present(ndev)) {
  190496. + fep->link = 0;
  190497. + } else if (phy_dev->link) {
  190498. if (!fep->link) {
  190499. fep->link = phy_dev->link;
  190500. status_change = 1;
  190501. }
  190502. - if (fep->full_duplex != phy_dev->duplex)
  190503. + if (fep->full_duplex != phy_dev->duplex) {
  190504. + fep->full_duplex = phy_dev->duplex;
  190505. status_change = 1;
  190506. + }
  190507. if (phy_dev->speed != fep->speed) {
  190508. fep->speed = phy_dev->speed;
  190509. @@ -1188,11 +1531,21 @@
  190510. }
  190511. /* if any of the above changed restart the FEC */
  190512. - if (status_change)
  190513. - fec_restart(ndev, phy_dev->duplex);
  190514. + if (status_change) {
  190515. + napi_disable(&fep->napi);
  190516. + netif_tx_lock_bh(ndev);
  190517. + fec_restart(ndev);
  190518. + netif_wake_queue(ndev);
  190519. + netif_tx_unlock_bh(ndev);
  190520. + napi_enable(&fep->napi);
  190521. + }
  190522. } else {
  190523. if (fep->link) {
  190524. + napi_disable(&fep->napi);
  190525. + netif_tx_lock_bh(ndev);
  190526. fec_stop(ndev);
  190527. + netif_tx_unlock_bh(ndev);
  190528. + napi_enable(&fep->napi);
  190529. fep->link = phy_dev->link;
  190530. status_change = 1;
  190531. }
  190532. @@ -1255,9 +1608,51 @@
  190533. return 0;
  190534. }
  190535. -static int fec_enet_mdio_reset(struct mii_bus *bus)
  190536. +static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
  190537. {
  190538. + struct fec_enet_private *fep = netdev_priv(ndev);
  190539. + int ret;
  190540. +
  190541. + if (enable) {
  190542. + pm_runtime_enable(&fep->pdev->dev);
  190543. +
  190544. + ret = clk_prepare_enable(fep->clk_ahb);
  190545. + if (ret)
  190546. + return ret;
  190547. + ret = clk_prepare_enable(fep->clk_ipg);
  190548. + if (ret)
  190549. + goto failed_clk_ipg;
  190550. + if (fep->clk_enet_out) {
  190551. + ret = clk_prepare_enable(fep->clk_enet_out);
  190552. + if (ret)
  190553. + goto failed_clk_enet_out;
  190554. + }
  190555. + if (fep->clk_ptp) {
  190556. + ret = clk_prepare_enable(fep->clk_ptp);
  190557. + if (ret)
  190558. + goto failed_clk_ptp;
  190559. + }
  190560. + } else {
  190561. + clk_disable_unprepare(fep->clk_ahb);
  190562. + clk_disable_unprepare(fep->clk_ipg);
  190563. + if (fep->clk_enet_out)
  190564. + clk_disable_unprepare(fep->clk_enet_out);
  190565. + if (fep->clk_ptp)
  190566. + clk_disable_unprepare(fep->clk_ptp);
  190567. +
  190568. + pm_runtime_disable(&fep->pdev->dev);
  190569. + }
  190570. +
  190571. return 0;
  190572. +failed_clk_ptp:
  190573. + if (fep->clk_enet_out)
  190574. + clk_disable_unprepare(fep->clk_enet_out);
  190575. +failed_clk_enet_out:
  190576. + clk_disable_unprepare(fep->clk_ipg);
  190577. +failed_clk_ipg:
  190578. + clk_disable_unprepare(fep->clk_ahb);
  190579. +
  190580. + return ret;
  190581. }
  190582. static int fec_enet_mii_probe(struct net_device *ndev)
  190583. @@ -1304,6 +1699,7 @@
  190584. /* mask with MAC supported features */
  190585. if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT) {
  190586. phy_dev->supported &= PHY_GBIT_FEATURES;
  190587. + phy_dev->supported &= ~SUPPORTED_1000baseT_Half;
  190588. #if !defined(CONFIG_M5272)
  190589. phy_dev->supported |= SUPPORTED_Pause;
  190590. #endif
  190591. @@ -1369,7 +1765,7 @@
  190592. * Reference Manual has an error on this, and gets fixed on i.MX6Q
  190593. * document.
  190594. */
  190595. - fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ahb), 5000000);
  190596. + fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ipg), 5000000);
  190597. if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
  190598. fep->phy_speed--;
  190599. fep->phy_speed <<= 1;
  190600. @@ -1384,7 +1780,6 @@
  190601. fep->mii_bus->name = "fec_enet_mii_bus";
  190602. fep->mii_bus->read = fec_enet_mdio_read;
  190603. fep->mii_bus->write = fec_enet_mdio_write;
  190604. - fep->mii_bus->reset = fec_enet_mdio_reset;
  190605. snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
  190606. pdev->name, fep->dev_id + 1);
  190607. fep->mii_bus->priv = fep;
  190608. @@ -1508,6 +1903,9 @@
  190609. {
  190610. struct fec_enet_private *fep = netdev_priv(ndev);
  190611. + if (!fep->phy_dev)
  190612. + return -ENODEV;
  190613. +
  190614. if (pause->tx_pause != pause->rx_pause) {
  190615. netdev_info(ndev,
  190616. "hardware only support enable/disable both tx and rx");
  190617. @@ -1533,8 +1931,14 @@
  190618. fec_stop(ndev);
  190619. phy_start_aneg(fep->phy_dev);
  190620. }
  190621. - if (netif_running(ndev))
  190622. - fec_restart(ndev, 0);
  190623. + if (netif_running(ndev)) {
  190624. + napi_disable(&fep->napi);
  190625. + netif_tx_lock_bh(ndev);
  190626. + fec_restart(ndev);
  190627. + netif_wake_queue(ndev);
  190628. + netif_tx_unlock_bh(ndev);
  190629. + napi_enable(&fep->napi);
  190630. + }
  190631. return 0;
  190632. }
  190633. @@ -1651,21 +2055,19 @@
  190634. }
  190635. static const struct ethtool_ops fec_enet_ethtool_ops = {
  190636. -#if !defined(CONFIG_M5272)
  190637. - .get_pauseparam = fec_enet_get_pauseparam,
  190638. - .set_pauseparam = fec_enet_set_pauseparam,
  190639. -#endif
  190640. .get_settings = fec_enet_get_settings,
  190641. .set_settings = fec_enet_set_settings,
  190642. .get_drvinfo = fec_enet_get_drvinfo,
  190643. - .get_link = ethtool_op_get_link,
  190644. - .get_ts_info = fec_enet_get_ts_info,
  190645. .nway_reset = fec_enet_nway_reset,
  190646. + .get_link = ethtool_op_get_link,
  190647. #ifndef CONFIG_M5272
  190648. - .get_ethtool_stats = fec_enet_get_ethtool_stats,
  190649. + .get_pauseparam = fec_enet_get_pauseparam,
  190650. + .set_pauseparam = fec_enet_set_pauseparam,
  190651. .get_strings = fec_enet_get_strings,
  190652. + .get_ethtool_stats = fec_enet_get_ethtool_stats,
  190653. .get_sset_count = fec_enet_get_sset_count,
  190654. #endif
  190655. + .get_ts_info = fec_enet_get_ts_info,
  190656. };
  190657. static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
  190658. @@ -1699,18 +2101,23 @@
  190659. bdp = fep->rx_bd_base;
  190660. for (i = 0; i < fep->rx_ring_size; i++) {
  190661. skb = fep->rx_skbuff[i];
  190662. -
  190663. - if (bdp->cbd_bufaddr)
  190664. + fep->rx_skbuff[i] = NULL;
  190665. + if (skb) {
  190666. dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
  190667. FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
  190668. - if (skb)
  190669. dev_kfree_skb(skb);
  190670. + }
  190671. bdp = fec_enet_get_nextdesc(bdp, fep);
  190672. }
  190673. bdp = fep->tx_bd_base;
  190674. - for (i = 0; i < fep->tx_ring_size; i++)
  190675. + for (i = 0; i < fep->tx_ring_size; i++) {
  190676. kfree(fep->tx_bounce[i]);
  190677. + fep->tx_bounce[i] = NULL;
  190678. + skb = fep->tx_skbuff[i];
  190679. + fep->tx_skbuff[i] = NULL;
  190680. + dev_kfree_skb(skb);
  190681. + }
  190682. }
  190683. static int fec_enet_alloc_buffers(struct net_device *ndev)
  190684. @@ -1722,21 +2129,23 @@
  190685. bdp = fep->rx_bd_base;
  190686. for (i = 0; i < fep->rx_ring_size; i++) {
  190687. + dma_addr_t addr;
  190688. +
  190689. skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
  190690. - if (!skb) {
  190691. - fec_enet_free_buffers(ndev);
  190692. - return -ENOMEM;
  190693. - }
  190694. - fep->rx_skbuff[i] = skb;
  190695. + if (!skb)
  190696. + goto err_alloc;
  190697. - bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data,
  190698. + addr = dma_map_single(&fep->pdev->dev, skb->data,
  190699. FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
  190700. - if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
  190701. - fec_enet_free_buffers(ndev);
  190702. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  190703. + dev_kfree_skb(skb);
  190704. if (net_ratelimit())
  190705. netdev_err(ndev, "Rx DMA memory map failed\n");
  190706. - return -ENOMEM;
  190707. + goto err_alloc;
  190708. }
  190709. +
  190710. + fep->rx_skbuff[i] = skb;
  190711. + bdp->cbd_bufaddr = addr;
  190712. bdp->cbd_sc = BD_ENET_RX_EMPTY;
  190713. if (fep->bufdesc_ex) {
  190714. @@ -1754,6 +2163,8 @@
  190715. bdp = fep->tx_bd_base;
  190716. for (i = 0; i < fep->tx_ring_size; i++) {
  190717. fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
  190718. + if (!fep->tx_bounce[i])
  190719. + goto err_alloc;
  190720. bdp->cbd_sc = 0;
  190721. bdp->cbd_bufaddr = 0;
  190722. @@ -1771,14 +2182,35 @@
  190723. bdp->cbd_sc |= BD_SC_WRAP;
  190724. return 0;
  190725. +
  190726. + err_alloc:
  190727. + fec_enet_free_buffers(ndev);
  190728. + return -ENOMEM;
  190729. }
  190730. static int
  190731. fec_enet_open(struct net_device *ndev)
  190732. {
  190733. struct fec_enet_private *fep = netdev_priv(ndev);
  190734. + const struct platform_device_id *id_entry =
  190735. + platform_get_device_id(fep->pdev);
  190736. int ret;
  190737. + if (id_entry->driver_data & FEC_QUIRK_BUG_WAITMODE)
  190738. + pm_qos_add_request(&ndev->pm_qos_req,
  190739. + PM_QOS_CPU_DMA_LATENCY,
  190740. + 0);
  190741. + else
  190742. + pm_qos_add_request(&ndev->pm_qos_req,
  190743. + PM_QOS_CPU_DMA_LATENCY,
  190744. + PM_QOS_DEFAULT_VALUE);
  190745. +
  190746. +
  190747. + pinctrl_pm_select_default_state(&fep->pdev->dev);
  190748. + ret = fec_enet_clk_enable(ndev, true);
  190749. + if (ret)
  190750. + return ret;
  190751. +
  190752. /* I should reset the ring buffers here, but I don't yet know
  190753. * a simple way to do that.
  190754. */
  190755. @@ -1794,10 +2226,12 @@
  190756. return ret;
  190757. }
  190758. + pm_runtime_get_sync(&fep->pdev->dev);
  190759. +
  190760. + fec_restart(ndev);
  190761. napi_enable(&fep->napi);
  190762. phy_start(fep->phy_dev);
  190763. netif_start_queue(ndev);
  190764. - fep->opened = 1;
  190765. return 0;
  190766. }
  190767. @@ -1806,17 +2240,22 @@
  190768. {
  190769. struct fec_enet_private *fep = netdev_priv(ndev);
  190770. - /* Don't know what to do yet. */
  190771. - napi_disable(&fep->napi);
  190772. - fep->opened = 0;
  190773. - netif_stop_queue(ndev);
  190774. - fec_stop(ndev);
  190775. + phy_stop(fep->phy_dev);
  190776. - if (fep->phy_dev) {
  190777. - phy_stop(fep->phy_dev);
  190778. - phy_disconnect(fep->phy_dev);
  190779. + if (netif_device_present(ndev)) {
  190780. + napi_disable(&fep->napi);
  190781. + netif_tx_disable(ndev);
  190782. + fec_stop(ndev);
  190783. }
  190784. + phy_disconnect(fep->phy_dev);
  190785. + fep->phy_dev = NULL;
  190786. +
  190787. + fec_enet_clk_enable(ndev, false);
  190788. + pinctrl_pm_select_sleep_state(&fep->pdev->dev);
  190789. + pm_qos_remove_request(&ndev->pm_qos_req);
  190790. + pm_runtime_put_sync_suspend(&fep->pdev->dev);
  190791. +
  190792. fec_enet_free_buffers(ndev);
  190793. return 0;
  190794. @@ -1904,10 +2343,11 @@
  190795. struct fec_enet_private *fep = netdev_priv(ndev);
  190796. struct sockaddr *addr = p;
  190797. - if (!is_valid_ether_addr(addr->sa_data))
  190798. - return -EADDRNOTAVAIL;
  190799. -
  190800. - memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
  190801. + if (addr) {
  190802. + if (!is_valid_ether_addr(addr->sa_data))
  190803. + return -EADDRNOTAVAIL;
  190804. + memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
  190805. + }
  190806. writel(ndev->dev_addr[3] | (ndev->dev_addr[2] << 8) |
  190807. (ndev->dev_addr[1] << 16) | (ndev->dev_addr[0] << 24),
  190808. @@ -1940,12 +2380,21 @@
  190809. }
  190810. #endif
  190811. +#define FEATURES_NEED_QUIESCE NETIF_F_RXCSUM
  190812. +
  190813. static int fec_set_features(struct net_device *netdev,
  190814. netdev_features_t features)
  190815. {
  190816. struct fec_enet_private *fep = netdev_priv(netdev);
  190817. netdev_features_t changed = features ^ netdev->features;
  190818. + /* Quiesce the device if necessary */
  190819. + if (netif_running(netdev) && changed & FEATURES_NEED_QUIESCE) {
  190820. + napi_disable(&fep->napi);
  190821. + netif_tx_lock_bh(netdev);
  190822. + fec_stop(netdev);
  190823. + }
  190824. +
  190825. netdev->features = features;
  190826. /* Receive checksum has been changed */
  190827. @@ -1954,14 +2403,14 @@
  190828. fep->csum_flags |= FLAG_RX_CSUM_ENABLED;
  190829. else
  190830. fep->csum_flags &= ~FLAG_RX_CSUM_ENABLED;
  190831. + }
  190832. - if (netif_running(netdev)) {
  190833. - fec_stop(netdev);
  190834. - fec_restart(netdev, fep->phy_dev->duplex);
  190835. - netif_wake_queue(netdev);
  190836. - } else {
  190837. - fec_restart(netdev, fep->phy_dev->duplex);
  190838. - }
  190839. + /* Resume the device after updates */
  190840. + if (netif_running(netdev) && changed & FEATURES_NEED_QUIESCE) {
  190841. + fec_restart(netdev);
  190842. + netif_wake_queue(netdev);
  190843. + netif_tx_unlock_bh(netdev);
  190844. + napi_enable(&fep->napi);
  190845. }
  190846. return 0;
  190847. @@ -1993,23 +2442,43 @@
  190848. const struct platform_device_id *id_entry =
  190849. platform_get_device_id(fep->pdev);
  190850. struct bufdesc *cbd_base;
  190851. + int bd_size;
  190852. +
  190853. + /* init the tx & rx ring size */
  190854. + fep->tx_ring_size = TX_RING_SIZE;
  190855. + fep->rx_ring_size = RX_RING_SIZE;
  190856. +
  190857. + fep->tx_stop_threshold = FEC_MAX_SKB_DESCS;
  190858. + fep->tx_wake_threshold = (fep->tx_ring_size - fep->tx_stop_threshold) / 2;
  190859. +
  190860. + if (fep->bufdesc_ex)
  190861. + fep->bufdesc_size = sizeof(struct bufdesc_ex);
  190862. + else
  190863. + fep->bufdesc_size = sizeof(struct bufdesc);
  190864. + bd_size = (fep->tx_ring_size + fep->rx_ring_size) *
  190865. + fep->bufdesc_size;
  190866. /* Allocate memory for buffer descriptors. */
  190867. - cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
  190868. + cbd_base = dma_alloc_coherent(NULL, bd_size, &fep->bd_dma,
  190869. GFP_KERNEL);
  190870. if (!cbd_base)
  190871. return -ENOMEM;
  190872. + fep->tso_hdrs = dma_alloc_coherent(NULL, fep->tx_ring_size * TSO_HEADER_SIZE,
  190873. + &fep->tso_hdrs_dma, GFP_KERNEL);
  190874. + if (!fep->tso_hdrs) {
  190875. + dma_free_coherent(NULL, bd_size, cbd_base, fep->bd_dma);
  190876. + return -ENOMEM;
  190877. + }
  190878. +
  190879. memset(cbd_base, 0, PAGE_SIZE);
  190880. fep->netdev = ndev;
  190881. /* Get the Ethernet address */
  190882. fec_get_mac(ndev);
  190883. -
  190884. - /* init the tx & rx ring size */
  190885. - fep->tx_ring_size = TX_RING_SIZE;
  190886. - fep->rx_ring_size = RX_RING_SIZE;
  190887. + /* make sure MAC we just acquired is programmed into the hw */
  190888. + fec_set_mac_address(ndev, NULL);
  190889. /* Set receive and transmit descriptor base. */
  190890. fep->rx_bd_base = cbd_base;
  190891. @@ -2027,22 +2496,22 @@
  190892. writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK);
  190893. netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, NAPI_POLL_WEIGHT);
  190894. - if (id_entry->driver_data & FEC_QUIRK_HAS_VLAN) {
  190895. + if (id_entry->driver_data & FEC_QUIRK_HAS_VLAN)
  190896. /* enable hw VLAN support */
  190897. ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
  190898. - ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
  190899. - }
  190900. if (id_entry->driver_data & FEC_QUIRK_HAS_CSUM) {
  190901. + ndev->gso_max_segs = FEC_MAX_TSO_SEGS;
  190902. +
  190903. /* enable hw accelerator */
  190904. ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
  190905. - | NETIF_F_RXCSUM);
  190906. - ndev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
  190907. - | NETIF_F_RXCSUM);
  190908. + | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO);
  190909. fep->csum_flags |= FLAG_RX_CSUM_ENABLED;
  190910. }
  190911. - fec_restart(ndev, 0);
  190912. + ndev->hw_features = ndev->features;
  190913. +
  190914. + fec_restart(ndev);
  190915. return 0;
  190916. }
  190917. @@ -2117,6 +2586,9 @@
  190918. fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG;
  190919. #endif
  190920. + /* Select default pin state */
  190921. + pinctrl_pm_select_default_state(&pdev->dev);
  190922. +
  190923. r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  190924. fep->hwp = devm_ioremap_resource(&pdev->dev, r);
  190925. if (IS_ERR(fep->hwp)) {
  190926. @@ -2167,26 +2639,10 @@
  190927. fep->bufdesc_ex = 0;
  190928. }
  190929. - ret = clk_prepare_enable(fep->clk_ahb);
  190930. + ret = fec_enet_clk_enable(ndev, true);
  190931. if (ret)
  190932. goto failed_clk;
  190933. - ret = clk_prepare_enable(fep->clk_ipg);
  190934. - if (ret)
  190935. - goto failed_clk_ipg;
  190936. -
  190937. - if (fep->clk_enet_out) {
  190938. - ret = clk_prepare_enable(fep->clk_enet_out);
  190939. - if (ret)
  190940. - goto failed_clk_enet_out;
  190941. - }
  190942. -
  190943. - if (fep->clk_ptp) {
  190944. - ret = clk_prepare_enable(fep->clk_ptp);
  190945. - if (ret)
  190946. - goto failed_clk_ptp;
  190947. - }
  190948. -
  190949. fep->reg_phy = devm_regulator_get(&pdev->dev, "phy");
  190950. if (!IS_ERR(fep->reg_phy)) {
  190951. ret = regulator_enable(fep->reg_phy);
  190952. @@ -2228,6 +2684,8 @@
  190953. /* Carrier starts down, phylib will bring it up */
  190954. netif_carrier_off(ndev);
  190955. + fec_enet_clk_enable(ndev, false);
  190956. + pinctrl_pm_select_sleep_state(&pdev->dev);
  190957. ret = register_netdev(ndev);
  190958. if (ret)
  190959. @@ -2236,7 +2694,7 @@
  190960. if (fep->bufdesc_ex && fep->ptp_clock)
  190961. netdev_info(ndev, "registered PHC device %d\n", fep->dev_id);
  190962. - INIT_DELAYED_WORK(&(fep->delay_work.delay_work), fec_enet_work);
  190963. + INIT_WORK(&fep->tx_timeout_work, fec_enet_timeout_work);
  190964. return 0;
  190965. failed_register:
  190966. @@ -2246,16 +2704,10 @@
  190967. failed_init:
  190968. if (fep->reg_phy)
  190969. regulator_disable(fep->reg_phy);
  190970. + if (fep->ptp_clock)
  190971. + ptp_clock_unregister(fep->ptp_clock);
  190972. failed_regulator:
  190973. - if (fep->clk_ptp)
  190974. - clk_disable_unprepare(fep->clk_ptp);
  190975. -failed_clk_ptp:
  190976. - if (fep->clk_enet_out)
  190977. - clk_disable_unprepare(fep->clk_enet_out);
  190978. -failed_clk_enet_out:
  190979. - clk_disable_unprepare(fep->clk_ipg);
  190980. -failed_clk_ipg:
  190981. - clk_disable_unprepare(fep->clk_ahb);
  190982. + fec_enet_clk_enable(ndev, false);
  190983. failed_clk:
  190984. failed_ioremap:
  190985. free_netdev(ndev);
  190986. @@ -2269,42 +2721,40 @@
  190987. struct net_device *ndev = platform_get_drvdata(pdev);
  190988. struct fec_enet_private *fep = netdev_priv(ndev);
  190989. - cancel_delayed_work_sync(&(fep->delay_work.delay_work));
  190990. + cancel_work_sync(&fep->tx_timeout_work);
  190991. unregister_netdev(ndev);
  190992. fec_enet_mii_remove(fep);
  190993. del_timer_sync(&fep->time_keep);
  190994. if (fep->reg_phy)
  190995. regulator_disable(fep->reg_phy);
  190996. - if (fep->clk_ptp)
  190997. - clk_disable_unprepare(fep->clk_ptp);
  190998. if (fep->ptp_clock)
  190999. ptp_clock_unregister(fep->ptp_clock);
  191000. - if (fep->clk_enet_out)
  191001. - clk_disable_unprepare(fep->clk_enet_out);
  191002. - clk_disable_unprepare(fep->clk_ipg);
  191003. - clk_disable_unprepare(fep->clk_ahb);
  191004. + fec_enet_clk_enable(ndev, false);
  191005. free_netdev(ndev);
  191006. return 0;
  191007. }
  191008. -#ifdef CONFIG_PM_SLEEP
  191009. +#ifdef CONFIG_PM
  191010. static int
  191011. fec_suspend(struct device *dev)
  191012. {
  191013. struct net_device *ndev = dev_get_drvdata(dev);
  191014. struct fec_enet_private *fep = netdev_priv(ndev);
  191015. + rtnl_lock();
  191016. if (netif_running(ndev)) {
  191017. - fec_stop(ndev);
  191018. + phy_stop(fep->phy_dev);
  191019. + napi_disable(&fep->napi);
  191020. + netif_tx_lock_bh(ndev);
  191021. netif_device_detach(ndev);
  191022. + netif_tx_unlock_bh(ndev);
  191023. + fec_stop(ndev);
  191024. }
  191025. - if (fep->clk_ptp)
  191026. - clk_disable_unprepare(fep->clk_ptp);
  191027. - if (fep->clk_enet_out)
  191028. - clk_disable_unprepare(fep->clk_enet_out);
  191029. - clk_disable_unprepare(fep->clk_ipg);
  191030. - clk_disable_unprepare(fep->clk_ahb);
  191031. + rtnl_unlock();
  191032. +
  191033. + fec_enet_clk_enable(ndev, false);
  191034. + pinctrl_pm_select_sleep_state(&fep->pdev->dev);
  191035. if (fep->reg_phy)
  191036. regulator_disable(fep->reg_phy);
  191037. @@ -2325,48 +2775,49 @@
  191038. return ret;
  191039. }
  191040. - ret = clk_prepare_enable(fep->clk_ahb);
  191041. - if (ret)
  191042. - goto failed_clk_ahb;
  191043. -
  191044. - ret = clk_prepare_enable(fep->clk_ipg);
  191045. + pinctrl_pm_select_default_state(&fep->pdev->dev);
  191046. + ret = fec_enet_clk_enable(ndev, true);
  191047. if (ret)
  191048. - goto failed_clk_ipg;
  191049. -
  191050. - if (fep->clk_enet_out) {
  191051. - ret = clk_prepare_enable(fep->clk_enet_out);
  191052. - if (ret)
  191053. - goto failed_clk_enet_out;
  191054. - }
  191055. -
  191056. - if (fep->clk_ptp) {
  191057. - ret = clk_prepare_enable(fep->clk_ptp);
  191058. - if (ret)
  191059. - goto failed_clk_ptp;
  191060. - }
  191061. + goto failed_clk;
  191062. + rtnl_lock();
  191063. if (netif_running(ndev)) {
  191064. - fec_restart(ndev, fep->full_duplex);
  191065. + fec_restart(ndev);
  191066. + netif_tx_lock_bh(ndev);
  191067. netif_device_attach(ndev);
  191068. + netif_tx_unlock_bh(ndev);
  191069. + napi_enable(&fep->napi);
  191070. + phy_start(fep->phy_dev);
  191071. }
  191072. + rtnl_unlock();
  191073. return 0;
  191074. -failed_clk_ptp:
  191075. - if (fep->clk_enet_out)
  191076. - clk_disable_unprepare(fep->clk_enet_out);
  191077. -failed_clk_enet_out:
  191078. - clk_disable_unprepare(fep->clk_ipg);
  191079. -failed_clk_ipg:
  191080. - clk_disable_unprepare(fep->clk_ahb);
  191081. -failed_clk_ahb:
  191082. +failed_clk:
  191083. if (fep->reg_phy)
  191084. regulator_disable(fep->reg_phy);
  191085. return ret;
  191086. }
  191087. +
  191088. +static int fec_runtime_suspend(struct device *dev)
  191089. +{
  191090. + release_bus_freq(BUS_FREQ_HIGH);
  191091. + return 0;
  191092. +}
  191093. +
  191094. +static int fec_runtime_resume(struct device *dev)
  191095. +{
  191096. + request_bus_freq(BUS_FREQ_HIGH);
  191097. + return 0;
  191098. +}
  191099. +
  191100. +static const struct dev_pm_ops fec_pm_ops = {
  191101. + SET_RUNTIME_PM_OPS(fec_runtime_suspend, fec_runtime_resume, NULL)
  191102. + SET_SYSTEM_SLEEP_PM_OPS(fec_suspend, fec_resume)
  191103. +};
  191104. +
  191105. #endif /* CONFIG_PM_SLEEP */
  191106. -static SIMPLE_DEV_PM_OPS(fec_pm_ops, fec_suspend, fec_resume);
  191107. static struct platform_driver fec_driver = {
  191108. .driver = {
  191109. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/fec_ptp.c linux-imx6-3.14/drivers/net/ethernet/freescale/fec_ptp.c
  191110. --- linux-3.14.14/drivers/net/ethernet/freescale/fec_ptp.c 2014-07-28 10:07:25.000000000 -0500
  191111. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/fec_ptp.c 2014-12-08 00:31:53.592418001 -0600
  191112. @@ -372,6 +372,7 @@
  191113. fep->ptp_caps.n_alarm = 0;
  191114. fep->ptp_caps.n_ext_ts = 0;
  191115. fep->ptp_caps.n_per_out = 0;
  191116. + fep->ptp_caps.n_pins = 0;
  191117. fep->ptp_caps.pps = 0;
  191118. fep->ptp_caps.adjfreq = fec_ptp_adjfreq;
  191119. fep->ptp_caps.adjtime = fec_ptp_adjtime;
  191120. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c linux-imx6-3.14/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
  191121. --- linux-3.14.14/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 2014-07-28 10:07:25.000000000 -0500
  191122. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 2014-12-08 00:31:53.592418001 -0600
  191123. @@ -91,6 +91,9 @@
  191124. u16 pkt_len, sc;
  191125. int curidx;
  191126. + if (budget <= 0)
  191127. + return received;
  191128. +
  191129. /*
  191130. * First, grab all of the stats for the incoming packet.
  191131. * These get messed up if we get called due to a busy condition.
  191132. @@ -789,10 +792,6 @@
  191133. phydev = of_phy_connect(dev, fep->fpi->phy_node, &fs_adjust_link, 0,
  191134. iface);
  191135. if (!phydev) {
  191136. - phydev = of_phy_connect_fixed_link(dev, &fs_adjust_link,
  191137. - iface);
  191138. - }
  191139. - if (!phydev) {
  191140. dev_err(&dev->dev, "Could not attach to PHY\n");
  191141. return -ENODEV;
  191142. }
  191143. @@ -1026,9 +1025,16 @@
  191144. fpi->use_napi = 1;
  191145. fpi->napi_weight = 17;
  191146. fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0);
  191147. - if ((!fpi->phy_node) && (!of_get_property(ofdev->dev.of_node, "fixed-link",
  191148. - NULL)))
  191149. - goto out_free_fpi;
  191150. + if (!fpi->phy_node && of_phy_is_fixed_link(ofdev->dev.of_node)) {
  191151. + err = of_phy_register_fixed_link(ofdev->dev.of_node);
  191152. + if (err)
  191153. + goto out_free_fpi;
  191154. +
  191155. + /* In the case of a fixed PHY, the DT node associated
  191156. + * to the PHY is the Ethernet MAC DT node.
  191157. + */
  191158. + fpi->phy_node = ofdev->dev.of_node;
  191159. + }
  191160. if (of_device_is_compatible(ofdev->dev.of_node, "fsl,mpc5125-fec")) {
  191161. phy_connection_type = of_get_property(ofdev->dev.of_node,
  191162. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/fs_enet/mii-fec.c linux-imx6-3.14/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
  191163. --- linux-3.14.14/drivers/net/ethernet/freescale/fs_enet/mii-fec.c 2014-07-28 10:07:25.000000000 -0500
  191164. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/fs_enet/mii-fec.c 2014-12-08 00:31:53.596418001 -0600
  191165. @@ -95,12 +95,6 @@
  191166. }
  191167. -static int fs_enet_fec_mii_reset(struct mii_bus *bus)
  191168. -{
  191169. - /* nothing here - for now */
  191170. - return 0;
  191171. -}
  191172. -
  191173. static struct of_device_id fs_enet_mdio_fec_match[];
  191174. static int fs_enet_mdio_probe(struct platform_device *ofdev)
  191175. {
  191176. @@ -128,7 +122,6 @@
  191177. new_bus->name = "FEC MII Bus";
  191178. new_bus->read = &fs_enet_fec_mii_read;
  191179. new_bus->write = &fs_enet_fec_mii_write;
  191180. - new_bus->reset = &fs_enet_fec_mii_reset;
  191181. ret = of_address_to_resource(ofdev->dev.of_node, 0, &res);
  191182. if (ret)
  191183. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/gianfar.c linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar.c
  191184. --- linux-3.14.14/drivers/net/ethernet/freescale/gianfar.c 2014-07-28 10:07:25.000000000 -0500
  191185. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar.c 2014-12-08 00:31:53.596418001 -0600
  191186. @@ -9,7 +9,7 @@
  191187. * Maintainer: Kumar Gala
  191188. * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  191189. *
  191190. - * Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
  191191. + * Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc.
  191192. * Copyright 2007 MontaVista Software, Inc.
  191193. *
  191194. * This program is free software; you can redistribute it and/or modify it
  191195. @@ -121,7 +121,7 @@
  191196. static irqreturn_t gfar_transmit(int irq, void *dev_id);
  191197. static irqreturn_t gfar_interrupt(int irq, void *dev_id);
  191198. static void adjust_link(struct net_device *dev);
  191199. -static void init_registers(struct net_device *dev);
  191200. +static noinline void gfar_update_link_state(struct gfar_private *priv);
  191201. static int init_phy(struct net_device *dev);
  191202. static int gfar_probe(struct platform_device *ofdev);
  191203. static int gfar_remove(struct platform_device *ofdev);
  191204. @@ -129,8 +129,10 @@
  191205. static void gfar_set_multi(struct net_device *dev);
  191206. static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
  191207. static void gfar_configure_serdes(struct net_device *dev);
  191208. -static int gfar_poll(struct napi_struct *napi, int budget);
  191209. -static int gfar_poll_sq(struct napi_struct *napi, int budget);
  191210. +static int gfar_poll_rx(struct napi_struct *napi, int budget);
  191211. +static int gfar_poll_tx(struct napi_struct *napi, int budget);
  191212. +static int gfar_poll_rx_sq(struct napi_struct *napi, int budget);
  191213. +static int gfar_poll_tx_sq(struct napi_struct *napi, int budget);
  191214. #ifdef CONFIG_NET_POLL_CONTROLLER
  191215. static void gfar_netpoll(struct net_device *dev);
  191216. #endif
  191217. @@ -138,9 +140,7 @@
  191218. static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue);
  191219. static void gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
  191220. int amount_pull, struct napi_struct *napi);
  191221. -void gfar_halt(struct net_device *dev);
  191222. -static void gfar_halt_nodisable(struct net_device *dev);
  191223. -void gfar_start(struct net_device *dev);
  191224. +static void gfar_halt_nodisable(struct gfar_private *priv);
  191225. static void gfar_clear_exact_match(struct net_device *dev);
  191226. static void gfar_set_mac_for_addr(struct net_device *dev, int num,
  191227. const u8 *addr);
  191228. @@ -332,72 +332,76 @@
  191229. }
  191230. }
  191231. -static void gfar_init_mac(struct net_device *ndev)
  191232. +static void gfar_rx_buff_size_config(struct gfar_private *priv)
  191233. {
  191234. - struct gfar_private *priv = netdev_priv(ndev);
  191235. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191236. - u32 rctrl = 0;
  191237. - u32 tctrl = 0;
  191238. - u32 attrs = 0;
  191239. -
  191240. - /* write the tx/rx base registers */
  191241. - gfar_init_tx_rx_base(priv);
  191242. -
  191243. - /* Configure the coalescing support */
  191244. - gfar_configure_coalescing_all(priv);
  191245. + int frame_size = priv->ndev->mtu + ETH_HLEN;
  191246. /* set this when rx hw offload (TOE) functions are being used */
  191247. priv->uses_rxfcb = 0;
  191248. + if (priv->ndev->features & (NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX))
  191249. + priv->uses_rxfcb = 1;
  191250. +
  191251. + if (priv->hwts_rx_en)
  191252. + priv->uses_rxfcb = 1;
  191253. +
  191254. + if (priv->uses_rxfcb)
  191255. + frame_size += GMAC_FCB_LEN;
  191256. +
  191257. + frame_size += priv->padding;
  191258. +
  191259. + frame_size = (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) +
  191260. + INCREMENTAL_BUFFER_SIZE;
  191261. +
  191262. + priv->rx_buffer_size = frame_size;
  191263. +}
  191264. +
  191265. +static void gfar_mac_rx_config(struct gfar_private *priv)
  191266. +{
  191267. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191268. + u32 rctrl = 0;
  191269. +
  191270. if (priv->rx_filer_enable) {
  191271. rctrl |= RCTRL_FILREN;
  191272. /* Program the RIR0 reg with the required distribution */
  191273. - gfar_write(&regs->rir0, DEFAULT_RIR0);
  191274. + if (priv->poll_mode == GFAR_SQ_POLLING)
  191275. + gfar_write(&regs->rir0, DEFAULT_2RXQ_RIR0);
  191276. + else /* GFAR_MQ_POLLING */
  191277. + gfar_write(&regs->rir0, DEFAULT_8RXQ_RIR0);
  191278. }
  191279. /* Restore PROMISC mode */
  191280. - if (ndev->flags & IFF_PROMISC)
  191281. + if (priv->ndev->flags & IFF_PROMISC)
  191282. rctrl |= RCTRL_PROM;
  191283. - if (ndev->features & NETIF_F_RXCSUM) {
  191284. + if (priv->ndev->features & NETIF_F_RXCSUM)
  191285. rctrl |= RCTRL_CHECKSUMMING;
  191286. - priv->uses_rxfcb = 1;
  191287. - }
  191288. -
  191289. - if (priv->extended_hash) {
  191290. - rctrl |= RCTRL_EXTHASH;
  191291. - gfar_clear_exact_match(ndev);
  191292. - rctrl |= RCTRL_EMEN;
  191293. - }
  191294. + if (priv->extended_hash)
  191295. + rctrl |= RCTRL_EXTHASH | RCTRL_EMEN;
  191296. if (priv->padding) {
  191297. rctrl &= ~RCTRL_PAL_MASK;
  191298. rctrl |= RCTRL_PADDING(priv->padding);
  191299. }
  191300. - /* Insert receive time stamps into padding alignment bytes */
  191301. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) {
  191302. - rctrl &= ~RCTRL_PAL_MASK;
  191303. - rctrl |= RCTRL_PADDING(8);
  191304. - priv->padding = 8;
  191305. - }
  191306. -
  191307. /* Enable HW time stamping if requested from user space */
  191308. - if (priv->hwts_rx_en) {
  191309. + if (priv->hwts_rx_en)
  191310. rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE;
  191311. - priv->uses_rxfcb = 1;
  191312. - }
  191313. - if (ndev->features & NETIF_F_HW_VLAN_CTAG_RX) {
  191314. + if (priv->ndev->features & NETIF_F_HW_VLAN_CTAG_RX)
  191315. rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT;
  191316. - priv->uses_rxfcb = 1;
  191317. - }
  191318. /* Init rctrl based on our settings */
  191319. gfar_write(&regs->rctrl, rctrl);
  191320. +}
  191321. - if (ndev->features & NETIF_F_IP_CSUM)
  191322. +static void gfar_mac_tx_config(struct gfar_private *priv)
  191323. +{
  191324. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191325. + u32 tctrl = 0;
  191326. +
  191327. + if (priv->ndev->features & NETIF_F_IP_CSUM)
  191328. tctrl |= TCTRL_INIT_CSUM;
  191329. if (priv->prio_sched_en)
  191330. @@ -408,30 +412,51 @@
  191331. gfar_write(&regs->tr47wt, DEFAULT_WRRS_WEIGHT);
  191332. }
  191333. - gfar_write(&regs->tctrl, tctrl);
  191334. + if (priv->ndev->features & NETIF_F_HW_VLAN_CTAG_TX)
  191335. + tctrl |= TCTRL_VLINS;
  191336. - /* Set the extraction length and index */
  191337. - attrs = ATTRELI_EL(priv->rx_stash_size) |
  191338. - ATTRELI_EI(priv->rx_stash_index);
  191339. + gfar_write(&regs->tctrl, tctrl);
  191340. +}
  191341. - gfar_write(&regs->attreli, attrs);
  191342. +static void gfar_configure_coalescing(struct gfar_private *priv,
  191343. + unsigned long tx_mask, unsigned long rx_mask)
  191344. +{
  191345. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191346. + u32 __iomem *baddr;
  191347. - /* Start with defaults, and add stashing or locking
  191348. - * depending on the approprate variables
  191349. - */
  191350. - attrs = ATTR_INIT_SETTINGS;
  191351. + if (priv->mode == MQ_MG_MODE) {
  191352. + int i = 0;
  191353. - if (priv->bd_stash_en)
  191354. - attrs |= ATTR_BDSTASH;
  191355. + baddr = &regs->txic0;
  191356. + for_each_set_bit(i, &tx_mask, priv->num_tx_queues) {
  191357. + gfar_write(baddr + i, 0);
  191358. + if (likely(priv->tx_queue[i]->txcoalescing))
  191359. + gfar_write(baddr + i, priv->tx_queue[i]->txic);
  191360. + }
  191361. - if (priv->rx_stash_size != 0)
  191362. - attrs |= ATTR_BUFSTASH;
  191363. + baddr = &regs->rxic0;
  191364. + for_each_set_bit(i, &rx_mask, priv->num_rx_queues) {
  191365. + gfar_write(baddr + i, 0);
  191366. + if (likely(priv->rx_queue[i]->rxcoalescing))
  191367. + gfar_write(baddr + i, priv->rx_queue[i]->rxic);
  191368. + }
  191369. + } else {
  191370. + /* Backward compatible case -- even if we enable
  191371. + * multiple queues, there's only single reg to program
  191372. + */
  191373. + gfar_write(&regs->txic, 0);
  191374. + if (likely(priv->tx_queue[0]->txcoalescing))
  191375. + gfar_write(&regs->txic, priv->tx_queue[0]->txic);
  191376. - gfar_write(&regs->attr, attrs);
  191377. + gfar_write(&regs->rxic, 0);
  191378. + if (unlikely(priv->rx_queue[0]->rxcoalescing))
  191379. + gfar_write(&regs->rxic, priv->rx_queue[0]->rxic);
  191380. + }
  191381. +}
  191382. - gfar_write(&regs->fifo_tx_thr, priv->fifo_threshold);
  191383. - gfar_write(&regs->fifo_tx_starve, priv->fifo_starve);
  191384. - gfar_write(&regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
  191385. +void gfar_configure_coalescing_all(struct gfar_private *priv)
  191386. +{
  191387. + gfar_configure_coalescing(priv, 0xFF, 0xFF);
  191388. }
  191389. static struct net_device_stats *gfar_get_stats(struct net_device *dev)
  191390. @@ -479,12 +504,27 @@
  191391. #endif
  191392. };
  191393. -void lock_rx_qs(struct gfar_private *priv)
  191394. +static void gfar_ints_disable(struct gfar_private *priv)
  191395. {
  191396. int i;
  191397. + for (i = 0; i < priv->num_grps; i++) {
  191398. + struct gfar __iomem *regs = priv->gfargrp[i].regs;
  191399. + /* Clear IEVENT */
  191400. + gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
  191401. - for (i = 0; i < priv->num_rx_queues; i++)
  191402. - spin_lock(&priv->rx_queue[i]->rxlock);
  191403. + /* Initialize IMASK */
  191404. + gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  191405. + }
  191406. +}
  191407. +
  191408. +static void gfar_ints_enable(struct gfar_private *priv)
  191409. +{
  191410. + int i;
  191411. + for (i = 0; i < priv->num_grps; i++) {
  191412. + struct gfar __iomem *regs = priv->gfargrp[i].regs;
  191413. + /* Unmask the interrupts we look for */
  191414. + gfar_write(&regs->imask, IMASK_DEFAULT);
  191415. + }
  191416. }
  191417. void lock_tx_qs(struct gfar_private *priv)
  191418. @@ -495,23 +535,50 @@
  191419. spin_lock(&priv->tx_queue[i]->txlock);
  191420. }
  191421. -void unlock_rx_qs(struct gfar_private *priv)
  191422. +void unlock_tx_qs(struct gfar_private *priv)
  191423. {
  191424. int i;
  191425. - for (i = 0; i < priv->num_rx_queues; i++)
  191426. - spin_unlock(&priv->rx_queue[i]->rxlock);
  191427. + for (i = 0; i < priv->num_tx_queues; i++)
  191428. + spin_unlock(&priv->tx_queue[i]->txlock);
  191429. }
  191430. -void unlock_tx_qs(struct gfar_private *priv)
  191431. +static int gfar_alloc_tx_queues(struct gfar_private *priv)
  191432. {
  191433. int i;
  191434. - for (i = 0; i < priv->num_tx_queues; i++)
  191435. - spin_unlock(&priv->tx_queue[i]->txlock);
  191436. + for (i = 0; i < priv->num_tx_queues; i++) {
  191437. + priv->tx_queue[i] = kzalloc(sizeof(struct gfar_priv_tx_q),
  191438. + GFP_KERNEL);
  191439. + if (!priv->tx_queue[i])
  191440. + return -ENOMEM;
  191441. +
  191442. + priv->tx_queue[i]->tx_skbuff = NULL;
  191443. + priv->tx_queue[i]->qindex = i;
  191444. + priv->tx_queue[i]->dev = priv->ndev;
  191445. + spin_lock_init(&(priv->tx_queue[i]->txlock));
  191446. + }
  191447. + return 0;
  191448. +}
  191449. +
  191450. +static int gfar_alloc_rx_queues(struct gfar_private *priv)
  191451. +{
  191452. + int i;
  191453. +
  191454. + for (i = 0; i < priv->num_rx_queues; i++) {
  191455. + priv->rx_queue[i] = kzalloc(sizeof(struct gfar_priv_rx_q),
  191456. + GFP_KERNEL);
  191457. + if (!priv->rx_queue[i])
  191458. + return -ENOMEM;
  191459. +
  191460. + priv->rx_queue[i]->rx_skbuff = NULL;
  191461. + priv->rx_queue[i]->qindex = i;
  191462. + priv->rx_queue[i]->dev = priv->ndev;
  191463. + }
  191464. + return 0;
  191465. }
  191466. -static void free_tx_pointers(struct gfar_private *priv)
  191467. +static void gfar_free_tx_queues(struct gfar_private *priv)
  191468. {
  191469. int i;
  191470. @@ -519,7 +586,7 @@
  191471. kfree(priv->tx_queue[i]);
  191472. }
  191473. -static void free_rx_pointers(struct gfar_private *priv)
  191474. +static void gfar_free_rx_queues(struct gfar_private *priv)
  191475. {
  191476. int i;
  191477. @@ -553,23 +620,26 @@
  191478. {
  191479. int i;
  191480. - for (i = 0; i < priv->num_grps; i++)
  191481. - napi_disable(&priv->gfargrp[i].napi);
  191482. + for (i = 0; i < priv->num_grps; i++) {
  191483. + napi_disable(&priv->gfargrp[i].napi_rx);
  191484. + napi_disable(&priv->gfargrp[i].napi_tx);
  191485. + }
  191486. }
  191487. static void enable_napi(struct gfar_private *priv)
  191488. {
  191489. int i;
  191490. - for (i = 0; i < priv->num_grps; i++)
  191491. - napi_enable(&priv->gfargrp[i].napi);
  191492. + for (i = 0; i < priv->num_grps; i++) {
  191493. + napi_enable(&priv->gfargrp[i].napi_rx);
  191494. + napi_enable(&priv->gfargrp[i].napi_tx);
  191495. + }
  191496. }
  191497. static int gfar_parse_group(struct device_node *np,
  191498. struct gfar_private *priv, const char *model)
  191499. {
  191500. struct gfar_priv_grp *grp = &priv->gfargrp[priv->num_grps];
  191501. - u32 *queue_mask;
  191502. int i;
  191503. for (i = 0; i < GFAR_NUM_IRQS; i++) {
  191504. @@ -598,16 +668,52 @@
  191505. grp->priv = priv;
  191506. spin_lock_init(&grp->grplock);
  191507. if (priv->mode == MQ_MG_MODE) {
  191508. - queue_mask = (u32 *)of_get_property(np, "fsl,rx-bit-map", NULL);
  191509. - grp->rx_bit_map = queue_mask ?
  191510. - *queue_mask : (DEFAULT_MAPPING >> priv->num_grps);
  191511. - queue_mask = (u32 *)of_get_property(np, "fsl,tx-bit-map", NULL);
  191512. - grp->tx_bit_map = queue_mask ?
  191513. - *queue_mask : (DEFAULT_MAPPING >> priv->num_grps);
  191514. + u32 *rxq_mask, *txq_mask;
  191515. + rxq_mask = (u32 *)of_get_property(np, "fsl,rx-bit-map", NULL);
  191516. + txq_mask = (u32 *)of_get_property(np, "fsl,tx-bit-map", NULL);
  191517. +
  191518. + if (priv->poll_mode == GFAR_SQ_POLLING) {
  191519. + /* One Q per interrupt group: Q0 to G0, Q1 to G1 */
  191520. + grp->rx_bit_map = (DEFAULT_MAPPING >> priv->num_grps);
  191521. + grp->tx_bit_map = (DEFAULT_MAPPING >> priv->num_grps);
  191522. + } else { /* GFAR_MQ_POLLING */
  191523. + grp->rx_bit_map = rxq_mask ?
  191524. + *rxq_mask : (DEFAULT_MAPPING >> priv->num_grps);
  191525. + grp->tx_bit_map = txq_mask ?
  191526. + *txq_mask : (DEFAULT_MAPPING >> priv->num_grps);
  191527. + }
  191528. } else {
  191529. grp->rx_bit_map = 0xFF;
  191530. grp->tx_bit_map = 0xFF;
  191531. }
  191532. +
  191533. + /* bit_map's MSB is q0 (from q0 to q7) but, for_each_set_bit parses
  191534. + * right to left, so we need to revert the 8 bits to get the q index
  191535. + */
  191536. + grp->rx_bit_map = bitrev8(grp->rx_bit_map);
  191537. + grp->tx_bit_map = bitrev8(grp->tx_bit_map);
  191538. +
  191539. + /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values,
  191540. + * also assign queues to groups
  191541. + */
  191542. + for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) {
  191543. + if (!grp->rx_queue)
  191544. + grp->rx_queue = priv->rx_queue[i];
  191545. + grp->num_rx_queues++;
  191546. + grp->rstat |= (RSTAT_CLEAR_RHALT >> i);
  191547. + priv->rqueue |= ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
  191548. + priv->rx_queue[i]->grp = grp;
  191549. + }
  191550. +
  191551. + for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) {
  191552. + if (!grp->tx_queue)
  191553. + grp->tx_queue = priv->tx_queue[i];
  191554. + grp->num_tx_queues++;
  191555. + grp->tstat |= (TSTAT_CLEAR_THALT >> i);
  191556. + priv->tqueue |= (TQUEUE_EN0 >> i);
  191557. + priv->tx_queue[i]->grp = grp;
  191558. + }
  191559. +
  191560. priv->num_grps++;
  191561. return 0;
  191562. @@ -628,13 +734,45 @@
  191563. const u32 *stash_idx;
  191564. unsigned int num_tx_qs, num_rx_qs;
  191565. u32 *tx_queues, *rx_queues;
  191566. + unsigned short mode, poll_mode;
  191567. if (!np || !of_device_is_available(np))
  191568. return -ENODEV;
  191569. - /* parse the num of tx and rx queues */
  191570. + if (of_device_is_compatible(np, "fsl,etsec2")) {
  191571. + mode = MQ_MG_MODE;
  191572. + poll_mode = GFAR_SQ_POLLING;
  191573. + } else {
  191574. + mode = SQ_SG_MODE;
  191575. + poll_mode = GFAR_SQ_POLLING;
  191576. + }
  191577. +
  191578. + /* parse the num of HW tx and rx queues */
  191579. tx_queues = (u32 *)of_get_property(np, "fsl,num_tx_queues", NULL);
  191580. - num_tx_qs = tx_queues ? *tx_queues : 1;
  191581. + rx_queues = (u32 *)of_get_property(np, "fsl,num_rx_queues", NULL);
  191582. +
  191583. + if (mode == SQ_SG_MODE) {
  191584. + num_tx_qs = 1;
  191585. + num_rx_qs = 1;
  191586. + } else { /* MQ_MG_MODE */
  191587. + /* get the actual number of supported groups */
  191588. + unsigned int num_grps = of_get_available_child_count(np);
  191589. +
  191590. + if (num_grps == 0 || num_grps > MAXGROUPS) {
  191591. + dev_err(&ofdev->dev, "Invalid # of int groups(%d)\n",
  191592. + num_grps);
  191593. + pr_err("Cannot do alloc_etherdev, aborting\n");
  191594. + return -EINVAL;
  191595. + }
  191596. +
  191597. + if (poll_mode == GFAR_SQ_POLLING) {
  191598. + num_tx_qs = num_grps; /* one txq per int group */
  191599. + num_rx_qs = num_grps; /* one rxq per int group */
  191600. + } else { /* GFAR_MQ_POLLING */
  191601. + num_tx_qs = tx_queues ? *tx_queues : 1;
  191602. + num_rx_qs = rx_queues ? *rx_queues : 1;
  191603. + }
  191604. + }
  191605. if (num_tx_qs > MAX_TX_QS) {
  191606. pr_err("num_tx_qs(=%d) greater than MAX_TX_QS(=%d)\n",
  191607. @@ -643,9 +781,6 @@
  191608. return -EINVAL;
  191609. }
  191610. - rx_queues = (u32 *)of_get_property(np, "fsl,num_rx_queues", NULL);
  191611. - num_rx_qs = rx_queues ? *rx_queues : 1;
  191612. -
  191613. if (num_rx_qs > MAX_RX_QS) {
  191614. pr_err("num_rx_qs(=%d) greater than MAX_RX_QS(=%d)\n",
  191615. num_rx_qs, MAX_RX_QS);
  191616. @@ -661,10 +796,20 @@
  191617. priv = netdev_priv(dev);
  191618. priv->ndev = dev;
  191619. + priv->mode = mode;
  191620. + priv->poll_mode = poll_mode;
  191621. +
  191622. priv->num_tx_queues = num_tx_qs;
  191623. netif_set_real_num_rx_queues(dev, num_rx_qs);
  191624. priv->num_rx_queues = num_rx_qs;
  191625. - priv->num_grps = 0x0;
  191626. +
  191627. + err = gfar_alloc_tx_queues(priv);
  191628. + if (err)
  191629. + goto tx_alloc_failed;
  191630. +
  191631. + err = gfar_alloc_rx_queues(priv);
  191632. + if (err)
  191633. + goto rx_alloc_failed;
  191634. /* Init Rx queue filer rule set linked list */
  191635. INIT_LIST_HEAD(&priv->rx_list.list);
  191636. @@ -677,52 +822,18 @@
  191637. priv->gfargrp[i].regs = NULL;
  191638. /* Parse and initialize group specific information */
  191639. - if (of_device_is_compatible(np, "fsl,etsec2")) {
  191640. - priv->mode = MQ_MG_MODE;
  191641. + if (priv->mode == MQ_MG_MODE) {
  191642. for_each_child_of_node(np, child) {
  191643. err = gfar_parse_group(child, priv, model);
  191644. if (err)
  191645. goto err_grp_init;
  191646. }
  191647. - } else {
  191648. - priv->mode = SQ_SG_MODE;
  191649. + } else { /* SQ_SG_MODE */
  191650. err = gfar_parse_group(np, priv, model);
  191651. if (err)
  191652. goto err_grp_init;
  191653. }
  191654. - for (i = 0; i < priv->num_tx_queues; i++)
  191655. - priv->tx_queue[i] = NULL;
  191656. - for (i = 0; i < priv->num_rx_queues; i++)
  191657. - priv->rx_queue[i] = NULL;
  191658. -
  191659. - for (i = 0; i < priv->num_tx_queues; i++) {
  191660. - priv->tx_queue[i] = kzalloc(sizeof(struct gfar_priv_tx_q),
  191661. - GFP_KERNEL);
  191662. - if (!priv->tx_queue[i]) {
  191663. - err = -ENOMEM;
  191664. - goto tx_alloc_failed;
  191665. - }
  191666. - priv->tx_queue[i]->tx_skbuff = NULL;
  191667. - priv->tx_queue[i]->qindex = i;
  191668. - priv->tx_queue[i]->dev = dev;
  191669. - spin_lock_init(&(priv->tx_queue[i]->txlock));
  191670. - }
  191671. -
  191672. - for (i = 0; i < priv->num_rx_queues; i++) {
  191673. - priv->rx_queue[i] = kzalloc(sizeof(struct gfar_priv_rx_q),
  191674. - GFP_KERNEL);
  191675. - if (!priv->rx_queue[i]) {
  191676. - err = -ENOMEM;
  191677. - goto rx_alloc_failed;
  191678. - }
  191679. - priv->rx_queue[i]->rx_skbuff = NULL;
  191680. - priv->rx_queue[i]->qindex = i;
  191681. - priv->rx_queue[i]->dev = dev;
  191682. - spin_lock_init(&(priv->rx_queue[i]->rxlock));
  191683. - }
  191684. -
  191685. -
  191686. stash = of_get_property(np, "bd-stash", NULL);
  191687. if (stash) {
  191688. @@ -749,17 +860,16 @@
  191689. memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
  191690. if (model && !strcasecmp(model, "TSEC"))
  191691. - priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
  191692. + priv->device_flags |= FSL_GIANFAR_DEV_HAS_GIGABIT |
  191693. FSL_GIANFAR_DEV_HAS_COALESCE |
  191694. FSL_GIANFAR_DEV_HAS_RMON |
  191695. FSL_GIANFAR_DEV_HAS_MULTI_INTR;
  191696. if (model && !strcasecmp(model, "eTSEC"))
  191697. - priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
  191698. + priv->device_flags |= FSL_GIANFAR_DEV_HAS_GIGABIT |
  191699. FSL_GIANFAR_DEV_HAS_COALESCE |
  191700. FSL_GIANFAR_DEV_HAS_RMON |
  191701. FSL_GIANFAR_DEV_HAS_MULTI_INTR |
  191702. - FSL_GIANFAR_DEV_HAS_PADDING |
  191703. FSL_GIANFAR_DEV_HAS_CSUM |
  191704. FSL_GIANFAR_DEV_HAS_VLAN |
  191705. FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
  191706. @@ -779,17 +889,28 @@
  191707. priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
  191708. + /* In the case of a fixed PHY, the DT node associated
  191709. + * to the PHY is the Ethernet MAC DT node.
  191710. + */
  191711. + if (of_phy_is_fixed_link(np)) {
  191712. + err = of_phy_register_fixed_link(np);
  191713. + if (err)
  191714. + goto err_grp_init;
  191715. +
  191716. + priv->phy_node = np;
  191717. + }
  191718. +
  191719. /* Find the TBI PHY. If it's not there, we don't support SGMII */
  191720. priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
  191721. return 0;
  191722. -rx_alloc_failed:
  191723. - free_rx_pointers(priv);
  191724. -tx_alloc_failed:
  191725. - free_tx_pointers(priv);
  191726. err_grp_init:
  191727. unmap_group_regs(priv);
  191728. +rx_alloc_failed:
  191729. + gfar_free_rx_queues(priv);
  191730. +tx_alloc_failed:
  191731. + gfar_free_tx_queues(priv);
  191732. free_gfar_dev(priv);
  191733. return err;
  191734. }
  191735. @@ -822,18 +943,16 @@
  191736. switch (config.rx_filter) {
  191737. case HWTSTAMP_FILTER_NONE:
  191738. if (priv->hwts_rx_en) {
  191739. - stop_gfar(netdev);
  191740. priv->hwts_rx_en = 0;
  191741. - startup_gfar(netdev);
  191742. + reset_gfar(netdev);
  191743. }
  191744. break;
  191745. default:
  191746. if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER))
  191747. return -ERANGE;
  191748. if (!priv->hwts_rx_en) {
  191749. - stop_gfar(netdev);
  191750. priv->hwts_rx_en = 1;
  191751. - startup_gfar(netdev);
  191752. + reset_gfar(netdev);
  191753. }
  191754. config.rx_filter = HWTSTAMP_FILTER_ALL;
  191755. break;
  191756. @@ -875,19 +994,6 @@
  191757. return phy_mii_ioctl(priv->phydev, rq, cmd);
  191758. }
  191759. -static unsigned int reverse_bitmap(unsigned int bit_map, unsigned int max_qs)
  191760. -{
  191761. - unsigned int new_bit_map = 0x0;
  191762. - int mask = 0x1 << (max_qs - 1), i;
  191763. -
  191764. - for (i = 0; i < max_qs; i++) {
  191765. - if (bit_map & mask)
  191766. - new_bit_map = new_bit_map + (1 << i);
  191767. - mask = mask >> 0x1;
  191768. - }
  191769. - return new_bit_map;
  191770. -}
  191771. -
  191772. static u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar,
  191773. u32 class)
  191774. {
  191775. @@ -1005,100 +1111,141 @@
  191776. priv->errata);
  191777. }
  191778. -/* Set up the ethernet device structure, private data,
  191779. - * and anything else we need before we start
  191780. - */
  191781. -static int gfar_probe(struct platform_device *ofdev)
  191782. +void gfar_mac_reset(struct gfar_private *priv)
  191783. {
  191784. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191785. u32 tempval;
  191786. - struct net_device *dev = NULL;
  191787. - struct gfar_private *priv = NULL;
  191788. - struct gfar __iomem *regs = NULL;
  191789. - int err = 0, i, grp_idx = 0;
  191790. - u32 rstat = 0, tstat = 0, rqueue = 0, tqueue = 0;
  191791. - u32 isrg = 0;
  191792. - u32 __iomem *baddr;
  191793. -
  191794. - err = gfar_of_init(ofdev, &dev);
  191795. -
  191796. - if (err)
  191797. - return err;
  191798. -
  191799. - priv = netdev_priv(dev);
  191800. - priv->ndev = dev;
  191801. - priv->ofdev = ofdev;
  191802. - priv->dev = &ofdev->dev;
  191803. - SET_NETDEV_DEV(dev, &ofdev->dev);
  191804. -
  191805. - spin_lock_init(&priv->bflock);
  191806. - INIT_WORK(&priv->reset_task, gfar_reset_task);
  191807. -
  191808. - platform_set_drvdata(ofdev, priv);
  191809. - regs = priv->gfargrp[0].regs;
  191810. -
  191811. - gfar_detect_errata(priv);
  191812. -
  191813. - /* Stop the DMA engine now, in case it was running before
  191814. - * (The firmware could have used it, and left it running).
  191815. - */
  191816. - gfar_halt(dev);
  191817. /* Reset MAC layer */
  191818. gfar_write(&regs->maccfg1, MACCFG1_SOFT_RESET);
  191819. /* We need to delay at least 3 TX clocks */
  191820. - udelay(2);
  191821. + udelay(3);
  191822. - tempval = 0;
  191823. - if (!priv->pause_aneg_en && priv->tx_pause_en)
  191824. - tempval |= MACCFG1_TX_FLOW;
  191825. - if (!priv->pause_aneg_en && priv->rx_pause_en)
  191826. - tempval |= MACCFG1_RX_FLOW;
  191827. /* the soft reset bit is not self-resetting, so we need to
  191828. * clear it before resuming normal operation
  191829. */
  191830. - gfar_write(&regs->maccfg1, tempval);
  191831. + gfar_write(&regs->maccfg1, 0);
  191832. - /* Initialize MACCFG2. */
  191833. - tempval = MACCFG2_INIT_SETTINGS;
  191834. - if (gfar_has_errata(priv, GFAR_ERRATA_74))
  191835. - tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK;
  191836. - gfar_write(&regs->maccfg2, tempval);
  191837. + udelay(3);
  191838. - /* Initialize ECNTRL */
  191839. - gfar_write(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
  191840. + /* Compute rx_buff_size based on config flags */
  191841. + gfar_rx_buff_size_config(priv);
  191842. - /* Set the dev->base_addr to the gfar reg region */
  191843. - dev->base_addr = (unsigned long) regs;
  191844. + /* Initialize the max receive frame/buffer lengths */
  191845. + gfar_write(&regs->maxfrm, priv->rx_buffer_size);
  191846. + gfar_write(&regs->mrblr, priv->rx_buffer_size);
  191847. - /* Fill in the dev structure */
  191848. - dev->watchdog_timeo = TX_TIMEOUT;
  191849. - dev->mtu = 1500;
  191850. - dev->netdev_ops = &gfar_netdev_ops;
  191851. - dev->ethtool_ops = &gfar_ethtool_ops;
  191852. + /* Initialize the Minimum Frame Length Register */
  191853. + gfar_write(&regs->minflr, MINFLR_INIT_SETTINGS);
  191854. - /* Register for napi ...We are registering NAPI for each grp */
  191855. - if (priv->mode == SQ_SG_MODE)
  191856. - netif_napi_add(dev, &priv->gfargrp[0].napi, gfar_poll_sq,
  191857. - GFAR_DEV_WEIGHT);
  191858. - else
  191859. - for (i = 0; i < priv->num_grps; i++)
  191860. - netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll,
  191861. - GFAR_DEV_WEIGHT);
  191862. + /* Initialize MACCFG2. */
  191863. + tempval = MACCFG2_INIT_SETTINGS;
  191864. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
  191865. - dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
  191866. - NETIF_F_RXCSUM;
  191867. - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
  191868. - NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
  191869. - }
  191870. + /* If the mtu is larger than the max size for standard
  191871. + * ethernet frames (ie, a jumbo frame), then set maccfg2
  191872. + * to allow huge frames, and to check the length
  191873. + */
  191874. + if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE ||
  191875. + gfar_has_errata(priv, GFAR_ERRATA_74))
  191876. + tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK;
  191877. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
  191878. - dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
  191879. - NETIF_F_HW_VLAN_CTAG_RX;
  191880. - dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
  191881. + gfar_write(&regs->maccfg2, tempval);
  191882. +
  191883. + /* Clear mac addr hash registers */
  191884. + gfar_write(&regs->igaddr0, 0);
  191885. + gfar_write(&regs->igaddr1, 0);
  191886. + gfar_write(&regs->igaddr2, 0);
  191887. + gfar_write(&regs->igaddr3, 0);
  191888. + gfar_write(&regs->igaddr4, 0);
  191889. + gfar_write(&regs->igaddr5, 0);
  191890. + gfar_write(&regs->igaddr6, 0);
  191891. + gfar_write(&regs->igaddr7, 0);
  191892. +
  191893. + gfar_write(&regs->gaddr0, 0);
  191894. + gfar_write(&regs->gaddr1, 0);
  191895. + gfar_write(&regs->gaddr2, 0);
  191896. + gfar_write(&regs->gaddr3, 0);
  191897. + gfar_write(&regs->gaddr4, 0);
  191898. + gfar_write(&regs->gaddr5, 0);
  191899. + gfar_write(&regs->gaddr6, 0);
  191900. + gfar_write(&regs->gaddr7, 0);
  191901. +
  191902. + if (priv->extended_hash)
  191903. + gfar_clear_exact_match(priv->ndev);
  191904. +
  191905. + gfar_mac_rx_config(priv);
  191906. +
  191907. + gfar_mac_tx_config(priv);
  191908. +
  191909. + gfar_set_mac_address(priv->ndev);
  191910. +
  191911. + gfar_set_multi(priv->ndev);
  191912. +
  191913. + /* clear ievent and imask before configuring coalescing */
  191914. + gfar_ints_disable(priv);
  191915. +
  191916. + /* Configure the coalescing support */
  191917. + gfar_configure_coalescing_all(priv);
  191918. +}
  191919. +
  191920. +static void gfar_hw_init(struct gfar_private *priv)
  191921. +{
  191922. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191923. + u32 attrs;
  191924. +
  191925. + /* Stop the DMA engine now, in case it was running before
  191926. + * (The firmware could have used it, and left it running).
  191927. + */
  191928. + gfar_halt(priv);
  191929. +
  191930. + gfar_mac_reset(priv);
  191931. +
  191932. + /* Zero out the rmon mib registers if it has them */
  191933. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
  191934. + memset_io(&(regs->rmon), 0, sizeof(struct rmon_mib));
  191935. +
  191936. + /* Mask off the CAM interrupts */
  191937. + gfar_write(&regs->rmon.cam1, 0xffffffff);
  191938. + gfar_write(&regs->rmon.cam2, 0xffffffff);
  191939. }
  191940. + /* Initialize ECNTRL */
  191941. + gfar_write(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
  191942. +
  191943. + /* Set the extraction length and index */
  191944. + attrs = ATTRELI_EL(priv->rx_stash_size) |
  191945. + ATTRELI_EI(priv->rx_stash_index);
  191946. +
  191947. + gfar_write(&regs->attreli, attrs);
  191948. +
  191949. + /* Start with defaults, and add stashing
  191950. + * depending on driver parameters
  191951. + */
  191952. + attrs = ATTR_INIT_SETTINGS;
  191953. +
  191954. + if (priv->bd_stash_en)
  191955. + attrs |= ATTR_BDSTASH;
  191956. +
  191957. + if (priv->rx_stash_size != 0)
  191958. + attrs |= ATTR_BUFSTASH;
  191959. +
  191960. + gfar_write(&regs->attr, attrs);
  191961. +
  191962. + /* FIFO configs */
  191963. + gfar_write(&regs->fifo_tx_thr, DEFAULT_FIFO_TX_THR);
  191964. + gfar_write(&regs->fifo_tx_starve, DEFAULT_FIFO_TX_STARVE);
  191965. + gfar_write(&regs->fifo_tx_starve_shutoff, DEFAULT_FIFO_TX_STARVE_OFF);
  191966. +
  191967. + /* Program the interrupt steering regs, only for MG devices */
  191968. + if (priv->num_grps > 1)
  191969. + gfar_write_isrg(priv);
  191970. +}
  191971. +
  191972. +static void gfar_init_addr_hash_table(struct gfar_private *priv)
  191973. +{
  191974. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  191975. +
  191976. if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
  191977. priv->extended_hash = 1;
  191978. priv->hash_width = 9;
  191979. @@ -1133,68 +1280,81 @@
  191980. priv->hash_regs[6] = &regs->gaddr6;
  191981. priv->hash_regs[7] = &regs->gaddr7;
  191982. }
  191983. +}
  191984. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_PADDING)
  191985. - priv->padding = DEFAULT_PADDING;
  191986. - else
  191987. - priv->padding = 0;
  191988. +/* Set up the ethernet device structure, private data,
  191989. + * and anything else we need before we start
  191990. + */
  191991. +static int gfar_probe(struct platform_device *ofdev)
  191992. +{
  191993. + struct net_device *dev = NULL;
  191994. + struct gfar_private *priv = NULL;
  191995. + int err = 0, i;
  191996. - if (dev->features & NETIF_F_IP_CSUM ||
  191997. - priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
  191998. - dev->needed_headroom = GMAC_FCB_LEN;
  191999. + err = gfar_of_init(ofdev, &dev);
  192000. - /* Program the isrg regs only if number of grps > 1 */
  192001. - if (priv->num_grps > 1) {
  192002. - baddr = &regs->isrg0;
  192003. - for (i = 0; i < priv->num_grps; i++) {
  192004. - isrg |= (priv->gfargrp[i].rx_bit_map << ISRG_SHIFT_RX);
  192005. - isrg |= (priv->gfargrp[i].tx_bit_map << ISRG_SHIFT_TX);
  192006. - gfar_write(baddr, isrg);
  192007. - baddr++;
  192008. - isrg = 0x0;
  192009. + if (err)
  192010. + return err;
  192011. +
  192012. + priv = netdev_priv(dev);
  192013. + priv->ndev = dev;
  192014. + priv->ofdev = ofdev;
  192015. + priv->dev = &ofdev->dev;
  192016. + SET_NETDEV_DEV(dev, &ofdev->dev);
  192017. +
  192018. + spin_lock_init(&priv->bflock);
  192019. + INIT_WORK(&priv->reset_task, gfar_reset_task);
  192020. +
  192021. + platform_set_drvdata(ofdev, priv);
  192022. +
  192023. + gfar_detect_errata(priv);
  192024. +
  192025. + /* Set the dev->base_addr to the gfar reg region */
  192026. + dev->base_addr = (unsigned long) priv->gfargrp[0].regs;
  192027. +
  192028. + /* Fill in the dev structure */
  192029. + dev->watchdog_timeo = TX_TIMEOUT;
  192030. + dev->mtu = 1500;
  192031. + dev->netdev_ops = &gfar_netdev_ops;
  192032. + dev->ethtool_ops = &gfar_ethtool_ops;
  192033. +
  192034. + /* Register for napi ...We are registering NAPI for each grp */
  192035. + for (i = 0; i < priv->num_grps; i++) {
  192036. + if (priv->poll_mode == GFAR_SQ_POLLING) {
  192037. + netif_napi_add(dev, &priv->gfargrp[i].napi_rx,
  192038. + gfar_poll_rx_sq, GFAR_DEV_WEIGHT);
  192039. + netif_napi_add(dev, &priv->gfargrp[i].napi_tx,
  192040. + gfar_poll_tx_sq, 2);
  192041. + } else {
  192042. + netif_napi_add(dev, &priv->gfargrp[i].napi_rx,
  192043. + gfar_poll_rx, GFAR_DEV_WEIGHT);
  192044. + netif_napi_add(dev, &priv->gfargrp[i].napi_tx,
  192045. + gfar_poll_tx, 2);
  192046. }
  192047. }
  192048. - /* Need to reverse the bit maps as bit_map's MSB is q0
  192049. - * but, for_each_set_bit parses from right to left, which
  192050. - * basically reverses the queue numbers
  192051. - */
  192052. - for (i = 0; i< priv->num_grps; i++) {
  192053. - priv->gfargrp[i].tx_bit_map =
  192054. - reverse_bitmap(priv->gfargrp[i].tx_bit_map, MAX_TX_QS);
  192055. - priv->gfargrp[i].rx_bit_map =
  192056. - reverse_bitmap(priv->gfargrp[i].rx_bit_map, MAX_RX_QS);
  192057. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
  192058. + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
  192059. + NETIF_F_RXCSUM;
  192060. + dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
  192061. + NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
  192062. }
  192063. - /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values,
  192064. - * also assign queues to groups
  192065. - */
  192066. - for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
  192067. - priv->gfargrp[grp_idx].num_rx_queues = 0x0;
  192068. -
  192069. - for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
  192070. - priv->num_rx_queues) {
  192071. - priv->gfargrp[grp_idx].num_rx_queues++;
  192072. - priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx];
  192073. - rstat = rstat | (RSTAT_CLEAR_RHALT >> i);
  192074. - rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
  192075. - }
  192076. - priv->gfargrp[grp_idx].num_tx_queues = 0x0;
  192077. -
  192078. - for_each_set_bit(i, &priv->gfargrp[grp_idx].tx_bit_map,
  192079. - priv->num_tx_queues) {
  192080. - priv->gfargrp[grp_idx].num_tx_queues++;
  192081. - priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx];
  192082. - tstat = tstat | (TSTAT_CLEAR_THALT >> i);
  192083. - tqueue = tqueue | (TQUEUE_EN0 >> i);
  192084. - }
  192085. - priv->gfargrp[grp_idx].rstat = rstat;
  192086. - priv->gfargrp[grp_idx].tstat = tstat;
  192087. - rstat = tstat =0;
  192088. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
  192089. + dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
  192090. + NETIF_F_HW_VLAN_CTAG_RX;
  192091. + dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
  192092. }
  192093. - gfar_write(&regs->rqueue, rqueue);
  192094. - gfar_write(&regs->tqueue, tqueue);
  192095. + gfar_init_addr_hash_table(priv);
  192096. +
  192097. + /* Insert receive time stamps into padding alignment bytes */
  192098. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
  192099. + priv->padding = 8;
  192100. +
  192101. + if (dev->features & NETIF_F_IP_CSUM ||
  192102. + priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
  192103. + dev->needed_headroom = GMAC_FCB_LEN;
  192104. priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE;
  192105. @@ -1220,6 +1380,10 @@
  192106. if (priv->num_tx_queues == 1)
  192107. priv->prio_sched_en = 1;
  192108. + set_bit(GFAR_DOWN, &priv->state);
  192109. +
  192110. + gfar_hw_init(priv);
  192111. +
  192112. /* Carrier starts down, phylib will bring it up */
  192113. netif_carrier_off(dev);
  192114. @@ -1251,9 +1415,6 @@
  192115. /* Initialize the filer table */
  192116. gfar_init_filer_table(priv);
  192117. - /* Create all the sysfs files */
  192118. - gfar_init_sysfs(dev);
  192119. -
  192120. /* Print out the device info */
  192121. netdev_info(dev, "mac: %pM\n", dev->dev_addr);
  192122. @@ -1272,8 +1433,8 @@
  192123. register_fail:
  192124. unmap_group_regs(priv);
  192125. - free_tx_pointers(priv);
  192126. - free_rx_pointers(priv);
  192127. + gfar_free_rx_queues(priv);
  192128. + gfar_free_tx_queues(priv);
  192129. if (priv->phy_node)
  192130. of_node_put(priv->phy_node);
  192131. if (priv->tbi_node)
  192132. @@ -1293,6 +1454,8 @@
  192133. unregister_netdev(priv->ndev);
  192134. unmap_group_regs(priv);
  192135. + gfar_free_rx_queues(priv);
  192136. + gfar_free_tx_queues(priv);
  192137. free_gfar_dev(priv);
  192138. return 0;
  192139. @@ -1318,9 +1481,8 @@
  192140. local_irq_save(flags);
  192141. lock_tx_qs(priv);
  192142. - lock_rx_qs(priv);
  192143. - gfar_halt_nodisable(ndev);
  192144. + gfar_halt_nodisable(priv);
  192145. /* Disable Tx, and Rx if wake-on-LAN is disabled. */
  192146. tempval = gfar_read(&regs->maccfg1);
  192147. @@ -1332,7 +1494,6 @@
  192148. gfar_write(&regs->maccfg1, tempval);
  192149. - unlock_rx_qs(priv);
  192150. unlock_tx_qs(priv);
  192151. local_irq_restore(flags);
  192152. @@ -1378,15 +1539,13 @@
  192153. */
  192154. local_irq_save(flags);
  192155. lock_tx_qs(priv);
  192156. - lock_rx_qs(priv);
  192157. tempval = gfar_read(&regs->maccfg2);
  192158. tempval &= ~MACCFG2_MPEN;
  192159. gfar_write(&regs->maccfg2, tempval);
  192160. - gfar_start(ndev);
  192161. + gfar_start(priv);
  192162. - unlock_rx_qs(priv);
  192163. unlock_tx_qs(priv);
  192164. local_irq_restore(flags);
  192165. @@ -1413,10 +1572,11 @@
  192166. return -ENOMEM;
  192167. }
  192168. - init_registers(ndev);
  192169. - gfar_set_mac_address(ndev);
  192170. - gfar_init_mac(ndev);
  192171. - gfar_start(ndev);
  192172. + gfar_mac_reset(priv);
  192173. +
  192174. + gfar_init_tx_rx_base(priv);
  192175. +
  192176. + gfar_start(priv);
  192177. priv->oldlink = 0;
  192178. priv->oldspeed = 0;
  192179. @@ -1511,9 +1671,6 @@
  192180. priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0,
  192181. interface);
  192182. - if (!priv->phydev)
  192183. - priv->phydev = of_phy_connect_fixed_link(dev, &adjust_link,
  192184. - interface);
  192185. if (!priv->phydev) {
  192186. dev_err(&dev->dev, "could not attach to PHY\n");
  192187. return -ENODEV;
  192188. @@ -1574,57 +1731,6 @@
  192189. BMCR_SPEED1000);
  192190. }
  192191. -static void init_registers(struct net_device *dev)
  192192. -{
  192193. - struct gfar_private *priv = netdev_priv(dev);
  192194. - struct gfar __iomem *regs = NULL;
  192195. - int i;
  192196. -
  192197. - for (i = 0; i < priv->num_grps; i++) {
  192198. - regs = priv->gfargrp[i].regs;
  192199. - /* Clear IEVENT */
  192200. - gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
  192201. -
  192202. - /* Initialize IMASK */
  192203. - gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  192204. - }
  192205. -
  192206. - regs = priv->gfargrp[0].regs;
  192207. - /* Init hash registers to zero */
  192208. - gfar_write(&regs->igaddr0, 0);
  192209. - gfar_write(&regs->igaddr1, 0);
  192210. - gfar_write(&regs->igaddr2, 0);
  192211. - gfar_write(&regs->igaddr3, 0);
  192212. - gfar_write(&regs->igaddr4, 0);
  192213. - gfar_write(&regs->igaddr5, 0);
  192214. - gfar_write(&regs->igaddr6, 0);
  192215. - gfar_write(&regs->igaddr7, 0);
  192216. -
  192217. - gfar_write(&regs->gaddr0, 0);
  192218. - gfar_write(&regs->gaddr1, 0);
  192219. - gfar_write(&regs->gaddr2, 0);
  192220. - gfar_write(&regs->gaddr3, 0);
  192221. - gfar_write(&regs->gaddr4, 0);
  192222. - gfar_write(&regs->gaddr5, 0);
  192223. - gfar_write(&regs->gaddr6, 0);
  192224. - gfar_write(&regs->gaddr7, 0);
  192225. -
  192226. - /* Zero out the rmon mib registers if it has them */
  192227. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
  192228. - memset_io(&(regs->rmon), 0, sizeof (struct rmon_mib));
  192229. -
  192230. - /* Mask off the CAM interrupts */
  192231. - gfar_write(&regs->rmon.cam1, 0xffffffff);
  192232. - gfar_write(&regs->rmon.cam2, 0xffffffff);
  192233. - }
  192234. -
  192235. - /* Initialize the max receive buffer length */
  192236. - gfar_write(&regs->mrblr, priv->rx_buffer_size);
  192237. -
  192238. - /* Initialize the Minimum Frame Length Register */
  192239. - gfar_write(&regs->minflr, MINFLR_INIT_SETTINGS);
  192240. -}
  192241. -
  192242. static int __gfar_is_rx_idle(struct gfar_private *priv)
  192243. {
  192244. u32 res;
  192245. @@ -1648,23 +1754,13 @@
  192246. }
  192247. /* Halt the receive and transmit queues */
  192248. -static void gfar_halt_nodisable(struct net_device *dev)
  192249. +static void gfar_halt_nodisable(struct gfar_private *priv)
  192250. {
  192251. - struct gfar_private *priv = netdev_priv(dev);
  192252. - struct gfar __iomem *regs = NULL;
  192253. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  192254. u32 tempval;
  192255. - int i;
  192256. -
  192257. - for (i = 0; i < priv->num_grps; i++) {
  192258. - regs = priv->gfargrp[i].regs;
  192259. - /* Mask all interrupts */
  192260. - gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  192261. - /* Clear all interrupts */
  192262. - gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
  192263. - }
  192264. + gfar_ints_disable(priv);
  192265. - regs = priv->gfargrp[0].regs;
  192266. /* Stop the DMA, and wait for it to stop */
  192267. tempval = gfar_read(&regs->dmactrl);
  192268. if ((tempval & (DMACTRL_GRS | DMACTRL_GTS)) !=
  192269. @@ -1685,56 +1781,41 @@
  192270. }
  192271. /* Halt the receive and transmit queues */
  192272. -void gfar_halt(struct net_device *dev)
  192273. +void gfar_halt(struct gfar_private *priv)
  192274. {
  192275. - struct gfar_private *priv = netdev_priv(dev);
  192276. struct gfar __iomem *regs = priv->gfargrp[0].regs;
  192277. u32 tempval;
  192278. - gfar_halt_nodisable(dev);
  192279. + /* Dissable the Rx/Tx hw queues */
  192280. + gfar_write(&regs->rqueue, 0);
  192281. + gfar_write(&regs->tqueue, 0);
  192282. - /* Disable Rx and Tx */
  192283. + mdelay(10);
  192284. +
  192285. + gfar_halt_nodisable(priv);
  192286. +
  192287. + /* Disable Rx/Tx DMA */
  192288. tempval = gfar_read(&regs->maccfg1);
  192289. tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
  192290. gfar_write(&regs->maccfg1, tempval);
  192291. }
  192292. -static void free_grp_irqs(struct gfar_priv_grp *grp)
  192293. -{
  192294. - free_irq(gfar_irq(grp, TX)->irq, grp);
  192295. - free_irq(gfar_irq(grp, RX)->irq, grp);
  192296. - free_irq(gfar_irq(grp, ER)->irq, grp);
  192297. -}
  192298. -
  192299. void stop_gfar(struct net_device *dev)
  192300. {
  192301. struct gfar_private *priv = netdev_priv(dev);
  192302. - unsigned long flags;
  192303. - int i;
  192304. -
  192305. - phy_stop(priv->phydev);
  192306. + netif_tx_stop_all_queues(dev);
  192307. - /* Lock it down */
  192308. - local_irq_save(flags);
  192309. - lock_tx_qs(priv);
  192310. - lock_rx_qs(priv);
  192311. + smp_mb__before_clear_bit();
  192312. + set_bit(GFAR_DOWN, &priv->state);
  192313. + smp_mb__after_clear_bit();
  192314. - gfar_halt(dev);
  192315. + disable_napi(priv);
  192316. - unlock_rx_qs(priv);
  192317. - unlock_tx_qs(priv);
  192318. - local_irq_restore(flags);
  192319. + /* disable ints and gracefully shut down Rx/Tx DMA */
  192320. + gfar_halt(priv);
  192321. - /* Free the IRQs */
  192322. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
  192323. - for (i = 0; i < priv->num_grps; i++)
  192324. - free_grp_irqs(&priv->gfargrp[i]);
  192325. - } else {
  192326. - for (i = 0; i < priv->num_grps; i++)
  192327. - free_irq(gfar_irq(&priv->gfargrp[i], TX)->irq,
  192328. - &priv->gfargrp[i]);
  192329. - }
  192330. + phy_stop(priv->phydev);
  192331. free_skb_resources(priv);
  192332. }
  192333. @@ -1825,17 +1906,15 @@
  192334. priv->tx_queue[0]->tx_bd_dma_base);
  192335. }
  192336. -void gfar_start(struct net_device *dev)
  192337. +void gfar_start(struct gfar_private *priv)
  192338. {
  192339. - struct gfar_private *priv = netdev_priv(dev);
  192340. struct gfar __iomem *regs = priv->gfargrp[0].regs;
  192341. u32 tempval;
  192342. int i = 0;
  192343. - /* Enable Rx and Tx in MACCFG1 */
  192344. - tempval = gfar_read(&regs->maccfg1);
  192345. - tempval |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
  192346. - gfar_write(&regs->maccfg1, tempval);
  192347. + /* Enable Rx/Tx hw queues */
  192348. + gfar_write(&regs->rqueue, priv->rqueue);
  192349. + gfar_write(&regs->tqueue, priv->tqueue);
  192350. /* Initialize DMACTRL to have WWR and WOP */
  192351. tempval = gfar_read(&regs->dmactrl);
  192352. @@ -1852,52 +1931,23 @@
  192353. /* Clear THLT/RHLT, so that the DMA starts polling now */
  192354. gfar_write(&regs->tstat, priv->gfargrp[i].tstat);
  192355. gfar_write(&regs->rstat, priv->gfargrp[i].rstat);
  192356. - /* Unmask the interrupts we look for */
  192357. - gfar_write(&regs->imask, IMASK_DEFAULT);
  192358. }
  192359. - dev->trans_start = jiffies; /* prevent tx timeout */
  192360. -}
  192361. -
  192362. -static void gfar_configure_coalescing(struct gfar_private *priv,
  192363. - unsigned long tx_mask, unsigned long rx_mask)
  192364. -{
  192365. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  192366. - u32 __iomem *baddr;
  192367. + /* Enable Rx/Tx DMA */
  192368. + tempval = gfar_read(&regs->maccfg1);
  192369. + tempval |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
  192370. + gfar_write(&regs->maccfg1, tempval);
  192371. - if (priv->mode == MQ_MG_MODE) {
  192372. - int i = 0;
  192373. + gfar_ints_enable(priv);
  192374. - baddr = &regs->txic0;
  192375. - for_each_set_bit(i, &tx_mask, priv->num_tx_queues) {
  192376. - gfar_write(baddr + i, 0);
  192377. - if (likely(priv->tx_queue[i]->txcoalescing))
  192378. - gfar_write(baddr + i, priv->tx_queue[i]->txic);
  192379. - }
  192380. -
  192381. - baddr = &regs->rxic0;
  192382. - for_each_set_bit(i, &rx_mask, priv->num_rx_queues) {
  192383. - gfar_write(baddr + i, 0);
  192384. - if (likely(priv->rx_queue[i]->rxcoalescing))
  192385. - gfar_write(baddr + i, priv->rx_queue[i]->rxic);
  192386. - }
  192387. - } else {
  192388. - /* Backward compatible case -- even if we enable
  192389. - * multiple queues, there's only single reg to program
  192390. - */
  192391. - gfar_write(&regs->txic, 0);
  192392. - if (likely(priv->tx_queue[0]->txcoalescing))
  192393. - gfar_write(&regs->txic, priv->tx_queue[0]->txic);
  192394. -
  192395. - gfar_write(&regs->rxic, 0);
  192396. - if (unlikely(priv->rx_queue[0]->rxcoalescing))
  192397. - gfar_write(&regs->rxic, priv->rx_queue[0]->rxic);
  192398. - }
  192399. + priv->ndev->trans_start = jiffies; /* prevent tx timeout */
  192400. }
  192401. -void gfar_configure_coalescing_all(struct gfar_private *priv)
  192402. +static void free_grp_irqs(struct gfar_priv_grp *grp)
  192403. {
  192404. - gfar_configure_coalescing(priv, 0xFF, 0xFF);
  192405. + free_irq(gfar_irq(grp, TX)->irq, grp);
  192406. + free_irq(gfar_irq(grp, RX)->irq, grp);
  192407. + free_irq(gfar_irq(grp, ER)->irq, grp);
  192408. }
  192409. static int register_grp_irqs(struct gfar_priv_grp *grp)
  192410. @@ -1956,46 +2006,65 @@
  192411. }
  192412. -/* Bring the controller up and running */
  192413. -int startup_gfar(struct net_device *ndev)
  192414. +static void gfar_free_irq(struct gfar_private *priv)
  192415. {
  192416. - struct gfar_private *priv = netdev_priv(ndev);
  192417. - struct gfar __iomem *regs = NULL;
  192418. - int err, i, j;
  192419. + int i;
  192420. - for (i = 0; i < priv->num_grps; i++) {
  192421. - regs= priv->gfargrp[i].regs;
  192422. - gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  192423. + /* Free the IRQs */
  192424. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
  192425. + for (i = 0; i < priv->num_grps; i++)
  192426. + free_grp_irqs(&priv->gfargrp[i]);
  192427. + } else {
  192428. + for (i = 0; i < priv->num_grps; i++)
  192429. + free_irq(gfar_irq(&priv->gfargrp[i], TX)->irq,
  192430. + &priv->gfargrp[i]);
  192431. }
  192432. +}
  192433. - regs= priv->gfargrp[0].regs;
  192434. - err = gfar_alloc_skb_resources(ndev);
  192435. - if (err)
  192436. - return err;
  192437. -
  192438. - gfar_init_mac(ndev);
  192439. +static int gfar_request_irq(struct gfar_private *priv)
  192440. +{
  192441. + int err, i, j;
  192442. for (i = 0; i < priv->num_grps; i++) {
  192443. err = register_grp_irqs(&priv->gfargrp[i]);
  192444. if (err) {
  192445. for (j = 0; j < i; j++)
  192446. free_grp_irqs(&priv->gfargrp[j]);
  192447. - goto irq_fail;
  192448. + return err;
  192449. }
  192450. }
  192451. - /* Start the controller */
  192452. - gfar_start(ndev);
  192453. + return 0;
  192454. +}
  192455. +
  192456. +/* Bring the controller up and running */
  192457. +int startup_gfar(struct net_device *ndev)
  192458. +{
  192459. + struct gfar_private *priv = netdev_priv(ndev);
  192460. + int err;
  192461. +
  192462. + gfar_mac_reset(priv);
  192463. +
  192464. + err = gfar_alloc_skb_resources(ndev);
  192465. + if (err)
  192466. + return err;
  192467. +
  192468. + gfar_init_tx_rx_base(priv);
  192469. +
  192470. + smp_mb__before_clear_bit();
  192471. + clear_bit(GFAR_DOWN, &priv->state);
  192472. + smp_mb__after_clear_bit();
  192473. +
  192474. + /* Start Rx/Tx DMA and enable the interrupts */
  192475. + gfar_start(priv);
  192476. phy_start(priv->phydev);
  192477. - gfar_configure_coalescing_all(priv);
  192478. + enable_napi(priv);
  192479. - return 0;
  192480. + netif_tx_wake_all_queues(ndev);
  192481. -irq_fail:
  192482. - free_skb_resources(priv);
  192483. - return err;
  192484. + return 0;
  192485. }
  192486. /* Called when something needs to use the ethernet device
  192487. @@ -2006,27 +2075,17 @@
  192488. struct gfar_private *priv = netdev_priv(dev);
  192489. int err;
  192490. - enable_napi(priv);
  192491. -
  192492. - /* Initialize a bunch of registers */
  192493. - init_registers(dev);
  192494. -
  192495. - gfar_set_mac_address(dev);
  192496. -
  192497. err = init_phy(dev);
  192498. + if (err)
  192499. + return err;
  192500. - if (err) {
  192501. - disable_napi(priv);
  192502. + err = gfar_request_irq(priv);
  192503. + if (err)
  192504. return err;
  192505. - }
  192506. err = startup_gfar(dev);
  192507. - if (err) {
  192508. - disable_napi(priv);
  192509. + if (err)
  192510. return err;
  192511. - }
  192512. -
  192513. - netif_tx_start_all_queues(dev);
  192514. device_set_wakeup_enable(&dev->dev, priv->wol_en);
  192515. @@ -2152,13 +2211,13 @@
  192516. skb_new = skb_realloc_headroom(skb, fcb_len);
  192517. if (!skb_new) {
  192518. dev->stats.tx_errors++;
  192519. - kfree_skb(skb);
  192520. + dev_kfree_skb_any(skb);
  192521. return NETDEV_TX_OK;
  192522. }
  192523. if (skb->sk)
  192524. skb_set_owner_w(skb_new, skb->sk);
  192525. - consume_skb(skb);
  192526. + dev_consume_skb_any(skb);
  192527. skb = skb_new;
  192528. }
  192529. @@ -2351,8 +2410,6 @@
  192530. {
  192531. struct gfar_private *priv = netdev_priv(dev);
  192532. - disable_napi(priv);
  192533. -
  192534. cancel_work_sync(&priv->reset_task);
  192535. stop_gfar(dev);
  192536. @@ -2360,7 +2417,7 @@
  192537. phy_disconnect(priv->phydev);
  192538. priv->phydev = NULL;
  192539. - netif_tx_stop_all_queues(dev);
  192540. + gfar_free_irq(priv);
  192541. return 0;
  192542. }
  192543. @@ -2373,77 +2430,9 @@
  192544. return 0;
  192545. }
  192546. -/* Check if rx parser should be activated */
  192547. -void gfar_check_rx_parser_mode(struct gfar_private *priv)
  192548. -{
  192549. - struct gfar __iomem *regs;
  192550. - u32 tempval;
  192551. -
  192552. - regs = priv->gfargrp[0].regs;
  192553. -
  192554. - tempval = gfar_read(&regs->rctrl);
  192555. - /* If parse is no longer required, then disable parser */
  192556. - if (tempval & RCTRL_REQ_PARSER) {
  192557. - tempval |= RCTRL_PRSDEP_INIT;
  192558. - priv->uses_rxfcb = 1;
  192559. - } else {
  192560. - tempval &= ~RCTRL_PRSDEP_INIT;
  192561. - priv->uses_rxfcb = 0;
  192562. - }
  192563. - gfar_write(&regs->rctrl, tempval);
  192564. -}
  192565. -
  192566. -/* Enables and disables VLAN insertion/extraction */
  192567. -void gfar_vlan_mode(struct net_device *dev, netdev_features_t features)
  192568. -{
  192569. - struct gfar_private *priv = netdev_priv(dev);
  192570. - struct gfar __iomem *regs = NULL;
  192571. - unsigned long flags;
  192572. - u32 tempval;
  192573. -
  192574. - regs = priv->gfargrp[0].regs;
  192575. - local_irq_save(flags);
  192576. - lock_rx_qs(priv);
  192577. -
  192578. - if (features & NETIF_F_HW_VLAN_CTAG_TX) {
  192579. - /* Enable VLAN tag insertion */
  192580. - tempval = gfar_read(&regs->tctrl);
  192581. - tempval |= TCTRL_VLINS;
  192582. - gfar_write(&regs->tctrl, tempval);
  192583. - } else {
  192584. - /* Disable VLAN tag insertion */
  192585. - tempval = gfar_read(&regs->tctrl);
  192586. - tempval &= ~TCTRL_VLINS;
  192587. - gfar_write(&regs->tctrl, tempval);
  192588. - }
  192589. -
  192590. - if (features & NETIF_F_HW_VLAN_CTAG_RX) {
  192591. - /* Enable VLAN tag extraction */
  192592. - tempval = gfar_read(&regs->rctrl);
  192593. - tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT);
  192594. - gfar_write(&regs->rctrl, tempval);
  192595. - priv->uses_rxfcb = 1;
  192596. - } else {
  192597. - /* Disable VLAN tag extraction */
  192598. - tempval = gfar_read(&regs->rctrl);
  192599. - tempval &= ~RCTRL_VLEX;
  192600. - gfar_write(&regs->rctrl, tempval);
  192601. -
  192602. - gfar_check_rx_parser_mode(priv);
  192603. - }
  192604. -
  192605. - gfar_change_mtu(dev, dev->mtu);
  192606. -
  192607. - unlock_rx_qs(priv);
  192608. - local_irq_restore(flags);
  192609. -}
  192610. -
  192611. static int gfar_change_mtu(struct net_device *dev, int new_mtu)
  192612. {
  192613. - int tempsize, tempval;
  192614. struct gfar_private *priv = netdev_priv(dev);
  192615. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  192616. - int oldsize = priv->rx_buffer_size;
  192617. int frame_size = new_mtu + ETH_HLEN;
  192618. if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) {
  192619. @@ -2451,45 +2440,33 @@
  192620. return -EINVAL;
  192621. }
  192622. - if (priv->uses_rxfcb)
  192623. - frame_size += GMAC_FCB_LEN;
  192624. -
  192625. - frame_size += priv->padding;
  192626. -
  192627. - tempsize = (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) +
  192628. - INCREMENTAL_BUFFER_SIZE;
  192629. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  192630. + cpu_relax();
  192631. - /* Only stop and start the controller if it isn't already
  192632. - * stopped, and we changed something
  192633. - */
  192634. - if ((oldsize != tempsize) && (dev->flags & IFF_UP))
  192635. + if (dev->flags & IFF_UP)
  192636. stop_gfar(dev);
  192637. - priv->rx_buffer_size = tempsize;
  192638. -
  192639. dev->mtu = new_mtu;
  192640. - gfar_write(&regs->mrblr, priv->rx_buffer_size);
  192641. - gfar_write(&regs->maxfrm, priv->rx_buffer_size);
  192642. + if (dev->flags & IFF_UP)
  192643. + startup_gfar(dev);
  192644. - /* If the mtu is larger than the max size for standard
  192645. - * ethernet frames (ie, a jumbo frame), then set maccfg2
  192646. - * to allow huge frames, and to check the length
  192647. - */
  192648. - tempval = gfar_read(&regs->maccfg2);
  192649. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  192650. - if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE ||
  192651. - gfar_has_errata(priv, GFAR_ERRATA_74))
  192652. - tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);
  192653. - else
  192654. - tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);
  192655. + return 0;
  192656. +}
  192657. - gfar_write(&regs->maccfg2, tempval);
  192658. +void reset_gfar(struct net_device *ndev)
  192659. +{
  192660. + struct gfar_private *priv = netdev_priv(ndev);
  192661. - if ((oldsize != tempsize) && (dev->flags & IFF_UP))
  192662. - startup_gfar(dev);
  192663. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  192664. + cpu_relax();
  192665. - return 0;
  192666. + stop_gfar(ndev);
  192667. + startup_gfar(ndev);
  192668. +
  192669. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  192670. }
  192671. /* gfar_reset_task gets scheduled when a packet has not been
  192672. @@ -2501,16 +2478,7 @@
  192673. {
  192674. struct gfar_private *priv = container_of(work, struct gfar_private,
  192675. reset_task);
  192676. - struct net_device *dev = priv->ndev;
  192677. -
  192678. - if (dev->flags & IFF_UP) {
  192679. - netif_tx_stop_all_queues(dev);
  192680. - stop_gfar(dev);
  192681. - startup_gfar(dev);
  192682. - netif_tx_start_all_queues(dev);
  192683. - }
  192684. -
  192685. - netif_tx_schedule_all(dev);
  192686. + reset_gfar(priv->ndev);
  192687. }
  192688. static void gfar_timeout(struct net_device *dev)
  192689. @@ -2623,8 +2591,10 @@
  192690. }
  192691. /* If we freed a buffer, we can restart transmission, if necessary */
  192692. - if (netif_tx_queue_stopped(txq) && tx_queue->num_txbdfree)
  192693. - netif_wake_subqueue(dev, tqi);
  192694. + if (tx_queue->num_txbdfree &&
  192695. + netif_tx_queue_stopped(txq) &&
  192696. + !(test_bit(GFAR_DOWN, &priv->state)))
  192697. + netif_wake_subqueue(priv->ndev, tqi);
  192698. /* Update dirty indicators */
  192699. tx_queue->skb_dirtytx = skb_dirtytx;
  192700. @@ -2633,31 +2603,6 @@
  192701. netdev_tx_completed_queue(txq, howmany, bytes_sent);
  192702. }
  192703. -static void gfar_schedule_cleanup(struct gfar_priv_grp *gfargrp)
  192704. -{
  192705. - unsigned long flags;
  192706. -
  192707. - spin_lock_irqsave(&gfargrp->grplock, flags);
  192708. - if (napi_schedule_prep(&gfargrp->napi)) {
  192709. - gfar_write(&gfargrp->regs->imask, IMASK_RTX_DISABLED);
  192710. - __napi_schedule(&gfargrp->napi);
  192711. - } else {
  192712. - /* Clear IEVENT, so interrupts aren't called again
  192713. - * because of the packets that have already arrived.
  192714. - */
  192715. - gfar_write(&gfargrp->regs->ievent, IEVENT_RTX_MASK);
  192716. - }
  192717. - spin_unlock_irqrestore(&gfargrp->grplock, flags);
  192718. -
  192719. -}
  192720. -
  192721. -/* Interrupt Handler for Transmit complete */
  192722. -static irqreturn_t gfar_transmit(int irq, void *grp_id)
  192723. -{
  192724. - gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id);
  192725. - return IRQ_HANDLED;
  192726. -}
  192727. -
  192728. static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp,
  192729. struct sk_buff *skb)
  192730. {
  192731. @@ -2728,7 +2673,48 @@
  192732. irqreturn_t gfar_receive(int irq, void *grp_id)
  192733. {
  192734. - gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id);
  192735. + struct gfar_priv_grp *grp = (struct gfar_priv_grp *)grp_id;
  192736. + unsigned long flags;
  192737. + u32 imask;
  192738. +
  192739. + if (likely(napi_schedule_prep(&grp->napi_rx))) {
  192740. + spin_lock_irqsave(&grp->grplock, flags);
  192741. + imask = gfar_read(&grp->regs->imask);
  192742. + imask &= IMASK_RX_DISABLED;
  192743. + gfar_write(&grp->regs->imask, imask);
  192744. + spin_unlock_irqrestore(&grp->grplock, flags);
  192745. + __napi_schedule(&grp->napi_rx);
  192746. + } else {
  192747. + /* Clear IEVENT, so interrupts aren't called again
  192748. + * because of the packets that have already arrived.
  192749. + */
  192750. + gfar_write(&grp->regs->ievent, IEVENT_RX_MASK);
  192751. + }
  192752. +
  192753. + return IRQ_HANDLED;
  192754. +}
  192755. +
  192756. +/* Interrupt Handler for Transmit complete */
  192757. +static irqreturn_t gfar_transmit(int irq, void *grp_id)
  192758. +{
  192759. + struct gfar_priv_grp *grp = (struct gfar_priv_grp *)grp_id;
  192760. + unsigned long flags;
  192761. + u32 imask;
  192762. +
  192763. + if (likely(napi_schedule_prep(&grp->napi_tx))) {
  192764. + spin_lock_irqsave(&grp->grplock, flags);
  192765. + imask = gfar_read(&grp->regs->imask);
  192766. + imask &= IMASK_TX_DISABLED;
  192767. + gfar_write(&grp->regs->imask, imask);
  192768. + spin_unlock_irqrestore(&grp->grplock, flags);
  192769. + __napi_schedule(&grp->napi_tx);
  192770. + } else {
  192771. + /* Clear IEVENT, so interrupts aren't called again
  192772. + * because of the packets that have already arrived.
  192773. + */
  192774. + gfar_write(&grp->regs->ievent, IEVENT_TX_MASK);
  192775. + }
  192776. +
  192777. return IRQ_HANDLED;
  192778. }
  192779. @@ -2852,7 +2838,7 @@
  192780. rx_queue->stats.rx_bytes += pkt_len;
  192781. skb_record_rx_queue(skb, rx_queue->qindex);
  192782. gfar_process_frame(dev, skb, amount_pull,
  192783. - &rx_queue->grp->napi);
  192784. + &rx_queue->grp->napi_rx);
  192785. } else {
  192786. netif_warn(priv, rx_err, dev, "Missing skb!\n");
  192787. @@ -2881,66 +2867,81 @@
  192788. return howmany;
  192789. }
  192790. -static int gfar_poll_sq(struct napi_struct *napi, int budget)
  192791. +static int gfar_poll_rx_sq(struct napi_struct *napi, int budget)
  192792. {
  192793. struct gfar_priv_grp *gfargrp =
  192794. - container_of(napi, struct gfar_priv_grp, napi);
  192795. + container_of(napi, struct gfar_priv_grp, napi_rx);
  192796. struct gfar __iomem *regs = gfargrp->regs;
  192797. - struct gfar_priv_tx_q *tx_queue = gfargrp->priv->tx_queue[0];
  192798. - struct gfar_priv_rx_q *rx_queue = gfargrp->priv->rx_queue[0];
  192799. + struct gfar_priv_rx_q *rx_queue = gfargrp->rx_queue;
  192800. int work_done = 0;
  192801. /* Clear IEVENT, so interrupts aren't called again
  192802. * because of the packets that have already arrived
  192803. */
  192804. - gfar_write(&regs->ievent, IEVENT_RTX_MASK);
  192805. -
  192806. - /* run Tx cleanup to completion */
  192807. - if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx])
  192808. - gfar_clean_tx_ring(tx_queue);
  192809. + gfar_write(&regs->ievent, IEVENT_RX_MASK);
  192810. work_done = gfar_clean_rx_ring(rx_queue, budget);
  192811. if (work_done < budget) {
  192812. + u32 imask;
  192813. napi_complete(napi);
  192814. /* Clear the halt bit in RSTAT */
  192815. gfar_write(&regs->rstat, gfargrp->rstat);
  192816. - gfar_write(&regs->imask, IMASK_DEFAULT);
  192817. -
  192818. - /* If we are coalescing interrupts, update the timer
  192819. - * Otherwise, clear it
  192820. - */
  192821. - gfar_write(&regs->txic, 0);
  192822. - if (likely(tx_queue->txcoalescing))
  192823. - gfar_write(&regs->txic, tx_queue->txic);
  192824. -
  192825. - gfar_write(&regs->rxic, 0);
  192826. - if (unlikely(rx_queue->rxcoalescing))
  192827. - gfar_write(&regs->rxic, rx_queue->rxic);
  192828. + spin_lock_irq(&gfargrp->grplock);
  192829. + imask = gfar_read(&regs->imask);
  192830. + imask |= IMASK_RX_DEFAULT;
  192831. + gfar_write(&regs->imask, imask);
  192832. + spin_unlock_irq(&gfargrp->grplock);
  192833. }
  192834. return work_done;
  192835. }
  192836. -static int gfar_poll(struct napi_struct *napi, int budget)
  192837. +static int gfar_poll_tx_sq(struct napi_struct *napi, int budget)
  192838. +{
  192839. + struct gfar_priv_grp *gfargrp =
  192840. + container_of(napi, struct gfar_priv_grp, napi_tx);
  192841. + struct gfar __iomem *regs = gfargrp->regs;
  192842. + struct gfar_priv_tx_q *tx_queue = gfargrp->tx_queue;
  192843. + u32 imask;
  192844. +
  192845. + /* Clear IEVENT, so interrupts aren't called again
  192846. + * because of the packets that have already arrived
  192847. + */
  192848. + gfar_write(&regs->ievent, IEVENT_TX_MASK);
  192849. +
  192850. + /* run Tx cleanup to completion */
  192851. + if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx])
  192852. + gfar_clean_tx_ring(tx_queue);
  192853. +
  192854. + napi_complete(napi);
  192855. +
  192856. + spin_lock_irq(&gfargrp->grplock);
  192857. + imask = gfar_read(&regs->imask);
  192858. + imask |= IMASK_TX_DEFAULT;
  192859. + gfar_write(&regs->imask, imask);
  192860. + spin_unlock_irq(&gfargrp->grplock);
  192861. +
  192862. + return 0;
  192863. +}
  192864. +
  192865. +static int gfar_poll_rx(struct napi_struct *napi, int budget)
  192866. {
  192867. struct gfar_priv_grp *gfargrp =
  192868. - container_of(napi, struct gfar_priv_grp, napi);
  192869. + container_of(napi, struct gfar_priv_grp, napi_rx);
  192870. struct gfar_private *priv = gfargrp->priv;
  192871. struct gfar __iomem *regs = gfargrp->regs;
  192872. - struct gfar_priv_tx_q *tx_queue = NULL;
  192873. struct gfar_priv_rx_q *rx_queue = NULL;
  192874. int work_done = 0, work_done_per_q = 0;
  192875. int i, budget_per_q = 0;
  192876. - int has_tx_work = 0;
  192877. unsigned long rstat_rxf;
  192878. int num_act_queues;
  192879. /* Clear IEVENT, so interrupts aren't called again
  192880. * because of the packets that have already arrived
  192881. */
  192882. - gfar_write(&regs->ievent, IEVENT_RTX_MASK);
  192883. + gfar_write(&regs->ievent, IEVENT_RX_MASK);
  192884. rstat_rxf = gfar_read(&regs->rstat) & RSTAT_RXF_MASK;
  192885. @@ -2948,15 +2949,6 @@
  192886. if (num_act_queues)
  192887. budget_per_q = budget/num_act_queues;
  192888. - for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) {
  192889. - tx_queue = priv->tx_queue[i];
  192890. - /* run Tx cleanup to completion */
  192891. - if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) {
  192892. - gfar_clean_tx_ring(tx_queue);
  192893. - has_tx_work = 1;
  192894. - }
  192895. - }
  192896. -
  192897. for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
  192898. /* skip queue if not active */
  192899. if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i)))
  192900. @@ -2979,25 +2971,62 @@
  192901. }
  192902. }
  192903. - if (!num_act_queues && !has_tx_work) {
  192904. -
  192905. + if (!num_act_queues) {
  192906. + u32 imask;
  192907. napi_complete(napi);
  192908. /* Clear the halt bit in RSTAT */
  192909. gfar_write(&regs->rstat, gfargrp->rstat);
  192910. - gfar_write(&regs->imask, IMASK_DEFAULT);
  192911. -
  192912. - /* If we are coalescing interrupts, update the timer
  192913. - * Otherwise, clear it
  192914. - */
  192915. - gfar_configure_coalescing(priv, gfargrp->rx_bit_map,
  192916. - gfargrp->tx_bit_map);
  192917. + spin_lock_irq(&gfargrp->grplock);
  192918. + imask = gfar_read(&regs->imask);
  192919. + imask |= IMASK_RX_DEFAULT;
  192920. + gfar_write(&regs->imask, imask);
  192921. + spin_unlock_irq(&gfargrp->grplock);
  192922. }
  192923. return work_done;
  192924. }
  192925. +static int gfar_poll_tx(struct napi_struct *napi, int budget)
  192926. +{
  192927. + struct gfar_priv_grp *gfargrp =
  192928. + container_of(napi, struct gfar_priv_grp, napi_tx);
  192929. + struct gfar_private *priv = gfargrp->priv;
  192930. + struct gfar __iomem *regs = gfargrp->regs;
  192931. + struct gfar_priv_tx_q *tx_queue = NULL;
  192932. + int has_tx_work = 0;
  192933. + int i;
  192934. +
  192935. + /* Clear IEVENT, so interrupts aren't called again
  192936. + * because of the packets that have already arrived
  192937. + */
  192938. + gfar_write(&regs->ievent, IEVENT_TX_MASK);
  192939. +
  192940. + for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) {
  192941. + tx_queue = priv->tx_queue[i];
  192942. + /* run Tx cleanup to completion */
  192943. + if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) {
  192944. + gfar_clean_tx_ring(tx_queue);
  192945. + has_tx_work = 1;
  192946. + }
  192947. + }
  192948. +
  192949. + if (!has_tx_work) {
  192950. + u32 imask;
  192951. + napi_complete(napi);
  192952. +
  192953. + spin_lock_irq(&gfargrp->grplock);
  192954. + imask = gfar_read(&regs->imask);
  192955. + imask |= IMASK_TX_DEFAULT;
  192956. + gfar_write(&regs->imask, imask);
  192957. + spin_unlock_irq(&gfargrp->grplock);
  192958. + }
  192959. +
  192960. + return 0;
  192961. +}
  192962. +
  192963. +
  192964. #ifdef CONFIG_NET_POLL_CONTROLLER
  192965. /* Polling 'interrupt' - used by things like netconsole to send skbs
  192966. * without having to re-enable interrupts. It's not called while
  192967. @@ -3056,41 +3085,6 @@
  192968. return IRQ_HANDLED;
  192969. }
  192970. -static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv)
  192971. -{
  192972. - struct phy_device *phydev = priv->phydev;
  192973. - u32 val = 0;
  192974. -
  192975. - if (!phydev->duplex)
  192976. - return val;
  192977. -
  192978. - if (!priv->pause_aneg_en) {
  192979. - if (priv->tx_pause_en)
  192980. - val |= MACCFG1_TX_FLOW;
  192981. - if (priv->rx_pause_en)
  192982. - val |= MACCFG1_RX_FLOW;
  192983. - } else {
  192984. - u16 lcl_adv, rmt_adv;
  192985. - u8 flowctrl;
  192986. - /* get link partner capabilities */
  192987. - rmt_adv = 0;
  192988. - if (phydev->pause)
  192989. - rmt_adv = LPA_PAUSE_CAP;
  192990. - if (phydev->asym_pause)
  192991. - rmt_adv |= LPA_PAUSE_ASYM;
  192992. -
  192993. - lcl_adv = mii_advertise_flowctrl(phydev->advertising);
  192994. -
  192995. - flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
  192996. - if (flowctrl & FLOW_CTRL_TX)
  192997. - val |= MACCFG1_TX_FLOW;
  192998. - if (flowctrl & FLOW_CTRL_RX)
  192999. - val |= MACCFG1_RX_FLOW;
  193000. - }
  193001. -
  193002. - return val;
  193003. -}
  193004. -
  193005. /* Called every time the controller might need to be made
  193006. * aware of new link state. The PHY code conveys this
  193007. * information through variables in the phydev structure, and this
  193008. @@ -3100,86 +3094,12 @@
  193009. static void adjust_link(struct net_device *dev)
  193010. {
  193011. struct gfar_private *priv = netdev_priv(dev);
  193012. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193013. - unsigned long flags;
  193014. struct phy_device *phydev = priv->phydev;
  193015. - int new_state = 0;
  193016. -
  193017. - local_irq_save(flags);
  193018. - lock_tx_qs(priv);
  193019. -
  193020. - if (phydev->link) {
  193021. - u32 tempval1 = gfar_read(&regs->maccfg1);
  193022. - u32 tempval = gfar_read(&regs->maccfg2);
  193023. - u32 ecntrl = gfar_read(&regs->ecntrl);
  193024. -
  193025. - /* Now we make sure that we can be in full duplex mode.
  193026. - * If not, we operate in half-duplex mode.
  193027. - */
  193028. - if (phydev->duplex != priv->oldduplex) {
  193029. - new_state = 1;
  193030. - if (!(phydev->duplex))
  193031. - tempval &= ~(MACCFG2_FULL_DUPLEX);
  193032. - else
  193033. - tempval |= MACCFG2_FULL_DUPLEX;
  193034. -
  193035. - priv->oldduplex = phydev->duplex;
  193036. - }
  193037. -
  193038. - if (phydev->speed != priv->oldspeed) {
  193039. - new_state = 1;
  193040. - switch (phydev->speed) {
  193041. - case 1000:
  193042. - tempval =
  193043. - ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII);
  193044. -
  193045. - ecntrl &= ~(ECNTRL_R100);
  193046. - break;
  193047. - case 100:
  193048. - case 10:
  193049. - tempval =
  193050. - ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
  193051. -
  193052. - /* Reduced mode distinguishes
  193053. - * between 10 and 100
  193054. - */
  193055. - if (phydev->speed == SPEED_100)
  193056. - ecntrl |= ECNTRL_R100;
  193057. - else
  193058. - ecntrl &= ~(ECNTRL_R100);
  193059. - break;
  193060. - default:
  193061. - netif_warn(priv, link, dev,
  193062. - "Ack! Speed (%d) is not 10/100/1000!\n",
  193063. - phydev->speed);
  193064. - break;
  193065. - }
  193066. -
  193067. - priv->oldspeed = phydev->speed;
  193068. - }
  193069. -
  193070. - tempval1 &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW);
  193071. - tempval1 |= gfar_get_flowctrl_cfg(priv);
  193072. -
  193073. - gfar_write(&regs->maccfg1, tempval1);
  193074. - gfar_write(&regs->maccfg2, tempval);
  193075. - gfar_write(&regs->ecntrl, ecntrl);
  193076. -
  193077. - if (!priv->oldlink) {
  193078. - new_state = 1;
  193079. - priv->oldlink = 1;
  193080. - }
  193081. - } else if (priv->oldlink) {
  193082. - new_state = 1;
  193083. - priv->oldlink = 0;
  193084. - priv->oldspeed = 0;
  193085. - priv->oldduplex = -1;
  193086. - }
  193087. - if (new_state && netif_msg_link(priv))
  193088. - phy_print_status(phydev);
  193089. - unlock_tx_qs(priv);
  193090. - local_irq_restore(flags);
  193091. + if (unlikely(phydev->link != priv->oldlink ||
  193092. + phydev->duplex != priv->oldduplex ||
  193093. + phydev->speed != priv->oldspeed))
  193094. + gfar_update_link_state(priv);
  193095. }
  193096. /* Update the hash table based on the current list of multicast
  193097. @@ -3425,6 +3345,114 @@
  193098. return IRQ_HANDLED;
  193099. }
  193100. +static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv)
  193101. +{
  193102. + struct phy_device *phydev = priv->phydev;
  193103. + u32 val = 0;
  193104. +
  193105. + if (!phydev->duplex)
  193106. + return val;
  193107. +
  193108. + if (!priv->pause_aneg_en) {
  193109. + if (priv->tx_pause_en)
  193110. + val |= MACCFG1_TX_FLOW;
  193111. + if (priv->rx_pause_en)
  193112. + val |= MACCFG1_RX_FLOW;
  193113. + } else {
  193114. + u16 lcl_adv, rmt_adv;
  193115. + u8 flowctrl;
  193116. + /* get link partner capabilities */
  193117. + rmt_adv = 0;
  193118. + if (phydev->pause)
  193119. + rmt_adv = LPA_PAUSE_CAP;
  193120. + if (phydev->asym_pause)
  193121. + rmt_adv |= LPA_PAUSE_ASYM;
  193122. +
  193123. + lcl_adv = mii_advertise_flowctrl(phydev->advertising);
  193124. +
  193125. + flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
  193126. + if (flowctrl & FLOW_CTRL_TX)
  193127. + val |= MACCFG1_TX_FLOW;
  193128. + if (flowctrl & FLOW_CTRL_RX)
  193129. + val |= MACCFG1_RX_FLOW;
  193130. + }
  193131. +
  193132. + return val;
  193133. +}
  193134. +
  193135. +static noinline void gfar_update_link_state(struct gfar_private *priv)
  193136. +{
  193137. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193138. + struct phy_device *phydev = priv->phydev;
  193139. +
  193140. + if (unlikely(test_bit(GFAR_RESETTING, &priv->state)))
  193141. + return;
  193142. +
  193143. + if (phydev->link) {
  193144. + u32 tempval1 = gfar_read(&regs->maccfg1);
  193145. + u32 tempval = gfar_read(&regs->maccfg2);
  193146. + u32 ecntrl = gfar_read(&regs->ecntrl);
  193147. +
  193148. + if (phydev->duplex != priv->oldduplex) {
  193149. + if (!(phydev->duplex))
  193150. + tempval &= ~(MACCFG2_FULL_DUPLEX);
  193151. + else
  193152. + tempval |= MACCFG2_FULL_DUPLEX;
  193153. +
  193154. + priv->oldduplex = phydev->duplex;
  193155. + }
  193156. +
  193157. + if (phydev->speed != priv->oldspeed) {
  193158. + switch (phydev->speed) {
  193159. + case 1000:
  193160. + tempval =
  193161. + ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII);
  193162. +
  193163. + ecntrl &= ~(ECNTRL_R100);
  193164. + break;
  193165. + case 100:
  193166. + case 10:
  193167. + tempval =
  193168. + ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
  193169. +
  193170. + /* Reduced mode distinguishes
  193171. + * between 10 and 100
  193172. + */
  193173. + if (phydev->speed == SPEED_100)
  193174. + ecntrl |= ECNTRL_R100;
  193175. + else
  193176. + ecntrl &= ~(ECNTRL_R100);
  193177. + break;
  193178. + default:
  193179. + netif_warn(priv, link, priv->ndev,
  193180. + "Ack! Speed (%d) is not 10/100/1000!\n",
  193181. + phydev->speed);
  193182. + break;
  193183. + }
  193184. +
  193185. + priv->oldspeed = phydev->speed;
  193186. + }
  193187. +
  193188. + tempval1 &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW);
  193189. + tempval1 |= gfar_get_flowctrl_cfg(priv);
  193190. +
  193191. + gfar_write(&regs->maccfg1, tempval1);
  193192. + gfar_write(&regs->maccfg2, tempval);
  193193. + gfar_write(&regs->ecntrl, ecntrl);
  193194. +
  193195. + if (!priv->oldlink)
  193196. + priv->oldlink = 1;
  193197. +
  193198. + } else if (priv->oldlink) {
  193199. + priv->oldlink = 0;
  193200. + priv->oldspeed = 0;
  193201. + priv->oldduplex = -1;
  193202. + }
  193203. +
  193204. + if (netif_msg_link(priv))
  193205. + phy_print_status(phydev);
  193206. +}
  193207. +
  193208. static struct of_device_id gfar_match[] =
  193209. {
  193210. {
  193211. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/gianfar_ethtool.c linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_ethtool.c
  193212. --- linux-3.14.14/drivers/net/ethernet/freescale/gianfar_ethtool.c 2014-07-28 10:07:25.000000000 -0500
  193213. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_ethtool.c 2014-12-08 00:31:53.596418001 -0600
  193214. @@ -44,10 +44,6 @@
  193215. #include "gianfar.h"
  193216. -extern void gfar_start(struct net_device *dev);
  193217. -extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue,
  193218. - int rx_work_limit);
  193219. -
  193220. #define GFAR_MAX_COAL_USECS 0xffff
  193221. #define GFAR_MAX_COAL_FRAMES 0xff
  193222. static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
  193223. @@ -364,25 +360,11 @@
  193224. struct ethtool_coalesce *cvals)
  193225. {
  193226. struct gfar_private *priv = netdev_priv(dev);
  193227. - int i = 0;
  193228. + int i, err = 0;
  193229. if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
  193230. return -EOPNOTSUPP;
  193231. - /* Set up rx coalescing */
  193232. - /* As of now, we will enable/disable coalescing for all
  193233. - * queues together in case of eTSEC2, this will be modified
  193234. - * along with the ethtool interface
  193235. - */
  193236. - if ((cvals->rx_coalesce_usecs == 0) ||
  193237. - (cvals->rx_max_coalesced_frames == 0)) {
  193238. - for (i = 0; i < priv->num_rx_queues; i++)
  193239. - priv->rx_queue[i]->rxcoalescing = 0;
  193240. - } else {
  193241. - for (i = 0; i < priv->num_rx_queues; i++)
  193242. - priv->rx_queue[i]->rxcoalescing = 1;
  193243. - }
  193244. -
  193245. if (NULL == priv->phydev)
  193246. return -ENODEV;
  193247. @@ -399,6 +381,32 @@
  193248. return -EINVAL;
  193249. }
  193250. + /* Check the bounds of the values */
  193251. + if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
  193252. + netdev_info(dev, "Coalescing is limited to %d microseconds\n",
  193253. + GFAR_MAX_COAL_USECS);
  193254. + return -EINVAL;
  193255. + }
  193256. +
  193257. + if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
  193258. + netdev_info(dev, "Coalescing is limited to %d frames\n",
  193259. + GFAR_MAX_COAL_FRAMES);
  193260. + return -EINVAL;
  193261. + }
  193262. +
  193263. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  193264. + cpu_relax();
  193265. +
  193266. + /* Set up rx coalescing */
  193267. + if ((cvals->rx_coalesce_usecs == 0) ||
  193268. + (cvals->rx_max_coalesced_frames == 0)) {
  193269. + for (i = 0; i < priv->num_rx_queues; i++)
  193270. + priv->rx_queue[i]->rxcoalescing = 0;
  193271. + } else {
  193272. + for (i = 0; i < priv->num_rx_queues; i++)
  193273. + priv->rx_queue[i]->rxcoalescing = 1;
  193274. + }
  193275. +
  193276. for (i = 0; i < priv->num_rx_queues; i++) {
  193277. priv->rx_queue[i]->rxic = mk_ic_value(
  193278. cvals->rx_max_coalesced_frames,
  193279. @@ -415,28 +423,22 @@
  193280. priv->tx_queue[i]->txcoalescing = 1;
  193281. }
  193282. - /* Check the bounds of the values */
  193283. - if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
  193284. - netdev_info(dev, "Coalescing is limited to %d microseconds\n",
  193285. - GFAR_MAX_COAL_USECS);
  193286. - return -EINVAL;
  193287. - }
  193288. -
  193289. - if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
  193290. - netdev_info(dev, "Coalescing is limited to %d frames\n",
  193291. - GFAR_MAX_COAL_FRAMES);
  193292. - return -EINVAL;
  193293. - }
  193294. -
  193295. for (i = 0; i < priv->num_tx_queues; i++) {
  193296. priv->tx_queue[i]->txic = mk_ic_value(
  193297. cvals->tx_max_coalesced_frames,
  193298. gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs));
  193299. }
  193300. - gfar_configure_coalescing_all(priv);
  193301. + if (dev->flags & IFF_UP) {
  193302. + stop_gfar(dev);
  193303. + err = startup_gfar(dev);
  193304. + } else {
  193305. + gfar_mac_reset(priv);
  193306. + }
  193307. +
  193308. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  193309. - return 0;
  193310. + return err;
  193311. }
  193312. /* Fills in rvals with the current ring parameters. Currently,
  193313. @@ -467,15 +469,13 @@
  193314. }
  193315. /* Change the current ring parameters, stopping the controller if
  193316. - * necessary so that we don't mess things up while we're in
  193317. - * motion. We wait for the ring to be clean before reallocating
  193318. - * the rings.
  193319. + * necessary so that we don't mess things up while we're in motion.
  193320. */
  193321. static int gfar_sringparam(struct net_device *dev,
  193322. struct ethtool_ringparam *rvals)
  193323. {
  193324. struct gfar_private *priv = netdev_priv(dev);
  193325. - int err = 0, i = 0;
  193326. + int err = 0, i;
  193327. if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE)
  193328. return -EINVAL;
  193329. @@ -493,44 +493,25 @@
  193330. return -EINVAL;
  193331. }
  193332. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  193333. + cpu_relax();
  193334. - if (dev->flags & IFF_UP) {
  193335. - unsigned long flags;
  193336. -
  193337. - /* Halt TX and RX, and process the frames which
  193338. - * have already been received
  193339. - */
  193340. - local_irq_save(flags);
  193341. - lock_tx_qs(priv);
  193342. - lock_rx_qs(priv);
  193343. -
  193344. - gfar_halt(dev);
  193345. -
  193346. - unlock_rx_qs(priv);
  193347. - unlock_tx_qs(priv);
  193348. - local_irq_restore(flags);
  193349. -
  193350. - for (i = 0; i < priv->num_rx_queues; i++)
  193351. - gfar_clean_rx_ring(priv->rx_queue[i],
  193352. - priv->rx_queue[i]->rx_ring_size);
  193353. -
  193354. - /* Now we take down the rings to rebuild them */
  193355. + if (dev->flags & IFF_UP)
  193356. stop_gfar(dev);
  193357. - }
  193358. - /* Change the size */
  193359. - for (i = 0; i < priv->num_rx_queues; i++) {
  193360. + /* Change the sizes */
  193361. + for (i = 0; i < priv->num_rx_queues; i++)
  193362. priv->rx_queue[i]->rx_ring_size = rvals->rx_pending;
  193363. +
  193364. + for (i = 0; i < priv->num_tx_queues; i++)
  193365. priv->tx_queue[i]->tx_ring_size = rvals->tx_pending;
  193366. - priv->tx_queue[i]->num_txbdfree =
  193367. - priv->tx_queue[i]->tx_ring_size;
  193368. - }
  193369. /* Rebuild the rings with the new size */
  193370. - if (dev->flags & IFF_UP) {
  193371. + if (dev->flags & IFF_UP)
  193372. err = startup_gfar(dev);
  193373. - netif_tx_wake_all_queues(dev);
  193374. - }
  193375. +
  193376. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  193377. +
  193378. return err;
  193379. }
  193380. @@ -552,6 +533,9 @@
  193381. struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193382. u32 oldadv, newadv;
  193383. + if (!phydev)
  193384. + return -ENODEV;
  193385. +
  193386. if (!(phydev->supported & SUPPORTED_Pause) ||
  193387. (!(phydev->supported & SUPPORTED_Asym_Pause) &&
  193388. (epause->rx_pause != epause->tx_pause)))
  193389. @@ -608,43 +592,29 @@
  193390. int gfar_set_features(struct net_device *dev, netdev_features_t features)
  193391. {
  193392. - struct gfar_private *priv = netdev_priv(dev);
  193393. - unsigned long flags;
  193394. - int err = 0, i = 0;
  193395. netdev_features_t changed = dev->features ^ features;
  193396. + struct gfar_private *priv = netdev_priv(dev);
  193397. + int err = 0;
  193398. - if (changed & (NETIF_F_HW_VLAN_CTAG_TX|NETIF_F_HW_VLAN_CTAG_RX))
  193399. - gfar_vlan_mode(dev, features);
  193400. -
  193401. - if (!(changed & NETIF_F_RXCSUM))
  193402. + if (!(changed & (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
  193403. + NETIF_F_RXCSUM)))
  193404. return 0;
  193405. - if (dev->flags & IFF_UP) {
  193406. - /* Halt TX and RX, and process the frames which
  193407. - * have already been received
  193408. - */
  193409. - local_irq_save(flags);
  193410. - lock_tx_qs(priv);
  193411. - lock_rx_qs(priv);
  193412. -
  193413. - gfar_halt(dev);
  193414. -
  193415. - unlock_tx_qs(priv);
  193416. - unlock_rx_qs(priv);
  193417. - local_irq_restore(flags);
  193418. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  193419. + cpu_relax();
  193420. - for (i = 0; i < priv->num_rx_queues; i++)
  193421. - gfar_clean_rx_ring(priv->rx_queue[i],
  193422. - priv->rx_queue[i]->rx_ring_size);
  193423. + dev->features = features;
  193424. + if (dev->flags & IFF_UP) {
  193425. /* Now we take down the rings to rebuild them */
  193426. stop_gfar(dev);
  193427. -
  193428. - dev->features = features;
  193429. -
  193430. err = startup_gfar(dev);
  193431. - netif_tx_wake_all_queues(dev);
  193432. + } else {
  193433. + gfar_mac_reset(priv);
  193434. }
  193435. +
  193436. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  193437. +
  193438. return err;
  193439. }
  193440. @@ -1610,9 +1580,6 @@
  193441. if (tab->index > MAX_FILER_IDX - 1)
  193442. return -EBUSY;
  193443. - /* Avoid inconsistent filer table to be processed */
  193444. - lock_rx_qs(priv);
  193445. -
  193446. /* Fill regular entries */
  193447. for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].ctrl);
  193448. i++)
  193449. @@ -1625,8 +1592,6 @@
  193450. */
  193451. gfar_write_filer(priv, i, 0x20, 0x0);
  193452. - unlock_rx_qs(priv);
  193453. -
  193454. return 0;
  193455. }
  193456. @@ -1831,6 +1796,9 @@
  193457. struct gfar_private *priv = netdev_priv(dev);
  193458. int ret = 0;
  193459. + if (test_bit(GFAR_RESETTING, &priv->state))
  193460. + return -EBUSY;
  193461. +
  193462. mutex_lock(&priv->rx_queue_access);
  193463. switch (cmd->cmd) {
  193464. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/gianfar.h linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar.h
  193465. --- linux-3.14.14/drivers/net/ethernet/freescale/gianfar.h 2014-07-28 10:07:25.000000000 -0500
  193466. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar.h 2014-12-08 00:31:53.596418001 -0600
  193467. @@ -9,7 +9,7 @@
  193468. * Maintainer: Kumar Gala
  193469. * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  193470. *
  193471. - * Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
  193472. + * Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc.
  193473. *
  193474. * This program is free software; you can redistribute it and/or modify it
  193475. * under the terms of the GNU General Public License as published by the
  193476. @@ -377,8 +377,11 @@
  193477. IMASK_RXFEN0 | IMASK_BSY | IMASK_EBERR | IMASK_BABR | \
  193478. IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
  193479. | IMASK_PERR)
  193480. -#define IMASK_RTX_DISABLED ((~(IMASK_RXFEN0 | IMASK_TXFEN | IMASK_BSY)) \
  193481. - & IMASK_DEFAULT)
  193482. +#define IMASK_RX_DEFAULT (IMASK_RXFEN0 | IMASK_BSY)
  193483. +#define IMASK_TX_DEFAULT (IMASK_TXFEN | IMASK_TXBEN)
  193484. +
  193485. +#define IMASK_RX_DISABLED ((~(IMASK_RX_DEFAULT)) & IMASK_DEFAULT)
  193486. +#define IMASK_TX_DISABLED ((~(IMASK_TX_DEFAULT)) & IMASK_DEFAULT)
  193487. /* Fifo management */
  193488. #define FIFO_TX_THR_MASK 0x01ff
  193489. @@ -409,7 +412,9 @@
  193490. /* This default RIR value directly corresponds
  193491. * to the 3-bit hash value generated */
  193492. -#define DEFAULT_RIR0 0x05397700
  193493. +#define DEFAULT_8RXQ_RIR0 0x05397700
  193494. +/* Map even hash values to Q0, and odd ones to Q1 */
  193495. +#define DEFAULT_2RXQ_RIR0 0x04104100
  193496. /* RQFCR register bits */
  193497. #define RQFCR_GPI 0x80000000
  193498. @@ -880,7 +885,6 @@
  193499. #define FSL_GIANFAR_DEV_HAS_CSUM 0x00000010
  193500. #define FSL_GIANFAR_DEV_HAS_VLAN 0x00000020
  193501. #define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH 0x00000040
  193502. -#define FSL_GIANFAR_DEV_HAS_PADDING 0x00000080
  193503. #define FSL_GIANFAR_DEV_HAS_MAGIC_PACKET 0x00000100
  193504. #define FSL_GIANFAR_DEV_HAS_BD_STASHING 0x00000200
  193505. #define FSL_GIANFAR_DEV_HAS_BUF_STASHING 0x00000400
  193506. @@ -892,8 +896,8 @@
  193507. #define DEFAULT_MAPPING 0xFF
  193508. #endif
  193509. -#define ISRG_SHIFT_TX 0x10
  193510. -#define ISRG_SHIFT_RX 0x18
  193511. +#define ISRG_RR0 0x80000000
  193512. +#define ISRG_TR0 0x00800000
  193513. /* The same driver can operate in two modes */
  193514. /* SQ_SG_MODE: Single Queue Single Group Mode
  193515. @@ -905,6 +909,22 @@
  193516. MQ_MG_MODE
  193517. };
  193518. +/* GFAR_SQ_POLLING: Single Queue NAPI polling mode
  193519. + * The driver supports a single pair of RX/Tx queues
  193520. + * per interrupt group (Rx/Tx int line). MQ_MG mode
  193521. + * devices have 2 interrupt groups, so the device will
  193522. + * have a total of 2 Tx and 2 Rx queues in this case.
  193523. + * GFAR_MQ_POLLING: Multi Queue NAPI polling mode
  193524. + * The driver supports all the 8 Rx and Tx HW queues
  193525. + * each queue mapped by the Device Tree to one of
  193526. + * the 2 interrupt groups. This mode implies significant
  193527. + * processing overhead (CPU and controller level).
  193528. + */
  193529. +enum gfar_poll_mode {
  193530. + GFAR_SQ_POLLING = 0,
  193531. + GFAR_MQ_POLLING
  193532. +};
  193533. +
  193534. /*
  193535. * Per TX queue stats
  193536. */
  193537. @@ -966,7 +986,6 @@
  193538. /**
  193539. * struct gfar_priv_rx_q - per rx queue structure
  193540. - * @rxlock: per queue rx spin lock
  193541. * @rx_skbuff: skb pointers
  193542. * @skb_currx: currently use skb pointer
  193543. * @rx_bd_base: First rx buffer descriptor
  193544. @@ -979,8 +998,7 @@
  193545. */
  193546. struct gfar_priv_rx_q {
  193547. - spinlock_t rxlock __attribute__ ((aligned (SMP_CACHE_BYTES)));
  193548. - struct sk_buff ** rx_skbuff;
  193549. + struct sk_buff **rx_skbuff __aligned(SMP_CACHE_BYTES);
  193550. dma_addr_t rx_bd_dma_base;
  193551. struct rxbd8 *rx_bd_base;
  193552. struct rxbd8 *cur_rx;
  193553. @@ -1016,17 +1034,20 @@
  193554. */
  193555. struct gfar_priv_grp {
  193556. - spinlock_t grplock __attribute__ ((aligned (SMP_CACHE_BYTES)));
  193557. - struct napi_struct napi;
  193558. - struct gfar_private *priv;
  193559. + spinlock_t grplock __aligned(SMP_CACHE_BYTES);
  193560. + struct napi_struct napi_rx;
  193561. + struct napi_struct napi_tx;
  193562. struct gfar __iomem *regs;
  193563. - unsigned int rstat;
  193564. - unsigned long num_rx_queues;
  193565. - unsigned long rx_bit_map;
  193566. - /* cacheline 3 */
  193567. + struct gfar_priv_tx_q *tx_queue;
  193568. + struct gfar_priv_rx_q *rx_queue;
  193569. unsigned int tstat;
  193570. + unsigned int rstat;
  193571. +
  193572. + struct gfar_private *priv;
  193573. unsigned long num_tx_queues;
  193574. unsigned long tx_bit_map;
  193575. + unsigned long num_rx_queues;
  193576. + unsigned long rx_bit_map;
  193577. struct gfar_irqinfo *irqinfo[GFAR_NUM_IRQS];
  193578. };
  193579. @@ -1041,6 +1062,11 @@
  193580. GFAR_ERRATA_12 = 0x08, /* a.k.a errata eTSEC49 */
  193581. };
  193582. +enum gfar_dev_state {
  193583. + GFAR_DOWN = 1,
  193584. + GFAR_RESETTING
  193585. +};
  193586. +
  193587. /* Struct stolen almost completely (and shamelessly) from the FCC enet source
  193588. * (Ok, that's not so true anymore, but there is a family resemblance)
  193589. * The GFAR buffer descriptors track the ring buffers. The rx_bd_base
  193590. @@ -1051,8 +1077,6 @@
  193591. * the buffer descriptor determines the actual condition.
  193592. */
  193593. struct gfar_private {
  193594. - unsigned int num_rx_queues;
  193595. -
  193596. struct device *dev;
  193597. struct net_device *ndev;
  193598. enum gfar_errata errata;
  193599. @@ -1060,6 +1084,7 @@
  193600. u16 uses_rxfcb;
  193601. u16 padding;
  193602. + u32 device_flags;
  193603. /* HW time stamping enabled flag */
  193604. int hwts_rx_en;
  193605. @@ -1069,10 +1094,12 @@
  193606. struct gfar_priv_rx_q *rx_queue[MAX_RX_QS];
  193607. struct gfar_priv_grp gfargrp[MAXGROUPS];
  193608. - u32 device_flags;
  193609. + unsigned long state;
  193610. - unsigned int mode;
  193611. + unsigned short mode;
  193612. + unsigned short poll_mode;
  193613. unsigned int num_tx_queues;
  193614. + unsigned int num_rx_queues;
  193615. unsigned int num_grps;
  193616. /* Network Statistics */
  193617. @@ -1113,6 +1140,9 @@
  193618. unsigned int total_tx_ring_size;
  193619. unsigned int total_rx_ring_size;
  193620. + u32 rqueue;
  193621. + u32 tqueue;
  193622. +
  193623. /* RX per device parameters */
  193624. unsigned int rx_stash_size;
  193625. unsigned int rx_stash_index;
  193626. @@ -1127,11 +1157,6 @@
  193627. u32 __iomem *hash_regs[16];
  193628. int hash_width;
  193629. - /* global parameters */
  193630. - unsigned int fifo_threshold;
  193631. - unsigned int fifo_starve;
  193632. - unsigned int fifo_starve_off;
  193633. -
  193634. /*Filer table*/
  193635. unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
  193636. unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
  193637. @@ -1176,21 +1201,42 @@
  193638. *fpr = gfar_read(&regs->rqfpr);
  193639. }
  193640. -void lock_rx_qs(struct gfar_private *priv);
  193641. -void lock_tx_qs(struct gfar_private *priv);
  193642. -void unlock_rx_qs(struct gfar_private *priv);
  193643. -void unlock_tx_qs(struct gfar_private *priv);
  193644. +static inline void gfar_write_isrg(struct gfar_private *priv)
  193645. +{
  193646. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193647. + u32 __iomem *baddr = &regs->isrg0;
  193648. + u32 isrg = 0;
  193649. + int grp_idx, i;
  193650. +
  193651. + for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
  193652. + struct gfar_priv_grp *grp = &priv->gfargrp[grp_idx];
  193653. +
  193654. + for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) {
  193655. + isrg |= (ISRG_RR0 >> i);
  193656. + }
  193657. +
  193658. + for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) {
  193659. + isrg |= (ISRG_TR0 >> i);
  193660. + }
  193661. +
  193662. + gfar_write(baddr, isrg);
  193663. +
  193664. + baddr++;
  193665. + isrg = 0;
  193666. + }
  193667. +}
  193668. +
  193669. irqreturn_t gfar_receive(int irq, void *dev_id);
  193670. int startup_gfar(struct net_device *dev);
  193671. void stop_gfar(struct net_device *dev);
  193672. -void gfar_halt(struct net_device *dev);
  193673. +void reset_gfar(struct net_device *dev);
  193674. +void gfar_mac_reset(struct gfar_private *priv);
  193675. +void gfar_halt(struct gfar_private *priv);
  193676. +void gfar_start(struct gfar_private *priv);
  193677. void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, int enable,
  193678. u32 regnum, u32 read);
  193679. void gfar_configure_coalescing_all(struct gfar_private *priv);
  193680. -void gfar_init_sysfs(struct net_device *dev);
  193681. int gfar_set_features(struct net_device *dev, netdev_features_t features);
  193682. -void gfar_check_rx_parser_mode(struct gfar_private *priv);
  193683. -void gfar_vlan_mode(struct net_device *dev, netdev_features_t features);
  193684. extern const struct ethtool_ops gfar_ethtool_ops;
  193685. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/gianfar_ptp.c linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_ptp.c
  193686. --- linux-3.14.14/drivers/net/ethernet/freescale/gianfar_ptp.c 2014-07-28 10:07:25.000000000 -0500
  193687. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_ptp.c 2014-12-08 00:31:53.596418001 -0600
  193688. @@ -414,6 +414,7 @@
  193689. .n_alarm = 0,
  193690. .n_ext_ts = N_EXT_TS,
  193691. .n_per_out = 0,
  193692. + .n_pins = 0,
  193693. .pps = 1,
  193694. .adjfreq = ptp_gianfar_adjfreq,
  193695. .adjtime = ptp_gianfar_adjtime,
  193696. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/gianfar_sysfs.c linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_sysfs.c
  193697. --- linux-3.14.14/drivers/net/ethernet/freescale/gianfar_sysfs.c 2014-07-28 10:07:25.000000000 -0500
  193698. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_sysfs.c 1969-12-31 18:00:00.000000000 -0600
  193699. @@ -1,340 +0,0 @@
  193700. -/*
  193701. - * drivers/net/ethernet/freescale/gianfar_sysfs.c
  193702. - *
  193703. - * Gianfar Ethernet Driver
  193704. - * This driver is designed for the non-CPM ethernet controllers
  193705. - * on the 85xx and 83xx family of integrated processors
  193706. - * Based on 8260_io/fcc_enet.c
  193707. - *
  193708. - * Author: Andy Fleming
  193709. - * Maintainer: Kumar Gala (galak@kernel.crashing.org)
  193710. - * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  193711. - *
  193712. - * Copyright 2002-2009 Freescale Semiconductor, Inc.
  193713. - *
  193714. - * This program is free software; you can redistribute it and/or modify it
  193715. - * under the terms of the GNU General Public License as published by the
  193716. - * Free Software Foundation; either version 2 of the License, or (at your
  193717. - * option) any later version.
  193718. - *
  193719. - * Sysfs file creation and management
  193720. - */
  193721. -
  193722. -#include <linux/kernel.h>
  193723. -#include <linux/string.h>
  193724. -#include <linux/errno.h>
  193725. -#include <linux/unistd.h>
  193726. -#include <linux/delay.h>
  193727. -#include <linux/etherdevice.h>
  193728. -#include <linux/spinlock.h>
  193729. -#include <linux/mm.h>
  193730. -#include <linux/device.h>
  193731. -
  193732. -#include <asm/uaccess.h>
  193733. -#include <linux/module.h>
  193734. -
  193735. -#include "gianfar.h"
  193736. -
  193737. -static ssize_t gfar_show_bd_stash(struct device *dev,
  193738. - struct device_attribute *attr, char *buf)
  193739. -{
  193740. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193741. -
  193742. - return sprintf(buf, "%s\n", priv->bd_stash_en ? "on" : "off");
  193743. -}
  193744. -
  193745. -static ssize_t gfar_set_bd_stash(struct device *dev,
  193746. - struct device_attribute *attr,
  193747. - const char *buf, size_t count)
  193748. -{
  193749. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193750. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193751. - int new_setting = 0;
  193752. - u32 temp;
  193753. - unsigned long flags;
  193754. -
  193755. - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BD_STASHING))
  193756. - return count;
  193757. -
  193758. -
  193759. - /* Find out the new setting */
  193760. - if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
  193761. - new_setting = 1;
  193762. - else if (!strncmp("off", buf, count - 1) ||
  193763. - !strncmp("0", buf, count - 1))
  193764. - new_setting = 0;
  193765. - else
  193766. - return count;
  193767. -
  193768. -
  193769. - local_irq_save(flags);
  193770. - lock_rx_qs(priv);
  193771. -
  193772. - /* Set the new stashing value */
  193773. - priv->bd_stash_en = new_setting;
  193774. -
  193775. - temp = gfar_read(&regs->attr);
  193776. -
  193777. - if (new_setting)
  193778. - temp |= ATTR_BDSTASH;
  193779. - else
  193780. - temp &= ~(ATTR_BDSTASH);
  193781. -
  193782. - gfar_write(&regs->attr, temp);
  193783. -
  193784. - unlock_rx_qs(priv);
  193785. - local_irq_restore(flags);
  193786. -
  193787. - return count;
  193788. -}
  193789. -
  193790. -static DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash);
  193791. -
  193792. -static ssize_t gfar_show_rx_stash_size(struct device *dev,
  193793. - struct device_attribute *attr, char *buf)
  193794. -{
  193795. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193796. -
  193797. - return sprintf(buf, "%d\n", priv->rx_stash_size);
  193798. -}
  193799. -
  193800. -static ssize_t gfar_set_rx_stash_size(struct device *dev,
  193801. - struct device_attribute *attr,
  193802. - const char *buf, size_t count)
  193803. -{
  193804. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193805. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193806. - unsigned int length = simple_strtoul(buf, NULL, 0);
  193807. - u32 temp;
  193808. - unsigned long flags;
  193809. -
  193810. - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
  193811. - return count;
  193812. -
  193813. - local_irq_save(flags);
  193814. - lock_rx_qs(priv);
  193815. -
  193816. - if (length > priv->rx_buffer_size)
  193817. - goto out;
  193818. -
  193819. - if (length == priv->rx_stash_size)
  193820. - goto out;
  193821. -
  193822. - priv->rx_stash_size = length;
  193823. -
  193824. - temp = gfar_read(&regs->attreli);
  193825. - temp &= ~ATTRELI_EL_MASK;
  193826. - temp |= ATTRELI_EL(length);
  193827. - gfar_write(&regs->attreli, temp);
  193828. -
  193829. - /* Turn stashing on/off as appropriate */
  193830. - temp = gfar_read(&regs->attr);
  193831. -
  193832. - if (length)
  193833. - temp |= ATTR_BUFSTASH;
  193834. - else
  193835. - temp &= ~(ATTR_BUFSTASH);
  193836. -
  193837. - gfar_write(&regs->attr, temp);
  193838. -
  193839. -out:
  193840. - unlock_rx_qs(priv);
  193841. - local_irq_restore(flags);
  193842. -
  193843. - return count;
  193844. -}
  193845. -
  193846. -static DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size,
  193847. - gfar_set_rx_stash_size);
  193848. -
  193849. -/* Stashing will only be enabled when rx_stash_size != 0 */
  193850. -static ssize_t gfar_show_rx_stash_index(struct device *dev,
  193851. - struct device_attribute *attr,
  193852. - char *buf)
  193853. -{
  193854. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193855. -
  193856. - return sprintf(buf, "%d\n", priv->rx_stash_index);
  193857. -}
  193858. -
  193859. -static ssize_t gfar_set_rx_stash_index(struct device *dev,
  193860. - struct device_attribute *attr,
  193861. - const char *buf, size_t count)
  193862. -{
  193863. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193864. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193865. - unsigned short index = simple_strtoul(buf, NULL, 0);
  193866. - u32 temp;
  193867. - unsigned long flags;
  193868. -
  193869. - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
  193870. - return count;
  193871. -
  193872. - local_irq_save(flags);
  193873. - lock_rx_qs(priv);
  193874. -
  193875. - if (index > priv->rx_stash_size)
  193876. - goto out;
  193877. -
  193878. - if (index == priv->rx_stash_index)
  193879. - goto out;
  193880. -
  193881. - priv->rx_stash_index = index;
  193882. -
  193883. - temp = gfar_read(&regs->attreli);
  193884. - temp &= ~ATTRELI_EI_MASK;
  193885. - temp |= ATTRELI_EI(index);
  193886. - gfar_write(&regs->attreli, temp);
  193887. -
  193888. -out:
  193889. - unlock_rx_qs(priv);
  193890. - local_irq_restore(flags);
  193891. -
  193892. - return count;
  193893. -}
  193894. -
  193895. -static DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index,
  193896. - gfar_set_rx_stash_index);
  193897. -
  193898. -static ssize_t gfar_show_fifo_threshold(struct device *dev,
  193899. - struct device_attribute *attr,
  193900. - char *buf)
  193901. -{
  193902. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193903. -
  193904. - return sprintf(buf, "%d\n", priv->fifo_threshold);
  193905. -}
  193906. -
  193907. -static ssize_t gfar_set_fifo_threshold(struct device *dev,
  193908. - struct device_attribute *attr,
  193909. - const char *buf, size_t count)
  193910. -{
  193911. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193912. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193913. - unsigned int length = simple_strtoul(buf, NULL, 0);
  193914. - u32 temp;
  193915. - unsigned long flags;
  193916. -
  193917. - if (length > GFAR_MAX_FIFO_THRESHOLD)
  193918. - return count;
  193919. -
  193920. - local_irq_save(flags);
  193921. - lock_tx_qs(priv);
  193922. -
  193923. - priv->fifo_threshold = length;
  193924. -
  193925. - temp = gfar_read(&regs->fifo_tx_thr);
  193926. - temp &= ~FIFO_TX_THR_MASK;
  193927. - temp |= length;
  193928. - gfar_write(&regs->fifo_tx_thr, temp);
  193929. -
  193930. - unlock_tx_qs(priv);
  193931. - local_irq_restore(flags);
  193932. -
  193933. - return count;
  193934. -}
  193935. -
  193936. -static DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold,
  193937. - gfar_set_fifo_threshold);
  193938. -
  193939. -static ssize_t gfar_show_fifo_starve(struct device *dev,
  193940. - struct device_attribute *attr, char *buf)
  193941. -{
  193942. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193943. -
  193944. - return sprintf(buf, "%d\n", priv->fifo_starve);
  193945. -}
  193946. -
  193947. -static ssize_t gfar_set_fifo_starve(struct device *dev,
  193948. - struct device_attribute *attr,
  193949. - const char *buf, size_t count)
  193950. -{
  193951. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193952. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193953. - unsigned int num = simple_strtoul(buf, NULL, 0);
  193954. - u32 temp;
  193955. - unsigned long flags;
  193956. -
  193957. - if (num > GFAR_MAX_FIFO_STARVE)
  193958. - return count;
  193959. -
  193960. - local_irq_save(flags);
  193961. - lock_tx_qs(priv);
  193962. -
  193963. - priv->fifo_starve = num;
  193964. -
  193965. - temp = gfar_read(&regs->fifo_tx_starve);
  193966. - temp &= ~FIFO_TX_STARVE_MASK;
  193967. - temp |= num;
  193968. - gfar_write(&regs->fifo_tx_starve, temp);
  193969. -
  193970. - unlock_tx_qs(priv);
  193971. - local_irq_restore(flags);
  193972. -
  193973. - return count;
  193974. -}
  193975. -
  193976. -static DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve,
  193977. - gfar_set_fifo_starve);
  193978. -
  193979. -static ssize_t gfar_show_fifo_starve_off(struct device *dev,
  193980. - struct device_attribute *attr,
  193981. - char *buf)
  193982. -{
  193983. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193984. -
  193985. - return sprintf(buf, "%d\n", priv->fifo_starve_off);
  193986. -}
  193987. -
  193988. -static ssize_t gfar_set_fifo_starve_off(struct device *dev,
  193989. - struct device_attribute *attr,
  193990. - const char *buf, size_t count)
  193991. -{
  193992. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  193993. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193994. - unsigned int num = simple_strtoul(buf, NULL, 0);
  193995. - u32 temp;
  193996. - unsigned long flags;
  193997. -
  193998. - if (num > GFAR_MAX_FIFO_STARVE_OFF)
  193999. - return count;
  194000. -
  194001. - local_irq_save(flags);
  194002. - lock_tx_qs(priv);
  194003. -
  194004. - priv->fifo_starve_off = num;
  194005. -
  194006. - temp = gfar_read(&regs->fifo_tx_starve_shutoff);
  194007. - temp &= ~FIFO_TX_STARVE_OFF_MASK;
  194008. - temp |= num;
  194009. - gfar_write(&regs->fifo_tx_starve_shutoff, temp);
  194010. -
  194011. - unlock_tx_qs(priv);
  194012. - local_irq_restore(flags);
  194013. -
  194014. - return count;
  194015. -}
  194016. -
  194017. -static DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off,
  194018. - gfar_set_fifo_starve_off);
  194019. -
  194020. -void gfar_init_sysfs(struct net_device *dev)
  194021. -{
  194022. - struct gfar_private *priv = netdev_priv(dev);
  194023. - int rc;
  194024. -
  194025. - /* Initialize the default values */
  194026. - priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
  194027. - priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
  194028. - priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
  194029. -
  194030. - /* Create our sysfs files */
  194031. - rc = device_create_file(&dev->dev, &dev_attr_bd_stash);
  194032. - rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_size);
  194033. - rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_index);
  194034. - rc |= device_create_file(&dev->dev, &dev_attr_fifo_threshold);
  194035. - rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve);
  194036. - rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve_off);
  194037. - if (rc)
  194038. - dev_err(&dev->dev, "Error creating gianfar sysfs files\n");
  194039. -}
  194040. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/Kconfig linux-imx6-3.14/drivers/net/ethernet/freescale/Kconfig
  194041. --- linux-3.14.14/drivers/net/ethernet/freescale/Kconfig 2014-07-28 10:07:25.000000000 -0500
  194042. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/Kconfig 2014-12-08 00:31:53.592418001 -0600
  194043. @@ -67,6 +67,7 @@
  194044. tristate "Freescale XGMAC MDIO"
  194045. depends on FSL_SOC
  194046. select PHYLIB
  194047. + select OF_MDIO
  194048. ---help---
  194049. This driver supports the MDIO bus on the Fman 10G Ethernet MACs.
  194050. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/Makefile linux-imx6-3.14/drivers/net/ethernet/freescale/Makefile
  194051. --- linux-3.14.14/drivers/net/ethernet/freescale/Makefile 2014-07-28 10:07:25.000000000 -0500
  194052. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/Makefile 2014-12-08 00:31:53.592418001 -0600
  194053. @@ -14,7 +14,6 @@
  194054. obj-$(CONFIG_GIANFAR) += gianfar_driver.o
  194055. obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o
  194056. gianfar_driver-objs := gianfar.o \
  194057. - gianfar_ethtool.o \
  194058. - gianfar_sysfs.o
  194059. + gianfar_ethtool.o
  194060. obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
  194061. ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
  194062. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/ucc_geth.c linux-imx6-3.14/drivers/net/ethernet/freescale/ucc_geth.c
  194063. --- linux-3.14.14/drivers/net/ethernet/freescale/ucc_geth.c 2014-07-28 10:07:25.000000000 -0500
  194064. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/ucc_geth.c 2014-12-08 00:31:53.596418001 -0600
  194065. @@ -1728,9 +1728,6 @@
  194066. phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0,
  194067. priv->phy_interface);
  194068. - if (!phydev)
  194069. - phydev = of_phy_connect_fixed_link(dev, &adjust_link,
  194070. - priv->phy_interface);
  194071. if (!phydev) {
  194072. dev_err(&dev->dev, "Could not attach to PHY\n");
  194073. return -ENODEV;
  194074. @@ -3261,7 +3258,7 @@
  194075. dev->stats.tx_packets++;
  194076. - dev_kfree_skb(skb);
  194077. + dev_consume_skb_any(skb);
  194078. ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
  194079. ugeth->skb_dirtytx[txQ] =
  194080. @@ -3790,6 +3787,17 @@
  194081. ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
  194082. ug_info->phy_node = of_parse_phandle(np, "phy-handle", 0);
  194083. + if (!ug_info->phy_node) {
  194084. + /* In the case of a fixed PHY, the DT node associated
  194085. + * to the PHY is the Ethernet MAC DT node.
  194086. + */
  194087. + if (of_phy_is_fixed_link(np)) {
  194088. + err = of_phy_register_fixed_link(np);
  194089. + if (err)
  194090. + return err;
  194091. + }
  194092. + ug_info->phy_node = np;
  194093. + }
  194094. /* Find the TBI PHY node. If it's not there, we don't support SGMII */
  194095. ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
  194096. diff -Nur linux-3.14.14/drivers/net/ethernet/freescale/xgmac_mdio.c linux-imx6-3.14/drivers/net/ethernet/freescale/xgmac_mdio.c
  194097. --- linux-3.14.14/drivers/net/ethernet/freescale/xgmac_mdio.c 2014-07-28 10:07:25.000000000 -0500
  194098. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/xgmac_mdio.c 2014-12-08 00:31:53.596418001 -0600
  194099. @@ -162,7 +162,9 @@
  194100. /* Return all Fs if nothing was there */
  194101. if (in_be32(&regs->mdio_stat) & MDIO_STAT_RD_ER) {
  194102. - dev_err(&bus->dev, "MDIO read error\n");
  194103. + dev_err(&bus->dev,
  194104. + "Error while reading PHY%d reg at %d.%d\n",
  194105. + phy_id, dev_addr, regnum);
  194106. return 0xffff;
  194107. }
  194108. diff -Nur linux-3.14.14/drivers/net/ethernet/intel/e1000e/ptp.c linux-imx6-3.14/drivers/net/ethernet/intel/e1000e/ptp.c
  194109. --- linux-3.14.14/drivers/net/ethernet/intel/e1000e/ptp.c 2014-07-28 10:07:25.000000000 -0500
  194110. +++ linux-imx6-3.14/drivers/net/ethernet/intel/e1000e/ptp.c 2014-12-08 00:31:53.616418001 -0600
  194111. @@ -191,6 +191,7 @@
  194112. .n_alarm = 0,
  194113. .n_ext_ts = 0,
  194114. .n_per_out = 0,
  194115. + .n_pins = 0,
  194116. .pps = 0,
  194117. .adjfreq = e1000e_phc_adjfreq,
  194118. .adjtime = e1000e_phc_adjtime,
  194119. diff -Nur linux-3.14.14/drivers/net/ethernet/mellanox/mlx4/en_clock.c linux-imx6-3.14/drivers/net/ethernet/mellanox/mlx4/en_clock.c
  194120. --- linux-3.14.14/drivers/net/ethernet/mellanox/mlx4/en_clock.c 2014-07-28 10:07:25.000000000 -0500
  194121. +++ linux-imx6-3.14/drivers/net/ethernet/mellanox/mlx4/en_clock.c 2014-12-08 00:31:53.648418001 -0600
  194122. @@ -276,6 +276,7 @@
  194123. .n_alarm = 0,
  194124. .n_ext_ts = 0,
  194125. .n_per_out = 0,
  194126. + .n_pins = 0,
  194127. .pps = 0,
  194128. .adjfreq = mlx4_en_phc_adjfreq,
  194129. .adjtime = mlx4_en_phc_adjtime,
  194130. diff -Nur linux-3.14.14/drivers/net/ethernet/sfc/ptp.c linux-imx6-3.14/drivers/net/ethernet/sfc/ptp.c
  194131. --- linux-3.14.14/drivers/net/ethernet/sfc/ptp.c 2014-07-28 10:07:25.000000000 -0500
  194132. +++ linux-imx6-3.14/drivers/net/ethernet/sfc/ptp.c 2014-12-08 00:31:53.696418001 -0600
  194133. @@ -1208,6 +1208,7 @@
  194134. .n_alarm = 0,
  194135. .n_ext_ts = 0,
  194136. .n_per_out = 0,
  194137. + .n_pins = 0,
  194138. .pps = 1,
  194139. .adjfreq = efx_phc_adjfreq,
  194140. .adjtime = efx_phc_adjtime,
  194141. diff -Nur linux-3.14.14/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c linux-imx6-3.14/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
  194142. --- linux-3.14.14/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c 2014-07-28 10:07:25.000000000 -0500
  194143. +++ linux-imx6-3.14/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c 2014-12-08 00:31:53.708418001 -0600
  194144. @@ -164,6 +164,7 @@
  194145. .n_alarm = 0,
  194146. .n_ext_ts = 0,
  194147. .n_per_out = 0,
  194148. + .n_pins = 0,
  194149. .pps = 0,
  194150. .adjfreq = stmmac_adjust_freq,
  194151. .adjtime = stmmac_adjust_time,
  194152. diff -Nur linux-3.14.14/drivers/net/ethernet/ti/cpts.c linux-imx6-3.14/drivers/net/ethernet/ti/cpts.c
  194153. --- linux-3.14.14/drivers/net/ethernet/ti/cpts.c 2014-07-28 10:07:25.000000000 -0500
  194154. +++ linux-imx6-3.14/drivers/net/ethernet/ti/cpts.c 2014-12-08 00:31:53.716418001 -0600
  194155. @@ -217,6 +217,7 @@
  194156. .name = "CTPS timer",
  194157. .max_adj = 1000000,
  194158. .n_ext_ts = 0,
  194159. + .n_pins = 0,
  194160. .pps = 0,
  194161. .adjfreq = cpts_ptp_adjfreq,
  194162. .adjtime = cpts_ptp_adjtime,
  194163. diff -Nur linux-3.14.14/drivers/net/ethernet/tile/tilegx.c linux-imx6-3.14/drivers/net/ethernet/tile/tilegx.c
  194164. --- linux-3.14.14/drivers/net/ethernet/tile/tilegx.c 2014-07-28 10:07:25.000000000 -0500
  194165. +++ linux-imx6-3.14/drivers/net/ethernet/tile/tilegx.c 2014-12-08 00:31:53.720418001 -0600
  194166. @@ -870,6 +870,7 @@
  194167. .name = "mPIPE clock",
  194168. .max_adj = 999999999,
  194169. .n_ext_ts = 0,
  194170. + .n_pins = 0,
  194171. .pps = 0,
  194172. .adjfreq = ptp_mpipe_adjfreq,
  194173. .adjtime = ptp_mpipe_adjtime,
  194174. diff -Nur linux-3.14.14/drivers/net/ieee802154/Kconfig linux-imx6-3.14/drivers/net/ieee802154/Kconfig
  194175. --- linux-3.14.14/drivers/net/ieee802154/Kconfig 2014-07-28 10:07:25.000000000 -0500
  194176. +++ linux-imx6-3.14/drivers/net/ieee802154/Kconfig 2014-12-08 00:31:53.736418001 -0600
  194177. @@ -15,9 +15,9 @@
  194178. depends on IEEE802154_DRIVERS
  194179. ---help---
  194180. Say Y here to enable the fake driver that serves as an example
  194181. - of HardMAC device driver.
  194182. + of HardMAC device driver.
  194183. - This driver can also be built as a module. To do so say M here.
  194184. + This driver can also be built as a module. To do so say M here.
  194185. The module will be called 'fakehard'.
  194186. config IEEE802154_FAKELB
  194187. @@ -31,17 +31,17 @@
  194188. The module will be called 'fakelb'.
  194189. config IEEE802154_AT86RF230
  194190. - depends on IEEE802154_DRIVERS && MAC802154
  194191. - tristate "AT86RF230/231 transceiver driver"
  194192. - depends on SPI
  194193. + depends on IEEE802154_DRIVERS && MAC802154
  194194. + tristate "AT86RF230/231 transceiver driver"
  194195. + depends on SPI
  194196. config IEEE802154_MRF24J40
  194197. - tristate "Microchip MRF24J40 transceiver driver"
  194198. - depends on IEEE802154_DRIVERS && MAC802154
  194199. - depends on SPI
  194200. - ---help---
  194201. - Say Y here to enable the MRF24J20 SPI 802.15.4 wireless
  194202. - controller.
  194203. + tristate "Microchip MRF24J40 transceiver driver"
  194204. + depends on IEEE802154_DRIVERS && MAC802154
  194205. + depends on SPI
  194206. + ---help---
  194207. + Say Y here to enable the MRF24J20 SPI 802.15.4 wireless
  194208. + controller.
  194209. - This driver can also be built as a module. To do so, say M here.
  194210. - the module will be called 'mrf24j40'.
  194211. + This driver can also be built as a module. To do so, say M here.
  194212. + the module will be called 'mrf24j40'.
  194213. diff -Nur linux-3.14.14/drivers/net/phy/at803x.c linux-imx6-3.14/drivers/net/phy/at803x.c
  194214. --- linux-3.14.14/drivers/net/phy/at803x.c 2014-07-28 10:07:25.000000000 -0500
  194215. +++ linux-imx6-3.14/drivers/net/phy/at803x.c 2014-12-08 00:31:53.744418001 -0600
  194216. @@ -27,6 +27,9 @@
  194217. #define AT803X_MMD_ACCESS_CONTROL 0x0D
  194218. #define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E
  194219. #define AT803X_FUNC_DATA 0x4003
  194220. +#define AT803X_INER 0x0012
  194221. +#define AT803X_INER_INIT 0xec00
  194222. +#define AT803X_INSR 0x0013
  194223. #define AT803X_DEBUG_ADDR 0x1D
  194224. #define AT803X_DEBUG_DATA 0x1E
  194225. #define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05
  194226. @@ -141,41 +144,11 @@
  194227. static int at803x_config_init(struct phy_device *phydev)
  194228. {
  194229. - int val;
  194230. int ret;
  194231. - u32 features;
  194232. - features = SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_AUI |
  194233. - SUPPORTED_FIBRE | SUPPORTED_BNC;
  194234. -
  194235. - val = phy_read(phydev, MII_BMSR);
  194236. - if (val < 0)
  194237. - return val;
  194238. -
  194239. - if (val & BMSR_ANEGCAPABLE)
  194240. - features |= SUPPORTED_Autoneg;
  194241. - if (val & BMSR_100FULL)
  194242. - features |= SUPPORTED_100baseT_Full;
  194243. - if (val & BMSR_100HALF)
  194244. - features |= SUPPORTED_100baseT_Half;
  194245. - if (val & BMSR_10FULL)
  194246. - features |= SUPPORTED_10baseT_Full;
  194247. - if (val & BMSR_10HALF)
  194248. - features |= SUPPORTED_10baseT_Half;
  194249. -
  194250. - if (val & BMSR_ESTATEN) {
  194251. - val = phy_read(phydev, MII_ESTATUS);
  194252. - if (val < 0)
  194253. - return val;
  194254. -
  194255. - if (val & ESTATUS_1000_TFULL)
  194256. - features |= SUPPORTED_1000baseT_Full;
  194257. - if (val & ESTATUS_1000_THALF)
  194258. - features |= SUPPORTED_1000baseT_Half;
  194259. - }
  194260. -
  194261. - phydev->supported = features;
  194262. - phydev->advertising = features;
  194263. + ret = genphy_config_init(phydev);
  194264. + if (ret < 0)
  194265. + return ret;
  194266. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
  194267. ret = phy_write(phydev, AT803X_DEBUG_ADDR,
  194268. @@ -191,6 +164,31 @@
  194269. return 0;
  194270. }
  194271. +static int at803x_ack_interrupt(struct phy_device *phydev)
  194272. +{
  194273. + int err;
  194274. +
  194275. + err = phy_read(phydev, AT803X_INSR);
  194276. +
  194277. + return (err < 0) ? err : 0;
  194278. +}
  194279. +
  194280. +static int at803x_config_intr(struct phy_device *phydev)
  194281. +{
  194282. + int err;
  194283. + int value;
  194284. +
  194285. + value = phy_read(phydev, AT803X_INER);
  194286. +
  194287. + if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  194288. + err = phy_write(phydev, AT803X_INER,
  194289. + value | AT803X_INER_INIT);
  194290. + else
  194291. + err = phy_write(phydev, AT803X_INER, 0);
  194292. +
  194293. + return err;
  194294. +}
  194295. +
  194296. static struct phy_driver at803x_driver[] = {
  194297. {
  194298. /* ATHEROS 8035 */
  194299. @@ -240,6 +238,8 @@
  194300. .flags = PHY_HAS_INTERRUPT,
  194301. .config_aneg = genphy_config_aneg,
  194302. .read_status = genphy_read_status,
  194303. + .ack_interrupt = &at803x_ack_interrupt,
  194304. + .config_intr = &at803x_config_intr,
  194305. .driver = {
  194306. .owner = THIS_MODULE,
  194307. },
  194308. @@ -253,8 +253,7 @@
  194309. static void __exit atheros_exit(void)
  194310. {
  194311. - return phy_drivers_unregister(at803x_driver,
  194312. - ARRAY_SIZE(at803x_driver));
  194313. + phy_drivers_unregister(at803x_driver, ARRAY_SIZE(at803x_driver));
  194314. }
  194315. module_init(atheros_init);
  194316. diff -Nur linux-3.14.14/drivers/net/phy/phy_device.c linux-imx6-3.14/drivers/net/phy/phy_device.c
  194317. --- linux-3.14.14/drivers/net/phy/phy_device.c 2014-07-28 10:07:25.000000000 -0500
  194318. +++ linux-imx6-3.14/drivers/net/phy/phy_device.c 2014-12-08 00:31:53.748418001 -0600
  194319. @@ -1029,7 +1029,7 @@
  194320. return 0;
  194321. }
  194322. -static int genphy_config_init(struct phy_device *phydev)
  194323. +int genphy_config_init(struct phy_device *phydev)
  194324. {
  194325. int val;
  194326. u32 features;
  194327. @@ -1075,6 +1075,8 @@
  194328. return 0;
  194329. }
  194330. +EXPORT_SYMBOL(genphy_config_init);
  194331. +
  194332. static int gen10g_config_init(struct phy_device *phydev)
  194333. {
  194334. /* Temporarily just say we support everything */
  194335. diff -Nur linux-3.14.14/drivers/net/phy/smsc.c linux-imx6-3.14/drivers/net/phy/smsc.c
  194336. --- linux-3.14.14/drivers/net/phy/smsc.c 2014-07-28 10:07:25.000000000 -0500
  194337. +++ linux-imx6-3.14/drivers/net/phy/smsc.c 2014-12-08 00:31:53.748418001 -0600
  194338. @@ -249,8 +249,7 @@
  194339. static void __exit smsc_exit(void)
  194340. {
  194341. - return phy_drivers_unregister(smsc_phy_driver,
  194342. - ARRAY_SIZE(smsc_phy_driver));
  194343. + phy_drivers_unregister(smsc_phy_driver, ARRAY_SIZE(smsc_phy_driver));
  194344. }
  194345. MODULE_DESCRIPTION("SMSC PHY driver");
  194346. diff -Nur linux-3.14.14/drivers/net/phy/vitesse.c linux-imx6-3.14/drivers/net/phy/vitesse.c
  194347. --- linux-3.14.14/drivers/net/phy/vitesse.c 2014-07-28 10:07:25.000000000 -0500
  194348. +++ linux-imx6-3.14/drivers/net/phy/vitesse.c 2014-12-08 00:31:53.748418001 -0600
  194349. @@ -319,8 +319,7 @@
  194350. static void __exit vsc82xx_exit(void)
  194351. {
  194352. - return phy_drivers_unregister(vsc82xx_driver,
  194353. - ARRAY_SIZE(vsc82xx_driver));
  194354. + phy_drivers_unregister(vsc82xx_driver, ARRAY_SIZE(vsc82xx_driver));
  194355. }
  194356. module_init(vsc82xx_init);
  194357. diff -Nur linux-3.14.14/drivers/net/veth.c linux-imx6-3.14/drivers/net/veth.c
  194358. --- linux-3.14.14/drivers/net/veth.c 2014-07-28 10:07:25.000000000 -0500
  194359. +++ linux-imx6-3.14/drivers/net/veth.c 2014-12-08 00:31:53.760418001 -0600
  194360. @@ -14,6 +14,7 @@
  194361. #include <linux/etherdevice.h>
  194362. #include <linux/u64_stats_sync.h>
  194363. +#include <net/rtnetlink.h>
  194364. #include <net/dst.h>
  194365. #include <net/xfrm.h>
  194366. #include <linux/veth.h>
  194367. @@ -336,10 +337,9 @@
  194368. nla_peer = data[VETH_INFO_PEER];
  194369. ifmp = nla_data(nla_peer);
  194370. - err = nla_parse(peer_tb, IFLA_MAX,
  194371. - nla_data(nla_peer) + sizeof(struct ifinfomsg),
  194372. - nla_len(nla_peer) - sizeof(struct ifinfomsg),
  194373. - ifla_policy);
  194374. + err = rtnl_nla_parse_ifla(peer_tb,
  194375. + nla_data(nla_peer) + sizeof(struct ifinfomsg),
  194376. + nla_len(nla_peer) - sizeof(struct ifinfomsg));
  194377. if (err < 0)
  194378. return err;
  194379. diff -Nur linux-3.14.14/drivers/net/wireless/ath/ar5523/ar5523.c linux-imx6-3.14/drivers/net/wireless/ath/ar5523/ar5523.c
  194380. --- linux-3.14.14/drivers/net/wireless/ath/ar5523/ar5523.c 2014-07-28 10:07:25.000000000 -0500
  194381. +++ linux-imx6-3.14/drivers/net/wireless/ath/ar5523/ar5523.c 2014-12-08 00:31:53.776418001 -0600
  194382. @@ -1090,7 +1090,8 @@
  194383. return ret;
  194384. }
  194385. -static void ar5523_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  194386. +static void ar5523_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  194387. + u32 queues, bool drop)
  194388. {
  194389. struct ar5523 *ar = hw->priv;
  194390. diff -Nur linux-3.14.14/drivers/net/wireless/ath/ath10k/mac.c linux-imx6-3.14/drivers/net/wireless/ath/ath10k/mac.c
  194391. --- linux-3.14.14/drivers/net/wireless/ath/ath10k/mac.c 2014-07-28 10:07:25.000000000 -0500
  194392. +++ linux-imx6-3.14/drivers/net/wireless/ath/ath10k/mac.c 2014-12-08 00:31:53.780418001 -0600
  194393. @@ -3183,7 +3183,8 @@
  194394. return ret;
  194395. }
  194396. -static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  194397. +static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  194398. + u32 queues, bool drop)
  194399. {
  194400. struct ath10k *ar = hw->priv;
  194401. bool skip;
  194402. diff -Nur linux-3.14.14/drivers/net/wireless/ath/ath6kl/cfg80211.c linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/cfg80211.c
  194403. --- linux-3.14.14/drivers/net/wireless/ath/ath6kl/cfg80211.c 2014-07-28 10:07:25.000000000 -0500
  194404. +++ linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/cfg80211.c 2014-12-08 00:31:53.788418001 -0600
  194405. @@ -790,7 +790,7 @@
  194406. if (nw_type & ADHOC_NETWORK) {
  194407. ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
  194408. nw_type & ADHOC_CREATOR ? "creator" : "joiner");
  194409. - cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
  194410. + cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
  194411. cfg80211_put_bss(ar->wiphy, bss);
  194412. return;
  194413. }
  194414. @@ -861,13 +861,9 @@
  194415. }
  194416. if (vif->nw_type & ADHOC_NETWORK) {
  194417. - if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
  194418. + if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
  194419. ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
  194420. "%s: ath6k not in ibss mode\n", __func__);
  194421. - return;
  194422. - }
  194423. - memset(bssid, 0, ETH_ALEN);
  194424. - cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
  194425. return;
  194426. }
  194427. diff -Nur linux-3.14.14/drivers/net/wireless/ath/ath6kl/hif.h linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/hif.h
  194428. --- linux-3.14.14/drivers/net/wireless/ath/ath6kl/hif.h 2014-07-28 10:07:25.000000000 -0500
  194429. +++ linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/hif.h 2014-12-08 00:31:53.788418001 -0600
  194430. @@ -197,9 +197,9 @@
  194431. /* bounce buffer for upper layers to copy to/from */
  194432. u8 *virt_dma_buf;
  194433. - struct hif_scatter_item scat_list[1];
  194434. -
  194435. u32 scat_q_depth;
  194436. +
  194437. + struct hif_scatter_item scat_list[0];
  194438. };
  194439. struct ath6kl_irq_proc_registers {
  194440. diff -Nur linux-3.14.14/drivers/net/wireless/ath/ath6kl/sdio.c linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/sdio.c
  194441. --- linux-3.14.14/drivers/net/wireless/ath/ath6kl/sdio.c 2014-07-28 10:07:25.000000000 -0500
  194442. +++ linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/sdio.c 2014-12-08 00:31:53.792418001 -0600
  194443. @@ -222,6 +222,7 @@
  194444. struct mmc_data *data)
  194445. {
  194446. struct scatterlist *sg;
  194447. + struct hif_scatter_item *scat_list;
  194448. int i;
  194449. data->blksz = HIF_MBOX_BLOCK_SIZE;
  194450. @@ -240,14 +241,14 @@
  194451. sg = scat_req->sgentries;
  194452. sg_init_table(sg, scat_req->scat_entries);
  194453. + scat_list = &scat_req->scat_list[0];
  194454. +
  194455. /* assemble SG list */
  194456. - for (i = 0; i < scat_req->scat_entries; i++, sg++) {
  194457. + for (i = 0; i < scat_req->scat_entries; i++, sg++, scat_list++) {
  194458. ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n",
  194459. - i, scat_req->scat_list[i].buf,
  194460. - scat_req->scat_list[i].len);
  194461. + i, scat_list->buf, scat_list->len);
  194462. - sg_set_buf(sg, scat_req->scat_list[i].buf,
  194463. - scat_req->scat_list[i].len);
  194464. + sg_set_buf(sg, scat_list->buf, scat_list->len);
  194465. }
  194466. /* set scatter-gather table for request */
  194467. @@ -348,7 +349,7 @@
  194468. int i, scat_req_sz, scat_list_sz, size;
  194469. u8 *virt_buf;
  194470. - scat_list_sz = (n_scat_entry - 1) * sizeof(struct hif_scatter_item);
  194471. + scat_list_sz = n_scat_entry * sizeof(struct hif_scatter_item);
  194472. scat_req_sz = sizeof(*s_req) + scat_list_sz;
  194473. if (!virt_scat)
  194474. diff -Nur linux-3.14.14/drivers/net/wireless/ath/ath9k/main.c linux-imx6-3.14/drivers/net/wireless/ath/ath9k/main.c
  194475. --- linux-3.14.14/drivers/net/wireless/ath/ath9k/main.c 2014-07-28 10:07:25.000000000 -0500
  194476. +++ linux-imx6-3.14/drivers/net/wireless/ath/ath9k/main.c 2014-12-08 00:31:53.808418001 -0600
  194477. @@ -1883,7 +1883,8 @@
  194478. return !!npend;
  194479. }
  194480. -static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  194481. +static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  194482. + u32 queues, bool drop)
  194483. {
  194484. struct ath_softc *sc = hw->priv;
  194485. struct ath_hw *ah = sc->sc_ah;
  194486. diff -Nur linux-3.14.14/drivers/net/wireless/ath/carl9170/main.c linux-imx6-3.14/drivers/net/wireless/ath/carl9170/main.c
  194487. --- linux-3.14.14/drivers/net/wireless/ath/carl9170/main.c 2014-07-28 10:07:25.000000000 -0500
  194488. +++ linux-imx6-3.14/drivers/net/wireless/ath/carl9170/main.c 2014-12-08 00:31:53.816418001 -0600
  194489. @@ -1707,7 +1707,9 @@
  194490. return 0;
  194491. }
  194492. -static void carl9170_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  194493. +static void carl9170_op_flush(struct ieee80211_hw *hw,
  194494. + struct ieee80211_vif *vif,
  194495. + u32 queues, bool drop)
  194496. {
  194497. struct ar9170 *ar = hw->priv;
  194498. unsigned int vid;
  194499. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
  194500. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c 2014-07-28 10:07:25.000000000 -0500
  194501. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c 2014-12-08 00:31:53.836418001 -0600
  194502. @@ -43,7 +43,6 @@
  194503. #include "dhd_bus.h"
  194504. #include "dhd_dbg.h"
  194505. #include "sdio_host.h"
  194506. -#include "sdio_chip.h"
  194507. #define SDIOH_API_ACCESS_RETRY_LIMIT 2
  194508. @@ -54,6 +53,12 @@
  194509. /* Maximum milliseconds to wait for F2 to come up */
  194510. #define SDIO_WAIT_F2RDY 3000
  194511. +#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
  194512. +#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
  194513. +
  194514. +static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
  194515. +module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
  194516. +MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
  194517. static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)
  194518. {
  194519. @@ -264,26 +269,17 @@
  194520. break;
  194521. }
  194522. - if (ret) {
  194523. - /*
  194524. - * SleepCSR register access can fail when
  194525. - * waking up the device so reduce this noise
  194526. - * in the logs.
  194527. - */
  194528. - if (addr != SBSDIO_FUNC1_SLEEPCSR)
  194529. - brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
  194530. - write ? "write" : "read", fn, addr, ret);
  194531. - else
  194532. - brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
  194533. - write ? "write" : "read", fn, addr, ret);
  194534. - }
  194535. + if (ret)
  194536. + brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
  194537. + write ? "write" : "read", fn, addr, ret);
  194538. +
  194539. return ret;
  194540. }
  194541. static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
  194542. u8 regsz, void *data, bool write)
  194543. {
  194544. - u8 func_num;
  194545. + u8 func;
  194546. s32 retry = 0;
  194547. int ret;
  194548. @@ -297,9 +293,9 @@
  194549. * The rest: function 1 silicon backplane core registers
  194550. */
  194551. if ((addr & ~REG_F0_REG_MASK) == 0)
  194552. - func_num = SDIO_FUNC_0;
  194553. + func = SDIO_FUNC_0;
  194554. else
  194555. - func_num = SDIO_FUNC_1;
  194556. + func = SDIO_FUNC_1;
  194557. do {
  194558. if (!write)
  194559. @@ -307,16 +303,26 @@
  194560. /* for retry wait for 1 ms till bus get settled down */
  194561. if (retry)
  194562. usleep_range(1000, 2000);
  194563. - ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz,
  194564. + ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
  194565. data, write);
  194566. } while (ret != 0 && ret != -ENOMEDIUM &&
  194567. retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
  194568. if (ret == -ENOMEDIUM)
  194569. brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM);
  194570. - else if (ret != 0)
  194571. - brcmf_err("failed with %d\n", ret);
  194572. -
  194573. + else if (ret != 0) {
  194574. + /*
  194575. + * SleepCSR register access can fail when
  194576. + * waking up the device so reduce this noise
  194577. + * in the logs.
  194578. + */
  194579. + if (addr != SBSDIO_FUNC1_SLEEPCSR)
  194580. + brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
  194581. + write ? "write" : "read", func, addr, ret);
  194582. + else
  194583. + brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
  194584. + write ? "write" : "read", func, addr, ret);
  194585. + }
  194586. return ret;
  194587. }
  194588. @@ -488,7 +494,6 @@
  194589. struct mmc_request mmc_req;
  194590. struct mmc_command mmc_cmd;
  194591. struct mmc_data mmc_dat;
  194592. - struct sg_table st;
  194593. struct scatterlist *sgl;
  194594. int ret = 0;
  194595. @@ -533,16 +538,11 @@
  194596. pkt_offset = 0;
  194597. pkt_next = target_list->next;
  194598. - if (sg_alloc_table(&st, max_seg_cnt, GFP_KERNEL)) {
  194599. - ret = -ENOMEM;
  194600. - goto exit;
  194601. - }
  194602. -
  194603. memset(&mmc_req, 0, sizeof(struct mmc_request));
  194604. memset(&mmc_cmd, 0, sizeof(struct mmc_command));
  194605. memset(&mmc_dat, 0, sizeof(struct mmc_data));
  194606. - mmc_dat.sg = st.sgl;
  194607. + mmc_dat.sg = sdiodev->sgtable.sgl;
  194608. mmc_dat.blksz = func_blk_sz;
  194609. mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
  194610. mmc_cmd.opcode = SD_IO_RW_EXTENDED;
  194611. @@ -558,7 +558,7 @@
  194612. while (seg_sz) {
  194613. req_sz = 0;
  194614. sg_cnt = 0;
  194615. - sgl = st.sgl;
  194616. + sgl = sdiodev->sgtable.sgl;
  194617. /* prep sg table */
  194618. while (pkt_next != (struct sk_buff *)target_list) {
  194619. pkt_data = pkt_next->data + pkt_offset;
  194620. @@ -640,7 +640,7 @@
  194621. }
  194622. exit:
  194623. - sg_free_table(&st);
  194624. + sg_init_table(sdiodev->sgtable.sgl, sdiodev->sgtable.orig_nents);
  194625. while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
  194626. brcmu_pkt_buf_free_skb(pkt_next);
  194627. @@ -827,7 +827,7 @@
  194628. }
  194629. if (!write)
  194630. memcpy(data, pkt->data, dsize);
  194631. - skb_trim(pkt, dsize);
  194632. + skb_trim(pkt, 0);
  194633. /* Adjust for next transfer (if any) */
  194634. size -= dsize;
  194635. @@ -864,6 +864,29 @@
  194636. return 0;
  194637. }
  194638. +static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
  194639. +{
  194640. + uint nents;
  194641. + int err;
  194642. +
  194643. + if (!sdiodev->sg_support)
  194644. + return;
  194645. +
  194646. + nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, brcmf_sdiod_txglomsz);
  194647. + nents += (nents >> 4) + 1;
  194648. +
  194649. + WARN_ON(nents > sdiodev->max_segment_count);
  194650. +
  194651. + brcmf_dbg(TRACE, "nents=%d\n", nents);
  194652. + err = sg_alloc_table(&sdiodev->sgtable, nents, GFP_KERNEL);
  194653. + if (err < 0) {
  194654. + brcmf_err("allocation failed: disable scatter-gather");
  194655. + sdiodev->sg_support = false;
  194656. + }
  194657. +
  194658. + sdiodev->txglomsz = brcmf_sdiod_txglomsz;
  194659. +}
  194660. +
  194661. static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
  194662. {
  194663. if (sdiodev->bus) {
  194664. @@ -881,6 +904,7 @@
  194665. sdio_disable_func(sdiodev->func[1]);
  194666. sdio_release_host(sdiodev->func[1]);
  194667. + sg_free_table(&sdiodev->sgtable);
  194668. sdiodev->sbwad = 0;
  194669. return 0;
  194670. @@ -936,6 +960,11 @@
  194671. SG_MAX_SINGLE_ALLOC);
  194672. sdiodev->max_segment_size = host->max_seg_size;
  194673. + /* allocate scatter-gather table. sg support
  194674. + * will be disabled upon allocation failure.
  194675. + */
  194676. + brcmf_sdiod_sgtable_alloc(sdiodev);
  194677. +
  194678. /* try to attach to the target device */
  194679. sdiodev->bus = brcmf_sdio_probe(sdiodev);
  194680. if (!sdiodev->bus) {
  194681. @@ -960,6 +989,7 @@
  194682. {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)},
  194683. {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM,
  194684. SDIO_DEVICE_ID_BROADCOM_4335_4339)},
  194685. + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4354)},
  194686. { /* end: all zeroes */ },
  194687. };
  194688. MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
  194689. @@ -1073,9 +1103,7 @@
  194690. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  194691. int ret = 0;
  194692. - brcmf_dbg(SDIO, "\n");
  194693. -
  194694. - atomic_set(&sdiodev->suspend, true);
  194695. + brcmf_dbg(SDIO, "Enter\n");
  194696. sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
  194697. if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
  194698. @@ -1083,9 +1111,12 @@
  194699. return -EINVAL;
  194700. }
  194701. + atomic_set(&sdiodev->suspend, true);
  194702. +
  194703. ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
  194704. if (ret) {
  194705. brcmf_err("Failed to set pm_flags\n");
  194706. + atomic_set(&sdiodev->suspend, false);
  194707. return ret;
  194708. }
  194709. @@ -1099,6 +1130,7 @@
  194710. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  194711. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  194712. + brcmf_dbg(SDIO, "Enter\n");
  194713. brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
  194714. atomic_set(&sdiodev->suspend, false);
  194715. return 0;
  194716. @@ -1115,14 +1147,15 @@
  194717. .remove = brcmf_ops_sdio_remove,
  194718. .name = BRCMFMAC_SDIO_PDATA_NAME,
  194719. .id_table = brcmf_sdmmc_ids,
  194720. -#ifdef CONFIG_PM_SLEEP
  194721. .drv = {
  194722. + .owner = THIS_MODULE,
  194723. +#ifdef CONFIG_PM_SLEEP
  194724. .pm = &brcmf_sdio_pm_ops,
  194725. - },
  194726. #endif /* CONFIG_PM_SLEEP */
  194727. + },
  194728. };
  194729. -static int brcmf_sdio_pd_probe(struct platform_device *pdev)
  194730. +static int __init brcmf_sdio_pd_probe(struct platform_device *pdev)
  194731. {
  194732. brcmf_dbg(SDIO, "Enter\n");
  194733. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/chip.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/chip.c
  194734. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/chip.c 1969-12-31 18:00:00.000000000 -0600
  194735. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/chip.c 2014-12-08 00:31:53.836418001 -0600
  194736. @@ -0,0 +1,1035 @@
  194737. +/*
  194738. + * Copyright (c) 2014 Broadcom Corporation
  194739. + *
  194740. + * Permission to use, copy, modify, and/or distribute this software for any
  194741. + * purpose with or without fee is hereby granted, provided that the above
  194742. + * copyright notice and this permission notice appear in all copies.
  194743. + *
  194744. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  194745. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  194746. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  194747. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  194748. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  194749. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  194750. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  194751. + */
  194752. +#include <linux/kernel.h>
  194753. +#include <linux/delay.h>
  194754. +#include <linux/list.h>
  194755. +#include <linux/ssb/ssb_regs.h>
  194756. +#include <linux/bcma/bcma.h>
  194757. +#include <linux/bcma/bcma_regs.h>
  194758. +
  194759. +#include <defs.h>
  194760. +#include <soc.h>
  194761. +#include <brcm_hw_ids.h>
  194762. +#include <brcmu_utils.h>
  194763. +#include <chipcommon.h>
  194764. +#include "dhd_dbg.h"
  194765. +#include "chip.h"
  194766. +
  194767. +/* SOC Interconnect types (aka chip types) */
  194768. +#define SOCI_SB 0
  194769. +#define SOCI_AI 1
  194770. +
  194771. +/* PL-368 DMP definitions */
  194772. +#define DMP_DESC_TYPE_MSK 0x0000000F
  194773. +#define DMP_DESC_EMPTY 0x00000000
  194774. +#define DMP_DESC_VALID 0x00000001
  194775. +#define DMP_DESC_COMPONENT 0x00000001
  194776. +#define DMP_DESC_MASTER_PORT 0x00000003
  194777. +#define DMP_DESC_ADDRESS 0x00000005
  194778. +#define DMP_DESC_ADDRSIZE_GT32 0x00000008
  194779. +#define DMP_DESC_EOT 0x0000000F
  194780. +
  194781. +#define DMP_COMP_DESIGNER 0xFFF00000
  194782. +#define DMP_COMP_DESIGNER_S 20
  194783. +#define DMP_COMP_PARTNUM 0x000FFF00
  194784. +#define DMP_COMP_PARTNUM_S 8
  194785. +#define DMP_COMP_CLASS 0x000000F0
  194786. +#define DMP_COMP_CLASS_S 4
  194787. +#define DMP_COMP_REVISION 0xFF000000
  194788. +#define DMP_COMP_REVISION_S 24
  194789. +#define DMP_COMP_NUM_SWRAP 0x00F80000
  194790. +#define DMP_COMP_NUM_SWRAP_S 19
  194791. +#define DMP_COMP_NUM_MWRAP 0x0007C000
  194792. +#define DMP_COMP_NUM_MWRAP_S 14
  194793. +#define DMP_COMP_NUM_SPORT 0x00003E00
  194794. +#define DMP_COMP_NUM_SPORT_S 9
  194795. +#define DMP_COMP_NUM_MPORT 0x000001F0
  194796. +#define DMP_COMP_NUM_MPORT_S 4
  194797. +
  194798. +#define DMP_MASTER_PORT_UID 0x0000FF00
  194799. +#define DMP_MASTER_PORT_UID_S 8
  194800. +#define DMP_MASTER_PORT_NUM 0x000000F0
  194801. +#define DMP_MASTER_PORT_NUM_S 4
  194802. +
  194803. +#define DMP_SLAVE_ADDR_BASE 0xFFFFF000
  194804. +#define DMP_SLAVE_ADDR_BASE_S 12
  194805. +#define DMP_SLAVE_PORT_NUM 0x00000F00
  194806. +#define DMP_SLAVE_PORT_NUM_S 8
  194807. +#define DMP_SLAVE_TYPE 0x000000C0
  194808. +#define DMP_SLAVE_TYPE_S 6
  194809. +#define DMP_SLAVE_TYPE_SLAVE 0
  194810. +#define DMP_SLAVE_TYPE_BRIDGE 1
  194811. +#define DMP_SLAVE_TYPE_SWRAP 2
  194812. +#define DMP_SLAVE_TYPE_MWRAP 3
  194813. +#define DMP_SLAVE_SIZE_TYPE 0x00000030
  194814. +#define DMP_SLAVE_SIZE_TYPE_S 4
  194815. +#define DMP_SLAVE_SIZE_4K 0
  194816. +#define DMP_SLAVE_SIZE_8K 1
  194817. +#define DMP_SLAVE_SIZE_16K 2
  194818. +#define DMP_SLAVE_SIZE_DESC 3
  194819. +
  194820. +/* EROM CompIdentB */
  194821. +#define CIB_REV_MASK 0xff000000
  194822. +#define CIB_REV_SHIFT 24
  194823. +
  194824. +/* ARM CR4 core specific control flag bits */
  194825. +#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
  194826. +
  194827. +/* D11 core specific control flag bits */
  194828. +#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
  194829. +#define D11_BCMA_IOCTL_PHYRESET 0x0008
  194830. +
  194831. +/* chip core base & ramsize */
  194832. +/* bcm4329 */
  194833. +/* SDIO device core, ID 0x829 */
  194834. +#define BCM4329_CORE_BUS_BASE 0x18011000
  194835. +/* internal memory core, ID 0x80e */
  194836. +#define BCM4329_CORE_SOCRAM_BASE 0x18003000
  194837. +/* ARM Cortex M3 core, ID 0x82a */
  194838. +#define BCM4329_CORE_ARM_BASE 0x18002000
  194839. +#define BCM4329_RAMSIZE 0x48000
  194840. +
  194841. +/* bcm43143 */
  194842. +/* SDIO device core */
  194843. +#define BCM43143_CORE_BUS_BASE 0x18002000
  194844. +/* internal memory core */
  194845. +#define BCM43143_CORE_SOCRAM_BASE 0x18004000
  194846. +/* ARM Cortex M3 core, ID 0x82a */
  194847. +#define BCM43143_CORE_ARM_BASE 0x18003000
  194848. +#define BCM43143_RAMSIZE 0x70000
  194849. +
  194850. +#define CORE_SB(base, field) \
  194851. + (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
  194852. +#define SBCOREREV(sbidh) \
  194853. + ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
  194854. + ((sbidh) & SSB_IDHIGH_RCLO))
  194855. +
  194856. +struct sbconfig {
  194857. + u32 PAD[2];
  194858. + u32 sbipsflag; /* initiator port ocp slave flag */
  194859. + u32 PAD[3];
  194860. + u32 sbtpsflag; /* target port ocp slave flag */
  194861. + u32 PAD[11];
  194862. + u32 sbtmerrloga; /* (sonics >= 2.3) */
  194863. + u32 PAD;
  194864. + u32 sbtmerrlog; /* (sonics >= 2.3) */
  194865. + u32 PAD[3];
  194866. + u32 sbadmatch3; /* address match3 */
  194867. + u32 PAD;
  194868. + u32 sbadmatch2; /* address match2 */
  194869. + u32 PAD;
  194870. + u32 sbadmatch1; /* address match1 */
  194871. + u32 PAD[7];
  194872. + u32 sbimstate; /* initiator agent state */
  194873. + u32 sbintvec; /* interrupt mask */
  194874. + u32 sbtmstatelow; /* target state */
  194875. + u32 sbtmstatehigh; /* target state */
  194876. + u32 sbbwa0; /* bandwidth allocation table0 */
  194877. + u32 PAD;
  194878. + u32 sbimconfiglow; /* initiator configuration */
  194879. + u32 sbimconfighigh; /* initiator configuration */
  194880. + u32 sbadmatch0; /* address match0 */
  194881. + u32 PAD;
  194882. + u32 sbtmconfiglow; /* target configuration */
  194883. + u32 sbtmconfighigh; /* target configuration */
  194884. + u32 sbbconfig; /* broadcast configuration */
  194885. + u32 PAD;
  194886. + u32 sbbstate; /* broadcast state */
  194887. + u32 PAD[3];
  194888. + u32 sbactcnfg; /* activate configuration */
  194889. + u32 PAD[3];
  194890. + u32 sbflagst; /* current sbflags */
  194891. + u32 PAD[3];
  194892. + u32 sbidlow; /* identification */
  194893. + u32 sbidhigh; /* identification */
  194894. +};
  194895. +
  194896. +struct brcmf_core_priv {
  194897. + struct brcmf_core pub;
  194898. + u32 wrapbase;
  194899. + struct list_head list;
  194900. + struct brcmf_chip_priv *chip;
  194901. +};
  194902. +
  194903. +/* ARM CR4 core specific control flag bits */
  194904. +#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
  194905. +
  194906. +/* D11 core specific control flag bits */
  194907. +#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
  194908. +#define D11_BCMA_IOCTL_PHYRESET 0x0008
  194909. +
  194910. +struct brcmf_chip_priv {
  194911. + struct brcmf_chip pub;
  194912. + const struct brcmf_buscore_ops *ops;
  194913. + void *ctx;
  194914. + /* assured first core is chipcommon, second core is buscore */
  194915. + struct list_head cores;
  194916. + u16 num_cores;
  194917. +
  194918. + bool (*iscoreup)(struct brcmf_core_priv *core);
  194919. + void (*coredisable)(struct brcmf_core_priv *core, u32 prereset,
  194920. + u32 reset);
  194921. + void (*resetcore)(struct brcmf_core_priv *core, u32 prereset, u32 reset,
  194922. + u32 postreset);
  194923. +};
  194924. +
  194925. +static void brcmf_chip_sb_corerev(struct brcmf_chip_priv *ci,
  194926. + struct brcmf_core *core)
  194927. +{
  194928. + u32 regdata;
  194929. +
  194930. + regdata = ci->ops->read32(ci->ctx, CORE_SB(core->base, sbidhigh));
  194931. + core->rev = SBCOREREV(regdata);
  194932. +}
  194933. +
  194934. +static bool brcmf_chip_sb_iscoreup(struct brcmf_core_priv *core)
  194935. +{
  194936. + struct brcmf_chip_priv *ci;
  194937. + u32 regdata;
  194938. + u32 address;
  194939. +
  194940. + ci = core->chip;
  194941. + address = CORE_SB(core->pub.base, sbtmstatelow);
  194942. + regdata = ci->ops->read32(ci->ctx, address);
  194943. + regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
  194944. + SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
  194945. + return SSB_TMSLOW_CLOCK == regdata;
  194946. +}
  194947. +
  194948. +static bool brcmf_chip_ai_iscoreup(struct brcmf_core_priv *core)
  194949. +{
  194950. + struct brcmf_chip_priv *ci;
  194951. + u32 regdata;
  194952. + bool ret;
  194953. +
  194954. + ci = core->chip;
  194955. + regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  194956. + ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
  194957. +
  194958. + regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
  194959. + ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
  194960. +
  194961. + return ret;
  194962. +}
  194963. +
  194964. +static void brcmf_chip_sb_coredisable(struct brcmf_core_priv *core,
  194965. + u32 prereset, u32 reset)
  194966. +{
  194967. + struct brcmf_chip_priv *ci;
  194968. + u32 val, base;
  194969. +
  194970. + ci = core->chip;
  194971. + base = core->pub.base;
  194972. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  194973. + if (val & SSB_TMSLOW_RESET)
  194974. + return;
  194975. +
  194976. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  194977. + if ((val & SSB_TMSLOW_CLOCK) != 0) {
  194978. + /*
  194979. + * set target reject and spin until busy is clear
  194980. + * (preserve core-specific bits)
  194981. + */
  194982. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  194983. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  194984. + val | SSB_TMSLOW_REJECT);
  194985. +
  194986. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  194987. + udelay(1);
  194988. + SPINWAIT((ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh))
  194989. + & SSB_TMSHIGH_BUSY), 100000);
  194990. +
  194991. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh));
  194992. + if (val & SSB_TMSHIGH_BUSY)
  194993. + brcmf_err("core state still busy\n");
  194994. +
  194995. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
  194996. + if (val & SSB_IDLOW_INITIATOR) {
  194997. + val = ci->ops->read32(ci->ctx,
  194998. + CORE_SB(base, sbimstate));
  194999. + val |= SSB_IMSTATE_REJECT;
  195000. + ci->ops->write32(ci->ctx,
  195001. + CORE_SB(base, sbimstate), val);
  195002. + val = ci->ops->read32(ci->ctx,
  195003. + CORE_SB(base, sbimstate));
  195004. + udelay(1);
  195005. + SPINWAIT((ci->ops->read32(ci->ctx,
  195006. + CORE_SB(base, sbimstate)) &
  195007. + SSB_IMSTATE_BUSY), 100000);
  195008. + }
  195009. +
  195010. + /* set reset and reject while enabling the clocks */
  195011. + val = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
  195012. + SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
  195013. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow), val);
  195014. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  195015. + udelay(10);
  195016. +
  195017. + /* clear the initiator reject bit */
  195018. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
  195019. + if (val & SSB_IDLOW_INITIATOR) {
  195020. + val = ci->ops->read32(ci->ctx,
  195021. + CORE_SB(base, sbimstate));
  195022. + val &= ~SSB_IMSTATE_REJECT;
  195023. + ci->ops->write32(ci->ctx,
  195024. + CORE_SB(base, sbimstate), val);
  195025. + }
  195026. + }
  195027. +
  195028. + /* leave reset and reject asserted */
  195029. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  195030. + (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
  195031. + udelay(1);
  195032. +}
  195033. +
  195034. +static void brcmf_chip_ai_coredisable(struct brcmf_core_priv *core,
  195035. + u32 prereset, u32 reset)
  195036. +{
  195037. + struct brcmf_chip_priv *ci;
  195038. + u32 regdata;
  195039. +
  195040. + ci = core->chip;
  195041. +
  195042. + /* if core is already in reset, skip reset */
  195043. + regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
  195044. + if ((regdata & BCMA_RESET_CTL_RESET) != 0)
  195045. + goto in_reset_configure;
  195046. +
  195047. + /* configure reset */
  195048. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
  195049. + prereset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
  195050. + ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  195051. +
  195052. + /* put in reset */
  195053. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_RESET_CTL,
  195054. + BCMA_RESET_CTL_RESET);
  195055. + usleep_range(10, 20);
  195056. +
  195057. + /* wait till reset is 1 */
  195058. + SPINWAIT(ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) !=
  195059. + BCMA_RESET_CTL_RESET, 300);
  195060. +
  195061. +in_reset_configure:
  195062. + /* in-reset configure */
  195063. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
  195064. + reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
  195065. + ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  195066. +}
  195067. +
  195068. +static void brcmf_chip_sb_resetcore(struct brcmf_core_priv *core, u32 prereset,
  195069. + u32 reset, u32 postreset)
  195070. +{
  195071. + struct brcmf_chip_priv *ci;
  195072. + u32 regdata;
  195073. + u32 base;
  195074. +
  195075. + ci = core->chip;
  195076. + base = core->pub.base;
  195077. + /*
  195078. + * Must do the disable sequence first to work for
  195079. + * arbitrary current core state.
  195080. + */
  195081. + brcmf_chip_sb_coredisable(core, 0, 0);
  195082. +
  195083. + /*
  195084. + * Now do the initialization sequence.
  195085. + * set reset while enabling the clock and
  195086. + * forcing them on throughout the core
  195087. + */
  195088. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  195089. + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
  195090. + SSB_TMSLOW_RESET);
  195091. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  195092. + udelay(1);
  195093. +
  195094. + /* clear any serror */
  195095. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh));
  195096. + if (regdata & SSB_TMSHIGH_SERR)
  195097. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatehigh), 0);
  195098. +
  195099. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbimstate));
  195100. + if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) {
  195101. + regdata &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO);
  195102. + ci->ops->write32(ci->ctx, CORE_SB(base, sbimstate), regdata);
  195103. + }
  195104. +
  195105. + /* clear reset and allow it to propagate throughout the core */
  195106. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  195107. + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK);
  195108. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  195109. + udelay(1);
  195110. +
  195111. + /* leave clock enabled */
  195112. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  195113. + SSB_TMSLOW_CLOCK);
  195114. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  195115. + udelay(1);
  195116. +}
  195117. +
  195118. +static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset,
  195119. + u32 reset, u32 postreset)
  195120. +{
  195121. + struct brcmf_chip_priv *ci;
  195122. + int count;
  195123. +
  195124. + ci = core->chip;
  195125. +
  195126. + /* must disable first to work for arbitrary current core state */
  195127. + brcmf_chip_ai_coredisable(core, prereset, reset);
  195128. +
  195129. + count = 0;
  195130. + while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) &
  195131. + BCMA_RESET_CTL_RESET) {
  195132. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_RESET_CTL, 0);
  195133. + count++;
  195134. + if (count > 50)
  195135. + break;
  195136. + usleep_range(40, 60);
  195137. + }
  195138. +
  195139. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
  195140. + postreset | BCMA_IOCTL_CLK);
  195141. + ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  195142. +}
  195143. +
  195144. +static char *brcmf_chip_name(uint chipid, char *buf, uint len)
  195145. +{
  195146. + const char *fmt;
  195147. +
  195148. + fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
  195149. + snprintf(buf, len, fmt, chipid);
  195150. + return buf;
  195151. +}
  195152. +
  195153. +static struct brcmf_core *brcmf_chip_add_core(struct brcmf_chip_priv *ci,
  195154. + u16 coreid, u32 base,
  195155. + u32 wrapbase)
  195156. +{
  195157. + struct brcmf_core_priv *core;
  195158. +
  195159. + core = kzalloc(sizeof(*core), GFP_KERNEL);
  195160. + if (!core)
  195161. + return ERR_PTR(-ENOMEM);
  195162. +
  195163. + core->pub.id = coreid;
  195164. + core->pub.base = base;
  195165. + core->chip = ci;
  195166. + core->wrapbase = wrapbase;
  195167. +
  195168. + list_add_tail(&core->list, &ci->cores);
  195169. + return &core->pub;
  195170. +}
  195171. +
  195172. +#ifdef DEBUG
  195173. +/* safety check for chipinfo */
  195174. +static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
  195175. +{
  195176. + struct brcmf_core_priv *core;
  195177. + bool need_socram = false;
  195178. + bool has_socram = false;
  195179. + int idx = 1;
  195180. +
  195181. + list_for_each_entry(core, &ci->cores, list) {
  195182. + brcmf_dbg(INFO, " [%-2d] core 0x%x:%-2d base 0x%08x wrap 0x%08x\n",
  195183. + idx++, core->pub.id, core->pub.rev, core->pub.base,
  195184. + core->wrapbase);
  195185. +
  195186. + switch (core->pub.id) {
  195187. + case BCMA_CORE_ARM_CM3:
  195188. + need_socram = true;
  195189. + break;
  195190. + case BCMA_CORE_INTERNAL_MEM:
  195191. + has_socram = true;
  195192. + break;
  195193. + case BCMA_CORE_ARM_CR4:
  195194. + if (ci->pub.rambase == 0) {
  195195. + brcmf_err("RAM base not provided with ARM CR4 core\n");
  195196. + return -ENOMEM;
  195197. + }
  195198. + break;
  195199. + default:
  195200. + break;
  195201. + }
  195202. + }
  195203. +
  195204. + /* check RAM core presence for ARM CM3 core */
  195205. + if (need_socram && !has_socram) {
  195206. + brcmf_err("RAM core not provided with ARM CM3 core\n");
  195207. + return -ENODEV;
  195208. + }
  195209. + return 0;
  195210. +}
  195211. +#else /* DEBUG */
  195212. +static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
  195213. +{
  195214. + return 0;
  195215. +}
  195216. +#endif
  195217. +
  195218. +static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
  195219. +{
  195220. + switch (ci->pub.chip) {
  195221. + case BCM4329_CHIP_ID:
  195222. + ci->pub.ramsize = BCM4329_RAMSIZE;
  195223. + break;
  195224. + case BCM43143_CHIP_ID:
  195225. + ci->pub.ramsize = BCM43143_RAMSIZE;
  195226. + break;
  195227. + case BCM43241_CHIP_ID:
  195228. + ci->pub.ramsize = 0x90000;
  195229. + break;
  195230. + case BCM4330_CHIP_ID:
  195231. + ci->pub.ramsize = 0x48000;
  195232. + break;
  195233. + case BCM4334_CHIP_ID:
  195234. + ci->pub.ramsize = 0x80000;
  195235. + break;
  195236. + case BCM4335_CHIP_ID:
  195237. + ci->pub.ramsize = 0xc0000;
  195238. + ci->pub.rambase = 0x180000;
  195239. + break;
  195240. + case BCM43362_CHIP_ID:
  195241. + ci->pub.ramsize = 0x3c000;
  195242. + break;
  195243. + case BCM4339_CHIP_ID:
  195244. + case BCM4354_CHIP_ID:
  195245. + ci->pub.ramsize = 0xc0000;
  195246. + ci->pub.rambase = 0x180000;
  195247. + break;
  195248. + default:
  195249. + brcmf_err("unknown chip: %s\n", ci->pub.name);
  195250. + break;
  195251. + }
  195252. +}
  195253. +
  195254. +static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
  195255. + u8 *type)
  195256. +{
  195257. + u32 val;
  195258. +
  195259. + /* read next descriptor */
  195260. + val = ci->ops->read32(ci->ctx, *eromaddr);
  195261. + *eromaddr += 4;
  195262. +
  195263. + if (!type)
  195264. + return val;
  195265. +
  195266. + /* determine descriptor type */
  195267. + *type = (val & DMP_DESC_TYPE_MSK);
  195268. + if ((*type & ~DMP_DESC_ADDRSIZE_GT32) == DMP_DESC_ADDRESS)
  195269. + *type = DMP_DESC_ADDRESS;
  195270. +
  195271. + return val;
  195272. +}
  195273. +
  195274. +static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv *ci, u32 *eromaddr,
  195275. + u32 *regbase, u32 *wrapbase)
  195276. +{
  195277. + u8 desc;
  195278. + u32 val;
  195279. + u8 mpnum = 0;
  195280. + u8 stype, sztype, wraptype;
  195281. +
  195282. + *regbase = 0;
  195283. + *wrapbase = 0;
  195284. +
  195285. + val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
  195286. + if (desc == DMP_DESC_MASTER_PORT) {
  195287. + mpnum = (val & DMP_MASTER_PORT_NUM) >> DMP_MASTER_PORT_NUM_S;
  195288. + wraptype = DMP_SLAVE_TYPE_MWRAP;
  195289. + } else if (desc == DMP_DESC_ADDRESS) {
  195290. + /* revert erom address */
  195291. + *eromaddr -= 4;
  195292. + wraptype = DMP_SLAVE_TYPE_SWRAP;
  195293. + } else {
  195294. + *eromaddr -= 4;
  195295. + return -EILSEQ;
  195296. + }
  195297. +
  195298. + do {
  195299. + /* locate address descriptor */
  195300. + do {
  195301. + val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
  195302. + /* unexpected table end */
  195303. + if (desc == DMP_DESC_EOT) {
  195304. + *eromaddr -= 4;
  195305. + return -EFAULT;
  195306. + }
  195307. + } while (desc != DMP_DESC_ADDRESS);
  195308. +
  195309. + /* skip upper 32-bit address descriptor */
  195310. + if (val & DMP_DESC_ADDRSIZE_GT32)
  195311. + brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
  195312. +
  195313. + sztype = (val & DMP_SLAVE_SIZE_TYPE) >> DMP_SLAVE_SIZE_TYPE_S;
  195314. +
  195315. + /* next size descriptor can be skipped */
  195316. + if (sztype == DMP_SLAVE_SIZE_DESC) {
  195317. + val = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
  195318. + /* skip upper size descriptor if present */
  195319. + if (val & DMP_DESC_ADDRSIZE_GT32)
  195320. + brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
  195321. + }
  195322. +
  195323. + /* only look for 4K register regions */
  195324. + if (sztype != DMP_SLAVE_SIZE_4K)
  195325. + continue;
  195326. +
  195327. + stype = (val & DMP_SLAVE_TYPE) >> DMP_SLAVE_TYPE_S;
  195328. +
  195329. + /* only regular slave and wrapper */
  195330. + if (*regbase == 0 && stype == DMP_SLAVE_TYPE_SLAVE)
  195331. + *regbase = val & DMP_SLAVE_ADDR_BASE;
  195332. + if (*wrapbase == 0 && stype == wraptype)
  195333. + *wrapbase = val & DMP_SLAVE_ADDR_BASE;
  195334. + } while (*regbase == 0 || *wrapbase == 0);
  195335. +
  195336. + return 0;
  195337. +}
  195338. +
  195339. +static
  195340. +int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci)
  195341. +{
  195342. + struct brcmf_core *core;
  195343. + u32 eromaddr;
  195344. + u8 desc_type = 0;
  195345. + u32 val;
  195346. + u16 id;
  195347. + u8 nmp, nsp, nmw, nsw, rev;
  195348. + u32 base, wrap;
  195349. + int err;
  195350. +
  195351. + eromaddr = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, eromptr));
  195352. +
  195353. + while (desc_type != DMP_DESC_EOT) {
  195354. + val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
  195355. + if (!(val & DMP_DESC_VALID))
  195356. + continue;
  195357. +
  195358. + if (desc_type == DMP_DESC_EMPTY)
  195359. + continue;
  195360. +
  195361. + /* need a component descriptor */
  195362. + if (desc_type != DMP_DESC_COMPONENT)
  195363. + continue;
  195364. +
  195365. + id = (val & DMP_COMP_PARTNUM) >> DMP_COMP_PARTNUM_S;
  195366. +
  195367. + /* next descriptor must be component as well */
  195368. + val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
  195369. + if (WARN_ON((val & DMP_DESC_TYPE_MSK) != DMP_DESC_COMPONENT))
  195370. + return -EFAULT;
  195371. +
  195372. + /* only look at cores with master port(s) */
  195373. + nmp = (val & DMP_COMP_NUM_MPORT) >> DMP_COMP_NUM_MPORT_S;
  195374. + nsp = (val & DMP_COMP_NUM_SPORT) >> DMP_COMP_NUM_SPORT_S;
  195375. + nmw = (val & DMP_COMP_NUM_MWRAP) >> DMP_COMP_NUM_MWRAP_S;
  195376. + nsw = (val & DMP_COMP_NUM_SWRAP) >> DMP_COMP_NUM_SWRAP_S;
  195377. + rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S;
  195378. +
  195379. + /* need core with ports */
  195380. + if (nmw + nsw == 0)
  195381. + continue;
  195382. +
  195383. + /* try to obtain register address info */
  195384. + err = brcmf_chip_dmp_get_regaddr(ci, &eromaddr, &base, &wrap);
  195385. + if (err)
  195386. + continue;
  195387. +
  195388. + /* finally a core to be added */
  195389. + core = brcmf_chip_add_core(ci, id, base, wrap);
  195390. + if (IS_ERR(core))
  195391. + return PTR_ERR(core);
  195392. +
  195393. + core->rev = rev;
  195394. + }
  195395. +
  195396. + return 0;
  195397. +}
  195398. +
  195399. +static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
  195400. +{
  195401. + struct brcmf_core *core;
  195402. + u32 regdata;
  195403. + u32 socitype;
  195404. +
  195405. + /* Get CC core rev
  195406. + * Chipid is assume to be at offset 0 from SI_ENUM_BASE
  195407. + * For different chiptypes or old sdio hosts w/o chipcommon,
  195408. + * other ways of recognition should be added here.
  195409. + */
  195410. + regdata = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, chipid));
  195411. + ci->pub.chip = regdata & CID_ID_MASK;
  195412. + ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
  195413. + socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
  195414. +
  195415. + brcmf_chip_name(ci->pub.chip, ci->pub.name, sizeof(ci->pub.name));
  195416. + brcmf_dbg(INFO, "found %s chip: BCM%s, rev=%d\n",
  195417. + socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name,
  195418. + ci->pub.chiprev);
  195419. +
  195420. + if (socitype == SOCI_SB) {
  195421. + if (ci->pub.chip != BCM4329_CHIP_ID) {
  195422. + brcmf_err("SB chip is not supported\n");
  195423. + return -ENODEV;
  195424. + }
  195425. + ci->iscoreup = brcmf_chip_sb_iscoreup;
  195426. + ci->coredisable = brcmf_chip_sb_coredisable;
  195427. + ci->resetcore = brcmf_chip_sb_resetcore;
  195428. +
  195429. + core = brcmf_chip_add_core(ci, BCMA_CORE_CHIPCOMMON,
  195430. + SI_ENUM_BASE, 0);
  195431. + brcmf_chip_sb_corerev(ci, core);
  195432. + core = brcmf_chip_add_core(ci, BCMA_CORE_SDIO_DEV,
  195433. + BCM4329_CORE_BUS_BASE, 0);
  195434. + brcmf_chip_sb_corerev(ci, core);
  195435. + core = brcmf_chip_add_core(ci, BCMA_CORE_INTERNAL_MEM,
  195436. + BCM4329_CORE_SOCRAM_BASE, 0);
  195437. + brcmf_chip_sb_corerev(ci, core);
  195438. + core = brcmf_chip_add_core(ci, BCMA_CORE_ARM_CM3,
  195439. + BCM4329_CORE_ARM_BASE, 0);
  195440. + brcmf_chip_sb_corerev(ci, core);
  195441. +
  195442. + core = brcmf_chip_add_core(ci, BCMA_CORE_80211, 0x18001000, 0);
  195443. + brcmf_chip_sb_corerev(ci, core);
  195444. + } else if (socitype == SOCI_AI) {
  195445. + ci->iscoreup = brcmf_chip_ai_iscoreup;
  195446. + ci->coredisable = brcmf_chip_ai_coredisable;
  195447. + ci->resetcore = brcmf_chip_ai_resetcore;
  195448. +
  195449. + brcmf_chip_dmp_erom_scan(ci);
  195450. + } else {
  195451. + brcmf_err("chip backplane type %u is not supported\n",
  195452. + socitype);
  195453. + return -ENODEV;
  195454. + }
  195455. +
  195456. + brcmf_chip_get_raminfo(ci);
  195457. +
  195458. + return brcmf_chip_cores_check(ci);
  195459. +}
  195460. +
  195461. +static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
  195462. +{
  195463. + struct brcmf_core *core;
  195464. + struct brcmf_core_priv *cr4;
  195465. + u32 val;
  195466. +
  195467. +
  195468. + core = brcmf_chip_get_core(&chip->pub, id);
  195469. + if (!core)
  195470. + return;
  195471. +
  195472. + switch (id) {
  195473. + case BCMA_CORE_ARM_CM3:
  195474. + brcmf_chip_coredisable(core, 0, 0);
  195475. + break;
  195476. + case BCMA_CORE_ARM_CR4:
  195477. + cr4 = container_of(core, struct brcmf_core_priv, pub);
  195478. +
  195479. + /* clear all IOCTL bits except HALT bit */
  195480. + val = chip->ops->read32(chip->ctx, cr4->wrapbase + BCMA_IOCTL);
  195481. + val &= ARMCR4_BCMA_IOCTL_CPUHALT;
  195482. + brcmf_chip_resetcore(core, val, ARMCR4_BCMA_IOCTL_CPUHALT,
  195483. + ARMCR4_BCMA_IOCTL_CPUHALT);
  195484. + break;
  195485. + default:
  195486. + brcmf_err("unknown id: %u\n", id);
  195487. + break;
  195488. + }
  195489. +}
  195490. +
  195491. +static int brcmf_chip_setup(struct brcmf_chip_priv *chip)
  195492. +{
  195493. + struct brcmf_chip *pub;
  195494. + struct brcmf_core_priv *cc;
  195495. + u32 base;
  195496. + u32 val;
  195497. + int ret = 0;
  195498. +
  195499. + pub = &chip->pub;
  195500. + cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
  195501. + base = cc->pub.base;
  195502. +
  195503. + /* get chipcommon capabilites */
  195504. + pub->cc_caps = chip->ops->read32(chip->ctx,
  195505. + CORE_CC_REG(base, capabilities));
  195506. +
  195507. + /* get pmu caps & rev */
  195508. + if (pub->cc_caps & CC_CAP_PMU) {
  195509. + val = chip->ops->read32(chip->ctx,
  195510. + CORE_CC_REG(base, pmucapabilities));
  195511. + pub->pmurev = val & PCAP_REV_MASK;
  195512. + pub->pmucaps = val;
  195513. + }
  195514. +
  195515. + brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, pmucaps=0x%x\n",
  195516. + cc->pub.rev, pub->pmurev, pub->pmucaps);
  195517. +
  195518. + /* execute bus core specific setup */
  195519. + if (chip->ops->setup)
  195520. + ret = chip->ops->setup(chip->ctx, pub);
  195521. +
  195522. + /*
  195523. + * Make sure any on-chip ARM is off (in case strapping is wrong),
  195524. + * or downloaded code was already running.
  195525. + */
  195526. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
  195527. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
  195528. + return ret;
  195529. +}
  195530. +
  195531. +struct brcmf_chip *brcmf_chip_attach(void *ctx,
  195532. + const struct brcmf_buscore_ops *ops)
  195533. +{
  195534. + struct brcmf_chip_priv *chip;
  195535. + int err = 0;
  195536. +
  195537. + if (WARN_ON(!ops->read32))
  195538. + err = -EINVAL;
  195539. + if (WARN_ON(!ops->write32))
  195540. + err = -EINVAL;
  195541. + if (WARN_ON(!ops->prepare))
  195542. + err = -EINVAL;
  195543. + if (WARN_ON(!ops->exit_dl))
  195544. + err = -EINVAL;
  195545. + if (err < 0)
  195546. + return ERR_PTR(-EINVAL);
  195547. +
  195548. + chip = kzalloc(sizeof(*chip), GFP_KERNEL);
  195549. + if (!chip)
  195550. + return ERR_PTR(-ENOMEM);
  195551. +
  195552. + INIT_LIST_HEAD(&chip->cores);
  195553. + chip->num_cores = 0;
  195554. + chip->ops = ops;
  195555. + chip->ctx = ctx;
  195556. +
  195557. + err = ops->prepare(ctx);
  195558. + if (err < 0)
  195559. + goto fail;
  195560. +
  195561. + err = brcmf_chip_recognition(chip);
  195562. + if (err < 0)
  195563. + goto fail;
  195564. +
  195565. + err = brcmf_chip_setup(chip);
  195566. + if (err < 0)
  195567. + goto fail;
  195568. +
  195569. + return &chip->pub;
  195570. +
  195571. +fail:
  195572. + brcmf_chip_detach(&chip->pub);
  195573. + return ERR_PTR(err);
  195574. +}
  195575. +
  195576. +void brcmf_chip_detach(struct brcmf_chip *pub)
  195577. +{
  195578. + struct brcmf_chip_priv *chip;
  195579. + struct brcmf_core_priv *core;
  195580. + struct brcmf_core_priv *tmp;
  195581. +
  195582. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195583. + list_for_each_entry_safe(core, tmp, &chip->cores, list) {
  195584. + list_del(&core->list);
  195585. + kfree(core);
  195586. + }
  195587. + kfree(chip);
  195588. +}
  195589. +
  195590. +struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
  195591. +{
  195592. + struct brcmf_chip_priv *chip;
  195593. + struct brcmf_core_priv *core;
  195594. +
  195595. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195596. + list_for_each_entry(core, &chip->cores, list)
  195597. + if (core->pub.id == coreid)
  195598. + return &core->pub;
  195599. +
  195600. + return NULL;
  195601. +}
  195602. +
  195603. +struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *pub)
  195604. +{
  195605. + struct brcmf_chip_priv *chip;
  195606. + struct brcmf_core_priv *cc;
  195607. +
  195608. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195609. + cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
  195610. + if (WARN_ON(!cc || cc->pub.id != BCMA_CORE_CHIPCOMMON))
  195611. + return brcmf_chip_get_core(pub, BCMA_CORE_CHIPCOMMON);
  195612. + return &cc->pub;
  195613. +}
  195614. +
  195615. +bool brcmf_chip_iscoreup(struct brcmf_core *pub)
  195616. +{
  195617. + struct brcmf_core_priv *core;
  195618. +
  195619. + core = container_of(pub, struct brcmf_core_priv, pub);
  195620. + return core->chip->iscoreup(core);
  195621. +}
  195622. +
  195623. +void brcmf_chip_coredisable(struct brcmf_core *pub, u32 prereset, u32 reset)
  195624. +{
  195625. + struct brcmf_core_priv *core;
  195626. +
  195627. + core = container_of(pub, struct brcmf_core_priv, pub);
  195628. + core->chip->coredisable(core, prereset, reset);
  195629. +}
  195630. +
  195631. +void brcmf_chip_resetcore(struct brcmf_core *pub, u32 prereset, u32 reset,
  195632. + u32 postreset)
  195633. +{
  195634. + struct brcmf_core_priv *core;
  195635. +
  195636. + core = container_of(pub, struct brcmf_core_priv, pub);
  195637. + core->chip->resetcore(core, prereset, reset, postreset);
  195638. +}
  195639. +
  195640. +static void
  195641. +brcmf_chip_cm3_enterdl(struct brcmf_chip_priv *chip)
  195642. +{
  195643. + struct brcmf_core *core;
  195644. +
  195645. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
  195646. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
  195647. + brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
  195648. + D11_BCMA_IOCTL_PHYCLOCKEN,
  195649. + D11_BCMA_IOCTL_PHYCLOCKEN,
  195650. + D11_BCMA_IOCTL_PHYCLOCKEN);
  195651. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
  195652. + brcmf_chip_resetcore(core, 0, 0, 0);
  195653. +}
  195654. +
  195655. +static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv *chip)
  195656. +{
  195657. + struct brcmf_core *core;
  195658. +
  195659. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
  195660. + if (!brcmf_chip_iscoreup(core)) {
  195661. + brcmf_err("SOCRAM core is down after reset?\n");
  195662. + return false;
  195663. + }
  195664. +
  195665. + chip->ops->exit_dl(chip->ctx, &chip->pub, 0);
  195666. +
  195667. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3);
  195668. + brcmf_chip_resetcore(core, 0, 0, 0);
  195669. +
  195670. + return true;
  195671. +}
  195672. +
  195673. +static inline void
  195674. +brcmf_chip_cr4_enterdl(struct brcmf_chip_priv *chip)
  195675. +{
  195676. + struct brcmf_core *core;
  195677. +
  195678. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
  195679. +
  195680. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
  195681. + brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
  195682. + D11_BCMA_IOCTL_PHYCLOCKEN,
  195683. + D11_BCMA_IOCTL_PHYCLOCKEN,
  195684. + D11_BCMA_IOCTL_PHYCLOCKEN);
  195685. +}
  195686. +
  195687. +static bool brcmf_chip_cr4_exitdl(struct brcmf_chip_priv *chip, u32 rstvec)
  195688. +{
  195689. + struct brcmf_core *core;
  195690. +
  195691. + chip->ops->exit_dl(chip->ctx, &chip->pub, rstvec);
  195692. +
  195693. + /* restore ARM */
  195694. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4);
  195695. + brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);
  195696. +
  195697. + return true;
  195698. +}
  195699. +
  195700. +void brcmf_chip_enter_download(struct brcmf_chip *pub)
  195701. +{
  195702. + struct brcmf_chip_priv *chip;
  195703. + struct brcmf_core *arm;
  195704. +
  195705. + brcmf_dbg(TRACE, "Enter\n");
  195706. +
  195707. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195708. + arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
  195709. + if (arm) {
  195710. + brcmf_chip_cr4_enterdl(chip);
  195711. + return;
  195712. + }
  195713. +
  195714. + brcmf_chip_cm3_enterdl(chip);
  195715. +}
  195716. +
  195717. +bool brcmf_chip_exit_download(struct brcmf_chip *pub, u32 rstvec)
  195718. +{
  195719. + struct brcmf_chip_priv *chip;
  195720. + struct brcmf_core *arm;
  195721. +
  195722. + brcmf_dbg(TRACE, "Enter\n");
  195723. +
  195724. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195725. + arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
  195726. + if (arm)
  195727. + return brcmf_chip_cr4_exitdl(chip, rstvec);
  195728. +
  195729. + return brcmf_chip_cm3_exitdl(chip);
  195730. +}
  195731. +
  195732. +bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
  195733. +{
  195734. + u32 base, addr, reg, pmu_cc3_mask = ~0;
  195735. + struct brcmf_chip_priv *chip;
  195736. +
  195737. + brcmf_dbg(TRACE, "Enter\n");
  195738. +
  195739. + /* old chips with PMU version less than 17 don't support save restore */
  195740. + if (pub->pmurev < 17)
  195741. + return false;
  195742. +
  195743. + base = brcmf_chip_get_chipcommon(pub)->base;
  195744. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  195745. +
  195746. + switch (pub->chip) {
  195747. + case BCM4354_CHIP_ID:
  195748. + /* explicitly check SR engine enable bit */
  195749. + pmu_cc3_mask = BIT(2);
  195750. + /* fall-through */
  195751. + case BCM43241_CHIP_ID:
  195752. + case BCM4335_CHIP_ID:
  195753. + case BCM4339_CHIP_ID:
  195754. + /* read PMU chipcontrol register 3 */
  195755. + addr = CORE_CC_REG(base, chipcontrol_addr);
  195756. + chip->ops->write32(chip->ctx, addr, 3);
  195757. + addr = CORE_CC_REG(base, chipcontrol_data);
  195758. + reg = chip->ops->read32(chip->ctx, addr);
  195759. + return (reg & pmu_cc3_mask) != 0;
  195760. + default:
  195761. + addr = CORE_CC_REG(base, pmucapabilities_ext);
  195762. + reg = chip->ops->read32(chip->ctx, addr);
  195763. + if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
  195764. + return false;
  195765. +
  195766. + addr = CORE_CC_REG(base, retention_ctl);
  195767. + reg = chip->ops->read32(chip->ctx, addr);
  195768. + return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
  195769. + PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
  195770. + }
  195771. +}
  195772. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/chip.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/chip.h
  195773. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/chip.h 1969-12-31 18:00:00.000000000 -0600
  195774. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/chip.h 2014-12-08 00:31:53.836418001 -0600
  195775. @@ -0,0 +1,91 @@
  195776. +/*
  195777. + * Copyright (c) 2014 Broadcom Corporation
  195778. + *
  195779. + * Permission to use, copy, modify, and/or distribute this software for any
  195780. + * purpose with or without fee is hereby granted, provided that the above
  195781. + * copyright notice and this permission notice appear in all copies.
  195782. + *
  195783. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  195784. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  195785. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  195786. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  195787. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  195788. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  195789. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  195790. + */
  195791. +#ifndef BRCMF_CHIP_H
  195792. +#define BRCMF_CHIP_H
  195793. +
  195794. +#include <linux/types.h>
  195795. +
  195796. +#define CORE_CC_REG(base, field) \
  195797. + (base + offsetof(struct chipcregs, field))
  195798. +
  195799. +/**
  195800. + * struct brcmf_chip - chip level information.
  195801. + *
  195802. + * @chip: chip identifier.
  195803. + * @chiprev: chip revision.
  195804. + * @cc_caps: chipcommon core capabilities.
  195805. + * @pmucaps: PMU capabilities.
  195806. + * @pmurev: PMU revision.
  195807. + * @rambase: RAM base address (only applicable for ARM CR4 chips).
  195808. + * @ramsize: amount of RAM on chip.
  195809. + * @name: string representation of the chip identifier.
  195810. + */
  195811. +struct brcmf_chip {
  195812. + u32 chip;
  195813. + u32 chiprev;
  195814. + u32 cc_caps;
  195815. + u32 pmucaps;
  195816. + u32 pmurev;
  195817. + u32 rambase;
  195818. + u32 ramsize;
  195819. + char name[8];
  195820. +};
  195821. +
  195822. +/**
  195823. + * struct brcmf_core - core related information.
  195824. + *
  195825. + * @id: core identifier.
  195826. + * @rev: core revision.
  195827. + * @base: base address of core register space.
  195828. + */
  195829. +struct brcmf_core {
  195830. + u16 id;
  195831. + u16 rev;
  195832. + u32 base;
  195833. +};
  195834. +
  195835. +/**
  195836. + * struct brcmf_buscore_ops - buscore specific callbacks.
  195837. + *
  195838. + * @read32: read 32-bit value over bus.
  195839. + * @write32: write 32-bit value over bus.
  195840. + * @prepare: prepare bus for core configuration.
  195841. + * @setup: bus-specific core setup.
  195842. + * @exit_dl: exit download state.
  195843. + * The callback should use the provided @rstvec when non-zero.
  195844. + */
  195845. +struct brcmf_buscore_ops {
  195846. + u32 (*read32)(void *ctx, u32 addr);
  195847. + void (*write32)(void *ctx, u32 addr, u32 value);
  195848. + int (*prepare)(void *ctx);
  195849. + int (*setup)(void *ctx, struct brcmf_chip *chip);
  195850. + void (*exit_dl)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
  195851. +};
  195852. +
  195853. +struct brcmf_chip *brcmf_chip_attach(void *ctx,
  195854. + const struct brcmf_buscore_ops *ops);
  195855. +void brcmf_chip_detach(struct brcmf_chip *chip);
  195856. +struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
  195857. +struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip);
  195858. +bool brcmf_chip_iscoreup(struct brcmf_core *core);
  195859. +void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset);
  195860. +void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset,
  195861. + u32 postreset);
  195862. +void brcmf_chip_enter_download(struct brcmf_chip *ci);
  195863. +bool brcmf_chip_exit_download(struct brcmf_chip *ci, u32 rstvec);
  195864. +bool brcmf_chip_sr_capable(struct brcmf_chip *pub);
  195865. +
  195866. +#endif /* BRCMF_AXIDMP_H */
  195867. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
  195868. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h 2014-07-28 10:07:25.000000000 -0500
  195869. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h 2014-12-08 00:31:53.840418001 -0600
  195870. @@ -63,7 +63,6 @@
  195871. */
  195872. struct brcmf_bus_ops {
  195873. int (*preinit)(struct device *dev);
  195874. - int (*init)(struct device *dev);
  195875. void (*stop)(struct device *dev);
  195876. int (*txdata)(struct device *dev, struct sk_buff *skb);
  195877. int (*txctl)(struct device *dev, unsigned char *msg, uint len);
  195878. @@ -99,6 +98,7 @@
  195879. unsigned long tx_realloc;
  195880. u32 chip;
  195881. u32 chiprev;
  195882. + bool always_use_fws_queue;
  195883. struct brcmf_bus_ops *ops;
  195884. };
  195885. @@ -113,11 +113,6 @@
  195886. return bus->ops->preinit(bus->dev);
  195887. }
  195888. -static inline int brcmf_bus_init(struct brcmf_bus *bus)
  195889. -{
  195890. - return bus->ops->init(bus->dev);
  195891. -}
  195892. -
  195893. static inline void brcmf_bus_stop(struct brcmf_bus *bus)
  195894. {
  195895. bus->ops->stop(bus->dev);
  195896. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
  195897. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c 2014-07-28 10:07:25.000000000 -0500
  195898. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c 2014-12-08 00:31:53.840418001 -0600
  195899. @@ -32,6 +32,9 @@
  195900. #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
  195901. #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00"
  195902. +/* boost value for RSSI_DELTA in preferred join selection */
  195903. +#define BRCMF_JOIN_PREF_RSSI_BOOST 8
  195904. +
  195905. bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
  195906. struct sk_buff *pkt, int prec)
  195907. @@ -246,6 +249,7 @@
  195908. {
  195909. s8 eventmask[BRCMF_EVENTING_MASK_LEN];
  195910. u8 buf[BRCMF_DCMD_SMLEN];
  195911. + struct brcmf_join_pref_params join_pref_params[2];
  195912. char *ptr;
  195913. s32 err;
  195914. @@ -298,6 +302,20 @@
  195915. goto done;
  195916. }
  195917. + /* Setup join_pref to select target by RSSI(with boost on 5GHz) */
  195918. + join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA;
  195919. + join_pref_params[0].len = 2;
  195920. + join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST;
  195921. + join_pref_params[0].band = WLC_BAND_5G;
  195922. + join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI;
  195923. + join_pref_params[1].len = 2;
  195924. + join_pref_params[1].rssi_gain = 0;
  195925. + join_pref_params[1].band = 0;
  195926. + err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
  195927. + sizeof(join_pref_params));
  195928. + if (err)
  195929. + brcmf_err("Set join_pref error (%d)\n", err);
  195930. +
  195931. /* Setup event_msgs, enable E_IF */
  195932. err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
  195933. BRCMF_EVENTING_MASK_LEN);
  195934. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/dhd.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
  195935. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/dhd.h 2014-07-28 10:07:25.000000000 -0500
  195936. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd.h 2014-12-08 00:31:53.836418001 -0600
  195937. @@ -186,7 +186,7 @@
  195938. void brcmf_txflowblock_if(struct brcmf_if *ifp,
  195939. enum brcmf_netif_stop_reason reason, bool state);
  195940. u32 brcmf_get_chip_info(struct brcmf_if *ifp);
  195941. -void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
  195942. +void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
  195943. bool success);
  195944. /* Sets dongle media info (drv_version, mac address). */
  195945. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
  195946. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c 2014-07-28 10:07:25.000000000 -0500
  195947. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c 2014-12-08 00:31:53.840418001 -0600
  195948. @@ -190,7 +190,7 @@
  195949. int ret;
  195950. struct brcmf_if *ifp = netdev_priv(ndev);
  195951. struct brcmf_pub *drvr = ifp->drvr;
  195952. - struct ethhdr *eh;
  195953. + struct ethhdr *eh = (struct ethhdr *)(skb->data);
  195954. brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx);
  195955. @@ -236,6 +236,9 @@
  195956. goto done;
  195957. }
  195958. + if (eh->h_proto == htons(ETH_P_PAE))
  195959. + atomic_inc(&ifp->pend_8021x_cnt);
  195960. +
  195961. ret = brcmf_fws_process_skb(ifp, skb);
  195962. done:
  195963. @@ -511,7 +514,7 @@
  195964. void brcmf_rx_frame(struct device *dev, struct sk_buff *skb)
  195965. {
  195966. - struct brcmf_if *ifp;
  195967. + struct brcmf_if *ifp = NULL;
  195968. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  195969. struct brcmf_pub *drvr = bus_if->drvr;
  195970. struct brcmf_skb_reorder_data *rd;
  195971. @@ -522,7 +525,7 @@
  195972. /* process and remove protocol-specific header */
  195973. ret = brcmf_proto_hdrpull(drvr, true, &ifidx, skb);
  195974. - ifp = drvr->iflist[ifidx];
  195975. + if (!ret) ifp = drvr->iflist[ifidx];
  195976. if (ret || !ifp || !ifp->ndev) {
  195977. if ((ret != -ENODATA) && ifp)
  195978. @@ -538,31 +541,26 @@
  195979. brcmf_netif_rx(ifp, skb);
  195980. }
  195981. -void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
  195982. +void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
  195983. bool success)
  195984. {
  195985. struct brcmf_if *ifp;
  195986. struct ethhdr *eh;
  195987. - u8 ifidx;
  195988. u16 type;
  195989. - int res;
  195990. -
  195991. - res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
  195992. ifp = drvr->iflist[ifidx];
  195993. if (!ifp)
  195994. goto done;
  195995. - if (res == 0) {
  195996. - eh = (struct ethhdr *)(txp->data);
  195997. - type = ntohs(eh->h_proto);
  195998. -
  195999. - if (type == ETH_P_PAE) {
  196000. - atomic_dec(&ifp->pend_8021x_cnt);
  196001. - if (waitqueue_active(&ifp->pend_8021x_wait))
  196002. - wake_up(&ifp->pend_8021x_wait);
  196003. - }
  196004. + eh = (struct ethhdr *)(txp->data);
  196005. + type = ntohs(eh->h_proto);
  196006. +
  196007. + if (type == ETH_P_PAE) {
  196008. + atomic_dec(&ifp->pend_8021x_cnt);
  196009. + if (waitqueue_active(&ifp->pend_8021x_wait))
  196010. + wake_up(&ifp->pend_8021x_wait);
  196011. }
  196012. +
  196013. if (!success)
  196014. ifp->stats.tx_errors++;
  196015. done:
  196016. @@ -573,13 +571,17 @@
  196017. {
  196018. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  196019. struct brcmf_pub *drvr = bus_if->drvr;
  196020. + u8 ifidx;
  196021. /* await txstatus signal for firmware if active */
  196022. if (brcmf_fws_fc_active(drvr->fws)) {
  196023. if (!success)
  196024. brcmf_fws_bustxfail(drvr->fws, txp);
  196025. } else {
  196026. - brcmf_txfinalize(drvr, txp, success);
  196027. + if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp))
  196028. + brcmu_pkt_buf_free_skb(txp);
  196029. + else
  196030. + brcmf_txfinalize(drvr, txp, ifidx, success);
  196031. }
  196032. }
  196033. @@ -914,13 +916,6 @@
  196034. brcmf_dbg(TRACE, "\n");
  196035. - /* Bring up the bus */
  196036. - ret = brcmf_bus_init(bus_if);
  196037. - if (ret != 0) {
  196038. - brcmf_err("brcmf_sdbrcm_bus_init failed %d\n", ret);
  196039. - return ret;
  196040. - }
  196041. -
  196042. /* add primary networking interface */
  196043. ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
  196044. if (IS_ERR(ifp))
  196045. @@ -1040,12 +1035,12 @@
  196046. brcmf_cfg80211_detach(drvr->config);
  196047. + brcmf_fws_deinit(drvr);
  196048. +
  196049. brcmf_bus_detach(drvr);
  196050. brcmf_proto_detach(drvr);
  196051. - brcmf_fws_deinit(drvr);
  196052. -
  196053. brcmf_debugfs_detach(drvr);
  196054. bus_if->drvr = NULL;
  196055. kfree(drvr);
  196056. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
  196057. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c 2014-07-28 10:07:25.000000000 -0500
  196058. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c 2014-12-08 00:31:53.840418001 -0600
  196059. @@ -23,6 +23,7 @@
  196060. #include <linux/interrupt.h>
  196061. #include <linux/sched.h>
  196062. #include <linux/mmc/sdio.h>
  196063. +#include <linux/mmc/sdio_ids.h>
  196064. #include <linux/mmc/sdio_func.h>
  196065. #include <linux/mmc/card.h>
  196066. #include <linux/semaphore.h>
  196067. @@ -40,8 +41,8 @@
  196068. #include <brcm_hw_ids.h>
  196069. #include <soc.h>
  196070. #include "sdio_host.h"
  196071. -#include "sdio_chip.h"
  196072. -#include "nvram.h"
  196073. +#include "chip.h"
  196074. +#include "firmware.h"
  196075. #define DCMD_RESP_TIMEOUT 2000 /* In milli second */
  196076. @@ -112,8 +113,6 @@
  196077. #define BRCMF_TXBOUND 20 /* Default for max tx frames in
  196078. one scheduling */
  196079. -#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
  196080. -
  196081. #define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
  196082. #define MEMBLOCK 2048 /* Block size used for downloading
  196083. @@ -156,6 +155,34 @@
  196084. /* manfid tuple length, include tuple, link bytes */
  196085. #define SBSDIO_CIS_MANFID_TUPLE_LEN 6
  196086. +#define CORE_BUS_REG(base, field) \
  196087. + (base + offsetof(struct sdpcmd_regs, field))
  196088. +
  196089. +/* SDIO function 1 register CHIPCLKCSR */
  196090. +/* Force ALP request to backplane */
  196091. +#define SBSDIO_FORCE_ALP 0x01
  196092. +/* Force HT request to backplane */
  196093. +#define SBSDIO_FORCE_HT 0x02
  196094. +/* Force ILP request to backplane */
  196095. +#define SBSDIO_FORCE_ILP 0x04
  196096. +/* Make ALP ready (power up xtal) */
  196097. +#define SBSDIO_ALP_AVAIL_REQ 0x08
  196098. +/* Make HT ready (power up PLL) */
  196099. +#define SBSDIO_HT_AVAIL_REQ 0x10
  196100. +/* Squelch clock requests from HW */
  196101. +#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
  196102. +/* Status: ALP is ready */
  196103. +#define SBSDIO_ALP_AVAIL 0x40
  196104. +/* Status: HT is ready */
  196105. +#define SBSDIO_HT_AVAIL 0x80
  196106. +#define SBSDIO_CSR_MASK 0x1F
  196107. +#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
  196108. +#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
  196109. +#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
  196110. +#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
  196111. +#define SBSDIO_CLKAV(regval, alponly) \
  196112. + (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
  196113. +
  196114. /* intstatus */
  196115. #define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */
  196116. #define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */
  196117. @@ -276,7 +303,6 @@
  196118. /* Flags for SDH calls */
  196119. #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
  196120. -#define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */
  196121. #define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
  196122. * when idle
  196123. */
  196124. @@ -433,10 +459,11 @@
  196125. bool alp_only; /* Don't use HT clock (ALP only) */
  196126. u8 *ctrl_frame_buf;
  196127. - u32 ctrl_frame_len;
  196128. + u16 ctrl_frame_len;
  196129. bool ctrl_frame_stat;
  196130. - spinlock_t txqlock;
  196131. + spinlock_t txq_lock; /* protect bus->txq */
  196132. + struct semaphore tx_seq_lock; /* protect bus->tx_seq */
  196133. wait_queue_head_t ctrl_wait;
  196134. wait_queue_head_t dcmd_resp_wait;
  196135. @@ -483,16 +510,58 @@
  196136. #define ALIGNMENT 4
  196137. -static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
  196138. -module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0);
  196139. -MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
  196140. -
  196141. enum brcmf_sdio_frmtype {
  196142. BRCMF_SDIO_FT_NORMAL,
  196143. BRCMF_SDIO_FT_SUPER,
  196144. BRCMF_SDIO_FT_SUB,
  196145. };
  196146. +#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
  196147. +
  196148. +/* SDIO Pad drive strength to select value mappings */
  196149. +struct sdiod_drive_str {
  196150. + u8 strength; /* Pad Drive Strength in mA */
  196151. + u8 sel; /* Chip-specific select value */
  196152. +};
  196153. +
  196154. +/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
  196155. +static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
  196156. + {32, 0x6},
  196157. + {26, 0x7},
  196158. + {22, 0x4},
  196159. + {16, 0x5},
  196160. + {12, 0x2},
  196161. + {8, 0x3},
  196162. + {4, 0x0},
  196163. + {0, 0x1}
  196164. +};
  196165. +
  196166. +/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
  196167. +static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = {
  196168. + {6, 0x7},
  196169. + {5, 0x6},
  196170. + {4, 0x5},
  196171. + {3, 0x4},
  196172. + {2, 0x2},
  196173. + {1, 0x1},
  196174. + {0, 0x0}
  196175. +};
  196176. +
  196177. +/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
  196178. +static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = {
  196179. + {3, 0x3},
  196180. + {2, 0x2},
  196181. + {1, 0x1},
  196182. + {0, 0x0} };
  196183. +
  196184. +/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
  196185. +static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
  196186. + {16, 0x7},
  196187. + {12, 0x5},
  196188. + {8, 0x3},
  196189. + {4, 0x1}
  196190. +};
  196191. +
  196192. #define BCM43143_FIRMWARE_NAME "brcm/brcmfmac43143-sdio.bin"
  196193. #define BCM43143_NVRAM_NAME "brcm/brcmfmac43143-sdio.txt"
  196194. #define BCM43241B0_FIRMWARE_NAME "brcm/brcmfmac43241b0-sdio.bin"
  196195. @@ -511,6 +580,8 @@
  196196. #define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt"
  196197. #define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin"
  196198. #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt"
  196199. +#define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin"
  196200. +#define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt"
  196201. MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME);
  196202. MODULE_FIRMWARE(BCM43143_NVRAM_NAME);
  196203. @@ -530,6 +601,8 @@
  196204. MODULE_FIRMWARE(BCM43362_NVRAM_NAME);
  196205. MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
  196206. MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
  196207. +MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
  196208. +MODULE_FIRMWARE(BCM4354_NVRAM_NAME);
  196209. struct brcmf_firmware_names {
  196210. u32 chipid;
  196211. @@ -555,46 +628,32 @@
  196212. { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
  196213. { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
  196214. { BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
  196215. - { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }
  196216. + { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
  196217. + { BCM4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
  196218. };
  196219. -
  196220. -static const struct firmware *brcmf_sdio_get_fw(struct brcmf_sdio *bus,
  196221. - enum brcmf_firmware_type type)
  196222. +static const char *brcmf_sdio_get_fwname(struct brcmf_chip *ci,
  196223. + enum brcmf_firmware_type type)
  196224. {
  196225. - const struct firmware *fw;
  196226. - const char *name;
  196227. - int err, i;
  196228. + int i;
  196229. for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
  196230. - if (brcmf_fwname_data[i].chipid == bus->ci->chip &&
  196231. - brcmf_fwname_data[i].revmsk & BIT(bus->ci->chiprev)) {
  196232. + if (brcmf_fwname_data[i].chipid == ci->chip &&
  196233. + brcmf_fwname_data[i].revmsk & BIT(ci->chiprev)) {
  196234. switch (type) {
  196235. case BRCMF_FIRMWARE_BIN:
  196236. - name = brcmf_fwname_data[i].bin;
  196237. - break;
  196238. + return brcmf_fwname_data[i].bin;
  196239. case BRCMF_FIRMWARE_NVRAM:
  196240. - name = brcmf_fwname_data[i].nv;
  196241. - break;
  196242. + return brcmf_fwname_data[i].nv;
  196243. default:
  196244. brcmf_err("invalid firmware type (%d)\n", type);
  196245. return NULL;
  196246. }
  196247. - goto found;
  196248. }
  196249. }
  196250. brcmf_err("Unknown chipid %d [%d]\n",
  196251. - bus->ci->chip, bus->ci->chiprev);
  196252. + ci->chip, ci->chiprev);
  196253. return NULL;
  196254. -
  196255. -found:
  196256. - err = request_firmware(&fw, name, &bus->sdiodev->func[2]->dev);
  196257. - if ((err) || (!fw)) {
  196258. - brcmf_err("fail to request firmware %s (%d)\n", name, err);
  196259. - return NULL;
  196260. - }
  196261. -
  196262. - return fw;
  196263. }
  196264. static void pkt_align(struct sk_buff *p, int len, int align)
  196265. @@ -618,27 +677,24 @@
  196266. * Reads a register in the SDIO hardware block. This block occupies a series of
  196267. * adresses on the 32 bit backplane bus.
  196268. */
  196269. -static int
  196270. -r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
  196271. +static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
  196272. {
  196273. - u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  196274. + struct brcmf_core *core;
  196275. int ret;
  196276. - *regvar = brcmf_sdiod_regrl(bus->sdiodev,
  196277. - bus->ci->c_inf[idx].base + offset, &ret);
  196278. + core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
  196279. + *regvar = brcmf_sdiod_regrl(bus->sdiodev, core->base + offset, &ret);
  196280. return ret;
  196281. }
  196282. -static int
  196283. -w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
  196284. +static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
  196285. {
  196286. - u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  196287. + struct brcmf_core *core;
  196288. int ret;
  196289. - brcmf_sdiod_regwl(bus->sdiodev,
  196290. - bus->ci->c_inf[idx].base + reg_offset,
  196291. - regval, &ret);
  196292. + core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
  196293. + brcmf_sdiod_regwl(bus->sdiodev, core->base + reg_offset, regval, &ret);
  196294. return ret;
  196295. }
  196296. @@ -650,16 +706,12 @@
  196297. int err = 0;
  196298. int try_cnt = 0;
  196299. - brcmf_dbg(TRACE, "Enter\n");
  196300. + brcmf_dbg(TRACE, "Enter: on=%d\n", on);
  196301. wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
  196302. /* 1st KSO write goes to AOS wake up core if device is asleep */
  196303. brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
  196304. wr_val, &err);
  196305. - if (err) {
  196306. - brcmf_err("SDIO_AOS KSO write error: %d\n", err);
  196307. - return err;
  196308. - }
  196309. if (on) {
  196310. /* device WAKEUP through KSO:
  196311. @@ -689,18 +741,22 @@
  196312. &err);
  196313. if (((rd_val & bmask) == cmp_val) && !err)
  196314. break;
  196315. - brcmf_dbg(SDIO, "KSO wr/rd retry:%d (max: %d) ERR:%x\n",
  196316. - try_cnt, MAX_KSO_ATTEMPTS, err);
  196317. +
  196318. udelay(KSO_WAIT_US);
  196319. brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
  196320. wr_val, &err);
  196321. } while (try_cnt++ < MAX_KSO_ATTEMPTS);
  196322. + if (try_cnt > 2)
  196323. + brcmf_dbg(SDIO, "try_cnt=%d rd_val=0x%x err=%d\n", try_cnt,
  196324. + rd_val, err);
  196325. +
  196326. + if (try_cnt > MAX_KSO_ATTEMPTS)
  196327. + brcmf_err("max tries: rd_val=0x%x err=%d\n", rd_val, err);
  196328. +
  196329. return err;
  196330. }
  196331. -#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND)
  196332. -
  196333. #define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
  196334. /* Turn backplane clock on or off */
  196335. @@ -799,7 +855,6 @@
  196336. }
  196337. #endif /* defined (DEBUG) */
  196338. - bus->activity = true;
  196339. } else {
  196340. clkreq = 0;
  196341. @@ -899,8 +954,9 @@
  196342. brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
  196343. {
  196344. int err = 0;
  196345. - brcmf_dbg(TRACE, "Enter\n");
  196346. - brcmf_dbg(SDIO, "request %s currently %s\n",
  196347. + u8 clkcsr;
  196348. +
  196349. + brcmf_dbg(SDIO, "Enter: request %s currently %s\n",
  196350. (sleep ? "SLEEP" : "WAKE"),
  196351. (bus->sleeping ? "SLEEP" : "WAKE"));
  196352. @@ -917,8 +973,20 @@
  196353. atomic_read(&bus->ipend) > 0 ||
  196354. (!atomic_read(&bus->fcstate) &&
  196355. brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
  196356. - data_ok(bus)))
  196357. - return -EBUSY;
  196358. + data_ok(bus))) {
  196359. + err = -EBUSY;
  196360. + goto done;
  196361. + }
  196362. +
  196363. + clkcsr = brcmf_sdiod_regrb(bus->sdiodev,
  196364. + SBSDIO_FUNC1_CHIPCLKCSR,
  196365. + &err);
  196366. + if ((clkcsr & SBSDIO_CSR_MASK) == 0) {
  196367. + brcmf_dbg(SDIO, "no clock, set ALP\n");
  196368. + brcmf_sdiod_regwb(bus->sdiodev,
  196369. + SBSDIO_FUNC1_CHIPCLKCSR,
  196370. + SBSDIO_ALP_AVAIL_REQ, &err);
  196371. + }
  196372. err = brcmf_sdio_kso_control(bus, false);
  196373. /* disable watchdog */
  196374. if (!err)
  196375. @@ -935,7 +1003,7 @@
  196376. } else {
  196377. brcmf_err("error while changing bus sleep state %d\n",
  196378. err);
  196379. - return err;
  196380. + goto done;
  196381. }
  196382. }
  196383. @@ -947,11 +1015,92 @@
  196384. } else {
  196385. brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
  196386. }
  196387. -
  196388. +done:
  196389. + brcmf_dbg(SDIO, "Exit: err=%d\n", err);
  196390. return err;
  196391. }
  196392. +#ifdef DEBUG
  196393. +static inline bool brcmf_sdio_valid_shared_address(u32 addr)
  196394. +{
  196395. + return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
  196396. +}
  196397. +
  196398. +static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
  196399. + struct sdpcm_shared *sh)
  196400. +{
  196401. + u32 addr;
  196402. + int rv;
  196403. + u32 shaddr = 0;
  196404. + struct sdpcm_shared_le sh_le;
  196405. + __le32 addr_le;
  196406. +
  196407. + shaddr = bus->ci->rambase + bus->ramsize - 4;
  196408. +
  196409. + /*
  196410. + * Read last word in socram to determine
  196411. + * address of sdpcm_shared structure
  196412. + */
  196413. + sdio_claim_host(bus->sdiodev->func[1]);
  196414. + brcmf_sdio_bus_sleep(bus, false, false);
  196415. + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
  196416. + sdio_release_host(bus->sdiodev->func[1]);
  196417. + if (rv < 0)
  196418. + return rv;
  196419. +
  196420. + addr = le32_to_cpu(addr_le);
  196421. +
  196422. + brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
  196423. +
  196424. + /*
  196425. + * Check if addr is valid.
  196426. + * NVRAM length at the end of memory should have been overwritten.
  196427. + */
  196428. + if (!brcmf_sdio_valid_shared_address(addr)) {
  196429. + brcmf_err("invalid sdpcm_shared address 0x%08X\n",
  196430. + addr);
  196431. + return -EINVAL;
  196432. + }
  196433. +
  196434. + /* Read hndrte_shared structure */
  196435. + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
  196436. + sizeof(struct sdpcm_shared_le));
  196437. + if (rv < 0)
  196438. + return rv;
  196439. +
  196440. + /* Endianness */
  196441. + sh->flags = le32_to_cpu(sh_le.flags);
  196442. + sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
  196443. + sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
  196444. + sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
  196445. + sh->assert_line = le32_to_cpu(sh_le.assert_line);
  196446. + sh->console_addr = le32_to_cpu(sh_le.console_addr);
  196447. + sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);
  196448. +
  196449. + if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
  196450. + brcmf_err("sdpcm shared version unsupported: dhd %d dongle %d\n",
  196451. + SDPCM_SHARED_VERSION,
  196452. + sh->flags & SDPCM_SHARED_VERSION_MASK);
  196453. + return -EPROTO;
  196454. + }
  196455. +
  196456. + return 0;
  196457. +}
  196458. +
  196459. +static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
  196460. +{
  196461. + struct sdpcm_shared sh;
  196462. +
  196463. + if (brcmf_sdio_readshared(bus, &sh) == 0)
  196464. + bus->console_addr = sh.console_addr;
  196465. +}
  196466. +#else
  196467. +static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
  196468. +{
  196469. +}
  196470. +#endif /* DEBUG */
  196471. +
  196472. static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
  196473. {
  196474. u32 intstatus = 0;
  196475. @@ -995,6 +1144,12 @@
  196476. else
  196477. brcmf_dbg(SDIO, "Dongle ready, protocol version %d\n",
  196478. bus->sdpcm_ver);
  196479. +
  196480. + /*
  196481. + * Retrieve console state address now that firmware should have
  196482. + * updated it.
  196483. + */
  196484. + brcmf_sdio_get_console_addr(bus);
  196485. }
  196486. /*
  196487. @@ -1083,6 +1238,28 @@
  196488. bus->cur_read.len = 0;
  196489. }
  196490. +static void brcmf_sdio_txfail(struct brcmf_sdio *bus)
  196491. +{
  196492. + struct brcmf_sdio_dev *sdiodev = bus->sdiodev;
  196493. + u8 i, hi, lo;
  196494. +
  196495. + /* On failure, abort the command and terminate the frame */
  196496. + brcmf_err("sdio error, abort command and terminate frame\n");
  196497. + bus->sdcnt.tx_sderrs++;
  196498. +
  196499. + brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2);
  196500. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
  196501. + bus->sdcnt.f1regdata++;
  196502. +
  196503. + for (i = 0; i < 3; i++) {
  196504. + hi = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL);
  196505. + lo = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL);
  196506. + bus->sdcnt.f1regdata += 2;
  196507. + if ((hi == 0) && (lo == 0))
  196508. + break;
  196509. + }
  196510. +}
  196511. +
  196512. /* return total length of buffer chain */
  196513. static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus)
  196514. {
  196515. @@ -1955,7 +2132,7 @@
  196516. memcpy(pkt_pad->data,
  196517. pkt->data + pkt->len - tail_chop,
  196518. tail_chop);
  196519. - *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
  196520. + *(u16 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
  196521. skb_trim(pkt, pkt->len - tail_chop);
  196522. skb_trim(pkt_pad, tail_pad + tail_chop);
  196523. __skb_queue_after(pktq, pkt, pkt_pad);
  196524. @@ -2003,7 +2180,7 @@
  196525. * already properly aligned and does not
  196526. * need an sdpcm header.
  196527. */
  196528. - if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
  196529. + if (*(u16 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
  196530. continue;
  196531. /* align packet data pointer */
  196532. @@ -2037,10 +2214,10 @@
  196533. if (BRCMF_BYTES_ON() &&
  196534. ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
  196535. (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
  196536. - brcmf_dbg_hex_dump(true, pkt_next, hd_info.len,
  196537. + brcmf_dbg_hex_dump(true, pkt_next->data, hd_info.len,
  196538. "Tx Frame:\n");
  196539. else if (BRCMF_HDRS_ON())
  196540. - brcmf_dbg_hex_dump(true, pkt_next,
  196541. + brcmf_dbg_hex_dump(true, pkt_next->data,
  196542. head_pad + bus->tx_hdrlen,
  196543. "Tx Header:\n");
  196544. }
  196545. @@ -2067,11 +2244,11 @@
  196546. u8 *hdr;
  196547. u32 dat_offset;
  196548. u16 tail_pad;
  196549. - u32 dummy_flags, chop_len;
  196550. + u16 dummy_flags, chop_len;
  196551. struct sk_buff *pkt_next, *tmp, *pkt_prev;
  196552. skb_queue_walk_safe(pktq, pkt_next, tmp) {
  196553. - dummy_flags = *(u32 *)(pkt_next->cb);
  196554. + dummy_flags = *(u16 *)(pkt_next->cb);
  196555. if (dummy_flags & ALIGN_SKB_FLAG) {
  196556. chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
  196557. if (chop_len) {
  196558. @@ -2100,7 +2277,6 @@
  196559. uint chan)
  196560. {
  196561. int ret;
  196562. - int i;
  196563. struct sk_buff *pkt_next, *tmp;
  196564. brcmf_dbg(TRACE, "Enter\n");
  196565. @@ -2113,28 +2289,9 @@
  196566. ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq);
  196567. bus->sdcnt.f2txdata++;
  196568. - if (ret < 0) {
  196569. - /* On failure, abort the command and terminate the frame */
  196570. - brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
  196571. - ret);
  196572. - bus->sdcnt.tx_sderrs++;
  196573. + if (ret < 0)
  196574. + brcmf_sdio_txfail(bus);
  196575. - brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
  196576. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
  196577. - SFC_WF_TERM, NULL);
  196578. - bus->sdcnt.f1regdata++;
  196579. -
  196580. - for (i = 0; i < 3; i++) {
  196581. - u8 hi, lo;
  196582. - hi = brcmf_sdiod_regrb(bus->sdiodev,
  196583. - SBSDIO_FUNC1_WFRAMEBCHI, NULL);
  196584. - lo = brcmf_sdiod_regrb(bus->sdiodev,
  196585. - SBSDIO_FUNC1_WFRAMEBCLO, NULL);
  196586. - bus->sdcnt.f1regdata += 2;
  196587. - if ((hi == 0) && (lo == 0))
  196588. - break;
  196589. - }
  196590. - }
  196591. sdio_release_host(bus->sdiodev->func[1]);
  196592. done:
  196593. @@ -2164,13 +2321,15 @@
  196594. /* Send frames until the limit or some other event */
  196595. for (cnt = 0; (cnt < maxframes) && data_ok(bus);) {
  196596. pkt_num = 1;
  196597. - __skb_queue_head_init(&pktq);
  196598. + if (down_interruptible(&bus->tx_seq_lock))
  196599. + return cnt;
  196600. if (bus->txglom)
  196601. pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
  196602. - brcmf_sdio_txglomsz);
  196603. + bus->sdiodev->txglomsz);
  196604. pkt_num = min_t(u32, pkt_num,
  196605. brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
  196606. - spin_lock_bh(&bus->txqlock);
  196607. + __skb_queue_head_init(&pktq);
  196608. + spin_lock_bh(&bus->txq_lock);
  196609. for (i = 0; i < pkt_num; i++) {
  196610. pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map,
  196611. &prec_out);
  196612. @@ -2178,15 +2337,19 @@
  196613. break;
  196614. __skb_queue_tail(&pktq, pkt);
  196615. }
  196616. - spin_unlock_bh(&bus->txqlock);
  196617. - if (i == 0)
  196618. + spin_unlock_bh(&bus->txq_lock);
  196619. + if (i == 0) {
  196620. + up(&bus->tx_seq_lock);
  196621. break;
  196622. + }
  196623. ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL);
  196624. + up(&bus->tx_seq_lock);
  196625. +
  196626. cnt += i;
  196627. /* In poll mode, need to check for other events */
  196628. - if (!bus->intr && cnt) {
  196629. + if (!bus->intr) {
  196630. /* Check device status, signal pending interrupt */
  196631. sdio_claim_host(bus->sdiodev->func[1]);
  196632. ret = r_sdreg32(bus, &intstatus,
  196633. @@ -2211,6 +2374,68 @@
  196634. return cnt;
  196635. }
  196636. +static int brcmf_sdio_tx_ctrlframe(struct brcmf_sdio *bus, u8 *frame, u16 len)
  196637. +{
  196638. + u8 doff;
  196639. + u16 pad;
  196640. + uint retries = 0;
  196641. + struct brcmf_sdio_hdrinfo hd_info = {0};
  196642. + int ret;
  196643. +
  196644. + brcmf_dbg(TRACE, "Enter\n");
  196645. +
  196646. + /* Back the pointer to make room for bus header */
  196647. + frame -= bus->tx_hdrlen;
  196648. + len += bus->tx_hdrlen;
  196649. +
  196650. + /* Add alignment padding (optional for ctl frames) */
  196651. + doff = ((unsigned long)frame % bus->head_align);
  196652. + if (doff) {
  196653. + frame -= doff;
  196654. + len += doff;
  196655. + memset(frame + bus->tx_hdrlen, 0, doff);
  196656. + }
  196657. +
  196658. + /* Round send length to next SDIO block */
  196659. + pad = 0;
  196660. + if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
  196661. + pad = bus->blocksize - (len % bus->blocksize);
  196662. + if ((pad > bus->roundup) || (pad >= bus->blocksize))
  196663. + pad = 0;
  196664. + } else if (len % bus->head_align) {
  196665. + pad = bus->head_align - (len % bus->head_align);
  196666. + }
  196667. + len += pad;
  196668. +
  196669. + hd_info.len = len - pad;
  196670. + hd_info.channel = SDPCM_CONTROL_CHANNEL;
  196671. + hd_info.dat_offset = doff + bus->tx_hdrlen;
  196672. + hd_info.seq_num = bus->tx_seq;
  196673. + hd_info.lastfrm = true;
  196674. + hd_info.tail_pad = pad;
  196675. + brcmf_sdio_hdpack(bus, frame, &hd_info);
  196676. +
  196677. + if (bus->txglom)
  196678. + brcmf_sdio_update_hwhdr(frame, len);
  196679. +
  196680. + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
  196681. + frame, len, "Tx Frame:\n");
  196682. + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
  196683. + BRCMF_HDRS_ON(),
  196684. + frame, min_t(u16, len, 16), "TxHdr:\n");
  196685. +
  196686. + do {
  196687. + ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len);
  196688. +
  196689. + if (ret < 0)
  196690. + brcmf_sdio_txfail(bus);
  196691. + else
  196692. + bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
  196693. + } while (ret < 0 && retries++ < TXRETRIES);
  196694. +
  196695. + return ret;
  196696. +}
  196697. +
  196698. static void brcmf_sdio_bus_stop(struct device *dev)
  196699. {
  196700. u32 local_hostintmask;
  196701. @@ -2292,21 +2517,29 @@
  196702. }
  196703. }
  196704. +static void atomic_orr(int val, atomic_t *v)
  196705. +{
  196706. + int old_val;
  196707. +
  196708. + old_val = atomic_read(v);
  196709. + while (atomic_cmpxchg(v, old_val, val | old_val) != old_val)
  196710. + old_val = atomic_read(v);
  196711. +}
  196712. +
  196713. static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
  196714. {
  196715. - u8 idx;
  196716. + struct brcmf_core *buscore;
  196717. u32 addr;
  196718. unsigned long val;
  196719. - int n, ret;
  196720. + int ret;
  196721. - idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  196722. - addr = bus->ci->c_inf[idx].base +
  196723. - offsetof(struct sdpcmd_regs, intstatus);
  196724. + buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
  196725. + addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus);
  196726. val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret);
  196727. bus->sdcnt.f1regdata++;
  196728. if (ret != 0)
  196729. - val = 0;
  196730. + return ret;
  196731. val &= bus->hostintmask;
  196732. atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE));
  196733. @@ -2315,13 +2548,7 @@
  196734. if (val) {
  196735. brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
  196736. bus->sdcnt.f1regdata++;
  196737. - }
  196738. -
  196739. - if (ret) {
  196740. - atomic_set(&bus->intstatus, 0);
  196741. - } else if (val) {
  196742. - for_each_set_bit(n, &val, 32)
  196743. - set_bit(n, (unsigned long *)&bus->intstatus.counter);
  196744. + atomic_orr(val, &bus->intstatus);
  196745. }
  196746. return ret;
  196747. @@ -2331,10 +2558,9 @@
  196748. {
  196749. u32 newstatus = 0;
  196750. unsigned long intstatus;
  196751. - uint rxlimit = bus->rxbound; /* Rx frames to read before resched */
  196752. uint txlimit = bus->txbound; /* Tx frames to send before resched */
  196753. - uint framecnt = 0; /* Temporary counter of tx/rx frames */
  196754. - int err = 0, n;
  196755. + uint framecnt; /* Temporary counter of tx/rx frames */
  196756. + int err = 0;
  196757. brcmf_dbg(TRACE, "Enter\n");
  196758. @@ -2431,70 +2657,38 @@
  196759. intstatus &= ~I_HMB_FRAME_IND;
  196760. /* On frame indication, read available frames */
  196761. - if (PKT_AVAILABLE() && bus->clkstate == CLK_AVAIL) {
  196762. - framecnt = brcmf_sdio_readframes(bus, rxlimit);
  196763. + if ((intstatus & I_HMB_FRAME_IND) && (bus->clkstate == CLK_AVAIL)) {
  196764. + brcmf_sdio_readframes(bus, bus->rxbound);
  196765. if (!bus->rxpending)
  196766. intstatus &= ~I_HMB_FRAME_IND;
  196767. - rxlimit -= min(framecnt, rxlimit);
  196768. }
  196769. /* Keep still-pending events for next scheduling */
  196770. - if (intstatus) {
  196771. - for_each_set_bit(n, &intstatus, 32)
  196772. - set_bit(n, (unsigned long *)&bus->intstatus.counter);
  196773. - }
  196774. + if (intstatus)
  196775. + atomic_orr(intstatus, &bus->intstatus);
  196776. brcmf_sdio_clrintr(bus);
  196777. - if (data_ok(bus) && bus->ctrl_frame_stat &&
  196778. - (bus->clkstate == CLK_AVAIL)) {
  196779. - int i;
  196780. -
  196781. - sdio_claim_host(bus->sdiodev->func[1]);
  196782. - err = brcmf_sdiod_send_buf(bus->sdiodev, bus->ctrl_frame_buf,
  196783. - (u32)bus->ctrl_frame_len);
  196784. -
  196785. - if (err < 0) {
  196786. - /* On failure, abort the command and
  196787. - terminate the frame */
  196788. - brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
  196789. - err);
  196790. - bus->sdcnt.tx_sderrs++;
  196791. -
  196792. - brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
  196793. -
  196794. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
  196795. - SFC_WF_TERM, &err);
  196796. - bus->sdcnt.f1regdata++;
  196797. -
  196798. - for (i = 0; i < 3; i++) {
  196799. - u8 hi, lo;
  196800. - hi = brcmf_sdiod_regrb(bus->sdiodev,
  196801. - SBSDIO_FUNC1_WFRAMEBCHI,
  196802. - &err);
  196803. - lo = brcmf_sdiod_regrb(bus->sdiodev,
  196804. - SBSDIO_FUNC1_WFRAMEBCLO,
  196805. - &err);
  196806. - bus->sdcnt.f1regdata += 2;
  196807. - if ((hi == 0) && (lo == 0))
  196808. - break;
  196809. - }
  196810. + if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
  196811. + (down_interruptible(&bus->tx_seq_lock) == 0)) {
  196812. + if (data_ok(bus)) {
  196813. + sdio_claim_host(bus->sdiodev->func[1]);
  196814. + err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf,
  196815. + bus->ctrl_frame_len);
  196816. + sdio_release_host(bus->sdiodev->func[1]);
  196817. - } else {
  196818. - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
  196819. + bus->ctrl_frame_stat = false;
  196820. + brcmf_sdio_wait_event_wakeup(bus);
  196821. }
  196822. - sdio_release_host(bus->sdiodev->func[1]);
  196823. - bus->ctrl_frame_stat = false;
  196824. - brcmf_sdio_wait_event_wakeup(bus);
  196825. + up(&bus->tx_seq_lock);
  196826. }
  196827. /* Send queued frames (limit 1 if rx may still be pending) */
  196828. - else if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) &&
  196829. - brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
  196830. - && data_ok(bus)) {
  196831. + if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) &&
  196832. + brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit &&
  196833. + data_ok(bus)) {
  196834. framecnt = bus->rxpending ? min(txlimit, bus->txminmax) :
  196835. txlimit;
  196836. - framecnt = brcmf_sdio_sendfromq(bus, framecnt);
  196837. - txlimit -= framecnt;
  196838. + brcmf_sdio_sendfromq(bus, framecnt);
  196839. }
  196840. if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) {
  196841. @@ -2504,19 +2698,9 @@
  196842. atomic_read(&bus->ipend) > 0 ||
  196843. (!atomic_read(&bus->fcstate) &&
  196844. brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
  196845. - data_ok(bus)) || PKT_AVAILABLE()) {
  196846. + data_ok(bus))) {
  196847. atomic_inc(&bus->dpc_tskcnt);
  196848. }
  196849. -
  196850. - /* If we're done for now, turn off clock request. */
  196851. - if ((bus->clkstate != CLK_PENDING)
  196852. - && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
  196853. - bus->activity = false;
  196854. - brcmf_dbg(SDIO, "idle state\n");
  196855. - sdio_claim_host(bus->sdiodev->func[1]);
  196856. - brcmf_sdio_bus_sleep(bus, true, false);
  196857. - sdio_release_host(bus->sdiodev->func[1]);
  196858. - }
  196859. }
  196860. static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev)
  196861. @@ -2531,15 +2715,12 @@
  196862. static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
  196863. {
  196864. int ret = -EBADE;
  196865. - uint datalen, prec;
  196866. + uint prec;
  196867. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  196868. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  196869. struct brcmf_sdio *bus = sdiodev->bus;
  196870. - ulong flags;
  196871. -
  196872. - brcmf_dbg(TRACE, "Enter\n");
  196873. - datalen = pkt->len;
  196874. + brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len);
  196875. /* Add space for the header */
  196876. skb_push(pkt, bus->tx_hdrlen);
  196877. @@ -2553,7 +2734,9 @@
  196878. bus->sdcnt.fcqueued++;
  196879. /* Priority based enq */
  196880. - spin_lock_irqsave(&bus->txqlock, flags);
  196881. + spin_lock_bh(&bus->txq_lock);
  196882. + /* reset bus_flags in packet cb */
  196883. + *(u16 *)(pkt->cb) = 0;
  196884. if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
  196885. skb_pull(pkt, bus->tx_hdrlen);
  196886. brcmf_err("out of bus->txq !!!\n");
  196887. @@ -2566,7 +2749,7 @@
  196888. bus->txoff = true;
  196889. brcmf_txflowblock(bus->sdiodev->dev, true);
  196890. }
  196891. - spin_unlock_irqrestore(&bus->txqlock, flags);
  196892. + spin_unlock_bh(&bus->txq_lock);
  196893. #ifdef DEBUG
  196894. if (pktq_plen(&bus->txq, prec) > qcount[prec])
  196895. @@ -2661,110 +2844,27 @@
  196896. }
  196897. #endif /* DEBUG */
  196898. -static int brcmf_sdio_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
  196899. -{
  196900. - int i;
  196901. - int ret;
  196902. -
  196903. - bus->ctrl_frame_stat = false;
  196904. - ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len);
  196905. -
  196906. - if (ret < 0) {
  196907. - /* On failure, abort the command and terminate the frame */
  196908. - brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
  196909. - ret);
  196910. - bus->sdcnt.tx_sderrs++;
  196911. -
  196912. - brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
  196913. -
  196914. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
  196915. - SFC_WF_TERM, NULL);
  196916. - bus->sdcnt.f1regdata++;
  196917. -
  196918. - for (i = 0; i < 3; i++) {
  196919. - u8 hi, lo;
  196920. - hi = brcmf_sdiod_regrb(bus->sdiodev,
  196921. - SBSDIO_FUNC1_WFRAMEBCHI, NULL);
  196922. - lo = brcmf_sdiod_regrb(bus->sdiodev,
  196923. - SBSDIO_FUNC1_WFRAMEBCLO, NULL);
  196924. - bus->sdcnt.f1regdata += 2;
  196925. - if (hi == 0 && lo == 0)
  196926. - break;
  196927. - }
  196928. - return ret;
  196929. - }
  196930. -
  196931. - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
  196932. -
  196933. - return ret;
  196934. -}
  196935. -
  196936. static int
  196937. brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
  196938. {
  196939. - u8 *frame;
  196940. - u16 len, pad;
  196941. - uint retries = 0;
  196942. - u8 doff = 0;
  196943. - int ret = -1;
  196944. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  196945. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  196946. struct brcmf_sdio *bus = sdiodev->bus;
  196947. - struct brcmf_sdio_hdrinfo hd_info = {0};
  196948. + int ret = -1;
  196949. brcmf_dbg(TRACE, "Enter\n");
  196950. - /* Back the pointer to make a room for bus header */
  196951. - frame = msg - bus->tx_hdrlen;
  196952. - len = (msglen += bus->tx_hdrlen);
  196953. + if (down_interruptible(&bus->tx_seq_lock))
  196954. + return -EINTR;
  196955. - /* Add alignment padding (optional for ctl frames) */
  196956. - doff = ((unsigned long)frame % bus->head_align);
  196957. - if (doff) {
  196958. - frame -= doff;
  196959. - len += doff;
  196960. - msglen += doff;
  196961. - memset(frame, 0, doff + bus->tx_hdrlen);
  196962. - }
  196963. - /* precondition: doff < bus->head_align */
  196964. - doff += bus->tx_hdrlen;
  196965. -
  196966. - /* Round send length to next SDIO block */
  196967. - pad = 0;
  196968. - if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
  196969. - pad = bus->blocksize - (len % bus->blocksize);
  196970. - if ((pad > bus->roundup) || (pad >= bus->blocksize))
  196971. - pad = 0;
  196972. - } else if (len % bus->head_align) {
  196973. - pad = bus->head_align - (len % bus->head_align);
  196974. - }
  196975. - len += pad;
  196976. -
  196977. - /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
  196978. -
  196979. - /* Make sure backplane clock is on */
  196980. - sdio_claim_host(bus->sdiodev->func[1]);
  196981. - brcmf_sdio_bus_sleep(bus, false, false);
  196982. - sdio_release_host(bus->sdiodev->func[1]);
  196983. -
  196984. - hd_info.len = (u16)msglen;
  196985. - hd_info.channel = SDPCM_CONTROL_CHANNEL;
  196986. - hd_info.dat_offset = doff;
  196987. - hd_info.seq_num = bus->tx_seq;
  196988. - hd_info.lastfrm = true;
  196989. - hd_info.tail_pad = pad;
  196990. - brcmf_sdio_hdpack(bus, frame, &hd_info);
  196991. -
  196992. - if (bus->txglom)
  196993. - brcmf_sdio_update_hwhdr(frame, len);
  196994. -
  196995. - if (!data_ok(bus)) {
  196996. - brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
  196997. - bus->tx_max, bus->tx_seq);
  196998. - bus->ctrl_frame_stat = true;
  196999. - /* Send from dpc */
  197000. - bus->ctrl_frame_buf = frame;
  197001. - bus->ctrl_frame_len = len;
  197002. + if (!data_ok(bus)) {
  197003. + brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
  197004. + bus->tx_max, bus->tx_seq);
  197005. + up(&bus->tx_seq_lock);
  197006. + /* Send from dpc */
  197007. + bus->ctrl_frame_buf = msg;
  197008. + bus->ctrl_frame_len = msglen;
  197009. + bus->ctrl_frame_stat = true;
  197010. wait_event_interruptible_timeout(bus->ctrl_wait,
  197011. !bus->ctrl_frame_stat,
  197012. @@ -2775,31 +2875,18 @@
  197013. ret = 0;
  197014. } else {
  197015. brcmf_dbg(SDIO, "ctrl_frame_stat == true\n");
  197016. + bus->ctrl_frame_stat = false;
  197017. + if (down_interruptible(&bus->tx_seq_lock))
  197018. + return -EINTR;
  197019. ret = -1;
  197020. }
  197021. }
  197022. -
  197023. if (ret == -1) {
  197024. - brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
  197025. - frame, len, "Tx Frame:\n");
  197026. - brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
  197027. - BRCMF_HDRS_ON(),
  197028. - frame, min_t(u16, len, 16), "TxHdr:\n");
  197029. -
  197030. - do {
  197031. - sdio_claim_host(bus->sdiodev->func[1]);
  197032. - ret = brcmf_sdio_tx_frame(bus, frame, len);
  197033. - sdio_release_host(bus->sdiodev->func[1]);
  197034. - } while (ret < 0 && retries++ < TXRETRIES);
  197035. - }
  197036. -
  197037. - if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) &&
  197038. - atomic_read(&bus->dpc_tskcnt) == 0) {
  197039. - bus->activity = false;
  197040. sdio_claim_host(bus->sdiodev->func[1]);
  197041. - brcmf_dbg(INFO, "idle\n");
  197042. - brcmf_sdio_clkctl(bus, CLK_NONE, true);
  197043. + brcmf_sdio_bus_sleep(bus, false, false);
  197044. + ret = brcmf_sdio_tx_ctrlframe(bus, msg, msglen);
  197045. sdio_release_host(bus->sdiodev->func[1]);
  197046. + up(&bus->tx_seq_lock);
  197047. }
  197048. if (ret)
  197049. @@ -2811,72 +2898,6 @@
  197050. }
  197051. #ifdef DEBUG
  197052. -static inline bool brcmf_sdio_valid_shared_address(u32 addr)
  197053. -{
  197054. - return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
  197055. -}
  197056. -
  197057. -static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
  197058. - struct sdpcm_shared *sh)
  197059. -{
  197060. - u32 addr;
  197061. - int rv;
  197062. - u32 shaddr = 0;
  197063. - struct sdpcm_shared_le sh_le;
  197064. - __le32 addr_le;
  197065. -
  197066. - shaddr = bus->ci->rambase + bus->ramsize - 4;
  197067. -
  197068. - /*
  197069. - * Read last word in socram to determine
  197070. - * address of sdpcm_shared structure
  197071. - */
  197072. - sdio_claim_host(bus->sdiodev->func[1]);
  197073. - brcmf_sdio_bus_sleep(bus, false, false);
  197074. - rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
  197075. - sdio_release_host(bus->sdiodev->func[1]);
  197076. - if (rv < 0)
  197077. - return rv;
  197078. -
  197079. - addr = le32_to_cpu(addr_le);
  197080. -
  197081. - brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
  197082. -
  197083. - /*
  197084. - * Check if addr is valid.
  197085. - * NVRAM length at the end of memory should have been overwritten.
  197086. - */
  197087. - if (!brcmf_sdio_valid_shared_address(addr)) {
  197088. - brcmf_err("invalid sdpcm_shared address 0x%08X\n",
  197089. - addr);
  197090. - return -EINVAL;
  197091. - }
  197092. -
  197093. - /* Read hndrte_shared structure */
  197094. - rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
  197095. - sizeof(struct sdpcm_shared_le));
  197096. - if (rv < 0)
  197097. - return rv;
  197098. -
  197099. - /* Endianness */
  197100. - sh->flags = le32_to_cpu(sh_le.flags);
  197101. - sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
  197102. - sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
  197103. - sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
  197104. - sh->assert_line = le32_to_cpu(sh_le.assert_line);
  197105. - sh->console_addr = le32_to_cpu(sh_le.console_addr);
  197106. - sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);
  197107. -
  197108. - if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
  197109. - brcmf_err("sdpcm shared version unsupported: dhd %d dongle %d\n",
  197110. - SDPCM_SHARED_VERSION,
  197111. - sh->flags & SDPCM_SHARED_VERSION_MASK);
  197112. - return -EPROTO;
  197113. - }
  197114. -
  197115. - return 0;
  197116. -}
  197117. -
  197118. static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
  197119. struct sdpcm_shared *sh, char __user *data,
  197120. size_t count)
  197121. @@ -3106,6 +3127,8 @@
  197122. debugfs_create_file("forensics", S_IRUGO, dentry, bus,
  197123. &brcmf_sdio_forensic_ops);
  197124. brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt);
  197125. + debugfs_create_u32("console_interval", 0644, dentry,
  197126. + &bus->console_interval);
  197127. }
  197128. #else
  197129. static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
  197130. @@ -3224,51 +3247,29 @@
  197131. const struct firmware *fw)
  197132. {
  197133. int err;
  197134. - int offset;
  197135. - int address;
  197136. - int len;
  197137. brcmf_dbg(TRACE, "Enter\n");
  197138. - err = 0;
  197139. - offset = 0;
  197140. - address = bus->ci->rambase;
  197141. - while (offset < fw->size) {
  197142. - len = ((offset + MEMBLOCK) < fw->size) ? MEMBLOCK :
  197143. - fw->size - offset;
  197144. - err = brcmf_sdiod_ramrw(bus->sdiodev, true, address,
  197145. - (u8 *)&fw->data[offset], len);
  197146. - if (err) {
  197147. - brcmf_err("error %d on writing %d membytes at 0x%08x\n",
  197148. - err, len, address);
  197149. - return err;
  197150. - }
  197151. - offset += len;
  197152. - address += len;
  197153. - }
  197154. - if (!err)
  197155. - if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase,
  197156. - (u8 *)fw->data, fw->size))
  197157. - err = -EIO;
  197158. + err = brcmf_sdiod_ramrw(bus->sdiodev, true, bus->ci->rambase,
  197159. + (u8 *)fw->data, fw->size);
  197160. + if (err)
  197161. + brcmf_err("error %d on writing %d membytes at 0x%08x\n",
  197162. + err, (int)fw->size, bus->ci->rambase);
  197163. + else if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase,
  197164. + (u8 *)fw->data, fw->size))
  197165. + err = -EIO;
  197166. return err;
  197167. }
  197168. static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus,
  197169. - const struct firmware *nv)
  197170. + void *vars, u32 varsz)
  197171. {
  197172. - void *vars;
  197173. - u32 varsz;
  197174. int address;
  197175. int err;
  197176. brcmf_dbg(TRACE, "Enter\n");
  197177. - vars = brcmf_nvram_strip(nv, &varsz);
  197178. -
  197179. - if (vars == NULL)
  197180. - return -EINVAL;
  197181. -
  197182. address = bus->ci->ramsize - varsz + bus->ci->rambase;
  197183. err = brcmf_sdiod_ramrw(bus->sdiodev, true, address, vars, varsz);
  197184. if (err)
  197185. @@ -3277,28 +3278,21 @@
  197186. else if (!brcmf_sdio_verifymemory(bus->sdiodev, address, vars, varsz))
  197187. err = -EIO;
  197188. - brcmf_nvram_free(vars);
  197189. -
  197190. return err;
  197191. }
  197192. -static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus)
  197193. +static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
  197194. + const struct firmware *fw,
  197195. + void *nvram, u32 nvlen)
  197196. {
  197197. int bcmerror = -EFAULT;
  197198. - const struct firmware *fw;
  197199. u32 rstvec;
  197200. sdio_claim_host(bus->sdiodev->func[1]);
  197201. brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
  197202. /* Keep arm in reset */
  197203. - brcmf_sdio_chip_enter_download(bus->sdiodev, bus->ci);
  197204. -
  197205. - fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN);
  197206. - if (fw == NULL) {
  197207. - bcmerror = -ENOENT;
  197208. - goto err;
  197209. - }
  197210. + brcmf_chip_enter_download(bus->ci);
  197211. rstvec = get_unaligned_le32(fw->data);
  197212. brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
  197213. @@ -3307,24 +3301,19 @@
  197214. release_firmware(fw);
  197215. if (bcmerror) {
  197216. brcmf_err("dongle image file download failed\n");
  197217. + brcmf_fw_nvram_free(nvram);
  197218. goto err;
  197219. }
  197220. - fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM);
  197221. - if (fw == NULL) {
  197222. - bcmerror = -ENOENT;
  197223. - goto err;
  197224. - }
  197225. -
  197226. - bcmerror = brcmf_sdio_download_nvram(bus, fw);
  197227. - release_firmware(fw);
  197228. + bcmerror = brcmf_sdio_download_nvram(bus, nvram, nvlen);
  197229. + brcmf_fw_nvram_free(nvram);
  197230. if (bcmerror) {
  197231. brcmf_err("dongle nvram file download failed\n");
  197232. goto err;
  197233. }
  197234. /* Take arm out of reset */
  197235. - if (!brcmf_sdio_chip_exit_download(bus->sdiodev, bus->ci, rstvec)) {
  197236. + if (!brcmf_chip_exit_download(bus->ci, rstvec)) {
  197237. brcmf_err("error getting out of ARM core reset\n");
  197238. goto err;
  197239. }
  197240. @@ -3339,40 +3328,6 @@
  197241. return bcmerror;
  197242. }
  197243. -static bool brcmf_sdio_sr_capable(struct brcmf_sdio *bus)
  197244. -{
  197245. - u32 addr, reg, pmu_cc3_mask = ~0;
  197246. - int err;
  197247. -
  197248. - brcmf_dbg(TRACE, "Enter\n");
  197249. -
  197250. - /* old chips with PMU version less than 17 don't support save restore */
  197251. - if (bus->ci->pmurev < 17)
  197252. - return false;
  197253. -
  197254. - switch (bus->ci->chip) {
  197255. - case BCM43241_CHIP_ID:
  197256. - case BCM4335_CHIP_ID:
  197257. - case BCM4339_CHIP_ID:
  197258. - /* read PMU chipcontrol register 3 */
  197259. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr);
  197260. - brcmf_sdiod_regwl(bus->sdiodev, addr, 3, NULL);
  197261. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data);
  197262. - reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL);
  197263. - return (reg & pmu_cc3_mask) != 0;
  197264. - default:
  197265. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, pmucapabilities_ext);
  197266. - reg = brcmf_sdiod_regrl(bus->sdiodev, addr, &err);
  197267. - if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
  197268. - return false;
  197269. -
  197270. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, retention_ctl);
  197271. - reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL);
  197272. - return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
  197273. - PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
  197274. - }
  197275. -}
  197276. -
  197277. static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
  197278. {
  197279. int err = 0;
  197280. @@ -3424,7 +3379,7 @@
  197281. brcmf_dbg(TRACE, "Enter\n");
  197282. /* KSO bit added in SDIO core rev 12 */
  197283. - if (bus->ci->c_inf[1].rev < 12)
  197284. + if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12)
  197285. return 0;
  197286. val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
  197287. @@ -3455,15 +3410,13 @@
  197288. struct brcmf_sdio *bus = sdiodev->bus;
  197289. uint pad_size;
  197290. u32 value;
  197291. - u8 idx;
  197292. int err;
  197293. /* the commands below use the terms tx and rx from
  197294. * a device perspective, ie. bus:txglom affects the
  197295. * bus transfers from device to host.
  197296. */
  197297. - idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  197298. - if (bus->ci->c_inf[idx].rev < 12) {
  197299. + if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) {
  197300. /* for sdio core rev < 12, disable txgloming */
  197301. value = 0;
  197302. err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
  197303. @@ -3503,97 +3456,6 @@
  197304. return err;
  197305. }
  197306. -static int brcmf_sdio_bus_init(struct device *dev)
  197307. -{
  197308. - struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  197309. - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  197310. - struct brcmf_sdio *bus = sdiodev->bus;
  197311. - int err, ret = 0;
  197312. - u8 saveclk;
  197313. -
  197314. - brcmf_dbg(TRACE, "Enter\n");
  197315. -
  197316. - /* try to download image and nvram to the dongle */
  197317. - if (bus_if->state == BRCMF_BUS_DOWN) {
  197318. - bus->alp_only = true;
  197319. - err = brcmf_sdio_download_firmware(bus);
  197320. - if (err)
  197321. - return err;
  197322. - bus->alp_only = false;
  197323. - }
  197324. -
  197325. - if (!bus->sdiodev->bus_if->drvr)
  197326. - return 0;
  197327. -
  197328. - /* Start the watchdog timer */
  197329. - bus->sdcnt.tickcnt = 0;
  197330. - brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
  197331. -
  197332. - sdio_claim_host(bus->sdiodev->func[1]);
  197333. -
  197334. - /* Make sure backplane clock is on, needed to generate F2 interrupt */
  197335. - brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
  197336. - if (bus->clkstate != CLK_AVAIL)
  197337. - goto exit;
  197338. -
  197339. - /* Force clocks on backplane to be sure F2 interrupt propagates */
  197340. - saveclk = brcmf_sdiod_regrb(bus->sdiodev,
  197341. - SBSDIO_FUNC1_CHIPCLKCSR, &err);
  197342. - if (!err) {
  197343. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  197344. - (saveclk | SBSDIO_FORCE_HT), &err);
  197345. - }
  197346. - if (err) {
  197347. - brcmf_err("Failed to force clock for F2: err %d\n", err);
  197348. - goto exit;
  197349. - }
  197350. -
  197351. - /* Enable function 2 (frame transfers) */
  197352. - w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
  197353. - offsetof(struct sdpcmd_regs, tosbmailboxdata));
  197354. - err = sdio_enable_func(bus->sdiodev->func[SDIO_FUNC_2]);
  197355. -
  197356. -
  197357. - brcmf_dbg(INFO, "enable F2: err=%d\n", err);
  197358. -
  197359. - /* If F2 successfully enabled, set core and enable interrupts */
  197360. - if (!err) {
  197361. - /* Set up the interrupt mask and enable interrupts */
  197362. - bus->hostintmask = HOSTINTMASK;
  197363. - w_sdreg32(bus, bus->hostintmask,
  197364. - offsetof(struct sdpcmd_regs, hostintmask));
  197365. -
  197366. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err);
  197367. - } else {
  197368. - /* Disable F2 again */
  197369. - sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
  197370. - ret = -ENODEV;
  197371. - }
  197372. -
  197373. - if (brcmf_sdio_sr_capable(bus)) {
  197374. - brcmf_sdio_sr_init(bus);
  197375. - } else {
  197376. - /* Restore previous clock setting */
  197377. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  197378. - saveclk, &err);
  197379. - }
  197380. -
  197381. - if (ret == 0) {
  197382. - ret = brcmf_sdiod_intr_register(bus->sdiodev);
  197383. - if (ret != 0)
  197384. - brcmf_err("intr register failed:%d\n", ret);
  197385. - }
  197386. -
  197387. - /* If we didn't come up, turn off backplane clock */
  197388. - if (ret != 0)
  197389. - brcmf_sdio_clkctl(bus, CLK_NONE, false);
  197390. -
  197391. -exit:
  197392. - sdio_release_host(bus->sdiodev->func[1]);
  197393. -
  197394. - return ret;
  197395. -}
  197396. -
  197397. void brcmf_sdio_isr(struct brcmf_sdio *bus)
  197398. {
  197399. brcmf_dbg(TRACE, "Enter\n");
  197400. @@ -3714,11 +3576,175 @@
  197401. datawork);
  197402. while (atomic_read(&bus->dpc_tskcnt)) {
  197403. + atomic_set(&bus->dpc_tskcnt, 0);
  197404. brcmf_sdio_dpc(bus);
  197405. - atomic_dec(&bus->dpc_tskcnt);
  197406. }
  197407. }
  197408. +static void
  197409. +brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
  197410. + struct brcmf_chip *ci, u32 drivestrength)
  197411. +{
  197412. + const struct sdiod_drive_str *str_tab = NULL;
  197413. + u32 str_mask;
  197414. + u32 str_shift;
  197415. + u32 base;
  197416. + u32 i;
  197417. + u32 drivestrength_sel = 0;
  197418. + u32 cc_data_temp;
  197419. + u32 addr;
  197420. +
  197421. + if (!(ci->cc_caps & CC_CAP_PMU))
  197422. + return;
  197423. +
  197424. + switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
  197425. + case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
  197426. + str_tab = sdiod_drvstr_tab1_1v8;
  197427. + str_mask = 0x00003800;
  197428. + str_shift = 11;
  197429. + break;
  197430. + case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
  197431. + str_tab = sdiod_drvstr_tab6_1v8;
  197432. + str_mask = 0x00001800;
  197433. + str_shift = 11;
  197434. + break;
  197435. + case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
  197436. + /* note: 43143 does not support tristate */
  197437. + i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
  197438. + if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
  197439. + str_tab = sdiod_drvstr_tab2_3v3;
  197440. + str_mask = 0x00000007;
  197441. + str_shift = 0;
  197442. + } else
  197443. + brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
  197444. + ci->name, drivestrength);
  197445. + break;
  197446. + case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
  197447. + str_tab = sdiod_drive_strength_tab5_1v8;
  197448. + str_mask = 0x00003800;
  197449. + str_shift = 11;
  197450. + break;
  197451. + default:
  197452. + brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
  197453. + ci->name, ci->chiprev, ci->pmurev);
  197454. + break;
  197455. + }
  197456. +
  197457. + if (str_tab != NULL) {
  197458. + for (i = 0; str_tab[i].strength != 0; i++) {
  197459. + if (drivestrength >= str_tab[i].strength) {
  197460. + drivestrength_sel = str_tab[i].sel;
  197461. + break;
  197462. + }
  197463. + }
  197464. + base = brcmf_chip_get_chipcommon(ci)->base;
  197465. + addr = CORE_CC_REG(base, chipcontrol_addr);
  197466. + brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
  197467. + cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
  197468. + cc_data_temp &= ~str_mask;
  197469. + drivestrength_sel <<= str_shift;
  197470. + cc_data_temp |= drivestrength_sel;
  197471. + brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
  197472. +
  197473. + brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
  197474. + str_tab[i].strength, drivestrength, cc_data_temp);
  197475. + }
  197476. +}
  197477. +
  197478. +static int brcmf_sdio_buscoreprep(void *ctx)
  197479. +{
  197480. + struct brcmf_sdio_dev *sdiodev = ctx;
  197481. + int err = 0;
  197482. + u8 clkval, clkset;
  197483. +
  197484. + /* Try forcing SDIO core to do ALPAvail request only */
  197485. + clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
  197486. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  197487. + if (err) {
  197488. + brcmf_err("error writing for HT off\n");
  197489. + return err;
  197490. + }
  197491. +
  197492. + /* If register supported, wait for ALPAvail and then force ALP */
  197493. + /* This may take up to 15 milliseconds */
  197494. + clkval = brcmf_sdiod_regrb(sdiodev,
  197495. + SBSDIO_FUNC1_CHIPCLKCSR, NULL);
  197496. +
  197497. + if ((clkval & ~SBSDIO_AVBITS) != clkset) {
  197498. + brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
  197499. + clkset, clkval);
  197500. + return -EACCES;
  197501. + }
  197502. +
  197503. + SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
  197504. + SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
  197505. + !SBSDIO_ALPAV(clkval)),
  197506. + PMU_MAX_TRANSITION_DLY);
  197507. + if (!SBSDIO_ALPAV(clkval)) {
  197508. + brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
  197509. + clkval);
  197510. + return -EBUSY;
  197511. + }
  197512. +
  197513. + clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
  197514. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  197515. + udelay(65);
  197516. +
  197517. + /* Also, disable the extra SDIO pull-ups */
  197518. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
  197519. +
  197520. + return 0;
  197521. +}
  197522. +
  197523. +static void brcmf_sdio_buscore_exitdl(void *ctx, struct brcmf_chip *chip,
  197524. + u32 rstvec)
  197525. +{
  197526. + struct brcmf_sdio_dev *sdiodev = ctx;
  197527. + struct brcmf_core *core;
  197528. + u32 reg_addr;
  197529. +
  197530. + /* clear all interrupts */
  197531. + core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
  197532. + reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus);
  197533. + brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
  197534. +
  197535. + if (rstvec)
  197536. + /* Write reset vector to address 0 */
  197537. + brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&rstvec,
  197538. + sizeof(rstvec));
  197539. +}
  197540. +
  197541. +static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
  197542. +{
  197543. + struct brcmf_sdio_dev *sdiodev = ctx;
  197544. + u32 val, rev;
  197545. +
  197546. + val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
  197547. + if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
  197548. + addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
  197549. + rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
  197550. + if (rev >= 2) {
  197551. + val &= ~CID_ID_MASK;
  197552. + val |= BCM4339_CHIP_ID;
  197553. + }
  197554. + }
  197555. + return val;
  197556. +}
  197557. +
  197558. +static void brcmf_sdio_buscore_write32(void *ctx, u32 addr, u32 val)
  197559. +{
  197560. + struct brcmf_sdio_dev *sdiodev = ctx;
  197561. +
  197562. + brcmf_sdiod_regwl(sdiodev, addr, val, NULL);
  197563. +}
  197564. +
  197565. +static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
  197566. + .prepare = brcmf_sdio_buscoreprep,
  197567. + .exit_dl = brcmf_sdio_buscore_exitdl,
  197568. + .read32 = brcmf_sdio_buscore_read32,
  197569. + .write32 = brcmf_sdio_buscore_write32,
  197570. +};
  197571. +
  197572. static bool
  197573. brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
  197574. {
  197575. @@ -3734,7 +3760,7 @@
  197576. brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
  197577. /*
  197578. - * Force PLL off until brcmf_sdio_chip_attach()
  197579. + * Force PLL off until brcmf_chip_attach()
  197580. * programs PLL control regs
  197581. */
  197582. @@ -3755,8 +3781,10 @@
  197583. */
  197584. brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN);
  197585. - if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci)) {
  197586. - brcmf_err("brcmf_sdio_chip_attach failed!\n");
  197587. + bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops);
  197588. + if (IS_ERR(bus->ci)) {
  197589. + brcmf_err("brcmf_chip_attach failed!\n");
  197590. + bus->ci = NULL;
  197591. goto fail;
  197592. }
  197593. @@ -3769,7 +3797,7 @@
  197594. drivestrength = bus->sdiodev->pdata->drive_strength;
  197595. else
  197596. drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;
  197597. - brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength);
  197598. + brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength);
  197599. /* Get info on the SOCRAM cores... */
  197600. bus->ramsize = bus->ci->ramsize;
  197601. @@ -3792,24 +3820,18 @@
  197602. goto fail;
  197603. /* set PMUControl so a backplane reset does PMU state reload */
  197604. - reg_addr = CORE_CC_REG(bus->ci->c_inf[0].base,
  197605. + reg_addr = CORE_CC_REG(brcmf_chip_get_chipcommon(bus->ci)->base,
  197606. pmucontrol);
  197607. - reg_val = brcmf_sdiod_regrl(bus->sdiodev,
  197608. - reg_addr,
  197609. - &err);
  197610. + reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err);
  197611. if (err)
  197612. goto fail;
  197613. reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT);
  197614. - brcmf_sdiod_regwl(bus->sdiodev,
  197615. - reg_addr,
  197616. - reg_val,
  197617. - &err);
  197618. + brcmf_sdiod_regwl(bus->sdiodev, reg_addr, reg_val, &err);
  197619. if (err)
  197620. goto fail;
  197621. -
  197622. sdio_release_host(bus->sdiodev->func[1]);
  197623. brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
  197624. @@ -3849,6 +3871,7 @@
  197625. brcmf_sdio_bus_watchdog(bus);
  197626. /* Count the tick for reference */
  197627. bus->sdcnt.tickcnt++;
  197628. + reinit_completion(&bus->watchdog_wait);
  197629. } else
  197630. break;
  197631. }
  197632. @@ -3872,13 +3895,114 @@
  197633. static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
  197634. .stop = brcmf_sdio_bus_stop,
  197635. .preinit = brcmf_sdio_bus_preinit,
  197636. - .init = brcmf_sdio_bus_init,
  197637. .txdata = brcmf_sdio_bus_txdata,
  197638. .txctl = brcmf_sdio_bus_txctl,
  197639. .rxctl = brcmf_sdio_bus_rxctl,
  197640. .gettxq = brcmf_sdio_bus_gettxq,
  197641. };
  197642. +static void brcmf_sdio_firmware_callback(struct device *dev,
  197643. + const struct firmware *code,
  197644. + void *nvram, u32 nvram_len)
  197645. +{
  197646. + struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  197647. + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  197648. + struct brcmf_sdio *bus = sdiodev->bus;
  197649. + int err = 0;
  197650. + u8 saveclk;
  197651. +
  197652. + brcmf_dbg(TRACE, "Enter: dev=%s\n", dev_name(dev));
  197653. +
  197654. + /* try to download image and nvram to the dongle */
  197655. + if (bus_if->state == BRCMF_BUS_DOWN) {
  197656. + bus->alp_only = true;
  197657. + err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
  197658. + if (err)
  197659. + goto fail;
  197660. + bus->alp_only = false;
  197661. + }
  197662. +
  197663. + if (!bus_if->drvr)
  197664. + return;
  197665. +
  197666. + /* Start the watchdog timer */
  197667. + bus->sdcnt.tickcnt = 0;
  197668. + brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
  197669. +
  197670. + sdio_claim_host(sdiodev->func[1]);
  197671. +
  197672. + /* Make sure backplane clock is on, needed to generate F2 interrupt */
  197673. + brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
  197674. + if (bus->clkstate != CLK_AVAIL)
  197675. + goto release;
  197676. +
  197677. + /* Force clocks on backplane to be sure F2 interrupt propagates */
  197678. + saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
  197679. + if (!err) {
  197680. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  197681. + (saveclk | SBSDIO_FORCE_HT), &err);
  197682. + }
  197683. + if (err) {
  197684. + brcmf_err("Failed to force clock for F2: err %d\n", err);
  197685. + goto release;
  197686. + }
  197687. +
  197688. + /* Enable function 2 (frame transfers) */
  197689. + w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
  197690. + offsetof(struct sdpcmd_regs, tosbmailboxdata));
  197691. + err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]);
  197692. +
  197693. +
  197694. + brcmf_dbg(INFO, "enable F2: err=%d\n", err);
  197695. +
  197696. + /* If F2 successfully enabled, set core and enable interrupts */
  197697. + if (!err) {
  197698. + /* Set up the interrupt mask and enable interrupts */
  197699. + bus->hostintmask = HOSTINTMASK;
  197700. + w_sdreg32(bus, bus->hostintmask,
  197701. + offsetof(struct sdpcmd_regs, hostintmask));
  197702. +
  197703. + brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, 8, &err);
  197704. + } else {
  197705. + /* Disable F2 again */
  197706. + sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
  197707. + goto release;
  197708. + }
  197709. +
  197710. + if (brcmf_chip_sr_capable(bus->ci)) {
  197711. + brcmf_sdio_sr_init(bus);
  197712. + } else {
  197713. + /* Restore previous clock setting */
  197714. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  197715. + saveclk, &err);
  197716. + }
  197717. +
  197718. + if (err == 0) {
  197719. + err = brcmf_sdiod_intr_register(sdiodev);
  197720. + if (err != 0)
  197721. + brcmf_err("intr register failed:%d\n", err);
  197722. + }
  197723. +
  197724. + /* If we didn't come up, turn off backplane clock */
  197725. + if (err != 0)
  197726. + brcmf_sdio_clkctl(bus, CLK_NONE, false);
  197727. +
  197728. + sdio_release_host(sdiodev->func[1]);
  197729. +
  197730. + err = brcmf_bus_start(dev);
  197731. + if (err != 0) {
  197732. + brcmf_err("dongle is not responding\n");
  197733. + goto fail;
  197734. + }
  197735. + return;
  197736. +
  197737. +release:
  197738. + sdio_release_host(sdiodev->func[1]);
  197739. +fail:
  197740. + brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err);
  197741. + device_release_driver(dev);
  197742. +}
  197743. +
  197744. struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
  197745. {
  197746. int ret;
  197747. @@ -3925,7 +4049,8 @@
  197748. }
  197749. spin_lock_init(&bus->rxctl_lock);
  197750. - spin_lock_init(&bus->txqlock);
  197751. + spin_lock_init(&bus->txq_lock);
  197752. + sema_init(&bus->tx_seq_lock, 1);
  197753. init_waitqueue_head(&bus->ctrl_wait);
  197754. init_waitqueue_head(&bus->dcmd_resp_wait);
  197755. @@ -3961,8 +4086,13 @@
  197756. goto fail;
  197757. }
  197758. + /* Query the F2 block size, set roundup accordingly */
  197759. + bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
  197760. + bus->roundup = min(max_roundup, bus->blocksize);
  197761. +
  197762. /* Allocate buffers */
  197763. if (bus->sdiodev->bus_if->maxctl) {
  197764. + bus->sdiodev->bus_if->maxctl += bus->roundup;
  197765. bus->rxblen =
  197766. roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN),
  197767. ALIGNMENT) + bus->head_align;
  197768. @@ -3990,10 +4120,6 @@
  197769. bus->idletime = BRCMF_IDLE_INTERVAL;
  197770. bus->idleclock = BRCMF_IDLE_ACTIVE;
  197771. - /* Query the F2 block size, set roundup accordingly */
  197772. - bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
  197773. - bus->roundup = min(max_roundup, bus->blocksize);
  197774. -
  197775. /* SR state */
  197776. bus->sleeping = false;
  197777. bus->sr_enabled = false;
  197778. @@ -4001,10 +4127,14 @@
  197779. brcmf_sdio_debugfs_create(bus);
  197780. brcmf_dbg(INFO, "completed!!\n");
  197781. - /* if firmware path present try to download and bring up bus */
  197782. - ret = brcmf_bus_start(bus->sdiodev->dev);
  197783. + ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM,
  197784. + brcmf_sdio_get_fwname(bus->ci,
  197785. + BRCMF_FIRMWARE_BIN),
  197786. + brcmf_sdio_get_fwname(bus->ci,
  197787. + BRCMF_FIRMWARE_NVRAM),
  197788. + brcmf_sdio_firmware_callback);
  197789. if (ret != 0) {
  197790. - brcmf_err("dongle is not responding\n");
  197791. + brcmf_err("async firmware request failed: %d\n", ret);
  197792. goto fail;
  197793. }
  197794. @@ -4024,14 +4154,12 @@
  197795. /* De-register interrupt handler */
  197796. brcmf_sdiod_intr_unregister(bus->sdiodev);
  197797. + brcmf_detach(bus->sdiodev->dev);
  197798. +
  197799. cancel_work_sync(&bus->datawork);
  197800. if (bus->brcmf_wq)
  197801. destroy_workqueue(bus->brcmf_wq);
  197802. - if (bus->sdiodev->bus_if->drvr) {
  197803. - brcmf_detach(bus->sdiodev->dev);
  197804. - }
  197805. -
  197806. if (bus->ci) {
  197807. if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
  197808. sdio_claim_host(bus->sdiodev->func[1]);
  197809. @@ -4042,12 +4170,11 @@
  197810. * all necessary cores.
  197811. */
  197812. msleep(20);
  197813. - brcmf_sdio_chip_enter_download(bus->sdiodev,
  197814. - bus->ci);
  197815. + brcmf_chip_enter_download(bus->ci);
  197816. brcmf_sdio_clkctl(bus, CLK_NONE, false);
  197817. sdio_release_host(bus->sdiodev->func[1]);
  197818. }
  197819. - brcmf_sdio_chip_detach(&bus->ci);
  197820. + brcmf_chip_detach(bus->ci);
  197821. }
  197822. kfree(bus->rxbuf);
  197823. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
  197824. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.c 1969-12-31 18:00:00.000000000 -0600
  197825. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.c 2014-12-08 00:31:53.840418001 -0600
  197826. @@ -0,0 +1,332 @@
  197827. +/*
  197828. + * Copyright (c) 2013 Broadcom Corporation
  197829. + *
  197830. + * Permission to use, copy, modify, and/or distribute this software for any
  197831. + * purpose with or without fee is hereby granted, provided that the above
  197832. + * copyright notice and this permission notice appear in all copies.
  197833. + *
  197834. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  197835. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  197836. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  197837. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  197838. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  197839. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  197840. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  197841. + */
  197842. +
  197843. +#include <linux/kernel.h>
  197844. +#include <linux/slab.h>
  197845. +#include <linux/device.h>
  197846. +#include <linux/firmware.h>
  197847. +
  197848. +#include "dhd_dbg.h"
  197849. +#include "firmware.h"
  197850. +
  197851. +enum nvram_parser_state {
  197852. + IDLE,
  197853. + KEY,
  197854. + VALUE,
  197855. + COMMENT,
  197856. + END
  197857. +};
  197858. +
  197859. +/**
  197860. + * struct nvram_parser - internal info for parser.
  197861. + *
  197862. + * @state: current parser state.
  197863. + * @fwnv: input buffer being parsed.
  197864. + * @nvram: output buffer with parse result.
  197865. + * @nvram_len: lenght of parse result.
  197866. + * @line: current line.
  197867. + * @column: current column in line.
  197868. + * @pos: byte offset in input buffer.
  197869. + * @entry: start position of key,value entry.
  197870. + */
  197871. +struct nvram_parser {
  197872. + enum nvram_parser_state state;
  197873. + const struct firmware *fwnv;
  197874. + u8 *nvram;
  197875. + u32 nvram_len;
  197876. + u32 line;
  197877. + u32 column;
  197878. + u32 pos;
  197879. + u32 entry;
  197880. +};
  197881. +
  197882. +static bool is_nvram_char(char c)
  197883. +{
  197884. + /* comment marker excluded */
  197885. + if (c == '#')
  197886. + return false;
  197887. +
  197888. + /* key and value may have any other readable character */
  197889. + return (c > 0x20 && c < 0x7f);
  197890. +}
  197891. +
  197892. +static bool is_whitespace(char c)
  197893. +{
  197894. + return (c == ' ' || c == '\r' || c == '\n' || c == '\t');
  197895. +}
  197896. +
  197897. +static enum nvram_parser_state brcmf_nvram_handle_idle(struct nvram_parser *nvp)
  197898. +{
  197899. + char c;
  197900. +
  197901. + c = nvp->fwnv->data[nvp->pos];
  197902. + if (c == '\n')
  197903. + return COMMENT;
  197904. + if (is_whitespace(c))
  197905. + goto proceed;
  197906. + if (c == '#')
  197907. + return COMMENT;
  197908. + if (is_nvram_char(c)) {
  197909. + nvp->entry = nvp->pos;
  197910. + return KEY;
  197911. + }
  197912. + brcmf_dbg(INFO, "warning: ln=%d:col=%d: ignoring invalid character\n",
  197913. + nvp->line, nvp->column);
  197914. +proceed:
  197915. + nvp->column++;
  197916. + nvp->pos++;
  197917. + return IDLE;
  197918. +}
  197919. +
  197920. +static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp)
  197921. +{
  197922. + enum nvram_parser_state st = nvp->state;
  197923. + char c;
  197924. +
  197925. + c = nvp->fwnv->data[nvp->pos];
  197926. + if (c == '=') {
  197927. + st = VALUE;
  197928. + } else if (!is_nvram_char(c)) {
  197929. + brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
  197930. + nvp->line, nvp->column);
  197931. + return COMMENT;
  197932. + }
  197933. +
  197934. + nvp->column++;
  197935. + nvp->pos++;
  197936. + return st;
  197937. +}
  197938. +
  197939. +static enum nvram_parser_state
  197940. +brcmf_nvram_handle_value(struct nvram_parser *nvp)
  197941. +{
  197942. + char c;
  197943. + char *skv;
  197944. + char *ekv;
  197945. + u32 cplen;
  197946. +
  197947. + c = nvp->fwnv->data[nvp->pos];
  197948. + if (!is_nvram_char(c)) {
  197949. + /* key,value pair complete */
  197950. + ekv = (u8 *)&nvp->fwnv->data[nvp->pos];
  197951. + skv = (u8 *)&nvp->fwnv->data[nvp->entry];
  197952. + cplen = ekv - skv;
  197953. + /* copy to output buffer */
  197954. + memcpy(&nvp->nvram[nvp->nvram_len], skv, cplen);
  197955. + nvp->nvram_len += cplen;
  197956. + nvp->nvram[nvp->nvram_len] = '\0';
  197957. + nvp->nvram_len++;
  197958. + return IDLE;
  197959. + }
  197960. + nvp->pos++;
  197961. + nvp->column++;
  197962. + return VALUE;
  197963. +}
  197964. +
  197965. +static enum nvram_parser_state
  197966. +brcmf_nvram_handle_comment(struct nvram_parser *nvp)
  197967. +{
  197968. + char *eol, *sol;
  197969. +
  197970. + sol = (char *)&nvp->fwnv->data[nvp->pos];
  197971. + eol = strchr(sol, '\n');
  197972. + if (eol == NULL)
  197973. + return END;
  197974. +
  197975. + /* eat all moving to next line */
  197976. + nvp->line++;
  197977. + nvp->column = 1;
  197978. + nvp->pos += (eol - sol) + 1;
  197979. + return IDLE;
  197980. +}
  197981. +
  197982. +static enum nvram_parser_state brcmf_nvram_handle_end(struct nvram_parser *nvp)
  197983. +{
  197984. + /* final state */
  197985. + return END;
  197986. +}
  197987. +
  197988. +static enum nvram_parser_state
  197989. +(*nv_parser_states[])(struct nvram_parser *nvp) = {
  197990. + brcmf_nvram_handle_idle,
  197991. + brcmf_nvram_handle_key,
  197992. + brcmf_nvram_handle_value,
  197993. + brcmf_nvram_handle_comment,
  197994. + brcmf_nvram_handle_end
  197995. +};
  197996. +
  197997. +static int brcmf_init_nvram_parser(struct nvram_parser *nvp,
  197998. + const struct firmware *nv)
  197999. +{
  198000. + memset(nvp, 0, sizeof(*nvp));
  198001. + nvp->fwnv = nv;
  198002. + /* Alloc for extra 0 byte + roundup by 4 + length field */
  198003. + nvp->nvram = kzalloc(nv->size + 1 + 3 + sizeof(u32), GFP_KERNEL);
  198004. + if (!nvp->nvram)
  198005. + return -ENOMEM;
  198006. +
  198007. + nvp->line = 1;
  198008. + nvp->column = 1;
  198009. + return 0;
  198010. +}
  198011. +
  198012. +/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a fil
  198013. + * and ending in a NUL. Removes carriage returns, empty lines, comment lines,
  198014. + * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
  198015. + * End of buffer is completed with token identifying length of buffer.
  198016. + */
  198017. +static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length)
  198018. +{
  198019. + struct nvram_parser nvp;
  198020. + u32 pad;
  198021. + u32 token;
  198022. + __le32 token_le;
  198023. +
  198024. + if (brcmf_init_nvram_parser(&nvp, nv) < 0)
  198025. + return NULL;
  198026. +
  198027. + while (nvp.pos < nv->size) {
  198028. + nvp.state = nv_parser_states[nvp.state](&nvp);
  198029. + if (nvp.state == END)
  198030. + break;
  198031. + }
  198032. + pad = nvp.nvram_len;
  198033. + *new_length = roundup(nvp.nvram_len + 1, 4);
  198034. + while (pad != *new_length) {
  198035. + nvp.nvram[pad] = 0;
  198036. + pad++;
  198037. + }
  198038. +
  198039. + token = *new_length / 4;
  198040. + token = (~token << 16) | (token & 0x0000FFFF);
  198041. + token_le = cpu_to_le32(token);
  198042. +
  198043. + memcpy(&nvp.nvram[*new_length], &token_le, sizeof(token_le));
  198044. + *new_length += sizeof(token_le);
  198045. +
  198046. + return nvp.nvram;
  198047. +}
  198048. +
  198049. +void brcmf_fw_nvram_free(void *nvram)
  198050. +{
  198051. + kfree(nvram);
  198052. +}
  198053. +
  198054. +struct brcmf_fw {
  198055. + struct device *dev;
  198056. + u16 flags;
  198057. + const struct firmware *code;
  198058. + const char *nvram_name;
  198059. + void (*done)(struct device *dev, const struct firmware *fw,
  198060. + void *nvram_image, u32 nvram_len);
  198061. +};
  198062. +
  198063. +static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
  198064. +{
  198065. + struct brcmf_fw *fwctx = ctx;
  198066. + u32 nvram_length = 0;
  198067. + void *nvram = NULL;
  198068. +
  198069. + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
  198070. + if (!fw && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
  198071. + goto fail;
  198072. +
  198073. + if (fw) {
  198074. + nvram = brcmf_fw_nvram_strip(fw, &nvram_length);
  198075. + release_firmware(fw);
  198076. + if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
  198077. + goto fail;
  198078. + }
  198079. +
  198080. + fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length);
  198081. + kfree(fwctx);
  198082. + return;
  198083. +
  198084. +fail:
  198085. + brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
  198086. + if (fwctx->code)
  198087. + release_firmware(fwctx->code);
  198088. + device_release_driver(fwctx->dev);
  198089. + kfree(fwctx);
  198090. +}
  198091. +
  198092. +static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
  198093. +{
  198094. + struct brcmf_fw *fwctx = ctx;
  198095. + int ret;
  198096. +
  198097. + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
  198098. + if (!fw)
  198099. + goto fail;
  198100. +
  198101. + /* only requested code so done here */
  198102. + if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) {
  198103. + fwctx->done(fwctx->dev, fw, NULL, 0);
  198104. + kfree(fwctx);
  198105. + return;
  198106. + }
  198107. + fwctx->code = fw;
  198108. + ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name,
  198109. + fwctx->dev, GFP_KERNEL, fwctx,
  198110. + brcmf_fw_request_nvram_done);
  198111. +
  198112. + if (!ret)
  198113. + return;
  198114. +
  198115. + /* when nvram is optional call .done() callback here */
  198116. + if (fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL) {
  198117. + fwctx->done(fwctx->dev, fw, NULL, 0);
  198118. + kfree(fwctx);
  198119. + return;
  198120. + }
  198121. +
  198122. + /* failed nvram request */
  198123. + release_firmware(fw);
  198124. +fail:
  198125. + brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
  198126. + device_release_driver(fwctx->dev);
  198127. + kfree(fwctx);
  198128. +}
  198129. +
  198130. +int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
  198131. + const char *code, const char *nvram,
  198132. + void (*fw_cb)(struct device *dev,
  198133. + const struct firmware *fw,
  198134. + void *nvram_image, u32 nvram_len))
  198135. +{
  198136. + struct brcmf_fw *fwctx;
  198137. +
  198138. + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
  198139. + if (!fw_cb || !code)
  198140. + return -EINVAL;
  198141. +
  198142. + if ((flags & BRCMF_FW_REQUEST_NVRAM) && !nvram)
  198143. + return -EINVAL;
  198144. +
  198145. + fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL);
  198146. + if (!fwctx)
  198147. + return -ENOMEM;
  198148. +
  198149. + fwctx->dev = dev;
  198150. + fwctx->flags = flags;
  198151. + fwctx->done = fw_cb;
  198152. + if (flags & BRCMF_FW_REQUEST_NVRAM)
  198153. + fwctx->nvram_name = nvram;
  198154. +
  198155. + return request_firmware_nowait(THIS_MODULE, true, code, dev,
  198156. + GFP_KERNEL, fwctx,
  198157. + brcmf_fw_request_code_done);
  198158. +}
  198159. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.h
  198160. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.h 1969-12-31 18:00:00.000000000 -0600
  198161. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.h 2014-12-08 00:31:53.840418001 -0600
  198162. @@ -0,0 +1,36 @@
  198163. +/*
  198164. + * Copyright (c) 2013 Broadcom Corporation
  198165. + *
  198166. + * Permission to use, copy, modify, and/or distribute this software for any
  198167. + * purpose with or without fee is hereby granted, provided that the above
  198168. + * copyright notice and this permission notice appear in all copies.
  198169. + *
  198170. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  198171. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  198172. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  198173. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  198174. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  198175. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  198176. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  198177. + */
  198178. +#ifndef BRCMFMAC_FIRMWARE_H
  198179. +#define BRCMFMAC_FIRMWARE_H
  198180. +
  198181. +#define BRCMF_FW_REQUEST 0x000F
  198182. +#define BRCMF_FW_REQUEST_NVRAM 0x0001
  198183. +#define BRCMF_FW_REQ_FLAGS 0x00F0
  198184. +#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010
  198185. +
  198186. +void brcmf_fw_nvram_free(void *nvram);
  198187. +/*
  198188. + * Request firmware(s) asynchronously. When the asynchronous request
  198189. + * fails it will not use the callback, but call device_release_driver()
  198190. + * instead which will call the driver .remove() callback.
  198191. + */
  198192. +int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
  198193. + const char *code, const char *nvram,
  198194. + void (*fw_cb)(struct device *dev,
  198195. + const struct firmware *fw,
  198196. + void *nvram_image, u32 nvram_len));
  198197. +
  198198. +#endif /* BRCMFMAC_FIRMWARE_H */
  198199. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
  198200. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.c 2014-07-28 10:07:25.000000000 -0500
  198201. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.c 2014-12-08 00:31:53.840418001 -0600
  198202. @@ -54,7 +54,7 @@
  198203. if (err >= 0)
  198204. err = 0;
  198205. else
  198206. - brcmf_err("Failed err=%d\n", err);
  198207. + brcmf_dbg(FIL, "Failed err=%d\n", err);
  198208. return err;
  198209. }
  198210. @@ -124,7 +124,8 @@
  198211. }
  198212. static u32
  198213. -brcmf_create_iovar(char *name, char *data, u32 datalen, char *buf, u32 buflen)
  198214. +brcmf_create_iovar(char *name, const char *data, u32 datalen,
  198215. + char *buf, u32 buflen)
  198216. {
  198217. u32 len;
  198218. @@ -144,7 +145,7 @@
  198219. s32
  198220. -brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data,
  198221. +brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, const void *data,
  198222. u32 len)
  198223. {
  198224. struct brcmf_pub *drvr = ifp->drvr;
  198225. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
  198226. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.h 2014-07-28 10:07:25.000000000 -0500
  198227. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.h 2014-12-08 00:31:53.840418001 -0600
  198228. @@ -83,7 +83,7 @@
  198229. s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data);
  198230. s32 brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data);
  198231. -s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data,
  198232. +s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, const void *data,
  198233. u32 len);
  198234. s32 brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data,
  198235. u32 len);
  198236. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
  198237. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h 2014-07-28 10:07:25.000000000 -0500
  198238. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h 2014-12-08 00:31:53.840418001 -0600
  198239. @@ -48,6 +48,19 @@
  198240. #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
  198241. +/* OBSS Coex Auto/On/Off */
  198242. +#define BRCMF_OBSS_COEX_AUTO (-1)
  198243. +#define BRCMF_OBSS_COEX_OFF 0
  198244. +#define BRCMF_OBSS_COEX_ON 1
  198245. +
  198246. +/* join preference types for join_pref iovar */
  198247. +enum brcmf_join_pref_types {
  198248. + BRCMF_JOIN_PREF_RSSI = 1,
  198249. + BRCMF_JOIN_PREF_WPA,
  198250. + BRCMF_JOIN_PREF_BAND,
  198251. + BRCMF_JOIN_PREF_RSSI_DELTA,
  198252. +};
  198253. +
  198254. enum brcmf_fil_p2p_if_types {
  198255. BRCMF_FIL_P2P_IF_CLIENT,
  198256. BRCMF_FIL_P2P_IF_GO,
  198257. @@ -87,6 +100,11 @@
  198258. __le32 enable;
  198259. };
  198260. +struct brcmf_fil_bwcap_le {
  198261. + __le32 band;
  198262. + __le32 bw_cap;
  198263. +};
  198264. +
  198265. /**
  198266. * struct tdls_iovar - common structure for tdls iovars.
  198267. *
  198268. @@ -272,6 +290,22 @@
  198269. __le16 chanspec_list[1];
  198270. };
  198271. +/**
  198272. + * struct join_pref params - parameters for preferred join selection.
  198273. + *
  198274. + * @type: preference type (see enum brcmf_join_pref_types).
  198275. + * @len: length of bytes following (currently always 2).
  198276. + * @rssi_gain: signal gain for selection (only when @type is RSSI_DELTA).
  198277. + * @band: band to which selection preference applies.
  198278. + * This is used if @type is BAND or RSSI_DELTA.
  198279. + */
  198280. +struct brcmf_join_pref_params {
  198281. + u8 type;
  198282. + u8 len;
  198283. + u8 rssi_gain;
  198284. + u8 band;
  198285. +};
  198286. +
  198287. /* used for join with or without a specific bssid and channel list */
  198288. struct brcmf_join_params {
  198289. struct brcmf_ssid_le ssid_le;
  198290. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
  198291. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c 2014-07-28 10:07:25.000000000 -0500
  198292. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c 2014-12-08 00:31:53.840418001 -0600
  198293. @@ -476,6 +476,7 @@
  198294. bool bus_flow_blocked;
  198295. bool creditmap_received;
  198296. u8 mode;
  198297. + bool avoid_queueing;
  198298. };
  198299. /*
  198300. @@ -1369,13 +1370,12 @@
  198301. }
  198302. static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
  198303. - struct sk_buff *skb, u32 genbit,
  198304. - u16 seq)
  198305. + struct sk_buff *skb, u8 ifidx,
  198306. + u32 genbit, u16 seq)
  198307. {
  198308. struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
  198309. u32 hslot;
  198310. int ret;
  198311. - u8 ifidx;
  198312. hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
  198313. @@ -1389,29 +1389,21 @@
  198314. entry->generation = genbit;
  198315. - ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
  198316. - if (ret == 0) {
  198317. - brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
  198318. - brcmf_skbcb(skb)->htod_seq = seq;
  198319. - if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
  198320. - brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
  198321. - brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
  198322. - } else {
  198323. - brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
  198324. - }
  198325. - ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
  198326. - skb);
  198327. + brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
  198328. + brcmf_skbcb(skb)->htod_seq = seq;
  198329. + if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
  198330. + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
  198331. + brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
  198332. + } else {
  198333. + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
  198334. }
  198335. + ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb);
  198336. if (ret != 0) {
  198337. - /* suppress q is full or hdrpull failed, drop this packet */
  198338. - brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
  198339. - true);
  198340. + /* suppress q is full drop this packet */
  198341. + brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, true);
  198342. } else {
  198343. - /*
  198344. - * Mark suppressed to avoid a double free during
  198345. - * wlfc cleanup
  198346. - */
  198347. + /* Mark suppressed to avoid a double free during wlfc cleanup */
  198348. brcmf_fws_hanger_mark_suppressed(&fws->hanger, hslot);
  198349. }
  198350. @@ -1428,6 +1420,7 @@
  198351. struct sk_buff *skb;
  198352. struct brcmf_skbuff_cb *skcb;
  198353. struct brcmf_fws_mac_descriptor *entry = NULL;
  198354. + u8 ifidx;
  198355. brcmf_dbg(DATA, "flags %d\n", flags);
  198356. @@ -1476,12 +1469,15 @@
  198357. }
  198358. brcmf_fws_macdesc_return_req_credit(skb);
  198359. + if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) {
  198360. + brcmu_pkt_buf_free_skb(skb);
  198361. + return -EINVAL;
  198362. + }
  198363. if (!remove_from_hanger)
  198364. - ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit,
  198365. - seq);
  198366. -
  198367. + ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx,
  198368. + genbit, seq);
  198369. if (remove_from_hanger || ret)
  198370. - brcmf_txfinalize(fws->drvr, skb, true);
  198371. + brcmf_txfinalize(fws->drvr, skb, ifidx, true);
  198372. return 0;
  198373. }
  198374. @@ -1868,7 +1864,7 @@
  198375. struct ethhdr *eh = (struct ethhdr *)(skb->data);
  198376. int fifo = BRCMF_FWS_FIFO_BCMC;
  198377. bool multicast = is_multicast_ether_addr(eh->h_dest);
  198378. - bool pae = eh->h_proto == htons(ETH_P_PAE);
  198379. + int rc = 0;
  198380. brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto));
  198381. /* determine the priority */
  198382. @@ -1876,8 +1872,13 @@
  198383. skb->priority = cfg80211_classify8021d(skb, NULL);
  198384. drvr->tx_multicast += !!multicast;
  198385. - if (pae)
  198386. - atomic_inc(&ifp->pend_8021x_cnt);
  198387. +
  198388. + if (fws->avoid_queueing) {
  198389. + rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb);
  198390. + if (rc < 0)
  198391. + brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
  198392. + return rc;
  198393. + }
  198394. /* set control buffer information */
  198395. skcb->if_flags = 0;
  198396. @@ -1899,15 +1900,12 @@
  198397. brcmf_fws_schedule_deq(fws);
  198398. } else {
  198399. brcmf_err("drop skb: no hanger slot\n");
  198400. - if (pae) {
  198401. - atomic_dec(&ifp->pend_8021x_cnt);
  198402. - if (waitqueue_active(&ifp->pend_8021x_wait))
  198403. - wake_up(&ifp->pend_8021x_wait);
  198404. - }
  198405. - brcmu_pkt_buf_free_skb(skb);
  198406. + brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
  198407. + rc = -ENOMEM;
  198408. }
  198409. brcmf_fws_unlock(fws);
  198410. - return 0;
  198411. +
  198412. + return rc;
  198413. }
  198414. void brcmf_fws_reset_interface(struct brcmf_if *ifp)
  198415. @@ -1982,7 +1980,8 @@
  198416. ret = brcmf_proto_txdata(drvr, ifidx, 0, skb);
  198417. brcmf_fws_lock(fws);
  198418. if (ret < 0)
  198419. - brcmf_txfinalize(drvr, skb, false);
  198420. + brcmf_txfinalize(drvr, skb, ifidx,
  198421. + false);
  198422. if (fws->bus_flow_blocked)
  198423. break;
  198424. }
  198425. @@ -2039,6 +2038,13 @@
  198426. fws->drvr = drvr;
  198427. fws->fcmode = fcmode;
  198428. + if ((drvr->bus_if->always_use_fws_queue == false) &&
  198429. + (fcmode == BRCMF_FWS_FCMODE_NONE)) {
  198430. + fws->avoid_queueing = true;
  198431. + brcmf_dbg(INFO, "FWS queueing will be avoided\n");
  198432. + return 0;
  198433. + }
  198434. +
  198435. fws->fws_wq = create_singlethread_workqueue("brcmf_fws_wq");
  198436. if (fws->fws_wq == NULL) {
  198437. brcmf_err("workqueue creation failed\n");
  198438. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/Makefile linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/Makefile
  198439. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/Makefile 2014-07-28 10:07:25.000000000 -0500
  198440. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/Makefile 2014-12-08 00:31:53.836418001 -0600
  198441. @@ -24,6 +24,7 @@
  198442. obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
  198443. brcmfmac-objs += \
  198444. wl_cfg80211.o \
  198445. + chip.o \
  198446. fwil.o \
  198447. fweh.o \
  198448. fwsignal.o \
  198449. @@ -32,12 +33,11 @@
  198450. bcdc.o \
  198451. dhd_common.o \
  198452. dhd_linux.o \
  198453. - nvram.o \
  198454. + firmware.o \
  198455. btcoex.o
  198456. brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
  198457. dhd_sdio.o \
  198458. - bcmsdh.o \
  198459. - sdio_chip.o
  198460. + bcmsdh.o
  198461. brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
  198462. usb.o
  198463. brcmfmac-$(CONFIG_BRCMDBG) += \
  198464. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.c
  198465. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.c 2014-07-28 10:07:25.000000000 -0500
  198466. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.c 1969-12-31 18:00:00.000000000 -0600
  198467. @@ -1,94 +0,0 @@
  198468. -/*
  198469. - * Copyright (c) 2013 Broadcom Corporation
  198470. - *
  198471. - * Permission to use, copy, modify, and/or distribute this software for any
  198472. - * purpose with or without fee is hereby granted, provided that the above
  198473. - * copyright notice and this permission notice appear in all copies.
  198474. - *
  198475. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  198476. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  198477. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  198478. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  198479. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  198480. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  198481. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  198482. - */
  198483. -
  198484. -#include <linux/kernel.h>
  198485. -#include <linux/slab.h>
  198486. -#include <linux/firmware.h>
  198487. -
  198488. -#include "nvram.h"
  198489. -
  198490. -/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a file
  198491. - * and ending in a NUL. Removes carriage returns, empty lines, comment lines,
  198492. - * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
  198493. - * End of buffer is completed with token identifying length of buffer.
  198494. - */
  198495. -void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length)
  198496. -{
  198497. - u8 *nvram;
  198498. - u32 i;
  198499. - u32 len;
  198500. - u32 column;
  198501. - u8 val;
  198502. - bool comment;
  198503. - u32 token;
  198504. - __le32 token_le;
  198505. -
  198506. - /* Alloc for extra 0 byte + roundup by 4 + length field */
  198507. - nvram = kmalloc(nv->size + 1 + 3 + sizeof(token_le), GFP_KERNEL);
  198508. - if (!nvram)
  198509. - return NULL;
  198510. -
  198511. - len = 0;
  198512. - column = 0;
  198513. - comment = false;
  198514. - for (i = 0; i < nv->size; i++) {
  198515. - val = nv->data[i];
  198516. - if (val == 0)
  198517. - break;
  198518. - if (val == '\r')
  198519. - continue;
  198520. - if (comment && (val != '\n'))
  198521. - continue;
  198522. - comment = false;
  198523. - if (val == '#') {
  198524. - comment = true;
  198525. - continue;
  198526. - }
  198527. - if (val == '\n') {
  198528. - if (column == 0)
  198529. - continue;
  198530. - nvram[len] = 0;
  198531. - len++;
  198532. - column = 0;
  198533. - continue;
  198534. - }
  198535. - nvram[len] = val;
  198536. - len++;
  198537. - column++;
  198538. - }
  198539. - column = len;
  198540. - *new_length = roundup(len + 1, 4);
  198541. - while (column != *new_length) {
  198542. - nvram[column] = 0;
  198543. - column++;
  198544. - }
  198545. -
  198546. - token = *new_length / 4;
  198547. - token = (~token << 16) | (token & 0x0000FFFF);
  198548. - token_le = cpu_to_le32(token);
  198549. -
  198550. - memcpy(&nvram[*new_length], &token_le, sizeof(token_le));
  198551. - *new_length += sizeof(token_le);
  198552. -
  198553. - return nvram;
  198554. -}
  198555. -
  198556. -void brcmf_nvram_free(void *nvram)
  198557. -{
  198558. - kfree(nvram);
  198559. -}
  198560. -
  198561. -
  198562. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.h
  198563. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.h 2014-07-28 10:07:25.000000000 -0500
  198564. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.h 1969-12-31 18:00:00.000000000 -0600
  198565. @@ -1,24 +0,0 @@
  198566. -/*
  198567. - * Copyright (c) 2013 Broadcom Corporation
  198568. - *
  198569. - * Permission to use, copy, modify, and/or distribute this software for any
  198570. - * purpose with or without fee is hereby granted, provided that the above
  198571. - * copyright notice and this permission notice appear in all copies.
  198572. - *
  198573. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  198574. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  198575. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  198576. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  198577. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  198578. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  198579. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  198580. - */
  198581. -#ifndef BRCMFMAC_NVRAM_H
  198582. -#define BRCMFMAC_NVRAM_H
  198583. -
  198584. -
  198585. -void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length);
  198586. -void brcmf_nvram_free(void *nvram);
  198587. -
  198588. -
  198589. -#endif /* BRCMFMAC_NVRAM_H */
  198590. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/p2p.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
  198591. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/p2p.c 2014-07-28 10:07:25.000000000 -0500
  198592. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/p2p.c 2014-12-08 00:31:53.840418001 -0600
  198593. @@ -797,7 +797,8 @@
  198594. /* SOCIAL CHANNELS 1, 6, 11 */
  198595. search_state = WL_P2P_DISC_ST_SEARCH;
  198596. brcmf_dbg(INFO, "P2P SEARCH PHASE START\n");
  198597. - } else if (dev != NULL && vif->mode == WL_MODE_AP) {
  198598. + } else if (dev != NULL &&
  198599. + vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
  198600. /* If you are already a GO, then do SEARCH only */
  198601. brcmf_dbg(INFO, "Already a GO. Do SEARCH Only\n");
  198602. search_state = WL_P2P_DISC_ST_SEARCH;
  198603. @@ -2256,7 +2257,6 @@
  198604. struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
  198605. struct brcmf_cfg80211_vif *vif;
  198606. enum brcmf_fil_p2p_if_types iftype;
  198607. - enum wl_mode mode;
  198608. int err;
  198609. if (brcmf_cfg80211_vif_event_armed(cfg))
  198610. @@ -2267,11 +2267,9 @@
  198611. switch (type) {
  198612. case NL80211_IFTYPE_P2P_CLIENT:
  198613. iftype = BRCMF_FIL_P2P_IF_CLIENT;
  198614. - mode = WL_MODE_BSS;
  198615. break;
  198616. case NL80211_IFTYPE_P2P_GO:
  198617. iftype = BRCMF_FIL_P2P_IF_GO;
  198618. - mode = WL_MODE_AP;
  198619. break;
  198620. case NL80211_IFTYPE_P2P_DEVICE:
  198621. return brcmf_p2p_create_p2pdev(&cfg->p2p, wiphy,
  198622. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
  198623. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c 2014-07-28 10:07:25.000000000 -0500
  198624. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c 1969-12-31 18:00:00.000000000 -0600
  198625. @@ -1,973 +0,0 @@
  198626. -/*
  198627. - * Copyright (c) 2011 Broadcom Corporation
  198628. - *
  198629. - * Permission to use, copy, modify, and/or distribute this software for any
  198630. - * purpose with or without fee is hereby granted, provided that the above
  198631. - * copyright notice and this permission notice appear in all copies.
  198632. - *
  198633. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  198634. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  198635. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  198636. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  198637. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  198638. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  198639. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  198640. - */
  198641. -/* ***** SDIO interface chip backplane handle functions ***** */
  198642. -
  198643. -#include <linux/types.h>
  198644. -#include <linux/netdevice.h>
  198645. -#include <linux/mmc/card.h>
  198646. -#include <linux/mmc/sdio_func.h>
  198647. -#include <linux/mmc/sdio_ids.h>
  198648. -#include <linux/ssb/ssb_regs.h>
  198649. -#include <linux/bcma/bcma.h>
  198650. -
  198651. -#include <chipcommon.h>
  198652. -#include <brcm_hw_ids.h>
  198653. -#include <brcmu_wifi.h>
  198654. -#include <brcmu_utils.h>
  198655. -#include <soc.h>
  198656. -#include "dhd_dbg.h"
  198657. -#include "sdio_host.h"
  198658. -#include "sdio_chip.h"
  198659. -
  198660. -/* chip core base & ramsize */
  198661. -/* bcm4329 */
  198662. -/* SDIO device core, ID 0x829 */
  198663. -#define BCM4329_CORE_BUS_BASE 0x18011000
  198664. -/* internal memory core, ID 0x80e */
  198665. -#define BCM4329_CORE_SOCRAM_BASE 0x18003000
  198666. -/* ARM Cortex M3 core, ID 0x82a */
  198667. -#define BCM4329_CORE_ARM_BASE 0x18002000
  198668. -#define BCM4329_RAMSIZE 0x48000
  198669. -
  198670. -/* bcm43143 */
  198671. -/* SDIO device core */
  198672. -#define BCM43143_CORE_BUS_BASE 0x18002000
  198673. -/* internal memory core */
  198674. -#define BCM43143_CORE_SOCRAM_BASE 0x18004000
  198675. -/* ARM Cortex M3 core, ID 0x82a */
  198676. -#define BCM43143_CORE_ARM_BASE 0x18003000
  198677. -#define BCM43143_RAMSIZE 0x70000
  198678. -
  198679. -/* All D11 cores, ID 0x812 */
  198680. -#define BCM43xx_CORE_D11_BASE 0x18001000
  198681. -
  198682. -#define SBCOREREV(sbidh) \
  198683. - ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
  198684. - ((sbidh) & SSB_IDHIGH_RCLO))
  198685. -
  198686. -/* SOC Interconnect types (aka chip types) */
  198687. -#define SOCI_SB 0
  198688. -#define SOCI_AI 1
  198689. -
  198690. -/* EROM CompIdentB */
  198691. -#define CIB_REV_MASK 0xff000000
  198692. -#define CIB_REV_SHIFT 24
  198693. -
  198694. -/* ARM CR4 core specific control flag bits */
  198695. -#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
  198696. -
  198697. -/* D11 core specific control flag bits */
  198698. -#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
  198699. -#define D11_BCMA_IOCTL_PHYRESET 0x0008
  198700. -
  198701. -#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
  198702. -/* SDIO Pad drive strength to select value mappings */
  198703. -struct sdiod_drive_str {
  198704. - u8 strength; /* Pad Drive Strength in mA */
  198705. - u8 sel; /* Chip-specific select value */
  198706. -};
  198707. -/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
  198708. -static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
  198709. - {32, 0x6},
  198710. - {26, 0x7},
  198711. - {22, 0x4},
  198712. - {16, 0x5},
  198713. - {12, 0x2},
  198714. - {8, 0x3},
  198715. - {4, 0x0},
  198716. - {0, 0x1}
  198717. -};
  198718. -
  198719. -/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
  198720. -static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = {
  198721. - {6, 0x7},
  198722. - {5, 0x6},
  198723. - {4, 0x5},
  198724. - {3, 0x4},
  198725. - {2, 0x2},
  198726. - {1, 0x1},
  198727. - {0, 0x0}
  198728. -};
  198729. -
  198730. -/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
  198731. -static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = {
  198732. - {3, 0x3},
  198733. - {2, 0x2},
  198734. - {1, 0x1},
  198735. - {0, 0x0} };
  198736. -
  198737. -/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
  198738. -static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
  198739. - {16, 0x7},
  198740. - {12, 0x5},
  198741. - {8, 0x3},
  198742. - {4, 0x1}
  198743. -};
  198744. -
  198745. -u8
  198746. -brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid)
  198747. -{
  198748. - u8 idx;
  198749. -
  198750. - for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
  198751. - if (coreid == ci->c_inf[idx].id)
  198752. - return idx;
  198753. -
  198754. - return BRCMF_MAX_CORENUM;
  198755. -}
  198756. -
  198757. -static u32
  198758. -brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
  198759. - struct brcmf_chip *ci, u16 coreid)
  198760. -{
  198761. - u32 regdata;
  198762. - u8 idx;
  198763. -
  198764. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198765. -
  198766. - regdata = brcmf_sdiod_regrl(sdiodev,
  198767. - CORE_SB(ci->c_inf[idx].base, sbidhigh),
  198768. - NULL);
  198769. - return SBCOREREV(regdata);
  198770. -}
  198771. -
  198772. -static u32
  198773. -brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
  198774. - struct brcmf_chip *ci, u16 coreid)
  198775. -{
  198776. - u8 idx;
  198777. -
  198778. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198779. -
  198780. - return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
  198781. -}
  198782. -
  198783. -static bool
  198784. -brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
  198785. - struct brcmf_chip *ci, u16 coreid)
  198786. -{
  198787. - u32 regdata;
  198788. - u8 idx;
  198789. -
  198790. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198791. - if (idx == BRCMF_MAX_CORENUM)
  198792. - return false;
  198793. -
  198794. - regdata = brcmf_sdiod_regrl(sdiodev,
  198795. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  198796. - NULL);
  198797. - regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
  198798. - SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
  198799. - return (SSB_TMSLOW_CLOCK == regdata);
  198800. -}
  198801. -
  198802. -static bool
  198803. -brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
  198804. - struct brcmf_chip *ci, u16 coreid)
  198805. -{
  198806. - u32 regdata;
  198807. - u8 idx;
  198808. - bool ret;
  198809. -
  198810. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198811. - if (idx == BRCMF_MAX_CORENUM)
  198812. - return false;
  198813. -
  198814. - regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
  198815. - NULL);
  198816. - ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
  198817. -
  198818. - regdata = brcmf_sdiod_regrl(sdiodev,
  198819. - ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
  198820. - NULL);
  198821. - ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
  198822. -
  198823. - return ret;
  198824. -}
  198825. -
  198826. -static void
  198827. -brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
  198828. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  198829. - u32 in_resetbits)
  198830. -{
  198831. - u32 regdata, base;
  198832. - u8 idx;
  198833. -
  198834. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198835. - base = ci->c_inf[idx].base;
  198836. -
  198837. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
  198838. - if (regdata & SSB_TMSLOW_RESET)
  198839. - return;
  198840. -
  198841. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
  198842. - if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
  198843. - /*
  198844. - * set target reject and spin until busy is clear
  198845. - * (preserve core-specific bits)
  198846. - */
  198847. - regdata = brcmf_sdiod_regrl(sdiodev,
  198848. - CORE_SB(base, sbtmstatelow), NULL);
  198849. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
  198850. - regdata | SSB_TMSLOW_REJECT, NULL);
  198851. -
  198852. - regdata = brcmf_sdiod_regrl(sdiodev,
  198853. - CORE_SB(base, sbtmstatelow), NULL);
  198854. - udelay(1);
  198855. - SPINWAIT((brcmf_sdiod_regrl(sdiodev,
  198856. - CORE_SB(base, sbtmstatehigh),
  198857. - NULL) &
  198858. - SSB_TMSHIGH_BUSY), 100000);
  198859. -
  198860. - regdata = brcmf_sdiod_regrl(sdiodev,
  198861. - CORE_SB(base, sbtmstatehigh),
  198862. - NULL);
  198863. - if (regdata & SSB_TMSHIGH_BUSY)
  198864. - brcmf_err("core state still busy\n");
  198865. -
  198866. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
  198867. - NULL);
  198868. - if (regdata & SSB_IDLOW_INITIATOR) {
  198869. - regdata = brcmf_sdiod_regrl(sdiodev,
  198870. - CORE_SB(base, sbimstate),
  198871. - NULL);
  198872. - regdata |= SSB_IMSTATE_REJECT;
  198873. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
  198874. - regdata, NULL);
  198875. - regdata = brcmf_sdiod_regrl(sdiodev,
  198876. - CORE_SB(base, sbimstate),
  198877. - NULL);
  198878. - udelay(1);
  198879. - SPINWAIT((brcmf_sdiod_regrl(sdiodev,
  198880. - CORE_SB(base, sbimstate),
  198881. - NULL) &
  198882. - SSB_IMSTATE_BUSY), 100000);
  198883. - }
  198884. -
  198885. - /* set reset and reject while enabling the clocks */
  198886. - regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
  198887. - SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
  198888. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
  198889. - regdata, NULL);
  198890. - regdata = brcmf_sdiod_regrl(sdiodev,
  198891. - CORE_SB(base, sbtmstatelow), NULL);
  198892. - udelay(10);
  198893. -
  198894. - /* clear the initiator reject bit */
  198895. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
  198896. - NULL);
  198897. - if (regdata & SSB_IDLOW_INITIATOR) {
  198898. - regdata = brcmf_sdiod_regrl(sdiodev,
  198899. - CORE_SB(base, sbimstate),
  198900. - NULL);
  198901. - regdata &= ~SSB_IMSTATE_REJECT;
  198902. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
  198903. - regdata, NULL);
  198904. - }
  198905. - }
  198906. -
  198907. - /* leave reset and reject asserted */
  198908. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
  198909. - (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
  198910. - udelay(1);
  198911. -}
  198912. -
  198913. -static void
  198914. -brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
  198915. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  198916. - u32 in_resetbits)
  198917. -{
  198918. - u8 idx;
  198919. - u32 regdata;
  198920. - u32 wrapbase;
  198921. -
  198922. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198923. - if (idx == BRCMF_MAX_CORENUM)
  198924. - return;
  198925. -
  198926. - wrapbase = ci->c_inf[idx].wrapbase;
  198927. -
  198928. - /* if core is already in reset, skip reset */
  198929. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL);
  198930. - if ((regdata & BCMA_RESET_CTL_RESET) != 0)
  198931. - goto post_reset_config;
  198932. -
  198933. - /* configure reset */
  198934. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
  198935. - BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
  198936. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  198937. -
  198938. - /* put in reset */
  198939. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL,
  198940. - BCMA_RESET_CTL_RESET, NULL);
  198941. - usleep_range(10, 20);
  198942. -
  198943. - /* wait till reset is 1 */
  198944. - SPINWAIT(brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) !=
  198945. - BCMA_RESET_CTL_RESET, 300);
  198946. -
  198947. -post_reset_config:
  198948. - /* post reset configure */
  198949. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
  198950. - BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
  198951. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  198952. -}
  198953. -
  198954. -static void
  198955. -brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
  198956. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  198957. - u32 in_resetbits, u32 post_resetbits)
  198958. -{
  198959. - u32 regdata;
  198960. - u8 idx;
  198961. -
  198962. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  198963. - if (idx == BRCMF_MAX_CORENUM)
  198964. - return;
  198965. -
  198966. - /*
  198967. - * Must do the disable sequence first to work for
  198968. - * arbitrary current core state.
  198969. - */
  198970. - brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, pre_resetbits,
  198971. - in_resetbits);
  198972. -
  198973. - /*
  198974. - * Now do the initialization sequence.
  198975. - * set reset while enabling the clock and
  198976. - * forcing them on throughout the core
  198977. - */
  198978. - brcmf_sdiod_regwl(sdiodev,
  198979. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  198980. - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
  198981. - NULL);
  198982. - regdata = brcmf_sdiod_regrl(sdiodev,
  198983. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  198984. - NULL);
  198985. - udelay(1);
  198986. -
  198987. - /* clear any serror */
  198988. - regdata = brcmf_sdiod_regrl(sdiodev,
  198989. - CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
  198990. - NULL);
  198991. - if (regdata & SSB_TMSHIGH_SERR)
  198992. - brcmf_sdiod_regwl(sdiodev,
  198993. - CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
  198994. - 0, NULL);
  198995. -
  198996. - regdata = brcmf_sdiod_regrl(sdiodev,
  198997. - CORE_SB(ci->c_inf[idx].base, sbimstate),
  198998. - NULL);
  198999. - if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
  199000. - brcmf_sdiod_regwl(sdiodev,
  199001. - CORE_SB(ci->c_inf[idx].base, sbimstate),
  199002. - regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
  199003. - NULL);
  199004. -
  199005. - /* clear reset and allow it to propagate throughout the core */
  199006. - brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  199007. - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
  199008. - regdata = brcmf_sdiod_regrl(sdiodev,
  199009. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  199010. - NULL);
  199011. - udelay(1);
  199012. -
  199013. - /* leave clock enabled */
  199014. - brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  199015. - SSB_TMSLOW_CLOCK, NULL);
  199016. - regdata = brcmf_sdiod_regrl(sdiodev,
  199017. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  199018. - NULL);
  199019. - udelay(1);
  199020. -}
  199021. -
  199022. -static void
  199023. -brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
  199024. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  199025. - u32 in_resetbits, u32 post_resetbits)
  199026. -{
  199027. - u8 idx;
  199028. - u32 regdata;
  199029. - u32 wrapbase;
  199030. -
  199031. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  199032. - if (idx == BRCMF_MAX_CORENUM)
  199033. - return;
  199034. -
  199035. - wrapbase = ci->c_inf[idx].wrapbase;
  199036. -
  199037. - /* must disable first to work for arbitrary current core state */
  199038. - brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, pre_resetbits,
  199039. - in_resetbits);
  199040. -
  199041. - while (brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) &
  199042. - BCMA_RESET_CTL_RESET) {
  199043. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL, 0, NULL);
  199044. - usleep_range(40, 60);
  199045. - }
  199046. -
  199047. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, post_resetbits |
  199048. - BCMA_IOCTL_CLK, NULL);
  199049. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  199050. -}
  199051. -
  199052. -#ifdef DEBUG
  199053. -/* safety check for chipinfo */
  199054. -static int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
  199055. -{
  199056. - u8 core_idx;
  199057. -
  199058. - /* check RAM core presence for ARM CM3 core */
  199059. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
  199060. - if (BRCMF_MAX_CORENUM != core_idx) {
  199061. - core_idx = brcmf_sdio_chip_getinfidx(ci,
  199062. - BCMA_CORE_INTERNAL_MEM);
  199063. - if (BRCMF_MAX_CORENUM == core_idx) {
  199064. - brcmf_err("RAM core not provided with ARM CM3 core\n");
  199065. - return -ENODEV;
  199066. - }
  199067. - }
  199068. -
  199069. - /* check RAM base for ARM CR4 core */
  199070. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
  199071. - if (BRCMF_MAX_CORENUM != core_idx) {
  199072. - if (ci->rambase == 0) {
  199073. - brcmf_err("RAM base not provided with ARM CR4 core\n");
  199074. - return -ENOMEM;
  199075. - }
  199076. - }
  199077. -
  199078. - return 0;
  199079. -}
  199080. -#else /* DEBUG */
  199081. -static inline int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
  199082. -{
  199083. - return 0;
  199084. -}
  199085. -#endif
  199086. -
  199087. -static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
  199088. - struct brcmf_chip *ci)
  199089. -{
  199090. - u32 regdata;
  199091. - u32 socitype;
  199092. -
  199093. - /* Get CC core rev
  199094. - * Chipid is assume to be at offset 0 from SI_ENUM_BASE
  199095. - * For different chiptypes or old sdio hosts w/o chipcommon,
  199096. - * other ways of recognition should be added here.
  199097. - */
  199098. - regdata = brcmf_sdiod_regrl(sdiodev,
  199099. - CORE_CC_REG(SI_ENUM_BASE, chipid),
  199100. - NULL);
  199101. - ci->chip = regdata & CID_ID_MASK;
  199102. - ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
  199103. - if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
  199104. - ci->chiprev >= 2)
  199105. - ci->chip = BCM4339_CHIP_ID;
  199106. - socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
  199107. -
  199108. - brcmf_dbg(INFO, "found %s chip: id=0x%x, rev=%d\n",
  199109. - socitype == SOCI_SB ? "SB" : "AXI", ci->chip, ci->chiprev);
  199110. -
  199111. - if (socitype == SOCI_SB) {
  199112. - if (ci->chip != BCM4329_CHIP_ID) {
  199113. - brcmf_err("SB chip is not supported\n");
  199114. - return -ENODEV;
  199115. - }
  199116. - ci->iscoreup = brcmf_sdio_sb_iscoreup;
  199117. - ci->corerev = brcmf_sdio_sb_corerev;
  199118. - ci->coredisable = brcmf_sdio_sb_coredisable;
  199119. - ci->resetcore = brcmf_sdio_sb_resetcore;
  199120. -
  199121. - ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
  199122. - ci->c_inf[0].base = SI_ENUM_BASE;
  199123. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199124. - ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
  199125. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199126. - ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
  199127. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199128. - ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
  199129. - ci->c_inf[4].id = BCMA_CORE_80211;
  199130. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199131. - ci->ramsize = BCM4329_RAMSIZE;
  199132. - } else if (socitype == SOCI_AI) {
  199133. - ci->iscoreup = brcmf_sdio_ai_iscoreup;
  199134. - ci->corerev = brcmf_sdio_ai_corerev;
  199135. - ci->coredisable = brcmf_sdio_ai_coredisable;
  199136. - ci->resetcore = brcmf_sdio_ai_resetcore;
  199137. -
  199138. - ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
  199139. - ci->c_inf[0].base = SI_ENUM_BASE;
  199140. -
  199141. - /* Address of cores for new chips should be added here */
  199142. - switch (ci->chip) {
  199143. - case BCM43143_CHIP_ID:
  199144. - ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000;
  199145. - ci->c_inf[0].cib = 0x2b000000;
  199146. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199147. - ci->c_inf[1].base = BCM43143_CORE_BUS_BASE;
  199148. - ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000;
  199149. - ci->c_inf[1].cib = 0x18000000;
  199150. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199151. - ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE;
  199152. - ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000;
  199153. - ci->c_inf[2].cib = 0x14000000;
  199154. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199155. - ci->c_inf[3].base = BCM43143_CORE_ARM_BASE;
  199156. - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
  199157. - ci->c_inf[3].cib = 0x07000000;
  199158. - ci->c_inf[4].id = BCMA_CORE_80211;
  199159. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199160. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  199161. - ci->ramsize = BCM43143_RAMSIZE;
  199162. - break;
  199163. - case BCM43241_CHIP_ID:
  199164. - ci->c_inf[0].wrapbase = 0x18100000;
  199165. - ci->c_inf[0].cib = 0x2a084411;
  199166. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199167. - ci->c_inf[1].base = 0x18002000;
  199168. - ci->c_inf[1].wrapbase = 0x18102000;
  199169. - ci->c_inf[1].cib = 0x0e004211;
  199170. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199171. - ci->c_inf[2].base = 0x18004000;
  199172. - ci->c_inf[2].wrapbase = 0x18104000;
  199173. - ci->c_inf[2].cib = 0x14080401;
  199174. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199175. - ci->c_inf[3].base = 0x18003000;
  199176. - ci->c_inf[3].wrapbase = 0x18103000;
  199177. - ci->c_inf[3].cib = 0x07004211;
  199178. - ci->c_inf[4].id = BCMA_CORE_80211;
  199179. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199180. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  199181. - ci->ramsize = 0x90000;
  199182. - break;
  199183. - case BCM4330_CHIP_ID:
  199184. - ci->c_inf[0].wrapbase = 0x18100000;
  199185. - ci->c_inf[0].cib = 0x27004211;
  199186. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199187. - ci->c_inf[1].base = 0x18002000;
  199188. - ci->c_inf[1].wrapbase = 0x18102000;
  199189. - ci->c_inf[1].cib = 0x07004211;
  199190. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199191. - ci->c_inf[2].base = 0x18004000;
  199192. - ci->c_inf[2].wrapbase = 0x18104000;
  199193. - ci->c_inf[2].cib = 0x0d080401;
  199194. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199195. - ci->c_inf[3].base = 0x18003000;
  199196. - ci->c_inf[3].wrapbase = 0x18103000;
  199197. - ci->c_inf[3].cib = 0x03004211;
  199198. - ci->c_inf[4].id = BCMA_CORE_80211;
  199199. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199200. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  199201. - ci->ramsize = 0x48000;
  199202. - break;
  199203. - case BCM4334_CHIP_ID:
  199204. - ci->c_inf[0].wrapbase = 0x18100000;
  199205. - ci->c_inf[0].cib = 0x29004211;
  199206. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199207. - ci->c_inf[1].base = 0x18002000;
  199208. - ci->c_inf[1].wrapbase = 0x18102000;
  199209. - ci->c_inf[1].cib = 0x0d004211;
  199210. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199211. - ci->c_inf[2].base = 0x18004000;
  199212. - ci->c_inf[2].wrapbase = 0x18104000;
  199213. - ci->c_inf[2].cib = 0x13080401;
  199214. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199215. - ci->c_inf[3].base = 0x18003000;
  199216. - ci->c_inf[3].wrapbase = 0x18103000;
  199217. - ci->c_inf[3].cib = 0x07004211;
  199218. - ci->c_inf[4].id = BCMA_CORE_80211;
  199219. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199220. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  199221. - ci->ramsize = 0x80000;
  199222. - break;
  199223. - case BCM4335_CHIP_ID:
  199224. - ci->c_inf[0].wrapbase = 0x18100000;
  199225. - ci->c_inf[0].cib = 0x2b084411;
  199226. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199227. - ci->c_inf[1].base = 0x18005000;
  199228. - ci->c_inf[1].wrapbase = 0x18105000;
  199229. - ci->c_inf[1].cib = 0x0f004211;
  199230. - ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
  199231. - ci->c_inf[2].base = 0x18002000;
  199232. - ci->c_inf[2].wrapbase = 0x18102000;
  199233. - ci->c_inf[2].cib = 0x01084411;
  199234. - ci->c_inf[3].id = BCMA_CORE_80211;
  199235. - ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
  199236. - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
  199237. - ci->ramsize = 0xc0000;
  199238. - ci->rambase = 0x180000;
  199239. - break;
  199240. - case BCM43362_CHIP_ID:
  199241. - ci->c_inf[0].wrapbase = 0x18100000;
  199242. - ci->c_inf[0].cib = 0x27004211;
  199243. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199244. - ci->c_inf[1].base = 0x18002000;
  199245. - ci->c_inf[1].wrapbase = 0x18102000;
  199246. - ci->c_inf[1].cib = 0x0a004211;
  199247. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  199248. - ci->c_inf[2].base = 0x18004000;
  199249. - ci->c_inf[2].wrapbase = 0x18104000;
  199250. - ci->c_inf[2].cib = 0x08080401;
  199251. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  199252. - ci->c_inf[3].base = 0x18003000;
  199253. - ci->c_inf[3].wrapbase = 0x18103000;
  199254. - ci->c_inf[3].cib = 0x03004211;
  199255. - ci->c_inf[4].id = BCMA_CORE_80211;
  199256. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  199257. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  199258. - ci->ramsize = 0x3C000;
  199259. - break;
  199260. - case BCM4339_CHIP_ID:
  199261. - ci->c_inf[0].wrapbase = 0x18100000;
  199262. - ci->c_inf[0].cib = 0x2e084411;
  199263. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  199264. - ci->c_inf[1].base = 0x18005000;
  199265. - ci->c_inf[1].wrapbase = 0x18105000;
  199266. - ci->c_inf[1].cib = 0x15004211;
  199267. - ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
  199268. - ci->c_inf[2].base = 0x18002000;
  199269. - ci->c_inf[2].wrapbase = 0x18102000;
  199270. - ci->c_inf[2].cib = 0x04084411;
  199271. - ci->c_inf[3].id = BCMA_CORE_80211;
  199272. - ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
  199273. - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
  199274. - ci->ramsize = 0xc0000;
  199275. - ci->rambase = 0x180000;
  199276. - break;
  199277. - default:
  199278. - brcmf_err("AXI chip is not supported\n");
  199279. - return -ENODEV;
  199280. - }
  199281. - } else {
  199282. - brcmf_err("chip backplane type %u is not supported\n",
  199283. - socitype);
  199284. - return -ENODEV;
  199285. - }
  199286. -
  199287. - return brcmf_sdio_chip_cichk(ci);
  199288. -}
  199289. -
  199290. -static int
  199291. -brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
  199292. -{
  199293. - int err = 0;
  199294. - u8 clkval, clkset;
  199295. -
  199296. - /* Try forcing SDIO core to do ALPAvail request only */
  199297. - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
  199298. - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  199299. - if (err) {
  199300. - brcmf_err("error writing for HT off\n");
  199301. - return err;
  199302. - }
  199303. -
  199304. - /* If register supported, wait for ALPAvail and then force ALP */
  199305. - /* This may take up to 15 milliseconds */
  199306. - clkval = brcmf_sdiod_regrb(sdiodev,
  199307. - SBSDIO_FUNC1_CHIPCLKCSR, NULL);
  199308. -
  199309. - if ((clkval & ~SBSDIO_AVBITS) != clkset) {
  199310. - brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
  199311. - clkset, clkval);
  199312. - return -EACCES;
  199313. - }
  199314. -
  199315. - SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
  199316. - SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
  199317. - !SBSDIO_ALPAV(clkval)),
  199318. - PMU_MAX_TRANSITION_DLY);
  199319. - if (!SBSDIO_ALPAV(clkval)) {
  199320. - brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
  199321. - clkval);
  199322. - return -EBUSY;
  199323. - }
  199324. -
  199325. - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
  199326. - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  199327. - udelay(65);
  199328. -
  199329. - /* Also, disable the extra SDIO pull-ups */
  199330. - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
  199331. -
  199332. - return 0;
  199333. -}
  199334. -
  199335. -static void
  199336. -brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
  199337. - struct brcmf_chip *ci)
  199338. -{
  199339. - u32 base = ci->c_inf[0].base;
  199340. -
  199341. - /* get chipcommon rev */
  199342. - ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
  199343. -
  199344. - /* get chipcommon capabilites */
  199345. - ci->c_inf[0].caps = brcmf_sdiod_regrl(sdiodev,
  199346. - CORE_CC_REG(base, capabilities),
  199347. - NULL);
  199348. -
  199349. - /* get pmu caps & rev */
  199350. - if (ci->c_inf[0].caps & CC_CAP_PMU) {
  199351. - ci->pmucaps =
  199352. - brcmf_sdiod_regrl(sdiodev,
  199353. - CORE_CC_REG(base, pmucapabilities),
  199354. - NULL);
  199355. - ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
  199356. - }
  199357. -
  199358. - ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id);
  199359. -
  199360. - brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
  199361. - ci->c_inf[0].rev, ci->pmurev,
  199362. - ci->c_inf[1].rev, ci->c_inf[1].id);
  199363. -
  199364. - /*
  199365. - * Make sure any on-chip ARM is off (in case strapping is wrong),
  199366. - * or downloaded code was already running.
  199367. - */
  199368. - ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
  199369. -}
  199370. -
  199371. -int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
  199372. - struct brcmf_chip **ci_ptr)
  199373. -{
  199374. - int ret;
  199375. - struct brcmf_chip *ci;
  199376. -
  199377. - brcmf_dbg(TRACE, "Enter\n");
  199378. -
  199379. - ci = kzalloc(sizeof(*ci), GFP_ATOMIC);
  199380. - if (!ci)
  199381. - return -ENOMEM;
  199382. -
  199383. - ret = brcmf_sdio_chip_buscoreprep(sdiodev);
  199384. - if (ret != 0)
  199385. - goto err;
  199386. -
  199387. - ret = brcmf_sdio_chip_recognition(sdiodev, ci);
  199388. - if (ret != 0)
  199389. - goto err;
  199390. -
  199391. - brcmf_sdio_chip_buscoresetup(sdiodev, ci);
  199392. -
  199393. - brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
  199394. - 0, NULL);
  199395. - brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
  199396. - 0, NULL);
  199397. -
  199398. - *ci_ptr = ci;
  199399. - return 0;
  199400. -
  199401. -err:
  199402. - kfree(ci);
  199403. - return ret;
  199404. -}
  199405. -
  199406. -void
  199407. -brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr)
  199408. -{
  199409. - brcmf_dbg(TRACE, "Enter\n");
  199410. -
  199411. - kfree(*ci_ptr);
  199412. - *ci_ptr = NULL;
  199413. -}
  199414. -
  199415. -static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
  199416. -{
  199417. - const char *fmt;
  199418. -
  199419. - fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
  199420. - snprintf(buf, len, fmt, chipid);
  199421. - return buf;
  199422. -}
  199423. -
  199424. -void
  199425. -brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
  199426. - struct brcmf_chip *ci, u32 drivestrength)
  199427. -{
  199428. - const struct sdiod_drive_str *str_tab = NULL;
  199429. - u32 str_mask;
  199430. - u32 str_shift;
  199431. - char chn[8];
  199432. - u32 base = ci->c_inf[0].base;
  199433. - u32 i;
  199434. - u32 drivestrength_sel = 0;
  199435. - u32 cc_data_temp;
  199436. - u32 addr;
  199437. -
  199438. - if (!(ci->c_inf[0].caps & CC_CAP_PMU))
  199439. - return;
  199440. -
  199441. - switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
  199442. - case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
  199443. - str_tab = sdiod_drvstr_tab1_1v8;
  199444. - str_mask = 0x00003800;
  199445. - str_shift = 11;
  199446. - break;
  199447. - case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
  199448. - str_tab = sdiod_drvstr_tab6_1v8;
  199449. - str_mask = 0x00001800;
  199450. - str_shift = 11;
  199451. - break;
  199452. - case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
  199453. - /* note: 43143 does not support tristate */
  199454. - i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
  199455. - if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
  199456. - str_tab = sdiod_drvstr_tab2_3v3;
  199457. - str_mask = 0x00000007;
  199458. - str_shift = 0;
  199459. - } else
  199460. - brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
  199461. - brcmf_sdio_chip_name(ci->chip, chn, 8),
  199462. - drivestrength);
  199463. - break;
  199464. - case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
  199465. - str_tab = sdiod_drive_strength_tab5_1v8;
  199466. - str_mask = 0x00003800;
  199467. - str_shift = 11;
  199468. - break;
  199469. - default:
  199470. - brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
  199471. - brcmf_sdio_chip_name(ci->chip, chn, 8),
  199472. - ci->chiprev, ci->pmurev);
  199473. - break;
  199474. - }
  199475. -
  199476. - if (str_tab != NULL) {
  199477. - for (i = 0; str_tab[i].strength != 0; i++) {
  199478. - if (drivestrength >= str_tab[i].strength) {
  199479. - drivestrength_sel = str_tab[i].sel;
  199480. - break;
  199481. - }
  199482. - }
  199483. - addr = CORE_CC_REG(base, chipcontrol_addr);
  199484. - brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
  199485. - cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
  199486. - cc_data_temp &= ~str_mask;
  199487. - drivestrength_sel <<= str_shift;
  199488. - cc_data_temp |= drivestrength_sel;
  199489. - brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
  199490. -
  199491. - brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
  199492. - str_tab[i].strength, drivestrength, cc_data_temp);
  199493. - }
  199494. -}
  199495. -
  199496. -static void
  199497. -brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev,
  199498. - struct brcmf_chip *ci)
  199499. -{
  199500. - ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
  199501. - ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
  199502. - D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
  199503. - D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
  199504. - ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0, 0, 0);
  199505. -}
  199506. -
  199507. -static bool brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev,
  199508. - struct brcmf_chip *ci)
  199509. -{
  199510. - u8 core_idx;
  199511. - u32 reg_addr;
  199512. -
  199513. - if (!ci->iscoreup(sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) {
  199514. - brcmf_err("SOCRAM core is down after reset?\n");
  199515. - return false;
  199516. - }
  199517. -
  199518. - /* clear all interrupts */
  199519. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
  199520. - reg_addr = ci->c_inf[core_idx].base;
  199521. - reg_addr += offsetof(struct sdpcmd_regs, intstatus);
  199522. - brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
  199523. -
  199524. - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0, 0);
  199525. -
  199526. - return true;
  199527. -}
  199528. -
  199529. -static inline void
  199530. -brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev,
  199531. - struct brcmf_chip *ci)
  199532. -{
  199533. - u8 idx;
  199534. - u32 regdata;
  199535. - u32 wrapbase;
  199536. - idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
  199537. -
  199538. - if (idx == BRCMF_MAX_CORENUM)
  199539. - return;
  199540. -
  199541. - wrapbase = ci->c_inf[idx].wrapbase;
  199542. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  199543. - regdata &= ARMCR4_BCMA_IOCTL_CPUHALT;
  199544. - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, regdata,
  199545. - ARMCR4_BCMA_IOCTL_CPUHALT, ARMCR4_BCMA_IOCTL_CPUHALT);
  199546. - ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
  199547. - D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
  199548. - D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
  199549. -}
  199550. -
  199551. -static bool brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev,
  199552. - struct brcmf_chip *ci, u32 rstvec)
  199553. -{
  199554. - u8 core_idx;
  199555. - u32 reg_addr;
  199556. -
  199557. - /* clear all interrupts */
  199558. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
  199559. - reg_addr = ci->c_inf[core_idx].base;
  199560. - reg_addr += offsetof(struct sdpcmd_regs, intstatus);
  199561. - brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
  199562. -
  199563. - /* Write reset vector to address 0 */
  199564. - brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&rstvec,
  199565. - sizeof(rstvec));
  199566. -
  199567. - /* restore ARM */
  199568. - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, ARMCR4_BCMA_IOCTL_CPUHALT,
  199569. - 0, 0);
  199570. -
  199571. - return true;
  199572. -}
  199573. -
  199574. -void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
  199575. - struct brcmf_chip *ci)
  199576. -{
  199577. - u8 arm_core_idx;
  199578. -
  199579. - arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
  199580. - if (BRCMF_MAX_CORENUM != arm_core_idx) {
  199581. - brcmf_sdio_chip_cm3_enterdl(sdiodev, ci);
  199582. - return;
  199583. - }
  199584. -
  199585. - brcmf_sdio_chip_cr4_enterdl(sdiodev, ci);
  199586. -}
  199587. -
  199588. -bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
  199589. - struct brcmf_chip *ci, u32 rstvec)
  199590. -{
  199591. - u8 arm_core_idx;
  199592. -
  199593. - arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
  199594. - if (BRCMF_MAX_CORENUM != arm_core_idx)
  199595. - return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci);
  199596. -
  199597. - return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, rstvec);
  199598. -}
  199599. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
  199600. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h 2014-07-28 10:07:25.000000000 -0500
  199601. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h 1969-12-31 18:00:00.000000000 -0600
  199602. @@ -1,231 +0,0 @@
  199603. -/*
  199604. - * Copyright (c) 2011 Broadcom Corporation
  199605. - *
  199606. - * Permission to use, copy, modify, and/or distribute this software for any
  199607. - * purpose with or without fee is hereby granted, provided that the above
  199608. - * copyright notice and this permission notice appear in all copies.
  199609. - *
  199610. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  199611. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  199612. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  199613. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  199614. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  199615. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  199616. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  199617. - */
  199618. -
  199619. -#ifndef _BRCMFMAC_SDIO_CHIP_H_
  199620. -#define _BRCMFMAC_SDIO_CHIP_H_
  199621. -
  199622. -/*
  199623. - * Core reg address translation.
  199624. - * Both macro's returns a 32 bits byte address on the backplane bus.
  199625. - */
  199626. -#define CORE_CC_REG(base, field) \
  199627. - (base + offsetof(struct chipcregs, field))
  199628. -#define CORE_BUS_REG(base, field) \
  199629. - (base + offsetof(struct sdpcmd_regs, field))
  199630. -#define CORE_SB(base, field) \
  199631. - (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
  199632. -
  199633. -/* SDIO function 1 register CHIPCLKCSR */
  199634. -/* Force ALP request to backplane */
  199635. -#define SBSDIO_FORCE_ALP 0x01
  199636. -/* Force HT request to backplane */
  199637. -#define SBSDIO_FORCE_HT 0x02
  199638. -/* Force ILP request to backplane */
  199639. -#define SBSDIO_FORCE_ILP 0x04
  199640. -/* Make ALP ready (power up xtal) */
  199641. -#define SBSDIO_ALP_AVAIL_REQ 0x08
  199642. -/* Make HT ready (power up PLL) */
  199643. -#define SBSDIO_HT_AVAIL_REQ 0x10
  199644. -/* Squelch clock requests from HW */
  199645. -#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
  199646. -/* Status: ALP is ready */
  199647. -#define SBSDIO_ALP_AVAIL 0x40
  199648. -/* Status: HT is ready */
  199649. -#define SBSDIO_HT_AVAIL 0x80
  199650. -#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
  199651. -#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
  199652. -#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
  199653. -#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
  199654. -#define SBSDIO_CLKAV(regval, alponly) \
  199655. - (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
  199656. -
  199657. -#define BRCMF_MAX_CORENUM 6
  199658. -
  199659. -struct brcmf_core {
  199660. - u16 id;
  199661. - u16 rev;
  199662. - u32 base;
  199663. - u32 wrapbase;
  199664. - u32 caps;
  199665. - u32 cib;
  199666. -};
  199667. -
  199668. -struct brcmf_chip {
  199669. - u32 chip;
  199670. - u32 chiprev;
  199671. - /* core info */
  199672. - /* always put chipcommon core at 0, bus core at 1 */
  199673. - struct brcmf_core c_inf[BRCMF_MAX_CORENUM];
  199674. - u32 pmurev;
  199675. - u32 pmucaps;
  199676. - u32 ramsize;
  199677. - u32 rambase;
  199678. - u32 rst_vec; /* reset vertor for ARM CR4 core */
  199679. -
  199680. - bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
  199681. - u16 coreid);
  199682. - u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
  199683. - u16 coreid);
  199684. - void (*coredisable)(struct brcmf_sdio_dev *sdiodev,
  199685. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  199686. - u32 in_resetbits);
  199687. - void (*resetcore)(struct brcmf_sdio_dev *sdiodev,
  199688. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  199689. - u32 in_resetbits, u32 post_resetbits);
  199690. -};
  199691. -
  199692. -struct sbconfig {
  199693. - u32 PAD[2];
  199694. - u32 sbipsflag; /* initiator port ocp slave flag */
  199695. - u32 PAD[3];
  199696. - u32 sbtpsflag; /* target port ocp slave flag */
  199697. - u32 PAD[11];
  199698. - u32 sbtmerrloga; /* (sonics >= 2.3) */
  199699. - u32 PAD;
  199700. - u32 sbtmerrlog; /* (sonics >= 2.3) */
  199701. - u32 PAD[3];
  199702. - u32 sbadmatch3; /* address match3 */
  199703. - u32 PAD;
  199704. - u32 sbadmatch2; /* address match2 */
  199705. - u32 PAD;
  199706. - u32 sbadmatch1; /* address match1 */
  199707. - u32 PAD[7];
  199708. - u32 sbimstate; /* initiator agent state */
  199709. - u32 sbintvec; /* interrupt mask */
  199710. - u32 sbtmstatelow; /* target state */
  199711. - u32 sbtmstatehigh; /* target state */
  199712. - u32 sbbwa0; /* bandwidth allocation table0 */
  199713. - u32 PAD;
  199714. - u32 sbimconfiglow; /* initiator configuration */
  199715. - u32 sbimconfighigh; /* initiator configuration */
  199716. - u32 sbadmatch0; /* address match0 */
  199717. - u32 PAD;
  199718. - u32 sbtmconfiglow; /* target configuration */
  199719. - u32 sbtmconfighigh; /* target configuration */
  199720. - u32 sbbconfig; /* broadcast configuration */
  199721. - u32 PAD;
  199722. - u32 sbbstate; /* broadcast state */
  199723. - u32 PAD[3];
  199724. - u32 sbactcnfg; /* activate configuration */
  199725. - u32 PAD[3];
  199726. - u32 sbflagst; /* current sbflags */
  199727. - u32 PAD[3];
  199728. - u32 sbidlow; /* identification */
  199729. - u32 sbidhigh; /* identification */
  199730. -};
  199731. -
  199732. -/* sdio core registers */
  199733. -struct sdpcmd_regs {
  199734. - u32 corecontrol; /* 0x00, rev8 */
  199735. - u32 corestatus; /* rev8 */
  199736. - u32 PAD[1];
  199737. - u32 biststatus; /* rev8 */
  199738. -
  199739. - /* PCMCIA access */
  199740. - u16 pcmciamesportaladdr; /* 0x010, rev8 */
  199741. - u16 PAD[1];
  199742. - u16 pcmciamesportalmask; /* rev8 */
  199743. - u16 PAD[1];
  199744. - u16 pcmciawrframebc; /* rev8 */
  199745. - u16 PAD[1];
  199746. - u16 pcmciaunderflowtimer; /* rev8 */
  199747. - u16 PAD[1];
  199748. -
  199749. - /* interrupt */
  199750. - u32 intstatus; /* 0x020, rev8 */
  199751. - u32 hostintmask; /* rev8 */
  199752. - u32 intmask; /* rev8 */
  199753. - u32 sbintstatus; /* rev8 */
  199754. - u32 sbintmask; /* rev8 */
  199755. - u32 funcintmask; /* rev4 */
  199756. - u32 PAD[2];
  199757. - u32 tosbmailbox; /* 0x040, rev8 */
  199758. - u32 tohostmailbox; /* rev8 */
  199759. - u32 tosbmailboxdata; /* rev8 */
  199760. - u32 tohostmailboxdata; /* rev8 */
  199761. -
  199762. - /* synchronized access to registers in SDIO clock domain */
  199763. - u32 sdioaccess; /* 0x050, rev8 */
  199764. - u32 PAD[3];
  199765. -
  199766. - /* PCMCIA frame control */
  199767. - u8 pcmciaframectrl; /* 0x060, rev8 */
  199768. - u8 PAD[3];
  199769. - u8 pcmciawatermark; /* rev8 */
  199770. - u8 PAD[155];
  199771. -
  199772. - /* interrupt batching control */
  199773. - u32 intrcvlazy; /* 0x100, rev8 */
  199774. - u32 PAD[3];
  199775. -
  199776. - /* counters */
  199777. - u32 cmd52rd; /* 0x110, rev8 */
  199778. - u32 cmd52wr; /* rev8 */
  199779. - u32 cmd53rd; /* rev8 */
  199780. - u32 cmd53wr; /* rev8 */
  199781. - u32 abort; /* rev8 */
  199782. - u32 datacrcerror; /* rev8 */
  199783. - u32 rdoutofsync; /* rev8 */
  199784. - u32 wroutofsync; /* rev8 */
  199785. - u32 writebusy; /* rev8 */
  199786. - u32 readwait; /* rev8 */
  199787. - u32 readterm; /* rev8 */
  199788. - u32 writeterm; /* rev8 */
  199789. - u32 PAD[40];
  199790. - u32 clockctlstatus; /* rev8 */
  199791. - u32 PAD[7];
  199792. -
  199793. - u32 PAD[128]; /* DMA engines */
  199794. -
  199795. - /* SDIO/PCMCIA CIS region */
  199796. - char cis[512]; /* 0x400-0x5ff, rev6 */
  199797. -
  199798. - /* PCMCIA function control registers */
  199799. - char pcmciafcr[256]; /* 0x600-6ff, rev6 */
  199800. - u16 PAD[55];
  199801. -
  199802. - /* PCMCIA backplane access */
  199803. - u16 backplanecsr; /* 0x76E, rev6 */
  199804. - u16 backplaneaddr0; /* rev6 */
  199805. - u16 backplaneaddr1; /* rev6 */
  199806. - u16 backplaneaddr2; /* rev6 */
  199807. - u16 backplaneaddr3; /* rev6 */
  199808. - u16 backplanedata0; /* rev6 */
  199809. - u16 backplanedata1; /* rev6 */
  199810. - u16 backplanedata2; /* rev6 */
  199811. - u16 backplanedata3; /* rev6 */
  199812. - u16 PAD[31];
  199813. -
  199814. - /* sprom "size" & "blank" info */
  199815. - u16 spromstatus; /* 0x7BE, rev2 */
  199816. - u32 PAD[464];
  199817. -
  199818. - u16 PAD[0x80];
  199819. -};
  199820. -
  199821. -int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
  199822. - struct brcmf_chip **ci_ptr);
  199823. -void brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr);
  199824. -void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
  199825. - struct brcmf_chip *ci,
  199826. - u32 drivestrength);
  199827. -u8 brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid);
  199828. -void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
  199829. - struct brcmf_chip *ci);
  199830. -bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
  199831. - struct brcmf_chip *ci, u32 rstvec);
  199832. -
  199833. -#endif /* _BRCMFMAC_SDIO_CHIP_H_ */
  199834. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
  199835. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h 2014-07-28 10:07:25.000000000 -0500
  199836. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h 2014-12-08 00:31:53.840418001 -0600
  199837. @@ -180,6 +180,97 @@
  199838. uint max_request_size;
  199839. ushort max_segment_count;
  199840. uint max_segment_size;
  199841. + uint txglomsz;
  199842. + struct sg_table sgtable;
  199843. +};
  199844. +
  199845. +/* sdio core registers */
  199846. +struct sdpcmd_regs {
  199847. + u32 corecontrol; /* 0x00, rev8 */
  199848. + u32 corestatus; /* rev8 */
  199849. + u32 PAD[1];
  199850. + u32 biststatus; /* rev8 */
  199851. +
  199852. + /* PCMCIA access */
  199853. + u16 pcmciamesportaladdr; /* 0x010, rev8 */
  199854. + u16 PAD[1];
  199855. + u16 pcmciamesportalmask; /* rev8 */
  199856. + u16 PAD[1];
  199857. + u16 pcmciawrframebc; /* rev8 */
  199858. + u16 PAD[1];
  199859. + u16 pcmciaunderflowtimer; /* rev8 */
  199860. + u16 PAD[1];
  199861. +
  199862. + /* interrupt */
  199863. + u32 intstatus; /* 0x020, rev8 */
  199864. + u32 hostintmask; /* rev8 */
  199865. + u32 intmask; /* rev8 */
  199866. + u32 sbintstatus; /* rev8 */
  199867. + u32 sbintmask; /* rev8 */
  199868. + u32 funcintmask; /* rev4 */
  199869. + u32 PAD[2];
  199870. + u32 tosbmailbox; /* 0x040, rev8 */
  199871. + u32 tohostmailbox; /* rev8 */
  199872. + u32 tosbmailboxdata; /* rev8 */
  199873. + u32 tohostmailboxdata; /* rev8 */
  199874. +
  199875. + /* synchronized access to registers in SDIO clock domain */
  199876. + u32 sdioaccess; /* 0x050, rev8 */
  199877. + u32 PAD[3];
  199878. +
  199879. + /* PCMCIA frame control */
  199880. + u8 pcmciaframectrl; /* 0x060, rev8 */
  199881. + u8 PAD[3];
  199882. + u8 pcmciawatermark; /* rev8 */
  199883. + u8 PAD[155];
  199884. +
  199885. + /* interrupt batching control */
  199886. + u32 intrcvlazy; /* 0x100, rev8 */
  199887. + u32 PAD[3];
  199888. +
  199889. + /* counters */
  199890. + u32 cmd52rd; /* 0x110, rev8 */
  199891. + u32 cmd52wr; /* rev8 */
  199892. + u32 cmd53rd; /* rev8 */
  199893. + u32 cmd53wr; /* rev8 */
  199894. + u32 abort; /* rev8 */
  199895. + u32 datacrcerror; /* rev8 */
  199896. + u32 rdoutofsync; /* rev8 */
  199897. + u32 wroutofsync; /* rev8 */
  199898. + u32 writebusy; /* rev8 */
  199899. + u32 readwait; /* rev8 */
  199900. + u32 readterm; /* rev8 */
  199901. + u32 writeterm; /* rev8 */
  199902. + u32 PAD[40];
  199903. + u32 clockctlstatus; /* rev8 */
  199904. + u32 PAD[7];
  199905. +
  199906. + u32 PAD[128]; /* DMA engines */
  199907. +
  199908. + /* SDIO/PCMCIA CIS region */
  199909. + char cis[512]; /* 0x400-0x5ff, rev6 */
  199910. +
  199911. + /* PCMCIA function control registers */
  199912. + char pcmciafcr[256]; /* 0x600-6ff, rev6 */
  199913. + u16 PAD[55];
  199914. +
  199915. + /* PCMCIA backplane access */
  199916. + u16 backplanecsr; /* 0x76E, rev6 */
  199917. + u16 backplaneaddr0; /* rev6 */
  199918. + u16 backplaneaddr1; /* rev6 */
  199919. + u16 backplaneaddr2; /* rev6 */
  199920. + u16 backplaneaddr3; /* rev6 */
  199921. + u16 backplanedata0; /* rev6 */
  199922. + u16 backplanedata1; /* rev6 */
  199923. + u16 backplanedata2; /* rev6 */
  199924. + u16 backplanedata3; /* rev6 */
  199925. + u16 PAD[31];
  199926. +
  199927. + /* sprom "size" & "blank" info */
  199928. + u16 spromstatus; /* 0x7BE, rev2 */
  199929. + u32 PAD[464];
  199930. +
  199931. + u16 PAD[0x80];
  199932. };
  199933. /* Register/deregister interrupt handler. */
  199934. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/usb.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/usb.c
  199935. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/usb.c 2014-07-28 10:07:25.000000000 -0500
  199936. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/usb.c 2014-12-08 00:31:53.840418001 -0600
  199937. @@ -25,6 +25,7 @@
  199938. #include <dhd_bus.h>
  199939. #include <dhd_dbg.h>
  199940. +#include "firmware.h"
  199941. #include "usb_rdl.h"
  199942. #include "usb.h"
  199943. @@ -61,12 +62,6 @@
  199944. u8 *image;
  199945. int image_len;
  199946. };
  199947. -static struct list_head fw_image_list;
  199948. -
  199949. -struct intr_transfer_buf {
  199950. - u32 notification;
  199951. - u32 reserved;
  199952. -};
  199953. struct brcmf_usbdev_info {
  199954. struct brcmf_usbdev bus_pub; /* MUST BE FIRST */
  199955. @@ -75,7 +70,7 @@
  199956. struct list_head rx_postq;
  199957. struct list_head tx_freeq;
  199958. struct list_head tx_postq;
  199959. - uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
  199960. + uint rx_pipe, tx_pipe, rx_pipe2;
  199961. int rx_low_watermark;
  199962. int tx_low_watermark;
  199963. @@ -87,7 +82,7 @@
  199964. struct brcmf_usbreq *tx_reqs;
  199965. struct brcmf_usbreq *rx_reqs;
  199966. - u8 *image; /* buffer for combine fw and nvram */
  199967. + const u8 *image; /* buffer for combine fw and nvram */
  199968. int image_len;
  199969. struct usb_device *usbdev;
  199970. @@ -104,10 +99,6 @@
  199971. ulong ctl_op;
  199972. struct urb *bulk_urb; /* used for FW download */
  199973. - struct urb *intr_urb; /* URB for interrupt endpoint */
  199974. - int intr_size; /* Size of interrupt message */
  199975. - int interval; /* Interrupt polling interval */
  199976. - struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */
  199977. };
  199978. static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
  199979. @@ -531,39 +522,6 @@
  199980. }
  199981. }
  199982. -static void
  199983. -brcmf_usb_intr_complete(struct urb *urb)
  199984. -{
  199985. - struct brcmf_usbdev_info *devinfo =
  199986. - (struct brcmf_usbdev_info *)urb->context;
  199987. - int err;
  199988. -
  199989. - brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status);
  199990. -
  199991. - if (devinfo == NULL)
  199992. - return;
  199993. -
  199994. - if (unlikely(urb->status)) {
  199995. - if (urb->status == -ENOENT ||
  199996. - urb->status == -ESHUTDOWN ||
  199997. - urb->status == -ENODEV) {
  199998. - brcmf_usb_state_change(devinfo,
  199999. - BRCMFMAC_USB_STATE_DOWN);
  200000. - }
  200001. - }
  200002. -
  200003. - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) {
  200004. - brcmf_err("intr cb when DBUS down, ignoring\n");
  200005. - return;
  200006. - }
  200007. -
  200008. - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) {
  200009. - err = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
  200010. - if (err)
  200011. - brcmf_err("usb_submit_urb, err=%d\n", err);
  200012. - }
  200013. -}
  200014. -
  200015. static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
  200016. {
  200017. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
  200018. @@ -619,7 +577,6 @@
  200019. {
  200020. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
  200021. u16 ifnum;
  200022. - int ret;
  200023. brcmf_dbg(USB, "Enter\n");
  200024. if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP)
  200025. @@ -628,23 +585,6 @@
  200026. /* Success, indicate devinfo is fully up */
  200027. brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_UP);
  200028. - if (devinfo->intr_urb) {
  200029. - usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev,
  200030. - devinfo->intr_pipe,
  200031. - &devinfo->intr,
  200032. - devinfo->intr_size,
  200033. - (usb_complete_t)brcmf_usb_intr_complete,
  200034. - devinfo,
  200035. - devinfo->interval);
  200036. -
  200037. - ret = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
  200038. - if (ret) {
  200039. - brcmf_err("USB_SUBMIT_URB failed with status %d\n",
  200040. - ret);
  200041. - return -EINVAL;
  200042. - }
  200043. - }
  200044. -
  200045. if (devinfo->ctl_urb) {
  200046. devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);
  200047. devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0);
  200048. @@ -681,8 +621,6 @@
  200049. return;
  200050. brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN);
  200051. - if (devinfo->intr_urb)
  200052. - usb_kill_urb(devinfo->intr_urb);
  200053. if (devinfo->ctl_urb)
  200054. usb_kill_urb(devinfo->ctl_urb);
  200055. @@ -1021,7 +959,7 @@
  200056. }
  200057. err = brcmf_usb_dlstart(devinfo,
  200058. - devinfo->image, devinfo->image_len);
  200059. + (u8 *)devinfo->image, devinfo->image_len);
  200060. if (err == 0)
  200061. err = brcmf_usb_dlrun(devinfo);
  200062. return err;
  200063. @@ -1036,7 +974,6 @@
  200064. brcmf_usb_free_q(&devinfo->rx_freeq, false);
  200065. brcmf_usb_free_q(&devinfo->tx_freeq, false);
  200066. - usb_free_urb(devinfo->intr_urb);
  200067. usb_free_urb(devinfo->ctl_urb);
  200068. usb_free_urb(devinfo->bulk_urb);
  200069. @@ -1080,68 +1017,20 @@
  200070. return -1;
  200071. }
  200072. -static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
  200073. +static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo)
  200074. {
  200075. - s8 *fwname;
  200076. - const struct firmware *fw;
  200077. - struct brcmf_usb_image *fw_image;
  200078. - int err;
  200079. -
  200080. - brcmf_dbg(USB, "Enter\n");
  200081. switch (devinfo->bus_pub.devid) {
  200082. case 43143:
  200083. - fwname = BRCMF_USB_43143_FW_NAME;
  200084. - break;
  200085. + return BRCMF_USB_43143_FW_NAME;
  200086. case 43235:
  200087. case 43236:
  200088. case 43238:
  200089. - fwname = BRCMF_USB_43236_FW_NAME;
  200090. - break;
  200091. + return BRCMF_USB_43236_FW_NAME;
  200092. case 43242:
  200093. - fwname = BRCMF_USB_43242_FW_NAME;
  200094. - break;
  200095. + return BRCMF_USB_43242_FW_NAME;
  200096. default:
  200097. - return -EINVAL;
  200098. - break;
  200099. - }
  200100. - brcmf_dbg(USB, "Loading FW %s\n", fwname);
  200101. - list_for_each_entry(fw_image, &fw_image_list, list) {
  200102. - if (fw_image->fwname == fwname) {
  200103. - devinfo->image = fw_image->image;
  200104. - devinfo->image_len = fw_image->image_len;
  200105. - return 0;
  200106. - }
  200107. - }
  200108. - /* fw image not yet loaded. Load it now and add to list */
  200109. - err = request_firmware(&fw, fwname, devinfo->dev);
  200110. - if (!fw) {
  200111. - brcmf_err("fail to request firmware %s\n", fwname);
  200112. - return err;
  200113. - }
  200114. - if (check_file(fw->data) < 0) {
  200115. - brcmf_err("invalid firmware %s\n", fwname);
  200116. - return -EINVAL;
  200117. + return NULL;
  200118. }
  200119. -
  200120. - fw_image = kzalloc(sizeof(*fw_image), GFP_ATOMIC);
  200121. - if (!fw_image)
  200122. - return -ENOMEM;
  200123. - INIT_LIST_HEAD(&fw_image->list);
  200124. - list_add_tail(&fw_image->list, &fw_image_list);
  200125. - fw_image->fwname = fwname;
  200126. - fw_image->image = vmalloc(fw->size);
  200127. - if (!fw_image->image)
  200128. - return -ENOMEM;
  200129. -
  200130. - memcpy(fw_image->image, fw->data, fw->size);
  200131. - fw_image->image_len = fw->size;
  200132. -
  200133. - release_firmware(fw);
  200134. -
  200135. - devinfo->image = fw_image->image;
  200136. - devinfo->image_len = fw_image->image_len;
  200137. -
  200138. - return 0;
  200139. }
  200140. @@ -1186,11 +1075,6 @@
  200141. goto error;
  200142. devinfo->tx_freecount = ntxq;
  200143. - devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);
  200144. - if (!devinfo->intr_urb) {
  200145. - brcmf_err("usb_alloc_urb (intr) failed\n");
  200146. - goto error;
  200147. - }
  200148. devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);
  200149. if (!devinfo->ctl_urb) {
  200150. brcmf_err("usb_alloc_urb (ctl) failed\n");
  200151. @@ -1202,16 +1086,6 @@
  200152. goto error;
  200153. }
  200154. - if (!brcmf_usb_dlneeded(devinfo))
  200155. - return &devinfo->bus_pub;
  200156. -
  200157. - brcmf_dbg(USB, "Start fw downloading\n");
  200158. - if (brcmf_usb_get_fw(devinfo))
  200159. - goto error;
  200160. -
  200161. - if (brcmf_usb_fw_download(devinfo))
  200162. - goto error;
  200163. -
  200164. return &devinfo->bus_pub;
  200165. error:
  200166. @@ -1222,18 +1096,77 @@
  200167. static struct brcmf_bus_ops brcmf_usb_bus_ops = {
  200168. .txdata = brcmf_usb_tx,
  200169. - .init = brcmf_usb_up,
  200170. .stop = brcmf_usb_down,
  200171. .txctl = brcmf_usb_tx_ctlpkt,
  200172. .rxctl = brcmf_usb_rx_ctlpkt,
  200173. };
  200174. +static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
  200175. +{
  200176. + int ret;
  200177. +
  200178. + /* Attach to the common driver interface */
  200179. + ret = brcmf_attach(devinfo->dev);
  200180. + if (ret) {
  200181. + brcmf_err("brcmf_attach failed\n");
  200182. + return ret;
  200183. + }
  200184. +
  200185. + ret = brcmf_usb_up(devinfo->dev);
  200186. + if (ret)
  200187. + goto fail;
  200188. +
  200189. + ret = brcmf_bus_start(devinfo->dev);
  200190. + if (ret)
  200191. + goto fail;
  200192. +
  200193. + return 0;
  200194. +fail:
  200195. + brcmf_detach(devinfo->dev);
  200196. + return ret;
  200197. +}
  200198. +
  200199. +static void brcmf_usb_probe_phase2(struct device *dev,
  200200. + const struct firmware *fw,
  200201. + void *nvram, u32 nvlen)
  200202. +{
  200203. + struct brcmf_bus *bus = dev_get_drvdata(dev);
  200204. + struct brcmf_usbdev_info *devinfo;
  200205. + int ret;
  200206. +
  200207. + brcmf_dbg(USB, "Start fw downloading\n");
  200208. + ret = check_file(fw->data);
  200209. + if (ret < 0) {
  200210. + brcmf_err("invalid firmware\n");
  200211. + release_firmware(fw);
  200212. + goto error;
  200213. + }
  200214. +
  200215. + devinfo = bus->bus_priv.usb->devinfo;
  200216. + devinfo->image = fw->data;
  200217. + devinfo->image_len = fw->size;
  200218. +
  200219. + ret = brcmf_usb_fw_download(devinfo);
  200220. + release_firmware(fw);
  200221. + if (ret)
  200222. + goto error;
  200223. +
  200224. + ret = brcmf_usb_bus_setup(devinfo);
  200225. + if (ret)
  200226. + goto error;
  200227. +
  200228. + return;
  200229. +error:
  200230. + brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret);
  200231. + device_release_driver(dev);
  200232. +}
  200233. +
  200234. static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
  200235. {
  200236. struct brcmf_bus *bus = NULL;
  200237. struct brcmf_usbdev *bus_pub = NULL;
  200238. - int ret;
  200239. struct device *dev = devinfo->dev;
  200240. + int ret;
  200241. brcmf_dbg(USB, "Enter\n");
  200242. bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);
  200243. @@ -1254,22 +1187,18 @@
  200244. bus->chip = bus_pub->devid;
  200245. bus->chiprev = bus_pub->chiprev;
  200246. bus->proto_type = BRCMF_PROTO_BCDC;
  200247. + bus->always_use_fws_queue = true;
  200248. - /* Attach to the common driver interface */
  200249. - ret = brcmf_attach(dev);
  200250. - if (ret) {
  200251. - brcmf_err("brcmf_attach failed\n");
  200252. - goto fail;
  200253. - }
  200254. -
  200255. - ret = brcmf_bus_start(dev);
  200256. - if (ret) {
  200257. - brcmf_err("dongle is not responding\n");
  200258. - brcmf_detach(dev);
  200259. - goto fail;
  200260. + if (!brcmf_usb_dlneeded(devinfo)) {
  200261. + ret = brcmf_usb_bus_setup(devinfo);
  200262. + if (ret)
  200263. + goto fail;
  200264. }
  200265. -
  200266. + /* request firmware here */
  200267. + brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,
  200268. + brcmf_usb_probe_phase2);
  200269. return 0;
  200270. +
  200271. fail:
  200272. /* Release resources in reverse order */
  200273. kfree(bus);
  200274. @@ -1357,9 +1286,6 @@
  200275. goto fail;
  200276. }
  200277. - endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
  200278. - devinfo->intr_pipe = usb_rcvintpipe(usb, endpoint_num);
  200279. -
  200280. devinfo->rx_pipe = 0;
  200281. devinfo->rx_pipe2 = 0;
  200282. devinfo->tx_pipe = 0;
  200283. @@ -1391,16 +1317,9 @@
  200284. }
  200285. }
  200286. - /* Allocate interrupt URB and data buffer */
  200287. - /* RNDIS says 8-byte intr, our old drivers used 4-byte */
  200288. - if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))
  200289. - devinfo->intr_size = 8;
  200290. - else
  200291. - devinfo->intr_size = 4;
  200292. -
  200293. - devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
  200294. -
  200295. - if (usb->speed == USB_SPEED_HIGH)
  200296. + if (usb->speed == USB_SPEED_SUPER)
  200297. + brcmf_dbg(USB, "Broadcom super speed USB wireless device detected\n");
  200298. + else if (usb->speed == USB_SPEED_HIGH)
  200299. brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n");
  200300. else
  200301. brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n");
  200302. @@ -1455,23 +1374,18 @@
  200303. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
  200304. brcmf_dbg(USB, "Enter\n");
  200305. - if (!brcmf_attach(devinfo->dev))
  200306. - return brcmf_bus_start(&usb->dev);
  200307. -
  200308. - return 0;
  200309. + return brcmf_usb_bus_setup(devinfo);
  200310. }
  200311. static int brcmf_usb_reset_resume(struct usb_interface *intf)
  200312. {
  200313. struct usb_device *usb = interface_to_usbdev(intf);
  200314. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
  200315. -
  200316. brcmf_dbg(USB, "Enter\n");
  200317. - if (!brcmf_usb_fw_download(devinfo))
  200318. - return brcmf_usb_resume(intf);
  200319. -
  200320. - return -EIO;
  200321. + return brcmf_fw_get_firmwares(&usb->dev, 0,
  200322. + brcmf_usb_get_fwname(devinfo), NULL,
  200323. + brcmf_usb_probe_phase2);
  200324. }
  200325. #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c
  200326. @@ -1506,16 +1420,6 @@
  200327. .disable_hub_initiated_lpm = 1,
  200328. };
  200329. -static void brcmf_release_fw(struct list_head *q)
  200330. -{
  200331. - struct brcmf_usb_image *fw_image, *next;
  200332. -
  200333. - list_for_each_entry_safe(fw_image, next, q, list) {
  200334. - vfree(fw_image->image);
  200335. - list_del_init(&fw_image->list);
  200336. - }
  200337. -}
  200338. -
  200339. static int brcmf_usb_reset_device(struct device *dev, void *notused)
  200340. {
  200341. /* device past is the usb interface so we
  200342. @@ -1534,12 +1438,10 @@
  200343. ret = driver_for_each_device(drv, NULL, NULL,
  200344. brcmf_usb_reset_device);
  200345. usb_deregister(&brcmf_usbdrvr);
  200346. - brcmf_release_fw(&fw_image_list);
  200347. }
  200348. void brcmf_usb_register(void)
  200349. {
  200350. brcmf_dbg(USB, "Enter\n");
  200351. - INIT_LIST_HEAD(&fw_image_list);
  200352. usb_register(&brcmf_usbdrvr);
  200353. }
  200354. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
  200355. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c 2014-07-28 10:07:25.000000000 -0500
  200356. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c 2014-12-08 00:31:53.844418001 -0600
  200357. @@ -18,6 +18,7 @@
  200358. #include <linux/kernel.h>
  200359. #include <linux/etherdevice.h>
  200360. +#include <linux/module.h>
  200361. #include <net/cfg80211.h>
  200362. #include <net/netlink.h>
  200363. @@ -190,6 +191,7 @@
  200364. .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
  200365. .bitrates = wl_g_rates,
  200366. .n_bitrates = wl_g_rates_size,
  200367. + .ht_cap = {IEEE80211_HT_CAP_SUP_WIDTH_20_40, true},
  200368. };
  200369. static struct ieee80211_supported_band __wl_band_5ghz_a = {
  200370. @@ -219,9 +221,9 @@
  200371. */
  200372. REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
  200373. /* IEEE 802.11a, channel 36..64 */
  200374. - REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
  200375. + REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
  200376. /* IEEE 802.11a, channel 100..165 */
  200377. - REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), }
  200378. + REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
  200379. };
  200380. static const u32 __wl_cipher_suites[] = {
  200381. @@ -251,6 +253,10 @@
  200382. struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
  200383. };
  200384. +static int brcmf_roamoff;
  200385. +module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
  200386. +MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
  200387. +
  200388. /* Quarter dBm units to mW
  200389. * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
  200390. * Table is offset so the last entry is largest mW value that fits in
  200391. @@ -335,6 +341,61 @@
  200392. return qdbm;
  200393. }
  200394. +static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
  200395. + struct cfg80211_chan_def *ch)
  200396. +{
  200397. + struct brcmu_chan ch_inf;
  200398. + s32 primary_offset;
  200399. +
  200400. + brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
  200401. + ch->chan->center_freq, ch->center_freq1, ch->width);
  200402. + ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
  200403. + primary_offset = ch->center_freq1 - ch->chan->center_freq;
  200404. + switch (ch->width) {
  200405. + case NL80211_CHAN_WIDTH_20_NOHT:
  200406. + case NL80211_CHAN_WIDTH_20:
  200407. + ch_inf.bw = BRCMU_CHAN_BW_20;
  200408. + WARN_ON(primary_offset != 0);
  200409. + break;
  200410. + case NL80211_CHAN_WIDTH_40:
  200411. + ch_inf.bw = BRCMU_CHAN_BW_40;
  200412. + if (primary_offset < 0)
  200413. + ch_inf.sb = BRCMU_CHAN_SB_U;
  200414. + else
  200415. + ch_inf.sb = BRCMU_CHAN_SB_L;
  200416. + break;
  200417. + case NL80211_CHAN_WIDTH_80:
  200418. + ch_inf.bw = BRCMU_CHAN_BW_80;
  200419. + if (primary_offset < 0) {
  200420. + if (primary_offset < -CH_10MHZ_APART)
  200421. + ch_inf.sb = BRCMU_CHAN_SB_UU;
  200422. + else
  200423. + ch_inf.sb = BRCMU_CHAN_SB_UL;
  200424. + } else {
  200425. + if (primary_offset > CH_10MHZ_APART)
  200426. + ch_inf.sb = BRCMU_CHAN_SB_LL;
  200427. + else
  200428. + ch_inf.sb = BRCMU_CHAN_SB_LU;
  200429. + }
  200430. + break;
  200431. + default:
  200432. + WARN_ON_ONCE(1);
  200433. + }
  200434. + switch (ch->chan->band) {
  200435. + case IEEE80211_BAND_2GHZ:
  200436. + ch_inf.band = BRCMU_CHAN_BAND_2G;
  200437. + break;
  200438. + case IEEE80211_BAND_5GHZ:
  200439. + ch_inf.band = BRCMU_CHAN_BAND_5G;
  200440. + break;
  200441. + default:
  200442. + WARN_ON_ONCE(1);
  200443. + }
  200444. + d11inf->encchspec(&ch_inf);
  200445. +
  200446. + return ch_inf.chspec;
  200447. +}
  200448. +
  200449. u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
  200450. struct ieee80211_channel *ch)
  200451. {
  200452. @@ -351,13 +412,11 @@
  200453. * triples, returning a pointer to the substring whose first element
  200454. * matches tag
  200455. */
  200456. -struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
  200457. +const struct brcmf_tlv *
  200458. +brcmf_parse_tlvs(const void *buf, int buflen, uint key)
  200459. {
  200460. - struct brcmf_tlv *elt;
  200461. - int totlen;
  200462. -
  200463. - elt = (struct brcmf_tlv *)buf;
  200464. - totlen = buflen;
  200465. + const struct brcmf_tlv *elt = buf;
  200466. + int totlen = buflen;
  200467. /* find tagged parameter */
  200468. while (totlen >= TLV_HDR_LEN) {
  200469. @@ -378,8 +437,8 @@
  200470. * not update the tlvs buffer pointer/length.
  200471. */
  200472. static bool
  200473. -brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
  200474. - u8 *oui, u32 oui_len, u8 type)
  200475. +brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
  200476. + const u8 *oui, u32 oui_len, u8 type)
  200477. {
  200478. /* If the contents match the OUI and the type */
  200479. if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
  200480. @@ -401,12 +460,12 @@
  200481. }
  200482. static struct brcmf_vs_tlv *
  200483. -brcmf_find_wpaie(u8 *parse, u32 len)
  200484. +brcmf_find_wpaie(const u8 *parse, u32 len)
  200485. {
  200486. - struct brcmf_tlv *ie;
  200487. + const struct brcmf_tlv *ie;
  200488. while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
  200489. - if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
  200490. + if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
  200491. WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
  200492. return (struct brcmf_vs_tlv *)ie;
  200493. }
  200494. @@ -414,9 +473,9 @@
  200495. }
  200496. static struct brcmf_vs_tlv *
  200497. -brcmf_find_wpsie(u8 *parse, u32 len)
  200498. +brcmf_find_wpsie(const u8 *parse, u32 len)
  200499. {
  200500. - struct brcmf_tlv *ie;
  200501. + const struct brcmf_tlv *ie;
  200502. while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
  200503. if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
  200504. @@ -491,6 +550,19 @@
  200505. return err;
  200506. }
  200507. +static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
  200508. +{
  200509. + enum nl80211_iftype iftype;
  200510. +
  200511. + iftype = vif->wdev.iftype;
  200512. + return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
  200513. +}
  200514. +
  200515. +static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
  200516. +{
  200517. + return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
  200518. +}
  200519. +
  200520. static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
  200521. const char *name,
  200522. enum nl80211_iftype type,
  200523. @@ -569,6 +641,9 @@
  200524. if (err)
  200525. brcmf_err("Scan abort failed\n");
  200526. }
  200527. +
  200528. + brcmf_set_mpc(ifp, 1);
  200529. +
  200530. /*
  200531. * e-scan can be initiated by scheduled scan
  200532. * which takes precedence.
  200533. @@ -578,12 +653,10 @@
  200534. cfg->sched_escan = false;
  200535. if (!aborted)
  200536. cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
  200537. - brcmf_set_mpc(ifp, 1);
  200538. } else if (scan_request) {
  200539. brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
  200540. aborted ? "Aborted" : "Done");
  200541. cfg80211_scan_done(scan_request, aborted);
  200542. - brcmf_set_mpc(ifp, 1);
  200543. }
  200544. if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
  200545. brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
  200546. @@ -651,7 +724,6 @@
  200547. type);
  200548. return -EOPNOTSUPP;
  200549. case NL80211_IFTYPE_ADHOC:
  200550. - vif->mode = WL_MODE_IBSS;
  200551. infra = 0;
  200552. break;
  200553. case NL80211_IFTYPE_STATION:
  200554. @@ -667,12 +739,10 @@
  200555. */
  200556. return 0;
  200557. }
  200558. - vif->mode = WL_MODE_BSS;
  200559. infra = 1;
  200560. break;
  200561. case NL80211_IFTYPE_AP:
  200562. case NL80211_IFTYPE_P2P_GO:
  200563. - vif->mode = WL_MODE_AP;
  200564. ap = 1;
  200565. break;
  200566. default:
  200567. @@ -696,7 +766,7 @@
  200568. err = -EAGAIN;
  200569. goto done;
  200570. }
  200571. - brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
  200572. + brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
  200573. "Adhoc" : "Infra");
  200574. }
  200575. ndev->ieee80211_ptr->iftype = type;
  200576. @@ -1222,8 +1292,8 @@
  200577. params->chandef.chan->center_freq);
  200578. if (params->channel_fixed) {
  200579. /* adding chanspec */
  200580. - chanspec = channel_to_chanspec(&cfg->d11inf,
  200581. - params->chandef.chan);
  200582. + chanspec = chandef_to_chanspec(&cfg->d11inf,
  200583. + &params->chandef);
  200584. join_params.params_le.chanspec_list[0] =
  200585. cpu_to_le16(chanspec);
  200586. join_params.params_le.chanspec_num = cpu_to_le32(1);
  200587. @@ -1340,13 +1410,14 @@
  200588. }
  200589. static s32
  200590. -brcmf_set_set_cipher(struct net_device *ndev,
  200591. - struct cfg80211_connect_params *sme)
  200592. +brcmf_set_wsec_mode(struct net_device *ndev,
  200593. + struct cfg80211_connect_params *sme, bool mfp)
  200594. {
  200595. struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
  200596. struct brcmf_cfg80211_security *sec;
  200597. s32 pval = 0;
  200598. s32 gval = 0;
  200599. + s32 wsec;
  200600. s32 err = 0;
  200601. if (sme->crypto.n_ciphers_pairwise) {
  200602. @@ -1398,7 +1469,12 @@
  200603. if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
  200604. sme->privacy)
  200605. pval = AES_ENABLED;
  200606. - err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
  200607. +
  200608. + if (mfp)
  200609. + wsec = pval | gval | MFP_CAPABLE;
  200610. + else
  200611. + wsec = pval | gval;
  200612. + err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
  200613. if (err) {
  200614. brcmf_err("error (%d)\n", err);
  200615. return err;
  200616. @@ -1562,13 +1638,12 @@
  200617. struct ieee80211_channel *chan = sme->channel;
  200618. struct brcmf_join_params join_params;
  200619. size_t join_params_size;
  200620. - struct brcmf_tlv *rsn_ie;
  200621. - struct brcmf_vs_tlv *wpa_ie;
  200622. - void *ie;
  200623. + const struct brcmf_tlv *rsn_ie;
  200624. + const struct brcmf_vs_tlv *wpa_ie;
  200625. + const void *ie;
  200626. u32 ie_len;
  200627. struct brcmf_ext_join_params_le *ext_join_params;
  200628. u16 chanspec;
  200629. -
  200630. s32 err = 0;
  200631. brcmf_dbg(TRACE, "Enter\n");
  200632. @@ -1591,7 +1666,8 @@
  200633. ie_len = wpa_ie->len + TLV_HDR_LEN;
  200634. } else {
  200635. /* find the RSN_IE */
  200636. - rsn_ie = brcmf_parse_tlvs((u8 *)sme->ie, sme->ie_len,
  200637. + rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
  200638. + sme->ie_len,
  200639. WLAN_EID_RSN);
  200640. if (rsn_ie) {
  200641. ie = rsn_ie;
  200642. @@ -1636,7 +1712,7 @@
  200643. goto done;
  200644. }
  200645. - err = brcmf_set_set_cipher(ndev, sme);
  200646. + err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
  200647. if (err) {
  200648. brcmf_err("wl_set_set_cipher failed (%d)\n", err);
  200649. goto done;
  200650. @@ -1678,22 +1754,9 @@
  200651. ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
  200652. memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
  200653. profile->ssid.SSID_len);
  200654. - /*increase dwell time to receive probe response or detect Beacon
  200655. - * from target AP at a noisy air only during connect command
  200656. - */
  200657. - ext_join_params->scan_le.active_time =
  200658. - cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
  200659. - ext_join_params->scan_le.passive_time =
  200660. - cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
  200661. +
  200662. /* Set up join scan parameters */
  200663. ext_join_params->scan_le.scan_type = -1;
  200664. - /* to sync with presence period of VSDB GO.
  200665. - * Send probe request more frequently. Probe request will be stopped
  200666. - * when it gets probe response from target AP/GO.
  200667. - */
  200668. - ext_join_params->scan_le.nprobes =
  200669. - cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
  200670. - BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
  200671. ext_join_params->scan_le.home_time = cpu_to_le32(-1);
  200672. if (sme->bssid)
  200673. @@ -1706,6 +1769,25 @@
  200674. ext_join_params->assoc_le.chanspec_list[0] =
  200675. cpu_to_le16(chanspec);
  200676. + /* Increase dwell time to receive probe response or detect
  200677. + * beacon from target AP at a noisy air only during connect
  200678. + * command.
  200679. + */
  200680. + ext_join_params->scan_le.active_time =
  200681. + cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
  200682. + ext_join_params->scan_le.passive_time =
  200683. + cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
  200684. + /* To sync with presence period of VSDB GO send probe request
  200685. + * more frequently. Probe request will be stopped when it gets
  200686. + * probe response from target AP/GO.
  200687. + */
  200688. + ext_join_params->scan_le.nprobes =
  200689. + cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
  200690. + BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
  200691. + } else {
  200692. + ext_join_params->scan_le.active_time = cpu_to_le32(-1);
  200693. + ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
  200694. + ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
  200695. }
  200696. err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
  200697. @@ -1913,7 +1995,7 @@
  200698. brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
  200699. memcpy(key.data, params->key, key.len);
  200700. - if ((ifp->vif->mode != WL_MODE_AP) &&
  200701. + if (!brcmf_is_apmode(ifp->vif) &&
  200702. (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
  200703. brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
  200704. memcpy(keybuf, &key.data[24], sizeof(keybuf));
  200705. @@ -1981,7 +2063,9 @@
  200706. if (!check_vif_up(ifp->vif))
  200707. return -EIO;
  200708. - if (mac_addr) {
  200709. + if (mac_addr &&
  200710. + (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
  200711. + (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
  200712. brcmf_dbg(TRACE, "Exit");
  200713. return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
  200714. }
  200715. @@ -2010,7 +2094,7 @@
  200716. brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
  200717. break;
  200718. case WLAN_CIPHER_SUITE_TKIP:
  200719. - if (ifp->vif->mode != WL_MODE_AP) {
  200720. + if (!brcmf_is_apmode(ifp->vif)) {
  200721. brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
  200722. memcpy(keybuf, &key.data[24], sizeof(keybuf));
  200723. memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
  200724. @@ -2164,12 +2248,14 @@
  200725. s32 err = 0;
  200726. u8 *bssid = profile->bssid;
  200727. struct brcmf_sta_info_le sta_info_le;
  200728. + u32 beacon_period;
  200729. + u32 dtim_period;
  200730. brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
  200731. if (!check_vif_up(ifp->vif))
  200732. return -EIO;
  200733. - if (ifp->vif->mode == WL_MODE_AP) {
  200734. + if (brcmf_is_apmode(ifp->vif)) {
  200735. memcpy(&sta_info_le, mac, ETH_ALEN);
  200736. err = brcmf_fil_iovar_data_get(ifp, "sta_info",
  200737. &sta_info_le,
  200738. @@ -2186,7 +2272,7 @@
  200739. }
  200740. brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
  200741. sinfo->inactive_time, sinfo->connected_time);
  200742. - } else if (ifp->vif->mode == WL_MODE_BSS) {
  200743. + } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) {
  200744. if (memcmp(mac, bssid, ETH_ALEN)) {
  200745. brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
  200746. mac, bssid);
  200747. @@ -2218,6 +2304,30 @@
  200748. sinfo->signal = rssi;
  200749. brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
  200750. }
  200751. + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD,
  200752. + &beacon_period);
  200753. + if (err) {
  200754. + brcmf_err("Could not get beacon period (%d)\n",
  200755. + err);
  200756. + goto done;
  200757. + } else {
  200758. + sinfo->bss_param.beacon_interval =
  200759. + beacon_period;
  200760. + brcmf_dbg(CONN, "Beacon peroid %d\n",
  200761. + beacon_period);
  200762. + }
  200763. + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD,
  200764. + &dtim_period);
  200765. + if (err) {
  200766. + brcmf_err("Could not get DTIM period (%d)\n",
  200767. + err);
  200768. + goto done;
  200769. + } else {
  200770. + sinfo->bss_param.dtim_period = dtim_period;
  200771. + brcmf_dbg(CONN, "DTIM peroid %d\n",
  200772. + dtim_period);
  200773. + }
  200774. + sinfo->filled |= STATION_INFO_BSS_PARAM;
  200775. }
  200776. } else
  200777. err = -EPERM;
  200778. @@ -2444,18 +2554,13 @@
  200779. return err;
  200780. }
  200781. -static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
  200782. -{
  200783. - return vif->mode == WL_MODE_IBSS;
  200784. -}
  200785. -
  200786. static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
  200787. struct brcmf_if *ifp)
  200788. {
  200789. struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
  200790. struct brcmf_bss_info_le *bi;
  200791. struct brcmf_ssid *ssid;
  200792. - struct brcmf_tlv *tim;
  200793. + const struct brcmf_tlv *tim;
  200794. u16 beacon_interval;
  200795. u8 dtim_period;
  200796. size_t ie_len;
  200797. @@ -3075,7 +3180,7 @@
  200798. }
  200799. if (!request->n_ssids || !request->n_match_sets) {
  200800. - brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
  200801. + brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
  200802. request->n_ssids);
  200803. return -EINVAL;
  200804. }
  200805. @@ -3220,8 +3325,9 @@
  200806. }
  200807. static s32
  200808. -brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
  200809. - bool is_rsn_ie)
  200810. +brcmf_configure_wpaie(struct net_device *ndev,
  200811. + const struct brcmf_vs_tlv *wpa_ie,
  200812. + bool is_rsn_ie)
  200813. {
  200814. struct brcmf_if *ifp = netdev_priv(ndev);
  200815. u32 auth = 0; /* d11 open authentication */
  200816. @@ -3684,42 +3790,26 @@
  200817. }
  200818. static s32
  200819. -brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
  200820. - struct brcmf_if *ifp,
  200821. - struct ieee80211_channel *channel)
  200822. -{
  200823. - u16 chanspec;
  200824. - s32 err;
  200825. -
  200826. - brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
  200827. - channel->center_freq);
  200828. -
  200829. - chanspec = channel_to_chanspec(&cfg->d11inf, channel);
  200830. - err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
  200831. -
  200832. - return err;
  200833. -}
  200834. -
  200835. -static s32
  200836. brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
  200837. struct cfg80211_ap_settings *settings)
  200838. {
  200839. s32 ie_offset;
  200840. struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
  200841. struct brcmf_if *ifp = netdev_priv(ndev);
  200842. - struct brcmf_tlv *ssid_ie;
  200843. + const struct brcmf_tlv *ssid_ie;
  200844. struct brcmf_ssid_le ssid_le;
  200845. s32 err = -EPERM;
  200846. - struct brcmf_tlv *rsn_ie;
  200847. - struct brcmf_vs_tlv *wpa_ie;
  200848. + const struct brcmf_tlv *rsn_ie;
  200849. + const struct brcmf_vs_tlv *wpa_ie;
  200850. struct brcmf_join_params join_params;
  200851. enum nl80211_iftype dev_role;
  200852. struct brcmf_fil_bss_enable_le bss_enable;
  200853. + u16 chanspec;
  200854. - brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
  200855. - cfg80211_get_chandef_type(&settings->chandef),
  200856. - settings->beacon_interval,
  200857. - settings->dtim_period);
  200858. + brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
  200859. + settings->chandef.chan->hw_value,
  200860. + settings->chandef.center_freq1, settings->chandef.width,
  200861. + settings->beacon_interval, settings->dtim_period);
  200862. brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
  200863. settings->ssid, settings->ssid_len, settings->auth_type,
  200864. settings->inactivity_timeout);
  200865. @@ -3776,9 +3866,10 @@
  200866. brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
  200867. - err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan);
  200868. + chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
  200869. + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
  200870. if (err < 0) {
  200871. - brcmf_err("Set Channel failed, %d\n", err);
  200872. + brcmf_err("Set Channel failed: chspec=%d, %d\n", chanspec, err);
  200873. goto exit;
  200874. }
  200875. @@ -4220,32 +4311,6 @@
  200876. CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
  200877. };
  200878. -static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
  200879. -{
  200880. - switch (type) {
  200881. - case NL80211_IFTYPE_AP_VLAN:
  200882. - case NL80211_IFTYPE_WDS:
  200883. - case NL80211_IFTYPE_MONITOR:
  200884. - case NL80211_IFTYPE_MESH_POINT:
  200885. - return -ENOTSUPP;
  200886. - case NL80211_IFTYPE_ADHOC:
  200887. - return WL_MODE_IBSS;
  200888. - case NL80211_IFTYPE_STATION:
  200889. - case NL80211_IFTYPE_P2P_CLIENT:
  200890. - return WL_MODE_BSS;
  200891. - case NL80211_IFTYPE_AP:
  200892. - case NL80211_IFTYPE_P2P_GO:
  200893. - return WL_MODE_AP;
  200894. - case NL80211_IFTYPE_P2P_DEVICE:
  200895. - return WL_MODE_P2P;
  200896. - case NL80211_IFTYPE_UNSPECIFIED:
  200897. - default:
  200898. - break;
  200899. - }
  200900. -
  200901. - return -EINVAL;
  200902. -}
  200903. -
  200904. static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
  200905. {
  200906. /* scheduled scan settings */
  200907. @@ -4340,6 +4405,8 @@
  200908. WIPHY_FLAG_OFFCHAN_TX |
  200909. WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
  200910. WIPHY_FLAG_SUPPORTS_TDLS;
  200911. + if (!brcmf_roamoff)
  200912. + wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
  200913. wiphy->mgmt_stypes = brcmf_txrx_stypes;
  200914. wiphy->max_remain_on_channel_duration = 5000;
  200915. brcmf_wiphy_pno_params(wiphy);
  200916. @@ -4370,7 +4437,6 @@
  200917. vif->wdev.wiphy = cfg->wiphy;
  200918. vif->wdev.iftype = type;
  200919. - vif->mode = brcmf_nl80211_iftype_to_mode(type);
  200920. vif->pm_block = pm_block;
  200921. vif->roam_off = -1;
  200922. @@ -4416,7 +4482,9 @@
  200923. u32 event = e->event_code;
  200924. u16 flags = e->flags;
  200925. - if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
  200926. + if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
  200927. + (event == BRCMF_E_DISASSOC_IND) ||
  200928. + ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
  200929. brcmf_dbg(CONN, "Processing link down\n");
  200930. return true;
  200931. }
  200932. @@ -4658,16 +4726,18 @@
  200933. struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
  200934. struct net_device *ndev = ifp->ndev;
  200935. struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
  200936. + struct ieee80211_channel *chan;
  200937. s32 err = 0;
  200938. - if (ifp->vif->mode == WL_MODE_AP) {
  200939. + if (brcmf_is_apmode(ifp->vif)) {
  200940. err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
  200941. } else if (brcmf_is_linkup(e)) {
  200942. brcmf_dbg(CONN, "Linkup\n");
  200943. if (brcmf_is_ibssmode(ifp->vif)) {
  200944. + chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
  200945. memcpy(profile->bssid, e->addr, ETH_ALEN);
  200946. wl_inform_ibss(cfg, ndev, e->addr);
  200947. - cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
  200948. + cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
  200949. clear_bit(BRCMF_VIF_STATUS_CONNECTING,
  200950. &ifp->vif->sme_state);
  200951. set_bit(BRCMF_VIF_STATUS_CONNECTED,
  200952. @@ -4678,10 +4748,6 @@
  200953. brcmf_dbg(CONN, "Linkdown\n");
  200954. if (!brcmf_is_ibssmode(ifp->vif)) {
  200955. brcmf_bss_connect_done(cfg, ndev, e, false);
  200956. - if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
  200957. - &ifp->vif->sme_state))
  200958. - cfg80211_disconnected(ndev, 0, NULL, 0,
  200959. - GFP_KERNEL);
  200960. }
  200961. brcmf_link_down(ifp->vif);
  200962. brcmf_init_prof(ndev_to_prof(ndev));
  200963. @@ -4875,11 +4941,8 @@
  200964. cfg->scan_request = NULL;
  200965. cfg->pwr_save = true;
  200966. - cfg->roam_on = true; /* roam on & off switch.
  200967. - we enable roam per default */
  200968. - cfg->active_scan = true; /* we do active scan for
  200969. - specific scan per default */
  200970. - cfg->dongle_up = false; /* dongle is not up yet */
  200971. + cfg->active_scan = true; /* we do active scan per default */
  200972. + cfg->dongle_up = false; /* dongle is not up yet */
  200973. err = brcmf_init_priv_mem(cfg);
  200974. if (err)
  200975. return err;
  200976. @@ -4904,6 +4967,30 @@
  200977. mutex_init(&event->vif_event_lock);
  200978. }
  200979. +static int brcmf_enable_bw40_2g(struct brcmf_if *ifp)
  200980. +{
  200981. + struct brcmf_fil_bwcap_le band_bwcap;
  200982. + u32 val;
  200983. + int err;
  200984. +
  200985. + /* verify support for bw_cap command */
  200986. + val = WLC_BAND_5G;
  200987. + err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
  200988. +
  200989. + if (!err) {
  200990. + /* only set 2G bandwidth using bw_cap command */
  200991. + band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
  200992. + band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
  200993. + err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
  200994. + sizeof(band_bwcap));
  200995. + } else {
  200996. + brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
  200997. + val = WLC_N_BW_40ALL;
  200998. + err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
  200999. + }
  201000. + return err;
  201001. +}
  201002. +
  201003. struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
  201004. struct device *busdev)
  201005. {
  201006. @@ -4961,6 +5048,17 @@
  201007. goto cfg80211_p2p_attach_out;
  201008. }
  201009. + /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
  201010. + * setup 40MHz in 2GHz band and enable OBSS scanning.
  201011. + */
  201012. + if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap &
  201013. + IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
  201014. + err = brcmf_enable_bw40_2g(ifp);
  201015. + if (!err)
  201016. + err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
  201017. + BRCMF_OBSS_COEX_AUTO);
  201018. + }
  201019. +
  201020. err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
  201021. if (err) {
  201022. brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
  201023. @@ -4999,7 +5097,7 @@
  201024. }
  201025. static s32
  201026. -brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
  201027. +brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
  201028. {
  201029. s32 err = 0;
  201030. __le32 roamtrigger[2];
  201031. @@ -5009,7 +5107,7 @@
  201032. * Setup timeout if Beacons are lost and roam is
  201033. * off to report link down
  201034. */
  201035. - if (roamvar) {
  201036. + if (brcmf_roamoff) {
  201037. err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
  201038. if (err) {
  201039. brcmf_err("bcn_timeout error (%d)\n", err);
  201040. @@ -5021,8 +5119,9 @@
  201041. * Enable/Disable built-in roaming to allow supplicant
  201042. * to take care of roaming
  201043. */
  201044. - brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
  201045. - err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
  201046. + brcmf_dbg(INFO, "Internal Roaming = %s\n",
  201047. + brcmf_roamoff ? "Off" : "On");
  201048. + err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
  201049. if (err) {
  201050. brcmf_err("roam_off error (%d)\n", err);
  201051. goto dongle_rom_out;
  201052. @@ -5148,6 +5247,9 @@
  201053. if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
  201054. ch.bw == BRCMU_CHAN_BW_40)
  201055. continue;
  201056. + if (!(bw_cap[band] & WLC_BW_80MHZ_BIT) &&
  201057. + ch.bw == BRCMU_CHAN_BW_80)
  201058. + continue;
  201059. update = false;
  201060. for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
  201061. if (band_chan_arr[j].hw_value == ch.chnum) {
  201062. @@ -5164,13 +5266,13 @@
  201063. ieee80211_channel_to_frequency(ch.chnum, band);
  201064. band_chan_arr[index].hw_value = ch.chnum;
  201065. - brcmf_err("channel %d: f=%d bw=%d sb=%d\n",
  201066. - ch.chnum, band_chan_arr[index].center_freq,
  201067. - ch.bw, ch.sb);
  201068. - if (ch.bw == BRCMU_CHAN_BW_40) {
  201069. - /* assuming the order is HT20, HT40 Upper,
  201070. - * HT40 lower from chanspecs
  201071. - */
  201072. + /* assuming the chanspecs order is HT20,
  201073. + * HT40 upper, HT40 lower, and VHT80.
  201074. + */
  201075. + if (ch.bw == BRCMU_CHAN_BW_80) {
  201076. + band_chan_arr[index].flags &=
  201077. + ~IEEE80211_CHAN_NO_80MHZ;
  201078. + } else if (ch.bw == BRCMU_CHAN_BW_40) {
  201079. ht40_flag = band_chan_arr[index].flags &
  201080. IEEE80211_CHAN_NO_HT40;
  201081. if (ch.sb == BRCMU_CHAN_SB_U) {
  201082. @@ -5191,8 +5293,13 @@
  201083. IEEE80211_CHAN_NO_HT40MINUS;
  201084. }
  201085. } else {
  201086. + /* disable other bandwidths for now as mentioned
  201087. + * order assure they are enabled for subsequent
  201088. + * chanspecs.
  201089. + */
  201090. band_chan_arr[index].flags =
  201091. - IEEE80211_CHAN_NO_HT40;
  201092. + IEEE80211_CHAN_NO_HT40 |
  201093. + IEEE80211_CHAN_NO_80MHZ;
  201094. ch.bw = BRCMU_CHAN_BW_20;
  201095. cfg->d11inf.encchspec(&ch);
  201096. channel = ch.chspec;
  201097. @@ -5259,14 +5366,66 @@
  201098. }
  201099. }
  201100. +static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
  201101. + u32 bw_cap[2], u32 nchain)
  201102. +{
  201103. + band->ht_cap.ht_supported = true;
  201104. + if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
  201105. + band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
  201106. + band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
  201107. + }
  201108. + band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
  201109. + band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
  201110. + band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
  201111. + band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
  201112. + memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
  201113. + band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
  201114. +}
  201115. +
  201116. +static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
  201117. +{
  201118. + u16 mcs_map;
  201119. + int i;
  201120. +
  201121. + for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
  201122. + mcs_map = (mcs_map << 2) | supp;
  201123. +
  201124. + return cpu_to_le16(mcs_map);
  201125. +}
  201126. +
  201127. +static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
  201128. + u32 bw_cap[2], u32 nchain)
  201129. +{
  201130. + __le16 mcs_map;
  201131. +
  201132. + /* not allowed in 2.4G band */
  201133. + if (band->band == IEEE80211_BAND_2GHZ)
  201134. + return;
  201135. +
  201136. + band->vht_cap.vht_supported = true;
  201137. + /* 80MHz is mandatory */
  201138. + band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
  201139. + if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
  201140. + band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
  201141. + band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
  201142. + }
  201143. + /* all support 256-QAM */
  201144. + mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
  201145. + band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
  201146. + band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
  201147. +}
  201148. +
  201149. static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
  201150. {
  201151. struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
  201152. struct wiphy *wiphy;
  201153. s32 phy_list;
  201154. u32 band_list[3];
  201155. - u32 nmode;
  201156. + u32 nmode = 0;
  201157. + u32 vhtmode = 0;
  201158. u32 bw_cap[2] = { 0, 0 };
  201159. + u32 rxchain;
  201160. + u32 nchain;
  201161. s8 phy;
  201162. s32 err;
  201163. u32 nband;
  201164. @@ -5294,14 +5453,26 @@
  201165. brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
  201166. band_list[0], band_list[1], band_list[2]);
  201167. + (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
  201168. err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
  201169. if (err) {
  201170. brcmf_err("nmode error (%d)\n", err);
  201171. } else {
  201172. brcmf_get_bwcap(ifp, bw_cap);
  201173. }
  201174. - brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode,
  201175. - bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]);
  201176. + brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
  201177. + nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
  201178. + bw_cap[IEEE80211_BAND_5GHZ]);
  201179. +
  201180. + err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
  201181. + if (err) {
  201182. + brcmf_err("rxchain error (%d)\n", err);
  201183. + nchain = 1;
  201184. + } else {
  201185. + for (nchain = 0; rxchain; nchain++)
  201186. + rxchain = rxchain & (rxchain - 1);
  201187. + }
  201188. + brcmf_dbg(INFO, "nchain=%d\n", nchain);
  201189. err = brcmf_construct_reginfo(cfg, bw_cap);
  201190. if (err) {
  201191. @@ -5322,20 +5493,10 @@
  201192. else
  201193. continue;
  201194. - if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
  201195. - band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
  201196. - band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
  201197. - }
  201198. - band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
  201199. - band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
  201200. - band->ht_cap.ht_supported = true;
  201201. - band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
  201202. - band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
  201203. - /* An HT shall support all EQM rates for one spatial
  201204. - * stream
  201205. - */
  201206. - band->ht_cap.mcs.rx_mask[0] = 0xff;
  201207. - band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
  201208. + if (nmode)
  201209. + brcmf_update_ht_cap(band, bw_cap, nchain);
  201210. + if (vhtmode)
  201211. + brcmf_update_vht_cap(band, bw_cap, nchain);
  201212. bands[band->band] = band;
  201213. }
  201214. @@ -5381,7 +5542,7 @@
  201215. brcmf_dbg(INFO, "power save set to %s\n",
  201216. (power_mode ? "enabled" : "disabled"));
  201217. - err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
  201218. + err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
  201219. if (err)
  201220. goto default_conf_out;
  201221. err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
  201222. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
  201223. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h 2014-07-28 10:07:25.000000000 -0500
  201224. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h 2014-12-08 00:31:53.844418001 -0600
  201225. @@ -89,21 +89,6 @@
  201226. BRCMF_SCAN_STATUS_SUPPRESS,
  201227. };
  201228. -/**
  201229. - * enum wl_mode - driver mode of virtual interface.
  201230. - *
  201231. - * @WL_MODE_BSS: connects to BSS.
  201232. - * @WL_MODE_IBSS: operate as ad-hoc.
  201233. - * @WL_MODE_AP: operate as access-point.
  201234. - * @WL_MODE_P2P: provide P2P discovery.
  201235. - */
  201236. -enum wl_mode {
  201237. - WL_MODE_BSS,
  201238. - WL_MODE_IBSS,
  201239. - WL_MODE_AP,
  201240. - WL_MODE_P2P
  201241. -};
  201242. -
  201243. /* dongle configuration */
  201244. struct brcmf_cfg80211_conf {
  201245. u32 frag_threshold;
  201246. @@ -193,7 +178,6 @@
  201247. * @ifp: lower layer interface pointer
  201248. * @wdev: wireless device.
  201249. * @profile: profile information.
  201250. - * @mode: operating mode.
  201251. * @roam_off: roaming state.
  201252. * @sme_state: SME state using enum brcmf_vif_status bits.
  201253. * @pm_block: power-management blocked.
  201254. @@ -204,7 +188,6 @@
  201255. struct brcmf_if *ifp;
  201256. struct wireless_dev wdev;
  201257. struct brcmf_cfg80211_profile profile;
  201258. - s32 mode;
  201259. s32 roam_off;
  201260. unsigned long sme_state;
  201261. bool pm_block;
  201262. @@ -402,7 +385,6 @@
  201263. bool ibss_starter;
  201264. bool pwr_save;
  201265. bool dongle_up;
  201266. - bool roam_on;
  201267. bool scan_tried;
  201268. u8 *dcmd_buf;
  201269. u8 *extra_buf;
  201270. @@ -491,7 +473,8 @@
  201271. s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
  201272. const u8 *vndr_ie_buf, u32 vndr_ie_len);
  201273. s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif);
  201274. -struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key);
  201275. +const struct brcmf_tlv *
  201276. +brcmf_parse_tlvs(const void *buf, int buflen, uint key);
  201277. u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
  201278. struct ieee80211_channel *ch);
  201279. u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state);
  201280. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
  201281. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c 2014-07-28 10:07:25.000000000 -0500
  201282. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c 2014-12-08 00:31:53.848418001 -0600
  201283. @@ -897,7 +897,8 @@
  201284. return result;
  201285. }
  201286. -static void brcms_ops_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201287. +static void brcms_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201288. + u32 queues, bool drop)
  201289. {
  201290. struct brcms_info *wl = hw->priv;
  201291. int ret;
  201292. @@ -1092,12 +1093,6 @@
  201293. * Attach to the WL device identified by vendor and device parameters.
  201294. * regs is a host accessible memory address pointing to WL device registers.
  201295. *
  201296. - * brcms_attach is not defined as static because in the case where no bus
  201297. - * is defined, wl_attach will never be called, and thus, gcc will issue
  201298. - * a warning that this function is defined but not used if we declare
  201299. - * it as static.
  201300. - *
  201301. - *
  201302. * is called in brcms_bcma_probe() context, therefore no locking required.
  201303. */
  201304. static struct brcms_info *brcms_attach(struct bcma_device *pdev)
  201305. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmsmac/main.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmsmac/main.c
  201306. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmsmac/main.c 2014-07-28 10:07:25.000000000 -0500
  201307. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmsmac/main.c 2014-12-08 00:31:53.848418001 -0600
  201308. @@ -4870,14 +4870,11 @@
  201309. /*
  201310. * low level detach
  201311. */
  201312. -static int brcms_b_detach(struct brcms_c_info *wlc)
  201313. +static void brcms_b_detach(struct brcms_c_info *wlc)
  201314. {
  201315. uint i;
  201316. struct brcms_hw_band *band;
  201317. struct brcms_hardware *wlc_hw = wlc->hw;
  201318. - int callbacks;
  201319. -
  201320. - callbacks = 0;
  201321. brcms_b_detach_dmapio(wlc_hw);
  201322. @@ -4900,9 +4897,6 @@
  201323. ai_detach(wlc_hw->sih);
  201324. wlc_hw->sih = NULL;
  201325. }
  201326. -
  201327. - return callbacks;
  201328. -
  201329. }
  201330. /*
  201331. @@ -4917,14 +4911,15 @@
  201332. */
  201333. uint brcms_c_detach(struct brcms_c_info *wlc)
  201334. {
  201335. - uint callbacks = 0;
  201336. + uint callbacks;
  201337. if (wlc == NULL)
  201338. return 0;
  201339. - callbacks += brcms_b_detach(wlc);
  201340. + brcms_b_detach(wlc);
  201341. /* delete software timers */
  201342. + callbacks = 0;
  201343. if (!brcms_c_radio_monitor_stop(wlc))
  201344. callbacks++;
  201345. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/brcmutil/d11.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmutil/d11.c
  201346. --- linux-3.14.14/drivers/net/wireless/brcm80211/brcmutil/d11.c 2014-07-28 10:07:25.000000000 -0500
  201347. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmutil/d11.c 2014-12-08 00:31:53.860418001 -0600
  201348. @@ -21,19 +21,46 @@
  201349. #include <brcmu_wifi.h>
  201350. #include <brcmu_d11.h>
  201351. -static void brcmu_d11n_encchspec(struct brcmu_chan *ch)
  201352. +static u16 d11n_sb(enum brcmu_chan_sb sb)
  201353. {
  201354. - ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK;
  201355. + switch (sb) {
  201356. + case BRCMU_CHAN_SB_NONE:
  201357. + return BRCMU_CHSPEC_D11N_SB_N;
  201358. + case BRCMU_CHAN_SB_L:
  201359. + return BRCMU_CHSPEC_D11N_SB_L;
  201360. + case BRCMU_CHAN_SB_U:
  201361. + return BRCMU_CHSPEC_D11N_SB_U;
  201362. + default:
  201363. + WARN_ON(1);
  201364. + }
  201365. + return 0;
  201366. +}
  201367. - switch (ch->bw) {
  201368. +static u16 d11n_bw(enum brcmu_chan_bw bw)
  201369. +{
  201370. + switch (bw) {
  201371. case BRCMU_CHAN_BW_20:
  201372. - ch->chspec |= BRCMU_CHSPEC_D11N_BW_20 | BRCMU_CHSPEC_D11N_SB_N;
  201373. - break;
  201374. + return BRCMU_CHSPEC_D11N_BW_20;
  201375. case BRCMU_CHAN_BW_40:
  201376. + return BRCMU_CHSPEC_D11N_BW_40;
  201377. default:
  201378. - WARN_ON_ONCE(1);
  201379. - break;
  201380. + WARN_ON(1);
  201381. }
  201382. + return 0;
  201383. +}
  201384. +
  201385. +static void brcmu_d11n_encchspec(struct brcmu_chan *ch)
  201386. +{
  201387. + if (ch->bw == BRCMU_CHAN_BW_20)
  201388. + ch->sb = BRCMU_CHAN_SB_NONE;
  201389. +
  201390. + ch->chspec = 0;
  201391. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,
  201392. + BRCMU_CHSPEC_CH_SHIFT, ch->chnum);
  201393. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_SB_MASK,
  201394. + 0, d11n_sb(ch->sb));
  201395. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_BW_MASK,
  201396. + 0, d11n_bw(ch->bw));
  201397. if (ch->chnum <= CH_MAX_2G_CHANNEL)
  201398. ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G;
  201399. @@ -41,23 +68,34 @@
  201400. ch->chspec |= BRCMU_CHSPEC_D11N_BND_5G;
  201401. }
  201402. -static void brcmu_d11ac_encchspec(struct brcmu_chan *ch)
  201403. +static u16 d11ac_bw(enum brcmu_chan_bw bw)
  201404. {
  201405. - ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK;
  201406. -
  201407. - switch (ch->bw) {
  201408. + switch (bw) {
  201409. case BRCMU_CHAN_BW_20:
  201410. - ch->chspec |= BRCMU_CHSPEC_D11AC_BW_20;
  201411. - break;
  201412. + return BRCMU_CHSPEC_D11AC_BW_20;
  201413. case BRCMU_CHAN_BW_40:
  201414. + return BRCMU_CHSPEC_D11AC_BW_40;
  201415. case BRCMU_CHAN_BW_80:
  201416. - case BRCMU_CHAN_BW_80P80:
  201417. - case BRCMU_CHAN_BW_160:
  201418. + return BRCMU_CHSPEC_D11AC_BW_80;
  201419. default:
  201420. - WARN_ON_ONCE(1);
  201421. - break;
  201422. + WARN_ON(1);
  201423. }
  201424. + return 0;
  201425. +}
  201426. +static void brcmu_d11ac_encchspec(struct brcmu_chan *ch)
  201427. +{
  201428. + if (ch->bw == BRCMU_CHAN_BW_20 || ch->sb == BRCMU_CHAN_SB_NONE)
  201429. + ch->sb = BRCMU_CHAN_SB_L;
  201430. +
  201431. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,
  201432. + BRCMU_CHSPEC_CH_SHIFT, ch->chnum);
  201433. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,
  201434. + BRCMU_CHSPEC_D11AC_SB_SHIFT, ch->sb);
  201435. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_BW_MASK,
  201436. + 0, d11ac_bw(ch->bw));
  201437. +
  201438. + ch->chspec &= ~BRCMU_CHSPEC_D11AC_BND_MASK;
  201439. if (ch->chnum <= CH_MAX_2G_CHANNEL)
  201440. ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G;
  201441. else
  201442. @@ -73,6 +111,7 @@
  201443. switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) {
  201444. case BRCMU_CHSPEC_D11N_BW_20:
  201445. ch->bw = BRCMU_CHAN_BW_20;
  201446. + ch->sb = BRCMU_CHAN_SB_NONE;
  201447. break;
  201448. case BRCMU_CHSPEC_D11N_BW_40:
  201449. ch->bw = BRCMU_CHAN_BW_40;
  201450. @@ -112,6 +151,7 @@
  201451. switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) {
  201452. case BRCMU_CHSPEC_D11AC_BW_20:
  201453. ch->bw = BRCMU_CHAN_BW_20;
  201454. + ch->sb = BRCMU_CHAN_SB_NONE;
  201455. break;
  201456. case BRCMU_CHSPEC_D11AC_BW_40:
  201457. ch->bw = BRCMU_CHAN_BW_40;
  201458. @@ -128,6 +168,25 @@
  201459. break;
  201460. case BRCMU_CHSPEC_D11AC_BW_80:
  201461. ch->bw = BRCMU_CHAN_BW_80;
  201462. + ch->sb = brcmu_maskget16(ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,
  201463. + BRCMU_CHSPEC_D11AC_SB_SHIFT);
  201464. + switch (ch->sb) {
  201465. + case BRCMU_CHAN_SB_LL:
  201466. + ch->chnum -= CH_30MHZ_APART;
  201467. + break;
  201468. + case BRCMU_CHAN_SB_LU:
  201469. + ch->chnum -= CH_10MHZ_APART;
  201470. + break;
  201471. + case BRCMU_CHAN_SB_UL:
  201472. + ch->chnum += CH_10MHZ_APART;
  201473. + break;
  201474. + case BRCMU_CHAN_SB_UU:
  201475. + ch->chnum += CH_30MHZ_APART;
  201476. + break;
  201477. + default:
  201478. + WARN_ON_ONCE(1);
  201479. + break;
  201480. + }
  201481. break;
  201482. case BRCMU_CHSPEC_D11AC_BW_8080:
  201483. case BRCMU_CHSPEC_D11AC_BW_160:
  201484. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
  201485. --- linux-3.14.14/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h 2014-07-28 10:07:25.000000000 -0500
  201486. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h 2014-12-08 00:31:53.860418001 -0600
  201487. @@ -43,5 +43,6 @@
  201488. #define BCM4335_CHIP_ID 0x4335
  201489. #define BCM43362_CHIP_ID 43362
  201490. #define BCM4339_CHIP_ID 0x4339
  201491. +#define BCM4354_CHIP_ID 0x4354
  201492. #endif /* _BRCM_HW_IDS_H_ */
  201493. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/include/brcmu_d11.h linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcmu_d11.h
  201494. --- linux-3.14.14/drivers/net/wireless/brcm80211/include/brcmu_d11.h 2014-07-28 10:07:25.000000000 -0500
  201495. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcmu_d11.h 2014-12-08 00:31:53.860418001 -0600
  201496. @@ -108,13 +108,7 @@
  201497. };
  201498. enum brcmu_chan_sb {
  201499. - BRCMU_CHAN_SB_NONE = 0,
  201500. - BRCMU_CHAN_SB_L,
  201501. - BRCMU_CHAN_SB_U,
  201502. - BRCMU_CHAN_SB_LL,
  201503. - BRCMU_CHAN_SB_LU,
  201504. - BRCMU_CHAN_SB_UL,
  201505. - BRCMU_CHAN_SB_UU,
  201506. + BRCMU_CHAN_SB_NONE = -1,
  201507. BRCMU_CHAN_SB_LLL,
  201508. BRCMU_CHAN_SB_LLU,
  201509. BRCMU_CHAN_SB_LUL,
  201510. @@ -123,6 +117,12 @@
  201511. BRCMU_CHAN_SB_ULU,
  201512. BRCMU_CHAN_SB_UUL,
  201513. BRCMU_CHAN_SB_UUU,
  201514. + BRCMU_CHAN_SB_L = BRCMU_CHAN_SB_LLL,
  201515. + BRCMU_CHAN_SB_U = BRCMU_CHAN_SB_LLU,
  201516. + BRCMU_CHAN_SB_LL = BRCMU_CHAN_SB_LLL,
  201517. + BRCMU_CHAN_SB_LU = BRCMU_CHAN_SB_LLU,
  201518. + BRCMU_CHAN_SB_UL = BRCMU_CHAN_SB_LUL,
  201519. + BRCMU_CHAN_SB_UU = BRCMU_CHAN_SB_LUU,
  201520. };
  201521. struct brcmu_chan {
  201522. diff -Nur linux-3.14.14/drivers/net/wireless/brcm80211/include/brcmu_wifi.h linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
  201523. --- linux-3.14.14/drivers/net/wireless/brcm80211/include/brcmu_wifi.h 2014-07-28 10:07:25.000000000 -0500
  201524. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcmu_wifi.h 2014-12-08 00:31:53.860418001 -0600
  201525. @@ -29,6 +29,7 @@
  201526. #define CH_UPPER_SB 0x01
  201527. #define CH_LOWER_SB 0x02
  201528. #define CH_EWA_VALID 0x04
  201529. +#define CH_30MHZ_APART 6
  201530. #define CH_20MHZ_APART 4
  201531. #define CH_10MHZ_APART 2
  201532. #define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
  201533. @@ -217,6 +218,9 @@
  201534. #define WSEC_SWFLAG 0x0008
  201535. /* to go into transition mode without setting wep */
  201536. #define SES_OW_ENABLED 0x0040
  201537. +/* MFP */
  201538. +#define MFP_CAPABLE 0x0200
  201539. +#define MFP_REQUIRED 0x0400
  201540. /* WPA authentication mode bitvec */
  201541. #define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */
  201542. diff -Nur linux-3.14.14/drivers/net/wireless/cw1200/sta.c linux-imx6-3.14/drivers/net/wireless/cw1200/sta.c
  201543. --- linux-3.14.14/drivers/net/wireless/cw1200/sta.c 2014-07-28 10:07:25.000000000 -0500
  201544. +++ linux-imx6-3.14/drivers/net/wireless/cw1200/sta.c 2014-12-08 00:31:53.860418001 -0600
  201545. @@ -936,7 +936,8 @@
  201546. return ret;
  201547. }
  201548. -void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201549. +void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201550. + u32 queues, bool drop)
  201551. {
  201552. struct cw1200_common *priv = hw->priv;
  201553. diff -Nur linux-3.14.14/drivers/net/wireless/cw1200/sta.h linux-imx6-3.14/drivers/net/wireless/cw1200/sta.h
  201554. --- linux-3.14.14/drivers/net/wireless/cw1200/sta.h 2014-07-28 10:07:25.000000000 -0500
  201555. +++ linux-imx6-3.14/drivers/net/wireless/cw1200/sta.h 2014-12-08 00:31:53.860418001 -0600
  201556. @@ -40,7 +40,8 @@
  201557. int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
  201558. -void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
  201559. +void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201560. + u32 queues, bool drop);
  201561. u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
  201562. struct netdev_hw_addr_list *mc_list);
  201563. diff -Nur linux-3.14.14/drivers/net/wireless/iwlegacy/common.c linux-imx6-3.14/drivers/net/wireless/iwlegacy/common.c
  201564. --- linux-3.14.14/drivers/net/wireless/iwlegacy/common.c 2014-07-28 10:07:25.000000000 -0500
  201565. +++ linux-imx6-3.14/drivers/net/wireless/iwlegacy/common.c 2014-12-08 00:31:53.876418001 -0600
  201566. @@ -4701,7 +4701,8 @@
  201567. }
  201568. EXPORT_SYMBOL(il_mac_change_interface);
  201569. -void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201570. +void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201571. + u32 queues, bool drop)
  201572. {
  201573. struct il_priv *il = hw->priv;
  201574. unsigned long timeout = jiffies + msecs_to_jiffies(500);
  201575. diff -Nur linux-3.14.14/drivers/net/wireless/iwlegacy/common.h linux-imx6-3.14/drivers/net/wireless/iwlegacy/common.h
  201576. --- linux-3.14.14/drivers/net/wireless/iwlegacy/common.h 2014-07-28 10:07:25.000000000 -0500
  201577. +++ linux-imx6-3.14/drivers/net/wireless/iwlegacy/common.h 2014-12-08 00:31:53.880418001 -0600
  201578. @@ -1722,7 +1722,8 @@
  201579. struct ieee80211_vif *vif);
  201580. int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201581. enum nl80211_iftype newtype, bool newp2p);
  201582. -void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
  201583. +void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201584. + u32 queues, bool drop);
  201585. int il_alloc_txq_mem(struct il_priv *il);
  201586. void il_free_txq_mem(struct il_priv *il);
  201587. diff -Nur linux-3.14.14/drivers/net/wireless/iwlwifi/dvm/mac80211.c linux-imx6-3.14/drivers/net/wireless/iwlwifi/dvm/mac80211.c
  201588. --- linux-3.14.14/drivers/net/wireless/iwlwifi/dvm/mac80211.c 2014-07-28 10:07:25.000000000 -0500
  201589. +++ linux-imx6-3.14/drivers/net/wireless/iwlwifi/dvm/mac80211.c 2014-12-08 00:31:53.880418001 -0600
  201590. @@ -1091,7 +1091,8 @@
  201591. FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
  201592. }
  201593. -static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201594. +static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201595. + u32 queues, bool drop)
  201596. {
  201597. struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
  201598. diff -Nur linux-3.14.14/drivers/net/wireless/libertas/cfg.c linux-imx6-3.14/drivers/net/wireless/libertas/cfg.c
  201599. --- linux-3.14.14/drivers/net/wireless/libertas/cfg.c 2014-07-28 10:07:25.000000000 -0500
  201600. +++ linux-imx6-3.14/drivers/net/wireless/libertas/cfg.c 2014-12-08 00:31:53.900418001 -0600
  201601. @@ -1766,7 +1766,8 @@
  201602. memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
  201603. priv->wdev->ssid_len = params->ssid_len;
  201604. - cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
  201605. + cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan,
  201606. + GFP_KERNEL);
  201607. /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
  201608. priv->connect_status = LBS_CONNECTED;
  201609. diff -Nur linux-3.14.14/drivers/net/wireless/mac80211_hwsim.c linux-imx6-3.14/drivers/net/wireless/mac80211_hwsim.c
  201610. --- linux-3.14.14/drivers/net/wireless/mac80211_hwsim.c 2014-07-28 10:07:25.000000000 -0500
  201611. +++ linux-imx6-3.14/drivers/net/wireless/mac80211_hwsim.c 2014-12-08 00:31:53.904418001 -0600
  201612. @@ -1671,7 +1671,9 @@
  201613. return 0;
  201614. }
  201615. -static void mac80211_hwsim_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201616. +static void mac80211_hwsim_flush(struct ieee80211_hw *hw,
  201617. + struct ieee80211_vif *vif,
  201618. + u32 queues, bool drop)
  201619. {
  201620. /* Not implemented, queues only on kernel side */
  201621. }
  201622. diff -Nur linux-3.14.14/drivers/net/wireless/mwifiex/cfg80211.c linux-imx6-3.14/drivers/net/wireless/mwifiex/cfg80211.c
  201623. --- linux-3.14.14/drivers/net/wireless/mwifiex/cfg80211.c 2014-07-28 10:07:25.000000000 -0500
  201624. +++ linux-imx6-3.14/drivers/net/wireless/mwifiex/cfg80211.c 2014-12-08 00:31:53.904418001 -0600
  201625. @@ -1881,7 +1881,8 @@
  201626. params->privacy);
  201627. done:
  201628. if (!ret) {
  201629. - cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
  201630. + cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
  201631. + params->chandef.chan, GFP_KERNEL);
  201632. dev_dbg(priv->adapter->dev,
  201633. "info: joined/created adhoc network with bssid"
  201634. " %pM successfully\n", priv->cfg_bssid);
  201635. diff -Nur linux-3.14.14/drivers/net/wireless/mwifiex/main.h linux-imx6-3.14/drivers/net/wireless/mwifiex/main.h
  201636. --- linux-3.14.14/drivers/net/wireless/mwifiex/main.h 2014-07-28 10:07:25.000000000 -0500
  201637. +++ linux-imx6-3.14/drivers/net/wireless/mwifiex/main.h 2014-12-08 00:31:53.908418001 -0600
  201638. @@ -1078,7 +1078,7 @@
  201639. const u8 *key, int key_len, u8 key_index,
  201640. const u8 *mac_addr, int disable);
  201641. -int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
  201642. +int mwifiex_set_gen_ie(struct mwifiex_private *priv, const u8 *ie, int ie_len);
  201643. int mwifiex_get_ver_ext(struct mwifiex_private *priv);
  201644. diff -Nur linux-3.14.14/drivers/net/wireless/mwifiex/sta_ioctl.c linux-imx6-3.14/drivers/net/wireless/mwifiex/sta_ioctl.c
  201645. --- linux-3.14.14/drivers/net/wireless/mwifiex/sta_ioctl.c 2014-07-28 10:07:25.000000000 -0500
  201646. +++ linux-imx6-3.14/drivers/net/wireless/mwifiex/sta_ioctl.c 2014-12-08 00:31:53.908418001 -0600
  201647. @@ -1391,7 +1391,7 @@
  201648. * with requisite parameters and calls the IOCTL handler.
  201649. */
  201650. int
  201651. -mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len)
  201652. +mwifiex_set_gen_ie(struct mwifiex_private *priv, const u8 *ie, int ie_len)
  201653. {
  201654. struct mwifiex_ds_misc_gen_ie gen_ie;
  201655. diff -Nur linux-3.14.14/drivers/net/wireless/p54/main.c linux-imx6-3.14/drivers/net/wireless/p54/main.c
  201656. --- linux-3.14.14/drivers/net/wireless/p54/main.c 2014-07-28 10:07:25.000000000 -0500
  201657. +++ linux-imx6-3.14/drivers/net/wireless/p54/main.c 2014-12-08 00:31:53.916418001 -0600
  201658. @@ -669,7 +669,8 @@
  201659. return total;
  201660. }
  201661. -static void p54_flush(struct ieee80211_hw *dev, u32 queues, bool drop)
  201662. +static void p54_flush(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
  201663. + u32 queues, bool drop)
  201664. {
  201665. struct p54_common *priv = dev->priv;
  201666. unsigned int total, i;
  201667. diff -Nur linux-3.14.14/drivers/net/wireless/rndis_wlan.c linux-imx6-3.14/drivers/net/wireless/rndis_wlan.c
  201668. --- linux-3.14.14/drivers/net/wireless/rndis_wlan.c 2014-07-28 10:07:25.000000000 -0500
  201669. +++ linux-imx6-3.14/drivers/net/wireless/rndis_wlan.c 2014-12-08 00:31:53.920418001 -0600
  201670. @@ -2835,7 +2835,9 @@
  201671. bssid, req_ie, req_ie_len,
  201672. resp_ie, resp_ie_len, GFP_KERNEL);
  201673. } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
  201674. - cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
  201675. + cfg80211_ibss_joined(usbdev->net, bssid,
  201676. + get_current_channel(usbdev, NULL),
  201677. + GFP_KERNEL);
  201678. kfree(info);
  201679. diff -Nur linux-3.14.14/drivers/net/wireless/rt2x00/rt2x00.h linux-imx6-3.14/drivers/net/wireless/rt2x00/rt2x00.h
  201680. --- linux-3.14.14/drivers/net/wireless/rt2x00/rt2x00.h 2014-07-28 10:07:25.000000000 -0500
  201681. +++ linux-imx6-3.14/drivers/net/wireless/rt2x00/rt2x00.h 2014-12-08 00:31:53.928418001 -0600
  201682. @@ -1449,7 +1449,8 @@
  201683. struct ieee80211_vif *vif, u16 queue,
  201684. const struct ieee80211_tx_queue_params *params);
  201685. void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
  201686. -void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
  201687. +void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201688. + u32 queues, bool drop);
  201689. int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
  201690. int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
  201691. void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
  201692. diff -Nur linux-3.14.14/drivers/net/wireless/rt2x00/rt2x00mac.c linux-imx6-3.14/drivers/net/wireless/rt2x00/rt2x00mac.c
  201693. --- linux-3.14.14/drivers/net/wireless/rt2x00/rt2x00mac.c 2014-07-28 10:07:25.000000000 -0500
  201694. +++ linux-imx6-3.14/drivers/net/wireless/rt2x00/rt2x00mac.c 2014-12-08 00:31:53.928418001 -0600
  201695. @@ -751,7 +751,8 @@
  201696. }
  201697. EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
  201698. -void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201699. +void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201700. + u32 queues, bool drop)
  201701. {
  201702. struct rt2x00_dev *rt2x00dev = hw->priv;
  201703. struct data_queue *queue;
  201704. diff -Nur linux-3.14.14/drivers/net/wireless/rtl818x/rtl8187/dev.c linux-imx6-3.14/drivers/net/wireless/rtl818x/rtl8187/dev.c
  201705. --- linux-3.14.14/drivers/net/wireless/rtl818x/rtl8187/dev.c 2014-07-28 10:07:25.000000000 -0500
  201706. +++ linux-imx6-3.14/drivers/net/wireless/rtl818x/rtl8187/dev.c 2014-12-08 00:31:53.932418001 -0600
  201707. @@ -1636,10 +1636,10 @@
  201708. err_free_dmabuf:
  201709. kfree(priv->io_dmabuf);
  201710. - err_free_dev:
  201711. - ieee80211_free_hw(dev);
  201712. usb_set_intfdata(intf, NULL);
  201713. usb_put_dev(udev);
  201714. + err_free_dev:
  201715. + ieee80211_free_hw(dev);
  201716. return err;
  201717. }
  201718. diff -Nur linux-3.14.14/drivers/net/wireless/rtlwifi/core.c linux-imx6-3.14/drivers/net/wireless/rtlwifi/core.c
  201719. --- linux-3.14.14/drivers/net/wireless/rtlwifi/core.c 2014-07-28 10:07:25.000000000 -0500
  201720. +++ linux-imx6-3.14/drivers/net/wireless/rtlwifi/core.c 2014-12-08 00:31:53.936418001 -0600
  201721. @@ -1309,7 +1309,8 @@
  201722. * before switch channel or power save, or tx buffer packet
  201723. * maybe send after offchannel or rf sleep, this may cause
  201724. * dis-association by AP */
  201725. -static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201726. +static void rtl_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201727. + u32 queues, bool drop)
  201728. {
  201729. struct rtl_priv *rtlpriv = rtl_priv(hw);
  201730. diff -Nur linux-3.14.14/drivers/net/wireless/ti/wlcore/main.c linux-imx6-3.14/drivers/net/wireless/ti/wlcore/main.c
  201731. --- linux-3.14.14/drivers/net/wireless/ti/wlcore/main.c 2014-07-28 10:07:25.000000000 -0500
  201732. +++ linux-imx6-3.14/drivers/net/wireless/ti/wlcore/main.c 2014-12-08 00:31:53.964418001 -0600
  201733. @@ -5156,7 +5156,8 @@
  201734. mutex_unlock(&wl->mutex);
  201735. }
  201736. -static void wlcore_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  201737. +static void wlcore_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  201738. + u32 queues, bool drop)
  201739. {
  201740. struct wl1271 *wl = hw->priv;
  201741. diff -Nur linux-3.14.14/drivers/pci/host/Kconfig linux-imx6-3.14/drivers/pci/host/Kconfig
  201742. --- linux-3.14.14/drivers/pci/host/Kconfig 2014-07-28 10:07:25.000000000 -0500
  201743. +++ linux-imx6-3.14/drivers/pci/host/Kconfig 2014-12-08 00:31:53.984418001 -0600
  201744. @@ -21,6 +21,23 @@
  201745. select PCIEPORTBUS
  201746. select PCIE_DW
  201747. +config EP_MODE_IN_EP_RC_SYS
  201748. + bool "PCI Express EP mode in the IMX6 RC/EP interconnection system"
  201749. + depends on PCI_IMX6
  201750. +
  201751. +config EP_SELF_IO_TEST
  201752. + bool "PCI Express EP_SELF_IO_TEST in EP mode"
  201753. + depends on EP_MODE_IN_EP_RC_SYS
  201754. +
  201755. +config RC_MODE_IN_EP_RC_SYS
  201756. + bool "PCI Express RC mode in the IMX6 RC/EP interconnection system"
  201757. + depends on PCI_IMX6
  201758. +
  201759. +config PCI_IMX_EP_DRV
  201760. + bool "i.MX6 PCI Express EP skeleton driver"
  201761. + depends on RC_MODE_IN_EP_RC_SYS
  201762. + default y
  201763. +
  201764. config PCI_TEGRA
  201765. bool "NVIDIA Tegra PCIe controller"
  201766. depends on ARCH_TEGRA
  201767. diff -Nur linux-3.14.14/drivers/pci/host/Makefile linux-imx6-3.14/drivers/pci/host/Makefile
  201768. --- linux-3.14.14/drivers/pci/host/Makefile 2014-07-28 10:07:25.000000000 -0500
  201769. +++ linux-imx6-3.14/drivers/pci/host/Makefile 2014-12-08 00:31:53.984418001 -0600
  201770. @@ -1,6 +1,7 @@
  201771. obj-$(CONFIG_PCIE_DW) += pcie-designware.o
  201772. obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
  201773. obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
  201774. +obj-$(CONFIG_PCI_IMX_EP_DRV) += pci-imx6-ep-driver.o
  201775. obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
  201776. obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
  201777. obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
  201778. diff -Nur linux-3.14.14/drivers/pci/host/pcie-designware.c linux-imx6-3.14/drivers/pci/host/pcie-designware.c
  201779. --- linux-3.14.14/drivers/pci/host/pcie-designware.c 2014-07-28 10:07:25.000000000 -0500
  201780. +++ linux-imx6-3.14/drivers/pci/host/pcie-designware.c 2014-12-08 00:31:53.984418001 -0600
  201781. @@ -23,48 +23,6 @@
  201782. #include "pcie-designware.h"
  201783. -/* Synopsis specific PCIE configuration registers */
  201784. -#define PCIE_PORT_LINK_CONTROL 0x710
  201785. -#define PORT_LINK_MODE_MASK (0x3f << 16)
  201786. -#define PORT_LINK_MODE_1_LANES (0x1 << 16)
  201787. -#define PORT_LINK_MODE_2_LANES (0x3 << 16)
  201788. -#define PORT_LINK_MODE_4_LANES (0x7 << 16)
  201789. -
  201790. -#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
  201791. -#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
  201792. -#define PORT_LOGIC_LINK_WIDTH_MASK (0x1ff << 8)
  201793. -#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
  201794. -#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
  201795. -#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
  201796. -
  201797. -#define PCIE_MSI_ADDR_LO 0x820
  201798. -#define PCIE_MSI_ADDR_HI 0x824
  201799. -#define PCIE_MSI_INTR0_ENABLE 0x828
  201800. -#define PCIE_MSI_INTR0_MASK 0x82C
  201801. -#define PCIE_MSI_INTR0_STATUS 0x830
  201802. -
  201803. -#define PCIE_ATU_VIEWPORT 0x900
  201804. -#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
  201805. -#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
  201806. -#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
  201807. -#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
  201808. -#define PCIE_ATU_CR1 0x904
  201809. -#define PCIE_ATU_TYPE_MEM (0x0 << 0)
  201810. -#define PCIE_ATU_TYPE_IO (0x2 << 0)
  201811. -#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
  201812. -#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
  201813. -#define PCIE_ATU_CR2 0x908
  201814. -#define PCIE_ATU_ENABLE (0x1 << 31)
  201815. -#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
  201816. -#define PCIE_ATU_LOWER_BASE 0x90C
  201817. -#define PCIE_ATU_UPPER_BASE 0x910
  201818. -#define PCIE_ATU_LIMIT 0x914
  201819. -#define PCIE_ATU_LOWER_TARGET 0x918
  201820. -#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
  201821. -#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
  201822. -#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
  201823. -#define PCIE_ATU_UPPER_TARGET 0x91C
  201824. -
  201825. static struct hw_pci dw_pci;
  201826. static unsigned long global_io_offset;
  201827. @@ -332,23 +290,28 @@
  201828. return -EINVAL;
  201829. }
  201830. - pci_read_config_word(pdev, desc->msi_attrib.pos+PCI_MSI_FLAGS,
  201831. - &msg_ctr);
  201832. - msgvec = (msg_ctr&PCI_MSI_FLAGS_QSIZE) >> 4;
  201833. - if (msgvec == 0)
  201834. - msgvec = (msg_ctr & PCI_MSI_FLAGS_QMASK) >> 1;
  201835. - if (msgvec > 5)
  201836. - msgvec = 0;
  201837. -
  201838. - irq = assign_irq((1 << msgvec), desc, &pos);
  201839. - if (irq < 0)
  201840. - return irq;
  201841. -
  201842. - /*
  201843. - * write_msi_msg() will update PCI_MSI_FLAGS so there is
  201844. - * no need to explicitly call pci_write_config_word().
  201845. - */
  201846. - desc->msi_attrib.multiple = msgvec;
  201847. + if (pp->quirks & DW_PCIE_QUIRK_NO_MSI_VEC) {
  201848. + irq = assign_irq(1, desc, &pos);
  201849. + set_irq_flags(irq, IRQF_VALID);
  201850. + } else {
  201851. + pci_read_config_word(pdev, desc->msi_attrib.pos+PCI_MSI_FLAGS,
  201852. + &msg_ctr);
  201853. + msgvec = (msg_ctr&PCI_MSI_FLAGS_QSIZE) >> 4;
  201854. + if (msgvec == 0)
  201855. + msgvec = (msg_ctr & PCI_MSI_FLAGS_QMASK) >> 1;
  201856. + if (msgvec > 5)
  201857. + msgvec = 0;
  201858. +
  201859. + irq = assign_irq((1 << msgvec), desc, &pos);
  201860. + if (irq < 0)
  201861. + return irq;
  201862. +
  201863. + msg_ctr &= ~PCI_MSI_FLAGS_QSIZE;
  201864. + msg_ctr |= msgvec << 4;
  201865. + pci_write_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
  201866. + msg_ctr);
  201867. + desc->msi_attrib.multiple = msgvec;
  201868. + }
  201869. msg.address_lo = virt_to_phys((void *)pp->msi_data);
  201870. msg.address_hi = 0x0;
  201871. @@ -363,9 +326,30 @@
  201872. clear_irq(irq);
  201873. }
  201874. +static int dw_msi_check_device(struct msi_chip *chip, struct pci_dev *pdev,
  201875. + int nvec, int type)
  201876. +{
  201877. + struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
  201878. + u32 val;
  201879. +
  201880. + if (pp->quirks & DW_PCIE_QUIRK_MSI_SELF_EN) {
  201881. + if ((type == PCI_CAP_ID_MSI) || (type == PCI_CAP_ID_MSIX)) {
  201882. + /* Set MSI enable of RC here */
  201883. + val = readl(pp->dbi_base + 0x50);
  201884. + if ((val & (PCI_MSI_FLAGS_ENABLE << 16)) == 0) {
  201885. + val |= PCI_MSI_FLAGS_ENABLE << 16;
  201886. + writel(val, pp->dbi_base + 0x50);
  201887. + }
  201888. + }
  201889. + }
  201890. +
  201891. + return 0;
  201892. +}
  201893. +
  201894. static struct msi_chip dw_pcie_msi_chip = {
  201895. .setup_irq = dw_msi_setup_irq,
  201896. .teardown_irq = dw_msi_teardown_irq,
  201897. + .check_device = dw_msi_check_device,
  201898. };
  201899. int dw_pcie_link_up(struct pcie_port *pp)
  201900. @@ -531,38 +515,6 @@
  201901. dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
  201902. }
  201903. -static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
  201904. -{
  201905. - /* Program viewport 0 : OUTBOUND : MEM */
  201906. - dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
  201907. - PCIE_ATU_VIEWPORT);
  201908. - dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
  201909. - dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE);
  201910. - dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE);
  201911. - dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1,
  201912. - PCIE_ATU_LIMIT);
  201913. - dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET);
  201914. - dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
  201915. - PCIE_ATU_UPPER_TARGET);
  201916. - dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
  201917. -}
  201918. -
  201919. -static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
  201920. -{
  201921. - /* Program viewport 1 : OUTBOUND : IO */
  201922. - dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
  201923. - PCIE_ATU_VIEWPORT);
  201924. - dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1);
  201925. - dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE);
  201926. - dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE);
  201927. - dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1,
  201928. - PCIE_ATU_LIMIT);
  201929. - dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET);
  201930. - dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
  201931. - PCIE_ATU_UPPER_TARGET);
  201932. - dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
  201933. -}
  201934. -
  201935. static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
  201936. u32 devfn, int where, int size, u32 *val)
  201937. {
  201938. @@ -577,12 +529,10 @@
  201939. dw_pcie_prog_viewport_cfg0(pp, busdev);
  201940. ret = dw_pcie_cfg_read(pp->va_cfg0_base + address, where, size,
  201941. val);
  201942. - dw_pcie_prog_viewport_mem_outbound(pp);
  201943. } else {
  201944. dw_pcie_prog_viewport_cfg1(pp, busdev);
  201945. ret = dw_pcie_cfg_read(pp->va_cfg1_base + address, where, size,
  201946. val);
  201947. - dw_pcie_prog_viewport_io_outbound(pp);
  201948. }
  201949. return ret;
  201950. @@ -602,12 +552,10 @@
  201951. dw_pcie_prog_viewport_cfg0(pp, busdev);
  201952. ret = dw_pcie_cfg_write(pp->va_cfg0_base + address, where, size,
  201953. val);
  201954. - dw_pcie_prog_viewport_mem_outbound(pp);
  201955. } else {
  201956. dw_pcie_prog_viewport_cfg1(pp, busdev);
  201957. ret = dw_pcie_cfg_write(pp->va_cfg1_base + address, where, size,
  201958. val);
  201959. - dw_pcie_prog_viewport_io_outbound(pp);
  201960. }
  201961. return ret;
  201962. @@ -739,7 +687,13 @@
  201963. {
  201964. struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
  201965. - return pp->irq;
  201966. + switch (pin) {
  201967. + case 1: return pp->irq;
  201968. + case 2: return pp->irq - 1;
  201969. + case 3: return pp->irq - 2;
  201970. + case 4: return pp->irq - 3;
  201971. + default: return -1;
  201972. + }
  201973. }
  201974. static void dw_pcie_add_bus(struct pci_bus *bus)
  201975. diff -Nur linux-3.14.14/drivers/pci/host/pcie-designware.h linux-imx6-3.14/drivers/pci/host/pcie-designware.h
  201976. --- linux-3.14.14/drivers/pci/host/pcie-designware.h 2014-07-28 10:07:25.000000000 -0500
  201977. +++ linux-imx6-3.14/drivers/pci/host/pcie-designware.h 2014-12-08 00:31:53.984418001 -0600
  201978. @@ -14,6 +14,48 @@
  201979. #ifndef _PCIE_DESIGNWARE_H
  201980. #define _PCIE_DESIGNWARE_H
  201981. +/* Synopsis specific PCIE configuration registers */
  201982. +#define PCIE_PORT_LINK_CONTROL 0x710
  201983. +#define PORT_LINK_MODE_MASK (0x3f << 16)
  201984. +#define PORT_LINK_MODE_1_LANES (0x1 << 16)
  201985. +#define PORT_LINK_MODE_2_LANES (0x3 << 16)
  201986. +#define PORT_LINK_MODE_4_LANES (0x7 << 16)
  201987. +
  201988. +#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
  201989. +#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
  201990. +#define PORT_LOGIC_LINK_WIDTH_MASK (0x1ff << 8)
  201991. +#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
  201992. +#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
  201993. +#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
  201994. +
  201995. +#define PCIE_MSI_ADDR_LO 0x820
  201996. +#define PCIE_MSI_ADDR_HI 0x824
  201997. +#define PCIE_MSI_INTR0_ENABLE 0x828
  201998. +#define PCIE_MSI_INTR0_MASK 0x82C
  201999. +#define PCIE_MSI_INTR0_STATUS 0x830
  202000. +
  202001. +#define PCIE_ATU_VIEWPORT 0x900
  202002. +#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
  202003. +#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
  202004. +#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
  202005. +#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
  202006. +#define PCIE_ATU_CR1 0x904
  202007. +#define PCIE_ATU_TYPE_MEM (0x0 << 0)
  202008. +#define PCIE_ATU_TYPE_IO (0x2 << 0)
  202009. +#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
  202010. +#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
  202011. +#define PCIE_ATU_CR2 0x908
  202012. +#define PCIE_ATU_ENABLE (0x1 << 31)
  202013. +#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
  202014. +#define PCIE_ATU_LOWER_BASE 0x90C
  202015. +#define PCIE_ATU_UPPER_BASE 0x910
  202016. +#define PCIE_ATU_LIMIT 0x914
  202017. +#define PCIE_ATU_LOWER_TARGET 0x918
  202018. +#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
  202019. +#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
  202020. +#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
  202021. +#define PCIE_ATU_UPPER_TARGET 0x91C
  202022. +
  202023. struct pcie_port_info {
  202024. u32 cfg0_size;
  202025. u32 cfg1_size;
  202026. @@ -49,6 +91,11 @@
  202027. int irq;
  202028. u32 lanes;
  202029. struct pcie_host_ops *ops;
  202030. + u32 quirks; /* Deviations from spec. */
  202031. +/* Controller doesn't support MSI VEC */
  202032. +#define DW_PCIE_QUIRK_NO_MSI_VEC (1<<0)
  202033. +/* MSI EN of Controller should be configured when MSI is enabled */
  202034. +#define DW_PCIE_QUIRK_MSI_SELF_EN (1<<1)
  202035. int msi_irq;
  202036. struct irq_domain *irq_domain;
  202037. unsigned long msi_data;
  202038. diff -Nur linux-3.14.14/drivers/pci/host/pci-imx6.c linux-imx6-3.14/drivers/pci/host/pci-imx6.c
  202039. --- linux-3.14.14/drivers/pci/host/pci-imx6.c 2014-07-28 10:07:25.000000000 -0500
  202040. +++ linux-imx6-3.14/drivers/pci/host/pci-imx6.c 2014-12-08 00:31:53.984418001 -0600
  202041. @@ -1,6 +1,7 @@
  202042. /*
  202043. * PCIe host controller driver for Freescale i.MX6 SoCs
  202044. *
  202045. + * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  202046. * Copyright (C) 2013 Kosagi
  202047. * http://www.kosagi.com
  202048. *
  202049. @@ -14,6 +15,7 @@
  202050. #include <linux/clk.h>
  202051. #include <linux/delay.h>
  202052. #include <linux/gpio.h>
  202053. +#include <linux/interrupt.h>
  202054. #include <linux/kernel.h>
  202055. #include <linux/mfd/syscon.h>
  202056. #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  202057. @@ -25,11 +27,22 @@
  202058. #include <linux/resource.h>
  202059. #include <linux/signal.h>
  202060. #include <linux/types.h>
  202061. +#include <linux/busfreq-imx6.h>
  202062. +#include "../pci.h"
  202063. #include "pcie-designware.h"
  202064. #define to_imx6_pcie(x) container_of(x, struct imx6_pcie, pp)
  202065. +/*
  202066. + * The default value of the reserved ddr memory
  202067. + * used to verify EP/RC memory space access operations.
  202068. + * BTW, here is the layout of the 1G ddr on SD boards
  202069. + * 0x1000_0000 ~ 0x4FFF_FFFF
  202070. + */
  202071. +static u32 ddr_test_region = 0x40000000;
  202072. +static u32 test_region_size = SZ_2M;
  202073. +
  202074. struct imx6_pcie {
  202075. int reset_gpio;
  202076. int power_on_gpio;
  202077. @@ -52,6 +65,9 @@
  202078. /* PCIe Port Logic registers (memory-mapped) */
  202079. #define PL_OFFSET 0x700
  202080. +#define PCIE_PL_PFLR (PL_OFFSET + 0x08)
  202081. +#define PCIE_PL_PFLR_LINK_STATE_MASK (0x3f << 16)
  202082. +#define PCIE_PL_PFLR_FORCE_LINK (1 << 15)
  202083. #define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)
  202084. #define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
  202085. #define PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING (1 << 29)
  202086. @@ -216,14 +232,14 @@
  202087. static int imx6_pcie_assert_core_reset(struct pcie_port *pp)
  202088. {
  202089. - struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
  202090. + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
  202091. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  202092. - IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
  202093. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  202094. - IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
  202095. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  202096. + IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
  202097. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  202098. + IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
  202099. - return 0;
  202100. + return 0;
  202101. }
  202102. static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
  202103. @@ -234,10 +250,7 @@
  202104. if (gpio_is_valid(imx6_pcie->power_on_gpio))
  202105. gpio_set_value(imx6_pcie->power_on_gpio, 1);
  202106. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  202107. - IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
  202108. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  202109. - IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
  202110. + request_bus_freq(BUS_FREQ_HIGH);
  202111. ret = clk_prepare_enable(imx6_pcie->sata_ref_100m);
  202112. if (ret) {
  202113. @@ -251,10 +264,13 @@
  202114. goto err_pcie_ref;
  202115. }
  202116. - ret = clk_prepare_enable(imx6_pcie->lvds_gate);
  202117. - if (ret) {
  202118. - dev_err(pp->dev, "unable to enable lvds_gate\n");
  202119. - goto err_lvds_gate;
  202120. + if (!IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)
  202121. + && !IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS)) {
  202122. + ret = clk_prepare_enable(imx6_pcie->lvds_gate);
  202123. + if (ret) {
  202124. + dev_err(pp->dev, "unable to enable lvds_gate\n");
  202125. + goto err_lvds_gate;
  202126. + }
  202127. }
  202128. ret = clk_prepare_enable(imx6_pcie->pcie_axi);
  202129. @@ -266,6 +282,12 @@
  202130. /* allow the clocks to stabilize */
  202131. usleep_range(200, 500);
  202132. + /* power up core phy and enable ref clock */
  202133. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  202134. + IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
  202135. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  202136. + IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
  202137. +
  202138. /* Some boards don't have PCIe reset GPIO. */
  202139. if (gpio_is_valid(imx6_pcie->reset_gpio)) {
  202140. gpio_set_value(imx6_pcie->reset_gpio, 0);
  202141. @@ -281,6 +303,7 @@
  202142. err_pcie_ref:
  202143. clk_disable_unprepare(imx6_pcie->sata_ref_100m);
  202144. err_sata_ref:
  202145. + release_bus_freq(BUS_FREQ_HIGH);
  202146. return ret;
  202147. }
  202148. @@ -288,13 +311,44 @@
  202149. static void imx6_pcie_init_phy(struct pcie_port *pp)
  202150. {
  202151. struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
  202152. + u32 val, gpr1, gpr12;
  202153. +
  202154. + /*
  202155. + * If the bootloader already enabled the link we need some special
  202156. + * handling to get the core back into a state where it is safe to
  202157. + * touch it for configuration. As there is no dedicated reset signal
  202158. + * wired up for MX6QDL, we need to manually force LTSSM into "detect"
  202159. + * state before completely disabling LTSSM, which is a prerequisite
  202160. + * for core configuration.
  202161. + * If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have a strong
  202162. + * indication that the bootloader activated the link.
  202163. + */
  202164. + regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, &gpr1);
  202165. + regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, &gpr12);
  202166. +
  202167. + if ((gpr1 & IMX6Q_GPR1_PCIE_REF_CLK_EN) &&
  202168. + (gpr12 & IMX6Q_GPR12_PCIE_CTL_2)) {
  202169. + val = readl(pp->dbi_base + PCIE_PL_PFLR);
  202170. + val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
  202171. + val |= PCIE_PL_PFLR_FORCE_LINK;
  202172. + writel(val, pp->dbi_base + PCIE_PL_PFLR);
  202173. +
  202174. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202175. + IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
  202176. + }
  202177. regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202178. IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
  202179. /* configure constant input signal to the pcie ctrl and phy */
  202180. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202181. - IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12);
  202182. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS))
  202183. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202184. + IMX6Q_GPR12_DEVICE_TYPE,
  202185. + PCI_EXP_TYPE_ENDPOINT << 12);
  202186. + else
  202187. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202188. + IMX6Q_GPR12_DEVICE_TYPE,
  202189. + PCI_EXP_TYPE_ROOT_PORT << 12);
  202190. regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202191. IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
  202192. @@ -326,6 +380,12 @@
  202193. return -EINVAL;
  202194. }
  202195. + if (IS_ENABLED(CONFIG_PCI_MSI)) {
  202196. + pp->quirks |= DW_PCIE_QUIRK_NO_MSI_VEC;
  202197. + pp->quirks |= DW_PCIE_QUIRK_MSI_SELF_EN;
  202198. + dw_pcie_msi_init(pp);
  202199. + }
  202200. +
  202201. return 0;
  202202. }
  202203. @@ -392,6 +452,15 @@
  202204. return ret;
  202205. }
  202206. +static irqreturn_t imx_pcie_msi_irq_handler(int irq, void *arg)
  202207. +{
  202208. + struct pcie_port *pp = arg;
  202209. +
  202210. + dw_handle_msi_irq(pp);
  202211. +
  202212. + return IRQ_HANDLED;
  202213. +}
  202214. +
  202215. static void imx6_pcie_host_init(struct pcie_port *pp)
  202216. {
  202217. imx6_pcie_assert_core_reset(pp);
  202218. @@ -498,6 +567,22 @@
  202219. return -ENODEV;
  202220. }
  202221. + if (IS_ENABLED(CONFIG_PCI_MSI)) {
  202222. + pp->msi_irq = pp->irq - 3;
  202223. + if (!pp->msi_irq) {
  202224. + dev_err(&pdev->dev, "failed to get msi irq\n");
  202225. + return -ENODEV;
  202226. + }
  202227. +
  202228. + ret = devm_request_irq(&pdev->dev, pp->msi_irq,
  202229. + imx_pcie_msi_irq_handler,
  202230. + IRQF_SHARED, "imx6q-pcie", pp);
  202231. + if (ret) {
  202232. + dev_err(&pdev->dev, "failed to request msi irq\n");
  202233. + return ret;
  202234. + }
  202235. + }
  202236. +
  202237. pp->root_bus_nr = -1;
  202238. pp->ops = &imx6_pcie_host_ops;
  202239. @@ -511,29 +596,188 @@
  202240. return 0;
  202241. }
  202242. +static ssize_t imx_pcie_bar0_addr_info(struct device *dev,
  202243. + struct device_attribute *devattr, char *buf)
  202244. +{
  202245. + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
  202246. + struct pcie_port *pp = &imx6_pcie->pp;
  202247. +
  202248. + return sprintf(buf, "imx-pcie-bar0-addr-info start 0x%08x\n",
  202249. + readl(pp->dbi_base + PCI_BASE_ADDRESS_0));
  202250. +}
  202251. +
  202252. +static ssize_t imx_pcie_bar0_addr_start(struct device *dev,
  202253. + struct device_attribute *attr, const char *buf, size_t count)
  202254. +{
  202255. + u32 bar_start;
  202256. + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
  202257. + struct pcie_port *pp = &imx6_pcie->pp;
  202258. +
  202259. + sscanf(buf, "%x\n", &bar_start);
  202260. + writel(bar_start, pp->dbi_base + PCI_BASE_ADDRESS_0);
  202261. +
  202262. + return count;
  202263. +}
  202264. +
  202265. +static void imx_pcie_regions_setup(struct device *dev)
  202266. +{
  202267. + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
  202268. + struct pcie_port *pp = &imx6_pcie->pp;
  202269. +
  202270. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
  202271. + /*
  202272. + * region2 outbound used to access rc mem
  202273. + * in imx6 pcie ep/rc validation system
  202274. + */
  202275. + writel(0, pp->dbi_base + PCIE_ATU_VIEWPORT);
  202276. + writel(0x01000000, pp->dbi_base + PCIE_ATU_LOWER_BASE);
  202277. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_BASE);
  202278. + writel(0x01000000 + test_region_size,
  202279. + pp->dbi_base + PCIE_ATU_LIMIT);
  202280. +
  202281. + writel(ddr_test_region,
  202282. + pp->dbi_base + PCIE_ATU_LOWER_TARGET);
  202283. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_TARGET);
  202284. + writel(PCIE_ATU_TYPE_MEM, pp->dbi_base + PCIE_ATU_CR1);
  202285. + writel(PCIE_ATU_ENABLE, pp->dbi_base + PCIE_ATU_CR2);
  202286. + }
  202287. +
  202288. + if (IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS)) {
  202289. + /*
  202290. + * region2 outbound used to access ep mem
  202291. + * in imx6 pcie ep/rc validation system
  202292. + */
  202293. + writel(2, pp->dbi_base + PCIE_ATU_VIEWPORT);
  202294. + writel(0x01000000, pp->dbi_base + PCIE_ATU_LOWER_BASE);
  202295. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_BASE);
  202296. + writel(0x01000000 + test_region_size,
  202297. + pp->dbi_base + PCIE_ATU_LIMIT);
  202298. +
  202299. + writel(ddr_test_region,
  202300. + pp->dbi_base + PCIE_ATU_LOWER_TARGET);
  202301. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_TARGET);
  202302. + writel(PCIE_ATU_TYPE_MEM, pp->dbi_base + PCIE_ATU_CR1);
  202303. + writel(PCIE_ATU_ENABLE, pp->dbi_base + PCIE_ATU_CR2);
  202304. + }
  202305. +}
  202306. +
  202307. +static ssize_t imx_pcie_memw_info(struct device *dev,
  202308. + struct device_attribute *devattr, char *buf)
  202309. +{
  202310. + return sprintf(buf, "imx-pcie-rc-memw-info start 0x%08x, size 0x%08x\n",
  202311. + ddr_test_region, test_region_size);
  202312. +}
  202313. +
  202314. +static ssize_t
  202315. +imx_pcie_memw_start(struct device *dev, struct device_attribute *attr,
  202316. + const char *buf, size_t count)
  202317. +{
  202318. + u32 memw_start;
  202319. +
  202320. + sscanf(buf, "%x\n", &memw_start);
  202321. +
  202322. + if (memw_start < 0x10000000) {
  202323. + dev_err(dev, "Invalid memory start address.\n");
  202324. + dev_info(dev, "For example: echo 0x41000000 > /sys/...");
  202325. + return -1;
  202326. + }
  202327. +
  202328. + if (ddr_test_region != memw_start) {
  202329. + ddr_test_region = memw_start;
  202330. + /* Re-setup the iATU */
  202331. + imx_pcie_regions_setup(dev);
  202332. + }
  202333. +
  202334. + return count;
  202335. +}
  202336. +
  202337. +static ssize_t
  202338. +imx_pcie_memw_size(struct device *dev, struct device_attribute *attr,
  202339. + const char *buf, size_t count)
  202340. +{
  202341. + u32 memw_size;
  202342. +
  202343. + sscanf(buf, "%x\n", &memw_size);
  202344. +
  202345. + if ((memw_size > (SZ_16M - SZ_1M)) || (memw_size < SZ_64K)) {
  202346. + dev_err(dev, "Invalid, should be [SZ_64K,SZ_16M - SZ_1MB].\n");
  202347. + dev_info(dev, "For example: echo 0x800000 > /sys/...");
  202348. + return -1;
  202349. + }
  202350. +
  202351. + if (test_region_size != memw_size) {
  202352. + test_region_size = memw_size;
  202353. + /* Re-setup the iATU */
  202354. + imx_pcie_regions_setup(dev);
  202355. + }
  202356. +
  202357. + return count;
  202358. +}
  202359. +
  202360. +static DEVICE_ATTR(memw_info, S_IRUGO, imx_pcie_memw_info, NULL);
  202361. +static DEVICE_ATTR(memw_start_set, S_IWUGO, NULL, imx_pcie_memw_start);
  202362. +static DEVICE_ATTR(memw_size_set, S_IWUGO, NULL, imx_pcie_memw_size);
  202363. +static DEVICE_ATTR(ep_bar0_addr, S_IRWXUGO, imx_pcie_bar0_addr_info,
  202364. + imx_pcie_bar0_addr_start);
  202365. +
  202366. +static struct attribute *imx_pcie_attrs[] = {
  202367. + /*
  202368. + * The start address, and the limitation (64KB ~ (16MB - 1MB))
  202369. + * of the ddr mem window reserved by RC, and used for EP to access.
  202370. + * BTW, these attrs are only configured at EP side.
  202371. + */
  202372. + &dev_attr_memw_info.attr,
  202373. + &dev_attr_memw_start_set.attr,
  202374. + &dev_attr_memw_size_set.attr,
  202375. + &dev_attr_ep_bar0_addr.attr,
  202376. + NULL
  202377. +};
  202378. +
  202379. +static struct attribute_group imx_pcie_attrgroup = {
  202380. + .attrs = imx_pcie_attrs,
  202381. +};
  202382. +
  202383. static int __init imx6_pcie_probe(struct platform_device *pdev)
  202384. {
  202385. struct imx6_pcie *imx6_pcie;
  202386. struct pcie_port *pp;
  202387. struct device_node *np = pdev->dev.of_node;
  202388. struct resource *dbi_base;
  202389. - int ret;
  202390. + int ret = 0;
  202391. + int i;
  202392. + void *test_reg1, *test_reg2;
  202393. + void __iomem *pcie_arb_base_addr;
  202394. + struct timeval tv1, tv2, tv3;
  202395. + u32 tv_count1, tv_count2;
  202396. imx6_pcie = devm_kzalloc(&pdev->dev, sizeof(*imx6_pcie), GFP_KERNEL);
  202397. - if (!imx6_pcie)
  202398. - return -ENOMEM;
  202399. + if (!imx6_pcie) {
  202400. + ret = -ENOMEM;
  202401. + goto err;
  202402. + }
  202403. pp = &imx6_pcie->pp;
  202404. pp->dev = &pdev->dev;
  202405. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
  202406. + /* add attributes for device */
  202407. + ret = sysfs_create_group(&pdev->dev.kobj, &imx_pcie_attrgroup);
  202408. + if (ret) {
  202409. + ret = -EINVAL;
  202410. + goto err;
  202411. + }
  202412. + }
  202413. +
  202414. /* Added for PCI abort handling */
  202415. hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0,
  202416. "imprecise external abort");
  202417. dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  202418. pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base);
  202419. - if (IS_ERR(pp->dbi_base))
  202420. - return PTR_ERR(pp->dbi_base);
  202421. + if (IS_ERR(pp->dbi_base)) {
  202422. + ret = PTR_ERR(pp->dbi_base);
  202423. + goto err;
  202424. + }
  202425. /* Fetch GPIOs */
  202426. imx6_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
  202427. @@ -542,7 +786,7 @@
  202428. GPIOF_OUT_INIT_LOW, "PCIe reset");
  202429. if (ret) {
  202430. dev_err(&pdev->dev, "unable to get reset gpio\n");
  202431. - return ret;
  202432. + goto err;
  202433. }
  202434. }
  202435. @@ -554,7 +798,7 @@
  202436. "PCIe power enable");
  202437. if (ret) {
  202438. dev_err(&pdev->dev, "unable to get power-on gpio\n");
  202439. - return ret;
  202440. + goto err;
  202441. }
  202442. }
  202443. @@ -566,7 +810,7 @@
  202444. "PCIe wake up");
  202445. if (ret) {
  202446. dev_err(&pdev->dev, "unable to get wake-up gpio\n");
  202447. - return ret;
  202448. + goto err;
  202449. }
  202450. }
  202451. @@ -578,7 +822,7 @@
  202452. "PCIe disable endpoint");
  202453. if (ret) {
  202454. dev_err(&pdev->dev, "unable to get disable-ep gpio\n");
  202455. - return ret;
  202456. + goto err;
  202457. }
  202458. }
  202459. @@ -587,28 +831,32 @@
  202460. if (IS_ERR(imx6_pcie->lvds_gate)) {
  202461. dev_err(&pdev->dev,
  202462. "lvds_gate clock select missing or invalid\n");
  202463. - return PTR_ERR(imx6_pcie->lvds_gate);
  202464. + ret = PTR_ERR(imx6_pcie->lvds_gate);
  202465. + goto err;
  202466. }
  202467. imx6_pcie->sata_ref_100m = devm_clk_get(&pdev->dev, "sata_ref_100m");
  202468. if (IS_ERR(imx6_pcie->sata_ref_100m)) {
  202469. dev_err(&pdev->dev,
  202470. "sata_ref_100m clock source missing or invalid\n");
  202471. - return PTR_ERR(imx6_pcie->sata_ref_100m);
  202472. + ret = PTR_ERR(imx6_pcie->sata_ref_100m);
  202473. + goto err;
  202474. }
  202475. imx6_pcie->pcie_ref_125m = devm_clk_get(&pdev->dev, "pcie_ref_125m");
  202476. if (IS_ERR(imx6_pcie->pcie_ref_125m)) {
  202477. dev_err(&pdev->dev,
  202478. "pcie_ref_125m clock source missing or invalid\n");
  202479. - return PTR_ERR(imx6_pcie->pcie_ref_125m);
  202480. + ret = PTR_ERR(imx6_pcie->pcie_ref_125m);
  202481. + goto err;
  202482. }
  202483. imx6_pcie->pcie_axi = devm_clk_get(&pdev->dev, "pcie_axi");
  202484. if (IS_ERR(imx6_pcie->pcie_axi)) {
  202485. dev_err(&pdev->dev,
  202486. "pcie_axi clock source missing or invalid\n");
  202487. - return PTR_ERR(imx6_pcie->pcie_axi);
  202488. + ret = PTR_ERR(imx6_pcie->pcie_axi);
  202489. + goto err;
  202490. }
  202491. /* Grab GPR config register range */
  202492. @@ -616,15 +864,178 @@
  202493. syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  202494. if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
  202495. dev_err(&pdev->dev, "unable to find iomuxc registers\n");
  202496. - return PTR_ERR(imx6_pcie->iomuxc_gpr);
  202497. + ret = PTR_ERR(imx6_pcie->iomuxc_gpr);
  202498. + goto err;
  202499. }
  202500. - ret = imx6_add_pcie_port(pp, pdev);
  202501. - if (ret < 0)
  202502. - return ret;
  202503. + if (of_find_property(np, "no-msi", NULL))
  202504. + pci_no_msi();
  202505. - platform_set_drvdata(pdev, imx6_pcie);
  202506. - return 0;
  202507. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
  202508. + if (IS_ENABLED(CONFIG_EP_SELF_IO_TEST)) {
  202509. + /* Prepare the test regions and data */
  202510. + test_reg1 = devm_kzalloc(&pdev->dev,
  202511. + test_region_size, GFP_KERNEL);
  202512. + if (!test_reg1) {
  202513. + pr_err("pcie ep: can't alloc the test reg1.\n");
  202514. + ret = PTR_ERR(test_reg1);
  202515. + goto err;
  202516. + }
  202517. +
  202518. + test_reg2 = devm_kzalloc(&pdev->dev,
  202519. + test_region_size, GFP_KERNEL);
  202520. + if (!test_reg2) {
  202521. + pr_err("pcie ep: can't alloc the test reg2.\n");
  202522. + ret = PTR_ERR(test_reg1);
  202523. + goto err;
  202524. + }
  202525. +
  202526. + pcie_arb_base_addr = ioremap_cache(0x01000000,
  202527. + test_region_size);
  202528. +
  202529. + if (!pcie_arb_base_addr) {
  202530. + pr_err("error with ioremap in ep selftest\n");
  202531. + ret = PTR_ERR(pcie_arb_base_addr);
  202532. + goto err;
  202533. + }
  202534. +
  202535. + for (i = 0; i < test_region_size; i = i + 4) {
  202536. + writel(0xE6600D00 + i, test_reg1 + i);
  202537. + writel(0xDEADBEAF, test_reg2 + i);
  202538. + }
  202539. + }
  202540. +
  202541. + imx6_pcie_init_phy(pp);
  202542. +
  202543. + imx6_pcie_deassert_core_reset(pp);
  202544. +
  202545. + /* assert LTSSM enable */
  202546. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  202547. + IMX6Q_GPR12_PCIE_CTL_2, 1 << 10);
  202548. +
  202549. +
  202550. + dev_info(&pdev->dev, "PCIe EP: waiting for link up...\n");
  202551. +
  202552. + platform_set_drvdata(pdev, imx6_pcie);
  202553. + /* link is indicated by the bit4 of DB_R1 register */
  202554. + do {
  202555. + usleep_range(10, 20);
  202556. + } while ((readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & 0x10) == 0);
  202557. +
  202558. + /* CMD reg:I/O space, MEM space, and Bus Master Enable */
  202559. + writel(readl(pp->dbi_base + PCI_COMMAND)
  202560. + | PCI_COMMAND_IO
  202561. + | PCI_COMMAND_MEMORY
  202562. + | PCI_COMMAND_MASTER,
  202563. + pp->dbi_base + PCI_COMMAND);
  202564. +
  202565. + /*
  202566. + * configure the class_rev(emaluate one memory ram ep device),
  202567. + * bar0 and bar1 of ep
  202568. + */
  202569. + writel(0xdeadbeaf, pp->dbi_base + PCI_VENDOR_ID);
  202570. + writel(readl(pp->dbi_base + PCI_CLASS_REVISION)
  202571. + | (PCI_CLASS_MEMORY_RAM << 16),
  202572. + pp->dbi_base + PCI_CLASS_REVISION);
  202573. + writel(0xdeadbeaf, pp->dbi_base
  202574. + + PCI_SUBSYSTEM_VENDOR_ID);
  202575. +
  202576. + /* 32bit none-prefetchable 8M bytes memory on bar0 */
  202577. + writel(0x0, pp->dbi_base + PCI_BASE_ADDRESS_0);
  202578. + writel(SZ_8M - 1, pp->dbi_base + (1 << 12)
  202579. + + PCI_BASE_ADDRESS_0);
  202580. +
  202581. + /* None used bar1 */
  202582. + writel(0x0, pp->dbi_base + PCI_BASE_ADDRESS_1);
  202583. + writel(0, pp->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_1);
  202584. +
  202585. + /* 4K bytes IO on bar2 */
  202586. + writel(0x1, pp->dbi_base + PCI_BASE_ADDRESS_2);
  202587. + writel(SZ_4K - 1, pp->dbi_base + (1 << 12) +
  202588. + PCI_BASE_ADDRESS_2);
  202589. +
  202590. + /*
  202591. + * 32bit prefetchable 1M bytes memory on bar3
  202592. + * FIXME BAR MASK3 is not changable, the size
  202593. + * is fixed to 256 bytes.
  202594. + */
  202595. + writel(0x8, pp->dbi_base + PCI_BASE_ADDRESS_3);
  202596. + writel(SZ_1M - 1, pp->dbi_base + (1 << 12)
  202597. + + PCI_BASE_ADDRESS_3);
  202598. +
  202599. + /*
  202600. + * 64bit prefetchable 1M bytes memory on bar4-5.
  202601. + * FIXME BAR4,5 are not enabled yet
  202602. + */
  202603. + writel(0xc, pp->dbi_base + PCI_BASE_ADDRESS_4);
  202604. + writel(SZ_1M - 1, pp->dbi_base + (1 << 12)
  202605. + + PCI_BASE_ADDRESS_4);
  202606. + writel(0, pp->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_5);
  202607. +
  202608. + /* Re-setup the iATU */
  202609. + imx_pcie_regions_setup(&pdev->dev);
  202610. +
  202611. + if (IS_ENABLED(CONFIG_EP_SELF_IO_TEST)) {
  202612. + /* PCIe EP start the data transfer after link up */
  202613. + pr_info("pcie ep: Starting data transfer...\n");
  202614. + do_gettimeofday(&tv1);
  202615. +
  202616. + memcpy((unsigned long *)pcie_arb_base_addr,
  202617. + (unsigned long *)test_reg1,
  202618. + test_region_size);
  202619. +
  202620. + do_gettimeofday(&tv2);
  202621. +
  202622. + memcpy((unsigned long *)test_reg2,
  202623. + (unsigned long *)pcie_arb_base_addr,
  202624. + test_region_size);
  202625. +
  202626. + do_gettimeofday(&tv3);
  202627. +
  202628. + if (memcmp(test_reg2, test_reg1, test_region_size) == 0) {
  202629. + tv_count1 = (tv2.tv_sec - tv1.tv_sec)
  202630. + * USEC_PER_SEC
  202631. + + tv2.tv_usec - tv1.tv_usec;
  202632. + tv_count2 = (tv3.tv_sec - tv2.tv_sec)
  202633. + * USEC_PER_SEC
  202634. + + tv3.tv_usec - tv2.tv_usec;
  202635. +
  202636. + pr_info("pcie ep: Data transfer is successful."
  202637. + " tv_count1 %dus,"
  202638. + " tv_count2 %dus.\n",
  202639. + tv_count1, tv_count2);
  202640. + pr_info("pcie ep: Data write speed:%ldMB/s.\n",
  202641. + ((test_region_size/1024)
  202642. + * MSEC_PER_SEC)
  202643. + /(tv_count1));
  202644. + pr_info("pcie ep: Data read speed:%ldMB/s.\n",
  202645. + ((test_region_size/1024)
  202646. + * MSEC_PER_SEC)
  202647. + /(tv_count2));
  202648. + } else {
  202649. + pr_info("pcie ep: Data transfer is failed.\n");
  202650. + }
  202651. + }
  202652. + } else {
  202653. + ret = imx6_add_pcie_port(pp, pdev);
  202654. + if (ret < 0)
  202655. + goto err;
  202656. + platform_set_drvdata(pdev, imx6_pcie);
  202657. +
  202658. + /* Re-setup the iATU */
  202659. + imx_pcie_regions_setup(&pdev->dev);
  202660. + }
  202661. +
  202662. +err:
  202663. + return ret;
  202664. +}
  202665. +
  202666. +static void imx6_pcie_shutdown(struct platform_device *pdev)
  202667. +{
  202668. + struct imx6_pcie *imx6_pcie = platform_get_drvdata(pdev);
  202669. +
  202670. + /* bring down link, so bootloader gets clean state in case of reboot */
  202671. + imx6_pcie_assert_core_reset(&imx6_pcie->pp);
  202672. }
  202673. static const struct of_device_id imx6_pcie_of_match[] = {
  202674. @@ -639,6 +1050,7 @@
  202675. .owner = THIS_MODULE,
  202676. .of_match_table = imx6_pcie_of_match,
  202677. },
  202678. + .shutdown = imx6_pcie_shutdown,
  202679. };
  202680. /* Freescale PCIe driver does not allow module unload */
  202681. diff -Nur linux-3.14.14/drivers/pci/host/pci-imx6-ep-driver.c linux-imx6-3.14/drivers/pci/host/pci-imx6-ep-driver.c
  202682. --- linux-3.14.14/drivers/pci/host/pci-imx6-ep-driver.c 1969-12-31 18:00:00.000000000 -0600
  202683. +++ linux-imx6-3.14/drivers/pci/host/pci-imx6-ep-driver.c 2014-12-08 00:31:53.984418001 -0600
  202684. @@ -0,0 +1,159 @@
  202685. +/*
  202686. + * PCIe endpoint skeleton driver for IMX6 SOCs
  202687. + *
  202688. + * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  202689. + *
  202690. + * This program is free software; you can redistribute it and/or modify
  202691. + * it under the terms of the GNU General Public License as published by
  202692. + * the Free Software Foundation; either version 2 of the License, or
  202693. + * (at your option) any later version.
  202694. +
  202695. + * This program is distributed in the hope that it will be useful,
  202696. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  202697. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  202698. + * GNU General Public License for more details.
  202699. +
  202700. + * You should have received a copy of the GNU General Public License along
  202701. + * with this program; if not, write to the Free Software Foundation, Inc.,
  202702. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  202703. + */
  202704. +
  202705. +#include <linux/kernel.h>
  202706. +#include <linux/module.h>
  202707. +#include <linux/init.h>
  202708. +#include <linux/pci.h>
  202709. +#include <linux/pci-aspm.h>
  202710. +#include <linux/slab.h>
  202711. +#include <linux/dma-mapping.h>
  202712. +#include <linux/delay.h>
  202713. +#include <linux/sched.h>
  202714. +#include <linux/interrupt.h>
  202715. +
  202716. +#define DRV_DESCRIPTION "i.MX PCIE endpoint device driver"
  202717. +#define DRV_VERSION "version 0.1"
  202718. +#define DRV_NAME "imx_pcie_ep"
  202719. +
  202720. +struct imx_pcie_ep_priv {
  202721. + struct pci_dev *pci_dev;
  202722. + void __iomem *hw_base;
  202723. +};
  202724. +
  202725. +/**
  202726. + * imx_pcie_ep_probe - Device Initialization Routine
  202727. + * @pdev: PCI device information struct
  202728. + * @id: entry in id_tbl
  202729. + *
  202730. + * Returns 0 on success, negative on failure
  202731. + **/
  202732. +static int imx_pcie_ep_probe(struct pci_dev *pdev,
  202733. + const struct pci_device_id *id)
  202734. +{
  202735. + int ret = 0;
  202736. + struct device *dev = &pdev->dev;
  202737. + struct imx_pcie_ep_priv *priv;
  202738. +
  202739. + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  202740. + if (!priv) {
  202741. + dev_err(dev, "can't alloc imx pcie priv\n");
  202742. + return -ENOMEM;
  202743. + }
  202744. +
  202745. + priv->pci_dev = pdev;
  202746. +
  202747. + if (pci_enable_device(pdev)) {
  202748. + ret = -ENODEV;
  202749. + goto out;
  202750. + }
  202751. + pci_set_master(pdev);
  202752. +
  202753. + pci_set_drvdata(pdev, priv);
  202754. +
  202755. + priv->hw_base = pci_iomap(pdev, 0, 0);
  202756. + if (!priv->hw_base) {
  202757. + ret = -ENODEV;
  202758. + goto out;
  202759. + }
  202760. +
  202761. + pr_info("pci_resource_len = 0x%08llx\n",
  202762. + (unsigned long long) pci_resource_len(pdev, 0));
  202763. + pr_info("pci_resource_base = %p\n", priv->hw_base);
  202764. +
  202765. + ret = pci_enable_msi(priv->pci_dev);
  202766. + if (ret < 0) {
  202767. + dev_err(dev, "can't enable msi\n");
  202768. + return ret;
  202769. + }
  202770. +
  202771. + /*
  202772. + * Force to use 0x01FF8000 as the MSI address,
  202773. + * to do the MSI demo
  202774. + */
  202775. + pci_bus_write_config_dword(pdev->bus, 0, 0x54, 0x01FF8000);
  202776. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x820, 0x01FF8000);
  202777. +
  202778. + /* configure rc's msi cap */
  202779. + pci_bus_read_config_dword(pdev->bus->parent, 0, 0x50, &ret);
  202780. + ret |= (PCI_MSI_FLAGS_ENABLE << 16);
  202781. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x50, ret);
  202782. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x828, 0x1);
  202783. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x82C, 0xFFFFFFFE);
  202784. +
  202785. + return 0;
  202786. +
  202787. +out:
  202788. + return ret;
  202789. +}
  202790. +
  202791. +static void imx_pcie_ep_remove(struct pci_dev *pdev)
  202792. +{
  202793. + struct imx_pcie_ep_priv *priv = pci_get_drvdata(pdev);
  202794. +
  202795. + if (!priv)
  202796. + return;
  202797. + pr_info("***imx pcie ep driver unload***\n");
  202798. +}
  202799. +
  202800. +static struct pci_device_id imx_pcie_ep_ids[] = {
  202801. + {
  202802. + .class = PCI_CLASS_MEMORY_RAM << 8,
  202803. + .class_mask = ~0,
  202804. + .vendor = 0xbeaf,
  202805. + .device = 0xdead,
  202806. + .subvendor = PCI_ANY_ID,
  202807. + .subdevice = PCI_ANY_ID,
  202808. + },
  202809. + { } /* terminate list */
  202810. +};
  202811. +MODULE_DEVICE_TABLE(pci, imx_pcie_ep_ids);
  202812. +
  202813. +static struct pci_driver imx_pcie_ep_driver = {
  202814. + .name = DRV_NAME,
  202815. + .id_table = imx_pcie_ep_ids,
  202816. + .probe = imx_pcie_ep_probe,
  202817. + .remove = imx_pcie_ep_remove,
  202818. +};
  202819. +
  202820. +static int __init imx_pcie_ep_init(void)
  202821. +{
  202822. + int ret;
  202823. + pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
  202824. +
  202825. + ret = pci_register_driver(&imx_pcie_ep_driver);
  202826. + if (ret)
  202827. + pr_err("Unable to initialize PCI module\n");
  202828. +
  202829. + return ret;
  202830. +}
  202831. +
  202832. +static void __exit imx_pcie_ep_exit(void)
  202833. +{
  202834. + pci_unregister_driver(&imx_pcie_ep_driver);
  202835. +}
  202836. +
  202837. +module_exit(imx_pcie_ep_exit);
  202838. +module_init(imx_pcie_ep_init);
  202839. +
  202840. +MODULE_DESCRIPTION(DRV_DESCRIPTION);
  202841. +MODULE_VERSION(DRV_VERSION);
  202842. +MODULE_LICENSE("GPL");
  202843. +MODULE_ALIAS("imx_pcie_ep");
  202844. diff -Nur linux-3.14.14/drivers/pinctrl/devicetree.c linux-imx6-3.14/drivers/pinctrl/devicetree.c
  202845. --- linux-3.14.14/drivers/pinctrl/devicetree.c 2014-07-28 10:07:25.000000000 -0500
  202846. +++ linux-imx6-3.14/drivers/pinctrl/devicetree.c 2014-12-08 00:31:54.008418001 -0600
  202847. @@ -18,6 +18,7 @@
  202848. #include <linux/device.h>
  202849. #include <linux/of.h>
  202850. +#include <linux/of_gpio.h>
  202851. #include <linux/pinctrl/pinctrl.h>
  202852. #include <linux/slab.h>
  202853. @@ -172,6 +173,43 @@
  202854. return dt_remember_or_free_map(p, statename, NULL, map, 1);
  202855. }
  202856. +static int dt_gpio_assert_pinctrl(struct pinctrl *p)
  202857. +{
  202858. + struct device_node *np = p->dev->of_node;
  202859. + enum of_gpio_flags flags;
  202860. + int gpio;
  202861. + int index = 0;
  202862. + int ret;
  202863. +
  202864. + if (!of_find_property(np, "pinctrl-assert-gpios", NULL))
  202865. + return 0; /* Missing the property, so nothing to be done */
  202866. +
  202867. + for (;; index++) {
  202868. + gpio = of_get_named_gpio_flags(np, "pinctrl-assert-gpios",
  202869. + index, &flags);
  202870. + if (gpio < 0)
  202871. + break; /* End of the phandle list */
  202872. +
  202873. + if (!gpio_is_valid(gpio))
  202874. + return -EINVAL;
  202875. +
  202876. + ret = devm_gpio_request_one(p->dev, gpio, GPIOF_OUT_INIT_LOW,
  202877. + NULL);
  202878. + if (ret < 0)
  202879. + return ret;
  202880. +
  202881. + if (flags & OF_GPIO_ACTIVE_LOW)
  202882. + continue;
  202883. +
  202884. + if (gpio_cansleep(gpio))
  202885. + gpio_set_value_cansleep(gpio, 1);
  202886. + else
  202887. + gpio_set_value(gpio, 1);
  202888. + }
  202889. +
  202890. + return 0;
  202891. +}
  202892. +
  202893. int pinctrl_dt_to_map(struct pinctrl *p)
  202894. {
  202895. struct device_node *np = p->dev->of_node;
  202896. @@ -190,6 +228,12 @@
  202897. return 0;
  202898. }
  202899. + ret = dt_gpio_assert_pinctrl(p);
  202900. + if (ret) {
  202901. + dev_dbg(p->dev, "failed to assert pinctrl setting: %d\n", ret);
  202902. + return ret;
  202903. + }
  202904. +
  202905. /* We may store pointers to property names within the node */
  202906. of_node_get(np);
  202907. diff -Nur linux-3.14.14/drivers/pinctrl/pinctrl-imx6sl.c linux-imx6-3.14/drivers/pinctrl/pinctrl-imx6sl.c
  202908. --- linux-3.14.14/drivers/pinctrl/pinctrl-imx6sl.c 2014-07-28 10:07:25.000000000 -0500
  202909. +++ linux-imx6-3.14/drivers/pinctrl/pinctrl-imx6sl.c 2014-12-08 00:31:54.016418001 -0600
  202910. @@ -384,6 +384,10 @@
  202911. },
  202912. .probe = imx6sl_pinctrl_probe,
  202913. .remove = imx_pinctrl_remove,
  202914. +#ifdef CONFIG_PM
  202915. + .suspend = imx_pinctrl_suspend,
  202916. + .resume = imx_pinctrl_resume,
  202917. +#endif
  202918. };
  202919. static int __init imx6sl_pinctrl_init(void)
  202920. diff -Nur linux-3.14.14/drivers/pinctrl/pinctrl-imx.c linux-imx6-3.14/drivers/pinctrl/pinctrl-imx.c
  202921. --- linux-3.14.14/drivers/pinctrl/pinctrl-imx.c 2014-07-28 10:07:25.000000000 -0500
  202922. +++ linux-imx6-3.14/drivers/pinctrl/pinctrl-imx.c 2014-12-08 00:31:54.012418001 -0600
  202923. @@ -1,7 +1,7 @@
  202924. /*
  202925. * Core driver for the imx pin controller
  202926. *
  202927. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  202928. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  202929. * Copyright (C) 2012 Linaro Ltd.
  202930. *
  202931. * Author: Dong Aisheng <dong.aisheng@linaro.org>
  202932. @@ -628,3 +628,25 @@
  202933. return 0;
  202934. }
  202935. +
  202936. +#ifdef CONFIG_PM
  202937. +int imx_pinctrl_suspend(struct platform_device *pdev, pm_message_t state)
  202938. +{
  202939. + struct imx_pinctrl *ipctl = platform_get_drvdata(pdev);
  202940. +
  202941. + if (!ipctl)
  202942. + return -EINVAL;
  202943. +
  202944. + return pinctrl_force_sleep(ipctl->pctl);
  202945. +}
  202946. +
  202947. +int imx_pinctrl_resume(struct platform_device *pdev)
  202948. +{
  202949. + struct imx_pinctrl *ipctl = platform_get_drvdata(pdev);
  202950. +
  202951. + if (!ipctl)
  202952. + return -EINVAL;
  202953. +
  202954. + return pinctrl_force_default(ipctl->pctl);
  202955. +}
  202956. +#endif
  202957. diff -Nur linux-3.14.14/drivers/pinctrl/pinctrl-imx.h linux-imx6-3.14/drivers/pinctrl/pinctrl-imx.h
  202958. --- linux-3.14.14/drivers/pinctrl/pinctrl-imx.h 2014-07-28 10:07:25.000000000 -0500
  202959. +++ linux-imx6-3.14/drivers/pinctrl/pinctrl-imx.h 2014-12-08 00:31:54.012418001 -0600
  202960. @@ -1,7 +1,7 @@
  202961. /*
  202962. * IMX pinmux core definitions
  202963. *
  202964. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  202965. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  202966. * Copyright (C) 2012 Linaro Ltd.
  202967. *
  202968. * Author: Dong Aisheng <dong.aisheng@linaro.org>
  202969. @@ -98,4 +98,8 @@
  202970. int imx_pinctrl_probe(struct platform_device *pdev,
  202971. struct imx_pinctrl_soc_info *info);
  202972. int imx_pinctrl_remove(struct platform_device *pdev);
  202973. +#ifdef CONFIG_PM
  202974. +int imx_pinctrl_suspend(struct platform_device *pdev, pm_message_t state);
  202975. +int imx_pinctrl_resume(struct platform_device *pdev);
  202976. +#endif
  202977. #endif /* __DRIVERS_PINCTRL_IMX_H */
  202978. diff -Nur linux-3.14.14/drivers/power/imx6_usb_charger.c linux-imx6-3.14/drivers/power/imx6_usb_charger.c
  202979. --- linux-3.14.14/drivers/power/imx6_usb_charger.c 1969-12-31 18:00:00.000000000 -0600
  202980. +++ linux-imx6-3.14/drivers/power/imx6_usb_charger.c 2014-12-08 00:31:54.052418001 -0600
  202981. @@ -0,0 +1,294 @@
  202982. +/*
  202983. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  202984. + *
  202985. + * The code contained herein is licensed under the GNU General Public
  202986. + * License. You may obtain a copy of the GNU General Public License
  202987. + * Version 2 or later at the following locations:
  202988. + *
  202989. + * http://www.opensource.org/licenses/gpl-license.html
  202990. + * http://www.gnu.org/copyleft/gpl.html
  202991. + */
  202992. +
  202993. +#include <linux/delay.h>
  202994. +#include <linux/device.h>
  202995. +#include <linux/power/imx6_usb_charger.h>
  202996. +#include <linux/regmap.h>
  202997. +
  202998. +#define HW_ANADIG_REG_3P0_SET (0x00000124)
  202999. +#define HW_ANADIG_REG_3P0_CLR (0x00000128)
  203000. +#define BM_ANADIG_REG_3P0_ENABLE_ILIMIT 0x00000004
  203001. +#define BM_ANADIG_REG_3P0_ENABLE_LINREG 0x00000001
  203002. +
  203003. +#define HW_ANADIG_USB1_CHRG_DETECT_SET (0x000001b4)
  203004. +#define HW_ANADIG_USB1_CHRG_DETECT_CLR (0x000001b8)
  203005. +
  203006. +#define BM_ANADIG_USB1_CHRG_DETECT_EN_B 0x00100000
  203007. +#define BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B 0x00080000
  203008. +#define BM_ANADIG_USB1_CHRG_DETECT_CHK_CONTACT 0x00040000
  203009. +
  203010. +#define HW_ANADIG_USB1_VBUS_DET_STAT (0x000001c0)
  203011. +
  203012. +#define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID 0x00000008
  203013. +
  203014. +#define HW_ANADIG_USB1_CHRG_DET_STAT (0x000001d0)
  203015. +
  203016. +#define BM_ANADIG_USB1_CHRG_DET_STAT_DM_STATE 0x00000004
  203017. +#define BM_ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED 0x00000002
  203018. +#define BM_ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT 0x00000001
  203019. +
  203020. +static char *imx6_usb_charger_supplied_to[] = {
  203021. + "imx6_usb_charger",
  203022. +};
  203023. +
  203024. +static enum power_supply_property imx6_usb_charger_power_props[] = {
  203025. + POWER_SUPPLY_PROP_PRESENT, /* Charger detected */
  203026. + POWER_SUPPLY_PROP_ONLINE, /* VBUS online */
  203027. + POWER_SUPPLY_PROP_CURRENT_MAX, /* Maximum current in mA */
  203028. +};
  203029. +
  203030. +static int imx6_usb_charger_get_property(struct power_supply *psy,
  203031. + enum power_supply_property psp,
  203032. + union power_supply_propval *val)
  203033. +{
  203034. + struct usb_charger *charger =
  203035. + container_of(psy, struct usb_charger, psy);
  203036. +
  203037. + switch (psp) {
  203038. + case POWER_SUPPLY_PROP_PRESENT:
  203039. + val->intval = charger->present;
  203040. + break;
  203041. + case POWER_SUPPLY_PROP_ONLINE:
  203042. + val->intval = charger->online;
  203043. + break;
  203044. + case POWER_SUPPLY_PROP_CURRENT_MAX:
  203045. + val->intval = charger->max_current;
  203046. + break;
  203047. + default:
  203048. + return -EINVAL;
  203049. + }
  203050. + return 0;
  203051. +}
  203052. +
  203053. +static void disable_charger_detector(struct regmap *regmap)
  203054. +{
  203055. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_SET,
  203056. + BM_ANADIG_USB1_CHRG_DETECT_EN_B |
  203057. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
  203058. +}
  203059. +
  203060. +static void disable_current_limiter(struct regmap *regmap)
  203061. +{
  203062. + /* Disable the vdd3p0 current limiter */
  203063. + regmap_write(regmap, HW_ANADIG_REG_3P0_CLR,
  203064. + BM_ANADIG_REG_3P0_ENABLE_ILIMIT);
  203065. +}
  203066. +
  203067. +/* Return value if the charger is present */
  203068. +static int imx6_usb_charger_detect(struct usb_charger *charger)
  203069. +{
  203070. + struct regmap *regmap = charger->anatop;
  203071. + u32 val;
  203072. + int i, data_pin_contact_count = 0;
  203073. +
  203074. + /* Enable the vdd3p0 curret limiter */
  203075. + regmap_write(regmap, HW_ANADIG_REG_3P0_SET,
  203076. + BM_ANADIG_REG_3P0_ENABLE_LINREG |
  203077. + BM_ANADIG_REG_3P0_ENABLE_ILIMIT);
  203078. +
  203079. + /* check if vbus is valid */
  203080. + regmap_read(regmap, HW_ANADIG_USB1_VBUS_DET_STAT, &val);
  203081. + if (!(val & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)) {
  203082. + dev_err(charger->dev, "vbus is error\n");
  203083. + disable_current_limiter(regmap);
  203084. + return -EINVAL;
  203085. + }
  203086. +
  203087. + /* Enable charger detector */
  203088. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_CLR,
  203089. + BM_ANADIG_USB1_CHRG_DETECT_EN_B);
  203090. + /*
  203091. + * - Do not check whether a charger is connected to the USB port
  203092. + * - Check whether the USB plug has been in contact with each other
  203093. + */
  203094. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_SET,
  203095. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
  203096. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
  203097. +
  203098. + /* Check if plug is connected */
  203099. + for (i = 0; i < 100; i = i + 1) {
  203100. + regmap_read(regmap, HW_ANADIG_USB1_CHRG_DET_STAT, &val);
  203101. + if (val & BM_ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT) {
  203102. + if (data_pin_contact_count++ > 5)
  203103. + /* Data pin makes contact */
  203104. + break;
  203105. + } else {
  203106. + msleep(20);
  203107. + }
  203108. + }
  203109. +
  203110. + if (i == 100) {
  203111. + dev_err(charger->dev,
  203112. + "VBUS is coming from a dedicated power supply.\n");
  203113. + disable_current_limiter(regmap);
  203114. + disable_charger_detector(regmap);
  203115. + return -ENXIO;
  203116. + }
  203117. +
  203118. + /*
  203119. + * - Do check whether a charger is connected to the USB port
  203120. + * - Do not Check whether the USB plug has been in contact with
  203121. + * each other
  203122. + */
  203123. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_CLR,
  203124. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
  203125. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
  203126. + msleep(45);
  203127. +
  203128. + /* Check if it is a charger */
  203129. + regmap_read(regmap, HW_ANADIG_USB1_CHRG_DET_STAT, &val);
  203130. + if (!(val & BM_ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED)) {
  203131. + dev_dbg(charger->dev, "It is a stardard downstream port\n");
  203132. + charger->psy.type = POWER_SUPPLY_TYPE_USB;
  203133. + charger->max_current = 500;
  203134. + disable_charger_detector(regmap);
  203135. + } else {
  203136. + /* It is a charger */
  203137. + disable_charger_detector(regmap);
  203138. + msleep(45);
  203139. + }
  203140. +
  203141. + disable_current_limiter(regmap);
  203142. +
  203143. + return 0;
  203144. +}
  203145. +
  203146. +/*
  203147. + * imx6_usb_vbus_connect - inform about VBUS connection
  203148. + * @charger: the usb charger
  203149. + *
  203150. + * Inform the charger VBUS is connected, vbus detect supplier should call it.
  203151. + * Besides, the USB device controller is expected to keep the dataline
  203152. + * pullups disabled.
  203153. + */
  203154. +int imx6_usb_vbus_connect(struct usb_charger *charger)
  203155. +{
  203156. + int ret;
  203157. +
  203158. + charger->online = 1;
  203159. +
  203160. + mutex_lock(&charger->lock);
  203161. +
  203162. + /* Start the 1st period charger detection. */
  203163. + ret = imx6_usb_charger_detect(charger);
  203164. + if (ret)
  203165. + dev_err(charger->dev,
  203166. + "Error occurs during detection: %d\n",
  203167. + ret);
  203168. + else
  203169. + charger->present = 1;
  203170. +
  203171. + mutex_unlock(&charger->lock);
  203172. +
  203173. + return ret;
  203174. +}
  203175. +EXPORT_SYMBOL(imx6_usb_vbus_connect);
  203176. +
  203177. +/*
  203178. + * It must be called after dp is pulled up (from USB controller driver),
  203179. + * That is used to differentiate DCP and CDP
  203180. + */
  203181. +int imx6_usb_charger_detect_post(struct usb_charger *charger)
  203182. +{
  203183. + struct regmap *regmap = charger->anatop;
  203184. + int val;
  203185. +
  203186. + mutex_lock(&charger->lock);
  203187. +
  203188. + msleep(40);
  203189. +
  203190. + regmap_read(regmap, HW_ANADIG_USB1_CHRG_DET_STAT, &val);
  203191. + if (val & BM_ANADIG_USB1_CHRG_DET_STAT_DM_STATE) {
  203192. + dev_dbg(charger->dev, "It is a dedicate charging port\n");
  203193. + charger->psy.type = POWER_SUPPLY_TYPE_USB_DCP;
  203194. + charger->max_current = 1500;
  203195. + } else {
  203196. + dev_dbg(charger->dev, "It is a charging downstream port\n");
  203197. + charger->psy.type = POWER_SUPPLY_TYPE_USB_CDP;
  203198. + charger->max_current = 900;
  203199. + }
  203200. +
  203201. + power_supply_changed(&charger->psy);
  203202. +
  203203. + mutex_unlock(&charger->lock);
  203204. +
  203205. + return 0;
  203206. +}
  203207. +EXPORT_SYMBOL(imx6_usb_charger_detect_post);
  203208. +
  203209. +/*
  203210. + * imx6_usb_vbus_disconnect - inform about VBUS disconnection
  203211. + * @charger: the usb charger
  203212. + *
  203213. + * Inform the charger that VBUS is disconnected. The charging will be
  203214. + * stopped and the charger properties cleared.
  203215. + */
  203216. +int imx6_usb_vbus_disconnect(struct usb_charger *charger)
  203217. +{
  203218. + charger->online = 0;
  203219. + charger->present = 0;
  203220. + charger->max_current = 0;
  203221. + charger->psy.type = POWER_SUPPLY_TYPE_MAINS;
  203222. +
  203223. + power_supply_changed(&charger->psy);
  203224. +
  203225. + return 0;
  203226. +}
  203227. +EXPORT_SYMBOL(imx6_usb_vbus_disconnect);
  203228. +
  203229. +/*
  203230. + * imx6_usb_create_charger - create a USB charger
  203231. + * @charger: the charger to be initialized
  203232. + * @name: name for the power supply
  203233. +
  203234. + * Registers a power supply for the charger. The USB Controller
  203235. + * driver will call this after filling struct usb_charger.
  203236. + */
  203237. +int imx6_usb_create_charger(struct usb_charger *charger,
  203238. + const char *name)
  203239. +{
  203240. + struct power_supply *psy = &charger->psy;
  203241. +
  203242. + if (!charger->dev)
  203243. + return -EINVAL;
  203244. +
  203245. + if (name)
  203246. + psy->name = name;
  203247. + else
  203248. + psy->name = "imx6_usb_charger";
  203249. +
  203250. + charger->bc = BATTERY_CHARGING_SPEC_1_2;
  203251. + mutex_init(&charger->lock);
  203252. +
  203253. + psy->type = POWER_SUPPLY_TYPE_MAINS;
  203254. + psy->properties = imx6_usb_charger_power_props;
  203255. + psy->num_properties = ARRAY_SIZE(imx6_usb_charger_power_props);
  203256. + psy->get_property = imx6_usb_charger_get_property;
  203257. + psy->supplied_to = imx6_usb_charger_supplied_to;
  203258. + psy->num_supplicants = sizeof(imx6_usb_charger_supplied_to)
  203259. + / sizeof(char *);
  203260. +
  203261. + return power_supply_register(charger->dev, psy);
  203262. +}
  203263. +EXPORT_SYMBOL(imx6_usb_create_charger);
  203264. +
  203265. +/*
  203266. + * imx6_usb_remove_charger - remove a USB charger
  203267. + * @charger: the charger to be removed
  203268. + *
  203269. + * Unregister the chargers power supply.
  203270. + */
  203271. +void imx6_usb_remove_charger(struct usb_charger *charger)
  203272. +{
  203273. + power_supply_unregister(&charger->psy);
  203274. +}
  203275. +EXPORT_SYMBOL(imx6_usb_remove_charger);
  203276. diff -Nur linux-3.14.14/drivers/power/Kconfig linux-imx6-3.14/drivers/power/Kconfig
  203277. --- linux-3.14.14/drivers/power/Kconfig 2014-07-28 10:07:25.000000000 -0500
  203278. +++ linux-imx6-3.14/drivers/power/Kconfig 2014-12-08 00:31:54.048418001 -0600
  203279. @@ -389,6 +389,12 @@
  203280. Say Y to enable support for the battery and AC power in the
  203281. Goldfish emulator.
  203282. +config IMX6_USB_CHARGER
  203283. + bool "Freescale imx6 USB Charger"
  203284. + depends on SOC_IMX6Q || SOC_IMX6SL
  203285. + help
  203286. + Say Y to enable Freescale imx6 USB Charger Detect.
  203287. +
  203288. source "drivers/power/reset/Kconfig"
  203289. endif # POWER_SUPPLY
  203290. diff -Nur linux-3.14.14/drivers/power/Makefile linux-imx6-3.14/drivers/power/Makefile
  203291. --- linux-3.14.14/drivers/power/Makefile 2014-07-28 10:07:25.000000000 -0500
  203292. +++ linux-imx6-3.14/drivers/power/Makefile 2014-12-08 00:31:54.048418001 -0600
  203293. @@ -58,3 +58,4 @@
  203294. obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
  203295. obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
  203296. obj-$(CONFIG_POWER_RESET) += reset/
  203297. +obj-$(CONFIG_IMX6_USB_CHARGER) += imx6_usb_charger.o
  203298. diff -Nur linux-3.14.14/drivers/ptp/ptp_chardev.c linux-imx6-3.14/drivers/ptp/ptp_chardev.c
  203299. --- linux-3.14.14/drivers/ptp/ptp_chardev.c 2014-07-28 10:07:25.000000000 -0500
  203300. +++ linux-imx6-3.14/drivers/ptp/ptp_chardev.c 2014-12-08 00:31:54.060418001 -0600
  203301. @@ -25,6 +25,96 @@
  203302. #include "ptp_private.h"
  203303. +static int ptp_disable_pinfunc(struct ptp_clock_info *ops,
  203304. + enum ptp_pin_function func, unsigned int chan)
  203305. +{
  203306. + struct ptp_clock_request rq;
  203307. + int err = 0;
  203308. +
  203309. + memset(&rq, 0, sizeof(rq));
  203310. +
  203311. + switch (func) {
  203312. + case PTP_PF_NONE:
  203313. + break;
  203314. + case PTP_PF_EXTTS:
  203315. + rq.type = PTP_CLK_REQ_EXTTS;
  203316. + rq.extts.index = chan;
  203317. + err = ops->enable(ops, &rq, 0);
  203318. + break;
  203319. + case PTP_PF_PEROUT:
  203320. + rq.type = PTP_CLK_REQ_PEROUT;
  203321. + rq.perout.index = chan;
  203322. + err = ops->enable(ops, &rq, 0);
  203323. + break;
  203324. + case PTP_PF_PHYSYNC:
  203325. + break;
  203326. + default:
  203327. + return -EINVAL;
  203328. + }
  203329. +
  203330. + return err;
  203331. +}
  203332. +
  203333. +int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
  203334. + enum ptp_pin_function func, unsigned int chan)
  203335. +{
  203336. + struct ptp_clock_info *info = ptp->info;
  203337. + struct ptp_pin_desc *pin1 = NULL, *pin2 = &info->pin_config[pin];
  203338. + unsigned int i;
  203339. +
  203340. + /* Check to see if any other pin previously had this function. */
  203341. + for (i = 0; i < info->n_pins; i++) {
  203342. + if (info->pin_config[i].func == func &&
  203343. + info->pin_config[i].chan == chan) {
  203344. + pin1 = &info->pin_config[i];
  203345. + break;
  203346. + }
  203347. + }
  203348. + if (pin1 && i == pin)
  203349. + return 0;
  203350. +
  203351. + /* Check the desired function and channel. */
  203352. + switch (func) {
  203353. + case PTP_PF_NONE:
  203354. + break;
  203355. + case PTP_PF_EXTTS:
  203356. + if (chan >= info->n_ext_ts)
  203357. + return -EINVAL;
  203358. + break;
  203359. + case PTP_PF_PEROUT:
  203360. + if (chan >= info->n_per_out)
  203361. + return -EINVAL;
  203362. + break;
  203363. + case PTP_PF_PHYSYNC:
  203364. + pr_err("sorry, cannot reassign the calibration pin\n");
  203365. + return -EINVAL;
  203366. + default:
  203367. + return -EINVAL;
  203368. + }
  203369. +
  203370. + if (pin2->func == PTP_PF_PHYSYNC) {
  203371. + pr_err("sorry, cannot reprogram the calibration pin\n");
  203372. + return -EINVAL;
  203373. + }
  203374. +
  203375. + if (info->verify(info, pin, func, chan)) {
  203376. + pr_err("driver cannot use function %u on pin %u\n", func, chan);
  203377. + return -EOPNOTSUPP;
  203378. + }
  203379. +
  203380. + /* Disable whatever function was previously assigned. */
  203381. + if (pin1) {
  203382. + ptp_disable_pinfunc(info, func, chan);
  203383. + pin1->func = PTP_PF_NONE;
  203384. + pin1->chan = 0;
  203385. + }
  203386. + ptp_disable_pinfunc(info, pin2->func, pin2->chan);
  203387. + pin2->func = func;
  203388. + pin2->chan = chan;
  203389. +
  203390. + return 0;
  203391. +}
  203392. +
  203393. int ptp_open(struct posix_clock *pc, fmode_t fmode)
  203394. {
  203395. return 0;
  203396. @@ -35,12 +125,13 @@
  203397. struct ptp_clock_caps caps;
  203398. struct ptp_clock_request req;
  203399. struct ptp_sys_offset *sysoff = NULL;
  203400. + struct ptp_pin_desc pd;
  203401. struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
  203402. struct ptp_clock_info *ops = ptp->info;
  203403. struct ptp_clock_time *pct;
  203404. struct timespec ts;
  203405. int enable, err = 0;
  203406. - unsigned int i;
  203407. + unsigned int i, pin_index;
  203408. switch (cmd) {
  203409. @@ -51,6 +142,7 @@
  203410. caps.n_ext_ts = ptp->info->n_ext_ts;
  203411. caps.n_per_out = ptp->info->n_per_out;
  203412. caps.pps = ptp->info->pps;
  203413. + caps.n_pins = ptp->info->n_pins;
  203414. if (copy_to_user((void __user *)arg, &caps, sizeof(caps)))
  203415. err = -EFAULT;
  203416. break;
  203417. @@ -126,6 +218,40 @@
  203418. err = -EFAULT;
  203419. break;
  203420. + case PTP_PIN_GETFUNC:
  203421. + if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
  203422. + err = -EFAULT;
  203423. + break;
  203424. + }
  203425. + pin_index = pd.index;
  203426. + if (pin_index >= ops->n_pins) {
  203427. + err = -EINVAL;
  203428. + break;
  203429. + }
  203430. + if (mutex_lock_interruptible(&ptp->pincfg_mux))
  203431. + return -ERESTARTSYS;
  203432. + pd = ops->pin_config[pin_index];
  203433. + mutex_unlock(&ptp->pincfg_mux);
  203434. + if (!err && copy_to_user((void __user *)arg, &pd, sizeof(pd)))
  203435. + err = -EFAULT;
  203436. + break;
  203437. +
  203438. + case PTP_PIN_SETFUNC:
  203439. + if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
  203440. + err = -EFAULT;
  203441. + break;
  203442. + }
  203443. + pin_index = pd.index;
  203444. + if (pin_index >= ops->n_pins) {
  203445. + err = -EINVAL;
  203446. + break;
  203447. + }
  203448. + if (mutex_lock_interruptible(&ptp->pincfg_mux))
  203449. + return -ERESTARTSYS;
  203450. + err = ptp_set_pinfunc(ptp, pin_index, pd.func, pd.chan);
  203451. + mutex_unlock(&ptp->pincfg_mux);
  203452. + break;
  203453. +
  203454. default:
  203455. err = -ENOTTY;
  203456. break;
  203457. diff -Nur linux-3.14.14/drivers/ptp/ptp_clock.c linux-imx6-3.14/drivers/ptp/ptp_clock.c
  203458. --- linux-3.14.14/drivers/ptp/ptp_clock.c 2014-07-28 10:07:25.000000000 -0500
  203459. +++ linux-imx6-3.14/drivers/ptp/ptp_clock.c 2014-12-08 00:31:54.060418001 -0600
  203460. @@ -169,6 +169,7 @@
  203461. struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
  203462. mutex_destroy(&ptp->tsevq_mux);
  203463. + mutex_destroy(&ptp->pincfg_mux);
  203464. ida_simple_remove(&ptp_clocks_map, ptp->index);
  203465. kfree(ptp);
  203466. }
  203467. @@ -203,6 +204,7 @@
  203468. ptp->index = index;
  203469. spin_lock_init(&ptp->tsevq.lock);
  203470. mutex_init(&ptp->tsevq_mux);
  203471. + mutex_init(&ptp->pincfg_mux);
  203472. init_waitqueue_head(&ptp->tsev_wq);
  203473. /* Create a new device in our class. */
  203474. @@ -249,6 +251,7 @@
  203475. device_destroy(ptp_class, ptp->devid);
  203476. no_device:
  203477. mutex_destroy(&ptp->tsevq_mux);
  203478. + mutex_destroy(&ptp->pincfg_mux);
  203479. no_slot:
  203480. kfree(ptp);
  203481. no_memory:
  203482. @@ -305,6 +308,26 @@
  203483. }
  203484. EXPORT_SYMBOL(ptp_clock_index);
  203485. +int ptp_find_pin(struct ptp_clock *ptp,
  203486. + enum ptp_pin_function func, unsigned int chan)
  203487. +{
  203488. + struct ptp_pin_desc *pin = NULL;
  203489. + int i;
  203490. +
  203491. + mutex_lock(&ptp->pincfg_mux);
  203492. + for (i = 0; i < ptp->info->n_pins; i++) {
  203493. + if (ptp->info->pin_config[i].func == func &&
  203494. + ptp->info->pin_config[i].chan == chan) {
  203495. + pin = &ptp->info->pin_config[i];
  203496. + break;
  203497. + }
  203498. + }
  203499. + mutex_unlock(&ptp->pincfg_mux);
  203500. +
  203501. + return pin ? i : -1;
  203502. +}
  203503. +EXPORT_SYMBOL(ptp_find_pin);
  203504. +
  203505. /* module operations */
  203506. static void __exit ptp_exit(void)
  203507. diff -Nur linux-3.14.14/drivers/ptp/ptp_ixp46x.c linux-imx6-3.14/drivers/ptp/ptp_ixp46x.c
  203508. --- linux-3.14.14/drivers/ptp/ptp_ixp46x.c 2014-07-28 10:07:25.000000000 -0500
  203509. +++ linux-imx6-3.14/drivers/ptp/ptp_ixp46x.c 2014-12-08 00:31:54.060418001 -0600
  203510. @@ -244,6 +244,7 @@
  203511. .name = "IXP46X timer",
  203512. .max_adj = 66666655,
  203513. .n_ext_ts = N_EXT_TS,
  203514. + .n_pins = 0,
  203515. .pps = 0,
  203516. .adjfreq = ptp_ixp_adjfreq,
  203517. .adjtime = ptp_ixp_adjtime,
  203518. diff -Nur linux-3.14.14/drivers/ptp/ptp_pch.c linux-imx6-3.14/drivers/ptp/ptp_pch.c
  203519. --- linux-3.14.14/drivers/ptp/ptp_pch.c 2014-07-28 10:07:25.000000000 -0500
  203520. +++ linux-imx6-3.14/drivers/ptp/ptp_pch.c 2014-12-08 00:31:54.060418001 -0600
  203521. @@ -514,6 +514,7 @@
  203522. .name = "PCH timer",
  203523. .max_adj = 50000000,
  203524. .n_ext_ts = N_EXT_TS,
  203525. + .n_pins = 0,
  203526. .pps = 0,
  203527. .adjfreq = ptp_pch_adjfreq,
  203528. .adjtime = ptp_pch_adjtime,
  203529. diff -Nur linux-3.14.14/drivers/ptp/ptp_private.h linux-imx6-3.14/drivers/ptp/ptp_private.h
  203530. --- linux-3.14.14/drivers/ptp/ptp_private.h 2014-07-28 10:07:25.000000000 -0500
  203531. +++ linux-imx6-3.14/drivers/ptp/ptp_private.h 2014-12-08 00:31:54.060418001 -0600
  203532. @@ -48,6 +48,7 @@
  203533. long dialed_frequency; /* remembers the frequency adjustment */
  203534. struct timestamp_event_queue tsevq; /* simple fifo for time stamps */
  203535. struct mutex tsevq_mux; /* one process at a time reading the fifo */
  203536. + struct mutex pincfg_mux; /* protect concurrent info->pin_config access */
  203537. wait_queue_head_t tsev_wq;
  203538. int defunct; /* tells readers to go away when clock is being removed */
  203539. };
  203540. @@ -69,6 +70,10 @@
  203541. * see ptp_chardev.c
  203542. */
  203543. +/* caller must hold pincfg_mux */
  203544. +int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
  203545. + enum ptp_pin_function func, unsigned int chan);
  203546. +
  203547. long ptp_ioctl(struct posix_clock *pc,
  203548. unsigned int cmd, unsigned long arg);
  203549. diff -Nur linux-3.14.14/drivers/pwm/pwm-imx.c linux-imx6-3.14/drivers/pwm/pwm-imx.c
  203550. --- linux-3.14.14/drivers/pwm/pwm-imx.c 2014-07-28 10:07:25.000000000 -0500
  203551. +++ linux-imx6-3.14/drivers/pwm/pwm-imx.c 2014-12-08 00:31:54.060418001 -0600
  203552. @@ -1,4 +1,5 @@
  203553. /*
  203554. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  203555. * simple driver for PWM (Pulse Width Modulator) controller
  203556. *
  203557. * This program is free software; you can redistribute it and/or modify
  203558. @@ -293,11 +294,34 @@
  203559. return pwmchip_remove(&imx->chip);
  203560. }
  203561. +#ifdef CONFIG_PM
  203562. +static int imx_pwm_suspend(struct device *dev)
  203563. +{
  203564. + pinctrl_pm_select_sleep_state(dev);
  203565. +
  203566. + return 0;
  203567. +}
  203568. +
  203569. +static int imx_pwm_resume(struct device *dev)
  203570. +{
  203571. + pinctrl_pm_select_default_state(dev);
  203572. +
  203573. + return 0;
  203574. +}
  203575. +
  203576. +static const struct dev_pm_ops imx_pwm_pm_ops = {
  203577. + SET_SYSTEM_SLEEP_PM_OPS(imx_pwm_suspend, imx_pwm_resume)
  203578. +};
  203579. +#endif
  203580. +
  203581. static struct platform_driver imx_pwm_driver = {
  203582. .driver = {
  203583. .name = "imx-pwm",
  203584. .owner = THIS_MODULE,
  203585. .of_match_table = imx_pwm_dt_ids,
  203586. +#ifdef CONFIG_PM
  203587. + .pm = &imx_pwm_pm_ops,
  203588. +#endif
  203589. },
  203590. .probe = imx_pwm_probe,
  203591. .remove = imx_pwm_remove,
  203592. diff -Nur linux-3.14.14/drivers/regulator/anatop-regulator.c linux-imx6-3.14/drivers/regulator/anatop-regulator.c
  203593. --- linux-3.14.14/drivers/regulator/anatop-regulator.c 2014-07-28 10:07:25.000000000 -0500
  203594. +++ linux-imx6-3.14/drivers/regulator/anatop-regulator.c 2014-12-08 00:31:54.068418001 -0600
  203595. @@ -1,5 +1,5 @@
  203596. /*
  203597. - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
  203598. + * Copyright (C) 2011, 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  203599. */
  203600. /*
  203601. @@ -34,6 +34,22 @@
  203602. #define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */
  203603. #define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */
  203604. +#define REG_SET 0x4
  203605. +#define REG_CLR 0x8
  203606. +#define SOC_PU_FIELD_OFFSET 0x9
  203607. +
  203608. +/*
  203609. + * for CORE, SOC and PU regulator, the register field
  203610. + * has following definition: 00001 -- Target core voltage
  203611. + * = 0.725V, which means the lowest setting in this
  203612. + * field is 0.725V once the regulator is enabled. So
  203613. + * when these regulators are turned on from off status,
  203614. + * we need to count the voltage step of 0V to 0.7V, it will
  203615. + * need additional delay, so the additional step number is
  203616. + * 700mV / 25mV = 28.
  203617. + */
  203618. +#define CORE_REG_ENABLE_STEP_ADD 28
  203619. +
  203620. struct anatop_regulator {
  203621. const char *name;
  203622. u32 control_reg;
  203623. @@ -97,12 +113,86 @@
  203624. return regulator_get_voltage_sel_regmap(reg);
  203625. }
  203626. +/*
  203627. + * currently on anatop regulators, only PU regulator supports
  203628. + * enable/disable function, and its voltage must be equal
  203629. + * to SOC voltage, so we need to get SOC voltage then set
  203630. + * into PU regulator. Other regulators are always on due
  203631. + * to hardware design, so enable/disable/is_enabled/enable_time
  203632. + * functions are only used by PU regulator.
  203633. + */
  203634. +static int anatop_regmap_enable(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. + val &= ((1 << anatop_reg->vol_bit_width) - 1) <<
  203644. + (anatop_reg->vol_bit_shift + SOC_PU_FIELD_OFFSET);
  203645. + regmap_write(anatop_reg->anatop, anatop_reg->control_reg +
  203646. + REG_SET, val >> SOC_PU_FIELD_OFFSET);
  203647. +
  203648. + return 0;
  203649. +}
  203650. +
  203651. +static int anatop_regmap_disable(struct regulator_dev *reg)
  203652. +{
  203653. + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  203654. +
  203655. + if (!anatop_reg->control_reg)
  203656. + return -ENOTSUPP;
  203657. +
  203658. + regmap_write(anatop_reg->anatop, anatop_reg->control_reg +
  203659. + REG_CLR, ((1 << anatop_reg->vol_bit_width) - 1) <<
  203660. + anatop_reg->vol_bit_shift);
  203661. +
  203662. + return 0;
  203663. +}
  203664. +
  203665. +static int anatop_regmap_is_enabled(struct regulator_dev *reg)
  203666. +{
  203667. + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  203668. + u32 val;
  203669. +
  203670. + if (!anatop_reg->control_reg)
  203671. + return -ENOTSUPP;
  203672. +
  203673. + regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
  203674. +
  203675. + return (val >> anatop_reg->vol_bit_shift) &
  203676. + ((1 << anatop_reg->vol_bit_width) - 1) ? 1 : 0;
  203677. +}
  203678. +
  203679. +static int anatop_regmap_enable_time(struct regulator_dev *reg)
  203680. +{
  203681. + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  203682. + u32 val, soc_val;
  203683. +
  203684. + if (!anatop_reg->control_reg)
  203685. + return -ENOTSUPP;
  203686. +
  203687. + regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
  203688. + soc_val = (val >> (anatop_reg->vol_bit_shift +
  203689. + SOC_PU_FIELD_OFFSET)) &
  203690. + ((1 << anatop_reg->vol_bit_width) - 1);
  203691. +
  203692. + return anatop_regmap_set_voltage_time_sel(reg, 0,
  203693. + soc_val + CORE_REG_ENABLE_STEP_ADD);
  203694. +}
  203695. +
  203696. static struct regulator_ops anatop_rops = {
  203697. .set_voltage_sel = anatop_regmap_set_voltage_sel,
  203698. .set_voltage_time_sel = anatop_regmap_set_voltage_time_sel,
  203699. .get_voltage_sel = anatop_regmap_get_voltage_sel,
  203700. + .enable = anatop_regmap_enable,
  203701. + .disable = anatop_regmap_disable,
  203702. + .is_enabled = anatop_regmap_is_enabled,
  203703. .list_voltage = regulator_list_voltage_linear,
  203704. .map_voltage = regulator_map_voltage_linear,
  203705. + .enable_time = anatop_regmap_enable_time,
  203706. };
  203707. static int anatop_regulator_probe(struct platform_device *pdev)
  203708. @@ -196,6 +286,7 @@
  203709. config.driver_data = sreg;
  203710. config.of_node = pdev->dev.of_node;
  203711. config.regmap = sreg->anatop;
  203712. + config.ena_gpio = -EINVAL;
  203713. /* register regulator */
  203714. rdev = devm_regulator_register(dev, rdesc, &config);
  203715. diff -Nur linux-3.14.14/drivers/regulator/core.c linux-imx6-3.14/drivers/regulator/core.c
  203716. --- linux-3.14.14/drivers/regulator/core.c 2014-07-28 10:07:25.000000000 -0500
  203717. +++ linux-imx6-3.14/drivers/regulator/core.c 2014-12-08 00:31:54.068418001 -0600
  203718. @@ -3,6 +3,7 @@
  203719. *
  203720. * Copyright 2007, 2008 Wolfson Microelectronics PLC.
  203721. * Copyright 2008 SlimLogic Ltd.
  203722. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  203723. *
  203724. * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  203725. *
  203726. @@ -24,6 +25,7 @@
  203727. #include <linux/suspend.h>
  203728. #include <linux/delay.h>
  203729. #include <linux/gpio.h>
  203730. +#include <linux/gpio/consumer.h>
  203731. #include <linux/of.h>
  203732. #include <linux/regmap.h>
  203733. #include <linux/regulator/of_regulator.h>
  203734. @@ -77,7 +79,7 @@
  203735. */
  203736. struct regulator_enable_gpio {
  203737. struct list_head list;
  203738. - int gpio;
  203739. + struct gpio_desc *gpiod;
  203740. u32 enable_count; /* a number of enabled shared GPIO */
  203741. u32 request_count; /* a number of requested shared GPIO */
  203742. unsigned int ena_gpio_invert:1;
  203743. @@ -1653,10 +1655,13 @@
  203744. const struct regulator_config *config)
  203745. {
  203746. struct regulator_enable_gpio *pin;
  203747. + struct gpio_desc *gpiod;
  203748. int ret;
  203749. + gpiod = gpio_to_desc(config->ena_gpio);
  203750. +
  203751. list_for_each_entry(pin, &regulator_ena_gpio_list, list) {
  203752. - if (pin->gpio == config->ena_gpio) {
  203753. + if (pin->gpiod == gpiod) {
  203754. rdev_dbg(rdev, "GPIO %d is already used\n",
  203755. config->ena_gpio);
  203756. goto update_ena_gpio_to_rdev;
  203757. @@ -1675,7 +1680,7 @@
  203758. return -ENOMEM;
  203759. }
  203760. - pin->gpio = config->ena_gpio;
  203761. + pin->gpiod = gpiod;
  203762. pin->ena_gpio_invert = config->ena_gpio_invert;
  203763. list_add(&pin->list, &regulator_ena_gpio_list);
  203764. @@ -1694,10 +1699,10 @@
  203765. /* Free the GPIO only in case of no use */
  203766. list_for_each_entry_safe(pin, n, &regulator_ena_gpio_list, list) {
  203767. - if (pin->gpio == rdev->ena_pin->gpio) {
  203768. + if (pin->gpiod == rdev->ena_pin->gpiod) {
  203769. if (pin->request_count <= 1) {
  203770. pin->request_count = 0;
  203771. - gpio_free(pin->gpio);
  203772. + gpiod_put(pin->gpiod);
  203773. list_del(&pin->list);
  203774. kfree(pin);
  203775. } else {
  203776. @@ -1725,8 +1730,8 @@
  203777. if (enable) {
  203778. /* Enable GPIO at initial use */
  203779. if (pin->enable_count == 0)
  203780. - gpio_set_value_cansleep(pin->gpio,
  203781. - !pin->ena_gpio_invert);
  203782. + gpiod_set_value_cansleep(pin->gpiod,
  203783. + !pin->ena_gpio_invert);
  203784. pin->enable_count++;
  203785. } else {
  203786. @@ -1737,8 +1742,8 @@
  203787. /* Disable GPIO if not used */
  203788. if (pin->enable_count <= 1) {
  203789. - gpio_set_value_cansleep(pin->gpio,
  203790. - pin->ena_gpio_invert);
  203791. + gpiod_set_value_cansleep(pin->gpiod,
  203792. + pin->ena_gpio_invert);
  203793. pin->enable_count = 0;
  203794. }
  203795. }
  203796. @@ -1815,6 +1820,7 @@
  203797. }
  203798. trace_regulator_enable_complete(rdev_get_name(rdev));
  203799. + _notifier_call_chain(rdev, REGULATOR_EVENT_ENABLE, NULL);
  203800. return 0;
  203801. }
  203802. @@ -1892,6 +1898,7 @@
  203803. {
  203804. int ret;
  203805. + _notifier_call_chain(rdev, REGULATOR_EVENT_PRE_DISABLE, NULL);
  203806. trace_regulator_disable(rdev_get_name(rdev));
  203807. if (rdev->ena_pin) {
  203808. @@ -2138,7 +2145,7 @@
  203809. * @regulator: regulator source
  203810. *
  203811. * Returns positive if the regulator driver backing the source/client
  203812. - * can change its voltage, false otherwise. Usefull for detecting fixed
  203813. + * can change its voltage, false otherwise. Useful for detecting fixed
  203814. * or dummy regulators and disabling voltage change logic in the client
  203815. * driver.
  203816. */
  203817. @@ -3445,7 +3452,7 @@
  203818. dev_set_drvdata(&rdev->dev, rdev);
  203819. - if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) {
  203820. + if (gpio_is_valid(config->ena_gpio)) {
  203821. ret = regulator_ena_gpio_request(rdev, config);
  203822. if (ret != 0) {
  203823. rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
  203824. diff -Nur linux-3.14.14/drivers/regulator/dummy.c linux-imx6-3.14/drivers/regulator/dummy.c
  203825. --- linux-3.14.14/drivers/regulator/dummy.c 2014-07-28 10:07:25.000000000 -0500
  203826. +++ linux-imx6-3.14/drivers/regulator/dummy.c 2014-12-08 00:31:54.068418001 -0600
  203827. @@ -44,6 +44,7 @@
  203828. config.dev = &pdev->dev;
  203829. config.init_data = &dummy_initdata;
  203830. + config.ena_gpio = -EINVAL;
  203831. dummy_regulator_rdev = regulator_register(&dummy_desc, &config);
  203832. if (IS_ERR(dummy_regulator_rdev)) {
  203833. diff -Nur linux-3.14.14/drivers/regulator/fixed.c linux-imx6-3.14/drivers/regulator/fixed.c
  203834. --- linux-3.14.14/drivers/regulator/fixed.c 2014-07-28 10:07:25.000000000 -0500
  203835. +++ linux-imx6-3.14/drivers/regulator/fixed.c 2014-12-08 00:31:54.068418001 -0600
  203836. @@ -163,9 +163,7 @@
  203837. drvdata->desc.n_voltages = 1;
  203838. drvdata->desc.fixed_uV = config->microvolts;
  203839. -
  203840. - if (config->gpio >= 0)
  203841. - cfg.ena_gpio = config->gpio;
  203842. + cfg.ena_gpio = config->gpio;
  203843. cfg.ena_gpio_invert = !config->enable_high;
  203844. if (config->enabled_at_boot) {
  203845. if (config->enable_high)
  203846. diff -Nur linux-3.14.14/drivers/reset/gpio-reset.c linux-imx6-3.14/drivers/reset/gpio-reset.c
  203847. --- linux-3.14.14/drivers/reset/gpio-reset.c 1969-12-31 18:00:00.000000000 -0600
  203848. +++ linux-imx6-3.14/drivers/reset/gpio-reset.c 2014-12-08 00:31:54.076418001 -0600
  203849. @@ -0,0 +1,187 @@
  203850. +/*
  203851. + * GPIO Reset Controller driver
  203852. + *
  203853. + * Copyright 2013 Philipp Zabel, Pengutronix
  203854. + *
  203855. + * This program is free software; you can redistribute it and/or modify
  203856. + * it under the terms of the GNU General Public License as published by
  203857. + * the Free Software Foundation; either version 2 of the License, or
  203858. + * (at your option) any later version.
  203859. + */
  203860. +#include <linux/delay.h>
  203861. +#include <linux/err.h>
  203862. +#include <linux/gpio.h>
  203863. +#include <linux/module.h>
  203864. +#include <linux/of_gpio.h>
  203865. +#include <linux/platform_device.h>
  203866. +#include <linux/reset-controller.h>
  203867. +
  203868. +struct gpio_reset_data {
  203869. + struct reset_controller_dev rcdev;
  203870. + unsigned int gpio;
  203871. + bool active_low;
  203872. + s32 delay_us;
  203873. +};
  203874. +
  203875. +static void gpio_reset_set(struct reset_controller_dev *rcdev, int asserted)
  203876. +{
  203877. + struct gpio_reset_data *drvdata = container_of(rcdev,
  203878. + struct gpio_reset_data, rcdev);
  203879. + int value = asserted;
  203880. +
  203881. + if (drvdata->active_low)
  203882. + value = !value;
  203883. +
  203884. + if (gpio_cansleep(drvdata->gpio))
  203885. + gpio_set_value_cansleep(drvdata->gpio, value);
  203886. + else
  203887. + gpio_set_value(drvdata->gpio, value);
  203888. +}
  203889. +
  203890. +static int gpio_reset(struct reset_controller_dev *rcdev, unsigned long id)
  203891. +{
  203892. + struct gpio_reset_data *drvdata = container_of(rcdev,
  203893. + struct gpio_reset_data, rcdev);
  203894. +
  203895. + if (drvdata->delay_us < 0)
  203896. + return -ENOSYS;
  203897. +
  203898. + gpio_reset_set(rcdev, 1);
  203899. + udelay(drvdata->delay_us);
  203900. + gpio_reset_set(rcdev, 0);
  203901. +
  203902. + return 0;
  203903. +}
  203904. +
  203905. +static int gpio_reset_assert(struct reset_controller_dev *rcdev,
  203906. + unsigned long id)
  203907. +{
  203908. + gpio_reset_set(rcdev, 1);
  203909. +
  203910. + return 0;
  203911. +}
  203912. +
  203913. +static int gpio_reset_deassert(struct reset_controller_dev *rcdev,
  203914. + unsigned long id)
  203915. +{
  203916. + gpio_reset_set(rcdev, 0);
  203917. +
  203918. + return 0;
  203919. +}
  203920. +
  203921. +static struct reset_control_ops gpio_reset_ops = {
  203922. + .reset = gpio_reset,
  203923. + .assert = gpio_reset_assert,
  203924. + .deassert = gpio_reset_deassert,
  203925. +};
  203926. +
  203927. +static int of_gpio_reset_xlate(struct reset_controller_dev *rcdev,
  203928. + const struct of_phandle_args *reset_spec)
  203929. +{
  203930. + if (WARN_ON(reset_spec->args_count != 0))
  203931. + return -EINVAL;
  203932. +
  203933. + return 0;
  203934. +}
  203935. +
  203936. +static int gpio_reset_probe(struct platform_device *pdev)
  203937. +{
  203938. + struct device_node *np = pdev->dev.of_node;
  203939. + struct gpio_reset_data *drvdata;
  203940. + enum of_gpio_flags flags;
  203941. + unsigned long gpio_flags;
  203942. + bool initially_in_reset;
  203943. + int ret;
  203944. +
  203945. + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
  203946. + if (drvdata == NULL)
  203947. + return -ENOMEM;
  203948. +
  203949. + if (of_gpio_named_count(np, "reset-gpios") != 1) {
  203950. + dev_err(&pdev->dev,
  203951. + "reset-gpios property missing, or not a single gpio\n");
  203952. + return -EINVAL;
  203953. + }
  203954. +
  203955. + drvdata->gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags);
  203956. + if (drvdata->gpio == -EPROBE_DEFER) {
  203957. + return drvdata->gpio;
  203958. + } else if (!gpio_is_valid(drvdata->gpio)) {
  203959. + dev_err(&pdev->dev, "invalid reset gpio: %d\n", drvdata->gpio);
  203960. + return drvdata->gpio;
  203961. + }
  203962. +
  203963. + drvdata->active_low = flags & OF_GPIO_ACTIVE_LOW;
  203964. +
  203965. + ret = of_property_read_u32(np, "reset-delay-us", &drvdata->delay_us);
  203966. + if (ret < 0)
  203967. + drvdata->delay_us = -1;
  203968. + else if (drvdata->delay_us < 0)
  203969. + dev_warn(&pdev->dev, "reset delay too high\n");
  203970. +
  203971. + initially_in_reset = of_property_read_bool(np, "initially-in-reset");
  203972. + if (drvdata->active_low ^ initially_in_reset)
  203973. + gpio_flags = GPIOF_OUT_INIT_HIGH;
  203974. + else
  203975. + gpio_flags = GPIOF_OUT_INIT_LOW;
  203976. +
  203977. + ret = devm_gpio_request_one(&pdev->dev, drvdata->gpio, gpio_flags, NULL);
  203978. + if (ret < 0) {
  203979. + dev_err(&pdev->dev, "failed to request gpio %d: %d\n",
  203980. + drvdata->gpio, ret);
  203981. + return ret;
  203982. + }
  203983. +
  203984. + platform_set_drvdata(pdev, drvdata);
  203985. +
  203986. + drvdata->rcdev.of_node = np;
  203987. + drvdata->rcdev.owner = THIS_MODULE;
  203988. + drvdata->rcdev.nr_resets = 1;
  203989. + drvdata->rcdev.ops = &gpio_reset_ops;
  203990. + drvdata->rcdev.of_xlate = of_gpio_reset_xlate;
  203991. + reset_controller_register(&drvdata->rcdev);
  203992. +
  203993. + return 0;
  203994. +}
  203995. +
  203996. +static int gpio_reset_remove(struct platform_device *pdev)
  203997. +{
  203998. + struct gpio_reset_data *drvdata = platform_get_drvdata(pdev);
  203999. +
  204000. + reset_controller_unregister(&drvdata->rcdev);
  204001. +
  204002. + return 0;
  204003. +}
  204004. +
  204005. +static struct of_device_id gpio_reset_dt_ids[] = {
  204006. + { .compatible = "gpio-reset" },
  204007. + { }
  204008. +};
  204009. +
  204010. +static struct platform_driver gpio_reset_driver = {
  204011. + .probe = gpio_reset_probe,
  204012. + .remove = gpio_reset_remove,
  204013. + .driver = {
  204014. + .name = "gpio-reset",
  204015. + .owner = THIS_MODULE,
  204016. + .of_match_table = of_match_ptr(gpio_reset_dt_ids),
  204017. + },
  204018. +};
  204019. +
  204020. +static int __init gpio_reset_init(void)
  204021. +{
  204022. + return platform_driver_register(&gpio_reset_driver);
  204023. +}
  204024. +arch_initcall(gpio_reset_init);
  204025. +
  204026. +static void __exit gpio_reset_exit(void)
  204027. +{
  204028. + platform_driver_unregister(&gpio_reset_driver);
  204029. +}
  204030. +module_exit(gpio_reset_exit);
  204031. +
  204032. +MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
  204033. +MODULE_DESCRIPTION("gpio reset controller");
  204034. +MODULE_LICENSE("GPL");
  204035. +MODULE_ALIAS("platform:gpio-reset");
  204036. +MODULE_DEVICE_TABLE(of, gpio_reset_dt_ids);
  204037. diff -Nur linux-3.14.14/drivers/reset/Kconfig linux-imx6-3.14/drivers/reset/Kconfig
  204038. --- linux-3.14.14/drivers/reset/Kconfig 2014-07-28 10:07:25.000000000 -0500
  204039. +++ linux-imx6-3.14/drivers/reset/Kconfig 2014-12-08 00:31:54.076418001 -0600
  204040. @@ -11,3 +11,15 @@
  204041. via GPIOs or SoC-internal reset controller modules.
  204042. If unsure, say no.
  204043. +
  204044. +if RESET_CONTROLLER
  204045. +
  204046. +config RESET_GPIO
  204047. + tristate "GPIO reset controller support"
  204048. + default y
  204049. + depends on GPIOLIB && OF
  204050. + help
  204051. + This driver provides support for reset lines that are controlled
  204052. + directly by GPIOs.
  204053. +
  204054. +endif
  204055. diff -Nur linux-3.14.14/drivers/reset/Makefile linux-imx6-3.14/drivers/reset/Makefile
  204056. --- linux-3.14.14/drivers/reset/Makefile 2014-07-28 10:07:25.000000000 -0500
  204057. +++ linux-imx6-3.14/drivers/reset/Makefile 2014-12-08 00:31:54.076418001 -0600
  204058. @@ -1,2 +1,3 @@
  204059. obj-$(CONFIG_RESET_CONTROLLER) += core.o
  204060. +obj-$(CONFIG_RESET_GPIO) += gpio-reset.o
  204061. obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
  204062. diff -Nur linux-3.14.14/drivers/rtc/rtc-pcf8523.c linux-imx6-3.14/drivers/rtc/rtc-pcf8523.c
  204063. --- linux-3.14.14/drivers/rtc/rtc-pcf8523.c 2014-07-28 10:07:25.000000000 -0500
  204064. +++ linux-imx6-3.14/drivers/rtc/rtc-pcf8523.c 2014-12-08 00:31:54.088418001 -0600
  204065. @@ -7,6 +7,7 @@
  204066. */
  204067. #include <linux/bcd.h>
  204068. +#include <linux/delay.h>
  204069. #include <linux/i2c.h>
  204070. #include <linux/module.h>
  204071. #include <linux/rtc.h>
  204072. @@ -82,24 +83,85 @@
  204073. return 0;
  204074. }
  204075. -static int pcf8523_select_capacitance(struct i2c_client *client, bool high)
  204076. +static int pcf8523_rtc_check_oscillator(struct i2c_client *client)
  204077. {
  204078. u8 value;
  204079. int err;
  204080. - err = pcf8523_read(client, REG_CONTROL1, &value);
  204081. + err = pcf8523_read(client, REG_SECONDS, &value);
  204082. if (err < 0)
  204083. return err;
  204084. - if (!high)
  204085. - value &= ~REG_CONTROL1_CAP_SEL;
  204086. - else
  204087. - value |= REG_CONTROL1_CAP_SEL;
  204088. + if (value & REG_SECONDS_OS) {
  204089. + /*
  204090. + * If the oscillator was stopped, try to clear the flag. Upon
  204091. + * power-up the flag is always set, but if we cannot clear it
  204092. + * the oscillator isn't running properly for some reason. The
  204093. + * sensible thing therefore is to return an error, signalling
  204094. + * that the clock cannot be assumed to be correct.
  204095. + */
  204096. +
  204097. + value &= ~REG_SECONDS_OS;
  204098. +
  204099. + err = pcf8523_write(client, REG_SECONDS, value);
  204100. + if (err < 0)
  204101. + return err;
  204102. +
  204103. + err = pcf8523_read(client, REG_SECONDS, &value);
  204104. + if (err < 0)
  204105. + return err;
  204106. +
  204107. + if (value & REG_SECONDS_OS)
  204108. + return -EAGAIN;
  204109. + }
  204110. +
  204111. + return 0;
  204112. +}
  204113. +
  204114. +static int pcf8523_switch_capacitance(struct i2c_client *client)
  204115. +{
  204116. + u8 value;
  204117. + int err;
  204118. +
  204119. + err = pcf8523_read(client, REG_CONTROL1, &value);
  204120. + if (err < 0)
  204121. + goto out;
  204122. +
  204123. + value ^= REG_CONTROL1_CAP_SEL;
  204124. err = pcf8523_write(client, REG_CONTROL1, value);
  204125. +
  204126. +out:
  204127. + return err;
  204128. +}
  204129. +
  204130. +static int pcf8523_enable_oscillator(struct i2c_client *client)
  204131. +{
  204132. + int err, loop;
  204133. +
  204134. + loop = 0;
  204135. + while (loop < 200) {
  204136. + err = pcf8523_rtc_check_oscillator(client);
  204137. + if (!err)
  204138. + return 0;
  204139. + loop++;
  204140. + msleep(10);
  204141. + }
  204142. +
  204143. + err = pcf8523_switch_capacitance(client);
  204144. if (err < 0)
  204145. - return err;
  204146. + goto out;
  204147. +
  204148. + loop = 0;
  204149. + while (loop < 200) {
  204150. + err = pcf8523_rtc_check_oscillator(client);
  204151. + if (!err)
  204152. + return 0;
  204153. + loop++;
  204154. + msleep(10);
  204155. + }
  204156. +out:
  204157. return err;
  204158. }
  204159. @@ -290,6 +352,7 @@
  204160. const struct i2c_device_id *id)
  204161. {
  204162. struct pcf8523 *pcf;
  204163. + u8 value;
  204164. int err;
  204165. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
  204166. @@ -299,10 +362,20 @@
  204167. if (!pcf)
  204168. return -ENOMEM;
  204169. - err = pcf8523_select_capacitance(client, true);
  204170. + /* Check whether the RTC reports battery low */
  204171. + err = pcf8523_read(client, REG_CONTROL3, &value);
  204172. if (err < 0)
  204173. return err;
  204174. + if (value & REG_CONTROL3_BLF)
  204175. + dev_warn(&client->dev, "RTC reports battery is low\n");
  204176. +
  204177. + err = pcf8523_enable_oscillator(client);
  204178. + if (err < 0) {
  204179. + dev_warn(&client->dev, "RTC reports oscillator is not running\n");
  204180. + return err;
  204181. + }
  204182. +
  204183. err = pcf8523_set_pm(client, 0);
  204184. if (err < 0)
  204185. return err;
  204186. diff -Nur linux-3.14.14/drivers/rtc/rtc-snvs.c linux-imx6-3.14/drivers/rtc/rtc-snvs.c
  204187. --- linux-3.14.14/drivers/rtc/rtc-snvs.c 2014-07-28 10:07:25.000000000 -0500
  204188. +++ linux-imx6-3.14/drivers/rtc/rtc-snvs.c 2014-12-08 00:31:54.088418001 -0600
  204189. @@ -1,5 +1,5 @@
  204190. /*
  204191. - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
  204192. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  204193. *
  204194. * The code contained herein is licensed under the GNU General Public
  204195. * License. You may obtain a copy of the GNU General Public License
  204196. @@ -41,6 +41,8 @@
  204197. spinlock_t lock;
  204198. };
  204199. +static void __iomem *snvs_base;
  204200. +
  204201. static u32 rtc_read_lp_counter(void __iomem *ioaddr)
  204202. {
  204203. u64 read1, read2;
  204204. @@ -241,6 +243,15 @@
  204205. return events ? IRQ_HANDLED : IRQ_NONE;
  204206. }
  204207. +static void snvs_poweroff(void)
  204208. +{
  204209. + u32 value;
  204210. +
  204211. + value = readl(snvs_base + SNVS_LPCR);
  204212. + /* set TOP and DP_EN bit */
  204213. + writel(value | 0x60, snvs_base + SNVS_LPCR);
  204214. +}
  204215. +
  204216. static int snvs_rtc_probe(struct platform_device *pdev)
  204217. {
  204218. struct snvs_rtc_data *data;
  204219. @@ -270,13 +281,15 @@
  204220. /* Clear interrupt status */
  204221. writel(0xffffffff, data->ioaddr + SNVS_LPSR);
  204222. + snvs_base = data->ioaddr;
  204223. /* Enable RTC */
  204224. snvs_rtc_enable(data, true);
  204225. device_init_wakeup(&pdev->dev, true);
  204226. ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler,
  204227. - IRQF_SHARED, "rtc alarm", &pdev->dev);
  204228. + IRQF_SHARED | IRQF_NO_SUSPEND,
  204229. + "rtc alarm", &pdev->dev);
  204230. if (ret) {
  204231. dev_err(&pdev->dev, "failed to request irq %d: %d\n",
  204232. data->irq, ret);
  204233. @@ -290,6 +303,12 @@
  204234. dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
  204235. return ret;
  204236. }
  204237. + /*
  204238. + * if no specific power off function in board file, power off system by
  204239. + * SNVS
  204240. + */
  204241. + if (!pm_power_off)
  204242. + pm_power_off = snvs_poweroff;
  204243. return 0;
  204244. }
  204245. diff -Nur linux-3.14.14/drivers/scsi/scsi_transport_iscsi.c linux-imx6-3.14/drivers/scsi/scsi_transport_iscsi.c
  204246. --- linux-3.14.14/drivers/scsi/scsi_transport_iscsi.c 2014-07-28 10:07:25.000000000 -0500
  204247. +++ linux-imx6-3.14/drivers/scsi/scsi_transport_iscsi.c 2014-12-08 00:31:54.276418001 -0600
  204248. @@ -1225,7 +1225,7 @@
  204249. * Adds a sysfs entry for the flashnode session attributes
  204250. *
  204251. * Returns:
  204252. - * pointer to allocated flashnode sess on sucess
  204253. + * pointer to allocated flashnode sess on success
  204254. * %NULL on failure
  204255. */
  204256. struct iscsi_bus_flash_session *
  204257. @@ -1423,7 +1423,7 @@
  204258. }
  204259. /**
  204260. - * iscsi_destroy_flashnode_sess - destory flashnode session entry
  204261. + * iscsi_destroy_flashnode_sess - destroy flashnode session entry
  204262. * @fnode_sess: pointer to flashnode session entry to be destroyed
  204263. *
  204264. * Deletes the flashnode session entry and all children flashnode connection
  204265. @@ -1453,7 +1453,7 @@
  204266. }
  204267. /**
  204268. - * iscsi_destroy_all_flashnode - destory all flashnode session entries
  204269. + * iscsi_destroy_all_flashnode - destroy all flashnode session entries
  204270. * @shost: pointer to host data
  204271. *
  204272. * Destroys all the flashnode session entries and all corresponding children
  204273. diff -Nur linux-3.14.14/drivers/staging/bcm/Typedefs.h linux-imx6-3.14/drivers/staging/bcm/Typedefs.h
  204274. --- linux-3.14.14/drivers/staging/bcm/Typedefs.h 2014-07-28 10:07:25.000000000 -0500
  204275. +++ linux-imx6-3.14/drivers/staging/bcm/Typedefs.h 2014-12-08 00:31:54.316418001 -0600
  204276. @@ -25,16 +25,16 @@
  204277. typedef unsigned long ULONG;
  204278. typedef unsigned long DWORD;
  204279. -typedef char* PCHAR;
  204280. -typedef short* PSHORT;
  204281. -typedef int* PINT;
  204282. -typedef long* PLONG;
  204283. -typedef void* PVOID;
  204284. +typedef char *PCHAR;
  204285. +typedef short *PSHORT;
  204286. +typedef int *PINT;
  204287. +typedef long *PLONG;
  204288. +typedef void *PVOID;
  204289. -typedef unsigned char* PUCHAR;
  204290. -typedef unsigned short* PUSHORT;
  204291. -typedef unsigned int* PUINT;
  204292. -typedef unsigned long* PULONG;
  204293. +typedef unsigned char *PUCHAR;
  204294. +typedef unsigned short *PUSHORT;
  204295. +typedef unsigned int *PUINT;
  204296. +typedef unsigned long *PULONG;
  204297. typedef unsigned long long ULONG64;
  204298. typedef unsigned long long LARGE_INTEGER;
  204299. typedef unsigned int UINT32;
  204300. diff -Nur linux-3.14.14/drivers/staging/media/lirc/Kconfig linux-imx6-3.14/drivers/staging/media/lirc/Kconfig
  204301. --- linux-3.14.14/drivers/staging/media/lirc/Kconfig 2014-07-28 10:07:25.000000000 -0500
  204302. +++ linux-imx6-3.14/drivers/staging/media/lirc/Kconfig 2014-12-08 00:31:54.468418001 -0600
  204303. @@ -38,6 +38,12 @@
  204304. help
  204305. Driver for Homebrew Parallel Port Receivers
  204306. +config LIRC_GPIO
  204307. + tristate "Homebrew GPIO Port Receiver/Transmitter"
  204308. + depends on LIRC
  204309. + help
  204310. + Driver for Homebrew GPIO Port Receiver/Transmitter
  204311. +
  204312. config LIRC_SASEM
  204313. tristate "Sasem USB IR Remote"
  204314. depends on LIRC && USB
  204315. diff -Nur linux-3.14.14/drivers/staging/media/lirc/lirc_gpio.c linux-imx6-3.14/drivers/staging/media/lirc/lirc_gpio.c
  204316. --- linux-3.14.14/drivers/staging/media/lirc/lirc_gpio.c 1969-12-31 18:00:00.000000000 -0600
  204317. +++ linux-imx6-3.14/drivers/staging/media/lirc/lirc_gpio.c 2014-12-08 00:31:54.468418001 -0600
  204318. @@ -0,0 +1,782 @@
  204319. +/*
  204320. + * lirc_gpio.c
  204321. + *
  204322. + * lirc_gpio - Device driver that records pulse- and pause-lengths
  204323. + * (space-lengths) (just like the lirc_serial driver does)
  204324. + * between GPIO interrupt events on GPIO capable devices.
  204325. + * Lots of code has been taken from the lirc_serial and the
  204326. + * lirc_rpi modules so I would like say thanks to the authors.
  204327. + *
  204328. + * Copyright (C) 2014 CurlyMo <curlymoo1@gmail.com>
  204329. + * Aron Robert Szabo <aron@reon.hu>,
  204330. + * Michael Bishop <cleverca22@gmail.com>
  204331. + * This program is free software; you can redistribute it and/or modify
  204332. + * it under the terms of the GNU General Public License as published by
  204333. + * the Free Software Foundation; either version 2 of the License, or
  204334. + * (at your option) any later version.
  204335. + *
  204336. + * This program is distributed in the hope that it will be useful,
  204337. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  204338. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  204339. + * GNU General Public License for more details.
  204340. + *
  204341. + * You should have received a copy of the GNU General Public License
  204342. + * along with this program; if not, write to the Free Software
  204343. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  204344. + */
  204345. +
  204346. +/*
  204347. + lirc_gpio {
  204348. + compatible = "lirc_gpio";
  204349. + gpios = <&gpio3 6 1 &gpio3 7 2>;
  204350. + pinctrl-names = "default";
  204351. + pinctrl-0 = <&pinctrl_hummingboard_gpio3_6>;
  204352. + pinctrl-1 = <&pinctrl_hummingboard_gpio3_7>;
  204353. + linux,sense = <-1>;
  204354. + linux,softcarrier = <1>;
  204355. + linux,validgpios = <1 73 72 71 70 194 195 67>;
  204356. + };
  204357. + */
  204358. +
  204359. +
  204360. +#include <linux/module.h>
  204361. +#include <linux/errno.h>
  204362. +#include <linux/interrupt.h>
  204363. +#include <linux/sched.h>
  204364. +#include <linux/kernel.h>
  204365. +#include <linux/time.h>
  204366. +#include <linux/string.h>
  204367. +#include <linux/delay.h>
  204368. +#include <linux/platform_device.h>
  204369. +#include <linux/irq.h>
  204370. +#include <linux/spinlock.h>
  204371. +#include <media/lirc.h>
  204372. +#include <media/lirc_dev.h>
  204373. +#include <linux/gpio.h>
  204374. +#include <linux/of.h>
  204375. +#include <linux/of_gpio.h>
  204376. +
  204377. +#define LIRC_DRIVER_NAME "lirc_gpio"
  204378. +#define RBUF_LEN 256
  204379. +#define LIRC_TRANSMITTER_LATENCY 256
  204380. +
  204381. +#ifndef MAX_UDELAY_MS
  204382. +#define MAX_UDELAY_US 5000
  204383. +#else
  204384. +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
  204385. +#endif
  204386. +
  204387. +static ssize_t lirc_write(struct file *file, const char *buf, size_t n, loff_t *ppos);
  204388. +static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
  204389. +static int set_use_inc(void *data);
  204390. +static void set_use_dec(void *data);
  204391. +static int lirc_gpio_probe(struct platform_device *pdev);
  204392. +static int lirc_gpio_remove(struct platform_device *pdev);
  204393. +
  204394. +struct lirc_gpio_platform_data {
  204395. + int gpio_rx_nr;
  204396. + int gpio_tx_nr;
  204397. + bool active_rx_low;
  204398. + bool active_tx_low;
  204399. + u64 allowed_rx_protos;
  204400. + u64 allowed_tx_protos;
  204401. + int sense;
  204402. + int softcarrier;
  204403. + int validgpios[255];
  204404. +};
  204405. +
  204406. +struct lirc_gpio_dev {
  204407. + int gpio_rx_nr;
  204408. + int gpio_tx_nr;
  204409. + int sense;
  204410. + int softcarrier;
  204411. + int validgpios[255];
  204412. +};
  204413. +
  204414. +struct lirc_gpio_dev *gpio_dev;
  204415. +
  204416. +static const struct file_operations lirc_fops = {
  204417. + .owner = THIS_MODULE,
  204418. + .write = lirc_write,
  204419. + .unlocked_ioctl = lirc_ioctl,
  204420. + .read = lirc_dev_fop_read,
  204421. + .poll = lirc_dev_fop_poll,
  204422. + .open = lirc_dev_fop_open,
  204423. + .release = lirc_dev_fop_close,
  204424. + .llseek = no_llseek,
  204425. +};
  204426. +
  204427. +struct irq_chip *irqchip;
  204428. +struct irq_data *irqdata;
  204429. +
  204430. +static struct timeval lasttv = { 0, 0 };
  204431. +static struct lirc_buffer rbuf;
  204432. +static spinlock_t lock;
  204433. +
  204434. +/* set the default GPIO input pin */
  204435. +static int gpio_in_pin = -1;
  204436. +/* set the default GPIO output pin */
  204437. +static int gpio_out_pin = -1;
  204438. +/* -1 = auto, 0 = active high, 1 = active low */
  204439. +static int sense = -2;
  204440. +/* use softcarrier by default */
  204441. +static int softcarrier = -1;
  204442. +
  204443. +/* initialized/set in init_timing_params() */
  204444. +static unsigned int freq = 38000;
  204445. +static unsigned int duty_cycle = 50;
  204446. +static unsigned long period;
  204447. +static unsigned long pulse_width;
  204448. +static unsigned long space_width;
  204449. +
  204450. +static struct lirc_driver driver = {
  204451. + .name = LIRC_DRIVER_NAME,
  204452. + .minor = -1,
  204453. + .code_length = 1,
  204454. + .sample_rate = 0,
  204455. + .data = NULL,
  204456. + .add_to_buf = NULL,
  204457. + .rbuf = &rbuf,
  204458. + .set_use_inc = set_use_inc,
  204459. + .set_use_dec = set_use_dec,
  204460. + .fops = &lirc_fops,
  204461. + .dev = NULL,
  204462. + .owner = THIS_MODULE,
  204463. +};
  204464. +
  204465. +static struct of_device_id lirc_gpio_of_match[] = {
  204466. + { .compatible = "lirc_gpio", },
  204467. + {}
  204468. +};
  204469. +
  204470. +static struct platform_driver lirc_gpio_driver = {
  204471. + .probe = lirc_gpio_probe,
  204472. + .remove = lirc_gpio_remove,
  204473. + .driver = {
  204474. + .name = LIRC_DRIVER_NAME,
  204475. + .owner = THIS_MODULE,
  204476. + .of_match_table = lirc_gpio_of_match,
  204477. + },
  204478. +};
  204479. +
  204480. +static void safe_udelay(unsigned long usecs) {
  204481. + while (usecs > MAX_UDELAY_US) {
  204482. + udelay(MAX_UDELAY_US);
  204483. + usecs -= MAX_UDELAY_US;
  204484. + }
  204485. + udelay(usecs);
  204486. +}
  204487. +
  204488. +static int init_timing_params(unsigned int new_duty_cycle, unsigned int new_freq) {
  204489. + /*
  204490. + * period, pulse/space width are kept with 8 binary places -
  204491. + * IE multiplied by 256.
  204492. + */
  204493. + if(256 * 1000000L / new_freq * new_duty_cycle / 100 <=
  204494. + LIRC_TRANSMITTER_LATENCY)
  204495. + return -EINVAL;
  204496. + if(256 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <=
  204497. + LIRC_TRANSMITTER_LATENCY)
  204498. + return -EINVAL;
  204499. + duty_cycle = new_duty_cycle;
  204500. + freq = new_freq;
  204501. + period = 256 * 1000000L / freq;
  204502. + pulse_width = period * duty_cycle / 100;
  204503. + space_width = period - pulse_width;
  204504. + return 0;
  204505. +}
  204506. +
  204507. +
  204508. +static long send_pulse_softcarrier(unsigned long length) {
  204509. + int flag;
  204510. + unsigned long actual, target, d;
  204511. +
  204512. + if(gpio_dev->gpio_tx_nr >= 0) {
  204513. + length <<= 8;
  204514. +
  204515. + actual = 0; target = 0; flag = 0;
  204516. + while(actual < length) {
  204517. + if(flag) {
  204518. + gpio_set_value(gpio_dev->gpio_tx_nr, 0);
  204519. + target += space_width;
  204520. + } else {
  204521. + gpio_set_value(gpio_dev->gpio_tx_nr, 1);
  204522. + target += pulse_width;
  204523. + }
  204524. + d = (target - actual - LIRC_TRANSMITTER_LATENCY + 128) >> 8;
  204525. + /*
  204526. + * Note - we've checked in ioctl that the pulse/space
  204527. + * widths are big enough so that d is > 0
  204528. + */
  204529. + udelay(d);
  204530. + actual += (d << 8) + LIRC_TRANSMITTER_LATENCY;
  204531. + flag = !flag;
  204532. + }
  204533. + return (actual-length) >> 8;
  204534. + }
  204535. + return 0;
  204536. +}
  204537. +
  204538. +static long send_pulse(unsigned long length) {
  204539. + if(length <= 0)
  204540. + return 0;
  204541. +
  204542. + if(gpio_dev->gpio_tx_nr >= 0) {
  204543. + if(gpio_dev->softcarrier) {
  204544. + return send_pulse_softcarrier(length);
  204545. + } else {
  204546. + gpio_set_value(gpio_dev->gpio_tx_nr, 1);
  204547. + safe_udelay(length);
  204548. + return 0;
  204549. + }
  204550. + }
  204551. + return 0;
  204552. +}
  204553. +
  204554. +static void send_space(long length) {
  204555. + if(gpio_dev->gpio_tx_nr >= 0) {
  204556. + gpio_set_value(gpio_dev->gpio_tx_nr, 0);
  204557. + if(length <= 0)
  204558. + return;
  204559. + safe_udelay(length);
  204560. + }
  204561. +}
  204562. +
  204563. +static void rbwrite(int l) {
  204564. + if (lirc_buffer_full(&rbuf)) {
  204565. + /* no new signals will be accepted */
  204566. + return;
  204567. + }
  204568. + lirc_buffer_write(&rbuf, (void *)&l);
  204569. +}
  204570. +
  204571. +static void frbwrite(int l) {
  204572. + /* simple noise filter */
  204573. + static int pulse, space;
  204574. + static unsigned int ptr;
  204575. +
  204576. + if(ptr > 0 && (l & PULSE_BIT)) {
  204577. + pulse += l & PULSE_MASK;
  204578. + if(pulse > 250) {
  204579. + rbwrite(space);
  204580. + rbwrite(pulse | PULSE_BIT);
  204581. + ptr = 0;
  204582. + pulse = 0;
  204583. + }
  204584. + return;
  204585. + }
  204586. + if(!(l & PULSE_BIT)) {
  204587. + if(ptr == 0) {
  204588. + if (l > 20000) {
  204589. + space = l;
  204590. + ptr++;
  204591. + return;
  204592. + }
  204593. + } else {
  204594. + if(l > 20000) {
  204595. + space += pulse;
  204596. + if (space > PULSE_MASK)
  204597. + space = PULSE_MASK;
  204598. + space += l;
  204599. + if (space > PULSE_MASK)
  204600. + space = PULSE_MASK;
  204601. + pulse = 0;
  204602. + return;
  204603. + }
  204604. + rbwrite(space);
  204605. + rbwrite(pulse | PULSE_BIT);
  204606. + ptr = 0;
  204607. + pulse = 0;
  204608. + }
  204609. + }
  204610. + rbwrite(l);
  204611. +}
  204612. +
  204613. +static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs) {
  204614. + struct timeval tv;
  204615. + long deltv;
  204616. + int data;
  204617. + int signal;
  204618. +
  204619. + /* use the GPIO signal level */
  204620. + signal = gpio_get_value(gpio_dev->gpio_rx_nr);
  204621. +
  204622. + /* unmask the irq */
  204623. + irqchip->irq_unmask(irqdata);
  204624. +
  204625. + if(gpio_dev->sense != -1) {
  204626. + /* The HB GPIO input acts like it is an analogue input.
  204627. + Therefor a high signal is 256 and a low signal is 1.
  204628. + For Lirc to properly interpret the spaces and pulses,
  204629. + we need to transform these to ones and zeros. To be
  204630. + on the safe side, every signal higher then 128 will
  204631. + be interpreted as a high and vice versa. */
  204632. + if (signal > 128) {
  204633. + signal = 1;
  204634. + } else {
  204635. + signal = 0;
  204636. + }
  204637. + /* get current time */
  204638. + do_gettimeofday(&tv);
  204639. +
  204640. + /* calc time since last interrupt in microseconds */
  204641. + deltv = tv.tv_sec-lasttv.tv_sec;
  204642. + if(tv.tv_sec < lasttv.tv_sec ||
  204643. + (tv.tv_sec == lasttv.tv_sec &&
  204644. + tv.tv_usec < lasttv.tv_usec)) {
  204645. + printk(KERN_WARNING LIRC_DRIVER_NAME
  204646. + ": AIEEEE: your clock just jumped backwards\n");
  204647. + printk(KERN_WARNING LIRC_DRIVER_NAME
  204648. + ": %d %d %lx %lx %lx %lx\n", signal, gpio_dev->sense,
  204649. + tv.tv_sec, lasttv.tv_sec,
  204650. + tv.tv_usec, lasttv.tv_usec);
  204651. + data = PULSE_MASK;
  204652. + } else if (deltv > 15) {
  204653. + data = PULSE_MASK; /* really long time */
  204654. + if(!(signal^gpio_dev->sense)) {
  204655. + /* sanity check */
  204656. + printk(KERN_WARNING LIRC_DRIVER_NAME
  204657. + ": AIEEEE: %d %d %lx %lx %lx %lx\n",
  204658. + signal, gpio_dev->sense, tv.tv_sec, lasttv.tv_sec,
  204659. + tv.tv_usec, lasttv.tv_usec);
  204660. + /*
  204661. + * detecting pulse while this
  204662. + * MUST be a space!
  204663. + */
  204664. + gpio_dev->sense = gpio_dev->sense ? 0 : 1;
  204665. + }
  204666. + } else {
  204667. + data = (int) (deltv*1000000 +
  204668. + (tv.tv_usec - lasttv.tv_usec));
  204669. + }
  204670. + frbwrite(signal^gpio_dev->sense ? data : (data|PULSE_BIT));
  204671. + lasttv = tv;
  204672. + wake_up_interruptible(&rbuf.wait_poll);
  204673. + }
  204674. +
  204675. + return IRQ_HANDLED;
  204676. +}
  204677. +
  204678. +// called when the character device is opened
  204679. +static int set_use_inc(void *data) {
  204680. + int result;
  204681. + unsigned long flags;
  204682. +
  204683. + /* initialize timestamp */
  204684. + do_gettimeofday(&lasttv);
  204685. +
  204686. + if(gpio_dev->gpio_rx_nr >= 0) {
  204687. + result = request_irq(gpio_to_irq(gpio_dev->gpio_rx_nr),
  204688. + (irq_handler_t) irq_handler, 0,
  204689. + LIRC_DRIVER_NAME, (void*) 0);
  204690. +
  204691. + switch (result) {
  204692. + case -EBUSY:
  204693. + printk(KERN_ERR LIRC_DRIVER_NAME
  204694. + ": IRQ %d is busy\n",
  204695. + gpio_to_irq(gpio_dev->gpio_rx_nr));
  204696. + return -EBUSY;
  204697. + case -EINVAL:
  204698. + printk(KERN_ERR LIRC_DRIVER_NAME
  204699. + ": Bad irq number or handler\n");
  204700. + return -EINVAL;
  204701. + default:
  204702. + break;
  204703. + };
  204704. +
  204705. + /* initialize pulse/space widths */
  204706. + init_timing_params(duty_cycle, freq);
  204707. +
  204708. + spin_lock_irqsave(&lock, flags);
  204709. +
  204710. + /* GPIO Pin Falling/Rising Edge Detect Enable */
  204711. + irqchip->irq_set_type(irqdata,
  204712. + IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING);
  204713. +
  204714. + /* unmask the irq */
  204715. + irqchip->irq_unmask(irqdata);
  204716. +
  204717. + spin_unlock_irqrestore(&lock, flags);
  204718. + }
  204719. +
  204720. + return 0;
  204721. +}
  204722. +
  204723. +static void set_use_dec(void *data) {
  204724. + unsigned long flags;
  204725. + if(gpio_dev->gpio_rx_nr >= 0) {
  204726. + spin_lock_irqsave(&lock, flags);
  204727. +
  204728. + /* GPIO Pin Falling/Rising Edge Detect Disable */
  204729. + irqchip->irq_set_type(irqdata, 0);
  204730. + irqchip->irq_mask(irqdata);
  204731. +
  204732. + spin_unlock_irqrestore(&lock, flags);
  204733. +
  204734. + free_irq(gpio_to_irq(gpio_dev->gpio_rx_nr), (void *) 0);
  204735. + }
  204736. +}
  204737. +
  204738. +static ssize_t lirc_write(struct file *file, const char *buf, size_t n, loff_t *ppos) {
  204739. + int i, count;
  204740. + unsigned long flags;
  204741. + long delta = 0;
  204742. + int *wbuf;
  204743. +
  204744. + if(gpio_dev->gpio_tx_nr >= 0) {
  204745. + count = n / sizeof(int);
  204746. + if(n % sizeof(int) || count % 2 == 0)
  204747. + return -EINVAL;
  204748. + wbuf = memdup_user(buf, n);
  204749. + if(IS_ERR(wbuf))
  204750. + return PTR_ERR(wbuf);
  204751. + spin_lock_irqsave(&lock, flags);
  204752. +
  204753. + for(i = 0; i < count; i++) {
  204754. + if(i%2)
  204755. + send_space(wbuf[i] - delta);
  204756. + else
  204757. + delta = send_pulse(wbuf[i]);
  204758. + }
  204759. + gpio_set_value(gpio_dev->gpio_tx_nr, 0);
  204760. +
  204761. + spin_unlock_irqrestore(&lock, flags);
  204762. + kfree(wbuf);
  204763. + return n;
  204764. + }
  204765. + return 0;
  204766. +}
  204767. +
  204768. +
  204769. +static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) {
  204770. + int result;
  204771. + __u32 value;
  204772. +
  204773. + switch(cmd) {
  204774. + case LIRC_GET_SEND_MODE:
  204775. + return -ENOIOCTLCMD;
  204776. + break;
  204777. +
  204778. + case LIRC_SET_SEND_MODE:
  204779. + result = get_user(value, (__u32 *) arg);
  204780. + if(result)
  204781. + return result;
  204782. + /* only LIRC_MODE_PULSE supported */
  204783. + if(value != LIRC_MODE_PULSE)
  204784. + return -ENOSYS;
  204785. + break;
  204786. +
  204787. + case LIRC_GET_LENGTH:
  204788. + return -ENOSYS;
  204789. + break;
  204790. +
  204791. + case LIRC_SET_SEND_DUTY_CYCLE:
  204792. + result = get_user(value, (__u32 *) arg);
  204793. + if (result)
  204794. + return result;
  204795. + if (value <= 0 || value > 100)
  204796. + return -EINVAL;
  204797. + return init_timing_params(value, freq);
  204798. + break;
  204799. +
  204800. + case LIRC_SET_SEND_CARRIER:
  204801. + result = get_user(value, (__u32 *) arg);
  204802. + if(result)
  204803. + return result;
  204804. + if(value > 500000 || value < 20000)
  204805. + return -EINVAL;
  204806. + return init_timing_params(duty_cycle, value);
  204807. + break;
  204808. +
  204809. + default:
  204810. + return lirc_dev_fop_ioctl(filep, cmd, arg);
  204811. + }
  204812. + return 0;
  204813. +}
  204814. +
  204815. +static int lirc_gpio_get_devtree_pdata(struct device *dev, struct lirc_gpio_platform_data *pdata) {
  204816. + struct device_node *np = dev->of_node;
  204817. + enum of_gpio_flags flags;
  204818. + struct property *prop;
  204819. + const __be32 *cur;
  204820. + int gpio = -1;
  204821. + int ret = 0;
  204822. + int i = 0;
  204823. +
  204824. + if(np) {
  204825. + gpio = of_get_gpio_flags(np, 0, &flags);
  204826. + if(gpio < 0) {
  204827. + if(gpio != -EPROBE_DEFER)
  204828. + dev_err(dev, "RX gpio not defined (%d)\n", gpio);
  204829. +
  204830. + pdata->gpio_rx_nr = -1;
  204831. + pdata->active_rx_low = 0;
  204832. + pdata->allowed_rx_protos = 0;
  204833. + } else {
  204834. + pdata->gpio_rx_nr = gpio;
  204835. + pdata->active_rx_low = (flags & OF_GPIO_ACTIVE_LOW);
  204836. + pdata->allowed_rx_protos = 0;
  204837. + }
  204838. +
  204839. + gpio = of_get_gpio_flags(np, 1, &flags);
  204840. + if(gpio < 0) {
  204841. + if(gpio != -EPROBE_DEFER)
  204842. + dev_err(dev, "TX gpio not defined (%d)\n", gpio);
  204843. +
  204844. + pdata->gpio_tx_nr = -1;
  204845. + pdata->active_tx_low = 0;
  204846. + pdata->allowed_tx_protos = 0;
  204847. + } else {
  204848. + pdata->gpio_tx_nr = gpio;
  204849. + pdata->active_tx_low = (flags & OF_GPIO_ACTIVE_LOW);
  204850. + pdata->allowed_tx_protos = 0;
  204851. + }
  204852. + ret = of_property_read_u32(np, "linux,sense", &pdata->sense);
  204853. + if(ret) {
  204854. + pdata->sense = -1;
  204855. + }
  204856. + ret = of_property_read_u32(np, "linux,softcarrier", &pdata->softcarrier);
  204857. + if(ret) {
  204858. + pdata->softcarrier = 1;
  204859. + }
  204860. + i = 0;
  204861. + printk(KERN_DEBUG LIRC_DRIVER_NAME ": valid gpios");
  204862. + of_property_for_each_u32(np, "linux,validgpios", prop, cur, gpio) {
  204863. + printk(" %d", gpio);
  204864. + pdata->validgpios[i++] = gpio;
  204865. + }
  204866. + printk("\n");
  204867. + pdata->validgpios[i] = -1;
  204868. + }
  204869. +
  204870. + return 0;
  204871. +}
  204872. +
  204873. +static int init_port(void) {
  204874. + int i, nlow, nhigh, ret, irq;
  204875. +
  204876. + if(gpio_dev->gpio_tx_nr >= 0) {
  204877. + if(gpio_request(gpio_dev->gpio_tx_nr, LIRC_DRIVER_NAME " ir/out")) {
  204878. + printk(KERN_ALERT LIRC_DRIVER_NAME ": cant claim gpio pin %d\n", gpio_dev->gpio_tx_nr);
  204879. + ret = -ENODEV;
  204880. + goto exit_init_port;
  204881. + }
  204882. + }
  204883. +
  204884. + if(gpio_dev->gpio_rx_nr >= 0) {
  204885. + if(gpio_request(gpio_dev->gpio_rx_nr, LIRC_DRIVER_NAME " ir/in")) {
  204886. + printk(KERN_ALERT LIRC_DRIVER_NAME ": cant claim gpio pin %d\n", gpio_dev->gpio_rx_nr);
  204887. + ret = -ENODEV;
  204888. + goto exit_gpio_free_out_pin;
  204889. + }
  204890. + }
  204891. +
  204892. + if(gpio_dev->gpio_rx_nr >= 0) {
  204893. + gpio_direction_input(gpio_dev->gpio_rx_nr);
  204894. + }
  204895. + if(gpio_dev->gpio_tx_nr >= 0) {
  204896. + gpio_direction_output(gpio_dev->gpio_tx_nr, 1);
  204897. + gpio_set_value(gpio_dev->gpio_tx_nr, 0);
  204898. + }
  204899. +
  204900. + if(gpio_dev->gpio_rx_nr >= 0) {
  204901. + irq = gpio_to_irq(gpio_dev->gpio_rx_nr);
  204902. + irqdata = irq_get_irq_data(irq);
  204903. +
  204904. + if(irqdata && irqdata->chip) {
  204905. + irqchip = irqdata->chip;
  204906. + } else {
  204907. + ret = -ENODEV;
  204908. + goto exit_gpio_free_in_pin;
  204909. + }
  204910. +
  204911. + /* if pin is high, then this must be an active low receiver. */
  204912. + if(gpio_dev->sense == -1) {
  204913. + /* wait 1/2 sec for the power supply */
  204914. + msleep(500);
  204915. +
  204916. + /*
  204917. + * probe 9 times every 0.04s, collect "votes" for
  204918. + * active high/low
  204919. + */
  204920. + nlow = 0;
  204921. + nhigh = 0;
  204922. + for(i = 0; i < 9; i++) {
  204923. + if(gpio_get_value(gpio_dev->gpio_rx_nr))
  204924. + nlow++;
  204925. + else
  204926. + nhigh++;
  204927. + msleep(40);
  204928. + }
  204929. + gpio_dev->sense = (nlow >= nhigh ? 1 : 0);
  204930. + printk(KERN_INFO LIRC_DRIVER_NAME ": auto-detected active %s receiver on GPIO pin %d\n",
  204931. + gpio_dev->sense ? "low" : "high", gpio_dev->gpio_rx_nr);
  204932. + } else {
  204933. + printk(KERN_INFO LIRC_DRIVER_NAME ": manually using active %s receiver on GPIO pin %d\n",
  204934. + gpio_dev->sense ? "low" : "high", gpio_dev->gpio_rx_nr);
  204935. + }
  204936. + }
  204937. +
  204938. + return 0;
  204939. +
  204940. +exit_gpio_free_in_pin:
  204941. + gpio_free(gpio_dev->gpio_rx_nr);
  204942. +
  204943. +exit_gpio_free_out_pin:
  204944. + gpio_free(gpio_dev->gpio_tx_nr);
  204945. +
  204946. +exit_init_port:
  204947. + return ret;
  204948. +}
  204949. +
  204950. +static void lirc_gpio_exit(void) {
  204951. + if(gpio_dev->gpio_tx_nr >= 0) {
  204952. + gpio_free(gpio_dev->gpio_tx_nr);
  204953. + }
  204954. + if(gpio_dev->gpio_rx_nr >= 0) {
  204955. + gpio_free(gpio_dev->gpio_rx_nr);
  204956. + }
  204957. +
  204958. + lirc_unregister_driver(driver.minor);
  204959. + lirc_buffer_free(&rbuf);
  204960. +}
  204961. +
  204962. +static int lirc_gpio_probe(struct platform_device *pdev) {
  204963. + const struct lirc_gpio_platform_data *pdata =
  204964. + pdev->dev.platform_data;
  204965. + int rc;
  204966. + int result = 0;
  204967. + int match = 0;
  204968. + int i = 0;
  204969. +
  204970. + if(pdev->dev.of_node) {
  204971. + struct lirc_gpio_platform_data *dtpdata = devm_kzalloc(&pdev->dev, sizeof(*dtpdata), GFP_KERNEL);
  204972. + if(!dtpdata)
  204973. + return -ENOMEM;
  204974. + rc = lirc_gpio_get_devtree_pdata(&pdev->dev, dtpdata);
  204975. + if(rc)
  204976. + return rc;
  204977. + pdata = dtpdata;
  204978. + }
  204979. +
  204980. + if(!pdata)
  204981. + return -EINVAL;
  204982. +
  204983. + gpio_dev = kzalloc(sizeof(struct lirc_gpio_dev), GFP_KERNEL);
  204984. + if(!gpio_dev)
  204985. + return -ENOMEM;
  204986. +
  204987. + gpio_dev->gpio_rx_nr = pdata->gpio_rx_nr;
  204988. + gpio_dev->gpio_tx_nr = pdata->gpio_tx_nr;
  204989. + gpio_dev->sense = pdata->sense;
  204990. + gpio_dev->softcarrier = pdata->softcarrier;
  204991. + memcpy(gpio_dev->validgpios, pdata->validgpios, 255);
  204992. +
  204993. + if(gpio_in_pin != gpio_out_pin) {
  204994. + match = 0;
  204995. + for(i = 0; (i < ARRAY_SIZE(gpio_dev->validgpios)) && (!match) && (gpio_dev->validgpios[i] != -1); i++) {
  204996. + if(gpio_in_pin == gpio_dev->validgpios[i]) {
  204997. + match = 1;
  204998. + break;
  204999. + }
  205000. + }
  205001. + if(gpio_in_pin > -1) {
  205002. + if(!match) {
  205003. + printk(KERN_ERR LIRC_DRIVER_NAME
  205004. + ": invalid RX GPIO pin specified!\n");
  205005. + return -EINVAL;
  205006. + } else {
  205007. + gpio_dev->gpio_rx_nr = gpio_in_pin;
  205008. + }
  205009. + }
  205010. + match = 0;
  205011. + for(i = 0; (i < ARRAY_SIZE(gpio_dev->validgpios)) && (!match) && (gpio_dev->validgpios[i] != -1); i++) {
  205012. + if(gpio_out_pin == gpio_dev->validgpios[i]) {
  205013. + match = 1;
  205014. + break;
  205015. + }
  205016. + }
  205017. + if(gpio_out_pin > -1) {
  205018. + if(!match) {
  205019. + printk(KERN_ERR LIRC_DRIVER_NAME
  205020. + ": invalid TX GPIO pin specified!\n");
  205021. + return -EINVAL;
  205022. + } else {
  205023. + gpio_dev->gpio_tx_nr = gpio_out_pin;
  205024. + }
  205025. + }
  205026. + }
  205027. + if(sense > -2) {
  205028. + gpio_dev->sense = sense;
  205029. + }
  205030. + if(softcarrier >= 0) {
  205031. + gpio_dev->softcarrier = softcarrier;
  205032. + }
  205033. +
  205034. + printk(KERN_DEBUG LIRC_DRIVER_NAME ": rx %d, tx %d, sense %d, softcarrier %d\n",
  205035. + gpio_dev->gpio_rx_nr, gpio_dev->gpio_tx_nr, gpio_dev->sense, gpio_dev->softcarrier);
  205036. +
  205037. + platform_set_drvdata(pdev, gpio_dev);
  205038. +
  205039. + result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
  205040. + if(result < 0)
  205041. + return -ENOMEM;
  205042. +
  205043. + driver.features = LIRC_CAN_SET_SEND_DUTY_CYCLE |
  205044. + LIRC_CAN_SET_SEND_CARRIER |
  205045. + LIRC_CAN_SEND_PULSE |
  205046. + LIRC_CAN_REC_MODE2;
  205047. +
  205048. + driver.dev = &pdev->dev;
  205049. + driver.minor = lirc_register_driver(&driver);
  205050. +
  205051. + if(driver.minor < 0) {
  205052. + printk(KERN_ERR LIRC_DRIVER_NAME ": device registration failed with %d\n", result);
  205053. + result = -EIO;
  205054. + goto exit_gpio;
  205055. + }
  205056. +
  205057. + result = init_port();
  205058. + if(result < 0)
  205059. + goto exit_gpio;
  205060. +
  205061. + return 0;
  205062. +
  205063. +exit_gpio:
  205064. + lirc_gpio_exit();
  205065. +
  205066. + return result;
  205067. +}
  205068. +
  205069. +static int lirc_gpio_remove(struct platform_device *pdev) {
  205070. + struct lirc_gpio_dev *gpio_dev = platform_get_drvdata(pdev);
  205071. +
  205072. + lirc_gpio_exit();
  205073. +
  205074. + kfree(gpio_dev);
  205075. +
  205076. + return 0;
  205077. +}
  205078. +
  205079. +MODULE_DEVICE_TABLE(of, lirc_gpio_of_match);
  205080. +module_platform_driver(lirc_gpio_driver);
  205081. +
  205082. +MODULE_DESCRIPTION("Infra-red GPIO receiver and blaster driver.");
  205083. +MODULE_AUTHOR("CurlyMo <development@xbian.org>");
  205084. +MODULE_AUTHOR("Aron Robert Szabo <aron@reon.hu>");
  205085. +MODULE_AUTHOR("Michael Bishop <cleverca22@gmail.com>");
  205086. +MODULE_LICENSE("GPL");
  205087. +
  205088. +module_param(gpio_out_pin, int, S_IRUGO);
  205089. +MODULE_PARM_DESC(gpio_out_pin, "GPIO output/transmitter pin number");
  205090. +
  205091. +module_param(gpio_in_pin, int, S_IRUGO);
  205092. +MODULE_PARM_DESC(gpio_in_pin, "GPIO input/receiver pin number.");
  205093. +
  205094. +module_param(sense, int, S_IRUGO);
  205095. +MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit"
  205096. + " (0 = active high, 1 = active low )");
  205097. +
  205098. +module_param(softcarrier, int, S_IRUGO);
  205099. +MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
  205100. +
  205101. diff -Nur linux-3.14.14/drivers/staging/octeon/ethernet-rgmii.c linux-imx6-3.14/drivers/staging/octeon/ethernet-rgmii.c
  205102. --- linux-3.14.14/drivers/staging/octeon/ethernet-rgmii.c 2014-07-28 10:07:25.000000000 -0500
  205103. +++ linux-imx6-3.14/drivers/staging/octeon/ethernet-rgmii.c 2014-12-08 00:31:54.480418001 -0600
  205104. @@ -166,9 +166,8 @@
  205105. if (use_global_register_lock)
  205106. spin_unlock_irqrestore(&global_register_lock, flags);
  205107. - else {
  205108. + else
  205109. mutex_unlock(&priv->phydev->bus->mdio_lock);
  205110. - }
  205111. if (priv->phydev == NULL) {
  205112. /* Tell core. */
  205113. diff -Nur linux-3.14.14/drivers/staging/rtl8821ae/core.c linux-imx6-3.14/drivers/staging/rtl8821ae/core.c
  205114. --- linux-3.14.14/drivers/staging/rtl8821ae/core.c 2014-07-28 10:07:25.000000000 -0500
  205115. +++ linux-imx6-3.14/drivers/staging/rtl8821ae/core.c 2014-12-08 00:31:54.552418001 -0600
  205116. @@ -1414,23 +1414,15 @@
  205117. * before switch channle or power save, or tx buffer packet
  205118. * maybe send after offchannel or rf sleep, this may cause
  205119. * dis-association by AP */
  205120. -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
  205121. -static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  205122. +static void rtl_op_flush(struct ieee80211_hw *hw,
  205123. + struct ieee80211_vif *vif,
  205124. + u32 queues, bool drop)
  205125. {
  205126. struct rtl_priv *rtlpriv = rtl_priv(hw);
  205127. if (rtlpriv->intf_ops->flush)
  205128. rtlpriv->intf_ops->flush(hw, queues, drop);
  205129. }
  205130. -#else
  205131. -static void rtl_op_flush(struct ieee80211_hw *hw, bool drop)
  205132. -{
  205133. - struct rtl_priv *rtlpriv = rtl_priv(hw);
  205134. -
  205135. - if (rtlpriv->intf_ops->flush)
  205136. - rtlpriv->intf_ops->flush(hw, drop);
  205137. -}
  205138. -#endif
  205139. const struct ieee80211_ops rtl_ops = {
  205140. .start = rtl_op_start,
  205141. diff -Nur linux-3.14.14/drivers/thermal/device_cooling.c linux-imx6-3.14/drivers/thermal/device_cooling.c
  205142. --- linux-3.14.14/drivers/thermal/device_cooling.c 1969-12-31 18:00:00.000000000 -0600
  205143. +++ linux-imx6-3.14/drivers/thermal/device_cooling.c 2014-12-08 00:31:54.668418001 -0600
  205144. @@ -0,0 +1,151 @@
  205145. +/*
  205146. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  205147. + *
  205148. + * This program is free software; you can redistribute it and/or modify
  205149. + * it under the terms of the GNU General Public License version 2 as
  205150. + * published by the Free Software Foundation.
  205151. + *
  205152. + */
  205153. +
  205154. +#include <linux/module.h>
  205155. +#include <linux/thermal.h>
  205156. +#include <linux/err.h>
  205157. +#include <linux/slab.h>
  205158. +
  205159. +struct devfreq_cooling_device {
  205160. + int id;
  205161. + struct thermal_cooling_device *cool_dev;
  205162. + unsigned int devfreq_state;
  205163. +};
  205164. +
  205165. +static DEFINE_IDR(devfreq_idr);
  205166. +static DEFINE_MUTEX(devfreq_cooling_lock);
  205167. +
  205168. +#define MAX_STATE 1
  205169. +
  205170. +static BLOCKING_NOTIFIER_HEAD(devfreq_cooling_chain_head);
  205171. +
  205172. +int register_devfreq_cooling_notifier(struct notifier_block *nb)
  205173. +{
  205174. + return blocking_notifier_chain_register(
  205175. + &devfreq_cooling_chain_head, nb);
  205176. +}
  205177. +EXPORT_SYMBOL_GPL(register_devfreq_cooling_notifier);
  205178. +
  205179. +int unregister_devfreq_cooling_notifier(struct notifier_block *nb)
  205180. +{
  205181. + return blocking_notifier_chain_unregister(
  205182. + &devfreq_cooling_chain_head, nb);
  205183. +}
  205184. +EXPORT_SYMBOL_GPL(unregister_devfreq_cooling_notifier);
  205185. +
  205186. +static int devfreq_cooling_notifier_call_chain(unsigned long val)
  205187. +{
  205188. + return (blocking_notifier_call_chain(
  205189. + &devfreq_cooling_chain_head, val, NULL)
  205190. + == NOTIFY_BAD) ? -EINVAL : 0;
  205191. +}
  205192. +
  205193. +static int devfreq_set_cur_state(struct thermal_cooling_device *cdev,
  205194. + unsigned long state)
  205195. +{
  205196. + struct devfreq_cooling_device *devfreq_device = cdev->devdata;
  205197. + int ret;
  205198. +
  205199. + ret = devfreq_cooling_notifier_call_chain(state);
  205200. + if (ret)
  205201. + return -EINVAL;
  205202. + devfreq_device->devfreq_state = state;
  205203. +
  205204. + return 0;
  205205. +}
  205206. +
  205207. +static int devfreq_get_max_state(struct thermal_cooling_device *cdev,
  205208. + unsigned long *state)
  205209. +{
  205210. + *state = MAX_STATE;
  205211. +
  205212. + return 0;
  205213. +}
  205214. +
  205215. +static int devfreq_get_cur_state(struct thermal_cooling_device *cdev,
  205216. + unsigned long *state)
  205217. +{
  205218. + struct devfreq_cooling_device *devfreq_device = cdev->devdata;
  205219. +
  205220. + *state = devfreq_device->devfreq_state;
  205221. +
  205222. + return 0;
  205223. +}
  205224. +
  205225. +static struct thermal_cooling_device_ops const devfreq_cooling_ops = {
  205226. + .get_max_state = devfreq_get_max_state,
  205227. + .get_cur_state = devfreq_get_cur_state,
  205228. + .set_cur_state = devfreq_set_cur_state,
  205229. +};
  205230. +
  205231. +static int get_idr(struct idr *idr, int *id)
  205232. +{
  205233. + int ret;
  205234. +
  205235. + mutex_lock(&devfreq_cooling_lock);
  205236. + ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
  205237. + mutex_unlock(&devfreq_cooling_lock);
  205238. + if (unlikely(ret < 0))
  205239. + return ret;
  205240. + *id = ret;
  205241. +
  205242. + return 0;
  205243. +}
  205244. +
  205245. +static void release_idr(struct idr *idr, int id)
  205246. +{
  205247. + mutex_lock(&devfreq_cooling_lock);
  205248. + idr_remove(idr, id);
  205249. + mutex_unlock(&devfreq_cooling_lock);
  205250. +}
  205251. +
  205252. +struct thermal_cooling_device *devfreq_cooling_register(void)
  205253. +{
  205254. + struct thermal_cooling_device *cool_dev;
  205255. + struct devfreq_cooling_device *devfreq_dev = NULL;
  205256. + char dev_name[THERMAL_NAME_LENGTH];
  205257. + int ret = 0;
  205258. +
  205259. + devfreq_dev = kzalloc(sizeof(struct devfreq_cooling_device),
  205260. + GFP_KERNEL);
  205261. + if (!devfreq_dev)
  205262. + return ERR_PTR(-ENOMEM);
  205263. +
  205264. + ret = get_idr(&devfreq_idr, &devfreq_dev->id);
  205265. + if (ret) {
  205266. + kfree(devfreq_dev);
  205267. + return ERR_PTR(-EINVAL);
  205268. + }
  205269. +
  205270. + snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d",
  205271. + devfreq_dev->id);
  205272. +
  205273. + cool_dev = thermal_cooling_device_register(dev_name, devfreq_dev,
  205274. + &devfreq_cooling_ops);
  205275. + if (!cool_dev) {
  205276. + release_idr(&devfreq_idr, devfreq_dev->id);
  205277. + kfree(devfreq_dev);
  205278. + return ERR_PTR(-EINVAL);
  205279. + }
  205280. + devfreq_dev->cool_dev = cool_dev;
  205281. + devfreq_dev->devfreq_state = 0;
  205282. +
  205283. + return cool_dev;
  205284. +}
  205285. +EXPORT_SYMBOL_GPL(devfreq_cooling_register);
  205286. +
  205287. +void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
  205288. +{
  205289. + struct devfreq_cooling_device *devfreq_dev = cdev->devdata;
  205290. +
  205291. + thermal_cooling_device_unregister(devfreq_dev->cool_dev);
  205292. + release_idr(&devfreq_idr, devfreq_dev->id);
  205293. + kfree(devfreq_dev);
  205294. +}
  205295. +EXPORT_SYMBOL_GPL(devfreq_cooling_unregister);
  205296. diff -Nur linux-3.14.14/drivers/thermal/imx_thermal.c linux-imx6-3.14/drivers/thermal/imx_thermal.c
  205297. --- linux-3.14.14/drivers/thermal/imx_thermal.c 2014-07-28 10:07:25.000000000 -0500
  205298. +++ linux-imx6-3.14/drivers/thermal/imx_thermal.c 2014-12-08 00:31:54.668418001 -0600
  205299. @@ -12,6 +12,7 @@
  205300. #include <linux/cpufreq.h>
  205301. #include <linux/delay.h>
  205302. #include <linux/device.h>
  205303. +#include <linux/device_cooling.h>
  205304. #include <linux/init.h>
  205305. #include <linux/interrupt.h>
  205306. #include <linux/io.h>
  205307. @@ -58,13 +59,14 @@
  205308. * that will trigger cooling action when crossed.
  205309. */
  205310. #define IMX_TEMP_PASSIVE 85000
  205311. +#define IMX_TEMP_PASSIVE_COOL_DELTA 10000
  205312. #define IMX_POLLING_DELAY 2000 /* millisecond */
  205313. #define IMX_PASSIVE_DELAY 1000
  205314. struct imx_thermal_data {
  205315. struct thermal_zone_device *tz;
  205316. - struct thermal_cooling_device *cdev;
  205317. + struct thermal_cooling_device *cdev[2];
  205318. enum thermal_device_mode mode;
  205319. struct regmap *tempmon;
  205320. int c1, c2; /* See formula in imx_get_sensor_data() */
  205321. @@ -286,6 +288,24 @@
  205322. return 0;
  205323. }
  205324. + int imx_get_trend(struct thermal_zone_device *tz,
  205325. + int trip, enum thermal_trend *trend)
  205326. +{
  205327. + int ret;
  205328. + unsigned long trip_temp;
  205329. +
  205330. + ret = imx_get_trip_temp(tz, trip, &trip_temp);
  205331. + if (ret < 0)
  205332. + return ret;
  205333. +
  205334. + if (tz->temperature >= (trip_temp - IMX_TEMP_PASSIVE_COOL_DELTA))
  205335. + *trend = THERMAL_TREND_RAISE_FULL;
  205336. + else
  205337. + *trend = THERMAL_TREND_DROP_FULL;
  205338. +
  205339. + return 0;
  205340. +}
  205341. +
  205342. static struct thermal_zone_device_ops imx_tz_ops = {
  205343. .bind = imx_bind,
  205344. .unbind = imx_unbind,
  205345. @@ -295,6 +315,7 @@
  205346. .get_trip_type = imx_get_trip_type,
  205347. .get_trip_temp = imx_get_trip_temp,
  205348. .get_crit_temp = imx_get_crit_temp,
  205349. + .get_trend = imx_get_trend,
  205350. .set_trip_temp = imx_set_trip_temp,
  205351. };
  205352. @@ -437,9 +458,17 @@
  205353. regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
  205354. cpumask_set_cpu(0, &clip_cpus);
  205355. - data->cdev = cpufreq_cooling_register(&clip_cpus);
  205356. - if (IS_ERR(data->cdev)) {
  205357. - ret = PTR_ERR(data->cdev);
  205358. + data->cdev[0] = cpufreq_cooling_register(&clip_cpus);
  205359. + if (IS_ERR(data->cdev[0])) {
  205360. + ret = PTR_ERR(data->cdev[0]);
  205361. + dev_err(&pdev->dev,
  205362. + "failed to register cpufreq cooling device: %d\n", ret);
  205363. + return ret;
  205364. + }
  205365. +
  205366. + data->cdev[1] = cpufreq_cooling_register(&clip_cpus);
  205367. + if (IS_ERR(data->cdev[1])) {
  205368. + ret = PTR_ERR(data->cdev[1]);
  205369. dev_err(&pdev->dev,
  205370. "failed to register cpufreq cooling device: %d\n", ret);
  205371. return ret;
  205372. @@ -455,7 +484,8 @@
  205373. ret = PTR_ERR(data->tz);
  205374. dev_err(&pdev->dev,
  205375. "failed to register thermal zone device %d\n", ret);
  205376. - cpufreq_cooling_unregister(data->cdev);
  205377. + cpufreq_cooling_unregister(data->cdev[0]);
  205378. + devfreq_cooling_unregister(data->cdev[1]);
  205379. return ret;
  205380. }
  205381. @@ -500,7 +530,8 @@
  205382. clk_disable_unprepare(data->thermal_clk);
  205383. thermal_zone_device_unregister(data->tz);
  205384. - cpufreq_cooling_unregister(data->cdev);
  205385. + cpufreq_cooling_unregister(data->cdev[0]);
  205386. + devfreq_cooling_unregister(data->cdev[1]);
  205387. return 0;
  205388. }
  205389. diff -Nur linux-3.14.14/drivers/thermal/Kconfig linux-imx6-3.14/drivers/thermal/Kconfig
  205390. --- linux-3.14.14/drivers/thermal/Kconfig 2014-07-28 10:07:25.000000000 -0500
  205391. +++ linux-imx6-3.14/drivers/thermal/Kconfig 2014-12-08 00:31:54.668418001 -0600
  205392. @@ -125,6 +125,13 @@
  205393. cpufreq is used as the cooling device to throttle CPUs when the
  205394. passive trip is crossed.
  205395. +config DEVICE_THERMAL
  205396. + tristate "generic device cooling support"
  205397. + help
  205398. + Support for device cooling.
  205399. + It supports notification of crossing passive trip for devices,
  205400. + devices need to do their own actions to cool down the SOC.
  205401. +
  205402. config SPEAR_THERMAL
  205403. bool "SPEAr thermal sensor driver"
  205404. depends on PLAT_SPEAR
  205405. diff -Nur linux-3.14.14/drivers/thermal/Makefile linux-imx6-3.14/drivers/thermal/Makefile
  205406. --- linux-3.14.14/drivers/thermal/Makefile 2014-07-28 10:07:25.000000000 -0500
  205407. +++ linux-imx6-3.14/drivers/thermal/Makefile 2014-12-08 00:31:54.668418001 -0600
  205408. @@ -26,6 +26,7 @@
  205409. obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
  205410. obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
  205411. obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
  205412. +obj-$(CONFIG_DEVICE_THERMAL) += device_cooling.o
  205413. obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
  205414. obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
  205415. obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o
  205416. diff -Nur linux-3.14.14/drivers/tty/serial/earlycon.c linux-imx6-3.14/drivers/tty/serial/earlycon.c
  205417. --- linux-3.14.14/drivers/tty/serial/earlycon.c 1969-12-31 18:00:00.000000000 -0600
  205418. +++ linux-imx6-3.14/drivers/tty/serial/earlycon.c 2014-12-08 00:31:54.688418001 -0600
  205419. @@ -0,0 +1,152 @@
  205420. +/*
  205421. + * Copyright (C) 2014 Linaro Ltd.
  205422. + * Author: Rob Herring <robh@kernel.org>
  205423. + *
  205424. + * Based on 8250 earlycon:
  205425. + * (c) Copyright 2004 Hewlett-Packard Development Company, L.P.
  205426. + * Bjorn Helgaas <bjorn.helgaas@hp.com>
  205427. + *
  205428. + * This program is free software: you can redistribute it and/or modify
  205429. + * it under the terms of the GNU General Public License version 2 as
  205430. + * published by the Free Software Foundation.
  205431. + */
  205432. +#include <linux/console.h>
  205433. +#include <linux/kernel.h>
  205434. +#include <linux/init.h>
  205435. +#include <linux/io.h>
  205436. +#include <linux/serial_core.h>
  205437. +
  205438. +#ifdef CONFIG_FIX_EARLYCON_MEM
  205439. +#include <asm/fixmap.h>
  205440. +#endif
  205441. +
  205442. +#include <asm/serial.h>
  205443. +
  205444. +static struct console early_con = {
  205445. + .name = "earlycon",
  205446. + .flags = CON_PRINTBUFFER | CON_BOOT,
  205447. + .index = -1,
  205448. +};
  205449. +
  205450. +static struct earlycon_device early_console_dev = {
  205451. + .con = &early_con,
  205452. +};
  205453. +
  205454. +static void __iomem * __init earlycon_map(unsigned long paddr, size_t size)
  205455. +{
  205456. + void __iomem *base;
  205457. +#ifdef CONFIG_FIX_EARLYCON_MEM
  205458. + set_fixmap_io(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK);
  205459. + base = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
  205460. + base += paddr & ~PAGE_MASK;
  205461. +#else
  205462. + base = ioremap(paddr, size);
  205463. +#endif
  205464. + if (!base)
  205465. + pr_err("%s: Couldn't map 0x%llx\n", __func__,
  205466. + (unsigned long long)paddr);
  205467. +
  205468. + return base;
  205469. +}
  205470. +
  205471. +static int __init parse_options(struct earlycon_device *device,
  205472. + char *options)
  205473. +{
  205474. + struct uart_port *port = &device->port;
  205475. + int mmio, mmio32, length, ret;
  205476. + unsigned long addr;
  205477. +
  205478. + if (!options)
  205479. + return -ENODEV;
  205480. +
  205481. + mmio = !strncmp(options, "mmio,", 5);
  205482. + mmio32 = !strncmp(options, "mmio32,", 7);
  205483. + if (mmio || mmio32) {
  205484. + port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32);
  205485. + options += mmio ? 5 : 7;
  205486. + ret = kstrtoul(options, 0, &addr);
  205487. + if (ret)
  205488. + return ret;
  205489. + port->mapbase = addr;
  205490. + if (mmio32)
  205491. + port->regshift = 2;
  205492. + } else if (!strncmp(options, "io,", 3)) {
  205493. + port->iotype = UPIO_PORT;
  205494. + options += 3;
  205495. + ret = kstrtoul(options, 0, &addr);
  205496. + if (ret)
  205497. + return ret;
  205498. + port->iobase = addr;
  205499. + mmio = 0;
  205500. + } else if (!strncmp(options, "0x", 2)) {
  205501. + port->iotype = UPIO_MEM;
  205502. + ret = kstrtoul(options, 0, &addr);
  205503. + if (ret)
  205504. + return ret;
  205505. + port->mapbase = addr;
  205506. + } else {
  205507. + return -EINVAL;
  205508. + }
  205509. +
  205510. + port->uartclk = BASE_BAUD * 16;
  205511. +
  205512. + options = strchr(options, ',');
  205513. + if (options) {
  205514. + options++;
  205515. + ret = kstrtouint(options, 0, &device->baud);
  205516. + if (ret)
  205517. + return ret;
  205518. + length = min(strcspn(options, " ") + 1,
  205519. + (size_t)(sizeof(device->options)));
  205520. + strlcpy(device->options, options, length);
  205521. + }
  205522. +
  205523. + if (mmio || mmio32)
  205524. + pr_info("Early serial console at MMIO%s 0x%llx (options '%s')\n",
  205525. + mmio32 ? "32" : "",
  205526. + (unsigned long long)port->mapbase,
  205527. + device->options);
  205528. + else
  205529. + pr_info("Early serial console at I/O port 0x%lx (options '%s')\n",
  205530. + port->iobase,
  205531. + device->options);
  205532. +
  205533. + return 0;
  205534. +}
  205535. +
  205536. +int __init setup_earlycon(char *buf, const char *match,
  205537. + int (*setup)(struct earlycon_device *, const char *))
  205538. +{
  205539. + int err;
  205540. + size_t len;
  205541. + struct uart_port *port = &early_console_dev.port;
  205542. +
  205543. + if (!buf || !match || !setup)
  205544. + return 0;
  205545. +
  205546. + len = strlen(match);
  205547. + if (strncmp(buf, match, len))
  205548. + return 0;
  205549. + if (buf[len] && (buf[len] != ','))
  205550. + return 0;
  205551. +
  205552. + buf += len + 1;
  205553. +
  205554. + err = parse_options(&early_console_dev, buf);
  205555. + /* On parsing error, pass the options buf to the setup function */
  205556. + if (!err)
  205557. + buf = NULL;
  205558. +
  205559. + if (port->mapbase)
  205560. + port->membase = earlycon_map(port->mapbase, 64);
  205561. +
  205562. + early_console_dev.con->data = &early_console_dev;
  205563. + err = setup(&early_console_dev, buf);
  205564. + if (err < 0)
  205565. + return err;
  205566. + if (!early_console_dev.con->write)
  205567. + return -ENODEV;
  205568. +
  205569. + register_console(early_console_dev.con);
  205570. + return 0;
  205571. +}
  205572. diff -Nur linux-3.14.14/drivers/tty/serial/Kconfig linux-imx6-3.14/drivers/tty/serial/Kconfig
  205573. --- linux-3.14.14/drivers/tty/serial/Kconfig 2014-07-28 10:07:25.000000000 -0500
  205574. +++ linux-imx6-3.14/drivers/tty/serial/Kconfig 2014-12-08 00:31:54.684418001 -0600
  205575. @@ -7,6 +7,13 @@
  205576. menu "Serial drivers"
  205577. depends on HAS_IOMEM
  205578. +config SERIAL_EARLYCON
  205579. + bool
  205580. + help
  205581. + Support for early consoles with the earlycon parameter. This enables
  205582. + the console before standard serial driver is probed. The console is
  205583. + enabled when early_param is processed.
  205584. +
  205585. source "drivers/tty/serial/8250/Kconfig"
  205586. comment "Non-8250 serial port support"
  205587. diff -Nur linux-3.14.14/drivers/tty/serial/Makefile linux-imx6-3.14/drivers/tty/serial/Makefile
  205588. --- linux-3.14.14/drivers/tty/serial/Makefile 2014-07-28 10:07:25.000000000 -0500
  205589. +++ linux-imx6-3.14/drivers/tty/serial/Makefile 2014-12-08 00:31:54.684418001 -0600
  205590. @@ -5,6 +5,8 @@
  205591. obj-$(CONFIG_SERIAL_CORE) += serial_core.o
  205592. obj-$(CONFIG_SERIAL_21285) += 21285.o
  205593. +obj-$(CONFIG_SERIAL_EARLYCON) += earlycon.o
  205594. +
  205595. # These Sparc drivers have to appear before others such as 8250
  205596. # which share ttySx minor node space. Otherwise console device
  205597. # names change and other unplesantries.
  205598. diff -Nur linux-3.14.14/drivers/usb/chipidea/ci.h linux-imx6-3.14/drivers/usb/chipidea/ci.h
  205599. --- linux-3.14.14/drivers/usb/chipidea/ci.h 2014-07-28 10:07:25.000000000 -0500
  205600. +++ linux-imx6-3.14/drivers/usb/chipidea/ci.h 2014-12-08 00:31:54.712418001 -0600
  205601. @@ -139,8 +139,8 @@
  205602. * @roles: array of supported roles for this controller
  205603. * @role: current role
  205604. * @is_otg: if the device is otg-capable
  205605. - * @work: work for role changing
  205606. - * @wq: workqueue thread
  205607. + * @otg_task: the thread for handling otg task
  205608. + * @otg_wait: the otg event waitqueue head
  205609. * @qh_pool: allocation pool for queue heads
  205610. * @td_pool: allocation pool for transfer descriptors
  205611. * @gadget: device side representation for peripheral controller
  205612. @@ -165,6 +165,10 @@
  205613. * @b_sess_valid_event: indicates there is a vbus event, and handled
  205614. * at ci_otg_work
  205615. * @imx28_write_fix: Freescale imx28 needs swp instruction for writing
  205616. + * @supports_runtime_pm: if runtime pm is supported
  205617. + * @in_lpm: if the core in low power mode
  205618. + * @wakeup_int: if wakeup interrupt occur
  205619. + * @timer: timer to delay clock closing
  205620. */
  205621. struct ci_hdrc {
  205622. struct device *dev;
  205623. @@ -174,8 +178,8 @@
  205624. struct ci_role_driver *roles[CI_ROLE_END];
  205625. enum ci_role role;
  205626. bool is_otg;
  205627. - struct work_struct work;
  205628. - struct workqueue_struct *wq;
  205629. + struct task_struct *otg_task;
  205630. + wait_queue_head_t otg_wait;
  205631. struct dma_pool *qh_pool;
  205632. struct dma_pool *td_pool;
  205633. @@ -204,6 +208,10 @@
  205634. bool id_event;
  205635. bool b_sess_valid_event;
  205636. bool imx28_write_fix;
  205637. + bool supports_runtime_pm;
  205638. + bool in_lpm;
  205639. + bool wakeup_int;
  205640. + struct timer_list timer;
  205641. };
  205642. static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
  205643. diff -Nur linux-3.14.14/drivers/usb/chipidea/ci_hdrc_imx.c linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_imx.c
  205644. --- linux-3.14.14/drivers/usb/chipidea/ci_hdrc_imx.c 2014-07-28 10:07:25.000000000 -0500
  205645. +++ linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_imx.c 2014-12-08 00:31:54.712418001 -0600
  205646. @@ -19,11 +19,14 @@
  205647. #include <linux/dma-mapping.h>
  205648. #include <linux/usb/chipidea.h>
  205649. #include <linux/clk.h>
  205650. +#include <linux/busfreq-imx6.h>
  205651. #include "ci.h"
  205652. #include "ci_hdrc_imx.h"
  205653. -#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
  205654. +#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
  205655. +#define CI_HDRC_IMX_SUPPORT_RUNTIME_PM BIT(1)
  205656. +#define CI_HDRC_IMX_HOST_QUIRK BIT(2)
  205657. struct ci_hdrc_imx_platform_flag {
  205658. unsigned int flags;
  205659. @@ -32,12 +35,30 @@
  205660. static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
  205661. };
  205662. +static const struct ci_hdrc_imx_platform_flag imx23_usb_data = {
  205663. + .flags = CI_HDRC_IMX_HOST_QUIRK,
  205664. +};
  205665. +
  205666. static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
  205667. - .flags = CI_HDRC_IMX_IMX28_WRITE_FIX,
  205668. + .flags = CI_HDRC_IMX_IMX28_WRITE_FIX |
  205669. + CI_HDRC_IMX_HOST_QUIRK,
  205670. +};
  205671. +
  205672. +static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
  205673. + .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM |
  205674. + CI_HDRC_IMX_HOST_QUIRK,
  205675. +};
  205676. +
  205677. +static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
  205678. + .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM |
  205679. + CI_HDRC_IMX_HOST_QUIRK,
  205680. };
  205681. static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
  205682. + { .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
  205683. + { .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
  205684. { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
  205685. + { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
  205686. { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
  205687. { /* sentinel */ }
  205688. };
  205689. @@ -48,6 +69,8 @@
  205690. struct platform_device *ci_pdev;
  205691. struct clk *clk;
  205692. struct imx_usbmisc_data *usbmisc_data;
  205693. + bool supports_runtime_pm;
  205694. + bool in_lpm;
  205695. };
  205696. /* Common functions shared by usbmisc drivers */
  205697. @@ -123,8 +146,10 @@
  205698. return PTR_ERR(data->clk);
  205699. }
  205700. + request_bus_freq(BUS_FREQ_HIGH);
  205701. ret = clk_prepare_enable(data->clk);
  205702. if (ret) {
  205703. + release_bus_freq(BUS_FREQ_HIGH);
  205704. dev_err(&pdev->dev,
  205705. "Failed to prepare or enable clock, err=%d\n", ret);
  205706. return ret;
  205707. @@ -145,6 +170,14 @@
  205708. if (ret)
  205709. goto err_clk;
  205710. + if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM) {
  205711. + pdata.flags |= CI_HDRC_SUPPORTS_RUNTIME_PM;
  205712. + data->supports_runtime_pm = true;
  205713. + }
  205714. +
  205715. + if (imx_platform_flag->flags & CI_HDRC_IMX_HOST_QUIRK)
  205716. + pdata.flags |= CI_HDRC_IMX_EHCI_QUIRK;
  205717. +
  205718. if (data->usbmisc_data) {
  205719. ret = imx_usbmisc_init(data->usbmisc_data);
  205720. if (ret) {
  205721. @@ -165,6 +198,11 @@
  205722. goto err_clk;
  205723. }
  205724. + /* usbmisc needs to know dr mode to choose wakeup setting */
  205725. + if (data->usbmisc_data)
  205726. + data->usbmisc_data->available_role =
  205727. + ci_hdrc_query_available_role(data->ci_pdev);
  205728. +
  205729. if (data->usbmisc_data) {
  205730. ret = imx_usbmisc_init_post(data->usbmisc_data);
  205731. if (ret) {
  205732. @@ -174,10 +212,23 @@
  205733. }
  205734. }
  205735. + if (data->usbmisc_data) {
  205736. + ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
  205737. + if (ret) {
  205738. + dev_err(&pdev->dev, "usbmisc set_wakeup failed, ret=%d\n",
  205739. + ret);
  205740. + goto disable_device;
  205741. + }
  205742. + }
  205743. +
  205744. platform_set_drvdata(pdev, data);
  205745. - pm_runtime_no_callbacks(&pdev->dev);
  205746. - pm_runtime_enable(&pdev->dev);
  205747. + device_set_wakeup_capable(&pdev->dev, true);
  205748. +
  205749. + if (data->supports_runtime_pm) {
  205750. + pm_runtime_set_active(&pdev->dev);
  205751. + pm_runtime_enable(&pdev->dev);
  205752. + }
  205753. return 0;
  205754. @@ -185,6 +236,7 @@
  205755. ci_hdrc_remove_device(data->ci_pdev);
  205756. err_clk:
  205757. clk_disable_unprepare(data->clk);
  205758. + release_bus_freq(BUS_FREQ_HIGH);
  205759. return ret;
  205760. }
  205761. @@ -195,10 +247,119 @@
  205762. pm_runtime_disable(&pdev->dev);
  205763. ci_hdrc_remove_device(data->ci_pdev);
  205764. clk_disable_unprepare(data->clk);
  205765. + release_bus_freq(BUS_FREQ_HIGH);
  205766. return 0;
  205767. }
  205768. +#ifdef CONFIG_PM
  205769. +static int imx_controller_suspend(struct device *dev)
  205770. +{
  205771. + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
  205772. + int ret;
  205773. +
  205774. + dev_dbg(dev, "at %s\n", __func__);
  205775. +
  205776. + if (data->in_lpm)
  205777. + return 0;
  205778. +
  205779. + if (data->usbmisc_data) {
  205780. + ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true);
  205781. + if (ret) {
  205782. + dev_err(dev,
  205783. + "usbmisc set_wakeup failed, ret=%d\n",
  205784. + ret);
  205785. + return ret;
  205786. + }
  205787. + }
  205788. +
  205789. + clk_disable_unprepare(data->clk);
  205790. + release_bus_freq(BUS_FREQ_HIGH);
  205791. + data->in_lpm = true;
  205792. +
  205793. + return 0;
  205794. +}
  205795. +
  205796. +static int imx_controller_resume(struct device *dev)
  205797. +{
  205798. + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
  205799. + int ret = 0;
  205800. +
  205801. + dev_dbg(dev, "at %s\n", __func__);
  205802. +
  205803. + if (!data->in_lpm)
  205804. + return 0;
  205805. +
  205806. + request_bus_freq(BUS_FREQ_HIGH);
  205807. + ret = clk_prepare_enable(data->clk);
  205808. + if (ret) {
  205809. + release_bus_freq(BUS_FREQ_HIGH);
  205810. + return ret;
  205811. + }
  205812. +
  205813. + data->in_lpm = false;
  205814. +
  205815. + if (data->usbmisc_data) {
  205816. + ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
  205817. + if (ret) {
  205818. + dev_err(dev,
  205819. + "usbmisc set_wakeup failed, ret=%d\n",
  205820. + ret);
  205821. + ret = -EINVAL;
  205822. + goto clk_disable;
  205823. + }
  205824. + }
  205825. +
  205826. + return 0;
  205827. +
  205828. +clk_disable:
  205829. + clk_disable_unprepare(data->clk);
  205830. + release_bus_freq(BUS_FREQ_HIGH);
  205831. +
  205832. + return ret;
  205833. +}
  205834. +
  205835. +#ifdef CONFIG_PM_SLEEP
  205836. +static int ci_hdrc_imx_suspend(struct device *dev)
  205837. +{
  205838. + return imx_controller_suspend(dev);
  205839. +}
  205840. +
  205841. +static int ci_hdrc_imx_resume(struct device *dev)
  205842. +{
  205843. + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
  205844. + int ret;
  205845. +
  205846. + ret = imx_controller_resume(dev);
  205847. + if (!ret && data->supports_runtime_pm) {
  205848. + pm_runtime_disable(dev);
  205849. + pm_runtime_set_active(dev);
  205850. + pm_runtime_enable(dev);
  205851. + }
  205852. +
  205853. + return ret;
  205854. +}
  205855. +#endif /* CONFIG_PM_SLEEP */
  205856. +
  205857. +#ifdef CONFIG_PM_RUNTIME
  205858. +static int ci_hdrc_imx_runtime_suspend(struct device *dev)
  205859. +{
  205860. + return imx_controller_suspend(dev);
  205861. +}
  205862. +
  205863. +static int ci_hdrc_imx_runtime_resume(struct device *dev)
  205864. +{
  205865. + return imx_controller_resume(dev);
  205866. +}
  205867. +#endif /* CONFIG_PM_RUNTIME */
  205868. +
  205869. +#endif /* CONFIG_PM */
  205870. +static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
  205871. + SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
  205872. + SET_RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend,
  205873. + ci_hdrc_imx_runtime_resume, NULL)
  205874. +};
  205875. +
  205876. static struct platform_driver ci_hdrc_imx_driver = {
  205877. .probe = ci_hdrc_imx_probe,
  205878. .remove = ci_hdrc_imx_remove,
  205879. @@ -206,6 +367,7 @@
  205880. .name = "imx_usb",
  205881. .owner = THIS_MODULE,
  205882. .of_match_table = ci_hdrc_imx_dt_ids,
  205883. + .pm = &ci_hdrc_imx_pm_ops,
  205884. },
  205885. };
  205886. diff -Nur linux-3.14.14/drivers/usb/chipidea/ci_hdrc_imx.h linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_imx.h
  205887. --- linux-3.14.14/drivers/usb/chipidea/ci_hdrc_imx.h 2014-07-28 10:07:25.000000000 -0500
  205888. +++ linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_imx.h 2014-12-08 00:31:54.712418001 -0600
  205889. @@ -1,5 +1,5 @@
  205890. /*
  205891. - * Copyright 2012 Freescale Semiconductor, Inc.
  205892. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  205893. *
  205894. * The code contained herein is licensed under the GNU General Public
  205895. * License. You may obtain a copy of the GNU General Public License
  205896. @@ -12,14 +12,18 @@
  205897. #ifndef __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H
  205898. #define __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H
  205899. +#include <linux/usb/otg.h>
  205900. +
  205901. struct imx_usbmisc_data {
  205902. int index;
  205903. unsigned int disable_oc:1; /* over current detect disabled */
  205904. unsigned int evdo:1; /* set external vbus divider option */
  205905. + enum usb_dr_mode available_role;
  205906. };
  205907. int imx_usbmisc_init(struct imx_usbmisc_data *);
  205908. int imx_usbmisc_init_post(struct imx_usbmisc_data *);
  205909. +int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *, bool);
  205910. #endif /* __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H */
  205911. diff -Nur linux-3.14.14/drivers/usb/chipidea/ci_hdrc_msm.c linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_msm.c
  205912. --- linux-3.14.14/drivers/usb/chipidea/ci_hdrc_msm.c 2014-07-28 10:07:25.000000000 -0500
  205913. +++ linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_msm.c 2014-12-08 00:31:54.712418001 -0600
  205914. @@ -17,7 +17,7 @@
  205915. #define MSM_USB_BASE (ci->hw_bank.abs)
  205916. -static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
  205917. +static int ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
  205918. {
  205919. struct device *dev = ci->gadget.dev.parent;
  205920. int val;
  205921. @@ -43,6 +43,8 @@
  205922. dev_dbg(dev, "unknown ci_hdrc event\n");
  205923. break;
  205924. }
  205925. +
  205926. + return 0;
  205927. }
  205928. static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
  205929. diff -Nur linux-3.14.14/drivers/usb/chipidea/core.c linux-imx6-3.14/drivers/usb/chipidea/core.c
  205930. --- linux-3.14.14/drivers/usb/chipidea/core.c 2014-07-28 10:07:25.000000000 -0500
  205931. +++ linux-imx6-3.14/drivers/usb/chipidea/core.c 2014-12-08 00:31:54.712418001 -0600
  205932. @@ -165,25 +165,30 @@
  205933. return hw_read(ci, OP_PORTSC, PORTSC_PTC) >> __ffs(PORTSC_PTC);
  205934. }
  205935. +static void hw_wait_phy_stable(void)
  205936. +{
  205937. + /* The controller needs at least 1ms to reflect PHY's status */
  205938. + usleep_range(2000, 2500);
  205939. +}
  205940. +
  205941. +static void delay_runtime_pm_put_timer(unsigned long arg)
  205942. +{
  205943. + struct ci_hdrc *ci = (struct ci_hdrc *)arg;
  205944. +
  205945. + pm_runtime_put(ci->dev);
  205946. +}
  205947. +
  205948. /* The PHY enters/leaves low power mode */
  205949. static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable)
  205950. {
  205951. enum ci_hw_regs reg = ci->hw_bank.lpm ? OP_DEVLC : OP_PORTSC;
  205952. bool lpm = !!(hw_read(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm)));
  205953. - if (enable && !lpm) {
  205954. + if (enable && !lpm)
  205955. hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
  205956. PORTSC_PHCD(ci->hw_bank.lpm));
  205957. - } else if (!enable && lpm) {
  205958. - hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
  205959. - 0);
  205960. - /*
  205961. - * The controller needs at least 1ms to reflect
  205962. - * PHY's status, the PHY also needs some time (less
  205963. - * than 1ms) to leave low power mode.
  205964. - */
  205965. - usleep_range(1500, 2000);
  205966. - }
  205967. + else if (!enable && lpm)
  205968. + hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm), 0);
  205969. }
  205970. static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
  205971. @@ -351,6 +356,13 @@
  205972. irqreturn_t ret = IRQ_NONE;
  205973. u32 otgsc = 0;
  205974. + if (ci->in_lpm) {
  205975. + disable_irq_nosync(irq);
  205976. + ci->wakeup_int = true;
  205977. + pm_runtime_get(ci->dev);
  205978. + return IRQ_HANDLED;
  205979. + }
  205980. +
  205981. if (ci->is_otg)
  205982. otgsc = hw_read(ci, OP_OTGSC, ~0);
  205983. @@ -362,7 +374,7 @@
  205984. ci->id_event = true;
  205985. ci_clear_otg_interrupt(ci, OTGSC_IDIS);
  205986. disable_irq_nosync(ci->irq);
  205987. - queue_work(ci->wq, &ci->work);
  205988. + wake_up(&ci->otg_wait);
  205989. return IRQ_HANDLED;
  205990. }
  205991. @@ -374,7 +386,7 @@
  205992. ci->b_sess_valid_event = true;
  205993. ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
  205994. disable_irq_nosync(ci->irq);
  205995. - queue_work(ci->wq, &ci->work);
  205996. + wake_up(&ci->otg_wait);
  205997. return IRQ_HANDLED;
  205998. }
  205999. @@ -473,6 +485,33 @@
  206000. }
  206001. EXPORT_SYMBOL_GPL(ci_hdrc_remove_device);
  206002. +/**
  206003. + * ci_hdrc_query_available_role: get runtime available operation mode
  206004. + *
  206005. + * The glue layer can get current operation mode (host/peripheral/otg)
  206006. + * This function should be called after ci core device has created.
  206007. + *
  206008. + * @pdev: the platform device of ci core.
  206009. + *
  206010. + * Return USB_DR_MODE_XXX.
  206011. + */
  206012. +enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev)
  206013. +{
  206014. + struct ci_hdrc *ci = platform_get_drvdata(pdev);
  206015. +
  206016. + if (!ci)
  206017. + return USB_DR_MODE_UNKNOWN;
  206018. + if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET])
  206019. + return USB_DR_MODE_OTG;
  206020. + else if (ci->roles[CI_ROLE_HOST])
  206021. + return USB_DR_MODE_HOST;
  206022. + else if (ci->roles[CI_ROLE_GADGET])
  206023. + return USB_DR_MODE_PERIPHERAL;
  206024. + else
  206025. + return USB_DR_MODE_UNKNOWN;
  206026. +}
  206027. +EXPORT_SYMBOL_GPL(ci_hdrc_query_available_role);
  206028. +
  206029. static inline void ci_role_destroy(struct ci_hdrc *ci)
  206030. {
  206031. ci_hdrc_gadget_destroy(ci);
  206032. @@ -498,9 +537,14 @@
  206033. static int ci_usb_phy_init(struct ci_hdrc *ci)
  206034. {
  206035. + int ret;
  206036. +
  206037. if (ci->platdata->phy) {
  206038. ci->transceiver = ci->platdata->phy;
  206039. - return usb_phy_init(ci->transceiver);
  206040. + ret = usb_phy_init(ci->transceiver);
  206041. + if (!ret)
  206042. + hw_wait_phy_stable();
  206043. + return ret;
  206044. } else {
  206045. ci->global_phy = true;
  206046. ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
  206047. @@ -559,8 +603,6 @@
  206048. return -ENODEV;
  206049. }
  206050. - hw_phymode_configure(ci);
  206051. -
  206052. ret = ci_usb_phy_init(ci);
  206053. if (ret) {
  206054. dev_err(dev, "unable to init phy: %d\n", ret);
  206055. @@ -578,7 +620,13 @@
  206056. ci_get_otg_capable(ci);
  206057. + hw_phymode_configure(ci);
  206058. +
  206059. dr_mode = ci->platdata->dr_mode;
  206060. +
  206061. + ci->supports_runtime_pm = !!(ci->platdata->flags &
  206062. + CI_HDRC_SUPPORTS_RUNTIME_PM);
  206063. +
  206064. /* initialize role(s) before the interrupt is requested */
  206065. if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
  206066. ret = ci_hdrc_host_init(ci);
  206067. @@ -619,11 +667,6 @@
  206068. if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
  206069. if (ci->is_otg) {
  206070. - /*
  206071. - * ID pin needs 1ms debouce time,
  206072. - * we delay 2ms for safe.
  206073. - */
  206074. - mdelay(2);
  206075. ci->role = ci_otg_role(ci);
  206076. ci_enable_otg_interrupt(ci, OTGSC_IDIE);
  206077. } else {
  206078. @@ -656,6 +699,15 @@
  206079. if (ret)
  206080. goto stop;
  206081. + device_set_wakeup_capable(&pdev->dev, true);
  206082. +
  206083. + if (ci->supports_runtime_pm) {
  206084. + pm_runtime_set_active(&pdev->dev);
  206085. + pm_runtime_enable(&pdev->dev);
  206086. + }
  206087. +
  206088. + setup_timer(&ci->timer, delay_runtime_pm_put_timer,
  206089. + (unsigned long)ci);
  206090. ret = dbg_create_files(ci);
  206091. if (!ret)
  206092. return 0;
  206093. @@ -673,6 +725,11 @@
  206094. {
  206095. struct ci_hdrc *ci = platform_get_drvdata(pdev);
  206096. + if (ci->supports_runtime_pm) {
  206097. + pm_runtime_get_sync(&pdev->dev);
  206098. + pm_runtime_disable(&pdev->dev);
  206099. + pm_runtime_put_noidle(&pdev->dev);
  206100. + }
  206101. dbg_remove_files(ci);
  206102. free_irq(ci->irq, ci);
  206103. ci_role_destroy(ci);
  206104. @@ -682,11 +739,120 @@
  206105. return 0;
  206106. }
  206107. +#ifdef CONFIG_PM
  206108. +static int ci_controller_suspend(struct device *dev)
  206109. +{
  206110. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  206111. +
  206112. + dev_dbg(dev, "at %s\n", __func__);
  206113. +
  206114. + if (ci->in_lpm)
  206115. + return 0;
  206116. +
  206117. + disable_irq(ci->irq);
  206118. +
  206119. + if (ci->transceiver)
  206120. + usb_phy_set_wakeup(ci->transceiver, true);
  206121. +
  206122. + ci_hdrc_enter_lpm(ci, true);
  206123. +
  206124. + if (ci->transceiver)
  206125. + usb_phy_set_suspend(ci->transceiver, 1);
  206126. +
  206127. + ci->in_lpm = true;
  206128. +
  206129. + enable_irq(ci->irq);
  206130. +
  206131. + return 0;
  206132. +}
  206133. +
  206134. +static int ci_controller_resume(struct device *dev)
  206135. +{
  206136. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  206137. +
  206138. + dev_dbg(dev, "at %s\n", __func__);
  206139. +
  206140. + if (!ci->in_lpm)
  206141. + return 0;
  206142. +
  206143. + ci_hdrc_enter_lpm(ci, false);
  206144. +
  206145. + if (ci->transceiver) {
  206146. + usb_phy_set_suspend(ci->transceiver, 0);
  206147. + usb_phy_set_wakeup(ci->transceiver, false);
  206148. + hw_wait_phy_stable();
  206149. + }
  206150. +
  206151. + ci->in_lpm = false;
  206152. +
  206153. + if (ci->wakeup_int) {
  206154. + ci->wakeup_int = false;
  206155. + enable_irq(ci->irq);
  206156. + mod_timer(&ci->timer, jiffies + msecs_to_jiffies(2000));
  206157. + }
  206158. +
  206159. + return 0;
  206160. +}
  206161. +
  206162. +#ifdef CONFIG_PM_SLEEP
  206163. +static int ci_suspend(struct device *dev)
  206164. +{
  206165. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  206166. + int ret;
  206167. +
  206168. + ret = ci_controller_suspend(dev);
  206169. + if (ret)
  206170. + return ret;
  206171. +
  206172. + if (device_may_wakeup(dev))
  206173. + enable_irq_wake(ci->irq);
  206174. +
  206175. + return ret;
  206176. +}
  206177. +
  206178. +static int ci_resume(struct device *dev)
  206179. +{
  206180. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  206181. + int ret;
  206182. +
  206183. + if (device_may_wakeup(dev))
  206184. + disable_irq_wake(ci->irq);
  206185. +
  206186. + ret = ci_controller_resume(dev);
  206187. + if (!ret && ci->supports_runtime_pm) {
  206188. + pm_runtime_disable(dev);
  206189. + pm_runtime_set_active(dev);
  206190. + pm_runtime_enable(dev);
  206191. + }
  206192. +
  206193. + return ret;
  206194. +}
  206195. +#endif /* CONFIG_PM_SLEEP */
  206196. +
  206197. +#ifdef CONFIG_PM_RUNTIME
  206198. +static int ci_runtime_suspend(struct device *dev)
  206199. +{
  206200. + return ci_controller_suspend(dev);
  206201. +}
  206202. +
  206203. +static int ci_runtime_resume(struct device *dev)
  206204. +{
  206205. + return ci_controller_resume(dev);
  206206. +}
  206207. +#endif /* CONFIG_PM_RUNTIME */
  206208. +
  206209. +#endif /* CONFIG_PM */
  206210. +static const struct dev_pm_ops ci_pm_ops = {
  206211. + SET_SYSTEM_SLEEP_PM_OPS(ci_suspend, ci_resume)
  206212. + SET_RUNTIME_PM_OPS(ci_runtime_suspend, ci_runtime_resume, NULL)
  206213. +};
  206214. +
  206215. static struct platform_driver ci_hdrc_driver = {
  206216. .probe = ci_hdrc_probe,
  206217. .remove = ci_hdrc_remove,
  206218. .driver = {
  206219. .name = "ci_hdrc",
  206220. + .pm = &ci_pm_ops,
  206221. },
  206222. };
  206223. diff -Nur linux-3.14.14/drivers/usb/chipidea/host.c linux-imx6-3.14/drivers/usb/chipidea/host.c
  206224. --- linux-3.14.14/drivers/usb/chipidea/host.c 2014-07-28 10:07:25.000000000 -0500
  206225. +++ linux-imx6-3.14/drivers/usb/chipidea/host.c 2014-12-08 00:31:54.712418001 -0600
  206226. @@ -33,6 +33,176 @@
  206227. #include "host.h"
  206228. static struct hc_driver __read_mostly ci_ehci_hc_driver;
  206229. +static int (*orig_bus_suspend)(struct usb_hcd *hcd);
  206230. +static int (*orig_bus_resume)(struct usb_hcd *hcd);
  206231. +static int (*orig_hub_control)(struct usb_hcd *hcd,
  206232. + u16 typeReq, u16 wValue, u16 wIndex,
  206233. + char *buf, u16 wLength);
  206234. +
  206235. +static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
  206236. +{
  206237. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  206238. + int port;
  206239. + u32 tmp;
  206240. +
  206241. + int ret = orig_bus_suspend(hcd);
  206242. +
  206243. + if (ret)
  206244. + return ret;
  206245. +
  206246. + port = HCS_N_PORTS(ehci->hcs_params);
  206247. + while (port--) {
  206248. + u32 __iomem *reg = &ehci->regs->port_status[port];
  206249. + u32 portsc = ehci_readl(ehci, reg);
  206250. +
  206251. + if (portsc & PORT_CONNECT) {
  206252. + /*
  206253. + * For chipidea, the resume signal will be ended
  206254. + * automatically, so for remote wakeup case, the
  206255. + * usbcmd.rs may not be set before the resume has
  206256. + * ended if other resume path consumes too much
  206257. + * time (~23ms-24ms), in that case, the SOF will not
  206258. + * send out within 3ms after resume ends, then the
  206259. + * device will enter suspend again.
  206260. + */
  206261. + if (hcd->self.root_hub->do_remote_wakeup) {
  206262. + ehci_dbg(ehci,
  206263. + "Remote wakeup is enabled, "
  206264. + "and device is on the port\n");
  206265. +
  206266. + tmp = ehci_readl(ehci, &ehci->regs->command);
  206267. + tmp |= CMD_RUN;
  206268. + ehci_writel(ehci, tmp, &ehci->regs->command);
  206269. + /*
  206270. + * It needs a short delay between set RUNSTOP
  206271. + * and set PHCD.
  206272. + */
  206273. + udelay(125);
  206274. + }
  206275. + if (hcd->phy && test_bit(port, &ehci->bus_suspended)
  206276. + && (ehci_port_speed(ehci, portsc) ==
  206277. + USB_PORT_STAT_HIGH_SPEED))
  206278. + /*
  206279. + * notify the USB PHY, it is for global
  206280. + * suspend case.
  206281. + */
  206282. + usb_phy_notify_suspend(hcd->phy,
  206283. + USB_SPEED_HIGH);
  206284. + }
  206285. + }
  206286. +
  206287. + return 0;
  206288. +}
  206289. +
  206290. +static int ci_imx_ehci_bus_resume(struct usb_hcd *hcd)
  206291. +{
  206292. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  206293. + int port;
  206294. +
  206295. + int ret = orig_bus_resume(hcd);
  206296. +
  206297. + if (ret)
  206298. + return ret;
  206299. +
  206300. + port = HCS_N_PORTS(ehci->hcs_params);
  206301. + while (port--) {
  206302. + u32 __iomem *reg = &ehci->regs->port_status[port];
  206303. + u32 portsc = ehci_readl(ehci, reg);
  206304. + /*
  206305. + * Notify PHY after resume signal has finished, it is
  206306. + * for global suspend case.
  206307. + */
  206308. + if (hcd->phy
  206309. + && test_bit(port, &ehci->bus_suspended)
  206310. + && (portsc & PORT_CONNECT)
  206311. + && (ehci_port_speed(ehci, portsc) ==
  206312. + USB_PORT_STAT_HIGH_SPEED))
  206313. + /* notify the USB PHY */
  206314. + usb_phy_notify_resume(hcd->phy, USB_SPEED_HIGH);
  206315. + }
  206316. +
  206317. + return 0;
  206318. +}
  206319. +
  206320. +/* The below code is based on tegra ehci driver */
  206321. +static int ci_imx_ehci_hub_control(
  206322. + struct usb_hcd *hcd,
  206323. + u16 typeReq,
  206324. + u16 wValue,
  206325. + u16 wIndex,
  206326. + char *buf,
  206327. + u16 wLength
  206328. +)
  206329. +{
  206330. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  206331. + u32 __iomem *status_reg;
  206332. + u32 temp;
  206333. + unsigned long flags;
  206334. + int retval = 0;
  206335. +
  206336. + status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
  206337. +
  206338. + spin_lock_irqsave(&ehci->lock, flags);
  206339. +
  206340. + if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
  206341. + temp = ehci_readl(ehci, status_reg);
  206342. + if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
  206343. + retval = -EPIPE;
  206344. + goto done;
  206345. + }
  206346. +
  206347. + temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
  206348. + temp |= PORT_WKDISC_E | PORT_WKOC_E;
  206349. + ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
  206350. +
  206351. + /*
  206352. + * If a transaction is in progress, there may be a delay in
  206353. + * suspending the port. Poll until the port is suspended.
  206354. + */
  206355. + if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
  206356. + PORT_SUSPEND, 5000))
  206357. + ehci_err(ehci, "timeout waiting for SUSPEND\n");
  206358. +
  206359. + spin_unlock_irqrestore(&ehci->lock, flags);
  206360. + if (ehci_port_speed(ehci, temp) ==
  206361. + USB_PORT_STAT_HIGH_SPEED && hcd->phy) {
  206362. + /* notify the USB PHY */
  206363. + usb_phy_notify_suspend(hcd->phy, USB_SPEED_HIGH);
  206364. + }
  206365. + spin_lock_irqsave(&ehci->lock, flags);
  206366. +
  206367. + set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
  206368. + goto done;
  206369. + }
  206370. +
  206371. + /*
  206372. + * After resume has finished, it needs do some post resume
  206373. + * operation for some SoCs.
  206374. + */
  206375. + else if (typeReq == ClearPortFeature &&
  206376. + wValue == USB_PORT_FEAT_C_SUSPEND) {
  206377. +
  206378. + /* Make sure the resume has finished, it should be finished */
  206379. + if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 25000))
  206380. + ehci_err(ehci, "timeout waiting for resume\n");
  206381. +
  206382. + temp = ehci_readl(ehci, status_reg);
  206383. +
  206384. + if (ehci_port_speed(ehci, temp) ==
  206385. + USB_PORT_STAT_HIGH_SPEED && hcd->phy) {
  206386. + /* notify the USB PHY */
  206387. + usb_phy_notify_resume(hcd->phy, USB_SPEED_HIGH);
  206388. + }
  206389. + }
  206390. +
  206391. + spin_unlock_irqrestore(&ehci->lock, flags);
  206392. +
  206393. + /* Handle the hub control events here */
  206394. + return orig_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
  206395. +done:
  206396. + spin_unlock_irqrestore(&ehci->lock, flags);
  206397. + return retval;
  206398. +}
  206399. static irqreturn_t host_irq(struct ci_hdrc *ci)
  206400. {
  206401. @@ -64,7 +234,6 @@
  206402. ehci = hcd_to_ehci(hcd);
  206403. ehci->caps = ci->hw_bank.cap;
  206404. ehci->has_hostpc = ci->hw_bank.lpm;
  206405. - ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
  206406. ehci->imx28_write_fix = ci->imx28_write_fix;
  206407. if (ci->platdata->reg_vbus) {
  206408. @@ -136,5 +305,15 @@
  206409. ehci_init_driver(&ci_ehci_hc_driver, NULL);
  206410. + orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
  206411. + orig_bus_resume = ci_ehci_hc_driver.bus_resume;
  206412. + orig_hub_control = ci_ehci_hc_driver.hub_control;
  206413. +
  206414. + ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
  206415. + if (ci->platdata->flags & CI_HDRC_IMX_EHCI_QUIRK) {
  206416. + ci_ehci_hc_driver.bus_resume = ci_imx_ehci_bus_resume;
  206417. + ci_ehci_hc_driver.hub_control = ci_imx_ehci_hub_control;
  206418. + }
  206419. +
  206420. return 0;
  206421. }
  206422. diff -Nur linux-3.14.14/drivers/usb/chipidea/otg.c linux-imx6-3.14/drivers/usb/chipidea/otg.c
  206423. --- linux-3.14.14/drivers/usb/chipidea/otg.c 2014-07-28 10:07:25.000000000 -0500
  206424. +++ linux-imx6-3.14/drivers/usb/chipidea/otg.c 2014-12-08 00:31:54.712418001 -0600
  206425. @@ -18,6 +18,8 @@
  206426. #include <linux/usb/otg.h>
  206427. #include <linux/usb/gadget.h>
  206428. #include <linux/usb/chipidea.h>
  206429. +#include <linux/kthread.h>
  206430. +#include <linux/freezer.h>
  206431. #include "ci.h"
  206432. #include "bits.h"
  206433. @@ -68,26 +70,53 @@
  206434. ci_role_start(ci, role);
  206435. }
  206436. }
  206437. +
  206438. +/* If there is pending otg event */
  206439. +static inline bool ci_otg_event_is_pending(struct ci_hdrc *ci)
  206440. +{
  206441. + return ci->id_event || ci->b_sess_valid_event;
  206442. +}
  206443. +
  206444. /**
  206445. - * ci_otg_work - perform otg (vbus/id) event handle
  206446. - * @work: work struct
  206447. + * ci_otg_event - perform otg (vbus/id) event handle
  206448. + * @ci: ci_hdrc struct
  206449. */
  206450. -static void ci_otg_work(struct work_struct *work)
  206451. +static void ci_otg_event(struct ci_hdrc *ci)
  206452. {
  206453. - struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
  206454. -
  206455. if (ci->id_event) {
  206456. ci->id_event = false;
  206457. + /* Keep controller active during id switch */
  206458. + pm_runtime_get_sync(ci->dev);
  206459. ci_handle_id_switch(ci);
  206460. + pm_runtime_put_sync(ci->dev);
  206461. } else if (ci->b_sess_valid_event) {
  206462. ci->b_sess_valid_event = false;
  206463. + pm_runtime_get_sync(ci->dev);
  206464. ci_handle_vbus_change(ci);
  206465. + pm_runtime_put_sync(ci->dev);
  206466. } else
  206467. - dev_err(ci->dev, "unexpected event occurs at %s\n", __func__);
  206468. + dev_dbg(ci->dev, "it should be quit event\n");
  206469. enable_irq(ci->irq);
  206470. }
  206471. +static int ci_otg_thread(void *ptr)
  206472. +{
  206473. + struct ci_hdrc *ci = ptr;
  206474. +
  206475. + set_freezable();
  206476. +
  206477. + do {
  206478. + wait_event_freezable(ci->otg_wait,
  206479. + ci_otg_event_is_pending(ci) ||
  206480. + kthread_should_stop());
  206481. + ci_otg_event(ci);
  206482. + } while (!kthread_should_stop());
  206483. +
  206484. + dev_warn(ci->dev, "ci_otg_thread quits\n");
  206485. +
  206486. + return 0;
  206487. +}
  206488. /**
  206489. * ci_hdrc_otg_init - initialize otg struct
  206490. @@ -95,11 +124,11 @@
  206491. */
  206492. int ci_hdrc_otg_init(struct ci_hdrc *ci)
  206493. {
  206494. - INIT_WORK(&ci->work, ci_otg_work);
  206495. - ci->wq = create_singlethread_workqueue("ci_otg");
  206496. - if (!ci->wq) {
  206497. - dev_err(ci->dev, "can't create workqueue\n");
  206498. - return -ENODEV;
  206499. + init_waitqueue_head(&ci->otg_wait);
  206500. + ci->otg_task = kthread_run(ci_otg_thread, ci, "ci otg thread");
  206501. + if (IS_ERR(ci->otg_task)) {
  206502. + dev_err(ci->dev, "error to create otg thread\n");
  206503. + return PTR_ERR(ci->otg_task);
  206504. }
  206505. return 0;
  206506. @@ -111,10 +140,7 @@
  206507. */
  206508. void ci_hdrc_otg_destroy(struct ci_hdrc *ci)
  206509. {
  206510. - if (ci->wq) {
  206511. - flush_workqueue(ci->wq);
  206512. - destroy_workqueue(ci->wq);
  206513. - }
  206514. + kthread_stop(ci->otg_task);
  206515. ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
  206516. ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
  206517. }
  206518. diff -Nur linux-3.14.14/drivers/usb/chipidea/udc.c linux-imx6-3.14/drivers/usb/chipidea/udc.c
  206519. --- linux-3.14.14/drivers/usb/chipidea/udc.c 2014-07-28 10:07:25.000000000 -0500
  206520. +++ linux-imx6-3.14/drivers/usb/chipidea/udc.c 2014-12-08 00:31:54.712418001 -0600
  206521. @@ -681,12 +681,6 @@
  206522. struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
  206523. unsigned long flags;
  206524. - spin_lock_irqsave(&ci->lock, flags);
  206525. - ci->gadget.speed = USB_SPEED_UNKNOWN;
  206526. - ci->remote_wakeup = 0;
  206527. - ci->suspended = 0;
  206528. - spin_unlock_irqrestore(&ci->lock, flags);
  206529. -
  206530. /* flush all endpoints */
  206531. gadget_for_each_ep(ep, gadget) {
  206532. usb_ep_fifo_flush(ep);
  206533. @@ -704,6 +698,12 @@
  206534. ci->status = NULL;
  206535. }
  206536. + spin_lock_irqsave(&ci->lock, flags);
  206537. + ci->gadget.speed = USB_SPEED_UNKNOWN;
  206538. + ci->remote_wakeup = 0;
  206539. + ci->suspended = 0;
  206540. + spin_unlock_irqrestore(&ci->lock, flags);
  206541. +
  206542. return 0;
  206543. }
  206544. @@ -1222,6 +1222,10 @@
  206545. return -EBUSY;
  206546. spin_lock_irqsave(hwep->lock, flags);
  206547. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  206548. + spin_unlock_irqrestore(hwep->lock, flags);
  206549. + return 0;
  206550. + }
  206551. /* only internal SW should disable ctrl endpts */
  206552. @@ -1311,6 +1315,10 @@
  206553. return -EINVAL;
  206554. spin_lock_irqsave(hwep->lock, flags);
  206555. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  206556. + spin_unlock_irqrestore(hwep->lock, flags);
  206557. + return 0;
  206558. + }
  206559. retval = _ep_queue(ep, req, gfp_flags);
  206560. spin_unlock_irqrestore(hwep->lock, flags);
  206561. return retval;
  206562. @@ -1334,8 +1342,8 @@
  206563. return -EINVAL;
  206564. spin_lock_irqsave(hwep->lock, flags);
  206565. -
  206566. - hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
  206567. + if (hwep->ci->gadget.speed != USB_SPEED_UNKNOWN)
  206568. + hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
  206569. list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) {
  206570. dma_pool_free(hwep->td_pool, node->ptr, node->dma);
  206571. @@ -1379,6 +1387,10 @@
  206572. spin_lock_irqsave(hwep->lock, flags);
  206573. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  206574. + spin_unlock_irqrestore(hwep->lock, flags);
  206575. + return 0;
  206576. + }
  206577. #ifndef STALL_IN
  206578. /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
  206579. if (value && hwep->type == USB_ENDPOINT_XFER_BULK && hwep->dir == TX &&
  206580. @@ -1440,6 +1452,10 @@
  206581. }
  206582. spin_lock_irqsave(hwep->lock, flags);
  206583. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  206584. + spin_unlock_irqrestore(hwep->lock, flags);
  206585. + return;
  206586. + }
  206587. hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
  206588. @@ -1506,6 +1522,10 @@
  206589. int ret = 0;
  206590. spin_lock_irqsave(&ci->lock, flags);
  206591. + if (ci->gadget.speed == USB_SPEED_UNKNOWN) {
  206592. + spin_unlock_irqrestore(&ci->lock, flags);
  206593. + return 0;
  206594. + }
  206595. if (!ci->remote_wakeup) {
  206596. ret = -EOPNOTSUPP;
  206597. goto out;
  206598. diff -Nur linux-3.14.14/drivers/usb/chipidea/usbmisc_imx.c linux-imx6-3.14/drivers/usb/chipidea/usbmisc_imx.c
  206599. --- linux-3.14.14/drivers/usb/chipidea/usbmisc_imx.c 2014-07-28 10:07:25.000000000 -0500
  206600. +++ linux-imx6-3.14/drivers/usb/chipidea/usbmisc_imx.c 2014-12-08 00:31:54.712418001 -0600
  206601. @@ -1,5 +1,5 @@
  206602. /*
  206603. - * Copyright 2012 Freescale Semiconductor, Inc.
  206604. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  206605. *
  206606. * The code contained herein is licensed under the GNU General Public
  206607. * License. You may obtain a copy of the GNU General Public License
  206608. @@ -11,10 +11,10 @@
  206609. #include <linux/module.h>
  206610. #include <linux/of_platform.h>
  206611. -#include <linux/clk.h>
  206612. #include <linux/err.h>
  206613. #include <linux/io.h>
  206614. #include <linux/delay.h>
  206615. +#include <linux/regulator/consumer.h>
  206616. #include "ci_hdrc_imx.h"
  206617. @@ -33,22 +33,28 @@
  206618. #define MX53_BM_OVER_CUR_DIS_UHx BIT(30)
  206619. #define MX6_BM_OVER_CUR_DIS BIT(7)
  206620. +#define MX6_BM_WAKEUP_ENABLE BIT(10)
  206621. +#define MX6_BM_ID_WAKEUP BIT(16)
  206622. +#define MX6_BM_VBUS_WAKEUP BIT(17)
  206623. +#define MX6_BM_WAKEUP_INTR BIT(31)
  206624. struct usbmisc_ops {
  206625. /* It's called once when probe a usb device */
  206626. int (*init)(struct imx_usbmisc_data *data);
  206627. /* It's called once after adding a usb device */
  206628. int (*post)(struct imx_usbmisc_data *data);
  206629. + /* It's called when we need to enable usb wakeup */
  206630. + int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled);
  206631. };
  206632. struct imx_usbmisc {
  206633. void __iomem *base;
  206634. spinlock_t lock;
  206635. - struct clk *clk;
  206636. const struct usbmisc_ops *ops;
  206637. };
  206638. static struct imx_usbmisc *usbmisc;
  206639. +static struct regulator *vbus_wakeup_reg;
  206640. static int usbmisc_imx25_post(struct imx_usbmisc_data *data)
  206641. {
  206642. @@ -158,6 +164,47 @@
  206643. return 0;
  206644. }
  206645. +static u32 imx6q_finalize_wakeup_setting(struct imx_usbmisc_data *data)
  206646. +{
  206647. + if (data->available_role == USB_DR_MODE_PERIPHERAL)
  206648. + return MX6_BM_VBUS_WAKEUP;
  206649. + else if (data->available_role == USB_DR_MODE_OTG)
  206650. + return MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP;
  206651. +
  206652. + return 0;
  206653. +}
  206654. +
  206655. +static int usbmisc_imx6q_set_wakeup
  206656. + (struct imx_usbmisc_data *data, bool enabled)
  206657. +{
  206658. + unsigned long flags;
  206659. + u32 reg, val = MX6_BM_WAKEUP_ENABLE;
  206660. + int ret = 0;
  206661. +
  206662. + if (data->index > 3)
  206663. + return -EINVAL;
  206664. +
  206665. + spin_lock_irqsave(&usbmisc->lock, flags);
  206666. + reg = readl(usbmisc->base + data->index * 4);
  206667. + if (enabled) {
  206668. + val |= imx6q_finalize_wakeup_setting(data);
  206669. + writel(reg | val, usbmisc->base + data->index * 4);
  206670. + if (vbus_wakeup_reg)
  206671. + ret = regulator_enable(vbus_wakeup_reg);
  206672. + } else {
  206673. + if (reg & MX6_BM_WAKEUP_INTR)
  206674. + pr_debug("wakeup int at ci_hdrc.%d\n", data->index);
  206675. + val = MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP
  206676. + | MX6_BM_ID_WAKEUP;
  206677. + writel(reg & ~val, usbmisc->base + data->index * 4);
  206678. + if (vbus_wakeup_reg && regulator_is_enabled(vbus_wakeup_reg))
  206679. + regulator_disable(vbus_wakeup_reg);
  206680. + }
  206681. + spin_unlock_irqrestore(&usbmisc->lock, flags);
  206682. +
  206683. + return ret;
  206684. +}
  206685. +
  206686. static const struct usbmisc_ops imx25_usbmisc_ops = {
  206687. .post = usbmisc_imx25_post,
  206688. };
  206689. @@ -172,6 +219,7 @@
  206690. static const struct usbmisc_ops imx6q_usbmisc_ops = {
  206691. .init = usbmisc_imx6q_init,
  206692. + .set_wakeup = usbmisc_imx6q_set_wakeup,
  206693. };
  206694. int imx_usbmisc_init(struct imx_usbmisc_data *data)
  206695. @@ -194,6 +242,16 @@
  206696. }
  206697. EXPORT_SYMBOL_GPL(imx_usbmisc_init_post);
  206698. +int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled)
  206699. +{
  206700. + if (!usbmisc)
  206701. + return -ENODEV;
  206702. + if (!usbmisc->ops->set_wakeup)
  206703. + return 0;
  206704. + return usbmisc->ops->set_wakeup(data, enabled);
  206705. +}
  206706. +EXPORT_SYMBOL_GPL(imx_usbmisc_set_wakeup);
  206707. +
  206708. static const struct of_device_id usbmisc_imx_dt_ids[] = {
  206709. {
  206710. .compatible = "fsl,imx25-usbmisc",
  206711. @@ -223,7 +281,6 @@
  206712. {
  206713. struct resource *res;
  206714. struct imx_usbmisc *data;
  206715. - int ret;
  206716. struct of_device_id *tmp_dev;
  206717. if (usbmisc)
  206718. @@ -240,31 +297,28 @@
  206719. if (IS_ERR(data->base))
  206720. return PTR_ERR(data->base);
  206721. - data->clk = devm_clk_get(&pdev->dev, NULL);
  206722. - if (IS_ERR(data->clk)) {
  206723. - dev_err(&pdev->dev,
  206724. - "failed to get clock, err=%ld\n", PTR_ERR(data->clk));
  206725. - return PTR_ERR(data->clk);
  206726. - }
  206727. -
  206728. - ret = clk_prepare_enable(data->clk);
  206729. - if (ret) {
  206730. - dev_err(&pdev->dev,
  206731. - "clk_prepare_enable failed, err=%d\n", ret);
  206732. - return ret;
  206733. - }
  206734. -
  206735. tmp_dev = (struct of_device_id *)
  206736. of_match_device(usbmisc_imx_dt_ids, &pdev->dev);
  206737. data->ops = (const struct usbmisc_ops *)tmp_dev->data;
  206738. usbmisc = data;
  206739. + vbus_wakeup_reg = devm_regulator_get(&pdev->dev, "vbus-wakeup");
  206740. + if (PTR_ERR(vbus_wakeup_reg) == -EPROBE_DEFER)
  206741. + return -EPROBE_DEFER;
  206742. + else if (PTR_ERR(vbus_wakeup_reg) == -ENODEV)
  206743. + /* no vbus regualator is needed */
  206744. + vbus_wakeup_reg = NULL;
  206745. + else if (IS_ERR(vbus_wakeup_reg)) {
  206746. + dev_err(&pdev->dev, "Getting regulator error: %ld\n",
  206747. + PTR_ERR(vbus_wakeup_reg));
  206748. + return PTR_ERR(vbus_wakeup_reg);
  206749. + }
  206750. +
  206751. return 0;
  206752. }
  206753. static int usbmisc_imx_remove(struct platform_device *pdev)
  206754. {
  206755. - clk_disable_unprepare(usbmisc->clk);
  206756. usbmisc = NULL;
  206757. return 0;
  206758. }
  206759. diff -Nur linux-3.14.14/drivers/usb/core/hub.c linux-imx6-3.14/drivers/usb/core/hub.c
  206760. --- linux-3.14.14/drivers/usb/core/hub.c 2014-07-28 10:07:25.000000000 -0500
  206761. +++ linux-imx6-3.14/drivers/usb/core/hub.c 2014-12-08 00:31:54.720418001 -0600
  206762. @@ -3867,6 +3867,12 @@
  206763. void usb_enable_ltm(struct usb_device *udev) { }
  206764. EXPORT_SYMBOL_GPL(usb_enable_ltm);
  206765. +static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
  206766. + u16 portstatus, u16 portchange)
  206767. +{
  206768. + return 0;
  206769. +}
  206770. +
  206771. #endif /* CONFIG_PM */
  206772. @@ -4460,8 +4466,7 @@
  206773. /* Disconnect any existing devices under this port */
  206774. if (udev) {
  206775. - if (hcd->phy && !hdev->parent &&
  206776. - !(portstatus & USB_PORT_STAT_CONNECTION))
  206777. + if (hcd->phy && !hdev->parent)
  206778. usb_phy_notify_disconnect(hcd->phy, udev->speed);
  206779. usb_disconnect(&hub->ports[port1 - 1]->child);
  206780. }
  206781. diff -Nur linux-3.14.14/drivers/usb/core/message.c linux-imx6-3.14/drivers/usb/core/message.c
  206782. --- linux-3.14.14/drivers/usb/core/message.c 2014-07-28 10:07:25.000000000 -0500
  206783. +++ linux-imx6-3.14/drivers/usb/core/message.c 2014-12-08 00:31:54.720418001 -0600
  206784. @@ -178,7 +178,7 @@
  206785. *
  206786. * Return:
  206787. * If successful, 0. Otherwise a negative error number. The number of actual
  206788. - * bytes transferred will be stored in the @actual_length paramater.
  206789. + * bytes transferred will be stored in the @actual_length parameter.
  206790. */
  206791. int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
  206792. void *data, int len, int *actual_length, int timeout)
  206793. diff -Nur linux-3.14.14/drivers/usb/core/urb.c linux-imx6-3.14/drivers/usb/core/urb.c
  206794. --- linux-3.14.14/drivers/usb/core/urb.c 2014-07-28 10:07:25.000000000 -0500
  206795. +++ linux-imx6-3.14/drivers/usb/core/urb.c 2014-12-08 00:31:54.720418001 -0600
  206796. @@ -831,7 +831,7 @@
  206797. *
  206798. * this allows all outstanding URBs to be unlinked starting
  206799. * from the back of the queue. This function is asynchronous.
  206800. - * The unlinking is just tiggered. It may happen after this
  206801. + * The unlinking is just triggered. It may happen after this
  206802. * function has returned.
  206803. *
  206804. * This routine should not be called by a driver after its disconnect
  206805. diff -Nur linux-3.14.14/drivers/usb/gadget/f_mass_storage.c linux-imx6-3.14/drivers/usb/gadget/f_mass_storage.c
  206806. --- linux-3.14.14/drivers/usb/gadget/f_mass_storage.c 2014-07-28 10:07:25.000000000 -0500
  206807. +++ linux-imx6-3.14/drivers/usb/gadget/f_mass_storage.c 2014-12-08 00:31:54.732418001 -0600
  206808. @@ -336,8 +336,15 @@
  206809. struct usb_ep *bulk_in;
  206810. struct usb_ep *bulk_out;
  206811. +#ifdef CONFIG_FSL_UTP
  206812. + void *utp;
  206813. +#endif
  206814. };
  206815. +#ifdef CONFIG_FSL_UTP
  206816. +#include "fsl_updater.h"
  206817. +#endif
  206818. +
  206819. static inline int __fsg_is_set(struct fsg_common *common,
  206820. const char *func, unsigned line)
  206821. {
  206822. @@ -1131,6 +1138,13 @@
  206823. }
  206824. #endif
  206825. +#ifdef CONFIG_FSL_UTP
  206826. + if (utp_get_sense(common->fsg) == 0) { /* got the sense from the UTP */
  206827. + sd = UTP_CTX(common->fsg)->sd;
  206828. + sdinfo = UTP_CTX(common->fsg)->sdinfo;
  206829. + valid = 0;
  206830. + } else
  206831. +#endif
  206832. if (!curlun) { /* Unsupported LUNs are okay */
  206833. common->bad_lun_okay = 1;
  206834. sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
  206835. @@ -1152,6 +1166,9 @@
  206836. buf[7] = 18 - 8; /* Additional sense length */
  206837. buf[12] = ASC(sd);
  206838. buf[13] = ASCQ(sd);
  206839. +#ifdef CONFIG_FSL_UTP
  206840. + put_unaligned_be32(UTP_CTX(common->fsg)->sdinfo_h, &buf[8]);
  206841. +#endif
  206842. return 18;
  206843. }
  206844. @@ -1645,7 +1662,18 @@
  206845. sd = SS_INVALID_COMMAND;
  206846. } else if (sd != SS_NO_SENSE) {
  206847. DBG(common, "sending command-failure status\n");
  206848. +#ifdef CONFIG_FSL_UTP
  206849. +/*
  206850. + * mfgtool host frequently reset bus during transfer
  206851. + * - the response in csw to request sense will be 1 due to UTP change
  206852. + * some storage information
  206853. + * - host will reset the bus if response to request sense is 1
  206854. + * - change the response to 0 if CONFIG_FSL_UTP is defined
  206855. + */
  206856. + status = US_BULK_STAT_OK;
  206857. +#else
  206858. status = US_BULK_STAT_FAIL;
  206859. +#endif
  206860. VDBG(common, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
  206861. " info x%x\n",
  206862. SK(sd), ASC(sd), ASCQ(sd), sdinfo);
  206863. @@ -1836,6 +1864,13 @@
  206864. common->phase_error = 0;
  206865. common->short_packet_received = 0;
  206866. +#ifdef CONFIG_FSL_UTP
  206867. + reply = utp_handle_message(common->fsg, common->cmnd, reply);
  206868. +
  206869. + if (reply != -EINVAL)
  206870. + return reply;
  206871. +#endif
  206872. +
  206873. down_read(&common->filesem); /* We're using the backing file */
  206874. switch (common->cmnd[0]) {
  206875. @@ -2502,12 +2537,14 @@
  206876. /* Allow the thread to be frozen */
  206877. set_freezable();
  206878. +#ifndef CONFIG_FSL_UTP
  206879. /*
  206880. * Arrange for userspace references to be interpreted as kernel
  206881. * pointers. That way we can pass a kernel pointer to a routine
  206882. * that expects a __user pointer and it will work okay.
  206883. */
  206884. set_fs(get_ds());
  206885. +#endif
  206886. /* The main loop */
  206887. while (common->state != FSG_STATE_TERMINATED) {
  206888. @@ -3096,6 +3133,10 @@
  206889. /*-------------------------------------------------------------------------*/
  206890. +#ifdef CONFIG_FSL_UTP
  206891. +#include "fsl_updater.c"
  206892. +#endif
  206893. +
  206894. static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
  206895. {
  206896. struct fsg_dev *fsg = fsg_from_func(f);
  206897. @@ -3127,6 +3168,10 @@
  206898. fsg_intf_desc.bInterfaceNumber = i;
  206899. fsg->interface_number = i;
  206900. +#ifdef CONFIG_FSL_UTP
  206901. + utp_init(fsg);
  206902. +#endif
  206903. +
  206904. /* Find all the endpoints we will use */
  206905. ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
  206906. if (!ep)
  206907. @@ -3185,6 +3230,10 @@
  206908. }
  206909. usb_free_all_descriptors(&fsg->function);
  206910. +
  206911. +#ifdef CONFIG_FSL_UTP
  206912. + utp_exit(fsg);
  206913. +#endif
  206914. }
  206915. static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
  206916. diff -Nur linux-3.14.14/drivers/usb/gadget/fsl_updater.c linux-imx6-3.14/drivers/usb/gadget/fsl_updater.c
  206917. --- linux-3.14.14/drivers/usb/gadget/fsl_updater.c 1969-12-31 18:00:00.000000000 -0600
  206918. +++ linux-imx6-3.14/drivers/usb/gadget/fsl_updater.c 2014-12-08 00:31:54.736418001 -0600
  206919. @@ -0,0 +1,594 @@
  206920. +/*
  206921. + * Freescale UUT driver
  206922. + *
  206923. + * Copyright 2008-2013 Freescale Semiconductor, Inc.
  206924. + * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
  206925. + */
  206926. +
  206927. +/*
  206928. + * The code contained herein is licensed under the GNU General Public
  206929. + * License. You may obtain a copy of the GNU General Public License
  206930. + * Version 2 or later at the following locations:
  206931. + *
  206932. + * http://www.opensource.org/licenses/gpl-license.html
  206933. + * http://www.gnu.org/copyleft/gpl.html
  206934. + */
  206935. +
  206936. +static u64 get_be64(u8 *buf)
  206937. +{
  206938. + return ((u64)get_unaligned_be32(buf) << 32) |
  206939. + get_unaligned_be32(buf + 4);
  206940. +}
  206941. +
  206942. +static int utp_init(struct fsg_dev *fsg)
  206943. +{
  206944. + init_waitqueue_head(&utp_context.wq);
  206945. + init_waitqueue_head(&utp_context.list_full_wq);
  206946. +
  206947. + INIT_LIST_HEAD(&utp_context.read);
  206948. + INIT_LIST_HEAD(&utp_context.write);
  206949. + mutex_init(&utp_context.lock);
  206950. +
  206951. + /* the max message is 64KB */
  206952. + utp_context.buffer = vmalloc(0x10000);
  206953. + if (!utp_context.buffer)
  206954. + return -EIO;
  206955. + utp_context.utp_version = 0x1ull;
  206956. + fsg->utp = &utp_context;
  206957. + return misc_register(&utp_dev);
  206958. +}
  206959. +
  206960. +static void utp_exit(struct fsg_dev *fsg)
  206961. +{
  206962. + vfree(utp_context.buffer);
  206963. + misc_deregister(&utp_dev);
  206964. +}
  206965. +
  206966. +static struct utp_user_data *utp_user_data_alloc(size_t size)
  206967. +{
  206968. + struct utp_user_data *uud;
  206969. +
  206970. + uud = vmalloc(size + sizeof(*uud));
  206971. + if (!uud)
  206972. + return uud;
  206973. + memset(uud, 0, size + sizeof(*uud));
  206974. + uud->data.size = size + sizeof(uud->data);
  206975. + INIT_LIST_HEAD(&uud->link);
  206976. + return uud;
  206977. +}
  206978. +
  206979. +static void utp_user_data_free(struct utp_user_data *uud)
  206980. +{
  206981. + mutex_lock(&utp_context.lock);
  206982. + list_del(&uud->link);
  206983. + mutex_unlock(&utp_context.lock);
  206984. + vfree(uud);
  206985. +}
  206986. +
  206987. +/* Get the number of element for list */
  206988. +static u32 count_list(struct list_head *l)
  206989. +{
  206990. + u32 count = 0;
  206991. + struct list_head *tmp;
  206992. +
  206993. + mutex_lock(&utp_context.lock);
  206994. + list_for_each(tmp, l) {
  206995. + count++;
  206996. + }
  206997. + mutex_unlock(&utp_context.lock);
  206998. +
  206999. + return count;
  207000. +}
  207001. +/* The routine will not go on if utp_context.queue is empty */
  207002. +#define WAIT_ACTIVITY(queue) \
  207003. + wait_event_interruptible(utp_context.wq, !list_empty(&utp_context.queue))
  207004. +
  207005. +/* Called by userspace program (uuc) */
  207006. +static ssize_t utp_file_read(struct file *file,
  207007. + char __user *buf,
  207008. + size_t size,
  207009. + loff_t *off)
  207010. +{
  207011. + struct utp_user_data *uud;
  207012. + size_t size_to_put;
  207013. + int free = 0;
  207014. +
  207015. + WAIT_ACTIVITY(read);
  207016. +
  207017. + mutex_lock(&utp_context.lock);
  207018. + uud = list_first_entry(&utp_context.read, struct utp_user_data, link);
  207019. + mutex_unlock(&utp_context.lock);
  207020. + size_to_put = uud->data.size;
  207021. +
  207022. + if (size >= size_to_put)
  207023. + free = !0;
  207024. + if (copy_to_user(buf, &uud->data, size_to_put)) {
  207025. + printk(KERN_INFO "[ %s ] copy error\n", __func__);
  207026. + return -EACCES;
  207027. + }
  207028. + if (free)
  207029. + utp_user_data_free(uud);
  207030. + else {
  207031. + pr_info("sizeof = %d, size = %d\n",
  207032. + sizeof(uud->data),
  207033. + uud->data.size);
  207034. +
  207035. + pr_err("Will not free utp_user_data, because buffer size = %d,"
  207036. + "need to put %d\n", size, size_to_put);
  207037. + }
  207038. +
  207039. + /*
  207040. + * The user program has already finished data process,
  207041. + * go on getting data from the host
  207042. + */
  207043. + wake_up(&utp_context.list_full_wq);
  207044. +
  207045. + return size_to_put;
  207046. +}
  207047. +
  207048. +static ssize_t utp_file_write(struct file *file, const char __user *buf,
  207049. + size_t size, loff_t *off)
  207050. +{
  207051. + struct utp_user_data *uud;
  207052. +
  207053. + if (size < sizeof(uud->data))
  207054. + return -EINVAL;
  207055. + uud = utp_user_data_alloc(size);
  207056. + if (uud == NULL)
  207057. + return -ENOMEM;
  207058. + if (copy_from_user(&uud->data, buf, size)) {
  207059. + printk(KERN_INFO "[ %s ] copy error!\n", __func__);
  207060. + vfree(uud);
  207061. + return -EACCES;
  207062. + }
  207063. + mutex_lock(&utp_context.lock);
  207064. + list_add_tail(&uud->link, &utp_context.write);
  207065. + /* Go on EXEC routine process */
  207066. + wake_up(&utp_context.wq);
  207067. + mutex_unlock(&utp_context.lock);
  207068. + return size;
  207069. +}
  207070. +
  207071. +/*
  207072. + * uuc should change to use soc bus infrastructure to soc information
  207073. + * /sys/devices/soc0/soc_id
  207074. + * this function can be removed.
  207075. + */
  207076. +static long
  207077. +utp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  207078. +{
  207079. + int cpu_id = 0;
  207080. +
  207081. + switch (cmd) {
  207082. + case UTP_GET_CPU_ID:
  207083. + return put_user(cpu_id, (int __user *)arg);
  207084. + default:
  207085. + return -ENOIOCTLCMD;
  207086. + }
  207087. +}
  207088. +
  207089. +/* Will be called when the host wants to get the sense data */
  207090. +static int utp_get_sense(struct fsg_dev *fsg)
  207091. +{
  207092. + if (UTP_CTX(fsg)->processed == 0)
  207093. + return -1;
  207094. +
  207095. + UTP_CTX(fsg)->processed = 0;
  207096. + return 0;
  207097. +}
  207098. +
  207099. +static int utp_do_read(struct fsg_dev *fsg, void *data, size_t size)
  207100. +{
  207101. + struct fsg_buffhd *bh;
  207102. + int rc;
  207103. + u32 amount_left;
  207104. + unsigned int amount;
  207105. +
  207106. + /* Get the starting Logical Block Address and check that it's
  207107. + * not too big */
  207108. +
  207109. + amount_left = size;
  207110. + if (unlikely(amount_left == 0))
  207111. + return -EIO; /* No default reply*/
  207112. +
  207113. + pr_debug("%s: sending %d\n", __func__, size);
  207114. + for (;;) {
  207115. + /* Figure out how much we need to read:
  207116. + * Try to read the remaining amount.
  207117. + * But don't read more than the buffer size.
  207118. + * And don't try to read past the end of the file.
  207119. + * Finally, if we're not at a page boundary, don't read past
  207120. + * the next page.
  207121. + * If this means reading 0 then we were asked to read past
  207122. + * the end of file. */
  207123. + amount = min((unsigned int) amount_left, FSG_BUFLEN);
  207124. +
  207125. + /* Wait for the next buffer to become available */
  207126. + bh = fsg->common->next_buffhd_to_fill;
  207127. + while (bh->state != BUF_STATE_EMPTY) {
  207128. + rc = sleep_thread(fsg->common);
  207129. + if (rc)
  207130. + return rc;
  207131. + }
  207132. +
  207133. + /* If we were asked to read past the end of file,
  207134. + * end with an empty buffer. */
  207135. + if (amount == 0) {
  207136. + bh->inreq->length = 0;
  207137. + bh->state = BUF_STATE_FULL;
  207138. + break;
  207139. + }
  207140. +
  207141. + /* Perform the read */
  207142. + pr_info("Copied to %p, %d bytes started from %d\n",
  207143. + bh->buf, amount, size - amount_left);
  207144. + /* from upt buffer to file_storeage buffer */
  207145. + memcpy(bh->buf, data + size - amount_left, amount);
  207146. + amount_left -= amount;
  207147. + fsg->common->residue -= amount;
  207148. +
  207149. + bh->inreq->length = amount;
  207150. + bh->state = BUF_STATE_FULL;
  207151. +
  207152. + /* Send this buffer and go read some more */
  207153. + bh->inreq->zero = 0;
  207154. +
  207155. + /* USB Physical transfer: Data from device to host */
  207156. + start_transfer(fsg, fsg->bulk_in, bh->inreq,
  207157. + &bh->inreq_busy, &bh->state);
  207158. +
  207159. + fsg->common->next_buffhd_to_fill = bh->next;
  207160. +
  207161. + if (amount_left <= 0)
  207162. + break;
  207163. + }
  207164. +
  207165. + return size - amount_left;
  207166. +}
  207167. +
  207168. +static int utp_do_write(struct fsg_dev *fsg, void *data, size_t size)
  207169. +{
  207170. + struct fsg_buffhd *bh;
  207171. + int get_some_more;
  207172. + u32 amount_left_to_req, amount_left_to_write;
  207173. + unsigned int amount;
  207174. + int rc;
  207175. + loff_t offset;
  207176. +
  207177. + /* Carry out the file writes */
  207178. + get_some_more = 1;
  207179. + amount_left_to_req = amount_left_to_write = size;
  207180. +
  207181. + if (unlikely(amount_left_to_write == 0))
  207182. + return -EIO;
  207183. +
  207184. + offset = 0;
  207185. + while (amount_left_to_write > 0) {
  207186. +
  207187. + /* Queue a request for more data from the host */
  207188. + bh = fsg->common->next_buffhd_to_fill;
  207189. + if (bh->state == BUF_STATE_EMPTY && get_some_more) {
  207190. +
  207191. + /* Figure out how much we want to get:
  207192. + * Try to get the remaining amount.
  207193. + * But don't get more than the buffer size.
  207194. + * And don't try to go past the end of the file.
  207195. + * If we're not at a page boundary,
  207196. + * don't go past the next page.
  207197. + * If this means getting 0, then we were asked
  207198. + * to write past the end of file.
  207199. + * Finally, round down to a block boundary. */
  207200. + amount = min(amount_left_to_req, FSG_BUFLEN);
  207201. +
  207202. + if (amount == 0) {
  207203. + get_some_more = 0;
  207204. + /* cry now */
  207205. + continue;
  207206. + }
  207207. +
  207208. + /* Get the next buffer */
  207209. + amount_left_to_req -= amount;
  207210. + if (amount_left_to_req == 0)
  207211. + get_some_more = 0;
  207212. +
  207213. + /* amount is always divisible by 512, hence by
  207214. + * the bulk-out maxpacket size */
  207215. + bh->outreq->length = bh->bulk_out_intended_length =
  207216. + amount;
  207217. + bh->outreq->short_not_ok = 1;
  207218. + start_transfer(fsg, fsg->bulk_out, bh->outreq,
  207219. + &bh->outreq_busy, &bh->state);
  207220. + fsg->common->next_buffhd_to_fill = bh->next;
  207221. + continue;
  207222. + }
  207223. +
  207224. + /* Write the received data to the backing file */
  207225. + bh = fsg->common->next_buffhd_to_drain;
  207226. + if (bh->state == BUF_STATE_EMPTY && !get_some_more)
  207227. + break; /* We stopped early */
  207228. + if (bh->state == BUF_STATE_FULL) {
  207229. + smp_rmb();
  207230. + fsg->common->next_buffhd_to_drain = bh->next;
  207231. + bh->state = BUF_STATE_EMPTY;
  207232. +
  207233. + /* Did something go wrong with the transfer? */
  207234. + if (bh->outreq->status != 0)
  207235. + /* cry again, COMMUNICATION_FAILURE */
  207236. + break;
  207237. +
  207238. + amount = bh->outreq->actual;
  207239. +
  207240. + /* Perform the write */
  207241. + memcpy(data + offset, bh->buf, amount);
  207242. +
  207243. + offset += amount;
  207244. + if (signal_pending(current))
  207245. + return -EINTR; /* Interrupted!*/
  207246. + amount_left_to_write -= amount;
  207247. + fsg->common->residue -= amount;
  207248. +
  207249. + /* Did the host decide to stop early? */
  207250. + if (bh->outreq->actual != bh->outreq->length) {
  207251. + fsg->common->short_packet_received = 1;
  207252. + break;
  207253. + }
  207254. + continue;
  207255. + }
  207256. +
  207257. + /* Wait for something to happen */
  207258. + rc = sleep_thread(fsg->common);
  207259. + if (rc)
  207260. + return rc;
  207261. + }
  207262. +
  207263. + return -EIO;
  207264. +}
  207265. +
  207266. +static inline void utp_set_sense(struct fsg_dev *fsg, u16 code, u64 reply)
  207267. +{
  207268. + UTP_CTX(fsg)->processed = true;
  207269. + UTP_CTX(fsg)->sdinfo = reply & 0xFFFFFFFF;
  207270. + UTP_CTX(fsg)->sdinfo_h = (reply >> 32) & 0xFFFFFFFF;
  207271. + UTP_CTX(fsg)->sd = (UTP_SENSE_KEY << 16) | code;
  207272. +}
  207273. +
  207274. +static void utp_poll(struct fsg_dev *fsg)
  207275. +{
  207276. + struct utp_context *ctx = UTP_CTX(fsg);
  207277. + struct utp_user_data *uud = NULL;
  207278. +
  207279. + mutex_lock(&ctx->lock);
  207280. + if (!list_empty(&ctx->write))
  207281. + uud = list_first_entry(&ctx->write, struct utp_user_data, link);
  207282. + mutex_unlock(&ctx->lock);
  207283. +
  207284. + if (uud) {
  207285. + if (uud->data.flags & UTP_FLAG_STATUS) {
  207286. + printk(KERN_WARNING "%s: exit with status %d\n",
  207287. + __func__, uud->data.status);
  207288. + UTP_SS_EXIT(fsg, uud->data.status);
  207289. + } else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
  207290. + UTP_SS_BUSY(fsg, --ctx->counter);
  207291. + } else {
  207292. + printk("%s: pass returned.\n", __func__);
  207293. + UTP_SS_PASS(fsg);
  207294. + }
  207295. + utp_user_data_free(uud);
  207296. + } else {
  207297. + if (utp_context.cur_state & UTP_FLAG_DATA) {
  207298. + if (count_list(&ctx->read) < 7) {
  207299. + pr_debug("%s: pass returned in POLL stage. \n", __func__);
  207300. + UTP_SS_PASS(fsg);
  207301. + utp_context.cur_state = 0;
  207302. + return;
  207303. + }
  207304. + }
  207305. + UTP_SS_BUSY(fsg, --ctx->counter);
  207306. + }
  207307. +}
  207308. +
  207309. +static int utp_exec(struct fsg_dev *fsg,
  207310. + char *command,
  207311. + int cmdsize,
  207312. + unsigned long long payload)
  207313. +{
  207314. + struct utp_user_data *uud = NULL, *uud2r;
  207315. + struct utp_context *ctx = UTP_CTX(fsg);
  207316. +
  207317. + ctx->counter = 0xFFFF;
  207318. + uud2r = utp_user_data_alloc(cmdsize + 1);
  207319. + if (!uud2r)
  207320. + return -ENOMEM;
  207321. + uud2r->data.flags = UTP_FLAG_COMMAND;
  207322. + uud2r->data.payload = payload;
  207323. + strncpy(uud2r->data.command, command, cmdsize);
  207324. +
  207325. + mutex_lock(&ctx->lock);
  207326. + list_add_tail(&uud2r->link, &ctx->read);
  207327. + mutex_unlock(&ctx->lock);
  207328. + /* wake up the read routine */
  207329. + wake_up(&ctx->wq);
  207330. +
  207331. + if (command[0] == '!') /* there will be no response */
  207332. + return 0;
  207333. +
  207334. + /*
  207335. + * the user program (uuc) will return utp_message
  207336. + * and add list to write list
  207337. + */
  207338. + WAIT_ACTIVITY(write);
  207339. +
  207340. + mutex_lock(&ctx->lock);
  207341. + if (!list_empty(&ctx->write)) {
  207342. + uud = list_first_entry(&ctx->write, struct utp_user_data, link);
  207343. +#ifdef DEBUG
  207344. + pr_info("UUD:\n\tFlags = %02X\n", uud->data.flags);
  207345. + if (uud->data.flags & UTP_FLAG_DATA) {
  207346. + pr_info("\tbufsize = %d\n", uud->data.bufsize);
  207347. + print_hex_dump(KERN_DEBUG, "\t", DUMP_PREFIX_NONE,
  207348. + 16, 2, uud->data.data, uud->data.bufsize, true);
  207349. + }
  207350. + if (uud->data.flags & UTP_FLAG_REPORT_BUSY)
  207351. + pr_info("\tBUSY\n");
  207352. +#endif
  207353. + }
  207354. + mutex_unlock(&ctx->lock);
  207355. +
  207356. + if (uud->data.flags & UTP_FLAG_DATA) {
  207357. + memcpy(ctx->buffer, uud->data.data, uud->data.bufsize);
  207358. + UTP_SS_SIZE(fsg, uud->data.bufsize);
  207359. + } else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
  207360. + UTP_SS_BUSY(fsg, ctx->counter);
  207361. + } else if (uud->data.flags & UTP_FLAG_STATUS) {
  207362. + printk(KERN_WARNING "%s: exit with status %d\n", __func__,
  207363. + uud->data.status);
  207364. + UTP_SS_EXIT(fsg, uud->data.status);
  207365. + } else {
  207366. + pr_debug("%s: pass returned in EXEC stage. \n", __func__);
  207367. + UTP_SS_PASS(fsg);
  207368. + }
  207369. + utp_user_data_free(uud);
  207370. + return 0;
  207371. +}
  207372. +
  207373. +static int utp_send_status(struct fsg_dev *fsg)
  207374. +{
  207375. + struct fsg_buffhd *bh;
  207376. + u8 status = US_BULK_STAT_OK;
  207377. + struct bulk_cs_wrap *csw;
  207378. + int rc;
  207379. +
  207380. + /* Wait for the next buffer to become available */
  207381. + bh = fsg->common->next_buffhd_to_fill;
  207382. + while (bh->state != BUF_STATE_EMPTY) {
  207383. + rc = sleep_thread(fsg->common);
  207384. + if (rc)
  207385. + return rc;
  207386. + }
  207387. +
  207388. + if (fsg->common->phase_error) {
  207389. + DBG(fsg, "sending phase-error status\n");
  207390. + status = US_BULK_STAT_PHASE;
  207391. +
  207392. + } else if ((UTP_CTX(fsg)->sd & 0xFFFF) != UTP_REPLY_PASS) {
  207393. + status = US_BULK_STAT_FAIL;
  207394. + }
  207395. +
  207396. + csw = bh->buf;
  207397. +
  207398. + /* Store and send the Bulk-only CSW */
  207399. + csw->Signature = __constant_cpu_to_le32(US_BULK_CS_SIGN);
  207400. + csw->Tag = fsg->common->tag;
  207401. + csw->Residue = cpu_to_le32(fsg->common->residue);
  207402. + csw->Status = status;
  207403. +
  207404. + bh->inreq->length = US_BULK_CS_WRAP_LEN;
  207405. + bh->inreq->zero = 0;
  207406. + start_transfer(fsg, fsg->bulk_in, bh->inreq,
  207407. + &bh->inreq_busy, &bh->state);
  207408. + fsg->common->next_buffhd_to_fill = bh->next;
  207409. + return 0;
  207410. +}
  207411. +
  207412. +static int utp_handle_message(struct fsg_dev *fsg,
  207413. + char *cdb_data,
  207414. + int default_reply)
  207415. +{
  207416. + struct utp_msg *m = (struct utp_msg *)cdb_data;
  207417. + void *data = NULL;
  207418. + int r;
  207419. + struct utp_user_data *uud2r;
  207420. + unsigned long long param;
  207421. + unsigned long tag;
  207422. +
  207423. + if (m->f0 != 0xF0)
  207424. + return default_reply;
  207425. +
  207426. + tag = get_unaligned_be32((void *)&m->utp_msg_tag);
  207427. + param = get_be64((void *)&m->param);
  207428. + pr_debug("Type 0x%x, tag 0x%08lx, param %llx\n",
  207429. + m->utp_msg_type, tag, param);
  207430. +
  207431. + switch ((enum utp_msg_type)m->utp_msg_type) {
  207432. +
  207433. + case UTP_POLL:
  207434. + if (get_be64((void *)&m->param) == 1) {
  207435. + pr_debug("%s: version request\n", __func__);
  207436. + UTP_SS_EXIT(fsg, UTP_CTX(fsg)->utp_version);
  207437. + break;
  207438. + }
  207439. + utp_poll(fsg);
  207440. + break;
  207441. + case UTP_EXEC:
  207442. + pr_debug("%s: EXEC\n", __func__);
  207443. + data = vmalloc(fsg->common->data_size);
  207444. + memset(data, 0, fsg->common->data_size);
  207445. + /* copy data from usb buffer to utp buffer */
  207446. + utp_do_write(fsg, data, fsg->common->data_size);
  207447. + utp_exec(fsg, data, fsg->common->data_size, param);
  207448. + vfree(data);
  207449. + break;
  207450. + case UTP_GET: /* data from device to host */
  207451. + pr_debug("%s: GET, %d bytes\n", __func__,
  207452. + fsg->common->data_size);
  207453. + r = utp_do_read(fsg, UTP_CTX(fsg)->buffer,
  207454. + fsg->common->data_size);
  207455. + UTP_SS_PASS(fsg);
  207456. + break;
  207457. + case UTP_PUT:
  207458. + utp_context.cur_state = UTP_FLAG_DATA;
  207459. + pr_debug("%s: PUT, Received %d bytes\n", __func__, fsg->common->data_size);/* data from host to device */
  207460. + uud2r = utp_user_data_alloc(fsg->common->data_size);
  207461. + if (!uud2r)
  207462. + return -ENOMEM;
  207463. + uud2r->data.bufsize = fsg->common->data_size;
  207464. + uud2r->data.flags = UTP_FLAG_DATA;
  207465. + utp_do_write(fsg, uud2r->data.data, fsg->common->data_size);
  207466. + /* don't know what will be written */
  207467. + mutex_lock(&UTP_CTX(fsg)->lock);
  207468. + list_add_tail(&uud2r->link, &UTP_CTX(fsg)->read);
  207469. + mutex_unlock(&UTP_CTX(fsg)->lock);
  207470. + wake_up(&UTP_CTX(fsg)->wq);
  207471. + /*
  207472. + * Return PASS or FAIL according to uuc's status
  207473. + * Please open it if need to check uuc's status
  207474. + * and use another version uuc
  207475. + */
  207476. +#if 0
  207477. + struct utp_user_data *uud = NULL;
  207478. + struct utp_context *ctx;
  207479. + WAIT_ACTIVITY(write);
  207480. + ctx = UTP_CTX(fsg);
  207481. + mutex_lock(&ctx->lock);
  207482. +
  207483. + if (!list_empty(&ctx->write))
  207484. + uud = list_first_entry(&ctx->write,
  207485. + struct utp_user_data, link);
  207486. +
  207487. + mutex_unlock(&ctx->lock);
  207488. + if (uud) {
  207489. + if (uud->data.flags & UTP_FLAG_STATUS) {
  207490. + printk(KERN_WARNING "%s: exit with status %d\n",
  207491. + __func__, uud->data.status);
  207492. + UTP_SS_EXIT(fsg, uud->data.status);
  207493. + } else {
  207494. + pr_debug("%s: pass\n", __func__);
  207495. + UTP_SS_PASS(fsg);
  207496. + }
  207497. + utp_user_data_free(uud);
  207498. + } else{
  207499. + UTP_SS_PASS(fsg);
  207500. + }
  207501. +#endif
  207502. + if (count_list(&UTP_CTX(fsg)->read) < 7) {
  207503. + utp_context.cur_state = 0;
  207504. + UTP_SS_PASS(fsg);
  207505. + } else
  207506. + UTP_SS_BUSY(fsg, UTP_CTX(fsg)->counter);
  207507. +
  207508. + break;
  207509. + }
  207510. +
  207511. + utp_send_status(fsg);
  207512. + return -1;
  207513. +}
  207514. diff -Nur linux-3.14.14/drivers/usb/gadget/fsl_updater.h linux-imx6-3.14/drivers/usb/gadget/fsl_updater.h
  207515. --- linux-3.14.14/drivers/usb/gadget/fsl_updater.h 1969-12-31 18:00:00.000000000 -0600
  207516. +++ linux-imx6-3.14/drivers/usb/gadget/fsl_updater.h 2014-12-08 00:31:54.736418001 -0600
  207517. @@ -0,0 +1,150 @@
  207518. +/*
  207519. + * Freescale UUT driver
  207520. + *
  207521. + * Copyright 2008-2013 Freescale Semiconductor, Inc.
  207522. + * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
  207523. + */
  207524. +
  207525. +/*
  207526. + * The code contained herein is licensed under the GNU General Public
  207527. + * License. You may obtain a copy of the GNU General Public License
  207528. + * Version 2 or later at the following locations:
  207529. + *
  207530. + * http://www.opensource.org/licenses/gpl-license.html
  207531. + * http://www.gnu.org/copyleft/gpl.html
  207532. + */
  207533. +
  207534. +#ifndef __FSL_UPDATER_H
  207535. +#define __FSL_UPDATER_H
  207536. +
  207537. +#include <linux/miscdevice.h>
  207538. +#include <linux/list.h>
  207539. +#include <linux/vmalloc.h>
  207540. +#include <linux/ioctl.h>
  207541. +/* #include <mach/hardware.h> */
  207542. +
  207543. +static int utp_init(struct fsg_dev *fsg);
  207544. +static void utp_exit(struct fsg_dev *fsg);
  207545. +static ssize_t utp_file_read(struct file *file,
  207546. + char __user *buf,
  207547. + size_t size,
  207548. + loff_t *off);
  207549. +
  207550. +static ssize_t utp_file_write(struct file *file,
  207551. + const char __user *buf,
  207552. + size_t size,
  207553. + loff_t *off);
  207554. +
  207555. +static long utp_ioctl(struct file *file,
  207556. + unsigned int cmd, unsigned long arg);
  207557. +static struct utp_user_data *utp_user_data_alloc(size_t size);
  207558. +static void utp_user_data_free(struct utp_user_data *uud);
  207559. +static int utp_get_sense(struct fsg_dev *fsg);
  207560. +static int utp_do_read(struct fsg_dev *fsg, void *data, size_t size);
  207561. +static int utp_do_write(struct fsg_dev *fsg, void *data, size_t size);
  207562. +static inline void utp_set_sense(struct fsg_dev *fsg, u16 code, u64 reply);
  207563. +static int utp_handle_message(struct fsg_dev *fsg,
  207564. + char *cdb_data,
  207565. + int default_reply);
  207566. +
  207567. +#define UTP_REPLY_PASS 0
  207568. +#define UTP_REPLY_EXIT 0x8001
  207569. +#define UTP_REPLY_BUSY 0x8002
  207570. +#define UTP_REPLY_SIZE 0x8003
  207571. +#define UTP_SENSE_KEY 9
  207572. +
  207573. +#define UTP_MINOR 222
  207574. +/* MISC_DYNAMIC_MINOR would be better, but... */
  207575. +
  207576. +#define UTP_COMMAND_SIZE 80
  207577. +
  207578. +#define UTP_SS_EXIT(fsg, r) utp_set_sense(fsg, UTP_REPLY_EXIT, (u64)r)
  207579. +#define UTP_SS_PASS(fsg) utp_set_sense(fsg, UTP_REPLY_PASS, 0)
  207580. +#define UTP_SS_BUSY(fsg, r) utp_set_sense(fsg, UTP_REPLY_BUSY, (u64)r)
  207581. +#define UTP_SS_SIZE(fsg, r) utp_set_sense(fsg, UTP_REPLY_SIZE, (u64)r)
  207582. +
  207583. +#define UTP_IOCTL_BASE 'U'
  207584. +#define UTP_GET_CPU_ID _IOR(UTP_IOCTL_BASE, 0, int)
  207585. +/* the structure of utp message which is mapped to 16-byte SCSI CBW's CDB */
  207586. +#pragma pack(1)
  207587. +struct utp_msg {
  207588. + u8 f0;
  207589. + u8 utp_msg_type;
  207590. + u32 utp_msg_tag;
  207591. + union {
  207592. + struct {
  207593. + u32 param_lsb;
  207594. + u32 param_msb;
  207595. + };
  207596. + u64 param;
  207597. + };
  207598. +};
  207599. +
  207600. +enum utp_msg_type {
  207601. + UTP_POLL = 0,
  207602. + UTP_EXEC,
  207603. + UTP_GET,
  207604. + UTP_PUT,
  207605. +};
  207606. +
  207607. +static struct utp_context {
  207608. + wait_queue_head_t wq;
  207609. + wait_queue_head_t list_full_wq;
  207610. + struct mutex lock;
  207611. + struct list_head read;
  207612. + struct list_head write;
  207613. + u32 sd, sdinfo, sdinfo_h; /* sense data */
  207614. + int processed;
  207615. + u8 *buffer;
  207616. + u32 counter;
  207617. + u64 utp_version;
  207618. + u32 cur_state;
  207619. +} utp_context;
  207620. +
  207621. +static const struct file_operations utp_fops = {
  207622. + .open = nonseekable_open,
  207623. + .read = utp_file_read,
  207624. + .write = utp_file_write,
  207625. + /* .ioctl = utp_ioctl, */
  207626. + .unlocked_ioctl = utp_ioctl,
  207627. +};
  207628. +
  207629. +static struct miscdevice utp_dev = {
  207630. + .minor = UTP_MINOR,
  207631. + .name = "utp",
  207632. + .fops = &utp_fops,
  207633. +};
  207634. +
  207635. +#define UTP_FLAG_COMMAND 0x00000001
  207636. +#define UTP_FLAG_DATA 0x00000002
  207637. +#define UTP_FLAG_STATUS 0x00000004
  207638. +#define UTP_FLAG_REPORT_BUSY 0x10000000
  207639. +struct utp_message {
  207640. + u32 flags;
  207641. + size_t size;
  207642. + union {
  207643. + struct {
  207644. + u64 payload;
  207645. + char command[1];
  207646. + };
  207647. + struct {
  207648. + size_t bufsize;
  207649. + u8 data[1];
  207650. + };
  207651. + u32 status;
  207652. + };
  207653. +};
  207654. +
  207655. +struct utp_user_data {
  207656. + struct list_head link;
  207657. + struct utp_message data;
  207658. +};
  207659. +#pragma pack()
  207660. +
  207661. +static inline struct utp_context *UTP_CTX(struct fsg_dev *fsg)
  207662. +{
  207663. + return (struct utp_context *)fsg->utp;
  207664. +}
  207665. +
  207666. +#endif /* __FSL_UPDATER_H */
  207667. +
  207668. diff -Nur linux-3.14.14/drivers/usb/gadget/Kconfig linux-imx6-3.14/drivers/usb/gadget/Kconfig
  207669. --- linux-3.14.14/drivers/usb/gadget/Kconfig 2014-07-28 10:07:25.000000000 -0500
  207670. +++ linux-imx6-3.14/drivers/usb/gadget/Kconfig 2014-12-08 00:31:54.724418001 -0600
  207671. @@ -952,6 +952,12 @@
  207672. Say "y" to link the driver statically, or "m" to build
  207673. a dynamically linked module called "g_mass_storage".
  207674. +config FSL_UTP
  207675. + bool "UTP over Storage Gadget"
  207676. + depends on USB_MASS_STORAGE
  207677. + help
  207678. + Freescale's extension to MSC protocol
  207679. +
  207680. config USB_GADGET_TARGET
  207681. tristate "USB Gadget Target Fabric Module"
  207682. depends on TARGET_CORE
  207683. diff -Nur linux-3.14.14/drivers/usb/gadget/mass_storage.c linux-imx6-3.14/drivers/usb/gadget/mass_storage.c
  207684. --- linux-3.14.14/drivers/usb/gadget/mass_storage.c 2014-07-28 10:07:25.000000000 -0500
  207685. +++ linux-imx6-3.14/drivers/usb/gadget/mass_storage.c 2014-12-08 00:31:54.740418001 -0600
  207686. @@ -266,7 +266,7 @@
  207687. {
  207688. return usb_composite_probe(&msg_driver);
  207689. }
  207690. -module_init(msg_init);
  207691. +late_initcall(msg_init);
  207692. static void msg_cleanup(void)
  207693. {
  207694. diff -Nur linux-3.14.14/drivers/usb/host/ehci-h20ahb.c linux-imx6-3.14/drivers/usb/host/ehci-h20ahb.c
  207695. --- linux-3.14.14/drivers/usb/host/ehci-h20ahb.c 1969-12-31 18:00:00.000000000 -0600
  207696. +++ linux-imx6-3.14/drivers/usb/host/ehci-h20ahb.c 2014-12-08 00:31:54.748418001 -0600
  207697. @@ -0,0 +1,341 @@
  207698. +/*
  207699. + * Copyright (C) 2007-2013 Texas Instruments, Inc.
  207700. + * Author: Vikram Pandita <vikram.pandita@ti.com>
  207701. + * Author: Anand Gadiyar <gadiyar@ti.com>
  207702. + * Author: Keshava Munegowda <keshava_mgowda@ti.com>
  207703. + * Author: Roger Quadros <rogerq@ti.com>
  207704. + *
  207705. + * Copyright (C) 2009 Nokia Corporation
  207706. + * Contact: Felipe Balbi <felipe.balbi@nokia.com>
  207707. + *
  207708. + * Based on ehci-omap.c - driver for USBHOST on OMAP3/4 processors
  207709. + *
  207710. + * This file is subject to the terms and conditions of the GNU General Public
  207711. + * License. See the file COPYING in the main directory of this archive
  207712. + * for more details.
  207713. + *
  207714. + */
  207715. +
  207716. +#include <linux/kernel.h>
  207717. +#include <linux/module.h>
  207718. +#include <linux/io.h>
  207719. +#include <linux/platform_device.h>
  207720. +#include <linux/slab.h>
  207721. +#include <linux/usb/ulpi.h>
  207722. +#include <linux/pm_runtime.h>
  207723. +#include <linux/gpio.h>
  207724. +#include <linux/clk.h>
  207725. +#include <linux/usb.h>
  207726. +#include <linux/usb/hcd.h>
  207727. +#include <linux/of.h>
  207728. +#include <linux/dma-mapping.h>
  207729. +
  207730. +#include "ehci.h"
  207731. +
  207732. +#define H20AHB_HS_USB_PORTS 1
  207733. +
  207734. +/* EHCI Synopsys-specific Register Set */
  207735. +#define EHCI_INSNREG04 (0xA0)
  207736. +#define EHCI_INSNREG04_DISABLE_UNSUSPEND (1 << 5)
  207737. +#define EHCI_INSNREG05_ULPI (0xA4)
  207738. +#define EHCI_INSNREG05_ULPI_CONTROL_SHIFT 31
  207739. +#define EHCI_INSNREG05_ULPI_PORTSEL_SHIFT 24
  207740. +#define EHCI_INSNREG05_ULPI_OPSEL_SHIFT 22
  207741. +#define EHCI_INSNREG05_ULPI_REGADD_SHIFT 16
  207742. +#define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8
  207743. +#define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0
  207744. +
  207745. +#define DRIVER_DESC "H20AHB-EHCI Host Controller driver"
  207746. +
  207747. +static const char hcd_name[] = "ehci-h20ahb";
  207748. +
  207749. +/*-------------------------------------------------------------------------*/
  207750. +
  207751. +struct h20ahb_hcd {
  207752. + struct usb_phy *phy[H20AHB_HS_USB_PORTS]; /* one PHY for each port */
  207753. + int nports;
  207754. +};
  207755. +
  207756. +static inline void ehci_write(void __iomem *base, u32 reg, u32 val)
  207757. +{
  207758. + __raw_writel(val, base + reg);
  207759. +}
  207760. +
  207761. +static inline u32 ehci_read(void __iomem *base, u32 reg)
  207762. +{
  207763. + return __raw_readl(base + reg);
  207764. +}
  207765. +
  207766. +/* configure so an HC device and id are always provided */
  207767. +/* always called with process context; sleeping is OK */
  207768. +
  207769. +static struct hc_driver __read_mostly ehci_h20ahb_hc_driver;
  207770. +
  207771. +static const struct ehci_driver_overrides ehci_h20ahb_overrides __initdata = {
  207772. + .extra_priv_size = sizeof(struct h20ahb_hcd),
  207773. +};
  207774. +
  207775. +static int ehci_h20ahb_phy_read(struct usb_phy *x, u32 reg)
  207776. +{
  207777. + u32 val = (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |
  207778. + (1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |
  207779. + (3 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |
  207780. + (reg << EHCI_INSNREG05_ULPI_REGADD_SHIFT);
  207781. + ehci_write(x->io_priv, 0, val);
  207782. + while ((val = ehci_read(x->io_priv, 0)) &
  207783. + (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT));
  207784. + return val & 0xff;
  207785. +}
  207786. +
  207787. +static int ehci_h20ahb_phy_write(struct usb_phy *x, u32 val, u32 reg)
  207788. +{
  207789. + u32 v = (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |
  207790. + (1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |
  207791. + (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |
  207792. + (reg << EHCI_INSNREG05_ULPI_REGADD_SHIFT) |
  207793. + (val & 0xff);
  207794. + ehci_write(x->io_priv, 0, v);
  207795. + while ((v = ehci_read(x->io_priv, 0)) &
  207796. + (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT));
  207797. + return 0;
  207798. +}
  207799. +
  207800. +static struct usb_phy_io_ops ehci_h20ahb_phy_io_ops = {
  207801. + .read = ehci_h20ahb_phy_read,
  207802. + .write = ehci_h20ahb_phy_write,
  207803. +};
  207804. +
  207805. +
  207806. +/**
  207807. + * ehci_hcd_h20ahb_probe - initialize Synopsis-based HCDs
  207808. + *
  207809. + * Allocates basic resources for this USB host controller, and
  207810. + * then invokes the start() method for the HCD associated with it
  207811. + * through the hotplug entry's driver_data.
  207812. + */
  207813. +static int ehci_hcd_h20ahb_probe(struct platform_device *pdev)
  207814. +{
  207815. + struct device *dev = &pdev->dev;
  207816. + struct resource *res;
  207817. + struct usb_hcd *hcd;
  207818. + void __iomem *regs;
  207819. + int ret;
  207820. + int irq;
  207821. + int i;
  207822. + struct h20ahb_hcd *h20ahb;
  207823. +
  207824. + if (usb_disabled())
  207825. + return -ENODEV;
  207826. +
  207827. + /* if (!dev->parent) {
  207828. + dev_err(dev, "Missing parent device\n");
  207829. + return -ENODEV;
  207830. + }*/
  207831. +
  207832. + /* For DT boot, get platform data from parent. i.e. usbhshost */
  207833. + /*if (dev->of_node) {
  207834. + pdata = dev_get_platdata(dev->parent);
  207835. + dev->platform_data = pdata;
  207836. + }
  207837. +
  207838. + if (!pdata) {
  207839. + dev_err(dev, "Missing platform data\n");
  207840. + return -ENODEV;
  207841. + }*/
  207842. +
  207843. + irq = platform_get_irq(pdev, 0);
  207844. + if (irq < 0) {
  207845. + dev_err(dev, "EHCI irq failed\n");
  207846. + return -ENODEV;
  207847. + }
  207848. +
  207849. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  207850. + regs = devm_ioremap_resource(dev, res);
  207851. + if (IS_ERR(regs))
  207852. + return PTR_ERR(regs);
  207853. +
  207854. + /*
  207855. + * Right now device-tree probed devices don't get dma_mask set.
  207856. + * Since shared usb code relies on it, set it here for now.
  207857. + * Once we have dma capability bindings this can go away.
  207858. + */
  207859. + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
  207860. + if (ret)
  207861. + return ret;
  207862. +
  207863. + ret = -ENODEV;
  207864. + hcd = usb_create_hcd(&ehci_h20ahb_hc_driver, dev,
  207865. + dev_name(dev));
  207866. + if (!hcd) {
  207867. + dev_err(dev, "Failed to create HCD\n");
  207868. + return -ENOMEM;
  207869. + }
  207870. +
  207871. + hcd->rsrc_start = res->start;
  207872. + hcd->rsrc_len = resource_size(res);
  207873. + hcd->regs = regs;
  207874. + hcd_to_ehci(hcd)->caps = regs;
  207875. +
  207876. + h20ahb = (struct h20ahb_hcd *)hcd_to_ehci(hcd)->priv;
  207877. + h20ahb->nports = 1;
  207878. +
  207879. + platform_set_drvdata(pdev, hcd);
  207880. +
  207881. + /* get the PHY devices if needed */
  207882. + for (i = 0 ; i < h20ahb->nports ; i++) {
  207883. + struct usb_phy *phy;
  207884. +
  207885. + /* get the PHY device */
  207886. +#if 0
  207887. + if (dev->of_node)
  207888. + phy = devm_usb_get_phy_by_phandle(dev, "phys", i);
  207889. + else
  207890. + phy = devm_usb_get_phy_dev(dev, i);
  207891. +#endif
  207892. + phy = otg_ulpi_create(&ehci_h20ahb_phy_io_ops, 0);
  207893. + if (IS_ERR(phy)) {
  207894. + ret = PTR_ERR(phy);
  207895. + dev_err(dev, "Can't get PHY device for port %d: %d\n",
  207896. + i, ret);
  207897. + goto err_phy;
  207898. + }
  207899. + phy->dev = dev;
  207900. + usb_add_phy_dev(phy);
  207901. +
  207902. + h20ahb->phy[i] = phy;
  207903. + phy->io_priv = hcd->regs + EHCI_INSNREG05_ULPI;
  207904. +
  207905. +#if 0
  207906. + usb_phy_init(h20ahb->phy[i]);
  207907. + /* bring PHY out of suspend */
  207908. + usb_phy_set_suspend(h20ahb->phy[i], 0);
  207909. +#endif
  207910. + }
  207911. +
  207912. + /* make the first port's phy the one used by hcd as well */
  207913. + hcd->phy = h20ahb->phy[0];
  207914. +
  207915. + pm_runtime_enable(dev);
  207916. + pm_runtime_get_sync(dev);
  207917. +
  207918. + /*
  207919. + * An undocumented "feature" in the H20AHB EHCI controller,
  207920. + * causes suspended ports to be taken out of suspend when
  207921. + * the USBCMD.Run/Stop bit is cleared (for example when
  207922. + * we do ehci_bus_suspend).
  207923. + * This breaks suspend-resume if the root-hub is allowed
  207924. + * to suspend. Writing 1 to this undocumented register bit
  207925. + * disables this feature and restores normal behavior.
  207926. + */
  207927. + ehci_write(regs, EHCI_INSNREG04,
  207928. + EHCI_INSNREG04_DISABLE_UNSUSPEND);
  207929. +
  207930. + ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
  207931. + if (ret) {
  207932. + dev_err(dev, "failed to add hcd with err %d\n", ret);
  207933. + goto err_pm_runtime;
  207934. + }
  207935. + device_wakeup_enable(hcd->self.controller);
  207936. +
  207937. + /*
  207938. + * Bring PHYs out of reset for non PHY modes.
  207939. + * Even though HSIC mode is a PHY-less mode, the reset
  207940. + * line exists between the chips and can be modelled
  207941. + * as a PHY device for reset control.
  207942. + */
  207943. + for (i = 0; i < h20ahb->nports; i++) {
  207944. + usb_phy_init(h20ahb->phy[i]);
  207945. + /* bring PHY out of suspend */
  207946. + usb_phy_set_suspend(h20ahb->phy[i], 0);
  207947. + }
  207948. +
  207949. + return 0;
  207950. +
  207951. +err_pm_runtime:
  207952. + pm_runtime_put_sync(dev);
  207953. +
  207954. +err_phy:
  207955. + for (i = 0; i < h20ahb->nports; i++) {
  207956. + if (h20ahb->phy[i])
  207957. + usb_phy_shutdown(h20ahb->phy[i]);
  207958. + }
  207959. +
  207960. + usb_put_hcd(hcd);
  207961. +
  207962. + return ret;
  207963. +}
  207964. +
  207965. +
  207966. +/**
  207967. + * ehci_hcd_h20ahb_remove - shutdown processing for EHCI HCDs
  207968. + * @pdev: USB Host Controller being removed
  207969. + *
  207970. + * Reverses the effect of usb_ehci_hcd_h20ahb_probe(), first invoking
  207971. + * the HCD's stop() method. It is always called from a thread
  207972. + * context, normally "rmmod", "apmd", or something similar.
  207973. + */
  207974. +static int ehci_hcd_h20ahb_remove(struct platform_device *pdev)
  207975. +{
  207976. + struct device *dev = &pdev->dev;
  207977. + struct usb_hcd *hcd = dev_get_drvdata(dev);
  207978. + struct h20ahb_hcd *h20ahb = (struct h20ahb_hcd *)hcd_to_ehci(hcd)->priv;
  207979. + int i;
  207980. +
  207981. + usb_remove_hcd(hcd);
  207982. +
  207983. + for (i = 0; i < h20ahb->nports; i++) {
  207984. + if (h20ahb->phy[i])
  207985. + usb_phy_shutdown(h20ahb->phy[i]);
  207986. + }
  207987. +
  207988. + usb_put_hcd(hcd);
  207989. + pm_runtime_put_sync(dev);
  207990. + pm_runtime_disable(dev);
  207991. +
  207992. + return 0;
  207993. +}
  207994. +
  207995. +static const struct of_device_id h20ahb_ehci_dt_ids[] = {
  207996. + { .compatible = "snps,ehci-h20ahb" },
  207997. + { }
  207998. +};
  207999. +
  208000. +MODULE_DEVICE_TABLE(of, h20ahb_ehci_dt_ids);
  208001. +
  208002. +static struct platform_driver ehci_hcd_h20ahb_driver = {
  208003. + .probe = ehci_hcd_h20ahb_probe,
  208004. + .remove = ehci_hcd_h20ahb_remove,
  208005. + .shutdown = usb_hcd_platform_shutdown,
  208006. + /*.suspend = ehci_hcd_h20ahb_suspend, */
  208007. + /*.resume = ehci_hcd_h20ahb_resume, */
  208008. + .driver = {
  208009. + .name = hcd_name,
  208010. + .of_match_table = h20ahb_ehci_dt_ids,
  208011. + }
  208012. +};
  208013. +
  208014. +/*-------------------------------------------------------------------------*/
  208015. +
  208016. +static int __init ehci_h20ahb_init(void)
  208017. +{
  208018. + if (usb_disabled())
  208019. + return -ENODEV;
  208020. +
  208021. + pr_info("%s: " DRIVER_DESC "\n", hcd_name);
  208022. +
  208023. + ehci_init_driver(&ehci_h20ahb_hc_driver, &ehci_h20ahb_overrides);
  208024. + return platform_driver_register(&ehci_hcd_h20ahb_driver);
  208025. +}
  208026. +module_init(ehci_h20ahb_init);
  208027. +
  208028. +static void __exit ehci_h20ahb_cleanup(void)
  208029. +{
  208030. + platform_driver_unregister(&ehci_hcd_h20ahb_driver);
  208031. +}
  208032. +module_exit(ehci_h20ahb_cleanup);
  208033. +
  208034. +MODULE_ALIAS("platform:ehci-h20ahb");
  208035. +MODULE_AUTHOR("Liviu Dudau <Liviu.Dudau@arm.com>");
  208036. +
  208037. +MODULE_DESCRIPTION(DRIVER_DESC);
  208038. +MODULE_LICENSE("GPL");
  208039. diff -Nur linux-3.14.14/drivers/usb/host/ehci-hcd.c linux-imx6-3.14/drivers/usb/host/ehci-hcd.c
  208040. --- linux-3.14.14/drivers/usb/host/ehci-hcd.c 2014-07-28 10:07:25.000000000 -0500
  208041. +++ linux-imx6-3.14/drivers/usb/host/ehci-hcd.c 2014-12-08 00:31:54.752418001 -0600
  208042. @@ -590,11 +590,16 @@
  208043. */
  208044. hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
  208045. if (HCC_64BIT_ADDR(hcc_params)) {
  208046. - ehci_writel(ehci, 0, &ehci->regs->segment);
  208047. -#if 0
  208048. -// this is deeply broken on almost all architectures
  208049. +#ifdef CONFIG_ARM64
  208050. + ehci_writel(ehci, ehci->periodic_dma >> 32, &ehci->regs->segment);
  208051. + /*
  208052. + * this is deeply broken on almost all architectures
  208053. + * but arm64 can use it so enable it
  208054. + */
  208055. if (!dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)))
  208056. ehci_info(ehci, "enabled 64bit DMA\n");
  208057. +#else
  208058. + ehci_writel(ehci, 0, &ehci->regs->segment);
  208059. #endif
  208060. }
  208061. diff -Nur linux-3.14.14/drivers/usb/host/ehci-hub.c linux-imx6-3.14/drivers/usb/host/ehci-hub.c
  208062. --- linux-3.14.14/drivers/usb/host/ehci-hub.c 2014-07-28 10:07:25.000000000 -0500
  208063. +++ linux-imx6-3.14/drivers/usb/host/ehci-hub.c 2014-12-08 00:31:54.752418001 -0600
  208064. @@ -313,6 +313,15 @@
  208065. USB_PORT_STAT_HIGH_SPEED)
  208066. fs_idle_delay = true;
  208067. ehci_writel(ehci, t2, reg);
  208068. + if ((t2 & PORT_WKDISC_E)
  208069. + && (ehci_port_speed(ehci, t2) ==
  208070. + USB_PORT_STAT_HIGH_SPEED))
  208071. + /*
  208072. + * If the high-speed device has not switched
  208073. + * to full-speed idle before WKDISC_E has
  208074. + * effected, there will be a WKDISC event.
  208075. + */
  208076. + mdelay(4);
  208077. changed = 1;
  208078. }
  208079. }
  208080. diff -Nur linux-3.14.14/drivers/usb/host/Kconfig linux-imx6-3.14/drivers/usb/host/Kconfig
  208081. --- linux-3.14.14/drivers/usb/host/Kconfig 2014-07-28 10:07:25.000000000 -0500
  208082. +++ linux-imx6-3.14/drivers/usb/host/Kconfig 2014-12-08 00:31:54.748418001 -0600
  208083. @@ -158,6 +158,13 @@
  208084. Enables support for the on-chip EHCI controller on
  208085. ST SPEAr chips.
  208086. +config USB_EHCI_HCD_SYNOPSYS
  208087. + tristate "Support for Synopsys Host-AHB USB 2.0 controller"
  208088. + depends on USB_EHCI_HCD && USB_PHY
  208089. + ---help---
  208090. + Enable support for onchip USB controllers based on DesignWare USB 2.0
  208091. + Host-AHB Controller IP from Synopsys.
  208092. +
  208093. config USB_EHCI_HCD_AT91
  208094. tristate "Support for Atmel on-chip EHCI USB controller"
  208095. depends on USB_EHCI_HCD && ARCH_AT91
  208096. diff -Nur linux-3.14.14/drivers/usb/host/Makefile linux-imx6-3.14/drivers/usb/host/Makefile
  208097. --- linux-3.14.14/drivers/usb/host/Makefile 2014-07-28 10:07:25.000000000 -0500
  208098. +++ linux-imx6-3.14/drivers/usb/host/Makefile 2014-12-08 00:31:54.748418001 -0600
  208099. @@ -33,6 +33,8 @@
  208100. obj-$(CONFIG_USB_EHCI_HCD_ORION) += ehci-orion.o
  208101. obj-$(CONFIG_USB_EHCI_HCD_SPEAR) += ehci-spear.o
  208102. obj-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
  208103. +obj-$(CONFIG_USB_EHCI_S5P) += ehci-s5p.o
  208104. +obj-$(CONFIG_USB_EHCI_HCD_SYNOPSYS) += ehci-h20ahb.o
  208105. obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
  208106. obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o
  208107. obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
  208108. diff -Nur linux-3.14.14/drivers/usb/phy/Kconfig linux-imx6-3.14/drivers/usb/phy/Kconfig
  208109. --- linux-3.14.14/drivers/usb/phy/Kconfig 2014-07-28 10:07:25.000000000 -0500
  208110. +++ linux-imx6-3.14/drivers/usb/phy/Kconfig 2014-12-08 00:31:54.784418001 -0600
  208111. @@ -253,7 +253,7 @@
  208112. config USB_ULPI
  208113. bool "Generic ULPI Transceiver Driver"
  208114. - depends on ARM
  208115. + depends on ARM || ARM64
  208116. help
  208117. Enable this to support ULPI connected USB OTG transceivers which
  208118. are likely found on embedded boards.
  208119. diff -Nur linux-3.14.14/drivers/usb/phy/phy-mxs-usb.c linux-imx6-3.14/drivers/usb/phy/phy-mxs-usb.c
  208120. --- linux-3.14.14/drivers/usb/phy/phy-mxs-usb.c 2014-07-28 10:07:25.000000000 -0500
  208121. +++ linux-imx6-3.14/drivers/usb/phy/phy-mxs-usb.c 2014-12-08 00:31:54.788418001 -0600
  208122. @@ -1,5 +1,5 @@
  208123. /*
  208124. - * Copyright 2012 Freescale Semiconductor, Inc.
  208125. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  208126. * Copyright (C) 2012 Marek Vasut <marex@denx.de>
  208127. * on behalf of DENX Software Engineering GmbH
  208128. *
  208129. @@ -20,6 +20,9 @@
  208130. #include <linux/delay.h>
  208131. #include <linux/err.h>
  208132. #include <linux/io.h>
  208133. +#include <linux/of_device.h>
  208134. +#include <linux/regmap.h>
  208135. +#include <linux/mfd/syscon.h>
  208136. #define DRIVER_NAME "mxs_phy"
  208137. @@ -28,18 +31,137 @@
  208138. #define HW_USBPHY_CTRL_SET 0x34
  208139. #define HW_USBPHY_CTRL_CLR 0x38
  208140. +#define HW_USBPHY_DEBUG_SET 0x54
  208141. +#define HW_USBPHY_DEBUG_CLR 0x58
  208142. +
  208143. +#define HW_USBPHY_IP 0x90
  208144. +#define HW_USBPHY_IP_SET 0x94
  208145. +#define HW_USBPHY_IP_CLR 0x98
  208146. +
  208147. #define BM_USBPHY_CTRL_SFTRST BIT(31)
  208148. #define BM_USBPHY_CTRL_CLKGATE BIT(30)
  208149. +#define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS BIT(26)
  208150. +#define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE BIT(25)
  208151. +#define BM_USBPHY_CTRL_ENVBUSCHG_WKUP BIT(23)
  208152. +#define BM_USBPHY_CTRL_ENIDCHG_WKUP BIT(22)
  208153. +#define BM_USBPHY_CTRL_ENDPDMCHG_WKUP BIT(21)
  208154. +#define BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD BIT(20)
  208155. +#define BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE BIT(19)
  208156. +#define BM_USBPHY_CTRL_ENAUTO_PWRON_PLL BIT(18)
  208157. #define BM_USBPHY_CTRL_ENUTMILEVEL3 BIT(15)
  208158. #define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14)
  208159. #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1)
  208160. +#define BM_USBPHY_IP_FIX (BIT(17) | BIT(18))
  208161. +
  208162. +#define BM_USBPHY_DEBUG_CLKGATE BIT(30)
  208163. +
  208164. +/* Anatop Registers */
  208165. +#define ANADIG_ANA_MISC0 0x150
  208166. +#define ANADIG_ANA_MISC0_SET 0x154
  208167. +#define ANADIG_ANA_MISC0_CLR 0x158
  208168. +
  208169. +#define ANADIG_USB1_VBUS_DET_STAT 0x1c0
  208170. +#define ANADIG_USB2_VBUS_DET_STAT 0x220
  208171. +
  208172. +#define ANADIG_USB1_LOOPBACK_SET 0x1e4
  208173. +#define ANADIG_USB1_LOOPBACK_CLR 0x1e8
  208174. +#define ANADIG_USB2_LOOPBACK_SET 0x244
  208175. +#define ANADIG_USB2_LOOPBACK_CLR 0x248
  208176. +
  208177. +#define ANADIG_USB1_MISC 0x1f0
  208178. +#define ANADIG_USB2_MISC 0x250
  208179. +
  208180. +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG BIT(12)
  208181. +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11)
  208182. +
  208183. +#define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID BIT(3)
  208184. +#define BM_ANADIG_USB2_VBUS_DET_STAT_VBUS_VALID BIT(3)
  208185. +
  208186. +#define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 BIT(2)
  208187. +#define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN BIT(5)
  208188. +#define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 BIT(2)
  208189. +#define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN BIT(5)
  208190. +
  208191. +#define BM_ANADIG_USB1_MISC_RX_VPIN_FS BIT(29)
  208192. +#define BM_ANADIG_USB1_MISC_RX_VMIN_FS BIT(28)
  208193. +#define BM_ANADIG_USB2_MISC_RX_VPIN_FS BIT(29)
  208194. +#define BM_ANADIG_USB2_MISC_RX_VMIN_FS BIT(28)
  208195. +
  208196. +#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
  208197. +
  208198. +/* Do disconnection between PHY and controller without vbus */
  208199. +#define MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS BIT(0)
  208200. +
  208201. +/*
  208202. + * The PHY will be in messy if there is an wakeup after putting
  208203. + * bus to suspend (set portsc.suspendM) but before setting PHY to low
  208204. + * power mode (set portsc.phcd).
  208205. + */
  208206. +#define MXS_PHY_ABNORAML_IN_SUSPEND BIT(1)
  208207. +
  208208. +/*
  208209. + * The SOF sends too fast after resuming, it will cause disconnection
  208210. + * between host and high speed device.
  208211. + */
  208212. +#define MXS_PHY_SENDING_SOF_TOO_FAST BIT(2)
  208213. +
  208214. +/* The SoCs who have anatop module */
  208215. +#define MXS_PHY_HAS_ANATOP BIT(3)
  208216. +
  208217. +struct mxs_phy_data {
  208218. + unsigned int flags;
  208219. +};
  208220. +
  208221. +static const struct mxs_phy_data imx23_phy_data = {
  208222. + .flags = MXS_PHY_ABNORAML_IN_SUSPEND | MXS_PHY_SENDING_SOF_TOO_FAST,
  208223. +};
  208224. +
  208225. +static const struct mxs_phy_data imx6q_phy_data = {
  208226. + .flags = MXS_PHY_SENDING_SOF_TOO_FAST |
  208227. + MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
  208228. + MXS_PHY_HAS_ANATOP,
  208229. +};
  208230. +
  208231. +static const struct mxs_phy_data imx6sl_phy_data = {
  208232. + .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
  208233. + MXS_PHY_HAS_ANATOP,
  208234. +};
  208235. +
  208236. +static const struct of_device_id mxs_phy_dt_ids[] = {
  208237. + { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
  208238. + { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
  208239. + { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
  208240. + { /* sentinel */ }
  208241. +};
  208242. +MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
  208243. +
  208244. struct mxs_phy {
  208245. struct usb_phy phy;
  208246. struct clk *clk;
  208247. + const struct mxs_phy_data *data;
  208248. + struct regmap *regmap_anatop;
  208249. + int port_id;
  208250. };
  208251. -#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
  208252. +static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy)
  208253. +{
  208254. + return mxs_phy->data == &imx6q_phy_data;
  208255. +}
  208256. +
  208257. +static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy)
  208258. +{
  208259. + return mxs_phy->data == &imx6sl_phy_data;
  208260. +}
  208261. +
  208262. +/*
  208263. + * PHY needs some 32K cycles to switch from 32K clock to
  208264. + * bus (such as AHB/AXI, etc) clock.
  208265. + */
  208266. +static void mxs_phy_clock_switch(void)
  208267. +{
  208268. + usleep_range(300, 400);
  208269. +}
  208270. static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
  208271. {
  208272. @@ -53,19 +175,122 @@
  208273. /* Power up the PHY */
  208274. writel(0, base + HW_USBPHY_PWD);
  208275. - /* enable FS/LS device */
  208276. - writel(BM_USBPHY_CTRL_ENUTMILEVEL2 |
  208277. - BM_USBPHY_CTRL_ENUTMILEVEL3,
  208278. + /*
  208279. + * USB PHY Ctrl Setting
  208280. + * - Auto clock/power on
  208281. + * - Enable full/low speed support
  208282. + */
  208283. + writel(BM_USBPHY_CTRL_ENAUTOSET_USBCLKS |
  208284. + BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE |
  208285. + BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD |
  208286. + BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE |
  208287. + BM_USBPHY_CTRL_ENAUTO_PWRON_PLL |
  208288. + BM_USBPHY_CTRL_ENUTMILEVEL2 |
  208289. + BM_USBPHY_CTRL_ENUTMILEVEL3,
  208290. base + HW_USBPHY_CTRL_SET);
  208291. + /* Enable IC solution */
  208292. + if (is_imx6q_phy(mxs_phy) || is_imx6sl_phy(mxs_phy))
  208293. + writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET);
  208294. +
  208295. return 0;
  208296. }
  208297. +/* Return true if the vbus is there */
  208298. +static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy)
  208299. +{
  208300. + unsigned int vbus_value;
  208301. +
  208302. + if (mxs_phy->port_id == 0)
  208303. + regmap_read(mxs_phy->regmap_anatop,
  208304. + ANADIG_USB1_VBUS_DET_STAT,
  208305. + &vbus_value);
  208306. + else if (mxs_phy->port_id == 1)
  208307. + regmap_read(mxs_phy->regmap_anatop,
  208308. + ANADIG_USB2_VBUS_DET_STAT,
  208309. + &vbus_value);
  208310. +
  208311. + if (vbus_value & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)
  208312. + return true;
  208313. + else
  208314. + return false;
  208315. +}
  208316. +
  208317. +static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
  208318. +{
  208319. + void __iomem *base = mxs_phy->phy.io_priv;
  208320. + u32 reg;
  208321. +
  208322. + if (disconnect)
  208323. + writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
  208324. + base + HW_USBPHY_DEBUG_CLR);
  208325. +
  208326. + if (mxs_phy->port_id == 0) {
  208327. + reg = disconnect ? ANADIG_USB1_LOOPBACK_SET
  208328. + : ANADIG_USB1_LOOPBACK_CLR;
  208329. + regmap_write(mxs_phy->regmap_anatop, reg,
  208330. + BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 |
  208331. + BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN);
  208332. + } else if (mxs_phy->port_id == 1) {
  208333. + reg = disconnect ? ANADIG_USB2_LOOPBACK_SET
  208334. + : ANADIG_USB2_LOOPBACK_CLR;
  208335. + regmap_write(mxs_phy->regmap_anatop, reg,
  208336. + BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 |
  208337. + BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN);
  208338. + }
  208339. +
  208340. + if (!disconnect)
  208341. + writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
  208342. + base + HW_USBPHY_DEBUG_SET);
  208343. +
  208344. + /* Delay some time, and let Linestate be SE0 for controller */
  208345. + if (disconnect)
  208346. + usleep_range(500, 1000);
  208347. +}
  208348. +
  208349. +static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
  208350. +{
  208351. + bool vbus_is_on = false;
  208352. +
  208353. + /* If the SoCs don't need to disconnect line without vbus, quit */
  208354. + if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS))
  208355. + return;
  208356. +
  208357. + /* If the SoCs don't have anatop, quit */
  208358. + if (!mxs_phy->regmap_anatop)
  208359. + return;
  208360. +
  208361. + vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
  208362. +
  208363. + if (on && !vbus_is_on)
  208364. + __mxs_phy_disconnect_line(mxs_phy, true);
  208365. + else
  208366. + __mxs_phy_disconnect_line(mxs_phy, false);
  208367. +
  208368. +}
  208369. +
  208370. +static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on)
  208371. +{
  208372. + unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR;
  208373. +
  208374. + /* If the SoCs don't have anatop, quit */
  208375. + if (!mxs_phy->regmap_anatop)
  208376. + return;
  208377. +
  208378. + if (is_imx6q_phy(mxs_phy))
  208379. + regmap_write(mxs_phy->regmap_anatop, reg,
  208380. + BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG);
  208381. + else if (is_imx6sl_phy(mxs_phy))
  208382. + regmap_write(mxs_phy->regmap_anatop,
  208383. + reg, BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL);
  208384. +}
  208385. +
  208386. static int mxs_phy_init(struct usb_phy *phy)
  208387. {
  208388. int ret;
  208389. struct mxs_phy *mxs_phy = to_mxs_phy(phy);
  208390. + mxs_phy_clock_switch();
  208391. ret = clk_prepare_enable(mxs_phy->clk);
  208392. if (ret)
  208393. return ret;
  208394. @@ -83,17 +308,62 @@
  208395. clk_disable_unprepare(mxs_phy->clk);
  208396. }
  208397. +static bool mxs_phy_is_low_speed_connection(struct mxs_phy *mxs_phy)
  208398. +{
  208399. + unsigned int line_state;
  208400. + /* bit definition is the same for all controllers */
  208401. + unsigned int dp_bit = BM_ANADIG_USB1_MISC_RX_VPIN_FS,
  208402. + dm_bit = BM_ANADIG_USB1_MISC_RX_VMIN_FS;
  208403. + unsigned int reg = ANADIG_USB1_MISC;
  208404. +
  208405. + /* If the SoCs don't have anatop, quit */
  208406. + if (!mxs_phy->regmap_anatop)
  208407. + return false;
  208408. +
  208409. + if (mxs_phy->port_id == 0)
  208410. + reg = ANADIG_USB1_MISC;
  208411. + else if (mxs_phy->port_id == 1)
  208412. + reg = ANADIG_USB2_MISC;
  208413. +
  208414. + regmap_read(mxs_phy->regmap_anatop, reg, &line_state);
  208415. +
  208416. + if ((line_state & (dp_bit | dm_bit)) == dm_bit)
  208417. + return true;
  208418. + else
  208419. + return false;
  208420. +}
  208421. +
  208422. static int mxs_phy_suspend(struct usb_phy *x, int suspend)
  208423. {
  208424. int ret;
  208425. struct mxs_phy *mxs_phy = to_mxs_phy(x);
  208426. + bool low_speed_connection, vbus_is_on;
  208427. +
  208428. + low_speed_connection = mxs_phy_is_low_speed_connection(mxs_phy);
  208429. + vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
  208430. if (suspend) {
  208431. writel(0xffffffff, x->io_priv + HW_USBPHY_PWD);
  208432. + /*
  208433. + * FIXME: Do not power down RXPWD1PT1 bit for low speed
  208434. + * connect. The low speed connection will have problem at
  208435. + * very rare cases during usb suspend and resume process.
  208436. + */
  208437. + if (low_speed_connection & vbus_is_on) {
  208438. + /*
  208439. + * If value to be set as pwd value is not 0xffffffff,
  208440. + * several 32Khz cycles are needed.
  208441. + */
  208442. + mxs_phy_clock_switch();
  208443. + writel(0xffbfffff, x->io_priv + HW_USBPHY_PWD);
  208444. + } else {
  208445. + writel(0xffffffff, x->io_priv + HW_USBPHY_PWD);
  208446. + }
  208447. writel(BM_USBPHY_CTRL_CLKGATE,
  208448. x->io_priv + HW_USBPHY_CTRL_SET);
  208449. clk_disable_unprepare(mxs_phy->clk);
  208450. } else {
  208451. + mxs_phy_clock_switch();
  208452. ret = clk_prepare_enable(mxs_phy->clk);
  208453. if (ret)
  208454. return ret;
  208455. @@ -105,11 +375,28 @@
  208456. return 0;
  208457. }
  208458. +static int mxs_phy_set_wakeup(struct usb_phy *x, bool enabled)
  208459. +{
  208460. + struct mxs_phy *mxs_phy = to_mxs_phy(x);
  208461. + u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP |
  208462. + BM_USBPHY_CTRL_ENDPDMCHG_WKUP |
  208463. + BM_USBPHY_CTRL_ENIDCHG_WKUP;
  208464. + if (enabled) {
  208465. + mxs_phy_disconnect_line(mxs_phy, true);
  208466. + writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_SET);
  208467. + } else {
  208468. + writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_CLR);
  208469. + mxs_phy_disconnect_line(mxs_phy, false);
  208470. + }
  208471. +
  208472. + return 0;
  208473. +}
  208474. +
  208475. static int mxs_phy_on_connect(struct usb_phy *phy,
  208476. enum usb_device_speed speed)
  208477. {
  208478. - dev_dbg(phy->dev, "%s speed device has connected\n",
  208479. - (speed == USB_SPEED_HIGH) ? "high" : "non-high");
  208480. + dev_dbg(phy->dev, "%s device has connected\n",
  208481. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  208482. if (speed == USB_SPEED_HIGH)
  208483. writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  208484. @@ -121,8 +408,8 @@
  208485. static int mxs_phy_on_disconnect(struct usb_phy *phy,
  208486. enum usb_device_speed speed)
  208487. {
  208488. - dev_dbg(phy->dev, "%s speed device has disconnected\n",
  208489. - (speed == USB_SPEED_HIGH) ? "high" : "non-high");
  208490. + dev_dbg(phy->dev, "%s device has disconnected\n",
  208491. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  208492. if (speed == USB_SPEED_HIGH)
  208493. writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  208494. @@ -131,6 +418,48 @@
  208495. return 0;
  208496. }
  208497. +static int mxs_phy_on_suspend(struct usb_phy *phy,
  208498. + enum usb_device_speed speed)
  208499. +{
  208500. + struct mxs_phy *mxs_phy = to_mxs_phy(phy);
  208501. +
  208502. + dev_dbg(phy->dev, "%s device has suspended\n",
  208503. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  208504. +
  208505. + /* delay 4ms to wait bus entering idle */
  208506. + usleep_range(4000, 5000);
  208507. +
  208508. + if (mxs_phy->data->flags & MXS_PHY_ABNORAML_IN_SUSPEND) {
  208509. + writel_relaxed(0xffffffff, phy->io_priv + HW_USBPHY_PWD);
  208510. + writel_relaxed(0, phy->io_priv + HW_USBPHY_PWD);
  208511. + }
  208512. +
  208513. + if (speed == USB_SPEED_HIGH)
  208514. + writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  208515. + phy->io_priv + HW_USBPHY_CTRL_CLR);
  208516. +
  208517. + return 0;
  208518. +}
  208519. +
  208520. +/*
  208521. + * The resume signal must be finished here.
  208522. + */
  208523. +static int mxs_phy_on_resume(struct usb_phy *phy,
  208524. + enum usb_device_speed speed)
  208525. +{
  208526. + dev_dbg(phy->dev, "%s device has resumed\n",
  208527. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  208528. +
  208529. + if (speed == USB_SPEED_HIGH) {
  208530. + /* Make sure the device has switched to High-Speed mode */
  208531. + udelay(500);
  208532. + writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  208533. + phy->io_priv + HW_USBPHY_CTRL_SET);
  208534. + }
  208535. +
  208536. + return 0;
  208537. +}
  208538. +
  208539. static int mxs_phy_probe(struct platform_device *pdev)
  208540. {
  208541. struct resource *res;
  208542. @@ -138,6 +467,9 @@
  208543. struct clk *clk;
  208544. struct mxs_phy *mxs_phy;
  208545. int ret;
  208546. + const struct of_device_id *of_id =
  208547. + of_match_device(mxs_phy_dt_ids, &pdev->dev);
  208548. + struct device_node *np = pdev->dev.of_node;
  208549. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  208550. base = devm_ioremap_resource(&pdev->dev, res);
  208551. @@ -157,6 +489,13 @@
  208552. return -ENOMEM;
  208553. }
  208554. + ret = of_alias_get_id(np, "usbphy");
  208555. + if (ret < 0) {
  208556. + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
  208557. + return ret;
  208558. + }
  208559. + mxs_phy->port_id = ret;
  208560. +
  208561. mxs_phy->phy.io_priv = base;
  208562. mxs_phy->phy.dev = &pdev->dev;
  208563. mxs_phy->phy.label = DRIVER_NAME;
  208564. @@ -166,11 +505,30 @@
  208565. mxs_phy->phy.notify_connect = mxs_phy_on_connect;
  208566. mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect;
  208567. mxs_phy->phy.type = USB_PHY_TYPE_USB2;
  208568. + mxs_phy->phy.set_wakeup = mxs_phy_set_wakeup;
  208569. mxs_phy->clk = clk;
  208570. + mxs_phy->data = of_id->data;
  208571. +
  208572. + if (mxs_phy->data->flags & MXS_PHY_SENDING_SOF_TOO_FAST) {
  208573. + mxs_phy->phy.notify_suspend = mxs_phy_on_suspend;
  208574. + mxs_phy->phy.notify_resume = mxs_phy_on_resume;
  208575. + }
  208576. platform_set_drvdata(pdev, mxs_phy);
  208577. + if (mxs_phy->data->flags & MXS_PHY_HAS_ANATOP) {
  208578. + mxs_phy->regmap_anatop = syscon_regmap_lookup_by_phandle
  208579. + (np, "fsl,anatop");
  208580. + if (IS_ERR(mxs_phy->regmap_anatop)) {
  208581. + dev_dbg(&pdev->dev,
  208582. + "failed to find regmap for anatop\n");
  208583. + return PTR_ERR(mxs_phy->regmap_anatop);
  208584. + }
  208585. + }
  208586. +
  208587. + device_set_wakeup_capable(&pdev->dev, true);
  208588. +
  208589. ret = usb_add_phy_dev(&mxs_phy->phy);
  208590. if (ret)
  208591. return ret;
  208592. @@ -187,11 +545,27 @@
  208593. return 0;
  208594. }
  208595. -static const struct of_device_id mxs_phy_dt_ids[] = {
  208596. - { .compatible = "fsl,imx23-usbphy", },
  208597. - { /* sentinel */ }
  208598. -};
  208599. -MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
  208600. +static int mxs_phy_system_suspend(struct device *dev)
  208601. +{
  208602. + struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
  208603. +
  208604. + if (device_may_wakeup(dev))
  208605. + mxs_phy_enable_ldo_in_suspend(mxs_phy, true);
  208606. +
  208607. + return 0;
  208608. +}
  208609. +
  208610. +static int mxs_phy_system_resume(struct device *dev)
  208611. +{
  208612. + struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
  208613. +
  208614. + if (device_may_wakeup(dev))
  208615. + mxs_phy_enable_ldo_in_suspend(mxs_phy, false);
  208616. +
  208617. + return 0;
  208618. +}
  208619. +
  208620. +SIMPLE_DEV_PM_OPS(mxs_phy_pm, mxs_phy_system_suspend, mxs_phy_system_resume);
  208621. static struct platform_driver mxs_phy_driver = {
  208622. .probe = mxs_phy_probe,
  208623. @@ -200,6 +574,7 @@
  208624. .name = DRIVER_NAME,
  208625. .owner = THIS_MODULE,
  208626. .of_match_table = mxs_phy_dt_ids,
  208627. + .pm = &mxs_phy_pm,
  208628. },
  208629. };
  208630. diff -Nur linux-3.14.14/drivers/usb/phy/phy-ulpi.c linux-imx6-3.14/drivers/usb/phy/phy-ulpi.c
  208631. --- linux-3.14.14/drivers/usb/phy/phy-ulpi.c 2014-07-28 10:07:25.000000000 -0500
  208632. +++ linux-imx6-3.14/drivers/usb/phy/phy-ulpi.c 2014-12-08 00:31:54.788418001 -0600
  208633. @@ -48,6 +48,7 @@
  208634. ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"),
  208635. ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"),
  208636. ULPI_INFO(ULPI_ID(0x0424, 0x0007), "SMSC USB3320"),
  208637. + ULPI_INFO(ULPI_ID(0x0424, 0x0009), "SMSC USB334x"),
  208638. ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"),
  208639. };
  208640. diff -Nur linux-3.14.14/drivers/video/amba-clcd.c linux-imx6-3.14/drivers/video/amba-clcd.c
  208641. --- linux-3.14.14/drivers/video/amba-clcd.c 2014-07-28 10:07:25.000000000 -0500
  208642. +++ linux-imx6-3.14/drivers/video/amba-clcd.c 2014-12-08 00:31:54.820418001 -0600
  208643. @@ -17,7 +17,10 @@
  208644. #include <linux/string.h>
  208645. #include <linux/slab.h>
  208646. #include <linux/delay.h>
  208647. +#include <linux/dma-mapping.h>
  208648. +#include <linux/memblock.h>
  208649. #include <linux/mm.h>
  208650. +#include <linux/of.h>
  208651. #include <linux/fb.h>
  208652. #include <linux/init.h>
  208653. #include <linux/ioport.h>
  208654. @@ -31,8 +34,20 @@
  208655. #define to_clcd(info) container_of(info, struct clcd_fb, fb)
  208656. +#ifdef CONFIG_ARM
  208657. +#define clcdfb_dma_alloc dma_alloc_writecombine
  208658. +#define clcdfb_dma_free dma_free_writecombine
  208659. +#define clcdfb_dma_mmap dma_mmap_writecombine
  208660. +#else
  208661. +#define clcdfb_dma_alloc dma_alloc_coherent
  208662. +#define clcdfb_dma_free dma_free_coherent
  208663. +#define clcdfb_dma_mmap dma_mmap_coherent
  208664. +#endif
  208665. +
  208666. /* This is limited to 16 characters when displayed by X startup */
  208667. static const char *clcd_name = "CLCD FB";
  208668. +static char *def_mode;
  208669. +module_param_named(mode, def_mode, charp, 0);
  208670. /*
  208671. * Unfortunately, the enable/disable functions may be called either from
  208672. @@ -234,6 +249,17 @@
  208673. bgr = caps & CLCD_CAP_BGR && var->blue.offset == 0;
  208674. rgb = caps & CLCD_CAP_RGB && var->red.offset == 0;
  208675. + /*
  208676. + * Seems that for 32-bit mode there is confusion about RGB
  208677. + * ordering somewhere between user-side, kernel and hardware.
  208678. + * The following hack seems get things working, at least on
  208679. + * vexpress hardware and models...
  208680. + */
  208681. + if (var->bits_per_pixel == 32) {
  208682. + bgr = false;
  208683. + rgb = true;
  208684. + }
  208685. +
  208686. if (!bgr && !rgb)
  208687. /*
  208688. * The requested format was not possible, try just
  208689. @@ -393,6 +419,44 @@
  208690. return 0;
  208691. }
  208692. +int clcdfb_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma)
  208693. +{
  208694. + return clcdfb_dma_mmap(&fb->dev->dev, vma,
  208695. + fb->fb.screen_base,
  208696. + fb->fb.fix.smem_start,
  208697. + fb->fb.fix.smem_len);
  208698. +}
  208699. +
  208700. +int clcdfb_mmap_io(struct clcd_fb *fb, struct vm_area_struct *vma)
  208701. +{
  208702. + unsigned long user_count, count, pfn, off;
  208703. +
  208704. + user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
  208705. + count = PAGE_ALIGN(fb->fb.fix.smem_len) >> PAGE_SHIFT;
  208706. + pfn = fb->fb.fix.smem_start >> PAGE_SHIFT;
  208707. + off = vma->vm_pgoff;
  208708. +
  208709. + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  208710. +
  208711. + if (off < count && user_count <= (count - off))
  208712. + return remap_pfn_range(vma, vma->vm_start, pfn + off,
  208713. + user_count << PAGE_SHIFT,
  208714. + vma->vm_page_prot);
  208715. +
  208716. + return -ENXIO;
  208717. +}
  208718. +
  208719. +void clcdfb_remove_dma(struct clcd_fb *fb)
  208720. +{
  208721. + clcdfb_dma_free(&fb->dev->dev, fb->fb.fix.smem_len,
  208722. + fb->fb.screen_base, fb->fb.fix.smem_start);
  208723. +}
  208724. +
  208725. +void clcdfb_remove_io(struct clcd_fb *fb)
  208726. +{
  208727. + iounmap(fb->fb.screen_base);
  208728. +}
  208729. +
  208730. static int clcdfb_mmap(struct fb_info *info,
  208731. struct vm_area_struct *vma)
  208732. {
  208733. @@ -543,14 +607,247 @@
  208734. return ret;
  208735. }
  208736. +struct string_lookup {
  208737. + const char *string;
  208738. + const u32 val;
  208739. +};
  208740. +
  208741. +static struct string_lookup vmode_lookups[] = {
  208742. + { "FB_VMODE_NONINTERLACED", FB_VMODE_NONINTERLACED},
  208743. + { "FB_VMODE_INTERLACED", FB_VMODE_INTERLACED},
  208744. + { "FB_VMODE_DOUBLE", FB_VMODE_DOUBLE},
  208745. + { "FB_VMODE_ODD_FLD_FIRST", FB_VMODE_ODD_FLD_FIRST},
  208746. + { NULL, 0 },
  208747. +};
  208748. +
  208749. +static struct string_lookup tim2_lookups[] = {
  208750. + { "TIM2_CLKSEL", TIM2_CLKSEL},
  208751. + { "TIM2_IVS", TIM2_IVS},
  208752. + { "TIM2_IHS", TIM2_IHS},
  208753. + { "TIM2_IPC", TIM2_IPC},
  208754. + { "TIM2_IOE", TIM2_IOE},
  208755. + { "TIM2_BCD", TIM2_BCD},
  208756. + { NULL, 0},
  208757. +};
  208758. +static struct string_lookup cntl_lookups[] = {
  208759. + {"CNTL_LCDEN", CNTL_LCDEN},
  208760. + {"CNTL_LCDBPP1", CNTL_LCDBPP1},
  208761. + {"CNTL_LCDBPP2", CNTL_LCDBPP2},
  208762. + {"CNTL_LCDBPP4", CNTL_LCDBPP4},
  208763. + {"CNTL_LCDBPP8", CNTL_LCDBPP8},
  208764. + {"CNTL_LCDBPP16", CNTL_LCDBPP16},
  208765. + {"CNTL_LCDBPP16_565", CNTL_LCDBPP16_565},
  208766. + {"CNTL_LCDBPP16_444", CNTL_LCDBPP16_444},
  208767. + {"CNTL_LCDBPP24", CNTL_LCDBPP24},
  208768. + {"CNTL_LCDBW", CNTL_LCDBW},
  208769. + {"CNTL_LCDTFT", CNTL_LCDTFT},
  208770. + {"CNTL_LCDMONO8", CNTL_LCDMONO8},
  208771. + {"CNTL_LCDDUAL", CNTL_LCDDUAL},
  208772. + {"CNTL_BGR", CNTL_BGR},
  208773. + {"CNTL_BEBO", CNTL_BEBO},
  208774. + {"CNTL_BEPO", CNTL_BEPO},
  208775. + {"CNTL_LCDPWR", CNTL_LCDPWR},
  208776. + {"CNTL_LCDVCOMP(1)", CNTL_LCDVCOMP(1)},
  208777. + {"CNTL_LCDVCOMP(2)", CNTL_LCDVCOMP(2)},
  208778. + {"CNTL_LCDVCOMP(3)", CNTL_LCDVCOMP(3)},
  208779. + {"CNTL_LCDVCOMP(4)", CNTL_LCDVCOMP(4)},
  208780. + {"CNTL_LCDVCOMP(5)", CNTL_LCDVCOMP(5)},
  208781. + {"CNTL_LCDVCOMP(6)", CNTL_LCDVCOMP(6)},
  208782. + {"CNTL_LCDVCOMP(7)", CNTL_LCDVCOMP(7)},
  208783. + {"CNTL_LDMAFIFOTIME", CNTL_LDMAFIFOTIME},
  208784. + {"CNTL_WATERMARK", CNTL_WATERMARK},
  208785. + { NULL, 0},
  208786. +};
  208787. +static struct string_lookup caps_lookups[] = {
  208788. + {"CLCD_CAP_RGB444", CLCD_CAP_RGB444},
  208789. + {"CLCD_CAP_RGB5551", CLCD_CAP_RGB5551},
  208790. + {"CLCD_CAP_RGB565", CLCD_CAP_RGB565},
  208791. + {"CLCD_CAP_RGB888", CLCD_CAP_RGB888},
  208792. + {"CLCD_CAP_BGR444", CLCD_CAP_BGR444},
  208793. + {"CLCD_CAP_BGR5551", CLCD_CAP_BGR5551},
  208794. + {"CLCD_CAP_BGR565", CLCD_CAP_BGR565},
  208795. + {"CLCD_CAP_BGR888", CLCD_CAP_BGR888},
  208796. + {"CLCD_CAP_444", CLCD_CAP_444},
  208797. + {"CLCD_CAP_5551", CLCD_CAP_5551},
  208798. + {"CLCD_CAP_565", CLCD_CAP_565},
  208799. + {"CLCD_CAP_888", CLCD_CAP_888},
  208800. + {"CLCD_CAP_RGB", CLCD_CAP_RGB},
  208801. + {"CLCD_CAP_BGR", CLCD_CAP_BGR},
  208802. + {"CLCD_CAP_ALL", CLCD_CAP_ALL},
  208803. + { NULL, 0},
  208804. +};
  208805. +
  208806. +u32 parse_setting(struct string_lookup *lookup, const char *name)
  208807. +{
  208808. + int i = 0;
  208809. + while (lookup[i].string != NULL) {
  208810. + if (strcmp(lookup[i].string, name) == 0)
  208811. + return lookup[i].val;
  208812. + ++i;
  208813. + }
  208814. + return -EINVAL;
  208815. +}
  208816. +
  208817. +u32 get_string_lookup(struct device_node *node, const char *name,
  208818. + struct string_lookup *lookup)
  208819. +{
  208820. + const char *string;
  208821. + int count, i, ret = 0;
  208822. +
  208823. + count = of_property_count_strings(node, name);
  208824. + if (count >= 0)
  208825. + for (i = 0; i < count; i++)
  208826. + if (of_property_read_string_index(node, name, i,
  208827. + &string) == 0)
  208828. + ret |= parse_setting(lookup, string);
  208829. + return ret;
  208830. +}
  208831. +
  208832. +int get_val(struct device_node *node, const char *string)
  208833. +{
  208834. + u32 ret = 0;
  208835. +
  208836. + if (of_property_read_u32(node, string, &ret))
  208837. + ret = -1;
  208838. + return ret;
  208839. +}
  208840. +
  208841. +struct clcd_panel *getPanel(struct device_node *node)
  208842. +{
  208843. + static struct clcd_panel panel;
  208844. +
  208845. + panel.mode.refresh = get_val(node, "refresh");
  208846. + panel.mode.xres = get_val(node, "xres");
  208847. + panel.mode.yres = get_val(node, "yres");
  208848. + panel.mode.pixclock = get_val(node, "pixclock");
  208849. + panel.mode.left_margin = get_val(node, "left_margin");
  208850. + panel.mode.right_margin = get_val(node, "right_margin");
  208851. + panel.mode.upper_margin = get_val(node, "upper_margin");
  208852. + panel.mode.lower_margin = get_val(node, "lower_margin");
  208853. + panel.mode.hsync_len = get_val(node, "hsync_len");
  208854. + panel.mode.vsync_len = get_val(node, "vsync_len");
  208855. + panel.mode.sync = get_val(node, "sync");
  208856. + panel.bpp = get_val(node, "bpp");
  208857. + panel.width = (signed short) get_val(node, "width");
  208858. + panel.height = (signed short) get_val(node, "height");
  208859. +
  208860. + panel.mode.vmode = get_string_lookup(node, "vmode", vmode_lookups);
  208861. + panel.tim2 = get_string_lookup(node, "tim2", tim2_lookups);
  208862. + panel.cntl = get_string_lookup(node, "cntl", cntl_lookups);
  208863. + panel.caps = get_string_lookup(node, "caps", caps_lookups);
  208864. +
  208865. + return &panel;
  208866. +}
  208867. +
  208868. +struct clcd_panel *clcdfb_get_panel(const char *name)
  208869. +{
  208870. + struct device_node *node = NULL;
  208871. + const char *mode;
  208872. + struct clcd_panel *panel = NULL;
  208873. +
  208874. + do {
  208875. + node = of_find_compatible_node(node, NULL, "panel");
  208876. + if (node)
  208877. + if (of_property_read_string(node, "mode", &mode) == 0)
  208878. + if (strcmp(mode, name) == 0) {
  208879. + panel = getPanel(node);
  208880. + panel->mode.name = name;
  208881. + }
  208882. + } while (node != NULL);
  208883. +
  208884. + return panel;
  208885. +}
  208886. +
  208887. +#ifdef CONFIG_OF
  208888. +static int clcdfb_dt_init(struct clcd_fb *fb)
  208889. +{
  208890. + int err = 0;
  208891. + struct device_node *node;
  208892. + const char *mode;
  208893. + dma_addr_t dma;
  208894. + u32 use_dma;
  208895. + const __be32 *prop;
  208896. + int len, na, ns;
  208897. + phys_addr_t fb_base, fb_size;
  208898. +
  208899. + node = fb->dev->dev.of_node;
  208900. + if (!node)
  208901. + return -ENODEV;
  208902. +
  208903. + na = of_n_addr_cells(node);
  208904. + ns = of_n_size_cells(node);
  208905. +
  208906. + if (def_mode && strlen(def_mode) > 0) {
  208907. + fb->panel = clcdfb_get_panel(def_mode);
  208908. + if (!fb->panel)
  208909. + printk(KERN_ERR "CLCD: invalid mode specified on the command line (%s)\n", def_mode);
  208910. + }
  208911. +
  208912. + if (!fb->panel) {
  208913. + if (WARN_ON(of_property_read_string(node, "mode", &mode)))
  208914. + return -ENODEV;
  208915. + fb->panel = clcdfb_get_panel(mode);
  208916. + }
  208917. +
  208918. + if (!fb->panel)
  208919. + return -EINVAL;
  208920. + fb->fb.fix.smem_len = fb->panel->mode.xres * fb->panel->mode.yres * 4;
  208921. +
  208922. + fb->board->name = "Device Tree CLCD PL111";
  208923. + fb->board->caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888;
  208924. + fb->board->check = clcdfb_check;
  208925. + fb->board->decode = clcdfb_decode;
  208926. +
  208927. + if (of_property_read_u32(node, "use_dma", &use_dma))
  208928. + use_dma = 0;
  208929. +
  208930. + if (use_dma) {
  208931. + fb->fb.screen_base = clcdfb_dma_alloc(&fb->dev->dev,
  208932. + fb->fb.fix.smem_len,
  208933. + &dma, GFP_KERNEL);
  208934. + if (!fb->fb.screen_base) {
  208935. + pr_err("CLCD: unable to map framebuffer\n");
  208936. + return -ENOMEM;
  208937. + }
  208938. +
  208939. + fb->fb.fix.smem_start = dma;
  208940. + fb->board->mmap = clcdfb_mmap_dma;
  208941. + fb->board->remove = clcdfb_remove_dma;
  208942. + } else {
  208943. + prop = of_get_property(node, "framebuffer", &len);
  208944. + if (WARN_ON(!prop || len < (na + ns) * sizeof(*prop)))
  208945. + return -EINVAL;
  208946. +
  208947. + fb_base = of_read_number(prop, na);
  208948. + fb_size = of_read_number(prop + na, ns);
  208949. +
  208950. + fb->fb.fix.smem_start = fb_base;
  208951. + fb->fb.screen_base = ioremap_wc(fb_base, fb_size);
  208952. + fb->board->mmap = clcdfb_mmap_io;
  208953. + fb->board->remove = clcdfb_remove_io;
  208954. + }
  208955. +
  208956. + return err;
  208957. +}
  208958. +#endif /* CONFIG_OF */
  208959. +
  208960. static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
  208961. {
  208962. struct clcd_board *board = dev_get_platdata(&dev->dev);
  208963. struct clcd_fb *fb;
  208964. int ret;
  208965. - if (!board)
  208966. - return -EINVAL;
  208967. + if (!board) {
  208968. +#ifdef CONFIG_OF
  208969. + if (dev->dev.of_node) {
  208970. + board = kzalloc(sizeof(struct clcd_board), GFP_KERNEL);
  208971. + if (!board)
  208972. + return -ENOMEM;
  208973. + board->setup = clcdfb_dt_init;
  208974. + } else
  208975. +#endif
  208976. + return -EINVAL;
  208977. + }
  208978. ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
  208979. if (ret)
  208980. diff -Nur linux-3.14.14/drivers/video/arm-hdlcd.c linux-imx6-3.14/drivers/video/arm-hdlcd.c
  208981. --- linux-3.14.14/drivers/video/arm-hdlcd.c 1969-12-31 18:00:00.000000000 -0600
  208982. +++ linux-imx6-3.14/drivers/video/arm-hdlcd.c 2014-12-08 00:31:54.824418001 -0600
  208983. @@ -0,0 +1,844 @@
  208984. +/*
  208985. + * drivers/video/arm-hdlcd.c
  208986. + *
  208987. + * Copyright (C) 2011 ARM Limited
  208988. + *
  208989. + * This file is subject to the terms and conditions of the GNU General Public
  208990. + * License. See the file COPYING in the main directory of this archive
  208991. + * for more details.
  208992. + *
  208993. + * ARM HDLCD Controller
  208994. + */
  208995. +
  208996. +#include <linux/module.h>
  208997. +#include <linux/kernel.h>
  208998. +#include <linux/errno.h>
  208999. +#include <linux/string.h>
  209000. +#include <linux/ctype.h>
  209001. +#include <linux/mm.h>
  209002. +#include <linux/delay.h>
  209003. +#include <linux/of.h>
  209004. +#include <linux/fb.h>
  209005. +#include <linux/clk.h>
  209006. +#include <linux/init.h>
  209007. +#include <linux/interrupt.h>
  209008. +#include <linux/ioport.h>
  209009. +#include <linux/dma-mapping.h>
  209010. +#include <linux/platform_device.h>
  209011. +#include <linux/memblock.h>
  209012. +#include <linux/arm-hdlcd.h>
  209013. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  209014. +#include <linux/proc_fs.h>
  209015. +#include <linux/seq_file.h>
  209016. +#endif
  209017. +
  209018. +#include "edid.h"
  209019. +
  209020. +#ifdef CONFIG_SERIAL_AMBA_PCU_UART
  209021. +int get_edid(u8 *msgbuf);
  209022. +#else
  209023. +#endif
  209024. +
  209025. +#define to_hdlcd_device(info) container_of(info, struct hdlcd_device, fb)
  209026. +
  209027. +static struct of_device_id hdlcd_of_matches[] = {
  209028. + { .compatible = "arm,hdlcd" },
  209029. + {},
  209030. +};
  209031. +
  209032. +/* Framebuffer size. */
  209033. +static unsigned long framebuffer_size;
  209034. +
  209035. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  209036. +static unsigned long buffer_underrun_events;
  209037. +static DEFINE_SPINLOCK(hdlcd_underrun_lock);
  209038. +
  209039. +static void hdlcd_underrun_set(unsigned long val)
  209040. +{
  209041. + spin_lock(&hdlcd_underrun_lock);
  209042. + buffer_underrun_events = val;
  209043. + spin_unlock(&hdlcd_underrun_lock);
  209044. +}
  209045. +
  209046. +static unsigned long hdlcd_underrun_get(void)
  209047. +{
  209048. + unsigned long val;
  209049. + spin_lock(&hdlcd_underrun_lock);
  209050. + val = buffer_underrun_events;
  209051. + spin_unlock(&hdlcd_underrun_lock);
  209052. + return val;
  209053. +}
  209054. +
  209055. +#ifdef CONFIG_PROC_FS
  209056. +static int hdlcd_underrun_show(struct seq_file *m, void *v)
  209057. +{
  209058. + unsigned char underrun_string[32];
  209059. + snprintf(underrun_string, 32, "%lu\n", hdlcd_underrun_get());
  209060. + seq_puts(m, underrun_string);
  209061. + return 0;
  209062. +}
  209063. +
  209064. +static int proc_hdlcd_underrun_open(struct inode *inode, struct file *file)
  209065. +{
  209066. + return single_open(file, hdlcd_underrun_show, NULL);
  209067. +}
  209068. +
  209069. +static const struct file_operations proc_hdlcd_underrun_operations = {
  209070. + .open = proc_hdlcd_underrun_open,
  209071. + .read = seq_read,
  209072. + .llseek = seq_lseek,
  209073. + .release = single_release,
  209074. +};
  209075. +
  209076. +static int hdlcd_underrun_init(void)
  209077. +{
  209078. + hdlcd_underrun_set(0);
  209079. + proc_create("hdlcd_underrun", 0, NULL, &proc_hdlcd_underrun_operations);
  209080. + return 0;
  209081. +}
  209082. +static void hdlcd_underrun_close(void)
  209083. +{
  209084. + remove_proc_entry("hdlcd_underrun", NULL);
  209085. +}
  209086. +#else
  209087. +static int hdlcd_underrun_init(void) { return 0; }
  209088. +static void hdlcd_underrun_close(void) { }
  209089. +#endif
  209090. +#endif
  209091. +
  209092. +static char *fb_mode = "1680x1050-32@60\0\0\0\0\0";
  209093. +
  209094. +static struct fb_var_screeninfo cached_var_screeninfo;
  209095. +
  209096. +static struct fb_videomode hdlcd_default_mode = {
  209097. + .refresh = 60,
  209098. + .xres = 1680,
  209099. + .yres = 1050,
  209100. + .pixclock = 8403,
  209101. + .left_margin = 80,
  209102. + .right_margin = 48,
  209103. + .upper_margin = 21,
  209104. + .lower_margin = 3,
  209105. + .hsync_len = 32,
  209106. + .vsync_len = 6,
  209107. + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  209108. + .vmode = FB_VMODE_NONINTERLACED
  209109. +};
  209110. +
  209111. +static inline void hdlcd_enable(struct hdlcd_device *hdlcd)
  209112. +{
  209113. + dev_dbg(hdlcd->dev, "HDLCD: output enabled\n");
  209114. + writel(1, hdlcd->base + HDLCD_REG_COMMAND);
  209115. +}
  209116. +
  209117. +static inline void hdlcd_disable(struct hdlcd_device *hdlcd)
  209118. +{
  209119. + dev_dbg(hdlcd->dev, "HDLCD: output disabled\n");
  209120. + writel(0, hdlcd->base + HDLCD_REG_COMMAND);
  209121. +}
  209122. +
  209123. +static int hdlcd_set_bitfields(struct hdlcd_device *hdlcd,
  209124. + struct fb_var_screeninfo *var)
  209125. +{
  209126. + int ret = 0;
  209127. +
  209128. + memset(&var->transp, 0, sizeof(var->transp));
  209129. + var->red.msb_right = 0;
  209130. + var->green.msb_right = 0;
  209131. + var->blue.msb_right = 0;
  209132. + var->blue.offset = 0;
  209133. +
  209134. + switch (var->bits_per_pixel) {
  209135. + case 8:
  209136. + /* pseudocolor */
  209137. + var->red.length = 8;
  209138. + var->green.length = 8;
  209139. + var->blue.length = 8;
  209140. + break;
  209141. + case 16:
  209142. + /* 565 format */
  209143. + var->red.length = 5;
  209144. + var->green.length = 6;
  209145. + var->blue.length = 5;
  209146. + break;
  209147. + case 32:
  209148. + var->transp.length = 8;
  209149. + case 24:
  209150. + var->red.length = 8;
  209151. + var->green.length = 8;
  209152. + var->blue.length = 8;
  209153. + break;
  209154. + default:
  209155. + ret = -EINVAL;
  209156. + break;
  209157. + }
  209158. +
  209159. + if (!ret) {
  209160. + if(var->bits_per_pixel != 32)
  209161. + {
  209162. + var->green.offset = var->blue.length;
  209163. + var->red.offset = var->green.offset + var->green.length;
  209164. + }
  209165. + else
  209166. + {
  209167. + /* Previously, the byte ordering for 32-bit color was
  209168. + * (msb)<alpha><red><green><blue>(lsb)
  209169. + * but this does not match what android expects and
  209170. + * the colors are odd. Instead, use
  209171. + * <alpha><blue><green><red>
  209172. + * Since we tell fb what we are doing, console
  209173. + * , X and directfb access should work fine.
  209174. + */
  209175. + var->green.offset = var->red.length;
  209176. + var->blue.offset = var->green.offset + var->green.length;
  209177. + var->transp.offset = var->blue.offset + var->blue.length;
  209178. + }
  209179. + }
  209180. +
  209181. + return ret;
  209182. +}
  209183. +
  209184. +static int hdlcd_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  209185. +{
  209186. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  209187. + int bytes_per_pixel = var->bits_per_pixel / 8;
  209188. +
  209189. +#ifdef HDLCD_NO_VIRTUAL_SCREEN
  209190. + var->yres_virtual = var->yres;
  209191. +#else
  209192. + var->yres_virtual = 2 * var->yres;
  209193. +#endif
  209194. +
  209195. + if ((var->xres_virtual * bytes_per_pixel * var->yres_virtual) > hdlcd->fb.fix.smem_len)
  209196. + return -ENOMEM;
  209197. +
  209198. + if (var->xres > HDLCD_MAX_XRES || var->yres > HDLCD_MAX_YRES)
  209199. + return -EINVAL;
  209200. +
  209201. + /* make sure the bitfields are set appropriately */
  209202. + return hdlcd_set_bitfields(hdlcd, var);
  209203. +}
  209204. +
  209205. +/* prototype */
  209206. +static int hdlcd_pan_display(struct fb_var_screeninfo *var,
  209207. + struct fb_info *info);
  209208. +
  209209. +#define WRITE_HDLCD_REG(reg, value) writel((value), hdlcd->base + (reg))
  209210. +#define READ_HDLCD_REG(reg) readl(hdlcd->base + (reg))
  209211. +
  209212. +static int hdlcd_set_par(struct fb_info *info)
  209213. +{
  209214. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  209215. + int bytes_per_pixel = hdlcd->fb.var.bits_per_pixel / 8;
  209216. + int polarities;
  209217. + int old_yoffset;
  209218. +
  209219. + /* check for shortcuts */
  209220. + old_yoffset = cached_var_screeninfo.yoffset;
  209221. + cached_var_screeninfo.yoffset = info->var.yoffset;
  209222. + if (!memcmp(&info->var, &cached_var_screeninfo,
  209223. + sizeof(struct fb_var_screeninfo))) {
  209224. + if(old_yoffset != info->var.yoffset) {
  209225. + /* we only changed yoffset, and we already
  209226. + * already recorded it a couple lines up
  209227. + */
  209228. + hdlcd_pan_display(&info->var, info);
  209229. + }
  209230. + /* or no change */
  209231. + return 0;
  209232. + }
  209233. +
  209234. + hdlcd->fb.fix.line_length = hdlcd->fb.var.xres * bytes_per_pixel;
  209235. +
  209236. + if (hdlcd->fb.var.bits_per_pixel >= 16)
  209237. + hdlcd->fb.fix.visual = FB_VISUAL_TRUECOLOR;
  209238. + else
  209239. + hdlcd->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
  209240. +
  209241. + memcpy(&cached_var_screeninfo, &info->var, sizeof(struct fb_var_screeninfo));
  209242. +
  209243. + polarities = HDLCD_POLARITY_DATAEN |
  209244. +#ifndef CONFIG_ARCH_TUSCAN
  209245. + HDLCD_POLARITY_PIXELCLK |
  209246. +#endif
  209247. + HDLCD_POLARITY_DATA;
  209248. + polarities |= (hdlcd->fb.var.sync & FB_SYNC_HOR_HIGH_ACT) ? HDLCD_POLARITY_HSYNC : 0;
  209249. + polarities |= (hdlcd->fb.var.sync & FB_SYNC_VERT_HIGH_ACT) ? HDLCD_POLARITY_VSYNC : 0;
  209250. +
  209251. + hdlcd_disable(hdlcd);
  209252. +
  209253. + WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_LENGTH, hdlcd->fb.var.xres * bytes_per_pixel);
  209254. + WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_PITCH, hdlcd->fb.var.xres * bytes_per_pixel);
  209255. + WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_COUNT, hdlcd->fb.var.yres - 1);
  209256. + WRITE_HDLCD_REG(HDLCD_REG_V_SYNC, hdlcd->fb.var.vsync_len - 1);
  209257. + WRITE_HDLCD_REG(HDLCD_REG_V_BACK_PORCH, hdlcd->fb.var.upper_margin - 1);
  209258. + WRITE_HDLCD_REG(HDLCD_REG_V_DATA, hdlcd->fb.var.yres - 1);
  209259. + WRITE_HDLCD_REG(HDLCD_REG_V_FRONT_PORCH, hdlcd->fb.var.lower_margin - 1);
  209260. + WRITE_HDLCD_REG(HDLCD_REG_H_SYNC, hdlcd->fb.var.hsync_len - 1);
  209261. + WRITE_HDLCD_REG(HDLCD_REG_H_BACK_PORCH, hdlcd->fb.var.left_margin - 1);
  209262. + WRITE_HDLCD_REG(HDLCD_REG_H_DATA, hdlcd->fb.var.xres - 1);
  209263. + WRITE_HDLCD_REG(HDLCD_REG_H_FRONT_PORCH, hdlcd->fb.var.right_margin - 1);
  209264. + WRITE_HDLCD_REG(HDLCD_REG_POLARITIES, polarities);
  209265. + WRITE_HDLCD_REG(HDLCD_REG_PIXEL_FORMAT, (bytes_per_pixel - 1) << 3);
  209266. +#ifdef HDLCD_RED_DEFAULT_COLOUR
  209267. + WRITE_HDLCD_REG(HDLCD_REG_RED_SELECT, (0x00ff0000 | (hdlcd->fb.var.red.length & 0xf) << 8) \
  209268. + | hdlcd->fb.var.red.offset);
  209269. +#else
  209270. + WRITE_HDLCD_REG(HDLCD_REG_RED_SELECT, ((hdlcd->fb.var.red.length & 0xf) << 8) | hdlcd->fb.var.red.offset);
  209271. +#endif
  209272. + WRITE_HDLCD_REG(HDLCD_REG_GREEN_SELECT, ((hdlcd->fb.var.green.length & 0xf) << 8) | hdlcd->fb.var.green.offset);
  209273. + WRITE_HDLCD_REG(HDLCD_REG_BLUE_SELECT, ((hdlcd->fb.var.blue.length & 0xf) << 8) | hdlcd->fb.var.blue.offset);
  209274. +
  209275. + clk_set_rate(hdlcd->clk, (1000000000 / hdlcd->fb.var.pixclock) * 1000);
  209276. + clk_enable(hdlcd->clk);
  209277. +
  209278. + hdlcd_enable(hdlcd);
  209279. +
  209280. + return 0;
  209281. +}
  209282. +
  209283. +static int hdlcd_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
  209284. + unsigned int blue, unsigned int transp, struct fb_info *info)
  209285. +{
  209286. + if (regno < 16) {
  209287. + u32 *pal = info->pseudo_palette;
  209288. +
  209289. + pal[regno] = ((red >> 8) << info->var.red.offset) |
  209290. + ((green >> 8) << info->var.green.offset) |
  209291. + ((blue >> 8) << info->var.blue.offset);
  209292. + }
  209293. +
  209294. + return 0;
  209295. +}
  209296. +
  209297. +static irqreturn_t hdlcd_irq(int irq, void *data)
  209298. +{
  209299. + struct hdlcd_device *hdlcd = data;
  209300. + unsigned long irq_mask, irq_status;
  209301. +
  209302. + irq_mask = READ_HDLCD_REG(HDLCD_REG_INT_MASK);
  209303. + irq_status = READ_HDLCD_REG(HDLCD_REG_INT_STATUS);
  209304. +
  209305. + /* acknowledge interrupt(s) */
  209306. + WRITE_HDLCD_REG(HDLCD_REG_INT_CLEAR, irq_status);
  209307. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  209308. + if (irq_status & HDLCD_INTERRUPT_UNDERRUN) {
  209309. + /* increment the count */
  209310. + hdlcd_underrun_set(hdlcd_underrun_get() + 1);
  209311. + }
  209312. +#endif
  209313. + if (irq_status & HDLCD_INTERRUPT_VSYNC) {
  209314. + /* disable future VSYNC interrupts */
  209315. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, irq_mask & ~HDLCD_INTERRUPT_VSYNC);
  209316. +
  209317. + complete(&hdlcd->vsync_completion);
  209318. + }
  209319. +
  209320. + return IRQ_HANDLED;
  209321. +}
  209322. +
  209323. +static int hdlcd_wait_for_vsync(struct fb_info *info)
  209324. +{
  209325. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  209326. + unsigned long irq_mask;
  209327. + int err;
  209328. +
  209329. + /* enable VSYNC interrupt */
  209330. + irq_mask = READ_HDLCD_REG(HDLCD_REG_INT_MASK);
  209331. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, irq_mask | HDLCD_INTERRUPT_VSYNC);
  209332. +
  209333. + err = wait_for_completion_interruptible_timeout(&hdlcd->vsync_completion,
  209334. + msecs_to_jiffies(100));
  209335. +
  209336. + if (!err)
  209337. + return -ETIMEDOUT;
  209338. +
  209339. + return 0;
  209340. +}
  209341. +
  209342. +static int hdlcd_blank(int blank_mode, struct fb_info *info)
  209343. +{
  209344. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  209345. +
  209346. + switch (blank_mode) {
  209347. + case FB_BLANK_POWERDOWN:
  209348. + clk_disable(hdlcd->clk);
  209349. + case FB_BLANK_NORMAL:
  209350. + hdlcd_disable(hdlcd);
  209351. + break;
  209352. + case FB_BLANK_UNBLANK:
  209353. + clk_enable(hdlcd->clk);
  209354. + hdlcd_enable(hdlcd);
  209355. + break;
  209356. + case FB_BLANK_VSYNC_SUSPEND:
  209357. + case FB_BLANK_HSYNC_SUSPEND:
  209358. + default:
  209359. + return 1;
  209360. + }
  209361. +
  209362. + return 0;
  209363. +}
  209364. +
  209365. +static void hdlcd_mmap_open(struct vm_area_struct *vma)
  209366. +{
  209367. +}
  209368. +
  209369. +static void hdlcd_mmap_close(struct vm_area_struct *vma)
  209370. +{
  209371. +}
  209372. +
  209373. +static struct vm_operations_struct hdlcd_mmap_ops = {
  209374. + .open = hdlcd_mmap_open,
  209375. + .close = hdlcd_mmap_close,
  209376. +};
  209377. +
  209378. +static int hdlcd_mmap(struct fb_info *info, struct vm_area_struct *vma)
  209379. +{
  209380. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  209381. + unsigned long off;
  209382. + unsigned long start;
  209383. + unsigned long len = hdlcd->fb.fix.smem_len;
  209384. +
  209385. + if (vma->vm_end - vma->vm_start == 0)
  209386. + return 0;
  209387. + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
  209388. + return -EINVAL;
  209389. +
  209390. + off = vma->vm_pgoff << PAGE_SHIFT;
  209391. + if ((off >= len) || (vma->vm_end - vma->vm_start + off) > len)
  209392. + return -EINVAL;
  209393. +
  209394. + start = hdlcd->fb.fix.smem_start;
  209395. + off += start;
  209396. +
  209397. + vma->vm_pgoff = off >> PAGE_SHIFT;
  209398. + vma->vm_flags |= VM_IO;
  209399. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  209400. + vma->vm_ops = &hdlcd_mmap_ops;
  209401. + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
  209402. + vma->vm_end - vma->vm_start,
  209403. + vma->vm_page_prot))
  209404. + return -EAGAIN;
  209405. +
  209406. + return 0;
  209407. +}
  209408. +
  209409. +static int hdlcd_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
  209410. +{
  209411. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  209412. +
  209413. + hdlcd->fb.var.yoffset = var->yoffset;
  209414. + WRITE_HDLCD_REG(HDLCD_REG_FB_BASE, hdlcd->fb.fix.smem_start +
  209415. + (var->yoffset * hdlcd->fb.fix.line_length));
  209416. +
  209417. + hdlcd_wait_for_vsync(info);
  209418. +
  209419. + return 0;
  209420. +}
  209421. +
  209422. +static int hdlcd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  209423. +{
  209424. + int err;
  209425. +
  209426. + switch (cmd) {
  209427. + case FBIO_WAITFORVSYNC:
  209428. + err = hdlcd_wait_for_vsync(info);
  209429. + break;
  209430. + default:
  209431. + err = -ENOIOCTLCMD;
  209432. + break;
  209433. + }
  209434. +
  209435. + return err;
  209436. +}
  209437. +
  209438. +static struct fb_ops hdlcd_ops = {
  209439. + .owner = THIS_MODULE,
  209440. + .fb_check_var = hdlcd_check_var,
  209441. + .fb_set_par = hdlcd_set_par,
  209442. + .fb_setcolreg = hdlcd_setcolreg,
  209443. + .fb_blank = hdlcd_blank,
  209444. + .fb_fillrect = cfb_fillrect,
  209445. + .fb_copyarea = cfb_copyarea,
  209446. + .fb_imageblit = cfb_imageblit,
  209447. + .fb_mmap = hdlcd_mmap,
  209448. + .fb_pan_display = hdlcd_pan_display,
  209449. + .fb_ioctl = hdlcd_ioctl,
  209450. + .fb_compat_ioctl = hdlcd_ioctl
  209451. +};
  209452. +
  209453. +static int hdlcd_setup(struct hdlcd_device *hdlcd)
  209454. +{
  209455. + u32 version;
  209456. + int err = -EFAULT;
  209457. +
  209458. + hdlcd->fb.device = hdlcd->dev;
  209459. +
  209460. + hdlcd->clk = clk_get(hdlcd->dev, NULL);
  209461. + if (IS_ERR(hdlcd->clk)) {
  209462. + dev_err(hdlcd->dev, "HDLCD: unable to find clock data\n");
  209463. + return PTR_ERR(hdlcd->clk);
  209464. + }
  209465. +
  209466. + err = clk_prepare(hdlcd->clk);
  209467. + if (err)
  209468. + goto clk_prepare_err;
  209469. +
  209470. + hdlcd->base = ioremap_nocache(hdlcd->fb.fix.mmio_start, hdlcd->fb.fix.mmio_len);
  209471. + if (!hdlcd->base) {
  209472. + dev_err(hdlcd->dev, "HDLCD: unable to map registers\n");
  209473. + goto remap_err;
  209474. + }
  209475. +
  209476. + hdlcd->fb.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
  209477. + if (!hdlcd->fb.pseudo_palette) {
  209478. + dev_err(hdlcd->dev, "HDLCD: unable to allocate pseudo_palette memory\n");
  209479. + err = -ENOMEM;
  209480. + goto kmalloc_err;
  209481. + }
  209482. +
  209483. + version = readl(hdlcd->base + HDLCD_REG_VERSION);
  209484. + if ((version & HDLCD_PRODUCT_MASK) != HDLCD_PRODUCT_ID) {
  209485. + dev_err(hdlcd->dev, "HDLCD: unknown product id: 0x%x\n", version);
  209486. + err = -EINVAL;
  209487. + goto kmalloc_err;
  209488. + }
  209489. + dev_info(hdlcd->dev, "HDLCD: found ARM HDLCD version r%dp%d\n",
  209490. + (version & HDLCD_VERSION_MAJOR_MASK) >> 8,
  209491. + version & HDLCD_VERSION_MINOR_MASK);
  209492. +
  209493. + strcpy(hdlcd->fb.fix.id, "hdlcd");
  209494. + hdlcd->fb.fbops = &hdlcd_ops;
  209495. + hdlcd->fb.flags = FBINFO_FLAG_DEFAULT/* | FBINFO_VIRTFB*/;
  209496. +
  209497. + hdlcd->fb.fix.type = FB_TYPE_PACKED_PIXELS;
  209498. + hdlcd->fb.fix.type_aux = 0;
  209499. + hdlcd->fb.fix.xpanstep = 0;
  209500. + hdlcd->fb.fix.ypanstep = 1;
  209501. + hdlcd->fb.fix.ywrapstep = 0;
  209502. + hdlcd->fb.fix.accel = FB_ACCEL_NONE;
  209503. +
  209504. + hdlcd->fb.var.nonstd = 0;
  209505. + hdlcd->fb.var.activate = FB_ACTIVATE_NOW;
  209506. + hdlcd->fb.var.height = -1;
  209507. + hdlcd->fb.var.width = -1;
  209508. + hdlcd->fb.var.accel_flags = 0;
  209509. +
  209510. + init_completion(&hdlcd->vsync_completion);
  209511. +
  209512. + if (hdlcd->edid) {
  209513. + /* build modedb from EDID */
  209514. + fb_edid_to_monspecs(hdlcd->edid, &hdlcd->fb.monspecs);
  209515. + fb_videomode_to_modelist(hdlcd->fb.monspecs.modedb,
  209516. + hdlcd->fb.monspecs.modedb_len,
  209517. + &hdlcd->fb.modelist);
  209518. + fb_find_mode(&hdlcd->fb.var, &hdlcd->fb, fb_mode,
  209519. + hdlcd->fb.monspecs.modedb,
  209520. + hdlcd->fb.monspecs.modedb_len,
  209521. + &hdlcd_default_mode, 32);
  209522. + } else {
  209523. + hdlcd->fb.monspecs.hfmin = 0;
  209524. + hdlcd->fb.monspecs.hfmax = 100000;
  209525. + hdlcd->fb.monspecs.vfmin = 0;
  209526. + hdlcd->fb.monspecs.vfmax = 400;
  209527. + hdlcd->fb.monspecs.dclkmin = 1000000;
  209528. + hdlcd->fb.monspecs.dclkmax = 100000000;
  209529. + fb_find_mode(&hdlcd->fb.var, &hdlcd->fb, fb_mode, NULL, 0, &hdlcd_default_mode, 32);
  209530. + }
  209531. +
  209532. + dev_info(hdlcd->dev, "using %dx%d-%d@%d mode\n", hdlcd->fb.var.xres,
  209533. + hdlcd->fb.var.yres, hdlcd->fb.var.bits_per_pixel,
  209534. + hdlcd->fb.mode ? hdlcd->fb.mode->refresh : 60);
  209535. + hdlcd->fb.var.xres_virtual = hdlcd->fb.var.xres;
  209536. +#ifdef HDLCD_NO_VIRTUAL_SCREEN
  209537. + hdlcd->fb.var.yres_virtual = hdlcd->fb.var.yres;
  209538. +#else
  209539. + hdlcd->fb.var.yres_virtual = hdlcd->fb.var.yres * 2;
  209540. +#endif
  209541. +
  209542. + /* initialise and set the palette */
  209543. + if (fb_alloc_cmap(&hdlcd->fb.cmap, NR_PALETTE, 0)) {
  209544. + dev_err(hdlcd->dev, "failed to allocate cmap memory\n");
  209545. + err = -ENOMEM;
  209546. + goto setup_err;
  209547. + }
  209548. + fb_set_cmap(&hdlcd->fb.cmap, &hdlcd->fb);
  209549. +
  209550. + /* Allow max number of outstanding requests with the largest beat burst */
  209551. + WRITE_HDLCD_REG(HDLCD_REG_BUS_OPTIONS, HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);
  209552. + /* Set the framebuffer base to start of allocated memory */
  209553. + WRITE_HDLCD_REG(HDLCD_REG_FB_BASE, hdlcd->fb.fix.smem_start);
  209554. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  209555. + /* turn on underrun interrupt for counting */
  209556. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, HDLCD_INTERRUPT_UNDERRUN);
  209557. +#else
  209558. + /* Ensure interrupts are disabled */
  209559. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, 0);
  209560. +#endif
  209561. + fb_set_var(&hdlcd->fb, &hdlcd->fb.var);
  209562. +
  209563. + if (!register_framebuffer(&hdlcd->fb)) {
  209564. + return 0;
  209565. + }
  209566. +
  209567. + dev_err(hdlcd->dev, "HDLCD: cannot register framebuffer\n");
  209568. +
  209569. + fb_dealloc_cmap(&hdlcd->fb.cmap);
  209570. +setup_err:
  209571. + iounmap(hdlcd->base);
  209572. +kmalloc_err:
  209573. + kfree(hdlcd->fb.pseudo_palette);
  209574. +remap_err:
  209575. + clk_unprepare(hdlcd->clk);
  209576. +clk_prepare_err:
  209577. + clk_put(hdlcd->clk);
  209578. + return err;
  209579. +}
  209580. +
  209581. +static inline unsigned char atohex(u8 data)
  209582. +{
  209583. + if (!isxdigit(data))
  209584. + return 0;
  209585. + /* truncate the upper nibble and add 9 to non-digit values */
  209586. + return (data > 0x39) ? ((data & 0xf) + 9) : (data & 0xf);
  209587. +}
  209588. +
  209589. +/* EDID data is passed from devicetree in a literal string that can contain spaces and
  209590. + the hexadecimal dump of the data */
  209591. +static int parse_edid_data(struct hdlcd_device *hdlcd, const u8 *edid_data, int data_len)
  209592. +{
  209593. + int i, j;
  209594. +
  209595. + if (!edid_data)
  209596. + return -EINVAL;
  209597. +
  209598. + hdlcd->edid = kzalloc(EDID_LENGTH, GFP_KERNEL);
  209599. + if (!hdlcd->edid)
  209600. + return -ENOMEM;
  209601. +
  209602. + for (i = 0, j = 0; i < data_len; i++) {
  209603. + if (isspace(edid_data[i]))
  209604. + continue;
  209605. + hdlcd->edid[j++] = atohex(edid_data[i]);
  209606. + if (j >= EDID_LENGTH)
  209607. + break;
  209608. + }
  209609. +
  209610. + if (j < EDID_LENGTH) {
  209611. + kfree(hdlcd->edid);
  209612. + hdlcd->edid = NULL;
  209613. + return -EINVAL;
  209614. + }
  209615. +
  209616. + return 0;
  209617. +}
  209618. +
  209619. +static int hdlcd_probe(struct platform_device *pdev)
  209620. +{
  209621. + int err = 0, i;
  209622. + struct hdlcd_device *hdlcd;
  209623. + struct resource *mem;
  209624. +#ifdef CONFIG_OF
  209625. + struct device_node *of_node;
  209626. +#endif
  209627. +
  209628. + memset(&cached_var_screeninfo, 0, sizeof(struct fb_var_screeninfo));
  209629. +
  209630. + dev_dbg(&pdev->dev, "HDLCD: probing\n");
  209631. +
  209632. + hdlcd = kzalloc(sizeof(*hdlcd), GFP_KERNEL);
  209633. + if (!hdlcd)
  209634. + return -ENOMEM;
  209635. +
  209636. +#ifdef CONFIG_OF
  209637. + of_node = pdev->dev.of_node;
  209638. + if (of_node) {
  209639. + int len;
  209640. + const u8 *edid;
  209641. + const __be32 *prop = of_get_property(of_node, "mode", &len);
  209642. + if (prop)
  209643. + strncpy(fb_mode, (char *)prop, len);
  209644. + prop = of_get_property(of_node, "framebuffer", &len);
  209645. + if (prop) {
  209646. + hdlcd->fb.fix.smem_start = of_read_ulong(prop,
  209647. + of_n_addr_cells(of_node));
  209648. + prop += of_n_addr_cells(of_node);
  209649. + framebuffer_size = of_read_ulong(prop,
  209650. + of_n_size_cells(of_node));
  209651. + if (framebuffer_size > HDLCD_MAX_FRAMEBUFFER_SIZE)
  209652. + framebuffer_size = HDLCD_MAX_FRAMEBUFFER_SIZE;
  209653. + dev_dbg(&pdev->dev, "HDLCD: phys_addr = 0x%lx, size = 0x%lx\n",
  209654. + hdlcd->fb.fix.smem_start, framebuffer_size);
  209655. + }
  209656. + edid = of_get_property(of_node, "edid", &len);
  209657. + if (edid) {
  209658. + err = parse_edid_data(hdlcd, edid, len);
  209659. +#ifdef CONFIG_SERIAL_AMBA_PCU_UART
  209660. + } else {
  209661. + /* ask the firmware to fetch the EDID */
  209662. + dev_dbg(&pdev->dev, "HDLCD: Requesting EDID data\n");
  209663. + hdlcd->edid = kzalloc(EDID_LENGTH, GFP_KERNEL);
  209664. + if (!hdlcd->edid)
  209665. + return -ENOMEM;
  209666. + err = get_edid(hdlcd->edid);
  209667. +#endif /* CONFIG_SERIAL_AMBA_PCU_UART */
  209668. + }
  209669. + if (err)
  209670. + dev_info(&pdev->dev, "HDLCD: Failed to parse EDID data\n");
  209671. + }
  209672. +#endif /* CONFIG_OF */
  209673. +
  209674. + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  209675. + if (!mem) {
  209676. + dev_err(&pdev->dev, "HDLCD: cannot get platform resources\n");
  209677. + err = -EINVAL;
  209678. + goto resource_err;
  209679. + }
  209680. +
  209681. + i = platform_get_irq(pdev, 0);
  209682. + if (i < 0) {
  209683. + dev_err(&pdev->dev, "HDLCD: no irq defined for vsync\n");
  209684. + err = -ENOENT;
  209685. + goto resource_err;
  209686. + } else {
  209687. + err = request_irq(i, hdlcd_irq, 0, dev_name(&pdev->dev), hdlcd);
  209688. + if (err) {
  209689. + dev_err(&pdev->dev, "HDLCD: unable to request irq\n");
  209690. + goto resource_err;
  209691. + }
  209692. + hdlcd->irq = i;
  209693. + }
  209694. +
  209695. + if (!request_mem_region(mem->start, resource_size(mem), dev_name(&pdev->dev))) {
  209696. + err = -ENXIO;
  209697. + goto request_err;
  209698. + }
  209699. +
  209700. + if (!hdlcd->fb.fix.smem_start) {
  209701. + dev_err(&pdev->dev, "platform did not allocate frame buffer memory\n");
  209702. + err = -ENOMEM;
  209703. + goto memalloc_err;
  209704. + }
  209705. + hdlcd->fb.screen_base = ioremap_wc(hdlcd->fb.fix.smem_start, framebuffer_size);
  209706. + if (!hdlcd->fb.screen_base) {
  209707. + dev_err(&pdev->dev, "unable to ioremap framebuffer\n");
  209708. + err = -ENOMEM;
  209709. + goto probe_err;
  209710. + }
  209711. +
  209712. + hdlcd->fb.screen_size = framebuffer_size;
  209713. + hdlcd->fb.fix.smem_len = framebuffer_size;
  209714. + hdlcd->fb.fix.mmio_start = mem->start;
  209715. + hdlcd->fb.fix.mmio_len = resource_size(mem);
  209716. +
  209717. + /* Clear the framebuffer */
  209718. + memset(hdlcd->fb.screen_base, 0, framebuffer_size);
  209719. +
  209720. + hdlcd->dev = &pdev->dev;
  209721. +
  209722. + dev_dbg(&pdev->dev, "HDLCD: framebuffer virt base %p, phys base 0x%lX\n",
  209723. + hdlcd->fb.screen_base, (unsigned long)hdlcd->fb.fix.smem_start);
  209724. +
  209725. + err = hdlcd_setup(hdlcd);
  209726. +
  209727. + if (err)
  209728. + goto probe_err;
  209729. +
  209730. + platform_set_drvdata(pdev, hdlcd);
  209731. + return 0;
  209732. +
  209733. +probe_err:
  209734. + iounmap(hdlcd->fb.screen_base);
  209735. + memblock_free(hdlcd->fb.fix.smem_start, hdlcd->fb.fix.smem_start);
  209736. +
  209737. +memalloc_err:
  209738. + release_mem_region(mem->start, resource_size(mem));
  209739. +
  209740. +request_err:
  209741. + free_irq(hdlcd->irq, hdlcd);
  209742. +
  209743. +resource_err:
  209744. + kfree(hdlcd);
  209745. +
  209746. + return err;
  209747. +}
  209748. +
  209749. +static int hdlcd_remove(struct platform_device *pdev)
  209750. +{
  209751. + struct hdlcd_device *hdlcd = platform_get_drvdata(pdev);
  209752. +
  209753. + clk_disable(hdlcd->clk);
  209754. + clk_unprepare(hdlcd->clk);
  209755. + clk_put(hdlcd->clk);
  209756. +
  209757. + /* unmap memory */
  209758. + iounmap(hdlcd->fb.screen_base);
  209759. + iounmap(hdlcd->base);
  209760. +
  209761. + /* deallocate fb memory */
  209762. + fb_dealloc_cmap(&hdlcd->fb.cmap);
  209763. + kfree(hdlcd->fb.pseudo_palette);
  209764. + memblock_free(hdlcd->fb.fix.smem_start, hdlcd->fb.fix.smem_start);
  209765. + release_mem_region(hdlcd->fb.fix.mmio_start, hdlcd->fb.fix.mmio_len);
  209766. +
  209767. + free_irq(hdlcd->irq, NULL);
  209768. + kfree(hdlcd);
  209769. +
  209770. + return 0;
  209771. +}
  209772. +
  209773. +#ifdef CONFIG_PM
  209774. +static int hdlcd_suspend(struct platform_device *pdev, pm_message_t state)
  209775. +{
  209776. + /* not implemented yet */
  209777. + return 0;
  209778. +}
  209779. +
  209780. +static int hdlcd_resume(struct platform_device *pdev)
  209781. +{
  209782. + /* not implemented yet */
  209783. + return 0;
  209784. +}
  209785. +#else
  209786. +#define hdlcd_suspend NULL
  209787. +#define hdlcd_resume NULL
  209788. +#endif
  209789. +
  209790. +static struct platform_driver hdlcd_driver = {
  209791. + .probe = hdlcd_probe,
  209792. + .remove = hdlcd_remove,
  209793. + .suspend = hdlcd_suspend,
  209794. + .resume = hdlcd_resume,
  209795. + .driver = {
  209796. + .name = "hdlcd",
  209797. + .owner = THIS_MODULE,
  209798. + .of_match_table = hdlcd_of_matches,
  209799. + },
  209800. +};
  209801. +
  209802. +static int __init hdlcd_init(void)
  209803. +{
  209804. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  209805. + int err = platform_driver_register(&hdlcd_driver);
  209806. + if (!err)
  209807. + hdlcd_underrun_init();
  209808. + return err;
  209809. +#else
  209810. + return platform_driver_register(&hdlcd_driver);
  209811. +#endif
  209812. +}
  209813. +
  209814. +void __exit hdlcd_exit(void)
  209815. +{
  209816. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  209817. + hdlcd_underrun_close();
  209818. +#endif
  209819. + platform_driver_unregister(&hdlcd_driver);
  209820. +}
  209821. +
  209822. +module_init(hdlcd_init);
  209823. +module_exit(hdlcd_exit);
  209824. +
  209825. +MODULE_AUTHOR("Liviu Dudau");
  209826. +MODULE_DESCRIPTION("ARM HDLCD core driver");
  209827. +MODULE_LICENSE("GPL v2");
  209828. diff -Nur linux-3.14.14/drivers/video/backlight/backlight.c linux-imx6-3.14/drivers/video/backlight/backlight.c
  209829. --- linux-3.14.14/drivers/video/backlight/backlight.c 2014-07-28 10:07:25.000000000 -0500
  209830. +++ linux-imx6-3.14/drivers/video/backlight/backlight.c 2014-12-08 00:31:54.828418001 -0600
  209831. @@ -41,6 +41,8 @@
  209832. {
  209833. struct backlight_device *bd;
  209834. struct fb_event *evdata = data;
  209835. + int node = evdata->info->node;
  209836. + int fb_blank = 0;
  209837. /* If we aren't interested in this event, skip it immediately ... */
  209838. if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK)
  209839. @@ -51,12 +53,24 @@
  209840. if (bd->ops)
  209841. if (!bd->ops->check_fb ||
  209842. bd->ops->check_fb(bd, evdata->info)) {
  209843. - bd->props.fb_blank = *(int *)evdata->data;
  209844. - if (bd->props.fb_blank == FB_BLANK_UNBLANK)
  209845. - bd->props.state &= ~BL_CORE_FBBLANK;
  209846. - else
  209847. - bd->props.state |= BL_CORE_FBBLANK;
  209848. - backlight_update_status(bd);
  209849. + fb_blank = *(int *)evdata->data;
  209850. + if (fb_blank == FB_BLANK_UNBLANK &&
  209851. + !bd->fb_bl_on[node]) {
  209852. + bd->fb_bl_on[node] = true;
  209853. + if (!bd->use_count++) {
  209854. + bd->props.state &= ~BL_CORE_FBBLANK;
  209855. + bd->props.fb_blank = FB_BLANK_UNBLANK;
  209856. + backlight_update_status(bd);
  209857. + }
  209858. + } else if (fb_blank != FB_BLANK_UNBLANK &&
  209859. + bd->fb_bl_on[node]) {
  209860. + bd->fb_bl_on[node] = false;
  209861. + if (!(--bd->use_count)) {
  209862. + bd->props.state |= BL_CORE_FBBLANK;
  209863. + bd->props.fb_blank = FB_BLANK_POWERDOWN;
  209864. + backlight_update_status(bd);
  209865. + }
  209866. + }
  209867. }
  209868. mutex_unlock(&bd->ops_lock);
  209869. return 0;
  209870. diff -Nur linux-3.14.14/drivers/video/Kconfig linux-imx6-3.14/drivers/video/Kconfig
  209871. --- linux-3.14.14/drivers/video/Kconfig 2014-07-28 10:07:25.000000000 -0500
  209872. +++ linux-imx6-3.14/drivers/video/Kconfig 2014-12-08 00:31:54.820418001 -0600
  209873. @@ -39,6 +39,11 @@
  209874. config HDMI
  209875. bool
  209876. +config VEXPRESS_DVI_CONTROL
  209877. + bool "Versatile Express DVI control"
  209878. + depends on FB && VEXPRESS_CONFIG
  209879. + default y
  209880. +
  209881. menuconfig FB
  209882. tristate "Support for frame buffer devices"
  209883. ---help---
  209884. @@ -327,6 +332,21 @@
  209885. here and read <file:Documentation/kbuild/modules.txt>. The module
  209886. will be called amba-clcd.
  209887. +config FB_ARMHDLCD
  209888. + tristate "ARM High Definition LCD support"
  209889. + depends on FB && ARM
  209890. + select FB_CFB_FILLRECT
  209891. + select FB_CFB_COPYAREA
  209892. + select FB_CFB_IMAGEBLIT
  209893. + help
  209894. + This framebuffer device driver is for the ARM High Definition
  209895. + Colour LCD controller.
  209896. +
  209897. + If you want to compile this as a module (=code which can be
  209898. + inserted into and removed from the running kernel), say M
  209899. + here and read <file:Documentation/kbuild/modules.txt>. The module
  209900. + will be called arm-hdlcd.
  209901. +
  209902. config FB_ACORN
  209903. bool "Acorn VIDC support"
  209904. depends on (FB = y) && ARM && ARCH_ACORN
  209905. @@ -2491,6 +2511,10 @@
  209906. source "drivers/video/mmp/Kconfig"
  209907. source "drivers/video/backlight/Kconfig"
  209908. +if ARCH_MXC
  209909. +source "drivers/video/mxc/Kconfig"
  209910. +endif
  209911. +
  209912. if VT
  209913. source "drivers/video/console/Kconfig"
  209914. endif
  209915. diff -Nur linux-3.14.14/drivers/video/Makefile linux-imx6-3.14/drivers/video/Makefile
  209916. --- linux-3.14.14/drivers/video/Makefile 2014-07-28 10:07:25.000000000 -0500
  209917. +++ linux-imx6-3.14/drivers/video/Makefile 2014-12-08 00:31:54.820418001 -0600
  209918. @@ -53,6 +53,7 @@
  209919. obj-$(CONFIG_FB_SAVAGE) += savage/
  209920. obj-$(CONFIG_FB_GEODE) += geode/
  209921. obj-$(CONFIG_FB_MBX) += mbx/
  209922. +obj-$(CONFIG_FB_MXC) += mxc/
  209923. obj-$(CONFIG_FB_NEOMAGIC) += neofb.o
  209924. obj-$(CONFIG_FB_3DFX) += tdfxfb.o
  209925. obj-$(CONFIG_FB_CONTROL) += controlfb.o
  209926. @@ -99,6 +100,7 @@
  209927. obj-$(CONFIG_FB_PVR2) += pvr2fb.o
  209928. obj-$(CONFIG_FB_VOODOO1) += sstfb.o
  209929. obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
  209930. +obj-$(CONFIG_FB_ARMHDLCD) += arm-hdlcd.o
  209931. obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
  209932. obj-$(CONFIG_FB_68328) += 68328fb.o
  209933. obj-$(CONFIG_FB_GBE) += gbefb.o
  209934. @@ -178,3 +180,6 @@
  209935. ifeq ($(CONFIG_OF),y)
  209936. obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o
  209937. endif
  209938. +
  209939. +# platform specific output drivers
  209940. +obj-$(CONFIG_VEXPRESS_DVI_CONTROL) += vexpress-dvi.o
  209941. diff -Nur linux-3.14.14/drivers/video/mxc/Kconfig linux-imx6-3.14/drivers/video/mxc/Kconfig
  209942. --- linux-3.14.14/drivers/video/mxc/Kconfig 1969-12-31 18:00:00.000000000 -0600
  209943. +++ linux-imx6-3.14/drivers/video/mxc/Kconfig 2014-12-08 00:31:54.860418001 -0600
  209944. @@ -0,0 +1,48 @@
  209945. +config FB_MXC
  209946. + tristate "MXC Framebuffer support"
  209947. + depends on FB
  209948. + select FB_CFB_FILLRECT
  209949. + select FB_CFB_COPYAREA
  209950. + select FB_CFB_IMAGEBLIT
  209951. + select FB_MODE_HELPERS
  209952. + default y
  209953. + help
  209954. + This is a framebuffer device for the MXC LCD Controller.
  209955. + See <http://www.linux-fbdev.org/> for information on framebuffer
  209956. + devices.
  209957. +
  209958. + If you plan to use the LCD display with your MXC system, say
  209959. + Y here.
  209960. +
  209961. +config FB_MXC_SYNC_PANEL
  209962. + depends on FB_MXC
  209963. + tristate "Synchronous Panel Framebuffer"
  209964. +
  209965. +config FB_MXC_LDB
  209966. + tristate "MXC LDB"
  209967. + depends on FB_MXC_SYNC_PANEL
  209968. + depends on MXC_IPU_V3
  209969. +
  209970. +config FB_MXC_MIPI_DSI
  209971. + tristate "MXC MIPI_DSI"
  209972. + depends on FB_MXC_SYNC_PANEL
  209973. + depends on MXC_IPU_V3
  209974. +
  209975. +config FB_MXC_TRULY_WVGA_SYNC_PANEL
  209976. + tristate "TRULY WVGA Panel"
  209977. + depends on FB_MXC_SYNC_PANEL
  209978. + depends on FB_MXC_MIPI_DSI
  209979. +
  209980. +config FB_MXC_HDMI
  209981. + depends on FB_MXC_SYNC_PANEL
  209982. + depends on MXC_IPU_V3
  209983. + depends on I2C
  209984. + tristate "MXC HDMI driver support"
  209985. + select MFD_MXC_HDMI
  209986. + help
  209987. + Driver for the on-chip MXC HDMI controller.
  209988. +
  209989. +config FB_MXC_EDID
  209990. + depends on FB_MXC && I2C
  209991. + tristate "MXC EDID support"
  209992. + default y
  209993. diff -Nur linux-3.14.14/drivers/video/mxc/ldb.c linux-imx6-3.14/drivers/video/mxc/ldb.c
  209994. --- linux-3.14.14/drivers/video/mxc/ldb.c 1969-12-31 18:00:00.000000000 -0600
  209995. +++ linux-imx6-3.14/drivers/video/mxc/ldb.c 2014-12-08 00:31:54.860418001 -0600
  209996. @@ -0,0 +1,1036 @@
  209997. +/*
  209998. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  209999. + */
  210000. +
  210001. +/*
  210002. + * This program is free software; you can redistribute it and/or modify
  210003. + * it under the terms of the GNU General Public License as published by
  210004. + * the Free Software Foundation; either version 2 of the License, or
  210005. + * (at your option) any later version.
  210006. +
  210007. + * This program is distributed in the hope that it will be useful,
  210008. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  210009. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  210010. + * GNU General Public License for more details.
  210011. +
  210012. + * You should have received a copy of the GNU General Public License along
  210013. + * with this program; if not, write to the Free Software Foundation, Inc.,
  210014. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  210015. + */
  210016. +
  210017. +/*!
  210018. + * @file mxc_ldb.c
  210019. + *
  210020. + * @brief This file contains the LDB driver device interface and fops
  210021. + * functions.
  210022. + */
  210023. +#include <linux/types.h>
  210024. +#include <linux/init.h>
  210025. +#include <linux/module.h>
  210026. +#include <linux/platform_device.h>
  210027. +#include <linux/err.h>
  210028. +#include <linux/clk.h>
  210029. +#include <linux/console.h>
  210030. +#include <linux/io.h>
  210031. +#include <linux/ipu.h>
  210032. +#include <linux/mxcfb.h>
  210033. +#include <linux/regulator/consumer.h>
  210034. +#include <linux/spinlock.h>
  210035. +#include <linux/of_device.h>
  210036. +#include <linux/mod_devicetable.h>
  210037. +#include "mxc_dispdrv.h"
  210038. +
  210039. +#define DISPDRV_LDB "ldb"
  210040. +
  210041. +#define LDB_BGREF_RMODE_MASK 0x00008000
  210042. +#define LDB_BGREF_RMODE_INT 0x00008000
  210043. +#define LDB_BGREF_RMODE_EXT 0x0
  210044. +
  210045. +#define LDB_DI1_VS_POL_MASK 0x00000400
  210046. +#define LDB_DI1_VS_POL_ACT_LOW 0x00000400
  210047. +#define LDB_DI1_VS_POL_ACT_HIGH 0x0
  210048. +#define LDB_DI0_VS_POL_MASK 0x00000200
  210049. +#define LDB_DI0_VS_POL_ACT_LOW 0x00000200
  210050. +#define LDB_DI0_VS_POL_ACT_HIGH 0x0
  210051. +
  210052. +#define LDB_BIT_MAP_CH1_MASK 0x00000100
  210053. +#define LDB_BIT_MAP_CH1_JEIDA 0x00000100
  210054. +#define LDB_BIT_MAP_CH1_SPWG 0x0
  210055. +#define LDB_BIT_MAP_CH0_MASK 0x00000040
  210056. +#define LDB_BIT_MAP_CH0_JEIDA 0x00000040
  210057. +#define LDB_BIT_MAP_CH0_SPWG 0x0
  210058. +
  210059. +#define LDB_DATA_WIDTH_CH1_MASK 0x00000080
  210060. +#define LDB_DATA_WIDTH_CH1_24 0x00000080
  210061. +#define LDB_DATA_WIDTH_CH1_18 0x0
  210062. +#define LDB_DATA_WIDTH_CH0_MASK 0x00000020
  210063. +#define LDB_DATA_WIDTH_CH0_24 0x00000020
  210064. +#define LDB_DATA_WIDTH_CH0_18 0x0
  210065. +
  210066. +#define LDB_CH1_MODE_MASK 0x0000000C
  210067. +#define LDB_CH1_MODE_EN_TO_DI1 0x0000000C
  210068. +#define LDB_CH1_MODE_EN_TO_DI0 0x00000004
  210069. +#define LDB_CH1_MODE_DISABLE 0x0
  210070. +#define LDB_CH0_MODE_MASK 0x00000003
  210071. +#define LDB_CH0_MODE_EN_TO_DI1 0x00000003
  210072. +#define LDB_CH0_MODE_EN_TO_DI0 0x00000001
  210073. +#define LDB_CH0_MODE_DISABLE 0x0
  210074. +
  210075. +#define LDB_SPLIT_MODE_EN 0x00000010
  210076. +
  210077. +enum {
  210078. + IMX6_LDB,
  210079. +};
  210080. +
  210081. +enum {
  210082. + LDB_IMX6 = 1,
  210083. +};
  210084. +
  210085. +struct fsl_mxc_ldb_platform_data {
  210086. + int devtype;
  210087. + u32 ext_ref;
  210088. +#define LDB_SPL_DI0 1
  210089. +#define LDB_SPL_DI1 2
  210090. +#define LDB_DUL_DI0 3
  210091. +#define LDB_DUL_DI1 4
  210092. +#define LDB_SIN0 5
  210093. +#define LDB_SIN1 6
  210094. +#define LDB_SEP0 7
  210095. +#define LDB_SEP1 8
  210096. + int mode;
  210097. + int ipu_id;
  210098. + int disp_id;
  210099. +
  210100. + /*only work for separate mode*/
  210101. + int sec_ipu_id;
  210102. + int sec_disp_id;
  210103. +};
  210104. +
  210105. +struct ldb_data {
  210106. + struct platform_device *pdev;
  210107. + struct mxc_dispdrv_handle *disp_ldb;
  210108. + uint32_t *reg;
  210109. + uint32_t *control_reg;
  210110. + uint32_t *gpr3_reg;
  210111. + uint32_t control_reg_data;
  210112. + struct regulator *lvds_bg_reg;
  210113. + int mode;
  210114. + bool inited;
  210115. + struct ldb_setting {
  210116. + struct clk *di_clk;
  210117. + struct clk *ldb_di_clk;
  210118. + struct clk *div_3_5_clk;
  210119. + struct clk *div_7_clk;
  210120. + struct clk *div_sel_clk;
  210121. + bool active;
  210122. + bool clk_en;
  210123. + int ipu;
  210124. + int di;
  210125. + uint32_t ch_mask;
  210126. + uint32_t ch_val;
  210127. + } setting[2];
  210128. + struct notifier_block nb;
  210129. +};
  210130. +
  210131. +static int g_ldb_mode;
  210132. +
  210133. +static struct fb_videomode ldb_modedb[] = {
  210134. + {
  210135. + "LDB-WXGA", 60, 1280, 800, 14065,
  210136. + 40, 40,
  210137. + 10, 3,
  210138. + 80, 10,
  210139. + 0,
  210140. + FB_VMODE_NONINTERLACED,
  210141. + FB_MODE_IS_DETAILED,},
  210142. + {
  210143. + "LDB-XGA", 60, 1024, 768, 15385,
  210144. + 220, 40,
  210145. + 21, 7,
  210146. + 60, 10,
  210147. + 0,
  210148. + FB_VMODE_NONINTERLACED,
  210149. + FB_MODE_IS_DETAILED,},
  210150. + {
  210151. + "LDB-1080P60", 60, 1920, 1080, 7692,
  210152. + 100, 40,
  210153. + 30, 3,
  210154. + 10, 2,
  210155. + 0,
  210156. + FB_VMODE_NONINTERLACED,
  210157. + FB_MODE_IS_DETAILED,},
  210158. +};
  210159. +static int ldb_modedb_sz = ARRAY_SIZE(ldb_modedb);
  210160. +
  210161. +static inline int is_imx6_ldb(struct fsl_mxc_ldb_platform_data *plat_data)
  210162. +{
  210163. + return (plat_data->devtype == LDB_IMX6);
  210164. +}
  210165. +
  210166. +static int bits_per_pixel(int pixel_fmt)
  210167. +{
  210168. + switch (pixel_fmt) {
  210169. + case IPU_PIX_FMT_BGR24:
  210170. + case IPU_PIX_FMT_RGB24:
  210171. + return 24;
  210172. + break;
  210173. + case IPU_PIX_FMT_BGR666:
  210174. + case IPU_PIX_FMT_RGB666:
  210175. + case IPU_PIX_FMT_LVDS666:
  210176. + return 18;
  210177. + break;
  210178. + default:
  210179. + break;
  210180. + }
  210181. + return 0;
  210182. +}
  210183. +
  210184. +static int valid_mode(int pixel_fmt)
  210185. +{
  210186. + return ((pixel_fmt == IPU_PIX_FMT_RGB24) ||
  210187. + (pixel_fmt == IPU_PIX_FMT_BGR24) ||
  210188. + (pixel_fmt == IPU_PIX_FMT_LVDS666) ||
  210189. + (pixel_fmt == IPU_PIX_FMT_RGB666) ||
  210190. + (pixel_fmt == IPU_PIX_FMT_BGR666));
  210191. +}
  210192. +
  210193. +static int parse_ldb_mode(char *mode)
  210194. +{
  210195. + int ldb_mode;
  210196. +
  210197. + if (!strcmp(mode, "spl0"))
  210198. + ldb_mode = LDB_SPL_DI0;
  210199. + else if (!strcmp(mode, "spl1"))
  210200. + ldb_mode = LDB_SPL_DI1;
  210201. + else if (!strcmp(mode, "dul0"))
  210202. + ldb_mode = LDB_DUL_DI0;
  210203. + else if (!strcmp(mode, "dul1"))
  210204. + ldb_mode = LDB_DUL_DI1;
  210205. + else if (!strcmp(mode, "sin0"))
  210206. + ldb_mode = LDB_SIN0;
  210207. + else if (!strcmp(mode, "sin1"))
  210208. + ldb_mode = LDB_SIN1;
  210209. + else if (!strcmp(mode, "sep0"))
  210210. + ldb_mode = LDB_SEP0;
  210211. + else if (!strcmp(mode, "sep1"))
  210212. + ldb_mode = LDB_SEP1;
  210213. + else
  210214. + ldb_mode = -EINVAL;
  210215. +
  210216. + return ldb_mode;
  210217. +}
  210218. +
  210219. +#ifndef MODULE
  210220. +/*
  210221. + * "ldb=spl0/1" -- split mode on DI0/1
  210222. + * "ldb=dul0/1" -- dual mode on DI0/1
  210223. + * "ldb=sin0/1" -- single mode on LVDS0/1
  210224. + * "ldb=sep0/1" -- separate mode begin from LVDS0/1
  210225. + *
  210226. + * there are two LVDS channels(LVDS0 and LVDS1) which can transfer video
  210227. + * datas, there two channels can be used as split/dual/single/separate mode.
  210228. + *
  210229. + * split mode means display data from DI0 or DI1 will send to both channels
  210230. + * LVDS0+LVDS1.
  210231. + * dual mode means display data from DI0 or DI1 will be duplicated on LVDS0
  210232. + * and LVDS1, it said, LVDS0 and LVDS1 has the same content.
  210233. + * single mode means only work for DI0/DI1->LVDS0 or DI0/DI1->LVDS1.
  210234. + * separate mode means you can make DI0/DI1->LVDS0 and DI0/DI1->LVDS1 work
  210235. + * at the same time.
  210236. + */
  210237. +static int __init ldb_setup(char *options)
  210238. +{
  210239. + g_ldb_mode = parse_ldb_mode(options);
  210240. + return (g_ldb_mode < 0) ? 0 : 1;
  210241. +}
  210242. +__setup("ldb=", ldb_setup);
  210243. +#endif
  210244. +
  210245. +static int ldb_get_of_property(struct platform_device *pdev,
  210246. + struct fsl_mxc_ldb_platform_data *plat_data)
  210247. +{
  210248. + struct device_node *np = pdev->dev.of_node;
  210249. + int err;
  210250. + u32 ipu_id, disp_id;
  210251. + u32 sec_ipu_id, sec_disp_id;
  210252. + char *mode;
  210253. + u32 ext_ref;
  210254. +
  210255. + err = of_property_read_string(np, "mode", (const char **)&mode);
  210256. + if (err) {
  210257. + dev_dbg(&pdev->dev, "get of property mode fail\n");
  210258. + return err;
  210259. + }
  210260. + err = of_property_read_u32(np, "ext_ref", &ext_ref);
  210261. + if (err) {
  210262. + dev_dbg(&pdev->dev, "get of property ext_ref fail\n");
  210263. + return err;
  210264. + }
  210265. + err = of_property_read_u32(np, "ipu_id", &ipu_id);
  210266. + if (err) {
  210267. + dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
  210268. + return err;
  210269. + }
  210270. + err = of_property_read_u32(np, "disp_id", &disp_id);
  210271. + if (err) {
  210272. + dev_dbg(&pdev->dev, "get of property disp_id fail\n");
  210273. + return err;
  210274. + }
  210275. + err = of_property_read_u32(np, "sec_ipu_id", &sec_ipu_id);
  210276. + if (err) {
  210277. + dev_dbg(&pdev->dev, "get of property sec_ipu_id fail\n");
  210278. + return err;
  210279. + }
  210280. + err = of_property_read_u32(np, "sec_disp_id", &sec_disp_id);
  210281. + if (err) {
  210282. + dev_dbg(&pdev->dev, "get of property sec_disp_id fail\n");
  210283. + return err;
  210284. + }
  210285. +
  210286. + plat_data->mode = parse_ldb_mode(mode);
  210287. + plat_data->ext_ref = ext_ref;
  210288. + plat_data->ipu_id = ipu_id;
  210289. + plat_data->disp_id = disp_id;
  210290. + plat_data->sec_ipu_id = sec_ipu_id;
  210291. + plat_data->sec_disp_id = sec_disp_id;
  210292. +
  210293. + return err;
  210294. +}
  210295. +
  210296. +static int find_ldb_setting(struct ldb_data *ldb, struct fb_info *fbi)
  210297. +{
  210298. + char *id_di[] = {
  210299. + "DISP3 BG",
  210300. + "DISP3 BG - DI1",
  210301. + };
  210302. + char id[16];
  210303. + int i;
  210304. +
  210305. + for (i = 0; i < 2; i++) {
  210306. + if (ldb->setting[i].active) {
  210307. + memset(id, 0, 16);
  210308. + memcpy(id, id_di[ldb->setting[i].di],
  210309. + strlen(id_di[ldb->setting[i].di]));
  210310. + id[4] += ldb->setting[i].ipu;
  210311. + if (!strcmp(id, fbi->fix.id))
  210312. + return i;
  210313. + }
  210314. + }
  210315. + return -EINVAL;
  210316. +}
  210317. +
  210318. +static int ldb_disp_setup(struct mxc_dispdrv_handle *disp, struct fb_info *fbi)
  210319. +{
  210320. + uint32_t reg, val;
  210321. + uint32_t pixel_clk, rounded_pixel_clk;
  210322. + struct clk *ldb_clk_parent;
  210323. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  210324. + int setting_idx, di;
  210325. + int ret;
  210326. +
  210327. + setting_idx = find_ldb_setting(ldb, fbi);
  210328. + if (setting_idx < 0)
  210329. + return setting_idx;
  210330. +
  210331. + di = ldb->setting[setting_idx].di;
  210332. +
  210333. + /* restore channel mode setting */
  210334. + val = readl(ldb->control_reg);
  210335. + val |= ldb->setting[setting_idx].ch_val;
  210336. + writel(val, ldb->control_reg);
  210337. + dev_dbg(&ldb->pdev->dev, "LDB setup, control reg:0x%x\n",
  210338. + readl(ldb->control_reg));
  210339. +
  210340. + /* vsync setup */
  210341. + reg = readl(ldb->control_reg);
  210342. + if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) {
  210343. + if (di == 0)
  210344. + reg = (reg & ~LDB_DI0_VS_POL_MASK)
  210345. + | LDB_DI0_VS_POL_ACT_HIGH;
  210346. + else
  210347. + reg = (reg & ~LDB_DI1_VS_POL_MASK)
  210348. + | LDB_DI1_VS_POL_ACT_HIGH;
  210349. + } else {
  210350. + if (di == 0)
  210351. + reg = (reg & ~LDB_DI0_VS_POL_MASK)
  210352. + | LDB_DI0_VS_POL_ACT_LOW;
  210353. + else
  210354. + reg = (reg & ~LDB_DI1_VS_POL_MASK)
  210355. + | LDB_DI1_VS_POL_ACT_LOW;
  210356. + }
  210357. + writel(reg, ldb->control_reg);
  210358. +
  210359. + /* clk setup */
  210360. + if (ldb->setting[setting_idx].clk_en)
  210361. + clk_disable_unprepare(ldb->setting[setting_idx].ldb_di_clk);
  210362. + pixel_clk = (PICOS2KHZ(fbi->var.pixclock)) * 1000UL;
  210363. + ldb_clk_parent = clk_get_parent(ldb->setting[setting_idx].ldb_di_clk);
  210364. + if (IS_ERR(ldb_clk_parent)) {
  210365. + dev_err(&ldb->pdev->dev, "get ldb di parent clk fail\n");
  210366. + return PTR_ERR(ldb_clk_parent);
  210367. + }
  210368. + if ((ldb->mode == LDB_SPL_DI0) || (ldb->mode == LDB_SPL_DI1))
  210369. + ret = clk_set_rate(ldb_clk_parent, pixel_clk * 7 / 2);
  210370. + else
  210371. + ret = clk_set_rate(ldb_clk_parent, pixel_clk * 7);
  210372. + if (ret < 0) {
  210373. + dev_err(&ldb->pdev->dev, "set ldb parent clk fail:%d\n", ret);
  210374. + return ret;
  210375. + }
  210376. + rounded_pixel_clk = clk_round_rate(ldb->setting[setting_idx].ldb_di_clk,
  210377. + pixel_clk);
  210378. + dev_dbg(&ldb->pdev->dev, "pixel_clk:%d, rounded_pixel_clk:%d\n",
  210379. + pixel_clk, rounded_pixel_clk);
  210380. + ret = clk_set_rate(ldb->setting[setting_idx].ldb_di_clk,
  210381. + rounded_pixel_clk);
  210382. + if (ret < 0) {
  210383. + dev_err(&ldb->pdev->dev, "set ldb di clk fail:%d\n", ret);
  210384. + return ret;
  210385. + }
  210386. + ret = clk_prepare_enable(ldb->setting[setting_idx].ldb_di_clk);
  210387. + if (ret < 0) {
  210388. + dev_err(&ldb->pdev->dev, "enable ldb di clk fail:%d\n", ret);
  210389. + return ret;
  210390. + }
  210391. +
  210392. + if (!ldb->setting[setting_idx].clk_en)
  210393. + ldb->setting[setting_idx].clk_en = true;
  210394. +
  210395. + return 0;
  210396. +}
  210397. +
  210398. +int ldb_fb_event(struct notifier_block *nb, unsigned long val, void *v)
  210399. +{
  210400. + struct ldb_data *ldb = container_of(nb, struct ldb_data, nb);
  210401. + struct fb_event *event = v;
  210402. + struct fb_info *fbi = event->info;
  210403. + int index;
  210404. + uint32_t data;
  210405. +
  210406. + index = find_ldb_setting(ldb, fbi);
  210407. + if (index < 0)
  210408. + return 0;
  210409. +
  210410. + fbi->mode = (struct fb_videomode *)fb_match_mode(&fbi->var,
  210411. + &fbi->modelist);
  210412. +
  210413. + if (!fbi->mode) {
  210414. + dev_warn(&ldb->pdev->dev,
  210415. + "LDB: can not find mode for xres=%d, yres=%d\n",
  210416. + fbi->var.xres, fbi->var.yres);
  210417. + if (ldb->setting[index].clk_en) {
  210418. + clk_disable(ldb->setting[index].ldb_di_clk);
  210419. + ldb->setting[index].clk_en = false;
  210420. + data = readl(ldb->control_reg);
  210421. + data &= ~ldb->setting[index].ch_mask;
  210422. + writel(data, ldb->control_reg);
  210423. + }
  210424. + return 0;
  210425. + }
  210426. +
  210427. + switch (val) {
  210428. + case FB_EVENT_BLANK:
  210429. + {
  210430. + if (*((int *)event->data) == FB_BLANK_UNBLANK) {
  210431. + if (!ldb->setting[index].clk_en) {
  210432. + clk_enable(ldb->setting[index].ldb_di_clk);
  210433. + ldb->setting[index].clk_en = true;
  210434. + }
  210435. + } else {
  210436. + if (ldb->setting[index].clk_en) {
  210437. + clk_disable(ldb->setting[index].ldb_di_clk);
  210438. + ldb->setting[index].clk_en = false;
  210439. + data = readl(ldb->control_reg);
  210440. + data &= ~ldb->setting[index].ch_mask;
  210441. + writel(data, ldb->control_reg);
  210442. + dev_dbg(&ldb->pdev->dev,
  210443. + "LDB blank, control reg:0x%x\n",
  210444. + readl(ldb->control_reg));
  210445. + }
  210446. + }
  210447. + break;
  210448. + }
  210449. + case FB_EVENT_SUSPEND:
  210450. + if (ldb->setting[index].clk_en) {
  210451. + clk_disable(ldb->setting[index].ldb_di_clk);
  210452. + ldb->setting[index].clk_en = false;
  210453. + }
  210454. + break;
  210455. + default:
  210456. + break;
  210457. + }
  210458. + return 0;
  210459. +}
  210460. +
  210461. +#define LVDS_MUX_CTL_WIDTH 2
  210462. +#define LVDS_MUX_CTL_MASK 3
  210463. +#define LVDS0_MUX_CTL_OFFS 6
  210464. +#define LVDS1_MUX_CTL_OFFS 8
  210465. +#define LVDS0_MUX_CTL_MASK (LVDS_MUX_CTL_MASK << 6)
  210466. +#define LVDS1_MUX_CTL_MASK (LVDS_MUX_CTL_MASK << 8)
  210467. +#define ROUTE_IPU_DI(ipu, di) (((ipu << 1) | di) & LVDS_MUX_CTL_MASK)
  210468. +static int ldb_ipu_ldb_route(int ipu, int di, struct ldb_data *ldb)
  210469. +{
  210470. + uint32_t reg;
  210471. + int channel;
  210472. + int shift;
  210473. + int mode = ldb->mode;
  210474. +
  210475. + reg = readl(ldb->gpr3_reg);
  210476. + if (mode < LDB_SIN0) {
  210477. + reg &= ~(LVDS0_MUX_CTL_MASK | LVDS1_MUX_CTL_MASK);
  210478. + reg |= (ROUTE_IPU_DI(ipu, di) << LVDS0_MUX_CTL_OFFS) |
  210479. + (ROUTE_IPU_DI(ipu, di) << LVDS1_MUX_CTL_OFFS);
  210480. + dev_dbg(&ldb->pdev->dev,
  210481. + "Dual/Split mode both channels route to IPU%d-DI%d\n",
  210482. + ipu, di);
  210483. + } else if ((mode == LDB_SIN0) || (mode == LDB_SIN1)) {
  210484. + reg &= ~(LVDS0_MUX_CTL_MASK | LVDS1_MUX_CTL_MASK);
  210485. + channel = mode - LDB_SIN0;
  210486. + shift = LVDS0_MUX_CTL_OFFS + channel * LVDS_MUX_CTL_WIDTH;
  210487. + reg |= ROUTE_IPU_DI(ipu, di) << shift;
  210488. + dev_dbg(&ldb->pdev->dev,
  210489. + "Single mode channel %d route to IPU%d-DI%d\n",
  210490. + channel, ipu, di);
  210491. + } else {
  210492. + static bool first = true;
  210493. +
  210494. + if (first) {
  210495. + if (mode == LDB_SEP0) {
  210496. + reg &= ~LVDS0_MUX_CTL_MASK;
  210497. + channel = 0;
  210498. + } else {
  210499. + reg &= ~LVDS1_MUX_CTL_MASK;
  210500. + channel = 1;
  210501. + }
  210502. + first = false;
  210503. + } else {
  210504. + if (mode == LDB_SEP0) {
  210505. + reg &= ~LVDS1_MUX_CTL_MASK;
  210506. + channel = 1;
  210507. + } else {
  210508. + reg &= ~LVDS0_MUX_CTL_MASK;
  210509. + channel = 0;
  210510. + }
  210511. + }
  210512. +
  210513. + shift = LVDS0_MUX_CTL_OFFS + channel * LVDS_MUX_CTL_WIDTH;
  210514. + reg |= ROUTE_IPU_DI(ipu, di) << shift;
  210515. +
  210516. + dev_dbg(&ldb->pdev->dev,
  210517. + "Separate mode channel %d route to IPU%d-DI%d\n",
  210518. + channel, ipu, di);
  210519. + }
  210520. + writel(reg, ldb->gpr3_reg);
  210521. +
  210522. + return 0;
  210523. +}
  210524. +
  210525. +static int ldb_disp_init(struct mxc_dispdrv_handle *disp,
  210526. + struct mxc_dispdrv_setting *setting)
  210527. +{
  210528. + int ret = 0, i, lvds_channel = 0;
  210529. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  210530. + struct fsl_mxc_ldb_platform_data *plat_data = ldb->pdev->dev.platform_data;
  210531. + struct resource *res;
  210532. + uint32_t reg, setting_idx;
  210533. + uint32_t ch_mask = 0, ch_val = 0;
  210534. + uint32_t ipu_id, disp_id;
  210535. + char di_clk[] = "ipu1_di0_sel";
  210536. + char ldb_clk[] = "ldb_di0";
  210537. + char div_3_5_clk[] = "di0_div_3_5";
  210538. + char div_7_clk[] = "di0_div_7";
  210539. + char div_sel_clk[] = "di0_div_sel";
  210540. +
  210541. + /* if input format not valid, make RGB666 as default*/
  210542. + if (!valid_mode(setting->if_fmt)) {
  210543. + dev_warn(&ldb->pdev->dev, "Input pixel format not valid"
  210544. + " use default RGB666\n");
  210545. + setting->if_fmt = IPU_PIX_FMT_RGB666;
  210546. + }
  210547. +
  210548. + if (!ldb->inited) {
  210549. + setting_idx = 0;
  210550. + res = platform_get_resource(ldb->pdev, IORESOURCE_MEM, 0);
  210551. + if (!res) {
  210552. + dev_err(&ldb->pdev->dev, "get iomem fail.\n");
  210553. + return -ENOMEM;
  210554. + }
  210555. +
  210556. + ldb->reg = devm_ioremap(&ldb->pdev->dev, res->start,
  210557. + resource_size(res));
  210558. + ldb->control_reg = ldb->reg + 2;
  210559. + ldb->gpr3_reg = ldb->reg + 3;
  210560. +
  210561. + /* ipu selected by platform data setting */
  210562. + setting->dev_id = plat_data->ipu_id;
  210563. +
  210564. + reg = readl(ldb->control_reg);
  210565. +
  210566. + /* refrence resistor select */
  210567. + reg &= ~LDB_BGREF_RMODE_MASK;
  210568. + if (plat_data->ext_ref)
  210569. + reg |= LDB_BGREF_RMODE_EXT;
  210570. + else
  210571. + reg |= LDB_BGREF_RMODE_INT;
  210572. +
  210573. + /* TODO: now only use SPWG data mapping for both channel */
  210574. + reg &= ~(LDB_BIT_MAP_CH0_MASK | LDB_BIT_MAP_CH1_MASK);
  210575. + reg |= LDB_BIT_MAP_CH0_SPWG | LDB_BIT_MAP_CH1_SPWG;
  210576. +
  210577. + /* channel mode setting */
  210578. + reg &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
  210579. + reg &= ~(LDB_DATA_WIDTH_CH0_MASK | LDB_DATA_WIDTH_CH1_MASK);
  210580. +
  210581. + if (bits_per_pixel(setting->if_fmt) == 24)
  210582. + reg |= LDB_DATA_WIDTH_CH0_24 | LDB_DATA_WIDTH_CH1_24;
  210583. + else
  210584. + reg |= LDB_DATA_WIDTH_CH0_18 | LDB_DATA_WIDTH_CH1_18;
  210585. +
  210586. + if (g_ldb_mode >= LDB_SPL_DI0)
  210587. + ldb->mode = g_ldb_mode;
  210588. + else
  210589. + ldb->mode = plat_data->mode;
  210590. +
  210591. + if ((ldb->mode == LDB_SIN0) || (ldb->mode == LDB_SIN1)) {
  210592. + ret = ldb->mode - LDB_SIN0;
  210593. + if (plat_data->disp_id != ret) {
  210594. + dev_warn(&ldb->pdev->dev,
  210595. + "change IPU DI%d to IPU DI%d for LDB "
  210596. + "channel%d.\n",
  210597. + plat_data->disp_id, ret, ret);
  210598. + plat_data->disp_id = ret;
  210599. + }
  210600. + } else if (((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1))
  210601. + && is_imx6_ldb(plat_data)) {
  210602. + if (plat_data->disp_id == plat_data->sec_disp_id) {
  210603. + dev_err(&ldb->pdev->dev,
  210604. + "For LVDS separate mode,"
  210605. + "two DIs should be different!\n");
  210606. + return -EINVAL;
  210607. + }
  210608. +
  210609. + if (((!plat_data->disp_id) && (ldb->mode == LDB_SEP1))
  210610. + || ((plat_data->disp_id) &&
  210611. + (ldb->mode == LDB_SEP0))) {
  210612. + dev_dbg(&ldb->pdev->dev,
  210613. + "LVDS separate mode:"
  210614. + "swap DI configuration!\n");
  210615. + ipu_id = plat_data->ipu_id;
  210616. + disp_id = plat_data->disp_id;
  210617. + plat_data->ipu_id = plat_data->sec_ipu_id;
  210618. + plat_data->disp_id = plat_data->sec_disp_id;
  210619. + plat_data->sec_ipu_id = ipu_id;
  210620. + plat_data->sec_disp_id = disp_id;
  210621. + }
  210622. + }
  210623. +
  210624. + if (ldb->mode == LDB_SPL_DI0) {
  210625. + reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI0
  210626. + | LDB_CH1_MODE_EN_TO_DI0;
  210627. + setting->disp_id = 0;
  210628. + } else if (ldb->mode == LDB_SPL_DI1) {
  210629. + reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI1
  210630. + | LDB_CH1_MODE_EN_TO_DI1;
  210631. + setting->disp_id = 1;
  210632. + } else if (ldb->mode == LDB_DUL_DI0) {
  210633. + reg &= ~LDB_SPLIT_MODE_EN;
  210634. + reg |= LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0;
  210635. + setting->disp_id = 0;
  210636. + } else if (ldb->mode == LDB_DUL_DI1) {
  210637. + reg &= ~LDB_SPLIT_MODE_EN;
  210638. + reg |= LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1;
  210639. + setting->disp_id = 1;
  210640. + } else if (ldb->mode == LDB_SIN0) {
  210641. + reg &= ~LDB_SPLIT_MODE_EN;
  210642. + setting->disp_id = plat_data->disp_id;
  210643. + if (setting->disp_id == 0)
  210644. + reg |= LDB_CH0_MODE_EN_TO_DI0;
  210645. + else
  210646. + reg |= LDB_CH0_MODE_EN_TO_DI1;
  210647. + ch_mask = LDB_CH0_MODE_MASK;
  210648. + ch_val = reg & LDB_CH0_MODE_MASK;
  210649. + } else if (ldb->mode == LDB_SIN1) {
  210650. + reg &= ~LDB_SPLIT_MODE_EN;
  210651. + setting->disp_id = plat_data->disp_id;
  210652. + if (setting->disp_id == 0)
  210653. + reg |= LDB_CH1_MODE_EN_TO_DI0;
  210654. + else
  210655. + reg |= LDB_CH1_MODE_EN_TO_DI1;
  210656. + ch_mask = LDB_CH1_MODE_MASK;
  210657. + ch_val = reg & LDB_CH1_MODE_MASK;
  210658. + } else { /* separate mode*/
  210659. + setting->disp_id = plat_data->disp_id;
  210660. +
  210661. + /* first output is LVDS0 or LVDS1 */
  210662. + if (ldb->mode == LDB_SEP0)
  210663. + lvds_channel = 0;
  210664. + else
  210665. + lvds_channel = 1;
  210666. +
  210667. + reg &= ~LDB_SPLIT_MODE_EN;
  210668. +
  210669. + if ((lvds_channel == 0) && (setting->disp_id == 0))
  210670. + reg |= LDB_CH0_MODE_EN_TO_DI0;
  210671. + else if ((lvds_channel == 0) && (setting->disp_id == 1))
  210672. + reg |= LDB_CH0_MODE_EN_TO_DI1;
  210673. + else if ((lvds_channel == 1) && (setting->disp_id == 0))
  210674. + reg |= LDB_CH1_MODE_EN_TO_DI0;
  210675. + else
  210676. + reg |= LDB_CH1_MODE_EN_TO_DI1;
  210677. + ch_mask = lvds_channel ? LDB_CH1_MODE_MASK :
  210678. + LDB_CH0_MODE_MASK;
  210679. + ch_val = reg & ch_mask;
  210680. +
  210681. + if (bits_per_pixel(setting->if_fmt) == 24) {
  210682. + if (lvds_channel == 0)
  210683. + reg &= ~LDB_DATA_WIDTH_CH1_24;
  210684. + else
  210685. + reg &= ~LDB_DATA_WIDTH_CH0_24;
  210686. + } else {
  210687. + if (lvds_channel == 0)
  210688. + reg &= ~LDB_DATA_WIDTH_CH1_18;
  210689. + else
  210690. + reg &= ~LDB_DATA_WIDTH_CH0_18;
  210691. + }
  210692. + }
  210693. +
  210694. + writel(reg, ldb->control_reg);
  210695. + if (ldb->mode < LDB_SIN0) {
  210696. + ch_mask = LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK;
  210697. + ch_val = reg & (LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
  210698. + }
  210699. + } else { /* second time for separate mode */
  210700. + if ((ldb->mode == LDB_SPL_DI0) ||
  210701. + (ldb->mode == LDB_SPL_DI1) ||
  210702. + (ldb->mode == LDB_DUL_DI0) ||
  210703. + (ldb->mode == LDB_DUL_DI1) ||
  210704. + (ldb->mode == LDB_SIN0) ||
  210705. + (ldb->mode == LDB_SIN1)) {
  210706. + dev_err(&ldb->pdev->dev, "for second ldb disp"
  210707. + "ldb mode should in separate mode\n");
  210708. + return -EINVAL;
  210709. + }
  210710. +
  210711. + setting_idx = 1;
  210712. + if (is_imx6_ldb(plat_data)) {
  210713. + setting->dev_id = plat_data->sec_ipu_id;
  210714. + setting->disp_id = plat_data->sec_disp_id;
  210715. + } else {
  210716. + setting->dev_id = plat_data->ipu_id;
  210717. + setting->disp_id = !plat_data->disp_id;
  210718. + }
  210719. + if (setting->disp_id == ldb->setting[0].di) {
  210720. + dev_err(&ldb->pdev->dev, "Err: for second ldb disp in"
  210721. + "separate mode, DI should be different!\n");
  210722. + return -EINVAL;
  210723. + }
  210724. +
  210725. + /* second output is LVDS0 or LVDS1 */
  210726. + if (ldb->mode == LDB_SEP0)
  210727. + lvds_channel = 1;
  210728. + else
  210729. + lvds_channel = 0;
  210730. +
  210731. + reg = readl(ldb->control_reg);
  210732. + if ((lvds_channel == 0) && (setting->disp_id == 0))
  210733. + reg |= LDB_CH0_MODE_EN_TO_DI0;
  210734. + else if ((lvds_channel == 0) && (setting->disp_id == 1))
  210735. + reg |= LDB_CH0_MODE_EN_TO_DI1;
  210736. + else if ((lvds_channel == 1) && (setting->disp_id == 0))
  210737. + reg |= LDB_CH1_MODE_EN_TO_DI0;
  210738. + else
  210739. + reg |= LDB_CH1_MODE_EN_TO_DI1;
  210740. + ch_mask = lvds_channel ? LDB_CH1_MODE_MASK :
  210741. + LDB_CH0_MODE_MASK;
  210742. + ch_val = reg & ch_mask;
  210743. +
  210744. + if (bits_per_pixel(setting->if_fmt) == 24) {
  210745. + if (lvds_channel == 0)
  210746. + reg |= LDB_DATA_WIDTH_CH0_24;
  210747. + else
  210748. + reg |= LDB_DATA_WIDTH_CH1_24;
  210749. + } else {
  210750. + if (lvds_channel == 0)
  210751. + reg |= LDB_DATA_WIDTH_CH0_18;
  210752. + else
  210753. + reg |= LDB_DATA_WIDTH_CH1_18;
  210754. + }
  210755. + writel(reg, ldb->control_reg);
  210756. + }
  210757. +
  210758. + /* get clocks */
  210759. + if (is_imx6_ldb(plat_data) &&
  210760. + ((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1))) {
  210761. + ldb_clk[6] += lvds_channel;
  210762. + div_3_5_clk[2] += lvds_channel;
  210763. + div_7_clk[2] += lvds_channel;
  210764. + div_sel_clk[2] += lvds_channel;
  210765. + } else {
  210766. + ldb_clk[6] += setting->disp_id;
  210767. + div_3_5_clk[2] += setting->disp_id;
  210768. + div_7_clk[2] += setting->disp_id;
  210769. + div_sel_clk[2] += setting->disp_id;
  210770. + }
  210771. + ldb->setting[setting_idx].ldb_di_clk = clk_get(&ldb->pdev->dev,
  210772. + ldb_clk);
  210773. + if (IS_ERR(ldb->setting[setting_idx].ldb_di_clk)) {
  210774. + dev_err(&ldb->pdev->dev, "get ldb clk failed\n");
  210775. + return PTR_ERR(ldb->setting[setting_idx].ldb_di_clk);
  210776. + }
  210777. +
  210778. + ldb->setting[setting_idx].div_3_5_clk = clk_get(&ldb->pdev->dev,
  210779. + div_3_5_clk);
  210780. + if (IS_ERR(ldb->setting[setting_idx].div_3_5_clk)) {
  210781. + dev_err(&ldb->pdev->dev, "get div 3.5 clk failed\n");
  210782. + return PTR_ERR(ldb->setting[setting_idx].div_3_5_clk);
  210783. + }
  210784. + ldb->setting[setting_idx].div_7_clk = clk_get(&ldb->pdev->dev,
  210785. + div_7_clk);
  210786. + if (IS_ERR(ldb->setting[setting_idx].div_7_clk)) {
  210787. + dev_err(&ldb->pdev->dev, "get div 7 clk failed\n");
  210788. + return PTR_ERR(ldb->setting[setting_idx].div_7_clk);
  210789. + }
  210790. +
  210791. + ldb->setting[setting_idx].div_sel_clk = clk_get(&ldb->pdev->dev,
  210792. + div_sel_clk);
  210793. + if (IS_ERR(ldb->setting[setting_idx].div_sel_clk)) {
  210794. + dev_err(&ldb->pdev->dev, "get div sel clk failed\n");
  210795. + return PTR_ERR(ldb->setting[setting_idx].div_sel_clk);
  210796. + }
  210797. +
  210798. + di_clk[3] += setting->dev_id;
  210799. + di_clk[7] += setting->disp_id;
  210800. + ldb->setting[setting_idx].di_clk = clk_get(&ldb->pdev->dev,
  210801. + di_clk);
  210802. + if (IS_ERR(ldb->setting[setting_idx].di_clk)) {
  210803. + dev_err(&ldb->pdev->dev, "get di clk failed\n");
  210804. + return PTR_ERR(ldb->setting[setting_idx].di_clk);
  210805. + }
  210806. +
  210807. + ldb->setting[setting_idx].ch_mask = ch_mask;
  210808. + ldb->setting[setting_idx].ch_val = ch_val;
  210809. +
  210810. + if (is_imx6_ldb(plat_data))
  210811. + ldb_ipu_ldb_route(setting->dev_id, setting->disp_id, ldb);
  210812. +
  210813. + /* must use spec video mode defined by driver */
  210814. + ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str,
  210815. + ldb_modedb, ldb_modedb_sz, NULL, setting->default_bpp);
  210816. + if (ret != 1)
  210817. + fb_videomode_to_var(&setting->fbi->var, &ldb_modedb[0]);
  210818. +
  210819. + INIT_LIST_HEAD(&setting->fbi->modelist);
  210820. + for (i = 0; i < ldb_modedb_sz; i++) {
  210821. + struct fb_videomode m;
  210822. + fb_var_to_videomode(&m, &setting->fbi->var);
  210823. + if (fb_mode_is_equal(&m, &ldb_modedb[i])) {
  210824. + fb_add_videomode(&ldb_modedb[i],
  210825. + &setting->fbi->modelist);
  210826. + break;
  210827. + }
  210828. + }
  210829. +
  210830. + ldb->setting[setting_idx].ipu = setting->dev_id;
  210831. + ldb->setting[setting_idx].di = setting->disp_id;
  210832. +
  210833. + return ret;
  210834. +}
  210835. +
  210836. +static int ldb_post_disp_init(struct mxc_dispdrv_handle *disp,
  210837. + int ipu_id, int disp_id)
  210838. +{
  210839. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  210840. + int setting_idx = ldb->inited ? 1 : 0;
  210841. + int ret = 0;
  210842. +
  210843. + if (!ldb->inited) {
  210844. + ldb->nb.notifier_call = ldb_fb_event;
  210845. + fb_register_client(&ldb->nb);
  210846. + }
  210847. +
  210848. + ret = clk_set_parent(ldb->setting[setting_idx].di_clk,
  210849. + ldb->setting[setting_idx].ldb_di_clk);
  210850. + if (ret) {
  210851. + dev_err(&ldb->pdev->dev, "fail to set ldb_di clk as"
  210852. + "the parent of ipu_di clk\n");
  210853. + return ret;
  210854. + }
  210855. +
  210856. + if ((ldb->mode == LDB_SPL_DI0) || (ldb->mode == LDB_SPL_DI1)) {
  210857. + ret = clk_set_parent(ldb->setting[setting_idx].div_sel_clk,
  210858. + ldb->setting[setting_idx].div_3_5_clk);
  210859. + if (ret) {
  210860. + dev_err(&ldb->pdev->dev, "fail to set div 3.5 clk as"
  210861. + "the parent of div sel clk\n");
  210862. + return ret;
  210863. + }
  210864. + } else {
  210865. + ret = clk_set_parent(ldb->setting[setting_idx].div_sel_clk,
  210866. + ldb->setting[setting_idx].div_7_clk);
  210867. + if (ret) {
  210868. + dev_err(&ldb->pdev->dev, "fail to set div 7 clk as"
  210869. + "the parent of div sel clk\n");
  210870. + return ret;
  210871. + }
  210872. + }
  210873. +
  210874. + /* save active ldb setting for fb notifier */
  210875. + ldb->setting[setting_idx].active = true;
  210876. +
  210877. + ldb->inited = true;
  210878. + return ret;
  210879. +}
  210880. +
  210881. +static void ldb_disp_deinit(struct mxc_dispdrv_handle *disp)
  210882. +{
  210883. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  210884. + int i;
  210885. +
  210886. + writel(0, ldb->control_reg);
  210887. +
  210888. + for (i = 0; i < 2; i++) {
  210889. + clk_disable(ldb->setting[i].ldb_di_clk);
  210890. + clk_put(ldb->setting[i].ldb_di_clk);
  210891. + clk_put(ldb->setting[i].div_3_5_clk);
  210892. + clk_put(ldb->setting[i].div_7_clk);
  210893. + clk_put(ldb->setting[i].div_sel_clk);
  210894. + }
  210895. +
  210896. + fb_unregister_client(&ldb->nb);
  210897. +}
  210898. +
  210899. +static struct mxc_dispdrv_driver ldb_drv = {
  210900. + .name = DISPDRV_LDB,
  210901. + .init = ldb_disp_init,
  210902. + .post_init = ldb_post_disp_init,
  210903. + .deinit = ldb_disp_deinit,
  210904. + .setup = ldb_disp_setup,
  210905. +};
  210906. +
  210907. +static int ldb_suspend(struct platform_device *pdev, pm_message_t state)
  210908. +{
  210909. + struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);
  210910. + uint32_t data;
  210911. +
  210912. + if (!ldb->inited)
  210913. + return 0;
  210914. + data = readl(ldb->control_reg);
  210915. + ldb->control_reg_data = data;
  210916. + data &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
  210917. + writel(data, ldb->control_reg);
  210918. +
  210919. + return 0;
  210920. +}
  210921. +
  210922. +static int ldb_resume(struct platform_device *pdev)
  210923. +{
  210924. + struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);
  210925. +
  210926. + if (!ldb->inited)
  210927. + return 0;
  210928. + writel(ldb->control_reg_data, ldb->control_reg);
  210929. +
  210930. + return 0;
  210931. +}
  210932. +
  210933. +static struct platform_device_id imx_ldb_devtype[] = {
  210934. + {
  210935. + .name = "ldb-imx6",
  210936. + .driver_data = LDB_IMX6,
  210937. + }, {
  210938. + /* sentinel */
  210939. + }
  210940. +};
  210941. +
  210942. +static const struct of_device_id imx_ldb_dt_ids[] = {
  210943. + { .compatible = "fsl,imx6q-ldb", .data = &imx_ldb_devtype[IMX6_LDB],},
  210944. + { /* sentinel */ }
  210945. +};
  210946. +
  210947. +/*!
  210948. + * This function is called by the driver framework to initialize the LDB
  210949. + * device.
  210950. + *
  210951. + * @param dev The device structure for the LDB passed in by the
  210952. + * driver framework.
  210953. + *
  210954. + * @return Returns 0 on success or negative error code on error
  210955. + */
  210956. +static int ldb_probe(struct platform_device *pdev)
  210957. +{
  210958. + int ret = 0;
  210959. + struct ldb_data *ldb;
  210960. + struct fsl_mxc_ldb_platform_data *plat_data;
  210961. + const struct of_device_id *of_id =
  210962. + of_match_device(imx_ldb_dt_ids, &pdev->dev);
  210963. +
  210964. + dev_dbg(&pdev->dev, "%s enter\n", __func__);
  210965. + ldb = devm_kzalloc(&pdev->dev, sizeof(struct ldb_data), GFP_KERNEL);
  210966. + if (!ldb)
  210967. + return -ENOMEM;
  210968. +
  210969. + plat_data = devm_kzalloc(&pdev->dev,
  210970. + sizeof(struct fsl_mxc_ldb_platform_data),
  210971. + GFP_KERNEL);
  210972. + if (!plat_data)
  210973. + return -ENOMEM;
  210974. + pdev->dev.platform_data = plat_data;
  210975. + if (of_id)
  210976. + pdev->id_entry = of_id->data;
  210977. + plat_data->devtype = pdev->id_entry->driver_data;
  210978. +
  210979. + ret = ldb_get_of_property(pdev, plat_data);
  210980. + if (ret < 0) {
  210981. + dev_err(&pdev->dev, "get ldb of property fail\n");
  210982. + return ret;
  210983. + }
  210984. +
  210985. + ldb->pdev = pdev;
  210986. + ldb->disp_ldb = mxc_dispdrv_register(&ldb_drv);
  210987. + mxc_dispdrv_setdata(ldb->disp_ldb, ldb);
  210988. +
  210989. + dev_set_drvdata(&pdev->dev, ldb);
  210990. +
  210991. + dev_dbg(&pdev->dev, "%s exit\n", __func__);
  210992. + return ret;
  210993. +}
  210994. +
  210995. +static int ldb_remove(struct platform_device *pdev)
  210996. +{
  210997. + struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);
  210998. +
  210999. + if (!ldb->inited)
  211000. + return 0;
  211001. + mxc_dispdrv_puthandle(ldb->disp_ldb);
  211002. + mxc_dispdrv_unregister(ldb->disp_ldb);
  211003. + return 0;
  211004. +}
  211005. +
  211006. +static struct platform_driver mxcldb_driver = {
  211007. + .driver = {
  211008. + .name = "mxc_ldb",
  211009. + .of_match_table = imx_ldb_dt_ids,
  211010. + },
  211011. + .probe = ldb_probe,
  211012. + .remove = ldb_remove,
  211013. + .suspend = ldb_suspend,
  211014. + .resume = ldb_resume,
  211015. +};
  211016. +
  211017. +static int __init ldb_init(void)
  211018. +{
  211019. + return platform_driver_register(&mxcldb_driver);
  211020. +}
  211021. +
  211022. +static void __exit ldb_uninit(void)
  211023. +{
  211024. + platform_driver_unregister(&mxcldb_driver);
  211025. +}
  211026. +
  211027. +module_init(ldb_init);
  211028. +module_exit(ldb_uninit);
  211029. +
  211030. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  211031. +MODULE_DESCRIPTION("MXC LDB driver");
  211032. +MODULE_LICENSE("GPL");
  211033. diff -Nur linux-3.14.14/drivers/video/mxc/Makefile linux-imx6-3.14/drivers/video/mxc/Makefile
  211034. --- linux-3.14.14/drivers/video/mxc/Makefile 1969-12-31 18:00:00.000000000 -0600
  211035. +++ linux-imx6-3.14/drivers/video/mxc/Makefile 2014-12-08 00:31:54.860418001 -0600
  211036. @@ -0,0 +1,6 @@
  211037. +obj-$(CONFIG_FB_MXC_LDB) += ldb.o
  211038. +obj-$(CONFIG_FB_MXC_MIPI_DSI) += mipi_dsi.o
  211039. +obj-$(CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL) += mxcfb_hx8369_wvga.o
  211040. +obj-$(CONFIG_FB_MXC_HDMI) += mxc_hdmi.o
  211041. +obj-$(CONFIG_FB_MXC_EDID) += mxc_edid.o
  211042. +obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxc_dispdrv.o mxc_lcdif.o mxc_ipuv3_fb.o
  211043. diff -Nur linux-3.14.14/drivers/video/mxc/mipi_dsi.c linux-imx6-3.14/drivers/video/mxc/mipi_dsi.c
  211044. --- linux-3.14.14/drivers/video/mxc/mipi_dsi.c 1969-12-31 18:00:00.000000000 -0600
  211045. +++ linux-imx6-3.14/drivers/video/mxc/mipi_dsi.c 2014-12-08 00:31:54.860418001 -0600
  211046. @@ -0,0 +1,953 @@
  211047. +/*
  211048. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  211049. + *
  211050. + * This program is free software; you can redistribute it and/or modify
  211051. + * it under the terms of the GNU General Public License as published by
  211052. + * the Free Software Foundation; either version 2 of the License, or
  211053. + * (at your option) any later version.
  211054. +
  211055. + * This program is distributed in the hope that it will be useful,
  211056. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  211057. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  211058. + * GNU General Public License for more details.
  211059. +
  211060. + * You should have received a copy of the GNU General Public License along
  211061. + * with this program; if not, write to the Free Software Foundation, Inc.,
  211062. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  211063. + */
  211064. +
  211065. +#include <linux/types.h>
  211066. +#include <linux/init.h>
  211067. +#include <linux/platform_device.h>
  211068. +#include <linux/err.h>
  211069. +#include <linux/clk.h>
  211070. +#include <linux/console.h>
  211071. +#include <linux/io.h>
  211072. +#include <linux/bitops.h>
  211073. +#include <linux/ipu.h>
  211074. +#include <linux/mfd/syscon.h>
  211075. +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  211076. +#include <linux/mipi_dsi.h>
  211077. +#include <linux/module.h>
  211078. +#include <linux/mxcfb.h>
  211079. +#include <linux/backlight.h>
  211080. +#include <linux/of_device.h>
  211081. +#include <linux/regulator/consumer.h>
  211082. +#include <linux/reset.h>
  211083. +#include <linux/spinlock.h>
  211084. +#include <linux/delay.h>
  211085. +#include <video/mipi_display.h>
  211086. +
  211087. +#include "mxc_dispdrv.h"
  211088. +#include "mipi_dsi.h"
  211089. +
  211090. +#define DISPDRV_MIPI "mipi_dsi"
  211091. +#define ROUND_UP(x) ((x)+1)
  211092. +#define NS2PS_RATIO (1000)
  211093. +#define NUMBER_OF_CHUNKS (0x8)
  211094. +#define NULL_PKT_SIZE (0x8)
  211095. +#define PHY_BTA_MAXTIME (0xd00)
  211096. +#define PHY_LP2HS_MAXTIME (0x40)
  211097. +#define PHY_HS2LP_MAXTIME (0x40)
  211098. +#define PHY_STOP_WAIT_TIME (0x20)
  211099. +#define DSI_CLKMGR_CFG_CLK_DIV (0x107)
  211100. +#define DSI_GEN_PLD_DATA_BUF_ENTRY (0x10)
  211101. +#define MIPI_MUX_CTRL(v) (((v) & 0x3) << 4)
  211102. +#define MIPI_LCD_SLEEP_MODE_DELAY (120)
  211103. +#define MIPI_DSI_REG_RW_TIMEOUT (20)
  211104. +#define MIPI_DSI_PHY_TIMEOUT (10)
  211105. +
  211106. +static struct mipi_dsi_match_lcd mipi_dsi_lcd_db[] = {
  211107. +#ifdef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
  211108. + {
  211109. + "TRULY-WVGA",
  211110. + {mipid_hx8369_get_lcd_videomode, mipid_hx8369_lcd_setup}
  211111. + },
  211112. +#endif
  211113. + {
  211114. + "", {NULL, NULL}
  211115. + }
  211116. +};
  211117. +
  211118. +struct _mipi_dsi_phy_pll_clk {
  211119. + u32 max_phy_clk;
  211120. + u32 config;
  211121. +};
  211122. +
  211123. +/* configure data for DPHY PLL 27M reference clk out */
  211124. +static const struct _mipi_dsi_phy_pll_clk mipi_dsi_phy_pll_clk_table[] = {
  211125. + {1000, 0x74}, /* 950-1000MHz */
  211126. + {950, 0x54}, /* 900-950Mhz */
  211127. + {900, 0x34}, /* 850-900Mhz */
  211128. + {850, 0x14}, /* 800-850MHz */
  211129. + {800, 0x32}, /* 750-800MHz */
  211130. + {750, 0x12}, /* 700-750Mhz */
  211131. + {700, 0x30}, /* 650-700Mhz */
  211132. + {650, 0x10}, /* 600-650MHz */
  211133. + {600, 0x2e}, /* 550-600MHz */
  211134. + {550, 0x0e}, /* 500-550Mhz */
  211135. + {500, 0x2c}, /* 450-500Mhz */
  211136. + {450, 0x0c}, /* 400-450MHz */
  211137. + {400, 0x4a}, /* 360-400MHz */
  211138. + {360, 0x2a}, /* 330-360Mhz */
  211139. + {330, 0x48}, /* 300-330Mhz */
  211140. + {300, 0x28}, /* 270-300MHz */
  211141. + {270, 0x08}, /* 250-270MHz */
  211142. + {250, 0x46}, /* 240-250Mhz */
  211143. + {240, 0x26}, /* 210-240Mhz */
  211144. + {210, 0x06}, /* 200-210MHz */
  211145. + {200, 0x44}, /* 180-200MHz */
  211146. + {180, 0x24}, /* 160-180MHz */
  211147. + {160, 0x04}, /* 150-160MHz */
  211148. +};
  211149. +
  211150. +static int valid_mode(int pixel_fmt)
  211151. +{
  211152. + return ((pixel_fmt == IPU_PIX_FMT_RGB24) ||
  211153. + (pixel_fmt == IPU_PIX_FMT_BGR24) ||
  211154. + (pixel_fmt == IPU_PIX_FMT_RGB666) ||
  211155. + (pixel_fmt == IPU_PIX_FMT_RGB565) ||
  211156. + (pixel_fmt == IPU_PIX_FMT_BGR666) ||
  211157. + (pixel_fmt == IPU_PIX_FMT_RGB332));
  211158. +}
  211159. +
  211160. +static inline void mipi_dsi_read_register(struct mipi_dsi_info *mipi_dsi,
  211161. + u32 reg, u32 *val)
  211162. +{
  211163. + *val = ioread32(mipi_dsi->mmio_base + reg);
  211164. + dev_dbg(&mipi_dsi->pdev->dev, "read_reg:0x%02x, val:0x%08x.\n",
  211165. + reg, *val);
  211166. +}
  211167. +
  211168. +static inline void mipi_dsi_write_register(struct mipi_dsi_info *mipi_dsi,
  211169. + u32 reg, u32 val)
  211170. +{
  211171. + iowrite32(val, mipi_dsi->mmio_base + reg);
  211172. + dev_dbg(&mipi_dsi->pdev->dev, "\t\twrite_reg:0x%02x, val:0x%08x.\n",
  211173. + reg, val);
  211174. +}
  211175. +
  211176. +int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi_dsi,
  211177. + u8 data_type, const u32 *buf, int len)
  211178. +{
  211179. + u32 val;
  211180. + u32 status = 0;
  211181. + int write_len = len;
  211182. + uint32_t timeout = 0;
  211183. +
  211184. + if (len) {
  211185. + /* generic long write command */
  211186. + while (len / DSI_GEN_PLD_DATA_BUF_SIZE) {
  211187. + mipi_dsi_write_register(mipi_dsi,
  211188. + MIPI_DSI_GEN_PLD_DATA, *buf);
  211189. + buf++;
  211190. + len -= DSI_GEN_PLD_DATA_BUF_SIZE;
  211191. + mipi_dsi_read_register(mipi_dsi,
  211192. + MIPI_DSI_CMD_PKT_STATUS, &status);
  211193. + while ((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) ==
  211194. + DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) {
  211195. + msleep(1);
  211196. + timeout++;
  211197. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  211198. + return -EIO;
  211199. + mipi_dsi_read_register(mipi_dsi,
  211200. + MIPI_DSI_CMD_PKT_STATUS, &status);
  211201. + }
  211202. + }
  211203. + /* write the remainder bytes */
  211204. + if (len > 0) {
  211205. + while ((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) ==
  211206. + DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) {
  211207. + msleep(1);
  211208. + timeout++;
  211209. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  211210. + return -EIO;
  211211. + mipi_dsi_read_register(mipi_dsi,
  211212. + MIPI_DSI_CMD_PKT_STATUS, &status);
  211213. + }
  211214. + mipi_dsi_write_register(mipi_dsi,
  211215. + MIPI_DSI_GEN_PLD_DATA, *buf);
  211216. + }
  211217. +
  211218. + val = data_type | ((write_len & DSI_GEN_HDR_DATA_MASK)
  211219. + << DSI_GEN_HDR_DATA_SHIFT);
  211220. + } else {
  211221. + /* generic short write command */
  211222. + val = data_type | ((*buf & DSI_GEN_HDR_DATA_MASK)
  211223. + << DSI_GEN_HDR_DATA_SHIFT);
  211224. + }
  211225. +
  211226. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &status);
  211227. + while ((status & DSI_CMD_PKT_STATUS_GEN_CMD_FULL) ==
  211228. + DSI_CMD_PKT_STATUS_GEN_CMD_FULL) {
  211229. + msleep(1);
  211230. + timeout++;
  211231. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  211232. + return -EIO;
  211233. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  211234. + &status);
  211235. + }
  211236. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_GEN_HDR, val);
  211237. +
  211238. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &status);
  211239. + while (!((status & DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY) ==
  211240. + DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY) ||
  211241. + !((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY) ==
  211242. + DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY)) {
  211243. + msleep(1);
  211244. + timeout++;
  211245. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  211246. + return -EIO;
  211247. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  211248. + &status);
  211249. + }
  211250. +
  211251. + return 0;
  211252. +}
  211253. +
  211254. +int mipi_dsi_pkt_read(struct mipi_dsi_info *mipi_dsi,
  211255. + u8 data_type, u32 *buf, int len)
  211256. +{
  211257. + u32 val;
  211258. + int read_len = 0;
  211259. + uint32_t timeout = 0;
  211260. +
  211261. + if (!len) {
  211262. + mipi_dbg("%s, len = 0 invalid error!\n", __func__);
  211263. + return -EINVAL;
  211264. + }
  211265. +
  211266. + val = data_type | ((*buf & DSI_GEN_HDR_DATA_MASK)
  211267. + << DSI_GEN_HDR_DATA_SHIFT);
  211268. + memset(buf, 0, len);
  211269. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_GEN_HDR, val);
  211270. +
  211271. + /* wait for cmd to sent out */
  211272. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &val);
  211273. + while ((val & DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) !=
  211274. + DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) {
  211275. + msleep(1);
  211276. + timeout++;
  211277. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  211278. + return -EIO;
  211279. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  211280. + &val);
  211281. + }
  211282. + /* wait for entire response stroed in FIFO */
  211283. + while ((val & DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) ==
  211284. + DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) {
  211285. + msleep(1);
  211286. + timeout++;
  211287. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  211288. + return -EIO;
  211289. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  211290. + &val);
  211291. + }
  211292. +
  211293. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &val);
  211294. + while (!(val & DSI_CMD_PKT_STATUS_GEN_PLD_R_EMPTY)) {
  211295. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_GEN_PLD_DATA, buf);
  211296. + read_len += DSI_GEN_PLD_DATA_BUF_SIZE;
  211297. + buf++;
  211298. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  211299. + &val);
  211300. + if (read_len == (DSI_GEN_PLD_DATA_BUF_ENTRY *
  211301. + DSI_GEN_PLD_DATA_BUF_SIZE))
  211302. + break;
  211303. + }
  211304. +
  211305. + if ((len <= read_len) &&
  211306. + ((len + DSI_GEN_PLD_DATA_BUF_SIZE) >= read_len))
  211307. + return 0;
  211308. + else {
  211309. + dev_err(&mipi_dsi->pdev->dev,
  211310. + "actually read_len:%d != len:%d.\n", read_len, len);
  211311. + return -ERANGE;
  211312. + }
  211313. +}
  211314. +
  211315. +int mipi_dsi_dcs_cmd(struct mipi_dsi_info *mipi_dsi,
  211316. + u8 cmd, const u32 *param, int num)
  211317. +{
  211318. + int err = 0;
  211319. + u32 buf[DSI_CMD_BUF_MAXSIZE];
  211320. +
  211321. + switch (cmd) {
  211322. + case MIPI_DCS_EXIT_SLEEP_MODE:
  211323. + case MIPI_DCS_ENTER_SLEEP_MODE:
  211324. + case MIPI_DCS_SET_DISPLAY_ON:
  211325. + case MIPI_DCS_SET_DISPLAY_OFF:
  211326. + buf[0] = cmd;
  211327. + err = mipi_dsi_pkt_write(mipi_dsi,
  211328. + MIPI_DSI_DCS_SHORT_WRITE, buf, 0);
  211329. + break;
  211330. +
  211331. + default:
  211332. + dev_err(&mipi_dsi->pdev->dev,
  211333. + "MIPI DSI DCS Command:0x%x Not supported!\n", cmd);
  211334. + break;
  211335. + }
  211336. +
  211337. + return err;
  211338. +}
  211339. +
  211340. +static void mipi_dsi_dphy_init(struct mipi_dsi_info *mipi_dsi,
  211341. + u32 cmd, u32 data)
  211342. +{
  211343. + u32 val;
  211344. + u32 timeout = 0;
  211345. +
  211346. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
  211347. + DSI_PHY_IF_CTRL_RESET);
  211348. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP, DSI_PWRUP_POWERUP);
  211349. +
  211350. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
  211351. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL1,
  211352. + (0x10000 | cmd));
  211353. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 2);
  211354. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
  211355. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL1, (0 | data));
  211356. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 2);
  211357. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
  211358. + val = DSI_PHY_RSTZ_EN_CLK | DSI_PHY_RSTZ_DISABLE_RST |
  211359. + DSI_PHY_RSTZ_DISABLE_SHUTDOWN;
  211360. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ, val);
  211361. +
  211362. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
  211363. + while ((val & DSI_PHY_STATUS_LOCK) != DSI_PHY_STATUS_LOCK) {
  211364. + msleep(1);
  211365. + timeout++;
  211366. + if (timeout == MIPI_DSI_PHY_TIMEOUT) {
  211367. + dev_err(&mipi_dsi->pdev->dev,
  211368. + "Error: phy lock timeout!\n");
  211369. + break;
  211370. + }
  211371. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
  211372. + }
  211373. + timeout = 0;
  211374. + while ((val & DSI_PHY_STATUS_STOPSTATE_CLK_LANE) !=
  211375. + DSI_PHY_STATUS_STOPSTATE_CLK_LANE) {
  211376. + msleep(1);
  211377. + timeout++;
  211378. + if (timeout == MIPI_DSI_PHY_TIMEOUT) {
  211379. + dev_err(&mipi_dsi->pdev->dev,
  211380. + "Error: phy lock lane timeout!\n");
  211381. + break;
  211382. + }
  211383. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
  211384. + }
  211385. +}
  211386. +
  211387. +static void mipi_dsi_enable_controller(struct mipi_dsi_info *mipi_dsi,
  211388. + bool init)
  211389. +{
  211390. + u32 val;
  211391. + u32 lane_byte_clk_period;
  211392. + struct fb_videomode *mode = mipi_dsi->mode;
  211393. + struct mipi_lcd_config *lcd_config = mipi_dsi->lcd_config;
  211394. +
  211395. + if (init) {
  211396. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  211397. + DSI_PWRUP_RESET);
  211398. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ,
  211399. + DSI_PHY_RSTZ_RST);
  211400. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CLKMGR_CFG,
  211401. + DSI_CLKMGR_CFG_CLK_DIV);
  211402. +
  211403. + if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
  211404. + val = DSI_DPI_CFG_VSYNC_ACT_LOW;
  211405. + if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
  211406. + val |= DSI_DPI_CFG_HSYNC_ACT_LOW;
  211407. + if ((mode->sync & FB_SYNC_OE_LOW_ACT))
  211408. + val |= DSI_DPI_CFG_DATAEN_ACT_LOW;
  211409. + if (MIPI_RGB666_LOOSELY == lcd_config->dpi_fmt)
  211410. + val |= DSI_DPI_CFG_EN18LOOSELY;
  211411. + val |= (lcd_config->dpi_fmt & DSI_DPI_CFG_COLORCODE_MASK)
  211412. + << DSI_DPI_CFG_COLORCODE_SHIFT;
  211413. + val |= (lcd_config->virtual_ch & DSI_DPI_CFG_VID_MASK)
  211414. + << DSI_DPI_CFG_VID_SHIFT;
  211415. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_DPI_CFG, val);
  211416. +
  211417. + val = DSI_PCKHDL_CFG_EN_BTA |
  211418. + DSI_PCKHDL_CFG_EN_ECC_RX |
  211419. + DSI_PCKHDL_CFG_EN_CRC_RX;
  211420. +
  211421. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PCKHDL_CFG, val);
  211422. +
  211423. + val = (mode->xres & DSI_VID_PKT_CFG_VID_PKT_SZ_MASK)
  211424. + << DSI_VID_PKT_CFG_VID_PKT_SZ_SHIFT;
  211425. + val |= (NUMBER_OF_CHUNKS & DSI_VID_PKT_CFG_NUM_CHUNKS_MASK)
  211426. + << DSI_VID_PKT_CFG_NUM_CHUNKS_SHIFT;
  211427. + val |= (NULL_PKT_SIZE & DSI_VID_PKT_CFG_NULL_PKT_SZ_MASK)
  211428. + << DSI_VID_PKT_CFG_NULL_PKT_SZ_SHIFT;
  211429. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_PKT_CFG, val);
  211430. +
  211431. + /* enable LP mode when TX DCS cmd and enable DSI command mode */
  211432. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG,
  211433. + MIPI_DSI_CMD_MODE_CFG_EN_LOWPOWER);
  211434. +
  211435. + /* mipi lane byte clk period in ns unit */
  211436. + lane_byte_clk_period = NS2PS_RATIO /
  211437. + (lcd_config->max_phy_clk / BITS_PER_BYTE);
  211438. + val = ROUND_UP(mode->hsync_len * mode->pixclock /
  211439. + NS2PS_RATIO / lane_byte_clk_period)
  211440. + << DSI_TME_LINE_CFG_HSA_TIME_SHIFT;
  211441. + val |= ROUND_UP(mode->left_margin * mode->pixclock /
  211442. + NS2PS_RATIO / lane_byte_clk_period)
  211443. + << DSI_TME_LINE_CFG_HBP_TIME_SHIFT;
  211444. + val |= ROUND_UP((mode->left_margin + mode->right_margin +
  211445. + mode->hsync_len + mode->xres) * mode->pixclock
  211446. + / NS2PS_RATIO / lane_byte_clk_period)
  211447. + << DSI_TME_LINE_CFG_HLINE_TIME_SHIFT;
  211448. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_TMR_LINE_CFG, val);
  211449. +
  211450. + val = ((mode->vsync_len & DSI_VTIMING_CFG_VSA_LINES_MASK)
  211451. + << DSI_VTIMING_CFG_VSA_LINES_SHIFT);
  211452. + val |= ((mode->upper_margin & DSI_VTIMING_CFG_VBP_LINES_MASK)
  211453. + << DSI_VTIMING_CFG_VBP_LINES_SHIFT);
  211454. + val |= ((mode->lower_margin & DSI_VTIMING_CFG_VFP_LINES_MASK)
  211455. + << DSI_VTIMING_CFG_VFP_LINES_SHIFT);
  211456. + val |= ((mode->yres & DSI_VTIMING_CFG_V_ACT_LINES_MASK)
  211457. + << DSI_VTIMING_CFG_V_ACT_LINES_SHIFT);
  211458. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VTIMING_CFG, val);
  211459. +
  211460. + val = ((PHY_BTA_MAXTIME & DSI_PHY_TMR_CFG_BTA_TIME_MASK)
  211461. + << DSI_PHY_TMR_CFG_BTA_TIME_SHIFT);
  211462. + val |= ((PHY_LP2HS_MAXTIME & DSI_PHY_TMR_CFG_LP2HS_TIME_MASK)
  211463. + << DSI_PHY_TMR_CFG_LP2HS_TIME_SHIFT);
  211464. + val |= ((PHY_HS2LP_MAXTIME & DSI_PHY_TMR_CFG_HS2LP_TIME_MASK)
  211465. + << DSI_PHY_TMR_CFG_HS2LP_TIME_SHIFT);
  211466. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TMR_CFG, val);
  211467. +
  211468. + val = (((lcd_config->data_lane_num - 1) &
  211469. + DSI_PHY_IF_CFG_N_LANES_MASK)
  211470. + << DSI_PHY_IF_CFG_N_LANES_SHIFT);
  211471. + val |= ((PHY_STOP_WAIT_TIME & DSI_PHY_IF_CFG_WAIT_TIME_MASK)
  211472. + << DSI_PHY_IF_CFG_WAIT_TIME_SHIFT);
  211473. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CFG, val);
  211474. +
  211475. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST0, &val);
  211476. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST1, &val);
  211477. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_ERROR_MSK0, 0);
  211478. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_ERROR_MSK1, 0);
  211479. +
  211480. + mipi_dsi_dphy_init(mipi_dsi, DSI_PHY_CLK_INIT_COMMAND,
  211481. + mipi_dsi->dphy_pll_config);
  211482. + } else {
  211483. + mipi_dsi_dphy_init(mipi_dsi, DSI_PHY_CLK_INIT_COMMAND,
  211484. + mipi_dsi->dphy_pll_config);
  211485. + }
  211486. +}
  211487. +
  211488. +static void mipi_dsi_disable_controller(struct mipi_dsi_info *mipi_dsi)
  211489. +{
  211490. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
  211491. + DSI_PHY_IF_CTRL_RESET);
  211492. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP, DSI_PWRUP_RESET);
  211493. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ, DSI_PHY_RSTZ_RST);
  211494. +}
  211495. +
  211496. +static irqreturn_t mipi_dsi_irq_handler(int irq, void *data)
  211497. +{
  211498. + u32 mask0;
  211499. + u32 mask1;
  211500. + u32 status0;
  211501. + u32 status1;
  211502. + struct mipi_dsi_info *mipi_dsi;
  211503. +
  211504. + mipi_dsi = (struct mipi_dsi_info *)data;
  211505. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST0, &status0);
  211506. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST1, &status1);
  211507. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_MSK0, &mask0);
  211508. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_MSK1, &mask1);
  211509. +
  211510. + if ((status0 & (~mask0)) || (status1 & (~mask1))) {
  211511. + dev_err(&mipi_dsi->pdev->dev,
  211512. + "mipi_dsi IRQ status0:0x%x, status1:0x%x!\n",
  211513. + status0, status1);
  211514. + }
  211515. +
  211516. + return IRQ_HANDLED;
  211517. +}
  211518. +
  211519. +static inline void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,
  211520. + bool cmd_mode)
  211521. +{
  211522. + u32 val;
  211523. +
  211524. + if (cmd_mode) {
  211525. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  211526. + DSI_PWRUP_RESET);
  211527. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
  211528. + val |= MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
  211529. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
  211530. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, 0);
  211531. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  211532. + DSI_PWRUP_POWERUP);
  211533. + } else {
  211534. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  211535. + DSI_PWRUP_RESET);
  211536. + /* Disable Command mode when tranfering video data */
  211537. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
  211538. + val &= ~MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
  211539. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
  211540. + val = DSI_VID_MODE_CFG_EN | DSI_VID_MODE_CFG_EN_BURSTMODE |
  211541. + DSI_VID_MODE_CFG_EN_LP_MODE;
  211542. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, val);
  211543. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  211544. + DSI_PWRUP_POWERUP);
  211545. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
  211546. + DSI_PHY_IF_CTRL_TX_REQ_CLK_HS);
  211547. + }
  211548. +}
  211549. +
  211550. +static int mipi_dsi_power_on(struct mxc_dispdrv_handle *disp)
  211551. +{
  211552. + int err;
  211553. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  211554. +
  211555. + if (!mipi_dsi->dsi_power_on) {
  211556. + clk_prepare_enable(mipi_dsi->dphy_clk);
  211557. + clk_prepare_enable(mipi_dsi->cfg_clk);
  211558. + mipi_dsi_enable_controller(mipi_dsi, false);
  211559. + mipi_dsi_set_mode(mipi_dsi, false);
  211560. + /* host send pclk/hsync/vsync for two frames before sleep-out */
  211561. + msleep((1000/mipi_dsi->mode->refresh + 1) << 1);
  211562. + mipi_dsi_set_mode(mipi_dsi, true);
  211563. + err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_EXIT_SLEEP_MODE,
  211564. + NULL, 0);
  211565. + if (err) {
  211566. + dev_err(&mipi_dsi->pdev->dev,
  211567. + "MIPI DSI DCS Command sleep-in error!\n");
  211568. + }
  211569. + msleep(MIPI_LCD_SLEEP_MODE_DELAY);
  211570. + mipi_dsi_set_mode(mipi_dsi, false);
  211571. + mipi_dsi->dsi_power_on = 1;
  211572. + }
  211573. +
  211574. + return 0;
  211575. +}
  211576. +
  211577. +void mipi_dsi_power_off(struct mxc_dispdrv_handle *disp)
  211578. +{
  211579. + int err;
  211580. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  211581. +
  211582. + if (mipi_dsi->dsi_power_on) {
  211583. + mipi_dsi_set_mode(mipi_dsi, true);
  211584. + err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_ENTER_SLEEP_MODE,
  211585. + NULL, 0);
  211586. + if (err) {
  211587. + dev_err(&mipi_dsi->pdev->dev,
  211588. + "MIPI DSI DCS Command display on error!\n");
  211589. + }
  211590. + /* To allow time for the supply voltages
  211591. + * and clock circuits to stabilize.
  211592. + */
  211593. + msleep(5);
  211594. + /* video stream timing on */
  211595. + mipi_dsi_set_mode(mipi_dsi, false);
  211596. + msleep(MIPI_LCD_SLEEP_MODE_DELAY);
  211597. +
  211598. + mipi_dsi_set_mode(mipi_dsi, true);
  211599. + mipi_dsi_disable_controller(mipi_dsi);
  211600. + mipi_dsi->dsi_power_on = 0;
  211601. + clk_disable_unprepare(mipi_dsi->dphy_clk);
  211602. + clk_disable_unprepare(mipi_dsi->cfg_clk);
  211603. + }
  211604. +}
  211605. +
  211606. +static int mipi_dsi_lcd_init(struct mipi_dsi_info *mipi_dsi,
  211607. + struct mxc_dispdrv_setting *setting)
  211608. +{
  211609. + int err;
  211610. + int size;
  211611. + int i;
  211612. + struct fb_videomode *mipi_lcd_modedb;
  211613. + struct fb_videomode mode;
  211614. + struct device *dev = &mipi_dsi->pdev->dev;
  211615. +
  211616. + for (i = 0; i < ARRAY_SIZE(mipi_dsi_lcd_db); i++) {
  211617. + if (!strcmp(mipi_dsi->lcd_panel,
  211618. + mipi_dsi_lcd_db[i].lcd_panel)) {
  211619. + mipi_dsi->lcd_callback =
  211620. + &mipi_dsi_lcd_db[i].lcd_callback;
  211621. + break;
  211622. + }
  211623. + }
  211624. + if (i == ARRAY_SIZE(mipi_dsi_lcd_db)) {
  211625. + dev_err(dev, "failed to find supported lcd panel.\n");
  211626. + return -EINVAL;
  211627. + }
  211628. + /* get the videomode in the order: cmdline->platform data->driver */
  211629. + mipi_dsi->lcd_callback->get_mipi_lcd_videomode(&mipi_lcd_modedb, &size,
  211630. + &mipi_dsi->lcd_config);
  211631. + err = fb_find_mode(&setting->fbi->var, setting->fbi,
  211632. + setting->dft_mode_str,
  211633. + mipi_lcd_modedb, size, NULL,
  211634. + setting->default_bpp);
  211635. + if (err != 1)
  211636. + fb_videomode_to_var(&setting->fbi->var, mipi_lcd_modedb);
  211637. +
  211638. + INIT_LIST_HEAD(&setting->fbi->modelist);
  211639. + for (i = 0; i < size; i++) {
  211640. + fb_var_to_videomode(&mode, &setting->fbi->var);
  211641. + if (fb_mode_is_equal(&mode, mipi_lcd_modedb + i)) {
  211642. + err = fb_add_videomode(mipi_lcd_modedb + i,
  211643. + &setting->fbi->modelist);
  211644. + /* Note: only support fb mode from driver */
  211645. + mipi_dsi->mode = mipi_lcd_modedb + i;
  211646. + break;
  211647. + }
  211648. + }
  211649. + if ((err < 0) || (size == i)) {
  211650. + dev_err(dev, "failed to add videomode.\n");
  211651. + return err;
  211652. + }
  211653. +
  211654. + for (i = 0; i < ARRAY_SIZE(mipi_dsi_phy_pll_clk_table); i++) {
  211655. + if (mipi_dsi_phy_pll_clk_table[i].max_phy_clk <
  211656. + mipi_dsi->lcd_config->max_phy_clk)
  211657. + break;
  211658. + }
  211659. + if ((i == ARRAY_SIZE(mipi_dsi_phy_pll_clk_table)) ||
  211660. + (mipi_dsi->lcd_config->max_phy_clk >
  211661. + mipi_dsi_phy_pll_clk_table[0].max_phy_clk)) {
  211662. + dev_err(dev, "failed to find data in"
  211663. + "mipi_dsi_phy_pll_clk_table.\n");
  211664. + return -EINVAL;
  211665. + }
  211666. + mipi_dsi->dphy_pll_config = mipi_dsi_phy_pll_clk_table[--i].config;
  211667. + dev_dbg(dev, "dphy_pll_config:0x%x.\n", mipi_dsi->dphy_pll_config);
  211668. +
  211669. + return 0;
  211670. +}
  211671. +
  211672. +int mipi_dsi_enable(struct mxc_dispdrv_handle *disp)
  211673. +{
  211674. + int err;
  211675. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  211676. +
  211677. + if (!mipi_dsi->lcd_inited) {
  211678. + err = clk_prepare_enable(mipi_dsi->dphy_clk);
  211679. + err |= clk_prepare_enable(mipi_dsi->cfg_clk);
  211680. + if (err)
  211681. + dev_err(&mipi_dsi->pdev->dev,
  211682. + "clk enable error:%d!\n", err);
  211683. + mipi_dsi_enable_controller(mipi_dsi, true);
  211684. + err = mipi_dsi->lcd_callback->mipi_lcd_setup(
  211685. + mipi_dsi);
  211686. + if (err < 0) {
  211687. + dev_err(&mipi_dsi->pdev->dev,
  211688. + "failed to init mipi lcd.");
  211689. + clk_disable_unprepare(mipi_dsi->dphy_clk);
  211690. + clk_disable_unprepare(mipi_dsi->cfg_clk);
  211691. + return err;
  211692. + }
  211693. + mipi_dsi_set_mode(mipi_dsi, false);
  211694. + mipi_dsi->dsi_power_on = 1;
  211695. + mipi_dsi->lcd_inited = 1;
  211696. + }
  211697. + mipi_dsi_power_on(mipi_dsi->disp_mipi);
  211698. +
  211699. + return 0;
  211700. +}
  211701. +
  211702. +static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
  211703. + struct mxc_dispdrv_setting *setting)
  211704. +{
  211705. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  211706. + struct device *dev = &mipi_dsi->pdev->dev;
  211707. + int ret = 0;
  211708. +
  211709. + if (!valid_mode(setting->if_fmt)) {
  211710. + dev_warn(dev, "Input pixel format not valid"
  211711. + "use default RGB24\n");
  211712. + setting->if_fmt = IPU_PIX_FMT_RGB24;
  211713. + }
  211714. +
  211715. + setting->dev_id = mipi_dsi->dev_id;
  211716. + setting->disp_id = mipi_dsi->disp_id;
  211717. +
  211718. + ret = mipi_dsi_lcd_init(mipi_dsi, setting);
  211719. + if (ret) {
  211720. + dev_err(dev, "failed to init mipi dsi lcd\n");
  211721. + return ret;
  211722. + }
  211723. +
  211724. + dev_dbg(dev, "MIPI DSI dispdrv inited!\n");
  211725. + return ret;
  211726. +}
  211727. +
  211728. +static void mipi_dsi_disp_deinit(struct mxc_dispdrv_handle *disp)
  211729. +{
  211730. + struct mipi_dsi_info *mipi_dsi;
  211731. +
  211732. + mipi_dsi = mxc_dispdrv_getdata(disp);
  211733. +
  211734. + mipi_dsi_power_off(mipi_dsi->disp_mipi);
  211735. + if (mipi_dsi->bl)
  211736. + backlight_device_unregister(mipi_dsi->bl);
  211737. +}
  211738. +
  211739. +static struct mxc_dispdrv_driver mipi_dsi_drv = {
  211740. + .name = DISPDRV_MIPI,
  211741. + .init = mipi_dsi_disp_init,
  211742. + .deinit = mipi_dsi_disp_deinit,
  211743. + .enable = mipi_dsi_enable,
  211744. + .disable = mipi_dsi_power_off,
  211745. +};
  211746. +
  211747. +static int imx6q_mipi_dsi_get_mux(int dev_id, int disp_id)
  211748. +{
  211749. + if (dev_id > 1 || disp_id > 1)
  211750. + return -EINVAL;
  211751. +
  211752. + return (dev_id << 5) | (disp_id << 4);
  211753. +}
  211754. +
  211755. +static struct mipi_dsi_bus_mux imx6q_mipi_dsi_mux[] = {
  211756. + {
  211757. + .reg = IOMUXC_GPR3,
  211758. + .mask = IMX6Q_GPR3_MIPI_MUX_CTL_MASK,
  211759. + .get_mux = imx6q_mipi_dsi_get_mux,
  211760. + },
  211761. +};
  211762. +
  211763. +static int imx6dl_mipi_dsi_get_mux(int dev_id, int disp_id)
  211764. +{
  211765. + if (dev_id > 1 || disp_id > 1)
  211766. + return -EINVAL;
  211767. +
  211768. + /* MIPI DSI source is LCDIF */
  211769. + if (dev_id)
  211770. + disp_id = 0;
  211771. +
  211772. + return (dev_id << 5) | (disp_id << 4);
  211773. +}
  211774. +
  211775. +static struct mipi_dsi_bus_mux imx6dl_mipi_dsi_mux[] = {
  211776. + {
  211777. + .reg = IOMUXC_GPR3,
  211778. + .mask = IMX6Q_GPR3_MIPI_MUX_CTL_MASK,
  211779. + .get_mux = imx6dl_mipi_dsi_get_mux,
  211780. + },
  211781. +};
  211782. +
  211783. +static const struct of_device_id imx_mipi_dsi_dt_ids[] = {
  211784. + { .compatible = "fsl,imx6q-mipi-dsi", .data = imx6q_mipi_dsi_mux, },
  211785. + { .compatible = "fsl,imx6dl-mipi-dsi", .data = imx6dl_mipi_dsi_mux, },
  211786. + { }
  211787. +};
  211788. +MODULE_DEVICE_TABLE(of, imx_mipi_dsi_dt_ids);
  211789. +
  211790. +/**
  211791. + * This function is called by the driver framework to initialize the MIPI DSI
  211792. + * device.
  211793. + *
  211794. + * @param pdev The device structure for the MIPI DSI passed in by the
  211795. + * driver framework.
  211796. + *
  211797. + * @return Returns 0 on success or negative error code on error
  211798. + */
  211799. +static int mipi_dsi_probe(struct platform_device *pdev)
  211800. +{
  211801. + struct device_node *np = pdev->dev.of_node;
  211802. + const struct of_device_id *of_id =
  211803. + of_match_device(of_match_ptr(imx_mipi_dsi_dt_ids),
  211804. + &pdev->dev);
  211805. + struct mipi_dsi_info *mipi_dsi;
  211806. + struct resource *res;
  211807. + u32 dev_id, disp_id;
  211808. + const char *lcd_panel;
  211809. + unsigned int mux;
  211810. + int ret = 0;
  211811. +
  211812. + mipi_dsi = devm_kzalloc(&pdev->dev, sizeof(*mipi_dsi), GFP_KERNEL);
  211813. + if (!mipi_dsi)
  211814. + return -ENOMEM;
  211815. +
  211816. + ret = of_property_read_string(np, "lcd_panel", &lcd_panel);
  211817. + if (ret) {
  211818. + dev_err(&pdev->dev, "failed to read of property lcd_panel\n");
  211819. + return ret;
  211820. + }
  211821. +
  211822. + ret = of_property_read_u32(np, "dev_id", &dev_id);
  211823. + if (ret) {
  211824. + dev_err(&pdev->dev, "failed to read of property dev_id\n");
  211825. + return ret;
  211826. + }
  211827. + ret = of_property_read_u32(np, "disp_id", &disp_id);
  211828. + if (ret) {
  211829. + dev_err(&pdev->dev, "failed to read of property disp_id\n");
  211830. + return ret;
  211831. + }
  211832. + mipi_dsi->dev_id = dev_id;
  211833. + mipi_dsi->disp_id = disp_id;
  211834. +
  211835. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  211836. + if (!res) {
  211837. + dev_err(&pdev->dev, "failed to get platform resource 0\n");
  211838. + return -ENODEV;
  211839. + }
  211840. +
  211841. + if (!devm_request_mem_region(&pdev->dev, res->start,
  211842. + resource_size(res), pdev->name))
  211843. + return -EBUSY;
  211844. +
  211845. + mipi_dsi->mmio_base = devm_ioremap(&pdev->dev, res->start,
  211846. + resource_size(res));
  211847. + if (!mipi_dsi->mmio_base)
  211848. + return -EBUSY;
  211849. +
  211850. + mipi_dsi->irq = platform_get_irq(pdev, 0);
  211851. + if (mipi_dsi->irq < 0) {
  211852. + dev_err(&pdev->dev, "failed get device irq\n");
  211853. + return -ENODEV;
  211854. + }
  211855. +
  211856. + ret = devm_request_irq(&pdev->dev, mipi_dsi->irq,
  211857. + mipi_dsi_irq_handler,
  211858. + 0, "mipi_dsi", mipi_dsi);
  211859. + if (ret) {
  211860. + dev_err(&pdev->dev, "failed to request irq\n");
  211861. + return ret;
  211862. + }
  211863. +
  211864. + mipi_dsi->dphy_clk = devm_clk_get(&pdev->dev, "mipi_pllref_clk");
  211865. + if (IS_ERR(mipi_dsi->dphy_clk)) {
  211866. + dev_err(&pdev->dev, "failed to get dphy pll_ref_clk\n");
  211867. + return PTR_ERR(mipi_dsi->dphy_clk);
  211868. + }
  211869. +
  211870. + mipi_dsi->cfg_clk = devm_clk_get(&pdev->dev, "mipi_cfg_clk");
  211871. + if (IS_ERR(mipi_dsi->cfg_clk)) {
  211872. + dev_err(&pdev->dev, "failed to get cfg_clk\n");
  211873. + return PTR_ERR(mipi_dsi->cfg_clk);
  211874. + }
  211875. +
  211876. + mipi_dsi->disp_power_on = devm_regulator_get(&pdev->dev,
  211877. + "disp-power-on");
  211878. + if (!IS_ERR(mipi_dsi->disp_power_on)) {
  211879. + ret = regulator_enable(mipi_dsi->disp_power_on);
  211880. + if (ret) {
  211881. + dev_err(&pdev->dev, "failed to enable display "
  211882. + "power regulator, err=%d\n", ret);
  211883. + return ret;
  211884. + }
  211885. + } else {
  211886. + mipi_dsi->disp_power_on = NULL;
  211887. + }
  211888. +
  211889. + ret = device_reset(&pdev->dev);
  211890. + if (ret) {
  211891. + dev_err(&pdev->dev, "failed to reset: %d\n", ret);
  211892. + goto dev_reset_fail;
  211893. + }
  211894. +
  211895. + if (of_id)
  211896. + mipi_dsi->bus_mux = of_id->data;
  211897. +
  211898. + mipi_dsi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
  211899. + if (IS_ERR(mipi_dsi->regmap)) {
  211900. + dev_err(&pdev->dev, "failed to get parent regmap\n");
  211901. + ret = PTR_ERR(mipi_dsi->regmap);
  211902. + goto get_parent_regmap_fail;
  211903. + }
  211904. +
  211905. + mux = mipi_dsi->bus_mux->get_mux(dev_id, disp_id);
  211906. + if (mux >= 0)
  211907. + regmap_update_bits(mipi_dsi->regmap, mipi_dsi->bus_mux->reg,
  211908. + mipi_dsi->bus_mux->mask, mux);
  211909. + else
  211910. + dev_warn(&pdev->dev, "invalid dev_id or disp_id muxing\n");
  211911. +
  211912. + mipi_dsi->lcd_panel = kstrdup(lcd_panel, GFP_KERNEL);
  211913. + if (!mipi_dsi->lcd_panel) {
  211914. + dev_err(&pdev->dev, "failed to allocate lcd panel name\n");
  211915. + ret = -ENOMEM;
  211916. + goto kstrdup_fail;
  211917. + }
  211918. +
  211919. + mipi_dsi->pdev = pdev;
  211920. + mipi_dsi->disp_mipi = mxc_dispdrv_register(&mipi_dsi_drv);
  211921. + if (IS_ERR(mipi_dsi->disp_mipi)) {
  211922. + dev_err(&pdev->dev, "mxc_dispdrv_register error\n");
  211923. + ret = PTR_ERR(mipi_dsi->disp_mipi);
  211924. + goto dispdrv_reg_fail;
  211925. + }
  211926. +
  211927. + mxc_dispdrv_setdata(mipi_dsi->disp_mipi, mipi_dsi);
  211928. + dev_set_drvdata(&pdev->dev, mipi_dsi);
  211929. +
  211930. + dev_info(&pdev->dev, "i.MX MIPI DSI driver probed\n");
  211931. + return ret;
  211932. +
  211933. +dispdrv_reg_fail:
  211934. + kfree(mipi_dsi->lcd_panel);
  211935. +kstrdup_fail:
  211936. +get_parent_regmap_fail:
  211937. +dev_reset_fail:
  211938. + if (mipi_dsi->disp_power_on)
  211939. + regulator_disable(mipi_dsi->disp_power_on);
  211940. + return ret;
  211941. +}
  211942. +
  211943. +static void mipi_dsi_shutdown(struct platform_device *pdev)
  211944. +{
  211945. + struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
  211946. +
  211947. + mipi_dsi_power_off(mipi_dsi->disp_mipi);
  211948. +}
  211949. +
  211950. +static int mipi_dsi_remove(struct platform_device *pdev)
  211951. +{
  211952. + struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
  211953. +
  211954. + mxc_dispdrv_puthandle(mipi_dsi->disp_mipi);
  211955. + mxc_dispdrv_unregister(mipi_dsi->disp_mipi);
  211956. +
  211957. + if (mipi_dsi->disp_power_on)
  211958. + regulator_disable(mipi_dsi->disp_power_on);
  211959. +
  211960. + kfree(mipi_dsi->lcd_panel);
  211961. + dev_set_drvdata(&pdev->dev, NULL);
  211962. +
  211963. + return 0;
  211964. +}
  211965. +
  211966. +static struct platform_driver mipi_dsi_driver = {
  211967. + .driver = {
  211968. + .of_match_table = imx_mipi_dsi_dt_ids,
  211969. + .name = "mxc_mipi_dsi",
  211970. + },
  211971. + .probe = mipi_dsi_probe,
  211972. + .remove = mipi_dsi_remove,
  211973. + .shutdown = mipi_dsi_shutdown,
  211974. +};
  211975. +
  211976. +static int __init mipi_dsi_init(void)
  211977. +{
  211978. + int err;
  211979. +
  211980. + err = platform_driver_register(&mipi_dsi_driver);
  211981. + if (err) {
  211982. + pr_err("mipi_dsi_driver register failed\n");
  211983. + return -ENODEV;
  211984. + }
  211985. + pr_info("MIPI DSI driver module loaded\n");
  211986. + return 0;
  211987. +}
  211988. +
  211989. +static void __exit mipi_dsi_cleanup(void)
  211990. +{
  211991. + platform_driver_unregister(&mipi_dsi_driver);
  211992. +}
  211993. +
  211994. +module_init(mipi_dsi_init);
  211995. +module_exit(mipi_dsi_cleanup);
  211996. +
  211997. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  211998. +MODULE_DESCRIPTION("i.MX MIPI DSI driver");
  211999. +MODULE_LICENSE("GPL");
  212000. diff -Nur linux-3.14.14/drivers/video/mxc/mipi_dsi.h linux-imx6-3.14/drivers/video/mxc/mipi_dsi.h
  212001. --- linux-3.14.14/drivers/video/mxc/mipi_dsi.h 1969-12-31 18:00:00.000000000 -0600
  212002. +++ linux-imx6-3.14/drivers/video/mxc/mipi_dsi.h 2014-12-08 00:31:54.860418001 -0600
  212003. @@ -0,0 +1,112 @@
  212004. +/*
  212005. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  212006. + *
  212007. + * This program is free software; you can redistribute it and/or modify
  212008. + * it under the terms of the GNU General Public License as published by
  212009. + * the Free Software Foundation; either version 2 of the License, or
  212010. + * (at your option) any later version.
  212011. +
  212012. + * This program is distributed in the hope that it will be useful,
  212013. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  212014. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  212015. + * GNU General Public License for more details.
  212016. +
  212017. + * You should have received a copy of the GNU General Public License along
  212018. + * with this program; if not, write to the Free Software Foundation, Inc.,
  212019. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  212020. + */
  212021. +
  212022. +#ifndef __MIPI_DSI_H__
  212023. +#define __MIPI_DSI_H__
  212024. +
  212025. +#include <linux/regmap.h>
  212026. +
  212027. +#ifdef DEBUG
  212028. +#define mipi_dbg(fmt, ...) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
  212029. +#else
  212030. +#define mipi_dbg(fmt, ...)
  212031. +#endif
  212032. +
  212033. +#define DSI_CMD_BUF_MAXSIZE (32)
  212034. +
  212035. +/* DPI interface pixel color coding map */
  212036. +enum mipi_dsi_dpi_fmt {
  212037. + MIPI_RGB565_PACKED = 0,
  212038. + MIPI_RGB565_LOOSELY,
  212039. + MIPI_RGB565_CONFIG3,
  212040. + MIPI_RGB666_PACKED,
  212041. + MIPI_RGB666_LOOSELY,
  212042. + MIPI_RGB888,
  212043. +};
  212044. +
  212045. +struct mipi_lcd_config {
  212046. + u32 virtual_ch;
  212047. + u32 data_lane_num;
  212048. + /* device max DPHY clock in MHz unit */
  212049. + u32 max_phy_clk;
  212050. + enum mipi_dsi_dpi_fmt dpi_fmt;
  212051. +};
  212052. +
  212053. +struct mipi_dsi_info;
  212054. +struct mipi_dsi_lcd_callback {
  212055. + /* callback for lcd panel operation */
  212056. + void (*get_mipi_lcd_videomode)(struct fb_videomode **, int *,
  212057. + struct mipi_lcd_config **);
  212058. + int (*mipi_lcd_setup)(struct mipi_dsi_info *);
  212059. +
  212060. +};
  212061. +
  212062. +struct mipi_dsi_match_lcd {
  212063. + char *lcd_panel;
  212064. + struct mipi_dsi_lcd_callback lcd_callback;
  212065. +};
  212066. +
  212067. +struct mipi_dsi_bus_mux {
  212068. + int reg;
  212069. + int mask;
  212070. + int (*get_mux) (int dev_id, int disp_id);
  212071. +};
  212072. +
  212073. +/* driver private data */
  212074. +struct mipi_dsi_info {
  212075. + struct platform_device *pdev;
  212076. + void __iomem *mmio_base;
  212077. + struct regmap *regmap;
  212078. + const struct mipi_dsi_bus_mux *bus_mux;
  212079. + int dsi_power_on;
  212080. + int lcd_inited;
  212081. + u32 dphy_pll_config;
  212082. + int dev_id;
  212083. + int disp_id;
  212084. + char *lcd_panel;
  212085. + int irq;
  212086. + struct clk *dphy_clk;
  212087. + struct clk *cfg_clk;
  212088. + struct mxc_dispdrv_handle *disp_mipi;
  212089. + struct fb_videomode *mode;
  212090. + struct regulator *disp_power_on;
  212091. + struct mipi_lcd_config *lcd_config;
  212092. + /* board related power control */
  212093. + struct backlight_device *bl;
  212094. + /* callback for lcd panel operation */
  212095. + struct mipi_dsi_lcd_callback *lcd_callback;
  212096. +};
  212097. +
  212098. +int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi,
  212099. + u8 data_type, const u32 *buf, int len);
  212100. +int mipi_dsi_pkt_read(struct mipi_dsi_info *mipi,
  212101. + u8 data_type, u32 *buf, int len);
  212102. +int mipi_dsi_dcs_cmd(struct mipi_dsi_info *mipi,
  212103. + u8 cmd, const u32 *param, int num);
  212104. +
  212105. +#ifdef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
  212106. +void mipid_hx8369_get_lcd_videomode(struct fb_videomode **mode, int *size,
  212107. + struct mipi_lcd_config **data);
  212108. +int mipid_hx8369_lcd_setup(struct mipi_dsi_info *);
  212109. +#endif
  212110. +
  212111. +#ifndef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
  212112. +#error "Please configure MIPI LCD panel, we cannot find one!"
  212113. +#endif
  212114. +
  212115. +#endif
  212116. diff -Nur linux-3.14.14/drivers/video/mxc/mxc_dispdrv.c linux-imx6-3.14/drivers/video/mxc/mxc_dispdrv.c
  212117. --- linux-3.14.14/drivers/video/mxc/mxc_dispdrv.c 1969-12-31 18:00:00.000000000 -0600
  212118. +++ linux-imx6-3.14/drivers/video/mxc/mxc_dispdrv.c 2014-12-08 00:31:54.860418001 -0600
  212119. @@ -0,0 +1,150 @@
  212120. +/*
  212121. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  212122. + */
  212123. +
  212124. +/*
  212125. + * The code contained herein is licensed under the GNU General Public
  212126. + * License. You may obtain a copy of the GNU General Public License
  212127. + * Version 2 or later at the following locations:
  212128. + *
  212129. + * http://www.opensource.org/licenses/gpl-license.html
  212130. + * http://www.gnu.org/copyleft/gpl.html
  212131. + */
  212132. +
  212133. +/*!
  212134. + * @file mxc_dispdrv.c
  212135. + * @brief mxc display driver framework.
  212136. + *
  212137. + * A display device driver could call mxc_dispdrv_register(drv) in its dev_probe() function.
  212138. + * Move all dev_probe() things into mxc_dispdrv_driver->init(), init() function should init
  212139. + * and feedback setting;
  212140. + * Necessary deferred operations can be done in mxc_dispdrv_driver->post_init(),
  212141. + * after dev_id and disp_id pass usage check;
  212142. + * Move all dev_remove() things into mxc_dispdrv_driver->deinit();
  212143. + * Move all dev_suspend() things into fb_notifier for SUSPEND, if there is;
  212144. + * Move all dev_resume() things into fb_notifier for RESUME, if there is;
  212145. + *
  212146. + * ipuv3 fb driver could call mxc_dispdrv_gethandle(name, setting) before a fb
  212147. + * need be added, with fbi param passing by setting, after
  212148. + * mxc_dispdrv_gethandle() return, FB driver should get the basic setting
  212149. + * about fbi info and ipuv3-hw (ipu_id and disp_id).
  212150. + *
  212151. + * @ingroup Framebuffer
  212152. + */
  212153. +
  212154. +#include <linux/kernel.h>
  212155. +#include <linux/module.h>
  212156. +#include <linux/list.h>
  212157. +#include <linux/mutex.h>
  212158. +#include <linux/slab.h>
  212159. +#include <linux/err.h>
  212160. +#include <linux/string.h>
  212161. +#include "mxc_dispdrv.h"
  212162. +
  212163. +static LIST_HEAD(dispdrv_list);
  212164. +static DEFINE_MUTEX(dispdrv_lock);
  212165. +
  212166. +struct mxc_dispdrv_entry {
  212167. + /* Note: drv always the first element */
  212168. + struct mxc_dispdrv_driver *drv;
  212169. + bool active;
  212170. + void *priv;
  212171. + struct list_head list;
  212172. +};
  212173. +
  212174. +struct mxc_dispdrv_handle *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv)
  212175. +{
  212176. + struct mxc_dispdrv_entry *new;
  212177. +
  212178. + mutex_lock(&dispdrv_lock);
  212179. +
  212180. + new = kzalloc(sizeof(struct mxc_dispdrv_entry), GFP_KERNEL);
  212181. + if (!new) {
  212182. + mutex_unlock(&dispdrv_lock);
  212183. + return ERR_PTR(-ENOMEM);
  212184. + }
  212185. +
  212186. + new->drv = drv;
  212187. + list_add_tail(&new->list, &dispdrv_list);
  212188. +
  212189. + mutex_unlock(&dispdrv_lock);
  212190. +
  212191. + return (struct mxc_dispdrv_handle *)new;
  212192. +}
  212193. +EXPORT_SYMBOL_GPL(mxc_dispdrv_register);
  212194. +
  212195. +int mxc_dispdrv_unregister(struct mxc_dispdrv_handle *handle)
  212196. +{
  212197. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  212198. +
  212199. + if (entry) {
  212200. + mutex_lock(&dispdrv_lock);
  212201. + list_del(&entry->list);
  212202. + mutex_unlock(&dispdrv_lock);
  212203. + kfree(entry);
  212204. + return 0;
  212205. + } else
  212206. + return -EINVAL;
  212207. +}
  212208. +EXPORT_SYMBOL_GPL(mxc_dispdrv_unregister);
  212209. +
  212210. +struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name,
  212211. + struct mxc_dispdrv_setting *setting)
  212212. +{
  212213. + int ret, found = 0;
  212214. + struct mxc_dispdrv_entry *entry;
  212215. +
  212216. + mutex_lock(&dispdrv_lock);
  212217. + list_for_each_entry(entry, &dispdrv_list, list) {
  212218. + if (!strcmp(entry->drv->name, name) && (entry->drv->init)) {
  212219. + ret = entry->drv->init((struct mxc_dispdrv_handle *)
  212220. + entry, setting);
  212221. + if (ret >= 0) {
  212222. + entry->active = true;
  212223. + found = 1;
  212224. + break;
  212225. + }
  212226. + }
  212227. + }
  212228. + mutex_unlock(&dispdrv_lock);
  212229. +
  212230. + return found ? (struct mxc_dispdrv_handle *)entry:ERR_PTR(-ENODEV);
  212231. +}
  212232. +EXPORT_SYMBOL_GPL(mxc_dispdrv_gethandle);
  212233. +
  212234. +void mxc_dispdrv_puthandle(struct mxc_dispdrv_handle *handle)
  212235. +{
  212236. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  212237. +
  212238. + mutex_lock(&dispdrv_lock);
  212239. + if (entry && entry->active && entry->drv->deinit) {
  212240. + entry->drv->deinit(handle);
  212241. + entry->active = false;
  212242. + }
  212243. + mutex_unlock(&dispdrv_lock);
  212244. +
  212245. +}
  212246. +EXPORT_SYMBOL_GPL(mxc_dispdrv_puthandle);
  212247. +
  212248. +int mxc_dispdrv_setdata(struct mxc_dispdrv_handle *handle, void *data)
  212249. +{
  212250. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  212251. +
  212252. + if (entry) {
  212253. + entry->priv = data;
  212254. + return 0;
  212255. + } else
  212256. + return -EINVAL;
  212257. +}
  212258. +EXPORT_SYMBOL_GPL(mxc_dispdrv_setdata);
  212259. +
  212260. +void *mxc_dispdrv_getdata(struct mxc_dispdrv_handle *handle)
  212261. +{
  212262. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  212263. +
  212264. + if (entry) {
  212265. + return entry->priv;
  212266. + } else
  212267. + return ERR_PTR(-EINVAL);
  212268. +}
  212269. +EXPORT_SYMBOL_GPL(mxc_dispdrv_getdata);
  212270. diff -Nur linux-3.14.14/drivers/video/mxc/mxc_dispdrv.h linux-imx6-3.14/drivers/video/mxc/mxc_dispdrv.h
  212271. --- linux-3.14.14/drivers/video/mxc/mxc_dispdrv.h 1969-12-31 18:00:00.000000000 -0600
  212272. +++ linux-imx6-3.14/drivers/video/mxc/mxc_dispdrv.h 2014-12-08 00:31:54.860418001 -0600
  212273. @@ -0,0 +1,54 @@
  212274. +/*
  212275. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  212276. + */
  212277. +
  212278. +/*
  212279. + * The code contained herein is licensed under the GNU General Public
  212280. + * License. You may obtain a copy of the GNU General Public License
  212281. + * Version 2 or later at the following locations:
  212282. + *
  212283. + * http://www.opensource.org/licenses/gpl-license.html
  212284. + * http://www.gnu.org/copyleft/gpl.html
  212285. + */
  212286. +#ifndef __MXC_DISPDRV_H__
  212287. +#define __MXC_DISPDRV_H__
  212288. +#include <linux/fb.h>
  212289. +
  212290. +struct mxc_dispdrv_handle {
  212291. + struct mxc_dispdrv_driver *drv;
  212292. +};
  212293. +
  212294. +struct mxc_dispdrv_setting {
  212295. + /*input-feedback parameter*/
  212296. + struct fb_info *fbi;
  212297. + int if_fmt;
  212298. + int default_bpp;
  212299. + char *dft_mode_str;
  212300. +
  212301. + /*feedback parameter*/
  212302. + int dev_id;
  212303. + int disp_id;
  212304. +};
  212305. +
  212306. +struct mxc_dispdrv_driver {
  212307. + const char *name;
  212308. + int (*init) (struct mxc_dispdrv_handle *, struct mxc_dispdrv_setting *);
  212309. + /* deferred operations after dev_id and disp_id pass usage check */
  212310. + int (*post_init) (struct mxc_dispdrv_handle *, int dev_id, int disp_id);
  212311. + void (*deinit) (struct mxc_dispdrv_handle *);
  212312. + /* display driver enable function for extension */
  212313. + int (*enable) (struct mxc_dispdrv_handle *);
  212314. + /* display driver disable function, called at early part of fb_blank */
  212315. + void (*disable) (struct mxc_dispdrv_handle *);
  212316. + /* display driver setup function, called at early part of fb_set_par */
  212317. + int (*setup) (struct mxc_dispdrv_handle *, struct fb_info *fbi);
  212318. +};
  212319. +
  212320. +struct mxc_dispdrv_handle *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv);
  212321. +int mxc_dispdrv_unregister(struct mxc_dispdrv_handle *handle);
  212322. +struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name,
  212323. + struct mxc_dispdrv_setting *setting);
  212324. +void mxc_dispdrv_puthandle(struct mxc_dispdrv_handle *handle);
  212325. +int mxc_dispdrv_setdata(struct mxc_dispdrv_handle *handle, void *data);
  212326. +void *mxc_dispdrv_getdata(struct mxc_dispdrv_handle *handle);
  212327. +#endif
  212328. diff -Nur linux-3.14.14/drivers/video/mxc/mxc_edid.c linux-imx6-3.14/drivers/video/mxc/mxc_edid.c
  212329. --- linux-3.14.14/drivers/video/mxc/mxc_edid.c 1969-12-31 18:00:00.000000000 -0600
  212330. +++ linux-imx6-3.14/drivers/video/mxc/mxc_edid.c 2014-12-08 00:31:54.860418001 -0600
  212331. @@ -0,0 +1,762 @@
  212332. +/*
  212333. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  212334. + */
  212335. +
  212336. +/*
  212337. + * The code contained herein is licensed under the GNU General Public
  212338. + * License. You may obtain a copy of the GNU General Public License
  212339. + * Version 2 or later at the following locations:
  212340. + *
  212341. + * http://www.opensource.org/licenses/gpl-license.html
  212342. + * http://www.gnu.org/copyleft/gpl.html
  212343. + */
  212344. +
  212345. +/*!
  212346. + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
  212347. + */
  212348. +
  212349. +/*!
  212350. + * @file mxc_edid.c
  212351. + *
  212352. + * @brief MXC EDID driver
  212353. + *
  212354. + * @ingroup Framebuffer
  212355. + */
  212356. +
  212357. +/*!
  212358. + * Include files
  212359. + */
  212360. +#include <linux/i2c.h>
  212361. +#include <linux/fb.h>
  212362. +#include <video/mxc_edid.h>
  212363. +#include "../edid.h"
  212364. +
  212365. +#undef DEBUG /* define this for verbose EDID parsing output */
  212366. +#ifdef DEBUG
  212367. +#define DPRINTK(fmt, args...) printk(fmt, ## args)
  212368. +#else
  212369. +#define DPRINTK(fmt, args...)
  212370. +#endif
  212371. +
  212372. +const struct fb_videomode mxc_cea_mode[64] = {
  212373. + /* #1: 640x480p@59.94/60Hz 4:3 */
  212374. + [1] = {
  212375. + NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0,
  212376. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  212377. + },
  212378. + /* #2: 720x480p@59.94/60Hz 4:3 */
  212379. + [2] = {
  212380. + NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
  212381. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  212382. + },
  212383. + /* #3: 720x480p@59.94/60Hz 16:9 */
  212384. + [3] = {
  212385. + NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
  212386. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212387. + },
  212388. + /* #4: 1280x720p@59.94/60Hz 16:9 */
  212389. + [4] = {
  212390. + NULL, 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5,
  212391. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  212392. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
  212393. + },
  212394. + /* #5: 1920x1080i@59.94/60Hz 16:9 */
  212395. + [5] = {
  212396. + NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5,
  212397. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  212398. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212399. + },
  212400. + /* #6: 720(1440)x480iH@59.94/60Hz 4:3 */
  212401. + [6] = {
  212402. + NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
  212403. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_4_3, 0,
  212404. + },
  212405. + /* #7: 720(1440)x480iH@59.94/60Hz 16:9 */
  212406. + [7] = {
  212407. + NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
  212408. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212409. + },
  212410. + /* #8: 720(1440)x240pH@59.94/60Hz 4:3 */
  212411. + [8] = {
  212412. + NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
  212413. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  212414. + },
  212415. + /* #9: 720(1440)x240pH@59.94/60Hz 16:9 */
  212416. + [9] = {
  212417. + NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
  212418. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212419. + },
  212420. + /* #14: 1440x480p@59.94/60Hz 4:3 */
  212421. + [14] = {
  212422. + NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
  212423. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  212424. + },
  212425. + /* #15: 1440x480p@59.94/60Hz 16:9 */
  212426. + [15] = {
  212427. + NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
  212428. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212429. + },
  212430. + /* #16: 1920x1080p@60Hz 16:9 */
  212431. + [16] = {
  212432. + NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
  212433. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  212434. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212435. + },
  212436. + /* #17: 720x576pH@50Hz 4:3 */
  212437. + [17] = {
  212438. + NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
  212439. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  212440. + },
  212441. + /* #18: 720x576pH@50Hz 16:9 */
  212442. + [18] = {
  212443. + NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
  212444. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212445. + },
  212446. + /* #19: 1280x720p@50Hz */
  212447. + [19] = {
  212448. + NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5,
  212449. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  212450. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212451. + },
  212452. + /* #20: 1920x1080i@50Hz */
  212453. + [20] = {
  212454. + NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5,
  212455. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  212456. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212457. + },
  212458. + /* #23: 720(1440)x288pH@50Hz 4:3 */
  212459. + [23] = {
  212460. + NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
  212461. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  212462. + },
  212463. + /* #24: 720(1440)x288pH@50Hz 16:9 */
  212464. + [24] = {
  212465. + NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
  212466. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212467. + },
  212468. + /* #29: 720(1440)x576pH@50Hz 4:3 */
  212469. + [29] = {
  212470. + NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
  212471. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  212472. + },
  212473. + /* #30: 720(1440)x576pH@50Hz 16:9 */
  212474. + [30] = {
  212475. + NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
  212476. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212477. + },
  212478. + /* #31: 1920x1080p@50Hz */
  212479. + [31] = {
  212480. + NULL, 50, 1920, 1080, 6734, 148, 528, 36, 4, 44, 5,
  212481. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  212482. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212483. + },
  212484. + /* #32: 1920x1080p@23.98/24Hz */
  212485. + [32] = {
  212486. + NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5,
  212487. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  212488. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212489. + },
  212490. + /* #33: 1920x1080p@25Hz */
  212491. + [33] = {
  212492. + NULL, 25, 1920, 1080, 13468, 148, 528, 36, 4, 44, 5,
  212493. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  212494. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212495. + },
  212496. + /* #34: 1920x1080p@30Hz */
  212497. + [34] = {
  212498. + NULL, 30, 1920, 1080, 13468, 148, 88, 36, 4, 44, 5,
  212499. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  212500. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  212501. + },
  212502. + /* #41: 1280x720p@100Hz 16:9 */
  212503. + [41] = {
  212504. + NULL, 100, 1280, 720, 6734, 220, 440, 20, 5, 40, 5,
  212505. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  212506. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
  212507. + },
  212508. + /* #47: 1280x720p@119.88/120Hz 16:9 */
  212509. + [47] = {
  212510. + NULL, 120, 1280, 720, 6734, 220, 110, 20, 5, 40, 5,
  212511. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  212512. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
  212513. + },
  212514. +};
  212515. +
  212516. +/*
  212517. + * We have a special version of fb_mode_is_equal that ignores
  212518. + * pixclock, since for many CEA modes, 2 frequencies are supported
  212519. + * e.g. 640x480 @ 60Hz or 59.94Hz
  212520. + */
  212521. +int mxc_edid_fb_mode_is_equal(bool use_aspect,
  212522. + const struct fb_videomode *mode1,
  212523. + const struct fb_videomode *mode2)
  212524. +{
  212525. + u32 mask;
  212526. +
  212527. + if (use_aspect)
  212528. + mask = ~0;
  212529. + else
  212530. + mask = ~FB_VMODE_ASPECT_MASK;
  212531. +
  212532. + return (mode1->xres == mode2->xres &&
  212533. + mode1->yres == mode2->yres &&
  212534. + mode1->hsync_len == mode2->hsync_len &&
  212535. + mode1->vsync_len == mode2->vsync_len &&
  212536. + mode1->left_margin == mode2->left_margin &&
  212537. + mode1->right_margin == mode2->right_margin &&
  212538. + mode1->upper_margin == mode2->upper_margin &&
  212539. + mode1->lower_margin == mode2->lower_margin &&
  212540. + mode1->sync == mode2->sync &&
  212541. + /* refresh check, 59.94Hz and 60Hz have the same parameter
  212542. + * in struct of mxc_cea_mode */
  212543. + abs(mode1->refresh - mode2->refresh) <= 1 &&
  212544. + (mode1->vmode & mask) == (mode2->vmode & mask));
  212545. +}
  212546. +
  212547. +static void get_detailed_timing(unsigned char *block,
  212548. + struct fb_videomode *mode)
  212549. +{
  212550. + mode->xres = H_ACTIVE;
  212551. + mode->yres = V_ACTIVE;
  212552. + mode->pixclock = PIXEL_CLOCK;
  212553. + mode->pixclock /= 1000;
  212554. + mode->pixclock = KHZ2PICOS(mode->pixclock);
  212555. + mode->right_margin = H_SYNC_OFFSET;
  212556. + mode->left_margin = (H_ACTIVE + H_BLANKING) -
  212557. + (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
  212558. + mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
  212559. + V_SYNC_WIDTH;
  212560. + mode->lower_margin = V_SYNC_OFFSET;
  212561. + mode->hsync_len = H_SYNC_WIDTH;
  212562. + mode->vsync_len = V_SYNC_WIDTH;
  212563. + if (HSYNC_POSITIVE)
  212564. + mode->sync |= FB_SYNC_HOR_HIGH_ACT;
  212565. + if (VSYNC_POSITIVE)
  212566. + mode->sync |= FB_SYNC_VERT_HIGH_ACT;
  212567. + mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
  212568. + (V_ACTIVE + V_BLANKING));
  212569. + if (INTERLACED) {
  212570. + mode->yres *= 2;
  212571. + mode->upper_margin *= 2;
  212572. + mode->lower_margin *= 2;
  212573. + mode->vsync_len *= 2;
  212574. + mode->vmode |= FB_VMODE_INTERLACED;
  212575. + }
  212576. + mode->flag = FB_MODE_IS_DETAILED;
  212577. +
  212578. + if ((H_SIZE / 16) == (V_SIZE / 9))
  212579. + mode->vmode |= FB_VMODE_ASPECT_16_9;
  212580. + else if ((H_SIZE / 4) == (V_SIZE / 3))
  212581. + mode->vmode |= FB_VMODE_ASPECT_4_3;
  212582. + else if ((mode->xres / 16) == (mode->yres / 9))
  212583. + mode->vmode |= FB_VMODE_ASPECT_16_9;
  212584. + else if ((mode->xres / 4) == (mode->yres / 3))
  212585. + mode->vmode |= FB_VMODE_ASPECT_4_3;
  212586. +
  212587. + if (mode->vmode & FB_VMODE_ASPECT_16_9)
  212588. + DPRINTK("Aspect ratio: 16:9\n");
  212589. + if (mode->vmode & FB_VMODE_ASPECT_4_3)
  212590. + DPRINTK("Aspect ratio: 4:3\n");
  212591. + DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000);
  212592. + DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET,
  212593. + H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING);
  212594. + DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET,
  212595. + V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING);
  212596. + DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-",
  212597. + (VSYNC_POSITIVE) ? "+" : "-");
  212598. +}
  212599. +
  212600. +int mxc_edid_parse_ext_blk(unsigned char *edid,
  212601. + struct mxc_edid_cfg *cfg,
  212602. + struct fb_monspecs *specs)
  212603. +{
  212604. + char detail_timing_desc_offset;
  212605. + struct fb_videomode *mode, *m;
  212606. + unsigned char index = 0x0;
  212607. + unsigned char *block;
  212608. + int i, num = 0, revision;
  212609. +
  212610. + if (edid[index++] != 0x2) /* only support cea ext block now */
  212611. + return -1;
  212612. + revision = edid[index++];
  212613. + DPRINTK("cea extent revision %d\n", revision);
  212614. + mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
  212615. + if (mode == NULL)
  212616. + return -1;
  212617. +
  212618. + detail_timing_desc_offset = edid[index++];
  212619. +
  212620. + if (revision >= 2) {
  212621. + cfg->cea_underscan = (edid[index] >> 7) & 0x1;
  212622. + cfg->cea_basicaudio = (edid[index] >> 6) & 0x1;
  212623. + cfg->cea_ycbcr444 = (edid[index] >> 5) & 0x1;
  212624. + cfg->cea_ycbcr422 = (edid[index] >> 4) & 0x1;
  212625. +
  212626. + DPRINTK("CEA underscan %d\n", cfg->cea_underscan);
  212627. + DPRINTK("CEA basicaudio %d\n", cfg->cea_basicaudio);
  212628. + DPRINTK("CEA ycbcr444 %d\n", cfg->cea_ycbcr444);
  212629. + DPRINTK("CEA ycbcr422 %d\n", cfg->cea_ycbcr422);
  212630. + }
  212631. +
  212632. + if (revision >= 3) {
  212633. + /* short desc */
  212634. + DPRINTK("CEA Short desc timmings\n");
  212635. + index++;
  212636. + while (index < detail_timing_desc_offset) {
  212637. + unsigned char tagcode, blklen;
  212638. +
  212639. + tagcode = (edid[index] >> 5) & 0x7;
  212640. + blklen = (edid[index]) & 0x1f;
  212641. +
  212642. + DPRINTK("Tagcode %x Len %d\n", tagcode, blklen);
  212643. +
  212644. + switch (tagcode) {
  212645. + case 0x2: /*Video data block*/
  212646. + {
  212647. + int cea_idx;
  212648. + i = 0;
  212649. + while (i < blklen) {
  212650. + index++;
  212651. + cea_idx = edid[index] & 0x7f;
  212652. + if (cea_idx < ARRAY_SIZE(mxc_cea_mode) &&
  212653. + (mxc_cea_mode[cea_idx].xres)) {
  212654. + DPRINTK("Support CEA Format #%d\n", cea_idx);
  212655. + mode[num] = mxc_cea_mode[cea_idx];
  212656. + mode[num].flag |= FB_MODE_IS_STANDARD;
  212657. + num++;
  212658. + }
  212659. + i++;
  212660. + }
  212661. + break;
  212662. + }
  212663. + case 0x3: /*Vendor specific data*/
  212664. + {
  212665. + unsigned char IEEE_reg_iden[3];
  212666. + unsigned char deep_color;
  212667. + unsigned char latency_present;
  212668. + unsigned char I_latency_present;
  212669. + unsigned char hdmi_video_present;
  212670. + unsigned char hdmi_3d_present;
  212671. + unsigned char hdmi_3d_multi_present;
  212672. + unsigned char hdmi_vic_len;
  212673. + unsigned char hdmi_3d_len;
  212674. + unsigned char index_inc = 0;
  212675. + unsigned char vsd_end;
  212676. +
  212677. + vsd_end = index + blklen;
  212678. +
  212679. + IEEE_reg_iden[0] = edid[index+1];
  212680. + IEEE_reg_iden[1] = edid[index+2];
  212681. + IEEE_reg_iden[2] = edid[index+3];
  212682. + cfg->physical_address[0] = (edid[index+4] & 0xf0) >> 4;
  212683. + cfg->physical_address[1] = (edid[index+4] & 0x0f);
  212684. + cfg->physical_address[2] = (edid[index+5] & 0xf0) >> 4;
  212685. + cfg->physical_address[3] = (edid[index+5] & 0x0f);
  212686. +
  212687. + if ((IEEE_reg_iden[0] == 0x03) &&
  212688. + (IEEE_reg_iden[1] == 0x0c) &&
  212689. + (IEEE_reg_iden[2] == 0x00))
  212690. + cfg->hdmi_cap = 1;
  212691. +
  212692. + if (blklen > 5) {
  212693. + deep_color = edid[index+6];
  212694. + if (deep_color & 0x80)
  212695. + cfg->vsd_support_ai = true;
  212696. + if (deep_color & 0x40)
  212697. + cfg->vsd_dc_48bit = true;
  212698. + if (deep_color & 0x20)
  212699. + cfg->vsd_dc_36bit = true;
  212700. + if (deep_color & 0x10)
  212701. + cfg->vsd_dc_30bit = true;
  212702. + if (deep_color & 0x08)
  212703. + cfg->vsd_dc_y444 = true;
  212704. + if (deep_color & 0x01)
  212705. + cfg->vsd_dvi_dual = true;
  212706. + }
  212707. +
  212708. + DPRINTK("VSD hdmi capability %d\n", cfg->hdmi_cap);
  212709. + DPRINTK("VSD support ai %d\n", cfg->vsd_support_ai);
  212710. + DPRINTK("VSD support deep color 48bit %d\n", cfg->vsd_dc_48bit);
  212711. + DPRINTK("VSD support deep color 36bit %d\n", cfg->vsd_dc_36bit);
  212712. + DPRINTK("VSD support deep color 30bit %d\n", cfg->vsd_dc_30bit);
  212713. + DPRINTK("VSD support deep color y444 %d\n", cfg->vsd_dc_y444);
  212714. + DPRINTK("VSD support dvi dual %d\n", cfg->vsd_dvi_dual);
  212715. +
  212716. + if (blklen > 6)
  212717. + cfg->vsd_max_tmdsclk_rate = edid[index+7] * 5;
  212718. + DPRINTK("VSD MAX TMDS CLOCK RATE %d\n", cfg->vsd_max_tmdsclk_rate);
  212719. +
  212720. + if (blklen > 7) {
  212721. + latency_present = edid[index+8] >> 7;
  212722. + I_latency_present = (edid[index+8] & 0x40) >> 6;
  212723. + hdmi_video_present = (edid[index+8] & 0x20) >> 5;
  212724. + cfg->vsd_cnc3 = (edid[index+8] & 0x8) >> 3;
  212725. + cfg->vsd_cnc2 = (edid[index+8] & 0x4) >> 2;
  212726. + cfg->vsd_cnc1 = (edid[index+8] & 0x2) >> 1;
  212727. + cfg->vsd_cnc0 = edid[index+8] & 0x1;
  212728. +
  212729. + DPRINTK("VSD cnc0 %d\n", cfg->vsd_cnc0);
  212730. + DPRINTK("VSD cnc1 %d\n", cfg->vsd_cnc1);
  212731. + DPRINTK("VSD cnc2 %d\n", cfg->vsd_cnc2);
  212732. + DPRINTK("VSD cnc3 %d\n", cfg->vsd_cnc3);
  212733. + DPRINTK("latency_present %d\n", latency_present);
  212734. + DPRINTK("I_latency_present %d\n", I_latency_present);
  212735. + DPRINTK("hdmi_video_present %d\n", hdmi_video_present);
  212736. +
  212737. + } else {
  212738. + index += blklen;
  212739. + break;
  212740. + }
  212741. +
  212742. + index += 9;
  212743. +
  212744. + /*latency present */
  212745. + if (latency_present) {
  212746. + cfg->vsd_video_latency = edid[index++];
  212747. + cfg->vsd_audio_latency = edid[index++];
  212748. +
  212749. + if (I_latency_present) {
  212750. + cfg->vsd_I_video_latency = edid[index++];
  212751. + cfg->vsd_I_audio_latency = edid[index++];
  212752. + } else {
  212753. + cfg->vsd_I_video_latency = cfg->vsd_video_latency;
  212754. + cfg->vsd_I_audio_latency = cfg->vsd_audio_latency;
  212755. + }
  212756. +
  212757. + DPRINTK("VSD latency video_latency %d\n", cfg->vsd_video_latency);
  212758. + DPRINTK("VSD latency audio_latency %d\n", cfg->vsd_audio_latency);
  212759. + DPRINTK("VSD latency I_video_latency %d\n", cfg->vsd_I_video_latency);
  212760. + DPRINTK("VSD latency I_audio_latency %d\n", cfg->vsd_I_audio_latency);
  212761. + }
  212762. +
  212763. + if (hdmi_video_present) {
  212764. + hdmi_3d_present = edid[index] >> 7;
  212765. + hdmi_3d_multi_present = (edid[index] & 0x60) >> 5;
  212766. + index++;
  212767. + hdmi_vic_len = (edid[index] & 0xe0) >> 5;
  212768. + hdmi_3d_len = edid[index] & 0x1f;
  212769. + index++;
  212770. +
  212771. + DPRINTK("hdmi_3d_present %d\n", hdmi_3d_present);
  212772. + DPRINTK("hdmi_3d_multi_present %d\n", hdmi_3d_multi_present);
  212773. + DPRINTK("hdmi_vic_len %d\n", hdmi_vic_len);
  212774. + DPRINTK("hdmi_3d_len %d\n", hdmi_3d_len);
  212775. +
  212776. + if (hdmi_vic_len > 0) {
  212777. + for (i = 0; i < hdmi_vic_len; i++) {
  212778. + cfg->hdmi_vic[i] = edid[index++];
  212779. + DPRINTK("HDMI_vic=%d\n", cfg->hdmi_vic[i]);
  212780. + }
  212781. + }
  212782. +
  212783. + if (hdmi_3d_len > 0) {
  212784. + if (hdmi_3d_present) {
  212785. + if (hdmi_3d_multi_present == 0x1) {
  212786. + cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
  212787. + index_inc = 2;
  212788. + } else if (hdmi_3d_multi_present == 0x2) {
  212789. + cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
  212790. + cfg->hdmi_3d_mask_all = (edid[index+2] << 8) | edid[index+3];
  212791. + index_inc = 4;
  212792. + } else
  212793. + index_inc = 0;
  212794. + }
  212795. +
  212796. + DPRINTK("HDMI 3d struct all =0x%x\n", cfg->hdmi_3d_struct_all);
  212797. + DPRINTK("HDMI 3d mask all =0x%x\n", cfg->hdmi_3d_mask_all);
  212798. +
  212799. + /* Read 2D vic 3D_struct */
  212800. + if ((hdmi_3d_len - index_inc) > 0) {
  212801. + DPRINTK("Support 3D video format\n");
  212802. + i = 0;
  212803. + while ((hdmi_3d_len - index_inc) > 0) {
  212804. +
  212805. + cfg->hdmi_3d_format[i].vic_order_2d = edid[index+index_inc] >> 4;
  212806. + cfg->hdmi_3d_format[i].struct_3d = edid[index+index_inc] & 0x0f;
  212807. + index_inc++;
  212808. +
  212809. + if (cfg->hdmi_3d_format[i].struct_3d == 8) {
  212810. + cfg->hdmi_3d_format[i].detail_3d = edid[index+index_inc] >> 4;
  212811. + index_inc++;
  212812. + } else if (cfg->hdmi_3d_format[i].struct_3d > 8) {
  212813. + cfg->hdmi_3d_format[i].detail_3d = 0;
  212814. + index_inc++;
  212815. + }
  212816. +
  212817. + DPRINTK("vic_order_2d=%d, 3d_struct=%d, 3d_detail=0x%x\n",
  212818. + cfg->hdmi_3d_format[i].vic_order_2d,
  212819. + cfg->hdmi_3d_format[i].struct_3d,
  212820. + cfg->hdmi_3d_format[i].detail_3d);
  212821. + i++;
  212822. + }
  212823. + }
  212824. + index += index_inc;
  212825. + }
  212826. + }
  212827. +
  212828. + index = vsd_end;
  212829. +
  212830. + break;
  212831. + }
  212832. + case 0x1: /*Audio data block*/
  212833. + {
  212834. + u8 audio_format, max_ch, byte1, byte2, byte3;
  212835. +
  212836. + i = 0;
  212837. + cfg->max_channels = 0;
  212838. + cfg->sample_rates = 0;
  212839. + cfg->sample_sizes = 0;
  212840. +
  212841. + while (i < blklen) {
  212842. + byte1 = edid[index + 1];
  212843. + byte2 = edid[index + 2];
  212844. + byte3 = edid[index + 3];
  212845. + index += 3;
  212846. + i += 3;
  212847. +
  212848. + audio_format = byte1 >> 3;
  212849. + max_ch = (byte1 & 0x07) + 1;
  212850. +
  212851. + DPRINTK("Audio Format Descriptor : %2d\n", audio_format);
  212852. + DPRINTK("Max Number of Channels : %2d\n", max_ch);
  212853. + DPRINTK("Sample Rates : %02x\n", byte2);
  212854. +
  212855. + /* ALSA can't specify specific compressed
  212856. + * formats, so only care about PCM for now. */
  212857. + if (audio_format == AUDIO_CODING_TYPE_LPCM) {
  212858. + if (max_ch > cfg->max_channels)
  212859. + cfg->max_channels = max_ch;
  212860. +
  212861. + cfg->sample_rates |= byte2;
  212862. + cfg->sample_sizes |= byte3 & 0x7;
  212863. + DPRINTK("Sample Sizes : %02x\n",
  212864. + byte3 & 0x7);
  212865. + }
  212866. + }
  212867. + break;
  212868. + }
  212869. + case 0x4: /*Speaker allocation block*/
  212870. + {
  212871. + i = 0;
  212872. + while (i < blklen) {
  212873. + cfg->speaker_alloc = edid[index + 1];
  212874. + index += 3;
  212875. + i += 3;
  212876. + DPRINTK("Speaker Alloc : %02x\n", cfg->speaker_alloc);
  212877. + }
  212878. + break;
  212879. + }
  212880. + case 0x7: /*User extended block*/
  212881. + default:
  212882. + /* skip */
  212883. + DPRINTK("Not handle block, tagcode = 0x%x\n", tagcode);
  212884. + index += blklen;
  212885. + break;
  212886. + }
  212887. +
  212888. + index++;
  212889. + }
  212890. + }
  212891. +
  212892. + /* long desc */
  212893. + DPRINTK("CEA long desc timmings\n");
  212894. + index = detail_timing_desc_offset;
  212895. + block = edid + index;
  212896. + while (index < (EDID_LENGTH - DETAILED_TIMING_DESCRIPTION_SIZE)) {
  212897. + if (!(block[0] == 0x00 && block[1] == 0x00)) {
  212898. + get_detailed_timing(block, &mode[num]);
  212899. + num++;
  212900. + }
  212901. + block += DETAILED_TIMING_DESCRIPTION_SIZE;
  212902. + index += DETAILED_TIMING_DESCRIPTION_SIZE;
  212903. + }
  212904. +
  212905. + if (!num) {
  212906. + kfree(mode);
  212907. + return 0;
  212908. + }
  212909. +
  212910. + m = kmalloc((num + specs->modedb_len) *
  212911. + sizeof(struct fb_videomode), GFP_KERNEL);
  212912. + if (!m)
  212913. + return 0;
  212914. +
  212915. + if (specs->modedb_len) {
  212916. + memmove(m, specs->modedb,
  212917. + specs->modedb_len * sizeof(struct fb_videomode));
  212918. + kfree(specs->modedb);
  212919. + }
  212920. + memmove(m+specs->modedb_len, mode,
  212921. + num * sizeof(struct fb_videomode));
  212922. + kfree(mode);
  212923. +
  212924. + specs->modedb_len += num;
  212925. + specs->modedb = m;
  212926. +
  212927. + return 0;
  212928. +}
  212929. +EXPORT_SYMBOL(mxc_edid_parse_ext_blk);
  212930. +
  212931. +static int mxc_edid_readblk(struct i2c_adapter *adp,
  212932. + unsigned short addr, unsigned char *edid)
  212933. +{
  212934. + int ret = 0, extblknum = 0;
  212935. + unsigned char regaddr = 0x0;
  212936. + struct i2c_msg msg[2] = {
  212937. + {
  212938. + .addr = addr,
  212939. + .flags = 0,
  212940. + .len = 1,
  212941. + .buf = &regaddr,
  212942. + }, {
  212943. + .addr = addr,
  212944. + .flags = I2C_M_RD,
  212945. + .len = EDID_LENGTH,
  212946. + .buf = edid,
  212947. + },
  212948. + };
  212949. +
  212950. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  212951. + if (ret != ARRAY_SIZE(msg)) {
  212952. + DPRINTK("unable to read EDID block\n");
  212953. + return -EIO;
  212954. + }
  212955. +
  212956. + if (edid[1] == 0x00)
  212957. + return -ENOENT;
  212958. +
  212959. + extblknum = edid[0x7E];
  212960. +
  212961. + if (extblknum) {
  212962. + regaddr = 128;
  212963. + msg[1].buf = edid + EDID_LENGTH;
  212964. +
  212965. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  212966. + if (ret != ARRAY_SIZE(msg)) {
  212967. + DPRINTK("unable to read EDID ext block\n");
  212968. + return -EIO;
  212969. + }
  212970. + }
  212971. +
  212972. + return extblknum;
  212973. +}
  212974. +
  212975. +static int mxc_edid_readsegblk(struct i2c_adapter *adp, unsigned short addr,
  212976. + unsigned char *edid, int seg_num)
  212977. +{
  212978. + int ret = 0;
  212979. + unsigned char segment = 0x1, regaddr = 0;
  212980. + struct i2c_msg msg[3] = {
  212981. + {
  212982. + .addr = 0x30,
  212983. + .flags = 0,
  212984. + .len = 1,
  212985. + .buf = &segment,
  212986. + }, {
  212987. + .addr = addr,
  212988. + .flags = 0,
  212989. + .len = 1,
  212990. + .buf = &regaddr,
  212991. + }, {
  212992. + .addr = addr,
  212993. + .flags = I2C_M_RD,
  212994. + .len = EDID_LENGTH,
  212995. + .buf = edid,
  212996. + },
  212997. + };
  212998. +
  212999. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  213000. + if (ret != ARRAY_SIZE(msg)) {
  213001. + DPRINTK("unable to read EDID block\n");
  213002. + return -EIO;
  213003. + }
  213004. +
  213005. + if (seg_num == 2) {
  213006. + regaddr = 128;
  213007. + msg[2].buf = edid + EDID_LENGTH;
  213008. +
  213009. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  213010. + if (ret != ARRAY_SIZE(msg)) {
  213011. + DPRINTK("unable to read EDID block\n");
  213012. + return -EIO;
  213013. + }
  213014. + }
  213015. +
  213016. + return ret;
  213017. +}
  213018. +
  213019. +int mxc_edid_var_to_vic(struct fb_var_screeninfo *var)
  213020. +{
  213021. + int i;
  213022. + struct fb_videomode m;
  213023. +
  213024. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  213025. + fb_var_to_videomode(&m, var);
  213026. + if (mxc_edid_fb_mode_is_equal(false, &m, &mxc_cea_mode[i]))
  213027. + break;
  213028. + }
  213029. +
  213030. + if (i == ARRAY_SIZE(mxc_cea_mode))
  213031. + return 0;
  213032. +
  213033. + return i;
  213034. +}
  213035. +EXPORT_SYMBOL(mxc_edid_var_to_vic);
  213036. +
  213037. +int mxc_edid_mode_to_vic(const struct fb_videomode *mode)
  213038. +{
  213039. + int i;
  213040. + bool use_aspect = (mode->vmode & FB_VMODE_ASPECT_MASK);
  213041. +
  213042. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  213043. + if (mxc_edid_fb_mode_is_equal(use_aspect, mode, &mxc_cea_mode[i]))
  213044. + break;
  213045. + }
  213046. +
  213047. + if (i == ARRAY_SIZE(mxc_cea_mode))
  213048. + return 0;
  213049. +
  213050. + return i;
  213051. +}
  213052. +EXPORT_SYMBOL(mxc_edid_mode_to_vic);
  213053. +
  213054. +/* make sure edid has 512 bytes*/
  213055. +int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
  213056. + unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi)
  213057. +{
  213058. + int ret = 0, extblknum;
  213059. + if (!adp || !edid || !cfg || !fbi)
  213060. + return -EINVAL;
  213061. +
  213062. + memset(edid, 0, EDID_LENGTH*4);
  213063. + memset(cfg, 0, sizeof(struct mxc_edid_cfg));
  213064. +
  213065. + extblknum = mxc_edid_readblk(adp, addr, edid);
  213066. + if (extblknum < 0)
  213067. + return extblknum;
  213068. +
  213069. + /* edid first block parsing */
  213070. + memset(&fbi->monspecs, 0, sizeof(fbi->monspecs));
  213071. + fb_edid_to_monspecs(edid, &fbi->monspecs);
  213072. +
  213073. + if (extblknum) {
  213074. + int i;
  213075. +
  213076. + /* need read segment block? */
  213077. + if (extblknum > 1) {
  213078. + ret = mxc_edid_readsegblk(adp, addr,
  213079. + edid + EDID_LENGTH*2, extblknum - 1);
  213080. + if (ret < 0)
  213081. + return ret;
  213082. + }
  213083. +
  213084. + for (i = 1; i <= extblknum; i++)
  213085. + /* edid ext block parsing */
  213086. + mxc_edid_parse_ext_blk(edid + i*EDID_LENGTH,
  213087. + cfg, &fbi->monspecs);
  213088. + }
  213089. +
  213090. + return 0;
  213091. +}
  213092. +EXPORT_SYMBOL(mxc_edid_read);
  213093. +
  213094. diff -Nur linux-3.14.14/drivers/video/mxc/mxcfb_hx8369_wvga.c linux-imx6-3.14/drivers/video/mxc/mxcfb_hx8369_wvga.c
  213095. --- linux-3.14.14/drivers/video/mxc/mxcfb_hx8369_wvga.c 1969-12-31 18:00:00.000000000 -0600
  213096. +++ linux-imx6-3.14/drivers/video/mxc/mxcfb_hx8369_wvga.c 2014-12-08 00:31:54.860418001 -0600
  213097. @@ -0,0 +1,449 @@
  213098. +/*
  213099. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  213100. + *
  213101. + * This program is free software; you can redistribute it and/or modify
  213102. + * it under the terms of the GNU General Public License as published by
  213103. + * the Free Software Foundation; either version 2 of the License, or
  213104. + * (at your option) any later version.
  213105. +
  213106. + * This program is distributed in the hope that it will be useful,
  213107. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  213108. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  213109. + * GNU General Public License for more details.
  213110. +
  213111. + * You should have received a copy of the GNU General Public License along
  213112. + * with this program; if not, write to the Free Software Foundation, Inc.,
  213113. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  213114. + */
  213115. +
  213116. +#include <linux/types.h>
  213117. +#include <linux/init.h>
  213118. +#include <linux/delay.h>
  213119. +#include <linux/platform_device.h>
  213120. +#include <linux/err.h>
  213121. +#include <linux/clk.h>
  213122. +#include <linux/console.h>
  213123. +#include <linux/io.h>
  213124. +#include <linux/bitops.h>
  213125. +#include <linux/spinlock.h>
  213126. +#include <linux/mipi_dsi.h>
  213127. +#include <linux/mxcfb.h>
  213128. +#include <linux/backlight.h>
  213129. +#include <video/mipi_display.h>
  213130. +
  213131. +#include "mipi_dsi.h"
  213132. +
  213133. +#define MIPI_DSI_MAX_RET_PACK_SIZE (0x4)
  213134. +
  213135. +#define HX8369BL_MAX_BRIGHT (255)
  213136. +#define HX8369BL_DEF_BRIGHT (255)
  213137. +
  213138. +#define HX8369_MAX_DPHY_CLK (800)
  213139. +#define HX8369_ONE_DATA_LANE (0x1)
  213140. +#define HX8369_TWO_DATA_LANE (0x2)
  213141. +
  213142. +#define HX8369_CMD_SETEXTC (0xB9)
  213143. +#define HX8369_CMD_SETEXTC_LEN (0x4)
  213144. +#define HX8369_CMD_SETEXTC_PARAM_1 (0x6983ff)
  213145. +
  213146. +#define HX8369_CMD_GETHXID (0xF4)
  213147. +#define HX8369_CMD_GETHXID_LEN (0x4)
  213148. +#define HX8369_ID (0x69)
  213149. +#define HX8369_ID_MASK (0xFF)
  213150. +
  213151. +#define HX8369_CMD_SETDISP (0xB2)
  213152. +#define HX8369_CMD_SETDISP_LEN (16)
  213153. +#define HX8369_CMD_SETDISP_1_HALT (0x00)
  213154. +#define HX8369_CMD_SETDISP_2_RES_MODE (0x23)
  213155. +#define HX8369_CMD_SETDISP_3_BP (0x03)
  213156. +#define HX8369_CMD_SETDISP_4_FP (0x03)
  213157. +#define HX8369_CMD_SETDISP_5_SAP (0x70)
  213158. +#define HX8369_CMD_SETDISP_6_GENON (0x00)
  213159. +#define HX8369_CMD_SETDISP_7_GENOFF (0xff)
  213160. +#define HX8369_CMD_SETDISP_8_RTN (0x00)
  213161. +#define HX8369_CMD_SETDISP_9_TEI (0x00)
  213162. +#define HX8369_CMD_SETDISP_10_TEP_UP (0x00)
  213163. +#define HX8369_CMD_SETDISP_11_TEP_LOW (0x00)
  213164. +#define HX8369_CMD_SETDISP_12_BP_PE (0x03)
  213165. +#define HX8369_CMD_SETDISP_13_FP_PE (0x03)
  213166. +#define HX8369_CMD_SETDISP_14_RTN_PE (0x00)
  213167. +#define HX8369_CMD_SETDISP_15_GON (0x01)
  213168. +
  213169. +#define HX8369_CMD_SETCYC (0xB4)
  213170. +#define HX8369_CMD_SETCYC_LEN (6)
  213171. +#define HX8369_CMD_SETCYC_PARAM_1 (0x5f1d00)
  213172. +#define HX8369_CMD_SETCYC_PARAM_2 (0x060e)
  213173. +
  213174. +#define HX8369_CMD_SETGIP (0xD5)
  213175. +#define HX8369_CMD_SETGIP_LEN (27)
  213176. +#define HX8369_CMD_SETGIP_PARAM_1 (0x030400)
  213177. +#define HX8369_CMD_SETGIP_PARAM_2 (0x1c050100)
  213178. +#define HX8369_CMD_SETGIP_PARAM_3 (0x00030170)
  213179. +#define HX8369_CMD_SETGIP_PARAM_4 (0x51064000)
  213180. +#define HX8369_CMD_SETGIP_PARAM_5 (0x41000007)
  213181. +#define HX8369_CMD_SETGIP_PARAM_6 (0x07075006)
  213182. +#define HX8369_CMD_SETGIP_PARAM_7 (0x040f)
  213183. +
  213184. +#define HX8369_CMD_SETPOWER (0xB1)
  213185. +#define HX8369_CMD_SETPOWER_LEN (20)
  213186. +#define HX8369_CMD_SETPOWER_PARAM_1 (0x340001)
  213187. +#define HX8369_CMD_SETPOWER_PARAM_2 (0x0f0f0006)
  213188. +#define HX8369_CMD_SETPOWER_PARAM_3 (0x3f3f322a)
  213189. +#define HX8369_CMD_SETPOWER_PARAM_4 (0xe6013a07)
  213190. +#define HX8369_CMD_SETPOWER_PARAM_5 (0xe6e6e6e6)
  213191. +
  213192. +#define HX8369_CMD_SETVCOM (0xB6)
  213193. +#define HX8369_CMD_SETVCOM_LEN (3)
  213194. +#define HX8369_CMD_SETVCOM_PARAM_1 (0x5656)
  213195. +
  213196. +#define HX8369_CMD_SETPANEL (0xCC)
  213197. +#define HX8369_CMD_SETPANEL_PARAM_1 (0x02)
  213198. +
  213199. +#define HX8369_CMD_SETGAMMA (0xE0)
  213200. +#define HX8369_CMD_SETGAMMA_LEN (35)
  213201. +#define HX8369_CMD_SETGAMMA_PARAM_1 (0x221d00)
  213202. +#define HX8369_CMD_SETGAMMA_PARAM_2 (0x2e3f3d38)
  213203. +#define HX8369_CMD_SETGAMMA_PARAM_3 (0x0f0d064a)
  213204. +#define HX8369_CMD_SETGAMMA_PARAM_4 (0x16131513)
  213205. +#define HX8369_CMD_SETGAMMA_PARAM_5 (0x1d001910)
  213206. +#define HX8369_CMD_SETGAMMA_PARAM_6 (0x3f3d3822)
  213207. +#define HX8369_CMD_SETGAMMA_PARAM_7 (0x0d064a2e)
  213208. +#define HX8369_CMD_SETGAMMA_PARAM_8 (0x1315130f)
  213209. +#define HX8369_CMD_SETGAMMA_PARAM_9 (0x191016)
  213210. +
  213211. +#define HX8369_CMD_SETMIPI (0xBA)
  213212. +#define HX8369_CMD_SETMIPI_LEN (14)
  213213. +#define HX8369_CMD_SETMIPI_PARAM_1 (0xc6a000)
  213214. +#define HX8369_CMD_SETMIPI_PARAM_2 (0x10000a00)
  213215. +#define HX8369_CMD_SETMIPI_ONELANE (0x10 << 24)
  213216. +#define HX8369_CMD_SETMIPI_TWOLANE (0x11 << 24)
  213217. +#define HX8369_CMD_SETMIPI_PARAM_3 (0x00026f30)
  213218. +#define HX8369_CMD_SETMIPI_PARAM_4 (0x4018)
  213219. +
  213220. +#define HX8369_CMD_SETPIXEL_FMT (0x3A)
  213221. +#define HX8369_CMD_SETPIXEL_FMT_24BPP (0x77)
  213222. +#define HX8369_CMD_SETPIXEL_FMT_18BPP (0x66)
  213223. +#define HX8369_CMD_SETPIXEL_FMT_16BPP (0x55)
  213224. +
  213225. +#define HX8369_CMD_SETCLUMN_ADDR (0x2A)
  213226. +#define HX8369_CMD_SETCLUMN_ADDR_LEN (5)
  213227. +#define HX8369_CMD_SETCLUMN_ADDR_PARAM_1 (0xdf0000)
  213228. +#define HX8369_CMD_SETCLUMN_ADDR_PARAM_2 (0x01)
  213229. +
  213230. +#define HX8369_CMD_SETPAGE_ADDR (0x2B)
  213231. +#define HX8369_CMD_SETPAGE_ADDR_LEN (5)
  213232. +#define HX8369_CMD_SETPAGE_ADDR_PARAM_1 (0x1f0000)
  213233. +#define HX8369_CMD_SETPAGE_ADDR_PARAM_2 (0x03)
  213234. +
  213235. +#define HX8369_CMD_WRT_DISP_BRIGHT (0x51)
  213236. +#define HX8369_CMD_WRT_DISP_BRIGHT_PARAM_1 (0xFF)
  213237. +
  213238. +#define HX8369_CMD_WRT_CABC_MIN_BRIGHT (0x5E)
  213239. +#define HX8369_CMD_WRT_CABC_MIN_BRIGHT_PARAM_1 (0x20)
  213240. +
  213241. +#define HX8369_CMD_WRT_CABC_CTRL (0x55)
  213242. +#define HX8369_CMD_WRT_CABC_CTRL_PARAM_1 (0x1)
  213243. +
  213244. +#define HX8369_CMD_WRT_CTRL_DISP (0x53)
  213245. +#define HX8369_CMD_WRT_CTRL_DISP_PARAM_1 (0x24)
  213246. +
  213247. +#define CHECK_RETCODE(ret) \
  213248. +do { \
  213249. + if (ret < 0) { \
  213250. + dev_err(&mipi_dsi->pdev->dev, \
  213251. + "%s ERR: ret:%d, line:%d.\n", \
  213252. + __func__, ret, __LINE__); \
  213253. + return ret; \
  213254. + } \
  213255. +} while (0)
  213256. +
  213257. +static int hx8369bl_brightness;
  213258. +static int mipid_init_backlight(struct mipi_dsi_info *mipi_dsi);
  213259. +
  213260. +static struct fb_videomode truly_lcd_modedb[] = {
  213261. + {
  213262. + "TRULY-WVGA", 64, 480, 800, 37880,
  213263. + 8, 8,
  213264. + 6, 6,
  213265. + 8, 6,
  213266. + FB_SYNC_OE_LOW_ACT,
  213267. + FB_VMODE_NONINTERLACED,
  213268. + 0,
  213269. + },
  213270. +};
  213271. +
  213272. +static struct mipi_lcd_config lcd_config = {
  213273. + .virtual_ch = 0x0,
  213274. + .data_lane_num = HX8369_TWO_DATA_LANE,
  213275. + .max_phy_clk = HX8369_MAX_DPHY_CLK,
  213276. + .dpi_fmt = MIPI_RGB888,
  213277. +};
  213278. +void mipid_hx8369_get_lcd_videomode(struct fb_videomode **mode, int *size,
  213279. + struct mipi_lcd_config **data)
  213280. +{
  213281. + *mode = &truly_lcd_modedb[0];
  213282. + *size = ARRAY_SIZE(truly_lcd_modedb);
  213283. + *data = &lcd_config;
  213284. +}
  213285. +
  213286. +int mipid_hx8369_lcd_setup(struct mipi_dsi_info *mipi_dsi)
  213287. +{
  213288. + u32 buf[DSI_CMD_BUF_MAXSIZE];
  213289. + int err;
  213290. +
  213291. + dev_dbg(&mipi_dsi->pdev->dev, "MIPI DSI LCD setup.\n");
  213292. + buf[0] = HX8369_CMD_SETEXTC | (HX8369_CMD_SETEXTC_PARAM_1 << 8);
  213293. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  213294. + buf, HX8369_CMD_SETEXTC_LEN);
  213295. + CHECK_RETCODE(err);
  213296. + buf[0] = MIPI_DSI_MAX_RET_PACK_SIZE;
  213297. + err = mipi_dsi_pkt_write(mipi_dsi,
  213298. + MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
  213299. + buf, 0);
  213300. + CHECK_RETCODE(err);
  213301. + buf[0] = HX8369_CMD_GETHXID;
  213302. + err = mipi_dsi_pkt_read(mipi_dsi,
  213303. + MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM,
  213304. + buf, HX8369_CMD_GETHXID_LEN);
  213305. + if (!err && ((buf[0] & HX8369_ID_MASK) == HX8369_ID)) {
  213306. + dev_info(&mipi_dsi->pdev->dev,
  213307. + "MIPI DSI LCD ID:0x%x.\n", buf[0]);
  213308. + } else {
  213309. + dev_err(&mipi_dsi->pdev->dev,
  213310. + "mipi_dsi_pkt_read err:%d, data:0x%x.\n",
  213311. + err, buf[0]);
  213312. + dev_info(&mipi_dsi->pdev->dev,
  213313. + "MIPI DSI LCD not detected!\n");
  213314. + return err;
  213315. + }
  213316. +
  213317. + /* set LCD resolution as 480RGBx800, DPI interface,
  213318. + * display operation mode: RGB data bypass GRAM mode.
  213319. + */
  213320. + buf[0] = HX8369_CMD_SETDISP | (HX8369_CMD_SETDISP_1_HALT << 8) |
  213321. + (HX8369_CMD_SETDISP_2_RES_MODE << 16) |
  213322. + (HX8369_CMD_SETDISP_3_BP << 24);
  213323. + buf[1] = HX8369_CMD_SETDISP_4_FP | (HX8369_CMD_SETDISP_5_SAP << 8) |
  213324. + (HX8369_CMD_SETDISP_6_GENON << 16) |
  213325. + (HX8369_CMD_SETDISP_7_GENOFF << 24);
  213326. + buf[2] = HX8369_CMD_SETDISP_8_RTN | (HX8369_CMD_SETDISP_9_TEI << 8) |
  213327. + (HX8369_CMD_SETDISP_10_TEP_UP << 16) |
  213328. + (HX8369_CMD_SETDISP_11_TEP_LOW << 24);
  213329. + buf[3] = HX8369_CMD_SETDISP_12_BP_PE |
  213330. + (HX8369_CMD_SETDISP_13_FP_PE << 8) |
  213331. + (HX8369_CMD_SETDISP_14_RTN_PE << 16) |
  213332. + (HX8369_CMD_SETDISP_15_GON << 24);
  213333. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  213334. + buf, HX8369_CMD_SETDISP_LEN);
  213335. + CHECK_RETCODE(err);
  213336. +
  213337. + /* Set display waveform cycle */
  213338. + buf[0] = HX8369_CMD_SETCYC | (HX8369_CMD_SETCYC_PARAM_1 << 8);
  213339. + buf[1] = HX8369_CMD_SETCYC_PARAM_2;
  213340. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  213341. + buf, HX8369_CMD_SETCYC_LEN);
  213342. + CHECK_RETCODE(err);
  213343. +
  213344. + /* Set GIP timing output control */
  213345. + buf[0] = HX8369_CMD_SETGIP | (HX8369_CMD_SETGIP_PARAM_1 << 8);
  213346. + buf[1] = HX8369_CMD_SETGIP_PARAM_2;
  213347. + buf[2] = HX8369_CMD_SETGIP_PARAM_3;
  213348. + buf[3] = HX8369_CMD_SETGIP_PARAM_4;
  213349. + buf[4] = HX8369_CMD_SETGIP_PARAM_5;
  213350. + buf[5] = HX8369_CMD_SETGIP_PARAM_6;
  213351. + buf[6] = HX8369_CMD_SETGIP_PARAM_7;
  213352. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  213353. + HX8369_CMD_SETGIP_LEN);
  213354. + CHECK_RETCODE(err);
  213355. +
  213356. + /* Set power: standby, DC etc. */
  213357. + buf[0] = HX8369_CMD_SETPOWER | (HX8369_CMD_SETPOWER_PARAM_1 << 8);
  213358. + buf[1] = HX8369_CMD_SETPOWER_PARAM_2;
  213359. + buf[2] = HX8369_CMD_SETPOWER_PARAM_3;
  213360. + buf[3] = HX8369_CMD_SETPOWER_PARAM_4;
  213361. + buf[4] = HX8369_CMD_SETPOWER_PARAM_5;
  213362. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  213363. + HX8369_CMD_SETPOWER_LEN);
  213364. + CHECK_RETCODE(err);
  213365. +
  213366. + /* Set VCOM voltage. */
  213367. + buf[0] = HX8369_CMD_SETVCOM | (HX8369_CMD_SETVCOM_PARAM_1 << 8);
  213368. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  213369. + HX8369_CMD_SETVCOM_LEN);
  213370. + CHECK_RETCODE(err);
  213371. +
  213372. + /* Set Panel: BGR/RGB or Inversion. */
  213373. + buf[0] = HX8369_CMD_SETPANEL | (HX8369_CMD_SETPANEL_PARAM_1 << 8);
  213374. + err = mipi_dsi_pkt_write(mipi_dsi,
  213375. + MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM, buf, 0);
  213376. + CHECK_RETCODE(err);
  213377. +
  213378. + /* Set gamma curve related setting */
  213379. + buf[0] = HX8369_CMD_SETGAMMA | (HX8369_CMD_SETGAMMA_PARAM_1 << 8);
  213380. + buf[1] = HX8369_CMD_SETGAMMA_PARAM_2;
  213381. + buf[2] = HX8369_CMD_SETGAMMA_PARAM_3;
  213382. + buf[3] = HX8369_CMD_SETGAMMA_PARAM_4;
  213383. + buf[4] = HX8369_CMD_SETGAMMA_PARAM_5;
  213384. + buf[5] = HX8369_CMD_SETGAMMA_PARAM_6;
  213385. + buf[7] = HX8369_CMD_SETGAMMA_PARAM_7;
  213386. + buf[7] = HX8369_CMD_SETGAMMA_PARAM_8;
  213387. + buf[8] = HX8369_CMD_SETGAMMA_PARAM_9;
  213388. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  213389. + HX8369_CMD_SETGAMMA_LEN);
  213390. + CHECK_RETCODE(err);
  213391. +
  213392. + /* Set MIPI: DPHYCMD & DSICMD, data lane number */
  213393. + buf[0] = HX8369_CMD_SETMIPI | (HX8369_CMD_SETMIPI_PARAM_1 << 8);
  213394. + buf[1] = HX8369_CMD_SETMIPI_PARAM_2;
  213395. + buf[2] = HX8369_CMD_SETMIPI_PARAM_3;
  213396. + if (lcd_config.data_lane_num == HX8369_ONE_DATA_LANE)
  213397. + buf[2] |= HX8369_CMD_SETMIPI_ONELANE;
  213398. + else
  213399. + buf[2] |= HX8369_CMD_SETMIPI_TWOLANE;
  213400. + buf[3] = HX8369_CMD_SETMIPI_PARAM_4;
  213401. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  213402. + HX8369_CMD_SETMIPI_LEN);
  213403. + CHECK_RETCODE(err);
  213404. +
  213405. + /* Set pixel format:24bpp */
  213406. + buf[0] = HX8369_CMD_SETPIXEL_FMT;
  213407. + switch (lcd_config.dpi_fmt) {
  213408. + case MIPI_RGB565_PACKED:
  213409. + case MIPI_RGB565_LOOSELY:
  213410. + case MIPI_RGB565_CONFIG3:
  213411. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_16BPP << 8);
  213412. + break;
  213413. +
  213414. + case MIPI_RGB666_LOOSELY:
  213415. + case MIPI_RGB666_PACKED:
  213416. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_18BPP << 8);
  213417. + break;
  213418. +
  213419. + case MIPI_RGB888:
  213420. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_24BPP << 8);
  213421. + break;
  213422. +
  213423. + default:
  213424. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_24BPP << 8);
  213425. + break;
  213426. + }
  213427. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  213428. + buf, 0);
  213429. + CHECK_RETCODE(err);
  213430. +
  213431. + /* Set column address: 0~479 */
  213432. + buf[0] = HX8369_CMD_SETCLUMN_ADDR |
  213433. + (HX8369_CMD_SETCLUMN_ADDR_PARAM_1 << 8);
  213434. + buf[1] = HX8369_CMD_SETCLUMN_ADDR_PARAM_2;
  213435. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  213436. + buf, HX8369_CMD_SETCLUMN_ADDR_LEN);
  213437. + CHECK_RETCODE(err);
  213438. +
  213439. + /* Set page address: 0~799 */
  213440. + buf[0] = HX8369_CMD_SETPAGE_ADDR |
  213441. + (HX8369_CMD_SETPAGE_ADDR_PARAM_1 << 8);
  213442. + buf[1] = HX8369_CMD_SETPAGE_ADDR_PARAM_2;
  213443. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  213444. + buf, HX8369_CMD_SETPAGE_ADDR_LEN);
  213445. + CHECK_RETCODE(err);
  213446. +
  213447. + /* Set display brightness related */
  213448. + buf[0] = HX8369_CMD_WRT_DISP_BRIGHT |
  213449. + (HX8369_CMD_WRT_DISP_BRIGHT_PARAM_1 << 8);
  213450. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  213451. + buf, 0);
  213452. + CHECK_RETCODE(err);
  213453. +
  213454. + buf[0] = HX8369_CMD_WRT_CABC_CTRL |
  213455. + (HX8369_CMD_WRT_CABC_CTRL_PARAM_1 << 8);
  213456. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  213457. + buf, 0);
  213458. + CHECK_RETCODE(err);
  213459. +
  213460. + buf[0] = HX8369_CMD_WRT_CTRL_DISP |
  213461. + (HX8369_CMD_WRT_CTRL_DISP_PARAM_1 << 8);
  213462. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  213463. + buf, 0);
  213464. + CHECK_RETCODE(err);
  213465. +
  213466. + /* exit sleep mode and set display on */
  213467. + buf[0] = MIPI_DCS_EXIT_SLEEP_MODE;
  213468. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM,
  213469. + buf, 0);
  213470. + CHECK_RETCODE(err);
  213471. + /* To allow time for the supply voltages
  213472. + * and clock circuits to stabilize.
  213473. + */
  213474. + msleep(5);
  213475. + buf[0] = MIPI_DCS_SET_DISPLAY_ON;
  213476. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM,
  213477. + buf, 0);
  213478. + CHECK_RETCODE(err);
  213479. +
  213480. + err = mipid_init_backlight(mipi_dsi);
  213481. + return err;
  213482. +}
  213483. +
  213484. +static int mipid_bl_update_status(struct backlight_device *bl)
  213485. +{
  213486. + u32 buf;
  213487. + int brightness = bl->props.brightness;
  213488. + struct mipi_dsi_info *mipi_dsi = bl_get_data(bl);
  213489. +
  213490. + if (bl->props.power != FB_BLANK_UNBLANK ||
  213491. + bl->props.fb_blank != FB_BLANK_UNBLANK)
  213492. + brightness = 0;
  213493. +
  213494. + buf = HX8369_CMD_WRT_DISP_BRIGHT |
  213495. + ((brightness & HX8369BL_MAX_BRIGHT) << 8);
  213496. + mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  213497. + &buf, 0);
  213498. +
  213499. + hx8369bl_brightness = brightness & HX8369BL_MAX_BRIGHT;
  213500. +
  213501. + dev_dbg(&bl->dev, "mipid backlight bringtness:%d.\n", brightness);
  213502. + return 0;
  213503. +}
  213504. +
  213505. +static int mipid_bl_get_brightness(struct backlight_device *bl)
  213506. +{
  213507. + return hx8369bl_brightness;
  213508. +}
  213509. +
  213510. +static int mipi_bl_check_fb(struct backlight_device *bl, struct fb_info *fbi)
  213511. +{
  213512. + return 0;
  213513. +}
  213514. +
  213515. +static const struct backlight_ops mipid_lcd_bl_ops = {
  213516. + .update_status = mipid_bl_update_status,
  213517. + .get_brightness = mipid_bl_get_brightness,
  213518. + .check_fb = mipi_bl_check_fb,
  213519. +};
  213520. +
  213521. +static int mipid_init_backlight(struct mipi_dsi_info *mipi_dsi)
  213522. +{
  213523. + struct backlight_properties props;
  213524. + struct backlight_device *bl;
  213525. +
  213526. + if (mipi_dsi->bl) {
  213527. + pr_debug("mipid backlight already init!\n");
  213528. + return 0;
  213529. + }
  213530. + memset(&props, 0, sizeof(struct backlight_properties));
  213531. + props.max_brightness = HX8369BL_MAX_BRIGHT;
  213532. + props.type = BACKLIGHT_RAW;
  213533. + bl = backlight_device_register("mipid-bl", &mipi_dsi->pdev->dev,
  213534. + mipi_dsi, &mipid_lcd_bl_ops, &props);
  213535. + if (IS_ERR(bl)) {
  213536. + pr_err("error %ld on backlight register\n", PTR_ERR(bl));
  213537. + return PTR_ERR(bl);
  213538. + }
  213539. + mipi_dsi->bl = bl;
  213540. + bl->props.power = FB_BLANK_UNBLANK;
  213541. + bl->props.fb_blank = FB_BLANK_UNBLANK;
  213542. + bl->props.brightness = HX8369BL_DEF_BRIGHT;
  213543. +
  213544. + mipid_bl_update_status(bl);
  213545. + return 0;
  213546. +}
  213547. diff -Nur linux-3.14.14/drivers/video/mxc/mxc_hdmi.c linux-imx6-3.14/drivers/video/mxc/mxc_hdmi.c
  213548. --- linux-3.14.14/drivers/video/mxc/mxc_hdmi.c 1969-12-31 18:00:00.000000000 -0600
  213549. +++ linux-imx6-3.14/drivers/video/mxc/mxc_hdmi.c 2014-12-08 00:31:54.860418001 -0600
  213550. @@ -0,0 +1,3042 @@
  213551. +/*
  213552. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
  213553. + *
  213554. + * This program is free software; you can redistribute it and/or modify
  213555. + * it under the terms of the GNU General Public License as published by
  213556. + * the Free Software Foundation; either version 2 of the License, or
  213557. + * (at your option) any later version.
  213558. + *
  213559. + * This program is distributed in the hope that it will be useful,
  213560. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  213561. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  213562. + * GNU General Public License for more details.
  213563. + *
  213564. + * You should have received a copy of the GNU General Public License
  213565. + * along with this program; if not, write to the Free Software
  213566. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  213567. + *
  213568. + */
  213569. +/*
  213570. + * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
  213571. + * for SLISHDMI13T and SLIPHDMIT IP cores
  213572. + *
  213573. + * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  213574. + *
  213575. + * This program is free software; you can redistribute it and/or modify
  213576. + * it under the terms of the GNU General Public License version 2 as
  213577. + * published by the Free Software Foundation.
  213578. + */
  213579. +
  213580. +#include <linux/module.h>
  213581. +#include <linux/kernel.h>
  213582. +#include <linux/device.h>
  213583. +#include <linux/platform_device.h>
  213584. +#include <linux/input.h>
  213585. +#include <linux/interrupt.h>
  213586. +#include <linux/irq.h>
  213587. +#include <linux/io.h>
  213588. +#include <linux/fb.h>
  213589. +#include <linux/init.h>
  213590. +#include <linux/list.h>
  213591. +#include <linux/delay.h>
  213592. +#include <linux/dma-mapping.h>
  213593. +#include <linux/err.h>
  213594. +#include <linux/clk.h>
  213595. +#include <linux/uaccess.h>
  213596. +#include <linux/cpufreq.h>
  213597. +#include <linux/firmware.h>
  213598. +#include <linux/kthread.h>
  213599. +#include <linux/regulator/driver.h>
  213600. +#include <linux/fsl_devices.h>
  213601. +#include <linux/ipu.h>
  213602. +#include <linux/regmap.h>
  213603. +#include <linux/pinctrl/consumer.h>
  213604. +#include <linux/of_device.h>
  213605. +
  213606. +#include <linux/console.h>
  213607. +#include <linux/types.h>
  213608. +
  213609. +#include "../edid.h"
  213610. +#include <video/mxc_edid.h>
  213611. +#include <video/mxc_hdmi.h>
  213612. +#include "mxc_dispdrv.h"
  213613. +
  213614. +#include <linux/mfd/mxc-hdmi-core.h>
  213615. +
  213616. +#define DISPDRV_HDMI "hdmi"
  213617. +#define HDMI_EDID_LEN 512
  213618. +
  213619. +/* status codes for reading edid */
  213620. +#define HDMI_EDID_SUCCESS 0
  213621. +#define HDMI_EDID_FAIL -1
  213622. +#define HDMI_EDID_SAME -2
  213623. +#define HDMI_EDID_NO_MODES -3
  213624. +
  213625. +#define NUM_CEA_VIDEO_MODES 64
  213626. +#define DEFAULT_VIDEO_MODE 16 /* 1080P */
  213627. +
  213628. +#define RGB 0
  213629. +#define YCBCR444 1
  213630. +#define YCBCR422_16BITS 2
  213631. +#define YCBCR422_8BITS 3
  213632. +#define XVYCC444 4
  213633. +
  213634. +/*
  213635. + * We follow a flowchart which is in the "Synopsys DesignWare Courses
  213636. + * HDMI Transmitter Controller User Guide, 1.30a", section 3.1
  213637. + * (dwc_hdmi_tx_user.pdf)
  213638. + *
  213639. + * Below are notes that say "HDMI Initialization Step X"
  213640. + * These correspond to the flowchart.
  213641. + */
  213642. +
  213643. +/*
  213644. + * We are required to configure VGA mode before reading edid
  213645. + * in HDMI Initialization Step B
  213646. + */
  213647. +static const struct fb_videomode vga_mode = {
  213648. + /* 640x480 @ 60 Hz, 31.5 kHz hsync */
  213649. + NULL, 60, 640, 480, 39721, 48, 16, 33, 10, 96, 2, 0,
  213650. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, FB_MODE_IS_VESA,
  213651. +};
  213652. +
  213653. +enum hdmi_datamap {
  213654. + RGB444_8B = 0x01,
  213655. + RGB444_10B = 0x03,
  213656. + RGB444_12B = 0x05,
  213657. + RGB444_16B = 0x07,
  213658. + YCbCr444_8B = 0x09,
  213659. + YCbCr444_10B = 0x0B,
  213660. + YCbCr444_12B = 0x0D,
  213661. + YCbCr444_16B = 0x0F,
  213662. + YCbCr422_8B = 0x16,
  213663. + YCbCr422_10B = 0x14,
  213664. + YCbCr422_12B = 0x12,
  213665. +};
  213666. +
  213667. +enum hdmi_colorimetry {
  213668. + eITU601,
  213669. + eITU709,
  213670. +};
  213671. +
  213672. +struct hdmi_vmode {
  213673. + bool mDVI;
  213674. + bool mHSyncPolarity;
  213675. + bool mVSyncPolarity;
  213676. + bool mInterlaced;
  213677. + bool mDataEnablePolarity;
  213678. +
  213679. + unsigned int mPixelClock;
  213680. + unsigned int mPixelRepetitionInput;
  213681. + unsigned int mPixelRepetitionOutput;
  213682. +};
  213683. +
  213684. +struct hdmi_data_info {
  213685. + unsigned int enc_in_format;
  213686. + unsigned int enc_out_format;
  213687. + unsigned int enc_color_depth;
  213688. + unsigned int colorimetry;
  213689. + unsigned int pix_repet_factor;
  213690. + unsigned int hdcp_enable;
  213691. + unsigned int rgb_out_enable;
  213692. + unsigned int rgb_quant_range;
  213693. + struct hdmi_vmode video_mode;
  213694. +};
  213695. +
  213696. +struct hdmi_phy_reg_config {
  213697. + /* HDMI PHY register config for pass HCT */
  213698. + u16 reg_vlev;
  213699. + u16 reg_cksymtx;
  213700. +};
  213701. +
  213702. +struct mxc_hdmi {
  213703. + struct platform_device *pdev;
  213704. + struct platform_device *core_pdev;
  213705. + struct mxc_dispdrv_handle *disp_mxc_hdmi;
  213706. + struct fb_info *fbi;
  213707. + struct clk *hdmi_isfr_clk;
  213708. + struct clk *hdmi_iahb_clk;
  213709. + struct timer_list jitter_timer;
  213710. + struct work_struct hotplug_work;
  213711. + struct delayed_work hdcp_hdp_work;
  213712. +
  213713. + struct notifier_block nb;
  213714. +
  213715. + struct hdmi_data_info hdmi_data;
  213716. + int vic;
  213717. + int edid_status;
  213718. + struct mxc_edid_cfg edid_cfg;
  213719. + u8 edid[HDMI_EDID_LEN];
  213720. + bool fb_reg;
  213721. + bool cable_plugin;
  213722. + u8 blank;
  213723. + bool dft_mode_set;
  213724. + char *dft_mode_str;
  213725. + int default_bpp;
  213726. + u8 latest_intr_stat;
  213727. + u8 plug_event;
  213728. + u8 plug_mask;
  213729. + bool irq_enabled;
  213730. + spinlock_t irq_lock;
  213731. + bool phy_enabled;
  213732. + struct fb_videomode default_mode;
  213733. + struct fb_videomode previous_non_vga_mode;
  213734. + bool requesting_vga_for_initialization;
  213735. +
  213736. + int *gpr_base;
  213737. + int *gpr_hdmi_base;
  213738. + int *gpr_sdma_base;
  213739. + int cpu_type;
  213740. + int cpu_version;
  213741. + struct hdmi_phy_reg_config phy_config;
  213742. +
  213743. + struct pinctrl *pinctrl;
  213744. +};
  213745. +
  213746. +static int hdmi_major;
  213747. +static struct class *hdmi_class;
  213748. +
  213749. +struct i2c_client *hdmi_i2c;
  213750. +struct mxc_hdmi *g_hdmi;
  213751. +
  213752. +static bool hdmi_inited;
  213753. +static bool hdcp_init;
  213754. +
  213755. +extern const struct fb_videomode mxc_cea_mode[64];
  213756. +extern void mxc_hdmi_cec_handle(u16 cec_stat);
  213757. +
  213758. +static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event);
  213759. +static void hdmi_enable_overflow_interrupts(void);
  213760. +static void hdmi_disable_overflow_interrupts(void);
  213761. +
  213762. +static char *rgb_quant_range = "default";
  213763. +module_param(rgb_quant_range, charp, S_IRUGO);
  213764. +MODULE_PARM_DESC(rgb_quant_range, "RGB Quant Range (default, limited, full)");
  213765. +
  213766. +static struct platform_device_id imx_hdmi_devtype[] = {
  213767. + {
  213768. + .name = "hdmi-imx6DL",
  213769. + .driver_data = IMX6DL_HDMI,
  213770. + }, {
  213771. + .name = "hdmi-imx6Q",
  213772. + .driver_data = IMX6Q_HDMI,
  213773. + }, {
  213774. + /* sentinel */
  213775. + }
  213776. +};
  213777. +MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
  213778. +
  213779. +static const struct of_device_id imx_hdmi_dt_ids[] = {
  213780. + { .compatible = "fsl,imx6dl-hdmi-video", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
  213781. + { .compatible = "fsl,imx6q-hdmi-video", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
  213782. + { /* sentinel */ }
  213783. +};
  213784. +MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
  213785. +
  213786. +static inline int cpu_is_imx6dl(struct mxc_hdmi *hdmi)
  213787. +{
  213788. + return hdmi->cpu_type == IMX6DL_HDMI;
  213789. +}
  213790. +#ifdef DEBUG
  213791. +static void dump_fb_videomode(struct fb_videomode *m)
  213792. +{
  213793. + pr_debug("fb_videomode = %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
  213794. + m->refresh, m->xres, m->yres, m->pixclock, m->left_margin,
  213795. + m->right_margin, m->upper_margin, m->lower_margin,
  213796. + m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
  213797. +}
  213798. +#else
  213799. +static void dump_fb_videomode(struct fb_videomode *m)
  213800. +{}
  213801. +#endif
  213802. +
  213803. +static ssize_t mxc_hdmi_show_name(struct device *dev,
  213804. + struct device_attribute *attr, char *buf)
  213805. +{
  213806. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213807. +
  213808. + strcpy(buf, hdmi->fbi->fix.id);
  213809. + sprintf(buf+strlen(buf), "\n");
  213810. +
  213811. + return strlen(buf);
  213812. +}
  213813. +
  213814. +static DEVICE_ATTR(fb_name, S_IRUGO, mxc_hdmi_show_name, NULL);
  213815. +
  213816. +static ssize_t mxc_hdmi_show_state(struct device *dev,
  213817. + struct device_attribute *attr, char *buf)
  213818. +{
  213819. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213820. +
  213821. + if (hdmi->cable_plugin == false)
  213822. + strcpy(buf, "plugout\n");
  213823. + else
  213824. + strcpy(buf, "plugin\n");
  213825. +
  213826. + return strlen(buf);
  213827. +}
  213828. +
  213829. +static DEVICE_ATTR(cable_state, S_IRUGO, mxc_hdmi_show_state, NULL);
  213830. +
  213831. +static ssize_t mxc_hdmi_show_edid(struct device *dev,
  213832. + struct device_attribute *attr, char *buf)
  213833. +{
  213834. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213835. + int i, j, len = 0;
  213836. +
  213837. + for (j = 0; j < HDMI_EDID_LEN/16; j++) {
  213838. + for (i = 0; i < 16; i++)
  213839. + len += sprintf(buf+len, "0x%02X ",
  213840. + hdmi->edid[j*16 + i]);
  213841. + len += sprintf(buf+len, "\n");
  213842. + }
  213843. +
  213844. + return len;
  213845. +}
  213846. +
  213847. +static DEVICE_ATTR(edid, S_IRUGO, mxc_hdmi_show_edid, NULL);
  213848. +
  213849. +static ssize_t mxc_hdmi_show_rgb_out_enable(struct device *dev,
  213850. + struct device_attribute *attr, char *buf)
  213851. +{
  213852. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213853. +
  213854. + if (hdmi->hdmi_data.rgb_out_enable == true)
  213855. + strcpy(buf, "RGB out\n");
  213856. + else
  213857. + strcpy(buf, "YCbCr out\n");
  213858. +
  213859. + return strlen(buf);
  213860. +}
  213861. +
  213862. +static ssize_t mxc_hdmi_store_rgb_out_enable(struct device *dev,
  213863. + struct device_attribute *attr, const char *buf, size_t count)
  213864. +{
  213865. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213866. + unsigned long value;
  213867. + int ret;
  213868. +
  213869. + ret = strict_strtoul(buf, 10, &value);
  213870. + if (ret)
  213871. + return ret;
  213872. +
  213873. + hdmi->hdmi_data.rgb_out_enable = value;
  213874. +
  213875. + /* Reconfig HDMI for output color space change */
  213876. + mxc_hdmi_setup(hdmi, 0);
  213877. +
  213878. + return count;
  213879. +}
  213880. +
  213881. +static DEVICE_ATTR(rgb_out_enable, S_IRUGO | S_IWUSR,
  213882. + mxc_hdmi_show_rgb_out_enable,
  213883. + mxc_hdmi_store_rgb_out_enable);
  213884. +
  213885. +static ssize_t mxc_hdmi_show_rgb_quant_range(struct device *dev,
  213886. + struct device_attribute *attr, char *buf)
  213887. +{
  213888. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213889. +
  213890. + switch (hdmi->hdmi_data.rgb_quant_range) {
  213891. + case HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE:
  213892. + strcpy(buf, "limited\n");
  213893. + break;
  213894. + case HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE:
  213895. + strcpy(buf, "full\n");
  213896. + break;
  213897. + case HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT:
  213898. + default:
  213899. + strcpy(buf, "default\n");
  213900. + break;
  213901. + };
  213902. +
  213903. + return strlen(buf);
  213904. +}
  213905. +
  213906. +static ssize_t mxc_hdmi_store_rgb_quant_range(struct device *dev,
  213907. + struct device_attribute *attr, const char *buf, size_t count)
  213908. +{
  213909. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213910. + int ret = count;
  213911. +
  213912. + if (sysfs_streq("limited", buf)) {
  213913. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE;
  213914. + } else if (sysfs_streq("full", buf)) {
  213915. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE;
  213916. + } else if (sysfs_streq("default", buf)) {
  213917. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT;
  213918. + } else {
  213919. + ret = -EINVAL;
  213920. + goto out;
  213921. + }
  213922. +
  213923. + /* Reconfig HDMI for output RGB Quant Range change if using RGB out */
  213924. + if(hdmi->hdmi_data.rgb_out_enable)
  213925. + mxc_hdmi_setup(hdmi, 0);
  213926. +out:
  213927. + return ret;
  213928. +}
  213929. +
  213930. +static DEVICE_ATTR(rgb_quant_range, S_IRUGO | S_IWUSR,
  213931. + mxc_hdmi_show_rgb_quant_range,
  213932. + mxc_hdmi_store_rgb_quant_range);
  213933. +
  213934. +static ssize_t mxc_hdmi_show_hdcp_enable(struct device *dev,
  213935. + struct device_attribute *attr, char *buf)
  213936. +{
  213937. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213938. +
  213939. + if (hdmi->hdmi_data.hdcp_enable == false)
  213940. + strcpy(buf, "hdcp disable\n");
  213941. + else
  213942. + strcpy(buf, "hdcp enable\n");
  213943. +
  213944. + return strlen(buf);
  213945. +
  213946. +}
  213947. +
  213948. +static ssize_t mxc_hdmi_store_hdcp_enable(struct device *dev,
  213949. + struct device_attribute *attr, const char *buf, size_t count)
  213950. +{
  213951. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  213952. + char event_string[32];
  213953. + char *envp[] = { event_string, NULL };
  213954. + unsigned long value;
  213955. + int ret;
  213956. +
  213957. + ret = strict_strtoul(buf, 10, &value);
  213958. + if (ret)
  213959. + return ret;
  213960. +
  213961. + hdmi->hdmi_data.hdcp_enable = value;
  213962. +
  213963. + /* Reconfig HDMI for HDCP */
  213964. + mxc_hdmi_setup(hdmi, 0);
  213965. +
  213966. + if (hdmi->hdmi_data.hdcp_enable == false) {
  213967. + sprintf(event_string, "EVENT=hdcpdisable");
  213968. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  213969. + } else {
  213970. + sprintf(event_string, "EVENT=hdcpenable");
  213971. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  213972. + }
  213973. +
  213974. + return count;
  213975. +
  213976. +}
  213977. +
  213978. +static DEVICE_ATTR(hdcp_enable, S_IRUGO | S_IWUSR,
  213979. + mxc_hdmi_show_hdcp_enable, mxc_hdmi_store_hdcp_enable);
  213980. +
  213981. +/*!
  213982. + * this submodule is responsible for the video data synchronization.
  213983. + * for example, for RGB 4:4:4 input, the data map is defined as
  213984. + * pin{47~40} <==> R[7:0]
  213985. + * pin{31~24} <==> G[7:0]
  213986. + * pin{15~8} <==> B[7:0]
  213987. + */
  213988. +static void hdmi_video_sample(struct mxc_hdmi *hdmi)
  213989. +{
  213990. + int color_format = 0;
  213991. + u8 val;
  213992. +
  213993. + if (hdmi->hdmi_data.enc_in_format == RGB) {
  213994. + if (hdmi->hdmi_data.enc_color_depth == 8)
  213995. + color_format = 0x01;
  213996. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  213997. + color_format = 0x03;
  213998. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  213999. + color_format = 0x05;
  214000. + else if (hdmi->hdmi_data.enc_color_depth == 16)
  214001. + color_format = 0x07;
  214002. + else
  214003. + return;
  214004. + } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) {
  214005. + if (hdmi->hdmi_data.enc_color_depth == 8)
  214006. + color_format = 0x09;
  214007. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  214008. + color_format = 0x0B;
  214009. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  214010. + color_format = 0x0D;
  214011. + else if (hdmi->hdmi_data.enc_color_depth == 16)
  214012. + color_format = 0x0F;
  214013. + else
  214014. + return;
  214015. + } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) {
  214016. + if (hdmi->hdmi_data.enc_color_depth == 8)
  214017. + color_format = 0x16;
  214018. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  214019. + color_format = 0x14;
  214020. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  214021. + color_format = 0x12;
  214022. + else
  214023. + return;
  214024. + }
  214025. +
  214026. + val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
  214027. + ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
  214028. + HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
  214029. + hdmi_writeb(val, HDMI_TX_INVID0);
  214030. +
  214031. + /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
  214032. + val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
  214033. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
  214034. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
  214035. + hdmi_writeb(val, HDMI_TX_INSTUFFING);
  214036. + hdmi_writeb(0x0, HDMI_TX_GYDATA0);
  214037. + hdmi_writeb(0x0, HDMI_TX_GYDATA1);
  214038. + hdmi_writeb(0x0, HDMI_TX_RCRDATA0);
  214039. + hdmi_writeb(0x0, HDMI_TX_RCRDATA1);
  214040. + hdmi_writeb(0x0, HDMI_TX_BCBDATA0);
  214041. + hdmi_writeb(0x0, HDMI_TX_BCBDATA1);
  214042. +}
  214043. +
  214044. +static int isColorSpaceConversion(struct mxc_hdmi *hdmi)
  214045. +{
  214046. + return (hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format) ||
  214047. + (hdmi->hdmi_data.enc_out_format == RGB &&
  214048. + ((hdmi->hdmi_data.rgb_quant_range == HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE) ||
  214049. + (hdmi->hdmi_data.rgb_quant_range == HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT && hdmi->vic > 1)));
  214050. +}
  214051. +
  214052. +static int isColorSpaceDecimation(struct mxc_hdmi *hdmi)
  214053. +{
  214054. + return ((hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) &&
  214055. + (hdmi->hdmi_data.enc_in_format == RGB ||
  214056. + hdmi->hdmi_data.enc_in_format == YCBCR444));
  214057. +}
  214058. +
  214059. +static int isColorSpaceInterpolation(struct mxc_hdmi *hdmi)
  214060. +{
  214061. + return ((hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) &&
  214062. + (hdmi->hdmi_data.enc_out_format == RGB
  214063. + || hdmi->hdmi_data.enc_out_format == YCBCR444));
  214064. +}
  214065. +
  214066. +/*!
  214067. + * update the color space conversion coefficients.
  214068. + */
  214069. +static void update_csc_coeffs(struct mxc_hdmi *hdmi)
  214070. +{
  214071. + unsigned short csc_coeff[3][4];
  214072. + unsigned int csc_scale = 1;
  214073. + u8 val;
  214074. + bool coeff_selected = false;
  214075. +
  214076. + if (isColorSpaceConversion(hdmi)) { /* csc needed */
  214077. + if (hdmi->hdmi_data.enc_out_format == RGB) {
  214078. + if (hdmi->hdmi_data.enc_in_format == RGB) {
  214079. + csc_coeff[0][0] = 0x1b80;
  214080. + csc_coeff[0][1] = 0x0000;
  214081. + csc_coeff[0][2] = 0x0000;
  214082. + csc_coeff[0][3] = 0x0020;
  214083. +
  214084. + csc_coeff[1][0] = 0x0000;
  214085. + csc_coeff[1][1] = 0x1b80;
  214086. + csc_coeff[1][2] = 0x0000;
  214087. + csc_coeff[1][3] = 0x0020;
  214088. +
  214089. + csc_coeff[2][0] = 0x0000;
  214090. + csc_coeff[2][1] = 0x0000;
  214091. + csc_coeff[2][2] = 0x1b80;
  214092. + csc_coeff[2][3] = 0x0020;
  214093. +
  214094. + csc_scale = 1;
  214095. + coeff_selected = true;
  214096. + } else if (hdmi->hdmi_data.colorimetry == eITU601) {
  214097. + csc_coeff[0][0] = 0x2000;
  214098. + csc_coeff[0][1] = 0x6926;
  214099. + csc_coeff[0][2] = 0x74fd;
  214100. + csc_coeff[0][3] = 0x010e;
  214101. +
  214102. + csc_coeff[1][0] = 0x2000;
  214103. + csc_coeff[1][1] = 0x2cdd;
  214104. + csc_coeff[1][2] = 0x0000;
  214105. + csc_coeff[1][3] = 0x7e9a;
  214106. +
  214107. + csc_coeff[2][0] = 0x2000;
  214108. + csc_coeff[2][1] = 0x0000;
  214109. + csc_coeff[2][2] = 0x38b4;
  214110. + csc_coeff[2][3] = 0x7e3b;
  214111. +
  214112. + csc_scale = 1;
  214113. + coeff_selected = true;
  214114. + } else if (hdmi->hdmi_data.colorimetry == eITU709) {
  214115. + csc_coeff[0][0] = 0x2000;
  214116. + csc_coeff[0][1] = 0x7106;
  214117. + csc_coeff[0][2] = 0x7a02;
  214118. + csc_coeff[0][3] = 0x00a7;
  214119. +
  214120. + csc_coeff[1][0] = 0x2000;
  214121. + csc_coeff[1][1] = 0x3264;
  214122. + csc_coeff[1][2] = 0x0000;
  214123. + csc_coeff[1][3] = 0x7e6d;
  214124. +
  214125. + csc_coeff[2][0] = 0x2000;
  214126. + csc_coeff[2][1] = 0x0000;
  214127. + csc_coeff[2][2] = 0x3b61;
  214128. + csc_coeff[2][3] = 0x7e25;
  214129. +
  214130. + csc_scale = 1;
  214131. + coeff_selected = true;
  214132. + }
  214133. + } else if (hdmi->hdmi_data.enc_in_format == RGB) {
  214134. + if (hdmi->hdmi_data.colorimetry == eITU601) {
  214135. + csc_coeff[0][0] = 0x2591;
  214136. + csc_coeff[0][1] = 0x1322;
  214137. + csc_coeff[0][2] = 0x074b;
  214138. + csc_coeff[0][3] = 0x0000;
  214139. +
  214140. + csc_coeff[1][0] = 0x6535;
  214141. + csc_coeff[1][1] = 0x2000;
  214142. + csc_coeff[1][2] = 0x7acc;
  214143. + csc_coeff[1][3] = 0x0200;
  214144. +
  214145. + csc_coeff[2][0] = 0x6acd;
  214146. + csc_coeff[2][1] = 0x7534;
  214147. + csc_coeff[2][2] = 0x2000;
  214148. + csc_coeff[2][3] = 0x0200;
  214149. +
  214150. + csc_scale = 0;
  214151. + coeff_selected = true;
  214152. + } else if (hdmi->hdmi_data.colorimetry == eITU709) {
  214153. + csc_coeff[0][0] = 0x2dc5;
  214154. + csc_coeff[0][1] = 0x0d9b;
  214155. + csc_coeff[0][2] = 0x049e;
  214156. + csc_coeff[0][3] = 0x0000;
  214157. +
  214158. + csc_coeff[1][0] = 0x62f0;
  214159. + csc_coeff[1][1] = 0x2000;
  214160. + csc_coeff[1][2] = 0x7d11;
  214161. + csc_coeff[1][3] = 0x0200;
  214162. +
  214163. + csc_coeff[2][0] = 0x6756;
  214164. + csc_coeff[2][1] = 0x78ab;
  214165. + csc_coeff[2][2] = 0x2000;
  214166. + csc_coeff[2][3] = 0x0200;
  214167. +
  214168. + csc_scale = 0;
  214169. + coeff_selected = true;
  214170. + }
  214171. + }
  214172. + }
  214173. +
  214174. + if (!coeff_selected) {
  214175. + csc_coeff[0][0] = 0x2000;
  214176. + csc_coeff[0][1] = 0x0000;
  214177. + csc_coeff[0][2] = 0x0000;
  214178. + csc_coeff[0][3] = 0x0000;
  214179. +
  214180. + csc_coeff[1][0] = 0x0000;
  214181. + csc_coeff[1][1] = 0x2000;
  214182. + csc_coeff[1][2] = 0x0000;
  214183. + csc_coeff[1][3] = 0x0000;
  214184. +
  214185. + csc_coeff[2][0] = 0x0000;
  214186. + csc_coeff[2][1] = 0x0000;
  214187. + csc_coeff[2][2] = 0x2000;
  214188. + csc_coeff[2][3] = 0x0000;
  214189. +
  214190. + csc_scale = 1;
  214191. + }
  214192. +
  214193. + /* Update CSC parameters in HDMI CSC registers */
  214194. + hdmi_writeb((unsigned char)(csc_coeff[0][0] & 0xFF),
  214195. + HDMI_CSC_COEF_A1_LSB);
  214196. + hdmi_writeb((unsigned char)(csc_coeff[0][0] >> 8),
  214197. + HDMI_CSC_COEF_A1_MSB);
  214198. + hdmi_writeb((unsigned char)(csc_coeff[0][1] & 0xFF),
  214199. + HDMI_CSC_COEF_A2_LSB);
  214200. + hdmi_writeb((unsigned char)(csc_coeff[0][1] >> 8),
  214201. + HDMI_CSC_COEF_A2_MSB);
  214202. + hdmi_writeb((unsigned char)(csc_coeff[0][2] & 0xFF),
  214203. + HDMI_CSC_COEF_A3_LSB);
  214204. + hdmi_writeb((unsigned char)(csc_coeff[0][2] >> 8),
  214205. + HDMI_CSC_COEF_A3_MSB);
  214206. + hdmi_writeb((unsigned char)(csc_coeff[0][3] & 0xFF),
  214207. + HDMI_CSC_COEF_A4_LSB);
  214208. + hdmi_writeb((unsigned char)(csc_coeff[0][3] >> 8),
  214209. + HDMI_CSC_COEF_A4_MSB);
  214210. +
  214211. + hdmi_writeb((unsigned char)(csc_coeff[1][0] & 0xFF),
  214212. + HDMI_CSC_COEF_B1_LSB);
  214213. + hdmi_writeb((unsigned char)(csc_coeff[1][0] >> 8),
  214214. + HDMI_CSC_COEF_B1_MSB);
  214215. + hdmi_writeb((unsigned char)(csc_coeff[1][1] & 0xFF),
  214216. + HDMI_CSC_COEF_B2_LSB);
  214217. + hdmi_writeb((unsigned char)(csc_coeff[1][1] >> 8),
  214218. + HDMI_CSC_COEF_B2_MSB);
  214219. + hdmi_writeb((unsigned char)(csc_coeff[1][2] & 0xFF),
  214220. + HDMI_CSC_COEF_B3_LSB);
  214221. + hdmi_writeb((unsigned char)(csc_coeff[1][2] >> 8),
  214222. + HDMI_CSC_COEF_B3_MSB);
  214223. + hdmi_writeb((unsigned char)(csc_coeff[1][3] & 0xFF),
  214224. + HDMI_CSC_COEF_B4_LSB);
  214225. + hdmi_writeb((unsigned char)(csc_coeff[1][3] >> 8),
  214226. + HDMI_CSC_COEF_B4_MSB);
  214227. +
  214228. + hdmi_writeb((unsigned char)(csc_coeff[2][0] & 0xFF),
  214229. + HDMI_CSC_COEF_C1_LSB);
  214230. + hdmi_writeb((unsigned char)(csc_coeff[2][0] >> 8),
  214231. + HDMI_CSC_COEF_C1_MSB);
  214232. + hdmi_writeb((unsigned char)(csc_coeff[2][1] & 0xFF),
  214233. + HDMI_CSC_COEF_C2_LSB);
  214234. + hdmi_writeb((unsigned char)(csc_coeff[2][1] >> 8),
  214235. + HDMI_CSC_COEF_C2_MSB);
  214236. + hdmi_writeb((unsigned char)(csc_coeff[2][2] & 0xFF),
  214237. + HDMI_CSC_COEF_C3_LSB);
  214238. + hdmi_writeb((unsigned char)(csc_coeff[2][2] >> 8),
  214239. + HDMI_CSC_COEF_C3_MSB);
  214240. + hdmi_writeb((unsigned char)(csc_coeff[2][3] & 0xFF),
  214241. + HDMI_CSC_COEF_C4_LSB);
  214242. + hdmi_writeb((unsigned char)(csc_coeff[2][3] >> 8),
  214243. + HDMI_CSC_COEF_C4_MSB);
  214244. +
  214245. + val = hdmi_readb(HDMI_CSC_SCALE);
  214246. + val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK;
  214247. + val |= csc_scale & HDMI_CSC_SCALE_CSCSCALE_MASK;
  214248. + hdmi_writeb(val, HDMI_CSC_SCALE);
  214249. +}
  214250. +
  214251. +static void hdmi_video_csc(struct mxc_hdmi *hdmi)
  214252. +{
  214253. + int color_depth = 0;
  214254. + int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
  214255. + int decimation = HDMI_CSC_CFG_DECMODE_DISABLE;
  214256. + u8 val;
  214257. +
  214258. + /* YCC422 interpolation to 444 mode */
  214259. + if (isColorSpaceInterpolation(hdmi))
  214260. + interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
  214261. + else if (isColorSpaceDecimation(hdmi))
  214262. + decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
  214263. +
  214264. + if (hdmi->hdmi_data.enc_color_depth == 8)
  214265. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
  214266. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  214267. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
  214268. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  214269. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
  214270. + else if (hdmi->hdmi_data.enc_color_depth == 16)
  214271. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
  214272. + else
  214273. + return;
  214274. +
  214275. + /*configure the CSC registers */
  214276. + hdmi_writeb(interpolation | decimation, HDMI_CSC_CFG);
  214277. + val = hdmi_readb(HDMI_CSC_SCALE);
  214278. + val &= ~HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK;
  214279. + val |= color_depth;
  214280. + hdmi_writeb(val, HDMI_CSC_SCALE);
  214281. +
  214282. + update_csc_coeffs(hdmi);
  214283. +}
  214284. +
  214285. +/*!
  214286. + * HDMI video packetizer is used to packetize the data.
  214287. + * for example, if input is YCC422 mode or repeater is used,
  214288. + * data should be repacked this module can be bypassed.
  214289. + */
  214290. +static void hdmi_video_packetize(struct mxc_hdmi *hdmi)
  214291. +{
  214292. + unsigned int color_depth = 0;
  214293. + unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
  214294. + unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
  214295. + struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
  214296. + u8 val;
  214297. +
  214298. + if (hdmi_data->enc_out_format == RGB
  214299. + || hdmi_data->enc_out_format == YCBCR444) {
  214300. + if (hdmi_data->enc_color_depth == 0)
  214301. + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
  214302. + else if (hdmi_data->enc_color_depth == 8) {
  214303. + color_depth = 4;
  214304. + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
  214305. + } else if (hdmi_data->enc_color_depth == 10)
  214306. + color_depth = 5;
  214307. + else if (hdmi_data->enc_color_depth == 12)
  214308. + color_depth = 6;
  214309. + else if (hdmi_data->enc_color_depth == 16)
  214310. + color_depth = 7;
  214311. + else
  214312. + return;
  214313. + } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
  214314. + if (hdmi_data->enc_color_depth == 0 ||
  214315. + hdmi_data->enc_color_depth == 8)
  214316. + remap_size = HDMI_VP_REMAP_YCC422_16bit;
  214317. + else if (hdmi_data->enc_color_depth == 10)
  214318. + remap_size = HDMI_VP_REMAP_YCC422_20bit;
  214319. + else if (hdmi_data->enc_color_depth == 12)
  214320. + remap_size = HDMI_VP_REMAP_YCC422_24bit;
  214321. + else
  214322. + return;
  214323. + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
  214324. + } else
  214325. + return;
  214326. +
  214327. + /* HDMI not support deep color,
  214328. + * because IPU MAX support color depth is 24bit */
  214329. + color_depth = 0;
  214330. +
  214331. + /* set the packetizer registers */
  214332. + val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
  214333. + HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
  214334. + ((hdmi_data->pix_repet_factor <<
  214335. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
  214336. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
  214337. + hdmi_writeb(val, HDMI_VP_PR_CD);
  214338. +
  214339. + val = hdmi_readb(HDMI_VP_STUFF);
  214340. + val &= ~HDMI_VP_STUFF_PR_STUFFING_MASK;
  214341. + val |= HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE;
  214342. + hdmi_writeb(val, HDMI_VP_STUFF);
  214343. +
  214344. + /* Data from pixel repeater block */
  214345. + if (hdmi_data->pix_repet_factor > 1) {
  214346. + val = hdmi_readb(HDMI_VP_CONF);
  214347. + val &= ~(HDMI_VP_CONF_PR_EN_MASK |
  214348. + HDMI_VP_CONF_BYPASS_SELECT_MASK);
  214349. + val |= HDMI_VP_CONF_PR_EN_ENABLE |
  214350. + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
  214351. + hdmi_writeb(val, HDMI_VP_CONF);
  214352. + } else { /* data from packetizer block */
  214353. + val = hdmi_readb(HDMI_VP_CONF);
  214354. + val &= ~(HDMI_VP_CONF_PR_EN_MASK |
  214355. + HDMI_VP_CONF_BYPASS_SELECT_MASK);
  214356. + val |= HDMI_VP_CONF_PR_EN_DISABLE |
  214357. + HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
  214358. + hdmi_writeb(val, HDMI_VP_CONF);
  214359. + }
  214360. +
  214361. + val = hdmi_readb(HDMI_VP_STUFF);
  214362. + val &= ~HDMI_VP_STUFF_IDEFAULT_PHASE_MASK;
  214363. + val |= 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET;
  214364. + hdmi_writeb(val, HDMI_VP_STUFF);
  214365. +
  214366. + hdmi_writeb(remap_size, HDMI_VP_REMAP);
  214367. +
  214368. + if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
  214369. + val = hdmi_readb(HDMI_VP_CONF);
  214370. + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
  214371. + HDMI_VP_CONF_PP_EN_ENMASK |
  214372. + HDMI_VP_CONF_YCC422_EN_MASK);
  214373. + val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
  214374. + HDMI_VP_CONF_PP_EN_ENABLE |
  214375. + HDMI_VP_CONF_YCC422_EN_DISABLE;
  214376. + hdmi_writeb(val, HDMI_VP_CONF);
  214377. + } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
  214378. + val = hdmi_readb(HDMI_VP_CONF);
  214379. + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
  214380. + HDMI_VP_CONF_PP_EN_ENMASK |
  214381. + HDMI_VP_CONF_YCC422_EN_MASK);
  214382. + val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
  214383. + HDMI_VP_CONF_PP_EN_DISABLE |
  214384. + HDMI_VP_CONF_YCC422_EN_ENABLE;
  214385. + hdmi_writeb(val, HDMI_VP_CONF);
  214386. + } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
  214387. + val = hdmi_readb(HDMI_VP_CONF);
  214388. + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
  214389. + HDMI_VP_CONF_PP_EN_ENMASK |
  214390. + HDMI_VP_CONF_YCC422_EN_MASK);
  214391. + val |= HDMI_VP_CONF_BYPASS_EN_ENABLE |
  214392. + HDMI_VP_CONF_PP_EN_DISABLE |
  214393. + HDMI_VP_CONF_YCC422_EN_DISABLE;
  214394. + hdmi_writeb(val, HDMI_VP_CONF);
  214395. + } else {
  214396. + return;
  214397. + }
  214398. +
  214399. + val = hdmi_readb(HDMI_VP_STUFF);
  214400. + val &= ~(HDMI_VP_STUFF_PP_STUFFING_MASK |
  214401. + HDMI_VP_STUFF_YCC422_STUFFING_MASK);
  214402. + val |= HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
  214403. + HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE;
  214404. + hdmi_writeb(val, HDMI_VP_STUFF);
  214405. +
  214406. + val = hdmi_readb(HDMI_VP_CONF);
  214407. + val &= ~HDMI_VP_CONF_OUTPUT_SELECTOR_MASK;
  214408. + val |= output_select;
  214409. + hdmi_writeb(val, HDMI_VP_CONF);
  214410. +}
  214411. +
  214412. +#if 0
  214413. +/* Force a fixed color screen */
  214414. +static void hdmi_video_force_output(struct mxc_hdmi *hdmi, unsigned char force)
  214415. +{
  214416. + u8 val;
  214417. +
  214418. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214419. +
  214420. + if (force) {
  214421. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */
  214422. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */
  214423. + hdmi_writeb(0xFF, HDMI_FC_DBGTMDS0); /* B */
  214424. + val = hdmi_readb(HDMI_FC_DBGFORCE);
  214425. + val |= HDMI_FC_DBGFORCE_FORCEVIDEO;
  214426. + hdmi_writeb(val, HDMI_FC_DBGFORCE);
  214427. + } else {
  214428. + val = hdmi_readb(HDMI_FC_DBGFORCE);
  214429. + val &= ~HDMI_FC_DBGFORCE_FORCEVIDEO;
  214430. + hdmi_writeb(val, HDMI_FC_DBGFORCE);
  214431. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */
  214432. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */
  214433. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS0); /* B */
  214434. + }
  214435. +}
  214436. +#endif
  214437. +
  214438. +static inline void hdmi_phy_test_clear(struct mxc_hdmi *hdmi,
  214439. + unsigned char bit)
  214440. +{
  214441. + u8 val = hdmi_readb(HDMI_PHY_TST0);
  214442. + val &= ~HDMI_PHY_TST0_TSTCLR_MASK;
  214443. + val |= (bit << HDMI_PHY_TST0_TSTCLR_OFFSET) &
  214444. + HDMI_PHY_TST0_TSTCLR_MASK;
  214445. + hdmi_writeb(val, HDMI_PHY_TST0);
  214446. +}
  214447. +
  214448. +static inline void hdmi_phy_test_enable(struct mxc_hdmi *hdmi,
  214449. + unsigned char bit)
  214450. +{
  214451. + u8 val = hdmi_readb(HDMI_PHY_TST0);
  214452. + val &= ~HDMI_PHY_TST0_TSTEN_MASK;
  214453. + val |= (bit << HDMI_PHY_TST0_TSTEN_OFFSET) &
  214454. + HDMI_PHY_TST0_TSTEN_MASK;
  214455. + hdmi_writeb(val, HDMI_PHY_TST0);
  214456. +}
  214457. +
  214458. +static inline void hdmi_phy_test_clock(struct mxc_hdmi *hdmi,
  214459. + unsigned char bit)
  214460. +{
  214461. + u8 val = hdmi_readb(HDMI_PHY_TST0);
  214462. + val &= ~HDMI_PHY_TST0_TSTCLK_MASK;
  214463. + val |= (bit << HDMI_PHY_TST0_TSTCLK_OFFSET) &
  214464. + HDMI_PHY_TST0_TSTCLK_MASK;
  214465. + hdmi_writeb(val, HDMI_PHY_TST0);
  214466. +}
  214467. +
  214468. +static inline void hdmi_phy_test_din(struct mxc_hdmi *hdmi,
  214469. + unsigned char bit)
  214470. +{
  214471. + hdmi_writeb(bit, HDMI_PHY_TST1);
  214472. +}
  214473. +
  214474. +static inline void hdmi_phy_test_dout(struct mxc_hdmi *hdmi,
  214475. + unsigned char bit)
  214476. +{
  214477. + hdmi_writeb(bit, HDMI_PHY_TST2);
  214478. +}
  214479. +
  214480. +static bool hdmi_phy_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
  214481. +{
  214482. + unsigned char val = 0;
  214483. + val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
  214484. + while (val == 0) {
  214485. + udelay(1000);
  214486. + if (msec-- == 0)
  214487. + return false;
  214488. + val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
  214489. + }
  214490. + return true;
  214491. +}
  214492. +
  214493. +static void hdmi_phy_i2c_write(struct mxc_hdmi *hdmi, unsigned short data,
  214494. + unsigned char addr)
  214495. +{
  214496. + hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
  214497. + hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
  214498. + hdmi_writeb((unsigned char)(data >> 8),
  214499. + HDMI_PHY_I2CM_DATAO_1_ADDR);
  214500. + hdmi_writeb((unsigned char)(data >> 0),
  214501. + HDMI_PHY_I2CM_DATAO_0_ADDR);
  214502. + hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
  214503. + HDMI_PHY_I2CM_OPERATION_ADDR);
  214504. + hdmi_phy_wait_i2c_done(hdmi, 1000);
  214505. +}
  214506. +
  214507. +#if 0
  214508. +static unsigned short hdmi_phy_i2c_read(struct mxc_hdmi *hdmi,
  214509. + unsigned char addr)
  214510. +{
  214511. + unsigned short data;
  214512. + unsigned char msb = 0, lsb = 0;
  214513. + hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
  214514. + hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
  214515. + hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_READ,
  214516. + HDMI_PHY_I2CM_OPERATION_ADDR);
  214517. + hdmi_phy_wait_i2c_done(hdmi, 1000);
  214518. + msb = hdmi_readb(HDMI_PHY_I2CM_DATAI_1_ADDR);
  214519. + lsb = hdmi_readb(HDMI_PHY_I2CM_DATAI_0_ADDR);
  214520. + data = (msb << 8) | lsb;
  214521. + return data;
  214522. +}
  214523. +
  214524. +static int hdmi_phy_i2c_write_verify(struct mxc_hdmi *hdmi, unsigned short data,
  214525. + unsigned char addr)
  214526. +{
  214527. + unsigned short val = 0;
  214528. + hdmi_phy_i2c_write(hdmi, data, addr);
  214529. + val = hdmi_phy_i2c_read(hdmi, addr);
  214530. + return (val == data);
  214531. +}
  214532. +#endif
  214533. +
  214534. +static bool hdmi_edid_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
  214535. +{
  214536. + unsigned char val = 0;
  214537. + val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2;
  214538. + while (val == 0) {
  214539. +
  214540. + udelay(1000);
  214541. + if (msec-- == 0) {
  214542. + dev_dbg(&hdmi->pdev->dev,
  214543. + "HDMI EDID i2c operation time out!!\n");
  214544. + return false;
  214545. + }
  214546. + val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2;
  214547. + }
  214548. + return true;
  214549. +}
  214550. +
  214551. +static u8 hdmi_edid_i2c_read(struct mxc_hdmi *hdmi,
  214552. + u8 addr, u8 blockno)
  214553. +{
  214554. + u8 spointer = blockno / 2;
  214555. + u8 edidaddress = ((blockno % 2) * 0x80) + addr;
  214556. + u8 data;
  214557. +
  214558. + hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0);
  214559. + hdmi_writeb(edidaddress, HDMI_I2CM_ADDRESS);
  214560. + hdmi_writeb(spointer, HDMI_I2CM_SEGADDR);
  214561. + if (spointer == 0)
  214562. + hdmi_writeb(HDMI_I2CM_OPERATION_READ,
  214563. + HDMI_I2CM_OPERATION);
  214564. + else
  214565. + hdmi_writeb(HDMI_I2CM_OPERATION_READ_EXT,
  214566. + HDMI_I2CM_OPERATION);
  214567. +
  214568. + hdmi_edid_wait_i2c_done(hdmi, 1000);
  214569. + data = hdmi_readb(HDMI_I2CM_DATAI);
  214570. + hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0);
  214571. + return data;
  214572. +}
  214573. +
  214574. +
  214575. +/* "Power-down enable (active low)"
  214576. + * That mean that power up == 1! */
  214577. +static void mxc_hdmi_phy_enable_power(u8 enable)
  214578. +{
  214579. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  214580. + HDMI_PHY_CONF0_PDZ_OFFSET,
  214581. + HDMI_PHY_CONF0_PDZ_MASK);
  214582. +}
  214583. +
  214584. +static void mxc_hdmi_phy_enable_tmds(u8 enable)
  214585. +{
  214586. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  214587. + HDMI_PHY_CONF0_ENTMDS_OFFSET,
  214588. + HDMI_PHY_CONF0_ENTMDS_MASK);
  214589. +}
  214590. +
  214591. +static void mxc_hdmi_phy_gen2_pddq(u8 enable)
  214592. +{
  214593. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  214594. + HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
  214595. + HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
  214596. +}
  214597. +
  214598. +static void mxc_hdmi_phy_gen2_txpwron(u8 enable)
  214599. +{
  214600. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  214601. + HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
  214602. + HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
  214603. +}
  214604. +
  214605. +#if 0
  214606. +static void mxc_hdmi_phy_gen2_enhpdrxsense(u8 enable)
  214607. +{
  214608. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  214609. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET,
  214610. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK);
  214611. +}
  214612. +#endif
  214613. +
  214614. +static void mxc_hdmi_phy_sel_data_en_pol(u8 enable)
  214615. +{
  214616. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  214617. + HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
  214618. + HDMI_PHY_CONF0_SELDATAENPOL_MASK);
  214619. +}
  214620. +
  214621. +static void mxc_hdmi_phy_sel_interface_control(u8 enable)
  214622. +{
  214623. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  214624. + HDMI_PHY_CONF0_SELDIPIF_OFFSET,
  214625. + HDMI_PHY_CONF0_SELDIPIF_MASK);
  214626. +}
  214627. +
  214628. +static int hdmi_phy_configure(struct mxc_hdmi *hdmi, unsigned char pRep,
  214629. + unsigned char cRes, int cscOn)
  214630. +{
  214631. + u8 val;
  214632. + u8 msec;
  214633. +
  214634. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214635. +
  214636. + /* color resolution 0 is 8 bit colour depth */
  214637. + if (cRes == 0)
  214638. + cRes = 8;
  214639. +
  214640. + if (pRep != 0)
  214641. + return false;
  214642. + else if (cRes != 8 && cRes != 12)
  214643. + return false;
  214644. +
  214645. + /* Enable csc path */
  214646. + if (cscOn)
  214647. + val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
  214648. + else
  214649. + val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
  214650. +
  214651. + hdmi_writeb(val, HDMI_MC_FLOWCTRL);
  214652. +
  214653. + /* gen2 tx power off */
  214654. + mxc_hdmi_phy_gen2_txpwron(0);
  214655. +
  214656. + /* gen2 pddq */
  214657. + mxc_hdmi_phy_gen2_pddq(1);
  214658. +
  214659. + /* PHY reset */
  214660. + hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
  214661. + hdmi_writeb(HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
  214662. +
  214663. + hdmi_writeb(HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
  214664. +
  214665. + hdmi_phy_test_clear(hdmi, 1);
  214666. + hdmi_writeb(HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
  214667. + HDMI_PHY_I2CM_SLAVE_ADDR);
  214668. + hdmi_phy_test_clear(hdmi, 0);
  214669. +
  214670. + if (hdmi->hdmi_data.video_mode.mPixelClock < 0) {
  214671. + dev_dbg(&hdmi->pdev->dev, "Pixel clock (%d) must be positive\n",
  214672. + hdmi->hdmi_data.video_mode.mPixelClock);
  214673. + return false;
  214674. + }
  214675. +
  214676. + if (hdmi->hdmi_data.video_mode.mPixelClock <= 45250000) {
  214677. + switch (cRes) {
  214678. + case 8:
  214679. + /* PLL/MPLL Cfg */
  214680. + hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06);
  214681. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); /* GMPCTRL */
  214682. + break;
  214683. + case 10:
  214684. + hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06);
  214685. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
  214686. + break;
  214687. + case 12:
  214688. + hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06);
  214689. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
  214690. + break;
  214691. + default:
  214692. + return false;
  214693. + }
  214694. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 92500000) {
  214695. + switch (cRes) {
  214696. + case 8:
  214697. + hdmi_phy_i2c_write(hdmi, 0x0140, 0x06);
  214698. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
  214699. + break;
  214700. + case 10:
  214701. + hdmi_phy_i2c_write(hdmi, 0x2141, 0x06);
  214702. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
  214703. + break;
  214704. + case 12:
  214705. + hdmi_phy_i2c_write(hdmi, 0x4142, 0x06);
  214706. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
  214707. + default:
  214708. + return false;
  214709. + }
  214710. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 148500000) {
  214711. + switch (cRes) {
  214712. + case 8:
  214713. + hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
  214714. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  214715. + break;
  214716. + case 10:
  214717. + hdmi_phy_i2c_write(hdmi, 0x20a1, 0x06);
  214718. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  214719. + break;
  214720. + case 12:
  214721. + hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06);
  214722. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  214723. + default:
  214724. + return false;
  214725. + }
  214726. + } else {
  214727. + switch (cRes) {
  214728. + case 8:
  214729. + hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
  214730. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  214731. + break;
  214732. + case 10:
  214733. + hdmi_phy_i2c_write(hdmi, 0x2001, 0x06);
  214734. + hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
  214735. + break;
  214736. + case 12:
  214737. + hdmi_phy_i2c_write(hdmi, 0x4002, 0x06);
  214738. + hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
  214739. + default:
  214740. + return false;
  214741. + }
  214742. + }
  214743. +
  214744. + if (hdmi->hdmi_data.video_mode.mPixelClock <= 54000000) {
  214745. + switch (cRes) {
  214746. + case 8:
  214747. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); /* CURRCTRL */
  214748. + break;
  214749. + case 10:
  214750. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  214751. + break;
  214752. + case 12:
  214753. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  214754. + break;
  214755. + default:
  214756. + return false;
  214757. + }
  214758. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 58400000) {
  214759. + switch (cRes) {
  214760. + case 8:
  214761. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  214762. + break;
  214763. + case 10:
  214764. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  214765. + break;
  214766. + case 12:
  214767. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  214768. + break;
  214769. + default:
  214770. + return false;
  214771. + }
  214772. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 72000000) {
  214773. + switch (cRes) {
  214774. + case 8:
  214775. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  214776. + break;
  214777. + case 10:
  214778. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  214779. + break;
  214780. + case 12:
  214781. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  214782. + break;
  214783. + default:
  214784. + return false;
  214785. + }
  214786. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 74250000) {
  214787. + switch (cRes) {
  214788. + case 8:
  214789. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  214790. + break;
  214791. + case 10:
  214792. + hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
  214793. + break;
  214794. + case 12:
  214795. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  214796. + break;
  214797. + default:
  214798. + return false;
  214799. + }
  214800. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 118800000) {
  214801. + switch (cRes) {
  214802. + case 8:
  214803. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  214804. + break;
  214805. + case 10:
  214806. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  214807. + break;
  214808. + case 12:
  214809. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  214810. + break;
  214811. + default:
  214812. + return false;
  214813. + }
  214814. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 216000000) {
  214815. + switch (cRes) {
  214816. + case 8:
  214817. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  214818. + break;
  214819. + case 10:
  214820. + hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
  214821. + break;
  214822. + case 12:
  214823. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  214824. + break;
  214825. + default:
  214826. + return false;
  214827. + }
  214828. + } else {
  214829. + dev_err(&hdmi->pdev->dev,
  214830. + "Pixel clock %d - unsupported by HDMI\n",
  214831. + hdmi->hdmi_data.video_mode.mPixelClock);
  214832. + return false;
  214833. + }
  214834. +
  214835. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */
  214836. + hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
  214837. + /* RESISTANCE TERM 133Ohm Cfg */
  214838. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */
  214839. + /* PREEMP Cgf 0.00 */
  214840. + hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */
  214841. + /* TX/CK LVL 10 */
  214842. + hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */
  214843. +
  214844. + /* Board specific setting for PHY register 0x09, 0x0e to pass HCT */
  214845. + if (hdmi->phy_config.reg_cksymtx != 0)
  214846. + hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_cksymtx, 0x09);
  214847. +
  214848. + if (hdmi->phy_config.reg_vlev != 0)
  214849. + hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_vlev, 0x0E);
  214850. +
  214851. + /* REMOVE CLK TERM */
  214852. + hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */
  214853. +
  214854. + if (hdmi->hdmi_data.video_mode.mPixelClock > 148500000) {
  214855. + hdmi_phy_i2c_write(hdmi, 0x800b, 0x09);
  214856. + hdmi_phy_i2c_write(hdmi, 0x0129, 0x0E);
  214857. + }
  214858. +
  214859. + mxc_hdmi_phy_enable_power(1);
  214860. +
  214861. + /* toggle TMDS enable */
  214862. + mxc_hdmi_phy_enable_tmds(0);
  214863. + mxc_hdmi_phy_enable_tmds(1);
  214864. +
  214865. + /* gen2 tx power on */
  214866. + mxc_hdmi_phy_gen2_txpwron(1);
  214867. + mxc_hdmi_phy_gen2_pddq(0);
  214868. +
  214869. + /*Wait for PHY PLL lock */
  214870. + msec = 4;
  214871. + val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
  214872. + while (val == 0) {
  214873. + udelay(1000);
  214874. + if (msec-- == 0) {
  214875. + dev_dbg(&hdmi->pdev->dev, "PHY PLL not locked\n");
  214876. + return false;
  214877. + }
  214878. + val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
  214879. + }
  214880. +
  214881. + return true;
  214882. +}
  214883. +
  214884. +static void mxc_hdmi_phy_init(struct mxc_hdmi *hdmi)
  214885. +{
  214886. + int i;
  214887. + bool cscon = false;
  214888. +
  214889. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  214890. +
  214891. + /* Never do phy init if pixel clock is gated.
  214892. + * Otherwise HDMI PHY will get messed up and generate an overflow
  214893. + * interrupt that can't be cleared or detected by accessing the
  214894. + * status register. */
  214895. + if (!hdmi->fb_reg || !hdmi->cable_plugin
  214896. + || (hdmi->blank != FB_BLANK_UNBLANK))
  214897. + return;
  214898. +
  214899. + /*check csc whether needed activated in HDMI mode */
  214900. + cscon = (isColorSpaceConversion(hdmi) &&
  214901. + !hdmi->hdmi_data.video_mode.mDVI);
  214902. +
  214903. + /* HDMI Phy spec says to do the phy initialization sequence twice */
  214904. + for (i = 0 ; i < 2 ; i++) {
  214905. + mxc_hdmi_phy_sel_data_en_pol(1);
  214906. + mxc_hdmi_phy_sel_interface_control(0);
  214907. + mxc_hdmi_phy_enable_tmds(0);
  214908. + mxc_hdmi_phy_enable_power(0);
  214909. +
  214910. + /* Enable CSC */
  214911. + hdmi_phy_configure(hdmi, 0, 8, cscon);
  214912. + }
  214913. +
  214914. + hdmi->phy_enabled = true;
  214915. + if (!hdmi->hdmi_data.video_mode.mDVI)
  214916. + hdmi_enable_overflow_interrupts();
  214917. +}
  214918. +
  214919. +static void hdmi_config_AVI(struct mxc_hdmi *hdmi)
  214920. +{
  214921. + u8 val;
  214922. + u8 pix_fmt;
  214923. + u8 under_scan;
  214924. + u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
  214925. + struct fb_videomode mode;
  214926. + const struct fb_videomode *edid_mode;
  214927. + bool aspect_16_9;
  214928. +
  214929. + dev_dbg(&hdmi->pdev->dev, "set up AVI frame\n");
  214930. +
  214931. + fb_var_to_videomode(&mode, &hdmi->fbi->var);
  214932. + /* Use mode from list extracted from EDID to get aspect ratio */
  214933. + if (!list_empty(&hdmi->fbi->modelist)) {
  214934. + edid_mode = fb_find_nearest_mode(&mode, &hdmi->fbi->modelist);
  214935. + if (edid_mode->vmode & FB_VMODE_ASPECT_16_9)
  214936. + aspect_16_9 = true;
  214937. + else
  214938. + aspect_16_9 = false;
  214939. + } else
  214940. + aspect_16_9 = false;
  214941. +
  214942. + /********************************************
  214943. + * AVI Data Byte 1
  214944. + ********************************************/
  214945. + if (hdmi->hdmi_data.enc_out_format == YCBCR444)
  214946. + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444;
  214947. + else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS)
  214948. + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422;
  214949. + else
  214950. + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
  214951. +
  214952. + if (hdmi->edid_cfg.cea_underscan)
  214953. + under_scan = HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN;
  214954. + else
  214955. + under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
  214956. +
  214957. + /*
  214958. + * Active format identification data is present in the AVI InfoFrame.
  214959. + * Under scan info, no bar data
  214960. + */
  214961. + val = pix_fmt | under_scan |
  214962. + HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
  214963. + HDMI_FC_AVICONF0_BAR_DATA_NO_DATA;
  214964. +
  214965. + hdmi_writeb(val, HDMI_FC_AVICONF0);
  214966. +
  214967. + /********************************************
  214968. + * AVI Data Byte 2
  214969. + ********************************************/
  214970. +
  214971. + /* Set the Aspect Ratio */
  214972. + if (aspect_16_9) {
  214973. + act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
  214974. + coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
  214975. + } else {
  214976. + act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
  214977. + coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
  214978. + }
  214979. +
  214980. + /* Set up colorimetry */
  214981. + if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
  214982. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
  214983. + if (hdmi->hdmi_data.colorimetry == eITU601)
  214984. + ext_colorimetry =
  214985. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  214986. + else /* hdmi->hdmi_data.colorimetry == eITU709 */
  214987. + ext_colorimetry =
  214988. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
  214989. + } else if (hdmi->hdmi_data.enc_out_format != RGB) {
  214990. + if (hdmi->hdmi_data.colorimetry == eITU601)
  214991. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
  214992. + else /* hdmi->hdmi_data.colorimetry == eITU709 */
  214993. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
  214994. + ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  214995. + } else { /* Carries no data */
  214996. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA;
  214997. + ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  214998. + }
  214999. +
  215000. + val = colorimetry | coded_ratio | act_ratio;
  215001. + hdmi_writeb(val, HDMI_FC_AVICONF1);
  215002. +
  215003. + /********************************************
  215004. + * AVI Data Byte 3
  215005. + ********************************************/
  215006. +
  215007. + val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry |
  215008. + hdmi->hdmi_data.rgb_quant_range |
  215009. + HDMI_FC_AVICONF2_SCALING_NONE;
  215010. + hdmi_writeb(val, HDMI_FC_AVICONF2);
  215011. +
  215012. + /********************************************
  215013. + * AVI Data Byte 4
  215014. + ********************************************/
  215015. + hdmi_writeb(hdmi->vic, HDMI_FC_AVIVID);
  215016. +
  215017. + /********************************************
  215018. + * AVI Data Byte 5
  215019. + ********************************************/
  215020. +
  215021. + /* Set up input and output pixel repetition */
  215022. + val = (((hdmi->hdmi_data.video_mode.mPixelRepetitionInput + 1) <<
  215023. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
  215024. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
  215025. + ((hdmi->hdmi_data.video_mode.mPixelRepetitionOutput <<
  215026. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
  215027. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
  215028. + hdmi_writeb(val, HDMI_FC_PRCONF);
  215029. +
  215030. + /* IT Content and quantization range = don't care */
  215031. + val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS |
  215032. + HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED;
  215033. + hdmi_writeb(val, HDMI_FC_AVICONF3);
  215034. +
  215035. + /********************************************
  215036. + * AVI Data Bytes 6-13
  215037. + ********************************************/
  215038. + hdmi_writeb(0, HDMI_FC_AVIETB0);
  215039. + hdmi_writeb(0, HDMI_FC_AVIETB1);
  215040. + hdmi_writeb(0, HDMI_FC_AVISBB0);
  215041. + hdmi_writeb(0, HDMI_FC_AVISBB1);
  215042. + hdmi_writeb(0, HDMI_FC_AVIELB0);
  215043. + hdmi_writeb(0, HDMI_FC_AVIELB1);
  215044. + hdmi_writeb(0, HDMI_FC_AVISRB0);
  215045. + hdmi_writeb(0, HDMI_FC_AVISRB1);
  215046. +}
  215047. +
  215048. +/*!
  215049. + * this submodule is responsible for the video/audio data composition.
  215050. + */
  215051. +static void hdmi_av_composer(struct mxc_hdmi *hdmi)
  215052. +{
  215053. + u8 inv_val;
  215054. + struct fb_info *fbi = hdmi->fbi;
  215055. + struct fb_videomode fb_mode;
  215056. + struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
  215057. + int hblank, vblank;
  215058. +
  215059. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215060. +
  215061. + fb_var_to_videomode(&fb_mode, &fbi->var);
  215062. +
  215063. + vmode->mHSyncPolarity = ((fb_mode.sync & FB_SYNC_HOR_HIGH_ACT) != 0);
  215064. + vmode->mVSyncPolarity = ((fb_mode.sync & FB_SYNC_VERT_HIGH_ACT) != 0);
  215065. + vmode->mInterlaced = ((fb_mode.vmode & FB_VMODE_INTERLACED) != 0);
  215066. + vmode->mPixelClock = (fb_mode.xres + fb_mode.left_margin +
  215067. + fb_mode.right_margin + fb_mode.hsync_len) * (fb_mode.yres +
  215068. + fb_mode.upper_margin + fb_mode.lower_margin +
  215069. + fb_mode.vsync_len) * fb_mode.refresh;
  215070. +
  215071. + dev_dbg(&hdmi->pdev->dev, "final pixclk = %d\n", vmode->mPixelClock);
  215072. +
  215073. + /* Set up HDMI_FC_INVIDCONF */
  215074. + inv_val = (vmode->mVSyncPolarity ?
  215075. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
  215076. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
  215077. +
  215078. + inv_val |= (vmode->mHSyncPolarity ?
  215079. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
  215080. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
  215081. +
  215082. + inv_val |= (vmode->mDataEnablePolarity ?
  215083. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
  215084. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
  215085. +
  215086. + if (hdmi->vic == 39)
  215087. + inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
  215088. + else
  215089. + inv_val |= (vmode->mInterlaced ?
  215090. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
  215091. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW);
  215092. +
  215093. + inv_val |= (vmode->mInterlaced ?
  215094. + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
  215095. + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE);
  215096. +
  215097. + inv_val |= (vmode->mDVI ?
  215098. + HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE :
  215099. + HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE);
  215100. +
  215101. + hdmi_writeb(inv_val, HDMI_FC_INVIDCONF);
  215102. +
  215103. + /* Set up horizontal active pixel region width */
  215104. + hdmi_writeb(fb_mode.xres >> 8, HDMI_FC_INHACTV1);
  215105. + hdmi_writeb(fb_mode.xres, HDMI_FC_INHACTV0);
  215106. +
  215107. + /* Set up vertical blanking pixel region width */
  215108. + hdmi_writeb(fb_mode.yres >> 8, HDMI_FC_INVACTV1);
  215109. + hdmi_writeb(fb_mode.yres, HDMI_FC_INVACTV0);
  215110. +
  215111. + /* Set up horizontal blanking pixel region width */
  215112. + hblank = fb_mode.left_margin + fb_mode.right_margin +
  215113. + fb_mode.hsync_len;
  215114. + hdmi_writeb(hblank >> 8, HDMI_FC_INHBLANK1);
  215115. + hdmi_writeb(hblank, HDMI_FC_INHBLANK0);
  215116. +
  215117. + /* Set up vertical blanking pixel region width */
  215118. + vblank = fb_mode.upper_margin + fb_mode.lower_margin +
  215119. + fb_mode.vsync_len;
  215120. + hdmi_writeb(vblank, HDMI_FC_INVBLANK);
  215121. +
  215122. + /* Set up HSYNC active edge delay width (in pixel clks) */
  215123. + hdmi_writeb(fb_mode.right_margin >> 8, HDMI_FC_HSYNCINDELAY1);
  215124. + hdmi_writeb(fb_mode.right_margin, HDMI_FC_HSYNCINDELAY0);
  215125. +
  215126. + /* Set up VSYNC active edge delay (in pixel clks) */
  215127. + hdmi_writeb(fb_mode.lower_margin, HDMI_FC_VSYNCINDELAY);
  215128. +
  215129. + /* Set up HSYNC active pulse width (in pixel clks) */
  215130. + hdmi_writeb(fb_mode.hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
  215131. + hdmi_writeb(fb_mode.hsync_len, HDMI_FC_HSYNCINWIDTH0);
  215132. +
  215133. + /* Set up VSYNC active edge delay (in pixel clks) */
  215134. + hdmi_writeb(fb_mode.vsync_len, HDMI_FC_VSYNCINWIDTH);
  215135. +
  215136. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  215137. +}
  215138. +
  215139. +static int mxc_edid_read_internal(struct mxc_hdmi *hdmi, unsigned char *edid,
  215140. + struct mxc_edid_cfg *cfg, struct fb_info *fbi)
  215141. +{
  215142. + int extblknum;
  215143. + int i, j, ret;
  215144. + unsigned char *ediddata = edid;
  215145. + unsigned char tmpedid[EDID_LENGTH];
  215146. +
  215147. + dev_info(&hdmi->pdev->dev, "%s\n", __func__);
  215148. +
  215149. + if (!edid || !cfg || !fbi)
  215150. + return -EINVAL;
  215151. +
  215152. + /* init HDMI I2CM for read edid*/
  215153. + hdmi_writeb(0x0, HDMI_I2CM_DIV);
  215154. + hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_HCNT_1_ADDR);
  215155. + hdmi_writeb(0x79, HDMI_I2CM_SS_SCL_HCNT_0_ADDR);
  215156. + hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_LCNT_1_ADDR);
  215157. + hdmi_writeb(0x91, HDMI_I2CM_SS_SCL_LCNT_0_ADDR);
  215158. +
  215159. + hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_HCNT_1_ADDR);
  215160. + hdmi_writeb(0x0F, HDMI_I2CM_FS_SCL_HCNT_0_ADDR);
  215161. + hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_LCNT_1_ADDR);
  215162. + hdmi_writeb(0x21, HDMI_I2CM_FS_SCL_LCNT_0_ADDR);
  215163. +
  215164. + hdmi_writeb(0x50, HDMI_I2CM_SLAVE);
  215165. + hdmi_writeb(0x30, HDMI_I2CM_SEGADDR);
  215166. +
  215167. + /* Umask edid interrupt */
  215168. + hdmi_writeb(HDMI_I2CM_INT_DONE_POL,
  215169. + HDMI_I2CM_INT);
  215170. +
  215171. + hdmi_writeb(HDMI_I2CM_CTLINT_NAC_POL |
  215172. + HDMI_I2CM_CTLINT_ARBITRATION_POL,
  215173. + HDMI_I2CM_CTLINT);
  215174. +
  215175. + /* reset edid data zero */
  215176. + memset(edid, 0, EDID_LENGTH*4);
  215177. + memset(cfg, 0, sizeof(struct mxc_edid_cfg));
  215178. +
  215179. + /* Check first three byte of EDID head */
  215180. + if (!(hdmi_edid_i2c_read(hdmi, 0, 0) == 0x00) ||
  215181. + !(hdmi_edid_i2c_read(hdmi, 1, 0) == 0xFF) ||
  215182. + !(hdmi_edid_i2c_read(hdmi, 2, 0) == 0xFF)) {
  215183. + dev_info(&hdmi->pdev->dev, "EDID head check failed!");
  215184. + return -ENOENT;
  215185. + }
  215186. +
  215187. + for (i = 0; i < 128; i++) {
  215188. + *ediddata = hdmi_edid_i2c_read(hdmi, i, 0);
  215189. + ediddata++;
  215190. + }
  215191. +
  215192. + extblknum = edid[0x7E];
  215193. + if (extblknum < 0)
  215194. + return extblknum;
  215195. +
  215196. + if (extblknum) {
  215197. + ediddata = edid + EDID_LENGTH;
  215198. + for (i = 0; i < 128; i++) {
  215199. + *ediddata = hdmi_edid_i2c_read(hdmi, i, 1);
  215200. + ediddata++;
  215201. + }
  215202. + }
  215203. +
  215204. + /* edid first block parsing */
  215205. + memset(&fbi->monspecs, 0, sizeof(fbi->monspecs));
  215206. + fb_edid_to_monspecs(edid, &fbi->monspecs);
  215207. +
  215208. + ret = mxc_edid_parse_ext_blk(edid + EDID_LENGTH,
  215209. + cfg, &fbi->monspecs);
  215210. + if (ret < 0) {
  215211. + fb_edid_add_monspecs(edid + EDID_LENGTH, &fbi->monspecs);
  215212. + if (fbi->monspecs.modedb_len > 0)
  215213. + hdmi->edid_cfg.hdmi_cap = false;
  215214. + else
  215215. + return -ENOENT;
  215216. + }
  215217. +
  215218. + /* need read segment block? */
  215219. + if (extblknum > 1) {
  215220. + for (j = 1; j <= extblknum; j++) {
  215221. + for (i = 0; i < 128; i++)
  215222. + *(tmpedid + 1) = hdmi_edid_i2c_read(hdmi, i, j);
  215223. +
  215224. + /* edid ext block parsing */
  215225. + ret = mxc_edid_parse_ext_blk(tmpedid + EDID_LENGTH,
  215226. + cfg, &fbi->monspecs);
  215227. + if (ret < 0)
  215228. + return -ENOENT;
  215229. + }
  215230. + }
  215231. +
  215232. + return 0;
  215233. +}
  215234. +
  215235. +static int mxc_hdmi_read_edid(struct mxc_hdmi *hdmi)
  215236. +{
  215237. + int ret;
  215238. + u8 edid_old[HDMI_EDID_LEN];
  215239. + u8 clkdis;
  215240. +
  215241. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215242. +
  215243. + /* save old edid */
  215244. + memcpy(edid_old, hdmi->edid, HDMI_EDID_LEN);
  215245. +
  215246. + /* Read EDID via HDMI DDC when HDCP Enable */
  215247. + if (!hdcp_init)
  215248. + ret = mxc_edid_read(hdmi_i2c->adapter, hdmi_i2c->addr,
  215249. + hdmi->edid, &hdmi->edid_cfg, hdmi->fbi);
  215250. + else {
  215251. +
  215252. + /* Disable HDCP clk */
  215253. + if (hdmi->hdmi_data.hdcp_enable) {
  215254. + clkdis = hdmi_readb(HDMI_MC_CLKDIS);
  215255. + clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE;
  215256. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  215257. + }
  215258. +
  215259. + ret = mxc_edid_read_internal(hdmi, hdmi->edid,
  215260. + &hdmi->edid_cfg, hdmi->fbi);
  215261. +
  215262. + /* Enable HDCP clk */
  215263. + if (hdmi->hdmi_data.hdcp_enable) {
  215264. + clkdis = hdmi_readb(HDMI_MC_CLKDIS);
  215265. + clkdis &= ~HDMI_MC_CLKDIS_HDCPCLK_DISABLE;
  215266. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  215267. + }
  215268. +
  215269. + }
  215270. +
  215271. + if (ret < 0)
  215272. + return HDMI_EDID_FAIL;
  215273. +
  215274. + dev_info(&hdmi->pdev->dev, "%s HDMI in %s mode\n", __func__, hdmi->edid_cfg.hdmi_cap?"HDMI":"DVI");
  215275. + hdmi->plug_event = hdmi->edid_cfg.hdmi_cap?HDMI_IH_PHY_STAT0_HPD:HDMI_DVI_IH_STAT;
  215276. + hdmi->plug_mask = hdmi->edid_cfg.hdmi_cap?HDMI_PHY_HPD:HDMI_DVI_STAT;
  215277. +
  215278. + if (!memcmp(edid_old, hdmi->edid, HDMI_EDID_LEN)) {
  215279. + dev_info(&hdmi->pdev->dev, "same edid\n");
  215280. + return HDMI_EDID_SAME;
  215281. + }
  215282. +
  215283. + if (hdmi->fbi->monspecs.modedb_len == 0) {
  215284. + dev_info(&hdmi->pdev->dev, "No modes read from edid\n");
  215285. + return HDMI_EDID_NO_MODES;
  215286. + }
  215287. +
  215288. + return HDMI_EDID_SUCCESS;
  215289. +}
  215290. +
  215291. +static void mxc_hdmi_phy_disable(struct mxc_hdmi *hdmi)
  215292. +{
  215293. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215294. +
  215295. + if (!hdmi->phy_enabled)
  215296. + return;
  215297. +
  215298. + hdmi_disable_overflow_interrupts();
  215299. +
  215300. + /* Setting PHY to reset status */
  215301. + hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
  215302. +
  215303. + /* Power down PHY */
  215304. + mxc_hdmi_phy_enable_tmds(0);
  215305. + mxc_hdmi_phy_enable_power(0);
  215306. + mxc_hdmi_phy_gen2_txpwron(0);
  215307. + mxc_hdmi_phy_gen2_pddq(1);
  215308. +
  215309. + hdmi->phy_enabled = false;
  215310. + dev_dbg(&hdmi->pdev->dev, "%s - exit\n", __func__);
  215311. +}
  215312. +
  215313. +/* HDMI Initialization Step B.4 */
  215314. +static void mxc_hdmi_enable_video_path(struct mxc_hdmi *hdmi)
  215315. +{
  215316. + u8 clkdis;
  215317. +
  215318. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215319. +
  215320. + /* control period minimum duration */
  215321. + hdmi_writeb(12, HDMI_FC_CTRLDUR);
  215322. + hdmi_writeb(32, HDMI_FC_EXCTRLDUR);
  215323. + hdmi_writeb(1, HDMI_FC_EXCTRLSPAC);
  215324. +
  215325. + /* Set to fill TMDS data channels */
  215326. + hdmi_writeb(0x0B, HDMI_FC_CH0PREAM);
  215327. + hdmi_writeb(0x16, HDMI_FC_CH1PREAM);
  215328. + hdmi_writeb(0x21, HDMI_FC_CH2PREAM);
  215329. +
  215330. + /* Save CEC clock */
  215331. + clkdis = hdmi_readb(HDMI_MC_CLKDIS) & HDMI_MC_CLKDIS_CECCLK_DISABLE;
  215332. + clkdis |= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
  215333. +
  215334. + /* Enable pixel clock and tmds data path */
  215335. + clkdis = 0x7F & clkdis;
  215336. + clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
  215337. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  215338. +
  215339. + clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
  215340. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  215341. +
  215342. + /* Enable csc path */
  215343. + if (isColorSpaceConversion(hdmi) && !hdmi->hdmi_data.video_mode.mDVI) {
  215344. + clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
  215345. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  215346. + }
  215347. +}
  215348. +
  215349. +static void hdmi_enable_audio_clk(struct mxc_hdmi *hdmi)
  215350. +{
  215351. + u8 clkdis;
  215352. +
  215353. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215354. +
  215355. + clkdis = hdmi_readb(HDMI_MC_CLKDIS);
  215356. + clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
  215357. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  215358. +}
  215359. +
  215360. +/* Workaround to clear the overflow condition */
  215361. +static void mxc_hdmi_clear_overflow(struct mxc_hdmi *hdmi)
  215362. +{
  215363. + int count;
  215364. + u8 val;
  215365. +
  215366. + /* TMDS software reset */
  215367. + hdmi_writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
  215368. +
  215369. + val = hdmi_readb(HDMI_FC_INVIDCONF);
  215370. +
  215371. + if (cpu_is_imx6dl(hdmi)) {
  215372. + hdmi_writeb(val, HDMI_FC_INVIDCONF);
  215373. + return;
  215374. + }
  215375. +
  215376. + for (count = 0 ; count < 5 ; count++)
  215377. + hdmi_writeb(val, HDMI_FC_INVIDCONF);
  215378. +}
  215379. +
  215380. +static void hdmi_enable_overflow_interrupts(void)
  215381. +{
  215382. + pr_debug("%s\n", __func__);
  215383. + hdmi_writeb(0, HDMI_FC_MASK2);
  215384. + hdmi_writeb(0, HDMI_IH_MUTE_FC_STAT2);
  215385. +}
  215386. +
  215387. +static void hdmi_disable_overflow_interrupts(void)
  215388. +{
  215389. + pr_debug("%s\n", __func__);
  215390. + hdmi_writeb(HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
  215391. + HDMI_IH_MUTE_FC_STAT2);
  215392. + hdmi_writeb(0xff, HDMI_FC_MASK2);
  215393. +}
  215394. +
  215395. +static void mxc_hdmi_notify_fb(struct mxc_hdmi *hdmi)
  215396. +{
  215397. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215398. +
  215399. + /* Don't notify if we aren't registered yet */
  215400. + WARN_ON(!hdmi->fb_reg);
  215401. +
  215402. + /* disable the phy before ipu changes mode */
  215403. + mxc_hdmi_phy_disable(hdmi);
  215404. +
  215405. + /*
  215406. + * Note that fb_set_var will block. During this time,
  215407. + * FB_EVENT_MODE_CHANGE callback will happen.
  215408. + * So by the end of this function, mxc_hdmi_setup()
  215409. + * will be done.
  215410. + */
  215411. + hdmi->fbi->var.activate |= FB_ACTIVATE_FORCE;
  215412. + console_lock();
  215413. + hdmi->fbi->flags |= FBINFO_MISC_USEREVENT;
  215414. + fb_set_var(hdmi->fbi, &hdmi->fbi->var);
  215415. + hdmi->fbi->flags &= ~FBINFO_MISC_USEREVENT;
  215416. + console_unlock();
  215417. +
  215418. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  215419. +}
  215420. +
  215421. +static void mxc_hdmi_edid_rebuild_modelist(struct mxc_hdmi *hdmi)
  215422. +{
  215423. + int i;
  215424. + struct fb_videomode *mode;
  215425. +
  215426. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215427. +
  215428. + console_lock();
  215429. +
  215430. + fb_destroy_modelist(&hdmi->fbi->modelist);
  215431. + fb_add_videomode(&vga_mode, &hdmi->fbi->modelist);
  215432. +
  215433. + for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) {
  215434. + /*
  215435. + * We might check here if mode is supported by HDMI.
  215436. + * We do not currently support interlaced modes.
  215437. + * And add CEA modes in the modelist.
  215438. + */
  215439. + mode = &hdmi->fbi->monspecs.modedb[i];
  215440. +
  215441. + if ((mode->vmode & FB_VMODE_INTERLACED) ||
  215442. + (hdmi->edid_cfg.hdmi_cap &&
  215443. + (mxc_edid_mode_to_vic(mode) == 0)))
  215444. + continue;
  215445. +
  215446. + dev_dbg(&hdmi->pdev->dev, "Added mode %d:", i);
  215447. + dev_dbg(&hdmi->pdev->dev,
  215448. + "xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n",
  215449. + hdmi->fbi->monspecs.modedb[i].xres,
  215450. + hdmi->fbi->monspecs.modedb[i].yres,
  215451. + hdmi->fbi->monspecs.modedb[i].refresh,
  215452. + hdmi->fbi->monspecs.modedb[i].vmode,
  215453. + hdmi->fbi->monspecs.modedb[i].flag);
  215454. +
  215455. + fb_add_videomode(mode, &hdmi->fbi->modelist);
  215456. + }
  215457. +
  215458. + console_unlock();
  215459. +}
  215460. +
  215461. +static void mxc_hdmi_default_edid_cfg(struct mxc_hdmi *hdmi)
  215462. +{
  215463. + /* Default setting HDMI working in HDMI mode */
  215464. + hdmi->edid_cfg.hdmi_cap = true;
  215465. +}
  215466. +
  215467. +static void mxc_hdmi_default_modelist(struct mxc_hdmi *hdmi)
  215468. +{
  215469. + u32 i;
  215470. + const struct fb_videomode *mode;
  215471. +
  215472. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215473. +
  215474. + /* If not EDID data read, set up default modelist */
  215475. + dev_info(&hdmi->pdev->dev, "No modes read from edid\n");
  215476. + dev_info(&hdmi->pdev->dev, "create default modelist\n");
  215477. +
  215478. + console_lock();
  215479. +
  215480. + fb_destroy_modelist(&hdmi->fbi->modelist);
  215481. +
  215482. + /*Add all no interlaced CEA mode to default modelist */
  215483. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  215484. + mode = &mxc_cea_mode[i];
  215485. + if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0))
  215486. + fb_add_videomode(mode, &hdmi->fbi->modelist);
  215487. + }
  215488. +
  215489. + console_unlock();
  215490. +}
  215491. +
  215492. +static void mxc_hdmi_set_mode_to_vga_dvi(struct mxc_hdmi *hdmi)
  215493. +{
  215494. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215495. +
  215496. + hdmi_disable_overflow_interrupts();
  215497. +
  215498. + fb_videomode_to_var(&hdmi->fbi->var, &vga_mode);
  215499. +
  215500. + hdmi->requesting_vga_for_initialization = true;
  215501. + mxc_hdmi_notify_fb(hdmi);
  215502. + hdmi->requesting_vga_for_initialization = false;
  215503. +}
  215504. +
  215505. +static void mxc_hdmi_set_mode(struct mxc_hdmi *hdmi)
  215506. +{
  215507. + const struct fb_videomode *mode;
  215508. + struct fb_videomode m;
  215509. + struct fb_var_screeninfo var;
  215510. +
  215511. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215512. +
  215513. + /* Set the default mode only once. */
  215514. + if (!hdmi->dft_mode_set) {
  215515. + fb_videomode_to_var(&var, &hdmi->default_mode);
  215516. + hdmi->dft_mode_set = true;
  215517. + } else
  215518. + fb_videomode_to_var(&var, &hdmi->previous_non_vga_mode);
  215519. +
  215520. + fb_var_to_videomode(&m, &var);
  215521. + dump_fb_videomode(&m);
  215522. +
  215523. + mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
  215524. + if (!mode) {
  215525. + pr_err("%s: could not find mode in modelist\n", __func__);
  215526. + return;
  215527. + }
  215528. +
  215529. + /* If video mode same as previous, init HDMI again */
  215530. + if (fb_mode_is_equal(&hdmi->previous_non_vga_mode, mode)) {
  215531. + dev_dbg(&hdmi->pdev->dev,
  215532. + "%s: Video mode same as previous\n", __func__);
  215533. + /* update fbi mode in case modelist is updated */
  215534. + hdmi->fbi->mode = (struct fb_videomode *)mode;
  215535. + /* update hdmi setting in case EDID data updated */
  215536. + mxc_hdmi_setup(hdmi, 0);
  215537. + } else {
  215538. + dev_dbg(&hdmi->pdev->dev, "%s: New video mode\n", __func__);
  215539. + mxc_hdmi_set_mode_to_vga_dvi(hdmi);
  215540. + fb_videomode_to_var(&hdmi->fbi->var, mode);
  215541. + dump_fb_videomode((struct fb_videomode *)mode);
  215542. + mxc_hdmi_notify_fb(hdmi);
  215543. + }
  215544. +
  215545. +}
  215546. +
  215547. +static void mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
  215548. +{
  215549. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215550. +
  215551. + hdmi->cable_plugin = true;
  215552. +
  215553. + /* HDMI Initialization Step C */
  215554. + hdmi->edid_status = mxc_hdmi_read_edid(hdmi);
  215555. +
  215556. + /* Read EDID again if first EDID read failed */
  215557. + if (hdmi->edid_status == HDMI_EDID_NO_MODES ||
  215558. + hdmi->edid_status == HDMI_EDID_FAIL) {
  215559. + dev_info(&hdmi->pdev->dev, "Read EDID again\n");
  215560. + hdmi->edid_status = mxc_hdmi_read_edid(hdmi);
  215561. + }
  215562. +
  215563. + /* HDMI Initialization Steps D, E, F */
  215564. + switch (hdmi->edid_status) {
  215565. + case HDMI_EDID_SUCCESS:
  215566. + mxc_hdmi_edid_rebuild_modelist(hdmi);
  215567. + break;
  215568. +
  215569. + /* Nothing to do if EDID same */
  215570. + case HDMI_EDID_SAME:
  215571. + break;
  215572. +
  215573. + case HDMI_EDID_FAIL:
  215574. + mxc_hdmi_default_edid_cfg(hdmi);
  215575. + /* No break here */
  215576. + case HDMI_EDID_NO_MODES:
  215577. + default:
  215578. + mxc_hdmi_default_modelist(hdmi);
  215579. + break;
  215580. + }
  215581. +
  215582. + /* Save edid cfg for audio driver */
  215583. + hdmi_set_edid_cfg(hdmi->edid_status, &hdmi->edid_cfg);
  215584. +
  215585. + /* Setting video mode */
  215586. + mxc_hdmi_set_mode(hdmi);
  215587. +
  215588. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  215589. +}
  215590. +
  215591. +static int mxc_hdmi_power_on(struct mxc_dispdrv_handle *disp)
  215592. +{
  215593. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  215594. + mxc_hdmi_phy_init(hdmi);
  215595. + return 0;
  215596. +}
  215597. +
  215598. +static void mxc_hdmi_power_off(struct mxc_dispdrv_handle *disp)
  215599. +{
  215600. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  215601. + mxc_hdmi_phy_disable(hdmi);
  215602. +}
  215603. +
  215604. +static void mxc_hdmi_cable_disconnected(struct mxc_hdmi *hdmi)
  215605. +{
  215606. + u8 clkdis;
  215607. +
  215608. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215609. +
  215610. + /* Save CEC clock */
  215611. + clkdis = hdmi_readb(HDMI_MC_CLKDIS) & HDMI_MC_CLKDIS_CECCLK_DISABLE;
  215612. + clkdis |= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
  215613. +
  215614. + /* Disable All HDMI clock */
  215615. + hdmi_writeb(0xff & clkdis, HDMI_MC_CLKDIS);
  215616. +
  215617. + mxc_hdmi_phy_disable(hdmi);
  215618. +
  215619. + hdmi_disable_overflow_interrupts();
  215620. +
  215621. + hdmi->cable_plugin = false;
  215622. +}
  215623. +
  215624. +static void hotplug_worker(struct work_struct *work)
  215625. +{
  215626. + struct mxc_hdmi *hdmi =
  215627. + container_of(work, struct mxc_hdmi, hotplug_work);
  215628. + u32 hdmi_phy_stat0, hdmi_phy_pol0, hdmi_phy_mask0;
  215629. + unsigned long flags;
  215630. + char event_string[32];
  215631. + char *envp[] = { event_string, NULL };
  215632. +
  215633. + hdmi_phy_stat0 = hdmi_readb(HDMI_PHY_STAT0);
  215634. + hdmi_phy_pol0 = hdmi_readb(HDMI_PHY_POL0);
  215635. +
  215636. + if (hdmi->latest_intr_stat & hdmi->plug_event) {
  215637. + /* Make HPD intr active low to capture unplug event or
  215638. + * active high to capture plugin event */
  215639. + hdmi_writeb((hdmi->plug_mask & ~hdmi_phy_pol0), HDMI_PHY_POL0);
  215640. +
  215641. + /* check cable status */
  215642. + if (hdmi_phy_stat0 & hdmi->plug_mask) {
  215643. + /* Plugin event */
  215644. + dev_dbg(&hdmi->pdev->dev, "EVENT=plugin\n");
  215645. + mxc_hdmi_cable_connected(hdmi);
  215646. +
  215647. + sprintf(event_string, "EVENT=plugin");
  215648. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  215649. +#ifdef CONFIG_MXC_HDMI_CEC
  215650. + mxc_hdmi_cec_handle(0x80);
  215651. +#endif
  215652. + hdmi_set_cable_state(1);
  215653. + } else {
  215654. + /* Plugout event */
  215655. + dev_dbg(&hdmi->pdev->dev, "EVENT=plugout\n");
  215656. + hdmi_set_cable_state(0);
  215657. + mxc_hdmi_abort_stream();
  215658. + mxc_hdmi_cable_disconnected(hdmi);
  215659. +
  215660. + sprintf(event_string, "EVENT=plugout");
  215661. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  215662. +#ifdef CONFIG_MXC_HDMI_CEC
  215663. + mxc_hdmi_cec_handle(0x100);
  215664. +#endif
  215665. + }
  215666. + }
  215667. +
  215668. + /* Lock here to ensure full powerdown sequence
  215669. + * completed before next interrupt processed */
  215670. + spin_lock_irqsave(&hdmi->irq_lock, flags);
  215671. +
  215672. + /* Re-enable HPD interrupts */
  215673. + hdmi_phy_mask0 = hdmi_readb(HDMI_PHY_MASK0);
  215674. + hdmi_phy_mask0 &= ~hdmi->plug_mask;
  215675. + hdmi_writeb(hdmi_phy_mask0, HDMI_PHY_MASK0);
  215676. +
  215677. + /* Unmute interrupts */
  215678. + hdmi_writeb(~hdmi->plug_event, HDMI_IH_MUTE_PHY_STAT0);
  215679. +
  215680. + if (hdmi_readb(HDMI_IH_FC_STAT2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK)
  215681. + mxc_hdmi_clear_overflow(hdmi);
  215682. +
  215683. + spin_unlock_irqrestore(&hdmi->irq_lock, flags);
  215684. +}
  215685. +
  215686. +static void hotplug_work_launch(unsigned long data)
  215687. +{
  215688. + struct mxc_hdmi *hdmi = (struct mxc_hdmi *)data;
  215689. + pr_debug("%s\n", __func__);
  215690. + schedule_work(&hdmi->hotplug_work);
  215691. +}
  215692. +
  215693. +static void hdcp_hdp_worker(struct work_struct *work)
  215694. +{
  215695. + struct delayed_work *delay_work = to_delayed_work(work);
  215696. + struct mxc_hdmi *hdmi =
  215697. + container_of(delay_work, struct mxc_hdmi, hdcp_hdp_work);
  215698. + char event_string[32];
  215699. + char *envp[] = { event_string, NULL };
  215700. +
  215701. + /* HDCP interrupt */
  215702. + sprintf(event_string, "EVENT=hdcpint");
  215703. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  215704. +
  215705. + /* Unmute interrupts in HDCP application*/
  215706. +}
  215707. +
  215708. +static irqreturn_t mxc_hdmi_hotplug(int irq, void *data)
  215709. +{
  215710. + struct mxc_hdmi *hdmi = data;
  215711. + u8 val, intr_stat;
  215712. + unsigned long flags;
  215713. +
  215714. + spin_lock_irqsave(&hdmi->irq_lock, flags);
  215715. +
  215716. + /* Check and clean packet overflow interrupt.*/
  215717. + if (hdmi_readb(HDMI_IH_FC_STAT2) &
  215718. + HDMI_IH_FC_STAT2_OVERFLOW_MASK) {
  215719. + mxc_hdmi_clear_overflow(hdmi);
  215720. +
  215721. + dev_dbg(&hdmi->pdev->dev, "Overflow interrupt received\n");
  215722. + /* clear irq status */
  215723. + hdmi_writeb(HDMI_IH_FC_STAT2_OVERFLOW_MASK,
  215724. + HDMI_IH_FC_STAT2);
  215725. + }
  215726. +
  215727. + /*
  215728. + * We could not disable the irq. Probably the audio driver
  215729. + * has enabled it. Masking off the HDMI interrupts using
  215730. + * HDMI registers.
  215731. + */
  215732. + /* Capture status - used in hotplug_worker ISR */
  215733. + intr_stat = hdmi_readb(HDMI_IH_PHY_STAT0);
  215734. + if (intr_stat & hdmi->plug_event) {
  215735. +
  215736. + dev_dbg(&hdmi->pdev->dev, "Hotplug interrupt received\n");
  215737. + dev_dbg(&hdmi->pdev->dev, "intr_stat %u plug_event %u\n", intr_stat, hdmi->plug_event);
  215738. + hdmi->latest_intr_stat = intr_stat;
  215739. +
  215740. + /* Mute interrupts until handled */
  215741. +
  215742. + val = hdmi_readb(HDMI_IH_MUTE_PHY_STAT0);
  215743. + val |= hdmi->plug_event;
  215744. + hdmi_writeb(val, HDMI_IH_MUTE_PHY_STAT0);
  215745. +
  215746. + val = hdmi_readb(HDMI_PHY_MASK0);
  215747. + val |= hdmi->plug_mask;
  215748. + hdmi_writeb(val, HDMI_PHY_MASK0);
  215749. +
  215750. + /* Clear Hotplug interrupts */
  215751. + hdmi_writeb(hdmi->plug_event, HDMI_IH_PHY_STAT0);
  215752. +
  215753. + if(hdmi_inited) {
  215754. + mod_timer(&hdmi->jitter_timer, jiffies + HZ);
  215755. + }
  215756. + }
  215757. +
  215758. + /* Check HDCP interrupt state */
  215759. + if (hdmi->hdmi_data.hdcp_enable) {
  215760. + val = hdmi_readb(HDMI_A_APIINTSTAT);
  215761. + if (val != 0) {
  215762. + /* Mute interrupts until interrupt handled */
  215763. + val = 0xFF;
  215764. + hdmi_writeb(val, HDMI_A_APIINTMSK);
  215765. + schedule_delayed_work(&(hdmi->hdcp_hdp_work), msecs_to_jiffies(50));
  215766. + }
  215767. + }
  215768. +
  215769. + spin_unlock_irqrestore(&hdmi->irq_lock, flags);
  215770. + return IRQ_HANDLED;
  215771. +}
  215772. +
  215773. +static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event)
  215774. +{
  215775. + struct fb_videomode m;
  215776. + const struct fb_videomode *edid_mode;
  215777. +
  215778. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215779. +
  215780. + fb_var_to_videomode(&m, &hdmi->fbi->var);
  215781. + dump_fb_videomode(&m);
  215782. +
  215783. + dev_dbg(&hdmi->pdev->dev, "%s - video mode changed\n", __func__);
  215784. +
  215785. + hdmi->vic = 0;
  215786. + if (!hdmi->requesting_vga_for_initialization) {
  215787. + /* Save mode if this isn't the result of requesting
  215788. + * vga default. */
  215789. + memcpy(&hdmi->previous_non_vga_mode, &m,
  215790. + sizeof(struct fb_videomode));
  215791. + if (!list_empty(&hdmi->fbi->modelist)) {
  215792. + edid_mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
  215793. + pr_debug("edid mode ");
  215794. + dump_fb_videomode((struct fb_videomode *)edid_mode);
  215795. + /* update fbi mode */
  215796. + hdmi->fbi->mode = (struct fb_videomode *)edid_mode;
  215797. + hdmi->vic = mxc_edid_mode_to_vic(edid_mode);
  215798. + }
  215799. + }
  215800. +
  215801. + hdmi_disable_overflow_interrupts();
  215802. +
  215803. + dev_dbg(&hdmi->pdev->dev, "CEA mode used vic=%d\n", hdmi->vic);
  215804. + if (hdmi->edid_cfg.hdmi_cap || !hdmi->edid_status) {
  215805. + hdmi_set_dvi_mode(0);
  215806. + hdmi->hdmi_data.video_mode.mDVI = false;
  215807. + } else {
  215808. + hdmi_set_dvi_mode(1);
  215809. + dev_dbg(&hdmi->pdev->dev, "CEA mode vic=%d work in DVI\n", hdmi->vic);
  215810. + hdmi->hdmi_data.video_mode.mDVI = true;
  215811. + }
  215812. +
  215813. + if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
  215814. + (hdmi->vic == 21) || (hdmi->vic == 22) ||
  215815. + (hdmi->vic == 2) || (hdmi->vic == 3) ||
  215816. + (hdmi->vic == 17) || (hdmi->vic == 18))
  215817. + hdmi->hdmi_data.colorimetry = eITU601;
  215818. + else
  215819. + hdmi->hdmi_data.colorimetry = eITU709;
  215820. +
  215821. + if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
  215822. + (hdmi->vic == 12) || (hdmi->vic == 13) ||
  215823. + (hdmi->vic == 14) || (hdmi->vic == 15) ||
  215824. + (hdmi->vic == 25) || (hdmi->vic == 26) ||
  215825. + (hdmi->vic == 27) || (hdmi->vic == 28) ||
  215826. + (hdmi->vic == 29) || (hdmi->vic == 30) ||
  215827. + (hdmi->vic == 35) || (hdmi->vic == 36) ||
  215828. + (hdmi->vic == 37) || (hdmi->vic == 38))
  215829. + hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 1;
  215830. + else
  215831. + hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 0;
  215832. +
  215833. + hdmi->hdmi_data.video_mode.mPixelRepetitionInput = 0;
  215834. +
  215835. + /* TODO: Get input format from IPU (via FB driver iface) */
  215836. + hdmi->hdmi_data.enc_in_format = RGB;
  215837. +
  215838. + hdmi->hdmi_data.enc_out_format = RGB;
  215839. +
  215840. + /* YCbCr only enabled in HDMI mode */
  215841. + if (!hdmi->hdmi_data.video_mode.mDVI &&
  215842. + !hdmi->hdmi_data.rgb_out_enable) {
  215843. + if (hdmi->edid_cfg.cea_ycbcr444)
  215844. + hdmi->hdmi_data.enc_out_format = YCBCR444;
  215845. + else if (hdmi->edid_cfg.cea_ycbcr422)
  215846. + hdmi->hdmi_data.enc_out_format = YCBCR422_8BITS;
  215847. + }
  215848. +
  215849. + /* IPU not support depth color output */
  215850. + hdmi->hdmi_data.enc_color_depth = 8;
  215851. + hdmi->hdmi_data.pix_repet_factor = 0;
  215852. + hdmi->hdmi_data.video_mode.mDataEnablePolarity = true;
  215853. +
  215854. + /* HDMI Initialization Step B.1 */
  215855. + hdmi_av_composer(hdmi);
  215856. +
  215857. + /* HDMI Initializateion Step B.2 */
  215858. + mxc_hdmi_phy_init(hdmi);
  215859. +
  215860. + /* HDMI Initialization Step B.3 */
  215861. + mxc_hdmi_enable_video_path(hdmi);
  215862. +
  215863. + /* not for DVI mode */
  215864. + if (hdmi->hdmi_data.video_mode.mDVI)
  215865. + dev_dbg(&hdmi->pdev->dev, "%s DVI mode\n", __func__);
  215866. + else {
  215867. + dev_dbg(&hdmi->pdev->dev, "%s CEA mode\n", __func__);
  215868. +
  215869. + /* HDMI Initialization Step E - Configure audio */
  215870. + hdmi_clk_regenerator_update_pixel_clock(hdmi->fbi->var.pixclock);
  215871. + hdmi_enable_audio_clk(hdmi);
  215872. +
  215873. + /* HDMI Initialization Step F - Configure AVI InfoFrame */
  215874. + hdmi_config_AVI(hdmi);
  215875. + }
  215876. +
  215877. + hdmi_video_packetize(hdmi);
  215878. + hdmi_video_csc(hdmi);
  215879. + hdmi_video_sample(hdmi);
  215880. +
  215881. + mxc_hdmi_clear_overflow(hdmi);
  215882. +
  215883. + dev_dbg(&hdmi->pdev->dev, "%s exit\n\n", __func__);
  215884. +
  215885. +}
  215886. +
  215887. +/* Wait until we are registered to enable interrupts */
  215888. +static void mxc_hdmi_fb_registered(struct mxc_hdmi *hdmi)
  215889. +{
  215890. + unsigned long flags;
  215891. +
  215892. + if (hdmi->fb_reg)
  215893. + return;
  215894. +
  215895. + spin_lock_irqsave(&hdmi->irq_lock, flags);
  215896. +
  215897. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  215898. +
  215899. + hdmi_writeb(HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
  215900. + HDMI_PHY_I2CM_INT_ADDR);
  215901. +
  215902. + hdmi_writeb(HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
  215903. + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
  215904. + HDMI_PHY_I2CM_CTLINT_ADDR);
  215905. +
  215906. + /* enable cable hot plug irq */
  215907. + hdmi_writeb(~hdmi->plug_mask, HDMI_PHY_MASK0);
  215908. +
  215909. + /* Clear Hotplug interrupts */
  215910. + hdmi_writeb(hdmi->plug_event, HDMI_IH_PHY_STAT0);
  215911. +
  215912. + /* Unmute interrupts */
  215913. + hdmi_writeb(~hdmi->plug_event, HDMI_IH_MUTE_PHY_STAT0);
  215914. +
  215915. + hdmi->fb_reg = true;
  215916. +
  215917. + spin_unlock_irqrestore(&hdmi->irq_lock, flags);
  215918. +
  215919. +}
  215920. +
  215921. +static int mxc_hdmi_fb_event(struct notifier_block *nb,
  215922. + unsigned long val, void *v)
  215923. +{
  215924. + struct fb_event *event = v;
  215925. + struct mxc_hdmi *hdmi = container_of(nb, struct mxc_hdmi, nb);
  215926. +
  215927. + if (strcmp(event->info->fix.id, hdmi->fbi->fix.id))
  215928. + return 0;
  215929. +
  215930. + switch (val) {
  215931. + case FB_EVENT_FB_REGISTERED:
  215932. + dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_REGISTERED\n");
  215933. + mxc_hdmi_fb_registered(hdmi);
  215934. + hdmi_set_registered(1);
  215935. + break;
  215936. +
  215937. + case FB_EVENT_FB_UNREGISTERED:
  215938. + dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_UNREGISTERED\n");
  215939. + hdmi->fb_reg = false;
  215940. + hdmi_set_registered(0);
  215941. + break;
  215942. +
  215943. + case FB_EVENT_MODE_CHANGE:
  215944. + dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_MODE_CHANGE\n");
  215945. + if (hdmi->fb_reg)
  215946. + mxc_hdmi_setup(hdmi, val);
  215947. + break;
  215948. +
  215949. + case FB_EVENT_BLANK:
  215950. + if ((*((int *)event->data) == FB_BLANK_UNBLANK) &&
  215951. + (*((int *)event->data) != hdmi->blank)) {
  215952. + dev_dbg(&hdmi->pdev->dev,
  215953. + "event=FB_EVENT_BLANK - UNBLANK\n");
  215954. +
  215955. + hdmi->blank = *((int *)event->data);
  215956. +
  215957. + /* Re-enable HPD interrupts */
  215958. + val = hdmi_readb(HDMI_PHY_MASK0);
  215959. + val &= ~hdmi->plug_mask;
  215960. + hdmi_writeb(val, HDMI_PHY_MASK0);
  215961. +
  215962. + /* Unmute interrupts */
  215963. + hdmi_writeb(~hdmi->plug_event, HDMI_IH_MUTE_PHY_STAT0);
  215964. +
  215965. + if (hdmi->fb_reg && hdmi->cable_plugin)
  215966. + mxc_hdmi_setup(hdmi, val);
  215967. + hdmi_set_blank_state(1);
  215968. + } else if (*((int *)event->data) != hdmi->blank) {
  215969. + dev_dbg(&hdmi->pdev->dev,
  215970. + "event=FB_EVENT_BLANK - BLANK\n");
  215971. + hdmi_set_blank_state(0);
  215972. + mxc_hdmi_abort_stream();
  215973. +
  215974. + mxc_hdmi_phy_disable(hdmi);
  215975. +
  215976. + if(hdmi->plug_mask == HDMI_DVI_STAT) {
  215977. + u8 val;
  215978. + pr_info("In DVI Mode disable interrupts\n");
  215979. + val = hdmi_readb(HDMI_IH_MUTE_PHY_STAT0);
  215980. + val |= hdmi->plug_event;
  215981. + hdmi_writeb(val, HDMI_IH_MUTE_PHY_STAT0);
  215982. +
  215983. + val = hdmi_readb(HDMI_PHY_MASK0);
  215984. + val |= hdmi->plug_mask;
  215985. + hdmi_writeb(val, HDMI_PHY_MASK0);
  215986. +
  215987. + hdmi_set_dvi_mode(1);
  215988. + }
  215989. +
  215990. + hdmi->blank = *((int *)event->data);
  215991. + } else
  215992. + dev_dbg(&hdmi->pdev->dev,
  215993. + "FB BLANK state no changed!\n");
  215994. +
  215995. + break;
  215996. +
  215997. + case FB_EVENT_SUSPEND:
  215998. + dev_dbg(&hdmi->pdev->dev,
  215999. + "event=FB_EVENT_SUSPEND\n");
  216000. +
  216001. + if (hdmi->blank == FB_BLANK_UNBLANK) {
  216002. + mxc_hdmi_phy_disable(hdmi);
  216003. + clk_disable(hdmi->hdmi_iahb_clk);
  216004. + clk_disable(hdmi->hdmi_isfr_clk);
  216005. + }
  216006. + break;
  216007. +
  216008. + case FB_EVENT_RESUME:
  216009. + dev_dbg(&hdmi->pdev->dev,
  216010. + "event=FB_EVENT_RESUME\n");
  216011. +
  216012. + if (hdmi->blank == FB_BLANK_UNBLANK) {
  216013. + clk_enable(hdmi->hdmi_iahb_clk);
  216014. + clk_enable(hdmi->hdmi_isfr_clk);
  216015. + mxc_hdmi_phy_init(hdmi);
  216016. + }
  216017. + break;
  216018. +
  216019. + }
  216020. + return 0;
  216021. +}
  216022. +
  216023. +static void hdmi_init_route(struct mxc_hdmi *hdmi)
  216024. +{
  216025. + uint32_t hdmi_mux_setting, reg;
  216026. + int ipu_id, disp_id;
  216027. +
  216028. + ipu_id = mxc_hdmi_ipu_id;
  216029. + disp_id = mxc_hdmi_disp_id;
  216030. +
  216031. + if ((ipu_id > 1) || (ipu_id < 0)) {
  216032. + pr_err("Invalid IPU select for HDMI: %d. Set to 0\n", ipu_id);
  216033. + ipu_id = 0;
  216034. + }
  216035. +
  216036. + if ((disp_id > 1) || (disp_id < 0)) {
  216037. + pr_err("Invalid DI select for HDMI: %d. Set to 0\n", disp_id);
  216038. + disp_id = 0;
  216039. + }
  216040. +
  216041. + reg = readl(hdmi->gpr_hdmi_base);
  216042. +
  216043. + /* Configure the connection between IPU1/2 and HDMI */
  216044. + hdmi_mux_setting = 2*ipu_id + disp_id;
  216045. +
  216046. + /* GPR3, bits 2-3 = HDMI_MUX_CTL */
  216047. + reg &= ~0xd;
  216048. + reg |= hdmi_mux_setting << 2;
  216049. +
  216050. + writel(reg, hdmi->gpr_hdmi_base);
  216051. +
  216052. + /* Set HDMI event as SDMA event2 for HDMI audio */
  216053. + reg = readl(hdmi->gpr_sdma_base);
  216054. + reg |= 0x1;
  216055. + writel(reg, hdmi->gpr_sdma_base);
  216056. +}
  216057. +
  216058. +static void hdmi_hdcp_get_property(struct platform_device *pdev)
  216059. +{
  216060. + struct device_node *np = pdev->dev.of_node;
  216061. +
  216062. + /* Check hdcp enable by dts.*/
  216063. + hdcp_init = of_property_read_bool(np, "fsl,hdcp");
  216064. + if (hdcp_init)
  216065. + dev_dbg(&pdev->dev, "hdcp enable\n");
  216066. + else
  216067. + dev_dbg(&pdev->dev, "hdcp disable\n");
  216068. +}
  216069. +
  216070. +static void hdmi_get_of_property(struct mxc_hdmi *hdmi)
  216071. +{
  216072. + struct platform_device *pdev = hdmi->pdev;
  216073. + struct device_node *np = pdev->dev.of_node;
  216074. + const struct of_device_id *of_id =
  216075. + of_match_device(imx_hdmi_dt_ids, &pdev->dev);
  216076. + int ret;
  216077. + u32 phy_reg_vlev = 0, phy_reg_cksymtx = 0;
  216078. +
  216079. + if (of_id) {
  216080. + pdev->id_entry = of_id->data;
  216081. + hdmi->cpu_type = pdev->id_entry->driver_data;
  216082. + }
  216083. +
  216084. + /* HDMI PHY register vlev and cksymtx preperty is optional.
  216085. + * It is for specific board to pass HCT electrical part.
  216086. + * Default value will been setting in HDMI PHY config function
  216087. + * if it is not define in device tree.
  216088. + */
  216089. + ret = of_property_read_u32(np, "fsl,phy_reg_vlev", &phy_reg_vlev);
  216090. + if (ret)
  216091. + dev_dbg(&pdev->dev, "No board specific HDMI PHY vlev\n");
  216092. +
  216093. + ret = of_property_read_u32(np, "fsl,phy_reg_cksymtx", &phy_reg_cksymtx);
  216094. + if (ret)
  216095. + dev_dbg(&pdev->dev, "No board specific HDMI PHY cksymtx\n");
  216096. +
  216097. + /* Specific phy config */
  216098. + hdmi->phy_config.reg_cksymtx = phy_reg_cksymtx;
  216099. + hdmi->phy_config.reg_vlev = phy_reg_vlev;
  216100. +
  216101. +}
  216102. +
  216103. +/* HDMI Initialization Step A */
  216104. +static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp,
  216105. + struct mxc_dispdrv_setting *setting)
  216106. +{
  216107. + int ret = 0;
  216108. + u32 i;
  216109. + const struct fb_videomode *mode;
  216110. + struct fb_videomode m;
  216111. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  216112. + int irq = platform_get_irq(hdmi->pdev, 0);
  216113. +
  216114. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  216115. +
  216116. + /* Check hdmi disp init once */
  216117. + if (hdmi_inited) {
  216118. + dev_err(&hdmi->pdev->dev,
  216119. + "Error only one HDMI output support now!\n");
  216120. + return -1;
  216121. + }
  216122. +
  216123. + hdmi_get_of_property(hdmi);
  216124. +
  216125. + if (irq < 0)
  216126. + return -ENODEV;
  216127. +
  216128. + /* Setting HDMI default to blank state */
  216129. + hdmi->blank = FB_BLANK_POWERDOWN;
  216130. +
  216131. + setting->dev_id = mxc_hdmi_ipu_id;
  216132. + setting->disp_id = mxc_hdmi_disp_id;
  216133. + setting->if_fmt = IPU_PIX_FMT_RGB24;
  216134. +
  216135. + hdmi->dft_mode_str = setting->dft_mode_str;
  216136. + hdmi->default_bpp = setting->default_bpp;
  216137. + dev_dbg(&hdmi->pdev->dev, "%s - default mode %s bpp=%d\n",
  216138. + __func__, hdmi->dft_mode_str, hdmi->default_bpp);
  216139. +
  216140. + hdmi->fbi = setting->fbi;
  216141. +
  216142. + hdmi_init_route(hdmi);
  216143. +
  216144. + hdmi->hdmi_isfr_clk = clk_get(&hdmi->pdev->dev, "hdmi_isfr");
  216145. + if (IS_ERR(hdmi->hdmi_isfr_clk)) {
  216146. + ret = PTR_ERR(hdmi->hdmi_isfr_clk);
  216147. + dev_err(&hdmi->pdev->dev,
  216148. + "Unable to get HDMI clk: %d\n", ret);
  216149. + goto egetclk1;
  216150. + }
  216151. +
  216152. + ret = clk_prepare_enable(hdmi->hdmi_isfr_clk);
  216153. + if (ret < 0) {
  216154. + dev_err(&hdmi->pdev->dev,
  216155. + "Cannot enable HDMI isfr clock: %d\n", ret);
  216156. + goto erate1;
  216157. + }
  216158. +
  216159. + hdmi->hdmi_iahb_clk = clk_get(&hdmi->pdev->dev, "hdmi_iahb");
  216160. + if (IS_ERR(hdmi->hdmi_iahb_clk)) {
  216161. + ret = PTR_ERR(hdmi->hdmi_iahb_clk);
  216162. + dev_err(&hdmi->pdev->dev,
  216163. + "Unable to get HDMI clk: %d\n", ret);
  216164. + goto egetclk2;
  216165. + }
  216166. +
  216167. + ret = clk_prepare_enable(hdmi->hdmi_iahb_clk);
  216168. + if (ret < 0) {
  216169. + dev_err(&hdmi->pdev->dev,
  216170. + "Cannot enable HDMI iahb clock: %d\n", ret);
  216171. + goto erate2;
  216172. + }
  216173. +
  216174. + dev_dbg(&hdmi->pdev->dev, "Enabled HDMI clocks\n");
  216175. +
  216176. + /* Init DDC pins for HDCP */
  216177. + if (hdcp_init) {
  216178. + hdmi->pinctrl = devm_pinctrl_get_select_default(&hdmi->pdev->dev);
  216179. + if (IS_ERR(hdmi->pinctrl)) {
  216180. + dev_err(&hdmi->pdev->dev, "can't get/select DDC pinctrl\n");
  216181. + goto erate2;
  216182. + }
  216183. + }
  216184. +
  216185. + /* Product and revision IDs */
  216186. + dev_info(&hdmi->pdev->dev,
  216187. + "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
  216188. + hdmi_readb(HDMI_DESIGN_ID),
  216189. + hdmi_readb(HDMI_REVISION_ID),
  216190. + hdmi_readb(HDMI_PRODUCT_ID0),
  216191. + hdmi_readb(HDMI_PRODUCT_ID1));
  216192. +
  216193. + /* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
  216194. + * N and cts values before enabling phy */
  216195. + hdmi_init_clk_regenerator();
  216196. +
  216197. + INIT_LIST_HEAD(&hdmi->fbi->modelist);
  216198. +
  216199. + spin_lock_init(&hdmi->irq_lock);
  216200. +
  216201. + /* Set the default mode and modelist when disp init. */
  216202. + fb_find_mode(&hdmi->fbi->var, hdmi->fbi,
  216203. + hdmi->dft_mode_str, NULL, 0, NULL,
  216204. + hdmi->default_bpp);
  216205. +
  216206. + console_lock();
  216207. +
  216208. + fb_destroy_modelist(&hdmi->fbi->modelist);
  216209. +
  216210. + /*Add all no interlaced CEA mode to default modelist */
  216211. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  216212. + mode = &mxc_cea_mode[i];
  216213. + if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0))
  216214. + fb_add_videomode(mode, &hdmi->fbi->modelist);
  216215. + }
  216216. +
  216217. + console_unlock();
  216218. +
  216219. + /* Find a nearest mode in default modelist */
  216220. + fb_var_to_videomode(&m, &hdmi->fbi->var);
  216221. + dump_fb_videomode(&m);
  216222. +
  216223. + hdmi->dft_mode_set = false;
  216224. + /* Save default video mode */
  216225. + memcpy(&hdmi->default_mode, &m, sizeof(struct fb_videomode));
  216226. +
  216227. + mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
  216228. + if (!mode) {
  216229. + pr_err("%s: could not find mode in modelist\n", __func__);
  216230. + return -1;
  216231. + }
  216232. +
  216233. + fb_videomode_to_var(&hdmi->fbi->var, mode);
  216234. +
  216235. + /* update fbi mode */
  216236. + hdmi->fbi->mode = (struct fb_videomode *)mode;
  216237. +
  216238. + /* Default setting HDMI working in HDMI mode*/
  216239. + hdmi->edid_cfg.hdmi_cap = true;
  216240. +
  216241. + hdmi->plug_event = HDMI_DVI_IH_STAT;
  216242. + hdmi->plug_mask = HDMI_DVI_STAT;
  216243. +
  216244. + setup_timer(&hdmi->jitter_timer, hotplug_work_launch, (unsigned long)hdmi);
  216245. + INIT_WORK(&hdmi->hotplug_work, hotplug_worker);
  216246. + INIT_DELAYED_WORK(&hdmi->hdcp_hdp_work, hdcp_hdp_worker);
  216247. +
  216248. + /* Configure registers related to HDMI interrupt
  216249. + * generation before registering IRQ. */
  216250. + hdmi_writeb(hdmi->plug_mask, HDMI_PHY_POL0);
  216251. +
  216252. + /* Clear Hotplug interrupts */
  216253. + hdmi_writeb(hdmi->plug_event, HDMI_IH_PHY_STAT0);
  216254. +
  216255. + hdmi->nb.notifier_call = mxc_hdmi_fb_event;
  216256. + ret = fb_register_client(&hdmi->nb);
  216257. + if (ret < 0)
  216258. + goto efbclient;
  216259. +
  216260. + memset(&hdmi->hdmi_data, 0, sizeof(struct hdmi_data_info));
  216261. +
  216262. + /* Default HDMI working in RGB mode */
  216263. + hdmi->hdmi_data.rgb_out_enable = true;
  216264. +
  216265. + if (!strcasecmp(rgb_quant_range, "limited")) {
  216266. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE;
  216267. + } else if (!strcasecmp(rgb_quant_range, "full")) {
  216268. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE;
  216269. + } else {
  216270. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT;
  216271. + }
  216272. +
  216273. + ret = devm_request_irq(&hdmi->pdev->dev, irq, mxc_hdmi_hotplug, IRQF_SHARED,
  216274. + dev_name(&hdmi->pdev->dev), hdmi);
  216275. + if (ret < 0) {
  216276. + dev_err(&hdmi->pdev->dev,
  216277. + "Unable to request irq: %d\n", ret);
  216278. + goto ereqirq;
  216279. + }
  216280. +
  216281. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_fb_name);
  216282. + if (ret < 0)
  216283. + dev_warn(&hdmi->pdev->dev,
  216284. + "cound not create sys node for fb name\n");
  216285. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_cable_state);
  216286. + if (ret < 0)
  216287. + dev_warn(&hdmi->pdev->dev,
  216288. + "cound not create sys node for cable state\n");
  216289. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_edid);
  216290. + if (ret < 0)
  216291. + dev_warn(&hdmi->pdev->dev,
  216292. + "cound not create sys node for edid\n");
  216293. +
  216294. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_rgb_out_enable);
  216295. + if (ret < 0)
  216296. + dev_warn(&hdmi->pdev->dev,
  216297. + "cound not create sys node for rgb out enable\n");
  216298. +
  216299. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_rgb_quant_range);
  216300. + if (ret < 0)
  216301. + dev_warn(&hdmi->pdev->dev,
  216302. + "cound not create sys node for rgb quant range\n");
  216303. +
  216304. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_hdcp_enable);
  216305. + if (ret < 0)
  216306. + dev_warn(&hdmi->pdev->dev,
  216307. + "cound not create sys node for hdcp enable\n");
  216308. +
  216309. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  216310. +
  216311. + hdmi_inited = true;
  216312. +
  216313. + return ret;
  216314. +
  216315. +efbclient:
  216316. + free_irq(irq, hdmi);
  216317. +ereqirq:
  216318. + clk_disable_unprepare(hdmi->hdmi_iahb_clk);
  216319. +erate2:
  216320. + clk_put(hdmi->hdmi_iahb_clk);
  216321. +egetclk2:
  216322. + clk_disable_unprepare(hdmi->hdmi_isfr_clk);
  216323. +erate1:
  216324. + clk_put(hdmi->hdmi_isfr_clk);
  216325. +egetclk1:
  216326. + dev_dbg(&hdmi->pdev->dev, "%s error exit\n", __func__);
  216327. +
  216328. + return ret;
  216329. +}
  216330. +
  216331. +static void mxc_hdmi_disp_deinit(struct mxc_dispdrv_handle *disp)
  216332. +{
  216333. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  216334. +
  216335. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  216336. +
  216337. + fb_unregister_client(&hdmi->nb);
  216338. +
  216339. + clk_disable_unprepare(hdmi->hdmi_isfr_clk);
  216340. + clk_put(hdmi->hdmi_isfr_clk);
  216341. + clk_disable_unprepare(hdmi->hdmi_iahb_clk);
  216342. + clk_put(hdmi->hdmi_iahb_clk);
  216343. +
  216344. + platform_device_unregister(hdmi->pdev);
  216345. +
  216346. + hdmi_inited = false;
  216347. +}
  216348. +
  216349. +static struct mxc_dispdrv_driver mxc_hdmi_drv = {
  216350. + .name = DISPDRV_HDMI,
  216351. + .init = mxc_hdmi_disp_init,
  216352. + .deinit = mxc_hdmi_disp_deinit,
  216353. + .enable = mxc_hdmi_power_on,
  216354. + .disable = mxc_hdmi_power_off,
  216355. +};
  216356. +
  216357. +
  216358. +static int mxc_hdmi_open(struct inode *inode, struct file *file)
  216359. +{
  216360. + return 0;
  216361. +}
  216362. +
  216363. +static long mxc_hdmi_ioctl(struct file *file,
  216364. + unsigned int cmd, unsigned long arg)
  216365. +{
  216366. + int __user *argp = (void __user *)arg;
  216367. + int ret = 0;
  216368. +
  216369. + switch (cmd) {
  216370. + case HDMI_IOC_GET_RESOURCE:
  216371. + ret = copy_to_user(argp, &g_hdmi->hdmi_data,
  216372. + sizeof(g_hdmi->hdmi_data)) ? -EFAULT : 0;
  216373. + break;
  216374. + case HDMI_IOC_GET_CPU_TYPE:
  216375. + *argp = g_hdmi->cpu_type;
  216376. + break;
  216377. + default:
  216378. + pr_debug("Unsupport cmd %d\n", cmd);
  216379. + break;
  216380. + }
  216381. + return ret;
  216382. +}
  216383. +
  216384. +static int mxc_hdmi_release(struct inode *inode, struct file *file)
  216385. +{
  216386. + return 0;
  216387. +}
  216388. +
  216389. +static const struct file_operations mxc_hdmi_fops = {
  216390. + .owner = THIS_MODULE,
  216391. + .open = mxc_hdmi_open,
  216392. + .release = mxc_hdmi_release,
  216393. + .unlocked_ioctl = mxc_hdmi_ioctl,
  216394. +};
  216395. +
  216396. +
  216397. +static int mxc_hdmi_probe(struct platform_device *pdev)
  216398. +{
  216399. + struct mxc_hdmi *hdmi;
  216400. + struct device *temp_class;
  216401. + struct resource *res;
  216402. + int ret = 0;
  216403. +
  216404. + /* Check I2C driver is loaded and available
  216405. + * check hdcp function is enable by dts */
  216406. + hdmi_hdcp_get_property(pdev);
  216407. + if (!hdmi_i2c && !hdcp_init)
  216408. + return -ENODEV;
  216409. +
  216410. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  216411. + if (!res)
  216412. + return -ENOENT;
  216413. +
  216414. + hdmi = devm_kzalloc(&pdev->dev,
  216415. + sizeof(struct mxc_hdmi),
  216416. + GFP_KERNEL);
  216417. + if (!hdmi) {
  216418. + dev_err(&pdev->dev, "Cannot allocate device data\n");
  216419. + ret = -ENOMEM;
  216420. + goto ealloc;
  216421. + }
  216422. + g_hdmi = hdmi;
  216423. +
  216424. + hdmi_major = register_chrdev(hdmi_major, "mxc_hdmi", &mxc_hdmi_fops);
  216425. + if (hdmi_major < 0) {
  216426. + printk(KERN_ERR "HDMI: unable to get a major for HDMI\n");
  216427. + ret = -EBUSY;
  216428. + goto ealloc;
  216429. + }
  216430. +
  216431. + hdmi_class = class_create(THIS_MODULE, "mxc_hdmi");
  216432. + if (IS_ERR(hdmi_class)) {
  216433. + ret = PTR_ERR(hdmi_class);
  216434. + goto err_out_chrdev;
  216435. + }
  216436. +
  216437. + temp_class = device_create(hdmi_class, NULL, MKDEV(hdmi_major, 0),
  216438. + NULL, "mxc_hdmi");
  216439. + if (IS_ERR(temp_class)) {
  216440. + ret = PTR_ERR(temp_class);
  216441. + goto err_out_class;
  216442. + }
  216443. +
  216444. + hdmi->pdev = pdev;
  216445. +
  216446. + hdmi->core_pdev = platform_device_alloc("mxc_hdmi_core", -1);
  216447. + if (!hdmi->core_pdev) {
  216448. + pr_err("%s failed platform_device_alloc for hdmi core\n",
  216449. + __func__);
  216450. + ret = -ENOMEM;
  216451. + goto ecore;
  216452. + }
  216453. +
  216454. + hdmi->gpr_base = ioremap(res->start, resource_size(res));
  216455. + if (!hdmi->gpr_base) {
  216456. + dev_err(&pdev->dev, "ioremap failed\n");
  216457. + ret = -ENOMEM;
  216458. + goto eiomap;
  216459. + }
  216460. +
  216461. + hdmi->gpr_hdmi_base = hdmi->gpr_base + 3;
  216462. + hdmi->gpr_sdma_base = hdmi->gpr_base;
  216463. +
  216464. + hdmi_inited = false;
  216465. +
  216466. + hdmi->disp_mxc_hdmi = mxc_dispdrv_register(&mxc_hdmi_drv);
  216467. + if (IS_ERR(hdmi->disp_mxc_hdmi)) {
  216468. + dev_err(&pdev->dev, "Failed to register dispdrv - 0x%x\n",
  216469. + (int)hdmi->disp_mxc_hdmi);
  216470. + ret = (int)hdmi->disp_mxc_hdmi;
  216471. + goto edispdrv;
  216472. + }
  216473. + mxc_dispdrv_setdata(hdmi->disp_mxc_hdmi, hdmi);
  216474. +
  216475. + platform_set_drvdata(pdev, hdmi);
  216476. +
  216477. + return 0;
  216478. +edispdrv:
  216479. + iounmap(hdmi->gpr_base);
  216480. +eiomap:
  216481. + platform_device_put(hdmi->core_pdev);
  216482. +ecore:
  216483. + kfree(hdmi);
  216484. +err_out_class:
  216485. + device_destroy(hdmi_class, MKDEV(hdmi_major, 0));
  216486. + class_destroy(hdmi_class);
  216487. +err_out_chrdev:
  216488. + unregister_chrdev(hdmi_major, "mxc_hdmi");
  216489. +ealloc:
  216490. + return ret;
  216491. +}
  216492. +
  216493. +static int mxc_hdmi_remove(struct platform_device *pdev)
  216494. +{
  216495. + struct mxc_hdmi *hdmi = platform_get_drvdata(pdev);
  216496. + int irq = platform_get_irq(pdev, 0);
  216497. +
  216498. + fb_unregister_client(&hdmi->nb);
  216499. +
  216500. + mxc_dispdrv_puthandle(hdmi->disp_mxc_hdmi);
  216501. + mxc_dispdrv_unregister(hdmi->disp_mxc_hdmi);
  216502. + iounmap(hdmi->gpr_base);
  216503. + /* No new work will be scheduled, wait for running ISR */
  216504. + free_irq(irq, hdmi);
  216505. + kfree(hdmi);
  216506. + g_hdmi = NULL;
  216507. +
  216508. + return 0;
  216509. +}
  216510. +
  216511. +static struct platform_driver mxc_hdmi_driver = {
  216512. + .probe = mxc_hdmi_probe,
  216513. + .remove = mxc_hdmi_remove,
  216514. + .driver = {
  216515. + .name = "mxc_hdmi",
  216516. + .of_match_table = imx_hdmi_dt_ids,
  216517. + .owner = THIS_MODULE,
  216518. + },
  216519. +};
  216520. +
  216521. +static int __init mxc_hdmi_init(void)
  216522. +{
  216523. + return platform_driver_register(&mxc_hdmi_driver);
  216524. +}
  216525. +module_init(mxc_hdmi_init);
  216526. +
  216527. +static void __exit mxc_hdmi_exit(void)
  216528. +{
  216529. + if (hdmi_major > 0) {
  216530. + device_destroy(hdmi_class, MKDEV(hdmi_major, 0));
  216531. + class_destroy(hdmi_class);
  216532. + unregister_chrdev(hdmi_major, "mxc_hdmi");
  216533. + hdmi_major = 0;
  216534. + }
  216535. +
  216536. + platform_driver_unregister(&mxc_hdmi_driver);
  216537. +}
  216538. +module_exit(mxc_hdmi_exit);
  216539. +
  216540. +static int mxc_hdmi_i2c_probe(struct i2c_client *client,
  216541. + const struct i2c_device_id *id)
  216542. +{
  216543. + if (!i2c_check_functionality(client->adapter,
  216544. + I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
  216545. + return -ENODEV;
  216546. +
  216547. + hdmi_i2c = client;
  216548. +
  216549. + return 0;
  216550. +}
  216551. +
  216552. +static int mxc_hdmi_i2c_remove(struct i2c_client *client)
  216553. +{
  216554. + hdmi_i2c = NULL;
  216555. + return 0;
  216556. +}
  216557. +
  216558. +static const struct of_device_id imx_hdmi_i2c_match[] = {
  216559. + { .compatible = "fsl,imx6-hdmi-i2c", },
  216560. + { /* sentinel */ }
  216561. +};
  216562. +
  216563. +static const struct i2c_device_id mxc_hdmi_i2c_id[] = {
  216564. + { "mxc_hdmi_i2c", 0 },
  216565. + {},
  216566. +};
  216567. +MODULE_DEVICE_TABLE(i2c, mxc_hdmi_i2c_id);
  216568. +
  216569. +static struct i2c_driver mxc_hdmi_i2c_driver = {
  216570. + .driver = {
  216571. + .name = "mxc_hdmi_i2c",
  216572. + .of_match_table = imx_hdmi_i2c_match,
  216573. + },
  216574. + .probe = mxc_hdmi_i2c_probe,
  216575. + .remove = mxc_hdmi_i2c_remove,
  216576. + .id_table = mxc_hdmi_i2c_id,
  216577. +};
  216578. +
  216579. +static int __init mxc_hdmi_i2c_init(void)
  216580. +{
  216581. + return i2c_add_driver(&mxc_hdmi_i2c_driver);
  216582. +}
  216583. +
  216584. +static void __exit mxc_hdmi_i2c_exit(void)
  216585. +{
  216586. + i2c_del_driver(&mxc_hdmi_i2c_driver);
  216587. +}
  216588. +
  216589. +module_init(mxc_hdmi_i2c_init);
  216590. +module_exit(mxc_hdmi_i2c_exit);
  216591. +
  216592. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  216593. diff -Nur linux-3.14.14/drivers/video/mxc/mxc_ipuv3_fb.c linux-imx6-3.14/drivers/video/mxc/mxc_ipuv3_fb.c
  216594. --- linux-3.14.14/drivers/video/mxc/mxc_ipuv3_fb.c 1969-12-31 18:00:00.000000000 -0600
  216595. +++ linux-imx6-3.14/drivers/video/mxc/mxc_ipuv3_fb.c 2014-12-08 00:31:54.860418001 -0600
  216596. @@ -0,0 +1,2578 @@
  216597. +/*
  216598. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  216599. + */
  216600. +
  216601. +/*
  216602. + * The code contained herein is licensed under the GNU General Public
  216603. + * License. You may obtain a copy of the GNU General Public License
  216604. + * Version 2 or later at the following locations:
  216605. + *
  216606. + * http://www.opensource.org/licenses/gpl-license.html
  216607. + * http://www.gnu.org/copyleft/gpl.html
  216608. + */
  216609. +
  216610. +/*!
  216611. + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
  216612. + */
  216613. +
  216614. +/*!
  216615. + * @file mxcfb.c
  216616. + *
  216617. + * @brief MXC Frame buffer driver for SDC
  216618. + *
  216619. + * @ingroup Framebuffer
  216620. + */
  216621. +
  216622. +/*!
  216623. + * Include files
  216624. + */
  216625. +#include <linux/clk.h>
  216626. +#include <linux/console.h>
  216627. +#include <linux/delay.h>
  216628. +#include <linux/dma-mapping.h>
  216629. +#include <linux/errno.h>
  216630. +#include <linux/fb.h>
  216631. +#include <linux/fsl_devices.h>
  216632. +#include <linux/init.h>
  216633. +#include <linux/interrupt.h>
  216634. +#include <linux/io.h>
  216635. +#include <linux/ioport.h>
  216636. +#include <linux/ipu.h>
  216637. +#include <linux/ipu-v3.h>
  216638. +#include <linux/kernel.h>
  216639. +#include <linux/module.h>
  216640. +#include <linux/mxcfb.h>
  216641. +#include <linux/of_device.h>
  216642. +#include <linux/platform_device.h>
  216643. +#include <linux/sched.h>
  216644. +#include <linux/slab.h>
  216645. +#include <linux/string.h>
  216646. +#include <linux/uaccess.h>
  216647. +
  216648. +#include "mxc_dispdrv.h"
  216649. +
  216650. +/*
  216651. + * Driver name
  216652. + */
  216653. +#define MXCFB_NAME "mxc_sdc_fb"
  216654. +
  216655. +/* Display port number */
  216656. +#define MXCFB_PORT_NUM 2
  216657. +/*!
  216658. + * Structure containing the MXC specific framebuffer information.
  216659. + */
  216660. +struct mxcfb_info {
  216661. + int default_bpp;
  216662. + int cur_blank;
  216663. + int next_blank;
  216664. + ipu_channel_t ipu_ch;
  216665. + int ipu_id;
  216666. + int ipu_di;
  216667. + u32 ipu_di_pix_fmt;
  216668. + bool ipu_int_clk;
  216669. + bool overlay;
  216670. + bool alpha_chan_en;
  216671. + bool late_init;
  216672. + bool first_set_par;
  216673. + dma_addr_t alpha_phy_addr0;
  216674. + dma_addr_t alpha_phy_addr1;
  216675. + void *alpha_virt_addr0;
  216676. + void *alpha_virt_addr1;
  216677. + uint32_t alpha_mem_len;
  216678. + uint32_t ipu_ch_irq;
  216679. + uint32_t ipu_ch_nf_irq;
  216680. + uint32_t ipu_alp_ch_irq;
  216681. + uint32_t cur_ipu_buf;
  216682. + uint32_t cur_ipu_alpha_buf;
  216683. +
  216684. + u32 pseudo_palette[16];
  216685. +
  216686. + bool mode_found;
  216687. + struct completion flip_complete;
  216688. + struct completion alpha_flip_complete;
  216689. + struct completion vsync_complete;
  216690. +
  216691. + void *ipu;
  216692. + struct fb_info *ovfbi;
  216693. +
  216694. + struct mxc_dispdrv_handle *dispdrv;
  216695. +
  216696. + struct fb_var_screeninfo cur_var;
  216697. +};
  216698. +
  216699. +struct mxcfb_pfmt {
  216700. + u32 fb_pix_fmt;
  216701. + int bpp;
  216702. + struct fb_bitfield red;
  216703. + struct fb_bitfield green;
  216704. + struct fb_bitfield blue;
  216705. + struct fb_bitfield transp;
  216706. +};
  216707. +
  216708. +static const struct mxcfb_pfmt mxcfb_pfmts[] = {
  216709. + /* pixel bpp red green blue transp */
  216710. + {IPU_PIX_FMT_RGB565, 16, {11, 5, 0}, { 5, 6, 0}, { 0, 5, 0}, { 0, 0, 0} },
  216711. + {IPU_PIX_FMT_RGB24, 24, { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0}, { 0, 0, 0} },
  216712. + {IPU_PIX_FMT_BGR24, 24, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 0, 0, 0} },
  216713. + {IPU_PIX_FMT_RGB32, 32, { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0}, {24, 8, 0} },
  216714. + {IPU_PIX_FMT_BGR32, 32, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, {24, 8, 0} },
  216715. + {IPU_PIX_FMT_ABGR32, 32, {24, 8, 0}, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0} },
  216716. +};
  216717. +
  216718. +struct mxcfb_alloc_list {
  216719. + struct list_head list;
  216720. + dma_addr_t phy_addr;
  216721. + void *cpu_addr;
  216722. + u32 size;
  216723. +};
  216724. +
  216725. +enum {
  216726. + BOTH_ON,
  216727. + SRC_ON,
  216728. + TGT_ON,
  216729. + BOTH_OFF
  216730. +};
  216731. +
  216732. +static bool g_dp_in_use[2];
  216733. +LIST_HEAD(fb_alloc_list);
  216734. +
  216735. +/* Return default standard(RGB) pixel format */
  216736. +static uint32_t bpp_to_pixfmt(int bpp)
  216737. +{
  216738. + uint32_t pixfmt = 0;
  216739. +
  216740. + switch (bpp) {
  216741. + case 24:
  216742. + pixfmt = IPU_PIX_FMT_BGR24;
  216743. + break;
  216744. + case 32:
  216745. + pixfmt = IPU_PIX_FMT_BGR32;
  216746. + break;
  216747. + case 16:
  216748. + pixfmt = IPU_PIX_FMT_RGB565;
  216749. + break;
  216750. + }
  216751. + return pixfmt;
  216752. +}
  216753. +
  216754. +static inline int bitfield_is_equal(struct fb_bitfield f1,
  216755. + struct fb_bitfield f2)
  216756. +{
  216757. + return !memcmp(&f1, &f2, sizeof(f1));
  216758. +}
  216759. +
  216760. +static int pixfmt_to_var(uint32_t pixfmt, struct fb_var_screeninfo *var)
  216761. +{
  216762. + int i, ret = -1;
  216763. +
  216764. + for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
  216765. + if (pixfmt == mxcfb_pfmts[i].fb_pix_fmt) {
  216766. + var->red = mxcfb_pfmts[i].red;
  216767. + var->green = mxcfb_pfmts[i].green;
  216768. + var->blue = mxcfb_pfmts[i].blue;
  216769. + var->transp = mxcfb_pfmts[i].transp;
  216770. + var->bits_per_pixel = mxcfb_pfmts[i].bpp;
  216771. + ret = 0;
  216772. + break;
  216773. + }
  216774. + }
  216775. + return ret;
  216776. +}
  216777. +
  216778. +static int bpp_to_var(int bpp, struct fb_var_screeninfo *var)
  216779. +{
  216780. + uint32_t pixfmt = 0;
  216781. +
  216782. + pixfmt = bpp_to_pixfmt(bpp);
  216783. + if (pixfmt)
  216784. + return pixfmt_to_var(pixfmt, var);
  216785. + else
  216786. + return -1;
  216787. +}
  216788. +
  216789. +static int check_var_pixfmt(struct fb_var_screeninfo *var)
  216790. +{
  216791. + int i, ret = -1;
  216792. +
  216793. + for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
  216794. + if (bitfield_is_equal(var->red, mxcfb_pfmts[i].red) &&
  216795. + bitfield_is_equal(var->green, mxcfb_pfmts[i].green) &&
  216796. + bitfield_is_equal(var->blue, mxcfb_pfmts[i].blue) &&
  216797. + bitfield_is_equal(var->transp, mxcfb_pfmts[i].transp) &&
  216798. + var->bits_per_pixel == mxcfb_pfmts[i].bpp) {
  216799. + ret = 0;
  216800. + break;
  216801. + }
  216802. + }
  216803. + return ret;
  216804. +}
  216805. +
  216806. +static uint32_t fbi_to_pixfmt(struct fb_info *fbi)
  216807. +{
  216808. + int i;
  216809. + uint32_t pixfmt = 0;
  216810. +
  216811. + if (fbi->var.nonstd)
  216812. + return fbi->var.nonstd;
  216813. +
  216814. + for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
  216815. + if (bitfield_is_equal(fbi->var.red, mxcfb_pfmts[i].red) &&
  216816. + bitfield_is_equal(fbi->var.green, mxcfb_pfmts[i].green) &&
  216817. + bitfield_is_equal(fbi->var.blue, mxcfb_pfmts[i].blue) &&
  216818. + bitfield_is_equal(fbi->var.transp, mxcfb_pfmts[i].transp)) {
  216819. + pixfmt = mxcfb_pfmts[i].fb_pix_fmt;
  216820. + break;
  216821. + }
  216822. + }
  216823. +
  216824. + if (pixfmt == 0)
  216825. + dev_err(fbi->device, "cannot get pixel format\n");
  216826. +
  216827. + return pixfmt;
  216828. +}
  216829. +
  216830. +static struct fb_info *found_registered_fb(ipu_channel_t ipu_ch, int ipu_id)
  216831. +{
  216832. + int i;
  216833. + struct mxcfb_info *mxc_fbi;
  216834. + struct fb_info *fbi = NULL;
  216835. +
  216836. + for (i = 0; i < num_registered_fb; i++) {
  216837. + mxc_fbi =
  216838. + ((struct mxcfb_info *)(registered_fb[i]->par));
  216839. +
  216840. + if ((mxc_fbi->ipu_ch == ipu_ch) &&
  216841. + (mxc_fbi->ipu_id == ipu_id)) {
  216842. + fbi = registered_fb[i];
  216843. + break;
  216844. + }
  216845. + }
  216846. + return fbi;
  216847. +}
  216848. +
  216849. +static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id);
  216850. +static irqreturn_t mxcfb_nf_irq_handler(int irq, void *dev_id);
  216851. +static int mxcfb_blank(int blank, struct fb_info *info);
  216852. +static int mxcfb_map_video_memory(struct fb_info *fbi);
  216853. +static int mxcfb_unmap_video_memory(struct fb_info *fbi);
  216854. +
  216855. +/*
  216856. + * Set fixed framebuffer parameters based on variable settings.
  216857. + *
  216858. + * @param info framebuffer information pointer
  216859. + */
  216860. +static int mxcfb_set_fix(struct fb_info *info)
  216861. +{
  216862. + struct fb_fix_screeninfo *fix = &info->fix;
  216863. + struct fb_var_screeninfo *var = &info->var;
  216864. +
  216865. + fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
  216866. +
  216867. + fix->type = FB_TYPE_PACKED_PIXELS;
  216868. + fix->accel = FB_ACCEL_NONE;
  216869. + fix->visual = FB_VISUAL_TRUECOLOR;
  216870. + fix->xpanstep = 1;
  216871. + fix->ywrapstep = 1;
  216872. + fix->ypanstep = 1;
  216873. +
  216874. + return 0;
  216875. +}
  216876. +
  216877. +static int _setup_disp_channel1(struct fb_info *fbi)
  216878. +{
  216879. + ipu_channel_params_t params;
  216880. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  216881. +
  216882. + memset(&params, 0, sizeof(params));
  216883. +
  216884. + if (mxc_fbi->ipu_ch == MEM_DC_SYNC) {
  216885. + params.mem_dc_sync.di = mxc_fbi->ipu_di;
  216886. + if (fbi->var.vmode & FB_VMODE_INTERLACED)
  216887. + params.mem_dc_sync.interlaced = true;
  216888. + params.mem_dc_sync.out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
  216889. + params.mem_dc_sync.in_pixel_fmt = fbi_to_pixfmt(fbi);
  216890. + } else {
  216891. + params.mem_dp_bg_sync.di = mxc_fbi->ipu_di;
  216892. + if (fbi->var.vmode & FB_VMODE_INTERLACED)
  216893. + params.mem_dp_bg_sync.interlaced = true;
  216894. + params.mem_dp_bg_sync.out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
  216895. + params.mem_dp_bg_sync.in_pixel_fmt = fbi_to_pixfmt(fbi);
  216896. + if (mxc_fbi->alpha_chan_en)
  216897. + params.mem_dp_bg_sync.alpha_chan_en = true;
  216898. + }
  216899. + ipu_init_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, &params);
  216900. +
  216901. + return 0;
  216902. +}
  216903. +
  216904. +static int _setup_disp_channel2(struct fb_info *fbi)
  216905. +{
  216906. + int retval = 0;
  216907. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  216908. + int fb_stride;
  216909. + unsigned long base;
  216910. + unsigned int fr_xoff, fr_yoff, fr_w, fr_h;
  216911. +
  216912. + switch (fbi_to_pixfmt(fbi)) {
  216913. + case IPU_PIX_FMT_YUV420P2:
  216914. + case IPU_PIX_FMT_YVU420P:
  216915. + case IPU_PIX_FMT_NV12:
  216916. + case IPU_PIX_FMT_YUV422P:
  216917. + case IPU_PIX_FMT_YVU422P:
  216918. + case IPU_PIX_FMT_YUV420P:
  216919. + case IPU_PIX_FMT_YUV444P:
  216920. + fb_stride = fbi->var.xres_virtual;
  216921. + break;
  216922. + default:
  216923. + fb_stride = fbi->fix.line_length;
  216924. + }
  216925. +
  216926. + base = fbi->fix.smem_start;
  216927. + fr_xoff = fbi->var.xoffset;
  216928. + fr_w = fbi->var.xres_virtual;
  216929. + if (!(fbi->var.vmode & FB_VMODE_YWRAP)) {
  216930. + dev_dbg(fbi->device, "Y wrap disabled\n");
  216931. + fr_yoff = fbi->var.yoffset % fbi->var.yres;
  216932. + fr_h = fbi->var.yres;
  216933. + base += fbi->fix.line_length * fbi->var.yres *
  216934. + (fbi->var.yoffset / fbi->var.yres);
  216935. + } else {
  216936. + dev_dbg(fbi->device, "Y wrap enabled\n");
  216937. + fr_yoff = fbi->var.yoffset;
  216938. + fr_h = fbi->var.yres_virtual;
  216939. + }
  216940. + base += fr_yoff * fb_stride + fr_xoff;
  216941. +
  216942. + mxc_fbi->cur_ipu_buf = 2;
  216943. + init_completion(&mxc_fbi->flip_complete);
  216944. + /*
  216945. + * We don't need to wait for vsync at the first time
  216946. + * we do pan display after fb is initialized, as IPU will
  216947. + * switch to the newly selected buffer automatically,
  216948. + * so we call complete() for both mxc_fbi->flip_complete
  216949. + * and mxc_fbi->alpha_flip_complete.
  216950. + */
  216951. + complete(&mxc_fbi->flip_complete);
  216952. + if (mxc_fbi->alpha_chan_en) {
  216953. + mxc_fbi->cur_ipu_alpha_buf = 1;
  216954. + init_completion(&mxc_fbi->alpha_flip_complete);
  216955. + complete(&mxc_fbi->alpha_flip_complete);
  216956. + }
  216957. +
  216958. + retval = ipu_init_channel_buffer(mxc_fbi->ipu,
  216959. + mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
  216960. + fbi_to_pixfmt(fbi),
  216961. + fbi->var.xres, fbi->var.yres,
  216962. + fb_stride,
  216963. + fbi->var.rotate,
  216964. + base,
  216965. + base,
  216966. + fbi->var.accel_flags &
  216967. + FB_ACCEL_DOUBLE_FLAG ? 0 : base,
  216968. + 0, 0);
  216969. + if (retval) {
  216970. + dev_err(fbi->device,
  216971. + "ipu_init_channel_buffer error %d\n", retval);
  216972. + return retval;
  216973. + }
  216974. +
  216975. + /* update u/v offset */
  216976. + ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  216977. + IPU_INPUT_BUFFER,
  216978. + fbi_to_pixfmt(fbi),
  216979. + fr_w,
  216980. + fr_h,
  216981. + fr_w,
  216982. + 0, 0,
  216983. + fr_yoff,
  216984. + fr_xoff);
  216985. +
  216986. + if (mxc_fbi->alpha_chan_en) {
  216987. + retval = ipu_init_channel_buffer(mxc_fbi->ipu,
  216988. + mxc_fbi->ipu_ch,
  216989. + IPU_ALPHA_IN_BUFFER,
  216990. + IPU_PIX_FMT_GENERIC,
  216991. + fbi->var.xres, fbi->var.yres,
  216992. + fbi->var.xres,
  216993. + fbi->var.rotate,
  216994. + mxc_fbi->alpha_phy_addr1,
  216995. + mxc_fbi->alpha_phy_addr0,
  216996. + 0,
  216997. + 0, 0);
  216998. + if (retval) {
  216999. + dev_err(fbi->device,
  217000. + "ipu_init_channel_buffer error %d\n", retval);
  217001. + return retval;
  217002. + }
  217003. + }
  217004. +
  217005. + return retval;
  217006. +}
  217007. +
  217008. +static bool mxcfb_need_to_set_par(struct fb_info *fbi)
  217009. +{
  217010. + struct mxcfb_info *mxc_fbi = fbi->par;
  217011. +
  217012. + if ((fbi->var.activate & FB_ACTIVATE_FORCE) &&
  217013. + (fbi->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
  217014. + return true;
  217015. +
  217016. + /*
  217017. + * Ignore xoffset and yoffset update,
  217018. + * because pan display handles this case.
  217019. + */
  217020. + mxc_fbi->cur_var.xoffset = fbi->var.xoffset;
  217021. + mxc_fbi->cur_var.yoffset = fbi->var.yoffset;
  217022. +
  217023. + return !!memcmp(&mxc_fbi->cur_var, &fbi->var,
  217024. + sizeof(struct fb_var_screeninfo));
  217025. +}
  217026. +
  217027. +/*
  217028. + * Set framebuffer parameters and change the operating mode.
  217029. + *
  217030. + * @param info framebuffer information pointer
  217031. + */
  217032. +static int mxcfb_set_par(struct fb_info *fbi)
  217033. +{
  217034. + int retval = 0;
  217035. + u32 mem_len, alpha_mem_len;
  217036. + ipu_di_signal_cfg_t sig_cfg;
  217037. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  217038. +
  217039. + int16_t ov_pos_x = 0, ov_pos_y = 0;
  217040. + int ov_pos_ret = 0;
  217041. + struct mxcfb_info *mxc_fbi_fg = NULL;
  217042. + bool ovfbi_enable = false;
  217043. +
  217044. + if (ipu_ch_param_bad_alpha_pos(fbi_to_pixfmt(fbi)) &&
  217045. + mxc_fbi->alpha_chan_en) {
  217046. + dev_err(fbi->device, "Bad pixel format for "
  217047. + "graphics plane fb\n");
  217048. + return -EINVAL;
  217049. + }
  217050. +
  217051. + if (mxc_fbi->ovfbi)
  217052. + mxc_fbi_fg = (struct mxcfb_info *)mxc_fbi->ovfbi->par;
  217053. +
  217054. + if (mxc_fbi->ovfbi && mxc_fbi_fg)
  217055. + if (mxc_fbi_fg->next_blank == FB_BLANK_UNBLANK)
  217056. + ovfbi_enable = true;
  217057. +
  217058. + if (!mxcfb_need_to_set_par(fbi))
  217059. + return 0;
  217060. +
  217061. + dev_dbg(fbi->device, "Reconfiguring framebuffer\n");
  217062. +
  217063. + if (fbi->var.xres == 0 || fbi->var.yres == 0)
  217064. + return 0;
  217065. +
  217066. + if (ovfbi_enable) {
  217067. + ov_pos_ret = ipu_disp_get_window_pos(
  217068. + mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch,
  217069. + &ov_pos_x, &ov_pos_y);
  217070. + if (ov_pos_ret < 0)
  217071. + dev_err(fbi->device, "Get overlay pos failed, dispdrv:%s.\n",
  217072. + mxc_fbi->dispdrv->drv->name);
  217073. +
  217074. + ipu_clear_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_irq);
  217075. + ipu_disable_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_irq);
  217076. + ipu_clear_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_nf_irq);
  217077. + ipu_disable_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_nf_irq);
  217078. + ipu_disable_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch, true);
  217079. + ipu_uninit_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
  217080. + }
  217081. +
  217082. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  217083. + ipu_disable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  217084. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  217085. + ipu_disable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  217086. + ipu_disable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, true);
  217087. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  217088. +
  217089. + /*
  217090. + * Disable IPU hsp clock if it is enabled for an
  217091. + * additional time in ipu common driver.
  217092. + */
  217093. + if (mxc_fbi->first_set_par && mxc_fbi->late_init)
  217094. + ipu_disable_hsp_clk(mxc_fbi->ipu);
  217095. +
  217096. + mxcfb_set_fix(fbi);
  217097. +
  217098. + mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
  217099. + if (!fbi->fix.smem_start || (mem_len > fbi->fix.smem_len)) {
  217100. + if (fbi->fix.smem_start)
  217101. + mxcfb_unmap_video_memory(fbi);
  217102. +
  217103. + if (mxcfb_map_video_memory(fbi) < 0)
  217104. + return -ENOMEM;
  217105. + }
  217106. +
  217107. + if (mxc_fbi->first_set_par) {
  217108. + /*
  217109. + * Clear the screen in case uboot fb pixel format is not
  217110. + * the same to kernel fb pixel format.
  217111. + */
  217112. + if (mxc_fbi->late_init)
  217113. + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
  217114. +
  217115. + mxc_fbi->first_set_par = false;
  217116. + }
  217117. +
  217118. + if (mxc_fbi->alpha_chan_en) {
  217119. + alpha_mem_len = fbi->var.xres * fbi->var.yres;
  217120. + if ((!mxc_fbi->alpha_phy_addr0 && !mxc_fbi->alpha_phy_addr1) ||
  217121. + (alpha_mem_len > mxc_fbi->alpha_mem_len)) {
  217122. + if (mxc_fbi->alpha_phy_addr0)
  217123. + dma_free_coherent(fbi->device,
  217124. + mxc_fbi->alpha_mem_len,
  217125. + mxc_fbi->alpha_virt_addr0,
  217126. + mxc_fbi->alpha_phy_addr0);
  217127. + if (mxc_fbi->alpha_phy_addr1)
  217128. + dma_free_coherent(fbi->device,
  217129. + mxc_fbi->alpha_mem_len,
  217130. + mxc_fbi->alpha_virt_addr1,
  217131. + mxc_fbi->alpha_phy_addr1);
  217132. +
  217133. + mxc_fbi->alpha_virt_addr0 =
  217134. + dma_alloc_coherent(fbi->device,
  217135. + alpha_mem_len,
  217136. + &mxc_fbi->alpha_phy_addr0,
  217137. + GFP_DMA | GFP_KERNEL);
  217138. +
  217139. + mxc_fbi->alpha_virt_addr1 =
  217140. + dma_alloc_coherent(fbi->device,
  217141. + alpha_mem_len,
  217142. + &mxc_fbi->alpha_phy_addr1,
  217143. + GFP_DMA | GFP_KERNEL);
  217144. + if (mxc_fbi->alpha_virt_addr0 == NULL ||
  217145. + mxc_fbi->alpha_virt_addr1 == NULL) {
  217146. + dev_err(fbi->device, "mxcfb: dma alloc for"
  217147. + " alpha buffer failed.\n");
  217148. + if (mxc_fbi->alpha_virt_addr0)
  217149. + dma_free_coherent(fbi->device,
  217150. + mxc_fbi->alpha_mem_len,
  217151. + mxc_fbi->alpha_virt_addr0,
  217152. + mxc_fbi->alpha_phy_addr0);
  217153. + if (mxc_fbi->alpha_virt_addr1)
  217154. + dma_free_coherent(fbi->device,
  217155. + mxc_fbi->alpha_mem_len,
  217156. + mxc_fbi->alpha_virt_addr1,
  217157. + mxc_fbi->alpha_phy_addr1);
  217158. + return -ENOMEM;
  217159. + }
  217160. + mxc_fbi->alpha_mem_len = alpha_mem_len;
  217161. + }
  217162. + }
  217163. +
  217164. + if (mxc_fbi->next_blank != FB_BLANK_UNBLANK)
  217165. + return retval;
  217166. +
  217167. + if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->setup) {
  217168. + retval = mxc_fbi->dispdrv->drv->setup(mxc_fbi->dispdrv, fbi);
  217169. + if (retval < 0) {
  217170. + dev_err(fbi->device, "setup error, dispdrv:%s.\n",
  217171. + mxc_fbi->dispdrv->drv->name);
  217172. + return -EINVAL;
  217173. + }
  217174. + }
  217175. +
  217176. + _setup_disp_channel1(fbi);
  217177. + if (ovfbi_enable)
  217178. + _setup_disp_channel1(mxc_fbi->ovfbi);
  217179. +
  217180. + if (!mxc_fbi->overlay) {
  217181. + uint32_t out_pixel_fmt;
  217182. +
  217183. + memset(&sig_cfg, 0, sizeof(sig_cfg));
  217184. + if (fbi->var.vmode & FB_VMODE_INTERLACED)
  217185. + sig_cfg.interlaced = true;
  217186. + out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
  217187. + if (fbi->var.vmode & FB_VMODE_ODD_FLD_FIRST) /* PAL */
  217188. + sig_cfg.odd_field_first = true;
  217189. + if (mxc_fbi->ipu_int_clk)
  217190. + sig_cfg.int_clk = true;
  217191. + if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
  217192. + sig_cfg.Hsync_pol = true;
  217193. + if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
  217194. + sig_cfg.Vsync_pol = true;
  217195. + if (!(fbi->var.sync & FB_SYNC_CLK_LAT_FALL))
  217196. + sig_cfg.clk_pol = true;
  217197. + if (fbi->var.sync & FB_SYNC_DATA_INVERT)
  217198. + sig_cfg.data_pol = true;
  217199. + if (!(fbi->var.sync & FB_SYNC_OE_LOW_ACT))
  217200. + sig_cfg.enable_pol = true;
  217201. + if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
  217202. + sig_cfg.clkidle_en = true;
  217203. +
  217204. + dev_dbg(fbi->device, "pixclock = %ul Hz\n",
  217205. + (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
  217206. +
  217207. + if (ipu_init_sync_panel(mxc_fbi->ipu, mxc_fbi->ipu_di,
  217208. + (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
  217209. + fbi->var.xres, fbi->var.yres,
  217210. + out_pixel_fmt,
  217211. + fbi->var.left_margin,
  217212. + fbi->var.hsync_len,
  217213. + fbi->var.right_margin,
  217214. + fbi->var.upper_margin,
  217215. + fbi->var.vsync_len,
  217216. + fbi->var.lower_margin,
  217217. + 0, sig_cfg) != 0) {
  217218. + dev_err(fbi->device,
  217219. + "mxcfb: Error initializing panel.\n");
  217220. + return -EINVAL;
  217221. + }
  217222. +
  217223. + fbi->mode =
  217224. + (struct fb_videomode *)fb_match_mode(&fbi->var,
  217225. + &fbi->modelist);
  217226. +
  217227. + ipu_disp_set_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch, 0, 0);
  217228. + }
  217229. +
  217230. + retval = _setup_disp_channel2(fbi);
  217231. + if (retval) {
  217232. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  217233. + return retval;
  217234. + }
  217235. +
  217236. + if (ovfbi_enable) {
  217237. + if (ov_pos_ret >= 0)
  217238. + ipu_disp_set_window_pos(
  217239. + mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch,
  217240. + ov_pos_x, ov_pos_y);
  217241. + retval = _setup_disp_channel2(mxc_fbi->ovfbi);
  217242. + if (retval) {
  217243. + ipu_uninit_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
  217244. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  217245. + return retval;
  217246. + }
  217247. + }
  217248. +
  217249. + ipu_enable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  217250. + if (ovfbi_enable)
  217251. + ipu_enable_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
  217252. +
  217253. + if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->enable) {
  217254. + retval = mxc_fbi->dispdrv->drv->enable(mxc_fbi->dispdrv);
  217255. + if (retval < 0) {
  217256. + dev_err(fbi->device, "enable error, dispdrv:%s.\n",
  217257. + mxc_fbi->dispdrv->drv->name);
  217258. + return -EINVAL;
  217259. + }
  217260. + }
  217261. +
  217262. + mxc_fbi->cur_var = fbi->var;
  217263. +
  217264. + return retval;
  217265. +}
  217266. +
  217267. +static int _swap_channels(struct fb_info *fbi_from,
  217268. + struct fb_info *fbi_to, bool both_on)
  217269. +{
  217270. + int retval, tmp;
  217271. + ipu_channel_t old_ch;
  217272. + struct fb_info *ovfbi;
  217273. + struct mxcfb_info *mxc_fbi_from = (struct mxcfb_info *)fbi_from->par;
  217274. + struct mxcfb_info *mxc_fbi_to = (struct mxcfb_info *)fbi_to->par;
  217275. +
  217276. + if (both_on) {
  217277. + ipu_disable_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch, true);
  217278. + ipu_uninit_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch);
  217279. + }
  217280. +
  217281. + /* switch the mxc fbi parameters */
  217282. + old_ch = mxc_fbi_from->ipu_ch;
  217283. + mxc_fbi_from->ipu_ch = mxc_fbi_to->ipu_ch;
  217284. + mxc_fbi_to->ipu_ch = old_ch;
  217285. + tmp = mxc_fbi_from->ipu_ch_irq;
  217286. + mxc_fbi_from->ipu_ch_irq = mxc_fbi_to->ipu_ch_irq;
  217287. + mxc_fbi_to->ipu_ch_irq = tmp;
  217288. + tmp = mxc_fbi_from->ipu_ch_nf_irq;
  217289. + mxc_fbi_from->ipu_ch_nf_irq = mxc_fbi_to->ipu_ch_nf_irq;
  217290. + mxc_fbi_to->ipu_ch_nf_irq = tmp;
  217291. + ovfbi = mxc_fbi_from->ovfbi;
  217292. + mxc_fbi_from->ovfbi = mxc_fbi_to->ovfbi;
  217293. + mxc_fbi_to->ovfbi = ovfbi;
  217294. +
  217295. + _setup_disp_channel1(fbi_from);
  217296. + retval = _setup_disp_channel2(fbi_from);
  217297. + if (retval)
  217298. + return retval;
  217299. +
  217300. + /* switch between dp and dc, disable old idmac, enable new idmac */
  217301. + retval = ipu_swap_channel(mxc_fbi_from->ipu, old_ch, mxc_fbi_from->ipu_ch);
  217302. + ipu_uninit_channel(mxc_fbi_from->ipu, old_ch);
  217303. +
  217304. + if (both_on) {
  217305. + _setup_disp_channel1(fbi_to);
  217306. + retval = _setup_disp_channel2(fbi_to);
  217307. + if (retval)
  217308. + return retval;
  217309. + ipu_enable_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch);
  217310. + }
  217311. +
  217312. + return retval;
  217313. +}
  217314. +
  217315. +static int swap_channels(struct fb_info *fbi_from)
  217316. +{
  217317. + int i;
  217318. + int swap_mode;
  217319. + ipu_channel_t ch_to;
  217320. + struct mxcfb_info *mxc_fbi_from = (struct mxcfb_info *)fbi_from->par;
  217321. + struct fb_info *fbi_to = NULL;
  217322. + struct mxcfb_info *mxc_fbi_to;
  217323. +
  217324. + /* what's the target channel? */
  217325. + if (mxc_fbi_from->ipu_ch == MEM_BG_SYNC)
  217326. + ch_to = MEM_DC_SYNC;
  217327. + else
  217328. + ch_to = MEM_BG_SYNC;
  217329. +
  217330. + fbi_to = found_registered_fb(ch_to, mxc_fbi_from->ipu_id);
  217331. + if (!fbi_to)
  217332. + return -1;
  217333. + mxc_fbi_to = (struct mxcfb_info *)fbi_to->par;
  217334. +
  217335. + ipu_clear_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq);
  217336. + ipu_clear_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq);
  217337. + ipu_free_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq, fbi_from);
  217338. + ipu_free_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq, fbi_to);
  217339. + ipu_clear_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq);
  217340. + ipu_clear_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq);
  217341. + ipu_free_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq, fbi_from);
  217342. + ipu_free_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq, fbi_to);
  217343. +
  217344. + if (mxc_fbi_from->cur_blank == FB_BLANK_UNBLANK) {
  217345. + if (mxc_fbi_to->cur_blank == FB_BLANK_UNBLANK)
  217346. + swap_mode = BOTH_ON;
  217347. + else
  217348. + swap_mode = SRC_ON;
  217349. + } else {
  217350. + if (mxc_fbi_to->cur_blank == FB_BLANK_UNBLANK)
  217351. + swap_mode = TGT_ON;
  217352. + else
  217353. + swap_mode = BOTH_OFF;
  217354. + }
  217355. +
  217356. + switch (swap_mode) {
  217357. + case BOTH_ON:
  217358. + /* disable target->switch src->enable target */
  217359. + _swap_channels(fbi_from, fbi_to, true);
  217360. + break;
  217361. + case SRC_ON:
  217362. + /* just switch src */
  217363. + _swap_channels(fbi_from, fbi_to, false);
  217364. + break;
  217365. + case TGT_ON:
  217366. + /* just switch target */
  217367. + _swap_channels(fbi_to, fbi_from, false);
  217368. + break;
  217369. + case BOTH_OFF:
  217370. + /* switch directly, no more need to do */
  217371. + mxc_fbi_to->ipu_ch = mxc_fbi_from->ipu_ch;
  217372. + mxc_fbi_from->ipu_ch = ch_to;
  217373. + i = mxc_fbi_from->ipu_ch_irq;
  217374. + mxc_fbi_from->ipu_ch_irq = mxc_fbi_to->ipu_ch_irq;
  217375. + mxc_fbi_to->ipu_ch_irq = i;
  217376. + i = mxc_fbi_from->ipu_ch_nf_irq;
  217377. + mxc_fbi_from->ipu_ch_nf_irq = mxc_fbi_to->ipu_ch_nf_irq;
  217378. + mxc_fbi_to->ipu_ch_nf_irq = i;
  217379. + break;
  217380. + default:
  217381. + break;
  217382. + }
  217383. +
  217384. + if (ipu_request_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq,
  217385. + mxcfb_irq_handler, IPU_IRQF_ONESHOT,
  217386. + MXCFB_NAME, fbi_from) != 0) {
  217387. + dev_err(fbi_from->device, "Error registering irq %d\n",
  217388. + mxc_fbi_from->ipu_ch_irq);
  217389. + return -EBUSY;
  217390. + }
  217391. + ipu_disable_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq);
  217392. + if (ipu_request_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq,
  217393. + mxcfb_irq_handler, IPU_IRQF_ONESHOT,
  217394. + MXCFB_NAME, fbi_to) != 0) {
  217395. + dev_err(fbi_to->device, "Error registering irq %d\n",
  217396. + mxc_fbi_to->ipu_ch_irq);
  217397. + return -EBUSY;
  217398. + }
  217399. + ipu_disable_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq);
  217400. + if (ipu_request_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq,
  217401. + mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT,
  217402. + MXCFB_NAME, fbi_from) != 0) {
  217403. + dev_err(fbi_from->device, "Error registering irq %d\n",
  217404. + mxc_fbi_from->ipu_ch_nf_irq);
  217405. + return -EBUSY;
  217406. + }
  217407. + ipu_disable_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq);
  217408. + if (ipu_request_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq,
  217409. + mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT,
  217410. + MXCFB_NAME, fbi_to) != 0) {
  217411. + dev_err(fbi_to->device, "Error registering irq %d\n",
  217412. + mxc_fbi_to->ipu_ch_nf_irq);
  217413. + return -EBUSY;
  217414. + }
  217415. + ipu_disable_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq);
  217416. +
  217417. + return 0;
  217418. +}
  217419. +
  217420. +/*
  217421. + * Check framebuffer variable parameters and adjust to valid values.
  217422. + *
  217423. + * @param var framebuffer variable parameters
  217424. + *
  217425. + * @param info framebuffer information pointer
  217426. + */
  217427. +static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  217428. +{
  217429. + u32 vtotal;
  217430. + u32 htotal;
  217431. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par;
  217432. +
  217433. +
  217434. + if (var->xres == 0 || var->yres == 0)
  217435. + return 0;
  217436. +
  217437. + /* fg should not bigger than bg */
  217438. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  217439. + struct fb_info *fbi_tmp;
  217440. + int bg_xres = 0, bg_yres = 0;
  217441. + int16_t pos_x, pos_y;
  217442. +
  217443. + bg_xres = var->xres;
  217444. + bg_yres = var->yres;
  217445. +
  217446. + fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  217447. + if (fbi_tmp) {
  217448. + bg_xres = fbi_tmp->var.xres;
  217449. + bg_yres = fbi_tmp->var.yres;
  217450. + }
  217451. +
  217452. + ipu_disp_get_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch, &pos_x, &pos_y);
  217453. +
  217454. + if ((var->xres + pos_x) > bg_xres)
  217455. + var->xres = bg_xres - pos_x;
  217456. + if ((var->yres + pos_y) > bg_yres)
  217457. + var->yres = bg_yres - pos_y;
  217458. + }
  217459. +
  217460. + if (var->rotate > IPU_ROTATE_VERT_FLIP)
  217461. + var->rotate = IPU_ROTATE_NONE;
  217462. +
  217463. + if (var->xres_virtual < var->xres)
  217464. + var->xres_virtual = var->xres;
  217465. +
  217466. + if (var->yres_virtual < var->yres)
  217467. + var->yres_virtual = var->yres * 3;
  217468. +
  217469. + if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) &&
  217470. + (var->bits_per_pixel != 16) && (var->bits_per_pixel != 12) &&
  217471. + (var->bits_per_pixel != 8))
  217472. + var->bits_per_pixel = 16;
  217473. +
  217474. + if (check_var_pixfmt(var))
  217475. + /* Fall back to default */
  217476. + bpp_to_var(var->bits_per_pixel, var);
  217477. +
  217478. + if (var->pixclock < 1000) {
  217479. + htotal = var->xres + var->right_margin + var->hsync_len +
  217480. + var->left_margin;
  217481. + vtotal = var->yres + var->lower_margin + var->vsync_len +
  217482. + var->upper_margin;
  217483. + var->pixclock = (vtotal * htotal * 6UL) / 100UL;
  217484. + var->pixclock = KHZ2PICOS(var->pixclock);
  217485. + dev_dbg(info->device,
  217486. + "pixclock set for 60Hz refresh = %u ps\n",
  217487. + var->pixclock);
  217488. + }
  217489. +
  217490. + var->height = -1;
  217491. + var->width = -1;
  217492. + var->grayscale = 0;
  217493. +
  217494. + return 0;
  217495. +}
  217496. +
  217497. +static inline u_int _chan_to_field(u_int chan, struct fb_bitfield *bf)
  217498. +{
  217499. + chan &= 0xffff;
  217500. + chan >>= 16 - bf->length;
  217501. + return chan << bf->offset;
  217502. +}
  217503. +
  217504. +static int mxcfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
  217505. + u_int trans, struct fb_info *fbi)
  217506. +{
  217507. + unsigned int val;
  217508. + int ret = 1;
  217509. +
  217510. + /*
  217511. + * If greyscale is true, then we convert the RGB value
  217512. + * to greyscale no matter what visual we are using.
  217513. + */
  217514. + if (fbi->var.grayscale)
  217515. + red = green = blue = (19595 * red + 38470 * green +
  217516. + 7471 * blue) >> 16;
  217517. + switch (fbi->fix.visual) {
  217518. + case FB_VISUAL_TRUECOLOR:
  217519. + /*
  217520. + * 16-bit True Colour. We encode the RGB value
  217521. + * according to the RGB bitfield information.
  217522. + */
  217523. + if (regno < 16) {
  217524. + u32 *pal = fbi->pseudo_palette;
  217525. +
  217526. + val = _chan_to_field(red, &fbi->var.red);
  217527. + val |= _chan_to_field(green, &fbi->var.green);
  217528. + val |= _chan_to_field(blue, &fbi->var.blue);
  217529. +
  217530. + pal[regno] = val;
  217531. + ret = 0;
  217532. + }
  217533. + break;
  217534. +
  217535. + case FB_VISUAL_STATIC_PSEUDOCOLOR:
  217536. + case FB_VISUAL_PSEUDOCOLOR:
  217537. + break;
  217538. + }
  217539. +
  217540. + return ret;
  217541. +}
  217542. +
  217543. +/*
  217544. + * Function to handle custom ioctls for MXC framebuffer.
  217545. + *
  217546. + * @param inode inode struct
  217547. + *
  217548. + * @param file file struct
  217549. + *
  217550. + * @param cmd Ioctl command to handle
  217551. + *
  217552. + * @param arg User pointer to command arguments
  217553. + *
  217554. + * @param fbi framebuffer information pointer
  217555. + */
  217556. +static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
  217557. +{
  217558. + int retval = 0;
  217559. + int __user *argp = (void __user *)arg;
  217560. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  217561. +
  217562. + switch (cmd) {
  217563. + case MXCFB_SET_GBL_ALPHA:
  217564. + {
  217565. + struct mxcfb_gbl_alpha ga;
  217566. +
  217567. + if (copy_from_user(&ga, (void *)arg, sizeof(ga))) {
  217568. + retval = -EFAULT;
  217569. + break;
  217570. + }
  217571. +
  217572. + if (ipu_disp_set_global_alpha(mxc_fbi->ipu,
  217573. + mxc_fbi->ipu_ch,
  217574. + (bool)ga.enable,
  217575. + ga.alpha)) {
  217576. + retval = -EINVAL;
  217577. + break;
  217578. + }
  217579. +
  217580. + if (ga.enable)
  217581. + mxc_fbi->alpha_chan_en = false;
  217582. +
  217583. + if (ga.enable)
  217584. + dev_dbg(fbi->device,
  217585. + "Set global alpha of %s to %d\n",
  217586. + fbi->fix.id, ga.alpha);
  217587. + break;
  217588. + }
  217589. + case MXCFB_SET_LOC_ALPHA:
  217590. + {
  217591. + struct mxcfb_loc_alpha la;
  217592. + bool bad_pixfmt =
  217593. + ipu_ch_param_bad_alpha_pos(fbi_to_pixfmt(fbi));
  217594. +
  217595. + if (copy_from_user(&la, (void *)arg, sizeof(la))) {
  217596. + retval = -EFAULT;
  217597. + break;
  217598. + }
  217599. +
  217600. + if (la.enable && !la.alpha_in_pixel) {
  217601. + struct fb_info *fbi_tmp;
  217602. + ipu_channel_t ipu_ch;
  217603. +
  217604. + if (bad_pixfmt) {
  217605. + dev_err(fbi->device, "Bad pixel format "
  217606. + "for graphics plane fb\n");
  217607. + retval = -EINVAL;
  217608. + break;
  217609. + }
  217610. +
  217611. + mxc_fbi->alpha_chan_en = true;
  217612. +
  217613. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC)
  217614. + ipu_ch = MEM_BG_SYNC;
  217615. + else if (mxc_fbi->ipu_ch == MEM_BG_SYNC)
  217616. + ipu_ch = MEM_FG_SYNC;
  217617. + else {
  217618. + retval = -EINVAL;
  217619. + break;
  217620. + }
  217621. +
  217622. + fbi_tmp = found_registered_fb(ipu_ch, mxc_fbi->ipu_id);
  217623. + if (fbi_tmp)
  217624. + ((struct mxcfb_info *)(fbi_tmp->par))->alpha_chan_en = false;
  217625. + } else
  217626. + mxc_fbi->alpha_chan_en = false;
  217627. +
  217628. + if (ipu_disp_set_global_alpha(mxc_fbi->ipu,
  217629. + mxc_fbi->ipu_ch,
  217630. + !(bool)la.enable, 0)) {
  217631. + retval = -EINVAL;
  217632. + break;
  217633. + }
  217634. +
  217635. + fbi->var.activate = (fbi->var.activate & ~FB_ACTIVATE_MASK) |
  217636. + FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
  217637. + mxcfb_set_par(fbi);
  217638. +
  217639. + la.alpha_phy_addr0 = mxc_fbi->alpha_phy_addr0;
  217640. + la.alpha_phy_addr1 = mxc_fbi->alpha_phy_addr1;
  217641. + if (copy_to_user((void *)arg, &la, sizeof(la))) {
  217642. + retval = -EFAULT;
  217643. + break;
  217644. + }
  217645. +
  217646. + if (la.enable)
  217647. + dev_dbg(fbi->device,
  217648. + "Enable DP local alpha for %s\n",
  217649. + fbi->fix.id);
  217650. + break;
  217651. + }
  217652. + case MXCFB_SET_LOC_ALP_BUF:
  217653. + {
  217654. + unsigned long base;
  217655. + uint32_t ipu_alp_ch_irq;
  217656. +
  217657. + if (!(((mxc_fbi->ipu_ch == MEM_FG_SYNC) ||
  217658. + (mxc_fbi->ipu_ch == MEM_BG_SYNC)) &&
  217659. + (mxc_fbi->alpha_chan_en))) {
  217660. + dev_err(fbi->device,
  217661. + "Should use background or overlay "
  217662. + "framebuffer to set the alpha buffer "
  217663. + "number\n");
  217664. + return -EINVAL;
  217665. + }
  217666. +
  217667. + if (get_user(base, argp))
  217668. + return -EFAULT;
  217669. +
  217670. + if (base != mxc_fbi->alpha_phy_addr0 &&
  217671. + base != mxc_fbi->alpha_phy_addr1) {
  217672. + dev_err(fbi->device,
  217673. + "Wrong alpha buffer physical address "
  217674. + "%lu\n", base);
  217675. + return -EINVAL;
  217676. + }
  217677. +
  217678. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC)
  217679. + ipu_alp_ch_irq = IPU_IRQ_FG_ALPHA_SYNC_EOF;
  217680. + else
  217681. + ipu_alp_ch_irq = IPU_IRQ_BG_ALPHA_SYNC_EOF;
  217682. +
  217683. + retval = wait_for_completion_timeout(
  217684. + &mxc_fbi->alpha_flip_complete, HZ/2);
  217685. + if (retval == 0) {
  217686. + dev_err(fbi->device, "timeout when waiting for alpha flip irq\n");
  217687. + retval = -ETIMEDOUT;
  217688. + break;
  217689. + }
  217690. +
  217691. + mxc_fbi->cur_ipu_alpha_buf =
  217692. + !mxc_fbi->cur_ipu_alpha_buf;
  217693. + if (ipu_update_channel_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  217694. + IPU_ALPHA_IN_BUFFER,
  217695. + mxc_fbi->
  217696. + cur_ipu_alpha_buf,
  217697. + base) == 0) {
  217698. + ipu_select_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  217699. + IPU_ALPHA_IN_BUFFER,
  217700. + mxc_fbi->cur_ipu_alpha_buf);
  217701. + ipu_clear_irq(mxc_fbi->ipu, ipu_alp_ch_irq);
  217702. + ipu_enable_irq(mxc_fbi->ipu, ipu_alp_ch_irq);
  217703. + } else {
  217704. + dev_err(fbi->device,
  217705. + "Error updating %s SDC alpha buf %d "
  217706. + "to address=0x%08lX\n",
  217707. + fbi->fix.id,
  217708. + mxc_fbi->cur_ipu_alpha_buf, base);
  217709. + }
  217710. + break;
  217711. + }
  217712. + case MXCFB_SET_CLR_KEY:
  217713. + {
  217714. + struct mxcfb_color_key key;
  217715. + if (copy_from_user(&key, (void *)arg, sizeof(key))) {
  217716. + retval = -EFAULT;
  217717. + break;
  217718. + }
  217719. + retval = ipu_disp_set_color_key(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  217720. + key.enable,
  217721. + key.color_key);
  217722. + dev_dbg(fbi->device, "Set color key to 0x%08X\n",
  217723. + key.color_key);
  217724. + break;
  217725. + }
  217726. + case MXCFB_SET_GAMMA:
  217727. + {
  217728. + struct mxcfb_gamma gamma;
  217729. + if (copy_from_user(&gamma, (void *)arg, sizeof(gamma))) {
  217730. + retval = -EFAULT;
  217731. + break;
  217732. + }
  217733. + retval = ipu_disp_set_gamma_correction(mxc_fbi->ipu,
  217734. + mxc_fbi->ipu_ch,
  217735. + gamma.enable,
  217736. + gamma.constk,
  217737. + gamma.slopek);
  217738. + break;
  217739. + }
  217740. + case MXCFB_WAIT_FOR_VSYNC:
  217741. + {
  217742. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  217743. + /* BG should poweron */
  217744. + struct mxcfb_info *bg_mxcfbi = NULL;
  217745. + struct fb_info *fbi_tmp;
  217746. +
  217747. + fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  217748. + if (fbi_tmp)
  217749. + bg_mxcfbi = ((struct mxcfb_info *)(fbi_tmp->par));
  217750. +
  217751. + if (!bg_mxcfbi) {
  217752. + retval = -EINVAL;
  217753. + break;
  217754. + }
  217755. + if (bg_mxcfbi->cur_blank != FB_BLANK_UNBLANK) {
  217756. + retval = -EINVAL;
  217757. + break;
  217758. + }
  217759. + }
  217760. + if (mxc_fbi->cur_blank != FB_BLANK_UNBLANK) {
  217761. + retval = -EINVAL;
  217762. + break;
  217763. + }
  217764. +
  217765. + init_completion(&mxc_fbi->vsync_complete);
  217766. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  217767. + ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  217768. + retval = wait_for_completion_interruptible_timeout(
  217769. + &mxc_fbi->vsync_complete, 1 * HZ);
  217770. + if (retval == 0) {
  217771. + dev_err(fbi->device,
  217772. + "MXCFB_WAIT_FOR_VSYNC: timeout %d\n",
  217773. + retval);
  217774. + retval = -ETIME;
  217775. + } else if (retval > 0) {
  217776. + retval = 0;
  217777. + }
  217778. + break;
  217779. + }
  217780. + case FBIO_ALLOC:
  217781. + {
  217782. + int size;
  217783. + struct mxcfb_alloc_list *mem;
  217784. +
  217785. + mem = kzalloc(sizeof(*mem), GFP_KERNEL);
  217786. + if (mem == NULL)
  217787. + return -ENOMEM;
  217788. +
  217789. + if (get_user(size, argp))
  217790. + return -EFAULT;
  217791. +
  217792. + mem->size = PAGE_ALIGN(size);
  217793. +
  217794. + mem->cpu_addr = dma_alloc_coherent(fbi->device, size,
  217795. + &mem->phy_addr,
  217796. + GFP_KERNEL);
  217797. + if (mem->cpu_addr == NULL) {
  217798. + kfree(mem);
  217799. + return -ENOMEM;
  217800. + }
  217801. +
  217802. + list_add(&mem->list, &fb_alloc_list);
  217803. +
  217804. + dev_dbg(fbi->device, "allocated %d bytes @ 0x%08X\n",
  217805. + mem->size, mem->phy_addr);
  217806. +
  217807. + if (put_user(mem->phy_addr, argp))
  217808. + return -EFAULT;
  217809. +
  217810. + break;
  217811. + }
  217812. + case FBIO_FREE:
  217813. + {
  217814. + unsigned long offset;
  217815. + struct mxcfb_alloc_list *mem;
  217816. +
  217817. + if (get_user(offset, argp))
  217818. + return -EFAULT;
  217819. +
  217820. + retval = -EINVAL;
  217821. + list_for_each_entry(mem, &fb_alloc_list, list) {
  217822. + if (mem->phy_addr == offset) {
  217823. + list_del(&mem->list);
  217824. + dma_free_coherent(fbi->device,
  217825. + mem->size,
  217826. + mem->cpu_addr,
  217827. + mem->phy_addr);
  217828. + kfree(mem);
  217829. + retval = 0;
  217830. + break;
  217831. + }
  217832. + }
  217833. +
  217834. + break;
  217835. + }
  217836. + case MXCFB_SET_OVERLAY_POS:
  217837. + {
  217838. + struct mxcfb_pos pos;
  217839. + struct fb_info *bg_fbi = NULL;
  217840. + struct mxcfb_info *bg_mxcfbi = NULL;
  217841. +
  217842. + if (mxc_fbi->ipu_ch != MEM_FG_SYNC) {
  217843. + dev_err(fbi->device, "Should use the overlay "
  217844. + "framebuffer to set the position of "
  217845. + "the overlay window\n");
  217846. + retval = -EINVAL;
  217847. + break;
  217848. + }
  217849. +
  217850. + if (copy_from_user(&pos, (void *)arg, sizeof(pos))) {
  217851. + retval = -EFAULT;
  217852. + break;
  217853. + }
  217854. +
  217855. + bg_fbi = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  217856. + if (bg_fbi)
  217857. + bg_mxcfbi = ((struct mxcfb_info *)(bg_fbi->par));
  217858. +
  217859. + if (bg_fbi == NULL) {
  217860. + dev_err(fbi->device, "Cannot find the "
  217861. + "background framebuffer\n");
  217862. + retval = -ENOENT;
  217863. + break;
  217864. + }
  217865. +
  217866. + /* if fb is unblank, check if the pos fit the display */
  217867. + if (mxc_fbi->cur_blank == FB_BLANK_UNBLANK) {
  217868. + if (fbi->var.xres + pos.x > bg_fbi->var.xres) {
  217869. + if (bg_fbi->var.xres < fbi->var.xres)
  217870. + pos.x = 0;
  217871. + else
  217872. + pos.x = bg_fbi->var.xres - fbi->var.xres;
  217873. + }
  217874. + if (fbi->var.yres + pos.y > bg_fbi->var.yres) {
  217875. + if (bg_fbi->var.yres < fbi->var.yres)
  217876. + pos.y = 0;
  217877. + else
  217878. + pos.y = bg_fbi->var.yres - fbi->var.yres;
  217879. + }
  217880. + }
  217881. +
  217882. + retval = ipu_disp_set_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  217883. + pos.x, pos.y);
  217884. +
  217885. + if (copy_to_user((void *)arg, &pos, sizeof(pos))) {
  217886. + retval = -EFAULT;
  217887. + break;
  217888. + }
  217889. + break;
  217890. + }
  217891. + case MXCFB_GET_FB_IPU_CHAN:
  217892. + {
  217893. + struct mxcfb_info *mxc_fbi =
  217894. + (struct mxcfb_info *)fbi->par;
  217895. +
  217896. + if (put_user(mxc_fbi->ipu_ch, argp))
  217897. + return -EFAULT;
  217898. + break;
  217899. + }
  217900. + case MXCFB_GET_DIFMT:
  217901. + {
  217902. + struct mxcfb_info *mxc_fbi =
  217903. + (struct mxcfb_info *)fbi->par;
  217904. +
  217905. + if (put_user(mxc_fbi->ipu_di_pix_fmt, argp))
  217906. + return -EFAULT;
  217907. + break;
  217908. + }
  217909. + case MXCFB_GET_FB_IPU_DI:
  217910. + {
  217911. + struct mxcfb_info *mxc_fbi =
  217912. + (struct mxcfb_info *)fbi->par;
  217913. +
  217914. + if (put_user(mxc_fbi->ipu_di, argp))
  217915. + return -EFAULT;
  217916. + break;
  217917. + }
  217918. + case MXCFB_GET_FB_BLANK:
  217919. + {
  217920. + struct mxcfb_info *mxc_fbi =
  217921. + (struct mxcfb_info *)fbi->par;
  217922. +
  217923. + if (put_user(mxc_fbi->cur_blank, argp))
  217924. + return -EFAULT;
  217925. + break;
  217926. + }
  217927. + case MXCFB_SET_DIFMT:
  217928. + {
  217929. + struct mxcfb_info *mxc_fbi =
  217930. + (struct mxcfb_info *)fbi->par;
  217931. +
  217932. + if (get_user(mxc_fbi->ipu_di_pix_fmt, argp))
  217933. + return -EFAULT;
  217934. +
  217935. + break;
  217936. + }
  217937. + case MXCFB_CSC_UPDATE:
  217938. + {
  217939. + struct mxcfb_csc_matrix csc;
  217940. +
  217941. + if (copy_from_user(&csc, (void *) arg, sizeof(csc)))
  217942. + return -EFAULT;
  217943. +
  217944. + if ((mxc_fbi->ipu_ch != MEM_FG_SYNC) &&
  217945. + (mxc_fbi->ipu_ch != MEM_BG_SYNC) &&
  217946. + (mxc_fbi->ipu_ch != MEM_BG_ASYNC0))
  217947. + return -EFAULT;
  217948. + ipu_set_csc_coefficients(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  217949. + csc.param);
  217950. + }
  217951. + default:
  217952. + retval = -EINVAL;
  217953. + }
  217954. + return retval;
  217955. +}
  217956. +
  217957. +/*
  217958. + * mxcfb_blank():
  217959. + * Blank the display.
  217960. + */
  217961. +static int mxcfb_blank(int blank, struct fb_info *info)
  217962. +{
  217963. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par;
  217964. + int ret = 0;
  217965. +
  217966. + dev_dbg(info->device, "blank = %d\n", blank);
  217967. +
  217968. + if (mxc_fbi->cur_blank == blank)
  217969. + return 0;
  217970. +
  217971. + mxc_fbi->next_blank = blank;
  217972. +
  217973. + switch (blank) {
  217974. + case FB_BLANK_POWERDOWN:
  217975. + case FB_BLANK_VSYNC_SUSPEND:
  217976. + case FB_BLANK_HSYNC_SUSPEND:
  217977. + case FB_BLANK_NORMAL:
  217978. + if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->disable)
  217979. + mxc_fbi->dispdrv->drv->disable(mxc_fbi->dispdrv);
  217980. + ipu_disable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, true);
  217981. + if (mxc_fbi->ipu_di >= 0)
  217982. + ipu_uninit_sync_panel(mxc_fbi->ipu, mxc_fbi->ipu_di);
  217983. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  217984. + break;
  217985. + case FB_BLANK_UNBLANK:
  217986. + info->var.activate = (info->var.activate & ~FB_ACTIVATE_MASK) |
  217987. + FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
  217988. + ret = mxcfb_set_par(info);
  217989. + break;
  217990. + }
  217991. + if (!ret)
  217992. + mxc_fbi->cur_blank = blank;
  217993. + return ret;
  217994. +}
  217995. +
  217996. +/*
  217997. + * Pan or Wrap the Display
  217998. + *
  217999. + * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
  218000. + *
  218001. + * @param var Variable screen buffer information
  218002. + * @param info Framebuffer information pointer
  218003. + */
  218004. +static int
  218005. +mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
  218006. +{
  218007. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par,
  218008. + *mxc_graphic_fbi = NULL;
  218009. + u_int y_bottom;
  218010. + unsigned int fr_xoff, fr_yoff, fr_w, fr_h;
  218011. + unsigned long base, active_alpha_phy_addr = 0;
  218012. + bool loc_alpha_en = false;
  218013. + int fb_stride;
  218014. + int i;
  218015. + int ret;
  218016. +
  218017. + /* no pan display during fb blank */
  218018. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  218019. + struct mxcfb_info *bg_mxcfbi = NULL;
  218020. + struct fb_info *fbi_tmp;
  218021. +
  218022. + fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  218023. + if (fbi_tmp)
  218024. + bg_mxcfbi = ((struct mxcfb_info *)(fbi_tmp->par));
  218025. + if (!bg_mxcfbi)
  218026. + return -EINVAL;
  218027. + if (bg_mxcfbi->cur_blank != FB_BLANK_UNBLANK)
  218028. + return -EINVAL;
  218029. + }
  218030. + if (mxc_fbi->cur_blank != FB_BLANK_UNBLANK)
  218031. + return -EINVAL;
  218032. +
  218033. + y_bottom = var->yoffset;
  218034. +
  218035. + if (y_bottom > info->var.yres_virtual)
  218036. + return -EINVAL;
  218037. +
  218038. + switch (fbi_to_pixfmt(info)) {
  218039. + case IPU_PIX_FMT_YUV420P2:
  218040. + case IPU_PIX_FMT_YVU420P:
  218041. + case IPU_PIX_FMT_NV12:
  218042. + case IPU_PIX_FMT_YUV422P:
  218043. + case IPU_PIX_FMT_YVU422P:
  218044. + case IPU_PIX_FMT_YUV420P:
  218045. + case IPU_PIX_FMT_YUV444P:
  218046. + fb_stride = info->var.xres_virtual;
  218047. + break;
  218048. + default:
  218049. + fb_stride = info->fix.line_length;
  218050. + }
  218051. +
  218052. + base = info->fix.smem_start;
  218053. + fr_xoff = var->xoffset;
  218054. + fr_w = info->var.xres_virtual;
  218055. + if (!(var->vmode & FB_VMODE_YWRAP)) {
  218056. + dev_dbg(info->device, "Y wrap disabled\n");
  218057. + fr_yoff = var->yoffset % info->var.yres;
  218058. + fr_h = info->var.yres;
  218059. + base += info->fix.line_length * info->var.yres *
  218060. + (var->yoffset / info->var.yres);
  218061. + } else {
  218062. + dev_dbg(info->device, "Y wrap enabled\n");
  218063. + fr_yoff = var->yoffset;
  218064. + fr_h = info->var.yres_virtual;
  218065. + }
  218066. + base += fr_yoff * fb_stride + fr_xoff;
  218067. +
  218068. + /* Check if DP local alpha is enabled and find the graphic fb */
  218069. + if (mxc_fbi->ipu_ch == MEM_BG_SYNC || mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  218070. + for (i = 0; i < num_registered_fb; i++) {
  218071. + char bg_id[] = "DISP3 BG";
  218072. + char fg_id[] = "DISP3 FG";
  218073. + char *idstr = registered_fb[i]->fix.id;
  218074. + bg_id[4] += mxc_fbi->ipu_id;
  218075. + fg_id[4] += mxc_fbi->ipu_id;
  218076. + if ((strcmp(idstr, bg_id) == 0 ||
  218077. + strcmp(idstr, fg_id) == 0) &&
  218078. + ((struct mxcfb_info *)
  218079. + (registered_fb[i]->par))->alpha_chan_en) {
  218080. + loc_alpha_en = true;
  218081. + mxc_graphic_fbi = (struct mxcfb_info *)
  218082. + (registered_fb[i]->par);
  218083. + active_alpha_phy_addr =
  218084. + mxc_fbi->cur_ipu_alpha_buf ?
  218085. + mxc_graphic_fbi->alpha_phy_addr1 :
  218086. + mxc_graphic_fbi->alpha_phy_addr0;
  218087. + dev_dbg(info->device, "Updating SDC alpha "
  218088. + "buf %d address=0x%08lX\n",
  218089. + !mxc_fbi->cur_ipu_alpha_buf,
  218090. + active_alpha_phy_addr);
  218091. + break;
  218092. + }
  218093. + }
  218094. + }
  218095. +
  218096. + ret = wait_for_completion_timeout(&mxc_fbi->flip_complete, HZ/2);
  218097. + if (ret == 0) {
  218098. + dev_err(info->device, "timeout when waiting for flip irq\n");
  218099. + return -ETIMEDOUT;
  218100. + }
  218101. +
  218102. + ++mxc_fbi->cur_ipu_buf;
  218103. + mxc_fbi->cur_ipu_buf %= 3;
  218104. + mxc_fbi->cur_ipu_alpha_buf = !mxc_fbi->cur_ipu_alpha_buf;
  218105. +
  218106. + dev_dbg(info->device, "Updating SDC %s buf %d address=0x%08lX\n",
  218107. + info->fix.id, mxc_fbi->cur_ipu_buf, base);
  218108. +
  218109. + if (ipu_update_channel_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
  218110. + mxc_fbi->cur_ipu_buf, base) == 0) {
  218111. + /* Update the DP local alpha buffer only for graphic plane */
  218112. + if (loc_alpha_en && mxc_graphic_fbi == mxc_fbi &&
  218113. + ipu_update_channel_buffer(mxc_graphic_fbi->ipu, mxc_graphic_fbi->ipu_ch,
  218114. + IPU_ALPHA_IN_BUFFER,
  218115. + mxc_fbi->cur_ipu_alpha_buf,
  218116. + active_alpha_phy_addr) == 0) {
  218117. + ipu_select_buffer(mxc_graphic_fbi->ipu, mxc_graphic_fbi->ipu_ch,
  218118. + IPU_ALPHA_IN_BUFFER,
  218119. + mxc_fbi->cur_ipu_alpha_buf);
  218120. + }
  218121. +
  218122. + /* update u/v offset */
  218123. + ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  218124. + IPU_INPUT_BUFFER,
  218125. + fbi_to_pixfmt(info),
  218126. + fr_w,
  218127. + fr_h,
  218128. + fr_w,
  218129. + 0, 0,
  218130. + fr_yoff,
  218131. + fr_xoff);
  218132. +
  218133. + ipu_select_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
  218134. + mxc_fbi->cur_ipu_buf);
  218135. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  218136. + ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  218137. + } else {
  218138. + dev_err(info->device,
  218139. + "Error updating SDC buf %d to address=0x%08lX, "
  218140. + "current buf %d, buf0 ready %d, buf1 ready %d, "
  218141. + "buf2 ready %d\n", mxc_fbi->cur_ipu_buf, base,
  218142. + ipu_get_cur_buffer_idx(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  218143. + IPU_INPUT_BUFFER),
  218144. + ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  218145. + IPU_INPUT_BUFFER, 0),
  218146. + ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  218147. + IPU_INPUT_BUFFER, 1),
  218148. + ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  218149. + IPU_INPUT_BUFFER, 2));
  218150. + ++mxc_fbi->cur_ipu_buf;
  218151. + mxc_fbi->cur_ipu_buf %= 3;
  218152. + ++mxc_fbi->cur_ipu_buf;
  218153. + mxc_fbi->cur_ipu_buf %= 3;
  218154. + mxc_fbi->cur_ipu_alpha_buf = !mxc_fbi->cur_ipu_alpha_buf;
  218155. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  218156. + ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  218157. + return -EBUSY;
  218158. + }
  218159. +
  218160. + dev_dbg(info->device, "Update complete\n");
  218161. +
  218162. + info->var.yoffset = var->yoffset;
  218163. +
  218164. + return 0;
  218165. +}
  218166. +
  218167. +/*
  218168. + * Function to handle custom mmap for MXC framebuffer.
  218169. + *
  218170. + * @param fbi framebuffer information pointer
  218171. + *
  218172. + * @param vma Pointer to vm_area_struct
  218173. + */
  218174. +static int mxcfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
  218175. +{
  218176. + bool found = false;
  218177. + u32 len;
  218178. + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  218179. + struct mxcfb_alloc_list *mem;
  218180. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  218181. +
  218182. + if (offset < fbi->fix.smem_len) {
  218183. + /* mapping framebuffer memory */
  218184. + len = fbi->fix.smem_len - offset;
  218185. + vma->vm_pgoff = (fbi->fix.smem_start + offset) >> PAGE_SHIFT;
  218186. + } else if ((vma->vm_pgoff ==
  218187. + (mxc_fbi->alpha_phy_addr0 >> PAGE_SHIFT)) ||
  218188. + (vma->vm_pgoff ==
  218189. + (mxc_fbi->alpha_phy_addr1 >> PAGE_SHIFT))) {
  218190. + len = mxc_fbi->alpha_mem_len;
  218191. + } else {
  218192. + list_for_each_entry(mem, &fb_alloc_list, list) {
  218193. + if (offset == mem->phy_addr) {
  218194. + found = true;
  218195. + len = mem->size;
  218196. + break;
  218197. + }
  218198. + }
  218199. + if (!found)
  218200. + return -EINVAL;
  218201. + }
  218202. +
  218203. + len = PAGE_ALIGN(len);
  218204. + if (vma->vm_end - vma->vm_start > len)
  218205. + return -EINVAL;
  218206. +
  218207. + /* make buffers bufferable */
  218208. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  218209. +
  218210. + vma->vm_flags |= VM_IO;
  218211. +
  218212. + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  218213. + vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
  218214. + dev_dbg(fbi->device, "mmap remap_pfn_range failed\n");
  218215. + return -ENOBUFS;
  218216. + }
  218217. +
  218218. + return 0;
  218219. +}
  218220. +
  218221. +/*!
  218222. + * This structure contains the pointers to the control functions that are
  218223. + * invoked by the core framebuffer driver to perform operations like
  218224. + * blitting, rectangle filling, copy regions and cursor definition.
  218225. + */
  218226. +static struct fb_ops mxcfb_ops = {
  218227. + .owner = THIS_MODULE,
  218228. + .fb_set_par = mxcfb_set_par,
  218229. + .fb_check_var = mxcfb_check_var,
  218230. + .fb_setcolreg = mxcfb_setcolreg,
  218231. + .fb_pan_display = mxcfb_pan_display,
  218232. + .fb_ioctl = mxcfb_ioctl,
  218233. + .fb_mmap = mxcfb_mmap,
  218234. + .fb_fillrect = cfb_fillrect,
  218235. + .fb_copyarea = cfb_copyarea,
  218236. + .fb_imageblit = cfb_imageblit,
  218237. + .fb_blank = mxcfb_blank,
  218238. +};
  218239. +
  218240. +static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id)
  218241. +{
  218242. + struct fb_info *fbi = dev_id;
  218243. + struct mxcfb_info *mxc_fbi = fbi->par;
  218244. +
  218245. + complete(&mxc_fbi->flip_complete);
  218246. + return IRQ_HANDLED;
  218247. +}
  218248. +
  218249. +static irqreturn_t mxcfb_nf_irq_handler(int irq, void *dev_id)
  218250. +{
  218251. + struct fb_info *fbi = dev_id;
  218252. + struct mxcfb_info *mxc_fbi = fbi->par;
  218253. +
  218254. + complete(&mxc_fbi->vsync_complete);
  218255. + return IRQ_HANDLED;
  218256. +}
  218257. +
  218258. +static irqreturn_t mxcfb_alpha_irq_handler(int irq, void *dev_id)
  218259. +{
  218260. + struct fb_info *fbi = dev_id;
  218261. + struct mxcfb_info *mxc_fbi = fbi->par;
  218262. +
  218263. + complete(&mxc_fbi->alpha_flip_complete);
  218264. + return IRQ_HANDLED;
  218265. +}
  218266. +
  218267. +/*
  218268. + * Suspends the framebuffer and blanks the screen. Power management support
  218269. + */
  218270. +static int mxcfb_suspend(struct platform_device *pdev, pm_message_t state)
  218271. +{
  218272. + struct fb_info *fbi = platform_get_drvdata(pdev);
  218273. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  218274. + int saved_blank;
  218275. +#ifdef CONFIG_FB_MXC_LOW_PWR_DISPLAY
  218276. + void *fbmem;
  218277. +#endif
  218278. +
  218279. + if (mxc_fbi->ovfbi) {
  218280. + struct mxcfb_info *mxc_fbi_fg =
  218281. + (struct mxcfb_info *)mxc_fbi->ovfbi->par;
  218282. +
  218283. + console_lock();
  218284. + fb_set_suspend(mxc_fbi->ovfbi, 1);
  218285. + saved_blank = mxc_fbi_fg->cur_blank;
  218286. + mxcfb_blank(FB_BLANK_POWERDOWN, mxc_fbi->ovfbi);
  218287. + mxc_fbi_fg->next_blank = saved_blank;
  218288. + console_unlock();
  218289. + }
  218290. +
  218291. + console_lock();
  218292. + fb_set_suspend(fbi, 1);
  218293. + saved_blank = mxc_fbi->cur_blank;
  218294. + mxcfb_blank(FB_BLANK_POWERDOWN, fbi);
  218295. + mxc_fbi->next_blank = saved_blank;
  218296. + console_unlock();
  218297. +
  218298. + return 0;
  218299. +}
  218300. +
  218301. +/*
  218302. + * Resumes the framebuffer and unblanks the screen. Power management support
  218303. + */
  218304. +static int mxcfb_resume(struct platform_device *pdev)
  218305. +{
  218306. + struct fb_info *fbi = platform_get_drvdata(pdev);
  218307. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  218308. +
  218309. + console_lock();
  218310. + mxcfb_blank(mxc_fbi->next_blank, fbi);
  218311. + fb_set_suspend(fbi, 0);
  218312. + console_unlock();
  218313. +
  218314. + if (mxc_fbi->ovfbi) {
  218315. + struct mxcfb_info *mxc_fbi_fg =
  218316. + (struct mxcfb_info *)mxc_fbi->ovfbi->par;
  218317. + console_lock();
  218318. + mxcfb_blank(mxc_fbi_fg->next_blank, mxc_fbi->ovfbi);
  218319. + fb_set_suspend(mxc_fbi->ovfbi, 0);
  218320. + console_unlock();
  218321. + }
  218322. +
  218323. + return 0;
  218324. +}
  218325. +
  218326. +/*
  218327. + * Main framebuffer functions
  218328. + */
  218329. +
  218330. +/*!
  218331. + * Allocates the DRAM memory for the frame buffer. This buffer is remapped
  218332. + * into a non-cached, non-buffered, memory region to allow palette and pixel
  218333. + * writes to occur without flushing the cache. Once this area is remapped,
  218334. + * all virtual memory access to the video memory should occur at the new region.
  218335. + *
  218336. + * @param fbi framebuffer information pointer
  218337. + *
  218338. + * @return Error code indicating success or failure
  218339. + */
  218340. +static int mxcfb_map_video_memory(struct fb_info *fbi)
  218341. +{
  218342. + if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length)
  218343. + fbi->fix.smem_len = fbi->var.yres_virtual *
  218344. + fbi->fix.line_length;
  218345. +
  218346. + fbi->screen_base = dma_alloc_writecombine(fbi->device,
  218347. + fbi->fix.smem_len,
  218348. + (dma_addr_t *)&fbi->fix.smem_start,
  218349. + GFP_DMA | GFP_KERNEL);
  218350. + if (fbi->screen_base == 0) {
  218351. + dev_err(fbi->device, "Unable to allocate framebuffer memory\n");
  218352. + fbi->fix.smem_len = 0;
  218353. + fbi->fix.smem_start = 0;
  218354. + return -EBUSY;
  218355. + }
  218356. +
  218357. + dev_dbg(fbi->device, "allocated fb @ paddr=0x%08X, size=%d.\n",
  218358. + (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
  218359. +
  218360. + fbi->screen_size = fbi->fix.smem_len;
  218361. +
  218362. + /* Clear the screen */
  218363. + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
  218364. +
  218365. + return 0;
  218366. +}
  218367. +
  218368. +/*!
  218369. + * De-allocates the DRAM memory for the frame buffer.
  218370. + *
  218371. + * @param fbi framebuffer information pointer
  218372. + *
  218373. + * @return Error code indicating success or failure
  218374. + */
  218375. +static int mxcfb_unmap_video_memory(struct fb_info *fbi)
  218376. +{
  218377. + dma_free_writecombine(fbi->device, fbi->fix.smem_len,
  218378. + fbi->screen_base, fbi->fix.smem_start);
  218379. + fbi->screen_base = 0;
  218380. + fbi->fix.smem_start = 0;
  218381. + fbi->fix.smem_len = 0;
  218382. + return 0;
  218383. +}
  218384. +
  218385. +/*!
  218386. + * Initializes the framebuffer information pointer. After allocating
  218387. + * sufficient memory for the framebuffer structure, the fields are
  218388. + * filled with custom information passed in from the configurable
  218389. + * structures. This includes information such as bits per pixel,
  218390. + * color maps, screen width/height and RGBA offsets.
  218391. + *
  218392. + * @return Framebuffer structure initialized with our information
  218393. + */
  218394. +static struct fb_info *mxcfb_init_fbinfo(struct device *dev, struct fb_ops *ops)
  218395. +{
  218396. + struct fb_info *fbi;
  218397. + struct mxcfb_info *mxcfbi;
  218398. +
  218399. + /*
  218400. + * Allocate sufficient memory for the fb structure
  218401. + */
  218402. + fbi = framebuffer_alloc(sizeof(struct mxcfb_info), dev);
  218403. + if (!fbi)
  218404. + return NULL;
  218405. +
  218406. + mxcfbi = (struct mxcfb_info *)fbi->par;
  218407. +
  218408. + fbi->var.activate = FB_ACTIVATE_NOW;
  218409. +
  218410. + fbi->fbops = ops;
  218411. + fbi->flags = FBINFO_FLAG_DEFAULT;
  218412. + fbi->pseudo_palette = mxcfbi->pseudo_palette;
  218413. +
  218414. + /*
  218415. + * Allocate colormap
  218416. + */
  218417. + fb_alloc_cmap(&fbi->cmap, 16, 0);
  218418. +
  218419. + return fbi;
  218420. +}
  218421. +
  218422. +static ssize_t show_disp_chan(struct device *dev,
  218423. + struct device_attribute *attr, char *buf)
  218424. +{
  218425. + struct fb_info *info = dev_get_drvdata(dev);
  218426. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
  218427. +
  218428. + if (mxcfbi->ipu_ch == MEM_BG_SYNC)
  218429. + return sprintf(buf, "2-layer-fb-bg\n");
  218430. + else if (mxcfbi->ipu_ch == MEM_FG_SYNC)
  218431. + return sprintf(buf, "2-layer-fb-fg\n");
  218432. + else if (mxcfbi->ipu_ch == MEM_DC_SYNC)
  218433. + return sprintf(buf, "1-layer-fb\n");
  218434. + else
  218435. + return sprintf(buf, "err: no display chan\n");
  218436. +}
  218437. +
  218438. +static ssize_t swap_disp_chan(struct device *dev,
  218439. + struct device_attribute *attr,
  218440. + const char *buf, size_t count)
  218441. +{
  218442. + struct fb_info *info = dev_get_drvdata(dev);
  218443. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
  218444. + struct mxcfb_info *fg_mxcfbi = NULL;
  218445. +
  218446. + console_lock();
  218447. + /* swap only happen between DP-BG and DC, while DP-FG disable */
  218448. + if (((mxcfbi->ipu_ch == MEM_BG_SYNC) &&
  218449. + (strstr(buf, "1-layer-fb") != NULL)) ||
  218450. + ((mxcfbi->ipu_ch == MEM_DC_SYNC) &&
  218451. + (strstr(buf, "2-layer-fb-bg") != NULL))) {
  218452. + struct fb_info *fbi_fg;
  218453. +
  218454. + fbi_fg = found_registered_fb(MEM_FG_SYNC, mxcfbi->ipu_id);
  218455. + if (fbi_fg)
  218456. + fg_mxcfbi = (struct mxcfb_info *)fbi_fg->par;
  218457. +
  218458. + if (!fg_mxcfbi ||
  218459. + fg_mxcfbi->cur_blank == FB_BLANK_UNBLANK) {
  218460. + dev_err(dev,
  218461. + "Can not switch while fb2(fb-fg) is on.\n");
  218462. + console_unlock();
  218463. + return count;
  218464. + }
  218465. +
  218466. + if (swap_channels(info) < 0)
  218467. + dev_err(dev, "Swap display channel failed.\n");
  218468. + }
  218469. +
  218470. + console_unlock();
  218471. + return count;
  218472. +}
  218473. +static DEVICE_ATTR(fsl_disp_property, S_IWUSR | S_IRUGO,
  218474. + show_disp_chan, swap_disp_chan);
  218475. +
  218476. +static ssize_t show_disp_dev(struct device *dev,
  218477. + struct device_attribute *attr, char *buf)
  218478. +{
  218479. + struct fb_info *info = dev_get_drvdata(dev);
  218480. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
  218481. +
  218482. + if (mxcfbi->ipu_ch == MEM_FG_SYNC)
  218483. + return sprintf(buf, "overlay\n");
  218484. + else
  218485. + return sprintf(buf, "%s\n", mxcfbi->dispdrv->drv->name);
  218486. +}
  218487. +static DEVICE_ATTR(fsl_disp_dev_property, S_IRUGO, show_disp_dev, NULL);
  218488. +
  218489. +static int mxcfb_dispdrv_init(struct platform_device *pdev,
  218490. + struct fb_info *fbi)
  218491. +{
  218492. + struct ipuv3_fb_platform_data *plat_data = pdev->dev.platform_data;
  218493. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
  218494. + struct mxc_dispdrv_setting setting;
  218495. + char disp_dev[32], *default_dev = "lcd";
  218496. + int ret = 0;
  218497. +
  218498. + setting.if_fmt = plat_data->interface_pix_fmt;
  218499. + setting.dft_mode_str = plat_data->mode_str;
  218500. + setting.default_bpp = plat_data->default_bpp;
  218501. + if (!setting.default_bpp)
  218502. + setting.default_bpp = 16;
  218503. + setting.fbi = fbi;
  218504. + if (!strlen(plat_data->disp_dev)) {
  218505. + memcpy(disp_dev, default_dev, strlen(default_dev));
  218506. + disp_dev[strlen(default_dev)] = '\0';
  218507. + } else {
  218508. + memcpy(disp_dev, plat_data->disp_dev,
  218509. + strlen(plat_data->disp_dev));
  218510. + disp_dev[strlen(plat_data->disp_dev)] = '\0';
  218511. + }
  218512. +
  218513. + dev_info(&pdev->dev, "register mxc display driver %s\n", disp_dev);
  218514. +
  218515. + mxcfbi->dispdrv = mxc_dispdrv_gethandle(disp_dev, &setting);
  218516. + if (IS_ERR(mxcfbi->dispdrv)) {
  218517. + ret = PTR_ERR(mxcfbi->dispdrv);
  218518. + dev_err(&pdev->dev, "NO mxc display driver found!\n");
  218519. + return ret;
  218520. + } else {
  218521. + /* fix-up */
  218522. + mxcfbi->ipu_di_pix_fmt = setting.if_fmt;
  218523. + mxcfbi->default_bpp = setting.default_bpp;
  218524. +
  218525. + /* setting */
  218526. + mxcfbi->ipu_id = setting.dev_id;
  218527. + mxcfbi->ipu_di = setting.disp_id;
  218528. + dev_dbg(&pdev->dev, "di_pixfmt:0x%x, bpp:0x%x, di:%d, ipu:%d\n",
  218529. + setting.if_fmt, setting.default_bpp,
  218530. + setting.disp_id, setting.dev_id);
  218531. + }
  218532. +
  218533. + return ret;
  218534. +}
  218535. +
  218536. +/*
  218537. + * Parse user specified options (`video=trident:')
  218538. + * example:
  218539. + * video=mxcfb0:dev=lcd,800x480M-16@55,if=RGB565,bpp=16,noaccel
  218540. + * video=mxcfb0:dev=lcd,800x480M-16@55,if=RGB565,fbpix=RGB565
  218541. + */
  218542. +static int mxcfb_option_setup(struct platform_device *pdev, struct fb_info *fbi)
  218543. +{
  218544. + struct ipuv3_fb_platform_data *pdata = pdev->dev.platform_data;
  218545. + char *options, *opt, *fb_mode_str = NULL;
  218546. + char name[] = "mxcfb0";
  218547. + uint32_t fb_pix_fmt = 0;
  218548. +
  218549. + name[5] += pdev->id;
  218550. + if (fb_get_options(name, &options)) {
  218551. + dev_err(&pdev->dev, "Can't get fb option for %s!\n", name);
  218552. + return -ENODEV;
  218553. + }
  218554. +
  218555. + if (!options || !*options)
  218556. + return 0;
  218557. +
  218558. + while ((opt = strsep(&options, ",")) != NULL) {
  218559. + if (!*opt)
  218560. + continue;
  218561. +
  218562. + if (!strncmp(opt, "dev=", 4)) {
  218563. + memcpy(pdata->disp_dev, opt + 4, strlen(opt) - 4);
  218564. + pdata->disp_dev[strlen(opt) - 4] = '\0';
  218565. + } else if (!strncmp(opt, "if=", 3)) {
  218566. + if (!strncmp(opt+3, "RGB24", 5))
  218567. + pdata->interface_pix_fmt = IPU_PIX_FMT_RGB24;
  218568. + else if (!strncmp(opt+3, "BGR24", 5))
  218569. + pdata->interface_pix_fmt = IPU_PIX_FMT_BGR24;
  218570. + else if (!strncmp(opt+3, "GBR24", 5))
  218571. + pdata->interface_pix_fmt = IPU_PIX_FMT_GBR24;
  218572. + else if (!strncmp(opt+3, "RGB565", 6))
  218573. + pdata->interface_pix_fmt = IPU_PIX_FMT_RGB565;
  218574. + else if (!strncmp(opt+3, "RGB666", 6))
  218575. + pdata->interface_pix_fmt = IPU_PIX_FMT_RGB666;
  218576. + else if (!strncmp(opt+3, "YUV444", 6))
  218577. + pdata->interface_pix_fmt = IPU_PIX_FMT_YUV444;
  218578. + else if (!strncmp(opt+3, "LVDS666", 7))
  218579. + pdata->interface_pix_fmt = IPU_PIX_FMT_LVDS666;
  218580. + else if (!strncmp(opt+3, "YUYV16", 6))
  218581. + pdata->interface_pix_fmt = IPU_PIX_FMT_YUYV;
  218582. + else if (!strncmp(opt+3, "UYVY16", 6))
  218583. + pdata->interface_pix_fmt = IPU_PIX_FMT_UYVY;
  218584. + else if (!strncmp(opt+3, "YVYU16", 6))
  218585. + pdata->interface_pix_fmt = IPU_PIX_FMT_YVYU;
  218586. + else if (!strncmp(opt+3, "VYUY16", 6))
  218587. + pdata->interface_pix_fmt = IPU_PIX_FMT_VYUY;
  218588. + } else if (!strncmp(opt, "fbpix=", 6)) {
  218589. + if (!strncmp(opt+6, "RGB24", 5))
  218590. + fb_pix_fmt = IPU_PIX_FMT_RGB24;
  218591. + else if (!strncmp(opt+6, "BGR24", 5))
  218592. + fb_pix_fmt = IPU_PIX_FMT_BGR24;
  218593. + else if (!strncmp(opt+6, "RGB32", 5))
  218594. + fb_pix_fmt = IPU_PIX_FMT_RGB32;
  218595. + else if (!strncmp(opt+6, "BGR32", 5))
  218596. + fb_pix_fmt = IPU_PIX_FMT_BGR32;
  218597. + else if (!strncmp(opt+6, "ABGR32", 6))
  218598. + fb_pix_fmt = IPU_PIX_FMT_ABGR32;
  218599. + else if (!strncmp(opt+6, "RGB565", 6))
  218600. + fb_pix_fmt = IPU_PIX_FMT_RGB565;
  218601. +
  218602. + if (fb_pix_fmt) {
  218603. + pixfmt_to_var(fb_pix_fmt, &fbi->var);
  218604. + pdata->default_bpp =
  218605. + fbi->var.bits_per_pixel;
  218606. + }
  218607. + } else if (!strncmp(opt, "int_clk", 7)) {
  218608. + pdata->int_clk = true;
  218609. + continue;
  218610. + } else if (!strncmp(opt, "bpp=", 4)) {
  218611. + /* bpp setting cannot overwirte fbpix setting */
  218612. + if (fb_pix_fmt)
  218613. + continue;
  218614. +
  218615. + pdata->default_bpp =
  218616. + simple_strtoul(opt + 4, NULL, 0);
  218617. +
  218618. + fb_pix_fmt = bpp_to_pixfmt(pdata->default_bpp);
  218619. + if (fb_pix_fmt)
  218620. + pixfmt_to_var(fb_pix_fmt, &fbi->var);
  218621. + } else
  218622. + fb_mode_str = opt;
  218623. + }
  218624. +
  218625. + if (fb_mode_str)
  218626. + pdata->mode_str = fb_mode_str;
  218627. +
  218628. + return 0;
  218629. +}
  218630. +
  218631. +static int mxcfb_register(struct fb_info *fbi)
  218632. +{
  218633. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
  218634. + struct fb_videomode m;
  218635. + int ret = 0;
  218636. + char bg0_id[] = "DISP3 BG";
  218637. + char bg1_id[] = "DISP3 BG - DI1";
  218638. + char fg_id[] = "DISP3 FG";
  218639. +
  218640. + if (mxcfbi->ipu_di == 0) {
  218641. + bg0_id[4] += mxcfbi->ipu_id;
  218642. + strcpy(fbi->fix.id, bg0_id);
  218643. + } else if (mxcfbi->ipu_di == 1) {
  218644. + bg1_id[4] += mxcfbi->ipu_id;
  218645. + strcpy(fbi->fix.id, bg1_id);
  218646. + } else { /* Overlay */
  218647. + fg_id[4] += mxcfbi->ipu_id;
  218648. + strcpy(fbi->fix.id, fg_id);
  218649. + }
  218650. +
  218651. + mxcfb_check_var(&fbi->var, fbi);
  218652. +
  218653. + mxcfb_set_fix(fbi);
  218654. +
  218655. + /* Added first mode to fbi modelist. */
  218656. + if (!fbi->modelist.next || !fbi->modelist.prev)
  218657. + INIT_LIST_HEAD(&fbi->modelist);
  218658. + fb_var_to_videomode(&m, &fbi->var);
  218659. + fb_add_videomode(&m, &fbi->modelist);
  218660. +
  218661. + if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq,
  218662. + mxcfb_irq_handler, IPU_IRQF_ONESHOT, MXCFB_NAME, fbi) != 0) {
  218663. + dev_err(fbi->device, "Error registering EOF irq handler.\n");
  218664. + ret = -EBUSY;
  218665. + goto err0;
  218666. + }
  218667. + ipu_disable_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq);
  218668. + if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq,
  218669. + mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT, MXCFB_NAME, fbi) != 0) {
  218670. + dev_err(fbi->device, "Error registering NFACK irq handler.\n");
  218671. + ret = -EBUSY;
  218672. + goto err1;
  218673. + }
  218674. + ipu_disable_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq);
  218675. +
  218676. + if (mxcfbi->ipu_alp_ch_irq != -1)
  218677. + if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq,
  218678. + mxcfb_alpha_irq_handler, IPU_IRQF_ONESHOT,
  218679. + MXCFB_NAME, fbi) != 0) {
  218680. + dev_err(fbi->device, "Error registering alpha irq "
  218681. + "handler.\n");
  218682. + ret = -EBUSY;
  218683. + goto err2;
  218684. + }
  218685. +
  218686. + if (!mxcfbi->late_init) {
  218687. + fbi->var.activate |= FB_ACTIVATE_FORCE;
  218688. + console_lock();
  218689. + fbi->flags |= FBINFO_MISC_USEREVENT;
  218690. + ret = fb_set_var(fbi, &fbi->var);
  218691. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  218692. + console_unlock();
  218693. + if (ret < 0) {
  218694. + dev_err(fbi->device, "Error fb_set_var ret:%d\n", ret);
  218695. + goto err3;
  218696. + }
  218697. +
  218698. + if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
  218699. + console_lock();
  218700. + ret = fb_blank(fbi, FB_BLANK_UNBLANK);
  218701. + console_unlock();
  218702. + if (ret < 0) {
  218703. + dev_err(fbi->device,
  218704. + "Error fb_blank ret:%d\n", ret);
  218705. + goto err4;
  218706. + }
  218707. + }
  218708. + } else {
  218709. + /*
  218710. + * Setup the channel again though bootloader
  218711. + * has done this, then set_par() can stop the
  218712. + * channel neatly and re-initialize it .
  218713. + */
  218714. + if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
  218715. + console_lock();
  218716. + _setup_disp_channel1(fbi);
  218717. + ipu_enable_channel(mxcfbi->ipu, mxcfbi->ipu_ch);
  218718. + console_unlock();
  218719. + }
  218720. + }
  218721. +
  218722. +
  218723. + ret = register_framebuffer(fbi);
  218724. + if (ret < 0)
  218725. + goto err5;
  218726. +
  218727. + return ret;
  218728. +err5:
  218729. + if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
  218730. + console_lock();
  218731. + if (!mxcfbi->late_init)
  218732. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  218733. + else {
  218734. + ipu_disable_channel(mxcfbi->ipu, mxcfbi->ipu_ch,
  218735. + true);
  218736. + ipu_uninit_channel(mxcfbi->ipu, mxcfbi->ipu_ch);
  218737. + }
  218738. + console_unlock();
  218739. + }
  218740. +err4:
  218741. +err3:
  218742. + if (mxcfbi->ipu_alp_ch_irq != -1)
  218743. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq, fbi);
  218744. +err2:
  218745. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq, fbi);
  218746. +err1:
  218747. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq, fbi);
  218748. +err0:
  218749. + return ret;
  218750. +}
  218751. +
  218752. +static void mxcfb_unregister(struct fb_info *fbi)
  218753. +{
  218754. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
  218755. +
  218756. + if (mxcfbi->ipu_alp_ch_irq != -1)
  218757. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq, fbi);
  218758. + if (mxcfbi->ipu_ch_irq)
  218759. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq, fbi);
  218760. + if (mxcfbi->ipu_ch_nf_irq)
  218761. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq, fbi);
  218762. +
  218763. + unregister_framebuffer(fbi);
  218764. +}
  218765. +
  218766. +static int mxcfb_setup_overlay(struct platform_device *pdev,
  218767. + struct fb_info *fbi_bg, struct resource *res)
  218768. +{
  218769. + struct fb_info *ovfbi;
  218770. + struct mxcfb_info *mxcfbi_bg = (struct mxcfb_info *)fbi_bg->par;
  218771. + struct mxcfb_info *mxcfbi_fg;
  218772. + int ret = 0;
  218773. +
  218774. + ovfbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops);
  218775. + if (!ovfbi) {
  218776. + ret = -ENOMEM;
  218777. + goto init_ovfbinfo_failed;
  218778. + }
  218779. + mxcfbi_fg = (struct mxcfb_info *)ovfbi->par;
  218780. +
  218781. + mxcfbi_fg->ipu = ipu_get_soc(mxcfbi_bg->ipu_id);
  218782. + if (IS_ERR(mxcfbi_fg->ipu)) {
  218783. + ret = -ENODEV;
  218784. + goto get_ipu_failed;
  218785. + }
  218786. + mxcfbi_fg->ipu_id = mxcfbi_bg->ipu_id;
  218787. + mxcfbi_fg->ipu_ch_irq = IPU_IRQ_FG_SYNC_EOF;
  218788. + mxcfbi_fg->ipu_ch_nf_irq = IPU_IRQ_FG_SYNC_NFACK;
  218789. + mxcfbi_fg->ipu_alp_ch_irq = IPU_IRQ_FG_ALPHA_SYNC_EOF;
  218790. + mxcfbi_fg->ipu_ch = MEM_FG_SYNC;
  218791. + mxcfbi_fg->ipu_di = -1;
  218792. + mxcfbi_fg->ipu_di_pix_fmt = mxcfbi_bg->ipu_di_pix_fmt;
  218793. + mxcfbi_fg->overlay = true;
  218794. + mxcfbi_fg->cur_blank = mxcfbi_fg->next_blank = FB_BLANK_POWERDOWN;
  218795. +
  218796. + /* Need dummy values until real panel is configured */
  218797. + ovfbi->var.xres = 240;
  218798. + ovfbi->var.yres = 320;
  218799. +
  218800. + if (res && res->start && res->end) {
  218801. + ovfbi->fix.smem_len = res->end - res->start + 1;
  218802. + ovfbi->fix.smem_start = res->start;
  218803. + ovfbi->screen_base = ioremap(
  218804. + ovfbi->fix.smem_start,
  218805. + ovfbi->fix.smem_len);
  218806. + }
  218807. +
  218808. + ret = mxcfb_register(ovfbi);
  218809. + if (ret < 0)
  218810. + goto register_ov_failed;
  218811. +
  218812. + mxcfbi_bg->ovfbi = ovfbi;
  218813. +
  218814. + return ret;
  218815. +
  218816. +register_ov_failed:
  218817. +get_ipu_failed:
  218818. + fb_dealloc_cmap(&ovfbi->cmap);
  218819. + framebuffer_release(ovfbi);
  218820. +init_ovfbinfo_failed:
  218821. + return ret;
  218822. +}
  218823. +
  218824. +static void mxcfb_unsetup_overlay(struct fb_info *fbi_bg)
  218825. +{
  218826. + struct mxcfb_info *mxcfbi_bg = (struct mxcfb_info *)fbi_bg->par;
  218827. + struct fb_info *ovfbi = mxcfbi_bg->ovfbi;
  218828. +
  218829. + mxcfb_unregister(ovfbi);
  218830. +
  218831. + if (&ovfbi->cmap)
  218832. + fb_dealloc_cmap(&ovfbi->cmap);
  218833. + framebuffer_release(ovfbi);
  218834. +}
  218835. +
  218836. +static bool ipu_usage[2][2];
  218837. +static int ipu_test_set_usage(int ipu, int di)
  218838. +{
  218839. + if (ipu_usage[ipu][di])
  218840. + return -EBUSY;
  218841. + else
  218842. + ipu_usage[ipu][di] = true;
  218843. + return 0;
  218844. +}
  218845. +
  218846. +static void ipu_clear_usage(int ipu, int di)
  218847. +{
  218848. + ipu_usage[ipu][di] = false;
  218849. +}
  218850. +
  218851. +static int mxcfb_get_of_property(struct platform_device *pdev,
  218852. + struct ipuv3_fb_platform_data *plat_data)
  218853. +{
  218854. + struct device_node *np = pdev->dev.of_node;
  218855. + const char *disp_dev;
  218856. + const char *mode_str;
  218857. + const char *pixfmt;
  218858. + int err;
  218859. + int len;
  218860. + u32 bpp, int_clk;
  218861. + u32 late_init;
  218862. +
  218863. + err = of_property_read_string(np, "disp_dev", &disp_dev);
  218864. + if (err < 0) {
  218865. + dev_dbg(&pdev->dev, "get of property disp_dev fail\n");
  218866. + return err;
  218867. + }
  218868. + err = of_property_read_string(np, "mode_str", &mode_str);
  218869. + if (err < 0) {
  218870. + dev_dbg(&pdev->dev, "get of property mode_str fail\n");
  218871. + return err;
  218872. + }
  218873. + err = of_property_read_string(np, "interface_pix_fmt", &pixfmt);
  218874. + if (err) {
  218875. + dev_dbg(&pdev->dev, "get of property pix fmt fail\n");
  218876. + return err;
  218877. + }
  218878. + err = of_property_read_u32(np, "default_bpp", &bpp);
  218879. + if (err) {
  218880. + dev_dbg(&pdev->dev, "get of property bpp fail\n");
  218881. + return err;
  218882. + }
  218883. + err = of_property_read_u32(np, "int_clk", &int_clk);
  218884. + if (err) {
  218885. + dev_dbg(&pdev->dev, "get of property int_clk fail\n");
  218886. + return err;
  218887. + }
  218888. + err = of_property_read_u32(np, "late_init", &late_init);
  218889. + if (err) {
  218890. + dev_dbg(&pdev->dev, "get of property late_init fail\n");
  218891. + return err;
  218892. + }
  218893. +
  218894. + if (!strncmp(pixfmt, "RGB24", 5))
  218895. + plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB24;
  218896. + else if (!strncmp(pixfmt, "BGR24", 5))
  218897. + plat_data->interface_pix_fmt = IPU_PIX_FMT_BGR24;
  218898. + else if (!strncmp(pixfmt, "GBR24", 5))
  218899. + plat_data->interface_pix_fmt = IPU_PIX_FMT_GBR24;
  218900. + else if (!strncmp(pixfmt, "RGB565", 6))
  218901. + plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB565;
  218902. + else if (!strncmp(pixfmt, "RGB666", 6))
  218903. + plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB666;
  218904. + else if (!strncmp(pixfmt, "YUV444", 6))
  218905. + plat_data->interface_pix_fmt = IPU_PIX_FMT_YUV444;
  218906. + else if (!strncmp(pixfmt, "LVDS666", 7))
  218907. + plat_data->interface_pix_fmt = IPU_PIX_FMT_LVDS666;
  218908. + else if (!strncmp(pixfmt, "YUYV16", 6))
  218909. + plat_data->interface_pix_fmt = IPU_PIX_FMT_YUYV;
  218910. + else if (!strncmp(pixfmt, "UYVY16", 6))
  218911. + plat_data->interface_pix_fmt = IPU_PIX_FMT_UYVY;
  218912. + else if (!strncmp(pixfmt, "YVYU16", 6))
  218913. + plat_data->interface_pix_fmt = IPU_PIX_FMT_YVYU;
  218914. + else if (!strncmp(pixfmt, "VYUY16", 6))
  218915. + plat_data->interface_pix_fmt = IPU_PIX_FMT_VYUY;
  218916. + else {
  218917. + dev_err(&pdev->dev, "err interface_pix_fmt!\n");
  218918. + return -ENOENT;
  218919. + }
  218920. +
  218921. + len = min(sizeof(plat_data->disp_dev) - 1, strlen(disp_dev));
  218922. + memcpy(plat_data->disp_dev, disp_dev, len);
  218923. + plat_data->disp_dev[len] = '\0';
  218924. + plat_data->mode_str = (char *)mode_str;
  218925. + plat_data->default_bpp = bpp;
  218926. + plat_data->int_clk = (bool)int_clk;
  218927. + plat_data->late_init = (bool)late_init;
  218928. + return err;
  218929. +}
  218930. +
  218931. +/*!
  218932. + * Probe routine for the framebuffer driver. It is called during the
  218933. + * driver binding process. The following functions are performed in
  218934. + * this routine: Framebuffer initialization, Memory allocation and
  218935. + * mapping, Framebuffer registration, IPU initialization.
  218936. + *
  218937. + * @return Appropriate error code to the kernel common code
  218938. + */
  218939. +static int mxcfb_probe(struct platform_device *pdev)
  218940. +{
  218941. + struct ipuv3_fb_platform_data *plat_data;
  218942. + struct fb_info *fbi;
  218943. + struct mxcfb_info *mxcfbi;
  218944. + struct resource *res;
  218945. + int ret = 0;
  218946. +
  218947. + dev_dbg(&pdev->dev, "%s enter\n", __func__);
  218948. + pdev->id = of_alias_get_id(pdev->dev.of_node, "mxcfb");
  218949. + if (pdev->id < 0) {
  218950. + dev_err(&pdev->dev, "can not get alias id\n");
  218951. + return pdev->id;
  218952. + }
  218953. +
  218954. + plat_data = devm_kzalloc(&pdev->dev, sizeof(struct
  218955. + ipuv3_fb_platform_data), GFP_KERNEL);
  218956. + if (!plat_data)
  218957. + return -ENOMEM;
  218958. + pdev->dev.platform_data = plat_data;
  218959. +
  218960. + ret = mxcfb_get_of_property(pdev, plat_data);
  218961. + if (ret < 0) {
  218962. + dev_err(&pdev->dev, "get mxcfb of property fail\n");
  218963. + return ret;
  218964. + }
  218965. +
  218966. + /* Initialize FB structures */
  218967. + fbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops);
  218968. + if (!fbi) {
  218969. + ret = -ENOMEM;
  218970. + goto init_fbinfo_failed;
  218971. + }
  218972. +
  218973. + ret = mxcfb_option_setup(pdev, fbi);
  218974. + if (ret)
  218975. + goto get_fb_option_failed;
  218976. +
  218977. + mxcfbi = (struct mxcfb_info *)fbi->par;
  218978. + mxcfbi->ipu_int_clk = plat_data->int_clk;
  218979. + mxcfbi->late_init = plat_data->late_init;
  218980. + mxcfbi->first_set_par = true;
  218981. + ret = mxcfb_dispdrv_init(pdev, fbi);
  218982. + if (ret < 0)
  218983. + goto init_dispdrv_failed;
  218984. +
  218985. + ret = ipu_test_set_usage(mxcfbi->ipu_id, mxcfbi->ipu_di);
  218986. + if (ret < 0) {
  218987. + dev_err(&pdev->dev, "ipu%d-di%d already in use\n",
  218988. + mxcfbi->ipu_id, mxcfbi->ipu_di);
  218989. + goto ipu_in_busy;
  218990. + }
  218991. +
  218992. + if (mxcfbi->dispdrv->drv->post_init) {
  218993. + ret = mxcfbi->dispdrv->drv->post_init(mxcfbi->dispdrv,
  218994. + mxcfbi->ipu_id,
  218995. + mxcfbi->ipu_di);
  218996. + if (ret < 0) {
  218997. + dev_err(&pdev->dev, "post init failed\n");
  218998. + goto post_init_failed;
  218999. + }
  219000. + }
  219001. +
  219002. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  219003. + if (res && res->start && res->end) {
  219004. + fbi->fix.smem_len = res->end - res->start + 1;
  219005. + fbi->fix.smem_start = res->start;
  219006. + fbi->screen_base = ioremap(fbi->fix.smem_start, fbi->fix.smem_len);
  219007. + /* Do not clear the fb content drawn in bootloader. */
  219008. + if (!mxcfbi->late_init)
  219009. + memset(fbi->screen_base, 0, fbi->fix.smem_len);
  219010. + }
  219011. +
  219012. + mxcfbi->ipu = ipu_get_soc(mxcfbi->ipu_id);
  219013. + if (IS_ERR(mxcfbi->ipu)) {
  219014. + ret = -ENODEV;
  219015. + goto get_ipu_failed;
  219016. + }
  219017. +
  219018. + /* first user uses DP with alpha feature */
  219019. + if (!g_dp_in_use[mxcfbi->ipu_id]) {
  219020. + mxcfbi->ipu_ch_irq = IPU_IRQ_BG_SYNC_EOF;
  219021. + mxcfbi->ipu_ch_nf_irq = IPU_IRQ_BG_SYNC_NFACK;
  219022. + mxcfbi->ipu_alp_ch_irq = IPU_IRQ_BG_ALPHA_SYNC_EOF;
  219023. + mxcfbi->ipu_ch = MEM_BG_SYNC;
  219024. + /* Unblank the primary fb only by default */
  219025. + if (pdev->id == 0)
  219026. + mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_UNBLANK;
  219027. + else
  219028. + mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
  219029. +
  219030. + ret = mxcfb_register(fbi);
  219031. + if (ret < 0)
  219032. + goto mxcfb_register_failed;
  219033. +
  219034. + ipu_disp_set_global_alpha(mxcfbi->ipu, mxcfbi->ipu_ch,
  219035. + true, 0x80);
  219036. + ipu_disp_set_color_key(mxcfbi->ipu, mxcfbi->ipu_ch, false, 0);
  219037. +
  219038. + res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  219039. + ret = mxcfb_setup_overlay(pdev, fbi, res);
  219040. +
  219041. + if (ret < 0) {
  219042. + mxcfb_unregister(fbi);
  219043. + goto mxcfb_setupoverlay_failed;
  219044. + }
  219045. +
  219046. + g_dp_in_use[mxcfbi->ipu_id] = true;
  219047. +
  219048. + ret = device_create_file(mxcfbi->ovfbi->dev,
  219049. + &dev_attr_fsl_disp_property);
  219050. + if (ret)
  219051. + dev_err(mxcfbi->ovfbi->dev, "Error %d on creating "
  219052. + "file for disp property\n",
  219053. + ret);
  219054. +
  219055. + ret = device_create_file(mxcfbi->ovfbi->dev,
  219056. + &dev_attr_fsl_disp_dev_property);
  219057. + if (ret)
  219058. + dev_err(mxcfbi->ovfbi->dev, "Error %d on creating "
  219059. + "file for disp device "
  219060. + "propety\n", ret);
  219061. + } else {
  219062. + mxcfbi->ipu_ch_irq = IPU_IRQ_DC_SYNC_EOF;
  219063. + mxcfbi->ipu_ch_nf_irq = IPU_IRQ_DC_SYNC_NFACK;
  219064. + mxcfbi->ipu_alp_ch_irq = -1;
  219065. + mxcfbi->ipu_ch = MEM_DC_SYNC;
  219066. + mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
  219067. +
  219068. + ret = mxcfb_register(fbi);
  219069. + if (ret < 0)
  219070. + goto mxcfb_register_failed;
  219071. + }
  219072. +
  219073. + platform_set_drvdata(pdev, fbi);
  219074. +
  219075. + ret = device_create_file(fbi->dev, &dev_attr_fsl_disp_property);
  219076. + if (ret)
  219077. + dev_err(&pdev->dev, "Error %d on creating file for disp "
  219078. + "property\n", ret);
  219079. +
  219080. + ret = device_create_file(fbi->dev, &dev_attr_fsl_disp_dev_property);
  219081. + if (ret)
  219082. + dev_err(&pdev->dev, "Error %d on creating file for disp "
  219083. + " device propety\n", ret);
  219084. +
  219085. + return 0;
  219086. +
  219087. +mxcfb_setupoverlay_failed:
  219088. +mxcfb_register_failed:
  219089. +get_ipu_failed:
  219090. +post_init_failed:
  219091. + ipu_clear_usage(mxcfbi->ipu_id, mxcfbi->ipu_di);
  219092. +ipu_in_busy:
  219093. +init_dispdrv_failed:
  219094. + fb_dealloc_cmap(&fbi->cmap);
  219095. + framebuffer_release(fbi);
  219096. +get_fb_option_failed:
  219097. +init_fbinfo_failed:
  219098. + return ret;
  219099. +}
  219100. +
  219101. +static int mxcfb_remove(struct platform_device *pdev)
  219102. +{
  219103. + struct fb_info *fbi = platform_get_drvdata(pdev);
  219104. + struct mxcfb_info *mxc_fbi = fbi->par;
  219105. +
  219106. + if (!fbi)
  219107. + return 0;
  219108. +
  219109. + device_remove_file(fbi->dev, &dev_attr_fsl_disp_dev_property);
  219110. + device_remove_file(fbi->dev, &dev_attr_fsl_disp_property);
  219111. + mxcfb_blank(FB_BLANK_POWERDOWN, fbi);
  219112. + mxcfb_unregister(fbi);
  219113. + mxcfb_unmap_video_memory(fbi);
  219114. +
  219115. + if (mxc_fbi->ovfbi) {
  219116. + device_remove_file(mxc_fbi->ovfbi->dev,
  219117. + &dev_attr_fsl_disp_dev_property);
  219118. + device_remove_file(mxc_fbi->ovfbi->dev,
  219119. + &dev_attr_fsl_disp_property);
  219120. + mxcfb_blank(FB_BLANK_POWERDOWN, mxc_fbi->ovfbi);
  219121. + mxcfb_unsetup_overlay(fbi);
  219122. + mxcfb_unmap_video_memory(mxc_fbi->ovfbi);
  219123. + }
  219124. +
  219125. + ipu_clear_usage(mxc_fbi->ipu_id, mxc_fbi->ipu_di);
  219126. + if (&fbi->cmap)
  219127. + fb_dealloc_cmap(&fbi->cmap);
  219128. + framebuffer_release(fbi);
  219129. + return 0;
  219130. +}
  219131. +
  219132. +static const struct of_device_id imx_mxcfb_dt_ids[] = {
  219133. + { .compatible = "fsl,mxc_sdc_fb"},
  219134. + { /* sentinel */ }
  219135. +};
  219136. +
  219137. +/*!
  219138. + * This structure contains pointers to the power management callback functions.
  219139. + */
  219140. +static struct platform_driver mxcfb_driver = {
  219141. + .driver = {
  219142. + .name = MXCFB_NAME,
  219143. + .of_match_table = imx_mxcfb_dt_ids,
  219144. + },
  219145. + .probe = mxcfb_probe,
  219146. + .remove = mxcfb_remove,
  219147. + .suspend = mxcfb_suspend,
  219148. + .resume = mxcfb_resume,
  219149. +};
  219150. +
  219151. +/*!
  219152. + * Main entry function for the framebuffer. The function registers the power
  219153. + * management callback functions with the kernel and also registers the MXCFB
  219154. + * callback functions with the core Linux framebuffer driver \b fbmem.c
  219155. + *
  219156. + * @return Error code indicating success or failure
  219157. + */
  219158. +int __init mxcfb_init(void)
  219159. +{
  219160. + return platform_driver_register(&mxcfb_driver);
  219161. +}
  219162. +
  219163. +void mxcfb_exit(void)
  219164. +{
  219165. + platform_driver_unregister(&mxcfb_driver);
  219166. +}
  219167. +
  219168. +module_init(mxcfb_init);
  219169. +module_exit(mxcfb_exit);
  219170. +
  219171. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  219172. +MODULE_DESCRIPTION("MXC framebuffer driver");
  219173. +MODULE_LICENSE("GPL");
  219174. +MODULE_SUPPORTED_DEVICE("fb");
  219175. diff -Nur linux-3.14.14/drivers/video/mxc/mxc_lcdif.c linux-imx6-3.14/drivers/video/mxc/mxc_lcdif.c
  219176. --- linux-3.14.14/drivers/video/mxc/mxc_lcdif.c 1969-12-31 18:00:00.000000000 -0600
  219177. +++ linux-imx6-3.14/drivers/video/mxc/mxc_lcdif.c 2014-12-08 00:31:54.860418001 -0600
  219178. @@ -0,0 +1,235 @@
  219179. +/*
  219180. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  219181. + */
  219182. +
  219183. +/*
  219184. + * The code contained herein is licensed under the GNU General Public
  219185. + * License. You may obtain a copy of the GNU General Public License
  219186. + * Version 2 or later at the following locations:
  219187. + *
  219188. + * http://www.opensource.org/licenses/gpl-license.html
  219189. + * http://www.gnu.org/copyleft/gpl.html
  219190. + */
  219191. +
  219192. +#include <linux/init.h>
  219193. +#include <linux/ipu.h>
  219194. +#include <linux/kernel.h>
  219195. +#include <linux/module.h>
  219196. +#include <linux/mxcfb.h>
  219197. +#include <linux/of_device.h>
  219198. +#include <linux/pinctrl/consumer.h>
  219199. +#include <linux/platform_device.h>
  219200. +
  219201. +#include "mxc_dispdrv.h"
  219202. +
  219203. +struct mxc_lcd_platform_data {
  219204. + u32 default_ifmt;
  219205. + u32 ipu_id;
  219206. + u32 disp_id;
  219207. +};
  219208. +
  219209. +struct mxc_lcdif_data {
  219210. + struct platform_device *pdev;
  219211. + struct mxc_dispdrv_handle *disp_lcdif;
  219212. +};
  219213. +
  219214. +#define DISPDRV_LCD "lcd"
  219215. +
  219216. +static struct fb_videomode lcdif_modedb[] = {
  219217. + {
  219218. + /* 800x480 @ 57 Hz , pixel clk @ 27MHz */
  219219. + "CLAA-WVGA", 57, 800, 480, 37037, 40, 60, 10, 10, 20, 10,
  219220. + FB_SYNC_CLK_LAT_FALL,
  219221. + FB_VMODE_NONINTERLACED,
  219222. + 0,},
  219223. + {
  219224. + /* 800x480 @ 60 Hz , pixel clk @ 32MHz */
  219225. + "SEIKO-WVGA", 60, 800, 480, 29850, 89, 164, 23, 10, 10, 10,
  219226. + FB_SYNC_CLK_LAT_FALL,
  219227. + FB_VMODE_NONINTERLACED,
  219228. + 0,},
  219229. +};
  219230. +static int lcdif_modedb_sz = ARRAY_SIZE(lcdif_modedb);
  219231. +
  219232. +static int lcdif_init(struct mxc_dispdrv_handle *disp,
  219233. + struct mxc_dispdrv_setting *setting)
  219234. +{
  219235. + int ret, i;
  219236. + struct mxc_lcdif_data *lcdif = mxc_dispdrv_getdata(disp);
  219237. + struct mxc_lcd_platform_data *plat_data
  219238. + = lcdif->pdev->dev.platform_data;
  219239. + struct fb_videomode *modedb = lcdif_modedb;
  219240. + int modedb_sz = lcdif_modedb_sz;
  219241. +
  219242. + /* use platform defined ipu/di */
  219243. + setting->dev_id = plat_data->ipu_id;
  219244. + setting->disp_id = plat_data->disp_id;
  219245. +
  219246. + ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str,
  219247. + modedb, modedb_sz, NULL, setting->default_bpp);
  219248. + if (!ret) {
  219249. + fb_videomode_to_var(&setting->fbi->var, &modedb[0]);
  219250. + setting->if_fmt = plat_data->default_ifmt;
  219251. + }
  219252. +
  219253. + INIT_LIST_HEAD(&setting->fbi->modelist);
  219254. + for (i = 0; i < modedb_sz; i++) {
  219255. + struct fb_videomode m;
  219256. + fb_var_to_videomode(&m, &setting->fbi->var);
  219257. + if (fb_mode_is_equal(&m, &modedb[i])) {
  219258. + fb_add_videomode(&modedb[i],
  219259. + &setting->fbi->modelist);
  219260. + break;
  219261. + }
  219262. + }
  219263. +
  219264. + return ret;
  219265. +}
  219266. +
  219267. +void lcdif_deinit(struct mxc_dispdrv_handle *disp)
  219268. +{
  219269. + /*TODO*/
  219270. +}
  219271. +
  219272. +static struct mxc_dispdrv_driver lcdif_drv = {
  219273. + .name = DISPDRV_LCD,
  219274. + .init = lcdif_init,
  219275. + .deinit = lcdif_deinit,
  219276. +};
  219277. +
  219278. +static int lcd_get_of_property(struct platform_device *pdev,
  219279. + struct mxc_lcd_platform_data *plat_data)
  219280. +{
  219281. + struct device_node *np = pdev->dev.of_node;
  219282. + int err;
  219283. + u32 ipu_id, disp_id;
  219284. + const char *default_ifmt;
  219285. +
  219286. + err = of_property_read_string(np, "default_ifmt", &default_ifmt);
  219287. + if (err) {
  219288. + dev_dbg(&pdev->dev, "get of property default_ifmt fail\n");
  219289. + return err;
  219290. + }
  219291. + err = of_property_read_u32(np, "ipu_id", &ipu_id);
  219292. + if (err) {
  219293. + dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
  219294. + return err;
  219295. + }
  219296. + err = of_property_read_u32(np, "disp_id", &disp_id);
  219297. + if (err) {
  219298. + dev_dbg(&pdev->dev, "get of property disp_id fail\n");
  219299. + return err;
  219300. + }
  219301. +
  219302. + plat_data->ipu_id = ipu_id;
  219303. + plat_data->disp_id = disp_id;
  219304. + if (!strncmp(default_ifmt, "RGB24", 5))
  219305. + plat_data->default_ifmt = IPU_PIX_FMT_RGB24;
  219306. + else if (!strncmp(default_ifmt, "BGR24", 5))
  219307. + plat_data->default_ifmt = IPU_PIX_FMT_BGR24;
  219308. + else if (!strncmp(default_ifmt, "GBR24", 5))
  219309. + plat_data->default_ifmt = IPU_PIX_FMT_GBR24;
  219310. + else if (!strncmp(default_ifmt, "RGB565", 6))
  219311. + plat_data->default_ifmt = IPU_PIX_FMT_RGB565;
  219312. + else if (!strncmp(default_ifmt, "RGB666", 6))
  219313. + plat_data->default_ifmt = IPU_PIX_FMT_RGB666;
  219314. + else if (!strncmp(default_ifmt, "YUV444", 6))
  219315. + plat_data->default_ifmt = IPU_PIX_FMT_YUV444;
  219316. + else if (!strncmp(default_ifmt, "LVDS666", 7))
  219317. + plat_data->default_ifmt = IPU_PIX_FMT_LVDS666;
  219318. + else if (!strncmp(default_ifmt, "YUYV16", 6))
  219319. + plat_data->default_ifmt = IPU_PIX_FMT_YUYV;
  219320. + else if (!strncmp(default_ifmt, "UYVY16", 6))
  219321. + plat_data->default_ifmt = IPU_PIX_FMT_UYVY;
  219322. + else if (!strncmp(default_ifmt, "YVYU16", 6))
  219323. + plat_data->default_ifmt = IPU_PIX_FMT_YVYU;
  219324. + else if (!strncmp(default_ifmt, "VYUY16", 6))
  219325. + plat_data->default_ifmt = IPU_PIX_FMT_VYUY;
  219326. + else {
  219327. + dev_err(&pdev->dev, "err default_ifmt!\n");
  219328. + return -ENOENT;
  219329. + }
  219330. +
  219331. + return err;
  219332. +}
  219333. +
  219334. +static int mxc_lcdif_probe(struct platform_device *pdev)
  219335. +{
  219336. + int ret;
  219337. + struct pinctrl *pinctrl;
  219338. + struct mxc_lcdif_data *lcdif;
  219339. + struct mxc_lcd_platform_data *plat_data;
  219340. +
  219341. + dev_dbg(&pdev->dev, "%s enter\n", __func__);
  219342. + lcdif = devm_kzalloc(&pdev->dev, sizeof(struct mxc_lcdif_data),
  219343. + GFP_KERNEL);
  219344. + if (!lcdif)
  219345. + return -ENOMEM;
  219346. + plat_data = devm_kzalloc(&pdev->dev,
  219347. + sizeof(struct mxc_lcd_platform_data),
  219348. + GFP_KERNEL);
  219349. + if (!plat_data)
  219350. + return -ENOMEM;
  219351. + pdev->dev.platform_data = plat_data;
  219352. +
  219353. + ret = lcd_get_of_property(pdev, plat_data);
  219354. + if (ret < 0) {
  219355. + dev_err(&pdev->dev, "get lcd of property fail\n");
  219356. + return ret;
  219357. + }
  219358. +
  219359. + pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
  219360. + if (IS_ERR(pinctrl)) {
  219361. + dev_err(&pdev->dev, "can't get/select pinctrl\n");
  219362. + return PTR_ERR(pinctrl);
  219363. + }
  219364. +
  219365. + lcdif->pdev = pdev;
  219366. + lcdif->disp_lcdif = mxc_dispdrv_register(&lcdif_drv);
  219367. + mxc_dispdrv_setdata(lcdif->disp_lcdif, lcdif);
  219368. +
  219369. + dev_set_drvdata(&pdev->dev, lcdif);
  219370. + dev_dbg(&pdev->dev, "%s exit\n", __func__);
  219371. +
  219372. + return ret;
  219373. +}
  219374. +
  219375. +static int mxc_lcdif_remove(struct platform_device *pdev)
  219376. +{
  219377. + struct mxc_lcdif_data *lcdif = dev_get_drvdata(&pdev->dev);
  219378. +
  219379. + mxc_dispdrv_puthandle(lcdif->disp_lcdif);
  219380. + mxc_dispdrv_unregister(lcdif->disp_lcdif);
  219381. + kfree(lcdif);
  219382. + return 0;
  219383. +}
  219384. +
  219385. +static const struct of_device_id imx_lcd_dt_ids[] = {
  219386. + { .compatible = "fsl,lcd"},
  219387. + { /* sentinel */ }
  219388. +};
  219389. +static struct platform_driver mxc_lcdif_driver = {
  219390. + .driver = {
  219391. + .name = "mxc_lcdif",
  219392. + .of_match_table = imx_lcd_dt_ids,
  219393. + },
  219394. + .probe = mxc_lcdif_probe,
  219395. + .remove = mxc_lcdif_remove,
  219396. +};
  219397. +
  219398. +static int __init mxc_lcdif_init(void)
  219399. +{
  219400. + return platform_driver_register(&mxc_lcdif_driver);
  219401. +}
  219402. +
  219403. +static void __exit mxc_lcdif_exit(void)
  219404. +{
  219405. + platform_driver_unregister(&mxc_lcdif_driver);
  219406. +}
  219407. +
  219408. +module_init(mxc_lcdif_init);
  219409. +module_exit(mxc_lcdif_exit);
  219410. +
  219411. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  219412. +MODULE_DESCRIPTION("i.MX ipuv3 LCD extern port driver");
  219413. +MODULE_LICENSE("GPL");
  219414. diff -Nur linux-3.14.14/drivers/video/mxsfb.c linux-imx6-3.14/drivers/video/mxsfb.c
  219415. --- linux-3.14.14/drivers/video/mxsfb.c 2014-07-28 10:07:25.000000000 -0500
  219416. +++ linux-imx6-3.14/drivers/video/mxsfb.c 2014-12-08 00:31:54.860418001 -0600
  219417. @@ -96,9 +96,10 @@
  219418. #define CTRL_DF24 (1 << 1)
  219419. #define CTRL_RUN (1 << 0)
  219420. -#define CTRL1_FIFO_CLEAR (1 << 21)
  219421. -#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
  219422. -#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
  219423. +#define CTRL1_RECOVERY_ON_UNDERFLOW (1 << 24)
  219424. +#define CTRL1_FIFO_CLEAR (1 << 21)
  219425. +#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
  219426. +#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
  219427. #define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16)
  219428. #define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff)
  219429. @@ -149,8 +150,8 @@
  219430. #define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
  219431. #define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
  219432. -#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
  219433. -#define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negtive edge sampling */
  219434. +#define FB_SYNC_OE_LOW_ACT 0x80000000
  219435. +#define FB_SYNC_CLK_LAT_FALL 0x40000000
  219436. enum mxsfb_devtype {
  219437. MXSFB_V3,
  219438. @@ -178,7 +179,6 @@
  219439. unsigned ld_intf_width;
  219440. unsigned dotclk_delay;
  219441. const struct mxsfb_devdata *devdata;
  219442. - u32 sync;
  219443. struct regulator *reg_lcd;
  219444. };
  219445. @@ -275,9 +275,15 @@
  219446. if (var->yres < MIN_YRES)
  219447. var->yres = MIN_YRES;
  219448. - var->xres_virtual = var->xres;
  219449. + if (var->xres_virtual > var->xres) {
  219450. + dev_dbg(fb_info->device, "stride not supported\n");
  219451. + return -EINVAL;
  219452. + }
  219453. - var->yres_virtual = var->yres;
  219454. + if (var->xres_virtual < var->xres)
  219455. + var->xres_virtual = var->xres;
  219456. + if (var->yres_virtual < var->yres)
  219457. + var->yres_virtual = var->yres;
  219458. switch (var->bits_per_pixel) {
  219459. case 16:
  219460. @@ -344,6 +350,9 @@
  219461. writel(CTRL_RUN, host->base + LCDC_CTRL + REG_SET);
  219462. + /* Recovery on underflow */
  219463. + writel(CTRL1_RECOVERY_ON_UNDERFLOW, host->base + LCDC_CTRL1 + REG_SET);
  219464. +
  219465. host->enabled = 1;
  219466. }
  219467. @@ -392,14 +401,6 @@
  219468. int line_size, fb_size;
  219469. int reenable = 0;
  219470. - line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
  219471. - fb_size = fb_info->var.yres_virtual * line_size;
  219472. -
  219473. - if (fb_size > fb_info->fix.smem_len)
  219474. - return -ENOMEM;
  219475. -
  219476. - fb_info->fix.line_length = line_size;
  219477. -
  219478. /*
  219479. * It seems, you can't re-program the controller if it is still running.
  219480. * This may lead into shifted pictures (FIFO issue?).
  219481. @@ -413,6 +414,19 @@
  219482. /* clear the FIFOs */
  219483. writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET);
  219484. + line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
  219485. + fb_info->fix.line_length = line_size;
  219486. + fb_size = fb_info->var.yres_virtual * line_size;
  219487. +
  219488. + /* Reallocate memory */
  219489. + if (!fb_info->fix.smem_start || (fb_size > fb_info->fix.smem_len)) {
  219490. + if (fb_info->fix.smem_start)
  219491. + mxsfb_unmap_videomem(fb_info);
  219492. +
  219493. + if (mxsfb_map_videomem(fb_info) < 0)
  219494. + return -ENOMEM;
  219495. + }
  219496. +
  219497. ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER |
  219498. CTRL_SET_BUS_WIDTH(host->ld_intf_width);
  219499. @@ -459,9 +473,9 @@
  219500. vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
  219501. if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT)
  219502. vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
  219503. - if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT)
  219504. + if (!(fb_info->var.sync & FB_SYNC_OE_LOW_ACT))
  219505. vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
  219506. - if (host->sync & MXSFB_SYNC_DOTCLK_FALLING_ACT)
  219507. + if (fb_info->var.sync & FB_SYNC_CLK_LAT_FALL)
  219508. vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING;
  219509. writel(vdctrl0, host->base + LCDC_VDCTRL0);
  219510. @@ -578,6 +592,34 @@
  219511. return 0;
  219512. }
  219513. +static int mxsfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
  219514. +{
  219515. + u32 len;
  219516. + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  219517. +
  219518. + if (offset < info->fix.smem_len) {
  219519. + /* mapping framebuffer memory */
  219520. + len = info->fix.smem_len - offset;
  219521. + vma->vm_pgoff = (info->fix.smem_start + offset) >> PAGE_SHIFT;
  219522. + } else
  219523. + return -EINVAL;
  219524. +
  219525. + len = PAGE_ALIGN(len);
  219526. + if (vma->vm_end - vma->vm_start > len)
  219527. + return -EINVAL;
  219528. +
  219529. + /* make buffers bufferable */
  219530. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  219531. +
  219532. + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  219533. + vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
  219534. + dev_dbg(info->device, "mmap remap_pfn_range failed\n");
  219535. + return -ENOBUFS;
  219536. + }
  219537. +
  219538. + return 0;
  219539. +}
  219540. +
  219541. static struct fb_ops mxsfb_ops = {
  219542. .owner = THIS_MODULE,
  219543. .fb_check_var = mxsfb_check_var,
  219544. @@ -585,6 +627,7 @@
  219545. .fb_setcolreg = mxsfb_setcolreg,
  219546. .fb_blank = mxsfb_blank,
  219547. .fb_pan_display = mxsfb_pan_display,
  219548. + .fb_mmap = mxsfb_mmap,
  219549. .fb_fillrect = cfb_fillrect,
  219550. .fb_copyarea = cfb_copyarea,
  219551. .fb_imageblit = cfb_imageblit,
  219552. @@ -800,7 +843,62 @@
  219553. {
  219554. struct fb_info *fb_info = &host->fb_info;
  219555. - free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len);
  219556. + mxsfb_unmap_videomem(fb_info);
  219557. +}
  219558. +
  219559. +/*!
  219560. + * Allocates the DRAM memory for the frame buffer. This buffer is remapped
  219561. + * into a non-cached, non-buffered, memory region to allow palette and pixel
  219562. + * writes to occur without flushing the cache. Once this area is remapped,
  219563. + * all virtual memory access to the video memory should occur at the new region.
  219564. + *
  219565. + * @param fbi framebuffer information pointer
  219566. + *
  219567. + * @return Error code indicating success or failure
  219568. + */
  219569. +static int mxsfb_map_videomem(struct fb_info *fbi)
  219570. +{
  219571. + if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length)
  219572. + fbi->fix.smem_len = fbi->var.yres_virtual *
  219573. + fbi->fix.line_length;
  219574. +
  219575. + fbi->screen_base = dma_alloc_writecombine(fbi->device,
  219576. + fbi->fix.smem_len,
  219577. + (dma_addr_t *)&fbi->fix.smem_start,
  219578. + GFP_DMA | GFP_KERNEL);
  219579. + if (fbi->screen_base == 0) {
  219580. + dev_err(fbi->device, "Unable to allocate framebuffer memory\n");
  219581. + fbi->fix.smem_len = 0;
  219582. + fbi->fix.smem_start = 0;
  219583. + return -EBUSY;
  219584. + }
  219585. +
  219586. + dev_dbg(fbi->device, "allocated fb @ paddr=0x%08X, size=%d.\n",
  219587. + (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
  219588. +
  219589. + fbi->screen_size = fbi->fix.smem_len;
  219590. +
  219591. + /* Clear the screen */
  219592. + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
  219593. +
  219594. + return 0;
  219595. +}
  219596. +
  219597. +/*!
  219598. + * De-allocates the DRAM memory for the frame buffer.
  219599. + *
  219600. + * @param fbi framebuffer information pointer
  219601. + *
  219602. + * @return Error code indicating success or failure
  219603. + */
  219604. +static int mxsfb_unmap_videomem(struct fb_info *fbi)
  219605. +{
  219606. + dma_free_writecombine(fbi->device, fbi->fix.smem_len,
  219607. + fbi->screen_base, fbi->fix.smem_start);
  219608. + fbi->screen_base = 0;
  219609. + fbi->fix.smem_start = 0;
  219610. + fbi->fix.smem_len = 0;
  219611. + return 0;
  219612. }
  219613. static struct platform_device_id mxsfb_devtype[] = {
  219614. diff -Nur linux-3.14.14/drivers/video/vexpress-dvi.c linux-imx6-3.14/drivers/video/vexpress-dvi.c
  219615. --- linux-3.14.14/drivers/video/vexpress-dvi.c 1969-12-31 18:00:00.000000000 -0600
  219616. +++ linux-imx6-3.14/drivers/video/vexpress-dvi.c 2014-12-08 00:31:54.892418001 -0600
  219617. @@ -0,0 +1,220 @@
  219618. +/*
  219619. + * This program is free software; you can redistribute it and/or modify
  219620. + * it under the terms of the GNU General Public License version 2 as
  219621. + * published by the Free Software Foundation.
  219622. + *
  219623. + * This program is distributed in the hope that it will be useful,
  219624. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  219625. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  219626. + * GNU General Public License for more details.
  219627. + *
  219628. + * Copyright (C) 2012 ARM Limited
  219629. + */
  219630. +
  219631. +#define pr_fmt(fmt) "vexpress-dvi: " fmt
  219632. +
  219633. +#include <linux/fb.h>
  219634. +#include <linux/of.h>
  219635. +#include <linux/of_device.h>
  219636. +#include <linux/vexpress.h>
  219637. +
  219638. +
  219639. +static struct vexpress_config_func *vexpress_dvimode_func;
  219640. +
  219641. +static struct {
  219642. + u32 xres, yres, mode;
  219643. +} vexpress_dvi_dvimodes[] = {
  219644. + { 640, 480, 0 }, /* VGA */
  219645. + { 800, 600, 1 }, /* SVGA */
  219646. + { 1024, 768, 2 }, /* XGA */
  219647. + { 1280, 1024, 3 }, /* SXGA */
  219648. + { 1600, 1200, 4 }, /* UXGA */
  219649. + { 1920, 1080, 5 }, /* HD1080 */
  219650. +};
  219651. +
  219652. +static void vexpress_dvi_mode_set(struct fb_info *info, u32 xres, u32 yres)
  219653. +{
  219654. + int err = -ENOENT;
  219655. + int i;
  219656. +
  219657. + if (!vexpress_dvimode_func)
  219658. + return;
  219659. +
  219660. + for (i = 0; i < ARRAY_SIZE(vexpress_dvi_dvimodes); i++) {
  219661. + if (vexpress_dvi_dvimodes[i].xres == xres &&
  219662. + vexpress_dvi_dvimodes[i].yres == yres) {
  219663. + pr_debug("mode: %ux%u = %d\n", xres, yres,
  219664. + vexpress_dvi_dvimodes[i].mode);
  219665. + err = vexpress_config_write(vexpress_dvimode_func, 0,
  219666. + vexpress_dvi_dvimodes[i].mode);
  219667. + break;
  219668. + }
  219669. + }
  219670. +
  219671. + if (err)
  219672. + pr_warn("Failed to set %ux%u mode! (%d)\n", xres, yres, err);
  219673. +}
  219674. +
  219675. +
  219676. +static struct vexpress_config_func *vexpress_muxfpga_func;
  219677. +static int vexpress_dvi_fb = -1;
  219678. +
  219679. +static int vexpress_dvi_mux_set(struct fb_info *info)
  219680. +{
  219681. + int err;
  219682. + u32 site = vexpress_get_site_by_dev(info->device);
  219683. +
  219684. + if (!vexpress_muxfpga_func)
  219685. + return -ENXIO;
  219686. +
  219687. + err = vexpress_config_write(vexpress_muxfpga_func, 0, site);
  219688. + if (!err) {
  219689. + pr_debug("Selected MUXFPGA input %d (fb%d)\n", site,
  219690. + info->node);
  219691. + vexpress_dvi_fb = info->node;
  219692. + vexpress_dvi_mode_set(info, info->var.xres,
  219693. + info->var.yres);
  219694. + } else {
  219695. + pr_warn("Failed to select MUXFPGA input %d (fb%d)! (%d)\n",
  219696. + site, info->node, err);
  219697. + }
  219698. +
  219699. + return err;
  219700. +}
  219701. +
  219702. +static int vexpress_dvi_fb_select(int fb)
  219703. +{
  219704. + int err;
  219705. + struct fb_info *info;
  219706. +
  219707. + /* fb0 is the default */
  219708. + if (fb < 0)
  219709. + fb = 0;
  219710. +
  219711. + info = registered_fb[fb];
  219712. + if (!info || !lock_fb_info(info))
  219713. + return -ENODEV;
  219714. +
  219715. + err = vexpress_dvi_mux_set(info);
  219716. +
  219717. + unlock_fb_info(info);
  219718. +
  219719. + return err;
  219720. +}
  219721. +
  219722. +static ssize_t vexpress_dvi_fb_show(struct device *dev,
  219723. + struct device_attribute *attr, char *buf)
  219724. +{
  219725. + return sprintf(buf, "%d\n", vexpress_dvi_fb);
  219726. +}
  219727. +
  219728. +static ssize_t vexpress_dvi_fb_store(struct device *dev,
  219729. + struct device_attribute *attr, const char *buf, size_t count)
  219730. +{
  219731. + long value;
  219732. + int err = kstrtol(buf, 0, &value);
  219733. +
  219734. + if (!err)
  219735. + err = vexpress_dvi_fb_select(value);
  219736. +
  219737. + return err ? err : count;
  219738. +}
  219739. +
  219740. +DEVICE_ATTR(fb, S_IRUGO | S_IWUSR, vexpress_dvi_fb_show,
  219741. + vexpress_dvi_fb_store);
  219742. +
  219743. +
  219744. +static int vexpress_dvi_fb_event_notify(struct notifier_block *self,
  219745. + unsigned long action, void *data)
  219746. +{
  219747. + struct fb_event *event = data;
  219748. + struct fb_info *info = event->info;
  219749. + struct fb_videomode *mode = event->data;
  219750. +
  219751. + switch (action) {
  219752. + case FB_EVENT_FB_REGISTERED:
  219753. + if (vexpress_dvi_fb < 0)
  219754. + vexpress_dvi_mux_set(info);
  219755. + break;
  219756. + case FB_EVENT_MODE_CHANGE:
  219757. + case FB_EVENT_MODE_CHANGE_ALL:
  219758. + if (info->node == vexpress_dvi_fb)
  219759. + vexpress_dvi_mode_set(info, mode->xres, mode->yres);
  219760. + break;
  219761. + }
  219762. +
  219763. + return NOTIFY_OK;
  219764. +}
  219765. +
  219766. +static struct notifier_block vexpress_dvi_fb_notifier = {
  219767. + .notifier_call = vexpress_dvi_fb_event_notify,
  219768. +};
  219769. +static bool vexpress_dvi_fb_notifier_registered;
  219770. +
  219771. +
  219772. +enum vexpress_dvi_func { FUNC_MUXFPGA, FUNC_DVIMODE };
  219773. +
  219774. +static struct of_device_id vexpress_dvi_of_match[] = {
  219775. + {
  219776. + .compatible = "arm,vexpress-muxfpga",
  219777. + .data = (void *)FUNC_MUXFPGA,
  219778. + }, {
  219779. + .compatible = "arm,vexpress-dvimode",
  219780. + .data = (void *)FUNC_DVIMODE,
  219781. + },
  219782. + {}
  219783. +};
  219784. +
  219785. +static int vexpress_dvi_probe(struct platform_device *pdev)
  219786. +{
  219787. + enum vexpress_dvi_func func;
  219788. + const struct of_device_id *match =
  219789. + of_match_device(vexpress_dvi_of_match, &pdev->dev);
  219790. +
  219791. + if (match)
  219792. + func = (enum vexpress_dvi_func)match->data;
  219793. + else
  219794. + func = pdev->id_entry->driver_data;
  219795. +
  219796. + switch (func) {
  219797. + case FUNC_MUXFPGA:
  219798. + vexpress_muxfpga_func =
  219799. + vexpress_config_func_get_by_dev(&pdev->dev);
  219800. + device_create_file(&pdev->dev, &dev_attr_fb);
  219801. + break;
  219802. + case FUNC_DVIMODE:
  219803. + vexpress_dvimode_func =
  219804. + vexpress_config_func_get_by_dev(&pdev->dev);
  219805. + break;
  219806. + }
  219807. +
  219808. + if (!vexpress_dvi_fb_notifier_registered) {
  219809. + fb_register_client(&vexpress_dvi_fb_notifier);
  219810. + vexpress_dvi_fb_notifier_registered = true;
  219811. + }
  219812. +
  219813. + vexpress_dvi_fb_select(vexpress_dvi_fb);
  219814. +
  219815. + return 0;
  219816. +}
  219817. +
  219818. +static const struct platform_device_id vexpress_dvi_id_table[] = {
  219819. + { .name = "vexpress-muxfpga", .driver_data = FUNC_MUXFPGA, },
  219820. + { .name = "vexpress-dvimode", .driver_data = FUNC_DVIMODE, },
  219821. + {}
  219822. +};
  219823. +
  219824. +static struct platform_driver vexpress_dvi_driver = {
  219825. + .probe = vexpress_dvi_probe,
  219826. + .driver = {
  219827. + .name = "vexpress-dvi",
  219828. + .of_match_table = vexpress_dvi_of_match,
  219829. + },
  219830. + .id_table = vexpress_dvi_id_table,
  219831. +};
  219832. +
  219833. +static int __init vexpress_dvi_init(void)
  219834. +{
  219835. + return platform_driver_register(&vexpress_dvi_driver);
  219836. +}
  219837. +device_initcall(vexpress_dvi_init);
  219838. diff -Nur linux-3.14.14/firmware/imx/sdma/sdma-imx6q.bin.ihex linux-imx6-3.14/firmware/imx/sdma/sdma-imx6q.bin.ihex
  219839. --- linux-3.14.14/firmware/imx/sdma/sdma-imx6q.bin.ihex 1969-12-31 18:00:00.000000000 -0600
  219840. +++ linux-imx6-3.14/firmware/imx/sdma/sdma-imx6q.bin.ihex 2014-12-08 00:31:54.948418001 -0600
  219841. @@ -0,0 +1,116 @@
  219842. +:1000000053444D4101000000010000001C000000AD
  219843. +:1000100026000000B40000007A0600008202000002
  219844. +:10002000FFFFFFFF00000000FFFFFFFFFFFFFFFFDC
  219845. +:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
  219846. +:10004000FFFFFFFFFFFFFFFF6A1A0000FFFFFFFF38
  219847. +:10005000EB020000BB180000FFFFFFFF08040000D8
  219848. +:10006000FFFFFFFFC0030000FFFFFFFFFFFFFFFFD9
  219849. +:10007000FFFFFFFFAB020000FFFFFFFF7B0300005D
  219850. +:10008000FFFFFFFFFFFFFFFF4C0400006E040000B6
  219851. +:10009000FFFFFFFF00180000FFFFFFFFFFFFFFFF54
  219852. +:1000A000000000000018000062180000161A00008E
  219853. +:1000B000061B0000E3C1DB57E35FE357F352016A1D
  219854. +:1000C0008F00D500017D8D00A005EB5D7804037DD8
  219855. +:1000D00079042C7D367C79041F7CEE56000F600677
  219856. +:1000E000057D0965437E0A62417E20980A623E7E54
  219857. +:1000F00009653C7E12051205AD026007037DFB55C4
  219858. +:10010000D36D2B98FB55041DD36DC86A2F7F011F3B
  219859. +:1001100003200048E47C5398FB55D76D1500057803
  219860. +:100120000962C86A0962C86AD76D5298FB55D76DD3
  219861. +:100130001500150005780A62C86A0A62C86AD76D98
  219862. +:100140005298FB55D76D15001500150005780B6208
  219863. +:10015000C86A0B62C86AD76D097CDF6D077F000033
  219864. +:10016000EB55004D077DFAC1E35706980700CC68B0
  219865. +:100170000C6813C20AC20398D9C1E3C1DB57E35F1D
  219866. +:10018000E357F352216A8F00D500017D8D00A00551
  219867. +:10019000EB5DFB567804037D79042A7D317C79047C
  219868. +:1001A000207C700B1103EB53000F6003057D096584
  219869. +:1001B000377E0A62357E86980A62327E0965307E15
  219870. +:1001C00012051205AD026007027C065A8E98265A67
  219871. +:1001D000277F011F03200048E87C700B1103135395
  219872. +:1001E000AF98150004780962065A0962265AAE983B
  219873. +:1001F0001500150004780A62065A0A62265AAE985B
  219874. +:1002000015001500150004780B62065A0B62265A79
  219875. +:10021000077C0000EB55004D067DFAC1E357699855
  219876. +:1002200007000C6813C20AC26698700B11031353BF
  219877. +:100230006C07017CD9C1FB5E8A066B07017CD9C1C2
  219878. +:10024000F35EDB59D3588F0110010F398B003CC18D
  219879. +:100250002B7DC05AC85B4EC1277C88038906E35CAE
  219880. +:10026000FF0D1105FF1DBC053E07004D187D7008F0
  219881. +:1002700011007E07097D7D07027D2852E698F8521D
  219882. +:10028000DB54BC02CC02097C7C07027D2852EF982B
  219883. +:10029000F852D354BC02CC02097D0004DD988B00D7
  219884. +:1002A000C052C85359C1D67D0002CD98FF08BF0087
  219885. +:1002B0007F07157D8804D500017D8D00A005EB5DCD
  219886. +:1002C0008F0212021202FF3ADA05027C3E071899E9
  219887. +:1002D000A402DD02027D3E0718995E071899EB55CE
  219888. +:1002E0009805EB5DF352FB546A07267D6C07017D90
  219889. +:1002F00055996B07577C6907047D6807027D010EDD
  219890. +:100300002F999358D600017D8E009355A005935DDB
  219891. +:10031000A00602780255045D1D7C004E087C69072A
  219892. +:10032000037D0255177E3C99045D147F8906935026
  219893. +:100330000048017D2799A099150006780255045DB3
  219894. +:100340004F070255245D2F07017CA09917006F0706
  219895. +:10035000017C012093559D000700A7D9F598D36C27
  219896. +:100360006907047D6807027D010E64999358D600E1
  219897. +:10037000017D8E009355A005935DA006027802557D
  219898. +:10038000C86D0F7C004E087C6907037D0255097E0D
  219899. +:100390007199C86D067F890693500048017D5C996C
  219900. +:1003A000A0999A99C36A6907047D6807027D010EC6
  219901. +:1003B00087999358D600017D8E009355A005935DD3
  219902. +:1003C000A0060278C865045D0F7C004E087C6907B2
  219903. +:1003D000037DC865097E9499045D067F8906935064
  219904. +:1003E0000048017D7F99A09993559D000700FF6CFF
  219905. +:1003F000A7D9F5980000E354EB55004D017CF59822
  219906. +:10040000DD98E354EB55FF0A1102FF1A7F07027CC7
  219907. +:10041000A005B4999D008C05BA05A0051002BA0488
  219908. +:10042000AD0454040600E3C1DB57FB52C36AF35228
  219909. +:10043000056A8F00D500017D8D00A005EB5D780475
  219910. +:10044000037D79042B7D1E7C7904337CEE56000FEE
  219911. +:10045000FB556007027DC36DD599041DC36DC8624D
  219912. +:100460003B7E6006027D10021202096A357F12028D
  219913. +:10047000096A327F1202096A2F7F011F0320004898
  219914. +:10048000E77C099AFB55C76D150015001500057826
  219915. +:10049000C8620B6AC8620B6AC76D089AFB55C76DC4
  219916. +:1004A000150015000578C8620A6AC8620A6AC76D35
  219917. +:1004B000089AFB55C76D15000578C862096AC862BD
  219918. +:1004C000096AC76D097C286A077F0000EB55004D5B
  219919. +:1004D000057DFAC1DB57BF9977C254040AC2BA99A5
  219920. +:1004E000D9C1E3C1DB57F352056A8F00D500017D06
  219921. +:1004F0008D00A005FB567804037D7904297D1F7CBF
  219922. +:1005000079042E7CE35D700D1105ED55000F600739
  219923. +:10051000027D0652329A2652337E6005027D100219
  219924. +:100520001202096A2D7F1202096A2A7F1202096AE1
  219925. +:10053000277F011F03200048EA7CE3555D9A1500E0
  219926. +:1005400015001500047806520B6A26520B6A5C9A55
  219927. +:1005500015001500047806520A6A26520A6A5C9A47
  219928. +:10056000150004780652096A2652096A097C286A2D
  219929. +:10057000077F0000DB57004D057DFAC1DB571B9A52
  219930. +:1005800077C254040AC2189AE3C1DB57F352056AD2
  219931. +:10059000FB568E02941AC36AC8626902247D941EB7
  219932. +:1005A000C36ED36EC8624802C86A9426981EC36E92
  219933. +:1005B000D36EC8624C02C86A9826C36E981EC36E7A
  219934. +:1005C000C8629826C36E6002097CC8626E02247DF0
  219935. +:1005D000096A1E7F0125004D257D849A286A187FAF
  219936. +:1005E00004627AC2B89AE36E8F00D805017D8D004F
  219937. +:1005F000A005C8626E02107D096A0A7F0120F97C9D
  219938. +:10060000286A067F0000004D0D7DFAC1DB576E9A07
  219939. +:10061000070004620C6AB59A286AFA7F04627AC2FB
  219940. +:1006200058045404286AF47F0AC26B9AD9C1E3C102
  219941. +:10063000DB57F352056AFB568E02941A0252690286
  219942. +:100640001D7D941E06524802065A9426981E065294
  219943. +:100650004C02065A9826981E065260020A7C98267A
  219944. +:1006600006526E02237D096A1D7F0125004D247DFF
  219945. +:10067000D19A286A177F04627AC2029B8F00D8053C
  219946. +:10068000017D8D00A00506526E02107D096A0A7F69
  219947. +:100690000120F97C286A067F0000004D0D7DFAC11B
  219948. +:1006A000DB57C19A070004620C6AFF9A286AFA7F36
  219949. +:1006B00004627AC258045404286AF47F0AC2BE9ABB
  219950. +:1006C000016E0B612F7E0B622D7E0B632B7E0C0D5A
  219951. +:1006D0001704170417049D04081DCC05017C0C0D9C
  219952. +:1006E000D16A000F4207C86FDD6F1C7F8E009D002E
  219953. +:1006F00001680B67177ED56B04080278C86F120774
  219954. +:10070000117C0B670F7E04080278C86F12070A7C01
  219955. +:10071000DD6F087FD169010FC86FDD6F037F0101B5
  219956. +:0E0720000004129B0700FF680C680002129B89
  219957. +:00000001FF
  219958. diff -Nur linux-3.14.14/firmware/Makefile linux-imx6-3.14/firmware/Makefile
  219959. --- linux-3.14.14/firmware/Makefile 2014-07-28 10:07:25.000000000 -0500
  219960. +++ linux-imx6-3.14/firmware/Makefile 2014-12-08 00:31:54.924418001 -0600
  219961. @@ -61,6 +61,7 @@
  219962. radeon/RV770_pfp.bin radeon/RV770_me.bin \
  219963. radeon/RV730_pfp.bin radeon/RV730_me.bin \
  219964. radeon/RV710_pfp.bin radeon/RV710_me.bin
  219965. +fw-shipped-$(CONFIG_IMX_SDMA) += imx/sdma/sdma-imx6q.bin
  219966. fw-shipped-$(CONFIG_DVB_AV7110) += av7110/bootcode.bin
  219967. fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
  219968. fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
  219969. @@ -210,6 +211,8 @@
  219970. $(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %)
  219971. $(call cmd,ihex)
  219972. +.NOTPARALLEL: $(obj)/%
  219973. +
  219974. # Don't depend on ihex2fw if we're installing and it already exists.
  219975. # Putting it after | in the dependencies doesn't seem sufficient when
  219976. # we're installing after a cross-compile, because ihex2fw has dependencies
  219977. diff -Nur linux-3.14.14/fs/btrfs/Kconfig linux-imx6-3.14/fs/btrfs/Kconfig
  219978. --- linux-3.14.14/fs/btrfs/Kconfig 2014-07-28 10:07:25.000000000 -0500
  219979. +++ linux-imx6-3.14/fs/btrfs/Kconfig 2014-12-08 00:31:54.976418001 -0600
  219980. @@ -1,5 +1,6 @@
  219981. config BTRFS_FS
  219982. tristate "Btrfs filesystem support"
  219983. + select LIBCRC32C
  219984. select CRYPTO
  219985. select CRYPTO_CRC32C
  219986. select ZLIB_INFLATE
  219987. diff -Nur linux-3.14.14/fs/buffer.c linux-imx6-3.14/fs/buffer.c
  219988. --- linux-3.14.14/fs/buffer.c 2014-07-28 10:07:25.000000000 -0500
  219989. +++ linux-imx6-3.14/fs/buffer.c 2014-12-08 00:31:54.996418001 -0600
  219990. @@ -3088,7 +3088,7 @@
  219991. * until the buffer gets unlocked).
  219992. *
  219993. * ll_rw_block sets b_end_io to simple completion handler that marks
  219994. - * the buffer up-to-date (if approriate), unlocks the buffer and wakes
  219995. + * the buffer up-to-date (if appropriate), unlocks the buffer and wakes
  219996. * any waiters.
  219997. *
  219998. * All of the buffers must be for the same device, and must also be a
  219999. diff -Nur linux-3.14.14/fs/compat_binfmt_elf.c linux-imx6-3.14/fs/compat_binfmt_elf.c
  220000. --- linux-3.14.14/fs/compat_binfmt_elf.c 2014-07-28 10:07:25.000000000 -0500
  220001. +++ linux-imx6-3.14/fs/compat_binfmt_elf.c 2014-12-08 00:31:55.016418001 -0600
  220002. @@ -88,6 +88,11 @@
  220003. #define ELF_HWCAP COMPAT_ELF_HWCAP
  220004. #endif
  220005. +#ifdef COMPAT_ELF_HWCAP2
  220006. +#undef ELF_HWCAP2
  220007. +#define ELF_HWCAP2 COMPAT_ELF_HWCAP2
  220008. +#endif
  220009. +
  220010. #ifdef COMPAT_ARCH_DLINFO
  220011. #undef ARCH_DLINFO
  220012. #define ARCH_DLINFO COMPAT_ARCH_DLINFO
  220013. diff -Nur linux-3.14.14/fs/debugfs/inode.c linux-imx6-3.14/fs/debugfs/inode.c
  220014. --- linux-3.14.14/fs/debugfs/inode.c 2014-07-28 10:07:25.000000000 -0500
  220015. +++ linux-imx6-3.14/fs/debugfs/inode.c 2014-12-08 00:31:55.020418001 -0600
  220016. @@ -358,7 +358,7 @@
  220017. * @name: a pointer to a string containing the name of the file to create.
  220018. * @mode: the permission that the file should have.
  220019. * @parent: a pointer to the parent dentry for this file. This should be a
  220020. - * directory dentry if set. If this paramater is NULL, then the
  220021. + * directory dentry if set. If this parameter is NULL, then the
  220022. * file will be created in the root of the debugfs filesystem.
  220023. * @data: a pointer to something that the caller will want to get to later
  220024. * on. The inode.i_private pointer will point to this value on
  220025. @@ -400,7 +400,7 @@
  220026. * @name: a pointer to a string containing the name of the directory to
  220027. * create.
  220028. * @parent: a pointer to the parent dentry for this file. This should be a
  220029. - * directory dentry if set. If this paramater is NULL, then the
  220030. + * directory dentry if set. If this parameter is NULL, then the
  220031. * directory will be created in the root of the debugfs filesystem.
  220032. *
  220033. * This function creates a directory in debugfs with the given name.
  220034. @@ -425,7 +425,7 @@
  220035. * @name: a pointer to a string containing the name of the symbolic link to
  220036. * create.
  220037. * @parent: a pointer to the parent dentry for this symbolic link. This
  220038. - * should be a directory dentry if set. If this paramater is NULL,
  220039. + * should be a directory dentry if set. If this parameter is NULL,
  220040. * then the symbolic link will be created in the root of the debugfs
  220041. * filesystem.
  220042. * @target: a pointer to a string containing the path to the target of the
  220043. diff -Nur linux-3.14.14/include/asm-generic/word-at-a-time.h linux-imx6-3.14/include/asm-generic/word-at-a-time.h
  220044. --- linux-3.14.14/include/asm-generic/word-at-a-time.h 2014-07-28 10:07:25.000000000 -0500
  220045. +++ linux-imx6-3.14/include/asm-generic/word-at-a-time.h 2014-12-08 00:31:55.240418001 -0600
  220046. @@ -50,7 +50,7 @@
  220047. }
  220048. #ifndef zero_bytemask
  220049. -#define zero_bytemask(mask) (~0ul << __fls(mask) << 1)
  220050. +#define zero_bytemask(mask) (~1ul << __fls(mask))
  220051. #endif
  220052. #endif /* _ASM_WORD_AT_A_TIME_H */
  220053. diff -Nur linux-3.14.14/include/crypto/algapi.h linux-imx6-3.14/include/crypto/algapi.h
  220054. --- linux-3.14.14/include/crypto/algapi.h 2014-07-28 10:07:25.000000000 -0500
  220055. +++ linux-imx6-3.14/include/crypto/algapi.h 2014-12-08 00:31:55.240418001 -0600
  220056. @@ -100,9 +100,12 @@
  220057. void *page;
  220058. u8 *buffer;
  220059. u8 *iv;
  220060. + unsigned int ivsize;
  220061. int flags;
  220062. - unsigned int blocksize;
  220063. + unsigned int walk_blocksize;
  220064. + unsigned int cipher_blocksize;
  220065. + unsigned int alignmask;
  220066. };
  220067. struct ablkcipher_walk {
  220068. @@ -192,6 +195,10 @@
  220069. int blkcipher_walk_virt_block(struct blkcipher_desc *desc,
  220070. struct blkcipher_walk *walk,
  220071. unsigned int blocksize);
  220072. +int blkcipher_aead_walk_virt_block(struct blkcipher_desc *desc,
  220073. + struct blkcipher_walk *walk,
  220074. + struct crypto_aead *tfm,
  220075. + unsigned int blocksize);
  220076. int ablkcipher_walk_done(struct ablkcipher_request *req,
  220077. struct ablkcipher_walk *walk, int err);
  220078. diff -Nur linux-3.14.14/include/drm/drm_fb_helper.h linux-imx6-3.14/include/drm/drm_fb_helper.h
  220079. --- linux-3.14.14/include/drm/drm_fb_helper.h 2014-07-28 10:07:25.000000000 -0500
  220080. +++ linux-imx6-3.14/include/drm/drm_fb_helper.h 2014-12-08 00:31:55.240418001 -0600
  220081. @@ -55,7 +55,7 @@
  220082. * save the current lut when force-restoring the fbdev for e.g.
  220083. * kdbg.
  220084. * @fb_probe: Driver callback to allocate and initialize the fbdev info
  220085. - * structure. Futhermore it also needs to allocate the drm
  220086. + * structure. Furthermore it also needs to allocate the drm
  220087. * framebuffer used to back the fbdev.
  220088. * @initial_config: Setup an initial fbdev display configuration
  220089. *
  220090. diff -Nur linux-3.14.14/include/dt-bindings/clock/imx6sl-clock.h linux-imx6-3.14/include/dt-bindings/clock/imx6sl-clock.h
  220091. --- linux-3.14.14/include/dt-bindings/clock/imx6sl-clock.h 2014-07-28 10:07:25.000000000 -0500
  220092. +++ linux-imx6-3.14/include/dt-bindings/clock/imx6sl-clock.h 2014-12-08 00:31:55.244418001 -0600
  220093. @@ -1,5 +1,5 @@
  220094. /*
  220095. - * Copyright 2013 Freescale Semiconductor, Inc.
  220096. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  220097. *
  220098. * This program is free software; you can redistribute it and/or modify
  220099. * it under the terms of the GNU General Public License version 2 as
  220100. @@ -71,8 +71,8 @@
  220101. #define IMX6SL_CLK_PERIPH 58
  220102. #define IMX6SL_CLK_PERIPH2 59
  220103. #define IMX6SL_CLK_OCRAM_PODF 60
  220104. -#define IMX6SL_CLK_PERIPH_CLK2_PODF 61
  220105. -#define IMX6SL_CLK_PERIPH2_CLK2_PODF 62
  220106. +#define IMX6SL_CLK_PERIPH_CLK2 61
  220107. +#define IMX6SL_CLK_PERIPH2_CLK2 62
  220108. #define IMX6SL_CLK_IPG 63
  220109. #define IMX6SL_CLK_CSI_PODF 64
  220110. #define IMX6SL_CLK_LCDIF_AXI_PODF 65
  220111. @@ -145,6 +145,7 @@
  220112. #define IMX6SL_CLK_USDHC4 132
  220113. #define IMX6SL_CLK_PLL4_AUDIO_DIV 133
  220114. #define IMX6SL_CLK_SPBA 134
  220115. -#define IMX6SL_CLK_END 135
  220116. +#define IMX6SL_CLK_UART_OSC_4M 135
  220117. +#define IMX6SL_CLK_END 136
  220118. #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */
  220119. diff -Nur linux-3.14.14/include/linux/ahci_platform.h linux-imx6-3.14/include/linux/ahci_platform.h
  220120. --- linux-3.14.14/include/linux/ahci_platform.h 2014-07-28 10:07:25.000000000 -0500
  220121. +++ linux-imx6-3.14/include/linux/ahci_platform.h 2014-12-08 00:31:55.248418001 -0600
  220122. @@ -19,15 +19,38 @@
  220123. struct device;
  220124. struct ata_port_info;
  220125. +struct ahci_host_priv;
  220126. +struct platform_device;
  220127. +/*
  220128. + * Note ahci_platform_data is deprecated, it is only kept around for use
  220129. + * by the old da850 and spear13xx ahci code.
  220130. + * New drivers should instead declare their own platform_driver struct, and
  220131. + * use ahci_platform* functions in their own probe, suspend and resume methods.
  220132. + */
  220133. struct ahci_platform_data {
  220134. int (*init)(struct device *dev, void __iomem *addr);
  220135. void (*exit)(struct device *dev);
  220136. int (*suspend)(struct device *dev);
  220137. int (*resume)(struct device *dev);
  220138. - const struct ata_port_info *ata_port_info;
  220139. - unsigned int force_port_map;
  220140. - unsigned int mask_port_map;
  220141. };
  220142. +int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
  220143. +void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
  220144. +int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
  220145. +void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
  220146. +struct ahci_host_priv *ahci_platform_get_resources(
  220147. + struct platform_device *pdev);
  220148. +int ahci_platform_init_host(struct platform_device *pdev,
  220149. + struct ahci_host_priv *hpriv,
  220150. + const struct ata_port_info *pi_template,
  220151. + unsigned long host_flags,
  220152. + unsigned int force_port_map,
  220153. + unsigned int mask_port_map);
  220154. +
  220155. +int ahci_platform_suspend_host(struct device *dev);
  220156. +int ahci_platform_resume_host(struct device *dev);
  220157. +int ahci_platform_suspend(struct device *dev);
  220158. +int ahci_platform_resume(struct device *dev);
  220159. +
  220160. #endif /* _AHCI_PLATFORM_H */
  220161. diff -Nur linux-3.14.14/include/linux/amba/clcd.h linux-imx6-3.14/include/linux/amba/clcd.h
  220162. --- linux-3.14.14/include/linux/amba/clcd.h 2014-07-28 10:07:25.000000000 -0500
  220163. +++ linux-imx6-3.14/include/linux/amba/clcd.h 2014-12-08 00:31:55.248418001 -0600
  220164. @@ -243,6 +243,9 @@
  220165. val |= CNTL_BGR;
  220166. }
  220167. + /* Reset the current colour depth */
  220168. + val &= ~CNTL_LCDBPP16_444;
  220169. +
  220170. switch (var->bits_per_pixel) {
  220171. case 1:
  220172. val |= CNTL_LCDBPP1;
  220173. @@ -264,14 +267,15 @@
  220174. */
  220175. if (amba_part(fb->dev) == 0x110 ||
  220176. var->green.length == 5)
  220177. - val |= CNTL_LCDBPP16;
  220178. + val |= CNTL_LCDBPP16 | CNTL_BGR;
  220179. else if (var->green.length == 6)
  220180. - val |= CNTL_LCDBPP16_565;
  220181. + val |= CNTL_LCDBPP16_565 | CNTL_BGR;
  220182. else
  220183. - val |= CNTL_LCDBPP16_444;
  220184. + val |= CNTL_LCDBPP16_444 | CNTL_BGR;
  220185. break;
  220186. case 32:
  220187. val |= CNTL_LCDBPP24;
  220188. + val &= ~CNTL_BGR;
  220189. break;
  220190. }
  220191. diff -Nur linux-3.14.14/include/linux/arm-hdlcd.h linux-imx6-3.14/include/linux/arm-hdlcd.h
  220192. --- linux-3.14.14/include/linux/arm-hdlcd.h 1969-12-31 18:00:00.000000000 -0600
  220193. +++ linux-imx6-3.14/include/linux/arm-hdlcd.h 2014-12-08 00:31:55.248418001 -0600
  220194. @@ -0,0 +1,122 @@
  220195. +/*
  220196. + * include/linux/arm-hdlcd.h
  220197. + *
  220198. + * Copyright (C) 2011 ARM Limited
  220199. + *
  220200. + * This file is subject to the terms and conditions of the GNU General Public
  220201. + * License. See the file COPYING in the main directory of this archive
  220202. + * for more details.
  220203. + *
  220204. + * ARM HDLCD Controller register definition
  220205. + */
  220206. +
  220207. +#include <linux/fb.h>
  220208. +#include <linux/completion.h>
  220209. +
  220210. +/* register offsets */
  220211. +#define HDLCD_REG_VERSION 0x0000 /* ro */
  220212. +#define HDLCD_REG_INT_RAWSTAT 0x0010 /* rw */
  220213. +#define HDLCD_REG_INT_CLEAR 0x0014 /* wo */
  220214. +#define HDLCD_REG_INT_MASK 0x0018 /* rw */
  220215. +#define HDLCD_REG_INT_STATUS 0x001c /* ro */
  220216. +#define HDLCD_REG_USER_OUT 0x0020 /* rw */
  220217. +#define HDLCD_REG_FB_BASE 0x0100 /* rw */
  220218. +#define HDLCD_REG_FB_LINE_LENGTH 0x0104 /* rw */
  220219. +#define HDLCD_REG_FB_LINE_COUNT 0x0108 /* rw */
  220220. +#define HDLCD_REG_FB_LINE_PITCH 0x010c /* rw */
  220221. +#define HDLCD_REG_BUS_OPTIONS 0x0110 /* rw */
  220222. +#define HDLCD_REG_V_SYNC 0x0200 /* rw */
  220223. +#define HDLCD_REG_V_BACK_PORCH 0x0204 /* rw */
  220224. +#define HDLCD_REG_V_DATA 0x0208 /* rw */
  220225. +#define HDLCD_REG_V_FRONT_PORCH 0x020c /* rw */
  220226. +#define HDLCD_REG_H_SYNC 0x0210 /* rw */
  220227. +#define HDLCD_REG_H_BACK_PORCH 0x0214 /* rw */
  220228. +#define HDLCD_REG_H_DATA 0x0218 /* rw */
  220229. +#define HDLCD_REG_H_FRONT_PORCH 0x021c /* rw */
  220230. +#define HDLCD_REG_POLARITIES 0x0220 /* rw */
  220231. +#define HDLCD_REG_COMMAND 0x0230 /* rw */
  220232. +#define HDLCD_REG_PIXEL_FORMAT 0x0240 /* rw */
  220233. +#define HDLCD_REG_BLUE_SELECT 0x0244 /* rw */
  220234. +#define HDLCD_REG_GREEN_SELECT 0x0248 /* rw */
  220235. +#define HDLCD_REG_RED_SELECT 0x024c /* rw */
  220236. +
  220237. +/* version */
  220238. +#define HDLCD_PRODUCT_ID 0x1CDC0000
  220239. +#define HDLCD_PRODUCT_MASK 0xFFFF0000
  220240. +#define HDLCD_VERSION_MAJOR_MASK 0x0000FF00
  220241. +#define HDLCD_VERSION_MINOR_MASK 0x000000FF
  220242. +
  220243. +/* interrupts */
  220244. +#define HDLCD_INTERRUPT_DMA_END (1 << 0)
  220245. +#define HDLCD_INTERRUPT_BUS_ERROR (1 << 1)
  220246. +#define HDLCD_INTERRUPT_VSYNC (1 << 2)
  220247. +#define HDLCD_INTERRUPT_UNDERRUN (1 << 3)
  220248. +
  220249. +/* polarity */
  220250. +#define HDLCD_POLARITY_VSYNC (1 << 0)
  220251. +#define HDLCD_POLARITY_HSYNC (1 << 1)
  220252. +#define HDLCD_POLARITY_DATAEN (1 << 2)
  220253. +#define HDLCD_POLARITY_DATA (1 << 3)
  220254. +#define HDLCD_POLARITY_PIXELCLK (1 << 4)
  220255. +
  220256. +/* commands */
  220257. +#define HDLCD_COMMAND_DISABLE (0 << 0)
  220258. +#define HDLCD_COMMAND_ENABLE (1 << 0)
  220259. +
  220260. +/* pixel format */
  220261. +#define HDLCD_PIXEL_FMT_LITTLE_ENDIAN (0 << 31)
  220262. +#define HDLCD_PIXEL_FMT_BIG_ENDIAN (1 << 31)
  220263. +#define HDLCD_BYTES_PER_PIXEL_MASK (3 << 3)
  220264. +
  220265. +/* bus options */
  220266. +#define HDLCD_BUS_BURST_MASK 0x01f
  220267. +#define HDLCD_BUS_MAX_OUTSTAND 0xf00
  220268. +#define HDLCD_BUS_BURST_NONE (0 << 0)
  220269. +#define HDLCD_BUS_BURST_1 (1 << 0)
  220270. +#define HDLCD_BUS_BURST_2 (1 << 1)
  220271. +#define HDLCD_BUS_BURST_4 (1 << 2)
  220272. +#define HDLCD_BUS_BURST_8 (1 << 3)
  220273. +#define HDLCD_BUS_BURST_16 (1 << 4)
  220274. +
  220275. +/* Max resolution supported is 4096x4096, 8 bit per color component,
  220276. + 8 bit alpha, but we are going to choose the usual hardware default
  220277. + (2048x2048, 32 bpp) and enable double buffering */
  220278. +#define HDLCD_MAX_XRES 2048
  220279. +#define HDLCD_MAX_YRES 2048
  220280. +#define HDLCD_MAX_FRAMEBUFFER_SIZE (HDLCD_MAX_XRES * HDLCD_MAX_YRES << 2)
  220281. +
  220282. +#define HDLCD_MEM_BASE (CONFIG_PAGE_OFFSET - 0x1000000)
  220283. +
  220284. +#define NR_PALETTE 256
  220285. +
  220286. +/* OEMs using HDLCD may wish to enable these settings if
  220287. + * display disruption is apparent and you suspect HDLCD
  220288. + * access to RAM may be starved.
  220289. + */
  220290. +/* Turn HDLCD default color red instead of black so
  220291. + * that it's easy to see pixel clock data underruns
  220292. + * (compared to other visual disruption)
  220293. + */
  220294. +//#define HDLCD_RED_DEFAULT_COLOUR
  220295. +/* Add a counter in the IRQ handler to count buffer underruns
  220296. + * and /proc/hdlcd_underrun to read the counter
  220297. + */
  220298. +//#define HDLCD_COUNT_BUFFERUNDERRUNS
  220299. +/* Restrict height to 1x screen size
  220300. + *
  220301. + */
  220302. +//#define HDLCD_NO_VIRTUAL_SCREEN
  220303. +
  220304. +#ifdef CONFIG_ANDROID
  220305. +#define HDLCD_NO_VIRTUAL_SCREEN
  220306. +#endif
  220307. +
  220308. +struct hdlcd_device {
  220309. + struct fb_info fb;
  220310. + struct device *dev;
  220311. + struct clk *clk;
  220312. + void __iomem *base;
  220313. + int irq;
  220314. + struct completion vsync_completion;
  220315. + unsigned char *edid;
  220316. +};
  220317. diff -Nur linux-3.14.14/include/linux/backlight.h linux-imx6-3.14/include/linux/backlight.h
  220318. --- linux-3.14.14/include/linux/backlight.h 2014-07-28 10:07:25.000000000 -0500
  220319. +++ linux-imx6-3.14/include/linux/backlight.h 2014-12-08 00:31:55.252418001 -0600
  220320. @@ -9,6 +9,7 @@
  220321. #define _LINUX_BACKLIGHT_H
  220322. #include <linux/device.h>
  220323. +#include <linux/fb.h>
  220324. #include <linux/mutex.h>
  220325. #include <linux/notifier.h>
  220326. @@ -104,6 +105,11 @@
  220327. struct list_head entry;
  220328. struct device dev;
  220329. +
  220330. + /* Multiple framebuffers may share one backlight device */
  220331. + bool fb_bl_on[FB_MAX];
  220332. +
  220333. + int use_count;
  220334. };
  220335. static inline void backlight_update_status(struct backlight_device *bd)
  220336. diff -Nur linux-3.14.14/include/linux/busfreq-imx6.h linux-imx6-3.14/include/linux/busfreq-imx6.h
  220337. --- linux-3.14.14/include/linux/busfreq-imx6.h 1969-12-31 18:00:00.000000000 -0600
  220338. +++ linux-imx6-3.14/include/linux/busfreq-imx6.h 2014-12-08 00:31:55.252418001 -0600
  220339. @@ -0,0 +1,23 @@
  220340. +/*
  220341. + * Copyright 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  220342. + *
  220343. + * This program is free software; you can redistribute it and/or modify
  220344. + * it under the terms of the GNU General Public License version 2 as
  220345. + * published by the Free Software Foundation.
  220346. + */
  220347. +
  220348. +#ifndef __ASM_ARCH_MXC_BUSFREQ_H__
  220349. +#define __ASM_ARCH_MXC_BUSFREQ_H__
  220350. +
  220351. +/*
  220352. + * This enumerates busfreq mode.
  220353. + */
  220354. +enum bus_freq_mode {
  220355. + BUS_FREQ_HIGH,
  220356. + BUS_FREQ_MED,
  220357. + BUS_FREQ_AUDIO,
  220358. + BUS_FREQ_LOW,
  220359. +};
  220360. +void request_bus_freq(enum bus_freq_mode mode);
  220361. +void release_bus_freq(enum bus_freq_mode mode);
  220362. +#endif
  220363. diff -Nur linux-3.14.14/include/linux/cgroup_subsys.h linux-imx6-3.14/include/linux/cgroup_subsys.h
  220364. --- linux-3.14.14/include/linux/cgroup_subsys.h 2014-07-28 10:07:25.000000000 -0500
  220365. +++ linux-imx6-3.14/include/linux/cgroup_subsys.h 2014-12-08 00:31:55.256418001 -0600
  220366. @@ -39,6 +39,10 @@
  220367. SUBSYS(blkio)
  220368. #endif
  220369. +#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_BFQIO)
  220370. +SUBSYS(bfqio)
  220371. +#endif
  220372. +
  220373. #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_PERF)
  220374. SUBSYS(perf)
  220375. #endif
  220376. diff -Nur linux-3.14.14/include/linux/clk-provider.h linux-imx6-3.14/include/linux/clk-provider.h
  220377. --- linux-3.14.14/include/linux/clk-provider.h 2014-07-28 10:07:25.000000000 -0500
  220378. +++ linux-imx6-3.14/include/linux/clk-provider.h 2014-12-08 00:31:55.256418001 -0600
  220379. @@ -30,6 +30,13 @@
  220380. #define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */
  220381. #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
  220382. #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
  220383. +/*
  220384. + * Basic mux clk, can't switch parent while there is another basic mux clk
  220385. + * being its child. Otherwise, a glitch might be propagated to downstream
  220386. + * clocks through this child mux.
  220387. + */
  220388. +#define CLK_IS_BASIC_MUX BIT(9)
  220389. +
  220390. struct clk_hw;
  220391. diff -Nur linux-3.14.14/include/linux/cma.h linux-imx6-3.14/include/linux/cma.h
  220392. --- linux-3.14.14/include/linux/cma.h 1969-12-31 18:00:00.000000000 -0600
  220393. +++ linux-imx6-3.14/include/linux/cma.h 2014-12-08 00:31:55.260418001 -0600
  220394. @@ -0,0 +1,27 @@
  220395. +#ifndef __CMA_H__
  220396. +#define __CMA_H__
  220397. +
  220398. +/*
  220399. + * There is always at least global CMA area and a few optional
  220400. + * areas configured in kernel .config.
  220401. + */
  220402. +#ifdef CONFIG_CMA_AREAS
  220403. +#define MAX_CMA_AREAS (1 + CONFIG_CMA_AREAS)
  220404. +
  220405. +#else
  220406. +#define MAX_CMA_AREAS (0)
  220407. +
  220408. +#endif
  220409. +
  220410. +struct cma;
  220411. +
  220412. +extern phys_addr_t cma_get_base(struct cma *cma);
  220413. +extern unsigned long cma_get_size(struct cma *cma);
  220414. +
  220415. +extern int __init cma_declare_contiguous(phys_addr_t size,
  220416. + phys_addr_t base, phys_addr_t limit,
  220417. + phys_addr_t alignment, unsigned int order_per_bit,
  220418. + bool fixed, struct cma **res_cma);
  220419. +extern struct page *cma_alloc(struct cma *cma, int count, unsigned int align);
  220420. +extern bool cma_release(struct cma *cma, struct page *pages, int count);
  220421. +#endif
  220422. diff -Nur linux-3.14.14/include/linux/cpufeature.h linux-imx6-3.14/include/linux/cpufeature.h
  220423. --- linux-3.14.14/include/linux/cpufeature.h 1969-12-31 18:00:00.000000000 -0600
  220424. +++ linux-imx6-3.14/include/linux/cpufeature.h 2014-12-08 00:31:55.260418001 -0600
  220425. @@ -0,0 +1,60 @@
  220426. +/*
  220427. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  220428. + *
  220429. + * This program is free software; you can redistribute it and/or modify
  220430. + * it under the terms of the GNU General Public License version 2 as
  220431. + * published by the Free Software Foundation.
  220432. + */
  220433. +
  220434. +#ifndef __LINUX_CPUFEATURE_H
  220435. +#define __LINUX_CPUFEATURE_H
  220436. +
  220437. +#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
  220438. +
  220439. +#include <linux/mod_devicetable.h>
  220440. +#include <asm/cpufeature.h>
  220441. +
  220442. +/*
  220443. + * Macros imported from <asm/cpufeature.h>:
  220444. + * - cpu_feature(x) ordinal value of feature called 'x'
  220445. + * - cpu_have_feature(u32 n) whether feature #n is available
  220446. + * - MAX_CPU_FEATURES upper bound for feature ordinal values
  220447. + * Optional:
  220448. + * - CPU_FEATURE_TYPEFMT format string fragment for printing the cpu type
  220449. + * - CPU_FEATURE_TYPEVAL set of values matching the format string above
  220450. + */
  220451. +
  220452. +#ifndef CPU_FEATURE_TYPEFMT
  220453. +#define CPU_FEATURE_TYPEFMT "%s"
  220454. +#endif
  220455. +
  220456. +#ifndef CPU_FEATURE_TYPEVAL
  220457. +#define CPU_FEATURE_TYPEVAL ELF_PLATFORM
  220458. +#endif
  220459. +
  220460. +/*
  220461. + * Use module_cpu_feature_match(feature, module_init_function) to
  220462. + * declare that
  220463. + * a) the module shall be probed upon discovery of CPU feature 'feature'
  220464. + * (typically at boot time using udev)
  220465. + * b) the module must not be loaded if CPU feature 'feature' is not present
  220466. + * (not even by manual insmod).
  220467. + *
  220468. + * For a list of legal values for 'feature', please consult the file
  220469. + * 'asm/cpufeature.h' of your favorite architecture.
  220470. + */
  220471. +#define module_cpu_feature_match(x, __init) \
  220472. +static struct cpu_feature const cpu_feature_match_ ## x[] = \
  220473. + { { .feature = cpu_feature(x) }, { } }; \
  220474. +MODULE_DEVICE_TABLE(cpu, cpu_feature_match_ ## x); \
  220475. + \
  220476. +static int cpu_feature_match_ ## x ## _init(void) \
  220477. +{ \
  220478. + if (!cpu_have_feature(cpu_feature(x))) \
  220479. + return -ENODEV; \
  220480. + return __init(); \
  220481. +} \
  220482. +module_init(cpu_feature_match_ ## x ## _init)
  220483. +
  220484. +#endif
  220485. +#endif
  220486. diff -Nur linux-3.14.14/include/linux/cpufreq.h linux-imx6-3.14/include/linux/cpufreq.h
  220487. --- linux-3.14.14/include/linux/cpufreq.h 2014-07-28 10:07:25.000000000 -0500
  220488. +++ linux-imx6-3.14/include/linux/cpufreq.h 2014-12-08 00:31:55.260418001 -0600
  220489. @@ -429,6 +429,9 @@
  220490. #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND)
  220491. extern struct cpufreq_governor cpufreq_gov_ondemand;
  220492. #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_ondemand)
  220493. +#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE)
  220494. +extern struct cpufreq_governor cpufreq_gov_interactive;
  220495. +#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_interactive)
  220496. #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE)
  220497. extern struct cpufreq_governor cpufreq_gov_conservative;
  220498. #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_conservative)
  220499. diff -Nur linux-3.14.14/include/linux/cpu.h linux-imx6-3.14/include/linux/cpu.h
  220500. --- linux-3.14.14/include/linux/cpu.h 2014-07-28 10:07:25.000000000 -0500
  220501. +++ linux-imx6-3.14/include/linux/cpu.h 2014-12-08 00:31:55.260418001 -0600
  220502. @@ -226,4 +226,11 @@
  220503. void arch_cpu_idle_exit(void);
  220504. void arch_cpu_idle_dead(void);
  220505. +#define IDLE_START 1
  220506. +#define IDLE_END 2
  220507. +
  220508. +void idle_notifier_register(struct notifier_block *n);
  220509. +void idle_notifier_unregister(struct notifier_block *n);
  220510. +void idle_notifier_call_chain(unsigned long val);
  220511. +
  220512. #endif /* _LINUX_CPU_H_ */
  220513. diff -Nur linux-3.14.14/include/linux/device_cooling.h linux-imx6-3.14/include/linux/device_cooling.h
  220514. --- linux-3.14.14/include/linux/device_cooling.h 1969-12-31 18:00:00.000000000 -0600
  220515. +++ linux-imx6-3.14/include/linux/device_cooling.h 2014-12-08 00:31:55.264418001 -0600
  220516. @@ -0,0 +1,45 @@
  220517. +/*
  220518. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  220519. + *
  220520. + * This program is free software; you can redistribute it and/or modify
  220521. + * it under the terms of the GNU General Public License version 2 as
  220522. + * published by the Free Software Foundation.
  220523. + *
  220524. + */
  220525. +
  220526. +#ifndef __DEVICE_THERMAL_H__
  220527. +#define __DEVICE_THERMAL_H__
  220528. +
  220529. +#include <linux/thermal.h>
  220530. +
  220531. +#ifdef CONFIG_DEVICE_THERMAL
  220532. +int register_devfreq_cooling_notifier(struct notifier_block *nb);
  220533. +int unregister_devfreq_cooling_notifier(struct notifier_block *nb);
  220534. +struct thermal_cooling_device *devfreq_cooling_register(void);
  220535. +void devfreq_cooling_unregister(struct thermal_cooling_device *cdev);
  220536. +#else
  220537. +static inline
  220538. +int register_devfreq_cooling_notifier(struct notifier_block *nb)
  220539. +{
  220540. + return 0;
  220541. +}
  220542. +
  220543. +static inline
  220544. +int unregister_devfreq_cooling_notifier(struct notifier_block *nb)
  220545. +{
  220546. + return 0;
  220547. +}
  220548. +
  220549. +static inline
  220550. +struct thermal_cooling_device *devfreq_cooling_register(void)
  220551. +{
  220552. + return NULL;
  220553. +}
  220554. +
  220555. +static inline
  220556. +void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
  220557. +{
  220558. + return;
  220559. +}
  220560. +#endif
  220561. +#endif /* __DEVICE_THERMAL_H__ */
  220562. diff -Nur linux-3.14.14/include/linux/dma-contiguous.h linux-imx6-3.14/include/linux/dma-contiguous.h
  220563. --- linux-3.14.14/include/linux/dma-contiguous.h 2014-07-28 10:07:25.000000000 -0500
  220564. +++ linux-imx6-3.14/include/linux/dma-contiguous.h 2014-12-08 00:31:55.264418001 -0600
  220565. @@ -53,18 +53,13 @@
  220566. #ifdef __KERNEL__
  220567. +#include <linux/device.h>
  220568. +
  220569. struct cma;
  220570. struct page;
  220571. -struct device;
  220572. #ifdef CONFIG_DMA_CMA
  220573. -/*
  220574. - * There is always at least global CMA area and a few optional device
  220575. - * private areas configured in kernel .config.
  220576. - */
  220577. -#define MAX_CMA_AREAS (1 + CONFIG_CMA_AREAS)
  220578. -
  220579. extern struct cma *dma_contiguous_default_area;
  220580. static inline struct cma *dev_get_cma_area(struct device *dev)
  220581. @@ -88,7 +83,8 @@
  220582. void dma_contiguous_reserve(phys_addr_t addr_limit);
  220583. int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
  220584. - phys_addr_t limit, struct cma **res_cma);
  220585. + phys_addr_t limit, struct cma **res_cma,
  220586. + bool fixed);
  220587. /**
  220588. * dma_declare_contiguous() - reserve area for contiguous memory handling
  220589. @@ -108,7 +104,7 @@
  220590. {
  220591. struct cma *cma;
  220592. int ret;
  220593. - ret = dma_contiguous_reserve_area(size, base, limit, &cma);
  220594. + ret = dma_contiguous_reserve_area(size, base, limit, &cma, true);
  220595. if (ret == 0)
  220596. dev_set_cma_area(dev, cma);
  220597. @@ -122,8 +118,6 @@
  220598. #else
  220599. -#define MAX_CMA_AREAS (0)
  220600. -
  220601. static inline struct cma *dev_get_cma_area(struct device *dev)
  220602. {
  220603. return NULL;
  220604. @@ -136,7 +130,9 @@
  220605. static inline void dma_contiguous_reserve(phys_addr_t limit) { }
  220606. static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
  220607. - phys_addr_t limit, struct cma **res_cma) {
  220608. + phys_addr_t limit, struct cma **res_cma,
  220609. + bool fixed)
  220610. +{
  220611. return -ENOSYS;
  220612. }
  220613. diff -Nur linux-3.14.14/include/linux/dmaengine.h linux-imx6-3.14/include/linux/dmaengine.h
  220614. --- linux-3.14.14/include/linux/dmaengine.h 2014-07-28 10:07:25.000000000 -0500
  220615. +++ linux-imx6-3.14/include/linux/dmaengine.h 2014-12-08 00:31:55.264418001 -0600
  220616. @@ -333,6 +333,8 @@
  220617. * @slave_id: Slave requester id. Only valid for slave channels. The dma
  220618. * slave peripheral will have unique id as dma requester which need to be
  220619. * pass as slave config.
  220620. + * @dma_request0: this is the first dma request of this dma channel.
  220621. + * @dma_request1: this is the second dma request of this dma channel.
  220622. *
  220623. * This struct is passed in as configuration data to a DMA engine
  220624. * in order to set up a certain channel for DMA transport at runtime.
  220625. @@ -361,6 +363,8 @@
  220626. u32 dst_maxburst;
  220627. bool device_fc;
  220628. unsigned int slave_id;
  220629. + int dma_request0;
  220630. + int dma_request1;
  220631. };
  220632. /**
  220633. diff -Nur linux-3.14.14/include/linux/ftrace.h linux-imx6-3.14/include/linux/ftrace.h
  220634. --- linux-3.14.14/include/linux/ftrace.h 2014-07-28 10:07:25.000000000 -0500
  220635. +++ linux-imx6-3.14/include/linux/ftrace.h 2014-12-08 00:31:55.272418001 -0600
  220636. @@ -605,25 +605,27 @@
  220637. #endif
  220638. }
  220639. -#ifndef HAVE_ARCH_CALLER_ADDR
  220640. +/* All archs should have this, but we define it for consistency */
  220641. +#ifndef ftrace_return_address0
  220642. +# define ftrace_return_address0 __builtin_return_address(0)
  220643. +#endif
  220644. +
  220645. +/* Archs may use other ways for ADDR1 and beyond */
  220646. +#ifndef ftrace_return_address
  220647. # ifdef CONFIG_FRAME_POINTER
  220648. -# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  220649. -# define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
  220650. -# define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
  220651. -# define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
  220652. -# define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
  220653. -# define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
  220654. -# define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
  220655. +# define ftrace_return_address(n) __builtin_return_address(n)
  220656. # else
  220657. -# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  220658. -# define CALLER_ADDR1 0UL
  220659. -# define CALLER_ADDR2 0UL
  220660. -# define CALLER_ADDR3 0UL
  220661. -# define CALLER_ADDR4 0UL
  220662. -# define CALLER_ADDR5 0UL
  220663. -# define CALLER_ADDR6 0UL
  220664. +# define ftrace_return_address(n) 0UL
  220665. # endif
  220666. -#endif /* ifndef HAVE_ARCH_CALLER_ADDR */
  220667. +#endif
  220668. +
  220669. +#define CALLER_ADDR0 ((unsigned long)ftrace_return_address0)
  220670. +#define CALLER_ADDR1 ((unsigned long)ftrace_return_address(1))
  220671. +#define CALLER_ADDR2 ((unsigned long)ftrace_return_address(2))
  220672. +#define CALLER_ADDR3 ((unsigned long)ftrace_return_address(3))
  220673. +#define CALLER_ADDR4 ((unsigned long)ftrace_return_address(4))
  220674. +#define CALLER_ADDR5 ((unsigned long)ftrace_return_address(5))
  220675. +#define CALLER_ADDR6 ((unsigned long)ftrace_return_address(6))
  220676. #ifdef CONFIG_IRQSOFF_TRACER
  220677. extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
  220678. diff -Nur linux-3.14.14/include/linux/hardirq.h linux-imx6-3.14/include/linux/hardirq.h
  220679. --- linux-3.14.14/include/linux/hardirq.h 2014-07-28 10:07:25.000000000 -0500
  220680. +++ linux-imx6-3.14/include/linux/hardirq.h 2014-12-08 00:31:55.276418001 -0600
  220681. @@ -9,6 +9,7 @@
  220682. extern void synchronize_irq(unsigned int irq);
  220683. +extern void synchronize_hardirq(unsigned int irq);
  220684. #if defined(CONFIG_TINY_RCU)
  220685. diff -Nur linux-3.14.14/include/linux/hsi/hsi.h linux-imx6-3.14/include/linux/hsi/hsi.h
  220686. --- linux-3.14.14/include/linux/hsi/hsi.h 2014-07-28 10:07:25.000000000 -0500
  220687. +++ linux-imx6-3.14/include/linux/hsi/hsi.h 2014-12-08 00:31:55.276418001 -0600
  220688. @@ -178,7 +178,7 @@
  220689. * @complete: Transfer completion callback
  220690. * @destructor: Destructor to free resources when flushing
  220691. * @status: Status of the transfer when completed
  220692. - * @actual_len: Actual length of data transfered on completion
  220693. + * @actual_len: Actual length of data transferred on completion
  220694. * @channel: Channel were to TX/RX the message
  220695. * @ttype: Transfer type (TX if set, RX otherwise)
  220696. * @break_frame: if true HSI will send/receive a break frame. Data buffers are
  220697. diff -Nur linux-3.14.14/include/linux/ipu.h linux-imx6-3.14/include/linux/ipu.h
  220698. --- linux-3.14.14/include/linux/ipu.h 1969-12-31 18:00:00.000000000 -0600
  220699. +++ linux-imx6-3.14/include/linux/ipu.h 2014-12-08 00:31:55.288418001 -0600
  220700. @@ -0,0 +1,38 @@
  220701. +/*
  220702. + * Copyright 2005-2013 Freescale Semiconductor, Inc.
  220703. + */
  220704. +
  220705. +/*
  220706. + * The code contained herein is licensed under the GNU Lesser General
  220707. + * Public License. You may obtain a copy of the GNU Lesser General
  220708. + * Public License Version 2.1 or later at the following locations:
  220709. + *
  220710. + * http://www.opensource.org/licenses/lgpl-license.html
  220711. + * http://www.gnu.org/copyleft/lgpl.html
  220712. + */
  220713. +
  220714. +/*!
  220715. + * @defgroup IPU MXC Image Processing Unit (IPU) Driver
  220716. + */
  220717. +/*!
  220718. + * @file linux/ipu.h
  220719. + *
  220720. + * @brief This file contains the IPU driver API declarations.
  220721. + *
  220722. + * @ingroup IPU
  220723. + */
  220724. +
  220725. +#ifndef __LINUX_IPU_H__
  220726. +#define __LINUX_IPU_H__
  220727. +
  220728. +#include <linux/interrupt.h>
  220729. +#include <uapi/linux/ipu.h>
  220730. +
  220731. +unsigned int fmt_to_bpp(unsigned int pixelformat);
  220732. +cs_t colorspaceofpixel(int fmt);
  220733. +int need_csc(int ifmt, int ofmt);
  220734. +
  220735. +int ipu_queue_task(struct ipu_task *task);
  220736. +int ipu_check_task(struct ipu_task *task);
  220737. +
  220738. +#endif
  220739. diff -Nur linux-3.14.14/include/linux/ipu-v3.h linux-imx6-3.14/include/linux/ipu-v3.h
  220740. --- linux-3.14.14/include/linux/ipu-v3.h 1969-12-31 18:00:00.000000000 -0600
  220741. +++ linux-imx6-3.14/include/linux/ipu-v3.h 2014-12-08 00:31:55.288418001 -0600
  220742. @@ -0,0 +1,752 @@
  220743. +/*
  220744. + * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
  220745. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  220746. + *
  220747. + * This program is free software; you can redistribute it and/or modify it
  220748. + * under the terms of the GNU General Public License as published by the
  220749. + * Free Software Foundation; either version 2 of the License, or (at your
  220750. + * option) any later version.
  220751. + *
  220752. + * This program is distributed in the hope that it will be useful, but
  220753. + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  220754. + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  220755. + * for more details.
  220756. + */
  220757. +
  220758. +#ifndef __LINUX_IPU_V3_H_
  220759. +#define __LINUX_IPU_V3_H_
  220760. +
  220761. +#include <linux/ipu.h>
  220762. +
  220763. +/* IPU Driver channels definitions. */
  220764. +/* Note these are different from IDMA channels */
  220765. +#define IPU_MAX_CH 32
  220766. +#define _MAKE_CHAN(num, v_in, g_in, a_in, out) \
  220767. + ((num << 24) | (v_in << 18) | (g_in << 12) | (a_in << 6) | out)
  220768. +#define _MAKE_ALT_CHAN(ch) (ch | (IPU_MAX_CH << 24))
  220769. +#define IPU_CHAN_ID(ch) (ch >> 24)
  220770. +#define IPU_CHAN_ALT(ch) (ch & 0x02000000)
  220771. +#define IPU_CHAN_ALPHA_IN_DMA(ch) ((uint32_t) (ch >> 6) & 0x3F)
  220772. +#define IPU_CHAN_GRAPH_IN_DMA(ch) ((uint32_t) (ch >> 12) & 0x3F)
  220773. +#define IPU_CHAN_VIDEO_IN_DMA(ch) ((uint32_t) (ch >> 18) & 0x3F)
  220774. +#define IPU_CHAN_OUT_DMA(ch) ((uint32_t) (ch & 0x3F))
  220775. +#define NO_DMA 0x3F
  220776. +#define ALT 1
  220777. +/*!
  220778. + * Enumeration of IPU logical channels. An IPU logical channel is defined as a
  220779. + * combination of an input (memory to IPU), output (IPU to memory), and/or
  220780. + * secondary input IDMA channels and in some cases an Image Converter task.
  220781. + * Some channels consist of only an input or output.
  220782. + */
  220783. +typedef enum {
  220784. + CHAN_NONE = -1,
  220785. + MEM_ROT_ENC_MEM = _MAKE_CHAN(1, 45, NO_DMA, NO_DMA, 48),
  220786. + MEM_ROT_VF_MEM = _MAKE_CHAN(2, 46, NO_DMA, NO_DMA, 49),
  220787. + MEM_ROT_PP_MEM = _MAKE_CHAN(3, 47, NO_DMA, NO_DMA, 50),
  220788. +
  220789. + MEM_PRP_ENC_MEM = _MAKE_CHAN(4, 12, 14, 17, 20),
  220790. + MEM_PRP_VF_MEM = _MAKE_CHAN(5, 12, 14, 17, 21),
  220791. + MEM_PP_MEM = _MAKE_CHAN(6, 11, 15, 18, 22),
  220792. +
  220793. + MEM_DC_SYNC = _MAKE_CHAN(7, 28, NO_DMA, NO_DMA, NO_DMA),
  220794. + MEM_DC_ASYNC = _MAKE_CHAN(8, 41, NO_DMA, NO_DMA, NO_DMA),
  220795. + MEM_BG_SYNC = _MAKE_CHAN(9, 23, NO_DMA, 51, NO_DMA),
  220796. + MEM_FG_SYNC = _MAKE_CHAN(10, 27, NO_DMA, 31, NO_DMA),
  220797. +
  220798. + MEM_BG_ASYNC0 = _MAKE_CHAN(11, 24, NO_DMA, 52, NO_DMA),
  220799. + MEM_FG_ASYNC0 = _MAKE_CHAN(12, 29, NO_DMA, 33, NO_DMA),
  220800. + MEM_BG_ASYNC1 = _MAKE_ALT_CHAN(MEM_BG_ASYNC0),
  220801. + MEM_FG_ASYNC1 = _MAKE_ALT_CHAN(MEM_FG_ASYNC0),
  220802. +
  220803. + DIRECT_ASYNC0 = _MAKE_CHAN(13, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
  220804. + DIRECT_ASYNC1 = _MAKE_CHAN(14, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
  220805. +
  220806. + CSI_MEM0 = _MAKE_CHAN(15, NO_DMA, NO_DMA, NO_DMA, 0),
  220807. + CSI_MEM1 = _MAKE_CHAN(16, NO_DMA, NO_DMA, NO_DMA, 1),
  220808. + CSI_MEM2 = _MAKE_CHAN(17, NO_DMA, NO_DMA, NO_DMA, 2),
  220809. + CSI_MEM3 = _MAKE_CHAN(18, NO_DMA, NO_DMA, NO_DMA, 3),
  220810. +
  220811. + CSI_MEM = CSI_MEM0,
  220812. +
  220813. + CSI_PRP_ENC_MEM = _MAKE_CHAN(19, NO_DMA, NO_DMA, NO_DMA, 20),
  220814. + CSI_PRP_VF_MEM = _MAKE_CHAN(20, NO_DMA, NO_DMA, NO_DMA, 21),
  220815. +
  220816. + /* for vdi mem->vdi->ic->mem , add graphics plane and alpha*/
  220817. + MEM_VDI_PRP_VF_MEM_P = _MAKE_CHAN(21, 8, 14, 17, 21),
  220818. + MEM_VDI_PRP_VF_MEM = _MAKE_CHAN(22, 9, 14, 17, 21),
  220819. + MEM_VDI_PRP_VF_MEM_N = _MAKE_CHAN(23, 10, 14, 17, 21),
  220820. +
  220821. + /* for vdi mem->vdi->mem */
  220822. + MEM_VDI_MEM_P = _MAKE_CHAN(24, 8, NO_DMA, NO_DMA, 5),
  220823. + MEM_VDI_MEM = _MAKE_CHAN(25, 9, NO_DMA, NO_DMA, 5),
  220824. + MEM_VDI_MEM_N = _MAKE_CHAN(26, 10, NO_DMA, NO_DMA, 5),
  220825. +
  220826. + /* fake channel for vdoa to link with IPU */
  220827. + MEM_VDOA_MEM = _MAKE_CHAN(27, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
  220828. +
  220829. + MEM_PP_ADC = CHAN_NONE,
  220830. + ADC_SYS2 = CHAN_NONE,
  220831. +
  220832. +} ipu_channel_t;
  220833. +
  220834. +/*!
  220835. + * Enumeration of types of buffers for a logical channel.
  220836. + */
  220837. +typedef enum {
  220838. + IPU_OUTPUT_BUFFER = 0, /*!< Buffer for output from IPU */
  220839. + IPU_ALPHA_IN_BUFFER = 1, /*!< Buffer for input to IPU */
  220840. + IPU_GRAPH_IN_BUFFER = 2, /*!< Buffer for input to IPU */
  220841. + IPU_VIDEO_IN_BUFFER = 3, /*!< Buffer for input to IPU */
  220842. + IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER,
  220843. + IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER,
  220844. +} ipu_buffer_t;
  220845. +
  220846. +#define IPU_PANEL_SERIAL 1
  220847. +#define IPU_PANEL_PARALLEL 2
  220848. +
  220849. +/*!
  220850. + * Enumeration of ADC channel operation mode.
  220851. + */
  220852. +typedef enum {
  220853. + Disable,
  220854. + WriteTemplateNonSeq,
  220855. + ReadTemplateNonSeq,
  220856. + WriteTemplateUnCon,
  220857. + ReadTemplateUnCon,
  220858. + WriteDataWithRS,
  220859. + WriteDataWoRS,
  220860. + WriteCmd
  220861. +} mcu_mode_t;
  220862. +
  220863. +/*!
  220864. + * Enumeration of ADC channel addressing mode.
  220865. + */
  220866. +typedef enum {
  220867. + FullWoBE,
  220868. + FullWithBE,
  220869. + XY
  220870. +} display_addressing_t;
  220871. +
  220872. +/*!
  220873. + * Union of initialization parameters for a logical channel.
  220874. + */
  220875. +typedef union {
  220876. + struct {
  220877. + uint32_t csi;
  220878. + uint32_t mipi_id;
  220879. + uint32_t mipi_vc;
  220880. + bool mipi_en;
  220881. + bool interlaced;
  220882. + } csi_mem;
  220883. + struct {
  220884. + uint32_t in_width;
  220885. + uint32_t in_height;
  220886. + uint32_t in_pixel_fmt;
  220887. + uint32_t out_width;
  220888. + uint32_t out_height;
  220889. + uint32_t out_pixel_fmt;
  220890. + uint32_t outh_resize_ratio;
  220891. + uint32_t outv_resize_ratio;
  220892. + uint32_t csi;
  220893. + uint32_t mipi_id;
  220894. + uint32_t mipi_vc;
  220895. + bool mipi_en;
  220896. + } csi_prp_enc_mem;
  220897. + struct {
  220898. + uint32_t in_width;
  220899. + uint32_t in_height;
  220900. + uint32_t in_pixel_fmt;
  220901. + uint32_t out_width;
  220902. + uint32_t out_height;
  220903. + uint32_t out_pixel_fmt;
  220904. + uint32_t outh_resize_ratio;
  220905. + uint32_t outv_resize_ratio;
  220906. + } mem_prp_enc_mem;
  220907. + struct {
  220908. + uint32_t in_width;
  220909. + uint32_t in_height;
  220910. + uint32_t in_pixel_fmt;
  220911. + uint32_t out_width;
  220912. + uint32_t out_height;
  220913. + uint32_t out_pixel_fmt;
  220914. + } mem_rot_enc_mem;
  220915. + struct {
  220916. + uint32_t in_width;
  220917. + uint32_t in_height;
  220918. + uint32_t in_pixel_fmt;
  220919. + uint32_t out_width;
  220920. + uint32_t out_height;
  220921. + uint32_t out_pixel_fmt;
  220922. + uint32_t outh_resize_ratio;
  220923. + uint32_t outv_resize_ratio;
  220924. + bool graphics_combine_en;
  220925. + bool global_alpha_en;
  220926. + bool key_color_en;
  220927. + uint32_t in_g_pixel_fmt;
  220928. + uint8_t alpha;
  220929. + uint32_t key_color;
  220930. + bool alpha_chan_en;
  220931. + ipu_motion_sel motion_sel;
  220932. + enum v4l2_field field_fmt;
  220933. + uint32_t csi;
  220934. + uint32_t mipi_id;
  220935. + uint32_t mipi_vc;
  220936. + bool mipi_en;
  220937. + } csi_prp_vf_mem;
  220938. + struct {
  220939. + uint32_t in_width;
  220940. + uint32_t in_height;
  220941. + uint32_t in_pixel_fmt;
  220942. + uint32_t out_width;
  220943. + uint32_t out_height;
  220944. + uint32_t out_pixel_fmt;
  220945. + bool graphics_combine_en;
  220946. + bool global_alpha_en;
  220947. + bool key_color_en;
  220948. + display_port_t disp;
  220949. + uint32_t out_left;
  220950. + uint32_t out_top;
  220951. + } csi_prp_vf_adc;
  220952. + struct {
  220953. + uint32_t in_width;
  220954. + uint32_t in_height;
  220955. + uint32_t in_pixel_fmt;
  220956. + uint32_t out_width;
  220957. + uint32_t out_height;
  220958. + uint32_t out_pixel_fmt;
  220959. + uint32_t outh_resize_ratio;
  220960. + uint32_t outv_resize_ratio;
  220961. + bool graphics_combine_en;
  220962. + bool global_alpha_en;
  220963. + bool key_color_en;
  220964. + uint32_t in_g_pixel_fmt;
  220965. + uint8_t alpha;
  220966. + uint32_t key_color;
  220967. + bool alpha_chan_en;
  220968. + ipu_motion_sel motion_sel;
  220969. + enum v4l2_field field_fmt;
  220970. + } mem_prp_vf_mem;
  220971. + struct {
  220972. + uint32_t temp;
  220973. + } mem_prp_vf_adc;
  220974. + struct {
  220975. + uint32_t temp;
  220976. + } mem_rot_vf_mem;
  220977. + struct {
  220978. + uint32_t in_width;
  220979. + uint32_t in_height;
  220980. + uint32_t in_pixel_fmt;
  220981. + uint32_t out_width;
  220982. + uint32_t out_height;
  220983. + uint32_t out_pixel_fmt;
  220984. + uint32_t outh_resize_ratio;
  220985. + uint32_t outv_resize_ratio;
  220986. + bool graphics_combine_en;
  220987. + bool global_alpha_en;
  220988. + bool key_color_en;
  220989. + uint32_t in_g_pixel_fmt;
  220990. + uint8_t alpha;
  220991. + uint32_t key_color;
  220992. + bool alpha_chan_en;
  220993. + } mem_pp_mem;
  220994. + struct {
  220995. + uint32_t temp;
  220996. + } mem_rot_mem;
  220997. + struct {
  220998. + uint32_t in_width;
  220999. + uint32_t in_height;
  221000. + uint32_t in_pixel_fmt;
  221001. + uint32_t out_width;
  221002. + uint32_t out_height;
  221003. + uint32_t out_pixel_fmt;
  221004. + bool graphics_combine_en;
  221005. + bool global_alpha_en;
  221006. + bool key_color_en;
  221007. + display_port_t disp;
  221008. + uint32_t out_left;
  221009. + uint32_t out_top;
  221010. + } mem_pp_adc;
  221011. + struct {
  221012. + uint32_t di;
  221013. + bool interlaced;
  221014. + uint32_t in_pixel_fmt;
  221015. + uint32_t out_pixel_fmt;
  221016. + } mem_dc_sync;
  221017. + struct {
  221018. + uint32_t temp;
  221019. + } mem_sdc_fg;
  221020. + struct {
  221021. + uint32_t di;
  221022. + bool interlaced;
  221023. + uint32_t in_pixel_fmt;
  221024. + uint32_t out_pixel_fmt;
  221025. + bool alpha_chan_en;
  221026. + } mem_dp_bg_sync;
  221027. + struct {
  221028. + uint32_t temp;
  221029. + } mem_sdc_bg;
  221030. + struct {
  221031. + uint32_t di;
  221032. + bool interlaced;
  221033. + uint32_t in_pixel_fmt;
  221034. + uint32_t out_pixel_fmt;
  221035. + bool alpha_chan_en;
  221036. + } mem_dp_fg_sync;
  221037. + struct {
  221038. + uint32_t di;
  221039. + } direct_async;
  221040. + struct {
  221041. + display_port_t disp;
  221042. + mcu_mode_t ch_mode;
  221043. + uint32_t out_left;
  221044. + uint32_t out_top;
  221045. + } adc_sys1;
  221046. + struct {
  221047. + display_port_t disp;
  221048. + mcu_mode_t ch_mode;
  221049. + uint32_t out_left;
  221050. + uint32_t out_top;
  221051. + } adc_sys2;
  221052. +} ipu_channel_params_t;
  221053. +
  221054. +/*
  221055. + * IPU_IRQF_ONESHOT - Interrupt is not reenabled after the irq handler finished.
  221056. + */
  221057. +#define IPU_IRQF_NONE 0x00000000
  221058. +#define IPU_IRQF_ONESHOT 0x00000001
  221059. +
  221060. +/*!
  221061. + * Enumeration of IPU interrupt sources.
  221062. + */
  221063. +enum ipu_irq_line {
  221064. + IPU_IRQ_CSI0_OUT_EOF = 0,
  221065. + IPU_IRQ_CSI1_OUT_EOF = 1,
  221066. + IPU_IRQ_CSI2_OUT_EOF = 2,
  221067. + IPU_IRQ_CSI3_OUT_EOF = 3,
  221068. + IPU_IRQ_VDIC_OUT_EOF = 5,
  221069. + IPU_IRQ_VDI_P_IN_EOF = 8,
  221070. + IPU_IRQ_VDI_C_IN_EOF = 9,
  221071. + IPU_IRQ_VDI_N_IN_EOF = 10,
  221072. + IPU_IRQ_PP_IN_EOF = 11,
  221073. + IPU_IRQ_PRP_IN_EOF = 12,
  221074. + IPU_IRQ_PRP_GRAPH_IN_EOF = 14,
  221075. + IPU_IRQ_PP_GRAPH_IN_EOF = 15,
  221076. + IPU_IRQ_PRP_ALPHA_IN_EOF = 17,
  221077. + IPU_IRQ_PP_ALPHA_IN_EOF = 18,
  221078. + IPU_IRQ_PRP_ENC_OUT_EOF = 20,
  221079. + IPU_IRQ_PRP_VF_OUT_EOF = 21,
  221080. + IPU_IRQ_PP_OUT_EOF = 22,
  221081. + IPU_IRQ_BG_SYNC_EOF = 23,
  221082. + IPU_IRQ_BG_ASYNC_EOF = 24,
  221083. + IPU_IRQ_FG_SYNC_EOF = 27,
  221084. + IPU_IRQ_DC_SYNC_EOF = 28,
  221085. + IPU_IRQ_FG_ASYNC_EOF = 29,
  221086. + IPU_IRQ_FG_ALPHA_SYNC_EOF = 31,
  221087. +
  221088. + IPU_IRQ_FG_ALPHA_ASYNC_EOF = 33,
  221089. + IPU_IRQ_DC_READ_EOF = 40,
  221090. + IPU_IRQ_DC_ASYNC_EOF = 41,
  221091. + IPU_IRQ_DC_CMD1_EOF = 42,
  221092. + IPU_IRQ_DC_CMD2_EOF = 43,
  221093. + IPU_IRQ_DC_MASK_EOF = 44,
  221094. + IPU_IRQ_PRP_ENC_ROT_IN_EOF = 45,
  221095. + IPU_IRQ_PRP_VF_ROT_IN_EOF = 46,
  221096. + IPU_IRQ_PP_ROT_IN_EOF = 47,
  221097. + IPU_IRQ_PRP_ENC_ROT_OUT_EOF = 48,
  221098. + IPU_IRQ_PRP_VF_ROT_OUT_EOF = 49,
  221099. + IPU_IRQ_PP_ROT_OUT_EOF = 50,
  221100. + IPU_IRQ_BG_ALPHA_SYNC_EOF = 51,
  221101. + IPU_IRQ_BG_ALPHA_ASYNC_EOF = 52,
  221102. +
  221103. + IPU_IRQ_BG_SYNC_NFACK = 64 + 23,
  221104. + IPU_IRQ_FG_SYNC_NFACK = 64 + 27,
  221105. + IPU_IRQ_DC_SYNC_NFACK = 64 + 28,
  221106. +
  221107. + IPU_IRQ_DP_SF_START = 448 + 2,
  221108. + IPU_IRQ_DP_SF_END = 448 + 3,
  221109. + IPU_IRQ_BG_SF_END = IPU_IRQ_DP_SF_END,
  221110. + IPU_IRQ_DC_FC_0 = 448 + 8,
  221111. + IPU_IRQ_DC_FC_1 = 448 + 9,
  221112. + IPU_IRQ_DC_FC_2 = 448 + 10,
  221113. + IPU_IRQ_DC_FC_3 = 448 + 11,
  221114. + IPU_IRQ_DC_FC_4 = 448 + 12,
  221115. + IPU_IRQ_DC_FC_6 = 448 + 13,
  221116. + IPU_IRQ_VSYNC_PRE_0 = 448 + 14,
  221117. + IPU_IRQ_VSYNC_PRE_1 = 448 + 15,
  221118. +
  221119. + IPU_IRQ_COUNT
  221120. +};
  221121. +
  221122. +/*!
  221123. + * Bitfield of Display Interface signal polarities.
  221124. + */
  221125. +typedef struct {
  221126. + unsigned datamask_en:1;
  221127. + unsigned int_clk:1;
  221128. + unsigned interlaced:1;
  221129. + unsigned odd_field_first:1;
  221130. + unsigned clksel_en:1;
  221131. + unsigned clkidle_en:1;
  221132. + unsigned data_pol:1; /* true = inverted */
  221133. + unsigned clk_pol:1; /* true = rising edge */
  221134. + unsigned enable_pol:1;
  221135. + unsigned Hsync_pol:1; /* true = active high */
  221136. + unsigned Vsync_pol:1;
  221137. +} ipu_di_signal_cfg_t;
  221138. +
  221139. +/*!
  221140. + * Bitfield of CSI signal polarities and modes.
  221141. + */
  221142. +
  221143. +typedef struct {
  221144. + unsigned data_width:4;
  221145. + unsigned clk_mode:3;
  221146. + unsigned ext_vsync:1;
  221147. + unsigned Vsync_pol:1;
  221148. + unsigned Hsync_pol:1;
  221149. + unsigned pixclk_pol:1;
  221150. + unsigned data_pol:1;
  221151. + unsigned sens_clksrc:1;
  221152. + unsigned pack_tight:1;
  221153. + unsigned force_eof:1;
  221154. + unsigned data_en_pol:1;
  221155. + unsigned data_fmt;
  221156. + unsigned csi;
  221157. + unsigned mclk;
  221158. +} ipu_csi_signal_cfg_t;
  221159. +
  221160. +/*!
  221161. + * Enumeration of CSI data bus widths.
  221162. + */
  221163. +enum {
  221164. + IPU_CSI_DATA_WIDTH_4 = 0,
  221165. + IPU_CSI_DATA_WIDTH_8 = 1,
  221166. + IPU_CSI_DATA_WIDTH_10 = 3,
  221167. + IPU_CSI_DATA_WIDTH_16 = 9,
  221168. +};
  221169. +
  221170. +/*!
  221171. + * Enumeration of CSI clock modes.
  221172. + */
  221173. +enum {
  221174. + IPU_CSI_CLK_MODE_GATED_CLK,
  221175. + IPU_CSI_CLK_MODE_NONGATED_CLK,
  221176. + IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE,
  221177. + IPU_CSI_CLK_MODE_CCIR656_INTERLACED,
  221178. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR,
  221179. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR,
  221180. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR,
  221181. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR,
  221182. +};
  221183. +
  221184. +enum {
  221185. + IPU_CSI_MIPI_DI0,
  221186. + IPU_CSI_MIPI_DI1,
  221187. + IPU_CSI_MIPI_DI2,
  221188. + IPU_CSI_MIPI_DI3,
  221189. +};
  221190. +
  221191. +typedef enum {
  221192. + RGB,
  221193. + YCbCr,
  221194. + YUV
  221195. +} ipu_color_space_t;
  221196. +
  221197. +/*!
  221198. + * Enumeration of ADC vertical sync mode.
  221199. + */
  221200. +typedef enum {
  221201. + VsyncNone,
  221202. + VsyncInternal,
  221203. + VsyncCSI,
  221204. + VsyncExternal
  221205. +} vsync_t;
  221206. +
  221207. +typedef enum {
  221208. + DAT,
  221209. + CMD
  221210. +} cmddata_t;
  221211. +
  221212. +/*!
  221213. + * Enumeration of ADC display update mode.
  221214. + */
  221215. +typedef enum {
  221216. + IPU_ADC_REFRESH_NONE,
  221217. + IPU_ADC_AUTO_REFRESH,
  221218. + IPU_ADC_AUTO_REFRESH_SNOOP,
  221219. + IPU_ADC_SNOOPING,
  221220. +} ipu_adc_update_mode_t;
  221221. +
  221222. +/*!
  221223. + * Enumeration of ADC display interface types (serial or parallel).
  221224. + */
  221225. +enum {
  221226. + IPU_ADC_IFC_MODE_SYS80_TYPE1,
  221227. + IPU_ADC_IFC_MODE_SYS80_TYPE2,
  221228. + IPU_ADC_IFC_MODE_SYS68K_TYPE1,
  221229. + IPU_ADC_IFC_MODE_SYS68K_TYPE2,
  221230. + IPU_ADC_IFC_MODE_3WIRE_SERIAL,
  221231. + IPU_ADC_IFC_MODE_4WIRE_SERIAL,
  221232. + IPU_ADC_IFC_MODE_5WIRE_SERIAL_CLK,
  221233. + IPU_ADC_IFC_MODE_5WIRE_SERIAL_CS,
  221234. +};
  221235. +
  221236. +enum {
  221237. + IPU_ADC_IFC_WIDTH_8,
  221238. + IPU_ADC_IFC_WIDTH_16,
  221239. +};
  221240. +
  221241. +/*!
  221242. + * Enumeration of ADC display interface burst mode.
  221243. + */
  221244. +enum {
  221245. + IPU_ADC_BURST_WCS,
  221246. + IPU_ADC_BURST_WBLCK,
  221247. + IPU_ADC_BURST_NONE,
  221248. + IPU_ADC_BURST_SERIAL,
  221249. +};
  221250. +
  221251. +/*!
  221252. + * Enumeration of ADC display interface RW signal timing modes.
  221253. + */
  221254. +enum {
  221255. + IPU_ADC_SER_NO_RW,
  221256. + IPU_ADC_SER_RW_BEFORE_RS,
  221257. + IPU_ADC_SER_RW_AFTER_RS,
  221258. +};
  221259. +
  221260. +/*!
  221261. + * Bitfield of ADC signal polarities and modes.
  221262. + */
  221263. +typedef struct {
  221264. + unsigned data_pol:1;
  221265. + unsigned clk_pol:1;
  221266. + unsigned cs_pol:1;
  221267. + unsigned rs_pol:1;
  221268. + unsigned addr_pol:1;
  221269. + unsigned read_pol:1;
  221270. + unsigned write_pol:1;
  221271. + unsigned Vsync_pol:1;
  221272. + unsigned burst_pol:1;
  221273. + unsigned burst_mode:2;
  221274. + unsigned ifc_mode:3;
  221275. + unsigned ifc_width:5;
  221276. + unsigned ser_preamble_len:4;
  221277. + unsigned ser_preamble:8;
  221278. + unsigned ser_rw_mode:2;
  221279. +} ipu_adc_sig_cfg_t;
  221280. +
  221281. +/*!
  221282. + * Enumeration of ADC template commands.
  221283. + */
  221284. +enum {
  221285. + RD_DATA,
  221286. + RD_ACK,
  221287. + RD_WAIT,
  221288. + WR_XADDR,
  221289. + WR_YADDR,
  221290. + WR_ADDR,
  221291. + WR_CMND,
  221292. + WR_DATA,
  221293. +};
  221294. +
  221295. +/*!
  221296. + * Enumeration of ADC template command flow control.
  221297. + */
  221298. +enum {
  221299. + SINGLE_STEP,
  221300. + PAUSE,
  221301. + STOP,
  221302. +};
  221303. +
  221304. +
  221305. +/*Define template constants*/
  221306. +#define ATM_ADDR_RANGE 0x20 /*offset address of DISP */
  221307. +#define TEMPLATE_BUF_SIZE 0x20 /*size of template */
  221308. +
  221309. +/*!
  221310. + * Define to create ADC template command entry.
  221311. + */
  221312. +#define ipu_adc_template_gen(oc, rs, fc, dat) (((rs) << 29) | ((fc) << 27) | \
  221313. + ((oc) << 24) | (dat))
  221314. +
  221315. +typedef struct {
  221316. + u32 reg;
  221317. + u32 value;
  221318. +} ipu_lpmc_reg_t;
  221319. +
  221320. +#define IPU_LPMC_REG_READ 0x80000000L
  221321. +
  221322. +#define CSI_MCLK_VF 1
  221323. +#define CSI_MCLK_ENC 2
  221324. +#define CSI_MCLK_RAW 4
  221325. +#define CSI_MCLK_I2C 8
  221326. +
  221327. +struct ipu_soc;
  221328. +/* Common IPU API */
  221329. +struct ipu_soc *ipu_get_soc(int id);
  221330. +int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params);
  221331. +void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel);
  221332. +void ipu_disable_hsp_clk(struct ipu_soc *ipu);
  221333. +
  221334. +static inline bool ipu_can_rotate_in_place(ipu_rotate_mode_t rot)
  221335. +{
  221336. +#ifdef CONFIG_MXC_IPU_V3D
  221337. + return (rot < IPU_ROTATE_HORIZ_FLIP);
  221338. +#else
  221339. + return (rot < IPU_ROTATE_90_RIGHT);
  221340. +#endif
  221341. +}
  221342. +
  221343. +int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  221344. + uint32_t pixel_fmt,
  221345. + uint16_t width, uint16_t height,
  221346. + uint32_t stride,
  221347. + ipu_rotate_mode_t rot_mode,
  221348. + dma_addr_t phyaddr_0, dma_addr_t phyaddr_1,
  221349. + dma_addr_t phyaddr_2,
  221350. + uint32_t u_offset, uint32_t v_offset);
  221351. +
  221352. +int32_t ipu_update_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  221353. + uint32_t bufNum, dma_addr_t phyaddr);
  221354. +
  221355. +int32_t ipu_update_channel_offset(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  221356. + uint32_t pixel_fmt,
  221357. + uint16_t width, uint16_t height,
  221358. + uint32_t stride,
  221359. + uint32_t u, uint32_t v,
  221360. + uint32_t vertical_offset, uint32_t horizontal_offset);
  221361. +
  221362. +int32_t ipu_select_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  221363. + ipu_buffer_t type, uint32_t bufNum);
  221364. +int32_t ipu_select_multi_vdi_buffer(struct ipu_soc *ipu, uint32_t bufNum);
  221365. +
  221366. +int32_t ipu_link_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch);
  221367. +int32_t ipu_unlink_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch);
  221368. +
  221369. +int32_t ipu_is_channel_busy(struct ipu_soc *ipu, ipu_channel_t channel);
  221370. +int32_t ipu_check_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  221371. + uint32_t bufNum);
  221372. +void ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  221373. + uint32_t bufNum);
  221374. +uint32_t ipu_get_cur_buffer_idx(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type);
  221375. +int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel);
  221376. +int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wait_for_stop);
  221377. +int32_t ipu_swap_channel(struct ipu_soc *ipu, ipu_channel_t from_ch, ipu_channel_t to_ch);
  221378. +uint32_t ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel);
  221379. +
  221380. +int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi);
  221381. +int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi);
  221382. +
  221383. +int ipu_lowpwr_display_enable(void);
  221384. +int ipu_lowpwr_display_disable(void);
  221385. +
  221386. +int ipu_enable_irq(struct ipu_soc *ipu, uint32_t irq);
  221387. +void ipu_disable_irq(struct ipu_soc *ipu, uint32_t irq);
  221388. +void ipu_clear_irq(struct ipu_soc *ipu, uint32_t irq);
  221389. +int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
  221390. + irqreturn_t(*handler) (int, void *),
  221391. + uint32_t irq_flags, const char *devname, void *dev_id);
  221392. +void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id);
  221393. +bool ipu_get_irq_status(struct ipu_soc *ipu, uint32_t irq);
  221394. +void ipu_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]);
  221395. +int32_t ipu_set_channel_bandmode(struct ipu_soc *ipu, ipu_channel_t channel,
  221396. + ipu_buffer_t type, uint32_t band_height);
  221397. +
  221398. +/* two stripe calculations */
  221399. +struct stripe_param{
  221400. + unsigned int input_width; /* width of the input stripe */
  221401. + unsigned int output_width; /* width of the output stripe */
  221402. + unsigned int input_column; /* the first column on the input stripe */
  221403. + unsigned int output_column; /* the first column on the output stripe */
  221404. + unsigned int idr;
  221405. + /* inverse downisizing ratio parameter; expressed as a power of 2 */
  221406. + unsigned int irr;
  221407. + /* inverse resizing ratio parameter; expressed as a multiple of 2^-13 */
  221408. +};
  221409. +int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
  221410. + unsigned int output_frame_width,
  221411. + const unsigned int maximal_stripe_width,
  221412. + const unsigned long long cirr,
  221413. + const unsigned int equal_stripes,
  221414. + u32 input_pixelformat,
  221415. + u32 output_pixelformat,
  221416. + struct stripe_param *left,
  221417. + struct stripe_param *right);
  221418. +
  221419. +/* SDC API */
  221420. +int32_t ipu_init_sync_panel(struct ipu_soc *ipu, int disp,
  221421. + uint32_t pixel_clk,
  221422. + uint16_t width, uint16_t height,
  221423. + uint32_t pixel_fmt,
  221424. + uint16_t h_start_width, uint16_t h_sync_width,
  221425. + uint16_t h_end_width, uint16_t v_start_width,
  221426. + uint16_t v_sync_width, uint16_t v_end_width,
  221427. + uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig);
  221428. +
  221429. +void ipu_uninit_sync_panel(struct ipu_soc *ipu, int disp);
  221430. +
  221431. +int32_t ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, int16_t x_pos,
  221432. + int16_t y_pos);
  221433. +int32_t ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, int16_t *x_pos,
  221434. + int16_t *y_pos);
  221435. +int32_t ipu_disp_set_global_alpha(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
  221436. + uint8_t alpha);
  221437. +int32_t ipu_disp_set_color_key(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
  221438. + uint32_t colorKey);
  221439. +int32_t ipu_disp_set_gamma_correction(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
  221440. + int constk[], int slopek[]);
  221441. +
  221442. +int ipu_init_async_panel(struct ipu_soc *ipu, int disp, int type, uint32_t cycle_time,
  221443. + uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig);
  221444. +void ipu_disp_direct_write(struct ipu_soc *ipu, ipu_channel_t channel, u32 value, u32 offset);
  221445. +void ipu_reset_disp_panel(struct ipu_soc *ipu);
  221446. +
  221447. +/* CMOS Sensor Interface API */
  221448. +int32_t ipu_csi_init_interface(struct ipu_soc *ipu, uint16_t width, uint16_t height,
  221449. + uint32_t pixel_fmt, ipu_csi_signal_cfg_t sig);
  221450. +
  221451. +int32_t ipu_csi_get_sensor_protocol(struct ipu_soc *ipu, uint32_t csi);
  221452. +
  221453. +int32_t ipu_csi_enable_mclk(struct ipu_soc *ipu, int src, bool flag, bool wait);
  221454. +
  221455. +static inline int32_t ipu_csi_enable_mclk_if(struct ipu_soc *ipu, int src, uint32_t csi,
  221456. + bool flag, bool wait)
  221457. +{
  221458. + return ipu_csi_enable_mclk(ipu, csi, flag, wait);
  221459. +}
  221460. +
  221461. +int ipu_csi_read_mclk_flag(void);
  221462. +
  221463. +void ipu_csi_flash_strobe(bool flag);
  221464. +
  221465. +void ipu_csi_get_window_size(struct ipu_soc *ipu, uint32_t *width, uint32_t *height, uint32_t csi);
  221466. +
  221467. +void ipu_csi_set_window_size(struct ipu_soc *ipu, uint32_t width, uint32_t height, uint32_t csi);
  221468. +
  221469. +void ipu_csi_set_window_pos(struct ipu_soc *ipu, uint32_t left, uint32_t top, uint32_t csi);
  221470. +
  221471. +uint32_t bytes_per_pixel(uint32_t fmt);
  221472. +
  221473. +bool ipu_ch_param_bad_alpha_pos(uint32_t fmt);
  221474. +
  221475. +struct ipuv3_fb_platform_data {
  221476. + char disp_dev[32];
  221477. + u32 interface_pix_fmt;
  221478. + char *mode_str;
  221479. + int default_bpp;
  221480. + bool int_clk;
  221481. +
  221482. + /* reserved mem */
  221483. + resource_size_t res_base[2];
  221484. + resource_size_t res_size[2];
  221485. +
  221486. + /*
  221487. + * Late init to avoid display channel being
  221488. + * re-initialized as we've probably setup the
  221489. + * channel in bootloader.
  221490. + */
  221491. + bool late_init;
  221492. +};
  221493. +
  221494. +#endif /* __LINUX_IPU_V3_H_ */
  221495. diff -Nur linux-3.14.14/include/linux/isl29023.h linux-imx6-3.14/include/linux/isl29023.h
  221496. --- linux-3.14.14/include/linux/isl29023.h 1969-12-31 18:00:00.000000000 -0600
  221497. +++ linux-imx6-3.14/include/linux/isl29023.h 2014-12-08 00:31:55.288418001 -0600
  221498. @@ -0,0 +1,47 @@
  221499. +/*
  221500. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  221501. + */
  221502. +
  221503. +/*
  221504. + * This program is free software; you can redistribute it and/or modify
  221505. + * it under the terms of the GNU General Public License as published by
  221506. + * the Free Software Foundation; either version 2 of the License, or
  221507. + * (at your option) any later version.
  221508. +
  221509. + * This program is distributed in the hope that it will be useful,
  221510. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  221511. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  221512. + * GNU General Public License for more details.
  221513. +
  221514. + * You should have received a copy of the GNU General Public License along
  221515. + * with this program; if not, write to the Free Software Foundation, Inc.,
  221516. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  221517. + */
  221518. +
  221519. +#ifndef __ISL29023_H__
  221520. +#define __ISL29023_H__
  221521. +
  221522. +#include <linux/types.h>
  221523. +
  221524. +#define ISL29023_PD_MODE 0x0
  221525. +#define ISL29023_ALS_ONCE_MODE 0x1
  221526. +#define ISL29023_IR_ONCE_MODE 0x2
  221527. +#define ISL29023_ALS_CONT_MODE 0x5
  221528. +#define ISL29023_IR_CONT_MODE 0x6
  221529. +
  221530. +#define ISL29023_INT_PERSISTS_1 0x0
  221531. +#define ISL29023_INT_PERSISTS_4 0x1
  221532. +#define ISL29023_INT_PERSISTS_8 0x2
  221533. +#define ISL29023_INT_PERSISTS_16 0x3
  221534. +
  221535. +#define ISL29023_RES_16 0x0
  221536. +#define ISL29023_RES_12 0x1
  221537. +#define ISL29023_RES_8 0x2
  221538. +#define ISL29023_RES_4 0x3
  221539. +
  221540. +#define ISL29023_RANGE_1K 0x0
  221541. +#define ISL29023_RANGE_4K 0x1
  221542. +#define ISL29023_RANGE_16K 0x2
  221543. +#define ISL29023_RANGE_64K 0x3
  221544. +
  221545. +#endif
  221546. diff -Nur linux-3.14.14/include/linux/kfifo.h linux-imx6-3.14/include/linux/kfifo.h
  221547. --- linux-3.14.14/include/linux/kfifo.h 2014-07-28 10:07:25.000000000 -0500
  221548. +++ linux-imx6-3.14/include/linux/kfifo.h 2014-12-08 00:31:55.292418001 -0600
  221549. @@ -722,7 +722,7 @@
  221550. /**
  221551. * kfifo_dma_out_finish - finish a DMA OUT operation
  221552. * @fifo: address of the fifo to be used
  221553. - * @len: number of bytes transferd
  221554. + * @len: number of bytes transferrd
  221555. *
  221556. * This macro finish a DMA OUT operation. The out counter will be updated by
  221557. * the len parameter. No error checking will be done.
  221558. diff -Nur linux-3.14.14/include/linux/mailbox_client.h linux-imx6-3.14/include/linux/mailbox_client.h
  221559. --- linux-3.14.14/include/linux/mailbox_client.h 1969-12-31 18:00:00.000000000 -0600
  221560. +++ linux-imx6-3.14/include/linux/mailbox_client.h 2014-12-08 00:31:55.296418001 -0600
  221561. @@ -0,0 +1,46 @@
  221562. +/*
  221563. + * Copyright (C) 2014 Linaro Ltd.
  221564. + * Author: Jassi Brar <jassisinghbrar@gmail.com>
  221565. + *
  221566. + * This program is free software; you can redistribute it and/or modify
  221567. + * it under the terms of the GNU General Public License version 2 as
  221568. + * published by the Free Software Foundation.
  221569. + */
  221570. +
  221571. +#ifndef __MAILBOX_CLIENT_H
  221572. +#define __MAILBOX_CLIENT_H
  221573. +
  221574. +#include <linux/of.h>
  221575. +
  221576. +struct mbox_chan;
  221577. +
  221578. +/**
  221579. + * struct mbox_client - User of a mailbox
  221580. + * @dev: The client device
  221581. + * @chan_name: The "controller:channel" this client wants
  221582. + * @rx_callback: Atomic callback to provide client the data received
  221583. + * @tx_done: Atomic callback to tell client of data transmission
  221584. + * @tx_block: If the mbox_send_message should block until data is
  221585. + * transmitted.
  221586. + * @tx_tout: Max block period in ms before TX is assumed failure
  221587. + * @knows_txdone: if the client could run the TX state machine. Usually
  221588. + * if the client receives some ACK packet for transmission.
  221589. + * Unused if the controller already has TX_Done/RTR IRQ.
  221590. + */
  221591. +struct mbox_client {
  221592. + struct device *dev;
  221593. + const char *chan_name;
  221594. + void (*rx_callback)(struct mbox_client *cl, void *mssg);
  221595. + void (*tx_done)(struct mbox_client *cl, void *mssg, int r);
  221596. + bool tx_block;
  221597. + unsigned long tx_tout;
  221598. + bool knows_txdone;
  221599. +};
  221600. +
  221601. +struct mbox_chan *mbox_request_channel(struct mbox_client *cl);
  221602. +int mbox_send_message(struct mbox_chan *chan, void *mssg);
  221603. +void mbox_client_txdone(struct mbox_chan *chan, int r);
  221604. +bool mbox_client_peek_data(struct mbox_chan *chan);
  221605. +void mbox_free_channel(struct mbox_chan *chan);
  221606. +
  221607. +#endif /* __MAILBOX_CLIENT_H */
  221608. diff -Nur linux-3.14.14/include/linux/mailbox_controller.h linux-imx6-3.14/include/linux/mailbox_controller.h
  221609. --- linux-3.14.14/include/linux/mailbox_controller.h 1969-12-31 18:00:00.000000000 -0600
  221610. +++ linux-imx6-3.14/include/linux/mailbox_controller.h 2014-12-08 00:31:55.296418001 -0600
  221611. @@ -0,0 +1,121 @@
  221612. +/*
  221613. + * This program is free software; you can redistribute it and/or modify
  221614. + * it under the terms of the GNU General Public License version 2 as
  221615. + * published by the Free Software Foundation.
  221616. + */
  221617. +
  221618. +#ifndef __MAILBOX_CONTROLLER_H
  221619. +#define __MAILBOX_CONTROLLER_H
  221620. +
  221621. +#include <linux/of.h>
  221622. +
  221623. +struct mbox_chan;
  221624. +
  221625. +/**
  221626. + * struct mbox_chan_ops - s/w representation of a communication chan
  221627. + * @send_data: The API asks the MBOX controller driver, in atomic
  221628. + * context try to transmit a message on the bus. Returns 0 if
  221629. + * data is accepted for transmission, -EBUSY while rejecting
  221630. + * if the remote hasn't yet read the last data sent. Actual
  221631. + * transmission of data is reported by the controller via
  221632. + * mbox_chan_txdone (if it has some TX ACK irq). It must not
  221633. + * block.
  221634. + * @startup: Called when a client requests the chan. The controller
  221635. + * could ask clients for additional parameters of communication
  221636. + * to be provided via client's chan_data. This call may
  221637. + * block. After this call the Controller must forward any
  221638. + * data received on the chan by calling mbox_chan_received_data.
  221639. + * @shutdown: Called when a client relinquishes control of a chan.
  221640. + * This call may block too. The controller must not forwared
  221641. + * any received data anymore.
  221642. + * @last_tx_done: If the controller sets 'txdone_poll', the API calls
  221643. + * this to poll status of last TX. The controller must
  221644. + * give priority to IRQ method over polling and never
  221645. + * set both txdone_poll and txdone_irq. Only in polling
  221646. + * mode 'send_data' is expected to return -EBUSY.
  221647. + * Used only if txdone_poll:=true && txdone_irq:=false
  221648. + * @peek_data: Atomic check for any received data. Return true if controller
  221649. + * has some data to push to the client. False otherwise.
  221650. + */
  221651. +struct mbox_chan_ops {
  221652. + int (*send_data)(struct mbox_chan *chan, void *data);
  221653. + int (*startup)(struct mbox_chan *chan);
  221654. + void (*shutdown)(struct mbox_chan *chan);
  221655. + bool (*last_tx_done)(struct mbox_chan *chan);
  221656. + bool (*peek_data)(struct mbox_chan *chan);
  221657. +};
  221658. +
  221659. +/**
  221660. + * struct mbox_controller - Controller of a class of communication chans
  221661. + * @dev: Device backing this controller
  221662. + * @controller_name: Literal name of the controller.
  221663. + * @ops: Operators that work on each communication chan
  221664. + * @chans: Null terminated array of chans.
  221665. + * @txdone_irq: Indicates if the controller can report to API when
  221666. + * the last transmitted data was read by the remote.
  221667. + * Eg, if it has some TX ACK irq.
  221668. + * @txdone_poll: If the controller can read but not report the TX
  221669. + * done. Ex, some register shows the TX status but
  221670. + * no interrupt rises. Ignored if 'txdone_irq' is set.
  221671. + * @txpoll_period: If 'txdone_poll' is in effect, the API polls for
  221672. + * last TX's status after these many millisecs
  221673. + */
  221674. +struct mbox_controller {
  221675. + struct device *dev;
  221676. + struct mbox_chan_ops *ops;
  221677. + struct mbox_chan *chans;
  221678. + int num_chans;
  221679. + bool txdone_irq;
  221680. + bool txdone_poll;
  221681. + unsigned txpoll_period;
  221682. + struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox,
  221683. + const struct of_phandle_args *sp);
  221684. + /*
  221685. + * If the controller supports only TXDONE_BY_POLL,
  221686. + * this timer polls all the links for txdone.
  221687. + */
  221688. + struct timer_list poll;
  221689. + unsigned period;
  221690. + /* Hook to add to the global controller list */
  221691. + struct list_head node;
  221692. +};
  221693. +
  221694. +/*
  221695. + * The length of circular buffer for queuing messages from a client.
  221696. + * 'msg_count' tracks the number of buffered messages while 'msg_free'
  221697. + * is the index where the next message would be buffered.
  221698. + * We shouldn't need it too big because every transferr is interrupt
  221699. + * triggered and if we have lots of data to transfer, the interrupt
  221700. + * latencies are going to be the bottleneck, not the buffer length.
  221701. + * Besides, mbox_send_message could be called from atomic context and
  221702. + * the client could also queue another message from the notifier 'tx_done'
  221703. + * of the last transfer done.
  221704. + * REVIST: If too many platforms see the "Try increasing MBOX_TX_QUEUE_LEN"
  221705. + * print, it needs to be taken from config option or somesuch.
  221706. + */
  221707. +#define MBOX_TX_QUEUE_LEN 20
  221708. +
  221709. +struct mbox_chan {
  221710. + struct mbox_controller *mbox; /* Parent Controller */
  221711. + unsigned txdone_method;
  221712. +
  221713. + /* client */
  221714. + struct mbox_client *cl;
  221715. + struct completion tx_complete;
  221716. +
  221717. + void *active_req;
  221718. + unsigned msg_count, msg_free;
  221719. + void *msg_data[MBOX_TX_QUEUE_LEN];
  221720. + /* Access to the channel */
  221721. + spinlock_t lock;
  221722. +
  221723. + /* Private data for controller */
  221724. + void *con_priv;
  221725. +};
  221726. +
  221727. +int mbox_controller_register(struct mbox_controller *mbox);
  221728. +void mbox_chan_received_data(struct mbox_chan *chan, void *data);
  221729. +void mbox_chan_txdone(struct mbox_chan *chan, int r);
  221730. +void mbox_controller_unregister(struct mbox_controller *mbox);
  221731. +
  221732. +#endif /* __MAILBOX_CONTROLLER_H */
  221733. diff -Nur linux-3.14.14/include/linux/mailbox.h linux-imx6-3.14/include/linux/mailbox.h
  221734. --- linux-3.14.14/include/linux/mailbox.h 2014-07-28 10:07:25.000000000 -0500
  221735. +++ linux-imx6-3.14/include/linux/mailbox.h 1969-12-31 18:00:00.000000000 -0600
  221736. @@ -1,17 +0,0 @@
  221737. -/*
  221738. - * This program is free software; you can redistribute it and/or modify it
  221739. - * under the terms and conditions of the GNU General Public License,
  221740. - * version 2, as published by the Free Software Foundation.
  221741. - *
  221742. - * This program is distributed in the hope it will be useful, but WITHOUT
  221743. - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  221744. - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  221745. - * more details.
  221746. - *
  221747. - * You should have received a copy of the GNU General Public License along with
  221748. - * this program. If not, see <http://www.gnu.org/licenses/>.
  221749. - */
  221750. -
  221751. -int pl320_ipc_transmit(u32 *data);
  221752. -int pl320_ipc_register_notifier(struct notifier_block *nb);
  221753. -int pl320_ipc_unregister_notifier(struct notifier_block *nb);
  221754. diff -Nur linux-3.14.14/include/linux/memblock.h linux-imx6-3.14/include/linux/memblock.h
  221755. --- linux-3.14.14/include/linux/memblock.h 2014-07-28 10:07:25.000000000 -0500
  221756. +++ linux-imx6-3.14/include/linux/memblock.h 2014-12-08 00:31:55.296418001 -0600
  221757. @@ -221,6 +221,8 @@
  221758. #define MEMBLOCK_ALLOC_ANYWHERE (~(phys_addr_t)0)
  221759. #define MEMBLOCK_ALLOC_ACCESSIBLE 0
  221760. +phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align,
  221761. + phys_addr_t start, phys_addr_t end);
  221762. phys_addr_t memblock_alloc_base(phys_addr_t size, phys_addr_t align,
  221763. phys_addr_t max_addr);
  221764. phys_addr_t __memblock_alloc_base(phys_addr_t size, phys_addr_t align,
  221765. diff -Nur linux-3.14.14/include/linux/mfd/abx500/ab8500.h linux-imx6-3.14/include/linux/mfd/abx500/ab8500.h
  221766. --- linux-3.14.14/include/linux/mfd/abx500/ab8500.h 2014-07-28 10:07:25.000000000 -0500
  221767. +++ linux-imx6-3.14/include/linux/mfd/abx500/ab8500.h 2014-12-08 00:31:55.300418001 -0600
  221768. @@ -347,7 +347,6 @@
  221769. struct mutex lock;
  221770. struct mutex irq_lock;
  221771. atomic_t transfer_ongoing;
  221772. - int irq_base;
  221773. int irq;
  221774. struct irq_domain *domain;
  221775. enum ab8500_version version;
  221776. @@ -378,7 +377,6 @@
  221777. * @regulator: machine-specific constraints for regulators
  221778. */
  221779. struct ab8500_platform_data {
  221780. - int irq_base;
  221781. void (*init) (struct ab8500 *);
  221782. struct ab8500_regulator_platform_data *regulator;
  221783. struct ab8500_codec_platform_data *codec;
  221784. diff -Nur linux-3.14.14/include/linux/mfd/dbx500-prcmu.h linux-imx6-3.14/include/linux/mfd/dbx500-prcmu.h
  221785. --- linux-3.14.14/include/linux/mfd/dbx500-prcmu.h 2014-07-28 10:07:25.000000000 -0500
  221786. +++ linux-imx6-3.14/include/linux/mfd/dbx500-prcmu.h 2014-12-08 00:31:55.304418001 -0600
  221787. @@ -183,8 +183,6 @@
  221788. bool enable_set_ddr_opp;
  221789. bool enable_ape_opp_100_voltage;
  221790. struct ab8500_platform_data *ab_platdata;
  221791. - int ab_irq;
  221792. - int irq_base;
  221793. u32 version_offset;
  221794. u32 legacy_offset;
  221795. u32 adt_offset;
  221796. diff -Nur linux-3.14.14/include/linux/mfd/mxc-hdmi-core.h linux-imx6-3.14/include/linux/mfd/mxc-hdmi-core.h
  221797. --- linux-3.14.14/include/linux/mfd/mxc-hdmi-core.h 1969-12-31 18:00:00.000000000 -0600
  221798. +++ linux-imx6-3.14/include/linux/mfd/mxc-hdmi-core.h 2014-12-08 00:31:55.304418001 -0600
  221799. @@ -0,0 +1,68 @@
  221800. +/*
  221801. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  221802. + *
  221803. + * This program is free software; you can redistribute it and/or modify
  221804. + * it under the terms of the GNU General Public License as published by
  221805. + * the Free Software Foundation; either version 2 of the License, or
  221806. + * (at your option) any later version.
  221807. + *
  221808. + * This program is distributed in the hope that it will be useful,
  221809. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  221810. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  221811. + * GNU General Public License for more details.
  221812. + *
  221813. + * You should have received a copy of the GNU General Public License
  221814. + * along with this program; if not, write to the Free Software
  221815. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  221816. + *
  221817. + */
  221818. +#ifndef __LINUX_MXC_HDMI_CORE_H_
  221819. +#define __LINUX_MXC_HDMI_CORE_H_
  221820. +
  221821. +#include <video/mxc_edid.h>
  221822. +
  221823. +#include <sound/core.h>
  221824. +#include <sound/pcm.h>
  221825. +#include <sound/pcm_params.h>
  221826. +#include <sound/soc.h>
  221827. +
  221828. +#define IRQ_DISABLE_SUCCEED 0
  221829. +#define IRQ_DISABLE_FAIL 1
  221830. +
  221831. +bool hdmi_check_overflow(void);
  221832. +
  221833. +u8 hdmi_readb(unsigned int reg);
  221834. +void hdmi_writeb(u8 value, unsigned int reg);
  221835. +void hdmi_mask_writeb(u8 data, unsigned int addr, u8 shift, u8 mask);
  221836. +unsigned int hdmi_read4(unsigned int reg);
  221837. +void hdmi_write4(unsigned int value, unsigned int reg);
  221838. +
  221839. +void hdmi_irq_init(void);
  221840. +void hdmi_irq_enable(int irq);
  221841. +unsigned int hdmi_irq_disable(int irq);
  221842. +
  221843. +void hdmi_set_sample_rate(unsigned int rate);
  221844. +void hdmi_set_dma_mode(unsigned int dma_running);
  221845. +void hdmi_init_clk_regenerator(void);
  221846. +void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock);
  221847. +
  221848. +void hdmi_set_edid_cfg(int edid_status, struct mxc_edid_cfg *cfg);
  221849. +int hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg);
  221850. +
  221851. +extern int mxc_hdmi_ipu_id;
  221852. +extern int mxc_hdmi_disp_id;
  221853. +
  221854. +void hdmi_set_registered(int registered);
  221855. +int hdmi_get_registered(void);
  221856. +int mxc_hdmi_abort_stream(void);
  221857. +int mxc_hdmi_register_audio(struct snd_pcm_substream *substream);
  221858. +void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream);
  221859. +void hdmi_set_dvi_mode(unsigned int state);
  221860. +unsigned int hdmi_set_cable_state(unsigned int state);
  221861. +unsigned int hdmi_set_blank_state(unsigned int state);
  221862. +int check_hdmi_state(void);
  221863. +
  221864. +void hdmi_cec_start_device(void);
  221865. +void hdmi_cec_stop_device(void);
  221866. +
  221867. +#endif
  221868. diff -Nur linux-3.14.14/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h linux-imx6-3.14/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
  221869. --- linux-3.14.14/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h 2014-07-28 10:07:25.000000000 -0500
  221870. +++ linux-imx6-3.14/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h 2014-12-08 00:31:55.308418001 -0600
  221871. @@ -1,5 +1,5 @@
  221872. /*
  221873. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  221874. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  221875. *
  221876. * This program is free software; you can redistribute it and/or modify
  221877. * it under the terms of the GNU General Public License version 2 as
  221878. @@ -122,7 +122,9 @@
  221879. #define IMX6Q_GPR1_USB_OTG_ID_SEL_MASK BIT(13)
  221880. #define IMX6Q_GPR1_USB_OTG_ID_SEL_ENET_RX_ER 0x0
  221881. #define IMX6Q_GPR1_USB_OTG_ID_SEL_GPIO_1 BIT(13)
  221882. -#define IMX6Q_GPR1_GINT BIT(12)
  221883. +#define IMX6Q_GPR1_GINT_MASK BIT(12)
  221884. +#define IMX6Q_GPR1_GINT_CLEAR 0x0
  221885. +#define IMX6Q_GPR1_GINT_ASSERT BIT(12)
  221886. #define IMX6Q_GPR1_ADDRS3_MASK (0x3 << 10)
  221887. #define IMX6Q_GPR1_ADDRS3_32MB (0x0 << 10)
  221888. #define IMX6Q_GPR1_ADDRS3_64MB (0x1 << 10)
  221889. diff -Nur linux-3.14.14/include/linux/mipi_csi2.h linux-imx6-3.14/include/linux/mipi_csi2.h
  221890. --- linux-3.14.14/include/linux/mipi_csi2.h 1969-12-31 18:00:00.000000000 -0600
  221891. +++ linux-imx6-3.14/include/linux/mipi_csi2.h 2014-12-08 00:31:55.312418001 -0600
  221892. @@ -0,0 +1,93 @@
  221893. +/*
  221894. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  221895. + *
  221896. + * This program is free software; you can redistribute it and/or modify
  221897. + * it under the terms of the GNU General Public License as published by
  221898. + * the Free Software Foundation; either version 2 of the License, or
  221899. + * (at your option) any later version.
  221900. + *
  221901. + * This program is distributed in the hope that it will be useful,
  221902. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  221903. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  221904. + * GNU General Public License for more details.
  221905. + *
  221906. + * You should have received a copy of the GNU General Public License along
  221907. + * with this program; if not, write to the Free Software Foundation, Inc.,
  221908. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  221909. + */
  221910. +
  221911. +#ifndef __INCLUDE_MIPI_CSI2_H
  221912. +#define __INCLUDE_MIPI_CSI2_H
  221913. +
  221914. +/* MIPI CSI2 registers */
  221915. +#define MIPI_CSI2_REG(offset) (offset)
  221916. +
  221917. +#define MIPI_CSI2_VERSION MIPI_CSI2_REG(0x000)
  221918. +#define MIPI_CSI2_N_LANES MIPI_CSI2_REG(0x004)
  221919. +#define MIPI_CSI2_PHY_SHUTDOWNZ MIPI_CSI2_REG(0x008)
  221920. +#define MIPI_CSI2_DPHY_RSTZ MIPI_CSI2_REG(0x00c)
  221921. +#define MIPI_CSI2_CSI2_RESETN MIPI_CSI2_REG(0x010)
  221922. +#define MIPI_CSI2_PHY_STATE MIPI_CSI2_REG(0x014)
  221923. +#define MIPI_CSI2_DATA_IDS_1 MIPI_CSI2_REG(0x018)
  221924. +#define MIPI_CSI2_DATA_IDS_2 MIPI_CSI2_REG(0x01c)
  221925. +#define MIPI_CSI2_ERR1 MIPI_CSI2_REG(0x020)
  221926. +#define MIPI_CSI2_ERR2 MIPI_CSI2_REG(0x024)
  221927. +#define MIPI_CSI2_MASK1 MIPI_CSI2_REG(0x028)
  221928. +#define MIPI_CSI2_MASK2 MIPI_CSI2_REG(0x02c)
  221929. +#define MIPI_CSI2_PHY_TST_CTRL0 MIPI_CSI2_REG(0x030)
  221930. +#define MIPI_CSI2_PHY_TST_CTRL1 MIPI_CSI2_REG(0x034)
  221931. +#define MIPI_CSI2_SFT_RESET MIPI_CSI2_REG(0xf00)
  221932. +
  221933. +/* mipi data type */
  221934. +#define MIPI_DT_YUV420 0x18 /* YYY.../UYVY.... */
  221935. +#define MIPI_DT_YUV420_LEGACY 0x1a /* UYY.../VYY... */
  221936. +#define MIPI_DT_YUV422 0x1e /* UYVY... */
  221937. +#define MIPI_DT_RGB444 0x20
  221938. +#define MIPI_DT_RGB555 0x21
  221939. +#define MIPI_DT_RGB565 0x22
  221940. +#define MIPI_DT_RGB666 0x23
  221941. +#define MIPI_DT_RGB888 0x24
  221942. +#define MIPI_DT_RAW6 0x28
  221943. +#define MIPI_DT_RAW7 0x29
  221944. +#define MIPI_DT_RAW8 0x2a
  221945. +#define MIPI_DT_RAW10 0x2b
  221946. +#define MIPI_DT_RAW12 0x2c
  221947. +#define MIPI_DT_RAW14 0x2d
  221948. +
  221949. +
  221950. +struct mipi_csi2_info;
  221951. +/* mipi csi2 API */
  221952. +struct mipi_csi2_info *mipi_csi2_get_info(void);
  221953. +
  221954. +bool mipi_csi2_enable(struct mipi_csi2_info *info);
  221955. +
  221956. +bool mipi_csi2_disable(struct mipi_csi2_info *info);
  221957. +
  221958. +bool mipi_csi2_get_status(struct mipi_csi2_info *info);
  221959. +
  221960. +int mipi_csi2_get_bind_ipu(struct mipi_csi2_info *info);
  221961. +
  221962. +unsigned int mipi_csi2_get_bind_csi(struct mipi_csi2_info *info);
  221963. +
  221964. +unsigned int mipi_csi2_get_virtual_channel(struct mipi_csi2_info *info);
  221965. +
  221966. +unsigned int mipi_csi2_set_lanes(struct mipi_csi2_info *info);
  221967. +
  221968. +unsigned int mipi_csi2_set_datatype(struct mipi_csi2_info *info,
  221969. + unsigned int datatype);
  221970. +
  221971. +unsigned int mipi_csi2_get_datatype(struct mipi_csi2_info *info);
  221972. +
  221973. +unsigned int mipi_csi2_dphy_status(struct mipi_csi2_info *info);
  221974. +
  221975. +unsigned int mipi_csi2_get_error1(struct mipi_csi2_info *info);
  221976. +
  221977. +unsigned int mipi_csi2_get_error2(struct mipi_csi2_info *info);
  221978. +
  221979. +int mipi_csi2_pixelclk_enable(struct mipi_csi2_info *info);
  221980. +
  221981. +void mipi_csi2_pixelclk_disable(struct mipi_csi2_info *info);
  221982. +
  221983. +int mipi_csi2_reset(struct mipi_csi2_info *info);
  221984. +
  221985. +#endif
  221986. diff -Nur linux-3.14.14/include/linux/mipi_dsi.h linux-imx6-3.14/include/linux/mipi_dsi.h
  221987. --- linux-3.14.14/include/linux/mipi_dsi.h 1969-12-31 18:00:00.000000000 -0600
  221988. +++ linux-imx6-3.14/include/linux/mipi_dsi.h 2014-12-08 00:31:55.312418001 -0600
  221989. @@ -0,0 +1,171 @@
  221990. +/*
  221991. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  221992. + *
  221993. + * This program is free software; you can redistribute it and/or modify
  221994. + * it under the terms of the GNU General Public License as published by
  221995. + * the Free Software Foundation; either version 2 of the License, or
  221996. + * (at your option) any later version.
  221997. + *
  221998. + * This program is distributed in the hope that it will be useful,
  221999. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  222000. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  222001. + * GNU General Public License for more details.
  222002. + *
  222003. + * You should have received a copy of the GNU General Public License along
  222004. + * with this program; if not, write to the Free Software Foundation, Inc.,
  222005. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  222006. + */
  222007. +
  222008. +#ifndef __INCLUDE_MIPI_DSI_H
  222009. +#define __INCLUDE_MIPI_DSI_H
  222010. +
  222011. +#define MIPI_DSI_VERSION (0x000)
  222012. +#define MIPI_DSI_PWR_UP (0x004)
  222013. +#define MIPI_DSI_CLKMGR_CFG (0x008)
  222014. +#define MIPI_DSI_DPI_CFG (0x00c)
  222015. +#define MIPI_DSI_DBI_CFG (0x010)
  222016. +#define MIPI_DSI_DBIS_CMDSIZE (0x014)
  222017. +#define MIPI_DSI_PCKHDL_CFG (0x018)
  222018. +#define MIPI_DSI_VID_MODE_CFG (0x01c)
  222019. +#define MIPI_DSI_VID_PKT_CFG (0x020)
  222020. +#define MIPI_DSI_CMD_MODE_CFG (0x024)
  222021. +#define MIPI_DSI_TMR_LINE_CFG (0x028)
  222022. +#define MIPI_DSI_VTIMING_CFG (0x02c)
  222023. +#define MIPI_DSI_PHY_TMR_CFG (0x030)
  222024. +#define MIPI_DSI_GEN_HDR (0x034)
  222025. +#define MIPI_DSI_GEN_PLD_DATA (0x038)
  222026. +#define MIPI_DSI_CMD_PKT_STATUS (0x03c)
  222027. +#define MIPI_DSI_TO_CNT_CFG (0x040)
  222028. +#define MIPI_DSI_ERROR_ST0 (0x044)
  222029. +#define MIPI_DSI_ERROR_ST1 (0x048)
  222030. +#define MIPI_DSI_ERROR_MSK0 (0x04c)
  222031. +#define MIPI_DSI_ERROR_MSK1 (0x050)
  222032. +#define MIPI_DSI_PHY_RSTZ (0x054)
  222033. +#define MIPI_DSI_PHY_IF_CFG (0x058)
  222034. +#define MIPI_DSI_PHY_IF_CTRL (0x05c)
  222035. +#define MIPI_DSI_PHY_STATUS (0x060)
  222036. +#define MIPI_DSI_PHY_TST_CTRL0 (0x064)
  222037. +#define MIPI_DSI_PHY_TST_CTRL1 (0x068)
  222038. +
  222039. +#define DSI_PWRUP_RESET (0x0 << 0)
  222040. +#define DSI_PWRUP_POWERUP (0x1 << 0)
  222041. +
  222042. +#define DSI_DPI_CFG_VID_SHIFT (0)
  222043. +#define DSI_DPI_CFG_VID_MASK (0x3)
  222044. +#define DSI_DPI_CFG_COLORCODE_SHIFT (2)
  222045. +#define DSI_DPI_CFG_COLORCODE_MASK (0x7)
  222046. +#define DSI_DPI_CFG_DATAEN_ACT_LOW (0x1 << 5)
  222047. +#define DSI_DPI_CFG_DATAEN_ACT_HIGH (0x0 << 5)
  222048. +#define DSI_DPI_CFG_VSYNC_ACT_LOW (0x1 << 6)
  222049. +#define DSI_DPI_CFG_VSYNC_ACT_HIGH (0x0 << 6)
  222050. +#define DSI_DPI_CFG_HSYNC_ACT_LOW (0x1 << 7)
  222051. +#define DSI_DPI_CFG_HSYNC_ACT_HIGH (0x0 << 7)
  222052. +#define DSI_DPI_CFG_SHUTD_ACT_LOW (0x1 << 8)
  222053. +#define DSI_DPI_CFG_SHUTD_ACT_HIGH (0x0 << 8)
  222054. +#define DSI_DPI_CFG_COLORMODE_ACT_LOW (0x1 << 9)
  222055. +#define DSI_DPI_CFG_COLORMODE_ACT_HIGH (0x0 << 9)
  222056. +#define DSI_DPI_CFG_EN18LOOSELY (0x1 << 10)
  222057. +
  222058. +#define DSI_PCKHDL_CFG_EN_EOTP_TX (0x1 << 0)
  222059. +#define DSI_PCKHDL_CFG_EN_EOTP_RX (0x1 << 1)
  222060. +#define DSI_PCKHDL_CFG_EN_BTA (0x1 << 2)
  222061. +#define DSI_PCKHDL_CFG_EN_ECC_RX (0x1 << 3)
  222062. +#define DSI_PCKHDL_CFG_EN_CRC_RX (0x1 << 4)
  222063. +#define DSI_PCKHDL_CFG_GEN_VID_RX_MASK (0x3)
  222064. +#define DSI_PCKHDL_CFG_GEN_VID_RX_SHIFT (5)
  222065. +
  222066. +#define DSI_VID_MODE_CFG_EN (0x1 << 0)
  222067. +#define DSI_VID_MODE_CFG_EN_BURSTMODE (0x3 << 1)
  222068. +#define DSI_VID_MODE_CFG_TYPE_MASK (0x3)
  222069. +#define DSI_VID_MODE_CFG_TYPE_SHIFT (1)
  222070. +#define DSI_VID_MODE_CFG_EN_LP_VSA (0x1 << 3)
  222071. +#define DSI_VID_MODE_CFG_EN_LP_VBP (0x1 << 4)
  222072. +#define DSI_VID_MODE_CFG_EN_LP_VFP (0x1 << 5)
  222073. +#define DSI_VID_MODE_CFG_EN_LP_VACT (0x1 << 6)
  222074. +#define DSI_VID_MODE_CFG_EN_LP_HBP (0x1 << 7)
  222075. +#define DSI_VID_MODE_CFG_EN_LP_HFP (0x1 << 8)
  222076. +#define DSI_VID_MODE_CFG_EN_MULTI_PKT (0x1 << 9)
  222077. +#define DSI_VID_MODE_CFG_EN_NULL_PKT (0x1 << 10)
  222078. +#define DSI_VID_MODE_CFG_EN_FRAME_ACK (0x1 << 11)
  222079. +#define DSI_VID_MODE_CFG_EN_LP_MODE (DSI_VID_MODE_CFG_EN_LP_VSA | \
  222080. + DSI_VID_MODE_CFG_EN_LP_VBP | \
  222081. + DSI_VID_MODE_CFG_EN_LP_VFP | \
  222082. + DSI_VID_MODE_CFG_EN_LP_HFP | \
  222083. + DSI_VID_MODE_CFG_EN_LP_HBP | \
  222084. + DSI_VID_MODE_CFG_EN_LP_VACT)
  222085. +
  222086. +
  222087. +
  222088. +#define DSI_VID_PKT_CFG_VID_PKT_SZ_MASK (0x7ff)
  222089. +#define DSI_VID_PKT_CFG_VID_PKT_SZ_SHIFT (0)
  222090. +#define DSI_VID_PKT_CFG_NUM_CHUNKS_MASK (0x3ff)
  222091. +#define DSI_VID_PKT_CFG_NUM_CHUNKS_SHIFT (11)
  222092. +#define DSI_VID_PKT_CFG_NULL_PKT_SZ_MASK (0x3ff)
  222093. +#define DSI_VID_PKT_CFG_NULL_PKT_SZ_SHIFT (21)
  222094. +
  222095. +#define MIPI_DSI_CMD_MODE_CFG_EN_LOWPOWER (0x1FFF)
  222096. +#define MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE (0x1 << 0)
  222097. +
  222098. +#define DSI_TME_LINE_CFG_HSA_TIME_MASK (0x1ff)
  222099. +#define DSI_TME_LINE_CFG_HSA_TIME_SHIFT (0)
  222100. +#define DSI_TME_LINE_CFG_HBP_TIME_MASK (0x1ff)
  222101. +#define DSI_TME_LINE_CFG_HBP_TIME_SHIFT (9)
  222102. +#define DSI_TME_LINE_CFG_HLINE_TIME_MASK (0x3fff)
  222103. +#define DSI_TME_LINE_CFG_HLINE_TIME_SHIFT (18)
  222104. +
  222105. +#define DSI_VTIMING_CFG_VSA_LINES_MASK (0xf)
  222106. +#define DSI_VTIMING_CFG_VSA_LINES_SHIFT (0)
  222107. +#define DSI_VTIMING_CFG_VBP_LINES_MASK (0x3f)
  222108. +#define DSI_VTIMING_CFG_VBP_LINES_SHIFT (4)
  222109. +#define DSI_VTIMING_CFG_VFP_LINES_MASK (0x3f)
  222110. +#define DSI_VTIMING_CFG_VFP_LINES_SHIFT (10)
  222111. +#define DSI_VTIMING_CFG_V_ACT_LINES_MASK (0x7ff)
  222112. +#define DSI_VTIMING_CFG_V_ACT_LINES_SHIFT (16)
  222113. +
  222114. +#define DSI_PHY_TMR_CFG_BTA_TIME_MASK (0xfff)
  222115. +#define DSI_PHY_TMR_CFG_BTA_TIME_SHIFT (0)
  222116. +#define DSI_PHY_TMR_CFG_LP2HS_TIME_MASK (0xff)
  222117. +#define DSI_PHY_TMR_CFG_LP2HS_TIME_SHIFT (12)
  222118. +#define DSI_PHY_TMR_CFG_HS2LP_TIME_MASK (0xff)
  222119. +#define DSI_PHY_TMR_CFG_HS2LP_TIME_SHIFT (20)
  222120. +
  222121. +#define DSI_PHY_IF_CFG_N_LANES_MASK (0x3)
  222122. +#define DSI_PHY_IF_CFG_N_LANES_SHIFT (0)
  222123. +#define DSI_PHY_IF_CFG_WAIT_TIME_MASK (0xff)
  222124. +#define DSI_PHY_IF_CFG_WAIT_TIME_SHIFT (2)
  222125. +
  222126. +#define DSI_PHY_RSTZ_EN_CLK (0x1 << 2)
  222127. +#define DSI_PHY_RSTZ_DISABLE_RST (0x1 << 1)
  222128. +#define DSI_PHY_RSTZ_DISABLE_SHUTDOWN (0x1 << 0)
  222129. +#define DSI_PHY_RSTZ_RST (0x0)
  222130. +
  222131. +#define DSI_PHY_STATUS_LOCK (0x1 << 0)
  222132. +#define DSI_PHY_STATUS_STOPSTATE_CLK_LANE (0x1 << 2)
  222133. +
  222134. +#define DSI_GEN_HDR_TYPE_MASK (0xff)
  222135. +#define DSI_GEN_HDR_TYPE_SHIFT (0)
  222136. +#define DSI_GEN_HDR_DATA_MASK (0xffff)
  222137. +#define DSI_GEN_HDR_DATA_SHIFT (8)
  222138. +
  222139. +#define DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY (0x1 << 0)
  222140. +#define DSI_CMD_PKT_STATUS_GEN_CMD_FULL (0x1 << 1)
  222141. +#define DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY (0x1 << 2)
  222142. +#define DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL (0x1 << 3)
  222143. +#define DSI_CMD_PKT_STATUS_GEN_PLD_R_EMPTY (0x1 << 4)
  222144. +#define DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY (0x1 << 6)
  222145. +
  222146. +#define DSI_ERROR_MSK0_ALL_MASK (0x1fffff)
  222147. +#define DSI_ERROR_MSK1_ALL_MASK (0x3ffff)
  222148. +
  222149. +#define DSI_PHY_IF_CTRL_RESET (0x0)
  222150. +#define DSI_PHY_IF_CTRL_TX_REQ_CLK_HS (0x1 << 0)
  222151. +#define DSI_PHY_IF_CTRL_TX_REQ_CLK_ULPS (0x1 << 1)
  222152. +#define DSI_PHY_IF_CTRL_TX_EXIT_CLK_ULPS (0x1 << 2)
  222153. +#define DSI_PHY_IF_CTRL_TX_REQ_DATA_ULPS (0x1 << 3)
  222154. +#define DSI_PHY_IF_CTRL_TX_EXIT_DATA_ULPS (0x1 << 4)
  222155. +#define DSI_PHY_IF_CTRL_TX_TRIG_MASK (0xF)
  222156. +#define DSI_PHY_IF_CTRL_TX_TRIG_SHIFT (5)
  222157. +
  222158. +#define DSI_PHY_CLK_INIT_COMMAND (0x44)
  222159. +#define DSI_GEN_PLD_DATA_BUF_SIZE (0x4)
  222160. +#endif
  222161. diff -Nur linux-3.14.14/include/linux/mmc/card.h linux-imx6-3.14/include/linux/mmc/card.h
  222162. --- linux-3.14.14/include/linux/mmc/card.h 2014-07-28 10:07:25.000000000 -0500
  222163. +++ linux-imx6-3.14/include/linux/mmc/card.h 2014-12-08 00:31:55.316418001 -0600
  222164. @@ -86,10 +86,13 @@
  222165. unsigned int data_sector_size; /* 512 bytes or 4KB */
  222166. unsigned int data_tag_unit_size; /* DATA TAG UNIT size */
  222167. unsigned int boot_ro_lock; /* ro lock support */
  222168. + unsigned int boot_size;
  222169. bool boot_ro_lockable;
  222170. u8 raw_exception_status; /* 54 */
  222171. u8 raw_partition_support; /* 160 */
  222172. u8 raw_rpmb_size_mult; /* 168 */
  222173. + u8 boot_bus_width; /* 177 */
  222174. + u8 boot_config; /* 179 */
  222175. u8 raw_erased_mem_count; /* 181 */
  222176. u8 raw_ext_csd_structure; /* 194 */
  222177. u8 raw_card_type; /* 196 */
  222178. @@ -102,6 +105,7 @@
  222179. u8 raw_hc_erase_gap_size; /* 221 */
  222180. u8 raw_erase_timeout_mult; /* 223 */
  222181. u8 raw_hc_erase_grp_size; /* 224 */
  222182. + u8 boot_info; /* 228 */
  222183. u8 raw_sec_trim_mult; /* 229 */
  222184. u8 raw_sec_erase_mult; /* 230 */
  222185. u8 raw_sec_feature_support;/* 231 */
  222186. diff -Nur linux-3.14.14/include/linux/mmc/host.h linux-imx6-3.14/include/linux/mmc/host.h
  222187. --- linux-3.14.14/include/linux/mmc/host.h 2014-07-28 10:07:25.000000000 -0500
  222188. +++ linux-imx6-3.14/include/linux/mmc/host.h 2014-12-08 00:31:55.316418001 -0600
  222189. @@ -282,6 +282,7 @@
  222190. MMC_CAP2_PACKED_WR)
  222191. #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */
  222192. #define MMC_CAP2_SANITIZE (1 << 15) /* Support Sanitize */
  222193. +#define MMC_CAP2_SDIO_NOTHREAD (1 << 16)
  222194. mmc_pm_flag_t pm_caps; /* supported pm features */
  222195. @@ -297,6 +298,11 @@
  222196. unsigned long clkgate_delay;
  222197. #endif
  222198. + /* card specific properties to deal with power and reset */
  222199. + struct regulator *card_regulator; /* External VCC needed by the card */
  222200. + struct gpio_desc *card_reset_gpios[2]; /* External resets, active low */
  222201. + struct clk *card_clk; /* External clock needed by the card */
  222202. +
  222203. /* host specific block data */
  222204. unsigned int max_seg_size; /* see blk_queue_max_segment_size */
  222205. unsigned short max_segs; /* see blk_queue_max_segments */
  222206. @@ -397,6 +403,8 @@
  222207. wake_up_process(host->sdio_irq_thread);
  222208. }
  222209. +void sdio_run_irqs(struct mmc_host *host);
  222210. +
  222211. #ifdef CONFIG_REGULATOR
  222212. int mmc_regulator_get_ocrmask(struct regulator *supply);
  222213. int mmc_regulator_set_ocr(struct mmc_host *mmc,
  222214. diff -Nur linux-3.14.14/include/linux/mmc/mmc.h linux-imx6-3.14/include/linux/mmc/mmc.h
  222215. --- linux-3.14.14/include/linux/mmc/mmc.h 2014-07-28 10:07:25.000000000 -0500
  222216. +++ linux-imx6-3.14/include/linux/mmc/mmc.h 2014-12-08 00:31:55.316418001 -0600
  222217. @@ -292,6 +292,7 @@
  222218. #define EXT_CSD_RPMB_MULT 168 /* RO */
  222219. #define EXT_CSD_BOOT_WP 173 /* R/W */
  222220. #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
  222221. +#define EXT_CSD_BOOT_BUS_WIDTH 177 /* R/W */
  222222. #define EXT_CSD_PART_CONFIG 179 /* R/W */
  222223. #define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
  222224. #define EXT_CSD_BUS_WIDTH 183 /* R/W */
  222225. @@ -313,6 +314,7 @@
  222226. #define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
  222227. #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
  222228. #define EXT_CSD_BOOT_MULT 226 /* RO */
  222229. +#define EXT_CSD_BOOT_INFO 228 /* RO, 1 bytes */
  222230. #define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
  222231. #define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
  222232. #define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
  222233. @@ -378,6 +380,29 @@
  222234. #define EXT_CSD_SEC_GB_CL_EN BIT(4)
  222235. #define EXT_CSD_SEC_SANITIZE BIT(6) /* v4.5 only */
  222236. +#define EXT_CSD_BOOT_BUS_WIDTH_MASK (0x1F)
  222237. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_MASK (0x3 << 3)
  222238. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_SDR_NORMAL (0x0)
  222239. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_SDR_HIGH (0x1)
  222240. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_DDR (0x2)
  222241. +#define EXT_CSD_BOOT_BUS_WIDTH_RST_WIDTH (1 << 2)
  222242. +#define EXT_CSD_BOOT_BUS_WIDTH_WIDTH_MASK (0x3)
  222243. +#define EXT_CSD_BOOT_BUS_WIDTH_1_SDR_4_DDR (0x0)
  222244. +#define EXT_CSD_BOOT_BUS_WIDTH_4_SDR_4_DDR (0x1)
  222245. +#define EXT_CSD_BOOT_BUS_WIDTH_8_SDR_8_DDR (0x2)
  222246. +
  222247. +#define EXT_CSD_BOOT_ACK_ENABLE (0x1 << 6)
  222248. +#define EXT_CSD_BOOT_PARTITION_ENABLE_MASK (0x7 << 3)
  222249. +#define EXT_CSD_BOOT_PARTITION_DISABLE (0x0)
  222250. +#define EXT_CSD_BOOT_PARTITION_PART1 (0x1 << 3)
  222251. +#define EXT_CSD_BOOT_PARTITION_PART2 (0x2 << 3)
  222252. +#define EXT_CSD_BOOT_PARTITION_USER (0x7 << 3)
  222253. +
  222254. +#define EXT_CSD_BOOT_PARTITION_ACCESS_MASK (0x7)
  222255. +#define EXT_CSD_BOOT_PARTITION_ACCESS_DISABLE (0x0)
  222256. +#define EXT_CSD_BOOT_PARTITION_ACCESS_PART1 (0x1)
  222257. +#define EXT_CSD_BOOT_PARTITION_ACCESS_PART2 (0x2)
  222258. +
  222259. #define EXT_CSD_RST_N_EN_MASK 0x3
  222260. #define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
  222261. diff -Nur linux-3.14.14/include/linux/mmc/sdhci.h linux-imx6-3.14/include/linux/mmc/sdhci.h
  222262. --- linux-3.14.14/include/linux/mmc/sdhci.h 2014-07-28 10:07:25.000000000 -0500
  222263. +++ linux-imx6-3.14/include/linux/mmc/sdhci.h 2014-12-08 00:31:55.316418001 -0600
  222264. @@ -57,12 +57,8 @@
  222265. #define SDHCI_QUIRK_BROKEN_CARD_DETECTION (1<<15)
  222266. /* Controller reports inverted write-protect state */
  222267. #define SDHCI_QUIRK_INVERTED_WRITE_PROTECT (1<<16)
  222268. -/* Controller has nonstandard clock management */
  222269. -#define SDHCI_QUIRK_NONSTANDARD_CLOCK (1<<17)
  222270. /* Controller does not like fast PIO transfers */
  222271. #define SDHCI_QUIRK_PIO_NEEDS_DELAY (1<<18)
  222272. -/* Controller losing signal/interrupt enable states after reset */
  222273. -#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET (1<<19)
  222274. /* Controller has to be forced to use block size of 2048 bytes */
  222275. #define SDHCI_QUIRK_FORCE_BLK_SZ_2048 (1<<20)
  222276. /* Controller cannot do multi-block transfers */
  222277. @@ -100,6 +96,7 @@
  222278. #define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
  222279. /* Controller does not support HS200 */
  222280. #define SDHCI_QUIRK2_BROKEN_HS200 (1<<6)
  222281. +#define SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER (1<<7)
  222282. int irq; /* Device IRQ */
  222283. void __iomem *ioaddr; /* Mapped address */
  222284. @@ -145,6 +142,7 @@
  222285. bool runtime_suspended; /* Host is runtime suspended */
  222286. bool bus_on; /* Bus power prevents runtime suspend */
  222287. + bool preset_enabled; /* Preset is enabled */
  222288. struct mmc_request *mrq; /* Current request */
  222289. struct mmc_command *cmd; /* Current command */
  222290. @@ -162,8 +160,7 @@
  222291. dma_addr_t adma_addr; /* Mapped ADMA descr. table */
  222292. dma_addr_t align_addr; /* Mapped bounce buffer */
  222293. - struct tasklet_struct card_tasklet; /* Tasklet structures */
  222294. - struct tasklet_struct finish_tasklet;
  222295. + struct tasklet_struct finish_tasklet; /* Tasklet structures */
  222296. struct timer_list timer; /* Timer for timeouts */
  222297. @@ -175,6 +172,13 @@
  222298. unsigned int ocr_avail_mmc;
  222299. u32 ocr_mask; /* available voltages */
  222300. + unsigned timing; /* Current timing */
  222301. +
  222302. + u32 thread_isr;
  222303. +
  222304. + /* cached registers */
  222305. + u32 ier;
  222306. +
  222307. wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */
  222308. unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */
  222309. diff -Nur linux-3.14.14/include/linux/mmc/sdio_ids.h linux-imx6-3.14/include/linux/mmc/sdio_ids.h
  222310. --- linux-3.14.14/include/linux/mmc/sdio_ids.h 2014-07-28 10:07:25.000000000 -0500
  222311. +++ linux-imx6-3.14/include/linux/mmc/sdio_ids.h 2014-12-08 00:31:55.316418001 -0600
  222312. @@ -31,6 +31,7 @@
  222313. #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
  222314. #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335
  222315. #define SDIO_DEVICE_ID_BROADCOM_43362 43362
  222316. +#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
  222317. #define SDIO_VENDOR_ID_INTEL 0x0089
  222318. #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402
  222319. diff -Nur linux-3.14.14/include/linux/mod_devicetable.h linux-imx6-3.14/include/linux/mod_devicetable.h
  222320. --- linux-3.14.14/include/linux/mod_devicetable.h 2014-07-28 10:07:25.000000000 -0500
  222321. +++ linux-imx6-3.14/include/linux/mod_devicetable.h 2014-12-08 00:31:55.316418001 -0600
  222322. @@ -564,6 +564,15 @@
  222323. #define X86_MODEL_ANY 0
  222324. #define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */
  222325. +/*
  222326. + * Generic table type for matching CPU features.
  222327. + * @feature: the bit number of the feature (0 - 65535)
  222328. + */
  222329. +
  222330. +struct cpu_feature {
  222331. + __u16 feature;
  222332. +};
  222333. +
  222334. #define IPACK_ANY_FORMAT 0xff
  222335. #define IPACK_ANY_ID (~0)
  222336. struct ipack_device_id {
  222337. diff -Nur linux-3.14.14/include/linux/mtd/map.h linux-imx6-3.14/include/linux/mtd/map.h
  222338. --- linux-3.14.14/include/linux/mtd/map.h 2014-07-28 10:07:25.000000000 -0500
  222339. +++ linux-imx6-3.14/include/linux/mtd/map.h 2014-12-08 00:31:55.320418001 -0600
  222340. @@ -438,7 +438,7 @@
  222341. if (map->cached)
  222342. memcpy(to, (char *)map->cached + from, len);
  222343. else
  222344. - memcpy_fromio(to, map->virt + from, len);
  222345. + memcpy(to, map->virt + from, len);
  222346. }
  222347. static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
  222348. diff -Nur linux-3.14.14/include/linux/mxc_asrc.h linux-imx6-3.14/include/linux/mxc_asrc.h
  222349. --- linux-3.14.14/include/linux/mxc_asrc.h 1969-12-31 18:00:00.000000000 -0600
  222350. +++ linux-imx6-3.14/include/linux/mxc_asrc.h 2014-12-08 00:31:55.320418001 -0600
  222351. @@ -0,0 +1,386 @@
  222352. +/*
  222353. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  222354. + *
  222355. + * The code contained herein is licensed under the GNU General Public
  222356. + * License. You may obtain a copy of the GNU General Public License
  222357. + * Version 2 or later at the following locations:
  222358. + *
  222359. + * http://www.opensource.org/licenses/gpl-license.html
  222360. + * http://www.gnu.org/copyleft/gpl.html
  222361. + *
  222362. + * @file mxc_asrc.h
  222363. + *
  222364. + * @brief i.MX Asynchronous Sample Rate Converter
  222365. + *
  222366. + * @ingroup Audio
  222367. + */
  222368. +
  222369. +#ifndef __MXC_ASRC_H__
  222370. +#define __MXC_ASRC_H__
  222371. +
  222372. +#include <uapi/linux/mxc_asrc.h>
  222373. +#include <linux/scatterlist.h>
  222374. +
  222375. +#define ASRC_DMA_BUFFER_NUM 2
  222376. +#define ASRC_INPUTFIFO_THRESHOLD 32
  222377. +#define ASRC_OUTPUTFIFO_THRESHOLD 32
  222378. +#define ASRC_FIFO_THRESHOLD_MIN 0
  222379. +#define ASRC_FIFO_THRESHOLD_MAX 63
  222380. +#define ASRC_DMA_BUFFER_SIZE (1024 * 48 * 4)
  222381. +#define ASRC_MAX_BUFFER_SIZE (1024 * 48)
  222382. +#define ASRC_OUTPUT_LAST_SAMPLE_DEFAULT 8
  222383. +
  222384. +
  222385. +/* Ideal Ratio mode doesn't care the outclk frequency, so be fixed */
  222386. +#define ASRC_PRESCALER_IDEAL_RATIO 5
  222387. +/* SPDIF rxclk pulse rate is 128 * samplerate, so 2 ^ 7 */
  222388. +#define ASRC_PRESCALER_SPDIF_RX 7
  222389. +/* SPDIF txclk pulse rate is 64 * samplerate, so 2 ^ 6 */
  222390. +#define ASRC_PRESCALER_SPDIF_TX 6
  222391. +/* I2S bclk is 16 * 2 = 32, so 2 ^ 5 */
  222392. +#define ASRC_PRESCALER_I2S_16BIT 5
  222393. +/* I2S bclk is 24 * 2 = 48 -> 64, so 2 ^ 6 */
  222394. +#define ASRC_PRESCALER_I2S_24BIT 6
  222395. +
  222396. +
  222397. +#define REG_ASRCTR 0x00
  222398. +#define REG_ASRIER 0x04
  222399. +#define REG_ASRCNCR 0x0C
  222400. +#define REG_ASRCFG 0x10
  222401. +#define REG_ASRCSR 0x14
  222402. +
  222403. +#define REG_ASRCDR1 0x18
  222404. +#define REG_ASRCDR2 0x1C
  222405. +#define REG_ASRCDR(x) ((x < 2) ? REG_ASRCDR1 : REG_ASRCDR2)
  222406. +
  222407. +#define REG_ASRSTR 0x20
  222408. +#define REG_ASRRA 0x24
  222409. +#define REG_ASRRB 0x28
  222410. +#define REG_ASRRC 0x2C
  222411. +#define REG_ASRPM1 0x40
  222412. +#define REG_ASRPM2 0x44
  222413. +#define REG_ASRPM3 0x48
  222414. +#define REG_ASRPM4 0x4C
  222415. +#define REG_ASRPM5 0x50
  222416. +#define REG_ASRTFR1 0x54
  222417. +#define REG_ASRCCR 0x5C
  222418. +
  222419. +#define REG_ASRDIA 0x60
  222420. +#define REG_ASRDOA 0x64
  222421. +#define REG_ASRDIB 0x68
  222422. +#define REG_ASRDOB 0x6C
  222423. +#define REG_ASRDIC 0x70
  222424. +#define REG_ASRDOC 0x74
  222425. +#define REG_ASRDI(x) (REG_ASRDIA + (x << 3))
  222426. +#define REG_ASRDO(x) (REG_ASRDOA + (x << 3))
  222427. +
  222428. +#define REG_ASRIDRHA 0x80
  222429. +#define REG_ASRIDRLA 0x84
  222430. +#define REG_ASRIDRHB 0x88
  222431. +#define REG_ASRIDRLB 0x8C
  222432. +#define REG_ASRIDRHC 0x90
  222433. +#define REG_ASRIDRLC 0x94
  222434. +#define REG_ASRIDRH(x) (REG_ASRIDRHA + (x << 3))
  222435. +#define REG_ASRIDRL(x) (REG_ASRIDRLA + (x << 3))
  222436. +
  222437. +#define REG_ASR76K 0x98
  222438. +#define REG_ASR56K 0x9C
  222439. +
  222440. +#define REG_ASRMCRA 0xA0
  222441. +#define REG_ASRFSTA 0xA4
  222442. +#define REG_ASRMCRB 0xA8
  222443. +#define REG_ASRFSTB 0xAC
  222444. +#define REG_ASRMCRC 0xB0
  222445. +#define REG_ASRFSTC 0xB4
  222446. +#define REG_ASRMCR(x) (REG_ASRMCRA + (x << 3))
  222447. +#define REG_ASRFST(x) (REG_ASRFSTA + (x << 3))
  222448. +
  222449. +#define REG_ASRMCR1A 0xC0
  222450. +#define REG_ASRMCR1B 0xC4
  222451. +#define REG_ASRMCR1C 0xC8
  222452. +#define REG_ASRMCR1(x) (REG_ASRMCR1A + (x << 2))
  222453. +
  222454. +
  222455. +/* REG0 0x00 REG_ASRCTR */
  222456. +#define ASRCTR_ATSx_SHIFT(x) (20 + x)
  222457. +#define ASRCTR_ATSx_MASK(x) (1 << ASRCTR_ATSx_SHIFT(x))
  222458. +#define ASRCTR_ATS(x) (1 << ASRCTR_ATSx_SHIFT(x))
  222459. +#define ASRCTR_USRx_SHIFT(x) (14 + (x << 1))
  222460. +#define ASRCTR_USRx_MASK(x) (1 << ASRCTR_USRx_SHIFT(x))
  222461. +#define ASRCTR_USR(x) (1 << ASRCTR_USRx_SHIFT(x))
  222462. +#define ASRCTR_IDRx_SHIFT(x) (13 + (x << 1))
  222463. +#define ASRCTR_IDRx_MASK(x) (1 << ASRCTR_IDRx_SHIFT(x))
  222464. +#define ASRCTR_IDR(x) (1 << ASRCTR_IDRx_SHIFT(x))
  222465. +#define ASRCTR_SRST_SHIFT 4
  222466. +#define ASRCTR_SRST_MASK (1 << ASRCTR_SRST_SHIFT)
  222467. +#define ASRCTR_SRST (1 << ASRCTR_SRST_SHIFT)
  222468. +#define ASRCTR_ASRCEx_SHIFT(x) (1 + x)
  222469. +#define ASRCTR_ASRCEx_MASK(x) (1 << ASRCTR_ASRCEx_SHIFT(x))
  222470. +#define ASRCTR_ASRCE(x) (1 << ASRCTR_ASRCEx_SHIFT(x))
  222471. +#define ASRCTR_ASRCEN_SHIFT 0
  222472. +#define ASRCTR_ASRCEN_MASK (1 << ASRCTR_ASRCEN_SHIFT)
  222473. +#define ASRCTR_ASRCEN (1 << ASRCTR_ASRCEN_SHIFT)
  222474. +
  222475. +/* REG1 0x04 REG_ASRIER */
  222476. +#define ASRIER_AFPWE_SHIFT 7
  222477. +#define ASRIER_AFPWE_MASK (1 << ASRIER_AFPWE_SHIFT)
  222478. +#define ASRIER_AFPWE (1 << ASRIER_AFPWE_SHIFT)
  222479. +#define ASRIER_AOLIE_SHIFT 6
  222480. +#define ASRIER_AOLIE_MASK (1 << ASRIER_AOLIE_SHIFT)
  222481. +#define ASRIER_AOLIE (1 << ASRIER_AOLIE_SHIFT)
  222482. +#define ASRIER_ADOEx_SHIFT(x) (3 + x)
  222483. +#define ASRIER_ADOEx_MASK(x) (1 << ASRIER_ADOEx_SHIFT(x))
  222484. +#define ASRIER_ADOE(x) (1 << ASRIER_ADOEx_SHIFT(x))
  222485. +#define ASRIER_ADIEx_SHIFT(x) (0 + x)
  222486. +#define ASRIER_ADIEx_MASK(x) (1 << ASRIER_ADIEx_SHIFT(x))
  222487. +#define ASRIER_ADIE(x) (1 << ASRIER_ADIEx_SHIFT(x))
  222488. +
  222489. +/* REG2 0x0C REG_ASRCNCR */
  222490. +#define ASRCNCR_ANCx_SHIFT(x, b) (b * x)
  222491. +#define ASRCNCR_ANCx_MASK(x, b) (((1 << b) - 1) << ASRCNCR_ANCx_SHIFT(x, b))
  222492. +#define ASRCNCR_ANCx_get(x, v, b) ((v & ASRCNCR_ANCx_MASK(x, b)) >> ASRCNCR_ANCx_SHIFT(x, b))
  222493. +#define ASRCNCR_ANCx_set(x, v, b) ((v << ASRCNCR_ANCx_SHIFT(x, b)) & ASRCNCR_ANCx_MASK(x, b))
  222494. +
  222495. +/* REG3 0x10 REG_ASRCFG */
  222496. +#define ASRCFG_INIRQx_SHIFT(x) (21 + x)
  222497. +#define ASRCFG_INIRQx_MASK(x) (1 << ASRCFG_INIRQx_SHIFT(x))
  222498. +#define ASRCFG_INIRQx (1 << ASRCFG_INIRQx_SHIFT(x))
  222499. +#define ASRCFG_NDPRx_SHIFT(x) (18 + x)
  222500. +#define ASRCFG_NDPRx_MASK(x) (1 << ASRCFG_NDPRx_SHIFT(x))
  222501. +#define ASRCFG_NDPRx (1 << ASRCFG_NDPRx_SHIFT(x))
  222502. +#define ASRCFG_POSTMODx_SHIFT(x) (8 + (x << 2))
  222503. +#define ASRCFG_POSTMODx_WIDTH 2
  222504. +#define ASRCFG_POSTMODx_MASK(x) (((1 << ASRCFG_POSTMODx_WIDTH) - 1) << ASRCFG_POSTMODx_SHIFT(x))
  222505. +#define ASRCFG_POSTMOD(x, v) ((v) << ASRCFG_POSTMODx_SHIFT(x))
  222506. +#define ASRCFG_POSTMODx_UP(x) (0 << ASRCFG_POSTMODx_SHIFT(x))
  222507. +#define ASRCFG_POSTMODx_DCON(x) (1 << ASRCFG_POSTMODx_SHIFT(x))
  222508. +#define ASRCFG_POSTMODx_DOWN(x) (2 << ASRCFG_POSTMODx_SHIFT(x))
  222509. +#define ASRCFG_PREMODx_SHIFT(x) (6 + (x << 2))
  222510. +#define ASRCFG_PREMODx_WIDTH 2
  222511. +#define ASRCFG_PREMODx_MASK(x) (((1 << ASRCFG_PREMODx_WIDTH) - 1) << ASRCFG_PREMODx_SHIFT(x))
  222512. +#define ASRCFG_PREMOD(x, v) ((v) << ASRCFG_PREMODx_SHIFT(x))
  222513. +#define ASRCFG_PREMODx_UP(x) (0 << ASRCFG_PREMODx_SHIFT(x))
  222514. +#define ASRCFG_PREMODx_DCON(x) (1 << ASRCFG_PREMODx_SHIFT(x))
  222515. +#define ASRCFG_PREMODx_DOWN(x) (2 << ASRCFG_PREMODx_SHIFT(x))
  222516. +#define ASRCFG_PREMODx_BYPASS(x) (3 << ASRCFG_PREMODx_SHIFT(x))
  222517. +
  222518. +/* REG4 0x14 REG_ASRCSR */
  222519. +#define ASRCSR_AxCSx_WIDTH 4
  222520. +#define ASRCSR_AxCSx_MASK ((1 << ASRCSR_AxCSx_WIDTH) - 1)
  222521. +#define ASRCSR_AOCSx_SHIFT(x) (12 + (x << 2))
  222522. +#define ASRCSR_AOCSx_MASK(x) (((1 << ASRCSR_AxCSx_WIDTH) - 1) << ASRCSR_AOCSx_SHIFT(x))
  222523. +#define ASRCSR_AOCS(x, v) ((v) << ASRCSR_AOCSx_SHIFT(x))
  222524. +#define ASRCSR_AICSx_SHIFT(x) (x << 2)
  222525. +#define ASRCSR_AICSx_MASK(x) (((1 << ASRCSR_AxCSx_WIDTH) - 1) << ASRCSR_AICSx_SHIFT(x))
  222526. +#define ASRCSR_AICS(x, v) ((v) << ASRCSR_AICSx_SHIFT(x))
  222527. +
  222528. +/* REG5&6 0x18 & 0x1C REG_ASRCDR1 & ASRCDR2 */
  222529. +#define ASRCDRx_AxCPx_WIDTH 3
  222530. +#define ASRCDRx_AICPx_SHIFT(x) (0 + (x % 2) * 6)
  222531. +#define ASRCDRx_AICPx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AICPx_SHIFT(x))
  222532. +#define ASRCDRx_AICP(x, v) ((v) << ASRCDRx_AICPx_SHIFT(x))
  222533. +#define ASRCDRx_AICDx_SHIFT(x) (3 + (x % 2) * 6)
  222534. +#define ASRCDRx_AICDx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AICDx_SHIFT(x))
  222535. +#define ASRCDRx_AICD(x, v) ((v) << ASRCDRx_AICDx_SHIFT(x))
  222536. +#define ASRCDRx_AOCPx_SHIFT(x) ((x < 2) ? 12 + x * 6 : 6)
  222537. +#define ASRCDRx_AOCPx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AOCPx_SHIFT(x))
  222538. +#define ASRCDRx_AOCP(x, v) ((v) << ASRCDRx_AOCPx_SHIFT(x))
  222539. +#define ASRCDRx_AOCDx_SHIFT(x) ((x < 2) ? 15 + x * 6 : 9)
  222540. +#define ASRCDRx_AOCDx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AOCDx_SHIFT(x))
  222541. +#define ASRCDRx_AOCD(x, v) ((v) << ASRCDRx_AOCDx_SHIFT(x))
  222542. +
  222543. +/* REG7 0x20 REG_ASRSTR */
  222544. +#define ASRSTR_DSLCNT_SHIFT 21
  222545. +#define ASRSTR_DSLCNT_MASK (1 << ASRSTR_DSLCNT_SHIFT)
  222546. +#define ASRSTR_DSLCNT (1 << ASRSTR_DSLCNT_SHIFT)
  222547. +#define ASRSTR_ATQOL_SHIFT 20
  222548. +#define ASRSTR_ATQOL_MASK (1 << ASRSTR_ATQOL_SHIFT)
  222549. +#define ASRSTR_ATQOL (1 << ASRSTR_ATQOL_SHIFT)
  222550. +#define ASRSTR_AOOLx_SHIFT(x) (17 + x)
  222551. +#define ASRSTR_AOOLx_MASK(x) (1 << ASRSTR_AOOLx_SHIFT(x))
  222552. +#define ASRSTR_AOOL(x) (1 << ASRSTR_AOOLx_SHIFT(x))
  222553. +#define ASRSTR_AIOLx_SHIFT(x) (14 + x)
  222554. +#define ASRSTR_AIOLx_MASK(x) (1 << ASRSTR_AIOLx_SHIFT(x))
  222555. +#define ASRSTR_AIOL(x) (1 << ASRSTR_AIOLx_SHIFT(x))
  222556. +#define ASRSTR_AODOx_SHIFT(x) (11 + x)
  222557. +#define ASRSTR_AODOx_MASK(x) (1 << ASRSTR_AODOx_SHIFT(x))
  222558. +#define ASRSTR_AODO(x) (1 << ASRSTR_AODOx_SHIFT(x))
  222559. +#define ASRSTR_AIDUx_SHIFT(x) (8 + x)
  222560. +#define ASRSTR_AIDUx_MASK(x) (1 << ASRSTR_AIDUx_SHIFT(x))
  222561. +#define ASRSTR_AIDU(x) (1 << ASRSTR_AIDUx_SHIFT(x))
  222562. +#define ASRSTR_FPWT_SHIFT 7
  222563. +#define ASRSTR_FPWT_MASK (1 << ASRSTR_FPWT_SHIFT)
  222564. +#define ASRSTR_FPWT (1 << ASRSTR_FPWT_SHIFT)
  222565. +#define ASRSTR_AOLE_SHIFT 6
  222566. +#define ASRSTR_AOLE_MASK (1 << ASRSTR_AOLE_SHIFT)
  222567. +#define ASRSTR_AOLE (1 << ASRSTR_AOLE_SHIFT)
  222568. +#define ASRSTR_AODEx_SHIFT(x) (3 + x)
  222569. +#define ASRSTR_AODFx_MASK(x) (1 << ASRSTR_AODEx_SHIFT(x))
  222570. +#define ASRSTR_AODF(x) (1 << ASRSTR_AODEx_SHIFT(x))
  222571. +#define ASRSTR_AIDEx_SHIFT(x) (0 + x)
  222572. +#define ASRSTR_AIDEx_MASK(x) (1 << ASRSTR_AIDEx_SHIFT(x))
  222573. +#define ASRSTR_AIDE(x) (1 << ASRSTR_AIDEx_SHIFT(x))
  222574. +
  222575. +/* REG10 0x54 REG_ASRTFR1 */
  222576. +#define ASRTFR1_TF_BASE_WIDTH 7
  222577. +#define ASRTFR1_TF_BASE_SHIFT 6
  222578. +#define ASRTFR1_TF_BASE_MASK (((1 << ASRTFR1_TF_BASE_WIDTH) - 1) << ASRTFR1_TF_BASE_SHIFT)
  222579. +#define ASRTFR1_TF_BASE(x) ((x) << ASRTFR1_TF_BASE_SHIFT)
  222580. +
  222581. +/*
  222582. + * REG22 0xA0 REG_ASRMCRA
  222583. + * REG24 0xA8 REG_ASRMCRB
  222584. + * REG26 0xB0 REG_ASRMCRC
  222585. + */
  222586. +#define ASRMCRx_ZEROBUFx_SHIFT 23
  222587. +#define ASRMCRx_ZEROBUFxCLR_MASK (1 << ASRMCRx_ZEROBUFx_SHIFT)
  222588. +#define ASRMCRx_ZEROBUFxCLR (1 << ASRMCRx_ZEROBUFx_SHIFT)
  222589. +#define ASRMCRx_EXTTHRSHx_SHIFT 22
  222590. +#define ASRMCRx_EXTTHRSHx_MASK (1 << ASRMCRx_EXTTHRSHx_SHIFT)
  222591. +#define ASRMCRx_EXTTHRSHx (1 << ASRMCRx_EXTTHRSHx_SHIFT)
  222592. +#define ASRMCRx_BUFSTALLx_SHIFT 21
  222593. +#define ASRMCRx_BUFSTALLx_MASK (1 << ASRMCRx_BUFSTALLx_SHIFT)
  222594. +#define ASRMCRx_BUFSTALLx (1 << ASRMCRx_BUFSTALLx_SHIFT)
  222595. +#define ASRMCRx_BYPASSPOLYx_SHIFT 20
  222596. +#define ASRMCRx_BYPASSPOLYx_MASK (1 << ASRMCRx_BYPASSPOLYx_SHIFT)
  222597. +#define ASRMCRx_BYPASSPOLYx (1 << ASRMCRx_BYPASSPOLYx_SHIFT)
  222598. +#define ASRMCRx_OUTFIFO_THRESHOLD_WIDTH 6
  222599. +#define ASRMCRx_OUTFIFO_THRESHOLD_SHIFT 12
  222600. +#define ASRMCRx_OUTFIFO_THRESHOLD_MASK (((1 << ASRMCRx_OUTFIFO_THRESHOLD_WIDTH) - 1) << ASRMCRx_OUTFIFO_THRESHOLD_SHIFT)
  222601. +#define ASRMCRx_OUTFIFO_THRESHOLD(v) (((v) << ASRMCRx_OUTFIFO_THRESHOLD_SHIFT) & ASRMCRx_OUTFIFO_THRESHOLD_MASK)
  222602. +#define ASRMCRx_RSYNIFx_SHIFT 11
  222603. +#define ASRMCRx_RSYNIFx_MASK (1 << ASRMCRx_RSYNIFx_SHIFT)
  222604. +#define ASRMCRx_RSYNIFx (1 << ASRMCRx_RSYNIFx_SHIFT)
  222605. +#define ASRMCRx_RSYNOFx_SHIFT 10
  222606. +#define ASRMCRx_RSYNOFx_MASK (1 << ASRMCRx_RSYNOFx_SHIFT)
  222607. +#define ASRMCRx_RSYNOFx (1 << ASRMCRx_RSYNOFx_SHIFT)
  222608. +#define ASRMCRx_INFIFO_THRESHOLD_WIDTH 6
  222609. +#define ASRMCRx_INFIFO_THRESHOLD_SHIFT 0
  222610. +#define ASRMCRx_INFIFO_THRESHOLD_MASK (((1 << ASRMCRx_INFIFO_THRESHOLD_WIDTH) - 1) << ASRMCRx_INFIFO_THRESHOLD_SHIFT)
  222611. +#define ASRMCRx_INFIFO_THRESHOLD(v) (((v) << ASRMCRx_INFIFO_THRESHOLD_SHIFT) & ASRMCRx_INFIFO_THRESHOLD_MASK)
  222612. +
  222613. +/*
  222614. + * REG23 0xA4 REG_ASRFSTA
  222615. + * REG25 0xAC REG_ASRFSTB
  222616. + * REG27 0xB4 REG_ASRFSTC
  222617. + */
  222618. +#define ASRFSTx_OAFx_SHIFT 23
  222619. +#define ASRFSTx_OAFx_MASK (1 << ASRFSTx_OAFx_SHIFT)
  222620. +#define ASRFSTx_OAFx (1 << ASRFSTx_OAFx_SHIFT)
  222621. +#define ASRFSTx_OUTPUT_FIFO_WIDTH 7
  222622. +#define ASRFSTx_OUTPUT_FIFO_SHIFT 12
  222623. +#define ASRFSTx_OUTPUT_FIFO_MASK (((1 << ASRFSTx_OUTPUT_FIFO_WIDTH) - 1) << ASRFSTx_OUTPUT_FIFO_SHIFT)
  222624. +#define ASRFSTx_IAEx_SHIFT 11
  222625. +#define ASRFSTx_IAEx_MASK (1 << ASRFSTx_OAFx_SHIFT)
  222626. +#define ASRFSTx_IAEx (1 << ASRFSTx_OAFx_SHIFT)
  222627. +#define ASRFSTx_INPUT_FIFO_WIDTH 7
  222628. +#define ASRFSTx_INPUT_FIFO_SHIFT 0
  222629. +#define ASRFSTx_INPUT_FIFO_MASK ((1 << ASRFSTx_INPUT_FIFO_WIDTH) - 1)
  222630. +
  222631. +/* REG28 0xC0 & 0xC4 & 0xC8 REG_ASRMCR1x */
  222632. +#define ASRMCR1x_IWD_WIDTH 3
  222633. +#define ASRMCR1x_IWD_SHIFT 9
  222634. +#define ASRMCR1x_IWD_MASK (((1 << ASRMCR1x_IWD_WIDTH) - 1) << ASRMCR1x_IWD_SHIFT)
  222635. +#define ASRMCR1x_IWD(v) ((v) << ASRMCR1x_IWD_SHIFT)
  222636. +#define ASRMCR1x_IMSB_SHIFT 8
  222637. +#define ASRMCR1x_IMSB_MASK (1 << ASRMCR1x_IMSB_SHIFT)
  222638. +#define ASRMCR1x_IMSB_MSB (1 << ASRMCR1x_IMSB_SHIFT)
  222639. +#define ASRMCR1x_IMSB_LSB (0 << ASRMCR1x_IMSB_SHIFT)
  222640. +#define ASRMCR1x_OMSB_SHIFT 2
  222641. +#define ASRMCR1x_OMSB_MASK (1 << ASRMCR1x_OMSB_SHIFT)
  222642. +#define ASRMCR1x_OMSB_MSB (1 << ASRMCR1x_OMSB_SHIFT)
  222643. +#define ASRMCR1x_OMSB_LSB (0 << ASRMCR1x_OMSB_SHIFT)
  222644. +#define ASRMCR1x_OSGN_SHIFT 1
  222645. +#define ASRMCR1x_OSGN_MASK (1 << ASRMCR1x_OSGN_SHIFT)
  222646. +#define ASRMCR1x_OSGN (1 << ASRMCR1x_OSGN_SHIFT)
  222647. +#define ASRMCR1x_OW16_SHIFT 0
  222648. +#define ASRMCR1x_OW16_MASK (1 << ASRMCR1x_OW16_SHIFT)
  222649. +#define ASRMCR1x_OW16(v) ((v) << ASRMCR1x_OW16_SHIFT)
  222650. +
  222651. +
  222652. +struct dma_block {
  222653. + unsigned int index;
  222654. + unsigned int length;
  222655. + void *dma_vaddr;
  222656. + dma_addr_t dma_paddr;
  222657. + struct list_head queue;
  222658. +};
  222659. +
  222660. +struct asrc_p2p_params {
  222661. + u32 p2p_rate; /* ASRC output rate for p2p */
  222662. + enum asrc_word_width p2p_width; /* ASRC output wordwidth for p2p */
  222663. +};
  222664. +
  222665. +struct asrc_pair_params {
  222666. + enum asrc_pair_index index;
  222667. + struct completion input_complete;
  222668. + struct completion output_complete;
  222669. + struct completion lastperiod_complete;
  222670. + struct dma_chan *input_dma_channel;
  222671. + struct dma_chan *output_dma_channel;
  222672. + unsigned int input_buffer_size;
  222673. + unsigned int output_buffer_size;
  222674. + unsigned int buffer_num;
  222675. + unsigned int pair_hold;
  222676. + unsigned int asrc_active;
  222677. + unsigned int channel_nums;
  222678. + struct dma_block input_dma_total;
  222679. + struct dma_block input_dma[ASRC_DMA_BUFFER_NUM];
  222680. + struct dma_block output_dma_total;
  222681. + struct dma_block output_dma[ASRC_DMA_BUFFER_NUM];
  222682. + struct dma_block output_last_period;
  222683. + struct dma_async_tx_descriptor *desc_in;
  222684. + struct dma_async_tx_descriptor *desc_out;
  222685. + struct work_struct task_output_work;
  222686. + unsigned int input_sg_nodes;
  222687. + unsigned int output_sg_nodes;
  222688. + struct scatterlist input_sg[4], output_sg[4];
  222689. + enum asrc_word_width input_word_width;
  222690. + enum asrc_word_width output_word_width;
  222691. + u32 input_sample_rate;
  222692. + u32 output_sample_rate;
  222693. + u32 input_wm;
  222694. + u32 output_wm;
  222695. + unsigned int last_period_sample;
  222696. +};
  222697. +
  222698. +struct asrc_data {
  222699. + struct asrc_pair asrc_pair[ASRC_PAIR_MAX_NUM];
  222700. + struct proc_dir_entry *proc_asrc;
  222701. + struct class *asrc_class;
  222702. + struct regmap *regmap;
  222703. + struct clk *asrc_clk;
  222704. + struct clk *dma_clk;
  222705. + unsigned long paddr;
  222706. + unsigned int channel_bits;
  222707. + int asrc_major;
  222708. + int irq;
  222709. + struct device *dev;
  222710. +};
  222711. +
  222712. +struct asrc_p2p_ops {
  222713. + void (*asrc_p2p_start_conv)(enum asrc_pair_index);
  222714. + void (*asrc_p2p_stop_conv)(enum asrc_pair_index);
  222715. + int (*asrc_p2p_get_dma_request)(enum asrc_pair_index, bool);
  222716. + u32 (*asrc_p2p_per_addr)(enum asrc_pair_index, bool);
  222717. + int (*asrc_p2p_req_pair)(int, enum asrc_pair_index *index);
  222718. + int (*asrc_p2p_config_pair)(struct asrc_config *config);
  222719. + void (*asrc_p2p_release_pair)(enum asrc_pair_index);
  222720. + void (*asrc_p2p_finish_conv)(enum asrc_pair_index);
  222721. +};
  222722. +
  222723. +extern void asrc_p2p_hook(struct asrc_p2p_ops *asrc_p2p_ct);
  222724. +
  222725. +extern int asrc_req_pair(int chn_num, enum asrc_pair_index *index);
  222726. +extern void asrc_release_pair(enum asrc_pair_index index);
  222727. +extern int asrc_config_pair(struct asrc_config *config);
  222728. +extern void asrc_get_status(struct asrc_status_flags *flags);
  222729. +extern void asrc_start_conv(enum asrc_pair_index index);
  222730. +extern void asrc_stop_conv(enum asrc_pair_index index);
  222731. +extern u32 asrc_get_per_addr(enum asrc_pair_index index, bool i);
  222732. +extern int asrc_get_dma_request(enum asrc_pair_index index, bool i);
  222733. +extern void asrc_finish_conv(enum asrc_pair_index index);
  222734. +extern int asrc_set_watermark(enum asrc_pair_index index,
  222735. + u32 in_wm, u32 out_wm);
  222736. +
  222737. +#endif/* __MXC_ASRC_H__ */
  222738. diff -Nur linux-3.14.14/include/linux/mxcfb.h linux-imx6-3.14/include/linux/mxcfb.h
  222739. --- linux-3.14.14/include/linux/mxcfb.h 1969-12-31 18:00:00.000000000 -0600
  222740. +++ linux-imx6-3.14/include/linux/mxcfb.h 2014-12-08 00:31:55.320418001 -0600
  222741. @@ -0,0 +1,46 @@
  222742. +/*
  222743. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  222744. + */
  222745. +
  222746. +/*
  222747. + * The code contained herein is licensed under the GNU Lesser General
  222748. + * Public License. You may obtain a copy of the GNU Lesser General
  222749. + * Public License Version 2.1 or later at the following locations:
  222750. + *
  222751. + * http://www.opensource.org/licenses/lgpl-license.html
  222752. + * http://www.gnu.org/copyleft/lgpl.html
  222753. + */
  222754. +
  222755. +/*
  222756. + * @file linux/mxcfb.h
  222757. + *
  222758. + * @brief Global header file for the MXC Frame buffer
  222759. + *
  222760. + * @ingroup Framebuffer
  222761. + */
  222762. +#ifndef __LINUX_MXCFB_H__
  222763. +#define __LINUX_MXCFB_H__
  222764. +
  222765. +#include <uapi/linux/mxcfb.h>
  222766. +
  222767. +extern struct fb_videomode mxcfb_modedb[];
  222768. +extern int mxcfb_modedb_sz;
  222769. +
  222770. +enum {
  222771. + MXC_DISP_SPEC_DEV = 0,
  222772. + MXC_DISP_DDC_DEV = 1,
  222773. +};
  222774. +
  222775. +enum {
  222776. + MXCFB_REFRESH_OFF,
  222777. + MXCFB_REFRESH_AUTO,
  222778. + MXCFB_REFRESH_PARTIAL,
  222779. +};
  222780. +
  222781. +int mxcfb_set_refresh_mode(struct fb_info *fbi, int mode,
  222782. + struct mxcfb_rect *update_region);
  222783. +int mxc_elcdif_frame_addr_setup(dma_addr_t phys);
  222784. +void mxcfb_elcdif_register_mode(const struct fb_videomode *modedb,
  222785. + int num_modes, int dev_mode);
  222786. +
  222787. +#endif
  222788. diff -Nur linux-3.14.14/include/linux/mxc_mlb.h linux-imx6-3.14/include/linux/mxc_mlb.h
  222789. --- linux-3.14.14/include/linux/mxc_mlb.h 1969-12-31 18:00:00.000000000 -0600
  222790. +++ linux-imx6-3.14/include/linux/mxc_mlb.h 2014-12-08 00:31:55.320418001 -0600
  222791. @@ -0,0 +1,55 @@
  222792. +/*
  222793. + * mxc_mlb.h
  222794. + *
  222795. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  222796. + */
  222797. +
  222798. +/*
  222799. + * The code contained herein is licensed under the GNU General Public
  222800. + * License. You may obtain a copy of the GNU General Public License
  222801. + * Version 2 or later at the following locations:
  222802. + *
  222803. + * http://www.opensource.org/licenses/gpl-license.html
  222804. + * http://www.gnu.org/copyleft/gpl.html
  222805. + */
  222806. +
  222807. +#ifndef _MXC_MLB_H
  222808. +#define _MXC_MLB_H
  222809. +
  222810. +/* define IOCTL command */
  222811. +#define MLB_DBG_RUNTIME _IO('S', 0x09)
  222812. +#define MLB_SET_FPS _IOW('S', 0x10, unsigned int)
  222813. +#define MLB_GET_VER _IOR('S', 0x11, unsigned long)
  222814. +#define MLB_SET_DEVADDR _IOR('S', 0x12, unsigned char)
  222815. +
  222816. +/*!
  222817. + * set channel address for each logical channel
  222818. + * the MSB 16bits is for tx channel, the left LSB is for rx channel
  222819. + */
  222820. +#define MLB_CHAN_SETADDR _IOW('S', 0x13, unsigned int)
  222821. +#define MLB_CHAN_STARTUP _IO('S', 0x14)
  222822. +#define MLB_CHAN_SHUTDOWN _IO('S', 0x15)
  222823. +#define MLB_CHAN_GETEVENT _IOR('S', 0x16, unsigned long)
  222824. +
  222825. +#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
  222826. +#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
  222827. +#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
  222828. +#define MLB_IRQ_ENABLE _IO('S', 0x20)
  222829. +#define MLB_IRQ_DISABLE _IO('S', 0x21)
  222830. +
  222831. +/*!
  222832. + * MLB event define
  222833. + */
  222834. +enum {
  222835. + MLB_EVT_TX_PROTO_ERR_CUR = 1 << 0,
  222836. + MLB_EVT_TX_BRK_DETECT_CUR = 1 << 1,
  222837. + MLB_EVT_TX_PROTO_ERR_PREV = 1 << 8,
  222838. + MLB_EVT_TX_BRK_DETECT_PREV = 1 << 9,
  222839. + MLB_EVT_RX_PROTO_ERR_CUR = 1 << 16,
  222840. + MLB_EVT_RX_BRK_DETECT_CUR = 1 << 17,
  222841. + MLB_EVT_RX_PROTO_ERR_PREV = 1 << 24,
  222842. + MLB_EVT_RX_BRK_DETECT_PREV = 1 << 25,
  222843. +};
  222844. +
  222845. +
  222846. +#endif /* _MXC_MLB_H */
  222847. diff -Nur linux-3.14.14/include/linux/mxc_v4l2.h linux-imx6-3.14/include/linux/mxc_v4l2.h
  222848. --- linux-3.14.14/include/linux/mxc_v4l2.h 1969-12-31 18:00:00.000000000 -0600
  222849. +++ linux-imx6-3.14/include/linux/mxc_v4l2.h 2014-12-08 00:31:55.320418001 -0600
  222850. @@ -0,0 +1,27 @@
  222851. +/*
  222852. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  222853. + */
  222854. +
  222855. +/*
  222856. + * The code contained herein is licensed under the GNU Lesser General
  222857. + * Public License. You may obtain a copy of the GNU Lesser General
  222858. + * Public License Version 2.1 or later at the following locations:
  222859. + *
  222860. + * http://www.opensource.org/licenses/lgpl-license.html
  222861. + * http://www.gnu.org/copyleft/lgpl.html
  222862. + */
  222863. +
  222864. +/*!
  222865. + * @file linux/mxc_v4l2.h
  222866. + *
  222867. + * @brief MXC V4L2 private header file
  222868. + *
  222869. + * @ingroup MXC V4L2
  222870. + */
  222871. +
  222872. +#ifndef __LINUX_MXC_V4L2_H__
  222873. +#define __LINUX_MXC_V4L2_H__
  222874. +
  222875. +#include <uapi/linux/mxc_v4l2.h>
  222876. +
  222877. +#endif
  222878. diff -Nur linux-3.14.14/include/linux/mxc_vpu.h linux-imx6-3.14/include/linux/mxc_vpu.h
  222879. --- linux-3.14.14/include/linux/mxc_vpu.h 1969-12-31 18:00:00.000000000 -0600
  222880. +++ linux-imx6-3.14/include/linux/mxc_vpu.h 2014-12-08 00:31:55.320418001 -0600
  222881. @@ -0,0 +1,118 @@
  222882. +/*
  222883. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  222884. + */
  222885. +
  222886. +/*
  222887. + * The code contained herein is licensed under the GNU Lesser General
  222888. + * Public License. You may obtain a copy of the GNU Lesser General
  222889. + * Public License Version 2.1 or later at the following locations:
  222890. + *
  222891. + * http://www.opensource.org/licenses/lgpl-license.html
  222892. + * http://www.gnu.org/copyleft/lgpl.html
  222893. + */
  222894. +
  222895. +/*!
  222896. + * @defgroup VPU Video Processor Unit Driver
  222897. + */
  222898. +
  222899. +/*!
  222900. + * @file linux/mxc_vpu.h
  222901. + *
  222902. + * @brief VPU system initialization and file operation definition
  222903. + *
  222904. + * @ingroup VPU
  222905. + */
  222906. +
  222907. +#ifndef __LINUX_MXC_VPU_H__
  222908. +#define __LINUX_MXC_VPU_H__
  222909. +
  222910. +#include <linux/fs.h>
  222911. +
  222912. +struct mxc_vpu_platform_data {
  222913. + bool iram_enable;
  222914. + int iram_size;
  222915. + void (*reset) (void);
  222916. + void (*pg) (int);
  222917. +};
  222918. +
  222919. +struct vpu_mem_desc {
  222920. + u32 size;
  222921. + dma_addr_t phy_addr;
  222922. + u32 cpu_addr; /* cpu address to free the dma mem */
  222923. + u32 virt_uaddr; /* virtual user space address */
  222924. +};
  222925. +
  222926. +#define VPU_IOC_MAGIC 'V'
  222927. +
  222928. +#define VPU_IOC_PHYMEM_ALLOC _IO(VPU_IOC_MAGIC, 0)
  222929. +#define VPU_IOC_PHYMEM_FREE _IO(VPU_IOC_MAGIC, 1)
  222930. +#define VPU_IOC_WAIT4INT _IO(VPU_IOC_MAGIC, 2)
  222931. +#define VPU_IOC_PHYMEM_DUMP _IO(VPU_IOC_MAGIC, 3)
  222932. +#define VPU_IOC_REG_DUMP _IO(VPU_IOC_MAGIC, 4)
  222933. +#define VPU_IOC_IRAM_SETTING _IO(VPU_IOC_MAGIC, 6)
  222934. +#define VPU_IOC_CLKGATE_SETTING _IO(VPU_IOC_MAGIC, 7)
  222935. +#define VPU_IOC_GET_WORK_ADDR _IO(VPU_IOC_MAGIC, 8)
  222936. +#define VPU_IOC_REQ_VSHARE_MEM _IO(VPU_IOC_MAGIC, 9)
  222937. +#define VPU_IOC_SYS_SW_RESET _IO(VPU_IOC_MAGIC, 11)
  222938. +#define VPU_IOC_GET_SHARE_MEM _IO(VPU_IOC_MAGIC, 12)
  222939. +#define VPU_IOC_QUERY_BITWORK_MEM _IO(VPU_IOC_MAGIC, 13)
  222940. +#define VPU_IOC_SET_BITWORK_MEM _IO(VPU_IOC_MAGIC, 14)
  222941. +#define VPU_IOC_PHYMEM_CHECK _IO(VPU_IOC_MAGIC, 15)
  222942. +#define VPU_IOC_LOCK_DEV _IO(VPU_IOC_MAGIC, 16)
  222943. +
  222944. +#define BIT_CODE_RUN 0x000
  222945. +#define BIT_CODE_DOWN 0x004
  222946. +#define BIT_INT_CLEAR 0x00C
  222947. +#define BIT_INT_STATUS 0x010
  222948. +#define BIT_CUR_PC 0x018
  222949. +#define BIT_INT_REASON 0x174
  222950. +
  222951. +#define MJPEG_PIC_STATUS_REG 0x3004
  222952. +#define MBC_SET_SUBBLK_EN 0x4A0
  222953. +
  222954. +#define BIT_WORK_CTRL_BUF_BASE 0x100
  222955. +#define BIT_WORK_CTRL_BUF_REG(i) (BIT_WORK_CTRL_BUF_BASE + i * 4)
  222956. +#define BIT_CODE_BUF_ADDR BIT_WORK_CTRL_BUF_REG(0)
  222957. +#define BIT_WORK_BUF_ADDR BIT_WORK_CTRL_BUF_REG(1)
  222958. +#define BIT_PARA_BUF_ADDR BIT_WORK_CTRL_BUF_REG(2)
  222959. +#define BIT_BIT_STREAM_CTRL BIT_WORK_CTRL_BUF_REG(3)
  222960. +#define BIT_FRAME_MEM_CTRL BIT_WORK_CTRL_BUF_REG(4)
  222961. +#define BIT_BIT_STREAM_PARAM BIT_WORK_CTRL_BUF_REG(5)
  222962. +
  222963. +#ifndef CONFIG_SOC_IMX6Q
  222964. +#define BIT_RESET_CTRL 0x11C
  222965. +#else
  222966. +#define BIT_RESET_CTRL 0x128
  222967. +#endif
  222968. +
  222969. +/* i could be 0, 1, 2, 3 */
  222970. +#define BIT_RD_PTR_BASE 0x120
  222971. +#define BIT_RD_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8)
  222972. +#define BIT_WR_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8 + 4)
  222973. +
  222974. +/* i could be 0, 1, 2, 3 */
  222975. +#define BIT_FRM_DIS_FLG_BASE (cpu_is_mx51() ? 0x150 : 0x140)
  222976. +#define BIT_FRM_DIS_FLG_REG(i) (BIT_FRM_DIS_FLG_BASE + i * 4)
  222977. +
  222978. +#define BIT_BUSY_FLAG 0x160
  222979. +#define BIT_RUN_COMMAND 0x164
  222980. +#define BIT_INT_ENABLE 0x170
  222981. +
  222982. +#define BITVAL_PIC_RUN 8
  222983. +
  222984. +#define VPU_SLEEP_REG_VALUE 10
  222985. +#define VPU_WAKE_REG_VALUE 11
  222986. +
  222987. +int vl2cc_init(u32 vl2cc_hw_base);
  222988. +void vl2cc_enable(void);
  222989. +void vl2cc_flush(void);
  222990. +void vl2cc_disable(void);
  222991. +void vl2cc_cleanup(void);
  222992. +
  222993. +int vl2cc_init(u32 vl2cc_hw_base);
  222994. +void vl2cc_enable(void);
  222995. +void vl2cc_flush(void);
  222996. +void vl2cc_disable(void);
  222997. +void vl2cc_cleanup(void);
  222998. +
  222999. +#endif
  223000. diff -Nur linux-3.14.14/include/linux/phy.h linux-imx6-3.14/include/linux/phy.h
  223001. --- linux-3.14.14/include/linux/phy.h 2014-07-28 10:07:25.000000000 -0500
  223002. +++ linux-imx6-3.14/include/linux/phy.h 2014-12-08 00:31:55.332418001 -0600
  223003. @@ -609,6 +609,7 @@
  223004. return phydev->drv->read_status(phydev);
  223005. }
  223006. +int genphy_config_init(struct phy_device *phydev);
  223007. int genphy_setup_forced(struct phy_device *phydev);
  223008. int genphy_restart_aneg(struct phy_device *phydev);
  223009. int genphy_config_aneg(struct phy_device *phydev);
  223010. diff -Nur linux-3.14.14/include/linux/pipe_fs_i.h linux-imx6-3.14/include/linux/pipe_fs_i.h
  223011. --- linux-3.14.14/include/linux/pipe_fs_i.h 2014-07-28 10:07:25.000000000 -0500
  223012. +++ linux-imx6-3.14/include/linux/pipe_fs_i.h 2014-12-08 00:31:55.332418001 -0600
  223013. @@ -35,7 +35,7 @@
  223014. * @tmp_page: cached released page
  223015. * @readers: number of current readers of this pipe
  223016. * @writers: number of current writers of this pipe
  223017. - * @files: number of struct file refering this pipe (protected by ->i_lock)
  223018. + * @files: number of struct file referring this pipe (protected by ->i_lock)
  223019. * @waiting_writers: number of writers blocked waiting for room
  223020. * @r_counter: reader counter
  223021. * @w_counter: writer counter
  223022. diff -Nur linux-3.14.14/include/linux/pl320-ipc.h linux-imx6-3.14/include/linux/pl320-ipc.h
  223023. --- linux-3.14.14/include/linux/pl320-ipc.h 1969-12-31 18:00:00.000000000 -0600
  223024. +++ linux-imx6-3.14/include/linux/pl320-ipc.h 2014-12-08 00:31:55.332418001 -0600
  223025. @@ -0,0 +1,17 @@
  223026. +/*
  223027. + * This program is free software; you can redistribute it and/or modify it
  223028. + * under the terms and conditions of the GNU General Public License,
  223029. + * version 2, as published by the Free Software Foundation.
  223030. + *
  223031. + * This program is distributed in the hope it will be useful, but WITHOUT
  223032. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  223033. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  223034. + * more details.
  223035. + *
  223036. + * You should have received a copy of the GNU General Public License along with
  223037. + * this program. If not, see <http://www.gnu.org/licenses/>.
  223038. + */
  223039. +
  223040. +int pl320_ipc_transmit(u32 *data);
  223041. +int pl320_ipc_register_notifier(struct notifier_block *nb);
  223042. +int pl320_ipc_unregister_notifier(struct notifier_block *nb);
  223043. diff -Nur linux-3.14.14/include/linux/platform_data/dma-imx.h linux-imx6-3.14/include/linux/platform_data/dma-imx.h
  223044. --- linux-3.14.14/include/linux/platform_data/dma-imx.h 2014-07-28 10:07:25.000000000 -0500
  223045. +++ linux-imx6-3.14/include/linux/platform_data/dma-imx.h 2014-12-08 00:31:55.336418001 -0600
  223046. @@ -1,5 +1,5 @@
  223047. /*
  223048. - * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
  223049. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  223050. *
  223051. * This program is free software; you can redistribute it and/or modify
  223052. * it under the terms of the GNU General Public License version 2 as
  223053. @@ -40,6 +40,7 @@
  223054. IMX_DMATYPE_ASRC, /* ASRC */
  223055. IMX_DMATYPE_ESAI, /* ESAI */
  223056. IMX_DMATYPE_SSI_DUAL, /* SSI Dual FIFO */
  223057. + IMX_DMATYPE_HDMI, /* HDMI Audio */
  223058. };
  223059. enum imx_dma_prio {
  223060. @@ -49,9 +50,11 @@
  223061. };
  223062. struct imx_dma_data {
  223063. - int dma_request; /* DMA request line */
  223064. + int dma_request0; /* DMA request line */
  223065. + int dma_request1;
  223066. enum sdma_peripheral_type peripheral_type;
  223067. int priority;
  223068. + void *data_addr1, *data_addr2;
  223069. };
  223070. static inline int imx_dma_is_ipu(struct dma_chan *chan)
  223071. @@ -59,6 +62,11 @@
  223072. return !strcmp(dev_name(chan->device->dev), "ipu-core");
  223073. }
  223074. +static inline int imx_dma_is_pxp(struct dma_chan *chan)
  223075. +{
  223076. + return strstr(dev_name(chan->device->dev), "pxp") != NULL;
  223077. +}
  223078. +
  223079. static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
  223080. {
  223081. return !strcmp(chan->device->dev->driver->name, "imx-sdma") ||
  223082. diff -Nur linux-3.14.14/include/linux/power/imx6_usb_charger.h linux-imx6-3.14/include/linux/power/imx6_usb_charger.h
  223083. --- linux-3.14.14/include/linux/power/imx6_usb_charger.h 1969-12-31 18:00:00.000000000 -0600
  223084. +++ linux-imx6-3.14/include/linux/power/imx6_usb_charger.h 2014-12-08 00:31:55.344418001 -0600
  223085. @@ -0,0 +1,80 @@
  223086. +/*
  223087. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  223088. + *
  223089. + * The code contained herein is licensed under the GNU General Public
  223090. + * License. You may obtain a copy of the GNU General Public License
  223091. + * Version 2 or later at the following locations:
  223092. + *
  223093. + * http://www.opensource.org/licenses/gpl-license.html
  223094. + * http://www.gnu.org/copyleft/gpl.html
  223095. + */
  223096. +
  223097. +#ifndef __IMXUSB6_CHARGER_H
  223098. +#define __IMXUSB6_CHARGER_H
  223099. +
  223100. +#include <linux/power_supply.h>
  223101. +enum battery_charging_spec {
  223102. + BATTERY_CHARGING_SPEC_NONE = 0,
  223103. + BATTERY_CHARGING_SPEC_UNKNOWN,
  223104. + BATTERY_CHARGING_SPEC_1_0,
  223105. + BATTERY_CHARGING_SPEC_1_1,
  223106. + BATTERY_CHARGING_SPEC_1_2,
  223107. +};
  223108. +
  223109. +struct usb_charger {
  223110. + /* The anatop regmap */
  223111. + struct regmap *anatop;
  223112. + /* USB controller */
  223113. + struct device *dev;
  223114. + struct power_supply psy;
  223115. + struct mutex lock;
  223116. +
  223117. + /* Compliant with Battery Charging Specification version (if any) */
  223118. + enum battery_charging_spec bc;
  223119. +
  223120. + /* properties */
  223121. + unsigned present:1;
  223122. + unsigned online:1;
  223123. + unsigned max_current;
  223124. + int (*connect)(struct usb_charger *charger);
  223125. + int (*disconnect)(struct usb_charger *charger);
  223126. + int (*set_power)(struct usb_charger *charger, unsigned mA);
  223127. +
  223128. + int (*detect)(struct usb_charger *charger);
  223129. +};
  223130. +
  223131. +#ifdef CONFIG_IMX6_USB_CHARGER
  223132. +extern void imx6_usb_remove_charger(struct usb_charger *charger);
  223133. +extern int imx6_usb_create_charger(struct usb_charger *charger,
  223134. + const char *name);
  223135. +extern int imx6_usb_vbus_disconnect(struct usb_charger *charger);
  223136. +extern int imx6_usb_vbus_connect(struct usb_charger *charger);
  223137. +extern int imx6_usb_charger_detect_post(struct usb_charger *charger);
  223138. +#else
  223139. +void imx6_usb_remove_charger(struct usb_charger *charger)
  223140. +{
  223141. +
  223142. +}
  223143. +
  223144. +int imx6_usb_create_charger(struct usb_charger *charger,
  223145. + const char *name)
  223146. +{
  223147. + return -ENODEV;
  223148. +}
  223149. +
  223150. +int imx6_usb_vbus_disconnect(struct usb_charger *charger)
  223151. +{
  223152. + return -ENODEV;
  223153. +}
  223154. +
  223155. +int imx6_usb_vbus_connect(struct usb_charger *charger)
  223156. +{
  223157. + return -ENODEV;
  223158. +}
  223159. +int imx6_usb_charger_detect_post(struct usb_charger *charger)
  223160. +{
  223161. + return -ENODEV;
  223162. +}
  223163. +#endif
  223164. +
  223165. +#endif /* __IMXUSB6_CHARGER_H */
  223166. diff -Nur linux-3.14.14/include/linux/ptp_clock_kernel.h linux-imx6-3.14/include/linux/ptp_clock_kernel.h
  223167. --- linux-3.14.14/include/linux/ptp_clock_kernel.h 2014-07-28 10:07:25.000000000 -0500
  223168. +++ linux-imx6-3.14/include/linux/ptp_clock_kernel.h 2014-12-08 00:31:55.344418001 -0600
  223169. @@ -49,7 +49,11 @@
  223170. * @n_alarm: The number of programmable alarms.
  223171. * @n_ext_ts: The number of external time stamp channels.
  223172. * @n_per_out: The number of programmable periodic signals.
  223173. + * @n_pins: The number of programmable pins.
  223174. * @pps: Indicates whether the clock supports a PPS callback.
  223175. + * @pin_config: Array of length 'n_pins'. If the number of
  223176. + * programmable pins is nonzero, then drivers must
  223177. + * allocate and initialize this array.
  223178. *
  223179. * clock operations
  223180. *
  223181. @@ -70,6 +74,18 @@
  223182. * parameter request: Desired resource to enable or disable.
  223183. * parameter on: Caller passes one to enable or zero to disable.
  223184. *
  223185. + * @verify: Confirm that a pin can perform a given function. The PTP
  223186. + * Hardware Clock subsystem maintains the 'pin_config'
  223187. + * array on behalf of the drivers, but the PHC subsystem
  223188. + * assumes that every pin can perform every function. This
  223189. + * hook gives drivers a way of telling the core about
  223190. + * limitations on specific pins. This function must return
  223191. + * zero if the function can be assigned to this pin, and
  223192. + * nonzero otherwise.
  223193. + * parameter pin: index of the pin in question.
  223194. + * parameter func: the desired function to use.
  223195. + * parameter chan: the function channel index to use.
  223196. + *
  223197. * Drivers should embed their ptp_clock_info within a private
  223198. * structure, obtaining a reference to it using container_of().
  223199. *
  223200. @@ -83,13 +99,17 @@
  223201. int n_alarm;
  223202. int n_ext_ts;
  223203. int n_per_out;
  223204. + int n_pins;
  223205. int pps;
  223206. + struct ptp_pin_desc *pin_config;
  223207. int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta);
  223208. int (*adjtime)(struct ptp_clock_info *ptp, s64 delta);
  223209. int (*gettime)(struct ptp_clock_info *ptp, struct timespec *ts);
  223210. int (*settime)(struct ptp_clock_info *ptp, const struct timespec *ts);
  223211. int (*enable)(struct ptp_clock_info *ptp,
  223212. struct ptp_clock_request *request, int on);
  223213. + int (*verify)(struct ptp_clock_info *ptp, unsigned int pin,
  223214. + enum ptp_pin_function func, unsigned int chan);
  223215. };
  223216. struct ptp_clock;
  223217. @@ -156,4 +176,17 @@
  223218. extern int ptp_clock_index(struct ptp_clock *ptp);
  223219. +/**
  223220. + * ptp_find_pin() - obtain the pin index of a given auxiliary function
  223221. + *
  223222. + * @ptp: The clock obtained from ptp_clock_register().
  223223. + * @func: One of the ptp_pin_function enumerated values.
  223224. + * @chan: The particular functional channel to find.
  223225. + * Return: Pin index in the range of zero to ptp_clock_caps.n_pins - 1,
  223226. + * or -1 if the auxiliary function cannot be found.
  223227. + */
  223228. +
  223229. +int ptp_find_pin(struct ptp_clock *ptp,
  223230. + enum ptp_pin_function func, unsigned int chan);
  223231. +
  223232. #endif
  223233. diff -Nur linux-3.14.14/include/linux/pxp_device.h linux-imx6-3.14/include/linux/pxp_device.h
  223234. --- linux-3.14.14/include/linux/pxp_device.h 1969-12-31 18:00:00.000000000 -0600
  223235. +++ linux-imx6-3.14/include/linux/pxp_device.h 2014-12-08 00:31:55.344418001 -0600
  223236. @@ -0,0 +1,68 @@
  223237. +/*
  223238. + * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  223239. + *
  223240. + * This program is free software; you can redistribute it and/or modify
  223241. + * it under the terms of the GNU General Public License as published by
  223242. + * the Free Software Foundation; either version 2 of the License, or
  223243. + * (at your option) any later version.
  223244. + *
  223245. + * This program is distributed in the hope that it will be useful,
  223246. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223247. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223248. + * GNU General Public License for more details.
  223249. + *
  223250. + * You should have received a copy of the GNU General Public License
  223251. + * along with this program; if not, write to the Free Software
  223252. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  223253. + *
  223254. + */
  223255. +#ifndef _PXP_DEVICE
  223256. +#define _PXP_DEVICE
  223257. +
  223258. +#include <linux/idr.h>
  223259. +#include <linux/hash.h>
  223260. +#include <uapi/linux/pxp_device.h>
  223261. +
  223262. +struct pxp_irq_info {
  223263. + wait_queue_head_t waitq;
  223264. + atomic_t irq_pending;
  223265. + int hist_status;
  223266. +};
  223267. +
  223268. +struct pxp_buffer_hash {
  223269. + struct hlist_head *hash_table;
  223270. + u32 order;
  223271. + spinlock_t hash_lock;
  223272. +};
  223273. +
  223274. +struct pxp_buf_obj {
  223275. + uint32_t handle;
  223276. +
  223277. + uint32_t size;
  223278. + uint32_t mem_type;
  223279. +
  223280. + unsigned long offset;
  223281. + void *virtual;
  223282. +
  223283. + struct hlist_node item;
  223284. +};
  223285. +
  223286. +struct pxp_chan_obj {
  223287. + uint32_t handle;
  223288. + struct dma_chan *chan;
  223289. +};
  223290. +
  223291. +/* File private data */
  223292. +struct pxp_file {
  223293. + struct file *filp;
  223294. +
  223295. + /* record allocated dma buffer */
  223296. + struct idr buffer_idr;
  223297. + spinlock_t buffer_lock;
  223298. +
  223299. + /* record allocated dma channel */
  223300. + struct idr channel_idr;
  223301. + spinlock_t channel_lock;
  223302. +};
  223303. +
  223304. +#endif
  223305. diff -Nur linux-3.14.14/include/linux/pxp_dma.h linux-imx6-3.14/include/linux/pxp_dma.h
  223306. --- linux-3.14.14/include/linux/pxp_dma.h 1969-12-31 18:00:00.000000000 -0600
  223307. +++ linux-imx6-3.14/include/linux/pxp_dma.h 2014-12-08 00:31:55.344418001 -0600
  223308. @@ -0,0 +1,72 @@
  223309. +/*
  223310. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  223311. + *
  223312. + * This program is free software; you can redistribute it and/or modify
  223313. + * it under the terms of the GNU General Public License as published by
  223314. + * the Free Software Foundation; either version 2 of the License, or
  223315. + * (at your option) any later version.
  223316. + *
  223317. + * This program is distributed in the hope that it will be useful,
  223318. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223319. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223320. + * GNU General Public License for more details.
  223321. + *
  223322. + * You should have received a copy of the GNU General Public License
  223323. + * along with this program; if not, write to the Free Software
  223324. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  223325. + *
  223326. + */
  223327. +#ifndef _PXP_DMA
  223328. +#define _PXP_DMA
  223329. +
  223330. +#include <uapi/linux/pxp_dma.h>
  223331. +
  223332. +struct pxp_tx_desc {
  223333. + struct dma_async_tx_descriptor txd;
  223334. + struct list_head tx_list;
  223335. + struct list_head list;
  223336. + int len;
  223337. + union {
  223338. + struct pxp_layer_param s0_param;
  223339. + struct pxp_layer_param out_param;
  223340. + struct pxp_layer_param ol_param;
  223341. + } layer_param;
  223342. + struct pxp_proc_data proc_data;
  223343. +
  223344. + u32 hist_status; /* Histogram output status */
  223345. +
  223346. + struct pxp_tx_desc *next;
  223347. +};
  223348. +
  223349. +struct pxp_channel {
  223350. + struct dma_chan dma_chan;
  223351. + dma_cookie_t completed; /* last completed cookie */
  223352. + enum pxp_channel_status status;
  223353. + void *client; /* Only one client per channel */
  223354. + unsigned int n_tx_desc;
  223355. + struct pxp_tx_desc *desc; /* allocated tx-descriptors */
  223356. + struct list_head queue; /* queued tx-descriptors */
  223357. + struct list_head list; /* track queued channel number */
  223358. + spinlock_t lock; /* protects sg[0,1], queue,
  223359. + * status, cookie, free_list
  223360. + */
  223361. + int active_buffer;
  223362. + unsigned int eof_irq;
  223363. + char eof_name[16]; /* EOF IRQ name for request_irq() */
  223364. +};
  223365. +
  223366. +#define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
  223367. +#define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
  223368. +
  223369. +void pxp_txd_ack(struct dma_async_tx_descriptor *txd,
  223370. + struct pxp_channel *pxp_chan);
  223371. +
  223372. +#ifdef CONFIG_MXC_PXP_CLIENT_DEVICE
  223373. +int register_pxp_device(void);
  223374. +void unregister_pxp_device(void);
  223375. +#else
  223376. +int register_pxp_device(void) { return 0; }
  223377. +void unregister_pxp_device(void) {}
  223378. +#endif
  223379. +
  223380. +#endif
  223381. diff -Nur linux-3.14.14/include/linux/regulator/consumer.h linux-imx6-3.14/include/linux/regulator/consumer.h
  223382. --- linux-3.14.14/include/linux/regulator/consumer.h 2014-07-28 10:07:25.000000000 -0500
  223383. +++ linux-imx6-3.14/include/linux/regulator/consumer.h 2014-12-08 00:31:55.348418001 -0600
  223384. @@ -2,6 +2,7 @@
  223385. * consumer.h -- SoC Regulator consumer support.
  223386. *
  223387. * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
  223388. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  223389. *
  223390. * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  223391. *
  223392. @@ -105,6 +106,8 @@
  223393. #define REGULATOR_EVENT_FORCE_DISABLE 0x20
  223394. #define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
  223395. #define REGULATOR_EVENT_DISABLE 0x80
  223396. +#define REGULATOR_EVENT_PRE_DISABLE 0x100
  223397. +#define REGULATOR_EVENT_ENABLE 0x200
  223398. struct regulator;
  223399. diff -Nur linux-3.14.14/include/linux/reset.h linux-imx6-3.14/include/linux/reset.h
  223400. --- linux-3.14.14/include/linux/reset.h 2014-07-28 10:07:25.000000000 -0500
  223401. +++ linux-imx6-3.14/include/linux/reset.h 2014-12-08 00:31:55.348418001 -0600
  223402. @@ -12,6 +12,13 @@
  223403. void reset_control_put(struct reset_control *rstc);
  223404. struct reset_control *devm_reset_control_get(struct device *dev, const char *id);
  223405. +#ifdef CONFIG_RESET_CONTROLLER
  223406. int device_reset(struct device *dev);
  223407. +#else
  223408. +static inline int device_reset(struct device *dev)
  223409. +{
  223410. + return 0;
  223411. +}
  223412. +#endif /* CONFIG_RESET_CONTROLLER */
  223413. #endif
  223414. diff -Nur linux-3.14.14/include/linux/serial_core.h linux-imx6-3.14/include/linux/serial_core.h
  223415. --- linux-3.14.14/include/linux/serial_core.h 2014-07-28 10:07:25.000000000 -0500
  223416. +++ linux-imx6-3.14/include/linux/serial_core.h 2014-12-08 00:31:55.356418001 -0600
  223417. @@ -285,6 +285,22 @@
  223418. /*
  223419. * Console helpers.
  223420. */
  223421. +struct earlycon_device {
  223422. + struct console *con;
  223423. + struct uart_port port;
  223424. + char options[16]; /* e.g., 115200n8 */
  223425. + unsigned int baud;
  223426. +};
  223427. +int setup_earlycon(char *buf, const char *match,
  223428. + int (*setup)(struct earlycon_device *, const char *));
  223429. +
  223430. +#define EARLYCON_DECLARE(name, func) \
  223431. +static int __init name ## _setup_earlycon(char *buf) \
  223432. +{ \
  223433. + return setup_earlycon(buf, __stringify(name), func); \
  223434. +} \
  223435. +early_param("earlycon", name ## _setup_earlycon);
  223436. +
  223437. struct uart_port *uart_get_console(struct uart_port *ports, int nr,
  223438. struct console *c);
  223439. void uart_parse_options(char *options, int *baud, int *parity, int *bits,
  223440. diff -Nur linux-3.14.14/include/linux/skbuff.h linux-imx6-3.14/include/linux/skbuff.h
  223441. --- linux-3.14.14/include/linux/skbuff.h 2014-07-28 10:07:25.000000000 -0500
  223442. +++ linux-imx6-3.14/include/linux/skbuff.h 2014-12-08 00:31:55.356418001 -0600
  223443. @@ -2038,7 +2038,7 @@
  223444. }
  223445. /**
  223446. - * skb_frag_page - retrieve the page refered to by a paged fragment
  223447. + * skb_frag_page - retrieve the page referred to by a paged fragment
  223448. * @frag: the paged fragment
  223449. *
  223450. * Returns the &struct page associated with @frag.
  223451. diff -Nur linux-3.14.14/include/linux/spi/spi.h linux-imx6-3.14/include/linux/spi/spi.h
  223452. --- linux-3.14.14/include/linux/spi/spi.h 2014-07-28 10:07:25.000000000 -0500
  223453. +++ linux-imx6-3.14/include/linux/spi/spi.h 2014-12-08 00:31:55.360418001 -0600
  223454. @@ -234,7 +234,7 @@
  223455. * @mode_bits: flags understood by this controller driver
  223456. * @bits_per_word_mask: A mask indicating which values of bits_per_word are
  223457. * supported by the driver. Bit n indicates that a bits_per_word n+1 is
  223458. - * suported. If set, the SPI core will reject any transfer with an
  223459. + * supported. If set, the SPI core will reject any transfer with an
  223460. * unsupported bits_per_word. If not set, this value is simply ignored,
  223461. * and it's up to the individual driver to perform any validation.
  223462. * @min_speed_hz: Lowest supported transfer speed
  223463. @@ -259,7 +259,7 @@
  223464. * @cur_msg: the currently in-flight message
  223465. * @cur_msg_prepared: spi_prepare_message was called for the currently
  223466. * in-flight message
  223467. - * @xfer_completion: used by core tranfer_one_message()
  223468. + * @xfer_completion: used by core transfer_one_message()
  223469. * @busy: message pump is busy
  223470. * @running: message pump is running
  223471. * @rt: whether this queue is set to run as a realtime task
  223472. @@ -498,7 +498,7 @@
  223473. * @rx_buf: data to be read (dma-safe memory), or NULL
  223474. * @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped
  223475. * @rx_dma: DMA address of rx_buf, if @spi_message.is_dma_mapped
  223476. - * @tx_nbits: number of bits used for writting. If 0 the default
  223477. + * @tx_nbits: number of bits used for writing. If 0 the default
  223478. * (SPI_NBITS_SINGLE) is used.
  223479. * @rx_nbits: number of bits used for reading. If 0 the default
  223480. * (SPI_NBITS_SINGLE) is used.
  223481. @@ -556,7 +556,7 @@
  223482. * by the results of previous messages and where the whole transaction
  223483. * ends when the chipselect goes intactive.
  223484. *
  223485. - * When SPI can transfer in 1x,2x or 4x. It can get this tranfer information
  223486. + * When SPI can transfer in 1x,2x or 4x. It can get this transfer information
  223487. * from device through @tx_nbits and @rx_nbits. In Bi-direction, these
  223488. * two should both be set. User can set transfer mode with SPI_NBITS_SINGLE(1x)
  223489. * SPI_NBITS_DUAL(2x) and SPI_NBITS_QUAD(4x) to support these three transfer.
  223490. diff -Nur linux-3.14.14/include/linux/syscalls.h linux-imx6-3.14/include/linux/syscalls.h
  223491. --- linux-3.14.14/include/linux/syscalls.h 2014-07-28 10:07:25.000000000 -0500
  223492. +++ linux-imx6-3.14/include/linux/syscalls.h 2014-12-08 00:31:55.364418001 -0600
  223493. @@ -744,6 +744,9 @@
  223494. int newdfd, const char __user *newname, int flags);
  223495. asmlinkage long sys_renameat(int olddfd, const char __user * oldname,
  223496. int newdfd, const char __user * newname);
  223497. +asmlinkage long sys_renameat2(int olddfd, const char __user *oldname,
  223498. + int newdfd, const char __user *newname,
  223499. + unsigned int flags);
  223500. asmlinkage long sys_futimesat(int dfd, const char __user *filename,
  223501. struct timeval __user *utimes);
  223502. asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode);
  223503. diff -Nur linux-3.14.14/include/linux/usb/chipidea.h linux-imx6-3.14/include/linux/usb/chipidea.h
  223504. --- linux-3.14.14/include/linux/usb/chipidea.h 2014-07-28 10:07:25.000000000 -0500
  223505. +++ linux-imx6-3.14/include/linux/usb/chipidea.h 2014-12-08 00:31:55.372418001 -0600
  223506. @@ -18,6 +18,7 @@
  223507. unsigned long flags;
  223508. #define CI_HDRC_REGS_SHARED BIT(0)
  223509. #define CI_HDRC_REQUIRE_TRANSCEIVER BIT(1)
  223510. +#define CI_HDRC_SUPPORTS_RUNTIME_PM BIT(2)
  223511. #define CI_HDRC_DISABLE_STREAMING BIT(3)
  223512. /*
  223513. * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
  223514. @@ -25,6 +26,7 @@
  223515. */
  223516. #define CI_HDRC_DUAL_ROLE_NOT_OTG BIT(4)
  223517. #define CI_HDRC_IMX28_WRITE_FIX BIT(5)
  223518. +#define CI_HDRC_IMX_EHCI_QUIRK BIT(6)
  223519. enum usb_dr_mode dr_mode;
  223520. #define CI_HDRC_CONTROLLER_RESET_EVENT 0
  223521. #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
  223522. @@ -42,4 +44,6 @@
  223523. /* Remove ci hdrc device */
  223524. void ci_hdrc_remove_device(struct platform_device *pdev);
  223525. +/* Get current available role */
  223526. +enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev);
  223527. #endif
  223528. diff -Nur linux-3.14.14/include/linux/usb/composite.h linux-imx6-3.14/include/linux/usb/composite.h
  223529. --- linux-3.14.14/include/linux/usb/composite.h 2014-07-28 10:07:25.000000000 -0500
  223530. +++ linux-imx6-3.14/include/linux/usb/composite.h 2014-12-08 00:31:55.372418001 -0600
  223531. @@ -92,7 +92,7 @@
  223532. * @suspend: Notifies functions when the host stops sending USB traffic.
  223533. * @resume: Notifies functions when the host restarts USB traffic.
  223534. * @get_status: Returns function status as a reply to
  223535. - * GetStatus() request when the recepient is Interface.
  223536. + * GetStatus() request when the recipient is Interface.
  223537. * @func_suspend: callback to be called when
  223538. * SetFeature(FUNCTION_SUSPEND) is reseived
  223539. *
  223540. diff -Nur linux-3.14.14/include/linux/usb/phy.h linux-imx6-3.14/include/linux/usb/phy.h
  223541. --- linux-3.14.14/include/linux/usb/phy.h 2014-07-28 10:07:25.000000000 -0500
  223542. +++ linux-imx6-3.14/include/linux/usb/phy.h 2014-12-08 00:31:55.372418001 -0600
  223543. @@ -111,11 +111,23 @@
  223544. int (*set_suspend)(struct usb_phy *x,
  223545. int suspend);
  223546. + /*
  223547. + * Set wakeup enable for PHY, in that case, the PHY can be
  223548. + * waken up from suspend status due to external events,
  223549. + * like vbus change, dp/dm change and id.
  223550. + */
  223551. + int (*set_wakeup)(struct usb_phy *x, bool enabled);
  223552. +
  223553. /* notify phy connect status change */
  223554. int (*notify_connect)(struct usb_phy *x,
  223555. enum usb_device_speed speed);
  223556. int (*notify_disconnect)(struct usb_phy *x,
  223557. enum usb_device_speed speed);
  223558. + int (*notify_suspend)(struct usb_phy *x,
  223559. + enum usb_device_speed speed);
  223560. + int (*notify_resume)(struct usb_phy *x,
  223561. + enum usb_device_speed speed);
  223562. +
  223563. };
  223564. /**
  223565. @@ -265,6 +277,15 @@
  223566. }
  223567. static inline int
  223568. +usb_phy_set_wakeup(struct usb_phy *x, bool enabled)
  223569. +{
  223570. + if (x && x->set_wakeup)
  223571. + return x->set_wakeup(x, enabled);
  223572. + else
  223573. + return 0;
  223574. +}
  223575. +
  223576. +static inline int
  223577. usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed)
  223578. {
  223579. if (x && x->notify_connect)
  223580. @@ -281,6 +302,24 @@
  223581. else
  223582. return 0;
  223583. }
  223584. +
  223585. +static inline int usb_phy_notify_suspend
  223586. + (struct usb_phy *x, enum usb_device_speed speed)
  223587. +{
  223588. + if (x && x->notify_suspend)
  223589. + return x->notify_suspend(x, speed);
  223590. + else
  223591. + return 0;
  223592. +}
  223593. +
  223594. +static inline int usb_phy_notify_resume
  223595. + (struct usb_phy *x, enum usb_device_speed speed)
  223596. +{
  223597. + if (x && x->notify_resume)
  223598. + return x->notify_resume(x, speed);
  223599. + else
  223600. + return 0;
  223601. +}
  223602. /* notifiers */
  223603. static inline int
  223604. diff -Nur linux-3.14.14/include/net/cfg80211.h linux-imx6-3.14/include/net/cfg80211.h
  223605. --- linux-3.14.14/include/net/cfg80211.h 2014-07-28 10:07:25.000000000 -0500
  223606. +++ linux-imx6-3.14/include/net/cfg80211.h 2014-12-08 00:31:55.392418001 -0600
  223607. @@ -1729,7 +1729,7 @@
  223608. u8 *ssid;
  223609. size_t ssid_len;
  223610. enum nl80211_auth_type auth_type;
  223611. - u8 *ie;
  223612. + const u8 *ie;
  223613. size_t ie_len;
  223614. bool privacy;
  223615. enum nl80211_mfp mfp;
  223616. @@ -3888,6 +3888,7 @@
  223617. *
  223618. * @dev: network device
  223619. * @bssid: the BSSID of the IBSS joined
  223620. + * @channel: the channel of the IBSS joined
  223621. * @gfp: allocation flags
  223622. *
  223623. * This function notifies cfg80211 that the device joined an IBSS or
  223624. @@ -3897,7 +3898,8 @@
  223625. * with the locally generated beacon -- this guarantees that there is
  223626. * always a scan result for this IBSS. cfg80211 will handle the rest.
  223627. */
  223628. -void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
  223629. +void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  223630. + struct ieee80211_channel *channel, gfp_t gfp);
  223631. /**
  223632. * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
  223633. diff -Nur linux-3.14.14/include/net/mac80211.h linux-imx6-3.14/include/net/mac80211.h
  223634. --- linux-3.14.14/include/net/mac80211.h 2014-07-28 10:07:25.000000000 -0500
  223635. +++ linux-imx6-3.14/include/net/mac80211.h 2014-12-08 00:31:55.400418001 -0600
  223636. @@ -1895,7 +1895,7 @@
  223637. *
  223638. * Driver informs U-APSD client support by enabling
  223639. * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the
  223640. - * uapsd paramater in conf_tx() operation. Hardware needs to send the QoS
  223641. + * uapsd parameter in conf_tx() operation. Hardware needs to send the QoS
  223642. * Nullfunc frames and stay awake until the service period has ended. To
  223643. * utilize U-APSD, dynamic powersave is disabled for voip AC and all frames
  223644. * from that AC are transmitted with powersave enabled.
  223645. @@ -2101,7 +2101,7 @@
  223646. * with the number of frames to be released and which TIDs they are
  223647. * to come from. In this case, the driver is responsible for setting
  223648. * the EOSP (for uAPSD) and MORE_DATA bits in the released frames,
  223649. - * to help the @more_data paramter is passed to tell the driver if
  223650. + * to help the @more_data parameter is passed to tell the driver if
  223651. * there is more data on other TIDs -- the TIDs to release frames
  223652. * from are ignored since mac80211 doesn't know how many frames the
  223653. * buffers for those TIDs contain.
  223654. @@ -2616,6 +2616,7 @@
  223655. * of queues to flush, which is useful if different virtual interfaces
  223656. * use different hardware queues; it may also indicate all queues.
  223657. * If the parameter @drop is set to %true, pending frames may be dropped.
  223658. + * Note that vif can be NULL.
  223659. * The callback can sleep.
  223660. *
  223661. * @channel_switch: Drivers that need (or want) to offload the channel
  223662. @@ -2662,7 +2663,7 @@
  223663. * parameters. In the case where the driver buffers some frames for
  223664. * sleeping stations mac80211 will use this callback to tell the driver
  223665. * to release some frames, either for PS-poll or uAPSD.
  223666. - * Note that if the @more_data paramter is %false the driver must check
  223667. + * Note that if the @more_data parameter is %false the driver must check
  223668. * if there are more frames on the given TIDs, and if there are more than
  223669. * the frames being released then it must still set the more-data bit in
  223670. * the frame. If the @more_data parameter is %true, then of course the
  223671. @@ -2878,7 +2879,8 @@
  223672. struct netlink_callback *cb,
  223673. void *data, int len);
  223674. #endif
  223675. - void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop);
  223676. + void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  223677. + u32 queues, bool drop);
  223678. void (*channel_switch)(struct ieee80211_hw *hw,
  223679. struct ieee80211_channel_switch *ch_switch);
  223680. int (*napi_poll)(struct ieee80211_hw *hw, int budget);
  223681. diff -Nur linux-3.14.14/include/net/rtnetlink.h linux-imx6-3.14/include/net/rtnetlink.h
  223682. --- linux-3.14.14/include/net/rtnetlink.h 2014-07-28 10:07:25.000000000 -0500
  223683. +++ linux-imx6-3.14/include/net/rtnetlink.h 2014-12-08 00:31:55.404418001 -0600
  223684. @@ -140,7 +140,7 @@
  223685. struct nlattr *tb[]);
  223686. int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm);
  223687. -extern const struct nla_policy ifla_policy[IFLA_MAX+1];
  223688. +int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len);
  223689. #define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind)
  223690. diff -Nur linux-3.14.14/include/net/tso.h linux-imx6-3.14/include/net/tso.h
  223691. --- linux-3.14.14/include/net/tso.h 1969-12-31 18:00:00.000000000 -0600
  223692. +++ linux-imx6-3.14/include/net/tso.h 2014-12-08 00:31:55.408418001 -0600
  223693. @@ -0,0 +1,20 @@
  223694. +#ifndef _TSO_H
  223695. +#define _TSO_H
  223696. +
  223697. +#include <net/ip.h>
  223698. +
  223699. +struct tso_t {
  223700. + int next_frag_idx;
  223701. + void *data;
  223702. + size_t size;
  223703. + u16 ip_id;
  223704. + u32 tcp_seq;
  223705. +};
  223706. +
  223707. +int tso_count_descs(struct sk_buff *skb);
  223708. +void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,
  223709. + int size, bool is_last);
  223710. +void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size);
  223711. +void tso_start(struct sk_buff *skb, struct tso_t *tso);
  223712. +
  223713. +#endif /* _TSO_H */
  223714. diff -Nur linux-3.14.14/include/sound/wm8962.h linux-imx6-3.14/include/sound/wm8962.h
  223715. --- linux-3.14.14/include/sound/wm8962.h 2014-07-28 10:07:25.000000000 -0500
  223716. +++ linux-imx6-3.14/include/sound/wm8962.h 2014-12-08 00:31:55.424418001 -0600
  223717. @@ -55,6 +55,9 @@
  223718. * in a DC measurement configuration.
  223719. */
  223720. bool in4_dc_measure;
  223721. +
  223722. + /* MCLK for wm8962 */
  223723. + struct clk *codec_mclk;
  223724. };
  223725. #endif
  223726. diff -Nur linux-3.14.14/include/trace/events/cpufreq_interactive.h linux-imx6-3.14/include/trace/events/cpufreq_interactive.h
  223727. --- linux-3.14.14/include/trace/events/cpufreq_interactive.h 1969-12-31 18:00:00.000000000 -0600
  223728. +++ linux-imx6-3.14/include/trace/events/cpufreq_interactive.h 2014-12-08 00:31:55.428418001 -0600
  223729. @@ -0,0 +1,112 @@
  223730. +#undef TRACE_SYSTEM
  223731. +#define TRACE_SYSTEM cpufreq_interactive
  223732. +
  223733. +#if !defined(_TRACE_CPUFREQ_INTERACTIVE_H) || defined(TRACE_HEADER_MULTI_READ)
  223734. +#define _TRACE_CPUFREQ_INTERACTIVE_H
  223735. +
  223736. +#include <linux/tracepoint.h>
  223737. +
  223738. +DECLARE_EVENT_CLASS(set,
  223739. + TP_PROTO(u32 cpu_id, unsigned long targfreq,
  223740. + unsigned long actualfreq),
  223741. + TP_ARGS(cpu_id, targfreq, actualfreq),
  223742. +
  223743. + TP_STRUCT__entry(
  223744. + __field( u32, cpu_id )
  223745. + __field(unsigned long, targfreq )
  223746. + __field(unsigned long, actualfreq )
  223747. + ),
  223748. +
  223749. + TP_fast_assign(
  223750. + __entry->cpu_id = (u32) cpu_id;
  223751. + __entry->targfreq = targfreq;
  223752. + __entry->actualfreq = actualfreq;
  223753. + ),
  223754. +
  223755. + TP_printk("cpu=%u targ=%lu actual=%lu",
  223756. + __entry->cpu_id, __entry->targfreq,
  223757. + __entry->actualfreq)
  223758. +);
  223759. +
  223760. +DEFINE_EVENT(set, cpufreq_interactive_setspeed,
  223761. + TP_PROTO(u32 cpu_id, unsigned long targfreq,
  223762. + unsigned long actualfreq),
  223763. + TP_ARGS(cpu_id, targfreq, actualfreq)
  223764. +);
  223765. +
  223766. +DECLARE_EVENT_CLASS(loadeval,
  223767. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  223768. + unsigned long curtarg, unsigned long curactual,
  223769. + unsigned long newtarg),
  223770. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg),
  223771. +
  223772. + TP_STRUCT__entry(
  223773. + __field(unsigned long, cpu_id )
  223774. + __field(unsigned long, load )
  223775. + __field(unsigned long, curtarg )
  223776. + __field(unsigned long, curactual )
  223777. + __field(unsigned long, newtarg )
  223778. + ),
  223779. +
  223780. + TP_fast_assign(
  223781. + __entry->cpu_id = cpu_id;
  223782. + __entry->load = load;
  223783. + __entry->curtarg = curtarg;
  223784. + __entry->curactual = curactual;
  223785. + __entry->newtarg = newtarg;
  223786. + ),
  223787. +
  223788. + TP_printk("cpu=%lu load=%lu cur=%lu actual=%lu targ=%lu",
  223789. + __entry->cpu_id, __entry->load, __entry->curtarg,
  223790. + __entry->curactual, __entry->newtarg)
  223791. +);
  223792. +
  223793. +DEFINE_EVENT(loadeval, cpufreq_interactive_target,
  223794. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  223795. + unsigned long curtarg, unsigned long curactual,
  223796. + unsigned long newtarg),
  223797. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
  223798. +);
  223799. +
  223800. +DEFINE_EVENT(loadeval, cpufreq_interactive_already,
  223801. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  223802. + unsigned long curtarg, unsigned long curactual,
  223803. + unsigned long newtarg),
  223804. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
  223805. +);
  223806. +
  223807. +DEFINE_EVENT(loadeval, cpufreq_interactive_notyet,
  223808. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  223809. + unsigned long curtarg, unsigned long curactual,
  223810. + unsigned long newtarg),
  223811. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
  223812. +);
  223813. +
  223814. +TRACE_EVENT(cpufreq_interactive_boost,
  223815. + TP_PROTO(const char *s),
  223816. + TP_ARGS(s),
  223817. + TP_STRUCT__entry(
  223818. + __string(s, s)
  223819. + ),
  223820. + TP_fast_assign(
  223821. + __assign_str(s, s);
  223822. + ),
  223823. + TP_printk("%s", __get_str(s))
  223824. +);
  223825. +
  223826. +TRACE_EVENT(cpufreq_interactive_unboost,
  223827. + TP_PROTO(const char *s),
  223828. + TP_ARGS(s),
  223829. + TP_STRUCT__entry(
  223830. + __string(s, s)
  223831. + ),
  223832. + TP_fast_assign(
  223833. + __assign_str(s, s);
  223834. + ),
  223835. + TP_printk("%s", __get_str(s))
  223836. +);
  223837. +
  223838. +#endif /* _TRACE_CPUFREQ_INTERACTIVE_H */
  223839. +
  223840. +/* This part must be outside protection */
  223841. +#include <trace/define_trace.h>
  223842. diff -Nur linux-3.14.14/include/uapi/linux/ipu.h linux-imx6-3.14/include/uapi/linux/ipu.h
  223843. --- linux-3.14.14/include/uapi/linux/ipu.h 1969-12-31 18:00:00.000000000 -0600
  223844. +++ linux-imx6-3.14/include/uapi/linux/ipu.h 2014-12-08 00:31:55.448418001 -0600
  223845. @@ -0,0 +1,282 @@
  223846. +/*
  223847. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  223848. + */
  223849. +
  223850. +/*
  223851. + * This program is free software; you can redistribute it and/or modify
  223852. + * it under the terms of the GNU General Public License as published by
  223853. + * the Free Software Foundation; either version 2 of the License, or
  223854. + * (at your option) any later version.
  223855. + *
  223856. + * This program is distributed in the hope that it will be useful,
  223857. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223858. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223859. + * GNU General Public License for more details.
  223860. + *
  223861. + * You should have received a copy of the GNU General Public License along
  223862. + * with this program; if not, write to the Free Software Foundation, Inc.,
  223863. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  223864. + */
  223865. +
  223866. +/*!
  223867. + * @defgroup IPU MXC Image Processing Unit (IPU) Driver
  223868. + */
  223869. +/*!
  223870. + * @file uapi/linux/ipu.h
  223871. + *
  223872. + * @brief This file contains the IPU driver API declarations.
  223873. + *
  223874. + * @ingroup IPU
  223875. + */
  223876. +
  223877. +#ifndef __ASM_ARCH_IPU_H__
  223878. +#define __ASM_ARCH_IPU_H__
  223879. +
  223880. +#include <linux/types.h>
  223881. +#include <linux/videodev2.h>
  223882. +
  223883. +#ifndef __KERNEL__
  223884. +#ifndef __cplusplus
  223885. +typedef unsigned char bool;
  223886. +#endif
  223887. +#define irqreturn_t int
  223888. +#define dma_addr_t int
  223889. +#define uint32_t unsigned int
  223890. +#define uint16_t unsigned short
  223891. +#define uint8_t unsigned char
  223892. +#define u32 unsigned int
  223893. +#define u8 unsigned char
  223894. +#define __u32 u32
  223895. +#endif
  223896. +
  223897. +/*!
  223898. + * Enumeration of IPU rotation modes
  223899. + */
  223900. +typedef enum {
  223901. + /* Note the enum values correspond to BAM value */
  223902. + IPU_ROTATE_NONE = 0,
  223903. + IPU_ROTATE_VERT_FLIP = 1,
  223904. + IPU_ROTATE_HORIZ_FLIP = 2,
  223905. + IPU_ROTATE_180 = 3,
  223906. + IPU_ROTATE_90_RIGHT = 4,
  223907. + IPU_ROTATE_90_RIGHT_VFLIP = 5,
  223908. + IPU_ROTATE_90_RIGHT_HFLIP = 6,
  223909. + IPU_ROTATE_90_LEFT = 7,
  223910. +} ipu_rotate_mode_t;
  223911. +
  223912. +/*!
  223913. + * Enumeration of VDI MOTION select
  223914. + */
  223915. +typedef enum {
  223916. + MED_MOTION = 0,
  223917. + LOW_MOTION = 1,
  223918. + HIGH_MOTION = 2,
  223919. +} ipu_motion_sel;
  223920. +
  223921. +/*!
  223922. + * Enumeration of DI ports for ADC.
  223923. + */
  223924. +typedef enum {
  223925. + DISP0,
  223926. + DISP1,
  223927. + DISP2,
  223928. + DISP3
  223929. +} display_port_t;
  223930. +
  223931. +/* IPU Pixel format definitions */
  223932. +/* Four-character-code (FOURCC) */
  223933. +#define fourcc(a, b, c, d)\
  223934. + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
  223935. +
  223936. +/*!
  223937. + * @name IPU Pixel Formats
  223938. + *
  223939. + * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
  223940. + * the same used by V4L2 API.
  223941. + */
  223942. +
  223943. +/*! @{ */
  223944. +/*! @name Generic or Raw Data Formats */
  223945. +/*! @{ */
  223946. +#define IPU_PIX_FMT_GENERIC fourcc('I', 'P', 'U', '0') /*!< IPU Generic Data */
  223947. +#define IPU_PIX_FMT_GENERIC_32 fourcc('I', 'P', 'U', '1') /*!< IPU Generic Data */
  223948. +#define IPU_PIX_FMT_GENERIC_16 fourcc('I', 'P', 'U', '2') /*!< IPU Generic Data */
  223949. +#define IPU_PIX_FMT_LVDS666 fourcc('L', 'V', 'D', '6') /*!< IPU Generic Data */
  223950. +#define IPU_PIX_FMT_LVDS888 fourcc('L', 'V', 'D', '8') /*!< IPU Generic Data */
  223951. +/*! @} */
  223952. +/*! @name RGB Formats */
  223953. +/*! @{ */
  223954. +#define IPU_PIX_FMT_RGB332 fourcc('R', 'G', 'B', '1') /*!< 8 RGB-3-3-2 */
  223955. +#define IPU_PIX_FMT_RGB555 fourcc('R', 'G', 'B', 'O') /*!< 16 RGB-5-5-5 */
  223956. +#define IPU_PIX_FMT_RGB565 fourcc('R', 'G', 'B', 'P') /*!< 1 6 RGB-5-6-5 */
  223957. +#define IPU_PIX_FMT_RGB666 fourcc('R', 'G', 'B', '6') /*!< 18 RGB-6-6-6 */
  223958. +#define IPU_PIX_FMT_BGR666 fourcc('B', 'G', 'R', '6') /*!< 18 BGR-6-6-6 */
  223959. +#define IPU_PIX_FMT_BGR24 fourcc('B', 'G', 'R', '3') /*!< 24 BGR-8-8-8 */
  223960. +#define IPU_PIX_FMT_RGB24 fourcc('R', 'G', 'B', '3') /*!< 24 RGB-8-8-8 */
  223961. +#define IPU_PIX_FMT_GBR24 fourcc('G', 'B', 'R', '3') /*!< 24 GBR-8-8-8 */
  223962. +#define IPU_PIX_FMT_BGR32 fourcc('B', 'G', 'R', '4') /*!< 32 BGR-8-8-8-8 */
  223963. +#define IPU_PIX_FMT_BGRA32 fourcc('B', 'G', 'R', 'A') /*!< 32 BGR-8-8-8-8 */
  223964. +#define IPU_PIX_FMT_RGB32 fourcc('R', 'G', 'B', '4') /*!< 32 RGB-8-8-8-8 */
  223965. +#define IPU_PIX_FMT_RGBA32 fourcc('R', 'G', 'B', 'A') /*!< 32 RGB-8-8-8-8 */
  223966. +#define IPU_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R') /*!< 32 ABGR-8-8-8-8 */
  223967. +/*! @} */
  223968. +/*! @name YUV Interleaved Formats */
  223969. +/*! @{ */
  223970. +#define IPU_PIX_FMT_YUYV fourcc('Y', 'U', 'Y', 'V') /*!< 16 YUV 4:2:2 */
  223971. +#define IPU_PIX_FMT_UYVY fourcc('U', 'Y', 'V', 'Y') /*!< 16 YUV 4:2:2 */
  223972. +#define IPU_PIX_FMT_YVYU fourcc('Y', 'V', 'Y', 'U') /*!< 16 YVYU 4:2:2 */
  223973. +#define IPU_PIX_FMT_VYUY fourcc('V', 'Y', 'U', 'Y') /*!< 16 VYYU 4:2:2 */
  223974. +#define IPU_PIX_FMT_Y41P fourcc('Y', '4', '1', 'P') /*!< 12 YUV 4:1:1 */
  223975. +#define IPU_PIX_FMT_YUV444 fourcc('Y', '4', '4', '4') /*!< 24 YUV 4:4:4 */
  223976. +#define IPU_PIX_FMT_VYU444 fourcc('V', '4', '4', '4') /*!< 24 VYU 4:4:4 */
  223977. +/* two planes -- one Y, one Cb + Cr interleaved */
  223978. +#define IPU_PIX_FMT_NV12 fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
  223979. +/* two planes -- 12 tiled Y/CbCr 4:2:0 */
  223980. +#define IPU_PIX_FMT_TILED_NV12 fourcc('T', 'N', 'V', 'P')
  223981. +#define IPU_PIX_FMT_TILED_NV12F fourcc('T', 'N', 'V', 'F')
  223982. +
  223983. +/*! @} */
  223984. +/*! @name YUV Planar Formats */
  223985. +/*! @{ */
  223986. +#define IPU_PIX_FMT_GREY fourcc('G', 'R', 'E', 'Y') /*!< 8 Greyscale */
  223987. +#define IPU_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*!< 9 YVU 4:1:0 */
  223988. +#define IPU_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*!< 9 YUV 4:1:0 */
  223989. +#define IPU_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*!< 12 YVU 4:2:0 */
  223990. +#define IPU_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*!< 12 YUV 4:2:0 */
  223991. +#define IPU_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2') /*!< 12 YUV 4:2:0 */
  223992. +#define IPU_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*!< 16 YVU 4:2:2 */
  223993. +#define IPU_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*!< 16 YUV 4:2:2 */
  223994. +/* non-interleaved 4:4:4 */
  223995. +#define IPU_PIX_FMT_YUV444P fourcc('4', '4', '4', 'P') /*!< 24 YUV 4:4:4 */
  223996. +/*! @} */
  223997. +#define IPU_PIX_FMT_TILED_NV12_MBALIGN (16)
  223998. +#define TILED_NV12_FRAME_SIZE(w, h) \
  223999. + (ALIGN((w) * (h), SZ_4K) + ALIGN((w) * (h) / 2, SZ_4K))
  224000. +/* IPU device */
  224001. +typedef enum {
  224002. + RGB_CS,
  224003. + YUV_CS,
  224004. + NULL_CS
  224005. +} cs_t;
  224006. +
  224007. +struct ipu_pos {
  224008. + u32 x;
  224009. + u32 y;
  224010. +};
  224011. +
  224012. +struct ipu_crop {
  224013. + struct ipu_pos pos;
  224014. + u32 w;
  224015. + u32 h;
  224016. +};
  224017. +
  224018. +struct ipu_deinterlace {
  224019. + bool enable;
  224020. + u8 motion; /*see ipu_motion_sel*/
  224021. +#define IPU_DEINTERLACE_FIELD_TOP 0
  224022. +#define IPU_DEINTERLACE_FIELD_BOTTOM 1
  224023. +#define IPU_DEINTERLACE_FIELD_MASK \
  224024. + (IPU_DEINTERLACE_FIELD_TOP | IPU_DEINTERLACE_FIELD_BOTTOM)
  224025. + /* deinterlace frame rate double flags */
  224026. +#define IPU_DEINTERLACE_RATE_EN 0x80
  224027. +#define IPU_DEINTERLACE_RATE_FRAME1 0x40
  224028. +#define IPU_DEINTERLACE_RATE_MASK \
  224029. + (IPU_DEINTERLACE_RATE_EN | IPU_DEINTERLACE_RATE_FRAME1)
  224030. +#define IPU_DEINTERLACE_MAX_FRAME 2
  224031. + u8 field_fmt;
  224032. +};
  224033. +
  224034. +struct ipu_input {
  224035. + u32 width;
  224036. + u32 height;
  224037. + u32 format;
  224038. + struct ipu_crop crop;
  224039. + dma_addr_t paddr;
  224040. +
  224041. + struct ipu_deinterlace deinterlace;
  224042. + dma_addr_t paddr_n; /*valid when deinterlace enable*/
  224043. +};
  224044. +
  224045. +struct ipu_alpha {
  224046. +#define IPU_ALPHA_MODE_GLOBAL 0
  224047. +#define IPU_ALPHA_MODE_LOCAL 1
  224048. + u8 mode;
  224049. + u8 gvalue; /* 0~255 */
  224050. + dma_addr_t loc_alp_paddr;
  224051. +};
  224052. +
  224053. +struct ipu_colorkey {
  224054. + bool enable;
  224055. + u32 value; /* RGB 24bit */
  224056. +};
  224057. +
  224058. +struct ipu_overlay {
  224059. + u32 width;
  224060. + u32 height;
  224061. + u32 format;
  224062. + struct ipu_crop crop;
  224063. + struct ipu_alpha alpha;
  224064. + struct ipu_colorkey colorkey;
  224065. + dma_addr_t paddr;
  224066. +};
  224067. +
  224068. +struct ipu_output {
  224069. + u32 width;
  224070. + u32 height;
  224071. + u32 format;
  224072. + u8 rotate;
  224073. + struct ipu_crop crop;
  224074. + dma_addr_t paddr;
  224075. +};
  224076. +
  224077. +struct ipu_task {
  224078. + struct ipu_input input;
  224079. + struct ipu_output output;
  224080. +
  224081. + bool overlay_en;
  224082. + struct ipu_overlay overlay;
  224083. +
  224084. +#define IPU_TASK_PRIORITY_NORMAL 0
  224085. +#define IPU_TASK_PRIORITY_HIGH 1
  224086. + u8 priority;
  224087. +
  224088. +#define IPU_TASK_ID_ANY 0
  224089. +#define IPU_TASK_ID_VF 1
  224090. +#define IPU_TASK_ID_PP 2
  224091. +#define IPU_TASK_ID_MAX 3
  224092. + u8 task_id;
  224093. +
  224094. + int timeout;
  224095. +};
  224096. +
  224097. +enum {
  224098. + IPU_CHECK_OK = 0,
  224099. + IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN = 0x1,
  224100. + IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN = 0x2,
  224101. + IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN = 0x4,
  224102. + IPU_CHECK_ERR_MIN,
  224103. + IPU_CHECK_ERR_INPUT_CROP,
  224104. + IPU_CHECK_ERR_OUTPUT_CROP,
  224105. + IPU_CHECK_ERR_OVERLAY_CROP,
  224106. + IPU_CHECK_ERR_INPUT_OVER_LIMIT,
  224107. + IPU_CHECK_ERR_OV_OUT_NO_FIT,
  224108. + IPU_CHECK_ERR_OVERLAY_WITH_VDI,
  224109. + IPU_CHECK_ERR_PROC_NO_NEED,
  224110. + IPU_CHECK_ERR_SPLIT_INPUTW_OVER,
  224111. + IPU_CHECK_ERR_SPLIT_INPUTH_OVER,
  224112. + IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER,
  224113. + IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER,
  224114. + IPU_CHECK_ERR_SPLIT_WITH_ROT,
  224115. + IPU_CHECK_ERR_NOT_SUPPORT,
  224116. + IPU_CHECK_ERR_NOT16ALIGN,
  224117. + IPU_CHECK_ERR_W_DOWNSIZE_OVER,
  224118. + IPU_CHECK_ERR_H_DOWNSIZE_OVER,
  224119. +};
  224120. +
  224121. +/* IOCTL commands */
  224122. +#define IPU_CHECK_TASK _IOWR('I', 0x1, struct ipu_task)
  224123. +#define IPU_QUEUE_TASK _IOW('I', 0x2, struct ipu_task)
  224124. +#define IPU_ALLOC _IOWR('I', 0x3, int)
  224125. +#define IPU_FREE _IOW('I', 0x4, int)
  224126. +
  224127. +#endif
  224128. diff -Nur linux-3.14.14/include/uapi/linux/isl29023.h linux-imx6-3.14/include/uapi/linux/isl29023.h
  224129. --- linux-3.14.14/include/uapi/linux/isl29023.h 1969-12-31 18:00:00.000000000 -0600
  224130. +++ linux-imx6-3.14/include/uapi/linux/isl29023.h 2014-12-08 00:31:55.448418001 -0600
  224131. @@ -0,0 +1,47 @@
  224132. +/*
  224133. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  224134. + */
  224135. +
  224136. +/*
  224137. + * This program is free software; you can redistribute it and/or modify
  224138. + * it under the terms of the GNU General Public License as published by
  224139. + * the Free Software Foundation; either version 2 of the License, or
  224140. + * (at your option) any later version.
  224141. +
  224142. + * This program is distributed in the hope that it will be useful,
  224143. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  224144. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  224145. + * GNU General Public License for more details.
  224146. +
  224147. + * You should have received a copy of the GNU General Public License along
  224148. + * with this program; if not, write to the Free Software Foundation, Inc.,
  224149. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  224150. + */
  224151. +
  224152. +#ifndef __UAPI_LINUX_ISL29023_H__
  224153. +#define __UAPI_LINUX_ISL29023_H__
  224154. +
  224155. +#include <linux/types.h>
  224156. +
  224157. +#define ISL29023_PD_MODE 0x0
  224158. +#define ISL29023_ALS_ONCE_MODE 0x1
  224159. +#define ISL29023_IR_ONCE_MODE 0x2
  224160. +#define ISL29023_ALS_CONT_MODE 0x5
  224161. +#define ISL29023_IR_CONT_MODE 0x6
  224162. +
  224163. +#define ISL29023_INT_PERSISTS_1 0x0
  224164. +#define ISL29023_INT_PERSISTS_4 0x1
  224165. +#define ISL29023_INT_PERSISTS_8 0x2
  224166. +#define ISL29023_INT_PERSISTS_16 0x3
  224167. +
  224168. +#define ISL29023_RES_16 0x0
  224169. +#define ISL29023_RES_12 0x1
  224170. +#define ISL29023_RES_8 0x2
  224171. +#define ISL29023_RES_4 0x3
  224172. +
  224173. +#define ISL29023_RANGE_1K 0x0
  224174. +#define ISL29023_RANGE_4K 0x1
  224175. +#define ISL29023_RANGE_16K 0x2
  224176. +#define ISL29023_RANGE_64K 0x3
  224177. +
  224178. +#endif
  224179. diff -Nur linux-3.14.14/include/uapi/linux/Kbuild linux-imx6-3.14/include/uapi/linux/Kbuild
  224180. --- linux-3.14.14/include/uapi/linux/Kbuild 2014-07-28 10:07:25.000000000 -0500
  224181. +++ linux-imx6-3.14/include/uapi/linux/Kbuild 2014-12-08 00:31:55.432418001 -0600
  224182. @@ -226,6 +226,7 @@
  224183. header-y += kvm_para.h
  224184. endif
  224185. +header-y += ipu.h
  224186. header-y += l2tp.h
  224187. header-y += libc-compat.h
  224188. header-y += limits.h
  224189. @@ -253,6 +254,9 @@
  224190. header-y += msdos_fs.h
  224191. header-y += msg.h
  224192. header-y += mtio.h
  224193. +header-y += mxcfb.h
  224194. +header-y += mxc_asrc.h
  224195. +header-y += mxc_v4l2.h
  224196. header-y += n_r3964.h
  224197. header-y += nbd.h
  224198. header-y += ncp.h
  224199. @@ -318,6 +322,8 @@
  224200. header-y += prctl.h
  224201. header-y += ptp_clock.h
  224202. header-y += ptrace.h
  224203. +header-y += pxp_dma.h
  224204. +header-y += pxp_device.h
  224205. header-y += qnx4_fs.h
  224206. header-y += qnxtypes.h
  224207. header-y += quota.h
  224208. diff -Nur linux-3.14.14/include/uapi/linux/mxc_asrc.h linux-imx6-3.14/include/uapi/linux/mxc_asrc.h
  224209. --- linux-3.14.14/include/uapi/linux/mxc_asrc.h 1969-12-31 18:00:00.000000000 -0600
  224210. +++ linux-imx6-3.14/include/uapi/linux/mxc_asrc.h 2014-12-08 00:31:55.452418001 -0600
  224211. @@ -0,0 +1,143 @@
  224212. +/*
  224213. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  224214. + *
  224215. + * The code contained herein is licensed under the GNU General Public
  224216. + * License. You may obtain a copy of the GNU General Public License
  224217. + * Version 2 or later at the following locations:
  224218. + *
  224219. + * http://www.opensource.org/licenses/gpl-license.html
  224220. + * http://www.gnu.org/copyleft/gpl.html
  224221. + *
  224222. + * @file mxc_asrc.h
  224223. + *
  224224. + * @brief i.MX Asynchronous Sample Rate Converter
  224225. + *
  224226. + * @ingroup Audio
  224227. + */
  224228. +
  224229. +#ifndef __MXC_ASRC_UAPI_H__
  224230. +#define __MXC_ASRC_UAPI_H__
  224231. +
  224232. +#define ASRC_IOC_MAGIC 'C'
  224233. +
  224234. +#define ASRC_REQ_PAIR _IOWR(ASRC_IOC_MAGIC, 0, struct asrc_req)
  224235. +#define ASRC_CONFIG_PAIR _IOWR(ASRC_IOC_MAGIC, 1, struct asrc_config)
  224236. +#define ASRC_RELEASE_PAIR _IOW(ASRC_IOC_MAGIC, 2, enum asrc_pair_index)
  224237. +#define ASRC_CONVERT _IOW(ASRC_IOC_MAGIC, 3, struct asrc_convert_buffer)
  224238. +#define ASRC_START_CONV _IOW(ASRC_IOC_MAGIC, 4, enum asrc_pair_index)
  224239. +#define ASRC_STOP_CONV _IOW(ASRC_IOC_MAGIC, 5, enum asrc_pair_index)
  224240. +#define ASRC_STATUS _IOW(ASRC_IOC_MAGIC, 6, struct asrc_status_flags)
  224241. +#define ASRC_FLUSH _IOW(ASRC_IOC_MAGIC, 7, enum asrc_pair_index)
  224242. +
  224243. +enum asrc_pair_index {
  224244. + ASRC_UNVALID_PAIR = -1,
  224245. + ASRC_PAIR_A = 0,
  224246. + ASRC_PAIR_B = 1,
  224247. + ASRC_PAIR_C = 2,
  224248. +};
  224249. +
  224250. +#define ASRC_PAIR_MAX_NUM (ASRC_PAIR_C + 1)
  224251. +
  224252. +enum asrc_inclk {
  224253. + INCLK_NONE = 0x03,
  224254. + INCLK_ESAI_RX = 0x00,
  224255. + INCLK_SSI1_RX = 0x01,
  224256. + INCLK_SSI2_RX = 0x02,
  224257. + INCLK_SSI3_RX = 0x07,
  224258. + INCLK_SPDIF_RX = 0x04,
  224259. + INCLK_MLB_CLK = 0x05,
  224260. + INCLK_PAD = 0x06,
  224261. + INCLK_ESAI_TX = 0x08,
  224262. + INCLK_SSI1_TX = 0x09,
  224263. + INCLK_SSI2_TX = 0x0a,
  224264. + INCLK_SSI3_TX = 0x0b,
  224265. + INCLK_SPDIF_TX = 0x0c,
  224266. + INCLK_ASRCK1_CLK = 0x0f,
  224267. +};
  224268. +
  224269. +enum asrc_outclk {
  224270. + OUTCLK_NONE = 0x03,
  224271. + OUTCLK_ESAI_TX = 0x00,
  224272. + OUTCLK_SSI1_TX = 0x01,
  224273. + OUTCLK_SSI2_TX = 0x02,
  224274. + OUTCLK_SSI3_TX = 0x07,
  224275. + OUTCLK_SPDIF_TX = 0x04,
  224276. + OUTCLK_MLB_CLK = 0x05,
  224277. + OUTCLK_PAD = 0x06,
  224278. + OUTCLK_ESAI_RX = 0x08,
  224279. + OUTCLK_SSI1_RX = 0x09,
  224280. + OUTCLK_SSI2_RX = 0x0a,
  224281. + OUTCLK_SSI3_RX = 0x0b,
  224282. + OUTCLK_SPDIF_RX = 0x0c,
  224283. + OUTCLK_ASRCK1_CLK = 0x0f,
  224284. +};
  224285. +
  224286. +enum asrc_word_width {
  224287. + ASRC_WIDTH_24_BIT = 0,
  224288. + ASRC_WIDTH_16_BIT = 1,
  224289. + ASRC_WIDTH_8_BIT = 2,
  224290. +};
  224291. +
  224292. +struct asrc_config {
  224293. + enum asrc_pair_index pair;
  224294. + unsigned int channel_num;
  224295. + unsigned int buffer_num;
  224296. + unsigned int dma_buffer_size;
  224297. + unsigned int input_sample_rate;
  224298. + unsigned int output_sample_rate;
  224299. + enum asrc_word_width input_word_width;
  224300. + enum asrc_word_width output_word_width;
  224301. + enum asrc_inclk inclk;
  224302. + enum asrc_outclk outclk;
  224303. +};
  224304. +
  224305. +struct asrc_pair {
  224306. + unsigned int start_channel;
  224307. + unsigned int chn_num;
  224308. + unsigned int chn_max;
  224309. + unsigned int active;
  224310. + unsigned int overload_error;
  224311. +};
  224312. +
  224313. +struct asrc_req {
  224314. + unsigned int chn_num;
  224315. + enum asrc_pair_index index;
  224316. +};
  224317. +
  224318. +struct asrc_querybuf {
  224319. + unsigned int buffer_index;
  224320. + unsigned int input_length;
  224321. + unsigned int output_length;
  224322. + unsigned long input_offset;
  224323. + unsigned long output_offset;
  224324. +};
  224325. +
  224326. +struct asrc_convert_buffer {
  224327. + void *input_buffer_vaddr;
  224328. + void *output_buffer_vaddr;
  224329. + unsigned int input_buffer_length;
  224330. + unsigned int output_buffer_length;
  224331. +};
  224332. +
  224333. +struct asrc_buffer {
  224334. + unsigned int index;
  224335. + unsigned int length;
  224336. + unsigned int output_last_length;
  224337. + int buf_valid;
  224338. +};
  224339. +
  224340. +struct asrc_status_flags {
  224341. + enum asrc_pair_index index;
  224342. + unsigned int overload_error;
  224343. +};
  224344. +
  224345. +#define ASRC_BUF_NA -35 /* ASRC DQ's buffer is NOT available */
  224346. +#define ASRC_BUF_AV 35 /* ASRC DQ's buffer is available */
  224347. +enum asrc_error_status {
  224348. + ASRC_TASK_Q_OVERLOAD = 0x01,
  224349. + ASRC_OUTPUT_TASK_OVERLOAD = 0x02,
  224350. + ASRC_INPUT_TASK_OVERLOAD = 0x04,
  224351. + ASRC_OUTPUT_BUFFER_OVERFLOW = 0x08,
  224352. + ASRC_INPUT_BUFFER_UNDERRUN = 0x10,
  224353. +};
  224354. +#endif/* __MXC_ASRC_UAPI_H__ */
  224355. diff -Nur linux-3.14.14/include/uapi/linux/mxcfb.h linux-imx6-3.14/include/uapi/linux/mxcfb.h
  224356. --- linux-3.14.14/include/uapi/linux/mxcfb.h 1969-12-31 18:00:00.000000000 -0600
  224357. +++ linux-imx6-3.14/include/uapi/linux/mxcfb.h 2014-12-08 00:31:55.452418001 -0600
  224358. @@ -0,0 +1,174 @@
  224359. +/*
  224360. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  224361. + */
  224362. +
  224363. +/*
  224364. + * This program is free software; you can redistribute it and/or modify
  224365. + * it under the terms of the GNU General Public License as published by
  224366. + * the Free Software Foundation; either version 2 of the License, or
  224367. + * (at your option) any later version.
  224368. + *
  224369. + * This program is distributed in the hope that it will be useful,
  224370. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  224371. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  224372. + * GNU General Public License for more details.
  224373. + *
  224374. + * You should have received a copy of the GNU General Public License along
  224375. + * with this program; if not, write to the Free Software Foundation, Inc.,
  224376. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  224377. + */
  224378. +
  224379. +/*
  224380. + * @file uapi/linux/mxcfb.h
  224381. + *
  224382. + * @brief Global header file for the MXC frame buffer
  224383. + *
  224384. + * @ingroup Framebuffer
  224385. + */
  224386. +#ifndef __ASM_ARCH_MXCFB_H__
  224387. +#define __ASM_ARCH_MXCFB_H__
  224388. +
  224389. +#include <linux/fb.h>
  224390. +
  224391. +#define FB_SYNC_OE_LOW_ACT 0x80000000
  224392. +#define FB_SYNC_CLK_LAT_FALL 0x40000000
  224393. +#define FB_SYNC_DATA_INVERT 0x20000000
  224394. +#define FB_SYNC_CLK_IDLE_EN 0x10000000
  224395. +#define FB_SYNC_SHARP_MODE 0x08000000
  224396. +#define FB_SYNC_SWAP_RGB 0x04000000
  224397. +#define FB_ACCEL_TRIPLE_FLAG 0x00000000
  224398. +#define FB_ACCEL_DOUBLE_FLAG 0x00000001
  224399. +
  224400. +struct mxcfb_gbl_alpha {
  224401. + int enable;
  224402. + int alpha;
  224403. +};
  224404. +
  224405. +struct mxcfb_loc_alpha {
  224406. + int enable;
  224407. + int alpha_in_pixel;
  224408. + unsigned long alpha_phy_addr0;
  224409. + unsigned long alpha_phy_addr1;
  224410. +};
  224411. +
  224412. +struct mxcfb_color_key {
  224413. + int enable;
  224414. + __u32 color_key;
  224415. +};
  224416. +
  224417. +struct mxcfb_pos {
  224418. + __u16 x;
  224419. + __u16 y;
  224420. +};
  224421. +
  224422. +struct mxcfb_gamma {
  224423. + int enable;
  224424. + int constk[16];
  224425. + int slopek[16];
  224426. +};
  224427. +
  224428. +struct mxcfb_rect {
  224429. + __u32 top;
  224430. + __u32 left;
  224431. + __u32 width;
  224432. + __u32 height;
  224433. +};
  224434. +
  224435. +#define GRAYSCALE_8BIT 0x1
  224436. +#define GRAYSCALE_8BIT_INVERTED 0x2
  224437. +#define GRAYSCALE_4BIT 0x3
  224438. +#define GRAYSCALE_4BIT_INVERTED 0x4
  224439. +
  224440. +#define AUTO_UPDATE_MODE_REGION_MODE 0
  224441. +#define AUTO_UPDATE_MODE_AUTOMATIC_MODE 1
  224442. +
  224443. +#define UPDATE_SCHEME_SNAPSHOT 0
  224444. +#define UPDATE_SCHEME_QUEUE 1
  224445. +#define UPDATE_SCHEME_QUEUE_AND_MERGE 2
  224446. +
  224447. +#define UPDATE_MODE_PARTIAL 0x0
  224448. +#define UPDATE_MODE_FULL 0x1
  224449. +
  224450. +#define WAVEFORM_MODE_AUTO 257
  224451. +
  224452. +#define TEMP_USE_AMBIENT 0x1000
  224453. +
  224454. +#define EPDC_FLAG_ENABLE_INVERSION 0x01
  224455. +#define EPDC_FLAG_FORCE_MONOCHROME 0x02
  224456. +#define EPDC_FLAG_USE_CMAP 0x04
  224457. +#define EPDC_FLAG_USE_ALT_BUFFER 0x100
  224458. +#define EPDC_FLAG_TEST_COLLISION 0x200
  224459. +#define EPDC_FLAG_GROUP_UPDATE 0x400
  224460. +#define EPDC_FLAG_USE_DITHERING_Y1 0x2000
  224461. +#define EPDC_FLAG_USE_DITHERING_Y4 0x4000
  224462. +
  224463. +#define FB_POWERDOWN_DISABLE -1
  224464. +
  224465. +struct mxcfb_alt_buffer_data {
  224466. + __u32 phys_addr;
  224467. + __u32 width; /* width of entire buffer */
  224468. + __u32 height; /* height of entire buffer */
  224469. + struct mxcfb_rect alt_update_region; /* region within buffer to update */
  224470. +};
  224471. +
  224472. +struct mxcfb_update_data {
  224473. + struct mxcfb_rect update_region;
  224474. + __u32 waveform_mode;
  224475. + __u32 update_mode;
  224476. + __u32 update_marker;
  224477. + int temp;
  224478. + unsigned int flags;
  224479. + struct mxcfb_alt_buffer_data alt_buffer_data;
  224480. +};
  224481. +
  224482. +struct mxcfb_update_marker_data {
  224483. + __u32 update_marker;
  224484. + __u32 collision_test;
  224485. +};
  224486. +
  224487. +/*
  224488. + * Structure used to define waveform modes for driver
  224489. + * Needed for driver to perform auto-waveform selection
  224490. + */
  224491. +struct mxcfb_waveform_modes {
  224492. + int mode_init;
  224493. + int mode_du;
  224494. + int mode_gc4;
  224495. + int mode_gc8;
  224496. + int mode_gc16;
  224497. + int mode_gc32;
  224498. +};
  224499. +
  224500. +/*
  224501. + * Structure used to define a 5*3 matrix of parameters for
  224502. + * setting IPU DP CSC module related to this framebuffer.
  224503. + */
  224504. +struct mxcfb_csc_matrix {
  224505. + int param[5][3];
  224506. +};
  224507. +
  224508. +#define MXCFB_WAIT_FOR_VSYNC _IOW('F', 0x20, u_int32_t)
  224509. +#define MXCFB_SET_GBL_ALPHA _IOW('F', 0x21, struct mxcfb_gbl_alpha)
  224510. +#define MXCFB_SET_CLR_KEY _IOW('F', 0x22, struct mxcfb_color_key)
  224511. +#define MXCFB_SET_OVERLAY_POS _IOWR('F', 0x24, struct mxcfb_pos)
  224512. +#define MXCFB_GET_FB_IPU_CHAN _IOR('F', 0x25, u_int32_t)
  224513. +#define MXCFB_SET_LOC_ALPHA _IOWR('F', 0x26, struct mxcfb_loc_alpha)
  224514. +#define MXCFB_SET_LOC_ALP_BUF _IOW('F', 0x27, unsigned long)
  224515. +#define MXCFB_SET_GAMMA _IOW('F', 0x28, struct mxcfb_gamma)
  224516. +#define MXCFB_GET_FB_IPU_DI _IOR('F', 0x29, u_int32_t)
  224517. +#define MXCFB_GET_DIFMT _IOR('F', 0x2A, u_int32_t)
  224518. +#define MXCFB_GET_FB_BLANK _IOR('F', 0x2B, u_int32_t)
  224519. +#define MXCFB_SET_DIFMT _IOW('F', 0x2C, u_int32_t)
  224520. +#define MXCFB_CSC_UPDATE _IOW('F', 0x2D, struct mxcfb_csc_matrix)
  224521. +
  224522. +/* IOCTLs for E-ink panel updates */
  224523. +#define MXCFB_SET_WAVEFORM_MODES _IOW('F', 0x2B, struct mxcfb_waveform_modes)
  224524. +#define MXCFB_SET_TEMPERATURE _IOW('F', 0x2C, int32_t)
  224525. +#define MXCFB_SET_AUTO_UPDATE_MODE _IOW('F', 0x2D, __u32)
  224526. +#define MXCFB_SEND_UPDATE _IOW('F', 0x2E, struct mxcfb_update_data)
  224527. +#define MXCFB_WAIT_FOR_UPDATE_COMPLETE _IOWR('F', 0x2F, struct mxcfb_update_marker_data)
  224528. +#define MXCFB_SET_PWRDOWN_DELAY _IOW('F', 0x30, int32_t)
  224529. +#define MXCFB_GET_PWRDOWN_DELAY _IOR('F', 0x31, int32_t)
  224530. +#define MXCFB_SET_UPDATE_SCHEME _IOW('F', 0x32, __u32)
  224531. +#define MXCFB_GET_WORK_BUFFER _IOWR('F', 0x34, unsigned long)
  224532. +#endif
  224533. diff -Nur linux-3.14.14/include/uapi/linux/mxc_mlb.h linux-imx6-3.14/include/uapi/linux/mxc_mlb.h
  224534. --- linux-3.14.14/include/uapi/linux/mxc_mlb.h 1969-12-31 18:00:00.000000000 -0600
  224535. +++ linux-imx6-3.14/include/uapi/linux/mxc_mlb.h 2014-12-08 00:31:55.452418001 -0600
  224536. @@ -0,0 +1,55 @@
  224537. +/*
  224538. + * mxc_mlb.h
  224539. + *
  224540. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  224541. + */
  224542. +
  224543. +/*
  224544. + * The code contained herein is licensed under the GNU General Public
  224545. + * License. You may obtain a copy of the GNU General Public License
  224546. + * Version 2 or later at the following locations:
  224547. + *
  224548. + * http://www.opensource.org/licenses/gpl-license.html
  224549. + * http://www.gnu.org/copyleft/gpl.html
  224550. + */
  224551. +
  224552. +#ifndef _MXC_MLB_UAPI_H
  224553. +#define _MXC_MLB_UAPI_H
  224554. +
  224555. +/* define IOCTL command */
  224556. +#define MLB_DBG_RUNTIME _IO('S', 0x09)
  224557. +#define MLB_SET_FPS _IOW('S', 0x10, unsigned int)
  224558. +#define MLB_GET_VER _IOR('S', 0x11, unsigned long)
  224559. +#define MLB_SET_DEVADDR _IOR('S', 0x12, unsigned char)
  224560. +
  224561. +/*!
  224562. + * set channel address for each logical channel
  224563. + * the MSB 16bits is for tx channel, the left LSB is for rx channel
  224564. + */
  224565. +#define MLB_CHAN_SETADDR _IOW('S', 0x13, unsigned int)
  224566. +#define MLB_CHAN_STARTUP _IO('S', 0x14)
  224567. +#define MLB_CHAN_SHUTDOWN _IO('S', 0x15)
  224568. +#define MLB_CHAN_GETEVENT _IOR('S', 0x16, unsigned long)
  224569. +
  224570. +#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
  224571. +#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
  224572. +#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
  224573. +#define MLB_IRQ_ENABLE _IO('S', 0x20)
  224574. +#define MLB_IRQ_DISABLE _IO('S', 0x21)
  224575. +
  224576. +/*!
  224577. + * MLB event define
  224578. + */
  224579. +enum {
  224580. + MLB_EVT_TX_PROTO_ERR_CUR = 1 << 0,
  224581. + MLB_EVT_TX_BRK_DETECT_CUR = 1 << 1,
  224582. + MLB_EVT_TX_PROTO_ERR_PREV = 1 << 8,
  224583. + MLB_EVT_TX_BRK_DETECT_PREV = 1 << 9,
  224584. + MLB_EVT_RX_PROTO_ERR_CUR = 1 << 16,
  224585. + MLB_EVT_RX_BRK_DETECT_CUR = 1 << 17,
  224586. + MLB_EVT_RX_PROTO_ERR_PREV = 1 << 24,
  224587. + MLB_EVT_RX_BRK_DETECT_PREV = 1 << 25,
  224588. +};
  224589. +
  224590. +
  224591. +#endif /* _MXC_MLB_H */
  224592. diff -Nur linux-3.14.14/include/uapi/linux/mxc_v4l2.h linux-imx6-3.14/include/uapi/linux/mxc_v4l2.h
  224593. --- linux-3.14.14/include/uapi/linux/mxc_v4l2.h 1969-12-31 18:00:00.000000000 -0600
  224594. +++ linux-imx6-3.14/include/uapi/linux/mxc_v4l2.h 2014-12-08 00:31:55.452418001 -0600
  224595. @@ -0,0 +1,56 @@
  224596. +/*
  224597. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  224598. + */
  224599. +
  224600. +/*
  224601. + * This program is free software; you can redistribute it and/or modify
  224602. + * it under the terms of the GNU General Public License as published by
  224603. + * the Free Software Foundation; either version 2 of the License, or
  224604. + * (at your option) any later version.
  224605. + *
  224606. + * This program is distributed in the hope that it will be useful,
  224607. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  224608. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  224609. + * GNU General Public License for more details.
  224610. + *
  224611. + * You should have received a copy of the GNU General Public License along
  224612. + * with this program; if not, write to the Free Software Foundation, Inc.,
  224613. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  224614. + */
  224615. +
  224616. +/*!
  224617. + * @file uapi/linux/mxc_v4l2.h
  224618. + *
  224619. + * @brief MXC V4L2 private header file
  224620. + *
  224621. + * @ingroup MXC V4L2
  224622. + */
  224623. +
  224624. +#ifndef __ASM_ARCH_MXC_V4L2_H__
  224625. +#define __ASM_ARCH_MXC_V4L2_H__
  224626. +
  224627. +/*
  224628. + * For IPUv1 and IPUv3, V4L2_CID_MXC_ROT means encoder ioctl ID.
  224629. + * And V4L2_CID_MXC_VF_ROT is viewfinder ioctl ID only for IPUv1 and IPUv3.
  224630. + */
  224631. +#define V4L2_CID_MXC_ROT (V4L2_CID_PRIVATE_BASE + 0)
  224632. +#define V4L2_CID_MXC_FLASH (V4L2_CID_PRIVATE_BASE + 1)
  224633. +#define V4L2_CID_MXC_VF_ROT (V4L2_CID_PRIVATE_BASE + 2)
  224634. +#define V4L2_CID_MXC_MOTION (V4L2_CID_PRIVATE_BASE + 3)
  224635. +#define V4L2_CID_MXC_SWITCH_CAM (V4L2_CID_PRIVATE_BASE + 6)
  224636. +
  224637. +#define V4L2_MXC_ROTATE_NONE 0
  224638. +#define V4L2_MXC_ROTATE_VERT_FLIP 1
  224639. +#define V4L2_MXC_ROTATE_HORIZ_FLIP 2
  224640. +#define V4L2_MXC_ROTATE_180 3
  224641. +#define V4L2_MXC_ROTATE_90_RIGHT 4
  224642. +#define V4L2_MXC_ROTATE_90_RIGHT_VFLIP 5
  224643. +#define V4L2_MXC_ROTATE_90_RIGHT_HFLIP 6
  224644. +#define V4L2_MXC_ROTATE_90_LEFT 7
  224645. +
  224646. +struct v4l2_mxc_offset {
  224647. + uint32_t u_offset;
  224648. + uint32_t v_offset;
  224649. +};
  224650. +
  224651. +#endif
  224652. diff -Nur linux-3.14.14/include/uapi/linux/ptp_clock.h linux-imx6-3.14/include/uapi/linux/ptp_clock.h
  224653. --- linux-3.14.14/include/uapi/linux/ptp_clock.h 2014-07-28 10:07:25.000000000 -0500
  224654. +++ linux-imx6-3.14/include/uapi/linux/ptp_clock.h 2014-12-08 00:31:55.460418001 -0600
  224655. @@ -50,7 +50,8 @@
  224656. int n_ext_ts; /* Number of external time stamp channels. */
  224657. int n_per_out; /* Number of programmable periodic signals. */
  224658. int pps; /* Whether the clock supports a PPS callback. */
  224659. - int rsv[15]; /* Reserved for future use. */
  224660. + int n_pins; /* Number of input/output pins. */
  224661. + int rsv[14]; /* Reserved for future use. */
  224662. };
  224663. struct ptp_extts_request {
  224664. @@ -80,6 +81,40 @@
  224665. struct ptp_clock_time ts[2 * PTP_MAX_SAMPLES + 1];
  224666. };
  224667. +enum ptp_pin_function {
  224668. + PTP_PF_NONE,
  224669. + PTP_PF_EXTTS,
  224670. + PTP_PF_PEROUT,
  224671. + PTP_PF_PHYSYNC,
  224672. +};
  224673. +
  224674. +struct ptp_pin_desc {
  224675. + /*
  224676. + * Hardware specific human readable pin name. This field is
  224677. + * set by the kernel during the PTP_PIN_GETFUNC ioctl and is
  224678. + * ignored for the PTP_PIN_SETFUNC ioctl.
  224679. + */
  224680. + char name[64];
  224681. + /*
  224682. + * Pin index in the range of zero to ptp_clock_caps.n_pins - 1.
  224683. + */
  224684. + unsigned int index;
  224685. + /*
  224686. + * Which of the PTP_PF_xxx functions to use on this pin.
  224687. + */
  224688. + unsigned int func;
  224689. + /*
  224690. + * The specific channel to use for this function.
  224691. + * This corresponds to the 'index' field of the
  224692. + * PTP_EXTTS_REQUEST and PTP_PEROUT_REQUEST ioctls.
  224693. + */
  224694. + unsigned int chan;
  224695. + /*
  224696. + * Reserved for future use.
  224697. + */
  224698. + unsigned int rsv[5];
  224699. +};
  224700. +
  224701. #define PTP_CLK_MAGIC '='
  224702. #define PTP_CLOCK_GETCAPS _IOR(PTP_CLK_MAGIC, 1, struct ptp_clock_caps)
  224703. @@ -87,6 +122,8 @@
  224704. #define PTP_PEROUT_REQUEST _IOW(PTP_CLK_MAGIC, 3, struct ptp_perout_request)
  224705. #define PTP_ENABLE_PPS _IOW(PTP_CLK_MAGIC, 4, int)
  224706. #define PTP_SYS_OFFSET _IOW(PTP_CLK_MAGIC, 5, struct ptp_sys_offset)
  224707. +#define PTP_PIN_GETFUNC _IOWR(PTP_CLK_MAGIC, 6, struct ptp_pin_desc)
  224708. +#define PTP_PIN_SETFUNC _IOW(PTP_CLK_MAGIC, 7, struct ptp_pin_desc)
  224709. struct ptp_extts_event {
  224710. struct ptp_clock_time t; /* Time event occured. */
  224711. diff -Nur linux-3.14.14/include/uapi/linux/pxp_device.h linux-imx6-3.14/include/uapi/linux/pxp_device.h
  224712. --- linux-3.14.14/include/uapi/linux/pxp_device.h 1969-12-31 18:00:00.000000000 -0600
  224713. +++ linux-imx6-3.14/include/uapi/linux/pxp_device.h 2014-12-08 00:31:55.460418001 -0600
  224714. @@ -0,0 +1,63 @@
  224715. +/*
  224716. + * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  224717. + *
  224718. + * This program is free software; you can redistribute it and/or modify
  224719. + * it under the terms of the GNU General Public License as published by
  224720. + * the Free Software Foundation; either version 2 of the License, or
  224721. + * (at your option) any later version.
  224722. + *
  224723. + * This program is distributed in the hope that it will be useful,
  224724. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  224725. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  224726. + * GNU General Public License for more details.
  224727. + *
  224728. + * You should have received a copy of the GNU General Public License
  224729. + * along with this program; if not, write to the Free Software
  224730. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  224731. + *
  224732. + */
  224733. +#ifndef _UAPI_PXP_DEVICE
  224734. +#define _UAPI_PXP_DEVICE
  224735. +
  224736. +#include <linux/pxp_dma.h>
  224737. +
  224738. +struct pxp_chan_handle {
  224739. + unsigned int handle;
  224740. + int hist_status;
  224741. +};
  224742. +
  224743. +struct pxp_mem_desc {
  224744. + unsigned int handle;
  224745. + unsigned int size;
  224746. + dma_addr_t phys_addr;
  224747. + unsigned int virt_uaddr; /* virtual user space address */
  224748. + unsigned int mtype;
  224749. +};
  224750. +
  224751. +struct pxp_mem_flush {
  224752. + unsigned int handle;
  224753. + unsigned int type;
  224754. +};
  224755. +
  224756. +#define PXP_IOC_MAGIC 'P'
  224757. +
  224758. +#define PXP_IOC_GET_CHAN _IOR(PXP_IOC_MAGIC, 0, struct pxp_mem_desc)
  224759. +#define PXP_IOC_PUT_CHAN _IOW(PXP_IOC_MAGIC, 1, struct pxp_mem_desc)
  224760. +#define PXP_IOC_CONFIG_CHAN _IOW(PXP_IOC_MAGIC, 2, struct pxp_mem_desc)
  224761. +#define PXP_IOC_START_CHAN _IOW(PXP_IOC_MAGIC, 3, struct pxp_mem_desc)
  224762. +#define PXP_IOC_GET_PHYMEM _IOWR(PXP_IOC_MAGIC, 4, struct pxp_mem_desc)
  224763. +#define PXP_IOC_PUT_PHYMEM _IOW(PXP_IOC_MAGIC, 5, struct pxp_mem_desc)
  224764. +#define PXP_IOC_WAIT4CMPLT _IOWR(PXP_IOC_MAGIC, 6, struct pxp_mem_desc)
  224765. +#define PXP_IOC_FLUSH_PHYMEM _IOR(PXP_IOC_MAGIC, 7, struct pxp_mem_flush)
  224766. +
  224767. +/* Memory types supported*/
  224768. +#define MEMORY_TYPE_UNCACHED 0x0
  224769. +#define MEMORY_TYPE_WC 0x1
  224770. +#define MEMORY_TYPE_CACHED 0x2
  224771. +
  224772. +/* Cache flush operations */
  224773. +#define CACHE_CLEAN 0x1
  224774. +#define CACHE_INVALIDATE 0x2
  224775. +#define CACHE_FLUSH 0x4
  224776. +
  224777. +#endif
  224778. diff -Nur linux-3.14.14/include/uapi/linux/pxp_dma.h linux-imx6-3.14/include/uapi/linux/pxp_dma.h
  224779. --- linux-3.14.14/include/uapi/linux/pxp_dma.h 1969-12-31 18:00:00.000000000 -0600
  224780. +++ linux-imx6-3.14/include/uapi/linux/pxp_dma.h 2014-12-08 00:31:55.460418001 -0600
  224781. @@ -0,0 +1,173 @@
  224782. +/*
  224783. + * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  224784. + *
  224785. + * This program is free software; you can redistribute it and/or modify
  224786. + * it under the terms of the GNU General Public License as published by
  224787. + * the Free Software Foundation; either version 2 of the License, or
  224788. + * (at your option) any later version.
  224789. + *
  224790. + * This program is distributed in the hope that it will be useful,
  224791. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  224792. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  224793. + * GNU General Public License for more details.
  224794. + *
  224795. + * You should have received a copy of the GNU General Public License
  224796. + * along with this program; if not, write to the Free Software
  224797. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  224798. + *
  224799. + */
  224800. +#ifndef _UAPI_PXP_DMA
  224801. +#define _UAPI_PXP_DMA
  224802. +
  224803. +#include <linux/posix_types.h>
  224804. +#include <linux/types.h>
  224805. +
  224806. +#ifndef __KERNEL__
  224807. +typedef unsigned long dma_addr_t;
  224808. +typedef unsigned char bool;
  224809. +#endif
  224810. +
  224811. +/* PXP Pixel format definitions */
  224812. +/* Four-character-code (FOURCC) */
  224813. +#define fourcc(a, b, c, d)\
  224814. + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
  224815. +
  224816. +/*!
  224817. + * @name PXP Pixel Formats
  224818. + *
  224819. + * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
  224820. + * the same used by V4L2 API.
  224821. + */
  224822. +
  224823. +/*! @} */
  224824. +/*! @name RGB Formats */
  224825. +/*! @{ */
  224826. +#define PXP_PIX_FMT_RGB332 fourcc('R', 'G', 'B', '1') /*!< 8 RGB-3-3-2 */
  224827. +#define PXP_PIX_FMT_RGB555 fourcc('R', 'G', 'B', 'O') /*!< 16 RGB-5-5-5 */
  224828. +#define PXP_PIX_FMT_RGB565 fourcc('R', 'G', 'B', 'P') /*!< 1 6 RGB-5-6-5 */
  224829. +#define PXP_PIX_FMT_RGB666 fourcc('R', 'G', 'B', '6') /*!< 18 RGB-6-6-6 */
  224830. +#define PXP_PIX_FMT_BGR666 fourcc('B', 'G', 'R', '6') /*!< 18 BGR-6-6-6 */
  224831. +#define PXP_PIX_FMT_BGR24 fourcc('B', 'G', 'R', '3') /*!< 24 BGR-8-8-8 */
  224832. +#define PXP_PIX_FMT_RGB24 fourcc('R', 'G', 'B', '3') /*!< 24 RGB-8-8-8 */
  224833. +#define PXP_PIX_FMT_BGR32 fourcc('B', 'G', 'R', '4') /*!< 32 BGR-8-8-8-8 */
  224834. +#define PXP_PIX_FMT_BGRA32 fourcc('B', 'G', 'R', 'A') /*!< 32 BGR-8-8-8-8 */
  224835. +#define PXP_PIX_FMT_RGB32 fourcc('R', 'G', 'B', '4') /*!< 32 RGB-8-8-8-8 */
  224836. +#define PXP_PIX_FMT_RGBA32 fourcc('R', 'G', 'B', 'A') /*!< 32 RGB-8-8-8-8 */
  224837. +#define PXP_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R') /*!< 32 ABGR-8-8-8-8 */
  224838. +/*! @} */
  224839. +/*! @name YUV Interleaved Formats */
  224840. +/*! @{ */
  224841. +#define PXP_PIX_FMT_YUYV fourcc('Y', 'U', 'Y', 'V') /*!< 16 YUV 4:2:2 */
  224842. +#define PXP_PIX_FMT_UYVY fourcc('U', 'Y', 'V', 'Y') /*!< 16 YUV 4:2:2 */
  224843. +#define PXP_PIX_FMT_VYUY fourcc('V', 'Y', 'U', 'Y') /*!< 16 YVU 4:2:2 */
  224844. +#define PXP_PIX_FMT_YVYU fourcc('Y', 'V', 'Y', 'U') /*!< 16 YVU 4:2:2 */
  224845. +#define PXP_PIX_FMT_Y41P fourcc('Y', '4', '1', 'P') /*!< 12 YUV 4:1:1 */
  224846. +#define PXP_PIX_FMT_YUV444 fourcc('Y', '4', '4', '4') /*!< 24 YUV 4:4:4 */
  224847. +/* two planes -- one Y, one Cb + Cr interleaved */
  224848. +#define PXP_PIX_FMT_NV12 fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
  224849. +#define PXP_PIX_FMT_NV21 fourcc('N', 'V', '2', '1') /* 12 Y/CbCr 4:2:0 */
  224850. +#define PXP_PIX_FMT_NV16 fourcc('N', 'V', '1', '6') /* 12 Y/CbCr 4:2:2 */
  224851. +#define PXP_PIX_FMT_NV61 fourcc('N', 'V', '6', '1') /* 12 Y/CbCr 4:2:2 */
  224852. +/*! @} */
  224853. +/*! @name YUV Planar Formats */
  224854. +/*! @{ */
  224855. +#define PXP_PIX_FMT_GREY fourcc('G', 'R', 'E', 'Y') /*!< 8 Greyscale */
  224856. +#define PXP_PIX_FMT_GY04 fourcc('G', 'Y', '0', '4') /*!< 4 Greyscale */
  224857. +#define PXP_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*!< 9 YVU 4:1:0 */
  224858. +#define PXP_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*!< 9 YUV 4:1:0 */
  224859. +#define PXP_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*!< 12 YVU 4:2:0 */
  224860. +#define PXP_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*!< 12 YUV 4:2:0 */
  224861. +#define PXP_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2') /*!< 12 YUV 4:2:0 */
  224862. +#define PXP_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*!< 16 YVU 4:2:2 */
  224863. +#define PXP_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*!< 16 YUV 4:2:2 */
  224864. +/*! @} */
  224865. +
  224866. +#define PXP_LUT_NONE 0x0
  224867. +#define PXP_LUT_INVERT 0x1
  224868. +#define PXP_LUT_BLACK_WHITE 0x2
  224869. +#define PXP_LUT_USE_CMAP 0x4
  224870. +
  224871. +#define NR_PXP_VIRT_CHANNEL 16
  224872. +
  224873. +/* Order significant! */
  224874. +enum pxp_channel_status {
  224875. + PXP_CHANNEL_FREE,
  224876. + PXP_CHANNEL_INITIALIZED,
  224877. + PXP_CHANNEL_READY,
  224878. +};
  224879. +
  224880. +struct rect {
  224881. + int top; /* Upper left coordinate of rectangle */
  224882. + int left;
  224883. + int width;
  224884. + int height;
  224885. +};
  224886. +
  224887. +struct pxp_layer_param {
  224888. + unsigned short width;
  224889. + unsigned short height;
  224890. + unsigned short stride; /* aka pitch */
  224891. + unsigned int pixel_fmt;
  224892. +
  224893. + /* layers combining parameters
  224894. + * (these are ignored for S0 and output
  224895. + * layers, and only apply for OL layer)
  224896. + */
  224897. + bool combine_enable;
  224898. + unsigned int color_key_enable;
  224899. + unsigned int color_key;
  224900. + bool global_alpha_enable;
  224901. + /* global alpha is either override or multiply */
  224902. + bool global_override;
  224903. + unsigned char global_alpha;
  224904. + bool alpha_invert;
  224905. + bool local_alpha_enable;
  224906. +
  224907. + dma_addr_t paddr;
  224908. +};
  224909. +
  224910. +struct pxp_proc_data {
  224911. + /* S0 Transformation Info */
  224912. + int scaling;
  224913. + int hflip;
  224914. + int vflip;
  224915. + int rotate;
  224916. + int rot_pos;
  224917. + int yuv;
  224918. +
  224919. + /* Source rectangle (srect) defines the sub-rectangle
  224920. + * within S0 to undergo processing.
  224921. + */
  224922. + struct rect srect;
  224923. + /* Dest rect (drect) defines how to position the processed
  224924. + * source rectangle (after resizing) within the output frame,
  224925. + * whose dimensions are defined in pxp->pxp_conf_state.out_param
  224926. + */
  224927. + struct rect drect;
  224928. +
  224929. + /* Current S0 configuration */
  224930. + unsigned int bgcolor;
  224931. +
  224932. + /* Output overlay support */
  224933. + int overlay_state;
  224934. +
  224935. + /* LUT transformation on Y data */
  224936. + int lut_transform;
  224937. + unsigned char *lut_map; /* 256 entries */
  224938. + bool lut_map_updated; /* Map recently changed */
  224939. + bool combine_enable;
  224940. +};
  224941. +
  224942. +struct pxp_config_data {
  224943. + struct pxp_layer_param s0_param;
  224944. + struct pxp_layer_param ol_param[8];
  224945. + struct pxp_layer_param out_param;
  224946. + struct pxp_proc_data proc_data;
  224947. + int layer_nr;
  224948. +
  224949. + /* Users don't touch */
  224950. + int handle;
  224951. +};
  224952. +
  224953. +
  224954. +#endif
  224955. diff -Nur linux-3.14.14/include/video/mxc_edid.h linux-imx6-3.14/include/video/mxc_edid.h
  224956. --- linux-3.14.14/include/video/mxc_edid.h 1969-12-31 18:00:00.000000000 -0600
  224957. +++ linux-imx6-3.14/include/video/mxc_edid.h 2014-12-08 00:31:55.476418001 -0600
  224958. @@ -0,0 +1,105 @@
  224959. +/*
  224960. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  224961. + */
  224962. +
  224963. +/*
  224964. + * The code contained herein is licensed under the GNU General Public
  224965. + * License. You may obtain a copy of the GNU General Public License
  224966. + * Version 2 or later at the following locations:
  224967. + *
  224968. + * http://www.opensource.org/licenses/gpl-license.html
  224969. + * http://www.gnu.org/copyleft/gpl.html
  224970. + */
  224971. +
  224972. +/*!
  224973. + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
  224974. + */
  224975. +
  224976. +/*!
  224977. + * @file mxc_edid.h
  224978. + *
  224979. + * @brief MXC EDID tools
  224980. + *
  224981. + * @ingroup Framebuffer
  224982. + */
  224983. +
  224984. +#ifndef MXC_EDID_H
  224985. +#define MXC_EDID_H
  224986. +
  224987. +#include <linux/fb.h>
  224988. +
  224989. +#define FB_VMODE_ASPECT_4_3 0x10
  224990. +#define FB_VMODE_ASPECT_16_9 0x20
  224991. +#define FB_VMODE_ASPECT_MASK (FB_VMODE_ASPECT_4_3 | FB_VMODE_ASPECT_16_9)
  224992. +
  224993. +enum cea_audio_coding_types {
  224994. + AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0,
  224995. + AUDIO_CODING_TYPE_LPCM = 1,
  224996. + AUDIO_CODING_TYPE_AC3 = 2,
  224997. + AUDIO_CODING_TYPE_MPEG1 = 3,
  224998. + AUDIO_CODING_TYPE_MP3 = 4,
  224999. + AUDIO_CODING_TYPE_MPEG2 = 5,
  225000. + AUDIO_CODING_TYPE_AACLC = 6,
  225001. + AUDIO_CODING_TYPE_DTS = 7,
  225002. + AUDIO_CODING_TYPE_ATRAC = 8,
  225003. + AUDIO_CODING_TYPE_SACD = 9,
  225004. + AUDIO_CODING_TYPE_EAC3 = 10,
  225005. + AUDIO_CODING_TYPE_DTS_HD = 11,
  225006. + AUDIO_CODING_TYPE_MLP = 12,
  225007. + AUDIO_CODING_TYPE_DST = 13,
  225008. + AUDIO_CODING_TYPE_WMAPRO = 14,
  225009. + AUDIO_CODING_TYPE_RESERVED = 15,
  225010. +};
  225011. +
  225012. +struct mxc_hdmi_3d_format {
  225013. + unsigned char vic_order_2d;
  225014. + unsigned char struct_3d;
  225015. + unsigned char detail_3d;
  225016. + unsigned char reserved;
  225017. +};
  225018. +
  225019. +struct mxc_edid_cfg {
  225020. + bool cea_underscan;
  225021. + bool cea_basicaudio;
  225022. + bool cea_ycbcr444;
  225023. + bool cea_ycbcr422;
  225024. + bool hdmi_cap;
  225025. +
  225026. + /*VSD*/
  225027. + bool vsd_support_ai;
  225028. + bool vsd_dc_48bit;
  225029. + bool vsd_dc_36bit;
  225030. + bool vsd_dc_30bit;
  225031. + bool vsd_dc_y444;
  225032. + bool vsd_dvi_dual;
  225033. +
  225034. + bool vsd_cnc0;
  225035. + bool vsd_cnc1;
  225036. + bool vsd_cnc2;
  225037. + bool vsd_cnc3;
  225038. +
  225039. + u8 vsd_video_latency;
  225040. + u8 vsd_audio_latency;
  225041. + u8 vsd_I_video_latency;
  225042. + u8 vsd_I_audio_latency;
  225043. +
  225044. + u8 physical_address[4];
  225045. + u8 hdmi_vic[64];
  225046. + struct mxc_hdmi_3d_format hdmi_3d_format[64];
  225047. + u16 hdmi_3d_mask_all;
  225048. + u16 hdmi_3d_struct_all;
  225049. + u32 vsd_max_tmdsclk_rate;
  225050. +
  225051. + u8 max_channels;
  225052. + u8 sample_sizes;
  225053. + u8 sample_rates;
  225054. + u8 speaker_alloc;
  225055. +};
  225056. +
  225057. +int mxc_edid_var_to_vic(struct fb_var_screeninfo *var);
  225058. +int mxc_edid_mode_to_vic(const struct fb_videomode *mode);
  225059. +int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
  225060. + unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi);
  225061. +int mxc_edid_parse_ext_blk(unsigned char *edid, struct mxc_edid_cfg *cfg,
  225062. + struct fb_monspecs *specs);
  225063. +#endif
  225064. diff -Nur linux-3.14.14/include/video/mxc_hdmi.h linux-imx6-3.14/include/video/mxc_hdmi.h
  225065. --- linux-3.14.14/include/video/mxc_hdmi.h 1969-12-31 18:00:00.000000000 -0600
  225066. +++ linux-imx6-3.14/include/video/mxc_hdmi.h 2014-12-08 00:31:55.476418001 -0600
  225067. @@ -0,0 +1,1027 @@
  225068. +/*
  225069. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  225070. + */
  225071. +
  225072. +/*
  225073. + * This program is free software; you can redistribute it and/or modify
  225074. + * it under the terms of the GNU General Public License as published by
  225075. + * the Free Software Foundation; either version 2 of the License, or
  225076. + * (at your option) any later version.
  225077. + *
  225078. + * This program is distributed in the hope that it will be useful,
  225079. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  225080. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  225081. + * GNU General Public License for more details.
  225082. + *
  225083. + * You should have received a copy of the GNU General Public License along
  225084. + * with this program; if not, write to the Free Software Foundation, Inc.,
  225085. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  225086. + */
  225087. +
  225088. +#ifndef __MXC_HDMI_H__
  225089. +#define __MXC_HDMI_H__
  225090. +
  225091. +/*
  225092. + * Hdmi controller registers
  225093. + */
  225094. +
  225095. +/* Identification Registers */
  225096. +#define HDMI_DESIGN_ID 0x0000
  225097. +#define HDMI_REVISION_ID 0x0001
  225098. +#define HDMI_PRODUCT_ID0 0x0002
  225099. +#define HDMI_PRODUCT_ID1 0x0003
  225100. +#define HDMI_CONFIG0_ID 0x0004
  225101. +#define HDMI_CONFIG1_ID 0x0005
  225102. +#define HDMI_CONFIG2_ID 0x0006
  225103. +#define HDMI_CONFIG3_ID 0x0007
  225104. +
  225105. +/* Interrupt Registers */
  225106. +#define HDMI_IH_FC_STAT0 0x0100
  225107. +#define HDMI_IH_FC_STAT1 0x0101
  225108. +#define HDMI_IH_FC_STAT2 0x0102
  225109. +#define HDMI_IH_AS_STAT0 0x0103
  225110. +#define HDMI_IH_PHY_STAT0 0x0104
  225111. +#define HDMI_IH_I2CM_STAT0 0x0105
  225112. +#define HDMI_IH_CEC_STAT0 0x0106
  225113. +#define HDMI_IH_VP_STAT0 0x0107
  225114. +#define HDMI_IH_I2CMPHY_STAT0 0x0108
  225115. +#define HDMI_IH_AHBDMAAUD_STAT0 0x0109
  225116. +
  225117. +#define HDMI_IH_MUTE_FC_STAT0 0x0180
  225118. +#define HDMI_IH_MUTE_FC_STAT1 0x0181
  225119. +#define HDMI_IH_MUTE_FC_STAT2 0x0182
  225120. +#define HDMI_IH_MUTE_AS_STAT0 0x0183
  225121. +#define HDMI_IH_MUTE_PHY_STAT0 0x0184
  225122. +#define HDMI_IH_MUTE_I2CM_STAT0 0x0185
  225123. +#define HDMI_IH_MUTE_CEC_STAT0 0x0186
  225124. +#define HDMI_IH_MUTE_VP_STAT0 0x0187
  225125. +#define HDMI_IH_MUTE_I2CMPHY_STAT0 0x0188
  225126. +#define HDMI_IH_MUTE_AHBDMAAUD_STAT0 0x0189
  225127. +#define HDMI_IH_MUTE 0x01FF
  225128. +
  225129. +/* Video Sample Registers */
  225130. +#define HDMI_TX_INVID0 0x0200
  225131. +#define HDMI_TX_INSTUFFING 0x0201
  225132. +#define HDMI_TX_GYDATA0 0x0202
  225133. +#define HDMI_TX_GYDATA1 0x0203
  225134. +#define HDMI_TX_RCRDATA0 0x0204
  225135. +#define HDMI_TX_RCRDATA1 0x0205
  225136. +#define HDMI_TX_BCBDATA0 0x0206
  225137. +#define HDMI_TX_BCBDATA1 0x0207
  225138. +
  225139. +/* Video Packetizer Registers */
  225140. +#define HDMI_VP_STATUS 0x0800
  225141. +#define HDMI_VP_PR_CD 0x0801
  225142. +#define HDMI_VP_STUFF 0x0802
  225143. +#define HDMI_VP_REMAP 0x0803
  225144. +#define HDMI_VP_CONF 0x0804
  225145. +#define HDMI_VP_STAT 0x0805
  225146. +#define HDMI_VP_INT 0x0806
  225147. +#define HDMI_VP_MASK 0x0807
  225148. +#define HDMI_VP_POL 0x0808
  225149. +
  225150. +/* Frame Composer Registers */
  225151. +#define HDMI_FC_INVIDCONF 0x1000
  225152. +#define HDMI_FC_INHACTV0 0x1001
  225153. +#define HDMI_FC_INHACTV1 0x1002
  225154. +#define HDMI_FC_INHBLANK0 0x1003
  225155. +#define HDMI_FC_INHBLANK1 0x1004
  225156. +#define HDMI_FC_INVACTV0 0x1005
  225157. +#define HDMI_FC_INVACTV1 0x1006
  225158. +#define HDMI_FC_INVBLANK 0x1007
  225159. +#define HDMI_FC_HSYNCINDELAY0 0x1008
  225160. +#define HDMI_FC_HSYNCINDELAY1 0x1009
  225161. +#define HDMI_FC_HSYNCINWIDTH0 0x100A
  225162. +#define HDMI_FC_HSYNCINWIDTH1 0x100B
  225163. +#define HDMI_FC_VSYNCINDELAY 0x100C
  225164. +#define HDMI_FC_VSYNCINWIDTH 0x100D
  225165. +#define HDMI_FC_INFREQ0 0x100E
  225166. +#define HDMI_FC_INFREQ1 0x100F
  225167. +#define HDMI_FC_INFREQ2 0x1010
  225168. +#define HDMI_FC_CTRLDUR 0x1011
  225169. +#define HDMI_FC_EXCTRLDUR 0x1012
  225170. +#define HDMI_FC_EXCTRLSPAC 0x1013
  225171. +#define HDMI_FC_CH0PREAM 0x1014
  225172. +#define HDMI_FC_CH1PREAM 0x1015
  225173. +#define HDMI_FC_CH2PREAM 0x1016
  225174. +#define HDMI_FC_AVICONF3 0x1017
  225175. +#define HDMI_FC_GCP 0x1018
  225176. +#define HDMI_FC_AVICONF0 0x1019
  225177. +#define HDMI_FC_AVICONF1 0x101A
  225178. +#define HDMI_FC_AVICONF2 0x101B
  225179. +#define HDMI_FC_AVIVID 0x101C
  225180. +#define HDMI_FC_AVIETB0 0x101D
  225181. +#define HDMI_FC_AVIETB1 0x101E
  225182. +#define HDMI_FC_AVISBB0 0x101F
  225183. +#define HDMI_FC_AVISBB1 0x1020
  225184. +#define HDMI_FC_AVIELB0 0x1021
  225185. +#define HDMI_FC_AVIELB1 0x1022
  225186. +#define HDMI_FC_AVISRB0 0x1023
  225187. +#define HDMI_FC_AVISRB1 0x1024
  225188. +#define HDMI_FC_AUDICONF0 0x1025
  225189. +#define HDMI_FC_AUDICONF1 0x1026
  225190. +#define HDMI_FC_AUDICONF2 0x1027
  225191. +#define HDMI_FC_AUDICONF3 0x1028
  225192. +#define HDMI_FC_VSDIEEEID0 0x1029
  225193. +#define HDMI_FC_VSDSIZE 0x102A
  225194. +#define HDMI_FC_VSDIEEEID1 0x1030
  225195. +#define HDMI_FC_VSDIEEEID2 0x1031
  225196. +#define HDMI_FC_VSDPAYLOAD0 0x1032
  225197. +#define HDMI_FC_VSDPAYLOAD1 0x1033
  225198. +#define HDMI_FC_VSDPAYLOAD2 0x1034
  225199. +#define HDMI_FC_VSDPAYLOAD3 0x1035
  225200. +#define HDMI_FC_VSDPAYLOAD4 0x1036
  225201. +#define HDMI_FC_VSDPAYLOAD5 0x1037
  225202. +#define HDMI_FC_VSDPAYLOAD6 0x1038
  225203. +#define HDMI_FC_VSDPAYLOAD7 0x1039
  225204. +#define HDMI_FC_VSDPAYLOAD8 0x103A
  225205. +#define HDMI_FC_VSDPAYLOAD9 0x103B
  225206. +#define HDMI_FC_VSDPAYLOAD10 0x103C
  225207. +#define HDMI_FC_VSDPAYLOAD11 0x103D
  225208. +#define HDMI_FC_VSDPAYLOAD12 0x103E
  225209. +#define HDMI_FC_VSDPAYLOAD13 0x103F
  225210. +#define HDMI_FC_VSDPAYLOAD14 0x1040
  225211. +#define HDMI_FC_VSDPAYLOAD15 0x1041
  225212. +#define HDMI_FC_VSDPAYLOAD16 0x1042
  225213. +#define HDMI_FC_VSDPAYLOAD17 0x1043
  225214. +#define HDMI_FC_VSDPAYLOAD18 0x1044
  225215. +#define HDMI_FC_VSDPAYLOAD19 0x1045
  225216. +#define HDMI_FC_VSDPAYLOAD20 0x1046
  225217. +#define HDMI_FC_VSDPAYLOAD21 0x1047
  225218. +#define HDMI_FC_VSDPAYLOAD22 0x1048
  225219. +#define HDMI_FC_VSDPAYLOAD23 0x1049
  225220. +#define HDMI_FC_SPDVENDORNAME0 0x104A
  225221. +#define HDMI_FC_SPDVENDORNAME1 0x104B
  225222. +#define HDMI_FC_SPDVENDORNAME2 0x104C
  225223. +#define HDMI_FC_SPDVENDORNAME3 0x104D
  225224. +#define HDMI_FC_SPDVENDORNAME4 0x104E
  225225. +#define HDMI_FC_SPDVENDORNAME5 0x104F
  225226. +#define HDMI_FC_SPDVENDORNAME6 0x1050
  225227. +#define HDMI_FC_SPDVENDORNAME7 0x1051
  225228. +#define HDMI_FC_SDPPRODUCTNAME0 0x1052
  225229. +#define HDMI_FC_SDPPRODUCTNAME1 0x1053
  225230. +#define HDMI_FC_SDPPRODUCTNAME2 0x1054
  225231. +#define HDMI_FC_SDPPRODUCTNAME3 0x1055
  225232. +#define HDMI_FC_SDPPRODUCTNAME4 0x1056
  225233. +#define HDMI_FC_SDPPRODUCTNAME5 0x1057
  225234. +#define HDMI_FC_SDPPRODUCTNAME6 0x1058
  225235. +#define HDMI_FC_SDPPRODUCTNAME7 0x1059
  225236. +#define HDMI_FC_SDPPRODUCTNAME8 0x105A
  225237. +#define HDMI_FC_SDPPRODUCTNAME9 0x105B
  225238. +#define HDMI_FC_SDPPRODUCTNAME10 0x105C
  225239. +#define HDMI_FC_SDPPRODUCTNAME11 0x105D
  225240. +#define HDMI_FC_SDPPRODUCTNAME12 0x105E
  225241. +#define HDMI_FC_SDPPRODUCTNAME13 0x105F
  225242. +#define HDMI_FC_SDPPRODUCTNAME14 0x1060
  225243. +#define HDMI_FC_SPDPRODUCTNAME15 0x1061
  225244. +#define HDMI_FC_SPDDEVICEINF 0x1062
  225245. +#define HDMI_FC_AUDSCONF 0x1063
  225246. +#define HDMI_FC_AUDSSTAT 0x1064
  225247. +#define HDMI_FC_DATACH0FILL 0x1070
  225248. +#define HDMI_FC_DATACH1FILL 0x1071
  225249. +#define HDMI_FC_DATACH2FILL 0x1072
  225250. +#define HDMI_FC_CTRLQHIGH 0x1073
  225251. +#define HDMI_FC_CTRLQLOW 0x1074
  225252. +#define HDMI_FC_ACP0 0x1075
  225253. +#define HDMI_FC_ACP28 0x1076
  225254. +#define HDMI_FC_ACP27 0x1077
  225255. +#define HDMI_FC_ACP26 0x1078
  225256. +#define HDMI_FC_ACP25 0x1079
  225257. +#define HDMI_FC_ACP24 0x107A
  225258. +#define HDMI_FC_ACP23 0x107B
  225259. +#define HDMI_FC_ACP22 0x107C
  225260. +#define HDMI_FC_ACP21 0x107D
  225261. +#define HDMI_FC_ACP20 0x107E
  225262. +#define HDMI_FC_ACP19 0x107F
  225263. +#define HDMI_FC_ACP18 0x1080
  225264. +#define HDMI_FC_ACP17 0x1081
  225265. +#define HDMI_FC_ACP16 0x1082
  225266. +#define HDMI_FC_ACP15 0x1083
  225267. +#define HDMI_FC_ACP14 0x1084
  225268. +#define HDMI_FC_ACP13 0x1085
  225269. +#define HDMI_FC_ACP12 0x1086
  225270. +#define HDMI_FC_ACP11 0x1087
  225271. +#define HDMI_FC_ACP10 0x1088
  225272. +#define HDMI_FC_ACP9 0x1089
  225273. +#define HDMI_FC_ACP8 0x108A
  225274. +#define HDMI_FC_ACP7 0x108B
  225275. +#define HDMI_FC_ACP6 0x108C
  225276. +#define HDMI_FC_ACP5 0x108D
  225277. +#define HDMI_FC_ACP4 0x108E
  225278. +#define HDMI_FC_ACP3 0x108F
  225279. +#define HDMI_FC_ACP2 0x1090
  225280. +#define HDMI_FC_ACP1 0x1091
  225281. +#define HDMI_FC_ISCR1_0 0x1092
  225282. +#define HDMI_FC_ISCR1_16 0x1093
  225283. +#define HDMI_FC_ISCR1_15 0x1094
  225284. +#define HDMI_FC_ISCR1_14 0x1095
  225285. +#define HDMI_FC_ISCR1_13 0x1096
  225286. +#define HDMI_FC_ISCR1_12 0x1097
  225287. +#define HDMI_FC_ISCR1_11 0x1098
  225288. +#define HDMI_FC_ISCR1_10 0x1099
  225289. +#define HDMI_FC_ISCR1_9 0x109A
  225290. +#define HDMI_FC_ISCR1_8 0x109B
  225291. +#define HDMI_FC_ISCR1_7 0x109C
  225292. +#define HDMI_FC_ISCR1_6 0x109D
  225293. +#define HDMI_FC_ISCR1_5 0x109E
  225294. +#define HDMI_FC_ISCR1_4 0x109F
  225295. +#define HDMI_FC_ISCR1_3 0x10A0
  225296. +#define HDMI_FC_ISCR1_2 0x10A1
  225297. +#define HDMI_FC_ISCR1_1 0x10A2
  225298. +#define HDMI_FC_ISCR2_15 0x10A3
  225299. +#define HDMI_FC_ISCR2_14 0x10A4
  225300. +#define HDMI_FC_ISCR2_13 0x10A5
  225301. +#define HDMI_FC_ISCR2_12 0x10A6
  225302. +#define HDMI_FC_ISCR2_11 0x10A7
  225303. +#define HDMI_FC_ISCR2_10 0x10A8
  225304. +#define HDMI_FC_ISCR2_9 0x10A9
  225305. +#define HDMI_FC_ISCR2_8 0x10AA
  225306. +#define HDMI_FC_ISCR2_7 0x10AB
  225307. +#define HDMI_FC_ISCR2_6 0x10AC
  225308. +#define HDMI_FC_ISCR2_5 0x10AD
  225309. +#define HDMI_FC_ISCR2_4 0x10AE
  225310. +#define HDMI_FC_ISCR2_3 0x10AF
  225311. +#define HDMI_FC_ISCR2_2 0x10B0
  225312. +#define HDMI_FC_ISCR2_1 0x10B1
  225313. +#define HDMI_FC_ISCR2_0 0x10B2
  225314. +#define HDMI_FC_DATAUTO0 0x10B3
  225315. +#define HDMI_FC_DATAUTO1 0x10B4
  225316. +#define HDMI_FC_DATAUTO2 0x10B5
  225317. +#define HDMI_FC_DATMAN 0x10B6
  225318. +#define HDMI_FC_DATAUTO3 0x10B7
  225319. +#define HDMI_FC_RDRB0 0x10B8
  225320. +#define HDMI_FC_RDRB1 0x10B9
  225321. +#define HDMI_FC_RDRB2 0x10BA
  225322. +#define HDMI_FC_RDRB3 0x10BB
  225323. +#define HDMI_FC_RDRB4 0x10BC
  225324. +#define HDMI_FC_RDRB5 0x10BD
  225325. +#define HDMI_FC_RDRB6 0x10BE
  225326. +#define HDMI_FC_RDRB7 0x10BF
  225327. +#define HDMI_FC_STAT0 0x10D0
  225328. +#define HDMI_FC_INT0 0x10D1
  225329. +#define HDMI_FC_MASK0 0x10D2
  225330. +#define HDMI_FC_POL0 0x10D3
  225331. +#define HDMI_FC_STAT1 0x10D4
  225332. +#define HDMI_FC_INT1 0x10D5
  225333. +#define HDMI_FC_MASK1 0x10D6
  225334. +#define HDMI_FC_POL1 0x10D7
  225335. +#define HDMI_FC_STAT2 0x10D8
  225336. +#define HDMI_FC_INT2 0x10D9
  225337. +#define HDMI_FC_MASK2 0x10DA
  225338. +#define HDMI_FC_POL2 0x10DB
  225339. +#define HDMI_FC_PRCONF 0x10E0
  225340. +
  225341. +#define HDMI_FC_GMD_STAT 0x1100
  225342. +#define HDMI_FC_GMD_EN 0x1101
  225343. +#define HDMI_FC_GMD_UP 0x1102
  225344. +#define HDMI_FC_GMD_CONF 0x1103
  225345. +#define HDMI_FC_GMD_HB 0x1104
  225346. +#define HDMI_FC_GMD_PB0 0x1105
  225347. +#define HDMI_FC_GMD_PB1 0x1106
  225348. +#define HDMI_FC_GMD_PB2 0x1107
  225349. +#define HDMI_FC_GMD_PB3 0x1108
  225350. +#define HDMI_FC_GMD_PB4 0x1109
  225351. +#define HDMI_FC_GMD_PB5 0x110A
  225352. +#define HDMI_FC_GMD_PB6 0x110B
  225353. +#define HDMI_FC_GMD_PB7 0x110C
  225354. +#define HDMI_FC_GMD_PB8 0x110D
  225355. +#define HDMI_FC_GMD_PB9 0x110E
  225356. +#define HDMI_FC_GMD_PB10 0x110F
  225357. +#define HDMI_FC_GMD_PB11 0x1110
  225358. +#define HDMI_FC_GMD_PB12 0x1111
  225359. +#define HDMI_FC_GMD_PB13 0x1112
  225360. +#define HDMI_FC_GMD_PB14 0x1113
  225361. +#define HDMI_FC_GMD_PB15 0x1114
  225362. +#define HDMI_FC_GMD_PB16 0x1115
  225363. +#define HDMI_FC_GMD_PB17 0x1116
  225364. +#define HDMI_FC_GMD_PB18 0x1117
  225365. +#define HDMI_FC_GMD_PB19 0x1118
  225366. +#define HDMI_FC_GMD_PB20 0x1119
  225367. +#define HDMI_FC_GMD_PB21 0x111A
  225368. +#define HDMI_FC_GMD_PB22 0x111B
  225369. +#define HDMI_FC_GMD_PB23 0x111C
  225370. +#define HDMI_FC_GMD_PB24 0x111D
  225371. +#define HDMI_FC_GMD_PB25 0x111E
  225372. +#define HDMI_FC_GMD_PB26 0x111F
  225373. +#define HDMI_FC_GMD_PB27 0x1120
  225374. +
  225375. +#define HDMI_FC_DBGFORCE 0x1200
  225376. +#define HDMI_FC_DBGAUD0CH0 0x1201
  225377. +#define HDMI_FC_DBGAUD1CH0 0x1202
  225378. +#define HDMI_FC_DBGAUD2CH0 0x1203
  225379. +#define HDMI_FC_DBGAUD0CH1 0x1204
  225380. +#define HDMI_FC_DBGAUD1CH1 0x1205
  225381. +#define HDMI_FC_DBGAUD2CH1 0x1206
  225382. +#define HDMI_FC_DBGAUD0CH2 0x1207
  225383. +#define HDMI_FC_DBGAUD1CH2 0x1208
  225384. +#define HDMI_FC_DBGAUD2CH2 0x1209
  225385. +#define HDMI_FC_DBGAUD0CH3 0x120A
  225386. +#define HDMI_FC_DBGAUD1CH3 0x120B
  225387. +#define HDMI_FC_DBGAUD2CH3 0x120C
  225388. +#define HDMI_FC_DBGAUD0CH4 0x120D
  225389. +#define HDMI_FC_DBGAUD1CH4 0x120E
  225390. +#define HDMI_FC_DBGAUD2CH4 0x120F
  225391. +#define HDMI_FC_DBGAUD0CH5 0x1210
  225392. +#define HDMI_FC_DBGAUD1CH5 0x1211
  225393. +#define HDMI_FC_DBGAUD2CH5 0x1212
  225394. +#define HDMI_FC_DBGAUD0CH6 0x1213
  225395. +#define HDMI_FC_DBGAUD1CH6 0x1214
  225396. +#define HDMI_FC_DBGAUD2CH6 0x1215
  225397. +#define HDMI_FC_DBGAUD0CH7 0x1216
  225398. +#define HDMI_FC_DBGAUD1CH7 0x1217
  225399. +#define HDMI_FC_DBGAUD2CH7 0x1218
  225400. +#define HDMI_FC_DBGTMDS0 0x1219
  225401. +#define HDMI_FC_DBGTMDS1 0x121A
  225402. +#define HDMI_FC_DBGTMDS2 0x121B
  225403. +
  225404. +/* HDMI Source PHY Registers */
  225405. +#define HDMI_PHY_CONF0 0x3000
  225406. +#define HDMI_PHY_TST0 0x3001
  225407. +#define HDMI_PHY_TST1 0x3002
  225408. +#define HDMI_PHY_TST2 0x3003
  225409. +#define HDMI_PHY_STAT0 0x3004
  225410. +#define HDMI_PHY_INT0 0x3005
  225411. +#define HDMI_PHY_MASK0 0x3006
  225412. +#define HDMI_PHY_POL0 0x3007
  225413. +
  225414. +/* HDMI Master PHY Registers */
  225415. +#define HDMI_PHY_I2CM_SLAVE_ADDR 0x3020
  225416. +#define HDMI_PHY_I2CM_ADDRESS_ADDR 0x3021
  225417. +#define HDMI_PHY_I2CM_DATAO_1_ADDR 0x3022
  225418. +#define HDMI_PHY_I2CM_DATAO_0_ADDR 0x3023
  225419. +#define HDMI_PHY_I2CM_DATAI_1_ADDR 0x3024
  225420. +#define HDMI_PHY_I2CM_DATAI_0_ADDR 0x3025
  225421. +#define HDMI_PHY_I2CM_OPERATION_ADDR 0x3026
  225422. +#define HDMI_PHY_I2CM_INT_ADDR 0x3027
  225423. +#define HDMI_PHY_I2CM_CTLINT_ADDR 0x3028
  225424. +#define HDMI_PHY_I2CM_DIV_ADDR 0x3029
  225425. +#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR 0x302a
  225426. +#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b
  225427. +#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c
  225428. +#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d
  225429. +#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e
  225430. +#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f
  225431. +#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030
  225432. +#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031
  225433. +#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032
  225434. +
  225435. +/* Audio Sampler Registers */
  225436. +#define HDMI_AUD_CONF0 0x3100
  225437. +#define HDMI_AUD_CONF1 0x3101
  225438. +#define HDMI_AUD_INT 0x3102
  225439. +#define HDMI_AUD_CONF2 0x3103
  225440. +#define HDMI_AUD_N1 0x3200
  225441. +#define HDMI_AUD_N2 0x3201
  225442. +#define HDMI_AUD_N3 0x3202
  225443. +#define HDMI_AUD_CTS1 0x3203
  225444. +#define HDMI_AUD_CTS2 0x3204
  225445. +#define HDMI_AUD_CTS3 0x3205
  225446. +#define HDMI_AUD_INPUTCLKFS 0x3206
  225447. +#define HDMI_AUD_SPDIFINT 0x3302
  225448. +#define HDMI_AUD_CONF0_HBR 0x3400
  225449. +#define HDMI_AUD_HBR_STATUS 0x3401
  225450. +#define HDMI_AUD_HBR_INT 0x3402
  225451. +#define HDMI_AUD_HBR_POL 0x3403
  225452. +#define HDMI_AUD_HBR_MASK 0x3404
  225453. +
  225454. +/* Generic Parallel Audio Interface Registers */
  225455. +/* Not used as GPAUD interface is not enabled in hw */
  225456. +#define HDMI_GP_CONF0 0x3500
  225457. +#define HDMI_GP_CONF1 0x3501
  225458. +#define HDMI_GP_CONF2 0x3502
  225459. +#define HDMI_GP_STAT 0x3503
  225460. +#define HDMI_GP_INT 0x3504
  225461. +#define HDMI_GP_MASK 0x3505
  225462. +#define HDMI_GP_POL 0x3506
  225463. +
  225464. +/* Audio DMA Registers */
  225465. +#define HDMI_AHB_DMA_CONF0 0x3600
  225466. +#define HDMI_AHB_DMA_START 0x3601
  225467. +#define HDMI_AHB_DMA_STOP 0x3602
  225468. +#define HDMI_AHB_DMA_THRSLD 0x3603
  225469. +#define HDMI_AHB_DMA_STRADDR0 0x3604
  225470. +#define HDMI_AHB_DMA_STRADDR1 0x3605
  225471. +#define HDMI_AHB_DMA_STRADDR2 0x3606
  225472. +#define HDMI_AHB_DMA_STRADDR3 0x3607
  225473. +#define HDMI_AHB_DMA_STPADDR0 0x3608
  225474. +#define HDMI_AHB_DMA_STPADDR1 0x3609
  225475. +#define HDMI_AHB_DMA_STPADDR2 0x360a
  225476. +#define HDMI_AHB_DMA_STPADDR3 0x360b
  225477. +#define HDMI_AHB_DMA_BSTADDR0 0x360c
  225478. +#define HDMI_AHB_DMA_BSTADDR1 0x360d
  225479. +#define HDMI_AHB_DMA_BSTADDR2 0x360e
  225480. +#define HDMI_AHB_DMA_BSTADDR3 0x360f
  225481. +#define HDMI_AHB_DMA_MBLENGTH0 0x3610
  225482. +#define HDMI_AHB_DMA_MBLENGTH1 0x3611
  225483. +#define HDMI_AHB_DMA_STAT 0x3612
  225484. +#define HDMI_AHB_DMA_INT 0x3613
  225485. +#define HDMI_AHB_DMA_MASK 0x3614
  225486. +#define HDMI_AHB_DMA_POL 0x3615
  225487. +#define HDMI_AHB_DMA_CONF1 0x3616
  225488. +#define HDMI_AHB_DMA_BUFFSTAT 0x3617
  225489. +#define HDMI_AHB_DMA_BUFFINT 0x3618
  225490. +#define HDMI_AHB_DMA_BUFFMASK 0x3619
  225491. +#define HDMI_AHB_DMA_BUFFPOL 0x361a
  225492. +
  225493. +/* Main Controller Registers */
  225494. +#define HDMI_MC_SFRDIV 0x4000
  225495. +#define HDMI_MC_CLKDIS 0x4001
  225496. +#define HDMI_MC_SWRSTZ 0x4002
  225497. +#define HDMI_MC_OPCTRL 0x4003
  225498. +#define HDMI_MC_FLOWCTRL 0x4004
  225499. +#define HDMI_MC_PHYRSTZ 0x4005
  225500. +#define HDMI_MC_LOCKONCLOCK 0x4006
  225501. +#define HDMI_MC_HEACPHY_RST 0x4007
  225502. +
  225503. +/* Color Space Converter Registers */
  225504. +#define HDMI_CSC_CFG 0x4100
  225505. +#define HDMI_CSC_SCALE 0x4101
  225506. +#define HDMI_CSC_COEF_A1_MSB 0x4102
  225507. +#define HDMI_CSC_COEF_A1_LSB 0x4103
  225508. +#define HDMI_CSC_COEF_A2_MSB 0x4104
  225509. +#define HDMI_CSC_COEF_A2_LSB 0x4105
  225510. +#define HDMI_CSC_COEF_A3_MSB 0x4106
  225511. +#define HDMI_CSC_COEF_A3_LSB 0x4107
  225512. +#define HDMI_CSC_COEF_A4_MSB 0x4108
  225513. +#define HDMI_CSC_COEF_A4_LSB 0x4109
  225514. +#define HDMI_CSC_COEF_B1_MSB 0x410A
  225515. +#define HDMI_CSC_COEF_B1_LSB 0x410B
  225516. +#define HDMI_CSC_COEF_B2_MSB 0x410C
  225517. +#define HDMI_CSC_COEF_B2_LSB 0x410D
  225518. +#define HDMI_CSC_COEF_B3_MSB 0x410E
  225519. +#define HDMI_CSC_COEF_B3_LSB 0x410F
  225520. +#define HDMI_CSC_COEF_B4_MSB 0x4110
  225521. +#define HDMI_CSC_COEF_B4_LSB 0x4111
  225522. +#define HDMI_CSC_COEF_C1_MSB 0x4112
  225523. +#define HDMI_CSC_COEF_C1_LSB 0x4113
  225524. +#define HDMI_CSC_COEF_C2_MSB 0x4114
  225525. +#define HDMI_CSC_COEF_C2_LSB 0x4115
  225526. +#define HDMI_CSC_COEF_C3_MSB 0x4116
  225527. +#define HDMI_CSC_COEF_C3_LSB 0x4117
  225528. +#define HDMI_CSC_COEF_C4_MSB 0x4118
  225529. +#define HDMI_CSC_COEF_C4_LSB 0x4119
  225530. +
  225531. +/* HDCP Interrupt Registers */
  225532. +#define HDMI_A_APIINTCLR 0x5006
  225533. +#define HDMI_A_APIINTSTAT 0x5007
  225534. +#define HDMI_A_APIINTMSK 0x5008
  225535. +
  225536. +/* CEC Engine Registers */
  225537. +#define HDMI_CEC_CTRL 0x7D00
  225538. +#define HDMI_CEC_STAT 0x7D01
  225539. +#define HDMI_CEC_MASK 0x7D02
  225540. +#define HDMI_CEC_POLARITY 0x7D03
  225541. +#define HDMI_CEC_INT 0x7D04
  225542. +#define HDMI_CEC_ADDR_L 0x7D05
  225543. +#define HDMI_CEC_ADDR_H 0x7D06
  225544. +#define HDMI_CEC_TX_CNT 0x7D07
  225545. +#define HDMI_CEC_RX_CNT 0x7D08
  225546. +#define HDMI_CEC_TX_DATA0 0x7D10
  225547. +#define HDMI_CEC_TX_DATA1 0x7D11
  225548. +#define HDMI_CEC_TX_DATA2 0x7D12
  225549. +#define HDMI_CEC_TX_DATA3 0x7D13
  225550. +#define HDMI_CEC_TX_DATA4 0x7D14
  225551. +#define HDMI_CEC_TX_DATA5 0x7D15
  225552. +#define HDMI_CEC_TX_DATA6 0x7D16
  225553. +#define HDMI_CEC_TX_DATA7 0x7D17
  225554. +#define HDMI_CEC_TX_DATA8 0x7D18
  225555. +#define HDMI_CEC_TX_DATA9 0x7D19
  225556. +#define HDMI_CEC_TX_DATA10 0x7D1a
  225557. +#define HDMI_CEC_TX_DATA11 0x7D1b
  225558. +#define HDMI_CEC_TX_DATA12 0x7D1c
  225559. +#define HDMI_CEC_TX_DATA13 0x7D1d
  225560. +#define HDMI_CEC_TX_DATA14 0x7D1e
  225561. +#define HDMI_CEC_TX_DATA15 0x7D1f
  225562. +#define HDMI_CEC_RX_DATA0 0x7D20
  225563. +#define HDMI_CEC_RX_DATA1 0x7D21
  225564. +#define HDMI_CEC_RX_DATA2 0x7D22
  225565. +#define HDMI_CEC_RX_DATA3 0x7D23
  225566. +#define HDMI_CEC_RX_DATA4 0x7D24
  225567. +#define HDMI_CEC_RX_DATA5 0x7D25
  225568. +#define HDMI_CEC_RX_DATA6 0x7D26
  225569. +#define HDMI_CEC_RX_DATA7 0x7D27
  225570. +#define HDMI_CEC_RX_DATA8 0x7D28
  225571. +#define HDMI_CEC_RX_DATA9 0x7D29
  225572. +#define HDMI_CEC_RX_DATA10 0x7D2a
  225573. +#define HDMI_CEC_RX_DATA11 0x7D2b
  225574. +#define HDMI_CEC_RX_DATA12 0x7D2c
  225575. +#define HDMI_CEC_RX_DATA13 0x7D2d
  225576. +#define HDMI_CEC_RX_DATA14 0x7D2e
  225577. +#define HDMI_CEC_RX_DATA15 0x7D2f
  225578. +#define HDMI_CEC_LOCK 0x7D30
  225579. +#define HDMI_CEC_WKUPCTRL 0x7D31
  225580. +
  225581. +/* I2C Master Registers (E-DDC) */
  225582. +#define HDMI_I2CM_SLAVE 0x7E00
  225583. +#define HDMI_I2CM_ADDRESS 0x7E01
  225584. +#define HDMI_I2CM_DATAO 0x7E02
  225585. +#define HDMI_I2CM_DATAI 0x7E03
  225586. +#define HDMI_I2CM_OPERATION 0x7E04
  225587. +#define HDMI_I2CM_INT 0x7E05
  225588. +#define HDMI_I2CM_CTLINT 0x7E06
  225589. +#define HDMI_I2CM_DIV 0x7E07
  225590. +#define HDMI_I2CM_SEGADDR 0x7E08
  225591. +#define HDMI_I2CM_SOFTRSTZ 0x7E09
  225592. +#define HDMI_I2CM_SEGPTR 0x7E0A
  225593. +#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR 0x7E0B
  225594. +#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x7E0C
  225595. +#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR 0x7E0D
  225596. +#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0x7E0E
  225597. +#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR 0x7E0F
  225598. +#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR 0x7E10
  225599. +#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR 0x7E11
  225600. +#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12
  225601. +
  225602. +/* Random Number Generator Registers (RNG) */
  225603. +#define HDMI_RNG_BASE 0x8000
  225604. +
  225605. +
  225606. +/*
  225607. + * Register field definitions
  225608. + */
  225609. +enum {
  225610. +/* IH_FC_INT2 field values */
  225611. + HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
  225612. + HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
  225613. + HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  225614. +
  225615. +/* IH_FC_STAT2 field values */
  225616. + HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03,
  225617. + HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
  225618. + HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  225619. +
  225620. +/* IH_PHY_STAT0 field values */
  225621. + HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20,
  225622. + HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10,
  225623. + HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8,
  225624. + HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4,
  225625. + HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2,
  225626. + HDMI_IH_PHY_STAT0_HPD = 0x1,
  225627. +
  225628. +/* IH_CEC_STAT0 field values */
  225629. + HDMI_IH_CEC_STAT0_WAKEUP = 0x40,
  225630. + HDMI_IH_CEC_STAT0_ERROR_FOLL = 0x20,
  225631. + HDMI_IH_CEC_STAT0_ERROR_INIT = 0x10,
  225632. + HDMI_IH_CEC_STAT0_ARB_LOST = 0x8,
  225633. + HDMI_IH_CEC_STAT0_NACK = 0x4,
  225634. + HDMI_IH_CEC_STAT0_EOM = 0x2,
  225635. + HDMI_IH_CEC_STAT0_DONE = 0x1,
  225636. +
  225637. +
  225638. +/* IH_MUTE_I2CMPHY_STAT0 field values */
  225639. + HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2,
  225640. + HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1,
  225641. +
  225642. +/* IH_PHY_STAT0 field values */
  225643. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE3 = 0x20,
  225644. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE2 = 0x10,
  225645. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE1 = 0x8,
  225646. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE0 = 0x4,
  225647. + HDMI_IH_MUTE_PHY_STAT0_TX_PHY_LOCK = 0x2,
  225648. + HDMI_IH_MUTE_PHY_STAT0_HPD = 0x1,
  225649. +
  225650. +/* IH and IH_MUTE convenience macro RX_SENSE | HPD*/
  225651. + HDMI_DVI_IH_STAT = 0x3D,
  225652. +
  225653. +
  225654. +/* IH_AHBDMAAUD_STAT0 field values */
  225655. + HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20,
  225656. + HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10,
  225657. + HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08,
  225658. + HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04,
  225659. + HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
  225660. + HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
  225661. +
  225662. +/* IH_MUTE_FC_STAT2 field values */
  225663. + HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03,
  225664. + HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
  225665. + HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  225666. +
  225667. +/* IH_MUTE_AHBDMAAUD_STAT0 field values */
  225668. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20,
  225669. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10,
  225670. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08,
  225671. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04,
  225672. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
  225673. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
  225674. +
  225675. +/* IH_MUTE field values */
  225676. + HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2,
  225677. + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1,
  225678. +
  225679. +/* TX_INVID0 field values */
  225680. + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80,
  225681. + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80,
  225682. + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00,
  225683. + HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F,
  225684. + HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0,
  225685. +
  225686. +/* TX_INSTUFFING field values */
  225687. + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4,
  225688. + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4,
  225689. + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0,
  225690. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2,
  225691. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2,
  225692. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0,
  225693. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1,
  225694. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1,
  225695. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0,
  225696. +
  225697. +/* VP_PR_CD field values */
  225698. + HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0,
  225699. + HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4,
  225700. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F,
  225701. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0,
  225702. +
  225703. +/* VP_STUFF field values */
  225704. + HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20,
  225705. + HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5,
  225706. + HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10,
  225707. + HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4,
  225708. + HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8,
  225709. + HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3,
  225710. + HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4,
  225711. + HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4,
  225712. + HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0,
  225713. + HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2,
  225714. + HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2,
  225715. + HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0,
  225716. + HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1,
  225717. + HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1,
  225718. + HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0,
  225719. +
  225720. +/* VP_CONF field values */
  225721. + HDMI_VP_CONF_BYPASS_EN_MASK = 0x40,
  225722. + HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40,
  225723. + HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00,
  225724. + HDMI_VP_CONF_PP_EN_ENMASK = 0x20,
  225725. + HDMI_VP_CONF_PP_EN_ENABLE = 0x20,
  225726. + HDMI_VP_CONF_PP_EN_DISABLE = 0x00,
  225727. + HDMI_VP_CONF_PR_EN_MASK = 0x10,
  225728. + HDMI_VP_CONF_PR_EN_ENABLE = 0x10,
  225729. + HDMI_VP_CONF_PR_EN_DISABLE = 0x00,
  225730. + HDMI_VP_CONF_YCC422_EN_MASK = 0x8,
  225731. + HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8,
  225732. + HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0,
  225733. + HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4,
  225734. + HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4,
  225735. + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0,
  225736. + HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3,
  225737. + HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3,
  225738. + HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1,
  225739. + HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0,
  225740. +
  225741. +/* VP_REMAP field values */
  225742. + HDMI_VP_REMAP_MASK = 0x3,
  225743. + HDMI_VP_REMAP_YCC422_24bit = 0x2,
  225744. + HDMI_VP_REMAP_YCC422_20bit = 0x1,
  225745. + HDMI_VP_REMAP_YCC422_16bit = 0x0,
  225746. +
  225747. +/* FC_INVIDCONF field values */
  225748. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40,
  225749. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40,
  225750. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
  225751. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20,
  225752. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20,
  225753. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
  225754. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10,
  225755. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10,
  225756. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00,
  225757. + HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8,
  225758. + HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8,
  225759. + HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0,
  225760. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2,
  225761. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2,
  225762. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0,
  225763. + HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1,
  225764. + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1,
  225765. + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0,
  225766. +
  225767. +/* FC_AUDICONF0 field values */
  225768. + HDMI_FC_AUDICONF0_CC_OFFSET = 4,
  225769. + HDMI_FC_AUDICONF0_CC_MASK = 0x70,
  225770. + HDMI_FC_AUDICONF0_CT_OFFSET = 0,
  225771. + HDMI_FC_AUDICONF0_CT_MASK = 0xF,
  225772. +
  225773. +/* FC_AUDICONF1 field values */
  225774. + HDMI_FC_AUDICONF1_SS_OFFSET = 3,
  225775. + HDMI_FC_AUDICONF1_SS_MASK = 0x18,
  225776. + HDMI_FC_AUDICONF1_SF_OFFSET = 0,
  225777. + HDMI_FC_AUDICONF1_SF_MASK = 0x7,
  225778. +
  225779. +/* FC_AUDICONF3 field values */
  225780. + HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5,
  225781. + HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60,
  225782. + HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4,
  225783. + HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10,
  225784. + HDMI_FC_AUDICONF3_LSV_OFFSET = 0,
  225785. + HDMI_FC_AUDICONF3_LSV_MASK = 0xF,
  225786. +
  225787. +/* FC_AUDSCHNLS0 field values */
  225788. + HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4,
  225789. + HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30,
  225790. + HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0,
  225791. + HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01,
  225792. +
  225793. +/* FC_AUDSCHNLS3-6 field values */
  225794. + HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0,
  225795. + HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f,
  225796. + HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4,
  225797. + HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0,
  225798. + HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0,
  225799. + HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f,
  225800. + HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4,
  225801. + HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0,
  225802. +
  225803. + HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0,
  225804. + HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f,
  225805. + HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4,
  225806. + HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0,
  225807. + HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0,
  225808. + HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f,
  225809. + HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4,
  225810. + HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0,
  225811. +
  225812. +/* HDMI_FC_AUDSCHNLS7 field values */
  225813. + HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4,
  225814. + HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30,
  225815. +
  225816. +/* HDMI_FC_AUDSCHNLS8 field values */
  225817. + HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0,
  225818. + HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4,
  225819. + HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f,
  225820. + HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0,
  225821. +
  225822. +/* FC_AUDSCONF field values */
  225823. + HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0,
  225824. + HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4,
  225825. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1,
  225826. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0,
  225827. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1,
  225828. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0,
  225829. +
  225830. +/* FC_STAT2 field values */
  225831. + HDMI_FC_STAT2_OVERFLOW_MASK = 0x03,
  225832. + HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
  225833. + HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  225834. +
  225835. +/* FC_INT2 field values */
  225836. + HDMI_FC_INT2_OVERFLOW_MASK = 0x03,
  225837. + HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
  225838. + HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  225839. +
  225840. +/* FC_MASK2 field values */
  225841. + HDMI_FC_MASK2_OVERFLOW_MASK = 0x03,
  225842. + HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02,
  225843. + HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01,
  225844. +
  225845. +/* FC_PRCONF field values */
  225846. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0,
  225847. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4,
  225848. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F,
  225849. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0,
  225850. +
  225851. +/* FC_AVICONF0-FC_AVICONF3 field values */
  225852. + HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03,
  225853. + HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00,
  225854. + HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01,
  225855. + HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02,
  225856. + HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40,
  225857. + HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40,
  225858. + HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00,
  225859. + HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C,
  225860. + HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00,
  225861. + HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04,
  225862. + HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08,
  225863. + HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C,
  225864. + HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30,
  225865. + HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10,
  225866. + HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20,
  225867. + HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00,
  225868. +
  225869. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F,
  225870. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08,
  225871. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09,
  225872. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A,
  225873. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B,
  225874. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30,
  225875. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00,
  225876. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10,
  225877. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20,
  225878. + HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0,
  225879. + HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00,
  225880. + HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40,
  225881. + HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80,
  225882. + HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0,
  225883. +
  225884. + HDMI_FC_AVICONF2_SCALING_MASK = 0x03,
  225885. + HDMI_FC_AVICONF2_SCALING_NONE = 0x00,
  225886. + HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01,
  225887. + HDMI_FC_AVICONF2_SCALING_VERT = 0x02,
  225888. + HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03,
  225889. + HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C,
  225890. + HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00,
  225891. + HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04,
  225892. + HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08,
  225893. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70,
  225894. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00,
  225895. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10,
  225896. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20,
  225897. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30,
  225898. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40,
  225899. + HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80,
  225900. + HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00,
  225901. + HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80,
  225902. +
  225903. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03,
  225904. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00,
  225905. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01,
  225906. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02,
  225907. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03,
  225908. + HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C,
  225909. + HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00,
  225910. + HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04,
  225911. +
  225912. +/* FC_DBGFORCE field values */
  225913. + HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10,
  225914. + HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1,
  225915. +
  225916. +/* PHY_CONF0 field values */
  225917. + HDMI_PHY_CONF0_PDZ_MASK = 0x80,
  225918. + HDMI_PHY_CONF0_PDZ_OFFSET = 7,
  225919. + HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
  225920. + HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
  225921. + HDMI_PHY_CONF0_SPARECTRL = 0x20,
  225922. + HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
  225923. + HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
  225924. + HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
  225925. + HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3,
  225926. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4,
  225927. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2,
  225928. + HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2,
  225929. + HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1,
  225930. + HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1,
  225931. + HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0,
  225932. +
  225933. +/* PHY_TST0 field values */
  225934. + HDMI_PHY_TST0_TSTCLR_MASK = 0x20,
  225935. + HDMI_PHY_TST0_TSTCLR_OFFSET = 5,
  225936. + HDMI_PHY_TST0_TSTEN_MASK = 0x10,
  225937. + HDMI_PHY_TST0_TSTEN_OFFSET = 4,
  225938. + HDMI_PHY_TST0_TSTCLK_MASK = 0x1,
  225939. + HDMI_PHY_TST0_TSTCLK_OFFSET = 0,
  225940. +
  225941. +/* PHY_STAT0 field values */
  225942. + HDMI_PHY_RX_SENSE3 = 0x80,
  225943. + HDMI_PHY_RX_SENSE2 = 0x40,
  225944. + HDMI_PHY_RX_SENSE1 = 0x20,
  225945. + HDMI_PHY_RX_SENSE0 = 0x10,
  225946. + HDMI_PHY_HPD = 0x02,
  225947. + HDMI_PHY_TX_PHY_LOCK = 0x01,
  225948. +
  225949. +/* HDMI STAT convenience RX_SENSE | HPD */
  225950. + HDMI_DVI_STAT = 0xF2,
  225951. +
  225952. +/* PHY_I2CM_SLAVE_ADDR field values */
  225953. + HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69,
  225954. + HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49,
  225955. +
  225956. +/* PHY_I2CM_OPERATION_ADDR field values */
  225957. + HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10,
  225958. + HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1,
  225959. +
  225960. +/* HDMI_PHY_I2CM_INT_ADDR */
  225961. + HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08,
  225962. + HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04,
  225963. +
  225964. +/* HDMI_PHY_I2CM_CTLINT_ADDR */
  225965. + HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80,
  225966. + HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40,
  225967. + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08,
  225968. + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04,
  225969. +
  225970. +/* AUD_CTS3 field values */
  225971. + HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5,
  225972. + HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0,
  225973. + HDMI_AUD_CTS3_N_SHIFT_1 = 0,
  225974. + HDMI_AUD_CTS3_N_SHIFT_16 = 0x20,
  225975. + HDMI_AUD_CTS3_N_SHIFT_32 = 0x40,
  225976. + HDMI_AUD_CTS3_N_SHIFT_64 = 0x60,
  225977. + HDMI_AUD_CTS3_N_SHIFT_128 = 0x80,
  225978. + HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0,
  225979. + /* note that the CTS3 MANUAL bit has been removed
  225980. + from our part. Can't set it, will read as 0. */
  225981. + HDMI_AUD_CTS3_CTS_MANUAL = 0x10,
  225982. + HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f,
  225983. +
  225984. +/* AHB_DMA_CONF0 field values */
  225985. + HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7,
  225986. + HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80,
  225987. + HDMI_AHB_DMA_CONF0_HBR_OFFSET = 4,
  225988. + HDMI_AHB_DMA_CONF0_HBR_MASK = 0x10,
  225989. + HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3,
  225990. + HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08,
  225991. + HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1,
  225992. + HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06,
  225993. + HDMI_AHB_DMA_CONF0_INCR4 = 0x0,
  225994. + HDMI_AHB_DMA_CONF0_INCR8 = 0x2,
  225995. + HDMI_AHB_DMA_CONF0_INCR16 = 0x4,
  225996. + HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1,
  225997. +
  225998. +/* HDMI_AHB_DMA_START field values */
  225999. + HDMI_AHB_DMA_START_START_OFFSET = 0,
  226000. + HDMI_AHB_DMA_START_START_MASK = 0x01,
  226001. +
  226002. +/* HDMI_AHB_DMA_STOP field values */
  226003. + HDMI_AHB_DMA_STOP_STOP_OFFSET = 0,
  226004. + HDMI_AHB_DMA_STOP_STOP_MASK = 0x01,
  226005. +
  226006. +/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */
  226007. + HDMI_AHB_DMA_DONE = 0x80,
  226008. + HDMI_AHB_DMA_RETRY_SPLIT = 0x40,
  226009. + HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20,
  226010. + HDMI_AHB_DMA_ERROR = 0x10,
  226011. + HDMI_AHB_DMA_FIFO_THREMPTY = 0x04,
  226012. + HDMI_AHB_DMA_FIFO_FULL = 0x02,
  226013. + HDMI_AHB_DMA_FIFO_EMPTY = 0x01,
  226014. +
  226015. +/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT, AHB_DMA_BUFFMASK, AHB_DMA_BUFFPOL field values */
  226016. + HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02,
  226017. + HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01,
  226018. +
  226019. +/* MC_CLKDIS field values */
  226020. + HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40,
  226021. + HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20,
  226022. + HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10,
  226023. + HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8,
  226024. + HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4,
  226025. + HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2,
  226026. + HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1,
  226027. +
  226028. +/* MC_SWRSTZ field values */
  226029. + HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02,
  226030. +
  226031. +/* MC_FLOWCTRL field values */
  226032. + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1,
  226033. + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1,
  226034. + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0,
  226035. +
  226036. +/* MC_PHYRSTZ field values */
  226037. + HDMI_MC_PHYRSTZ_ASSERT = 0x0,
  226038. + HDMI_MC_PHYRSTZ_DEASSERT = 0x1,
  226039. +
  226040. +/* MC_HEACPHY_RST field values */
  226041. + HDMI_MC_HEACPHY_RST_ASSERT = 0x1,
  226042. + HDMI_MC_HEACPHY_RST_DEASSERT = 0x0,
  226043. +
  226044. +/* CSC_CFG field values */
  226045. + HDMI_CSC_CFG_INTMODE_MASK = 0x30,
  226046. + HDMI_CSC_CFG_INTMODE_OFFSET = 4,
  226047. + HDMI_CSC_CFG_INTMODE_DISABLE = 0x00,
  226048. + HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10,
  226049. + HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20,
  226050. + HDMI_CSC_CFG_DECMODE_MASK = 0x3,
  226051. + HDMI_CSC_CFG_DECMODE_OFFSET = 0,
  226052. + HDMI_CSC_CFG_DECMODE_DISABLE = 0x0,
  226053. + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1,
  226054. + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2,
  226055. + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3,
  226056. +
  226057. +/* CSC_SCALE field values */
  226058. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0,
  226059. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00,
  226060. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50,
  226061. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60,
  226062. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70,
  226063. + HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03,
  226064. +
  226065. +/* I2CM_OPERATION field values */
  226066. + HDMI_I2CM_OPERATION_WRITE = 0x10,
  226067. + HDMI_I2CM_OPERATION_READ_EXT = 0x2,
  226068. + HDMI_I2CM_OPERATION_READ = 0x1,
  226069. +
  226070. +/* HDMI_I2CM_INT */
  226071. + HDMI_I2CM_INT_DONE_POL = 0x08,
  226072. + HDMI_I2CM_INT_DONE_MASK = 0x04,
  226073. +
  226074. +/* HDMI_I2CM_CTLINT */
  226075. + HDMI_I2CM_CTLINT_NAC_POL = 0x80,
  226076. + HDMI_I2CM_CTLINT_NAC_MASK = 0x40,
  226077. + HDMI_I2CM_CTLINT_ARBITRATION_POL = 0x08,
  226078. + HDMI_I2CM_CTLINT_ARBITRATION_MASK = 0x04,
  226079. +
  226080. +};
  226081. +
  226082. +enum imx_hdmi_type {
  226083. + IMX6DL_HDMI,
  226084. + IMX6Q_HDMI,
  226085. +};
  226086. +
  226087. +/* IOCTL commands */
  226088. +#define HDMI_IOC_MAGIC 'H'
  226089. +
  226090. +#define HDMI_IOC_GET_RESOURCE _IO(HDMI_IOC_MAGIC, 0)
  226091. +#define HDMI_IOC_GET_CPU_TYPE _IO(HDMI_IOC_MAGIC, 1)
  226092. +
  226093. +
  226094. +#endif /* __MXC_HDMI_H__ */
  226095. diff -Nur linux-3.14.14/kernel/cpu.c linux-imx6-3.14/kernel/cpu.c
  226096. --- linux-3.14.14/kernel/cpu.c 2014-07-28 10:07:25.000000000 -0500
  226097. +++ linux-imx6-3.14/kernel/cpu.c 2014-12-08 00:31:55.492418001 -0600
  226098. @@ -722,3 +722,22 @@
  226099. {
  226100. cpumask_copy(to_cpumask(cpu_online_bits), src);
  226101. }
  226102. +
  226103. +static ATOMIC_NOTIFIER_HEAD(idle_notifier);
  226104. +void idle_notifier_register(struct notifier_block *n)
  226105. +{
  226106. + atomic_notifier_chain_register(&idle_notifier, n);
  226107. +}
  226108. +EXPORT_SYMBOL_GPL(idle_notifier_register);
  226109. +
  226110. +void idle_notifier_unregister(struct notifier_block *n)
  226111. +{
  226112. + atomic_notifier_chain_unregister(&idle_notifier, n);
  226113. +}
  226114. +EXPORT_SYMBOL_GPL(idle_notifier_unregister);
  226115. +
  226116. +void idle_notifier_call_chain(unsigned long val)
  226117. +{
  226118. + atomic_notifier_call_chain(&idle_notifier, val, NULL);
  226119. +}
  226120. +EXPORT_SYMBOL_GPL(idle_notifier_call_chain);
  226121. diff -Nur linux-3.14.14/kernel/irq/manage.c linux-imx6-3.14/kernel/irq/manage.c
  226122. --- linux-3.14.14/kernel/irq/manage.c 2014-07-28 10:07:25.000000000 -0500
  226123. +++ linux-imx6-3.14/kernel/irq/manage.c 2014-12-08 00:31:55.500418001 -0600
  226124. @@ -32,24 +32,10 @@
  226125. early_param("threadirqs", setup_forced_irqthreads);
  226126. #endif
  226127. -/**
  226128. - * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
  226129. - * @irq: interrupt number to wait for
  226130. - *
  226131. - * This function waits for any pending IRQ handlers for this interrupt
  226132. - * to complete before returning. If you use this function while
  226133. - * holding a resource the IRQ handler may need you will deadlock.
  226134. - *
  226135. - * This function may be called - with care - from IRQ context.
  226136. - */
  226137. -void synchronize_irq(unsigned int irq)
  226138. +static void __synchronize_hardirq(struct irq_desc *desc)
  226139. {
  226140. - struct irq_desc *desc = irq_to_desc(irq);
  226141. bool inprogress;
  226142. - if (!desc)
  226143. - return;
  226144. -
  226145. do {
  226146. unsigned long flags;
  226147. @@ -67,12 +53,56 @@
  226148. /* Oops, that failed? */
  226149. } while (inprogress);
  226150. +}
  226151. +
  226152. +/**
  226153. + * synchronize_hardirq - wait for pending hard IRQ handlers (on other CPUs)
  226154. + * @irq: interrupt number to wait for
  226155. + *
  226156. + * This function waits for any pending hard IRQ handlers for this
  226157. + * interrupt to complete before returning. If you use this
  226158. + * function while holding a resource the IRQ handler may need you
  226159. + * will deadlock. It does not take associated threaded handlers
  226160. + * into account.
  226161. + *
  226162. + * Do not use this for shutdown scenarios where you must be sure
  226163. + * that all parts (hardirq and threaded handler) have completed.
  226164. + *
  226165. + * This function may be called - with care - from IRQ context.
  226166. + */
  226167. +void synchronize_hardirq(unsigned int irq)
  226168. +{
  226169. + struct irq_desc *desc = irq_to_desc(irq);
  226170. - /*
  226171. - * We made sure that no hardirq handler is running. Now verify
  226172. - * that no threaded handlers are active.
  226173. - */
  226174. - wait_event(desc->wait_for_threads, !atomic_read(&desc->threads_active));
  226175. + if (desc)
  226176. + __synchronize_hardirq(desc);
  226177. +}
  226178. +EXPORT_SYMBOL(synchronize_hardirq);
  226179. +
  226180. +/**
  226181. + * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
  226182. + * @irq: interrupt number to wait for
  226183. + *
  226184. + * This function waits for any pending IRQ handlers for this interrupt
  226185. + * to complete before returning. If you use this function while
  226186. + * holding a resource the IRQ handler may need you will deadlock.
  226187. + *
  226188. + * This function may be called - with care - from IRQ context.
  226189. + */
  226190. +void synchronize_irq(unsigned int irq)
  226191. +{
  226192. + struct irq_desc *desc = irq_to_desc(irq);
  226193. +
  226194. + if (desc) {
  226195. + __synchronize_hardirq(desc);
  226196. + /*
  226197. + * We made sure that no hardirq handler is
  226198. + * running. Now verify that no threaded handlers are
  226199. + * active.
  226200. + */
  226201. + wait_event(desc->wait_for_threads,
  226202. + !atomic_read(&desc->threads_active));
  226203. + }
  226204. }
  226205. EXPORT_SYMBOL(synchronize_irq);
  226206. diff -Nur linux-3.14.14/kernel/relay.c linux-imx6-3.14/kernel/relay.c
  226207. --- linux-3.14.14/kernel/relay.c 2014-07-28 10:07:25.000000000 -0500
  226208. +++ linux-imx6-3.14/kernel/relay.c 2014-12-08 00:31:55.516418001 -0600
  226209. @@ -227,7 +227,7 @@
  226210. * relay_remove_buf - remove a channel buffer
  226211. * @kref: target kernel reference that contains the relay buffer
  226212. *
  226213. - * Removes the file from the fileystem, which also frees the
  226214. + * Removes the file from the filesystem, which also frees the
  226215. * rchan_buf_struct and the channel buffer. Should only be called from
  226216. * kref_put().
  226217. */
  226218. diff -Nur linux-3.14.14/kernel/signal.c linux-imx6-3.14/kernel/signal.c
  226219. --- linux-3.14.14/kernel/signal.c 2014-07-28 10:07:25.000000000 -0500
  226220. +++ linux-imx6-3.14/kernel/signal.c 2014-12-08 00:31:55.524418001 -0600
  226221. @@ -2382,7 +2382,7 @@
  226222. * @regs: user register state
  226223. * @stepping: nonzero if debugger single-step or block-step in use
  226224. *
  226225. - * This function should be called when a signal has succesfully been
  226226. + * This function should be called when a signal has successfully been
  226227. * delivered. It updates the blocked signals accordingly (@ka->sa.sa_mask
  226228. * is always blocked, and the signal itself is blocked unless %SA_NODEFER
  226229. * is set in @ka->sa.sa_flags. Tracing is notified.
  226230. diff -Nur linux-3.14.14/linaro/configs/android.conf linux-imx6-3.14/linaro/configs/android.conf
  226231. --- linux-3.14.14/linaro/configs/android.conf 1969-12-31 18:00:00.000000000 -0600
  226232. +++ linux-imx6-3.14/linaro/configs/android.conf 2014-12-08 00:31:55.560418001 -0600
  226233. @@ -0,0 +1,42 @@
  226234. +CONFIG_IPV6=y
  226235. +# CONFIG_IPV6_SIT is not set
  226236. +CONFIG_PANIC_TIMEOUT=0
  226237. +CONFIG_HAS_WAKELOCK=y
  226238. +CONFIG_WAKELOCK=y
  226239. +CONFIG_BLK_DEV_LOOP=y
  226240. +CONFIG_DM_CRYPT=y
  226241. +CONFIG_POWER_SUPPLY=y
  226242. +CONFIG_ANDROID_PARANOID_NETWORK=y
  226243. +CONFIG_NET_ACTIVITY_STATS=y
  226244. +CONFIG_INPUT_MISC=y
  226245. +CONFIG_INPUT_UINPUT=y
  226246. +CONFIG_INPUT_GPIO=y
  226247. +CONFIG_USB_G_ANDROID=y
  226248. +CONFIG_SWITCH=y
  226249. +CONFIG_STAGING=y
  226250. +CONFIG_ANDROID=y
  226251. +CONFIG_ANDROID_BINDER_IPC=y
  226252. +CONFIG_ASHMEM=y
  226253. +CONFIG_ANDROID_LOGGER=y
  226254. +CONFIG_ANDROID_TIMED_OUTPUT=y
  226255. +CONFIG_ANDROID_TIMED_GPIO=y
  226256. +CONFIG_ANDROID_LOW_MEMORY_KILLER=y
  226257. +CONFIG_ANDROID_INTF_ALARM_DEV=y
  226258. +CONFIG_CRYPTO_TWOFISH=y
  226259. +CONFIG_BLK_DEV_RAM=y
  226260. +CONFIG_BLK_DEV_RAM_COUNT=16
  226261. +CONFIG_BLK_DEV_RAM_SIZE=16384
  226262. +CONFIG_FUSE_FS=y
  226263. +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
  226264. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  226265. +CONFIG_ION=y
  226266. +CONFIG_SYNC=y
  226267. +CONFIG_SW_SYNC=y
  226268. +CONFIG_SW_SYNC_USER=y
  226269. +CONFIG_ION_TEST=y
  226270. +CONFIG_ION_DUMMY=y
  226271. +CONFIG_ADF=y
  226272. +CONFIG_ADF_FBDEV=y
  226273. +CONFIG_ADF_MEMBLOCK=y
  226274. +CONFIG_DMA_SHARED_BUFFER=y
  226275. +CONFIG_TUN=y
  226276. diff -Nur linux-3.14.14/linaro/configs/arndale.conf linux-imx6-3.14/linaro/configs/arndale.conf
  226277. --- linux-3.14.14/linaro/configs/arndale.conf 1969-12-31 18:00:00.000000000 -0600
  226278. +++ linux-imx6-3.14/linaro/configs/arndale.conf 2014-12-08 00:31:55.560418001 -0600
  226279. @@ -0,0 +1,66 @@
  226280. +CONFIG_KALLSYMS_ALL=y
  226281. +CONFIG_PARTITION_ADVANCED=y
  226282. +CONFIG_BSD_DISKLABEL=y
  226283. +CONFIG_SOLARIS_X86_PARTITION=y
  226284. +CONFIG_ARCH_EXYNOS=y
  226285. +CONFIG_S3C_LOWLEVEL_UART_PORT=2
  226286. +CONFIG_ARCH_EXYNOS5=y
  226287. +# CONFIG_EXYNOS_ATAGS is not set
  226288. +CONFIG_MACH_EXYNOS4_DT=y
  226289. +CONFIG_VMSPLIT_2G=y
  226290. +CONFIG_NR_CPUS=2
  226291. +CONFIG_HIGHMEM=y
  226292. +# CONFIG_COMPACTION is not set
  226293. +CONFIG_ARM_APPENDED_DTB=y
  226294. +CONFIG_ARM_ATAG_DTB_COMPAT=y
  226295. +CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init= mem=256M"
  226296. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  226297. +CONFIG_VFP=y
  226298. +CONFIG_NEON=y
  226299. +CONFIG_PM_RUNTIME=y
  226300. +CONFIG_BLK_DEV_LOOP=y
  226301. +CONFIG_BLK_DEV_SD=y
  226302. +CONFIG_CHR_DEV_SG=y
  226303. +CONFIG_ATA=y
  226304. +CONFIG_SATA_AHCI_PLATFORM=y
  226305. +CONFIG_SATA_EXYNOS=y
  226306. +CONFIG_AX88796=y
  226307. +CONFIG_AX88796_93CX6=y
  226308. +CONFIG_INPUT_EVDEV=y
  226309. +CONFIG_KEYBOARD_GPIO=y
  226310. +CONFIG_INPUT_TOUCHSCREEN=y
  226311. +CONFIG_SERIAL_8250=y
  226312. +CONFIG_SERIAL_SAMSUNG=y
  226313. +CONFIG_SERIAL_SAMSUNG_CONSOLE=y
  226314. +CONFIG_HW_RANDOM=y
  226315. +CONFIG_I2C=y
  226316. +CONFIG_I2C_S3C2410=y
  226317. +CONFIG_THERMAL=y
  226318. +CONFIG_CPU_THERMAL=y
  226319. +CONFIG_EXYNOS_THERMAL=y
  226320. +CONFIG_MFD_SEC_CORE=y
  226321. +CONFIG_REGULATOR=y
  226322. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  226323. +CONFIG_REGULATOR_S5M8767=y
  226324. +CONFIG_DRM=y
  226325. +CONFIG_DRM_LOAD_EDID_FIRMWARE=y
  226326. +CONFIG_DRM_EXYNOS=y
  226327. +CONFIG_DRM_EXYNOS_DMABUF=y
  226328. +CONFIG_DRM_EXYNOS_HDMI=y
  226329. +CONFIG_FRAMEBUFFER_CONSOLE=y
  226330. +CONFIG_LOGO=y
  226331. +CONFIG_MMC=y
  226332. +CONFIG_MMC_UNSAFE_RESUME=y
  226333. +CONFIG_MMC_DW=y
  226334. +CONFIG_MMC_DW_IDMAC=y
  226335. +CONFIG_MMC_DW_EXYNOS=y
  226336. +CONFIG_RTC_CLASS=y
  226337. +CONFIG_RTC_DRV_S3C=y
  226338. +CONFIG_DEBUG_KERNEL=y
  226339. +CONFIG_DETECT_HUNG_TASK=y
  226340. +CONFIG_DEBUG_RT_MUTEXES=y
  226341. +CONFIG_DEBUG_SPINLOCK=y
  226342. +CONFIG_DEBUG_INFO=y
  226343. +CONFIG_RCU_CPU_STALL_TIMEOUT=60
  226344. +CONFIG_DEBUG_USER=y
  226345. +CONFIG_TUN=y
  226346. diff -Nur linux-3.14.14/linaro/configs/bigendian.conf linux-imx6-3.14/linaro/configs/bigendian.conf
  226347. --- linux-3.14.14/linaro/configs/bigendian.conf 1969-12-31 18:00:00.000000000 -0600
  226348. +++ linux-imx6-3.14/linaro/configs/bigendian.conf 2014-12-08 00:31:55.560418001 -0600
  226349. @@ -0,0 +1,4 @@
  226350. +CONFIG_CPU_BIG_ENDIAN=y
  226351. +CONFIG_CPU_ENDIAN_BE8=y
  226352. +# CONFIG_VIRTUALIZATION is not set
  226353. +# CONFIG_MMC_DW_IDMAC is not set
  226354. diff -Nur linux-3.14.14/linaro/configs/big-LITTLE-IKS.conf linux-imx6-3.14/linaro/configs/big-LITTLE-IKS.conf
  226355. --- linux-3.14.14/linaro/configs/big-LITTLE-IKS.conf 1969-12-31 18:00:00.000000000 -0600
  226356. +++ linux-imx6-3.14/linaro/configs/big-LITTLE-IKS.conf 2014-12-08 00:31:55.560418001 -0600
  226357. @@ -0,0 +1,5 @@
  226358. +CONFIG_BIG_LITTLE=y
  226359. +CONFIG_BL_SWITCHER=y
  226360. +CONFIG_ARM_DT_BL_CPUFREQ=y
  226361. +CONFIG_ARM_VEXPRESS_BL_CPUFREQ=y
  226362. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  226363. diff -Nur linux-3.14.14/linaro/configs/debug.conf linux-imx6-3.14/linaro/configs/debug.conf
  226364. --- linux-3.14.14/linaro/configs/debug.conf 1969-12-31 18:00:00.000000000 -0600
  226365. +++ linux-imx6-3.14/linaro/configs/debug.conf 2014-12-08 00:31:55.560418001 -0600
  226366. @@ -0,0 +1 @@
  226367. +CONFIG_PROVE_LOCKING=y
  226368. diff -Nur linux-3.14.14/linaro/configs/distribution.conf linux-imx6-3.14/linaro/configs/distribution.conf
  226369. --- linux-3.14.14/linaro/configs/distribution.conf 1969-12-31 18:00:00.000000000 -0600
  226370. +++ linux-imx6-3.14/linaro/configs/distribution.conf 2014-12-08 00:31:55.560418001 -0600
  226371. @@ -0,0 +1,49 @@
  226372. +# CONFIG_LOCALVERSION_AUTO is not set
  226373. +CONFIG_CGROUPS=y
  226374. +# CONFIG_COMPAT_BRK is not set
  226375. +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
  226376. +CONFIG_SECCOMP=y
  226377. +CONFIG_CC_STACKPROTECTOR=y
  226378. +CONFIG_SYN_COOKIES=y
  226379. +CONFIG_IPV6=y
  226380. +CONFIG_NETLABEL=y
  226381. +CONFIG_BRIDGE_NETFILTER=y
  226382. +CONFIG_NF_CONNTRACK=m
  226383. +CONFIG_NETFILTER_XT_CONNMARK=m
  226384. +CONFIG_NETFILTER_XT_MARK=m
  226385. +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
  226386. +CONFIG_NF_CONNTRACK_IPV4=m
  226387. +CONFIG_NF_NAT_IPV4=m
  226388. +CONFIG_IP_NF_IPTABLES=m
  226389. +CONFIG_IP_NF_FILTER=m
  226390. +CONFIG_IP_NF_MANGLE=m
  226391. +CONFIG_NF_CONNTRACK_IPV6=m
  226392. +CONFIG_NF_NAT_IPV6=m
  226393. +CONFIG_IP6_NF_IPTABLES=m
  226394. +CONFIG_IP6_NF_FILTER=m
  226395. +CONFIG_IP6_NF_MANGLE=m
  226396. +CONFIG_BRIDGE_NF_EBTABLES=m
  226397. +CONFIG_BRIDGE_EBT_MARK_T=m
  226398. +CONFIG_BRIDGE=m
  226399. +CONFIG_TUN=y
  226400. +CONFIG_DEVTMPFS=y
  226401. +CONFIG_DEVTMPFS_MOUNT=y
  226402. +CONFIG_BLK_DEV_RAM=y
  226403. +CONFIG_BLK_DEV_RAM_SIZE=65536
  226404. +CONFIG_INPUT_MISC=y
  226405. +CONFIG_INPUT_UINPUT=y
  226406. +# CONFIG_DEVKMEM is not set
  226407. +CONFIG_FRAMEBUFFER_CONSOLE=y
  226408. +CONFIG_AUTOFS4_FS=y
  226409. +CONFIG_TMPFS_POSIX_ACL=y
  226410. +CONFIG_STRICT_DEVMEM=y
  226411. +CONFIG_SECURITY=y
  226412. +CONFIG_LSM_MMAP_MIN_ADDR=0
  226413. +CONFIG_SECURITY_SELINUX=y
  226414. +CONFIG_SECURITY_SMACK=y
  226415. +CONFIG_SECURITY_APPARMOR=y
  226416. +CONFIG_DEFAULT_SECURITY_APPARMOR=y
  226417. +CONFIG_HUGETLBFS=y
  226418. +CONFIG_HUGETLB_PAGE=y
  226419. +CONFIG_TRANSPARENT_HUGEPAGE=y
  226420. +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
  226421. diff -Nur linux-3.14.14/linaro/configs/highbank.conf linux-imx6-3.14/linaro/configs/highbank.conf
  226422. --- linux-3.14.14/linaro/configs/highbank.conf 1969-12-31 18:00:00.000000000 -0600
  226423. +++ linux-imx6-3.14/linaro/configs/highbank.conf 2014-12-08 00:31:55.560418001 -0600
  226424. @@ -0,0 +1,40 @@
  226425. +CONFIG_EXPERIMENTAL=y
  226426. +CONFIG_NO_HZ=y
  226427. +CONFIG_HIGH_RES_TIMERS=y
  226428. +CONFIG_ARCH_HIGHBANK=y
  226429. +CONFIG_ARM_ERRATA_754322=y
  226430. +CONFIG_SMP=y
  226431. +CONFIG_SCHED_MC=y
  226432. +CONFIG_AEABI=y
  226433. +CONFIG_CMDLINE="console=ttyAMA0"
  226434. +CONFIG_CPU_IDLE=y
  226435. +CONFIG_VFP=y
  226436. +CONFIG_NEON=y
  226437. +CONFIG_NET=y
  226438. +CONFIG_SCSI=y
  226439. +CONFIG_BLK_DEV_SD=y
  226440. +CONFIG_ATA=y
  226441. +CONFIG_SATA_AHCI_PLATFORM=y
  226442. +CONFIG_SATA_HIGHBANK=y
  226443. +CONFIG_NETDEVICES=y
  226444. +CONFIG_NET_CALXEDA_XGMAC=y
  226445. +CONFIG_SERIAL_AMBA_PL011=y
  226446. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  226447. +CONFIG_IPMI_HANDLER=y
  226448. +CONFIG_IPMI_SI=y
  226449. +CONFIG_I2C=y
  226450. +CONFIG_I2C_DESIGNWARE_PLATFORM=y
  226451. +CONFIG_SPI=y
  226452. +CONFIG_SPI_PL022=y
  226453. +CONFIG_GPIO_PL061=y
  226454. +CONFIG_MMC=y
  226455. +CONFIG_MMC_SDHCI=y
  226456. +CONFIG_MMC_SDHCI_PLTFM=y
  226457. +CONFIG_EDAC=y
  226458. +CONFIG_EDAC_MM_EDAC=y
  226459. +CONFIG_EDAC_HIGHBANK_MC=y
  226460. +CONFIG_EDAC_HIGHBANK_L2=y
  226461. +CONFIG_RTC_CLASS=y
  226462. +CONFIG_RTC_DRV_PL031=y
  226463. +CONFIG_DMADEVICES=y
  226464. +CONFIG_PL330_DMA=y
  226465. diff -Nur linux-3.14.14/linaro/configs/kvm-guest.conf linux-imx6-3.14/linaro/configs/kvm-guest.conf
  226466. --- linux-3.14.14/linaro/configs/kvm-guest.conf 1969-12-31 18:00:00.000000000 -0600
  226467. +++ linux-imx6-3.14/linaro/configs/kvm-guest.conf 2014-12-08 00:31:55.560418001 -0600
  226468. @@ -0,0 +1,11 @@
  226469. +CONFIG_BALLOON_COMPACTION=y
  226470. +CONFIG_VIRTIO_BLK=y
  226471. +CONFIG_VIRTIO_NET=y
  226472. +CONFIG_HVC_DRIVER=y
  226473. +CONFIG_VIRTIO_CONSOLE=y
  226474. +CONFIG_VIRTIO=y
  226475. +CONFIG_VIRTIO_BALLOON=y
  226476. +CONFIG_VIRTIO_MMIO=y
  226477. +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
  226478. +CONFIG_VIRTUALIZATION=y
  226479. +# CONFIG_THUMB2_KERNEL is not set
  226480. diff -Nur linux-3.14.14/linaro/configs/kvm-host.conf linux-imx6-3.14/linaro/configs/kvm-host.conf
  226481. --- linux-3.14.14/linaro/configs/kvm-host.conf 1969-12-31 18:00:00.000000000 -0600
  226482. +++ linux-imx6-3.14/linaro/configs/kvm-host.conf 2014-12-08 00:31:55.560418001 -0600
  226483. @@ -0,0 +1,11 @@
  226484. +CONFIG_VIRTUALIZATION=y
  226485. +CONFIG_ARM_LPAE=y
  226486. +CONFIG_ARM_VIRT_EXT=y
  226487. +CONFIG_HAVE_KVM_IRQCHIP=y
  226488. +CONFIG_KVM_ARM_HOST=y
  226489. +CONFIG_KVM_ARM_MAX_VCPUS=4
  226490. +CONFIG_KVM_ARM_TIMER=y
  226491. +CONFIG_KVM_ARM_VGIC=y
  226492. +CONFIG_KVM_MMIO=y
  226493. +CONFIG_KVM=y
  226494. +CONFIG_BLK_DEV_NBD=m
  226495. diff -Nur linux-3.14.14/linaro/configs/linaro-base.conf linux-imx6-3.14/linaro/configs/linaro-base.conf
  226496. --- linux-3.14.14/linaro/configs/linaro-base.conf 1969-12-31 18:00:00.000000000 -0600
  226497. +++ linux-imx6-3.14/linaro/configs/linaro-base.conf 2014-12-08 00:31:55.560418001 -0600
  226498. @@ -0,0 +1,115 @@
  226499. +CONFIG_SYSVIPC=y
  226500. +CONFIG_POSIX_MQUEUE=y
  226501. +CONFIG_BSD_PROCESS_ACCT=y
  226502. +CONFIG_IKCONFIG=y
  226503. +CONFIG_IKCONFIG_PROC=y
  226504. +CONFIG_LOG_BUF_SHIFT=16
  226505. +CONFIG_BLK_DEV_INITRD=y
  226506. +CONFIG_EMBEDDED=y
  226507. +CONFIG_HOTPLUG=y
  226508. +CONFIG_PERF_EVENTS=y
  226509. +CONFIG_SLAB=y
  226510. +CONFIG_PROFILING=y
  226511. +CONFIG_OPROFILE=y
  226512. +CONFIG_MODULES=y
  226513. +CONFIG_MODULE_UNLOAD=y
  226514. +CONFIG_NO_HZ=y
  226515. +CONFIG_HIGH_RES_TIMERS=y
  226516. +CONFIG_SMP=y
  226517. +CONFIG_SCHED_MC=y
  226518. +CONFIG_SCHED_SMT=y
  226519. +CONFIG_THUMB2_KERNEL=y
  226520. +CONFIG_AEABI=y
  226521. +# CONFIG_OABI_COMPAT is not set
  226522. +CONFIG_CPU_FREQ=y
  226523. +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
  226524. +CONFIG_CPU_IDLE=y
  226525. +CONFIG_BINFMT_MISC=y
  226526. +CONFIG_MD=y
  226527. +CONFIG_BLK_DEV_DM=y
  226528. +CONFIG_NET=y
  226529. +CONFIG_PACKET=y
  226530. +CONFIG_UNIX=y
  226531. +CONFIG_XFRM_USER=y
  226532. +CONFIG_NET_KEY=y
  226533. +CONFIG_NET_KEY_MIGRATE=y
  226534. +CONFIG_INET=y
  226535. +CONFIG_IP_MULTICAST=y
  226536. +CONFIG_IP_PNP=y
  226537. +CONFIG_IP_PNP_DHCP=y
  226538. +CONFIG_IP_PNP_BOOTP=y
  226539. +CONFIG_IP_PNP_RARP=y
  226540. +# CONFIG_INET_LRO is not set
  226541. +CONFIG_NETFILTER=y
  226542. +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
  226543. +CONFIG_CONNECTOR=y
  226544. +CONFIG_MTD=y
  226545. +CONFIG_MTD_CMDLINE_PARTS=y
  226546. +CONFIG_MTD_BLOCK=y
  226547. +CONFIG_MTD_OOPS=y
  226548. +CONFIG_MTD_CFI=y
  226549. +CONFIG_MTD_CFI_INTELEXT=y
  226550. +CONFIG_MTD_NAND=y
  226551. +CONFIG_NETDEVICES=y
  226552. +CONFIG_EXT2_FS=y
  226553. +CONFIG_EXT3_FS=y
  226554. +CONFIG_EXT4_FS=y
  226555. +CONFIG_BTRFS_FS=y
  226556. +CONFIG_QUOTA=y
  226557. +CONFIG_QFMT_V2=y
  226558. +CONFIG_MSDOS_FS=y
  226559. +CONFIG_VFAT_FS=y
  226560. +CONFIG_TMPFS=y
  226561. +CONFIG_ECRYPT_FS=y
  226562. +CONFIG_JFFS2_FS=y
  226563. +CONFIG_JFFS2_SUMMARY=y
  226564. +CONFIG_JFFS2_FS_XATTR=y
  226565. +CONFIG_JFFS2_COMPRESSION_OPTIONS=y
  226566. +CONFIG_JFFS2_LZO=y
  226567. +CONFIG_JFFS2_RUBIN=y
  226568. +CONFIG_CRAMFS=y
  226569. +CONFIG_NETWORK_FILESYSTEMS=y
  226570. +CONFIG_NFS_FS=y
  226571. +# CONFIG_NFS_V2 is not set
  226572. +CONFIG_NFS_V3=y
  226573. +CONFIG_NFS_V3_ACL=y
  226574. +CONFIG_NFS_V4=y
  226575. +CONFIG_ROOT_NFS=y
  226576. +CONFIG_NLS_CODEPAGE_437=y
  226577. +CONFIG_NLS_ISO8859_1=y
  226578. +CONFIG_PRINTK_TIME=y
  226579. +CONFIG_MAGIC_SYSRQ=y
  226580. +CONFIG_DEBUG_FS=y
  226581. +CONFIG_SCHEDSTATS=y
  226582. +CONFIG_TIMER_STATS=y
  226583. +CONFIG_KEYS=y
  226584. +CONFIG_CRYPTO_MICHAEL_MIC=y
  226585. +CONFIG_CRC_CCITT=y
  226586. +CONFIG_CRC_T10DIF=y
  226587. +CONFIG_CRC_ITU_T=y
  226588. +CONFIG_CRC7=y
  226589. +CONFIG_HW_PERF_EVENTS=y
  226590. +CONFIG_FUNCTION_TRACER=y
  226591. +CONFIG_ENABLE_DEFAULT_TRACERS=y
  226592. +CONFIG_PROC_DEVICETREE=y
  226593. +CONFIG_JUMP_LABEL=y
  226594. +CONFIG_STRICT_DEVMEM=y
  226595. +CONFIG_KGDB=y
  226596. +CONFIG_KGDB_TESTS=y
  226597. +CONFIG_OF_IDLE_STATES=y
  226598. +CONFIG_FTRACE=y
  226599. +CONFIG_FUNCTION_TRACER=y
  226600. +CONFIG_FTRACE_SYSCALLS=y
  226601. +CONFIG_STACK_TRACER=y
  226602. +CONFIG_FUNCTION_PROFILER=y
  226603. +CONFIG_MAILBOX=y
  226604. +CONFIG_AUDIT=y
  226605. +CONFIG_NF_CONNTRACK_SECMARK=y
  226606. +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
  226607. +CONFIG_NETFILTER_XT_TARGET_SECMARK=y
  226608. +CONFIG_IP_NF_SECURITY=y
  226609. +CONFIG_SECURITY=y
  226610. +CONFIG_SECURITY_NETWORK=y
  226611. +CONFIG_LSM_MMAP_MIN_ADDR=4096
  226612. +CONFIG_SECURITY_SELINUX=y
  226613. +CONFIG_EXT4_FS_SECURITY=y
  226614. diff -Nur linux-3.14.14/linaro/configs/omap4.conf linux-imx6-3.14/linaro/configs/omap4.conf
  226615. --- linux-3.14.14/linaro/configs/omap4.conf 1969-12-31 18:00:00.000000000 -0600
  226616. +++ linux-imx6-3.14/linaro/configs/omap4.conf 2014-12-08 00:31:55.560418001 -0600
  226617. @@ -0,0 +1,196 @@
  226618. +CONFIG_EXPERT=y
  226619. +CONFIG_KPROBES=y
  226620. +CONFIG_MODULE_FORCE_LOAD=y
  226621. +CONFIG_MODULE_FORCE_UNLOAD=y
  226622. +CONFIG_MODVERSIONS=y
  226623. +CONFIG_MODULE_SRCVERSION_ALL=y
  226624. +# CONFIG_BLK_DEV_BSG is not set
  226625. +CONFIG_PARTITION_ADVANCED=y
  226626. +CONFIG_GPIO_PCA953X=y
  226627. +CONFIG_OMAP_RESET_CLOCKS=y
  226628. +CONFIG_OMAP_MUX_DEBUG=y
  226629. +CONFIG_ARCH_OMAP3=y
  226630. +CONFIG_ARCH_OMAP4=y
  226631. +CONFIG_ARCH_OMAP2PLUS=y
  226632. +CONFIG_SOC_OMAP5=y
  226633. +# CONFIG_ARCH_OMAP2 is not set
  226634. +CONFIG_ARCH_VEXPRESS_CA9X4=y
  226635. +CONFIG_ARM_THUMBEE=y
  226636. +CONFIG_ARM_ERRATA_411920=y
  226637. +CONFIG_NR_CPUS=2
  226638. +CONFIG_ZBOOT_ROM_TEXT=0x0
  226639. +CONFIG_ZBOOT_ROM_BSS=0x0
  226640. +CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
  226641. +CONFIG_KEXEC=y
  226642. +CONFIG_PM_DEBUG=y
  226643. +CONFIG_CAN=m
  226644. +CONFIG_CAN_C_CAN=m
  226645. +CONFIG_CAN_C_CAN_PLATFORM=m
  226646. +CONFIG_BT=m
  226647. +CONFIG_BT_HCIUART=m
  226648. +CONFIG_BT_HCIUART_H4=y
  226649. +CONFIG_BT_HCIUART_BCSP=y
  226650. +CONFIG_BT_HCIUART_LL=y
  226651. +CONFIG_BT_HCIBCM203X=m
  226652. +CONFIG_BT_HCIBPA10X=m
  226653. +CONFIG_CFG80211=m
  226654. +CONFIG_MAC80211=m
  226655. +CONFIG_MAC80211_RC_PID=y
  226656. +CONFIG_MAC80211_RC_DEFAULT_PID=y
  226657. +CONFIG_CMA=y
  226658. +CONFIG_MTD_NAND_OMAP2=y
  226659. +CONFIG_MTD_ONENAND=y
  226660. +CONFIG_MTD_ONENAND_VERIFY_WRITE=y
  226661. +CONFIG_MTD_ONENAND_OMAP2=y
  226662. +CONFIG_MTD_UBI=y
  226663. +CONFIG_BLK_DEV_LOOP=y
  226664. +CONFIG_BLK_DEV_RAM_SIZE=16384
  226665. +CONFIG_SENSORS_TSL2550=m
  226666. +CONFIG_SENSORS_LIS3_I2C=m
  226667. +CONFIG_SCSI=y
  226668. +CONFIG_BLK_DEV_SD=y
  226669. +CONFIG_SCSI_MULTI_LUN=y
  226670. +CONFIG_SCSI_SCAN_ASYNC=y
  226671. +CONFIG_KS8851=y
  226672. +CONFIG_KS8851_MLL=y
  226673. +CONFIG_SMC91X=y
  226674. +CONFIG_SMSC911X=y
  226675. +CONFIG_TI_CPSW=y
  226676. +CONFIG_SMSC_PHY=y
  226677. +CONFIG_USB_USBNET=y
  226678. +CONFIG_USB_NET_SMSC95XX=y
  226679. +CONFIG_USB_ALI_M5632=y
  226680. +CONFIG_USB_AN2720=y
  226681. +CONFIG_USB_EPSON2888=y
  226682. +CONFIG_USB_KC2190=y
  226683. +CONFIG_LIBERTAS=m
  226684. +CONFIG_LIBERTAS_USB=m
  226685. +CONFIG_LIBERTAS_SDIO=m
  226686. +CONFIG_LIBERTAS_DEBUG=y
  226687. +CONFIG_INPUT_JOYDEV=y
  226688. +CONFIG_INPUT_EVDEV=y
  226689. +CONFIG_KEYBOARD_GPIO=y
  226690. +CONFIG_KEYBOARD_MATRIX=m
  226691. +CONFIG_KEYBOARD_TWL4030=y
  226692. +CONFIG_INPUT_TOUCHSCREEN=y
  226693. +CONFIG_TOUCHSCREEN_ADS7846=y
  226694. +CONFIG_INPUT_TWL4030_PWRBUTTON=y
  226695. +CONFIG_VT_HW_CONSOLE_BINDING=y
  226696. +# CONFIG_LEGACY_PTYS is not set
  226697. +CONFIG_SERIAL_8250=y
  226698. +CONFIG_SERIAL_8250_CONSOLE=y
  226699. +CONFIG_SERIAL_8250_NR_UARTS=32
  226700. +CONFIG_SERIAL_8250_EXTENDED=y
  226701. +CONFIG_SERIAL_8250_MANY_PORTS=y
  226702. +CONFIG_SERIAL_8250_SHARE_IRQ=y
  226703. +CONFIG_SERIAL_8250_DETECT_IRQ=y
  226704. +CONFIG_SERIAL_8250_RSA=y
  226705. +CONFIG_SERIAL_AMBA_PL011=y
  226706. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  226707. +CONFIG_SERIAL_OMAP=y
  226708. +CONFIG_SERIAL_OMAP_CONSOLE=y
  226709. +CONFIG_HW_RANDOM=y
  226710. +CONFIG_I2C_CHARDEV=y
  226711. +CONFIG_SPI=y
  226712. +CONFIG_SPI_OMAP24XX=y
  226713. +CONFIG_PINCTRL_SINGLE=y
  226714. +CONFIG_DEBUG_GPIO=y
  226715. +CONFIG_GPIO_SYSFS=y
  226716. +CONFIG_GPIO_TWL4030=y
  226717. +CONFIG_W1=y
  226718. +CONFIG_SENSORS_LM75=m
  226719. +CONFIG_WATCHDOG=y
  226720. +CONFIG_OMAP_WATCHDOG=y
  226721. +CONFIG_TWL4030_WATCHDOG=y
  226722. +CONFIG_MFD_TPS65217=y
  226723. +CONFIG_MFD_TPS65910=y
  226724. +CONFIG_TWL6040_CORE=y
  226725. +CONFIG_REGULATOR_TPS65023=y
  226726. +CONFIG_REGULATOR_TPS6507X=y
  226727. +CONFIG_REGULATOR_TPS65217=y
  226728. +CONFIG_REGULATOR_TPS65910=y
  226729. +CONFIG_REGULATOR_TWL4030=y
  226730. +CONFIG_FB=y
  226731. +CONFIG_FIRMWARE_EDID=y
  226732. +CONFIG_FB_MODE_HELPERS=y
  226733. +CONFIG_FB_TILEBLITTING=y
  226734. +CONFIG_OMAP2_DSS=m
  226735. +CONFIG_OMAP2_DSS_RFBI=y
  226736. +CONFIG_OMAP2_DSS_SDI=y
  226737. +CONFIG_OMAP2_DSS_DSI=y
  226738. +CONFIG_FB_OMAP2=m
  226739. +CONFIG_PANEL_GENERIC_DPI=m
  226740. +CONFIG_PANEL_TFP410=m
  226741. +CONFIG_PANEL_SHARP_LS037V7DW01=m
  226742. +CONFIG_PANEL_NEC_NL8048HL11_01B=m
  226743. +CONFIG_PANEL_TAAL=m
  226744. +CONFIG_PANEL_TPO_TD043MTEA1=m
  226745. +CONFIG_PANEL_ACX565AKM=m
  226746. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  226747. +CONFIG_LCD_CLASS_DEVICE=y
  226748. +CONFIG_LCD_PLATFORM=y
  226749. +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
  226750. +CONFIG_FONTS=y
  226751. +CONFIG_FONT_8x8=y
  226752. +CONFIG_FONT_8x16=y
  226753. +CONFIG_LOGO=y
  226754. +CONFIG_SOUND=m
  226755. +CONFIG_SND=m
  226756. +CONFIG_SND_VERBOSE_PRINTK=y
  226757. +CONFIG_SND_DEBUG=y
  226758. +CONFIG_SND_USB_AUDIO=m
  226759. +CONFIG_SND_SOC=m
  226760. +CONFIG_SND_OMAP_SOC=m
  226761. +CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m
  226762. +CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m
  226763. +CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
  226764. +CONFIG_USB=y
  226765. +CONFIG_USB_DEBUG=y
  226766. +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
  226767. +CONFIG_USB_MON=y
  226768. +CONFIG_USB_EHCI_HCD=y
  226769. +CONFIG_USB_OHCI_HCD=y
  226770. +CONFIG_USB_WDM=y
  226771. +CONFIG_USB_STORAGE=y
  226772. +CONFIG_USB_TEST=y
  226773. +CONFIG_USB_PHY=y
  226774. +CONFIG_NOP_USB_XCEIV=y
  226775. +CONFIG_USB_GADGET=y
  226776. +CONFIG_USB_GADGET_DEBUG=y
  226777. +CONFIG_USB_GADGET_DEBUG_FILES=y
  226778. +CONFIG_USB_GADGET_DEBUG_FS=y
  226779. +CONFIG_USB_ZERO=m
  226780. +CONFIG_MMC=y
  226781. +CONFIG_MMC_UNSAFE_RESUME=y
  226782. +CONFIG_SDIO_UART=y
  226783. +CONFIG_MMC_ARMMMCI=y
  226784. +CONFIG_MMC_OMAP=y
  226785. +CONFIG_MMC_OMAP_HS=y
  226786. +CONFIG_NEW_LEDS=y
  226787. +CONFIG_LEDS_CLASS=y
  226788. +CONFIG_LEDS_GPIO=y
  226789. +CONFIG_LEDS_TRIGGERS=y
  226790. +CONFIG_LEDS_TRIGGER_TIMER=y
  226791. +CONFIG_LEDS_TRIGGER_ONESHOT=y
  226792. +CONFIG_LEDS_TRIGGER_HEARTBEAT=y
  226793. +CONFIG_LEDS_TRIGGER_BACKLIGHT=y
  226794. +CONFIG_LEDS_TRIGGER_CPU=y
  226795. +CONFIG_LEDS_TRIGGER_GPIO=y
  226796. +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
  226797. +CONFIG_RTC_CLASS=y
  226798. +CONFIG_RTC_DRV_TWL92330=y
  226799. +CONFIG_RTC_DRV_TWL4030=y
  226800. +CONFIG_RTC_DRV_OMAP=y
  226801. +CONFIG_DMADEVICES=y
  226802. +CONFIG_DMA_OMAP=y
  226803. +# CONFIG_EXT3_FS_XATTR is not set
  226804. +CONFIG_UBIFS_FS=y
  226805. +CONFIG_NFS_FS=y
  226806. +CONFIG_NFS_V3_ACL=y
  226807. +CONFIG_NFS_V4=y
  226808. +CONFIG_ROOT_NFS=y
  226809. +# CONFIG_DEBUG_BUGVERBOSE is not set
  226810. +CONFIG_DEBUG_INFO=y
  226811. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  226812. +CONFIG_LIBCRC32C=y
  226813. +# CONFIG_CPU_FREQ is not set
  226814. diff -Nur linux-3.14.14/linaro/configs/preempt-rt.conf linux-imx6-3.14/linaro/configs/preempt-rt.conf
  226815. --- linux-3.14.14/linaro/configs/preempt-rt.conf 1969-12-31 18:00:00.000000000 -0600
  226816. +++ linux-imx6-3.14/linaro/configs/preempt-rt.conf 2014-12-08 00:31:55.560418001 -0600
  226817. @@ -0,0 +1,4 @@
  226818. +CONFIG_PREEMPT=y
  226819. +CONFIG_PREEMPT_RT_FULL=y
  226820. +CONFIG_SLUB=y
  226821. +# CONFIG_CPU_FREQ is not set
  226822. diff -Nur linux-3.14.14/linaro/configs/vexpress64.conf linux-imx6-3.14/linaro/configs/vexpress64.conf
  226823. --- linux-3.14.14/linaro/configs/vexpress64.conf 1969-12-31 18:00:00.000000000 -0600
  226824. +++ linux-imx6-3.14/linaro/configs/vexpress64.conf 2014-12-08 00:31:55.560418001 -0600
  226825. @@ -0,0 +1,56 @@
  226826. +CONFIG_ARCH_VEXPRESS=y
  226827. +CONFIG_SMP=y
  226828. +CONFIG_NR_CPUS=8
  226829. +CONFIG_CMDLINE="console=ttyAMA0"
  226830. +CONFIG_COMPAT=y
  226831. +CONFIG_SMC91X=y
  226832. +CONFIG_INPUT_EVDEV=y
  226833. +CONFIG_SERIO_AMBAKMI=y
  226834. +CONFIG_SERIAL_AMBA_PL011=y
  226835. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  226836. +# CONFIG_SERIO_I8042 is not set
  226837. +CONFIG_FB=y
  226838. +CONFIG_FB_ARMCLCD=y
  226839. +CONFIG_FRAMEBUFFER_CONSOLE=y
  226840. +# CONFIG_VGA_CONSOLE is not set
  226841. +CONFIG_LOGO=y
  226842. +# CONFIG_LOGO_LINUX_MONO is not set
  226843. +# CONFIG_LOGO_LINUX_VGA16 is not set
  226844. +CONFIG_MMC=y
  226845. +CONFIG_MMC_ARMMMCI=y
  226846. +CONFIG_RTC_CLASS=y
  226847. +CONFIG_RTC_DRV_PL031=y
  226848. +CONFIG_NFS_FS=y
  226849. +CONFIG_NFS_V3=y
  226850. +CONFIG_NFS_V3_ACL=y
  226851. +CONFIG_NFS_V4=y
  226852. +CONFIG_ROOT_NFS=y
  226853. +CONFIG_VIRTIO=y
  226854. +CONFIG_VIRTIO_BLK=y
  226855. +CONFIG_VIRTIO_MMIO=y
  226856. +CONFIG_REGULATOR=y
  226857. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  226858. +CONFIG_CMA=y
  226859. +CONFIG_DMA_CMA=y
  226860. +CONFIG_COMMON_CLK_SCPI=y
  226861. +CONFIG_SMSC911X=y
  226862. +CONFIG_I2C=y
  226863. +CONFIG_ARM_MHU_MBOX=y
  226864. +CONFIG_ARM_SCPI_PROTOCOL=y
  226865. +CONFIG_USB_HIDDEV=y
  226866. +CONFIG_SCSI=y
  226867. +CONFIG_BLK_DEV_SD=y
  226868. +CONFIG_USB_STORAGE=y
  226869. +CONFIG_USB=y
  226870. +CONFIG_USB_ULPI=y
  226871. +CONFIG_USB_EHCI_HCD=y
  226872. +CONFIG_USB_EHCI_HCD_SYNOPSYS=y
  226873. +CONFIG_USB_OHCI_HCD=y
  226874. +CONFIG_USB_PHY=y
  226875. +CONFIG_USB_ISP1301=y
  226876. +CONFIG_PM_OPP=y
  226877. +CONFIG_GENERIC_CPUFREQ_CPU0=y
  226878. +CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
  226879. +CONFIG_ARM_DT_BL_CPUFREQ=y
  226880. +CONFIG_ARM64_CPUIDLE=y
  226881. +CONFIG_ARM64_CRYPTO=y
  226882. diff -Nur linux-3.14.14/linaro/configs/vexpress.conf linux-imx6-3.14/linaro/configs/vexpress.conf
  226883. --- linux-3.14.14/linaro/configs/vexpress.conf 1969-12-31 18:00:00.000000000 -0600
  226884. +++ linux-imx6-3.14/linaro/configs/vexpress.conf 2014-12-08 00:31:55.560418001 -0600
  226885. @@ -0,0 +1,64 @@
  226886. +CONFIG_ARCH_VEXPRESS=y
  226887. +CONFIG_ARCH_VEXPRESS_CA9X4=y
  226888. +CONFIG_HAVE_ARM_ARCH_TIMER=y
  226889. +CONFIG_NR_CPUS=8
  226890. +CONFIG_HIGHMEM=y
  226891. +CONFIG_HIGHPTE=y
  226892. +CONFIG_ARM_PSCI=y
  226893. +CONFIG_MCPM=y
  226894. +CONFIG_ARCH_VEXPRESS_DCSCB=y
  226895. +CONFIG_ARCH_VEXPRESS_TC2_PM=y
  226896. +CONFIG_ARM_BIG_LITTLE_CPUIDLE=y
  226897. +CONFIG_BIG_LITTLE=y
  226898. +CONFIG_ARM_VEXPRESS_SPC_CPUFREQ=y
  226899. +CONFIG_PM_OPP=y
  226900. +CONFIG_CPU_FREQ=y
  226901. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  226902. +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
  226903. +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
  226904. +CONFIG_CMDLINE="console=ttyAMA0,38400n8 root=/dev/mmcblk0p2 rootwait mmci.fmax=4000000"
  226905. +CONFIG_VFP=y
  226906. +CONFIG_NEON=y
  226907. +CONFIG_SCSI=y
  226908. +CONFIG_BLK_DEV_SD=y
  226909. +CONFIG_SMSC911X=y
  226910. +CONFIG_SMC91X=y
  226911. +CONFIG_INPUT_EVDEV=y
  226912. +CONFIG_SERIO_AMBAKMI=y
  226913. +CONFIG_SERIAL_AMBA_PL011=y
  226914. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  226915. +CONFIG_FB=y
  226916. +CONFIG_FB_ARMCLCD=y
  226917. +CONFIG_FB_ARMHDLCD=y
  226918. +CONFIG_LOGO=y
  226919. +# CONFIG_LOGO_LINUX_MONO is not set
  226920. +# CONFIG_LOGO_LINUX_VGA16 is not set
  226921. +CONFIG_SOUND=y
  226922. +CONFIG_SND=y
  226923. +CONFIG_SND_ARMAACI=y
  226924. +CONFIG_USB=y
  226925. +CONFIG_USB_ISP1760_HCD=y
  226926. +CONFIG_USB_STORAGE=y
  226927. +CONFIG_MMC=y
  226928. +CONFIG_MMC_ARMMMCI=y
  226929. +CONFIG_RTC_CLASS=y
  226930. +CONFIG_RTC_DRV_PL031=y
  226931. +CONFIG_NFS_FS=y
  226932. +CONFIG_NFS_V3=y
  226933. +CONFIG_NFS_V3_ACL=y
  226934. +CONFIG_NFS_V4=y
  226935. +CONFIG_ROOT_NFS=y
  226936. +CONFIG_VEXPRESS_CONFIG=y
  226937. +CONFIG_SENSORS_VEXPRESS=y
  226938. +CONFIG_REGULATOR=y
  226939. +CONFIG_REGULATOR_VEXPRESS=y
  226940. +CONFIG_NEW_LEDS=y
  226941. +CONFIG_LEDS_CLASS=y
  226942. +CONFIG_LEDS_GPIO=y
  226943. +CONFIG_LEDS_TRIGGERS=y
  226944. +CONFIG_LEDS_TRIGGER_HEARTBEAT=y
  226945. +CONFIG_LEDS_TRIGGER_CPU=y
  226946. +CONFIG_VIRTIO=y
  226947. +CONFIG_VIRTIO_BLK=y
  226948. +CONFIG_VIRTIO_MMIO=y
  226949. +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
  226950. diff -Nur linux-3.14.14/linaro/configs/vexpress-tuning.conf linux-imx6-3.14/linaro/configs/vexpress-tuning.conf
  226951. --- linux-3.14.14/linaro/configs/vexpress-tuning.conf 1969-12-31 18:00:00.000000000 -0600
  226952. +++ linux-imx6-3.14/linaro/configs/vexpress-tuning.conf 2014-12-08 00:31:55.560418001 -0600
  226953. @@ -0,0 +1 @@
  226954. +# CONFIG_PROVE_LOCKING is not set
  226955. diff -Nur linux-3.14.14/linaro/configs/xen.conf linux-imx6-3.14/linaro/configs/xen.conf
  226956. --- linux-3.14.14/linaro/configs/xen.conf 1969-12-31 18:00:00.000000000 -0600
  226957. +++ linux-imx6-3.14/linaro/configs/xen.conf 2014-12-08 00:31:55.560418001 -0600
  226958. @@ -0,0 +1,7 @@
  226959. +CONFIG_XEN=y
  226960. +CONFIG_XEN_NETDEV_FRONTEND=y
  226961. +CONFIG_XEN_NETDEV_BACKEND=y
  226962. +CONFIG_XEN_BLKDEV_FRONTEND=y
  226963. +CONFIG_XEN_BLKDEV_BACKEND=y
  226964. +CONFIG_XENFS=y
  226965. +CONFIG_XEN_COMPAT_XENFS=y
  226966. diff -Nur linux-3.14.14/MAINTAINERS linux-imx6-3.14/MAINTAINERS
  226967. --- linux-3.14.14/MAINTAINERS 2014-07-28 10:07:25.000000000 -0500
  226968. +++ linux-imx6-3.14/MAINTAINERS 2014-12-08 00:31:51.072418001 -0600
  226969. @@ -5511,6 +5511,14 @@
  226970. F: drivers/net/macvlan.c
  226971. F: include/linux/if_macvlan.h
  226972. +MAILBOX API
  226973. +M: Jassi Brar <jassisinghbrar@gmail.com>
  226974. +L: linux-kernel@vger.kernel.org
  226975. +S: Maintained
  226976. +F: drivers/mailbox/
  226977. +F: include/linux/mailbox_client.h
  226978. +F: include/linux/mailbox_controller.h
  226979. +
  226980. MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
  226981. M: Michael Kerrisk <mtk.manpages@gmail.com>
  226982. W: http://www.kernel.org/doc/man-pages
  226983. diff -Nur linux-3.14.14/mm/cma.c linux-imx6-3.14/mm/cma.c
  226984. --- linux-3.14.14/mm/cma.c 1969-12-31 18:00:00.000000000 -0600
  226985. +++ linux-imx6-3.14/mm/cma.c 2014-12-08 00:31:55.568418001 -0600
  226986. @@ -0,0 +1,356 @@
  226987. +/*
  226988. + * Contiguous Memory Allocator
  226989. + *
  226990. + * Copyright (c) 2010-2011 by Samsung Electronics.
  226991. + * Copyright IBM Corporation, 2013
  226992. + * Copyright LG Electronics Inc., 2014
  226993. + * Written by:
  226994. + * Marek Szyprowski <m.szyprowski@samsung.com>
  226995. + * Michal Nazarewicz <mina86@mina86.com>
  226996. + * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
  226997. + * Joonsoo Kim <iamjoonsoo.kim@lge.com>
  226998. + *
  226999. + * This program is free software; you can redistribute it and/or
  227000. + * modify it under the terms of the GNU General Public License as
  227001. + * published by the Free Software Foundation; either version 2 of the
  227002. + * License or (at your optional) any later version of the license.
  227003. + */
  227004. +
  227005. +#define pr_fmt(fmt) "cma: " fmt
  227006. +
  227007. +#ifdef CONFIG_CMA_DEBUG
  227008. +#ifndef DEBUG
  227009. +# define DEBUG
  227010. +#endif
  227011. +#endif
  227012. +
  227013. +#include <linux/memblock.h>
  227014. +#include <linux/err.h>
  227015. +#include <linux/mm.h>
  227016. +#include <linux/mutex.h>
  227017. +#include <linux/sizes.h>
  227018. +#include <linux/slab.h>
  227019. +#include <linux/log2.h>
  227020. +#include <linux/cma.h>
  227021. +#include <linux/highmem.h>
  227022. +
  227023. +struct cma {
  227024. + unsigned long base_pfn;
  227025. + unsigned long count;
  227026. + unsigned long *bitmap;
  227027. + unsigned int order_per_bit; /* Order of pages represented by one bit */
  227028. + struct mutex lock;
  227029. +};
  227030. +
  227031. +static struct cma cma_areas[MAX_CMA_AREAS];
  227032. +static unsigned cma_area_count;
  227033. +static DEFINE_MUTEX(cma_mutex);
  227034. +
  227035. +phys_addr_t cma_get_base(struct cma *cma)
  227036. +{
  227037. + return PFN_PHYS(cma->base_pfn);
  227038. +}
  227039. +
  227040. +unsigned long cma_get_size(struct cma *cma)
  227041. +{
  227042. + return cma->count << PAGE_SHIFT;
  227043. +}
  227044. +
  227045. +static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int align_order)
  227046. +{
  227047. + return (1UL << (align_order >> cma->order_per_bit)) - 1;
  227048. +}
  227049. +
  227050. +static unsigned long cma_bitmap_maxno(struct cma *cma)
  227051. +{
  227052. + return cma->count >> cma->order_per_bit;
  227053. +}
  227054. +
  227055. +static unsigned long cma_bitmap_pages_to_bits(struct cma *cma,
  227056. + unsigned long pages)
  227057. +{
  227058. + return ALIGN(pages, 1UL << cma->order_per_bit) >> cma->order_per_bit;
  227059. +}
  227060. +
  227061. +static void cma_clear_bitmap(struct cma *cma, unsigned long pfn, int count)
  227062. +{
  227063. + unsigned long bitmap_no, bitmap_count;
  227064. +
  227065. + bitmap_no = (pfn - cma->base_pfn) >> cma->order_per_bit;
  227066. + bitmap_count = cma_bitmap_pages_to_bits(cma, count);
  227067. +
  227068. + mutex_lock(&cma->lock);
  227069. + bitmap_clear(cma->bitmap, bitmap_no, bitmap_count);
  227070. + mutex_unlock(&cma->lock);
  227071. +}
  227072. +
  227073. +static int __init cma_activate_area(struct cma *cma)
  227074. +{
  227075. + int bitmap_size = BITS_TO_LONGS(cma_bitmap_maxno(cma)) * sizeof(long);
  227076. + unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;
  227077. + unsigned i = cma->count >> pageblock_order;
  227078. + struct zone *zone;
  227079. +
  227080. + cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
  227081. +
  227082. + if (!cma->bitmap)
  227083. + return -ENOMEM;
  227084. +
  227085. + WARN_ON_ONCE(!pfn_valid(pfn));
  227086. + zone = page_zone(pfn_to_page(pfn));
  227087. +
  227088. + do {
  227089. + unsigned j;
  227090. +
  227091. + base_pfn = pfn;
  227092. + for (j = pageblock_nr_pages; j; --j, pfn++) {
  227093. + WARN_ON_ONCE(!pfn_valid(pfn));
  227094. + /*
  227095. + * alloc_contig_range requires the pfn range
  227096. + * specified to be in the same zone. Make this
  227097. + * simple by forcing the entire CMA resv range
  227098. + * to be in the same zone.
  227099. + */
  227100. + if (page_zone(pfn_to_page(pfn)) != zone)
  227101. + goto err;
  227102. + }
  227103. + init_cma_reserved_pageblock(pfn_to_page(base_pfn));
  227104. + } while (--i);
  227105. +
  227106. + mutex_init(&cma->lock);
  227107. + return 0;
  227108. +
  227109. +err:
  227110. + kfree(cma->bitmap);
  227111. + return -EINVAL;
  227112. +}
  227113. +
  227114. +static int __init cma_init_reserved_areas(void)
  227115. +{
  227116. + int i;
  227117. +
  227118. + for (i = 0; i < cma_area_count; i++) {
  227119. + int ret = cma_activate_area(&cma_areas[i]);
  227120. +
  227121. + if (ret)
  227122. + return ret;
  227123. + }
  227124. +
  227125. + return 0;
  227126. +}
  227127. +core_initcall(cma_init_reserved_areas);
  227128. +
  227129. +/**
  227130. + * cma_declare_contiguous() - reserve custom contiguous area
  227131. + * @base: Base address of the reserved area optional, use 0 for any
  227132. + * @size: Size of the reserved area (in bytes),
  227133. + * @limit: End address of the reserved memory (optional, 0 for any).
  227134. + * @alignment: Alignment for the CMA area, should be power of 2 or zero
  227135. + * @order_per_bit: Order of pages represented by one bit on bitmap.
  227136. + * @fixed: hint about where to place the reserved area
  227137. + * @res_cma: Pointer to store the created cma region.
  227138. + *
  227139. + * This function reserves memory from early allocator. It should be
  227140. + * called by arch specific code once the early allocator (memblock or bootmem)
  227141. + * has been activated and all other subsystems have already allocated/reserved
  227142. + * memory. This function allows to create custom reserved areas.
  227143. + *
  227144. + * If @fixed is true, reserve contiguous area at exactly @base. If false,
  227145. + * reserve in range from @base to @limit.
  227146. + */
  227147. +int __init cma_declare_contiguous(phys_addr_t base,
  227148. + phys_addr_t size, phys_addr_t limit,
  227149. + phys_addr_t alignment, unsigned int order_per_bit,
  227150. + bool fixed, struct cma **res_cma)
  227151. +{
  227152. + struct cma *cma;
  227153. + phys_addr_t memblock_end = memblock_end_of_DRAM();
  227154. + phys_addr_t highmem_start = __pa(high_memory);
  227155. + int ret = 0;
  227156. +
  227157. + pr_debug("%s(size %lx, base %08lx, limit %08lx alignment %08lx)\n",
  227158. + __func__, (unsigned long)size, (unsigned long)base,
  227159. + (unsigned long)limit, (unsigned long)alignment);
  227160. +
  227161. + if (cma_area_count == ARRAY_SIZE(cma_areas)) {
  227162. + pr_err("Not enough slots for CMA reserved regions!\n");
  227163. + return -ENOSPC;
  227164. + }
  227165. +
  227166. + if (!size)
  227167. + return -EINVAL;
  227168. +
  227169. + if (alignment && !is_power_of_2(alignment))
  227170. + return -EINVAL;
  227171. +
  227172. + /*
  227173. + * Sanitise input arguments.
  227174. + * Pages both ends in CMA area could be merged into adjacent unmovable
  227175. + * migratetype page by page allocator's buddy algorithm. In the case,
  227176. + * you couldn't get a contiguous memory, which is not what we want.
  227177. + */
  227178. + alignment = max(alignment,
  227179. + (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order));
  227180. + base = ALIGN(base, alignment);
  227181. + size = ALIGN(size, alignment);
  227182. + limit &= ~(alignment - 1);
  227183. +
  227184. + /* size should be aligned with order_per_bit */
  227185. + if (!IS_ALIGNED(size >> PAGE_SHIFT, 1 << order_per_bit))
  227186. + return -EINVAL;
  227187. +
  227188. + /*
  227189. + * adjust limit to avoid crossing low/high memory boundary for
  227190. + * automatically allocated regions
  227191. + */
  227192. + if (((limit == 0 || limit > memblock_end) &&
  227193. + (memblock_end - size < highmem_start &&
  227194. + memblock_end > highmem_start)) ||
  227195. + (!fixed && limit > highmem_start && limit - size < highmem_start)) {
  227196. + limit = highmem_start;
  227197. + }
  227198. +
  227199. + if (fixed && base < highmem_start && base+size > highmem_start) {
  227200. + ret = -EINVAL;
  227201. + pr_err("Region at %08lx defined on low/high memory boundary (%08lx)\n",
  227202. + (unsigned long)base, (unsigned long)highmem_start);
  227203. + goto err;
  227204. + }
  227205. +
  227206. + /* Reserve memory */
  227207. + if (base && fixed) {
  227208. + if (memblock_is_region_reserved(base, size) ||
  227209. + memblock_reserve(base, size) < 0) {
  227210. + ret = -EBUSY;
  227211. + goto err;
  227212. + }
  227213. + } else {
  227214. + phys_addr_t addr = memblock_alloc_range(size, alignment, base,
  227215. + limit);
  227216. + if (!addr) {
  227217. + ret = -ENOMEM;
  227218. + goto err;
  227219. + } else {
  227220. + base = addr;
  227221. + }
  227222. + }
  227223. +
  227224. + /*
  227225. + * Each reserved area must be initialised later, when more kernel
  227226. + * subsystems (like slab allocator) are available.
  227227. + */
  227228. + cma = &cma_areas[cma_area_count];
  227229. + cma->base_pfn = PFN_DOWN(base);
  227230. + cma->count = size >> PAGE_SHIFT;
  227231. + cma->order_per_bit = order_per_bit;
  227232. + *res_cma = cma;
  227233. + cma_area_count++;
  227234. +
  227235. + pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
  227236. + (unsigned long)base);
  227237. + return 0;
  227238. +
  227239. +err:
  227240. + pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
  227241. + return ret;
  227242. +}
  227243. +
  227244. +/**
  227245. + * cma_alloc() - allocate pages from contiguous area
  227246. + * @cma: Contiguous memory region for which the allocation is performed.
  227247. + * @count: Requested number of pages.
  227248. + * @align: Requested alignment of pages (in PAGE_SIZE order).
  227249. + *
  227250. + * This function allocates part of contiguous memory on specific
  227251. + * contiguous memory area.
  227252. + */
  227253. +struct page *cma_alloc(struct cma *cma, int count, unsigned int align)
  227254. +{
  227255. + unsigned long mask, pfn, start = 0;
  227256. + unsigned long bitmap_maxno, bitmap_no, bitmap_count;
  227257. + struct page *page = NULL;
  227258. + int ret;
  227259. +
  227260. + if (!cma || !cma->count)
  227261. + return NULL;
  227262. +
  227263. + pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma,
  227264. + count, align);
  227265. +
  227266. + if (!count)
  227267. + return NULL;
  227268. +
  227269. + mask = cma_bitmap_aligned_mask(cma, align);
  227270. + bitmap_maxno = cma_bitmap_maxno(cma);
  227271. + bitmap_count = cma_bitmap_pages_to_bits(cma, count);
  227272. +
  227273. + for (;;) {
  227274. + mutex_lock(&cma->lock);
  227275. + bitmap_no = bitmap_find_next_zero_area(cma->bitmap,
  227276. + bitmap_maxno, start, bitmap_count, mask);
  227277. + if (bitmap_no >= bitmap_maxno) {
  227278. + mutex_unlock(&cma->lock);
  227279. + break;
  227280. + }
  227281. + bitmap_set(cma->bitmap, bitmap_no, bitmap_count);
  227282. + /*
  227283. + * It's safe to drop the lock here. We've marked this region for
  227284. + * our exclusive use. If the migration fails we will take the
  227285. + * lock again and unmark it.
  227286. + */
  227287. + mutex_unlock(&cma->lock);
  227288. +
  227289. + pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit);
  227290. + mutex_lock(&cma_mutex);
  227291. + ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
  227292. + mutex_unlock(&cma_mutex);
  227293. + if (ret == 0) {
  227294. + page = pfn_to_page(pfn);
  227295. + break;
  227296. + }
  227297. +
  227298. + cma_clear_bitmap(cma, pfn, count);
  227299. + if (ret != -EBUSY)
  227300. + break;
  227301. +
  227302. + pr_debug("%s(): memory range at %p is busy, retrying\n",
  227303. + __func__, pfn_to_page(pfn));
  227304. + /* try again with a bit different memory target */
  227305. + start = bitmap_no + mask + 1;
  227306. + }
  227307. +
  227308. + pr_debug("%s(): returned %p\n", __func__, page);
  227309. + return page;
  227310. +}
  227311. +
  227312. +/**
  227313. + * cma_release() - release allocated pages
  227314. + * @cma: Contiguous memory region for which the allocation is performed.
  227315. + * @pages: Allocated pages.
  227316. + * @count: Number of allocated pages.
  227317. + *
  227318. + * This function releases memory allocated by alloc_cma().
  227319. + * It returns false when provided pages do not belong to contiguous area and
  227320. + * true otherwise.
  227321. + */
  227322. +bool cma_release(struct cma *cma, struct page *pages, int count)
  227323. +{
  227324. + unsigned long pfn;
  227325. +
  227326. + if (!cma || !pages)
  227327. + return false;
  227328. +
  227329. + pr_debug("%s(page %p)\n", __func__, (void *)pages);
  227330. +
  227331. + pfn = page_to_pfn(pages);
  227332. +
  227333. + if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
  227334. + return false;
  227335. +
  227336. + VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
  227337. +
  227338. + free_contig_range(pfn, count);
  227339. + cma_clear_bitmap(cma, pfn, count);
  227340. +
  227341. + return true;
  227342. +}
  227343. diff -Nur linux-3.14.14/mm/Kconfig linux-imx6-3.14/mm/Kconfig
  227344. --- linux-3.14.14/mm/Kconfig 2014-07-28 10:07:25.000000000 -0500
  227345. +++ linux-imx6-3.14/mm/Kconfig 2014-12-08 00:31:55.568418001 -0600
  227346. @@ -514,6 +514,17 @@
  227347. processing calls such as dma_alloc_from_contiguous().
  227348. This option does not affect warning and error messages.
  227349. +config CMA_AREAS
  227350. + int "Maximum count of the CMA areas"
  227351. + depends on CMA
  227352. + default 7
  227353. + help
  227354. + CMA allows to create CMA areas for particular purpose, mainly,
  227355. + used as device private area. This parameter sets the maximum
  227356. + number of CMA area in the system.
  227357. +
  227358. + If unsure, leave the default value "7".
  227359. +
  227360. config ZBUD
  227361. tristate
  227362. default n
  227363. diff -Nur linux-3.14.14/mm/Makefile linux-imx6-3.14/mm/Makefile
  227364. --- linux-3.14.14/mm/Makefile 2014-07-28 10:07:25.000000000 -0500
  227365. +++ linux-imx6-3.14/mm/Makefile 2014-12-08 00:31:55.568418001 -0600
  227366. @@ -61,3 +61,4 @@
  227367. obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o
  227368. obj-$(CONFIG_ZBUD) += zbud.o
  227369. obj-$(CONFIG_ZSMALLOC) += zsmalloc.o
  227370. +obj-$(CONFIG_CMA) += cma.o
  227371. diff -Nur linux-3.14.14/mm/memblock.c linux-imx6-3.14/mm/memblock.c
  227372. --- linux-3.14.14/mm/memblock.c 2014-07-28 10:07:25.000000000 -0500
  227373. +++ linux-imx6-3.14/mm/memblock.c 2014-12-08 00:31:55.572418001 -0600
  227374. @@ -975,22 +975,35 @@
  227375. }
  227376. #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */
  227377. -static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size,
  227378. - phys_addr_t align, phys_addr_t max_addr,
  227379. - int nid)
  227380. +static phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
  227381. + phys_addr_t align, phys_addr_t start,
  227382. + phys_addr_t end, int nid)
  227383. {
  227384. phys_addr_t found;
  227385. if (!align)
  227386. align = SMP_CACHE_BYTES;
  227387. - found = memblock_find_in_range_node(size, align, 0, max_addr, nid);
  227388. + found = memblock_find_in_range_node(size, align, start, end, nid);
  227389. if (found && !memblock_reserve(found, size))
  227390. return found;
  227391. return 0;
  227392. }
  227393. +phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align,
  227394. + phys_addr_t start, phys_addr_t end)
  227395. +{
  227396. + return memblock_alloc_range_nid(size, align, start, end, NUMA_NO_NODE);
  227397. +}
  227398. +
  227399. +static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size,
  227400. + phys_addr_t align, phys_addr_t max_addr,
  227401. + int nid)
  227402. +{
  227403. + return memblock_alloc_range_nid(size, align, 0, max_addr, nid);
  227404. +}
  227405. +
  227406. phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid)
  227407. {
  227408. return memblock_alloc_base_nid(size, align, MEMBLOCK_ALLOC_ACCESSIBLE, nid);
  227409. diff -Nur linux-3.14.14/net/atm/svc.c linux-imx6-3.14/net/atm/svc.c
  227410. --- linux-3.14.14/net/atm/svc.c 2014-07-28 10:07:25.000000000 -0500
  227411. +++ linux-imx6-3.14/net/atm/svc.c 2014-12-08 00:31:55.688418001 -0600
  227412. @@ -263,17 +263,11 @@
  227413. goto out;
  227414. }
  227415. }
  227416. -/*
  227417. - * Not supported yet
  227418. - *
  227419. - * #ifndef CONFIG_SINGLE_SIGITF
  227420. - */
  227421. +
  227422. vcc->qos.txtp.max_pcr = SELECT_TOP_PCR(vcc->qos.txtp);
  227423. vcc->qos.txtp.pcr = 0;
  227424. vcc->qos.txtp.min_pcr = 0;
  227425. -/*
  227426. - * #endif
  227427. - */
  227428. +
  227429. error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci);
  227430. if (!error)
  227431. sock->state = SS_CONNECTED;
  227432. diff -Nur linux-3.14.14/net/core/dev.c linux-imx6-3.14/net/core/dev.c
  227433. --- linux-3.14.14/net/core/dev.c 2014-07-28 10:07:25.000000000 -0500
  227434. +++ linux-imx6-3.14/net/core/dev.c 2014-12-08 00:31:55.716418001 -0600
  227435. @@ -3453,7 +3453,7 @@
  227436. * @rx_handler: receive handler to register
  227437. * @rx_handler_data: data pointer that is used by rx handler
  227438. *
  227439. - * Register a receive hander for a device. This handler will then be
  227440. + * Register a receive handler for a device. This handler will then be
  227441. * called from __netif_receive_skb. A negative errno code is returned
  227442. * on a failure.
  227443. *
  227444. diff -Nur linux-3.14.14/net/core/Makefile linux-imx6-3.14/net/core/Makefile
  227445. --- linux-3.14.14/net/core/Makefile 2014-07-28 10:07:25.000000000 -0500
  227446. +++ linux-imx6-3.14/net/core/Makefile 2014-12-08 00:31:55.712418001 -0600
  227447. @@ -9,7 +9,7 @@
  227448. obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \
  227449. neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
  227450. - sock_diag.o dev_ioctl.o
  227451. + sock_diag.o dev_ioctl.o tso.o
  227452. obj-$(CONFIG_XFRM) += flow.o
  227453. obj-y += net-sysfs.o
  227454. diff -Nur linux-3.14.14/net/core/rtnetlink.c linux-imx6-3.14/net/core/rtnetlink.c
  227455. --- linux-3.14.14/net/core/rtnetlink.c 2014-07-28 10:07:25.000000000 -0500
  227456. +++ linux-imx6-3.14/net/core/rtnetlink.c 2014-12-08 00:31:55.720418001 -0600
  227457. @@ -1156,73 +1156,7 @@
  227458. return -EMSGSIZE;
  227459. }
  227460. -static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
  227461. -{
  227462. - struct net *net = sock_net(skb->sk);
  227463. - int h, s_h;
  227464. - int idx = 0, s_idx;
  227465. - struct net_device *dev;
  227466. - struct hlist_head *head;
  227467. - struct nlattr *tb[IFLA_MAX+1];
  227468. - u32 ext_filter_mask = 0;
  227469. - int err;
  227470. - int hdrlen;
  227471. -
  227472. - s_h = cb->args[0];
  227473. - s_idx = cb->args[1];
  227474. -
  227475. - rcu_read_lock();
  227476. - cb->seq = net->dev_base_seq;
  227477. -
  227478. - /* A hack to preserve kernel<->userspace interface.
  227479. - * The correct header is ifinfomsg. It is consistent with rtnl_getlink.
  227480. - * However, before Linux v3.9 the code here assumed rtgenmsg and that's
  227481. - * what iproute2 < v3.9.0 used.
  227482. - * We can detect the old iproute2. Even including the IFLA_EXT_MASK
  227483. - * attribute, its netlink message is shorter than struct ifinfomsg.
  227484. - */
  227485. - hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ?
  227486. - sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
  227487. -
  227488. - if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) {
  227489. -
  227490. - if (tb[IFLA_EXT_MASK])
  227491. - ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
  227492. - }
  227493. -
  227494. - for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
  227495. - idx = 0;
  227496. - head = &net->dev_index_head[h];
  227497. - hlist_for_each_entry_rcu(dev, head, index_hlist) {
  227498. - if (idx < s_idx)
  227499. - goto cont;
  227500. - err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
  227501. - NETLINK_CB(cb->skb).portid,
  227502. - cb->nlh->nlmsg_seq, 0,
  227503. - NLM_F_MULTI,
  227504. - ext_filter_mask);
  227505. - /* If we ran out of room on the first message,
  227506. - * we're in trouble
  227507. - */
  227508. - WARN_ON((err == -EMSGSIZE) && (skb->len == 0));
  227509. -
  227510. - if (err <= 0)
  227511. - goto out;
  227512. -
  227513. - nl_dump_check_consistent(cb, nlmsg_hdr(skb));
  227514. -cont:
  227515. - idx++;
  227516. - }
  227517. - }
  227518. -out:
  227519. - rcu_read_unlock();
  227520. - cb->args[1] = idx;
  227521. - cb->args[0] = h;
  227522. -
  227523. - return skb->len;
  227524. -}
  227525. -
  227526. -const struct nla_policy ifla_policy[IFLA_MAX+1] = {
  227527. +static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
  227528. [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
  227529. [IFLA_ADDRESS] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
  227530. [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
  227531. @@ -1249,7 +1183,6 @@
  227532. [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
  227533. [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
  227534. };
  227535. -EXPORT_SYMBOL(ifla_policy);
  227536. static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
  227537. [IFLA_INFO_KIND] = { .type = NLA_STRING },
  227538. @@ -1287,6 +1220,61 @@
  227539. [IFLA_PORT_RESPONSE] = { .type = NLA_U16, },
  227540. };
  227541. +static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
  227542. +{
  227543. + struct net *net = sock_net(skb->sk);
  227544. + int h, s_h;
  227545. + int idx = 0, s_idx;
  227546. + struct net_device *dev;
  227547. + struct hlist_head *head;
  227548. + struct nlattr *tb[IFLA_MAX+1];
  227549. + u32 ext_filter_mask = 0;
  227550. +
  227551. + s_h = cb->args[0];
  227552. + s_idx = cb->args[1];
  227553. +
  227554. + rcu_read_lock();
  227555. + cb->seq = net->dev_base_seq;
  227556. +
  227557. + if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
  227558. + ifla_policy) >= 0) {
  227559. +
  227560. + if (tb[IFLA_EXT_MASK])
  227561. + ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
  227562. + }
  227563. +
  227564. + for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
  227565. + idx = 0;
  227566. + head = &net->dev_index_head[h];
  227567. + hlist_for_each_entry_rcu(dev, head, index_hlist) {
  227568. + if (idx < s_idx)
  227569. + goto cont;
  227570. + if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
  227571. + NETLINK_CB(cb->skb).portid,
  227572. + cb->nlh->nlmsg_seq, 0,
  227573. + NLM_F_MULTI,
  227574. + ext_filter_mask) <= 0)
  227575. + goto out;
  227576. +
  227577. + nl_dump_check_consistent(cb, nlmsg_hdr(skb));
  227578. +cont:
  227579. + idx++;
  227580. + }
  227581. + }
  227582. +out:
  227583. + rcu_read_unlock();
  227584. + cb->args[1] = idx;
  227585. + cb->args[0] = h;
  227586. +
  227587. + return skb->len;
  227588. +}
  227589. +
  227590. +int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len)
  227591. +{
  227592. + return nla_parse(tb, IFLA_MAX, head, len, ifla_policy);
  227593. +}
  227594. +EXPORT_SYMBOL(rtnl_nla_parse_ifla);
  227595. +
  227596. struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
  227597. {
  227598. struct net *net;
  227599. diff -Nur linux-3.14.14/net/core/tso.c linux-imx6-3.14/net/core/tso.c
  227600. --- linux-3.14.14/net/core/tso.c 1969-12-31 18:00:00.000000000 -0600
  227601. +++ linux-imx6-3.14/net/core/tso.c 2014-12-08 00:31:55.720418001 -0600
  227602. @@ -0,0 +1,72 @@
  227603. +#include <net/ip.h>
  227604. +#include <net/tso.h>
  227605. +
  227606. +/* Calculate expected number of TX descriptors */
  227607. +int tso_count_descs(struct sk_buff *skb)
  227608. +{
  227609. + /* The Marvell Way */
  227610. + return skb_shinfo(skb)->gso_segs * 2 + skb_shinfo(skb)->nr_frags;
  227611. +}
  227612. +
  227613. +void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,
  227614. + int size, bool is_last)
  227615. +{
  227616. + struct iphdr *iph;
  227617. + struct tcphdr *tcph;
  227618. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  227619. + int mac_hdr_len = skb_network_offset(skb);
  227620. +
  227621. + memcpy(hdr, skb->data, hdr_len);
  227622. + iph = (struct iphdr *)(hdr + mac_hdr_len);
  227623. + iph->id = htons(tso->ip_id);
  227624. + iph->tot_len = htons(size + hdr_len - mac_hdr_len);
  227625. + tcph = (struct tcphdr *)(hdr + skb_transport_offset(skb));
  227626. + tcph->seq = htonl(tso->tcp_seq);
  227627. + tso->ip_id++;
  227628. +
  227629. + if (!is_last) {
  227630. + /* Clear all special flags for not last packet */
  227631. + tcph->psh = 0;
  227632. + tcph->fin = 0;
  227633. + tcph->rst = 0;
  227634. + }
  227635. +}
  227636. +
  227637. +void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size)
  227638. +{
  227639. + tso->tcp_seq += size;
  227640. + tso->size -= size;
  227641. + tso->data += size;
  227642. +
  227643. + if ((tso->size == 0) &&
  227644. + (tso->next_frag_idx < skb_shinfo(skb)->nr_frags)) {
  227645. + skb_frag_t *frag = &skb_shinfo(skb)->frags[tso->next_frag_idx];
  227646. +
  227647. + /* Move to next segment */
  227648. + tso->size = frag->size;
  227649. + tso->data = page_address(frag->page.p) + frag->page_offset;
  227650. + tso->next_frag_idx++;
  227651. + }
  227652. +}
  227653. +
  227654. +void tso_start(struct sk_buff *skb, struct tso_t *tso)
  227655. +{
  227656. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  227657. +
  227658. + tso->ip_id = ntohs(ip_hdr(skb)->id);
  227659. + tso->tcp_seq = ntohl(tcp_hdr(skb)->seq);
  227660. + tso->next_frag_idx = 0;
  227661. +
  227662. + /* Build first data */
  227663. + tso->size = skb_headlen(skb) - hdr_len;
  227664. + tso->data = skb->data + hdr_len;
  227665. + if ((tso->size == 0) &&
  227666. + (tso->next_frag_idx < skb_shinfo(skb)->nr_frags)) {
  227667. + skb_frag_t *frag = &skb_shinfo(skb)->frags[tso->next_frag_idx];
  227668. +
  227669. + /* Move to next segment */
  227670. + tso->size = frag->size;
  227671. + tso->data = page_address(frag->page.p) + frag->page_offset;
  227672. + tso->next_frag_idx++;
  227673. + }
  227674. +}
  227675. diff -Nur linux-3.14.14/net/ieee802154/Kconfig linux-imx6-3.14/net/ieee802154/Kconfig
  227676. --- linux-3.14.14/net/ieee802154/Kconfig 2014-07-28 10:07:25.000000000 -0500
  227677. +++ linux-imx6-3.14/net/ieee802154/Kconfig 2014-12-08 00:31:55.728418001 -0600
  227678. @@ -15,7 +15,7 @@
  227679. depends on IEEE802154 && IPV6
  227680. select 6LOWPAN_IPHC
  227681. ---help---
  227682. - IPv6 compression over IEEE 802.15.4.
  227683. + IPv6 compression over IEEE 802.15.4.
  227684. config 6LOWPAN_IPHC
  227685. tristate
  227686. diff -Nur linux-3.14.14/net/mac80211/driver-ops.h linux-imx6-3.14/net/mac80211/driver-ops.h
  227687. --- linux-3.14.14/net/mac80211/driver-ops.h 2014-07-28 10:07:25.000000000 -0500
  227688. +++ linux-imx6-3.14/net/mac80211/driver-ops.h 2014-12-08 00:31:55.780418001 -0600
  227689. @@ -722,13 +722,19 @@
  227690. }
  227691. static inline void drv_flush(struct ieee80211_local *local,
  227692. + struct ieee80211_sub_if_data *sdata,
  227693. u32 queues, bool drop)
  227694. {
  227695. + struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL;
  227696. +
  227697. might_sleep();
  227698. + if (sdata)
  227699. + check_sdata_in_driver(sdata);
  227700. +
  227701. trace_drv_flush(local, queues, drop);
  227702. if (local->ops->flush)
  227703. - local->ops->flush(&local->hw, queues, drop);
  227704. + local->ops->flush(&local->hw, vif, queues, drop);
  227705. trace_drv_return_void(local);
  227706. }
  227707. diff -Nur linux-3.14.14/net/mac80211/ibss.c linux-imx6-3.14/net/mac80211/ibss.c
  227708. --- linux-3.14.14/net/mac80211/ibss.c 2014-07-28 10:07:25.000000000 -0500
  227709. +++ linux-imx6-3.14/net/mac80211/ibss.c 2014-12-08 00:31:55.780418001 -0600
  227710. @@ -386,7 +386,7 @@
  227711. presp->head_len, 0, GFP_KERNEL);
  227712. cfg80211_put_bss(local->hw.wiphy, bss);
  227713. netif_carrier_on(sdata->dev);
  227714. - cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
  227715. + cfg80211_ibss_joined(sdata->dev, ifibss->bssid, chan, GFP_KERNEL);
  227716. }
  227717. static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
  227718. diff -Nur linux-3.14.14/net/mac80211/util.c linux-imx6-3.14/net/mac80211/util.c
  227719. --- linux-3.14.14/net/mac80211/util.c 2014-07-28 10:07:25.000000000 -0500
  227720. +++ linux-imx6-3.14/net/mac80211/util.c 2014-12-08 00:31:55.788418001 -0600
  227721. @@ -554,7 +554,7 @@
  227722. ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
  227723. IEEE80211_QUEUE_STOP_REASON_FLUSH);
  227724. - drv_flush(local, queues, false);
  227725. + drv_flush(local, sdata, queues, false);
  227726. ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
  227727. IEEE80211_QUEUE_STOP_REASON_FLUSH);
  227728. diff -Nur linux-3.14.14/net/wireless/core.h linux-imx6-3.14/net/wireless/core.h
  227729. --- linux-3.14.14/net/wireless/core.h 2014-07-28 10:07:25.000000000 -0500
  227730. +++ linux-imx6-3.14/net/wireless/core.h 2014-12-08 00:31:55.864418001 -0600
  227731. @@ -211,6 +211,7 @@
  227732. } dc;
  227733. struct {
  227734. u8 bssid[ETH_ALEN];
  227735. + struct ieee80211_channel *channel;
  227736. } ij;
  227737. };
  227738. };
  227739. @@ -258,7 +259,8 @@
  227740. struct net_device *dev, bool nowext);
  227741. int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
  227742. struct net_device *dev, bool nowext);
  227743. -void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
  227744. +void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  227745. + struct ieee80211_channel *channel);
  227746. int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
  227747. struct wireless_dev *wdev);
  227748. diff -Nur linux-3.14.14/net/wireless/ibss.c linux-imx6-3.14/net/wireless/ibss.c
  227749. --- linux-3.14.14/net/wireless/ibss.c 2014-07-28 10:07:25.000000000 -0500
  227750. +++ linux-imx6-3.14/net/wireless/ibss.c 2014-12-08 00:31:55.864418001 -0600
  227751. @@ -14,7 +14,8 @@
  227752. #include "rdev-ops.h"
  227753. -void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
  227754. +void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  227755. + struct ieee80211_channel *channel)
  227756. {
  227757. struct wireless_dev *wdev = dev->ieee80211_ptr;
  227758. struct cfg80211_bss *bss;
  227759. @@ -28,8 +29,7 @@
  227760. if (!wdev->ssid_len)
  227761. return;
  227762. - bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
  227763. - wdev->ssid, wdev->ssid_len,
  227764. + bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0,
  227765. WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
  227766. if (WARN_ON(!bss))
  227767. @@ -54,21 +54,26 @@
  227768. #endif
  227769. }
  227770. -void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
  227771. +void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  227772. + struct ieee80211_channel *channel, gfp_t gfp)
  227773. {
  227774. struct wireless_dev *wdev = dev->ieee80211_ptr;
  227775. struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
  227776. struct cfg80211_event *ev;
  227777. unsigned long flags;
  227778. - trace_cfg80211_ibss_joined(dev, bssid);
  227779. + trace_cfg80211_ibss_joined(dev, bssid, channel);
  227780. +
  227781. + if (WARN_ON(!channel))
  227782. + return;
  227783. ev = kzalloc(sizeof(*ev), gfp);
  227784. if (!ev)
  227785. return;
  227786. ev->type = EVENT_IBSS_JOINED;
  227787. - memcpy(ev->cr.bssid, bssid, ETH_ALEN);
  227788. + memcpy(ev->ij.bssid, bssid, ETH_ALEN);
  227789. + ev->ij.channel = channel;
  227790. spin_lock_irqsave(&wdev->event_lock, flags);
  227791. list_add_tail(&ev->list, &wdev->event_list);
  227792. diff -Nur linux-3.14.14/net/wireless/trace.h linux-imx6-3.14/net/wireless/trace.h
  227793. --- linux-3.14.14/net/wireless/trace.h 2014-07-28 10:07:25.000000000 -0500
  227794. +++ linux-imx6-3.14/net/wireless/trace.h 2014-12-08 00:31:55.868418001 -0600
  227795. @@ -2278,11 +2278,6 @@
  227796. TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr))
  227797. );
  227798. -DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined,
  227799. - TP_PROTO(struct net_device *netdev, const u8 *addr),
  227800. - TP_ARGS(netdev, addr)
  227801. -);
  227802. -
  227803. DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame,
  227804. TP_PROTO(struct net_device *netdev, const u8 *addr),
  227805. TP_ARGS(netdev, addr)
  227806. @@ -2293,6 +2288,24 @@
  227807. TP_ARGS(netdev, addr)
  227808. );
  227809. +TRACE_EVENT(cfg80211_ibss_joined,
  227810. + TP_PROTO(struct net_device *netdev, const u8 *bssid,
  227811. + struct ieee80211_channel *channel),
  227812. + TP_ARGS(netdev, bssid, channel),
  227813. + TP_STRUCT__entry(
  227814. + NETDEV_ENTRY
  227815. + MAC_ENTRY(bssid)
  227816. + CHAN_ENTRY
  227817. + ),
  227818. + TP_fast_assign(
  227819. + NETDEV_ASSIGN;
  227820. + MAC_ASSIGN(bssid, bssid);
  227821. + CHAN_ASSIGN(channel);
  227822. + ),
  227823. + TP_printk(NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", " CHAN_PR_FMT,
  227824. + NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
  227825. +);
  227826. +
  227827. TRACE_EVENT(cfg80211_probe_status,
  227828. TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie,
  227829. bool acked),
  227830. diff -Nur linux-3.14.14/net/wireless/util.c linux-imx6-3.14/net/wireless/util.c
  227831. --- linux-3.14.14/net/wireless/util.c 2014-07-28 10:07:25.000000000 -0500
  227832. +++ linux-imx6-3.14/net/wireless/util.c 2014-12-08 00:31:55.868418001 -0600
  227833. @@ -820,7 +820,8 @@
  227834. ev->dc.reason, true);
  227835. break;
  227836. case EVENT_IBSS_JOINED:
  227837. - __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
  227838. + __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,
  227839. + ev->ij.channel);
  227840. break;
  227841. }
  227842. wdev_unlock(wdev);
  227843. diff -Nur linux-3.14.14/scripts/Makefile.lib linux-imx6-3.14/scripts/Makefile.lib
  227844. --- linux-3.14.14/scripts/Makefile.lib 2014-07-28 10:07:25.000000000 -0500
  227845. +++ linux-imx6-3.14/scripts/Makefile.lib 2014-12-08 00:31:55.876418001 -0600
  227846. @@ -153,6 +153,7 @@
  227847. -I$(srctree)/arch/$(SRCARCH)/boot/dts \
  227848. -I$(srctree)/arch/$(SRCARCH)/boot/dts/include \
  227849. -I$(srctree)/drivers/of/testcase-data \
  227850. + -I$(srctree)/include \
  227851. -undef -D__DTS__
  227852. # Finds the multi-part object the current object will be linked into
  227853. diff -Nur linux-3.14.14/scripts/mod/devicetable-offsets.c linux-imx6-3.14/scripts/mod/devicetable-offsets.c
  227854. --- linux-3.14.14/scripts/mod/devicetable-offsets.c 2014-07-28 10:07:25.000000000 -0500
  227855. +++ linux-imx6-3.14/scripts/mod/devicetable-offsets.c 2014-12-08 00:31:55.892418001 -0600
  227856. @@ -174,6 +174,9 @@
  227857. DEVID_FIELD(x86_cpu_id, model);
  227858. DEVID_FIELD(x86_cpu_id, vendor);
  227859. + DEVID(cpu_feature);
  227860. + DEVID_FIELD(cpu_feature, feature);
  227861. +
  227862. DEVID(mei_cl_device_id);
  227863. DEVID_FIELD(mei_cl_device_id, name);
  227864. diff -Nur linux-3.14.14/scripts/mod/file2alias.c linux-imx6-3.14/scripts/mod/file2alias.c
  227865. --- linux-3.14.14/scripts/mod/file2alias.c 2014-07-28 10:07:25.000000000 -0500
  227866. +++ linux-imx6-3.14/scripts/mod/file2alias.c 2014-12-08 00:31:55.892418001 -0600
  227867. @@ -1135,6 +1135,16 @@
  227868. }
  227869. ADD_TO_DEVTABLE("x86cpu", x86_cpu_id, do_x86cpu_entry);
  227870. +/* LOOKS like cpu:type:*:feature:*FEAT* */
  227871. +static int do_cpu_entry(const char *filename, void *symval, char *alias)
  227872. +{
  227873. + DEF_FIELD(symval, cpu_feature, feature);
  227874. +
  227875. + sprintf(alias, "cpu:type:*:feature:*%04X*", feature);
  227876. + return 1;
  227877. +}
  227878. +ADD_TO_DEVTABLE("cpu", cpu_feature, do_cpu_entry);
  227879. +
  227880. /* Looks like: mei:S */
  227881. static int do_mei_entry(const char *filename, void *symval,
  227882. char *alias)
  227883. diff -Nur linux-3.14.14/scripts/recordmcount.c linux-imx6-3.14/scripts/recordmcount.c
  227884. --- linux-3.14.14/scripts/recordmcount.c 2014-07-28 10:07:25.000000000 -0500
  227885. +++ linux-imx6-3.14/scripts/recordmcount.c 2014-12-08 00:31:55.896418001 -0600
  227886. @@ -40,6 +40,11 @@
  227887. #define R_METAG_NONE 3
  227888. #endif
  227889. +#ifndef EM_AARCH64
  227890. +#define EM_AARCH64 183
  227891. +#define R_AARCH64_ABS64 257
  227892. +#endif
  227893. +
  227894. static int fd_map; /* File descriptor for file being modified. */
  227895. static int mmap_failed; /* Boolean flag. */
  227896. static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */
  227897. @@ -347,6 +352,8 @@
  227898. case EM_ARM: reltype = R_ARM_ABS32;
  227899. altmcount = "__gnu_mcount_nc";
  227900. break;
  227901. + case EM_AARCH64:
  227902. + reltype = R_AARCH64_ABS64; gpfx = '_'; break;
  227903. case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break;
  227904. case EM_METAG: reltype = R_METAG_ADDR32;
  227905. altmcount = "_mcount_wrapper";
  227906. diff -Nur linux-3.14.14/scripts/recordmcount.pl linux-imx6-3.14/scripts/recordmcount.pl
  227907. --- linux-3.14.14/scripts/recordmcount.pl 2014-07-28 10:07:25.000000000 -0500
  227908. +++ linux-imx6-3.14/scripts/recordmcount.pl 2014-12-08 00:31:55.896418001 -0600
  227909. @@ -279,6 +279,11 @@
  227910. $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_ARM_(CALL|PC24|THM_CALL)" .
  227911. "\\s+(__gnu_mcount_nc|mcount)\$";
  227912. +} elsif ($arch eq "arm64") {
  227913. + $alignment = 3;
  227914. + $section_type = '%progbits';
  227915. + $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_AARCH64_CALL26\\s+_mcount\$";
  227916. + $type = ".quad";
  227917. } elsif ($arch eq "ia64") {
  227918. $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
  227919. $type = "data8";
  227920. diff -Nur linux-3.14.14/sound/soc/codecs/cs42888.c linux-imx6-3.14/sound/soc/codecs/cs42888.c
  227921. --- linux-3.14.14/sound/soc/codecs/cs42888.c 1969-12-31 18:00:00.000000000 -0600
  227922. +++ linux-imx6-3.14/sound/soc/codecs/cs42888.c 2014-12-08 00:31:56.076418001 -0600
  227923. @@ -0,0 +1,934 @@
  227924. +/*
  227925. + * cs42888.c -- CS42888 ALSA SoC Audio Driver
  227926. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  227927. + */
  227928. +/*
  227929. + * The code contained herein is licensed under the GNU General Public
  227930. + * License. You may obtain a copy of the GNU General Public License
  227931. + * Version 2 or later at the following locations:
  227932. + *
  227933. + * http://www.opensource.org/licenses/gpl-license.html
  227934. + * http://www.gnu.org/copyleft/gpl.html
  227935. + */
  227936. +
  227937. +#include <linux/module.h>
  227938. +#include <linux/moduleparam.h>
  227939. +#include <linux/kernel.h>
  227940. +#include <linux/init.h>
  227941. +#include <linux/clk.h>
  227942. +#include <linux/delay.h>
  227943. +#include <linux/pm.h>
  227944. +#include <linux/i2c.h>
  227945. +#include <linux/spi/spi.h>
  227946. +#include <linux/platform_device.h>
  227947. +#include <linux/regulator/consumer.h>
  227948. +
  227949. +#include <sound/core.h>
  227950. +#include <sound/pcm.h>
  227951. +#include <sound/pcm_params.h>
  227952. +#include <sound/soc.h>
  227953. +#include <sound/soc-dapm.h>
  227954. +#include <sound/tlv.h>
  227955. +#include <sound/initval.h>
  227956. +#include <asm/div64.h>
  227957. +#include "cs42888.h"
  227958. +
  227959. +#define CS42888_NUM_SUPPLIES 4
  227960. +static const char *cs42888_supply_names[CS42888_NUM_SUPPLIES] = {
  227961. + "VA",
  227962. + "VD",
  227963. + "VLS",
  227964. + "VLC",
  227965. +};
  227966. +
  227967. +#define CS42888_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
  227968. + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
  227969. +
  227970. +/* Private data for the CS42888 */
  227971. +struct cs42888_private {
  227972. + struct clk *clk;
  227973. + struct snd_soc_codec *codec;
  227974. + u8 reg_cache[CS42888_NUMREGS + 1];
  227975. + unsigned int mclk; /* Input frequency of the MCLK pin */
  227976. + unsigned int slave_mode;
  227977. + struct regulator_bulk_data supplies[CS42888_NUM_SUPPLIES];
  227978. +};
  227979. +
  227980. +/**
  227981. + * cs42888_fill_cache - pre-fill the CS42888 register cache.
  227982. + * @codec: the codec for this CS42888
  227983. + *
  227984. + * This function fills in the CS42888 register cache by reading the register
  227985. + * values from the hardware.
  227986. + *
  227987. + * This CS42888 registers are cached to avoid excessive I2C I/O operations.
  227988. + * After the initial read to pre-fill the cache, the CS42888 never updates
  227989. + * the register values, so we won't have a cache coherency problem.
  227990. + *
  227991. + * We use the auto-increment feature of the CS42888 to read all registers in
  227992. + * one shot.
  227993. + */
  227994. +static int cs42888_fill_cache(struct snd_soc_codec *codec)
  227995. +{
  227996. + u8 *cache = codec->reg_cache;
  227997. + struct i2c_client *i2c_client = to_i2c_client(codec->dev);
  227998. + s32 length;
  227999. +
  228000. + length = i2c_smbus_read_i2c_block_data(i2c_client,
  228001. + CS42888_FIRSTREG | CS42888_I2C_INCR, CS42888_NUMREGS, \
  228002. + cache + 1);
  228003. +
  228004. + if (length != CS42888_NUMREGS) {
  228005. + dev_err(codec->dev, "i2c read failure, addr=0x%x\n",
  228006. + i2c_client->addr);
  228007. + return -EIO;
  228008. + }
  228009. + return 0;
  228010. +}
  228011. +
  228012. +#ifdef DEBUG
  228013. +static void dump_reg(struct snd_soc_codec *codec)
  228014. +{
  228015. + int i, reg;
  228016. + int ret;
  228017. + u8 *cache = codec->reg_cache + 1;
  228018. +
  228019. + dev_dbg(codec->dev, "dump begin\n");
  228020. + dev_dbg(codec->dev, "reg value in cache\n");
  228021. + for (i = 0; i < CS42888_NUMREGS; i++)
  228022. + dev_dbg(codec->dev, "reg[%d] = 0x%x\n", i, cache[i]);
  228023. +
  228024. + dev_dbg(codec->dev, "real reg value\n");
  228025. + ret = cs42888_fill_cache(codec);
  228026. + if (ret < 0) {
  228027. + dev_err(codec->dev, "failed to fill register cache\n");
  228028. + return ret;
  228029. + }
  228030. + for (i = 0; i < CS42888_NUMREGS; i++)
  228031. + dev_dbg(codec->dev, "reg[%d] = 0x%x\n", i, cache[i]);
  228032. +
  228033. + dev_dbg(codec->dev, "dump end\n");
  228034. +}
  228035. +#else
  228036. +static void dump_reg(struct snd_soc_codec *codec)
  228037. +{
  228038. +}
  228039. +#endif
  228040. +
  228041. +/* -127.5dB to 0dB with step of 0.5dB */
  228042. +static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
  228043. +/* -64dB to 24dB with step of 0.5dB */
  228044. +static const DECLARE_TLV_DB_SCALE(adc_tlv, -6400, 50, 1);
  228045. +
  228046. +static int cs42888_out_vu(struct snd_kcontrol *kcontrol,
  228047. + struct snd_ctl_elem_value *ucontrol)
  228048. +{
  228049. + return snd_soc_put_volsw_2r(kcontrol, ucontrol);
  228050. +}
  228051. +
  228052. +static int cs42888_info_volsw_s8(struct snd_kcontrol *kcontrol,
  228053. + struct snd_ctl_elem_info *uinfo)
  228054. +{
  228055. + struct soc_mixer_control *mc =
  228056. + (struct soc_mixer_control *)kcontrol->private_value;
  228057. +
  228058. + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  228059. + uinfo->count = 2;
  228060. + uinfo->value.integer.min = 0;
  228061. + uinfo->value.integer.max = mc->max - mc->min;
  228062. + return 0;
  228063. +}
  228064. +
  228065. +static int cs42888_get_volsw_s8(struct snd_kcontrol *kcontrol,
  228066. + struct snd_ctl_elem_value *ucontrol)
  228067. +{
  228068. + struct soc_mixer_control *mc =
  228069. + (struct soc_mixer_control *)kcontrol->private_value;
  228070. + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  228071. + s8 val = snd_soc_read(codec, mc->reg);
  228072. + ucontrol->value.integer.value[0] = val - mc->min;
  228073. +
  228074. + val = snd_soc_read(codec, mc->rreg);
  228075. + ucontrol->value.integer.value[1] = val - mc->min;
  228076. + return 0;
  228077. +}
  228078. +
  228079. +int cs42888_put_volsw_s8(struct snd_kcontrol *kcontrol,
  228080. + struct snd_ctl_elem_value *ucontrol)
  228081. +{
  228082. + struct soc_mixer_control *mc =
  228083. + (struct soc_mixer_control *)kcontrol->private_value;
  228084. + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  228085. + unsigned short val;
  228086. + int ret;
  228087. +
  228088. + val = ucontrol->value.integer.value[0] + mc->min;
  228089. + ret = snd_soc_write(codec, mc->reg, val);
  228090. + if (ret < 0) {
  228091. + dev_err(codec->dev, "i2c write failed\n");
  228092. + return ret;
  228093. + }
  228094. +
  228095. + val = ucontrol->value.integer.value[1] + mc->min;
  228096. + ret = snd_soc_write(codec, mc->rreg, val);
  228097. + if (ret < 0) {
  228098. + dev_err(codec->dev, "i2c write failed\n");
  228099. + return ret;
  228100. + }
  228101. + return 0;
  228102. +}
  228103. +
  228104. +#define SOC_CS42888_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
  228105. + xinvert, tlv_array) \
  228106. +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  228107. + .name = (xname), \
  228108. + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
  228109. + SNDRV_CTL_ELEM_ACCESS_READWRITE, \
  228110. + .tlv.p = (tlv_array), \
  228111. + .info = snd_soc_info_volsw, \
  228112. + .get = snd_soc_get_volsw, \
  228113. + .put = cs42888_out_vu, \
  228114. + .private_value = (unsigned long)&(struct soc_mixer_control) \
  228115. + {.reg = reg_left, \
  228116. + .rreg = reg_right, \
  228117. + .shift = xshift, \
  228118. + .max = xmax, \
  228119. + .invert = xinvert} \
  228120. +}
  228121. +
  228122. +#define SOC_CS42888_DOUBLE_R_S8_TLV(xname, reg_left, reg_right, xmin, xmax, \
  228123. + tlv_array) \
  228124. +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
  228125. + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
  228126. + SNDRV_CTL_ELEM_ACCESS_READWRITE, \
  228127. + .tlv.p = (tlv_array), \
  228128. + .info = cs42888_info_volsw_s8, \
  228129. + .get = cs42888_get_volsw_s8, \
  228130. + .put = cs42888_put_volsw_s8, \
  228131. + .private_value = (unsigned long)&(struct soc_mixer_control) \
  228132. + {.reg = reg_left, \
  228133. + .rreg = reg_right, \
  228134. + .min = xmin, \
  228135. + .max = xmax} \
  228136. +}
  228137. +
  228138. +static const char *cs42888_adcfilter[] = { "None", "High Pass" };
  228139. +static const char *cs42888_dacinvert[] = { "Disabled", "Enabled" };
  228140. +static const char *cs42888_adcinvert[] = { "Disabled", "Enabled" };
  228141. +static const char *cs42888_dacamute[] = { "Disabled", "AutoMute" };
  228142. +static const char *cs42888_dac_sngvol[] = { "Disabled", "Enabled" };
  228143. +static const char *cs42888_dac_szc[] = { "Immediate Change", "Zero Cross",
  228144. + "Soft Ramp", "Soft Ramp on Zero Cross" };
  228145. +static const char *cs42888_mute_adc[] = { "UnMute", "Mute" };
  228146. +static const char *cs42888_adc_sngvol[] = { "Disabled", "Enabled" };
  228147. +static const char *cs42888_adc_szc[] = { "Immediate Change", "Zero Cross",
  228148. + "Soft Ramp", "Soft Ramp on Zero Cross" };
  228149. +static const char *cs42888_dac_dem[] = { "No-De-Emphasis", "De-Emphasis" };
  228150. +static const char *cs42888_adc_single[] = { "Differential", "Single-Ended" };
  228151. +
  228152. +static const struct soc_enum cs42888_enum[] = {
  228153. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 7, 2, cs42888_adcfilter),
  228154. + SOC_ENUM_DOUBLE(CS42888_DACINV, 0, 1, 2, cs42888_dacinvert),
  228155. + SOC_ENUM_DOUBLE(CS42888_DACINV, 2, 3, 2, cs42888_dacinvert),
  228156. + SOC_ENUM_DOUBLE(CS42888_DACINV, 4, 5, 2, cs42888_dacinvert),
  228157. + SOC_ENUM_DOUBLE(CS42888_DACINV, 6, 7, 2, cs42888_dacinvert),
  228158. + SOC_ENUM_DOUBLE(CS42888_ADCINV, 0, 1, 2, cs42888_adcinvert),
  228159. + SOC_ENUM_DOUBLE(CS42888_ADCINV, 2, 3, 2, cs42888_adcinvert),
  228160. + SOC_ENUM_SINGLE(CS42888_TRANS, 4, 2, cs42888_dacamute),
  228161. + SOC_ENUM_SINGLE(CS42888_TRANS, 7, 2, cs42888_dac_sngvol),
  228162. + SOC_ENUM_SINGLE(CS42888_TRANS, 5, 4, cs42888_dac_szc),
  228163. + SOC_ENUM_SINGLE(CS42888_TRANS, 3, 2, cs42888_mute_adc),
  228164. + SOC_ENUM_SINGLE(CS42888_TRANS, 2, 2, cs42888_adc_sngvol),
  228165. + SOC_ENUM_SINGLE(CS42888_TRANS, 0, 4, cs42888_adc_szc),
  228166. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 5, 2, cs42888_dac_dem),
  228167. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 4, 2, cs42888_adc_single),
  228168. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 3, 2, cs42888_adc_single),
  228169. +};
  228170. +
  228171. +static const struct snd_kcontrol_new cs42888_snd_controls[] = {
  228172. + SOC_CS42888_DOUBLE_R_TLV("DAC1 Playback Volume", CS42888_VOLAOUT1,
  228173. + CS42888_VOLAOUT2, 0, 0xff, 1, dac_tlv),
  228174. + SOC_CS42888_DOUBLE_R_TLV("DAC2 Playback Volume", CS42888_VOLAOUT3,
  228175. + CS42888_VOLAOUT4, 0, 0xff, 1, dac_tlv),
  228176. + SOC_CS42888_DOUBLE_R_TLV("DAC3 Playback Volume", CS42888_VOLAOUT5,
  228177. + CS42888_VOLAOUT6, 0, 0xff, 1, dac_tlv),
  228178. + SOC_CS42888_DOUBLE_R_TLV("DAC4 Playback Volume", CS42888_VOLAOUT7,
  228179. + CS42888_VOLAOUT8, 0, 0xff, 1, dac_tlv),
  228180. + SOC_CS42888_DOUBLE_R_S8_TLV("ADC1 Capture Volume", CS42888_VOLAIN1,
  228181. + CS42888_VOLAIN2, -128, 48, adc_tlv),
  228182. + SOC_CS42888_DOUBLE_R_S8_TLV("ADC2 Capture Volume", CS42888_VOLAIN3,
  228183. + CS42888_VOLAIN4, -128, 48, adc_tlv),
  228184. + SOC_ENUM("ADC High-Pass Filter Switch", cs42888_enum[0]),
  228185. + SOC_ENUM("DAC1 Invert Switch", cs42888_enum[1]),
  228186. + SOC_ENUM("DAC2 Invert Switch", cs42888_enum[2]),
  228187. + SOC_ENUM("DAC3 Invert Switch", cs42888_enum[3]),
  228188. + SOC_ENUM("DAC4 Invert Switch", cs42888_enum[4]),
  228189. + SOC_ENUM("ADC1 Invert Switch", cs42888_enum[5]),
  228190. + SOC_ENUM("ADC2 Invert Switch", cs42888_enum[6]),
  228191. + SOC_ENUM("DAC Auto Mute Switch", cs42888_enum[7]),
  228192. + SOC_ENUM("DAC Single Volume Control Switch", cs42888_enum[8]),
  228193. + SOC_ENUM("DAC Soft Ramp and Zero Cross Control Switch", cs42888_enum[9]),
  228194. + SOC_ENUM("Mute ADC Serial Port Switch", cs42888_enum[10]),
  228195. + SOC_ENUM("ADC Single Volume Control Switch", cs42888_enum[11]),
  228196. + SOC_ENUM("ADC Soft Ramp and Zero Cross Control Switch", cs42888_enum[12]),
  228197. + SOC_ENUM("DAC Deemphasis Switch", cs42888_enum[13]),
  228198. + SOC_ENUM("ADC1 Single Ended Mode Switch", cs42888_enum[14]),
  228199. + SOC_ENUM("ADC2 Single Ended Mode Switch", cs42888_enum[15]),
  228200. +};
  228201. +
  228202. +
  228203. +static const struct snd_soc_dapm_widget cs42888_dapm_widgets[] = {
  228204. + SND_SOC_DAPM_DAC("DAC1", "codec-Playback", CS42888_PWRCTL, 1, 1),
  228205. + SND_SOC_DAPM_DAC("DAC2", "codec-Playback", CS42888_PWRCTL, 2, 1),
  228206. + SND_SOC_DAPM_DAC("DAC3", "codec-Playback", CS42888_PWRCTL, 3, 1),
  228207. + SND_SOC_DAPM_DAC("DAC4", "codec-Playback", CS42888_PWRCTL, 4, 1),
  228208. +
  228209. + SND_SOC_DAPM_OUTPUT("AOUT1L"),
  228210. + SND_SOC_DAPM_OUTPUT("AOUT1R"),
  228211. + SND_SOC_DAPM_OUTPUT("AOUT2L"),
  228212. + SND_SOC_DAPM_OUTPUT("AOUT2R"),
  228213. + SND_SOC_DAPM_OUTPUT("AOUT3L"),
  228214. + SND_SOC_DAPM_OUTPUT("AOUT3R"),
  228215. + SND_SOC_DAPM_OUTPUT("AOUT4L"),
  228216. + SND_SOC_DAPM_OUTPUT("AOUT4R"),
  228217. +
  228218. + SND_SOC_DAPM_ADC("ADC1", "codec-Capture", CS42888_PWRCTL, 5, 1),
  228219. + SND_SOC_DAPM_ADC("ADC2", "codec-Capture", CS42888_PWRCTL, 6, 1),
  228220. +
  228221. + SND_SOC_DAPM_INPUT("AIN1L"),
  228222. + SND_SOC_DAPM_INPUT("AIN1R"),
  228223. + SND_SOC_DAPM_INPUT("AIN2L"),
  228224. + SND_SOC_DAPM_INPUT("AIN2R"),
  228225. +
  228226. + SND_SOC_DAPM_PGA_E("PWR", CS42888_PWRCTL, 0, 1, NULL, 0,
  228227. + NULL, 0),
  228228. +};
  228229. +
  228230. +static const struct snd_soc_dapm_route audio_map[] = {
  228231. + /* Playback */
  228232. + { "PWR", NULL, "DAC1" },
  228233. + { "PWR", NULL, "DAC1" },
  228234. +
  228235. + { "PWR", NULL, "DAC2" },
  228236. + { "PWR", NULL, "DAC2" },
  228237. +
  228238. + { "PWR", NULL, "DAC3" },
  228239. + { "PWR", NULL, "DAC3" },
  228240. +
  228241. + { "PWR", NULL, "DAC4" },
  228242. + { "PWR", NULL, "DAC4" },
  228243. +
  228244. + { "AOUT1L", NULL, "PWR" },
  228245. + { "AOUT1R", NULL, "PWR" },
  228246. +
  228247. + { "AOUT2L", NULL, "PWR" },
  228248. + { "AOUT2R", NULL, "PWR" },
  228249. +
  228250. + { "AOUT3L", NULL, "PWR" },
  228251. + { "AOUT3R", NULL, "PWR" },
  228252. +
  228253. + { "AOUT4L", NULL, "PWR" },
  228254. + { "AOUT4R", NULL, "PWR" },
  228255. +
  228256. + /* Capture */
  228257. + { "PWR", NULL, "AIN1L" },
  228258. + { "PWR", NULL, "AIN1R" },
  228259. +
  228260. + { "PWR", NULL, "AIN2L" },
  228261. + { "PWR", NULL, "AIN2R" },
  228262. +
  228263. + { "ADC1", NULL, "PWR" },
  228264. + { "ADC1", NULL, "PWR" },
  228265. +
  228266. + { "ADC2", NULL, "PWR" },
  228267. + { "ADC2", NULL, "PWR" },
  228268. +};
  228269. +
  228270. +
  228271. +static int cs42888_add_widgets(struct snd_soc_codec *codec)
  228272. +{
  228273. + snd_soc_dapm_new_controls(&codec->dapm, cs42888_dapm_widgets,
  228274. + ARRAY_SIZE(cs42888_dapm_widgets));
  228275. +
  228276. + snd_soc_dapm_add_routes(&codec->dapm, audio_map, ARRAY_SIZE(audio_map));
  228277. +
  228278. + snd_soc_dapm_new_widgets(&codec->dapm);
  228279. + return 0;
  228280. +}
  228281. +
  228282. +/**
  228283. + * struct cs42888_mode_ratios - clock ratio tables
  228284. + * @ratio: the ratio of MCLK to the sample rate
  228285. + * @speed_mode: the Speed Mode bits to set in the Mode Control register for
  228286. + * this ratio
  228287. + * @mclk: the Ratio Select bits to set in the Mode Control register for this
  228288. + * ratio
  228289. + *
  228290. + * The data for this chart is taken from Table 10 of the CS42888 reference
  228291. + * manual.
  228292. + *
  228293. + * This table is used to determine how to program the Functional Mode register.
  228294. + * It is also used by cs42888_set_dai_sysclk() to tell ALSA which sampling
  228295. + * rates the CS42888 currently supports.
  228296. + *
  228297. + * @speed_mode is the corresponding bit pattern to be written to the
  228298. + * MODE bits of the Mode Control Register
  228299. + *
  228300. + * @mclk is the corresponding bit pattern to be wirten to the MCLK bits of
  228301. + * the Mode Control Register.
  228302. + *
  228303. + */
  228304. +struct cs42888_mode_ratios {
  228305. + unsigned int ratio;
  228306. + u8 speed_mode;
  228307. + u8 mclk;
  228308. +};
  228309. +
  228310. +static struct cs42888_mode_ratios cs42888_mode_ratios[] = {
  228311. + {64, CS42888_MODE_4X, CS42888_MODE_DIV1},
  228312. + {96, CS42888_MODE_4X, CS42888_MODE_DIV2},
  228313. + {128, CS42888_MODE_2X, CS42888_MODE_DIV1},
  228314. + {192, CS42888_MODE_2X, CS42888_MODE_DIV2},
  228315. + {256, CS42888_MODE_1X, CS42888_MODE_DIV1},
  228316. + {384, CS42888_MODE_2X, CS42888_MODE_DIV4},
  228317. + {512, CS42888_MODE_1X, CS42888_MODE_DIV3},
  228318. + {768, CS42888_MODE_1X, CS42888_MODE_DIV4},
  228319. + {1024, CS42888_MODE_1X, CS42888_MODE_DIV5}
  228320. +};
  228321. +
  228322. +/* The number of MCLK/LRCK ratios supported by the CS42888 */
  228323. +#define NUM_MCLK_RATIOS ARRAY_SIZE(cs42888_mode_ratios)
  228324. +
  228325. +/**
  228326. + * cs42888_set_dai_sysclk - determine the CS42888 samples rates.
  228327. + * @codec_dai: the codec DAI
  228328. + * @clk_id: the clock ID (ignored)
  228329. + * @freq: the MCLK input frequency
  228330. + * @dir: the clock direction (ignored)
  228331. + *
  228332. + * This function is used to tell the codec driver what the input MCLK
  228333. + * frequency is.
  228334. + *
  228335. + */
  228336. +static int cs42888_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  228337. + int clk_id, unsigned int freq, int dir)
  228338. +{
  228339. + struct snd_soc_codec *codec = codec_dai->codec;
  228340. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  228341. +
  228342. + cs42888->mclk = freq;
  228343. + return 0;
  228344. +}
  228345. +
  228346. +/**
  228347. + * cs42888_set_dai_fmt - configure the codec for the selected audio format
  228348. + * @codec_dai: the codec DAI
  228349. + * @format: a SND_SOC_DAIFMT_x value indicating the data format
  228350. + *
  228351. + * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the
  228352. + * codec accordingly.
  228353. + *
  228354. + * Currently, this function only supports SND_SOC_DAIFMT_I2S and
  228355. + * SND_SOC_DAIFMT_LEFT_J. The CS42888 codec also supports right-justified
  228356. + * data for playback only, but ASoC currently does not support different
  228357. + * formats for playback vs. record.
  228358. + */
  228359. +static int cs42888_set_dai_fmt(struct snd_soc_dai *codec_dai,
  228360. + unsigned int format)
  228361. +{
  228362. + struct snd_soc_codec *codec = codec_dai->codec;
  228363. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  228364. + int ret = 0;
  228365. + u8 val;
  228366. +
  228367. + val = snd_soc_read(codec, CS42888_FORMAT);
  228368. + val &= ~CS42888_FORMAT_DAC_DIF_MASK;
  228369. + val &= ~CS42888_FORMAT_ADC_DIF_MASK;
  228370. + /* set DAI format */
  228371. + switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
  228372. + case SND_SOC_DAIFMT_LEFT_J:
  228373. + val |= DIF_LEFT_J << CS42888_FORMAT_DAC_DIF_OFFSET;
  228374. + val |= DIF_LEFT_J << CS42888_FORMAT_ADC_DIF_OFFSET;
  228375. + break;
  228376. + case SND_SOC_DAIFMT_I2S:
  228377. + val |= DIF_I2S << CS42888_FORMAT_DAC_DIF_OFFSET;
  228378. + val |= DIF_I2S << CS42888_FORMAT_ADC_DIF_OFFSET;
  228379. + break;
  228380. + case SND_SOC_DAIFMT_RIGHT_J:
  228381. + val |= DIF_RIGHT_J << CS42888_FORMAT_DAC_DIF_OFFSET;
  228382. + val |= DIF_RIGHT_J << CS42888_FORMAT_ADC_DIF_OFFSET;
  228383. + break;
  228384. + default:
  228385. + dev_err(codec->dev, "invalid dai format\n");
  228386. + return -EINVAL;
  228387. + }
  228388. +
  228389. + ret = snd_soc_write(codec, CS42888_FORMAT, val);
  228390. + if (ret < 0) {
  228391. + dev_err(codec->dev, "i2c write failed\n");
  228392. + return ret;
  228393. + }
  228394. +
  228395. + val = snd_soc_read(codec, CS42888_MODE);
  228396. + /* set master/slave audio interface */
  228397. + switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
  228398. + case SND_SOC_DAIFMT_CBS_CFS:
  228399. + cs42888->slave_mode = 1;
  228400. + val &= ~CS42888_MODE_SPEED_MASK;
  228401. + val |= CS42888_MODE_SLAVE;
  228402. + break;
  228403. + case SND_SOC_DAIFMT_CBM_CFM:
  228404. + cs42888->slave_mode = 0;
  228405. + break;
  228406. + default:
  228407. + /* all other modes are unsupported by the hardware */
  228408. + return -EINVAL;
  228409. + }
  228410. +
  228411. + ret = snd_soc_write(codec, CS42888_MODE, val);
  228412. + if (ret < 0) {
  228413. + dev_err(codec->dev, "i2c write failed\n");
  228414. + return ret;
  228415. + }
  228416. +
  228417. + dump_reg(codec);
  228418. + return ret;
  228419. +}
  228420. +
  228421. +/**
  228422. + * cs42888_hw_params - program the CS42888 with the given hardware parameters.
  228423. + * @substream: the audio stream
  228424. + * @params: the hardware parameters to set
  228425. +
  228426. + * @dai: the SOC DAI (ignored)
  228427. + *
  228428. + * This function programs the hardware with the values provided.
  228429. + * Specifically, the sample rate and the data format.
  228430. + *
  228431. + * The .ops functions are used to provide board-specific data, like input
  228432. + * frequencies, to this driver. This function takes that information,
  228433. + * combines it with the hardware parameters provided, and programs the
  228434. + * hardware accordingly.
  228435. + */
  228436. +static int cs42888_hw_params(struct snd_pcm_substream *substream,
  228437. + struct snd_pcm_hw_params *params,
  228438. + struct snd_soc_dai *dai)
  228439. +{
  228440. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  228441. + struct snd_soc_codec *codec = rtd->codec;
  228442. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  228443. + int ret;
  228444. + u32 i, rate, ratio, val;
  228445. +
  228446. + rate = params_rate(params); /* Sampling rate, in Hz */
  228447. + ratio = cs42888->mclk / rate; /* MCLK/LRCK ratio */
  228448. + for (i = 0; i < NUM_MCLK_RATIOS; i++) {
  228449. + if (cs42888_mode_ratios[i].ratio == ratio)
  228450. + break;
  228451. + }
  228452. +
  228453. + if (i == NUM_MCLK_RATIOS) {
  228454. + /* We did not find a matching ratio */
  228455. + dev_err(codec->dev, "could not find matching ratio\n");
  228456. + return -EINVAL;
  228457. + }
  228458. +
  228459. + if (!cs42888->slave_mode) {
  228460. + val = snd_soc_read(codec, CS42888_MODE);
  228461. + val &= ~CS42888_MODE_SPEED_MASK;
  228462. + val |= cs42888_mode_ratios[i].speed_mode;
  228463. + val &= ~CS42888_MODE_DIV_MASK;
  228464. + val |= cs42888_mode_ratios[i].mclk;
  228465. + } else {
  228466. + val = snd_soc_read(codec, CS42888_MODE);
  228467. + val &= ~CS42888_MODE_SPEED_MASK;
  228468. + val |= CS42888_MODE_SLAVE;
  228469. + val &= ~CS42888_MODE_DIV_MASK;
  228470. + val |= cs42888_mode_ratios[i].mclk;
  228471. + }
  228472. + ret = snd_soc_write(codec, CS42888_MODE, val);
  228473. + if (ret < 0) {
  228474. + dev_err(codec->dev, "i2c write failed\n");
  228475. + return ret;
  228476. + }
  228477. +
  228478. + /* Unmute all the channels */
  228479. + val = snd_soc_read(codec, CS42888_MUTE);
  228480. + val &= ~CS42888_MUTE_ALL;
  228481. + ret = snd_soc_write(codec, CS42888_MUTE, val);
  228482. + if (ret < 0) {
  228483. + dev_err(codec->dev, "i2c write failed\n");
  228484. + return ret;
  228485. + }
  228486. +
  228487. + ret = cs42888_fill_cache(codec);
  228488. + if (ret < 0) {
  228489. + dev_err(codec->dev, "failed to fill register cache\n");
  228490. + return ret;
  228491. + }
  228492. +
  228493. + dump_reg(codec);
  228494. + return ret;
  228495. +}
  228496. +
  228497. +/**
  228498. + * cs42888_shutdown - cs42888 enters into low power mode again.
  228499. + * @substream: the audio stream
  228500. + * @dai: the SOC DAI (ignored)
  228501. + *
  228502. + * The .ops functions are used to provide board-specific data, like input
  228503. + * frequencies, to this driver. This function takes that information,
  228504. + * combines it with the hardware parameters provided, and programs the
  228505. + * hardware accordingly.
  228506. + */
  228507. +static void cs42888_shutdown(struct snd_pcm_substream *substream,
  228508. + struct snd_soc_dai *dai)
  228509. +{
  228510. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  228511. + struct snd_soc_codec *codec = rtd->codec;
  228512. + int ret;
  228513. + u8 val;
  228514. +
  228515. + /* Mute all the channels */
  228516. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  228517. + val = snd_soc_read(codec, CS42888_MUTE);
  228518. + val |= CS42888_MUTE_ALL;
  228519. + ret = snd_soc_write(codec, CS42888_MUTE, val);
  228520. + if (ret < 0)
  228521. + dev_err(codec->dev, "i2c write failed\n");
  228522. + }
  228523. +}
  228524. +
  228525. +static int cs42888_prepare(struct snd_pcm_substream *substream,
  228526. + struct snd_soc_dai *dai)
  228527. +{
  228528. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  228529. + struct snd_soc_card *card = rtd->card;
  228530. + struct snd_soc_dai *tmp_codec_dai;
  228531. + struct snd_soc_pcm_runtime *tmp_rtd;
  228532. + u32 i;
  228533. +
  228534. + for (i = 0; i < card->num_rtd; i++) {
  228535. + tmp_codec_dai = card->rtd[i].codec_dai;
  228536. + tmp_rtd = (struct snd_soc_pcm_runtime *)(card->rtd + i);
  228537. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  228538. + cancel_delayed_work(&tmp_rtd->delayed_work);
  228539. + }
  228540. + return 0;
  228541. +}
  228542. +
  228543. +static struct snd_soc_dai_ops cs42888_dai_ops = {
  228544. + .set_fmt = cs42888_set_dai_fmt,
  228545. + .set_sysclk = cs42888_set_dai_sysclk,
  228546. + .hw_params = cs42888_hw_params,
  228547. + .shutdown = cs42888_shutdown,
  228548. + .prepare = cs42888_prepare,
  228549. +};
  228550. +
  228551. +
  228552. +static struct snd_soc_dai_driver cs42888_dai = {
  228553. + .name = "CS42888",
  228554. + .playback = {
  228555. + .stream_name = "codec-Playback",
  228556. + .channels_min = 2,
  228557. + .channels_max = 8,
  228558. + .rates = SNDRV_PCM_RATE_8000_192000,
  228559. + .formats = CS42888_FORMATS,
  228560. + },
  228561. + .capture = {
  228562. + .stream_name = "codec-Capture",
  228563. + .channels_min = 2,
  228564. + .channels_max = 4,
  228565. + .rates = SNDRV_PCM_RATE_8000_192000,
  228566. + .formats = CS42888_FORMATS,
  228567. + },
  228568. + .ops = &cs42888_dai_ops,
  228569. +};
  228570. +
  228571. +/**
  228572. + * cs42888_probe - ASoC probe function
  228573. + * @pdev: platform device
  228574. + *
  228575. + * This function is called when ASoC has all the pieces it needs to
  228576. + * instantiate a sound driver.
  228577. + */
  228578. +static int cs42888_probe(struct snd_soc_codec *codec)
  228579. +{
  228580. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  228581. + int ret, i, val;
  228582. +
  228583. + cs42888->codec = codec;
  228584. + /* setup i2c data ops */
  228585. + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
  228586. + if (ret < 0) {
  228587. + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
  228588. + return ret;
  228589. + }
  228590. +
  228591. + for (i = 0; i < ARRAY_SIZE(cs42888->supplies); i++)
  228592. + cs42888->supplies[i].supply = cs42888_supply_names[i];
  228593. +
  228594. + ret = devm_regulator_bulk_get(codec->dev,
  228595. + ARRAY_SIZE(cs42888->supplies), cs42888->supplies);
  228596. + if (ret) {
  228597. + dev_err(codec->dev, "Failed to request supplies: %d\n",
  228598. + ret);
  228599. + return ret;
  228600. + }
  228601. +
  228602. + ret = regulator_bulk_enable(ARRAY_SIZE(cs42888->supplies),
  228603. + cs42888->supplies);
  228604. + if (ret) {
  228605. + dev_err(codec->dev, "Failed to enable supplies: %d\n",
  228606. + ret);
  228607. + goto err;
  228608. + }
  228609. + msleep(1);
  228610. +
  228611. + /* The I2C interface is set up, so pre-fill our register cache */
  228612. + ret = cs42888_fill_cache(codec);
  228613. + if (ret < 0) {
  228614. + dev_err(codec->dev, "failed to fill register cache\n");
  228615. + goto err;
  228616. + }
  228617. +
  228618. + /* Enter low power state */
  228619. + val = snd_soc_read(codec, CS42888_PWRCTL);
  228620. + val |= CS42888_PWRCTL_PDN_MASK;
  228621. + ret = snd_soc_write(codec, CS42888_PWRCTL, val);
  228622. + if (ret < 0) {
  228623. + dev_err(codec->dev, "i2c write failed\n");
  228624. + goto err;
  228625. + }
  228626. +
  228627. + /* Disable auto-mute */
  228628. + val = snd_soc_read(codec, CS42888_TRANS);
  228629. + val &= ~CS42888_TRANS_AMUTE_MASK;
  228630. + val &= ~CS42888_TRANS_DAC_SZC_MASK;
  228631. + val |= CS42888_TRANS_DAC_SZC_SR;
  228632. + ret = snd_soc_write(codec, CS42888_TRANS, val);
  228633. + if (ret < 0) {
  228634. + dev_err(codec->dev, "i2c write failed\n");
  228635. + goto err;
  228636. + }
  228637. + /* Add the non-DAPM controls */
  228638. + snd_soc_add_codec_controls(codec, cs42888_snd_controls,
  228639. + ARRAY_SIZE(cs42888_snd_controls));
  228640. +
  228641. + /* Add DAPM controls */
  228642. + cs42888_add_widgets(codec);
  228643. + return 0;
  228644. +err:
  228645. + regulator_bulk_disable(ARRAY_SIZE(cs42888->supplies),
  228646. + cs42888->supplies);
  228647. + return ret;
  228648. +}
  228649. +
  228650. +/**
  228651. + * cs42888_remove - ASoC remove function
  228652. + * @pdev: platform device
  228653. + *
  228654. + * This function is the counterpart to cs42888_probe().
  228655. + */
  228656. +static int cs42888_remove(struct snd_soc_codec *codec)
  228657. +{
  228658. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  228659. +
  228660. + regulator_bulk_disable(ARRAY_SIZE(cs42888->supplies),
  228661. + cs42888->supplies);
  228662. +
  228663. + return 0;
  228664. +};
  228665. +
  228666. +/*
  228667. + * ASoC codec device structure
  228668. + *
  228669. + * Assign this variable to the codec_dev field of the machine driver's
  228670. + * snd_soc_device structure.
  228671. + */
  228672. +static struct snd_soc_codec_driver cs42888_driver = {
  228673. + .probe = cs42888_probe,
  228674. + .remove = cs42888_remove,
  228675. + .reg_cache_size = CS42888_NUMREGS + 1,
  228676. + .reg_word_size = sizeof(u8),
  228677. + .reg_cache_step = 1,
  228678. +};
  228679. +
  228680. +/**
  228681. + * cs42888_i2c_probe - initialize the I2C interface of the CS42888
  228682. + * @i2c_client: the I2C client object
  228683. + * @id: the I2C device ID (ignored)
  228684. + *
  228685. + * This function is called whenever the I2C subsystem finds a device that
  228686. + * matches the device ID given via a prior call to i2c_add_driver().
  228687. + */
  228688. +static int cs42888_i2c_probe(struct i2c_client *i2c_client,
  228689. + const struct i2c_device_id *id)
  228690. +{
  228691. + struct cs42888_private *cs42888;
  228692. + int ret, val;
  228693. +
  228694. + /* Verify that we have a CS42888 */
  228695. + val = i2c_smbus_read_byte_data(i2c_client, CS42888_CHIPID);
  228696. + if (val < 0) {
  228697. + dev_err(&i2c_client->dev, "Device with ID register %x is not a CS42888", val);
  228698. + return -ENODEV;
  228699. + }
  228700. + /* The top four bits of the chip ID should be 0000. */
  228701. + if ((val & CS42888_CHIPID_ID_MASK) != 0x00) {
  228702. + dev_err(&i2c_client->dev, "device is not a CS42888\n");
  228703. + return -ENODEV;
  228704. + }
  228705. +
  228706. + dev_info(&i2c_client->dev, "found device at i2c address %X\n",
  228707. + i2c_client->addr);
  228708. + dev_info(&i2c_client->dev, "hardware revision %X\n", val & 0xF);
  228709. +
  228710. + /* Allocate enough space for the snd_soc_codec structure
  228711. + and our private data together. */
  228712. + cs42888 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42888_private), GFP_KERNEL);
  228713. + if (!cs42888) {
  228714. + dev_err(&i2c_client->dev, "could not allocate codec\n");
  228715. + return -ENOMEM;
  228716. + }
  228717. +
  228718. + i2c_set_clientdata(i2c_client, cs42888);
  228719. +
  228720. + cs42888->clk = devm_clk_get(&i2c_client->dev, NULL);
  228721. + if (IS_ERR(cs42888->clk)) {
  228722. + ret = PTR_ERR(cs42888->clk);
  228723. + dev_err(&i2c_client->dev, "Cannot get the clock: %d\n", ret);
  228724. + return ret;
  228725. + }
  228726. +
  228727. + cs42888->mclk = clk_get_rate(cs42888->clk);
  228728. + switch (cs42888->mclk) {
  228729. + case 24576000:
  228730. + cs42888_dai.playback.rates = SNDRV_PCM_RATE_48000 |
  228731. + SNDRV_PCM_RATE_96000 |
  228732. + SNDRV_PCM_RATE_192000;
  228733. + cs42888_dai.capture.rates = SNDRV_PCM_RATE_48000 |
  228734. + SNDRV_PCM_RATE_96000 |
  228735. + SNDRV_PCM_RATE_192000;
  228736. + break;
  228737. + case 16934400:
  228738. + cs42888_dai.playback.rates = SNDRV_PCM_RATE_44100 |
  228739. + SNDRV_PCM_RATE_88200 |
  228740. + SNDRV_PCM_RATE_176400;
  228741. + cs42888_dai.capture.rates = SNDRV_PCM_RATE_44100 |
  228742. + SNDRV_PCM_RATE_88200 |
  228743. + SNDRV_PCM_RATE_176400;
  228744. + break;
  228745. + default:
  228746. + dev_err(&i2c_client->dev, "codec mclk is not supported %d\n", cs42888->mclk);
  228747. + break;
  228748. + }
  228749. +
  228750. + ret = snd_soc_register_codec(&i2c_client->dev,
  228751. + &cs42888_driver, &cs42888_dai, 1);
  228752. + if (ret) {
  228753. + dev_err(&i2c_client->dev, "Failed to register codec:%d\n", ret);
  228754. + return ret;
  228755. + }
  228756. + return 0;
  228757. +}
  228758. +
  228759. +/**
  228760. + * cs42888_i2c_remove - remove an I2C device
  228761. + * @i2c_client: the I2C client object
  228762. + *
  228763. + * This function is the counterpart to cs42888_i2c_probe().
  228764. + */
  228765. +static int cs42888_i2c_remove(struct i2c_client *i2c_client)
  228766. +{
  228767. + snd_soc_unregister_codec(&i2c_client->dev);
  228768. + return 0;
  228769. +}
  228770. +
  228771. +/*
  228772. + * cs42888_i2c_id - I2C device IDs supported by this driver
  228773. + */
  228774. +static struct i2c_device_id cs42888_i2c_id[] = {
  228775. + {"cs42888", 0},
  228776. + {}
  228777. +};
  228778. +MODULE_DEVICE_TABLE(i2c, cs42888_i2c_id);
  228779. +
  228780. +#ifdef CONFIG_PM
  228781. +/* This suspend/resume implementation can handle both - a simple standby
  228782. + * where the codec remains powered, and a full suspend, where the voltage
  228783. + * domain the codec is connected to is teared down and/or any other hardware
  228784. + * reset condition is asserted.
  228785. + *
  228786. + * The codec's own power saving features are enabled in the suspend callback,
  228787. + * and all registers are written back to the hardware when resuming.
  228788. + */
  228789. +
  228790. +static int cs42888_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
  228791. +{
  228792. + struct cs42888_private *cs42888 = i2c_get_clientdata(client);
  228793. + struct snd_soc_codec *codec = cs42888->codec;
  228794. + int reg = snd_soc_read(codec, CS42888_PWRCTL) | CS42888_PWRCTL_PDN_MASK;
  228795. + return snd_soc_write(codec, CS42888_PWRCTL, reg);
  228796. +}
  228797. +
  228798. +static int cs42888_i2c_resume(struct i2c_client *client)
  228799. +{
  228800. + struct cs42888_private *cs42888 = i2c_get_clientdata(client);
  228801. + struct snd_soc_codec *codec = cs42888->codec;
  228802. + int reg;
  228803. +
  228804. + /* In case the device was put to hard reset during sleep, we need to
  228805. + * wait 500ns here before any I2C communication. */
  228806. + ndelay(500);
  228807. +
  228808. + /* first restore the entire register cache ... */
  228809. + for (reg = CS42888_FIRSTREG; reg <= CS42888_LASTREG; reg++) {
  228810. + u8 val = snd_soc_read(codec, reg);
  228811. +
  228812. + if (i2c_smbus_write_byte_data(client, reg, val)) {
  228813. + dev_err(codec->dev, "i2c write failed\n");
  228814. + return -EIO;
  228815. + }
  228816. + }
  228817. +
  228818. + /* ... then disable the power-down bits */
  228819. + reg = snd_soc_read(codec, CS42888_PWRCTL);
  228820. + reg &= ~CS42888_PWRCTL_PDN_MASK;
  228821. + return snd_soc_write(codec, CS42888_PWRCTL, reg);
  228822. +}
  228823. +#else
  228824. +#define cs42888_i2c_suspend NULL
  228825. +#define cs42888_i2c_resume NULL
  228826. +#endif /* CONFIG_PM */
  228827. +
  228828. +/*
  228829. + * cs42888_i2c_driver - I2C device identification
  228830. + *
  228831. + * This structure tells the I2C subsystem how to identify and support a
  228832. + * given I2C device type.
  228833. + */
  228834. +
  228835. +static const struct of_device_id cs42888_dt_ids[] = {
  228836. + { .compatible = "cirrus,cs42888", },
  228837. + { /* sentinel */ }
  228838. +};
  228839. +
  228840. +static struct i2c_driver cs42888_i2c_driver = {
  228841. + .driver = {
  228842. + .name = "cs42888",
  228843. + .owner = THIS_MODULE,
  228844. + .of_match_table = cs42888_dt_ids,
  228845. + },
  228846. + .probe = cs42888_i2c_probe,
  228847. + .remove = cs42888_i2c_remove,
  228848. + .suspend = cs42888_i2c_suspend,
  228849. + .resume = cs42888_i2c_resume,
  228850. + .id_table = cs42888_i2c_id,
  228851. +};
  228852. +
  228853. +module_i2c_driver(cs42888_i2c_driver);
  228854. +
  228855. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  228856. +MODULE_DESCRIPTION("Cirrus Logic CS42888 ALSA SoC Codec Driver");
  228857. +MODULE_LICENSE("GPL");
  228858. diff -Nur linux-3.14.14/sound/soc/codecs/cs42888.h linux-imx6-3.14/sound/soc/codecs/cs42888.h
  228859. --- linux-3.14.14/sound/soc/codecs/cs42888.h 1969-12-31 18:00:00.000000000 -0600
  228860. +++ linux-imx6-3.14/sound/soc/codecs/cs42888.h 2014-12-08 00:31:56.076418001 -0600
  228861. @@ -0,0 +1,123 @@
  228862. +/*
  228863. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  228864. + */
  228865. +
  228866. +/*
  228867. + * The code contained herein is licensed under the GNU General Public
  228868. + * License. You may obtain a copy of the GNU General Public License
  228869. + * Version 2 or later at the following locations:
  228870. + *
  228871. + * http://www.opensource.org/licenses/gpl-license.html
  228872. + * http://www.gnu.org/copyleft/gpl.html
  228873. + */
  228874. +
  228875. +#ifndef _CS42888_H
  228876. +#define _CS42888_H
  228877. +
  228878. +/* CS42888 registers addresses */
  228879. +#define CS42888_CHIPID 0x01 /* Chip ID */
  228880. +#define CS42888_PWRCTL 0x02 /* Power Control */
  228881. +#define CS42888_MODE 0x03 /* Functional Mode */
  228882. +#define CS42888_FORMAT 0x04 /* Interface Formats */
  228883. +#define CS42888_ADCCTL 0x05 /* ADC Control */
  228884. +#define CS42888_TRANS 0x06 /* Transition Control */
  228885. +#define CS42888_MUTE 0x07 /* Mute Control */
  228886. +#define CS42888_VOLAOUT1 0x08 /* Volume Control AOUT1*/
  228887. +#define CS42888_VOLAOUT2 0x09 /* Volume Control AOUT2*/
  228888. +#define CS42888_VOLAOUT3 0x0A /* Volume Control AOUT3*/
  228889. +#define CS42888_VOLAOUT4 0x0B /* Volume Control AOUT4*/
  228890. +#define CS42888_VOLAOUT5 0x0C /* Volume Control AOUT5*/
  228891. +#define CS42888_VOLAOUT6 0x0D /* Volume Control AOUT6*/
  228892. +#define CS42888_VOLAOUT7 0x0E /* Volume Control AOUT7*/
  228893. +#define CS42888_VOLAOUT8 0x0F /* Volume Control AOUT8*/
  228894. +#define CS42888_DACINV 0x10 /* DAC Channel Invert */
  228895. +#define CS42888_VOLAIN1 0x11 /* Volume Control AIN1 */
  228896. +#define CS42888_VOLAIN2 0x12 /* Volume Control AIN2 */
  228897. +#define CS42888_VOLAIN3 0x13 /* Volume Control AIN3 */
  228898. +#define CS42888_VOLAIN4 0x14 /* Volume Control AIN4 */
  228899. +#define CS42888_ADCINV 0x17 /* ADC Channel Invert */
  228900. +#define CS42888_STATUSCTL 0x18 /* Status Control */
  228901. +#define CS42888_STATUS 0x19 /* Status */
  228902. +#define CS42888_STATUSMASK 0x1A /* Status Mask */
  228903. +
  228904. +#define CS42888_FIRSTREG 0x01
  228905. +#define CS42888_LASTREG 0x1A
  228906. +#define CS42888_NUMREGS (CS42888_LASTREG - CS42888_FIRSTREG + 1)
  228907. +#define CS42888_I2C_INCR 0x80
  228908. +
  228909. +/* Bit masks for the CS42888 registers */
  228910. +#define CS42888_CHIPID_ID_MASK 0xF0
  228911. +#define CS42888_CHIPID_REV 0x0F
  228912. +#define CS42888_PWRCTL_PDN_ADC2_OFFSET 6
  228913. +#define CS42888_PWRCTL_PDN_ADC1_OFFSET 5
  228914. +#define CS42888_PWRCTL_PDN_DAC4_OFFSET 4
  228915. +#define CS42888_PWRCTL_PDN_DAC3_OFFSET 3
  228916. +#define CS42888_PWRCTL_PDN_DAC2_OFFSET 2
  228917. +#define CS42888_PWRCTL_PDN_DAC1_OFFSET 1
  228918. +#define CS42888_PWRCTL_PDN_OFFSET 0
  228919. +#define CS42888_PWRCTL_PDN_ADC2_MASK (1 << CS42888_PWRCTL_PDN_ADC2_OFFSET)
  228920. +#define CS42888_PWRCTL_PDN_ADC1_MASK (1 << CS42888_PWRCTL_PDN_ADC1_OFFSET)
  228921. +#define CS42888_PWRCTL_PDN_DAC4_MASK (1 << CS42888_PWRCTL_PDN_DAC4_OFFSET)
  228922. +#define CS42888_PWRCTL_PDN_DAC3_MASK (1 << CS42888_PWRCTL_PDN_DAC3_OFFSET)
  228923. +#define CS42888_PWRCTL_PDN_DAC2_MASK (1 << CS42888_PWRCTL_PDN_DAC2_OFFSET)
  228924. +#define CS42888_PWRCTL_PDN_DAC1_MASK (1 << CS42888_PWRCTL_PDN_DAC1_OFFSET)
  228925. +#define CS42888_PWRCTL_PDN_MASK (1 << CS42888_PWRCTL_PDN_OFFSET)
  228926. +
  228927. +#define CS42888_MODE_SPEED_MASK 0xF0
  228928. +#define CS42888_MODE_1X 0x00
  228929. +#define CS42888_MODE_2X 0x50
  228930. +#define CS42888_MODE_4X 0xA0
  228931. +#define CS42888_MODE_SLAVE 0xF0
  228932. +#define CS42888_MODE_DIV_MASK 0x0E
  228933. +#define CS42888_MODE_DIV1 0x00
  228934. +#define CS42888_MODE_DIV2 0x02
  228935. +#define CS42888_MODE_DIV3 0x04
  228936. +#define CS42888_MODE_DIV4 0x06
  228937. +#define CS42888_MODE_DIV5 0x08
  228938. +
  228939. +#define CS42888_FORMAT_FREEZE_OFFSET 7
  228940. +#define CS42888_FORMAT_AUX_DIF_OFFSET 6
  228941. +#define CS42888_FORMAT_DAC_DIF_OFFSET 3
  228942. +#define CS42888_FORMAT_ADC_DIF_OFFSET 0
  228943. +#define CS42888_FORMAT_FREEZE_MASK (1 << CS42888_FORMAT_FREEZE_OFFSET)
  228944. +#define CS42888_FORMAT_AUX_DIF_MASK (1 << CS42888_FORMAT_AUX_DIF_OFFSET)
  228945. +#define CS42888_FORMAT_DAC_DIF_MASK (7 << CS42888_FORMAT_DAC_DIF_OFFSET)
  228946. +#define CS42888_FORMAT_ADC_DIF_MASK (7 << CS42888_FORMAT_ADC_DIF_OFFSET)
  228947. +
  228948. +#define CS42888_TRANS_DAC_SNGVOL_OFFSET 7
  228949. +#define CS42888_TRANS_DAC_SZC_OFFSET 5
  228950. +#define CS42888_TRANS_AMUTE_OFFSET 4
  228951. +#define CS42888_TRANS_MUTE_ADC_SP_OFFSET 3
  228952. +#define CS42888_TRANS_ADC_SNGVOL_OFFSET 2
  228953. +#define CS42888_TRANS_ADC_SZC_OFFSET 0
  228954. +#define CS42888_TRANS_DAC_SNGVOL_MASK (1 << CS42888_TRANS_DAC_SNGVOL_OFFSET)
  228955. +#define CS42888_TRANS_DAC_SZC_MASK (3 << CS42888_TRANS_DAC_SZC_OFFSET)
  228956. +#define CS42888_TRANS_AMUTE_MASK (1 << CS42888_TRANS_AMUTE_OFFSET)
  228957. +#define CS42888_TRANS_MUTE_ADC_SP_MASK (1 << CS42888_TRANS_MUTE_ADC_SP_OFFSET)
  228958. +#define CS42888_TRANS_ADC_SNGVOL_MASK (1 << CS42888_TRANS_ADC_SNGVOL_OFFSET)
  228959. +#define CS42888_TRANS_ADC_SZC_MASK (3 << CS42888_TRANS_ADC_SZC_OFFSET)
  228960. +#define CS42888_TRANS_DAC_SZC_IC (0 << CS42888_TRANS_DAC_SZC_OFFSET)
  228961. +#define CS42888_TRANS_DAC_SZC_ZC (1 << CS42888_TRANS_DAC_SZC_OFFSET)
  228962. +#define CS42888_TRANS_DAC_SZC_SR (2 << CS42888_TRANS_DAC_SZC_OFFSET)
  228963. +#define CS42888_TRANS_DAC_SZC_SRZC (3 << CS42888_TRANS_DAC_SZC_OFFSET)
  228964. +
  228965. +#define CS42888_MUTE_AOUT8 (0x1 << 7)
  228966. +#define CS42888_MUTE_AOUT7 (0x1 << 6)
  228967. +#define CS42888_MUTE_AOUT6 (0x1 << 5)
  228968. +#define CS42888_MUTE_AOUT5 (0x1 << 4)
  228969. +#define CS42888_MUTE_AOUT4 (0x1 << 3)
  228970. +#define CS42888_MUTE_AOUT3 (0x1 << 2)
  228971. +#define CS42888_MUTE_AOUT2 (0x1 << 1)
  228972. +#define CS42888_MUTE_AOUT1 (0x1 << 0)
  228973. +#define CS42888_MUTE_ALL (CS42888_MUTE_AOUT1 | CS42888_MUTE_AOUT2 | \
  228974. + CS42888_MUTE_AOUT3 | CS42888_MUTE_AOUT4 | \
  228975. + CS42888_MUTE_AOUT5 | CS42888_MUTE_AOUT6 | \
  228976. + CS42888_MUTE_AOUT7 | CS42888_MUTE_AOUT8)
  228977. +
  228978. +#define DIF_LEFT_J 0
  228979. +#define DIF_I2S 1
  228980. +#define DIF_RIGHT_J 2
  228981. +#define DIF_TDM 6
  228982. +
  228983. +
  228984. +#endif
  228985. diff -Nur linux-3.14.14/sound/soc/codecs/Kconfig linux-imx6-3.14/sound/soc/codecs/Kconfig
  228986. --- linux-3.14.14/sound/soc/codecs/Kconfig 2014-07-28 10:07:25.000000000 -0500
  228987. +++ linux-imx6-3.14/sound/soc/codecs/Kconfig 2014-12-08 00:31:56.072418001 -0600
  228988. @@ -37,6 +37,7 @@
  228989. select SND_SOC_CS42L73 if I2C
  228990. select SND_SOC_CS4270 if I2C
  228991. select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
  228992. + select SND_SOC_CS42888 if I2C
  228993. select SND_SOC_CX20442 if TTY
  228994. select SND_SOC_DA7210 if I2C
  228995. select SND_SOC_DA7213 if I2C
  228996. @@ -254,6 +255,9 @@
  228997. config SND_SOC_CS4271
  228998. tristate
  228999. +config SND_SOC_CS42888
  229000. + tristate
  229001. +
  229002. config SND_SOC_CX20442
  229003. tristate
  229004. depends on TTY
  229005. diff -Nur linux-3.14.14/sound/soc/codecs/Makefile linux-imx6-3.14/sound/soc/codecs/Makefile
  229006. --- linux-3.14.14/sound/soc/codecs/Makefile 2014-07-28 10:07:25.000000000 -0500
  229007. +++ linux-imx6-3.14/sound/soc/codecs/Makefile 2014-12-08 00:31:56.072418001 -0600
  229008. @@ -23,6 +23,7 @@
  229009. snd-soc-cs42l73-objs := cs42l73.o
  229010. snd-soc-cs4270-objs := cs4270.o
  229011. snd-soc-cs4271-objs := cs4271.o
  229012. +snd-soc-cs42888-objs := cs42888.o
  229013. snd-soc-cx20442-objs := cx20442.o
  229014. snd-soc-da7210-objs := da7210.o
  229015. snd-soc-da7213-objs := da7213.o
  229016. @@ -156,6 +157,7 @@
  229017. obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o
  229018. obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
  229019. obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
  229020. +obj-$(CONFIG_SND_SOC_CS42888) += snd-soc-cs42888.o
  229021. obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
  229022. obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
  229023. obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
  229024. diff -Nur linux-3.14.14/sound/soc/codecs/sgtl5000.c linux-imx6-3.14/sound/soc/codecs/sgtl5000.c
  229025. --- linux-3.14.14/sound/soc/codecs/sgtl5000.c 2014-07-28 10:07:25.000000000 -0500
  229026. +++ linux-imx6-3.14/sound/soc/codecs/sgtl5000.c 2014-12-08 00:31:56.084418001 -0600
  229027. @@ -756,7 +756,7 @@
  229028. struct ldo_regulator *ldo = rdev_get_drvdata(dev);
  229029. struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
  229030. int reg;
  229031. -
  229032. +dev_info(codec->dev, "%s(): enabled %u\n", __func__, ldo->enabled);
  229033. if (ldo_regulator_is_enabled(dev))
  229034. return 0;
  229035. @@ -788,10 +788,16 @@
  229036. {
  229037. struct ldo_regulator *ldo = rdev_get_drvdata(dev);
  229038. struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
  229039. +dev_info(codec->dev, "%s(): enabled %u\n", __func__, ldo->enabled);
  229040. +
  229041. + snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  229042. + SGTL5000_LINREG_SIMPLE_POWERUP,
  229043. + SGTL5000_LINREG_SIMPLE_POWERUP);
  229044. snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  229045. SGTL5000_LINEREG_D_POWERUP,
  229046. 0);
  229047. +dev_info(codec->dev, "%s: ANA_POWER = 0x%04x\n", __func__, snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER));
  229048. /* clear voltage info */
  229049. snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
  229050. @@ -849,6 +855,7 @@
  229051. config.dev = codec->dev;
  229052. config.driver_data = ldo;
  229053. config.init_data = init_data;
  229054. + config.ena_gpio = -EINVAL;
  229055. ldo->dev = regulator_register(&ldo->desc, &config);
  229056. if (IS_ERR(ldo->dev)) {
  229057. @@ -1202,8 +1209,11 @@
  229058. * if vddio and vddd > 3.1v,
  229059. * charge pump should be clean before set ana_pwr
  229060. */
  229061. - snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  229062. - SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
  229063. +// FIXME: this is total crap - we have read this register above into
  229064. +// ana_pwr, which we then modify (above), and then write back to the
  229065. +// register below. This modification just gets completely overwritten.
  229066. +// snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  229067. +// SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
  229068. /* VDDC use VDDIO rail */
  229069. lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
  229070. @@ -1320,7 +1330,7 @@
  229071. return ret;
  229072. }
  229073. - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
  229074. + ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
  229075. sgtl5000->supplies);
  229076. if (ret)
  229077. goto err_ldo_remove;
  229078. @@ -1328,16 +1338,13 @@
  229079. ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
  229080. sgtl5000->supplies);
  229081. if (ret)
  229082. - goto err_regulator_free;
  229083. + goto err_ldo_remove;
  229084. /* wait for all power rails bring up */
  229085. udelay(10);
  229086. return 0;
  229087. -err_regulator_free:
  229088. - regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
  229089. - sgtl5000->supplies);
  229090. err_ldo_remove:
  229091. if (!external_vddd)
  229092. ldo_regulator_remove(codec);
  229093. @@ -1358,6 +1365,9 @@
  229094. return ret;
  229095. }
  229096. + if (!devres_open_group(codec->dev, NULL, GFP_KERNEL))
  229097. + return -ENOMEM;
  229098. +
  229099. ret = sgtl5000_enable_regulators(codec);
  229100. if (ret)
  229101. return ret;
  229102. @@ -1415,8 +1425,9 @@
  229103. err:
  229104. regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
  229105. sgtl5000->supplies);
  229106. - regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
  229107. - sgtl5000->supplies);
  229108. +
  229109. + devres_release_group(codec->dev, NULL);
  229110. +
  229111. ldo_regulator_remove(codec);
  229112. return ret;
  229113. @@ -1430,8 +1441,9 @@
  229114. regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
  229115. sgtl5000->supplies);
  229116. - regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
  229117. - sgtl5000->supplies);
  229118. +
  229119. + devres_release_group(codec->dev, NULL);
  229120. +
  229121. ldo_regulator_remove(codec);
  229122. return 0;
  229123. diff -Nur linux-3.14.14/sound/soc/codecs/spdif_transmitter.c linux-imx6-3.14/sound/soc/codecs/spdif_transmitter.c
  229124. --- linux-3.14.14/sound/soc/codecs/spdif_transmitter.c 2014-07-28 10:07:25.000000000 -0500
  229125. +++ linux-imx6-3.14/sound/soc/codecs/spdif_transmitter.c 2014-12-08 00:31:56.084418001 -0600
  229126. @@ -24,7 +24,7 @@
  229127. #define DRV_NAME "spdif-dit"
  229128. -#define STUB_RATES SNDRV_PCM_RATE_8000_96000
  229129. +#define STUB_RATES SNDRV_PCM_RATE_8000_192000
  229130. #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
  229131. SNDRV_PCM_FMTBIT_S20_3LE | \
  229132. SNDRV_PCM_FMTBIT_S24_LE)
  229133. diff -Nur linux-3.14.14/sound/soc/codecs/wm8962.c linux-imx6-3.14/sound/soc/codecs/wm8962.c
  229134. --- linux-3.14.14/sound/soc/codecs/wm8962.c 2014-07-28 10:07:25.000000000 -0500
  229135. +++ linux-imx6-3.14/sound/soc/codecs/wm8962.c 2014-12-08 00:31:56.100418001 -0600
  229136. @@ -16,6 +16,7 @@
  229137. #include <linux/init.h>
  229138. #include <linux/delay.h>
  229139. #include <linux/pm.h>
  229140. +#include <linux/clk.h>
  229141. #include <linux/gcd.h>
  229142. #include <linux/gpio.h>
  229143. #include <linux/i2c.h>
  229144. @@ -2942,7 +2943,8 @@
  229145. WM8962_DAC_MUTE, val);
  229146. }
  229147. -#define WM8962_RATES SNDRV_PCM_RATE_8000_96000
  229148. +#define WM8962_RATES (SNDRV_PCM_RATE_8000_48000 |\
  229149. + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
  229150. #define WM8962_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
  229151. SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
  229152. @@ -3536,6 +3538,15 @@
  229153. pdata->gpio_init[i] = 0x0;
  229154. }
  229155. + pdata->codec_mclk = devm_clk_get(&i2c->dev, NULL);
  229156. +
  229157. + /*
  229158. + * If clk_get() failed, we assume that clock's enabled by default.
  229159. + * Otherwise, we let driver prepare and control the clock source.
  229160. + */
  229161. + if (IS_ERR(pdata->codec_mclk))
  229162. + pdata->codec_mclk = NULL;
  229163. +
  229164. return 0;
  229165. }
  229166. @@ -3567,6 +3578,9 @@
  229167. return ret;
  229168. }
  229169. + if (wm8962->pdata.codec_mclk)
  229170. + clk_prepare(wm8962->pdata.codec_mclk);
  229171. +
  229172. for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
  229173. wm8962->supplies[i].supply = wm8962_supply_names[i];
  229174. @@ -3669,6 +3683,27 @@
  229175. WM8962_MICBIAS_LVL,
  229176. wm8962->pdata.mic_cfg);
  229177. + /* set the default volume for playback and record*/
  229178. + snd_soc_update_bits(codec, WM8962_HPOUTL_VOLUME,
  229179. + WM8962_HPOUTL_VOL_MASK, 0x5d);
  229180. + snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME,
  229181. + WM8962_HPOUTR_VOL_MASK, 0x5d);
  229182. + snd_soc_update_bits(codec, WM8962_SPKOUTL_VOLUME,
  229183. + WM8962_SPKOUTL_VOL_MASK, 0x72);
  229184. + snd_soc_update_bits(codec, WM8962_SPKOUTR_VOLUME,
  229185. + WM8962_SPKOUTR_VOL_MASK, 0x72);
  229186. +
  229187. + snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME,
  229188. + WM8962_INL_VOL_MASK, 0x3f);
  229189. + snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_VOLUME,
  229190. + WM8962_INR_VOL_MASK, 0x3f);
  229191. + snd_soc_update_bits(codec, WM8962_LEFT_ADC_VOLUME,
  229192. + WM8962_ADCL_VOL_MASK, 0xd8);
  229193. + snd_soc_update_bits(codec, WM8962_RIGHT_ADC_VOLUME,
  229194. + WM8962_ADCR_VOL_MASK, 0xd8);
  229195. + snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_MIXER_VOLUME,
  229196. + WM8962_IN3R_MIXINR_VOL_MASK, 0x7);
  229197. +
  229198. /* Latch volume update bits */
  229199. regmap_update_bits(wm8962->regmap, WM8962_LEFT_INPUT_VOLUME,
  229200. WM8962_IN_VU, WM8962_IN_VU);
  229201. @@ -3752,6 +3787,9 @@
  229202. regcache_cache_only(wm8962->regmap, true);
  229203. + /* The cache-only should be turned on before we power down the codec */
  229204. + regcache_cache_only(wm8962->regmap, true);
  229205. +
  229206. /* The drivers should power up as needed */
  229207. regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
  229208. @@ -3760,11 +3798,19 @@
  229209. err_enable:
  229210. regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
  229211. err:
  229212. + if (wm8962->pdata.codec_mclk)
  229213. + clk_unprepare(wm8962->pdata.codec_mclk);
  229214. +
  229215. return ret;
  229216. }
  229217. static int wm8962_i2c_remove(struct i2c_client *client)
  229218. {
  229219. + struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev);
  229220. +
  229221. + if (wm8962->pdata.codec_mclk)
  229222. + clk_unprepare(wm8962->pdata.codec_mclk);
  229223. +
  229224. snd_soc_unregister_codec(&client->dev);
  229225. return 0;
  229226. }
  229227. @@ -3775,6 +3821,9 @@
  229228. struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
  229229. int ret;
  229230. + if (wm8962->pdata.codec_mclk)
  229231. + clk_enable(wm8962->pdata.codec_mclk);
  229232. +
  229233. ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
  229234. wm8962->supplies);
  229235. if (ret != 0) {
  229236. @@ -3834,6 +3883,10 @@
  229237. regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
  229238. wm8962->supplies);
  229239. + if (wm8962->pdata.codec_mclk)
  229240. + clk_disable(wm8962->pdata.codec_mclk);
  229241. +
  229242. +
  229243. return 0;
  229244. }
  229245. #endif
  229246. diff -Nur linux-3.14.14/sound/soc/fsl/fsl_asrc.c linux-imx6-3.14/sound/soc/fsl/fsl_asrc.c
  229247. --- linux-3.14.14/sound/soc/fsl/fsl_asrc.c 1969-12-31 18:00:00.000000000 -0600
  229248. +++ linux-imx6-3.14/sound/soc/fsl/fsl_asrc.c 2014-12-08 00:31:56.116418001 -0600
  229249. @@ -0,0 +1,498 @@
  229250. +/*
  229251. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  229252. + *
  229253. + * The code contained herein is licensed under the GNU General Public
  229254. + * License. You may obtain a copy of the GNU General Public License
  229255. + * Version 2 or later at the following locations:
  229256. + *
  229257. + * http://www.opensource.org/licenses/gpl-license.html
  229258. + * http://www.gnu.org/copyleft/gpl.html
  229259. + */
  229260. +
  229261. +#include <linux/module.h>
  229262. +#include <linux/of.h>
  229263. +#include <linux/of_platform.h>
  229264. +#include <linux/slab.h>
  229265. +#include <linux/device.h>
  229266. +#include <linux/i2c.h>
  229267. +#include <linux/clk.h>
  229268. +#include <linux/delay.h>
  229269. +#include <linux/mxc_asrc.h>
  229270. +#include <sound/core.h>
  229271. +#include <sound/pcm.h>
  229272. +#include <sound/pcm_params.h>
  229273. +#include <sound/soc.h>
  229274. +#include <sound/initval.h>
  229275. +#include <sound/dmaengine_pcm.h>
  229276. +
  229277. +#include "fsl_asrc.h"
  229278. +#include "imx-pcm.h"
  229279. +
  229280. +static bool filter(struct dma_chan *chan, void *param)
  229281. +{
  229282. + if (!imx_dma_is_general_purpose(chan))
  229283. + return false;
  229284. +
  229285. + chan->private = param;
  229286. +
  229287. + return true;
  229288. +}
  229289. +
  229290. +static int asrc_p2p_request_channel(struct snd_pcm_substream *substream)
  229291. +{
  229292. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  229293. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  229294. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  229295. + enum dma_slave_buswidth buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
  229296. + struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
  229297. + struct snd_dmaengine_dai_dma_data *dma_params_fe = NULL;
  229298. + struct imx_dma_data *fe_filter_data = NULL;
  229299. + struct imx_dma_data *be_filter_data = NULL;
  229300. +
  229301. + struct dma_slave_config slave_config;
  229302. + dma_cap_mask_t mask;
  229303. + struct dma_chan *chan;
  229304. + int ret;
  229305. + struct snd_soc_dpcm *dpcm;
  229306. +
  229307. + /* find the be for this fe stream */
  229308. + list_for_each_entry(dpcm, &rtd->dpcm[substream->stream].be_clients, list_be) {
  229309. + if (dpcm->fe == rtd) {
  229310. + struct snd_soc_pcm_runtime *be = dpcm->be;
  229311. + struct snd_soc_dai *dai = be->cpu_dai;
  229312. + struct snd_pcm_substream *be_substream;
  229313. + be_substream = snd_soc_dpcm_get_substream(be, substream->stream);
  229314. + dma_params_be = snd_soc_dai_get_dma_data(dai, be_substream);
  229315. + break;
  229316. + }
  229317. + }
  229318. +
  229319. + if (!dma_params_be) {
  229320. + dev_err(rtd->card->dev, "can not get be substream\n");
  229321. + return -EINVAL;
  229322. + }
  229323. +
  229324. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  229325. + dma_params_fe = &asrc_p2p->dma_params_tx;
  229326. + else
  229327. + dma_params_fe = &asrc_p2p->dma_params_rx;
  229328. +
  229329. + fe_filter_data = dma_params_fe->filter_data;
  229330. + be_filter_data = dma_params_be->filter_data;
  229331. +
  229332. + if (asrc_p2p->output_width == 16)
  229333. + buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
  229334. + else
  229335. + buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
  229336. +
  229337. + /* reconfig memory to FIFO dma request */
  229338. + dma_params_fe->addr = asrc_p2p->asrc_ops.asrc_p2p_per_addr(
  229339. + asrc_p2p->asrc_index, 1);
  229340. + fe_filter_data->dma_request0 = asrc_p2p->dmarx[asrc_p2p->asrc_index];
  229341. + dma_params_fe->maxburst = dma_params_be->maxburst;
  229342. +
  229343. + dma_cap_zero(mask);
  229344. + dma_cap_set(DMA_SLAVE, mask);
  229345. + dma_cap_set(DMA_CYCLIC, mask);
  229346. +
  229347. + /* config p2p dma channel */
  229348. + asrc_p2p->asrc_p2p_dma_data.peripheral_type = IMX_DMATYPE_ASRC;
  229349. + asrc_p2p->asrc_p2p_dma_data.priority = DMA_PRIO_HIGH;
  229350. + asrc_p2p->asrc_p2p_dma_data.dma_request1 = asrc_p2p->dmatx[asrc_p2p->asrc_index];
  229351. + /* need to get target device's dma dma_addr, burstsize */
  229352. + asrc_p2p->asrc_p2p_dma_data.dma_request0 = be_filter_data->dma_request0;
  229353. +
  229354. + /* Request channel */
  229355. + asrc_p2p->asrc_p2p_dma_chan =
  229356. + dma_request_channel(mask, filter, &asrc_p2p->asrc_p2p_dma_data);
  229357. +
  229358. + if (!asrc_p2p->asrc_p2p_dma_chan) {
  229359. + dev_err(rtd->card->dev, "can not request dma channel\n");
  229360. + goto error;
  229361. + }
  229362. + chan = asrc_p2p->asrc_p2p_dma_chan;
  229363. +
  229364. + /*
  229365. + * Buswidth is not used in the sdma for p2p. Here we set the maxburst fix to
  229366. + * twice of dma_params's burstsize.
  229367. + */
  229368. + slave_config.direction = DMA_DEV_TO_DEV;
  229369. + slave_config.src_addr = asrc_p2p->asrc_ops.asrc_p2p_per_addr(asrc_p2p->asrc_index, 0);
  229370. + slave_config.src_addr_width = buswidth;
  229371. + slave_config.src_maxburst = dma_params_be->maxburst * 2;
  229372. + slave_config.dst_addr = dma_params_be->addr;
  229373. + slave_config.dst_addr_width = buswidth;
  229374. + slave_config.dst_maxburst = dma_params_be->maxburst * 2;
  229375. + slave_config.dma_request0 = be_filter_data->dma_request0;
  229376. + slave_config.dma_request1 = asrc_p2p->dmatx[asrc_p2p->asrc_index];
  229377. +
  229378. + ret = dmaengine_slave_config(asrc_p2p->asrc_p2p_dma_chan,
  229379. + &slave_config);
  229380. + if (ret) {
  229381. + dev_err(rtd->card->dev, "can not config dma channel\n");
  229382. + goto error;
  229383. + }
  229384. +
  229385. + return 0;
  229386. +error:
  229387. + if (asrc_p2p->asrc_p2p_dma_chan) {
  229388. + dma_release_channel(asrc_p2p->asrc_p2p_dma_chan);
  229389. + asrc_p2p->asrc_p2p_dma_chan = NULL;
  229390. + }
  229391. +
  229392. + return -EINVAL;
  229393. +}
  229394. +
  229395. +static int config_asrc(struct snd_pcm_substream *substream,
  229396. + struct snd_pcm_hw_params *params)
  229397. +{
  229398. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  229399. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  229400. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  229401. + unsigned int rate = params_rate(params);
  229402. + unsigned int channel = params_channels(params);
  229403. + struct asrc_config config = {0};
  229404. + int output_word_width = 0;
  229405. + int input_word_width = 0;
  229406. + int ret = 0;
  229407. + if ((channel != 2) && (channel != 4) && (channel != 6)) {
  229408. + dev_err(cpu_dai->dev, "param channel is not correct\n");
  229409. + return -EINVAL;
  229410. + }
  229411. +
  229412. + ret = asrc_p2p->asrc_ops.asrc_p2p_req_pair(channel, &asrc_p2p->asrc_index);
  229413. + if (ret < 0) {
  229414. + dev_err(cpu_dai->dev, "Fail to request asrc pair\n");
  229415. + return -EINVAL;
  229416. + }
  229417. +
  229418. + if (asrc_p2p->output_width == 16)
  229419. + output_word_width = ASRC_WIDTH_16_BIT;
  229420. + else
  229421. + output_word_width = ASRC_WIDTH_24_BIT;
  229422. +
  229423. + switch (params_format(params)) {
  229424. + case SNDRV_PCM_FORMAT_U16:
  229425. + case SNDRV_PCM_FORMAT_S16_LE:
  229426. + case SNDRV_PCM_FORMAT_S16_BE:
  229427. + input_word_width = ASRC_WIDTH_16_BIT;
  229428. + break;
  229429. + case SNDRV_PCM_FORMAT_S20_3LE:
  229430. + case SNDRV_PCM_FORMAT_S20_3BE:
  229431. + case SNDRV_PCM_FORMAT_S24_3LE:
  229432. + case SNDRV_PCM_FORMAT_S24_3BE:
  229433. + case SNDRV_PCM_FORMAT_S24_BE:
  229434. + case SNDRV_PCM_FORMAT_S24_LE:
  229435. + case SNDRV_PCM_FORMAT_U24_BE:
  229436. + case SNDRV_PCM_FORMAT_U24_LE:
  229437. + case SNDRV_PCM_FORMAT_U24_3BE:
  229438. + case SNDRV_PCM_FORMAT_U24_3LE:
  229439. + input_word_width = ASRC_WIDTH_24_BIT;
  229440. + break;
  229441. + case SNDRV_PCM_FORMAT_S8:
  229442. + case SNDRV_PCM_FORMAT_U8:
  229443. + case SNDRV_PCM_FORMAT_S32:
  229444. + case SNDRV_PCM_FORMAT_U32:
  229445. + default:
  229446. + dev_err(cpu_dai->dev, "Format is not support!\n");
  229447. + return -EINVAL;
  229448. + }
  229449. +
  229450. + config.input_word_width = input_word_width;
  229451. + config.output_word_width = output_word_width;
  229452. + config.pair = asrc_p2p->asrc_index;
  229453. + config.channel_num = channel;
  229454. + config.input_sample_rate = rate;
  229455. + config.output_sample_rate = asrc_p2p->output_rate;
  229456. + config.inclk = INCLK_NONE;
  229457. +
  229458. + switch (asrc_p2p->per_dev) {
  229459. + case SSI1:
  229460. + config.outclk = OUTCLK_SSI1_TX;
  229461. + break;
  229462. + case SSI2:
  229463. + config.outclk = OUTCLK_SSI2_TX;
  229464. + break;
  229465. + case SSI3:
  229466. + config.outclk = OUTCLK_SSI3_TX;
  229467. + break;
  229468. + case ESAI:
  229469. + config.outclk = OUTCLK_ESAI_TX;
  229470. + break;
  229471. + default:
  229472. + dev_err(cpu_dai->dev, "peripheral device is not correct\n");
  229473. + return -EINVAL;
  229474. + }
  229475. +
  229476. + ret = asrc_p2p->asrc_ops.asrc_p2p_config_pair(&config);
  229477. + if (ret < 0) {
  229478. + dev_err(cpu_dai->dev, "Fail to config asrc\n");
  229479. + return ret;
  229480. + }
  229481. +
  229482. + return 0;
  229483. +}
  229484. +
  229485. +static int fsl_asrc_p2p_hw_params(struct snd_pcm_substream *substream,
  229486. + struct snd_pcm_hw_params *params,
  229487. + struct snd_soc_dai *cpu_dai)
  229488. +{
  229489. + int ret = 0;
  229490. +
  229491. + ret = config_asrc(substream, params);
  229492. + if (ret < 0)
  229493. + return ret;
  229494. +
  229495. + return asrc_p2p_request_channel(substream);
  229496. +}
  229497. +
  229498. +static int fsl_asrc_p2p_hw_free(struct snd_pcm_substream *substream,
  229499. + struct snd_soc_dai *cpu_dai)
  229500. +{
  229501. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  229502. +
  229503. + if (asrc_p2p->asrc_p2p_dma_chan) {
  229504. + /* Release p2p dma resource */
  229505. + dma_release_channel(asrc_p2p->asrc_p2p_dma_chan);
  229506. + asrc_p2p->asrc_p2p_dma_chan = NULL;
  229507. + }
  229508. +
  229509. + if (asrc_p2p->asrc_index != -1) {
  229510. + asrc_p2p->asrc_ops.asrc_p2p_release_pair(asrc_p2p->asrc_index);
  229511. + asrc_p2p->asrc_ops.asrc_p2p_finish_conv(asrc_p2p->asrc_index);
  229512. + }
  229513. + asrc_p2p->asrc_index = -1;
  229514. +
  229515. + return 0;
  229516. +}
  229517. +
  229518. +static int fsl_asrc_dma_prepare_and_submit(struct snd_pcm_substream *substream,
  229519. + struct fsl_asrc_p2p *asrc_p2p)
  229520. +{
  229521. + struct dma_async_tx_descriptor *desc = asrc_p2p->asrc_p2p_desc;
  229522. + struct dma_chan *chan = asrc_p2p->asrc_p2p_dma_chan;
  229523. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  229524. + struct device *dev = rtd->platform->dev;
  229525. +
  229526. + desc = dmaengine_prep_dma_cyclic(chan, 0xffff, 64, 64, DMA_DEV_TO_DEV, 0);
  229527. + if (!desc) {
  229528. + dev_err(dev, "failed to prepare slave dma\n");
  229529. + return -EINVAL;
  229530. + }
  229531. +
  229532. + dmaengine_submit(desc);
  229533. +
  229534. + return 0;
  229535. +}
  229536. +
  229537. +static int fsl_asrc_p2p_trigger(struct snd_pcm_substream *substream, int cmd,
  229538. + struct snd_soc_dai *cpu_dai)
  229539. +{
  229540. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  229541. + int ret;
  229542. +
  229543. + switch (cmd) {
  229544. + case SNDRV_PCM_TRIGGER_START:
  229545. + case SNDRV_PCM_TRIGGER_RESUME:
  229546. + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  229547. + ret = fsl_asrc_dma_prepare_and_submit(substream, asrc_p2p);
  229548. + if (ret)
  229549. + return ret;
  229550. + dma_async_issue_pending(asrc_p2p->asrc_p2p_dma_chan);
  229551. + asrc_p2p->asrc_ops.asrc_p2p_start_conv(asrc_p2p->asrc_index);
  229552. + break;
  229553. + case SNDRV_PCM_TRIGGER_SUSPEND:
  229554. + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  229555. + case SNDRV_PCM_TRIGGER_STOP:
  229556. + dmaengine_terminate_all(asrc_p2p->asrc_p2p_dma_chan);
  229557. + asrc_p2p->asrc_ops.asrc_p2p_stop_conv(asrc_p2p->asrc_index);
  229558. + break;
  229559. + default:
  229560. + return -EINVAL;
  229561. + }
  229562. +
  229563. + return 0;
  229564. +}
  229565. +
  229566. +#define IMX_ASRC_RATES SNDRV_PCM_RATE_8000_192000
  229567. +
  229568. +#define IMX_ASRC_FORMATS \
  229569. + (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE | \
  229570. + SNDRV_PCM_FORMAT_S20_3LE)
  229571. +
  229572. +static struct snd_soc_dai_ops fsl_asrc_p2p_dai_ops = {
  229573. + .trigger = fsl_asrc_p2p_trigger,
  229574. + .hw_params = fsl_asrc_p2p_hw_params,
  229575. + .hw_free = fsl_asrc_p2p_hw_free,
  229576. +};
  229577. +
  229578. +static int fsl_asrc_p2p_dai_probe(struct snd_soc_dai *dai)
  229579. +{
  229580. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(dai);
  229581. +
  229582. + dai->playback_dma_data = &asrc_p2p->dma_params_tx;
  229583. + dai->capture_dma_data = &asrc_p2p->dma_params_rx;
  229584. +
  229585. + return 0;
  229586. +}
  229587. +
  229588. +static struct snd_soc_dai_driver fsl_asrc_p2p_dai = {
  229589. + .probe = fsl_asrc_p2p_dai_probe,
  229590. + .playback = {
  229591. + .stream_name = "asrc-Playback",
  229592. + .channels_min = 1,
  229593. + .channels_max = 10,
  229594. + .rates = IMX_ASRC_RATES,
  229595. + .formats = IMX_ASRC_FORMATS,
  229596. + },
  229597. + .capture = {
  229598. + .stream_name = "asrc-Capture",
  229599. + .channels_min = 1,
  229600. + .channels_max = 4,
  229601. + .rates = IMX_ASRC_RATES,
  229602. + .formats = IMX_ASRC_FORMATS,
  229603. + },
  229604. + .ops = &fsl_asrc_p2p_dai_ops,
  229605. +};
  229606. +
  229607. +static const struct snd_soc_component_driver fsl_asrc_p2p_component = {
  229608. + .name = "fsl-asrc-p2p",
  229609. +};
  229610. +
  229611. +/*
  229612. + * This function will register the snd_soc_pcm_link drivers.
  229613. + */
  229614. +static int fsl_asrc_p2p_probe(struct platform_device *pdev)
  229615. +{
  229616. + struct fsl_asrc_p2p *asrc_p2p;
  229617. + struct device_node *np = pdev->dev.of_node;
  229618. + const char *p;
  229619. + const uint32_t *iprop_rate, *iprop_width;
  229620. + int ret = 0;
  229621. +
  229622. + if (!of_device_is_available(np)) {
  229623. + dev_err(&pdev->dev, "There is no device node\n");
  229624. + return -ENODEV;
  229625. + }
  229626. +
  229627. + asrc_p2p = devm_kzalloc(&pdev->dev, sizeof(struct fsl_asrc_p2p), GFP_KERNEL);
  229628. + if (!asrc_p2p) {
  229629. + dev_err(&pdev->dev, "can not alloc memory\n");
  229630. + return -ENOMEM;
  229631. + }
  229632. + asrc_p2p->asrc_ops.asrc_p2p_start_conv = asrc_start_conv;
  229633. + asrc_p2p->asrc_ops.asrc_p2p_stop_conv = asrc_stop_conv;
  229634. + asrc_p2p->asrc_ops.asrc_p2p_per_addr = asrc_get_per_addr;
  229635. + asrc_p2p->asrc_ops.asrc_p2p_req_pair = asrc_req_pair;
  229636. + asrc_p2p->asrc_ops.asrc_p2p_config_pair = asrc_config_pair;
  229637. + asrc_p2p->asrc_ops.asrc_p2p_release_pair = asrc_release_pair;
  229638. + asrc_p2p->asrc_ops.asrc_p2p_finish_conv = asrc_finish_conv;
  229639. +
  229640. + asrc_p2p->asrc_index = -1;
  229641. +
  229642. + iprop_rate = of_get_property(np, "fsl,output-rate", NULL);
  229643. + if (iprop_rate)
  229644. + asrc_p2p->output_rate = be32_to_cpup(iprop_rate);
  229645. + else {
  229646. + dev_err(&pdev->dev, "There is no output-rate in dts\n");
  229647. + return -EINVAL;
  229648. + }
  229649. + iprop_width = of_get_property(np, "fsl,output-width", NULL);
  229650. + if (iprop_width)
  229651. + asrc_p2p->output_width = be32_to_cpup(iprop_width);
  229652. +
  229653. + if (asrc_p2p->output_width != 16 && asrc_p2p->output_width != 24) {
  229654. + dev_err(&pdev->dev, "output_width is not acceptable\n");
  229655. + return -EINVAL;
  229656. + }
  229657. +
  229658. + ret = of_property_read_u32_array(np,
  229659. + "fsl,asrc-dma-tx-events", asrc_p2p->dmatx, 3);
  229660. + if (ret) {
  229661. + dev_err(&pdev->dev, "Failed to get fsl,asrc-dma-tx-events.\n");
  229662. + return -EINVAL;
  229663. + }
  229664. +
  229665. + ret = of_property_read_u32_array(np,
  229666. + "fsl,asrc-dma-rx-events", asrc_p2p->dmarx, 3);
  229667. + if (ret) {
  229668. + dev_err(&pdev->dev, "Failed to get fsl,asrc-dma-rx-events.\n");
  229669. + return -EINVAL;
  229670. + }
  229671. +
  229672. + asrc_p2p->filter_data_tx.peripheral_type = IMX_DMATYPE_ASRC;
  229673. + asrc_p2p->filter_data_rx.peripheral_type = IMX_DMATYPE_ASRC;
  229674. +
  229675. + asrc_p2p->dma_params_tx.filter_data = &asrc_p2p->filter_data_tx;
  229676. + asrc_p2p->dma_params_rx.filter_data = &asrc_p2p->filter_data_rx;
  229677. +
  229678. + platform_set_drvdata(pdev, asrc_p2p);
  229679. +
  229680. + p = strrchr(np->full_name, '/') + 1;
  229681. + strcpy(asrc_p2p->name, p);
  229682. + fsl_asrc_p2p_dai.name = asrc_p2p->name;
  229683. +
  229684. + ret = snd_soc_register_component(&pdev->dev, &fsl_asrc_p2p_component,
  229685. + &fsl_asrc_p2p_dai, 1);
  229686. + if (ret) {
  229687. + dev_err(&pdev->dev, "register DAI failed\n");
  229688. + goto failed_register;
  229689. + }
  229690. +
  229691. + asrc_p2p->soc_platform_pdev = platform_device_register_simple(
  229692. + "imx-pcm-asrc", -1, NULL, 0);
  229693. + if (IS_ERR(asrc_p2p->soc_platform_pdev)) {
  229694. + ret = PTR_ERR(asrc_p2p->soc_platform_pdev);
  229695. + goto failed_pdev_alloc;
  229696. + }
  229697. +
  229698. + ret = imx_pcm_dma_init(asrc_p2p->soc_platform_pdev, SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
  229699. + SND_DMAENGINE_PCM_FLAG_NO_DT |
  229700. + SND_DMAENGINE_PCM_FLAG_COMPAT,
  229701. + IMX_ASRC_DMABUF_SIZE);
  229702. + if (ret) {
  229703. + dev_err(&pdev->dev, "init pcm dma failed\n");
  229704. + goto failed_pcm_init;
  229705. + }
  229706. +
  229707. + return 0;
  229708. +
  229709. +failed_pcm_init:
  229710. + platform_device_unregister(asrc_p2p->soc_platform_pdev);
  229711. +failed_pdev_alloc:
  229712. + snd_soc_unregister_component(&pdev->dev);
  229713. +failed_register:
  229714. +
  229715. + return ret;
  229716. +}
  229717. +
  229718. +static int fsl_asrc_p2p_remove(struct platform_device *pdev)
  229719. +{
  229720. + struct fsl_asrc_p2p *asrc_p2p = platform_get_drvdata(pdev);
  229721. +
  229722. + platform_device_unregister(asrc_p2p->soc_platform_pdev);
  229723. + snd_soc_unregister_component(&pdev->dev);
  229724. +
  229725. + return 0;
  229726. +}
  229727. +
  229728. +static const struct of_device_id fsl_asrc_p2p_dt_ids[] = {
  229729. + { .compatible = "fsl,imx6q-asrc-p2p", },
  229730. + { /* sentinel */ }
  229731. +};
  229732. +
  229733. +static struct platform_driver fsl_asrc_p2p_driver = {
  229734. + .probe = fsl_asrc_p2p_probe,
  229735. + .remove = fsl_asrc_p2p_remove,
  229736. + .driver = {
  229737. + .name = "fsl-asrc-p2p",
  229738. + .owner = THIS_MODULE,
  229739. + .of_match_table = fsl_asrc_p2p_dt_ids,
  229740. + },
  229741. +};
  229742. +module_platform_driver(fsl_asrc_p2p_driver);
  229743. +
  229744. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  229745. +MODULE_DESCRIPTION("i.MX ASoC ASRC P2P driver");
  229746. +MODULE_ALIAS("platform:fsl-asrc-p2p");
  229747. +MODULE_LICENSE("GPL");
  229748. diff -Nur linux-3.14.14/sound/soc/fsl/fsl_asrc.h linux-imx6-3.14/sound/soc/fsl/fsl_asrc.h
  229749. --- linux-3.14.14/sound/soc/fsl/fsl_asrc.h 1969-12-31 18:00:00.000000000 -0600
  229750. +++ linux-imx6-3.14/sound/soc/fsl/fsl_asrc.h 2014-12-08 00:31:56.116418001 -0600
  229751. @@ -0,0 +1,48 @@
  229752. +/*
  229753. + * fsl_asrc.h - ALSA ASRC interface
  229754. + *
  229755. + * Copyright (C) 2013 Freescale Semiconductor, Inc. This file is licensed
  229756. + * under the terms of the GNU General Public License version 2. This
  229757. + * program is licensed "as is" without any warranty of any kind, whether
  229758. + * express or implied.
  229759. + */
  229760. +
  229761. +#ifndef _FSL_ASRC_P2P_H
  229762. +#define _FSL_ASRC_P2P_H
  229763. +
  229764. +#include <linux/mxc_asrc.h>
  229765. +#include <sound/dmaengine_pcm.h>
  229766. +#include <linux/platform_data/dma-imx.h>
  229767. +
  229768. +enum peripheral_device_type {
  229769. + UNKNOWN,
  229770. + SSI1,
  229771. + SSI2,
  229772. + SSI3,
  229773. + ESAI,
  229774. +};
  229775. +
  229776. +struct fsl_asrc_p2p {
  229777. + int output_rate;
  229778. + int output_width;
  229779. + enum asrc_pair_index asrc_index;
  229780. + enum peripheral_device_type per_dev;
  229781. + struct asrc_p2p_ops asrc_ops;
  229782. +
  229783. + struct snd_dmaengine_dai_dma_data dma_params_rx;
  229784. + struct snd_dmaengine_dai_dma_data dma_params_tx;
  229785. + struct imx_dma_data filter_data_tx;
  229786. + struct imx_dma_data filter_data_rx;
  229787. +
  229788. + struct dma_async_tx_descriptor *asrc_p2p_desc;
  229789. + struct dma_chan *asrc_p2p_dma_chan;
  229790. + struct imx_dma_data asrc_p2p_dma_data;
  229791. + struct platform_device *soc_platform_pdev;
  229792. +
  229793. + int dmarx[3];
  229794. + int dmatx[3];
  229795. +
  229796. + char name[32];
  229797. +};
  229798. +
  229799. +#endif
  229800. diff -Nur linux-3.14.14/sound/soc/fsl/fsl_asrc_pcm.c linux-imx6-3.14/sound/soc/fsl/fsl_asrc_pcm.c
  229801. --- linux-3.14.14/sound/soc/fsl/fsl_asrc_pcm.c 1969-12-31 18:00:00.000000000 -0600
  229802. +++ linux-imx6-3.14/sound/soc/fsl/fsl_asrc_pcm.c 2014-12-08 00:31:56.116418001 -0600
  229803. @@ -0,0 +1,41 @@
  229804. +/*
  229805. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  229806. + *
  229807. + * The code contained herein is licensed under the GNU General Public
  229808. + * License. You may obtain a copy of the GNU General Public License
  229809. + * Version 2 or later at the following locations:
  229810. + *
  229811. + * http://www.opensource.org/licenses/gpl-license.html
  229812. + * http://www.gnu.org/copyleft/gpl.html
  229813. + */
  229814. +
  229815. +#include <linux/module.h>
  229816. +#include <linux/platform_device.h>
  229817. +
  229818. +
  229819. +/*
  229820. + * Here add one platform module "imx-pcm-asrc" as pcm platform module.
  229821. + * If we use the asrc_p2p node as the pcm platform, there will be one issue.
  229822. + * snd_soc_dapm_new_dai_widgets will be called twice, one in probe link_dais,
  229823. + * one in probe platform. so there will be two dai_widgets added to widget list.
  229824. + * but only the seconed one will be recorded in dai->playback_widget.
  229825. + * Machine driver will add the audio route, but when it go through the
  229826. + * widget list, it will found the cpu_dai widget is the first one in the list.
  229827. + * add use the first one to link the audio route.
  229828. + * when use the fe/be architecture for asrc p2p, it need to go through from
  229829. + * the fe->cpu_dai->playback_widget. but this is the second widget, so the
  229830. + * result is that it can't find a availble audio route for p2p case. So here
  229831. + * use another pcm platform to avoid this issue.
  229832. + */
  229833. +static struct platform_driver imx_pcm_driver = {
  229834. + .driver = {
  229835. + .name = "imx-pcm-asrc",
  229836. + .owner = THIS_MODULE,
  229837. + },
  229838. +};
  229839. +
  229840. +module_platform_driver(imx_pcm_driver);
  229841. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  229842. +MODULE_DESCRIPTION("i.MX ASoC PCM driver");
  229843. +MODULE_ALIAS("platform:imx-pcm-asrc");
  229844. +MODULE_LICENSE("GPL");
  229845. diff -Nur linux-3.14.14/sound/soc/fsl/fsl_esai.c linux-imx6-3.14/sound/soc/fsl/fsl_esai.c
  229846. --- linux-3.14.14/sound/soc/fsl/fsl_esai.c 2014-07-28 10:07:25.000000000 -0500
  229847. +++ linux-imx6-3.14/sound/soc/fsl/fsl_esai.c 2014-12-08 00:31:56.116418001 -0600
  229848. @@ -785,7 +785,7 @@
  229849. return ret;
  229850. }
  229851. - ret = imx_pcm_dma_init(pdev);
  229852. + ret = imx_pcm_dma_init(pdev, NULL, IMX_ESAI_DMABUF_SIZE);
  229853. if (ret)
  229854. dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
  229855. diff -Nur linux-3.14.14/sound/soc/fsl/fsl_hdmi.c linux-imx6-3.14/sound/soc/fsl/fsl_hdmi.c
  229856. --- linux-3.14.14/sound/soc/fsl/fsl_hdmi.c 1969-12-31 18:00:00.000000000 -0600
  229857. +++ linux-imx6-3.14/sound/soc/fsl/fsl_hdmi.c 2014-12-08 00:31:56.116418001 -0600
  229858. @@ -0,0 +1,614 @@
  229859. +/*
  229860. + * ALSA SoC HDMI Audio Layer for Freescale i.MX
  229861. + *
  229862. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  229863. + *
  229864. + * Some code from patch_hdmi.c
  229865. + * Copyright (c) 2008-2010 Intel Corporation. All rights reserved.
  229866. + * Copyright (c) 2006 ATI Technologies Inc.
  229867. + * Copyright (c) 2008 NVIDIA Corp. All rights reserved.
  229868. + * Copyright (c) 2008 Wei Ni <wni@nvidia.com>
  229869. + *
  229870. + * This program is free software; you can redistribute it and/or modify
  229871. + * it under the terms of the GNU General Public License as published by
  229872. + * the Free Software Foundation; either version 2 of the License, or
  229873. + * (at your option) any later version.
  229874. + *
  229875. + * This program is distributed in the hope that it will be useful,
  229876. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  229877. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  229878. + * GNU General Public License for more details.
  229879. + *
  229880. + * You should have received a copy of the GNU General Public License along
  229881. + * with this program; if not, write to the Free Software Foundation, Inc.,
  229882. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  229883. + */
  229884. +
  229885. +#include <linux/init.h>
  229886. +#include <linux/module.h>
  229887. +#include <linux/dma-mapping.h>
  229888. +#include <linux/slab.h>
  229889. +#include <linux/clk.h>
  229890. +#include <linux/delay.h>
  229891. +#include <linux/mfd/mxc-hdmi-core.h>
  229892. +#include <sound/pcm.h>
  229893. +#include <sound/soc.h>
  229894. +#include <sound/asoundef.h>
  229895. +
  229896. +#include <video/mxc_hdmi.h>
  229897. +
  229898. +#include "imx-hdmi.h"
  229899. +
  229900. +
  229901. +static struct mxc_edid_cfg edid_cfg;
  229902. +
  229903. +static u32 playback_rates[HDMI_MAX_RATES];
  229904. +static u32 playback_sample_size[HDMI_MAX_SAMPLE_SIZE];
  229905. +static u32 playback_channels[HDMI_MAX_CHANNEL_CONSTRAINTS];
  229906. +
  229907. +static struct snd_pcm_hw_constraint_list playback_constraint_rates;
  229908. +static struct snd_pcm_hw_constraint_list playback_constraint_bits;
  229909. +static struct snd_pcm_hw_constraint_list playback_constraint_channels;
  229910. +
  229911. +#ifdef DEBUG
  229912. +static void dumpregs(struct snd_soc_dai *dai)
  229913. +{
  229914. + u32 n, cts;
  229915. +
  229916. + cts = (hdmi_readb(HDMI_AUD_CTS3) << 16) |
  229917. + (hdmi_readb(HDMI_AUD_CTS2) << 8) |
  229918. + hdmi_readb(HDMI_AUD_CTS1);
  229919. +
  229920. + n = (hdmi_readb(HDMI_AUD_N3) << 16) |
  229921. + (hdmi_readb(HDMI_AUD_N2) << 8) |
  229922. + hdmi_readb(HDMI_AUD_N1);
  229923. +
  229924. + dev_dbg(dai->dev, "HDMI_PHY_CONF0 0x%02x\n",
  229925. + hdmi_readb(HDMI_PHY_CONF0));
  229926. + dev_dbg(dai->dev, "HDMI_MC_CLKDIS 0x%02x\n",
  229927. + hdmi_readb(HDMI_MC_CLKDIS));
  229928. + dev_dbg(dai->dev, "HDMI_AUD_N[1-3] 0x%06x (%d)\n",
  229929. + n, n);
  229930. + dev_dbg(dai->dev, "HDMI_AUD_CTS[1-3] 0x%06x (%d)\n",
  229931. + cts, cts);
  229932. + dev_dbg(dai->dev, "HDMI_FC_AUDSCONF 0x%02x\n",
  229933. + hdmi_readb(HDMI_FC_AUDSCONF));
  229934. +}
  229935. +#else
  229936. +static void dumpregs(struct snd_soc_dai *dai) {}
  229937. +#endif
  229938. +
  229939. +enum cea_speaker_placement {
  229940. + FL = (1 << 0), /* Front Left */
  229941. + FC = (1 << 1), /* Front Center */
  229942. + FR = (1 << 2), /* Front Right */
  229943. + FLC = (1 << 3), /* Front Left Center */
  229944. + FRC = (1 << 4), /* Front Right Center */
  229945. + RL = (1 << 5), /* Rear Left */
  229946. + RC = (1 << 6), /* Rear Center */
  229947. + RR = (1 << 7), /* Rear Right */
  229948. + RLC = (1 << 8), /* Rear Left Center */
  229949. + RRC = (1 << 9), /* Rear Right Center */
  229950. + LFE = (1 << 10), /* Low Frequency Effect */
  229951. + FLW = (1 << 11), /* Front Left Wide */
  229952. + FRW = (1 << 12), /* Front Right Wide */
  229953. + FLH = (1 << 13), /* Front Left High */
  229954. + FCH = (1 << 14), /* Front Center High */
  229955. + FRH = (1 << 15), /* Front Right High */
  229956. + TC = (1 << 16), /* Top Center */
  229957. +};
  229958. +
  229959. +/*
  229960. + * EDID SA bits in the CEA Speaker Allocation data block
  229961. + */
  229962. +static int edid_speaker_allocation_bits[] = {
  229963. + [0] = FL | FR,
  229964. + [1] = LFE,
  229965. + [2] = FC,
  229966. + [3] = RL | RR,
  229967. + [4] = RC,
  229968. + [5] = FLC | FRC,
  229969. + [6] = RLC | RRC,
  229970. + [7] = FLW | FRW,
  229971. + [8] = FLH | FRH,
  229972. + [9] = TC,
  229973. + [10] = FCH,
  229974. +};
  229975. +
  229976. +struct cea_channel_speaker_allocation {
  229977. + int ca_index;
  229978. + int speakers[8];
  229979. +
  229980. + /* Derived values, just for convenience */
  229981. + int channels;
  229982. + int spk_mask;
  229983. +};
  229984. +
  229985. +/*
  229986. + * This is an ordered list!
  229987. + *
  229988. + * The preceding ones have better chances to be selected by
  229989. + * hdmi_channel_allocation().
  229990. + */
  229991. +static struct cea_channel_speaker_allocation channel_allocations[] = {
  229992. + /* channel: 7 6 5 4 3 2 1 0 */
  229993. + { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL },},
  229994. + /* 2.1 */
  229995. + { .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL },},
  229996. + /* Dolby Surround */
  229997. + { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL },}, /* Prefer FL/FR/RL/RR over FL/FR/LFE/FC */
  229998. + { .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL },},
  229999. + { .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL },},
  230000. + { .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL },},
  230001. + { .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL },},
  230002. + { .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL },},
  230003. + { .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL },},
  230004. + { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL },},
  230005. + { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL },},
  230006. + /* surround51 */
  230007. + { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL },},
  230008. + { .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL },},
  230009. + { .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL },},
  230010. + { .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL },},
  230011. + /* 6.1 */
  230012. + { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL },},
  230013. + { .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL },},
  230014. + { .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL },},
  230015. + { .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL },},
  230016. + /* surround71 */
  230017. + { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL },},
  230018. + { .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL },},
  230019. + { .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL },},
  230020. + { .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL },},
  230021. + { .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL },},
  230022. + { .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL },},
  230023. + { .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL },},
  230024. + { .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL },},
  230025. + { .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL },},
  230026. + { .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL },},
  230027. + { .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL },},
  230028. + { .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL },},
  230029. + { .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL },},
  230030. + { .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL },},
  230031. + { .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL },},
  230032. + { .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL },},
  230033. + { .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL },},
  230034. + { .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL },},
  230035. + { .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL },},
  230036. + { .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL },},
  230037. + { .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL },},
  230038. + { .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL },},
  230039. + { .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL },},
  230040. + { .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL },},
  230041. + { .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL },},
  230042. + { .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL },},
  230043. + { .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL },},
  230044. + { .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL },},
  230045. + { .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL },},
  230046. + { .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL },},
  230047. + { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL },},
  230048. +};
  230049. +
  230050. +/* Compute derived values in channel_allocations[] */
  230051. +static void init_channel_allocations(void)
  230052. +{
  230053. + struct cea_channel_speaker_allocation *p;
  230054. + int i, j;
  230055. +
  230056. + for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  230057. + p = channel_allocations + i;
  230058. + p->channels = 0;
  230059. + p->spk_mask = 0;
  230060. + for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
  230061. + if (p->speakers[j]) {
  230062. + p->channels++;
  230063. + p->spk_mask |= p->speakers[j];
  230064. + }
  230065. + }
  230066. +}
  230067. +
  230068. +/*
  230069. + * The transformation takes two steps:
  230070. + *
  230071. + * speaker_alloc => (edid_speaker_allocation_bits[]) => spk_mask
  230072. + * spk_mask => (channel_allocations[]) => CA
  230073. + *
  230074. + * TODO: it could select the wrong CA from multiple candidates.
  230075. +*/
  230076. +static int hdmi_channel_allocation(int channels)
  230077. +{
  230078. + int spk_mask = 0, ca = 0, i, tmpchn, tmpspk;
  230079. +
  230080. + /* CA defaults to 0 for basic stereo audio */
  230081. + if (channels <= 2)
  230082. + return 0;
  230083. +
  230084. + /*
  230085. + * Expand EDID's speaker allocation mask
  230086. + *
  230087. + * EDID tells the speaker mask in a compact(paired) form,
  230088. + * expand EDID's notions to match the ones used by Audio InfoFrame.
  230089. + */
  230090. + for (i = 0; i < ARRAY_SIZE(edid_speaker_allocation_bits); i++) {
  230091. + if (edid_cfg.speaker_alloc & (1 << i))
  230092. + spk_mask |= edid_speaker_allocation_bits[i];
  230093. + }
  230094. +
  230095. + /* Search for the first working match in the CA table */
  230096. + for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  230097. + tmpchn = channel_allocations[i].channels;
  230098. + tmpspk = channel_allocations[i].spk_mask;
  230099. +
  230100. + if (channels == tmpchn && (spk_mask & tmpspk) == tmpspk) {
  230101. + ca = channel_allocations[i].ca_index;
  230102. + break;
  230103. + }
  230104. + }
  230105. +
  230106. + return ca;
  230107. +}
  230108. +
  230109. +static void hdmi_set_audio_infoframe(unsigned int channels)
  230110. +{
  230111. + u8 audiconf0, audiconf2;
  230112. +
  230113. + /*
  230114. + * From CEA-861-D spec:
  230115. + * HDMI requires the CT, SS and SF fields to be set to 0 ("Refer
  230116. + * to Stream Header") as these items are carried in the audio stream.
  230117. + *
  230118. + * So we only set the CC and CA fields.
  230119. + */
  230120. + audiconf0 = ((channels - 1) << HDMI_FC_AUDICONF0_CC_OFFSET) &
  230121. + HDMI_FC_AUDICONF0_CC_MASK;
  230122. +
  230123. + audiconf2 = hdmi_channel_allocation(channels);
  230124. +
  230125. + hdmi_writeb(audiconf0, HDMI_FC_AUDICONF0);
  230126. + hdmi_writeb(0, HDMI_FC_AUDICONF1);
  230127. + hdmi_writeb(audiconf2, HDMI_FC_AUDICONF2);
  230128. + hdmi_writeb(0, HDMI_FC_AUDICONF3);
  230129. +}
  230130. +
  230131. +static int cea_audio_rates[HDMI_MAX_RATES] = {
  230132. + 32000, 44100, 48000, 88200, 96000, 176400, 192000,
  230133. +};
  230134. +
  230135. +static void fsl_hdmi_get_playback_rates(void)
  230136. +{
  230137. + int i, count = 0;
  230138. + u8 rates;
  230139. +
  230140. + /* Always assume basic audio support */
  230141. + rates = edid_cfg.sample_rates | 0x7;
  230142. +
  230143. + for (i = 0 ; i < HDMI_MAX_RATES ; i++)
  230144. + if ((rates & (1 << i)) != 0)
  230145. + playback_rates[count++] = cea_audio_rates[i];
  230146. +
  230147. + playback_constraint_rates.list = playback_rates;
  230148. + playback_constraint_rates.count = count;
  230149. +
  230150. + for (i = 0 ; i < playback_constraint_rates.count ; i++)
  230151. + pr_debug("%s: constraint = %d Hz\n", __func__, playback_rates[i]);
  230152. +}
  230153. +
  230154. +static void fsl_hdmi_get_playback_sample_size(void)
  230155. +{
  230156. + int i = 0;
  230157. +
  230158. + /* Always assume basic audio support */
  230159. + playback_sample_size[i++] = 16;
  230160. +
  230161. + if (edid_cfg.sample_sizes & 0x4)
  230162. + playback_sample_size[i++] = 32;
  230163. +
  230164. + playback_constraint_bits.list = playback_sample_size;
  230165. + playback_constraint_bits.count = i;
  230166. +
  230167. + for (i = 0 ; i < playback_constraint_bits.count ; i++)
  230168. + pr_debug("%s: constraint = %d bits\n", __func__, playback_sample_size[i]);
  230169. +}
  230170. +
  230171. +static void fsl_hdmi_get_playback_channels(void)
  230172. +{
  230173. + int channels = 2, i = 0;
  230174. +
  230175. + /* Always assume basic audio support */
  230176. + playback_channels[i++] = channels;
  230177. + channels += 2;
  230178. +
  230179. + while ((i < HDMI_MAX_CHANNEL_CONSTRAINTS) &&
  230180. + (channels <= edid_cfg.max_channels)) {
  230181. + playback_channels[i++] = channels;
  230182. + channels += 2;
  230183. + }
  230184. +
  230185. + playback_constraint_channels.list = playback_channels;
  230186. + playback_constraint_channels.count = i;
  230187. +
  230188. + for (i = 0 ; i < playback_constraint_channels.count ; i++)
  230189. + pr_debug("%s: constraint = %d channels\n", __func__, playback_channels[i]);
  230190. +}
  230191. +
  230192. +static int fsl_hdmi_update_constraints(struct snd_pcm_substream *substream)
  230193. +{
  230194. + struct snd_pcm_runtime *runtime = substream->runtime;
  230195. + int edid_status, ret;
  230196. +
  230197. + edid_status = hdmi_get_edid_cfg(&edid_cfg);
  230198. +
  230199. + if (edid_status && !edid_cfg.hdmi_cap)
  230200. + return -1;
  230201. +
  230202. + fsl_hdmi_get_playback_rates();
  230203. + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  230204. + &playback_constraint_rates);
  230205. + if (ret)
  230206. + return ret;
  230207. +
  230208. + fsl_hdmi_get_playback_sample_size();
  230209. + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
  230210. + &playback_constraint_bits);
  230211. + if (ret)
  230212. + return ret;
  230213. +
  230214. + fsl_hdmi_get_playback_channels();
  230215. + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
  230216. + &playback_constraint_channels);
  230217. + if (ret)
  230218. + return ret;
  230219. +
  230220. + ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
  230221. + if (ret)
  230222. + return ret;
  230223. +
  230224. + return 0;
  230225. +}
  230226. +
  230227. +static int fsl_hdmi_soc_startup(struct snd_pcm_substream *substream,
  230228. + struct snd_soc_dai *dai)
  230229. +{
  230230. + struct imx_hdmi *hdmi_data = snd_soc_dai_get_drvdata(dai);
  230231. + int ret;
  230232. +
  230233. + ret = fsl_hdmi_update_constraints(substream);
  230234. + if (ret < 0)
  230235. + return ret;
  230236. +
  230237. + clk_prepare_enable(hdmi_data->isfr_clk);
  230238. + clk_prepare_enable(hdmi_data->iahb_clk);
  230239. +
  230240. + dev_dbg(dai->dev, "%s hdmi clks: isfr:%d iahb:%d\n", __func__,
  230241. + (int)clk_get_rate(hdmi_data->isfr_clk),
  230242. + (int)clk_get_rate(hdmi_data->iahb_clk));
  230243. +
  230244. + /* Indicates the subpacket represents a flatline sample */
  230245. + hdmi_audio_writeb(FC_AUDSCONF, AUD_PACKET_SAMPFIT, 0x0);
  230246. +
  230247. + return 0;
  230248. +}
  230249. +
  230250. +static void fsl_hdmi_soc_shutdown(struct snd_pcm_substream *substream,
  230251. + struct snd_soc_dai *dai)
  230252. +{
  230253. + struct imx_hdmi *hdmi_data = snd_soc_dai_get_drvdata(dai);
  230254. +
  230255. + clk_disable_unprepare(hdmi_data->iahb_clk);
  230256. + clk_disable_unprepare(hdmi_data->isfr_clk);
  230257. +}
  230258. +
  230259. +static int fsl_hdmi_soc_prepare(struct snd_pcm_substream *substream,
  230260. + struct snd_soc_dai *dai)
  230261. +{
  230262. + struct snd_pcm_runtime *runtime = substream->runtime;
  230263. +
  230264. + hdmi_set_audio_infoframe(runtime->channels);
  230265. + hdmi_audio_writeb(FC_AUDSCONF, AUD_PACKET_LAYOUT,
  230266. + (runtime->channels > 2) ? 0x1 : 0x0);
  230267. + hdmi_set_sample_rate(runtime->rate);
  230268. + dumpregs(dai);
  230269. +
  230270. + return 0;
  230271. +}
  230272. +
  230273. +static struct snd_soc_dai_ops fsl_hdmi_soc_dai_ops = {
  230274. + .startup = fsl_hdmi_soc_startup,
  230275. + .shutdown = fsl_hdmi_soc_shutdown,
  230276. + .prepare = fsl_hdmi_soc_prepare,
  230277. +};
  230278. +
  230279. +/* IEC60958 status functions */
  230280. +static int fsl_hdmi_iec_info(struct snd_kcontrol *kcontrol,
  230281. + struct snd_ctl_elem_info *uinfo)
  230282. +{
  230283. + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
  230284. + uinfo->count = 1;
  230285. +
  230286. + return 0;
  230287. +}
  230288. +
  230289. +
  230290. +static int fsl_hdmi_iec_get(struct snd_kcontrol *kcontrol,
  230291. + struct snd_ctl_elem_value *uvalue)
  230292. +{
  230293. + int i;
  230294. +
  230295. + for (i = 0 ; i < 6 ; i++)
  230296. + uvalue->value.iec958.status[i] = iec_header.status[i];
  230297. +
  230298. + return 0;
  230299. +}
  230300. +
  230301. +static int fsl_hdmi_iec_put(struct snd_kcontrol *kcontrol,
  230302. + struct snd_ctl_elem_value *uvalue)
  230303. +{
  230304. + int i;
  230305. +
  230306. + /* Do not allow professional mode */
  230307. + if (uvalue->value.iec958.status[0] & IEC958_AES0_PROFESSIONAL)
  230308. + return -EPERM;
  230309. +
  230310. + for (i = 0 ; i < 6 ; i++) {
  230311. + iec_header.status[i] = uvalue->value.iec958.status[i];
  230312. + pr_debug("%s status[%d]=0x%02x\n", __func__, i, iec_header.status[i]);
  230313. + }
  230314. +
  230315. + return 0;
  230316. +}
  230317. +
  230318. +static struct snd_kcontrol_new fsl_hdmi_ctrls[] = {
  230319. + /* Status cchanel controller */
  230320. + {
  230321. + .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  230322. + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
  230323. + .access = SNDRV_CTL_ELEM_ACCESS_READ |
  230324. + SNDRV_CTL_ELEM_ACCESS_WRITE |
  230325. + SNDRV_CTL_ELEM_ACCESS_VOLATILE,
  230326. + .info = fsl_hdmi_iec_info,
  230327. + .get = fsl_hdmi_iec_get,
  230328. + .put = fsl_hdmi_iec_put,
  230329. + },
  230330. +};
  230331. +
  230332. +static int fsl_hdmi_soc_dai_probe(struct snd_soc_dai *dai)
  230333. +{
  230334. + int ret;
  230335. +
  230336. + init_channel_allocations();
  230337. +
  230338. + ret = snd_soc_add_dai_controls(dai, fsl_hdmi_ctrls,
  230339. + ARRAY_SIZE(fsl_hdmi_ctrls));
  230340. + if (ret)
  230341. + dev_warn(dai->dev, "failed to add dai controls\n");
  230342. +
  230343. + return 0;
  230344. +}
  230345. +
  230346. +static struct snd_soc_dai_driver fsl_hdmi_dai = {
  230347. + .probe = &fsl_hdmi_soc_dai_probe,
  230348. + .playback = {
  230349. + .channels_min = 2,
  230350. + .channels_max = 8,
  230351. + .rates = MXC_HDMI_RATES_PLAYBACK,
  230352. + .formats = MXC_HDMI_FORMATS_PLAYBACK,
  230353. + },
  230354. + .ops = &fsl_hdmi_soc_dai_ops,
  230355. +};
  230356. +
  230357. +static const struct snd_soc_component_driver fsl_hdmi_component = {
  230358. + .name = "fsl-hdmi",
  230359. +};
  230360. +
  230361. +static int fsl_hdmi_dai_probe(struct platform_device *pdev)
  230362. +{
  230363. + struct device_node *np = pdev->dev.of_node;
  230364. + struct imx_hdmi *hdmi_data;
  230365. + int ret = 0;
  230366. +
  230367. + if (!np)
  230368. + return -ENODEV;
  230369. +
  230370. + if (!hdmi_get_registered()) {
  230371. + dev_err(&pdev->dev, "failed to probe. Load HDMI-video first.\n");
  230372. + return -ENOMEM;
  230373. + }
  230374. +
  230375. + hdmi_data = devm_kzalloc(&pdev->dev, sizeof(*hdmi_data), GFP_KERNEL);
  230376. + if (!hdmi_data) {
  230377. + dev_err(&pdev->dev, "failed to alloc hdmi_data\n");
  230378. + return -ENOMEM;
  230379. + }
  230380. +
  230381. + hdmi_data->pdev = pdev;
  230382. +
  230383. + memcpy(&hdmi_data->cpu_dai_drv, &fsl_hdmi_dai, sizeof(fsl_hdmi_dai));
  230384. + hdmi_data->cpu_dai_drv.name = np->name;
  230385. +
  230386. + hdmi_data->isfr_clk = devm_clk_get(&pdev->dev, "hdmi_isfr");
  230387. + if (IS_ERR(hdmi_data->isfr_clk)) {
  230388. + ret = PTR_ERR(hdmi_data->isfr_clk);
  230389. + dev_err(&pdev->dev, "failed to get HDMI isfr clk: %d\n", ret);
  230390. + return -EINVAL;
  230391. + }
  230392. +
  230393. + hdmi_data->iahb_clk = devm_clk_get(&pdev->dev, "hdmi_iahb");
  230394. + if (IS_ERR(hdmi_data->iahb_clk)) {
  230395. + ret = PTR_ERR(hdmi_data->iahb_clk);
  230396. + dev_err(&pdev->dev, "failed to get HDMI ahb clk: %d\n", ret);
  230397. + return -EINVAL;
  230398. + }
  230399. +
  230400. + dev_set_drvdata(&pdev->dev, hdmi_data);
  230401. + ret = snd_soc_register_component(&pdev->dev, &fsl_hdmi_component,
  230402. + &hdmi_data->cpu_dai_drv, 1);
  230403. + if (ret) {
  230404. + dev_err(&pdev->dev, "register DAI failed\n");
  230405. + return ret;
  230406. + }
  230407. +
  230408. + hdmi_data->codec_dev = platform_device_register_simple(
  230409. + "hdmi-audio-codec", -1, NULL, 0);
  230410. + if (IS_ERR(hdmi_data->codec_dev)) {
  230411. + dev_err(&pdev->dev, "failed to register HDMI audio codec\n");
  230412. + ret = PTR_ERR(hdmi_data->codec_dev);
  230413. + goto fail;
  230414. + }
  230415. +
  230416. + hdmi_data->dma_dev = platform_device_alloc("imx-hdmi-audio", -1);
  230417. + if (IS_ERR(hdmi_data->dma_dev)) {
  230418. + ret = PTR_ERR(hdmi_data->dma_dev);
  230419. + goto fail_dma;
  230420. + }
  230421. +
  230422. + platform_set_drvdata(hdmi_data->dma_dev, hdmi_data);
  230423. +
  230424. + ret = platform_device_add(hdmi_data->dma_dev);
  230425. + if (ret) {
  230426. + platform_device_put(hdmi_data->dma_dev);
  230427. + goto fail_dma;
  230428. + }
  230429. +
  230430. + return 0;
  230431. +
  230432. +fail_dma:
  230433. + platform_device_unregister(hdmi_data->codec_dev);
  230434. +fail:
  230435. + snd_soc_unregister_component(&pdev->dev);
  230436. +
  230437. + return ret;
  230438. +}
  230439. +
  230440. +static int fsl_hdmi_dai_remove(struct platform_device *pdev)
  230441. +{
  230442. + struct imx_hdmi *hdmi_data = platform_get_drvdata(pdev);
  230443. +
  230444. + platform_device_unregister(hdmi_data->dma_dev);
  230445. + platform_device_unregister(hdmi_data->codec_dev);
  230446. + snd_soc_unregister_component(&pdev->dev);
  230447. +
  230448. + return 0;
  230449. +}
  230450. +
  230451. +static const struct of_device_id fsl_hdmi_dai_dt_ids[] = {
  230452. + { .compatible = "fsl,imx6dl-hdmi-audio", },
  230453. + { .compatible = "fsl,imx6q-hdmi-audio", },
  230454. + { /* sentinel */ }
  230455. +};
  230456. +MODULE_DEVICE_TABLE(of, fsl_hdmi_dai_dt_ids);
  230457. +
  230458. +static struct platform_driver fsl_hdmi_driver = {
  230459. + .probe = fsl_hdmi_dai_probe,
  230460. + .remove = fsl_hdmi_dai_remove,
  230461. + .driver = {
  230462. + .name = "fsl-hdmi-dai",
  230463. + .owner = THIS_MODULE,
  230464. + .of_match_table = fsl_hdmi_dai_dt_ids,
  230465. + },
  230466. +};
  230467. +module_platform_driver(fsl_hdmi_driver);
  230468. +
  230469. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  230470. +MODULE_DESCRIPTION("IMX HDMI TX DAI");
  230471. +MODULE_LICENSE("GPL");
  230472. +MODULE_ALIAS("platform:fsl-hdmi-dai");
  230473. diff -Nur linux-3.14.14/sound/soc/fsl/fsl_spdif.c linux-imx6-3.14/sound/soc/fsl/fsl_spdif.c
  230474. --- linux-3.14.14/sound/soc/fsl/fsl_spdif.c 2014-07-28 10:07:25.000000000 -0500
  230475. +++ linux-imx6-3.14/sound/soc/fsl/fsl_spdif.c 2014-12-08 00:31:56.116418001 -0600
  230476. @@ -21,6 +21,8 @@
  230477. #include <linux/of_address.h>
  230478. #include <linux/of_device.h>
  230479. #include <linux/of_irq.h>
  230480. +#include <linux/pm_runtime.h>
  230481. +#include <linux/busfreq-imx6.h>
  230482. #include <sound/asoundef.h>
  230483. #include <sound/soc.h>
  230484. @@ -53,7 +55,7 @@
  230485. spinlock_t ctl_lock;
  230486. /* IEC958 channel tx status bit */
  230487. - unsigned char ch_status[4];
  230488. + unsigned char ch_status[6];
  230489. /* User bits */
  230490. unsigned char subcode[2 * SPDIF_UBITS_SIZE];
  230491. @@ -80,6 +82,7 @@
  230492. u8 rxclk_src;
  230493. struct clk *txclk[SPDIF_TXRATE_MAX];
  230494. struct clk *rxclk;
  230495. + struct clk *sysclk;
  230496. struct snd_dmaengine_dai_dma_data dma_params_tx;
  230497. struct snd_dmaengine_dai_dma_data dma_params_rx;
  230498. @@ -295,11 +298,11 @@
  230499. return -EBUSY;
  230500. }
  230501. -static void spdif_set_cstatus(struct spdif_mixer_control *ctrl,
  230502. - u8 mask, u8 cstatus)
  230503. +static inline void spdif_set_cstatus(struct spdif_mixer_control *ctrl,
  230504. + u8 byteno, u8 mask, u8 cstatus)
  230505. {
  230506. - ctrl->ch_status[3] &= ~mask;
  230507. - ctrl->ch_status[3] |= cstatus & mask;
  230508. + ctrl->ch_status[byteno] &= ~mask;
  230509. + ctrl->ch_status[byteno] |= cstatus & mask;
  230510. }
  230511. static void spdif_write_channel_status(struct fsl_spdif_priv *spdif_priv)
  230512. @@ -316,10 +319,16 @@
  230513. dev_dbg(&pdev->dev, "STCSCH: 0x%06x\n", ch_status);
  230514. - ch_status = bitrev8(ctrl->ch_status[3]) << 16;
  230515. + ch_status = bitrev8(ctrl->ch_status[3]) << 16 |
  230516. + (bitrev8(ctrl->ch_status[4]) << 8) |
  230517. + bitrev8(ctrl->ch_status[5]);
  230518. regmap_write(regmap, REG_SPDIF_STCSCL, ch_status);
  230519. dev_dbg(&pdev->dev, "STCSCL: 0x%06x\n", ch_status);
  230520. +
  230521. + /* Set outgoing validity (0: pcm, 1: non-audio) */
  230522. + regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_VAL_MASK,
  230523. + (ctrl->ch_status[0] & IEC958_AES0_NONAUDIO) ? 0 : SCR_VAL_CLEAR);
  230524. }
  230525. /* Set SPDIF PhaseConfig register for rx clock */
  230526. @@ -347,23 +356,45 @@
  230527. struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
  230528. struct regmap *regmap = spdif_priv->regmap;
  230529. struct platform_device *pdev = spdif_priv->pdev;
  230530. - unsigned long csfs = 0;
  230531. u32 stc, mask, rate;
  230532. - u8 clk, div;
  230533. + u8 clk, div, csfs, csofs;
  230534. int ret;
  230535. switch (sample_rate) {
  230536. case 32000:
  230537. rate = SPDIF_TXRATE_32000;
  230538. csfs = IEC958_AES3_CON_FS_32000;
  230539. + csofs = IEC958_AES4_CON_ORIGFS_32000;
  230540. break;
  230541. case 44100:
  230542. rate = SPDIF_TXRATE_44100;
  230543. csfs = IEC958_AES3_CON_FS_44100;
  230544. + csofs = IEC958_AES4_CON_ORIGFS_44100;
  230545. break;
  230546. case 48000:
  230547. rate = SPDIF_TXRATE_48000;
  230548. csfs = IEC958_AES3_CON_FS_48000;
  230549. + csofs = IEC958_AES4_CON_ORIGFS_48000;
  230550. + break;
  230551. + case 88200:
  230552. + rate = SPDIF_TXRATE_88200;
  230553. + csfs = IEC958_AES3_CON_FS_88200;
  230554. + csofs = IEC958_AES4_CON_ORIGFS_88200;
  230555. + break;
  230556. + case 96000:
  230557. + rate = SPDIF_TXRATE_96000;
  230558. + csfs = IEC958_AES3_CON_FS_96000;
  230559. + csofs = IEC958_AES4_CON_ORIGFS_96000;
  230560. + break;
  230561. + case 176400:
  230562. + rate = SPDIF_TXRATE_176400;
  230563. + csfs = IEC958_AES3_CON_FS_176400;
  230564. + csofs = IEC958_AES4_CON_ORIGFS_176400;
  230565. + break;
  230566. + case 192000:
  230567. + rate = SPDIF_TXRATE_192000;
  230568. + csfs = IEC958_AES3_CON_FS_192000;
  230569. + csofs = IEC958_AES4_CON_ORIGFS_192000;
  230570. break;
  230571. default:
  230572. dev_err(&pdev->dev, "unsupported sample rate %d\n", sample_rate);
  230573. @@ -399,7 +430,8 @@
  230574. clk_get_rate(spdif_priv->txclk[rate]));
  230575. /* set fs field in consumer channel status */
  230576. - spdif_set_cstatus(ctrl, IEC958_AES3_CON_FS, csfs);
  230577. + spdif_set_cstatus(ctrl, 3, IEC958_AES3_CON_FS, csfs);
  230578. + spdif_set_cstatus(ctrl, 4, IEC958_AES4_CON_ORIGFS, csofs);
  230579. /* select clock source and divisor */
  230580. stc = STC_TXCLK_ALL_EN | STC_TXCLK_SRC_SET(clk) | STC_TXCLK_DIV(div);
  230581. @@ -421,6 +453,8 @@
  230582. u32 scr, mask, i;
  230583. int ret;
  230584. + pm_runtime_get_sync(cpu_dai->dev);
  230585. +
  230586. /* Reset module and interrupts only for first initialization */
  230587. if (!cpu_dai->active) {
  230588. ret = spdif_softreset(spdif_priv);
  230589. @@ -485,6 +519,8 @@
  230590. regmap_update_bits(regmap, REG_SPDIF_SCR,
  230591. SCR_LOW_POWER, SCR_LOW_POWER);
  230592. }
  230593. +
  230594. + pm_runtime_put_sync(cpu_dai->dev);
  230595. }
  230596. static int fsl_spdif_hw_params(struct snd_pcm_substream *substream,
  230597. @@ -505,8 +541,8 @@
  230598. __func__, sample_rate);
  230599. return ret;
  230600. }
  230601. - spdif_set_cstatus(ctrl, IEC958_AES3_CON_CLOCK,
  230602. - IEC958_AES3_CON_CLOCK_1000PPM);
  230603. + spdif_set_cstatus(ctrl, 3, IEC958_AES3_CON_CLOCK,
  230604. + IEC958_AES3_CON_CLOCK_1000PPM);
  230605. spdif_write_channel_status(spdif_priv);
  230606. } else {
  230607. /* Setup rx clock source */
  230608. @@ -576,14 +612,13 @@
  230609. static int fsl_spdif_pb_get(struct snd_kcontrol *kcontrol,
  230610. struct snd_ctl_elem_value *uvalue)
  230611. {
  230612. + int i;
  230613. struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
  230614. struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
  230615. struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
  230616. - uvalue->value.iec958.status[0] = ctrl->ch_status[0];
  230617. - uvalue->value.iec958.status[1] = ctrl->ch_status[1];
  230618. - uvalue->value.iec958.status[2] = ctrl->ch_status[2];
  230619. - uvalue->value.iec958.status[3] = ctrl->ch_status[3];
  230620. + for (i = 0; i < ARRAY_SIZE(ctrl->ch_status); i++)
  230621. + uvalue->value.iec958.status[i] = ctrl->ch_status[i];
  230622. return 0;
  230623. }
  230624. @@ -591,14 +626,13 @@
  230625. static int fsl_spdif_pb_put(struct snd_kcontrol *kcontrol,
  230626. struct snd_ctl_elem_value *uvalue)
  230627. {
  230628. + int i;
  230629. struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
  230630. struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
  230631. struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
  230632. - ctrl->ch_status[0] = uvalue->value.iec958.status[0];
  230633. - ctrl->ch_status[1] = uvalue->value.iec958.status[1];
  230634. - ctrl->ch_status[2] = uvalue->value.iec958.status[2];
  230635. - ctrl->ch_status[3] = uvalue->value.iec958.status[3];
  230636. + for (i = 0; i < ARRAY_SIZE(ctrl->ch_status); i++)
  230637. + ctrl->ch_status[i] = uvalue->value.iec958.status[i];
  230638. spdif_write_channel_status(spdif_priv);
  230639. @@ -754,7 +788,7 @@
  230640. clksrc = (phaseconf >> SRPC_CLKSRC_SEL_OFFSET) & 0xf;
  230641. if (srpc_dpll_locked[clksrc] && (phaseconf & SRPC_DPLL_LOCKED)) {
  230642. /* Get bus clock from system */
  230643. - busclk_freq = clk_get_rate(spdif_priv->rxclk);
  230644. + busclk_freq = clk_get_rate(spdif_priv->sysclk);
  230645. }
  230646. /* FreqMeas_CLK = (BUS_CLK * FreqMeas) / 2 ^ 10 / GAINSEL / 128 */
  230647. @@ -999,7 +1033,7 @@
  230648. struct clk *clk, u64 savesub,
  230649. enum spdif_txrate index)
  230650. {
  230651. - const u32 rate[] = { 32000, 44100, 48000 };
  230652. + const u32 rate[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 };
  230653. u64 rate_ideal, rate_actual, sub;
  230654. u32 div, arate;
  230655. @@ -1017,7 +1051,7 @@
  230656. break;
  230657. } else if (arate / rate[index] == 1) {
  230658. /* A little bigger than expect */
  230659. - sub = (arate - rate[index]) * 100000;
  230660. + sub = (u64)(arate - rate[index]) * 100000;
  230661. do_div(sub, rate[index]);
  230662. if (sub < savesub) {
  230663. savesub = sub;
  230664. @@ -1025,7 +1059,7 @@
  230665. }
  230666. } else if (rate[index] / arate == 1) {
  230667. /* A little smaller than expect */
  230668. - sub = (rate[index] - arate) * 100000;
  230669. + sub = (u64)(rate[index] - arate) * 100000;
  230670. do_div(sub, rate[index]);
  230671. if (sub < savesub) {
  230672. savesub = sub;
  230673. @@ -1040,7 +1074,7 @@
  230674. static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
  230675. enum spdif_txrate index)
  230676. {
  230677. - const u32 rate[] = { 32000, 44100, 48000 };
  230678. + const u32 rate[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 };
  230679. struct platform_device *pdev = spdif_priv->pdev;
  230680. struct device *dev = &pdev->dev;
  230681. u64 savesub = 100000, ret;
  230682. @@ -1058,6 +1092,13 @@
  230683. if (!clk_get_rate(clk))
  230684. continue;
  230685. + /* TODO: We here ignore sysclk source due to imperfect clock
  230686. + * selecting mechanism: sysclk is a bit different which we can
  230687. + * not change its clock rate but use another inner divider to
  230688. + * derive a proper clock rate. */
  230689. + if (i == SPDIF_CLK_SRC_SYSCLK)
  230690. + continue;
  230691. +
  230692. ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index);
  230693. if (savesub == ret)
  230694. continue;
  230695. @@ -1131,6 +1172,13 @@
  230696. return ret;
  230697. }
  230698. + /* Get system clock for rx clock rate calculation */
  230699. + spdif_priv->sysclk = devm_clk_get(&pdev->dev, "rxtx5");
  230700. + if (IS_ERR(spdif_priv->sysclk)) {
  230701. + dev_err(&pdev->dev, "no system clock(rxtx5) in devicetree\n");
  230702. + return PTR_ERR(spdif_priv->sysclk);
  230703. + }
  230704. +
  230705. /* Select clock source for rx/tx clock */
  230706. spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1");
  230707. if (IS_ERR(spdif_priv->rxclk)) {
  230708. @@ -1150,12 +1198,13 @@
  230709. spin_lock_init(&ctrl->ctl_lock);
  230710. /* Init tx channel status default value */
  230711. - ctrl->ch_status[0] =
  230712. - IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_5015;
  230713. + ctrl->ch_status[0] = IEC958_AES0_CON_NOT_COPYRIGHT;
  230714. ctrl->ch_status[1] = IEC958_AES1_CON_DIGDIGCONV_ID;
  230715. ctrl->ch_status[2] = 0x00;
  230716. ctrl->ch_status[3] =
  230717. IEC958_AES3_CON_FS_44100 | IEC958_AES3_CON_CLOCK_1000PPM;
  230718. + ctrl->ch_status[4] = IEC958_AES4_CON_ORIGFS_44100;
  230719. + ctrl->ch_status[5] = IEC958_AES5_CON_CGMSA_COPYFREELY;
  230720. spdif_priv->dpll_locked = false;
  230721. @@ -1164,6 +1213,8 @@
  230722. spdif_priv->dma_params_tx.addr = res->start + REG_SPDIF_STL;
  230723. spdif_priv->dma_params_rx.addr = res->start + REG_SPDIF_SRL;
  230724. + pm_runtime_enable(&pdev->dev);
  230725. +
  230726. /* Register with ASoC */
  230727. dev_set_drvdata(&pdev->dev, spdif_priv);
  230728. @@ -1174,13 +1225,34 @@
  230729. return ret;
  230730. }
  230731. - ret = imx_pcm_dma_init(pdev);
  230732. + ret = imx_pcm_dma_init(pdev, SND_DMAENGINE_PCM_FLAG_COMPAT,
  230733. + IMX_SPDIF_DMABUF_SIZE);
  230734. if (ret)
  230735. dev_err(&pdev->dev, "imx_pcm_dma_init failed: %d\n", ret);
  230736. return ret;
  230737. }
  230738. +#ifdef CONFIG_PM_RUNTIME
  230739. +static int fsl_spdif_runtime_resume(struct device *dev)
  230740. +{
  230741. + request_bus_freq(BUS_FREQ_HIGH);
  230742. + return 0;
  230743. +}
  230744. +
  230745. +static int fsl_spdif_runtime_suspend(struct device *dev)
  230746. +{
  230747. + release_bus_freq(BUS_FREQ_HIGH);
  230748. + return 0;
  230749. +}
  230750. +#endif
  230751. +
  230752. +static const struct dev_pm_ops fsl_spdif_pm = {
  230753. + SET_RUNTIME_PM_OPS(fsl_spdif_runtime_suspend,
  230754. + fsl_spdif_runtime_resume,
  230755. + NULL)
  230756. +};
  230757. +
  230758. static const struct of_device_id fsl_spdif_dt_ids[] = {
  230759. { .compatible = "fsl,imx35-spdif", },
  230760. {}
  230761. @@ -1192,6 +1264,7 @@
  230762. .name = "fsl-spdif-dai",
  230763. .owner = THIS_MODULE,
  230764. .of_match_table = fsl_spdif_dt_ids,
  230765. + .pm = &fsl_spdif_pm,
  230766. },
  230767. .probe = fsl_spdif_probe,
  230768. };
  230769. diff -Nur linux-3.14.14/sound/soc/fsl/fsl_spdif.h linux-imx6-3.14/sound/soc/fsl/fsl_spdif.h
  230770. --- linux-3.14.14/sound/soc/fsl/fsl_spdif.h 2014-07-28 10:07:25.000000000 -0500
  230771. +++ linux-imx6-3.14/sound/soc/fsl/fsl_spdif.h 2014-12-08 00:31:56.116418001 -0600
  230772. @@ -157,13 +157,19 @@
  230773. #define STC_TXCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_TXCLK_DIV_MASK)
  230774. #define STC_TXCLK_SRC_MAX 8
  230775. +#define SPDIF_CLK_SRC_SYSCLK 5
  230776. +
  230777. /* SPDIF tx rate */
  230778. enum spdif_txrate {
  230779. SPDIF_TXRATE_32000 = 0,
  230780. SPDIF_TXRATE_44100,
  230781. SPDIF_TXRATE_48000,
  230782. + SPDIF_TXRATE_88200,
  230783. + SPDIF_TXRATE_96000,
  230784. + SPDIF_TXRATE_176400,
  230785. + SPDIF_TXRATE_192000,
  230786. };
  230787. -#define SPDIF_TXRATE_MAX (SPDIF_TXRATE_48000 + 1)
  230788. +#define SPDIF_TXRATE_MAX (SPDIF_TXRATE_192000 + 1)
  230789. #define SPDIF_CSTATUS_BYTE 6
  230790. @@ -173,7 +179,11 @@
  230791. #define FSL_SPDIF_RATES_PLAYBACK (SNDRV_PCM_RATE_32000 | \
  230792. SNDRV_PCM_RATE_44100 | \
  230793. - SNDRV_PCM_RATE_48000)
  230794. + SNDRV_PCM_RATE_48000 | \
  230795. + SNDRV_PCM_RATE_88200 | \
  230796. + SNDRV_PCM_RATE_96000 | \
  230797. + SNDRV_PCM_RATE_176400| \
  230798. + SNDRV_PCM_RATE_192000)
  230799. #define FSL_SPDIF_RATES_CAPTURE (SNDRV_PCM_RATE_16000 | \
  230800. SNDRV_PCM_RATE_32000 | \
  230801. diff -Nur linux-3.14.14/sound/soc/fsl/fsl_ssi.c linux-imx6-3.14/sound/soc/fsl/fsl_ssi.c
  230802. --- linux-3.14.14/sound/soc/fsl/fsl_ssi.c 2014-07-28 10:07:25.000000000 -0500
  230803. +++ linux-imx6-3.14/sound/soc/fsl/fsl_ssi.c 2014-12-08 00:31:56.116418001 -0600
  230804. @@ -3,7 +3,7 @@
  230805. *
  230806. * Author: Timur Tabi <timur@freescale.com>
  230807. *
  230808. - * Copyright 2007-2010 Freescale Semiconductor, Inc.
  230809. + * Copyright (C) 2007-2013 Freescale Semiconductor, Inc.
  230810. *
  230811. * This file is licensed under the terms of the GNU General Public License
  230812. * version 2. This program is licensed "as is" without any warranty of any
  230813. @@ -30,6 +30,7 @@
  230814. * around this by not polling these bits but only wait a fixed delay.
  230815. */
  230816. +#include <linux/busfreq-imx6.h>
  230817. #include <linux/init.h>
  230818. #include <linux/io.h>
  230819. #include <linux/module.h>
  230820. @@ -43,6 +44,7 @@
  230821. #include <linux/of_address.h>
  230822. #include <linux/of_irq.h>
  230823. #include <linux/of_platform.h>
  230824. +#include <linux/pm_runtime.h>
  230825. #include <sound/core.h>
  230826. #include <sound/pcm.h>
  230827. @@ -73,6 +75,24 @@
  230828. }
  230829. #endif
  230830. +#ifdef DEBUG
  230831. +#define NUM_OF_SSI_REG (sizeof(struct ccsr_ssi) / sizeof(__be32))
  230832. +
  230833. +void dump_reg(struct ccsr_ssi __iomem *ssi)
  230834. +{
  230835. + u32 val, i;
  230836. +
  230837. + for (i = 0; i < NUM_OF_SSI_REG; i++) {
  230838. + if (&ssi->stx0 + i == NULL)
  230839. + continue;
  230840. + val = read_ssi(&ssi->stx0 + i);
  230841. + pr_debug("REG %x = %x\n", (u32)(&ssi->stx0 + i) & 0xff, val);
  230842. + }
  230843. +}
  230844. +#else
  230845. +void dump_reg(struct ccsr_ssi __iomem *ssi) {}
  230846. +#endif
  230847. +
  230848. /**
  230849. * FSLSSI_I2S_RATES: sample rates supported by the I2S
  230850. *
  230851. @@ -171,8 +191,6 @@
  230852. struct clk *clk;
  230853. struct snd_dmaengine_dai_dma_data dma_params_tx;
  230854. struct snd_dmaengine_dai_dma_data dma_params_rx;
  230855. - struct imx_dma_data filter_data_tx;
  230856. - struct imx_dma_data filter_data_rx;
  230857. struct imx_pcm_fiq_params fiq_params;
  230858. /* Register values for rx/tx configuration */
  230859. struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
  230860. @@ -206,6 +224,26 @@
  230861. char name[1];
  230862. };
  230863. +#ifdef CONFIG_PM_RUNTIME
  230864. +static int fsl_ssi_runtime_resume(struct device *dev)
  230865. +{
  230866. + request_bus_freq(BUS_FREQ_AUDIO);
  230867. + return 0;
  230868. +}
  230869. +
  230870. +static int fsl_ssi_runtime_suspend(struct device *dev)
  230871. +{
  230872. + release_bus_freq(BUS_FREQ_AUDIO);
  230873. + return 0;
  230874. +}
  230875. +#endif
  230876. +
  230877. +static const struct dev_pm_ops fsl_ssi_pm = {
  230878. + SET_RUNTIME_PM_OPS(fsl_ssi_runtime_suspend,
  230879. + fsl_ssi_runtime_resume,
  230880. + NULL)
  230881. +};
  230882. +
  230883. static const struct of_device_id fsl_ssi_ids[] = {
  230884. { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610},
  230885. { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51},
  230886. @@ -489,6 +527,23 @@
  230887. }
  230888. }
  230889. +static void fsl_ssi_clk_ctrl(struct fsl_ssi_private *ssi_private, bool enable)
  230890. +{
  230891. + if (enable) {
  230892. + if (ssi_private->ssi_on_imx) {
  230893. + if (!IS_ERR(ssi_private->baudclk))
  230894. + clk_enable(ssi_private->baudclk);
  230895. + clk_enable(ssi_private->clk);
  230896. + }
  230897. + } else {
  230898. + if (ssi_private->ssi_on_imx) {
  230899. + if (!IS_ERR(ssi_private->baudclk))
  230900. + clk_disable(ssi_private->baudclk);
  230901. + clk_disable(ssi_private->clk);
  230902. + }
  230903. + }
  230904. +}
  230905. +
  230906. /*
  230907. * Enable/Disable a ssi configuration. You have to pass either
  230908. * ssi_private->rxtx_reg_val.rx or tx as vals parameter.
  230909. @@ -509,6 +564,8 @@
  230910. else
  230911. avals = &ssi_private->rxtx_reg_val.rx;
  230912. + fsl_ssi_clk_ctrl(ssi_private, enable);
  230913. +
  230914. /* If vals should be disabled, start with disabling the unit */
  230915. if (!enable) {
  230916. u32 scr = vals->scr & (vals->scr ^ avals->scr);
  230917. @@ -748,6 +805,8 @@
  230918. snd_soc_dai_get_drvdata(rtd->cpu_dai);
  230919. unsigned long flags;
  230920. + pm_runtime_get_sync(dai->dev);
  230921. +
  230922. /* First, we only do fsl_ssi_setup() when SSI is going to be active.
  230923. * Second, fsl_ssi_setup was already called by ac97_init earlier if
  230924. * the driver is in ac97 mode.
  230925. @@ -1083,14 +1142,17 @@
  230926. switch (cmd) {
  230927. case SNDRV_PCM_TRIGGER_START:
  230928. + case SNDRV_PCM_TRIGGER_RESUME:
  230929. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  230930. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  230931. fsl_ssi_tx_config(ssi_private, true);
  230932. else
  230933. fsl_ssi_rx_config(ssi_private, true);
  230934. + dump_reg(ssi);
  230935. break;
  230936. case SNDRV_PCM_TRIGGER_STOP:
  230937. + case SNDRV_PCM_TRIGGER_SUSPEND:
  230938. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  230939. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  230940. fsl_ssi_tx_config(ssi_private, false);
  230941. @@ -1119,6 +1181,12 @@
  230942. return 0;
  230943. }
  230944. +static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
  230945. + struct snd_soc_dai *dai)
  230946. +{
  230947. + pm_runtime_put_sync(dai->dev);
  230948. +}
  230949. +
  230950. static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
  230951. {
  230952. struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);
  230953. @@ -1138,6 +1206,7 @@
  230954. .set_sysclk = fsl_ssi_set_dai_sysclk,
  230955. .set_tdm_slot = fsl_ssi_set_dai_tdm_slot,
  230956. .trigger = fsl_ssi_trigger,
  230957. + .shutdown = fsl_ssi_shutdown,
  230958. };
  230959. /* Template for the CPU dai driver structure */
  230960. @@ -1257,13 +1326,13 @@
  230961. int ret = 0;
  230962. struct device_attribute *dev_attr = NULL;
  230963. struct device_node *np = pdev->dev.of_node;
  230964. + u32 dmas[4];
  230965. const struct of_device_id *of_id;
  230966. enum fsl_ssi_type hw_type;
  230967. const char *p, *sprop;
  230968. const uint32_t *iprop;
  230969. struct resource res;
  230970. char name[64];
  230971. - bool shared;
  230972. bool ac97 = false;
  230973. /* SSIs that are not connected on the board should have a
  230974. @@ -1381,7 +1450,6 @@
  230975. if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 ||
  230976. hw_type == FSL_SSI_MX35) {
  230977. - u32 dma_events[2], dmas[4];
  230978. ssi_private->ssi_on_imx = true;
  230979. ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
  230980. @@ -1390,9 +1458,9 @@
  230981. dev_err(&pdev->dev, "could not get clock: %d\n", ret);
  230982. goto error_irqmap;
  230983. }
  230984. - ret = clk_prepare_enable(ssi_private->clk);
  230985. + ret = clk_prepare(ssi_private->clk);
  230986. if (ret) {
  230987. - dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n",
  230988. + dev_err(&pdev->dev, "clk_prepare failed: %d\n",
  230989. ret);
  230990. goto error_irqmap;
  230991. }
  230992. @@ -1405,41 +1473,21 @@
  230993. dev_dbg(&pdev->dev, "could not get baud clock: %ld\n",
  230994. PTR_ERR(ssi_private->baudclk));
  230995. else
  230996. - clk_prepare_enable(ssi_private->baudclk);
  230997. + clk_prepare(ssi_private->baudclk);
  230998. /*
  230999. * We have burstsize be "fifo_depth - 2" to match the SSI
  231000. * watermark setting in fsl_ssi_startup().
  231001. */
  231002. - ssi_private->dma_params_tx.maxburst =
  231003. - ssi_private->fifo_depth - 2;
  231004. - ssi_private->dma_params_rx.maxburst =
  231005. - ssi_private->fifo_depth - 2;
  231006. + ssi_private->dma_params_tx.maxburst = ssi_private->fifo_depth - 2;
  231007. + ssi_private->dma_params_rx.maxburst = ssi_private->fifo_depth - 2;
  231008. ssi_private->dma_params_tx.addr =
  231009. ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
  231010. ssi_private->dma_params_rx.addr =
  231011. ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
  231012. - ssi_private->dma_params_tx.filter_data =
  231013. - &ssi_private->filter_data_tx;
  231014. - ssi_private->dma_params_rx.filter_data =
  231015. - &ssi_private->filter_data_rx;
  231016. - if (!of_property_read_bool(pdev->dev.of_node, "dmas") &&
  231017. - ssi_private->use_dma) {
  231018. - /*
  231019. - * FIXME: This is a temporary solution until all
  231020. - * necessary dma drivers support the generic dma
  231021. - * bindings.
  231022. - */
  231023. - ret = of_property_read_u32_array(pdev->dev.of_node,
  231024. - "fsl,ssi-dma-events", dma_events, 2);
  231025. - if (ret && ssi_private->use_dma) {
  231026. - dev_err(&pdev->dev, "could not get dma events but fsl-ssi is configured to use DMA\n");
  231027. - goto error_clk;
  231028. - }
  231029. - }
  231030. - /* Should this be merge with the above? */
  231031. - if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4)
  231032. - && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
  231033. +
  231034. + ret = !of_property_read_u32_array(np, "dmas", dmas, 4);
  231035. + if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
  231036. ssi_private->use_dual_fifo = true;
  231037. /* When using dual fifo mode, we need to keep watermark
  231038. * as even numbers due to dma script limitation.
  231039. @@ -1447,14 +1495,6 @@
  231040. ssi_private->dma_params_tx.maxburst &= ~0x1;
  231041. ssi_private->dma_params_rx.maxburst &= ~0x1;
  231042. }
  231043. -
  231044. - shared = of_device_is_compatible(of_get_parent(np),
  231045. - "fsl,spba-bus");
  231046. -
  231047. - imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx,
  231048. - dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
  231049. - imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
  231050. - dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
  231051. }
  231052. /*
  231053. @@ -1474,6 +1514,8 @@
  231054. }
  231055. }
  231056. + pm_runtime_enable(&pdev->dev);
  231057. +
  231058. /* Register with ASoC */
  231059. dev_set_drvdata(&pdev->dev, ssi_private);
  231060. @@ -1509,7 +1551,8 @@
  231061. if (ret)
  231062. goto error_pcm;
  231063. } else {
  231064. - ret = imx_pcm_dma_init(pdev);
  231065. + ret = imx_pcm_dma_init(pdev, NULL,
  231066. + IMX_SSI_DMABUF_SIZE);
  231067. if (ret)
  231068. goto error_pcm;
  231069. }
  231070. @@ -1565,12 +1608,16 @@
  231071. error_dev:
  231072. device_remove_file(&pdev->dev, dev_attr);
  231073. -error_clk:
  231074. if (ssi_private->ssi_on_imx) {
  231075. if (!IS_ERR(ssi_private->baudclk))
  231076. - clk_disable_unprepare(ssi_private->baudclk);
  231077. - clk_disable_unprepare(ssi_private->clk);
  231078. + clk_unprepare(ssi_private->baudclk);
  231079. + clk_unprepare(ssi_private->clk);
  231080. }
  231081. +error_clk:
  231082. + if (!IS_ERR(ssi_private->baudclk))
  231083. + clk_unprepare(ssi_private->baudclk);
  231084. + if (!IS_ERR(ssi_private->clk))
  231085. + clk_unprepare(ssi_private->clk);
  231086. error_irqmap:
  231087. if (ssi_private->irq_stats)
  231088. @@ -1590,8 +1637,8 @@
  231089. snd_soc_unregister_component(&pdev->dev);
  231090. if (ssi_private->ssi_on_imx) {
  231091. if (!IS_ERR(ssi_private->baudclk))
  231092. - clk_disable_unprepare(ssi_private->baudclk);
  231093. - clk_disable_unprepare(ssi_private->clk);
  231094. + clk_unprepare(ssi_private->baudclk);
  231095. + clk_unprepare(ssi_private->clk);
  231096. }
  231097. if (ssi_private->irq_stats)
  231098. irq_dispose_mapping(ssi_private->irq);
  231099. @@ -1604,6 +1651,7 @@
  231100. .name = "fsl-ssi-dai",
  231101. .owner = THIS_MODULE,
  231102. .of_match_table = fsl_ssi_ids,
  231103. + .pm = &fsl_ssi_pm,
  231104. },
  231105. .probe = fsl_ssi_probe,
  231106. .remove = fsl_ssi_remove,
  231107. diff -Nur linux-3.14.14/sound/soc/fsl/imx-cs42888.c linux-imx6-3.14/sound/soc/fsl/imx-cs42888.c
  231108. --- linux-3.14.14/sound/soc/fsl/imx-cs42888.c 1969-12-31 18:00:00.000000000 -0600
  231109. +++ linux-imx6-3.14/sound/soc/fsl/imx-cs42888.c 2014-12-08 00:31:56.116418001 -0600
  231110. @@ -0,0 +1,369 @@
  231111. +/*
  231112. + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  231113. + */
  231114. +
  231115. +/*
  231116. + * The code contained herein is licensed under the GNU General Public
  231117. + * License. You may obtain a copy of the GNU General Public License
  231118. + * Version 2 or later at the following locations:
  231119. + *
  231120. + * http://www.opensource.org/licenses/gpl-license.html
  231121. + * http://www.gnu.org/copyleft/gpl.html
  231122. + */
  231123. +
  231124. +#include <linux/module.h>
  231125. +#include <linux/of.h>
  231126. +#include <linux/of_platform.h>
  231127. +#include <linux/slab.h>
  231128. +#include <linux/device.h>
  231129. +#include <linux/i2c.h>
  231130. +#include <linux/clk.h>
  231131. +#include <linux/delay.h>
  231132. +#include <sound/core.h>
  231133. +#include <sound/pcm.h>
  231134. +#include <sound/soc.h>
  231135. +#include <sound/initval.h>
  231136. +#include <sound/pcm_params.h>
  231137. +
  231138. +#include "fsl_esai.h"
  231139. +#include "fsl_asrc.h"
  231140. +
  231141. +#define CODEC_CLK_EXTER_OSC 1
  231142. +#define CODEC_CLK_ESAI_HCKT 2
  231143. +
  231144. +struct imx_priv {
  231145. + int hw;
  231146. + int fe_output_rate;
  231147. + int fe_output_width;
  231148. + unsigned int mclk_freq;
  231149. + unsigned int codec_mclk;
  231150. + struct platform_device *pdev;
  231151. +};
  231152. +
  231153. +static struct imx_priv card_priv;
  231154. +
  231155. +static int imx_cs42888_startup(struct snd_pcm_substream *substream)
  231156. +{
  231157. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231158. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  231159. + struct imx_priv *priv = &card_priv;
  231160. +
  231161. + if (!cpu_dai->active)
  231162. + priv->hw = 0;
  231163. + return 0;
  231164. +}
  231165. +
  231166. +static void imx_cs42888_shutdown(struct snd_pcm_substream *substream)
  231167. +{
  231168. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231169. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  231170. + struct imx_priv *priv = &card_priv;
  231171. +
  231172. + if (!cpu_dai->active)
  231173. + priv->hw = 0;
  231174. +}
  231175. +
  231176. +static const struct {
  231177. + int rate;
  231178. + int ratio1;
  231179. + int ratio2;
  231180. +} sr_vals[] = {
  231181. + { 32000, 5, 3 },
  231182. + { 48000, 5, 3 },
  231183. + { 64000, 2, 1 },
  231184. + { 96000, 2, 1 },
  231185. + { 128000, 2, 1 },
  231186. + { 44100, 5, 3 },
  231187. + { 88200, 2, 1 },
  231188. + { 176400, 0, 0 },
  231189. + { 192000, 0, 0 },
  231190. +};
  231191. +
  231192. +static int imx_cs42888_surround_hw_params(struct snd_pcm_substream *substream,
  231193. + struct snd_pcm_hw_params *params)
  231194. +{
  231195. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231196. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  231197. + struct snd_soc_dai *codec_dai = rtd->codec_dai;
  231198. + struct imx_priv *priv = &card_priv;
  231199. + unsigned int rate = params_rate(params);
  231200. + unsigned int lrclk_ratio = 0, i;
  231201. + u32 dai_format = 0;
  231202. +
  231203. + if (priv->hw)
  231204. + return 0;
  231205. +
  231206. + priv->hw = 1;
  231207. +
  231208. + if (priv->codec_mclk & CODEC_CLK_ESAI_HCKT) {
  231209. + for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
  231210. + if (sr_vals[i].rate == rate) {
  231211. + lrclk_ratio = sr_vals[i].ratio1;
  231212. + break;
  231213. + }
  231214. + }
  231215. + if (i == ARRAY_SIZE(sr_vals)) {
  231216. + dev_err(&priv->pdev->dev, "Unsupported rate %dHz\n", rate);
  231217. + return -EINVAL;
  231218. + }
  231219. +
  231220. + dai_format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
  231221. + SND_SOC_DAIFMT_CBS_CFS;
  231222. +
  231223. + /* set the ESAI system clock as output */
  231224. + snd_soc_dai_set_sysclk(cpu_dai, ESAI_CLK_EXTAL_DIV,
  231225. + priv->mclk_freq, SND_SOC_CLOCK_OUT);
  231226. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PM, 2);
  231227. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PM, 2);
  231228. + /* set codec Master clock */
  231229. + snd_soc_dai_set_sysclk(codec_dai, 0, priv->mclk_freq,\
  231230. + SND_SOC_CLOCK_IN);
  231231. + } else if (priv->codec_mclk & CODEC_CLK_EXTER_OSC) {
  231232. + for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
  231233. + if (sr_vals[i].rate == rate) {
  231234. + lrclk_ratio = sr_vals[i].ratio2;
  231235. + break;
  231236. + }
  231237. + }
  231238. + if (i == ARRAY_SIZE(sr_vals)) {
  231239. + dev_err(&priv->pdev->dev, "Unsupported rate %dHz\n", rate);
  231240. + return -EINVAL;
  231241. + }
  231242. +
  231243. + dai_format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
  231244. + SND_SOC_DAIFMT_CBS_CFS;
  231245. +
  231246. + snd_soc_dai_set_sysclk(cpu_dai, ESAI_CLK_EXTAL,
  231247. + priv->mclk_freq, SND_SOC_CLOCK_OUT);
  231248. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PM, 0);
  231249. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PM, 0);
  231250. + snd_soc_dai_set_sysclk(codec_dai, 0, priv->mclk_freq,\
  231251. + SND_SOC_CLOCK_IN);
  231252. + }
  231253. +
  231254. + /* set cpu DAI configuration */
  231255. + snd_soc_dai_set_fmt(cpu_dai, dai_format);
  231256. + /* set i.MX active slot mask */
  231257. + snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 32);
  231258. + /* set the ratio */
  231259. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PSR, 1);
  231260. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_FP, lrclk_ratio);
  231261. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PSR, 1);
  231262. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_FP, lrclk_ratio);
  231263. +
  231264. + /* set codec DAI configuration */
  231265. + snd_soc_dai_set_fmt(codec_dai, dai_format);
  231266. + return 0;
  231267. +}
  231268. +
  231269. +static struct snd_soc_ops imx_cs42888_surround_ops = {
  231270. + .startup = imx_cs42888_startup,
  231271. + .shutdown = imx_cs42888_shutdown,
  231272. + .hw_params = imx_cs42888_surround_hw_params,
  231273. +};
  231274. +
  231275. +static const struct snd_soc_dapm_widget imx_cs42888_dapm_widgets[] = {
  231276. + SND_SOC_DAPM_LINE("Line Out Jack", NULL),
  231277. + SND_SOC_DAPM_LINE("Line In Jack", NULL),
  231278. +};
  231279. +
  231280. +static const struct snd_soc_dapm_route audio_map[] = {
  231281. + /* Line out jack */
  231282. + {"Line Out Jack", NULL, "AOUT1L"},
  231283. + {"Line Out Jack", NULL, "AOUT1R"},
  231284. + {"Line Out Jack", NULL, "AOUT2L"},
  231285. + {"Line Out Jack", NULL, "AOUT2R"},
  231286. + {"Line Out Jack", NULL, "AOUT3L"},
  231287. + {"Line Out Jack", NULL, "AOUT3R"},
  231288. + {"Line Out Jack", NULL, "AOUT4L"},
  231289. + {"Line Out Jack", NULL, "AOUT4R"},
  231290. + {"AIN1L", NULL, "Line In Jack"},
  231291. + {"AIN1R", NULL, "Line In Jack"},
  231292. + {"AIN2L", NULL, "Line In Jack"},
  231293. + {"AIN2R", NULL, "Line In Jack"},
  231294. + {"esai-Playback", NULL, "asrc-Playback"},
  231295. + {"codec-Playback", NULL, "esai-Playback"},/*Playback is the codec dai*/
  231296. +};
  231297. +
  231298. +static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
  231299. + struct snd_pcm_hw_params *params) {
  231300. +
  231301. + struct imx_priv *priv = &card_priv;
  231302. +
  231303. + hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = priv->fe_output_rate;
  231304. + hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max = priv->fe_output_rate;
  231305. + snd_mask_none(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT));
  231306. + if (priv->fe_output_width == 16)
  231307. + snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
  231308. + SNDRV_PCM_FORMAT_S16_LE);
  231309. + else
  231310. + snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
  231311. + SNDRV_PCM_FORMAT_S24_LE);
  231312. + return 0;
  231313. +}
  231314. +
  231315. +static struct snd_soc_dai_link imx_cs42888_dai[] = {
  231316. + {
  231317. + .name = "HiFi",
  231318. + .stream_name = "HiFi",
  231319. + .codec_dai_name = "CS42888",
  231320. + .ops = &imx_cs42888_surround_ops,
  231321. + },
  231322. + {
  231323. + .name = "HiFi-ASRC-FE",
  231324. + .stream_name = "HiFi-ASRC-FE",
  231325. + .codec_name = "snd-soc-dummy",
  231326. + .codec_dai_name = "snd-soc-dummy-dai",
  231327. + .dynamic = 1,
  231328. + },
  231329. + {
  231330. + .name = "HiFi-ASRC-BE",
  231331. + .stream_name = "HiFi-ASRC-BE",
  231332. + .codec_dai_name = "CS42888",
  231333. + .platform_name = "snd-soc-dummy",
  231334. + .no_pcm = 1,
  231335. + .ops = &imx_cs42888_surround_ops,
  231336. + .be_hw_params_fixup = be_hw_params_fixup,
  231337. + },
  231338. +};
  231339. +
  231340. +static struct snd_soc_card snd_soc_card_imx_cs42888 = {
  231341. + .name = "cs42888-audio",
  231342. + .dai_link = imx_cs42888_dai,
  231343. + .dapm_widgets = imx_cs42888_dapm_widgets,
  231344. + .num_dapm_widgets = ARRAY_SIZE(imx_cs42888_dapm_widgets),
  231345. + .dapm_routes = audio_map,
  231346. + .num_dapm_routes = ARRAY_SIZE(audio_map),
  231347. +};
  231348. +
  231349. +/*
  231350. + * This function will register the snd_soc_pcm_link drivers.
  231351. + */
  231352. +static int imx_cs42888_probe(struct platform_device *pdev)
  231353. +{
  231354. + struct device_node *esai_np, *codec_np;
  231355. + struct device_node *asrc_np;
  231356. + struct platform_device *esai_pdev;
  231357. + struct platform_device *asrc_pdev = NULL;
  231358. + struct i2c_client *codec_dev;
  231359. + struct imx_priv *priv = &card_priv;
  231360. + struct clk *codec_clk = NULL;
  231361. + const char *mclk_name;
  231362. + int ret;
  231363. +
  231364. + priv->pdev = pdev;
  231365. +
  231366. + esai_np = of_parse_phandle(pdev->dev.of_node, "esai-controller", 0);
  231367. + codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
  231368. + if (!esai_np || !codec_np) {
  231369. + dev_err(&pdev->dev, "phandle missing or invalid\n");
  231370. + ret = -EINVAL;
  231371. + goto fail;
  231372. + }
  231373. +
  231374. + asrc_np = of_parse_phandle(pdev->dev.of_node, "asrc-controller", 0);
  231375. + if (asrc_np) {
  231376. + asrc_pdev = of_find_device_by_node(asrc_np);
  231377. + if (asrc_pdev) {
  231378. + struct fsl_asrc_p2p *asrc_p2p;
  231379. + asrc_p2p = platform_get_drvdata(asrc_pdev);
  231380. + asrc_p2p->per_dev = ESAI;
  231381. + priv->fe_output_rate = asrc_p2p->output_rate;
  231382. + priv->fe_output_width = asrc_p2p->output_width;
  231383. + }
  231384. + }
  231385. +
  231386. + esai_pdev = of_find_device_by_node(esai_np);
  231387. + if (!esai_pdev) {
  231388. + dev_err(&pdev->dev, "failed to find ESAI platform device\n");
  231389. + ret = -EINVAL;
  231390. + goto fail;
  231391. + }
  231392. + codec_dev = of_find_i2c_device_by_node(codec_np);
  231393. + if (!codec_dev) {
  231394. + dev_err(&pdev->dev, "failed to find codec platform device\n");
  231395. + ret = -EINVAL;
  231396. + goto fail;
  231397. + }
  231398. +
  231399. + /*if there is no asrc controller, we only enable one device*/
  231400. + if (!asrc_pdev) {
  231401. + imx_cs42888_dai[0].codec_of_node = codec_np;
  231402. + imx_cs42888_dai[0].cpu_dai_name = dev_name(&esai_pdev->dev);
  231403. + imx_cs42888_dai[0].platform_of_node = esai_np;
  231404. + snd_soc_card_imx_cs42888.num_links = 1;
  231405. + } else {
  231406. + imx_cs42888_dai[0].codec_of_node = codec_np;
  231407. + imx_cs42888_dai[0].cpu_dai_name = dev_name(&esai_pdev->dev);
  231408. + imx_cs42888_dai[0].platform_of_node = esai_np;
  231409. + imx_cs42888_dai[1].cpu_dai_name = dev_name(&asrc_pdev->dev);
  231410. + imx_cs42888_dai[1].platform_name = "imx-pcm-asrc";
  231411. + imx_cs42888_dai[2].codec_of_node = codec_np;
  231412. + imx_cs42888_dai[2].cpu_dai_name = dev_name(&esai_pdev->dev);
  231413. + snd_soc_card_imx_cs42888.num_links = 3;
  231414. + }
  231415. +
  231416. + codec_clk = devm_clk_get(&codec_dev->dev, NULL);
  231417. + if (IS_ERR(codec_clk)) {
  231418. + ret = PTR_ERR(codec_clk);
  231419. + dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
  231420. + goto fail;
  231421. + }
  231422. + priv->mclk_freq = clk_get_rate(codec_clk);
  231423. +
  231424. + ret = of_property_read_string(codec_np, "clock-names", &mclk_name);
  231425. + if (ret) {
  231426. + dev_err(&pdev->dev, "%s: failed to get mclk source\n", __func__);
  231427. + goto fail;
  231428. + }
  231429. + if (!strcmp(mclk_name, "codec_osc"))
  231430. + priv->codec_mclk = CODEC_CLK_EXTER_OSC;
  231431. + else if (!strcmp(mclk_name, "esai"))
  231432. + priv->codec_mclk = CODEC_CLK_ESAI_HCKT;
  231433. + else {
  231434. + dev_err(&pdev->dev, "mclk source is not correct %s\n", mclk_name);
  231435. + goto fail;
  231436. + }
  231437. +
  231438. + snd_soc_card_imx_cs42888.dev = &pdev->dev;
  231439. +
  231440. + platform_set_drvdata(pdev, &snd_soc_card_imx_cs42888);
  231441. +
  231442. + ret = snd_soc_register_card(&snd_soc_card_imx_cs42888);
  231443. + if (ret)
  231444. + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
  231445. +fail:
  231446. + if (esai_np)
  231447. + of_node_put(esai_np);
  231448. + if (codec_np)
  231449. + of_node_put(codec_np);
  231450. + return ret;
  231451. +}
  231452. +
  231453. +static int imx_cs42888_remove(struct platform_device *pdev)
  231454. +{
  231455. + snd_soc_unregister_card(&snd_soc_card_imx_cs42888);
  231456. + return 0;
  231457. +}
  231458. +
  231459. +static const struct of_device_id imx_cs42888_dt_ids[] = {
  231460. + { .compatible = "fsl,imx-audio-cs42888", },
  231461. + { /* sentinel */ }
  231462. +};
  231463. +
  231464. +static struct platform_driver imx_cs42888_driver = {
  231465. + .probe = imx_cs42888_probe,
  231466. + .remove = imx_cs42888_remove,
  231467. + .driver = {
  231468. + .name = "imx-cs42888",
  231469. + .owner = THIS_MODULE,
  231470. + .pm = &snd_soc_pm_ops,
  231471. + .of_match_table = imx_cs42888_dt_ids,
  231472. + },
  231473. +};
  231474. +module_platform_driver(imx_cs42888_driver);
  231475. +
  231476. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  231477. +MODULE_DESCRIPTION("ALSA SoC cs42888 Machine Layer Driver");
  231478. +MODULE_ALIAS("platform:imx-cs42888");
  231479. +MODULE_LICENSE("GPL");
  231480. diff -Nur linux-3.14.14/sound/soc/fsl/imx-hdmi.c linux-imx6-3.14/sound/soc/fsl/imx-hdmi.c
  231481. --- linux-3.14.14/sound/soc/fsl/imx-hdmi.c 1969-12-31 18:00:00.000000000 -0600
  231482. +++ linux-imx6-3.14/sound/soc/fsl/imx-hdmi.c 2014-12-08 00:31:56.116418001 -0600
  231483. @@ -0,0 +1,113 @@
  231484. +/*
  231485. + * ASoC HDMI Transmitter driver for IMX development boards
  231486. + *
  231487. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  231488. + *
  231489. + * based on stmp3780_devb_hdmi.c
  231490. + *
  231491. + * Vladimir Barinov <vbarinov@embeddedalley.com>
  231492. + *
  231493. + * Copyright 2008 SigmaTel, Inc
  231494. + * Copyright 2008 Embedded Alley Solutions, Inc
  231495. + *
  231496. + * This file is licensed under the terms of the GNU General Public License
  231497. + * version 2. This program is licensed "as is" without any warranty of any
  231498. + * kind, whether express or implied.
  231499. + */
  231500. +
  231501. +#include <linux/module.h>
  231502. +#include <linux/of_platform.h>
  231503. +#include <linux/mfd/mxc-hdmi-core.h>
  231504. +#include <sound/soc.h>
  231505. +
  231506. +#include "imx-hdmi.h"
  231507. +
  231508. +/* imx digital audio interface glue - connects codec <--> CPU */
  231509. +static struct snd_soc_dai_link imx_hdmi_dai_link = {
  231510. + .name = "i.MX HDMI Audio Tx",
  231511. + .stream_name = "i.MX HDMI Audio Tx",
  231512. + .codec_dai_name = "hdmi-hifi",
  231513. + .codec_name = "hdmi-audio-codec",
  231514. + .platform_name = "imx-hdmi-audio",
  231515. +};
  231516. +
  231517. +static struct snd_soc_card snd_soc_card_imx_hdmi = {
  231518. + .name = "imx-hdmi-soc",
  231519. + .dai_link = &imx_hdmi_dai_link,
  231520. + .num_links = 1,
  231521. +};
  231522. +
  231523. +static int imx_hdmi_audio_probe(struct platform_device *pdev)
  231524. +{
  231525. + struct device_node *hdmi_np, *np = pdev->dev.of_node;
  231526. + struct snd_soc_card *card = &snd_soc_card_imx_hdmi;
  231527. + struct platform_device *hdmi_pdev;
  231528. + int ret = 0;
  231529. +
  231530. + if (!hdmi_get_registered()) {
  231531. + dev_err(&pdev->dev, "initialize HDMI-audio failed. load HDMI-video first!\n");
  231532. + return -ENODEV;
  231533. + }
  231534. +
  231535. + hdmi_np = of_parse_phandle(np, "hdmi-controller", 0);
  231536. + if (!hdmi_np) {
  231537. + dev_err(&pdev->dev, "failed to find hdmi-audio cpudai\n");
  231538. + ret = -EINVAL;
  231539. + goto end;
  231540. + }
  231541. +
  231542. + hdmi_pdev = of_find_device_by_node(hdmi_np);
  231543. + if (!hdmi_pdev) {
  231544. + dev_err(&pdev->dev, "failed to find SSI platform device\n");
  231545. + ret = -EINVAL;
  231546. + goto end;
  231547. + }
  231548. +
  231549. + card->dev = &pdev->dev;
  231550. + card->dai_link->cpu_dai_name = dev_name(&hdmi_pdev->dev);
  231551. +
  231552. + platform_set_drvdata(pdev, card);
  231553. +
  231554. + ret = snd_soc_register_card(card);
  231555. + if (ret)
  231556. + dev_err(&pdev->dev, "failed to register card: %d\n", ret);
  231557. +
  231558. +end:
  231559. + if (hdmi_np)
  231560. + of_node_put(hdmi_np);
  231561. +
  231562. + return ret;
  231563. +}
  231564. +
  231565. +static int imx_hdmi_audio_remove(struct platform_device *pdev)
  231566. +{
  231567. + struct snd_soc_card *card = platform_get_drvdata(pdev);
  231568. +
  231569. + snd_soc_unregister_card(card);
  231570. +
  231571. + return 0;
  231572. +}
  231573. +
  231574. +static const struct of_device_id imx_hdmi_dt_ids[] = {
  231575. + { .compatible = "fsl,imx-audio-hdmi", },
  231576. + { /* sentinel */ }
  231577. +};
  231578. +MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
  231579. +
  231580. +static struct platform_driver imx_hdmi_audio_driver = {
  231581. + .probe = imx_hdmi_audio_probe,
  231582. + .remove = imx_hdmi_audio_remove,
  231583. + .driver = {
  231584. + .of_match_table = imx_hdmi_dt_ids,
  231585. + .name = "imx-audio-hdmi",
  231586. + .owner = THIS_MODULE,
  231587. + .pm = &snd_soc_pm_ops,
  231588. + },
  231589. +};
  231590. +
  231591. +module_platform_driver(imx_hdmi_audio_driver);
  231592. +
  231593. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  231594. +MODULE_DESCRIPTION("IMX HDMI TX ASoC driver");
  231595. +MODULE_LICENSE("GPL");
  231596. +MODULE_ALIAS("platform:imx-audio-hdmi");
  231597. diff -Nur linux-3.14.14/sound/soc/fsl/imx-hdmi-dma.c linux-imx6-3.14/sound/soc/fsl/imx-hdmi-dma.c
  231598. --- linux-3.14.14/sound/soc/fsl/imx-hdmi-dma.c 1969-12-31 18:00:00.000000000 -0600
  231599. +++ linux-imx6-3.14/sound/soc/fsl/imx-hdmi-dma.c 2014-12-08 00:31:56.116418001 -0600
  231600. @@ -0,0 +1,1240 @@
  231601. +/*
  231602. + * imx-hdmi-dma.c -- HDMI DMA driver for ALSA Soc Audio Layer
  231603. + *
  231604. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
  231605. + *
  231606. + * based on imx-pcm-dma-mx2.c
  231607. + * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
  231608. + *
  231609. + * This code is based on code copyrighted by Freescale,
  231610. + * Liam Girdwood, Javier Martin and probably others.
  231611. + *
  231612. + * This program is free software; you can redistribute it and/or modify it
  231613. + * under the terms of the GNU General Public License as published by the
  231614. + * Free Software Foundation; either version 2 of the License, or (at your
  231615. + * option) any later version.
  231616. + */
  231617. +
  231618. +#include <linux/module.h>
  231619. +#include <linux/delay.h>
  231620. +#include <linux/dma-mapping.h>
  231621. +#include <linux/mfd/mxc-hdmi-core.h>
  231622. +#include <linux/platform_data/dma-imx.h>
  231623. +
  231624. +#include <video/mxc_hdmi.h>
  231625. +
  231626. +#include "imx-hdmi.h"
  231627. +
  231628. +#define HDMI_DMA_BURST_UNSPECIFIED_LEGNTH 0
  231629. +#define HDMI_DMA_BURST_INCR4 1
  231630. +#define HDMI_DMA_BURST_INCR8 2
  231631. +#define HDMI_DMA_BURST_INCR16 3
  231632. +
  231633. +#define HDMI_BASE_ADDR 0x00120000
  231634. +
  231635. +struct hdmi_sdma_script {
  231636. + int control_reg_addr;
  231637. + int status_reg_addr;
  231638. + int dma_start_addr;
  231639. + u32 buffer[20];
  231640. +};
  231641. +
  231642. +struct hdmi_dma_priv {
  231643. + struct snd_pcm_substream *substream;
  231644. + struct platform_device *pdev;
  231645. +
  231646. + struct snd_dma_buffer hw_buffer;
  231647. + unsigned long buffer_bytes;
  231648. + unsigned long appl_bytes;
  231649. +
  231650. + int periods;
  231651. + int period_time;
  231652. + int period_bytes;
  231653. + int dma_period_bytes;
  231654. + int buffer_ratio;
  231655. +
  231656. + unsigned long offset;
  231657. +
  231658. + snd_pcm_format_t format;
  231659. + int sample_align;
  231660. + int sample_bits;
  231661. + int channels;
  231662. + int rate;
  231663. +
  231664. + int frame_idx;
  231665. +
  231666. + bool tx_active;
  231667. + spinlock_t irq_lock;
  231668. +
  231669. + /* SDMA part */
  231670. + dma_addr_t phy_hdmi_sdma_t;
  231671. + struct hdmi_sdma_script *hdmi_sdma_t;
  231672. + struct dma_chan *dma_channel;
  231673. + struct imx_dma_data dma_data;
  231674. + struct dma_async_tx_descriptor *desc;
  231675. + struct imx_hdmi_sdma_params sdma_params;
  231676. +};
  231677. +
  231678. +/* bit 0:0:0:b:p(0):c:(u)0:(v)0 */
  231679. +/* max 8 channels supported; channels are interleaved */
  231680. +static u8 g_packet_head_table[48 * 8];
  231681. +
  231682. +/* channel remapping for hdmi_dma_copy_xxxx() */
  231683. +static u8 g_channel_remap_table[24];
  231684. +
  231685. +/* default mapping tables */
  231686. +static const u8 channel_maps_alsa_cea[5][8] = {
  231687. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 0CH: no remapping */
  231688. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 2CH: no remapping */
  231689. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 4CH: no remapping */
  231690. + { 0, 1, 4, 5, 3, 2, 6, 7 }, /* 6CH: ALSA5.1 to CEA */
  231691. + { 0, 1, 6, 7, 3, 2, 4, 5 } /* 8CH: ALSA7.1 to CEA */
  231692. +};
  231693. +
  231694. +static const u8 channel_maps_cea_alsa[5][8] = {
  231695. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 0CH: no remapping */
  231696. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 2CH: no remapping */
  231697. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 4CH: no remapping */
  231698. + { 0, 1, 5, 4, 2, 3, 6, 7 }, /* 6CH: CEA to ALSA5.1 */
  231699. + { 0, 1, 5, 4, 6, 7, 2, 3 } /* 8CH: CEA to ALSA7.1 */
  231700. +};
  231701. +
  231702. +union hdmi_audio_header_t iec_header;
  231703. +EXPORT_SYMBOL(iec_header);
  231704. +
  231705. +/*
  231706. + * Note that the period size for DMA != period size for ALSA because the
  231707. + * driver adds iec frame info to the audio samples (in hdmi_dma_copy).
  231708. + *
  231709. + * Each 4 byte subframe = 1 byte of iec data + 3 byte audio sample.
  231710. + *
  231711. + * A 16 bit audio sample becomes 32 bits including the frame info. Ratio=2
  231712. + * A 24 bit audio sample becomes 32 bits including the frame info. Ratio=3:4
  231713. + * If the 24 bit raw audio is in 32 bit words, the
  231714. + *
  231715. + * Original Packed into subframe Ratio of size Format
  231716. + * sample how many size of DMA buffer
  231717. + * (bits) bits to ALSA buffer
  231718. + * -------- ----------- -------- -------------- ------------------------
  231719. + * 16 16 32 2 SNDRV_PCM_FORMAT_S16_LE
  231720. + * 24 24 32 1.33 SNDRV_PCM_FORMAT_S24_3LE*
  231721. + * 24 32 32 1 SNDRV_PCM_FORMAT_S24_LE
  231722. + *
  231723. + * *so SNDRV_PCM_FORMAT_S24_3LE is not supported.
  231724. + */
  231725. +
  231726. +/*
  231727. + * The minimum dma period is one IEC audio frame (192 * 4 * channels).
  231728. + * The maximum dma period for the HDMI DMA is 8K.
  231729. + *
  231730. + * channels minimum maximum
  231731. + * dma period dma period
  231732. + * -------- ------------------ ----------
  231733. + * 2 192 * 4 * 2 = 1536 * 4 = 6144
  231734. + * 4 192 * 4 * 4 = 3072 * 2 = 6144
  231735. + * 6 192 * 4 * 6 = 4608 * 1 = 4608
  231736. + * 8 192 * 4 * 8 = 6144 * 1 = 6144
  231737. + *
  231738. + * Bottom line:
  231739. + * 1. Must keep the ratio of DMA buffer to ALSA buffer consistent.
  231740. + * 2. frame_idx is saved in the private data, so even if a frame cannot be
  231741. + * transmitted in a period, it can be continued in the next period. This
  231742. + * is necessary for 6 ch.
  231743. + */
  231744. +#define HDMI_DMA_PERIOD_BYTES (12288)
  231745. +#define HDMI_DMA_BUF_SIZE (1280 * 1024)
  231746. +#define HDMI_PCM_BUF_SIZE (1280 * 1024)
  231747. +
  231748. +#define hdmi_audio_debug(dev, reg) \
  231749. + dev_dbg(dev, #reg ": 0x%02x\n", hdmi_readb(reg))
  231750. +
  231751. +#ifdef DEBUG
  231752. +static void dumpregs(struct device *dev)
  231753. +{
  231754. + hdmi_audio_debug(dev, HDMI_AHB_DMA_CONF0);
  231755. + hdmi_audio_debug(dev, HDMI_AHB_DMA_START);
  231756. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STOP);
  231757. + hdmi_audio_debug(dev, HDMI_AHB_DMA_THRSLD);
  231758. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STRADDR0);
  231759. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STPADDR0);
  231760. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BSTADDR0);
  231761. + hdmi_audio_debug(dev, HDMI_AHB_DMA_MBLENGTH0);
  231762. + hdmi_audio_debug(dev, HDMI_AHB_DMA_MBLENGTH1);
  231763. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STAT);
  231764. + hdmi_audio_debug(dev, HDMI_AHB_DMA_INT);
  231765. + hdmi_audio_debug(dev, HDMI_AHB_DMA_MASK);
  231766. + hdmi_audio_debug(dev, HDMI_AHB_DMA_POL);
  231767. + hdmi_audio_debug(dev, HDMI_AHB_DMA_CONF1);
  231768. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFSTAT);
  231769. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFINT);
  231770. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFMASK);
  231771. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFPOL);
  231772. + hdmi_audio_debug(dev, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  231773. + hdmi_audio_debug(dev, HDMI_IH_AHBDMAAUD_STAT0);
  231774. + hdmi_audio_debug(dev, HDMI_IH_MUTE);
  231775. +}
  231776. +
  231777. +static void dumppriv(struct device *dev, struct hdmi_dma_priv *priv)
  231778. +{
  231779. + dev_dbg(dev, "channels = %d\n", priv->channels);
  231780. + dev_dbg(dev, "periods = %d\n", priv->periods);
  231781. + dev_dbg(dev, "period_bytes = %d\n", priv->period_bytes);
  231782. + dev_dbg(dev, "dma period_bytes = %d\n", priv->dma_period_bytes);
  231783. + dev_dbg(dev, "buffer_ratio = %d\n", priv->buffer_ratio);
  231784. + dev_dbg(dev, "hw dma buffer = 0x%08x\n", (int)priv->hw_buffer.addr);
  231785. + dev_dbg(dev, "dma buf size = %d\n", (int)priv->buffer_bytes);
  231786. + dev_dbg(dev, "sample_rate = %d\n", (int)priv->rate);
  231787. +}
  231788. +#else
  231789. +static void dumpregs(struct device *dev) {}
  231790. +static void dumppriv(struct device *dev, struct hdmi_dma_priv *priv) {}
  231791. +#endif
  231792. +
  231793. +/*
  231794. + * Conditions for DMA to work:
  231795. + * ((final_addr - initial_addr)>>2)+1) < 2k. So max period is 8k.
  231796. + * (inital_addr & 0x3) == 0
  231797. + * (final_addr & 0x3) == 0x3
  231798. + *
  231799. + * The DMA Period should be an integer multiple of the IEC 60958 audio
  231800. + * frame size, which is 768 bytes (192 * 4).
  231801. + */
  231802. +static void hdmi_dma_set_addr(int start_addr, int dma_period_bytes)
  231803. +{
  231804. + int final_addr = start_addr + dma_period_bytes - 1;
  231805. +
  231806. + hdmi_write4(start_addr, HDMI_AHB_DMA_STRADDR0);
  231807. + hdmi_write4(final_addr, HDMI_AHB_DMA_STPADDR0);
  231808. +}
  231809. +
  231810. +static void hdmi_dma_irq_set(bool set)
  231811. +{
  231812. + u8 val = hdmi_readb(HDMI_AHB_DMA_MASK);
  231813. +
  231814. + if (set)
  231815. + val |= HDMI_AHB_DMA_DONE;
  231816. + else
  231817. + val &= (u8)~HDMI_AHB_DMA_DONE;
  231818. +
  231819. + hdmi_writeb(val, HDMI_AHB_DMA_MASK);
  231820. +}
  231821. +
  231822. +static void hdmi_mask(int mask)
  231823. +{
  231824. + u8 regval = hdmi_readb(HDMI_AHB_DMA_MASK);
  231825. +
  231826. + if (mask)
  231827. + regval |= HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY;
  231828. + else
  231829. + regval &= (u8)~(HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY);
  231830. +
  231831. + hdmi_writeb(regval, HDMI_AHB_DMA_MASK);
  231832. +}
  231833. +
  231834. +static inline int odd_ones(unsigned a)
  231835. +{
  231836. + a ^= a >> 16;
  231837. + a ^= a >> 8;
  231838. + a ^= a >> 4;
  231839. + a ^= a >> 2;
  231840. + a ^= a >> 1;
  231841. +
  231842. + return a & 1;
  231843. +}
  231844. +
  231845. +/* Add frame information for one pcm subframe */
  231846. +static u32 hdmi_dma_add_frame_info(struct hdmi_dma_priv *priv,
  231847. + u32 pcm_data, int subframe_idx)
  231848. +{
  231849. + union hdmi_audio_dma_data_t subframe;
  231850. + union hdmi_audio_header_t tmp_header;
  231851. +
  231852. + subframe.U = 0;
  231853. +
  231854. + if (priv->frame_idx < 42) {
  231855. + tmp_header = iec_header;
  231856. +
  231857. + /* fill v (validity) */
  231858. + subframe.B.v = tmp_header.B.linear_pcm;
  231859. +
  231860. + /* fill c (channel status) */
  231861. + if (tmp_header.B.linear_pcm == 0)
  231862. + tmp_header.B.channel = subframe_idx + 1;
  231863. + subframe.B.c = tmp_header.U >> priv->frame_idx;
  231864. + } else {
  231865. + /* fill v (validity), c is always zero */
  231866. + subframe.B.v = iec_header.B.linear_pcm;
  231867. + }
  231868. +
  231869. + /* fill data */
  231870. + if (priv->sample_bits == 16)
  231871. + pcm_data <<= 8;
  231872. + subframe.B.data = pcm_data;
  231873. +
  231874. + /* fill p (parity) Note: Do not include b ! */
  231875. + subframe.B.p = odd_ones(subframe.U);
  231876. +
  231877. + /* fill b (start-of-block) */
  231878. + if (priv->frame_idx == 0)
  231879. + subframe.B.b = 1;
  231880. +
  231881. + return subframe.U;
  231882. +}
  231883. +
  231884. +static void init_table(int channels)
  231885. +{
  231886. + int i, map_sel, ch;
  231887. + unsigned char *p = g_packet_head_table;
  231888. + union hdmi_audio_header_t tmp_header = iec_header;
  231889. +
  231890. + for (i = 0; i < 48; i++) {
  231891. + int b = 0;
  231892. + if (i == 0)
  231893. + b = 1;
  231894. +
  231895. + for (ch = 0; ch < channels; ch++) {
  231896. + int c = 0;
  231897. + if (i < 42) {
  231898. + tmp_header.B.channel = ch + 1;
  231899. + c = (tmp_header.U >> i) & 0x1;
  231900. + }
  231901. + /* preset bit p as c */
  231902. + *p++ = (b << 4) | (c << 2) | (c << 3);
  231903. + }
  231904. + }
  231905. +
  231906. + map_sel = channels / 2;
  231907. + for (i = 0; i < 24; i++) {
  231908. + g_channel_remap_table[i] = (i / channels) * channels +
  231909. + channel_maps_cea_alsa[map_sel][i % channels];
  231910. + }
  231911. +}
  231912. +
  231913. +/* Optimization for IEC head */
  231914. +static void hdmi_dma_copy_16_c_lut(u16 *src, u32 *dst, int samples,
  231915. + u8 *lookup_table)
  231916. +{
  231917. + u32 sample, head;
  231918. + int i = 0;
  231919. +
  231920. + while (samples--) {
  231921. + /* get source sample */
  231922. + sample = src[g_channel_remap_table[i]];
  231923. +
  231924. + /* get packet header and p-bit */
  231925. + head = *lookup_table++ ^ (odd_ones(sample) << 3);
  231926. +
  231927. + /* store sample and header */
  231928. + *dst++ = (head << 24) | (sample << 8);
  231929. +
  231930. + if (++i == 24) {
  231931. + src += 24;
  231932. + i = 0;
  231933. + }
  231934. + }
  231935. +}
  231936. +
  231937. +static void hdmi_dma_copy_16_c_fast(u16 *src, u32 *dst, int samples)
  231938. +{
  231939. + u32 sample;
  231940. + int i = 0;
  231941. +
  231942. + while (samples--) {
  231943. + /* get source sample */
  231944. + sample = src[g_channel_remap_table[i]];
  231945. +
  231946. + /* store sample and p-bit */
  231947. + *dst++ = (odd_ones(sample) << (3+24)) | (sample << 8);
  231948. +
  231949. + if (++i == 24) {
  231950. + src += 24;
  231951. + i = 0;
  231952. + }
  231953. + }
  231954. +}
  231955. +
  231956. +static void hdmi_dma_copy_24_c_lut(u32 *src, u32 *dst, int samples,
  231957. + u8 *lookup_table)
  231958. +{
  231959. + u32 sample, head;
  231960. + int i = 0;
  231961. +
  231962. + while (samples--) {
  231963. + /* get source sample */
  231964. + sample = src[g_channel_remap_table[i]] & 0x00ffffff;
  231965. +
  231966. + /* get packet header and p-bit */
  231967. + head = *lookup_table++ ^ (odd_ones(sample) << 3);
  231968. +
  231969. + /* store sample and header */
  231970. + *dst++ = (head << 24) | sample;
  231971. +
  231972. + if (++i == 24) {
  231973. + src += 24;
  231974. + i = 0;
  231975. + }
  231976. + }
  231977. +}
  231978. +
  231979. +static void hdmi_dma_copy_24_c_fast(u32 *src, u32 *dst, int samples)
  231980. +{
  231981. + u32 sample;
  231982. + int i = 0;
  231983. +
  231984. + while (samples--) {
  231985. + /* get source sample */
  231986. + sample = src[g_channel_remap_table[i]] & 0x00ffffff;
  231987. +
  231988. + /* store sample and p-bit */
  231989. + *dst++ = (odd_ones(sample) << (3+24)) | sample;
  231990. +
  231991. + if (++i == 24) {
  231992. + src += 24;
  231993. + i = 0;
  231994. + }
  231995. + }
  231996. +}
  231997. +
  231998. +static void hdmi_mmap_copy(u8 *src, int samplesize, u32 *dst, int framecnt, int channelcnt)
  231999. +{
  232000. + /* split input frames into 192-frame each */
  232001. + int count_in_192 = (framecnt + 191) / 192;
  232002. + int i;
  232003. +
  232004. + typedef void (*fn_copy_lut)(u8 *src, u32 *dst, int samples, u8 *lookup_table);
  232005. + typedef void (*fn_copy_fast)(u8 *src, u32 *dst, int samples);
  232006. + fn_copy_lut copy_lut;
  232007. + fn_copy_fast copy_fast;
  232008. +
  232009. + if (samplesize == 4) {
  232010. + copy_lut = (fn_copy_lut)hdmi_dma_copy_24_c_lut;
  232011. + copy_fast = (fn_copy_fast)hdmi_dma_copy_24_c_fast;
  232012. + } else {
  232013. + copy_lut = (fn_copy_lut)hdmi_dma_copy_16_c_lut;
  232014. + copy_fast = (fn_copy_fast)hdmi_dma_copy_16_c_fast;
  232015. + }
  232016. +
  232017. + for (i = 0; i < count_in_192; i++) {
  232018. + int count, samples;
  232019. +
  232020. + /* handles frame index [0, 48) */
  232021. + count = (framecnt < 48) ? framecnt : 48;
  232022. + samples = count * channelcnt;
  232023. + copy_lut(src, dst, samples, g_packet_head_table);
  232024. + framecnt -= count;
  232025. + if (framecnt == 0)
  232026. + break;
  232027. +
  232028. + src += samples * samplesize;
  232029. + dst += samples;
  232030. +
  232031. + /* handles frame index [48, 192) */
  232032. + count = (framecnt < 192 - 48) ? framecnt : 192 - 48;
  232033. + samples = count * channelcnt;
  232034. + copy_fast(src, dst, samples);
  232035. + framecnt -= count;
  232036. + src += samples * samplesize;
  232037. + dst += samples;
  232038. + }
  232039. +}
  232040. +
  232041. +static void hdmi_dma_mmap_copy(struct snd_pcm_substream *substream,
  232042. + int offset, int count)
  232043. +{
  232044. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  232045. + struct snd_pcm_runtime *runtime = substream->runtime;
  232046. + struct hdmi_dma_priv *priv = runtime->private_data;
  232047. + struct device *dev = rtd->platform->dev;
  232048. + u32 framecount, *dst;
  232049. +
  232050. + framecount = count / (priv->sample_align * priv->channels);
  232051. +
  232052. + /* hw_buffer is the destination for pcm data plus frame info. */
  232053. + dst = (u32 *)(priv->hw_buffer.area + (offset * priv->buffer_ratio));
  232054. +
  232055. + switch (priv->format) {
  232056. + case SNDRV_PCM_FORMAT_S16_LE:
  232057. + case SNDRV_PCM_FORMAT_S24_LE:
  232058. + /* dma_buffer is the mmapped buffer we are copying pcm from. */
  232059. + hdmi_mmap_copy(runtime->dma_area + offset,
  232060. + priv->sample_align, dst, framecount, priv->channels);
  232061. + break;
  232062. + default:
  232063. + dev_err(dev, "unsupported sample format %s\n",
  232064. + snd_pcm_format_name(priv->format));
  232065. + return;
  232066. + }
  232067. +}
  232068. +
  232069. +static void hdmi_dma_data_copy(struct snd_pcm_substream *substream,
  232070. + struct hdmi_dma_priv *priv, char type)
  232071. +{
  232072. + struct snd_pcm_runtime *runtime = substream->runtime;
  232073. + unsigned long offset, count, appl_bytes, space_to_end;
  232074. +
  232075. + if (runtime->access != SNDRV_PCM_ACCESS_MMAP_INTERLEAVED)
  232076. + return;
  232077. +
  232078. + appl_bytes = frames_to_bytes(runtime, runtime->status->hw_ptr);
  232079. +
  232080. + switch (type) {
  232081. + case 'p':
  232082. + offset = (appl_bytes + 2 * priv->period_bytes) % priv->buffer_bytes;
  232083. + count = priv->period_bytes;
  232084. + space_to_end = priv->period_bytes;
  232085. + break;
  232086. + case 'b':
  232087. + offset = appl_bytes % priv->buffer_bytes;
  232088. + count = priv->buffer_bytes;
  232089. + space_to_end = priv->buffer_bytes - offset;
  232090. + break;
  232091. + default:
  232092. + return;
  232093. + }
  232094. +
  232095. + if (count <= space_to_end) {
  232096. + hdmi_dma_mmap_copy(substream, offset, count);
  232097. + } else {
  232098. + hdmi_dma_mmap_copy(substream, offset, space_to_end);
  232099. + hdmi_dma_mmap_copy(substream, 0, count - space_to_end);
  232100. + }
  232101. +}
  232102. +
  232103. +static void hdmi_sdma_callback(void *data)
  232104. +{
  232105. + struct hdmi_dma_priv *priv = (struct hdmi_dma_priv *)data;
  232106. + struct snd_pcm_substream *substream = priv->substream;
  232107. + struct snd_pcm_runtime *runtime = substream->runtime;
  232108. + unsigned long flags;
  232109. +
  232110. + spin_lock_irqsave(&priv->irq_lock, flags);
  232111. +
  232112. + if (runtime && runtime->dma_area && priv->tx_active) {
  232113. + priv->offset += priv->period_bytes;
  232114. + priv->offset %= priv->period_bytes * priv->periods;
  232115. +
  232116. + /* Copy data by period_bytes */
  232117. + hdmi_dma_data_copy(substream, priv, 'p');
  232118. +
  232119. + snd_pcm_period_elapsed(substream);
  232120. + }
  232121. +
  232122. + spin_unlock_irqrestore(&priv->irq_lock, flags);
  232123. +
  232124. + return;
  232125. +}
  232126. +
  232127. +static int hdmi_dma_set_thrsld_incrtype(struct device *dev, int channels)
  232128. +{
  232129. + u8 mask = HDMI_AHB_DMA_CONF0_BURST_MODE | HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK;
  232130. + u8 val = hdmi_readb(HDMI_AHB_DMA_CONF0) & ~mask;
  232131. + int incr_type, threshold;
  232132. +
  232133. + switch (hdmi_readb(HDMI_REVISION_ID)) {
  232134. + case 0x0a:
  232135. + incr_type = HDMI_DMA_BURST_INCR4;
  232136. + if (channels == 2)
  232137. + threshold = 126;
  232138. + else
  232139. + threshold = 124;
  232140. + break;
  232141. + case 0x1a:
  232142. + incr_type = HDMI_DMA_BURST_INCR8;
  232143. + threshold = 128;
  232144. + break;
  232145. + default:
  232146. + dev_err(dev, "unknown hdmi controller!\n");
  232147. + return -ENODEV;
  232148. + }
  232149. +
  232150. + hdmi_writeb(threshold, HDMI_AHB_DMA_THRSLD);
  232151. +
  232152. + switch (incr_type) {
  232153. + case HDMI_DMA_BURST_UNSPECIFIED_LEGNTH:
  232154. + break;
  232155. + case HDMI_DMA_BURST_INCR4:
  232156. + val |= HDMI_AHB_DMA_CONF0_BURST_MODE;
  232157. + break;
  232158. + case HDMI_DMA_BURST_INCR8:
  232159. + val |= HDMI_AHB_DMA_CONF0_BURST_MODE |
  232160. + HDMI_AHB_DMA_CONF0_INCR8;
  232161. + break;
  232162. + case HDMI_DMA_BURST_INCR16:
  232163. + val |= HDMI_AHB_DMA_CONF0_BURST_MODE |
  232164. + HDMI_AHB_DMA_CONF0_INCR16;
  232165. + break;
  232166. + default:
  232167. + dev_err(dev, "invalid increment type: %d!", incr_type);
  232168. + return -EINVAL;
  232169. + }
  232170. +
  232171. + hdmi_writeb(val, HDMI_AHB_DMA_CONF0);
  232172. +
  232173. + hdmi_audio_debug(dev, HDMI_AHB_DMA_THRSLD);
  232174. +
  232175. + return 0;
  232176. +}
  232177. +
  232178. +static int hdmi_dma_configure_dma(struct device *dev, int channels)
  232179. +{
  232180. + int ret;
  232181. + static u8 chan_enable[] = { 0x00, 0x03, 0x33, 0x3f, 0xff };
  232182. +
  232183. + if (channels <= 0 || channels > 8 || channels % 2 != 0) {
  232184. + dev_err(dev, "unsupported channel number: %d\n", channels);
  232185. + return -EINVAL;
  232186. + }
  232187. +
  232188. + hdmi_audio_writeb(AHB_DMA_CONF0, EN_HLOCK, 0x1);
  232189. +
  232190. + ret = hdmi_dma_set_thrsld_incrtype(dev, channels);
  232191. + if (ret)
  232192. + return ret;
  232193. +
  232194. + hdmi_writeb(chan_enable[channels / 2], HDMI_AHB_DMA_CONF1);
  232195. +
  232196. + return 0;
  232197. +}
  232198. +
  232199. +static void hdmi_dma_init_iec_header(void)
  232200. +{
  232201. + iec_header.U = 0;
  232202. +
  232203. + iec_header.B.consumer = 0; /* Consumer use */
  232204. + iec_header.B.linear_pcm = 0; /* linear pcm audio */
  232205. + iec_header.B.copyright = 1; /* no copyright */
  232206. + iec_header.B.pre_emphasis = 0; /* 2 channels without pre-emphasis */
  232207. + iec_header.B.mode = 0; /* Mode 0 */
  232208. +
  232209. + iec_header.B.category_code = 0;
  232210. +
  232211. + iec_header.B.source = 2; /* stereo */
  232212. + iec_header.B.channel = 0;
  232213. +
  232214. + iec_header.B.sample_freq = 0x02; /* 48 KHz */
  232215. + iec_header.B.clock_acc = 0; /* Level II */
  232216. +
  232217. + iec_header.B.word_length = 0x02; /* 16 bits */
  232218. + iec_header.B.org_sample_freq = 0x0D; /* 48 KHz */
  232219. +
  232220. + iec_header.B.cgms_a = 0; /* Copying is permitted without restriction */
  232221. +}
  232222. +
  232223. +static int hdmi_dma_update_iec_header(struct snd_pcm_substream *substream)
  232224. +{
  232225. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  232226. + struct snd_pcm_runtime *runtime = substream->runtime;
  232227. + struct hdmi_dma_priv *priv = runtime->private_data;
  232228. + struct device *dev = rtd->platform->dev;
  232229. +
  232230. + iec_header.B.source = priv->channels;
  232231. +
  232232. + switch (priv->rate) {
  232233. + case 32000:
  232234. + iec_header.B.sample_freq = 0x03;
  232235. + iec_header.B.org_sample_freq = 0x0C;
  232236. + break;
  232237. + case 44100:
  232238. + iec_header.B.sample_freq = 0x00;
  232239. + iec_header.B.org_sample_freq = 0x0F;
  232240. + break;
  232241. + case 48000:
  232242. + iec_header.B.sample_freq = 0x02;
  232243. + iec_header.B.org_sample_freq = 0x0D;
  232244. + break;
  232245. + case 88200:
  232246. + iec_header.B.sample_freq = 0x08;
  232247. + iec_header.B.org_sample_freq = 0x07;
  232248. + break;
  232249. + case 96000:
  232250. + iec_header.B.sample_freq = 0x0A;
  232251. + iec_header.B.org_sample_freq = 0x05;
  232252. + break;
  232253. + case 176400:
  232254. + iec_header.B.sample_freq = 0x0C;
  232255. + iec_header.B.org_sample_freq = 0x03;
  232256. + break;
  232257. + case 192000:
  232258. + iec_header.B.sample_freq = 0x0E;
  232259. + iec_header.B.org_sample_freq = 0x01;
  232260. + break;
  232261. + default:
  232262. + dev_err(dev, "unsupported sample rate\n");
  232263. + return -EFAULT;
  232264. + }
  232265. +
  232266. + switch (priv->format) {
  232267. + case SNDRV_PCM_FORMAT_S16_LE:
  232268. + iec_header.B.word_length = 0x02;
  232269. + break;
  232270. + case SNDRV_PCM_FORMAT_S24_LE:
  232271. + iec_header.B.word_length = 0x0b;
  232272. + break;
  232273. + default:
  232274. + return -EFAULT;
  232275. + }
  232276. +
  232277. + return 0;
  232278. +}
  232279. +
  232280. +/*
  232281. + * The HDMI block transmits the audio data without adding any of the audio
  232282. + * frame bits. So we have to copy the raw dma data from the ALSA buffer
  232283. + * to the DMA buffer, adding the frame information.
  232284. + */
  232285. +static int hdmi_dma_copy(struct snd_pcm_substream *substream, int channel,
  232286. + snd_pcm_uframes_t pos, void __user *buf,
  232287. + snd_pcm_uframes_t frames)
  232288. +{
  232289. + struct snd_pcm_runtime *runtime = substream->runtime;
  232290. + struct hdmi_dma_priv *priv = runtime->private_data;
  232291. + unsigned int count = frames_to_bytes(runtime, frames);
  232292. + unsigned int pos_bytes = frames_to_bytes(runtime, pos);
  232293. + int channel_no, pcm_idx, subframe_idx, bits_left, sample_bits, map_sel;
  232294. + u32 pcm_data[8], pcm_temp, *hw_buf, sample_block, inc_mask;
  232295. +
  232296. + /* Adding frame info to pcm data from userspace and copy to hw_buffer */
  232297. + hw_buf = (u32 *)(priv->hw_buffer.area + (pos_bytes * priv->buffer_ratio));
  232298. +
  232299. + sample_bits = priv->sample_align * 8;
  232300. + sample_block = priv->sample_align * priv->channels;
  232301. +
  232302. + if (iec_header.B.linear_pcm == 0) {
  232303. + map_sel = priv->channels / 2;
  232304. + inc_mask = 1 << (priv->channels - 1);
  232305. + } else {
  232306. + map_sel = 0;
  232307. + inc_mask = 0xaa;
  232308. + }
  232309. +
  232310. + while (count > 0) {
  232311. + if (copy_from_user(pcm_data, buf, sample_block))
  232312. + return -EFAULT;
  232313. +
  232314. + buf += sample_block;
  232315. + count -= sample_block;
  232316. +
  232317. + channel_no = pcm_idx = 0;
  232318. + do {
  232319. + pcm_temp = pcm_data[pcm_idx++];
  232320. + bits_left = 32;
  232321. + for (;;) {
  232322. + /* re-map channels */
  232323. + subframe_idx = channel_maps_alsa_cea[map_sel][channel_no];
  232324. +
  232325. + /* Save the header info to the audio dma buffer */
  232326. + hw_buf[subframe_idx] = hdmi_dma_add_frame_info(
  232327. + priv, pcm_temp, subframe_idx);
  232328. +
  232329. + if (inc_mask & (1 << channel_no)) {
  232330. + if (++priv->frame_idx == 192)
  232331. + priv->frame_idx = 0;
  232332. + }
  232333. +
  232334. + channel_no++;
  232335. +
  232336. + if (bits_left <= sample_bits)
  232337. + break;
  232338. +
  232339. + bits_left -= sample_bits;
  232340. + pcm_temp >>= sample_bits;
  232341. + }
  232342. + } while (channel_no < priv->channels);
  232343. +
  232344. + hw_buf += priv->channels;
  232345. + }
  232346. +
  232347. + return 0;
  232348. +}
  232349. +
  232350. +static int hdmi_sdma_initbuf(struct device *dev, struct hdmi_dma_priv *priv)
  232351. +{
  232352. + struct hdmi_sdma_script *hdmi_sdma_t = priv->hdmi_sdma_t;
  232353. + u32 *head, *tail, i;
  232354. +
  232355. + if (!hdmi_sdma_t) {
  232356. + dev_err(dev, "hdmi private addr invalid!!!\n");
  232357. + return -EINVAL;
  232358. + }
  232359. +
  232360. + hdmi_sdma_t->control_reg_addr = HDMI_BASE_ADDR + HDMI_AHB_DMA_START;
  232361. + hdmi_sdma_t->status_reg_addr = HDMI_BASE_ADDR + HDMI_IH_AHBDMAAUD_STAT0;
  232362. + hdmi_sdma_t->dma_start_addr = HDMI_BASE_ADDR + HDMI_AHB_DMA_STRADDR0;
  232363. +
  232364. + head = &hdmi_sdma_t->buffer[0];
  232365. + tail = &hdmi_sdma_t->buffer[1];
  232366. +
  232367. + for (i = 0; i < priv->sdma_params.buffer_num; i++) {
  232368. + *head = priv->hw_buffer.addr + i * priv->period_bytes * priv->buffer_ratio;
  232369. + *tail = *head + priv->dma_period_bytes - 1;
  232370. + head += 2;
  232371. + tail += 2;
  232372. + }
  232373. +
  232374. + return 0;
  232375. +}
  232376. +
  232377. +static int hdmi_sdma_config(struct snd_pcm_substream *substream,
  232378. + struct hdmi_dma_priv *priv)
  232379. +{
  232380. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  232381. + struct device *dai_dev = &priv->pdev->dev;
  232382. + struct device *dev = rtd->platform->dev;
  232383. + struct dma_slave_config slave_config;
  232384. + int ret;
  232385. +
  232386. + priv->dma_channel = dma_request_slave_channel(dai_dev, "tx");
  232387. + if (priv->dma_channel == NULL) {
  232388. + dev_err(dev, "failed to alloc dma channel\n");
  232389. + return -EBUSY;
  232390. + }
  232391. +
  232392. + priv->dma_data.data_addr1 = &priv->sdma_params.buffer_num;
  232393. + priv->dma_data.data_addr2 = &priv->sdma_params.phyaddr;
  232394. + priv->dma_channel->private = &priv->dma_data;
  232395. +
  232396. + slave_config.direction = DMA_TRANS_NONE;
  232397. + slave_config.dma_request0 = 0;
  232398. + slave_config.dma_request1 = 0;
  232399. +
  232400. + ret = dmaengine_slave_config(priv->dma_channel, &slave_config);
  232401. + if (ret) {
  232402. + dev_err(dev, "failed to config slave dma\n");
  232403. + return -EINVAL;
  232404. + }
  232405. +
  232406. + return 0;
  232407. +}
  232408. +
  232409. +static int hdmi_dma_hw_free(struct snd_pcm_substream *substream)
  232410. +{
  232411. + struct snd_pcm_runtime *runtime = substream->runtime;
  232412. + struct hdmi_dma_priv *priv = runtime->private_data;
  232413. +
  232414. + if (priv->dma_channel) {
  232415. + dma_release_channel(priv->dma_channel);
  232416. + priv->dma_channel = NULL;
  232417. + }
  232418. +
  232419. + return 0;
  232420. +}
  232421. +
  232422. +static int hdmi_dma_hw_params(struct snd_pcm_substream *substream,
  232423. + struct snd_pcm_hw_params *params)
  232424. +{
  232425. + struct snd_pcm_runtime *runtime = substream->runtime;
  232426. + struct hdmi_dma_priv *priv = runtime->private_data;
  232427. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  232428. + struct device *dev = rtd->platform->dev;
  232429. + int ret;
  232430. +
  232431. + priv->buffer_bytes = params_buffer_bytes(params);
  232432. + priv->periods = params_periods(params);
  232433. + priv->period_bytes = params_period_bytes(params);
  232434. + priv->channels = params_channels(params);
  232435. + priv->format = params_format(params);
  232436. + priv->rate = params_rate(params);
  232437. +
  232438. + priv->offset = 0;
  232439. + priv->period_time = HZ / (priv->rate / params_period_size(params));
  232440. +
  232441. + switch (priv->format) {
  232442. + case SNDRV_PCM_FORMAT_S16_LE:
  232443. + priv->buffer_ratio = 2;
  232444. + priv->sample_align = 2;
  232445. + priv->sample_bits = 16;
  232446. + break;
  232447. + case SNDRV_PCM_FORMAT_S24_LE:
  232448. + /* 24 bit audio in 32 bit word */
  232449. + priv->buffer_ratio = 1;
  232450. + priv->sample_align = 4;
  232451. + priv->sample_bits = 24;
  232452. + break;
  232453. + default:
  232454. + dev_err(dev, "unsupported sample format: %d\n", priv->format);
  232455. + return -EINVAL;
  232456. + }
  232457. +
  232458. + priv->dma_period_bytes = priv->period_bytes * priv->buffer_ratio;
  232459. + priv->sdma_params.buffer_num = priv->periods;
  232460. + priv->sdma_params.phyaddr = priv->phy_hdmi_sdma_t;
  232461. +
  232462. + ret = hdmi_sdma_initbuf(dev, priv);
  232463. + if (ret)
  232464. + return ret;
  232465. +
  232466. + ret = hdmi_sdma_config(substream, priv);
  232467. + if (ret)
  232468. + return ret;
  232469. +
  232470. + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
  232471. +
  232472. + ret = hdmi_dma_configure_dma(dev, priv->channels);
  232473. + if (ret)
  232474. + return ret;
  232475. +
  232476. + hdmi_dma_set_addr(priv->hw_buffer.addr, priv->dma_period_bytes);
  232477. +
  232478. + dumppriv(dev, priv);
  232479. +
  232480. + hdmi_dma_update_iec_header(substream);
  232481. +
  232482. + /* Init par for mmap optimizate */
  232483. + init_table(priv->channels);
  232484. +
  232485. + priv->appl_bytes = 0;
  232486. + priv->frame_idx = 0;
  232487. +
  232488. + return 0;
  232489. +}
  232490. +
  232491. +static void hdmi_dma_trigger_init(struct snd_pcm_substream *substream,
  232492. + struct hdmi_dma_priv *priv)
  232493. +{
  232494. + unsigned long status;
  232495. + bool hbr;
  232496. +
  232497. + /*
  232498. + * Set HBR mode (>192kHz IEC-61937 HD audio bitstreaming).
  232499. + * This is done this late because userspace may alter the AESx
  232500. + * parameters until the stream is finally prepared.
  232501. + */
  232502. + hbr = (iec_header.B.linear_pcm != 0 && priv->channels == 8);
  232503. + hdmi_audio_writeb(AHB_DMA_CONF0, HBR, !!hbr);
  232504. +
  232505. + /*
  232506. + * Override AES3 - parameter: This is a temporary hack for
  232507. + * callers that provide incorrect information when opening
  232508. + * the device. 0x09 (i.e. 768K) is the only acceptable value.
  232509. + */
  232510. + if (hbr) {
  232511. + iec_header.B.sample_freq = 0x09;
  232512. + iec_header.B.org_sample_freq = 0x00;
  232513. + }
  232514. +
  232515. + priv->offset = 0;
  232516. +
  232517. + /* Copy data by buffer_bytes */
  232518. + hdmi_dma_data_copy(substream, priv, 'b');
  232519. +
  232520. + hdmi_audio_writeb(AHB_DMA_CONF0, SW_FIFO_RST, 0x1);
  232521. +
  232522. + /* Delay after reset */
  232523. + udelay(1);
  232524. +
  232525. + status = hdmi_readb(HDMI_IH_AHBDMAAUD_STAT0);
  232526. + hdmi_writeb(status, HDMI_IH_AHBDMAAUD_STAT0);
  232527. +}
  232528. +
  232529. +static int hdmi_dma_prepare_and_submit(struct snd_pcm_substream *substream,
  232530. + struct hdmi_dma_priv *priv)
  232531. +{
  232532. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  232533. + struct device *dev = rtd->platform->dev;
  232534. +
  232535. + priv->desc = dmaengine_prep_dma_cyclic(priv->dma_channel, 0, 0, 0,
  232536. + DMA_TRANS_NONE, 0);
  232537. + if (!priv->desc) {
  232538. + dev_err(dev, "failed to prepare slave dma\n");
  232539. + return -EINVAL;
  232540. + }
  232541. +
  232542. + priv->desc->callback = hdmi_sdma_callback;
  232543. + priv->desc->callback_param = (void *)priv;
  232544. + dmaengine_submit(priv->desc);
  232545. +
  232546. + return 0;
  232547. +}
  232548. +
  232549. +static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd)
  232550. +{
  232551. + struct snd_pcm_runtime *runtime = substream->runtime;
  232552. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  232553. + struct hdmi_dma_priv *priv = runtime->private_data;
  232554. + struct device *dev = rtd->platform->dev;
  232555. + int ret;
  232556. +
  232557. + switch (cmd) {
  232558. + case SNDRV_PCM_TRIGGER_START:
  232559. + case SNDRV_PCM_TRIGGER_RESUME:
  232560. + if (!check_hdmi_state())
  232561. + return 0;
  232562. + hdmi_dma_trigger_init(substream, priv);
  232563. +
  232564. + dumpregs(dev);
  232565. +
  232566. + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  232567. + priv->tx_active = true;
  232568. + hdmi_audio_writeb(AHB_DMA_START, START, 0x1);
  232569. + hdmi_dma_irq_set(false);
  232570. + hdmi_set_dma_mode(1);
  232571. + ret = hdmi_dma_prepare_and_submit(substream, priv);
  232572. + if (ret)
  232573. + return ret;
  232574. + dma_async_issue_pending(priv->desc->chan);
  232575. + break;
  232576. + case SNDRV_PCM_TRIGGER_STOP:
  232577. + case SNDRV_PCM_TRIGGER_SUSPEND:
  232578. + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  232579. + dmaengine_terminate_all(priv->dma_channel);
  232580. + hdmi_set_dma_mode(0);
  232581. + hdmi_dma_irq_set(true);
  232582. + hdmi_audio_writeb(AHB_DMA_STOP, STOP, 0x1);
  232583. + priv->tx_active = false;
  232584. + break;
  232585. + default:
  232586. + return -EINVAL;
  232587. + }
  232588. +
  232589. + return 0;
  232590. +}
  232591. +
  232592. +static snd_pcm_uframes_t hdmi_dma_pointer(struct snd_pcm_substream *substream)
  232593. +{
  232594. + struct snd_pcm_runtime *runtime = substream->runtime;
  232595. + struct hdmi_dma_priv *priv = runtime->private_data;
  232596. +
  232597. + return bytes_to_frames(runtime, priv->offset);
  232598. +}
  232599. +
  232600. +static struct snd_pcm_hardware snd_imx_hardware = {
  232601. + .info = SNDRV_PCM_INFO_INTERLEAVED |
  232602. + SNDRV_PCM_INFO_BLOCK_TRANSFER |
  232603. + SNDRV_PCM_INFO_MMAP |
  232604. + SNDRV_PCM_INFO_MMAP_VALID |
  232605. + SNDRV_PCM_INFO_PAUSE |
  232606. + SNDRV_PCM_INFO_RESUME,
  232607. + .formats = MXC_HDMI_FORMATS_PLAYBACK,
  232608. + .rate_min = 32000,
  232609. + .channels_min = 2,
  232610. + .channels_max = 8,
  232611. + .buffer_bytes_max = HDMI_PCM_BUF_SIZE,
  232612. + .period_bytes_min = HDMI_DMA_PERIOD_BYTES / 2,
  232613. + .period_bytes_max = HDMI_DMA_PERIOD_BYTES / 2,
  232614. + .periods_min = 8,
  232615. + .periods_max = HDMI_DMA_BUF_SIZE / HDMI_DMA_PERIOD_BYTES,
  232616. + .fifo_size = 0,
  232617. +};
  232618. +
  232619. +static void hdmi_dma_irq_enable(struct hdmi_dma_priv *priv)
  232620. +{
  232621. + unsigned long flags;
  232622. +
  232623. + hdmi_writeb(0xff, HDMI_AHB_DMA_POL);
  232624. + hdmi_writeb(0xff, HDMI_AHB_DMA_BUFFPOL);
  232625. +
  232626. + spin_lock_irqsave(&priv->irq_lock, flags);
  232627. +
  232628. + hdmi_writeb(0xff, HDMI_IH_AHBDMAAUD_STAT0);
  232629. + hdmi_writeb(0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  232630. + hdmi_dma_irq_set(false);
  232631. + hdmi_mask(0);
  232632. +
  232633. + spin_unlock_irqrestore(&priv->irq_lock, flags);
  232634. +}
  232635. +
  232636. +static void hdmi_dma_irq_disable(struct hdmi_dma_priv *priv)
  232637. +{
  232638. + unsigned long flags;
  232639. +
  232640. + spin_lock_irqsave(&priv->irq_lock, flags);
  232641. +
  232642. + hdmi_dma_irq_set(true);
  232643. + hdmi_writeb(0x0, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  232644. + hdmi_writeb(0xff, HDMI_IH_AHBDMAAUD_STAT0);
  232645. + hdmi_mask(1);
  232646. +
  232647. + spin_unlock_irqrestore(&priv->irq_lock, flags);
  232648. +}
  232649. +
  232650. +static int hdmi_dma_open(struct snd_pcm_substream *substream)
  232651. +{
  232652. + struct snd_pcm_runtime *runtime = substream->runtime;
  232653. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  232654. + struct device *dev = rtd->platform->dev;
  232655. + struct hdmi_dma_priv *priv = dev_get_drvdata(dev);
  232656. + int ret;
  232657. +
  232658. + runtime->private_data = priv;
  232659. +
  232660. + ret = mxc_hdmi_register_audio(substream);
  232661. + if (ret < 0) {
  232662. + dev_err(dev, "HDMI Video is not ready!\n");
  232663. + return ret;
  232664. + }
  232665. +
  232666. + hdmi_audio_writeb(AHB_DMA_CONF0, SW_FIFO_RST, 0x1);
  232667. +
  232668. + ret = snd_pcm_hw_constraint_integer(substream->runtime,
  232669. + SNDRV_PCM_HW_PARAM_PERIODS);
  232670. + if (ret < 0)
  232671. + return ret;
  232672. +
  232673. + snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
  232674. +
  232675. + hdmi_dma_irq_enable(priv);
  232676. +
  232677. + return 0;
  232678. +}
  232679. +
  232680. +static int hdmi_dma_close(struct snd_pcm_substream *substream)
  232681. +{
  232682. + struct snd_pcm_runtime *runtime = substream->runtime;
  232683. + struct hdmi_dma_priv *priv = runtime->private_data;
  232684. +
  232685. + hdmi_dma_irq_disable(priv);
  232686. + mxc_hdmi_unregister_audio(substream);
  232687. +
  232688. + return 0;
  232689. +}
  232690. +
  232691. +static struct snd_pcm_ops imx_hdmi_dma_pcm_ops = {
  232692. + .open = hdmi_dma_open,
  232693. + .close = hdmi_dma_close,
  232694. + .ioctl = snd_pcm_lib_ioctl,
  232695. + .hw_params = hdmi_dma_hw_params,
  232696. + .hw_free = hdmi_dma_hw_free,
  232697. + .trigger = hdmi_dma_trigger,
  232698. + .pointer = hdmi_dma_pointer,
  232699. + .copy = hdmi_dma_copy,
  232700. +};
  232701. +
  232702. +static int imx_hdmi_dma_pcm_new(struct snd_soc_pcm_runtime *rtd)
  232703. +{
  232704. + struct hdmi_dma_priv *priv = dev_get_drvdata(rtd->platform->dev);
  232705. + struct snd_card *card = rtd->card->snd_card;
  232706. + struct snd_pcm_substream *substream;
  232707. + struct snd_pcm *pcm = rtd->pcm;
  232708. + u64 dma_mask = DMA_BIT_MASK(32);
  232709. + int ret = 0;
  232710. +
  232711. + if (!card->dev->dma_mask)
  232712. + card->dev->dma_mask = &dma_mask;
  232713. + if (!card->dev->coherent_dma_mask)
  232714. + card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  232715. +
  232716. + substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
  232717. +
  232718. + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
  232719. + HDMI_PCM_BUF_SIZE, &substream->dma_buffer);
  232720. + if (ret) {
  232721. + dev_err(card->dev, "failed to alloc playback dma buffer\n");
  232722. + return ret;
  232723. + }
  232724. +
  232725. + priv->substream = substream;
  232726. +
  232727. + /* Alloc the hw_buffer */
  232728. + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
  232729. + HDMI_DMA_BUF_SIZE, &priv->hw_buffer);
  232730. + if (ret) {
  232731. + dev_err(card->dev, "failed to alloc hw dma buffer\n");
  232732. + return ret;
  232733. + }
  232734. +
  232735. + return ret;
  232736. +}
  232737. +
  232738. +static void imx_hdmi_dma_pcm_free(struct snd_pcm *pcm)
  232739. +{
  232740. + int stream = SNDRV_PCM_STREAM_PLAYBACK;
  232741. + struct snd_pcm_substream *substream = pcm->streams[stream].substream;
  232742. + struct snd_soc_pcm_runtime *rtd = pcm->private_data;
  232743. + struct hdmi_dma_priv *priv = dev_get_drvdata(rtd->platform->dev);
  232744. +
  232745. + if (substream) {
  232746. + snd_dma_free_pages(&substream->dma_buffer);
  232747. + substream->dma_buffer.area = NULL;
  232748. + substream->dma_buffer.addr = 0;
  232749. + }
  232750. +
  232751. + /* Free the hw_buffer */
  232752. + snd_dma_free_pages(&priv->hw_buffer);
  232753. + priv->hw_buffer.area = NULL;
  232754. + priv->hw_buffer.addr = 0;
  232755. +}
  232756. +
  232757. +static struct snd_soc_platform_driver imx_hdmi_platform = {
  232758. + .ops = &imx_hdmi_dma_pcm_ops,
  232759. + .pcm_new = imx_hdmi_dma_pcm_new,
  232760. + .pcm_free = imx_hdmi_dma_pcm_free,
  232761. +};
  232762. +
  232763. +static int imx_soc_platform_probe(struct platform_device *pdev)
  232764. +{
  232765. + struct imx_hdmi *hdmi_drvdata = platform_get_drvdata(pdev);
  232766. + struct hdmi_dma_priv *priv;
  232767. + int ret = 0;
  232768. +
  232769. + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  232770. + if (!priv) {
  232771. + dev_err(&pdev->dev, "Failed to alloc hdmi_dma\n");
  232772. + return -ENOMEM;
  232773. + }
  232774. +
  232775. + priv->hdmi_sdma_t = dma_alloc_coherent(NULL,
  232776. + sizeof(struct hdmi_sdma_script),
  232777. + &priv->phy_hdmi_sdma_t, GFP_KERNEL);
  232778. + if (!priv->hdmi_sdma_t) {
  232779. + dev_err(&pdev->dev, "Failed to alloc hdmi_sdma_t\n");
  232780. + return -ENOMEM;
  232781. + }
  232782. +
  232783. + priv->tx_active = false;
  232784. + spin_lock_init(&priv->irq_lock);
  232785. +
  232786. + priv->pdev = hdmi_drvdata->pdev;
  232787. +
  232788. + hdmi_dma_init_iec_header();
  232789. +
  232790. + dev_set_drvdata(&pdev->dev, priv);
  232791. +
  232792. + switch (hdmi_readb(HDMI_REVISION_ID)) {
  232793. + case 0x0a:
  232794. + snd_imx_hardware.period_bytes_max = HDMI_DMA_PERIOD_BYTES / 4;
  232795. + snd_imx_hardware.period_bytes_min = HDMI_DMA_PERIOD_BYTES / 4;
  232796. + snd_imx_hardware.periods_max = HDMI_DMA_BUF_SIZE / (HDMI_DMA_PERIOD_BYTES / 2);
  232797. + break;
  232798. + default:
  232799. + break;
  232800. + }
  232801. +
  232802. + ret = snd_soc_register_platform(&pdev->dev, &imx_hdmi_platform);
  232803. + if (ret)
  232804. + goto err_plat;
  232805. +
  232806. + return 0;
  232807. +
  232808. +err_plat:
  232809. + dma_free_coherent(NULL, sizeof(struct hdmi_sdma_script),
  232810. + priv->hdmi_sdma_t, priv->phy_hdmi_sdma_t);
  232811. +
  232812. + return ret;
  232813. +}
  232814. +
  232815. +static int imx_soc_platform_remove(struct platform_device *pdev)
  232816. +{
  232817. + struct hdmi_dma_priv *priv = dev_get_drvdata(&pdev->dev);
  232818. +
  232819. + dma_free_coherent(NULL, sizeof(struct hdmi_sdma_script),
  232820. + priv->hdmi_sdma_t, priv->phy_hdmi_sdma_t);
  232821. +
  232822. + snd_soc_unregister_platform(&pdev->dev);
  232823. +
  232824. + return 0;
  232825. +}
  232826. +
  232827. +static struct platform_driver imx_hdmi_dma_driver = {
  232828. + .driver = {
  232829. + .name = "imx-hdmi-audio",
  232830. + .owner = THIS_MODULE,
  232831. + },
  232832. + .probe = imx_soc_platform_probe,
  232833. + .remove = imx_soc_platform_remove,
  232834. +};
  232835. +
  232836. +module_platform_driver(imx_hdmi_dma_driver);
  232837. +
  232838. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  232839. +MODULE_DESCRIPTION("i.MX HDMI audio DMA");
  232840. +MODULE_LICENSE("GPL");
  232841. diff -Nur linux-3.14.14/sound/soc/fsl/imx-hdmi.h linux-imx6-3.14/sound/soc/fsl/imx-hdmi.h
  232842. --- linux-3.14.14/sound/soc/fsl/imx-hdmi.h 1969-12-31 18:00:00.000000000 -0600
  232843. +++ linux-imx6-3.14/sound/soc/fsl/imx-hdmi.h 2014-12-08 00:31:56.116418001 -0600
  232844. @@ -0,0 +1,105 @@
  232845. +/*
  232846. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  232847. + *
  232848. + * This program is free software; you can redistribute it and/or modify
  232849. + * it under the terms of the GNU General Public License as published by
  232850. + * the Free Software Foundation; either version 2 of the License, or
  232851. + * (at your option) any later version.
  232852. + *
  232853. + * This program is distributed in the hope that it will be useful,
  232854. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  232855. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  232856. + * GNU General Public License for more details.
  232857. + *
  232858. + * You should have received a copy of the GNU General Public License along
  232859. + * with this program; if not, write to the Free Software Foundation, Inc.,
  232860. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  232861. + */
  232862. +
  232863. +#ifndef __IMX_HDMI_H
  232864. +#define __IMX_HDMI_H
  232865. +
  232866. +struct imx_hdmi_sdma_params {
  232867. + dma_addr_t phyaddr;
  232868. + u32 buffer_num;
  232869. + int dma;
  232870. +};
  232871. +
  232872. +struct imx_hdmi {
  232873. + struct snd_soc_dai_driver cpu_dai_drv;
  232874. + struct platform_device *codec_dev;
  232875. + struct platform_device *dma_dev;
  232876. + struct platform_device *pdev;
  232877. + struct clk *isfr_clk;
  232878. + struct clk *iahb_clk;
  232879. +};
  232880. +
  232881. +#define HDMI_MAX_RATES 7
  232882. +#define HDMI_MAX_SAMPLE_SIZE 3
  232883. +#define HDMI_MAX_CHANNEL_CONSTRAINTS 4
  232884. +
  232885. +#define MXC_HDMI_RATES_PLAYBACK \
  232886. + (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
  232887. + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
  232888. + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
  232889. +
  232890. +#define MXC_HDMI_FORMATS_PLAYBACK \
  232891. + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
  232892. +
  232893. +union hdmi_audio_header_t {
  232894. + uint64_t U;
  232895. + struct {
  232896. + unsigned consumer:1;
  232897. + unsigned linear_pcm:1;
  232898. + unsigned copyright:1;
  232899. + unsigned pre_emphasis:3;
  232900. + unsigned mode:2;
  232901. +
  232902. + unsigned category_code:8;
  232903. +
  232904. + unsigned source:4;
  232905. + unsigned channel:4;
  232906. +
  232907. + unsigned sample_freq:4;
  232908. + unsigned clock_acc:2;
  232909. + unsigned reserved0:2;
  232910. +
  232911. + unsigned word_length:4;
  232912. + unsigned org_sample_freq:4;
  232913. +
  232914. + unsigned cgms_a:2;
  232915. + unsigned reserved1:6;
  232916. +
  232917. + unsigned reserved2:8;
  232918. +
  232919. + unsigned reserved3:8;
  232920. + } B;
  232921. + unsigned char status[8];
  232922. +};
  232923. +
  232924. +union hdmi_audio_dma_data_t {
  232925. + uint32_t U;
  232926. + struct {
  232927. + unsigned data:24;
  232928. + unsigned v:1;
  232929. + unsigned u:1;
  232930. + unsigned c:1;
  232931. + unsigned p:1;
  232932. + unsigned b:1;
  232933. + unsigned reserved:3;
  232934. + } B;
  232935. +};
  232936. +
  232937. +extern union hdmi_audio_header_t iec_header;
  232938. +
  232939. +#define hdmi_audio_writeb(reg, bit, val) \
  232940. + do { \
  232941. + hdmi_mask_writeb(val, HDMI_ ## reg, \
  232942. + HDMI_ ## reg ## _ ## bit ## _OFFSET, \
  232943. + HDMI_ ## reg ## _ ## bit ## _MASK); \
  232944. + pr_debug("Set reg: HDMI_" #reg " (0x%x) "\
  232945. + "bit: HDMI_" #reg "_" #bit " (%d) to val: %x\n", \
  232946. + HDMI_ ## reg, HDMI_ ## reg ## _ ## bit ## _OFFSET, val); \
  232947. + } while (0)
  232948. +
  232949. +#endif /* __IMX_HDMI_H */
  232950. diff -Nur linux-3.14.14/sound/soc/fsl/imx-pcm-dma.c linux-imx6-3.14/sound/soc/fsl/imx-pcm-dma.c
  232951. --- linux-3.14.14/sound/soc/fsl/imx-pcm-dma.c 2014-07-28 10:07:25.000000000 -0500
  232952. +++ linux-imx6-3.14/sound/soc/fsl/imx-pcm-dma.c 2014-12-08 00:31:56.116418001 -0600
  232953. @@ -11,6 +11,10 @@
  232954. * Free Software Foundation; either version 2 of the License, or (at your
  232955. * option) any later version.
  232956. */
  232957. +#include <linux/init.h>
  232958. +#include <linux/kernel.h>
  232959. +#include <linux/module.h>
  232960. +#include <linux/device.h>
  232961. #include <linux/platform_device.h>
  232962. #include <linux/dmaengine.h>
  232963. #include <linux/types.h>
  232964. @@ -20,6 +24,7 @@
  232965. #include <sound/pcm.h>
  232966. #include <sound/soc.h>
  232967. #include <sound/dmaengine_pcm.h>
  232968. +#include <linux/platform_data/dma-imx.h>
  232969. #include "imx-pcm.h"
  232970. @@ -40,28 +45,97 @@
  232971. SNDRV_PCM_INFO_MMAP_VALID |
  232972. SNDRV_PCM_INFO_PAUSE |
  232973. SNDRV_PCM_INFO_RESUME,
  232974. - .formats = SNDRV_PCM_FMTBIT_S16_LE,
  232975. - .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
  232976. + .formats = SNDRV_PCM_FMTBIT_S16_LE |
  232977. + SNDRV_PCM_FMTBIT_S24_LE |
  232978. + SNDRV_PCM_FMTBIT_S20_3LE,
  232979. + .buffer_bytes_max = IMX_DEFAULT_DMABUF_SIZE,
  232980. .period_bytes_min = 128,
  232981. .period_bytes_max = 65535, /* Limited by SDMA engine */
  232982. - .periods_min = 2,
  232983. + .periods_min = 4,
  232984. .periods_max = 255,
  232985. .fifo_size = 0,
  232986. };
  232987. +static void imx_pcm_dma_set_config_from_dai_data(
  232988. + const struct snd_pcm_substream *substream,
  232989. + const struct snd_dmaengine_dai_dma_data *dma_data,
  232990. + struct dma_slave_config *slave_config)
  232991. +{
  232992. + struct imx_dma_data *filter_data = dma_data->filter_data;
  232993. +
  232994. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  232995. + slave_config->dst_addr = dma_data->addr;
  232996. + slave_config->dst_maxburst = dma_data->maxburst;
  232997. + if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
  232998. + slave_config->dst_addr_width = dma_data->addr_width;
  232999. + } else {
  233000. + slave_config->src_addr = dma_data->addr;
  233001. + slave_config->src_maxburst = dma_data->maxburst;
  233002. + if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
  233003. + slave_config->src_addr_width = dma_data->addr_width;
  233004. + }
  233005. +
  233006. + slave_config->slave_id = dma_data->slave_id;
  233007. +
  233008. + /*
  233009. + * In dma binding mode, there is no filter_data, so dma_request need to be
  233010. + * set to zero.
  233011. + */
  233012. + if (filter_data) {
  233013. + slave_config->dma_request0 = filter_data->dma_request0;
  233014. + slave_config->dma_request1 = filter_data->dma_request1;
  233015. + } else {
  233016. + slave_config->dma_request0 = 0;
  233017. + slave_config->dma_request1 = 0;
  233018. + }
  233019. +}
  233020. +
  233021. +static int imx_pcm_dma_prepare_slave_config(struct snd_pcm_substream *substream,
  233022. + struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config)
  233023. +{
  233024. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  233025. + struct snd_dmaengine_dai_dma_data *dma_data;
  233026. + int ret;
  233027. +
  233028. + dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
  233029. +
  233030. + ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
  233031. + if (ret)
  233032. + return ret;
  233033. +
  233034. + imx_pcm_dma_set_config_from_dai_data(substream, dma_data,
  233035. + slave_config);
  233036. +
  233037. + return 0;
  233038. +}
  233039. +
  233040. static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = {
  233041. .pcm_hardware = &imx_pcm_hardware,
  233042. - .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
  233043. + .prepare_slave_config = imx_pcm_dma_prepare_slave_config,
  233044. .compat_filter_fn = filter,
  233045. - .prealloc_buffer_size = IMX_SSI_DMABUF_SIZE,
  233046. + .prealloc_buffer_size = IMX_DEFAULT_DMABUF_SIZE,
  233047. };
  233048. -int imx_pcm_dma_init(struct platform_device *pdev)
  233049. +int imx_pcm_dma_init(struct platform_device *pdev, unsigned int flags, size_t size)
  233050. {
  233051. - return devm_snd_dmaengine_pcm_register(&pdev->dev,
  233052. - &imx_dmaengine_pcm_config,
  233053. - SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
  233054. - SND_DMAENGINE_PCM_FLAG_COMPAT);
  233055. + struct snd_dmaengine_pcm_config *config;
  233056. + struct snd_pcm_hardware *pcm_hardware;
  233057. +
  233058. + config = devm_kzalloc(&pdev->dev,
  233059. + sizeof(struct snd_dmaengine_pcm_config), GFP_KERNEL);
  233060. + *config = imx_dmaengine_pcm_config;
  233061. + if (size)
  233062. + config->prealloc_buffer_size = size;
  233063. +
  233064. + pcm_hardware = devm_kzalloc(&pdev->dev,
  233065. + sizeof(struct snd_pcm_hardware), GFP_KERNEL);
  233066. + *pcm_hardware = imx_pcm_hardware;
  233067. + if (size)
  233068. + pcm_hardware->buffer_bytes_max = size;
  233069. +
  233070. + config->pcm_hardware = pcm_hardware;
  233071. +
  233072. + return devm_snd_dmaengine_pcm_register(&pdev->dev, config, flags);
  233073. }
  233074. EXPORT_SYMBOL_GPL(imx_pcm_dma_init);
  233075. diff -Nur linux-3.14.14/sound/soc/fsl/imx-pcm.h linux-imx6-3.14/sound/soc/fsl/imx-pcm.h
  233076. --- linux-3.14.14/sound/soc/fsl/imx-pcm.h 2014-07-28 10:07:25.000000000 -0500
  233077. +++ linux-imx6-3.14/sound/soc/fsl/imx-pcm.h 2014-12-08 00:31:56.116418001 -0600
  233078. @@ -18,13 +18,17 @@
  233079. /*
  233080. * Do not change this as the FIQ handler depends on this size
  233081. */
  233082. +#define IMX_DEFAULT_DMABUF_SIZE (256 * 1024)
  233083. #define IMX_SSI_DMABUF_SIZE (64 * 1024)
  233084. +#define IMX_SPDIF_DMABUF_SIZE (64 * 1024)
  233085. +#define IMX_ESAI_DMABUF_SIZE (256 * 1024)
  233086. +#define IMX_ASRC_DMABUF_SIZE (256 * 1024)
  233087. static inline void
  233088. imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data,
  233089. int dma, enum sdma_peripheral_type peripheral_type)
  233090. {
  233091. - dma_data->dma_request = dma;
  233092. + dma_data->dma_request0 = dma;
  233093. dma_data->priority = DMA_PRIO_HIGH;
  233094. dma_data->peripheral_type = peripheral_type;
  233095. }
  233096. @@ -39,9 +43,10 @@
  233097. };
  233098. #if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA)
  233099. -int imx_pcm_dma_init(struct platform_device *pdev);
  233100. +int imx_pcm_dma_init(struct platform_device *pdev, unsigned int flags, size_t size);
  233101. #else
  233102. -static inline int imx_pcm_dma_init(struct platform_device *pdev)
  233103. +static inline int imx_pcm_dma_init(struct platform_device *pdev,
  233104. + unsigned int flags, size_t size)
  233105. {
  233106. return -ENODEV;
  233107. }
  233108. diff -Nur linux-3.14.14/sound/soc/fsl/imx-spdif.c linux-imx6-3.14/sound/soc/fsl/imx-spdif.c
  233109. --- linux-3.14.14/sound/soc/fsl/imx-spdif.c 2014-07-28 10:07:25.000000000 -0500
  233110. +++ linux-imx6-3.14/sound/soc/fsl/imx-spdif.c 2014-12-08 00:31:56.116418001 -0600
  233111. @@ -65,14 +65,15 @@
  233112. if (ret)
  233113. goto end;
  233114. + platform_set_drvdata(pdev, &data->card);
  233115. + snd_soc_card_set_drvdata(&data->card, data);
  233116. +
  233117. ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
  233118. if (ret) {
  233119. dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret);
  233120. goto end;
  233121. }
  233122. - platform_set_drvdata(pdev, data);
  233123. -
  233124. end:
  233125. if (spdif_np)
  233126. of_node_put(spdif_np);
  233127. @@ -90,6 +91,7 @@
  233128. .driver = {
  233129. .name = "imx-spdif",
  233130. .owner = THIS_MODULE,
  233131. + .pm = &snd_soc_pm_ops,
  233132. .of_match_table = imx_spdif_dt_ids,
  233133. },
  233134. .probe = imx_spdif_audio_probe,
  233135. diff -Nur linux-3.14.14/sound/soc/fsl/imx-ssi.c linux-imx6-3.14/sound/soc/fsl/imx-ssi.c
  233136. --- linux-3.14.14/sound/soc/fsl/imx-ssi.c 2014-07-28 10:07:25.000000000 -0500
  233137. +++ linux-imx6-3.14/sound/soc/fsl/imx-ssi.c 2014-12-08 00:31:56.116418001 -0600
  233138. @@ -602,7 +602,8 @@
  233139. ssi->fiq_params.dma_params_tx = &ssi->dma_params_tx;
  233140. ssi->fiq_init = imx_pcm_fiq_init(pdev, &ssi->fiq_params);
  233141. - ssi->dma_init = imx_pcm_dma_init(pdev);
  233142. + ssi->dma_init = imx_pcm_dma_init(pdev, SND_DMAENGINE_PCM_FLAG_NO_RESIDUE,
  233143. + IMX_SSI_DMABUF_SIZE);
  233144. if (ssi->fiq_init && ssi->dma_init) {
  233145. ret = ssi->fiq_init;
  233146. diff -Nur linux-3.14.14/sound/soc/fsl/imx-wm8962.c linux-imx6-3.14/sound/soc/fsl/imx-wm8962.c
  233147. --- linux-3.14.14/sound/soc/fsl/imx-wm8962.c 2014-07-28 10:07:25.000000000 -0500
  233148. +++ linux-imx6-3.14/sound/soc/fsl/imx-wm8962.c 2014-12-08 00:31:56.116418001 -0600
  233149. @@ -1,9 +1,9 @@
  233150. /*
  233151. - * Copyright 2013 Freescale Semiconductor, Inc.
  233152. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  233153. *
  233154. * Based on imx-sgtl5000.c
  233155. - * Copyright 2012 Freescale Semiconductor, Inc.
  233156. - * Copyright 2012 Linaro Ltd.
  233157. + * Copyright (C) 2012 Freescale Semiconductor, Inc.
  233158. + * Copyright (C) 2012 Linaro Ltd.
  233159. *
  233160. * The code contained herein is licensed under the GNU General Public
  233161. * License. You may obtain a copy of the GNU General Public License
  233162. @@ -16,9 +16,12 @@
  233163. #include <linux/module.h>
  233164. #include <linux/of_platform.h>
  233165. #include <linux/i2c.h>
  233166. +#include <linux/of_gpio.h>
  233167. #include <linux/slab.h>
  233168. +#include <linux/gpio.h>
  233169. #include <linux/clk.h>
  233170. #include <sound/soc.h>
  233171. +#include <sound/jack.h>
  233172. #include <sound/pcm_params.h>
  233173. #include <sound/soc-dapm.h>
  233174. #include <linux/pinctrl/consumer.h>
  233175. @@ -33,15 +36,134 @@
  233176. struct snd_soc_card card;
  233177. char codec_dai_name[DAI_NAME_SIZE];
  233178. char platform_name[DAI_NAME_SIZE];
  233179. - struct clk *codec_clk;
  233180. unsigned int clk_frequency;
  233181. };
  233182. struct imx_priv {
  233183. + int hp_gpio;
  233184. + int hp_active_low;
  233185. + int mic_gpio;
  233186. + int mic_active_low;
  233187. + bool amic_mono;
  233188. + bool dmic_mono;
  233189. + struct snd_soc_codec *codec;
  233190. struct platform_device *pdev;
  233191. + struct snd_pcm_substream *first_stream;
  233192. + struct snd_pcm_substream *second_stream;
  233193. };
  233194. static struct imx_priv card_priv;
  233195. +static struct snd_soc_jack imx_hp_jack;
  233196. +static struct snd_soc_jack_pin imx_hp_jack_pins[] = {
  233197. + {
  233198. + .pin = "Headphone Jack",
  233199. + .mask = SND_JACK_HEADPHONE,
  233200. + },
  233201. +};
  233202. +static struct snd_soc_jack_gpio imx_hp_jack_gpio = {
  233203. + .name = "headphone detect",
  233204. + .report = SND_JACK_HEADPHONE,
  233205. + .debounce_time = 250,
  233206. + .invert = 0,
  233207. +};
  233208. +
  233209. +static struct snd_soc_jack imx_mic_jack;
  233210. +static struct snd_soc_jack_pin imx_mic_jack_pins[] = {
  233211. + {
  233212. + .pin = "AMIC",
  233213. + .mask = SND_JACK_MICROPHONE,
  233214. + },
  233215. +};
  233216. +static struct snd_soc_jack_gpio imx_mic_jack_gpio = {
  233217. + .name = "microphone detect",
  233218. + .report = SND_JACK_MICROPHONE,
  233219. + .debounce_time = 250,
  233220. + .invert = 0,
  233221. +};
  233222. +
  233223. +static int hpjack_status_check(void)
  233224. +{
  233225. + struct imx_priv *priv = &card_priv;
  233226. + struct platform_device *pdev = priv->pdev;
  233227. + char *envp[3], *buf;
  233228. + int hp_status, ret;
  233229. +
  233230. + if (!gpio_is_valid(priv->hp_gpio))
  233231. + return 0;
  233232. +
  233233. + hp_status = gpio_get_value(priv->hp_gpio) ? 1 : 0;
  233234. +
  233235. + buf = kmalloc(32, GFP_ATOMIC);
  233236. + if (!buf) {
  233237. + dev_err(&pdev->dev, "%s kmalloc failed\n", __func__);
  233238. + return -ENOMEM;
  233239. + }
  233240. +
  233241. + if (hp_status != priv->hp_active_low) {
  233242. + snprintf(buf, 32, "STATE=%d", 2);
  233243. + snd_soc_dapm_disable_pin(&priv->codec->dapm, "Ext Spk");
  233244. + ret = imx_hp_jack_gpio.report;
  233245. + } else {
  233246. + snprintf(buf, 32, "STATE=%d", 0);
  233247. + snd_soc_dapm_enable_pin(&priv->codec->dapm, "Ext Spk");
  233248. + ret = 0;
  233249. + }
  233250. +
  233251. + envp[0] = "NAME=headphone";
  233252. + envp[1] = buf;
  233253. + envp[2] = NULL;
  233254. + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
  233255. + kfree(buf);
  233256. +
  233257. + return ret;
  233258. +}
  233259. +
  233260. +static int micjack_status_check(void)
  233261. +{
  233262. + struct imx_priv *priv = &card_priv;
  233263. + struct platform_device *pdev = priv->pdev;
  233264. + char *envp[3], *buf;
  233265. + int mic_status, ret;
  233266. +
  233267. + if (!gpio_is_valid(priv->mic_gpio))
  233268. + return 0;
  233269. +
  233270. + mic_status = gpio_get_value(priv->mic_gpio) ? 1 : 0;
  233271. +
  233272. + if ((mic_status != priv->mic_active_low && priv->amic_mono)
  233273. + || (mic_status == priv->mic_active_low && priv->dmic_mono))
  233274. + snd_soc_update_bits(priv->codec, WM8962_THREED1,
  233275. + WM8962_ADC_MONOMIX_MASK, WM8962_ADC_MONOMIX);
  233276. + else
  233277. + snd_soc_update_bits(priv->codec, WM8962_THREED1,
  233278. + WM8962_ADC_MONOMIX_MASK, 0);
  233279. +
  233280. + buf = kmalloc(32, GFP_ATOMIC);
  233281. + if (!buf) {
  233282. + dev_err(&pdev->dev, "%s kmalloc failed\n", __func__);
  233283. + return -ENOMEM;
  233284. + }
  233285. +
  233286. + if (mic_status != priv->mic_active_low) {
  233287. + snprintf(buf, 32, "STATE=%d", 2);
  233288. + snd_soc_dapm_disable_pin(&priv->codec->dapm, "DMIC");
  233289. + ret = imx_mic_jack_gpio.report;
  233290. + } else {
  233291. + snprintf(buf, 32, "STATE=%d", 0);
  233292. + snd_soc_dapm_enable_pin(&priv->codec->dapm, "DMIC");
  233293. + ret = 0;
  233294. + }
  233295. +
  233296. + envp[0] = "NAME=microphone";
  233297. + envp[1] = buf;
  233298. + envp[2] = NULL;
  233299. + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
  233300. + kfree(buf);
  233301. +
  233302. + return ret;
  233303. +}
  233304. +
  233305. +
  233306. static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
  233307. SND_SOC_DAPM_HP("Headphone Jack", NULL),
  233308. SND_SOC_DAPM_SPK("Ext Spk", NULL),
  233309. @@ -49,14 +171,57 @@
  233310. SND_SOC_DAPM_MIC("DMIC", NULL),
  233311. };
  233312. -static int sample_rate = 44100;
  233313. -static snd_pcm_format_t sample_format = SNDRV_PCM_FORMAT_S16_LE;
  233314. -
  233315. static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
  233316. - struct snd_pcm_hw_params *params)
  233317. + struct snd_pcm_hw_params *params)
  233318. {
  233319. - sample_rate = params_rate(params);
  233320. - sample_format = params_format(params);
  233321. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  233322. + struct snd_soc_dai *codec_dai = rtd->codec_dai;
  233323. + struct imx_priv *priv = &card_priv;
  233324. + struct device *dev = &priv->pdev->dev;
  233325. + struct snd_soc_card *card = codec_dai->codec->card;
  233326. + struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
  233327. + unsigned int sample_rate = params_rate(params);
  233328. + snd_pcm_format_t sample_format = params_format(params);
  233329. + u32 dai_format, pll_out;
  233330. + int ret = 0;
  233331. +
  233332. + if (!priv->first_stream) {
  233333. + priv->first_stream = substream;
  233334. + } else {
  233335. + priv->second_stream = substream;
  233336. +
  233337. + /* We suppose the two substream are using same params */
  233338. + return 0;
  233339. + }
  233340. +
  233341. + dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  233342. + SND_SOC_DAIFMT_CBM_CFM;
  233343. +
  233344. + /* set codec DAI configuration */
  233345. + ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
  233346. + if (ret) {
  233347. + dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
  233348. + return ret;
  233349. + }
  233350. +
  233351. + if (sample_format == SNDRV_PCM_FORMAT_S24_LE)
  233352. + pll_out = sample_rate * 384;
  233353. + else
  233354. + pll_out = sample_rate * 256;
  233355. +
  233356. + ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, WM8962_FLL_MCLK,
  233357. + data->clk_frequency, pll_out);
  233358. + if (ret) {
  233359. + dev_err(dev, "failed to start FLL: %d\n", ret);
  233360. + return ret;
  233361. + }
  233362. +
  233363. + ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_FLL,
  233364. + pll_out, SND_SOC_CLOCK_IN);
  233365. + if (ret) {
  233366. + dev_err(dev, "failed to set SYSCLK: %d\n", ret);
  233367. + return ret;
  233368. + }
  233369. return 0;
  233370. }
  233371. @@ -133,6 +298,89 @@
  233372. return 0;
  233373. }
  233374. +static int imx_wm8962_gpio_init(struct snd_soc_pcm_runtime *rtd)
  233375. +{
  233376. + struct snd_soc_codec *codec = rtd->codec;
  233377. + struct imx_priv *priv = &card_priv;
  233378. +
  233379. + priv->codec = codec;
  233380. +
  233381. + if (gpio_is_valid(priv->hp_gpio)) {
  233382. + imx_hp_jack_gpio.gpio = priv->hp_gpio;
  233383. + imx_hp_jack_gpio.jack_status_check = hpjack_status_check;
  233384. +
  233385. + snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, &imx_hp_jack);
  233386. + snd_soc_jack_add_pins(&imx_hp_jack,
  233387. + ARRAY_SIZE(imx_hp_jack_pins), imx_hp_jack_pins);
  233388. + snd_soc_jack_add_gpios(&imx_hp_jack, 1, &imx_hp_jack_gpio);
  233389. + }
  233390. +
  233391. + if (gpio_is_valid(priv->mic_gpio)) {
  233392. + imx_mic_jack_gpio.gpio = priv->mic_gpio;
  233393. + imx_mic_jack_gpio.jack_status_check = micjack_status_check;
  233394. +
  233395. + snd_soc_jack_new(codec, "AMIC", SND_JACK_MICROPHONE, &imx_mic_jack);
  233396. + snd_soc_jack_add_pins(&imx_mic_jack,
  233397. + ARRAY_SIZE(imx_mic_jack_pins), imx_mic_jack_pins);
  233398. + snd_soc_jack_add_gpios(&imx_mic_jack, 1, &imx_mic_jack_gpio);
  233399. + } else if (priv->amic_mono || priv->dmic_mono) {
  233400. + /*
  233401. + * Permanent set monomix bit if only one microphone
  233402. + * is present on the board while it needs monomix.
  233403. + */
  233404. + snd_soc_update_bits(priv->codec, WM8962_THREED1,
  233405. + WM8962_ADC_MONOMIX_MASK, WM8962_ADC_MONOMIX);
  233406. + }
  233407. +
  233408. + return 0;
  233409. +}
  233410. +
  233411. +static ssize_t show_headphone(struct device_driver *dev, char *buf)
  233412. +{
  233413. + struct imx_priv *priv = &card_priv;
  233414. + int hp_status;
  233415. +
  233416. + if (!gpio_is_valid(priv->hp_gpio)) {
  233417. + strcpy(buf, "no detect gpio connected\n");
  233418. + return strlen(buf);
  233419. + }
  233420. +
  233421. + /* Check if headphone is plugged in */
  233422. + hp_status = gpio_get_value(priv->hp_gpio) ? 1 : 0;
  233423. +
  233424. + if (hp_status != priv->hp_active_low)
  233425. + strcpy(buf, "headphone\n");
  233426. + else
  233427. + strcpy(buf, "speaker\n");
  233428. +
  233429. + return strlen(buf);
  233430. +}
  233431. +
  233432. +static DRIVER_ATTR(headphone, S_IRUGO | S_IWUSR, show_headphone, NULL);
  233433. +
  233434. +static ssize_t show_mic(struct device_driver *dev, char *buf)
  233435. +{
  233436. + struct imx_priv *priv = &card_priv;
  233437. + int mic_status;
  233438. +
  233439. + if (!gpio_is_valid(priv->mic_gpio)) {
  233440. + strcpy(buf, "no detect gpio connected\n");
  233441. + return strlen(buf);
  233442. + }
  233443. +
  233444. + /* Check if analog microphone is plugged in */
  233445. + mic_status = gpio_get_value(priv->mic_gpio) ? 1 : 0;
  233446. +
  233447. + if (mic_status != priv->mic_active_low)
  233448. + strcpy(buf, "amic\n");
  233449. + else
  233450. + strcpy(buf, "dmic\n");
  233451. +
  233452. + return strlen(buf);
  233453. +}
  233454. +
  233455. +static DRIVER_ATTR(microphone, S_IRUGO | S_IWUSR, show_mic, NULL);
  233456. +
  233457. static int imx_wm8962_late_probe(struct snd_soc_card *card)
  233458. {
  233459. struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
  233460. @@ -157,6 +405,7 @@
  233461. struct imx_priv *priv = &card_priv;
  233462. struct i2c_client *codec_dev;
  233463. struct imx_wm8962_data *data;
  233464. + struct clk *codec_clk = NULL;
  233465. int int_port, ext_port;
  233466. int ret;
  233467. @@ -219,25 +468,31 @@
  233468. goto fail;
  233469. }
  233470. + priv->first_stream = NULL;
  233471. + priv->second_stream = NULL;
  233472. +
  233473. data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
  233474. if (!data) {
  233475. ret = -ENOMEM;
  233476. goto fail;
  233477. }
  233478. - data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
  233479. - if (IS_ERR(data->codec_clk)) {
  233480. - ret = PTR_ERR(data->codec_clk);
  233481. + codec_clk = devm_clk_get(&codec_dev->dev, NULL);
  233482. + if (IS_ERR(codec_clk)) {
  233483. + ret = PTR_ERR(codec_clk);
  233484. dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
  233485. goto fail;
  233486. }
  233487. - data->clk_frequency = clk_get_rate(data->codec_clk);
  233488. - ret = clk_prepare_enable(data->codec_clk);
  233489. - if (ret) {
  233490. - dev_err(&codec_dev->dev, "failed to enable codec clk: %d\n", ret);
  233491. - goto fail;
  233492. - }
  233493. + data->clk_frequency = clk_get_rate(codec_clk);
  233494. +
  233495. + priv->amic_mono = of_property_read_bool(codec_np, "amic-mono");
  233496. + priv->dmic_mono = of_property_read_bool(codec_np, "dmic-mono");
  233497. +
  233498. + priv->hp_gpio = of_get_named_gpio_flags(np, "hp-det-gpios", 0,
  233499. + (enum of_gpio_flags *)&priv->hp_active_low);
  233500. + priv->mic_gpio = of_get_named_gpio_flags(np, "mic-det-gpios", 0,
  233501. + (enum of_gpio_flags *)&priv->mic_active_low);
  233502. data->dai.name = "HiFi";
  233503. data->dai.stream_name = "HiFi";
  233504. @@ -246,23 +501,23 @@
  233505. data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev);
  233506. data->dai.platform_of_node = ssi_np;
  233507. data->dai.ops = &imx_hifi_ops;
  233508. + data->dai.init = &imx_wm8962_gpio_init;
  233509. data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  233510. SND_SOC_DAIFMT_CBM_CFM;
  233511. data->card.dev = &pdev->dev;
  233512. ret = snd_soc_of_parse_card_name(&data->card, "model");
  233513. if (ret)
  233514. - goto clk_fail;
  233515. + goto fail;
  233516. ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
  233517. if (ret)
  233518. - goto clk_fail;
  233519. + goto fail;
  233520. data->card.num_links = 1;
  233521. data->card.dai_link = &data->dai;
  233522. data->card.dapm_widgets = imx_wm8962_dapm_widgets;
  233523. data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8962_dapm_widgets);
  233524. data->card.late_probe = imx_wm8962_late_probe;
  233525. - data->card.set_bias_level = imx_wm8962_set_bias_level;
  233526. platform_set_drvdata(pdev, &data->card);
  233527. snd_soc_card_set_drvdata(&data->card, data);
  233528. @@ -270,16 +525,31 @@
  233529. ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
  233530. if (ret) {
  233531. dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
  233532. - goto clk_fail;
  233533. + goto fail;
  233534. }
  233535. - of_node_put(ssi_np);
  233536. - of_node_put(codec_np);
  233537. + if (gpio_is_valid(priv->hp_gpio)) {
  233538. + ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone);
  233539. + if (ret) {
  233540. + dev_err(&pdev->dev, "create hp attr failed (%d)\n", ret);
  233541. + goto fail_hp;
  233542. + }
  233543. + }
  233544. - return 0;
  233545. + if (gpio_is_valid(priv->mic_gpio)) {
  233546. + ret = driver_create_file(pdev->dev.driver, &driver_attr_microphone);
  233547. + if (ret) {
  233548. + dev_err(&pdev->dev, "create mic attr failed (%d)\n", ret);
  233549. + goto fail_mic;
  233550. + }
  233551. + }
  233552. +
  233553. + goto fail;
  233554. -clk_fail:
  233555. - clk_disable_unprepare(data->codec_clk);
  233556. +fail_mic:
  233557. + driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
  233558. +fail_hp:
  233559. + snd_soc_unregister_card(&data->card);
  233560. fail:
  233561. if (ssi_np)
  233562. of_node_put(ssi_np);
  233563. @@ -291,11 +561,8 @@
  233564. static int imx_wm8962_remove(struct platform_device *pdev)
  233565. {
  233566. - struct snd_soc_card *card = platform_get_drvdata(pdev);
  233567. - struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
  233568. -
  233569. - if (!IS_ERR(data->codec_clk))
  233570. - clk_disable_unprepare(data->codec_clk);
  233571. + driver_remove_file(pdev->dev.driver, &driver_attr_microphone);
  233572. + driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
  233573. return 0;
  233574. }
  233575. diff -Nur linux-3.14.14/sound/soc/fsl/Kconfig linux-imx6-3.14/sound/soc/fsl/Kconfig
  233576. --- linux-3.14.14/sound/soc/fsl/Kconfig 2014-07-28 10:07:25.000000000 -0500
  233577. +++ linux-imx6-3.14/sound/soc/fsl/Kconfig 2014-12-08 00:31:56.116418001 -0600
  233578. @@ -11,6 +11,12 @@
  233579. config SND_SOC_FSL_ESAI
  233580. tristate
  233581. +config SND_SOC_FSL_ASRC
  233582. + tristate
  233583. +
  233584. +config SND_SOC_FSL_HDMI
  233585. + tristate
  233586. +
  233587. config SND_SOC_FSL_UTILS
  233588. tristate
  233589. @@ -126,6 +132,11 @@
  233590. tristate
  233591. select SND_SOC_GENERIC_DMAENGINE_PCM
  233592. +config SND_SOC_IMX_HDMI_DMA
  233593. + bool
  233594. + select SND_SOC_GENERIC_DMAENGINE_PCM
  233595. + select SND_SOC_IMX_PCM_DMA
  233596. +
  233597. config SND_SOC_IMX_AUDMUX
  233598. tristate
  233599. @@ -178,6 +189,18 @@
  233600. Enable I2S based access to the TLV320AIC23B codec attached
  233601. to the SSI interface
  233602. +config SND_SOC_IMX_CS42888
  233603. + tristate "SoC Audio support for i.MX boards with cs42888"
  233604. + depends on OF && I2C
  233605. + select SND_SOC_CS42888
  233606. + select SND_SOC_IMX_PCM_DMA
  233607. + select SND_SOC_FSL_ESAI
  233608. + select SND_SOC_FSL_UTILS
  233609. + help
  233610. + SoC Audio support for i.MX boards with cs42888
  233611. + Say Y if you want to add support for SoC audio on an i.MX board with
  233612. + a cs42888 codec.
  233613. +
  233614. config SND_SOC_IMX_WM8962
  233615. tristate "SoC Audio support for i.MX boards with wm8962"
  233616. depends on OF && I2C
  233617. @@ -210,6 +233,17 @@
  233618. Say Y if you want to add support for SoC audio on an i.MX board with
  233619. a S/DPDIF.
  233620. +config SND_SOC_IMX_HDMI
  233621. + tristate "SoC Audio support for i.MX boards with HDMI port"
  233622. + depends on MFD_MXC_HDMI
  233623. + select SND_SOC_IMX_HDMI_DMA
  233624. + select SND_SOC_FSL_HDMI
  233625. + select SND_SOC_HDMI_CODEC
  233626. + help
  233627. + SoC Audio support for i.MX boards with HDMI audio
  233628. + Say Y if you want to add support for SoC audio on an i.MX board with
  233629. + IMX HDMI.
  233630. +
  233631. config SND_SOC_IMX_MC13783
  233632. tristate "SoC Audio support for I.MX boards with mc13783"
  233633. depends on MFD_MC13XXX && ARM
  233634. diff -Nur linux-3.14.14/sound/soc/fsl/Makefile linux-imx6-3.14/sound/soc/fsl/Makefile
  233635. --- linux-3.14.14/sound/soc/fsl/Makefile 2014-07-28 10:07:25.000000000 -0500
  233636. +++ linux-imx6-3.14/sound/soc/fsl/Makefile 2014-12-08 00:31:56.116418001 -0600
  233637. @@ -14,13 +14,19 @@
  233638. snd-soc-fsl-sai-objs := fsl_sai.o
  233639. snd-soc-fsl-ssi-objs := fsl_ssi.o
  233640. snd-soc-fsl-spdif-objs := fsl_spdif.o
  233641. +snd-soc-fsl-hdmi-objs := fsl_hdmi.o
  233642. snd-soc-fsl-esai-objs := fsl_esai.o
  233643. +snd-soc-fsl-asrc-pcm-objs := fsl_asrc_pcm.o
  233644. +snd-soc-fsl-asrc-objs := fsl_asrc.o
  233645. snd-soc-fsl-utils-objs := fsl_utils.o
  233646. snd-soc-fsl-dma-objs := fsl_dma.o
  233647. obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
  233648. obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
  233649. obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o
  233650. +obj-$(CONFIG_SND_SOC_FSL_HDMI) += snd-soc-fsl-hdmi.o
  233651. obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o
  233652. +obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc-pcm.o
  233653. +obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
  233654. obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
  233655. obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
  233656. @@ -41,22 +47,27 @@
  233657. obj-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o
  233658. obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
  233659. +obj-$(CONFIG_SND_SOC_IMX_HDMI_DMA) += imx-hdmi-dma.o
  233660. # i.MX Machine Support
  233661. snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
  233662. snd-soc-phycore-ac97-objs := phycore-ac97.o
  233663. snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
  233664. snd-soc-wm1133-ev1-objs := wm1133-ev1.o
  233665. +snd-soc-imx-cs42888-objs := imx-cs42888.o
  233666. snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
  233667. snd-soc-imx-wm8962-objs := imx-wm8962.o
  233668. snd-soc-imx-spdif-objs := imx-spdif.o
  233669. +snd-soc-imx-hdmi-objs := imx-hdmi.o
  233670. snd-soc-imx-mc13783-objs := imx-mc13783.o
  233671. obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
  233672. obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
  233673. obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
  233674. obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
  233675. +obj-$(CONFIG_SND_SOC_IMX_CS42888) += snd-soc-imx-cs42888.o
  233676. obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
  233677. obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
  233678. obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
  233679. +obj-$(CONFIG_SND_SOC_IMX_HDMI) += snd-soc-imx-hdmi.o
  233680. obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
  233681. diff -Nur linux-3.14.14/sound/soc/soc-pcm.c linux-imx6-3.14/sound/soc/soc-pcm.c
  233682. --- linux-3.14.14/sound/soc/soc-pcm.c 2014-07-28 10:07:25.000000000 -0500
  233683. +++ linux-imx6-3.14/sound/soc/soc-pcm.c 2014-12-08 00:31:56.132418001 -0600
  233684. @@ -945,7 +945,7 @@
  233685. }
  233686. }
  233687. - dev_err(card->dev, "ASoC: can't get %s BE for %s\n",
  233688. + dev_dbg(card->dev, "ASoC: can't get %s BE for %s\n",
  233689. stream ? "capture" : "playback", widget->name);
  233690. return NULL;
  233691. }
  233692. @@ -1062,7 +1062,7 @@
  233693. /* is there a valid BE rtd for this widget */
  233694. be = dpcm_get_be(card, list->widgets[i], stream);
  233695. if (!be) {
  233696. - dev_err(fe->dev, "ASoC: no BE found for %s\n",
  233697. + dev_dbg(fe->dev, "ASoC: no BE found for %s\n",
  233698. list->widgets[i]->name);
  233699. continue;
  233700. }